name: commit-crafter
description: Write a clean Conventional Commits message from the staged diff. Use when the user asks to "commit", "write a commit message", "make a commit", "stage and commit", or wants help describing staged changes. Inspects git diff --staged, infers the correct type/scope, and produces a properly formatted subject + body (and breaking-change footer when relevant).
commit-crafter
Turn staged changes into a precise Conventional Commits message — never a vague "update files".
When this runs
The user wants to commit work that is already (or about to be) staged. Your job is to read the actual diff, understand what changed and why it matters, and emit a message that a future maintainer (or a changelog generator) can rely on.
Procedure
Read what is staged. Run:
git diff --staged --stat git diff --stagedIf nothing is staged, run
git status --short. If there are unstaged changes the user clearly intends to commit, tell them what's unstaged and ask whether togit addit — do not silently stage everything.Classify the change. Pick exactly one type from the diff's dominant intent:
type use for feata new user-facing capability fixa bug fix docsdocumentation only styleformatting, whitespace, no logic change refactorcode change that neither fixes a bug nor adds a feature perfa change that improves performance testadding or correcting tests buildbuild system, dependencies, packaging ciCI configuration and scripts choremaintenance that doesn't touch src or tests revertreverts a previous commit If a single commit genuinely mixes two unrelated types (e.g. a feature and an unrelated fix), recommend splitting it into separate commits and propose the split. Don't paper over it with
chore.Infer a scope (optional but preferred). The scope is the area of the codebase touched — a package, module, or directory (
api,auth,parser,ui). Derive it from the changed paths. Omit it rather than guess wrong.Write the subject line. Format:
type(scope): summary- imperative mood ("add", not "added"/"adds")
- no trailing period
- lower-case after the colon
- ≤ 50 characters for the whole subject; hard ceiling 72
- describe the effect, not the file list ("fix race in token refresh", not "edit auth.ts")
Write the body when the change isn't self-evident. Wrap at 72 columns. Cover why the change was made and any non-obvious consequence. Skip the body for trivial commits (a typo fix needs none).
Footers when applicable:
- Breaking change: a
!after the type/scope (feat(api)!: ...) and aBREAKING CHANGE: <what broke + migration path>footer. - Issue links:
Closes #123,Refs #456.
- Breaking change: a
Present, then commit. Show the full message in a fenced block. Then commit it for real:
git commit -m "subject" -m "body..."Use repeated
-mflags (one per paragraph) so newlines survive — do not embed literal\n. If the user only asked for the message, output the block and stop without committing.
Output shape
feat(parser): support trailing commas in config arrays
Accept a trailing comma after the last element so hand-edited
config files don't fail to load. Matches JSON5 behaviour.
Closes #214
Rules
- Never invent a reason you can't see in the diff. If "why" isn't inferable, write only the what and keep the body short or omit it.
- Never commit unrelated changes together to make the message simpler — propose a split instead.
- Match the repo's existing convention if it already uses something other than Conventional Commits (check
git log --oneline -20). Consistency with history beats the template. - Do not add a
Co-Authored-Byor tool-signature line unless the repo's own convention (or the user) asks for it.