Bump Version
SkillDev toolsBump a native addon package's version in package.json and write its CHANGELOG.md entry. Defaults to a minor bump. Use before /release.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Bump Version skill
What this skill tells your AI
The instructions your AI receives, as published by tetherto/qvac in packages/ocr-ggml/.agent/skills/bump-version/SKILL.md and read by ahel’s review.
Bump a native addon package's version in package.json and write the matching CHANGELOG.md entry,
so /release can publish it. Defaults to a minor bump.
$ARGUMENTS is <package-name> [major|minor|patch] — the package directory name under packages/,
plus an optional explicit bump level.
Usage
/bump-version llm-llamacpp # minor (default): 0.39.0 -> 0.40.0
/bump-version llm-llamacpp patch # 0.39.0 -> 0.39.1
/bump-version ocr-ggml minor
/bump-version translation-nmtcpp major # never chosen automatically — must be explicit
When to use this skill
Use it when work has merged to main for an addon package and the package still carries the previous
version — i.e. the feature is on main but unreleasable because nothing bumped it. This is the routine
gap that /addon-changelog and /release both refuse to fill:
/addon-changelogwrites the changelog but refuses to bump — it stops with aVERSION BUMP REQUIREDbanner ifpackage.jsonis unchanged vsmain./releasevalidates the bump then stops and tells you to bump first.
Do not use it for:
| Case | Use instead |
|---|---|
SDK/TS pods: sdk, cli, rag, logging, error, ai-sdk-provider | /sdk-changelog |
Back-porting a fix onto a shipped release-* line | /release-patch |
A qvac-fabric bump across all 7 consumers | /rollout-phase-b |
| Publishing an existing bump | /release |
Refusals — stop, do not edit anything
- SDK pods. Their root
CHANGELOG.mdis machine-generated byscripts/sdk/generate-changelog-sdk-pod.cjs(rebuildRootChangelog()); a hand-edit is destroyed on the next generator run. Tell the user to run/sdk-changelogand stop. - Version not higher than npm
latest. Report both numbers and stop. - Working branch is a
release-*branch. That is/release-patchterritory — a release branch must stay a byte-exact copy of its base. Stop. - Package has no
CHANGELOG.md. Ask the user before creating one.
fabric is NOT a refusal. An earlier version of this skill refused it, claiming its release read
packages/fabric/release-notes/v<ver>.md via create-github-release-fabric.yml. That workflow does
not exist and is referenced nowhere; on-merge-fabric.yml passes
changelog-path: packages/fabric/CHANGELOG.md, and that file is current and correctly bracketed.
packages/fabric/release-notes/ holds only a v0.1.0.md leftover and is not the release source.
Treat fabric like any other addon.
Step 1 — Read the real current version
Never trust the local checkout; it is routinely days or thousands of commits behind.
git -C <repo> fetch origin main
git -C <repo> show origin/main:packages/<pkg>/package.json
Read version from that output. Cross-check the published version:
npm view @qvac/<pkg> dist-tags.latest
Expect npm to equal or trail origin/main. If origin/main is already ahead of npm, a bump is
already pending — say so and confirm with the user before adding another.
Step 2 — Find what changed since the last bump
Resolve the previous release tag (see Step 6 — do not guess it from the directory name), then:
git -C <repo> log <prev-tag>..origin/main --oneline -- packages/<pkg>/
If the tag is missing, fall back to the last commit that touched
packages/<pkg>/package.json and diff from there. Harvest PR numbers from the commit subjects
((#1234)) for the ### Pull Requests list, and read the PR titles:
gh pr view <number> --repo tetherto/qvac --json title,body
Drop any PR whose diff does not touch packages/<pkg>/. Read the actual source diff for the
user-visible behaviour — do not paraphrase commit messages, which go stale. (A real example: a merged
commit advertised an opt-in env var that did not exist in the merged code.)
Step 3 — Choose the bump level
Honour an explicit major|minor|patch argument. Otherwise default to minor, and state the
reasoning before editing. The de-facto rule from this repo's history:
| Change | Level |
|---|---|
| New public API, new config key, new supported model, changed default | minor |
| Bug fix only | patch |
qvac-fabric dependency bump | minor for 0.x, major for >=1.0 — see /rollout-phase-b |
| Breaking change | major — never selected automatically |
Never auto-select major. For a package already at major ≥ 1 still default to minor here; a major
bump must be an explicit user decision, passed as the major argument.
translation-nmtcpp is the only current post-1.0 addon (9.0.0). Its history used to be
inconsistent — the same rollout landed as both minor and major — but 8.3.1 → 9.0.0 (#3567), a
dependency-floor alignment with no breaking API change, settled it: post-1.0 packages take the major
on a fabric rollout. /rollout-phase-b codifies that and passes major explicitly, which satisfies
the never-auto-select rule.
Note that for a 0.x package a minor bump is technically the SemVer breaking-change signal; this repo leans on that deliberately, so a minor default is correct rather than conservative.
Print the decision before touching files:
llm-llamacpp: 0.39.0 -> 0.40.0 (minor)
reason: adds new supported finetuning architectures (new accepted config values)
Step 4 — Bump package.json
Edit packages/<pkg>/package.json with the Edit tool, changing only the version field. Nothing
else in that file, and no other file — in particular never vcpkg.json (that is a dependency floor,
not the package version) and never vcpkg-configuration.json's default-registry.baseline.
Step 5 — Write the CHANGELOG entry
Insert at the top of packages/<pkg>/CHANGELOG.md, directly below the preamble and above the previous
version heading. The dominant addon shape:
## [<version>] - <YYYY-MM-DD>
<optional 1-3 sentence intro — worth it for a feature release, skip for a one-line fix>
### Added
- <bullet; backtick identifiers; use -> for transitions; explain why it matters, not just what changed>
### Pull Requests
- [#3509](https://github.com/tetherto/qvac/pull/3509) - <PR title>
Rules:
- The heading must be bracketed — literally
## [0.40.0].## 0.40.0,##[0.40.0]and### [0.40.0]all fail the extractor at.github/actions/verify-changelog-notes/action.yml, whose awk is$0 ~ "^## \\[" version "\\]". This is the single most common way this task goes wrong. - Use the date the bump lands,
YYYY-MM-DD. - Section headings are level-3:
### Added,### Changed,### Fixed. Pick by intent — new capability isAdded, altered behaviour or a dependency bump isChanged, a defect fix isFixed. Do not use the level-2## Features/## Bug Fixesstyle;/addon-changelog's own documentation still shows it, but that documentation is stale and no current addon entry uses it. - The body must be non-empty until the next
^## [, or the extractor errors withChangelog section for version X is empty. ## [Unreleased]blocks exist inocr-ggml,tts-ggmlanddecoder-audio. Insert the new dated entry below the Unreleased block. Do not fold Unreleased content into your version, and do not insert above it — that makes the extractor slice your body off at## [Unreleased]. Precedent: commitdfd1fd7ebonocr-ggml.- Match the file's existing preamble. Some packages have a Keep-a-Changelog + SemVer preamble, some
just
# Changelog. Do not add one that was not there. - If the version documents work someone else merged, describe the merged code, and say so if a commit message contradicts it.
Step 6 — Report what happens next
Look up the git tag by reading repo_name: from .github/workflows/on-merge-<pkg>.yml. Never derive
the tag from the directory name — several are counter-intuitive:
| Package | Tag |
|---|---|
llm-llamacpp | llamacpp-llm-v<ver> (reversed) |
embed-llamacpp | llamacpp-embed-v<ver> (reversed) |
vla-ggml | vla-v<ver> (no -ggml) |
translation-nmtcpp | bare v<ver> |
ocr-ggml | ocr-ggml-v<ver> |
classification-ggml | classification-ggml-v<ver> |
Addons get a git tag only, no GitHub Release — on-merge-<pkg>.yml calls create-release-tag.yml
since #2602. Do not promise a Releases-page entry; only the SDK publishes one.
Then tell the user the next step is /release <pkg>, which cuts release-<pkg>-<version>, dispatches
on-merge-<pkg>.yml, and pauses at the human-only npm approval gate.
Step 7 — Verify before committing
grep -nE "^## \[<version>\]" packages/<pkg>/CHANGELOG.md
git -C <repo> diff --stat origin/main
- The
grepmust match. This is the extractor's own regex — if it does not match, the release fails later, not now. package.jsonversion must equal the heading version exactly.- The diff must show exactly two files:
package.jsonandCHANGELOG.md. Anything else means something was swept in.
Then commit on a branch off origin/main — never on main, never on a release-* branch:
git -C <repo> worktree add -b <TICKET>/bump-<pkg>-<version> <path> origin/main
Commit title follows the repo convention TICKET prefix[tags]: subject, with chore as the prefix
(precedent: chore: bump llm-llamacpp to 0.38.1):
QVAC-12345 chore: bump <pkg> to <version> for <reason>
Add no [api] tag unless the public API or config surface actually changed — widening the set of
accepted values is not an API change. Add no AI signature or Co-Authored-By trailer.
PR body uses the repo's four-section format: problem / how / tested / breaking changes.
What CI actually enforces
Be accurate about this; two in-repo docs are wrong.
For addons, release-merge-guard (.github/actions/release-merge-guard/) asserts exactly three
things:
- the branch matches
release-<slug>-x.y.z; package.jsonversion equals the version in the branch name;CHANGELOG.mdwas modified (skipped on initial branch push and onworkflow_dispatch).
It does not validate the heading text for addons, and no CI check anywhere compares the new
version against the previous one. So a malformed heading will not fail the guard — it fails /release
Step 1, and would fail the release-body extractor for the SDK and the two lib packages that still use
it.
Write the bracketed heading regardless: /release, /addon-changelog, /release-patch and
/release-fabric-consumers all assume it.
Do not copy from ci-validation.mdc:234 (claims the guard checks the heading, and shows an unbracketed
## x.y.z) or from /addon-changelog's level-2 section example. Both are stale.
Bash discipline
Per repo CLAUDE.md: no heredocs, no $() command substitution, no &&/||/; chaining, no pipes or
redirects. Use Read / Write / Edit / Grep / Glob instead of cat / sed / grep / find, and
git -C <path> instead of cd. Put anything longer than a single command in a script file and run
bash <file>.
Error handling
release-merge-guardfails on merge — version not bumped, the branch name does not match the version, orCHANGELOG.mdwas not modified./releaseStep 1 fails — the changelog heading is missing or unbracketed. Fix the heading.- npm publish rejects the version — it already exists. Check
npm view @qvac/<pkg> versionsand pick the next free one. - Never weaken, skip, or delete a test to get a bump through.
Signals
- GitHub stars
- 601
- Forks
- 111
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
bump-version-tetherto- Source
- github.com/tetherto/qvac