speccrew 0.7.73 → 0.7.75
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 +96 -0
- package/.speccrew/agents/speccrew-product-manager.md +55 -0
- package/.speccrew/agents/speccrew-system-deployer.md +178 -0
- package/.speccrew/agents/speccrew-system-developer.md +177 -0
- package/.speccrew/agents/speccrew-task-worker.md +18 -0
- package/.speccrew/agents/speccrew-team-leader.md +56 -0
- package/.speccrew/agents/speccrew-test-manager.md +167 -0
- package/.speccrew/skills/speccrew-agentflow-manager/SKILL.md +6 -149
- package/.speccrew/skills/speccrew-deploy-build/SKILL.md +2 -59
- package/.speccrew/skills/speccrew-deploy-migrate/SKILL.md +2 -64
- package/.speccrew/skills/speccrew-deploy-smoke-test/SKILL.md +2 -75
- package/.speccrew/skills/speccrew-deploy-startup/SKILL.md +2 -70
- package/.speccrew/skills/speccrew-dev-backend/SKILL.md +2 -381
- package/.speccrew/skills/speccrew-dev-desktop-electron/SKILL.md +2 -369
- package/.speccrew/skills/speccrew-dev-desktop-tauri/SKILL.md +2 -362
- package/.speccrew/skills/speccrew-dev-frontend/SKILL.md +2 -304
- package/.speccrew/skills/speccrew-dev-mobile/SKILL.md +2 -294
- package/.speccrew/skills/speccrew-dev-review-backend/SKILL.md +2 -204
- package/.speccrew/skills/speccrew-dev-review-desktop/SKILL.md +2 -173
- package/.speccrew/skills/speccrew-dev-review-frontend/SKILL.md +2 -169
- package/.speccrew/skills/speccrew-dev-review-mobile/SKILL.md +2 -173
- package/.speccrew/skills/speccrew-fd-api-contract/SKILL.md +2 -251
- package/.speccrew/skills/speccrew-fd-feature-analyze/SKILL.md +2 -254
- package/.speccrew/skills/speccrew-fd-feature-design/SKILL.md +2 -748
- package/.speccrew/skills/speccrew-feature-designer-orchestration/SKILL.md +6 -105
- package/.speccrew/skills/speccrew-get-timestamp/SKILL.md +6 -33
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/SKILL.md +3 -138
- package/.speccrew/skills/speccrew-knowledge-bizs-api-graph/SKILL.md +3 -283
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/SKILL.md +3 -1014
- package/.speccrew/skills/speccrew-knowledge-bizs-identify-entries/SKILL.md +4 -343
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/SKILL.md +4 -235
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/SKILL.md +6 -72
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/SKILL.md +3 -534
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-graph/SKILL.md +3 -432
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/SKILL.md +4 -391
- package/.speccrew/skills/speccrew-knowledge-graph-query/SKILL.md +3 -98
- package/.speccrew/skills/speccrew-knowledge-graph-write/SKILL.md +3 -92
- package/.speccrew/skills/speccrew-knowledge-module-summarize/SKILL.md +3 -181
- package/.speccrew/skills/speccrew-knowledge-system-summarize/SKILL.md +3 -148
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/SKILL.md +3 -330
- package/.speccrew/skills/speccrew-knowledge-techs-generate/SKILL.md +6 -159
- package/.speccrew/skills/speccrew-knowledge-techs-generate-conventions/SKILL.md +3 -142
- package/.speccrew/skills/speccrew-knowledge-techs-generate-quality/SKILL.md +3 -568
- package/.speccrew/skills/speccrew-knowledge-techs-generate-ui-style/SKILL.md +3 -180
- package/.speccrew/skills/speccrew-knowledge-techs-index/SKILL.md +3 -154
- package/.speccrew/skills/speccrew-knowledge-techs-init/SKILL.md +3 -176
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/SKILL.md +3 -135
- package/.speccrew/skills/speccrew-pm-knowledge-detector/SKILL.md +4 -88
- package/.speccrew/skills/speccrew-pm-module-initializer/SKILL.md +4 -178
- package/.speccrew/skills/speccrew-pm-module-matcher/SKILL.md +3 -102
- package/.speccrew/skills/speccrew-pm-phase0-init/SKILL.md +5 -78
- package/.speccrew/skills/speccrew-pm-phase1-knowledge-check/SKILL.md +5 -85
- package/.speccrew/skills/speccrew-pm-phase2-complexity-assess/SKILL.md +4 -100
- package/.speccrew/skills/speccrew-pm-phase5-subprd-dispatch/SKILL.md +14 -106
- package/.speccrew/skills/speccrew-pm-phase6-verify-confirm/SKILL.md +7 -84
- package/.speccrew/skills/speccrew-pm-requirement-analysis/SKILL.md +6 -66
- package/.speccrew/skills/speccrew-pm-requirement-assess/SKILL.md +4 -96
- package/.speccrew/skills/speccrew-pm-requirement-clarify/SKILL.md +4 -131
- package/.speccrew/skills/speccrew-pm-requirement-model/SKILL.md +6 -79
- package/.speccrew/skills/speccrew-pm-requirement-simple/SKILL.md +4 -76
- package/.speccrew/skills/speccrew-pm-sub-prd-generate/SKILL.md +3 -281
- package/.speccrew/skills/speccrew-product-manager-orchestration/SKILL.md +6 -165
- package/.speccrew/skills/speccrew-system-deployer-orchestration/SKILL.md +6 -79
- package/.speccrew/skills/speccrew-system-designer-orchestration/SKILL.md +2 -35
- package/.speccrew/skills/speccrew-system-developer-orchestration/SKILL.md +6 -98
- package/.speccrew/skills/speccrew-task-worker-execution/SKILL.md +6 -94
- package/.speccrew/skills/speccrew-team-leader-routing/SKILL.md +6 -79
- package/.speccrew/skills/speccrew-test-case-design/SKILL.md +2 -58
- package/.speccrew/skills/speccrew-test-code-gen/SKILL.md +2 -61
- package/.speccrew/skills/speccrew-test-manager-orchestration/SKILL.md +6 -94
- package/.speccrew/skills/speccrew-test-reporter/SKILL.md +2 -102
- package/.speccrew/skills/speccrew-test-runner/SKILL.md +3 -121
- package/package.json +1 -1
- package/workspace-template/docs/rules/agentflow-spec.md +56 -8
|
@@ -4,351 +4,12 @@ description: Analyze source directory structures to identify business module ent
|
|
|
4
4
|
tools: Read, Write, Glob, Grep, Bash
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
Analyze source directory structures to identify business module entry directories for each platform using XML workflow blocks.
|
|
10
|
-
|
|
11
|
-
## Language Adaptation
|
|
12
|
-
|
|
13
|
-
All generated documents must match the user's language. Detect the language from the user's input and generate content accordingly.
|
|
14
|
-
|
|
15
|
-
- User writes in 中文 → Generate Chinese documents, use `language: "zh"`
|
|
16
|
-
- User writes in English → Generate English documents, use `language: "en"`
|
|
17
|
-
- User writes in other languages → Use appropriate language code
|
|
18
|
-
|
|
19
|
-
## Trigger Scenarios
|
|
20
|
-
|
|
21
|
-
- Called by `speccrew-knowledge-bizs-dispatch` Stage 1
|
|
7
|
+
# Trigger Scenarios
|
|
8
|
+
- Called by speccrew-knowledge-bizs-dispatch Stage 1
|
|
22
9
|
- "Identify business module entry directories"
|
|
23
10
|
- "Analyze source structure for business modules"
|
|
24
11
|
|
|
25
|
-
## Input Parameters
|
|
26
|
-
|
|
27
|
-
| Parameter | Type | Required | Description |
|
|
28
|
-
|-----------|------|----------|-------------|
|
|
29
|
-
| `{platforms}` | array | Yes | Platform list from detection phase. Each item: `{platformId, sourcePath, platformType, platformSubtype, techStack}` |
|
|
30
|
-
| `{workspace_path}` | string | Yes | Absolute path to speccrew-workspace directory |
|
|
31
|
-
| `{sync_state_bizs_dir}` | string | Yes | Absolute path to entry-dirs JSON output directory |
|
|
32
|
-
| `{configs_dir}` | string | Yes | Absolute path to configuration files directory (for `tech-stack-mappings.json`) |
|
|
33
|
-
|
|
34
|
-
## Output
|
|
35
|
-
|
|
36
|
-
For each platform, generates:
|
|
37
|
-
- `{sync_state_bizs_dir}/entry-dirs-{platform_id}.json`
|
|
38
|
-
|
|
39
12
|
## AgentFlow Definition
|
|
40
|
-
|
|
41
13
|
<!-- @agentflow: SKILL.xml -->
|
|
42
|
-
|
|
43
|
-
>
|
|
44
|
-
|
|
45
|
-
<!-- ============================================================
|
|
46
|
-
Input Parameters Definition
|
|
47
|
-
============================================================ -->
|
|
48
|
-
<block type="input" id="I1" desc="Workflow input parameters">
|
|
49
|
-
<field name="platforms" required="true" type="array" desc="Platform list from detection phase"/>
|
|
50
|
-
<field name="workspace_path" required="true" type="string" desc="Absolute path to speccrew-workspace directory"/>
|
|
51
|
-
<field name="sync_state_bizs_dir" required="true" type="string" desc="Absolute path to entry-dirs JSON output directory"/>
|
|
52
|
-
<field name="configs_dir" required="true" type="string" desc="Absolute path to configuration files directory"/>
|
|
53
|
-
</block>
|
|
54
|
-
|
|
55
|
-
<!-- ============================================================
|
|
56
|
-
Global Constraints
|
|
57
|
-
============================================================ -->
|
|
58
|
-
<block type="rule" id="R1" level="mandatory" desc="Path constraints">
|
|
59
|
-
<field name="text">Use the provided absolute paths directly. DO NOT construct or derive paths yourself.</field>
|
|
60
|
-
<field name="text">All entryDirs paths must use forward slashes / as path separators (even on Windows)</field>
|
|
61
|
-
<field name="text">Do not include leading or trailing slashes in entryDirs paths</field>
|
|
62
|
-
</block>
|
|
63
|
-
|
|
64
|
-
<block type="rule" id="R-TECHSTACK" level="mandatory" desc="techStack values MUST match tech-stack-mappings.json keys">
|
|
65
|
-
<field name="text">
|
|
66
|
-
The techStack array values MUST exactly match keys defined in tech-stack-mappings.json (e.g., "fastapi", "vue3", "uniapp").
|
|
67
|
-
DO NOT prefix with language name (e.g., use "fastapi" NOT "python-fastapi", use "express" NOT "node-express").
|
|
68
|
-
The tech_identifier input parameter value should be used as the primary techStack entry.
|
|
69
|
-
</field>
|
|
70
|
-
</block>
|
|
71
|
-
|
|
72
|
-
<!-- ============================================================
|
|
73
|
-
Global Continuous Execution Rules
|
|
74
|
-
============================================================ -->
|
|
75
|
-
<block type="rule" id="GLOBAL-R1" level="forbidden" desc="Continuous execution constraints — NEVER violate">
|
|
76
|
-
<field name="text">DO NOT ask user "Should I continue?" or "How would you like to proceed?" during execution</field>
|
|
77
|
-
<field name="text">DO NOT offer options like "Full execution / Partial / Stop" — always execute ALL tasks to completion</field>
|
|
78
|
-
<field name="text">DO NOT suggest "Due to context window limits, let me pause" — complete current task, use checkpoint for resumption</field>
|
|
79
|
-
<field name="text">DO NOT estimate workload and suggest breaking it into phases — execute ALL items in sequence</field>
|
|
80
|
-
<field name="text">DO NOT warn about "large number of files" or "this may take a while" — proceed with generation</field>
|
|
81
|
-
<field name="text">Context window management: if approaching limit, save progress to checkpoint file and resume — do NOT ask user for guidance</field>
|
|
82
|
-
</block>
|
|
83
|
-
|
|
84
|
-
<!-- ============================================================
|
|
85
|
-
Main Processing Sequence
|
|
86
|
-
============================================================ -->
|
|
87
|
-
<sequence id="S1" name="Process Platforms" status="pending" desc="Iterate each platform to identify entry directories">
|
|
88
|
-
|
|
89
|
-
<!-- Loop: Process Each Platform -->
|
|
90
|
-
<block type="loop" id="L1" over="${platforms}" as="platform" desc="Iterate each platform to identify entry directories">
|
|
91
|
-
|
|
92
|
-
<!-- Step 1: Read Directory Tree -->
|
|
93
|
-
<block type="task" id="B1" action="run-script" desc="Read each platform's sourcePath directory structure (3 levels deep)">
|
|
94
|
-
<field name="command">Get-ChildItem -Path "${platform.sourcePath}" -Recurse -Directory -Depth 2 | Select-Object -ExpandProperty FullName</field>
|
|
95
|
-
<field name="note">MUST use Get-ChildItem (NOT tree command). MUST use ${platform.sourcePath} absolute path (NOT relative path). Scan depth follows module_scan.depth configuration from tech-stack-mappings.json.</field>
|
|
96
|
-
<field name="output" var="directory_tree"/>
|
|
97
|
-
</block>
|
|
98
|
-
|
|
99
|
-
<!-- Step 2: LLM Analysis - Identify Entry Directories -->
|
|
100
|
-
<block type="task" id="B2" action="analyze" desc="Analyze directory tree and identify entry directories based on platform type">
|
|
101
|
-
<field name="input" value="${directory_tree}"/>
|
|
102
|
-
<field name="platform_type" value="${platform.platformType}"/>
|
|
103
|
-
<field name="platform_subtype" value="${platform.platformSubtype}"/>
|
|
104
|
-
<field name="tech_stack" value="${platform.techStack}"/>
|
|
105
|
-
<field name="logic_module_scan" value="Read tech-stack-mappings.json for the techStack's module_scan configuration. Use module_scan.root as the scan starting point and module_scan.depth as the grouping level (depth=1 means first-level subdirectories = one module each)"/>
|
|
106
|
-
<field name="logic_backend" value="Find all directories containing *Controller.java or *Controller.kt files under module_scan.root. These are API entry directories. Module name = the business package name of the entry directory. Apply module_scan.depth for grouping level"/>
|
|
107
|
-
<field name="logic_frontend_vue_react" value="Find directories under module_scan.root (e.g., src/views or src/pages). First-level subdirectories under module_scan.root are business modules when depth=1"/>
|
|
108
|
-
<field name="logic_mobile_uniapp" value="Find first-level subdirectories under module_scan.root (e.g., src/pages). Plus top-level pages-* directories (module name = directory name without pages- prefix)"/>
|
|
109
|
-
<field name="logic_mobile_miniprogram" value="Find first-level subdirectories under module_scan.root (e.g., pages) as modules"/>
|
|
110
|
-
<field name="output" var="identified_entries"/>
|
|
111
|
-
</block>
|
|
112
|
-
|
|
113
|
-
<!-- Step 3: Load Exclusion Rules -->
|
|
114
|
-
<block type="task" id="B3" action="read-file" desc="Read tech-stack-mappings.json to load exclusion patterns">
|
|
115
|
-
<field name="path" value="${configs_dir}/tech-stack-mappings.json"/>
|
|
116
|
-
<field name="output" var="exclusion_rules"/>
|
|
117
|
-
</block>
|
|
118
|
-
|
|
119
|
-
<!-- Gateway: Apply Exclusion Rules -->
|
|
120
|
-
<block type="gateway" id="G1" mode="guard" desc="Check if identified_entries is not empty">
|
|
121
|
-
<branch test="${identified_entries} != null AND ${identified_entries.length} > 0">
|
|
122
|
-
<block type="task" id="B4" action="analyze" desc="Apply exclusion rules to filter out technical directories">
|
|
123
|
-
<field name="input" value="${identified_entries}"/>
|
|
124
|
-
<field name="exclusion_rules" value="${exclusion_rules}"/>
|
|
125
|
-
<field name="exclusions_pure_technical" value="config, framework, enums, exception, util, utils, common, constant, constants, type, types, dto, vo, entity, model, mapper, repository, dao, service, impl"/>
|
|
126
|
-
<field name="exclusions_build_output" value="dist, build, target, out, node_modules"/>
|
|
127
|
-
<field name="exclusions_test_directories" value="test, tests, spec, __tests__, e2e"/>
|
|
128
|
-
<field name="exclusions_config_directories" value=".git, .idea, .vscode, .speccrew"/>
|
|
129
|
-
<field name="root_handling" value="Assign entry files not under any subdirectory to _root module"/>
|
|
130
|
-
<field name="output" var="filtered_entries"/>
|
|
131
|
-
</block>
|
|
132
|
-
</branch>
|
|
133
|
-
</block>
|
|
134
|
-
|
|
135
|
-
<!-- Step 4: Generate entry-dirs JSON -->
|
|
136
|
-
<block type="task" id="B5" action="write-file" desc="Generate entry-dirs JSON file for the platform">
|
|
137
|
-
<field name="path" value="${sync_state_bizs_dir}/entry-dirs-${platform.platformId}.json"/>
|
|
138
|
-
<field name="content_json">
|
|
139
|
-
{
|
|
140
|
-
"platformId": "${platform.platformId}",
|
|
141
|
-
"platformName": "${platform.platformName}",
|
|
142
|
-
"platformType": "${platform.platformType}",
|
|
143
|
-
"platformSubtype": "${platform.platformSubtype}",
|
|
144
|
-
"sourcePath": "${platform.sourcePath}",
|
|
145
|
-
"techStack": "${platform.techStack}",
|
|
146
|
-
"modules": [
|
|
147
|
-
{ "name": "module-name", "entryDirs": ["relative/path/to/entry"] }
|
|
148
|
-
]
|
|
149
|
-
}
|
|
150
|
-
</field>
|
|
151
|
-
<field name="output" var="generated_json_path"/>
|
|
152
|
-
</block>
|
|
153
|
-
|
|
154
|
-
<!-- Rule: Output JSON Format Validation -->
|
|
155
|
-
<block type="rule" id="R-FORMAT" scope="mandatory" desc="Output JSON format validation">
|
|
156
|
-
<field name="content">
|
|
157
|
-
The generated entry-dirs JSON file MUST strictly follow this structure:
|
|
158
|
-
- Root object MUST contain "modules" field (array type)
|
|
159
|
-
- Root object MUST NOT contain "businessModules", "subModules", or "components" fields
|
|
160
|
-
- Each module in "modules" array MUST have exactly two fields: "name" (string) and "entryDirs" (array of strings)
|
|
161
|
-
- For platforms with hierarchical directory structure (e.g. frontend views/system/user/), flatten into individual modules
|
|
162
|
-
- Module names should use hyphen-separated composite names for sub-modules (e.g. "system-user", "system-role")
|
|
163
|
-
- Multiple modules MUST NOT share the same entryDirs value. If multiple business areas share the same directory, they belong to ONE module.
|
|
164
|
-
- If the generated JSON does not match this format, you MUST regenerate it before proceeding
|
|
165
|
-
</field>
|
|
166
|
-
<field name="text">Output is strictly the entry-dirs JSON file at the specified output path. Per agentflow-spec.md "Strict Block Adherence" rule, no extra files are permitted.</field>
|
|
167
|
-
</block>
|
|
168
|
-
|
|
169
|
-
<!-- Checkpoint: Persist Generated JSON -->
|
|
170
|
-
<block type="checkpoint" id="CP1" name="entry-dirs-generated" desc="Verify entry-dirs JSON was generated">
|
|
171
|
-
<field name="file" value="${sync_state_bizs_dir}/entry-dirs-${platform.platformId}.json"/>
|
|
172
|
-
<field name="verify" value="file_exists(${sync_state_bizs_dir}/entry-dirs-${platform.platformId}.json)"/>
|
|
173
|
-
</block>
|
|
174
|
-
|
|
175
|
-
<!-- Step 5: Validation -->
|
|
176
|
-
<block type="task" id="B6" action="analyze" desc="Validate the generated entry-dirs JSON">
|
|
177
|
-
<field name="input" value="${generated_json_path}"/>
|
|
178
|
-
<field name="validation_rules">
|
|
179
|
-
- modules array is not empty
|
|
180
|
-
- each module has at least one entry directory
|
|
181
|
-
- module names are business-meaningful (not technical terms like config, util)
|
|
182
|
-
- entryDirs paths are correct and accessible
|
|
183
|
-
- JSON format is valid
|
|
184
|
-
</field>
|
|
185
|
-
<field name="output" var="validation_result"/>
|
|
186
|
-
</block>
|
|
187
|
-
|
|
188
|
-
<!-- Gateway: Validation Result -->
|
|
189
|
-
<block type="gateway" id="G2" mode="exclusive" desc="Handle validation result">
|
|
190
|
-
<branch test="${validation_result.status} == 'failed'">
|
|
191
|
-
<block type="error-handler" id="EH1" desc="Handle validation failure">
|
|
192
|
-
<catch error-type="validation_failed">
|
|
193
|
-
<block type="event" id="E1" action="log" level="warn" desc="Log validation failure">
|
|
194
|
-
<field name="message">Entry directory recognition failed for platform ${platform.platformId}</field>
|
|
195
|
-
</block>
|
|
196
|
-
<block type="task" id="B7" action="analyze" desc="Re-analyze the directory tree due to validation failure">
|
|
197
|
-
<field name="input" value="${directory_tree}"/>
|
|
198
|
-
<field name="output" var="re_analyzed_entries"/>
|
|
199
|
-
</block>
|
|
200
|
-
</catch>
|
|
201
|
-
</block>
|
|
202
|
-
</branch>
|
|
203
|
-
<branch test="${validation_result.status} == 'passed'">
|
|
204
|
-
<block type="event" id="E2" action="log" level="info" desc="Log validation success">
|
|
205
|
-
<field name="message">Platform ${platform.platformId} entry-dirs validation passed</field>
|
|
206
|
-
</block>
|
|
207
|
-
</branch>
|
|
208
|
-
</block>
|
|
209
|
-
|
|
210
|
-
</block>
|
|
211
|
-
|
|
212
|
-
</sequence>
|
|
213
|
-
|
|
214
|
-
<!-- ============================================================
|
|
215
|
-
Output Results
|
|
216
|
-
============================================================ -->
|
|
217
|
-
<block type="output" id="O1" desc="Workflow output results">
|
|
218
|
-
<field name="generated_files" from="${generated_json_path}" type="array" desc="List of all generated entry-dirs JSON files"/>
|
|
219
|
-
<field name="validation_summary" from="${validation_result}" type="object" desc="Summary of validation results for all platforms"/>
|
|
220
|
-
</block>
|
|
221
|
-
|
|
222
|
-
</workflow>
|
|
223
|
-
|
|
224
|
-
## Output JSON Format
|
|
225
|
-
|
|
226
|
-
```json
|
|
227
|
-
{
|
|
228
|
-
"platformId": "backend-ai",
|
|
229
|
-
"platformName": "AI Module Backend",
|
|
230
|
-
"platformType": "backend",
|
|
231
|
-
"platformSubtype": "ai",
|
|
232
|
-
"sourcePath": "yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai",
|
|
233
|
-
"techStack": ["spring-boot", "mybatis-plus"],
|
|
234
|
-
"modules": [
|
|
235
|
-
{ "name": "chat", "entryDirs": ["controller/admin/chat"] },
|
|
236
|
-
{ "name": "image", "entryDirs": ["controller/admin/image"] },
|
|
237
|
-
{ "name": "knowledge", "entryDirs": ["controller/admin/knowledge"] },
|
|
238
|
-
{ "name": "_root", "entryDirs": ["controller/admin"] }
|
|
239
|
-
]
|
|
240
|
-
}
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### Module Granularity (CRITICAL)
|
|
244
|
-
|
|
245
|
-
**Core Principle**: modules = directory-level groupings, NOT file-level features
|
|
246
|
-
|
|
247
|
-
**Configuration-Driven Approach**:
|
|
248
|
-
1. Read `tech-stack-mappings.json` to get the `module_scan` configuration for the detected `techStack`
|
|
249
|
-
2. Use `module_scan.root` as the scanning starting point (e.g., `src/views` for vue, `controller` for spring)
|
|
250
|
-
3. Use `module_scan.depth` as the grouping level:
|
|
251
|
-
- `depth=1`: Each first-level subdirectory under `module_scan.root` = ONE module
|
|
252
|
-
- `depth=2`: Each second-level subdirectory = ONE module (e.g., for android)
|
|
253
|
-
4. Each module represents a distinct source directory containing entry files
|
|
254
|
-
|
|
255
|
-
**NEVER create multiple modules pointing to the SAME entryDirs** — if 10 controller files all reside in the same directory, that is ONE module with that directory as entryDirs, NOT 10 separate modules
|
|
256
|
-
|
|
257
|
-
**Key Rules**:
|
|
258
|
-
- The downstream `generate-inventory.js` script handles file-level decomposition within each module's entryDirs — that is NOT the job of this skill
|
|
259
|
-
- Module names should correspond to directory names, not individual file names
|
|
260
|
-
- Typical module count for a medium project: 3-10 modules (not 30+)
|
|
261
|
-
|
|
262
|
-
**Correct example** (directory-level, vue with module_scan.root="src/views", depth=1):
|
|
263
|
-
```json
|
|
264
|
-
{
|
|
265
|
-
"modules": [
|
|
266
|
-
{ "name": "ai", "entryDirs": ["src/views/ai"] },
|
|
267
|
-
{ "name": "bpm", "entryDirs": ["src/views/bpm"] },
|
|
268
|
-
{ "name": "system", "entryDirs": ["src/views/system"] }
|
|
269
|
-
]
|
|
270
|
-
}
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
**WRONG example** (file-level — FORBIDDEN):
|
|
274
|
-
```json
|
|
275
|
-
{
|
|
276
|
-
"modules": [
|
|
277
|
-
{ "name": "system-user", "entryDirs": ["src/views/system"] },
|
|
278
|
-
{ "name": "system-role", "entryDirs": ["src/views/system"] },
|
|
279
|
-
{ "name": "system-dept", "entryDirs": ["src/views/system"] }
|
|
280
|
-
]
|
|
281
|
-
}
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
### Format Constraints
|
|
285
|
-
|
|
286
|
-
- **MUST use `modules` array** — never use `businessModules`, `components`, or any alternative field name
|
|
287
|
-
- **MUST flatten hierarchy** — if a platform has sub-modules (e.g. frontend `system/user`, `system/role`), each sub-module must be a separate top-level module entry in the `modules` array
|
|
288
|
-
- 例如:`system` 有 `user` 和 `role` 子目录 → 生成 `{ "name": "system-user", "entryDirs": ["src/views/system/user"] }` 和 `{ "name": "system-role", "entryDirs": ["src/views/system/role"] }`
|
|
289
|
-
- **Forbidden fields**: `businessModules`, `subModules`, `components`, `hasSubModules` — 这些都不被下游脚本支持
|
|
290
|
-
- **Each module's entryDirs** must point to directories containing actual entry files (e.g. .vue, .py, .java), not parent wrapper directories
|
|
291
|
-
|
|
292
|
-
### Field Definitions
|
|
293
|
-
|
|
294
|
-
- `platformId`: Platform identifier (e.g., `backend-ai`, `web-vue`, `mobile-uniapp`)
|
|
295
|
-
- `platformName`: (Optional) Human-readable platform name. Auto-generated as `{platform_type}-{platform_subtype}` if missing
|
|
296
|
-
- `platformType`: (Optional) Platform type: `backend`, `web`, `mobile`, `desktop`. Inferred from platform_id if missing
|
|
297
|
-
- `platformSubtype`: (Optional) Platform subtype (e.g., `ai`, `vue`, `uniapp`). Inferred from platform_id if missing
|
|
298
|
-
- `sourcePath`: Absolute path to the platform source root
|
|
299
|
-
- `techStack`: (Optional) Array of tech stack names (e.g., `["spring-boot", "mybatis-plus"]`). Default inferred from platform_type
|
|
300
|
-
- `modules`: Array of business modules
|
|
301
|
-
- `name`: Module name (business-meaningful, e.g., `chat`, `system`, `order`)
|
|
302
|
-
- `entryDirs`: Array of entry directory paths (relative to `{source_path}`)
|
|
303
|
-
|
|
304
|
-
### Path Rules
|
|
305
|
-
|
|
306
|
-
- All `entryDirs` paths must be relative to `{sourcePath}`
|
|
307
|
-
- Use forward slashes `/` as path separators (even on Windows)
|
|
308
|
-
- Do not include leading or trailing slashes
|
|
309
|
-
|
|
310
|
-
## Error Handling
|
|
311
|
-
|
|
312
|
-
| Scenario | Handling |
|
|
313
|
-
|----------|----------|
|
|
314
|
-
| Entry directory recognition fails | STOP and report error with platform details. Do NOT continue processing that platform. |
|
|
315
|
-
| Validation fails | Re-analyze the directory tree and regenerate |
|
|
316
|
-
| Config file not found | Use default exclusion rules and log warning |
|
|
317
|
-
|
|
318
|
-
## Checklist
|
|
319
|
-
|
|
320
|
-
- [ ] All platforms' entry-dirs JSON files have been generated
|
|
321
|
-
- [ ] Each platform's `modules` array is non-empty
|
|
322
|
-
- [ ] Module names have business meaning (not technical terms like config, util)
|
|
323
|
-
- [ ] `entryDirs` paths are correct and accessible
|
|
324
|
-
- [ ] JSON format is valid
|
|
325
|
-
- [ ] All paths use forward slashes as separators
|
|
326
|
-
- [ ] No leading or trailing slashes in entryDirs paths
|
|
327
|
-
|
|
328
|
-
> **MANDATORY**: Use the provided absolute paths directly. DO NOT construct or derive paths yourself.
|
|
329
|
-
|
|
330
|
-
## Example Usage
|
|
331
|
-
|
|
332
|
-
```
|
|
333
|
-
Skill: speccrew-knowledge-bizs-identify-entries
|
|
334
|
-
Args:
|
|
335
|
-
platforms: [
|
|
336
|
-
{
|
|
337
|
-
"platformId": "backend-ai",
|
|
338
|
-
"sourcePath": "/path/to/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai",
|
|
339
|
-
"platformType": "backend",
|
|
340
|
-
"platformSubtype": "ai",
|
|
341
|
-
"techStack": ["spring-boot", "mybatis-plus"]
|
|
342
|
-
},
|
|
343
|
-
{
|
|
344
|
-
"platformId": "web-vue",
|
|
345
|
-
"sourcePath": "/path/to/yudao-ui-admin/src",
|
|
346
|
-
"platformType": "web",
|
|
347
|
-
"platformSubtype": "vue",
|
|
348
|
-
"techStack": ["vue3", "element-plus"]
|
|
349
|
-
}
|
|
350
|
-
]
|
|
351
|
-
workspace_path: "/path/to/speccrew-workspace"
|
|
352
|
-
sync_state_bizs_dir: "/path/to/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs"
|
|
353
|
-
configs_dir: "/path/to/speccrew-workspace/docs/configs"
|
|
354
|
-
```
|
|
14
|
+
> **REQUIRED**: Before executing this workflow, read the XML workflow specification: speccrew-workspace/docs/rules/agentflow-spec.md
|
|
15
|
+
> Then read and execute the XML workflow in SKILL.xml block-by-block as the authoritative execution plan.
|
|
@@ -4,243 +4,12 @@ description: Execute generate-inventory.js script to create features.json invent
|
|
|
4
4
|
tools: Read, Write, Bash
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
8
|
-
|
|
9
|
-
Execute generate-inventory.js script to create features.json inventory for a single platform. This is a Stage 1b worker skill called by dispatch after platform detection and entry directory identification are complete.
|
|
10
|
-
|
|
11
|
-
## Language Adaptation
|
|
12
|
-
|
|
13
|
-
All generated documents must match the user's language. Detect the language from the user's input and generate content accordingly.
|
|
14
|
-
|
|
15
|
-
- User writes in 中文 → Generate Chinese documents, use `language: "zh"`
|
|
16
|
-
- User writes in English → Generate English documents, use `language: "en"`
|
|
17
|
-
- User writes in other languages → Use appropriate language code
|
|
18
|
-
|
|
19
|
-
## Trigger Scenarios
|
|
20
|
-
|
|
21
|
-
- Called by `speccrew-knowledge-bizs-dispatch` Stage 1b
|
|
7
|
+
# Trigger Scenarios
|
|
8
|
+
- Called by speccrew-knowledge-bizs-dispatch Stage 1b
|
|
22
9
|
- "Generate feature inventory for platform"
|
|
23
10
|
- "Create features.json from entry-dirs"
|
|
24
11
|
|
|
25
|
-
## Input Parameters
|
|
26
|
-
|
|
27
|
-
| Parameter | Type | Required | Description |
|
|
28
|
-
|-----------|------|----------|-------------|
|
|
29
|
-
| `platformId` | string | Yes | Platform identifier (e.g., "backend-fastapi", "web-vue3", "mobile-uniapp") |
|
|
30
|
-
| `platformName` | string | Yes | Platform display name |
|
|
31
|
-
| `platformType` | string | Yes | Platform type: backend, web, mobile |
|
|
32
|
-
| `platformSubtype` | string | No | Platform subtype (e.g., vue, react, uniapp) |
|
|
33
|
-
| `sourcePath` | string | Yes | Absolute path to platform source root |
|
|
34
|
-
| `techIdentifier` | string | Yes | Technology stack identifier |
|
|
35
|
-
| `entryDirsFile` | string | Yes | Absolute path to entry-dirs JSON file |
|
|
36
|
-
| `outputDir` | string | Yes | Absolute path to features JSON output directory |
|
|
37
|
-
| `workspace_path` | string | Yes | Absolute path to speccrew-workspace directory |
|
|
38
|
-
| `sync_state_bizs_dir` | string | Yes | Absolute path to knowledges/base/sync-state/knowledge-bizs/ (✓ correct: .../knowledges/base/sync-state/knowledge-bizs/ | ✗ wrong: .../knowledges/bizs/sync-state/knowledge-bizs/) |
|
|
39
|
-
| `language` | string | Yes | Language code for generated content |
|
|
40
|
-
|
|
41
|
-
## Output
|
|
42
|
-
|
|
43
|
-
- `${outputDir}/features-${platformId}.json`
|
|
44
|
-
|
|
45
12
|
## AgentFlow Definition
|
|
46
|
-
|
|
47
13
|
<!-- @agentflow: SKILL.xml -->
|
|
48
|
-
|
|
49
|
-
>
|
|
50
|
-
|
|
51
|
-
<!-- ============================================================
|
|
52
|
-
Input Parameters Definition
|
|
53
|
-
============================================================ -->
|
|
54
|
-
<block type="input" id="I1" desc="Workflow input parameters">
|
|
55
|
-
<field name="platformId" required="true" type="string" desc="Platform identifier"/>
|
|
56
|
-
<field name="platformName" required="true" type="string" desc="Platform display name"/>
|
|
57
|
-
<field name="platformType" required="true" type="string" desc="Platform type: backend/web/mobile"/>
|
|
58
|
-
<field name="platformSubtype" required="false" type="string" desc="Platform subtype"/>
|
|
59
|
-
<field name="sourcePath" required="true" type="string" desc="Absolute path to platform source root"/>
|
|
60
|
-
<field name="techIdentifier" required="true" type="string" desc="Technology stack identifier"/>
|
|
61
|
-
<field name="entryDirsFile" required="true" type="string" desc="Absolute path to entry-dirs JSON file"/>
|
|
62
|
-
<field name="outputDir" required="true" type="string" desc="Absolute path to features JSON output directory"/>
|
|
63
|
-
<field name="workspace_path" required="true" type="string" desc="Absolute path to speccrew-workspace directory"/>
|
|
64
|
-
<field name="sync_state_bizs_dir" required="true" type="string" desc="Absolute path to knowledges/base/sync-state/knowledge-bizs/ (✓ correct: .../knowledges/base/sync-state/knowledge-bizs/ | ✗ wrong: .../knowledges/bizs/sync-state/knowledge-bizs/)"/>
|
|
65
|
-
<field name="language" required="true" type="string" desc="Language code for generated content"/>
|
|
66
|
-
</block>
|
|
67
|
-
|
|
68
|
-
<!-- ============================================================
|
|
69
|
-
Global Constraints
|
|
70
|
-
============================================================ -->
|
|
71
|
-
<block type="rule" id="R1" level="mandatory" desc="Path constraints">
|
|
72
|
-
<field name="text">Use the provided absolute paths directly. DO NOT construct or derive paths yourself.</field>
|
|
73
|
-
<field name="text">All paths must use forward slashes / as path separators (even on Windows)</field>
|
|
74
|
-
</block>
|
|
75
|
-
|
|
76
|
-
<block type="rule" id="R2" level="forbidden" desc="Script execution constraints">
|
|
77
|
-
<field name="text">DO NOT manually scan source files or manually construct features JSON</field>
|
|
78
|
-
<field name="text">MUST execute generate-inventory.js script - if script not found, STOP and report error</field>
|
|
79
|
-
<field name="text">DO NOT use read_file, Glob, Grep, or search_codebase as substitutes for script execution</field>
|
|
80
|
-
</block>
|
|
81
|
-
|
|
82
|
-
<!-- ============================================================
|
|
83
|
-
Global Continuous Execution Rules
|
|
84
|
-
============================================================ -->
|
|
85
|
-
<block type="rule" id="GLOBAL-R1" level="forbidden" desc="Continuous execution constraints — NEVER violate">
|
|
86
|
-
<field name="text">DO NOT ask user "Should I continue?" or "How would you like to proceed?" during execution</field>
|
|
87
|
-
<field name="text">DO NOT offer options like "Full execution / Partial / Stop" — always execute ALL tasks to completion</field>
|
|
88
|
-
<field name="text">DO NOT suggest "Due to context window limits, let me pause" — complete current task, use checkpoint for resumption</field>
|
|
89
|
-
<field name="text">DO NOT estimate workload and suggest breaking it into phases — execute ALL items in sequence</field>
|
|
90
|
-
<field name="text">DO NOT warn about "large number of files" or "this may take a while" — proceed with generation</field>
|
|
91
|
-
<field name="text">Context window management: if approaching limit, save progress to checkpoint file and resume — do NOT ask user for guidance</field>
|
|
92
|
-
</block>
|
|
93
|
-
|
|
94
|
-
<!-- ============================================================
|
|
95
|
-
Main Processing Sequence
|
|
96
|
-
============================================================ -->
|
|
97
|
-
<sequence id="S1" name="Generate Features Inventory" status="pending" desc="Execute script to generate features.json">
|
|
98
|
-
|
|
99
|
-
<!-- Step 1: Verify entry-dirs JSON exists and is valid -->
|
|
100
|
-
<block type="task" id="B1" action="read-file" desc="Read entry-dirs JSON to verify file exists and modules non-empty">
|
|
101
|
-
<field name="path" value="${entryDirsFile}"/>
|
|
102
|
-
<field name="output" var="entry_dirs_content"/>
|
|
103
|
-
</block>
|
|
104
|
-
|
|
105
|
-
<!-- Gateway: Validate entry-dirs content -->
|
|
106
|
-
<block type="gateway" id="G1" mode="guard" desc="Verify entry-dirs has modules"
|
|
107
|
-
test="${entry_dirs_content.modules} != null AND ${entry_dirs_content.modules.length} > 0"
|
|
108
|
-
fail-action="stop">
|
|
109
|
-
<field name="message">Entry-dirs JSON must have non-empty modules array: ${entryDirsFile}</field>
|
|
110
|
-
</block>
|
|
111
|
-
|
|
112
|
-
<!-- Step 2: Execute generate-inventory.js script -->
|
|
113
|
-
<block type="task" id="B2" action="run-script" desc="Execute generate-inventory.js to create features.json">
|
|
114
|
-
<field name="command">node "${workspace_path}/../.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js" --entryDirsFile "${entryDirsFile}" --outputDir "${outputDir}"</field>
|
|
115
|
-
<field name="note">Script path discovery: Worker must locate generate-inventory.js in IDE skills directory. Search order: 1) .qoder/skills/ 2) .speccrew/skills/ 3) .cursor/skills/ - all relative to project root (workspace_path parent). If script not found, STOP and report error.</field>
|
|
116
|
-
<field name="output" var="script_result"/>
|
|
117
|
-
</block>
|
|
118
|
-
|
|
119
|
-
<!-- Checkpoint: Verify features.json generated -->
|
|
120
|
-
<block type="checkpoint" id="CP1" name="features-generated" desc="Verify features JSON was generated">
|
|
121
|
-
<field name="file" value="${outputDir}/features-${platformId}.json"/>
|
|
122
|
-
<field name="verify" value="file_exists(${outputDir}/features-${platformId}.json)"/>
|
|
123
|
-
</block>
|
|
124
|
-
|
|
125
|
-
<!-- Step 3: Validate output JSON structure -->
|
|
126
|
-
<block type="task" id="B3" action="analyze" desc="Validate features.json structure">
|
|
127
|
-
<field name="input" value="${outputDir}/features-${platformId}.json"/>
|
|
128
|
-
<field name="validation_rules">
|
|
129
|
-
- platformName matches input platformName
|
|
130
|
-
- platformType matches input platformType
|
|
131
|
-
- techStack is valid array
|
|
132
|
-
- features array is non-empty
|
|
133
|
-
- each feature has: fileName, sourcePath, module, analyzed=false
|
|
134
|
-
- sourcePath uses forward slashes
|
|
135
|
-
</field>
|
|
136
|
-
<field name="output" var="validation_result"/>
|
|
137
|
-
</block>
|
|
138
|
-
|
|
139
|
-
<!-- Gateway: Handle validation result -->
|
|
140
|
-
<block type="gateway" id="G2" mode="exclusive" desc="Handle validation result">
|
|
141
|
-
<branch test="${validation_result.status} == 'failed'">
|
|
142
|
-
<block type="event" id="E1" action="log" level="error" desc="Log validation failure">
|
|
143
|
-
<field name="message">Features JSON validation failed for platform ${platformId}: ${validation_result.errors}</field>
|
|
144
|
-
</block>
|
|
145
|
-
<block type="error-handler" id="EH1" desc="Handle validation failure">
|
|
146
|
-
<catch error-type="validation_failed">
|
|
147
|
-
<field name="action">STOP - features.json structure invalid, manual intervention required</field>
|
|
148
|
-
</catch>
|
|
149
|
-
</block>
|
|
150
|
-
</branch>
|
|
151
|
-
<branch test="${validation_result.status} == 'passed'">
|
|
152
|
-
<block type="event" id="E2" action="log" level="info" desc="Log validation success">
|
|
153
|
-
<field name="message">Platform ${platformId} features.json validation passed</field>
|
|
154
|
-
</block>
|
|
155
|
-
</branch>
|
|
156
|
-
</block>
|
|
157
|
-
|
|
158
|
-
</sequence>
|
|
159
|
-
|
|
160
|
-
<!-- ============================================================
|
|
161
|
-
Output Results
|
|
162
|
-
============================================================ -->
|
|
163
|
-
<block type="output" id="O1" desc="Workflow output results">
|
|
164
|
-
<field name="generated_file" value="${outputDir}/features-${platformId}.json" type="string" desc="Path to generated features JSON"/>
|
|
165
|
-
<field name="feature_count" from="${validation_result.feature_count}" type="number" desc="Number of features in inventory"/>
|
|
166
|
-
<field name="validation_status" from="${validation_result.status}" type="string" desc="Validation result status"/>
|
|
167
|
-
</block>
|
|
168
|
-
|
|
169
|
-
</workflow>
|
|
170
|
-
|
|
171
|
-
## Output JSON Format
|
|
172
|
-
|
|
173
|
-
```json
|
|
174
|
-
{
|
|
175
|
-
"platformName": "Web Frontend",
|
|
176
|
-
"platformType": "web",
|
|
177
|
-
"sourcePath": "frontend-web/src/views",
|
|
178
|
-
"techStack": ["vue", "typescript"],
|
|
179
|
-
"modules": [
|
|
180
|
-
{ "name": "chat", "featureCount": 12 },
|
|
181
|
-
{ "name": "image", "featureCount": 8 }
|
|
182
|
-
],
|
|
183
|
-
"totalFiles": 25,
|
|
184
|
-
"analyzedCount": 0,
|
|
185
|
-
"pendingCount": 25,
|
|
186
|
-
"generatedAt": "2024-01-15-103000",
|
|
187
|
-
"features": [
|
|
188
|
-
{
|
|
189
|
-
"fileName": "index",
|
|
190
|
-
"sourcePath": "frontend-web/src/views/system/user/index.vue",
|
|
191
|
-
"documentPath": "speccrew-workspace/knowledges/bizs/web-vue/src/views/system/user/index.md",
|
|
192
|
-
"module": "system",
|
|
193
|
-
"analyzed": false,
|
|
194
|
-
"startedAt": null,
|
|
195
|
-
"completedAt": null,
|
|
196
|
-
"analysisNotes": null
|
|
197
|
-
}
|
|
198
|
-
]
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### Field Definitions
|
|
203
|
-
|
|
204
|
-
- `platformName`: Human-readable platform name
|
|
205
|
-
- `platformType`: Platform type (backend, web, mobile)
|
|
206
|
-
- `sourcePath`: Platform source root path (project-root-relative)
|
|
207
|
-
- `techStack`: Array of technology identifiers
|
|
208
|
-
- `modules`: Array of modules with feature counts
|
|
209
|
-
- `totalFiles`: Total number of feature files
|
|
210
|
-
- `analyzedCount`: Number of analyzed features (initially 0)
|
|
211
|
-
- `pendingCount`: Number of pending features (initially totalFiles)
|
|
212
|
-
- `generatedAt`: ISO timestamp when file was generated
|
|
213
|
-
- `features`: Array of feature objects
|
|
214
|
-
- `fileName`: File name without extension
|
|
215
|
-
- `sourcePath`: Relative path to source file (project-root-relative)
|
|
216
|
-
- `documentPath`: Relative path to target document
|
|
217
|
-
- `module`: Module name this feature belongs to
|
|
218
|
-
- `analyzed`: Whether analysis is complete (initially false)
|
|
219
|
-
- `startedAt`: Analysis start timestamp (null initially)
|
|
220
|
-
- `completedAt`: Analysis completion timestamp (null initially)
|
|
221
|
-
- `analysisNotes`: Analysis notes (null initially)
|
|
222
|
-
|
|
223
|
-
## Error Handling
|
|
224
|
-
|
|
225
|
-
| Scenario | Handling |
|
|
226
|
-
|----------|----------|
|
|
227
|
-
| entry-dirs JSON not found | STOP and report error with file path |
|
|
228
|
-
| entry-dirs modules array empty | STOP - cannot generate features without entry directories |
|
|
229
|
-
| generate-inventory.js script not found | STOP and report error - do NOT attempt manual generation |
|
|
230
|
-
| Script execution fails | STOP and report error with exit code and stderr |
|
|
231
|
-
| features.json validation fails | STOP - manual intervention required |
|
|
232
|
-
| features array empty | WARNING - platform may have no recognizable features |
|
|
233
|
-
|
|
234
|
-
## Checklist
|
|
235
|
-
|
|
236
|
-
- [ ] entry-dirs JSON file exists and is readable
|
|
237
|
-
- [ ] entry-dirs JSON has non-empty modules array
|
|
238
|
-
- [ ] generate-inventory.js script located and executed
|
|
239
|
-
- [ ] features-${platformId}.json file generated
|
|
240
|
-
- [ ] Output JSON has valid platform metadata
|
|
241
|
-
- [ ] features array is non-empty
|
|
242
|
-
- [ ] Each feature has required fields (fileName, sourcePath, module, analyzed)
|
|
243
|
-
- [ ] All sourcePath values use forward slashes
|
|
244
|
-
- [ ] analyzed field is false for all features (initial state)
|
|
245
|
-
|
|
246
|
-
> **MANDATORY**: Use the provided absolute paths directly. DO NOT construct or derive paths yourself. DO NOT manually create JSON files - MUST execute the script.
|
|
14
|
+
> **REQUIRED**: Before executing this workflow, read the XML workflow specification: speccrew-workspace/docs/rules/agentflow-spec.md
|
|
15
|
+
> Then read and execute the XML workflow in SKILL.xml block-by-block as the authoritative execution plan.
|