Release
Claude Code plugin marketplace — sdd (spec-driven dev) and gh (GitHub workflow) plugins
npx -y skills add kborovik/pilot-skills --skill releaseAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 4 stars4 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.
What its author says it does
Copied from the file, not written here
Cut SemVer release for single-package repo — bump `version` in detected manifest, commit, create annotated tag `v<x.y.z>`. Local only, not push, not GitHub Actions. Triggers when user says "release", "tag", "ship", "cut a version", "bump version".
SKILL.md
10.1 KB, as published. Nobody here has run it
Cut SemVer release for single-package repo. Local workflow — bumps version in repo's package manifest, commits, inits annotated tag v<x.y.z>. not push.
Scope
Single-package repos only. not monorepo orchestration — ≥ 2 manifests at distinct paths → bail with note: "monorepo detected, use a repo-local release procedure".
Manifest auto-detect
Grep at repo root in priority order. First hit wins:
1. package.json → .version
2. pyproject.toml → [project].version | [tool.poetry].version
3. Cargo.toml → [package].version
4. .claude-plugin/plugin.json → .version (single-plugin repo)
5. VERSION → raw SemVer text
not found → ask user which file holds version and how to update.
Tag format: v<x.y.z> (e.g. v1.0.0, v2.3.1).
Process
-
Parse $ARGUMENTS:
- not arg → auto bump (or baseline-mode if first release).
patchorminorormajor→ bump direction override.x.y.z(literal SemVer) → pin exactly. ! match^[0-9]+\.[0-9]+\.[0-9]+$. Permits downgrade.retag-baseline→ recovery mode. Drops every prior tag matching §3 pattern and retags HEAD at current manifest version. Requires ≥ 1 prior tag (else error: "no prior tag — use baseline mode by omitting arg"). not touches manifest. If manifest version is also wrong, fix it manually first or usex.y.zform instead.
-
Detect manifest (per table above). ≥ 2 candidates → bail (monorepo).
-
Find last tag:
git tag --list "v*" --sort=-v:refname | head -n 1- not tag → first release (baseline mode applies in §6).
-
Read current version from manifest. Invalid SemVer → error.
-
Collect commits in range:
- Range:
<last-tag>..HEADif tag exists, else full history. - Retag-baseline mode → range = full history regardless of prior tags (redoing baseline; prior tags about to be dropped).
git log <range> --pretty=format:"%H%x09%s"- Exclude commits whose subject matches
^chore(\([^)]+\))?: release v[0-9]+\.[0-9]+\.[0-9]+— skill's own release commits not count toward bump. - not commits remaining → exit cleanly w/ this exact shape (bypassed in retag-baseline mode):
Nothing to release. Range: <last-tag>..HEAD (or "full history" if no prior tag) Last tag: <last-tag-or-NONE> Manifest @ version: <manifest-path> @ <current-version> Commits in range: <total> Filtered self-release: <n> (matches §5 regex) Commits remaining: 0 Next steps: - Add commits, then re-run. - To force a release with no new commits, pass an explicit `<x.y.z>` arg. - To recover a wrong prior tag, pass `retag-baseline`. - not side effects beyond stdout. Same fail-loud spirit as the confirm-step (auto-detect breakdown and user-confirm-before-mutate) — not silent exits.
- Range:
-
Determine target version:
- Arg =
retag-baseline→ target = current manifest version. Manifest unchanged. Proceeds to drop prior tags in §11.5. - Arg =
x.y.z→ target =x.y.z. Skip auto-detect. - Arg =
patch/minor/major→ bump from current. Skip auto-detect. - not arg and not prior tag → baseline mode: target = current version (use what's in manifest, not bump). Sets the starting tag at the version already declared.
- not arg and prior tag exists → auto-detect from commit subjects:
- Any
<type>(<scope>)?!:or body containingBREAKING CHANGE→ major - Else any
feat(<scope>)?:→ minor - Else → patch
- Any
- Arg =
-
Compute next version (skip if explicit
x.y.z):- patch:
x.y.z→x.y.(z+1) - minor:
x.y.z→x.(y+1).0 - major:
x.y.z→(x+1).0.0 - baseline: target = current
- patch:
-
Render release notes (steno-styled, grouped):
- Group commits by Conventional Commits type:
- Features ←
feat - Fixes ←
fix - Other ←
refactor/docs/chore(non-release) /test/perf/build/ci/style - Uncategorized ← anything not matching
<type>(<scope>)?:prefix
- Features ←
- Each entry: bullet with subject minus
<type>(<scope>):prefix. Keep scope only if it disambiguates. - Preserve
#refs, paths, identifiers, SHAs verbatim. - Apply
core:stenoskill — fragments, not filler. - Baseline mode + only-init-commits → release notes may be empty / sparse. Acceptable.
- Group commits by Conventional Commits type:
-
Confirm before mutation — render breakdown so bump derivation auditable. Required fields:
- Manifest: path and current version (e.g.
<plugin-dir>/.claude-plugin/plugin.json @ <x.y.z>). - Range:
<last-tag>..HEADor<full history>if baseline. - Commit counts by Conventional Commits type: e.g.
feat:0 fix:0 refactor:1 docs:0 chore:0 breaking:0 uncategorized:0. Cover all types observed in range. - Filtered self-release commits: count of commits matching §5 self-release regex. Show count even if zero (proves the self-release filter ran).
- Bump derivation: explicit one-liner showing rule fired — e.g.
0 breaking + 0 feat → patch (default),1 breaking → major,arg "x.y.z" → pinned,no prior tag & no arg → baseline (no bump),arg "retag-baseline" → recovery (no bump, manifest unchanged). - Target tag:
v<x.y.z>(or<plugin>-v<x.y.z>for monorepo orchestrator). - Tags scheduled for deletion (retag-baseline only): list every prior tag matching §3 pattern. Note: if any pushed, user must drop them remotely too — instructions in §13.
- Rendered release notes (steno-styled, grouped per §8).
- Wait for user confirmation. not confirm → exit, not side effects.
- Manifest: path and current version (e.g.
-
Bump version in manifest (skip if baseline mode or retag-baseline mode — manifest already at target):
- Edit manifest → set version field.
- Stage:
git add <manifest-path>.
-
Commit (skip if baseline mode or retag-baseline mode — manifest unchanged):
- Heredoc +
--cleanup=verbatim(keeps any future#-prefix lines from being stripped as git comments):git commit --cleanup=verbatim --message "$(cat <<'EOF' chore: release v<x.y.z> EOF )"
- Heredoc +
11.5 Delete prior tags (retag-baseline mode only):
- For every tag listed in §9 "Tags scheduled for deletion":
git tag --delete <tag>
- Local deletion only at this step. Remote deletion → §13.
-
Init annotated tag w/ notes inline —
--cleanup=verbatimis mandatory (release notes use## Features/## Otherheaders that git's default cleanup would strip as comments):git tag --annotate --cleanup=verbatim v<x.y.z> --message "$(cat <<'EOF' v<x.y.z> <release notes> EOF )" -
Echo result to user:
- Tag name, target SHA, computed bump.
- Re-print rendered annotation (else hidden in
git show <tag>). - Push instructions:
git push origin main && git push origin v<x.y.z>. not push automatically. - Retag-baseline mode → also instruct remote-tag deletion for each dropped tag:
git push origin :refs/tags/<old-tag>. Skip for tags not pushed.
Release notes shape
## Features
- new release skill (`/gh:release`)
- add `--auto` example for merge queues
## Fixes
- token expiry boundary (`<` → `≤`)
## Other
- rewrite skills in math-glyph encoding
- drop unused gh CLI flag reference blocks
Write-time glyph gate
Pre-publish: rg --pcre2 '[∀∃∴⊥∈∉∧∨≤≥≠≡¬]' <body> on rendered release notes (§8) before §9 confirm render, release commit body (§11) before git commit, tag annotation body (§12) before git tag --annotate; match → bail and rewrite per core:steno register before mutation.
Style
Apply core:steno to release notes. Tag name and version string and identifiers / paths / #refs / SHAs preserved verbatim.
Requirements
- Single-package only. Monorepos → bail; user runs repo-local release procedure instead.
- SemVer only —
x.y.z, not pre-release suffixes (skill scope = simple). - Annotated tag (
-a/--annotate), not lightweight. - Local only — not
git push, notgh release create. User pushes manually. - not render
CHANGELOG.md— release notes live in tag annotation. - Baseline mode for first release: not bump if no prior tag and not explicit arg. Tags version already declared in manifest.
- Retag-baseline recovery: explicit
retag-baselinearg drops every prior tag matching pattern and retags HEAD at current manifest version. Requires ≥ 1 prior tag. Manifest unchanged. If manifest is also wrong, fix it manually first or usex.y.zarg (permits downgrade). - Self-release commits (
chore: release v*) excluded from auto-detect scan → empty range exits cleanly. - Confirm before mutation. not silently rewrite version files. Confirm step ! list tags scheduled for deletion in retag-baseline mode.
- All
git tag --annotateandgit commitcalls in this skill ! pass--cleanup=verbatim. git's defaultcommit.cleanup=stripwould silently drop#-prefix lines (release-note section headers) from messages.
OUTPUT — "Next" block
Heading ## Next; 1–5 atomic items (one sentence each, no Reply prefix); positional dispatch (run <int> or run /<plugin>:<cmd> [args]). Tag cut locally → follow-up usually push (git push origin main && git push origin v<x.y.z>) or gh release create to attach binaries or resume next §T row.
Canonical example after tag created (e.g. v1.2.3):
## Next
1. git push origin main && git push origin v1.2.3 — publish commit + tag
2. gh release create v1.2.3 --notes-from-tag — create GitHub Release w/ tag annotation
3. /sdd:build — start the next §T row