Version Bumper
Bump the project version everywhere it lives in one consistent pass — package.json, lockfile, nested/CLI package manifests, version constants, README badges, docs — then roll the changelog's Unreleased section under the new version and stage an annotated git tag. Use when you've already decided the new version (X.Y.Z or a pre-release like -rc.1) and need every artifact updated to the same value without drift, or before cutting a release.
npx agentscamp add skills/version-bumperInstall to ~/.claude/skills/version-bumper/SKILL.md
A skill that bumps the version consistently across every artifact at once. It greps out all the places a version string hides — package.json, lockfile, nested CLI/submodule manifests, constants, badges, docs — sets them to one agreed value, moves the changelog's Unreleased entries under the new version and date, and stages (never runs unprompted) the annotated tag and release commit.
Bumping a version is rarely one line. The number hides in package.json, a lockfile, a nested CLI or submodule manifest, a __version__ constant, a README badge, and a docs install snippet — and any one you miss ships as drift. This skill finds every occurrence, sets them all to a single agreed value, rolls the changelog, and stages the tag. It never picks the version for you and never publishes without your say-so.
When to use this skill
- You've decided the new version (e.g.
2.4.0, or a pre-release2.4.0-rc.1) and need every artifact updated to match in one pass. - You're cutting a release and want the bump commit to be clean, atomic, and correctly tagged.
- A previous bump left drift —
package.jsonsays one version, the lockfile or a badge says another — and you want them reconciled. - You maintain a monorepo or a repo with a bundled CLI sub-package whose versions and dependency ranges must move together.
NOTE
This skill applies a version you've already chosen. If you haven't decided whether the change is major/minor/patch, run a semver analysis first (see semver-advisor) — getting the number right is out of scope here.
Instructions
-
Confirm the exact target version before touching anything. Read the current version from the root
package.json(orpyproject.toml,Cargo.toml, etc.). State the old → new transition explicitly and stop if the new value isn't strictly greater, or if it's malformed. A pre-release identifier (-rc.1,-beta.2,-next.0) is valid and must be carried verbatim into every artifact — do not silently drop it. -
Find every place the version lives. Don't assume — grep. The number leaks into more files than you expect:
OLD="1.2.3" # current version, escaped if it contains dots grep -rnF "$OLD" \ --include='*.json' --include='*.toml' --include='*.md' \ --include='*.ts' --include='*.js' --include='*.py' --include='*.yml' --include='*.yaml' \ --exclude-dir=node_modules --exclude-dir=.git --exclude-dir=dist .Then triage each hit. Update version declarations; never blanket-replace — a
1.2.3in changelog history or a test fixture must stay put. -
Update the canonical manifest(s). Edit the
versionfield in the rootpackage.json. For nested packages (acli/package.json, workspace packages, a submodule manifest), update each one to the same value unless they version independently — confirm which model the repo uses before assuming lockstep. -
Update the lockfile so it doesn't drift. Editing
package.jsonalone leavespackage-lock.json(and thepackages[""].versionentry inside it) stale. Regenerate it deterministically rather than hand-editing:npm install --package-lock-only --ignore-scriptsFor
pnpmusepnpm install --lockfile-only; foryarnrunyarn install --mode update-lockfile. -
Update version constants and human-facing references. Catch the non-manifest spots the grep surfaced: a
VERSION/__version__constant in source, a README shields.io badge (version-1.2.3-→version-2.4.0-), install snippets pinningpkg@1.2.3, and anydocs/page that names the current version. Skip historical mentions (changelog entries, migration notes about old releases). -
Roll the changelog. Move everything under the
## [Unreleased]heading into a new## [X.Y.Z] — YYYY-MM-DDsection dated today, then leave## [Unreleased]empty above it. Update the link-reference footer if the changelog uses compare-URL refs ([X.Y.Z]: …/compare/vOLD...vX.Y.Zand a fresh[Unreleased]: …/compare/vX.Y.Z...HEAD). -
For monorepos, keep interdependent versions and ranges consistent. When package A depends on package B and both bump, update A's dependency range on B (e.g.
"@scope/b": "^2.4.0") so a consumer doesn't resolve a mismatched pair. Verify noworkspace:*range was accidentally pinned to a literal. -
Stage — do not run — the release commit and annotated tag. Print the exact commands and wait for the user. The bump commit must land before the tag points at it; tag from the wrong commit and you've published a tag that doesn't match its tree.
git add -A git commit -m "chore(release): vX.Y.Z" git tag -a vX.Y.Z -m "vX.Y.Z" # push only when asked: git push origin HEAD vX.Y.Z
WARNING
Never run git tag before the bump commit is committed — an annotated tag captures the commit it points to, so a premature tag will reference the previous state, and moving a published tag breaks anyone who already fetched it. Commit first, verify git show HEAD --stat contains the version edits, then tag.
WARNING
A lockfile left at the old version is the single most common bump bug: CI installs, sees package-lock.json disagrees with package.json, and either fails or silently resolves the old version. Always regenerate the lockfile in the same commit as the manifest bump.
Output
Two artifacts, both reviewable before anything is committed:
-
A change table of every file touched, old → new:
File Old New package.json1.2.32.4.0package-lock.json1.2.32.4.0cli/package.json1.2.32.4.0src/version.ts1.2.32.4.0README.md(badge)1.2.32.4.0CHANGELOG.mdUnreleased ## [2.4.0] — 2026-06-17 -
The exact release commands, ready to paste and run only on request:
git add -A git commit -m "chore(release): v2.4.0" git tag -a v2.4.0 -m "v2.4.0" # git push origin HEAD v2.4.0Plus a one-line note of anything skipped on purpose (historical version mentions left untouched) or anything that needs a human decision (a sub-package that may version independently).
Frequently asked questions
- Does this skill decide which version to bump to?
- No. You supply the target version (it already decided semver via /semver-advisor or your judgment). This skill's job is to apply that exact value everywhere consistently, not to pick it.
- Will it commit and push the tag for me?
- Only when you explicitly ask. By default it edits files and prints the exact `git commit` and `git tag -a` commands so you can review the diff first — tagging before the bump commit lands is a common, hard-to-undo mistake.
Related
- Changelog From PRsDraft a release changelog by summarizing merged pull requests since the last tag. Use when preparing a release or writing release notes.
- SemVer AdvisorDecide the correct semantic-version bump — major, minor, or patch — by diffing a release range, mapping the changes onto the public API surface, and classifying each as breaking, additive, or a fix. Use before cutting a release when you are unsure whether changes are breaking, when a teammate proposes a bump you want to sanity-check, or when a behavior change has no signature change and you need to know if it is still breaking.
- Migration WriterWrite a safe, reversible, zero-downtime database migration using expand-contract — add the new shape, backfill in batches, switch reads/writes, then drop the old — so every deploy stays compatible with the running app version. Use when adding or changing schema on a live system, renaming/dropping a column, adding NOT NULL or a foreign key on a large table, or when a migration risks locks, table rewrites, or an unrevertable step.
- Release Notes WriterWrite user-facing release notes — the curated 'what's new and what it means for you' — by starting from the real changes (git log / merged PRs / the changelog since the last release) and translating developer-speak into user impact, grouped by what the user cares about with breaking changes and required actions surfaced first. Use when shipping a release to users or customers and the raw commit log isn't something a user should read, when you need a published GitHub-release / blog / in-app announcement, or when a breaking change must be made unmissable so upgrades don't break.