claude-flow-novice 2.15.2 → 2.15.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (533) 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 +16 -2
  34. package/.claude/commands/switch-api.md +31 -10
  35. package/.claude/hooks/cfn-BACKUP_USAGE.md +243 -243
  36. package/.claude/hooks/cfn-invoke-security-validation.sh +69 -69
  37. package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
  38. package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +109 -78
  39. package/.claude/hooks/cfn-post-edit.config.json +44 -44
  40. package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
  41. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  42. package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  43. package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  44. package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  45. package/.claude/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
  46. package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  47. package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  48. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
  49. package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  50. package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  51. package/.claude/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
  52. package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  53. package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
  54. package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  55. package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
  56. package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  57. package/.claude/skills/cfn-redis-coordination/get-context.sh +145 -112
  58. package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  59. package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
  60. package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  61. package/.claude/skills/cfn-redis-coordination/redis-functions.sh +33 -0
  62. package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
  63. package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
  64. package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  65. package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  66. package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  67. package/.claude/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
  68. package/.claude/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
  69. package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  70. package/.claude/skills/cfn-transparency-middleware/test-integration.sh +161 -161
  71. package/.claude/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
  72. package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +107 -92
  73. package/.claude/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
  74. package/README.md +116 -475
  75. package/claude-assets/agents/cfn-dev-team/README.md +103 -0
  76. package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
  77. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
  78. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
  79. package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
  80. package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
  81. package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
  82. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
  83. package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
  84. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
  85. package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
  86. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
  87. package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
  88. package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
  89. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
  90. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
  91. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
  92. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
  93. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
  94. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
  95. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
  96. package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
  97. package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
  98. package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
  99. package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
  100. package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
  101. package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
  102. package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
  103. package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
  104. package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
  105. package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +828 -0
  106. package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
  107. package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
  108. package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
  109. package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
  110. package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
  111. package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
  112. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
  113. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
  114. package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
  115. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
  116. package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
  117. package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
  118. package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
  119. package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
  120. package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
  121. package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
  122. package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
  123. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
  124. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
  125. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
  126. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
  127. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
  128. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
  129. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
  130. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
  131. package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
  132. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
  133. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
  134. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
  135. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
  136. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
  137. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
  138. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
  139. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
  140. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
  141. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
  142. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
  143. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
  144. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
  145. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
  146. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
  147. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
  148. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
  149. package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
  150. package/claude-assets/commands/cfn-loop-cli.md +16 -2
  151. package/claude-assets/commands/switch-api.md +31 -10
  152. package/claude-assets/hooks/cfn-BACKUP_USAGE.md +243 -243
  153. package/claude-assets/hooks/cfn-invoke-security-validation.sh +69 -69
  154. package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
  155. package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +109 -78
  156. package/claude-assets/hooks/cfn-post-edit.config.json +44 -44
  157. package/claude-assets/hooks/cfn-post-execution/memory-cleanup.sh +19 -19
  158. package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
  159. package/claude-assets/hooks/cfn-pre-execution/memory-check.sh +19 -19
  160. package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
  161. package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
  162. package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +543 -572
  163. package/claude-assets/skills/agent-lifecycle/simple-audit.sh +57 -30
  164. package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
  165. package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
  166. package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
  167. package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
  168. package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
  169. package/claude-assets/skills/bootstrap/database-connection.md +464 -0
  170. package/claude-assets/skills/bootstrap/error-handling.md +580 -0
  171. package/claude-assets/skills/bootstrap/file-operations.md +699 -0
  172. package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
  173. package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
  174. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  175. package/claude-assets/skills/cfn-automatic-memory-persistence/persist-agent-output.sh +48 -48
  176. package/claude-assets/skills/cfn-automatic-memory-persistence/query-agent-history.sh +34 -34
  177. package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
  178. package/claude-assets/skills/cfn-deliverable-validation/confidence-calculator.sh +261 -261
  179. package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
  180. package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
  181. package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  182. package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  183. package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  184. package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
  185. package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
  186. package/claude-assets/skills/cfn-expert-update/update-expert.sh +345 -345
  187. package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
  188. package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
  189. package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
  190. package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
  191. package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
  192. package/claude-assets/skills/cfn-hybrid-routing/check-dependencies.sh +51 -51
  193. package/claude-assets/skills/cfn-intervention-detector/detect-intervention.sh +110 -110
  194. package/claude-assets/skills/cfn-intervention-orchestrator/execute-intervention.sh +58 -58
  195. package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
  196. package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
  197. package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
  198. package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
  199. package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
  200. package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  201. package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  202. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +184 -23
  203. package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  204. package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  205. package/claude-assets/skills/cfn-loop-validation/orchestrate-cfn-loop.sh +252 -252
  206. package/claude-assets/skills/cfn-loop2-output-processing/process-validator-output.sh +275 -275
  207. package/claude-assets/skills/cfn-memory-management/check-memory.sh +159 -159
  208. package/claude-assets/skills/cfn-memory-management/cleanup-memory.sh +196 -196
  209. package/claude-assets/skills/cfn-node-heap-sizer/task-mode-heap-limiter.sh +325 -325
  210. package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
  211. package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
  212. package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
  213. package/claude-assets/skills/cfn-playbook-auto-update/auto-update-playbook.sh +85 -85
  214. package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
  215. package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
  216. package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  217. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
  218. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  219. package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +74 -74
  220. package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  221. package/claude-assets/skills/cfn-redis-coordination/get-context.sh +145 -112
  222. package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  223. package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +3 -0
  224. package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  225. package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +33 -0
  226. package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
  227. package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
  228. package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  229. package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  230. package/claude-assets/skills/cfn-scope-simplifier/simplify-scope.sh +67 -67
  231. package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
  232. package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
  233. package/claude-assets/skills/cfn-specialist-injection/recommend-specialist.sh +56 -56
  234. package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  235. package/claude-assets/skills/cfn-standardized-error-handling/capture-agent-error.sh +86 -86
  236. package/claude-assets/skills/cfn-standardized-error-handling/test-error-handling.sh +165 -165
  237. package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
  238. package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
  239. package/claude-assets/skills/cfn-task-config-init/initialize-config.sh +264 -264
  240. package/claude-assets/skills/cfn-task-decomposition/task-decomposer.sh +278 -278
  241. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
  242. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
  243. package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
  244. package/claude-assets/skills/cfn-transparency-middleware/middleware-config.sh +28 -28
  245. package/claude-assets/skills/cfn-transparency-middleware/performance-benchmark.sh +78 -78
  246. package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  247. package/claude-assets/skills/cfn-transparency-middleware/test-integration.sh +161 -161
  248. package/claude-assets/skills/cfn-transparency-middleware/test-transparency-skill.sh +367 -367
  249. package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +107 -92
  250. package/claude-assets/skills/cfn-transparency-middleware/wrap-agent.sh +131 -131
  251. package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
  252. package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
  253. package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
  254. package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
  255. package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
  256. package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
  257. package/claude-assets/skills/cfn-utilities/test.sh +317 -0
  258. package/claude-assets/skills/docker-build/SKILL.md +96 -203
  259. package/claude-assets/skills/docker-build/build.sh +73 -73
  260. package/claude-assets/skills/integration/agent-handoff.sh +492 -0
  261. package/claude-assets/skills/integration/file-operations.sh +414 -0
  262. package/claude-assets/skills/json-validation/SKILL.md +431 -0
  263. package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
  264. package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
  265. package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
  266. package/claude-assets/skills/workflow-codification/APPROVAL_WORKFLOW.md +806 -0
  267. package/claude-assets/skills/workflow-codification/COST_TRACKING.md +637 -0
  268. package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
  269. package/claude-assets/skills/workflow-codification/EDGE_CASE_TRACKING.md +404 -0
  270. package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
  271. package/claude-assets/skills/workflow-codification/README_PHASE4.md +457 -0
  272. package/claude-assets/skills/workflow-codification/SKILL.md +110 -0
  273. package/claude-assets/skills/workflow-codification/analyze-patterns.sh +899 -0
  274. package/claude-assets/skills/workflow-codification/approval-workflow.sh +514 -0
  275. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
  276. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
  277. package/claude-assets/skills/workflow-codification/generate-skill-update.sh +525 -0
  278. package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
  279. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
  280. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
  281. package/claude-assets/skills/workflow-codification/review-skill.sh +643 -0
  282. package/claude-assets/skills/workflow-codification/templates/email-notification.txt +114 -0
  283. package/claude-assets/skills/workflow-codification/templates/slack-notification.md +85 -0
  284. package/claude-assets/skills/workflow-codification/test-integration.sh +296 -0
  285. package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
  286. package/claude-assets/skills/workflow-codification/track-cost-savings.sh +486 -0
  287. package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
  288. package/claude-assets/skills/workflow-codification/track-edge-case.sh +290 -0
  289. package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
  290. package/dist/ace/ace-curator.js +10 -2
  291. package/dist/ace/ace-curator.js.map +1 -1
  292. package/dist/ace/ace-generator.js +4 -0
  293. package/dist/ace/ace-generator.js.map +1 -1
  294. package/dist/ace/ace-reflector.js +1 -1
  295. package/dist/ace/ace-reflector.js.map +1 -1
  296. package/dist/ace/context-injection.js +24 -2
  297. package/dist/ace/context-injection.js.map +1 -1
  298. package/dist/agents/agent-loader.js +146 -165
  299. package/dist/agents/agent-loader.js.map +1 -1
  300. package/dist/agents/task-agent-integration.js +1 -1
  301. package/dist/agents/task-agent-integration.js.map +1 -1
  302. package/dist/api/health-endpoints.js +390 -0
  303. package/dist/api/health-endpoints.js.map +1 -0
  304. package/dist/cli/agent-executor.js +4 -1
  305. package/dist/cli/agent-executor.js.map +1 -1
  306. package/dist/cli/agent-prompt-builder.js +89 -1
  307. package/dist/cli/agent-prompt-builder.js.map +1 -1
  308. package/dist/cli/agent-spawn.js +130 -37
  309. package/dist/cli/agent-spawn.js.map +1 -1
  310. package/dist/cli/config-manager.js +91 -109
  311. package/dist/cli/config-manager.js.map +1 -1
  312. package/dist/cli/skill-cache-validator.js +412 -0
  313. package/dist/cli/skill-cache-validator.js.map +1 -0
  314. package/dist/cli/skill-cli.js +991 -0
  315. package/dist/cli/skill-cli.js.map +1 -0
  316. package/dist/cli/skill-execution-logger.js +284 -0
  317. package/dist/cli/skill-execution-logger.js.map +1 -0
  318. package/dist/cli/skill-loader.js +457 -0
  319. package/dist/cli/skill-loader.js.map +1 -0
  320. package/dist/coordination/event-bus.js +2 -2
  321. package/dist/coordination/event-bus.js.map +1 -1
  322. package/dist/coordination/fleet-manager.js +1 -1
  323. package/dist/coordination/fleet-manager.js.map +1 -1
  324. package/dist/coordination/index.js +23 -9
  325. package/dist/coordination/index.js.map +1 -1
  326. package/dist/coordination/types/fleet-manager.types.js.map +1 -1
  327. package/dist/db/migration-manager.js +483 -0
  328. package/dist/db/migration-manager.js.map +1 -0
  329. package/dist/db/skills-query.js +535 -0
  330. package/dist/db/skills-query.js.map +1 -0
  331. package/dist/integration/DatabaseHandoff.js +507 -0
  332. package/dist/integration/DatabaseHandoff.js.map +1 -0
  333. package/dist/integration/StandardAdapter.js +291 -0
  334. package/dist/integration/StandardAdapter.js.map +1 -0
  335. package/dist/jobs/edge-case-analyzer.js +367 -0
  336. package/dist/jobs/edge-case-analyzer.js.map +1 -0
  337. package/dist/jobs/promotion-sla-enforcer.js +288 -0
  338. package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
  339. package/dist/lib/agent-output-parser.js +518 -0
  340. package/dist/lib/agent-output-parser.js.map +1 -0
  341. package/dist/lib/agent-output-validator.js +950 -0
  342. package/dist/lib/agent-output-validator.js.map +1 -0
  343. package/dist/lib/agent-workspace.js +281 -0
  344. package/dist/lib/agent-workspace.js.map +1 -0
  345. package/dist/lib/artifact-registry.js +443 -0
  346. package/dist/lib/artifact-registry.js.map +1 -0
  347. package/dist/lib/atomic-file-writer.js +377 -0
  348. package/dist/lib/atomic-file-writer.js.map +1 -0
  349. package/dist/lib/backup-manager.js +779 -0
  350. package/dist/lib/backup-manager.js.map +1 -0
  351. package/dist/lib/checkpoint-manager.js +837 -0
  352. package/dist/lib/checkpoint-manager.js.map +1 -0
  353. package/dist/lib/circuit-breaker.js +340 -0
  354. package/dist/lib/circuit-breaker.js.map +1 -0
  355. package/dist/lib/completion-signal-handler.js +243 -0
  356. package/dist/lib/completion-signal-handler.js.map +1 -0
  357. package/dist/lib/config-manager.js +312 -0
  358. package/dist/lib/config-manager.js.map +1 -0
  359. package/dist/lib/config-migrator.js +386 -0
  360. package/dist/lib/config-migrator.js.map +1 -0
  361. package/dist/lib/config-validator.js +687 -0
  362. package/dist/lib/config-validator.js.map +1 -0
  363. package/dist/lib/correlation-cache.js +311 -0
  364. package/dist/lib/correlation-cache.js.map +1 -0
  365. package/dist/lib/correlation.js +263 -0
  366. package/dist/lib/correlation.js.map +1 -0
  367. package/dist/lib/database-service/connection-pool-manager.js +520 -0
  368. package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
  369. package/dist/lib/database-service/correlation.js +329 -0
  370. package/dist/lib/database-service/correlation.js.map +1 -0
  371. package/dist/lib/database-service/errors.js +120 -0
  372. package/dist/lib/database-service/errors.js.map +1 -0
  373. package/dist/lib/database-service/index.js +168 -0
  374. package/dist/lib/database-service/index.js.map +1 -0
  375. package/dist/lib/database-service/postgres-adapter.js +526 -0
  376. package/dist/lib/database-service/postgres-adapter.js.map +1 -0
  377. package/dist/lib/database-service/redis-adapter.js +360 -0
  378. package/dist/lib/database-service/redis-adapter.js.map +1 -0
  379. package/dist/lib/database-service/sqlite-adapter.js +544 -0
  380. package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
  381. package/dist/lib/database-service/transaction-manager.js +773 -0
  382. package/dist/lib/database-service/transaction-manager.js.map +1 -0
  383. package/dist/lib/database-service/types.js +23 -0
  384. package/dist/lib/database-service/types.js.map +1 -0
  385. package/dist/lib/deadlock-resolver.js +292 -0
  386. package/dist/lib/deadlock-resolver.js.map +1 -0
  387. package/dist/lib/distributed-lock.js +451 -0
  388. package/dist/lib/distributed-lock.js.map +1 -0
  389. package/dist/lib/edge-case-deduplicator.js +227 -0
  390. package/dist/lib/edge-case-deduplicator.js.map +1 -0
  391. package/dist/lib/encryption-manager.js +322 -0
  392. package/dist/lib/encryption-manager.js.map +1 -0
  393. package/dist/lib/error-aggregator.js +234 -0
  394. package/dist/lib/error-aggregator.js.map +1 -0
  395. package/dist/lib/errors.js +287 -0
  396. package/dist/lib/errors.js.map +1 -0
  397. package/dist/lib/file-lock-manager.js +578 -0
  398. package/dist/lib/file-lock-manager.js.map +1 -0
  399. package/dist/lib/file-operations.js +367 -0
  400. package/dist/lib/file-operations.js.map +1 -0
  401. package/dist/lib/idempotent-write.js +237 -0
  402. package/dist/lib/idempotent-write.js.map +1 -0
  403. package/dist/lib/integration-schema-validator.js +522 -0
  404. package/dist/lib/integration-schema-validator.js.map +1 -0
  405. package/dist/lib/lock-health-monitor.js +298 -0
  406. package/dist/lib/lock-health-monitor.js.map +1 -0
  407. package/dist/lib/log-shipper.js +422 -0
  408. package/dist/lib/log-shipper.js.map +1 -0
  409. package/dist/lib/logging.js +146 -0
  410. package/dist/lib/logging.js.map +1 -0
  411. package/dist/lib/message-deduplicator.js +439 -0
  412. package/dist/lib/message-deduplicator.js.map +1 -0
  413. package/dist/lib/multi-system-query.js +604 -0
  414. package/dist/lib/multi-system-query.js.map +1 -0
  415. package/dist/lib/orphan-detector.js +332 -0
  416. package/dist/lib/orphan-detector.js.map +1 -0
  417. package/dist/lib/password-generator.js +166 -0
  418. package/dist/lib/password-generator.js.map +1 -0
  419. package/dist/lib/path-validator.js +429 -0
  420. package/dist/lib/path-validator.js.map +1 -0
  421. package/dist/lib/query-translator.js +905 -0
  422. package/dist/lib/query-translator.js.map +1 -0
  423. package/dist/lib/queue-recovery.js +469 -0
  424. package/dist/lib/queue-recovery.js.map +1 -0
  425. package/dist/lib/redis-queue-manager.js +512 -0
  426. package/dist/lib/redis-queue-manager.js.map +1 -0
  427. package/dist/lib/reflection-archiver.js +272 -0
  428. package/dist/lib/reflection-archiver.js.map +1 -0
  429. package/dist/lib/retry-manager.js +453 -0
  430. package/dist/lib/retry-manager.js.map +1 -0
  431. package/dist/lib/retry.js +262 -0
  432. package/dist/lib/retry.js.map +1 -0
  433. package/dist/lib/schema-transform.js +695 -0
  434. package/dist/lib/schema-transform.js.map +1 -0
  435. package/dist/lib/schema-validator.js +491 -0
  436. package/dist/lib/schema-validator.js.map +1 -0
  437. package/dist/lib/skill-cache.js +297 -0
  438. package/dist/lib/skill-cache.js.map +1 -0
  439. package/dist/lib/skill-content-manager.js +337 -0
  440. package/dist/lib/skill-content-manager.js.map +1 -0
  441. package/dist/lib/skill-frontmatter-parser.js +237 -0
  442. package/dist/lib/skill-frontmatter-parser.js.map +1 -0
  443. package/dist/lib/skill-git-integration.js +275 -0
  444. package/dist/lib/skill-git-integration.js.map +1 -0
  445. package/dist/lib/skill-markdown-validator.js +396 -0
  446. package/dist/lib/skill-markdown-validator.js.map +1 -0
  447. package/dist/lib/skill-output-parser.js +312 -0
  448. package/dist/lib/skill-output-parser.js.map +1 -0
  449. package/dist/lib/unified-query-api.js +467 -0
  450. package/dist/lib/unified-query-api.js.map +1 -0
  451. package/dist/middleware/auth-middleware.js +350 -0
  452. package/dist/middleware/auth-middleware.js.map +1 -0
  453. package/dist/middleware/schema-validation.js +347 -0
  454. package/dist/middleware/schema-validation.js.map +1 -0
  455. package/dist/providers/anthropic-provider.js +1 -1
  456. package/dist/providers/anthropic-provider.js.map +1 -1
  457. package/dist/providers/provider-factory.js +2 -2
  458. package/dist/providers/provider-factory.js.map +1 -1
  459. package/dist/services/edge-case-analyzer.js +321 -0
  460. package/dist/services/edge-case-analyzer.js.map +1 -0
  461. package/dist/services/edge-case-deduplicator.js +266 -0
  462. package/dist/services/edge-case-deduplicator.js.map +1 -0
  463. package/dist/services/edge-case-detector.js +337 -0
  464. package/dist/services/edge-case-detector.js.map +1 -0
  465. package/dist/services/edge-case-tracker.js +547 -0
  466. package/dist/services/edge-case-tracker.js.map +1 -0
  467. package/dist/services/health-check-system.js +586 -0
  468. package/dist/services/health-check-system.js.map +1 -0
  469. package/dist/services/metrics-logger.js +412 -0
  470. package/dist/services/metrics-logger.js.map +1 -0
  471. package/dist/services/patch-generator.js +378 -0
  472. package/dist/services/patch-generator.js.map +1 -0
  473. package/dist/services/patch-validator.js +337 -0
  474. package/dist/services/patch-validator.js.map +1 -0
  475. package/dist/services/performance-monitor.js +811 -0
  476. package/dist/services/performance-monitor.js.map +1 -0
  477. package/dist/services/promotion-pipeline.js +918 -0
  478. package/dist/services/promotion-pipeline.js.map +1 -0
  479. package/dist/services/promotion-validator.js +394 -0
  480. package/dist/services/promotion-validator.js.map +1 -0
  481. package/dist/services/reflection-logger.js +388 -0
  482. package/dist/services/reflection-logger.js.map +1 -0
  483. package/dist/services/skill-deployment.js +472 -0
  484. package/dist/services/skill-deployment.js.map +1 -0
  485. package/dist/services/skill-loader.js +427 -0
  486. package/dist/services/skill-loader.js.map +1 -0
  487. package/dist/services/skill-promotion.js +372 -0
  488. package/dist/services/skill-promotion.js.map +1 -0
  489. package/dist/services/skill-validator.js +454 -0
  490. package/dist/services/skill-validator.js.map +1 -0
  491. package/dist/services/skill-versioning.js +244 -0
  492. package/dist/services/skill-versioning.js.map +1 -0
  493. package/dist/services/workspace-supervisor.js +597 -0
  494. package/dist/services/workspace-supervisor.js.map +1 -0
  495. package/dist/types/agent-output.js +44 -0
  496. package/dist/types/agent-output.js.map +1 -0
  497. package/dist/types/config.js +28 -0
  498. package/dist/types/config.js.map +1 -0
  499. package/dist/types/edge-case.js +45 -0
  500. package/dist/types/edge-case.js.map +1 -0
  501. package/package.json +201 -176
  502. package/readme/README.md +19 -4
  503. package/scripts/artifact-cleanup.sh +392 -0
  504. package/scripts/backup-cleanup.sh +627 -0
  505. package/scripts/cleanup-workspaces.sh +412 -0
  506. package/scripts/cleanup-yaml-configs.sh +141 -0
  507. package/scripts/deploy-approved-skills.sh +263 -0
  508. package/scripts/deploy-production.sh +355 -355
  509. package/scripts/docker-playwright-fix.sh +311 -311
  510. package/scripts/docker-rebuild-all-agents.sh +127 -127
  511. package/scripts/health-check.sh +447 -0
  512. package/scripts/log-aggregator.sh +554 -0
  513. package/scripts/log-monitor.sh +629 -0
  514. package/scripts/manage-agent-workspaces.sh +434 -0
  515. package/scripts/memory-leak-prevention.sh +305 -305
  516. package/scripts/migrate-artifacts.sh +563 -0
  517. package/scripts/migrate-schema.sh +533 -0
  518. package/scripts/migrate-yaml-to-json.sh +465 -0
  519. package/scripts/promote-staged-skills.sh +423 -0
  520. package/scripts/run-marketing-tests.sh +42 -42
  521. package/scripts/update_paths.sh +46 -46
  522. package/scripts/verify-no-secrets.sh +88 -35
  523. package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  524. package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  525. package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  526. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  527. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
  528. package/README.md.backup_before_replace +0 -781
  529. package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  530. package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  531. package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  532. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  533. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/database-service/index.ts"],"sourcesContent":["/**\r\n * Database Service - Main Entry Point\r\n *\r\n * Unified database abstraction layer for Redis, SQLite, and PostgreSQL.\r\n * Part of Task 0.4: Database Query Abstraction Layer (MVP)\r\n *\r\n * @example\r\n * ```typescript\r\n * const dbService = new DatabaseService({\r\n * redis: { type: 'redis', host: 'localhost', port: 6379 },\r\n * sqlite: { type: 'sqlite', database: './data.db' },\r\n * postgres: { type: 'postgres', connectionString: 'postgresql://...' }\r\n * });\r\n *\r\n * await dbService.connect();\r\n *\r\n * // Get data by correlation key across all databases\r\n * const data = await dbService.getByCorrelationKey({\r\n * type: 'task',\r\n * id: 'abc123',\r\n * entity: 'agent'\r\n * });\r\n * ```\r\n */\r\n\r\nimport {\r\n IDatabaseService,\r\n IDatabaseAdapter,\r\n DatabaseConfig,\r\n CrossDatabaseResult,\r\n CorrelationKey,\r\n} from './types.js';\r\nimport { RedisAdapter } from './redis-adapter.js';\r\nimport { SQLiteAdapter } from './sqlite-adapter.js';\r\nimport { PostgresAdapter } from './postgres-adapter.js';\r\nimport { TransactionManager } from './transaction-manager.js';\r\nimport {\r\n buildCorrelationKey,\r\n parseCorrelationKey,\r\n buildTaskKey,\r\n buildAgentKey,\r\n buildSkillKey,\r\n buildExecutionKey,\r\n} from './correlation.js';\r\nimport { DatabaseErrorCode, createDatabaseError } from './errors.js';\r\n\r\nexport interface DatabaseServiceConfig {\r\n redis?: DatabaseConfig;\r\n sqlite?: DatabaseConfig;\r\n postgres?: DatabaseConfig;\r\n}\r\n\r\nexport class DatabaseService implements IDatabaseService {\r\n private adapters: Map<string, IDatabaseAdapter> = new Map();\r\n private transactionManager: TransactionManager;\r\n private config: DatabaseServiceConfig;\r\n\r\n constructor(config: DatabaseServiceConfig) {\r\n this.config = config;\r\n this.transactionManager = new TransactionManager();\r\n\r\n // Initialize adapters\r\n if (config.redis) {\r\n this.adapters.set('redis', new RedisAdapter(config.redis));\r\n }\r\n\r\n if (config.sqlite) {\r\n this.adapters.set('sqlite', new SQLiteAdapter(config.sqlite));\r\n }\r\n\r\n if (config.postgres) {\r\n this.adapters.set('postgres', new PostgresAdapter(config.postgres));\r\n }\r\n }\r\n\r\n /**\r\n * Connect to all configured databases\r\n */\r\n async connect(): Promise<void> {\r\n const promises = Array.from(this.adapters.values()).map(adapter => adapter.connect());\r\n await Promise.all(promises);\r\n }\r\n\r\n /**\r\n * Disconnect from all databases\r\n */\r\n async disconnect(): Promise<void> {\r\n const promises = Array.from(this.adapters.values()).map(adapter => adapter.disconnect());\r\n await Promise.all(promises);\r\n }\r\n\r\n /**\r\n * Get adapter for specific database\r\n */\r\n getAdapter(type: 'redis' | 'sqlite' | 'postgres'): IDatabaseAdapter {\r\n const adapter = this.adapters.get(type);\r\n\r\n if (!adapter) {\r\n throw createDatabaseError(\r\n DatabaseErrorCode.CONNECTION_FAILED,\r\n `Database adapter not configured: ${type}`,\r\n undefined,\r\n { type }\r\n );\r\n }\r\n\r\n return adapter;\r\n }\r\n\r\n /**\r\n * Get record by correlation key across all databases\r\n */\r\n async getByCorrelationKey<T = any>(key: CorrelationKey): Promise<CrossDatabaseResult<T>> {\r\n const correlationKeyString = buildCorrelationKey(key);\r\n\r\n const result: CrossDatabaseResult<T> = {\r\n correlationKey: correlationKeyString,\r\n timestamp: new Date(),\r\n };\r\n\r\n // Query each database in parallel\r\n const promises: Promise<void>[] = [];\r\n\r\n if (this.adapters.has('redis')) {\r\n promises.push(\r\n this.adapters.get('redis')!.get<T>(correlationKeyString)\r\n .then(data => { if (data !== null && data !== undefined) result.redis = data; })\r\n .catch(err => console.warn('Redis lookup failed:', err))\r\n );\r\n }\r\n\r\n if (this.adapters.has('sqlite')) {\r\n promises.push(\r\n this.adapters.get('sqlite')!.get<T>(correlationKeyString)\r\n .then(data => { if (data !== null && data !== undefined) result.sqlite = data; })\r\n .catch(err => console.warn('SQLite lookup failed:', err))\r\n );\r\n }\r\n\r\n if (this.adapters.has('postgres')) {\r\n promises.push(\r\n this.adapters.get('postgres')!.get<T>(correlationKeyString)\r\n .then(data => { if (data !== null && data !== undefined) result.postgres = data; })\r\n .catch(err => console.warn('PostgreSQL lookup failed:', err))\r\n );\r\n }\r\n\r\n await Promise.all(promises);\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Execute cross-database transaction\r\n */\r\n async executeTransaction<T = any>(\r\n operations: Array<{\r\n database: 'redis' | 'sqlite' | 'postgres';\r\n operation: (adapter: IDatabaseAdapter) => Promise<T>;\r\n }>\r\n ): Promise<T[]> {\r\n const adapters = operations.map(op => this.getAdapter(op.database));\r\n const ops = operations.map(op => op.operation);\r\n\r\n return this.transactionManager.executeTransaction(adapters, ops);\r\n }\r\n\r\n /**\r\n * Build correlation key\r\n */\r\n buildCorrelationKey(key: CorrelationKey): string {\r\n return buildCorrelationKey(key);\r\n }\r\n\r\n /**\r\n * Parse correlation key\r\n */\r\n parseCorrelationKey(key: string): CorrelationKey | null {\r\n return parseCorrelationKey(key);\r\n }\r\n\r\n /**\r\n * Get transaction manager\r\n */\r\n getTransactionManager(): TransactionManager {\r\n return this.transactionManager;\r\n }\r\n\r\n /**\r\n * Check if all configured databases are connected\r\n */\r\n isConnected(): boolean {\r\n return Array.from(this.adapters.values()).every(adapter => adapter.isConnected());\r\n }\r\n\r\n /**\r\n * Get database statistics including connection pool metrics\r\n */\r\n getStats() {\r\n const poolStats: any = {};\r\n\r\n // Get pool stats from each adapter\r\n if (this.adapters.has('redis')) {\r\n const adapter = this.adapters.get('redis') as any;\r\n poolStats.redis = adapter.getPoolStats?.();\r\n }\r\n\r\n if (this.adapters.has('sqlite')) {\r\n const adapter = this.adapters.get('sqlite') as any;\r\n poolStats.sqlite = adapter.getPoolStats?.();\r\n }\r\n\r\n if (this.adapters.has('postgres')) {\r\n const adapter = this.adapters.get('postgres') as any;\r\n poolStats.postgres = adapter.getPoolStats?.();\r\n }\r\n\r\n return {\r\n adapters: {\r\n redis: this.adapters.has('redis') && this.adapters.get('redis')!.isConnected(),\r\n sqlite: this.adapters.has('sqlite') && this.adapters.get('sqlite')!.isConnected(),\r\n postgres: this.adapters.has('postgres') && this.adapters.get('postgres')!.isConnected(),\r\n },\r\n transactions: {\r\n active: this.transactionManager.getActiveCount(),\r\n },\r\n connectionPools: poolStats,\r\n };\r\n }\r\n}\r\n\r\n// Re-export types and utilities\r\nexport * from './types.js';\r\nexport * from './errors.js';\r\nexport * from './correlation.js';\r\nexport { RedisAdapter } from './redis-adapter.js';\r\nexport { SQLiteAdapter } from './sqlite-adapter.js';\r\nexport { PostgresAdapter } from './postgres-adapter.js';\r\nexport { TransactionManager } from './transaction-manager.js';\r\nexport { ConnectionPoolManager } from './connection-pool-manager.js';\r\n\r\n// Re-export correlation utilities\r\nexport {\r\n buildTaskKey,\r\n buildAgentKey,\r\n buildSkillKey,\r\n buildExecutionKey,\r\n};\r\n"],"names":["RedisAdapter","SQLiteAdapter","PostgresAdapter","TransactionManager","buildCorrelationKey","parseCorrelationKey","buildTaskKey","buildAgentKey","buildSkillKey","buildExecutionKey","DatabaseErrorCode","createDatabaseError","DatabaseService","adapters","Map","transactionManager","config","redis","set","sqlite","postgres","connect","promises","Array","from","values","map","adapter","Promise","all","disconnect","getAdapter","type","get","CONNECTION_FAILED","undefined","getByCorrelationKey","key","correlationKeyString","result","correlationKey","timestamp","Date","has","push","then","data","catch","err","console","warn","executeTransaction","operations","op","database","ops","operation","getTransactionManager","isConnected","every","getStats","poolStats","getPoolStats","transactions","active","getActiveCount","connectionPools","ConnectionPoolManager"],"mappings":"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"}
@@ -0,0 +1,526 @@
1
+ /**
2
+ * PostgreSQL Database Adapter
3
+ *
4
+ * Implements IDatabaseAdapter for PostgreSQL with connection pooling and parameterized queries.
5
+ * Part of Task 0.4: Database Query Abstraction Layer (MVP)
6
+ *
7
+ * SECURITY: Requires password authentication and uses parameterized queries for SQL injection prevention
8
+ */ import { Pool } from 'pg';
9
+ import { DatabaseErrorCode, createDatabaseError, createSuccessResult, createFailedResult, mapPostgresError } from './errors.js';
10
+ import { withDatabaseRetry } from '../retry-manager.js';
11
+ import { v4 as uuidv4 } from 'uuid';
12
+ export class PostgresAdapter {
13
+ pool = null;
14
+ config;
15
+ connected = false;
16
+ transactions = new Map();
17
+ errorAggregator;
18
+ correlationId;
19
+ constructor(config, errorAggregator){
20
+ this.config = config;
21
+ this.errorAggregator = errorAggregator;
22
+ this.correlationId = uuidv4();
23
+ }
24
+ getType() {
25
+ return 'postgres';
26
+ }
27
+ /**
28
+ * Track error with error aggregator
29
+ * @private
30
+ */ trackError(error, operation, context) {
31
+ if (this.errorAggregator) {
32
+ const dbError = error.code ? error : createDatabaseError(DatabaseErrorCode.QUERY_FAILED, `PostgreSQL ${operation} failed`, error instanceof Error ? error : new Error(String(error)), context);
33
+ this.errorAggregator.addError('postgres', dbError, {
34
+ ...context,
35
+ operation,
36
+ correlationId: this.correlationId
37
+ });
38
+ }
39
+ }
40
+ /**
41
+ * Record successful operation with error aggregator
42
+ * @private
43
+ */ recordSuccess() {
44
+ if (this.errorAggregator) {
45
+ this.errorAggregator.recordSuccess('postgres');
46
+ }
47
+ }
48
+ async connect() {
49
+ // SECURITY: Validate password is provided for authentication
50
+ if (!this.config.password && !this.config.connectionString) {
51
+ throw createDatabaseError(DatabaseErrorCode.CONNECTION_FAILED, 'PostgreSQL password is required. Set POSTGRES_PASSWORD environment variable.', undefined, {
52
+ reason: 'missing_authentication'
53
+ });
54
+ }
55
+ // Wrap connection with retry logic for transient failures
56
+ await withDatabaseRetry(async ()=>{
57
+ try {
58
+ const poolConfig = {
59
+ host: this.config.host,
60
+ port: this.config.port,
61
+ database: this.config.database,
62
+ user: this.config.username,
63
+ password: this.config.password,
64
+ max: this.config.poolSize || 10,
65
+ idleTimeoutMillis: this.config.timeout || 30000,
66
+ connectionTimeoutMillis: 5000
67
+ };
68
+ // Use connectionString if provided, otherwise build from components
69
+ if (this.config.connectionString) {
70
+ poolConfig.connectionString = this.config.connectionString;
71
+ }
72
+ this.pool = new Pool(poolConfig);
73
+ // Test connection
74
+ const client = await this.pool.connect();
75
+ client.release();
76
+ this.connected = true;
77
+ this.recordSuccess();
78
+ } catch (err) {
79
+ const error = createDatabaseError(DatabaseErrorCode.CONNECTION_FAILED, 'Failed to connect to PostgreSQL', err instanceof Error ? err : new Error(String(err)), {
80
+ config: this.config,
81
+ correlationId: this.correlationId
82
+ });
83
+ this.trackError(error, 'connect');
84
+ throw error;
85
+ }
86
+ });
87
+ }
88
+ async disconnect() {
89
+ if (this.pool) {
90
+ await this.pool.end();
91
+ this.pool = null;
92
+ this.connected = false;
93
+ }
94
+ }
95
+ isConnected() {
96
+ return this.connected && this.pool !== null;
97
+ }
98
+ async get(key, transactionId) {
99
+ this.ensureConnected();
100
+ try {
101
+ // Parse correlation key format: table:id or table:id:entity:subtype
102
+ // For SQL adapters, we use only table:id for lookup
103
+ const parts = key.split(':');
104
+ const table = parts[0];
105
+ const id = parts.slice(1).join(':'); // Rejoin remaining parts as ID
106
+ if (!table || !id) {
107
+ throw new Error('Invalid key format. Expected "table:id" or "table:id:entity:subtype"');
108
+ }
109
+ const query = `SELECT * FROM ${this.sanitizeIdentifier(table)} WHERE id = $1`;
110
+ const client = this.getQueryClient(transactionId);
111
+ const result = await client.query(query, [
112
+ id
113
+ ]);
114
+ this.recordSuccess();
115
+ return result.rows.length > 0 ? result.rows[0] : null;
116
+ } catch (err) {
117
+ const errorCode = mapPostgresError(err);
118
+ const error = createDatabaseError(errorCode, `Failed to get record: ${key}`, err instanceof Error ? err : new Error(String(err)), {
119
+ key,
120
+ correlationId: this.correlationId
121
+ });
122
+ this.trackError(error, 'get', {
123
+ key
124
+ });
125
+ throw error;
126
+ }
127
+ }
128
+ async list(table, options, transactionId) {
129
+ this.ensureConnected();
130
+ try {
131
+ let query = `SELECT * FROM ${this.sanitizeIdentifier(table)}`;
132
+ const params = [];
133
+ let paramIndex = 1;
134
+ // Apply filters
135
+ if (options?.filters && options.filters.length > 0) {
136
+ const whereClauses = options.filters.map((filter)=>{
137
+ return this.buildWhereClause(filter, params);
138
+ });
139
+ query += ` WHERE ${whereClauses.join(' AND ')}`;
140
+ }
141
+ // Apply ordering
142
+ if (options?.orderBy) {
143
+ const order = options.order || 'asc';
144
+ query += ` ORDER BY ${this.sanitizeIdentifier(String(options.orderBy))} ${order.toUpperCase()}`;
145
+ }
146
+ // Apply limit and offset
147
+ if (options?.limit) {
148
+ query += ` LIMIT $${paramIndex++}`;
149
+ params.push(options.limit);
150
+ }
151
+ if (options?.offset) {
152
+ query += ` OFFSET $${paramIndex++}`;
153
+ params.push(options.offset);
154
+ }
155
+ const client = this.getQueryClient(transactionId);
156
+ const result = await client.query(query, params);
157
+ this.recordSuccess();
158
+ return result.rows;
159
+ } catch (err) {
160
+ const errorCode = mapPostgresError(err);
161
+ const error = createDatabaseError(errorCode, `Failed to list records from table: ${table}`, err instanceof Error ? err : new Error(String(err)), {
162
+ table,
163
+ options,
164
+ correlationId: this.correlationId
165
+ });
166
+ this.trackError(error, 'list', {
167
+ table
168
+ });
169
+ throw error;
170
+ }
171
+ }
172
+ async query(table, filters, transactionId) {
173
+ return this.list(table, {
174
+ filters
175
+ }, transactionId);
176
+ }
177
+ async insert(table, data, transactionId) {
178
+ this.ensureConnected();
179
+ try {
180
+ const keys = Object.keys(data);
181
+ const values = Object.values(data);
182
+ const placeholders = keys.map((_, i)=>`$${i + 1}`).join(', ');
183
+ const columns = keys.map((k)=>this.sanitizeIdentifier(k)).join(', ');
184
+ const query = `INSERT INTO ${this.sanitizeIdentifier(table)} (${columns}) VALUES (${placeholders}) RETURNING *`;
185
+ const client = this.getQueryClient(transactionId);
186
+ const result = await client.query(query, values);
187
+ this.recordSuccess();
188
+ return createSuccessResult(result.rows[0], result.rowCount || 0, result.rows[0] ? result.rows[0].id : undefined);
189
+ } catch (err) {
190
+ const errorCode = mapPostgresError(err);
191
+ const error = createDatabaseError(errorCode, `Failed to insert record into table: ${table}`, err instanceof Error ? err : new Error(String(err)), {
192
+ table,
193
+ data,
194
+ correlationId: this.correlationId
195
+ });
196
+ this.trackError(error, 'insert', {
197
+ table
198
+ });
199
+ return createFailedResult(error);
200
+ }
201
+ }
202
+ async insertMany(table, data, transactionId) {
203
+ this.ensureConnected();
204
+ // Check if we're already in a transaction
205
+ const hasActiveTransaction = transactionId && this.transactions.has(transactionId);
206
+ const client = hasActiveTransaction ? this.getQueryClient(transactionId) : await this.pool.connect();
207
+ try {
208
+ // Only begin transaction if not already in one
209
+ if (!hasActiveTransaction) {
210
+ await client.query('BEGIN');
211
+ }
212
+ const results = [];
213
+ for (const item of data){
214
+ const keys = Object.keys(item);
215
+ const values = Object.values(item);
216
+ const placeholders = keys.map((_, i)=>`$${i + 1}`).join(', ');
217
+ const columns = keys.map((k)=>this.sanitizeIdentifier(k)).join(', ');
218
+ const query = `INSERT INTO ${this.sanitizeIdentifier(table)} (${columns}) VALUES (${placeholders}) RETURNING *`;
219
+ const result = await client.query(query, values);
220
+ results.push(result.rows[0]);
221
+ }
222
+ // Only commit if we started the transaction
223
+ if (!hasActiveTransaction) {
224
+ await client.query('COMMIT');
225
+ }
226
+ this.recordSuccess();
227
+ return createSuccessResult(results, results.length);
228
+ } catch (err) {
229
+ // Only rollback if we started the transaction
230
+ if (!hasActiveTransaction) {
231
+ await client.query('ROLLBACK');
232
+ }
233
+ const errorCode = mapPostgresError(err);
234
+ const error = createDatabaseError(errorCode, `Failed to insert multiple records into table: ${table}`, err instanceof Error ? err : new Error(String(err)), {
235
+ table,
236
+ count: data.length,
237
+ correlationId: this.correlationId
238
+ });
239
+ this.trackError(error, 'insertMany', {
240
+ table,
241
+ count: data.length
242
+ });
243
+ return createFailedResult(error);
244
+ } finally{
245
+ // Only release client if we acquired it (not using existing transaction client)
246
+ if (!hasActiveTransaction) {
247
+ client.release();
248
+ }
249
+ }
250
+ }
251
+ async update(table, key, data, transactionId) {
252
+ this.ensureConnected();
253
+ try {
254
+ const keys = Object.keys(data);
255
+ const values = Object.values(data);
256
+ const setClauses = keys.map((k, i)=>`${this.sanitizeIdentifier(k)} = $${i + 1}`).join(', ');
257
+ const query = `UPDATE ${this.sanitizeIdentifier(table)} SET ${setClauses} WHERE id = $${keys.length + 1} RETURNING *`;
258
+ const client = this.getQueryClient(transactionId);
259
+ const result = await client.query(query, [
260
+ ...values,
261
+ key
262
+ ]);
263
+ if (result.rowCount === 0) {
264
+ const error = createDatabaseError(DatabaseErrorCode.NOT_FOUND, `Record not found in table: ${table}`, undefined, {
265
+ table,
266
+ key,
267
+ correlationId: this.correlationId
268
+ });
269
+ this.trackError(error, 'update', {
270
+ table,
271
+ key
272
+ });
273
+ return createFailedResult(error);
274
+ }
275
+ this.recordSuccess();
276
+ return createSuccessResult(result.rows[0], result.rowCount || 0);
277
+ } catch (err) {
278
+ const errorCode = mapPostgresError(err);
279
+ const error = createDatabaseError(errorCode, `Failed to update record in table: ${table}`, err instanceof Error ? err : new Error(String(err)), {
280
+ table,
281
+ key,
282
+ data,
283
+ correlationId: this.correlationId
284
+ });
285
+ this.trackError(error, 'update', {
286
+ table,
287
+ key
288
+ });
289
+ return createFailedResult(error);
290
+ }
291
+ }
292
+ async delete(table, key, transactionId) {
293
+ this.ensureConnected();
294
+ try {
295
+ const query = `DELETE FROM ${this.sanitizeIdentifier(table)} WHERE id = $1`;
296
+ const client = this.getQueryClient(transactionId);
297
+ const result = await client.query(query, [
298
+ key
299
+ ]);
300
+ if (result.rowCount === 0) {
301
+ const error = createDatabaseError(DatabaseErrorCode.NOT_FOUND, `Record not found in table: ${table}`, undefined, {
302
+ table,
303
+ key,
304
+ correlationId: this.correlationId
305
+ });
306
+ this.trackError(error, 'delete', {
307
+ table,
308
+ key
309
+ });
310
+ return createFailedResult(error);
311
+ }
312
+ this.recordSuccess();
313
+ return createSuccessResult(undefined, result.rowCount || 0);
314
+ } catch (err) {
315
+ const errorCode = mapPostgresError(err);
316
+ const error = createDatabaseError(errorCode, `Failed to delete record from table: ${table}`, err instanceof Error ? err : new Error(String(err)), {
317
+ table,
318
+ key,
319
+ correlationId: this.correlationId
320
+ });
321
+ this.trackError(error, 'delete', {
322
+ table,
323
+ key
324
+ });
325
+ return createFailedResult(error);
326
+ }
327
+ }
328
+ async raw(query, params, transactionId) {
329
+ this.ensureConnected();
330
+ try {
331
+ const client = this.getQueryClient(transactionId);
332
+ const result = await client.query(query, params);
333
+ this.recordSuccess();
334
+ return result.rows;
335
+ } catch (err) {
336
+ const errorCode = mapPostgresError(err);
337
+ const error = createDatabaseError(errorCode, `Failed to execute raw query`, err instanceof Error ? err : new Error(String(err)), {
338
+ query,
339
+ params,
340
+ correlationId: this.correlationId
341
+ });
342
+ this.trackError(error, 'raw', {
343
+ query
344
+ });
345
+ throw error;
346
+ }
347
+ }
348
+ async beginTransaction() {
349
+ this.ensureConnected();
350
+ const client = await this.pool.connect();
351
+ const context = {
352
+ id: `postgres-tx-${Date.now()}`,
353
+ databases: [
354
+ 'postgres'
355
+ ],
356
+ startTime: new Date(),
357
+ status: 'pending'
358
+ };
359
+ await client.query('BEGIN');
360
+ this.transactions.set(context.id, {
361
+ context,
362
+ client
363
+ });
364
+ return context;
365
+ }
366
+ async prepareTransaction(context) {
367
+ const transaction = this.transactions.get(context.id);
368
+ if (!transaction) {
369
+ throw createDatabaseError(DatabaseErrorCode.TRANSACTION_FAILED, 'Transaction not found', undefined, {
370
+ transactionId: context.id
371
+ });
372
+ }
373
+ try {
374
+ // PostgreSQL supports PREPARE TRANSACTION for two-phase commit
375
+ // Note: This requires max_prepared_transactions > 0 in postgresql.conf
376
+ await transaction.client.query(`PREPARE TRANSACTION '${context.id}'`);
377
+ context.status = 'prepared';
378
+ context.preparedAt = new Date();
379
+ return true;
380
+ } catch (err) {
381
+ // If prepare fails, the transaction is still active and can be rolled back
382
+ throw createDatabaseError(DatabaseErrorCode.TRANSACTION_FAILED, 'Failed to prepare transaction', err instanceof Error ? err : new Error(String(err)), {
383
+ transactionId: context.id
384
+ });
385
+ }
386
+ }
387
+ async commitTransaction(context) {
388
+ const transaction = this.transactions.get(context.id);
389
+ if (!transaction) {
390
+ throw createDatabaseError(DatabaseErrorCode.TRANSACTION_FAILED, 'Transaction not found', undefined, {
391
+ transactionId: context.id
392
+ });
393
+ }
394
+ try {
395
+ // If transaction was prepared, use COMMIT PREPARED
396
+ if (context.status === 'prepared') {
397
+ await transaction.client.query(`COMMIT PREPARED '${context.id}'`);
398
+ } else {
399
+ await transaction.client.query('COMMIT');
400
+ }
401
+ context.status = 'committed';
402
+ } finally{
403
+ transaction.client.release();
404
+ this.transactions.delete(context.id);
405
+ }
406
+ }
407
+ async rollbackTransaction(context) {
408
+ const transaction = this.transactions.get(context.id);
409
+ if (!transaction) {
410
+ throw createDatabaseError(DatabaseErrorCode.TRANSACTION_FAILED, 'Transaction not found', undefined, {
411
+ transactionId: context.id
412
+ });
413
+ }
414
+ try {
415
+ // If transaction was prepared, use ROLLBACK PREPARED
416
+ if (context.status === 'prepared') {
417
+ await transaction.client.query(`ROLLBACK PREPARED '${context.id}'`);
418
+ } else {
419
+ await transaction.client.query('ROLLBACK');
420
+ }
421
+ context.status = 'rolled_back';
422
+ } finally{
423
+ transaction.client.release();
424
+ this.transactions.delete(context.id);
425
+ }
426
+ }
427
+ ensureConnected() {
428
+ if (!this.isConnected()) {
429
+ throw createDatabaseError(DatabaseErrorCode.CONNECTION_FAILED, 'Not connected to PostgreSQL', undefined, {
430
+ config: this.config
431
+ });
432
+ }
433
+ }
434
+ sanitizeIdentifier(identifier) {
435
+ // Remove any characters that aren't alphanumeric or underscore
436
+ return identifier.replace(/[^a-zA-Z0-9_]/g, '');
437
+ }
438
+ /**
439
+ * Get client for query execution (transaction client if available, otherwise pool)
440
+ */ getQueryClient(transactionId) {
441
+ if (transactionId) {
442
+ const transaction = this.transactions.get(transactionId);
443
+ if (transaction) {
444
+ return transaction.client;
445
+ }
446
+ }
447
+ return this.pool;
448
+ }
449
+ buildWhereClause(filter, params) {
450
+ const field = this.sanitizeIdentifier(String(filter.field));
451
+ switch(filter.operator){
452
+ case 'eq':
453
+ {
454
+ const paramIndex = params.length + 1;
455
+ params.push(filter.value);
456
+ return `${field} = $${paramIndex}`;
457
+ }
458
+ case 'ne':
459
+ {
460
+ const paramIndex = params.length + 1;
461
+ params.push(filter.value);
462
+ return `${field} != $${paramIndex}`;
463
+ }
464
+ case 'gt':
465
+ {
466
+ const paramIndex = params.length + 1;
467
+ params.push(filter.value);
468
+ return `${field} > $${paramIndex}`;
469
+ }
470
+ case 'gte':
471
+ {
472
+ const paramIndex = params.length + 1;
473
+ params.push(filter.value);
474
+ return `${field} >= $${paramIndex}`;
475
+ }
476
+ case 'lt':
477
+ {
478
+ const paramIndex = params.length + 1;
479
+ params.push(filter.value);
480
+ return `${field} < $${paramIndex}`;
481
+ }
482
+ case 'lte':
483
+ {
484
+ const paramIndex = params.length + 1;
485
+ params.push(filter.value);
486
+ return `${field} <= $${paramIndex}`;
487
+ }
488
+ case 'in':
489
+ {
490
+ if (!Array.isArray(filter.value)) {
491
+ throw new TypeError(`Field '${String(filter.field)}' with operator 'in' requires an array value`);
492
+ }
493
+ if (filter.value.length === 0) {
494
+ // Empty IN list - return false condition without invalid SQL
495
+ return '1=0';
496
+ }
497
+ const startIndex = params.length + 1;
498
+ const placeholders = filter.value.map((_, i)=>`$${startIndex + i}`).join(', ');
499
+ params.push(...filter.value);
500
+ return `${field} IN (${placeholders})`;
501
+ }
502
+ case 'like':
503
+ {
504
+ const paramIndex = params.length + 1;
505
+ params.push(`%${filter.value}%`);
506
+ return `${field} LIKE $${paramIndex}`;
507
+ }
508
+ case 'between':
509
+ {
510
+ if (!Array.isArray(filter.value)) {
511
+ throw new TypeError(`Field '${String(filter.field)}' with operator 'between' requires an array value`);
512
+ }
513
+ if (filter.value.length !== 2) {
514
+ throw new TypeError(`Field '${String(filter.field)}' with operator 'between' requires exactly 2 elements, got ${filter.value.length}`);
515
+ }
516
+ const paramIndex = params.length + 1;
517
+ params.push(filter.value[0], filter.value[1]);
518
+ return `${field} BETWEEN $${paramIndex} AND $${paramIndex + 1}`;
519
+ }
520
+ default:
521
+ return '1=1';
522
+ }
523
+ }
524
+ }
525
+
526
+ //# sourceMappingURL=postgres-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/database-service/postgres-adapter.ts"],"sourcesContent":["/**\r\n * PostgreSQL Database Adapter\r\n *\r\n * Implements IDatabaseAdapter for PostgreSQL with connection pooling and parameterized queries.\r\n * Part of Task 0.4: Database Query Abstraction Layer (MVP)\r\n *\r\n * SECURITY: Requires password authentication and uses parameterized queries for SQL injection prevention\r\n */\r\n\r\nimport { Pool, PoolClient, QueryResult } from 'pg';\r\nimport {\r\n IDatabaseAdapter,\r\n DatabaseConfig,\r\n QueryOptions,\r\n QueryFilter,\r\n OperationResult,\r\n TransactionContext,\r\n} from './types.js';\r\nimport {\r\n DatabaseErrorCode,\r\n createDatabaseError,\r\n createSuccessResult,\r\n createFailedResult,\r\n mapPostgresError,\r\n} from './errors.js';\r\nimport { withDatabaseRetry } from '../retry-manager.js';\r\nimport { ErrorAggregator } from '../error-aggregator.js';\r\nimport { v4 as uuidv4 } from 'uuid';\r\n\r\nexport class PostgresAdapter implements IDatabaseAdapter {\r\n private pool: Pool | null = null;\r\n private config: DatabaseConfig;\r\n private connected: boolean = false;\r\n private transactions: Map<string, { context: TransactionContext; client: PoolClient }> = new Map();\r\n private errorAggregator?: ErrorAggregator;\r\n private correlationId: string;\r\n\r\n constructor(config: DatabaseConfig, errorAggregator?: ErrorAggregator) {\r\n this.config = config;\r\n this.errorAggregator = errorAggregator;\r\n this.correlationId = uuidv4();\r\n }\r\n\r\n getType(): 'postgres' {\r\n return 'postgres';\r\n }\r\n\r\n /**\r\n * Track error with error aggregator\r\n * @private\r\n */\r\n private trackError(error: any, operation: string, context?: Record<string, any>): void {\r\n if (this.errorAggregator) {\r\n const dbError = error.code ? error : createDatabaseError(\r\n DatabaseErrorCode.QUERY_FAILED,\r\n `PostgreSQL ${operation} failed`,\r\n error instanceof Error ? error : new Error(String(error)),\r\n context\r\n );\r\n\r\n this.errorAggregator.addError('postgres', dbError, {\r\n ...context,\r\n operation,\r\n correlationId: this.correlationId,\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Record successful operation with error aggregator\r\n * @private\r\n */\r\n private recordSuccess(): void {\r\n if (this.errorAggregator) {\r\n this.errorAggregator.recordSuccess('postgres');\r\n }\r\n }\r\n\r\n async connect(): Promise<void> {\r\n // SECURITY: Validate password is provided for authentication\r\n if (!this.config.password && !this.config.connectionString) {\r\n throw createDatabaseError(\r\n DatabaseErrorCode.CONNECTION_FAILED,\r\n 'PostgreSQL password is required. Set POSTGRES_PASSWORD environment variable.',\r\n undefined,\r\n { reason: 'missing_authentication' }\r\n );\r\n }\r\n\r\n // Wrap connection with retry logic for transient failures\r\n await withDatabaseRetry(async () => {\r\n try {\r\n const poolConfig: any = {\r\n host: this.config.host,\r\n port: this.config.port,\r\n database: this.config.database,\r\n user: this.config.username,\r\n password: this.config.password,\r\n max: this.config.poolSize || 10,\r\n idleTimeoutMillis: this.config.timeout || 30000,\r\n connectionTimeoutMillis: 5000,\r\n };\r\n\r\n // Use connectionString if provided, otherwise build from components\r\n if (this.config.connectionString) {\r\n poolConfig.connectionString = this.config.connectionString;\r\n }\r\n\r\n this.pool = new Pool(poolConfig);\r\n\r\n // Test connection\r\n const client = await this.pool.connect();\r\n client.release();\r\n\r\n this.connected = true;\r\n this.recordSuccess();\r\n } catch (err) {\r\n const error = createDatabaseError(\r\n DatabaseErrorCode.CONNECTION_FAILED,\r\n 'Failed to connect to PostgreSQL',\r\n err instanceof Error ? err : new Error(String(err)),\r\n { config: this.config, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'connect');\r\n throw error;\r\n }\r\n });\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n if (this.pool) {\r\n await this.pool.end();\r\n this.pool = null;\r\n this.connected = false;\r\n }\r\n }\r\n\r\n isConnected(): boolean {\r\n return this.connected && this.pool !== null;\r\n }\r\n\r\n async get<T = any>(key: string, transactionId?: string): Promise<T | null> {\r\n this.ensureConnected();\r\n\r\n try {\r\n // Parse correlation key format: table:id or table:id:entity:subtype\r\n // For SQL adapters, we use only table:id for lookup\r\n const parts = key.split(':');\r\n const table = parts[0];\r\n const id = parts.slice(1).join(':'); // Rejoin remaining parts as ID\r\n\r\n if (!table || !id) {\r\n throw new Error('Invalid key format. Expected \"table:id\" or \"table:id:entity:subtype\"');\r\n }\r\n\r\n const query = `SELECT * FROM ${this.sanitizeIdentifier(table)} WHERE id = $1`;\r\n const client = this.getQueryClient(transactionId);\r\n const result = await client.query<T>(query, [id]);\r\n\r\n this.recordSuccess();\r\n return result.rows.length > 0 ? result.rows[0] : null;\r\n } catch (err) {\r\n const errorCode = mapPostgresError(err);\r\n const error = createDatabaseError(\r\n errorCode,\r\n `Failed to get record: ${key}`,\r\n err instanceof Error ? err : new Error(String(err)),\r\n { key, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'get', { key });\r\n throw error;\r\n }\r\n }\r\n\r\n async list<T = any>(table: string, options?: QueryOptions<T>, transactionId?: string): Promise<T[]> {\r\n this.ensureConnected();\r\n\r\n try {\r\n let query = `SELECT * FROM ${this.sanitizeIdentifier(table)}`;\r\n const params: any[] = [];\r\n let paramIndex = 1;\r\n\r\n // Apply filters\r\n if (options?.filters && options.filters.length > 0) {\r\n const whereClauses = options.filters.map(filter => {\r\n return this.buildWhereClause(filter, params);\r\n });\r\n query += ` WHERE ${whereClauses.join(' AND ')}`;\r\n }\r\n\r\n // Apply ordering\r\n if (options?.orderBy) {\r\n const order = options.order || 'asc';\r\n query += ` ORDER BY ${this.sanitizeIdentifier(String(options.orderBy))} ${order.toUpperCase()}`;\r\n }\r\n\r\n // Apply limit and offset\r\n if (options?.limit) {\r\n query += ` LIMIT $${paramIndex++}`;\r\n params.push(options.limit);\r\n }\r\n\r\n if (options?.offset) {\r\n query += ` OFFSET $${paramIndex++}`;\r\n params.push(options.offset);\r\n }\r\n\r\n const client = this.getQueryClient(transactionId);\r\n const result = await client.query<T>(query, params);\r\n this.recordSuccess();\r\n return result.rows;\r\n } catch (err) {\r\n const errorCode = mapPostgresError(err);\r\n const error = createDatabaseError(\r\n errorCode,\r\n `Failed to list records from table: ${table}`,\r\n err instanceof Error ? err : new Error(String(err)),\r\n { table, options, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'list', { table });\r\n throw error;\r\n }\r\n }\r\n\r\n async query<T = any>(table: string, filters: QueryFilter<T>[], transactionId?: string): Promise<T[]> {\r\n return this.list(table, { filters }, transactionId);\r\n }\r\n\r\n async insert<T = any>(table: string, data: T, transactionId?: string): Promise<OperationResult<T>> {\r\n this.ensureConnected();\r\n\r\n try {\r\n const keys = Object.keys(data as any);\r\n const values = Object.values(data as any);\r\n\r\n const placeholders = keys.map((_, i) => `$${i + 1}`).join(', ');\r\n const columns = keys.map(k => this.sanitizeIdentifier(k)).join(', ');\r\n\r\n const query = `INSERT INTO ${this.sanitizeIdentifier(table)} (${columns}) VALUES (${placeholders}) RETURNING *`;\r\n\r\n const client = this.getQueryClient(transactionId);\r\n const result = await client.query<T>(query, values);\r\n\r\n this.recordSuccess();\r\n return createSuccessResult(result.rows[0], result.rowCount || 0, result.rows[0] ? (result.rows[0] as any).id : undefined);\r\n } catch (err) {\r\n const errorCode = mapPostgresError(err);\r\n const error = createDatabaseError(\r\n errorCode,\r\n `Failed to insert record into table: ${table}`,\r\n err instanceof Error ? err : new Error(String(err)),\r\n { table, data, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'insert', { table });\r\n return createFailedResult(error);\r\n }\r\n }\r\n\r\n async insertMany<T = any>(table: string, data: T[], transactionId?: string): Promise<OperationResult<T[]>> {\r\n this.ensureConnected();\r\n\r\n // Check if we're already in a transaction\r\n const hasActiveTransaction = transactionId && this.transactions.has(transactionId);\r\n const client = hasActiveTransaction ? this.getQueryClient(transactionId) as PoolClient : await this.pool!.connect();\r\n\r\n try {\r\n // Only begin transaction if not already in one\r\n if (!hasActiveTransaction) {\r\n await client.query('BEGIN');\r\n }\r\n\r\n const results: T[] = [];\r\n\r\n for (const item of data) {\r\n const keys = Object.keys(item as any);\r\n const values = Object.values(item as any);\r\n\r\n const placeholders = keys.map((_, i) => `$${i + 1}`).join(', ');\r\n const columns = keys.map(k => this.sanitizeIdentifier(k)).join(', ');\r\n\r\n const query = `INSERT INTO ${this.sanitizeIdentifier(table)} (${columns}) VALUES (${placeholders}) RETURNING *`;\r\n\r\n const result = await client.query<T>(query, values);\r\n results.push(result.rows[0]);\r\n }\r\n\r\n // Only commit if we started the transaction\r\n if (!hasActiveTransaction) {\r\n await client.query('COMMIT');\r\n }\r\n\r\n this.recordSuccess();\r\n return createSuccessResult(results, results.length);\r\n } catch (err) {\r\n // Only rollback if we started the transaction\r\n if (!hasActiveTransaction) {\r\n await client.query('ROLLBACK');\r\n }\r\n\r\n const errorCode = mapPostgresError(err);\r\n const error = createDatabaseError(\r\n errorCode,\r\n `Failed to insert multiple records into table: ${table}`,\r\n err instanceof Error ? err : new Error(String(err)),\r\n { table, count: data.length, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'insertMany', { table, count: data.length });\r\n return createFailedResult(error);\r\n } finally {\r\n // Only release client if we acquired it (not using existing transaction client)\r\n if (!hasActiveTransaction) {\r\n client.release();\r\n }\r\n }\r\n }\r\n\r\n async update<T = any>(table: string, key: string, data: Partial<T>, transactionId?: string): Promise<OperationResult<T>> {\r\n this.ensureConnected();\r\n\r\n try {\r\n const keys = Object.keys(data as any);\r\n const values = Object.values(data as any);\r\n\r\n const setClauses = keys.map((k, i) => `${this.sanitizeIdentifier(k)} = $${i + 1}`).join(', ');\r\n\r\n const query = `UPDATE ${this.sanitizeIdentifier(table)} SET ${setClauses} WHERE id = $${keys.length + 1} RETURNING *`;\r\n\r\n const client = this.getQueryClient(transactionId);\r\n const result = await client.query<T>(query, [...values, key]);\r\n\r\n if (result.rowCount === 0) {\r\n const error = createDatabaseError(\r\n DatabaseErrorCode.NOT_FOUND,\r\n `Record not found in table: ${table}`,\r\n undefined,\r\n { table, key, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'update', { table, key });\r\n return createFailedResult(error);\r\n }\r\n\r\n this.recordSuccess();\r\n return createSuccessResult(result.rows[0], result.rowCount || 0);\r\n } catch (err) {\r\n const errorCode = mapPostgresError(err);\r\n const error = createDatabaseError(\r\n errorCode,\r\n `Failed to update record in table: ${table}`,\r\n err instanceof Error ? err : new Error(String(err)),\r\n { table, key, data, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'update', { table, key });\r\n return createFailedResult(error);\r\n }\r\n }\r\n\r\n async delete(table: string, key: string, transactionId?: string): Promise<OperationResult<void>> {\r\n this.ensureConnected();\r\n\r\n try {\r\n const query = `DELETE FROM ${this.sanitizeIdentifier(table)} WHERE id = $1`;\r\n\r\n const client = this.getQueryClient(transactionId);\r\n const result = await client.query(query, [key]);\r\n\r\n if (result.rowCount === 0) {\r\n const error = createDatabaseError(\r\n DatabaseErrorCode.NOT_FOUND,\r\n `Record not found in table: ${table}`,\r\n undefined,\r\n { table, key, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'delete', { table, key });\r\n return createFailedResult(error);\r\n }\r\n\r\n this.recordSuccess();\r\n return createSuccessResult(undefined, result.rowCount || 0);\r\n } catch (err) {\r\n const errorCode = mapPostgresError(err);\r\n const error = createDatabaseError(\r\n errorCode,\r\n `Failed to delete record from table: ${table}`,\r\n err instanceof Error ? err : new Error(String(err)),\r\n { table, key, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'delete', { table, key });\r\n return createFailedResult(error);\r\n }\r\n }\r\n\r\n async raw<T = any>(query: string, params?: any[], transactionId?: string): Promise<T> {\r\n this.ensureConnected();\r\n\r\n try {\r\n const client = this.getQueryClient(transactionId);\r\n const result = await client.query<T>(query, params);\r\n this.recordSuccess();\r\n return result.rows as T;\r\n } catch (err) {\r\n const errorCode = mapPostgresError(err);\r\n const error = createDatabaseError(\r\n errorCode,\r\n `Failed to execute raw query`,\r\n err instanceof Error ? err : new Error(String(err)),\r\n { query, params, correlationId: this.correlationId }\r\n );\r\n this.trackError(error, 'raw', { query });\r\n throw error;\r\n }\r\n }\r\n\r\n async beginTransaction(): Promise<TransactionContext> {\r\n this.ensureConnected();\r\n\r\n const client = await this.pool!.connect();\r\n\r\n const context: TransactionContext = {\r\n id: `postgres-tx-${Date.now()}`,\r\n databases: ['postgres'],\r\n startTime: new Date(),\r\n status: 'pending',\r\n };\r\n\r\n await client.query('BEGIN');\r\n this.transactions.set(context.id, { context, client });\r\n\r\n return context;\r\n }\r\n\r\n async prepareTransaction(context: TransactionContext): Promise<boolean> {\r\n const transaction = this.transactions.get(context.id);\r\n\r\n if (!transaction) {\r\n throw createDatabaseError(\r\n DatabaseErrorCode.TRANSACTION_FAILED,\r\n 'Transaction not found',\r\n undefined,\r\n { transactionId: context.id }\r\n );\r\n }\r\n\r\n try {\r\n // PostgreSQL supports PREPARE TRANSACTION for two-phase commit\r\n // Note: This requires max_prepared_transactions > 0 in postgresql.conf\r\n await transaction.client.query(`PREPARE TRANSACTION '${context.id}'`);\r\n context.status = 'prepared';\r\n context.preparedAt = new Date();\r\n return true;\r\n } catch (err) {\r\n // If prepare fails, the transaction is still active and can be rolled back\r\n throw createDatabaseError(\r\n DatabaseErrorCode.TRANSACTION_FAILED,\r\n 'Failed to prepare transaction',\r\n err instanceof Error ? err : new Error(String(err)),\r\n { transactionId: context.id }\r\n );\r\n }\r\n }\r\n\r\n async commitTransaction(context: TransactionContext): Promise<void> {\r\n const transaction = this.transactions.get(context.id);\r\n\r\n if (!transaction) {\r\n throw createDatabaseError(\r\n DatabaseErrorCode.TRANSACTION_FAILED,\r\n 'Transaction not found',\r\n undefined,\r\n { transactionId: context.id }\r\n );\r\n }\r\n\r\n try {\r\n // If transaction was prepared, use COMMIT PREPARED\r\n if (context.status === 'prepared') {\r\n await transaction.client.query(`COMMIT PREPARED '${context.id}'`);\r\n } else {\r\n await transaction.client.query('COMMIT');\r\n }\r\n context.status = 'committed';\r\n } finally {\r\n transaction.client.release();\r\n this.transactions.delete(context.id);\r\n }\r\n }\r\n\r\n async rollbackTransaction(context: TransactionContext): Promise<void> {\r\n const transaction = this.transactions.get(context.id);\r\n\r\n if (!transaction) {\r\n throw createDatabaseError(\r\n DatabaseErrorCode.TRANSACTION_FAILED,\r\n 'Transaction not found',\r\n undefined,\r\n { transactionId: context.id }\r\n );\r\n }\r\n\r\n try {\r\n // If transaction was prepared, use ROLLBACK PREPARED\r\n if (context.status === 'prepared') {\r\n await transaction.client.query(`ROLLBACK PREPARED '${context.id}'`);\r\n } else {\r\n await transaction.client.query('ROLLBACK');\r\n }\r\n context.status = 'rolled_back';\r\n } finally {\r\n transaction.client.release();\r\n this.transactions.delete(context.id);\r\n }\r\n }\r\n\r\n private ensureConnected(): void {\r\n if (!this.isConnected()) {\r\n throw createDatabaseError(\r\n DatabaseErrorCode.CONNECTION_FAILED,\r\n 'Not connected to PostgreSQL',\r\n undefined,\r\n { config: this.config }\r\n );\r\n }\r\n }\r\n\r\n private sanitizeIdentifier(identifier: string): string {\r\n // Remove any characters that aren't alphanumeric or underscore\r\n return identifier.replace(/[^a-zA-Z0-9_]/g, '');\r\n }\r\n\r\n /**\r\n * Get client for query execution (transaction client if available, otherwise pool)\r\n */\r\n private getQueryClient(transactionId?: string): Pool | PoolClient {\r\n if (transactionId) {\r\n const transaction = this.transactions.get(transactionId);\r\n if (transaction) {\r\n return transaction.client;\r\n }\r\n }\r\n return this.pool!;\r\n }\r\n\r\n private buildWhereClause<T>(filter: QueryFilter<T>, params: any[]): string {\r\n const field = this.sanitizeIdentifier(String(filter.field));\r\n\r\n switch (filter.operator) {\r\n case 'eq': {\r\n const paramIndex = params.length + 1;\r\n params.push(filter.value);\r\n return `${field} = $${paramIndex}`;\r\n }\r\n case 'ne': {\r\n const paramIndex = params.length + 1;\r\n params.push(filter.value);\r\n return `${field} != $${paramIndex}`;\r\n }\r\n case 'gt': {\r\n const paramIndex = params.length + 1;\r\n params.push(filter.value);\r\n return `${field} > $${paramIndex}`;\r\n }\r\n case 'gte': {\r\n const paramIndex = params.length + 1;\r\n params.push(filter.value);\r\n return `${field} >= $${paramIndex}`;\r\n }\r\n case 'lt': {\r\n const paramIndex = params.length + 1;\r\n params.push(filter.value);\r\n return `${field} < $${paramIndex}`;\r\n }\r\n case 'lte': {\r\n const paramIndex = params.length + 1;\r\n params.push(filter.value);\r\n return `${field} <= $${paramIndex}`;\r\n }\r\n case 'in': {\r\n if (!Array.isArray(filter.value)) {\r\n throw new TypeError(`Field '${String(filter.field)}' with operator 'in' requires an array value`);\r\n }\r\n if (filter.value.length === 0) {\r\n // Empty IN list - return false condition without invalid SQL\r\n return '1=0';\r\n }\r\n const startIndex = params.length + 1;\r\n const placeholders = filter.value.map((_, i) => `$${startIndex + i}`).join(', ');\r\n params.push(...filter.value);\r\n return `${field} IN (${placeholders})`;\r\n }\r\n case 'like': {\r\n const paramIndex = params.length + 1;\r\n params.push(`%${filter.value}%`);\r\n return `${field} LIKE $${paramIndex}`;\r\n }\r\n case 'between': {\r\n if (!Array.isArray(filter.value)) {\r\n throw new TypeError(`Field '${String(filter.field)}' with operator 'between' requires an array value`);\r\n }\r\n if (filter.value.length !== 2) {\r\n throw new TypeError(`Field '${String(filter.field)}' with operator 'between' requires exactly 2 elements, got ${filter.value.length}`);\r\n }\r\n const paramIndex = params.length + 1;\r\n params.push(filter.value[0], filter.value[1]);\r\n return `${field} BETWEEN $${paramIndex} AND $${paramIndex + 1}`;\r\n }\r\n default:\r\n return '1=1';\r\n }\r\n }\r\n}\r\n"],"names":["Pool","DatabaseErrorCode","createDatabaseError","createSuccessResult","createFailedResult","mapPostgresError","withDatabaseRetry","v4","uuidv4","PostgresAdapter","pool","config","connected","transactions","Map","errorAggregator","correlationId","getType","trackError","error","operation","context","dbError","code","QUERY_FAILED","Error","String","addError","recordSuccess","connect","password","connectionString","CONNECTION_FAILED","undefined","reason","poolConfig","host","port","database","user","username","max","poolSize","idleTimeoutMillis","timeout","connectionTimeoutMillis","client","release","err","disconnect","end","isConnected","get","key","transactionId","ensureConnected","parts","split","table","id","slice","join","query","sanitizeIdentifier","getQueryClient","result","rows","length","errorCode","list","options","params","paramIndex","filters","whereClauses","map","filter","buildWhereClause","orderBy","order","toUpperCase","limit","push","offset","insert","data","keys","Object","values","placeholders","_","i","columns","k","rowCount","insertMany","hasActiveTransaction","has","results","item","count","update","setClauses","NOT_FOUND","delete","raw","beginTransaction","Date","now","databases","startTime","status","set","prepareTransaction","transaction","TRANSACTION_FAILED","preparedAt","commitTransaction","rollbackTransaction","identifier","replace","field","operator","value","Array","isArray","TypeError","startIndex"],"mappings":"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"}