speccrew 0.6.13 → 0.6.15
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,32 @@ 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
|
+
>
|
|
451
|
+
> 🛑 **CRITICAL GATE — DO NOT SKIP Steps 2-5**:
|
|
452
|
+
> After matcher completes, you MUST execute Steps 2-5 to deep-initialize the matched modules' knowledge base.
|
|
453
|
+
> DO NOT jump to Phase 2 (Complexity Assessment) or Phase 3 (Requirement Clarification) until ALL Steps complete.
|
|
454
|
+
> The matcher output is INPUT for Step 2, not the final output of Path B.
|
|
455
|
+
> Skipping Steps 2-5 means the PRD will lack descriptions of existing system features.
|
|
456
|
+
>
|
|
425
457
|
> **Path B Step 2: Generate Analyze Task Plan**
|
|
426
458
|
> For EACH matched module, dispatch Worker with `speccrew-pm-module-initializer` skill.
|
|
427
459
|
> This Worker will output a task plan JSON (list of features to analyze + analyzer parameters).
|
|
@@ -449,33 +481,70 @@ No knowledge base exists. A lightweight feature inventory scan is triggered to d
|
|
|
449
481
|
>
|
|
450
482
|
> Wait for ALL module-initializer Workers to complete. Collect all task plan JSON outputs.
|
|
451
483
|
>
|
|
452
|
-
> **Path B Step 3: Execute Feature Analysis**
|
|
453
|
-
> Based on the task plans from Step 2, dispatch Worker for EACH pending feature.
|
|
484
|
+
> **Path B Step 3: Execute Feature Analysis (Dispatch-Tracked)**
|
|
454
485
|
>
|
|
455
|
-
>
|
|
456
|
-
>
|
|
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
|
|
457
491
|
>
|
|
458
|
-
> **
|
|
459
|
-
>
|
|
460
|
-
>
|
|
461
|
-
> -
|
|
462
|
-
>
|
|
463
|
-
>
|
|
464
|
-
>
|
|
465
|
-
>
|
|
466
|
-
>
|
|
467
|
-
>
|
|
468
|
-
>
|
|
469
|
-
>
|
|
470
|
-
>
|
|
471
|
-
>
|
|
472
|
-
>
|
|
473
|
-
>
|
|
474
|
-
>
|
|
475
|
-
>
|
|
476
|
-
>
|
|
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"
|
|
496
|
+
>
|
|
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
|
+
> ```
|
|
477
523
|
>
|
|
478
|
-
>
|
|
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.
|
|
479
548
|
>
|
|
480
549
|
> **Path B Step 4: Generate Module Summaries**
|
|
481
550
|
> For each matched module, dispatch Worker with `speccrew-knowledge-module-summarize` skill:
|
|
@@ -494,6 +563,16 @@ No knowledge base exists. A lightweight feature inventory scan is triggered to d
|
|
|
494
563
|
> After all analyze Workers complete, update each analyzed feature's `analyzed` field to `true` in the corresponding features-*.json file.
|
|
495
564
|
>
|
|
496
565
|
> Only after ALL Steps complete, proceed to Phase 2 (Requirement Clarification).
|
|
566
|
+
>
|
|
567
|
+
> 🛑 **Path B Completion Check**:
|
|
568
|
+
> Before proceeding to Phase 2, verify:
|
|
569
|
+
> - [ ] Step 1.5 completed: DISPATCH-PROGRESS.json created with all tasks
|
|
570
|
+
> - [ ] Step 2 completed: task plan JSON generated for each matched module
|
|
571
|
+
> - [ ] Step 3 completed: analyze Workers dispatched and completed for ALL pending features
|
|
572
|
+
> - [ ] Step 4 completed: module-summarize Workers completed for ALL matched modules
|
|
573
|
+
> - [ ] Step 5 completed: features-*.json updated with analyzed=true
|
|
574
|
+
>
|
|
575
|
+
> If ANY step is incomplete, DO NOT proceed. Execute the missing steps first.
|
|
497
576
|
|
|
498
577
|
4. **IF feature inventory fails**:
|
|
499
578
|
- Report to user: "Project structure scan encountered issues: [specific error]. Continuing without knowledge base context."
|
|
@@ -515,6 +594,10 @@ This context will be passed to Phase 3 (Requirement Clarification) and Phase 4 (
|
|
|
515
594
|
|
|
516
595
|
## Phase 2: Complexity Assessment & Skill Routing
|
|
517
596
|
|
|
597
|
+
> **PRE-CONDITION**: Path B Steps 2-5 must be completed before entering Phase 2.
|
|
598
|
+
> If matched_modules exist but knowledges/bizs/ directories are empty, Path B was not fully executed.
|
|
599
|
+
> Go back and execute the remaining Path B steps.
|
|
600
|
+
|
|
518
601
|
Before starting requirement analysis, assess the requirement complexity to determine the appropriate skill path.
|
|
519
602
|
|
|
520
603
|
### 2.1 Complexity 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
|
}
|