Changelog
Every invocation creates a versioned release. Gathers commits since the last tag, writes a dated release entry in CHANGELOG.md, commits, tags, and pushes. Follows Keep a Changelog format and Conventional Commits conventions.
Step 1: Pre-Flight Checks
git status --porcelain must return empty (CHANGELOG.md exempt). If dirty, abort and tell the user to commit or stash first.
git fetch origin
- Branch not behind remote:
git rev-list --count HEAD..origin/$(git branch --show-current). If behind, abort and tell the user to pull first.
Step 2: Determine Version
If $ARGUMENTS contains a version (e.g., v1.2.0), use it directly.
Otherwise, auto-detect from commits since the last tag:
git tag --sort=-v:refname | head -1
If no tags exist, treat the current version as 0.0.0.
Scan commits: git log --pretty=format:"%s%n%b" <last-tag>..HEAD. Apply the highest-priority rule:
| Priority |
Signal |
Bump |
| 1 |
Breaking change — BREAKING CHANGE in body/footer, or type! suffix (feat!, fix!) |
Major |
| 2 |
New feature — feat or feat(scope) prefix |
Minor |
| 3 |
Bug fix or improvement — fix, perf, or other included types |
Patch |
If all commits were filtered (docs, test, ci, chore only), report "No release needed" and stop.
Report the detected version before continuing:
Next version: X.Y.Z (bump — reason)
Commits since vCURRENT: N total (N included, N filtered)
Step 3: Check No Duplicate Tag
git tag -l vX.Y.Z. If the tag already exists, abort and report the conflict.
Step 4: Gather and Categorize Commits
- Get all commits since the last tag:
git log --oneline <last-tag>..HEAD
- Categorize using the mapping below.
- Filter noise: always drop merge commits,
ci:, chore:, test:, docs:, and style: commits. For refactor: commits, include only when the diff touches a public API, CLI flag, configuration schema, or user-facing output; otherwise drop.
- Translate technical commits to user-friendly descriptions.
Step 5: Write Release Entry
- If no CHANGELOG.md exists, create one with a header and footer links (detect remote URL with
git remote get-url origin).
- If CHANGELOG.md exists, read it and preserve all existing content.
- Add a new versioned section
## [X.Y.Z] - YYYY-MM-DD with today's date, placed above existing version sections.
- Remove any existing Unreleased section and its footer link.
- Update footer comparison links.
- Verify: Entry count matches categorized commit count (minus filtered).
Step 6: Commit, Tag, Push
git add CHANGELOG.md
git commit -m "Release vX.Y.Z"
git tag -a vX.Y.Z -m "Release vX.Y.Z - <one-line summary of changes>"
git push --follow-tags
- Verify:
git ls-remote --tags origin | grep vX.Y.Z and report the version, tag, and commit hash.
Commit Categorization
Map Conventional Commits prefixes to Keep a Changelog sections. See references/changelog_format.md for the full mapping, writing style, and anti-patterns.
| Commit Prefix |
Changelog Section |
feat: |
Added |
fix: |
Fixed |
refactor: (user-visible) |
Changed |
security: |
Security |
docs:, test:, ci:, chore: |
Filter out |
Always include: features, user-facing bug fixes, breaking changes, security fixes.
Always filter: merge commits, internal refactors, test changes, CI config, typos.
Translate technical commits to user-friendly language:
fix(auth): resolve JWT expiry edge case -> "Fixed session timeout issues for long-running sessions"
feat(api): add /users endpoint -> "Added user management API endpoints"
Git Analysis Commands
# All commits since last tag
git log --oneline $(git describe --tags --abbrev=0 2>/dev/null || echo "")..HEAD
# Commits between tags
git log --oneline v1.0.0..v1.1.0
# Current tags
git tag --sort=-v:refname | head -10
Output Format
# Changelog
All notable changes to this project will be documented in this file.
## [1.1.0] - 2026-02-13
### Added
- New feature description
### Changed
- Modified behavior description
### Fixed
- Bug fix description
## [1.0.0] - 2026-02-01
### Added
- Initial release features
[1.1.0]: https://github.com/owner/repo/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/owner/repo/releases/tag/v1.0.0
Examples
References
| File |
Content |
references/changelog_format.md |
Full Keep a Changelog spec, Conventional Commits mapping, writing style guide, anti-patterns, release workflow reference, complete example |
1---2name: changelog3description: Generates changelogs and creates tagged releases. Use when updating changelogs, preparing releases, or tagging versions.4license: MIT5---67# Changelog89Every invocation creates a versioned release. Gathers commits since the last tag, writes a dated release entry in CHANGELOG.md, commits, tags, and pushes. Follows Keep a Changelog format and Conventional Commits conventions.1011<instructions>1213## Step 1: Pre-Flight Checks14151. `git status --porcelain` must return empty (CHANGELOG.md exempt). If dirty, abort and tell the user to commit or stash first.162. `git fetch origin`173. Branch not behind remote: `git rev-list --count HEAD..origin/$(git branch --show-current)`. If behind, abort and tell the user to pull first.1819## Step 2: Determine Version2021If `$ARGUMENTS` contains a version (e.g., `v1.2.0`), use it directly.2223Otherwise, auto-detect from commits since the last tag:2425```bash26git tag --sort=-v:refname | head -127```2829If no tags exist, treat the current version as `0.0.0`.3031Scan commits: `git log --pretty=format:"%s%n%b" <last-tag>..HEAD`. Apply the highest-priority rule:3233| Priority | Signal | Bump |34|----------|--------|------|35| 1 | Breaking change — BREAKING CHANGE in body/footer, or type! suffix (feat!, fix!) | Major |36| 2 | New feature — feat or feat(scope) prefix | Minor |37| 3 | Bug fix or improvement — fix, perf, or other included types | Patch |3839If all commits were filtered (docs, test, ci, chore only), report "No release needed" and stop.4041Report the detected version before continuing:4243```44Next version: X.Y.Z (bump — reason)45Commits since vCURRENT: N total (N included, N filtered)46```4748## Step 3: Check No Duplicate Tag4950`git tag -l vX.Y.Z`. If the tag already exists, abort and report the conflict.5152## Step 4: Gather and Categorize Commits53541. Get all commits since the last tag: `git log --oneline <last-tag>..HEAD`552. Categorize using the mapping below.563. Filter noise: always drop merge commits, `ci:`, `chore:`, `test:`, `docs:`, and `style:` commits. For `refactor:` commits, include only when the diff touches a public API, CLI flag, configuration schema, or user-facing output; otherwise drop.574. Translate technical commits to user-friendly descriptions.5859## Step 5: Write Release Entry60611. If no CHANGELOG.md exists, create one with a header and footer links (detect remote URL with `git remote get-url origin`).622. If CHANGELOG.md exists, read it and preserve all existing content.633. Add a new versioned section `## [X.Y.Z] - YYYY-MM-DD` with today's date, placed above existing version sections.644. Remove any existing Unreleased section and its footer link.655. Update footer comparison links.666. **Verify:** Entry count matches categorized commit count (minus filtered).6768## Step 6: Commit, Tag, Push69701. `git add CHANGELOG.md`712. `git commit -m "Release vX.Y.Z"`723. `git tag -a vX.Y.Z -m "Release vX.Y.Z - <one-line summary of changes>"`734. `git push --follow-tags`745. **Verify:** `git ls-remote --tags origin | grep vX.Y.Z` and report the version, tag, and commit hash.7576---7778## Commit Categorization7980Map Conventional Commits prefixes to Keep a Changelog sections. See `references/changelog_format.md` for the full mapping, writing style, and anti-patterns.8182| Commit Prefix | Changelog Section |83|---------------|-------------------|84| `feat:` | Added |85| `fix:` | Fixed |86| `refactor:` (user-visible) | Changed |87| `security:` | Security |88| `docs:`, `test:`, `ci:`, `chore:` | Filter out |8990**Always include:** features, user-facing bug fixes, breaking changes, security fixes.91**Always filter:** merge commits, internal refactors, test changes, CI config, typos.9293Translate technical commits to user-friendly language:94- `fix(auth): resolve JWT expiry edge case` -> "Fixed session timeout issues for long-running sessions"95- `feat(api): add /users endpoint` -> "Added user management API endpoints"9697## Git Analysis Commands9899```bash100# All commits since last tag101git log --oneline $(git describe --tags --abbrev=0 2>/dev/null || echo "")..HEAD102103# Commits between tags104git log --oneline v1.0.0..v1.1.0105106# Current tags107git tag --sort=-v:refname | head -10108```109110</instructions>111112<formatting>113114## Output Format115116```markdown117# Changelog118119All notable changes to this project will be documented in this file.120121## [1.1.0] - 2026-02-13122123### Added124- New feature description125126### Changed127- Modified behavior description128129### Fixed130- Bug fix description131132## [1.0.0] - 2026-02-01133134### Added135- Initial release features136137[1.1.0]: https://github.com/owner/repo/compare/v1.0.0...v1.1.0138[1.0.0]: https://github.com/owner/repo/releases/tag/v1.0.0139```140141</formatting>142143## Examples144145<example>146**User request**: `/changelog` (no arguments, first time)147**Action**: No CHANGELOG.md. Create from full git history. Auto-detect version as v0.1.0.148**Steps**:1491. Auto-detect: v0.1.0 (patch — first release with features)1502. Generate CHANGELOG.md with `## [0.1.0] - 2026-02-13`1513. `git add CHANGELOG.md`1524. `git commit -m "Release v0.1.0"`1535. `git tag -a v0.1.0 -m "Release v0.1.0 - Initial release"`1546. `git push --follow-tags`155**Output**: Released v0.1.0, tagged, and pushed.156</example>157158<example>159**User request**: `/changelog` (existing CHANGELOG.md, new commits since last tag)160**Action**: Auto-detect version. Write versioned entry. Commit, tag, push.161**Steps**:1621. Auto-detect: v1.3.0 (minor — new feature commits detected)1632. Write `## [1.3.0] - 2026-02-13` entry to CHANGELOG.md1643. `git add CHANGELOG.md`1654. `git commit -m "Release v1.3.0"`1665. `git tag -a v1.3.0 -m "Release v1.3.0 - Dark mode and CSV export"`1676. `git push --follow-tags`168**Output**: Released v1.3.0, tagged, and pushed.169</example>170171<example>172**User request**: `/changelog v2.0.0` (explicit version)173**Action**: Use provided version. Write versioned entry. Commit, tag, push.174**Steps**:1751. Version: v2.0.0 (explicit, skip auto-detection)1762. Write `## [2.0.0] - 2026-02-13` entry1773. `git add CHANGELOG.md`1784. `git commit -m "Release v2.0.0"`1795. `git tag -a v2.0.0 -m "Release v2.0.0 - Complete API redesign"`1806. `git push --follow-tags`181**Output**: Released v2.0.0, tagged, and pushed.182</example>183184<example>185**User request**: `/changelog` (no new commits since last tag)186**Action**: All commits filtered. No release needed.187**Output**: No release needed. All commits since v1.3.0 are docs/test/CI changes.188</example>189190## References191192| File | Content |193|------|---------|194| `references/changelog_format.md` | Full Keep a Changelog spec, Conventional Commits mapping, writing style guide, anti-patterns, release workflow reference, complete example |