@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,91 @@
|
|
|
1
|
+
// engine/model-router/historical-learner.ts — Learn from past model outcomes.
|
|
2
|
+
// SPEC-076 AC-03
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// In-memory outcome store (JSON persistence is left to the storage layer)
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
let outcomes = [];
|
|
7
|
+
const TIER_ORDER = ['haiku', 'sonnet', 'opus'];
|
|
8
|
+
function tierIndex(tier) {
|
|
9
|
+
return TIER_ORDER.indexOf(tier);
|
|
10
|
+
}
|
|
11
|
+
function tierByIndex(index) {
|
|
12
|
+
const clamped = Math.max(0, Math.min(index, TIER_ORDER.length - 1));
|
|
13
|
+
return TIER_ORDER[clamped] ?? 'sonnet';
|
|
14
|
+
}
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Public API
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
/** Record a model outcome for future learning. */
|
|
19
|
+
export function recordOutcome(outcome) {
|
|
20
|
+
outcomes.push(outcome);
|
|
21
|
+
}
|
|
22
|
+
/** Get all recorded outcomes (for testing / export). */
|
|
23
|
+
export function getOutcomes() {
|
|
24
|
+
return outcomes;
|
|
25
|
+
}
|
|
26
|
+
/** Clear all outcomes (for testing). */
|
|
27
|
+
export function clearOutcomes() {
|
|
28
|
+
outcomes = [];
|
|
29
|
+
}
|
|
30
|
+
/** Load outcomes from an external source (e.g. JSON file). */
|
|
31
|
+
export function loadOutcomes(loaded) {
|
|
32
|
+
outcomes = [...loaded];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Find outcomes whose taskSignature matches the given signature.
|
|
36
|
+
* Uses exact match for now; vector similarity can be added later (SPEC-075).
|
|
37
|
+
*/
|
|
38
|
+
export function findSimilarOutcomes(taskSignature) {
|
|
39
|
+
return outcomes.filter((o) => o.taskSignature === taskSignature);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Compute a task signature from a description or spec ID.
|
|
43
|
+
* For now this is a simple normalisation; in the future it can use embeddings.
|
|
44
|
+
*/
|
|
45
|
+
export function computeTaskSignature(text) {
|
|
46
|
+
return text.trim().toLowerCase().replace(/\s+/g, '-').slice(0, 80);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Given the rules engine recommendation and a task signature,
|
|
50
|
+
* adjust the tier based on historical outcomes.
|
|
51
|
+
* Maximum adjustment: plus or minus 1 tier.
|
|
52
|
+
*/
|
|
53
|
+
export function adjustFromHistory(recommendedModel, taskSignature) {
|
|
54
|
+
const similar = findSimilarOutcomes(taskSignature);
|
|
55
|
+
if (similar.length === 0) {
|
|
56
|
+
return {
|
|
57
|
+
adjustedModel: recommendedModel,
|
|
58
|
+
reason: 'No historical data available.',
|
|
59
|
+
adjusted: false,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const successCount = similar.filter((o) => o.success).length;
|
|
63
|
+
const failCount = similar.length - successCount;
|
|
64
|
+
const successRate = successCount / similar.length;
|
|
65
|
+
// Check if a lighter model was consistently successful
|
|
66
|
+
const lighterSuccesses = similar.filter((o) => o.success && tierIndex(o.modelUsed) < tierIndex(recommendedModel));
|
|
67
|
+
if (lighterSuccesses.length >= 2 && successRate > 0.8) {
|
|
68
|
+
const lighterTier = tierByIndex(tierIndex(recommendedModel) - 1);
|
|
69
|
+
return {
|
|
70
|
+
adjustedModel: lighterTier,
|
|
71
|
+
reason: `Historical data shows a lighter model (${lighterTier}) succeeded ${String(lighterSuccesses.length)} times for similar tasks.`,
|
|
72
|
+
adjusted: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// Check if the recommended model or lighter models frequently failed
|
|
76
|
+
const recFailures = similar.filter((o) => !o.success && tierIndex(o.modelUsed) <= tierIndex(recommendedModel));
|
|
77
|
+
if (recFailures.length >= 2 && failCount > successCount) {
|
|
78
|
+
const heavierTier = tierByIndex(tierIndex(recommendedModel) + 1);
|
|
79
|
+
return {
|
|
80
|
+
adjustedModel: heavierTier,
|
|
81
|
+
reason: `Historical data shows ${String(recFailures.length)} failures at tier ${recommendedModel} or below — upgrading to ${heavierTier}.`,
|
|
82
|
+
adjusted: true,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
adjustedModel: recommendedModel,
|
|
87
|
+
reason: 'Historical data supports the current recommendation.',
|
|
88
|
+
adjusted: false,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=historical-learner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"historical-learner.js","sourceRoot":"","sources":["../../../src/engine/model-router/historical-learner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ComplexitySignals, RoutingRule, RuleCondition, RuleMatch, RulesEngineResult } from '../../types/index.js';
|
|
2
|
+
/** Evaluate a single condition against a signal value. */
|
|
3
|
+
export declare function evaluateCondition(signals: ComplexitySignals, condition: RuleCondition): boolean;
|
|
4
|
+
/** Evaluate a single rule against the given signals. */
|
|
5
|
+
export declare function evaluateRule(signals: ComplexitySignals, rule: RoutingRule): RuleMatch;
|
|
6
|
+
/** Load rules from the built-in config. Custom rules support is left as a hook. */
|
|
7
|
+
export declare function loadRules(customRules?: RoutingRule[]): RoutingRule[];
|
|
8
|
+
/**
|
|
9
|
+
* Evaluate all rules against the given signals and return the best model
|
|
10
|
+
* recommendation with alternatives.
|
|
11
|
+
*/
|
|
12
|
+
export declare function evaluateRules(signals: ComplexitySignals, customRules?: RoutingRule[]): RulesEngineResult;
|
|
13
|
+
//# sourceMappingURL=rules-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules-engine.d.ts","sourceRoot":"","sources":["../../../src/engine/model-router/rules-engine.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EAEjB,WAAW,EAEX,aAAa,EACb,SAAS,EACT,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAyB9B,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CA6B/F;AAMD,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,CAWrF;AAED,mFAAmF;AACnF,wBAAgB,SAAS,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAQpE;AAMD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,iBAAiB,EAC1B,WAAW,CAAC,EAAE,WAAW,EAAE,GAC1B,iBAAiB,CAmDnB"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// engine/model-router/rules-engine.ts — Deterministic rules evaluation for model routing.
|
|
2
|
+
// SPEC-076 AC-02
|
|
3
|
+
import defaultRulesJson from '../../config/model-routing-rules.json' with { type: 'json' };
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Model tier ordering (for tie-breaking: higher index = more capable)
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
const TIER_ORDER = ['haiku', 'sonnet', 'opus'];
|
|
8
|
+
function tierIndex(tier) {
|
|
9
|
+
return TIER_ORDER.indexOf(tier);
|
|
10
|
+
}
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Condition evaluation
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
function getSignalValue(signals, signal) {
|
|
15
|
+
return signals[signal];
|
|
16
|
+
}
|
|
17
|
+
/** Evaluate a single condition against a signal value. */
|
|
18
|
+
export function evaluateCondition(signals, condition) {
|
|
19
|
+
const raw = getSignalValue(signals, condition.signal);
|
|
20
|
+
if (raw === undefined) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const { operator, value } = condition;
|
|
24
|
+
switch (operator) {
|
|
25
|
+
case 'eq':
|
|
26
|
+
return raw === value;
|
|
27
|
+
case 'gt':
|
|
28
|
+
return typeof raw === 'number' && typeof value === 'number' && raw > value;
|
|
29
|
+
case 'gte':
|
|
30
|
+
return typeof raw === 'number' && typeof value === 'number' && raw >= value;
|
|
31
|
+
case 'lt':
|
|
32
|
+
return typeof raw === 'number' && typeof value === 'number' && raw < value;
|
|
33
|
+
case 'lte':
|
|
34
|
+
return typeof raw === 'number' && typeof value === 'number' && raw <= value;
|
|
35
|
+
case 'between': {
|
|
36
|
+
if (typeof raw !== 'number' || !Array.isArray(value)) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
const [lo, hi] = value;
|
|
40
|
+
return raw >= lo && raw <= hi;
|
|
41
|
+
}
|
|
42
|
+
default:
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// Rule evaluation
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
/** Evaluate a single rule against the given signals. */
|
|
50
|
+
export function evaluateRule(signals, rule) {
|
|
51
|
+
// An empty conditions list means "always match" (catch-all)
|
|
52
|
+
if (rule.conditions.length === 0) {
|
|
53
|
+
return { rule, matchRatio: 1, confidence: rule.weight };
|
|
54
|
+
}
|
|
55
|
+
const matches = rule.conditions.filter((c) => evaluateCondition(signals, c));
|
|
56
|
+
const matchRatio = matches.length / rule.conditions.length;
|
|
57
|
+
const confidence = matchRatio * rule.weight;
|
|
58
|
+
return { rule, matchRatio, confidence };
|
|
59
|
+
}
|
|
60
|
+
/** Load rules from the built-in config. Custom rules support is left as a hook. */
|
|
61
|
+
export function loadRules(customRules) {
|
|
62
|
+
const config = defaultRulesJson;
|
|
63
|
+
const base = config.rules;
|
|
64
|
+
if (!customRules || customRules.length === 0) {
|
|
65
|
+
return base;
|
|
66
|
+
}
|
|
67
|
+
// Custom rules have higher priority: prepend them
|
|
68
|
+
return [...customRules, ...base];
|
|
69
|
+
}
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Main evaluation
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
/**
|
|
74
|
+
* Evaluate all rules against the given signals and return the best model
|
|
75
|
+
* recommendation with alternatives.
|
|
76
|
+
*/
|
|
77
|
+
export function evaluateRules(signals, customRules) {
|
|
78
|
+
const rules = loadRules(customRules);
|
|
79
|
+
const matches = rules.map((r) => evaluateRule(signals, r));
|
|
80
|
+
// Only keep matches where at least all conditions matched (matchRatio === 1)
|
|
81
|
+
// unless no rule fully matches, then relax to best partial match
|
|
82
|
+
let fullMatches = matches.filter((m) => m.matchRatio === 1 && m.confidence > 0);
|
|
83
|
+
if (fullMatches.length === 0) {
|
|
84
|
+
fullMatches = matches.filter((m) => m.confidence > 0);
|
|
85
|
+
}
|
|
86
|
+
// Sort by confidence desc, then by tier capability desc (tie-break: more capable wins)
|
|
87
|
+
fullMatches.sort((a, b) => {
|
|
88
|
+
const confDiff = b.confidence - a.confidence;
|
|
89
|
+
if (Math.abs(confDiff) > 0.001) {
|
|
90
|
+
return confDiff;
|
|
91
|
+
}
|
|
92
|
+
return tierIndex(b.rule.result) - tierIndex(a.rule.result);
|
|
93
|
+
});
|
|
94
|
+
const best = fullMatches[0];
|
|
95
|
+
/* c8 ignore next 5 */
|
|
96
|
+
if (!best) {
|
|
97
|
+
// Absolute fallback — should never happen because of the catch-all sonnet rule
|
|
98
|
+
return {
|
|
99
|
+
model: 'sonnet',
|
|
100
|
+
confidence: 0.5,
|
|
101
|
+
reasoning: ['Default: sonnet (no rule matched)'],
|
|
102
|
+
alternatives: [],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const reasoning = buildReasoning(best, signals);
|
|
106
|
+
// Collect alternatives (different model tiers from other matches)
|
|
107
|
+
const seen = new Set([best.rule.result]);
|
|
108
|
+
const alternatives = [];
|
|
109
|
+
for (const m of fullMatches) {
|
|
110
|
+
if (!seen.has(m.rule.result)) {
|
|
111
|
+
seen.add(m.rule.result);
|
|
112
|
+
alternatives.push({ model: m.rule.result, confidence: m.confidence });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
model: best.rule.result,
|
|
117
|
+
confidence: best.confidence,
|
|
118
|
+
reasoning,
|
|
119
|
+
alternatives,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Reasoning builder
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
function buildReasoning(match, signals) {
|
|
126
|
+
const reasons = [];
|
|
127
|
+
reasons.push(`Rule "${match.rule.name}" matched with confidence ${match.confidence.toFixed(2)}.`);
|
|
128
|
+
if (signals.criteriaCount > 15) {
|
|
129
|
+
reasons.push(`High criteria count (${String(signals.criteriaCount)}) suggests a complex task.`);
|
|
130
|
+
}
|
|
131
|
+
if (signals.crossLayerCount > 2) {
|
|
132
|
+
reasons.push(`Cross-layer changes (${String(signals.crossLayerCount)} layers) increase coordination complexity.`);
|
|
133
|
+
}
|
|
134
|
+
if (signals.isReadOnly) {
|
|
135
|
+
reasons.push('Read-only task — a lighter model can handle this efficiently.');
|
|
136
|
+
}
|
|
137
|
+
if (signals.hasSecurityImplications) {
|
|
138
|
+
reasons.push('Security implications detected — a more capable model is recommended.');
|
|
139
|
+
}
|
|
140
|
+
return reasons;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=rules-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules-engine.js","sourceRoot":"","sources":["../../../src/engine/model-router/rules-engine.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,iBAAiB;AAYjB,OAAO,gBAAgB,MAAM,uCAAuC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAE3F,8EAA8E;AAC9E,sEAAsE;AACtE,8EAA8E;AAE9E,MAAM,UAAU,GAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAE5D,SAAS,SAAS,CAAC,IAAe;IAChC,OAAO,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E,SAAS,cAAc,CACrB,OAA0B,EAC1B,MAAc;IAEd,OAAQ,OAAgE,CAAC,MAAM,CAAC,CAAC;AACnF,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,iBAAiB,CAAC,OAA0B,EAAE,SAAwB;IACpF,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;IAEtC,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,IAAI;YACP,OAAO,GAAG,KAAK,KAAK,CAAC;QACvB,KAAK,IAAI;YACP,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,GAAG,GAAG,KAAK,CAAC;QAC7E,KAAK,KAAK;YACR,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,GAAG,IAAI,KAAK,CAAC;QAC9E,KAAK,IAAI;YACP,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,GAAG,GAAG,KAAK,CAAC;QAC7E,KAAK,KAAK;YACR,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,GAAG,IAAI,KAAK,CAAC;QAC9E,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrD,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC;YACvB,OAAO,GAAG,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,CAAC;QAChC,CAAC;QACD;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,wDAAwD;AACxD,MAAM,UAAU,YAAY,CAAC,OAA0B,EAAE,IAAiB;IACxE,4DAA4D;IAC5D,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;IAC3D,MAAM,UAAU,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC;IAE5C,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;AAC1C,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,SAAS,CAAC,WAA2B;IACnD,MAAM,MAAM,GAAG,gBAAsC,CAAC;IACtD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;IAC1B,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,kDAAkD;IAClD,OAAO,CAAC,GAAG,WAAW,EAAE,GAAG,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,OAA0B,EAC1B,WAA2B;IAE3B,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IAE3D,6EAA6E;IAC7E,iEAAiE;IACjE,IAAI,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IAChF,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;IACxD,CAAC;IAED,uFAAuF;IACvF,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACxB,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;QAC7C,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,KAAK,EAAE,CAAC;YAC/B,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAE5B,sBAAsB;IACtB,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,+EAA+E;QAC/E,OAAO;YACL,KAAK,EAAE,QAAQ;YACf,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,CAAC,mCAAmC,CAAC;YAChD,YAAY,EAAE,EAAE;SACjB,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEhD,kEAAkE;IAClE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACpD,MAAM,YAAY,GAA+C,EAAE,CAAC;IACpE,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,SAAS;QACT,YAAY;KACb,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,SAAS,cAAc,CAAC,KAAgB,EAAE,OAA0B;IAClE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,6BAA6B,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAElG,IAAI,OAAO,CAAC,aAAa,GAAG,EAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,IAAI,CAAC,wBAAwB,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,4BAA4B,CAAC,CAAC;IAClG,CAAC;IACD,IAAI,OAAO,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CACV,wBAAwB,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,4CAA4C,CACpG,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;IACxF,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { PlanuConfig } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
|
-
* Create a new PlanuConfig with defaults.
|
|
3
|
+
* Create a new PlanuConfig with defaults. Always uses modern spec location.
|
|
4
4
|
*/
|
|
5
|
-
export declare function createPlanuConfig(
|
|
5
|
+
export declare function createPlanuConfig(): PlanuConfig;
|
|
6
6
|
/**
|
|
7
7
|
* Serialize PlanuConfig to JSON string.
|
|
8
8
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planu-config-writer.d.ts","sourceRoot":"","sources":["../../src/engine/planu-config-writer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKrD;;GAEG;AACH,wBAAgB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"planu-config-writer.d.ts","sourceRoot":"","sources":["../../src/engine/planu-config-writer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKrD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAU/C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEhE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAKA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAE9D"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
const PLANU_CONFIG_VERSION = '1.0.0';
|
|
2
2
|
const DEFAULT_SPEC_LOCATION = 'planu/specs';
|
|
3
3
|
/**
|
|
4
|
-
* Create a new PlanuConfig with defaults.
|
|
4
|
+
* Create a new PlanuConfig with defaults. Always uses modern spec location.
|
|
5
5
|
*/
|
|
6
|
-
export function createPlanuConfig(
|
|
6
|
+
export function createPlanuConfig() {
|
|
7
7
|
const now = new Date().toISOString();
|
|
8
|
-
const location = specLocation ?? DEFAULT_SPEC_LOCATION;
|
|
9
|
-
const isLegacy = location.includes('docs/sdd/specs');
|
|
10
8
|
return {
|
|
11
9
|
version: PLANU_CONFIG_VERSION,
|
|
12
|
-
specLocation:
|
|
13
|
-
specNaming:
|
|
10
|
+
specLocation: DEFAULT_SPEC_LOCATION,
|
|
11
|
+
specNaming: 'modern',
|
|
14
12
|
createdAt: now,
|
|
15
13
|
updatedAt: now,
|
|
16
14
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planu-config-writer.js","sourceRoot":"","sources":["../../src/engine/planu-config-writer.ts"],"names":[],"mappings":"AAGA,MAAM,oBAAoB,GAAG,OAAO,CAAC;AACrC,MAAM,qBAAqB,GAAG,aAAa,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,iBAAiB
|
|
1
|
+
{"version":3,"file":"planu-config-writer.js","sourceRoot":"","sources":["../../src/engine/planu-config-writer.ts"],"names":[],"mappings":"AAGA,MAAM,oBAAoB,GAAG,OAAO,CAAC;AACrC,MAAM,qBAAqB,GAAG,aAAa,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAErC,OAAO;QACL,OAAO,EAAE,oBAAoB;QAC7B,YAAY,EAAE,qBAAqB;QACnC,UAAU,EAAE,QAAQ;QACpB,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;KACf,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAA2B;IAK1D,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;IACnF,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;AACjF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAAoB;IACnD,OAAO,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CriterionCoverage, CoverageTestFile, RawCriterion } from '../../types/index.js';
|
|
2
|
+
export { extractKeywords } from './keyword-extractor.js';
|
|
2
3
|
/**
|
|
3
4
|
* Parses HU.md content and returns a list of acceptance criteria with their
|
|
4
5
|
* identifiers and descriptions. Supports flexible AC formats:
|
|
@@ -13,6 +14,4 @@ export declare function extractCriteria(huContent: string): readonly RawCriterio
|
|
|
13
14
|
* defined in SPEC-068. Returns the full CriterionCoverage for that criterion.
|
|
14
15
|
*/
|
|
15
16
|
export declare function mapTestsToCriterion(criterion: RawCriterion, testFiles: readonly CoverageTestFile[], testContents: ReadonlyMap<string, string>, specId: string): CriterionCoverage;
|
|
16
|
-
/** Extracts 3–5 meaningful keywords from an AC description text. */
|
|
17
|
-
export declare function extractKeywords(text: string): readonly string[];
|
|
18
17
|
//# sourceMappingURL=criteria-mapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"criteria-mapper.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-coverage/criteria-mapper.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EAIjB,gBAAgB,EAChB,YAAY,EACb,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"criteria-mapper.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-coverage/criteria-mapper.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EAIjB,gBAAgB,EAChB,YAAY,EACb,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAMzD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,YAAY,EAAE,CAmC1E;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,YAAY,EACvB,SAAS,EAAE,SAAS,gBAAgB,EAAE,EACtC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACzC,MAAM,EAAE,MAAM,GACb,iBAAiB,CAsCnB"}
|
|
@@ -1,78 +1,9 @@
|
|
|
1
1
|
// engine/spec-coverage/criteria-mapper.ts — Extracts acceptance criteria from
|
|
2
2
|
// HU.md and maps test files to each criterion using 3 strategies.
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
|
|
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
|
-
]);
|
|
3
|
+
import { findDirectReferences, findSpecReferences, findKeywordMatches } from './test-matchers.js';
|
|
4
|
+
import { extractKeywords } from './keyword-extractor.js';
|
|
5
|
+
// Re-export for backward compatibility
|
|
6
|
+
export { extractKeywords } from './keyword-extractor.js';
|
|
76
7
|
// ---------------------------------------------------------------------------
|
|
77
8
|
// AC extraction
|
|
78
9
|
// ---------------------------------------------------------------------------
|
|
@@ -152,136 +83,6 @@ export function mapTestsToCriterion(criterion, testFiles, testContents, specId)
|
|
|
152
83
|
};
|
|
153
84
|
}
|
|
154
85
|
// ---------------------------------------------------------------------------
|
|
155
|
-
// Strategy implementations
|
|
156
|
-
// ---------------------------------------------------------------------------
|
|
157
|
-
/** Strategy 1: look for AC-ID or AC ID (with space or no dash) in test content. */
|
|
158
|
-
function findDirectReferences(acId, testFiles, testContents) {
|
|
159
|
-
const matches = [];
|
|
160
|
-
// Build regex variants: AC-01, AC01, #AC-01, AC 01
|
|
161
|
-
const acNum = acId.replace('AC-', '');
|
|
162
|
-
const pattern = new RegExp(`\\b(?:AC[-\\s]?${acNum}|#AC-?${acNum})\\b`, 'i');
|
|
163
|
-
for (const tf of testFiles) {
|
|
164
|
-
const content = testContents.get(tf.file) ?? '';
|
|
165
|
-
if (!pattern.test(content)) {
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
// Extract the test name from the first matching line
|
|
169
|
-
const testName = extractTestName(content, pattern);
|
|
170
|
-
matches.push({ file: tf.file, testName, strategy: 'direct-reference' });
|
|
171
|
-
}
|
|
172
|
-
return matches;
|
|
173
|
-
}
|
|
174
|
-
/** Strategy 2: look for SPEC-ID in file path or content. */
|
|
175
|
-
function findSpecReferences(specId, testFiles, testContents) {
|
|
176
|
-
const matches = [];
|
|
177
|
-
const specPattern = new RegExp(`\\b${specId.replace('-', '[-_]?')}\\b`, 'i');
|
|
178
|
-
for (const tf of testFiles) {
|
|
179
|
-
const inPath = specPattern.test(tf.file);
|
|
180
|
-
const content = testContents.get(tf.file) ?? '';
|
|
181
|
-
const inContent = specPattern.test(content);
|
|
182
|
-
if (!inPath && !inContent) {
|
|
183
|
-
continue;
|
|
184
|
-
}
|
|
185
|
-
const testName = inContent ? extractTestName(content, specPattern) : tf.file;
|
|
186
|
-
matches.push({ file: tf.file, testName, strategy: 'spec-reference' });
|
|
187
|
-
}
|
|
188
|
-
return matches;
|
|
189
|
-
}
|
|
190
|
-
/** Strategy 3: match keywords from criterion text against test names in files. */
|
|
191
|
-
function findKeywordMatches(keywords, testFiles, testContents) {
|
|
192
|
-
const matches = [];
|
|
193
|
-
for (const tf of testFiles) {
|
|
194
|
-
const content = testContents.get(tf.file) ?? '';
|
|
195
|
-
// Extract all describe/it/test block names
|
|
196
|
-
const testNames = extractAllTestNames(content);
|
|
197
|
-
const combinedText = [...testNames, tf.file].join(' ').toLowerCase();
|
|
198
|
-
const matchCount = keywords.filter((kw) => combinedText.includes(kw.toLowerCase())).length;
|
|
199
|
-
if (matchCount >= 2) {
|
|
200
|
-
matches.push({
|
|
201
|
-
file: tf.file,
|
|
202
|
-
/* v8 ignore next 1 */
|
|
203
|
-
testName: testNames[0] ?? tf.file,
|
|
204
|
-
strategy: 'heuristic',
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return matches;
|
|
209
|
-
}
|
|
210
|
-
// ---------------------------------------------------------------------------
|
|
211
|
-
// Keyword extraction
|
|
212
|
-
// ---------------------------------------------------------------------------
|
|
213
|
-
/** Extracts 3–5 meaningful keywords from an AC description text. */
|
|
214
|
-
export function extractKeywords(text) {
|
|
215
|
-
const words = text
|
|
216
|
-
.toLowerCase()
|
|
217
|
-
.replace(/[^a-zA-Z0-9\s_àáéíóúñüÀÁÉÍÓÚÑÜ]/g, ' ')
|
|
218
|
-
.split(/\s+/)
|
|
219
|
-
.filter((w) => w.length >= 3 && !STOP_WORDS.has(w));
|
|
220
|
-
// De-duplicate preserving order
|
|
221
|
-
const seen = new Set();
|
|
222
|
-
const unique = [];
|
|
223
|
-
for (const w of words) {
|
|
224
|
-
if (!seen.has(w)) {
|
|
225
|
-
seen.add(w);
|
|
226
|
-
unique.push(w);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return unique.slice(0, 5);
|
|
230
|
-
}
|
|
231
|
-
// ---------------------------------------------------------------------------
|
|
232
|
-
// Test name extraction helpers
|
|
233
|
-
// ---------------------------------------------------------------------------
|
|
234
|
-
/** Patterns for extracting test block names from source code. */
|
|
235
|
-
const TEST_NAME_PATTERNS = [
|
|
236
|
-
/(?:describe|it|test|context|suite|feature|scenario)\s*\(\s*['"`](.*?)['"`]/g,
|
|
237
|
-
/(?:func\s+Test\w+)\s*\(/g, // Go: func TestXxx(
|
|
238
|
-
/(?:def\s+test_\w+)\s*\(/g, // Python: def test_xxx(
|
|
239
|
-
/#\[test\]\s*(?:fn\s+(\w+))/g, // Rust: #[test] fn name
|
|
240
|
-
/(?:func|fun)\s+(test\w+)\s*\(/gi, // Swift/Kotlin
|
|
241
|
-
];
|
|
242
|
-
/** Extracts the first matching test name from source code. */
|
|
243
|
-
function extractTestName(content, nearPattern) {
|
|
244
|
-
// Find the line with the pattern match, then look for a nearby test name
|
|
245
|
-
const lines = content.split('\n');
|
|
246
|
-
for (let i = 0; i < lines.length; i++) {
|
|
247
|
-
/* v8 ignore next 1 */
|
|
248
|
-
const line = lines[i] ?? '';
|
|
249
|
-
if (!nearPattern.test(line)) {
|
|
250
|
-
continue;
|
|
251
|
-
}
|
|
252
|
-
// Look in ±5 lines for a test name
|
|
253
|
-
const start = Math.max(0, i - 5);
|
|
254
|
-
const end = Math.min(lines.length - 1, i + 5);
|
|
255
|
-
for (let j = start; j <= end; j++) {
|
|
256
|
-
/* v8 ignore next 1 */
|
|
257
|
-
const nearby = lines[j] ?? '';
|
|
258
|
-
const nameMatch = /(?:describe|it|test|context)\s*\(\s*['"`](.*?)['"`]/.exec(nearby);
|
|
259
|
-
if (nameMatch?.[1]) {
|
|
260
|
-
return nameMatch[1];
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return line.trim().slice(0, 80);
|
|
264
|
-
}
|
|
265
|
-
return '';
|
|
266
|
-
}
|
|
267
|
-
/** Extracts all test/describe block names from source code. */
|
|
268
|
-
function extractAllTestNames(content) {
|
|
269
|
-
const names = [];
|
|
270
|
-
for (const pattern of TEST_NAME_PATTERNS) {
|
|
271
|
-
pattern.lastIndex = 0;
|
|
272
|
-
let match;
|
|
273
|
-
while ((match = pattern.exec(content)) !== null) {
|
|
274
|
-
/* v8 ignore next 1 */
|
|
275
|
-
const name = match[1] ?? match[0];
|
|
276
|
-
/* v8 ignore next 1 */
|
|
277
|
-
if (name) {
|
|
278
|
-
names.push(name);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return names;
|
|
283
|
-
}
|
|
284
|
-
// ---------------------------------------------------------------------------
|
|
285
86
|
// Result builder
|
|
286
87
|
// ---------------------------------------------------------------------------
|
|
287
88
|
function buildResult(acId, description, status, strategy, rawMatches, testFiles) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"criteria-mapper.js","sourceRoot":"","sources":["../../../src/engine/spec-coverage/criteria-mapper.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kEAAkE;
|
|
1
|
+
{"version":3,"file":"criteria-mapper.js","sourceRoot":"","sources":["../../../src/engine/spec-coverage/criteria-mapper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const STOP_WORDS: Set<string>;
|
|
2
|
+
/** Extracts 3-5 meaningful keywords from an AC description text. */
|
|
3
|
+
export declare function extractKeywords(text: string): readonly string[];
|
|
4
|
+
/** Patterns for extracting test block names from source code. */
|
|
5
|
+
export declare const TEST_NAME_PATTERNS: RegExp[];
|
|
6
|
+
/** Extracts the first matching test name from source code. */
|
|
7
|
+
export declare function extractTestName(content: string, nearPattern: RegExp): string;
|
|
8
|
+
/** Extracts all test/describe block names from source code. */
|
|
9
|
+
export declare function extractAllTestNames(content: string): readonly string[];
|
|
10
|
+
//# sourceMappingURL=keyword-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyword-extractor.d.ts","sourceRoot":"","sources":["../../../src/engine/spec-coverage/keyword-extractor.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,UAAU,aAqErB,CAAC;AAEH,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAkB/D;AAMD,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,UAM9B,CAAC;AAEF,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAuB5E;AAED,+DAA+D;AAC/D,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAetE"}
|