speccrew 0.6.5 → 0.6.8

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.
@@ -8,19 +8,23 @@ tools: Read, Write, Glob, Grep, SearchCodebase, Skill, Bash
8
8
 
9
9
  | Parameter | Type | Required | Description |
10
10
  |-----------|------|----------|-------------|
11
- | {source_path} | string | No | Source code directory path (default: project root) |
12
- | {language} | string | Yes | Target language for generated content (e.g., "zh", "en") |
11
+ | `source_path` | string | No | Source code directory path (default: project root) |
12
+ | `language` | string | Yes | Target language for generated content (e.g., "zh", "en") |
13
+ | `sync_state_bizs_dir` | string | Yes | Absolute path to features and entry-dirs JSON output directory |
14
+ | `configs_dir` | string | Yes | Absolute path to configuration files directory |
15
+ | `ide_skills_dir` | string | Yes | Absolute path to IDE skills directory (e.g., `.qoder/skills`) |
13
16
 
14
17
  ## Output
15
18
 
16
- - `speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/features-{platform}.json` - Platform-specific feature inventory files
19
+ - `{sync_state_bizs_dir}/features-{platform}.json` - Platform-specific feature inventory files
20
+ - `{sync_state_bizs_dir}/entry-dirs-{platform}.json` - Entry directories configuration files
17
21
 
18
22
  ## Workflow
19
23
 
20
24
  ```mermaid
21
25
  flowchart TD
22
26
  Start([Start]) --> Step1[Step 1: Identify Platforms]
23
- Step1 --> Step2[Step 2: Configure Platform Parameters]
27
+ Step1 --> Step2[Step 2: Identify Entry Directories]
24
28
  Step2 --> Step3[Step 3: Execute Inventory Scripts]
25
29
  Step3 --> Step4[Step 4: Report Results]
26
30
  Step4 --> End([End])
@@ -31,8 +35,8 @@ flowchart TD
31
35
  **Detection Process:**
32
36
 
33
37
  1. **Read Configuration:**
34
- - `speccrew-workspace/docs/configs/platform-mapping.json` - Platform type and subtype mappings
35
- - `speccrew-workspace/docs/configs/tech-stack-mappings.json` - Tech stack configurations and exclude directories
38
+ - `{configs_dir}/platform-mapping.json` - Platform type and subtype mappings
39
+ - `{configs_dir}/tech-stack-mappings.json` - Tech stack configurations and exclude directories
36
40
 
37
41
  2. Scan `{source_path}` for platform-specific configuration files (e.g., package.json, pubspec.yaml, pom.xml)
38
42
 
@@ -52,122 +56,70 @@ flowchart TD
52
56
  - Lookup `platform-mapping.json`: `web` + `vue` → `platform_type=web`, `platform_subtype=vue`
53
57
  - Lookup `tech-stack-mappings.json`: vue → extensions=[".vue"], exclude_dirs=["components","utils"]
54
58
 
55
- ### Step 2: Configure Platform Parameters
59
+ ### Step 2: Identify Entry Directories
56
60
 
57
- For each detected platform, configure the following parameters:
61
+ For each platform detected in Step 1, identify business module entry directories.
58
62
 
59
- | Parameter | Description | Example |
60
- |-----------|-------------|---------|
61
- | `SourcePath` | Source directory relative to project root | `frontend-web/src/views` |
62
- | `OutputFileName` | Output file name | `features-web.json` |
63
- | `PlatformName` | Human-readable platform name | `Web Frontend` |
64
- | `PlatformType` | Platform category | `web`, `mobile`, `backend`, `desktop` |
65
- | `PlatformSubtype` | Technology/framework | `vue`, `react`, `flutter`, `spring` |
66
- | `TechStack` | Technology stack array | `["vue", "typescript"]` |
67
- | `FileExtensions` | File extensions to scan | `[".vue", ".ts"]` |
68
- | `ExcludeDirs` | Directories to exclude | `["components", "utils"]` |
63
+ **Option A: Invoke Skill (Recommended)**
69
64
 
70
- ### Step 3: Execute Inventory Scripts
65
+ Dispatch Worker with `speccrew-knowledge-bizs-identify-entries` skill:
71
66
 
72
- > **MANDATORY**: You MUST execute the provided scripts via `run_in_terminal`. DO NOT use `read_file`, `search_codebase`, `Glob`, or any other tool to substitute script execution. DO NOT manually scan files and construct JSON output yourself.
67
+ | Parameter | Value |
68
+ |-----------|-------|
69
+ | `platforms` | Platform list from Step 1 (each with platformId, sourcePath, platformType, platformSubtype, techStack) |
70
+ | `workspace_path` | Absolute path to speccrew-workspace |
71
+ | `sync_state_bizs_dir` | `{sync_state_bizs_dir}` |
72
+ | `configs_dir` | `{configs_dir}` |
73
73
 
74
- Execute the inventory script for each platform:
74
+ Worker generates `entry-dirs-{platform_id}.json` files in `{sync_state_bizs_dir}/`.
75
75
 
76
- **Prerequisites:**
77
- - Node.js 14.0+
76
+ **Option B: Direct Execution**
78
77
 
79
- **Script Location (relative to this skill's directory):**
80
- - All Platforms: `{skill_path}/scripts/generate-inventory.js`
78
+ If executing directly (without Worker dispatch), follow the same logic as the `speccrew-knowledge-bizs-identify-entries` skill:
79
+ 1. Read each platform's directory tree (3 levels deep)
80
+ 2. Identify entry directories based on platform type:
81
+ - **Backend**: Find directories containing `*Controller.*` files, extract business package names
82
+ - **Frontend**: Find `views/` or `pages/` directories, use first-level subdirectories as modules
83
+ - **Mobile**: Find `pages/` subdirectories + top-level `pages-*` directories
84
+ 3. Apply exclusion rules from `{configs_dir}/tech-stack-mappings.json`
85
+ 4. Generate `entry-dirs-{platform_id}.json` files to `{sync_state_bizs_dir}/`
81
86
 
82
- **Example - Web Platform (Vue):**
83
- ```bash
84
- node "scripts/generate-inventory.js" \
85
- --sourcePath "frontend-web/src/views" \
86
- --outputFileName "features-web.json" \
87
- --platformName "Web Frontend" \
88
- --platformType "web" \
89
- --platformSubtype "vue" \
90
- --techStack "vue,typescript" \
91
- --fileExtensions ".vue" \
92
- --excludeDirs "components,composables,hooks,utils"
93
- ```
87
+ **Verification**: Confirm each entry-dirs JSON has non-empty `modules` array with business-meaningful names.
94
88
 
95
- **Example - Mobile Platform (UniApp):**
96
- ```bash
97
- node "scripts/generate-inventory.js" \
98
- --sourcePath "frontend-mobile/pages" \
99
- --outputFileName "features-mobile.json" \
100
- --platformName "Mobile App" \
101
- --platformType "mobile" \
102
- --platformSubtype "uniapp" \
103
- --techStack "uniapp,vue" \
104
- --fileExtensions ".vue" \
105
- --excludeDirs "components,utils"
106
- ```
89
+ ### Step 3: Execute Inventory Scripts
107
90
 
108
- **Example - Backend Platform (Spring Single Module):**
109
- ```bash
110
- node "scripts/generate-inventory.js" \
111
- --sourcePath "backend/src/main/java/com/example/controller" \
112
- --outputFileName "features-backend.json" \
113
- --platformName "Backend API" \
114
- --platformType "backend" \
115
- --platformSubtype "spring" \
116
- --techStack "spring-boot,java" \
117
- --fileExtensions ".java" \
118
- --excludeDirs ""
119
- ```
91
+ > **MANDATORY**: You MUST execute the provided scripts via `run_in_terminal`. DO NOT use `read_file`, `search_codebase`, `Glob`, or any other tool to substitute script execution. DO NOT manually scan files and construct JSON output yourself.
120
92
 
121
- **Example - Backend Platform (Spring Multi-Module):**
93
+ Execute the inventory script for each platform using the entry-dirs JSON from Step 2:
122
94
 
123
- > **IMPORTANT for Java/Kotlin backends**: Set `sourcePath` to the Java package root directory (e.g., `yudao-module-system/src/main/java/cn/iocoder/yudao/module/system`), NOT the module root. This ensures the `getModuleName` function extracts business module names (like `dept`, `auth`) instead of Java package segments (like `src`, `cn`).
95
+ **Prerequisites:**
96
+ - Node.js 14.0+
124
97
 
125
- For projects with multiple backend modules (e.g., ruoyi-vue-pro), execute the script once per module:
98
+ **Script Location:**
99
+ - All Platforms: `{ide_skills_dir}/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js`
126
100
 
101
+ **Execution Command:**
127
102
  ```bash
128
- # Module 1: AI
129
- node "scripts/generate-inventory.js" \
130
- --sourcePath "yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai" \
131
- --outputFileName "features-backend-ai.json" \
132
- --platformName "Backend API - AI Module" \
133
- --platformType "backend" \
134
- --platformSubtype "ai" \
135
- --techIdentifier "spring" \
136
- --techStack "spring-boot,java" \
137
- --fileExtensions ".java" \
138
- --excludeDirs ""
139
-
140
- # Module 2: System
141
- node "scripts/generate-inventory.js" \
142
- --sourcePath "yudao-module-system/src/main/java/cn/iocoder/yudao/module/system" \
143
- --outputFileName "features-backend-system.json" \
144
- --platformName "Backend API - System Module" \
145
- --platformType "backend" \
146
- --platformSubtype "system" \
147
- --techIdentifier "spring" \
148
- --techStack "spring-boot,java" \
149
- --fileExtensions ".java" \
150
- --excludeDirs ""
103
+ node "{ide_skills_dir}/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js" --entryDirsFile "{sync_state_bizs_dir}/entry-dirs-{platform_id}.json" --outputDir "{sync_state_bizs_dir}"
151
104
  ```
152
105
 
153
- > **Note**: For multi-module backend projects, prefer per-module execution (above) over scan-all to get proper module-level directory isolation (e.g., `backend-ai/`, `backend-system/`).
154
-
155
- **Alternative: Scan All Modules at Once**
156
-
157
- If all modules share the same parent directory structure, you can scan from the project root:
106
+ **Parameters:**
107
+ - `--entryDirsFile`: Path to the `entry-dirs-{platform_id}.json` file in `{sync_state_bizs_dir}/`
108
+ - `--outputDir`: Output directory for `features-{platform}.json` (use `{sync_state_bizs_dir}`)
158
109
 
110
+ **Example:**
159
111
  ```bash
160
- node "scripts/generate-inventory.js" \
161
- --sourcePath "." \
162
- --outputFileName "features-backend-all.json" \
163
- --platformName "Backend API - All Modules" \
164
- --platformType "backend" \
165
- --platformSubtype "spring" \
166
- --techStack "spring-boot,java" \
167
- --fileExtensions ".java" \
168
- --excludeDirs "test,target,.git"
112
+ # Execute for each platform's entry-dirs file
113
+ node "d:/project/.qoder/skills/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js" --entryDirsFile "d:/project/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/entry-dirs-backend-system.json" --outputDir "d:/project/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs"
169
114
  ```
170
115
 
116
+ **Script Parameters**:
117
+ - `--entryDirsFile`: (Required) Path to the `entry-dirs-{platform_id}.json` file in `{sync_state_bizs_dir}/`
118
+ - `--outputDir`: (Required) Output directory for `features-{platform}.json` (use `{sync_state_bizs_dir}`)
119
+ - `--techIdentifier`: (Optional) Technology identifier for tech-stack lookup (auto-detected from platform mapping if omitted)
120
+ - `--fileExtensions`: (Optional) Comma-separated list of file extensions to include
121
+ - `--excludeDirs`: (Optional) Additional directories to exclude
122
+
171
123
  **Output: `features-{platform}.json` Structure:**
172
124
  ```json
173
125
  {
@@ -175,7 +127,10 @@ node "scripts/generate-inventory.js" \
175
127
  "platformType": "web",
176
128
  "sourcePath": "frontend-web/src/views",
177
129
  "techStack": ["vue", "typescript"],
178
- "modules": ["system", "trade", "infra"],
130
+ "modules": [
131
+ { "name": "chat", "featureCount": 12 },
132
+ { "name": "image", "featureCount": 8 }
133
+ ],
179
134
  "totalFiles": 25,
180
135
  "analyzedCount": 0,
181
136
  "pendingCount": 25,
@@ -196,12 +151,10 @@ node "scripts/generate-inventory.js" \
196
151
  ```
197
152
 
198
153
  **Module Detection Rule:**
199
- - The `module` field is automatically extracted from each file's relative directory path
200
- - It uses the **first non-excluded directory level** as the module name
201
- - Example: `system/user/index.vue` module = `system`
202
- - Example: `components/Table.vue` (excluded dir)skipped by ExcludeDirs
203
- - Files at root level (no subdirectory) → module = `_root`
204
- - The top-level `modules` array lists all unique module names found
154
+ - When using `--entryDirsFile` mode (recommended), the `module` field for each feature is determined by matching the file's path against the entry directories defined in the entry-dirs JSON
155
+ - Each file is assigned to the module whose `entryDirs` path matches the file's relative directory
156
+ - The top-level `modules` array lists all modules with their feature counts
157
+ - Files not matching any entry directory module = `_root`
205
158
 
206
159
  **sourcePath Format:**
207
160
  - In both full-scan mode and entry-dirs mode, `sourcePath` is always a **project-root-relative path**
@@ -225,23 +178,23 @@ Feature Inventory Generated
225
178
 
226
179
  Platform Inventory Files:
227
180
  - Web Frontend:
228
- - Inventory File: speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/features-web.json
181
+ - Inventory File: {sync_state_bizs_dir}/features-web.json
229
182
  - Total Features: [N]
230
183
  - Status: Generated ✓
231
184
  - Mobile App:
232
- - Inventory File: speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/features-mobile.json
185
+ - Inventory File: {sync_state_bizs_dir}/features-mobile.json
233
186
  - Total Features: [N]
234
187
  - Status: Generated ✓
235
188
  - Backend API:
236
- - Inventory File: speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/features-api.json
189
+ - Inventory File: {sync_state_bizs_dir}/features-api.json
237
190
  - Total Features: [N]
238
191
  - Status: Generated ✓
239
192
 
240
193
  Final Output:
241
194
  - Platform Files:
242
- - speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/features-web.json
243
- - speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/features-mobile.json
244
- - speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/features-api.json
195
+ - {sync_state_bizs_dir}/features-web.json
196
+ - {sync_state_bizs_dir}/features-mobile.json
197
+ - {sync_state_bizs_dir}/features-api.json
245
198
  ```
246
199
 
247
200
  ## Checklist
@@ -251,6 +204,12 @@ Final Output:
251
204
  - [ ] Each platform has correct `platformName`, `platformType`, `techStack` configuration
252
205
  - [ ] Source directories located for all platforms
253
206
 
207
+ ### Entry Directory Identification
208
+ - [ ] Entry-dirs JSON files generated for all platforms
209
+ - [ ] Each platform has non-empty modules array
210
+ - [ ] Module names are business-meaningful (not technical terms like `config`, `util`, `controller`)
211
+ - [ ] Entry directory paths are correct and accessible
212
+
254
213
  ### Inventory Generation
255
214
  - [ ] **Inventory scripts executed**: Node.js script generated `features-{platform}.json` files
256
215
  - [ ] **Inventory files valid**: JSON structure correct, all features listed
@@ -258,7 +217,9 @@ Final Output:
258
217
  - [ ] **File paths correct**: All `sourcePath` and `documentPath` values are accurate (sourcePath MUST be project-root-relative path)
259
218
 
260
219
  ### Output Generation
261
- - [ ] All platform inventory files generated in `sync-state` directory
220
+ - [ ] All platform inventory files generated in `{sync_state_bizs_dir}` directory
262
221
  - [ ] Output path verified
263
222
  - [ ] Results reported
264
223
 
224
+ > **MANDATORY**: Use the provided absolute paths directly. DO NOT construct or derive paths yourself. DO NOT manually create JSON files.
225
+
@@ -5,7 +5,7 @@
5
5
  * Scans source directory for page files and generates a flat feature list with analysis status tracking.
6
6
  * All configuration is passed via parameters - the script does not infer anything.
7
7
  *
8
- * Usage: node generate-inventory.js --sourcePath <path> --outputFileName <name> --platformName <name> --platformType <type> --techStack <json> --fileExtensions <json> [--platformSubtype <subtype>] [--techIdentifier <identifier>] [--analysisMethod <method>] [--excludeDirs <json>] [--includeDataObjects <true|false>]
8
+ * Usage: node generate-inventory.js --sourcePath <path> --outputFileName <name> --platformName <name> --platformType <type> --techStack <json> --fileExtensions <json> [--platformSubtype <subtype>] [--techIdentifier <identifier>] [--analysisMethod <method>] [--excludeDirs <json>] [--includeDataObjects <true|false>] [--outputDir <dir>]
9
9
  * Array parameters (--techStack, --fileExtensions, --excludeDirs) accept both JSON format and comma-separated format.
10
10
  *
11
11
  * Whitelist Mode (using --entryDirsFile):
@@ -20,6 +20,11 @@
20
20
  * The suffixes are read from tech-stack-mappings.json (exclude_file_suffixes field).
21
21
  * Use --includeDataObjects true to include them.
22
22
  *
23
+ * Output Directory (--outputDir):
24
+ * By default, the script uses findProjectRoot() to locate the project root and outputs to:
25
+ * <projectRoot>/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/
26
+ * Use --outputDir to explicitly specify the output directory, bypassing findProjectRoot().
27
+ *
23
28
  * Example (full scan mode):
24
29
  * node generate-inventory.js \
25
30
  * --sourcePath "src/views" \
@@ -639,8 +644,14 @@ function main() {
639
644
 
640
645
  console.log(`Platform config: type=${platformType}, subtype=${platformSubtype}, framework=${framework}`);
641
646
 
642
- // Set output directory
643
- const outputDir = path.join(projectRoot, 'speccrew-workspace', 'knowledges', 'base', 'sync-state', 'knowledge-bizs');
647
+ // Set output directory (prefer --outputDir parameter, fallback to findProjectRoot)
648
+ let outputDir;
649
+ if (params.outputDir) {
650
+ outputDir = path.resolve(params.outputDir);
651
+ console.log(`Using outputDir from parameter: ${outputDir}`);
652
+ } else {
653
+ outputDir = path.join(projectRoot, 'speccrew-workspace', 'knowledges', 'base', 'sync-state', 'knowledge-bizs');
654
+ }
644
655
 
645
656
  // Generate features from entry dirs
646
657
  const success = generateFromEntryDirs(entryDirsData, platformConfig, projectRoot, outputDir);
@@ -735,13 +746,19 @@ function main() {
735
746
 
736
747
  // Validate required parameters
737
748
  if (!sourcePath || !outputFileName || !platformName || !platformType || !techStackStr || !fileExtensionsStr) {
738
- console.error('Usage: node generate-inventory.js --sourcePath <path> --outputFileName <name> --platformName <name> --platformType <type> --techStack <json> --fileExtensions <json> [--platformSubtype <subtype>] [--techIdentifier <identifier>] [--analysisMethod <method>] [--excludeDirs <json>] [--includeDataObjects <true|false>]');
749
+ console.error('Usage: node generate-inventory.js --sourcePath <path> --outputFileName <name> --platformName <name> --platformType <type> --techStack <json> --fileExtensions <json> [--platformSubtype <subtype>] [--techIdentifier <identifier>] [--analysisMethod <method>] [--excludeDirs <json>] [--includeDataObjects <true|false>] [--outputDir <dir>]');
739
750
  console.error('Example: node generate-inventory.js --sourcePath "src/views" --outputFileName "features-web.json" --platformName "Web Frontend" --platformType "web" --platformSubtype "vue" --techStack "vue,typescript" --fileExtensions ".vue,.ts" --analysisMethod "ui-based" --excludeDirs "components,composables,hooks,utils"');
740
751
  process.exit(1);
741
752
  }
742
753
 
743
- // Find sync-state directory
744
- const syncStateDir = path.join(projectRoot, 'speccrew-workspace', 'knowledges', 'base', 'sync-state', 'knowledge-bizs');
754
+ // Find sync-state directory (prefer --outputDir parameter, fallback to findProjectRoot)
755
+ let syncStateDir;
756
+ if (params.outputDir) {
757
+ syncStateDir = path.resolve(params.outputDir);
758
+ console.log(`Using outputDir from parameter: ${syncStateDir}`);
759
+ } else {
760
+ syncStateDir = path.join(projectRoot, 'speccrew-workspace', 'knowledges', 'base', 'sync-state', 'knowledge-bizs');
761
+ }
745
762
  const outputPath = path.join(syncStateDir, outputFileName);
746
763
 
747
764
  // Calculate relative source path from project root
@@ -29,7 +29,9 @@ Detect business knowledge base availability and completeness status. Scans the s
29
29
 
30
30
  | Variable | Type | Description | Required |
31
31
  |----------|------|-------------|----------|
32
- | `workspace_path` | string | Path to speccrew workspace (e.g., `speccrew-workspace`) | **Yes** |
32
+ | `workspace_path` | string | Absolute path to speccrew workspace (e.g., `speccrew-workspace`) | **Yes** |
33
+ | `sync_state_bizs_dir` | string | Absolute path to `knowledges/base/sync-state/knowledge-bizs/` directory | **Yes** |
34
+ | `configs_dir` | string | Absolute path to `docs/configs/` directory | **Yes** |
33
35
 
34
36
  ## Output JSON
35
37
 
@@ -72,7 +74,7 @@ flowchart TD
72
74
 
73
75
  Check if the system overview file exists:
74
76
 
75
- 1. Construct path: `{workspace_path}/knowledges/bizs/system-overview.md`
77
+ 1. Path: `{workspace_path}/knowledges/bizs/system-overview.md`
76
78
  2. Attempt to read the file
77
79
  3. Set `has_system_overview` = true if exists, false otherwise
78
80
  4. Set `system_overview_path` = path if exists, null otherwise
@@ -83,7 +85,7 @@ Check if the system overview file exists:
83
85
 
84
86
  Scan the sync-state directory for feature inventory files:
85
87
 
86
- 1. Construct path: `{workspace_path}/knowledges/base/sync-state/knowledge-bizs/`
88
+ 1. Use provided path: `{sync_state_bizs_dir}/`
87
89
  2. Glob pattern: `features-*.json`
88
90
  3. Collect all matching files into `features_files` array
89
91
  4. Set `has_features` = true if any files found
@@ -94,7 +96,7 @@ Scan the sync-state directory for feature inventory files:
94
96
 
95
97
  Scan for entry directory configuration files:
96
98
 
97
- 1. Use same sync-state path
99
+ 1. Use provided path: `{sync_state_bizs_dir}/`
98
100
  2. Glob pattern: `entry-dirs-*.json`
99
101
  3. Collect all matching files into `entry_dirs_files` array
100
102
  4. Set `has_entry_dirs` = true if any files found
@@ -137,6 +139,8 @@ Return the complete JSON output.
137
139
  3. **Graceful handling**: Return empty arrays if directories don't exist
138
140
  4. **Path format**: All returned paths should be relative to workspace_path
139
141
 
142
+ > **MANDATORY**: Use the provided absolute paths directly. DO NOT construct or derive paths yourself.
143
+
140
144
  ## Task Completion Report
141
145
 
142
146
  When the task is complete, report:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "speccrew",
3
- "version": "0.6.5",
3
+ "version": "0.6.8",
4
4
  "description": "Spec-Driven Development toolkit for AI-powered IDEs",
5
5
  "author": "charlesmu99",
6
6
  "repository": {
@@ -0,0 +1,134 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+
5
+ /**
6
+ * Path utility functions for speccrew workspace.
7
+ * All functions expect absolute paths as input.
8
+ */
9
+
10
+ /**
11
+ * Get the sync-state bizs directory path.
12
+ * @param {string} workspacePath - Absolute path to speccrew-workspace
13
+ * @returns {string} Absolute path to knowledges/base/sync-state/knowledge-bizs/
14
+ */
15
+ function getSyncStateBizsDir(workspacePath) {
16
+ return path.join(workspacePath, 'knowledges', 'base', 'sync-state', 'knowledge-bizs');
17
+ }
18
+
19
+ /**
20
+ * Get the sync-state techs directory path.
21
+ * @param {string} workspacePath - Absolute path to speccrew-workspace
22
+ * @returns {string} Absolute path to knowledges/base/sync-state/knowledge-techs/
23
+ */
24
+ function getSyncStateTechsDir(workspacePath) {
25
+ return path.join(workspacePath, 'knowledges', 'base', 'sync-state', 'knowledge-techs');
26
+ }
27
+
28
+ /**
29
+ * Get the features JSON file path for a platform.
30
+ * @param {string} syncStateBizsDir - Absolute path to sync-state/knowledge-bizs/
31
+ * @param {string} platformId - Platform identifier (e.g., 'backend-spring')
32
+ * @returns {string} Absolute path to features-{platformId}.json
33
+ */
34
+ function getFeaturesFilePath(syncStateBizsDir, platformId) {
35
+ return path.join(syncStateBizsDir, `features-${platformId}.json`);
36
+ }
37
+
38
+ /**
39
+ * Get the entry-dirs JSON file path for a platform.
40
+ * @param {string} syncStateBizsDir - Absolute path to sync-state/knowledge-bizs/
41
+ * @param {string} platformId - Platform identifier
42
+ * @returns {string} Absolute path to entry-dirs-{platformId}.json
43
+ */
44
+ function getEntryDirsFilePath(syncStateBizsDir, platformId) {
45
+ return path.join(syncStateBizsDir, `entry-dirs-${platformId}.json`);
46
+ }
47
+
48
+ /**
49
+ * Get the feature document path in bizs knowledge base.
50
+ * @param {string} workspacePath - Absolute path to speccrew-workspace
51
+ * @param {string} platformId - Platform identifier
52
+ * @param {string} moduleName - Business module name
53
+ * @param {string} fileName - Document file name (without extension)
54
+ * @returns {string} Absolute path to the feature document
55
+ */
56
+ function getFeatureDocPath(workspacePath, platformId, moduleName, fileName) {
57
+ return path.join(workspacePath, 'knowledges', 'bizs', platformId, moduleName, `${fileName}.md`);
58
+ }
59
+
60
+ /**
61
+ * Get the graph knowledge file path.
62
+ * @param {string} workspacePath - Absolute path to speccrew-workspace
63
+ * @param {string} platformId - Platform identifier
64
+ * @param {string} moduleName - Business module name
65
+ * @param {string} fileName - Graph file name (e.g., 'knowledge-graph.json')
66
+ * @returns {string} Absolute path to the graph file
67
+ */
68
+ function getGraphFilePath(workspacePath, platformId, moduleName, fileName) {
69
+ return path.join(workspacePath, 'knowledges', 'bizs', platformId, moduleName, fileName);
70
+ }
71
+
72
+ /**
73
+ * Generate a standardized marker file name for dispatch tracking.
74
+ * Format: {module}-{subpath}-{fileName}.{type}.json
75
+ * @param {string} moduleName - Business module name
76
+ * @param {string} subpath - Sub-path within module (use '-' separator, empty string if none)
77
+ * @param {string} fileName - Source file name (without extension)
78
+ * @param {string} [type='done'] - Marker type ('done', 'error', 'skip')
79
+ * @returns {string} Marker file name
80
+ */
81
+ function getMarkerFileName(moduleName, subpath, fileName, type = 'done') {
82
+ const subpathPart = subpath ? `-${subpath.replace(/[\/\\]/g, '-')}` : '';
83
+ return `${moduleName}${subpathPart}-${fileName}.${type}.json`;
84
+ }
85
+
86
+ /**
87
+ * Get the completed markers directory path.
88
+ * @param {string} syncStateBizsDir - Absolute path to sync-state/knowledge-bizs/
89
+ * @returns {string} Absolute path to completed/ directory
90
+ */
91
+ function getCompletedDir(syncStateBizsDir) {
92
+ return path.join(syncStateBizsDir, 'completed');
93
+ }
94
+
95
+ /**
96
+ * Get the iterations directory path.
97
+ * @param {string} workspacePath - Absolute path to speccrew-workspace
98
+ * @returns {string} Absolute path to iterations/
99
+ */
100
+ function getIterationsDir(workspacePath) {
101
+ return path.join(workspacePath, 'iterations');
102
+ }
103
+
104
+ /**
105
+ * Get the configs directory path.
106
+ * @param {string} workspacePath - Absolute path to speccrew-workspace
107
+ * @returns {string} Absolute path to docs/configs/
108
+ */
109
+ function getConfigsDir(workspacePath) {
110
+ return path.join(workspacePath, 'docs', 'configs');
111
+ }
112
+
113
+ /**
114
+ * Get the update-progress.js script path.
115
+ * @param {string} workspacePath - Absolute path to speccrew-workspace
116
+ * @returns {string} Absolute path to scripts/update-progress.js
117
+ */
118
+ function getUpdateProgressScript(workspacePath) {
119
+ return path.join(workspacePath, 'scripts', 'update-progress.js');
120
+ }
121
+
122
+ module.exports = {
123
+ getSyncStateBizsDir,
124
+ getSyncStateTechsDir,
125
+ getFeaturesFilePath,
126
+ getEntryDirsFilePath,
127
+ getFeatureDocPath,
128
+ getGraphFilePath,
129
+ getMarkerFileName,
130
+ getCompletedDir,
131
+ getIterationsDir,
132
+ getConfigsDir,
133
+ getUpdateProgressScript
134
+ };