claude-code-workflow 6.3.13 → 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.
- package/.claude/agents/issue-plan-agent.md +57 -103
- package/.claude/agents/issue-queue-agent.md +69 -120
- package/.claude/commands/issue/new.md +217 -473
- package/.claude/commands/issue/plan.md +76 -154
- package/.claude/commands/issue/queue.md +208 -259
- package/.claude/skills/issue-manage/SKILL.md +63 -22
- package/.claude/workflows/cli-templates/schemas/discovery-finding-schema.json +3 -3
- package/.claude/workflows/cli-templates/schemas/issues-jsonl-schema.json +3 -3
- package/.claude/workflows/cli-templates/schemas/queue-schema.json +0 -5
- package/.codex/prompts/issue-plan.md +16 -19
- package/.codex/prompts/issue-queue.md +0 -1
- package/README.md +1 -0
- package/ccw/dist/cli.d.ts.map +1 -1
- package/ccw/dist/cli.js +3 -1
- package/ccw/dist/cli.js.map +1 -1
- package/ccw/dist/commands/cli.d.ts.map +1 -1
- package/ccw/dist/commands/cli.js +45 -3
- package/ccw/dist/commands/cli.js.map +1 -1
- package/ccw/dist/commands/issue.d.ts +3 -1
- package/ccw/dist/commands/issue.d.ts.map +1 -1
- package/ccw/dist/commands/issue.js +383 -30
- package/ccw/dist/commands/issue.js.map +1 -1
- package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/issue-routes.js +77 -16
- package/ccw/dist/core/routes/issue-routes.js.map +1 -1
- package/ccw/dist/tools/cli-executor.d.ts.map +1 -1
- package/ccw/dist/tools/cli-executor.js +117 -4
- package/ccw/dist/tools/cli-executor.js.map +1 -1
- package/ccw/dist/tools/litellm-executor.d.ts +4 -0
- package/ccw/dist/tools/litellm-executor.d.ts.map +1 -1
- package/ccw/dist/tools/litellm-executor.js +54 -1
- package/ccw/dist/tools/litellm-executor.js.map +1 -1
- package/ccw/dist/tools/ui-generate-preview.d.ts +18 -0
- package/ccw/dist/tools/ui-generate-preview.d.ts.map +1 -1
- package/ccw/dist/tools/ui-generate-preview.js +26 -10
- package/ccw/dist/tools/ui-generate-preview.js.map +1 -1
- package/ccw/src/cli.ts +3 -1
- package/ccw/src/commands/cli.ts +47 -3
- package/ccw/src/commands/issue.ts +442 -34
- package/ccw/src/core/routes/issue-routes.ts +82 -16
- package/ccw/src/tools/cli-executor.ts +125 -4
- package/ccw/src/tools/litellm-executor.ts +107 -24
- package/ccw/src/tools/ui-generate-preview.js +60 -37
- package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/__pycache__/entities.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/config.py +25 -2
- package/codex-lens/src/codexlens/entities.py +5 -1
- package/codex-lens/src/codexlens/indexing/__pycache__/symbol_extractor.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/indexing/symbol_extractor.py +243 -243
- package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/parsers/factory.py +256 -256
- package/codex-lens/src/codexlens/parsers/treesitter_parser.py +335 -335
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/chain_search.py +30 -1
- package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/reranker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/embedder.py +6 -9
- package/codex-lens/src/codexlens/semantic/vector_store.py +271 -200
- package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/sqlite_store.py +184 -108
- package/package.json +6 -1
- 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
|
-
-
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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-ISS-20251227-003-1",
|
|
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-ISS-20251227-001-1",
|
|
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-ISS-20251227-002-1",
|
|
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,208 +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
|
-
├─
|
|
176
|
-
├─
|
|
177
|
-
|
|
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
|
|
83
|
+
├─ Launch issue-queue-agent with solutions array
|
|
183
84
|
├─ Agent performs:
|
|
184
|
-
│ ├─
|
|
185
|
-
│ ├─ Build dependency DAG from
|
|
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
|
-
└─
|
|
89
|
+
└─ Agent writes: queue JSON + index update
|
|
191
90
|
|
|
192
|
-
Phase 5:
|
|
193
|
-
├─
|
|
194
|
-
├─
|
|
195
|
-
|
|
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
|
|
96
|
+
|
|
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
|
-
**
|
|
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
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
136
|
+
**Agent Prompt**:
|
|
258
137
|
```
|
|
138
|
+
## Order Solutions into Execution Queue
|
|
259
139
|
|
|
260
|
-
|
|
140
|
+
**Queue ID**: ${queueId}
|
|
141
|
+
**Solutions**: ${solutions.length} from ${issues.length} issues
|
|
142
|
+
**Project Root**: ${cwd}
|
|
261
143
|
|
|
262
|
-
|
|
263
|
-
|
|
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
|
-
|
|
268
|
-
const agentPrompt = `
|
|
269
|
-
## Order Solutions
|
|
147
|
+
### Workflow
|
|
270
148
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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
|
-
###
|
|
276
|
-
\`\`\`json
|
|
277
|
-
${JSON.stringify(allSolutions, null, 2)}
|
|
278
|
-
\`\`\`
|
|
156
|
+
### Output Requirements
|
|
279
157
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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
|
-
|
|
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": "
|
|
165
|
+
"queue_id": "${queueId}",
|
|
313
166
|
"total_solutions": N,
|
|
314
167
|
"total_tasks": N,
|
|
315
|
-
"execution_groups": [{
|
|
316
|
-
"
|
|
317
|
-
"
|
|
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
|
-
|
|
325
|
-
description=`Order ${
|
|
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:
|
|
197
|
+
### Phase 5: Conflict Clarification
|
|
333
198
|
|
|
334
|
-
|
|
335
|
-
|
|
199
|
+
**Check Agent Return:**
|
|
200
|
+
- Parse agent result JSON
|
|
201
|
+
- If `clarifications` array exists and non-empty → user decision required
|
|
336
202
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
if (
|
|
340
|
-
|
|
341
|
-
|
|
203
|
+
**Clarification Flow:**
|
|
204
|
+
```javascript
|
|
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
|
+
}]
|
|
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
|
+
);
|
|
223
|
+
}
|
|
342
224
|
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Phase 6: Status Update & Summary
|
|
228
|
+
|
|
229
|
+
**Status Update** (MUST use CLI command, NOT direct file operations):
|
|
230
|
+
|
|
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
|
|
236
|
+
|
|
237
|
+
# Option 2: Individual issue update
|
|
238
|
+
ccw issue update <issue-id> --status queued
|
|
239
|
+
```
|
|
343
240
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
241
|
+
**⚠️ IMPORTANT**: Do NOT directly modify `issues.jsonl`. Always use CLI command to ensure proper validation and history tracking.
|
|
242
|
+
|
|
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
|
|
347
252
|
}
|
|
253
|
+
```
|
|
254
|
+
|
|
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
|
|
259
|
+
|
|
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`
|
|
264
|
+
|
|
348
265
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
266
|
+
## Storage Structure (Queue History)
|
|
267
|
+
|
|
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
|
+
```
|
|
352
279
|
|
|
353
|
-
|
|
354
|
-
- Tasks: ${summary.total_tasks}
|
|
355
|
-
- Issues: ${summary.issues_queued.join(', ')}
|
|
280
|
+
### Queue Index Schema
|
|
356
281
|
|
|
357
|
-
|
|
358
|
-
|
|
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
|
+
}
|
|
359
296
|
```
|
|
360
297
|
|
|
298
|
+
**Note**: Queue file schema is produced by `issue-queue-agent`. See agent documentation for details.
|
|
361
299
|
## Error Handling
|
|
362
300
|
|
|
363
301
|
| Error | Resolution |
|
|
364
302
|
|-------|------------|
|
|
365
303
|
| No bound solutions | Display message, suggest /issue:plan |
|
|
366
304
|
| Circular dependency | List cycles, abort queue formation |
|
|
367
|
-
|
|
|
368
|
-
|
|
|
305
|
+
| High-severity conflict | Return `clarifications`, prompt user decision |
|
|
306
|
+
| User cancels clarification | Abort queue formation |
|
|
369
307
|
| **index.json not updated** | Auto-fix: Set active_queue_id to new queue |
|
|
370
|
-
| **Wrong status value** | Auto-fix: Convert non-pending status to "pending" |
|
|
371
|
-
| **No entry points (all have deps)** | Auto-fix: Clear depends_on for first item |
|
|
372
308
|
| **Queue file missing solutions** | Abort with error, agent must regenerate |
|
|
373
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
|
+
|
|
374
322
|
## Related Commands
|
|
375
323
|
|
|
376
324
|
- `/issue:plan` - Plan issues and bind solutions
|
|
377
325
|
- `/issue:execute` - Execute queue with codex
|
|
378
326
|
- `ccw issue queue list` - View current queue
|
|
327
|
+
- `ccw issue update --from-queue [queue-id]` - Sync issue statuses from queue
|