From core
Generate a changelog from git history. Compares tags, branches, or commits to produce a categorized, human-readable changelog. Handles multiple scenarios: what's unreleased on HEAD vs latest tag, tag-to-tag comparisons, staging/RC vs production, or any custom git range. Invoke with /gen-changelog or trigger naturally with phrases like 'what changed since v2.0', 'release notes', 'compare staging to prod', 'what's unreleased'.
How this skill is triggered — by the user, by Claude, or both
Slash command
/core:gen-changelogThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generate a categorized changelog by comparing two points in git history. Works in any repo with any tag naming convention.
Generate a categorized changelog by comparing two points in git history. Works in any repo with any tag naming convention.
| Mode | When to use | Example invocation |
|---|---|---|
| Unreleased (default) | What's on HEAD but not yet tagged | /gen-changelog |
| Tag-to-tag | Compare two specific releases | changelog v2.1.0 vs v2.0.0 |
| Since tag | Everything since a known release | what changed since v1.5.0 |
| Staging vs prod | Pre-release tags against release tags | changelog staging vs prod |
| Custom range | Any two git refs | changelog abc123..def456 |
Run these commands in parallel to understand the repo:
git rev-parse --show-toplevel
git tag -l --sort=-v:refname | head -30
git branch --show-current
git rev-parse --short HEAD
git status --porcelain | head -5
From the output:
v* (semver), rc-*, CalVer (2024.01.15), or something custom. Don't assume any pattern.-rc, -beta, -alpha, rc-, or staging- are pre-release. Everything else is a release tag.git tag -l returns nothing, you'll need the user to provide two refs explicitly.Based on user input, select the mode:
.. or ...) — Custom range modeIf the intent is ambiguous, list the discovered tags and ask the user to pick.
Each mode resolves to a {BASE} and {HEAD}:
# BASE = latest tag
git tag -l --sort=-v:refname | head -1
# HEAD = current HEAD
If no tags exist: tell the user "No tags found. Provide two commit refs to compare, or specify a range like HEAD~20..HEAD."
Both refs come from the user. Verify both tags exist:
git rev-parse --verify <tag1> && git rev-parse --verify <tag2>
Determine chronological order using git log -1 --format=%ai <tag> so BASE is always the older ref.
# BASE = user-specified tag
git rev-parse --verify <tag>
# HEAD = current HEAD
Auto-discover the latest pre-release and release tags:
# Find latest release tag (exclude pre-release patterns)
git tag -l --sort=-v:refname | grep -v -E '(-rc|-beta|-alpha|^rc-|^staging-)' | head -1
# Find latest pre-release tag
git tag -l --sort=-v:refname | grep -E '(-rc|-beta|-alpha|^rc-|^staging-)' | head -1
BASE = latest release tag, HEAD = latest pre-release tag. Confirm both were found, show them to the user, and proceed.
Parse the range directly from user input. Validate both sides exist with git rev-parse --verify.
git log {BASE}..{HEAD} --pretty=format:"%h|%an|%s" --no-merges
git shortlog -sn --no-merges {BASE}..{HEAD}
git diff --stat {BASE}..{HEAD} | tail -1
| Prefix | Category | Heading |
|---|---|---|
feat: feature: | Features | ### Features |
fix: bugfix: | Bug Fixes | ### Bug Fixes |
perf: | Performance | ### Performance |
docs: doc: | Documentation | ### Documentation |
test: tests: | Tests | ### Tests |
refactor: | Refactoring | ### Refactoring |
chore: ci: build: | Maintenance | ### Maintenance |
style: | Style | ### Style |
revert: | Reverts | ### Reverts |
| Everything else | Other | ### Other |
Parsing rules:
^(feat|fix|docs|...)(\\(.*\\))?!?:\\s*! or the body contains BREAKING CHANGE, also add the commit to a Breaking Changes section at the topProduce markdown in this format:
# Changelog
_Generated: YYYY-MM-DD_
## {HEAD_LABEL} vs {BASE_LABEL}
Comparing **{HEAD_REF}** against **{BASE_REF}**
### Breaking Changes
- description (`hash`) - @author
### Features
- description (`hash`) - @author
### Bug Fixes
- description (`hash`) - @author
[...remaining categories with commits...]
---
**Summary:** X commits | Y contributors | Z files changed
**Range:** `git log {BASE}..{HEAD}`
Where:
{HEAD_LABEL} / {BASE_LABEL} are human-readable — e.g., "Unreleased (main)", "v2.1.0", "rc-2024.03.15"CHANGELOG.md at the repo root without askinggit fetch --unshallow or git fetch --tags.git tag -l '*partial*') to help them find the right one.git log {BASE}..{HEAD} -- <path>.npx claudepluginhub trickycdm/tricky-cc-plugins --plugin coreGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.