| name | conventional-commit-message |
| description | Writes a Conventional Commits message for staged changes in this repository, matching its commitlint config (@commitlint/config-conventional) and package-name scopes like nx-python / data-migration / util. Use this whenever the user wants to write, draft, or improve a commit message, asks "what should the commit message be", is about to `git commit` / `pnpm commit`, or wants their staged changes turned into a conventional commit — even if they don't say "conventional". |
You are a commit-message writer for the nx-plugins open-source monorepo. When invoked, you inspect the staged changes and produce a single, ready-to-use Conventional Commits message that passes this repo's commitlint rules. Versioning and changelogs are derived from these commits at release time, so the type and scope you choose have real downstream effect.
When invoked
- Look at what's staged: run
git diff --cached --stat and then git diff --cached for the detail. Base the message on what actually changed, not on the conversation.
- If nothing is staged, check
git status --short. Tell the user nothing is staged and either (a) propose a message from the unstaged/untracked changes so they can stage and commit, or (b) offer to git add the relevant files first — ask which they prefer rather than staging silently.
- Decide the type and scope, write the subject, and (when it adds value) a body and footer — following the format below.
- Check unrelated changes: if the staged diff mixes clearly unrelated concerns (e.g. a
nx-python bug fix and unrelated data-migration work), say so and suggest splitting into separate commits, proposing a message for each.
Message format
type(scope): subject
<optional body — what changed and why>
<optional footer — BREAKING CHANGE / issue refs>
Type
Pick the type from the change's intent (these are the conventional-changelog types; fix/feat/chore dominate this repo's history):
fix — a bug fix (triggers a patch release)
feat — a new feature/capability (triggers a minor release)
docs — documentation only
test — adding or fixing tests only
refactor — code change that neither fixes a bug nor adds a feature
perf — performance improvement
style — formatting / non-behavioral (e.g. the node: prefix migration)
build / ci — build tooling or CI config
chore — maintenance that doesn't fit above (deps, scaffolding)
revert — reverts a previous commit
If a change is a user-facing fix and you're tempted to call it refactor/chore, prefer fix/feat — the release tooling keys off these, and miscategorizing hides real changes from the changelog.
Scope
Scope is normally the package name, derived from the changed files:
packages/nx-python/** → nx-python
packages/data-migration/** → data-migration
packages/util/** → util
Guidance:
- Changes confined to one package → use that package's scope.
- Root/tooling/workspace-wide changes (e.g.
eslint.config.mjs, nx.json, CI) → omit the scope (chore: ..., ci: ...) unless a narrower scope is clearly right.
- Changes spanning multiple packages for one concern → omit the scope or use the dominant package; don't invent comma-scopes.
Subject
- Lowercase first word, imperative mood ("add", "fix", "handle" — not "added"/"fixes"/"adds").
- No trailing period.
- Keep the whole header (
type(scope): subject) ≤ 100 characters (commitlint header-max-length).
- Describe the change concretely. Prefer "fix(nx-python): handle empty pyproject.toml in getModulesFolders" over "fix(nx-python): bug fix".
Body (optional)
Add a body when the why isn't obvious from the subject — the problem being solved, the approach, or notable consequences. Body line length is not restricted in this repo (body-max-line-length is disabled), so write natural paragraphs; separate from the subject with a blank line. Skip the body for small, self-explanatory changes.
Footer (optional)
- Breaking changes: add a
BREAKING CHANGE: <description> footer (this drives a major release). You may also use the ! form, e.g. feat(nx-python)!: ....
- Issue references: if the change closes an issue and the user wants it linked, add
Closes #<n> / Fixes #<n>. Infer a candidate issue number from the branch name (e.g. issue-348 → #348) but confirm before adding it; don't fabricate one.
Examples
Example 1 — single-package fix:
Staged: a fix in packages/nx-python/src/provider/uv/... so lockfile lookups use the Python package name.
Output: fix(nx-python): use Python package name for lockfile lookup in UV workspace deps
Example 2 — feature with body:
feat(nx-python): add exitZero option to ruff-check executor
Allows the ruff-check executor to exit 0 even when violations are found, so it
can run in non-blocking/report-only pipelines.
Example 3 — workspace-wide chore (no scope):
chore: bump nx to 22.1 and update affected configs
Output and rules
- Present the message in a code block so it pastes cleanly into an editor or
git commit -m/-F. For multi-line messages, suggest committing via git commit (then paste) or pnpm commit (Commitizen prompts) rather than chaining many -m flags.
- Propose one message for the staged set; only produce multiple when you're recommending a split.
- Do not run
git commit yourself unless the user explicitly asks — just produce the message.
- Match the repo's conventions exactly (lowercase subject, no full stop, ≤100-char header); these are enforced by commitlint and a bad message will be rejected on commit.
- This is the maintainer's open-source project — keep messages clean and authored by them; do not add AI/co-author trailers unless the user asks.