From ship
Autonomous PR lifecycle — push to merged with zero babysitting. Idempotent — run repeatedly to resume from wherever you left off.
How this command is triggered — by the user, by Claude, or both
Slash command
/ship:shipThe summary Claude sees in its command listing — used to decide when to auto-load this command
# /ship — Autonomous PR Lifecycle Take the current branch from wherever it is to merged. Idempotent — detect current state and resume from there. Run `/ship` as many times as needed; it always picks up where it left off. Do the work. Don't describe a checklist — execute each phase, capture evidence, and report terse status updates. ## Step 0: Detect State & Resume Before running any phase, figure out where we are: **Route to the right phase:** 1. **Already merged** (`PR_EXISTS.state == MERGED`) → Report: `Already merged.` Done. 2. **In merge queue** (`PR_EXISTS.mergeStateStatus == B...
Take the current branch from wherever it is to merged. Idempotent — detect current state and resume from there. Run /ship as many times as needed; it always picks up where it left off.
Do the work. Don't describe a checklist — execute each phase, capture evidence, and report terse status updates.
Before running any phase, figure out where we are:
BRANCH = git rev-parse --abbrev-ref HEAD
PR_EXISTS = gh pr view --json number,url,isDraft,title,body,state,mergeStateStatus,headRefOid 2>/dev/null
Route to the right phase:
PR_EXISTS.state == MERGED) → Report: Already merged. Done.PR_EXISTS.mergeStateStatus == BEHIND or auto-merge is enabled) → skip to Phase 3.3 (monitor queue).To detect Greptile state: call list_merge_request_comments with greptileGenerated: true, addressed: false. If comments exist, there's unresolved review work.
To detect auto-merge: gh pr view --json autoMergeRequest -q .autoMergeRequest. Non-null means auto-merge is enabled (we're queued or waiting for checks).
Report: Resuming from Phase <N>. (or Starting fresh. if no prior state)
Verify ALL of these. If any fail, STOP with the exact reason.
main or master.git status --porcelain is empty). If non-empty, STOP: "Dirty worktree. Commit or stash changes first."gh auth status.WIP, wip, draft, or DRAFT.list_pull_requests (limit 1). If the tool errors, STOP: "Greptile MCP tools unavailable."Report: Preflight: OK
Push the branch:
git push -u origin HEAD
Check for existing PR:
gh pr view --json number,url,isDraft,title,body,headRefOid
gh pr create --fillgh pr readyRecord PR_NUMBER, PR_URL, and HEAD_SHA.
Extract repo owner/name: gh repo view --json nameWithOwner -q .nameWithOwner
Report: Phase 1: PR #<N> created/found (<URL>)
Set ITERATION = 0, MAX_ITERATIONS = 5.
ITERATION += 1. If ITERATION > MAX_ITERATIONS:
Record HEAD_SHA via git rev-parse HEAD.
Poll for the latest completed review:
list_code_reviews with the PR number, status COMPLETED, limit 1.completedAt is AFTER the push, proceed.trigger_code_review once, then poll another 5 minutes.On resume: If there's already a completed review newer than HEAD_SHA, skip waiting and read it directly.
gh pr view --json body -q .body — Greptile writes its summary and score here (if shouldUpdateDescription is enabled in greptile.json).get_code_review with the review ID → get score.list_merge_request_comments with greptileGenerated: true, addressed: false.Report: Phase 2: Greptile review (iteration <N>/5) — Score X/5, N unresolved comments.
gh pr view --json reviewDecision -q .reviewDecision returns CHANGES_REQUESTED from a non-bot) → STOP: "Human reviewer requested changes."For each actionable unresolved Greptile comment:
gh api repos/{owner}/{repo}/pulls/{pr}/comments/{comment_id}/replies -f body="<terse reply>"
Good: "done", "moved to a const", "added guard clause", "yep good catch"
Bad: "Fixed: extracted to a named constant", "Great suggestion! I've updated the code to..."gh api repos/{owner}/{repo}/pulls/{pr}/comments/{comment_id} --jq .node_id
gh api graphql -f query='mutation { resolveReviewThread(input: {threadId: "<thread_node_id>"}) { thread { isResolved } } }'
If you disagree with a comment or it needs human judgment, reply with why (still terse) and leave it unresolved.
Stage changed files (never stage .env, credentials, or secrets). Commit with a message describing what changed. Push.
Update HEAD_SHA = git rev-parse HEAD.
Report: Phase 2: Fixed N comments, resolved threads. Pushed.
Go back to Loop start.
On resume: If auto-merge is already enabled, skip to 3.3.
gh pr checks --watch
If any check fails → STOP: "PR check failure: ." Include the failing output.
Report: Phase 3: PR checks passed.
gh pr merge --auto --squash --delete-branch
If the repo uses a merge queue, this enters it. If not, this waits for required checks then merges.
Report: Phase 3: Auto-merge enabled.
Poll every 60 seconds:
gh pr view --json state,mergeStateStatus -q '.state + " " + .mergeStateStatus'
gh pr checks --json name,state,conclusion
gh pr merge --auto --squash --delete-branch
Phase 3: Non-deterministic test failure. Requeue <N>/2.Report: Phase 3: Merged PR #<N>. Branch deleted.
| Condition | Phase | Message |
|---|---|---|
| Default branch | Preflight | "Cannot ship from main/master." |
| Dirty worktree | Preflight | "Dirty worktree. Commit or stash." |
| WIP/draft in branch name | Preflight | "Branch name contains WIP/draft." |
| WIP/draft in PR title/body | Phase 1 | "PR marked as WIP/draft." |
gh auth fails | Preflight | "GitHub CLI not authenticated." |
| Greptile tools unavailable | Preflight | "Greptile MCP tools unavailable." |
| Human requested changes | Phase 2 | "Human reviewer requested changes." |
| Greptile non-convergence | Phase 2 | "Non-convergence after 5 iterations." |
| Greptile review timeout | Phase 2 | "Greptile review timeout (10 min)." |
| PR check failure | Phase 3 | "Check failure: ." |
| Ambiguous merge failure | Phase 3 | "Merge failure: . Unable to classify." |
| 2 requeues exhausted | Phase 3 | "Persistent test failure after 2 requeues." |
| Merge conflicts | Any | "Merge conflicts detected." |
Terse. One line per phase transition. No walls of text. Examples:
First run:
Preflight: OK
Starting fresh.
Phase 1: PR #745 created (https://github.com/org/repo/pull/745)
Phase 2: Greptile review (iteration 1/5) — Score 3/5, 4 unresolved.
Phase 2: Fixed 3 comments, resolved threads. 1 left (style preference, disagree). Pushed.
Phase 2: Greptile review (iteration 2/5) — Score 5/5, 0 unresolved. Proceeding.
Phase 3: PR checks passed. Auto-merge enabled.
Phase 3: Merged PR #745. Branch deleted.
Resume after a previous stop:
Preflight: OK
Resuming from Phase 2. PR #745 exists, 2 unresolved Greptile comments.
Phase 2: Fixed 2 comments, resolved threads. Pushed.
Phase 2: Score 5/5, 0 unresolved. Proceeding.
Phase 3: Merged PR #745. Branch deleted.
Resume when already queued:
Preflight: OK
Resuming from Phase 3.3. PR #745 auto-merge enabled.
Phase 3: Merged PR #745. Branch deleted.
npx claudepluginhub refactornator/ship --plugin ship/shipOrchestrates parallel pre-launch checklist via specialist personas for code review, security audit, and test coverage, synthesizing go/no-go decision with rollback plan.
/shipExecutes universal 8-phase shipping workflow for code, content, marketing, sales, research, or any project. Supports dry-run, auto-approve, force, rollback, monitor, type/target overrides, checklist-only, and iterations flags.
/shipPushes the current branch, creates a pull request with an auto-generated body, optionally triggers review, and tracks merge to close the development loop after verification passes.
/shipExecutes full feature shipping workflow: verifies readiness, runs checks, deploys to staging then production, verifies, and announces. Outputs formatted status summary.
/shipExecutes full PR workflow from commit to production: pre-flight checks, PR creation, CI/review monitoring, merge, deployment, and validation with quality gates.
/shipArchives completed feature artifacts (define, design, build report) and creates a shipped summary with lessons learned. Part of a 5-phase AgentSpec workflow.