claude-code-workflow 6.3.7 → 6.3.8
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 +136 -760
- package/.claude/agents/issue-queue-agent.md +149 -616
- package/.claude/commands/issue/execute.md +55 -26
- package/.claude/commands/issue/manage.md +37 -789
- package/.claude/commands/issue/new.md +9 -42
- package/.claude/commands/issue/plan.md +86 -278
- package/.claude/commands/issue/queue.md +99 -159
- package/.claude/skills/issue-manage/SKILL.md +244 -0
- package/.codex/prompts/issue-execute.md +11 -11
- package/ccw/dist/cli.d.ts.map +1 -1
- package/ccw/dist/cli.js +1 -0
- package/ccw/dist/cli.js.map +1 -1
- package/ccw/dist/commands/issue.d.ts +1 -0
- package/ccw/dist/commands/issue.d.ts.map +1 -1
- package/ccw/dist/commands/issue.js +86 -70
- package/ccw/dist/commands/issue.js.map +1 -1
- package/ccw/dist/core/routes/issue-routes.d.ts +3 -1
- package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/issue-routes.js +30 -18
- package/ccw/dist/core/routes/issue-routes.js.map +1 -1
- package/ccw/src/cli.ts +1 -0
- package/ccw/src/commands/issue.ts +111 -76
- package/ccw/src/core/routes/issue-routes.ts +34 -18
- package/ccw/src/templates/dashboard-js/views/issue-manager.js +14 -14
- package/package.json +1 -1
|
@@ -51,51 +51,18 @@ interface Issue {
|
|
|
51
51
|
}
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
##
|
|
54
|
+
## Lifecycle Requirements
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
The `lifecycle_requirements` field guides downstream commands (`/issue:plan`, `/issue:execute`):
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// Phase 1: Implementation
|
|
66
|
-
implementation: string[]; // Step-by-step implementation
|
|
67
|
-
modification_points: { file: string; target: string; change: string }[];
|
|
68
|
-
|
|
69
|
-
// Phase 2: Testing
|
|
70
|
-
test: {
|
|
71
|
-
unit?: string[]; // Unit test requirements
|
|
72
|
-
integration?: string[]; // Integration test requirements
|
|
73
|
-
commands?: string[]; // Test commands to run
|
|
74
|
-
coverage_target?: number; // Minimum coverage %
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// Phase 3: Regression
|
|
78
|
-
regression: string[]; // Regression check commands/points
|
|
79
|
-
|
|
80
|
-
// Phase 4: Acceptance
|
|
81
|
-
acceptance: {
|
|
82
|
-
criteria: string[]; // Testable acceptance criteria
|
|
83
|
-
verification: string[]; // How to verify each criterion
|
|
84
|
-
manual_checks?: string[]; // Manual verification if needed
|
|
85
|
-
};
|
|
58
|
+
| Field | Options | Purpose |
|
|
59
|
+
|-------|---------|---------|
|
|
60
|
+
| `test_strategy` | `unit`, `integration`, `e2e`, `manual`, `auto` | Which test types to generate |
|
|
61
|
+
| `regression_scope` | `affected`, `related`, `full` | Which tests to run for regression |
|
|
62
|
+
| `acceptance_type` | `automated`, `manual`, `both` | How to verify completion |
|
|
63
|
+
| `commit_strategy` | `per-task`, `squash`, `atomic` | Commit granularity |
|
|
86
64
|
|
|
87
|
-
|
|
88
|
-
commit: {
|
|
89
|
-
type: 'feat' | 'fix' | 'refactor' | 'test' | 'docs' | 'chore';
|
|
90
|
-
scope: string; // e.g., "auth", "api"
|
|
91
|
-
message_template: string; // Commit message template
|
|
92
|
-
breaking?: boolean;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
depends_on: string[];
|
|
96
|
-
executor: 'codex' | 'gemini' | 'agent' | 'auto';
|
|
97
|
-
}
|
|
98
|
-
```
|
|
65
|
+
> **Note**: Task structure (SolutionTask) is defined in `/issue:plan` - see `.claude/commands/issue/plan.md`
|
|
99
66
|
|
|
100
67
|
## Usage
|
|
101
68
|
|
|
@@ -9,13 +9,35 @@ allowed-tools: TodoWrite(*), Task(*), SlashCommand(*), AskUserQuestion(*), Bash(
|
|
|
9
9
|
|
|
10
10
|
## Overview
|
|
11
11
|
|
|
12
|
-
Unified planning command using **issue-plan-agent** that combines exploration and planning into a single closed-loop workflow.
|
|
12
|
+
Unified planning command using **issue-plan-agent** that combines exploration and planning into a single closed-loop workflow.
|
|
13
|
+
|
|
14
|
+
## Output Requirements
|
|
15
|
+
|
|
16
|
+
**Generate Files:**
|
|
17
|
+
1. `.workflow/issues/solutions/{issue-id}.jsonl` - Solution with tasks for each issue
|
|
18
|
+
|
|
19
|
+
**Return Summary:**
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"bound": [{ "issue_id": "...", "solution_id": "...", "task_count": N }],
|
|
23
|
+
"pending_selection": [{ "issue_id": "...", "solutions": [...] }],
|
|
24
|
+
"conflicts": [{ "file": "...", "issues": [...] }]
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Completion Criteria:**
|
|
29
|
+
- [ ] Solution file generated for each issue
|
|
30
|
+
- [ ] Single solution → auto-bound via `ccw issue bind`
|
|
31
|
+
- [ ] Multiple solutions → returned for user selection
|
|
32
|
+
- [ ] Tasks conform to schema: `cat .claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json`
|
|
33
|
+
- [ ] Each task has quantified `delivery_criteria`
|
|
34
|
+
|
|
35
|
+
## Core Capabilities
|
|
13
36
|
|
|
14
|
-
**Core capabilities:**
|
|
15
37
|
- **Closed-loop agent**: issue-plan-agent combines explore + plan
|
|
16
38
|
- Batch processing: 1 agent processes 1-3 issues
|
|
17
39
|
- ACE semantic search integrated into planning
|
|
18
|
-
- Solution with executable tasks and
|
|
40
|
+
- Solution with executable tasks and delivery criteria
|
|
19
41
|
- Automatic solution registration and binding
|
|
20
42
|
|
|
21
43
|
## Storage Structure (Flat JSONL)
|
|
@@ -75,26 +97,16 @@ Phase 4: Summary
|
|
|
75
97
|
|
|
76
98
|
## Implementation
|
|
77
99
|
|
|
78
|
-
### Phase 1: Issue Loading
|
|
100
|
+
### Phase 1: Issue Loading (IDs Only)
|
|
79
101
|
|
|
80
102
|
```javascript
|
|
81
|
-
// Parse input and flags
|
|
82
|
-
const issuesPath = '.workflow/issues/issues.jsonl';
|
|
83
103
|
const batchSize = flags.batchSize || 3;
|
|
84
|
-
|
|
85
|
-
// Key fields for planning (avoid loading full issue data)
|
|
86
|
-
const PLAN_FIELDS = 'id,title,status,context,affected_components,lifecycle_requirements,priority,bound_solution_id';
|
|
87
|
-
|
|
88
104
|
let issueIds = [];
|
|
89
105
|
|
|
90
106
|
if (flags.allPending) {
|
|
91
|
-
//
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
jq -r 'select(.status == "pending" or .status == "registered") | .id' 2>/dev/null || echo ''
|
|
95
|
-
`).trim();
|
|
96
|
-
|
|
97
|
-
issueIds = pendingIds ? pendingIds.split('\n').filter(Boolean) : [];
|
|
107
|
+
// Get pending issue IDs directly via CLI
|
|
108
|
+
const ids = Bash(`ccw issue list --status pending,registered --ids`).trim();
|
|
109
|
+
issueIds = ids ? ids.split('\n').filter(Boolean) : [];
|
|
98
110
|
|
|
99
111
|
if (issueIds.length === 0) {
|
|
100
112
|
console.log('No pending issues found.');
|
|
@@ -106,135 +118,66 @@ if (flags.allPending) {
|
|
|
106
118
|
issueIds = userInput.includes(',')
|
|
107
119
|
? userInput.split(',').map(s => s.trim())
|
|
108
120
|
: [userInput.trim()];
|
|
109
|
-
}
|
|
110
121
|
|
|
111
|
-
//
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
// Use jq to find issue by ID and extract only needed fields
|
|
115
|
-
const issueJson = Bash(`
|
|
116
|
-
cat "${issuesPath}" 2>/dev/null | \\
|
|
117
|
-
jq -c 'select(.id == "${id}") | {${PLAN_FIELDS}}' 2>/dev/null | head -1
|
|
118
|
-
`).trim();
|
|
119
|
-
|
|
120
|
-
let issue;
|
|
121
|
-
if (issueJson) {
|
|
122
|
-
issue = JSON.parse(issueJson);
|
|
123
|
-
} else {
|
|
124
|
-
console.log(`Issue ${id} not found. Creating...`);
|
|
125
|
-
issue = {
|
|
126
|
-
id,
|
|
127
|
-
title: `Issue ${id}`,
|
|
128
|
-
status: 'registered',
|
|
129
|
-
priority: 3,
|
|
130
|
-
context: '',
|
|
131
|
-
created_at: new Date().toISOString(),
|
|
132
|
-
updated_at: new Date().toISOString()
|
|
133
|
-
};
|
|
134
|
-
// Append to issues.jsonl
|
|
135
|
-
Bash(`echo '${JSON.stringify(issue)}' >> "${issuesPath}"`);
|
|
122
|
+
// Create if not exists
|
|
123
|
+
for (const id of issueIds) {
|
|
124
|
+
Bash(`ccw issue init ${id} --title "Issue ${id}" 2>/dev/null || true`);
|
|
136
125
|
}
|
|
137
|
-
|
|
138
|
-
issues.push(issue);
|
|
139
126
|
}
|
|
140
127
|
|
|
141
128
|
// Group into batches
|
|
142
129
|
const batches = [];
|
|
143
|
-
for (let i = 0; i <
|
|
144
|
-
batches.push(
|
|
130
|
+
for (let i = 0; i < issueIds.length; i += batchSize) {
|
|
131
|
+
batches.push(issueIds.slice(i, i + batchSize));
|
|
145
132
|
}
|
|
146
133
|
|
|
147
|
-
console.log(`Processing ${
|
|
134
|
+
console.log(`Processing ${issueIds.length} issues in ${batches.length} batch(es)`);
|
|
148
135
|
|
|
149
136
|
TodoWrite({
|
|
150
|
-
todos: batches.
|
|
151
|
-
|
|
152
|
-
|
|
137
|
+
todos: batches.map((_, i) => ({
|
|
138
|
+
content: `Plan batch ${i+1}`,
|
|
139
|
+
status: 'pending',
|
|
140
|
+
activeForm: `Planning batch ${i+1}`
|
|
141
|
+
}))
|
|
153
142
|
});
|
|
154
143
|
```
|
|
155
144
|
|
|
156
145
|
### Phase 2: Unified Explore + Plan (issue-plan-agent)
|
|
157
146
|
|
|
158
147
|
```javascript
|
|
159
|
-
// Ensure solutions directory exists
|
|
160
148
|
Bash(`mkdir -p .workflow/issues/solutions`);
|
|
149
|
+
const pendingSelections = []; // Collect multi-solution issues for user selection
|
|
161
150
|
|
|
162
151
|
for (const [batchIndex, batch] of batches.entries()) {
|
|
163
152
|
updateTodo(`Plan batch ${batchIndex + 1}`, 'in_progress');
|
|
164
153
|
|
|
165
|
-
// Build
|
|
154
|
+
// Build minimal prompt - agent handles exploration, planning, and binding
|
|
166
155
|
const issuePrompt = `
|
|
167
|
-
##
|
|
156
|
+
## Plan Issues
|
|
168
157
|
|
|
169
|
-
${batch.
|
|
170
|
-
|
|
171
|
-
**Title**: ${issue.title}
|
|
172
|
-
**Context**: ${issue.context || 'No context provided'}
|
|
173
|
-
**Affected Components**: ${issue.affected_components?.join(', ') || 'Not specified'}
|
|
158
|
+
**Issue IDs**: ${batch.join(', ')}
|
|
159
|
+
**Project Root**: ${process.cwd()}
|
|
174
160
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
`).join('\n')}
|
|
180
|
-
|
|
181
|
-
## Project Root
|
|
182
|
-
${process.cwd()}
|
|
183
|
-
|
|
184
|
-
## Output Requirements
|
|
161
|
+
### Steps
|
|
162
|
+
1. Fetch: \`ccw issue status <id> --json\`
|
|
163
|
+
2. Explore (ACE) → Plan solution
|
|
164
|
+
3. Register & bind: \`ccw issue bind <id> --solution <file>\`
|
|
185
165
|
|
|
186
|
-
|
|
166
|
+
### Generate Files
|
|
167
|
+
\`.workflow/issues/solutions/{issue-id}.jsonl\` - Solution with tasks (schema: cat .claude/workflows/cli-templates/schemas/issue-task-jsonl-schema.json)
|
|
187
168
|
|
|
188
|
-
###
|
|
189
|
-
|
|
190
|
-
-
|
|
191
|
-
- Solution must include all closed-loop task fields (see Solution Format below)
|
|
169
|
+
### Binding Rules
|
|
170
|
+
- **Single solution**: Auto-bind via \`ccw issue bind <id> --solution <file>\`
|
|
171
|
+
- **Multiple solutions**: Register only, return for user selection
|
|
192
172
|
|
|
193
|
-
###
|
|
194
|
-
After writing solutions, return ONLY a brief JSON summary:
|
|
173
|
+
### Return Summary
|
|
195
174
|
\`\`\`json
|
|
196
175
|
{
|
|
197
|
-
"
|
|
198
|
-
|
|
199
|
-
]
|
|
200
|
-
"conflicts": [
|
|
201
|
-
{ "file": "path/to/file", "issues": ["ID1", "ID2"], "suggested_order": ["ID1", "ID2"] }
|
|
202
|
-
]
|
|
176
|
+
"bound": [{ "issue_id": "...", "solution_id": "...", "task_count": N }],
|
|
177
|
+
"pending_selection": [{ "issue_id": "...", "solutions": [{ "id": "...", "description": "...", "task_count": N }] }],
|
|
178
|
+
"conflicts": [{ "file": "...", "issues": [...] }]
|
|
203
179
|
}
|
|
204
180
|
\`\`\`
|
|
205
|
-
|
|
206
|
-
## Closed-Loop Task Requirements
|
|
207
|
-
|
|
208
|
-
Each task MUST include ALL lifecycle phases:
|
|
209
|
-
|
|
210
|
-
### 1. Implementation
|
|
211
|
-
- implementation: string[] (2-7 concrete steps)
|
|
212
|
-
- modification_points: { file, target, change }[]
|
|
213
|
-
|
|
214
|
-
### 2. Test
|
|
215
|
-
- test.unit: string[] (unit test requirements)
|
|
216
|
-
- test.integration: string[] (integration test requirements if needed)
|
|
217
|
-
- test.commands: string[] (actual test commands to run)
|
|
218
|
-
- test.coverage_target: number (minimum coverage %)
|
|
219
|
-
|
|
220
|
-
### 3. Regression
|
|
221
|
-
- regression: string[] (commands to run for regression check)
|
|
222
|
-
|
|
223
|
-
### 4. Acceptance
|
|
224
|
-
- acceptance.criteria: string[] (testable acceptance criteria)
|
|
225
|
-
- acceptance.verification: string[] (how to verify each criterion)
|
|
226
|
-
|
|
227
|
-
### 5. Commit
|
|
228
|
-
- commit.type: feat|fix|refactor|test|docs|chore
|
|
229
|
-
- commit.scope: string (module name)
|
|
230
|
-
- commit.message_template: string (full commit message)
|
|
231
|
-
- commit.breaking: boolean
|
|
232
|
-
|
|
233
|
-
## Additional Requirements
|
|
234
|
-
1. Use ACE semantic search (mcp__ace-tool__search_context) for exploration
|
|
235
|
-
2. Detect file conflicts if multiple issues
|
|
236
|
-
3. Generate executable test commands based on project's test framework
|
|
237
|
-
4. Infer commit scope from affected files
|
|
238
181
|
`;
|
|
239
182
|
|
|
240
183
|
// Launch issue-plan-agent - agent writes solutions directly
|
|
@@ -245,192 +188,68 @@ Each task MUST include ALL lifecycle phases:
|
|
|
245
188
|
prompt=issuePrompt
|
|
246
189
|
);
|
|
247
190
|
|
|
248
|
-
// Parse
|
|
191
|
+
// Parse summary from agent
|
|
249
192
|
const summary = JSON.parse(result);
|
|
250
193
|
|
|
251
|
-
// Display
|
|
252
|
-
for (const item of summary.
|
|
253
|
-
console.log(`✓ ${item.issue_id}: ${item.solution_id} (${item.task_count} tasks)
|
|
194
|
+
// Display auto-bound solutions
|
|
195
|
+
for (const item of summary.bound || []) {
|
|
196
|
+
console.log(`✓ ${item.issue_id}: ${item.solution_id} (${item.task_count} tasks)`);
|
|
254
197
|
}
|
|
255
198
|
|
|
256
|
-
//
|
|
199
|
+
// Collect pending selections for Phase 3
|
|
200
|
+
pendingSelections.push(...(summary.pending_selection || []));
|
|
201
|
+
|
|
202
|
+
// Show conflicts
|
|
257
203
|
if (summary.conflicts?.length > 0) {
|
|
258
|
-
console.log(
|
|
259
|
-
summary.conflicts.forEach(c => {
|
|
260
|
-
console.log(` ${c.file}: ${c.issues.join(', ')} → suggested: ${c.suggested_order.join(' → ')}`);
|
|
261
|
-
});
|
|
204
|
+
console.log(`⚠ Conflicts: ${summary.conflicts.map(c => c.file).join(', ')}`);
|
|
262
205
|
}
|
|
263
206
|
|
|
264
207
|
updateTodo(`Plan batch ${batchIndex + 1}`, 'completed');
|
|
265
208
|
}
|
|
266
209
|
```
|
|
267
210
|
|
|
268
|
-
### Phase 3: Solution
|
|
211
|
+
### Phase 3: Multi-Solution Selection
|
|
269
212
|
|
|
270
213
|
```javascript
|
|
271
|
-
//
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
for (const issue of issues) {
|
|
275
|
-
const solPath = `.workflow/issues/solutions/${issue.id}.jsonl`;
|
|
276
|
-
|
|
277
|
-
// Use jq to count solutions
|
|
278
|
-
const count = parseInt(Bash(`cat "${solPath}" 2>/dev/null | jq -s 'length' 2>/dev/null || echo '0'`).trim()) || 0;
|
|
279
|
-
|
|
280
|
-
if (count === 0) continue; // No solutions - skip silently (agent already reported)
|
|
281
|
-
|
|
282
|
-
if (count === 1) {
|
|
283
|
-
// Auto-bind single solution
|
|
284
|
-
const solId = Bash(`cat "${solPath}" | jq -r '.id' | head -1`).trim();
|
|
285
|
-
bindSolution(issue.id, solId);
|
|
286
|
-
} else {
|
|
287
|
-
// Multiple solutions - collect for batch selection
|
|
288
|
-
const options = Bash(`cat "${solPath}" | jq -c '{id, description, task_count: (.tasks | length)}'`).trim();
|
|
289
|
-
needSelection.push({ issue, options: options.split('\n').map(s => JSON.parse(s)) });
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Batch ask user for multiple-solution issues
|
|
294
|
-
if (needSelection.length > 0) {
|
|
214
|
+
// Only handle issues where agent generated multiple solutions
|
|
215
|
+
if (pendingSelections.length > 0) {
|
|
295
216
|
const answer = AskUserQuestion({
|
|
296
|
-
questions:
|
|
297
|
-
question: `Select solution for ${
|
|
298
|
-
header:
|
|
217
|
+
questions: pendingSelections.map(({ issue_id, solutions }) => ({
|
|
218
|
+
question: `Select solution for ${issue_id}:`,
|
|
219
|
+
header: issue_id,
|
|
299
220
|
multiSelect: false,
|
|
300
|
-
options:
|
|
221
|
+
options: solutions.map(s => ({
|
|
301
222
|
label: `${s.id} (${s.task_count} tasks)`,
|
|
302
|
-
description: s.description
|
|
223
|
+
description: s.description
|
|
303
224
|
}))
|
|
304
225
|
}))
|
|
305
226
|
});
|
|
306
227
|
|
|
307
|
-
// Bind selected solutions
|
|
308
|
-
for (const {
|
|
309
|
-
const
|
|
310
|
-
if (
|
|
228
|
+
// Bind user-selected solutions
|
|
229
|
+
for (const { issue_id } of pendingSelections) {
|
|
230
|
+
const selectedId = extractSelectedSolutionId(answer, issue_id);
|
|
231
|
+
if (selectedId) {
|
|
232
|
+
Bash(`ccw issue bind ${issue_id} ${selectedId}`);
|
|
233
|
+
console.log(`✓ ${issue_id}: ${selectedId} bound`);
|
|
234
|
+
}
|
|
311
235
|
}
|
|
312
236
|
}
|
|
313
|
-
|
|
314
|
-
// Helper: bind solution to issue
|
|
315
|
-
function bindSolution(issueId, solutionId) {
|
|
316
|
-
const now = new Date().toISOString();
|
|
317
|
-
const solPath = `.workflow/issues/solutions/${issueId}.jsonl`;
|
|
318
|
-
|
|
319
|
-
// Update issue status
|
|
320
|
-
Bash(`
|
|
321
|
-
tmpfile=$(mktemp) && \\
|
|
322
|
-
cat "${issuesPath}" | jq -c 'if .id == "${issueId}" then . + {
|
|
323
|
-
bound_solution_id: "${solutionId}", status: "planned",
|
|
324
|
-
planned_at: "${now}", updated_at: "${now}"
|
|
325
|
-
} else . end' > "$tmpfile" && mv "$tmpfile" "${issuesPath}"
|
|
326
|
-
`);
|
|
327
|
-
|
|
328
|
-
// Mark solution as bound
|
|
329
|
-
Bash(`
|
|
330
|
-
tmpfile=$(mktemp) && \\
|
|
331
|
-
cat "${solPath}" | jq -c 'if .id == "${solutionId}" then . + {
|
|
332
|
-
is_bound: true, bound_at: "${now}"
|
|
333
|
-
} else . + {is_bound: false} end' > "$tmpfile" && mv "$tmpfile" "${solPath}"
|
|
334
|
-
`);
|
|
335
|
-
}
|
|
336
237
|
```
|
|
337
238
|
|
|
338
239
|
### Phase 4: Summary
|
|
339
240
|
|
|
340
241
|
```javascript
|
|
341
|
-
//
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
jq -s '[.[] | select(.status == "planned")] | length' 2>/dev/null || echo '0'
|
|
345
|
-
`).trim();
|
|
242
|
+
// Count planned issues via CLI
|
|
243
|
+
const plannedIds = Bash(`ccw issue list --status planned --ids`).trim();
|
|
244
|
+
const plannedCount = plannedIds ? plannedIds.split('\n').length : 0;
|
|
346
245
|
|
|
347
246
|
console.log(`
|
|
348
|
-
## Done: ${
|
|
247
|
+
## Done: ${issueIds.length} issues → ${plannedCount} planned
|
|
349
248
|
|
|
350
249
|
Next: \`/issue:queue\` → \`/issue:execute\`
|
|
351
250
|
`);
|
|
352
251
|
```
|
|
353
252
|
|
|
354
|
-
## Solution Format (Closed-Loop Tasks)
|
|
355
|
-
|
|
356
|
-
Each solution line in `solutions/{issue-id}.jsonl`:
|
|
357
|
-
|
|
358
|
-
```json
|
|
359
|
-
{
|
|
360
|
-
"id": "SOL-20251226-001",
|
|
361
|
-
"description": "Direct Implementation",
|
|
362
|
-
"tasks": [
|
|
363
|
-
{
|
|
364
|
-
"id": "T1",
|
|
365
|
-
"title": "Create auth middleware",
|
|
366
|
-
"scope": "src/middleware/",
|
|
367
|
-
"action": "Create",
|
|
368
|
-
"description": "Create JWT validation middleware",
|
|
369
|
-
"modification_points": [
|
|
370
|
-
{ "file": "src/middleware/auth.ts", "target": "new file", "change": "Create middleware" }
|
|
371
|
-
],
|
|
372
|
-
|
|
373
|
-
"implementation": [
|
|
374
|
-
"Create auth.ts file in src/middleware/",
|
|
375
|
-
"Implement JWT token validation using jsonwebtoken",
|
|
376
|
-
"Add error handling for invalid/expired tokens",
|
|
377
|
-
"Export middleware function"
|
|
378
|
-
],
|
|
379
|
-
|
|
380
|
-
"test": {
|
|
381
|
-
"unit": [
|
|
382
|
-
"Test valid token passes through",
|
|
383
|
-
"Test invalid token returns 401",
|
|
384
|
-
"Test expired token returns 401",
|
|
385
|
-
"Test missing token returns 401"
|
|
386
|
-
],
|
|
387
|
-
"commands": [
|
|
388
|
-
"npm test -- --grep 'auth middleware'",
|
|
389
|
-
"npm run test:coverage -- src/middleware/auth.ts"
|
|
390
|
-
],
|
|
391
|
-
"coverage_target": 80
|
|
392
|
-
},
|
|
393
|
-
|
|
394
|
-
"regression": [
|
|
395
|
-
"npm test -- --grep 'protected routes'",
|
|
396
|
-
"npm run test:integration -- auth"
|
|
397
|
-
],
|
|
398
|
-
|
|
399
|
-
"acceptance": {
|
|
400
|
-
"criteria": [
|
|
401
|
-
"Middleware validates JWT tokens successfully",
|
|
402
|
-
"Returns 401 for invalid or missing tokens",
|
|
403
|
-
"Passes decoded token to request context"
|
|
404
|
-
],
|
|
405
|
-
"verification": [
|
|
406
|
-
"curl -H 'Authorization: Bearer valid_token' /api/protected → 200",
|
|
407
|
-
"curl /api/protected → 401",
|
|
408
|
-
"curl -H 'Authorization: Bearer invalid' /api/protected → 401"
|
|
409
|
-
]
|
|
410
|
-
},
|
|
411
|
-
|
|
412
|
-
"commit": {
|
|
413
|
-
"type": "feat",
|
|
414
|
-
"scope": "auth",
|
|
415
|
-
"message_template": "feat(auth): add JWT validation middleware\n\n- Implement token validation\n- Add error handling for invalid tokens\n- Export for route protection",
|
|
416
|
-
"breaking": false
|
|
417
|
-
},
|
|
418
|
-
|
|
419
|
-
"depends_on": [],
|
|
420
|
-
"estimated_minutes": 30,
|
|
421
|
-
"executor": "codex"
|
|
422
|
-
}
|
|
423
|
-
],
|
|
424
|
-
"exploration_context": {
|
|
425
|
-
"relevant_files": ["src/config/auth.ts"],
|
|
426
|
-
"patterns": "Follow existing middleware pattern"
|
|
427
|
-
},
|
|
428
|
-
"is_bound": true,
|
|
429
|
-
"created_at": "2025-12-26T10:00:00Z",
|
|
430
|
-
"bound_at": "2025-12-26T10:05:00Z"
|
|
431
|
-
}
|
|
432
|
-
```
|
|
433
|
-
|
|
434
253
|
## Error Handling
|
|
435
254
|
|
|
436
255
|
| Error | Resolution |
|
|
@@ -441,17 +260,6 @@ Each solution line in `solutions/{issue-id}.jsonl`:
|
|
|
441
260
|
| User cancels selection | Skip issue, continue with others |
|
|
442
261
|
| File conflicts | Agent detects and suggests resolution order |
|
|
443
262
|
|
|
444
|
-
## Agent Integration
|
|
445
|
-
|
|
446
|
-
The command uses `issue-plan-agent` which:
|
|
447
|
-
1. Performs ACE semantic search per issue
|
|
448
|
-
2. Identifies modification points and patterns
|
|
449
|
-
3. Generates task breakdown with dependencies
|
|
450
|
-
4. Detects cross-issue file conflicts
|
|
451
|
-
5. Outputs solution JSON for registration
|
|
452
|
-
|
|
453
|
-
See `.claude/agents/issue-plan-agent.md` for agent specification.
|
|
454
|
-
|
|
455
263
|
## Related Commands
|
|
456
264
|
|
|
457
265
|
- `/issue:queue` - Form execution queue from bound solutions
|