Developer pack
Claude Skill
Commit Message Writer
Generates conventional commit messages from staged changes — subject + body, why-not-what.
What it does
Reads a diff (typically `git diff --cached`) and produces a conventional-commit subject line plus a short body explaining the WHY. Refuses to write "update files" or "fix stuff" — pushes the user to articulate the change's purpose, not just its mechanics.
When to use
- ✓You have staged changes and want a clean, conventional message
- ✓You're squashing a branch and need one good message instead of "wip", "wip2", "fix"
- ✓You want to keep `git log` actually readable
When not to use
- ✗WIP commits on a personal branch you'll squash anyway — message hygiene doesn't matter yet
- ✗You don't know what your own change does — figure that out first
Install
Download the .zip, then unzip into your Claude skills folder.
mkdir -p ~/.claude/skills
unzip ~/Downloads/commit-message-writer.zip -d ~/.claude/skills/
# Restart Claude Code session.
# Skill is now available — Claude will use it when relevant.SKILL.md
SKILL.md
---
name: commit-message-writer
description: Use when writing a commit message from a staged diff or condensing a branch into one message. Triggers on "commit message", "git commit message", "conventional commit", or pasted `git diff --cached` output.
---
# Commit Message Writer
Most commits in `git log` are noise. The few that aren't share three traits: they describe the WHY (not the WHAT), they're scannable in one line, and the body fills in just enough context to make the change self-explanatory in 6 months.
## Required inputs
1. **The diff** — `git diff --cached` or equivalent
2. **The reason** — what user/system problem this solves; if not obvious from the diff, ask
3. **Linked issue** — Jira / Linear / GitHub issue if any
If the diff is mechanical (config bump, dependency update) the reason can be terse. For behavior changes, the reason should be in the body.
## Format (Conventional Commits)
```
<type>(<scope>): <subject>
<body — wrap at 72 chars>
<footer — refs, breaking change notes>
```
### Types
- `feat` — new user-visible feature
- `fix` — bug fix
- `refactor` — internal restructure, no behavior change
- `perf` — performance improvement
- `docs` — docs only
- `test` — tests only
- `build` — build system, dependencies
- `ci` — CI config
- `chore` — tooling, config; nothing user-visible
- `revert` — reverts a prior commit
### Scope
Project-specific. Common: a service name, package name, top-level directory.
### Subject line rules
- 50 chars target, 72 max
- Imperative mood: "add", "fix", "update" — NOT "added", "fixes", "updating"
- No trailing period
- Lowercase after the type prefix unless naming a proper noun
GOOD: `fix(checkout): retry idempotency lookup on transient ECONNRESET`
BAD: `Fix: Fixed some issues with the checkout.`
### Body
Skip the body for trivial commits. Include it when the diff doesn't tell the whole story:
- WHY this change (1-2 sentences)
- What was considered and rejected (if non-obvious)
- Any caveat the future reader needs (deferred work, related TODOs)
- "Closes #123" or "Refs PROJ-456" in footer
The body answers the question: why did this change become necessary?
## Anti-patterns to refuse
If the user asks for a commit message and the change is just "update files" or "various fixes," push back:
- "What problem does this solve?"
- "Is this a bug fix, a feature, or a refactor? They get different prefixes."
Reject these subject lines on sight:
- `update X` (update HOW)
- `fix bug` (which bug?)
- `misc changes` (split the commit)
- `wip` (squash before merging)
- `address review feedback` (squash into the original commit)
## Examples
```
feat(auth): add refresh token rotation
Implements rotating refresh tokens per RFC 6749 §10.4. Old refresh
token is invalidated on use; reuse triggers session revocation across
all devices for that user.
Closes PROJ-2031.
```
```
fix(checkout): release DB connection on early-return path
If the cart was empty we returned 200 before releasing the pooled
connection, slowly leaking pool capacity. Reproduced under k6 load
at 50rps; pool exhausted in ~12 minutes.
```
```
refactor(billing): extract pricing calc into pure function
No behavior change. Prep for the tiered-pricing work in PROJ-2099.
```
## Squash guidance
When condensing a branch:
- Pick the type and scope of the meaningful change (ignore WIP / fixup commits)
- Subject describes the OUTCOME of the branch, not the journey
- Body can list the 2-3 substantial pieces if the change is multi-part
- Drop the per-commit nitty-gritty; `git log` shouldn't read like a diary
## Output
Return the message in a single fenced code block ready for `git commit -m` or `git commit -F`. If the change has multiple logical parts, suggest splitting into multiple commits before writing the message.
Example prompts
Once installed, try these prompts in Claude:
- Write a commit message for this staged diff. [paste git diff --cached]
- Squash these 6 commits into one good message. [paste git log of branch]