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
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/integration/DatabaseHandoff.ts"],"sourcesContent":["/**\r\n * DatabaseHandoff.ts - Standard database handoff patterns with cross-database correlation\r\n *\r\n * Features:\r\n * - Cross-database correlation via task_id\r\n * - Transaction management (begin/commit/rollback)\r\n * - Query builder with standard correlation\r\n * - Connection pooling (PostgreSQL, SQLite)\r\n * - Automatic retry on transient failures\r\n */\r\n\r\nimport { Pool as PgPool, PoolClient, QueryResult } from 'pg';\r\nimport sqlite3 from 'sqlite3';\r\nimport { Database as SqliteDB } from 'sqlite';\r\nimport { StandardAdapter, Logger, JSONLogger } from './StandardAdapter';\r\n\r\n/**\r\n * Standard handoff record structure\r\n */\r\nexport interface HandoffRecord {\r\n /** Unique handoff ID */\r\n handoff_id: string;\r\n /** Task correlation ID */\r\n task_id: string;\r\n /** Source agent ID */\r\n source_agent_id: string;\r\n /** Target agent ID (if known) */\r\n target_agent_id?: string;\r\n /** Handoff status: pending, in_progress, completed, failed */\r\n status: 'pending' | 'in_progress' | 'completed' | 'failed';\r\n /** Handoff payload (JSON) */\r\n payload: Record<string, unknown>;\r\n /** Optional metadata */\r\n metadata?: Record<string, unknown>;\r\n /** Creation timestamp */\r\n created_at: Date;\r\n /** Update timestamp */\r\n updated_at: Date;\r\n /** Completion timestamp */\r\n completed_at?: Date;\r\n}\r\n\r\n/**\r\n * Database connection configuration\r\n */\r\nexport interface DatabaseConfig {\r\n type: 'postgresql' | 'sqlite';\r\n /** PostgreSQL connection config */\r\n pg?: {\r\n host: string;\r\n port: number;\r\n database: string;\r\n user: string;\r\n password: string;\r\n max_connections?: number;\r\n };\r\n /** SQLite connection config */\r\n sqlite?: {\r\n filepath: string;\r\n mode?: number;\r\n };\r\n}\r\n\r\n/**\r\n * Transaction context for safe rollback\r\n */\r\ninterface TransactionContext {\r\n client?: PoolClient;\r\n in_transaction: boolean;\r\n}\r\n\r\n/**\r\n * DatabaseHandoff - Reference implementation for cross-database correlation\r\n *\r\n * @example\r\n * ```typescript\r\n * // PostgreSQL example\r\n * const pgHandoff = new DatabaseHandoff({\r\n * type: 'postgresql',\r\n * pg: {\r\n * host: 'localhost',\r\n * port: 5432,\r\n * database: 'cfn_db',\r\n * user: 'cfn_user',\r\n * password: 'secret',\r\n * },\r\n * }, {\r\n * task_id: 'task-123',\r\n * agent_id: 'agent-456',\r\n * });\r\n *\r\n * await pgHandoff.initialize();\r\n *\r\n * // Create handoff with automatic correlation\r\n * const handoff = await pgHandoff.createHandoff({\r\n * source_agent_id: 'agent-456',\r\n * target_agent_id: 'agent-789',\r\n * payload: { data: 'example' },\r\n * });\r\n *\r\n * // Query by task_id (cross-database correlation)\r\n * const handoffs = await pgHandoff.getHandoffsByTaskId('task-123');\r\n *\r\n * // Transaction example\r\n * await pgHandoff.withTransaction(async (tx) => {\r\n * await tx.query('INSERT INTO tasks ...');\r\n * await tx.query('UPDATE agents ...');\r\n * // Automatic commit on success, rollback on error\r\n * });\r\n * ```\r\n */\r\nexport class DatabaseHandoff {\r\n private config: DatabaseConfig;\r\n private adapter: StandardAdapter;\r\n private logger: Logger;\r\n\r\n // Connection pools\r\n private pg_pool?: PgPool;\r\n private sqlite_db?: SqliteDB;\r\n\r\n // Initialization state\r\n private initialized = false;\r\n\r\n constructor(\r\n config: DatabaseConfig,\r\n context: { task_id: string; agent_id?: string; logger?: Logger }\r\n ) {\r\n this.config = config;\r\n this.logger = context.logger || new JSONLogger();\r\n this.adapter = new StandardAdapter({\r\n task_id: context.task_id,\r\n agent_id: context.agent_id,\r\n logger: this.logger,\r\n });\r\n }\r\n\r\n /**\r\n * Initialize database connection and schema\r\n */\r\n async initialize(): Promise<void> {\r\n if (this.initialized) {\r\n return;\r\n }\r\n\r\n try {\r\n if (this.config.type === 'postgresql') {\r\n await this.initializePostgreSQL();\r\n } else if (this.config.type === 'sqlite') {\r\n await this.initializeSQLite();\r\n } else {\r\n throw new Error(`Unsupported database type: ${this.config.type}`);\r\n }\r\n\r\n await this.ensureSchema();\r\n this.initialized = true;\r\n\r\n this.logger.info('Database handoff initialized', {\r\n task_id: this.adapter.getContext().task_id,\r\n database_type: this.config.type,\r\n });\r\n } catch (error) {\r\n this.logger.error('Failed to initialize database', {\r\n task_id: this.adapter.getContext().task_id,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Create a new handoff record\r\n */\r\n async createHandoff(params: {\r\n source_agent_id: string;\r\n target_agent_id?: string;\r\n payload: Record<string, unknown>;\r\n metadata?: Record<string, unknown>;\r\n }): Promise<HandoffRecord> {\r\n this.ensureInitialized();\r\n\r\n const handoff_id = this.generateHandoffId();\r\n const { task_id } = this.adapter.getContext();\r\n\r\n const handoff: HandoffRecord = {\r\n handoff_id,\r\n task_id,\r\n source_agent_id: params.source_agent_id,\r\n target_agent_id: params.target_agent_id,\r\n status: 'pending',\r\n payload: params.payload,\r\n metadata: params.metadata,\r\n created_at: new Date(),\r\n updated_at: new Date(),\r\n };\r\n\r\n return await this.adapter.withRetry(async () => {\r\n if (this.config.type === 'postgresql') {\r\n return await this.createHandoffPostgreSQL(handoff);\r\n } else {\r\n return await this.createHandoffSQLite(handoff);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get handoff by ID\r\n */\r\n async getHandoff(handoff_id: string): Promise<HandoffRecord | null> {\r\n this.ensureInitialized();\r\n\r\n return await this.adapter.withRetry(async () => {\r\n if (this.config.type === 'postgresql') {\r\n return await this.getHandoffPostgreSQL(handoff_id);\r\n } else {\r\n return await this.getHandoffSQLite(handoff_id);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get all handoffs for a task (cross-database correlation)\r\n */\r\n async getHandoffsByTaskId(task_id: string): Promise<HandoffRecord[]> {\r\n this.ensureInitialized();\r\n\r\n return await this.adapter.withRetry(async () => {\r\n if (this.config.type === 'postgresql') {\r\n return await this.getHandoffsByTaskIdPostgreSQL(task_id);\r\n } else {\r\n return await this.getHandoffsByTaskIdSQLite(task_id);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Update handoff status\r\n */\r\n async updateHandoffStatus(\r\n handoff_id: string,\r\n status: HandoffRecord['status'],\r\n metadata?: Record<string, unknown>\r\n ): Promise<void> {\r\n this.ensureInitialized();\r\n\r\n await this.adapter.withRetry(async () => {\r\n if (this.config.type === 'postgresql') {\r\n await this.updateHandoffStatusPostgreSQL(handoff_id, status, metadata);\r\n } else {\r\n await this.updateHandoffStatusSQLite(handoff_id, status, metadata);\r\n }\r\n });\r\n\r\n this.logger.info('Handoff status updated', {\r\n handoff_id,\r\n status,\r\n task_id: this.adapter.getContext().task_id,\r\n });\r\n }\r\n\r\n /**\r\n * Execute queries within a transaction\r\n * Automatically commits on success, rolls back on error\r\n */\r\n async withTransaction<T>(\r\n callback: (tx: TransactionClient) => Promise<T>\r\n ): Promise<T> {\r\n this.ensureInitialized();\r\n\r\n if (this.config.type === 'postgresql') {\r\n return await this.withTransactionPostgreSQL(callback);\r\n } else {\r\n return await this.withTransactionSQLite(callback);\r\n }\r\n }\r\n\r\n /**\r\n * Close all database connections\r\n */\r\n async close(): Promise<void> {\r\n try {\r\n if (this.pg_pool) {\r\n await this.pg_pool.end();\r\n this.logger.info('PostgreSQL connection pool closed');\r\n }\r\n\r\n if (this.sqlite_db) {\r\n await this.sqlite_db.close();\r\n this.logger.info('SQLite connection closed');\r\n }\r\n\r\n this.initialized = false;\r\n } catch (error) {\r\n this.logger.error('Error closing database connections', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // --- PostgreSQL Implementation ---\r\n\r\n private async initializePostgreSQL(): Promise<void> {\r\n if (!this.config.pg) {\r\n throw new Error('PostgreSQL configuration missing');\r\n }\r\n\r\n this.pg_pool = new PgPool({\r\n host: this.config.pg.host,\r\n port: this.config.pg.port,\r\n database: this.config.pg.database,\r\n user: this.config.pg.user,\r\n password: this.config.pg.password,\r\n max: this.config.pg.max_connections || 10,\r\n idleTimeoutMillis: 30000,\r\n connectionTimeoutMillis: 5000,\r\n });\r\n\r\n // Test connection\r\n const client = await this.pg_pool.connect();\r\n client.release();\r\n }\r\n\r\n private async createHandoffPostgreSQL(handoff: HandoffRecord): Promise<HandoffRecord> {\r\n const query = `\r\n INSERT INTO handoffs (\r\n handoff_id, task_id, source_agent_id, target_agent_id,\r\n status, payload, metadata, created_at, updated_at\r\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)\r\n RETURNING *\r\n `;\r\n\r\n const values = [\r\n handoff.handoff_id,\r\n handoff.task_id,\r\n handoff.source_agent_id,\r\n handoff.target_agent_id || null,\r\n handoff.status,\r\n JSON.stringify(handoff.payload),\r\n handoff.metadata ? JSON.stringify(handoff.metadata) : null,\r\n handoff.created_at,\r\n handoff.updated_at,\r\n ];\r\n\r\n const result = await this.pg_pool!.query(query, values);\r\n return this.rowToHandoff(result.rows[0]);\r\n }\r\n\r\n private async getHandoffPostgreSQL(handoff_id: string): Promise<HandoffRecord | null> {\r\n const query = 'SELECT * FROM handoffs WHERE handoff_id = $1';\r\n const result = await this.pg_pool!.query(query, [handoff_id]);\r\n return result.rows.length > 0 ? this.rowToHandoff(result.rows[0]) : null;\r\n }\r\n\r\n private async getHandoffsByTaskIdPostgreSQL(task_id: string): Promise<HandoffRecord[]> {\r\n const query = 'SELECT * FROM handoffs WHERE task_id = $1 ORDER BY created_at DESC';\r\n const result = await this.pg_pool!.query(query, [task_id]);\r\n return result.rows.map(row => this.rowToHandoff(row));\r\n }\r\n\r\n private async updateHandoffStatusPostgreSQL(\r\n handoff_id: string,\r\n status: HandoffRecord['status'],\r\n metadata?: Record<string, unknown>\r\n ): Promise<void> {\r\n const updates: string[] = ['status = $2', 'updated_at = $3'];\r\n const values: any[] = [handoff_id, status, new Date()];\r\n\r\n if (status === 'completed') {\r\n updates.push('completed_at = $4');\r\n values.push(new Date());\r\n }\r\n\r\n if (metadata) {\r\n const idx = values.length + 1;\r\n updates.push(`metadata = $${idx}`);\r\n values.push(JSON.stringify(metadata));\r\n }\r\n\r\n const query = `UPDATE handoffs SET ${updates.join(', ')} WHERE handoff_id = $1`;\r\n await this.pg_pool!.query(query, values);\r\n }\r\n\r\n private async withTransactionPostgreSQL<T>(\r\n callback: (tx: TransactionClient) => Promise<T>\r\n ): Promise<T> {\r\n const client = await this.pg_pool!.connect();\r\n\r\n try {\r\n await client.query('BEGIN');\r\n this.logger.debug('Transaction started (PostgreSQL)');\r\n\r\n const tx = new TransactionClient(client, this.logger);\r\n const result = await callback(tx);\r\n\r\n await client.query('COMMIT');\r\n this.logger.debug('Transaction committed (PostgreSQL)');\r\n\r\n return result;\r\n } catch (error) {\r\n await client.query('ROLLBACK');\r\n this.logger.warn('Transaction rolled back (PostgreSQL)', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n } finally {\r\n client.release();\r\n }\r\n }\r\n\r\n // --- SQLite Implementation ---\r\n\r\n private async initializeSQLite(): Promise<void> {\r\n if (!this.config.sqlite) {\r\n throw new Error('SQLite configuration missing');\r\n }\r\n\r\n const sqlite = await import('sqlite');\r\n this.sqlite_db = await sqlite.open({\r\n filename: this.config.sqlite.filepath,\r\n driver: sqlite3.Database,\r\n });\r\n }\r\n\r\n private async createHandoffSQLite(handoff: HandoffRecord): Promise<HandoffRecord> {\r\n const query = `\r\n INSERT INTO handoffs (\r\n handoff_id, task_id, source_agent_id, target_agent_id,\r\n status, payload, metadata, created_at, updated_at\r\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\r\n `;\r\n\r\n await this.sqlite_db!.run(query, [\r\n handoff.handoff_id,\r\n handoff.task_id,\r\n handoff.source_agent_id,\r\n handoff.target_agent_id || null,\r\n handoff.status,\r\n JSON.stringify(handoff.payload),\r\n handoff.metadata ? JSON.stringify(handoff.metadata) : null,\r\n handoff.created_at.toISOString(),\r\n handoff.updated_at.toISOString(),\r\n ]);\r\n\r\n return handoff;\r\n }\r\n\r\n private async getHandoffSQLite(handoff_id: string): Promise<HandoffRecord | null> {\r\n const query = 'SELECT * FROM handoffs WHERE handoff_id = ?';\r\n const row = await this.sqlite_db!.get(query, [handoff_id]);\r\n return row ? this.rowToHandoff(row) : null;\r\n }\r\n\r\n private async getHandoffsByTaskIdSQLite(task_id: string): Promise<HandoffRecord[]> {\r\n const query = 'SELECT * FROM handoffs WHERE task_id = ? ORDER BY created_at DESC';\r\n const rows = await this.sqlite_db!.all(query, [task_id]);\r\n return rows.map(row => this.rowToHandoff(row));\r\n }\r\n\r\n private async updateHandoffStatusSQLite(\r\n handoff_id: string,\r\n status: HandoffRecord['status'],\r\n metadata?: Record<string, unknown>\r\n ): Promise<void> {\r\n let query = 'UPDATE handoffs SET status = ?, updated_at = ?';\r\n const values: any[] = [status, new Date().toISOString()];\r\n\r\n if (status === 'completed') {\r\n query += ', completed_at = ?';\r\n values.push(new Date().toISOString());\r\n }\r\n\r\n if (metadata) {\r\n query += ', metadata = ?';\r\n values.push(JSON.stringify(metadata));\r\n }\r\n\r\n query += ' WHERE handoff_id = ?';\r\n values.push(handoff_id);\r\n\r\n await this.sqlite_db!.run(query, values);\r\n }\r\n\r\n private async withTransactionSQLite<T>(\r\n callback: (tx: TransactionClient) => Promise<T>\r\n ): Promise<T> {\r\n try {\r\n await this.sqlite_db!.run('BEGIN TRANSACTION');\r\n this.logger.debug('Transaction started (SQLite)');\r\n\r\n const tx = new TransactionClient(this.sqlite_db!, this.logger);\r\n const result = await callback(tx);\r\n\r\n await this.sqlite_db!.run('COMMIT');\r\n this.logger.debug('Transaction committed (SQLite)');\r\n\r\n return result;\r\n } catch (error) {\r\n await this.sqlite_db!.run('ROLLBACK');\r\n this.logger.warn('Transaction rolled back (SQLite)', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // --- Schema Management ---\r\n\r\n private async ensureSchema(): Promise<void> {\r\n const schema = `\r\n CREATE TABLE IF NOT EXISTS handoffs (\r\n handoff_id TEXT PRIMARY KEY,\r\n task_id TEXT NOT NULL,\r\n source_agent_id TEXT NOT NULL,\r\n target_agent_id TEXT,\r\n status TEXT NOT NULL,\r\n payload TEXT NOT NULL,\r\n metadata TEXT,\r\n created_at TEXT NOT NULL,\r\n updated_at TEXT NOT NULL,\r\n completed_at TEXT\r\n );\r\n CREATE INDEX IF NOT EXISTS idx_handoffs_task_id ON handoffs(task_id);\r\n CREATE INDEX IF NOT EXISTS idx_handoffs_status ON handoffs(status);\r\n CREATE INDEX IF NOT EXISTS idx_handoffs_created_at ON handoffs(created_at);\r\n `;\r\n\r\n if (this.config.type === 'postgresql') {\r\n // PostgreSQL schema (adjust types)\r\n const pgSchema = schema\r\n .replace(/TEXT/g, 'VARCHAR(255)')\r\n .replace(/payload VARCHAR\\(255\\)/g, 'payload JSONB')\r\n .replace(/metadata VARCHAR\\(255\\)/g, 'metadata JSONB')\r\n .replace(/created_at VARCHAR\\(255\\)/g, 'created_at TIMESTAMP')\r\n .replace(/updated_at VARCHAR\\(255\\)/g, 'updated_at TIMESTAMP')\r\n .replace(/completed_at VARCHAR\\(255\\)/g, 'completed_at TIMESTAMP');\r\n\r\n const statements = pgSchema.split(';').filter(s => s.trim());\r\n for (const stmt of statements) {\r\n await this.pg_pool!.query(stmt);\r\n }\r\n } else {\r\n // SQLite schema\r\n const statements = schema.split(';').filter(s => s.trim());\r\n for (const stmt of statements) {\r\n await this.sqlite_db!.run(stmt);\r\n }\r\n }\r\n }\r\n\r\n // --- Helper Methods ---\r\n\r\n private ensureInitialized(): void {\r\n if (!this.initialized) {\r\n throw new Error('DatabaseHandoff not initialized. Call initialize() first.');\r\n }\r\n }\r\n\r\n private generateHandoffId(): string {\r\n const timestamp = Date.now();\r\n const random = Math.random().toString(36).substring(2, 10);\r\n return `handoff-${timestamp}-${random}`;\r\n }\r\n\r\n private rowToHandoff(row: any): HandoffRecord {\r\n return {\r\n handoff_id: row.handoff_id,\r\n task_id: row.task_id,\r\n source_agent_id: row.source_agent_id,\r\n target_agent_id: row.target_agent_id,\r\n status: row.status,\r\n payload: typeof row.payload === 'string' ? JSON.parse(row.payload) : row.payload,\r\n metadata: row.metadata\r\n ? typeof row.metadata === 'string'\r\n ? JSON.parse(row.metadata)\r\n : row.metadata\r\n : undefined,\r\n created_at: new Date(row.created_at),\r\n updated_at: new Date(row.updated_at),\r\n completed_at: row.completed_at ? new Date(row.completed_at) : undefined,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Transaction client for safe query execution within transactions\r\n */\r\nexport class TransactionClient {\r\n constructor(\r\n private client: PoolClient | SqliteDB,\r\n private logger: Logger\r\n ) {}\r\n\r\n async query(sql: string, params?: any[]): Promise<any> {\r\n this.logger.debug('Executing query in transaction', { sql });\r\n\r\n if ('query' in this.client) {\r\n // PostgreSQL\r\n const result = await this.client.query(sql, params);\r\n return result;\r\n } else {\r\n // SQLite\r\n if (sql.trim().toUpperCase().startsWith('SELECT')) {\r\n return await this.client.all(sql, params);\r\n } else {\r\n return await this.client.run(sql, params);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * USAGE EXAMPLE - Before (Ad-hoc database access):\r\n *\r\n * ```typescript\r\n * // ❌ No correlation, no transaction safety, manual connection management\r\n * import { Pool } from 'pg';\r\n *\r\n * const pool = new Pool({ ... });\r\n *\r\n * async function createTask(data: any) {\r\n * const client = await pool.connect();\r\n * try {\r\n * await client.query('BEGIN');\r\n * await client.query('INSERT INTO tasks ...');\r\n * await client.query('INSERT INTO task_metadata ...');\r\n * await client.query('COMMIT');\r\n * } catch (err) {\r\n * await client.query('ROLLBACK');\r\n * throw err;\r\n * } finally {\r\n * client.release();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * USAGE EXAMPLE - After (Standardized with correlation):\r\n *\r\n * ```typescript\r\n * // ✅ Automatic correlation, transaction safety, retry logic\r\n * const handoff = new DatabaseHandoff({\r\n * type: 'postgresql',\r\n * pg: { host: 'localhost', port: 5432, database: 'cfn', user: 'user', password: 'pass' },\r\n * }, {\r\n * task_id: 'task-123',\r\n * agent_id: 'agent-456',\r\n * });\r\n *\r\n * await handoff.initialize();\r\n *\r\n * async function createTask(data: any) {\r\n * await handoff.withTransaction(async (tx) => {\r\n * await tx.query('INSERT INTO tasks (task_id, data) VALUES ($1, $2)', ['task-123', data]);\r\n * await tx.query('INSERT INTO task_metadata (task_id, source) VALUES ($1, $2)', ['task-123', 'agent-456']);\r\n * // Auto-commit on success, auto-rollback on error\r\n * });\r\n * }\r\n * ```\r\n */\r\n"],"names":["Pool","PgPool","sqlite3","StandardAdapter","JSONLogger","DatabaseHandoff","config","adapter","logger","pg_pool","sqlite_db","initialized","context","task_id","agent_id","initialize","type","initializePostgreSQL","initializeSQLite","Error","ensureSchema","info","getContext","database_type","error","message","String","createHandoff","params","ensureInitialized","handoff_id","generateHandoffId","handoff","source_agent_id","target_agent_id","status","payload","metadata","created_at","Date","updated_at","withRetry","createHandoffPostgreSQL","createHandoffSQLite","getHandoff","getHandoffPostgreSQL","getHandoffSQLite","getHandoffsByTaskId","getHandoffsByTaskIdPostgreSQL","getHandoffsByTaskIdSQLite","updateHandoffStatus","updateHandoffStatusPostgreSQL","updateHandoffStatusSQLite","withTransaction","callback","withTransactionPostgreSQL","withTransactionSQLite","close","end","pg","host","port","database","user","password","max","max_connections","idleTimeoutMillis","connectionTimeoutMillis","client","connect","release","query","values","JSON","stringify","result","rowToHandoff","rows","length","map","row","updates","push","idx","join","debug","tx","TransactionClient","warn","sqlite","open","filename","filepath","driver","Database","run","toISOString","get","all","schema","pgSchema","replace","statements","split","filter","s","trim","stmt","timestamp","now","random","Math","toString","substring","parse","undefined","completed_at","sql","toUpperCase","startsWith"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/integration/DatabaseHandoff.ts"],"sourcesContent":["/**\r\n * DatabaseHandoff.ts - Standard database handoff patterns with cross-database correlation\r\n *\r\n * Features:\r\n * - Cross-database correlation via task_id\r\n * - Transaction management (begin/commit/rollback)\r\n * - Query builder with standard correlation\r\n * - Connection pooling (PostgreSQL, SQLite)\r\n * - Automatic retry on transient failures\r\n */\r\n\r\nimport { Pool as PgPool, PoolClient, QueryResult } from 'pg';\r\nimport sqlite3 from 'sqlite3';\r\nimport { Database as SqliteDB } from 'sqlite';\r\nimport { StandardAdapter, Logger, JSONLogger } from './StandardAdapter.js';\r\n\r\n/**\r\n * Standard handoff record structure\r\n */\r\nexport interface HandoffRecord {\r\n /** Unique handoff ID */\r\n handoff_id: string;\r\n /** Task correlation ID */\r\n task_id: string;\r\n /** Source agent ID */\r\n source_agent_id: string;\r\n /** Target agent ID (if known) */\r\n target_agent_id?: string;\r\n /** Handoff status: pending, in_progress, completed, failed */\r\n status: 'pending' | 'in_progress' | 'completed' | 'failed';\r\n /** Handoff payload (JSON) */\r\n payload: Record<string, unknown>;\r\n /** Optional metadata */\r\n metadata?: Record<string, unknown>;\r\n /** Creation timestamp */\r\n created_at: Date;\r\n /** Update timestamp */\r\n updated_at: Date;\r\n /** Completion timestamp */\r\n completed_at?: Date;\r\n}\r\n\r\n/**\r\n * Database connection configuration\r\n */\r\nexport interface DatabaseConfig {\r\n type: 'postgresql' | 'sqlite';\r\n /** PostgreSQL connection config */\r\n pg?: {\r\n host: string;\r\n port: number;\r\n database: string;\r\n user: string;\r\n password: string;\r\n max_connections?: number;\r\n };\r\n /** SQLite connection config */\r\n sqlite?: {\r\n filepath: string;\r\n mode?: number;\r\n };\r\n}\r\n\r\n/**\r\n * Transaction context for safe rollback\r\n */\r\ninterface TransactionContext {\r\n client?: PoolClient;\r\n in_transaction: boolean;\r\n}\r\n\r\n/**\r\n * DatabaseHandoff - Reference implementation for cross-database correlation\r\n *\r\n * @example\r\n * ```typescript\r\n * // PostgreSQL example\r\n * const pgHandoff = new DatabaseHandoff({\r\n * type: 'postgresql',\r\n * pg: {\r\n * host: 'localhost',\r\n * port: 5432,\r\n * database: 'cfn_db',\r\n * user: 'cfn_user',\r\n * password: 'secret',\r\n * },\r\n * }, {\r\n * task_id: 'task-123',\r\n * agent_id: 'agent-456',\r\n * });\r\n *\r\n * await pgHandoff.initialize();\r\n *\r\n * // Create handoff with automatic correlation\r\n * const handoff = await pgHandoff.createHandoff({\r\n * source_agent_id: 'agent-456',\r\n * target_agent_id: 'agent-789',\r\n * payload: { data: 'example' },\r\n * });\r\n *\r\n * // Query by task_id (cross-database correlation)\r\n * const handoffs = await pgHandoff.getHandoffsByTaskId('task-123');\r\n *\r\n * // Transaction example\r\n * await pgHandoff.withTransaction(async (tx) => {\r\n * await tx.query('INSERT INTO tasks ...');\r\n * await tx.query('UPDATE agents ...');\r\n * // Automatic commit on success, rollback on error\r\n * });\r\n * ```\r\n */\r\nexport class DatabaseHandoff {\r\n private config: DatabaseConfig;\r\n private adapter: StandardAdapter;\r\n private logger: Logger;\r\n\r\n // Connection pools\r\n private pg_pool?: PgPool;\r\n private sqlite_db?: SqliteDB;\r\n\r\n // Initialization state\r\n private initialized = false;\r\n\r\n constructor(\r\n config: DatabaseConfig,\r\n context: { task_id: string; agent_id?: string; logger?: Logger }\r\n ) {\r\n this.config = config;\r\n this.logger = context.logger || new JSONLogger();\r\n this.adapter = new StandardAdapter({\r\n task_id: context.task_id,\r\n agent_id: context.agent_id,\r\n logger: this.logger,\r\n });\r\n }\r\n\r\n /**\r\n * Initialize database connection and schema\r\n */\r\n async initialize(): Promise<void> {\r\n if (this.initialized) {\r\n return;\r\n }\r\n\r\n try {\r\n if (this.config.type === 'postgresql') {\r\n await this.initializePostgreSQL();\r\n } else if (this.config.type === 'sqlite') {\r\n await this.initializeSQLite();\r\n } else {\r\n throw new Error(`Unsupported database type: ${this.config.type}`);\r\n }\r\n\r\n await this.ensureSchema();\r\n this.initialized = true;\r\n\r\n this.logger.info('Database handoff initialized', {\r\n task_id: this.adapter.getContext().task_id,\r\n database_type: this.config.type,\r\n });\r\n } catch (error) {\r\n this.logger.error('Failed to initialize database', {\r\n task_id: this.adapter.getContext().task_id,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Create a new handoff record\r\n */\r\n async createHandoff(params: {\r\n source_agent_id: string;\r\n target_agent_id?: string;\r\n payload: Record<string, unknown>;\r\n metadata?: Record<string, unknown>;\r\n }): Promise<HandoffRecord> {\r\n this.ensureInitialized();\r\n\r\n const handoff_id = this.generateHandoffId();\r\n const { task_id } = this.adapter.getContext();\r\n\r\n const handoff: HandoffRecord = {\r\n handoff_id,\r\n task_id,\r\n source_agent_id: params.source_agent_id,\r\n target_agent_id: params.target_agent_id,\r\n status: 'pending',\r\n payload: params.payload,\r\n metadata: params.metadata,\r\n created_at: new Date(),\r\n updated_at: new Date(),\r\n };\r\n\r\n return await this.adapter.withRetry(async () => {\r\n if (this.config.type === 'postgresql') {\r\n return await this.createHandoffPostgreSQL(handoff);\r\n } else {\r\n return await this.createHandoffSQLite(handoff);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get handoff by ID\r\n */\r\n async getHandoff(handoff_id: string): Promise<HandoffRecord | null> {\r\n this.ensureInitialized();\r\n\r\n return await this.adapter.withRetry(async () => {\r\n if (this.config.type === 'postgresql') {\r\n return await this.getHandoffPostgreSQL(handoff_id);\r\n } else {\r\n return await this.getHandoffSQLite(handoff_id);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Get all handoffs for a task (cross-database correlation)\r\n */\r\n async getHandoffsByTaskId(task_id: string): Promise<HandoffRecord[]> {\r\n this.ensureInitialized();\r\n\r\n return await this.adapter.withRetry(async () => {\r\n if (this.config.type === 'postgresql') {\r\n return await this.getHandoffsByTaskIdPostgreSQL(task_id);\r\n } else {\r\n return await this.getHandoffsByTaskIdSQLite(task_id);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Update handoff status\r\n */\r\n async updateHandoffStatus(\r\n handoff_id: string,\r\n status: HandoffRecord['status'],\r\n metadata?: Record<string, unknown>\r\n ): Promise<void> {\r\n this.ensureInitialized();\r\n\r\n await this.adapter.withRetry(async () => {\r\n if (this.config.type === 'postgresql') {\r\n await this.updateHandoffStatusPostgreSQL(handoff_id, status, metadata);\r\n } else {\r\n await this.updateHandoffStatusSQLite(handoff_id, status, metadata);\r\n }\r\n });\r\n\r\n this.logger.info('Handoff status updated', {\r\n handoff_id,\r\n status,\r\n task_id: this.adapter.getContext().task_id,\r\n });\r\n }\r\n\r\n /**\r\n * Execute queries within a transaction\r\n * Automatically commits on success, rolls back on error\r\n */\r\n async withTransaction<T>(\r\n callback: (tx: TransactionClient) => Promise<T>\r\n ): Promise<T> {\r\n this.ensureInitialized();\r\n\r\n if (this.config.type === 'postgresql') {\r\n return await this.withTransactionPostgreSQL(callback);\r\n } else {\r\n return await this.withTransactionSQLite(callback);\r\n }\r\n }\r\n\r\n /**\r\n * Close all database connections\r\n */\r\n async close(): Promise<void> {\r\n try {\r\n if (this.pg_pool) {\r\n await this.pg_pool.end();\r\n this.logger.info('PostgreSQL connection pool closed');\r\n }\r\n\r\n if (this.sqlite_db) {\r\n await this.sqlite_db.close();\r\n this.logger.info('SQLite connection closed');\r\n }\r\n\r\n this.initialized = false;\r\n } catch (error) {\r\n this.logger.error('Error closing database connections', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // --- PostgreSQL Implementation ---\r\n\r\n private async initializePostgreSQL(): Promise<void> {\r\n if (!this.config.pg) {\r\n throw new Error('PostgreSQL configuration missing');\r\n }\r\n\r\n this.pg_pool = new PgPool({\r\n host: this.config.pg.host,\r\n port: this.config.pg.port,\r\n database: this.config.pg.database,\r\n user: this.config.pg.user,\r\n password: this.config.pg.password,\r\n max: this.config.pg.max_connections || 10,\r\n idleTimeoutMillis: 30000,\r\n connectionTimeoutMillis: 5000,\r\n });\r\n\r\n // Test connection\r\n const client = await this.pg_pool.connect();\r\n client.release();\r\n }\r\n\r\n private async createHandoffPostgreSQL(handoff: HandoffRecord): Promise<HandoffRecord> {\r\n const query = `\r\n INSERT INTO handoffs (\r\n handoff_id, task_id, source_agent_id, target_agent_id,\r\n status, payload, metadata, created_at, updated_at\r\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)\r\n RETURNING *\r\n `;\r\n\r\n const values = [\r\n handoff.handoff_id,\r\n handoff.task_id,\r\n handoff.source_agent_id,\r\n handoff.target_agent_id || null,\r\n handoff.status,\r\n JSON.stringify(handoff.payload),\r\n handoff.metadata ? JSON.stringify(handoff.metadata) : null,\r\n handoff.created_at,\r\n handoff.updated_at,\r\n ];\r\n\r\n const result = await this.pg_pool!.query(query, values);\r\n return this.rowToHandoff(result.rows[0]);\r\n }\r\n\r\n private async getHandoffPostgreSQL(handoff_id: string): Promise<HandoffRecord | null> {\r\n const query = 'SELECT * FROM handoffs WHERE handoff_id = $1';\r\n const result = await this.pg_pool!.query(query, [handoff_id]);\r\n return result.rows.length > 0 ? this.rowToHandoff(result.rows[0]) : null;\r\n }\r\n\r\n private async getHandoffsByTaskIdPostgreSQL(task_id: string): Promise<HandoffRecord[]> {\r\n const query = 'SELECT * FROM handoffs WHERE task_id = $1 ORDER BY created_at DESC';\r\n const result = await this.pg_pool!.query(query, [task_id]);\r\n return result.rows.map(row => this.rowToHandoff(row));\r\n }\r\n\r\n private async updateHandoffStatusPostgreSQL(\r\n handoff_id: string,\r\n status: HandoffRecord['status'],\r\n metadata?: Record<string, unknown>\r\n ): Promise<void> {\r\n const updates: string[] = ['status = $2', 'updated_at = $3'];\r\n const values: any[] = [handoff_id, status, new Date()];\r\n\r\n if (status === 'completed') {\r\n updates.push('completed_at = $4');\r\n values.push(new Date());\r\n }\r\n\r\n if (metadata) {\r\n const idx = values.length + 1;\r\n updates.push(`metadata = $${idx}`);\r\n values.push(JSON.stringify(metadata));\r\n }\r\n\r\n const query = `UPDATE handoffs SET ${updates.join(', ')} WHERE handoff_id = $1`;\r\n await this.pg_pool!.query(query, values);\r\n }\r\n\r\n private async withTransactionPostgreSQL<T>(\r\n callback: (tx: TransactionClient) => Promise<T>\r\n ): Promise<T> {\r\n const client = await this.pg_pool!.connect();\r\n\r\n try {\r\n await client.query('BEGIN');\r\n this.logger.debug('Transaction started (PostgreSQL)');\r\n\r\n const tx = new TransactionClient(client, this.logger);\r\n const result = await callback(tx);\r\n\r\n await client.query('COMMIT');\r\n this.logger.debug('Transaction committed (PostgreSQL)');\r\n\r\n return result;\r\n } catch (error) {\r\n await client.query('ROLLBACK');\r\n this.logger.warn('Transaction rolled back (PostgreSQL)', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n } finally {\r\n client.release();\r\n }\r\n }\r\n\r\n // --- SQLite Implementation ---\r\n\r\n private async initializeSQLite(): Promise<void> {\r\n if (!this.config.sqlite) {\r\n throw new Error('SQLite configuration missing');\r\n }\r\n\r\n const sqlite = await import('sqlite');\r\n this.sqlite_db = await sqlite.open({\r\n filename: this.config.sqlite.filepath,\r\n driver: sqlite3.Database,\r\n });\r\n }\r\n\r\n private async createHandoffSQLite(handoff: HandoffRecord): Promise<HandoffRecord> {\r\n const query = `\r\n INSERT INTO handoffs (\r\n handoff_id, task_id, source_agent_id, target_agent_id,\r\n status, payload, metadata, created_at, updated_at\r\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\r\n `;\r\n\r\n await this.sqlite_db!.run(query, [\r\n handoff.handoff_id,\r\n handoff.task_id,\r\n handoff.source_agent_id,\r\n handoff.target_agent_id || null,\r\n handoff.status,\r\n JSON.stringify(handoff.payload),\r\n handoff.metadata ? JSON.stringify(handoff.metadata) : null,\r\n handoff.created_at.toISOString(),\r\n handoff.updated_at.toISOString(),\r\n ]);\r\n\r\n return handoff;\r\n }\r\n\r\n private async getHandoffSQLite(handoff_id: string): Promise<HandoffRecord | null> {\r\n const query = 'SELECT * FROM handoffs WHERE handoff_id = ?';\r\n const row = await this.sqlite_db!.get(query, [handoff_id]);\r\n return row ? this.rowToHandoff(row) : null;\r\n }\r\n\r\n private async getHandoffsByTaskIdSQLite(task_id: string): Promise<HandoffRecord[]> {\r\n const query = 'SELECT * FROM handoffs WHERE task_id = ? ORDER BY created_at DESC';\r\n const rows = await this.sqlite_db!.all(query, [task_id]);\r\n return rows.map(row => this.rowToHandoff(row));\r\n }\r\n\r\n private async updateHandoffStatusSQLite(\r\n handoff_id: string,\r\n status: HandoffRecord['status'],\r\n metadata?: Record<string, unknown>\r\n ): Promise<void> {\r\n let query = 'UPDATE handoffs SET status = ?, updated_at = ?';\r\n const values: any[] = [status, new Date().toISOString()];\r\n\r\n if (status === 'completed') {\r\n query += ', completed_at = ?';\r\n values.push(new Date().toISOString());\r\n }\r\n\r\n if (metadata) {\r\n query += ', metadata = ?';\r\n values.push(JSON.stringify(metadata));\r\n }\r\n\r\n query += ' WHERE handoff_id = ?';\r\n values.push(handoff_id);\r\n\r\n await this.sqlite_db!.run(query, values);\r\n }\r\n\r\n private async withTransactionSQLite<T>(\r\n callback: (tx: TransactionClient) => Promise<T>\r\n ): Promise<T> {\r\n try {\r\n await this.sqlite_db!.run('BEGIN TRANSACTION');\r\n this.logger.debug('Transaction started (SQLite)');\r\n\r\n const tx = new TransactionClient(this.sqlite_db!, this.logger);\r\n const result = await callback(tx);\r\n\r\n await this.sqlite_db!.run('COMMIT');\r\n this.logger.debug('Transaction committed (SQLite)');\r\n\r\n return result;\r\n } catch (error) {\r\n await this.sqlite_db!.run('ROLLBACK');\r\n this.logger.warn('Transaction rolled back (SQLite)', {\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n throw error;\r\n }\r\n }\r\n\r\n // --- Schema Management ---\r\n\r\n private async ensureSchema(): Promise<void> {\r\n const schema = `\r\n CREATE TABLE IF NOT EXISTS handoffs (\r\n handoff_id TEXT PRIMARY KEY,\r\n task_id TEXT NOT NULL,\r\n source_agent_id TEXT NOT NULL,\r\n target_agent_id TEXT,\r\n status TEXT NOT NULL,\r\n payload TEXT NOT NULL,\r\n metadata TEXT,\r\n created_at TEXT NOT NULL,\r\n updated_at TEXT NOT NULL,\r\n completed_at TEXT\r\n );\r\n CREATE INDEX IF NOT EXISTS idx_handoffs_task_id ON handoffs(task_id);\r\n CREATE INDEX IF NOT EXISTS idx_handoffs_status ON handoffs(status);\r\n CREATE INDEX IF NOT EXISTS idx_handoffs_created_at ON handoffs(created_at);\r\n `;\r\n\r\n if (this.config.type === 'postgresql') {\r\n // PostgreSQL schema (adjust types)\r\n const pgSchema = schema\r\n .replace(/TEXT/g, 'VARCHAR(255)')\r\n .replace(/payload VARCHAR\\(255\\)/g, 'payload JSONB')\r\n .replace(/metadata VARCHAR\\(255\\)/g, 'metadata JSONB')\r\n .replace(/created_at VARCHAR\\(255\\)/g, 'created_at TIMESTAMP')\r\n .replace(/updated_at VARCHAR\\(255\\)/g, 'updated_at TIMESTAMP')\r\n .replace(/completed_at VARCHAR\\(255\\)/g, 'completed_at TIMESTAMP');\r\n\r\n const statements = pgSchema.split(';').filter(s => s.trim());\r\n for (const stmt of statements) {\r\n await this.pg_pool!.query(stmt);\r\n }\r\n } else {\r\n // SQLite schema\r\n const statements = schema.split(';').filter(s => s.trim());\r\n for (const stmt of statements) {\r\n await this.sqlite_db!.run(stmt);\r\n }\r\n }\r\n }\r\n\r\n // --- Helper Methods ---\r\n\r\n private ensureInitialized(): void {\r\n if (!this.initialized) {\r\n throw new Error('DatabaseHandoff not initialized. Call initialize() first.');\r\n }\r\n }\r\n\r\n private generateHandoffId(): string {\r\n const timestamp = Date.now();\r\n const random = Math.random().toString(36).substring(2, 10);\r\n return `handoff-${timestamp}-${random}`;\r\n }\r\n\r\n private rowToHandoff(row: any): HandoffRecord {\r\n return {\r\n handoff_id: row.handoff_id,\r\n task_id: row.task_id,\r\n source_agent_id: row.source_agent_id,\r\n target_agent_id: row.target_agent_id,\r\n status: row.status,\r\n payload: typeof row.payload === 'string' ? JSON.parse(row.payload) : row.payload,\r\n metadata: row.metadata\r\n ? typeof row.metadata === 'string'\r\n ? JSON.parse(row.metadata)\r\n : row.metadata\r\n : undefined,\r\n created_at: new Date(row.created_at),\r\n updated_at: new Date(row.updated_at),\r\n completed_at: row.completed_at ? new Date(row.completed_at) : undefined,\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Transaction client for safe query execution within transactions\r\n */\r\nexport class TransactionClient {\r\n constructor(\r\n private client: PoolClient | SqliteDB,\r\n private logger: Logger\r\n ) {}\r\n\r\n async query(sql: string, params?: any[]): Promise<any> {\r\n this.logger.debug('Executing query in transaction', { sql });\r\n\r\n if ('query' in this.client) {\r\n // PostgreSQL\r\n const result = await this.client.query(sql, params);\r\n return result;\r\n } else {\r\n // SQLite\r\n if (sql.trim().toUpperCase().startsWith('SELECT')) {\r\n return await this.client.all(sql, params);\r\n } else {\r\n return await this.client.run(sql, params);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * USAGE EXAMPLE - Before (Ad-hoc database access):\r\n *\r\n * ```typescript\r\n * // ❌ No correlation, no transaction safety, manual connection management\r\n * import { Pool } from 'pg';\r\n *\r\n * const pool = new Pool({ ... });\r\n *\r\n * async function createTask(data: any) {\r\n * const client = await pool.connect();\r\n * try {\r\n * await client.query('BEGIN');\r\n * await client.query('INSERT INTO tasks ...');\r\n * await client.query('INSERT INTO task_metadata ...');\r\n * await client.query('COMMIT');\r\n * } catch (err) {\r\n * await client.query('ROLLBACK');\r\n * throw err;\r\n * } finally {\r\n * client.release();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * USAGE EXAMPLE - After (Standardized with correlation):\r\n *\r\n * ```typescript\r\n * // ✅ Automatic correlation, transaction safety, retry logic\r\n * const handoff = new DatabaseHandoff({\r\n * type: 'postgresql',\r\n * pg: { host: 'localhost', port: 5432, database: 'cfn', user: 'user', password: 'pass' },\r\n * }, {\r\n * task_id: 'task-123',\r\n * agent_id: 'agent-456',\r\n * });\r\n *\r\n * await handoff.initialize();\r\n *\r\n * async function createTask(data: any) {\r\n * await handoff.withTransaction(async (tx) => {\r\n * await tx.query('INSERT INTO tasks (task_id, data) VALUES ($1, $2)', ['task-123', data]);\r\n * await tx.query('INSERT INTO task_metadata (task_id, source) VALUES ($1, $2)', ['task-123', 'agent-456']);\r\n * // Auto-commit on success, auto-rollback on error\r\n * });\r\n * }\r\n * ```\r\n */\r\n"],"names":["Pool","PgPool","sqlite3","StandardAdapter","JSONLogger","DatabaseHandoff","config","adapter","logger","pg_pool","sqlite_db","initialized","context","task_id","agent_id","initialize","type","initializePostgreSQL","initializeSQLite","Error","ensureSchema","info","getContext","database_type","error","message","String","createHandoff","params","ensureInitialized","handoff_id","generateHandoffId","handoff","source_agent_id","target_agent_id","status","payload","metadata","created_at","Date","updated_at","withRetry","createHandoffPostgreSQL","createHandoffSQLite","getHandoff","getHandoffPostgreSQL","getHandoffSQLite","getHandoffsByTaskId","getHandoffsByTaskIdPostgreSQL","getHandoffsByTaskIdSQLite","updateHandoffStatus","updateHandoffStatusPostgreSQL","updateHandoffStatusSQLite","withTransaction","callback","withTransactionPostgreSQL","withTransactionSQLite","close","end","pg","host","port","database","user","password","max","max_connections","idleTimeoutMillis","connectionTimeoutMillis","client","connect","release","query","values","JSON","stringify","result","rowToHandoff","rows","length","map","row","updates","push","idx","join","debug","tx","TransactionClient","warn","sqlite","open","filename","filepath","driver","Database","run","toISOString","get","all","schema","pgSchema","replace","statements","split","filter","s","trim","stmt","timestamp","now","random","Math","toString","substring","parse","undefined","completed_at","sql","toUpperCase","startsWith"],"mappings":"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"}
@@ -0,0 +1,367 @@
1
+ /**
2
+ * Edge Case Analyzer Job
3
+ *
4
+ * Analyzes edge cases to detect patterns and generate dashboard data.
5
+ * Part of Task 1.5: MVP Edge Case Feedback Loop
6
+ *
7
+ * Features:
8
+ * - Pattern detection across multiple edge cases
9
+ * - Common error substring extraction
10
+ * - Common input pattern detection
11
+ * - Severity aggregation
12
+ * - Dashboard data generation
13
+ * - Scheduled analysis (cron job ready)
14
+ *
15
+ * Usage:
16
+ * const analyzer = new EdgeCaseAnalyzer(dbService, logger);
17
+ * const report = await analyzer.analyzeEdgeCases();
18
+ * const patterns = await analyzer.generatePatterns();
19
+ */ import { createLogger } from '../lib/logging.js';
20
+ import { createError, ErrorCode } from '../lib/errors.js';
21
+ import { generateShortCorrelationId } from '../lib/correlation.js';
22
+ /**
23
+ * Edge case analyzer service
24
+ */ export class EdgeCaseAnalyzer {
25
+ dbService;
26
+ logger;
27
+ config;
28
+ constructor(dbService, logger, config){
29
+ this.dbService = dbService;
30
+ this.logger = logger || createLogger('edge-case-analyzer');
31
+ // Set default config
32
+ this.config = {
33
+ minPatternOccurrences: config?.minPatternOccurrences ?? 3,
34
+ maxPatterns: config?.maxPatterns ?? 50,
35
+ minSubstringLength: config?.minSubstringLength ?? 10
36
+ };
37
+ }
38
+ /**
39
+ * Analyze all edge cases and generate comprehensive report
40
+ *
41
+ * @returns Analysis report
42
+ */ async analyzeEdgeCases() {
43
+ this.logger.info('Starting edge case analysis');
44
+ try {
45
+ const sqlite = this.dbService.getAdapter('sqlite');
46
+ // Get total edge cases
47
+ const totalResult = await sqlite.raw('SELECT COUNT(*) as count FROM edge_cases');
48
+ const totalEdgeCases = Array.isArray(totalResult) && totalResult[0] ? totalResult[0].count : 0;
49
+ // Get new edge cases
50
+ const newResult = await sqlite.raw('SELECT COUNT(*) as count FROM edge_cases WHERE status = "new"');
51
+ const newEdgeCases = Array.isArray(newResult) && newResult[0] ? newResult[0].count : 0;
52
+ // Get top failures
53
+ const topFailures = await this.getTopFailures();
54
+ // Get high severity failures
55
+ const highSeverityFailures = await this.getHighSeverityFailures();
56
+ // Get failure trends
57
+ const trends = await this.getFailureTrends();
58
+ // Generate patterns
59
+ const patterns = await this.generatePatterns();
60
+ const patternsDetected = patterns.length;
61
+ const report = {
62
+ timestamp: new Date(),
63
+ totalEdgeCases,
64
+ newEdgeCases,
65
+ patternsDetected,
66
+ topFailures,
67
+ highSeverityFailures,
68
+ trends
69
+ };
70
+ this.logger.info('Edge case analysis complete', {
71
+ totalEdgeCases,
72
+ newEdgeCases,
73
+ patternsDetected
74
+ });
75
+ return report;
76
+ } catch (error) {
77
+ this.logger.error('Failed to analyze edge cases', error);
78
+ throw createError(ErrorCode.UNKNOWN_ERROR, 'Edge case analysis failed', undefined, error);
79
+ }
80
+ }
81
+ /**
82
+ * Generate failure patterns from edge cases
83
+ *
84
+ * @returns Array of detected patterns
85
+ */ async generatePatterns() {
86
+ this.logger.info('Generating failure patterns');
87
+ try {
88
+ const sqlite = this.dbService.getAdapter('sqlite');
89
+ // 1. Query all edge cases
90
+ const edgeCases = await this.getAllNewEdgeCases();
91
+ if (edgeCases.length === 0) {
92
+ this.logger.debug('No edge cases to analyze');
93
+ return [];
94
+ }
95
+ // 2. Group by error type and skill
96
+ const groups = this.groupEdgeCases(edgeCases);
97
+ // 3. Find patterns
98
+ const patterns = [];
99
+ for (const [key, cases] of Object.entries(groups)){
100
+ if (cases.length < this.config.minPatternOccurrences) {
101
+ continue; // Need ≥minPatternOccurrences occurrences
102
+ }
103
+ const [skill_id, error_type] = key.split(':');
104
+ // Extract common patterns
105
+ const commonErrors = this.findCommonSubstrings(cases.map((c)=>c.error_message));
106
+ const commonInputs = this.findCommonInputPatterns(cases);
107
+ const severity = this.calculateAverageSeverity(cases);
108
+ const pattern = {
109
+ pattern_id: `pattern-${generateShortCorrelationId()}`,
110
+ skill_id,
111
+ error_type: error_type,
112
+ occurrence_count: cases.length,
113
+ common_errors: commonErrors,
114
+ common_inputs: commonInputs,
115
+ severity,
116
+ suggested_fix: null,
117
+ status: 'detected',
118
+ first_detected: new Date(),
119
+ last_updated: new Date()
120
+ };
121
+ patterns.push(pattern);
122
+ // Store pattern in database
123
+ await this.storePattern(pattern);
124
+ }
125
+ this.logger.info(`Generated ${patterns.length} patterns`);
126
+ return patterns.slice(0, this.config.maxPatterns);
127
+ } catch (error) {
128
+ this.logger.error('Failed to generate patterns', error);
129
+ throw createError(ErrorCode.UNKNOWN_ERROR, 'Pattern generation failed', undefined, error);
130
+ }
131
+ }
132
+ /**
133
+ * Get top failures by skill and error type
134
+ */ async getTopFailures() {
135
+ const sqlite = this.dbService.getAdapter('sqlite');
136
+ const query = `
137
+ SELECT
138
+ skill_id,
139
+ error_type,
140
+ SUM(occurrence_count) as total_failures,
141
+ MAX(severity) as max_severity,
142
+ COUNT(*) as unique_cases,
143
+ MAX(last_seen) as most_recent
144
+ FROM edge_cases
145
+ WHERE status = 'new'
146
+ GROUP BY skill_id, error_type
147
+ ORDER BY total_failures DESC
148
+ LIMIT 10
149
+ `;
150
+ const rows = await sqlite.raw(query);
151
+ if (!Array.isArray(rows)) {
152
+ return [];
153
+ }
154
+ return rows.map((row)=>({
155
+ skill_id: row.skill_id,
156
+ error_type: row.error_type,
157
+ total_failures: row.total_failures,
158
+ max_severity: row.max_severity,
159
+ unique_cases: row.unique_cases,
160
+ most_recent: new Date(row.most_recent)
161
+ }));
162
+ }
163
+ /**
164
+ * Get high severity failures
165
+ */ async getHighSeverityFailures() {
166
+ const sqlite = this.dbService.getAdapter('sqlite');
167
+ const query = `
168
+ SELECT
169
+ id,
170
+ skill_id,
171
+ error_type,
172
+ severity,
173
+ error_message,
174
+ occurrence_count,
175
+ last_seen
176
+ FROM edge_cases
177
+ WHERE severity IN ('critical', 'high')
178
+ AND status = 'new'
179
+ ORDER BY last_seen DESC, occurrence_count DESC
180
+ LIMIT 20
181
+ `;
182
+ const rows = await sqlite.raw(query);
183
+ if (!Array.isArray(rows)) {
184
+ return [];
185
+ }
186
+ return rows.map((row)=>({
187
+ id: row.id,
188
+ skill_id: row.skill_id,
189
+ error_type: row.error_type,
190
+ severity: row.severity,
191
+ error_message: row.error_message,
192
+ occurrence_count: row.occurrence_count,
193
+ last_seen: new Date(row.last_seen)
194
+ }));
195
+ }
196
+ /**
197
+ * Get failure trends (last 30 days)
198
+ */ async getFailureTrends() {
199
+ const sqlite = this.dbService.getAdapter('sqlite');
200
+ const query = `
201
+ SELECT
202
+ DATE(first_seen) as date,
203
+ error_type,
204
+ COUNT(*) as new_failures,
205
+ SUM(occurrence_count) as total_occurrences
206
+ FROM edge_cases
207
+ WHERE first_seen >= datetime('now', '-30 days')
208
+ GROUP BY DATE(first_seen), error_type
209
+ ORDER BY date DESC
210
+ `;
211
+ const rows = await sqlite.raw(query);
212
+ if (!Array.isArray(rows)) {
213
+ return [];
214
+ }
215
+ return rows.map((row)=>({
216
+ date: row.date,
217
+ error_type: row.error_type,
218
+ new_failures: row.new_failures,
219
+ total_occurrences: row.total_occurrences
220
+ }));
221
+ }
222
+ /**
223
+ * Get all new edge cases
224
+ */ async getAllNewEdgeCases() {
225
+ const sqlite = this.dbService.getAdapter('sqlite');
226
+ const query = 'SELECT * FROM edge_cases WHERE status = "new"';
227
+ const rows = await sqlite.raw(query);
228
+ if (!Array.isArray(rows)) {
229
+ return [];
230
+ }
231
+ return rows.map((row)=>this.mapRowToEdgeCase(row));
232
+ }
233
+ /**
234
+ * Group edge cases by skill and error type
235
+ */ groupEdgeCases(edgeCases) {
236
+ const groups = {};
237
+ for (const edgeCase of edgeCases){
238
+ const key = `${edgeCase.skill_id}:${edgeCase.error_type}`;
239
+ if (!groups[key]) {
240
+ groups[key] = [];
241
+ }
242
+ groups[key].push(edgeCase);
243
+ }
244
+ return groups;
245
+ }
246
+ /**
247
+ * Find common substrings in error messages
248
+ */ findCommonSubstrings(messages) {
249
+ if (messages.length < 2) {
250
+ return messages;
251
+ }
252
+ const substrings = new Set();
253
+ // Find substrings in first message
254
+ const firstMessage = messages[0];
255
+ for(let i = 0; i < firstMessage.length; i++){
256
+ for(let j = i + this.config.minSubstringLength; j <= firstMessage.length; j++){
257
+ const substring = firstMessage.substring(i, j);
258
+ // Check if substring appears in all messages
259
+ if (messages.every((msg)=>msg.includes(substring))) {
260
+ substrings.add(substring);
261
+ }
262
+ }
263
+ }
264
+ // Return longest substrings (remove substrings that are part of longer ones)
265
+ const sorted = Array.from(substrings).sort((a, b)=>b.length - a.length);
266
+ const result = [];
267
+ for (const substring of sorted){
268
+ const isSubstringOfExisting = result.some((existing)=>existing.includes(substring));
269
+ if (!isSubstringOfExisting) {
270
+ result.push(substring);
271
+ }
272
+ }
273
+ return result.slice(0, 5); // Top 5 common substrings
274
+ }
275
+ /**
276
+ * Find common input patterns
277
+ */ findCommonInputPatterns(edgeCases) {
278
+ const patterns = new Set();
279
+ // Extract input fields that appear in all cases
280
+ const inputObjects = edgeCases.map((ec)=>{
281
+ try {
282
+ return JSON.parse(ec.input_context);
283
+ } catch {
284
+ return {};
285
+ }
286
+ });
287
+ if (inputObjects.length === 0) {
288
+ return [];
289
+ }
290
+ // Find common keys
291
+ const firstKeys = Object.keys(inputObjects[0]);
292
+ for (const key of firstKeys){
293
+ if (inputObjects.every((obj)=>key in obj)) {
294
+ patterns.add(`common_field: ${key}`);
295
+ }
296
+ }
297
+ // Find common values
298
+ for (const key of firstKeys){
299
+ const values = inputObjects.map((obj)=>obj[key]).filter((v)=>v !== undefined);
300
+ const uniqueValues = new Set(values.map((v)=>JSON.stringify(v)));
301
+ if (uniqueValues.size === 1) {
302
+ patterns.add(`common_value: ${key}=${values[0]}`);
303
+ }
304
+ }
305
+ return Array.from(patterns).slice(0, 10); // Top 10 patterns
306
+ }
307
+ /**
308
+ * Calculate average severity
309
+ */ calculateAverageSeverity(edgeCases) {
310
+ const severityOrder = [
311
+ 'low',
312
+ 'medium',
313
+ 'high',
314
+ 'critical'
315
+ ];
316
+ const severityScores = edgeCases.map((ec)=>severityOrder.indexOf(ec.severity));
317
+ const avgScore = severityScores.reduce((a, b)=>a + b, 0) / severityScores.length;
318
+ const roundedScore = Math.round(avgScore);
319
+ return severityOrder[roundedScore];
320
+ }
321
+ /**
322
+ * Store pattern in database
323
+ */ async storePattern(pattern) {
324
+ const sqlite = this.dbService.getAdapter('sqlite');
325
+ const result = await sqlite.insert('failure_patterns', {
326
+ id: pattern.pattern_id,
327
+ skill_id: pattern.skill_id,
328
+ error_type: pattern.error_type,
329
+ common_errors: JSON.stringify(pattern.common_errors),
330
+ common_inputs: JSON.stringify(pattern.common_inputs),
331
+ occurrence_count: pattern.occurrence_count,
332
+ severity: pattern.severity,
333
+ suggested_fix: pattern.suggested_fix,
334
+ status: pattern.status,
335
+ first_detected: pattern.first_detected.toISOString(),
336
+ last_updated: pattern.last_updated.toISOString(),
337
+ metadata: JSON.stringify({})
338
+ });
339
+ if (!result.success) {
340
+ this.logger.warn('Failed to store pattern', {
341
+ pattern_id: pattern.pattern_id,
342
+ error: result.error
343
+ });
344
+ }
345
+ }
346
+ /**
347
+ * Map database row to EdgeCase object
348
+ */ mapRowToEdgeCase(row) {
349
+ return {
350
+ id: row.id,
351
+ skill_id: row.skill_id,
352
+ error_type: row.error_type,
353
+ severity: row.severity,
354
+ error_message: row.error_message,
355
+ stack_trace: row.stack_trace,
356
+ input_context: row.input_context,
357
+ output_context: row.output_context,
358
+ first_seen: new Date(row.first_seen),
359
+ last_seen: new Date(row.last_seen),
360
+ occurrence_count: row.occurrence_count,
361
+ status: row.status,
362
+ metadata: row.metadata ? JSON.parse(row.metadata) : {}
363
+ };
364
+ }
365
+ }
366
+
367
+ //# sourceMappingURL=edge-case-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/jobs/edge-case-analyzer.ts"],"sourcesContent":["/**\r\n * Edge Case Analyzer Job\r\n *\r\n * Analyzes edge cases to detect patterns and generate dashboard data.\r\n * Part of Task 1.5: MVP Edge Case Feedback Loop\r\n *\r\n * Features:\r\n * - Pattern detection across multiple edge cases\r\n * - Common error substring extraction\r\n * - Common input pattern detection\r\n * - Severity aggregation\r\n * - Dashboard data generation\r\n * - Scheduled analysis (cron job ready)\r\n *\r\n * Usage:\r\n * const analyzer = new EdgeCaseAnalyzer(dbService, logger);\r\n * const report = await analyzer.analyzeEdgeCases();\r\n * const patterns = await analyzer.generatePatterns();\r\n */\r\n\r\nimport { DatabaseService, OperationResult } from '../lib/database-service.js';\r\nimport { createLogger, Logger } from '../lib/logging.js';\r\nimport { createError, ErrorCode } from '../lib/errors.js';\r\nimport { generateShortCorrelationId } from '../lib/correlation.js';\r\nimport type { EdgeCase, ErrorCategory, Severity } from './edge-case-detector.js';\r\n\r\n/**\r\n * Analysis report\r\n */\r\nexport interface AnalysisReport {\r\n timestamp: Date;\r\n totalEdgeCases: number;\r\n newEdgeCases: number;\r\n patternsDetected: number;\r\n topFailures: TopFailure[];\r\n highSeverityFailures: HighSeverityFailure[];\r\n trends: FailureTrend[];\r\n}\r\n\r\n/**\r\n * Top failure record\r\n */\r\nexport interface TopFailure {\r\n skill_id: string;\r\n error_type: ErrorCategory;\r\n total_failures: number;\r\n max_severity: Severity;\r\n unique_cases: number;\r\n most_recent: Date;\r\n}\r\n\r\n/**\r\n * High severity failure record\r\n */\r\nexport interface HighSeverityFailure {\r\n id: string;\r\n skill_id: string;\r\n error_type: ErrorCategory;\r\n severity: Severity;\r\n error_message: string;\r\n occurrence_count: number;\r\n last_seen: Date;\r\n}\r\n\r\n/**\r\n * Failure trend record\r\n */\r\nexport interface FailureTrend {\r\n date: string;\r\n error_type: ErrorCategory;\r\n new_failures: number;\r\n total_occurrences: number;\r\n}\r\n\r\n/**\r\n * Failure pattern\r\n */\r\nexport interface FailurePattern {\r\n pattern_id: string;\r\n skill_id: string;\r\n error_type: ErrorCategory;\r\n occurrence_count: number;\r\n common_errors: string[];\r\n common_inputs: string[];\r\n severity: Severity;\r\n suggested_fix: string | null;\r\n status: 'detected' | 'analyzing' | 'fixed' | 'ignored';\r\n first_detected: Date;\r\n last_updated: Date;\r\n}\r\n\r\n/**\r\n * Analyzer configuration\r\n */\r\nexport interface AnalyzerConfig {\r\n /** Minimum occurrences to form a pattern (default: 3) */\r\n minPatternOccurrences?: number;\r\n /** Maximum patterns to detect per run (default: 50) */\r\n maxPatterns?: number;\r\n /** Minimum substring length for common errors (default: 10) */\r\n minSubstringLength?: number;\r\n}\r\n\r\n/**\r\n * Edge case analyzer service\r\n */\r\nexport class EdgeCaseAnalyzer {\r\n private logger: Logger;\r\n private config: Required<AnalyzerConfig>;\r\n\r\n constructor(\r\n private dbService: DatabaseService,\r\n logger?: Logger,\r\n config?: AnalyzerConfig\r\n ) {\r\n this.logger = logger || createLogger('edge-case-analyzer');\r\n\r\n // Set default config\r\n this.config = {\r\n minPatternOccurrences: config?.minPatternOccurrences ?? 3,\r\n maxPatterns: config?.maxPatterns ?? 50,\r\n minSubstringLength: config?.minSubstringLength ?? 10,\r\n };\r\n }\r\n\r\n /**\r\n * Analyze all edge cases and generate comprehensive report\r\n *\r\n * @returns Analysis report\r\n */\r\n async analyzeEdgeCases(): Promise<AnalysisReport> {\r\n this.logger.info('Starting edge case analysis');\r\n\r\n try {\r\n const sqlite = this.dbService.getAdapter('sqlite');\r\n\r\n // Get total edge cases\r\n const totalResult = await sqlite.raw<any[]>(\r\n 'SELECT COUNT(*) as count FROM edge_cases'\r\n );\r\n const totalEdgeCases = Array.isArray(totalResult) && totalResult[0]\r\n ? totalResult[0].count\r\n : 0;\r\n\r\n // Get new edge cases\r\n const newResult = await sqlite.raw<any[]>(\r\n 'SELECT COUNT(*) as count FROM edge_cases WHERE status = \"new\"'\r\n );\r\n const newEdgeCases = Array.isArray(newResult) && newResult[0]\r\n ? newResult[0].count\r\n : 0;\r\n\r\n // Get top failures\r\n const topFailures = await this.getTopFailures();\r\n\r\n // Get high severity failures\r\n const highSeverityFailures = await this.getHighSeverityFailures();\r\n\r\n // Get failure trends\r\n const trends = await this.getFailureTrends();\r\n\r\n // Generate patterns\r\n const patterns = await this.generatePatterns();\r\n const patternsDetected = patterns.length;\r\n\r\n const report: AnalysisReport = {\r\n timestamp: new Date(),\r\n totalEdgeCases,\r\n newEdgeCases,\r\n patternsDetected,\r\n topFailures,\r\n highSeverityFailures,\r\n trends,\r\n };\r\n\r\n this.logger.info('Edge case analysis complete', {\r\n totalEdgeCases,\r\n newEdgeCases,\r\n patternsDetected,\r\n });\r\n\r\n return report;\r\n } catch (error) {\r\n this.logger.error('Failed to analyze edge cases', error as Error);\r\n throw createError(\r\n ErrorCode.UNKNOWN_ERROR,\r\n 'Edge case analysis failed',\r\n undefined,\r\n error as Error\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Generate failure patterns from edge cases\r\n *\r\n * @returns Array of detected patterns\r\n */\r\n async generatePatterns(): Promise<FailurePattern[]> {\r\n this.logger.info('Generating failure patterns');\r\n\r\n try {\r\n const sqlite = this.dbService.getAdapter('sqlite');\r\n\r\n // 1. Query all edge cases\r\n const edgeCases = await this.getAllNewEdgeCases();\r\n\r\n if (edgeCases.length === 0) {\r\n this.logger.debug('No edge cases to analyze');\r\n return [];\r\n }\r\n\r\n // 2. Group by error type and skill\r\n const groups = this.groupEdgeCases(edgeCases);\r\n\r\n // 3. Find patterns\r\n const patterns: FailurePattern[] = [];\r\n\r\n for (const [key, cases] of Object.entries(groups)) {\r\n if (cases.length < this.config.minPatternOccurrences) {\r\n continue; // Need ≥minPatternOccurrences occurrences\r\n }\r\n\r\n const [skill_id, error_type] = key.split(':');\r\n\r\n // Extract common patterns\r\n const commonErrors = this.findCommonSubstrings(\r\n cases.map(c => c.error_message)\r\n );\r\n const commonInputs = this.findCommonInputPatterns(cases);\r\n const severity = this.calculateAverageSeverity(cases);\r\n\r\n const pattern: FailurePattern = {\r\n pattern_id: `pattern-${generateShortCorrelationId()}`,\r\n skill_id,\r\n error_type: error_type as ErrorCategory,\r\n occurrence_count: cases.length,\r\n common_errors: commonErrors,\r\n common_inputs: commonInputs,\r\n severity,\r\n suggested_fix: null, // Phase 2 feature\r\n status: 'detected',\r\n first_detected: new Date(),\r\n last_updated: new Date(),\r\n };\r\n\r\n patterns.push(pattern);\r\n\r\n // Store pattern in database\r\n await this.storePattern(pattern);\r\n }\r\n\r\n this.logger.info(`Generated ${patterns.length} patterns`);\r\n\r\n return patterns.slice(0, this.config.maxPatterns);\r\n } catch (error) {\r\n this.logger.error('Failed to generate patterns', error as Error);\r\n throw createError(\r\n ErrorCode.UNKNOWN_ERROR,\r\n 'Pattern generation failed',\r\n undefined,\r\n error as Error\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get top failures by skill and error type\r\n */\r\n private async getTopFailures(): Promise<TopFailure[]> {\r\n const sqlite = this.dbService.getAdapter('sqlite');\r\n\r\n const query = `\r\n SELECT\r\n skill_id,\r\n error_type,\r\n SUM(occurrence_count) as total_failures,\r\n MAX(severity) as max_severity,\r\n COUNT(*) as unique_cases,\r\n MAX(last_seen) as most_recent\r\n FROM edge_cases\r\n WHERE status = 'new'\r\n GROUP BY skill_id, error_type\r\n ORDER BY total_failures DESC\r\n LIMIT 10\r\n `;\r\n\r\n const rows = await sqlite.raw<any[]>(query);\r\n\r\n if (!Array.isArray(rows)) {\r\n return [];\r\n }\r\n\r\n return rows.map(row => ({\r\n skill_id: row.skill_id,\r\n error_type: row.error_type as ErrorCategory,\r\n total_failures: row.total_failures,\r\n max_severity: row.max_severity as Severity,\r\n unique_cases: row.unique_cases,\r\n most_recent: new Date(row.most_recent),\r\n }));\r\n }\r\n\r\n /**\r\n * Get high severity failures\r\n */\r\n private async getHighSeverityFailures(): Promise<HighSeverityFailure[]> {\r\n const sqlite = this.dbService.getAdapter('sqlite');\r\n\r\n const query = `\r\n SELECT\r\n id,\r\n skill_id,\r\n error_type,\r\n severity,\r\n error_message,\r\n occurrence_count,\r\n last_seen\r\n FROM edge_cases\r\n WHERE severity IN ('critical', 'high')\r\n AND status = 'new'\r\n ORDER BY last_seen DESC, occurrence_count DESC\r\n LIMIT 20\r\n `;\r\n\r\n const rows = await sqlite.raw<any[]>(query);\r\n\r\n if (!Array.isArray(rows)) {\r\n return [];\r\n }\r\n\r\n return rows.map(row => ({\r\n id: row.id,\r\n skill_id: row.skill_id,\r\n error_type: row.error_type as ErrorCategory,\r\n severity: row.severity as Severity,\r\n error_message: row.error_message,\r\n occurrence_count: row.occurrence_count,\r\n last_seen: new Date(row.last_seen),\r\n }));\r\n }\r\n\r\n /**\r\n * Get failure trends (last 30 days)\r\n */\r\n private async getFailureTrends(): Promise<FailureTrend[]> {\r\n const sqlite = this.dbService.getAdapter('sqlite');\r\n\r\n const query = `\r\n SELECT\r\n DATE(first_seen) as date,\r\n error_type,\r\n COUNT(*) as new_failures,\r\n SUM(occurrence_count) as total_occurrences\r\n FROM edge_cases\r\n WHERE first_seen >= datetime('now', '-30 days')\r\n GROUP BY DATE(first_seen), error_type\r\n ORDER BY date DESC\r\n `;\r\n\r\n const rows = await sqlite.raw<any[]>(query);\r\n\r\n if (!Array.isArray(rows)) {\r\n return [];\r\n }\r\n\r\n return rows.map(row => ({\r\n date: row.date,\r\n error_type: row.error_type as ErrorCategory,\r\n new_failures: row.new_failures,\r\n total_occurrences: row.total_occurrences,\r\n }));\r\n }\r\n\r\n /**\r\n * Get all new edge cases\r\n */\r\n private async getAllNewEdgeCases(): Promise<EdgeCase[]> {\r\n const sqlite = this.dbService.getAdapter('sqlite');\r\n\r\n const query = 'SELECT * FROM edge_cases WHERE status = \"new\"';\r\n const rows = await sqlite.raw<any[]>(query);\r\n\r\n if (!Array.isArray(rows)) {\r\n return [];\r\n }\r\n\r\n return rows.map(row => this.mapRowToEdgeCase(row));\r\n }\r\n\r\n /**\r\n * Group edge cases by skill and error type\r\n */\r\n private groupEdgeCases(edgeCases: EdgeCase[]): Record<string, EdgeCase[]> {\r\n const groups: Record<string, EdgeCase[]> = {};\r\n\r\n for (const edgeCase of edgeCases) {\r\n const key = `${edgeCase.skill_id}:${edgeCase.error_type}`;\r\n\r\n if (!groups[key]) {\r\n groups[key] = [];\r\n }\r\n\r\n groups[key].push(edgeCase);\r\n }\r\n\r\n return groups;\r\n }\r\n\r\n /**\r\n * Find common substrings in error messages\r\n */\r\n private findCommonSubstrings(messages: string[]): string[] {\r\n if (messages.length < 2) {\r\n return messages;\r\n }\r\n\r\n const substrings: Set<string> = new Set();\r\n\r\n // Find substrings in first message\r\n const firstMessage = messages[0];\r\n for (let i = 0; i < firstMessage.length; i++) {\r\n for (let j = i + this.config.minSubstringLength; j <= firstMessage.length; j++) {\r\n const substring = firstMessage.substring(i, j);\r\n\r\n // Check if substring appears in all messages\r\n if (messages.every(msg => msg.includes(substring))) {\r\n substrings.add(substring);\r\n }\r\n }\r\n }\r\n\r\n // Return longest substrings (remove substrings that are part of longer ones)\r\n const sorted = Array.from(substrings).sort((a, b) => b.length - a.length);\r\n const result: string[] = [];\r\n\r\n for (const substring of sorted) {\r\n const isSubstringOfExisting = result.some(existing => existing.includes(substring));\r\n if (!isSubstringOfExisting) {\r\n result.push(substring);\r\n }\r\n }\r\n\r\n return result.slice(0, 5); // Top 5 common substrings\r\n }\r\n\r\n /**\r\n * Find common input patterns\r\n */\r\n private findCommonInputPatterns(edgeCases: EdgeCase[]): string[] {\r\n const patterns: Set<string> = new Set();\r\n\r\n // Extract input fields that appear in all cases\r\n const inputObjects = edgeCases.map(ec => {\r\n try {\r\n return JSON.parse(ec.input_context);\r\n } catch {\r\n return {};\r\n }\r\n });\r\n\r\n if (inputObjects.length === 0) {\r\n return [];\r\n }\r\n\r\n // Find common keys\r\n const firstKeys = Object.keys(inputObjects[0]);\r\n for (const key of firstKeys) {\r\n if (inputObjects.every(obj => key in obj)) {\r\n patterns.add(`common_field: ${key}`);\r\n }\r\n }\r\n\r\n // Find common values\r\n for (const key of firstKeys) {\r\n const values = inputObjects.map(obj => obj[key]).filter(v => v !== undefined);\r\n const uniqueValues = new Set(values.map(v => JSON.stringify(v)));\r\n\r\n if (uniqueValues.size === 1) {\r\n patterns.add(`common_value: ${key}=${values[0]}`);\r\n }\r\n }\r\n\r\n return Array.from(patterns).slice(0, 10); // Top 10 patterns\r\n }\r\n\r\n /**\r\n * Calculate average severity\r\n */\r\n private calculateAverageSeverity(edgeCases: EdgeCase[]): Severity {\r\n const severityOrder = ['low', 'medium', 'high', 'critical'];\r\n const severityScores = edgeCases.map(ec =>\r\n severityOrder.indexOf(ec.severity)\r\n );\r\n\r\n const avgScore = severityScores.reduce((a, b) => a + b, 0) / severityScores.length;\r\n const roundedScore = Math.round(avgScore);\r\n\r\n return severityOrder[roundedScore] as Severity;\r\n }\r\n\r\n /**\r\n * Store pattern in database\r\n */\r\n private async storePattern(pattern: FailurePattern): Promise<void> {\r\n const sqlite = this.dbService.getAdapter('sqlite');\r\n\r\n const result: OperationResult = await sqlite.insert('failure_patterns', {\r\n id: pattern.pattern_id,\r\n skill_id: pattern.skill_id,\r\n error_type: pattern.error_type,\r\n common_errors: JSON.stringify(pattern.common_errors),\r\n common_inputs: JSON.stringify(pattern.common_inputs),\r\n occurrence_count: pattern.occurrence_count,\r\n severity: pattern.severity,\r\n suggested_fix: pattern.suggested_fix,\r\n status: pattern.status,\r\n first_detected: pattern.first_detected.toISOString(),\r\n last_updated: pattern.last_updated.toISOString(),\r\n metadata: JSON.stringify({}),\r\n });\r\n\r\n if (!result.success) {\r\n this.logger.warn('Failed to store pattern', {\r\n pattern_id: pattern.pattern_id,\r\n error: result.error,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Map database row to EdgeCase object\r\n */\r\n private mapRowToEdgeCase(row: any): EdgeCase {\r\n return {\r\n id: row.id,\r\n skill_id: row.skill_id,\r\n error_type: row.error_type as ErrorCategory,\r\n severity: row.severity as Severity,\r\n error_message: row.error_message,\r\n stack_trace: row.stack_trace,\r\n input_context: row.input_context,\r\n output_context: row.output_context,\r\n first_seen: new Date(row.first_seen),\r\n last_seen: new Date(row.last_seen),\r\n occurrence_count: row.occurrence_count,\r\n status: row.status as any,\r\n metadata: row.metadata ? JSON.parse(row.metadata) : {},\r\n };\r\n }\r\n}\r\n"],"names":["createLogger","createError","ErrorCode","generateShortCorrelationId","EdgeCaseAnalyzer","logger","config","dbService","minPatternOccurrences","maxPatterns","minSubstringLength","analyzeEdgeCases","info","sqlite","getAdapter","totalResult","raw","totalEdgeCases","Array","isArray","count","newResult","newEdgeCases","topFailures","getTopFailures","highSeverityFailures","getHighSeverityFailures","trends","getFailureTrends","patterns","generatePatterns","patternsDetected","length","report","timestamp","Date","error","UNKNOWN_ERROR","undefined","edgeCases","getAllNewEdgeCases","debug","groups","groupEdgeCases","key","cases","Object","entries","skill_id","error_type","split","commonErrors","findCommonSubstrings","map","c","error_message","commonInputs","findCommonInputPatterns","severity","calculateAverageSeverity","pattern","pattern_id","occurrence_count","common_errors","common_inputs","suggested_fix","status","first_detected","last_updated","push","storePattern","slice","query","rows","row","total_failures","max_severity","unique_cases","most_recent","id","last_seen","date","new_failures","total_occurrences","mapRowToEdgeCase","edgeCase","messages","substrings","Set","firstMessage","i","j","substring","every","msg","includes","add","sorted","from","sort","a","b","result","isSubstringOfExisting","some","existing","inputObjects","ec","JSON","parse","input_context","firstKeys","keys","obj","values","filter","v","uniqueValues","stringify","size","severityOrder","severityScores","indexOf","avgScore","reduce","roundedScore","Math","round","insert","toISOString","metadata","success","warn","stack_trace","output_context","first_seen"],"mappings":"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"}