| name | ship:finish |
| description | Use when a feature has been verified and needs to be completed — creates PR, merges locally, or keeps branch |
| effort | medium |
| allowed-tools | Read, Bash, Glob, AskUserQuestion |
| argument-hint | [feature-name] [--accept-inconclusive "reason"] |
Finish the active feature after verification passes.
Parse Arguments
Parse $ARGUMENTS (a single string) into two components:
--accept-inconclusive "reason" — if this flag appears anywhere in the string, set ACCEPT_INCONCLUSIVE = true and extract the quoted reason text (everything between the matching "s after the flag).
- Remaining tokens (after removing the flag + reason) — treat as feature name.
If --accept-inconclusive appears WITHOUT a quoted reason, abort and tell the user: --accept-inconclusive requires a non-empty reason in quotes. Example: /ship:finish my-feature --accept-inconclusive "manually verified end-to-end on staging".
If ACCEPT_INCONCLUSIVE = false, behave as before.
Find Active Feature
Feature state is injected by hooks at session start and after compaction — check conversation context for "SHIP ACTIVE FEATURES" or "SHIP FEATURE STATE" blocks first.
- If
$ARGUMENTS is provided, use it as the feature name
- Otherwise, use injected feature state to identify the feature with status
done
- If no injected state is available, fall back to scanning
.planning/features/*/CONTEXT.md
- If no candidates, report that no finished features were found
Check INCONCLUSIVE Verdicts
Read .planning/features/{name}/VERIFY.md. Search for any of:
status: INCONCLUSIVE in the frontmatter, OR
- Any row in the Stage 1 table with verdict
INCONCLUSIVE.
If found:
If VERIFY.md has no INCONCLUSIVE markers, proceed directly to Prerequisites.
Prerequisites
Run the project's test suite to confirm everything passes:
If tests fail, stop and report failures. Do not proceed.
Present Options
Feature '{name}' is verified and complete.
1. Create a Pull Request (push branch + gh pr create)
2. Merge to {base-branch} locally
3. Keep as-is (I'll handle it later)
Which option?
Use AskUserQuestion to get the user's choice.
Execute Choice
Option 1: Create PR
First, check that gh is available: gh auth status. If it fails, tell the user to install/authenticate gh and abort.
git rev-parse --verify main &>/dev/null && echo main || echo master
git push -u origin HEAD
gh pr create --title "{type}: {feature-name}" --body "$(cat <<'EOF'
## Summary
{2-3 bullets from CONTEXT.md acceptance criteria}
## Test plan
{key verify commands from PLAN.md}
Built with [Ship](https://github.com/dilhanz/ship)
EOF
)"
Report the PR URL to the user.
Option 2: Merge Locally
BASE=$(git rev-parse --verify main &>/dev/null && echo main || echo master)
git checkout $BASE
git merge {feature-branch}
Run tests again on the merged result. If tests pass, report success.
Option 3: Keep As-Is
Report: "Feature '{name}' kept on current branch. Run /ship:finish again when ready."
Do NOT archive the feature directory for this option.
Archive Feature
After Option 1 or Option 2 completes successfully, move the feature directory to the archive:
mkdir -p .planning/archive
mv .planning/features/{feature-name} .planning/archive/{feature-name}
This preserves the full history (CONTEXT.md, PLAN.md, VERIFY.md) while keeping .planning/features/ clean for active work.
Report
## FEATURE FINISHED
Feature: {name}
Action: {PR created / Merged to main / Kept as-is}
{If PR:} PR: {url}
{If merged:} Branch merged and tests passing
Archived: .planning/archive/{name}
$ARGUMENTS