claude-code-workflow 6.3.9 → 6.3.10
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/CLAUDE.md +1 -1
- package/.claude/agents/issue-plan-agent.md +3 -10
- package/.claude/agents/issue-queue-agent.md +103 -83
- package/.claude/commands/issue/execute.md +195 -363
- package/.claude/commands/issue/plan.md +9 -2
- package/.claude/commands/issue/queue.md +130 -66
- package/.claude/commands/workflow/init.md +75 -29
- package/.claude/commands/workflow/lite-fix.md +8 -0
- package/.claude/commands/workflow/lite-plan.md +8 -0
- package/.claude/commands/workflow/review-module-cycle.md +4 -0
- package/.claude/commands/workflow/review-session-cycle.md +4 -0
- package/.claude/commands/workflow/review.md +4 -4
- package/.claude/commands/workflow/session/solidify.md +299 -0
- package/.claude/commands/workflow/session/start.md +10 -7
- package/.claude/commands/workflow/tools/context-gather.md +17 -10
- package/.claude/workflows/cli-templates/schemas/queue-schema.json +225 -108
- package/.claude/workflows/cli-templates/schemas/solution-schema.json +6 -28
- package/.claude/workflows/context-tools.md +17 -25
- package/.codex/AGENTS.md +10 -5
- package/ccw/dist/commands/issue.d.ts.map +1 -1
- package/ccw/dist/commands/issue.js +348 -115
- package/ccw/dist/commands/issue.js.map +1 -1
- package/ccw/src/commands/issue.ts +392 -149
- package/ccw/src/templates/dashboard-js/components/cli-status.js +1 -78
- package/ccw/src/templates/dashboard-js/i18n.js +0 -4
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +0 -18
- package/ccw/src/templates/dashboard-js/views/issue-manager.js +57 -26
- package/package.json +1 -1
- package/.claude/workflows/context-tools-ace.md +0 -105
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: execute
|
|
3
|
-
description: Execute queue with codex using
|
|
4
|
-
argument-hint: "[--parallel <n>] [--executor codex|gemini]"
|
|
3
|
+
description: Execute queue with codex using DAG-based parallel orchestration (solution-level)
|
|
4
|
+
argument-hint: "[--parallel <n>] [--executor codex|gemini|agent]"
|
|
5
5
|
allowed-tools: TodoWrite(*), Bash(*), Read(*), AskUserQuestion(*)
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -9,26 +9,14 @@ allowed-tools: TodoWrite(*), Bash(*), Read(*), AskUserQuestion(*)
|
|
|
9
9
|
|
|
10
10
|
## Overview
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Minimal orchestrator that dispatches **solution IDs** to executors. Each executor receives a complete solution with all its tasks.
|
|
13
13
|
|
|
14
|
-
**
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
## Storage Structure (Queue History)
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
.workflow/issues/
|
|
24
|
-
├── issues.jsonl # All issues (one per line)
|
|
25
|
-
├── queues/ # Queue history directory
|
|
26
|
-
│ ├── index.json # Queue index (active + history)
|
|
27
|
-
│ └── {queue-id}.json # Individual queue files
|
|
28
|
-
└── solutions/
|
|
29
|
-
├── {issue-id}.jsonl # Solutions for issue
|
|
30
|
-
└── ...
|
|
31
|
-
```
|
|
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**
|
|
32
20
|
|
|
33
21
|
## Usage
|
|
34
22
|
|
|
@@ -36,427 +24,271 @@ Execution orchestrator that coordinates codex instances. Each task is executed b
|
|
|
36
24
|
/issue:execute [FLAGS]
|
|
37
25
|
|
|
38
26
|
# Examples
|
|
39
|
-
/issue:execute # Execute
|
|
40
|
-
/issue:execute --parallel
|
|
41
|
-
/issue:execute --executor
|
|
27
|
+
/issue:execute # Execute with default parallelism
|
|
28
|
+
/issue:execute --parallel 4 # Execute up to 4 tasks in parallel
|
|
29
|
+
/issue:execute --executor agent # Use agent instead of codex
|
|
42
30
|
|
|
43
31
|
# Flags
|
|
44
|
-
--parallel <n> Max parallel
|
|
45
|
-
--executor <type> Force executor: codex|gemini|agent
|
|
46
|
-
--dry-run Show
|
|
32
|
+
--parallel <n> Max parallel executors (default: 3)
|
|
33
|
+
--executor <type> Force executor: codex|gemini|agent (default: codex)
|
|
34
|
+
--dry-run Show DAG and batches without executing
|
|
47
35
|
```
|
|
48
36
|
|
|
49
|
-
## Execution
|
|
37
|
+
## Execution Flow
|
|
50
38
|
|
|
51
39
|
```
|
|
52
|
-
Phase 1:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
├─
|
|
59
|
-
├─
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
│ ├─ Codex receives task data (NOT file)
|
|
67
|
-
│ ├─ Codex executes task
|
|
68
|
-
│ ├─ Codex calls: ccw issue complete <queue-id>
|
|
69
|
-
│ └─ Update TodoWrite
|
|
70
|
-
└─ Parallel execution based on --parallel flag
|
|
71
|
-
|
|
72
|
-
Phase 4: Completion
|
|
73
|
-
├─ Generate execution summary
|
|
74
|
-
├─ Update issue statuses in issues.jsonl
|
|
75
|
-
└─ Display results
|
|
40
|
+
Phase 1: Get DAG
|
|
41
|
+
└─ ccw issue queue dag → { parallel_batches: [["S-1","S-2"], ["S-3"]] }
|
|
42
|
+
|
|
43
|
+
Phase 2: Dispatch Parallel Batch
|
|
44
|
+
├─ For each solution ID in batch (parallel):
|
|
45
|
+
│ ├─ Executor calls: ccw issue detail <id> (READ-ONLY)
|
|
46
|
+
│ ├─ Executor gets FULL SOLUTION with all tasks
|
|
47
|
+
│ ├─ Executor implements all tasks sequentially (T1 → T2 → T3)
|
|
48
|
+
│ ├─ Executor tests + commits per task
|
|
49
|
+
│ └─ Executor calls: ccw issue done <id>
|
|
50
|
+
└─ Wait for batch completion
|
|
51
|
+
|
|
52
|
+
Phase 3: Next Batch
|
|
53
|
+
└─ ccw issue queue dag → check for newly-ready solutions
|
|
76
54
|
```
|
|
77
55
|
|
|
78
56
|
## Implementation
|
|
79
57
|
|
|
80
|
-
### Phase 1:
|
|
58
|
+
### Phase 1: Get DAG
|
|
81
59
|
|
|
82
60
|
```javascript
|
|
83
|
-
//
|
|
84
|
-
const
|
|
85
|
-
const
|
|
61
|
+
// Get dependency graph and parallel batches
|
|
62
|
+
const dagJson = Bash(`ccw issue queue dag`).trim();
|
|
63
|
+
const dag = JSON.parse(dagJson);
|
|
86
64
|
|
|
87
|
-
if (
|
|
88
|
-
console.log('No
|
|
65
|
+
if (dag.error || dag.ready_count === 0) {
|
|
66
|
+
console.log(dag.error || 'No solutions ready for execution');
|
|
67
|
+
console.log('Use /issue:queue to form a queue first');
|
|
89
68
|
return;
|
|
90
69
|
}
|
|
91
70
|
|
|
92
|
-
// Count by status
|
|
93
|
-
const pending = queue.tasks.filter(q => q.status === 'pending');
|
|
94
|
-
const executing = queue.tasks.filter(q => q.status === 'executing');
|
|
95
|
-
const completed = queue.tasks.filter(q => q.status === 'completed');
|
|
96
|
-
|
|
97
71
|
console.log(`
|
|
98
|
-
##
|
|
72
|
+
## Queue DAG (Solution-Level)
|
|
99
73
|
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
- Completed: ${
|
|
103
|
-
-
|
|
74
|
+
- Total Solutions: ${dag.total}
|
|
75
|
+
- Ready: ${dag.ready_count}
|
|
76
|
+
- Completed: ${dag.completed_count}
|
|
77
|
+
- Parallel in batch 1: ${dag.parallel_batches[0]?.length || 0}
|
|
104
78
|
`);
|
|
105
79
|
|
|
106
|
-
|
|
107
|
-
|
|
80
|
+
// Dry run mode
|
|
81
|
+
if (flags.dryRun) {
|
|
82
|
+
console.log('### Parallel Batches:\n');
|
|
83
|
+
dag.parallel_batches.forEach((batch, i) => {
|
|
84
|
+
console.log(`Batch ${i + 1}: ${batch.join(', ')}`);
|
|
85
|
+
});
|
|
108
86
|
return;
|
|
109
87
|
}
|
|
110
88
|
```
|
|
111
89
|
|
|
112
|
-
### Phase 2:
|
|
90
|
+
### Phase 2: Dispatch Parallel Batch
|
|
113
91
|
|
|
114
92
|
```javascript
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const completedIds = new Set(
|
|
118
|
-
queue.tasks.filter(q => q.status === 'completed').map(q => q.item_id)
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
return queue.tasks.filter(item => {
|
|
122
|
-
if (item.status !== 'pending') return false;
|
|
123
|
-
return item.depends_on.every(depId => completedIds.has(depId));
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const readyTasks = getReadyTasks();
|
|
128
|
-
|
|
129
|
-
if (readyTasks.length === 0) {
|
|
130
|
-
if (executing.length > 0) {
|
|
131
|
-
console.log('Tasks are currently executing. Wait for completion.');
|
|
132
|
-
} else {
|
|
133
|
-
console.log('No ready tasks. Check for blocked dependencies.');
|
|
134
|
-
}
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
console.log(`Found ${readyTasks.length} ready tasks`);
|
|
93
|
+
const parallelLimit = flags.parallel || 3;
|
|
94
|
+
const executor = flags.executor || 'codex';
|
|
139
95
|
|
|
140
|
-
//
|
|
141
|
-
|
|
96
|
+
// Process first batch (all solutions can run in parallel)
|
|
97
|
+
const batch = dag.parallel_batches[0] || [];
|
|
142
98
|
|
|
143
99
|
// Initialize TodoWrite
|
|
144
100
|
TodoWrite({
|
|
145
|
-
todos:
|
|
146
|
-
content: `
|
|
101
|
+
todos: batch.map(id => ({
|
|
102
|
+
content: `Execute solution ${id}`,
|
|
147
103
|
status: 'pending',
|
|
148
|
-
activeForm: `Executing ${
|
|
104
|
+
activeForm: `Executing solution ${id}`
|
|
149
105
|
}))
|
|
150
106
|
});
|
|
151
|
-
```
|
|
152
107
|
|
|
153
|
-
|
|
108
|
+
// Dispatch all in parallel (up to limit)
|
|
109
|
+
const chunks = [];
|
|
110
|
+
for (let i = 0; i < batch.length; i += parallelLimit) {
|
|
111
|
+
chunks.push(batch.slice(i, i + parallelLimit));
|
|
112
|
+
}
|
|
154
113
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
async function executeTask(queueItem) {
|
|
158
|
-
const codexPrompt = `
|
|
159
|
-
## Single Task Execution - CLOSED-LOOP LIFECYCLE
|
|
114
|
+
for (const chunk of chunks) {
|
|
115
|
+
console.log(`\n### Executing Solutions: ${chunk.join(', ')}`);
|
|
160
116
|
|
|
161
|
-
|
|
117
|
+
// Launch all in parallel
|
|
118
|
+
const executions = chunk.map(solutionId => {
|
|
119
|
+
updateTodo(solutionId, 'in_progress');
|
|
120
|
+
return dispatchExecutor(solutionId, executor);
|
|
121
|
+
});
|
|
162
122
|
|
|
163
|
-
|
|
164
|
-
|
|
123
|
+
await Promise.all(executions);
|
|
124
|
+
chunk.forEach(id => updateTodo(id, 'completed'));
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Executor Dispatch
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
function dispatchExecutor(solutionId, executorType) {
|
|
132
|
+
// Executor fetches FULL SOLUTION via READ-ONLY detail command
|
|
133
|
+
// Executor handles all tasks within solution sequentially
|
|
134
|
+
// Then reports completion via done command
|
|
135
|
+
const prompt = `
|
|
136
|
+
## Execute Solution ${solutionId}
|
|
137
|
+
|
|
138
|
+
### Step 1: Get Solution (read-only)
|
|
165
139
|
\`\`\`bash
|
|
166
|
-
ccw issue
|
|
140
|
+
ccw issue detail ${solutionId}
|
|
167
141
|
\`\`\`
|
|
168
142
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
**Phase 1: IMPLEMENT**
|
|
179
|
-
1. Follow task.implementation steps in order
|
|
180
|
-
2. Modify files specified in modification_points
|
|
181
|
-
3. Use context.relevant_files for reference
|
|
182
|
-
4. Use context.patterns for code style
|
|
183
|
-
|
|
184
|
-
**Phase 2: TEST**
|
|
185
|
-
1. Run test commands from task.test.commands
|
|
186
|
-
2. Ensure all unit tests pass (task.test.unit)
|
|
187
|
-
3. Run integration tests if specified (task.test.integration)
|
|
188
|
-
4. Verify coverage meets task.test.coverage_target if specified
|
|
189
|
-
5. If tests fail → fix code and re-run, do NOT proceed until tests pass
|
|
190
|
-
|
|
191
|
-
**Phase 3: REGRESSION**
|
|
192
|
-
1. Run all commands in task.regression
|
|
193
|
-
2. Ensure no existing tests are broken
|
|
194
|
-
3. If regression fails → fix and re-run
|
|
195
|
-
|
|
196
|
-
**Phase 4: ACCEPTANCE**
|
|
197
|
-
1. Verify each criterion in task.acceptance.criteria
|
|
198
|
-
2. Execute verification steps in task.acceptance.verification
|
|
199
|
-
3. Complete any manual_checks if specified
|
|
200
|
-
4. All criteria MUST pass before proceeding
|
|
201
|
-
|
|
202
|
-
**Phase 5: COMMIT**
|
|
203
|
-
1. Stage all modified files
|
|
204
|
-
2. Use task.commit.message_template as commit message
|
|
205
|
-
3. Commit with: git commit -m "$(cat <<'EOF'\n<message>\nEOF\n)"
|
|
206
|
-
4. If commit_strategy is 'per-task', commit now
|
|
207
|
-
5. If commit_strategy is 'atomic' or 'squash', stage but don't commit
|
|
143
|
+
### Step 2: Execute All Tasks Sequentially
|
|
144
|
+
The detail command returns a FULL SOLUTION with all tasks.
|
|
145
|
+
Execute each task in order (T1 → T2 → T3 → ...):
|
|
146
|
+
|
|
147
|
+
For each task:
|
|
148
|
+
1. Follow task.implementation steps
|
|
149
|
+
2. Run task.test commands
|
|
150
|
+
3. Verify task.acceptance criteria
|
|
151
|
+
4. Commit using task.commit specification
|
|
208
152
|
|
|
209
153
|
### Step 3: Report Completion
|
|
210
|
-
When ALL
|
|
154
|
+
When ALL tasks in solution are done:
|
|
211
155
|
\`\`\`bash
|
|
212
|
-
ccw issue
|
|
213
|
-
"files_modified": ["path1", "path2"],
|
|
214
|
-
"tests_passed": true,
|
|
215
|
-
"regression_passed": true,
|
|
216
|
-
"acceptance_passed": true,
|
|
217
|
-
"committed": true,
|
|
218
|
-
"commit_hash": "<hash>",
|
|
219
|
-
"summary": "What was done"
|
|
220
|
-
}'
|
|
156
|
+
ccw issue done ${solutionId} --result '{"summary": "...", "files_modified": [...], "tasks_completed": N}'
|
|
221
157
|
\`\`\`
|
|
222
158
|
|
|
223
|
-
If any
|
|
159
|
+
If any task failed:
|
|
224
160
|
\`\`\`bash
|
|
225
|
-
ccw issue
|
|
161
|
+
ccw issue done ${solutionId} --fail --reason "Task TX failed: ..."
|
|
226
162
|
\`\`\`
|
|
227
|
-
|
|
228
|
-
### Rules
|
|
229
|
-
- NEVER skip any lifecycle phase
|
|
230
|
-
- Tests MUST pass before proceeding to acceptance
|
|
231
|
-
- Regression MUST pass before commit
|
|
232
|
-
- ALL acceptance criteria MUST be verified
|
|
233
|
-
- Report accurate lifecycle status in result
|
|
234
|
-
|
|
235
|
-
### Start Now
|
|
236
|
-
Begin by running: ccw issue next
|
|
237
163
|
`;
|
|
238
164
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
Bash(
|
|
244
|
-
`ccw cli -p "${escapePrompt(codexPrompt)}" --tool codex --mode write --id exec-${queueItem.item_id}`,
|
|
245
|
-
timeout=3600000 // 1 hour timeout
|
|
165
|
+
if (executorType === 'codex') {
|
|
166
|
+
return Bash(
|
|
167
|
+
`ccw cli -p "${escapePrompt(prompt)}" --tool codex --mode write --id exec-${solutionId}`,
|
|
168
|
+
{ timeout: 7200000, run_in_background: true } // 2hr for full solution
|
|
246
169
|
);
|
|
247
|
-
} else if (
|
|
248
|
-
Bash(
|
|
249
|
-
`ccw cli -p "${escapePrompt(
|
|
250
|
-
timeout
|
|
170
|
+
} else if (executorType === 'gemini') {
|
|
171
|
+
return Bash(
|
|
172
|
+
`ccw cli -p "${escapePrompt(prompt)}" --tool gemini --mode write --id exec-${solutionId}`,
|
|
173
|
+
{ timeout: 3600000, run_in_background: true }
|
|
251
174
|
);
|
|
252
175
|
} else {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
prompt=codexPrompt
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Execute with parallelism
|
|
264
|
-
const parallelLimit = flags.parallel || 1;
|
|
265
|
-
|
|
266
|
-
for (let i = 0; i < readyTasks.length; i += parallelLimit) {
|
|
267
|
-
const batch = readyTasks.slice(i, i + parallelLimit);
|
|
268
|
-
|
|
269
|
-
console.log(`\n### Executing Batch ${Math.floor(i / parallelLimit) + 1}`);
|
|
270
|
-
console.log(batch.map(t => `- ${t.item_id}: ${t.issue_id}:${t.task_id}`).join('\n'));
|
|
271
|
-
|
|
272
|
-
if (parallelLimit === 1) {
|
|
273
|
-
// Sequential execution
|
|
274
|
-
for (const task of batch) {
|
|
275
|
-
updateTodo(task.item_id, 'in_progress');
|
|
276
|
-
await executeTask(task);
|
|
277
|
-
updateTodo(task.item_id, 'completed');
|
|
278
|
-
}
|
|
279
|
-
} else {
|
|
280
|
-
// Parallel execution - launch all at once
|
|
281
|
-
const executions = batch.map(task => {
|
|
282
|
-
updateTodo(task.item_id, 'in_progress');
|
|
283
|
-
return executeTask(task);
|
|
176
|
+
return Task({
|
|
177
|
+
subagent_type: 'code-developer',
|
|
178
|
+
run_in_background: false,
|
|
179
|
+
description: `Execute solution ${solutionId}`,
|
|
180
|
+
prompt: prompt
|
|
284
181
|
});
|
|
285
|
-
await Promise.all(executions);
|
|
286
|
-
batch.forEach(task => updateTodo(task.item_id, 'completed'));
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// Refresh ready tasks after batch
|
|
290
|
-
const newReady = getReadyTasks();
|
|
291
|
-
if (newReady.length > 0) {
|
|
292
|
-
console.log(`${newReady.length} more tasks now ready`);
|
|
293
182
|
}
|
|
294
183
|
}
|
|
295
184
|
```
|
|
296
185
|
|
|
297
|
-
###
|
|
298
|
-
|
|
299
|
-
When codex calls `ccw issue next`, it receives:
|
|
300
|
-
|
|
301
|
-
```json
|
|
302
|
-
{
|
|
303
|
-
"item_id": "T-1",
|
|
304
|
-
"issue_id": "GH-123",
|
|
305
|
-
"solution_id": "SOL-001",
|
|
306
|
-
"task": {
|
|
307
|
-
"id": "T1",
|
|
308
|
-
"title": "Create auth middleware",
|
|
309
|
-
"scope": "src/middleware/",
|
|
310
|
-
"action": "Create",
|
|
311
|
-
"description": "Create JWT validation middleware",
|
|
312
|
-
"modification_points": [
|
|
313
|
-
{ "file": "src/middleware/auth.ts", "target": "new file", "change": "Create middleware" }
|
|
314
|
-
],
|
|
315
|
-
"implementation": [
|
|
316
|
-
"Create auth.ts file in src/middleware/",
|
|
317
|
-
"Implement JWT token validation using jsonwebtoken",
|
|
318
|
-
"Add error handling for invalid/expired tokens",
|
|
319
|
-
"Export middleware function"
|
|
320
|
-
],
|
|
321
|
-
"acceptance": [
|
|
322
|
-
"Middleware validates JWT tokens successfully",
|
|
323
|
-
"Returns 401 for invalid or missing tokens",
|
|
324
|
-
"Passes token payload to request context"
|
|
325
|
-
]
|
|
326
|
-
},
|
|
327
|
-
"context": {
|
|
328
|
-
"relevant_files": ["src/config/auth.ts", "src/types/auth.d.ts"],
|
|
329
|
-
"patterns": "Follow existing middleware pattern in src/middleware/logger.ts"
|
|
330
|
-
},
|
|
331
|
-
"execution_hints": {
|
|
332
|
-
"executor": "codex",
|
|
333
|
-
"estimated_minutes": 30
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### Phase 4: Completion Summary
|
|
186
|
+
### Phase 3: Check Next Batch
|
|
339
187
|
|
|
340
188
|
```javascript
|
|
341
|
-
//
|
|
342
|
-
const
|
|
343
|
-
const finalQueue = JSON.parse(finalQueueJson);
|
|
344
|
-
|
|
345
|
-
// Use queue._metadata for summary (already calculated by CLI)
|
|
346
|
-
const summary = finalQueue._metadata || {
|
|
347
|
-
completed_count: 0,
|
|
348
|
-
failed_count: 0,
|
|
349
|
-
pending_count: 0,
|
|
350
|
-
total_tasks: 0
|
|
351
|
-
};
|
|
189
|
+
// Refresh DAG after batch completes
|
|
190
|
+
const refreshedDag = JSON.parse(Bash(`ccw issue queue dag`).trim());
|
|
352
191
|
|
|
353
192
|
console.log(`
|
|
354
|
-
##
|
|
355
|
-
|
|
356
|
-
**Completed**: ${summary.completed_count}/${summary.total_tasks}
|
|
357
|
-
**Failed**: ${summary.failed_count}
|
|
358
|
-
**Pending**: ${summary.pending_count}
|
|
359
|
-
|
|
360
|
-
### Task Results
|
|
361
|
-
${(finalQueue.tasks || []).map(q => {
|
|
362
|
-
const icon = q.status === 'completed' ? '✓' :
|
|
363
|
-
q.status === 'failed' ? '✗' :
|
|
364
|
-
q.status === 'executing' ? '⟳' : '○';
|
|
365
|
-
return `${icon} ${q.item_id} [${q.issue_id}:${q.task_id}] - ${q.status}`;
|
|
366
|
-
}).join('\n')}
|
|
367
|
-
`);
|
|
193
|
+
## Batch Complete
|
|
368
194
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
if (summary.pending_count > 0) {
|
|
373
|
-
console.log(`
|
|
374
|
-
### Continue Execution
|
|
375
|
-
Run \`/issue:execute\` again to execute remaining tasks.
|
|
195
|
+
- Solutions Completed: ${refreshedDag.completed_count}/${refreshedDag.total}
|
|
196
|
+
- Next ready: ${refreshedDag.ready_count}
|
|
376
197
|
`);
|
|
377
|
-
}
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
## Dry Run Mode
|
|
381
198
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
console.log(`
|
|
385
|
-
## Dry Run - Would Execute
|
|
386
|
-
|
|
387
|
-
${readyTasks.map((t, i) => `
|
|
388
|
-
${i + 1}. ${t.item_id}
|
|
389
|
-
Issue: ${t.issue_id}
|
|
390
|
-
Task: ${t.task_id}
|
|
391
|
-
Executor: ${t.assigned_executor}
|
|
392
|
-
Group: ${t.execution_group}
|
|
393
|
-
`).join('')}
|
|
394
|
-
|
|
395
|
-
No changes made. Remove --dry-run to execute.
|
|
396
|
-
`);
|
|
397
|
-
return;
|
|
199
|
+
if (refreshedDag.ready_count > 0) {
|
|
200
|
+
console.log('Run `/issue:execute` again for next batch.');
|
|
398
201
|
}
|
|
399
202
|
```
|
|
400
203
|
|
|
401
|
-
##
|
|
402
|
-
|
|
403
|
-
| Error | Resolution |
|
|
404
|
-
|-------|------------|
|
|
405
|
-
| Queue not found | Display message, suggest /issue:queue |
|
|
406
|
-
| No ready tasks | Check dependencies, show blocked tasks |
|
|
407
|
-
| Codex timeout | Mark as failed, allow retry |
|
|
408
|
-
| ccw issue next empty | All tasks done or blocked |
|
|
409
|
-
| Task execution failure | Marked via ccw issue fail, use `ccw issue retry` to reset |
|
|
410
|
-
|
|
411
|
-
## Troubleshooting
|
|
412
|
-
|
|
413
|
-
### Interrupted Tasks
|
|
414
|
-
|
|
415
|
-
If execution was interrupted (crashed/stopped), `ccw issue next` will automatically resume:
|
|
204
|
+
## Parallel Execution Model
|
|
416
205
|
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
|
|
206
|
+
```
|
|
207
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
208
|
+
│ Orchestrator │
|
|
209
|
+
├─────────────────────────────────────────────────────────────┤
|
|
210
|
+
│ 1. ccw issue queue dag │
|
|
211
|
+
│ → { parallel_batches: [["S-1","S-2"], ["S-3"]] } │
|
|
212
|
+
│ │
|
|
213
|
+
│ 2. Dispatch batch 1 (parallel): │
|
|
214
|
+
│ ┌──────────────────────┐ ┌──────────────────────┐ │
|
|
215
|
+
│ │ Executor 1 │ │ Executor 2 │ │
|
|
216
|
+
│ │ detail S-1 │ │ detail S-2 │ │
|
|
217
|
+
│ │ → gets full solution │ │ → gets full solution │ │
|
|
218
|
+
│ │ [T1→T2→T3 sequential]│ │ [T1→T2 sequential] │ │
|
|
219
|
+
│ │ done S-1 │ │ done S-2 │ │
|
|
220
|
+
│ └──────────────────────┘ └──────────────────────┘ │
|
|
221
|
+
│ │
|
|
222
|
+
│ 3. ccw issue queue dag (refresh) │
|
|
223
|
+
│ → S-3 now ready (S-1 completed, file conflict resolved) │
|
|
224
|
+
└─────────────────────────────────────────────────────────────┘
|
|
420
225
|
```
|
|
421
226
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
227
|
+
**Why this works for parallel:**
|
|
228
|
+
- `detail <id>` is READ-ONLY → no race conditions
|
|
229
|
+
- Each executor handles **all tasks within a solution** sequentially
|
|
230
|
+
- `done <id>` updates only its own solution status
|
|
231
|
+
- `queue dag` recalculates ready solutions after each batch
|
|
232
|
+
- Solutions in same batch have NO file conflicts
|
|
427
233
|
|
|
428
|
-
|
|
429
|
-
# Reset all failed tasks to pending
|
|
430
|
-
ccw issue retry
|
|
234
|
+
## CLI Endpoint Contract
|
|
431
235
|
|
|
432
|
-
|
|
433
|
-
|
|
236
|
+
### `ccw issue queue dag`
|
|
237
|
+
Returns dependency graph with parallel batches (solution-level):
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"queue_id": "QUE-...",
|
|
241
|
+
"total": 3,
|
|
242
|
+
"ready_count": 2,
|
|
243
|
+
"completed_count": 0,
|
|
244
|
+
"nodes": [
|
|
245
|
+
{ "id": "S-1", "issue_id": "ISS-xxx", "status": "pending", "ready": true, "task_count": 3 },
|
|
246
|
+
{ "id": "S-2", "issue_id": "ISS-yyy", "status": "pending", "ready": true, "task_count": 2 },
|
|
247
|
+
{ "id": "S-3", "issue_id": "ISS-zzz", "status": "pending", "ready": false, "depends_on": ["S-1"] }
|
|
248
|
+
],
|
|
249
|
+
"parallel_batches": [["S-1", "S-2"], ["S-3"]]
|
|
250
|
+
}
|
|
434
251
|
```
|
|
435
252
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
-
|
|
441
|
-
|
|
253
|
+
### `ccw issue detail <item_id>`
|
|
254
|
+
Returns FULL SOLUTION with all tasks (READ-ONLY):
|
|
255
|
+
```json
|
|
256
|
+
{
|
|
257
|
+
"item_id": "S-1",
|
|
258
|
+
"issue_id": "ISS-xxx",
|
|
259
|
+
"solution_id": "SOL-xxx",
|
|
260
|
+
"status": "pending",
|
|
261
|
+
"solution": {
|
|
262
|
+
"id": "SOL-xxx",
|
|
263
|
+
"approach": "...",
|
|
264
|
+
"tasks": [
|
|
265
|
+
{ "id": "T1", "title": "...", "implementation": [...], "test": {...} },
|
|
266
|
+
{ "id": "T2", "title": "...", "implementation": [...], "test": {...} },
|
|
267
|
+
{ "id": "T3", "title": "...", "implementation": [...], "test": {...} }
|
|
268
|
+
],
|
|
269
|
+
"exploration_context": { "relevant_files": [...] }
|
|
270
|
+
},
|
|
271
|
+
"execution_hints": { "executor": "codex", "estimated_minutes": 180 }
|
|
272
|
+
}
|
|
273
|
+
```
|
|
442
274
|
|
|
443
|
-
### `ccw issue
|
|
444
|
-
|
|
445
|
-
- Updates queue.json
|
|
446
|
-
- Checks if issue is fully complete
|
|
275
|
+
### `ccw issue done <item_id>`
|
|
276
|
+
Marks solution completed/failed, updates queue state, checks for queue completion.
|
|
447
277
|
|
|
448
|
-
|
|
449
|
-
- Marks task as 'failed'
|
|
450
|
-
- Records failure reason
|
|
451
|
-
- Allows retry via /issue:execute
|
|
278
|
+
## Error Handling
|
|
452
279
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
280
|
+
| Error | Resolution |
|
|
281
|
+
|-------|------------|
|
|
282
|
+
| No queue | Run /issue:queue first |
|
|
283
|
+
| No ready solutions | Dependencies blocked, check DAG |
|
|
284
|
+
| Executor timeout | Solution not marked done, can retry |
|
|
285
|
+
| Solution failure | Use `ccw issue retry` to reset |
|
|
286
|
+
| Partial task failure | Executor reports which task failed via `done --fail` |
|
|
456
287
|
|
|
457
288
|
## Related Commands
|
|
458
289
|
|
|
459
290
|
- `/issue:plan` - Plan issues with solutions
|
|
460
291
|
- `/issue:queue` - Form execution queue
|
|
461
|
-
- `ccw issue queue
|
|
462
|
-
- `ccw issue
|
|
292
|
+
- `ccw issue queue dag` - View dependency graph
|
|
293
|
+
- `ccw issue detail <id>` - View task details
|
|
294
|
+
- `ccw issue retry` - Reset failed tasks
|