claude-code-workflow 7.2.14 → 7.2.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/commands/workflow/analyze-with-file.md +7 -0
- package/.codex/skills/analyze-with-file/SKILL.md +1181 -1182
- package/.codex/skills/brainstorm/SKILL.md +723 -725
- package/.codex/skills/brainstorm-with-file/SKILL.md +10 -5
- package/.codex/skills/clean/SKILL.md +33 -26
- package/.codex/skills/collaborative-plan-with-file/SKILL.md +830 -831
- package/.codex/skills/csv-wave-pipeline/SKILL.md +906 -906
- package/.codex/skills/issue-discover/SKILL.md +57 -50
- package/.codex/skills/issue-discover/phases/01-issue-new.md +18 -11
- package/.codex/skills/issue-discover/phases/02-discover.md +31 -26
- package/.codex/skills/issue-discover/phases/03-discover-by-prompt.md +13 -11
- package/.codex/skills/issue-discover/phases/04-quick-execute.md +32 -27
- package/.codex/skills/parallel-dev-cycle/SKILL.md +402 -402
- package/.codex/skills/project-documentation-workflow/SKILL.md +13 -3
- package/.codex/skills/roadmap-with-file/SKILL.md +901 -897
- package/.codex/skills/session-sync/SKILL.md +222 -212
- package/.codex/skills/spec-add/SKILL.md +620 -613
- package/.codex/skills/spec-generator/SKILL.md +2 -2
- package/.codex/skills/spec-generator/phases/01-5-requirement-clarification.md +10 -10
- package/.codex/skills/spec-generator/phases/01-discovery.md +11 -18
- package/.codex/skills/spec-generator/phases/02-product-brief.md +5 -5
- package/.codex/skills/spec-generator/phases/03-requirements.md +7 -7
- package/.codex/skills/spec-generator/phases/04-architecture.md +4 -4
- package/.codex/skills/spec-generator/phases/05-epics-stories.md +5 -6
- package/.codex/skills/spec-generator/phases/06-readiness-check.md +10 -17
- package/.codex/skills/spec-generator/phases/07-issue-export.md +326 -329
- package/.codex/skills/spec-setup/SKILL.md +669 -657
- package/.codex/skills/team-arch-opt/SKILL.md +50 -50
- package/.codex/skills/team-arch-opt/agents/completion-handler.md +3 -3
- package/.codex/skills/team-brainstorm/SKILL.md +724 -725
- package/.codex/skills/team-coordinate/SKILL.md +51 -51
- package/.codex/skills/team-coordinate/agents/completion-handler.md +3 -3
- package/.codex/skills/team-coordinate/agents/plan-reviewer.md +4 -4
- package/.codex/skills/team-designer/SKILL.md +691 -691
- package/.codex/skills/team-designer/agents/requirement-clarifier.md +11 -12
- package/.codex/skills/team-executor/SKILL.md +45 -45
- package/.codex/skills/team-frontend/SKILL.md +45 -45
- package/.codex/skills/team-frontend/agents/completion-handler.md +3 -3
- package/.codex/skills/team-frontend/agents/qa-gate-reviewer.md +4 -4
- package/.codex/skills/team-frontend-debug/SKILL.md +50 -50
- package/.codex/skills/team-frontend-debug/agents/completion-handler.md +3 -3
- package/.codex/skills/team-frontend-debug/agents/conditional-skip-gate.md +4 -4
- package/.codex/skills/team-issue/SKILL.md +751 -740
- package/.codex/skills/team-iterdev/SKILL.md +825 -826
- package/.codex/skills/team-lifecycle-v4/SKILL.md +775 -775
- package/.codex/skills/team-lifecycle-v4/agents/quality-gate.md +165 -165
- package/.codex/skills/team-lifecycle-v4/agents/requirement-clarifier.md +163 -163
- package/.codex/skills/team-perf-opt/SKILL.md +50 -50
- package/.codex/skills/team-perf-opt/agents/completion-handler.md +3 -3
- package/.codex/skills/team-planex-v2/SKILL.md +652 -637
- package/.codex/skills/team-quality-assurance/SKILL.md +51 -52
- package/.codex/skills/team-review/SKILL.md +40 -40
- package/.codex/skills/team-roadmap-dev/SKILL.md +51 -51
- package/.codex/skills/team-roadmap-dev/agents/roadmap-discusser.md +8 -8
- package/.codex/skills/team-tech-debt/SKILL.md +50 -50
- package/.codex/skills/team-tech-debt/agents/plan-approver.md +5 -5
- package/.codex/skills/team-testing/SKILL.md +51 -52
- package/.codex/skills/team-uidesign/SKILL.md +40 -40
- package/.codex/skills/team-uidesign/agents/completion-handler.md +177 -177
- package/.codex/skills/team-ultra-analyze/SKILL.md +786 -787
- package/.codex/skills/team-ultra-analyze/agents/discussion-feedback.md +8 -8
- package/.codex/skills/team-ux-improve/SKILL.md +51 -52
- package/.codex/skills/team-ux-improve/agents/ux-designer.md +2 -2
- package/.codex/skills/team-ux-improve/agents/ux-explorer.md +1 -1
- package/.codex/skills/unified-execute-with-file/SKILL.md +797 -796
- package/.codex/skills/workflow-execute/SKILL.md +1117 -1118
- package/.codex/skills/workflow-lite-planex/SKILL.md +1144 -1141
- package/.codex/skills/workflow-plan/SKILL.md +631 -636
- package/.codex/skills/workflow-tdd-plan/SKILL.md +753 -759
- package/.codex/skills/workflow-test-fix-cycle/SKILL.md +402 -392
- package/README.md +25 -0
- package/ccw/dist/commands/install.d.ts.map +1 -1
- package/ccw/dist/commands/install.js +12 -0
- package/ccw/dist/commands/install.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,329 +1,326 @@
|
|
|
1
|
-
# Phase 7: Issue Export
|
|
2
|
-
|
|
3
|
-
Map specification Epics to issues, create them via `ccw issue create`, and generate an export report with spec document links.
|
|
4
|
-
|
|
5
|
-
> **Execution Mode: Inline**
|
|
6
|
-
> This phase runs in the main orchestrator context (not delegated to agent) for direct access to `ccw issue create` CLI and interactive handoff options.
|
|
7
|
-
|
|
8
|
-
## Objective
|
|
9
|
-
|
|
10
|
-
- Read all EPIC-*.md files from Phase 5 output
|
|
11
|
-
- Assign waves: MVP epics → wave-1, non-MVP → wave-2
|
|
12
|
-
- Create one issue per Epic via `ccw issue create`
|
|
13
|
-
- Map Epic dependencies to issue dependencies
|
|
14
|
-
- Generate issue-export-report.md with mapping table and spec links
|
|
15
|
-
- Present handoff options for execution
|
|
16
|
-
|
|
17
|
-
## Input
|
|
18
|
-
|
|
19
|
-
- Dependency: `{workDir}/epics/_index.md` (and individual `EPIC-*.md` files)
|
|
20
|
-
- Reference: `{workDir}/readiness-report.md`, `{workDir}/spec-config.json`
|
|
21
|
-
- Reference: `{workDir}/product-brief.md`, `{workDir}/requirements/_index.md`, `{workDir}/architecture/_index.md`
|
|
22
|
-
|
|
23
|
-
## Execution Steps
|
|
24
|
-
|
|
25
|
-
### Step 1: Load Epic Files
|
|
26
|
-
|
|
27
|
-
```javascript
|
|
28
|
-
const specConfig = JSON.parse(Read(`${workDir}/spec-config.json`));
|
|
29
|
-
const epicFiles = Glob(`${workDir}/epics/EPIC-*.md`);
|
|
30
|
-
const epicsIndex = Read(`${workDir}/epics/_index.md`);
|
|
31
|
-
|
|
32
|
-
// Parse each Epic file
|
|
33
|
-
const epics = epicFiles.map(epicFile => {
|
|
34
|
-
const content = Read(epicFile);
|
|
35
|
-
const fm = parseFrontmatter(content);
|
|
36
|
-
const title = extractTitle(content);
|
|
37
|
-
const description = extractSection(content, "Description");
|
|
38
|
-
const stories = extractSection(content, "Stories");
|
|
39
|
-
const reqRefs = extractSection(content, "Requirements");
|
|
40
|
-
const adrRefs = extractSection(content, "Architecture");
|
|
41
|
-
const deps = fm.dependencies || [];
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
file: epicFile,
|
|
45
|
-
id: fm.id, // e.g., EPIC-001
|
|
46
|
-
title,
|
|
47
|
-
description,
|
|
48
|
-
stories,
|
|
49
|
-
reqRefs,
|
|
50
|
-
adrRefs,
|
|
51
|
-
priority: fm.priority,
|
|
52
|
-
mvp: fm.mvp || false,
|
|
53
|
-
dependencies: deps, // other EPIC IDs this depends on
|
|
54
|
-
size: fm.size
|
|
55
|
-
};
|
|
56
|
-
});
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Step 2: Wave Assignment
|
|
60
|
-
|
|
61
|
-
```javascript
|
|
62
|
-
const epicWaves = epics.map(epic => ({
|
|
63
|
-
...epic,
|
|
64
|
-
wave: epic.mvp ? 1 : 2
|
|
65
|
-
}));
|
|
66
|
-
|
|
67
|
-
// Log wave assignment
|
|
68
|
-
const wave1 = epicWaves.filter(e => e.wave === 1);
|
|
69
|
-
const wave2 = epicWaves.filter(e => e.wave === 2);
|
|
70
|
-
// wave-1: MVP epics (must-have, core functionality)
|
|
71
|
-
// wave-2: Post-MVP epics (should-have, enhancements)
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Step 3: Issue Creation Loop
|
|
75
|
-
|
|
76
|
-
```javascript
|
|
77
|
-
const createdIssues = [];
|
|
78
|
-
const epicToIssue = {}; // EPIC-ID -> Issue ID mapping
|
|
79
|
-
|
|
80
|
-
for (const epic of epicWaves) {
|
|
81
|
-
// Build issue JSON matching roadmap-with-file schema
|
|
82
|
-
const issueData = {
|
|
83
|
-
title: `[${specConfig.session_id}] ${epic.title}`,
|
|
84
|
-
status: "pending",
|
|
85
|
-
priority: epic.wave === 1 ? 2 : 3, // wave-1 = higher priority
|
|
86
|
-
context: `## ${epic.title}
|
|
87
|
-
|
|
88
|
-
${epic.description}
|
|
89
|
-
|
|
90
|
-
## Stories
|
|
91
|
-
${epic.stories}
|
|
92
|
-
|
|
93
|
-
## Spec References
|
|
94
|
-
- Epic: ${epic.file}
|
|
95
|
-
- Requirements: ${epic.reqRefs}
|
|
96
|
-
- Architecture: ${epic.adrRefs}
|
|
97
|
-
- Product Brief: ${workDir}/product-brief.md
|
|
98
|
-
- Full Spec: ${workDir}/`,
|
|
99
|
-
source: "text",
|
|
100
|
-
tags: [
|
|
101
|
-
"spec-generated",
|
|
102
|
-
`spec:${specConfig.session_id}`,
|
|
103
|
-
`wave-${epic.wave}`,
|
|
104
|
-
epic.mvp ? "mvp" : "post-mvp",
|
|
105
|
-
`epic:${epic.id}`
|
|
106
|
-
],
|
|
107
|
-
extended_context: {
|
|
108
|
-
notes: {
|
|
109
|
-
session: specConfig.session_id,
|
|
110
|
-
spec_dir: workDir,
|
|
111
|
-
source_epic: epic.id,
|
|
112
|
-
wave: epic.wave,
|
|
113
|
-
depends_on_issues: [], // Filled in Step 4
|
|
114
|
-
spec_documents: {
|
|
115
|
-
product_brief: `${workDir}/product-brief.md`,
|
|
116
|
-
requirements: `${workDir}/requirements/_index.md`,
|
|
117
|
-
architecture: `${workDir}/architecture/_index.md`,
|
|
118
|
-
epic: epic.file
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
lifecycle_requirements: {
|
|
123
|
-
test_strategy: "acceptance",
|
|
124
|
-
regression_scope: "affected",
|
|
125
|
-
acceptance_type: "manual",
|
|
126
|
-
commit_strategy: "per-epic"
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
// Create issue via ccw issue create (pipe JSON to avoid shell escaping)
|
|
131
|
-
const result = Bash(`echo '${JSON.stringify(issueData)}' | ccw issue create`);
|
|
132
|
-
|
|
133
|
-
// Parse returned issue ID
|
|
134
|
-
const issueId = JSON.parse(result).id; // e.g., ISS-20260308-001
|
|
135
|
-
epicToIssue[epic.id] = issueId;
|
|
136
|
-
|
|
137
|
-
createdIssues.push({
|
|
138
|
-
epic_id: epic.id,
|
|
139
|
-
epic_title: epic.title,
|
|
140
|
-
issue_id: issueId,
|
|
141
|
-
wave: epic.wave,
|
|
142
|
-
priority: issueData.priority,
|
|
143
|
-
mvp: epic.mvp
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Step 4: Epic Dependency → Issue Dependency Mapping
|
|
149
|
-
|
|
150
|
-
```javascript
|
|
151
|
-
// Map EPIC dependencies to Issue dependencies
|
|
152
|
-
for (const epic of epicWaves) {
|
|
153
|
-
if (epic.dependencies.length === 0) continue;
|
|
154
|
-
|
|
155
|
-
const issueId = epicToIssue[epic.id];
|
|
156
|
-
const depIssueIds = epic.dependencies
|
|
157
|
-
.map(depEpicId => epicToIssue[depEpicId])
|
|
158
|
-
.filter(Boolean);
|
|
159
|
-
|
|
160
|
-
if (depIssueIds.length > 0) {
|
|
161
|
-
// Update issue's extended_context.notes.depends_on_issues
|
|
162
|
-
// This is informational — actual dependency enforcement is in execution phase
|
|
163
|
-
// Note: ccw issue create already created the issue; dependency info is in the context
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Step 5: Generate issue-export-report.md
|
|
169
|
-
|
|
170
|
-
```javascript
|
|
171
|
-
const timestamp = new Date().toISOString();
|
|
172
|
-
|
|
173
|
-
const reportContent = `---
|
|
174
|
-
session_id: ${specConfig.session_id}
|
|
175
|
-
phase: 7
|
|
176
|
-
document_type: issue-export-report
|
|
177
|
-
status: complete
|
|
178
|
-
generated_at: ${timestamp}
|
|
179
|
-
stepsCompleted: ["load-epics", "wave-assignment", "issue-creation", "dependency-mapping", "report-generation"]
|
|
180
|
-
version: 1
|
|
181
|
-
dependencies:
|
|
182
|
-
- epics/_index.md
|
|
183
|
-
- readiness-report.md
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
# Issue Export Report
|
|
187
|
-
|
|
188
|
-
## Summary
|
|
189
|
-
|
|
190
|
-
- **Session**: ${specConfig.session_id}
|
|
191
|
-
- **Issues Created**: ${createdIssues.length}
|
|
192
|
-
- **Wave 1 (MVP)**: ${wave1.length} issues
|
|
193
|
-
- **Wave 2 (Post-MVP)**: ${wave2.length} issues
|
|
194
|
-
- **Export Date**: ${timestamp}
|
|
195
|
-
|
|
196
|
-
## Issue Mapping
|
|
197
|
-
|
|
198
|
-
| Epic ID | Epic Title | Issue ID | Wave | Priority | MVP |
|
|
199
|
-
|---------|-----------|----------|------|----------|-----|
|
|
200
|
-
${createdIssues.map(i =>
|
|
201
|
-
`| ${i.epic_id} | ${i.epic_title} | ${i.issue_id} | ${i.wave} | ${i.priority} | ${i.mvp ? 'Yes' : 'No'} |`
|
|
202
|
-
).join('\n')}
|
|
203
|
-
|
|
204
|
-
## Spec Document Links
|
|
205
|
-
|
|
206
|
-
| Document | Path | Description |
|
|
207
|
-
|----------|------|-------------|
|
|
208
|
-
| Product Brief | ${workDir}/product-brief.md | Vision, goals, scope |
|
|
209
|
-
| Requirements | ${workDir}/requirements/_index.md | Functional + non-functional requirements |
|
|
210
|
-
| Architecture | ${workDir}/architecture/_index.md | Components, ADRs, tech stack |
|
|
211
|
-
| Epics | ${workDir}/epics/_index.md | Epic/Story breakdown |
|
|
212
|
-
| Readiness Report | ${workDir}/readiness-report.md | Quality validation |
|
|
213
|
-
| Spec Summary | ${workDir}/spec-summary.md | Executive summary |
|
|
214
|
-
|
|
215
|
-
## Dependency Map
|
|
216
|
-
|
|
217
|
-
| Issue ID | Depends On |
|
|
218
|
-
|----------|-----------|
|
|
219
|
-
${createdIssues.map(i => {
|
|
220
|
-
const epic = epicWaves.find(e => e.id === i.epic_id);
|
|
221
|
-
const deps = (epic.dependencies || []).map(d => epicToIssue[d]).filter(Boolean);
|
|
222
|
-
return `| ${i.issue_id} | ${deps.length > 0 ? deps.join(', ') : 'None'} |`;
|
|
223
|
-
}).join('\n')}
|
|
224
|
-
|
|
225
|
-
## Next Steps
|
|
226
|
-
|
|
227
|
-
1. **team-planex**: Execute all issues via coordinated team workflow
|
|
228
|
-
2. **Wave 1 only**: Execute MVP issues first (${wave1.length} issues)
|
|
229
|
-
3. **View issues**: Browse created issues via \`ccw issue list --tag spec:${specConfig.session_id}\`
|
|
230
|
-
4. **Manual review**: Review individual issues before execution
|
|
231
|
-
`;
|
|
232
|
-
|
|
233
|
-
Write(`${workDir}/issue-export-report.md`, reportContent);
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
### Step 6: Update spec-config.json
|
|
237
|
-
|
|
238
|
-
```javascript
|
|
239
|
-
specConfig.issue_ids = createdIssues.map(i => i.issue_id);
|
|
240
|
-
specConfig.issues_created = createdIssues.length;
|
|
241
|
-
specConfig.phasesCompleted.push({
|
|
242
|
-
phase: 7,
|
|
243
|
-
name: "issue-export",
|
|
244
|
-
output_file: "issue-export-report.md",
|
|
245
|
-
issues_created: createdIssues.length,
|
|
246
|
-
wave_1_count: wave1.length,
|
|
247
|
-
wave_2_count: wave2.length,
|
|
248
|
-
completed_at: timestamp
|
|
249
|
-
});
|
|
250
|
-
Write(`${workDir}/spec-config.json`, JSON.stringify(specConfig, null, 2));
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### Step 7: Handoff Options
|
|
254
|
-
|
|
255
|
-
```javascript
|
|
256
|
-
|
|
257
|
-
questions: [
|
|
258
|
-
{
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
options: [
|
|
263
|
-
{
|
|
264
|
-
label: "Execute via team-planex",
|
|
265
|
-
description: `Execute all ${createdIssues.length} issues with coordinated team workflow`
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
label: "Wave 1 only",
|
|
269
|
-
description: `Execute ${wave1.length} MVP issues first`
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
label: "
|
|
273
|
-
description: "
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
- [ ]
|
|
309
|
-
- [ ]
|
|
310
|
-
- [ ]
|
|
311
|
-
- [ ]
|
|
312
|
-
- [ ]
|
|
313
|
-
- [ ]
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
|
321
|
-
|
|
322
|
-
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
## Completion
|
|
328
|
-
|
|
329
|
-
Phase 7 is the final phase. The specification package has been fully converted to executable issues ready for team-planex or manual execution.
|
|
1
|
+
# Phase 7: Issue Export
|
|
2
|
+
|
|
3
|
+
Map specification Epics to issues, create them via `ccw issue create`, and generate an export report with spec document links.
|
|
4
|
+
|
|
5
|
+
> **Execution Mode: Inline**
|
|
6
|
+
> This phase runs in the main orchestrator context (not delegated to agent) for direct access to `ccw issue create` CLI and interactive handoff options.
|
|
7
|
+
|
|
8
|
+
## Objective
|
|
9
|
+
|
|
10
|
+
- Read all EPIC-*.md files from Phase 5 output
|
|
11
|
+
- Assign waves: MVP epics → wave-1, non-MVP → wave-2
|
|
12
|
+
- Create one issue per Epic via `ccw issue create`
|
|
13
|
+
- Map Epic dependencies to issue dependencies
|
|
14
|
+
- Generate issue-export-report.md with mapping table and spec links
|
|
15
|
+
- Present handoff options for execution
|
|
16
|
+
|
|
17
|
+
## Input
|
|
18
|
+
|
|
19
|
+
- Dependency: `{workDir}/epics/_index.md` (and individual `EPIC-*.md` files)
|
|
20
|
+
- Reference: `{workDir}/readiness-report.md`, `{workDir}/spec-config.json`
|
|
21
|
+
- Reference: `{workDir}/product-brief.md`, `{workDir}/requirements/_index.md`, `{workDir}/architecture/_index.md`
|
|
22
|
+
|
|
23
|
+
## Execution Steps
|
|
24
|
+
|
|
25
|
+
### Step 1: Load Epic Files
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
const specConfig = JSON.parse(Read(`${workDir}/spec-config.json`));
|
|
29
|
+
const epicFiles = Glob(`${workDir}/epics/EPIC-*.md`);
|
|
30
|
+
const epicsIndex = Read(`${workDir}/epics/_index.md`);
|
|
31
|
+
|
|
32
|
+
// Parse each Epic file
|
|
33
|
+
const epics = epicFiles.map(epicFile => {
|
|
34
|
+
const content = Read(epicFile);
|
|
35
|
+
const fm = parseFrontmatter(content);
|
|
36
|
+
const title = extractTitle(content);
|
|
37
|
+
const description = extractSection(content, "Description");
|
|
38
|
+
const stories = extractSection(content, "Stories");
|
|
39
|
+
const reqRefs = extractSection(content, "Requirements");
|
|
40
|
+
const adrRefs = extractSection(content, "Architecture");
|
|
41
|
+
const deps = fm.dependencies || [];
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
file: epicFile,
|
|
45
|
+
id: fm.id, // e.g., EPIC-001
|
|
46
|
+
title,
|
|
47
|
+
description,
|
|
48
|
+
stories,
|
|
49
|
+
reqRefs,
|
|
50
|
+
adrRefs,
|
|
51
|
+
priority: fm.priority,
|
|
52
|
+
mvp: fm.mvp || false,
|
|
53
|
+
dependencies: deps, // other EPIC IDs this depends on
|
|
54
|
+
size: fm.size
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Step 2: Wave Assignment
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
const epicWaves = epics.map(epic => ({
|
|
63
|
+
...epic,
|
|
64
|
+
wave: epic.mvp ? 1 : 2
|
|
65
|
+
}));
|
|
66
|
+
|
|
67
|
+
// Log wave assignment
|
|
68
|
+
const wave1 = epicWaves.filter(e => e.wave === 1);
|
|
69
|
+
const wave2 = epicWaves.filter(e => e.wave === 2);
|
|
70
|
+
// wave-1: MVP epics (must-have, core functionality)
|
|
71
|
+
// wave-2: Post-MVP epics (should-have, enhancements)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Step 3: Issue Creation Loop
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
const createdIssues = [];
|
|
78
|
+
const epicToIssue = {}; // EPIC-ID -> Issue ID mapping
|
|
79
|
+
|
|
80
|
+
for (const epic of epicWaves) {
|
|
81
|
+
// Build issue JSON matching roadmap-with-file schema
|
|
82
|
+
const issueData = {
|
|
83
|
+
title: `[${specConfig.session_id}] ${epic.title}`,
|
|
84
|
+
status: "pending",
|
|
85
|
+
priority: epic.wave === 1 ? 2 : 3, // wave-1 = higher priority
|
|
86
|
+
context: `## ${epic.title}
|
|
87
|
+
|
|
88
|
+
${epic.description}
|
|
89
|
+
|
|
90
|
+
## Stories
|
|
91
|
+
${epic.stories}
|
|
92
|
+
|
|
93
|
+
## Spec References
|
|
94
|
+
- Epic: ${epic.file}
|
|
95
|
+
- Requirements: ${epic.reqRefs}
|
|
96
|
+
- Architecture: ${epic.adrRefs}
|
|
97
|
+
- Product Brief: ${workDir}/product-brief.md
|
|
98
|
+
- Full Spec: ${workDir}/`,
|
|
99
|
+
source: "text",
|
|
100
|
+
tags: [
|
|
101
|
+
"spec-generated",
|
|
102
|
+
`spec:${specConfig.session_id}`,
|
|
103
|
+
`wave-${epic.wave}`,
|
|
104
|
+
epic.mvp ? "mvp" : "post-mvp",
|
|
105
|
+
`epic:${epic.id}`
|
|
106
|
+
],
|
|
107
|
+
extended_context: {
|
|
108
|
+
notes: {
|
|
109
|
+
session: specConfig.session_id,
|
|
110
|
+
spec_dir: workDir,
|
|
111
|
+
source_epic: epic.id,
|
|
112
|
+
wave: epic.wave,
|
|
113
|
+
depends_on_issues: [], // Filled in Step 4
|
|
114
|
+
spec_documents: {
|
|
115
|
+
product_brief: `${workDir}/product-brief.md`,
|
|
116
|
+
requirements: `${workDir}/requirements/_index.md`,
|
|
117
|
+
architecture: `${workDir}/architecture/_index.md`,
|
|
118
|
+
epic: epic.file
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
lifecycle_requirements: {
|
|
123
|
+
test_strategy: "acceptance",
|
|
124
|
+
regression_scope: "affected",
|
|
125
|
+
acceptance_type: "manual",
|
|
126
|
+
commit_strategy: "per-epic"
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// Create issue via ccw issue create (pipe JSON to avoid shell escaping)
|
|
131
|
+
const result = Bash(`echo '${JSON.stringify(issueData)}' | ccw issue create`);
|
|
132
|
+
|
|
133
|
+
// Parse returned issue ID
|
|
134
|
+
const issueId = JSON.parse(result).id; // e.g., ISS-20260308-001
|
|
135
|
+
epicToIssue[epic.id] = issueId;
|
|
136
|
+
|
|
137
|
+
createdIssues.push({
|
|
138
|
+
epic_id: epic.id,
|
|
139
|
+
epic_title: epic.title,
|
|
140
|
+
issue_id: issueId,
|
|
141
|
+
wave: epic.wave,
|
|
142
|
+
priority: issueData.priority,
|
|
143
|
+
mvp: epic.mvp
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Step 4: Epic Dependency → Issue Dependency Mapping
|
|
149
|
+
|
|
150
|
+
```javascript
|
|
151
|
+
// Map EPIC dependencies to Issue dependencies
|
|
152
|
+
for (const epic of epicWaves) {
|
|
153
|
+
if (epic.dependencies.length === 0) continue;
|
|
154
|
+
|
|
155
|
+
const issueId = epicToIssue[epic.id];
|
|
156
|
+
const depIssueIds = epic.dependencies
|
|
157
|
+
.map(depEpicId => epicToIssue[depEpicId])
|
|
158
|
+
.filter(Boolean);
|
|
159
|
+
|
|
160
|
+
if (depIssueIds.length > 0) {
|
|
161
|
+
// Update issue's extended_context.notes.depends_on_issues
|
|
162
|
+
// This is informational — actual dependency enforcement is in execution phase
|
|
163
|
+
// Note: ccw issue create already created the issue; dependency info is in the context
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Step 5: Generate issue-export-report.md
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
const timestamp = new Date().toISOString();
|
|
172
|
+
|
|
173
|
+
const reportContent = `---
|
|
174
|
+
session_id: ${specConfig.session_id}
|
|
175
|
+
phase: 7
|
|
176
|
+
document_type: issue-export-report
|
|
177
|
+
status: complete
|
|
178
|
+
generated_at: ${timestamp}
|
|
179
|
+
stepsCompleted: ["load-epics", "wave-assignment", "issue-creation", "dependency-mapping", "report-generation"]
|
|
180
|
+
version: 1
|
|
181
|
+
dependencies:
|
|
182
|
+
- epics/_index.md
|
|
183
|
+
- readiness-report.md
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
# Issue Export Report
|
|
187
|
+
|
|
188
|
+
## Summary
|
|
189
|
+
|
|
190
|
+
- **Session**: ${specConfig.session_id}
|
|
191
|
+
- **Issues Created**: ${createdIssues.length}
|
|
192
|
+
- **Wave 1 (MVP)**: ${wave1.length} issues
|
|
193
|
+
- **Wave 2 (Post-MVP)**: ${wave2.length} issues
|
|
194
|
+
- **Export Date**: ${timestamp}
|
|
195
|
+
|
|
196
|
+
## Issue Mapping
|
|
197
|
+
|
|
198
|
+
| Epic ID | Epic Title | Issue ID | Wave | Priority | MVP |
|
|
199
|
+
|---------|-----------|----------|------|----------|-----|
|
|
200
|
+
${createdIssues.map(i =>
|
|
201
|
+
`| ${i.epic_id} | ${i.epic_title} | ${i.issue_id} | ${i.wave} | ${i.priority} | ${i.mvp ? 'Yes' : 'No'} |`
|
|
202
|
+
).join('\n')}
|
|
203
|
+
|
|
204
|
+
## Spec Document Links
|
|
205
|
+
|
|
206
|
+
| Document | Path | Description |
|
|
207
|
+
|----------|------|-------------|
|
|
208
|
+
| Product Brief | ${workDir}/product-brief.md | Vision, goals, scope |
|
|
209
|
+
| Requirements | ${workDir}/requirements/_index.md | Functional + non-functional requirements |
|
|
210
|
+
| Architecture | ${workDir}/architecture/_index.md | Components, ADRs, tech stack |
|
|
211
|
+
| Epics | ${workDir}/epics/_index.md | Epic/Story breakdown |
|
|
212
|
+
| Readiness Report | ${workDir}/readiness-report.md | Quality validation |
|
|
213
|
+
| Spec Summary | ${workDir}/spec-summary.md | Executive summary |
|
|
214
|
+
|
|
215
|
+
## Dependency Map
|
|
216
|
+
|
|
217
|
+
| Issue ID | Depends On |
|
|
218
|
+
|----------|-----------|
|
|
219
|
+
${createdIssues.map(i => {
|
|
220
|
+
const epic = epicWaves.find(e => e.id === i.epic_id);
|
|
221
|
+
const deps = (epic.dependencies || []).map(d => epicToIssue[d]).filter(Boolean);
|
|
222
|
+
return `| ${i.issue_id} | ${deps.length > 0 ? deps.join(', ') : 'None'} |`;
|
|
223
|
+
}).join('\n')}
|
|
224
|
+
|
|
225
|
+
## Next Steps
|
|
226
|
+
|
|
227
|
+
1. **team-planex**: Execute all issues via coordinated team workflow
|
|
228
|
+
2. **Wave 1 only**: Execute MVP issues first (${wave1.length} issues)
|
|
229
|
+
3. **View issues**: Browse created issues via \`ccw issue list --tag spec:${specConfig.session_id}\`
|
|
230
|
+
4. **Manual review**: Review individual issues before execution
|
|
231
|
+
`;
|
|
232
|
+
|
|
233
|
+
Write(`${workDir}/issue-export-report.md`, reportContent);
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Step 6: Update spec-config.json
|
|
237
|
+
|
|
238
|
+
```javascript
|
|
239
|
+
specConfig.issue_ids = createdIssues.map(i => i.issue_id);
|
|
240
|
+
specConfig.issues_created = createdIssues.length;
|
|
241
|
+
specConfig.phasesCompleted.push({
|
|
242
|
+
phase: 7,
|
|
243
|
+
name: "issue-export",
|
|
244
|
+
output_file: "issue-export-report.md",
|
|
245
|
+
issues_created: createdIssues.length,
|
|
246
|
+
wave_1_count: wave1.length,
|
|
247
|
+
wave_2_count: wave2.length,
|
|
248
|
+
completed_at: timestamp
|
|
249
|
+
});
|
|
250
|
+
Write(`${workDir}/spec-config.json`, JSON.stringify(specConfig, null, 2));
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Step 7: Handoff Options
|
|
254
|
+
|
|
255
|
+
```javascript
|
|
256
|
+
const answer = request_user_input({
|
|
257
|
+
questions: [
|
|
258
|
+
{
|
|
259
|
+
header: "Next Step",
|
|
260
|
+
id: "next_step",
|
|
261
|
+
question: `${createdIssues.length} issues created from ${epicWaves.length} Epics. What would you like to do next?`,
|
|
262
|
+
options: [
|
|
263
|
+
{
|
|
264
|
+
label: "Execute via team-planex(Recommended)",
|
|
265
|
+
description: `Execute all ${createdIssues.length} issues with coordinated team workflow`
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
label: "Wave 1 only",
|
|
269
|
+
description: `Execute ${wave1.length} MVP issues first`
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
label: "Done",
|
|
273
|
+
description: "Export complete, handle manually"
|
|
274
|
+
}
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Based on user selection:
|
|
281
|
+
const selection = answer.answers.next_step.answers[0];
|
|
282
|
+
if (selection === "Execute via team-planex(Recommended)") {
|
|
283
|
+
const issueIds = createdIssues.map(i => i.issue_id).join(',');
|
|
284
|
+
Skill({ skill: "team-planex", args: `--issues ${issueIds}` });
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (selection === "Wave 1 only") {
|
|
288
|
+
const wave1Ids = createdIssues.filter(i => i.wave === 1).map(i => i.issue_id).join(',');
|
|
289
|
+
Skill({ skill: "team-planex", args: `--issues ${wave1Ids}` });
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (selection === "Done") {
|
|
293
|
+
// Export complete, handle manually
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Output
|
|
298
|
+
|
|
299
|
+
- **File**: `issue-export-report.md` — Issue mapping table + spec links + next steps
|
|
300
|
+
- **Updated**: `.workflow/issues/issues.jsonl` — New issue entries appended
|
|
301
|
+
- **Updated**: `spec-config.json` — Phase 7 completion + issue IDs
|
|
302
|
+
|
|
303
|
+
## Quality Checklist
|
|
304
|
+
|
|
305
|
+
- [ ] All MVP Epics have corresponding issues created
|
|
306
|
+
- [ ] All non-MVP Epics have corresponding issues created
|
|
307
|
+
- [ ] Issue tags include `spec-generated` and `spec:{session_id}`
|
|
308
|
+
- [ ] Issue `extended_context.notes.spec_documents` paths are correct
|
|
309
|
+
- [ ] Wave assignment matches MVP status (MVP → wave-1, non-MVP → wave-2)
|
|
310
|
+
- [ ] Epic dependencies mapped to issue dependency references
|
|
311
|
+
- [ ] `issue-export-report.md` generated with mapping table
|
|
312
|
+
- [ ] `spec-config.json` updated with `issue_ids` and `issues_created`
|
|
313
|
+
- [ ] Handoff options presented
|
|
314
|
+
|
|
315
|
+
## Error Handling
|
|
316
|
+
|
|
317
|
+
| Error | Blocking? | Action |
|
|
318
|
+
|-------|-----------|--------|
|
|
319
|
+
| `ccw issue create` fails for one Epic | No | Log error, continue with remaining Epics, report partial creation |
|
|
320
|
+
| No EPIC files found | Yes | Error and return to Phase 5 |
|
|
321
|
+
| All issue creations fail | Yes | Error with CLI diagnostic, suggest manual creation |
|
|
322
|
+
| Dependency EPIC not found in mapping | No | Skip dependency link, log warning |
|
|
323
|
+
|
|
324
|
+
## Completion
|
|
325
|
+
|
|
326
|
+
Phase 7 is the final phase. The specification package has been fully converted to executable issues ready for team-planex or manual execution.
|