zone-ai-agent 0.4.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/.gittignore +4 -0
- package/README.md +36 -0
- package/dist/api/server.js +136 -0
- package/dist/api/server.js.map +1 -0
- package/dist/apply/applyPatchPlan.js +17 -0
- package/dist/apply/applyPatchPlan.js.map +1 -0
- package/dist/apply/canApplyDecision.js +26 -0
- package/dist/apply/canApplyDecision.js.map +1 -0
- package/dist/apply/patchPlan.js +3 -0
- package/dist/apply/patchPlan.js.map +1 -0
- package/dist/apply/renderApplyResult.js +18 -0
- package/dist/apply/renderApplyResult.js.map +1 -0
- package/dist/apply/runApplyFlow.js +40 -0
- package/dist/apply/runApplyFlow.js.map +1 -0
- package/dist/apply/types.js +3 -0
- package/dist/apply/types.js.map +1 -0
- package/dist/audit/auditDiffIntelligence.js +3 -0
- package/dist/audit/auditDiffIntelligence.js.map +1 -0
- package/dist/audit/auditSnapshot.js +87 -0
- package/dist/audit/auditSnapshot.js.map +1 -0
- package/dist/audit/renderAuditDiff.js +64 -0
- package/dist/audit/renderAuditDiff.js.map +1 -0
- package/dist/audit/snapshotDiff.js +53 -0
- package/dist/audit/snapshotDiff.js.map +1 -0
- package/dist/audit/snapshotReader.js +31 -0
- package/dist/audit/snapshotReader.js.map +1 -0
- package/dist/audit/snapshotWriter.js +59 -0
- package/dist/audit/snapshotWriter.js.map +1 -0
- package/dist/ci/evaluateCiResult.js +142 -0
- package/dist/ci/evaluateCiResult.js.map +1 -0
- package/dist/cli/buildGeneratedPatchPlanPreview.js +65 -0
- package/dist/cli/buildGeneratedPatchPlanPreview.js.map +1 -0
- package/dist/cli/colors.js +28 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/diffOutput.js +37 -0
- package/dist/cli/diffOutput.js.map +1 -0
- package/dist/cli/index.js +850 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/loadPatchPlan.js +52 -0
- package/dist/cli/loadPatchPlan.js.map +1 -0
- package/dist/cli/output.js +34 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/parseCliArgs.js +3 -0
- package/dist/cli/parseCliArgs.js.map +1 -0
- package/dist/cli/runGeneratedPatchPlanFlow.js +23 -0
- package/dist/cli/runGeneratedPatchPlanFlow.js.map +1 -0
- package/dist/components/LoginForm.js +64 -0
- package/dist/components/LoginForm.js.map +1 -0
- package/dist/core/analyzeCodePatterns.js +3 -0
- package/dist/core/analyzeCodePatterns.js.map +1 -0
- package/dist/core/applyLlmPatches.js +43 -0
- package/dist/core/applyLlmPatches.js.map +1 -0
- package/dist/core/buildConfidenceBreakdownFromSignals.js +33 -0
- package/dist/core/buildConfidenceBreakdownFromSignals.js.map +1 -0
- package/dist/core/buildDecisionAuditSnapshot.js +18 -0
- package/dist/core/buildDecisionAuditSnapshot.js.map +1 -0
- package/dist/core/buildDecisionTrace.js +113 -0
- package/dist/core/buildDecisionTrace.js.map +1 -0
- package/dist/core/buildFallbackPatchPlan.js +23 -0
- package/dist/core/buildFallbackPatchPlan.js.map +1 -0
- package/dist/core/buildFallbackPlan.js +25 -0
- package/dist/core/buildFallbackPlan.js.map +1 -0
- package/dist/core/buildSchemaAwareContext.js +49 -0
- package/dist/core/buildSchemaAwareContext.js.map +1 -0
- package/dist/core/buildTaskExecutionContext.js +70 -0
- package/dist/core/buildTaskExecutionContext.js.map +1 -0
- package/dist/core/ciEvaluator.js +83 -0
- package/dist/core/ciEvaluator.js.map +1 -0
- package/dist/core/computeRiskScore.js +43 -0
- package/dist/core/computeRiskScore.js.map +1 -0
- package/dist/core/computeRiskScoreDetails.js +106 -0
- package/dist/core/computeRiskScoreDetails.js.map +1 -0
- package/dist/core/confidenceGate.js +83 -0
- package/dist/core/confidenceGate.js.map +1 -0
- package/dist/core/decision/buildDecisionExplanation.js +91 -0
- package/dist/core/decision/buildDecisionExplanation.js.map +1 -0
- package/dist/core/decision/buildDecisionReasonCodes.js +65 -0
- package/dist/core/decision/buildDecisionReasonCodes.js.map +1 -0
- package/dist/core/decision/buildReasonSummaryLine.js +24 -0
- package/dist/core/decision/buildReasonSummaryLine.js.map +1 -0
- package/dist/core/decision/buildRecommendation.js +43 -0
- package/dist/core/decision/buildRecommendation.js.map +1 -0
- package/dist/core/decision/decideExecutionMode.js +125 -0
- package/dist/core/decision/decideExecutionMode.js.map +1 -0
- package/dist/core/decision/decisionReasonCodeMeta.js +91 -0
- package/dist/core/decision/decisionReasonCodeMeta.js.map +1 -0
- package/dist/core/decision/renderDecisionSummary.js +115 -0
- package/dist/core/decision/renderDecisionSummary.js.map +1 -0
- package/dist/core/detectResourceStorage.js +78 -0
- package/dist/core/detectResourceStorage.js.map +1 -0
- package/dist/core/formatOutput.js +53 -0
- package/dist/core/formatOutput.js.map +1 -0
- package/dist/core/intentAwareScore.js +35 -0
- package/dist/core/intentAwareScore.js.map +1 -0
- package/dist/core/loadSavedAgentResult.js +18 -0
- package/dist/core/loadSavedAgentResult.js.map +1 -0
- package/dist/core/normalizeIssues.js +50 -0
- package/dist/core/normalizeIssues.js.map +1 -0
- package/dist/core/normalizeSignals.js +40 -0
- package/dist/core/normalizeSignals.js.map +1 -0
- package/dist/core/output/zoneStageTypes.js +3 -0
- package/dist/core/output/zoneStageTypes.js.map +1 -0
- package/dist/core/patchRiskAnalyzer.js +50 -0
- package/dist/core/patchRiskAnalyzer.js.map +1 -0
- package/dist/core/renderRunAgentResult.js +77 -0
- package/dist/core/renderRunAgentResult.js.map +1 -0
- package/dist/core/result/buildApplyStageResult.js +61 -0
- package/dist/core/result/buildApplyStageResult.js.map +1 -0
- package/dist/core/result/buildCliViewModel.js +79 -0
- package/dist/core/result/buildCliViewModel.js.map +1 -0
- package/dist/core/result/buildConversionStageResult.js +62 -0
- package/dist/core/result/buildConversionStageResult.js.map +1 -0
- package/dist/core/result/buildDecisionStageResult.js +61 -0
- package/dist/core/result/buildDecisionStageResult.js.map +1 -0
- package/dist/core/result/buildExecutionResult.js +148 -0
- package/dist/core/result/buildExecutionResult.js.map +1 -0
- package/dist/core/result/buildPreviewStageResult.js +47 -0
- package/dist/core/result/buildPreviewStageResult.js.map +1 -0
- package/dist/core/result/buildSavedDecisionExplanation.js +52 -0
- package/dist/core/result/buildSavedDecisionExplanation.js.map +1 -0
- package/dist/core/result/buildSavedRecommendation.js +39 -0
- package/dist/core/result/buildSavedRecommendation.js.map +1 -0
- package/dist/core/result/buildStageResultV2.js +52 -0
- package/dist/core/result/buildStageResultV2.js.map +1 -0
- package/dist/core/result/renderBundledResult.js +47 -0
- package/dist/core/result/renderBundledResult.js.map +1 -0
- package/dist/core/result/renderCliResult.js +93 -0
- package/dist/core/result/renderCliResult.js.map +1 -0
- package/dist/core/result/scoreTopRisks.js +205 -0
- package/dist/core/result/scoreTopRisks.js.map +1 -0
- package/dist/core/runAgent.js +210 -0
- package/dist/core/runAgent.js.map +1 -0
- package/dist/core/runFeatureAgent.js +684 -0
- package/dist/core/runFeatureAgent.js.map +1 -0
- package/dist/core/runLlmPatchFlow.js +522 -0
- package/dist/core/runLlmPatchFlow.js.map +1 -0
- package/dist/core/saveAgentResult.js +234 -0
- package/dist/core/saveAgentResult.js.map +1 -0
- package/dist/core/scoring/computeConfidenceBreakdown.js +130 -0
- package/dist/core/scoring/computeConfidenceBreakdown.js.map +1 -0
- package/dist/core/scoring/computeConfidenceScore.js +37 -0
- package/dist/core/scoring/computeConfidenceScore.js.map +1 -0
- package/dist/core/scoring/confidenceRules.js +58 -0
- package/dist/core/scoring/confidenceRules.js.map +1 -0
- package/dist/core/scoring/confidenceScore.js +8 -0
- package/dist/core/scoring/confidenceScore.js.map +1 -0
- package/dist/core/selectRelevantBlocks.js +58 -0
- package/dist/core/selectRelevantBlocks.js.map +1 -0
- package/dist/core/selfHealingLoop.js +209 -0
- package/dist/core/selfHealingLoop.js.map +1 -0
- package/dist/core/taskIntentParser.js +165 -0
- package/dist/core/taskIntentParser.js.map +1 -0
- package/dist/core/types/agentResult.js +3 -0
- package/dist/core/types/agentResult.js.map +1 -0
- package/dist/core/types/risk.js +3 -0
- package/dist/core/types/risk.js.map +1 -0
- package/dist/core/validatePatchAgainstSchema.js +100 -0
- package/dist/core/validatePatchAgainstSchema.js.map +1 -0
- package/dist/core/validateSuggestedArchitecture.js +24 -0
- package/dist/core/validateSuggestedArchitecture.js.map +1 -0
- package/dist/engine/buildDecisionExplanation.js +114 -0
- package/dist/engine/buildDecisionExplanation.js.map +1 -0
- package/dist/engine/contradictionDetector.js +40 -0
- package/dist/engine/contradictionDetector.js.map +1 -0
- package/dist/engine/decisionEngine.js +19 -0
- package/dist/engine/decisionEngine.js.map +1 -0
- package/dist/llm/openaiClient.js +19 -0
- package/dist/llm/openaiClient.js.map +1 -0
- package/dist/llm/planFeature.js +57 -0
- package/dist/llm/planFeature.js.map +1 -0
- package/dist/llm/planFix.js +3 -0
- package/dist/llm/planFix.js.map +1 -0
- package/dist/llm/planFullPatch.js +62 -0
- package/dist/llm/planFullPatch.js.map +1 -0
- package/dist/llm/planPatchPreview.js +60 -0
- package/dist/llm/planPatchPreview.js.map +1 -0
- package/dist/llm/prompts.js +131 -0
- package/dist/llm/prompts.js.map +1 -0
- package/dist/llm/schemas.js +28 -0
- package/dist/llm/schemas.js.map +1 -0
- package/dist/patch/apply/formatApplyFlowResult.js +23 -0
- package/dist/patch/apply/formatApplyFlowResult.js.map +1 -0
- package/dist/patch/apply/renderApplyFlowResult.js +15 -0
- package/dist/patch/apply/renderApplyFlowResult.js.map +1 -0
- package/dist/patch/apply/runApplyFlow.js +88 -0
- package/dist/patch/apply/runApplyFlow.js.map +1 -0
- package/dist/patch/applyFlowTypes.js +3 -0
- package/dist/patch/applyFlowTypes.js.map +1 -0
- package/dist/patch/applyPatchPlan.js +117 -0
- package/dist/patch/applyPatchPlan.js.map +1 -0
- package/dist/patch/backupFile.js +23 -0
- package/dist/patch/backupFile.js.map +1 -0
- package/dist/patch/conversion/canConvertGeneratedPlanToPatchPlan.js +57 -0
- package/dist/patch/conversion/canConvertGeneratedPlanToPatchPlan.js.map +1 -0
- package/dist/patch/conversion/convertGeneratedPlanToPatchPlan.js +38 -0
- package/dist/patch/conversion/convertGeneratedPlanToPatchPlan.js.map +1 -0
- package/dist/patch/conversion/formatGeneratedPlanConversionFailure.js +17 -0
- package/dist/patch/conversion/formatGeneratedPlanConversionFailure.js.map +1 -0
- package/dist/patch/conversion/generatedPlanConversionFailureMeta.js +40 -0
- package/dist/patch/conversion/generatedPlanConversionFailureMeta.js.map +1 -0
- package/dist/patch/conversion/generatedPlanConversionTypes.js +3 -0
- package/dist/patch/conversion/generatedPlanConversionTypes.js.map +1 -0
- package/dist/patch/conversion/renderGeneratedPlanConversionFailure.js +16 -0
- package/dist/patch/conversion/renderGeneratedPlanConversionFailure.js.map +1 -0
- package/dist/patch/generatedPlanConversion.js +96 -0
- package/dist/patch/generatedPlanConversion.js.map +1 -0
- package/dist/patch/patchAnchors.js +3 -0
- package/dist/patch/patchAnchors.js.map +1 -0
- package/dist/patch/patchValidationRules.js +116 -0
- package/dist/patch/patchValidationRules.js.map +1 -0
- package/dist/patch/patchValidationTypes.js +3 -0
- package/dist/patch/patchValidationTypes.js.map +1 -0
- package/dist/patch/renderApplyFlowResult.js +26 -0
- package/dist/patch/renderApplyFlowResult.js.map +1 -0
- package/dist/patch/validatePatchPlan.js +148 -0
- package/dist/patch/validatePatchPlan.js.map +1 -0
- package/dist/patch-generation/buildGeneratedPatchPlan.js +94 -0
- package/dist/patch-generation/buildGeneratedPatchPlan.js.map +1 -0
- package/dist/patch-generation/buildPatchOperations.js +41 -0
- package/dist/patch-generation/buildPatchOperations.js.map +1 -0
- package/dist/patch-generation/classifyPatchIntent.js +62 -0
- package/dist/patch-generation/classifyPatchIntent.js.map +1 -0
- package/dist/patch-generation/formatGeneratedPatchPlanPreview.js +25 -0
- package/dist/patch-generation/formatGeneratedPatchPlanPreview.js.map +1 -0
- package/dist/patch-generation/generatePatchPlan.js +74 -0
- package/dist/patch-generation/generatePatchPlan.js.map +1 -0
- package/dist/patch-generation/generatedPatchPlanTypes.js +3 -0
- package/dist/patch-generation/generatedPatchPlanTypes.js.map +1 -0
- package/dist/patch-generation/isIntentAllowed.js +15 -0
- package/dist/patch-generation/isIntentAllowed.js.map +1 -0
- package/dist/patch-generation/renderGeneratedPatchPlan.js +62 -0
- package/dist/patch-generation/renderGeneratedPatchPlan.js.map +1 -0
- package/dist/prompts/developerPrompt.js +213 -0
- package/dist/prompts/developerPrompt.js.map +1 -0
- package/dist/prompts/fullPatchPrompt.js +82 -0
- package/dist/prompts/fullPatchPrompt.js.map +1 -0
- package/dist/prompts/patchPreviewPrompt.js +83 -0
- package/dist/prompts/patchPreviewPrompt.js.map +1 -0
- package/dist/prompts/planFeaturePrompt.js +73 -0
- package/dist/prompts/planFeaturePrompt.js.map +1 -0
- package/dist/prompts/testEngineerContext.js +184 -0
- package/dist/prompts/testEngineerContext.js.map +1 -0
- package/dist/prompts/testEngineerPrompt.js +135 -0
- package/dist/prompts/testEngineerPrompt.js.map +1 -0
- package/dist/repo/analyzeProjectPatterns.js +46 -0
- package/dist/repo/analyzeProjectPatterns.js.map +1 -0
- package/dist/repo/detectProjectStructure.js +45 -0
- package/dist/repo/detectProjectStructure.js.map +1 -0
- package/dist/repo/getGitChangedFiles.js +96 -0
- package/dist/repo/getGitChangedFiles.js.map +1 -0
- package/dist/repo/loadSchemaSnapshot.js +29 -0
- package/dist/repo/loadSchemaSnapshot.js.map +1 -0
- package/dist/repo/rankRelevantFiles.js +306 -0
- package/dist/repo/rankRelevantFiles.js.map +1 -0
- package/dist/repo/readProjectFiles.js +27 -0
- package/dist/repo/readProjectFiles.js.map +1 -0
- package/dist/repo/scanRepo.js +93 -0
- package/dist/repo/scanRepo.js.map +1 -0
- package/dist/repo/validateSuggestedFiles.js +66 -0
- package/dist/repo/validateSuggestedFiles.js.map +1 -0
- package/dist/roles/dataAnalystContext.js +155 -0
- package/dist/roles/dataAnalystContext.js.map +1 -0
- package/dist/roles/detectDataSchema.js +152 -0
- package/dist/roles/detectDataSchema.js.map +1 -0
- package/dist/roles/detectTestComplexity.js +74 -0
- package/dist/roles/detectTestComplexity.js.map +1 -0
- package/dist/roles/detectTestFramework.js +166 -0
- package/dist/roles/detectTestFramework.js.map +1 -0
- package/dist/roles/runDataAnalystFlow.js +221 -0
- package/dist/roles/runDataAnalystFlow.js.map +1 -0
- package/dist/roles/runTestEngineerFlow.js +266 -0
- package/dist/roles/runTestEngineerFlow.js.map +1 -0
- package/dist/roles/testEngineerContext.js +282 -0
- package/dist/roles/testEngineerContext.js.map +1 -0
- package/dist/roles/testOutputValidator.js +474 -0
- package/dist/roles/testOutputValidator.js.map +1 -0
- package/dist/types/agent.js +3 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/analysis.js +3 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/types/patch.js +3 -0
- package/dist/types/patch.js.map +1 -0
- package/dist/types/project.js +3 -0
- package/dist/types/project.js.map +1 -0
- package/dist/types/schema.js +3 -0
- package/dist/types/schema.js.map +1 -0
- package/dist/utils/executionTracker.js +33 -0
- package/dist/utils/executionTracker.js.map +1 -0
- package/dist/utils/files.js +35 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/logger.js +179 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.js +14 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/trace.js +10 -0
- package/dist/utils/trace.js.map +1 -0
- package/dist/utils/validation.js +24 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +53 -0
- package/tsconfig.json +17 -0
- package/vitest.config.ts +21 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.runSelfHealingLoop = runSelfHealingLoop;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
function extractErrorContext(errorMessage) {
|
|
10
|
+
// TypeError: X is not a constructor
|
|
11
|
+
if (errorMessage.includes("is not a constructor")) {
|
|
12
|
+
const match = errorMessage.match(/(\w+)\.default is not a constructor/);
|
|
13
|
+
const className = match?.[1] ?? "Unknown";
|
|
14
|
+
return {
|
|
15
|
+
type: "EXPORT_ERROR",
|
|
16
|
+
description: `${className} is exported as an instance, not a class`,
|
|
17
|
+
hint: `Change "export default new ${className}()" to "export default ${className}"`,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// TypeError: X is not a function
|
|
21
|
+
if (errorMessage.includes("is not a function")) {
|
|
22
|
+
const match = errorMessage.match(/(\w+\.?\w+) is not a function/);
|
|
23
|
+
const fnName = match?.[1] ?? "unknown";
|
|
24
|
+
return {
|
|
25
|
+
type: "METHOD_ERROR",
|
|
26
|
+
description: `Method "${fnName}" does not exist`,
|
|
27
|
+
hint: `Check the method name in the page object — it may be named differently`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// Cannot find module
|
|
31
|
+
if (errorMessage.includes("Cannot find module") ||
|
|
32
|
+
errorMessage.includes("Module not found")) {
|
|
33
|
+
const match = errorMessage.match(/['"]([^'"]+)['"]/);
|
|
34
|
+
const modulePath = match?.[1] ?? "unknown";
|
|
35
|
+
return {
|
|
36
|
+
type: "IMPORT_ERROR",
|
|
37
|
+
description: `Module not found: ${modulePath}`,
|
|
38
|
+
hint: `Check the import path — use relative paths like "../../support/pageObjects/LoginPage"`,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
// Timed out
|
|
42
|
+
if (errorMessage.includes("Timed out") || errorMessage.includes("timeout")) {
|
|
43
|
+
return {
|
|
44
|
+
type: "TIMEOUT_ERROR",
|
|
45
|
+
description: "Page or element load timeout",
|
|
46
|
+
hint: `Use cy.visit("/") instead of absolute URLs when baseUrl is configured`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// AssertionError
|
|
50
|
+
if (errorMessage.includes("AssertionError") ||
|
|
51
|
+
errorMessage.includes("expected") && errorMessage.includes("but got")) {
|
|
52
|
+
return {
|
|
53
|
+
type: "ASSERTION_ERROR",
|
|
54
|
+
description: "Test assertion failed",
|
|
55
|
+
hint: `Check the expected value — the actual value from the page may differ`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
type: "UNKNOWN_ERROR",
|
|
60
|
+
description: errorMessage.slice(0, 200),
|
|
61
|
+
hint: "Review the error and fix the affected file",
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function buildHealingPrompt(input) {
|
|
65
|
+
const relatedSection = input.relatedFiles.length > 0
|
|
66
|
+
? input.relatedFiles
|
|
67
|
+
.map((f) => `FILE: ${f.path}\n\`\`\`\n${f.content}\n\`\`\``)
|
|
68
|
+
.join("\n\n")
|
|
69
|
+
: "(no related files)";
|
|
70
|
+
return `
|
|
71
|
+
You are fixing a test automation error.
|
|
72
|
+
|
|
73
|
+
ORIGINAL TASK
|
|
74
|
+
${input.task}
|
|
75
|
+
|
|
76
|
+
ERROR TYPE
|
|
77
|
+
${input.errorContext.type}
|
|
78
|
+
|
|
79
|
+
ERROR DESCRIPTION
|
|
80
|
+
${input.errorContext.description}
|
|
81
|
+
|
|
82
|
+
FIX HINT
|
|
83
|
+
${input.errorContext.hint}
|
|
84
|
+
|
|
85
|
+
FILE TO FIX
|
|
86
|
+
${input.filePath}
|
|
87
|
+
|
|
88
|
+
CURRENT FILE CONTENT
|
|
89
|
+
\`\`\`
|
|
90
|
+
${input.fileContent}
|
|
91
|
+
\`\`\`
|
|
92
|
+
|
|
93
|
+
RELATED FILES (for reference)
|
|
94
|
+
${relatedSection}
|
|
95
|
+
|
|
96
|
+
STRICT RULES
|
|
97
|
+
1. Fix ONLY the specific error described above
|
|
98
|
+
2. Do not change unrelated code
|
|
99
|
+
3. For EXPORT_ERROR: change "export default new ClassName()" to "export default ClassName"
|
|
100
|
+
4. For METHOD_ERROR: use ONLY method names that exist in the related files
|
|
101
|
+
5. For IMPORT_ERROR: use correct relative import paths
|
|
102
|
+
6. For TIMEOUT_ERROR: use cy.visit("/") not absolute URLs
|
|
103
|
+
7. Return the COMPLETE fixed file content
|
|
104
|
+
8. Return raw JSON only — no markdown
|
|
105
|
+
|
|
106
|
+
OUTPUT FORMAT
|
|
107
|
+
{
|
|
108
|
+
"filePath": "${input.filePath}",
|
|
109
|
+
"fullContent": "complete fixed file content",
|
|
110
|
+
"summary": "what was fixed",
|
|
111
|
+
"warnings": []
|
|
112
|
+
}
|
|
113
|
+
`.trim();
|
|
114
|
+
}
|
|
115
|
+
async function runSelfHealingLoop(input) {
|
|
116
|
+
const maxAttempts = input.maxAttempts ?? 3;
|
|
117
|
+
const attempts = [];
|
|
118
|
+
let currentError = input.errorMessage;
|
|
119
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
120
|
+
console.log(`[zone:heal] Attempt ${attempt}/${maxAttempts} — analyzing error...`);
|
|
121
|
+
const errorContext = extractErrorContext(currentError);
|
|
122
|
+
console.log(`[zone:heal] Error type: ${errorContext.type}`);
|
|
123
|
+
console.log(`[zone:heal] Hint: ${errorContext.hint}`);
|
|
124
|
+
const filesChanged = [];
|
|
125
|
+
let anyFixed = false;
|
|
126
|
+
for (const affectedFile of input.affectedFiles) {
|
|
127
|
+
const absolutePath = node_path_1.default.resolve(input.repoPath, affectedFile.filePath);
|
|
128
|
+
// Read related files for context
|
|
129
|
+
const allFilesInDir = await getRelatedFiles(node_path_1.default.dirname(absolutePath), input.repoPath);
|
|
130
|
+
const prompt = buildHealingPrompt({
|
|
131
|
+
task: input.task,
|
|
132
|
+
errorContext,
|
|
133
|
+
filePath: affectedFile.filePath,
|
|
134
|
+
fileContent: affectedFile.fullContent,
|
|
135
|
+
relatedFiles: allFilesInDir,
|
|
136
|
+
});
|
|
137
|
+
try {
|
|
138
|
+
const { createOpenAIClient, getModelName } = await import("../llm/openaiClient.js");
|
|
139
|
+
const client = createOpenAIClient();
|
|
140
|
+
const model = getModelName();
|
|
141
|
+
const response = await client.responses.create({
|
|
142
|
+
model,
|
|
143
|
+
input: prompt,
|
|
144
|
+
});
|
|
145
|
+
const rawText = response.output_text || "";
|
|
146
|
+
const firstBrace = rawText.indexOf("{");
|
|
147
|
+
const lastBrace = rawText.lastIndexOf("}");
|
|
148
|
+
if (firstBrace < 0 || lastBrace < 0)
|
|
149
|
+
continue;
|
|
150
|
+
const parsed = JSON.parse(rawText.slice(firstBrace, lastBrace + 1));
|
|
151
|
+
if (parsed.fullContent) {
|
|
152
|
+
await node_fs_1.promises.mkdir(node_path_1.default.dirname(absolutePath), { recursive: true });
|
|
153
|
+
await node_fs_1.promises.writeFile(absolutePath, parsed.fullContent, "utf8");
|
|
154
|
+
filesChanged.push(affectedFile.filePath);
|
|
155
|
+
anyFixed = true;
|
|
156
|
+
console.log(`[zone:heal] Fixed: ${affectedFile.filePath} — ${parsed.summary}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
console.error(`[zone:heal] Failed to fix ${affectedFile.filePath}: ${err instanceof Error ? err.message : String(err)}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
attempts.push({
|
|
164
|
+
attempt,
|
|
165
|
+
error: currentError,
|
|
166
|
+
fixed: anyFixed,
|
|
167
|
+
filesChanged,
|
|
168
|
+
});
|
|
169
|
+
if (anyFixed) {
|
|
170
|
+
return {
|
|
171
|
+
healed: true,
|
|
172
|
+
attempts,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
healed: false,
|
|
178
|
+
attempts,
|
|
179
|
+
finalError: currentError,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
async function getRelatedFiles(dir, repoPath) {
|
|
183
|
+
try {
|
|
184
|
+
const entries = await node_fs_1.promises.readdir(dir, { withFileTypes: true });
|
|
185
|
+
const jsFiles = entries
|
|
186
|
+
.filter((e) => e.isFile() &&
|
|
187
|
+
(e.name.endsWith(".js") ||
|
|
188
|
+
e.name.endsWith(".ts") ||
|
|
189
|
+
e.name.endsWith(".java")))
|
|
190
|
+
.slice(0, 4);
|
|
191
|
+
const results = [];
|
|
192
|
+
for (const file of jsFiles) {
|
|
193
|
+
const absPath = node_path_1.default.join(dir, file.name);
|
|
194
|
+
const relPath = node_path_1.default.relative(repoPath, absPath).replace(/\\/g, "/");
|
|
195
|
+
try {
|
|
196
|
+
const content = await node_fs_1.promises.readFile(absPath, "utf8");
|
|
197
|
+
results.push({ path: relPath, content });
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// skip unreadable files
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return results;
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=selfHealingLoop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selfHealingLoop.js","sourceRoot":"","sources":["../../src/core/selfHealingLoop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseTaskIntent = parseTaskIntent;
|
|
4
|
+
const UPDATE_WORDS = ["edit", "update", "modify", "change", "patch"];
|
|
5
|
+
const DELETE_WORDS = ["delete", "remove"];
|
|
6
|
+
const CREATE_WORDS = ["create", "add", "insert"];
|
|
7
|
+
const READ_WORDS = ["get", "fetch", "show", "read", "list"];
|
|
8
|
+
const COLLECTION_HINTS = ["all ", "list ", "many ", "multiple ", "bulk "];
|
|
9
|
+
const NESTED_ITEM_WORDS = [
|
|
10
|
+
"item",
|
|
11
|
+
"entry",
|
|
12
|
+
"sub-item",
|
|
13
|
+
"sub item",
|
|
14
|
+
"nested",
|
|
15
|
+
"timeline item",
|
|
16
|
+
"timeline entry",
|
|
17
|
+
"comment item",
|
|
18
|
+
"line item",
|
|
19
|
+
"note",
|
|
20
|
+
"notes",
|
|
21
|
+
"attachment",
|
|
22
|
+
"attachments",
|
|
23
|
+
"comment",
|
|
24
|
+
"comments",
|
|
25
|
+
"stage",
|
|
26
|
+
"step"
|
|
27
|
+
];
|
|
28
|
+
const PARENT_RESOURCE_WORDS = [
|
|
29
|
+
"record",
|
|
30
|
+
"treatment",
|
|
31
|
+
"patient",
|
|
32
|
+
"appointment",
|
|
33
|
+
"lead",
|
|
34
|
+
"clinic",
|
|
35
|
+
"analysis"
|
|
36
|
+
];
|
|
37
|
+
const KNOWN_PARENT_RESOURCES = [
|
|
38
|
+
"treatment",
|
|
39
|
+
"patient",
|
|
40
|
+
"appointment",
|
|
41
|
+
"lead",
|
|
42
|
+
"clinic",
|
|
43
|
+
"analysis"
|
|
44
|
+
];
|
|
45
|
+
const KNOWN_NESTED_MAP = [
|
|
46
|
+
{
|
|
47
|
+
match: /\btimeline\b/i,
|
|
48
|
+
parent: "treatment",
|
|
49
|
+
nested: "timeline",
|
|
50
|
+
paramHints: ["treatmentId", "timelineId"],
|
|
51
|
+
routeHints: ["/treatments/:treatmentId/timeline/:timelineId"]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
match: /\bnote(s)?\b/i,
|
|
55
|
+
parent: "patient",
|
|
56
|
+
nested: "notes",
|
|
57
|
+
paramHints: ["patientId", "noteId"],
|
|
58
|
+
routeHints: ["/patients/:patientId/notes/:noteId"]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
match: /\battachment(s)?\b/i,
|
|
62
|
+
parent: "patient",
|
|
63
|
+
nested: "attachments",
|
|
64
|
+
paramHints: ["patientId", "attachmentId"],
|
|
65
|
+
routeHints: ["/patients/:patientId/attachments/:attachmentId"]
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
match: /\bcomment(s)?\b/i,
|
|
69
|
+
parent: "patient",
|
|
70
|
+
nested: "comments",
|
|
71
|
+
paramHints: ["patientId", "commentId"],
|
|
72
|
+
routeHints: ["/patients/:patientId/comments/:commentId"]
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
function normalizeTask(task) {
|
|
76
|
+
return task.trim().toLowerCase().replace(/\s+/g, " ");
|
|
77
|
+
}
|
|
78
|
+
function includesAny(text, words) {
|
|
79
|
+
return words.some((word) => text.includes(word));
|
|
80
|
+
}
|
|
81
|
+
function detectAction(task) {
|
|
82
|
+
if (includesAny(task, DELETE_WORDS))
|
|
83
|
+
return "delete";
|
|
84
|
+
if (includesAny(task, UPDATE_WORDS))
|
|
85
|
+
return "update";
|
|
86
|
+
if (includesAny(task, CREATE_WORDS))
|
|
87
|
+
return "create";
|
|
88
|
+
if (includesAny(task, READ_WORDS))
|
|
89
|
+
return "read";
|
|
90
|
+
return "unknown";
|
|
91
|
+
}
|
|
92
|
+
function detectParentResource(task) {
|
|
93
|
+
return KNOWN_PARENT_RESOURCES.find((resource) => task.includes(resource));
|
|
94
|
+
}
|
|
95
|
+
function detectScope(input) {
|
|
96
|
+
if (includesAny(input.normalizedTask, COLLECTION_HINTS)) {
|
|
97
|
+
return "collection";
|
|
98
|
+
}
|
|
99
|
+
if (input.mentionsNestedItem) {
|
|
100
|
+
return "single_item";
|
|
101
|
+
}
|
|
102
|
+
if (input.action === "read" && input.normalizedTask.includes("by id")) {
|
|
103
|
+
return "single_item";
|
|
104
|
+
}
|
|
105
|
+
if (input.action === "unknown") {
|
|
106
|
+
return "unknown";
|
|
107
|
+
}
|
|
108
|
+
return "parent_record";
|
|
109
|
+
}
|
|
110
|
+
function parseTaskIntent(rawTask) {
|
|
111
|
+
const normalizedTask = normalizeTask(rawTask);
|
|
112
|
+
const warnings = [];
|
|
113
|
+
const action = detectAction(normalizedTask);
|
|
114
|
+
const matchedNestedConfig = KNOWN_NESTED_MAP.find((item) => item.match.test(normalizedTask));
|
|
115
|
+
const mentionsNestedItem = !!matchedNestedConfig || includesAny(normalizedTask, NESTED_ITEM_WORDS);
|
|
116
|
+
const detectedParentResource = matchedNestedConfig?.parent ?? detectParentResource(normalizedTask);
|
|
117
|
+
const detectedNestedResource = matchedNestedConfig?.nested;
|
|
118
|
+
const resourceKind = mentionsNestedItem
|
|
119
|
+
? "nested_resource"
|
|
120
|
+
: detectedParentResource
|
|
121
|
+
? "parent_resource"
|
|
122
|
+
: includesAny(normalizedTask, PARENT_RESOURCE_WORDS)
|
|
123
|
+
? "parent_resource"
|
|
124
|
+
: "unknown";
|
|
125
|
+
const scope = detectScope({
|
|
126
|
+
normalizedTask,
|
|
127
|
+
action,
|
|
128
|
+
mentionsNestedItem
|
|
129
|
+
});
|
|
130
|
+
const destructiveRisk = action === "delete" &&
|
|
131
|
+
(resourceKind === "nested_resource" || resourceKind === "parent_resource");
|
|
132
|
+
if (action === "unknown") {
|
|
133
|
+
warnings.push("Could not confidently determine CRUD action from task wording.");
|
|
134
|
+
}
|
|
135
|
+
if (!detectedParentResource && resourceKind !== "unknown") {
|
|
136
|
+
warnings.push("Resource kind was inferred, but parent resource could not be confidently identified.");
|
|
137
|
+
}
|
|
138
|
+
if (action === "delete") {
|
|
139
|
+
warnings.push("Delete action detected. Verify target scope carefully.");
|
|
140
|
+
}
|
|
141
|
+
if (resourceKind === "nested_resource") {
|
|
142
|
+
warnings.push("Nested resource detected. Parent resource should not be directly replaced.");
|
|
143
|
+
}
|
|
144
|
+
if (action === "update" && resourceKind === "nested_resource") {
|
|
145
|
+
warnings.push("Update should target the nested item only, not the whole parent record.");
|
|
146
|
+
}
|
|
147
|
+
if (scope === "collection" && action === "delete") {
|
|
148
|
+
warnings.push("Collection-level delete detected. Confirm that bulk deletion is intended.");
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
rawTask,
|
|
152
|
+
normalizedTask,
|
|
153
|
+
action,
|
|
154
|
+
resourceKind,
|
|
155
|
+
scope,
|
|
156
|
+
parentResource: detectedParentResource,
|
|
157
|
+
nestedResource: detectedNestedResource,
|
|
158
|
+
mentionsNestedItem,
|
|
159
|
+
destructiveRisk,
|
|
160
|
+
routeHints: matchedNestedConfig?.routeHints ?? [],
|
|
161
|
+
paramHints: matchedNestedConfig?.paramHints ?? [],
|
|
162
|
+
warnings
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=taskIntentParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskIntentParser.js","sourceRoot":"","sources":["../../src/core/taskIntentParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentResult.js","sourceRoot":"","sources":["../../../src/core/types/agentResult.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"risk.js","sourceRoot":"","sources":["../../../src/core/types/risk.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validatePatchAgainstSchema = validatePatchAgainstSchema;
|
|
4
|
+
function extractTableNames(content) {
|
|
5
|
+
const matches = [...content.matchAll(/from\(["'`]([a-zA-Z0-9_]+)["'`]\)/g)];
|
|
6
|
+
return matches.map((match) => match[1]);
|
|
7
|
+
}
|
|
8
|
+
function extractEqColumns(content) {
|
|
9
|
+
const matches = [...content.matchAll(/\.eq\(["'`]([a-zA-Z0-9_]+)["'`]\s*,/g)];
|
|
10
|
+
return matches.map((match) => match[1]);
|
|
11
|
+
}
|
|
12
|
+
function extractSelectColumns(content) {
|
|
13
|
+
const matches = [...content.matchAll(/select\(["'`]([^"'`]+)["'`]\)/g)];
|
|
14
|
+
const rawColumns = matches.flatMap((match) => match[1]
|
|
15
|
+
.split(",")
|
|
16
|
+
.map((part) => part.trim())
|
|
17
|
+
.filter(Boolean));
|
|
18
|
+
return rawColumns
|
|
19
|
+
.map((col) => col.replace(/\s+/g, ""))
|
|
20
|
+
.filter((col) => col !== "*" && !col.includes("(") && !col.includes(")"));
|
|
21
|
+
}
|
|
22
|
+
function extractUpdateColumns(content) {
|
|
23
|
+
const matches = [...content.matchAll(/update\(\s*\{([\s\S]*?)\}\s*\)/g)];
|
|
24
|
+
const columns = [];
|
|
25
|
+
for (const match of matches) {
|
|
26
|
+
const objectBody = match[1];
|
|
27
|
+
const keyMatches = [...objectBody.matchAll(/([a-zA-Z0-9_]+)\s*:/g)];
|
|
28
|
+
for (const keyMatch of keyMatches) {
|
|
29
|
+
columns.push(keyMatch[1]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return columns;
|
|
33
|
+
}
|
|
34
|
+
function buildSchemaIssue(input) {
|
|
35
|
+
return {
|
|
36
|
+
level: input.level,
|
|
37
|
+
code: input.code,
|
|
38
|
+
message: input.message,
|
|
39
|
+
filePath: input.filePath,
|
|
40
|
+
details: input.details,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function validatePatchAgainstSchema(patchItems, schema) {
|
|
44
|
+
const issues = [];
|
|
45
|
+
if (!schema) {
|
|
46
|
+
issues.push(buildSchemaIssue({
|
|
47
|
+
level: "warning",
|
|
48
|
+
code: "SCHEMA_SNAPSHOT_MISSING",
|
|
49
|
+
message: "No schema snapshot loaded. Schema-level patch validation skipped.",
|
|
50
|
+
}));
|
|
51
|
+
return issues;
|
|
52
|
+
}
|
|
53
|
+
const knownTables = new Set(schema.tables);
|
|
54
|
+
const columnsByTable = new Map();
|
|
55
|
+
for (const column of schema.columns) {
|
|
56
|
+
if (!columnsByTable.has(column.tableName)) {
|
|
57
|
+
columnsByTable.set(column.tableName, new Set());
|
|
58
|
+
}
|
|
59
|
+
columnsByTable.get(column.tableName)?.add(column.columnName);
|
|
60
|
+
}
|
|
61
|
+
for (const item of patchItems) {
|
|
62
|
+
const content = item.contentPreview ?? "";
|
|
63
|
+
const referencedTables = extractTableNames(content);
|
|
64
|
+
for (const tableName of referencedTables) {
|
|
65
|
+
if (!knownTables.has(tableName)) {
|
|
66
|
+
issues.push(buildSchemaIssue({
|
|
67
|
+
level: "warning",
|
|
68
|
+
code: "SCHEMA_PATH_NOT_FOUND",
|
|
69
|
+
message: `Referenced table '${tableName}' not found in schema snapshot.`,
|
|
70
|
+
filePath: item.path,
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (referencedTables.length !== 1) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const activeTable = referencedTables[0];
|
|
78
|
+
const knownColumns = columnsByTable.get(activeTable);
|
|
79
|
+
if (!knownColumns) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const referencedColumns = [
|
|
83
|
+
...extractEqColumns(content),
|
|
84
|
+
...extractSelectColumns(content),
|
|
85
|
+
...extractUpdateColumns(content),
|
|
86
|
+
];
|
|
87
|
+
for (const columnName of referencedColumns) {
|
|
88
|
+
if (!knownColumns.has(columnName)) {
|
|
89
|
+
issues.push(buildSchemaIssue({
|
|
90
|
+
level: "warning",
|
|
91
|
+
code: "SCHEMA_FIELD_MISMATCH",
|
|
92
|
+
message: `Referenced column '${activeTable}.${columnName}' not found in schema snapshot.`,
|
|
93
|
+
filePath: item.path,
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return issues;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=validatePatchAgainstSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validatePatchAgainstSchema.js","sourceRoot":"","sources":["../../src/core/validatePatchAgainstSchema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSuggestedArchitecture = validateSuggestedArchitecture;
|
|
4
|
+
function validateSuggestedArchitecture(intent, suggestedFiles) {
|
|
5
|
+
const warnings = [];
|
|
6
|
+
const lowerFiles = suggestedFiles.map((f) => f.toLowerCase());
|
|
7
|
+
const hasRoute = lowerFiles.some((f) => f.includes("route"));
|
|
8
|
+
const hasController = lowerFiles.some((f) => f.includes("controller"));
|
|
9
|
+
const hasService = lowerFiles.some((f) => f.includes("service"));
|
|
10
|
+
const hasUi = lowerFiles.some((f) => f.includes("page") ||
|
|
11
|
+
f.includes("component") ||
|
|
12
|
+
f.includes("view"));
|
|
13
|
+
if (intent.action === "update" || intent.action === "delete") {
|
|
14
|
+
if (!hasRoute)
|
|
15
|
+
warnings.push("Mutation task suggested files are missing route layer.");
|
|
16
|
+
if (!hasController)
|
|
17
|
+
warnings.push("Mutation task suggested files are missing controller layer.");
|
|
18
|
+
}
|
|
19
|
+
if (intent.resourceKind === "nested_resource" && !hasService && !hasUi) {
|
|
20
|
+
warnings.push("Nested resource change may also require service/UI updates depending on stack.");
|
|
21
|
+
}
|
|
22
|
+
return { warnings };
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=validateSuggestedArchitecture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validateSuggestedArchitecture.js","sourceRoot":"","sources":["../../src/core/validateSuggestedArchitecture.ts"],"names":[],"mappings":";;AAMA,sEA2BC;AA3BD,SAAgB,6BAA6B,CAC3C,MAAkB,EAClB,cAAwB;IAExB,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,UAAU,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAE9D,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAC3B,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAClB,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;QACvB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CACrB,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7D,IAAI,CAAC,QAAQ;YAAE,QAAQ,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAC;QACvF,IAAI,CAAC,aAAa;YAAE,QAAQ,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;IACnG,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,KAAK,iBAAiB,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;QACvE,QAAQ,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC;IAClG,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildDecisionExplanation = buildDecisionExplanation;
|
|
4
|
+
const decisionReasonCodeMeta_js_1 = require("../core/decision/decisionReasonCodeMeta.js");
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Fallback constants — deterministic, documented, all string literals
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
/** Applied when the caller provides null, undefined, or an empty reasonCodes array. */
|
|
9
|
+
const WHY_EMPTY_CODES = "No reason codes provided";
|
|
10
|
+
/** Applied when every supplied code is unknown (not found in the metadata registry). */
|
|
11
|
+
const WHY_NO_VALID_CODES = "No valid reason codes resolved";
|
|
12
|
+
/** Fallback when a metadata entry exists but its severity field is missing or unrecognised. */
|
|
13
|
+
const FALLBACK_SEVERITY = "info";
|
|
14
|
+
/** Fallback when a metadata entry exists but its category field is missing or empty. */
|
|
15
|
+
const FALLBACK_CATEGORY = "general";
|
|
16
|
+
/** Fallback when a metadata entry exists but its summary field is missing or empty. */
|
|
17
|
+
const FALLBACK_SUMMARY = "No summary available";
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Internal helpers
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Normalises raw metadata severity (the registry's "low" | "medium" | "high" scale)
|
|
23
|
+
* to the engine's three-level severity scale ("info" | "warning" | "critical").
|
|
24
|
+
*
|
|
25
|
+
* Missing or unrecognised severity → FALLBACK_SEVERITY ("info").
|
|
26
|
+
*/
|
|
27
|
+
function resolveReasonSeverity(raw) {
|
|
28
|
+
// Missing severity → default to "info" (documented fallback, no throw)
|
|
29
|
+
if (!raw)
|
|
30
|
+
return FALLBACK_SEVERITY;
|
|
31
|
+
switch (raw) {
|
|
32
|
+
case "high":
|
|
33
|
+
return "critical";
|
|
34
|
+
case "medium":
|
|
35
|
+
return "warning";
|
|
36
|
+
case "low":
|
|
37
|
+
return "info";
|
|
38
|
+
default:
|
|
39
|
+
// Unknown severity string → safe default, no throw
|
|
40
|
+
return FALLBACK_SEVERITY;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Builds the "why" summary string for a successful explanation (≥1 resolved reason).
|
|
45
|
+
* Lists the count and the code identifiers for full traceability.
|
|
46
|
+
*/
|
|
47
|
+
function buildWhyFromReasons(reasons) {
|
|
48
|
+
const count = reasons.length;
|
|
49
|
+
const codeList = reasons.map((r) => r.code).join(", ");
|
|
50
|
+
return `Decision backed by ${count} reason code(s): ${codeList}`;
|
|
51
|
+
}
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Public API
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
/**
|
|
56
|
+
* Builds a deterministic, fully-populated DecisionExplanation from an array of
|
|
57
|
+
* reason codes.
|
|
58
|
+
*
|
|
59
|
+
* Edge-case guarantees — all silent (no throws, no console output):
|
|
60
|
+
*
|
|
61
|
+
* • null / undefined reasonCodes → treated as []
|
|
62
|
+
* • empty reasonCodes → { why: "No reason codes provided", reasons: [] }
|
|
63
|
+
* • unknown code (not in registry)→ skipped silently; never throws
|
|
64
|
+
* • all codes unknown → { why: "No valid reason codes resolved", reasons: [] }
|
|
65
|
+
* • missing severity in metadata → defaults to "info"
|
|
66
|
+
* • missing category in metadata → defaults to "general"
|
|
67
|
+
* • missing summary in metadata → defaults to "No summary available"
|
|
68
|
+
*
|
|
69
|
+
* The output object is always complete: every field is a non-null, non-undefined
|
|
70
|
+
* string or array. The normal production path is completely unaffected by the
|
|
71
|
+
* fallback handling — it only activates on genuinely missing data.
|
|
72
|
+
*
|
|
73
|
+
* @param input - Object containing the reasonCodes to resolve.
|
|
74
|
+
* @param options - Optional: metadata registry override for test injection.
|
|
75
|
+
* @returns A fully-populated DecisionExplanation.
|
|
76
|
+
*/
|
|
77
|
+
function buildDecisionExplanation(input, options = {}) {
|
|
78
|
+
// Normalise null / undefined → [] (silent, no throw)
|
|
79
|
+
const rawCodes = input.reasonCodes ?? [];
|
|
80
|
+
// Empty input → early return with documented fallback why
|
|
81
|
+
if (rawCodes.length === 0) {
|
|
82
|
+
return { why: WHY_EMPTY_CODES, reasons: [] };
|
|
83
|
+
}
|
|
84
|
+
// Resolve metadata source: injected override takes precedence over the default registry
|
|
85
|
+
const metaRegistry = options.metadata ??
|
|
86
|
+
decisionReasonCodeMeta_js_1.DECISION_REASON_CODE_META;
|
|
87
|
+
const reasons = [];
|
|
88
|
+
for (const code of rawCodes) {
|
|
89
|
+
// Unknown code — not present in registry → skip silently, do NOT throw
|
|
90
|
+
const meta = metaRegistry[code];
|
|
91
|
+
if (!meta)
|
|
92
|
+
continue;
|
|
93
|
+
const resolved = {
|
|
94
|
+
code,
|
|
95
|
+
// Missing severity → default to "info"
|
|
96
|
+
severity: resolveReasonSeverity(meta.severity),
|
|
97
|
+
// Missing category → default to "general"
|
|
98
|
+
category: typeof meta.category === "string" && meta.category.length > 0
|
|
99
|
+
? meta.category
|
|
100
|
+
: FALLBACK_CATEGORY,
|
|
101
|
+
// Missing summary → default to "No summary available"
|
|
102
|
+
summary: typeof meta.summary === "string" && meta.summary.length > 0
|
|
103
|
+
? meta.summary
|
|
104
|
+
: FALLBACK_SUMMARY,
|
|
105
|
+
};
|
|
106
|
+
reasons.push(resolved);
|
|
107
|
+
}
|
|
108
|
+
// Every supplied code was unknown → fallback why
|
|
109
|
+
if (reasons.length === 0) {
|
|
110
|
+
return { why: WHY_NO_VALID_CODES, reasons: [] };
|
|
111
|
+
}
|
|
112
|
+
return { why: buildWhyFromReasons(reasons), reasons };
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=buildDecisionExplanation.js.map
|