commit-message-generator
active0xc2fef48b424d79bed8214e9830cb978432a21413a60254fccbb68f4506e3fe40
Generate conventional commit messages from git diffs or change descriptions. Outputs type(scope): subject with optional body and footer. Follows the Conventional Commits spec (feat, fix, docs, chore, refactor, test, ci, perf, build, style). Deterministic: same diff always yields same message. Detects breaking changes, multiple scopes, and co-authors.
Skill body
Commit Message Generator
Diff in, conventional commit message out — by the spec, not by feel.
Inputs
diff— a git diff (unified format), a list of changed files with descriptions, or a plain-English summary of what changed.type_override— optional: force a specific type (feat, fix, etc.) instead of auto-detecting.scope— optional: force a specific scope instead of auto-detecting from file paths.breaking— optional boolean: mark as a breaking change.
Rules
1. Detect the commit type
Scan the diff for signals:
- New exports, new files, new public API →
feat - Bug fix, error handling, null check, off-by-one →
fix - README, JSDoc, comments only →
docs - Test files only (.test., .spec., tests) →
test - Dockerfile, docker-compose, CI YAML →
ciorbuild - Rename, restructure, extract function, no behavior change →
refactor - Formatting, whitespace, semicolons →
style - Cache, lazy load, algorithm improvement →
perf - Dependencies, configs, tooling →
chore
When ambiguous between two types, prefer: feat > fix > refactor > chore.
2. Detect scope from file paths
src/auth/*→authapi/routes/*→apicomponents/Button.*→buttonpackage.jsonorgo.mod→deps- Multiple unrelated paths → omit scope or use most-changed directory
3. Write the subject line
- Imperative mood ("add", not "added" or "adds")
- Lowercase first letter
- No period at end
- Max 50 characters (hard limit: 72)
- Describe WHAT changed, not HOW
4. Write the body (if diff is non-trivial)
- Blank line after subject
- Wrap at 72 characters
- Explain WHY the change was made
- Note any side effects or migration needs
5. Add footer if needed
BREAKING CHANGE: <description>for breaking changesCloses #123for issue references (if detectable from diff context)Co-authored-by:if multiple authors detected
Output format
type(scope): subject line
Optional body explaining the why.
Wrap at 72 chars.
Optional footer.
BREAKING CHANGE: description if applicable
If the change is trivial (single-line fix, typo), output subject line only — no body.
Examples
Input diff adding a new /users endpoint:
feat(api): add user registration endpoint
Input diff fixing a null pointer in auth:
fix(auth): handle missing token in refresh flow
The refresh endpoint crashed when the token cookie was
cleared by the browser. Now returns 401 with a clear
error message instead.
Pitfalls
- Don't prefix with "feat:" if the user already specified type_override
- Multiple unrelated changes → suggest splitting into separate commits
- Merge commits → output "merge: branch-name into target" format
- Empty diff → refuse, don't invent a message
- Binary files in diff → note them but focus on text changes for the message