ship
Skill1 starsChanged 3 months agoMITView on GitHub
Package and release a verified forge-built plugin: claude plugin validate --strict, frontmatter/scoped-name/freshness lints, README with the permission story, versioning decision (SHA vs pinned semver), distribution menu (skills-dir, private marketplace, community), and installing the trace-capture flywheel. Use when the user says ship, release, publish, or distribute the plugin.
194 other projects use a version of this.
Adopted by
Most recently taken up by
- wboayue/rust-ibapitheir own version, first seen Nov 9, 2026
- haiggoh/run-to-completiontheir own version, first seen Nov 8, 2026
- sanmidable/skillstheir own version, first seen Nov 8, 2026
- Yesterday-AI/ytstacktheir own version, first seen Nov 8, 2026
- gaoyu06/harnesstheir own version, first seen Nov 8, 2026
- PeanutGT/NutsSkillstheir own version, first seen Nov 8, 2026
Used with
Projects with it also use ios-sync, open-gstack-browser 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.
Saqlain-811Skillios-sync
Regenerate the iOS debug bridge against the latest upstream gstack templates. (gstack)
Also in 6 projects that use this
seek888Skillopen-gstack-browser
Launch GStack Browser — AI-controlled Chromium with the sidebar extension baked in. Opens a visible browser window where you can watch every action in real time. The sidebar shows a live activity feed and chat. Anti-bot stealth built in. Use when asked to "open gstack browser", "launch browser", "connect chrome", "open chrome", "real browser", "launch chrome", "side panel", or "control my browser". Voice triggers (speech-to-text aliases): "show me the browser".
Also in 10 projects that use this
ayudaySkillsetup-deploy
Configure deployment settings for /land-and-deploy. Detects your deploy platform (Fly.io, Render, Vercel, Netlify, Heroku, GitHub Actions, custom), production URL, health check endpoints, and deploy status commands. Writes the configuration to CLAUDE.md so all future deploys are automatic. Use when: "setup deploy", "configure deployment", "set up land-and-deploy", "how do I deploy with gstack", "add deploy config".
Also in 19 projects that use this
ShreyRaviSkilllanding-report
Read-only queue dashboard for workspace-aware ship. Shows which VERSION slots are currently claimed by open PRs, which sibling Conductor workspaces have WIP work likely to ship soon, and what slot /ship would pick next. No mutations — just a snapshot. Use when asked to "landing report", "what's in the queue", "show me open PRs", or "which version do I claim next". (gstack)
Also in 9 projects that use this
zebbernSkilldebug-fix
Find and fix a bug or issue — from any source (GitHub issue, error message, user report, or observed behavior)
Also in 4 projects that use this
ramybarsoumSkilldocument-release
Post-ship documentation update. Reads all project docs, cross-references the diff, updates README/ARCHITECTURE/CONTRIBUTING/CLAUDE.md to match what shipped, polishes CHANGELOG voice, cleans up TODOS, and optionally bumps VERSION. Use when asked to "update the docs", "sync documentation", or "post-ship docs". Proactively suggest after a PR is merged or code is shipped.
Also in 23 projects that use this
Other versions194 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 194
- garrytan/gstack★ 141ksame name
- rtk-ai/rtk★ 86ksame name
- simstudioai/sim★ 30ksame name
- millionco/react-doctor★ 15ksame name
- BuilderIO/agent-native★ 7.6ksame name
- nightly-labs/openbot★ 6.3ksame name
- fallow-rs/fallow★ 5.3ksame name
- puncsky/system-design-and-architecture★ 3.6ksame name
- plugin87/ux-ui-agent-skills★ 3.1ksame name
- ShenSeanChen/waku-agent★ 2ksame name
184 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 repository10 other files it gives its agents.
- arm-evalsSkill
- build-evalsSkill
- build-loopSkill
- forgeSkill
- generation-standardsSkill
- primitive-catalogSkill
- prompt-optimizerSkill
- skill-forgeSkill
- verifySkill
- write-contractSkill
The file
We split this skill into the rules it gives an agent
5 rules. 0 are common, 0 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 180 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 23
If the line above shows a policy notice instead of JSON (org setting disableSkillShellExecution), read .forge/state.json with the Read tool …
- Very specific: line 100
Every hit in hook matchers, permission rules, agent tools lists, or skill allowed-tools is a FAIL — unless it names an EXTERNAL server the …
- Very specific: line 231
Ask via AskUserQuestion unless $ARGUMENTS pre-selects a path:
- Very specific: line 272
If CONTRACT.md says the plugin runs in cloud sessions or scheduled routines, personal installs are invisible there (cloud sessions never …
- Very specific: line 301
Leave .forge/ in place: it is the flywheel's memory (freeze hash, change requests, run history).
“Common” is measured: kept by at least 6 in 10 of the 180 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
Ship — validate, lint, document, version, distribute
Current forge state: !cat .forge/state.json 2>/dev/null || echo NO_STATE
If the line above shows a policy notice instead of JSON (org setting
disableSkillShellExecution), read .forge/state.json with the Read tool
before continuing.
Phase gate (hard)
Proceed only when phase is ship — verification must already be green. For
any other state, run NOTHING and reply with exactly the remediation below,
then stop:
| Injected state | Reply and stop |
| NO_STATE | "No forge run in this project. Run /plugin-forge:forge to start one." |
interview | "Interview incomplete. Run /plugin-forge:forge." |
contract | "No approved contract yet. Run /plugin-forge:write-contract." |
evals | "Suite not armed. Run /plugin-forge:build-evals, then /plugin-forge:arm-evals." |
armed | "Nothing built yet. Run /plugin-forge:build-loop." |
building | "Build loop has not gone green. Run /plugin-forge:build-loop." |
smoke or verify | "Verification is not complete. Run /plugin-forge:verify." |
Inputs to read before Step 1: plugin_name and plugin_dir from the injected
state; design/CONTRACT.md (C6 distribution decisions, runtime answers —
cloud/routine or local, version floors, permission story, cost sheet); the
latest runs/<ts>/verify-report.md (baseline numbers for the README); and
.forge/freeze.json (suite version).
Step 1 — Static gates (all four pass before anything is written)
1a. Strict validation — the same check the community pipeline runs:
claude plugin validate --strict <plugin_dir>1b. Frontmatter YAML lint on every generated SKILL.md. Malformed YAML fails silently: the body loads with no metadata, so the skill never auto-triggers. Run:
python3 - <plugin_dir> <<'EOF'
import sys, re, pathlib
root, bad = pathlib.Path(sys.argv[1]), []
files = sorted(root.glob('skills/**/SKILL.md')) + sorted(root.glob('SKILL.md'))
for f in files:
t = f.read_text(encoding='utf-8')
m = re.match(r'\A---\r?\n(.*?)\r?\n---\r?\n', t, re.S)
if not m:
bad.append(f'{f}: frontmatter fence missing or unclosed'); continue
fm = m.group(1)
tops = [(k.group(1), k.start()) for k in re.finditer(r'^([A-Za-z][\w-]*):', fm, re.M)]
names = [k for k, _ in tops]
for req in ('name', 'description'):
if req not in names: bad.append(f'{f}: missing required key {req}:')
if '\t' in fm: bad.append(f'{f}: literal tab in frontmatter (YAML hazard)')
for b in re.finditer(r':\s*(yes|no|on|off)\s*$', fm, re.M | re.I):
bad.append(f'{f}: boolean "{b.group(1)}" needs >=2.1.218 - use true/false')
def block(key):
d = dict(tops)
if key not in d: return ''
starts = sorted(s for _, s in tops); i = starts.index(d[key])
return fm[d[key]:starts[i+1]] if i + 1 < len(starts) else fm[d[key]:]
if len(block('description')) + len(block('when_to_use')) > 1536:
bad.append(f'{f}: description+when_to_use exceed the 1536-char listing cut')
for b in bad: print('FAIL', b)
print('frontmatter lint:', 'FAIL' if bad else 'PASS')
sys.exit(1 if bad else 0)
EOF1c. Scoped-name lint — bundled-MCP references using a bare server name
never fire; they must be mcp__plugin_<plugin>_<server>__<tool> (and
plugin:<plugin>:<server> in mcp_tool hook server fields):
grep -rnE 'mcp__' <plugin_dir> --include='*.md' --include='*.json' | grep -v 'mcp__plugin_'Every hit in hook matchers, permission rules, agent tools lists, or skill
allowed-tools is a FAIL — unless it names an EXTERNAL server the plugin does
not bundle (check against the plugin's .mcp.json before failing).
1d. Freshness lint — deprecated shapes must not ship:
grep -rnE '"decision"[[:space:]]*:[[:space:]]*"(approve|block)"' <plugin_dir>
grep -rn '/mnt/skills' <plugin_dir>Both greps must return nothing. The decision-JSON hook shape is deprecated
(current discipline: stderr + exit 2 to block, or hookSpecificOutput);
/mnt/skills paths are foreign-environment rot that never resolves in Claude
Code. Fix at the source, never by weakening the lint.
Step 2 — Install the flywheel (trace capture)
mkdir -p <plugin_dir>/hooks/scripts
cp "${CLAUDE_PLUGIN_ROOT}/templates/hooks/trace-capture.sh" <plugin_dir>/hooks/scripts/trace-capture.sh
chmod +x <plugin_dir>/hooks/scripts/trace-capture.shMerge ${CLAUDE_PLUGIN_ROOT}/templates/hooks/hooks-snippet.json into
<plugin_dir>/hooks/hooks.json: create the file from the snippet when the
plugin ships no hooks yet; otherwise append the snippet's PostToolUse entry to
the existing array — never clobber existing entries. Confirm the merged entry
is exec-form and references
"${CLAUDE_PLUGIN_ROOT}/hooks/scripts/trace-capture.sh" — at the generated
plugin's runtime that variable resolves to ITS root, not to plugin-forge's.
Why this ships in every generated plugin: the hook appends tool
args/results/errors to ${CLAUDE_PLUGIN_DATA}/traces/*.jsonl, so production
failures become eval tasks — /plugin-forge:build-evals mine converts traces
to tasks, /plugin-forge:arm-evals re-freezes vN+1, and
/plugin-forge:build-loop rebuilds until green. Document the loop in the
README (Step 4).
Step 3 — Optional observability (fleet/long-job plugins)
Offer when the generated plugin dispatches subagent fleets or long jobs; otherwise skip.
- subagentStatusLine — a plugin
settings.jsonsupports ONLY theagentandsubagentStatusLinekeys:
{"subagentStatusLine": {"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/status.sh"}}with the script reading a ${CLAUDE_PLUGIN_DATA}/status.json the plugin's
long-running jobs update.
- Monitor — pair each long-job skill with
monitors/monitors.json:
[{"name": "<job>-watch", "command": "tail -F <log path>",
"description": "streams <job> progress into the session",
"when": "on-skill-invoke:<skill-name>"}]State the caveats wherever this is offered: monitors are experimental,
interactive-CLI only, do not load from project-scope skills-dir installs,
reject ${user_config.*} in commands, and need a session restart after
plugin updates.
Step 4 — README for the generated plugin
Instantiate
${CLAUDE_PLUGIN_ROOT}/skills/generation-standards/templates/readme.tmpl.md
into <plugin_dir>/README.md. Required sections:
- Overview + invocations — what the plugin does; every user-facing skill
as
/<plugin_name>:<skill>with its argument hint. - Permission story — a
permissions.allowlist covering EVERY command the plugin's skills and agents run. allowed-tools grants are turn-scoped (cleared on the next user message), so long flows need standing allows in the consumer's.claude/settings.json:{"permissions": {"allow": ["Bash(<cmd> *)", "..."]}}. - Minimum Claude Code version — the highest floor among features used
(from CONTRACT C6). Known floors:
${CLAUDE_SKILL_DIR}in allowed-tools 2.1.129;defaultEnabled2.1.154; marketplacerenames2.1.193;--json-schemahard errors / LSPrestartOnCrash2.1.205; worktree resume 2.1.212; frontmatternamesegment override 2.1.216; yes/no boolean forms and background-fork default 2.1.218. - Headless recipe — the
claude -pinvocation for CI/routines, using the suite's sandbox settings profile (never--dangerously-skip-permissions), plusCLAUDE_CODE_PLUGIN_SEED_DIRfor network-free container loading. - How to run your evals — the
evals/layout;evals/bin/run.pyis vendored and stdlib-only, so the suite runs WITHOUT plugin-forge installed; red baseline via the no-plugin target; the finalFORGE_EVAL:line and exit code as the CI signal; run the regression suite in CI; cost honesty (--max-cost-usd); current baseline for future battle A/B: suite version from.forge/freeze.json, pass^3 and cost fromverify-report.md. - Flywheel — traces land in
${CLAUDE_PLUGIN_DATA}/traces/; feed failures back with/plugin-forge:build-evals mine.
Step 5 — Versioning decision (ask the user)
Present exactly two options via AskUserQuestion:
- Still iterating — OMIT
versionfrom plugin.json. The git SHA becomes the version: every pushed commit reaches users. - Releasing — pin semver in plugin.json, add a CHANGELOG entry, and run
claude plugin tag --push(creates the<name>--v<version>tag that dependency constraints resolve against).
Explain the trap before they choose: a pinned semver means users update ONLY when the field is bumped — pushing commits under a stale pin does nothing ("already at latest version"). A plugin pinned at 1.0.0 and then iterated strands every installed user on the first build. Never pin without a release process that bumps it.
Also state: the plugin name is a permanent public identifier (the
marketplace renames map is the only migration path, 2.1.193+);
displayName is the safe-to-change label.
Step 6 — Final re-validation
Steps 2–4 added files. Re-run on the FINAL tree:
claude plugin validate --strict <plugin_dir>and repeat the Step 1c/1d greps over the added files. Ship nothing that is not green here.
Step 7 — Distribution menu
Ask via AskUserQuestion unless $ARGUMENTS pre-selects a path:
A. skills-dir plugin (lightest) — copy <plugin_dir> (with
.claude-plugin/plugin.json) to ~/.claude/skills/<plugin_name>/ (personal)
or <repo>/.claude/skills/<plugin_name>/ (project). It loads as
<plugin_name>@skills-dir next session; SKILL.md edits are live, hooks/MCP
changes need /reload-plugins. Warn: project scope is trust-gated, does NOT
walk up to the repo root (launch Claude from the root), and monitors do not
load.
B. Private marketplace — add or extend .claude-plugin/marketplace.json
in the hosting repo:
{"name": "<marketplace-name>", "owner": {"name": "<owner>"},
"plugins": [{"name": "<plugin_name>", "source": "./<relative-path>",
"description": "<one line>", "category": "<category>"}]}Validate the marketplace repo with claude plugin validate .. Consumers run:
claude plugin marketplace add <org>/<repo>
claude plugin install <plugin_name>@<marketplace-name>Maintenance: claude plugin marketplace update <marketplace-name>; inspection:
claude plugin marketplace list --json. Warn: marketplace names collide
globally per user (a second add replaces the first) and several names are
reserved — pick something distinctive.
C. Community submission — pre-submission requirements: kebab-case plugin
name (the claude.ai marketplace sync REJECTS non-kebab names);
claude plugin validate --strict clean (the community pipeline runs the same
check as Step 1a); README and LICENSE present; semver pinned and tagged via
claude plugin tag --push; public repo. Then submit the repo through the
community marketplace submission form, with the marketplace-entry fields
(name, source, description, category, tags) prepared to paste.
Step 8 — Repo-declared settings (cloud/routine contracts)
If CONTRACT.md says the plugin runs in cloud sessions or scheduled routines,
personal installs are invisible there (cloud sessions never read
~/.claude/skills) — the consuming repo must declare the plugin. Instantiate
${CLAUDE_PLUGIN_ROOT}/skills/generation-standards/templates/settings-snippet.tmpl.json
into the consuming repo's .claude/settings.json:
{"extraKnownMarketplaces": {"<marketplace-name>": {"source":
{"source": "github", "repo": "<org>/<repo>"}}},
"enabledPlugins": {"<plugin_name>@<marketplace-name>": true}}Teammates get a one-time trust prompt, then auto-install. When the contract
includes long headless runs, fold the Step 4 permissions.allow block into
the same snippet.
Step 9 — Wrap up
Report to the user:
- Gates re-passed on the final tree (Step 6).
- Files added:
hooks/scripts/trace-capture.sh, the hooks.json entry,README.md, plussettings.json/monitors/monitors.jsonif chosen. - Version strategy chosen and why; distribution path with the exact consumer commands; settings snippet emitted (or why not).
- Baseline carried into the README: suite vN, pass^3, cost, run timestamp.
- The honest claim: the plugin is "green + holdout + triaged" against suite vN — not proven "correct".
Leave .forge/ in place: it is the flywheel's memory (freeze hash, change
requests, run history). Phase stays ship. To start a fresh forge run in
this project later, forge-eval doctor clears stuck state safely.
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.

