@camacho/bail
Reflects, updates GitHub Issue, closes PR if open, cleans up worktree/branch.
| name | bail |
| description | Reflects, updates GitHub Issue, closes PR if open, cleans up worktree/branch. |
Bail-out protocol: always reflect FIRST, then clean up. All commands use absolute paths and git -C.
Inputs
WORKTREE: absolute path to current worktree (or primary if no worktree)- Optional reason string (if not provided, ask for one)
Steps
Detect current step by examining what exists:
What exists Estimated step Just an issue, no branch Step 0 (Capture) .branch-context.md, no worktree Step 1 (Orient) Worktree exists, no code changes Step 2 (Isolate) Plan file on branch Step 3-4 (Design/Review) Code changes committed Step 5-7 (Build/Verify/Archive) PR open on GitHub Step 8 (Ship) Prompt for reason if not provided.
Write learnings to .branch-context.md in the worktree:
# Write bail context — use absolute path cat >> "$WORKTREE/.branch-context.md" <<EOF ## Bail - Reason: <reason> - What was attempted: <summary> - What was learned: <learnings> EOF git -C "$WORKTREE" add .branch-context.md git -C "$WORKTREE" commit -m "docs: capture bail context"Consolidate learnings to MEMORY.md via disposable clone (never checkout main in a worktree):
BAIL_DIR="${CLAUDE_SESSION_DIR:-$TMPDIR}/bail-reflect" [ -d "$BAIL_DIR" ] && rm -rf "$BAIL_DIR" git clone --depth 50 "$(git -C "$WORKTREE" remote get-url origin)" "$BAIL_DIR"Read
$BAIL_DIR/ai-workspace/MEMORY.md, append relevant learnings from.branch-context.md, then:git -C "$BAIL_DIR" add ai-workspace/MEMORY.md git -C "$BAIL_DIR" commit -m "docs: consolidate learnings from abandoned <branch> Co-Authored-By: Claude <model>" git -C "$BAIL_DIR" pushOn non-fast-forward:
git -C "$BAIL_DIR" pull --rebasethen push. Max 3 retries. Clean up:rm -rf "$BAIL_DIR"Update GitHub Issue (if accessible):
GH_REPO=<owner/repo> gh issue comment <number> --body "Bailing: <reason>. Learnings captured in MEMORY.md." GH_REPO=<owner/repo> gh issue edit <number> --add-label "deferred" --remove-label "triage"Close PR if open:
PR_NUM=$(GH_REPO=<owner/repo> gh pr list --head "<branch>" --json number -q '.[0].number') if [ -n "$PR_NUM" ]; then GH_REPO=<owner/repo> gh pr close "$PR_NUM" fiAsk about branch preservation:
Default: preserve the branch (user can resume later).
If user explicitly says delete — confirm by showing what will be destroyed:
This will delete: - Branch: <name> - Worktree: <path> - Remote branch (if pushed) Type 'delete' to confirm.Only after typed confirmation:
PRIMARY="$(git -C "$WORKTREE" worktree list --porcelain | grep -m1 '^worktree ' | sed 's/^worktree //')" # Verify branch is merged before deleting (-d fails if unmerged, -D would force) git -C "$PRIMARY" worktree remove "$WORKTREE" git -C "$PRIMARY" branch -d <branch>If
branch -dfails (unmerged work), warn the user and stop. Do NOT usebranch -D.Done. Do not checkout main — stay in whatever CWD the session has.
Edge Cases
- No worktree exists (bailing at Step 0-1) → skip worktree cleanup, just update issue
- No GitHub access → skip issue update, still do local cleanup + memory consolidation
- PR already merged → don't close, just note it in the output
- No .branch-context.md → create one with just the bail reason before consolidating
CLAUDE_SESSION_DIRunset → fall back to$TMPDIRfor clone
Output: Summary of what was cleaned up and where learnings were saved.
Loading...
Select a file to preview
Analyzing security...
Checking scan reports and verification data.
Bill of Materials
Everything this skill can do — files, network, commands, and more.