agentsclimarketplace

Version bump

Skill bostonaholic/team/.claude/skills/version-bump

Version the Team plugin at land time (DEV-internal, not distributed): decide the SemVer level, compute the next free version against current `main`, update all five version strings, cut the `[Unreleased]` changelog body into a dated `## [X.Y.Z]` section, run the land-time consistency assertion, and commit `chore(version): X.Y.Z`. This is the Team-internal bumper; the generic runtime `/shipit` skill then pushes, waits for CI, and squash-merges. Use when landing a Team PR, or when the user asks to "bump the version" or "version this PR".From its SKILL.md

Install
npx -y skills add bostonaholic/team --skill version-bump

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

10.0 KB, ~2.6k tokens by cl100k_base, as published. Nobody here has run it

Version Bump — version a Team PR at land time

Follow skills/progress-tracking/SKILL.md: this procedure has more than two steps — seed one todo item per step below before starting and mark each complete as you go.

This skill versions the Team plugin itself at land time. It is dev-only (lives under .claude/, never distributed to plugin users). Tagging and the GitHub release are not part of this procedure — release-on-merge.yml does both automatically when the PR merges. Full policy: docs/versioning.md.

The dev land process

Landing a Team PR is two steps, in order:

  1. Bump (this skill). Run version-bump against current main. It picks the level, assigns the next free version, and bumps the five version strings. It cuts the [Unreleased] changelog into a dated ## [X.Y.Z] section, runs the land-time consistency assertion, and commits chore(version): X.Y.Z.
  2. Land (the generic /shipit skill). Run the distributed runtime /shipit skill to push the branch, wait for CI, and squash-merge. shipit is project-agnostic — it does no versioning. This skill is the Team-internal bumper it composes with.

Run this skill before /shipit, against the version of main you intend to land onto.

The bump is conditional, not universal. Step 0 below decides if this PR warrants a bump at all. Only PRs that change the distributed plugin bump. A dev-only PR (CI, docs, tests, evals, .claude/ tooling) lands with no bump and no changelog cut. Run step 0, see it say "no bump", and go straight to /shipit with the plain conventional title.

Steps

0. Runtime-vs-dev gate — does this PR warrant a bump at all?

Run this before everything else. Most steps below only apply if it says yes.

The version, changelog, and GitHub release exist for plugin end users — people who install Team and run /team. They are driven only by changes to the distributed plugin. Contributor-facing / plugin-developer infrastructure does not move the version, no matter what conventional-commit type it carries.

Using the Runtime vs. Development split in CLAUDE.md:

  • Runtime (bump-worthy): agents/, skills/, hooks/, and host manifest content.claude-plugin/, .codex-plugin/, .agents/plugins/ — meaning a real change to a manifest, not the bare "version" field. Every host's manifest ships to that host's end users, so a Codex-only manifest change is as much a runtime change as a Claude Code one.
  • Development (never bumps): .github/, .claude/, docs/, tests/, evals/, package.json/bun.lock tooling — everything that only validates or builds the plugin.

Check what this PR actually changed:

.github/scripts/version-bump-required.sh   # HEAD_SHA/BASE_SHA from the PR; deterministic gate
# or, locally, just look:
git diff origin/main...HEAD --name-only
  • No runtime files changed → DO NOT BUMP. Skip every step below. Leave the version untouched, do not cut the changelog, and land with the plain conventional title (<type>: <subject>). Precedent: 710d44c (CI), 7d2e218 (docs), 0821129 (evals feat:) all landed plain. Then go straight to /shipit.
  • Runtime files changed → continue to step 1.

This is a hard gate, not a judgment call. The same check runs deterministically in CI, through .github/scripts/version-bump-required.sh, which tests/version-bump-required.test.ts pins. It fails the PR if a dev-only diff bumped, or a runtime diff did not.

1. Decide the bump level

Reached only when step 0 said a bump is warranted (the PR changed runtime files). The level question is never "does this bump?" — step 0 already answered that — only "how big is the bump?"

git log origin/main..HEAD --oneline
git diff origin/main...HEAD --stat

Pick the highest-impact runtime change in the PR:

  • major — breaking change to the plugin's contract (commands, artifact formats, hook behavior).
  • minor — new backward-compatible capability (feat:).
  • patch — everything else (fix:, docs:, chore:, refactor:, test:, ci:).

The conventional-commit type only picks the level. It never overrides step 0. A ci:/test:/docs:/chore: commit that ships no runtime change never reaches this table — it already stopped at step 0 with no bump.

State the chosen level and the reasoning. If genuinely ambiguous, ask.

2. Compute the next version

bash .claude/scripts/next-version.sh <level>

This prints bump(<default branch>'s version, level)deterministic, a pure function of the base and the level, with no open-PR scan. The base is read from the remote's default branch (resolved through origin/HEAD, not a hardcoded main). Under the land-time model the version is assigned against current main and landing is serialized, so bump(main, level) is always free. A concurrent race is handled by /shipit (rebase + recompute) and release-on-merge.yml's duplicate-tag backstop.

3. Bump all five version strings

The version lives in five places across four files:

FileOccurrences
.claude-plugin/plugin.json1 (version)
.claude-plugin/marketplace.json2 (metadata.version and plugins[0].version)
.codex-plugin/plugin.json1 (version)
package.json1 (version)

Codex reads .codex-plugin/plugin.json in preference to the Claude manifest, and shows the version it finds there. A stale one makes the same release look like two different versions depending on the host.

Edit all four files, then prove it:

grep -rn '"version"' package.json .claude-plugin/plugin.json \
  .claude-plugin/marketplace.json .codex-plugin/plugin.json

All five lines must show the new version. Zero may still show the old one.

4. Cut the changelog section

This moves the accumulated [Unreleased] body into a new dated section. It is the inverse of release-on-merge.yml's awk extraction, because you write the section the release workflow later reads. In CHANGELOG.md (Keep a Changelog format, entry style per skills/changelog/SKILL.md):

  • Move the entire [Unreleased] body into a new ## [X.Y.Z] - YYYY-MM-DD (today's date) section inserted directly below ## [Unreleased]. Leave ## [Unreleased] in place, now empty again.
  • Re-point the link-reference footer:
    • [Unreleased] compare base → vX.Y.Z...HEAD
    • Add [X.Y.Z]: https://github.com/bostonaholic/team/compare/v<prev>...vX.Y.Z

This section becomes the GitHub release notes verbatim — write it for a reader deciding if the upgrade is worth it. Any links must be absolute URLs: relative paths (e.g. docs/versioning.md) render as dead links on the release page (see skills/changelog/SKILL.md).

Empty-[Unreleased] edge case. A PR that reached this step passed step 0, so it did change runtime files. An empty [Unreleased] on it means nobody wrote the user-facing bullet. Derive at least one bullet from the PR's runtime commits (feat:/fix:/perf:/security: per skills/changelog/SKILL.md style). Never write an empty section (release-on-merge.yml errors on empty release notes).

Empty [Unreleased] and no runtime change is not this case. That PR must have stopped at step 0, with no bump and no changelog cut. Do not invent a bullet to justify a bump that step 0 already declined. Go back and land plain.

5. Land-time consistency assertion

After the changelog cut and before committing, run the consistency check — it must run after the cut (so the dated section exists to validate). This is the in-tree replacement for the retired version-gate.yml:

bun test tests/version-consistency.test.ts
node -e "['.claude-plugin/plugin.json','.claude-plugin/marketplace.json','.codex-plugin/plugin.json','.agents/plugins/marketplace.json','package.json'].forEach(f=>JSON.parse(require('fs').readFileSync(f)));console.log('JSON OK')"

The tripwire asserts strict semver, that all five strings agree, and that the host manifests agree on the plugin and marketplace names. Additionally assert inline the released-section + footer-compare-link invariants (these hold only after the cut, so they live here, not in the tripwire):

V=$(jq -r .version .claude-plugin/plugin.json)
ESC=$(sed 's/\./\\./g' <<<"$V")
grep -qE "^## \[$ESC\] - [0-9]{4}-[0-9]{2}-[0-9]{2}$" CHANGELOG.md \
  || { echo "::error::no '## [$V] - YYYY-MM-DD' section — the cut did not land"; exit 1; }
grep -qE "^\[$ESC\]: https://" CHANGELOG.md \
  || { echo "::error::no footer compare link for $V"; exit 1; }
grep -q "\[Unreleased\]: https://github.com/bostonaholic/team/compare/v$V...HEAD" CHANGELOG.md \
  || { echo "::error::[Unreleased] footer does not compare from v$V"; exit 1; }
echo "OK: land-time consistency holds"

If any check fails, stop before committing and fix the cut.

6. Commit

Commit the bump as its own commit in the PR branch, for clean reverts:

git add .claude-plugin/plugin.json .claude-plugin/marketplace.json \
  .codex-plugin/plugin.json package.json CHANGELOG.md
git commit -m "chore(version): X.Y.Z"

7. Title the PR

vX.Y.Z <type>: <subject> — e.g. v0.6.0 feat: add the shipit land skill. Set it on the existing PR (gh pr edit --title). The PR title sync workflow corrects drift, but it is a backstop — do not rely on it.

Then run /shipit (step 2 of the dev land process) to push, wait for CI, and squash-merge.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.