@planu/cli 0.27.0 → 0.29.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/dist/config/model-routing-rules.json +98 -0
- package/dist/config/tool-groups.json +140 -0
- package/dist/engine/ai-cost-estimator/core.d.ts +1 -1
- package/dist/engine/ai-cost-estimator/core.d.ts.map +1 -1
- package/dist/engine/ai-cost-estimator/core.js +3 -167
- package/dist/engine/ai-cost-estimator/core.js.map +1 -1
- package/dist/engine/ai-cost-estimator/recommender.d.ts +8 -0
- package/dist/engine/ai-cost-estimator/recommender.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/recommender.js +94 -0
- package/dist/engine/ai-cost-estimator/recommender.js.map +1 -0
- package/dist/engine/ai-cost-estimator/spec-loader.d.ts +13 -0
- package/dist/engine/ai-cost-estimator/spec-loader.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/spec-loader.js +102 -0
- package/dist/engine/ai-cost-estimator/spec-loader.js.map +1 -0
- package/dist/engine/code-transforms/transform-engine.d.ts +7 -0
- package/dist/engine/code-transforms/transform-engine.d.ts.map +1 -0
- package/dist/engine/code-transforms/transform-engine.js +67 -0
- package/dist/engine/code-transforms/transform-engine.js.map +1 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.d.ts +6 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.js +92 -0
- package/dist/engine/code-transforms/typescript/add-error-handling.js.map +1 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.d.ts +6 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.js +83 -0
- package/dist/engine/code-transforms/typescript/add-jsdoc.js.map +1 -0
- package/dist/engine/code-transforms/typescript/add-types.d.ts +3 -0
- package/dist/engine/code-transforms/typescript/add-types.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/add-types.js +182 -0
- package/dist/engine/code-transforms/typescript/add-types.js.map +1 -0
- package/dist/engine/code-transforms/typescript/ast-utils.d.ts +38 -0
- package/dist/engine/code-transforms/typescript/ast-utils.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/ast-utils.js +90 -0
- package/dist/engine/code-transforms/typescript/ast-utils.js.map +1 -0
- package/dist/engine/code-transforms/typescript/extract-interface.d.ts +6 -0
- package/dist/engine/code-transforms/typescript/extract-interface.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/extract-interface.js +103 -0
- package/dist/engine/code-transforms/typescript/extract-interface.js.map +1 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.d.ts +3 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.js +213 -0
- package/dist/engine/code-transforms/typescript/modernize-syntax.js.map +1 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.d.ts +8 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.d.ts.map +1 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.js +40 -0
- package/dist/engine/code-transforms/typescript/rename-symbol.js.map +1 -0
- package/dist/engine/focus-tracker.d.ts.map +1 -1
- package/dist/engine/focus-tracker.js +1 -0
- package/dist/engine/focus-tracker.js.map +1 -1
- package/dist/engine/mermaid/core.d.ts +18 -0
- package/dist/engine/mermaid/core.d.ts.map +1 -0
- package/dist/engine/mermaid/core.js +88 -0
- package/dist/engine/mermaid/core.js.map +1 -0
- package/dist/engine/mermaid/diagram-generators.d.ts +22 -0
- package/dist/engine/mermaid/diagram-generators.d.ts.map +1 -0
- package/dist/engine/mermaid/diagram-generators.js +139 -0
- package/dist/engine/mermaid/diagram-generators.js.map +1 -0
- package/dist/engine/mermaid/helpers.d.ts +8 -0
- package/dist/engine/mermaid/helpers.d.ts.map +1 -0
- package/dist/engine/mermaid/helpers.js +61 -0
- package/dist/engine/mermaid/helpers.js.map +1 -0
- package/dist/engine/mermaid-generator.d.ts +2 -37
- package/dist/engine/mermaid-generator.d.ts.map +1 -1
- package/dist/engine/mermaid-generator.js +4 -276
- package/dist/engine/mermaid-generator.js.map +1 -1
- package/dist/engine/model-router/complexity-analyzer.d.ts +26 -0
- package/dist/engine/model-router/complexity-analyzer.d.ts.map +1 -0
- package/dist/engine/model-router/complexity-analyzer.js +182 -0
- package/dist/engine/model-router/complexity-analyzer.js.map +1 -0
- package/dist/engine/model-router/cost-estimator.d.ts +6 -0
- package/dist/engine/model-router/cost-estimator.d.ts.map +1 -0
- package/dist/engine/model-router/cost-estimator.js +60 -0
- package/dist/engine/model-router/cost-estimator.js.map +1 -0
- package/dist/engine/model-router/historical-learner.d.ts +26 -0
- package/dist/engine/model-router/historical-learner.d.ts.map +1 -0
- package/dist/engine/model-router/historical-learner.js +91 -0
- package/dist/engine/model-router/historical-learner.js.map +1 -0
- package/dist/engine/model-router/rules-engine.d.ts +13 -0
- package/dist/engine/model-router/rules-engine.d.ts.map +1 -0
- package/dist/engine/model-router/rules-engine.js +142 -0
- package/dist/engine/model-router/rules-engine.js.map +1 -0
- package/dist/engine/planu-config-writer.d.ts +2 -2
- package/dist/engine/planu-config-writer.d.ts.map +1 -1
- package/dist/engine/planu-config-writer.js +4 -6
- package/dist/engine/planu-config-writer.js.map +1 -1
- package/dist/engine/spec-coverage/criteria-mapper.d.ts +1 -2
- package/dist/engine/spec-coverage/criteria-mapper.d.ts.map +1 -1
- package/dist/engine/spec-coverage/criteria-mapper.js +4 -203
- package/dist/engine/spec-coverage/criteria-mapper.js.map +1 -1
- package/dist/engine/spec-coverage/keyword-extractor.d.ts +10 -0
- package/dist/engine/spec-coverage/keyword-extractor.d.ts.map +1 -0
- package/dist/engine/spec-coverage/keyword-extractor.js +147 -0
- package/dist/engine/spec-coverage/keyword-extractor.js.map +1 -0
- package/dist/engine/spec-coverage/test-matchers.d.ts +9 -0
- package/dist/engine/spec-coverage/test-matchers.d.ts.map +1 -0
- package/dist/engine/spec-coverage/test-matchers.js +59 -0
- package/dist/engine/spec-coverage/test-matchers.js.map +1 -0
- package/dist/engine/spec-migrator.d.ts +17 -0
- package/dist/engine/spec-migrator.d.ts.map +1 -0
- package/dist/engine/spec-migrator.js +119 -0
- package/dist/engine/spec-migrator.js.map +1 -0
- package/dist/engine/spec-templates/catalog-extra.d.ts +1 -1
- package/dist/engine/spec-templates/catalog-extra.d.ts.map +1 -1
- package/dist/engine/spec-templates/catalog-extra.js +8 -363
- package/dist/engine/spec-templates/catalog-extra.js.map +1 -1
- package/dist/engine/spec-templates/catalog.d.ts.map +1 -1
- package/dist/engine/spec-templates/catalog.js +10 -381
- package/dist/engine/spec-templates/catalog.js.map +1 -1
- package/dist/engine/spec-templates/templates-api-ui.d.ts +6 -0
- package/dist/engine/spec-templates/templates-api-ui.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-api-ui.js +188 -0
- package/dist/engine/spec-templates/templates-api-ui.js.map +1 -0
- package/dist/engine/spec-templates/templates-auth-crud.d.ts +6 -0
- package/dist/engine/spec-templates/templates-auth-crud.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-auth-crud.js +198 -0
- package/dist/engine/spec-templates/templates-auth-crud.js.map +1 -0
- package/dist/engine/spec-templates/templates-data-security.d.ts +6 -0
- package/dist/engine/spec-templates/templates-data-security.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-data-security.js +172 -0
- package/dist/engine/spec-templates/templates-data-security.js.map +1 -0
- package/dist/engine/spec-templates/templates-perf-integration.d.ts +6 -0
- package/dist/engine/spec-templates/templates-perf-integration.d.ts.map +1 -0
- package/dist/engine/spec-templates/templates-perf-integration.js +199 -0
- package/dist/engine/spec-templates/templates-perf-integration.js.map +1 -0
- package/dist/engine/tool-groups/context-analyzer.d.ts +11 -0
- package/dist/engine/tool-groups/context-analyzer.d.ts.map +1 -0
- package/dist/engine/tool-groups/context-analyzer.js +40 -0
- package/dist/engine/tool-groups/context-analyzer.js.map +1 -0
- package/dist/engine/tool-groups/group-manager.d.ts +35 -0
- package/dist/engine/tool-groups/group-manager.d.ts.map +1 -0
- package/dist/engine/tool-groups/group-manager.js +201 -0
- package/dist/engine/tool-groups/group-manager.js.map +1 -0
- package/dist/engine/vector-store/hnsw.d.ts +37 -0
- package/dist/engine/vector-store/hnsw.d.ts.map +1 -0
- package/dist/engine/vector-store/hnsw.js +294 -0
- package/dist/engine/vector-store/hnsw.js.map +1 -0
- package/dist/engine/vector-store/similarity.d.ts +21 -0
- package/dist/engine/vector-store/similarity.d.ts.map +1 -0
- package/dist/engine/vector-store/similarity.js +86 -0
- package/dist/engine/vector-store/similarity.js.map +1 -0
- package/dist/engine/vector-store/tfidf.d.ts +35 -0
- package/dist/engine/vector-store/tfidf.d.ts.map +1 -0
- package/dist/engine/vector-store/tfidf.js +255 -0
- package/dist/engine/vector-store/tfidf.js.map +1 -0
- package/dist/engine/web-fetcher/registry-loader.d.ts.map +1 -1
- package/dist/engine/web-fetcher/registry-loader.js +2 -0
- package/dist/engine/web-fetcher/registry-loader.js.map +1 -1
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/vector-store/backend-factory.d.ts +9 -0
- package/dist/storage/vector-store/backend-factory.d.ts.map +1 -0
- package/dist/storage/vector-store/backend-factory.js +33 -0
- package/dist/storage/vector-store/backend-factory.js.map +1 -0
- package/dist/storage/vector-store/json-fallback.d.ts +21 -0
- package/dist/storage/vector-store/json-fallback.d.ts.map +1 -0
- package/dist/storage/vector-store/json-fallback.js +85 -0
- package/dist/storage/vector-store/json-fallback.js.map +1 -0
- package/dist/storage/vector-store/migrator.d.ts +10 -0
- package/dist/storage/vector-store/migrator.d.ts.map +1 -0
- package/dist/storage/vector-store/migrator.js +139 -0
- package/dist/storage/vector-store/migrator.js.map +1 -0
- package/dist/storage/vector-store/sqlite-adapter.d.ts +28 -0
- package/dist/storage/vector-store/sqlite-adapter.d.ts.map +1 -0
- package/dist/storage/vector-store/sqlite-adapter.js +142 -0
- package/dist/storage/vector-store/sqlite-adapter.js.map +1 -0
- package/dist/tools/create-spec/constitution-validator.d.ts +4 -0
- package/dist/tools/create-spec/constitution-validator.d.ts.map +1 -0
- package/dist/tools/create-spec/constitution-validator.js +37 -0
- package/dist/tools/create-spec/constitution-validator.js.map +1 -0
- package/dist/tools/create-spec/post-creation.d.ts +11 -0
- package/dist/tools/create-spec/post-creation.d.ts.map +1 -0
- package/dist/tools/create-spec/post-creation.js +48 -0
- package/dist/tools/create-spec/post-creation.js.map +1 -0
- package/dist/tools/create-spec/spec-builder.d.ts +14 -0
- package/dist/tools/create-spec/spec-builder.d.ts.map +1 -0
- package/dist/tools/create-spec/spec-builder.js +131 -0
- package/dist/tools/create-spec/spec-builder.js.map +1 -0
- package/dist/tools/create-spec.d.ts.map +1 -1
- package/dist/tools/create-spec.js +42 -172
- package/dist/tools/create-spec.js.map +1 -1
- package/dist/tools/data-governance/audit-handler.d.ts.map +1 -1
- package/dist/tools/data-governance/audit-handler.js +1 -0
- package/dist/tools/data-governance/audit-handler.js.map +1 -1
- package/dist/tools/design-schema.d.ts.map +1 -1
- package/dist/tools/design-schema.js +1 -0
- package/dist/tools/design-schema.js.map +1 -1
- package/dist/tools/init-project/handler.d.ts.map +1 -1
- package/dist/tools/init-project/handler.js +48 -14
- package/dist/tools/init-project/handler.js.map +1 -1
- package/dist/tools/recommend-model-handler.d.ts +8 -0
- package/dist/tools/recommend-model-handler.d.ts.map +1 -0
- package/dist/tools/recommend-model-handler.js +65 -0
- package/dist/tools/recommend-model-handler.js.map +1 -0
- package/dist/tools/register-ai-cost-tools.js +1 -1
- package/dist/tools/register-ai-cost-tools.js.map +1 -1
- package/dist/tools/register-model-tools.d.ts +3 -0
- package/dist/tools/register-model-tools.d.ts.map +1 -0
- package/dist/tools/register-model-tools.js +50 -0
- package/dist/tools/register-model-tools.js.map +1 -0
- package/dist/tools/register-search-tools.d.ts +7 -0
- package/dist/tools/register-search-tools.d.ts.map +1 -0
- package/dist/tools/register-search-tools.js +34 -0
- package/dist/tools/register-search-tools.js.map +1 -0
- package/dist/tools/register-spec-tools/core-spec-tools.d.ts.map +1 -1
- package/dist/tools/register-spec-tools/core-spec-tools.js +0 -4
- package/dist/tools/register-spec-tools/core-spec-tools.js.map +1 -1
- package/dist/tools/register-tool-groups.d.ts +7 -0
- package/dist/tools/register-tool-groups.d.ts.map +1 -0
- package/dist/tools/register-tool-groups.js +39 -0
- package/dist/tools/register-tool-groups.js.map +1 -0
- package/dist/tools/register-transform-tools.d.ts +3 -0
- package/dist/tools/register-transform-tools.d.ts.map +1 -0
- package/dist/tools/register-transform-tools.js +29 -0
- package/dist/tools/register-transform-tools.js.map +1 -0
- package/dist/tools/semantic-search-handler.d.ts +7 -0
- package/dist/tools/semantic-search-handler.d.ts.map +1 -0
- package/dist/tools/semantic-search-handler.js +72 -0
- package/dist/tools/semantic-search-handler.js.map +1 -0
- package/dist/tools/suggest-tooling/orchestration-generator.js +1 -1
- package/dist/tools/suggest-tooling/orchestration-generator.js.map +1 -1
- package/dist/tools/tool-group-handler.d.ts +9 -0
- package/dist/tools/tool-group-handler.d.ts.map +1 -0
- package/dist/tools/tool-group-handler.js +82 -0
- package/dist/tools/tool-group-handler.js.map +1 -0
- package/dist/tools/transform-code-handler.d.ts +7 -0
- package/dist/tools/transform-code-handler.d.ts.map +1 -0
- package/dist/tools/transform-code-handler.js +58 -0
- package/dist/tools/transform-code-handler.js.map +1 -0
- package/dist/types/advanced-framework.d.ts +47 -0
- package/dist/types/advanced-framework.d.ts.map +1 -0
- package/dist/types/advanced-framework.js +3 -0
- package/dist/types/advanced-framework.js.map +1 -0
- package/dist/types/code-transforms.d.ts +114 -0
- package/dist/types/code-transforms.d.ts.map +1 -0
- package/dist/types/code-transforms.js +11 -0
- package/dist/types/code-transforms.js.map +1 -0
- package/dist/types/css-framework.d.ts +110 -0
- package/dist/types/css-framework.d.ts.map +1 -0
- package/dist/types/css-framework.js +3 -0
- package/dist/types/css-framework.js.map +1 -0
- package/dist/types/dashboard.d.ts +77 -0
- package/dist/types/dashboard.d.ts.map +1 -0
- package/dist/types/dashboard.js +2 -0
- package/dist/types/dashboard.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/model-routing.d.ts +127 -0
- package/dist/types/model-routing.d.ts.map +1 -0
- package/dist/types/model-routing.js +3 -0
- package/dist/types/model-routing.js.map +1 -0
- package/dist/types/project/inputs.d.ts +0 -1
- package/dist/types/project/inputs.d.ts.map +1 -1
- package/dist/types/spec/core.d.ts +28 -1
- package/dist/types/spec/core.d.ts.map +1 -1
- package/dist/types/spec/inputs.d.ts +9 -6
- package/dist/types/spec/inputs.d.ts.map +1 -1
- package/dist/types/tool-groups.d.ts +57 -0
- package/dist/types/tool-groups.d.ts.map +1 -0
- package/dist/types/tool-groups.js +3 -0
- package/dist/types/tool-groups.js.map +1 -0
- package/dist/types/ui.d.ts +3 -231
- package/dist/types/ui.d.ts.map +1 -1
- package/dist/types/ui.js +7 -1
- package/dist/types/ui.js.map +1 -1
- package/dist/types/vector-store.d.ts +137 -0
- package/dist/types/vector-store.d.ts.map +1 -0
- package/dist/types/vector-store.js +3 -0
- package/dist/types/vector-store.js.map +1 -0
- package/package.json +1 -1
- package/src/config/model-routing-rules.json +98 -0
- package/src/config/tool-groups.json +140 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// engine/spec-coverage/keyword-extractor.ts — Keyword extraction and test name parsing.
|
|
2
|
+
// Extracted from criteria-mapper.ts to keep file sizes within limits.
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Stop words for heuristic keyword extraction
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
export const STOP_WORDS = new Set([
|
|
7
|
+
'the',
|
|
8
|
+
'a',
|
|
9
|
+
'an',
|
|
10
|
+
'is',
|
|
11
|
+
'are',
|
|
12
|
+
'was',
|
|
13
|
+
'were',
|
|
14
|
+
'be',
|
|
15
|
+
'been',
|
|
16
|
+
'being',
|
|
17
|
+
'have',
|
|
18
|
+
'has',
|
|
19
|
+
'had',
|
|
20
|
+
'do',
|
|
21
|
+
'does',
|
|
22
|
+
'did',
|
|
23
|
+
'will',
|
|
24
|
+
'would',
|
|
25
|
+
'could',
|
|
26
|
+
'should',
|
|
27
|
+
'may',
|
|
28
|
+
'might',
|
|
29
|
+
'shall',
|
|
30
|
+
'must',
|
|
31
|
+
'can',
|
|
32
|
+
'to',
|
|
33
|
+
'of',
|
|
34
|
+
'in',
|
|
35
|
+
'on',
|
|
36
|
+
'at',
|
|
37
|
+
'by',
|
|
38
|
+
'for',
|
|
39
|
+
'with',
|
|
40
|
+
'from',
|
|
41
|
+
'as',
|
|
42
|
+
'and',
|
|
43
|
+
'or',
|
|
44
|
+
'but',
|
|
45
|
+
'not',
|
|
46
|
+
'no',
|
|
47
|
+
'if',
|
|
48
|
+
'when',
|
|
49
|
+
'where',
|
|
50
|
+
'that',
|
|
51
|
+
'which',
|
|
52
|
+
'this',
|
|
53
|
+
'it',
|
|
54
|
+
'its',
|
|
55
|
+
'el',
|
|
56
|
+
'la',
|
|
57
|
+
'los',
|
|
58
|
+
'las',
|
|
59
|
+
'un',
|
|
60
|
+
'una',
|
|
61
|
+
'de',
|
|
62
|
+
'del',
|
|
63
|
+
'en',
|
|
64
|
+
'que',
|
|
65
|
+
'se',
|
|
66
|
+
'por',
|
|
67
|
+
'para',
|
|
68
|
+
'con',
|
|
69
|
+
'al',
|
|
70
|
+
'lo',
|
|
71
|
+
'le',
|
|
72
|
+
'les',
|
|
73
|
+
'y',
|
|
74
|
+
'o',
|
|
75
|
+
]);
|
|
76
|
+
/** Extracts 3-5 meaningful keywords from an AC description text. */
|
|
77
|
+
export function extractKeywords(text) {
|
|
78
|
+
const words = text
|
|
79
|
+
.toLowerCase()
|
|
80
|
+
.replace(/[^a-zA-Z0-9\s_àáéíóúñüÀÁÉÍÓÚÑÜ]/g, ' ')
|
|
81
|
+
.split(/\s+/)
|
|
82
|
+
.filter((w) => w.length >= 3 && !STOP_WORDS.has(w));
|
|
83
|
+
// De-duplicate preserving order
|
|
84
|
+
const seen = new Set();
|
|
85
|
+
const unique = [];
|
|
86
|
+
for (const w of words) {
|
|
87
|
+
if (!seen.has(w)) {
|
|
88
|
+
seen.add(w);
|
|
89
|
+
unique.push(w);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return unique.slice(0, 5);
|
|
93
|
+
}
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Test name extraction helpers
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
/** Patterns for extracting test block names from source code. */
|
|
98
|
+
export const TEST_NAME_PATTERNS = [
|
|
99
|
+
/(?:describe|it|test|context|suite|feature|scenario)\s*\(\s*['"`](.*?)['"`]/g,
|
|
100
|
+
/(?:func\s+Test\w+)\s*\(/g, // Go: func TestXxx(
|
|
101
|
+
/(?:def\s+test_\w+)\s*\(/g, // Python: def test_xxx(
|
|
102
|
+
/#\[test\]\s*(?:fn\s+(\w+))/g, // Rust: #[test] fn name
|
|
103
|
+
/(?:func|fun)\s+(test\w+)\s*\(/gi, // Swift/Kotlin
|
|
104
|
+
];
|
|
105
|
+
/** Extracts the first matching test name from source code. */
|
|
106
|
+
export function extractTestName(content, nearPattern) {
|
|
107
|
+
// Find the line with the pattern match, then look for a nearby test name
|
|
108
|
+
const lines = content.split('\n');
|
|
109
|
+
for (let i = 0; i < lines.length; i++) {
|
|
110
|
+
/* v8 ignore next 1 */
|
|
111
|
+
const line = lines[i] ?? '';
|
|
112
|
+
if (!nearPattern.test(line)) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
// Look in ±5 lines for a test name
|
|
116
|
+
const start = Math.max(0, i - 5);
|
|
117
|
+
const end = Math.min(lines.length - 1, i + 5);
|
|
118
|
+
for (let j = start; j <= end; j++) {
|
|
119
|
+
/* v8 ignore next 1 */
|
|
120
|
+
const nearby = lines[j] ?? '';
|
|
121
|
+
const nameMatch = /(?:describe|it|test|context)\s*\(\s*['"`](.*?)['"`]/.exec(nearby);
|
|
122
|
+
if (nameMatch?.[1]) {
|
|
123
|
+
return nameMatch[1];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return line.trim().slice(0, 80);
|
|
127
|
+
}
|
|
128
|
+
return '';
|
|
129
|
+
}
|
|
130
|
+
/** Extracts all test/describe block names from source code. */
|
|
131
|
+
export function extractAllTestNames(content) {
|
|
132
|
+
const names = [];
|
|
133
|
+
for (const pattern of TEST_NAME_PATTERNS) {
|
|
134
|
+
pattern.lastIndex = 0;
|
|
135
|
+
let match;
|
|
136
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
137
|
+
/* v8 ignore next 1 */
|
|
138
|
+
const name = match[1] ?? match[0];
|
|
139
|
+
/* v8 ignore next 1 */
|
|
140
|
+
if (name) {
|
|
141
|
+
names.push(name);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return names;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=keyword-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-extractor.js","sourceRoot":"","sources":["../../../src/engine/spec-coverage/keyword-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TestMatch, CoverageTestFile } from '../../types/index.js';
|
|
2
|
+
/** Strategy 1: look for AC-ID or AC ID (with space or no dash) in test content. */
|
|
3
|
+
export declare function findDirectReferences(acId: string, testFiles: readonly CoverageTestFile[], testContents: ReadonlyMap<string, string>): TestMatch[];
|
|
4
|
+
/** Strategy 2: look for SPEC-ID in file path or content. */
|
|
5
|
+
export declare function findSpecReferences(specId: string, testFiles: readonly CoverageTestFile[], testContents: ReadonlyMap<string, string>): TestMatch[];
|
|
6
|
+
/** Strategy 3: match keywords from criterion text against test names in files. */
|
|
7
|
+
export declare function findKeywordMatches(keywords: readonly string[], testFiles: readonly CoverageTestFile[], testContents: ReadonlyMap<string, string>): TestMatch[];
|
|
8
|
+
export { extractKeywords } from './keyword-extractor.js';
|
|
9
|
+
//# sourceMappingURL=test-matchers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-matchers.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-coverage/test-matchers.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxE,mFAAmF;AACnF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,SAAS,EAAE,CAkBb;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,SAAS,EAAE,CAgBb;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,SAAS,EAAE,CAqBb;AAGD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// engine/spec-coverage/test-matchers.ts — Test-to-criterion matching strategies.
|
|
2
|
+
// Extracted from criteria-mapper.ts to keep file sizes within limits.
|
|
3
|
+
import { extractTestName, extractAllTestNames } from './keyword-extractor.js';
|
|
4
|
+
/** Strategy 1: look for AC-ID or AC ID (with space or no dash) in test content. */
|
|
5
|
+
export function findDirectReferences(acId, testFiles, testContents) {
|
|
6
|
+
const matches = [];
|
|
7
|
+
// Build regex variants: AC-01, AC01, #AC-01, AC 01
|
|
8
|
+
const acNum = acId.replace('AC-', '');
|
|
9
|
+
const pattern = new RegExp(`\\b(?:AC[-\\s]?${acNum}|#AC-?${acNum})\\b`, 'i');
|
|
10
|
+
for (const tf of testFiles) {
|
|
11
|
+
const content = testContents.get(tf.file) ?? '';
|
|
12
|
+
if (!pattern.test(content)) {
|
|
13
|
+
continue;
|
|
14
|
+
}
|
|
15
|
+
// Extract the test name from the first matching line
|
|
16
|
+
const testName = extractTestName(content, pattern);
|
|
17
|
+
matches.push({ file: tf.file, testName, strategy: 'direct-reference' });
|
|
18
|
+
}
|
|
19
|
+
return matches;
|
|
20
|
+
}
|
|
21
|
+
/** Strategy 2: look for SPEC-ID in file path or content. */
|
|
22
|
+
export function findSpecReferences(specId, testFiles, testContents) {
|
|
23
|
+
const matches = [];
|
|
24
|
+
const specPattern = new RegExp(`\\b${specId.replace('-', '[-_]?')}\\b`, 'i');
|
|
25
|
+
for (const tf of testFiles) {
|
|
26
|
+
const inPath = specPattern.test(tf.file);
|
|
27
|
+
const content = testContents.get(tf.file) ?? '';
|
|
28
|
+
const inContent = specPattern.test(content);
|
|
29
|
+
if (!inPath && !inContent) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const testName = inContent ? extractTestName(content, specPattern) : tf.file;
|
|
33
|
+
matches.push({ file: tf.file, testName, strategy: 'spec-reference' });
|
|
34
|
+
}
|
|
35
|
+
return matches;
|
|
36
|
+
}
|
|
37
|
+
/** Strategy 3: match keywords from criterion text against test names in files. */
|
|
38
|
+
export function findKeywordMatches(keywords, testFiles, testContents) {
|
|
39
|
+
const matches = [];
|
|
40
|
+
for (const tf of testFiles) {
|
|
41
|
+
const content = testContents.get(tf.file) ?? '';
|
|
42
|
+
// Extract all describe/it/test block names
|
|
43
|
+
const testNames = extractAllTestNames(content);
|
|
44
|
+
const combinedText = [...testNames, tf.file].join(' ').toLowerCase();
|
|
45
|
+
const matchCount = keywords.filter((kw) => combinedText.includes(kw.toLowerCase())).length;
|
|
46
|
+
if (matchCount >= 2) {
|
|
47
|
+
matches.push({
|
|
48
|
+
file: tf.file,
|
|
49
|
+
/* v8 ignore next 1 */
|
|
50
|
+
testName: testNames[0] ?? tf.file,
|
|
51
|
+
strategy: 'heuristic',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return matches;
|
|
56
|
+
}
|
|
57
|
+
// Re-export extractKeywords for backward compatibility
|
|
58
|
+
export { extractKeywords } from './keyword-extractor.js';
|
|
59
|
+
//# sourceMappingURL=test-matchers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-matchers.js","sourceRoot":"","sources":["../../../src/engine/spec-coverage/test-matchers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Spec, SpecMigrationResult, SpecMigrationDeps } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Detect specs stored under a legacy location (docs/sdd/specs/).
|
|
4
|
+
* Caller provides the list of specs (from storage layer).
|
|
5
|
+
*/
|
|
6
|
+
export declare function filterLegacySpecs(specs: Spec[]): Spec[];
|
|
7
|
+
/**
|
|
8
|
+
* Migrate legacy specs to planu/specs/ with modern file naming.
|
|
9
|
+
* Moves files on disk and calls the provided updateSpec for each migrated spec.
|
|
10
|
+
* Also rewrites planu.json.
|
|
11
|
+
*/
|
|
12
|
+
export declare function migrateSpecs(projectPath: string, legacySpecs: Spec[], deps: SpecMigrationDeps): Promise<SpecMigrationResult>;
|
|
13
|
+
/**
|
|
14
|
+
* Check if a project path has a planu.json with legacy specLocation.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hasLegacyConfig(projectPath: string): Promise<boolean>;
|
|
17
|
+
//# sourceMappingURL=spec-migrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-migrator.d.ts","sourceRoot":"","sources":["../../src/engine/spec-migrator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAetF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAEvD;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,IAAI,EAAE,EACnB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,mBAAmB,CAAC,CAoB9B;AA8ED;;GAEG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAS3E"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { isLegacyLocation, createPlanuConfig, serializePlanuConfig, } from './planu-config-writer.js';
|
|
2
|
+
import { mkdir, rename, readdir, rmdir, access, writeFile, readFile } from 'node:fs/promises';
|
|
3
|
+
import { join, dirname } from 'node:path';
|
|
4
|
+
const LEGACY_TO_MODERN_NAMES = {
|
|
5
|
+
'HU.md': 'spec.md',
|
|
6
|
+
'FICHA-TECNICA.md': 'technical.md',
|
|
7
|
+
'PROGRESS.md': 'progress.md',
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Detect specs stored under a legacy location (docs/sdd/specs/).
|
|
11
|
+
* Caller provides the list of specs (from storage layer).
|
|
12
|
+
*/
|
|
13
|
+
export function filterLegacySpecs(specs) {
|
|
14
|
+
return specs.filter((s) => isLegacyLocation(s.specPath) || isLegacyLocation(s.technicalPath));
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Migrate legacy specs to planu/specs/ with modern file naming.
|
|
18
|
+
* Moves files on disk and calls the provided updateSpec for each migrated spec.
|
|
19
|
+
* Also rewrites planu.json.
|
|
20
|
+
*/
|
|
21
|
+
export async function migrateSpecs(projectPath, legacySpecs, deps) {
|
|
22
|
+
const errors = [];
|
|
23
|
+
let migratedCount = 0;
|
|
24
|
+
for (const spec of legacySpecs) {
|
|
25
|
+
try {
|
|
26
|
+
await migrateSingleSpec(projectPath, spec, deps);
|
|
27
|
+
migratedCount++;
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
31
|
+
errors.push(`${spec.id}: ${msg}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// Rewrite planu.json with modern config
|
|
35
|
+
const planuConfigPath = join(projectPath, 'planu.json');
|
|
36
|
+
const planuConfig = createPlanuConfig();
|
|
37
|
+
await writeFile(planuConfigPath, serializePlanuConfig(planuConfig), 'utf-8');
|
|
38
|
+
return { migratedCount, errors };
|
|
39
|
+
}
|
|
40
|
+
async function migrateSingleSpec(projectPath, spec, deps) {
|
|
41
|
+
const oldSpecDir = dirname(join(projectPath, spec.specPath));
|
|
42
|
+
const newRelDir = spec.specPath
|
|
43
|
+
.replace(/docs\/sdd\/specs/, 'planu/specs')
|
|
44
|
+
.replace(/\/[^/]+$/, '');
|
|
45
|
+
const newAbsDir = join(projectPath, newRelDir);
|
|
46
|
+
// Create target directory
|
|
47
|
+
await mkdir(newAbsDir, { recursive: true });
|
|
48
|
+
// Move and rename known files
|
|
49
|
+
const dirEntries = await safeReaddir(oldSpecDir);
|
|
50
|
+
for (const entry of dirEntries) {
|
|
51
|
+
const modernName = LEGACY_TO_MODERN_NAMES[entry] ?? entry;
|
|
52
|
+
const src = join(oldSpecDir, entry);
|
|
53
|
+
const dest = join(newAbsDir, modernName);
|
|
54
|
+
await rename(src, dest);
|
|
55
|
+
}
|
|
56
|
+
// Update spec paths in storage
|
|
57
|
+
const updates = {
|
|
58
|
+
specPath: rewritePath(spec.specPath),
|
|
59
|
+
technicalPath: rewritePath(spec.technicalPath),
|
|
60
|
+
};
|
|
61
|
+
if (spec.progressPath) {
|
|
62
|
+
updates.progressPath = rewritePath(spec.progressPath);
|
|
63
|
+
}
|
|
64
|
+
if (spec.executiveReportPath) {
|
|
65
|
+
updates.executiveReportPath = rewritePath(spec.executiveReportPath);
|
|
66
|
+
}
|
|
67
|
+
if (spec.technicalReportPath) {
|
|
68
|
+
updates.technicalReportPath = rewritePath(spec.technicalReportPath);
|
|
69
|
+
}
|
|
70
|
+
if (spec.planPath) {
|
|
71
|
+
updates.planPath = rewritePath(spec.planPath);
|
|
72
|
+
}
|
|
73
|
+
await deps.updateSpec(spec.projectId, spec.id, updates);
|
|
74
|
+
// Cleanup empty legacy directories
|
|
75
|
+
await cleanupEmptyDirs(oldSpecDir);
|
|
76
|
+
}
|
|
77
|
+
function rewritePath(path) {
|
|
78
|
+
return path
|
|
79
|
+
.replace(/docs\/sdd\/specs/, 'planu/specs')
|
|
80
|
+
.replace(/\/HU\.md$/, '/spec.md')
|
|
81
|
+
.replace(/\/FICHA-TECNICA\.md$/, '/technical.md')
|
|
82
|
+
.replace(/\/PROGRESS\.md$/, '/progress.md');
|
|
83
|
+
}
|
|
84
|
+
async function safeReaddir(dir) {
|
|
85
|
+
try {
|
|
86
|
+
return await readdir(dir);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function cleanupEmptyDirs(dir) {
|
|
93
|
+
try {
|
|
94
|
+
const entries = await readdir(dir);
|
|
95
|
+
if (entries.length === 0) {
|
|
96
|
+
await rmdir(dir);
|
|
97
|
+
// Try to clean parent too (e.g., docs/sdd/specs/ itself)
|
|
98
|
+
await cleanupEmptyDirs(dirname(dir));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Directory might not exist or not be empty — safe to ignore
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if a project path has a planu.json with legacy specLocation.
|
|
107
|
+
*/
|
|
108
|
+
export async function hasLegacyConfig(projectPath) {
|
|
109
|
+
try {
|
|
110
|
+
await access(join(projectPath, 'planu.json'));
|
|
111
|
+
const content = await readFile(join(projectPath, 'planu.json'), 'utf-8');
|
|
112
|
+
const config = JSON.parse(content);
|
|
113
|
+
return config.specLocation ? isLegacyLocation(config.specLocation) : false;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=spec-migrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-migrator.js","sourceRoot":"","sources":["../../src/engine/spec-migrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { SpecTemplateEntry } from '../../types/spec-templates.js';
|
|
2
|
-
/** Extra built-in spec templates (data, security, performance). */
|
|
2
|
+
/** Extra built-in spec templates (data, security, performance, integration). */
|
|
3
3
|
export declare const EXTRA_TEMPLATES: SpecTemplateEntry[];
|
|
4
4
|
//# sourceMappingURL=catalog-extra.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalog-extra.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-templates/catalog-extra.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"catalog-extra.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-templates/catalog-extra.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAOvE,gFAAgF;AAChF,eAAO,MAAM,eAAe,EAAE,iBAAiB,EAK9C,CAAC"}
|