Conventional Commit
Goal
Analyze staged changes and generate a commit message following the Conventional Commits specification, adapted to project conventions when they exist.
Inputs you must collect before starting
| Input |
Required |
How to obtain |
| Staged changes |
Yes |
git diff --staged |
| Project conventions |
No |
Check commitlint config, CLAUDE.md, CONTRIBUTING.md |
| Type, scope, or intent |
No |
Ask the user if not clear from the diff |
Procedure
Step 1 — Check staged changes
Run git diff --staged. If empty, inform the user there are no staged changes and offer help with git add.
Step 2 — Summary of changed files
Run git diff --staged --stat for a summary of modified, added, or removed files.
Step 3 — Check project conventions
Look for project-specific commit configurations:
.commitlintrc, .commitlintrc.json, .commitlintrc.yml, commitlint.config.js, commitlint.config.ts
commitlint section in package.json
CONTRIBUTING.md, CLAUDE.md
- Recent commit history:
git log --oneline -5
If found, project conventions take precedence over default rules.
Step 4 — Analyze the diff
Read the full diff and identify:
- What was added, removed, or modified
- The intent behind the changes (new feature, bug fix, refactor, etc.)
- Which areas of the codebase were affected
Step 5 — Determine the commit type
Choose the appropriate type:
| Type |
When to use |
feat |
New feature for the user |
fix |
Bug fix |
refactor |
Code restructuring without changing behavior |
perf |
Performance improvement |
style |
Formatting, whitespace, semicolons (no logic change) |
test |
Adding or fixing tests |
docs |
Documentation only |
build |
Build system, external dependencies |
ci |
CI/CD configuration |
chore |
Maintenance tasks that don't fit other types |
Step 6 — Determine the scope (optional)
Identify scope from the area of the codebase affected. Examples: auth, api, ui, db, config. Use scope only if it adds clarity.
Step 7 — Compose the message
Format:
<type>(<scope>): <description>
<optional body>
<optional footer>
Description (subject line) rules:
- Maximum 72 characters
- Imperative mood ("add", not "added" or "adds")
- Lowercase first letter
- No period at the end
Body rules (only when needed):
- Default to no body. Most commits should be subject-only. Add a body only if the "why" is non-obvious from subject + diff (hidden constraint, surprising trade-off, non-local consequence).
- Hard cap: ≤ 4 lines, ≤ 300 characters total, single paragraph. If you need more, split into multiple commits.
- Wrap at 72 characters, separated from the description by a blank line.
- Explain the "why", not the "what". The diff already shows what changed — do not narrate it.
- Forbidden patterns: per-file or per-section enumeration ("Three changes:", "- File A now does X", "- File B now does Y"); restating the subject in prose; describing code structure ("the function now branches on..."); meta-commentary ("Result:", "Confirma?"); trailing questions.
- Bullets allowed only when listing 3+ genuinely independent concerns that share one "why". If you can write one sentence instead, do.
Footer rules (when applicable):
BREAKING CHANGE: <description> for backward-incompatible changes
Refs: #<number> to reference issues or PRs
Step 8 — Present and confirm
- Present the message in a code block
- Wait for user approval
- After approval, execute
git commit with the message
Constraints
- Follow the Conventional Commits spec strictly
- Never invent changes — only describe what the diff shows
- Subject line must be at most 72 characters, imperative mood, lowercase, no period
- Default to subject-only. A body is the exception, not the rule. When unsure, omit it.
- Body, if present, must be ≤ 4 lines and ≤ 350 characters, wrap at 72, separated by a blank line
- Never enumerate files or sections in the body — the diff is the enumeration
- Never end the body with a question or confirmation prompt; the confirmation lives outside the message
- Project conventions take precedence
- Include
BREAKING CHANGE: in the footer when the change breaks backward compatibility
- Reference issues/PRs in the footer when the user mentions them
- Never commit without explicit user approval
- Never include the AI agent (Claude, Codex, etc.) in the commit message
- Never include co-authorship in the commit message
Output format
Present the commit message in a code block followed by a confirmation prompt. See examples in EXAMPLE.md.
Example request
- "Commit my changes"
- "Create a commit for the login fix"
- "Commit these changes as a feat"
- "Commit with scope api"
1---2name: github-commit3description: Generate Conventional Commit from staged diff. Triggers: 'commit', 'create commit', 'commit message'.4---56# Conventional Commit78## Goal910Analyze staged changes and generate a commit message following the [Conventional Commits](https://www.conventionalcommits.org/) specification, adapted to project conventions when they exist.1112## Inputs you must collect before starting1314| Input | Required | How to obtain |15| :--- | :--- | :--- |16| Staged changes | Yes | `git diff --staged` |17| Project conventions | No | Check commitlint config, CLAUDE.md, CONTRIBUTING.md |18| Type, scope, or intent | No | Ask the user if not clear from the diff |1920## Procedure2122### Step 1 — Check staged changes2324Run `git diff --staged`. If empty, inform the user there are no staged changes and offer help with `git add`.2526### Step 2 — Summary of changed files2728Run `git diff --staged --stat` for a summary of modified, added, or removed files.2930### Step 3 — Check project conventions3132Look for project-specific commit configurations:3334- `.commitlintrc`, `.commitlintrc.json`, `.commitlintrc.yml`, `commitlint.config.js`, `commitlint.config.ts`35- `commitlint` section in `package.json`36- `CONTRIBUTING.md`, `CLAUDE.md`37- Recent commit history: `git log --oneline -5`3839If found, project conventions take precedence over default rules.4041### Step 4 — Analyze the diff4243Read the full diff and identify:4445- What was added, removed, or modified46- The intent behind the changes (new feature, bug fix, refactor, etc.)47- Which areas of the codebase were affected4849### Step 5 — Determine the commit type5051Choose the appropriate type:5253| Type | When to use |54| :--- | :--- |55| `feat` | New feature for the user |56| `fix` | Bug fix |57| `refactor` | Code restructuring without changing behavior |58| `perf` | Performance improvement |59| `style` | Formatting, whitespace, semicolons (no logic change) |60| `test` | Adding or fixing tests |61| `docs` | Documentation only |62| `build` | Build system, external dependencies |63| `ci` | CI/CD configuration |64| `chore` | Maintenance tasks that don't fit other types |6566### Step 6 — Determine the scope (optional)6768Identify scope from the area of the codebase affected. Examples: `auth`, `api`, `ui`, `db`, `config`. Use scope only if it adds clarity.6970### Step 7 — Compose the message7172Format:7374```bash7576<type>(<scope>): <description>7778<optional body>7980<optional footer>81```8283**Description** (subject line) rules:8485- Maximum 72 characters86- Imperative mood ("add", not "added" or "adds")87- Lowercase first letter88- No period at the end8990**Body** rules (only when needed):9192- **Default to no body.** Most commits should be subject-only. Add a body only if the "why" is non-obvious from subject + diff (hidden constraint, surprising trade-off, non-local consequence).93- Hard cap: **≤ 4 lines, ≤ 300 characters total**, single paragraph. If you need more, split into multiple commits.94- Wrap at 72 characters, separated from the description by a blank line.95- Explain the "why", not the "what". The diff already shows what changed — do not narrate it.96- **Forbidden patterns:** per-file or per-section enumeration ("Three changes:", "- File A now does X", "- File B now does Y"); restating the subject in prose; describing code structure ("the function now branches on..."); meta-commentary ("Result:", "Confirma?"); trailing questions.97- Bullets allowed **only** when listing 3+ genuinely independent concerns that share one "why". If you can write one sentence instead, do.9899**Footer** rules (when applicable):100101- `BREAKING CHANGE: <description>` for backward-incompatible changes102- `Refs: #<number>` to reference issues or PRs103104### Step 8 — Present and confirm1051061. Present the message in a code block1072. Wait for user approval1083. After approval, execute `git commit` with the message109110## Constraints111112- Follow the Conventional Commits spec strictly113- Never invent changes — only describe what the diff shows114- Subject line must be at most 72 characters, imperative mood, lowercase, no period115- **Default to subject-only.** A body is the exception, not the rule. When unsure, omit it.116- Body, if present, must be ≤ 4 lines and ≤ 350 characters, wrap at 72, separated by a blank line117- Never enumerate files or sections in the body — the diff is the enumeration118- Never end the body with a question or confirmation prompt; the confirmation lives outside the message119- Project conventions take precedence120- Include `BREAKING CHANGE:` in the footer when the change breaks backward compatibility121- Reference issues/PRs in the footer when the user mentions them122- Never commit without explicit user approval123- Never include the AI agent (Claude, Codex, etc.) in the commit message124- Never include co-authorship in the commit message125126## Output format127128Present the commit message in a code block followed by a confirmation prompt. See examples in [`EXAMPLE.md`](./EXAMPLE.md).129130## Example request131132- "Commit my changes"133- "Create a commit for the login fix"134- "Commit these changes as a feat"135- "Commit with scope api"