claude-code-workflow 6.3.43 → 6.3.44

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.
Files changed (77) hide show
  1. package/.claude/agents/tdd-developer.md +530 -0
  2. package/.claude/commands/issue/discover-by-prompt.md +5 -1
  3. package/.claude/commands/issue/discover.md +472 -468
  4. package/.claude/commands/issue/execute.md +580 -581
  5. package/.claude/commands/issue/new.md +417 -413
  6. package/.claude/commands/issue/plan.md +5 -1
  7. package/.claude/commands/issue/queue.md +445 -441
  8. package/.claude/commands/task/breakdown.md +207 -203
  9. package/.claude/commands/task/replan.md +440 -436
  10. package/.claude/commands/workflow/action-plan-verify.md +485 -447
  11. package/.claude/commands/workflow/brainstorm/artifacts.md +457 -453
  12. package/.claude/commands/workflow/brainstorm/auto-parallel.md +5 -1
  13. package/.claude/commands/workflow/brainstorm/synthesis.md +402 -398
  14. package/.claude/commands/workflow/clean.md +67 -35
  15. package/.claude/commands/workflow/debug-with-file.md +670 -666
  16. package/.claude/commands/workflow/debug.md +331 -327
  17. package/.claude/commands/workflow/develop-with-file.md +5 -1
  18. package/.claude/commands/workflow/execute.md +546 -498
  19. package/.claude/commands/workflow/lite-execute.md +44 -26
  20. package/.claude/commands/workflow/lite-fix.md +780 -730
  21. package/.claude/commands/workflow/lite-lite-lite.md +5 -1
  22. package/.claude/commands/workflow/lite-plan.md +87 -39
  23. package/.claude/commands/workflow/multi-cli-plan.md +572 -568
  24. package/.claude/commands/workflow/plan-verify.md +527 -0
  25. package/.claude/commands/workflow/plan.md +555 -551
  26. package/.claude/commands/workflow/replan.md +572 -515
  27. package/.claude/commands/workflow/review-fix.md +608 -610
  28. package/.claude/commands/workflow/session/complete.md +37 -14
  29. package/.claude/commands/workflow/session/solidify.md +303 -299
  30. package/.claude/commands/workflow/tdd-plan.md +630 -597
  31. package/.claude/commands/workflow/tdd-verify.md +391 -206
  32. package/.claude/commands/workflow/tools/conflict-resolution.md +24 -12
  33. package/.claude/commands/workflow/tools/task-generate-agent.md +583 -563
  34. package/.claude/commands/workflow/tools/task-generate-tdd.md +749 -517
  35. package/.claude/commands/workflow/ui-design/animation-extract.md +1154 -1150
  36. package/.claude/commands/workflow/ui-design/layout-extract.md +792 -788
  37. package/.claude/commands/workflow/ui-design/style-extract.md +777 -773
  38. package/.claude/skills/ccw/command.json +4 -4
  39. package/.claude/skills/ccw-coordinator/README.md +45 -0
  40. package/.claude/skills/ccw-coordinator/SKILL.md +320 -0
  41. package/.claude/skills/ccw-coordinator/phases/actions/action-abort.md +9 -0
  42. package/.claude/skills/ccw-coordinator/phases/actions/action-command-build.md +40 -0
  43. package/.claude/skills/ccw-coordinator/phases/actions/action-command-execute.md +124 -0
  44. package/.claude/skills/ccw-coordinator/phases/actions/action-command-selection.md +48 -0
  45. package/.claude/skills/ccw-coordinator/phases/actions/action-complete.md +25 -0
  46. package/.claude/skills/ccw-coordinator/phases/actions/action-init.md +26 -0
  47. package/.claude/skills/ccw-coordinator/phases/orchestrator.md +59 -0
  48. package/.claude/skills/ccw-coordinator/phases/state-schema.md +66 -0
  49. package/.claude/skills/ccw-coordinator/skill-config.json +66 -0
  50. package/.claude/skills/ccw-coordinator/specs/command-library.md +169 -0
  51. package/.claude/skills/ccw-coordinator/specs/specs.md +362 -0
  52. package/.claude/skills/ccw-coordinator/tools/README.md +95 -0
  53. package/.claude/skills/ccw-coordinator/tools/chain-validate.cjs +320 -0
  54. package/.claude/skills/ccw-coordinator/tools/command-registry.cjs +255 -0
  55. package/.claude/skills/ccw-help/command.json +5 -5
  56. package/.claude/skills/ccw-help/scripts/analyze_commands.py +337 -337
  57. package/.claude/workflows/cli-templates/prompts/workflow-impl-plan-template.txt +1 -1
  58. package/ccw/dist/commands/issue.d.ts +4 -0
  59. package/ccw/dist/commands/issue.d.ts.map +1 -1
  60. package/ccw/dist/commands/issue.js +73 -6
  61. package/ccw/dist/commands/issue.js.map +1 -1
  62. package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
  63. package/ccw/dist/core/routes/cli-routes.js +32 -28
  64. package/ccw/dist/core/routes/cli-routes.js.map +1 -1
  65. package/ccw/dist/tools/claude-cli-tools.d.ts +10 -0
  66. package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
  67. package/ccw/dist/tools/claude-cli-tools.js +45 -0
  68. package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
  69. package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
  70. package/ccw/dist/tools/codex-lens.js +38 -11
  71. package/ccw/dist/tools/codex-lens.js.map +1 -1
  72. package/ccw/src/commands/issue.ts +84 -6
  73. package/ccw/src/core/routes/cli-routes.ts +30 -25
  74. package/ccw/src/templates/dashboard-js/views/help.js +1 -1
  75. package/ccw/src/tools/claude-cli-tools.ts +50 -0
  76. package/ccw/src/tools/codex-lens.ts +40 -11
  77. package/package.json +1 -1
@@ -1,581 +1,580 @@
1
- ---
2
- name: execute
3
- description: Execute queue with DAG-based parallel orchestration (one commit per solution)
4
- argument-hint: "--queue <queue-id> [--worktree [<existing-path>]]"
5
- allowed-tools: TodoWrite(*), Bash(*), Read(*), AskUserQuestion(*)
6
- ---
7
-
8
- # Issue Execute Command (/issue:execute)
9
-
10
- ## Overview
11
-
12
- Minimal orchestrator that dispatches **solution IDs** to executors. Each executor receives a complete solution with all its tasks.
13
-
14
- **Design Principles:**
15
- - `queue dag` → returns parallel batches with solution IDs (S-1, S-2, ...)
16
- - `detail <id>` READ-ONLY solution fetch (returns full solution with all tasks)
17
- - `done <id>` → update solution completion status
18
- - No race conditions: status changes only via `done`
19
- - **Executor handles all tasks within a solution sequentially**
20
- - **Single worktree for entire queue**: One worktree isolates ALL queue execution from main workspace
21
-
22
- ## Queue ID Requirement (MANDATORY)
23
-
24
- **Queue ID is REQUIRED.** You MUST specify which queue to execute via `--queue <queue-id>`.
25
-
26
- ### If Queue ID Not Provided
27
-
28
- When `--queue` parameter is missing, you MUST:
29
-
30
- 1. **List available queues** by running:
31
- ```javascript
32
- const result = Bash('ccw issue queue list --brief --json');
33
- const index = JSON.parse(result);
34
- ```
35
-
36
- 2. **Display available queues** to user:
37
- ```
38
- Available Queues:
39
- ID Status Progress Issues
40
- -----------------------------------------------------------
41
- → QUE-20251215-001 active 3/10 ISS-001, ISS-002
42
- QUE-20251210-002 active 0/5 ISS-003
43
- QUE-20251205-003 completed 8/8 ISS-004
44
- ```
45
-
46
- 3. **Stop and ask user** to specify which queue to execute:
47
- ```javascript
48
- AskUserQuestion({
49
- questions: [{
50
- question: "Which queue would you like to execute?",
51
- header: "Queue",
52
- multiSelect: false,
53
- options: index.queues
54
- .filter(q => q.status === 'active')
55
- .map(q => ({
56
- label: q.id,
57
- description: `${q.status}, ${q.completed_solutions || 0}/${q.total_solutions || 0} completed, Issues: ${q.issue_ids.join(', ')}`
58
- }))
59
- }]
60
- })
61
- ```
62
-
63
- 4. **After user selection**, continue execution with the selected queue ID.
64
-
65
- **DO NOT auto-select queues.** Explicit user confirmation is required to prevent accidental execution of wrong queue.
66
-
67
- ## Usage
68
-
69
- ```bash
70
- /issue:execute --queue QUE-xxx # Execute specific queue (REQUIRED)
71
- /issue:execute --queue QUE-xxx --worktree # Execute in isolated worktree
72
- /issue:execute --queue QUE-xxx --worktree /path/to/existing/worktree # Resume
73
- ```
74
-
75
- **Parallelism**: Determined automatically by task dependency DAG (no manual control)
76
- **Executor & Dry-run**: Selected via interactive prompt (AskUserQuestion)
77
- **Worktree**: Creates ONE worktree for the entire queue execution (not per-solution)
78
-
79
- **⭐ Recommended Executor**: **Codex** - Best for long-running autonomous work (2hr timeout), supports background execution and full write access
80
-
81
- **Worktree Options**:
82
- - `--worktree` - Create a new worktree with timestamp-based name
83
- - `--worktree <existing-path>` - Resume in an existing worktree (for recovery/continuation)
84
-
85
- **Resume**: Use `git worktree list` to find existing worktrees from interrupted executions
86
-
87
- ## Execution Flow
88
-
89
- ```
90
- Phase 0: Validate Queue ID (REQUIRED)
91
- ├─ If --queue provided → use specified queue
92
- ├─ If --queue missing → list queues, prompt user to select
93
- └─ Store QUEUE_ID for all subsequent commands
94
-
95
- Phase 0.5 (if --worktree): Setup Queue Worktree
96
- ├─ Create ONE worktree for entire queue: .ccw/worktrees/queue-<timestamp>
97
- ├─ All subsequent execution happens in this worktree
98
- └─ Main workspace remains clean and untouched
99
-
100
- Phase 1: Get DAG & User Selection
101
- ├─ ccw issue queue dag --queue ${QUEUE_ID} → { parallel_batches: [["S-1","S-2"], ["S-3"]] }
102
- └─ AskUserQuestion executor type (codex|gemini|agent), dry-run mode, worktree mode
103
-
104
- Phase 2: Dispatch Parallel Batch (DAG-driven)
105
- ├─ Parallelism determined by DAG (no manual limit)
106
- ├─ All executors work in the SAME worktree (or main if no worktree)
107
- ├─ For each solution ID in batch (parallel - all at once):
108
- │ ├─ Executor calls: ccw issue detail <id> (READ-ONLY)
109
- ├─ Executor gets FULL SOLUTION with all tasks
110
- ├─ Executor implements all tasks sequentially (T1 T2 T3)
111
- ├─ Executor tests + verifies each task
112
- │ ├─ Executor commits ONCE per solution (with formatted summary)
113
- └─ Executor calls: ccw issue done <id>
114
- └─ Wait for batch completion
115
-
116
- Phase 3: Next Batch (repeat Phase 2)
117
- └─ ccw issue queue dag → check for newly-ready solutions
118
-
119
- Phase 4 (if --worktree): Worktree Completion
120
- ├─ All batches complete prompt for merge strategy
121
- └─ Options: Create PR / Merge to main / Keep branch
122
- ```
123
-
124
- ## Implementation
125
-
126
- ### Phase 0: Validate Queue ID
127
-
128
- ```javascript
129
- // Check if --queue was provided
130
- let QUEUE_ID = args.queue;
131
-
132
- if (!QUEUE_ID) {
133
- // List available queues
134
- const listResult = Bash('ccw issue queue list --brief --json').trim();
135
- const index = JSON.parse(listResult);
136
-
137
- if (index.queues.length === 0) {
138
- console.log('No queues found. Use /issue:queue to create one first.');
139
- return;
140
- }
141
-
142
- // Filter active queues only
143
- const activeQueues = index.queues.filter(q => q.status === 'active');
144
-
145
- if (activeQueues.length === 0) {
146
- console.log('No active queues found.');
147
- console.log('Available queues:', index.queues.map(q => `${q.id} (${q.status})`).join(', '));
148
- return;
149
- }
150
-
151
- // Display and prompt user
152
- console.log('\nAvailable Queues:');
153
- console.log('ID'.padEnd(22) + 'Status'.padEnd(12) + 'Progress'.padEnd(12) + 'Issues');
154
- console.log('-'.repeat(70));
155
- for (const q of index.queues) {
156
- const marker = q.id === index.active_queue_id ? ' ' : ' ';
157
- console.log(marker + q.id.padEnd(20) + q.status.padEnd(12) +
158
- `${q.completed_solutions || 0}/${q.total_solutions || 0}`.padEnd(12) +
159
- q.issue_ids.join(', '));
160
- }
161
-
162
- const answer = AskUserQuestion({
163
- questions: [{
164
- question: "Which queue would you like to execute?",
165
- header: "Queue",
166
- multiSelect: false,
167
- options: activeQueues.map(q => ({
168
- label: q.id,
169
- description: `${q.completed_solutions || 0}/${q.total_solutions || 0} completed, Issues: ${q.issue_ids.join(', ')}`
170
- }))
171
- }]
172
- });
173
-
174
- QUEUE_ID = answer['Queue'];
175
- }
176
-
177
- console.log(`\n## Executing Queue: ${QUEUE_ID}\n`);
178
- ```
179
-
180
- ### Phase 1: Get DAG & User Selection
181
-
182
- ```javascript
183
- // Get dependency graph and parallel batches (QUEUE_ID required)
184
- const dagJson = Bash(`ccw issue queue dag --queue ${QUEUE_ID}`).trim();
185
- const dag = JSON.parse(dagJson);
186
-
187
- if (dag.error || dag.ready_count === 0) {
188
- console.log(dag.error || 'No solutions ready for execution');
189
- console.log('Use /issue:queue to form a queue first');
190
- return;
191
- }
192
-
193
- console.log(`
194
- ## Queue DAG (Solution-Level)
195
-
196
- - Total Solutions: ${dag.total}
197
- - Ready: ${dag.ready_count}
198
- - Completed: ${dag.completed_count}
199
- - Parallel in batch 1: ${dag.parallel_batches[0]?.length || 0}
200
- `);
201
-
202
- // Interactive selection via AskUserQuestion
203
- const answer = AskUserQuestion({
204
- questions: [
205
- {
206
- question: 'Select executor type:',
207
- header: 'Executor',
208
- multiSelect: false,
209
- options: [
210
- { label: 'Codex (Recommended)', description: 'Autonomous coding with full write access' },
211
- { label: 'Gemini', description: 'Large context analysis and implementation' },
212
- { label: 'Agent', description: 'Claude Code sub-agent for complex tasks' }
213
- ]
214
- },
215
- {
216
- question: 'Execution mode:',
217
- header: 'Mode',
218
- multiSelect: false,
219
- options: [
220
- { label: 'Execute (Recommended)', description: 'Run all ready solutions' },
221
- { label: 'Dry-run', description: 'Show DAG and batches without executing' }
222
- ]
223
- },
224
- {
225
- question: 'Use git worktree for queue isolation?',
226
- header: 'Worktree',
227
- multiSelect: false,
228
- options: [
229
- { label: 'Yes (Recommended)', description: 'Create ONE worktree for entire queue - main stays clean' },
230
- { label: 'No', description: 'Work directly in current directory' }
231
- ]
232
- }
233
- ]
234
- });
235
-
236
- const executor = answer['Executor'].toLowerCase().split(' ')[0]; // codex|gemini|agent
237
- const isDryRun = answer['Mode'].includes('Dry-run');
238
- const useWorktree = answer['Worktree'].includes('Yes');
239
-
240
- // Dry run mode
241
- if (isDryRun) {
242
- console.log('### Parallel Batches (Dry-run):\n');
243
- dag.parallel_batches.forEach((batch, i) => {
244
- console.log(`Batch ${i + 1}: ${batch.join(', ')}`);
245
- });
246
- return;
247
- }
248
- ```
249
-
250
- ### Phase 0 & 2: Setup Queue Worktree & Dispatch
251
-
252
- ```javascript
253
- // Parallelism determined by DAG - no manual limit
254
- // All solutions in same batch have NO file conflicts and can run in parallel
255
- const batch = dag.parallel_batches[0] || [];
256
-
257
- // Initialize TodoWrite
258
- TodoWrite({
259
- todos: batch.map(id => ({
260
- content: `Execute solution ${id}`,
261
- status: 'pending',
262
- activeForm: `Executing solution ${id}`
263
- }))
264
- });
265
-
266
- console.log(`\n### Executing Solutions (DAG batch 1): ${batch.join(', ')}`);
267
-
268
- // Parse existing worktree path from args if provided
269
- // Example: --worktree /path/to/existing/worktree
270
- const existingWorktree = args.worktree && typeof args.worktree === 'string' ? args.worktree : null;
271
-
272
- // Setup ONE worktree for entire queue (not per-solution)
273
- let worktreePath = null;
274
- let worktreeBranch = null;
275
-
276
- if (useWorktree) {
277
- const repoRoot = Bash('git rev-parse --show-toplevel').trim();
278
- const worktreeBase = `${repoRoot}/.ccw/worktrees`;
279
- Bash(`mkdir -p "${worktreeBase}"`);
280
- Bash('git worktree prune'); // Cleanup stale worktrees
281
-
282
- if (existingWorktree) {
283
- // Resume mode: Use existing worktree
284
- worktreePath = existingWorktree;
285
- worktreeBranch = Bash(`git -C "${worktreePath}" branch --show-current`).trim();
286
- console.log(`Resuming in existing worktree: ${worktreePath} (branch: ${worktreeBranch})`);
287
- } else {
288
- // Create mode: ONE worktree for the entire queue
289
- const timestamp = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14);
290
- worktreeBranch = `queue-exec-${dag.queue_id || timestamp}`;
291
- worktreePath = `${worktreeBase}/${worktreeBranch}`;
292
- Bash(`git worktree add "${worktreePath}" -b "${worktreeBranch}"`);
293
- console.log(`Created queue worktree: ${worktreePath}`);
294
- }
295
- }
296
-
297
- // Launch ALL solutions in batch in parallel (DAG guarantees no conflicts)
298
- // All executors work in the SAME worktree (or main if no worktree)
299
- const executions = batch.map(solutionId => {
300
- updateTodo(solutionId, 'in_progress');
301
- return dispatchExecutor(solutionId, executor, worktreePath);
302
- });
303
-
304
- await Promise.all(executions);
305
- batch.forEach(id => updateTodo(id, 'completed'));
306
- ```
307
-
308
- ### Executor Dispatch
309
-
310
- ```javascript
311
- // worktreePath: path to shared worktree (null if not using worktree)
312
- function dispatchExecutor(solutionId, executorType, worktreePath = null) {
313
- // If worktree is provided, executor works in that directory
314
- // No per-solution worktree creation - ONE worktree for entire queue
315
- const cdCommand = worktreePath ? `cd "${worktreePath}"` : '';
316
-
317
- const prompt = `
318
- ## Execute Solution ${solutionId}
319
- ${worktreePath ? `
320
- ### Step 0: Enter Queue Worktree
321
- \`\`\`bash
322
- cd "${worktreePath}"
323
- \`\`\`
324
- ` : ''}
325
- ### Step 1: Get Solution (read-only)
326
- \`\`\`bash
327
- ccw issue detail ${solutionId}
328
- \`\`\`
329
-
330
- ### Step 2: Execute All Tasks Sequentially
331
- The detail command returns a FULL SOLUTION with all tasks.
332
- Execute each task in order (T1 → T2 → T3 → ...):
333
-
334
- For each task:
335
- 1. Follow task.implementation steps
336
- 2. Run task.test commands
337
- 3. Verify task.acceptance criteria
338
- (Do NOT commit after each task)
339
-
340
- ### Step 3: Commit Solution (Once)
341
- After ALL tasks pass, commit once with formatted summary:
342
- \`\`\`bash
343
- git add <all-modified-files>
344
- git commit -m "[type](scope): [solution.description]
345
-
346
- ## Solution Summary
347
- - Solution-ID: ${solutionId}
348
- - Tasks: T1, T2, ...
349
-
350
- ## Tasks Completed
351
- - [T1] task1.title: action
352
- - [T2] task2.title: action
353
-
354
- ## Files Modified
355
- - file1.ts
356
- - file2.ts
357
-
358
- ## Verification
359
- - All tests passed
360
- - All acceptance criteria verified"
361
- \`\`\`
362
-
363
- ### Step 4: Report Completion
364
- \`\`\`bash
365
- ccw issue done ${solutionId} --result '{"summary": "...", "files_modified": [...], "commit": {"hash": "...", "type": "feat"}, "tasks_completed": N}'
366
- \`\`\`
367
-
368
- If any task failed:
369
- \`\`\`bash
370
- ccw issue done ${solutionId} --fail --reason '{"task_id": "TX", "error_type": "test_failure", "message": "..."}'
371
- \`\`\`
372
-
373
- **Note**: Do NOT cleanup worktree after this solution. Worktree is shared by all solutions in the queue.
374
- `;
375
-
376
- // For CLI tools, pass --cd to set working directory
377
- const cdOption = worktreePath ? ` --cd "${worktreePath}"` : '';
378
-
379
- if (executorType === 'codex') {
380
- return Bash(
381
- `ccw cli -p "${escapePrompt(prompt)}" --tool codex --mode write --id exec-${solutionId}${cdOption}`,
382
- { timeout: 7200000, run_in_background: true } // 2hr for full solution
383
- );
384
- } else if (executorType === 'gemini') {
385
- return Bash(
386
- `ccw cli -p "${escapePrompt(prompt)}" --tool gemini --mode write --id exec-${solutionId}${cdOption}`,
387
- { timeout: 3600000, run_in_background: true }
388
- );
389
- } else {
390
- return Task({
391
- subagent_type: 'code-developer',
392
- run_in_background: false,
393
- description: `Execute solution ${solutionId}`,
394
- prompt: worktreePath ? `Working directory: ${worktreePath}\n\n${prompt}` : prompt
395
- });
396
- }
397
- }
398
- ```
399
-
400
- ### Phase 3: Check Next Batch
401
-
402
- ```javascript
403
- // Refresh DAG after batch completes (use same QUEUE_ID)
404
- const refreshedDag = JSON.parse(Bash(`ccw issue queue dag --queue ${QUEUE_ID}`).trim());
405
-
406
- console.log(`
407
- ## Batch Complete
408
-
409
- - Solutions Completed: ${refreshedDag.completed_count}/${refreshedDag.total}
410
- - Next ready: ${refreshedDag.ready_count}
411
- `);
412
-
413
- if (refreshedDag.ready_count > 0) {
414
- console.log(`Run \`/issue:execute --queue ${QUEUE_ID}\` again for next batch.`);
415
- // Note: If resuming, pass existing worktree path:
416
- // /issue:execute --queue ${QUEUE_ID} --worktree <worktreePath>
417
- }
418
- ```
419
-
420
- ### Phase 4: Worktree Completion (after ALL batches)
421
-
422
- ```javascript
423
- // Only run when ALL solutions completed AND using worktree
424
- if (useWorktree && refreshedDag.ready_count === 0 && refreshedDag.completed_count === refreshedDag.total) {
425
- console.log('\n## All Solutions Completed - Worktree Cleanup');
426
-
427
- const answer = AskUserQuestion({
428
- questions: [{
429
- question: `Queue complete. What to do with worktree branch "${worktreeBranch}"?`,
430
- header: 'Merge',
431
- multiSelect: false,
432
- options: [
433
- { label: 'Create PR (Recommended)', description: 'Push branch and create pull request' },
434
- { label: 'Merge to main', description: 'Merge all commits and cleanup worktree' },
435
- { label: 'Keep branch', description: 'Cleanup worktree, keep branch for manual handling' }
436
- ]
437
- }]
438
- });
439
-
440
- const repoRoot = Bash('git rev-parse --show-toplevel').trim();
441
-
442
- if (answer['Merge'].includes('Create PR')) {
443
- Bash(`git -C "${worktreePath}" push -u origin "${worktreeBranch}"`);
444
- Bash(`gh pr create --title "Queue ${dag.queue_id}" --body "Issue queue execution - all solutions completed" --head "${worktreeBranch}"`);
445
- Bash(`git worktree remove "${worktreePath}"`);
446
- console.log(`PR created for branch: ${worktreeBranch}`);
447
- } else if (answer['Merge'].includes('Merge to main')) {
448
- // Check main is clean
449
- const mainDirty = Bash('git status --porcelain').trim();
450
- if (mainDirty) {
451
- console.log('Warning: Main has uncommitted changes. Falling back to PR.');
452
- Bash(`git -C "${worktreePath}" push -u origin "${worktreeBranch}"`);
453
- Bash(`gh pr create --title "Queue ${dag.queue_id}" --body "Issue queue execution (main had uncommitted changes)" --head "${worktreeBranch}"`);
454
- } else {
455
- Bash(`git merge --no-ff "${worktreeBranch}" -m "Merge queue ${dag.queue_id}"`);
456
- Bash(`git branch -d "${worktreeBranch}"`);
457
- }
458
- Bash(`git worktree remove "${worktreePath}"`);
459
- } else {
460
- Bash(`git worktree remove "${worktreePath}"`);
461
- console.log(`Branch ${worktreeBranch} kept for manual handling`);
462
- }
463
- }
464
- ```
465
-
466
- ## Parallel Execution Model
467
-
468
- ```
469
- ┌─────────────────────────────────────────────────────────────────┐
470
- │ Orchestrator │
471
- ├─────────────────────────────────────────────────────────────────┤
472
- 0. Validate QUEUE_ID (required, or prompt user to select)
473
-
474
- 0.5 (if --worktree) Create ONE worktree for entire queue
475
- → .ccw/worktrees/queue-exec-<queue-id>
476
-
477
- 1. ccw issue queue dag --queue ${QUEUE_ID}
478
- → { parallel_batches: [["S-1","S-2"], ["S-3"]] }
479
-
480
- 2. Dispatch batch 1 (parallel, SAME worktree):
481
- ┌──────────────────────────────────────────────────────┐
482
- │ │ Shared Queue Worktree (or main) │ │
483
- │ │ ┌──────────────────┐ ┌──────────────────┐ │ │
484
- │ │ │ Executor 1 │ │ Executor 2 │ │ │
485
- │ │ │ detail S-1 │ │ detail S-2 │ │ │
486
- │ │ │ [T1→T2→T3] │ │ [T1→T2] │ │ │
487
- │ │ │ commit S-1 │ │ commit S-2 │ │ │
488
- │ │ done S-1 │ │ done S-2 │ │ │
489
- │ └──────────────────┘ └──────────────────┘ │
490
- └──────────────────────────────────────────────────────┘
491
-
492
- │ 3. ccw issue queue dag (refresh)
493
- → S-3 now ready → dispatch batch 2 (same worktree)
494
-
495
- 4. (if --worktree) ALL batches complete cleanup worktree
496
- │ → Prompt: Create PR / Merge to main / Keep branch │
497
- └─────────────────────────────────────────────────────────────────┘
498
- ```
499
-
500
- **Why this works for parallel:**
501
- - **ONE worktree for entire queue** all solutions share same isolated workspace
502
- - `detail <id>` is READ-ONLY no race conditions
503
- - Each executor handles **all tasks within a solution** sequentially
504
- - **One commit per solution** with formatted summary (not per-task)
505
- - `done <id>` updates only its own solution status
506
- - `queue dag` recalculates ready solutions after each batch
507
- - Solutions in same batch have NO file conflicts (DAG guarantees)
508
- - **Main workspace stays clean** until merge/PR decision
509
-
510
- ## CLI Endpoint Contract
511
-
512
- ### `ccw issue queue list --brief --json`
513
- Returns queue index for selection (used when --queue not provided):
514
- ```json
515
- {
516
- "active_queue_id": "QUE-20251215-001",
517
- "queues": [
518
- { "id": "QUE-20251215-001", "status": "active", "issue_ids": ["ISS-001"], "total_solutions": 5, "completed_solutions": 2 }
519
- ]
520
- }
521
- ```
522
-
523
- ### `ccw issue queue dag --queue <queue-id>`
524
- Returns dependency graph with parallel batches (solution-level, **--queue required**):
525
- ```json
526
- {
527
- "queue_id": "QUE-...",
528
- "total": 3,
529
- "ready_count": 2,
530
- "completed_count": 0,
531
- "nodes": [
532
- { "id": "S-1", "issue_id": "ISS-xxx", "status": "pending", "ready": true, "task_count": 3 },
533
- { "id": "S-2", "issue_id": "ISS-yyy", "status": "pending", "ready": true, "task_count": 2 },
534
- { "id": "S-3", "issue_id": "ISS-zzz", "status": "pending", "ready": false, "depends_on": ["S-1"] }
535
- ],
536
- "parallel_batches": [["S-1", "S-2"], ["S-3"]]
537
- }
538
- ```
539
-
540
- ### `ccw issue detail <item_id>`
541
- Returns FULL SOLUTION with all tasks (READ-ONLY):
542
- ```json
543
- {
544
- "item_id": "S-1",
545
- "issue_id": "ISS-xxx",
546
- "solution_id": "SOL-xxx",
547
- "status": "pending",
548
- "solution": {
549
- "id": "SOL-xxx",
550
- "approach": "...",
551
- "tasks": [
552
- { "id": "T1", "title": "...", "implementation": [...], "test": {...} },
553
- { "id": "T2", "title": "...", "implementation": [...], "test": {...} },
554
- { "id": "T3", "title": "...", "implementation": [...], "test": {...} }
555
- ],
556
- "exploration_context": { "relevant_files": [...] }
557
- },
558
- "execution_hints": { "executor": "codex", "estimated_minutes": 180 }
559
- }
560
- ```
561
-
562
- ### `ccw issue done <item_id>`
563
- Marks solution completed/failed, updates queue state, checks for queue completion.
564
-
565
- ## Error Handling
566
-
567
- | Error | Resolution |
568
- |-------|------------|
569
- | No queue | Run /issue:queue first |
570
- | No ready solutions | Dependencies blocked, check DAG |
571
- | Executor timeout | Solution not marked done, can retry |
572
- | Solution failure | Use `ccw issue retry` to reset |
573
- | Partial task failure | Executor reports which task failed via `done --fail` |
574
-
575
- ## Related Commands
576
-
577
- - `/issue:plan` - Plan issues with solutions
578
- - `/issue:queue` - Form execution queue
579
- - `ccw issue queue dag` - View dependency graph
580
- - `ccw issue detail <id>` - View task details
581
- - `ccw issue retry` - Reset failed tasks
1
+ ---
2
+ name: execute
3
+ description: Execute queue with DAG-based parallel orchestration (one commit per solution)
4
+ argument-hint: "[-y|--yes] --queue <queue-id> [--worktree [<existing-path>]]"
5
+ allowed-tools: TodoWrite(*), Bash(*), Read(*), AskUserQuestion(*)
6
+ ---
7
+
8
+ ## Auto Mode
9
+
10
+ When `--yes` or `-y`: Auto-confirm execution, use recommended settings.
11
+
12
+ # Issue Execute Command (/issue:execute)
13
+
14
+ ## Overview
15
+
16
+ Minimal orchestrator that dispatches **solution IDs** to executors. Each executor receives a complete solution with all its tasks.
17
+
18
+ **Design Principles:**
19
+ - `queue dag` returns parallel batches with solution IDs (S-1, S-2, ...)
20
+ - `detail <id>` READ-ONLY solution fetch (returns full solution with all tasks)
21
+ - `done <id>` → update solution completion status
22
+ - No race conditions: status changes only via `done`
23
+ - **Executor handles all tasks within a solution sequentially**
24
+ - **Single worktree for entire queue**: One worktree isolates ALL queue execution from main workspace
25
+
26
+ ## Queue ID Requirement (MANDATORY)
27
+
28
+ **Queue ID is REQUIRED.** You MUST specify which queue to execute via `--queue <queue-id>`.
29
+
30
+ ### If Queue ID Not Provided
31
+
32
+ When `--queue` parameter is missing, you MUST:
33
+
34
+ 1. **List available queues** by running:
35
+ ```javascript
36
+ const result = Bash('ccw issue queue list --brief --json');
37
+ const index = JSON.parse(result);
38
+ ```
39
+
40
+ 2. **Display available queues** to user:
41
+ ```
42
+ Available Queues:
43
+ ID Status Progress Issues
44
+ -----------------------------------------------------------
45
+ → QUE-20251215-001 active 3/10 ISS-001, ISS-002
46
+ QUE-20251210-002 active 0/5 ISS-003
47
+ QUE-20251205-003 completed 8/8 ISS-004
48
+ ```
49
+
50
+ 3. **Stop and ask user** to specify which queue to execute:
51
+ ```javascript
52
+ AskUserQuestion({
53
+ questions: [{
54
+ question: "Which queue would you like to execute?",
55
+ header: "Queue",
56
+ multiSelect: false,
57
+ options: index.queues
58
+ .filter(q => q.status === 'active')
59
+ .map(q => ({
60
+ label: q.id,
61
+ description: `${q.status}, ${q.completed_solutions || 0}/${q.total_solutions || 0} completed, Issues: ${q.issue_ids.join(', ')}`
62
+ }))
63
+ }]
64
+ })
65
+ ```
66
+
67
+ 4. **After user selection**, continue execution with the selected queue ID.
68
+
69
+ **DO NOT auto-select queues.** Explicit user confirmation is required to prevent accidental execution of wrong queue.
70
+
71
+ ## Usage
72
+
73
+ ```bash
74
+ /issue:execute --queue QUE-xxx # Execute specific queue (REQUIRED)
75
+ /issue:execute --queue QUE-xxx --worktree # Execute in isolated worktree
76
+ /issue:execute --queue QUE-xxx --worktree /path/to/existing/worktree # Resume
77
+ ```
78
+
79
+ **Parallelism**: Determined automatically by task dependency DAG (no manual control)
80
+ **Executor & Dry-run**: Selected via interactive prompt (AskUserQuestion)
81
+ **Worktree**: Creates ONE worktree for the entire queue execution (not per-solution)
82
+
83
+ **⭐ Recommended Executor**: **Codex** - Best for long-running autonomous work (2hr timeout), supports background execution and full write access
84
+
85
+ **Worktree Options**:
86
+ - `--worktree` - Create a new worktree with timestamp-based name
87
+ - `--worktree <existing-path>` - Resume in an existing worktree (for recovery/continuation)
88
+
89
+ **Resume**: Use `git worktree list` to find existing worktrees from interrupted executions
90
+
91
+ ## Execution Flow
92
+
93
+ ```
94
+ Phase 0: Validate Queue ID (REQUIRED)
95
+ ├─ If --queue provided use specified queue
96
+ ├─ If --queue missing list queues, prompt user to select
97
+ └─ Store QUEUE_ID for all subsequent commands
98
+
99
+ Phase 0.5 (if --worktree): Setup Queue Worktree
100
+ ├─ Create ONE worktree for entire queue: .ccw/worktrees/queue-<timestamp>
101
+ ├─ All subsequent execution happens in this worktree
102
+ └─ Main workspace remains clean and untouched
103
+
104
+ Phase 1: Get DAG & User Selection
105
+ ├─ ccw issue queue dag --queue ${QUEUE_ID} → { parallel_batches: [["S-1","S-2"], ["S-3"]] }
106
+ └─ AskUserQuestion executor type (codex|gemini|agent), dry-run mode, worktree mode
107
+
108
+ Phase 2: Dispatch Parallel Batch (DAG-driven)
109
+ ├─ Parallelism determined by DAG (no manual limit)
110
+ ├─ All executors work in the SAME worktree (or main if no worktree)
111
+ ├─ For each solution ID in batch (parallel - all at once):
112
+ │ ├─ Executor calls: ccw issue detail <id> (READ-ONLY)
113
+ ├─ Executor gets FULL SOLUTION with all tasks
114
+ │ ├─ Executor implements all tasks sequentially (T1 → T2 → T3)
115
+ │ ├─ Executor tests + verifies each task
116
+ │ ├─ Executor commits ONCE per solution (with formatted summary)
117
+ └─ Executor calls: ccw issue done <id>
118
+ └─ Wait for batch completion
119
+
120
+ Phase 3: Next Batch (repeat Phase 2)
121
+ └─ ccw issue queue dag check for newly-ready solutions
122
+
123
+ Phase 4 (if --worktree): Worktree Completion
124
+ ├─ All batches complete → prompt for merge strategy
125
+ └─ Options: Create PR / Merge to main / Keep branch
126
+ ```
127
+
128
+ ## Implementation
129
+
130
+ ### Phase 0: Validate Queue ID
131
+
132
+ ```javascript
133
+ // Check if --queue was provided
134
+ let QUEUE_ID = args.queue;
135
+
136
+ if (!QUEUE_ID) {
137
+ // List available queues
138
+ const listResult = Bash('ccw issue queue list --brief --json').trim();
139
+ const index = JSON.parse(listResult);
140
+
141
+ if (index.queues.length === 0) {
142
+ console.log('No queues found. Use /issue:queue to create one first.');
143
+ return;
144
+ }
145
+
146
+ // Filter active queues only
147
+ const activeQueues = index.queues.filter(q => q.status === 'active');
148
+
149
+ if (activeQueues.length === 0) {
150
+ console.log('No active queues found.');
151
+ console.log('Available queues:', index.queues.map(q => `${q.id} (${q.status})`).join(', '));
152
+ return;
153
+ }
154
+
155
+ // Display and prompt user
156
+ console.log('\nAvailable Queues:');
157
+ console.log('ID'.padEnd(22) + 'Status'.padEnd(12) + 'Progress'.padEnd(12) + 'Issues');
158
+ console.log('-'.repeat(70));
159
+ for (const q of index.queues) {
160
+ const marker = q.id === index.active_queue_id ? '→ ' : ' ';
161
+ console.log(marker + q.id.padEnd(20) + q.status.padEnd(12) +
162
+ `${q.completed_solutions || 0}/${q.total_solutions || 0}`.padEnd(12) +
163
+ q.issue_ids.join(', '));
164
+ }
165
+
166
+ const answer = AskUserQuestion({
167
+ questions: [{
168
+ question: "Which queue would you like to execute?",
169
+ header: "Queue",
170
+ multiSelect: false,
171
+ options: activeQueues.map(q => ({
172
+ label: q.id,
173
+ description: `${q.completed_solutions || 0}/${q.total_solutions || 0} completed, Issues: ${q.issue_ids.join(', ')}`
174
+ }))
175
+ }]
176
+ });
177
+
178
+ QUEUE_ID = answer['Queue'];
179
+ }
180
+
181
+ console.log(`\n## Executing Queue: ${QUEUE_ID}\n`);
182
+ ```
183
+
184
+ ### Phase 1: Get DAG & User Selection
185
+
186
+ ```javascript
187
+ // Get dependency graph and parallel batches (QUEUE_ID required)
188
+ const dagJson = Bash(`ccw issue queue dag --queue ${QUEUE_ID}`).trim();
189
+ const dag = JSON.parse(dagJson);
190
+
191
+ if (dag.error || dag.ready_count === 0) {
192
+ console.log(dag.error || 'No solutions ready for execution');
193
+ console.log('Use /issue:queue to form a queue first');
194
+ return;
195
+ }
196
+
197
+ console.log(`
198
+ ## Queue DAG (Solution-Level)
199
+
200
+ - Total Solutions: ${dag.total}
201
+ - Ready: ${dag.ready_count}
202
+ - Completed: ${dag.completed_count}
203
+ - Parallel in batch 1: ${dag.parallel_batches[0]?.length || 0}
204
+ `);
205
+
206
+ // Interactive selection via AskUserQuestion
207
+ const answer = AskUserQuestion({
208
+ questions: [
209
+ {
210
+ question: 'Select executor type:',
211
+ header: 'Executor',
212
+ multiSelect: false,
213
+ options: [
214
+ { label: 'Codex (Recommended)', description: 'Autonomous coding with full write access' },
215
+ { label: 'Gemini', description: 'Large context analysis and implementation' },
216
+ { label: 'Agent', description: 'Claude Code sub-agent for complex tasks' }
217
+ ]
218
+ },
219
+ {
220
+ question: 'Execution mode:',
221
+ header: 'Mode',
222
+ multiSelect: false,
223
+ options: [
224
+ { label: 'Execute (Recommended)', description: 'Run all ready solutions' },
225
+ { label: 'Dry-run', description: 'Show DAG and batches without executing' }
226
+ ]
227
+ },
228
+ {
229
+ question: 'Use git worktree for queue isolation?',
230
+ header: 'Worktree',
231
+ multiSelect: false,
232
+ options: [
233
+ { label: 'Yes (Recommended)', description: 'Create ONE worktree for entire queue - main stays clean' },
234
+ { label: 'No', description: 'Work directly in current directory' }
235
+ ]
236
+ }
237
+ ]
238
+ });
239
+
240
+ const executor = answer['Executor'].toLowerCase().split(' ')[0]; // codex|gemini|agent
241
+ const isDryRun = answer['Mode'].includes('Dry-run');
242
+ const useWorktree = answer['Worktree'].includes('Yes');
243
+
244
+ // Dry run mode
245
+ if (isDryRun) {
246
+ console.log('### Parallel Batches (Dry-run):\n');
247
+ dag.parallel_batches.forEach((batch, i) => {
248
+ console.log(`Batch ${i + 1}: ${batch.join(', ')}`);
249
+ });
250
+ return;
251
+ }
252
+ ```
253
+
254
+ ### Phase 0 & 2: Setup Queue Worktree & Dispatch
255
+
256
+ ```javascript
257
+ // Parallelism determined by DAG - no manual limit
258
+ // All solutions in same batch have NO file conflicts and can run in parallel
259
+ const batch = dag.parallel_batches[0] || [];
260
+
261
+ // Initialize TodoWrite
262
+ TodoWrite({
263
+ todos: batch.map(id => ({
264
+ content: `Execute solution ${id}`,
265
+ status: 'pending',
266
+ activeForm: `Executing solution ${id}`
267
+ }))
268
+ });
269
+
270
+ console.log(`\n### Executing Solutions (DAG batch 1): ${batch.join(', ')}`);
271
+
272
+ // Parse existing worktree path from args if provided
273
+ // Example: --worktree /path/to/existing/worktree
274
+ const existingWorktree = args.worktree && typeof args.worktree === 'string' ? args.worktree : null;
275
+
276
+ // Setup ONE worktree for entire queue (not per-solution)
277
+ let worktreePath = null;
278
+ let worktreeBranch = null;
279
+
280
+ if (useWorktree) {
281
+ const repoRoot = Bash('git rev-parse --show-toplevel').trim();
282
+ const worktreeBase = `${repoRoot}/.ccw/worktrees`;
283
+ Bash(`mkdir -p "${worktreeBase}"`);
284
+ Bash('git worktree prune'); // Cleanup stale worktrees
285
+
286
+ if (existingWorktree) {
287
+ // Resume mode: Use existing worktree
288
+ worktreePath = existingWorktree;
289
+ worktreeBranch = Bash(`git -C "${worktreePath}" branch --show-current`).trim();
290
+ console.log(`Resuming in existing worktree: ${worktreePath} (branch: ${worktreeBranch})`);
291
+ } else {
292
+ // Create mode: ONE worktree for the entire queue
293
+ const timestamp = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14);
294
+ worktreeBranch = `queue-exec-${dag.queue_id || timestamp}`;
295
+ worktreePath = `${worktreeBase}/${worktreeBranch}`;
296
+ Bash(`git worktree add "${worktreePath}" -b "${worktreeBranch}"`);
297
+ console.log(`Created queue worktree: ${worktreePath}`);
298
+ }
299
+ }
300
+
301
+ // Launch ALL solutions in batch in parallel (DAG guarantees no conflicts)
302
+ // All executors work in the SAME worktree (or main if no worktree)
303
+ const executions = batch.map(solutionId => {
304
+ updateTodo(solutionId, 'in_progress');
305
+ return dispatchExecutor(solutionId, executor, worktreePath);
306
+ });
307
+
308
+ await Promise.all(executions);
309
+ batch.forEach(id => updateTodo(id, 'completed'));
310
+ ```
311
+
312
+ ### Executor Dispatch
313
+
314
+ ```javascript
315
+ // worktreePath: path to shared worktree (null if not using worktree)
316
+ function dispatchExecutor(solutionId, executorType, worktreePath = null) {
317
+ // If worktree is provided, executor works in that directory
318
+ // No per-solution worktree creation - ONE worktree for entire queue
319
+
320
+ // Pre-defined values (replaced at dispatch time, NOT by executor)
321
+ const SOLUTION_ID = solutionId;
322
+ const WORK_DIR = worktreePath || null;
323
+
324
+ // Build prompt without markdown code blocks to avoid escaping issues
325
+ const prompt = `
326
+ ## Execute Solution: ${SOLUTION_ID}
327
+ ${WORK_DIR ? `Working Directory: ${WORK_DIR}` : ''}
328
+
329
+ ### Step 1: Get Solution Details
330
+ Run this command to get the full solution with all tasks:
331
+ ccw issue detail ${SOLUTION_ID}
332
+
333
+ ### Step 2: Execute All Tasks Sequentially
334
+ The detail command returns a FULL SOLUTION with all tasks.
335
+ Execute each task in order (T1 → T2 → T3 → ...):
336
+
337
+ For each task:
338
+ - Follow task.implementation steps
339
+ - Run task.test commands
340
+ - Verify task.acceptance criteria
341
+ - Do NOT commit after each task
342
+
343
+ ### Step 3: Commit Solution (Once)
344
+ After ALL tasks pass, commit once with formatted summary.
345
+
346
+ Command:
347
+ git add -A
348
+ git commit -m "<type>(<scope>): <description>
349
+
350
+ Solution: ${SOLUTION_ID}
351
+ Tasks completed: <list task IDs>
352
+
353
+ Changes:
354
+ - <file1>: <what changed>
355
+ - <file2>: <what changed>
356
+
357
+ Verified: all tests passed"
358
+
359
+ Replace <type> with: feat|fix|refactor|docs|test
360
+ Replace <scope> with: affected module name
361
+ Replace <description> with: brief summary from solution
362
+
363
+ ### Step 4: Report Completion
364
+ On success, run:
365
+ ccw issue done ${SOLUTION_ID} --result '{"summary": "<brief>", "files_modified": ["<file1>", "<file2>"], "commit": {"hash": "<hash>", "type": "<type>"}, "tasks_completed": <N>}'
366
+
367
+ On failure, run:
368
+ ccw issue done ${SOLUTION_ID} --fail --reason '{"task_id": "<TX>", "error_type": "<test_failure|build_error|other>", "message": "<error details>"}'
369
+
370
+ ### Important Notes
371
+ - Do NOT cleanup worktree - it is shared by all solutions in the queue
372
+ - Replace all <placeholder> values with actual values from your execution
373
+ `;
374
+
375
+ // For CLI tools, pass --cd to set working directory
376
+ const cdOption = worktreePath ? ` --cd "${worktreePath}"` : '';
377
+
378
+ if (executorType === 'codex') {
379
+ return Bash(
380
+ `ccw cli -p "${escapePrompt(prompt)}" --tool codex --mode write --id exec-${solutionId}${cdOption}`,
381
+ { timeout: 7200000, run_in_background: true } // 2hr for full solution
382
+ );
383
+ } else if (executorType === 'gemini') {
384
+ return Bash(
385
+ `ccw cli -p "${escapePrompt(prompt)}" --tool gemini --mode write --id exec-${solutionId}${cdOption}`,
386
+ { timeout: 3600000, run_in_background: true }
387
+ );
388
+ } else {
389
+ return Task({
390
+ subagent_type: 'code-developer',
391
+ run_in_background: false,
392
+ description: `Execute solution ${solutionId}`,
393
+ prompt: worktreePath ? `Working directory: ${worktreePath}\n\n${prompt}` : prompt
394
+ });
395
+ }
396
+ }
397
+ ```
398
+
399
+ ### Phase 3: Check Next Batch
400
+
401
+ ```javascript
402
+ // Refresh DAG after batch completes (use same QUEUE_ID)
403
+ const refreshedDag = JSON.parse(Bash(`ccw issue queue dag --queue ${QUEUE_ID}`).trim());
404
+
405
+ console.log(`
406
+ ## Batch Complete
407
+
408
+ - Solutions Completed: ${refreshedDag.completed_count}/${refreshedDag.total}
409
+ - Next ready: ${refreshedDag.ready_count}
410
+ `);
411
+
412
+ if (refreshedDag.ready_count > 0) {
413
+ console.log(`Run \`/issue:execute --queue ${QUEUE_ID}\` again for next batch.`);
414
+ // Note: If resuming, pass existing worktree path:
415
+ // /issue:execute --queue ${QUEUE_ID} --worktree <worktreePath>
416
+ }
417
+ ```
418
+
419
+ ### Phase 4: Worktree Completion (after ALL batches)
420
+
421
+ ```javascript
422
+ // Only run when ALL solutions completed AND using worktree
423
+ if (useWorktree && refreshedDag.ready_count === 0 && refreshedDag.completed_count === refreshedDag.total) {
424
+ console.log('\n## All Solutions Completed - Worktree Cleanup');
425
+
426
+ const answer = AskUserQuestion({
427
+ questions: [{
428
+ question: `Queue complete. What to do with worktree branch "${worktreeBranch}"?`,
429
+ header: 'Merge',
430
+ multiSelect: false,
431
+ options: [
432
+ { label: 'Create PR (Recommended)', description: 'Push branch and create pull request' },
433
+ { label: 'Merge to main', description: 'Merge all commits and cleanup worktree' },
434
+ { label: 'Keep branch', description: 'Cleanup worktree, keep branch for manual handling' }
435
+ ]
436
+ }]
437
+ });
438
+
439
+ const repoRoot = Bash('git rev-parse --show-toplevel').trim();
440
+
441
+ if (answer['Merge'].includes('Create PR')) {
442
+ Bash(`git -C "${worktreePath}" push -u origin "${worktreeBranch}"`);
443
+ Bash(`gh pr create --title "Queue ${dag.queue_id}" --body "Issue queue execution - all solutions completed" --head "${worktreeBranch}"`);
444
+ Bash(`git worktree remove "${worktreePath}"`);
445
+ console.log(`PR created for branch: ${worktreeBranch}`);
446
+ } else if (answer['Merge'].includes('Merge to main')) {
447
+ // Check main is clean
448
+ const mainDirty = Bash('git status --porcelain').trim();
449
+ if (mainDirty) {
450
+ console.log('Warning: Main has uncommitted changes. Falling back to PR.');
451
+ Bash(`git -C "${worktreePath}" push -u origin "${worktreeBranch}"`);
452
+ Bash(`gh pr create --title "Queue ${dag.queue_id}" --body "Issue queue execution (main had uncommitted changes)" --head "${worktreeBranch}"`);
453
+ } else {
454
+ Bash(`git merge --no-ff "${worktreeBranch}" -m "Merge queue ${dag.queue_id}"`);
455
+ Bash(`git branch -d "${worktreeBranch}"`);
456
+ }
457
+ Bash(`git worktree remove "${worktreePath}"`);
458
+ } else {
459
+ Bash(`git worktree remove "${worktreePath}"`);
460
+ console.log(`Branch ${worktreeBranch} kept for manual handling`);
461
+ }
462
+ }
463
+ ```
464
+
465
+ ## Parallel Execution Model
466
+
467
+ ```
468
+ ┌─────────────────────────────────────────────────────────────────┐
469
+ │ Orchestrator │
470
+ ├─────────────────────────────────────────────────────────────────┤
471
+ │ 0. Validate QUEUE_ID (required, or prompt user to select) │
472
+
473
+ 0.5 (if --worktree) Create ONE worktree for entire queue
474
+ .ccw/worktrees/queue-exec-<queue-id>
475
+
476
+ 1. ccw issue queue dag --queue ${QUEUE_ID}
477
+ { parallel_batches: [["S-1","S-2"], ["S-3"]] }
478
+
479
+ 2. Dispatch batch 1 (parallel, SAME worktree):
480
+ ┌──────────────────────────────────────────────────────┐
481
+ │ Shared Queue Worktree (or main) │
482
+ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │
483
+ │ │ Executor 1 │ │ Executor 2 │ │ │
484
+ │ │ │ detail S-1 │ │ detail S-2 │ │ │
485
+ │ │ │ [T1→T2→T3] │ │ [T1→T2] │ │ │
486
+ │ │ │ commit S-1 │ │ commit S-2 │ │ │
487
+ │ │ │ done S-1 │ │ done S-2 │ │ │
488
+ │ │ └──────────────────┘ └──────────────────┘ │ │
489
+ └──────────────────────────────────────────────────────┘
490
+
491
+ 3. ccw issue queue dag (refresh)
492
+ S-3 now ready dispatch batch 2 (same worktree)
493
+
494
+ 4. (if --worktree) ALL batches complete → cleanup worktree
495
+ Prompt: Create PR / Merge to main / Keep branch
496
+ └─────────────────────────────────────────────────────────────────┘
497
+ ```
498
+
499
+ **Why this works for parallel:**
500
+ - **ONE worktree for entire queue** → all solutions share same isolated workspace
501
+ - `detail <id>` is READ-ONLYno race conditions
502
+ - Each executor handles **all tasks within a solution** sequentially
503
+ - **One commit per solution** with formatted summary (not per-task)
504
+ - `done <id>` updates only its own solution status
505
+ - `queue dag` recalculates ready solutions after each batch
506
+ - Solutions in same batch have NO file conflicts (DAG guarantees)
507
+ - **Main workspace stays clean** until merge/PR decision
508
+
509
+ ## CLI Endpoint Contract
510
+
511
+ ### `ccw issue queue list --brief --json`
512
+ Returns queue index for selection (used when --queue not provided):
513
+ ```json
514
+ {
515
+ "active_queue_id": "QUE-20251215-001",
516
+ "queues": [
517
+ { "id": "QUE-20251215-001", "status": "active", "issue_ids": ["ISS-001"], "total_solutions": 5, "completed_solutions": 2 }
518
+ ]
519
+ }
520
+ ```
521
+
522
+ ### `ccw issue queue dag --queue <queue-id>`
523
+ Returns dependency graph with parallel batches (solution-level, **--queue required**):
524
+ ```json
525
+ {
526
+ "queue_id": "QUE-...",
527
+ "total": 3,
528
+ "ready_count": 2,
529
+ "completed_count": 0,
530
+ "nodes": [
531
+ { "id": "S-1", "issue_id": "ISS-xxx", "status": "pending", "ready": true, "task_count": 3 },
532
+ { "id": "S-2", "issue_id": "ISS-yyy", "status": "pending", "ready": true, "task_count": 2 },
533
+ { "id": "S-3", "issue_id": "ISS-zzz", "status": "pending", "ready": false, "depends_on": ["S-1"] }
534
+ ],
535
+ "parallel_batches": [["S-1", "S-2"], ["S-3"]]
536
+ }
537
+ ```
538
+
539
+ ### `ccw issue detail <item_id>`
540
+ Returns FULL SOLUTION with all tasks (READ-ONLY):
541
+ ```json
542
+ {
543
+ "item_id": "S-1",
544
+ "issue_id": "ISS-xxx",
545
+ "solution_id": "SOL-xxx",
546
+ "status": "pending",
547
+ "solution": {
548
+ "id": "SOL-xxx",
549
+ "approach": "...",
550
+ "tasks": [
551
+ { "id": "T1", "title": "...", "implementation": [...], "test": {...} },
552
+ { "id": "T2", "title": "...", "implementation": [...], "test": {...} },
553
+ { "id": "T3", "title": "...", "implementation": [...], "test": {...} }
554
+ ],
555
+ "exploration_context": { "relevant_files": [...] }
556
+ },
557
+ "execution_hints": { "executor": "codex", "estimated_minutes": 180 }
558
+ }
559
+ ```
560
+
561
+ ### `ccw issue done <item_id>`
562
+ Marks solution completed/failed, updates queue state, checks for queue completion.
563
+
564
+ ## Error Handling
565
+
566
+ | Error | Resolution |
567
+ |-------|------------|
568
+ | No queue | Run /issue:queue first |
569
+ | No ready solutions | Dependencies blocked, check DAG |
570
+ | Executor timeout | Solution not marked done, can retry |
571
+ | Solution failure | Use `ccw issue retry` to reset |
572
+ | Partial task failure | Executor reports which task failed via `done --fail` |
573
+
574
+ ## Related Commands
575
+
576
+ - `/issue:plan` - Plan issues with solutions
577
+ - `/issue:queue` - Form execution queue
578
+ - `ccw issue queue dag` - View dependency graph
579
+ - `ccw issue detail <id>` - View task details
580
+ - `ccw issue retry` - Reset failed tasks