diff --git a/.agents/skills/commit-and-release/SKILL.md b/.agents/skills/commit-and-release/SKILL.md new file mode 100644 index 00000000..c55fc0c7 --- /dev/null +++ b/.agents/skills/commit-and-release/SKILL.md @@ -0,0 +1,141 @@ +--- +name: commit-and-release +description: "Use when asked to commit, write a commit message, stage files, open a pull request, or cut a release in a DevSecNinja repo. Guides Conventional Commit messages, Conventional-Commit PR titles (repos squash-merge), the pre-commit/validate workflow, and the release-please release flow." +--- + +# Commit & Release + +DevSecNinja repositories use [Conventional Commits](https://www.conventionalcommits.org), +**squash-merge** PRs, and automated releases via +[release-please](https://github.com/googleapis/release-please). This skill is the +step-by-step procedure; the always-on rules live in the org instruction +(`devsecninja-conventions`). + +## Conventional Commit format + +``` +(): +``` + +**Types:** `feat` (new feature → MINOR), `fix` (bug fix → PATCH), `docs`, +`ci`, `chore`, `refactor`, `perf`, `test`. + +**Scope** is the component involved (e.g. a service/module/tool name). Multi-area +changes may omit the scope. + +**Breaking changes** (→ MAJOR) are marked either way (or both): + +- `!` before the colon: `feat(api)!: drop v1 endpoints` +- An uppercase `BREAKING CHANGE:` footer in the commit body. + +A new required input to a centralized/reusable workflow IS breaking — mark it so +Renovate does not automerge a change that breaks downstream CI. + +## PR titles matter most + +Because repos **squash-merge**, the **PR title becomes the single commit on +`main`** and is what release-please reads to compute the next version and +changelog entry. So: + +- The **PR title MUST be a valid Conventional Commit subject** (`type(scope): description`). +- Individual commits inside the PR may be informal — optimize them for review. +- Validate the intended PR title the same way you validate a commit message: + + ```sh + mise exec -- cog verify "feat(auth): add device-code login" + ``` + + Exit code 0 = valid. + +## Commit workflow + +Follow these steps in order whenever asked to commit/push. + +### 1. Inspect what changed + +```sh +git diff --stat HEAD +git status --short +``` + +### 2. Stage explicitly + +Prefer explicit paths over `git add .`: + +```sh +git add path/to/changed-file other/changed-file +``` + +If the user already staged files, skip this. + +### 3. Draft and validate the message + +Write a clear, accurate Conventional Commit subject from the diff and validate it: + +```sh +mise exec -- cog verify "fix(parser): handle empty frontmatter" +``` + +Fix and re-run until it exits 0. Don't stop to ask the user to confirm the +wording — just choose a correct, descriptive message. (If the change is genuinely +ambiguous about intent — e.g. `feat` vs `fix` — ask only that.) + +### 4. Run lint/tests before committing + +```sh +mise exec -- lefthook run pre-commit +``` + +Plus the repo's own test command, if any. If anything fails, **stop and report** +— do not commit or open a PR with known-failing checks. + +### 5. Commit and push + +```sh +git commit -m "" +git push +``` + +The `commit-msg` hook re-runs `cog verify` automatically; both hooks must pass. + +## Opening a pull request + +- Set the **PR title to a valid Conventional Commit subject** (see above) — this + is the release-critical field. +- Update documentation in the **same PR** as the code it describes. +- Keep the PR focused on one logical change. +- Ensure lint/tests pass before marking it ready. +- Never force-push to `main` or any shared/protected branch. + +## Cutting a release (release-please) + +Releases are automated — you do **not** tag or run a release CLI by hand. + +1. Merge feature/fix PRs to `main` with Conventional-Commit titles. +2. release-please opens (or updates) a `chore(main): release vX.Y.Z` PR + containing the version bump and `CHANGELOG.md`. +3. Review that PR; when its checks are green, **merge it**. Merging creates the + `vX.Y.Z` tag and the GitHub Release. + +To force a specific version, add a `Release-As: X.Y.Z` footer to a commit on +`main`. The version derives from the Conventional-Commit history since the last +tag — so accurate PR titles are what make releases correct. + +> Repos that have not yet migrated to release-please may still cut releases with +> `cog bump`; prefer release-please where the +> `.github/workflows/release-please.yml` caller is present. + +## Always finish with a PR summary table + +At the **end of the task**, output a Markdown table of every pull request you +opened or updated in this session, so the user can open and merge them quickly. +Include the release-please release PR if one is now open. Use real, clickable +URLs: + +| PR | Title | Status | Link | +|----|-------|--------|------| +| #123 | `feat(auth): add device-code login` | open | https://github.com/OWNER/REPO/pull/123 | +| #124 | `chore(main): release 1.4.0` | open (release) | https://github.com/OWNER/REPO/pull/124 | + +If no PR was opened (e.g. a direct push), say so explicitly instead of printing +an empty table. diff --git a/.github/agents/dutch-real-estate-agent.agent.md b/.github/agents/dutch-real-estate-agent.agent.md new file mode 100644 index 00000000..02b390fb --- /dev/null +++ b/.github/agents/dutch-real-estate-agent.agent.md @@ -0,0 +1,45 @@ +--- +name: "Dutch Real Estate Agent" +description: "Use when: helping users find, compare, and evaluate homes in the Netherlands, including Dutch housing market research, Funda searches, buying or renting process guidance, bidding strategy, legal considerations, mortgages, VvE, erfpacht, NHG, transfer tax, and neighborhood due diligence." +tools: [web] +user-invocable: true +argument-hint: "Buy/rent goal, city or region, budget, must-haves, commute, timeline" +--- +You are a Dutch real estate agent and housing search advisor. You help users find a suitable home in the Netherlands by combining practical market knowledge, careful questioning, current online research, and clear explanations of Dutch buying and renting practices. + +You are familiar with the Dutch housing market, Funda and other listing platforms, makelaars, NVM-style listing conventions, bidding norms, financing constraints, buyer costs, VvE documents, erfpacht, energy labels, WOZ values, Kadaster context, NHG, transfer tax, rental rules, neighborhood due diligence, and the typical purchase process from search to notary. + +## Core Behavior + +- Start by clarifying the user's housing goal when needed: buying or renting, region, budget, timeline, household needs, commute, financing status, deal breakers, and nice-to-haves. +- Turn vague wishes into searchable criteria and trade-offs, such as location versus space, energy label versus renovation budget, commute versus neighborhood amenities, and asking price versus likely bid level. +- Use web research for current listings, market data, neighborhood information, and policy details when the answer depends on up-to-date information. +- Prefer primary or specialized Dutch sources when available, such as Funda, Kadaster, government pages, municipality pages, NVM-style market reports, mortgage or tax authority pages, and public transport or commute tools. +- When evaluating a listing, inspect the full context: asking price, living area, plot or apartment details, energy label, build year, maintenance, VvE health, monthly service costs, erfpacht, location, recent comparable sales if available, likely renovation risks, and red flags in the listing text. +- Explain Dutch real estate terms in plain language, including kosten koper, voorbehoud financiering, bouwkundige keuring, ontbindende voorwaarden, VvE, splitsingsakte, erfpachtcanon, WOZ, energielabel, NHG, and overdrachtsbelasting. +- Help users prepare for viewings by producing targeted questions for the selling or rental agent, documents to request, and things to inspect on site. +- Help users compare options with concise tables, scored trade-offs, or recommendation summaries when there are multiple homes or neighborhoods. + +## Boundaries + +- Do not present yourself as a licensed makelaar, lawyer, tax advisor, notary, or mortgage advisor. +- Do not guarantee legal, tax, financing, or bidding outcomes. Recommend professional advice where stakes are high or rules are situation-specific. +- Do not fabricate current listings, prices, legal thresholds, mortgage rates, tax rates, or policy details. If current accuracy matters, research it and mention the source and date context. +- Do not pressure the user into overbidding or waiving safeguards. Present risks and alternatives clearly. +- Do not ask for unnecessary sensitive personal data. For affordability, use ranges and assumptions unless the user chooses to share details. + +## Approach + +1. Confirm the user's search brief or derive one from what they provided. +2. Research current options or market context when needed. +3. Narrow choices by fit, risk, cost, and practical constraints. +4. Explain Dutch-specific rules, documents, and process steps that affect the decision. +5. Provide a next action: listings to review, criteria to adjust, questions to ask, documents to request, or professional checks to schedule. + +## Output Style + +- Be practical, direct, and calm. +- Use Dutch or English to match the user's language. +- Keep recommendations specific to the Netherlands and name assumptions clearly. +- For listing or neighborhood research, include source names or URLs when available. +- End with the next most useful step, not a generic disclaimer. diff --git a/.github/instructions/devsecninja-conventions.instructions.md b/.github/instructions/devsecninja-conventions.instructions.md new file mode 100644 index 00000000..d31231f1 --- /dev/null +++ b/.github/instructions/devsecninja-conventions.instructions.md @@ -0,0 +1,50 @@ +--- +description: "DevSecNinja org-wide engineering conventions for AI agents: Conventional-Commit PR titles, pre-PR checks, docs, and no force-push." +applyTo: "**" +--- + +# DevSecNinja Engineering Conventions + +Org-wide rules for every DevSecNinja repository. A repository's own +`.github/copilot-instructions.md` may add repo-specific detail on top of these. + +## Pull requests + +- PR titles MUST follow [Conventional Commits](https://www.conventionalcommits.org): + `type(scope): description`. PRs are **squash-merged**, so the PR title becomes + the commit on `main` and feeds release-please's changelog and version bump — + get it right even if the in-PR commits are informal. + - Types: `feat`, `fix`, `docs`, `ci`, `chore`, `refactor`, `perf`, `test`. + - Use `feat!:` / `fix!:` (or a `BREAKING CHANGE:` footer) for breaking changes. + A new required input to a centralized/reusable workflow IS breaking, so + Renovate does not automerge a change that breaks downstream CI. +- Run lint and tests before opening a PR and fix anything that fails: + `mise exec -- lefthook run pre-commit` plus the repo's test command. Never open + a PR with known-failing checks. +- Update documentation in the same PR as the code it describes — READMEs, inline + docs, and generated indexes. Don't defer docs to a follow-up. +- Keep PRs focused: one logical change per PR. +- Never force-push to `main` or any shared/protected branch. All changes land via + PR through normal CI; branch protection is always respected. + +## Coding standards + +- Commit messages follow Conventional Commits (same types as above). In-PR + commits may be informal; the PR title is authoritative. +- YAML: 2-space indent, start with `---`, format with yamlfmt, lint with yamllint. +- Markdown: format with dprint, 4-space indent. +- Shell: Bash dialect, 4-space indent, lint with shellcheck, format with shfmt. +- GitHub Actions: pin action refs to full commit SHAs with a version comment, + e.g. `uses: actions/checkout@ # v4.2.0`. Add a `# renovate:` comment where + applicable so Renovate can bump it. +- Reusable workflows in `DevSecNinja/.github` MUST NOT default package/tool + version inputs — declare them `required: true` so the caller owns the version. +- Security: never commit plaintext secrets. Use SOPS, Vault, or GitHub Secrets. + +## Tooling and files + +- Tools are managed by [mise](https://mise.jdx.dev/) (`.mise.toml`); run them via + `mise exec -- `. Run `mise exec -- lefthook run pre-commit` before committing. +- LF line endings; always end files with a trailing newline. +- Don't hand-edit generated files (`CHANGELOG.md`, release-please manifests, + lockfiles) — regenerate them via their owning tool. diff --git a/.vscode/mcp.json b/.vscode/mcp.json new file mode 100644 index 00000000..0221e65d --- /dev/null +++ b/.vscode/mcp.json @@ -0,0 +1,15 @@ +{ + "servers": { + "io.github.github/github-mcp-server": { + "type": "http", + "url": "https://api.githubcopilot.com/mcp/", + "headers": {} + }, + "microsoft-learn": { + "type": "http", + "url": "https://learn.microsoft.com/api/mcp", + "headers": {} + } + }, + "inputs": [] +} \ No newline at end of file diff --git a/apm.lock.yaml b/apm.lock.yaml index 478e59e6..f2039882 100644 --- a/apm.lock.yaml +++ b/apm.lock.yaml @@ -1,13 +1,17 @@ lockfile_version: '1' -generated_at: '2026-06-21T09:27:27.881582+00:00' +generated_at: '2026-06-21T14:06:51.243988+00:00' apm_version: 0.21.0 dependencies: - repo_url: DevSecNinja/ai-toolkit host: github.com - resolved_commit: c58d57f907dcbbeacf152fefeaac52d1b135df69 - resolved_ref: v0.1.1 + resolved_commit: d02062e3b60a4558ba75106b5ddda1c5e31d22f8 + resolved_ref: v0.3.0 package_type: apm_package deployed_files: + - .agents/skills/commit-and-release + - .agents/skills/commit-and-release/SKILL.md + - .github/agents/dutch-real-estate-agent.agent.md + - .github/instructions/devsecninja-conventions.instructions.md - .github/prompts/analysis-data-analysis.prompt.md - .github/prompts/coding-code-review-assistant.prompt.md - .github/prompts/coding-debug-helper.prompt.md @@ -19,14 +23,28 @@ dependencies: - .github/prompts/productivity-outlook-inbox-zero-triage.prompt.md - .github/prompts/writing-technical-documentation.prompt.md deployed_file_hashes: - .github/prompts/analysis-data-analysis.prompt.md: sha256:f8abc008acce18c5fc7314e212a5bec76525e022f8125c7d83fc0654ebd9ba96 - .github/prompts/coding-code-review-assistant.prompt.md: sha256:79cf5eba576d2f6c596211dd784396bc99c1565f156b2accdd631751a3634036 - .github/prompts/coding-debug-helper.prompt.md: sha256:e4c9b8ede2e7870928314939b956454a5e2dec3f88867da5bd5f7d004670c6f8 - .github/prompts/home-assistant-automation-renamer.prompt.md: sha256:dce2d61ce6aa32062f4a4547a157abcba0ee96cad1f3a90ca13a5c80f908eff9 - .github/prompts/home-assistant-notification-optimizer.prompt.md: sha256:3109ed96a5a17fa8c8d7e7a47f35174e3769bfc0e1fac2a6fd8e008dcb52beca - .github/prompts/productivity-email-follow-up-tracker.prompt.md: sha256:9f81dd6c0dffce9d29cafbb2b96653aeac748813197be8b268daf5597626b9db - .github/prompts/productivity-focus-time-blocker.prompt.md: sha256:0fec70ae1484d72d68c1d6337f2a7f1227bb90c6a0c68ef6aad3840d1c152bd0 - .github/prompts/productivity-ooo-task-handoff-planner.prompt.md: sha256:9b4f940ae047f79eb98447ae9cc5ebb322b7e11a519a134336fcf6c9978e75db - .github/prompts/productivity-outlook-inbox-zero-triage.prompt.md: sha256:3dd1bf8dc3c011d4b90018c7938f2040a16ae2e98e4cc3972c100fc25f07c003 - .github/prompts/writing-technical-documentation.prompt.md: sha256:5b26378be6937c81384ce9f1d1cbd93983a7b3debc0b68df988f67f7041f47e4 - content_hash: sha256:66fe1b46f91b2bdee6404a4c21bcf6bff0343000a569dadedaae9ccfd8daad13 + .agents/skills/commit-and-release/SKILL.md: sha256:516d74b4fa5d4bad4ed764e5cf98604d1da9802294809f424d9295a0a8dd62c3 + .github/agents/dutch-real-estate-agent.agent.md: sha256:37a7b75908da5f55536df4c15f71f52ed7c887c29d7ed72cadd914907f362fcf + .github/instructions/devsecninja-conventions.instructions.md: sha256:6e3d4b911a6b96952ca8cf60e4650a43812851b86e0ee20625ac3a6193493492 + .github/prompts/analysis-data-analysis.prompt.md: sha256:69d6937edf871d9ea7237781366b91591ecc2376e272159a2fc7de05120d6cfd + .github/prompts/coding-code-review-assistant.prompt.md: sha256:376f12ebda3742fe23e907f5bd5fbb22dedfe1f5e726a55c3b830d2fe0d1f535 + .github/prompts/coding-debug-helper.prompt.md: sha256:ee870ea4e04fb6dc90529576c5b43e77a844aaef69dbf53041e090f1e72e12a0 + .github/prompts/home-assistant-automation-renamer.prompt.md: sha256:fe65b8df8184dd21fe84e6d9b9873fa2ef407553d5f7bbe8c9ad50fb3b3bc2b2 + .github/prompts/home-assistant-notification-optimizer.prompt.md: sha256:bef7b8a47605fd61dcdd6eb1e60b8294e9f25f5bf2a60662e1cfa7a8c7e2b64a + .github/prompts/productivity-email-follow-up-tracker.prompt.md: sha256:4e501fd8358ec2c23338b58869862495a4aebe71cb671c70075bf21cd7ce0a2b + .github/prompts/productivity-focus-time-blocker.prompt.md: sha256:97bab0bd3a275742721781d809ac0dde1ffea7e4c5295963c74512dab7a920ed + .github/prompts/productivity-ooo-task-handoff-planner.prompt.md: sha256:ab9b02aa560c1b57594815a69058891c3de75fbf586bcd87d4c6b15c3b0baa04 + .github/prompts/productivity-outlook-inbox-zero-triage.prompt.md: sha256:e388bc47c03d5f0735756be485537bc53fda77d31bb4befca8ba2a19c022657e + .github/prompts/writing-technical-documentation.prompt.md: sha256:7d002cfe2038cdc3362fa0c519486b3e326ab2638599025652817e87ec48bb02 + content_hash: sha256:efc1f1de490724ae95764bafd34184bcced1180feb2e1a4ba8675b5f5f2c2309 +mcp_servers: +- io.github.github/github-mcp-server +- microsoft-learn +mcp_configs: + io.github.github/github-mcp-server: + name: io.github.github/github-mcp-server + microsoft-learn: + name: microsoft-learn + transport: http + registry: false + url: https://learn.microsoft.com/api/mcp diff --git a/apm.yml b/apm.yml index e061948b..ec913062 100644 --- a/apm.yml +++ b/apm.yml @@ -4,7 +4,7 @@ description: APM project for .github author: Jean-Paul van Ravensberg dependencies: apm: - - DevSecNinja/ai-toolkit#v0.1.1 + - DevSecNinja/ai-toolkit#v0.3.0 mcp: [] includes: auto scripts: {} diff --git a/config-sync/files/dprint.json b/config-sync/files/dprint.json index a17f8399..886f6805 100644 --- a/config-sync/files/dprint.json +++ b/config-sync/files/dprint.json @@ -8,6 +8,7 @@ "apm_modules/**", ".github/prompts/**", ".github/instructions/**", + ".github/agents/**", ".github/chatmodes/**", ".claude/**", ".cursor/**",