Changelog Generator
Turn raw git history into release notes that customers actually understand.
Overview
Developers write commit messages for developers. Users need something different: clear, benefit-focused descriptions of what changed and why they should care. This skill bridges that gap by reading git commits, categorizing them by impact, and rewriting them in plain language.
Step 1: Determine the commit range
Default (no range specified):
# Find the last tag
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)
if [ -z "$LAST_TAG" ]; then
# No tags yet — use all commits
git log --no-merges --pretty=format:"%H%x09%s%x09%b" --date=short
else
# Commits since last tag
git log ${LAST_TAG}..HEAD --no-merges --pretty=format:"%H%x09%s%x09%b" --date=short
fi
User-specified range: Use whatever the user provides — tag names (v1.2.0..v1.3.0), branches, --since="3 weeks ago", commit hashes, etc.
If there are no commits in the range, say so clearly and stop.
Step 2: Categorize each commit
Always use --no-merges to skip merge commits automatically.
For each commit subject line, determine its category:
Conventional Commits (subject matches type(scope): description or type: description):
| Type |
Category |
feat |
New Features |
fix |
Bug Fixes |
perf |
Improvements |
refactor, style |
Improvements |
docs |
Improvements (only if user-visible, e.g., new guides or API docs) |
chore, ci, build, test |
Improvements (only if meaningful to users, e.g., dependency security update) |
feat!, fix!, or body contains BREAKING CHANGE: |
Breaking Changes |
Free-form commits (no conventional prefix — infer from keywords):
- "add", "added", "implement", "create", "introduce", "new", "support", "enable" → New Features
- "fix", "fixed", "resolve", "bug", "patch", "correct", "crash", "error", "issue", "regression" → Bug Fixes
- "improve", "update", "upgrade", "enhance", "speed", "faster", "refactor", "optimize", "clean", "remove deprecated" → Improvements
- Unclear → Improvements (default)
When to skip a commit entirely: Skip commits that clearly have zero user impact: "rename variable", "add comment to code", "fix typo in internal test name". When in doubt, include it — over-including is safer than silently dropping something that matters.
Step 3: Rewrite for users
This is the most important step. Translate each commit message from developer-speak into language that any user understands.
Goal: A non-technical user reads the entry and knows what changed and how it affects them.
Rewriting principles:
- Lead with the user benefit, not the technical mechanism
- Use active voice, past tense: "Added X", "Fixed Y", "Improved Z"
- Replace internal identifiers (class names, function names, file paths, column names) with feature descriptions
- Remove implementation jargon: "null pointer exception" → "crash", "race condition" → "intermittent issue", "migration" → skip or describe the user-visible effect
- If a change has no elegant user description, describe the effect: perf improvement → "loads faster", dependency update → "improved reliability"
Transformation examples:
| Raw commit |
User-facing note |
fix: resolve NPE in UserService.getUser() when userId null |
Fixed a crash when viewing certain user profiles |
feat: add CSV export to DataTable component |
You can now export any table to CSV with one click |
perf: lazy load feed images using IntersectionObserver |
The feed loads significantly faster, especially on slower connections |
chore(deps): bump postgres driver to 14.2 |
Updated database driver for improved reliability and security |
fix: race condition in auth token refresh |
Fixed an issue where you could be unexpectedly signed out |
Added dark mode support to settings page |
Added dark mode — toggle it in Settings |
Removed legacy onboarding flow |
Simplified the onboarding experience |
Upgrade Node minimum to 18 |
Dropped support for Node.js versions below 18 |
Consolidate related commits: When multiple commits clearly relate to the same user-facing change (e.g., "feat: add dark mode", "fix: dark mode icon color", "perf: dark mode transition speed"), merge them into a single clean entry: "Added dark mode with smooth transitions throughout the app".
Step 4: Format the output
Use this structure:
## What's New in [version or date]
### Breaking Changes
- [What broke, and what users need to do to adapt]
### New Features
- [User-facing description]
### Bug Fixes
- [User-facing description]
### Improvements
- [User-facing description]
Formatting rules:
- Put Breaking Changes first — users need to see these before anything else
- Omit any section that has no entries (don't include an empty "### Improvements" heading)
- Each bullet is 1–2 sentences maximum; longer is rarely better
- No numbering — bullets only
Determine the version header:
- If the user is cutting a named release, use that tag (e.g.,
v1.3.0)
- If noting unreleased/untagged changes, use
Unreleased or today's date
- If you can infer the right semantic version bump from the commit types (patch for fixes only, minor for new features, major for breaking changes), suggest it
Example output:
## What's New in v2.1.0
### New Features
- You can now export any report to PDF directly from the toolbar
- Added two-factor authentication support via authenticator apps
### Bug Fixes
- Fixed a crash when opening settings on accounts created before 2023
- Resolved an issue where email notifications were delayed by up to 30 minutes
### Improvements
- The dashboard now loads noticeably faster on slower connections
- Updated dependencies for improved security
1---2name: changelog-generator3description: Use when the user wants to generate a changelog, release notes, what's new document, or any summary of recent changes for end users. Trigger when the user says things like "generate a changelog", "write release notes", "what changed since the last release", "create a CHANGELOG entry", "summarize recent git commits for users", "write up the changes for v1.2.0", "prepare release documentation", or anything about translating git history into user-facing communication. Also trigger if the user is preparing a GitHub release, writing a What's New page, or asking what went into a release. Use this skill whenever the conversation involves git history and communicating changes to end users.4---56# Changelog Generator78Turn raw git history into release notes that customers actually understand.910## Overview1112Developers write commit messages for developers. Users need something different: clear, benefit-focused descriptions of what changed and why they should care. This skill bridges that gap by reading git commits, categorizing them by impact, and rewriting them in plain language.1314## Step 1: Determine the commit range1516**Default (no range specified):**17```bash18# Find the last tag19LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)2021if [ -z "$LAST_TAG" ]; then22 # No tags yet — use all commits23 git log --no-merges --pretty=format:"%H%x09%s%x09%b" --date=short24else25 # Commits since last tag26 git log ${LAST_TAG}..HEAD --no-merges --pretty=format:"%H%x09%s%x09%b" --date=short27fi28```2930**User-specified range:** Use whatever the user provides — tag names (`v1.2.0..v1.3.0`), branches, `--since="3 weeks ago"`, commit hashes, etc.3132If there are no commits in the range, say so clearly and stop.3334## Step 2: Categorize each commit3536Always use `--no-merges` to skip merge commits automatically.3738For each commit subject line, determine its category:3940**Conventional Commits** (subject matches `type(scope): description` or `type: description`):4142| Type | Category |43|------|----------|44| `feat` | New Features |45| `fix` | Bug Fixes |46| `perf` | Improvements |47| `refactor`, `style` | Improvements |48| `docs` | Improvements (only if user-visible, e.g., new guides or API docs) |49| `chore`, `ci`, `build`, `test` | Improvements (only if meaningful to users, e.g., dependency security update) |50| `feat!`, `fix!`, or body contains `BREAKING CHANGE:` | Breaking Changes |5152**Free-form commits** (no conventional prefix — infer from keywords):53- "add", "added", "implement", "create", "introduce", "new", "support", "enable" → **New Features**54- "fix", "fixed", "resolve", "bug", "patch", "correct", "crash", "error", "issue", "regression" → **Bug Fixes**55- "improve", "update", "upgrade", "enhance", "speed", "faster", "refactor", "optimize", "clean", "remove deprecated" → **Improvements**56- Unclear → **Improvements** (default)5758**When to skip a commit entirely:** Skip commits that clearly have zero user impact: "rename variable", "add comment to code", "fix typo in internal test name". When in doubt, include it — over-including is safer than silently dropping something that matters.5960## Step 3: Rewrite for users6162This is the most important step. Translate each commit message from developer-speak into language that any user understands.6364**Goal:** A non-technical user reads the entry and knows what changed and how it affects them.6566**Rewriting principles:**67- Lead with the user benefit, not the technical mechanism68- Use active voice, past tense: "Added X", "Fixed Y", "Improved Z"69- Replace internal identifiers (class names, function names, file paths, column names) with feature descriptions70- Remove implementation jargon: "null pointer exception" → "crash", "race condition" → "intermittent issue", "migration" → skip or describe the user-visible effect71- If a change has no elegant user description, describe the effect: perf improvement → "loads faster", dependency update → "improved reliability"7273**Transformation examples:**7475| Raw commit | User-facing note |76|-----------|-----------------|77| `fix: resolve NPE in UserService.getUser() when userId null` | Fixed a crash when viewing certain user profiles |78| `feat: add CSV export to DataTable component` | You can now export any table to CSV with one click |79| `perf: lazy load feed images using IntersectionObserver` | The feed loads significantly faster, especially on slower connections |80| `chore(deps): bump postgres driver to 14.2` | Updated database driver for improved reliability and security |81| `fix: race condition in auth token refresh` | Fixed an issue where you could be unexpectedly signed out |82| `Added dark mode support to settings page` | Added dark mode — toggle it in Settings |83| `Removed legacy onboarding flow` | Simplified the onboarding experience |84| `Upgrade Node minimum to 18` | Dropped support for Node.js versions below 18 |8586**Consolidate related commits:** When multiple commits clearly relate to the same user-facing change (e.g., "feat: add dark mode", "fix: dark mode icon color", "perf: dark mode transition speed"), merge them into a single clean entry: "Added dark mode with smooth transitions throughout the app".8788## Step 4: Format the output8990Use this structure:9192```markdown93## What's New in [version or date]9495### Breaking Changes96- [What broke, and what users need to do to adapt]9798### New Features99- [User-facing description]100101### Bug Fixes102- [User-facing description]103104### Improvements105- [User-facing description]106```107108**Formatting rules:**109- Put **Breaking Changes** first — users need to see these before anything else110- Omit any section that has no entries (don't include an empty "### Improvements" heading)111- Each bullet is 1–2 sentences maximum; longer is rarely better112- No numbering — bullets only113114**Determine the version header:**115- If the user is cutting a named release, use that tag (e.g., `v1.3.0`)116- If noting unreleased/untagged changes, use `Unreleased` or today's date117- If you can infer the right semantic version bump from the commit types (patch for fixes only, minor for new features, major for breaking changes), suggest it118119**Example output:**120```markdown121## What's New in v2.1.0122123### New Features124- You can now export any report to PDF directly from the toolbar125- Added two-factor authentication support via authenticator apps126127### Bug Fixes128- Fixed a crash when opening settings on accounts created before 2023129- Resolved an issue where email notifications were delayed by up to 30 minutes130131### Improvements132- The dashboard now loads noticeably faster on slower connections133- Updated dependencies for improved security134```