cut-release
Skill4 starsChanged 11 days agoMITView on GitHub
Bump a plugin's version and changelog in its own repo, then pin the pushed commit in both Foundry catalogs.
- Deletes or force-pushes
- Commits and pushes
36 other projects use a version of this.
Adopted by
Most recently taken up by
- GLinnik21/plx-nativetheir own version, first seen Nov 8, 2026
- mediajunkie/piper-morgan-producttheir own version, first seen Nov 8, 2026
- delexw/motion-graphics-agenttheir own version, first seen Nov 8, 2026
- tansu-io/tansutheir own version, first seen Nov 1, 2026
- rpraharaj/ai-sdlctheir own version, first seen Nov 1, 2026
- rpraharaj/ai-engineertheir own version, first seen Nov 1, 2026
Used with
Projects with it also use quota-axi, iterate-pr and 6 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.
layer5ioSkillquota-axi
Report local Claude, Codex, Cursor, GitHub Copilot, and Grok quota windows via the quota-axi CLI - remaining percentages, reset times, and provider status read from local auth sources, with no routing, recommendation, or provider mutation. Use before deciding whether it is safe to keep spending a provider's quota, when the user asks about usage, rate limits, or remaining quota, or when comparing local provider headroom.
Also in 4 projects that use this
SentrySkilliterate-pr
Iterate on a PR until actionable CI passes and high/medium review feedback is addressed. Use for PR CI failures, review feedback, or green-check loops; do not wait for human approval, draft status, or merge gates.
Also in 4 projects that use this
layer5ioSkillgh-axi
Operate GitHub through the gh-axi CLI - issues, pull requests, workflow runs, workflows, releases, repositories, labels, Projects (v2), Actions secrets and variables, search, and raw API access. Use whenever a task touches GitHub: listing or filing issues, reviewing or merging PRs, checking CI runs, triggering workflows, cutting releases, managing Projects boards, or managing Actions secrets/variables.
Also in 4 projects that use this
kunchenguidSkillchrome-devtools-axi
Control a Chrome browser session through the chrome-devtools-axi CLI - navigate, snapshot, click, fill forms, run JavaScript, inspect console and network, take screenshots, audit performance. Use whenever a task needs a real browser: opening or testing a web page, clicking through a flow, extracting page content, or debugging a website.
Also in 4 projects that use this
kunchenguidSkilllavish
Turn complex or visual agent responses into rich, reviewable HTML artifacts (HTML files) the user can annotate and send feedback on, using the lavish-axi CLI. Use when about to give a plan, comparison, diagram, table, code diff, report, or anything easier to grasp visually than as prose.
Also in 4 projects that use this
ThisIsSadeghiSkillverify-ui
Verify UI implementation against Stitch design via a token audit (HTML ↔ Code, with X-component default-render checks) and an X-components compliance check.
Also in 3 projects that use this
Other versions36 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 36
- ToolJet/ToolJet★ 41ksame name
- meshery/meshery★ 12ksame name
- danielmeppiel/apm★ 4.2ksame name
- microsoft/apm★ 4.2ksame name
- Screenly/Anthias★ 3.7ksame name
- Netflix/bpftop★ 2.7ksame name
- tansu-io/tansu★ 1.9ksame name
- fim-ai/fim-agent★ 1.6ksame name
- fim-ai/fim-one★ 1.6ksame name
- libredb/libredb-studio★ 1.3ksame name
26 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 repository5 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- brandSkill
- cut-releaseSkill
- brandSkill
The file
We split this skill into the rules it gives an agent
8 rules. 0 are common, 4 are distinctive, and 4 are very specific to this project.
0
Common
Most of the 36 edited versions we read keep these.
4
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 41
Every manifest a plugin carries holds the same version.
- Distinctive: line 71
Run the plugin's suite from inside its directory.
- Very specific: line 80
Read the current version from <plugin>/.claude-plugin/plugin.json.
- Distinctive: line 141
Verify that pins, gitlinks and manifests agree and that the plugins' shared copies still match, then validate the Claude catalog:
- Very specific: line 285
Start codex --no-daemon in the same project and open /hooks.
- Distinctive: line 329
Delete the scratch folder afterwards, which removes both homes, the relocated profile, the clone and the project:
- Distinctive: line 347
Write or edit plugin source, skills, agents or hooks.
- Very specific: line 348
Add a version to a catalog entry, or a plugin to a catalog that does not list it.
“Common” is measured: kept by at least 6 in 10 of the 36 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
cut-release
Cuts a release for one plugin this marketplace lists. Plugins are submodules, so a release is two
commits that move together: one in the plugin's own repository, pushed to its main, then one in
Foundry that pins that commit in every catalog listing the plugin.
Which plugins exist is not written down here. Plugins get added and retired, so read the current set from the catalogs. Never assume a plugin name — list them.
Copy this checklist into your reply and tick each step as it finishes:
- [ ] Step 0: plugin chosen, checkout state reported, suite green or go-ahead recorded
- [ ] Step 1: new version agreed
- [ ] Step 2: changelog entry and every manifest bumped
- [ ] Step 3: plugin release commit pushed and on origin/main, CI green
- [ ] Step 4: pins, gitlink and checks agree; Foundry commit pushed
- [ ] Step 5: release installed on each host it ships for, or marked not run
- [ ] Step 6: results reportedWhere the version lives, and where the pin lives
| Host | Version | Pin |
| Claude Code | <plugin>/.claude-plugin/plugin.json | .claude-plugin/marketplace.json, the entry's source.sha |
| Codex | <plugin>/.codex-plugin/plugin.json | .agents/plugins/marketplace.json, the entry's source.sha |
| Antigravity | <plugin>/plugin.json | Foundry's gitlink for the plugin: users install from a Foundry clone, which checks the plugin out at its gitlink |
Every manifest a plugin carries holds the same version. A catalog entry carries no version and
must not gain one: only source.sha moves, together with the gitlink. A plugin missing from a
catalog does not ship for that host; a release does not add it.
The gitlink and source.sha name the same commit, so the Foundry push in step 4 releases to every
host the plugin ships for at once, and a push to the plugin's main reaches nobody until it is
pinned. An Antigravity install is a copy: its user takes the release by pulling the Foundry clone,
running git submodule update --init and running agy plugin install again.
Step 0 — which plugin, and is it ready
List what each catalog ships, and ask which plugin if the user did not say:
node -e "for (const c of ['.claude-plugin/marketplace.json', '.agents/plugins/marketplace.json']) for (const p of require('./' + c).plugins) console.log(c, p.name, p.source.ref, p.source.sha.slice(0, 7))"Then look at the plugin checkout. A release ships from its main, so the branch, the unpushed
commits and the uncommitted edits all matter:
git -C <plugin> fetch origin
git -C <plugin> status --short --branch
git -C <plugin> log --oneline <pinned-sha>..origin/main
git -C <plugin> log --oneline origin/main..mainReport what is unpushed and what is uncommitted. A dirty checkout is not authorization to include everything in it; say what is coming along rather than sweeping it in silently.
Run the plugin's suite from inside its directory; Foreman's takes about 300 s. Stop and report if it is red; do not release over it without the user's explicit go-ahead:
node --test "tests/*.test.js"Step 1 — pick the new version
Read the current version from <plugin>/.claude-plugin/plugin.json. Ask the user for the new one,
or propose a semver bump from the Step 0 log: patch for fixes, minor for new user-facing behaviour,
major for breaking changes.
Step 2 — changelog and manifests, in the plugin
Read<plugin>/docs/knowledge/changelog.md. Entries are## <version> — <YYYY-MM-DD>followed by a short user-facing paragraph. Rename the top## Unreleasedheading to the new entry's heading, or add the entry at the top when there is none. State the effect, not the journey: no methodology, no counts, no design rationale.Editversionin<plugin>/.claude-plugin/plugin.jsonand, when they exist,<plugin>/.codex-plugin/plugin.jsonand<plugin>/plugin.json. Then confirm every hit reads the same string:
grep -n '"version"' <plugin>/.claude-plugin/plugin.json <plugin>/.codex-plugin/plugin.json <plugin>/plugin.jsonStep 3 — commit and push the plugin
Stage only the release surface: docs/knowledge/changelog.md, .claude-plugin/plugin.json and, when they exist,
.codex-plugin/plugin.json and plugin.json. The plugin's own pre-commit hook reruns its suite.
git -C <plugin> commit -m "Release <plugin> <version>"
git -C <plugin> push origin mainEach plugin's main, like Foundry's, has a ruleset that requires a squash-only pull request and a
status check. A squash merge lands the release under a new sha, so the local main and any pin
taken from it no longer match origin/main. A direct push keeps the shas but succeeds only
through the owner's admin bypass. Before either push, read the ruleset
(gh api repos/V-Songbird/<repo>/rulesets) and ask the owner: name the bypassed rules and the
required check next to the pull-request option.
The pin waits until the release commit is reachable from origin/main and the plugin's CI passed
on it; that CI is the suite's only Linux run:
git -C <plugin> fetch origin
git -C <plugin> branch -r --contains <release-sha>branch -r --contains proves only reachability. Read the CI result with:
gh run list --repo V-Songbird/<repo> --commit <release-sha> --json workflowName,status,conclusionPin only when every run listed shows status completed and conclusion success. If a run ends
failure, cancelled or timed_out, stop and report it; pin only on the user's explicit go-ahead.
An empty list means no run has started yet: rerun it once after a short wait, and if it stays empty,
check that <release-sha> is on origin/main and that <repo> is right, then stop and report.
Step 4 — pin the commit in Foundry
Editsource.shain the plugin's entry of.claude-plugin/marketplace.jsonand, when the plugin is listed there,.agents/plugins/marketplace.json. Both pins name the same full SHA.- The plugin checkout already sits on that commit, so stage the gitlink:
git add <plugin>. In a worktree whose plugin folder is empty,git add <plugin>stages nothing; stage the full SHA directly withgit update-index --cacheinfo 160000,<sha>,<plugin>. - Verify that pins, gitlinks and manifests agree and that the plugins' shared copies still match, then validate the Claude catalog:
node -e '
const fs = require("fs"), path = require("path"), { execFileSync } = require("child_process");
const root = process.argv[1] || ".";
const git = (args, cwd = ".") => execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
const manifests = [".claude-plugin/plugin.json", ".codex-plugin/plugin.json", "plugin.json"];
for (const catalog of [".claude-plugin/marketplace.json", ".agents/plugins/marketplace.json"])
for (const p of JSON.parse(fs.readFileSync(catalog, "utf8")).plugins) {
const { sha, ref } = p.source, dir = path.join(root, p.name);
const gitlink = git(["ls-files", "-s", p.name]).split(" ")[1] === sha;
try { git(["cat-file", "-e", sha + "^{commit}"], dir); }
catch { console.log(catalog, p.name, "COMMIT NOT IN " + dir + ": fetch it there, or pass the Foundry root"); process.exitCode = 1; continue; }
const pushed = git(["branch", "-r", "--contains", sha], dir).includes("origin/" + ref);
const versions = new Set(manifests.flatMap((m) => { try { return [JSON.parse(git(["show", sha + ":" + m], dir)).version]; } catch { return []; } }));
console.log(catalog, p.name, [...versions].join("/"), versions.size === 1 ? "manifests agree" : "MANIFEST VERSIONS DIFFER", gitlink ? "gitlink ok" : "GITLINK DIFFERS", pushed ? "on origin/" + ref : "NOT ON origin/" + ref);
if (versions.size !== 1 || !gitlink || !pushed) process.exitCode = 1;
}' .
node scripts/check-shared-copies.js .
claude plugin validate .The pin check prints every line and exits non-zero on any problem, so read each line: an uppercase
word means stop and fix it before you push. MANIFEST VERSIONS DIFFER: bump every manifest together in
step 2, then commit, push and pin the new commit. GITLINK DIFFERS: check the plugin out at the
pinned commit and stage its gitlink, as in item 2. NOT ON origin/<ref>: push the plugin's main
and fetch, as in step 3. COMMIT NOT IN <dir>: that
plugin checkout lacks the pinned commit, so fetch it there or pass the right root.
The pin check and the shared-copy check read the gitlinks, staged ones included, of the
checkout they run in, the pin check its catalogs too, and each plugin's history from the plugin checkouts under the Foundry
root: the path after the pin check's closing quote and the shared-copy check's argument, .
when you run them there. Run both from the root of the checkout that holds the release
commit. From a worktree, whose plugin folders are empty or stale, replace both . with the
Foundry root's path; the release commit must be fetched into the root's plugin checkout.
scripts/check-shared-copies.js compares the code after the header comment of Hush's and Razor's
hooks/lib/safe-write.js and the FIXTURES array of their tests/turn_boundary_conformance.test.js,
the Node.js and fnm lookup in Foreman's and Razor's hooks/windows-launcher.ps1, and the whole
of the README nav check's seven files in Foreman, Hush and Razor:
scripts/git-hooks/check-readme-nav.js, scripts/git-hooks/pre-commit, the two files under
scripts/git-hooks/vendor/, tests/readme_nav.test.js, tests/pre_commit.test.js and
tests/fixtures/github-slugger-fixtures.json.
It reads every file at the commit each plugin's gitlink pins, including the gitlink you just
staged, and names that commit; a checkout's branch and uncommitted edits do not count. A
difference means one plugin ships a fix another lacks: land the missing change in that plugin
before you push the pin. The check skips a plugin with no checkout and names it, fails when it
compared nothing, and fails when a pinned commit is missing from its checkout.
It also compares flint's output-styles/hush.md, at flint's gitlink, with Hush's at the commit
flint's README.md names, not at Hush's pin, after cutting the plugin-only parts flint's
AGENTS.md lists; any other difference, or a listed part Hush no longer has, fails. It skips
flint, and names it, when flint or Hush has no checkout.
agy plugin validate <plugin> checks the Antigravity package of a plugin that ships one, when
the Antigravity CLI is installed; report it as not run otherwise.
- Commit and push:
git add .claude-plugin/marketplace.json .agents/plugins/marketplace.json <plugin>
git commit -m "Install <plugin> <version> from main"
git push origin mainNothing here is pre-approved beyond reading and editing: every command in this skill goes through
the usual permission prompt, and the two pushes are the ones you should read before allowing.
Foundry's push meets the same ruleset as the plugin's, with the required validate check; ask
about it as in step 3.
Step 5 — install the release as a user would
The pin is public now. Install from the catalog into a throwaway config home per host, so your own
installs, settings and hook trust stay untouched. Each new home starts without a login: the lines
marked owner login, and every model session after them, bill the owner's account, so ask before
running them and let the owner pick the account. Keep both homes and a
disposable project in one scratch folder. The project holds one open roadmap entry, so Foreman's
session hook has something to say. It is its own Git repository, because Codex otherwise reads
the AGENTS.md of any repository that encloses the scratch folder:
check="$(mktemp -d)" && mkdir "$check/project" "$check/claude-home" "$check/codex-home"
cd "$check/project" && git init -q
printf '%s\n' '{"id":"001","title":"Release hook check","status":"in_progress"}' > ROADMAP.jsonlClaude Code. Install the released plugin, and Foreman too when another plugin is released, because the Task-event check needs it. Then run one short session with hook events in its output. A capture hook on the two Task events receives the same input as Foreman's task-created and task-completed hooks:
export CLAUDE_CONFIG_DIR="$check/claude-home"
claude --version
claude plugin marketplace add V-Songbird/foundry
claude plugin install <plugin>@foundry
claude plugin install foreman@foundry # when <plugin> is not foreman
claude plugin list
claude # owner login: sign in, then quit
cat > capture.js <<'EOF'
const fs = require("fs");
fs.appendFileSync("task-events.jsonl", fs.readFileSync(0, "utf8").trim() + "\n");
EOF
claude -p "Use TaskCreate to add one task, then mark it completed with TaskUpdate. Do nothing else." \
--model haiku --allowedTools TaskCreate,TaskUpdate \
--settings '{"hooks":{"TaskCreated":[{"hooks":[{"type":"command","command":"node capture.js"}]}],"TaskCompleted":[{"hooks":[{"type":"command","command":"node capture.js"}]}]}}' \
--output-format stream-json --verbose --include-hook-events < /dev/null > session.jsonl
node -e '
const fs = require("fs");
const read = (f) => fs.readFileSync(f, "utf8").split("\n").filter(Boolean).map((l) => JSON.parse(l));
const ok = read("session.jsonl").filter((e) => e.subtype === "hook_response" && e.outcome === "success");
const fired = (event, text) => ok.some((e) => e.hook_event === event && e.stdout.includes(text));
console.log("foreman SessionStart:", fired("SessionStart", "[Foreman]"));
console.log("razor SessionStart:", fired("SessionStart", "RAZOR ACTIVE"));
console.log("hush UserPromptSubmit:", fired("UserPromptSubmit", "hush:"));
for (const event of ["TaskCreated", "TaskCompleted"]) console.log(event, "hooks that ran:", ok.filter((e) => e.hook_event === event).length);
for (const e of read("task-events.jsonl"))
console.log(e.hook_event_name, ["task_id", "task_subject", "task_description"].map((k) => k + (typeof e[k] === "string" ? " ok" : " MISSING")).join(", "));
'claude plugin list must show the new version, and every plugin you installed must print true.
Each Task event must show two hooks that ran, the capture hook and Foreman's, and all three fields
ok. A MISSING field means Claude Code changed the Task-event input, which silently turns
Foreman's task hooks off: report it as a Foreman bug with the Claude Code version. A plugin that
prints false only in the first session of a new home may have hit its hook timeout on a cold
start; run the session once more before reporting it.
Codex. Skip it when the release is Hush, which has no Codex package. When the codex CLI is not installed, report the Codex check as not run. Otherwise install the released plugin and trust its hooks the way a user does:
export CODEX_HOME="$check/codex-home"
codex --version
codex login # owner login
codex plugin marketplace add V-Songbird/foundry
codex plugin add <plugin>@foundry
codex plugin list --marketplace foundry --jsonThe listing must show the new version. The owner's sign-in also syncs their account plugins into
the new home; an AuthRequired error their MCP servers print on stderr is not a release failure.
Start codex --no-daemon in the same project and open /hooks; without the flag the TUI fails
when CODEX_HOME sits under a long path.
Record whether Codex asked you to review and trust the plugin's hooks before they ran; in a fresh
home it should. Trust them, quit, and start codex --no-daemon again. Ask the new session to quote the first
line of each note it received at session start: Razor's begins RAZOR ACTIVE, and Foreman's
[Foreman] Roadmap entries still open. A NODE_OPTIONS preload that logs which hook ran must
read process.execArgv, not process.argv: Foreman's hooks start as node -e "require(...)",
so their argv names no script.
Existing Codex users keep their trust unless a hook definition changed. This command compares the pin step 0 printed with the release; when it prints anything, record that existing users must review and trust the hooks again:
git -C <plugin> diff --stat <pinned-sha> <release-sha> -- hooks/codex-hooks.jsonAntigravity. Skip it for a plugin without a root plugin.json, such as Hush. Antigravity has
no config-home setting: agy plugin install writes into ~/.gemini/config/plugins of the user
who runs it. So run it in a throwaway user profile, with HOME, USERPROFILE, APPDATA and
LOCALAPPDATA relocated into the scratch folder, and install from a Foundry clone at the pin, as
a user would:
git clone -q --recurse-submodules https://github.com/V-Songbird/foundry.git "$check/foundry"
profile="$(cd "$check" && { pwd -W 2>/dev/null || pwd; })/agy-profile"
mkdir -p "$profile/AppData/Roaming" "$profile/AppData/Local"
in_profile() { HOME="$profile" USERPROFILE="$profile" APPDATA="$profile/AppData/Roaming" LOCALAPPDATA="$profile/AppData/Local" "$@"; }
ls ~/.gemini/config/plugins > "$check/gemini-before.txt" 2>/dev/null
in_profile agy --version
in_profile agy plugin install "$check/foundry/<plugin>"
in_profile agy plugin list
diff -r --exclude=.git "$check/foundry/<plugin>" "$profile/.gemini/config/plugins/<plugin>"
ls ~/.gemini/config/plugins 2>/dev/null | diff "$check/gemini-before.txt" -Record the agy version and that agy plugin list names the plugin with its skills and hooks.
Both diff commands must print nothing: the installed copy equals the clone, and your own
~/.gemini/config/plugins did not change. The relocated profile has no Antigravity sign-in, so
it cannot show a hook firing in a live conversation. That check is owner login: with the
owner's go-ahead, sign in inside the relocated profile, start a conversation in
$check/project, and ask it to quote the first line of each note it received at its first model
call; Razor's begins RAZOR ACTIVE. Report it as not run otherwise.
Delete the scratch folder afterwards, which removes both homes, the relocated profile, the clone and the project:
cd && rm -rf "$check" && unset CLAUDE_CONFIG_DIR CODEX_HOMEStep 6 — confirm
Report the plugin, the version, the plugin release SHA, the Foundry commit SHA and both push results. Add step 5's results: the Claude Code and Codex versions, which hook fired for each plugin on each host, whether Codex asked to trust the hooks and whether existing users must trust them again, the Task-event fields, and Antigravity's version, listing and live check, each as run or not run. A local commit, a valid catalog or a green suite is not publication; if a push failed, surface that rather than retrying silently.
What this skill does not do
- Write or edit plugin source, skills, agents or hooks.
- Add a
versionto a catalog entry, or a plugin to a catalog that does not list it. - Pin a commit that is not reachable from the plugin's
origin/main. - Decide the bump size without asking, unless the user already stated it.
- Force-push, skip hooks, or release over a red suite without explicit confirmation.
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.

