scene-capability-engine 3.0.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/CHANGELOG.md +2513 -0
- package/LICENSE +21 -0
- package/README.md +765 -0
- package/README.zh.md +630 -0
- package/bin/kiro-spec-engine.js +796 -0
- package/bin/kse.js +3 -0
- package/bin/sce.js +3 -0
- package/bin/sco.js +3 -0
- package/docs/331-poc-adaptation-roadmap.md +156 -0
- package/docs/331-poc-dual-track-integration-guide.md +120 -0
- package/docs/331-poc-weekly-delivery-checklist.md +52 -0
- package/docs/OFFLINE_INSTALL.md +96 -0
- package/docs/README.md +279 -0
- package/docs/adopt-migration-guide.md +599 -0
- package/docs/adoption-guide.md +616 -0
- package/docs/agent-hooks-analysis.md +815 -0
- package/docs/architecture.md +733 -0
- package/docs/articles/ai-driven-development-philosophy-and-practice-review.md +208 -0
- package/docs/articles/ai-driven-development-philosophy-and-practice.en.md +459 -0
- package/docs/articles/ai-driven-development-philosophy-and-practice.md +492 -0
- package/docs/autonomous-control-guide.md +851 -0
- package/docs/command-reference.md +1368 -0
- package/docs/community.md +115 -0
- package/docs/cross-tool-guide.md +555 -0
- package/docs/developer-guide.md +619 -0
- package/docs/document-governance.md +865 -0
- package/docs/environment-management-guide.md +526 -0
- package/docs/examples/add-export-command/design.md +194 -0
- package/docs/examples/add-export-command/requirements.md +110 -0
- package/docs/examples/add-export-command/tasks.md +88 -0
- package/docs/examples/add-rest-api/design.md +855 -0
- package/docs/examples/add-rest-api/requirements.md +323 -0
- package/docs/examples/add-rest-api/tasks.md +355 -0
- package/docs/examples/add-user-dashboard/design.md +192 -0
- package/docs/examples/add-user-dashboard/requirements.md +143 -0
- package/docs/examples/add-user-dashboard/tasks.md +91 -0
- package/docs/faq.md +697 -0
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.json +156 -0
- package/docs/handoffs/evidence/ontology/moqui-template-baseline-2026-02-17-232922.md +24 -0
- package/docs/images/wechat-qr.png +0 -0
- package/docs/integration-modes.md +529 -0
- package/docs/integration-philosophy.md +313 -0
- package/docs/knowledge-management-guide.md +263 -0
- package/docs/manual-workflows-guide.md +418 -0
- package/docs/moqui-capability-matrix.md +73 -0
- package/docs/moqui-template-core-library-playbook.md +109 -0
- package/docs/multi-agent-coordination-guide.md +553 -0
- package/docs/multi-repo-management-guide.md +1344 -0
- package/docs/quick-start-with-ai-tools.md +375 -0
- package/docs/quick-start.md +146 -0
- package/docs/release-checklist.md +121 -0
- package/docs/releases/README.md +13 -0
- package/docs/releases/v1.46.2-validation.md +45 -0
- package/docs/releases/v1.46.2.md +50 -0
- package/docs/scene-runtime-guide.md +347 -0
- package/docs/spec-collaboration-guide.md +369 -0
- package/docs/spec-locking-guide.md +225 -0
- package/docs/spec-numbering-guide.md +348 -0
- package/docs/spec-workflow.md +519 -0
- package/docs/steering-strategy-guide.md +196 -0
- package/docs/team-collaboration-guide.md +465 -0
- package/docs/testing-strategy.md +272 -0
- package/docs/tools/claude-guide.md +654 -0
- package/docs/tools/cursor-guide.md +706 -0
- package/docs/tools/generic-guide.md +446 -0
- package/docs/tools/kiro-guide.md +308 -0
- package/docs/tools/vscode-guide.md +445 -0
- package/docs/tools/windsurf-guide.md +391 -0
- package/docs/troubleshooting.md +1135 -0
- package/docs/upgrade-guide.md +639 -0
- package/docs/value-observability-guide.md +127 -0
- package/docs/zh/README.md +341 -0
- package/docs/zh/quick-start.md +764 -0
- package/docs/zh/release-checklist.md +121 -0
- package/docs/zh/releases/README.md +13 -0
- package/docs/zh/releases/v1.46.2-validation.md +45 -0
- package/docs/zh/releases/v1.46.2.md +50 -0
- package/docs/zh/spec-numbering-guide.md +348 -0
- package/docs/zh/tools/claude-guide.md +349 -0
- package/docs/zh/tools/cursor-guide.md +281 -0
- package/docs/zh/tools/generic-guide.md +499 -0
- package/docs/zh/tools/kiro-guide.md +342 -0
- package/docs/zh/tools/vscode-guide.md +449 -0
- package/docs/zh/tools/windsurf-guide.md +378 -0
- package/docs/zh/value-observability-guide.md +127 -0
- package/docs//344/272/244/344/273/230/346/270/205/345/215/225.md +75 -0
- package/lib/adoption/adoption-logger.js +487 -0
- package/lib/adoption/adoption-strategy.js +538 -0
- package/lib/adoption/backup-manager.js +420 -0
- package/lib/adoption/conflict-resolver.js +410 -0
- package/lib/adoption/detection-engine.js +275 -0
- package/lib/adoption/diff-viewer.js +226 -0
- package/lib/adoption/error-formatter.js +509 -0
- package/lib/adoption/file-classifier.js +385 -0
- package/lib/adoption/progress-reporter.js +534 -0
- package/lib/adoption/smart-orchestrator.js +470 -0
- package/lib/adoption/strategy-selector.js +218 -0
- package/lib/adoption/summary-generator.js +493 -0
- package/lib/adoption/template-sync.js +605 -0
- package/lib/auto/autonomous-engine.js +485 -0
- package/lib/auto/checkpoint-manager.js +300 -0
- package/lib/auto/close-loop-runner.js +2476 -0
- package/lib/auto/config-schema.js +176 -0
- package/lib/auto/decision-engine.js +344 -0
- package/lib/auto/error-recovery-manager.js +580 -0
- package/lib/auto/goal-decomposer.js +278 -0
- package/lib/auto/progress-tracker.js +502 -0
- package/lib/auto/safety-manager.js +186 -0
- package/lib/auto/semantic-decomposer.js +137 -0
- package/lib/auto/state-manager.js +126 -0
- package/lib/auto/task-queue-manager.js +340 -0
- package/lib/backup/backup-system.js +372 -0
- package/lib/backup/selective-backup.js +207 -0
- package/lib/collab/agent-registry.js +240 -0
- package/lib/collab/collab-manager.js +285 -0
- package/lib/collab/contract-manager.js +320 -0
- package/lib/collab/coordinator.js +370 -0
- package/lib/collab/dependency-manager.js +280 -0
- package/lib/collab/index.js +20 -0
- package/lib/collab/integration-manager.js +202 -0
- package/lib/collab/merge-coordinator.js +252 -0
- package/lib/collab/metadata-manager.js +233 -0
- package/lib/collab/multi-agent-config.js +120 -0
- package/lib/collab/spec-lifecycle-manager.js +304 -0
- package/lib/collab/sync-barrier.js +88 -0
- package/lib/collab/visualizer.js +208 -0
- package/lib/commands/adopt.js +749 -0
- package/lib/commands/auto.js +19559 -0
- package/lib/commands/collab.js +275 -0
- package/lib/commands/context.js +99 -0
- package/lib/commands/docs.js +808 -0
- package/lib/commands/doctor.js +273 -0
- package/lib/commands/env.js +420 -0
- package/lib/commands/knowledge.js +309 -0
- package/lib/commands/lock.js +235 -0
- package/lib/commands/ops.js +409 -0
- package/lib/commands/orchestrate.js +446 -0
- package/lib/commands/prompt.js +105 -0
- package/lib/commands/repo.js +118 -0
- package/lib/commands/rollback.js +219 -0
- package/lib/commands/scene.js +15549 -0
- package/lib/commands/spec-bootstrap.js +147 -0
- package/lib/commands/spec-gate.js +157 -0
- package/lib/commands/spec-pipeline.js +205 -0
- package/lib/commands/status.js +321 -0
- package/lib/commands/task.js +199 -0
- package/lib/commands/templates.js +654 -0
- package/lib/commands/upgrade.js +231 -0
- package/lib/commands/value.js +569 -0
- package/lib/commands/watch.js +684 -0
- package/lib/commands/workflows.js +240 -0
- package/lib/commands/workspace-multi.js +325 -0
- package/lib/commands/workspace.js +189 -0
- package/lib/context/context-exporter.js +378 -0
- package/lib/context/prompt-generator.js +482 -0
- package/lib/data/moqui-capability-lexicon.json +45 -0
- package/lib/environment/backup-system.js +189 -0
- package/lib/environment/environment-manager.js +379 -0
- package/lib/environment/environment-registry.js +168 -0
- package/lib/gitignore/gitignore-backup.js +229 -0
- package/lib/gitignore/gitignore-detector.js +239 -0
- package/lib/gitignore/gitignore-integration.js +267 -0
- package/lib/gitignore/gitignore-transformer.js +193 -0
- package/lib/gitignore/layered-rules-template.js +42 -0
- package/lib/governance/archive-tool.js +284 -0
- package/lib/governance/cleanup-tool.js +237 -0
- package/lib/governance/config-manager.js +186 -0
- package/lib/governance/diagnostic-engine.js +271 -0
- package/lib/governance/doc-reference-checker.js +200 -0
- package/lib/governance/execution-logger.js +243 -0
- package/lib/governance/file-scanner.js +285 -0
- package/lib/governance/hooks-manager.js +333 -0
- package/lib/governance/reporter.js +337 -0
- package/lib/governance/validation-engine.js +181 -0
- package/lib/i18n.js +79 -0
- package/lib/knowledge/entry-manager.js +208 -0
- package/lib/knowledge/index-manager.js +261 -0
- package/lib/knowledge/knowledge-manager.js +273 -0
- package/lib/knowledge/template-manager.js +191 -0
- package/lib/lock/index.js +21 -0
- package/lib/lock/lock-file.js +192 -0
- package/lib/lock/lock-manager.js +321 -0
- package/lib/lock/machine-identifier.js +135 -0
- package/lib/lock/steering-file-lock.js +207 -0
- package/lib/lock/task-lock-manager.js +345 -0
- package/lib/operations/audit-logger.js +293 -0
- package/lib/operations/feedback-manager.js +1147 -0
- package/lib/operations/index.js +23 -0
- package/lib/operations/models/index.js +170 -0
- package/lib/operations/operations-manager.js +151 -0
- package/lib/operations/operations-validator.js +280 -0
- package/lib/operations/permission-manager.js +354 -0
- package/lib/operations/template-loader.js +143 -0
- package/lib/orchestrator/agent-spawner.js +629 -0
- package/lib/orchestrator/bootstrap-prompt-builder.js +236 -0
- package/lib/orchestrator/index.js +19 -0
- package/lib/orchestrator/orchestration-engine.js +1270 -0
- package/lib/orchestrator/orchestrator-config.js +173 -0
- package/lib/orchestrator/status-monitor.js +591 -0
- package/lib/python-checker.js +209 -0
- package/lib/repo/config-manager.js +580 -0
- package/lib/repo/errors/config-error.js +13 -0
- package/lib/repo/errors/git-error.js +15 -0
- package/lib/repo/errors/repo-error.js +14 -0
- package/lib/repo/git-operations.js +181 -0
- package/lib/repo/handlers/.gitkeep +1 -0
- package/lib/repo/handlers/exec-handler.js +155 -0
- package/lib/repo/handlers/health-handler.js +169 -0
- package/lib/repo/handlers/init-handler.js +197 -0
- package/lib/repo/handlers/status-handler.js +176 -0
- package/lib/repo/output-formatter.js +184 -0
- package/lib/repo/path-resolver.js +178 -0
- package/lib/repo/repo-manager.js +514 -0
- package/lib/scene-runtime/audit-emitter.js +59 -0
- package/lib/scene-runtime/binding-plugin-loader.js +351 -0
- package/lib/scene-runtime/binding-registry.js +349 -0
- package/lib/scene-runtime/eval-bridge.js +44 -0
- package/lib/scene-runtime/index.js +19 -0
- package/lib/scene-runtime/moqui-adapter.js +620 -0
- package/lib/scene-runtime/moqui-client.js +606 -0
- package/lib/scene-runtime/moqui-extractor.js +2029 -0
- package/lib/scene-runtime/plan-compiler.js +208 -0
- package/lib/scene-runtime/policy-gate.js +58 -0
- package/lib/scene-runtime/runtime-executor.js +358 -0
- package/lib/scene-runtime/scene-loader.js +96 -0
- package/lib/scene-runtime/scene-ontology.js +959 -0
- package/lib/scene-runtime/scene-template-linter.js +852 -0
- package/lib/scene-runtime/templates/scene-template-erp-query-v0.1.yaml +28 -0
- package/lib/scene-runtime/templates/scene-template-hybrid-shadow-v0.1.yaml +34 -0
- package/lib/spec/bootstrap/context-collector.js +48 -0
- package/lib/spec/bootstrap/draft-generator.js +158 -0
- package/lib/spec/bootstrap/questionnaire-engine.js +70 -0
- package/lib/spec/bootstrap/trace-emitter.js +59 -0
- package/lib/spec/multi-spec-orchestrate.js +93 -0
- package/lib/spec/pipeline/constants.js +6 -0
- package/lib/spec/pipeline/stage-adapters.js +118 -0
- package/lib/spec/pipeline/stage-runner.js +146 -0
- package/lib/spec/pipeline/state-store.js +119 -0
- package/lib/spec-gate/engine/gate-engine.js +165 -0
- package/lib/spec-gate/policy/default-policy.js +22 -0
- package/lib/spec-gate/policy/policy-loader.js +103 -0
- package/lib/spec-gate/result-emitter.js +81 -0
- package/lib/spec-gate/rules/default-rules.js +156 -0
- package/lib/spec-gate/rules/rule-registry.js +51 -0
- package/lib/steering/adoption-config.js +164 -0
- package/lib/steering/compliance-auto-fixer.js +204 -0
- package/lib/steering/compliance-cache.js +99 -0
- package/lib/steering/compliance-error-reporter.js +70 -0
- package/lib/steering/context-sync-manager.js +273 -0
- package/lib/steering/index.js +92 -0
- package/lib/steering/spec-steering.js +230 -0
- package/lib/steering/steering-compliance-checker.js +73 -0
- package/lib/steering/steering-loader.js +144 -0
- package/lib/steering/steering-manager.js +289 -0
- package/lib/task/index.js +12 -0
- package/lib/task/task-claimer.js +489 -0
- package/lib/task/task-status-store.js +418 -0
- package/lib/templates/cache-manager.js +440 -0
- package/lib/templates/content-generalizer.js +247 -0
- package/lib/templates/frontmatter-generator.js +128 -0
- package/lib/templates/git-handler.js +471 -0
- package/lib/templates/metadata-collector.js +328 -0
- package/lib/templates/path-utils.js +144 -0
- package/lib/templates/registry-parser.js +505 -0
- package/lib/templates/spec-reader.js +216 -0
- package/lib/templates/template-applicator.js +249 -0
- package/lib/templates/template-creator.js +256 -0
- package/lib/templates/template-error.js +143 -0
- package/lib/templates/template-exporter.js +502 -0
- package/lib/templates/template-manager.js +782 -0
- package/lib/templates/template-validator.js +361 -0
- package/lib/upgrade/migration-engine.js +382 -0
- package/lib/upgrade/migrations/.gitkeep +52 -0
- package/lib/upgrade/migrations/1.0.0-to-1.1.0.js +78 -0
- package/lib/utils/file-diff.js +177 -0
- package/lib/utils/fs-utils.js +274 -0
- package/lib/utils/tool-detector.js +383 -0
- package/lib/utils/validation.js +324 -0
- package/lib/value/gate-summary-emitter.js +99 -0
- package/lib/value/metric-contract-loader.js +210 -0
- package/lib/value/risk-evaluator.js +117 -0
- package/lib/value/weekly-snapshot-builder.js +61 -0
- package/lib/version/version-checker.js +156 -0
- package/lib/version/version-manager.js +327 -0
- package/lib/watch/action-executor.js +458 -0
- package/lib/watch/event-debouncer.js +323 -0
- package/lib/watch/execution-logger.js +550 -0
- package/lib/watch/file-watcher.js +499 -0
- package/lib/watch/presets.js +266 -0
- package/lib/watch/watch-manager.js +533 -0
- package/lib/workspace/multi/global-config.js +150 -0
- package/lib/workspace/multi/index.js +22 -0
- package/lib/workspace/multi/path-utils.js +173 -0
- package/lib/workspace/multi/workspace-context-resolver.js +244 -0
- package/lib/workspace/multi/workspace-registry.js +196 -0
- package/lib/workspace/multi/workspace-state-manager.js +537 -0
- package/lib/workspace/multi/workspace.js +90 -0
- package/lib/workspace/workspace-manager.js +370 -0
- package/lib/workspace/workspace-sync.js +356 -0
- package/locales/en.json +114 -0
- package/locales/zh.json +114 -0
- package/package.json +102 -0
- package/template/.kiro/README.md +247 -0
- package/template/.kiro/hooks/check-spec-on-create.kiro.hook +17 -0
- package/template/.kiro/hooks/run-tests-on-save.kiro.hook +13 -0
- package/template/.kiro/hooks/sync-tasks-on-edit.kiro.hook +16 -0
- package/template/.kiro/specs/SPEC_WORKFLOW_GUIDE.md +134 -0
- package/template/.kiro/steering/CORE_PRINCIPLES.md +133 -0
- package/template/.kiro/steering/CURRENT_CONTEXT.md +30 -0
- package/template/.kiro/steering/ENVIRONMENT.md +35 -0
- package/template/.kiro/steering/RULES_GUIDE.md +46 -0
- package/template/.kiro/templates/operations/default/change-impact.md +112 -0
- package/template/.kiro/templates/operations/default/deployment.md +91 -0
- package/template/.kiro/templates/operations/default/feedback-response.md +269 -0
- package/template/.kiro/templates/operations/default/migration-plan.md +172 -0
- package/template/.kiro/templates/operations/default/monitoring.md +135 -0
- package/template/.kiro/templates/operations/default/operations.md +135 -0
- package/template/.kiro/templates/operations/default/rollback.md +143 -0
- package/template/.kiro/templates/operations/default/tools.yaml +364 -0
- package/template/.kiro/templates/operations/default/troubleshooting.md +123 -0
- package/template/.kiro/tools/backup_manager.py +295 -0
- package/template/.kiro/tools/configuration_manager.py +218 -0
- package/template/.kiro/tools/document_evaluator.py +550 -0
- package/template/.kiro/tools/enhancement_logger.py +168 -0
- package/template/.kiro/tools/error_handler.py +335 -0
- package/template/.kiro/tools/improvement_identifier.py +444 -0
- package/template/.kiro/tools/modification_applicator.py +737 -0
- package/template/.kiro/tools/quality_gate_enforcer.py +207 -0
- package/template/.kiro/tools/quality_scorer.py +305 -0
- package/template/.kiro/tools/report_generator.py +154 -0
- package/template/.kiro/tools/ultrawork_enhancer.py +676 -0
- package/template/.kiro/tools/ultrawork_enhancer_refactored.py +0 -0
- package/template/.kiro/tools/ultrawork_enhancer_v2.py +463 -0
- package/template/.kiro/tools/ultrawork_enhancer_v3.py +606 -0
- package/template/.kiro/tools/workflow_quality_gate.py +100 -0
- package/template/README.md +111 -0
|
@@ -0,0 +1,580 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Recovery Manager
|
|
3
|
+
* Automatic error diagnosis and resolution with learning capabilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs-extra');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
class ErrorRecoveryManager {
|
|
10
|
+
constructor(config = {}) {
|
|
11
|
+
this.config = {
|
|
12
|
+
maxAttempts: config.maxAttempts || 3,
|
|
13
|
+
strategies: config.strategies || [],
|
|
14
|
+
learningEnabled: config.learningEnabled !== false
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
this.strategyRegistry = new Map();
|
|
18
|
+
this.successHistory = new Map(); // error type -> successful strategies
|
|
19
|
+
this.failureHistory = new Map(); // error type -> failed strategies
|
|
20
|
+
this.recoveryLog = [];
|
|
21
|
+
this.attemptCounts = new Map(); // error signature -> attempt count
|
|
22
|
+
this.pauseCallback = null; // Callback to pause execution
|
|
23
|
+
this.learningDataPath = path.join(process.cwd(), '.kiro', 'auto', 'learning-data.json');
|
|
24
|
+
|
|
25
|
+
// Register default strategies
|
|
26
|
+
this.registerDefaultStrategies();
|
|
27
|
+
|
|
28
|
+
// Load learning data
|
|
29
|
+
this.loadLearningData();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Set pause callback for emergency pause
|
|
34
|
+
* @param {Function} callback - Callback to pause execution
|
|
35
|
+
*/
|
|
36
|
+
setPauseCallback(callback) {
|
|
37
|
+
this.pauseCallback = callback;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get error signature for tracking attempts
|
|
42
|
+
* @param {Error} error - Error object
|
|
43
|
+
* @returns {string} - Error signature
|
|
44
|
+
*/
|
|
45
|
+
getErrorSignature(error) {
|
|
46
|
+
return `${error.name}:${error.message.substring(0, 100)}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Check if retry limit reached
|
|
51
|
+
* @param {Error} error - Error object
|
|
52
|
+
* @returns {boolean} - True if limit reached
|
|
53
|
+
*/
|
|
54
|
+
isRetryLimitReached(error) {
|
|
55
|
+
const signature = this.getErrorSignature(error);
|
|
56
|
+
const attempts = this.attemptCounts.get(signature) || 0;
|
|
57
|
+
return attempts >= this.config.maxAttempts;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Increment attempt count
|
|
62
|
+
* @param {Error} error - Error object
|
|
63
|
+
* @returns {number} - New attempt count
|
|
64
|
+
*/
|
|
65
|
+
incrementAttemptCount(error) {
|
|
66
|
+
const signature = this.getErrorSignature(error);
|
|
67
|
+
const attempts = (this.attemptCounts.get(signature) || 0) + 1;
|
|
68
|
+
this.attemptCounts.set(signature, attempts);
|
|
69
|
+
return attempts;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Reset attempt count
|
|
74
|
+
* @param {Error} error - Error object
|
|
75
|
+
*/
|
|
76
|
+
resetAttemptCount(error) {
|
|
77
|
+
const signature = this.getErrorSignature(error);
|
|
78
|
+
this.attemptCounts.delete(signature);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Trigger emergency pause
|
|
83
|
+
* @param {Error} error - Error that triggered pause
|
|
84
|
+
* @param {string} reason - Reason for pause
|
|
85
|
+
*/
|
|
86
|
+
async triggerEmergencyPause(error, reason) {
|
|
87
|
+
console.error(`Emergency pause triggered: ${reason}`);
|
|
88
|
+
console.error(`Error: ${error.message}`);
|
|
89
|
+
|
|
90
|
+
if (this.pauseCallback) {
|
|
91
|
+
await this.pauseCallback({
|
|
92
|
+
type: 'emergency',
|
|
93
|
+
error,
|
|
94
|
+
reason,
|
|
95
|
+
timestamp: new Date().toISOString()
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Register default recovery strategies
|
|
102
|
+
*/
|
|
103
|
+
registerDefaultStrategies() {
|
|
104
|
+
// Syntax fix strategy
|
|
105
|
+
this.registerStrategy('syntax-fix', async (error, context) => {
|
|
106
|
+
const analysis = this.analyzeError(error, context);
|
|
107
|
+
if (analysis.type !== 'compilation') return { success: false };
|
|
108
|
+
|
|
109
|
+
// Extract syntax error details
|
|
110
|
+
const syntaxMatch = error.message.match(/Unexpected token|Unexpected identifier|Missing|Expected/i);
|
|
111
|
+
if (!syntaxMatch) return { success: false };
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
success: true,
|
|
115
|
+
action: 'fix-syntax',
|
|
116
|
+
details: `Identified syntax error: ${syntaxMatch[0]}`
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Import resolution strategy
|
|
121
|
+
this.registerStrategy('import-resolution', async (error, context) => {
|
|
122
|
+
const analysis = this.analyzeError(error, context);
|
|
123
|
+
if (analysis.type !== 'compilation' && analysis.type !== 'runtime') {
|
|
124
|
+
return { success: false };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Check for missing module errors
|
|
128
|
+
const importMatch = error.message.match(/Cannot find module ['"](.+)['"]/);
|
|
129
|
+
if (!importMatch) return { success: false };
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
success: true,
|
|
133
|
+
action: 'add-import',
|
|
134
|
+
module: importMatch[1],
|
|
135
|
+
details: `Missing module: ${importMatch[1]}`
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Type correction strategy
|
|
140
|
+
this.registerStrategy('type-correction', async (error, context) => {
|
|
141
|
+
const analysis = this.analyzeError(error, context);
|
|
142
|
+
if (analysis.type !== 'compilation') return { success: false };
|
|
143
|
+
|
|
144
|
+
// Check for type errors
|
|
145
|
+
const typeMatch = error.message.match(/Type ['"](.+)['"] is not assignable to type ['"](.+)['"]/);
|
|
146
|
+
if (!typeMatch) return { success: false };
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
success: true,
|
|
150
|
+
action: 'fix-type',
|
|
151
|
+
from: typeMatch[1],
|
|
152
|
+
to: typeMatch[2],
|
|
153
|
+
details: `Type mismatch: ${typeMatch[1]} -> ${typeMatch[2]}`
|
|
154
|
+
};
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Null check strategy
|
|
158
|
+
this.registerStrategy('null-check', async (error, context) => {
|
|
159
|
+
const analysis = this.analyzeError(error, context);
|
|
160
|
+
if (analysis.type !== 'runtime') return { success: false };
|
|
161
|
+
|
|
162
|
+
// Check for null/undefined errors
|
|
163
|
+
const nullMatch = error.message.match(/Cannot read property|undefined is not|null is not/i);
|
|
164
|
+
if (!nullMatch) return { success: false };
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
success: true,
|
|
168
|
+
action: 'add-null-check',
|
|
169
|
+
details: `Null/undefined access detected`
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Error handling strategy
|
|
174
|
+
this.registerStrategy('error-handling', async (error, context) => {
|
|
175
|
+
const analysis = this.analyzeError(error, context);
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
success: true,
|
|
179
|
+
action: 'add-try-catch',
|
|
180
|
+
details: `Wrap code in try-catch block`
|
|
181
|
+
};
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Analyze error and extract information
|
|
187
|
+
* @param {Error} error - Error to analyze
|
|
188
|
+
* @param {Object} context - Execution context
|
|
189
|
+
* @returns {Object} - Error analysis
|
|
190
|
+
*/
|
|
191
|
+
analyzeError(error, context = {}) {
|
|
192
|
+
const message = error.message || '';
|
|
193
|
+
const stack = error.stack || '';
|
|
194
|
+
|
|
195
|
+
// Determine error type
|
|
196
|
+
let type = 'unknown';
|
|
197
|
+
let severity = 'medium';
|
|
198
|
+
|
|
199
|
+
if (message.match(/SyntaxError|Unexpected token|Parse error/i)) {
|
|
200
|
+
type = 'compilation';
|
|
201
|
+
severity = 'high';
|
|
202
|
+
} else if (message.match(/Test failed|Assertion failed|Expected/i)) {
|
|
203
|
+
type = 'test-failure';
|
|
204
|
+
severity = 'medium';
|
|
205
|
+
} else if (message.match(/TypeError|ReferenceError|Cannot read/i)) {
|
|
206
|
+
type = 'runtime';
|
|
207
|
+
severity = 'high';
|
|
208
|
+
} else if (message.match(/Cannot find module|Module not found/i)) {
|
|
209
|
+
type = 'dependency';
|
|
210
|
+
severity = 'high';
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Extract context from stack trace
|
|
214
|
+
const fileMatch = stack.match(/at .+ \((.+):(\d+):(\d+)\)/);
|
|
215
|
+
const errorContext = fileMatch ? {
|
|
216
|
+
file: fileMatch[1],
|
|
217
|
+
line: parseInt(fileMatch[2]),
|
|
218
|
+
column: parseInt(fileMatch[3])
|
|
219
|
+
} : context;
|
|
220
|
+
|
|
221
|
+
// Suggest strategies based on error type
|
|
222
|
+
const suggestedStrategies = this.getSuggestedStrategies(type, message);
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
type,
|
|
226
|
+
severity,
|
|
227
|
+
message,
|
|
228
|
+
stackTrace: stack,
|
|
229
|
+
context: errorContext,
|
|
230
|
+
suggestedStrategies
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Get suggested strategies for error type
|
|
236
|
+
* @param {string} type - Error type
|
|
237
|
+
* @param {string} message - Error message
|
|
238
|
+
* @returns {Array} - Suggested strategy names
|
|
239
|
+
*/
|
|
240
|
+
getSuggestedStrategies(type, message) {
|
|
241
|
+
const strategies = [];
|
|
242
|
+
|
|
243
|
+
// Check learning history first
|
|
244
|
+
if (this.learningEnabled && this.successHistory.has(type)) {
|
|
245
|
+
const successfulStrategies = this.successHistory.get(type);
|
|
246
|
+
strategies.push(...successfulStrategies.slice(0, 2)); // Top 2 successful
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Add type-specific strategies
|
|
250
|
+
switch (type) {
|
|
251
|
+
case 'compilation':
|
|
252
|
+
strategies.push('syntax-fix', 'import-resolution', 'type-correction');
|
|
253
|
+
break;
|
|
254
|
+
case 'test-failure':
|
|
255
|
+
strategies.push('error-handling');
|
|
256
|
+
break;
|
|
257
|
+
case 'runtime':
|
|
258
|
+
strategies.push('null-check', 'error-handling', 'import-resolution');
|
|
259
|
+
break;
|
|
260
|
+
case 'dependency':
|
|
261
|
+
strategies.push('import-resolution');
|
|
262
|
+
break;
|
|
263
|
+
default:
|
|
264
|
+
strategies.push('error-handling');
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return [...new Set(strategies)]; // Remove duplicates
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Select best recovery strategy
|
|
272
|
+
* @param {Object} errorAnalysis - Error analysis result
|
|
273
|
+
* @returns {string|null} - Strategy name or null
|
|
274
|
+
*/
|
|
275
|
+
async selectRecoveryStrategy(errorAnalysis) {
|
|
276
|
+
const { suggestedStrategies } = errorAnalysis;
|
|
277
|
+
|
|
278
|
+
// Try suggested strategies in order
|
|
279
|
+
for (const strategyName of suggestedStrategies) {
|
|
280
|
+
if (this.strategyRegistry.has(strategyName)) {
|
|
281
|
+
return strategyName;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Apply recovery strategy
|
|
290
|
+
* @param {string} strategyName - Strategy to apply
|
|
291
|
+
* @param {Object} context - Execution context
|
|
292
|
+
* @returns {Object} - Recovery result
|
|
293
|
+
*/
|
|
294
|
+
async applyRecoveryStrategy(strategyName, context) {
|
|
295
|
+
const strategy = this.strategyRegistry.get(strategyName);
|
|
296
|
+
if (!strategy) {
|
|
297
|
+
throw new Error(`Strategy not found: ${strategyName}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
try {
|
|
301
|
+
const result = await strategy(context.error, context);
|
|
302
|
+
return result;
|
|
303
|
+
} catch (error) {
|
|
304
|
+
return {
|
|
305
|
+
success: false,
|
|
306
|
+
error: error.message
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Validate recovery by re-running tests
|
|
313
|
+
* @param {Object} context - Execution context
|
|
314
|
+
* @returns {boolean} - True if recovery successful
|
|
315
|
+
*/
|
|
316
|
+
async validateRecovery(context) {
|
|
317
|
+
// This would run tests to verify the fix
|
|
318
|
+
// For now, return true (actual implementation would run tests)
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Register a recovery strategy
|
|
324
|
+
* @param {string} name - Strategy name
|
|
325
|
+
* @param {Function} strategyFn - Strategy function
|
|
326
|
+
*/
|
|
327
|
+
registerStrategy(name, strategyFn) {
|
|
328
|
+
this.strategyRegistry.set(name, strategyFn);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Get available strategies
|
|
333
|
+
* @returns {Array} - Strategy names
|
|
334
|
+
*/
|
|
335
|
+
getAvailableStrategies() {
|
|
336
|
+
return Array.from(this.strategyRegistry.keys());
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Record successful recovery
|
|
341
|
+
* @param {Object} errorAnalysis - Error analysis
|
|
342
|
+
* @param {string} strategy - Strategy that succeeded
|
|
343
|
+
*/
|
|
344
|
+
async recordSuccess(errorAnalysis, strategy) {
|
|
345
|
+
if (!this.learningEnabled) return;
|
|
346
|
+
|
|
347
|
+
const { type } = errorAnalysis;
|
|
348
|
+
|
|
349
|
+
if (!this.successHistory.has(type)) {
|
|
350
|
+
this.successHistory.set(type, []);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const successes = this.successHistory.get(type);
|
|
354
|
+
if (!successes.includes(strategy)) {
|
|
355
|
+
successes.unshift(strategy); // Add to front
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
this.recoveryLog.push({
|
|
359
|
+
timestamp: new Date().toISOString(),
|
|
360
|
+
type,
|
|
361
|
+
strategy,
|
|
362
|
+
success: true
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
// Persist learning data
|
|
366
|
+
await this.saveLearningData();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Record failed recovery
|
|
371
|
+
* @param {Object} errorAnalysis - Error analysis
|
|
372
|
+
* @param {string} strategy - Strategy that failed
|
|
373
|
+
*/
|
|
374
|
+
async recordFailure(errorAnalysis, strategy) {
|
|
375
|
+
if (!this.learningEnabled) return;
|
|
376
|
+
|
|
377
|
+
const { type } = errorAnalysis;
|
|
378
|
+
|
|
379
|
+
if (!this.failureHistory.has(type)) {
|
|
380
|
+
this.failureHistory.set(type, []);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const failures = this.failureHistory.get(type);
|
|
384
|
+
if (!failures.includes(strategy)) {
|
|
385
|
+
failures.push(strategy);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
this.recoveryLog.push({
|
|
389
|
+
timestamp: new Date().toISOString(),
|
|
390
|
+
type,
|
|
391
|
+
strategy,
|
|
392
|
+
success: false
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
// Persist learning data
|
|
396
|
+
await this.saveLearningData();
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Load learning data from disk
|
|
401
|
+
*/
|
|
402
|
+
async loadLearningData() {
|
|
403
|
+
try {
|
|
404
|
+
if (await fs.pathExists(this.learningDataPath)) {
|
|
405
|
+
const data = await fs.readJson(this.learningDataPath);
|
|
406
|
+
|
|
407
|
+
// Restore success history
|
|
408
|
+
if (data.successHistory) {
|
|
409
|
+
this.successHistory = new Map(Object.entries(data.successHistory));
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Restore failure history
|
|
413
|
+
if (data.failureHistory) {
|
|
414
|
+
this.failureHistory = new Map(Object.entries(data.failureHistory));
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Restore recovery log
|
|
418
|
+
if (data.recoveryLog) {
|
|
419
|
+
this.recoveryLog = data.recoveryLog;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
} catch (error) {
|
|
423
|
+
console.warn('Failed to load learning data:', error.message);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Save learning data to disk
|
|
429
|
+
*/
|
|
430
|
+
async saveLearningData() {
|
|
431
|
+
try {
|
|
432
|
+
await fs.ensureDir(path.dirname(this.learningDataPath));
|
|
433
|
+
|
|
434
|
+
const data = {
|
|
435
|
+
successHistory: Object.fromEntries(this.successHistory),
|
|
436
|
+
failureHistory: Object.fromEntries(this.failureHistory),
|
|
437
|
+
recoveryLog: this.recoveryLog,
|
|
438
|
+
lastUpdated: new Date().toISOString()
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
await fs.writeJson(this.learningDataPath, data, { spaces: 2 });
|
|
442
|
+
} catch (error) {
|
|
443
|
+
console.warn('Failed to save learning data:', error.message);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Clear learning data
|
|
449
|
+
*/
|
|
450
|
+
async clearLearningData() {
|
|
451
|
+
this.successHistory.clear();
|
|
452
|
+
this.failureHistory.clear();
|
|
453
|
+
this.recoveryLog = [];
|
|
454
|
+
|
|
455
|
+
try {
|
|
456
|
+
if (await fs.pathExists(this.learningDataPath)) {
|
|
457
|
+
await fs.remove(this.learningDataPath);
|
|
458
|
+
}
|
|
459
|
+
} catch (error) {
|
|
460
|
+
console.warn('Failed to clear learning data:', error.message);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Get recovery log
|
|
466
|
+
* @returns {Array} - Recovery log entries
|
|
467
|
+
*/
|
|
468
|
+
getRecoveryLog() {
|
|
469
|
+
return this.recoveryLog;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Get success rate for strategy
|
|
474
|
+
* @param {string} strategy - Strategy name
|
|
475
|
+
* @returns {number} - Success rate (0-1)
|
|
476
|
+
*/
|
|
477
|
+
getSuccessRate(strategy) {
|
|
478
|
+
const entries = this.recoveryLog.filter(e => e.strategy === strategy);
|
|
479
|
+
if (entries.length === 0) return 0;
|
|
480
|
+
|
|
481
|
+
const successes = entries.filter(e => e.success).length;
|
|
482
|
+
return successes / entries.length;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Prioritize errors by severity
|
|
487
|
+
* @param {Array} errors - Array of errors with analysis
|
|
488
|
+
* @returns {Array} - Sorted errors (critical -> high -> medium -> low)
|
|
489
|
+
*/
|
|
490
|
+
prioritizeErrors(errors) {
|
|
491
|
+
const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
|
|
492
|
+
|
|
493
|
+
return errors.sort((a, b) => {
|
|
494
|
+
const severityA = severityOrder[a.analysis.severity] || 999;
|
|
495
|
+
const severityB = severityOrder[b.analysis.severity] || 999;
|
|
496
|
+
return severityA - severityB;
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Get resolution order for multiple errors
|
|
502
|
+
* @param {Array} errors - Array of errors
|
|
503
|
+
* @returns {Array} - Errors with analysis, sorted by priority
|
|
504
|
+
*/
|
|
505
|
+
async getResolutionOrder(errors) {
|
|
506
|
+
const analyzed = errors.map(error => ({
|
|
507
|
+
error,
|
|
508
|
+
analysis: this.analyzeError(error)
|
|
509
|
+
}));
|
|
510
|
+
|
|
511
|
+
return this.prioritizeErrors(analyzed);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Attempt error recovery with retry limit
|
|
516
|
+
* @param {Error} error - Error to recover from
|
|
517
|
+
* @param {Object} context - Execution context
|
|
518
|
+
* @returns {Object} - Recovery result
|
|
519
|
+
*/
|
|
520
|
+
async attemptRecovery(error, context) {
|
|
521
|
+
// Check retry limit
|
|
522
|
+
if (this.isRetryLimitReached(error)) {
|
|
523
|
+
await this.triggerEmergencyPause(
|
|
524
|
+
error,
|
|
525
|
+
`Maximum retry attempts (${this.config.maxAttempts}) reached`
|
|
526
|
+
);
|
|
527
|
+
return {
|
|
528
|
+
success: false,
|
|
529
|
+
message: 'Retry limit reached',
|
|
530
|
+
requiresUserIntervention: true
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Increment attempt count
|
|
535
|
+
const attemptNumber = this.incrementAttemptCount(error);
|
|
536
|
+
|
|
537
|
+
const analysis = this.analyzeError(error, context);
|
|
538
|
+
const strategy = await this.selectRecoveryStrategy(analysis);
|
|
539
|
+
|
|
540
|
+
if (!strategy) {
|
|
541
|
+
return {
|
|
542
|
+
success: false,
|
|
543
|
+
message: 'No suitable recovery strategy found',
|
|
544
|
+
attemptNumber
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
const result = await this.applyRecoveryStrategy(strategy, { ...context, error });
|
|
549
|
+
|
|
550
|
+
if (result.success) {
|
|
551
|
+
await this.recordSuccess(analysis, strategy);
|
|
552
|
+
this.resetAttemptCount(error); // Reset on success
|
|
553
|
+
} else {
|
|
554
|
+
await this.recordFailure(analysis, strategy);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return {
|
|
558
|
+
...result,
|
|
559
|
+
attemptNumber,
|
|
560
|
+
strategy
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Record error for tracking
|
|
566
|
+
* @param {Error} error - Error to record
|
|
567
|
+
*/
|
|
568
|
+
async recordError(error) {
|
|
569
|
+
const analysis = this.analyzeError(error);
|
|
570
|
+
this.recoveryLog.push({
|
|
571
|
+
timestamp: new Date().toISOString(),
|
|
572
|
+
type: analysis.type,
|
|
573
|
+
severity: analysis.severity,
|
|
574
|
+
message: error.message,
|
|
575
|
+
recorded: true
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
module.exports = ErrorRecoveryManager;
|