| name | finish |
| description | Use when implementation + verification are complete and the work needs to be integrated — commit, open a PR, merge, or clean up the branch. The final step of the craft pipeline (after develop/test/report). Works in the current checkout; no worktree assumption. |
Finish
Integrate completed work. The craft pipeline builds and verifies a feature but stops at "Report" — this skill takes it the last step: commit, PR, merge, or cleanup. It is the craft-native equivalent of branch-finishing, operating on the current checkout and this project's conventions.
Input
The user input is: $ARGUMENTS — an optional hint (pr, merge, commit, cleanup). If empty, detect state and present options.
Step 0: Read project conventions
FIRST ACTION: read the project's CLAUDE.md for git/commit conventions (commit message style, whether to add or omit a Co-Authored-By trailer, branch/PR norms). Follow them exactly — they override this skill's defaults.
Step 1: Verify the work is integrable
Do NOT offer to commit work that isn't done:
- Confirm the tree is in the intended state:
git status --short.
- Confirm verification passed. If a craft
develop run just finished, its Step 4 verification already ran — confirm it was clean. Otherwise run whatever checks the project actually uses (lint/typecheck/build/test from package.json scripts, a Makefile, or a repo-specific check like npm run sync:check); if the repo has no automated checks, confirm the tree is sound by its own means. STOP if anything fails.
- Confirm craft scratch is cleaned: no
.shared-state.md, .craft-progress.md, .craft-review.diff, .craft-profile, .llm-task-*.txt left in the tree (develop Step 5 removes these; if invoked standalone, remove any stragglers — they are gitignored but shouldn't be committed).
Step 2: Detect branch state
BRANCH=$(git branch --show-current)
DEFAULT=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@')
[ -z "$DEFAULT" ] && git remote set-head origin -a >/dev/null 2>&1 && DEFAULT=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@')
[ -z "$DEFAULT" ] && DEFAULT=$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name 2>/dev/null)
[ -z "$DEFAULT" ] && DEFAULT=main
echo "branch: $BRANCH | default: $DEFAULT"
git status --short
git log --oneline "$DEFAULT..HEAD" 2>/dev/null | head -20
git remote -v | head -1
If $DEFAULT fell through to the main guess, confirm it's actually the repo's default (git branch -r) before merging or opening a PR against it.
- If on the default branch with uncommitted changes: offer to branch first (
git checkout -b <name>), never commit feature work straight to the default branch unless the user insists.
- If on a feature branch: note how many commits are ahead and whether a remote exists.
Step 3: Present options (pick by $ARGUMENTS or ask)
Present the applicable options and let the user choose. Do NOT push or open a PR without explicit confirmation — these are outward-facing.
| Option | What it does |
|---|
| commit | Stage + commit the remaining changes on the current branch with a conventional message (follow CLAUDE.md). Stop there. |
| pr | Commit if needed, push the branch, open a PR against the default branch via gh pr create (title + body summarizing the feature). Requires a remote + gh auth — confirm the active gh/git account can actually push to the remote (a mismatch fails the push). |
| merge | Commit if needed, then merge the feature branch into the default branch locally (fast-forward when possible). Pushing the default branch is a separate, explicitly-confirmed step. |
| cleanup | After a merged PR: delete the local feature branch, prune, return to the default branch. |
Commit messages: conventional, imperative, scoped. Honor the project's Co-Authored-By policy from CLAUDE.md (some repos require omitting it, some keep it).
Step 4: Execute the chosen option
- commit:
git add -A && git commit (message per conventions). Report the SHA.
- pr:
git push -u origin "$BRANCH" then gh pr create --base "$DEFAULT" --title "..." --body "...". If push fails on auth, STOP and tell the user which account is needed — do not silently retry.
- merge:
git checkout "$DEFAULT" && git merge --ff-only "$BRANCH" (fall back to a merge commit if not fast-forwardable, after confirming). Leave pushing $DEFAULT to an explicit follow-up.
- cleanup: verify the PR/branch is merged first (
gh pr view or git branch --merged), then git branch -d "$BRANCH".
Step 5: Report
Report what was done (SHA / PR URL / merge result), the branch state, and any follow-up the user still owns (e.g. "push main to trigger release", "delete the remote branch").
Notes
- No worktree creation. Unlike some branch-finishing tools, this skill never creates a
.worktrees/ directory. It operates on the current checkout as-is — which may itself be a git worktree; that's fine, all its git commands are checkout-relative.
- Outward-facing actions need confirmation. Pushing and opening PRs publish work — confirm before doing them, even if the rest of the pipeline ran autonomously.
- Some repos auto-release on merge to the default branch (CI). If CLAUDE.md notes this, remind the user (and mention
[skip release] if they want to hold it).