@torka/claude-workflows 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +51 -0
- package/LICENSE +21 -0
- package/README.md +299 -0
- package/agents/principal-code-reviewer.md +80 -0
- package/agents/story-prep-master.md +53 -0
- package/commands/git-cleanup-and-merge.md +519 -0
- package/commands/implement-epic-with-subagents.md +5 -0
- package/commands/plan-parallelization.md +194 -0
- package/examples/settings.local.example.json +57 -0
- package/hooks/auto_approve_safe.py +261 -0
- package/hooks/auto_approve_safe.rules.json +134 -0
- package/install.js +181 -0
- package/package.json +52 -0
- package/scripts/context-monitor.py +175 -0
- package/skills/agent-creator/COMMUNITY-REPOS.md +212 -0
- package/skills/agent-creator/NON-STORY-AGENT-TEMPLATE.md +90 -0
- package/skills/agent-creator/REGISTRY.yaml +107 -0
- package/skills/agent-creator/SKILL.md +339 -0
- package/skills/agent-creator/STORY-AGENT-TEMPLATE.md +199 -0
- package/uninstall.js +186 -0
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 'Analyze git branches, cleanup merged branches, push changes, create PRs, wait for CI, and merge to main'
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
IT IS CRITICAL THAT YOU FOLLOW THIS WORKFLOW EXACTLY.
|
|
6
|
+
|
|
7
|
+
<workflow CRITICAL="TRUE">
|
|
8
|
+
|
|
9
|
+
## Phase 0: Pre-flight Checks
|
|
10
|
+
|
|
11
|
+
Before any operations, verify the environment is safe:
|
|
12
|
+
|
|
13
|
+
1. **Check gh authentication**: Run `gh auth status`. If not authenticated, STOP and inform user.
|
|
14
|
+
|
|
15
|
+
2. **Check for uncommitted changes**: Run `git status --porcelain`. If output is non-empty, STOP and inform user to commit or stash changes first.
|
|
16
|
+
|
|
17
|
+
3. **Detect git directory** (worktree-compatible):
|
|
18
|
+
- Run `git rev-parse --git-dir` to get the actual git directory path
|
|
19
|
+
- This works correctly in both main and linked worktrees (where `.git` is a file, not a directory)
|
|
20
|
+
- Store this path for use in step 4
|
|
21
|
+
|
|
22
|
+
4. **Check for in-progress operations**: Using the git directory from step 3, check if any of these exist:
|
|
23
|
+
- `<git-dir>/rebase-merge` or `<git-dir>/rebase-apply` (rebase in progress)
|
|
24
|
+
- `<git-dir>/MERGE_HEAD` (merge in progress)
|
|
25
|
+
- `<git-dir>/CHERRY_PICK_HEAD` (cherry-pick in progress)
|
|
26
|
+
If any exist, STOP and inform user to complete or abort the operation.
|
|
27
|
+
|
|
28
|
+
5. **Detect remote name**: Run `git remote` and use the first result (usually `origin`).
|
|
29
|
+
|
|
30
|
+
6. **Detect default branch**: Run `gh repo view --json defaultBranchRef -q .defaultBranchRef.name`. Fallback to `main` if this fails.
|
|
31
|
+
|
|
32
|
+
7. **Record current branch and worktree**:
|
|
33
|
+
- Run `git branch --show-current` to get current branch name
|
|
34
|
+
- **If empty (detached HEAD)**: Run `git rev-parse HEAD` to save the commit SHA instead
|
|
35
|
+
- Run `git rev-parse --show-toplevel` to record the current worktree path
|
|
36
|
+
- Track whether we started in detached HEAD state for Phase 8 restoration
|
|
37
|
+
|
|
38
|
+
8. **Build worktree inventory**: Run `git worktree list --porcelain` to detect all worktrees.
|
|
39
|
+
- Parse the output to build a map: `{ branch_name -> worktree_path }`
|
|
40
|
+
- **For each worktree path, verify it exists on the filesystem**
|
|
41
|
+
- **If a path doesn't exist (stale entry), run `git worktree prune` to clean it up before continuing**
|
|
42
|
+
- Identify which worktree is the main worktree vs linked worktrees
|
|
43
|
+
- For each branch, record if it's checked out in a worktree and where
|
|
44
|
+
|
|
45
|
+
9. **Check for uncommitted changes in other worktrees**: For each linked worktree (not the current one):
|
|
46
|
+
- Run `git -C <worktree-path> status --porcelain`
|
|
47
|
+
- If any worktree has uncommitted changes, WARN the user (but do not block)
|
|
48
|
+
- Track which worktrees have uncommitted changes for later phases
|
|
49
|
+
|
|
50
|
+
10. **Display worktree overview** (if multiple worktrees exist):
|
|
51
|
+
```
|
|
52
|
+
Worktrees detected:
|
|
53
|
+
/path/to/main (main) - this worktree
|
|
54
|
+
/path/to/feature (feature-x) - clean
|
|
55
|
+
/path/to/docs (docs-update) - uncommitted changes!
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
11. **Initialize operation log**: Create an in-memory log to track all operations performed.
|
|
59
|
+
- This log will be used for error recovery if something fails mid-workflow
|
|
60
|
+
- Track: operation type, target (branch/worktree), status (success/failed)
|
|
61
|
+
- Log each destructive operation as it completes (worktree removal, branch deletion, push, PR creation, merge)
|
|
62
|
+
|
|
63
|
+
If any pre-flight check fails, STOP and clearly explain what the user needs to do.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Phase 1: Branch Analysis
|
|
68
|
+
|
|
69
|
+
Gather comprehensive information about all branches:
|
|
70
|
+
|
|
71
|
+
1. Run `git fetch <remote>` to get latest remote state
|
|
72
|
+
2. Run `git branch -a` to list all branches
|
|
73
|
+
3. Run `git branch -a --merged <remote>/<default-branch>` to identify merged branches
|
|
74
|
+
4. Detect squash-merged branches:
|
|
75
|
+
- Get merged PR branch names: `gh pr list --state merged --limit 100 --json headRefName,number,mergedAt`
|
|
76
|
+
- For each local branch, check if its name matches a merged PR's `headRefName`
|
|
77
|
+
- **If branch name matches a merged PR, trust the GitHub API - mark as "squash-merged"**
|
|
78
|
+
- **Do NOT use `git rev-list` to verify** (commit ancestry doesn't work for squash merges since commits are rewritten into a single new commit)
|
|
79
|
+
5. Run `git branch -vv` and look for `: gone]` to find orphaned tracking branches
|
|
80
|
+
6. For each local branch with a remote, run `git rev-list --left-right --count <remote>/<branch>...<branch>` to detect sync status
|
|
81
|
+
7. Run `gh pr list --state open` to check for open PRs
|
|
82
|
+
8. Run `gh pr list --state open --json number,createdAt,headRefName` to identify stale PRs (>30 days old)
|
|
83
|
+
9. **Cross-reference with worktree inventory** (from Phase 0): For each branch, note if it's checked out in a worktree
|
|
84
|
+
|
|
85
|
+
**Present a summary table to the user with these columns:**
|
|
86
|
+
| Branch | Location | Sync Status | Open PR | Worktree | Recommendation |
|
|
87
|
+
|
|
88
|
+
**Worktree column values:**
|
|
89
|
+
- `-` - Not checked out in any worktree
|
|
90
|
+
- `/path/to/worktree` - Path where branch is checked out
|
|
91
|
+
- `/path/to/worktree (this)` - Checked out in the current worktree
|
|
92
|
+
- `/path/to/worktree (dirty)` - Checked out in a worktree with uncommitted changes
|
|
93
|
+
|
|
94
|
+
**Sync Status values:**
|
|
95
|
+
- `merged` - Already merged to default branch
|
|
96
|
+
- `synced` - Local and remote are identical
|
|
97
|
+
- `ahead` - Local has unpushed commits (show count)
|
|
98
|
+
- `behind` - Remote has commits not in local (show count)
|
|
99
|
+
- `diverged` - Both ahead and behind (show counts)
|
|
100
|
+
- `local-only` - No remote tracking branch
|
|
101
|
+
- `orphaned` - Remote tracking branch was deleted
|
|
102
|
+
|
|
103
|
+
**Recommendation adjustments for worktrees:**
|
|
104
|
+
- If branch is `merged` AND in a worktree → "remove worktree first, then delete"
|
|
105
|
+
- If branch is `merged` AND in current worktree → "switch to default, then delete"
|
|
106
|
+
- If branch is in a worktree with uncommitted changes → include "(worktree has changes)" warning
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Phase 2: WIP Identification
|
|
111
|
+
|
|
112
|
+
Use the `AskUserQuestion` tool with `multiSelect: true` to ask the user which branches are Work-In-Progress and should be skipped.
|
|
113
|
+
|
|
114
|
+
Present all non-merged branches as options with worktree context:
|
|
115
|
+
- **Current worktree branch**: Auto-select as WIP with description "(current worktree)"
|
|
116
|
+
- **Branches in other worktrees**: Include worktree path in description, e.g., "(in worktree: /path/to/feature)"
|
|
117
|
+
- **Branches with uncommitted worktree changes**: Add warning "(worktree has uncommitted changes)"
|
|
118
|
+
|
|
119
|
+
Example multi-select presentation:
|
|
120
|
+
```
|
|
121
|
+
Select WIP branches to skip:
|
|
122
|
+
[x] feature-current (current worktree) ← auto-selected
|
|
123
|
+
[ ] feature-x (in worktree: /path/to/feature-x)
|
|
124
|
+
[ ] feature-y (in worktree: /path/to/feature-y - has uncommitted changes!)
|
|
125
|
+
[ ] bugfix-1
|
|
126
|
+
[ ] docs-update
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Store the WIP branches list for use in subsequent phases. Also maintain a separate list of branches that are in worktrees (regardless of WIP status) for Phase 3 handling.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Phase 3: Cleanup Merged Branches
|
|
134
|
+
|
|
135
|
+
For all branches identified as merged (via regular merge OR squash merge):
|
|
136
|
+
|
|
137
|
+
### Step 1: Categorize merged branches by worktree status
|
|
138
|
+
|
|
139
|
+
**Category A - No worktree (safe to delete directly):**
|
|
140
|
+
- Branches not checked out in any worktree
|
|
141
|
+
- These can be deleted with standard `git branch -d`
|
|
142
|
+
|
|
143
|
+
**Category B - In linked worktrees (requires worktree handling first):**
|
|
144
|
+
- Branches checked out in worktrees OTHER than the current one
|
|
145
|
+
- Cannot delete until worktree is removed or switched to different branch
|
|
146
|
+
|
|
147
|
+
**Category C - In current worktree:**
|
|
148
|
+
- The branch you're currently on (if it's merged)
|
|
149
|
+
- Requires checkout to default branch first
|
|
150
|
+
|
|
151
|
+
### Step 2: Present categorized list to user
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
Merged branches to clean up:
|
|
155
|
+
|
|
156
|
+
A) Ready to delete (no worktree):
|
|
157
|
+
- old-feature (last commit: abc123, 5 days ago)
|
|
158
|
+
- bugfix-123 (last commit: def456, 2 weeks ago)
|
|
159
|
+
|
|
160
|
+
B) In linked worktrees (need handling first):
|
|
161
|
+
- feature-x at /path/to/feature-x (clean)
|
|
162
|
+
- docs-update at /path/to/docs (has uncommitted changes!)
|
|
163
|
+
|
|
164
|
+
C) In current worktree:
|
|
165
|
+
- hotfix-1 (will switch to <default-branch> first)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Step 3: Handle Category C (current worktree)
|
|
169
|
+
|
|
170
|
+
If the current branch is in the delete list:
|
|
171
|
+
- Run `git checkout <default-branch>` first
|
|
172
|
+
- Then proceed to delete the branch
|
|
173
|
+
|
|
174
|
+
### Step 4: Handle Category B (branches in linked worktrees)
|
|
175
|
+
|
|
176
|
+
For EACH branch in a linked worktree, use `AskUserQuestion` to ask:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
Branch '<branch>' is checked out in worktree at '<path>'.
|
|
180
|
+
|
|
181
|
+
Options:
|
|
182
|
+
1. Remove worktree and delete branch (Recommended)
|
|
183
|
+
2. Skip this branch
|
|
184
|
+
3. Switch worktree to <default-branch>, then delete branch
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**If option 1 (Remove worktree):**
|
|
188
|
+
1. Check for uncommitted changes: `git -C <worktree-path> status --porcelain`
|
|
189
|
+
2. If uncommitted changes exist:
|
|
190
|
+
- WARN: "Worktree at '<path>' has uncommitted changes that will be LOST"
|
|
191
|
+
- Ask for explicit confirmation: "Proceed anyway?" / "Skip this worktree"
|
|
192
|
+
- If skip, move to next branch
|
|
193
|
+
3. Remove worktree: `git worktree remove <worktree-path>`
|
|
194
|
+
4. If removal fails (locked, etc.), inform user and skip
|
|
195
|
+
5. Proceed to delete branch (now safe)
|
|
196
|
+
|
|
197
|
+
**If option 2 (Skip):**
|
|
198
|
+
- Skip this branch entirely
|
|
199
|
+
- Add to "skipped due to worktree" list for summary
|
|
200
|
+
|
|
201
|
+
**If option 3 (Switch worktree branch):**
|
|
202
|
+
1. Run `git -C <worktree-path> checkout <default-branch>`
|
|
203
|
+
2. If checkout fails, inform user and skip
|
|
204
|
+
3. Proceed to delete branch (now safe)
|
|
205
|
+
|
|
206
|
+
### Step 5: Delete Category A branches and handled Category B/C branches
|
|
207
|
+
|
|
208
|
+
For each branch now eligible for deletion:
|
|
209
|
+
- Delete local: `git branch -d <branch>` (use `-D` for squash-merged branches that git doesn't recognize as merged)
|
|
210
|
+
- Delete remote (if exists): `git push <remote> --delete <branch>`
|
|
211
|
+
|
|
212
|
+
### Step 6: Clean up orphaned tracking branches
|
|
213
|
+
|
|
214
|
+
- Run `git branch -vv | grep ': gone]'` and delete them
|
|
215
|
+
|
|
216
|
+
### Step 7: Final cleanup
|
|
217
|
+
|
|
218
|
+
- Run `git fetch --prune` to clean up stale refs
|
|
219
|
+
- Run `git worktree prune` to clean up stale worktree admin entries
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Phase 4: Push Local Changes to Remote
|
|
224
|
+
|
|
225
|
+
For branches that are NOT marked as WIP:
|
|
226
|
+
|
|
227
|
+
**Local-only branches:**
|
|
228
|
+
- Show the branch and its commits
|
|
229
|
+
- Confirm with user
|
|
230
|
+
- Run `git push -u <remote> <branch>`
|
|
231
|
+
- Note: Branches in worktrees CAN be pushed without issues - just note "(in worktree: /path)" in the confirmation
|
|
232
|
+
|
|
233
|
+
**Branches ahead of remote (unpushed commits):**
|
|
234
|
+
- Show commits that will be pushed: `git log <remote>/<branch>..<branch> --oneline`
|
|
235
|
+
- If branch is in a worktree, note: "(checked out at /path)"
|
|
236
|
+
- Confirm with user
|
|
237
|
+
- Run `git push <remote> <branch>`
|
|
238
|
+
|
|
239
|
+
**Diverged branches (both ahead and behind):**
|
|
240
|
+
|
|
241
|
+
*If branch is NOT in a worktree:*
|
|
242
|
+
- Warn user that rebase is needed
|
|
243
|
+
- Ask: "Skip this branch", "Attempt rebase", or "Manual fix"
|
|
244
|
+
- If rebase chosen:
|
|
245
|
+
- Run `git checkout <branch>`
|
|
246
|
+
- Run `git rebase <remote>/<branch>`
|
|
247
|
+
- If rebase has conflicts:
|
|
248
|
+
- Run `git rebase --abort`
|
|
249
|
+
- Inform user of the conflict
|
|
250
|
+
- Skip this branch
|
|
251
|
+
- If rebase succeeds:
|
|
252
|
+
- Run `git push <remote> <branch>`
|
|
253
|
+
- Return to original branch when done
|
|
254
|
+
|
|
255
|
+
*If branch IS in a linked worktree:*
|
|
256
|
+
- Cannot checkout branch (already checked out elsewhere)
|
|
257
|
+
- Ask user with `AskUserQuestion`:
|
|
258
|
+
```
|
|
259
|
+
Branch '<branch>' has diverged and is checked out at '<path>'.
|
|
260
|
+
|
|
261
|
+
Options:
|
|
262
|
+
1. Rebase in that worktree (Recommended)
|
|
263
|
+
2. Skip this branch
|
|
264
|
+
3. Manual fix
|
|
265
|
+
```
|
|
266
|
+
- If option 1 (Rebase in worktree):
|
|
267
|
+
- Check for uncommitted changes: `git -C <worktree-path> status --porcelain`
|
|
268
|
+
- If uncommitted changes exist, WARN and ask to skip or proceed
|
|
269
|
+
- Run `git -C <worktree-path> fetch <remote>`
|
|
270
|
+
- Run `git -C <worktree-path> rebase <remote>/<branch>`
|
|
271
|
+
- If rebase has conflicts:
|
|
272
|
+
- Run `git -C <worktree-path> rebase --abort`
|
|
273
|
+
- Inform user of the conflict
|
|
274
|
+
- Skip this branch
|
|
275
|
+
- If rebase succeeds:
|
|
276
|
+
- Run `git -C <worktree-path> push <remote> <branch>`
|
|
277
|
+
|
|
278
|
+
*If branch is in the CURRENT worktree:*
|
|
279
|
+
- Handle same as non-worktree case (can checkout and rebase normally in current worktree)
|
|
280
|
+
|
|
281
|
+
**Behind branches:**
|
|
282
|
+
- Warn user these need to be updated before further work
|
|
283
|
+
- Skip from PR creation unless user explicitly requests
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Phase 5: Create PRs
|
|
288
|
+
|
|
289
|
+
Identify eligible branches:
|
|
290
|
+
- Have commits ahead of the default branch
|
|
291
|
+
- Don't already have an open PR
|
|
292
|
+
- Are NOT marked as WIP
|
|
293
|
+
|
|
294
|
+
**Before creating PRs:**
|
|
295
|
+
1. Build a summary table of all PRs to be created:
|
|
296
|
+
| Branch | Proposed Title | # Commits | Age |
|
|
297
|
+
2. Show the table to user
|
|
298
|
+
3. Use `AskUserQuestion` to ask: "Create all X PRs?", "Let me select which ones", "Skip PR creation"
|
|
299
|
+
4. If "select", present branches as multi-select options
|
|
300
|
+
5. Proceed only with confirmed branches
|
|
301
|
+
|
|
302
|
+
For each confirmed branch:
|
|
303
|
+
1. Check divergence: `git rev-list --left-right --count <default-branch>...<branch>`
|
|
304
|
+
2. If behind default branch, warn user rebase may be needed after PR creation
|
|
305
|
+
3. For branches >30 days old, add note in PR body about age
|
|
306
|
+
4. Create PR: `gh pr create --head <branch> --title "<conventional commit title based on commits>" --body "<summary of changes>"`
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## Phase 6: CI Loop
|
|
311
|
+
|
|
312
|
+
For each open PR (including newly created ones):
|
|
313
|
+
|
|
314
|
+
**Configuration:**
|
|
315
|
+
- Max 3 fix attempts per PR
|
|
316
|
+
- Max 5 minute wait per CI run
|
|
317
|
+
- 30 second polling interval
|
|
318
|
+
|
|
319
|
+
**Process:**
|
|
320
|
+
1. Check CI status: `gh pr checks <pr-number>` or `gh pr view <pr-number> --json statusCheckRollup`
|
|
321
|
+
2. If CI is running:
|
|
322
|
+
- Display: "Waiting for CI on PR #<number>... (attempt X/3, Xs elapsed)"
|
|
323
|
+
- Wait 30 seconds
|
|
324
|
+
- Re-check (up to 5 minutes total)
|
|
325
|
+
3. If CI passes: Mark PR as ready for merge, proceed to Phase 7
|
|
326
|
+
4. If CI fails:
|
|
327
|
+
- Fetch and display the failure output
|
|
328
|
+
- Categorize the failure:
|
|
329
|
+
- **Lint/Formatting errors**: Offer to run `npm run lint -- --fix` automatically
|
|
330
|
+
- **Type errors**: Show errors, ask user: "Skip this PR", "I'll fix manually"
|
|
331
|
+
- **Test failures**: Show test output, ask user: "Skip this PR", "I'll fix manually"
|
|
332
|
+
- **Build errors**: Show error, ask user: "Skip this PR", "I'll fix manually"
|
|
333
|
+
- If auto-fix chosen (lint only):
|
|
334
|
+
- Run the fix command
|
|
335
|
+
- Show the diff to user
|
|
336
|
+
- Ask for confirmation before committing
|
|
337
|
+
- Commit with message: "fix: auto-fix lint errors"
|
|
338
|
+
- Push and decrement retry counter
|
|
339
|
+
- If manual fix chosen:
|
|
340
|
+
- Inform user and pause for this PR
|
|
341
|
+
- Ask: "Continue with other PRs?" or "Wait for manual fix?"
|
|
342
|
+
5. If max retries exceeded:
|
|
343
|
+
- Ask user: "Skip this PR", "Abort workflow", or "I'll fix manually"
|
|
344
|
+
- Handle accordingly
|
|
345
|
+
|
|
346
|
+
**IMPORTANT**: NEVER auto-fix test failures or type errors. Only lint/formatting issues are safe to auto-fix.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Phase 7: Merge PRs
|
|
351
|
+
|
|
352
|
+
For each PR that passed CI:
|
|
353
|
+
|
|
354
|
+
**Pre-merge checks:**
|
|
355
|
+
1. Re-verify CI status (avoid race condition): `gh pr view <pr-number> --json statusCheckRollup`
|
|
356
|
+
2. Check merge state: `gh pr view <pr-number> --json mergeStateStatus,mergeable`
|
|
357
|
+
|
|
358
|
+
**If branch is behind default branch (`mergeStateStatus` is `BEHIND`):**
|
|
359
|
+
- Ask user: "Update branch via GitHub" or "Skip this PR"
|
|
360
|
+
- If update chosen:
|
|
361
|
+
- Run: `gh api repos/{owner}/{repo}/pulls/{pr-number}/update-branch -X PUT`
|
|
362
|
+
- If the API call fails (e.g., merge conflicts), inform user and offer to skip
|
|
363
|
+
- Wait for CI to re-run after update
|
|
364
|
+
- Re-check merge state
|
|
365
|
+
|
|
366
|
+
**If merge conflicts exist (`mergeable` is `CONFLICTING`):**
|
|
367
|
+
- STOP - cannot auto-merge
|
|
368
|
+
- Show the PR URL
|
|
369
|
+
- Ask user: "Skip this PR" or "I'll resolve conflicts manually"
|
|
370
|
+
- If manual resolution, wait for user confirmation then re-check
|
|
371
|
+
|
|
372
|
+
**Merge:**
|
|
373
|
+
- Run `gh pr merge <pr-number> --delete-branch`
|
|
374
|
+
- This respects the repository's merge strategy settings
|
|
375
|
+
- The `--delete-branch` flag removes the remote branch after merge
|
|
376
|
+
|
|
377
|
+
**If merge fails:**
|
|
378
|
+
- Report the error
|
|
379
|
+
- Ask user how to proceed
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Phase 8: Final Cleanup & Summary
|
|
384
|
+
|
|
385
|
+
### Step 1: Handle orphaned worktrees from merged PRs
|
|
386
|
+
|
|
387
|
+
For any worktrees whose branches were merged in Phase 7:
|
|
388
|
+
- The remote branch is now deleted, but the local worktree may still exist
|
|
389
|
+
- For each such worktree, ask user:
|
|
390
|
+
```
|
|
391
|
+
Worktree at '<path>' is now on merged branch '<branch>'.
|
|
392
|
+
|
|
393
|
+
Options:
|
|
394
|
+
1. Remove worktree (Recommended)
|
|
395
|
+
2. Keep worktree (switch to <default-branch>)
|
|
396
|
+
```
|
|
397
|
+
- If remove: `git worktree remove <path>`
|
|
398
|
+
- If keep: `git -C <path> checkout <default-branch>`
|
|
399
|
+
|
|
400
|
+
### Step 2: Clean up stale refs and worktree entries
|
|
401
|
+
|
|
402
|
+
1. Run `git fetch --prune` to clean up all stale remote refs
|
|
403
|
+
2. Run `git worktree prune` to clean up stale worktree admin entries
|
|
404
|
+
3. Delete any local branches that were merged (check against PRs merged in Phase 7)
|
|
405
|
+
- Skip branches that are checked out in remaining worktrees
|
|
406
|
+
|
|
407
|
+
### Step 3: Return to original context
|
|
408
|
+
|
|
409
|
+
- **If original state was a branch**: Run `git checkout <original-branch>` (if it still exists, otherwise stay on default branch)
|
|
410
|
+
- **If original state was detached HEAD**: Run `git checkout <original-commit-sha>` to restore exact position
|
|
411
|
+
- If the original branch was merged and deleted, inform user: "Your original branch '<branch>' was merged. You are now on '<default-branch>'."
|
|
412
|
+
|
|
413
|
+
### Step 4: Display final summary
|
|
414
|
+
|
|
415
|
+
```
|
|
416
|
+
=====================================================
|
|
417
|
+
Git Branch Cleanup Complete!
|
|
418
|
+
=====================================================
|
|
419
|
+
|
|
420
|
+
BRANCHES:
|
|
421
|
+
✓ Deleted X merged branches (local + remote)
|
|
422
|
+
✓ Pushed X branches to remote
|
|
423
|
+
✓ Created X PRs
|
|
424
|
+
✓ Merged X PRs
|
|
425
|
+
○ Skipped X WIP branches
|
|
426
|
+
✗ X PRs skipped (CI failed / merge conflicts)
|
|
427
|
+
|
|
428
|
+
WORKTREES:
|
|
429
|
+
✓ Removed X worktrees (merged branches)
|
|
430
|
+
✓ Pruned X stale worktree entries
|
|
431
|
+
○ Preserved X active worktrees
|
|
432
|
+
|
|
433
|
+
CURRENT STATE:
|
|
434
|
+
Branch: <current-branch>
|
|
435
|
+
Worktree: <current-worktree-path>
|
|
436
|
+
|
|
437
|
+
REMAINING BRANCHES:
|
|
438
|
+
- feature-wip (in worktree: /path/to/feature-wip)
|
|
439
|
+
- bugfix-active (ahead 2)
|
|
440
|
+
|
|
441
|
+
ACTIVE WORKTREES:
|
|
442
|
+
/path/to/main main (this worktree)
|
|
443
|
+
/path/to/feature feature-wip clean
|
|
444
|
+
|
|
445
|
+
WARNINGS (if any):
|
|
446
|
+
- PR #42 has merge conflicts, needs manual resolution
|
|
447
|
+
- Worktree at /path/to/feature has uncommitted changes
|
|
448
|
+
=====================================================
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
</workflow>
|
|
452
|
+
|
|
453
|
+
## Error Recovery
|
|
454
|
+
|
|
455
|
+
If the workflow fails at any point, display:
|
|
456
|
+
|
|
457
|
+
1. **Operations completed successfully** (from the operation log)
|
|
458
|
+
2. **The operation that failed** and the error message
|
|
459
|
+
3. **Current repository state**:
|
|
460
|
+
- Current branch: `git branch --show-current`
|
|
461
|
+
- Uncommitted changes: `git status --porcelain`
|
|
462
|
+
- Any in-progress operations: check for rebase/merge/cherry-pick
|
|
463
|
+
|
|
464
|
+
4. **Recovery guidance based on failure point**:
|
|
465
|
+
|
|
466
|
+
**If failed during worktree removal:**
|
|
467
|
+
- Worktree may be partially removed
|
|
468
|
+
- Run: `git worktree prune` to clean up
|
|
469
|
+
- Branch was NOT deleted (safe)
|
|
470
|
+
|
|
471
|
+
**If failed during branch deletion:**
|
|
472
|
+
- Local branch may be deleted but remote still exists (or vice versa)
|
|
473
|
+
- Check: `git branch -a | grep <branch>`
|
|
474
|
+
- Manual cleanup: `git branch -d <branch>` or `git push origin --delete <branch>`
|
|
475
|
+
|
|
476
|
+
**If failed during push:**
|
|
477
|
+
- Changes are local, nothing lost
|
|
478
|
+
- Retry: `git push <remote> <branch>`
|
|
479
|
+
|
|
480
|
+
**If failed during PR creation:**
|
|
481
|
+
- Branch is pushed, PR was not created
|
|
482
|
+
- Retry: `gh pr create --head <branch>`
|
|
483
|
+
|
|
484
|
+
**If failed during merge:**
|
|
485
|
+
- PR still exists, not merged
|
|
486
|
+
- Check PR status: `gh pr view <number>`
|
|
487
|
+
- Retry via GitHub UI or: `gh pr merge <number>`
|
|
488
|
+
|
|
489
|
+
**If failed during rebase:**
|
|
490
|
+
- Rebase may be in progress
|
|
491
|
+
- Check: `git status`
|
|
492
|
+
- Abort if needed: `git rebase --abort`
|
|
493
|
+
- Branch is in original state (safe)
|
|
494
|
+
|
|
495
|
+
5. **Always safe to re-run**: The workflow is idempotent - running it again will skip already-completed operations.
|
|
496
|
+
|
|
497
|
+
---
|
|
498
|
+
|
|
499
|
+
## Safety Rules
|
|
500
|
+
|
|
501
|
+
### Branch Safety Rules
|
|
502
|
+
- NEVER use force push (`--force` or `-f`)
|
|
503
|
+
- NEVER use force delete for branches (`-D`) unless confirmed squash-merged
|
|
504
|
+
- ALWAYS confirm with user before destructive operations
|
|
505
|
+
- NEVER merge without CI passing
|
|
506
|
+
- ALWAYS respect retry limits
|
|
507
|
+
- ALWAYS preserve the user's working context (return to original branch)
|
|
508
|
+
|
|
509
|
+
### Worktree Safety Rules
|
|
510
|
+
- NEVER remove a worktree with uncommitted changes without explicit user confirmation
|
|
511
|
+
- NEVER force remove a worktree (`git worktree remove --force`) - always handle uncommitted changes properly
|
|
512
|
+
- ALWAYS check worktree status (`git -C <path> status --porcelain`) before attempting branch deletion
|
|
513
|
+
- ALWAYS run `git worktree prune` after removing worktrees to clean up stale entries
|
|
514
|
+
- NEVER attempt to remove the main worktree (git will error, but check anyway)
|
|
515
|
+
- ALWAYS use `git -C <path>` for operations in linked worktrees (never cd into them)
|
|
516
|
+
- NEVER delete a branch without first handling its worktree (remove or switch branch)
|
|
517
|
+
- ALWAYS warn user if an operation will affect a worktree they're not currently in
|
|
518
|
+
- ALWAYS preserve at least one worktree (the main one cannot be removed)
|
|
519
|
+
- ALWAYS check for in-progress operations (rebase, merge, cherry-pick) in worktrees before operating on them
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 'Automate entire epic execution by orchestrating sub-agents to execute all stories sequentially with minimal human intervention'
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
IT IS CRITICAL THAT YOU FOLLOW THIS COMMAND: LOAD the FULL @_bmad/bmm/workflows/4-implementation/implement-epic-with-subagents/workflow.md, READ its entire contents and follow its directions exactly!
|