mit einem Klick
ship
// Use when code is ready to ship — creates PRs, merges, deploys, and verifies. Handles the full PR-to-production pipeline. Triggers on /ship.
// Use when code is ready to ship — creates PRs, merges, deploys, and verifies. Handles the full PR-to-production pipeline. Triggers on /ship.
| name | ship |
| description | Use when code is ready to ship — creates PRs, merges, deploys, and verifies. Handles the full PR-to-production pipeline. Triggers on /ship. |
| concurrency | exclusive |
| depends_on | ["review","qa","security"] |
| summary | Release pipeline. PR creation, CI monitoring, post-deploy verification, rollback plan. |
| estimated_tokens | 350 |
| hooks | {"PreToolUse":[{"matcher":"Bash","command":"./ship/bin/pre-ship-check.sh"}]} |
You get code from "done" to "verified in production" in one pass. You own the full pipeline: pre-flight, PR, CI, deploy, verification. If something breaks after merge, you rollback first and debug second.
Defensive telemetry init. No-op if telemetry is disabled via NANOSTACK_NO_TELEMETRY=1, ~/.nanostack/.telemetry-disabled, or if the helpers are removed.
_P="$HOME/.claude/skills/nanostack/bin/lib/skill-preamble.sh"
[ -f "$_P" ] && . "$_P" ship
unset _P
Read profile, run_mode, autopilot, and plan_approval per reference/session-state-contract.md BEFORE doing any pre-flight or pipeline work. This is required for /ship because every subsequent step in this skill mutates state (commit, push, PR, deploy, rollback) and the contract forbids that when run_mode == report_only.
SESSION=$NANOSTACK_STORE/session.json
[ -f "$SESSION" ] || SESSION="$HOME/.nanostack/session.json"
PROFILE=$(jq -r '.profile // (if (.capabilities // null) == null then "guided" else "professional" end)' "$SESSION" 2>/dev/null || echo "professional")
RUN_MODE=$(jq -r '.run_mode // "normal"' "$SESSION" 2>/dev/null || echo "normal")
AUTOPILOT=$(jq -r '.autopilot // false' "$SESSION" 2>/dev/null || echo "false")
PLAN_APPROVAL=$(jq -r '.plan_approval // (if .autopilot then "auto" else "manual" end)' "$SESSION" 2>/dev/null || echo "manual")
When RUN_MODE == "report_only", /ship enters Shipping report mode and MUST NOT mutate anything. The session-state contract is explicit: report-only sprints exist so the user can see what /ship would do without committing the agent to action.
Allowed in report-only:
quality-check.sh.Forbidden in report-only:
git commit, git push, git tag, any other mutating git command.gh pr create, gh pr merge, any other GitHub mutation.fly deploy, vercel deploy, wrangler deploy, etc.).bin/init-project.sh --fix, bin/nano-doctor.sh --fix, any other repair flag..nanostack/ (read-only inspection only). save-artifact.sh ship is skipped by default; treat artifact persistence as a future opt-in (--save-report).If RUN_MODE == "report_only", jump straight from this section to the Report output section at the end of this skill, then stop. Do not run pre-flight, do not run quality-check (it reads only and is fine), do not enter the PR / CI / deploy flow below.
Run source bin/lib/git-context.sh && detect_git_mode.
If local (no git repo): Skip the entire PR/CI/deploy flow below. Instead:
ship/bin/quality-check.sh (already works without git).open index.html (or the main HTML file) so the user sees it instantly. Then say "Se abrió en tu navegador."If local-git (git, no remote): Run pre-ship check and quality check. Skip PR/CI/deploy. Suggest git tag for versioning. Output: "Listo. Commit: [hash]."
If full: Continue with the normal process below.
Run both checks before proceeding:
ship/bin/pre-ship-check.sh # uncommitted changes, missing tests, staged secrets, branch check
ship/bin/quality-check.sh # broken README links, stale references, writing quality, secrets in diff
If either reports errors, fix them before proceeding. Warnings are informational but should be reviewed.
Resolve context and verify review findings were resolved:
~/.claude/skills/nanostack/bin/resolve.sh ship
The output is JSON with upstream_artifacts (review, security, qa paths). If a review artifact exists, read it and check that all blocking findings have been addressed. For each blocking finding, verify the code at the reported file and line no longer has the issue. If a blocking finding is still present, do NOT proceed. Flag it.
Then verify:
# Are there uncommitted changes?
git status
# Do tests pass?
# (use the project's test command — check package.json, Makefile, etc.)
# Is the branch up to date with the target?
git fetch origin && git log --oneline HEAD..origin/main | head -5
If tests fail, fix them first. Do not ship broken code with a "will fix later" comment.
If the branch is behind, rebase or merge:
git rebase origin/main # preferred for clean history
# or
git merge origin/main # if rebase would be messy
Before creating the PR, show the user a full preview. This is a mandatory stop because after creation it's public.
## PR Preview
**Title:** {{title}}
**Branch:** {{branch}} → {{base}}
**Files changed:** {{count}}
### Summary
{{1-3 bullets of what changed and why}}
### Changes
{{file list with one-line description each}}
### Test plan
{{how to verify}}
Wait for user approval. Only proceed after explicit confirmation. If the user adjusts something, update the preview and ask again.
After approval, use the template at ship/templates/pr-template.md for the PR body.
gh pr create \
--title "{{concise title, under 70 chars}}" \
--body "$(cat <<'EOF'
{{filled PR template}}
EOF
)"
PR title rules:
PR body rules:
After creating the PR, check CI status:
gh pr checks <number> --watch
If CI fails:
gh pr checks <number> --fail-onlyAfter the PR is merged:
# Verify merge completed
gh pr view <number> --json state,mergedAt
# Check deploy pipeline
gh run list --limit 3
If the project has a staging/production URL, run a post-deploy checklist:
/qa --quick against prod URL)gh run view --log-failed — any new errors in the deploy?If any check fails: stop and rollback before debugging. A broken prod is worse than a reverted feature.
If something goes wrong after deploy:
# Quick rollback: revert the merge commit
git revert <merge-commit-sha> --mainline 1
gh pr create --title "Revert: {{original PR title}}" --body "Reverting due to {{reason}}"
Document what went wrong for the team.
Before creating the PR, verify the standards in ship/references/repo-quality-standards.md (README links, PR/commit quality, repo hygiene). The public repo is the face of the project. ship/bin/quality-check.sh automates the checks it can; use judgment for the rest.
After shipping, do these steps in order:
Step 1: Save the artifact. Run this command now — do not skip it. The save is validated against the per-phase schema (see reference/artifact-schema.md); a normal-mode ship artifact requires summary (object) and context_checkpoint. Report-only ship runs may save a looser shape with run_mode: "report_only".
The snippet below sets safe JSON defaults first so jq --argjson does not fail when a shell variable is unset (PR_NUMBER may legitimately be unset in local-mode ships, on a no-PR push, or when CI has not reported yet).
# Safe defaults so --argjson always gets valid JSON, even when a
# variable was not exported in this ship path.
: "${PR_NUMBER:=null}"
: "${PR_URL:=}"
: "${PR_TITLE:=}"
: "${PR_STATUS:=open}"
: "${CI_PASSED:=false}"
SHIP_JSON=$(jq -n \
--argjson pr_number "$PR_NUMBER" \
--arg pr_url "$PR_URL" \
--arg title "$PR_TITLE" \
--arg status "$PR_STATUS" \
--argjson ci_passed "$CI_PASSED" \
--arg checkpoint_summary "PR #N <title> shipped, CI status, deploy result." \
'{
phase: "ship",
summary: {
pr_number: $pr_number,
pr_url: $pr_url,
title: $title,
status: $status,
ci_passed: $ci_passed
},
context_checkpoint: {
summary: $checkpoint_summary,
key_files: [],
decisions_made: [],
open_questions: []
}
}')
~/.claude/skills/nanostack/bin/save-artifact.sh ship "$SHIP_JSON"
~/.claude/skills/nanostack/bin/sprint-journal.sh
For a report-only ship (no PR cut, no commit), save the artifact with run_mode: "report_only" instead so the validator accepts the looser shape:
~/.claude/skills/nanostack/bin/save-artifact.sh ship \
'{"phase":"ship","run_mode":"report_only","summary":"Pre-flight check only; nothing was pushed."}'
Step 2: Proof block. Before "How to see the result", emit a proof block summarizing what was verified during the sprint. Read it from session phase_log:
SESSION=$NANOSTACK_STORE/session.json
[ -f "$SESSION" ] || SESSION="$HOME/.nanostack/session.json"
jq -r '
([.phase_log[]? | select(.phase == "review" and .status == "completed")] | length) as $rev |
([.phase_log[]? | select(.phase == "security" and .status == "completed")] | length) as $sec |
([.phase_log[]? | select(.phase == "qa" and .status == "completed")] | length) as $qa |
"Reviewed: \(if $rev > 0 then "yes" else "no" end)\n" +
"Security checked: \(if $sec > 0 then "yes" else "no" end)\n" +
"QA checked: \(if $qa > 0 then "yes" else "no" end)"
' "$SESSION" 2>/dev/null
If a phase says no, list it under "Not verified" so the user sees what was skipped instead of inferring it from absence.
Step 3: How to see the result.
Read profile from session per reference/session-state-contract.md. The branch differs by profile:
If profile == "guided" (or no git remote, even when professional): Skip the deployment menu and focus on how to try the result locally. Tell the user where the entry point is and the exact command to run, then list anything that is not yet verified (e.g. "I did not deploy this to the internet"). One next action only. Follow reference/plain-language-contract.md for wording. Example:
Resultado: Listo para probar.
Como verlo:
1. Abri index.html en el navegador.
Que revise:
- La pantalla carga.
- El boton principal responde.
- No encontre secretos en archivos visibles.
Pendiente:
- No esta publicado en internet todavia.
- No revise la seguridad de las dependencias.
If profile == "professional" and autopilot == true: Skip this question. Go directly to Next Step (compound + sprint summary). The user will decide how to run it after the sprint closes.
Otherwise (professional, manual), ask:
How do you want to see it?
- Local — I'll start the server and show you how to open it
- Production — I'll guide you through deploying to the internet
- I'm done — just the commit
If Local (option 1):
index.html in your browser"npm start, node src/server.js, etc.) and tell the user the URLopen commands. Show the path and let the user decide.If Production (option 2): Detect project type, recommend ONE provider (Next.js→Vercel, Node→Railway, Static→Cloudflare Pages, Python→Railway, Go→Fly.io). Walk through: account, connect repo, env vars, push. Mention domain (~$10/yr), SSL (automatic), monitoring (Sentry free + UptimeRobot free). Show monthly cost.
If Done (option 3): Skip to next features.
When RUN_MODE == "report_only", this is the only section that runs. It produces a summary the user can read and act on; the agent itself does not commit to any action.
The report has four blocks:
.nanostack/. List which of review / security / qa are present and pass. Use bin/find-artifact.sh <phase> 1 to confirm freshness. If any are missing or stale, name them.To ship for real:
/review # missing
/security # missing
/qa # missing
session.sh init development --run-mode normal
/ship
Use the wording in reference/plain-language-contract.md when PROFILE == "guided" (Resultado / Como verlo / Que revise / Pendiente). Professional output may keep technical terms (PR, CI, branch).
Stop after printing the report. Do not call telemetry-finalize with success; pass report_only so the event reflects what actually happened.
Close with a summary:
Ship: PR #N created. CI passed.
Tests: X → Y (+N new). No regressions.
Include before/after test counts when tests were added. Quantify the improvement.
Before handing off to compound or the user:
_F="$HOME/.claude/skills/nanostack/bin/lib/skill-finalize.sh"
[ -f "$_F" ] && . "$_F" ship success
unset _F
Pass abort or error instead of success if ship did not complete normally.
After shipping, two things happen in order:
First: capture learnings. Run compound immediately:
Use Skill tool: skill="compound"
Do not ask. Do not skip. Compound reads the sprint artifacts and saves solutions for future sprints.
Then: close the sprint. This is the last thing the user sees. Make it count.
1. What was built. Summarize what the user now has in plain language. Not phase names or artifact counts. What does the thing DO, where is it, and how to use it.
2. How to use it. Show the exact command or URL to try it right now.
3. What could come next. Suggest 2-3 concrete extensions as /feature commands the user can run immediately.
Example:
Sprint complete. You have a JSON validator CLI.
Try it:
node src/index.js test.jsonIdeas for the next feature:
/feature Add --format flag to pretty-print valid JSON/feature Add directory mode: jsonlint schemas/*.json/feature Add --fix mode that auto-corrects trailing commas
Use when working near production, sensitive systems, or destructive operations. Activates on-demand safety hooks that block dangerous commands. Supports modes — careful (warn), freeze (guided, keeps writes within scope), unfreeze (remove restrictions). Triggers on /guard, /careful, /freeze, /unfreeze.
Orchestrate parallel agent sessions through a sprint. Coordinates task claiming, dependency resolution, and artifact handoff between independent agents. Triggers on /conductor, /sprint, /parallel.
Add a feature to an existing project with a full sprint. Skips /think diagnostic, goes straight to planning. Use when the user knows what they want and the project already exists. Triggers on /feature.
Use to verify that code works correctly — browser-based testing with Playwright, native app testing with computer use, CLI testing, API testing, or root-cause debugging. Supports --quick, --standard, --thorough modes. Triggers on /qa.
Use when starting non-trivial work (touching 3+ files, new features, refactors, bug investigations). Produces a scoped, actionable implementation plan before any code is written. Triggers on /nano.
Use after writing code to get a thorough code review. Runs two passes — structural correctness then adversarial edge-case hunting. Scales depth by diff size. Supports --quick, --standard, --thorough modes. Triggers on /review.