update-changelog
Version Changelog
Dual-mode skill for changelog lifecycle management. Detects existing systems and adapts.
Quick Reference
| Task | Mode | Details |
|---|---|---|
| First-time setup | Setup | Read setup-workflow.md |
| Update existing changelog | Update | Inline below (the hot path) |
| CHANGELOG.md format | Reference | Read changelog-format-spec.md |
| UI components | Reference | Read ui-component-guide.md |
| Detection algorithm | Reference | Read detection-logic.md |
| Parse CHANGELOG.md → JSON | Script | Run parse-changelog.sh |
| Tags and GitHub Releases | Publish | Approval-gated in Update Mode |
Detection Phase
Run these checks BEFORE choosing a mode. All are read-only.
1. Version source
Check in order, use the first match:
package.json→ read"version"field (Node/JS projects)pyproject.toml→ readversionunder[project]or[tool.poetry]Cargo.toml→ readversionunder[package]VERSIONfile at project root (plain text)- If none found: will create during setup
2. Changelog files
Check for existing changelog data:
CHANGELOG.mdat project rootdocs/CHANGELOG.mdlib/changelog-data.tsxorlib/changelog-data.tslib/changelog-data.jsonorchangelog.json- Any file matching glob
**/changelog-data.*
3. Framework detection (for UI setup)
next.config.*orpackage.jsoncontaining"next"→ Next.jspackage.jsoncontaining"react"→ React (non-Next)package.jsoncontaining"vue"ornuxt.config.*→ Vue/Nuxtpackage.jsoncontaining"svelte"→ SvelteKit- None of the above → CLI/backend project (skip UI components)
4. Existing UI components
- Grep for
changelogincomponents/,src/components/,app/ - Check for version display patterns: grep for
getCurrentVersion,packageJson.version,APP_VERSION
Mode Selection
IF no CHANGELOG.md found AND no structured data file found:
→ SETUP MODE (read references/setup-workflow.md)
ELSE:
→ UPDATE MODE (continue below)
Setup Mode (Summary)
Read references/setup-workflow.md for the complete setup workflow.
High-level steps:
- Create
CHANGELOG.mdat project root using Keep a Changelog format. Populate with initial entry using detected version (or1.0.0). - Create structured data file (web projects only):
lib/changelog-data.tswith typed entries. Use the template from assets/changelog-data-template.ts. - Create UI components (React/Next.js only):
- Changelog modal — adapt assets/changelog-modal.tsx
- Version trigger — adapt assets/changelog-trigger.tsx
- Changelog page route (optional)
- Wire version helper:
getCurrentVersion()reads frompackage.json. - Ask user where to place the version trigger (footer, sidebar, header, settings).
- Commit:
chore: set up changelog system (vX.Y.Z)— stage only the new files.
After setup, immediately offer to run Update Mode if there are existing changes to document.
Update Mode
This is the primary workflow. Follow every step in order.
Step 1: Read current state and release preflight
# Current version
cat package.json | jq -r '.version'
# Recent commits (adjust depth as needed)
git log --oneline -20
# What's changed since last entry
git diff --stat
git status
# Release context
git branch --show-current
git tag --list --sort=-v:refname | head -20
git remote -v
command -v gh >/dev/null && gh auth status
Read the existing changelog file(s) to find the last documented version and its date.
If a structured data file exists (e.g., lib/changelog-data.tsx), read it to understand the entry format:
- Does it use JSX/ReactNode for
content? (e.g.,<div className="prose">...</div>) - Does it use markdown strings for
content? - Does it use a different structure entirely?
Store the detected format. New entries MUST match the existing format exactly.
Check release workflow context before drafting:
- Branch: For release-only version/changelog bumps, recommend
main. If already on a feature branch with the code being released, keep the changelog/version bump on that branch so the merge carries code + release notes together. If not onmainand intent is unclear, ask before writing. - Tags: Detect existing tag style with
git tag --list. If tags usevX.Y.Z, usevX.Y.Z. If tags useX.Y.Z, useX.Y.Z. If there are no tags, ask and recommendvX.Y.Z. - GitHub Release readiness: Note whether
ghexists andgh auth statussucceeds. If not, skip GitHub Release creation unless the user fixes auth/tooling. - Deploy coupling: Look for
.github/workflows/,vercel.json,netlify.toml,fly.toml,render.yaml,railway.json, or package scripts that imply deploy onmain. Ifmainauto-deploys, warn during approval: "Committing this release on main may ship vX.Y.Z to production."
Step 2: Assess scope
Analyze ALL changes since the last changelog entry. This includes:
- Commits since the last entry's date
- Any uncommitted/staged changes in the working tree
- Any populated
[Unreleased]section - Files changed, features added, bugs fixed
Categorize. Default to patch. Only escalate to minor when there is clearly a new, user-facing capability worth announcing. When torn between patch and minor, choose patch.
- Patch (x.x.+1) — the default, and most releases land here. Use for:
- Bug fixes, typo fixes, copy tweaks
- Dependency updates, config adjustments, build tooling changes
- Refactors, cleanup, internal code changes with no user-visible behavior change
- Small UI tweaks, style/layout polish, accessibility fixes
- Performance improvements that don't change behavior
- New internal helpers, small extensions of existing features
- Docs, tests, CI changes
- Minor (x.+1.0) — reserved for genuinely notable new capability. Requires ALL of:
- A new user-facing feature, page, workflow, integration, or public API surface
- Something a user would reasonably see in release notes and say "oh, that's new"
- Not just an extension or polish of an existing feature
- Examples that qualify: a brand-new page/route, a new integration with a third-party service, a new public API endpoint, a new major UI surface (modal/panel/tool) that didn't exist before
- Examples that do NOT qualify (these are patches): adding a button to an existing page, new config option, new CLI flag, new variant of an existing component, extending an existing feature, small new helper function
- Major (+1.0.0) — breaking changes, API redesigns, major rewrites. Rare. Never pick this without explicit user direction.
Tiebreaker: If the change feels "meh, it's just more of what we already do" → patch. If you find yourself justifying why it's minor → it's probably patch.
Step 3: Determine new version
Calculate the new version number based on the scope assessment. Remember: patch is the default. Only pick minor if the Step 2 criteria for minor are clearly met.
Pre-release handling:
- Stable releases are the default. Do not create
-alpha,-beta, or-rcversions unless the user asks or the current version is already a pre-release. - If current version is
1.2.0-beta.1and the work continues that track, recommend incrementing the pre-release number (1.2.0-beta.2) instead of jumping stable. - If current version is
1.2.0-rc.1and the user says it is ready, recommend finalizing to1.2.0. - For
0.xprojects, still use semver shape: patch for fixes, minor for new user-facing capability, major only by explicit direction.
Present your recommendation with rationale. If you picked minor, explicitly justify which Step 2 minor-criterion the change meets — if you can't point to one cleanly, downgrade to patch before presenting.
Current version: 1.15.7
Recommended bump: patch → 1.15.8
Reason: Bug fixes and small UI tweaks, no new user-facing capability
Or, for a minor bump:
Current version: 1.15.7
Recommended bump: minor → 1.16.0
Reason: Adds new /reports page (new user-facing surface) — qualifies as minor under Step 2 criteria
The user may override your recommendation. Accept their choice.
Step 4: Draft the changelog entry
Draft entries for ALL detected changelog targets:
A. CHANGELOG.md entry (always):
## [X.Y.Z] - Month DD, YYYY
### Added
- Add new feature description
### Changed
- Update changed behavior description
### Fixed
- Fix bug description
Use only the categories that apply: Added, Changed, Deprecated, Removed, Fixed, Security.
If CHANGELOG.md has populated [Unreleased] items, promote relevant items into the new version entry and leave a fresh empty ## [Unreleased] above it.
Add traceability only when it helps:
- Prefer issue/PR refs when available:
Fix login redirect (#142). - Use short commit refs only for hard-to-trace changes or when no PR/issue exists:
Fix migration ordering (a1b2c3d). - Do not clutter every line with hashes if the release commit already groups the work clearly.
B. Structured data file entry (if one exists):
Match the EXACT format of existing entries. Examples:
For TSX with JSX content (like LemonNotes lib/changelog-data.tsx):
{
version: "X.Y.Z",
title: "vX.Y.Z: Brief Title",
date: "Month DD, YYYY",
excerpt: "One-sentence summary.",
content: (
<div className="prose dark:prose-invert prose-sm">
<h3>Section</h3>
<ul>
<li>Change description</li>
</ul>
</div>
),
},
For TS with markdown strings:
{
version: "X.Y.Z",
title: "vX.Y.Z: Brief Title",
date: "Month DD, YYYY",
excerpt: "One-sentence summary.",
content: "### Added\n- Feature description\n\n### Fixed\n- Bug fix",
},
Step 5: Present for approval
CRITICAL: This is a hard stop. Do NOT proceed without explicit user approval.
Show the user:
- Version bump:
current → proposed(with bump type) - CHANGELOG.md entry: full formatted text
- Structured data entry: full formatted entry (if applicable)
- Files to be modified: list every file that will change
- Release context: branch recommendation, detected tag style, GitHub Release readiness, and any main auto-deploy warning
Use this friendly approval shape:
I found changes since vX.Y.Z and recommend a patch bump to vX.Y.Z.
Release context:
- Branch: main
- Tags: existing tags use a v-prefix, so I will use vX.Y.Z
- GitHub Release: gh is authenticated
- Deploy: main appears to auto-deploy, so this may ship to production
Proposed changelog:
## [X.Y.Z] - Month DD, YYYY
### Fixed
- Fix ...
Files I will modify:
- package.json
- CHANGELOG.md
Reply "approved" to write and commit this release, or tell me what to change.
Keep it compact. Replace unavailable release context lines with clear status such as GitHub Release: gh is not authenticated, so I will skip release creation unless that is fixed. Omit sections that do not apply, like structured data when there is no structured data file.
Wait for the user to explicitly approve (e.g., "looks good", "approved", "go", "yes", "do it").
If the user requests changes, revise and present again. Loop until approved.
Step 6: Write changes
After approval, execute ALL writes:
A. Bump version in version source file:
package.json: update the"version"field- Other files: update the version string in the appropriate location
B. Prepend to CHANGELOG.md:
- Add the new entry immediately after the
# Changelogheader (or after any intro text) - If
[Unreleased]exists, keep it above the new version entry and make it empty after promoting released items - Preserve all existing entries unchanged
C. Update structured data file (if exists):
- Add the new entry to the TOP of the releases array
- Match exact formatting and indentation of existing entries
- Do not modify any existing entries
Step 7: Commit
# Stage only the modified files — be explicit
git add package.json CHANGELOG.md <structured-data-file-if-exists> <any-other-changed-source-files>
# Commit with version in message
git commit -m "release: vX.Y.Z — <brief title describing the changes>"
Include any source code files that were part of the changes being documented (i.e., if this is a "commit and push" workflow where you also wrote code, stage those files too).
Step 8: Offer approval-gated publish actions
Report what was written:
- Version bumped:
old → new - Files modified: list
- Commit hash: show it
Then offer only the publish actions that are actually available:
- Annotated local tag:
git tag -a <tag> -m "<tag>" - Push tag:
git push origin <tag> - GitHub Release:
gh release create <tag> --notes-file <release-notes-file>
Use the detected tag style. If there are no existing tags and the user has not chosen a style yet, ask before tagging and recommend vX.Y.Z.
For GitHub Releases, first verify the tag exists on the remote; create and push the annotated tag after approval if needed. Then write release notes from the new changelog entry to a temporary file and pass it with --notes-file. Use --notes-from-tag only when the tag message is intentionally the release notes.
Use this post-commit shape:
Release commit created: abc1234
Available publish actions:
- Create annotated local tag vX.Y.Z
- Push tag vX.Y.Z to origin
- Create GitHub Release from the changelog notes
I will not publish anything unless you explicitly approve those actions.
If some actions are unavailable, say why in the same list: Create GitHub Release: unavailable because gh is not authenticated.
Hard stop: Do not create tags, push tags, or create GitHub Releases until the user explicitly approves those publish actions after the commit.
Step 9: Done
After any approved publish actions, report:
- Tag created/pushed, if any
- GitHub Release URL, if created
- Anything skipped because tooling/auth was unavailable
Execution Rules
These rules are non-negotiable. Follow them exactly.
Publish only after approval
- Do NOT push commits as part of this skill
- Do NOT create tags without explicit approval
- Do NOT push tags without explicit approval
- Do NOT create GitHub Releases without explicit approval
- The default workflow stops after the release commit unless the user approves publish actions
Date accuracy
- ALWAYS verify the actual current date before writing entries
- NEVER copy dates from previous entries
- NEVER assume the year — check it
- Format:
Month DD, YYYY(e.g.,April 9, 2026)
Format fidelity
- When updating an existing structured data file, match the EXACT format of existing entries
- Same indentation, same quote style, same field order, same content structure
- If existing entries use JSX with
className="prose dark:prose-invert prose-sm", use that exact pattern - If existing entries use markdown strings, use markdown strings
- Read at least 2 existing entries to confirm the pattern before drafting
Commit message format
- Pattern:
release: vX.Y.Z — <brief description> - The description should summarize the most notable change(s)
- Examples:
release: v1.15.8 — fix audio upload timeout & improve error messagesrelease: v1.16.0 — add project grouping & bulk actionsrelease: v2.0.0 — redesign API with breaking schema changes
Version in structured data must match package.json
- After bumping, verify the version string is identical in ALL locations
package.json,CHANGELOG.md, and the structured data file must all agree
Dual-write guarantee
- If BOTH
CHANGELOG.mdand a structured data file exist, BOTH must be updated - Never update one without the other
- If only
CHANGELOG.mdexists, that's fine — just update it
Handling Edge Cases
"Commit and push" user intent
When a user says "commit and push" in a project with this skill installed, treat it as an Update Mode trigger. Commit the changelog/version only after approval. Do not push commits. After the commit, ask for explicit approval before tag push or GitHub Release publication.
No changes to document
If git log shows no commits since the last changelog entry and there are no uncommitted changes, inform the user: "No changes found since the last changelog entry (vX.Y.Z on Date). Nothing to update."
Version mismatch
If package.json version differs from the latest CHANGELOG.md version, flag it:
"package.json is at vX.Y.Z but the latest changelog entry is vA.B.C. Which should I use as the base?"
Multiple structured data files
If both a .tsx and .json changelog data file exist, update both. Ask the user which is canonical if unclear.
Pre-release ambiguity
If the user requests a pre-release but does not specify the label, ask whether to use alpha, beta, or rc. If a pre-release label already exists, continue that label by default.
Non-JS projects
For Python, Rust, Go, or other projects without package.json:
- Bump version in the appropriate file (
pyproject.toml,Cargo.toml,VERSION) - Skip structured data file and UI component steps
- CHANGELOG.md is the only changelog target
More from jakerains/agentskills
shot-list
Generate professional shot lists from screenplays and scripts. Use when user uploads a screenplay (.fountain, .fdx, .txt, .pdf, .docx) or describes scenes for production planning. Parses scripts to extract scenes, helps determine camera setups, shot types, framing, and movement through collaborative discussion, then generates beautifully formatted PDF shot lists for production. Triggers include requests to create shot lists, plan shots, break down scripts for filming, or organize camera coverage.
27nextjs-pwa
Build Progressive Web Apps with Next.js: service workers, offline support, caching strategies, push notifications, install prompts, and web app manifest. Use when creating PWAs, adding offline capability, configuring service workers, implementing push notifications, handling install prompts, or optimizing PWA performance. Triggers: PWA, progressive web app, service worker, offline, cache strategy, web manifest, push notification, installable app, Serwist, next-pwa, workbox, background sync.
9elevenlabs
Complete ElevenLabs AI audio platform: text-to-speech (TTS), speech-to-text (STT/Scribe), voice cloning, voice design, sound effects, music generation, dubbing, voice changer, voice isolator, and conversational voice agents. Use when working with audio generation, voice synthesis, transcription, audio processing, or building voice-enabled applications. Triggers: generate speech, clone voice, transcribe audio, create sound effects, compose music, dub video, change voice, isolate vocals, build voice agent, ElevenLabs API/SDK/CLI/MCP.
9onnx-webgpu-converter
Convert HuggingFace transformer models to ONNX format for browser inference with Transformers.js and WebGPU. Use when given a HuggingFace model link to convert to ONNX, when setting up optimum-cli for ONNX export, when quantizing models (fp16, q8, q4) for web deployment, when configuring Transformers.js with WebGPU acceleration, or when troubleshooting ONNX conversion errors. Triggers on mentions of ONNX conversion, Transformers.js, WebGPU inference, optimum export, model quantization for browser, or running ML models in the browser.
8skill-seekers
Convert documentation websites, GitHub repositories, and PDFs into Claude AI skills. Use when creating Claude skills from docs, scraping documentation, packaging websites into skills, or converting repos/PDFs to Claude knowledge.
7vercel-workflow
Build durable workflows with Vercel Workflow DevKit using "use workflow" and "use step" directives. Use for long-running tasks, background jobs, AI agents, webhooks, scheduled tasks, retries, and workflow orchestration. Supports Next.js, Vite, Astro, Express, Fastify, Hono, Nitro, Nuxt, SvelteKit.
7