claude-flow-novice 2.15.3 → 2.15.5

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.
Files changed (473) hide show
  1. package/.claude/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
  2. package/.claude/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
  3. package/.claude/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
  4. package/.claude/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
  5. package/.claude/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
  6. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
  7. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
  8. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
  9. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
  10. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
  11. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
  12. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
  13. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
  14. package/.claude/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
  15. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
  16. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
  17. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
  18. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
  19. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
  20. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
  21. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
  22. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
  23. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
  24. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
  25. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
  26. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
  27. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
  28. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
  29. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
  30. package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
  31. package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
  32. package/.claude/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
  33. package/.claude/commands/cfn-loop-cli.md +29 -6
  34. package/.claude/commands/switch-api.md +31 -10
  35. package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
  36. package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
  37. package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
  38. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  39. package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  40. package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  41. package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  42. package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  43. package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  44. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +238 -29
  45. package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  46. package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  47. package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  48. package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
  49. package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  50. package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
  51. package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  52. package/.claude/skills/cfn-redis-coordination/get-context.sh +33 -0
  53. package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  54. package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +6 -2
  55. package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  56. package/.claude/skills/cfn-redis-coordination/redis-functions.sh +34 -0
  57. package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
  58. package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
  59. package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  60. package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  61. package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  62. package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  63. package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
  64. package/README.md +116 -475
  65. package/claude-assets/agents/cfn-dev-team/README.md +103 -0
  66. package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
  67. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
  68. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
  69. package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
  70. package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
  71. package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
  72. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
  73. package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
  74. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
  75. package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
  76. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
  77. package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
  78. package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
  79. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
  80. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
  81. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
  82. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
  83. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
  84. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
  85. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
  86. package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
  87. package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
  88. package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
  89. package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
  90. package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
  91. package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
  92. package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
  93. package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
  94. package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
  95. package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +828 -0
  96. package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
  97. package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
  98. package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
  99. package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
  100. package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
  101. package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
  102. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
  103. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
  104. package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
  105. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
  106. package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
  107. package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
  108. package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
  109. package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
  110. package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
  111. package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
  112. package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
  113. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
  114. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
  115. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
  116. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
  117. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
  118. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
  119. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
  120. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
  121. package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
  122. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
  123. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
  124. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
  125. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
  126. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
  127. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
  128. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
  129. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
  130. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
  131. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
  132. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
  133. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
  134. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
  135. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
  136. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
  137. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
  138. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
  139. package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
  140. package/claude-assets/commands/cfn-loop-cli.md +29 -6
  141. package/claude-assets/commands/switch-api.md +31 -10
  142. package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
  143. package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
  144. package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
  145. package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
  146. package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
  147. package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +84 -113
  148. package/claude-assets/skills/agent-lifecycle/simple-audit.sh +33 -6
  149. package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
  150. package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
  151. package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
  152. package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
  153. package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
  154. package/claude-assets/skills/bootstrap/database-connection.md +464 -0
  155. package/claude-assets/skills/bootstrap/error-handling.md +580 -0
  156. package/claude-assets/skills/bootstrap/file-operations.md +699 -0
  157. package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
  158. package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
  159. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  160. package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
  161. package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
  162. package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
  163. package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  164. package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  165. package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  166. package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
  167. package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
  168. package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
  169. package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
  170. package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
  171. package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
  172. package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
  173. package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
  174. package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
  175. package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
  176. package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
  177. package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
  178. package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  179. package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  180. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +238 -29
  181. package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  182. package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  183. package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
  184. package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
  185. package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
  186. package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
  187. package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
  188. package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  189. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
  190. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  191. package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
  192. package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  193. package/claude-assets/skills/cfn-redis-coordination/get-context.sh +33 -0
  194. package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  195. package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +6 -2
  196. package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  197. package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +34 -0
  198. package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
  199. package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
  200. package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  201. package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  202. package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
  203. package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
  204. package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  205. package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
  206. package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
  207. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
  208. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
  209. package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
  210. package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  211. package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
  212. package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
  213. package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
  214. package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
  215. package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
  216. package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
  217. package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
  218. package/claude-assets/skills/cfn-utilities/test.sh +317 -0
  219. package/claude-assets/skills/integration/agent-handoff.sh +62 -64
  220. package/claude-assets/skills/json-validation/SKILL.md +431 -0
  221. package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
  222. package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
  223. package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
  224. package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
  225. package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
  226. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
  227. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
  228. package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
  229. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
  230. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
  231. package/claude-assets/skills/workflow-codification/test-integration.sh +15 -0
  232. package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
  233. package/claude-assets/skills/workflow-codification/track-cost-savings.sh +55 -14
  234. package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
  235. package/claude-assets/skills/workflow-codification/track-edge-case.sh +27 -60
  236. package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
  237. package/dist/ace/ace-curator.js +10 -2
  238. package/dist/ace/ace-curator.js.map +1 -1
  239. package/dist/ace/ace-generator.js +4 -0
  240. package/dist/ace/ace-generator.js.map +1 -1
  241. package/dist/ace/ace-reflector.js +1 -1
  242. package/dist/ace/ace-reflector.js.map +1 -1
  243. package/dist/ace/context-injection.js +24 -2
  244. package/dist/ace/context-injection.js.map +1 -1
  245. package/dist/agents/task-agent-integration.js +1 -1
  246. package/dist/agents/task-agent-integration.js.map +1 -1
  247. package/dist/api/health-endpoints.js +390 -0
  248. package/dist/api/health-endpoints.js.map +1 -0
  249. package/dist/cli/agent-executor.js +4 -1
  250. package/dist/cli/agent-executor.js.map +1 -1
  251. package/dist/cli/agent-prompt-builder.js +89 -1
  252. package/dist/cli/agent-prompt-builder.js.map +1 -1
  253. package/dist/cli/agent-spawn.js +130 -37
  254. package/dist/cli/agent-spawn.js.map +1 -1
  255. package/dist/cli/config-manager.js +109 -91
  256. package/dist/cli/config-manager.js.map +1 -1
  257. package/dist/cli/conversation-fork-cleanup.js +201 -0
  258. package/dist/cli/conversation-fork-cleanup.js.map +1 -0
  259. package/dist/cli/conversation-fork.js +16 -3
  260. package/dist/cli/conversation-fork.js.map +1 -1
  261. package/dist/cli/skill-cache-validator.js +412 -0
  262. package/dist/cli/skill-cache-validator.js.map +1 -0
  263. package/dist/cli/skill-cli.js +991 -0
  264. package/dist/cli/skill-cli.js.map +1 -0
  265. package/dist/cli/skill-execution-logger.js +284 -0
  266. package/dist/cli/skill-execution-logger.js.map +1 -0
  267. package/dist/cli/skill-loader.js +457 -0
  268. package/dist/cli/skill-loader.js.map +1 -0
  269. package/dist/coordination/event-bus.js +2 -2
  270. package/dist/coordination/event-bus.js.map +1 -1
  271. package/dist/coordination/fleet-manager.js +1 -1
  272. package/dist/coordination/fleet-manager.js.map +1 -1
  273. package/dist/coordination/index.js +23 -9
  274. package/dist/coordination/index.js.map +1 -1
  275. package/dist/coordination/types/fleet-manager.types.js.map +1 -1
  276. package/dist/db/migration-manager.js +483 -0
  277. package/dist/db/migration-manager.js.map +1 -0
  278. package/dist/db/skills-query.js +535 -0
  279. package/dist/db/skills-query.js.map +1 -0
  280. package/dist/integration/DatabaseHandoff.js +1 -1
  281. package/dist/integration/DatabaseHandoff.js.map +1 -1
  282. package/dist/jobs/edge-case-analyzer.js +367 -0
  283. package/dist/jobs/edge-case-analyzer.js.map +1 -0
  284. package/dist/jobs/promotion-sla-enforcer.js +288 -0
  285. package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
  286. package/dist/lib/agent-output-parser.js.map +1 -1
  287. package/dist/lib/agent-output-validator.js.map +1 -1
  288. package/dist/lib/agent-workspace.js +281 -0
  289. package/dist/lib/agent-workspace.js.map +1 -0
  290. package/dist/lib/atomic-file-writer.js +377 -0
  291. package/dist/lib/atomic-file-writer.js.map +1 -0
  292. package/dist/lib/backup-manager.js +779 -0
  293. package/dist/lib/backup-manager.js.map +1 -0
  294. package/dist/lib/checkpoint-manager.js +837 -0
  295. package/dist/lib/checkpoint-manager.js.map +1 -0
  296. package/dist/lib/circuit-breaker.js +340 -0
  297. package/dist/lib/circuit-breaker.js.map +1 -0
  298. package/dist/lib/completion-signal-handler.js +243 -0
  299. package/dist/lib/completion-signal-handler.js.map +1 -0
  300. package/dist/lib/config-manager.js +312 -0
  301. package/dist/lib/config-manager.js.map +1 -0
  302. package/dist/lib/config-migrator.js +386 -0
  303. package/dist/lib/config-migrator.js.map +1 -0
  304. package/dist/lib/config-validator.js.map +1 -1
  305. package/dist/lib/correlation-cache.js +311 -0
  306. package/dist/lib/correlation-cache.js.map +1 -0
  307. package/dist/lib/correlation.js +263 -0
  308. package/dist/lib/correlation.js.map +1 -0
  309. package/dist/lib/database-service/connection-pool-manager.js +520 -0
  310. package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
  311. package/dist/lib/database-service/correlation.js +329 -0
  312. package/dist/lib/database-service/correlation.js.map +1 -0
  313. package/dist/lib/database-service/errors.js +120 -0
  314. package/dist/lib/database-service/errors.js.map +1 -0
  315. package/dist/lib/database-service/index.js +168 -0
  316. package/dist/lib/database-service/index.js.map +1 -0
  317. package/dist/lib/database-service/postgres-adapter.js +526 -0
  318. package/dist/lib/database-service/postgres-adapter.js.map +1 -0
  319. package/dist/lib/database-service/redis-adapter.js +360 -0
  320. package/dist/lib/database-service/redis-adapter.js.map +1 -0
  321. package/dist/lib/database-service/sqlite-adapter.js +544 -0
  322. package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
  323. package/dist/lib/database-service/transaction-manager.js +773 -0
  324. package/dist/lib/database-service/transaction-manager.js.map +1 -0
  325. package/dist/lib/database-service/types.js +23 -0
  326. package/dist/lib/database-service/types.js.map +1 -0
  327. package/dist/lib/deadlock-resolver.js +292 -0
  328. package/dist/lib/deadlock-resolver.js.map +1 -0
  329. package/dist/lib/distributed-lock.js +451 -0
  330. package/dist/lib/distributed-lock.js.map +1 -0
  331. package/dist/lib/edge-case-deduplicator.js +227 -0
  332. package/dist/lib/edge-case-deduplicator.js.map +1 -0
  333. package/dist/lib/encryption-manager.js +322 -0
  334. package/dist/lib/encryption-manager.js.map +1 -0
  335. package/dist/lib/error-aggregator.js +234 -0
  336. package/dist/lib/error-aggregator.js.map +1 -0
  337. package/dist/lib/errors.js +287 -0
  338. package/dist/lib/errors.js.map +1 -0
  339. package/dist/lib/file-lock-manager.js +578 -0
  340. package/dist/lib/file-lock-manager.js.map +1 -0
  341. package/dist/lib/file-operations.js +367 -0
  342. package/dist/lib/file-operations.js.map +1 -0
  343. package/dist/lib/idempotent-write.js +237 -0
  344. package/dist/lib/idempotent-write.js.map +1 -0
  345. package/dist/lib/integration-schema-validator.js +522 -0
  346. package/dist/lib/integration-schema-validator.js.map +1 -0
  347. package/dist/lib/lock-health-monitor.js +298 -0
  348. package/dist/lib/lock-health-monitor.js.map +1 -0
  349. package/dist/lib/log-shipper.js +422 -0
  350. package/dist/lib/log-shipper.js.map +1 -0
  351. package/dist/lib/logging.js +146 -0
  352. package/dist/lib/logging.js.map +1 -0
  353. package/dist/lib/message-deduplicator.js +439 -0
  354. package/dist/lib/message-deduplicator.js.map +1 -0
  355. package/dist/lib/multi-system-query.js +604 -0
  356. package/dist/lib/multi-system-query.js.map +1 -0
  357. package/dist/lib/orphan-detector.js +332 -0
  358. package/dist/lib/orphan-detector.js.map +1 -0
  359. package/dist/lib/password-generator.js +166 -0
  360. package/dist/lib/password-generator.js.map +1 -0
  361. package/dist/lib/path-validator.js +429 -0
  362. package/dist/lib/path-validator.js.map +1 -0
  363. package/dist/lib/query-translator.js +905 -0
  364. package/dist/lib/query-translator.js.map +1 -0
  365. package/dist/lib/queue-recovery.js +469 -0
  366. package/dist/lib/queue-recovery.js.map +1 -0
  367. package/dist/lib/redis-queue-manager.js +512 -0
  368. package/dist/lib/redis-queue-manager.js.map +1 -0
  369. package/dist/lib/reflection-archiver.js +272 -0
  370. package/dist/lib/reflection-archiver.js.map +1 -0
  371. package/dist/lib/retry-manager.js +453 -0
  372. package/dist/lib/retry-manager.js.map +1 -0
  373. package/dist/lib/retry.js +262 -0
  374. package/dist/lib/retry.js.map +1 -0
  375. package/dist/lib/schema-transform.js +695 -0
  376. package/dist/lib/schema-transform.js.map +1 -0
  377. package/dist/lib/schema-validator.js +491 -0
  378. package/dist/lib/schema-validator.js.map +1 -0
  379. package/dist/lib/skill-cache.js +297 -0
  380. package/dist/lib/skill-cache.js.map +1 -0
  381. package/dist/lib/skill-content-manager.js +337 -0
  382. package/dist/lib/skill-content-manager.js.map +1 -0
  383. package/dist/lib/skill-frontmatter-parser.js +237 -0
  384. package/dist/lib/skill-frontmatter-parser.js.map +1 -0
  385. package/dist/lib/skill-git-integration.js +275 -0
  386. package/dist/lib/skill-git-integration.js.map +1 -0
  387. package/dist/lib/skill-markdown-validator.js +396 -0
  388. package/dist/lib/skill-markdown-validator.js.map +1 -0
  389. package/dist/lib/skill-output-parser.js +312 -0
  390. package/dist/lib/skill-output-parser.js.map +1 -0
  391. package/dist/lib/unified-query-api.js +467 -0
  392. package/dist/lib/unified-query-api.js.map +1 -0
  393. package/dist/middleware/auth-middleware.js +350 -0
  394. package/dist/middleware/auth-middleware.js.map +1 -0
  395. package/dist/middleware/schema-validation.js +347 -0
  396. package/dist/middleware/schema-validation.js.map +1 -0
  397. package/dist/providers/anthropic-provider.js +1 -1
  398. package/dist/providers/anthropic-provider.js.map +1 -1
  399. package/dist/providers/provider-factory.js +2 -2
  400. package/dist/providers/provider-factory.js.map +1 -1
  401. package/dist/services/edge-case-analyzer.js +321 -0
  402. package/dist/services/edge-case-analyzer.js.map +1 -0
  403. package/dist/services/edge-case-deduplicator.js +266 -0
  404. package/dist/services/edge-case-deduplicator.js.map +1 -0
  405. package/dist/services/edge-case-detector.js +337 -0
  406. package/dist/services/edge-case-detector.js.map +1 -0
  407. package/dist/services/edge-case-tracker.js +547 -0
  408. package/dist/services/edge-case-tracker.js.map +1 -0
  409. package/dist/services/health-check-system.js +586 -0
  410. package/dist/services/health-check-system.js.map +1 -0
  411. package/dist/services/metrics-logger.js +412 -0
  412. package/dist/services/metrics-logger.js.map +1 -0
  413. package/dist/services/patch-generator.js +378 -0
  414. package/dist/services/patch-generator.js.map +1 -0
  415. package/dist/services/patch-validator.js +337 -0
  416. package/dist/services/patch-validator.js.map +1 -0
  417. package/dist/services/performance-monitor.js +811 -0
  418. package/dist/services/performance-monitor.js.map +1 -0
  419. package/dist/services/promotion-pipeline.js +918 -0
  420. package/dist/services/promotion-pipeline.js.map +1 -0
  421. package/dist/services/promotion-validator.js +394 -0
  422. package/dist/services/promotion-validator.js.map +1 -0
  423. package/dist/services/reflection-logger.js +388 -0
  424. package/dist/services/reflection-logger.js.map +1 -0
  425. package/dist/services/skill-deployment.js +472 -0
  426. package/dist/services/skill-deployment.js.map +1 -0
  427. package/dist/services/skill-loader.js +427 -0
  428. package/dist/services/skill-loader.js.map +1 -0
  429. package/dist/services/skill-promotion.js +372 -0
  430. package/dist/services/skill-promotion.js.map +1 -0
  431. package/dist/services/skill-validator.js +454 -0
  432. package/dist/services/skill-validator.js.map +1 -0
  433. package/dist/services/skill-versioning.js +244 -0
  434. package/dist/services/skill-versioning.js.map +1 -0
  435. package/dist/services/workspace-supervisor.js +597 -0
  436. package/dist/services/workspace-supervisor.js.map +1 -0
  437. package/dist/types/edge-case.js +45 -0
  438. package/dist/types/edge-case.js.map +1 -0
  439. package/docs/BUG_19_MEMORY_LEAK_TASK_MODE.md +405 -0
  440. package/docs/MEMORY_CLEANUP_GUIDE.md +358 -0
  441. package/docs/MEMORY_LEAK_FIX_SUMMARY.md +322 -0
  442. package/docs/REDIS_CLEANUP_EXECUTIVE_SUMMARY.md +319 -0
  443. package/docs/REDIS_CLEANUP_VERIFICATION_REPORT.md +574 -0
  444. package/package.json +35 -4
  445. package/readme/README.md +53 -5
  446. package/scripts/backup-cleanup.sh +627 -0
  447. package/scripts/cleanup-workspaces.sh +412 -0
  448. package/scripts/cleanup-yaml-configs.sh +141 -0
  449. package/scripts/deploy-approved-skills.sh +263 -0
  450. package/scripts/health-check.sh +447 -0
  451. package/scripts/log-aggregator.sh +554 -0
  452. package/scripts/log-monitor.sh +629 -0
  453. package/scripts/manage-agent-workspaces.sh +434 -0
  454. package/scripts/migrate-schema.sh +533 -0
  455. package/scripts/promote-staged-skills.sh +423 -0
  456. package/scripts/verify-no-secrets.sh +88 -35
  457. package/scripts/verify-redis-cleanup.sh +173 -0
  458. package/tests/README.md +84 -0
  459. package/tests/test-memory-leak-task-mode.sh +435 -0
  460. package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  461. package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  462. package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  463. package/.claude/skills/agent-lifecycle/SKILL.md +0 -60
  464. package/.claude/skills/agent-lifecycle/execute-lifecycle-hook.sh +0 -573
  465. package/.claude/skills/agent-lifecycle/simple-audit.sh +0 -31
  466. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  467. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
  468. package/README.md.backup_before_replace +0 -781
  469. package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  470. package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  471. package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  472. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  473. 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