LLM-Assisted Changelog Generation¶
This guide covers tools and prompts for using LLMs (like Claude) to generate changelogs from git history.
Overview¶
The schangelog CLI includes tools optimized for LLM-assisted workflows:
| Tool | Purpose | Token Savings |
|---|---|---|
parse-commits |
Convert git log to structured output | ~8x reduction (TOON) |
suggest-category |
Classify commits into changelog categories | Consistent mapping |
validate --format |
Rich error output with suggestions | Actionable fixes |
Output Formats¶
All LLM-facing commands default to TOON (Token-Oriented Object Notation) for maximum token efficiency:
| Format | Flag | Description |
|---|---|---|
| TOON | --format=toon (default) |
~40% fewer tokens than JSON |
| JSON | --format=json |
Standard JSON with indentation |
| JSON Compact | --format=json-compact |
Minified JSON |
TOON is a compact, human-readable format optimized for LLM consumption. See toonformat.dev for the specification.
Tools¶
parse-commits¶
Parses git history into structured output optimized for LLM consumption.
# Parse commits since a tag (TOON format, default)
schangelog parse-commits --since=v0.3.0
# Parse commits with JSON output
schangelog parse-commits --since=v0.3.0 --format=json
# Parse commits between versions
schangelog parse-commits --since=v0.2.0 --until=v0.3.0
# Parse last N commits
schangelog parse-commits --last=20
# Exclude file list from output
schangelog parse-commits --since=v0.3.0 --no-files
# Exclude merge commits
schangelog parse-commits --since=v0.3.0 --no-merges
# Mark external contributors (reads maintainers/bots from CHANGELOG.json)
schangelog parse-commits --since=v0.3.0 --changelog=CHANGELOG.json
Output includes:
- Conventional commit parsing (type, scope, subject)
- Breaking change detection (
!orBREAKING CHANGE:) - Issue/PR references extracted from messages
- File statistics (insertions, deletions, files changed)
- Suggested changelog category for each commit
- Summary statistics grouped by type and category
- External contributor marking (with
--changelogflag) - Contributors summary with deduplicated author list
Example TOON output (default):
Repository: github.com/example/project
Range:
Since: v0.3.0
Until: HEAD
CommitCount: 5
Commits[5]{Hash,Author,Date,Type,Scope,Subject,FilesChanged,Insertions,SuggestedCategory}:
abc123d,John Doe,2026-01-04,feat,auth,add OAuth2 support,3,230,Added
def456a,Jane Smith,2026-01-03,fix,,resolve memory leak,1,12,Fixed
Summary:
ByType{feat,fix}:
3,2
BySuggestedCategory{Added,Fixed}:
3,2
Example JSON output (--format=json):
{
"repository": "github.com/example/project",
"range": {
"since": "v0.3.0",
"until": "HEAD",
"commit_count": 5
},
"commits": [
{
"hash": "abc123d",
"author": "John Doe",
"date": "2026-01-04",
"message": "feat(auth): add OAuth2 support",
"type": "feat",
"scope": "auth",
"subject": "add OAuth2 support",
"breaking": false,
"issue": 123,
"files_changed": 3,
"insertions": 230,
"suggested_category": "Added"
}
],
"summary": {
"by_type": { "feat": 3, "fix": 2 },
"by_suggested_category": { "Added": 3, "Fixed": 2 }
}
}
suggest-category¶
Suggests changelog categories for commit messages based on conventional commit types and keywords.
# Single message (TOON format, default)
schangelog suggest-category "feat(auth): add OAuth2 support"
# Single message with JSON output
schangelog suggest-category --format=json "feat(auth): add OAuth2 support"
# Batch mode from stdin
git log --format="%s" v0.3.0..HEAD | schangelog suggest-category --batch
Example TOON output (default):
Input: "feat(auth): add OAuth2 support"
Suggestions[2]{Category,Tier,Confidence,Reasoning}:
Added,core,0.95,Conventional commit type 'feat' indicates new functionality
Security,core,0.6,Feature relates to authentication or security
ConventionalCommit:
Type: feat
Scope: auth
Subject: add OAuth2 support
Breaking: false
Example JSON output (--format=json):
{
"input": "feat(auth): add OAuth2 support",
"suggestions": [
{
"category": "Added",
"tier": "core",
"confidence": 0.95,
"reasoning": "Conventional commit type 'feat' indicates new functionality"
},
{
"category": "Security",
"tier": "core",
"confidence": 0.60,
"reasoning": "Feature relates to authentication or security"
}
],
"conventional_commit": {
"type": "feat",
"scope": "auth",
"subject": "add OAuth2 support"
}
}
Category mapping:
| Commit Type | Category | Tier |
|---|---|---|
feat |
Added | core |
fix |
Fixed | core |
docs |
Documentation | extended |
perf |
Performance | standard |
test |
Tests | extended |
build |
Build | extended |
ci |
Infrastructure | optional |
chore |
Internal | optional |
refactor |
Changed | core |
security |
Security | core |
deps |
Dependencies | standard |
validate --format¶
Validates changelog with rich, actionable error messages.
# TOON output with detailed errors
schangelog validate --format=toon CHANGELOG.json
# JSON output with detailed errors
schangelog validate --format=json CHANGELOG.json
# Strict mode (warnings become errors)
schangelog validate --format=toon --strict CHANGELOG.json
# Require commit hashes on all entries
schangelog validate --format=toon --require-commits CHANGELOG.json
Commit validation:
The --require-commits flag requires commit hashes on all entries, except for categories that are exempt:
highlights— Human-readable summaries not tied to specific commitsupgradeGuide— Documentation/guidance for usersknownIssues— Ongoing issues that may not have a specific commit
Without --require-commits, missing commits generate W005 warnings. With the flag, they become E010 errors.
Example TOON output:
Valid: false
Errors[1]{Code,Severity,Path,Message,Actual,Expected,Suggestion}:
E001,error,releases[0].date,Invalid date format,January 4 2026,YYYY-MM-DD format (ISO 8601),Convert to ISO 8601 format: YYYY-MM-DD
Summary:
ErrorCount: 1
WarningCount: 0
ReleaseCount: 3
EntriesCount: 15
Example JSON output (--format=json):
{
"valid": false,
"errors": [
{
"code": "E001",
"severity": "error",
"path": "releases[0].date",
"message": "Invalid date format",
"actual": "January 4, 2026",
"expected": "YYYY-MM-DD format (ISO 8601)",
"suggestion": "Convert to ISO 8601 format: YYYY-MM-DD",
"documentation": "https://keepachangelog.com/en/1.1.0/#how"
}
],
"warnings": [
{
"code": "W001",
"severity": "warning",
"path": "releases[0].security[0]",
"message": "Security entry missing CVE identifier",
"suggestion": "Add 'cve' field with format CVE-YYYY-NNNNN"
}
],
"summary": {
"error_count": 1,
"warning_count": 1,
"releases_checked": 3,
"entries_checked": 15
}
}
Error codes:
| Code | Description |
|---|---|
| E001 | Invalid date format |
| E002 | Invalid version format |
| E003 | Invalid CVE format |
| E004 | Invalid GHSA format |
| E005 | Invalid severity level |
| E006 | Invalid CVSS score |
| E007 | Invalid IR version |
| E008 | Invalid versioning scheme |
| E009 | Invalid commit convention |
| E010 | Missing commit hash (with --require-commits) |
| E100 | Missing required field |
| E101 | Duplicate version |
| E103 | Empty description |
| W001 | Security entry missing CVE |
| W002 | Description too short |
| W003 | Tier coverage below minimum |
| W004 | Missing severity |
| W005 | Entry missing commit hash |
Example Prompts¶
Use these prompts with Claude or other LLMs to generate changelogs.
Generate a Changelog Release¶
Generate changelog entries for v0.5.0 based on commits since v0.4.0.
1. Run `schangelog parse-commits --since=v0.4.0` to get structured commit data
2. Review the commits and create appropriate CHANGELOG.json entries
3. Group related commits into single entries where appropriate
4. Write descriptions that explain "why" not just "what"
5. Validate with `schangelog validate --format=toon`
Review and Categorize Changes¶
Parse the commits since v0.4.0 and help me categorize them for the changelog.
Use `schangelog parse-commits --since=v0.4.0` and then:
- Group related commits together
- Identify any breaking changes
- Suggest which category each change belongs to
- Flag anything that might need security review
Fix Validation Errors¶
Validate CHANGELOG.json and fix any issues:
1. Run `schangelog validate --format=toon CHANGELOG.json`
2. For each error, apply the suggested fix
3. Re-validate until clean
Complete Release Workflow¶
Help me prepare the v0.5.0 release:
1. Parse commits: `schangelog parse-commits --since=v0.4.0`
2. Create CHANGELOG.json entries for the new version
3. Validate: `schangelog validate --format=toon CHANGELOG.json`
4. Generate markdown: `schangelog generate CHANGELOG.json -o CHANGELOG.md`
5. Summarize what's in the release
Batch Processing¶
I have a backlog of releases to document. For each version tag pair,
parse the commits and generate changelog entries:
- v0.1.0 to v0.2.0
- v0.2.0 to v0.3.0
- v0.3.0 to v0.4.0
Use `schangelog parse-commits --since=<from> --until=<to>` for each range.
Token Efficiency¶
Raw git log output is verbose. The parse-commits tool with TOON format reduces token usage significantly:
| Format | Tokens per Commit | 50 Commits |
|---|---|---|
Raw git log --stat |
~150 | ~7,500 |
| Parsed JSON | ~30 | ~1,500 |
| Parsed TOON | ~18 | ~900 |
| Total Savings | ~8x | ~6,600 tokens |
Use --no-files for further reduction when file lists aren't needed.
Tips¶
- Start with parse-commits — Get structured data before asking the LLM to categorize
- Use TOON format — Default format is optimized for LLM token efficiency
- Use batch mode — Process multiple commits at once with
suggest-category --batch - Validate early — Run
validate --format=toonto catch issues before they accumulate - Trust the suggestions — The category suggestions are accurate for conventional commits (~95%)
- Override when needed — The LLM can apply judgment for ambiguous cases
- Use JSON for debugging — Switch to
--format=jsonwhen you need human-readable output