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.
- package/.claude/agents/issue-plan-agent.md +62 -36
- package/.claude/agents/issue-queue-agent.md +110 -57
- package/.claude/commands/issue/execute.md +53 -40
- package/.claude/commands/issue/new.md +226 -380
- package/.claude/commands/issue/plan.md +122 -125
- package/.claude/commands/issue/queue.md +198 -321
- 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 +141 -168
- package/.claude/workflows/cli-templates/schemas/queue-schema.json +0 -5
- package/.claude/workflows/cli-templates/schemas/solution-schema.json +3 -2
- package/.codex/prompts/issue-execute.md +3 -3
- package/.codex/prompts/issue-plan.md +16 -19
- package/.codex/prompts/issue-queue.md +3 -4
- 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 +88 -83
- 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-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
|
-
├─
|
|
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
|
|
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
|
|
193
|
-
├─
|
|
194
|
-
|
|
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
|
-
**
|
|
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
|
|
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
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
);
|
|
237
|
+
# Option 2: Individual issue update
|
|
238
|
+
ccw issue update <issue-id> --status queued
|
|
239
|
+
```
|
|
389
240
|
|
|
390
|
-
|
|
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
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
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
|
-
|
|
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
|
-
|
|
410
|
-
|
|
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
|
-
|
|
420
|
-
`);
|
|
266
|
+
## Storage Structure (Queue History)
|
|
421
267
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
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
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
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
|
-
|
|
|
440
|
-
|
|
|
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
|