claude-code-workflow 6.3.6 → 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 +80 -71
- package/.claude/commands/issue/manage.md +37 -789
- package/.claude/commands/issue/new.md +9 -42
- package/.claude/commands/issue/plan.md +128 -281
- 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 +110 -53
- 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 +137 -58
- 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
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plan
|
|
3
3
|
description: Batch plan issue resolution using issue-plan-agent (explore + plan closed-loop)
|
|
4
|
-
argument-hint: "<issue-id>[,<issue-id>,...] [--batch-size 3]"
|
|
4
|
+
argument-hint: "<issue-id>[,<issue-id>,...] [--batch-size 3] --all-pending"
|
|
5
5
|
allowed-tools: TodoWrite(*), Task(*), SlashCommand(*), AskUserQuestion(*), Bash(*), Read(*), Write(*)
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -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,120 +97,90 @@ 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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const allIssues = Bash(`cat "${issuesPath}" 2>/dev/null || echo ''`)
|
|
89
|
-
.split('\n')
|
|
90
|
-
.filter(line => line.trim())
|
|
91
|
-
.map(line => JSON.parse(line));
|
|
92
|
-
|
|
93
|
-
// Load and validate issues
|
|
94
|
-
const issues = [];
|
|
95
|
-
for (const id of issueIds) {
|
|
96
|
-
let issue = allIssues.find(i => i.id === id);
|
|
97
|
-
|
|
98
|
-
if (!issue) {
|
|
99
|
-
console.log(`Issue ${id} not found. Creating...`);
|
|
100
|
-
issue = {
|
|
101
|
-
id,
|
|
102
|
-
title: `Issue ${id}`,
|
|
103
|
-
status: 'registered',
|
|
104
|
-
priority: 3,
|
|
105
|
-
context: '',
|
|
106
|
-
created_at: new Date().toISOString(),
|
|
107
|
-
updated_at: new Date().toISOString()
|
|
108
|
-
};
|
|
109
|
-
// Append to issues.jsonl
|
|
110
|
-
Bash(`echo '${JSON.stringify(issue)}' >> "${issuesPath}"`);
|
|
111
|
-
}
|
|
103
|
+
const batchSize = flags.batchSize || 3;
|
|
104
|
+
let issueIds = [];
|
|
105
|
+
|
|
106
|
+
if (flags.allPending) {
|
|
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) : [];
|
|
112
110
|
|
|
113
|
-
|
|
111
|
+
if (issueIds.length === 0) {
|
|
112
|
+
console.log('No pending issues found.');
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
console.log(`Found ${issueIds.length} pending issues`);
|
|
116
|
+
} else {
|
|
117
|
+
// Parse comma-separated issue IDs
|
|
118
|
+
issueIds = userInput.includes(',')
|
|
119
|
+
? userInput.split(',').map(s => s.trim())
|
|
120
|
+
: [userInput.trim()];
|
|
121
|
+
|
|
122
|
+
// Create if not exists
|
|
123
|
+
for (const id of issueIds) {
|
|
124
|
+
Bash(`ccw issue init ${id} --title "Issue ${id}" 2>/dev/null || true`);
|
|
125
|
+
}
|
|
114
126
|
}
|
|
115
127
|
|
|
116
128
|
// Group into batches
|
|
117
|
-
const batchSize = flags.batchSize || 3;
|
|
118
129
|
const batches = [];
|
|
119
|
-
for (let i = 0; i <
|
|
120
|
-
batches.push(
|
|
130
|
+
for (let i = 0; i < issueIds.length; i += batchSize) {
|
|
131
|
+
batches.push(issueIds.slice(i, i + batchSize));
|
|
121
132
|
}
|
|
122
133
|
|
|
134
|
+
console.log(`Processing ${issueIds.length} issues in ${batches.length} batch(es)`);
|
|
135
|
+
|
|
123
136
|
TodoWrite({
|
|
124
|
-
todos: batches.
|
|
125
|
-
|
|
126
|
-
|
|
137
|
+
todos: batches.map((_, i) => ({
|
|
138
|
+
content: `Plan batch ${i+1}`,
|
|
139
|
+
status: 'pending',
|
|
140
|
+
activeForm: `Planning batch ${i+1}`
|
|
141
|
+
}))
|
|
127
142
|
});
|
|
128
143
|
```
|
|
129
144
|
|
|
130
145
|
### Phase 2: Unified Explore + Plan (issue-plan-agent)
|
|
131
146
|
|
|
132
147
|
```javascript
|
|
148
|
+
Bash(`mkdir -p .workflow/issues/solutions`);
|
|
149
|
+
const pendingSelections = []; // Collect multi-solution issues for user selection
|
|
150
|
+
|
|
133
151
|
for (const [batchIndex, batch] of batches.entries()) {
|
|
134
152
|
updateTodo(`Plan batch ${batchIndex + 1}`, 'in_progress');
|
|
135
153
|
|
|
136
|
-
// Build
|
|
154
|
+
// Build minimal prompt - agent handles exploration, planning, and binding
|
|
137
155
|
const issuePrompt = `
|
|
138
|
-
##
|
|
139
|
-
|
|
140
|
-
${batch.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
### 2. Test
|
|
164
|
-
- test.unit: string[] (unit test requirements)
|
|
165
|
-
- test.integration: string[] (integration test requirements if needed)
|
|
166
|
-
- test.commands: string[] (actual test commands to run)
|
|
167
|
-
- test.coverage_target: number (minimum coverage %)
|
|
168
|
-
|
|
169
|
-
### 3. Regression
|
|
170
|
-
- regression: string[] (commands to run for regression check)
|
|
171
|
-
- Based on issue's regression_scope setting
|
|
172
|
-
|
|
173
|
-
### 4. Acceptance
|
|
174
|
-
- acceptance.criteria: string[] (testable acceptance criteria)
|
|
175
|
-
- acceptance.verification: string[] (how to verify each criterion)
|
|
176
|
-
- acceptance.manual_checks: string[] (manual checks if needed)
|
|
177
|
-
|
|
178
|
-
### 5. Commit
|
|
179
|
-
- commit.type: feat|fix|refactor|test|docs|chore
|
|
180
|
-
- commit.scope: string (module name)
|
|
181
|
-
- commit.message_template: string (full commit message)
|
|
182
|
-
- commit.breaking: boolean
|
|
183
|
-
|
|
184
|
-
## Additional Requirements
|
|
185
|
-
1. Use ACE semantic search (mcp__ace-tool__search_context) for exploration
|
|
186
|
-
2. Detect file conflicts if multiple issues
|
|
187
|
-
3. Generate executable test commands based on project's test framework
|
|
188
|
-
4. Infer commit scope from affected files
|
|
156
|
+
## Plan Issues
|
|
157
|
+
|
|
158
|
+
**Issue IDs**: ${batch.join(', ')}
|
|
159
|
+
**Project Root**: ${process.cwd()}
|
|
160
|
+
|
|
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>\`
|
|
165
|
+
|
|
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)
|
|
168
|
+
|
|
169
|
+
### Binding Rules
|
|
170
|
+
- **Single solution**: Auto-bind via \`ccw issue bind <id> --solution <file>\`
|
|
171
|
+
- **Multiple solutions**: Register only, return for user selection
|
|
172
|
+
|
|
173
|
+
### Return Summary
|
|
174
|
+
\`\`\`json
|
|
175
|
+
{
|
|
176
|
+
"bound": [{ "issue_id": "...", "solution_id": "...", "task_count": N }],
|
|
177
|
+
"pending_selection": [{ "issue_id": "...", "solutions": [{ "id": "...", "description": "...", "task_count": N }] }],
|
|
178
|
+
"conflicts": [{ "file": "...", "issues": [...] }]
|
|
179
|
+
}
|
|
180
|
+
\`\`\`
|
|
189
181
|
`;
|
|
190
182
|
|
|
191
|
-
// Launch issue-plan-agent
|
|
183
|
+
// Launch issue-plan-agent - agent writes solutions directly
|
|
192
184
|
const result = Task(
|
|
193
185
|
subagent_type="issue-plan-agent",
|
|
194
186
|
run_in_background=false,
|
|
@@ -196,200 +188,66 @@ Each task MUST include ALL lifecycle phases:
|
|
|
196
188
|
prompt=issuePrompt
|
|
197
189
|
);
|
|
198
190
|
|
|
199
|
-
// Parse agent
|
|
200
|
-
const
|
|
191
|
+
// Parse summary from agent
|
|
192
|
+
const summary = JSON.parse(result);
|
|
201
193
|
|
|
202
|
-
//
|
|
203
|
-
for (const item of
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
// Ensure solutions directory exists
|
|
207
|
-
Bash(`mkdir -p .workflow/issues/solutions`);
|
|
208
|
-
|
|
209
|
-
// Append solution as new line
|
|
210
|
-
Bash(`echo '${JSON.stringify(item.solution)}' >> "${solutionPath}"`);
|
|
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)`);
|
|
211
197
|
}
|
|
212
198
|
|
|
213
|
-
//
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
});
|
|
199
|
+
// Collect pending selections for Phase 3
|
|
200
|
+
pendingSelections.push(...(summary.pending_selection || []));
|
|
201
|
+
|
|
202
|
+
// Show conflicts
|
|
203
|
+
if (summary.conflicts?.length > 0) {
|
|
204
|
+
console.log(`⚠ Conflicts: ${summary.conflicts.map(c => c.file).join(', ')}`);
|
|
219
205
|
}
|
|
220
206
|
|
|
221
207
|
updateTodo(`Plan batch ${batchIndex + 1}`, 'completed');
|
|
222
208
|
}
|
|
223
209
|
```
|
|
224
210
|
|
|
225
|
-
### Phase 3: Solution
|
|
211
|
+
### Phase 3: Multi-Solution Selection
|
|
226
212
|
|
|
227
213
|
```javascript
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
// Auto-bind single solution
|
|
250
|
-
selectedSolId = solutions[0].id;
|
|
251
|
-
console.log(`✓ Auto-bound ${selectedSolId} to ${issue.id} (${solutions[0].tasks?.length || 0} tasks)`);
|
|
252
|
-
} else {
|
|
253
|
-
// Multiple solutions - ask user
|
|
254
|
-
const answer = AskUserQuestion({
|
|
255
|
-
questions: [{
|
|
256
|
-
question: `Select solution for ${issue.id}:`,
|
|
257
|
-
header: issue.id,
|
|
258
|
-
multiSelect: false,
|
|
259
|
-
options: solutions.map(s => ({
|
|
260
|
-
label: `${s.id}: ${s.description || 'Solution'}`,
|
|
261
|
-
description: `${s.tasks?.length || 0} tasks`
|
|
262
|
-
}))
|
|
263
|
-
}]
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
selectedSolId = extractSelectedSolutionId(answer);
|
|
267
|
-
console.log(`✓ Bound ${selectedSolId} to ${issue.id}`);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Update issue in allIssuesUpdated
|
|
271
|
-
const issueIndex = allIssuesUpdated.findIndex(i => i.id === issue.id);
|
|
272
|
-
if (issueIndex !== -1) {
|
|
273
|
-
allIssuesUpdated[issueIndex].bound_solution_id = selectedSolId;
|
|
274
|
-
allIssuesUpdated[issueIndex].status = 'planned';
|
|
275
|
-
allIssuesUpdated[issueIndex].planned_at = new Date().toISOString();
|
|
276
|
-
allIssuesUpdated[issueIndex].updated_at = new Date().toISOString();
|
|
214
|
+
// Only handle issues where agent generated multiple solutions
|
|
215
|
+
if (pendingSelections.length > 0) {
|
|
216
|
+
const answer = AskUserQuestion({
|
|
217
|
+
questions: pendingSelections.map(({ issue_id, solutions }) => ({
|
|
218
|
+
question: `Select solution for ${issue_id}:`,
|
|
219
|
+
header: issue_id,
|
|
220
|
+
multiSelect: false,
|
|
221
|
+
options: solutions.map(s => ({
|
|
222
|
+
label: `${s.id} (${s.task_count} tasks)`,
|
|
223
|
+
description: s.description
|
|
224
|
+
}))
|
|
225
|
+
}))
|
|
226
|
+
});
|
|
227
|
+
|
|
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
|
+
}
|
|
277
235
|
}
|
|
278
|
-
|
|
279
|
-
// Mark solution as bound in solutions file
|
|
280
|
-
const updatedSolutions = solutions.map(s => ({
|
|
281
|
-
...s,
|
|
282
|
-
is_bound: s.id === selectedSolId,
|
|
283
|
-
bound_at: s.id === selectedSolId ? new Date().toISOString() : s.bound_at
|
|
284
|
-
}));
|
|
285
|
-
Write(solPath, updatedSolutions.map(s => JSON.stringify(s)).join('\n'));
|
|
286
236
|
}
|
|
287
|
-
|
|
288
|
-
// Write updated issues.jsonl
|
|
289
|
-
Write(issuesPath, allIssuesUpdated.map(i => JSON.stringify(i)).join('\n'));
|
|
290
237
|
```
|
|
291
238
|
|
|
292
239
|
### Phase 4: Summary
|
|
293
240
|
|
|
294
241
|
```javascript
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
**Issues Planned**: ${issues.length}
|
|
299
|
-
|
|
300
|
-
### Bound Solutions
|
|
301
|
-
${issues.map(i => {
|
|
302
|
-
const issue = allIssuesUpdated.find(a => a.id === i.id);
|
|
303
|
-
return issue?.bound_solution_id
|
|
304
|
-
? `✓ ${i.id}: ${issue.bound_solution_id}`
|
|
305
|
-
: `○ ${i.id}: No solution bound`;
|
|
306
|
-
}).join('\n')}
|
|
307
|
-
|
|
308
|
-
### Next Steps
|
|
309
|
-
1. Review: \`ccw issue status <issue-id>\`
|
|
310
|
-
2. Form queue: \`/issue:queue\`
|
|
311
|
-
3. Execute: \`/issue:execute\`
|
|
312
|
-
`);
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
## Solution Format (Closed-Loop Tasks)
|
|
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;
|
|
316
245
|
|
|
317
|
-
|
|
246
|
+
console.log(`
|
|
247
|
+
## Done: ${issueIds.length} issues → ${plannedCount} planned
|
|
318
248
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
"id": "SOL-20251226-001",
|
|
322
|
-
"description": "Direct Implementation",
|
|
323
|
-
"tasks": [
|
|
324
|
-
{
|
|
325
|
-
"id": "T1",
|
|
326
|
-
"title": "Create auth middleware",
|
|
327
|
-
"scope": "src/middleware/",
|
|
328
|
-
"action": "Create",
|
|
329
|
-
"description": "Create JWT validation middleware",
|
|
330
|
-
"modification_points": [
|
|
331
|
-
{ "file": "src/middleware/auth.ts", "target": "new file", "change": "Create middleware" }
|
|
332
|
-
],
|
|
333
|
-
|
|
334
|
-
"implementation": [
|
|
335
|
-
"Create auth.ts file in src/middleware/",
|
|
336
|
-
"Implement JWT token validation using jsonwebtoken",
|
|
337
|
-
"Add error handling for invalid/expired tokens",
|
|
338
|
-
"Export middleware function"
|
|
339
|
-
],
|
|
340
|
-
|
|
341
|
-
"test": {
|
|
342
|
-
"unit": [
|
|
343
|
-
"Test valid token passes through",
|
|
344
|
-
"Test invalid token returns 401",
|
|
345
|
-
"Test expired token returns 401",
|
|
346
|
-
"Test missing token returns 401"
|
|
347
|
-
],
|
|
348
|
-
"commands": [
|
|
349
|
-
"npm test -- --grep 'auth middleware'",
|
|
350
|
-
"npm run test:coverage -- src/middleware/auth.ts"
|
|
351
|
-
],
|
|
352
|
-
"coverage_target": 80
|
|
353
|
-
},
|
|
354
|
-
|
|
355
|
-
"regression": [
|
|
356
|
-
"npm test -- --grep 'protected routes'",
|
|
357
|
-
"npm run test:integration -- auth"
|
|
358
|
-
],
|
|
359
|
-
|
|
360
|
-
"acceptance": {
|
|
361
|
-
"criteria": [
|
|
362
|
-
"Middleware validates JWT tokens successfully",
|
|
363
|
-
"Returns 401 for invalid or missing tokens",
|
|
364
|
-
"Passes decoded token to request context"
|
|
365
|
-
],
|
|
366
|
-
"verification": [
|
|
367
|
-
"curl -H 'Authorization: Bearer valid_token' /api/protected → 200",
|
|
368
|
-
"curl /api/protected → 401",
|
|
369
|
-
"curl -H 'Authorization: Bearer invalid' /api/protected → 401"
|
|
370
|
-
]
|
|
371
|
-
},
|
|
372
|
-
|
|
373
|
-
"commit": {
|
|
374
|
-
"type": "feat",
|
|
375
|
-
"scope": "auth",
|
|
376
|
-
"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",
|
|
377
|
-
"breaking": false
|
|
378
|
-
},
|
|
379
|
-
|
|
380
|
-
"depends_on": [],
|
|
381
|
-
"estimated_minutes": 30,
|
|
382
|
-
"executor": "codex"
|
|
383
|
-
}
|
|
384
|
-
],
|
|
385
|
-
"exploration_context": {
|
|
386
|
-
"relevant_files": ["src/config/auth.ts"],
|
|
387
|
-
"patterns": "Follow existing middleware pattern"
|
|
388
|
-
},
|
|
389
|
-
"is_bound": true,
|
|
390
|
-
"created_at": "2025-12-26T10:00:00Z",
|
|
391
|
-
"bound_at": "2025-12-26T10:05:00Z"
|
|
392
|
-
}
|
|
249
|
+
Next: \`/issue:queue\` → \`/issue:execute\`
|
|
250
|
+
`);
|
|
393
251
|
```
|
|
394
252
|
|
|
395
253
|
## Error Handling
|
|
@@ -402,17 +260,6 @@ Each solution line in `solutions/{issue-id}.jsonl`:
|
|
|
402
260
|
| User cancels selection | Skip issue, continue with others |
|
|
403
261
|
| File conflicts | Agent detects and suggests resolution order |
|
|
404
262
|
|
|
405
|
-
## Agent Integration
|
|
406
|
-
|
|
407
|
-
The command uses `issue-plan-agent` which:
|
|
408
|
-
1. Performs ACE semantic search per issue
|
|
409
|
-
2. Identifies modification points and patterns
|
|
410
|
-
3. Generates task breakdown with dependencies
|
|
411
|
-
4. Detects cross-issue file conflicts
|
|
412
|
-
5. Outputs solution JSON for registration
|
|
413
|
-
|
|
414
|
-
See `.claude/agents/issue-plan-agent.md` for agent specification.
|
|
415
|
-
|
|
416
263
|
## Related Commands
|
|
417
264
|
|
|
418
265
|
- `/issue:queue` - Form execution queue from bound solutions
|