From superpowers
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work - guides completion of development work by presenting structured options for integration, PR, or cleanup
How this skill is triggered — by the user, by Claude, or both
Slash command
/superpowers:finishing-a-development-branchThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Guide completion of development work by presenting clear options and handling chosen workflow.
Guide completion of development work by presenting clear options and handling chosen workflow.
Core principle: Verify tests → Detect environment → Present options → Execute choice → Clean up.
Announce at start: "I'm using the finishing-a-development-branch skill to complete this work."
Before presenting options, verify tests pass:
# Run project's test suite
npm test / cargo test / uv run pytest / go test ./...
If tests fail:
Tests failing (<N> failures). Must fix before completing:
[Show failures]
Cannot proceed with integration/PR until tests pass.
Stop. Don't proceed to Step 2.
If tests pass: Continue to Step 2.
Determine workspace state before presenting options:
# List all jj workspaces and their paths
jj workspace list --no-pager
This determines which menu to show and how cleanup works:
| State | Menu | Cleanup |
|---|---|---|
| Default workspace (repo root) | Standard 4 options | No workspace to clean up |
Named workspace under .workspaces/ | Standard 4 options | Provenance-based (see Step 6) |
| Named workspace (harness-owned) | Reduced 3 options | No cleanup (externally managed) |
A workspace is "harness-owned" if it was not created by the using-jj-workspaces skill (i.e., not under .workspaces/).
# Check where your work diverged from trunk
jj log
# Identify the base - typically trunk() or the 'main' bookmark
jj log -r "trunk()"
jj log -r "bookmarks(exact:main)"
Or ask: "This work is based on main — is that correct?"
Default workspace or provenance-owned workspace — present exactly these 4 options:
Implementation complete. What would you like to do?
1. Integrate changes into main locally
2. Push and create a Pull Request
3. Keep the changes as-is (I'll handle it later)
4. Discard this work
Which option?
Harness-owned workspace — present exactly these 3 options:
Implementation complete. You're in an externally managed workspace.
1. Push as new branch and create a Pull Request
2. Keep as-is (I'll handle it later)
3. Discard this work
Which option?
Don't add explanation - keep options concise.
# Rebase your changes onto trunk if needed
jj rebase -r <your-changes> -d 'trunk()'
# Move the main bookmark forward
jj bookmark set main -r <your-final-change>
# Or if the user has the 'tug' alias:
jj tug
# Verify tests on integrated result
<test command>
# Verify
jj log -r 'trunk()..@'
# Start fresh
jj new
Then: Cleanup workspace (Step 6), then Post-Integration Cleanup (Step 7)
# Push bookmark to remote
jj bookmark set <bookmark-name> -r @
jj git push -b <bookmark-name>
Then: Create PR. Do NOT clean up workspace (user needs it for PR iteration).
No action needed. Inform user where to find the work:
Changes preserved. Workspace/changes remain in current state.
Require typed confirmation:
This will permanently discard all work in this change. Type "discard" to confirm:
Wait for user to type "discard".
# Abandon the change(s)
jj abandon <change-id>
Then: Cleanup workspace (Step 6).
Only runs for Options 1 and 4. Options 2 and 3 always preserve the workspace.
# Record workspace path before changing directories
WORKSPACE_PATH=$(pwd)
WORKSPACE_NAME=$(basename "$WORKSPACE_PATH")
If in default workspace: No workspace to clean up. Done.
If workspace path is under .workspaces/: Superpowers created this workspace — we own cleanup.
# Navigate to the repo root (outside the workspace)
cd "$(jj root --no-pager)"
# Forget the workspace record first
jj workspace forget "$WORKSPACE_NAME"
# Remove the directory (verify path first!)
rm -rf "$WORKSPACE_PATH"
Otherwise: The host environment (harness) owns this workspace. Do NOT remove it. If your platform provides a workspace-exit tool, use it. Otherwise, leave the workspace in place.
After integration, especially if there were conflicts:
# Clean any stale jj artifacts from git's index
# (jj uses git for storage, conflict markers can get stuck)
git status --porcelain | grep -E "\.jj-" && git rm --cached .jj-* 2>/dev/null
# Verify environment still works
direnv allow 2>/dev/null
# Run the actual app, not just tests
# (tests use temp dirs, won't catch missing production paths)
make serve # or equivalent
| Situation | Action |
|---|---|
| Tests fail | Fix before proceeding |
| All good, want to land now | Option 1 (Integrate) |
| Need PR review | Option 2 (Push) |
| Not ready to land | Option 3 (Keep) |
| Throw it away | Option 4 (Discard) |
Skipping test verification
Open-ended questions
Cleaning up workspace for Option 2
Forgetting workspace before directory removal
jj workspace forget before rm -rfCleaning up harness-owned workspaces
.workspaces/No confirmation for discard
Using git merge, git checkout, git branch
jj rebase, jj edit, jj bookmarkNever:
git merge, git checkout, git branch — use jj equivalentsjj workspace forgetAlways:
rm -rfCalled by:
Pairs with:
npx claudepluginhub johnstegeman/superpowersCreates structured, bite-sized implementation plans from specs or requirements before writing code. Useful for breaking down multi-step tasks into testable steps with file structure and task boundaries.