claude-code-workflow 7.2.29 → 7.2.30
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/.ccw/workflows/cli-templates/schemas/plan-overview-base-schema.json +2 -2
- package/.ccw/workflows/cli-templates/schemas/task-schema.json +14 -7
- package/.claude/agents/action-planning-agent.md +7 -4
- package/.claude/agents/cli-explore-agent.md +77 -63
- package/.claude/agents/cli-lite-planning-agent.md +11 -10
- package/.claude/agents/issue-plan-agent.md +421 -426
- package/.claude/commands/workflow/spec/setup.md +1 -1
- package/.claude/skills/ccw-chain/SKILL.md +119 -0
- package/.claude/skills/ccw-chain/chains/ccw-cycle.json +21 -0
- package/.claude/skills/ccw-chain/chains/ccw-exploration.json +47 -0
- package/.claude/skills/ccw-chain/chains/ccw-issue.json +33 -0
- package/.claude/skills/ccw-chain/chains/ccw-lightweight.json +57 -0
- package/.claude/skills/ccw-chain/chains/ccw-main.json +52 -0
- package/.claude/skills/ccw-chain/chains/ccw-standard.json +39 -0
- package/.claude/skills/ccw-chain/chains/ccw-team.json +10 -0
- package/.claude/skills/ccw-chain/chains/ccw-with-file.json +31 -0
- package/.claude/skills/ccw-chain/phases/analyze-with-file.md +788 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/SKILL.md +408 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/phases/01-mode-routing.md +207 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/phases/02-artifacts.md +567 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/phases/03-role-analysis.md +748 -0
- package/.claude/skills/ccw-chain/phases/brainstorm/phases/04-synthesis.md +827 -0
- package/.claude/skills/ccw-chain/phases/brainstorm-with-file.md +482 -0
- package/.claude/skills/ccw-chain/phases/collaborative-plan-with-file.md +639 -0
- package/.claude/skills/ccw-chain/phases/debug-with-file.md +656 -0
- package/.claude/skills/ccw-chain/phases/integration-test-cycle.md +936 -0
- package/.claude/skills/ccw-chain/phases/issue-convert-to-plan.md +720 -0
- package/.claude/skills/ccw-chain/phases/issue-discover.md +483 -0
- package/.claude/skills/ccw-chain/phases/issue-execute.md +629 -0
- package/.claude/skills/ccw-chain/phases/issue-from-brainstorm.md +382 -0
- package/.claude/skills/ccw-chain/phases/issue-plan.md +343 -0
- package/.claude/skills/ccw-chain/phases/issue-queue.md +464 -0
- package/.claude/skills/ccw-chain/phases/refactor-cycle.md +852 -0
- package/.claude/skills/ccw-chain/phases/review-cycle/SKILL.md +132 -0
- package/.claude/skills/ccw-chain/phases/review-cycle/phases/review-fix.md +760 -0
- package/.claude/skills/ccw-chain/phases/review-cycle/phases/review-module.md +764 -0
- package/.claude/skills/ccw-chain/phases/review-cycle/phases/review-session.md +775 -0
- package/.claude/skills/ccw-chain/phases/roadmap-with-file.md +544 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/SKILL.md +338 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/01-5-requirement-clarification.md +404 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/01-discovery.md +257 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/02-product-brief.md +274 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/03-requirements.md +184 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/04-architecture.md +248 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/05-epics-stories.md +178 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/06-5-auto-fix.md +144 -0
- package/.claude/skills/ccw-chain/phases/spec-generator/phases/06-readiness-check.md +480 -0
- package/.claude/skills/ccw-chain/phases/team-planex.md +123 -0
- package/.claude/skills/ccw-chain/phases/ui-design-explore-auto.md +678 -0
- package/.claude/skills/ccw-chain/phases/unified-execute-with-file.md +870 -0
- package/.claude/skills/ccw-chain/phases/workflow-execute/SKILL.md +625 -0
- package/.claude/skills/ccw-chain/phases/workflow-execute/phases/06-review.md +215 -0
- package/.claude/skills/ccw-chain/phases/workflow-lite-plan.md +616 -0
- package/.claude/skills/ccw-chain/phases/workflow-multi-cli-plan.md +424 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/SKILL.md +466 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/01-session-discovery.md +99 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/02-context-gathering.md +338 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/03-conflict-resolution.md +422 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/04-task-generation.md +440 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/05-plan-verify.md +395 -0
- package/.claude/skills/ccw-chain/phases/workflow-plan/phases/06-replan.md +594 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/SKILL.md +527 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/01-session-discovery.md +57 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/02-context-gathering.md +407 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/03-test-coverage-analysis.md +172 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/04-conflict-resolution.md +426 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/05-tdd-task-generation.md +473 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/06-tdd-structure-validation.md +189 -0
- package/.claude/skills/ccw-chain/phases/workflow-tdd-plan/phases/07-tdd-verify.md +635 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/SKILL.md +482 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/01-session-start.md +60 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/02-test-context-gather.md +493 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/03-test-concept-enhanced.md +150 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/04-test-task-generate.md +346 -0
- package/.claude/skills/ccw-chain/phases/workflow-test-fix/phases/05-test-cycle-execute.md +538 -0
- package/.claude/skills/ccw-chain/specs/auto-mode.md +47 -0
- package/.claude/skills/ccw-chain/specs/intent-patterns.md +60 -0
- package/.claude/skills/chain-loader/SKILL.md +78 -0
- package/.claude/skills/chain-loader/phases/01-analyze-skill.md +53 -0
- package/.claude/skills/chain-loader/phases/02-design-graph.md +73 -0
- package/.claude/skills/chain-loader/phases/03-generate-validate.md +75 -0
- package/.claude/skills/chain-loader/specs/chain-schema.md +99 -0
- package/.claude/skills/chain-loader/specs/design-patterns.md +99 -0
- package/.claude/skills/chain-loader/templates/chain-json.md +63 -0
- package/.claude/skills/review-cycle/phases/review-module.md +764 -764
- package/.claude/skills/review-cycle/phases/review-session.md +775 -775
- package/.claude/skills/workflow-multi-cli-plan/SKILL.md +2 -2
- package/.claude/skills/workflow-plan/phases/03-conflict-resolution.md +422 -422
- package/.claude/skills/workflow-plan/phases/05-plan-verify.md +395 -395
- package/.claude/skills/workflow-tdd-plan/phases/02-context-gathering.md +407 -407
- package/.claude/skills/workflow-tdd-plan/phases/04-conflict-resolution.md +426 -426
- package/.claude/skills/workflow-test-fix/phases/02-test-context-gather.md +493 -493
- package/README.md +14 -0
- package/ccw/dist/core/routes/litellm-api-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/litellm-api-routes.js +0 -23
- package/ccw/dist/core/routes/litellm-api-routes.js.map +1 -1
- package/ccw/dist/tools/chain-loader.d.ts +10 -0
- package/ccw/dist/tools/chain-loader.d.ts.map +1 -0
- package/ccw/dist/tools/chain-loader.js +642 -0
- package/ccw/dist/tools/chain-loader.js.map +1 -0
- package/ccw/dist/tools/index.d.ts.map +1 -1
- package/ccw/dist/tools/index.js +2 -0
- package/ccw/dist/tools/index.js.map +1 -1
- package/ccw/dist/tools/json-builder.js +20 -0
- package/ccw/dist/tools/json-builder.js.map +1 -1
- package/ccw/dist/types/chain-types.d.ts +72 -0
- package/ccw/dist/types/chain-types.d.ts.map +1 -0
- package/ccw/dist/types/chain-types.js +5 -0
- package/ccw/dist/types/chain-types.js.map +1 -0
- package/ccw/scripts/prepublish-clean.mjs +0 -1
- package/package.json +1 -3
- package/ccw-litellm/README.md +0 -180
- package/ccw-litellm/pyproject.toml +0 -35
- package/ccw-litellm/src/ccw_litellm/__init__.py +0 -47
- package/ccw-litellm/src/ccw_litellm/cli.py +0 -108
- package/ccw-litellm/src/ccw_litellm/clients/__init__.py +0 -12
- package/ccw-litellm/src/ccw_litellm/clients/litellm_embedder.py +0 -270
- package/ccw-litellm/src/ccw_litellm/clients/litellm_llm.py +0 -198
- package/ccw-litellm/src/ccw_litellm/config/__init__.py +0 -22
- package/ccw-litellm/src/ccw_litellm/config/loader.py +0 -343
- package/ccw-litellm/src/ccw_litellm/config/models.py +0 -162
- package/ccw-litellm/src/ccw_litellm/interfaces/__init__.py +0 -14
- package/ccw-litellm/src/ccw_litellm/interfaces/embedder.py +0 -52
- package/ccw-litellm/src/ccw_litellm/interfaces/llm.py +0 -45
package/.claude/skills/ccw-chain/phases/spec-generator/phases/01-5-requirement-clarification.md
ADDED
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
# Phase 1.5: Requirement Expansion & Clarification
|
|
2
|
+
|
|
3
|
+
在进入正式文档生成前,通过多轮交互讨论对原始需求进行深度挖掘、扩展和确认。
|
|
4
|
+
|
|
5
|
+
## Objective
|
|
6
|
+
|
|
7
|
+
- 识别原始需求中的模糊点、遗漏和潜在风险
|
|
8
|
+
- 通过 CLI 辅助分析需求完整性,生成深度探测问题
|
|
9
|
+
- 支持多轮交互讨论,逐步细化需求
|
|
10
|
+
- 生成经用户确认的 `refined-requirements.json` 作为后续阶段的高质量输入
|
|
11
|
+
|
|
12
|
+
## Input
|
|
13
|
+
|
|
14
|
+
- Dependency: `{workDir}/spec-config.json` (Phase 1 output)
|
|
15
|
+
- Optional: `{workDir}/discovery-context.json` (codebase context)
|
|
16
|
+
|
|
17
|
+
## Execution Steps
|
|
18
|
+
|
|
19
|
+
### Step 1: Load Phase 1 Context
|
|
20
|
+
|
|
21
|
+
```javascript
|
|
22
|
+
const specConfig = JSON.parse(Read(`${workDir}/spec-config.json`));
|
|
23
|
+
const { seed_analysis, seed_input, focus_areas, has_codebase, depth } = specConfig;
|
|
24
|
+
|
|
25
|
+
let discoveryContext = null;
|
|
26
|
+
if (has_codebase) {
|
|
27
|
+
try {
|
|
28
|
+
discoveryContext = JSON.parse(Read(`${workDir}/discovery-context.json`));
|
|
29
|
+
} catch (e) { /* proceed without */ }
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Step 2: CLI Gap Analysis & Question Generation
|
|
34
|
+
|
|
35
|
+
调用 Gemini CLI 分析原始需求的完整性,识别模糊点并生成探测问题。
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
Bash({
|
|
39
|
+
command: `ccw cli -p "PURPOSE: 深度分析用户的初始需求,识别模糊点、遗漏和需要澄清的领域。
|
|
40
|
+
Success: 生成 3-5 个高质量的探测问题,覆盖功能范围、边界条件、非功能性需求、用户场景等维度。
|
|
41
|
+
|
|
42
|
+
ORIGINAL SEED INPUT:
|
|
43
|
+
${seed_input}
|
|
44
|
+
|
|
45
|
+
SEED ANALYSIS:
|
|
46
|
+
${JSON.stringify(seed_analysis, null, 2)}
|
|
47
|
+
|
|
48
|
+
FOCUS AREAS: ${focus_areas.join(', ')}
|
|
49
|
+
${discoveryContext ? `
|
|
50
|
+
CODEBASE CONTEXT:
|
|
51
|
+
- Existing patterns: ${discoveryContext.existing_patterns?.slice(0,5).join(', ') || 'none'}
|
|
52
|
+
- Tech stack: ${JSON.stringify(discoveryContext.tech_stack || {})}
|
|
53
|
+
` : ''}
|
|
54
|
+
|
|
55
|
+
TASK:
|
|
56
|
+
1. 评估当前需求描述的完整性(1-10 分,列出缺失维度)
|
|
57
|
+
2. 识别 3-5 个关键模糊区域,每个区域包含:
|
|
58
|
+
- 模糊点描述(为什么不清楚)
|
|
59
|
+
- 1-2 个开放式探测问题
|
|
60
|
+
- 1-2 个扩展建议(基于领域最佳实践)
|
|
61
|
+
3. 检查以下维度是否有遗漏:
|
|
62
|
+
- 功能范围边界(什么在范围内/外?)
|
|
63
|
+
- 核心用户场景和流程
|
|
64
|
+
- 非功能性需求(性能、安全、可用性、可扩展性)
|
|
65
|
+
- 集成点和外部依赖
|
|
66
|
+
- 数据模型和存储需求
|
|
67
|
+
- 错误处理和异常场景
|
|
68
|
+
4. 基于领域经验提供需求扩展建议
|
|
69
|
+
|
|
70
|
+
MODE: analysis
|
|
71
|
+
EXPECTED: JSON output:
|
|
72
|
+
{
|
|
73
|
+
\"completeness_score\": 7,
|
|
74
|
+
\"missing_dimensions\": [\"Performance requirements\", \"Error handling\"],
|
|
75
|
+
\"clarification_areas\": [
|
|
76
|
+
{
|
|
77
|
+
\"area\": \"Scope boundary\",
|
|
78
|
+
\"rationale\": \"Input does not clarify...\",
|
|
79
|
+
\"questions\": [\"Question 1?\", \"Question 2?\"],
|
|
80
|
+
\"suggestions\": [\"Suggestion 1\", \"Suggestion 2\"]
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
\"expansion_recommendations\": [
|
|
84
|
+
{
|
|
85
|
+
\"category\": \"Non-functional\",
|
|
86
|
+
\"recommendation\": \"Consider adding...\",
|
|
87
|
+
\"priority\": \"high|medium|low\"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
CONSTRAINTS: 问题必须是开放式的,建议必须具体可执行,使用用户输入的语言
|
|
92
|
+
" --tool gemini --mode analysis`,
|
|
93
|
+
run_in_background: true
|
|
94
|
+
});
|
|
95
|
+
// Wait for CLI result before continuing
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
解析 CLI 输出为结构化数据:
|
|
99
|
+
```javascript
|
|
100
|
+
const gapAnalysis = {
|
|
101
|
+
completeness_score: 0,
|
|
102
|
+
missing_dimensions: [],
|
|
103
|
+
clarification_areas: [],
|
|
104
|
+
expansion_recommendations: []
|
|
105
|
+
};
|
|
106
|
+
// Parse from CLI output
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Step 3: Interactive Discussion Loop
|
|
110
|
+
|
|
111
|
+
核心多轮交互循环。每轮:展示分析结果 → 用户回应 → 更新需求状态 → 判断是否继续。
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
// Initialize requirement state
|
|
115
|
+
let requirementState = {
|
|
116
|
+
problem_statement: seed_analysis.problem_statement,
|
|
117
|
+
target_users: seed_analysis.target_users,
|
|
118
|
+
domain: seed_analysis.domain,
|
|
119
|
+
constraints: seed_analysis.constraints,
|
|
120
|
+
confirmed_features: [],
|
|
121
|
+
non_functional_requirements: [],
|
|
122
|
+
boundary_conditions: [],
|
|
123
|
+
integration_points: [],
|
|
124
|
+
key_assumptions: [],
|
|
125
|
+
discussion_rounds: 0
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
let discussionLog = [];
|
|
129
|
+
let userSatisfied = false;
|
|
130
|
+
|
|
131
|
+
// === Round 1: Present gap analysis results ===
|
|
132
|
+
// Display completeness_score, clarification_areas, expansion_recommendations
|
|
133
|
+
// Then ask user to respond
|
|
134
|
+
|
|
135
|
+
while (!userSatisfied && requirementState.discussion_rounds < 5) {
|
|
136
|
+
requirementState.discussion_rounds++;
|
|
137
|
+
|
|
138
|
+
if (requirementState.discussion_rounds === 1) {
|
|
139
|
+
// --- First round: present initial gap analysis ---
|
|
140
|
+
// Format questions and suggestions from gapAnalysis for display
|
|
141
|
+
// Present as a structured summary to the user
|
|
142
|
+
|
|
143
|
+
AskUserQuestion({
|
|
144
|
+
questions: [
|
|
145
|
+
{
|
|
146
|
+
question: buildDiscussionPrompt(gapAnalysis, requirementState),
|
|
147
|
+
header: "Req Expand",
|
|
148
|
+
multiSelect: false,
|
|
149
|
+
options: [
|
|
150
|
+
{ label: "I'll answer", description: "I have answers/feedback to provide (type in 'Other')" },
|
|
151
|
+
{ label: "Accept all suggestions", description: "Accept all expansion recommendations as-is" },
|
|
152
|
+
{ label: "Skip to generation", description: "Requirements are clear enough, proceed directly" }
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
]
|
|
156
|
+
});
|
|
157
|
+
} else {
|
|
158
|
+
// --- Subsequent rounds: refine based on user feedback ---
|
|
159
|
+
// Call CLI with accumulated context for follow-up analysis
|
|
160
|
+
Bash({
|
|
161
|
+
command: `ccw cli -p "PURPOSE: 基于用户最新回应,更新需求理解,识别剩余模糊点。
|
|
162
|
+
|
|
163
|
+
CURRENT REQUIREMENT STATE:
|
|
164
|
+
${JSON.stringify(requirementState, null, 2)}
|
|
165
|
+
|
|
166
|
+
DISCUSSION HISTORY:
|
|
167
|
+
${JSON.stringify(discussionLog, null, 2)}
|
|
168
|
+
|
|
169
|
+
USER'S LATEST RESPONSE:
|
|
170
|
+
${lastUserResponse}
|
|
171
|
+
|
|
172
|
+
TASK:
|
|
173
|
+
1. 将用户回应整合到需求状态中
|
|
174
|
+
2. 识别 1-3 个仍需澄清或可扩展的领域
|
|
175
|
+
3. 生成后续问题(如有必要)
|
|
176
|
+
4. 如果需求已充分,输出最终需求摘要
|
|
177
|
+
|
|
178
|
+
MODE: analysis
|
|
179
|
+
EXPECTED: JSON output:
|
|
180
|
+
{
|
|
181
|
+
\"updated_fields\": { /* fields to merge into requirementState */ },
|
|
182
|
+
\"status\": \"need_more_discussion\" | \"ready_for_confirmation\",
|
|
183
|
+
\"follow_up\": {
|
|
184
|
+
\"remaining_areas\": [{\"area\": \"...\", \"questions\": [\"...\"]}],
|
|
185
|
+
\"summary\": \"...\"
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
CONSTRAINTS: 避免重复已回答的问题,聚焦未覆盖的领域
|
|
189
|
+
" --tool gemini --mode analysis`,
|
|
190
|
+
run_in_background: true
|
|
191
|
+
});
|
|
192
|
+
// Wait for CLI result, parse and continue
|
|
193
|
+
|
|
194
|
+
// If status === "ready_for_confirmation", break to confirmation step
|
|
195
|
+
// If status === "need_more_discussion", present follow-up questions
|
|
196
|
+
|
|
197
|
+
AskUserQuestion({
|
|
198
|
+
questions: [
|
|
199
|
+
{
|
|
200
|
+
question: buildFollowUpPrompt(followUpAnalysis, requirementState),
|
|
201
|
+
header: "Follow-up",
|
|
202
|
+
multiSelect: false,
|
|
203
|
+
options: [
|
|
204
|
+
{ label: "I'll answer", description: "I have more feedback (type in 'Other')" },
|
|
205
|
+
{ label: "Looks good", description: "Requirements are sufficiently clear now" },
|
|
206
|
+
{ label: "Accept suggestions", description: "Accept remaining suggestions" }
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Process user response
|
|
214
|
+
// - "Skip to generation" / "Looks good" → userSatisfied = true
|
|
215
|
+
// - "Accept all suggestions" → merge suggestions into requirementState, userSatisfied = true
|
|
216
|
+
// - "I'll answer" (with Other text) → record in discussionLog, continue loop
|
|
217
|
+
// - User selects Other with custom text → parse and record
|
|
218
|
+
|
|
219
|
+
discussionLog.push({
|
|
220
|
+
round: requirementState.discussion_rounds,
|
|
221
|
+
agent_prompt: currentPrompt,
|
|
222
|
+
user_response: userResponse,
|
|
223
|
+
timestamp: new Date().toISOString()
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
#### Helper: Build Discussion Prompt
|
|
229
|
+
|
|
230
|
+
```javascript
|
|
231
|
+
function buildDiscussionPrompt(gapAnalysis, state) {
|
|
232
|
+
let prompt = `## Requirement Analysis Results\n\n`;
|
|
233
|
+
prompt += `**Completeness Score**: ${gapAnalysis.completeness_score}/10\n`;
|
|
234
|
+
|
|
235
|
+
if (gapAnalysis.missing_dimensions.length > 0) {
|
|
236
|
+
prompt += `**Missing Dimensions**: ${gapAnalysis.missing_dimensions.join(', ')}\n\n`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
prompt += `### Key Questions\n\n`;
|
|
240
|
+
gapAnalysis.clarification_areas.forEach((area, i) => {
|
|
241
|
+
prompt += `**${i+1}. ${area.area}**\n`;
|
|
242
|
+
prompt += ` ${area.rationale}\n`;
|
|
243
|
+
area.questions.forEach(q => { prompt += ` - ${q}\n`; });
|
|
244
|
+
if (area.suggestions.length > 0) {
|
|
245
|
+
prompt += ` Suggestions: ${area.suggestions.join('; ')}\n`;
|
|
246
|
+
}
|
|
247
|
+
prompt += `\n`;
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
if (gapAnalysis.expansion_recommendations.length > 0) {
|
|
251
|
+
prompt += `### Expansion Recommendations\n\n`;
|
|
252
|
+
gapAnalysis.expansion_recommendations.forEach(rec => {
|
|
253
|
+
prompt += `- [${rec.priority}] **${rec.category}**: ${rec.recommendation}\n`;
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
prompt += `\nPlease answer the questions above, or choose an option below.`;
|
|
258
|
+
return prompt;
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Step 4: Auto Mode Handling
|
|
263
|
+
|
|
264
|
+
```javascript
|
|
265
|
+
if (autoMode) {
|
|
266
|
+
// Skip interactive discussion
|
|
267
|
+
// CLI generates default requirement expansion based on seed_analysis
|
|
268
|
+
Bash({
|
|
269
|
+
command: `ccw cli -p "PURPOSE: 基于种子分析自动生成需求扩展,无需用户交互。
|
|
270
|
+
|
|
271
|
+
SEED ANALYSIS:
|
|
272
|
+
${JSON.stringify(seed_analysis, null, 2)}
|
|
273
|
+
|
|
274
|
+
SEED INPUT: ${seed_input}
|
|
275
|
+
DEPTH: ${depth}
|
|
276
|
+
${discoveryContext ? `CODEBASE: ${JSON.stringify(discoveryContext.tech_stack || {})}` : ''}
|
|
277
|
+
|
|
278
|
+
TASK:
|
|
279
|
+
1. 基于领域最佳实践,自动扩展功能需求清单
|
|
280
|
+
2. 推断合理的非功能性需求
|
|
281
|
+
3. 识别明显的边界条件
|
|
282
|
+
4. 列出关键假设
|
|
283
|
+
|
|
284
|
+
MODE: analysis
|
|
285
|
+
EXPECTED: JSON output matching refined-requirements.json schema
|
|
286
|
+
CONSTRAINTS: 保守推断,只添加高置信度的扩展
|
|
287
|
+
" --tool gemini --mode analysis`,
|
|
288
|
+
run_in_background: true
|
|
289
|
+
});
|
|
290
|
+
// Parse output directly into refined-requirements.json
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Step 5: Generate Requirement Confirmation Summary
|
|
295
|
+
|
|
296
|
+
在写入文件前,向用户展示最终的需求确认摘要(非 auto mode)。
|
|
297
|
+
|
|
298
|
+
```javascript
|
|
299
|
+
if (!autoMode) {
|
|
300
|
+
// Build confirmation summary from requirementState
|
|
301
|
+
const summary = buildConfirmationSummary(requirementState);
|
|
302
|
+
|
|
303
|
+
AskUserQuestion({
|
|
304
|
+
questions: [
|
|
305
|
+
{
|
|
306
|
+
question: `## Requirement Confirmation\n\n${summary}\n\nConfirm and proceed to specification generation?`,
|
|
307
|
+
header: "Confirm",
|
|
308
|
+
multiSelect: false,
|
|
309
|
+
options: [
|
|
310
|
+
{ label: "Confirm & proceed", description: "Requirements confirmed, start spec generation" },
|
|
311
|
+
{ label: "Need adjustments", description: "Go back and refine further" }
|
|
312
|
+
]
|
|
313
|
+
}
|
|
314
|
+
]
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// If "Need adjustments" → loop back to Step 3
|
|
318
|
+
// If "Confirm & proceed" → continue to Step 6
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Step 6: Write refined-requirements.json
|
|
323
|
+
|
|
324
|
+
```javascript
|
|
325
|
+
const refinedRequirements = {
|
|
326
|
+
session_id: specConfig.session_id,
|
|
327
|
+
phase: "1.5",
|
|
328
|
+
generated_at: new Date().toISOString(),
|
|
329
|
+
source: autoMode ? "auto-expansion" : "interactive-discussion",
|
|
330
|
+
discussion_rounds: requirementState.discussion_rounds,
|
|
331
|
+
|
|
332
|
+
// Core requirement content
|
|
333
|
+
clarified_problem_statement: requirementState.problem_statement,
|
|
334
|
+
confirmed_target_users: requirementState.target_users.map(u =>
|
|
335
|
+
typeof u === 'string' ? { name: u, needs: [], pain_points: [] } : u
|
|
336
|
+
),
|
|
337
|
+
confirmed_domain: requirementState.domain,
|
|
338
|
+
|
|
339
|
+
confirmed_features: requirementState.confirmed_features.map(f => ({
|
|
340
|
+
name: f.name,
|
|
341
|
+
description: f.description,
|
|
342
|
+
acceptance_criteria: f.acceptance_criteria || [],
|
|
343
|
+
edge_cases: f.edge_cases || [],
|
|
344
|
+
priority: f.priority || "unset"
|
|
345
|
+
})),
|
|
346
|
+
|
|
347
|
+
non_functional_requirements: requirementState.non_functional_requirements.map(nfr => ({
|
|
348
|
+
type: nfr.type, // Performance, Security, Usability, Scalability, etc.
|
|
349
|
+
details: nfr.details,
|
|
350
|
+
measurable_criteria: nfr.measurable_criteria || ""
|
|
351
|
+
})),
|
|
352
|
+
|
|
353
|
+
boundary_conditions: {
|
|
354
|
+
in_scope: requirementState.boundary_conditions.filter(b => b.scope === 'in'),
|
|
355
|
+
out_of_scope: requirementState.boundary_conditions.filter(b => b.scope === 'out'),
|
|
356
|
+
constraints: requirementState.constraints
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
integration_points: requirementState.integration_points,
|
|
360
|
+
key_assumptions: requirementState.key_assumptions,
|
|
361
|
+
|
|
362
|
+
// Traceability
|
|
363
|
+
discussion_log: autoMode ? [] : discussionLog
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
Write(`${workDir}/refined-requirements.json`, JSON.stringify(refinedRequirements, null, 2));
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Step 7: Update spec-config.json
|
|
370
|
+
|
|
371
|
+
```javascript
|
|
372
|
+
specConfig.refined_requirements_file = "refined-requirements.json";
|
|
373
|
+
specConfig.phasesCompleted.push({
|
|
374
|
+
phase: 1.5,
|
|
375
|
+
name: "requirement-clarification",
|
|
376
|
+
output_file: "refined-requirements.json",
|
|
377
|
+
discussion_rounds: requirementState.discussion_rounds,
|
|
378
|
+
completed_at: new Date().toISOString()
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
Write(`${workDir}/spec-config.json`, JSON.stringify(specConfig, null, 2));
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
## Output
|
|
385
|
+
|
|
386
|
+
- **File**: `refined-requirements.json`
|
|
387
|
+
- **Format**: JSON
|
|
388
|
+
- **Updated**: `spec-config.json` (added `refined_requirements_file` field and phase 1.5 to `phasesCompleted`)
|
|
389
|
+
|
|
390
|
+
## Quality Checklist
|
|
391
|
+
|
|
392
|
+
- [ ] Problem statement refined (>= 30 characters, more specific than seed)
|
|
393
|
+
- [ ] At least 2 confirmed features with descriptions
|
|
394
|
+
- [ ] At least 1 non-functional requirement identified
|
|
395
|
+
- [ ] Boundary conditions defined (in-scope + out-of-scope)
|
|
396
|
+
- [ ] Key assumptions listed (>= 1)
|
|
397
|
+
- [ ] Discussion rounds recorded (>= 1 in interactive mode)
|
|
398
|
+
- [ ] User explicitly confirmed requirements (non-auto mode)
|
|
399
|
+
- [ ] `refined-requirements.json` written with valid JSON
|
|
400
|
+
- [ ] `spec-config.json` updated with phase 1.5 completion
|
|
401
|
+
|
|
402
|
+
## Next Phase
|
|
403
|
+
|
|
404
|
+
Proceed to [Phase 2: Product Brief](02-product-brief.md). Phase 2 should load `refined-requirements.json` as primary input instead of relying solely on `spec-config.json.seed_analysis`.
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Phase 1: Discovery
|
|
2
|
+
|
|
3
|
+
Parse input, analyze the seed idea, optionally explore codebase, establish session configuration.
|
|
4
|
+
|
|
5
|
+
## Objective
|
|
6
|
+
|
|
7
|
+
- Generate session ID and create output directory
|
|
8
|
+
- Parse user input (text description or file reference)
|
|
9
|
+
- Analyze seed via Gemini CLI to extract problem space dimensions
|
|
10
|
+
- Conditionally explore codebase for existing patterns and constraints
|
|
11
|
+
- Gather user preferences (depth, focus areas) via interactive confirmation
|
|
12
|
+
- Write `spec-config.json` as the session state file
|
|
13
|
+
|
|
14
|
+
## Input
|
|
15
|
+
|
|
16
|
+
- Dependency: `$ARGUMENTS` (user input from command)
|
|
17
|
+
- Flags: `-y` (auto mode), `-c` (continue mode)
|
|
18
|
+
|
|
19
|
+
## Execution Steps
|
|
20
|
+
|
|
21
|
+
### Step 1: Session Initialization
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
// Parse arguments
|
|
25
|
+
const args = $ARGUMENTS;
|
|
26
|
+
const autoMode = args.includes('-y') || args.includes('--yes');
|
|
27
|
+
const continueMode = args.includes('-c') || args.includes('--continue');
|
|
28
|
+
|
|
29
|
+
// Extract the idea/topic (remove flags)
|
|
30
|
+
const idea = args.replace(/(-y|--yes|-c|--continue)\s*/g, '').trim();
|
|
31
|
+
|
|
32
|
+
// Generate session ID
|
|
33
|
+
const slug = idea.toLowerCase()
|
|
34
|
+
.replace(/[^a-z0-9\u4e00-\u9fff]+/g, '-')
|
|
35
|
+
.replace(/^-|-$/g, '')
|
|
36
|
+
.slice(0, 40);
|
|
37
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
38
|
+
const sessionId = `SPEC-${slug}-${date}`;
|
|
39
|
+
const workDir = `.workflow/.spec/${sessionId}`;
|
|
40
|
+
|
|
41
|
+
// Check for continue mode
|
|
42
|
+
if (continueMode) {
|
|
43
|
+
// Find existing session
|
|
44
|
+
const existingSessions = Glob('.workflow/.spec/SPEC-*/spec-config.json');
|
|
45
|
+
// If slug matches an existing session, load it and resume
|
|
46
|
+
// Read spec-config.json, find first incomplete phase, jump to that phase
|
|
47
|
+
return; // Resume logic handled by orchestrator
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Create output directory
|
|
51
|
+
Bash(`mkdir -p "${workDir}"`);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Step 2: Input Parsing
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
// Determine input type
|
|
58
|
+
if (idea.startsWith('@') || idea.endsWith('.md') || idea.endsWith('.txt')) {
|
|
59
|
+
// File reference - read and extract content
|
|
60
|
+
const filePath = idea.replace(/^@/, '');
|
|
61
|
+
const fileContent = Read(filePath);
|
|
62
|
+
// Use file content as the seed
|
|
63
|
+
inputType = 'file';
|
|
64
|
+
seedInput = fileContent;
|
|
65
|
+
} else {
|
|
66
|
+
// Direct text description
|
|
67
|
+
inputType = 'text';
|
|
68
|
+
seedInput = idea;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Step 3: Seed Analysis via Gemini CLI
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
Bash({
|
|
76
|
+
command: `ccw cli -p "PURPOSE: Analyze this seed idea/requirement to extract structured problem space dimensions.
|
|
77
|
+
Success: Clear problem statement, target users, domain identification, 3-5 exploration dimensions.
|
|
78
|
+
|
|
79
|
+
SEED INPUT:
|
|
80
|
+
${seedInput}
|
|
81
|
+
|
|
82
|
+
TASK:
|
|
83
|
+
- Extract a clear problem statement (what problem does this solve?)
|
|
84
|
+
- Identify target users (who benefits?)
|
|
85
|
+
- Determine the domain (technical, business, consumer, etc.)
|
|
86
|
+
- List constraints (budget, time, technical, regulatory)
|
|
87
|
+
- Generate 3-5 exploration dimensions (key areas to investigate)
|
|
88
|
+
- Assess complexity: simple (1-2 components), moderate (3-5 components), complex (6+ components)
|
|
89
|
+
|
|
90
|
+
MODE: analysis
|
|
91
|
+
EXPECTED: JSON output with fields: problem_statement, target_users[], domain, constraints[], dimensions[], complexity
|
|
92
|
+
CONSTRAINTS: Be specific and actionable, not vague
|
|
93
|
+
" --tool gemini --mode analysis`,
|
|
94
|
+
run_in_background: true
|
|
95
|
+
});
|
|
96
|
+
// Wait for CLI result before continuing
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Parse the CLI output into structured `seedAnalysis`:
|
|
100
|
+
```javascript
|
|
101
|
+
const seedAnalysis = {
|
|
102
|
+
problem_statement: "...",
|
|
103
|
+
target_users: ["..."],
|
|
104
|
+
domain: "...",
|
|
105
|
+
constraints: ["..."],
|
|
106
|
+
dimensions: ["..."]
|
|
107
|
+
};
|
|
108
|
+
const complexity = "moderate"; // from CLI output
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Step 4: Codebase Exploration (Conditional)
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
// Detect if running inside a project with code
|
|
115
|
+
const hasCodebase = Glob('**/*.{ts,js,py,java,go,rs}').length > 0
|
|
116
|
+
|| Glob('package.json').length > 0
|
|
117
|
+
|| Glob('Cargo.toml').length > 0;
|
|
118
|
+
|
|
119
|
+
if (hasCodebase) {
|
|
120
|
+
Agent({
|
|
121
|
+
subagent_type: "cli-explore-agent",
|
|
122
|
+
run_in_background: false,
|
|
123
|
+
description: `Explore codebase for spec: ${slug}`,
|
|
124
|
+
prompt: `
|
|
125
|
+
## Spec Generator Context
|
|
126
|
+
Topic: ${seedInput}
|
|
127
|
+
Dimensions: ${seedAnalysis.dimensions.join(', ')}
|
|
128
|
+
Session: ${workDir}
|
|
129
|
+
|
|
130
|
+
## MANDATORY FIRST STEPS
|
|
131
|
+
1. Search for code related to topic keywords
|
|
132
|
+
2. Read project config files (package.json, pyproject.toml, etc.) if they exist
|
|
133
|
+
|
|
134
|
+
## Exploration Focus
|
|
135
|
+
- Identify existing implementations related to the topic
|
|
136
|
+
- Find patterns that could inform architecture decisions
|
|
137
|
+
- Map current architecture constraints
|
|
138
|
+
- Locate integration points and dependencies
|
|
139
|
+
|
|
140
|
+
## Output
|
|
141
|
+
Write findings to: ${workDir}/discovery-context.json
|
|
142
|
+
|
|
143
|
+
Schema:
|
|
144
|
+
{
|
|
145
|
+
"relevant_files": [{"path": "...", "relevance": "high|medium|low", "rationale": "..."}],
|
|
146
|
+
"existing_patterns": ["pattern descriptions"],
|
|
147
|
+
"architecture_constraints": ["constraint descriptions"],
|
|
148
|
+
"integration_points": ["integration point descriptions"],
|
|
149
|
+
"tech_stack": {"languages": [], "frameworks": [], "databases": []},
|
|
150
|
+
"_metadata": { "exploration_type": "spec-discovery", "timestamp": "ISO8601" }
|
|
151
|
+
}
|
|
152
|
+
`
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Step 5: User Confirmation (Interactive)
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
if (!autoMode) {
|
|
161
|
+
// Confirm problem statement and select depth
|
|
162
|
+
AskUserQuestion({
|
|
163
|
+
questions: [
|
|
164
|
+
{
|
|
165
|
+
question: `Problem statement: "${seedAnalysis.problem_statement}" - Is this accurate?`,
|
|
166
|
+
header: "Problem",
|
|
167
|
+
multiSelect: false,
|
|
168
|
+
options: [
|
|
169
|
+
{ label: "Accurate", description: "Proceed with this problem statement" },
|
|
170
|
+
{ label: "Needs adjustment", description: "I'll refine the problem statement" }
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
question: "What specification depth do you need?",
|
|
175
|
+
header: "Depth",
|
|
176
|
+
multiSelect: false,
|
|
177
|
+
options: [
|
|
178
|
+
{ label: "Light", description: "Quick overview - key decisions only" },
|
|
179
|
+
{ label: "Standard (Recommended)", description: "Balanced detail for most projects" },
|
|
180
|
+
{ label: "Comprehensive", description: "Maximum detail for complex/critical projects" }
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
question: "Which areas should we focus on?",
|
|
185
|
+
header: "Focus",
|
|
186
|
+
multiSelect: true,
|
|
187
|
+
options: seedAnalysis.dimensions.map(d => ({ label: d, description: `Explore ${d} in depth` }))
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
question: "What type of specification is this?",
|
|
191
|
+
header: "Spec Type",
|
|
192
|
+
multiSelect: false,
|
|
193
|
+
options: [
|
|
194
|
+
{ label: "Service (Recommended)", description: "Long-running service with lifecycle, state machine, observability" },
|
|
195
|
+
{ label: "API", description: "REST/GraphQL API with endpoints, auth, rate limiting" },
|
|
196
|
+
{ label: "Library/SDK", description: "Reusable package with public API surface, examples" },
|
|
197
|
+
{ label: "Platform", description: "Multi-component system, uses Service profile" }
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
});
|
|
202
|
+
} else {
|
|
203
|
+
// Auto mode defaults
|
|
204
|
+
depth = "standard";
|
|
205
|
+
focusAreas = seedAnalysis.dimensions;
|
|
206
|
+
specType = "service"; // default for auto mode
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Step 6: Write spec-config.json
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
const specConfig = {
|
|
214
|
+
session_id: sessionId,
|
|
215
|
+
seed_input: seedInput,
|
|
216
|
+
input_type: inputType,
|
|
217
|
+
timestamp: new Date().toISOString(),
|
|
218
|
+
mode: autoMode ? "auto" : "interactive",
|
|
219
|
+
complexity: complexity,
|
|
220
|
+
depth: depth,
|
|
221
|
+
focus_areas: focusAreas,
|
|
222
|
+
seed_analysis: seedAnalysis,
|
|
223
|
+
has_codebase: hasCodebase,
|
|
224
|
+
spec_type: specType, // "service" | "api" | "library" | "platform"
|
|
225
|
+
iteration_count: 0,
|
|
226
|
+
iteration_history: [],
|
|
227
|
+
phasesCompleted: [
|
|
228
|
+
{
|
|
229
|
+
phase: 1,
|
|
230
|
+
name: "discovery",
|
|
231
|
+
output_file: "spec-config.json",
|
|
232
|
+
completed_at: new Date().toISOString()
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
Write(`${workDir}/spec-config.json`, JSON.stringify(specConfig, null, 2));
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Output
|
|
241
|
+
|
|
242
|
+
- **File**: `spec-config.json`
|
|
243
|
+
- **File**: `discovery-context.json` (optional, if codebase detected)
|
|
244
|
+
- **Format**: JSON
|
|
245
|
+
|
|
246
|
+
## Quality Checklist
|
|
247
|
+
|
|
248
|
+
- [ ] Session ID matches `SPEC-{slug}-{date}` format
|
|
249
|
+
- [ ] Problem statement exists and is >= 20 characters
|
|
250
|
+
- [ ] Target users identified (>= 1)
|
|
251
|
+
- [ ] 3-5 exploration dimensions generated
|
|
252
|
+
- [ ] spec-config.json written with all required fields
|
|
253
|
+
- [ ] Output directory created
|
|
254
|
+
|
|
255
|
+
## Next Phase
|
|
256
|
+
|
|
257
|
+
Proceed to [Phase 2: Product Brief](02-product-brief.md) with the generated spec-config.json.
|