mcpField
S
ship

ship

github.com/borkwebDevelopment846 installsUpdated 2d ago
Repository

About ship

ship is an automated workflow for taking feature-branch changes through review, tests, commits, release metadata updates, and pull request creation. It groups changes into bisectable commits and stops for failures or decisions that require human judgment.

Key features

  1. 01Merges the base branch before testing
  2. 02Runs project tests and pre-landing reviews
  3. 03Automatically fixes eligible review findings
  4. 04Organizes changes into bisectable commits
  5. 05Updates version and changelog when present
  6. 06Prepares a pull request

Use cases

  1. 01Shipping a feature branch as a pull request
  2. 02Running checks and review before landing
  3. 03Splitting a large changeset into logical commits

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/borkweb/skills --skill ship

After installing, type/shipin Claude Code to confirm it loaded.

Details

From the project README

Step 0: Detect base branch

Determine which branch this PR targets. Use the result as "the base branch" in all subsequent steps.

Run the shared helper:

BASE=$(bash "$CLAUDE_PLUGIN_ROOT/scripts/detect-base-branch.sh")

The helper checks (in order) the current PR's baseRefName, the repo's default branch, then falls back to main. It always prints a usable name.


Ship: Fully Automated Ship Workflow

You are running the /ship workflow. This is a non-interactive, fully automated workflow. Do NOT ask for confirmation at any step. The user said /ship which means DO IT. Run straight through and output the PR URL at the end.

Only stop for:

  • On the base branch (abort)
  • Merge conflicts that can't be auto-resolved (stop, show conflicts)
  • Test failures (stop, show failures)
  • Pre-landing review finds ASK items that need user judgment
  • MINOR or MAJOR version bump needed (ask — see Step 5)

Never stop for:

  • Uncommitted changes (always include them)
  • Version bump choice (auto-pick MICRO or PATCH — see Step 5)
  • CHANGELOG content (auto-generate from commits)
  • Commit message approval (auto-commit)
  • Multi-file changesets (auto-split into bisectable commits)
  • TODOS.md completed-item detection (auto-mark)
  • Auto-fixable review findings (dead code, N+1, stale comments — fixed automatically)

Step 1: Pre-flight

  1. Check the current branch. If on the base branch, abort: "You're on the base branch. Ship from a feature branch."

  2. Run git status (never use -uall). Uncommitted changes are always included — no need to ask.

  3. Run git diff <base>...HEAD --stat and git log <base>..HEAD --oneline to understand what's being shipped.

  4. Detect linked issues. Scan for issue references in:

    • Branch name (e.g., fix/123-broken-login, feature/GH-45)
    • Commit messages (Fixes #123, Closes #45, Relates to #78)
    • TODOS.md entries that reference issues Collect all issue numbers — they go into the PR body in Step 9.

Recovery: If git status or git log fails (e.g., corrupted index), run git fsck and report. Do not proceed.


Step 2: Merge the base branch (BEFORE tests)

Fetch and merge the base branch into the feature branch so tests run against the merged state:

git fetch origin <base> && git merge origin/<base> --no-edit

If there are merge conflicts: Try to auto-resolve if they are simple (VERSION, schema, CHANGELOG ordering). If conflicts are complex or ambiguous, STOP and show them.

If already up to date: Continue silently.

Recovery: If git fetch fails (network, auth), report the error and STOP. If git merge fails for reasons other than conflicts (e.g., unrelated histories), report and STOP.


Step 3: Run tests (on merged code)

Detect the project's test command from the codebase (package.json scripts, Makefile, Gemfile, etc.) and run it.

If any test fails: Show the failures and STOP. Do not proceed.

If all pass: Continue silently — just note the counts briefly.

Recovery: If the test runner itself fails to execute (missing deps, config error), report the error clearly. Do not treat "runner crashed" as "tests passed."


Step 3.5: Pre-Landing Review (delegated to review skill)

Delegate the review to the /review skill's checklist rather than duplicating its logic.

  1. Read checklist.md from the review skill directory (skills/gstack/review/checklist.md). If not found, STOP and report.

  2. Read design-checklist.md from the review skill directory (skills/gstack/review/design-checklist.md). Keep available for Step 3.5.4.

  3. Run git diff origin/<base> to get the full diff.

  4. Apply the review in two passes per the checklist:

    • Pass 1 (CRITICAL): SQL & Data Safety, Migration & Schema Safety, Race Conditions & Concurrency, Auth & Permission Gaps, LLM Output Trust Boundary, Enum & Value Completeness, API Contract Breaking Changes
    • Pass 2 (INFORMATIONAL): Error Handling Anti-Patterns, Conditional Side Effects, Magic Numbers & String Coupling, Dead Code & Consistency, LLM Prompt Issues, Test Gaps, Crypto & Entropy, Time Window Safety, Type Coercion at Boundaries, View/Frontend, Performance & Bundle Impact
  5. Check for frontend changes:

    bash "$CLAUDE_PLUGIN_ROOT/scripts/detect-frontend-files.sh" "$BASE"
    

    If any files print, apply the design checklist (loaded in step 2). Check for DESIGN.md in the repo root first — patterns blessed there are not flagged.

  6. Classify each finding as AUTO-FIX or ASK per the Fix-First Heuristic in the checklist. Critical findings lean toward ASK; informational lean toward AUTO-FIX.

  7. Auto-fix all AUTO-FIX items. Output one line per fix: [AUTO-FIXED] [file:line] Problem → what you did

  8. If ASK items remain, present them in ONE AskUserQuestion:

    • List each with number, severity, problem, recommended fix
    • Per-item options: A) Fix B) Skip
    • Overall RECOMMENDATION
  9. After all fixes (auto + user-approved):

    • If ANY fixes were applied: commit fixed files, then re-run tests before continuing.
    • If no fixes applied: continue to Step 4.
  10. Output summary: Pre-Landing Review: N issues — M auto-fixed, K asked (J fixed, L skipped)

Save the review output — it goes into the PR body in Step 9.


Step 3.7: Adversarial review

Dispatch an adversarial reviewer via the Agent tool when the diff meets ANY of:

  • More than 200 lines changed
  • Touches auth, payment, or security-related files
  • Introduces new external service integrations
  • Contains new cryptographic operations or secret handling

For diffs under 200 lines that don't touch sensitive files, skip this step.

Subagent prompt: "Read the diff for this branch with git diff origin/<base>. Think like an attacker and a chaos engineer. Your job is to find ways this code will fail in production. Look for: edge cases, race conditions, security holes, resource leaks, failure modes, silent data corruption, logic errors that produce wrong results silently, error handling that swallows failures, and trust boundary violations. Be adversarial. Be thorough. No compliments — just the problems. For each finding, classify as FIXABLE (you know how to fix it) or INVESTIGATE (needs human judgment)."

Present findings. FIXABLE findings flow into the Fix-First pipeline (auto-fix, re-run tests if code changed). INVESTIGATE findings are informational only.

Save the adversarial review output — it goes into the PR body in Step 9.


Step 4: Commit (bisectable chunks)

Goal: Create small, logical commits that work well with git bisect.

  1. Group changes into logical commits. Each = one coherent change.

  2. Commit ordering — use this as a default, adapt to the project structure:

    • Foundation changes first: migrations, config, schema, routes, dependencies
    • Core logic next: models, services, libraries (with their tests)
    • Surface layer last: controllers, views, CLI commands (with their tests)
    • Metadata always final: VERSION + CHANGELOG + TODOS.md in the last commit

    For libraries or CLI tools, adapt: core API → internal modules → public interface → metadata. For monorepos, group by package rather than layer.

  3. Rules:

    • A module/service and its test go in the same commit
    • If total diff is small (< 50 lines across < 4 files), a single commit is fine
    • Each commit must be independently valid — no broken imports
  4. Compose commit messages: <type>: <summary> (feat/fix/chore/refactor/docs)


Step 5: Version bump (auto-decide)

If a VERSION file exists:

  1. Read the current version.

  2. Auto-decide the bump level based on what changed, not just how much:

    MICRO (auto) — internal-only changes:

    • Bug fixes, typos, comment updates, test-only changes
    • Refactors that don't change public API or behavior
    • Documentation updates

    PATCH (auto) — user-facing but non-breaking:

    • Bug fixes that change observable behavior
    • Performance improvements
    • New optional parameters with defaults
    • Dependency updates

    MINOR (ASK) — new capability:

    • New endpoints, commands, features, or public API methods
    • New database tables or significant schema additions
    • New external service integrations

    MAJOR (ASK) — breaking changes:

    • Removed or renamed public API methods/endpoints
    • Changed response formats or required parameters
    • Database migrations that require data transformation
    • Dropped support for a runtime/platform
  3. Compute and write the new version.

If no VERSION file exists, skip this step.


Step 6: CHANGELOG (auto-generate)

If a CHANGELOG.md exists:

  1. Read the header to know the format.

  2. Auto-generate the entry using commit messages from Step 4 as the primary signal:

    • Commits prefixed feat: → ### Added
    • Commits prefixed fix: → ### Fixed
    • Commits prefixed refactor: / chore: → ### Changed
    • Commits that remove features → ### Removed
    • Fall back to diff analysis for any uncategorized changes
    • Write concise, descriptive bullet points
    • Insert after the file header, dated today

Do NOT ask the user to describe changes. Infer from commits and diff.

If no CHANGELOG.md exists, skip this step.


Step 6.5: TODOS.md (auto-update)

If TODOS.md exists:

  1. Cross-reference the diff against open TODOs
  2. Auto-mark completed items — only when the diff clearly shows the work is done (be conservative)
  3. Move completed items to a Completed section with version and date
  4. Output summary: TODOS.md: N items marked complete. M items remaining.

If TODOS.md doesn't exist, skip silently.


Step 6.7: Plan Completion Audit

If a plan file exists for this branch, verify that everything in the plan actually shipped. Skip silently if no plan file is found.

Plan File Discovery
  1. Conversation context (primary): If the host agent's system messages reference a plan file path, use it directly.
  2. Filesystem search (fallback): Look in docs/plans/, docs/designs/, .claude/plans/, project root for a markdown file matching the current branch name. Take the most recently modified match. If multiple candidates exist and none clearly matches, treat as "no plan file found."
  3. Validation: Read the first 20 lines. If it doesn't appear related to the current branch's work, treat as "no plan file found."

If no plan file is found: Skip with "No plan file detected — skipping plan completion audit." Continue to Step 7.

Dispatch as Subagent

Use the Agent tool with subagent_type: "general-purpose". The subagent reads the plan and the diff in fresh context; parent gets the conclusion. Subagent prompt:

Audit plan completion for the current branch. Base branch: <base>. Plan file: <path>.

Extract actionable items from the plan: checkboxes (- [ ] / - [x]), numbered implementation steps, imperative statements ("Add X", "Create Y"), file-level specs, test requirements, data model changes. Cap at 50 items. Ignore Context/Background/Problem sections, open questions ("TBD", "TODO: decide"), explicitly deferred items ("Out of scope:", "Future:", "P2:", "P3:"), and previous review reports.

Classify how each item can be verified:

  • DIFF-VERIFIABLE — Would show up in git diff <base>...HEAD for this repo.
  • CROSS-REPO — Names a file in a sibling repo. Try [ -f <path> ] if the path is reachable; UNVERIFIABLE if not.
  • EXTERNAL-STATE — Names state in an external system (DNS, OAuth allowlist, SaaS config). Always UNVERIFIABLE.
  • CONTENT-SHAPE — File must follow a convention. Run any project validator (validate-*, lint-docs, etc.) before falling back to UNVERIFIABLE.

Path concreteness rule: If a plan item names a concrete filesystem path, it MUST be DONE or NOT DONE based on [ -f <path> ]. UNVERIFIABLE is only valid when the path is genuinely abstract or unreachable.

Status per item:

  • DONE — Clear evidence in the diff or filesystem. Cite the file(s).
  • PARTIAL — Some work toward the item exists but incomplete.
  • NOT DONE — Verification ran and produced negative evidence.
  • CHANGED — Implemented differently but same goal achieved; note the difference.
  • UNVERIFIABLE — Cannot prove or disprove. Cite the specific manual check.

Honesty rule: Code that handles a deliverable is not the deliverable. Shipping a markdown-extraction library is not the same as shipping the markdown file. When in doubt between DONE and UNVERIFIABLE, prefer UNVERIFIABLE.

Output a markdown checklist grouped by category (Implementation / Tests / Migrations / Cross-Repo / External) with [STATUS] prefixes. End with a summary line: COMPLETION: X/Y DONE, A PARTIAL, B NOT DONE, C CHANGED, D UNVERIFIABLE.

Gate Logic

After the subagent returns, evaluate in priority order:

  1. Any NOT DONE items (known missing work). Use AskUserQuestion:

    • Show the completion checklist.
    • "{N} items from the plan are NOT DONE."
    • Options: A) Stop — implement before shipping. B) Ship anyway — defer as P1 TODOs. C) Intentionally dropped — remove from scope.
    • RECOMMENDATION: A if core functionality missing, B for minor docs/config.
    • On A: STOP. On B: continue, append Deferred from plan: {path} to TODOS.md for each. On C: continue, note in PR body.
  2. Any UNVERIFIABLE items (only after NOT DONE is resolved or absent). Per-item confirmation is mandatory — no blanket-confirm. Loop one at a time:

    • For each item, AskUserQuestion with that item's specific manual check ("Confirm: does ~/path/to/file exist?", not "Have you checked all items?").
    • Per-item options: Y) Confirmed done — cite what you verified (free-text). N) Not done — block ship, re-enter priority 1. D) Intentionally dropped.
    • On any N: STOP. On all Y or D: continue, embed ## Plan Completion — Manual Verifications in PR body with each Y'd item's evidence and each D'd item marked dropped.
    • Cap: If more than 5 UNVERIFIABLE items, present them as a list first and ask: (1) confirm each individually [recommended], (2) stop and reduce scope, (3) explicitly accept blanket-confirmation (warn this is the failure shape that prompted this gate).
  3. Only PARTIAL items (no NOT DONE, no UNVERIFIABLE): Continue with a note in PR body. Not blocking.

  4. All DONE or CHANGED: Pass. Continue.

Fail-Closed on Subagent Failure

If the subagent fails or returns malformed output, do NOT silently pass. Try once to run the extraction inline in the parent context. If that also fails, surface as AskUserQuestion:

"Plan Completion audit could not run ({reason}). Options: A) Skip audit and ship anyway — record that the audit was skipped in the PR body. B) Stop and fix the audit."

RECOMMENDATION: B. Silent fail-open is the failure shape this gate exists to prevent.

PR Body

Add a ## Plan Completion section to the PR body in Step 9 with the checklist summary. If UNVERIFIABLE items were confirmed via per-item flow, also add ## Plan Completion — Manual Verifications listing each confirmation.


Step 7: Verification Gate

IRON LAW: NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE.

Before pushing, re-verify if code changed during Steps 4-6.5:

  1. If ANY code changed after Step 3's test run (review fixes, etc.), re-run tests. Paste fresh output.
  2. If the project has a build step, run it.
  3. If tests fail: STOP. Do not push.

Step 8: Push

git push -u origin <branch-name>

Recovery: If push fails:

  • Branch protection / pre-receive hook rejection: Report the error. Do NOT force push. Suggest what the user needs to fix (e.g., required reviewers, status checks).
  • Authentication failure: Report and STOP.
  • Diverged remote (non-fast-forward): Report and STOP. Do NOT force push. Suggest git pull --rebase origin <branch-name> and re-running verification.

Step 9: Create PR

Step 9.1: Detect PR metadata
  1. Labels: Check for repo label conventions:

    gh label list --limit 20 --json name --jq '.[].name'
    

    Auto-apply labels that match the change type:

    • bug / bugfix for fix: commits
    • enhancement / feature for feat: commits
    • dependencies if lockfiles changed
    • Size labels if the repo uses them (S/M/L based on diff lines) If no matching labels exist, skip — don't create new labels.
  2. Reviewers: Check for CODEOWNERS:

    cat .github/CODEOWNERS 2>/dev/null || cat CODEOWNERS 2>/dev/null
    

    If CODEOWNERS exists, let GitHub auto-assign. Otherwise, skip reviewer assignment.

  3. Draft mode: Create as draft (--draft) if ANY of:

    • Branch name starts with wip/ or draft/
    • Any commit message contains [WIP] or [DRAFT]
    • TODOS.md has items marked as in-progress that relate to this branch's work
Step 9.2: Create the PR
gh pr create --base <base> \
  --title "<type>: <summary>" \
  [--draft] \
  [--label "<label1>" --label "<label2>"] \
  --body "$(cat <<'EOF'
## Summary
<bullet points from CHANGELOG or diff summary>

<If linked issues were detected in Step 1:>
Closes #<issue>
<or>
Relates to #<issue>

## Pre-Landing Review
<findings from Step 3.5, or "No issues found.">

<If adversarial review was run in Step 3.7:>
## Adversarial Review
<INVESTIGATE findings, or "No issues found.">
<FIXABLE findings that were applied are noted as resolved.>

## TODOS
<completed items, or "No TODO items completed in this PR.">

<If Step 6.7 ran:>
## Plan Completion
<checklist summary from Step 6.7, or "No plan file detected.">

<If UNVERIFIABLE items were confirmed via per-item flow:>
## Plan Completion — Manual Verifications
<each Y'd item with user evidence; each D'd item marked "intentionally dropped">

## Test plan
- [x] All tests pass
- [x] Verification gate passed

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"

Output the PR URL.

Recovery: If gh pr create fails:

  • PR already exists: Run gh pr view --json url --jq .url and output the existing URL. Offer to update the existing PR body instead.
  • Missing permissions: Report and STOP.
  • Network error: Retry once. If still failing, report and STOP. The code is pushed — the user can create the PR manually.

Important Rules

  • Never skip tests. If tests fail, stop.
  • Never force push. Use regular git push only.
  • Never ask for trivial confirmations (e.g., "ready to push?", "create PR?"). DO stop for: version bumps (MINOR/MAJOR) and pre-landing review ASK items.
  • Split commits for bisectability — each commit = one logical change.
  • TODOS.md completion detection must be conservative. Only mark items done when the diff clearly shows it.
  • Never push without fresh verification evidence. If code changed after Step 3, re-run before pushing.
  • Recovery over failure. Each step includes recovery guidance. Follow it before giving up.
  • The goal is: user says /ship, next thing they see is the PR URL.

Comments

Markdown supported