claude-code-workflow 7.2.30 → 7.3.0

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.
Files changed (183) hide show
  1. package/.claude/commands/workflow-skill.md +130 -0
  2. package/.claude/skills/ccw-chain/SKILL.md +44 -71
  3. package/.claude/skills/ccw-chain/chains/ccw-cycle.json +13 -3
  4. package/.claude/skills/ccw-chain/chains/ccw-exploration.json +33 -22
  5. package/.claude/skills/ccw-chain/chains/ccw-issue.json +23 -12
  6. package/.claude/skills/ccw-chain/chains/ccw-lightweight.json +23 -9
  7. package/.claude/skills/ccw-chain/chains/ccw-main.json +15 -2
  8. package/.claude/skills/ccw-chain/chains/ccw-standard.json +28 -16
  9. package/.claude/skills/ccw-chain/chains/ccw-team.json +7 -2
  10. package/.claude/skills/ccw-chain/chains/ccw-with-file.json +25 -9
  11. package/.claude/skills/chain-loader/phases/01-analyze-skill.md +53 -53
  12. package/.claude/skills/chain-loader/specs/chain-schema.md +30 -3
  13. package/.claude/skills/chain-loader/templates/chain-json.md +63 -63
  14. package/.claude/skills/workflow-plan/SKILL.md +1 -0
  15. package/.claude/skills/workflow-plan/phases/01-session-discovery.md +19 -2
  16. package/.claude/skills/workflow-plan/phases/02-context-gathering.md +2 -2
  17. package/.claude/skills/workflow-plan/phases/04-task-generation.md +9 -1
  18. package/.codex/skills/analyze-with-file/SKILL.md +383 -134
  19. package/.codex/skills/brainstorm/SKILL.md +3 -3
  20. package/.codex/skills/brainstorm-with-file/SKILL.md +208 -88
  21. package/.codex/skills/clean/SKILL.md +1 -1
  22. package/.codex/skills/csv-wave-pipeline/SKILL.md +2 -2
  23. package/.codex/skills/investigate/orchestrator.md +24 -0
  24. package/.codex/skills/issue-discover/SKILL.md +374 -361
  25. package/.codex/skills/issue-discover/phases/01-issue-new.md +1 -1
  26. package/.codex/skills/issue-discover/phases/02-discover.md +2 -2
  27. package/.codex/skills/issue-discover/phases/03-discover-by-prompt.md +1 -1
  28. package/.codex/skills/issue-discover/phases/04-quick-execute.md +2 -2
  29. package/.codex/skills/parallel-dev-cycle/SKILL.md +44 -37
  30. package/.codex/skills/project-documentation-workflow/SKILL.md +1 -1
  31. package/.codex/skills/review-cycle/SKILL.md +31 -12
  32. package/.codex/skills/roadmap-with-file/SKILL.md +141 -133
  33. package/.codex/skills/security-audit/orchestrator.md +29 -0
  34. package/.codex/skills/session-sync/SKILL.md +1 -1
  35. package/.codex/skills/ship/orchestrator.md +24 -0
  36. package/.codex/skills/spec-add/SKILL.md +5 -5
  37. package/.codex/skills/spec-generator/SKILL.md +33 -2
  38. package/.codex/skills/spec-generator/phases/01-5-requirement-clarification.md +3 -3
  39. package/.codex/skills/spec-generator/phases/01-discovery.md +1 -1
  40. package/.codex/skills/spec-generator/phases/02-product-brief.md +1 -1
  41. package/.codex/skills/spec-generator/phases/03-requirements.md +1 -1
  42. package/.codex/skills/spec-generator/phases/04-architecture.md +1 -1
  43. package/.codex/skills/spec-generator/phases/05-epics-stories.md +1 -1
  44. package/.codex/skills/spec-generator/phases/06-readiness-check.md +1 -1
  45. package/.codex/skills/spec-generator/phases/07-issue-export.md +1 -1
  46. package/.codex/skills/spec-setup/SKILL.md +669 -669
  47. package/.codex/skills/team-arch-opt/specs/team-config.json +1 -1
  48. package/.codex/skills/team-brainstorm/SKILL.md +259 -259
  49. package/.codex/skills/team-coordinate/SKILL.md +359 -359
  50. package/.codex/skills/team-coordinate/roles/coordinator/commands/monitor.md +1 -1
  51. package/.codex/skills/team-designer/SKILL.md +27 -1
  52. package/.codex/skills/team-designer/phases/01-requirements-analysis.md +2 -2
  53. package/.codex/skills/team-designer/phases/02-scaffold-generation.md +1 -1
  54. package/.codex/skills/team-designer/phases/04-validation.md +1 -1
  55. package/.codex/skills/team-executor/SKILL.md +218 -218
  56. package/.codex/skills/team-frontend/SKILL.md +227 -227
  57. package/.codex/skills/team-frontend-debug/SKILL.md +278 -278
  58. package/.codex/skills/team-frontend-debug/roles/coordinator/commands/analyze.md +2 -2
  59. package/.codex/skills/team-interactive-craft/SKILL.md +220 -220
  60. package/.codex/skills/team-interactive-craft/roles/coordinator/role.md +209 -209
  61. package/.codex/skills/team-issue/SKILL.md +269 -269
  62. package/.codex/skills/team-issue/roles/coordinator/role.md +1 -1
  63. package/.codex/skills/team-lifecycle-v4/SKILL.md +305 -305
  64. package/.codex/skills/team-motion-design/SKILL.md +222 -222
  65. package/.codex/skills/team-motion-design/roles/coordinator/role.md +210 -210
  66. package/.codex/skills/team-perf-opt/SKILL.md +258 -258
  67. package/.codex/skills/team-perf-opt/specs/team-config.json +1 -1
  68. package/.codex/skills/team-planex/SKILL.md +216 -216
  69. package/.codex/skills/team-quality-assurance/SKILL.md +229 -229
  70. package/.codex/skills/team-review/SKILL.md +227 -227
  71. package/.codex/skills/team-roadmap-dev/SKILL.md +238 -238
  72. package/.codex/skills/team-roadmap-dev/roles/coordinator/commands/roadmap-discuss.md +5 -5
  73. package/.codex/skills/team-tech-debt/SKILL.md +206 -206
  74. package/.codex/skills/team-tech-debt/roles/coordinator/commands/monitor.md +1 -1
  75. package/.codex/skills/team-testing/SKILL.md +237 -237
  76. package/.codex/skills/team-ui-polish/SKILL.md +218 -218
  77. package/.codex/skills/team-ui-polish/roles/coordinator/role.md +213 -213
  78. package/.codex/skills/team-uidesign/SKILL.md +219 -219
  79. package/.codex/skills/team-uidesign/roles/coordinator/role.md +2 -2
  80. package/.codex/skills/team-ultra-analyze/SKILL.md +260 -260
  81. package/.codex/skills/team-ultra-analyze/roles/coordinator/commands/monitor.md +1 -1
  82. package/.codex/skills/team-ultra-analyze/roles/coordinator/role.md +1 -1
  83. package/.codex/skills/team-ux-improve/SKILL.md +227 -227
  84. package/.codex/skills/team-ux-improve/roles/coordinator/role.md +1 -1
  85. package/.codex/skills/team-ux-improve/specs/team-config.json +1 -1
  86. package/.codex/skills/team-visual-a11y/SKILL.md +319 -319
  87. package/.codex/skills/team-visual-a11y/roles/coordinator/role.md +213 -213
  88. package/.codex/skills/workflow-execute/SKILL.md +5 -5
  89. package/.codex/skills/workflow-lite-planex/SKILL.md +3 -3
  90. package/.codex/skills/workflow-plan/SKILL.md +3 -3
  91. package/.codex/skills/workflow-tdd-plan/SKILL.md +4 -4
  92. package/.codex/skills/workflow-test-fix-cycle/SKILL.md +403 -402
  93. package/ccw/dist/cli.d.ts.map +1 -1
  94. package/ccw/dist/cli.js +16 -0
  95. package/ccw/dist/cli.js.map +1 -1
  96. package/ccw/dist/commands/chain-loader.d.ts +2 -0
  97. package/ccw/dist/commands/chain-loader.d.ts.map +1 -0
  98. package/ccw/dist/commands/chain-loader.js +11 -0
  99. package/ccw/dist/commands/chain-loader.js.map +1 -0
  100. package/ccw/dist/commands/install.d.ts.map +1 -1
  101. package/ccw/dist/commands/install.js +52 -1
  102. package/ccw/dist/commands/install.js.map +1 -1
  103. package/ccw/dist/commands/launcher.d.ts +2 -0
  104. package/ccw/dist/commands/launcher.d.ts.map +1 -0
  105. package/ccw/dist/commands/launcher.js +434 -0
  106. package/ccw/dist/commands/launcher.js.map +1 -0
  107. package/ccw/dist/tools/chain-loader.d.ts.map +1 -1
  108. package/ccw/dist/tools/chain-loader.js +457 -45
  109. package/ccw/dist/tools/chain-loader.js.map +1 -1
  110. package/ccw/dist/tools/skill-context-loader.d.ts.map +1 -1
  111. package/ccw/dist/tools/skill-context-loader.js +12 -26
  112. package/ccw/dist/tools/skill-context-loader.js.map +1 -1
  113. package/ccw/dist/types/chain-types.d.ts +41 -1
  114. package/ccw/dist/types/chain-types.d.ts.map +1 -1
  115. package/ccw/dist/utils/chain-visualizer.d.ts +13 -0
  116. package/ccw/dist/utils/chain-visualizer.d.ts.map +1 -0
  117. package/ccw/dist/utils/chain-visualizer.js +164 -0
  118. package/ccw/dist/utils/chain-visualizer.js.map +1 -0
  119. package/package.json +1 -1
  120. package/.claude/commands/cli/cli-init.md +0 -441
  121. package/.claude/commands/cli/codex-review.md +0 -361
  122. package/.claude/commands/flow-create.md +0 -663
  123. package/.claude/skills/ccw-chain/phases/analyze-with-file.md +0 -788
  124. package/.claude/skills/ccw-chain/phases/brainstorm/SKILL.md +0 -408
  125. package/.claude/skills/ccw-chain/phases/brainstorm/phases/01-mode-routing.md +0 -207
  126. package/.claude/skills/ccw-chain/phases/brainstorm/phases/02-artifacts.md +0 -567
  127. package/.claude/skills/ccw-chain/phases/brainstorm/phases/03-role-analysis.md +0 -748
  128. package/.claude/skills/ccw-chain/phases/brainstorm/phases/04-synthesis.md +0 -827
  129. package/.claude/skills/ccw-chain/phases/brainstorm-with-file.md +0 -482
  130. package/.claude/skills/ccw-chain/phases/collaborative-plan-with-file.md +0 -639
  131. package/.claude/skills/ccw-chain/phases/debug-with-file.md +0 -656
  132. package/.claude/skills/ccw-chain/phases/integration-test-cycle.md +0 -936
  133. package/.claude/skills/ccw-chain/phases/issue-convert-to-plan.md +0 -720
  134. package/.claude/skills/ccw-chain/phases/issue-discover.md +0 -483
  135. package/.claude/skills/ccw-chain/phases/issue-execute.md +0 -629
  136. package/.claude/skills/ccw-chain/phases/issue-from-brainstorm.md +0 -382
  137. package/.claude/skills/ccw-chain/phases/issue-plan.md +0 -343
  138. package/.claude/skills/ccw-chain/phases/issue-queue.md +0 -464
  139. package/.claude/skills/ccw-chain/phases/refactor-cycle.md +0 -852
  140. package/.claude/skills/ccw-chain/phases/review-cycle/SKILL.md +0 -132
  141. package/.claude/skills/ccw-chain/phases/review-cycle/phases/review-fix.md +0 -760
  142. package/.claude/skills/ccw-chain/phases/review-cycle/phases/review-module.md +0 -764
  143. package/.claude/skills/ccw-chain/phases/review-cycle/phases/review-session.md +0 -775
  144. package/.claude/skills/ccw-chain/phases/roadmap-with-file.md +0 -544
  145. package/.claude/skills/ccw-chain/phases/spec-generator/SKILL.md +0 -338
  146. package/.claude/skills/ccw-chain/phases/spec-generator/phases/01-5-requirement-clarification.md +0 -404
  147. package/.claude/skills/ccw-chain/phases/spec-generator/phases/01-discovery.md +0 -257
  148. package/.claude/skills/ccw-chain/phases/spec-generator/phases/02-product-brief.md +0 -274
  149. package/.claude/skills/ccw-chain/phases/spec-generator/phases/03-requirements.md +0 -184
  150. package/.claude/skills/ccw-chain/phases/spec-generator/phases/04-architecture.md +0 -248
  151. package/.claude/skills/ccw-chain/phases/spec-generator/phases/05-epics-stories.md +0 -178
  152. package/.claude/skills/ccw-chain/phases/spec-generator/phases/06-5-auto-fix.md +0 -144
  153. package/.claude/skills/ccw-chain/phases/spec-generator/phases/06-readiness-check.md +0 -480
  154. package/.claude/skills/ccw-chain/phases/team-planex.md +0 -123
  155. package/.claude/skills/ccw-chain/phases/ui-design-explore-auto.md +0 -678
  156. package/.claude/skills/ccw-chain/phases/unified-execute-with-file.md +0 -870
  157. package/.claude/skills/ccw-chain/phases/workflow-execute/SKILL.md +0 -625
  158. package/.claude/skills/ccw-chain/phases/workflow-execute/phases/06-review.md +0 -215
  159. package/.claude/skills/ccw-chain/phases/workflow-lite-plan.md +0 -616
  160. package/.claude/skills/ccw-chain/phases/workflow-multi-cli-plan.md +0 -424
  161. package/.claude/skills/ccw-chain/phases/workflow-plan/SKILL.md +0 -466
  162. package/.claude/skills/ccw-chain/phases/workflow-plan/phases/01-session-discovery.md +0 -99
  163. package/.claude/skills/ccw-chain/phases/workflow-plan/phases/02-context-gathering.md +0 -338
  164. package/.claude/skills/ccw-chain/phases/workflow-plan/phases/03-conflict-resolution.md +0 -422
  165. package/.claude/skills/ccw-chain/phases/workflow-plan/phases/04-task-generation.md +0 -440
  166. package/.claude/skills/ccw-chain/phases/workflow-plan/phases/05-plan-verify.md +0 -395
  167. package/.claude/skills/ccw-chain/phases/workflow-plan/phases/06-replan.md +0 -594
  168. package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/SKILL.md +0 -527
  169. package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/01-session-discovery.md +0 -57
  170. package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/02-context-gathering.md +0 -407
  171. package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/03-test-coverage-analysis.md +0 -172
  172. package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/04-conflict-resolution.md +0 -426
  173. package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/05-tdd-task-generation.md +0 -473
  174. package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/06-tdd-structure-validation.md +0 -189
  175. package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/07-tdd-verify.md +0 -635
  176. package/.claude/skills/ccw-chain/phases/workflow-test-fix/SKILL.md +0 -482
  177. package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/01-session-start.md +0 -60
  178. package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/02-test-context-gather.md +0 -493
  179. package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/03-test-concept-enhanced.md +0 -150
  180. package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/04-test-task-generate.md +0 -346
  181. package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/05-test-cycle-execute.md +0 -538
  182. package/.claude/skills/ccw-chain/specs/intent-patterns.md +0 -60
  183. package/.claude/skills/team-edict.zip +0 -0
@@ -1,720 +0,0 @@
1
- ---
2
- name: convert-to-plan
3
- description: Convert planning artifacts (lite-plan, workflow session, markdown) to issue solutions
4
- argument-hint: "[-y|--yes] [--issue <id>] [--supplement] <SOURCE>"
5
- allowed-tools: TodoWrite(*), Bash(*), Read(*), Write(*), Glob(*), AskUserQuestion(*)
6
- ---
7
-
8
- ## Auto Mode
9
-
10
- When `--yes` or `-y`: Skip confirmation, auto-create issue and bind solution.
11
-
12
- # Issue Convert-to-Plan Command (/issue:convert-to-plan)
13
-
14
- ## Overview
15
-
16
- Converts various planning artifact formats into issue workflow solutions with intelligent detection and automatic binding.
17
-
18
- **Supported Sources** (auto-detected):
19
- - **lite-plan**: `.workflow/.lite-plan/{slug}/plan.json`
20
- - **workflow-session**: `WFS-xxx` ID or `.workflow/active/{session}/` folder
21
- - **markdown**: Any `.md` file with implementation/task content
22
- - **json**: Direct JSON files matching plan-json-schema
23
-
24
- ## Quick Reference
25
-
26
- ```bash
27
- # Convert lite-plan to new issue (auto-creates issue)
28
- /issue:convert-to-plan ".workflow/.lite-plan/implement-auth-2026-01-25"
29
-
30
- # Convert workflow session to existing issue
31
- /issue:convert-to-plan WFS-auth-impl --issue GH-123
32
-
33
- # Supplement existing solution with additional tasks
34
- /issue:convert-to-plan "./docs/additional-tasks.md" --issue ISS-001 --supplement
35
-
36
- # Auto mode - skip confirmations
37
- /issue:convert-to-plan ".workflow/.lite-plan/my-plan" -y
38
- ```
39
-
40
- ## Command Options
41
-
42
- | Option | Description | Default |
43
- |--------|-------------|---------|
44
- | `<SOURCE>` | Planning artifact path or WFS-xxx ID | Required |
45
- | `--issue <id>` | Bind to existing issue instead of creating new | Auto-create |
46
- | `--supplement` | Add tasks to existing solution (requires --issue) | false |
47
- | `-y, --yes` | Skip all confirmations | false |
48
-
49
- ## Core Data Access Principle
50
-
51
- **⚠️ Important**: Use CLI commands for all issue/solution operations.
52
-
53
- | Operation | Correct | Incorrect |
54
- |-----------|---------|-----------|
55
- | Get issue | `ccw issue status <id> --json` | Read issues.jsonl directly |
56
- | Create issue | `ccw issue init <id> --title "..."` | Write to issues.jsonl |
57
- | Bind solution | `ccw issue bind <id> <sol-id>` | Edit issues.jsonl |
58
- | List solutions | `ccw issue solution <id> --brief` | Read solutions/*.jsonl |
59
-
60
- ## Solution Schema Reference
61
-
62
- Target format for all extracted data (from solution-schema.json):
63
-
64
- ```typescript
65
- interface Solution {
66
- id: string; // SOL-{issue-id}-{4-char-uid}
67
- description?: string; // High-level summary
68
- approach?: string; // Technical strategy
69
- tasks: Task[]; // Required: at least 1 task
70
- exploration_context?: object; // Optional: source context
71
- analysis?: { risk, impact, complexity };
72
- score?: number; // 0.0-1.0
73
- is_bound: boolean;
74
- created_at: string;
75
- bound_at?: string;
76
- }
77
-
78
- interface Task {
79
- id: string; // T1, T2, T3... (pattern: ^T[0-9]+$)
80
- title: string; // Required: action verb + target
81
- scope: string; // Required: module path or feature area
82
- action: Action; // Required: Create|Update|Implement|...
83
- description?: string;
84
- files?: Array<{path, target, change}>;
85
- implementation: string[]; // Required: step-by-step guide
86
- test?: { unit?, integration?, commands?, coverage_target? };
87
- convergence: { criteria: string[], verification: string[] }; // Required
88
- commit?: { type, scope, message_template, breaking? };
89
- depends_on?: string[];
90
- priority?: number; // 1-5 (default: 3)
91
- }
92
-
93
- type Action = 'Create' | 'Update' | 'Implement' | 'Refactor' | 'Add' | 'Delete' | 'Configure' | 'Test' | 'Fix';
94
- ```
95
-
96
- ## Implementation
97
-
98
- ### Phase 1: Parse Arguments & Detect Source Type
99
-
100
- ```javascript
101
- const input = userInput.trim();
102
- const flags = parseFlags(userInput); // --issue, --supplement, -y/--yes
103
-
104
- // Extract source path (first non-flag argument)
105
- const source = extractSourceArg(input);
106
-
107
- // Detect source type
108
- function detectSourceType(source) {
109
- // Check for WFS-xxx pattern (workflow session ID)
110
- if (source.match(/^WFS-[\w-]+$/)) {
111
- return { type: 'workflow-session-id', path: `.workflow/active/${source}` };
112
- }
113
-
114
- // Check if directory
115
- const isDir = Bash(`test -d "${source}" && echo "dir" || echo "file"`).trim() === 'dir';
116
-
117
- if (isDir) {
118
- // Check for lite-plan indicator
119
- const hasPlanJson = Bash(`test -f "${source}/plan.json" && echo "yes" || echo "no"`).trim() === 'yes';
120
- if (hasPlanJson) {
121
- return { type: 'lite-plan', path: source };
122
- }
123
-
124
- // Check for workflow session indicator
125
- const hasSession = Bash(`test -f "${source}/workflow-session.json" && echo "yes" || echo "no"`).trim() === 'yes';
126
- if (hasSession) {
127
- return { type: 'workflow-session', path: source };
128
- }
129
- }
130
-
131
- // Check file extensions
132
- if (source.endsWith('.json')) {
133
- return { type: 'json-file', path: source };
134
- }
135
- if (source.endsWith('.md')) {
136
- return { type: 'markdown-file', path: source };
137
- }
138
-
139
- // Check if path exists at all
140
- const exists = Bash(`test -e "${source}" && echo "yes" || echo "no"`).trim() === 'yes';
141
- if (!exists) {
142
- throw new Error(`E001: Source not found: ${source}`);
143
- }
144
-
145
- return { type: 'unknown', path: source };
146
- }
147
-
148
- const sourceInfo = detectSourceType(source);
149
- if (sourceInfo.type === 'unknown') {
150
- throw new Error(`E002: Unable to detect source format for: ${source}`);
151
- }
152
-
153
- console.log(`Detected source type: ${sourceInfo.type}`);
154
- ```
155
-
156
- ### Phase 2: Extract Data Using Format-Specific Extractor
157
-
158
- ```javascript
159
- let extracted = { title: '', approach: '', tasks: [], metadata: {} };
160
-
161
- switch (sourceInfo.type) {
162
- case 'lite-plan':
163
- extracted = extractFromLitePlan(sourceInfo.path);
164
- break;
165
- case 'workflow-session':
166
- case 'workflow-session-id':
167
- extracted = extractFromWorkflowSession(sourceInfo.path);
168
- break;
169
- case 'markdown-file':
170
- extracted = await extractFromMarkdownAI(sourceInfo.path);
171
- break;
172
- case 'json-file':
173
- extracted = extractFromJsonFile(sourceInfo.path);
174
- break;
175
- }
176
-
177
- // Validate extraction
178
- if (!extracted.tasks || extracted.tasks.length === 0) {
179
- throw new Error('E006: No tasks extracted from source');
180
- }
181
-
182
- // Ensure task IDs are normalized to T1, T2, T3...
183
- extracted.tasks = normalizeTaskIds(extracted.tasks);
184
-
185
- console.log(`Extracted: ${extracted.tasks.length} tasks`);
186
- ```
187
-
188
- #### Extractor: Lite-Plan
189
-
190
- ```javascript
191
- function extractFromLitePlan(folderPath) {
192
- const planJson = Read(`${folderPath}/plan.json`);
193
- const plan = JSON.parse(planJson);
194
-
195
- return {
196
- title: plan.summary?.split('.')[0]?.trim() || 'Untitled Plan',
197
- description: plan.summary,
198
- approach: plan.approach,
199
- tasks: plan.tasks.map(t => ({
200
- id: t.id,
201
- title: t.title,
202
- scope: t.scope || '',
203
- action: t.action || 'Implement',
204
- description: t.description || t.title,
205
- files: (t.modification_points || []).map(mp => ({ path: mp.file, target: mp.target, change: mp.change })),
206
- implementation: Array.isArray(t.implementation) ? t.implementation : [t.implementation || ''],
207
- test: t.verification ? {
208
- unit: t.verification.unit_tests,
209
- integration: t.verification.integration_tests,
210
- commands: t.verification.manual_checks
211
- } : {},
212
- convergence: {
213
- criteria: Array.isArray(t.acceptance) ? t.acceptance : [t.acceptance || ''],
214
- verification: t.verification?.manual_checks || []
215
- },
216
- depends_on: t.depends_on || [],
217
- priority: 3
218
- })),
219
- metadata: {
220
- source_type: 'lite-plan',
221
- source_path: folderPath,
222
- complexity: plan.complexity,
223
- estimated_time: plan.estimated_time,
224
- exploration_angles: plan._metadata?.exploration_angles || [],
225
- original_timestamp: plan._metadata?.timestamp
226
- }
227
- };
228
- }
229
- ```
230
-
231
- #### Extractor: Workflow Session
232
-
233
- ```javascript
234
- function extractFromWorkflowSession(sessionPath) {
235
- // Load session metadata
236
- const sessionJson = Read(`${sessionPath}/workflow-session.json`);
237
- const session = JSON.parse(sessionJson);
238
-
239
- // Load IMPL_PLAN.md for approach (if exists)
240
- let approach = '';
241
- const implPlanPath = `${sessionPath}/IMPL_PLAN.md`;
242
- const hasImplPlan = Bash(`test -f "${implPlanPath}" && echo "yes" || echo "no"`).trim() === 'yes';
243
- if (hasImplPlan) {
244
- const implPlan = Read(implPlanPath);
245
- // Extract overview/approach section
246
- const overviewMatch = implPlan.match(/##\s*(?:Overview|Approach|Strategy)\s*\n([\s\S]*?)(?=\n##|$)/i);
247
- approach = overviewMatch?.[1]?.trim() || implPlan.split('\n').slice(0, 10).join('\n');
248
- }
249
-
250
- // Load all task JSONs from .task folder
251
- const taskFiles = Glob({ pattern: `${sessionPath}/.task/IMPL-*.json` });
252
- const tasks = taskFiles.map(f => {
253
- const taskJson = Read(f);
254
- const task = JSON.parse(taskJson);
255
- return {
256
- id: task.id?.replace(/^IMPL-0*/, 'T') || 'T1', // IMPL-001 → T1
257
- title: task.title,
258
- scope: task.scope || inferScopeFromTask(task),
259
- action: capitalizeAction(task.type) || 'Implement',
260
- description: task.description,
261
- files: (task.implementation?.modification_points || []).map(mp => ({ path: mp.file, target: mp.target, change: mp.change })),
262
- implementation: task.implementation?.steps || [],
263
- test: task.implementation?.test || {},
264
- convergence: {
265
- criteria: task.acceptance_criteria || [],
266
- verification: task.verification_steps || []
267
- },
268
- commit: task.commit,
269
- depends_on: (task.depends_on || []).map(d => d.replace(/^IMPL-0*/, 'T')),
270
- priority: task.priority || 3
271
- };
272
- });
273
-
274
- return {
275
- title: session.name || session.description?.split('.')[0] || 'Workflow Session',
276
- description: session.description || session.name,
277
- approach: approach || session.description,
278
- tasks: tasks,
279
- metadata: {
280
- source_type: 'workflow-session',
281
- source_path: sessionPath,
282
- session_id: session.id,
283
- created_at: session.created_at
284
- }
285
- };
286
- }
287
-
288
- function inferScopeFromTask(task) {
289
- if (task.files?.length) {
290
- const paths = task.files.map(f => f.path);
291
- // Find common directory prefix
292
- const dirs = paths.map(p => p.split('/').slice(0, -1).join('/'));
293
- return [...new Set(dirs)][0] || '';
294
- }
295
- return '';
296
- }
297
-
298
- function capitalizeAction(type) {
299
- if (!type) return 'Implement';
300
- const map = { feature: 'Implement', bugfix: 'Fix', refactor: 'Refactor', test: 'Test', docs: 'Update' };
301
- return map[type.toLowerCase()] || type.charAt(0).toUpperCase() + type.slice(1);
302
- }
303
- ```
304
-
305
- #### Extractor: Markdown (AI-Assisted via Gemini)
306
-
307
- ```javascript
308
- async function extractFromMarkdownAI(filePath) {
309
- const fileContent = Read(filePath);
310
-
311
- // Use Gemini CLI for intelligent extraction
312
- const cliPrompt = `PURPOSE: Extract implementation plan from markdown document for issue solution conversion. Must output ONLY valid JSON.
313
- TASK: • Analyze document structure • Identify title/summary • Extract approach/strategy section • Parse tasks from any format (lists, tables, sections, code blocks) • Normalize each task to solution schema
314
- MODE: analysis
315
- CONTEXT: Document content provided below
316
- EXPECTED: Valid JSON object with format:
317
- {
318
- "title": "extracted title",
319
- "approach": "extracted approach/strategy",
320
- "tasks": [
321
- {
322
- "id": "T1",
323
- "title": "task title",
324
- "scope": "module or feature area",
325
- "action": "Implement|Update|Create|Fix|Refactor|Add|Delete|Configure|Test",
326
- "description": "what to do",
327
- "implementation": ["step 1", "step 2"],
328
- "acceptance": ["criteria 1", "criteria 2"]
329
- }
330
- ]
331
- }
332
- CONSTRAINTS: Output ONLY valid JSON - no markdown, no explanation | Action must be one of: Create, Update, Implement, Refactor, Add, Delete, Configure, Test, Fix | Tasks must have id, title, scope, action, implementation (array), acceptance (array)
333
-
334
- DOCUMENT CONTENT:
335
- ${fileContent}`;
336
-
337
- // Execute Gemini CLI
338
- const result = Bash(`ccw cli -p '${cliPrompt.replace(/'/g, "'\\''")}' --tool gemini --mode analysis`, { timeout: 120000 });
339
-
340
- // Parse JSON from result (may be wrapped in markdown code block)
341
- let jsonText = result.trim();
342
- const jsonMatch = jsonText.match(/```(?:json)?\s*([\s\S]*?)```/);
343
- if (jsonMatch) {
344
- jsonText = jsonMatch[1].trim();
345
- }
346
-
347
- try {
348
- const extracted = JSON.parse(jsonText);
349
-
350
- // Normalize tasks
351
- const tasks = (extracted.tasks || []).map((t, i) => ({
352
- id: t.id || `T${i + 1}`,
353
- title: t.title || 'Untitled task',
354
- scope: t.scope || '',
355
- action: validateAction(t.action) || 'Implement',
356
- description: t.description || t.title,
357
- files: (t.modification_points || []).map(mp => ({ path: mp.file, target: mp.target, change: mp.change })),
358
- implementation: Array.isArray(t.implementation) ? t.implementation : [t.implementation || ''],
359
- test: t.test || {},
360
- convergence: {
361
- criteria: Array.isArray(t.acceptance) ? t.acceptance : [t.acceptance || ''],
362
- verification: t.verification || []
363
- },
364
- depends_on: t.depends_on || [],
365
- priority: t.priority || 3
366
- }));
367
-
368
- return {
369
- title: extracted.title || 'Extracted Plan',
370
- description: extracted.summary || extracted.title,
371
- approach: extracted.approach || '',
372
- tasks: tasks,
373
- metadata: {
374
- source_type: 'markdown',
375
- source_path: filePath,
376
- extraction_method: 'gemini-ai'
377
- }
378
- };
379
- } catch (e) {
380
- // Provide more context for debugging
381
- throw new Error(`E005: Failed to extract tasks from markdown. Gemini response was not valid JSON. Error: ${e.message}. Response preview: ${jsonText.substring(0, 200)}...`);
382
- }
383
- }
384
-
385
- function validateAction(action) {
386
- const validActions = ['Create', 'Update', 'Implement', 'Refactor', 'Add', 'Delete', 'Configure', 'Test', 'Fix'];
387
- if (!action) return null;
388
- const normalized = action.charAt(0).toUpperCase() + action.slice(1).toLowerCase();
389
- return validActions.includes(normalized) ? normalized : null;
390
- }
391
- ```
392
-
393
- #### Extractor: JSON File
394
-
395
- ```javascript
396
- function extractFromJsonFile(filePath) {
397
- const content = Read(filePath);
398
- const plan = JSON.parse(content);
399
-
400
- // Detect if it's already solution format or plan format
401
- if (plan.tasks && Array.isArray(plan.tasks)) {
402
- // Map tasks to normalized format
403
- const tasks = plan.tasks.map((t, i) => ({
404
- id: t.id || `T${i + 1}`,
405
- title: t.title,
406
- scope: t.scope || '',
407
- action: t.action || 'Implement',
408
- description: t.description || t.title,
409
- files: (t.modification_points || []).map(mp => ({ path: mp.file, target: mp.target, change: mp.change })),
410
- implementation: Array.isArray(t.implementation) ? t.implementation : [t.implementation || ''],
411
- test: t.test || t.verification || {},
412
- convergence: normalizeConvergence(t.acceptance, t.convergence),
413
- depends_on: t.depends_on || [],
414
- priority: t.priority || 3
415
- }));
416
-
417
- return {
418
- title: plan.summary?.split('.')[0] || plan.title || 'JSON Plan',
419
- description: plan.summary || plan.description,
420
- approach: plan.approach,
421
- tasks: tasks,
422
- metadata: {
423
- source_type: 'json',
424
- source_path: filePath,
425
- complexity: plan.complexity,
426
- original_metadata: plan._metadata
427
- }
428
- };
429
- }
430
-
431
- throw new Error('E002: JSON file does not contain valid plan structure (missing tasks array)');
432
- }
433
-
434
- function normalizeConvergence(acceptance, convergence) {
435
- // Prefer new convergence field; fall back to legacy acceptance
436
- const source = convergence || acceptance;
437
- if (!source) return { criteria: [], verification: [] };
438
- if (typeof source === 'object' && source.criteria) return source;
439
- if (Array.isArray(source)) return { criteria: source, verification: [] };
440
- return { criteria: [String(source)], verification: [] };
441
- }
442
- ```
443
-
444
- ### Phase 3: Normalize Task IDs
445
-
446
- ```javascript
447
- function normalizeTaskIds(tasks) {
448
- return tasks.map((t, i) => ({
449
- ...t,
450
- id: `T${i + 1}`,
451
- // Also normalize depends_on references
452
- depends_on: (t.depends_on || []).map(d => {
453
- // Handle various ID formats: IMPL-001, T1, 1, etc.
454
- const num = d.match(/\d+/)?.[0];
455
- return num ? `T${parseInt(num)}` : d;
456
- })
457
- }));
458
- }
459
- ```
460
-
461
- ### Phase 4: Resolve Issue (Create or Find)
462
-
463
- ```javascript
464
- let issueId = flags.issue;
465
- let existingSolution = null;
466
-
467
- if (issueId) {
468
- // Validate issue exists
469
- let issueCheck;
470
- try {
471
- issueCheck = Bash(`ccw issue status ${issueId} --json 2>/dev/null`).trim();
472
- if (!issueCheck || issueCheck === '') {
473
- throw new Error('empty response');
474
- }
475
- } catch (e) {
476
- throw new Error(`E003: Issue not found: ${issueId}`);
477
- }
478
-
479
- const issue = JSON.parse(issueCheck);
480
-
481
- // Check if issue already has bound solution
482
- if (issue.bound_solution_id && !flags.supplement) {
483
- throw new Error(`E004: Issue ${issueId} already has bound solution (${issue.bound_solution_id}). Use --supplement to add tasks.`);
484
- }
485
-
486
- // Load existing solution for supplement mode
487
- if (flags.supplement && issue.bound_solution_id) {
488
- try {
489
- const solResult = Bash(`ccw issue solution ${issue.bound_solution_id} --json`).trim();
490
- existingSolution = JSON.parse(solResult);
491
- console.log(`Loaded existing solution with ${existingSolution.tasks.length} tasks`);
492
- } catch (e) {
493
- throw new Error(`Failed to load existing solution: ${e.message}`);
494
- }
495
- }
496
- } else {
497
- // Create new issue via ccw issue create (auto-generates correct ID)
498
- // Smart extraction: title from content, priority from complexity
499
- const title = extracted.title || 'Converted Plan';
500
- const context = extracted.description || extracted.approach || title;
501
-
502
- // Auto-determine priority based on complexity
503
- const complexityMap = { high: 2, medium: 3, low: 4 };
504
- const priority = complexityMap[extracted.metadata.complexity?.toLowerCase()] || 3;
505
-
506
- try {
507
- // Use heredoc to avoid shell escaping issues
508
- const createResult = Bash(`ccw issue create << 'EOF'
509
- {
510
- "title": ${JSON.stringify(title)},
511
- "context": ${JSON.stringify(context)},
512
- "priority": ${priority},
513
- "source": "converted"
514
- }
515
- EOF`).trim();
516
-
517
- // Parse result to get created issue ID
518
- const created = JSON.parse(createResult);
519
- issueId = created.id;
520
- console.log(`Created issue: ${issueId} (priority: ${priority})`);
521
- } catch (e) {
522
- throw new Error(`Failed to create issue: ${e.message}`);
523
- }
524
- }
525
- ```
526
-
527
- ### Phase 5: Generate Solution
528
-
529
- ```javascript
530
- // Generate solution ID
531
- function generateSolutionId(issueId) {
532
- const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
533
- let uid = '';
534
- for (let i = 0; i < 4; i++) {
535
- uid += chars[Math.floor(Math.random() * chars.length)];
536
- }
537
- return `SOL-${issueId}-${uid}`;
538
- }
539
-
540
- let solution;
541
- const solutionId = generateSolutionId(issueId);
542
-
543
- if (flags.supplement && existingSolution) {
544
- // Supplement mode: merge with existing solution
545
- const maxTaskId = Math.max(...existingSolution.tasks.map(t => parseInt(t.id.slice(1))));
546
-
547
- const newTasks = extracted.tasks.map((t, i) => ({
548
- ...t,
549
- id: `T${maxTaskId + i + 1}`
550
- }));
551
-
552
- solution = {
553
- ...existingSolution,
554
- tasks: [...existingSolution.tasks, ...newTasks],
555
- approach: existingSolution.approach + '\n\n[Supplementary] ' + (extracted.approach || ''),
556
- updated_at: new Date().toISOString()
557
- };
558
-
559
- console.log(`Supplementing: ${existingSolution.tasks.length} existing + ${newTasks.length} new = ${solution.tasks.length} total tasks`);
560
- } else {
561
- // New solution
562
- solution = {
563
- id: solutionId,
564
- description: extracted.description || extracted.title,
565
- approach: extracted.approach,
566
- tasks: extracted.tasks,
567
- exploration_context: extracted.metadata.exploration_angles ? {
568
- exploration_angles: extracted.metadata.exploration_angles
569
- } : undefined,
570
- analysis: {
571
- risk: 'medium',
572
- impact: 'medium',
573
- complexity: extracted.metadata.complexity?.toLowerCase() || 'medium'
574
- },
575
- is_bound: false,
576
- created_at: new Date().toISOString(),
577
- _conversion_metadata: {
578
- source_type: extracted.metadata.source_type,
579
- source_path: extracted.metadata.source_path,
580
- converted_at: new Date().toISOString()
581
- }
582
- };
583
- }
584
- ```
585
-
586
- ### Phase 6: Confirm & Persist
587
-
588
- ```javascript
589
- // Display preview
590
- console.log(`
591
- ## Conversion Summary
592
-
593
- **Issue**: ${issueId}
594
- **Solution**: ${flags.supplement ? existingSolution.id : solutionId}
595
- **Tasks**: ${solution.tasks.length}
596
- **Mode**: ${flags.supplement ? 'Supplement' : 'New'}
597
-
598
- ### Tasks:
599
- ${solution.tasks.map(t => `- ${t.id}: ${t.title} [${t.action}]`).join('\n')}
600
- `);
601
-
602
- // Confirm if not auto mode
603
- if (!flags.yes && !flags.y) {
604
- const confirm = AskUserQuestion({
605
- questions: [{
606
- question: `Create solution for issue ${issueId} with ${solution.tasks.length} tasks?`,
607
- header: 'Confirm',
608
- multiSelect: false,
609
- options: [
610
- { label: 'Yes, create solution', description: 'Create and bind solution' },
611
- { label: 'Cancel', description: 'Abort without changes' }
612
- ]
613
- }]
614
- });
615
-
616
- if (!confirm.answers?.['Confirm']?.includes('Yes')) {
617
- console.log('Cancelled.');
618
- return;
619
- }
620
- }
621
-
622
- // Persist solution (following issue-plan-agent pattern)
623
- Bash(`mkdir -p .workflow/issues/solutions`);
624
-
625
- const solutionFile = `.workflow/issues/solutions/${issueId}.jsonl`;
626
-
627
- if (flags.supplement) {
628
- // Supplement mode: update existing solution line atomically
629
- try {
630
- const existingContent = Read(solutionFile);
631
- const lines = existingContent.trim().split('\n').filter(l => l);
632
- const updatedLines = lines.map(line => {
633
- const sol = JSON.parse(line);
634
- if (sol.id === existingSolution.id) {
635
- return JSON.stringify(solution);
636
- }
637
- return line;
638
- });
639
- // Atomic write: write entire content at once
640
- Write({ file_path: solutionFile, content: updatedLines.join('\n') + '\n' });
641
- console.log(`✓ Updated solution: ${existingSolution.id}`);
642
- } catch (e) {
643
- throw new Error(`Failed to update solution: ${e.message}`);
644
- }
645
-
646
- // Note: No need to rebind - solution is already bound to issue
647
- } else {
648
- // New solution: append to JSONL file (following issue-plan-agent pattern)
649
- try {
650
- const solutionLine = JSON.stringify(solution);
651
-
652
- // Read existing content, append new line, write atomically
653
- const existing = Bash(`test -f "${solutionFile}" && cat "${solutionFile}" || echo ""`).trim();
654
- const newContent = existing ? existing + '\n' + solutionLine + '\n' : solutionLine + '\n';
655
- Write({ file_path: solutionFile, content: newContent });
656
-
657
- console.log(`✓ Created solution: ${solutionId}`);
658
- } catch (e) {
659
- throw new Error(`Failed to write solution: ${e.message}`);
660
- }
661
-
662
- // Bind solution to issue
663
- try {
664
- Bash(`ccw issue bind ${issueId} ${solutionId}`);
665
- console.log(`✓ Bound solution to issue`);
666
- } catch (e) {
667
- // Cleanup: remove solution file on bind failure
668
- try {
669
- Bash(`rm -f "${solutionFile}"`);
670
- } catch (cleanupError) {
671
- // Ignore cleanup errors
672
- }
673
- throw new Error(`Failed to bind solution: ${e.message}`);
674
- }
675
-
676
- // Update issue status to planned
677
- try {
678
- Bash(`ccw issue update ${issueId} --status planned`);
679
- } catch (e) {
680
- throw new Error(`Failed to update issue status: ${e.message}`);
681
- }
682
- }
683
- ```
684
-
685
- ### Phase 7: Summary
686
-
687
- ```javascript
688
- console.log(`
689
- ## Done
690
-
691
- **Issue**: ${issueId}
692
- **Solution**: ${flags.supplement ? existingSolution.id : solutionId}
693
- **Tasks**: ${solution.tasks.length}
694
- **Status**: planned
695
-
696
- ### Next Steps:
697
- - \`/issue:queue\` → Form execution queue
698
- - \`ccw issue status ${issueId}\` → View issue details
699
- - \`ccw issue solution ${flags.supplement ? existingSolution.id : solutionId}\` → View solution
700
- `);
701
- ```
702
-
703
- ## Error Handling
704
-
705
- | Error | Code | Resolution |
706
- |-------|------|------------|
707
- | Source not found | E001 | Check path exists |
708
- | Invalid source format | E002 | Verify file contains valid plan structure |
709
- | Issue not found | E003 | Check issue ID or omit --issue to create new |
710
- | Solution already bound | E004 | Use --supplement to add tasks |
711
- | AI extraction failed | E005 | Check markdown structure, try simpler format |
712
- | No tasks extracted | E006 | Source must contain at least 1 task |
713
-
714
- ## Related Commands
715
-
716
- - `/issue:plan` - Generate solutions from issue exploration
717
- - `/issue:queue` - Form execution queue from bound solutions
718
- - `/issue:execute` - Execute queue with DAG parallelism
719
- - `ccw issue status <id>` - View issue details
720
- - `ccw issue solution <id>` - View solution details