speccrew 0.7.4 → 0.7.6
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/.speccrew/agents/speccrew-feature-designer.md +6 -0
- package/.speccrew/agents/speccrew-product-manager.md +6 -0
- package/.speccrew/agents/speccrew-system-deployer.md +6 -0
- package/.speccrew/agents/speccrew-system-designer.md +6 -0
- package/.speccrew/agents/speccrew-system-developer.md +6 -0
- package/.speccrew/agents/speccrew-task-worker.md +5 -0
- package/.speccrew/agents/speccrew-test-manager.md +6 -0
- package/.speccrew/skills/speccrew-feature-designer-orchestration/SKILL.md +117 -0
- package/.speccrew/skills/speccrew-feature-designer-orchestration/workflow.agentflow.xml +463 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/workflow.agentflow.xml +119 -10
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/SKILL.md +3 -3
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/SKILL.md +1 -1
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js +289 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/reindex-modules.js +1 -1
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/workflow.agentflow.xml +170 -3
- package/.speccrew/skills/speccrew-knowledge-graph-write/SKILL.md +1 -1
- package/.speccrew/skills/speccrew-pm-module-initializer/SKILL.md +1 -1
- package/.speccrew/skills/speccrew-pm-module-initializer/workflow.agentflow.xml +1 -1
- package/.speccrew/skills/speccrew-product-manager-orchestration/SKILL.md +111 -0
- package/.speccrew/skills/speccrew-product-manager-orchestration/workflow.agentflow.xml +534 -0
- package/.speccrew/skills/speccrew-system-deployer-orchestration/SKILL.md +91 -0
- package/.speccrew/skills/speccrew-system-deployer-orchestration/workflow.agentflow.xml +309 -0
- package/.speccrew/skills/speccrew-system-designer-orchestration/SKILL.md +102 -0
- package/.speccrew/skills/speccrew-system-designer-orchestration/workflow.agentflow.xml +375 -0
- package/.speccrew/skills/speccrew-system-developer-orchestration/SKILL.md +110 -0
- package/.speccrew/skills/speccrew-system-developer-orchestration/workflow.agentflow.xml +422 -0
- package/.speccrew/skills/speccrew-task-worker-execution/SKILL.md +106 -0
- package/.speccrew/skills/speccrew-task-worker-execution/workflow.agentflow.xml +177 -0
- package/.speccrew/skills/speccrew-test-manager-orchestration/SKILL.md +106 -0
- package/.speccrew/skills/speccrew-test-manager-orchestration/workflow.agentflow.xml +442 -0
- package/package.json +1 -1
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<workflow id="fd-orchestration-main" status="pending">
|
|
3
|
+
|
|
4
|
+
<!-- ========== Input Parameters ========== -->
|
|
5
|
+
<block type="input" id="I1" desc="FD Orchestration Input">
|
|
6
|
+
<field name="prd_path" required="true" type="string" desc="PRD document directory path"/>
|
|
7
|
+
<field name="iteration_path" required="true" type="string" desc="Current iteration directory path"/>
|
|
8
|
+
<field name="workspace_root" required="true" type="string" desc="speccrew-workspace root directory path"/>
|
|
9
|
+
<field name="frontend_platforms" required="false" type="array" desc="Frontend platform list from techs-manifest"/>
|
|
10
|
+
</block>
|
|
11
|
+
|
|
12
|
+
<!-- ========== Phase 0: Workflow Progress Management ========== -->
|
|
13
|
+
<sequence name="Phase 0: Workflow Progress Management">
|
|
14
|
+
|
|
15
|
+
<!-- Phase 0.1: Stage Gate — Verify Upstream Completion -->
|
|
16
|
+
<block type="task" id="P0-B1" action="run-script" status="pending" desc="Read WORKFLOW-PROGRESS.json overview">
|
|
17
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js read --file ${iteration_path}/WORKFLOW-PROGRESS.json --overview</field>
|
|
18
|
+
<field name="output" var="workflow_progress"/>
|
|
19
|
+
</block>
|
|
20
|
+
|
|
21
|
+
<block type="gateway" id="P0-G1" mode="exclusive" desc="Verify PRD Stage Status">
|
|
22
|
+
<branch test="${workflow_progress.stages.01_prd.status} != 'confirmed'" name="PRD Not Confirmed">
|
|
23
|
+
<block type="event" id="P0-E1" action="log" desc="Report PRD not confirmed">
|
|
24
|
+
<field name="message">❌ PRD stage has not been confirmed. Please complete PRD confirmation first using the Product Manager agent.</field>
|
|
25
|
+
</block>
|
|
26
|
+
<block type="abort" id="P0-ABORT1" reason="Stage gate failed"/>
|
|
27
|
+
</branch>
|
|
28
|
+
<branch default="true" name="PRD Confirmed - Proceed"/>
|
|
29
|
+
</block>
|
|
30
|
+
|
|
31
|
+
<block type="task" id="P0-B2" action="run-script" status="pending" desc="Update stage status to in_progress">
|
|
32
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js update-workflow --file ${iteration_path}/WORKFLOW-PROGRESS.json --stage 02_feature_design --status in_progress</field>
|
|
33
|
+
</block>
|
|
34
|
+
|
|
35
|
+
<!-- Phase 0.2: Check Resume State -->
|
|
36
|
+
<block type="gateway" id="P0-G2" mode="exclusive" desc="Check checkpoint file">
|
|
37
|
+
<branch test="exists(${iteration_path}/02.feature-design/.checkpoints.json)" name="Has Checkpoint">
|
|
38
|
+
<block type="task" id="P0-B3" action="run-script" status="pending" desc="Read checkpoints">
|
|
39
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js read --file ${iteration_path}/02.feature-design/.checkpoints.json --checkpoints</field>
|
|
40
|
+
<field name="output" var="checkpoints"/>
|
|
41
|
+
</block>
|
|
42
|
+
|
|
43
|
+
<block type="gateway" id="P0-G3" mode="exclusive" desc="Evaluate checkpoint status">
|
|
44
|
+
<branch test="${checkpoints.api_contract_joint.passed} == true" name="All Complete">
|
|
45
|
+
<block type="event" id="P0-E2" action="confirm" desc="Ask user about redo">
|
|
46
|
+
<field name="prompt">Feature Design phase already completed. Do you want to redo?</field>
|
|
47
|
+
</block>
|
|
48
|
+
</branch>
|
|
49
|
+
<branch test="${checkpoints.feature_spec_review.passed} == true" name="Resume from Phase 4">
|
|
50
|
+
<block type="set-variable" id="P0-V1" name="resume_phase" value="4"/>
|
|
51
|
+
</branch>
|
|
52
|
+
<branch test="${checkpoints.function_decomposition.passed} == true" name="Resume from Phase 3b">
|
|
53
|
+
<block type="set-variable" id="P0-V2" name="resume_phase" value="3b"/>
|
|
54
|
+
</branch>
|
|
55
|
+
<branch default="true" name="Resume from Phase 1"/>
|
|
56
|
+
</block>
|
|
57
|
+
|
|
58
|
+
<block type="event" id="P0-E3" action="log" desc="Display resume summary">
|
|
59
|
+
<field name="template">resume-summary</field>
|
|
60
|
+
<field name="data" value="${checkpoints}"/>
|
|
61
|
+
</block>
|
|
62
|
+
</branch>
|
|
63
|
+
<branch default="true" name="No Checkpoint - Fresh Start">
|
|
64
|
+
<block type="set-variable" id="P0-V3" name="resume_phase" value="1"/>
|
|
65
|
+
</branch>
|
|
66
|
+
</block>
|
|
67
|
+
|
|
68
|
+
<!-- Phase 0.3: Check Dispatch Resume -->
|
|
69
|
+
<block type="gateway" id="P0-G4" mode="exclusive" desc="Check dispatch progress">
|
|
70
|
+
<branch test="exists(${iteration_path}/02.feature-design/DISPATCH-PROGRESS.json)" name="Has Dispatch Progress">
|
|
71
|
+
<block type="task" id="P0-B4" action="run-script" status="pending" desc="Read dispatch summary">
|
|
72
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js read --file ${iteration_path}/02.feature-design/DISPATCH-PROGRESS.json --summary</field>
|
|
73
|
+
<field name="output" var="dispatch_progress"/>
|
|
74
|
+
</block>
|
|
75
|
+
<block type="event" id="P0-E4" action="log" desc="Display dispatch status">
|
|
76
|
+
<field name="template">dispatch-status</field>
|
|
77
|
+
<field name="data" value="${dispatch_progress}"/>
|
|
78
|
+
</block>
|
|
79
|
+
</branch>
|
|
80
|
+
<branch default="true" name="No Dispatch Progress"/>
|
|
81
|
+
</block>
|
|
82
|
+
</sequence>
|
|
83
|
+
|
|
84
|
+
<!-- ========== Phase 1: Preparation ========== -->
|
|
85
|
+
<sequence name="Phase 1: Preparation">
|
|
86
|
+
|
|
87
|
+
<!-- Phase 1.1: Identify PRD Documents -->
|
|
88
|
+
<block type="task" id="P1-B1" action="glob-files" status="pending" desc="Find PRD documents">
|
|
89
|
+
<field name="path" value="${prd_path}"/>
|
|
90
|
+
<field name="pattern" value="*-prd.md"/>
|
|
91
|
+
<field name="output" var="prd_files"/>
|
|
92
|
+
</block>
|
|
93
|
+
|
|
94
|
+
<!-- Phase 1.2: Check Existing Feature Specs -->
|
|
95
|
+
<block type="task" id="P1-B2" action="glob-files" status="pending" desc="Check existing feature specs">
|
|
96
|
+
<field name="path" value="${iteration_path}/02.feature-design"/>
|
|
97
|
+
<field name="pattern" value="*-feature-spec.md"/>
|
|
98
|
+
<field name="output" var="existing_specs"/>
|
|
99
|
+
</block>
|
|
100
|
+
|
|
101
|
+
<block type="gateway" id="P1-G1" mode="exclusive" desc="Check for existing specs">
|
|
102
|
+
<branch test="${existing_specs.count} > 0" name="Has Existing Specs">
|
|
103
|
+
<block type="event" id="P1-E1" action="confirm" desc="Ask user about overwrite">
|
|
104
|
+
<field name="prompt">Existing feature specification documents found. Overwrite or create new version?</field>
|
|
105
|
+
<field name="options" value="overwrite,new_version"/>
|
|
106
|
+
</block>
|
|
107
|
+
</branch>
|
|
108
|
+
<branch default="true" name="No Existing Specs - Proceed"/>
|
|
109
|
+
</block>
|
|
110
|
+
</sequence>
|
|
111
|
+
|
|
112
|
+
<!-- ========== Phase 2: Load Feature List ========== -->
|
|
113
|
+
<sequence name="Phase 2: Load Feature List">
|
|
114
|
+
|
|
115
|
+
<block type="rule" id="P2-R1" level="mandatory" desc="Phase 2 Orchestrator Rules">
|
|
116
|
+
<field name="text">DO NOT read PRD files directly</field>
|
|
117
|
+
<field name="text">DO NOT parse Feature Breakdown tables yourself</field>
|
|
118
|
+
<field name="text">ONLY read .prd-feature-list.json generated by PM Agent</field>
|
|
119
|
+
<field name="text">ONLY present summary and collect user confirmation</field>
|
|
120
|
+
</block>
|
|
121
|
+
|
|
122
|
+
<!-- Step 1: Confirm PRD Path -->
|
|
123
|
+
<block type="task" id="P2-B1" action="read-json" status="pending" desc="Read feature list">
|
|
124
|
+
<field name="path" value="${prd_path}/.prd-feature-list.json"/>
|
|
125
|
+
<field name="output" var="feature_list"/>
|
|
126
|
+
</block>
|
|
127
|
+
|
|
128
|
+
<block type="gateway" id="P2-G1" mode="exclusive" desc="Check feature list file">
|
|
129
|
+
<branch test="${feature_list} == null" name="File Not Found">
|
|
130
|
+
<block type="event" id="P2-E1" action="log" desc="Report missing feature list">
|
|
131
|
+
<field name="message">❌ ERROR: Feature list file not found. This file should be generated by PM Agent during Sub-PRD dispatch.</field>
|
|
132
|
+
</block>
|
|
133
|
+
<block type="abort" id="P2-ABORT1" reason="Feature list file missing"/>
|
|
134
|
+
</branch>
|
|
135
|
+
<branch default="true" name="File Exists"/>
|
|
136
|
+
</block>
|
|
137
|
+
|
|
138
|
+
<!-- Step 2-3: Verify Structure & Extract Statistics -->
|
|
139
|
+
<block type="task" id="P2-B2" action="extract-statistics" status="pending" desc="Extract feature statistics">
|
|
140
|
+
<field name="feature_list" value="${feature_list}"/>
|
|
141
|
+
<field name="output" var="feature_stats"/>
|
|
142
|
+
<field name="output" var="total_features"/>
|
|
143
|
+
<field name="output" var="total_modules"/>
|
|
144
|
+
</block>
|
|
145
|
+
|
|
146
|
+
<block type="event" id="P2-E2" action="log" desc="Display feature list summary">
|
|
147
|
+
<field name="template">feature-list-summary</field>
|
|
148
|
+
<field name="data" value="${feature_stats}"/>
|
|
149
|
+
</block>
|
|
150
|
+
|
|
151
|
+
<!-- Step 4: Write Checkpoint -->
|
|
152
|
+
<block type="task" id="P2-B3" action="run-script" status="pending" desc="Write feature checkpoint">
|
|
153
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js write-checkpoint --file ${iteration_path}/02.feature-design/.checkpoints.json --stage 02_feature_design --checkpoint function_decomposition --data '${feature_list_json}'</field>
|
|
154
|
+
</block>
|
|
155
|
+
|
|
156
|
+
<!-- Step 5: HARD STOP — User Confirmation -->
|
|
157
|
+
<block type="checkpoint" id="P2-CP1" name="feature_list_confirmation" desc="Feature List confirmation gate">
|
|
158
|
+
<field name="required" value="true"/>
|
|
159
|
+
</block>
|
|
160
|
+
|
|
161
|
+
<block type="event" id="P2-E3" action="confirm" desc="Present feature list for confirmation">
|
|
162
|
+
<field name="prompt">⚠️ HARD STOP — Please review the Feature List before proceeding to Feature Design. Confirm the granularity, IDs, Types, and dependencies are correct.</field>
|
|
163
|
+
<field name="template">feature-list-table</field>
|
|
164
|
+
<field name="data" value="${feature_list}"/>
|
|
165
|
+
</block>
|
|
166
|
+
|
|
167
|
+
<block type="task" id="P2-B4" action="run-script" status="pending" desc="Update checkpoint passed">
|
|
168
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js write-checkpoint --file ${iteration_path}/02.feature-design/.checkpoints.json --stage 02_feature_design --checkpoint function_decomposition --passed true</field>
|
|
169
|
+
</block>
|
|
170
|
+
|
|
171
|
+
<!-- Determine dispatch mode -->
|
|
172
|
+
<block type="gateway" id="P2-G2" mode="exclusive" desc="Determine dispatch mode">
|
|
173
|
+
<branch test="${total_features} == 1" name="Single Feature">
|
|
174
|
+
<block type="set-variable" id="P2-V1" name="dispatch_mode" value="direct"/>
|
|
175
|
+
</branch>
|
|
176
|
+
<branch test="${total_features} >= 2" name="Multiple Features">
|
|
177
|
+
<block type="set-variable" id="P2-V2" name="dispatch_mode" value="worker"/>
|
|
178
|
+
</branch>
|
|
179
|
+
</block>
|
|
180
|
+
</sequence>
|
|
181
|
+
|
|
182
|
+
<!-- ========== Phase 3: Feature Design — Two-Stage Pipeline ========== -->
|
|
183
|
+
<sequence name="Phase 3: Feature Design — Two-Stage Pipeline">
|
|
184
|
+
|
|
185
|
+
<block type="rule" id="P3-R1" level="mandatory" desc="Phase 3 Mandatory Rules">
|
|
186
|
+
<field name="text">DO NOT ask user which strategy to use - strategy determined by Phase 2 extraction</field>
|
|
187
|
+
<field name="text">DO NOT invoke skills directly when 2+ Features - MUST dispatch speccrew-task-worker</field>
|
|
188
|
+
<field name="text">Dispatch granularity is PER FEATURE, not per module</field>
|
|
189
|
+
<field name="text">DO NOT generate Feature Spec documents yourself - role is to DISPATCH workers</field>
|
|
190
|
+
<field name="text">Phase 3a → 3b → 3c is STRICTLY SERIAL</field>
|
|
191
|
+
<field name="text">Feature name is LOCKED after Phase 2 confirmation</field>
|
|
192
|
+
</block>
|
|
193
|
+
|
|
194
|
+
<!-- ========== Phase 3a: Analyze — Function Decomposition ========== -->
|
|
195
|
+
<block type="event" id="P3-E1" action="log" desc="Start Phase 3a">
|
|
196
|
+
<field name="message">📊 Phase 3a: Analyze — Function Decomposition</field>
|
|
197
|
+
</block>
|
|
198
|
+
|
|
199
|
+
<block type="gateway" id="P3-G1" mode="exclusive" desc="Dispatch mode for Phase 3a">
|
|
200
|
+
|
|
201
|
+
<!-- Single Feature: Direct Invocation -->
|
|
202
|
+
<branch test="${dispatch_mode} == 'direct'" name="Direct Invocation">
|
|
203
|
+
<block type="task" id="P3-B1" action="run-skill" status="pending" desc="Invoke feature analyze skill">
|
|
204
|
+
<field name="skill">speccrew-fd-feature-analyze</field>
|
|
205
|
+
<field name="context">
|
|
206
|
+
prd_path: ${prd_files[0]}
|
|
207
|
+
feature_id: ${feature_list.modules[0].features[0].feature_id}
|
|
208
|
+
feature_name: ${feature_list.modules[0].features[0].feature_name}
|
|
209
|
+
feature_type: ${feature_list.modules[0].features[0].feature_type}
|
|
210
|
+
iteration_id: ${iteration_path}
|
|
211
|
+
frontend_platforms: ${frontend_platforms}
|
|
212
|
+
</field>
|
|
213
|
+
<field name="output" var="analyze_result"/>
|
|
214
|
+
</block>
|
|
215
|
+
</branch>
|
|
216
|
+
|
|
217
|
+
<!-- Multiple Features: Worker Dispatch -->
|
|
218
|
+
<branch test="${dispatch_mode} == 'worker'" name="Worker Dispatch">
|
|
219
|
+
|
|
220
|
+
<block type="rule" id="P3-R2" level="mandatory" desc="Worker dispatch rules">
|
|
221
|
+
<field name="text">MUST dispatch Workers for ALL tasks with status pending</field>
|
|
222
|
+
<field name="text">DO NOT skip any pending task</field>
|
|
223
|
+
<field name="text">DO NOT stop mid-way to ask user for options</field>
|
|
224
|
+
</block>
|
|
225
|
+
|
|
226
|
+
<!-- Initialize DISPATCH-PROGRESS.json -->
|
|
227
|
+
<block type="task" id="P3-B2" action="run-script" status="pending" desc="Initialize dispatch progress">
|
|
228
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js init --file ${iteration_path}/02.feature-design/DISPATCH-PROGRESS.json --stage 02_feature_design_analyze --tasks-file ${iteration_path}/02.feature-design/.tasks-temp.json</field>
|
|
229
|
+
</block>
|
|
230
|
+
|
|
231
|
+
<!-- Dispatch Workers in batches of 6 -->
|
|
232
|
+
<block type="loop" id="P3-L1" mode="batch" batch_size="6" desc="Dispatch analyze workers">
|
|
233
|
+
<field name="items" value="${all_features}"/>
|
|
234
|
+
|
|
235
|
+
<block type="task" id="P3-B3" action="dispatch-to-worker" status="pending" desc="Dispatch analyze worker">
|
|
236
|
+
<field name="agent">speccrew-task-worker</field>
|
|
237
|
+
<field name="skill">speccrew-fd-feature-analyze</field>
|
|
238
|
+
<field name="context">
|
|
239
|
+
prd_path: ${item.prd_path}
|
|
240
|
+
feature_id: ${item.feature_id}
|
|
241
|
+
feature_name: ${item.feature_name}
|
|
242
|
+
feature_type: ${item.feature_type}
|
|
243
|
+
iteration_id: ${iteration_path}
|
|
244
|
+
frontend_platforms: ${frontend_platforms}
|
|
245
|
+
skip_checkpoint: true
|
|
246
|
+
</field>
|
|
247
|
+
</block>
|
|
248
|
+
|
|
249
|
+
<block type="task" id="P3-B4" action="run-script" status="pending" desc="Update worker progress">
|
|
250
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js update-task --file ${iteration_path}/02.feature-design/DISPATCH-PROGRESS.json --task-id ${item.feature_id} --status ${worker_status}</field>
|
|
251
|
+
</block>
|
|
252
|
+
</block>
|
|
253
|
+
|
|
254
|
+
<!-- All completed: Present summary -->
|
|
255
|
+
<block type="event" id="P3-E2" action="log" desc="Display analyze summary">
|
|
256
|
+
<field name="template">analyze-summary</field>
|
|
257
|
+
<field name="data" value="${analyze_results}"/>
|
|
258
|
+
</block>
|
|
259
|
+
|
|
260
|
+
<block type="event" id="P3-E3" action="confirm" desc="HARD STOP for analyze confirmation">
|
|
261
|
+
<field name="prompt">📊 Phase 3a (Analyze) complete. Does this function breakdown align with your understanding?</field>
|
|
262
|
+
</block>
|
|
263
|
+
</branch>
|
|
264
|
+
</block>
|
|
265
|
+
|
|
266
|
+
<!-- ========== Phase 3b: Design & Generate — Feature Spec Production ========== -->
|
|
267
|
+
<block type="event" id="P3-E4" action="log" desc="Start Phase 3b">
|
|
268
|
+
<field name="message">📊 Phase 3b: Design & Generate — Feature Spec Production</field>
|
|
269
|
+
</block>
|
|
270
|
+
|
|
271
|
+
<block type="gateway" id="P3-G2" mode="exclusive" desc="Dispatch mode for Phase 3b">
|
|
272
|
+
|
|
273
|
+
<!-- Single Feature: Direct Invocation -->
|
|
274
|
+
<branch test="${dispatch_mode} == 'direct'" name="Direct Invocation">
|
|
275
|
+
<block type="task" id="P3-B5" action="run-skill" status="pending" desc="Invoke feature design skill">
|
|
276
|
+
<field name="skill">speccrew-fd-feature-design</field>
|
|
277
|
+
<field name="context">
|
|
278
|
+
feature_analysis_path: ${analyze_result.output_path}
|
|
279
|
+
prd_path: ${prd_files[0]}
|
|
280
|
+
feature_id: ${feature_list.modules[0].features[0].feature_id}
|
|
281
|
+
feature_name: ${feature_list.modules[0].features[0].feature_name}
|
|
282
|
+
feature_type: ${feature_list.modules[0].features[0].feature_type}
|
|
283
|
+
frontend_platforms: ${frontend_platforms}
|
|
284
|
+
output_path: ${iteration_path}/02.feature-design/${feature_id}-${feature_name}-feature-spec.md
|
|
285
|
+
</field>
|
|
286
|
+
<field name="output" var="design_result"/>
|
|
287
|
+
</block>
|
|
288
|
+
</branch>
|
|
289
|
+
|
|
290
|
+
<!-- Multiple Features: Worker Dispatch -->
|
|
291
|
+
<branch test="${dispatch_mode} == 'worker'" name="Worker Dispatch">
|
|
292
|
+
|
|
293
|
+
<!-- Initialize DISPATCH-PROGRESS.json for Design stage -->
|
|
294
|
+
<block type="task" id="P3-B6" action="run-script" status="pending" desc="Initialize design dispatch progress">
|
|
295
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js init --file ${iteration_path}/02.feature-design/DISPATCH-PROGRESS.json --stage 02_feature_design_spec --tasks-file ${iteration_path}/02.feature-design/.tasks-temp.json</field>
|
|
296
|
+
</block>
|
|
297
|
+
|
|
298
|
+
<!-- Dispatch Workers in batches of 6 -->
|
|
299
|
+
<block type="loop" id="P3-L2" mode="batch" batch_size="6" desc="Dispatch design workers">
|
|
300
|
+
<field name="items" value="${all_features}"/>
|
|
301
|
+
|
|
302
|
+
<block type="task" id="P3-B7" action="dispatch-to-worker" status="pending" desc="Dispatch design worker">
|
|
303
|
+
<field name="agent">speccrew-task-worker</field>
|
|
304
|
+
<field name="skill">speccrew-fd-feature-design</field>
|
|
305
|
+
<field name="context">
|
|
306
|
+
feature_analysis_path: ${item.analysis_path}
|
|
307
|
+
prd_path: ${item.prd_path}
|
|
308
|
+
feature_id: ${item.feature_id}
|
|
309
|
+
feature_name: ${item.feature_name}
|
|
310
|
+
feature_type: ${item.feature_type}
|
|
311
|
+
frontend_platforms: ${frontend_platforms}
|
|
312
|
+
output_path: ${iteration_path}/02.feature-design/${item.feature_id}-${item.feature_name}-feature-spec.md
|
|
313
|
+
skip_checkpoint: true
|
|
314
|
+
</field>
|
|
315
|
+
</block>
|
|
316
|
+
|
|
317
|
+
<block type="task" id="P3-B8" action="run-script" status="pending" desc="Update worker progress">
|
|
318
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js update-task --file ${iteration_path}/02.feature-design/DISPATCH-PROGRESS.json --task-id ${item.feature_id} --status ${worker_status}</field>
|
|
319
|
+
</block>
|
|
320
|
+
</block>
|
|
321
|
+
</branch>
|
|
322
|
+
</block>
|
|
323
|
+
|
|
324
|
+
<!-- ========== Phase 3c: Confirm — Batch Spec Review (Multi-Feature Only) ========== -->
|
|
325
|
+
<block type="gateway" id="P3-G3" mode="exclusive" desc="Check if Phase 3c needed">
|
|
326
|
+
<branch test="${dispatch_mode} == 'worker'" name="Multi-Feature Confirmation">
|
|
327
|
+
|
|
328
|
+
<block type="rule" id="P3-R3" level="mandatory" desc="Phase 3c Orchestrator Rules">
|
|
329
|
+
<field name="text">DO NOT read feature-spec.md files for summary aggregation</field>
|
|
330
|
+
<field name="text">DO NOT count functions/components/APIs by parsing Spec documents</field>
|
|
331
|
+
<field name="text">ONLY read DISPATCH-PROGRESS.json for summary data</field>
|
|
332
|
+
</block>
|
|
333
|
+
|
|
334
|
+
<block type="task" id="P3-B9" action="run-script" status="pending" desc="Read progress summary">
|
|
335
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js read --file ${iteration_path}/02.feature-design/DISPATCH-PROGRESS.json --overview</field>
|
|
336
|
+
<field name="output" var="design_progress"/>
|
|
337
|
+
</block>
|
|
338
|
+
|
|
339
|
+
<block type="event" id="P3-E5" action="confirm" desc="HARD STOP for batch spec review">
|
|
340
|
+
<field name="prompt">📋 Batch Feature Spec Summary. Please review all Feature Specs before proceeding to API Contract generation.</field>
|
|
341
|
+
<field name="template">batch-spec-summary</field>
|
|
342
|
+
<field name="data" value="${design_progress}"/>
|
|
343
|
+
</block>
|
|
344
|
+
|
|
345
|
+
<block type="task" id="P3-B10" action="run-script" status="pending" desc="Update checkpoint">
|
|
346
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js write-checkpoint --file ${iteration_path}/02.feature-design/.checkpoints.json --stage 02_feature_design --checkpoint feature_spec_review --passed true</field>
|
|
347
|
+
</block>
|
|
348
|
+
</branch>
|
|
349
|
+
<branch default="true" name="Single Feature - Skip Phase 3c"/>
|
|
350
|
+
</block>
|
|
351
|
+
|
|
352
|
+
<!-- Phase 3 Error Handling -->
|
|
353
|
+
<block type="gateway" id="P3-G4" mode="exclusive" desc="Check for errors">
|
|
354
|
+
<branch test="${batch_failed_count} > ${batch_total} / 2" name="Majority Failed">
|
|
355
|
+
<block type="event" id="P3-E6" action="log" desc="Report batch failure">
|
|
356
|
+
<field name="message">⚠️ More than 50% workers failed. Stopping workflow.</field>
|
|
357
|
+
</block>
|
|
358
|
+
<block type="abort" id="P3-ABORT1" reason="Batch failure threshold exceeded"/>
|
|
359
|
+
</branch>
|
|
360
|
+
<branch test="${batch_failed_count} > 0" name="Some Failed">
|
|
361
|
+
<block type="event" id="P3-E7" action="confirm" desc="Ask for retry strategy">
|
|
362
|
+
<field name="prompt">Some features failed. Retry failed features?</field>
|
|
363
|
+
</block>
|
|
364
|
+
</branch>
|
|
365
|
+
<branch default="true" name="All Success"/>
|
|
366
|
+
</block>
|
|
367
|
+
</sequence>
|
|
368
|
+
|
|
369
|
+
<!-- ========== Phase 4: API Contract Generation ========== -->
|
|
370
|
+
<sequence name="Phase 4: API Contract Generation">
|
|
371
|
+
|
|
372
|
+
<block type="event" id="P4-E1" action="log" desc="Start Phase 4">
|
|
373
|
+
<field name="message">📊 Phase 4: API Contract Generation</field>
|
|
374
|
+
</block>
|
|
375
|
+
|
|
376
|
+
<!-- Phase 4.1: Dispatch Mode Decision -->
|
|
377
|
+
<block type="gateway" id="P4-G1" mode="exclusive" desc="Dispatch mode for API Contract">
|
|
378
|
+
|
|
379
|
+
<!-- Single Feature: Direct Invocation -->
|
|
380
|
+
<branch test="${dispatch_mode} == 'direct'" name="Direct Invocation">
|
|
381
|
+
<block type="task" id="P4-B1" action="run-skill" status="pending" desc="Invoke API contract skill">
|
|
382
|
+
<field name="skill">speccrew-fd-api-contract</field>
|
|
383
|
+
<field name="context">
|
|
384
|
+
feature_spec_path: ${design_result.output_path}
|
|
385
|
+
feature_id: ${feature_list.modules[0].features[0].feature_id}
|
|
386
|
+
feature_name: ${feature_list.modules[0].features[0].feature_name}
|
|
387
|
+
feature_type: ${feature_list.modules[0].features[0].feature_type}
|
|
388
|
+
output_path: ${iteration_path}/02.feature-design/${feature_id}-${feature_name}-api-contract.md
|
|
389
|
+
</field>
|
|
390
|
+
<field name="output" var="api_contract_result"/>
|
|
391
|
+
</block>
|
|
392
|
+
</branch>
|
|
393
|
+
|
|
394
|
+
<!-- Multiple Features: Worker Dispatch -->
|
|
395
|
+
<branch test="${dispatch_mode} == 'worker'" name="Worker Dispatch">
|
|
396
|
+
|
|
397
|
+
<block type="rule" id="P4-R1" level="mandatory" desc="Phase 4 Worker Rules">
|
|
398
|
+
<field name="text">MUST dispatch Workers via speccrew-task-worker</field>
|
|
399
|
+
<field name="text">DO NOT invoke speccrew-fd-api-contract directly</field>
|
|
400
|
+
</block>
|
|
401
|
+
|
|
402
|
+
<!-- Initialize DISPATCH-PROGRESS.json for API Contract stage -->
|
|
403
|
+
<block type="task" id="P4-B2" action="run-script" status="pending" desc="Initialize API contract dispatch">
|
|
404
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js init --file ${iteration_path}/02.feature-design/DISPATCH-PROGRESS.json --stage 02_feature_design_api_contract --tasks-file ${iteration_path}/02.feature-design/.tasks-temp.json</field>
|
|
405
|
+
</block>
|
|
406
|
+
|
|
407
|
+
<!-- Dispatch Workers in batches of 6 -->
|
|
408
|
+
<block type="loop" id="P4-L1" mode="batch" batch_size="6" desc="Dispatch API contract workers">
|
|
409
|
+
<field name="items" value="${all_features}"/>
|
|
410
|
+
|
|
411
|
+
<block type="task" id="P4-B3" action="dispatch-to-worker" status="pending" desc="Dispatch API contract worker">
|
|
412
|
+
<field name="agent">speccrew-task-worker</field>
|
|
413
|
+
<field name="skill">speccrew-fd-api-contract</field>
|
|
414
|
+
<field name="context">
|
|
415
|
+
feature_spec_path: ${item.spec_path}
|
|
416
|
+
feature_id: ${item.feature_id}
|
|
417
|
+
feature_name: ${item.feature_name}
|
|
418
|
+
feature_type: ${item.feature_type}
|
|
419
|
+
output_path: ${iteration_path}/02.feature-design/${item.feature_id}-${item.feature_name}-api-contract.md
|
|
420
|
+
</field>
|
|
421
|
+
</block>
|
|
422
|
+
|
|
423
|
+
<block type="task" id="P4-B4" action="run-script" status="pending" desc="Update worker progress">
|
|
424
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js update-task --file ${iteration_path}/02.feature-design/DISPATCH-PROGRESS.json --task-id ${item.feature_id} --status ${worker_status}</field>
|
|
425
|
+
</block>
|
|
426
|
+
</block>
|
|
427
|
+
</branch>
|
|
428
|
+
</block>
|
|
429
|
+
|
|
430
|
+
<!-- Phase 4.4: Joint Confirmation -->
|
|
431
|
+
<block type="checkpoint" id="P4-CP1" name="api_contract_joint" desc="Joint confirmation gate">
|
|
432
|
+
<field name="required" value="true"/>
|
|
433
|
+
</block>
|
|
434
|
+
|
|
435
|
+
<block type="event" id="P4-E2" action="confirm" desc="Present for joint confirmation">
|
|
436
|
+
<field name="prompt">📋 Feature Design Complete. Please review all Feature Spec and API Contract documents before confirmation.</field>
|
|
437
|
+
<field name="template">joint-confirmation</field>
|
|
438
|
+
<field name="data" value="${all_outputs}"/>
|
|
439
|
+
</block>
|
|
440
|
+
|
|
441
|
+
<block type="task" id="P4-B5" action="run-script" status="pending" desc="Update joint confirmation checkpoint">
|
|
442
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js write-checkpoint --file ${iteration_path}/02.feature-design/.checkpoints.json --stage 02_feature_design --checkpoint api_contract_joint --passed true</field>
|
|
443
|
+
</block>
|
|
444
|
+
|
|
445
|
+
<!-- Phase 4.5: Finalize Stage -->
|
|
446
|
+
<block type="task" id="P4-B6" action="run-script" status="pending" desc="Update workflow progress">
|
|
447
|
+
<field name="command">node ${workspace_root}/scripts/update-progress.js update-workflow --file ${iteration_path}/WORKFLOW-PROGRESS.json --stage 02_feature_design --status confirmed --output "${output_files}"</field>
|
|
448
|
+
</block>
|
|
449
|
+
|
|
450
|
+
<block type="event" id="P4-E3" action="log" desc="Output completion message">
|
|
451
|
+
<field name="message">✅ Feature Design phase completed and confirmed. Ready to start System Design phase.</field>
|
|
452
|
+
</block>
|
|
453
|
+
</sequence>
|
|
454
|
+
|
|
455
|
+
<!-- ========== Output ========== -->
|
|
456
|
+
<block type="output" id="O1" desc="FD Orchestration execution result">
|
|
457
|
+
<field name="status" from="${execution.status}" type="string" desc="success / partial / failed"/>
|
|
458
|
+
<field name="feature_specs" from="${feature_spec_files}" type="array" desc="Generated feature spec file list"/>
|
|
459
|
+
<field name="api_contracts" from="${api_contract_files}" type="array" desc="Generated API contract file list"/>
|
|
460
|
+
<field name="workflow_stage" from="02_feature_design" type="string" desc="Current workflow stage"/>
|
|
461
|
+
<field name="next_agent" value="speccrew-system-designer" type="string" desc="Suggested next agent"/>
|
|
462
|
+
</block>
|
|
463
|
+
</workflow>
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
<field name="completed_dir" required="true" type="string" desc="Marker files output directory"/>
|
|
16
16
|
<field name="sourceFile" required="true" type="string" desc="Source features JSON file name"/>
|
|
17
17
|
<field name="language" required="true" type="string" desc="Target language for content"/>
|
|
18
|
+
<field name="workspace_path" required="true" type="string" desc="Workspace root path"/>
|
|
18
19
|
</block>
|
|
19
20
|
|
|
20
21
|
<!-- ==================== CONSTRAINT RULES ==================== -->
|
|
@@ -248,7 +249,7 @@
|
|
|
248
249
|
<field name="text">
|
|
249
250
|
The output document file MUST be created at the EXACT path specified by ${documentPath} input parameter.
|
|
250
251
|
DO NOT use the template file name (e.g., FEATURE-DETAIL-TEMPLATE-*.md) as the output file name.
|
|
251
|
-
The documentPath already contains the correct target path including file name (e.g., speccrew-workspace/knowledges/bizs/backend-
|
|
252
|
+
The documentPath already contains the correct target path including file name (e.g., speccrew-workspace/knowledges/bizs/backend-fastapi/admin/cache/cache_controller.md).
|
|
252
253
|
Before creating the file, ensure the parent directory exists (create if necessary).
|
|
253
254
|
</field>
|
|
254
255
|
</block>
|
|
@@ -478,17 +479,125 @@
|
|
|
478
479
|
<field name="verify" value="file.exists(${completed_dir}/${markerName}.done.json)"/>
|
|
479
480
|
</block>
|
|
480
481
|
|
|
481
|
-
<!--
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
<field name="
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
482
|
+
<!-- Step 7b: Construct and Append Graph Data -->
|
|
483
|
+
<!-- Construct Graph Nodes from API Analysis -->
|
|
484
|
+
<block type="task" id="B32a" action="analyze" desc="Construct API endpoint nodes">
|
|
485
|
+
<field name="endpoints" value="${endpoints}"/>
|
|
486
|
+
<field name="module" value="${module}"/>
|
|
487
|
+
<field name="sourcePath" value="${sourcePath}"/>
|
|
488
|
+
<field name="documentPath" value="${documentPath}"/>
|
|
489
|
+
<field name="output" var="apiNodes"/>
|
|
490
|
+
</block>
|
|
491
|
+
|
|
492
|
+
<block type="task" id="B32b" action="analyze" desc="Construct service nodes">
|
|
493
|
+
<field name="services" value="${services}"/>
|
|
494
|
+
<field name="module" value="${module}"/>
|
|
495
|
+
<field name="sourcePath" value="${sourcePath}"/>
|
|
496
|
+
<field name="documentPath" value="${documentPath}"/>
|
|
497
|
+
<field name="output" var="serviceNodes"/>
|
|
498
|
+
</block>
|
|
499
|
+
|
|
500
|
+
<block type="task" id="B32c" action="analyze" desc="Construct table nodes">
|
|
501
|
+
<field name="tables" value="${databaseTables}"/>
|
|
502
|
+
<field name="module" value="${module}"/>
|
|
503
|
+
<field name="output" var="tableNodes"/>
|
|
504
|
+
</block>
|
|
505
|
+
|
|
506
|
+
<!-- Construct Graph Edges -->
|
|
507
|
+
<block type="task" id="B32d" action="analyze" desc="Construct API-to-Service edges">
|
|
508
|
+
<field name="endpoints" value="${endpoints}"/>
|
|
509
|
+
<field name="module" value="${module}"/>
|
|
510
|
+
<field name="output" var="invokesEdges"/>
|
|
511
|
+
</block>
|
|
512
|
+
|
|
513
|
+
<block type="task" id="B32e" action="analyze" desc="Construct API-to-Table edges">
|
|
514
|
+
<field name="endpoints" value="${endpoints}"/>
|
|
515
|
+
<field name="tables" value="${databaseTables}"/>
|
|
516
|
+
<field name="module" value="${module}"/>
|
|
517
|
+
<field name="output" var="operatesEdges"/>
|
|
518
|
+
</block>
|
|
519
|
+
|
|
520
|
+
<!-- Append Graph Data to nodes.json and edges.json -->
|
|
521
|
+
<block type="task" id="B32f" action="run-script" desc="Append graph nodes to nodes.json">
|
|
522
|
+
<field name="command">node -e "
|
|
523
|
+
const fs = require('fs');
|
|
524
|
+
const path = require('path');
|
|
525
|
+
const graphDir = path.join('${workspace_path}', 'speccrew-workspace', 'knowledges', 'bizs', 'graph');
|
|
526
|
+
const nodesFile = path.join(graphDir, 'nodes.json');
|
|
527
|
+
|
|
528
|
+
// Ensure directory exists
|
|
529
|
+
if (!fs.existsSync(graphDir)) {
|
|
530
|
+
fs.mkdirSync(graphDir, { recursive: true });
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Read existing nodes or initialize empty array
|
|
534
|
+
let existingNodes = [];
|
|
535
|
+
if (fs.existsSync(nodesFile)) {
|
|
536
|
+
try {
|
|
537
|
+
existingNodes = JSON.parse(fs.readFileSync(nodesFile, 'utf8'));
|
|
538
|
+
if (!Array.isArray(existingNodes)) existingNodes = [];
|
|
539
|
+
} catch (e) {
|
|
540
|
+
existingNodes = [];
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Parse new nodes from input
|
|
545
|
+
const newNodes = JSON.parse('${apiNodes}' || '[]').concat(JSON.parse('${serviceNodes}' || '[]')).concat(JSON.parse('${tableNodes}' || '[]'));
|
|
546
|
+
|
|
547
|
+
// Deduplicate by id
|
|
548
|
+
const nodeMap = new Map();
|
|
549
|
+
existingNodes.forEach(n => nodeMap.set(n.id, n));
|
|
550
|
+
newNodes.forEach(n => nodeMap.set(n.id, n));
|
|
551
|
+
|
|
552
|
+
// Write back
|
|
553
|
+
fs.writeFileSync(nodesFile, JSON.stringify(Array.from(nodeMap.values()), null, 2));
|
|
554
|
+
console.log('Nodes appended:', newNodes.length);
|
|
555
|
+
"
|
|
490
556
|
</field>
|
|
491
557
|
</block>
|
|
558
|
+
|
|
559
|
+
<block type="task" id="B32g" action="run-script" desc="Append graph edges to edges.json">
|
|
560
|
+
<field name="command">node -e "
|
|
561
|
+
const fs = require('fs');
|
|
562
|
+
const path = require('path');
|
|
563
|
+
const graphDir = path.join('${workspace_path}', 'speccrew-workspace', 'knowledges', 'bizs', 'graph');
|
|
564
|
+
const edgesFile = path.join(graphDir, 'edges.json');
|
|
565
|
+
|
|
566
|
+
// Read existing edges or initialize empty array
|
|
567
|
+
let existingEdges = [];
|
|
568
|
+
if (fs.existsSync(edgesFile)) {
|
|
569
|
+
try {
|
|
570
|
+
existingEdges = JSON.parse(fs.readFileSync(edgesFile, 'utf8'));
|
|
571
|
+
if (!Array.isArray(existingEdges)) existingEdges = [];
|
|
572
|
+
} catch (e) {
|
|
573
|
+
existingEdges = [];
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// Parse new edges from input
|
|
578
|
+
const newEdges = JSON.parse('${invokesEdges}' || '[]').concat(JSON.parse('${operatesEdges}' || '[]'));
|
|
579
|
+
|
|
580
|
+
// Deduplicate by composite key (source+target+type)
|
|
581
|
+
const edgeMap = new Map();
|
|
582
|
+
existingEdges.forEach(e => {
|
|
583
|
+
const key = e.source + '|' + e.target + '|' + e.type;
|
|
584
|
+
edgeMap.set(key, e);
|
|
585
|
+
});
|
|
586
|
+
newEdges.forEach(e => {
|
|
587
|
+
const key = e.source + '|' + e.target + '|' + e.type;
|
|
588
|
+
edgeMap.set(key, e);
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
// Write back
|
|
592
|
+
fs.writeFileSync(edgesFile, JSON.stringify(Array.from(edgeMap.values()), null, 2));
|
|
593
|
+
console.log('Edges appended:', newEdges.length);
|
|
594
|
+
"
|
|
595
|
+
</field>
|
|
596
|
+
</block>
|
|
597
|
+
|
|
598
|
+
<block type="checkpoint" id="CP-graph" name="graph-written" desc="Graph data written">
|
|
599
|
+
<field name="verify" value="true"/>
|
|
600
|
+
</block>
|
|
492
601
|
|
|
493
602
|
<block type="event" id="E10" action="log" level="info" desc="Log marker status">
|
|
494
603
|
<field name="message" value="Step 7 Status: COMPLETED - Marker file written to ${completed_dir}"/>
|
|
@@ -1001,11 +1001,11 @@ Requirements:
|
|
|
1001
1001
|
"fileName": "UserController",
|
|
1002
1002
|
"sourcePath": "controller/admin/user/UserController.java",
|
|
1003
1003
|
"module": "user",
|
|
1004
|
-
"documentPath": "speccrew-workspace/knowledges/bizs/backend-
|
|
1004
|
+
"documentPath": "speccrew-workspace/knowledges/bizs/backend-spring/user/UserController.md",
|
|
1005
1005
|
"platformType": "backend",
|
|
1006
1006
|
"platformSubtype": "spring",
|
|
1007
|
-
"platformId": "backend-
|
|
1008
|
-
"sourceFile": "features-backend-
|
|
1007
|
+
"platformId": "backend-spring",
|
|
1008
|
+
"sourceFile": "features-backend-spring.json"
|
|
1009
1009
|
}
|
|
1010
1010
|
]
|
|
1011
1011
|
}
|
|
@@ -26,7 +26,7 @@ All generated documents must match the user's language. Detect the language from
|
|
|
26
26
|
|
|
27
27
|
| Parameter | Type | Required | Description |
|
|
28
28
|
|-----------|------|----------|-------------|
|
|
29
|
-
| `platformId` | string | Yes | Platform identifier (e.g., "backend-
|
|
29
|
+
| `platformId` | string | Yes | Platform identifier (e.g., "backend-fastapi", "web-vue3", "mobile-uniapp") |
|
|
30
30
|
| `platformName` | string | Yes | Platform display name |
|
|
31
31
|
| `platformType` | string | Yes | Platform type: backend, web, mobile |
|
|
32
32
|
| `platformSubtype` | string | No | Platform subtype (e.g., vue, react, uniapp) |
|