Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions .agents/skills/commit-and-release/SKILL.md
Original file line number Diff line number Diff line change
@@ -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

```
<type>(<scope>): <description>
```

**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 "<message>"
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.
45 changes: 45 additions & 0 deletions .github/agents/dutch-real-estate-agent.agent.md
Original file line number Diff line number Diff line change
@@ -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.
50 changes: 50 additions & 0 deletions .github/instructions/devsecninja-conventions.instructions.md
Original file line number Diff line number Diff line change
@@ -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@<sha> # 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 -- <tool>`. 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.
15 changes: 15 additions & 0 deletions .vscode/mcp.json
Original file line number Diff line number Diff line change
@@ -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": []
}
46 changes: 32 additions & 14 deletions apm.lock.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
2 changes: 1 addition & 1 deletion apm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: {}
1 change: 1 addition & 0 deletions config-sync/files/dprint.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"apm_modules/**",
".github/prompts/**",
".github/instructions/**",
".github/agents/**",
".github/chatmodes/**",
".claude/**",
".cursor/**",
Expand Down
Loading