claude-code-workflow 6.3.12 → 6.3.15

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 (72) hide show
  1. package/.claude/agents/issue-plan-agent.md +62 -36
  2. package/.claude/agents/issue-queue-agent.md +110 -57
  3. package/.claude/commands/issue/execute.md +53 -40
  4. package/.claude/commands/issue/new.md +226 -380
  5. package/.claude/commands/issue/plan.md +122 -125
  6. package/.claude/commands/issue/queue.md +198 -321
  7. package/.claude/skills/issue-manage/SKILL.md +63 -22
  8. package/.claude/workflows/cli-templates/schemas/discovery-finding-schema.json +3 -3
  9. package/.claude/workflows/cli-templates/schemas/issues-jsonl-schema.json +141 -168
  10. package/.claude/workflows/cli-templates/schemas/queue-schema.json +0 -5
  11. package/.claude/workflows/cli-templates/schemas/solution-schema.json +3 -2
  12. package/.codex/prompts/issue-execute.md +3 -3
  13. package/.codex/prompts/issue-plan.md +16 -19
  14. package/.codex/prompts/issue-queue.md +3 -4
  15. package/README.md +1 -0
  16. package/ccw/dist/cli.d.ts.map +1 -1
  17. package/ccw/dist/cli.js +3 -1
  18. package/ccw/dist/cli.js.map +1 -1
  19. package/ccw/dist/commands/cli.d.ts.map +1 -1
  20. package/ccw/dist/commands/cli.js +45 -3
  21. package/ccw/dist/commands/cli.js.map +1 -1
  22. package/ccw/dist/commands/issue.d.ts +3 -1
  23. package/ccw/dist/commands/issue.d.ts.map +1 -1
  24. package/ccw/dist/commands/issue.js +383 -30
  25. package/ccw/dist/commands/issue.js.map +1 -1
  26. package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
  27. package/ccw/dist/core/routes/issue-routes.js +77 -16
  28. package/ccw/dist/core/routes/issue-routes.js.map +1 -1
  29. package/ccw/dist/tools/cli-executor.d.ts.map +1 -1
  30. package/ccw/dist/tools/cli-executor.js +117 -4
  31. package/ccw/dist/tools/cli-executor.js.map +1 -1
  32. package/ccw/dist/tools/litellm-executor.d.ts +4 -0
  33. package/ccw/dist/tools/litellm-executor.d.ts.map +1 -1
  34. package/ccw/dist/tools/litellm-executor.js +54 -1
  35. package/ccw/dist/tools/litellm-executor.js.map +1 -1
  36. package/ccw/dist/tools/ui-generate-preview.d.ts +18 -0
  37. package/ccw/dist/tools/ui-generate-preview.d.ts.map +1 -1
  38. package/ccw/dist/tools/ui-generate-preview.js +26 -10
  39. package/ccw/dist/tools/ui-generate-preview.js.map +1 -1
  40. package/ccw/src/cli.ts +3 -1
  41. package/ccw/src/commands/cli.ts +47 -3
  42. package/ccw/src/commands/issue.ts +442 -34
  43. package/ccw/src/core/routes/issue-routes.ts +82 -16
  44. package/ccw/src/tools/cli-executor.ts +125 -4
  45. package/ccw/src/tools/litellm-executor.ts +107 -24
  46. package/ccw/src/tools/ui-generate-preview.js +60 -37
  47. package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
  48. package/codex-lens/src/codexlens/__pycache__/entities.cpython-313.pyc +0 -0
  49. package/codex-lens/src/codexlens/config.py +25 -2
  50. package/codex-lens/src/codexlens/entities.py +5 -1
  51. package/codex-lens/src/codexlens/indexing/__pycache__/symbol_extractor.cpython-313.pyc +0 -0
  52. package/codex-lens/src/codexlens/indexing/symbol_extractor.py +243 -243
  53. package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-313.pyc +0 -0
  54. package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-313.pyc +0 -0
  55. package/codex-lens/src/codexlens/parsers/factory.py +256 -256
  56. package/codex-lens/src/codexlens/parsers/treesitter_parser.py +335 -335
  57. package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
  58. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
  59. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
  60. package/codex-lens/src/codexlens/search/chain_search.py +30 -1
  61. package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-313.pyc +0 -0
  62. package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-313.pyc +0 -0
  63. package/codex-lens/src/codexlens/semantic/__pycache__/reranker.cpython-313.pyc +0 -0
  64. package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
  65. package/codex-lens/src/codexlens/semantic/embedder.py +6 -9
  66. package/codex-lens/src/codexlens/semantic/vector_store.py +271 -200
  67. package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-313.pyc +0 -0
  68. package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-313.pyc +0 -0
  69. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-313.pyc +0 -0
  70. package/codex-lens/src/codexlens/storage/sqlite_store.py +184 -108
  71. package/package.json +88 -83
  72. package/.claude/commands/issue/manage.md +0 -113
@@ -13,135 +13,38 @@ Queue formation command using **issue-queue-agent** that analyzes all bound solu
13
13
 
14
14
  **Design Principle**: Queue items are **solutions**, not individual tasks. Each executor receives a complete solution with all its tasks.
15
15
 
16
- ## Output Requirements
17
-
18
- **Generate Files:**
19
- 1. `.workflow/issues/queues/{queue-id}.json` - Full queue with solutions, conflicts, groups
20
- 2. `.workflow/issues/queues/index.json` - Update with new queue entry
21
-
22
- **Return Summary:**
23
- ```json
24
- {
25
- "queue_id": "QUE-20251227-143000",
26
- "total_solutions": N,
27
- "total_tasks": N,
28
- "execution_groups": [{ "id": "P1", "type": "parallel", "count": N }],
29
- "conflicts_resolved": N,
30
- "issues_queued": ["ISS-xxx", "ISS-yyy"]
31
- }
32
- ```
33
-
34
- **Completion Criteria:**
35
- - [ ] Queue JSON generated with valid DAG (no cycles between solutions)
36
- - [ ] All inter-solution file conflicts resolved with rationale
37
- - [ ] Semantic priority calculated for each solution
38
- - [ ] Execution groups assigned (parallel P* / sequential S*)
39
- - [ ] Issue statuses updated to `queued` via `ccw issue update`
40
-
41
16
  ## Core Capabilities
42
17
 
43
18
  - **Agent-driven**: issue-queue-agent handles all ordering logic
44
19
  - **Solution-level granularity**: Queue items are solutions, not tasks
45
- - Inter-solution dependency DAG (based on file conflicts)
46
- - File conflict detection between solutions
20
+ - **Conflict clarification**: High-severity conflicts prompt user decision
47
21
  - Semantic priority calculation per solution (0.0-1.0)
48
22
  - Parallel/Sequential group assignment for solutions
49
23
 
50
- ## Storage Structure (Queue History)
24
+ ## Core Guidelines
51
25
 
52
- ```
53
- .workflow/issues/
54
- ├── issues.jsonl # All issues (one per line)
55
- ├── queues/ # Queue history directory
56
- │ ├── index.json # Queue index (active + history)
57
- │ ├── {queue-id}.json # Individual queue files
58
- │ └── ...
59
- └── solutions/
60
- ├── {issue-id}.jsonl # Solutions for issue
61
- └── ...
62
- ```
26
+ **⚠️ Data Access Principle**: Issues and queue files can grow very large. To avoid context overflow:
63
27
 
64
- ### Queue Index Schema
28
+ | Operation | Correct | Incorrect |
29
+ |-----------|---------|-----------|
30
+ | List issues (brief) | `ccw issue list --status planned --brief` | `Read('issues.jsonl')` |
31
+ | List queue (brief) | `ccw issue queue --brief` | `Read('queues/*.json')` |
32
+ | Read issue details | `ccw issue status <id> --json` | `Read('issues.jsonl')` |
33
+ | Get next item | `ccw issue next --json` | `Read('queues/*.json')` |
34
+ | Update status | `ccw issue update <id> --status ...` | Direct file edit |
35
+ | Sync from queue | `ccw issue update --from-queue` | Direct file edit |
65
36
 
66
- ```json
67
- {
68
- "active_queue_id": "QUE-20251227-143000",
69
- "queues": [
70
- {
71
- "id": "QUE-20251227-143000",
72
- "status": "active",
73
- "issue_ids": ["ISS-xxx", "ISS-yyy"],
74
- "total_solutions": 3,
75
- "completed_solutions": 1,
76
- "created_at": "2025-12-27T14:30:00Z"
77
- }
78
- ]
79
- }
80
- ```
37
+ **Output Options**:
38
+ - `--brief`: JSON with minimal fields (id, status, counts)
39
+ - `--json`: Full JSON (agent use only)
40
+
41
+ **Orchestration vs Execution**:
42
+ - **Command (orchestrator)**: Use `--brief` for minimal context
43
+ - **Agent (executor)**: Fetch full details → `ccw issue status <id> --json`
44
+
45
+ **ALWAYS** use CLI commands for CRUD operations. **NEVER** read entire `issues.jsonl` or `queues/*.json` directly.
81
46
 
82
- ### Queue File Schema (Solution-Level)
83
47
 
84
- ```json
85
- {
86
- "id": "QUE-20251227-143000",
87
- "status": "active",
88
- "solutions": [
89
- {
90
- "item_id": "S-1",
91
- "issue_id": "ISS-20251227-003",
92
- "solution_id": "SOL-20251227-003",
93
- "status": "pending",
94
- "execution_order": 1,
95
- "execution_group": "P1",
96
- "depends_on": [],
97
- "semantic_priority": 0.8,
98
- "assigned_executor": "codex",
99
- "files_touched": ["src/auth.ts", "src/utils.ts"],
100
- "task_count": 3
101
- },
102
- {
103
- "item_id": "S-2",
104
- "issue_id": "ISS-20251227-001",
105
- "solution_id": "SOL-20251227-001",
106
- "status": "pending",
107
- "execution_order": 2,
108
- "execution_group": "P1",
109
- "depends_on": [],
110
- "semantic_priority": 0.7,
111
- "assigned_executor": "codex",
112
- "files_touched": ["src/api.ts"],
113
- "task_count": 2
114
- },
115
- {
116
- "item_id": "S-3",
117
- "issue_id": "ISS-20251227-002",
118
- "solution_id": "SOL-20251227-002",
119
- "status": "pending",
120
- "execution_order": 3,
121
- "execution_group": "S2",
122
- "depends_on": ["S-1"],
123
- "semantic_priority": 0.5,
124
- "assigned_executor": "codex",
125
- "files_touched": ["src/auth.ts"],
126
- "task_count": 4
127
- }
128
- ],
129
- "conflicts": [
130
- {
131
- "type": "file_conflict",
132
- "file": "src/auth.ts",
133
- "solutions": ["S-1", "S-3"],
134
- "resolution": "sequential",
135
- "resolution_order": ["S-1", "S-3"],
136
- "rationale": "S-1 creates auth module, S-3 extends it"
137
- }
138
- ],
139
- "execution_groups": [
140
- { "id": "P1", "type": "parallel", "solutions": ["S-1", "S-2"] },
141
- { "id": "S2", "type": "sequential", "solutions": ["S-3"] }
142
- ]
143
- }
144
- ```
145
48
 
146
49
  ## Usage
147
50
 
@@ -171,280 +74,254 @@ ccw issue queue delete <queue-id> Delete queue from history
171
74
 
172
75
  ```
173
76
  Phase 1: Solution Loading
174
- ├─ Load issues.jsonl
175
- ├─ Filter issues with bound_solution_id
176
- ├─ Read solutions/{issue-id}.jsonl for each issue
177
- ├─ Find bound solution by ID
178
- ├─ Collect files_touched from all tasks in solution
179
- └─ Build solution objects (NOT individual tasks)
77
+ ├─ Load issues.jsonl, filter by status='planned' + bound_solution_id
78
+ ├─ Read solutions/{issue-id}.jsonl, find bound solution
79
+ ├─ Extract files_touched from task modification_points
80
+ └─ Build solution objects array
180
81
 
181
82
  Phase 2-4: Agent-Driven Queue Formation (issue-queue-agent)
182
- ├─ Launch issue-queue-agent with all solutions
83
+ ├─ Launch issue-queue-agent with solutions array
183
84
  ├─ Agent performs:
184
- │ ├─ Detect file overlaps between solutions
185
- │ ├─ Build dependency DAG from file conflicts
186
- │ ├─ Detect circular dependencies
187
- │ ├─ Resolve conflicts using priority rules
85
+ │ ├─ Conflict analysis (5 types via Gemini CLI)
86
+ │ ├─ Build dependency DAG from conflicts
188
87
  │ ├─ Calculate semantic priority per solution
189
88
  │ └─ Assign execution groups (parallel/sequential)
190
- └─ Output: queue JSON with ordered solutions (S-1, S-2, ...)
89
+ └─ Agent writes: queue JSON + index update
90
+
91
+ Phase 5: Conflict Clarification (if needed)
92
+ ├─ Check agent return for `clarifications` array
93
+ ├─ If clarifications exist → AskUserQuestion
94
+ ├─ Pass user decisions back to agent (resume)
95
+ └─ Agent updates queue with resolved conflicts
191
96
 
192
- Phase 5: Queue Output
193
- ├─ Write queue.json with solutions array
194
- ├─ Update issue statuses in issues.jsonl
195
- └─ Display queue summary
97
+ Phase 6: Status Update & Summary
98
+ ├─ Update issue statuses to 'queued'
99
+ └─ Display queue summary, next step: /issue:execute
196
100
  ```
197
101
 
198
102
  ## Implementation
199
103
 
200
104
  ### Phase 1: Solution Loading
201
105
 
202
- **NOTE**: Execute code directly. DO NOT pre-read solution files - Bash cat handles all reading.
106
+ **Data Loading:**
107
+ - Load `issues.jsonl` and filter issues with `status === 'planned'` and `bound_solution_id`
108
+ - If no planned issues found → display message, suggest `/issue:plan`
203
109
 
204
- ```javascript
205
- // Load issues.jsonl
206
- const issuesPath = '.workflow/issues/issues.jsonl';
207
- const allIssues = Bash(`cat "${issuesPath}" 2>/dev/null || echo ''`)
208
- .split('\n')
209
- .filter(line => line.trim())
210
- .map(line => JSON.parse(line));
211
-
212
- // Filter issues with bound solutions
213
- const plannedIssues = allIssues.filter(i =>
214
- i.status === 'planned' && i.bound_solution_id
215
- );
110
+ **Solution Collection** (for each planned issue):
111
+ - Read `solutions/{issue-id}.jsonl`
112
+ - Find bound solution by `bound_solution_id`
113
+ - If bound solution not found warn and skip issue
114
+ - Extract `files_touched` from all task `modification_points`
216
115
 
217
- if (plannedIssues.length === 0) {
218
- console.log('No issues with bound solutions found.');
219
- console.log('Run /issue:plan first to create and bind solutions.');
220
- return;
116
+ **Build Solution Objects:**
117
+ ```json
118
+ {
119
+ "issue_id": "ISS-xxx",
120
+ "solution_id": "SOL-ISS-xxx-1",
121
+ "task_count": 3,
122
+ "files_touched": ["src/auth.ts", "src/utils.ts"],
123
+ "priority": "medium"
221
124
  }
125
+ ```
222
126
 
223
- // Load bound solutions (not individual tasks)
224
- const allSolutions = [];
225
- for (const issue of plannedIssues) {
226
- const solPath = `.workflow/issues/solutions/${issue.id}.jsonl`;
227
- const solutions = Bash(`cat "${solPath}" 2>/dev/null || echo ''`)
228
- .split('\n')
229
- .filter(line => line.trim())
230
- .map(line => JSON.parse(line));
231
-
232
- // Find bound solution
233
- const boundSol = solutions.find(s => s.id === issue.bound_solution_id);
234
-
235
- if (!boundSol) {
236
- console.log(`⚠ Bound solution ${issue.bound_solution_id} not found for ${issue.id}`);
237
- continue;
238
- }
127
+ **Output:** Array of solution objects ready for agent processing
239
128
 
240
- // Collect all files touched by this solution
241
- const filesTouched = new Set();
242
- for (const task of boundSol.tasks || []) {
243
- for (const mp of task.modification_points || []) {
244
- filesTouched.add(mp.file);
245
- }
246
- }
129
+ ### Phase 2-4: Agent-Driven Queue Formation
247
130
 
248
- allSolutions.push({
249
- issue_id: issue.id,
250
- solution_id: issue.bound_solution_id,
251
- task_count: boundSol.tasks?.length || 0,
252
- files_touched: Array.from(filesTouched),
253
- priority: issue.priority || 'medium'
254
- });
255
- }
131
+ **Generate Queue ID** (command layer, pass to agent):
132
+ ```javascript
133
+ const queueId = `QUE-${new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)}`;
134
+ ```
256
135
 
257
- console.log(`Loaded ${allSolutions.length} solutions from ${plannedIssues.length} issues`);
136
+ **Agent Prompt**:
258
137
  ```
138
+ ## Order Solutions into Execution Queue
259
139
 
260
- ### Phase 2-4: Agent-Driven Queue Formation
140
+ **Queue ID**: ${queueId}
141
+ **Solutions**: ${solutions.length} from ${issues.length} issues
142
+ **Project Root**: ${cwd}
261
143
 
262
- ```javascript
263
- // Generate queue-id ONCE here, pass to agent
264
- const now = new Date();
265
- const queueId = `QUE-${now.toISOString().replace(/[-:T]/g, '').slice(0, 14)}`;
144
+ ### Input
145
+ ${JSON.stringify(solutions)}
266
146
 
267
- // Build minimal prompt - agent orders SOLUTIONS, not tasks
268
- const agentPrompt = `
269
- ## Order Solutions
147
+ ### Workflow
270
148
 
271
- **Queue ID**: ${queueId}
272
- **Solutions**: ${allSolutions.length} from ${plannedIssues.length} issues
273
- **Project Root**: ${process.cwd()}
149
+ Step 1: Build dependency graph from solutions (nodes=solutions, edges=file conflicts)
150
+ Step 2: Use Gemini CLI for conflict analysis (5 types: file, API, data, dependency, architecture)
151
+ Step 3: For high-severity conflicts without clear resolution → add to `clarifications`
152
+ Step 4: Calculate semantic priority (base from issue priority + task_count boost)
153
+ Step 5: Assign execution groups: P* (parallel, no overlaps) / S* (sequential, shared files)
154
+ Step 6: Write queue JSON + update index
274
155
 
275
- ### Input (Solution-Level)
276
- \`\`\`json
277
- ${JSON.stringify(allSolutions, null, 2)}
278
- \`\`\`
156
+ ### Output Requirements
279
157
 
280
- ### Steps
281
- 1. Parse solutions: Extract solution IDs, files_touched, task_count, priority
282
- 2. Detect conflicts: Find file overlaps between solutions (files_touched intersection)
283
- 3. Build DAG: Create dependency edges where solutions share files
284
- 4. Detect cycles: Verify no circular dependencies (abort if found)
285
- 5. Resolve conflicts: Apply ordering rules based on action types
286
- 6. Calculate priority: Compute semantic priority (0.0-1.0) per solution
287
- 7. Assign groups: Parallel (P*) for no-conflict, Sequential (S*) for conflicts
288
- 8. Generate queue: Write queue JSON with ordered solutions
289
- 9. Update index: Update queues/index.json with new queue entry
158
+ **Write files** (exactly 2):
159
+ - `.workflow/issues/queues/${queueId}.json` - Full queue with solutions, conflicts, groups
160
+ - `.workflow/issues/queues/index.json` - Update with new queue entry
290
161
 
291
- ### Rules
292
- - **Solution Granularity**: Queue items are solutions, NOT individual tasks
293
- - **DAG Validity**: Output must be valid DAG with no circular dependencies
294
- - **Conflict Detection**: Two solutions conflict if files_touched intersect
295
- - **Ordering Priority**:
296
- 1. Higher issue priority first (critical > high > medium > low)
297
- 2. Fewer dependencies first (foundation solutions)
298
- 3. More tasks = higher priority (larger impact)
299
- - **Parallel Safety**: Solutions in same parallel group must have NO file overlaps
300
- - **Queue Item ID Format**: \`S-N\` (S-1, S-2, S-3, ...)
301
- - **Queue ID**: Use the provided Queue ID (passed above), do NOT generate new one
302
-
303
- ### Generate Files (STRICT - only these 2)
304
- 1. \`.workflow/issues/queues/{Queue ID}.json\` - Use Queue ID from above
305
- 2. \`.workflow/issues/queues/index.json\` - Update existing index
306
-
307
- Write ONLY these 2 files, using the provided Queue ID.
308
-
309
- ### Return Summary
162
+ **Return JSON**:
310
163
  \`\`\`json
311
164
  {
312
- "queue_id": "QUE-YYYYMMDD-HHMMSS",
165
+ "queue_id": "${queueId}",
313
166
  "total_solutions": N,
314
167
  "total_tasks": N,
315
- "execution_groups": [{ "id": "P1", "type": "parallel", "count": N }],
316
- "conflicts_resolved": N,
317
- "issues_queued": ["ISS-xxx"]
168
+ "execution_groups": [{"id": "P1", "type": "parallel", "count": N}],
169
+ "issues_queued": ["ISS-xxx"],
170
+ "clarifications": [{"conflict_id": "CFT-1", "question": "...", "options": [...]}]
318
171
  }
319
172
  \`\`\`
320
- `;
321
173
 
174
+ ### Rules
175
+ - Solution granularity (NOT individual tasks)
176
+ - Queue Item ID format: S-1, S-2, S-3, ...
177
+ - Use provided Queue ID (do NOT generate new)
178
+ - `clarifications` only present if high-severity unresolved conflicts exist
179
+
180
+ ### Done Criteria
181
+ - [ ] Queue JSON written with all solutions ordered
182
+ - [ ] Index updated with active_queue_id
183
+ - [ ] No circular dependencies
184
+ - [ ] Parallel groups have no file overlaps
185
+ - [ ] Return JSON matches required shape
186
+ ```
187
+
188
+ **Launch Agent**:
189
+ ```javascript
322
190
  const result = Task(
323
191
  subagent_type="issue-queue-agent",
324
- run_in_background=false,
325
- description=`Order ${allSolutions.length} solutions`,
326
- prompt=agentPrompt
192
+ prompt=agentPrompt,
193
+ description=`Order ${solutions.length} solutions`
327
194
  );
328
-
329
- const summary = JSON.parse(result);
330
195
  ```
331
196
 
332
- ### Phase 5: Validation & Status Update
197
+ ### Phase 5: Conflict Clarification
198
+
199
+ **Check Agent Return:**
200
+ - Parse agent result JSON
201
+ - If `clarifications` array exists and non-empty → user decision required
333
202
 
203
+ **Clarification Flow:**
334
204
  ```javascript
335
- // ============ VALIDATION: Prevent "next returns empty" issues ============
336
-
337
- const queuesDir = '.workflow/issues/queues';
338
- const indexPath = `${queuesDir}/index.json`;
339
- const queuePath = `${queuesDir}/${queueId}.json`;
340
-
341
- // 1. Validate index.json has active_queue_id
342
- const indexContent = Bash(`cat "${indexPath}" 2>/dev/null || echo '{}'`);
343
- const index = JSON.parse(indexContent);
344
-
345
- if (index.active_queue_id !== queueId) {
346
- console.log(`⚠ Fixing: index.json active_queue_id not set to ${queueId}`);
347
- index.active_queue_id = queueId;
348
- // Ensure queue entry exists in index
349
- if (!index.queues) index.queues = [];
350
- const existing = index.queues.find(q => q.id === queueId);
351
- if (!existing) {
352
- index.queues.unshift({
353
- id: queueId,
354
- status: 'active',
355
- issue_ids: summary.issues_queued,
356
- total_solutions: summary.total_solutions,
357
- completed_solutions: 0,
358
- created_at: new Date().toISOString()
205
+ if (result.clarifications?.length > 0) {
206
+ for (const clarification of result.clarifications) {
207
+ // Present to user via AskUserQuestion
208
+ const answer = AskUserQuestion({
209
+ questions: [{
210
+ question: clarification.question,
211
+ header: clarification.conflict_id,
212
+ options: clarification.options,
213
+ multiSelect: false
214
+ }]
359
215
  });
216
+
217
+ // Resume agent with user decision
218
+ Task(
219
+ subagent_type="issue-queue-agent",
220
+ resume=agentId,
221
+ prompt=`Conflict ${clarification.conflict_id} resolved: ${answer.selected}`
222
+ );
360
223
  }
361
- Bash(`echo '${JSON.stringify(index, null, 2)}' > "${indexPath}"`);
362
- console.log(`✓ Fixed: index.json updated with active_queue_id: ${queueId}`);
363
224
  }
225
+ ```
364
226
 
365
- // 2. Validate queue file exists and has correct structure
366
- const queueContent = Bash(`cat "${queuePath}" 2>/dev/null || echo '{}'`);
367
- const queue = JSON.parse(queueContent);
227
+ ### Phase 6: Status Update & Summary
368
228
 
369
- if (!queue.solutions || queue.solutions.length === 0) {
370
- console.error(`✗ ERROR: Queue file ${queuePath} has no solutions array`);
371
- console.error(' Agent did not generate queue correctly. Aborting.');
372
- return;
373
- }
229
+ **Status Update** (MUST use CLI command, NOT direct file operations):
374
230
 
375
- // 3. Validate all solutions have status: "pending" (not "queued" or other)
376
- let statusFixed = 0;
377
- for (const sol of queue.solutions) {
378
- if (sol.status !== 'pending' && sol.status !== 'executing' && sol.status !== 'completed') {
379
- console.log(`⚠ Fixing: ${sol.item_id} status "${sol.status}" "pending"`);
380
- sol.status = 'pending';
381
- statusFixed++;
382
- }
383
- }
231
+ ```bash
232
+ # Option 1: Batch update from queue (recommended)
233
+ ccw issue update --from-queue [queue-id] --json
234
+ ccw issue update --from-queue --json # Use active queue
235
+ ccw issue update --from-queue QUE-xxx --json # Use specific queue
384
236
 
385
- // 4. Validate at least one item has no dependencies (DAG entry point)
386
- const entryPoints = queue.solutions.filter(s =>
387
- s.status === 'pending' && (!s.depends_on || s.depends_on.length === 0)
388
- );
237
+ # Option 2: Individual issue update
238
+ ccw issue update <issue-id> --status queued
239
+ ```
389
240
 
390
- if (entryPoints.length === 0) {
391
- console.error(`✗ ERROR: No entry points found (all items have dependencies)`);
392
- console.error(' This will cause "ccw issue next" to return empty.');
393
- console.error(' Check depends_on fields for circular dependencies.');
394
- // Try to fix by clearing first item's dependencies
395
- if (queue.solutions.length > 0) {
396
- console.log(`⚠ Fixing: Clearing depends_on for first item ${queue.solutions[0].item_id}`);
397
- queue.solutions[0].depends_on = [];
398
- }
399
- }
241
+ **⚠️ IMPORTANT**: Do NOT directly modify `issues.jsonl`. Always use CLI command to ensure proper validation and history tracking.
400
242
 
401
- // Write back fixed queue if any changes made
402
- if (statusFixed > 0 || entryPoints.length === 0) {
403
- Bash(`echo '${JSON.stringify(queue, null, 2)}' > "${queuePath}"`);
404
- console.log(`✓ Queue file updated with ${statusFixed} status fixes`);
243
+ **Output** (JSON):
244
+ ```json
245
+ {
246
+ "success": true,
247
+ "queue_id": "QUE-xxx",
248
+ "queued": ["ISS-001", "ISS-002"],
249
+ "queued_count": 2,
250
+ "unplanned": ["ISS-003"],
251
+ "unplanned_count": 1
405
252
  }
253
+ ```
406
254
 
407
- // ============ OUTPUT SUMMARY ============
255
+ **Behavior:**
256
+ - Updates issues in queue to `status: 'queued'` (skips already queued/executing/completed)
257
+ - Identifies planned issues with `bound_solution_id` NOT in queue → `unplanned` array
258
+ - Optional `queue-id`: defaults to active queue if omitted
408
259
 
409
- console.log(`
410
- ## Queue Formed: ${summary.queue_id}
260
+ **Summary Output:**
261
+ - Display queue ID, solution count, task count
262
+ - Show unplanned issues (planned but NOT in queue)
263
+ - Show next step: `/issue:execute`
411
264
 
412
- **Solutions**: ${summary.total_solutions}
413
- **Tasks**: ${summary.total_tasks}
414
- **Issues**: ${summary.issues_queued.join(', ')}
415
- **Groups**: ${summary.execution_groups.map(g => `${g.id}(${g.count})`).join(', ')}
416
- **Conflicts Resolved**: ${summary.conflicts_resolved}
417
- **Entry Points**: ${entryPoints.length} (items ready for immediate execution)
418
265
 
419
- Next: \`/issue:execute\` or \`ccw issue next\`
420
- `);
266
+ ## Storage Structure (Queue History)
421
267
 
422
- // Update issue statuses via CLI
423
- for (const issueId of summary.issues_queued) {
424
- Bash(`ccw issue update ${issueId} --status queued`);
425
- }
268
+ ```
269
+ .workflow/issues/
270
+ ├── issues.jsonl # All issues (one per line)
271
+ ├── queues/ # Queue history directory
272
+ │ ├── index.json # Queue index (active + history)
273
+ │ ├── {queue-id}.json # Individual queue files
274
+ │ └── ...
275
+ └── solutions/
276
+ ├── {issue-id}.jsonl # Solutions for issue
277
+ └── ...
278
+ ```
426
279
 
427
- // Final verification
428
- const verifyResult = Bash(`ccw issue queue dag 2>/dev/null | head -20`);
429
- console.log('\n### Verification (DAG Preview):');
430
- console.log(verifyResult);
280
+ ### Queue Index Schema
281
+
282
+ ```json
283
+ {
284
+ "active_queue_id": "QUE-20251227-143000",
285
+ "queues": [
286
+ {
287
+ "id": "QUE-20251227-143000",
288
+ "status": "active",
289
+ "issue_ids": ["ISS-xxx", "ISS-yyy"],
290
+ "total_solutions": 3,
291
+ "completed_solutions": 1,
292
+ "created_at": "2025-12-27T14:30:00Z"
293
+ }
294
+ ]
295
+ }
431
296
  ```
432
297
 
298
+ **Note**: Queue file schema is produced by `issue-queue-agent`. See agent documentation for details.
433
299
  ## Error Handling
434
300
 
435
301
  | Error | Resolution |
436
302
  |-------|------------|
437
303
  | No bound solutions | Display message, suggest /issue:plan |
438
304
  | Circular dependency | List cycles, abort queue formation |
439
- | Unresolved conflicts | Agent resolves using ordering rules |
440
- | Invalid task reference | Skip and warn |
305
+ | High-severity conflict | Return `clarifications`, prompt user decision |
306
+ | User cancels clarification | Abort queue formation |
441
307
  | **index.json not updated** | Auto-fix: Set active_queue_id to new queue |
442
- | **Wrong status value** | Auto-fix: Convert non-pending status to "pending" |
443
- | **No entry points (all have deps)** | Auto-fix: Clear depends_on for first item |
444
308
  | **Queue file missing solutions** | Abort with error, agent must regenerate |
445
309
 
310
+ ## Quality Checklist
311
+
312
+ Before completing, verify:
313
+
314
+ - [ ] All planned issues with `bound_solution_id` are included
315
+ - [ ] Queue JSON written to `queues/{queue-id}.json`
316
+ - [ ] Index updated in `queues/index.json` with `active_queue_id`
317
+ - [ ] No circular dependencies in solution DAG
318
+ - [ ] All conflicts resolved (auto or via user clarification)
319
+ - [ ] Parallel groups have no file overlaps
320
+ - [ ] Issue statuses updated to `queued`
321
+
446
322
  ## Related Commands
447
323
 
448
324
  - `/issue:plan` - Plan issues and bind solutions
449
325
  - `/issue:execute` - Execute queue with codex
450
326
  - `ccw issue queue list` - View current queue
327
+ - `ccw issue update --from-queue [queue-id]` - Sync issue statuses from queue