claude-flow-novice 2.15.3 → 2.15.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. package/.claude/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
  2. package/.claude/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
  3. package/.claude/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
  4. package/.claude/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
  5. package/.claude/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
  6. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
  7. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
  8. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
  9. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
  10. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
  11. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
  12. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
  13. package/.claude/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
  14. package/.claude/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
  15. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
  16. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
  17. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
  18. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
  19. package/.claude/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
  20. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
  21. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
  22. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
  23. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
  24. package/.claude/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
  25. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
  26. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
  27. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
  28. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
  29. package/.claude/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
  30. package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
  31. package/.claude/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
  32. package/.claude/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
  33. package/.claude/commands/cfn-loop-cli.md +29 -6
  34. package/.claude/commands/switch-api.md +31 -10
  35. package/.claude/hooks/cfn-lint-sql-injection.sh +61 -0
  36. package/.claude/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
  37. package/.claude/hooks/cfn-pre-edit-security-warning.sh +40 -0
  38. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  39. package/.claude/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  40. package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  41. package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  42. package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  43. package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  44. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +238 -29
  45. package/.claude/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  46. package/.claude/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  47. package/.claude/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  48. package/.claude/skills/cfn-redis-coordination/agent-log.sh +4 -0
  49. package/.claude/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  50. package/.claude/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
  51. package/.claude/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  52. package/.claude/skills/cfn-redis-coordination/get-context.sh +33 -0
  53. package/.claude/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  54. package/.claude/skills/cfn-redis-coordination/invoke-waiting-mode.sh +6 -2
  55. package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  56. package/.claude/skills/cfn-redis-coordination/redis-functions.sh +34 -0
  57. package/.claude/skills/cfn-redis-coordination/report-completion.sh +24 -31
  58. package/.claude/skills/cfn-redis-coordination/store-context.sh +4 -0
  59. package/.claude/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  60. package/.claude/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  61. package/.claude/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  62. package/.claude/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  63. package/.claude/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
  64. package/README.md +116 -475
  65. package/claude-assets/agents/cfn-dev-team/README.md +103 -0
  66. package/claude-assets/agents/cfn-dev-team/architecture/goal-planner.md +1 -1
  67. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +77 -15
  68. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +355 -6
  69. package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +82 -1
  70. package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +82 -1
  71. package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +77 -15
  72. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +99 -12
  73. package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +1 -1
  74. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +97 -0
  75. package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +20 -1
  76. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +97 -0
  77. package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +110 -13
  78. package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +106 -15
  79. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +115 -11
  80. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +94 -7
  81. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +87 -9
  82. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +85 -7
  83. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +160 -28
  84. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +101 -19
  85. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +108 -14
  86. package/claude-assets/agents/cfn-dev-team/reviewers/{reviewer.md → code-reviewer.md} +95 -8
  87. package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +107 -7
  88. package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +98 -7
  89. package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +95 -7
  90. package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +136 -9
  91. package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +108 -1
  92. package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +107 -13
  93. package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +737 -0
  94. package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
  95. package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +828 -0
  96. package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +106 -7
  97. package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +77 -0
  98. package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +684 -0
  99. package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +110 -1
  100. package/claude-assets/agents/cfn-dev-team/testers/tester.md +94 -7
  101. package/claude-assets/agents/cfn-dev-team/utility/code-booster.md +1 -3
  102. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +87 -13
  103. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +103 -7
  104. package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -3
  105. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +94 -7
  106. package/claude-assets/agents/docker-coordinators/cfn-docker-v3-coordinator.md +46 -0
  107. package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
  108. package/claude-assets/cfn-extras/skills/advanced-features/cfn-agent-swap/recommend-swap.sh +59 -59
  109. package/claude-assets/cfn-extras/skills/analytics/cfn-improvement-recommender/recommend-improvements.sh +91 -91
  110. package/claude-assets/cfn-extras/skills/analytics/cfn-pattern-extraction/extract-patterns.sh +79 -79
  111. package/claude-assets/cfn-extras/skills/analytics/cfn-retrospective-report/generate-report.sh +100 -100
  112. package/claude-assets/cfn-extras/skills/analytics/cfn-telemetry/start-telemetry.sh +110 -110
  113. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/add-bullet.sh +145 -145
  114. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/log-merge.sh +67 -67
  115. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/monitor-injection-performance.sh +137 -137
  116. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/optimize-injection-pipeline.sh +168 -168
  117. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/query-reflections.sh +35 -35
  118. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/store-reflection.sh +45 -45
  119. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/track-ab-test.sh +41 -41
  120. package/claude-assets/cfn-extras/skills/deprecated/cfn-ace-system/update-reflection.sh +41 -41
  121. package/claude-assets/cfn-extras/skills/deprecated/cfn-cli-setup/validate-cli-environment.sh +191 -191
  122. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/create-campaign.sh +231 -231
  123. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/get-campaign-performance.sh +190 -190
  124. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/pause-campaign.sh +142 -142
  125. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/set-budget.sh +181 -181
  126. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-ad-campaigns/operations/update-bid-strategy.sh +133 -133
  127. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/get-conversation-history.sh +121 -121
  128. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/qualify-lead.sh +156 -156
  129. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/schedule-demo.sh +181 -181
  130. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/send-message.sh +137 -137
  131. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-chatbot-conversations/operations/transfer-to-human.sh +179 -179
  132. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/create-campaign.sh +183 -183
  133. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/get-delivery-status.sh +139 -139
  134. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/opt-out.sh +150 -150
  135. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/schedule-campaign.sh +187 -187
  136. package/claude-assets/cfn-extras/skills/marketing/cfn-marketing-sms-campaigns/operations/send-sms.sh +181 -181
  137. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/test-web-portal-skill.sh +50 -50
  138. package/claude-assets/cfn-extras/skills/ui-portal/cfn-web-portal/validate-deployment.sh +84 -84
  139. package/claude-assets/cfn-extras/skills/utility/cfn-environment-sanitization/sanitize-environment.sh +243 -243
  140. package/claude-assets/commands/cfn-loop-cli.md +29 -6
  141. package/claude-assets/commands/switch-api.md +31 -10
  142. package/claude-assets/hooks/cfn-lint-sql-injection.sh +61 -0
  143. package/claude-assets/hooks/cfn-post-edit-cfn-retrospective.sh +33 -2
  144. package/claude-assets/hooks/cfn-pre-edit-security-warning.sh +40 -0
  145. package/claude-assets/hooks/detect-hardcoded-credentials.sh +212 -0
  146. package/claude-assets/skills/SKILL_TEMPLATE.md +774 -0
  147. package/claude-assets/skills/agent-lifecycle/execute-lifecycle-hook.sh +84 -113
  148. package/claude-assets/skills/agent-lifecycle/simple-audit.sh +33 -6
  149. package/claude-assets/skills/agent-template-generator/SKILL.md +440 -0
  150. package/claude-assets/skills/agent-template-generator/generate-agent.sh +405 -0
  151. package/claude-assets/skills/agent-validation-linter/SKILL.md +589 -0
  152. package/claude-assets/skills/agent-validation-linter/lint-agents.sh +271 -0
  153. package/claude-assets/skills/bootstrap/bash-fundamentals.md +786 -0
  154. package/claude-assets/skills/bootstrap/database-connection.md +464 -0
  155. package/claude-assets/skills/bootstrap/error-handling.md +580 -0
  156. package/claude-assets/skills/bootstrap/file-operations.md +699 -0
  157. package/claude-assets/skills/bootstrap/skill-loader.md +616 -0
  158. package/claude-assets/skills/bootstrap/sqlite-params.sh +287 -0
  159. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh +22 -24
  160. package/claude-assets/skills/cfn-automatic-memory-persistence/test-memory-persistence.sh +17 -16
  161. package/claude-assets/skills/cfn-deployment/SKILL.md +293 -0
  162. package/claude-assets/skills/cfn-deployment/execute.sh +21 -0
  163. package/claude-assets/skills/cfn-docker-agent-spawning/SKILL.md +28 -4
  164. package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +3 -1
  165. package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +224 -20
  166. package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +38 -0
  167. package/claude-assets/skills/cfn-error-batching-strategy/lib/core-functions.sh +47 -47
  168. package/claude-assets/skills/cfn-file-operations/SKILL.md +290 -0
  169. package/claude-assets/skills/cfn-file-operations/execute.sh +129 -0
  170. package/claude-assets/skills/cfn-file-operations/lib/atomic-write.sh +294 -0
  171. package/claude-assets/skills/cfn-file-operations/lib/lock.sh +361 -0
  172. package/claude-assets/skills/cfn-file-operations/test.sh +369 -0
  173. package/claude-assets/skills/cfn-log-operations/SKILL.md +308 -0
  174. package/claude-assets/skills/cfn-log-operations/execute.sh +420 -0
  175. package/claude-assets/skills/cfn-log-operations/lib/rotate.sh +406 -0
  176. package/claude-assets/skills/cfn-log-operations/lib/search.sh +448 -0
  177. package/claude-assets/skills/cfn-log-operations/test.sh +394 -0
  178. package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +550 -46
  179. package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +277 -0
  180. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +238 -29
  181. package/claude-assets/skills/cfn-loop-orchestration/security_utils.sh +24 -0
  182. package/claude-assets/skills/cfn-loop-orchestration/test-iteration-context-injection.sh +366 -0
  183. package/claude-assets/skills/cfn-parameterized-queries/SKILL.md +339 -0
  184. package/claude-assets/skills/cfn-playbook/query-playbook.sh +19 -15
  185. package/claude-assets/skills/cfn-playbook/update-playbook.sh +25 -14
  186. package/claude-assets/skills/cfn-process-instrumentation/instrument-process.sh +44 -0
  187. package/claude-assets/skills/cfn-promotion/SKILL.md +305 -0
  188. package/claude-assets/skills/cfn-redis-coordination/CENTRALIZED_REDIS_WRAPPER.md +319 -0
  189. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh +4 -0
  190. package/claude-assets/skills/cfn-redis-coordination/agent-log.sh.bak +124 -0
  191. package/claude-assets/skills/cfn-redis-coordination/agent-recovery.sh +2 -2
  192. package/claude-assets/skills/cfn-redis-coordination/collect-confidence-scores.sh +30 -0
  193. package/claude-assets/skills/cfn-redis-coordination/get-context.sh +33 -0
  194. package/claude-assets/skills/cfn-redis-coordination/get-success-criteria.sh +54 -0
  195. package/claude-assets/skills/cfn-redis-coordination/invoke-waiting-mode.sh +6 -2
  196. package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +24 -3
  197. package/claude-assets/skills/cfn-redis-coordination/redis-functions.sh +34 -0
  198. package/claude-assets/skills/cfn-redis-coordination/report-completion.sh +24 -31
  199. package/claude-assets/skills/cfn-redis-coordination/store-context.sh +4 -0
  200. package/claude-assets/skills/cfn-redis-coordination/store-success-criteria.sh +85 -0
  201. package/claude-assets/skills/cfn-redis-coordination/update-all-scripts.sh +67 -0
  202. package/claude-assets/skills/cfn-skill-loader/SKILL.md +466 -0
  203. package/claude-assets/skills/cfn-skill-loader/execute.sh +344 -0
  204. package/claude-assets/skills/cfn-sqlite-memory/ttl-cleanup.sh +17 -25
  205. package/claude-assets/skills/cfn-task-audit/get-audit-data.sh +42 -21
  206. package/claude-assets/skills/cfn-task-audit/store-task-audit.sh +17 -10
  207. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh +17 -14
  208. package/claude-assets/skills/cfn-test-runner/detect-regressions.sh.backup-1763392821 +55 -0
  209. package/claude-assets/skills/cfn-test-runner/store-benchmarks.sh +17 -19
  210. package/claude-assets/skills/cfn-transparency-middleware/test-e2e.sh +15 -0
  211. package/claude-assets/skills/cfn-transparency-middleware/tests/input-validation.sh +15 -0
  212. package/claude-assets/skills/cfn-utilities/SKILL.md +237 -0
  213. package/claude-assets/skills/cfn-utilities/execute.sh +32 -0
  214. package/claude-assets/skills/cfn-utilities/lib/errors.sh +56 -0
  215. package/claude-assets/skills/cfn-utilities/lib/file-ops.sh +164 -0
  216. package/claude-assets/skills/cfn-utilities/lib/logging.sh +77 -0
  217. package/claude-assets/skills/cfn-utilities/lib/retry.sh +127 -0
  218. package/claude-assets/skills/cfn-utilities/test.sh +317 -0
  219. package/claude-assets/skills/integration/agent-handoff.sh +62 -64
  220. package/claude-assets/skills/json-validation/SKILL.md +431 -0
  221. package/claude-assets/skills/json-validation/test-validate-success-criteria.sh +421 -0
  222. package/claude-assets/skills/json-validation/validate-success-criteria.sh +197 -0
  223. package/claude-assets/skills/redis-coordination/validate-parameters.sh +34 -0
  224. package/claude-assets/skills/workflow-codification/DEPLOY_QUICK_REFERENCE.md +106 -0
  225. package/claude-assets/skills/workflow-codification/PROPAGATE_UPDATE_QUICK_REFERENCE.md +366 -0
  226. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh +481 -0
  227. package/claude-assets/skills/workflow-codification/deploy-approved-skill.sh.backup-1763392820 +512 -0
  228. package/claude-assets/skills/workflow-codification/lib/security-utils.sh +204 -0
  229. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh +648 -0
  230. package/claude-assets/skills/workflow-codification/propagate-skill-update.sh.backup-1763392820 +664 -0
  231. package/claude-assets/skills/workflow-codification/test-integration.sh +15 -0
  232. package/claude-assets/skills/workflow-codification/test-metadata-update.sh +350 -0
  233. package/claude-assets/skills/workflow-codification/track-cost-savings.sh +55 -14
  234. package/claude-assets/skills/workflow-codification/track-cost-savings.sh.backup-1763392821 +445 -0
  235. package/claude-assets/skills/workflow-codification/track-edge-case.sh +27 -60
  236. package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
  237. package/dist/ace/ace-curator.js +10 -2
  238. package/dist/ace/ace-curator.js.map +1 -1
  239. package/dist/ace/ace-generator.js +4 -0
  240. package/dist/ace/ace-generator.js.map +1 -1
  241. package/dist/ace/ace-reflector.js +1 -1
  242. package/dist/ace/ace-reflector.js.map +1 -1
  243. package/dist/ace/context-injection.js +24 -2
  244. package/dist/ace/context-injection.js.map +1 -1
  245. package/dist/agents/task-agent-integration.js +1 -1
  246. package/dist/agents/task-agent-integration.js.map +1 -1
  247. package/dist/api/health-endpoints.js +390 -0
  248. package/dist/api/health-endpoints.js.map +1 -0
  249. package/dist/cli/agent-executor.js +4 -1
  250. package/dist/cli/agent-executor.js.map +1 -1
  251. package/dist/cli/agent-prompt-builder.js +89 -1
  252. package/dist/cli/agent-prompt-builder.js.map +1 -1
  253. package/dist/cli/agent-spawn.js +130 -37
  254. package/dist/cli/agent-spawn.js.map +1 -1
  255. package/dist/cli/config-manager.js +109 -91
  256. package/dist/cli/config-manager.js.map +1 -1
  257. package/dist/cli/conversation-fork-cleanup.js +201 -0
  258. package/dist/cli/conversation-fork-cleanup.js.map +1 -0
  259. package/dist/cli/conversation-fork.js +16 -3
  260. package/dist/cli/conversation-fork.js.map +1 -1
  261. package/dist/cli/skill-cache-validator.js +412 -0
  262. package/dist/cli/skill-cache-validator.js.map +1 -0
  263. package/dist/cli/skill-cli.js +991 -0
  264. package/dist/cli/skill-cli.js.map +1 -0
  265. package/dist/cli/skill-execution-logger.js +284 -0
  266. package/dist/cli/skill-execution-logger.js.map +1 -0
  267. package/dist/cli/skill-loader.js +457 -0
  268. package/dist/cli/skill-loader.js.map +1 -0
  269. package/dist/coordination/event-bus.js +2 -2
  270. package/dist/coordination/event-bus.js.map +1 -1
  271. package/dist/coordination/fleet-manager.js +1 -1
  272. package/dist/coordination/fleet-manager.js.map +1 -1
  273. package/dist/coordination/index.js +23 -9
  274. package/dist/coordination/index.js.map +1 -1
  275. package/dist/coordination/types/fleet-manager.types.js.map +1 -1
  276. package/dist/db/migration-manager.js +483 -0
  277. package/dist/db/migration-manager.js.map +1 -0
  278. package/dist/db/skills-query.js +535 -0
  279. package/dist/db/skills-query.js.map +1 -0
  280. package/dist/integration/DatabaseHandoff.js +1 -1
  281. package/dist/integration/DatabaseHandoff.js.map +1 -1
  282. package/dist/jobs/edge-case-analyzer.js +367 -0
  283. package/dist/jobs/edge-case-analyzer.js.map +1 -0
  284. package/dist/jobs/promotion-sla-enforcer.js +288 -0
  285. package/dist/jobs/promotion-sla-enforcer.js.map +1 -0
  286. package/dist/lib/agent-output-parser.js.map +1 -1
  287. package/dist/lib/agent-output-validator.js.map +1 -1
  288. package/dist/lib/agent-workspace.js +281 -0
  289. package/dist/lib/agent-workspace.js.map +1 -0
  290. package/dist/lib/atomic-file-writer.js +377 -0
  291. package/dist/lib/atomic-file-writer.js.map +1 -0
  292. package/dist/lib/backup-manager.js +779 -0
  293. package/dist/lib/backup-manager.js.map +1 -0
  294. package/dist/lib/checkpoint-manager.js +837 -0
  295. package/dist/lib/checkpoint-manager.js.map +1 -0
  296. package/dist/lib/circuit-breaker.js +340 -0
  297. package/dist/lib/circuit-breaker.js.map +1 -0
  298. package/dist/lib/completion-signal-handler.js +243 -0
  299. package/dist/lib/completion-signal-handler.js.map +1 -0
  300. package/dist/lib/config-manager.js +312 -0
  301. package/dist/lib/config-manager.js.map +1 -0
  302. package/dist/lib/config-migrator.js +386 -0
  303. package/dist/lib/config-migrator.js.map +1 -0
  304. package/dist/lib/config-validator.js.map +1 -1
  305. package/dist/lib/correlation-cache.js +311 -0
  306. package/dist/lib/correlation-cache.js.map +1 -0
  307. package/dist/lib/correlation.js +263 -0
  308. package/dist/lib/correlation.js.map +1 -0
  309. package/dist/lib/database-service/connection-pool-manager.js +520 -0
  310. package/dist/lib/database-service/connection-pool-manager.js.map +1 -0
  311. package/dist/lib/database-service/correlation.js +329 -0
  312. package/dist/lib/database-service/correlation.js.map +1 -0
  313. package/dist/lib/database-service/errors.js +120 -0
  314. package/dist/lib/database-service/errors.js.map +1 -0
  315. package/dist/lib/database-service/index.js +168 -0
  316. package/dist/lib/database-service/index.js.map +1 -0
  317. package/dist/lib/database-service/postgres-adapter.js +526 -0
  318. package/dist/lib/database-service/postgres-adapter.js.map +1 -0
  319. package/dist/lib/database-service/redis-adapter.js +360 -0
  320. package/dist/lib/database-service/redis-adapter.js.map +1 -0
  321. package/dist/lib/database-service/sqlite-adapter.js +544 -0
  322. package/dist/lib/database-service/sqlite-adapter.js.map +1 -0
  323. package/dist/lib/database-service/transaction-manager.js +773 -0
  324. package/dist/lib/database-service/transaction-manager.js.map +1 -0
  325. package/dist/lib/database-service/types.js +23 -0
  326. package/dist/lib/database-service/types.js.map +1 -0
  327. package/dist/lib/deadlock-resolver.js +292 -0
  328. package/dist/lib/deadlock-resolver.js.map +1 -0
  329. package/dist/lib/distributed-lock.js +451 -0
  330. package/dist/lib/distributed-lock.js.map +1 -0
  331. package/dist/lib/edge-case-deduplicator.js +227 -0
  332. package/dist/lib/edge-case-deduplicator.js.map +1 -0
  333. package/dist/lib/encryption-manager.js +322 -0
  334. package/dist/lib/encryption-manager.js.map +1 -0
  335. package/dist/lib/error-aggregator.js +234 -0
  336. package/dist/lib/error-aggregator.js.map +1 -0
  337. package/dist/lib/errors.js +287 -0
  338. package/dist/lib/errors.js.map +1 -0
  339. package/dist/lib/file-lock-manager.js +578 -0
  340. package/dist/lib/file-lock-manager.js.map +1 -0
  341. package/dist/lib/file-operations.js +367 -0
  342. package/dist/lib/file-operations.js.map +1 -0
  343. package/dist/lib/idempotent-write.js +237 -0
  344. package/dist/lib/idempotent-write.js.map +1 -0
  345. package/dist/lib/integration-schema-validator.js +522 -0
  346. package/dist/lib/integration-schema-validator.js.map +1 -0
  347. package/dist/lib/lock-health-monitor.js +298 -0
  348. package/dist/lib/lock-health-monitor.js.map +1 -0
  349. package/dist/lib/log-shipper.js +422 -0
  350. package/dist/lib/log-shipper.js.map +1 -0
  351. package/dist/lib/logging.js +146 -0
  352. package/dist/lib/logging.js.map +1 -0
  353. package/dist/lib/message-deduplicator.js +439 -0
  354. package/dist/lib/message-deduplicator.js.map +1 -0
  355. package/dist/lib/multi-system-query.js +604 -0
  356. package/dist/lib/multi-system-query.js.map +1 -0
  357. package/dist/lib/orphan-detector.js +332 -0
  358. package/dist/lib/orphan-detector.js.map +1 -0
  359. package/dist/lib/password-generator.js +166 -0
  360. package/dist/lib/password-generator.js.map +1 -0
  361. package/dist/lib/path-validator.js +429 -0
  362. package/dist/lib/path-validator.js.map +1 -0
  363. package/dist/lib/query-translator.js +905 -0
  364. package/dist/lib/query-translator.js.map +1 -0
  365. package/dist/lib/queue-recovery.js +469 -0
  366. package/dist/lib/queue-recovery.js.map +1 -0
  367. package/dist/lib/redis-queue-manager.js +512 -0
  368. package/dist/lib/redis-queue-manager.js.map +1 -0
  369. package/dist/lib/reflection-archiver.js +272 -0
  370. package/dist/lib/reflection-archiver.js.map +1 -0
  371. package/dist/lib/retry-manager.js +453 -0
  372. package/dist/lib/retry-manager.js.map +1 -0
  373. package/dist/lib/retry.js +262 -0
  374. package/dist/lib/retry.js.map +1 -0
  375. package/dist/lib/schema-transform.js +695 -0
  376. package/dist/lib/schema-transform.js.map +1 -0
  377. package/dist/lib/schema-validator.js +491 -0
  378. package/dist/lib/schema-validator.js.map +1 -0
  379. package/dist/lib/skill-cache.js +297 -0
  380. package/dist/lib/skill-cache.js.map +1 -0
  381. package/dist/lib/skill-content-manager.js +337 -0
  382. package/dist/lib/skill-content-manager.js.map +1 -0
  383. package/dist/lib/skill-frontmatter-parser.js +237 -0
  384. package/dist/lib/skill-frontmatter-parser.js.map +1 -0
  385. package/dist/lib/skill-git-integration.js +275 -0
  386. package/dist/lib/skill-git-integration.js.map +1 -0
  387. package/dist/lib/skill-markdown-validator.js +396 -0
  388. package/dist/lib/skill-markdown-validator.js.map +1 -0
  389. package/dist/lib/skill-output-parser.js +312 -0
  390. package/dist/lib/skill-output-parser.js.map +1 -0
  391. package/dist/lib/unified-query-api.js +467 -0
  392. package/dist/lib/unified-query-api.js.map +1 -0
  393. package/dist/middleware/auth-middleware.js +350 -0
  394. package/dist/middleware/auth-middleware.js.map +1 -0
  395. package/dist/middleware/schema-validation.js +347 -0
  396. package/dist/middleware/schema-validation.js.map +1 -0
  397. package/dist/providers/anthropic-provider.js +1 -1
  398. package/dist/providers/anthropic-provider.js.map +1 -1
  399. package/dist/providers/provider-factory.js +2 -2
  400. package/dist/providers/provider-factory.js.map +1 -1
  401. package/dist/services/edge-case-analyzer.js +321 -0
  402. package/dist/services/edge-case-analyzer.js.map +1 -0
  403. package/dist/services/edge-case-deduplicator.js +266 -0
  404. package/dist/services/edge-case-deduplicator.js.map +1 -0
  405. package/dist/services/edge-case-detector.js +337 -0
  406. package/dist/services/edge-case-detector.js.map +1 -0
  407. package/dist/services/edge-case-tracker.js +547 -0
  408. package/dist/services/edge-case-tracker.js.map +1 -0
  409. package/dist/services/health-check-system.js +586 -0
  410. package/dist/services/health-check-system.js.map +1 -0
  411. package/dist/services/metrics-logger.js +412 -0
  412. package/dist/services/metrics-logger.js.map +1 -0
  413. package/dist/services/patch-generator.js +378 -0
  414. package/dist/services/patch-generator.js.map +1 -0
  415. package/dist/services/patch-validator.js +337 -0
  416. package/dist/services/patch-validator.js.map +1 -0
  417. package/dist/services/performance-monitor.js +811 -0
  418. package/dist/services/performance-monitor.js.map +1 -0
  419. package/dist/services/promotion-pipeline.js +918 -0
  420. package/dist/services/promotion-pipeline.js.map +1 -0
  421. package/dist/services/promotion-validator.js +394 -0
  422. package/dist/services/promotion-validator.js.map +1 -0
  423. package/dist/services/reflection-logger.js +388 -0
  424. package/dist/services/reflection-logger.js.map +1 -0
  425. package/dist/services/skill-deployment.js +472 -0
  426. package/dist/services/skill-deployment.js.map +1 -0
  427. package/dist/services/skill-loader.js +427 -0
  428. package/dist/services/skill-loader.js.map +1 -0
  429. package/dist/services/skill-promotion.js +372 -0
  430. package/dist/services/skill-promotion.js.map +1 -0
  431. package/dist/services/skill-validator.js +454 -0
  432. package/dist/services/skill-validator.js.map +1 -0
  433. package/dist/services/skill-versioning.js +244 -0
  434. package/dist/services/skill-versioning.js.map +1 -0
  435. package/dist/services/workspace-supervisor.js +597 -0
  436. package/dist/services/workspace-supervisor.js.map +1 -0
  437. package/dist/types/edge-case.js +45 -0
  438. package/dist/types/edge-case.js.map +1 -0
  439. package/docs/BUG_19_MEMORY_LEAK_TASK_MODE.md +405 -0
  440. package/docs/MEMORY_CLEANUP_GUIDE.md +358 -0
  441. package/docs/MEMORY_LEAK_FIX_SUMMARY.md +322 -0
  442. package/docs/REDIS_CLEANUP_EXECUTIVE_SUMMARY.md +319 -0
  443. package/docs/REDIS_CLEANUP_VERIFICATION_REPORT.md +574 -0
  444. package/package.json +35 -4
  445. package/readme/README.md +53 -5
  446. package/scripts/backup-cleanup.sh +627 -0
  447. package/scripts/cleanup-workspaces.sh +412 -0
  448. package/scripts/cleanup-yaml-configs.sh +141 -0
  449. package/scripts/deploy-approved-skills.sh +263 -0
  450. package/scripts/health-check.sh +447 -0
  451. package/scripts/log-aggregator.sh +554 -0
  452. package/scripts/log-monitor.sh +629 -0
  453. package/scripts/manage-agent-workspaces.sh +434 -0
  454. package/scripts/migrate-schema.sh +533 -0
  455. package/scripts/promote-staged-skills.sh +423 -0
  456. package/scripts/verify-no-secrets.sh +88 -35
  457. package/scripts/verify-redis-cleanup.sh +173 -0
  458. package/tests/README.md +84 -0
  459. package/tests/test-memory-leak-task-mode.sh +435 -0
  460. package/.claude/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  461. package/.claude/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  462. package/.claude/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  463. package/.claude/skills/agent-lifecycle/SKILL.md +0 -60
  464. package/.claude/skills/agent-lifecycle/execute-lifecycle-hook.sh +0 -573
  465. package/.claude/skills/agent-lifecycle/simple-audit.sh +0 -31
  466. package/.claude/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  467. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
  468. package/README.md.backup_before_replace +0 -781
  469. package/claude-assets/cfn-extras/agents/deprecated-coordinators/adaptive-coordinator.md.backup +0 -161
  470. package/claude-assets/cfn-extras/agents/deprecated-coordinators/blocking-coordinator-example.md.backup +0 -728
  471. package/claude-assets/cfn-extras/agents/deprecated-coordinators/mesh-coordinator.md.backup +0 -131
  472. package/claude-assets/skills/cfn-agent-spawning/spawn-agent.sh.backup +0 -273
  473. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh.backup +0 -949
@@ -0,0 +1,779 @@
1
+ /**
2
+ * Unified Backup & Restore Manager
3
+ *
4
+ * Centralized backup and restore system for all critical file operations.
5
+ * Part of Task 4.3: Unified Backup & Restore System
6
+ *
7
+ * Features:
8
+ * - Multiple backup types (pre-edit, checkpoint, manual)
9
+ * - SQLite metadata storage with queryability
10
+ * - Restore operations (latest, by timestamp, by hash)
11
+ * - Restore verification with hash comparison
12
+ * - Dry-run mode for restore preview
13
+ * - Automatic rollback on verification failure
14
+ * - Rate limiting for restore operations
15
+ * - Comprehensive audit trail
16
+ * - Disk usage monitoring
17
+ * - Automatic cleanup based on TTL
18
+ * - Integration with FileLockManager
19
+ *
20
+ * Usage:
21
+ * const manager = new BackupManager();
22
+ * const backup = await manager.createBackup('/path/to/file.txt', {
23
+ * agentId: 'backend-dev-001',
24
+ * backupType: 'pre-edit'
25
+ * });
26
+ *
27
+ * // Restore latest backup
28
+ * await manager.restoreLatest('/path/to/file.txt', {
29
+ * agentId: 'backend-dev-001',
30
+ * verify: true
31
+ * });
32
+ */ import * as fs from 'fs';
33
+ import * as path from 'path';
34
+ import * as crypto from 'crypto';
35
+ import { promisify } from 'util';
36
+ import { randomUUID } from 'crypto';
37
+ import Database from 'better-sqlite3';
38
+ import { createLogger } from './logging.js';
39
+ import { createError, ErrorCode, StandardError } from './errors.js';
40
+ import { getFileLockManager } from './file-lock-manager.js';
41
+ import { withFileSystemRetry } from './retry-manager.js';
42
+ import { getEncryptionManager } from './encryption-manager.js';
43
+ const logger = createLogger('backup-manager');
44
+ const fsReadFile = promisify(fs.readFile);
45
+ const fsWriteFile = promisify(fs.writeFile);
46
+ const fsCopyFile = promisify(fs.copyFile);
47
+ const fsStat = promisify(fs.stat);
48
+ const fsMkdir = promisify(fs.mkdir);
49
+ const fsAccess = promisify(fs.access);
50
+ const fsReaddir = promisify(fs.readdir);
51
+ const fsUnlink = promisify(fs.unlink);
52
+ /**
53
+ * Backup type classification
54
+ */ export var BackupType = /*#__PURE__*/ function(BackupType) {
55
+ BackupType["PRE_EDIT"] = "pre-edit";
56
+ BackupType["CHECKPOINT"] = "checkpoint";
57
+ BackupType["MANUAL"] = "manual";
58
+ return BackupType;
59
+ }({});
60
+ /**
61
+ * Unified Backup & Restore Manager
62
+ */ export class BackupManager {
63
+ db;
64
+ lockManager;
65
+ encryptionManager;
66
+ backupDir;
67
+ defaultTtlMs;
68
+ rateLimitConfig;
69
+ projectRoot;
70
+ constructor(config = {}){
71
+ this.projectRoot = config.projectRoot || process.cwd();
72
+ this.backupDir = config.backupDir || path.join(this.projectRoot, '.backups');
73
+ this.defaultTtlMs = config.defaultTtlMs || 24 * 60 * 60 * 1000; // 24 hours
74
+ this.rateLimitConfig = config.rateLimit || {
75
+ maxRestoresPerHour: 100
76
+ };
77
+ const dbPath = config.dbPath || path.join(this.projectRoot, 'claude-assets/skills/cfn-redis-coordination/data/backups.db');
78
+ // Initialize database
79
+ this.db = this.initializeDatabase(dbPath);
80
+ // Initialize file lock manager
81
+ this.lockManager = getFileLockManager();
82
+ // Initialize encryption manager (CVSS 7.2 mitigation)
83
+ this.encryptionManager = getEncryptionManager();
84
+ // Ensure backup directory exists
85
+ this.ensureBackupDirectory();
86
+ logger.info('Backup manager initialized', {
87
+ backupDir: this.backupDir,
88
+ dbPath,
89
+ defaultTtlMs: this.defaultTtlMs,
90
+ encryptionEnabled: this.encryptionManager.isEnabled()
91
+ });
92
+ }
93
+ /**
94
+ * Create a backup of a file
95
+ *
96
+ * @param filePath - Path to file to backup
97
+ * @param options - Backup options
98
+ * @returns Backup instance
99
+ */ async createBackup(filePath, options) {
100
+ const startTime = Date.now();
101
+ const absolutePath = path.resolve(filePath);
102
+ logger.info('Creating backup', {
103
+ filePath: absolutePath,
104
+ agentId: options.agentId,
105
+ backupType: options.backupType
106
+ });
107
+ // Acquire file lock
108
+ const lock = await this.lockManager.acquireLock(absolutePath, {
109
+ agentId: options.agentId,
110
+ timeout: 30000
111
+ });
112
+ try {
113
+ // Check if file exists
114
+ const exists = await this.fileExists(absolutePath);
115
+ if (!exists) {
116
+ throw createError(ErrorCode.FILE_NOT_FOUND, `File does not exist: ${absolutePath}`, {
117
+ filePath: absolutePath
118
+ });
119
+ }
120
+ // Read file and calculate hash
121
+ const fileContent = await fsReadFile(absolutePath);
122
+ const originalHash = this.calculateHash(fileContent);
123
+ const fileSize = fileContent.length;
124
+ // Create backup directory structure
125
+ const timestamp = Date.now();
126
+ const backupPath = this.getBackupPath(options.agentId, timestamp, originalHash);
127
+ await this.ensureDirectory(path.dirname(backupPath));
128
+ // Copy file to backup location with retry logic for transient failures
129
+ await withFileSystemRetry(async ()=>{
130
+ await fsCopyFile(absolutePath, backupPath);
131
+ });
132
+ // Verify backup with retry logic
133
+ const backupContent = await withFileSystemRetry(async ()=>{
134
+ return await fsReadFile(backupPath);
135
+ });
136
+ const backupHash = this.calculateHash(backupContent);
137
+ if (!this.constantTimeHashCompare(originalHash, backupHash)) {
138
+ // Cleanup failed backup
139
+ await this.safeUnlink(backupPath);
140
+ throw createError(ErrorCode.VALIDATION_FAILED, 'Backup verification failed: hash mismatch', {
141
+ originalHash,
142
+ backupHash,
143
+ filePath: absolutePath
144
+ });
145
+ }
146
+ // Calculate expiration
147
+ const ttlMs = options.ttlMs || this.defaultTtlMs;
148
+ const expiresAt = new Date(Date.now() + ttlMs);
149
+ // Store metadata in database
150
+ const backupId = randomUUID();
151
+ const backup = {
152
+ id: backupId,
153
+ filePath: absolutePath,
154
+ backupPath,
155
+ agentId: options.agentId,
156
+ backupType: options.backupType,
157
+ originalHash,
158
+ backupHash,
159
+ fileSize,
160
+ createdAt: new Date(),
161
+ expiresAt,
162
+ metadata: options.metadata
163
+ };
164
+ // ENCRYPTION SUPPORT (CVSS 7.2 mitigation)
165
+ let encryptionMetadata = null;
166
+ if (this.encryptionManager.isEnabled()) {
167
+ try {
168
+ const encrypted = await this.encryptionManager.encrypt(backupContent, backupId);
169
+ encryptionMetadata = encrypted.metadata;
170
+ // Write encrypted backup
171
+ await withFileSystemRetry(async ()=>{
172
+ await fsWriteFile(backupPath, encrypted.data);
173
+ });
174
+ logger.info('Backup encrypted successfully', {
175
+ backupId,
176
+ algorithm: encrypted.metadata.algorithm,
177
+ originalSize: backupContent.length,
178
+ encryptedSize: encrypted.data.length
179
+ });
180
+ } catch (encryptError) {
181
+ logger.error('Backup encryption failed', encryptError instanceof Error ? encryptError : undefined, {
182
+ backupId,
183
+ filePath: absolutePath
184
+ });
185
+ // Cleanup failed backup
186
+ await this.safeUnlink(backupPath);
187
+ throw encryptError;
188
+ }
189
+ }
190
+ this.insertBackup(backup, encryptionMetadata);
191
+ const duration = Date.now() - startTime;
192
+ logger.info('Backup created successfully', {
193
+ backupId,
194
+ filePath: absolutePath,
195
+ backupPath,
196
+ fileSize,
197
+ durationMs: duration
198
+ });
199
+ return backup;
200
+ } catch (error) {
201
+ const duration = Date.now() - startTime;
202
+ logger.error('Backup creation failed', error instanceof Error ? error : undefined, {
203
+ filePath: absolutePath,
204
+ durationMs: duration
205
+ });
206
+ // Log failed backup to audit trail
207
+ this.logAuditEntry({
208
+ backupId: null,
209
+ operation: 'create',
210
+ agentId: options.agentId,
211
+ status: 'failure',
212
+ filePath: absolutePath,
213
+ errorMessage: error instanceof Error ? error.message : String(error),
214
+ errorCode: error instanceof StandardError ? error.code : ErrorCode.UNKNOWN_ERROR,
215
+ durationMs: duration
216
+ });
217
+ throw error;
218
+ } finally{
219
+ await this.lockManager.releaseLock(lock.id);
220
+ }
221
+ }
222
+ /**
223
+ * Restore the latest backup for a file
224
+ *
225
+ * @param filePath - Path to file to restore
226
+ * @param options - Restore options
227
+ * @returns Restore result
228
+ */ async restoreLatest(filePath, options) {
229
+ const absolutePath = path.resolve(filePath);
230
+ const backup = this.getLatestBackup(absolutePath);
231
+ if (!backup) {
232
+ throw createError(ErrorCode.FILE_NOT_FOUND, `No backup found for: ${absolutePath}`, {
233
+ filePath: absolutePath
234
+ });
235
+ }
236
+ return this.restoreBackup(backup.id, options);
237
+ }
238
+ /**
239
+ * Restore backup by timestamp
240
+ *
241
+ * @param filePath - Path to file
242
+ * @param timestamp - Backup timestamp
243
+ * @param options - Restore options
244
+ * @returns Restore result
245
+ */ async restoreByTimestamp(filePath, timestamp, options) {
246
+ const absolutePath = path.resolve(filePath);
247
+ const backup = this.getBackupByTimestamp(absolutePath, timestamp);
248
+ if (!backup) {
249
+ throw createError(ErrorCode.FILE_NOT_FOUND, `No backup found for: ${absolutePath} at timestamp ${timestamp.toISOString()}`, {
250
+ filePath: absolutePath,
251
+ timestamp: timestamp.toISOString()
252
+ });
253
+ }
254
+ return this.restoreBackup(backup.id, options);
255
+ }
256
+ /**
257
+ * Restore backup by hash
258
+ *
259
+ * @param filePath - Path to file
260
+ * @param hash - File hash
261
+ * @param options - Restore options
262
+ * @returns Restore result
263
+ */ async restoreByHash(filePath, hash, options) {
264
+ const absolutePath = path.resolve(filePath);
265
+ const backup = this.getBackupByHash(absolutePath, hash);
266
+ if (!backup) {
267
+ throw createError(ErrorCode.FILE_NOT_FOUND, `No backup found for: ${absolutePath} with hash ${hash}`, {
268
+ filePath: absolutePath,
269
+ hash
270
+ });
271
+ }
272
+ return this.restoreBackup(backup.id, options);
273
+ }
274
+ /**
275
+ * Restore a specific backup by ID
276
+ *
277
+ * @param backupId - Backup ID
278
+ * @param options - Restore options
279
+ * @returns Restore result
280
+ */ async restoreBackup(backupId, options) {
281
+ const startTime = Date.now();
282
+ const verify = options.verify !== false;
283
+ const dryRun = options.dryRun || false;
284
+ const force = options.force || false;
285
+ const createBackupBeforeRestore = options.createBackupBeforeRestore !== false;
286
+ logger.info('Restoring backup', {
287
+ backupId,
288
+ agentId: options.agentId,
289
+ verify,
290
+ dryRun
291
+ });
292
+ // Get backup metadata
293
+ const metadata = this.getBackupMetadata(backupId);
294
+ if (!metadata) {
295
+ throw createError(ErrorCode.FILE_NOT_FOUND, `Backup not found: ${backupId}`, {
296
+ backupId
297
+ });
298
+ }
299
+ // Check rate limit
300
+ if (!force && !dryRun) {
301
+ const rateLimitOk = this.checkRateLimit(options.agentId);
302
+ if (!rateLimitOk) {
303
+ throw createError(ErrorCode.LOCK_TIMEOUT, 'Restore rate limit exceeded', {
304
+ agentId: options.agentId,
305
+ maxRestoresPerHour: this.rateLimitConfig.maxRestoresPerHour
306
+ });
307
+ }
308
+ }
309
+ // Verify backup file exists
310
+ const backupExists = await this.fileExists(metadata.backupPath);
311
+ if (!backupExists) {
312
+ throw createError(ErrorCode.FILE_NOT_FOUND, `Backup file not found: ${metadata.backupPath}`, {
313
+ backupId,
314
+ backupPath: metadata.backupPath
315
+ });
316
+ }
317
+ // Dry-run mode: just verify and return
318
+ if (dryRun) {
319
+ const backupContent = await fsReadFile(metadata.backupPath);
320
+ const verificationHash = this.calculateHash(backupContent);
321
+ return {
322
+ success: true,
323
+ backupId,
324
+ filePath: metadata.filePath,
325
+ backupPath: metadata.backupPath,
326
+ verified: this.constantTimeHashCompare(verificationHash, metadata.backupHash),
327
+ dryRun: true,
328
+ restoredAt: new Date(),
329
+ verificationHash,
330
+ expectedHash: metadata.backupHash
331
+ };
332
+ }
333
+ // Acquire file lock
334
+ const lock = await this.lockManager.acquireLock(metadata.filePath, {
335
+ agentId: options.agentId,
336
+ timeout: 30000
337
+ });
338
+ let rollbackBackupId;
339
+ try {
340
+ // Create backup of current file before restore
341
+ if (createBackupBeforeRestore && await this.fileExists(metadata.filePath)) {
342
+ const rollbackBackup = await this.createBackup(metadata.filePath, {
343
+ agentId: options.agentId,
344
+ backupType: "pre-edit",
345
+ metadata: {
346
+ reason: 'pre-restore-backup',
347
+ restoringBackupId: backupId
348
+ }
349
+ });
350
+ rollbackBackupId = rollbackBackup.id;
351
+ }
352
+ // DECRYPTION SUPPORT (CVSS 7.2 mitigation)
353
+ let backupDataToRestore;
354
+ if (metadata.isEncrypted && this.encryptionManager.isEnabled()) {
355
+ try {
356
+ const encryptedBackupContent = await withFileSystemRetry(async ()=>{
357
+ return await fsReadFile(metadata.backupPath);
358
+ });
359
+ const encryptedPayload = {
360
+ data: encryptedBackupContent,
361
+ metadata: {
362
+ algorithm: 'AES-256-GCM',
363
+ iv: metadata.encryptionIv,
364
+ authTag: metadata.encryptionAuthTag,
365
+ hmac: metadata.encryptionHmac,
366
+ encryptedAt: metadata.encryptedAt,
367
+ keyVersion: metadata.encryptionKeyVersion
368
+ }
369
+ };
370
+ const decryptionResult = await this.encryptionManager.decrypt(encryptedPayload, backupId);
371
+ if (!decryptionResult.integrityVerified) {
372
+ logger.warn('Backup integrity check failed during restore', {
373
+ backupId,
374
+ integrityVerified: false
375
+ });
376
+ }
377
+ backupDataToRestore = decryptionResult.data;
378
+ logger.info('Backup decrypted successfully', {
379
+ backupId,
380
+ integrityVerified: decryptionResult.integrityVerified
381
+ });
382
+ } catch (decryptError) {
383
+ logger.error('Backup decryption failed', decryptError instanceof Error ? decryptError : undefined, {
384
+ backupId,
385
+ filePath: metadata.filePath
386
+ });
387
+ throw decryptError;
388
+ }
389
+ } else {
390
+ // Load unencrypted backup
391
+ backupDataToRestore = await withFileSystemRetry(async ()=>{
392
+ return await fsReadFile(metadata.backupPath);
393
+ });
394
+ }
395
+ // Perform restore with retry logic for transient failures
396
+ await withFileSystemRetry(async ()=>{
397
+ await fsWriteFile(metadata.filePath, backupDataToRestore);
398
+ });
399
+ // Verify restore if requested
400
+ let verified = false;
401
+ let verificationHash;
402
+ if (verify) {
403
+ const restoredContent = await withFileSystemRetry(async ()=>{
404
+ return await fsReadFile(metadata.filePath);
405
+ });
406
+ verificationHash = this.calculateHash(restoredContent);
407
+ verified = this.constantTimeHashCompare(verificationHash, metadata.originalHash);
408
+ if (!verified) {
409
+ // Verification failed - rollback if we created a backup
410
+ let rollbackPerformed = false;
411
+ if (rollbackBackupId) {
412
+ try {
413
+ await this.restoreBackup(rollbackBackupId, {
414
+ agentId: options.agentId,
415
+ verify: false,
416
+ dryRun: false,
417
+ force: true,
418
+ createBackupBeforeRestore: false
419
+ });
420
+ rollbackPerformed = true;
421
+ } catch (rollbackError) {
422
+ logger.error('Rollback failed after verification failure', rollbackError instanceof Error ? rollbackError : undefined, {
423
+ backupId,
424
+ rollbackBackupId
425
+ });
426
+ }
427
+ }
428
+ throw createError(ErrorCode.VALIDATION_FAILED, 'Restore verification failed: hash mismatch', {
429
+ backupId,
430
+ filePath: metadata.filePath,
431
+ verificationHash,
432
+ expectedHash: metadata.originalHash,
433
+ rollbackPerformed
434
+ });
435
+ }
436
+ }
437
+ // Record restore in rate limit table
438
+ this.recordRestore(backupId, options.agentId, metadata.filePath);
439
+ // Log successful restore to audit trail
440
+ const duration = Date.now() - startTime;
441
+ this.logAuditEntry({
442
+ backupId,
443
+ operation: 'restore',
444
+ agentId: options.agentId,
445
+ status: 'success',
446
+ filePath: metadata.filePath,
447
+ backupPath: metadata.backupPath,
448
+ durationMs: duration,
449
+ metadata: {
450
+ verified,
451
+ rollbackBackupId
452
+ }
453
+ });
454
+ logger.info('Restore completed successfully', {
455
+ backupId,
456
+ filePath: metadata.filePath,
457
+ verified,
458
+ durationMs: duration
459
+ });
460
+ return {
461
+ success: true,
462
+ backupId,
463
+ filePath: metadata.filePath,
464
+ backupPath: metadata.backupPath,
465
+ verified,
466
+ dryRun: false,
467
+ restoredAt: new Date(),
468
+ verificationHash,
469
+ expectedHash: metadata.originalHash
470
+ };
471
+ } catch (error) {
472
+ const duration = Date.now() - startTime;
473
+ logger.error('Restore failed', error instanceof Error ? error : undefined, {
474
+ backupId,
475
+ filePath: metadata.filePath,
476
+ durationMs: duration
477
+ });
478
+ // Log failed restore to audit trail
479
+ this.logAuditEntry({
480
+ backupId,
481
+ operation: 'restore',
482
+ agentId: options.agentId,
483
+ status: 'failure',
484
+ filePath: metadata.filePath,
485
+ backupPath: metadata.backupPath,
486
+ errorMessage: error instanceof Error ? error.message : String(error),
487
+ errorCode: error instanceof StandardError ? error.code : ErrorCode.UNKNOWN_ERROR,
488
+ durationMs: duration
489
+ });
490
+ throw error;
491
+ } finally{
492
+ await this.lockManager.releaseLock(lock.id);
493
+ }
494
+ }
495
+ /**
496
+ * Get disk usage statistics
497
+ */ getDiskUsage() {
498
+ const stmt = this.db.prepare(`
499
+ SELECT
500
+ COUNT(*) as total_backups,
501
+ SUM(CASE WHEN deleted_at IS NULL AND expires_at > datetime('now') THEN 1 ELSE 0 END) as active_backups,
502
+ SUM(CASE WHEN deleted_at IS NULL AND expires_at <= datetime('now') THEN 1 ELSE 0 END) as expired_backups,
503
+ SUM(file_size) as total_size_bytes,
504
+ SUM(CASE WHEN is_compressed = 1 THEN file_size ELSE 0 END) as compressed_size_bytes,
505
+ AVG(CASE WHEN is_compressed = 1 THEN compression_ratio ELSE NULL END) as avg_compression_ratio,
506
+ MIN(created_at) as oldest_backup,
507
+ MAX(created_at) as newest_backup
508
+ FROM backups
509
+ WHERE deleted_at IS NULL
510
+ `);
511
+ const result = stmt.get();
512
+ const byTypeStmt = this.db.prepare(`
513
+ SELECT backup_type, COUNT(*) as count
514
+ FROM backups
515
+ WHERE deleted_at IS NULL
516
+ GROUP BY backup_type
517
+ `);
518
+ const byType = byTypeStmt.all();
519
+ const byAgentStmt = this.db.prepare(`
520
+ SELECT agent_id, COUNT(*) as count
521
+ FROM backups
522
+ WHERE deleted_at IS NULL
523
+ GROUP BY agent_id
524
+ `);
525
+ const byAgent = byAgentStmt.all();
526
+ return {
527
+ totalBackups: result.total_backups || 0,
528
+ activeBackups: result.active_backups || 0,
529
+ expiredBackups: result.expired_backups || 0,
530
+ totalSizeBytes: result.total_size_bytes || 0,
531
+ compressedSizeBytes: result.compressed_size_bytes || 0,
532
+ averageCompressionRatio: result.avg_compression_ratio || 0,
533
+ oldestBackupDate: result.oldest_backup ? new Date(result.oldest_backup) : null,
534
+ newestBackupDate: result.newest_backup ? new Date(result.newest_backup) : null,
535
+ backupsByType: byType.reduce((acc, row)=>{
536
+ acc[row.backup_type] = row.count;
537
+ return acc;
538
+ }, {}),
539
+ backupsByAgent: byAgent.reduce((acc, row)=>{
540
+ acc[row.agent_id] = row.count;
541
+ return acc;
542
+ }, {})
543
+ };
544
+ }
545
+ /**
546
+ * List backups for a file
547
+ */ listBackups(filePath) {
548
+ const absolutePath = path.resolve(filePath);
549
+ const stmt = this.db.prepare(`
550
+ SELECT * FROM backups
551
+ WHERE file_path = ? AND deleted_at IS NULL
552
+ ORDER BY created_at DESC
553
+ `);
554
+ return stmt.all(absolutePath);
555
+ }
556
+ /**
557
+ * Delete expired backups
558
+ */ deleteExpiredBackups() {
559
+ const expiredBackups = this.db.prepare(`
560
+ SELECT id, backup_path FROM backups
561
+ WHERE deleted_at IS NULL AND expires_at <= datetime('now')
562
+ `).all();
563
+ let deletedCount = 0;
564
+ for (const backup of expiredBackups){
565
+ try {
566
+ // Delete backup file
567
+ fs.unlinkSync(backup.backup_path);
568
+ // Mark as deleted in database
569
+ this.db.prepare(`
570
+ UPDATE backups SET deleted_at = datetime('now')
571
+ WHERE id = ?
572
+ `).run(backup.id);
573
+ deletedCount++;
574
+ } catch (error) {
575
+ logger.error('Failed to delete expired backup', error instanceof Error ? error : undefined, {
576
+ backupId: backup.id,
577
+ backupPath: backup.backup_path
578
+ });
579
+ }
580
+ }
581
+ logger.info('Expired backups deleted', {
582
+ count: deletedCount
583
+ });
584
+ return deletedCount;
585
+ }
586
+ /**
587
+ * Close database connection
588
+ */ close() {
589
+ this.db.close();
590
+ logger.info('Backup manager closed');
591
+ }
592
+ // ============================================================================
593
+ // Private Helper Methods
594
+ // ============================================================================
595
+ initializeDatabase(dbPath) {
596
+ const dbDir = path.dirname(dbPath);
597
+ if (!fs.existsSync(dbDir)) {
598
+ fs.mkdirSync(dbDir, {
599
+ recursive: true
600
+ });
601
+ }
602
+ const db = new Database(dbPath);
603
+ // Run migration
604
+ const migrationPath = path.join(this.projectRoot, 'src/db/migrations/up/004-backup-metadata-schema.sql');
605
+ if (fs.existsSync(migrationPath)) {
606
+ const migration = fs.readFileSync(migrationPath, 'utf8');
607
+ db.exec(migration);
608
+ logger.info('Database migration applied', {
609
+ migrationPath
610
+ });
611
+ }
612
+ return db;
613
+ }
614
+ ensureBackupDirectory() {
615
+ if (!fs.existsSync(this.backupDir)) {
616
+ fs.mkdirSync(this.backupDir, {
617
+ recursive: true,
618
+ mode: 0o755
619
+ });
620
+ logger.info('Created backup directory', {
621
+ directory: this.backupDir
622
+ });
623
+ }
624
+ }
625
+ async ensureDirectory(dirPath) {
626
+ try {
627
+ await fsMkdir(dirPath, {
628
+ recursive: true,
629
+ mode: 0o755
630
+ });
631
+ } catch (error) {
632
+ // Ignore if directory already exists
633
+ if (error.code !== 'EEXIST') {
634
+ throw error;
635
+ }
636
+ }
637
+ }
638
+ getBackupPath(agentId, timestamp, hash) {
639
+ return path.join(this.backupDir, agentId, `${timestamp}_${hash}`, 'original');
640
+ }
641
+ calculateHash(content) {
642
+ return crypto.createHash('sha256').update(content).digest('hex');
643
+ }
644
+ /**
645
+ * Constant-time hash comparison to prevent timing attacks
646
+ * @param hash1 First hash (hex string)
647
+ * @param hash2 Second hash (hex string)
648
+ * @returns true if hashes match, false otherwise
649
+ */ constantTimeHashCompare(hash1, hash2) {
650
+ try {
651
+ // Convert hex strings to buffers
652
+ const buffer1 = Buffer.from(hash1, 'hex');
653
+ const buffer2 = Buffer.from(hash2, 'hex');
654
+ // Length check (not timing-sensitive as length is not secret)
655
+ if (buffer1.length !== buffer2.length) {
656
+ return false;
657
+ }
658
+ // Constant-time comparison
659
+ return crypto.timingSafeEqual(buffer1, buffer2);
660
+ } catch (error) {
661
+ // Handle Buffer conversion failures
662
+ logger.error('Hash comparison failed', error instanceof Error ? error : undefined, {
663
+ hash1Length: hash1?.length,
664
+ hash2Length: hash2?.length
665
+ });
666
+ return false;
667
+ }
668
+ }
669
+ async fileExists(filePath) {
670
+ try {
671
+ await fsAccess(filePath, fs.constants.F_OK);
672
+ return true;
673
+ } catch {
674
+ return false;
675
+ }
676
+ }
677
+ async safeUnlink(filePath) {
678
+ try {
679
+ await fsUnlink(filePath);
680
+ } catch {
681
+ // Ignore errors
682
+ }
683
+ }
684
+ insertBackup(backup, encryptionMetadata) {
685
+ const stmt = this.db.prepare(`
686
+ INSERT INTO backups (
687
+ id, agent_id, file_path, backup_path, original_hash, backup_hash,
688
+ file_size, backup_type, created_at, expires_at, metadata,
689
+ is_encrypted, encrypted_at, encryption_algorithm, encryption_iv,
690
+ encryption_auth_tag, encryption_hmac, encryption_key_version
691
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
692
+ `);
693
+ stmt.run(backup.id, backup.agentId, backup.filePath, backup.backupPath, backup.originalHash, backup.backupHash, backup.fileSize, backup.backupType, backup.createdAt.toISOString(), backup.expiresAt.toISOString(), backup.metadata ? JSON.stringify(backup.metadata) : null, // ENCRYPTION SUPPORT (CVSS 7.2 mitigation)
694
+ encryptionMetadata ? 1 : 0, encryptionMetadata ? encryptionMetadata.encryptedAt : null, encryptionMetadata ? encryptionMetadata.algorithm : null, encryptionMetadata ? encryptionMetadata.iv : null, encryptionMetadata ? encryptionMetadata.authTag : null, encryptionMetadata ? encryptionMetadata.hmac : null, encryptionMetadata ? encryptionMetadata.keyVersion : null);
695
+ }
696
+ getBackupMetadata(backupId) {
697
+ const stmt = this.db.prepare(`
698
+ SELECT * FROM backups WHERE id = ? AND deleted_at IS NULL
699
+ `);
700
+ return stmt.get(backupId) || null;
701
+ }
702
+ getLatestBackup(filePath) {
703
+ const stmt = this.db.prepare(`
704
+ SELECT * FROM backups
705
+ WHERE file_path = ? AND deleted_at IS NULL
706
+ ORDER BY created_at DESC
707
+ LIMIT 1
708
+ `);
709
+ return stmt.get(filePath) || null;
710
+ }
711
+ getBackupByTimestamp(filePath, timestamp) {
712
+ const stmt = this.db.prepare(`
713
+ SELECT * FROM backups
714
+ WHERE file_path = ? AND deleted_at IS NULL AND created_at <= ?
715
+ ORDER BY created_at DESC
716
+ LIMIT 1
717
+ `);
718
+ return stmt.get(filePath, timestamp.toISOString()) || null;
719
+ }
720
+ getBackupByHash(filePath, hash) {
721
+ const stmt = this.db.prepare(`
722
+ SELECT * FROM backups
723
+ WHERE file_path = ? AND original_hash = ? AND deleted_at IS NULL
724
+ ORDER BY created_at DESC
725
+ LIMIT 1
726
+ `);
727
+ return stmt.get(filePath, hash) || null;
728
+ }
729
+ checkRateLimit(agentId) {
730
+ const stmt = this.db.prepare(`
731
+ SELECT COUNT(*) as count
732
+ FROM restore_rate_limits
733
+ WHERE agent_id = ? AND restored_at > datetime('now', '-1 hour')
734
+ `);
735
+ const result = stmt.get(agentId);
736
+ return result.count < this.rateLimitConfig.maxRestoresPerHour;
737
+ }
738
+ recordRestore(backupId, agentId, filePath) {
739
+ const stmt = this.db.prepare(`
740
+ INSERT INTO restore_rate_limits (id, backup_id, agent_id, file_path, restored_at)
741
+ VALUES (?, ?, ?, ?, datetime('now'))
742
+ `);
743
+ stmt.run(randomUUID(), backupId, agentId, filePath);
744
+ }
745
+ logAuditEntry(entry) {
746
+ const stmt = this.db.prepare(`
747
+ INSERT INTO backup_audit_log (
748
+ id, backup_id, operation, agent_id, status, file_path, backup_path,
749
+ timestamp, duration_ms, error_message, error_code, metadata
750
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'), ?, ?, ?, ?)
751
+ `);
752
+ stmt.run(randomUUID(), entry.backupId, entry.operation, entry.agentId, entry.status, entry.filePath, entry.backupPath || null, entry.durationMs || null, entry.errorMessage || null, entry.errorCode || null, entry.metadata ? JSON.stringify(entry.metadata) : null);
753
+ }
754
+ }
755
+ /**
756
+ * Singleton instance
757
+ */ let defaultManager = null;
758
+ /**
759
+ * Get the default backup manager instance
760
+ */ export function getBackupManager(config) {
761
+ if (!defaultManager) {
762
+ defaultManager = new BackupManager(config);
763
+ }
764
+ return defaultManager;
765
+ }
766
+ /**
767
+ * Execute a function with automatic backup
768
+ *
769
+ * @param filePath - File to backup
770
+ * @param fn - Function to execute
771
+ * @param options - Backup options
772
+ * @returns Promise that resolves with function result
773
+ */ export async function withBackup(filePath, fn, options) {
774
+ const manager = getBackupManager();
775
+ await manager.createBackup(filePath, options);
776
+ return fn();
777
+ }
778
+
779
+ //# sourceMappingURL=backup-manager.js.map