- name
- ship
- description
- Finish a branch: infer which review passes the change warrants, run them, open the PR, babysit CI to green, triage bot comments, and refresh the body from a clean context.
- argument-hint
- [--merge] [--effort <level>] [--simplify] [--human] [--skip <pass>] [--base <ref>]
- allowed-tools
- ["Agent","AskUserQuestion","Bash(git diff:*)","Bash(git status:*)","Bash(git fetch:*)","Bash(git rev-parse:*)","Skill(plan:review)","Skill(code-review)","Skill(simplify)","Skill(run)","Skill(comments:audit)","Skill(github:copilot)","Skill(prompting:scan)","Skill(prompting:prompting)","Skill(writing:review)","Skill(review:human)","Skill(pull-request:create)","Skill(pull-request:babysit)","Skill(pull-request:follow-up)"]
# Ship
Gate review passes on the diff, run them in order, open the PR, babysit CI to green, refresh the body from a clean context. Each pass fans out on its own; ship only gates and orders.
Default end state **green and ready**: CI green, bot comments triaged, body refreshed, stopped for your web review. `--merge` drives to merged.
## Context
- Working tree: !`git status --short`
## Decide What Applies
Resolve the base to a **remote** ref so ship's view matches what the PR merges against. From the base branch (default `main`, or `--base <parent>` on a stack), take its tracking ref via `git rev-parse --abbrev-ref --symbolic-full-name <base>@{u}`, falling back to `origin/<base>`. Fetch it first (`git fetch`) so a stale local `<base>` never inflates the diff with already-merged commits. Diff `git diff <resolved>...HEAD`, plus a plain `git diff` for uncommitted work, and thread the resolved ref as `--base` to every gated pass that takes it. `code-review` takes the range `<resolved>...HEAD` as its target instead. Gate each pass on the file set, its size, and the content behind any judgment call (new comments, refactor or new behavior). Full matrix and heuristics: [`references/passes.md`](references/passes.md).
- **`plan:review`**: a substantial approved plan is in context (`~/.claude/plans/` file) *and* the session ran long or redirected enough that the diff could have drifted from it. Skip otherwise ([full gate](references/passes.md#plan-review)).
- **Correctness and quality**: code changed. Exactly one of `code-review <effort> --fix` (default) or `simplify` (pure refactor, no new behavior). Skip on docs/config-only.
- **`comments:audit`**: diff adds code comments.
- **`pull-request:follow-up --local`**: a supported review bot is available for the repo *and* the diff clears the [Bot Review Gate](references/passes.md#bot-review-gate). Runs the hosted reviewer locally before the PR exists.
- **`github:copilot`**: code changed on a repo I own *and* the diff clears the [Cross-Model Gate](references/passes.md#cross-model-gate). A second model reads the diff before the PR exists.
- **`prompting:scan`**: diff touches a document a model executes: `CLAUDE.md`, `AGENTS.md`, `SKILL.md`, a skill's `references/`, `.claude/agents`, `.claude/commands`, `.claude/rules`, or a `prompt/` or `prompts/` dir. Fix confirmed findings with the `prompting` skill.
- **`writing:review`**: diff touches prose people read (READMEs, docs, `.mdx`, `.rst`), excluding the prompt files above. A diff with both runs both passes, each over its own files.
- **`run`**: diff has a runtime surface. Drive the change in the real app, not just tests. Skip on docs-only and tests-only.
- **`review:human`**: the diff clears the [Human Review Gate](references/passes.md#human-review-gate), which skips trivial diffs. Ben reads the cleaned diff last, for architecture and slop.
Infer, don't interrogate. Present the plan in one line, then proceed. `AskUserQuestion` only on a real toss-up: refactor versus behavior change, or `medium` versus `high` effort.
## Flags
- `--merge`: drive to merged (babysit `--merge`). Default: green and ready.
- `--effort <low|medium|high|xhigh>`: override inferred `code-review` effort.
- `--simplify`: force `simplify` over `code-review`.
- `--human`: force `review:human` on a diff the gate skips.
- `--skip <pass>` (repeatable): drop a gated pass. Names: `plan`, `code-review` (the old `review:code` is accepted as an alias), `simplify`, `comments`, `bot`, `copilot`, `prompting`, `writing`, `run` (the old `verify` is accepted as an alias), `human`.
- `--base <ref>`: base branch for gating. Default `main`; on a stack, the parent branch. Resolved to its upstream tracking ref (e.g. `origin/...`) before diffing.
## Pre-PR Reviews
Serialized before create: `code-review --fix`, `simplify`, and comment trims all write to the branch. `plan:review`, when gated in, is read-only, so it runs as a background dispatch alongside these and joins before create rather than gating them. [`references/passes.md`](references/passes.md) has the DAG.
1. **`comments:audit`**: needs a clean tree (the fix passes dirty it), lands trims via fast-forward (see [Comment Trims](#comment-trims)). Its preflight fans out on its own at diff scale and asks only past ten agents.
2. **`pull-request:follow-up --local`**: reviews committed work only and commits its own fixes, so it runs while the tree is still clean, before the fix passes. Pass the resolved base.
3. **`github:copilot`**: the cross-model pass, in the same slot and for the same reason. Findings triage and fix in-branch. It spends a metered credit allotment. [`references/passes.md`](references/passes.md) gates it.
4. **Correctness and quality**: `code-review <effort> --fix` or `simplify`.
5. **`prompting:scan`** over touched prompt files. Fix confirmed findings with the `prompting` skill.
6. **`writing:review`** over touched human prose. Address salient findings before the body is written.
7. **`run`** to drive the change end to end.
8. **Join `plan:review`** when it was gated in, and act on fix-worthy drift before the human review sees the diff. Carry deferred follow-ups into the report.
9. **`review:human`** when gated in: after every fix pass and the join, so the cleaned diff is what gets seen ([Human Review Gate](references/passes.md#human-review-gate)). Terminal mode by default: it ends the turn, and Create runs only when the review resumes with approval.
Dirty tree at the comment pass: ask whether to commit first. `comments:audit` operates on `HEAD` and needs a clean tree.
#### Comment Trims
`comments:audit` commits trims to a fresh `comments/audit-<hash>` branch off `HEAD`, leaving the tree untouched. Run `comments:audit --base <base> --fix` and capture the branch name. No branch means nothing to trim: skip. Otherwise dispatch a short-lived `general-purpose` Agent with that name to fast-forward and delete it (rationale and rejected alternatives: [`references/passes.md`](references/passes.md#comment-trims)):
```
git merge --ff-only comments/audit-<hash>
git branch -d comments/audit-<hash>
```
## Create
The plan-review join and any human review are behind you. `pull-request:create` commits the working-tree fixes, pushes, opens the PR. Capture the URL: babysit and body-refresh need it.
Pass `--no-review-body` through whenever `review:human` did not run, gated out or dropped by `--skip human`, so create's own body review honors the skip.
Pass `--base <parent>` through when `/ship --base` named a stack parent. Create needs it to target the PR at the parent and to link the layer into the stack on GitHub. Without it the PR opens against the default branch and carries every lower layer's diff.
Pass `--label review` only when the [Bot Review Gate](references/passes.md#bot-review-gate) routed to the hosted channel (local CLI unavailable); the review then starts with the PR. A local pass already covered the diff, so labeling after it pays a second credit for the same review.
## Babysit
`pull-request:babysit <url>` watches CI and fixes trivial failures to green.
- `--reviews` (default on): after first green, hand bot comments to `pull-request:follow-up --auto`. Covers a bot review landing after the green push with no CI event to key off ([why](references/passes.md#babysit-and-reviews)).
- `--merge`: only when `/ship --merge` was passed; else stop at green.
## Refresh the Body
Dispatch a background `general-purpose` Agent (cheaper model if set) to run `pull-request:update <url>` on every run that opened a PR. Never `fork`: it must read the final PR and diff cold, not this session's transcript, so the body describes the finished change with no review narration.
## Report
PR link, passes run and gated out, final state (green and ready, or merging), and whether the body refresh was dispatched.
GitHub에서 보기