About conventional-commits
conventional-commits is an agent skill for applying Conventional Commits 1.0.0 to commits, branches, pull requests, and issues. It guides atomic changes and checks proposed messages against both the specification and the actual diff.
Key features
- 01Applies Conventional Commits 1.0.0 formats
- 02Maps change types to the staged diff
- 03Splits work into atomic commits
- 04Checks subjects, bodies, and footers
- 05Preserves tool-generated default messages
Use cases
- 01Writing a commit message for a staged change
- 02Naming a branch, pull request, or issue
- 03Reviewing breaking-change markers and message formatting
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ falcondev-oss/ skills --skill conventional-commitsAfter installing, type/conventional-commitsin Claude Code to confirm it loaded.
Details
From the project READMEConventional Commits
Every commit, branch, PR, and issue you name follows the Conventional Commits 1.0.0 spec exactly. Two rules override anything else: each commit is atomic (one logical change), and you verify the message against the spec and the actual diff before it lands.
Exception — keep tool-generated default messages. Merges and similar auto-generated commits keep their default message (Merge branch ..., Merge pull request ..., Revert ...), never rewritten into a Conventional Commits subject. Many tools identify and filter these by their default prefix, so the prefix must stay intact.
The format
<type>[optional scope][optional !]: <description>
[optional body]
[optional footer(s)]
Types — pick the one that matches what the diff actually does:
| type | use for | SemVer |
|---|---|---|
feat | a new feature | MINOR |
fix | a bug fix | PATCH |
docs | documentation only | — |
style | whitespace, formatting, semicolons; never CSS or visual changes | — |
refactor | code change that neither fixes a bug nor adds a feature | — |
perf | a performance improvement | — |
test | adding or correcting tests | — |
build | build system or dependencies | — |
ci | CI configuration | — |
chore | anything else with no production-code effect | — |
wayfinder | a wayfinder map ticket/issue | — |
spec | a spec (e.g. from a wayfinder map via /to-spec) | — |
CSS, Tailwind classes, and other visual changes are code, never style: use feat for a new look, fix for a visual bug, and refactor for restructured styles with no visible change.
A wayfinder map ticket/issue is always wayfinder, and a spec is always spec — the artifact decides the type, overriding what the change itself does (feat, fix, etc.).
Subject-line rules:
typeis required, lowercase, from the table above.scopeis optional: a noun in parentheses naming the affected section —fix(parser):.!immediately before the colon marks a breaking change (MAJOR) —feat(api)!:.- Exactly one colon and one space, then the description.
description: a concise, imperative summary on the same line as the type, led by substance. The type already carries the verb, so cut any leading verb that only echoes it (feat: add…,fix: fix…) or fills space (give…,make…,update…); keep a verb only when it names how the change happens in a way the type can't (refactor(auth): extract token parser).feat(time-tracking): add shift-derived automatic blocking→feat(time-tracking): shift-derived automatic blockingrefactor(seeder): give duty-plan departments unique shifts→refactor(seeder): unique shifts per duty-plan department
Body & footers (only when the change needs them):
- Body: one blank line after the description, then free-form paragraphs.
- Footers: one blank line after the body. Each footer is
Token: valueorToken #value. The token replaces spaces with-(e.g.Reviewed-by,Refs), exceptBREAKING CHANGE. - Breaking change: either
!in the prefix, or a footerBREAKING CHANGE: <description>— the token must be uppercase (BREAKING-CHANGEis synonymous).
Language:
- Always use american english.
Common presets
Reach for these exact messages when the diff matches — they keep recurring commits consistent:
style: lint— the commit contains only linting/formatting changes (no change to code meaning).build(deps): upgrade deps— a broad dependency update touching multiple packages.build(deps): upgrade <package>— a dependency update scoped to one package, e.g.build(deps): upgrade vitest.
A preset applies only when the staged diff is genuinely just that change; if anything else is bundled in, split it out (see step 2 below) rather than stretching the preset.
Making a commit
-
Survey the whole diff. Run
git statusandgit diff(staged and unstaged). Understand every hunk before writing anything. -
Split into atomic commits. Group the hunks so each planned commit is a single type + scope + intent. A diff that mixes features, fixes, refactors, or unrelated scopes is not atomic — plan one commit per unit. Done when every hunk is assigned to exactly one planned commit and each planned commit is one type/scope/intent.
-
Stage and draft, one commit at a time. Stage only that commit's hunks (
git add <paths>, orgit add -pfor partial files), then draft its message in the format above. -
Verify (below) before committing. Do not run
git commituntil every check passes. -
Commit with the verified message, then return to step 3 for the next planned commit.
Verify
The feedback run. Re-read the drafted message against both the spec and the staged diff. Every item must pass; if one fails, revise the message (or re-split the commit) and run the checklist again.
- Format: matches
<type>[scope][!]: <description>— lowercase type from the table, one colon + one space. - Type matches reality: the type describes what the staged diff does — not
featfor a refactor, notfixfor a new capability, notstylefor CSS or UI changes. - Atomic: the staged diff is one logical change; nothing unrelated is bundled in.
- Description: imperative, concise, true to the change, and led by substance — no leading verb that merely echoes the type or fills space.
- Body/footers (if any): blank-line separated; footer tokens well-formed; any breaking change flagged with
!or an uppercaseBREAKING CHANGE:footer. - Authorship: the attribution footer is exactly the one the Authorship section below asks for, and nothing follows it.
Branches, PRs, and issues
The same type vocabulary and the subject-line rules apply, and each is verified the same way:
- Branch:
<type>/<kebab-case-summary>—feat/user-export,fix/parser-crash. - PR title: an exact Conventional Commits subject line (
<type>[scope][!]: <description>), because it becomes the squash-merge commit. - Issue title:
<type>[scope]: <description>naming the desired change or the bug.
Authorship
Add exactly the attribution footer the harness or user instructions specify.
Commit-message formatting
When committing from a shell, pass each paragraph as a separate -m argument. Ordinary quoted \n remains literal text.
git commit \
-m 'type(scope): summary' \
-m 'Body paragraph.' \
-m 'Closes #123'
For exact formatting, use git commit -F <message-file> with real line breaks.
Before pushing, verify:
git show -s --format=%B HEAD | sed -n l
Completion criterion: every intended line appears separately, with no literal \n.