speccrew 0.1.12 → 0.2.1
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 +120 -0
- package/.speccrew/agents/speccrew-product-manager.md +54 -0
- package/.speccrew/agents/speccrew-system-designer.md +150 -14
- package/.speccrew/agents/speccrew-system-developer.md +309 -37
- package/.speccrew/agents/speccrew-task-worker.md +43 -0
- package/.speccrew/agents/speccrew-team-leader.md +108 -11
- package/.speccrew/agents/speccrew-test-manager.md +278 -0
- package/.speccrew/skills/speccrew-dev-backend/SKILL.md +44 -0
- package/.speccrew/skills/speccrew-dev-desktop/SKILL.md +44 -0
- package/.speccrew/skills/speccrew-dev-frontend/SKILL.md +44 -0
- package/.speccrew/skills/speccrew-dev-mobile/SKILL.md +44 -0
- package/.speccrew/skills/speccrew-fd-api-contract/SKILL.md +70 -0
- package/.speccrew/skills/speccrew-fd-feature-design/SKILL.md +158 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/SKILL.md +59 -29
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/SKILL.md +37 -15
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/STATUS-FORMATS.md +29 -4
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/process-batch-results.js +71 -4
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/SKILL.md +60 -30
- package/.speccrew/skills/speccrew-pm-requirement-analysis/SKILL.md +65 -0
- package/.speccrew/skills/speccrew-sd-backend/SKILL.md +38 -0
- package/.speccrew/skills/speccrew-sd-desktop/SKILL.md +38 -0
- package/.speccrew/skills/speccrew-sd-frontend/SKILL.md +38 -0
- package/.speccrew/skills/speccrew-sd-mobile/SKILL.md +38 -0
- package/.speccrew/skills/speccrew-test-case-design/SKILL.md +33 -0
- package/.speccrew/skills/speccrew-test-code-gen/SKILL.md +34 -0
- package/.speccrew/skills/speccrew-test-execute/SKILL.md +34 -0
- package/README.ar.md +70 -3
- package/README.bn.md +52 -0
- package/README.bs.md +70 -3
- package/README.da.md +70 -3
- package/README.de.md +70 -3
- package/README.el.md +52 -0
- package/README.en.md +69 -2
- package/README.es.md +70 -3
- package/README.fr.md +70 -3
- package/README.it.md +70 -3
- package/README.ja.md +70 -3
- package/README.ko.md +70 -3
- package/README.md +69 -2
- package/README.no.md +70 -3
- package/README.pl.md +70 -3
- package/README.pt-BR.md +70 -3
- package/README.ru.md +70 -3
- package/README.th.md +69 -2
- package/README.tr.md +69 -2
- package/README.uk.md +69 -2
- package/README.vi.md +52 -0
- package/README.zh-TW.md +70 -3
- package/docs/GETTING-STARTED.ar.md +78 -4
- package/docs/GETTING-STARTED.bn.md +78 -4
- package/docs/GETTING-STARTED.bs.md +78 -4
- package/docs/GETTING-STARTED.da.md +78 -4
- package/docs/GETTING-STARTED.de.md +78 -4
- package/docs/GETTING-STARTED.el.md +78 -4
- package/docs/GETTING-STARTED.en.md +78 -4
- package/docs/GETTING-STARTED.es.md +78 -4
- package/docs/GETTING-STARTED.fr.md +78 -4
- package/docs/GETTING-STARTED.it.md +78 -4
- package/docs/GETTING-STARTED.ja.md +79 -5
- package/docs/GETTING-STARTED.ko.md +79 -5
- package/docs/GETTING-STARTED.md +78 -4
- package/docs/GETTING-STARTED.no.md +78 -4
- package/docs/GETTING-STARTED.pl.md +78 -4
- package/docs/GETTING-STARTED.pt-BR.md +78 -4
- package/docs/GETTING-STARTED.ru.md +78 -4
- package/docs/GETTING-STARTED.th.md +79 -5
- package/docs/GETTING-STARTED.tr.md +78 -4
- package/docs/GETTING-STARTED.uk.md +78 -4
- package/docs/GETTING-STARTED.vi.md +79 -5
- package/docs/GETTING-STARTED.zh-TW.md +79 -5
- package/package.json +1 -1
- package/.speccrew/skills/speccrew-create-agents/SKILL.md +0 -98
- package/.speccrew/skills/speccrew-create-agents/templates/agents/designer-agent.md +0 -54
- package/.speccrew/skills/speccrew-create-agents/templates/agents/dev-agent.md +0 -79
- package/.speccrew/skills/speccrew-create-agents/templates/agents/test-agent.md +0 -80
- package/.speccrew/skills/speccrew-project-diagnosis/SKILL.md +0 -233
- package/.speccrew/skills/speccrew-project-diagnosis/templates/DIAGNOSIS-REPORT-TEMPLATE.md +0 -202
- package/.speccrew/skills/speccrew-workflow-diagnose/SKILL.md +0 -155
- 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 +0 -586
- package/workspace-template/docs/solutions/harness.md +0 -410
|
@@ -98,6 +98,38 @@ For each function, identify:
|
|
|
98
98
|
|
|
99
99
|
Ask: "Here is the function breakdown with [EXISTING]/[MODIFIED]/[NEW] markers. Does this align with your understanding of the requirements?"
|
|
100
100
|
|
|
101
|
+
### Checkpoint A Progress Update
|
|
102
|
+
|
|
103
|
+
After user confirms the function breakdown:
|
|
104
|
+
|
|
105
|
+
1. **Write/Update `.checkpoints.json`**:
|
|
106
|
+
- Path: `speccrew-workspace/iterations/{iteration-id}/02.feature-design/.checkpoints.json`
|
|
107
|
+
- Content:
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"stage": "02_feature_design",
|
|
111
|
+
"checkpoints": {
|
|
112
|
+
"function_decomposition": {
|
|
113
|
+
"passed": true,
|
|
114
|
+
"confirmed_at": "{current_timestamp}",
|
|
115
|
+
"description": "Function decomposition confirmed"
|
|
116
|
+
},
|
|
117
|
+
"feature_spec_review": {
|
|
118
|
+
"passed": false,
|
|
119
|
+
"confirmed_at": null
|
|
120
|
+
},
|
|
121
|
+
"api_contract_joint": {
|
|
122
|
+
"passed": false,
|
|
123
|
+
"confirmed_at": null
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
2. If the file already exists, merge with existing content (preserve other checkpoints)
|
|
130
|
+
|
|
131
|
+
3. Log: "✅ Checkpoint A (function_decomposition) passed and recorded"
|
|
132
|
+
|
|
101
133
|
## Step 4: Determine Output Structure
|
|
102
134
|
|
|
103
135
|
Based on PRD structure, determine feature spec output structure:
|
|
@@ -398,6 +430,38 @@ Data Entities: {count} new, {count} modified
|
|
|
398
430
|
4. Are all business rules and constraints captured?
|
|
399
431
|
5. **[Master-Sub]** Is the module breakdown appropriate?
|
|
400
432
|
|
|
433
|
+
### Checkpoint B Progress Update
|
|
434
|
+
|
|
435
|
+
After user confirms the complete feature spec:
|
|
436
|
+
|
|
437
|
+
1. **Update `.checkpoints.json`**:
|
|
438
|
+
- Path: `speccrew-workspace/iterations/{iteration-id}/02.feature-design/.checkpoints.json`
|
|
439
|
+
- Update content:
|
|
440
|
+
```json
|
|
441
|
+
{
|
|
442
|
+
"stage": "02_feature_design",
|
|
443
|
+
"checkpoints": {
|
|
444
|
+
"function_decomposition": {
|
|
445
|
+
"passed": true,
|
|
446
|
+
"confirmed_at": "..."
|
|
447
|
+
},
|
|
448
|
+
"feature_spec_review": {
|
|
449
|
+
"passed": true,
|
|
450
|
+
"confirmed_at": "{current_timestamp}",
|
|
451
|
+
"description": "Feature specification confirmed"
|
|
452
|
+
},
|
|
453
|
+
"api_contract_joint": {
|
|
454
|
+
"passed": false,
|
|
455
|
+
"confirmed_at": null
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
2. Preserve `function_decomposition` checkpoint status when updating
|
|
462
|
+
|
|
463
|
+
3. Log: "✅ Checkpoint B (feature_spec_review) passed and recorded"
|
|
464
|
+
|
|
401
465
|
## Step 10: Write Files
|
|
402
466
|
|
|
403
467
|
### 10.1 Determine Output Paths
|
|
@@ -473,6 +537,100 @@ Key requirements:
|
|
|
473
537
|
|
|
474
538
|
After feature spec documents are complete, call `speccrew-fd-api-contract/SKILL.md` to generate API contract document.
|
|
475
539
|
|
|
540
|
+
### 10.5 Multi-Platform Dispatch Progress Management
|
|
541
|
+
|
|
542
|
+
**For multi-platform feature design (multiple frontend platforms):**
|
|
543
|
+
|
|
544
|
+
#### 10.5.1 Pre-Dispatch: Check Resume State
|
|
545
|
+
|
|
546
|
+
Before dispatching to multiple platforms:
|
|
547
|
+
|
|
548
|
+
1. **Read existing `DISPATCH-PROGRESS.json`**:
|
|
549
|
+
- Path: `speccrew-workspace/iterations/{iteration-id}/02.feature-design/DISPATCH-PROGRESS.json`
|
|
550
|
+
- If exists, analyze task status:
|
|
551
|
+
```json
|
|
552
|
+
{
|
|
553
|
+
"stage": "02_feature_design",
|
|
554
|
+
"total": 3,
|
|
555
|
+
"completed": 2,
|
|
556
|
+
"failed": 0,
|
|
557
|
+
"pending": 1,
|
|
558
|
+
"tasks": [
|
|
559
|
+
{
|
|
560
|
+
"id": "fd-web-vue",
|
|
561
|
+
"platform": "web-vue",
|
|
562
|
+
"skill": "speccrew-fd-feature-design",
|
|
563
|
+
"status": "completed",
|
|
564
|
+
"started_at": "...",
|
|
565
|
+
"completed_at": "...",
|
|
566
|
+
"output": "02.feature-design/[feature]-web-vue-feature-spec.md",
|
|
567
|
+
"error": null
|
|
568
|
+
}
|
|
569
|
+
]
|
|
570
|
+
}
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
2. **Resume Strategy**:
|
|
574
|
+
- Skip tasks with `status == "completed"`
|
|
575
|
+
- Re-execute tasks with `status == "failed"`
|
|
576
|
+
- Execute tasks with `status == "pending"`
|
|
577
|
+
|
|
578
|
+
#### 10.5.2 Initialize/Update Dispatch Progress
|
|
579
|
+
|
|
580
|
+
Create or update `DISPATCH-PROGRESS.json` before starting dispatch:
|
|
581
|
+
|
|
582
|
+
```json
|
|
583
|
+
{
|
|
584
|
+
"stage": "02_feature_design",
|
|
585
|
+
"total": {count},
|
|
586
|
+
"completed": 0,
|
|
587
|
+
"failed": 0,
|
|
588
|
+
"pending": {count},
|
|
589
|
+
"tasks": [
|
|
590
|
+
{
|
|
591
|
+
"id": "fd-{platform}",
|
|
592
|
+
"platform": "{platform}",
|
|
593
|
+
"skill": "speccrew-fd-feature-design",
|
|
594
|
+
"status": "pending",
|
|
595
|
+
"started_at": null,
|
|
596
|
+
"completed_at": null,
|
|
597
|
+
"output": null,
|
|
598
|
+
"error": null
|
|
599
|
+
}
|
|
600
|
+
]
|
|
601
|
+
}
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
#### 10.5.3 Update Task Status on Completion
|
|
605
|
+
|
|
606
|
+
After each worker completes:
|
|
607
|
+
|
|
608
|
+
1. **Read current `DISPATCH-PROGRESS.json`**
|
|
609
|
+
|
|
610
|
+
2. **Update the corresponding task entry**:
|
|
611
|
+
- On success:
|
|
612
|
+
```json
|
|
613
|
+
{
|
|
614
|
+
"status": "completed",
|
|
615
|
+
"completed_at": "{timestamp}",
|
|
616
|
+
"output": "{output_file_path}"
|
|
617
|
+
}
|
|
618
|
+
```
|
|
619
|
+
- On failure:
|
|
620
|
+
```json
|
|
621
|
+
{
|
|
622
|
+
"status": "failed",
|
|
623
|
+
"completed_at": "{timestamp}",
|
|
624
|
+
"error": "{error_message}"
|
|
625
|
+
}
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
3. **Update summary counters** (`completed`, `failed`, `pending`)
|
|
629
|
+
|
|
630
|
+
4. **Write updated `DISPATCH-PROGRESS.json`**
|
|
631
|
+
|
|
632
|
+
5. Log progress: "📊 Dispatch progress: {completed}/{total} completed, {failed} failed, {pending} pending"
|
|
633
|
+
|
|
476
634
|
# Key Rules
|
|
477
635
|
|
|
478
636
|
| Rule | Description |
|
|
@@ -76,8 +76,8 @@ This skill operates in **strict sequential execution mode**:
|
|
|
76
76
|
|
|
77
77
|
**Generated Files:**
|
|
78
78
|
1. `{{documentPath}}` - Controller documentation file
|
|
79
|
-
2. `{{completed_dir}}/{{fileName}
|
|
80
|
-
3. `{{completed_dir}}/{{fileName}
|
|
79
|
+
2. `{{completed_dir}}/{module}-{subpath}-{fileName}.done.json` - Completion status marker
|
|
80
|
+
3. `{{completed_dir}}/{module}-{subpath}-{fileName}.graph.json` - Graph data marker
|
|
81
81
|
|
|
82
82
|
**Return Value:**
|
|
83
83
|
```json
|
|
@@ -856,7 +856,7 @@ Or in case of failure:
|
|
|
856
856
|
> **ASSUMPTION**: The `completed_dir` directory already exists (pre-created by dispatch Stage 2). If write fails, report error — do NOT attempt to create directories.
|
|
857
857
|
|
|
858
858
|
### Pre-write Checklist (VERIFY before writing each file):
|
|
859
|
-
- [ ] Filename follows `{fileName}` pattern (
|
|
859
|
+
- [ ] Filename follows `{module}-{subpath}-{fileName}` pattern (see naming convention below)
|
|
860
860
|
- [ ] File content is valid JSON (not empty)
|
|
861
861
|
- [ ] All required fields are present and non-empty
|
|
862
862
|
- [ ] File is written with UTF-8 encoding
|
|
@@ -875,30 +875,57 @@ Or in case of failure:
|
|
|
875
875
|
|
|
876
876
|
**✅ CORRECT Format - MUST USE:**
|
|
877
877
|
```
|
|
878
|
-
{completed_dir}/{fileName}.done.json ← Completion status marker (JSON format)
|
|
879
|
-
{completed_dir}/{fileName}.graph.json ← Graph data marker (JSON format)
|
|
878
|
+
{completed_dir}/{module}-{subpath}-{fileName}.done.json ← Completion status marker (JSON format)
|
|
879
|
+
{completed_dir}/{module}-{subpath}-{fileName}.graph.json ← Graph data marker (JSON format)
|
|
880
880
|
```
|
|
881
881
|
|
|
882
|
+
**Naming Rule Explanation:**
|
|
883
|
+
|
|
884
|
+
The marker filename MUST follow the composite naming pattern `{module}-{subpath}-{fileName}` to prevent conflicts between same-named source files.
|
|
885
|
+
|
|
886
|
+
**How to Extract Each Component from `{{sourcePath}}`:**
|
|
887
|
+
|
|
888
|
+
1. **module**: Use `{{module}}` input variable directly (e.g., `system`, `trade`, `ai`)
|
|
889
|
+
|
|
890
|
+
2. **subpath**: Extract the middle path between the module package root and the controller file:
|
|
891
|
+
- For Java: Remove package prefix up to the business layer (e.g., `controller/admin/`, `controller/app/`)
|
|
892
|
+
- Remove the file name at the end
|
|
893
|
+
- Replace path separators (`/`) with hyphens (`-`)
|
|
894
|
+
- If the file is at the module root directory, subpath will be empty → omit from filename
|
|
895
|
+
|
|
896
|
+
3. **fileName**: Use `{{fileName}}` input variable (Java class name WITHOUT `.java` extension)
|
|
897
|
+
|
|
882
898
|
**Examples:**
|
|
883
|
-
|
|
884
|
-
|
|
899
|
+
|
|
900
|
+
| sourcePath | module | subpath | fileName | Marker Filename |
|
|
901
|
+
|------------|--------|---------|----------|-----------------|
|
|
902
|
+
| `yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/NotifyMessageController.java` | `system` | `controller-admin-notify` | `NotifyMessageController` | `system-controller-admin-notify-NotifyMessageController.done.json` |
|
|
903
|
+
| `yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java` | `system` | `controller-admin-user` | `UserController` | `system-controller-admin-user-UserController.done.json` |
|
|
904
|
+
| `yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/chat/ChatConversationController.java` | `ai` | `controller-admin-chat` | `ChatConversationController` | `ai-controller-admin-chat-ChatConversationController.done.json` |
|
|
905
|
+
|
|
906
|
+
**Special Case - Empty subpath:**
|
|
907
|
+
- If the controller is directly in the controller root directory (no subpath), use format: `{module}-{fileName}.done.json`
|
|
908
|
+
- Example: `.../controller/admin/SystemController.java` → `system-SystemController.done.json`
|
|
909
|
+
|
|
910
|
+
**Full Path Examples:**
|
|
911
|
+
- `d:/dev/speccrew/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed/system-controller-admin-notify-NotifyMessageController.done.json`
|
|
912
|
+
- `d:/dev/speccrew/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed/ai-controller-admin-chat-ChatConversationController.graph.json`
|
|
885
913
|
|
|
886
914
|
**❌ WRONG Format - NEVER USE:**
|
|
887
915
|
```
|
|
888
|
-
{fileName}.
|
|
889
|
-
{fileName}.
|
|
890
|
-
{fileName}.done.
|
|
891
|
-
{fileName}
|
|
892
|
-
{fileName}
|
|
916
|
+
{fileName}.done.json ← WRONG: missing module and subpath (causes conflicts)
|
|
917
|
+
{fileName}.graph.json ← WRONG: missing module and subpath (causes conflicts)
|
|
918
|
+
{module}-{fileName}.done.json ← WRONG: missing subpath (may still conflict)
|
|
919
|
+
{fileName}.completed.json ← WRONG extension
|
|
920
|
+
{fileName}.done ← WRONG extension (missing .json)
|
|
921
|
+
{fileName}_done.json ← WRONG separator and extension
|
|
893
922
|
```
|
|
894
923
|
|
|
895
924
|
**❌ WRONG Filename Examples - NEVER USE:**
|
|
925
|
+
- `UserController.done.json` - WRONG: missing module and subpath (conflicts with other `UserController.java` files)
|
|
926
|
+
- `system-UserController.done.json` - WRONG: missing subpath (if file is in `controller/admin/user/`)
|
|
896
927
|
- `UserController.completed.json` - WRONG: uses `.completed.json` instead of `.done.json`
|
|
897
|
-
- `UserController.done` - WRONG: uses `.done` instead of `.done.json`
|
|
898
|
-
- `UserController.done.txt` - WRONG: uses `.done.txt` instead of `.done.json`
|
|
899
928
|
- `UserController_done.json` - WRONG: uses underscore and wrong extension
|
|
900
|
-
- `dict-UserController.done.json` - WRONG: has module prefix
|
|
901
|
-
- `system-UserController.done.json` - WRONG: has module prefix
|
|
902
929
|
|
|
903
930
|
---
|
|
904
931
|
|
|
@@ -959,9 +986,9 @@ Or in case of failure:
|
|
|
959
986
|
> {"fileName": "UserController", "status": "success", ...}
|
|
960
987
|
> ```
|
|
961
988
|
|
|
962
|
-
Use the Write tool to create file at `{{completed_dir}}/{{fileName}
|
|
989
|
+
Use the Write tool to create file at `{{completed_dir}}/{module}-{subpath}-{fileName}.done.json`:
|
|
963
990
|
|
|
964
|
-
**Full path example:** `d:/dev/speccrew/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed/UserController.done.json`
|
|
991
|
+
**Full path example:** `d:/dev/speccrew/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed/system-controller-admin-user-UserController.done.json`
|
|
965
992
|
|
|
966
993
|
**Complete JSON Template (ALL fields required):**
|
|
967
994
|
```json
|
|
@@ -998,12 +1025,13 @@ Use the Write tool to create file at `{{completed_dir}}/{{fileName}}.done.json`:
|
|
|
998
1025
|
|
|
999
1026
|
> **⚠️ CRITICAL**: The `documentPath` field is MANDATORY. It MUST match the `{{documentPath}}` variable from Step 5a. This is used to verify the document was created successfully.
|
|
1000
1027
|
|
|
1001
|
-
⚠️ **CRITICAL NAMING RULE:** Filename MUST be `{fileName}.done.json
|
|
1002
|
-
- ✅ CORRECT: `UserController.done.json` (
|
|
1003
|
-
- ✅ CORRECT: `
|
|
1028
|
+
⚠️ **CRITICAL NAMING RULE:** Filename MUST be `{module}-{subpath}-{fileName}.done.json` to prevent conflicts between same-named files.
|
|
1029
|
+
- ✅ CORRECT: `system-controller-admin-user-UserController.done.json` (full composite naming)
|
|
1030
|
+
- ✅ CORRECT: `ai-controller-admin-chat-ChatConversationController.done.json` (full composite naming)
|
|
1031
|
+
- ✅ CORRECT: `system-SystemController.done.json` (when subpath is empty, controller at root)
|
|
1032
|
+
- ❌ WRONG: `UserController.done.json` (missing module and subpath - will conflict)
|
|
1004
1033
|
- ❌ WRONG: `UserController.done` (missing .json extension)
|
|
1005
|
-
- ❌ WRONG: `
|
|
1006
|
-
- ❌ WRONG: `system-UserController.done.json` (using module prefix)
|
|
1034
|
+
- ❌ WRONG: `system-UserController.done.json` (missing subpath when controller is in nested package)
|
|
1007
1035
|
|
|
1008
1036
|
⚠️ **CRITICAL:** The file MUST contain valid JSON content. Empty files or files with only whitespace will cause processing failures.
|
|
1009
1037
|
|
|
@@ -1011,9 +1039,9 @@ Use the Write tool to create file at `{{completed_dir}}/{{fileName}}.done.json`:
|
|
|
1011
1039
|
|
|
1012
1040
|
> **⚠️ CRITICAL FORMAT REQUIREMENT**: The `.graph.json` file MUST be valid JSON and **MUST include the root-level `module` field**. Do NOT rely on scripts to infer the module from `.done` file - the `module` field MUST be explicitly present at the root level of `.graph.json`.
|
|
1013
1041
|
|
|
1014
|
-
Use the Write tool to create file at `{{completed_dir}}/{{fileName}
|
|
1042
|
+
Use the Write tool to create file at `{{completed_dir}}/{module}-{subpath}-{fileName}.graph.json`:
|
|
1015
1043
|
|
|
1016
|
-
**Full path example:** `d:/dev/speccrew/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed/UserController.graph.json`
|
|
1044
|
+
**Full path example:** `d:/dev/speccrew/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed/system-controller-admin-user-UserController.graph.json`
|
|
1017
1045
|
|
|
1018
1046
|
```json
|
|
1019
1047
|
{
|
|
@@ -1045,11 +1073,13 @@ Use the Write tool to create file at `{{completed_dir}}/{{fileName}}.graph.json`
|
|
|
1045
1073
|
> - Do NOT assume scripts will fall back to reading from `.done` file
|
|
1046
1074
|
> - Missing `module` field will cause the graph merge pipeline to reject this file
|
|
1047
1075
|
|
|
1048
|
-
⚠️ **CRITICAL NAMING RULE:** Filename MUST be `{fileName}.graph.json
|
|
1049
|
-
- ✅ CORRECT: `UserController.graph.json` (
|
|
1050
|
-
- ✅ CORRECT: `
|
|
1076
|
+
⚠️ **CRITICAL NAMING RULE:** Filename MUST be `{module}-{subpath}-{fileName}.graph.json` to prevent conflicts between same-named files.
|
|
1077
|
+
- ✅ CORRECT: `system-controller-admin-user-UserController.graph.json` (full composite naming)
|
|
1078
|
+
- ✅ CORRECT: `ai-controller-admin-chat-ChatConversationController.graph.json` (full composite naming)
|
|
1079
|
+
- ✅ CORRECT: `system-SystemController.graph.json` (when subpath is empty, controller at root)
|
|
1080
|
+
- ❌ WRONG: `UserController.graph.json` (missing module and subpath - will conflict)
|
|
1051
1081
|
- ❌ WRONG: `dict-UserController.graph.json` (using old featureId format)
|
|
1052
|
-
- ❌ WRONG: `system-UserController.graph.json` (
|
|
1082
|
+
- ❌ WRONG: `system-UserController.graph.json` (missing subpath when controller is in nested package)
|
|
1053
1083
|
|
|
1054
1084
|
⚠️ **CRITICAL:** The file MUST contain valid JSON content. Empty files or files with only whitespace will cause processing failures.
|
|
1055
1085
|
|
|
@@ -426,30 +426,52 @@ Example: If batch has 5 features → create and launch 5 Worker Tasks simultaneo
|
|
|
426
426
|
|
|
427
427
|
**✅ CORRECT Format - MUST USE:**
|
|
428
428
|
```
|
|
429
|
-
{completed_dir}/{fileName}.done.json ← Completion status marker (JSON format)
|
|
430
|
-
{completed_dir}/{fileName}.graph.json ← Graph data marker (JSON format)
|
|
429
|
+
{completed_dir}/{module}-{subpath}-{fileName}.done.json ← Completion status marker (JSON format)
|
|
430
|
+
{completed_dir}/{module}-{subpath}-{fileName}.graph.json ← Graph data marker (JSON format)
|
|
431
431
|
```
|
|
432
432
|
|
|
433
|
+
**Naming Rule Explanation:**
|
|
434
|
+
|
|
435
|
+
The marker filename MUST follow the composite naming pattern `{module}-{subpath}-{fileName}` to prevent conflicts between same-named source files.
|
|
436
|
+
|
|
437
|
+
**How Workers Generate the Filename:**
|
|
438
|
+
|
|
439
|
+
1. **module**: Use the `{{module}}` input variable directly
|
|
440
|
+
|
|
441
|
+
2. **subpath**: Extract from `{{sourcePath}}`:
|
|
442
|
+
- For UI (Vue/React): Middle path between `views/` or `pages/` and the file name
|
|
443
|
+
- For API (Java): Middle path between controller root and the file name
|
|
444
|
+
- Replace path separators (`/`) with hyphens (`-`)
|
|
445
|
+
- Omit if file is at module root (empty subpath)
|
|
446
|
+
|
|
447
|
+
3. **fileName**: Use `{{fileName}}` input variable (file name WITHOUT extension)
|
|
448
|
+
|
|
433
449
|
**Examples:**
|
|
434
|
-
|
|
435
|
-
|
|
450
|
+
|
|
451
|
+
| Source File | module | subpath | fileName | Marker Filename |
|
|
452
|
+
|-------------|--------|---------|----------|-----------------|
|
|
453
|
+
| `yudao-ui/.../views/system/notify/message/index.vue` | `system` | `notify-message` | `index` | `system-notify-message-index.done.json` |
|
|
454
|
+
| `yudao-ui/.../views/system/user/index.vue` | `system` | `user` | `index` | `system-user-index.done.json` |
|
|
455
|
+
| `yudao-module-system/.../controller/admin/user/UserController.java` | `system` | `controller-admin-user` | `UserController` | `system-controller-admin-user-UserController.done.json` |
|
|
456
|
+
|
|
457
|
+
**Full Path Examples:**
|
|
458
|
+
- `d:/dev/speccrew/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed/system-notify-message-index.done.json`
|
|
459
|
+
- `d:/dev/speccrew/speccrew-workspace/knowledges/base/sync-state/knowledge-bizs/completed/system-controller-admin-user-UserController.graph.json`
|
|
436
460
|
|
|
437
461
|
**❌ WRONG Format - NEVER USE:**
|
|
438
462
|
```
|
|
439
|
-
{fileName}.
|
|
440
|
-
{fileName}.
|
|
441
|
-
{fileName}.
|
|
442
|
-
{fileName}
|
|
443
|
-
{fileName}
|
|
463
|
+
{fileName}.done.json ← WRONG: missing module and subpath (causes conflicts)
|
|
464
|
+
{fileName}.graph.json ← WRONG: missing module and subpath (causes conflicts)
|
|
465
|
+
{fileName}.completed.json ← WRONG extension
|
|
466
|
+
{fileName}.done ← WRONG extension (missing .json)
|
|
467
|
+
{fileName}_done.json ← WRONG separator and extension
|
|
444
468
|
```
|
|
445
469
|
|
|
446
470
|
**❌ WRONG Filename Examples - NEVER USE:**
|
|
471
|
+
- `index.done.json` - WRONG: missing module and subpath (conflicts with other `index.vue` files)
|
|
472
|
+
- `UserController.done.json` - WRONG: missing module and subpath (conflicts with other controllers)
|
|
447
473
|
- `UserController.completed.json` - WRONG: uses `.completed.json` instead of `.done.json`
|
|
448
|
-
- `UserController.done` - WRONG: uses `.done` instead of `.done.json`
|
|
449
|
-
- `UserController.done.txt` - WRONG: uses `.done.txt` instead of `.done.json`
|
|
450
474
|
- `UserController_done.json` - WRONG: uses underscore and wrong extension
|
|
451
|
-
- `dict-UserController.done.json` - WRONG: has module prefix
|
|
452
|
-
- `system-UserController.done.json` - WRONG: has module prefix
|
|
453
475
|
|
|
454
476
|
---
|
|
455
477
|
|
|
@@ -508,8 +530,8 @@ Example: If batch has 5 features → create and launch 5 Worker Tasks simultaneo
|
|
|
508
530
|
|
|
509
531
|
| Marker Type | File Name Format | Example |
|
|
510
532
|
|-------------|------------------|---------|
|
|
511
|
-
| Completion marker | `{fileName}.done.json` | `index.done.json`, `UserController.done.json
|
|
512
|
-
| Graph data | `{fileName}.graph.json` | `index.graph.json`, `UserController.graph.json
|
|
533
|
+
| Completion marker | `{module}-{subpath}-{fileName}.done.json` | `system-notify-message-index.done.json`, `system-controller-admin-user-UserController.done.json` |
|
|
534
|
+
| Graph data | `{module}-{subpath}-{fileName}.graph.json` | `system-notify-message-index.graph.json`, `system-controller-admin-user-UserController.graph.json` |
|
|
513
535
|
|
|
514
536
|
**Worker Completion Requirements:**
|
|
515
537
|
|
|
@@ -6,6 +6,32 @@ This document defines the status tracking formats for the bizs pipeline.
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## Marker File Naming Convention
|
|
10
|
+
|
|
11
|
+
Marker files (`.done.json` and `.graph.json`) use a composite naming pattern to prevent conflicts between same-named source files.
|
|
12
|
+
|
|
13
|
+
**Format:** `{module}-{subpath}-{fileName}.{type}.json`
|
|
14
|
+
|
|
15
|
+
**Components:**
|
|
16
|
+
- **module**: Business module name (e.g., `system`, `ai`, `bpm`, `trade`)
|
|
17
|
+
- **subpath**: Middle path extracted from sourcePath, with `/` replaced by `-` (e.g., `notify-message`, `controller-admin-user`)
|
|
18
|
+
- **fileName**: Source file name without extension (e.g., `index`, `UserController`)
|
|
19
|
+
- **type**: `done` or `graph`
|
|
20
|
+
|
|
21
|
+
**Examples:**
|
|
22
|
+
|
|
23
|
+
| Source File | Marker Filename |
|
|
24
|
+
|-------------|-----------------|
|
|
25
|
+
| `yudao-ui/.../views/system/notify/message/index.vue` | `system-notify-message-index.done.json` |
|
|
26
|
+
| `yudao-ui/.../views/system/user/index.vue` | `system-user-index.done.json` |
|
|
27
|
+
| `yudao-module-system/.../controller/admin/user/UserController.java` | `system-controller-admin-user-UserController.done.json` |
|
|
28
|
+
|
|
29
|
+
**Special Case:** If subpath is empty (file at module root), use format: `{module}-{fileName}.{type}.json`
|
|
30
|
+
|
|
31
|
+
**Legacy Format Support:** The processing scripts support both new format (`{module}-{subpath}-{fileName}`) and legacy format (`{fileName}`) for backward compatibility.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
9
35
|
## Feature Status Tracking (Stage 2)
|
|
10
36
|
|
|
11
37
|
Feature analysis status is tracked directly in `features-{platform}.json` files located at:
|
|
@@ -61,11 +87,10 @@ Module summarization status is determined by aggregating feature statuses from `
|
|
|
61
87
|
|
|
62
88
|
| Field | Type | Description |
|
|
63
89
|
|-------|------|-------------|
|
|
64
|
-
| `features[].
|
|
65
|
-
| `features[].
|
|
66
|
-
| `features[].sourcePath` | string | Source code file path |
|
|
90
|
+
| `features[].fileName` | string | Feature file name (without extension) - used as part of marker file naming |
|
|
91
|
+
| `features[].sourcePath` | string | Source code file path - used to extract subpath for marker file naming |
|
|
67
92
|
| `features[].documentPath` | string | Generated documentation path |
|
|
68
|
-
| `features[].module` | string | Module code_name |
|
|
93
|
+
| `features[].module` | string | Module code_name - used as prefix for marker file naming |
|
|
69
94
|
| `features[].analyzed` | boolean | Whether feature has been analyzed |
|
|
70
95
|
| `features[].status` | string | `pending`, `in_progress`, `completed`, `failed` |
|
|
71
96
|
| `features[].startedAt` | string | ISO timestamp when analysis started |
|
|
@@ -11,6 +11,53 @@ const fs = require('fs');
|
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const { execFileSync } = require('child_process');
|
|
13
13
|
|
|
14
|
+
// Helper: Parse marker filename to extract components
|
|
15
|
+
// New format: {module}-{subpath}-{fileName}.done.json
|
|
16
|
+
// Legacy format: {fileName}.done.json
|
|
17
|
+
function parseMarkerFilename(markerFile, fileType) {
|
|
18
|
+
// fileType: 'done' or 'graph'
|
|
19
|
+
const ext = `.${fileType}.json`;
|
|
20
|
+
if (!markerFile.endsWith(ext)) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const baseName = markerFile.slice(0, -ext.length);
|
|
25
|
+
const parts = baseName.split('-');
|
|
26
|
+
|
|
27
|
+
// New format: must have at least 3 parts (module-subpath-fileName)
|
|
28
|
+
// But subpath can be empty, so minimum is 2 parts (module-fileName)
|
|
29
|
+
if (parts.length >= 2) {
|
|
30
|
+
// Try to identify if this is new format or legacy format
|
|
31
|
+
// New format has module prefix (known modules are usually short names like 'system', 'ai', 'bpm', 'trade')
|
|
32
|
+
// Legacy format is just fileName (e.g., 'index', 'UserController')
|
|
33
|
+
|
|
34
|
+
// Heuristic: if first part is a known module-like name and there are more parts,
|
|
35
|
+
// treat it as new format
|
|
36
|
+
// For now, we'll return both possible interpretations and let the caller decide
|
|
37
|
+
return {
|
|
38
|
+
baseName: baseName,
|
|
39
|
+
parts: parts,
|
|
40
|
+
// For new format: fileName is the last part
|
|
41
|
+
newFormatFileName: parts[parts.length - 1],
|
|
42
|
+
// For new format: module is the first part
|
|
43
|
+
newFormatModule: parts[0],
|
|
44
|
+
// For new format: subpath is everything in between
|
|
45
|
+
newFormatSubpath: parts.length > 2 ? parts.slice(1, -1).join('-') : '',
|
|
46
|
+
// For legacy format: fileName is the entire baseName
|
|
47
|
+
legacyFileName: baseName,
|
|
48
|
+
// Detect likely format based on pattern
|
|
49
|
+
isLikelyNewFormat: parts.length > 1 && parts[0].length < 20 // module names are usually short
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
baseName: baseName,
|
|
55
|
+
parts: parts,
|
|
56
|
+
legacyFileName: baseName,
|
|
57
|
+
isLikelyNewFormat: false
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
14
61
|
// Helper: Validate and normalize .done.json file content
|
|
15
62
|
function validateAndNormalizeDoneContent(content, doneFile) {
|
|
16
63
|
// Strip file extensions from fileName if present
|
|
@@ -371,12 +418,16 @@ function main() {
|
|
|
371
418
|
|
|
372
419
|
// Fallback: recover minimal info from filename and context when .done.json is non-JSON
|
|
373
420
|
function recoverDoneFileFromContext(doneFile, completedDir, syncStatePath) {
|
|
374
|
-
const
|
|
421
|
+
const parseResult = parseMarkerFilename(doneFile, 'done');
|
|
422
|
+
|
|
423
|
+
// Determine fileName: prefer content from .done.json, fall back to filename parsing
|
|
424
|
+
let fileName = parseResult ? parseResult.legacyFileName : doneFile.replace(/\.done\.json$/, '');
|
|
425
|
+
|
|
375
426
|
console.warn(`[WARN] .done.json file is not valid JSON: ${doneFile}. Attempting recovery from filename...`);
|
|
376
|
-
|
|
427
|
+
|
|
377
428
|
// Try to get module from same-named .graph.json
|
|
378
429
|
let module = 'unknown';
|
|
379
|
-
const graphFilePath = path.join(completedDir,
|
|
430
|
+
const graphFilePath = path.join(completedDir, doneFile.replace('.done.json', '.graph.json'));
|
|
380
431
|
if (fs.existsSync(graphFilePath)) {
|
|
381
432
|
try {
|
|
382
433
|
const graphContent = JSON.parse(fs.readFileSync(graphFilePath, 'utf8'));
|
|
@@ -387,6 +438,11 @@ function main() {
|
|
|
387
438
|
// Ignore parse errors
|
|
388
439
|
}
|
|
389
440
|
}
|
|
441
|
+
|
|
442
|
+
// If module is still unknown, try to extract from new-format filename
|
|
443
|
+
if (module === 'unknown' && parseResult && parseResult.isLikelyNewFormat) {
|
|
444
|
+
module = parseResult.newFormatModule;
|
|
445
|
+
}
|
|
390
446
|
|
|
391
447
|
// Try to match sourceFile from features-*.json files
|
|
392
448
|
let sourceFile = 'unknown';
|
|
@@ -399,7 +455,18 @@ function main() {
|
|
|
399
455
|
try {
|
|
400
456
|
const content = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
401
457
|
if (content.features && Array.isArray(content.features)) {
|
|
402
|
-
|
|
458
|
+
// Try both new format and legacy format matching
|
|
459
|
+
let found = content.features.find(feat => feat.fileName === fileName);
|
|
460
|
+
|
|
461
|
+
// If not found with legacy fileName and we have new format info,
|
|
462
|
+
// try matching with newFormatFileName
|
|
463
|
+
if (!found && parseResult && parseResult.isLikelyNewFormat) {
|
|
464
|
+
found = content.features.find(feat => feat.fileName === parseResult.newFormatFileName);
|
|
465
|
+
if (found) {
|
|
466
|
+
fileName = parseResult.newFormatFileName;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
403
470
|
if (found) {
|
|
404
471
|
sourceFile = f;
|
|
405
472
|
break;
|