release
Skill1 starsChanged 10 days agoMITView on GitHub
Cut a release — every project with a pending level via p:release,
- Reads credentials
- Commits and pushes
196 other projects use a version of this.
Adopted by
Most recently taken up by
- zxcvbn-ts/zxcvbntheir own version, first seen Nov 9, 2026
- TechbeeAT/jtxBoardtheir own version, first seen Nov 9, 2026
- ddnexus/pagytheir own version, first seen Nov 9, 2026
- zerx-lab/FluxDowntheir own version, first seen Nov 9, 2026
- orioledb/orioledbtheir own version, first seen Nov 9, 2026
- AmruthPillai/Reactive-Resumetheir own version, first seen Nov 8, 2026
Used with
Projects with it also use create-agent-adapter, changelog-style and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
MicrosoftSkillcreate-agent-adapter
Technical guide for creating a new Paperclip agent adapter. Use when building a new adapter package, adding support for a new AI coding tool (e.g. a new CLI agent, API-based agent, or custom process), or when modifying the adapter system. Covers the required interfaces, module structure, registration points, and conventions derived from the existing claude-local and codex-local adapters.
Also in 5 projects that use this
GrinvSkillchangelog-style
Turn a commit range into CHANGELOG.md entries following common-changelog style. Use when finishing a PR or cutting a release, to write/fix the [Unreleased] section's entries — moving [Unreleased] under a new dated version heading is a separate, automated step (see the release skill / scripts/sync-version.ts), not this skill's job.
Also in 4 projects that use this
GrinvSkilldocs-consistency-check
Check README/manifest.json/server.json/CHANGELOG.md/AGENTS.md and docs/*.md for drift against the actual registered tools and source. Use after adding, renaming, or removing a tool, or as part of a live-audit pass.
Also in 4 projects that use this
Microsoft AzureSkillcomponent-release
Prepares a verifiable Agent Landing Zone UI release. Use for release branches, VERSION, changelog entries, tags, release notes, and compatibility evidence; never publish without explicit human approval.
Also in 4 projects that use this
Microsoft AzureSkilldocumentation-consistency
Keeps AI Landing Zone contributor, user, and operator documentation aligned with shipped Bicep behavior. Use for parameters, defaults, outputs, topology, deployment flow, operations, or releases.
Also in 8 projects that use this
rivet-devSkilllaunch-graphics
Generate agentOS marketing/launch graphics (launch & social heroes, code-snippet cards) from the committed generators in docs-internal/graphics. Use when asked to make, update, or render an agentOS launch image, social image, "agentOS Apps" graphic, or technical code-snippet image.
Also in 3 projects that use this
- +3 more from Grinv
Other versions196 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 196
- paperclipai/paperclip★ 112ksame name
- modelcontextprotocol/servers★ 92ksame name
- remotion-dev/remotion★ 72ksame name
- traefik/traefik★ 65ksame name
- usememos/memos★ 64ksame name
- tw93/Pake★ 63ksame name
- AmruthPillai/Reactive-Resume★ 45ksame name
- amruthpillai/reactive-resume★ 45ksame name
- reactive-resume/reactive-resume★ 45ksame name
- Yeachan-Heo/oh-my-claude-sisyphus★ 41ksame name
186 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository7 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- installer/CLAUDE.mdCLAUDE.md
- site/CLAUDE.mdCLAUDE.md
- plugin-authoringSkill
- skill-kitSkill
- stackgen-pluginSkill
- vwf-pluginSkill
The file
We split this skill into the rules it gives an agent
4 rules. 0 are common, 0 are distinctive, and 4 are very specific to this project.
0
Common
Most of the 186 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 177
If plugins.yml goes red on main with *"marketplace.json pins X, which is not a tag"*, the merge landed and the tags did not.
- Very specific: line 209
Every installer-vX.Y.Z tag carries one — the tag is the npm-publish trigger, the Release is the human-readable record beside it.
- Very specific: line 248
Every site-vX.Y.Z tag carries one, in the note format below — the same 1:1 rule as the installer's.
- Very specific: line 261
Follow .config/git-conventional-commits.yaml — the same config the repo already uses.
“Common” is measured: kept by at least 6 in 10 of the 186 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Release
Ask the user before running p:release, p:i:release, p:plugins:release or
p:site:release. It is the repo's hard rule, and every one of them commits,
merges and tags. There is no exception: no plan folder carries a release step.
--dry-run is the one form that may run without asking — it writes nothing.
There are three things to release, and one tag family each. p:release
releases every one that has something pending; each task alone releases its own.
| Releasing | Tag | Task | Ends at |
| one or more plugins | <name>-v<version> | p:plugins:release | the pushed tag |
| the installer CLI | installer-v<version> | p:i:release | npm + GitHub Release |
| the website | site-v<version> | p:site:release | Workers + GitHub Release |
The namespaces must all stay prefixed. GitHub's tag globs match any character
except /, so a bare v* family matched vwf-v19.9.0 and fired the npm
publish on a plugin release — which is why release.yml filters installer-v*.
The 54 pre-2026-08-30 v1.2.1–v6.0.0 tags are history; nothing fires on them,
and they are deliberately left unprotected.
Adding a fourth tag family means widening the ruleset. GitHub's
release-tags ruleset blocks deletion and re-pointing for refs/tags/*-v*,
which covers all three families above and every plugin ref the generator can
emit — a test pins their shape to /^[a-z][a-z0-9-]*-v\d+\.\d+\.\d+/, and
site-v1.0.0 matches both, so the site family needed no widening. A family
without -v in the name (nightly-2026-09, say) simply falls outside the
pattern and gets no protection, silently: nothing fails, it is just
unguarded. Either give the new family a -v or widen
conditions.ref_name.include to ["~ALL"] on ruleset 21871515.
Local first
A plugin is staged locally before it is tagged publicly. The staging command
is mise run p:plugins:local: it copies each changed plugin into the gitignored
dev marketplace under X.Y.Z+N and updates this machine's install, so the
author runs the plugin they are about to publish. It commits nothing, pushes
nothing and cuts no tag; /vwf:execute takes it as the plan folder's
after-landing step, recorded run at the interview — run without a prompt on a
green landing — and .config/vwf.yaml's after_landing: names it, so every
landing in this repo runs it. A hand-made change reaches it the same way.
So, before a plugin release, confirm the plugin being tagged has been staged and
actually exercised — in a restarted session, since skills are read at
session start. If it has not, offer to run p:plugins:local and stop there; the
tag can be cut in the next session and nothing is lost by waiting. This is a
question, not a gate: the user can say the change is docs-only, or that they
have exercised it another way, and that answer stands.
Two limits, both worth stating rather than papering over:
- It covers plugins only. The installer's and the website's nearest local
steps are
mise run p:i:testandmise run p:site:check— gates over the built artifact, not an install of it, so they prove less.p:site:devserves the site locally and is the closest thing the website has to running the real change. - It refuses in user mode, where the registered marketplace is the published
one — it would otherwise re-copy the last release, which is the state it
exists to escape. Setup is
.claude/docs/dev-marketplace.md. A refusal is reported, never routed around.
The ritual
# on develop, clean
mise run p:release -- --dry-run # show the user, then ask
mise run p:releaseNo person and no plan bumps a version by hand. A landing plan records a
level per project — NONE, PATCH, MINOR or MAJOR — and /vwf:execute
raises it in .config/releases.yaml, the highest level winning. The release
tasks read that file:
- The base is always the project's last tag —
<name>-v*,installer-v*,site-v*— never the manifest. - The level is the higher of the recorded one and the one an untagged
manifest implies against that tag (the first component that differs). Tag
vwf-v21.0.0, manifest21.2.0, recordedMAJOR→22.0.0. - The manifest is the floor: a target below the manifest releases the
manifest as it stands, so a release never lowers it. Tag
vwf-v21.0.0, manifest21.2.0, no record → impliedMINOR→21.1.0, raised to21.2.0. - The version skips 13 and 17: the target comes from the same guard the
version tasks use, so
1.1.12patched is1.1.14, and the task says what it skipped. A level that can never clear the number refuses. - A project at
NONE, with no record and a manifest equal to its tag, is skipped. A project with no tag yet releases its manifest as it stands. - Each task reads and clears only its own keys:
vwfandstackgenforp:plugins:release,installerforp:i:release,siteforp:site:release. A duplicated key in the file refuses.
--dry-run prints one line per project — its last tag, its level, and
→ <version>, → skip or → refused — checks no branch or tree, writes
nothing and exits zero. Show it to the user before asking.
p:release runs the three as one release: it plans from their dry-run lines
and stops on any refused; checks gh and runs p:i:test and p:site:check
for the projects that need them, before the first bump; then runs each task
--no-commit, makes one commit (ops: release …, naming the versions
staged), pushes develop, runs code:merge:main, and on main runs each
releasing task --tag-only — plugins, installer, site, in that order — and
switches back to develop. Its own tag steps carry RELEASE_GATES_DONE=1, so
the installer and site gates it already ran are not run again on main.
A stop prints its resume commands. The first failure stops the run and
prints the steps left, from develop: a tag already on origin is not cut again,
a tag cut but never pushed is pushed rather than re-made, and the resume lines
never carry RELEASE_GATES_DONE=1 — a resume may follow a fix no gate of the
run checked. When code:merge:main stops, it adds the resolve-or-abort hint:
finish the merge and push main, or git merge --abort and switch back to
develop.
One task alone is the same sequence for one project: from develop on a
clean tree it bumps, clears its key, commits (ops: release …), pushes
develop, merges with code:merge:main, tags on main, pushes, and switches
back to develop whatever happens. Two modes split it, for p:release and for
the fallback below:
| Mode | Runs on | Does |
--no-commit | develop | the bump step alone, staged; refuses only unstaged and untracked changes |
--tag-only | main | the tag step alone — tags what the manifest already names; no bump |
main stays merge-only. The bump is an ordinary commit on develop, and
main receives it by merge, so the no-commit-to-branch hook never has to be
skipped.
The merge model must be direct. Under pr, code:merge:main only opens a
pull request, and a tag would name a stale main. So full mode, --ci and
p:release refuse when [branch.main].merge_model in .config/bootstrap.toml
is pr; a missing file or key is direct.
The fallback is the two halves: each task --no-commit on develop, commit,
land the PR by hand, then each --tag-only on main.
Releasing plugins
Each entry in .claude-plugin/marketplace.json pins its plugin to a
<name>-v<version> tag, and that ref is derived from the plugin manifest's
version. p:plugins:release writes the target into
plugins/<name>/.claude-plugin/plugin.json — every target validated before any
file is written — and runs p:plugins:marketplace, so the ref renames itself in
the same commit.
The tracked version is plain X.Y.Z always; the X.Y.Z+N the authoring machine
runs between releases exists only in the gitignored staged copies
p:plugins:local writes, and p:plugins:check fails a manifest that carries
one.
13 and 17 are never issued as a version component, on any version line this
repo maintains — a plugin manifest, the installer, the site, config_format,
blueprint_format. The release tasks skip past them when they compute a target;
p:plugins:check refuses a manifest whose version has one (1.13.0, 17.0.0,
2.1.17; 1.130.0 and 113.0.0 are ordinary versions that merely contain the
digits), and the tag step refuses the whole run when any ref it would newly
cut carries one — refs already tagged predate the rule and stay. The +N
staging counter is not a component and never trips it.
The tag step tags only the refs with no tag yet, so a plugin whose version did not move is skipped and its entry stays byte-identical — that is what makes releases per-plugin. It pushes the tags in one push.
No GitHub Release and no npm publish. The tag is the release. Users move
with claude plugin marketplace update virajp-plugins (re-reads the pins) then
claude plugin update <name> (fetches them) — both steps, or nothing moves.
If plugins.yml goes red on main with "marketplace.json pins X, which is not
a tag", the merge landed and the tags did not. Run
mise run p:plugins:release -- --tag-only on main.
Releasing the installer CLI
Releasing via CI is preferred over the local p:i:publish, so every version
keeps the strongest npm trust level (trusted publisher).
1. Bump, merge and tag
p:i:release bumps package.json (through p:i:version when the manifest
equals the tag on a clean tree, by direct write otherwise), commits on
develop, merges, and on main refuses a version carrying a 13 or 17
component, refuses if installer-vX.Y.Z already exists, runs p:i:test,
creates the annotated tag, then pushes main first and the tag second and
watches the release.yml run with gh run watch --exit-status, so the task
only succeeds if the publish pipeline does. It needs gh installed and
authenticated, and checks it before any bump, commit or merge — in full mode
and under --tag-only.
The push order is load-bearing: release.yml checks the tagged commit is
reachable from origin/main, so a tag arriving before the branch fails that
gate. p:plugins:release pushes tags alone because no plugin tag is checked for
reachability.
--ci runs the same bump, commit, merge and tag, then stops, with no push of
the tag and no watch. deps-update.yml passes it, having raised the installer
to PATCH and committed the refresh first. Do not pass it by hand.
2. Cut the GitHub Release
Every installer-vX.Y.Z tag carries one — the tag is the npm-publish trigger,
the Release is the human-readable record beside it. The mapping is 1:1, so a
missing Release means a missed step. Plugin tags get no Release.
gh release create installer-vX.Y.Z --title installer-vX.Y.Z \
--notes-file < notes > --verify-tag- Creating a Release never publishes.
release.ymltriggers onpush: tags: installer-v*; nothing listens forreleaseevents.--verify-tagkeeps it that way by refusing to invent a tag — which would push and publish. --latestresolves by publish date, so a normal forward release is correct by default. Pass--latest=falsewhen backfilling out of order.
Releasing the site
The website deploys only from a site-v<version> tag; a merge to main ships
nothing. Same shape as the installer.
1. Bump, merge and tag
p:site:release checks gh first, before it bumps anything, then bumps
site/package.json — through p:site:version when the manifest equals the last
tag and the tree is clean, by direct write otherwise — commits on develop,
merges, and on main refuses a version carrying a 13 or 17 component, refuses
if site-vX.Y.Z already exists, runs mise run p:site:check, checks gh again
before it creates the annotated tag (the only check under --tag-only), then
pushes main first and the tag second and watches the site.yml run with
gh run watch --exit-status, so the task only succeeds if the deploy does. The
push order is load-bearing for the same reason as the installer's: site.yml
checks the tagged commit is reachable from origin/main.
--ci stops after the tag, with no push and no watch. Nothing passes it today;
do not pass it by hand.
2. Cut the GitHub Release
Every site-vX.Y.Z tag carries one, in the note format below — the same 1:1
rule as the installer's.
gh release create site-vX.Y.Z --title site-vX.Y.Z \
--notes-file < notes > --verify-tagsite.yml triggers on push: tags: site-v*; creating a Release never deploys,
and --verify-tag refuses to invent a tag that would.
The note format
Follow .config/git-conventional-commits.yaml — the same config the repo
already uses. Do not invent a second changelog format.
- Eligible types are
feat,fixandrefactor, plus breaking changes.includeInvalidCommits: false, soops:/docs:/blueprint:/merge:are excluded. Commits matching^[wW][iI][pP]\bare skipped. - Headlines: Features, Bug Fixes, Performance Improvements, Merges, BREAKING CHANGES.
- Scopes are bolded; each entry links its commit via
https://github.com/virajp/claude-plugins/commit/%commit%.
Shape of the note, in order:
- An optional
**Plugin versions:**line — only the marketplace entries whose version changed since the previous tag. Informational: those plugins ship on their own tags, not on this one. - The changelog sections.
- A
**Full Changelog**compare link.
A tag with no eligible commits still gets a Release, saying it is a maintenance release.
Facts that make a failed publish legible
- npm allows exactly one Trusted Publisher per package, and it validates the
entry-point workflow's filename — so it is set to
release.ymlonly.workflow_calltherefore does not work: the repo shipped it that way for two months and both monthly runs died at the publish step withENEEDAUTH, because npm sawdeps-update.ymland matched nothing.deps-update.ymlpublishes by dispatchingrelease.ymlon the new tag. - Refs pushed with
GITHUB_TOKENdo not start workflow runs — butworkflow_dispatchandrepository_dispatchare explicit exceptions, which is why no PAT or GitHub App token is needed. The dispatch is fire-and-forget; therelease.ymlrun is the publish record. - The publish step is idempotent: it skips (does not fail) if that version is already on npm, so tag re-points, dispatch retries and re-runs are safe.
release.ymlgates onosv-scannerover the lockfile before publishing, so an unpatched advisory in a transitive dep blocks the release. The remedy is an entry inpnpm-workspace.yaml'soverrides, not a bypass.- Publishing uses the npm CLI; everything else stays pnpm.
- No publish path may move into another file — that is why plugin validation
lives in the separate
plugins.yml, which publishes nothing and holds noid-tokenpermission. Narrowing which tags reachrelease.ymlis a different thing and is safe: npm matches the filename, not the trigger. That is what let the tag filter becomeinstaller-v*.
Before cutting
Confirm you are on develop with a clean tree, that a plugin release has been
through the local stage above, that mise run p:release -- --dry-run names the
versions the user expects, and that the change being released has its docs
reconciled — readme.md, CLAUDE.md and
site/src/content/docs/plugins/<plugin>.md ship with the change, not after it.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

