speccrew 0.6.14 → 0.6.16
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.
|
@@ -408,6 +408,12 @@ No knowledge base exists. A lightweight feature inventory scan is triggered to d
|
|
|
408
408
|
> 🛑 **MANDATORY -- Path C -> Path B Sequence**:
|
|
409
409
|
> After init-features completes (features-*.json generated), you MUST immediately execute Path B:
|
|
410
410
|
>
|
|
411
|
+
> **Path B Recovery Check**:
|
|
412
|
+
> Before starting Step 1, check if `{workspace_path}/knowledges/bizs/DISPATCH-PROGRESS.json` exists:
|
|
413
|
+
> - If exists with pending tasks → resume from Step 3 (skip Step 1 and Step 1.5)
|
|
414
|
+
> - If exists with all completed → skip to Step 5 (Update Features Status)
|
|
415
|
+
> - If not exists → start from Step 1
|
|
416
|
+
>
|
|
411
417
|
> **Path B Step 1: Module Matching**
|
|
412
418
|
> Dispatch Worker with `speccrew-pm-module-matcher` skill to match requirement features against the generated features inventory.
|
|
413
419
|
>
|
|
@@ -422,6 +428,26 @@ No knowledge base exists. A lightweight feature inventory scan is triggered to d
|
|
|
422
428
|
> requirement_summary: <brief summary of user's requirement>
|
|
423
429
|
> ```
|
|
424
430
|
>
|
|
431
|
+
> **Path B Step 1.5: Initialize Knowledge Dispatch Progress**
|
|
432
|
+
>
|
|
433
|
+
> Save the matcher Worker's output to a temporary file:
|
|
434
|
+
> - File path: `{workspace_path}/knowledges/bizs/.matcher-result.json`
|
|
435
|
+
> - Content: The matcher's full JSON output (matched modules with platform_id, module_name, confidence)
|
|
436
|
+
>
|
|
437
|
+
> Run the dispatch progress initialization script:
|
|
438
|
+
> ```bash
|
|
439
|
+
> node "{update_progress_script}" init-knowledge-tasks `
|
|
440
|
+
> --file "{workspace_path}/knowledges/bizs/DISPATCH-PROGRESS.json" `
|
|
441
|
+
> --matcher-result "{workspace_path}/knowledges/bizs/.matcher-result.json" `
|
|
442
|
+
> --features-dir "{workspace_path}/knowledges/bizs"
|
|
443
|
+
> ```
|
|
444
|
+
>
|
|
445
|
+
> Verify the DISPATCH-PROGRESS.json was created successfully and log the total task count.
|
|
446
|
+
>
|
|
447
|
+
> 🛑 **HARD GATE — DISPATCH-PROGRESS.json MUST exist before proceeding**
|
|
448
|
+
> DO NOT proceed to Step 2 until DISPATCH-PROGRESS.json is created and contains tasks.
|
|
449
|
+
> If the script fails, diagnose the error and retry. DO NOT skip this step.
|
|
450
|
+
>
|
|
425
451
|
> 🛑 **CRITICAL GATE — DO NOT SKIP Steps 2-5**:
|
|
426
452
|
> After matcher completes, you MUST execute Steps 2-5 to deep-initialize the matched modules' knowledge base.
|
|
427
453
|
> DO NOT jump to Phase 2 (Complexity Assessment) or Phase 3 (Requirement Clarification) until ALL Steps complete.
|
|
@@ -455,33 +481,70 @@ No knowledge base exists. A lightweight feature inventory scan is triggered to d
|
|
|
455
481
|
>
|
|
456
482
|
> Wait for ALL module-initializer Workers to complete. Collect all task plan JSON outputs.
|
|
457
483
|
>
|
|
458
|
-
> **Path B Step 3: Execute Feature Analysis**
|
|
459
|
-
> Based on the task plans from Step 2, dispatch Worker for EACH pending feature.
|
|
484
|
+
> **Path B Step 3: Execute Feature Analysis (Dispatch-Tracked)**
|
|
460
485
|
>
|
|
461
|
-
>
|
|
462
|
-
>
|
|
486
|
+
> ⚠️ **MANDATORY RULES FOR THIS STEP:**
|
|
487
|
+
> 1. MUST dispatch Workers for ALL tasks with status "pending" in DISPATCH-PROGRESS.json
|
|
488
|
+
> 2. DO NOT skip any pending task — the matcher already determined relevance
|
|
489
|
+
> 3. DO NOT stop mid-way to ask user for options (A/B/C) — execute ALL tasks
|
|
490
|
+
> 4. After each Worker completes, update task status via script
|
|
463
491
|
>
|
|
464
|
-
> **
|
|
465
|
-
>
|
|
466
|
-
>
|
|
467
|
-
> -
|
|
468
|
-
> - task: Execute {analyzer_skill} for feature "{fileName}"
|
|
469
|
-
> - context:
|
|
470
|
-
> skill: {analyzer_skill}
|
|
471
|
-
> fileName: {task.fileName}
|
|
472
|
-
> sourcePath: {source_path}/{task.sourcePath}
|
|
473
|
-
> documentPath: {workspace_path}/{task.documentPath}
|
|
474
|
-
> module: {task.module}
|
|
475
|
-
> analyzed: false
|
|
476
|
-
> platform_type: {task.platform_type}
|
|
477
|
-
> platform_subtype: {task.platform_subtype}
|
|
478
|
-
> tech_stack: {task.tech_stack}
|
|
479
|
-
> language: {language}
|
|
480
|
-
> completed_dir: {sync_state_bizs_dir}/completed
|
|
481
|
-
> sourceFile: features-{platform_id}.json
|
|
482
|
-
> ```
|
|
492
|
+
> **Recovery Check**: Read `{workspace_path}/knowledges/bizs/DISPATCH-PROGRESS.json`:
|
|
493
|
+
> - If tasks with `status: "completed"` exist, skip them (resuming from interruption)
|
|
494
|
+
> - Only dispatch tasks with `status: "pending"`
|
|
495
|
+
> - Log: "Resuming: {completed_count} completed, {pending_count} remaining"
|
|
483
496
|
>
|
|
484
|
-
>
|
|
497
|
+
> **Dispatch Loop**:
|
|
498
|
+
> For each task in DISPATCH-PROGRESS.json where status == "pending":
|
|
499
|
+
>
|
|
500
|
+
> 1. Dispatch `speccrew-task-worker` with:
|
|
501
|
+
> - **skill**: `{task.analyzer_skill}` (e.g., `speccrew-knowledge-bizs-api-analyze` or `speccrew-knowledge-bizs-ui-analyze`)
|
|
502
|
+
> - **context**: All task fields (module, platform_id, fileName, sourcePath, etc.)
|
|
503
|
+
>
|
|
504
|
+
> **Agent Tool Invocation**:
|
|
505
|
+
> ```
|
|
506
|
+
> Use the Agent tool to invoke speccrew-task-worker:
|
|
507
|
+
> - agent: speccrew-task-worker
|
|
508
|
+
> - task: Execute {task.analyzer_skill} for feature "{task.fileName}"
|
|
509
|
+
> - context:
|
|
510
|
+
> skill: {task.analyzer_skill}
|
|
511
|
+
> fileName: {task.fileName}
|
|
512
|
+
> sourcePath: {source_path}/{task.sourcePath}
|
|
513
|
+
> documentPath: {workspace_path}/{task.documentPath}
|
|
514
|
+
> module: {task.module}
|
|
515
|
+
> platform_id: {task.platform_id}
|
|
516
|
+
> platform_type: {task.platform_type}
|
|
517
|
+
> platform_subtype: {task.platform_subtype}
|
|
518
|
+
> tech_stack: {task.tech_stack}
|
|
519
|
+
> language: {language}
|
|
520
|
+
> completed_dir: {sync_state_bizs_dir}/completed
|
|
521
|
+
> sourceFile: features-{task.platform_id}.json
|
|
522
|
+
> ```
|
|
523
|
+
>
|
|
524
|
+
> 2. After Worker completes successfully, update progress:
|
|
525
|
+
> ```bash
|
|
526
|
+
> node "{update_progress_script}" update-task `
|
|
527
|
+
> --file "{workspace_path}/knowledges/bizs/DISPATCH-PROGRESS.json" `
|
|
528
|
+
> --task-id "{task.id}" `
|
|
529
|
+
> --status completed
|
|
530
|
+
> ```
|
|
531
|
+
>
|
|
532
|
+
> 3. If Worker fails, update status to "failed" and continue with next task:
|
|
533
|
+
> ```bash
|
|
534
|
+
> node "{update_progress_script}" update-task `
|
|
535
|
+
> --file "{workspace_path}/knowledges/bizs/DISPATCH-PROGRESS.json" `
|
|
536
|
+
> --task-id "{task.id}" `
|
|
537
|
+
> --status failed
|
|
538
|
+
> ```
|
|
539
|
+
>
|
|
540
|
+
> **Completion Check**: After all dispatches complete, read DISPATCH-PROGRESS.json:
|
|
541
|
+
> - If all tasks are "completed" → proceed to Step 4
|
|
542
|
+
> - If some tasks "failed" → log failures and proceed (do not block on failures)
|
|
543
|
+
>
|
|
544
|
+
> 🛑 **CONTINUOUS EXECUTION — DO NOT INTERRUPT**
|
|
545
|
+
> Process ALL pending tasks without stopping for user confirmation.
|
|
546
|
+
> The scope was already determined by the matcher in Step 1.
|
|
547
|
+
> Asking "do you want to continue?" mid-way is FORBIDDEN.
|
|
485
548
|
>
|
|
486
549
|
> **Path B Step 4: Generate Module Summaries**
|
|
487
550
|
> For each matched module, dispatch Worker with `speccrew-knowledge-module-summarize` skill:
|
|
@@ -503,6 +566,7 @@ No knowledge base exists. A lightweight feature inventory scan is triggered to d
|
|
|
503
566
|
>
|
|
504
567
|
> 🛑 **Path B Completion Check**:
|
|
505
568
|
> Before proceeding to Phase 2, verify:
|
|
569
|
+
> - [ ] Step 1.5 completed: DISPATCH-PROGRESS.json created with all tasks
|
|
506
570
|
> - [ ] Step 2 completed: task plan JSON generated for each matched module
|
|
507
571
|
> - [ ] Step 3 completed: analyze Workers dispatched and completed for ALL pending features
|
|
508
572
|
> - [ ] Step 4 completed: module-summarize Workers completed for ALL matched modules
|
|
@@ -530,12 +594,39 @@ This context will be passed to Phase 3 (Requirement Clarification) and Phase 4 (
|
|
|
530
594
|
|
|
531
595
|
## Phase 2: Complexity Assessment & Skill Routing
|
|
532
596
|
|
|
533
|
-
> **PRE-CONDITION**: Path B Steps 2-5 must be completed before entering Phase 2.
|
|
534
|
-
> If matched_modules exist but knowledges/bizs/ directories are empty, Path B was not fully executed.
|
|
535
|
-
> Go back and execute the remaining Path B steps.
|
|
536
|
-
|
|
537
597
|
Before starting requirement analysis, assess the requirement complexity to determine the appropriate skill path.
|
|
538
598
|
|
|
599
|
+
### Phase 2.0: Knowledge Initialization Verification (MANDATORY)
|
|
600
|
+
|
|
601
|
+
> ⚠️ **THIS STEP IS MANDATORY AND CANNOT BE SKIPPED**
|
|
602
|
+
> You MUST execute the verification commands below before ANY complexity assessment.
|
|
603
|
+
|
|
604
|
+
**Step 2.0.1**: Check if DISPATCH-PROGRESS.json exists:
|
|
605
|
+
```bash
|
|
606
|
+
# Read the file — if it does not exist, Path B Step 1.5 was not executed
|
|
607
|
+
cat "{workspace_path}/knowledges/bizs/DISPATCH-PROGRESS.json"
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
**Step 2.0.2**: Evaluate the file content:
|
|
611
|
+
|
|
612
|
+
| Condition | Action |
|
|
613
|
+
|-----------|--------|
|
|
614
|
+
| File does NOT exist | Path B was not executed. Go back to Phase 1.2 Path B Step 1. |
|
|
615
|
+
| File exists, `counts.pending > 0` | Knowledge initialization is INCOMPLETE. Go back to Path B Step 3 and dispatch remaining tasks. |
|
|
616
|
+
| File exists, `counts.pending == 0` AND `counts.completed > 0` | Knowledge initialization is COMPLETE. Proceed to Phase 2.1. |
|
|
617
|
+
| File exists, `counts.total == 0` | No features to analyze (all already analyzed). Proceed to Phase 2.1. |
|
|
618
|
+
|
|
619
|
+
**Step 2.0.3**: If going back to Path B:
|
|
620
|
+
1. Read DISPATCH-PROGRESS.json to get pending task list
|
|
621
|
+
2. For each module with pending tasks, dispatch `speccrew-task-worker` with `speccrew-pm-module-initializer` skill (if Step 2 not done)
|
|
622
|
+
3. Then dispatch analyze Workers for all pending features (Step 3)
|
|
623
|
+
4. Then dispatch summarize Workers (Step 4)
|
|
624
|
+
5. Update features status (Step 5)
|
|
625
|
+
6. Return here to Phase 2.0 and re-verify
|
|
626
|
+
|
|
627
|
+
> 🔴 **ABSOLUTE RULE**: DO NOT proceed to Phase 2.1 (Complexity Assessment) while `counts.pending > 0`.
|
|
628
|
+
> The matcher identified these features as relevant. Skipping their analysis means the PRD will lack existing system feature descriptions.
|
|
629
|
+
|
|
539
630
|
### 2.1 Complexity Indicators
|
|
540
631
|
|
|
541
632
|
Evaluate the user's requirement against these indicators:
|
|
@@ -52,6 +52,7 @@ Generate analyze task plan for a single business module. Reads features-*.json,
|
|
|
52
52
|
"analyzer_skill": "speccrew-knowledge-bizs-ui-analyze",
|
|
53
53
|
"tasks": [
|
|
54
54
|
{
|
|
55
|
+
"id": "ki-web-vue-system-index",
|
|
55
56
|
"fileName": "index",
|
|
56
57
|
"sourcePath": "src/views/system/user/index.vue",
|
|
57
58
|
"documentPath": "knowledges/bizs/web-vue/system/features",
|
|
@@ -59,7 +60,8 @@ Generate analyze task plan for a single business module. Reads features-*.json,
|
|
|
59
60
|
"platform_type": "web",
|
|
60
61
|
"platform_subtype": "vue",
|
|
61
62
|
"tech_stack": ["vue", "typescript"],
|
|
62
|
-
"language": "zh"
|
|
63
|
+
"language": "zh",
|
|
64
|
+
"status": "pending"
|
|
63
65
|
}
|
|
64
66
|
],
|
|
65
67
|
"total_pending": 90,
|
|
@@ -83,6 +85,18 @@ Generate analyze task plan for a single business module. Reads features-*.json,
|
|
|
83
85
|
| `total_pending` | Count of pending features |
|
|
84
86
|
| `summarize_params` | Parameters for module-summarize skill (to be executed after all analyze tasks complete) |
|
|
85
87
|
|
|
88
|
+
**Task ID Naming Convention**:
|
|
89
|
+
|
|
90
|
+
The `id` field follows the format: `ki-{platform_id}-{module}-{fileName}`
|
|
91
|
+
- `ki` = knowledge initialization
|
|
92
|
+
- `platform_id` = Platform identifier (e.g., "web-vue", "admin-api")
|
|
93
|
+
- `module` = Business module name
|
|
94
|
+
- `fileName` = Feature file name
|
|
95
|
+
|
|
96
|
+
Example: `"ki-web-vue-system-index"`
|
|
97
|
+
|
|
98
|
+
> **Note**: This ID is consistent with task IDs in DISPATCH-PROGRESS.json and is used for progress tracking.
|
|
99
|
+
|
|
86
100
|
## Workflow
|
|
87
101
|
|
|
88
102
|
```mermaid
|
|
@@ -132,6 +146,7 @@ For each pending feature from Step 1, build a task object with analyzer paramete
|
|
|
132
146
|
|
|
133
147
|
```json
|
|
134
148
|
{
|
|
149
|
+
"id": "ki-{platform_id}-{feature.module}-{feature.fileName}",
|
|
135
150
|
"fileName": "{feature.fileName}",
|
|
136
151
|
"sourcePath": "{feature.sourcePath}",
|
|
137
152
|
"documentPath": "{output_path}/bizs/{platform_id}/{feature.module}/features",
|
|
@@ -139,7 +154,8 @@ For each pending feature from Step 1, build a task object with analyzer paramete
|
|
|
139
154
|
"platform_type": "{platform_type}",
|
|
140
155
|
"platform_subtype": "{platform_subtype}",
|
|
141
156
|
"tech_stack": "{tech_stack}",
|
|
142
|
-
"language": "{language}"
|
|
157
|
+
"language": "{language}",
|
|
158
|
+
"status": "pending"
|
|
143
159
|
}
|
|
144
160
|
```
|
|
145
161
|
|
|
@@ -151,6 +167,8 @@ For backend features (api-analyze), also include:
|
|
|
151
167
|
}
|
|
152
168
|
```
|
|
153
169
|
|
|
170
|
+
**Note**: The `id` field format is `ki-{platform_id}-{module}-{fileName}` where `ki` stands for "knowledge initialization". This ID is consistent with task IDs in DISPATCH-PROGRESS.json for progress tracking.
|
|
171
|
+
|
|
154
172
|
**Output**: "Step 3 Status: ✅ COMPLETED - Built {count} task entries"
|
|
155
173
|
|
|
156
174
|
### Step 4: Build Summarize Parameters
|
package/package.json
CHANGED
|
@@ -56,6 +56,14 @@
|
|
|
56
56
|
* --status <status> Status: pending/in_progress/completed/confirmed (required)
|
|
57
57
|
* --output <text> Output information (optional)
|
|
58
58
|
*
|
|
59
|
+
* 7. init-knowledge-tasks - Generate knowledge initialization tasks from matcher results
|
|
60
|
+
* node update-progress.js init-knowledge-tasks --file <path> --matcher-result <path> --features-dir <dir> [--force]
|
|
61
|
+
* Options:
|
|
62
|
+
* --file <path> Progress file path (required)
|
|
63
|
+
* --matcher-result <path> Matcher result JSON file path (required)
|
|
64
|
+
* --features-dir <dir> Directory containing features-*.json files (required)
|
|
65
|
+
* --force Overwrite existing file
|
|
66
|
+
*
|
|
59
67
|
* Output Format:
|
|
60
68
|
* Success: {"success": true, "message": "...", "data": {...}}
|
|
61
69
|
* Failure: {"success": false, "error": "..."} (output to stderr, exit code 1)
|
|
@@ -345,6 +353,10 @@ function parseArgs() {
|
|
|
345
353
|
case '-Force':
|
|
346
354
|
result.force = true;
|
|
347
355
|
break;
|
|
356
|
+
case '--matcher-result':
|
|
357
|
+
case '-Matcher-Result':
|
|
358
|
+
result.matcherResult = args[++i];
|
|
359
|
+
break;
|
|
348
360
|
}
|
|
349
361
|
}
|
|
350
362
|
|
|
@@ -816,6 +828,201 @@ function cmdUpdateWorkflow(args) {
|
|
|
816
828
|
}
|
|
817
829
|
}
|
|
818
830
|
|
|
831
|
+
/**
|
|
832
|
+
* Determine analyzer skill based on platform_id
|
|
833
|
+
* @param {string} platformId - Platform identifier
|
|
834
|
+
* @returns {string} Analyzer skill name
|
|
835
|
+
*/
|
|
836
|
+
function getAnalyzerSkill(platformId) {
|
|
837
|
+
const pid = platformId.toLowerCase();
|
|
838
|
+
if (pid.includes('web') || pid.includes('mobile')) {
|
|
839
|
+
return 'speccrew-knowledge-bizs-ui-analyze';
|
|
840
|
+
}
|
|
841
|
+
if (pid.includes('backend') || pid.includes('api')) {
|
|
842
|
+
return 'speccrew-knowledge-bizs-api-analyze';
|
|
843
|
+
}
|
|
844
|
+
// Default to UI analyzer for unknown platforms
|
|
845
|
+
return 'speccrew-knowledge-bizs-ui-analyze';
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
/**
|
|
849
|
+
* Command: init-knowledge-tasks - Generate knowledge initialization tasks from matcher results
|
|
850
|
+
*
|
|
851
|
+
* Reads matcher result and features-*.json files to generate a task list for knowledge initialization.
|
|
852
|
+
* Each task corresponds to a feature that needs to be analyzed.
|
|
853
|
+
*/
|
|
854
|
+
function cmdInitKnowledgeTasks(args) {
|
|
855
|
+
// Validate required arguments
|
|
856
|
+
if (!args.file || !args.matcherResult || !args.featuresDir) {
|
|
857
|
+
outputError('Usage: init-knowledge-tasks --file <path> --matcher-result <path> --features-dir <dir> [--force]');
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
const filePath = path.resolve(args.file);
|
|
861
|
+
const matcherResultPath = path.resolve(args.matcherResult);
|
|
862
|
+
const featuresDir = path.resolve(args.featuresDir);
|
|
863
|
+
|
|
864
|
+
// Check if matcher result file exists
|
|
865
|
+
if (!fs.existsSync(matcherResultPath)) {
|
|
866
|
+
outputError(`Matcher result file not found: ${matcherResultPath}`);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// Check if features directory exists
|
|
870
|
+
if (!fs.existsSync(featuresDir)) {
|
|
871
|
+
outputError(`Features directory not found: ${featuresDir}`);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// Check if target file already exists (prevent overwrite without --force)
|
|
875
|
+
if (fs.existsSync(filePath) && !args.force) {
|
|
876
|
+
outputError(`Progress file already exists: ${filePath}. Use --force to overwrite.`);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
// Read matcher result
|
|
880
|
+
let matcherResult;
|
|
881
|
+
try {
|
|
882
|
+
matcherResult = readJsonFile(matcherResultPath);
|
|
883
|
+
} catch (e) {
|
|
884
|
+
outputError(`Failed to read matcher result: ${e.message}`);
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
// Extract matched modules (high + medium confidence)
|
|
888
|
+
const matchedModules = matcherResult.matched_modules || [];
|
|
889
|
+
if (matchedModules.length === 0) {
|
|
890
|
+
outputError('No matched modules found in matcher result');
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// Filter to high and medium confidence matches
|
|
894
|
+
const validConfidences = ['high', 'medium'];
|
|
895
|
+
const filteredModules = matchedModules.filter(m =>
|
|
896
|
+
validConfidences.includes((m.confidence || '').toLowerCase())
|
|
897
|
+
);
|
|
898
|
+
|
|
899
|
+
if (filteredModules.length === 0) {
|
|
900
|
+
outputError('No modules with high or medium confidence found');
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
// Scan features-*.json files
|
|
904
|
+
const featuresFiles = fs.readdirSync(featuresDir).filter(f =>
|
|
905
|
+
f.startsWith('features-') && f.endsWith('.json')
|
|
906
|
+
);
|
|
907
|
+
|
|
908
|
+
if (featuresFiles.length === 0) {
|
|
909
|
+
outputError(`No features-*.json files found in: ${featuresDir}`);
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
// Load all features data indexed by platform_id
|
|
913
|
+
const featuresDataByPlatform = {};
|
|
914
|
+
for (const file of featuresFiles) {
|
|
915
|
+
const filePath = path.join(featuresDir, file);
|
|
916
|
+
try {
|
|
917
|
+
const data = readJsonFile(filePath);
|
|
918
|
+
if (data.platform_id) {
|
|
919
|
+
featuresDataByPlatform[data.platform_id] = data;
|
|
920
|
+
}
|
|
921
|
+
} catch (e) {
|
|
922
|
+
outputError(`Failed to parse features file ${file}: ${e.message}`);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// Generate tasks from matched modules and features
|
|
927
|
+
const tasks = [];
|
|
928
|
+
const now = getTimestamp();
|
|
929
|
+
|
|
930
|
+
for (const matchedModule of filteredModules) {
|
|
931
|
+
const { module_name, platform_id, features: matchedFeatures } = matchedModule;
|
|
932
|
+
|
|
933
|
+
// Determine analyzer skill based on platform
|
|
934
|
+
const analyzerSkill = getAnalyzerSkill(platform_id);
|
|
935
|
+
|
|
936
|
+
// Get features for this module
|
|
937
|
+
let featuresToProcess = [];
|
|
938
|
+
|
|
939
|
+
if (matchedFeatures && Array.isArray(matchedFeatures) && matchedFeatures.length > 0) {
|
|
940
|
+
// Use features directly from matcher result
|
|
941
|
+
featuresToProcess = matchedFeatures;
|
|
942
|
+
} else {
|
|
943
|
+
// Look up features from features-*.json files
|
|
944
|
+
const platformData = featuresDataByPlatform[platform_id];
|
|
945
|
+
if (platformData && platformData.modules && platformData.modules[module_name]) {
|
|
946
|
+
const moduleData = platformData.modules[module_name];
|
|
947
|
+
if (moduleData.features && Array.isArray(moduleData.features)) {
|
|
948
|
+
featuresToProcess = moduleData.features;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// Filter to only unanalyzed features (analyzed !== true)
|
|
954
|
+
const unanalyzedFeatures = featuresToProcess.filter(f => f.analyzed !== true);
|
|
955
|
+
|
|
956
|
+
// Create task for each unanalyzed feature
|
|
957
|
+
for (const feature of unanalyzedFeatures) {
|
|
958
|
+
const fileName = feature.fileName || feature.file_name || 'unknown';
|
|
959
|
+
const sourcePath = feature.sourcePath || feature.source_path || '';
|
|
960
|
+
|
|
961
|
+
// Generate task ID: ki-{platform_id}-{module}-{fileName}
|
|
962
|
+
// Sanitize fileName for ID (remove extension, replace special chars)
|
|
963
|
+
const fileNameForId = fileName.replace(/\.[^.]+$/, '').replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
964
|
+
const taskId = `ki-${platform_id}-${module_name}-${fileNameForId}`;
|
|
965
|
+
|
|
966
|
+
tasks.push({
|
|
967
|
+
id: taskId,
|
|
968
|
+
name: `Analyze ${module_name}.${fileName} (${platform_id})`,
|
|
969
|
+
status: 'pending',
|
|
970
|
+
module: module_name,
|
|
971
|
+
platform_id: platform_id,
|
|
972
|
+
fileName: fileName,
|
|
973
|
+
sourcePath: sourcePath,
|
|
974
|
+
analyzer_skill: analyzerSkill,
|
|
975
|
+
created_at: now
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// Sort tasks: by platform_id, then module, then fileName
|
|
981
|
+
tasks.sort((a, b) => {
|
|
982
|
+
if (a.platform_id !== b.platform_id) {
|
|
983
|
+
return a.platform_id.localeCompare(b.platform_id);
|
|
984
|
+
}
|
|
985
|
+
if (a.module !== b.module) {
|
|
986
|
+
return a.module.localeCompare(b.module);
|
|
987
|
+
}
|
|
988
|
+
return a.fileName.localeCompare(b.fileName);
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
// Create progress file structure
|
|
992
|
+
const progressData = {
|
|
993
|
+
stage: 'knowledge_initialization',
|
|
994
|
+
created_at: now,
|
|
995
|
+
updated_at: now,
|
|
996
|
+
counts: calculateCounts(tasks),
|
|
997
|
+
tasks: tasks,
|
|
998
|
+
checkpoints: {}
|
|
999
|
+
};
|
|
1000
|
+
|
|
1001
|
+
// Ensure directory exists
|
|
1002
|
+
const dir = path.dirname(filePath);
|
|
1003
|
+
if (!fs.existsSync(dir)) {
|
|
1004
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// Acquire lock and write
|
|
1008
|
+
let lockPath = null;
|
|
1009
|
+
try {
|
|
1010
|
+
lockPath = acquireLock(filePath);
|
|
1011
|
+
atomicWriteJson(filePath, progressData);
|
|
1012
|
+
outputSuccess(
|
|
1013
|
+
`Generated ${tasks.length} knowledge initialization tasks`,
|
|
1014
|
+
{
|
|
1015
|
+
file: filePath,
|
|
1016
|
+
stage: 'knowledge_initialization',
|
|
1017
|
+
matched_modules: filteredModules.length,
|
|
1018
|
+
counts: progressData.counts
|
|
1019
|
+
}
|
|
1020
|
+
);
|
|
1021
|
+
} finally {
|
|
1022
|
+
if (lockPath) releaseLock(lockPath);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
819
1026
|
/**
|
|
820
1027
|
* Command: init-tasks - Scan feature-design directory to generate task list
|
|
821
1028
|
*/
|
|
@@ -983,6 +1190,7 @@ function main() {
|
|
|
983
1190
|
console.error(' write-checkpoint Write or update a checkpoint');
|
|
984
1191
|
console.error(' update-workflow Update a workflow stage status');
|
|
985
1192
|
console.error(' init-tasks Generate tasks from feature-spec files');
|
|
1193
|
+
console.error(' init-knowledge-tasks Generate knowledge initialization tasks from matcher results');
|
|
986
1194
|
console.error('');
|
|
987
1195
|
console.error('Run "node update-progress.js <command> --help" for more information.');
|
|
988
1196
|
process.exit(1);
|
|
@@ -1012,6 +1220,9 @@ function main() {
|
|
|
1012
1220
|
case 'init-tasks':
|
|
1013
1221
|
cmdInitTasks(args);
|
|
1014
1222
|
break;
|
|
1223
|
+
case 'init-knowledge-tasks':
|
|
1224
|
+
cmdInitKnowledgeTasks(args);
|
|
1225
|
+
break;
|
|
1015
1226
|
default:
|
|
1016
1227
|
outputError(`Unknown command: ${args.command}`);
|
|
1017
1228
|
}
|