speccrew 0.1.0
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 +142 -0
- package/.speccrew/agents/speccrew-product-manager.md +61 -0
- package/.speccrew/agents/speccrew-system-designer.md +200 -0
- package/.speccrew/agents/speccrew-system-developer.md +238 -0
- package/.speccrew/agents/speccrew-task-worker.md +80 -0
- package/.speccrew/agents/speccrew-team-leader.md +92 -0
- package/.speccrew/agents/speccrew-test-manager.md +313 -0
- package/.speccrew/skills/speccrew-create-agents/SKILL.md +98 -0
- package/.speccrew/skills/speccrew-create-agents/templates/agents/designer-agent.md +54 -0
- package/.speccrew/skills/speccrew-create-agents/templates/agents/dev-agent.md +79 -0
- package/.speccrew/skills/speccrew-create-agents/templates/agents/test-agent.md +80 -0
- package/.speccrew/skills/speccrew-dev-backend/SKILL.md +205 -0
- package/.speccrew/skills/speccrew-dev-backend/templates/TASK-RECORD-TEMPLATE.md +118 -0
- package/.speccrew/skills/speccrew-dev-desktop/SKILL.md +258 -0
- package/.speccrew/skills/speccrew-dev-desktop/templates/TASK-RECORD-TEMPLATE.md +161 -0
- package/.speccrew/skills/speccrew-dev-frontend/SKILL.md +202 -0
- package/.speccrew/skills/speccrew-dev-frontend/templates/TASK-RECORD-TEMPLATE.md +115 -0
- package/.speccrew/skills/speccrew-dev-mobile/SKILL.md +200 -0
- package/.speccrew/skills/speccrew-dev-mobile/templates/TASK-RECORD-TEMPLATE.md +125 -0
- package/.speccrew/skills/speccrew-fd-api-contract/SKILL.md +73 -0
- package/.speccrew/skills/speccrew-fd-api-contract/templates/API-CONTRACT-TEMPLATE.md +96 -0
- package/.speccrew/skills/speccrew-fd-feature-design/SKILL.md +395 -0
- package/.speccrew/skills/speccrew-fd-feature-design/templates/FEATURE-SPEC-TEMPLATE.md +387 -0
- package/.speccrew/skills/speccrew-get-timestamp/SKILL.md +80 -0
- package/.speccrew/skills/speccrew-get-timestamp/scripts/get-timestamp.js +35 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/SKILL.md +1116 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-FASTAPI.md +462 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-JAVA.md +480 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-NET.md +464 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE.md +480 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/MODULE-OVERVIEW-TEMPLATE.md +367 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/SKILL.md +667 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/STATUS-FORMATS.md +74 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/batch-orchestrator.js +176 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/get-next-batch.js +150 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/get-pending-features.js +106 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/mark-stale.js +249 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/process-batch-results.js +848 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/update-feature-status.js +226 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/SKILL.md +264 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/examples/features.json +34 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js +867 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/test-inventory.js +26 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/SKILL.md +165 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/apply-module-mapping.js +208 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/extract-module-summary.js +180 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/reindex-modules.js +358 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/SKILL.md +1055 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-DESKTOP.md +303 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-ELECTRON.md +327 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-MINIAPP.md +292 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-MOBILE.md +281 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI.md +324 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/SKILL.md +270 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/templates/COMPONENT-PATTERN-TEMPLATE.md +33 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/templates/LAYOUT-PATTERN-TEMPLATE.md +33 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/templates/PAGE-TYPE-TEMPLATE.md +33 -0
- package/.speccrew/skills/speccrew-knowledge-graph-query/SKILL.md +229 -0
- package/.speccrew/skills/speccrew-knowledge-graph-query/scripts/graph-query.js +549 -0
- package/.speccrew/skills/speccrew-knowledge-graph-write/SKILL.md +181 -0
- package/.speccrew/skills/speccrew-knowledge-graph-write/scripts/graph-write.js +651 -0
- package/.speccrew/skills/speccrew-knowledge-module-summarize/SKILL.md +305 -0
- package/.speccrew/skills/speccrew-knowledge-module-summarize/templates/MODULE-OVERVIEW-TEMPLATE.md +400 -0
- package/.speccrew/skills/speccrew-knowledge-system-summarize/SKILL.md +351 -0
- package/.speccrew/skills/speccrew-knowledge-system-summarize/templates/SYSTEM-OVERVIEW-TEMPLATE.md +294 -0
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/SKILL.md +683 -0
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/STATUS-FORMATS.md +550 -0
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/templates/techs-manifest-EXAMPLE.json +35 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/SKILL.md +1087 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/ARCHITECTURE-TEMPLATE.md +240 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/COLOR-SYSTEM-TEMPLATE.md +68 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/COMPONENT-LIBRARY-TEMPLATE.md +86 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-BUILD-TEMPLATE.md +466 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-DATA-TEMPLATE.md +432 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-DESIGN-TEMPLATE.md +1209 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-DEV-TEMPLATE.md +1433 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-SYSTEM-TEST-TEMPLATE.md +1052 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-UNIT-TEST-TEMPLATE.md +946 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/INDEX-TEMPLATE.md +29 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/PAGE-LAYOUTS-TEMPLATE.md +69 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/PAGE-TYPE-SUMMARY-TEMPLATE.md +74 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/TECH-STACK-TEMPLATE.md +232 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate-conventions/SKILL.md +628 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate-ui-style/SKILL.md +392 -0
- package/.speccrew/skills/speccrew-knowledge-techs-index/SKILL.md +489 -0
- package/.speccrew/skills/speccrew-knowledge-techs-index/templates/INDEX-TEMPLATE.md +243 -0
- package/.speccrew/skills/speccrew-knowledge-techs-init/SKILL.md +269 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/SKILL.md +562 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/BUSINESS-COMPONENTS-TEMPLATE.md +171 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/COMMON-COMPONENTS-TEMPLATE.md +177 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/COMPONENT-INDIVIDUAL-TEMPLATE.md +80 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/COMPONENT-LIBRARY-TEMPLATE.md +118 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/LAYOUT-INDIVIDUAL-TEMPLATE.md +97 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/LAYOUT-PATTERNS-TEMPLATE.md +208 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/NAVIGATION-PATTERNS-TEMPLATE.md +157 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/PAGE-TYPE-INDIVIDUAL-TEMPLATE.md +123 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/PAGE-TYPE-SUMMARY-TEMPLATE.md +58 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/SPACING-TEMPLATE.md +119 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/STYLE-SYSTEM-TEMPLATE.md +117 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/TYPOGRAPHY-TEMPLATE.md +107 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/UI-STYLE-GUIDE-TEMPLATE.md +171 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/SKILL.md +434 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/templates/BIZS-MODELING-TEMPLATE.md +332 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/templates/PRD-TEMPLATE.md +200 -0
- package/.speccrew/skills/speccrew-pm-requirement-assess/SKILL.md +195 -0
- package/.speccrew/skills/speccrew-project-diagnosis/SKILL.md +208 -0
- package/.speccrew/skills/speccrew-project-diagnosis/templates/DIAGNOSIS-REPORT-TEMPLATE.md +202 -0
- package/.speccrew/skills/speccrew-sd-backend/SKILL.md +188 -0
- package/.speccrew/skills/speccrew-sd-backend/templates/INDEX-TEMPLATE.md +85 -0
- package/.speccrew/skills/speccrew-sd-backend/templates/SD-BACKEND-TEMPLATE.md +269 -0
- package/.speccrew/skills/speccrew-sd-desktop/SKILL.md +192 -0
- package/.speccrew/skills/speccrew-sd-desktop/templates/INDEX-TEMPLATE.md +271 -0
- package/.speccrew/skills/speccrew-sd-desktop/templates/SD-DESKTOP-TEMPLATE.md +673 -0
- package/.speccrew/skills/speccrew-sd-frontend/SKILL.md +176 -0
- package/.speccrew/skills/speccrew-sd-frontend/templates/INDEX-TEMPLATE.md +184 -0
- package/.speccrew/skills/speccrew-sd-frontend/templates/SD-FRONTEND-TEMPLATE.md +382 -0
- package/.speccrew/skills/speccrew-sd-mobile/SKILL.md +189 -0
- package/.speccrew/skills/speccrew-sd-mobile/templates/INDEX-TEMPLATE.md +219 -0
- package/.speccrew/skills/speccrew-sd-mobile/templates/SD-MOBILE-TEMPLATE.md +534 -0
- package/.speccrew/skills/speccrew-test-case-design/SKILL.md +284 -0
- package/.speccrew/skills/speccrew-test-case-design/templates/TEST-CASE-DESIGN-TEMPLATE.md +263 -0
- package/.speccrew/skills/speccrew-test-code-gen/SKILL.md +313 -0
- package/.speccrew/skills/speccrew-test-code-gen/templates/TEST-CODE-PLAN-TEMPLATE.md +180 -0
- package/.speccrew/skills/speccrew-test-execute/SKILL.md +283 -0
- package/.speccrew/skills/speccrew-test-execute/templates/BUG-REPORT-TEMPLATE.md +50 -0
- package/.speccrew/skills/speccrew-test-execute/templates/TEST-REPORT-TEMPLATE.md +57 -0
- package/.speccrew/skills/speccrew-workflow-diagnose/SKILL.md +155 -0
- package/LICENSE +21 -0
- package/README.ar.md +318 -0
- package/README.en.md +318 -0
- package/README.es.md +318 -0
- package/README.md +340 -0
- package/bin/cli.js +62 -0
- package/lib/commands/doctor.js +138 -0
- package/lib/commands/init.js +231 -0
- package/lib/commands/list.js +114 -0
- package/lib/commands/uninstall.js +117 -0
- package/lib/commands/update.js +351 -0
- package/lib/ide-adapters.js +73 -0
- package/lib/utils.js +104 -0
- package/package.json +28 -0
- package/workspace-template/docs/configs/document-templates.json +667 -0
- package/workspace-template/docs/configs/platform-mapping.json +194 -0
- package/workspace-template/docs/configs/tech-stack-mappings.json +313 -0
- package/workspace-template/docs/configs/validation-rules.json +87 -0
- package/workspace-template/docs/rules/mermaid-rule.md +114 -0
- package/workspace-template/docs/solutions/Agent/346/212/200/350/203/275/345/256/232/344/271/211+/351/234/200/346/261/202/346/226/207/346/241/243+UML/344/275/277/347/224/250/346/250/241/346/235/277/357/274/210ISA-95/345/205/255/346/256/265/345/274/217/350/236/215/345/220/210/347/211/210/357/274/211.md +586 -0
- package/workspace-template/docs/solutions/agent-knowledge-map.md +238 -0
- package/workspace-template/docs/solutions/bizs-knowledge-pipeline.md +678 -0
- package/workspace-template/docs/solutions/harness.md +410 -0
- package/workspace-template/docs/solutions/knowledge-incremental-sync-spec.md +943 -0
- package/workspace-template/docs/solutions/techs-knowledge-pipeline.md +803 -0
- package/workspace-template/docs/solutions/workspace-structure.md +318 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const { spawnSync } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const scriptPath = path.join(__dirname, 'generate-inventory.js');
|
|
5
|
+
const sourcePath = 'd:/dev/speccrew/ruoyi-vue-pro/yudao-ui/yudao-ui-admin-vue3/src/views';
|
|
6
|
+
|
|
7
|
+
// Build arguments array - avoids shell escaping issues
|
|
8
|
+
const args = [
|
|
9
|
+
scriptPath,
|
|
10
|
+
'--sourcePath', sourcePath,
|
|
11
|
+
'--outputFileName', 'features-vue3.json',
|
|
12
|
+
'--platformName', 'Vue3 Admin',
|
|
13
|
+
'--platformType', 'web',
|
|
14
|
+
'--platformSubtype', 'vue3',
|
|
15
|
+
'--techStack', '["vue3","typescript"]',
|
|
16
|
+
'--fileExtensions', '[".vue",".ts"]',
|
|
17
|
+
'--analysisMethod', 'ui-based',
|
|
18
|
+
'--excludeDirs', '["components","composables","hooks","utils"]'
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
console.log('Testing generate-inventory.js...');
|
|
22
|
+
const result = spawnSync(process.execPath, args, { encoding: 'utf8', stdio: 'inherit' });
|
|
23
|
+
console.log('Exit code:', result.status);
|
|
24
|
+
if (result.error) {
|
|
25
|
+
console.error('Error:', result.error.message);
|
|
26
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: speccrew-knowledge-bizs-module-classify
|
|
3
|
+
description: Classify features into business modules by analyzing source code structure. Overrides directory-based module assignments from init-features with semantically meaningful business module groupings.
|
|
4
|
+
tools: None
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Bizs Module Classify
|
|
8
|
+
|
|
9
|
+
Reclassify features in `features-{platform}.json` files into proper business modules based on source code analysis.
|
|
10
|
+
|
|
11
|
+
## Language Adaptation
|
|
12
|
+
|
|
13
|
+
**CRITICAL**: All generated documents must match the user's language. Detect the language from the user's input and use it consistently.
|
|
14
|
+
|
|
15
|
+
- User writes in 中文 → Generate Chinese content, use `language: "zh"`
|
|
16
|
+
- User writes in English → Generate English content, use `language: "en"`
|
|
17
|
+
- User writes in other languages → Use appropriate language code
|
|
18
|
+
|
|
19
|
+
## Input
|
|
20
|
+
|
|
21
|
+
| Variable | Description | Default |
|
|
22
|
+
|----------|-------------|---------|
|
|
23
|
+
| `features_file` | Path to features-{platform}.json file (for reference only, Worker should NOT read it) | **REQUIRED** |
|
|
24
|
+
| `source_path` | Source code root path for context | **REQUIRED** |
|
|
25
|
+
| `module_summary` | JSON string containing module names, feature counts, and sample source paths (provided by dispatch via extract-module-summary.js) | **REQUIRED** |
|
|
26
|
+
| `language` | User's language code (e.g., "zh", "en") | **REQUIRED** |
|
|
27
|
+
|
|
28
|
+
## Output
|
|
29
|
+
|
|
30
|
+
Worker MUST return a JSON result containing the module mapping (NOT modify the features file directly):
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"status": "success|failed",
|
|
35
|
+
"message": "description of reclassification",
|
|
36
|
+
"mapping": {
|
|
37
|
+
"old_module_1": "new_module_1",
|
|
38
|
+
"old_module_2": "new_module_2"
|
|
39
|
+
},
|
|
40
|
+
"modules_reclassified": N
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**IMPORTANT**:
|
|
45
|
+
- Only include modules that need to change in the `mapping` object
|
|
46
|
+
- Modules that remain the same should NOT be listed
|
|
47
|
+
- The `mapping` will be passed to `apply-module-mapping.js` by the dispatch agent to batch-update the features file
|
|
48
|
+
- Worker MUST NOT modify the features file directly
|
|
49
|
+
|
|
50
|
+
## Workflow
|
|
51
|
+
|
|
52
|
+
> **CRITICAL CONSTRAINT**: This skill is a PURE REASONING task. DO NOT use any tools (Read, Write, Bash, terminal, etc.). DO NOT read files — the module summary is provided as input parameter `module_summary`. DO NOT modify any files — output a mapping JSON only.
|
|
53
|
+
|
|
54
|
+
### Step 1: Parse Module Summary
|
|
55
|
+
|
|
56
|
+
- Parse the `module_summary` JSON parameter (pre-processed by dispatch via extract-module-summary.js)
|
|
57
|
+
- Extract: module names, feature counts per module, and sample source paths
|
|
58
|
+
- Note: The summary contains compact data for LLM analysis, not the full features file
|
|
59
|
+
|
|
60
|
+
### Step 2: Analyze Module Semantics
|
|
61
|
+
|
|
62
|
+
- Analyze each module's `sampleSourcePaths` to identify business semantics
|
|
63
|
+
- Identify logical business domains based on path patterns:
|
|
64
|
+
|
|
65
|
+
**Path pattern analysis for web/mobile platforms:**
|
|
66
|
+
- Examine sample paths under views/pages directories
|
|
67
|
+
- Match directory naming patterns to business domains
|
|
68
|
+
- Cross-reference with common business module patterns
|
|
69
|
+
|
|
70
|
+
**Path pattern analysis for backend platforms:**
|
|
71
|
+
- Examine controller/module directory patterns
|
|
72
|
+
- Identify domain boundaries from package naming
|
|
73
|
+
|
|
74
|
+
- Build a **business module map**: a list of logical business domains with descriptions
|
|
75
|
+
- Example: `system` (system management), `trade` (trade/order), `bpm` (business process), `infra` (infrastructure)
|
|
76
|
+
|
|
77
|
+
### Step 3: Reclassify Modules
|
|
78
|
+
|
|
79
|
+
- For each module in the `module_summary`:
|
|
80
|
+
- Analyze sample source paths and directory context
|
|
81
|
+
- Match to the most appropriate business module from the module map
|
|
82
|
+
- Determine if the module name needs to change
|
|
83
|
+
|
|
84
|
+
**Naming rules:**
|
|
85
|
+
- Use lowercase for module names (e.g., `system`, `trade`, `bpm`)
|
|
86
|
+
- Use kebab-case for multi-word names (e.g., `order-management`)
|
|
87
|
+
- Module names must reflect business domains, NOT page types or UI components
|
|
88
|
+
|
|
89
|
+
**Classification rules:**
|
|
90
|
+
- Modules clearly belonging to a business domain → use that domain name
|
|
91
|
+
- Example: `system/user` paths → module: `system`
|
|
92
|
+
- Example: `trade/order` paths → module: `trade`
|
|
93
|
+
- Utility/common modules that don't belong to a specific domain → module: `_common`
|
|
94
|
+
- Example: `Error` module → module: `_common`
|
|
95
|
+
- Example: `Home` module → module: `_common`
|
|
96
|
+
- Example: `Redirect` module → module: `_common`
|
|
97
|
+
- Login/authentication modules → module: `system` (or domain-appropriate)
|
|
98
|
+
- Example: `Login` module → module: `system`
|
|
99
|
+
|
|
100
|
+
**Validation:**
|
|
101
|
+
- Every module in the mapping must have a valid business domain name
|
|
102
|
+
- No page-type module names should remain as values (Error, Login, Home, Profile, Redirect)
|
|
103
|
+
- All new module names are lowercase or kebab-case
|
|
104
|
+
|
|
105
|
+
### Step 4: Output Module Mapping
|
|
106
|
+
|
|
107
|
+
> **CRITICAL CONSTRAINT**: This skill produces a module mapping as output only. DO NOT modify the features JSON file. DO NOT create any temporary scripts or files. The dispatch agent will apply the mapping using the `apply-module-mapping.js` script.
|
|
108
|
+
|
|
109
|
+
Based on the reclassification analysis, construct and return the mapping result:
|
|
110
|
+
|
|
111
|
+
1. **Build the mapping object**: For each module that needs to change:
|
|
112
|
+
- Key: original module name (directory-based)
|
|
113
|
+
- Value: new business module name
|
|
114
|
+
- Example: `{ "Error": "_common", "Login": "system" }`
|
|
115
|
+
|
|
116
|
+
2. **Count reclassified features**: Calculate total number of features that will be affected by this mapping
|
|
117
|
+
|
|
118
|
+
3. **Return the JSON result**:
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"status": "success",
|
|
122
|
+
"message": "Reclassified 12 features from 5 directory modules to 4 business modules",
|
|
123
|
+
"mapping": {
|
|
124
|
+
"Error": "_common",
|
|
125
|
+
"Home": "_common",
|
|
126
|
+
"Login": "system",
|
|
127
|
+
"Profile": "_common",
|
|
128
|
+
"Redirect": "_common"
|
|
129
|
+
},
|
|
130
|
+
"modules_reclassified": 12
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Validation before returning**:
|
|
135
|
+
- Every mapping key-value pair has non-empty values
|
|
136
|
+
- No page-type module names remain as values (Error, Login, Home, Profile, Redirect should not appear as values)
|
|
137
|
+
- All new module names are lowercase or kebab-case
|
|
138
|
+
- `modules_reclassified` count is accurate
|
|
139
|
+
|
|
140
|
+
## Return
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"status": "success",
|
|
145
|
+
"message": "Reclassified 12 features from 5 directory modules to 4 business modules",
|
|
146
|
+
"mapping": {
|
|
147
|
+
"Error": "_common",
|
|
148
|
+
"Home": "_common",
|
|
149
|
+
"Login": "system",
|
|
150
|
+
"Profile": "_common",
|
|
151
|
+
"Redirect": "_common"
|
|
152
|
+
},
|
|
153
|
+
"modules_reclassified": 12
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Checklist
|
|
158
|
+
|
|
159
|
+
- [ ] All modules from `module_summary` are analyzed
|
|
160
|
+
- [ ] No page-type module names remain in mapping values (Error, Login, Home, Profile, Redirect)
|
|
161
|
+
- [ ] All new module names in mapping are lowercase or kebab-case
|
|
162
|
+
- [ ] Only modules that need to change are included in the `mapping` object
|
|
163
|
+
- [ ] `modules_reclassified` count is accurate
|
|
164
|
+
- [ ] Worker did NOT use any tools (Read, Write, Bash, terminal)
|
|
165
|
+
- [ ] Worker did NOT modify any files directly
|
package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/apply-module-mapping.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Apply Module Mapping Script
|
|
5
|
+
*
|
|
6
|
+
* Updates features JSON file based on module mapping.
|
|
7
|
+
* Supports both JSON and key:value comma-separated format for mapping parameter.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parse command line arguments
|
|
15
|
+
*/
|
|
16
|
+
function parseArgs() {
|
|
17
|
+
const args = {};
|
|
18
|
+
const argv = process.argv.slice(2);
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < argv.length; i++) {
|
|
21
|
+
const arg = argv[i];
|
|
22
|
+
if (arg.startsWith('--')) {
|
|
23
|
+
const key = arg.slice(2);
|
|
24
|
+
const value = argv[i + 1] && !argv[i + 1].startsWith('--') ? argv[i + 1] : '';
|
|
25
|
+
args[key] = value;
|
|
26
|
+
if (value) i++;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return args;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Parse mapping parameter - supports both JSON and key:value comma-separated format
|
|
35
|
+
* JSON: '{"auth":"authentication","util":"_common"}'
|
|
36
|
+
* Key-value: "auth:authentication,util:_common" (recommended for PowerShell)
|
|
37
|
+
*/
|
|
38
|
+
function parseMapping(value) {
|
|
39
|
+
if (!value) return {};
|
|
40
|
+
|
|
41
|
+
const trimmed = value.trim();
|
|
42
|
+
|
|
43
|
+
// Try JSON format first
|
|
44
|
+
if (trimmed.startsWith('{')) {
|
|
45
|
+
try {
|
|
46
|
+
return JSON.parse(trimmed);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
// JSON parse failed, fall through to key:value parsing
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Parse comma-separated key:value pairs
|
|
53
|
+
const result = {};
|
|
54
|
+
trimmed.split(',').forEach(pair => {
|
|
55
|
+
const separatorIndex = pair.indexOf(':');
|
|
56
|
+
if (separatorIndex > 0) {
|
|
57
|
+
const key = pair.slice(0, separatorIndex).trim();
|
|
58
|
+
const val = pair.slice(separatorIndex + 1).trim();
|
|
59
|
+
if (key && val) {
|
|
60
|
+
result[key] = val;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Output error and exit
|
|
70
|
+
*/
|
|
71
|
+
function exitError(message) {
|
|
72
|
+
console.error(JSON.stringify({
|
|
73
|
+
status: 'error',
|
|
74
|
+
message: message
|
|
75
|
+
}, null, 2));
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Main function
|
|
81
|
+
*/
|
|
82
|
+
function main() {
|
|
83
|
+
const args = parseArgs();
|
|
84
|
+
|
|
85
|
+
// Validate required parameters
|
|
86
|
+
if (!args.featuresFile) {
|
|
87
|
+
exitError('Missing required parameter: --featuresFile');
|
|
88
|
+
}
|
|
89
|
+
if (!args.mapping) {
|
|
90
|
+
exitError('Missing required parameter: --mapping');
|
|
91
|
+
}
|
|
92
|
+
if (!args.platformId) {
|
|
93
|
+
exitError('Missing required parameter: --platformId');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const featuresFile = args.featuresFile;
|
|
97
|
+
const platformId = args.platformId;
|
|
98
|
+
|
|
99
|
+
// Parse mapping
|
|
100
|
+
const mapping = parseMapping(args.mapping);
|
|
101
|
+
if (Object.keys(mapping).length === 0) {
|
|
102
|
+
exitError('Failed to parse mapping parameter. Expected JSON or key:value comma-separated format.');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Read features file
|
|
106
|
+
let featuresData;
|
|
107
|
+
try {
|
|
108
|
+
const content = fs.readFileSync(featuresFile, 'utf-8');
|
|
109
|
+
featuresData = JSON.parse(content);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
if (e.code === 'ENOENT') {
|
|
112
|
+
exitError(`Features file not found: ${featuresFile}`);
|
|
113
|
+
} else if (e instanceof SyntaxError) {
|
|
114
|
+
exitError(`Invalid JSON in features file: ${e.message}`);
|
|
115
|
+
} else {
|
|
116
|
+
exitError(`Failed to read features file: ${e.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Validate features data structure
|
|
121
|
+
if (!featuresData || typeof featuresData !== 'object') {
|
|
122
|
+
exitError('Invalid features data: expected object');
|
|
123
|
+
}
|
|
124
|
+
if (!Array.isArray(featuresData.features)) {
|
|
125
|
+
exitError('Invalid features data: missing or invalid features array');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Store original modules for comparison
|
|
129
|
+
const modulesBefore = [...(featuresData.modules || [])];
|
|
130
|
+
|
|
131
|
+
// Track reclassification count
|
|
132
|
+
let reclassifiedCount = 0;
|
|
133
|
+
const reclassifiedModules = new Set();
|
|
134
|
+
|
|
135
|
+
// Process all features
|
|
136
|
+
const updatedFeatures = featuresData.features.map(feature => {
|
|
137
|
+
const oldModule = feature.module;
|
|
138
|
+
|
|
139
|
+
// Check if this feature's module needs to be updated
|
|
140
|
+
if (oldModule && mapping.hasOwnProperty(oldModule)) {
|
|
141
|
+
const newModule = mapping[oldModule];
|
|
142
|
+
reclassifiedCount++;
|
|
143
|
+
reclassifiedModules.add(oldModule);
|
|
144
|
+
|
|
145
|
+
// Rebuild documentPath(使用 fileName 而非 feature.id,避免文件名过长)
|
|
146
|
+
const newDocumentPath = `speccrew-workspace/knowledges/bizs/${platformId}/${newModule}/${feature.fileName}.md`;
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
...feature,
|
|
150
|
+
module: newModule,
|
|
151
|
+
documentPath: newDocumentPath
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return feature;
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Rebuild modules array (unique and sorted)
|
|
159
|
+
const allModules = new Set();
|
|
160
|
+
updatedFeatures.forEach(feature => {
|
|
161
|
+
if (feature.module) {
|
|
162
|
+
allModules.add(feature.module);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
const modulesAfter = Array.from(allModules).sort();
|
|
166
|
+
|
|
167
|
+
// Calculate analyzed and pending counts
|
|
168
|
+
const analyzedCount = updatedFeatures.filter(f => f.analyzed === true).length;
|
|
169
|
+
const pendingCount = updatedFeatures.length - analyzedCount;
|
|
170
|
+
|
|
171
|
+
// Build updated data
|
|
172
|
+
const updatedData = {
|
|
173
|
+
...featuresData,
|
|
174
|
+
features: updatedFeatures,
|
|
175
|
+
modules: modulesAfter,
|
|
176
|
+
analyzedCount: analyzedCount,
|
|
177
|
+
pendingCount: pendingCount,
|
|
178
|
+
updatedAt: new Date().toISOString()
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// Preserve createdAt if it exists
|
|
182
|
+
if (!updatedData.createdAt) {
|
|
183
|
+
updatedData.createdAt = featuresData.updatedAt || new Date().toISOString();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Write back to file
|
|
187
|
+
try {
|
|
188
|
+
fs.writeFileSync(featuresFile, JSON.stringify(updatedData, null, 2), 'utf-8');
|
|
189
|
+
} catch (e) {
|
|
190
|
+
exitError(`Failed to write features file: ${e.message}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Output result
|
|
194
|
+
const result = {
|
|
195
|
+
status: 'success',
|
|
196
|
+
modules_before: modulesBefore,
|
|
197
|
+
modules_after: modulesAfter,
|
|
198
|
+
reclassified_count: reclassifiedCount,
|
|
199
|
+
total_features: updatedFeatures.length,
|
|
200
|
+
mapping_applied: mapping
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
console.log(JSON.stringify(result, null, 2));
|
|
204
|
+
process.exit(0);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Run main function
|
|
208
|
+
main();
|
package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/extract-module-summary.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extract Module Summary Script
|
|
5
|
+
*
|
|
6
|
+
* Extracts compact module summary from features JSON for LLM inference.
|
|
7
|
+
* Run by Dispatch before delegating to Worker.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parse command line arguments
|
|
15
|
+
*/
|
|
16
|
+
function parseArgs() {
|
|
17
|
+
const args = {};
|
|
18
|
+
const argv = process.argv.slice(2);
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < argv.length; i++) {
|
|
21
|
+
const arg = argv[i];
|
|
22
|
+
if (arg.startsWith('--')) {
|
|
23
|
+
const key = arg.slice(2);
|
|
24
|
+
const value = argv[i + 1] && !argv[i + 1].startsWith('--') ? argv[i + 1] : '';
|
|
25
|
+
args[key] = value;
|
|
26
|
+
if (value) i++;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return args;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Output error to stderr and exit with code 1
|
|
35
|
+
*/
|
|
36
|
+
function exitError(message) {
|
|
37
|
+
console.error(message);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get the technology layer from a source path
|
|
43
|
+
* Returns: 'controller', 'service', 'dal', 'api', 'manager', 'convert', or 'other'
|
|
44
|
+
*/
|
|
45
|
+
function getTechLayer(sourcePath) {
|
|
46
|
+
if (!sourcePath) return 'other';
|
|
47
|
+
|
|
48
|
+
const lowerPath = sourcePath.toLowerCase();
|
|
49
|
+
|
|
50
|
+
// Check for common tech layer directories
|
|
51
|
+
if (lowerPath.includes('/controller/') || lowerPath.includes('\\controller\\')) return 'controller';
|
|
52
|
+
if (lowerPath.includes('/service/') || lowerPath.includes('\\service\\')) return 'service';
|
|
53
|
+
if (lowerPath.includes('/dal/') || lowerPath.includes('\\dal\\')) return 'dal';
|
|
54
|
+
if (lowerPath.includes('/api/') || lowerPath.includes('\\api\\')) return 'api';
|
|
55
|
+
if (lowerPath.includes('/manager/') || lowerPath.includes('\\manager\\')) return 'manager';
|
|
56
|
+
if (lowerPath.includes('/convert/') || lowerPath.includes('\\convert\\')) return 'convert';
|
|
57
|
+
|
|
58
|
+
return 'other';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Select representative sample paths for a module
|
|
63
|
+
* Prioritizes different tech layers (controller, service, dal, etc.)
|
|
64
|
+
* Returns max 3 paths
|
|
65
|
+
*/
|
|
66
|
+
function selectSamplePaths(features) {
|
|
67
|
+
// Group paths by tech layer
|
|
68
|
+
const layers = {
|
|
69
|
+
controller: [],
|
|
70
|
+
service: [],
|
|
71
|
+
dal: [],
|
|
72
|
+
api: [],
|
|
73
|
+
manager: [],
|
|
74
|
+
convert: [],
|
|
75
|
+
other: []
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
for (const feature of features) {
|
|
79
|
+
const sourcePath = feature.sourcePath;
|
|
80
|
+
if (!sourcePath) continue;
|
|
81
|
+
|
|
82
|
+
const layer = getTechLayer(sourcePath);
|
|
83
|
+
layers[layer].push(sourcePath);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Select up to 3 samples, prioritizing different layers
|
|
87
|
+
// Priority: controller > service > dal > api > manager > convert > other
|
|
88
|
+
const priorityOrder = ['controller', 'service', 'dal', 'api', 'manager', 'convert', 'other'];
|
|
89
|
+
const selected = [];
|
|
90
|
+
|
|
91
|
+
for (const layer of priorityOrder) {
|
|
92
|
+
if (layers[layer].length > 0 && selected.length < 3) {
|
|
93
|
+
// Take the first path from this layer
|
|
94
|
+
selected.push(layers[layer][0]);
|
|
95
|
+
}
|
|
96
|
+
if (selected.length >= 3) break;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return selected;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Main function
|
|
104
|
+
*/
|
|
105
|
+
function main() {
|
|
106
|
+
const args = parseArgs();
|
|
107
|
+
|
|
108
|
+
// Validate required parameter
|
|
109
|
+
if (!args.featuresFile) {
|
|
110
|
+
exitError('Error: Missing required parameter --featuresFile');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const featuresFile = args.featuresFile;
|
|
114
|
+
|
|
115
|
+
// Read features file
|
|
116
|
+
let featuresData;
|
|
117
|
+
try {
|
|
118
|
+
const content = fs.readFileSync(featuresFile, 'utf-8');
|
|
119
|
+
featuresData = JSON.parse(content);
|
|
120
|
+
} catch (e) {
|
|
121
|
+
if (e.code === 'ENOENT') {
|
|
122
|
+
exitError(`Error: Features file not found: ${featuresFile}`);
|
|
123
|
+
} else if (e instanceof SyntaxError) {
|
|
124
|
+
exitError(`Error: Invalid JSON in features file: ${e.message}`);
|
|
125
|
+
} else {
|
|
126
|
+
exitError(`Error: Failed to read features file: ${e.message}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Validate features data structure
|
|
131
|
+
if (!featuresData || typeof featuresData !== 'object') {
|
|
132
|
+
exitError('Error: Invalid features data: expected object');
|
|
133
|
+
}
|
|
134
|
+
if (!Array.isArray(featuresData.features)) {
|
|
135
|
+
exitError('Error: Invalid features data: missing or invalid features array');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Extract platform info from features data
|
|
139
|
+
const platformType = featuresData.platformType || 'unknown';
|
|
140
|
+
const platformSubtype = featuresData.platformSubtype || 'unknown';
|
|
141
|
+
|
|
142
|
+
// Group features by module
|
|
143
|
+
const moduleGroups = {};
|
|
144
|
+
for (const feature of featuresData.features) {
|
|
145
|
+
const moduleName = feature.module || '_unclassified';
|
|
146
|
+
if (!moduleGroups[moduleName]) {
|
|
147
|
+
moduleGroups[moduleName] = [];
|
|
148
|
+
}
|
|
149
|
+
moduleGroups[moduleName].push(feature);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Build module summaries
|
|
153
|
+
const modules = [];
|
|
154
|
+
for (const [moduleName, features] of Object.entries(moduleGroups)) {
|
|
155
|
+
const summary = {
|
|
156
|
+
name: moduleName,
|
|
157
|
+
featureCount: features.length,
|
|
158
|
+
sampleSourcePaths: selectSamplePaths(features)
|
|
159
|
+
};
|
|
160
|
+
modules.push(summary);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Sort by featureCount descending
|
|
164
|
+
modules.sort((a, b) => b.featureCount - a.featureCount);
|
|
165
|
+
|
|
166
|
+
// Build output
|
|
167
|
+
const output = {
|
|
168
|
+
platformType: platformType,
|
|
169
|
+
platformSubtype: platformSubtype,
|
|
170
|
+
totalFeatures: featuresData.features.length,
|
|
171
|
+
modules: modules
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// Output JSON to stdout
|
|
175
|
+
console.log(JSON.stringify(output, null, 2));
|
|
176
|
+
process.exit(0);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Run main function
|
|
180
|
+
main();
|