speccrew 0.6.42 → 0.6.44

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.
@@ -21,25 +21,25 @@ Analyze one specific API controller from source code, extract all business featu
21
21
 
22
22
  | Variable | Type | Description | Example |
23
23
  |----------|------|-------------|---------|
24
- | `{{feature}}` | object | Complete feature object from features.json | - |
25
- | `{{fileName}}` | string | Controller file name | `"UserController"`, `"OrderController"` |
26
- | `{{sourcePath}}` | string | Relative path to source file | `"yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java"` |
27
- | `{{documentPath}}` | string | Target path for generated document | `"speccrew-workspace/knowledges/bizs/admin-api/system/user/UserController.md"` |
28
- | `{{module}}` | string | Business module name (from feature.module) | `"system"`, `"trade"`, `"_root"` |
29
- | `{{analyzed}}` | boolean | Analysis status flag | `true` / `false` |
30
- | `{{platform_type}}` | string | Platform type | `"admin-api"`, `"app-api"` |
31
- | `{{platform_subtype}}` | string | Platform subtype | `"spring-boot"`, `"java"` |
32
- | `{{tech_stack}}` | array | Platform tech stack | `["java", "spring-boot", "mybatis-plus"]` |
33
- | `{{completed_dir}}` | string | Marker files output directory | `"speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed"` |
34
- | `{{sourceFile}}` | string | Source features JSON file name | `"features-admin-api.json"` |
35
- | `{{language}}` | string | Target language for content | `"zh"`, `"en"` |
24
+ | `${feature}` | object | Complete feature object from features.json | - |
25
+ | `${fileName}` | string | Controller file name | `"UserController"`, `"OrderController"` |
26
+ | `${sourcePath}` | string | Relative path to source file | `"yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java"` |
27
+ | `${documentPath}` | string | Target path for generated document | `"speccrew-workspace/knowledges/bizs/admin-api/system/user/UserController.md"` |
28
+ | `${module}` | string | Business module name (from feature.module) | `"system"`, `"trade"`, `"_root"` |
29
+ | `${analyzed}` | boolean | Analysis status flag | `true` / `false` |
30
+ | `${platform_type}` | string | Platform type | `"admin-api"`, `"app-api"` |
31
+ | `${platform_subtype}` | string | Platform subtype | `"spring-boot"`, `"java"` |
32
+ | `${tech_stack}` | array | Platform tech stack | `["java", "spring-boot", "mybatis-plus"]` |
33
+ | `${completed_dir}` | string | Marker files output directory | `"speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed"` |
34
+ | `${sourceFile}` | string | Source features JSON file name | `"features-admin-api.json"` |
35
+ | `${language}` | string | Target language for content | `"zh"`, `"en"` |
36
36
 
37
37
  ## Language Adaptation
38
38
 
39
- **CRITICAL**: Generate all content in the language specified by the `{{language}}` parameter.
39
+ **CRITICAL**: Generate all content in the language specified by the `${language}` parameter.
40
40
 
41
- - `{{language}} == "zh"` → Generate all content in 中文
42
- - `{{language}} == "en"` → Generate all content in English
41
+ - `${language} == "zh"` → Generate all content in 中文
42
+ - `${language} == "en"` → Generate all content in English
43
43
  - Other languages → Use the specified language
44
44
 
45
45
  **All output content (feature names, descriptions, business rules) must be in the target language only.**
@@ -48,10 +48,10 @@ Analyze one specific API controller from source code, extract all business featu
48
48
 
49
49
  | Variable | Type | Description |
50
50
  |----------|------|-------------|
51
- | `{{status}}` | string | Analysis status: `"success"`, `"partial"`, or `"failed"` |
52
- | `{{feature_name}}` | string | Name of the analyzed controller |
53
- | `{{generated_file}}` | string | Path to the generated documentation file |
54
- | `{{message}}` | string | Summary message for status update |
51
+ | `${status}` | string | Analysis status: `"success"`, `"partial"`, or `"failed"` |
52
+ | `${feature_name}` | string | Name of the analyzed controller |
53
+ | `${generated_file}` | string | Path to the generated documentation file |
54
+ | `${message}` | string | Summary message for status update |
55
55
 
56
56
  ## Execution Requirements
57
57
 
@@ -63,8 +63,8 @@ This skill operates in **strict sequential execution mode**:
63
63
  ## Output
64
64
 
65
65
  **Generated Files:**
66
- 1. `{{documentPath}}` - Controller documentation file
67
- 2. `{{completed_dir}}/{module}-{subpath}-{fileName}.done.json` - Completion status marker
66
+ 1. `${documentPath}` - Controller documentation file
67
+ 2. `${completed_dir}/{module}-{subpath}-{fileName}.done.json` - Completion status marker
68
68
 
69
69
  **Graph Data Generation:**
70
70
  Graph data (nodes, edges) construction is handled by `speccrew-knowledge-bizs-api-graph-xml` Skill.
@@ -95,499 +95,527 @@ The return value is used by dispatch to update the feature status in `features-{
95
95
 
96
96
  Before executing the workflow, verify the following inputs:
97
97
 
98
- - Controller: `{{fileName}}` (`{{sourcePath}}`)
99
- - Target: `{{documentPath}}`
100
- - Language: `{{language}}`
101
- - Module: `{{module}}`
102
- - Platform: `{{platform_type}}`/`{{platform_subtype}}`
103
- - Completed Dir: `{{completed_dir}}`
104
- - Source File: `{{sourceFile}}`
98
+ - Controller: `${fileName}` (`${sourcePath}`)
99
+ - Target: `${documentPath}`
100
+ - Language: `${language}`
101
+ - Module: `${module}`
102
+ - Platform: `${platform_type}`/`${platform_subtype}`
103
+ - Completed Dir: `${completed_dir}`
104
+ - Source File: `${sourceFile}`
105
105
 
106
106
  ## Workflow
107
107
 
108
108
  > **REQUIRED**: Before executing this workflow, read the XML workflow specification: `docs/rules/xml-workflow-spec.md`
109
109
 
110
- ```xml
111
- <workflow name="api-controller-analysis" version="1.0">
110
+ <workflow id="api-controller-analysis" status="pending" version="1.0" desc="API controller analysis workflow">
112
111
 
113
112
  <!-- ==================== INPUT PARAMETERS ==================== -->
114
- <input name="feature" type="object" required="true" description="Complete feature object from features.json"/>
115
- <input name="fileName" type="string" required="true" description="Controller file name"/>
116
- <input name="sourcePath" type="string" required="true" description="Relative path to source file"/>
117
- <input name="documentPath" type="string" required="true" description="Target path for generated document"/>
118
- <input name="module" type="string" required="true" description="Business module name"/>
119
- <input name="analyzed" type="boolean" required="true" description="Analysis status flag"/>
120
- <input name="platform_type" type="string" required="true" description="Platform type: admin-api, app-api"/>
121
- <input name="platform_subtype" type="string" required="true" description="Platform subtype: spring-boot, java"/>
122
- <input name="tech_stack" type="array" required="true" description="Platform tech stack"/>
123
- <input name="completed_dir" type="string" required="true" description="Marker files output directory"/>
124
- <input name="sourceFile" type="string" required="true" description="Source features JSON file name"/>
125
- <input name="language" type="string" required="true" description="Target language for content"/>
113
+ <block type="input" id="I1" desc="API controller analysis input parameters">
114
+ <field name="feature" required="true" type="object" desc="Complete feature object from features.json"/>
115
+ <field name="fileName" required="true" type="string" desc="Controller file name"/>
116
+ <field name="sourcePath" required="true" type="string" desc="Relative path to source file"/>
117
+ <field name="documentPath" required="true" type="string" desc="Target path for generated document"/>
118
+ <field name="module" required="true" type="string" desc="Business module name"/>
119
+ <field name="analyzed" required="true" type="boolean" desc="Analysis status flag"/>
120
+ <field name="platform_type" required="true" type="string" desc="Platform type: admin-api, app-api"/>
121
+ <field name="platform_subtype" required="true" type="string" desc="Platform subtype: spring-boot, java"/>
122
+ <field name="tech_stack" required="true" type="array" desc="Platform tech stack"/>
123
+ <field name="completed_dir" required="true" type="string" desc="Marker files output directory"/>
124
+ <field name="sourceFile" required="true" type="string" desc="Source features JSON file name"/>
125
+ <field name="language" required="true" type="string" desc="Target language for content"/>
126
+ </block>
126
127
 
127
128
  <!-- ==================== CONSTRAINT RULES ==================== -->
128
- <rule level="forbidden" id="no-create-file-for-docs">
129
- NEVER use create_file to rewrite entire document. Documents MUST be created by copying template then filling with search_replace.
130
- </rule>
131
- <rule level="forbidden" id="no-file-deletion">
132
- NEVER delete generated files. If a file is malformed, fix it with search_replace.
133
- </rule>
134
- <rule level="forbidden" id="no-full-rewrite">
135
- NEVER rewrite entire document. Always use targeted search_replace on specific sections.
136
- </rule>
137
- <rule level="mandatory" id="template-first">
138
- Template copying (Step 5a) MUST execute before section filling (Step 5b).
139
- </rule>
140
- <rule level="mandatory" id="write-both-markers">
141
- MUST write both .done.json and .graph.json marker files in Step 7.
142
- </rule>
143
- <rule level="mandatory" id="marker-naming">
144
- Marker file names MUST follow pattern: {module}-{subpath}-{fileName}.done.json
145
- </rule>
146
- <rule level="mandatory" id="no-extension-in-filename">
147
- fileName in .done.json MUST NOT include file extension.
148
- </rule>
149
- <rule level="mandatory" id="relative-paths-only">
150
- ALL paths in JSON content MUST be relative, NEVER absolute paths.
151
- </rule>
152
- <rule level="mandatory" id="language-compliance">
153
- ALL content MUST be generated in the language specified by {{language}} parameter.
154
- </rule>
129
+ <block type="rule" id="R-FORB1" level="forbidden" desc="Document creation constraint">
130
+ <field name="text">NEVER use create_file to rewrite entire document. Documents MUST be created by copying template then filling with search_replace.</field>
131
+ </block>
132
+ <block type="rule" id="R-FORB2" level="forbidden" desc="File deletion constraint">
133
+ <field name="text">NEVER delete generated files. If a file is malformed, fix it with search_replace.</field>
134
+ </block>
135
+ <block type="rule" id="R-FORB3" level="forbidden" desc="Full rewrite constraint">
136
+ <field name="text">NEVER rewrite entire document. Always use targeted search_replace on specific sections.</field>
137
+ </block>
138
+ <block type="rule" id="R-MAND1" level="mandatory" desc="Template-first constraint">
139
+ <field name="text">Template copying (Step 5a) MUST execute before section filling (Step 5b).</field>
140
+ </block>
141
+ <block type="rule" id="R-MAND2" level="mandatory" desc="Marker files constraint">
142
+ <field name="text">MUST write both .done.json and .graph.json marker files in Step 7.</field>
143
+ </block>
144
+ <block type="rule" id="R-MAND3" level="mandatory" desc="Marker naming constraint">
145
+ <field name="text">Marker file names MUST follow pattern: {module}-{subpath}-{fileName}.done.json</field>
146
+ </block>
147
+ <block type="rule" id="R-MAND4" level="mandatory" desc="No extension in filename">
148
+ <field name="text">fileName in .done.json MUST NOT include file extension.</field>
149
+ </block>
150
+ <block type="rule" id="R-MAND5" level="mandatory" desc="Relative paths constraint">
151
+ <field name="text">ALL paths in JSON content MUST be relative, NEVER absolute paths.</field>
152
+ </block>
153
+ <block type="rule" id="R-MAND6" level="mandatory" desc="Language compliance">
154
+ <field name="text">ALL content MUST be generated in the language specified by ${language} parameter.</field>
155
+ </block>
156
+
157
+ <!-- ==================== GLOBAL CONTINUOUS EXECUTION RULES ==================== -->
158
+ <block type="rule" id="GLOBAL-R1" level="forbidden" desc="Continuous execution constraints — NEVER violate">
159
+ <field name="text">DO NOT ask user "Should I continue?" or "How would you like to proceed?" during execution</field>
160
+ <field name="text">DO NOT offer options like "Full execution / Partial / Stop" — always execute ALL tasks to completion</field>
161
+ <field name="text">DO NOT suggest "Due to context window limits, let me pause" — complete current task, use checkpoint for resumption</field>
162
+ <field name="text">DO NOT estimate workload and suggest breaking it into phases — execute ALL items in sequence</field>
163
+ <field name="text">DO NOT warn about "large number of files" or "this may take a while" — proceed with generation</field>
164
+ <field name="text">Context window management: if approaching limit, save progress to checkpoint file and resume — do NOT ask user for guidance</field>
165
+ </block>
155
166
 
156
167
  <!-- ==================== STEP 0: CHECK ANALYSIS STATUS ==================== -->
157
- <gateway name="check-analyzed-status" mode="exclusive">
158
- <branch condition="{{analyzed}} == true">
159
- <event action="log" level="info" message="Step 0 Status: SKIPPED (already analyzed)"/>
160
- <output name="status" value="skipped"/>
161
- <output name="message" value="Controller already analyzed, skipping"/>
162
- <checkpoint name="skip-complete" verify="true"/>
168
+ <block type="gateway" id="G0" mode="exclusive" desc="Check if already analyzed">
169
+ <branch test="${analyzed} == true" name="Already analyzed">
170
+ <block type="event" id="E1" action="log" level="info" desc="Log skip status">
171
+ <field name="message" value="Step 0 Status: SKIPPED (already analyzed)"/>
172
+ </block>
173
+ <block type="output" id="O-skip" desc="Skip output">
174
+ <field name="status" value="skipped"/>
175
+ <field name="message" value="Controller already analyzed, skipping"/>
176
+ </block>
177
+ <block type="checkpoint" id="CP-skip" name="skip-complete" desc="Skip checkpoint">
178
+ <field name="verify" value="true"/>
179
+ </block>
163
180
  </branch>
164
- <branch condition="{{analyzed}} == false">
165
- <event action="log" level="info" message="Step 0 Status: PROCEEDING (analysis required)"/>
181
+ <branch test="${analyzed} == false" name="Analysis required">
182
+ <block type="event" id="E2" action="log" level="info" desc="Log proceed status">
183
+ <field name="message" value="Step 0 Status: PROCEEDING (analysis required)"/>
184
+ </block>
166
185
  </branch>
167
- </gateway>
186
+ </block>
168
187
 
169
188
  <!-- ==================== STEP 1: READ ANALYSIS TEMPLATE ==================== -->
170
- <task name="step1-read-template" action="run-skill">
171
- <description>Read the appropriate template based on tech stack</description>
172
- <parameter name="tech_stack">{{tech_stack}}</parameter>
173
- <script>
174
- <!-- Template Selection Logic -->
175
- <gateway name="template-selection" mode="exclusive">
176
- <branch condition="{{tech_stack}} contains 'fastapi' OR {{tech_stack}} contains 'python'">
177
- <output name="templateFile" value="../speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-FASTAPI.md"/>
178
- </branch>
179
- <branch condition="{{tech_stack}} contains 'dotnet' OR {{tech_stack}} contains '.net'">
180
- <output name="templateFile" value="../speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-NET.md"/>
181
- </branch>
182
- <branch condition="default">
183
- <output name="templateFile" value="../speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE.md"/>
184
- </branch>
185
- </gateway>
186
-
187
- <!-- Read Template Content -->
188
- <task action="read-file" target="{{templateFile}}">
189
- <output name="templateContent" from="file.content"/>
190
- <output name="sectionCount" from="template.sections.count"/>
191
- </task>
192
-
193
- <!-- Validate Template Structure -->
194
- <checkpoint name="template-loaded" verify="{{templateContent}} != null AND {{templateContent}} != ''"/>
195
- <event action="log" level="info" message="Step 1 Status: COMPLETED - Template loaded, {{sectionCount}} sections identified for analysis"/>
196
- </script>
197
- </task>
189
+ <!-- Template Selection Logic -->
190
+ <block type="gateway" id="G1" mode="exclusive" desc="Select template based on tech stack">
191
+ <branch test="${tech_stack} contains 'fastapi' OR ${tech_stack} contains 'python'" name="FastAPI template">
192
+ <block type="output" id="O-tpl1" desc="Set FastAPI template path">
193
+ <field name="templateFile" value="../speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-FASTAPI.md"/>
194
+ </block>
195
+ </branch>
196
+ <branch test="${tech_stack} contains 'dotnet' OR ${tech_stack} contains '.net'" name=".NET template">
197
+ <block type="output" id="O-tpl2" desc="Set .NET template path">
198
+ <field name="templateFile" value="../speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-NET.md"/>
199
+ </block>
200
+ </branch>
201
+ <branch default="true" name="Default template">
202
+ <block type="output" id="O-tpl3" desc="Set default template path">
203
+ <field name="templateFile" value="../speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE.md"/>
204
+ </block>
205
+ </branch>
206
+ </block>
207
+
208
+ <!-- Read Template Content -->
209
+ <block type="task" id="B1" action="read-file" desc="Read selected template">
210
+ <field name="target" value="${templateFile}"/>
211
+ <field name="output" var="templateContent" from="file.content"/>
212
+ <field name="output" var="sectionCount" from="template.sections.count"/>
213
+ </block>
214
+
215
+ <!-- Validate Template Structure -->
216
+ <block type="checkpoint" id="CP1" name="template-loaded" desc="Template loaded successfully">
217
+ <field name="verify" value="${templateContent} != null AND ${templateContent} != ''"/>
218
+ </block>
219
+ <block type="event" id="E3" action="log" level="info" desc="Log template status">
220
+ <field name="message" value="Step 1 Status: COMPLETED - Template loaded, ${sectionCount} sections identified for analysis"/>
221
+ </block>
198
222
 
199
223
  <!-- ==================== STEP 2: READ CONTROLLER AND ANALYZE API STRUCTURE ==================== -->
200
- <task name="step2-read-controller" action="run-skill">
201
- <description>Read controller file and analyze API handler structure</description>
202
- <parameter name="sourcePath">{{sourcePath}}</parameter>
203
- <parameter name="tech_stack">{{tech_stack}}</parameter>
204
- <script>
205
- <!-- Read Source File -->
206
- <task action="read-file" target="{{sourcePath}}">
207
- <output name="sourceContent" from="file.content"/>
208
- <output name="lineCount" from="file.lineCount"/>
209
- </task>
210
-
211
- <!-- Analyze API Structure Based on Tech Stack -->
212
- <gateway name="tech-specific-analysis" mode="exclusive">
213
- <branch condition="{{tech_stack}} contains 'java' OR {{tech_stack}} contains 'spring'">
214
- <task action="parse-spring-controller">
215
- <input name="content">{{sourceContent}}</input>
216
- <output name="endpoints" from="parser.endpoints"/>
217
- <output name="endpointCount" from="parser.endpointCount"/>
218
- <output name="services" from="parser.services"/>
219
- <output name="serviceCount" from="parser.serviceCount"/>
220
- </task>
221
- </branch>
222
- <branch condition="{{tech_stack}} contains 'fastapi' OR {{tech_stack}} contains 'python'">
223
- <task action="parse-fastapi-router">
224
- <input name="content">{{sourceContent}}</input>
225
- <output name="endpoints" from="parser.endpoints"/>
226
- <output name="endpointCount" from="parser.endpointCount"/>
227
- <output name="services" from="parser.services"/>
228
- <output name="serviceCount" from="parser.serviceCount"/>
229
- </task>
230
- </branch>
231
- <branch condition="{{tech_stack}} contains 'dotnet' OR {{tech_stack}} contains '.net'">
232
- <task action="parse-dotnet-controller">
233
- <input name="content">{{sourceContent}}</input>
234
- <output name="endpoints" from="parser.endpoints"/>
235
- <output name="endpointCount" from="parser.endpointCount"/>
236
- <output name="services" from="parser.services"/>
237
- <output name="serviceCount" from="parser.serviceCount"/>
238
- </task>
239
- </branch>
240
- <branch condition="default">
241
- <task action="parse-generic-controller">
242
- <input name="content">{{sourceContent}}</input>
243
- <output name="endpoints" from="parser.endpoints"/>
244
- <output name="endpointCount" from="parser.endpointCount"/>
245
- <output name="services" from="parser.services"/>
246
- <output name="serviceCount" from="parser.serviceCount"/>
247
- </task>
248
- </branch>
249
- </gateway>
250
-
251
- <checkpoint name="controller-analyzed" verify="{{sourceContent}} != null"/>
252
- <event action="log" level="info" message="Step 2 Status: COMPLETED - Read {{sourcePath}} ({{lineCount}} lines), Analyzed {{endpointCount}} endpoints, {{serviceCount}} services"/>
253
- </script>
254
- </task>
224
+ <!-- Read Source File -->
225
+ <block type="task" id="B2" action="read-file" desc="Read controller source file">
226
+ <field name="target" value="${sourcePath}"/>
227
+ <field name="output" var="sourceContent" from="file.content"/>
228
+ <field name="output" var="lineCount" from="file.lineCount"/>
229
+ </block>
230
+
231
+ <!-- Analyze API Structure Based on Tech Stack -->
232
+ <block type="gateway" id="G2" mode="exclusive" desc="Tech-specific API analysis">
233
+ <branch test="${tech_stack} contains 'java' OR ${tech_stack} contains 'spring'" name="Spring/Java analysis">
234
+ <block type="task" id="B3" action="parse-spring-controller" desc="Parse Spring controller">
235
+ <field name="content" value="${sourceContent}"/>
236
+ <field name="output" var="endpoints" from="parser.endpoints"/>
237
+ <field name="output" var="endpointCount" from="parser.endpointCount"/>
238
+ <field name="output" var="services" from="parser.services"/>
239
+ <field name="output" var="serviceCount" from="parser.serviceCount"/>
240
+ </block>
241
+ </branch>
242
+ <branch test="${tech_stack} contains 'fastapi' OR ${tech_stack} contains 'python'" name="FastAPI/Python analysis">
243
+ <block type="task" id="B4" action="parse-fastapi-router" desc="Parse FastAPI router">
244
+ <field name="content" value="${sourceContent}"/>
245
+ <field name="output" var="endpoints" from="parser.endpoints"/>
246
+ <field name="output" var="endpointCount" from="parser.endpointCount"/>
247
+ <field name="output" var="services" from="parser.services"/>
248
+ <field name="output" var="serviceCount" from="parser.serviceCount"/>
249
+ </block>
250
+ </branch>
251
+ <branch test="${tech_stack} contains 'dotnet' OR ${tech_stack} contains '.net'" name=".NET analysis">
252
+ <block type="task" id="B5" action="parse-dotnet-controller" desc="Parse .NET controller">
253
+ <field name="content" value="${sourceContent}"/>
254
+ <field name="output" var="endpoints" from="parser.endpoints"/>
255
+ <field name="output" var="endpointCount" from="parser.endpointCount"/>
256
+ <field name="output" var="services" from="parser.services"/>
257
+ <field name="output" var="serviceCount" from="parser.serviceCount"/>
258
+ </block>
259
+ </branch>
260
+ <branch default="true" name="Generic analysis">
261
+ <block type="task" id="B6" action="parse-generic-controller" desc="Parse generic controller">
262
+ <field name="content" value="${sourceContent}"/>
263
+ <field name="output" var="endpoints" from="parser.endpoints"/>
264
+ <field name="output" var="endpointCount" from="parser.endpointCount"/>
265
+ <field name="output" var="services" from="parser.services"/>
266
+ <field name="output" var="serviceCount" from="parser.serviceCount"/>
267
+ </block>
268
+ </branch>
269
+ </block>
270
+
271
+ <block type="checkpoint" id="CP2" name="controller-analyzed" desc="Controller analyzed successfully">
272
+ <field name="verify" value="${sourceContent} != null"/>
273
+ </block>
274
+ <block type="event" id="E4" action="log" level="info" desc="Log controller status">
275
+ <field name="message" value="Step 2 Status: COMPLETED - Read ${sourcePath} (${lineCount} lines), Analyzed ${endpointCount} endpoints, ${serviceCount} services"/>
276
+ </block>
255
277
 
256
278
  <!-- ==================== STEP 3: EXTRACT API FEATURES ==================== -->
257
- <task name="step3-extract-features" action="run-skill">
258
- <description>Extract API features, business flows, and data structures from controller analysis</description>
259
- <parameter name="endpoints">{{endpoints}}</parameter>
260
- <parameter name="sourcePath">{{sourcePath}}</parameter>
261
- <parameter name="language">{{language}}</parameter>
262
- <script>
263
- <!-- Read Mermaid Rules -->
264
- <task action="read-file" target="speccrew-workspace/docs/rules/mermaid-rule.md">
265
- <output name="mermaidRules" from="file.content"/>
266
- </task>
267
-
268
- <!-- Extract Each API Endpoint Details -->
269
- <loop name="extract-endpoint-details" over="{{endpoints}}" as="endpoint">
270
- <task action="analyze-endpoint">
271
- <input name="endpoint">{{endpoint}}</input>
272
- <input name="tech_stack">{{tech_stack}}</input>
273
- <output name="requestDTO" from="analysis.requestDTO"/>
274
- <output name="responseDTO" from="analysis.responseDTO"/>
275
- <output name="businessFlow" from="analysis.flow"/>
276
- <output name="validationRules" from="analysis.validations"/>
277
- </task>
278
- </loop>
279
-
280
- <!-- Trace Backend Call Chain -->
281
- <task action="trace-call-chain">
282
- <input name="endpoints">{{endpoints}}</input>
283
- <input name="services">{{services}}</input>
284
- <input name="tech_stack">{{tech_stack}}</input>
285
- <output name="callChains" from="trace.chains"/>
286
- <output name="databaseTables" from="trace.tables"/>
287
- <output name="transactionBoundaries" from="trace.transactions"/>
288
- <output name="crossModuleCalls" from="trace.crossModules"/>
289
- </task>
290
-
291
- <!-- Generate Mermaid Flowcharts -->
292
- <task action="generate-flowcharts">
293
- <input name="endpoints">{{endpoints}}</input>
294
- <input name="callChains">{{callChains}}</input>
295
- <input name="mermaidRules">{{mermaidRules}}</input>
296
- <output name="flowcharts" from="generation.flowcharts"/>
297
- <output name="flowCount" from="generation.count"/>
298
- </task>
299
-
300
- <checkpoint name="features-extracted" verify="{{endpointCount}} &gt; 0"/>
301
- <event action="log" level="info" message="Step 3 Status: COMPLETED - Extracted {{endpointCount}} API endpoints, {{flowCount}} business flows"/>
302
- </script>
303
- </task>
279
+ <!-- Read Mermaid Rules -->
280
+ <block type="task" id="B7" action="read-file" desc="Read Mermaid rules">
281
+ <field name="target" value="speccrew-workspace/docs/rules/mermaid-rule.md"/>
282
+ <field name="output" var="mermaidRules" from="file.content"/>
283
+ </block>
284
+
285
+ <!-- Extract Each API Endpoint Details -->
286
+ <block type="loop" id="L1" over="${endpoints}" as="endpoint" desc="Extract endpoint details">
287
+ <block type="task" id="B8" action="analyze-endpoint" desc="Analyze single endpoint">
288
+ <field name="endpoint" value="${endpoint}"/>
289
+ <field name="tech_stack" value="${tech_stack}"/>
290
+ <field name="output" var="requestDTO" from="analysis.requestDTO"/>
291
+ <field name="output" var="responseDTO" from="analysis.responseDTO"/>
292
+ <field name="output" var="businessFlow" from="analysis.flow"/>
293
+ <field name="output" var="validationRules" from="analysis.validations"/>
294
+ </block>
295
+ </block>
296
+
297
+ <!-- Trace Backend Call Chain -->
298
+ <block type="task" id="B9" action="trace-call-chain" desc="Trace call chains">
299
+ <field name="endpoints" value="${endpoints}"/>
300
+ <field name="services" value="${services}"/>
301
+ <field name="tech_stack" value="${tech_stack}"/>
302
+ <field name="output" var="callChains" from="trace.chains"/>
303
+ <field name="output" var="databaseTables" from="trace.tables"/>
304
+ <field name="output" var="transactionBoundaries" from="trace.transactions"/>
305
+ <field name="output" var="crossModuleCalls" from="trace.crossModules"/>
306
+ </block>
307
+
308
+ <!-- Generate Mermaid Flowcharts -->
309
+ <block type="task" id="B10" action="generate-flowcharts" desc="Generate Mermaid diagrams">
310
+ <field name="endpoints" value="${endpoints}"/>
311
+ <field name="callChains" value="${callChains}"/>
312
+ <field name="mermaidRules" value="${mermaidRules}"/>
313
+ <field name="output" var="flowcharts" from="generation.flowcharts"/>
314
+ <field name="output" var="flowCount" from="generation.count"/>
315
+ </block>
316
+
317
+ <block type="checkpoint" id="CP3" name="features-extracted" desc="Features extracted successfully">
318
+ <field name="verify" value="${endpointCount} > 0"/>
319
+ </block>
320
+ <block type="event" id="E5" action="log" level="info" desc="Log extraction status">
321
+ <field name="message" value="Step 3 Status: COMPLETED - Extracted ${endpointCount} API endpoints, ${flowCount} business flows"/>
322
+ </block>
304
323
 
305
324
  <!-- ==================== STEP 4: FIND API CONSUMERS ==================== -->
306
- <task name="step4-find-consumers" action="run-skill">
307
- <description>Search frontend page files to find which pages call the APIs in this controller</description>
308
- <parameter name="endpoints">{{endpoints}}</parameter>
309
- <parameter name="fileName">{{fileName}}</parameter>
310
- <script>
311
- <!-- Search for API Client Calls -->
312
- <task action="grep-search">
313
- <input name="pattern">{{fileName}}</input>
314
- <input name="glob">*.{vue,tsx,jsx,ts,js}</input>
315
- <output name="clientMatches" from="search.results"/>
316
- </task>
317
-
318
- <!-- Search for HTTP Requests to Controller Path -->
319
- <loop name="search-endpoint-paths" over="{{endpoints}}" as="endpoint">
320
- <task action="grep-search">
321
- <input name="pattern">{{endpoint.path}}</input>
322
- <input name="glob">*.{vue,tsx,jsx,ts,js}</input>
323
- <output name="pathMatches" from="search.results" accumulate="true"/>
324
- </task>
325
- </loop>
326
-
327
- <!-- Compile Consumer Pages -->
328
- <task action="compile-consumers">
329
- <input name="clientMatches">{{clientMatches}}</input>
330
- <input name="pathMatches">{{pathMatches}}</input>
331
- <output name="consumerPages" from="compilation.pages"/>
332
- <output name="consumerCount" from="compilation.count"/>
333
- </task>
334
-
335
- <event action="log" level="info" message="Step 4 Status: COMPLETED - Found {{consumerCount}} API consumers"/>
336
- </script>
337
- </task>
325
+ <!-- Search for API Client Calls -->
326
+ <block type="task" id="B11" action="grep-search" desc="Search for API client calls">
327
+ <field name="pattern" value="${fileName}"/>
328
+ <field name="glob" value="*.{vue,tsx,jsx,ts,js}"/>
329
+ <field name="output" var="clientMatches" from="search.results"/>
330
+ </block>
331
+
332
+ <!-- Search for HTTP Requests to Controller Path -->
333
+ <block type="loop" id="L2" over="${endpoints}" as="endpoint" desc="Search endpoint paths">
334
+ <block type="task" id="B12" action="grep-search" desc="Search for endpoint path">
335
+ <field name="pattern" value="${endpoint.path}"/>
336
+ <field name="glob" value="*.{vue,tsx,jsx,ts,js}"/>
337
+ <field name="output" var="pathMatches" from="search.results" accumulate="true"/>
338
+ </block>
339
+ </block>
340
+
341
+ <!-- Compile Consumer Pages -->
342
+ <block type="task" id="B13" action="compile-consumers" desc="Compile consumer pages">
343
+ <field name="clientMatches" value="${clientMatches}"/>
344
+ <field name="pathMatches" value="${pathMatches}"/>
345
+ <field name="output" var="consumerPages" from="compilation.pages"/>
346
+ <field name="output" var="consumerCount" from="compilation.count"/>
347
+ </block>
348
+
349
+ <block type="event" id="E6" action="log" level="info" desc="Log consumer status">
350
+ <field name="message" value="Step 4 Status: COMPLETED - Found ${consumerCount} API consumers"/>
351
+ </block>
338
352
 
339
353
  <!-- ==================== STEP 5A: COPY TEMPLATE TO DOCUMENT PATH ==================== -->
340
- <task name="step5a-copy-template" action="run-skill">
341
- <description>Copy the appropriate template to the target document path and replace top-level placeholders</description>
342
- <parameter name="templateContent">{{templateContent}}</parameter>
343
- <parameter name="documentPath">{{documentPath}}</parameter>
344
- <parameter name="fileName">{{fileName}}</parameter>
345
- <parameter name="sourcePath">{{sourcePath}}</parameter>
346
- <parameter name="module">{{module}}</parameter>
347
- <script>
348
- <!-- Replace Top-Level Placeholders -->
349
- <task action="replace-placeholders">
350
- <input name="template">{{templateContent}}</input>
351
- <replacements>
352
- <replacement from="{Controller}" to="{{fileName}}"/>
353
- <replacement from="{sourcePath}" to="{{sourcePath}}"/>
354
- <replacement from="{documentPath}" to="{{documentPath}}"/>
355
- <replacement from="{module}" to="{{module}}"/>
356
- <replacement from="[Feature Name]" to="{{fileName}}"/>
357
- </replacements>
358
- <output name="documentSkeleton" from="result.content"/>
359
- </task>
360
-
361
- <!-- Create Document File -->
362
- <task action="create-file" target="{{documentPath}}">
363
- <content>{{documentSkeleton}}</content>
364
- </task>
365
-
366
- <!-- Verify Document Skeleton -->
367
- <task action="verify-structure">
368
- <input name="documentPath">{{documentPath}}</input>
369
- <output name="structureValid" from="verification.valid"/>
370
- </task>
371
-
372
- <checkpoint name="template-copied" verify="file.exists({{documentPath}}) AND {{structureValid}}"/>
373
- <event action="log" level="info" message="Step 5a Status: COMPLETED - Template copied to {{documentPath}}, ready for section filling"/>
374
- </script>
375
- </task>
354
+ <!-- Replace Top-Level Placeholders -->
355
+ <block type="task" id="B14" action="replace-placeholders" desc="Replace template placeholders">
356
+ <field name="template" value="${templateContent}"/>
357
+ <field name="replacements">
358
+ <replacement from="{Controller}" to="${fileName}"/>
359
+ <replacement from="{sourcePath}" to="${sourcePath}"/>
360
+ <replacement from="{documentPath}" to="${documentPath}"/>
361
+ <replacement from="{module}" to="${module}"/>
362
+ <replacement from="[Feature Name]" to="${fileName}"/>
363
+ </field>
364
+ <field name="output" var="documentSkeleton" from="result.content"/>
365
+ </block>
366
+
367
+ <!-- Create Document File -->
368
+ <block type="task" id="B15" action="create-file" desc="Create document file">
369
+ <field name="target" value="${documentPath}"/>
370
+ <field name="content" value="${documentSkeleton}"/>
371
+ </block>
372
+
373
+ <!-- Verify Document Skeleton -->
374
+ <block type="task" id="B16" action="verify-structure" desc="Verify document structure">
375
+ <field name="documentPath" value="${documentPath}"/>
376
+ <field name="output" var="structureValid" from="verification.valid"/>
377
+ </block>
378
+
379
+ <block type="checkpoint" id="CP4" name="template-copied" desc="Template copied successfully">
380
+ <field name="verify" value="file.exists(${documentPath}) AND ${structureValid}"/>
381
+ </block>
382
+ <block type="event" id="E7" action="log" level="info" desc="Log template copy status">
383
+ <field name="message" value="Step 5a Status: COMPLETED - Template copied to ${documentPath}, ready for section filling"/>
384
+ </block>
376
385
 
377
386
  <!-- ==================== STEP 5B: FILL EACH SECTION USING SEARCH_REPLACE ==================== -->
378
- <task name="step5b-fill-sections" action="run-skill">
379
- <description>Fill each section of the document with actual data extracted from source code analysis</description>
380
- <parameter name="documentPath">{{documentPath}}</parameter>
381
- <parameter name="endpoints">{{endpoints}}</parameter>
382
- <parameter name="consumerPages">{{consumerPages}}</parameter>
383
- <parameter name="callChains">{{callChains}}</parameter>
384
- <parameter name="flowcharts">{{flowcharts}}</parameter>
385
- <parameter name="databaseTables">{{databaseTables}}</parameter>
386
- <parameter name="language">{{language}}</parameter>
387
- <script>
388
- <!-- Calculate Dynamic Path Prefix -->
389
- <task action="calculate-path-prefix">
390
- <input name="documentPath">{{documentPath}}</input>
391
- <output name="pathPrefix" from="calculation.prefix"/>
392
- </task>
393
-
394
- <!-- Section 1: Content Overview -->
395
- <task action="search_replace" target="{{documentPath}}">
396
- <anchor><!-- AI-TAG: OVERVIEW --></anchor>
397
- <replace>{{overviewContent}}</replace>
398
- </task>
399
-
400
- <!-- Section 2: API Endpoints -->
401
- <task action="search_replace" target="{{documentPath}}">
402
- <anchor><!-- AI-TAG: API_ENDPOINTS --></anchor>
403
- <replace>{{endpointDefinitions}}</replace>
404
- </task>
405
-
406
- <!-- Section 3: Data Fields -->
407
- <task action="search_replace" target="{{documentPath}}">
408
- <anchor><!-- AI-TAG: DATA_DEFINITION --></anchor>
409
- <replace>{{dataFieldDefinitions}}</replace>
410
- </task>
411
-
412
- <!-- Section 4: References -->
413
- <task action="search_replace" target="{{documentPath}}">
414
- <anchor><!-- AI-TAG: REFERENCES --></anchor>
415
- <replace>{{referencesContent}}</replace>
416
- </task>
417
-
418
- <!-- Section 5: Business Rules -->
419
- <task action="search_replace" target="{{documentPath}}">
420
- <anchor><!-- AI-TAG: BUSINESS_RULES --></anchor>
421
- <replace>{{businessRulesContent}}</replace>
422
- </task>
423
-
424
- <!-- Section 6: Dependencies -->
425
- <task action="search_replace" target="{{documentPath}}">
426
- <anchor><!-- AI-TAG: DEPENDENCIES --></anchor>
427
- <replace>{{dependenciesContent}}</replace>
428
- </task>
429
-
430
- <!-- Section 7: Performance -->
431
- <task action="search_replace" target="{{documentPath}}">
432
- <anchor><!-- AI-TAG: PERFORMANCE --></anchor>
433
- <replace>{{performanceContent}}</replace>
434
- </task>
435
-
436
- <!-- Section 8: Troubleshooting -->
437
- <task action="search_replace" target="{{documentPath}}">
438
- <anchor><!-- AI-TAG: TROUBLESHOOTING --></anchor>
439
- <replace>{{troubleshootingContent}}</replace>
440
- </task>
441
-
442
- <!-- Section 9: Notes -->
443
- <task action="search_replace" target="{{documentPath}}">
444
- <anchor><!-- AI-TAG: ADDITIONAL_NOTES --></anchor>
445
- <replace>{{additionalNotes}}</replace>
446
- </task>
447
-
448
- <!-- Section 10: Appendix -->
449
- <task action="search_replace" target="{{documentPath}}">
450
- <search>## 10. Appendix.*</search>
451
- <replace>## 10. Appendix
452
-
453
- {{appendixContent}}</replace>
454
- </task>
455
-
456
- <!-- Get File Size -->
457
- <task action="get-file-size" target="{{documentPath}}">
458
- <output name="fileSize" from="file.size"/>
459
- </task>
460
-
461
- <checkpoint name="all-sections-filled" verify="all.sections.filled"/>
462
- <event action="log" level="info" message="Step 5b Status: COMPLETED - All sections filled at {{documentPath}} ({{fileSize}} bytes)"/>
463
- </script>
464
- </task>
387
+ <!-- Calculate Dynamic Path Prefix -->
388
+ <block type="task" id="B17" action="calculate-path-prefix" desc="Calculate path prefix">
389
+ <field name="documentPath" value="${documentPath}"/>
390
+ <field name="output" var="pathPrefix" from="calculation.prefix"/>
391
+ </block>
392
+
393
+ <!-- Section 1: Content Overview -->
394
+ <block type="task" id="B18" action="search_replace" desc="Fill overview section">
395
+ <field name="target" value="${documentPath}"/>
396
+ <field name="anchor" value="<!-- AI-TAG: OVERVIEW -->"/>
397
+ <field name="replace" value="${overviewContent}"/>
398
+ </block>
399
+
400
+ <!-- Section 2: API Endpoints -->
401
+ <block type="task" id="B19" action="search_replace" desc="Fill API endpoints section">
402
+ <field name="target" value="${documentPath}"/>
403
+ <field name="anchor" value="<!-- AI-TAG: API_ENDPOINTS -->"/>
404
+ <field name="replace" value="${endpointDefinitions}"/>
405
+ </block>
406
+
407
+ <!-- Section 3: Data Fields -->
408
+ <block type="task" id="B20" action="search_replace" desc="Fill data definition section">
409
+ <field name="target" value="${documentPath}"/>
410
+ <field name="anchor" value="<!-- AI-TAG: DATA_DEFINITION -->"/>
411
+ <field name="replace" value="${dataFieldDefinitions}"/>
412
+ </block>
413
+
414
+ <!-- Section 4: References -->
415
+ <block type="task" id="B21" action="search_replace" desc="Fill references section">
416
+ <field name="target" value="${documentPath}"/>
417
+ <field name="anchor" value="<!-- AI-TAG: REFERENCES -->"/>
418
+ <field name="replace" value="${referencesContent}"/>
419
+ </block>
420
+
421
+ <!-- Section 5: Business Rules -->
422
+ <block type="task" id="B22" action="search_replace" desc="Fill business rules section">
423
+ <field name="target" value="${documentPath}"/>
424
+ <field name="anchor" value="<!-- AI-TAG: BUSINESS_RULES -->"/>
425
+ <field name="replace" value="${businessRulesContent}"/>
426
+ </block>
427
+
428
+ <!-- Section 6: Dependencies -->
429
+ <block type="task" id="B23" action="search_replace" desc="Fill dependencies section">
430
+ <field name="target" value="${documentPath}"/>
431
+ <field name="anchor" value="<!-- AI-TAG: DEPENDENCIES -->"/>
432
+ <field name="replace" value="${dependenciesContent}"/>
433
+ </block>
434
+
435
+ <!-- Section 7: Performance -->
436
+ <block type="task" id="B24" action="search_replace" desc="Fill performance section">
437
+ <field name="target" value="${documentPath}"/>
438
+ <field name="anchor" value="<!-- AI-TAG: PERFORMANCE -->"/>
439
+ <field name="replace" value="${performanceContent}"/>
440
+ </block>
441
+
442
+ <!-- Section 8: Troubleshooting -->
443
+ <block type="task" id="B25" action="search_replace" desc="Fill troubleshooting section">
444
+ <field name="target" value="${documentPath}"/>
445
+ <field name="anchor" value="<!-- AI-TAG: TROUBLESHOOTING -->"/>
446
+ <field name="replace" value="${troubleshootingContent}"/>
447
+ </block>
448
+
449
+ <!-- Section 9: Notes -->
450
+ <block type="task" id="B26" action="search_replace" desc="Fill additional notes section">
451
+ <field name="target" value="${documentPath}"/>
452
+ <field name="anchor" value="<!-- AI-TAG: ADDITIONAL_NOTES -->"/>
453
+ <field name="replace" value="${additionalNotes}"/>
454
+ </block>
455
+
456
+ <!-- Section 10: Appendix -->
457
+ <block type="task" id="B27" action="search_replace" desc="Fill appendix section">
458
+ <field name="target" value="${documentPath}"/>
459
+ <field name="search" value="## 10. Appendix.*"/>
460
+ <field name="replace" value="## 10. Appendix&#10;&#10;${appendixContent}"/>
461
+ </block>
462
+
463
+ <!-- Get File Size -->
464
+ <block type="task" id="B28" action="get-file-size" desc="Get generated file size">
465
+ <field name="target" value="${documentPath}"/>
466
+ <field name="output" var="fileSize" from="file.size"/>
467
+ </block>
468
+
469
+ <block type="checkpoint" id="CP5" name="all-sections-filled" desc="All sections filled">
470
+ <field name="verify" value="all.sections.filled"/>
471
+ </block>
472
+ <block type="event" id="E8" action="log" level="info" desc="Log sections filled status">
473
+ <field name="message" value="Step 5b Status: COMPLETED - All sections filled at ${documentPath} (${fileSize} bytes)"/>
474
+ </block>
465
475
 
466
476
  <!-- ==================== STEP 6: REPORT RESULTS ==================== -->
467
- <task name="step6-report" action="run-skill">
468
- <description>Return analysis result summary to dispatch</description>
469
- <script>
470
- <gateway name="determine-status" mode="exclusive">
471
- <branch condition="{{endpointCount}} == 0">
472
- <output name="status" value="failed"/>
473
- <output name="message" value="No API endpoints found in controller"/>
474
- </branch>
475
- <branch condition="{{errors}} != null AND {{errors.length}} &gt; 0">
476
- <output name="status" value="partial"/>
477
- <output name="message" value="Analysis completed with {{errors.length}} warnings"/>
478
- </branch>
479
- <branch condition="default">
480
- <output name="status" value="success"/>
481
- <output name="message" value="Successfully analyzed {{fileName}} with {{endpointCount}} API endpoints"/>
482
- </branch>
483
- </gateway>
484
-
485
- <output name="feature_name" value="{{fileName}}"/>
486
- <output name="generated_file" value="{{documentPath}}"/>
487
-
488
- <event action="log" level="info" message="Step 6 Status: COMPLETED - Analysis {{status}}: {{message}}"/>
489
- </script>
490
- </task>
477
+ <block type="gateway" id="G3" mode="exclusive" desc="Determine analysis status">
478
+ <branch test="${endpointCount} == 0" name="No endpoints">
479
+ <block type="output" id="O-fail" desc="Failed output">
480
+ <field name="status" value="failed"/>
481
+ <field name="message" value="No API endpoints found in controller"/>
482
+ </block>
483
+ </branch>
484
+ <branch test="${errors} != null AND ${errors.length} > 0" name="Partial success">
485
+ <block type="output" id="O-partial" desc="Partial output">
486
+ <field name="status" value="partial"/>
487
+ <field name="message" value="Analysis completed with ${errors.length} warnings"/>
488
+ </block>
489
+ </branch>
490
+ <branch default="true" name="Success">
491
+ <block type="output" id="O-success" desc="Success output">
492
+ <field name="status" value="success"/>
493
+ <field name="message" value="Successfully analyzed ${fileName} with ${endpointCount} API endpoints"/>
494
+ </block>
495
+ </branch>
496
+ </block>
497
+
498
+ <block type="output" id="O-vals" desc="Feature outputs">
499
+ <field name="feature_name" value="${fileName}"/>
500
+ <field name="generated_file" value="${documentPath}"/>
501
+ </block>
502
+
503
+ <block type="event" id="E9" action="log" level="info" desc="Log report status">
504
+ <field name="message" value="Step 6 Status: COMPLETED - Analysis ${status}: ${message}"/>
505
+ </block>
491
506
 
492
507
  <!-- ==================== STEP 7: WRITE COMPLETION MARKERS ==================== -->
493
- <task name="step7-write-markers" action="run-skill">
494
- <description>Write analysis results to marker files for dispatch batch processing</description>
495
- <parameter name="completed_dir">{{completed_dir}}</parameter>
496
- <parameter name="module">{{module}}</parameter>
497
- <parameter name="sourcePath">{{sourcePath}}</parameter>
498
- <parameter name="fileName">{{fileName}}</parameter>
499
- <parameter name="sourceFile">{{sourceFile}}</parameter>
500
- <parameter name="documentPath">{{documentPath}}</parameter>
501
- <parameter name="status">{{status}}</parameter>
502
- <parameter name="message">{{message}}</parameter>
503
- <script>
504
- <!-- Calculate Subpath from Source Path -->
505
- <task action="calculate-subpath">
506
- <input name="sourcePath">{{sourcePath}}</input>
507
- <output name="subpath" from="calculation.subpath"/>
508
- </task>
509
-
510
- <!-- Generate Marker File Name -->
511
- <task action="generate-marker-name">
512
- <input name="module">{{module}}</input>
513
- <input name="subpath">{{subpath}}</input>
514
- <input name="fileName">{{fileName}}</input>
515
- <output name="markerName" from="generation.name"/>
516
- </task>
517
-
518
- <!-- Pre-write Verification -->
519
- <checkpoint name="pre-write-check" verify="{{fileName}} does-not-contain '.' AND {{sourceFile}} matches 'features-*.json'"/>
520
-
521
- <!-- Write .done.json File -->
522
- <task action="create-file" target="{{completed_dir}}/{{markerName}}.done.json">
523
- <content>{
524
- "fileName": "{{fileName}}",
525
- "sourcePath": "{{sourcePath}}",
526
- "sourceFile": "{{sourceFile}}",
527
- "module": "{{module}}",
528
- "documentPath": "{{documentPath}}",
529
- "status": "{{status}}",
530
- "analysisNotes": "{{message}}"
531
- }</content>
532
- </task>
533
-
534
- <!-- Verify Marker File Written -->
535
- <checkpoint name="marker-written" verify="file.exists({{completed_dir}}/{{markerName}}.done.json)"/>
536
-
537
- <!-- Dispatch to Graph Skill for .graph.json -->
538
- <task name="dispatch-graph-generation" action="dispatch-to-worker">
539
- <skill>speccrew-knowledge-bizs-api-graph-xml</skill>
540
- <parameters>
541
- <parameter name="controllerFile">{{fileName}}</parameter>
542
- <parameter name="sourcePath">{{sourcePath}}</parameter>
543
- <parameter name="endpoints">{{endpoints}}</parameter>
544
- <parameter name="completed_dir">{{completed_dir}}</parameter>
545
- <parameter name="markerName">{{markerName}}</parameter>
546
- </parameters>
547
- </task>
548
-
549
- <event action="log" level="info" message="Step 7 Status: COMPLETED - Marker file written to {{completed_dir}}"/>
550
- </script>
551
- </task>
508
+ <!-- Calculate Subpath from Source Path -->
509
+ <block type="task" id="B29" action="calculate-subpath" desc="Calculate subpath">
510
+ <field name="sourcePath" value="${sourcePath}"/>
511
+ <field name="output" var="subpath" from="calculation.subpath"/>
512
+ </block>
513
+
514
+ <!-- Generate Marker File Name -->
515
+ <block type="task" id="B30" action="generate-marker-name" desc="Generate marker name">
516
+ <field name="module" value="${module}"/>
517
+ <field name="subpath" value="${subpath}"/>
518
+ <field name="fileName" value="${fileName}"/>
519
+ <field name="output" var="markerName" from="generation.name"/>
520
+ </block>
521
+
522
+ <!-- Pre-write Verification -->
523
+ <block type="checkpoint" id="CP6" name="pre-write-check" desc="Pre-write verification">
524
+ <field name="verify" value="${fileName} does-not-contain '.' AND ${sourceFile} matches 'features-*.json'"/>
525
+ </block>
526
+
527
+ <!-- Write .done.json File -->
528
+ <block type="task" id="B31" action="create-file" desc="Write done marker file">
529
+ <field name="target" value="${completed_dir}/${markerName}.done.json"/>
530
+ <field name="content" value="{
531
+ &quot;fileName&quot;: &quot;${fileName}&quot;,
532
+ &quot;sourcePath&quot;: &quot;${sourcePath}&quot;,
533
+ &quot;sourceFile&quot;: &quot;${sourceFile}&quot;,
534
+ &quot;module&quot;: &quot;${module}&quot;,
535
+ &quot;documentPath&quot;: &quot;${documentPath}&quot;,
536
+ &quot;status&quot;: &quot;${status}&quot;,
537
+ &quot;analysisNotes&quot;: &quot;${message}&quot;
538
+ }"/>
539
+ </block>
540
+
541
+ <!-- Verify Marker File Written -->
542
+ <block type="checkpoint" id="CP7" name="marker-written" desc="Marker file written">
543
+ <field name="verify" value="file.exists(${completed_dir}/${markerName}.done.json)"/>
544
+ </block>
545
+
546
+ <!-- Dispatch to Graph Skill for .graph.json -->
547
+ <block type="task" id="B32" action="dispatch-to-worker" desc="Dispatch graph generation">
548
+ <field name="skill">speccrew-knowledge-bizs-api-graph-xml</field>
549
+ <field name="parameters">
550
+ <field name="controllerFile">${fileName}</field>
551
+ <field name="sourcePath">${sourcePath}</field>
552
+ <field name="endpoints">${endpoints}</field>
553
+ <field name="completed_dir">${completed_dir}</field>
554
+ <field name="markerName">${markerName}</field>
555
+ </field>
556
+ </block>
557
+
558
+ <block type="event" id="E10" action="log" level="info" desc="Log marker status">
559
+ <field name="message" value="Step 7 Status: COMPLETED - Marker file written to ${completed_dir}"/>
560
+ </block>
552
561
 
553
562
  <!-- ==================== FINAL OUTPUT ==================== -->
554
- <output name="status" from="step6-report.status"/>
555
- <output name="feature" from="step6-report.feature"/>
556
- <output name="platformType" from="input.platform_type"/>
557
- <output name="module" from="input.module"/>
558
- <output name="featureName" from="step6-report.feature_name"/>
559
- <output name="generatedFile" from="step6-report.generated_file"/>
560
- <output name="message" from="step6-report.message"/>
563
+ <block type="output" id="O1" desc="Final workflow outputs">
564
+ <field name="status" from="step6-report.status"/>
565
+ <field name="feature" from="step6-report.feature"/>
566
+ <field name="platformType" from="input.platform_type"/>
567
+ <field name="module" from="input.module"/>
568
+ <field name="featureName" from="step6-report.feature_name"/>
569
+ <field name="generatedFile" from="step6-report.generated_file"/>
570
+ <field name="message" from="step6-report.message"/>
571
+ </block>
561
572
 
562
573
  <!-- ==================== ERROR HANDLING ==================== -->
563
- <error-handler>
564
- <catch type="file-not-found">
565
- <event action="log" level="error" message="Source file not found: {{sourcePath}}"/>
566
- <output name="status" value="failed"/>
567
- <output name="message" value="Source file not found: {{sourcePath}}"/>
574
+ <block type="error-handler" id="EH1" desc="Global error handling">
575
+ <catch error-type="file-not-found">
576
+ <block type="event" id="E-err1" action="log" level="error" desc="Log file not found">
577
+ <field name="message" value="Source file not found: ${sourcePath}"/>
578
+ </block>
579
+ <block type="output" id="O-err1" desc="Error output">
580
+ <field name="status" value="failed"/>
581
+ <field name="message" value="Source file not found: ${sourcePath}"/>
582
+ </block>
568
583
  </catch>
569
- <catch type="template-error">
570
- <event action="log" level="error" message="Template processing error"/>
571
- <output name="status" value="failed"/>
572
- <output name="message" value="Failed to process template"/>
584
+ <catch error-type="template-error">
585
+ <block type="event" id="E-err2" action="log" level="error" desc="Log template error">
586
+ <field name="message" value="Template processing error"/>
587
+ </block>
588
+ <block type="output" id="O-err2" desc="Error output">
589
+ <field name="status" value="failed"/>
590
+ <field name="message" value="Failed to process template"/>
591
+ </block>
573
592
  </catch>
574
- <catch type="marker-write-error">
575
- <event action="log" level="error" message="Failed to write marker file: {{error.message}}"/>
576
- <output name="status" value="failed"/>
577
- <output name="message" value="Failed to write completion marker"/>
593
+ <catch error-type="marker-write-error">
594
+ <block type="event" id="E-err3" action="log" level="error" desc="Log marker write error">
595
+ <field name="message" value="Failed to write marker file: ${error.message}"/>
596
+ </block>
597
+ <block type="output" id="O-err3" desc="Error output">
598
+ <field name="status" value="failed"/>
599
+ <field name="message" value="Failed to write completion marker"/>
600
+ </block>
578
601
  </catch>
579
- <catch type="validation-error">
580
- <event action="log" level="error" message="Validation failed: {{error.message}}"/>
581
- <output name="status" value="partial"/>
582
- <output name="message" value="Analysis completed with validation errors"/>
602
+ <catch error-type="validation-error">
603
+ <block type="event" id="E-err4" action="log" level="error" desc="Log validation error">
604
+ <field name="message" value="Validation failed: ${error.message}"/>
605
+ </block>
606
+ <block type="output" id="O-err4" desc="Partial output">
607
+ <field name="status" value="partial"/>
608
+ <field name="message" value="Analysis completed with validation errors"/>
609
+ </block>
583
610
  </catch>
584
611
  <finally>
585
- <event action="log" level="info" message="Workflow execution completed"/>
612
+ <block type="event" id="E-finally" action="log" level="info" desc="Log workflow complete">
613
+ <field name="message" value="Workflow execution completed"/>
614
+ </block>
586
615
  </finally>
587
- </error-handler>
616
+ </block>
588
617
 
589
618
  </workflow>
590
- ```
591
619
 
592
620
  ## Reference Guides
593
621
 
@@ -607,9 +635,9 @@ When generating Mermaid diagrams, follow compatibility guidelines:
607
635
 
608
636
  ## Constraints
609
637
 
610
- 1. **DO NOT analyze files outside the specified `{{sourcePath}}`**
638
+ 1. **DO NOT analyze files outside the specified `${sourcePath}`**
611
639
  2. **DO NOT generate separate documents for internal/private methods**
612
- 3. **All content MUST be in the language specified by `{{language}}`**
640
+ 3. **All content MUST be in the language specified by `${language}`**
613
641
  4. **Use `search_replace` for section filling, NEVER rewrite entire document**
614
642
  5. **Mermaid diagrams MUST follow the rules in `mermaid-rule.md`**
615
643
  6. **All links MUST use relative paths, NEVER `file://` protocol**
@@ -619,14 +647,14 @@ When generating Mermaid diagrams, follow compatibility guidelines:
619
647
 
620
648
  ## Checklist
621
649
 
622
- - [ ] Template file selected based on `{{tech_stack}}`
650
+ - [ ] Template file selected based on `${tech_stack}`
623
651
  - [ ] Template content read successfully
624
652
  - [ ] Controller file read and analyzed
625
653
  - [ ] API endpoints extracted with business flows
626
654
  - [ ] API consumers found
627
655
  - [ ] Template copied to document path
628
656
  - [ ] All sections filled using search_replace
629
- - [ ] All content in target language (`{{language}}`)
657
+ - [ ] All content in target language (`${language}`)
630
658
  - [ ] Results reported in JSON format
631
659
  - [ ] .done.json marker file written successfully
632
660
  - [ ] .graph.json generation dispatched to graph skill