claude-flow-novice 2.15.2 → 2.15.4
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/.claude/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/.claude/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/.claude/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/.claude/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/.claude/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/.claude/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/.claude/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/.claude/commands/cfn-loop-cli.md +16 -2
- package/.claude/commands/switch-api.md +31 -10
- package/.claude/hooks/cfn-BACKUP_USAGE.md +243 -243
- package/.claude/hooks/cfn-invoke-security-validation.sh +69 -69
- package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
- package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +109 -78
- package/.claude/hooks/cfn-post-edit.config.json +44 -44
- package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/.claude/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
- package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
- package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
- package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
- package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/.claude/skills/cfn-redis-coordination/get-context.sh +145 -112
- package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
- package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/.claude/skills/cfn-redis-coordination/redis-functions.sh +33 -0
- package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/.claude/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
- package/.claude/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
- package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/.claude/skills/cfn-transparency-middleware/test-integration.sh +161 -161
- package/.claude/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
- package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +107 -92
- package/.claude/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
- package/README.md +116 -475
- package/claude-assets/agents/cfn-dev-team/README.md +103 -0
- package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
- package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
- package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
- package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
- package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
- package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
- package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
- package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +828 -0
- package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
- package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
- package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
- package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
- package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
- package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
- package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
- package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
- package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
- package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
- package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
- package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
- package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
- package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
- package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
- package/claude-assets/commands/cfn-loop-cli.md +16 -2
- package/claude-assets/commands/switch-api.md +31 -10
- package/claude-assets/hooks/cfn-BACKUP_USAGE.md +243 -243
- package/claude-assets/hooks/cfn-invoke-security-validation.sh +69 -69
- package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
- package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +109 -78
- package/claude-assets/hooks/cfn-post-edit.config.json +44 -44
- package/claude-assets/hooks/cfn-post-execution/memory-cleanup.sh +19 -19
- package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
- package/claude-assets/hooks/cfn-pre-execution/memory-check.sh +19 -19
- package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
- package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
- package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +543 -572
- package/claude-assets/skills/agent-lifecycle/simple-audit.sh +57 -30
- package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
- package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
- package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
- package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
- package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
- package/claude-assets/skills/bootstrap/database-connection.md +464 -0
- package/claude-assets/skills/bootstrap/error-handling.md +580 -0
- package/claude-assets/skills/bootstrap/file-operations.md +699 -0
- package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
- package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
- package/claude-assets/skills/cfn-automatic-memory-persistence/persist-agent-output.sh +48 -48
- package/claude-assets/skills/cfn-automatic-memory-persistence/query-agent-history.sh +34 -34
- package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
- package/claude-assets/skills/cfn-deliverable-validation/confidence-calculator.sh +261 -261
- package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
- package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
- package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
- package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
- package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
- package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
- package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
- package/claude-assets/skills/cfn-expert-update/update-expert.sh +345 -345
- package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
- package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
- package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
- package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
- package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
- package/claude-assets/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
- package/claude-assets/skills/cfn-intervention-detector/detect-intervention.sh +110 -110
- package/claude-assets/skills/cfn-intervention-orchestrator/execute-intervention.sh +58 -58
- package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
- package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
- package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
- package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
- package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
- package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
- package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
- package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
- package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
- package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
- package/claude-assets/skills/cfn-loop2-output-processing/process-validator-output.sh +275 -275
- package/claude-assets/skills/cfn-memory-management/check-memory.sh +159 -159
- package/claude-assets/skills/cfn-memory-management/cleanup-memory.sh +196 -196
- package/claude-assets/skills/cfn-node-heap-sizer/task-mode-heap-limiter.sh +325 -325
- package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
- package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
- package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
- package/claude-assets/skills/cfn-playbook-auto-update/auto-update-playbook.sh +85 -85
- package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
- package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
- package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
- package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
- package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
- package/claude-assets/skills/cfn-redis-coordination/get-context.sh +145 -112
- package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
- package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
- package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
- package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +33 -0
- package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
- package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
- package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
- package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
- package/claude-assets/skills/cfn-scope-simplifier/simplify-scope.sh +67 -67
- package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
- package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
- package/claude-assets/skills/cfn-specialist-injection/recommend-specialist.sh +56 -56
- package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
- package/claude-assets/skills/cfn-standardized-error-handling/capture-agent-error.sh +86 -86
- package/claude-assets/skills/cfn-standardized-error-handling/test-error-handling.sh +165 -165
- package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
- package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
- package/claude-assets/skills/cfn-task-config-init/initialize-config.sh +264 -264
- package/claude-assets/skills/cfn-task-decomposition/task-decomposer.sh +278 -278
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
- package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
- package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
- package/claude-assets/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
- package/claude-assets/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
- package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
- package/claude-assets/skills/cfn-transparency-middleware/test-integration.sh +161 -161
- package/claude-assets/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
- package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +107 -92
- package/claude-assets/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
- package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
- package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
- package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
- package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
- package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
- package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
- package/claude-assets/skills/cfn-utilities/test.sh +317 -0
- package/claude-assets/skills/docker-build/SKILL.md +96 -203
- package/claude-assets/skills/docker-build/build.sh +73 -73
- package/claude-assets/skills/integration/agent-handoff.sh +492 -0
- package/claude-assets/skills/integration/file-operations.sh +414 -0
- package/claude-assets/skills/json-validation/SKILL.md +431 -0
- package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
- package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
- package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
- package/claude-assets/skills/workflow-codification/APPROVAL_WORKFLOW.md +806 -0
- package/claude-assets/skills/workflow-codification/COST_TRACKING.md +637 -0
- package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
- package/claude-assets/skills/workflow-codification/EDGE_CASE_TRACKING.md +404 -0
- package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
- package/claude-assets/skills/workflow-codification/README_PHASE4.md +457 -0
- package/claude-assets/skills/workflow-codification/SKILL.md +110 -0
- package/claude-assets/skills/workflow-codification/analyze-patterns.sh +899 -0
- package/claude-assets/skills/workflow-codification/approval-workflow.sh +514 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
- package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
- package/claude-assets/skills/workflow-codification/generate-skill-update.sh +525 -0
- package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
- package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
- package/claude-assets/skills/workflow-codification/review-skill.sh +643 -0
- package/claude-assets/skills/workflow-codification/templates/email-notification.txt +114 -0
- package/claude-assets/skills/workflow-codification/templates/slack-notification.md +85 -0
- package/claude-assets/skills/workflow-codification/test-integration.sh +296 -0
- package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh +486 -0
- package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
- package/claude-assets/skills/workflow-codification/track-edge-case.sh +290 -0
- package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
- package/dist/ace/ace-curator.js +10 -2
- package/dist/ace/ace-curator.js.map +1 -1
- package/dist/ace/ace-generator.js +4 -0
- package/dist/ace/ace-generator.js.map +1 -1
- package/dist/ace/ace-reflector.js +1 -1
- package/dist/ace/ace-reflector.js.map +1 -1
- package/dist/ace/context-injection.js +24 -2
- package/dist/ace/context-injection.js.map +1 -1
- package/dist/agents/agent-loader.js +146 -165
- package/dist/agents/agent-loader.js.map +1 -1
- package/dist/agents/task-agent-integration.js +1 -1
- package/dist/agents/task-agent-integration.js.map +1 -1
- package/dist/api/health-endpoints.js +390 -0
- package/dist/api/health-endpoints.js.map +1 -0
- package/dist/cli/agent-executor.js +4 -1
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/cli/agent-prompt-builder.js +89 -1
- package/dist/cli/agent-prompt-builder.js.map +1 -1
- package/dist/cli/agent-spawn.js +130 -37
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/config-manager.js +91 -109
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/skill-cache-validator.js +412 -0
- package/dist/cli/skill-cache-validator.js.map +1 -0
- package/dist/cli/skill-cli.js +991 -0
- package/dist/cli/skill-cli.js.map +1 -0
- package/dist/cli/skill-execution-logger.js +284 -0
- package/dist/cli/skill-execution-logger.js.map +1 -0
- package/dist/cli/skill-loader.js +457 -0
- package/dist/cli/skill-loader.js.map +1 -0
- package/dist/coordination/event-bus.js +2 -2
- package/dist/coordination/event-bus.js.map +1 -1
- package/dist/coordination/fleet-manager.js +1 -1
- package/dist/coordination/fleet-manager.js.map +1 -1
- package/dist/coordination/index.js +23 -9
- package/dist/coordination/index.js.map +1 -1
- package/dist/coordination/types/fleet-manager.types.js.map +1 -1
- package/dist/db/migration-manager.js +483 -0
- package/dist/db/migration-manager.js.map +1 -0
- package/dist/db/skills-query.js +535 -0
- package/dist/db/skills-query.js.map +1 -0
- package/dist/integration/DatabaseHandoff.js +507 -0
- package/dist/integration/DatabaseHandoff.js.map +1 -0
- package/dist/integration/StandardAdapter.js +291 -0
- package/dist/integration/StandardAdapter.js.map +1 -0
- package/dist/jobs/edge-case-analyzer.js +367 -0
- package/dist/jobs/edge-case-analyzer.js.map +1 -0
- package/dist/jobs/promotion-sla-enforcer.js +288 -0
- package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
- package/dist/lib/agent-output-parser.js +518 -0
- package/dist/lib/agent-output-parser.js.map +1 -0
- package/dist/lib/agent-output-validator.js +950 -0
- package/dist/lib/agent-output-validator.js.map +1 -0
- package/dist/lib/agent-workspace.js +281 -0
- package/dist/lib/agent-workspace.js.map +1 -0
- package/dist/lib/artifact-registry.js +443 -0
- package/dist/lib/artifact-registry.js.map +1 -0
- package/dist/lib/atomic-file-writer.js +377 -0
- package/dist/lib/atomic-file-writer.js.map +1 -0
- package/dist/lib/backup-manager.js +779 -0
- package/dist/lib/backup-manager.js.map +1 -0
- package/dist/lib/checkpoint-manager.js +837 -0
- package/dist/lib/checkpoint-manager.js.map +1 -0
- package/dist/lib/circuit-breaker.js +340 -0
- package/dist/lib/circuit-breaker.js.map +1 -0
- package/dist/lib/completion-signal-handler.js +243 -0
- package/dist/lib/completion-signal-handler.js.map +1 -0
- package/dist/lib/config-manager.js +312 -0
- package/dist/lib/config-manager.js.map +1 -0
- package/dist/lib/config-migrator.js +386 -0
- package/dist/lib/config-migrator.js.map +1 -0
- package/dist/lib/config-validator.js +687 -0
- package/dist/lib/config-validator.js.map +1 -0
- package/dist/lib/correlation-cache.js +311 -0
- package/dist/lib/correlation-cache.js.map +1 -0
- package/dist/lib/correlation.js +263 -0
- package/dist/lib/correlation.js.map +1 -0
- package/dist/lib/database-service/connection-pool-manager.js +520 -0
- package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
- package/dist/lib/database-service/correlation.js +329 -0
- package/dist/lib/database-service/correlation.js.map +1 -0
- package/dist/lib/database-service/errors.js +120 -0
- package/dist/lib/database-service/errors.js.map +1 -0
- package/dist/lib/database-service/index.js +168 -0
- package/dist/lib/database-service/index.js.map +1 -0
- package/dist/lib/database-service/postgres-adapter.js +526 -0
- package/dist/lib/database-service/postgres-adapter.js.map +1 -0
- package/dist/lib/database-service/redis-adapter.js +360 -0
- package/dist/lib/database-service/redis-adapter.js.map +1 -0
- package/dist/lib/database-service/sqlite-adapter.js +544 -0
- package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
- package/dist/lib/database-service/transaction-manager.js +773 -0
- package/dist/lib/database-service/transaction-manager.js.map +1 -0
- package/dist/lib/database-service/types.js +23 -0
- package/dist/lib/database-service/types.js.map +1 -0
- package/dist/lib/deadlock-resolver.js +292 -0
- package/dist/lib/deadlock-resolver.js.map +1 -0
- package/dist/lib/distributed-lock.js +451 -0
- package/dist/lib/distributed-lock.js.map +1 -0
- package/dist/lib/edge-case-deduplicator.js +227 -0
- package/dist/lib/edge-case-deduplicator.js.map +1 -0
- package/dist/lib/encryption-manager.js +322 -0
- package/dist/lib/encryption-manager.js.map +1 -0
- package/dist/lib/error-aggregator.js +234 -0
- package/dist/lib/error-aggregator.js.map +1 -0
- package/dist/lib/errors.js +287 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/file-lock-manager.js +578 -0
- package/dist/lib/file-lock-manager.js.map +1 -0
- package/dist/lib/file-operations.js +367 -0
- package/dist/lib/file-operations.js.map +1 -0
- package/dist/lib/idempotent-write.js +237 -0
- package/dist/lib/idempotent-write.js.map +1 -0
- package/dist/lib/integration-schema-validator.js +522 -0
- package/dist/lib/integration-schema-validator.js.map +1 -0
- package/dist/lib/lock-health-monitor.js +298 -0
- package/dist/lib/lock-health-monitor.js.map +1 -0
- package/dist/lib/log-shipper.js +422 -0
- package/dist/lib/log-shipper.js.map +1 -0
- package/dist/lib/logging.js +146 -0
- package/dist/lib/logging.js.map +1 -0
- package/dist/lib/message-deduplicator.js +439 -0
- package/dist/lib/message-deduplicator.js.map +1 -0
- package/dist/lib/multi-system-query.js +604 -0
- package/dist/lib/multi-system-query.js.map +1 -0
- package/dist/lib/orphan-detector.js +332 -0
- package/dist/lib/orphan-detector.js.map +1 -0
- package/dist/lib/password-generator.js +166 -0
- package/dist/lib/password-generator.js.map +1 -0
- package/dist/lib/path-validator.js +429 -0
- package/dist/lib/path-validator.js.map +1 -0
- package/dist/lib/query-translator.js +905 -0
- package/dist/lib/query-translator.js.map +1 -0
- package/dist/lib/queue-recovery.js +469 -0
- package/dist/lib/queue-recovery.js.map +1 -0
- package/dist/lib/redis-queue-manager.js +512 -0
- package/dist/lib/redis-queue-manager.js.map +1 -0
- package/dist/lib/reflection-archiver.js +272 -0
- package/dist/lib/reflection-archiver.js.map +1 -0
- package/dist/lib/retry-manager.js +453 -0
- package/dist/lib/retry-manager.js.map +1 -0
- package/dist/lib/retry.js +262 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/lib/schema-transform.js +695 -0
- package/dist/lib/schema-transform.js.map +1 -0
- package/dist/lib/schema-validator.js +491 -0
- package/dist/lib/schema-validator.js.map +1 -0
- package/dist/lib/skill-cache.js +297 -0
- package/dist/lib/skill-cache.js.map +1 -0
- package/dist/lib/skill-content-manager.js +337 -0
- package/dist/lib/skill-content-manager.js.map +1 -0
- package/dist/lib/skill-frontmatter-parser.js +237 -0
- package/dist/lib/skill-frontmatter-parser.js.map +1 -0
- package/dist/lib/skill-git-integration.js +275 -0
- package/dist/lib/skill-git-integration.js.map +1 -0
- package/dist/lib/skill-markdown-validator.js +396 -0
- package/dist/lib/skill-markdown-validator.js.map +1 -0
- package/dist/lib/skill-output-parser.js +312 -0
- package/dist/lib/skill-output-parser.js.map +1 -0
- package/dist/lib/unified-query-api.js +467 -0
- package/dist/lib/unified-query-api.js.map +1 -0
- package/dist/middleware/auth-middleware.js +350 -0
- package/dist/middleware/auth-middleware.js.map +1 -0
- package/dist/middleware/schema-validation.js +347 -0
- package/dist/middleware/schema-validation.js.map +1 -0
- package/dist/providers/anthropic-provider.js +1 -1
- package/dist/providers/anthropic-provider.js.map +1 -1
- package/dist/providers/provider-factory.js +2 -2
- package/dist/providers/provider-factory.js.map +1 -1
- package/dist/services/edge-case-analyzer.js +321 -0
- package/dist/services/edge-case-analyzer.js.map +1 -0
- package/dist/services/edge-case-deduplicator.js +266 -0
- package/dist/services/edge-case-deduplicator.js.map +1 -0
- package/dist/services/edge-case-detector.js +337 -0
- package/dist/services/edge-case-detector.js.map +1 -0
- package/dist/services/edge-case-tracker.js +547 -0
- package/dist/services/edge-case-tracker.js.map +1 -0
- package/dist/services/health-check-system.js +586 -0
- package/dist/services/health-check-system.js.map +1 -0
- package/dist/services/metrics-logger.js +412 -0
- package/dist/services/metrics-logger.js.map +1 -0
- package/dist/services/patch-generator.js +378 -0
- package/dist/services/patch-generator.js.map +1 -0
- package/dist/services/patch-validator.js +337 -0
- package/dist/services/patch-validator.js.map +1 -0
- package/dist/services/performance-monitor.js +811 -0
- package/dist/services/performance-monitor.js.map +1 -0
- package/dist/services/promotion-pipeline.js +918 -0
- package/dist/services/promotion-pipeline.js.map +1 -0
- package/dist/services/promotion-validator.js +394 -0
- package/dist/services/promotion-validator.js.map +1 -0
- package/dist/services/reflection-logger.js +388 -0
- package/dist/services/reflection-logger.js.map +1 -0
- package/dist/services/skill-deployment.js +472 -0
- package/dist/services/skill-deployment.js.map +1 -0
- package/dist/services/skill-loader.js +427 -0
- package/dist/services/skill-loader.js.map +1 -0
- package/dist/services/skill-promotion.js +372 -0
- package/dist/services/skill-promotion.js.map +1 -0
- package/dist/services/skill-validator.js +454 -0
- package/dist/services/skill-validator.js.map +1 -0
- package/dist/services/skill-versioning.js +244 -0
- package/dist/services/skill-versioning.js.map +1 -0
- package/dist/services/workspace-supervisor.js +597 -0
- package/dist/services/workspace-supervisor.js.map +1 -0
- package/dist/types/agent-output.js +44 -0
- package/dist/types/agent-output.js.map +1 -0
- package/dist/types/config.js +28 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/edge-case.js +45 -0
- package/dist/types/edge-case.js.map +1 -0
- package/package.json +201 -176
- package/readme/README.md +19 -4
- package/scripts/artifact-cleanup.sh +392 -0
- package/scripts/backup-cleanup.sh +627 -0
- package/scripts/cleanup-workspaces.sh +412 -0
- package/scripts/cleanup-yaml-configs.sh +141 -0
- package/scripts/deploy-approved-skills.sh +263 -0
- package/scripts/deploy-production.sh +355 -355
- package/scripts/docker-playwright-fix.sh +311 -311
- package/scripts/docker-rebuild-all-agents.sh +127 -127
- package/scripts/health-check.sh +447 -0
- package/scripts/log-aggregator.sh +554 -0
- package/scripts/log-monitor.sh +629 -0
- package/scripts/manage-agent-workspaces.sh +434 -0
- package/scripts/memory-leak-prevention.sh +305 -305
- package/scripts/migrate-artifacts.sh +563 -0
- package/scripts/migrate-schema.sh +533 -0
- package/scripts/migrate-yaml-to-json.sh +465 -0
- package/scripts/promote-staged-skills.sh +423 -0
- package/scripts/run-marketing-tests.sh +42 -42
- package/scripts/update_paths.sh +46 -46
- package/scripts/verify-no-secrets.sh +88 -35
- package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
- package/README.md.backup_before_replace +0 -781
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
- package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
- package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
- package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge Case Analyzer
|
|
3
|
+
* Part of Task 5.1: Edge Case Analyzer & Skill Patcher
|
|
4
|
+
*
|
|
5
|
+
* Analyzes skill execution failures to identify patterns and categorize edge cases.
|
|
6
|
+
* Supports pattern matching, confidence scoring, and failure statistics.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Automatic failure categorization (syntax, logic, timeout, validation, unknown)
|
|
10
|
+
* - Pattern matching for similar failures
|
|
11
|
+
* - Confidence scoring based on failure frequency
|
|
12
|
+
* - Integration with DatabaseService
|
|
13
|
+
* - Performance optimized (<500ms for pattern matching)
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* const analyzer = new EdgeCaseAnalyzer({ dbPath: './edge-cases.db' });
|
|
17
|
+
* const pattern = await analyzer.analyzeFailure(error, { skillId: 'my-skill' });
|
|
18
|
+
* console.log(`Detected ${pattern.category} with ${pattern.confidence} confidence`);
|
|
19
|
+
*/ import * as crypto from 'crypto';
|
|
20
|
+
import Database from 'better-sqlite3';
|
|
21
|
+
import { createLogger } from '../lib/logging.js';
|
|
22
|
+
import { StandardError, ErrorCode } from '../lib/errors.js';
|
|
23
|
+
const logger = createLogger('edge-case-analyzer');
|
|
24
|
+
/**
|
|
25
|
+
* Failure category classification
|
|
26
|
+
*/ export var FailureCategory = /*#__PURE__*/ function(FailureCategory) {
|
|
27
|
+
FailureCategory["SYNTAX_ERROR"] = "SYNTAX_ERROR";
|
|
28
|
+
FailureCategory["LOGIC_ERROR"] = "LOGIC_ERROR";
|
|
29
|
+
FailureCategory["TIMEOUT"] = "TIMEOUT";
|
|
30
|
+
FailureCategory["VALIDATION_ERROR"] = "VALIDATION_ERROR";
|
|
31
|
+
FailureCategory["UNKNOWN"] = "UNKNOWN";
|
|
32
|
+
return FailureCategory;
|
|
33
|
+
}({});
|
|
34
|
+
/**
|
|
35
|
+
* Edge Case Analyzer Service
|
|
36
|
+
*/ export class EdgeCaseAnalyzer {
|
|
37
|
+
db;
|
|
38
|
+
constructor(config){
|
|
39
|
+
this.db = new Database(config.dbPath);
|
|
40
|
+
this.initializeDatabase();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Initialize database schema
|
|
44
|
+
*/ initializeDatabase() {
|
|
45
|
+
this.db.exec(`
|
|
46
|
+
CREATE TABLE IF NOT EXISTS edge_cases (
|
|
47
|
+
id TEXT PRIMARY KEY,
|
|
48
|
+
skill_id TEXT NOT NULL,
|
|
49
|
+
category TEXT NOT NULL,
|
|
50
|
+
error_message TEXT,
|
|
51
|
+
stack_trace TEXT,
|
|
52
|
+
context TEXT,
|
|
53
|
+
detected_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
54
|
+
pattern_hash TEXT,
|
|
55
|
+
confidence REAL
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_edge_cases_skill ON edge_cases(skill_id);
|
|
59
|
+
CREATE INDEX IF NOT EXISTS idx_edge_cases_category ON edge_cases(category);
|
|
60
|
+
CREATE INDEX IF NOT EXISTS idx_edge_cases_pattern ON edge_cases(pattern_hash);
|
|
61
|
+
`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Categorize failure based on error type and context
|
|
65
|
+
*
|
|
66
|
+
* Performance target: <200ms
|
|
67
|
+
*/ categorizeFailure(error, context) {
|
|
68
|
+
const startTime = Date.now();
|
|
69
|
+
try {
|
|
70
|
+
// Check for syntax errors
|
|
71
|
+
if (error instanceof SyntaxError) {
|
|
72
|
+
logger.debug('Categorized as SYNTAX_ERROR', {
|
|
73
|
+
error: error.message
|
|
74
|
+
});
|
|
75
|
+
return "SYNTAX_ERROR";
|
|
76
|
+
}
|
|
77
|
+
// Check for timeout errors
|
|
78
|
+
if (error instanceof StandardError && (error.code === ErrorCode.OPERATION_TIMEOUT || error.code === ErrorCode.DB_TIMEOUT)) {
|
|
79
|
+
logger.debug('Categorized as TIMEOUT', {
|
|
80
|
+
error: error.message
|
|
81
|
+
});
|
|
82
|
+
return "TIMEOUT";
|
|
83
|
+
}
|
|
84
|
+
if (error.message && /timeout|timed out/i.test(error.message)) {
|
|
85
|
+
logger.debug('Categorized as TIMEOUT from message', {
|
|
86
|
+
error: error.message
|
|
87
|
+
});
|
|
88
|
+
return "TIMEOUT";
|
|
89
|
+
}
|
|
90
|
+
// Check for validation errors
|
|
91
|
+
if (error instanceof StandardError && (error.code === ErrorCode.VALIDATION_FAILED || error.code === ErrorCode.INVALID_INPUT || error.code === ErrorCode.DB_VALIDATION_FAILED)) {
|
|
92
|
+
logger.debug('Categorized as VALIDATION_ERROR', {
|
|
93
|
+
error: error.message
|
|
94
|
+
});
|
|
95
|
+
return "VALIDATION_ERROR";
|
|
96
|
+
}
|
|
97
|
+
// Check for null/undefined errors (validation)
|
|
98
|
+
if (error instanceof TypeError && (error.message.includes('null') || error.message.includes('undefined') || error.message.includes('Cannot read property'))) {
|
|
99
|
+
logger.debug('Categorized as VALIDATION_ERROR (null/undefined)', {
|
|
100
|
+
error: error.message
|
|
101
|
+
});
|
|
102
|
+
return "VALIDATION_ERROR";
|
|
103
|
+
}
|
|
104
|
+
// Check for logic errors (file not found, reference errors, etc.)
|
|
105
|
+
if (error instanceof ReferenceError) {
|
|
106
|
+
logger.debug('Categorized as LOGIC_ERROR (ReferenceError)', {
|
|
107
|
+
error: error.message
|
|
108
|
+
});
|
|
109
|
+
return "LOGIC_ERROR";
|
|
110
|
+
}
|
|
111
|
+
if (error instanceof StandardError && (error.code === ErrorCode.FILE_NOT_FOUND || error.code === ErrorCode.FILE_WRITE_FAILED)) {
|
|
112
|
+
logger.debug('Categorized as LOGIC_ERROR (file operation)', {
|
|
113
|
+
error: error.message
|
|
114
|
+
});
|
|
115
|
+
return "LOGIC_ERROR";
|
|
116
|
+
}
|
|
117
|
+
// Default to unknown
|
|
118
|
+
logger.debug('Categorized as UNKNOWN', {
|
|
119
|
+
error: error.message
|
|
120
|
+
});
|
|
121
|
+
return "UNKNOWN";
|
|
122
|
+
} finally{
|
|
123
|
+
const duration = Date.now() - startTime;
|
|
124
|
+
logger.debug('Categorization completed', {
|
|
125
|
+
durationMs: duration
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Find similar failures by skill and category
|
|
131
|
+
*
|
|
132
|
+
* Performance target: <500ms
|
|
133
|
+
*/ findSimilarFailures(failure) {
|
|
134
|
+
const startTime = Date.now();
|
|
135
|
+
try {
|
|
136
|
+
const stmt = this.db.prepare(`
|
|
137
|
+
SELECT * FROM edge_cases
|
|
138
|
+
WHERE skill_id = ?
|
|
139
|
+
AND category = ?
|
|
140
|
+
AND id != ?
|
|
141
|
+
ORDER BY detected_at DESC
|
|
142
|
+
LIMIT 10
|
|
143
|
+
`);
|
|
144
|
+
const rows = stmt.all(failure.skillId, failure.category, failure.id);
|
|
145
|
+
const similar = rows.map((row)=>({
|
|
146
|
+
id: row.id,
|
|
147
|
+
skillId: row.skill_id,
|
|
148
|
+
category: row.category,
|
|
149
|
+
errorMessage: row.error_message,
|
|
150
|
+
stackTrace: row.stack_trace,
|
|
151
|
+
context: JSON.parse(row.context || '{}'),
|
|
152
|
+
detectedAt: new Date(row.detected_at),
|
|
153
|
+
patternHash: row.pattern_hash,
|
|
154
|
+
confidence: row.confidence
|
|
155
|
+
}));
|
|
156
|
+
logger.debug('Found similar failures', {
|
|
157
|
+
count: similar.length,
|
|
158
|
+
durationMs: Date.now() - startTime
|
|
159
|
+
});
|
|
160
|
+
return similar;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
logger.error('Failed to find similar failures', error);
|
|
163
|
+
return [];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Calculate confidence score based on failure frequency
|
|
168
|
+
*
|
|
169
|
+
* Formula:
|
|
170
|
+
* - 0 failures: 0.0
|
|
171
|
+
* - 1 failure: 0.5
|
|
172
|
+
* - 2-3 failures: 0.6-0.7
|
|
173
|
+
* - 4-6 failures: 0.75-0.85
|
|
174
|
+
* - 7-10 failures: 0.85-0.95
|
|
175
|
+
* - 10+ failures: 0.95+
|
|
176
|
+
*/ calculatePatternConfidence(failures) {
|
|
177
|
+
if (failures.length === 0) {
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
if (failures.length === 1) {
|
|
181
|
+
return 0.5;
|
|
182
|
+
}
|
|
183
|
+
if (failures.length <= 3) {
|
|
184
|
+
return 0.6 + failures.length * 0.05;
|
|
185
|
+
}
|
|
186
|
+
if (failures.length <= 6) {
|
|
187
|
+
return 0.75 + (failures.length - 3) * 0.03;
|
|
188
|
+
}
|
|
189
|
+
if (failures.length <= 10) {
|
|
190
|
+
return 0.85 + (failures.length - 6) * 0.025;
|
|
191
|
+
}
|
|
192
|
+
return Math.min(0.98, 0.95 + (failures.length - 10) * 0.01);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Generate pattern hash from error message and category
|
|
196
|
+
*/ generatePatternHash(category, errorMessage) {
|
|
197
|
+
// Normalize error message (remove numbers, paths, etc.)
|
|
198
|
+
const normalized = errorMessage.replace(/\d+/g, 'N') // Replace numbers
|
|
199
|
+
.replace(/\/[^\s]*/g, '/PATH') // Replace file paths
|
|
200
|
+
.replace(/at [^\n]*/g, 'at LOCATION') // Replace stack locations
|
|
201
|
+
.toLowerCase();
|
|
202
|
+
const hashInput = `${category}:${normalized}`;
|
|
203
|
+
return crypto.createHash('sha256').update(hashInput).digest('hex').substring(0, 16);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Analyze failure and detect patterns
|
|
207
|
+
*
|
|
208
|
+
* Returns failure pattern with confidence score
|
|
209
|
+
*/ async analyzeFailure(error, context) {
|
|
210
|
+
const startTime = Date.now();
|
|
211
|
+
// Categorize the failure
|
|
212
|
+
const category = this.categorizeFailure(error, context);
|
|
213
|
+
// Generate pattern hash
|
|
214
|
+
const patternHash = this.generatePatternHash(category, error.message);
|
|
215
|
+
// Create failure record
|
|
216
|
+
const failure = {
|
|
217
|
+
id: crypto.randomUUID(),
|
|
218
|
+
skillId: context.skillId || 'unknown',
|
|
219
|
+
category,
|
|
220
|
+
errorMessage: error.message,
|
|
221
|
+
stackTrace: error.stack || '',
|
|
222
|
+
context,
|
|
223
|
+
detectedAt: new Date(),
|
|
224
|
+
patternHash
|
|
225
|
+
};
|
|
226
|
+
// Find similar failures
|
|
227
|
+
const similar = this.findSimilarFailures(failure);
|
|
228
|
+
// Calculate confidence
|
|
229
|
+
const allFailures = [
|
|
230
|
+
failure,
|
|
231
|
+
...similar
|
|
232
|
+
];
|
|
233
|
+
const confidence = this.calculatePatternConfidence(allFailures);
|
|
234
|
+
// Store failure
|
|
235
|
+
this.db.prepare(`
|
|
236
|
+
INSERT INTO edge_cases (id, skill_id, category, error_message, stack_trace, context, pattern_hash, confidence)
|
|
237
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
238
|
+
`).run(failure.id, failure.skillId, failure.category, failure.errorMessage, failure.stackTrace, JSON.stringify(failure.context), failure.patternHash, confidence);
|
|
239
|
+
// Build pattern
|
|
240
|
+
const skillIds = Array.from(new Set([
|
|
241
|
+
failure.skillId,
|
|
242
|
+
...similar.map((f)=>f.skillId)
|
|
243
|
+
]));
|
|
244
|
+
const pattern = {
|
|
245
|
+
category,
|
|
246
|
+
patternHash,
|
|
247
|
+
failureCount: allFailures.length,
|
|
248
|
+
confidence,
|
|
249
|
+
firstSeenAt: similar.length > 0 ? similar[similar.length - 1].detectedAt : failure.detectedAt,
|
|
250
|
+
lastSeenAt: failure.detectedAt,
|
|
251
|
+
skillIds
|
|
252
|
+
};
|
|
253
|
+
logger.info('Failure analyzed', {
|
|
254
|
+
category,
|
|
255
|
+
confidence,
|
|
256
|
+
failureCount: allFailures.length,
|
|
257
|
+
durationMs: Date.now() - startTime
|
|
258
|
+
});
|
|
259
|
+
return pattern;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Get failure statistics
|
|
263
|
+
*/ getFailureStats(skillId) {
|
|
264
|
+
const whereClause = skillId ? 'WHERE skill_id = ?' : '';
|
|
265
|
+
const params = skillId ? [
|
|
266
|
+
skillId
|
|
267
|
+
] : [];
|
|
268
|
+
// Total failures
|
|
269
|
+
const totalStmt = this.db.prepare(`SELECT COUNT(*) as count FROM edge_cases ${whereClause}`);
|
|
270
|
+
const totalResult = totalStmt.get(...params);
|
|
271
|
+
const totalFailures = totalResult.count;
|
|
272
|
+
// By category
|
|
273
|
+
const categoryStmt = this.db.prepare(`
|
|
274
|
+
SELECT category, COUNT(*) as count
|
|
275
|
+
FROM edge_cases
|
|
276
|
+
${whereClause}
|
|
277
|
+
GROUP BY category
|
|
278
|
+
`);
|
|
279
|
+
const categoryResults = categoryStmt.all(...params);
|
|
280
|
+
const byCategory = {};
|
|
281
|
+
for (const row of categoryResults){
|
|
282
|
+
byCategory[row.category] = row.count;
|
|
283
|
+
}
|
|
284
|
+
// Unique patterns
|
|
285
|
+
const patternsStmt = this.db.prepare(`
|
|
286
|
+
SELECT COUNT(DISTINCT pattern_hash) as count
|
|
287
|
+
FROM edge_cases
|
|
288
|
+
${whereClause}
|
|
289
|
+
`);
|
|
290
|
+
const patternsResult = patternsStmt.get(...params);
|
|
291
|
+
const uniquePatterns = patternsResult.count;
|
|
292
|
+
// Top patterns
|
|
293
|
+
const topStmt = this.db.prepare(`
|
|
294
|
+
SELECT pattern_hash, category, COUNT(*) as count
|
|
295
|
+
FROM edge_cases
|
|
296
|
+
${whereClause}
|
|
297
|
+
GROUP BY pattern_hash, category
|
|
298
|
+
ORDER BY count DESC
|
|
299
|
+
LIMIT 5
|
|
300
|
+
`);
|
|
301
|
+
const topResults = topStmt.all(...params);
|
|
302
|
+
const topPatterns = topResults.map((row)=>({
|
|
303
|
+
patternHash: row.pattern_hash,
|
|
304
|
+
count: row.count,
|
|
305
|
+
category: row.category
|
|
306
|
+
}));
|
|
307
|
+
return {
|
|
308
|
+
totalFailures,
|
|
309
|
+
byCategory,
|
|
310
|
+
uniquePatterns,
|
|
311
|
+
topPatterns
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Close database connection
|
|
316
|
+
*/ close() {
|
|
317
|
+
this.db.close();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
//# sourceMappingURL=edge-case-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/edge-case-analyzer.ts"],"sourcesContent":["/**\r\n * Edge Case Analyzer\r\n * Part of Task 5.1: Edge Case Analyzer & Skill Patcher\r\n *\r\n * Analyzes skill execution failures to identify patterns and categorize edge cases.\r\n * Supports pattern matching, confidence scoring, and failure statistics.\r\n *\r\n * Features:\r\n * - Automatic failure categorization (syntax, logic, timeout, validation, unknown)\r\n * - Pattern matching for similar failures\r\n * - Confidence scoring based on failure frequency\r\n * - Integration with DatabaseService\r\n * - Performance optimized (<500ms for pattern matching)\r\n *\r\n * Usage:\r\n * const analyzer = new EdgeCaseAnalyzer({ dbPath: './edge-cases.db' });\r\n * const pattern = await analyzer.analyzeFailure(error, { skillId: 'my-skill' });\r\n * console.log(`Detected ${pattern.category} with ${pattern.confidence} confidence`);\r\n */\r\n\r\nimport * as crypto from 'crypto';\r\nimport Database from 'better-sqlite3';\r\nimport { createLogger } from '../lib/logging.js';\r\nimport { StandardError, ErrorCode, createError } from '../lib/errors.js';\r\n\r\nconst logger = createLogger('edge-case-analyzer');\r\n\r\n/**\r\n * Failure category classification\r\n */\r\nexport enum FailureCategory {\r\n SYNTAX_ERROR = 'SYNTAX_ERROR',\r\n LOGIC_ERROR = 'LOGIC_ERROR',\r\n TIMEOUT = 'TIMEOUT',\r\n VALIDATION_ERROR = 'VALIDATION_ERROR',\r\n UNKNOWN = 'UNKNOWN',\r\n}\r\n\r\n/**\r\n * Failure record\r\n */\r\nexport interface Failure {\r\n id: string;\r\n skillId: string;\r\n category: FailureCategory;\r\n errorMessage: string;\r\n stackTrace: string;\r\n context: Record<string, any>;\r\n detectedAt: Date;\r\n patternHash: string;\r\n confidence?: number;\r\n}\r\n\r\n/**\r\n * Failure pattern with statistics\r\n */\r\nexport interface FailurePattern {\r\n category: FailureCategory;\r\n patternHash: string;\r\n failureCount: number;\r\n confidence: number;\r\n firstSeenAt: Date;\r\n lastSeenAt: Date;\r\n skillIds: string[];\r\n}\r\n\r\n/**\r\n * Failure statistics\r\n */\r\nexport interface FailureStats {\r\n totalFailures: number;\r\n byCategory: Record<string, number>;\r\n uniquePatterns: number;\r\n topPatterns: Array<{\r\n patternHash: string;\r\n count: number;\r\n category: FailureCategory;\r\n }>;\r\n}\r\n\r\n/**\r\n * Analyzer configuration\r\n */\r\nexport interface EdgeCaseAnalyzerConfig {\r\n dbPath: string;\r\n}\r\n\r\n/**\r\n * Edge Case Analyzer Service\r\n */\r\nexport class EdgeCaseAnalyzer {\r\n private db: Database.Database;\r\n\r\n constructor(config: EdgeCaseAnalyzerConfig) {\r\n this.db = new Database(config.dbPath);\r\n this.initializeDatabase();\r\n }\r\n\r\n /**\r\n * Initialize database schema\r\n */\r\n private initializeDatabase(): void {\r\n this.db.exec(`\r\n CREATE TABLE IF NOT EXISTS edge_cases (\r\n id TEXT PRIMARY KEY,\r\n skill_id TEXT NOT NULL,\r\n category TEXT NOT NULL,\r\n error_message TEXT,\r\n stack_trace TEXT,\r\n context TEXT,\r\n detected_at TEXT DEFAULT CURRENT_TIMESTAMP,\r\n pattern_hash TEXT,\r\n confidence REAL\r\n );\r\n\r\n CREATE INDEX IF NOT EXISTS idx_edge_cases_skill ON edge_cases(skill_id);\r\n CREATE INDEX IF NOT EXISTS idx_edge_cases_category ON edge_cases(category);\r\n CREATE INDEX IF NOT EXISTS idx_edge_cases_pattern ON edge_cases(pattern_hash);\r\n `);\r\n }\r\n\r\n /**\r\n * Categorize failure based on error type and context\r\n *\r\n * Performance target: <200ms\r\n */\r\n categorizeFailure(error: Error, context: any): FailureCategory {\r\n const startTime = Date.now();\r\n\r\n try {\r\n // Check for syntax errors\r\n if (error instanceof SyntaxError) {\r\n logger.debug('Categorized as SYNTAX_ERROR', { error: error.message });\r\n return FailureCategory.SYNTAX_ERROR;\r\n }\r\n\r\n // Check for timeout errors\r\n if (\r\n error instanceof StandardError &&\r\n (error.code === ErrorCode.OPERATION_TIMEOUT || error.code === ErrorCode.DB_TIMEOUT)\r\n ) {\r\n logger.debug('Categorized as TIMEOUT', { error: error.message });\r\n return FailureCategory.TIMEOUT;\r\n }\r\n\r\n if (error.message && /timeout|timed out/i.test(error.message)) {\r\n logger.debug('Categorized as TIMEOUT from message', { error: error.message });\r\n return FailureCategory.TIMEOUT;\r\n }\r\n\r\n // Check for validation errors\r\n if (\r\n error instanceof StandardError &&\r\n (error.code === ErrorCode.VALIDATION_FAILED ||\r\n error.code === ErrorCode.INVALID_INPUT ||\r\n error.code === ErrorCode.DB_VALIDATION_FAILED)\r\n ) {\r\n logger.debug('Categorized as VALIDATION_ERROR', { error: error.message });\r\n return FailureCategory.VALIDATION_ERROR;\r\n }\r\n\r\n // Check for null/undefined errors (validation)\r\n if (\r\n error instanceof TypeError &&\r\n (error.message.includes('null') ||\r\n error.message.includes('undefined') ||\r\n error.message.includes('Cannot read property'))\r\n ) {\r\n logger.debug('Categorized as VALIDATION_ERROR (null/undefined)', {\r\n error: error.message,\r\n });\r\n return FailureCategory.VALIDATION_ERROR;\r\n }\r\n\r\n // Check for logic errors (file not found, reference errors, etc.)\r\n if (error instanceof ReferenceError) {\r\n logger.debug('Categorized as LOGIC_ERROR (ReferenceError)', { error: error.message });\r\n return FailureCategory.LOGIC_ERROR;\r\n }\r\n\r\n if (\r\n error instanceof StandardError &&\r\n (error.code === ErrorCode.FILE_NOT_FOUND || error.code === ErrorCode.FILE_WRITE_FAILED)\r\n ) {\r\n logger.debug('Categorized as LOGIC_ERROR (file operation)', { error: error.message });\r\n return FailureCategory.LOGIC_ERROR;\r\n }\r\n\r\n // Default to unknown\r\n logger.debug('Categorized as UNKNOWN', { error: error.message });\r\n return FailureCategory.UNKNOWN;\r\n } finally {\r\n const duration = Date.now() - startTime;\r\n logger.debug('Categorization completed', { durationMs: duration });\r\n }\r\n }\r\n\r\n /**\r\n * Find similar failures by skill and category\r\n *\r\n * Performance target: <500ms\r\n */\r\n findSimilarFailures(failure: Failure): Failure[] {\r\n const startTime = Date.now();\r\n\r\n try {\r\n const stmt = this.db.prepare(`\r\n SELECT * FROM edge_cases\r\n WHERE skill_id = ?\r\n AND category = ?\r\n AND id != ?\r\n ORDER BY detected_at DESC\r\n LIMIT 10\r\n `);\r\n\r\n const rows = stmt.all(failure.skillId, failure.category, failure.id) as any[];\r\n\r\n const similar = rows.map(row => ({\r\n id: row.id,\r\n skillId: row.skill_id,\r\n category: row.category as FailureCategory,\r\n errorMessage: row.error_message,\r\n stackTrace: row.stack_trace,\r\n context: JSON.parse(row.context || '{}'),\r\n detectedAt: new Date(row.detected_at),\r\n patternHash: row.pattern_hash,\r\n confidence: row.confidence,\r\n }));\r\n\r\n logger.debug('Found similar failures', {\r\n count: similar.length,\r\n durationMs: Date.now() - startTime,\r\n });\r\n\r\n return similar;\r\n } catch (error) {\r\n logger.error('Failed to find similar failures', error as Error);\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * Calculate confidence score based on failure frequency\r\n *\r\n * Formula:\r\n * - 0 failures: 0.0\r\n * - 1 failure: 0.5\r\n * - 2-3 failures: 0.6-0.7\r\n * - 4-6 failures: 0.75-0.85\r\n * - 7-10 failures: 0.85-0.95\r\n * - 10+ failures: 0.95+\r\n */\r\n calculatePatternConfidence(failures: Failure[]): number {\r\n if (failures.length === 0) {\r\n return 0;\r\n }\r\n\r\n if (failures.length === 1) {\r\n return 0.5;\r\n }\r\n\r\n if (failures.length <= 3) {\r\n return 0.6 + failures.length * 0.05;\r\n }\r\n\r\n if (failures.length <= 6) {\r\n return 0.75 + (failures.length - 3) * 0.03;\r\n }\r\n\r\n if (failures.length <= 10) {\r\n return 0.85 + (failures.length - 6) * 0.025;\r\n }\r\n\r\n return Math.min(0.98, 0.95 + (failures.length - 10) * 0.01);\r\n }\r\n\r\n /**\r\n * Generate pattern hash from error message and category\r\n */\r\n private generatePatternHash(category: FailureCategory, errorMessage: string): string {\r\n // Normalize error message (remove numbers, paths, etc.)\r\n const normalized = errorMessage\r\n .replace(/\\d+/g, 'N') // Replace numbers\r\n .replace(/\\/[^\\s]*/g, '/PATH') // Replace file paths\r\n .replace(/at [^\\n]*/g, 'at LOCATION') // Replace stack locations\r\n .toLowerCase();\r\n\r\n const hashInput = `${category}:${normalized}`;\r\n return crypto.createHash('sha256').update(hashInput).digest('hex').substring(0, 16);\r\n }\r\n\r\n /**\r\n * Analyze failure and detect patterns\r\n *\r\n * Returns failure pattern with confidence score\r\n */\r\n async analyzeFailure(error: Error, context: any): Promise<FailurePattern> {\r\n const startTime = Date.now();\r\n\r\n // Categorize the failure\r\n const category = this.categorizeFailure(error, context);\r\n\r\n // Generate pattern hash\r\n const patternHash = this.generatePatternHash(category, error.message);\r\n\r\n // Create failure record\r\n const failure: Failure = {\r\n id: crypto.randomUUID(),\r\n skillId: context.skillId || 'unknown',\r\n category,\r\n errorMessage: error.message,\r\n stackTrace: error.stack || '',\r\n context,\r\n detectedAt: new Date(),\r\n patternHash,\r\n };\r\n\r\n // Find similar failures\r\n const similar = this.findSimilarFailures(failure);\r\n\r\n // Calculate confidence\r\n const allFailures = [failure, ...similar];\r\n const confidence = this.calculatePatternConfidence(allFailures);\r\n\r\n // Store failure\r\n this.db\r\n .prepare(\r\n `\r\n INSERT INTO edge_cases (id, skill_id, category, error_message, stack_trace, context, pattern_hash, confidence)\r\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\r\n `\r\n )\r\n .run(\r\n failure.id,\r\n failure.skillId,\r\n failure.category,\r\n failure.errorMessage,\r\n failure.stackTrace,\r\n JSON.stringify(failure.context),\r\n failure.patternHash,\r\n confidence\r\n );\r\n\r\n // Build pattern\r\n const skillIds = Array.from(new Set([failure.skillId, ...similar.map(f => f.skillId)]));\r\n\r\n const pattern: FailurePattern = {\r\n category,\r\n patternHash,\r\n failureCount: allFailures.length,\r\n confidence,\r\n firstSeenAt: similar.length > 0 ? similar[similar.length - 1].detectedAt : failure.detectedAt,\r\n lastSeenAt: failure.detectedAt,\r\n skillIds,\r\n };\r\n\r\n logger.info('Failure analyzed', {\r\n category,\r\n confidence,\r\n failureCount: allFailures.length,\r\n durationMs: Date.now() - startTime,\r\n });\r\n\r\n return pattern;\r\n }\r\n\r\n /**\r\n * Get failure statistics\r\n */\r\n getFailureStats(skillId?: string): FailureStats {\r\n const whereClause = skillId ? 'WHERE skill_id = ?' : '';\r\n const params = skillId ? [skillId] : [];\r\n\r\n // Total failures\r\n const totalStmt = this.db.prepare(`SELECT COUNT(*) as count FROM edge_cases ${whereClause}`);\r\n const totalResult = totalStmt.get(...params) as any;\r\n const totalFailures = totalResult.count;\r\n\r\n // By category\r\n const categoryStmt = this.db.prepare(`\r\n SELECT category, COUNT(*) as count\r\n FROM edge_cases\r\n ${whereClause}\r\n GROUP BY category\r\n `);\r\n const categoryResults = categoryStmt.all(...params) as any[];\r\n\r\n const byCategory: Record<string, number> = {};\r\n for (const row of categoryResults) {\r\n byCategory[row.category] = row.count;\r\n }\r\n\r\n // Unique patterns\r\n const patternsStmt = this.db.prepare(`\r\n SELECT COUNT(DISTINCT pattern_hash) as count\r\n FROM edge_cases\r\n ${whereClause}\r\n `);\r\n const patternsResult = patternsStmt.get(...params) as any;\r\n const uniquePatterns = patternsResult.count;\r\n\r\n // Top patterns\r\n const topStmt = this.db.prepare(`\r\n SELECT pattern_hash, category, COUNT(*) as count\r\n FROM edge_cases\r\n ${whereClause}\r\n GROUP BY pattern_hash, category\r\n ORDER BY count DESC\r\n LIMIT 5\r\n `);\r\n const topResults = topStmt.all(...params) as any[];\r\n\r\n const topPatterns = topResults.map(row => ({\r\n patternHash: row.pattern_hash,\r\n count: row.count,\r\n category: row.category as FailureCategory,\r\n }));\r\n\r\n return {\r\n totalFailures,\r\n byCategory,\r\n uniquePatterns,\r\n topPatterns,\r\n };\r\n }\r\n\r\n /**\r\n * Close database connection\r\n */\r\n close(): void {\r\n this.db.close();\r\n }\r\n}\r\n"],"names":["crypto","Database","createLogger","StandardError","ErrorCode","logger","FailureCategory","EdgeCaseAnalyzer","db","config","dbPath","initializeDatabase","exec","categorizeFailure","error","context","startTime","Date","now","SyntaxError","debug","message","code","OPERATION_TIMEOUT","DB_TIMEOUT","test","VALIDATION_FAILED","INVALID_INPUT","DB_VALIDATION_FAILED","TypeError","includes","ReferenceError","FILE_NOT_FOUND","FILE_WRITE_FAILED","duration","durationMs","findSimilarFailures","failure","stmt","prepare","rows","all","skillId","category","id","similar","map","row","skill_id","errorMessage","error_message","stackTrace","stack_trace","JSON","parse","detectedAt","detected_at","patternHash","pattern_hash","confidence","count","length","calculatePatternConfidence","failures","Math","min","generatePatternHash","normalized","replace","toLowerCase","hashInput","createHash","update","digest","substring","analyzeFailure","randomUUID","stack","allFailures","run","stringify","skillIds","Array","from","Set","f","pattern","failureCount","firstSeenAt","lastSeenAt","info","getFailureStats","whereClause","params","totalStmt","totalResult","get","totalFailures","categoryStmt","categoryResults","byCategory","patternsStmt","patternsResult","uniquePatterns","topStmt","topResults","topPatterns","close"],"mappings":"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"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge Case Deduplicator Service
|
|
3
|
+
*
|
|
4
|
+
* Deduplicates edge cases to prevent redundant tracking.
|
|
5
|
+
* Part of Task 1.5: MVP Edge Case Feedback Loop
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Similarity detection using Levenshtein distance
|
|
9
|
+
* - Pattern matching for error messages and stack traces
|
|
10
|
+
* - Configurable similarity threshold (default: 90%)
|
|
11
|
+
* - Occurrence count tracking
|
|
12
|
+
* - Smart deduplication based on skill + error type + message similarity
|
|
13
|
+
*
|
|
14
|
+
* Usage:
|
|
15
|
+
* const deduplicator = new EdgeCaseDeduplicator(dbService, logger);
|
|
16
|
+
* const isDuplicate = await deduplicator.deduplicateEdgeCase(edgeCase);
|
|
17
|
+
*/ import { createLogger } from '../lib/logging.js';
|
|
18
|
+
/**
|
|
19
|
+
* Edge case deduplicator service
|
|
20
|
+
*/ export class EdgeCaseDeduplicator {
|
|
21
|
+
dbService;
|
|
22
|
+
logger;
|
|
23
|
+
config;
|
|
24
|
+
constructor(dbService, logger, config){
|
|
25
|
+
this.dbService = dbService;
|
|
26
|
+
this.logger = logger || createLogger('edge-case-deduplicator');
|
|
27
|
+
// Set default config
|
|
28
|
+
this.config = {
|
|
29
|
+
similarityThreshold: config?.similarityThreshold ?? 0.90,
|
|
30
|
+
maxAgedays: config?.maxAgedays ?? 30,
|
|
31
|
+
maxCandidates: config?.maxCandidates ?? 50
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Deduplicate edge case against existing records
|
|
36
|
+
*
|
|
37
|
+
* @param edgeCase - Edge case to deduplicate
|
|
38
|
+
* @returns True if duplicate found and handled, false otherwise
|
|
39
|
+
*/ async deduplicateEdgeCase(edgeCase) {
|
|
40
|
+
try {
|
|
41
|
+
// 1. Find similar failures
|
|
42
|
+
const similar = await this.findSimilarFailures(edgeCase);
|
|
43
|
+
if (similar.length === 0) {
|
|
44
|
+
this.logger.debug('No similar edge cases found', {
|
|
45
|
+
skill_id: edgeCase.skill_id,
|
|
46
|
+
error_type: edgeCase.error_type
|
|
47
|
+
});
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
this.logger.debug(`Found ${similar.length} similar edge cases`, {
|
|
51
|
+
skill_id: edgeCase.skill_id,
|
|
52
|
+
error_type: edgeCase.error_type
|
|
53
|
+
});
|
|
54
|
+
// 2. Calculate similarity scores
|
|
55
|
+
for (const candidate of similar){
|
|
56
|
+
const score = this.calculateSimilarity(edgeCase, candidate);
|
|
57
|
+
this.logger.debug('Similarity score calculated', {
|
|
58
|
+
candidate_id: candidate.id,
|
|
59
|
+
total_score: score.total,
|
|
60
|
+
threshold: this.config.similarityThreshold
|
|
61
|
+
});
|
|
62
|
+
// 3. If >threshold% similar, it's a duplicate
|
|
63
|
+
if (score.total >= this.config.similarityThreshold) {
|
|
64
|
+
this.logger.info('Duplicate edge case found', {
|
|
65
|
+
edge_case_id: edgeCase.id,
|
|
66
|
+
duplicate_of: candidate.id,
|
|
67
|
+
similarity_score: score.total
|
|
68
|
+
});
|
|
69
|
+
// Update existing edge case
|
|
70
|
+
await this.incrementOccurrenceCount(candidate.id);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// No duplicates found
|
|
75
|
+
return false;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
this.logger.error('Failed to deduplicate edge case', error, {
|
|
78
|
+
edge_case_id: edgeCase.id
|
|
79
|
+
});
|
|
80
|
+
// Don't throw - allow edge case to be stored even if deduplication fails
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find similar failures based on skill and error type
|
|
86
|
+
*
|
|
87
|
+
* @param edgeCase - Edge case to find similar failures for
|
|
88
|
+
* @returns Array of similar edge cases
|
|
89
|
+
*/ async findSimilarFailures(edgeCase) {
|
|
90
|
+
const sqlite = this.dbService.getAdapter('sqlite');
|
|
91
|
+
// Calculate cutoff date
|
|
92
|
+
const cutoffDate = new Date();
|
|
93
|
+
cutoffDate.setDate(cutoffDate.getDate() - this.config.maxAgedays);
|
|
94
|
+
// Query for similar edge cases
|
|
95
|
+
const query = `
|
|
96
|
+
SELECT *
|
|
97
|
+
FROM edge_cases
|
|
98
|
+
WHERE skill_id = ?
|
|
99
|
+
AND error_type = ?
|
|
100
|
+
AND status = 'new'
|
|
101
|
+
AND last_seen >= ?
|
|
102
|
+
ORDER BY occurrence_count DESC, last_seen DESC
|
|
103
|
+
LIMIT ?
|
|
104
|
+
`;
|
|
105
|
+
const rows = await sqlite.raw(query, [
|
|
106
|
+
edgeCase.skill_id,
|
|
107
|
+
edgeCase.error_type,
|
|
108
|
+
cutoffDate.toISOString(),
|
|
109
|
+
this.config.maxCandidates
|
|
110
|
+
]);
|
|
111
|
+
if (!Array.isArray(rows)) {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
return rows.map((row)=>this.mapRowToEdgeCase(row));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Calculate similarity between two edge cases
|
|
118
|
+
*
|
|
119
|
+
* Similarity breakdown:
|
|
120
|
+
* - Same skill + error type: 40%
|
|
121
|
+
* - Error message similarity: 30%
|
|
122
|
+
* - Stack trace similarity: 30%
|
|
123
|
+
*
|
|
124
|
+
* @param a - First edge case
|
|
125
|
+
* @param b - Second edge case
|
|
126
|
+
* @returns Similarity score (0.0 - 1.0)
|
|
127
|
+
*/ calculateSimilarity(a, b) {
|
|
128
|
+
let score = 0;
|
|
129
|
+
const breakdown = {
|
|
130
|
+
total: 0,
|
|
131
|
+
skillAndType: 0,
|
|
132
|
+
messageMatch: 0,
|
|
133
|
+
stackMatch: 0
|
|
134
|
+
};
|
|
135
|
+
// Same skill + error type = 40%
|
|
136
|
+
if (a.skill_id === b.skill_id && a.error_type === b.error_type) {
|
|
137
|
+
score += 0.40;
|
|
138
|
+
breakdown.skillAndType = 0.40;
|
|
139
|
+
}
|
|
140
|
+
// Similar error message = 30%
|
|
141
|
+
const messageSimilarity = this.computeLevenshteinSimilarity(a.error_message, b.error_message);
|
|
142
|
+
const messageScore = messageSimilarity * 0.30;
|
|
143
|
+
score += messageScore;
|
|
144
|
+
breakdown.messageMatch = messageScore;
|
|
145
|
+
// Similar stack trace = 30%
|
|
146
|
+
const stackA = a.stack_trace || '';
|
|
147
|
+
const stackB = b.stack_trace || '';
|
|
148
|
+
const stackSimilarity = this.computeLevenshteinSimilarity(stackA, stackB);
|
|
149
|
+
const stackScore = stackSimilarity * 0.30;
|
|
150
|
+
score += stackScore;
|
|
151
|
+
breakdown.stackMatch = stackScore;
|
|
152
|
+
breakdown.total = score;
|
|
153
|
+
return breakdown;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Compute Levenshtein similarity (normalized)
|
|
157
|
+
*
|
|
158
|
+
* @param a - First string
|
|
159
|
+
* @param b - Second string
|
|
160
|
+
* @returns Similarity score (0.0 - 1.0)
|
|
161
|
+
*/ computeLevenshteinSimilarity(a, b) {
|
|
162
|
+
if (a === b) return 1.0;
|
|
163
|
+
if (!a || !b) return 0.0;
|
|
164
|
+
const distance = this.levenshteinDistance(a, b);
|
|
165
|
+
const maxLength = Math.max(a.length, b.length);
|
|
166
|
+
if (maxLength === 0) return 1.0;
|
|
167
|
+
return 1.0 - distance / maxLength;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Calculate Levenshtein distance between two strings
|
|
171
|
+
*
|
|
172
|
+
* @param a - First string
|
|
173
|
+
* @param b - Second string
|
|
174
|
+
* @returns Edit distance
|
|
175
|
+
*/ levenshteinDistance(a, b) {
|
|
176
|
+
const matrix = [];
|
|
177
|
+
// Initialize matrix
|
|
178
|
+
for(let i = 0; i <= b.length; i++){
|
|
179
|
+
matrix[i] = [
|
|
180
|
+
i
|
|
181
|
+
];
|
|
182
|
+
}
|
|
183
|
+
for(let j = 0; j <= a.length; j++){
|
|
184
|
+
matrix[0][j] = j;
|
|
185
|
+
}
|
|
186
|
+
// Fill matrix
|
|
187
|
+
for(let i = 1; i <= b.length; i++){
|
|
188
|
+
for(let j = 1; j <= a.length; j++){
|
|
189
|
+
if (b.charAt(i - 1) === a.charAt(j - 1)) {
|
|
190
|
+
matrix[i][j] = matrix[i - 1][j - 1];
|
|
191
|
+
} else {
|
|
192
|
+
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j] + 1 // deletion
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return matrix[b.length][a.length];
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Increment occurrence count for existing edge case
|
|
201
|
+
*
|
|
202
|
+
* @param edgeCaseId - Edge case ID
|
|
203
|
+
*/ async incrementOccurrenceCount(edgeCaseId) {
|
|
204
|
+
const sqlite = this.dbService.getAdapter('sqlite');
|
|
205
|
+
const query = `
|
|
206
|
+
UPDATE edge_cases
|
|
207
|
+
SET occurrence_count = occurrence_count + 1,
|
|
208
|
+
last_seen = CURRENT_TIMESTAMP
|
|
209
|
+
WHERE id = ?
|
|
210
|
+
`;
|
|
211
|
+
const result = await sqlite.raw(query, [
|
|
212
|
+
edgeCaseId
|
|
213
|
+
]);
|
|
214
|
+
this.logger.info('Incremented occurrence count', {
|
|
215
|
+
edge_case_id: edgeCaseId
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get deduplication statistics
|
|
220
|
+
*/ async getStats() {
|
|
221
|
+
const sqlite = this.dbService.getAdapter('sqlite');
|
|
222
|
+
// Total edge cases
|
|
223
|
+
const totalResult = await sqlite.raw('SELECT COUNT(*) as count FROM edge_cases WHERE status = "new"');
|
|
224
|
+
const totalEdgeCases = Array.isArray(totalResult) && totalResult[0] ? totalResult[0].count : 0;
|
|
225
|
+
// Unique skills
|
|
226
|
+
const uniqueResult = await sqlite.raw('SELECT COUNT(DISTINCT skill_id) as count FROM edge_cases WHERE status = "new"');
|
|
227
|
+
const uniqueSkills = Array.isArray(uniqueResult) && uniqueResult[0] ? uniqueResult[0].count : 0;
|
|
228
|
+
// Average occurrence count
|
|
229
|
+
const avgResult = await sqlite.raw('SELECT AVG(occurrence_count) as avg FROM edge_cases WHERE status = "new"');
|
|
230
|
+
const avgOccurrenceCount = Array.isArray(avgResult) && avgResult[0] ? avgResult[0].avg || 0 : 0;
|
|
231
|
+
// Most frequent failure
|
|
232
|
+
const frequentResult = await sqlite.raw(`SELECT id, skill_id, error_type, occurrence_count
|
|
233
|
+
FROM edge_cases
|
|
234
|
+
WHERE status = 'new'
|
|
235
|
+
ORDER BY occurrence_count DESC
|
|
236
|
+
LIMIT 1`);
|
|
237
|
+
const mostFrequentFailure = Array.isArray(frequentResult) && frequentResult[0] ? frequentResult[0] : null;
|
|
238
|
+
return {
|
|
239
|
+
totalEdgeCases,
|
|
240
|
+
uniqueSkills,
|
|
241
|
+
avgOccurrenceCount,
|
|
242
|
+
mostFrequentFailure
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Map database row to EdgeCase object
|
|
247
|
+
*/ mapRowToEdgeCase(row) {
|
|
248
|
+
return {
|
|
249
|
+
id: row.id,
|
|
250
|
+
skill_id: row.skill_id,
|
|
251
|
+
error_type: row.error_type,
|
|
252
|
+
severity: row.severity,
|
|
253
|
+
error_message: row.error_message,
|
|
254
|
+
stack_trace: row.stack_trace,
|
|
255
|
+
input_context: row.input_context,
|
|
256
|
+
output_context: row.output_context,
|
|
257
|
+
first_seen: new Date(row.first_seen),
|
|
258
|
+
last_seen: new Date(row.last_seen),
|
|
259
|
+
occurrence_count: row.occurrence_count,
|
|
260
|
+
status: row.status,
|
|
261
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : {}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
//# sourceMappingURL=edge-case-deduplicator.js.map
|