claude-flow-novice 2.15.5 → 2.15.7

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 (540) hide show
  1. package/.claude/cfn-extras/.gs-api-quota.json +16 -0
  2. package/.claude/cfn-extras/.gs-progress-state.json +22 -0
  3. package/.claude/cfn-extras/GOOGLE_SHEETS_IMPLEMENTATION_SUMMARY.md +414 -0
  4. package/.claude/cfn-extras/agents/google-sheets/README.md +114 -0
  5. package/.claude/cfn-extras/agents/google-sheets/google-sheets-advanced-analytics-specialist.md +288 -0
  6. package/.claude/cfn-extras/agents/google-sheets/google-sheets-api-integrator.md +127 -0
  7. package/.claude/cfn-extras/agents/google-sheets/google-sheets-automation-scripting-specialist.md +195 -0
  8. package/.claude/cfn-extras/agents/google-sheets/google-sheets-business-validator.md +179 -0
  9. package/.claude/cfn-extras/agents/google-sheets/google-sheets-collaboration-security-specialist.md +240 -0
  10. package/.claude/cfn-extras/agents/google-sheets/google-sheets-coordinator.md +214 -0
  11. package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-transformer.md +127 -0
  12. package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-validation-quality-specialist.md +177 -0
  13. package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-validator.md +119 -0
  14. package/.claude/cfn-extras/agents/google-sheets/google-sheets-data-visualization-specialist.md +135 -0
  15. package/.claude/cfn-extras/agents/google-sheets/google-sheets-design-layout-specialist.md +109 -0
  16. package/.claude/cfn-extras/agents/google-sheets/google-sheets-formula-engineer.md +127 -0
  17. package/.claude/cfn-extras/agents/google-sheets/google-sheets-formula-engineering-specialist.md +138 -0
  18. package/.claude/cfn-extras/agents/google-sheets/google-sheets-formula-validator.md +128 -0
  19. package/.claude/cfn-extras/agents/google-sheets/google-sheets-generalist.md +645 -0
  20. package/.claude/cfn-extras/agents/google-sheets/google-sheets-integration-api-specialist.md +258 -0
  21. package/.claude/cfn-extras/agents/google-sheets/google-sheets-performance-analyst.md +125 -0
  22. package/.claude/cfn-extras/agents/google-sheets/google-sheets-performance-optimization-specialist.md +211 -0
  23. package/.claude/cfn-extras/agents/google-sheets/google-sheets-schema-designer.md +130 -0
  24. package/.claude/cfn-extras/agents/google-sheets/google-sheets-template-architecture-specialist.md +259 -0
  25. package/.claude/cfn-extras/docs/GOOGLE_SHEETS_CFN_LOOP.md +617 -0
  26. package/.claude/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +453 -0
  27. package/.claude/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +272 -0
  28. package/.claude/cfn-extras/skills/google-sheets-api-coordinator/api-call.sh +254 -0
  29. package/.claude/cfn-extras/skills/google-sheets-api-coordinator/test.sh +174 -0
  30. package/.claude/cfn-extras/skills/google-sheets-api-coordinator/validate.sh +98 -0
  31. package/.claude/cfn-extras/skills/google-sheets-decomposition/SKILL.md +269 -0
  32. package/.claude/cfn-extras/skills/google-sheets-decomposition/decompose.sh +313 -0
  33. package/.claude/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +237 -0
  34. package/.claude/cfn-extras/skills/google-sheets-formula-builder/build-formula.sh +220 -0
  35. package/.claude/cfn-extras/skills/google-sheets-formula-builder/test.sh +172 -0
  36. package/.claude/cfn-extras/skills/google-sheets-formula-builder/validate.sh +98 -0
  37. package/.claude/cfn-extras/skills/google-sheets-progress/SKILL.md +287 -0
  38. package/.claude/cfn-extras/skills/google-sheets-progress/test.sh +385 -0
  39. package/.claude/cfn-extras/skills/google-sheets-progress/track-progress.sh +516 -0
  40. package/.claude/cfn-extras/skills/google-sheets-progress/validate.sh +119 -0
  41. package/.claude/cfn-extras/skills/google-sheets-sprint-order/SKILL.md +277 -0
  42. package/.claude/cfn-extras/skills/google-sheets-sprint-order/order-sprints.sh +233 -0
  43. package/.claude/cfn-extras/skills/google-sheets-validation/SKILL.md +352 -0
  44. package/.claude/cfn-extras/skills/google-sheets-validation/test.sh +355 -0
  45. package/.claude/cfn-extras/skills/google-sheets-validation/validate-state.sh +374 -0
  46. package/.claude/cfn-extras/skills/google-sheets-validation/validate.sh +128 -0
  47. package/.claude/commands/cfn-context.md +10 -0
  48. package/.claude/commands/cfn-loop-cli.md +36 -15
  49. package/.claude/commands/google-sheets/google-sheets-loop.md +289 -0
  50. package/.claude/skills/cfn-agent-selector/SKILL.md +143 -0
  51. package/.claude/skills/cfn-agent-selector/select-agents.sh +94 -0
  52. package/.claude/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -2
  53. package/.claude/skills/cfn-docker-agent-spawning/spawn-agent.sh +21 -2
  54. package/.claude/skills/cfn-docker-loop-orchestration/orchestrate.sh +11 -5
  55. package/.claude/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +348 -0
  56. package/.claude/skills/cfn-docker-redis-coordination/README.md +294 -0
  57. package/.claude/skills/cfn-docker-redis-coordination/jest.config.js +37 -0
  58. package/.claude/skills/cfn-docker-redis-coordination/package-lock.json +5259 -0
  59. package/.claude/skills/cfn-docker-redis-coordination/package.json +40 -0
  60. package/.claude/skills/cfn-docker-redis-coordination/src/coordinator.ts +801 -0
  61. package/.claude/skills/cfn-docker-redis-coordination/src/index.ts +42 -0
  62. package/.claude/skills/cfn-docker-redis-coordination/src/types.ts +351 -0
  63. package/.claude/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +1464 -0
  64. package/.claude/skills/cfn-docker-redis-coordination/tsconfig.json +30 -0
  65. package/.claude/skills/cfn-loop-orchestration/.eslintrc.js +56 -0
  66. package/.claude/skills/cfn-loop-orchestration/.prettierrc.json +18 -0
  67. package/.claude/skills/cfn-loop-orchestration/README.md +149 -41
  68. package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +39 -577
  69. package/.claude/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +49 -270
  70. package/.claude/skills/cfn-loop-orchestration/jest.config.js +67 -0
  71. package/.claude/skills/cfn-loop-orchestration/orchestrate-wrapper.sh +268 -0
  72. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +91 -8
  73. package/.claude/skills/cfn-loop-orchestration/package-lock.json +5470 -0
  74. package/.claude/skills/cfn-loop-orchestration/package.json +49 -0
  75. package/.claude/skills/cfn-loop-orchestration/src/agent-spawner/agent-spawner.ts +34 -0
  76. package/.claude/skills/cfn-loop-orchestration/src/gate-checker/gate-checker.ts +36 -0
  77. package/.claude/skills/cfn-loop-orchestration/src/helpers/consensus.ts +87 -0
  78. package/.claude/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +115 -0
  79. package/.claude/skills/cfn-loop-orchestration/src/helpers/parse-test-results.ts +372 -0
  80. package/.claude/skills/cfn-loop-orchestration/src/index.ts +14 -0
  81. package/.claude/skills/cfn-loop-orchestration/src/orchestrator/orchestrator.ts +31 -0
  82. package/.claude/skills/cfn-loop-orchestration/src/redis/redis-coordinator.ts +72 -0
  83. package/.claude/skills/cfn-loop-orchestration/src/types.ts +188 -0
  84. package/.claude/skills/cfn-loop-orchestration/src/utils/logger.ts +32 -0
  85. package/.claude/skills/cfn-loop-orchestration/tests/consensus.test.ts +142 -0
  86. package/.claude/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +199 -0
  87. package/.claude/skills/cfn-loop-orchestration/tests/gate-check.test.ts +325 -0
  88. package/.claude/skills/cfn-loop-orchestration/tests/iteration-manager.test.ts +132 -0
  89. package/.claude/skills/cfn-loop-orchestration/tests/parse-test-results.test.ts +382 -0
  90. package/.claude/skills/cfn-loop-orchestration/tests/setup.ts +22 -0
  91. package/.claude/skills/cfn-loop-orchestration/tests/timeout-calculator.test.ts +118 -0
  92. package/.claude/skills/cfn-loop-orchestration/tests/types.test.ts +132 -0
  93. package/.claude/skills/cfn-loop-orchestration/tsconfig.json +54 -0
  94. package/.claude/skills/cfn-redis-coordination/bash-wrappers/store-context.sh +23 -0
  95. package/.claude/skills/cfn-redis-coordination/coverage/clover.xml +1447 -0
  96. package/.claude/skills/cfn-redis-coordination/coverage/coverage-final.json +13 -0
  97. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/agent-logger.ts.html +1423 -0
  98. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/agent-recovery.ts.html +1447 -0
  99. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/base.css +224 -0
  100. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/block-navigation.js +87 -0
  101. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/completion-reporter.ts.html +1273 -0
  102. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/context-manager.ts.html +1066 -0
  103. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/favicon.png +0 -0
  104. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/index.html +281 -0
  105. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/mode-detector.ts.html +550 -0
  106. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/prettify.css +1 -0
  107. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/prettify.js +2 -0
  108. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/redis-client.ts.html +2047 -0
  109. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/result-collector.ts.html +1396 -0
  110. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  111. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/sorter.js +210 -0
  112. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/swarm-manager.ts.html +1567 -0
  113. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/task-analyzer.ts.html +1297 -0
  114. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/task-executor.ts.html +1354 -0
  115. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/types.ts.html +790 -0
  116. package/.claude/skills/cfn-redis-coordination/coverage/lcov-report/waiting-coordinator.ts.html +1846 -0
  117. package/.claude/skills/cfn-redis-coordination/coverage/lcov.info +2650 -0
  118. package/.claude/skills/cfn-redis-coordination/dist/agent-logger.d.ts +92 -0
  119. package/.claude/skills/cfn-redis-coordination/dist/agent-logger.d.ts.map +1 -0
  120. package/.claude/skills/cfn-redis-coordination/dist/agent-logger.js +329 -0
  121. package/.claude/skills/cfn-redis-coordination/dist/agent-logger.js.map +1 -0
  122. package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.d.ts +75 -0
  123. package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.d.ts.map +1 -0
  124. package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.js +302 -0
  125. package/.claude/skills/cfn-redis-coordination/dist/agent-recovery.js.map +1 -0
  126. package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.d.ts +58 -0
  127. package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.d.ts.map +1 -0
  128. package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.js +237 -0
  129. package/.claude/skills/cfn-redis-coordination/dist/completion-reporter.js.map +1 -0
  130. package/.claude/skills/cfn-redis-coordination/dist/context-manager.d.ts +63 -0
  131. package/.claude/skills/cfn-redis-coordination/dist/context-manager.d.ts.map +1 -0
  132. package/.claude/skills/cfn-redis-coordination/dist/context-manager.js +230 -0
  133. package/.claude/skills/cfn-redis-coordination/dist/context-manager.js.map +1 -0
  134. package/.claude/skills/cfn-redis-coordination/dist/index.d.ts +45 -0
  135. package/.claude/skills/cfn-redis-coordination/dist/index.d.ts.map +1 -0
  136. package/.claude/skills/cfn-redis-coordination/dist/index.js +114 -0
  137. package/.claude/skills/cfn-redis-coordination/dist/index.js.map +1 -0
  138. package/.claude/skills/cfn-redis-coordination/dist/mode-detector.d.ts +31 -0
  139. package/.claude/skills/cfn-redis-coordination/dist/mode-detector.d.ts.map +1 -0
  140. package/.claude/skills/cfn-redis-coordination/dist/mode-detector.js +185 -0
  141. package/.claude/skills/cfn-redis-coordination/dist/mode-detector.js.map +1 -0
  142. package/.claude/skills/cfn-redis-coordination/dist/redis-client.d.ts +191 -0
  143. package/.claude/skills/cfn-redis-coordination/dist/redis-client.d.ts.map +1 -0
  144. package/.claude/skills/cfn-redis-coordination/dist/redis-client.js +509 -0
  145. package/.claude/skills/cfn-redis-coordination/dist/redis-client.js.map +1 -0
  146. package/.claude/skills/cfn-redis-coordination/dist/result-collector.d.ts +75 -0
  147. package/.claude/skills/cfn-redis-coordination/dist/result-collector.d.ts.map +1 -0
  148. package/.claude/skills/cfn-redis-coordination/dist/result-collector.js +281 -0
  149. package/.claude/skills/cfn-redis-coordination/dist/result-collector.js.map +1 -0
  150. package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.d.ts +75 -0
  151. package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.d.ts.map +1 -0
  152. package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.js +354 -0
  153. package/.claude/skills/cfn-redis-coordination/dist/swarm-manager.js.map +1 -0
  154. package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.d.ts +62 -0
  155. package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.d.ts.map +1 -0
  156. package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.js +305 -0
  157. package/.claude/skills/cfn-redis-coordination/dist/task-analyzer.js.map +1 -0
  158. package/.claude/skills/cfn-redis-coordination/dist/task-executor.d.ts +97 -0
  159. package/.claude/skills/cfn-redis-coordination/dist/task-executor.d.ts.map +1 -0
  160. package/.claude/skills/cfn-redis-coordination/dist/task-executor.js +283 -0
  161. package/.claude/skills/cfn-redis-coordination/dist/task-executor.js.map +1 -0
  162. package/.claude/skills/cfn-redis-coordination/dist/types.d.ts +176 -0
  163. package/.claude/skills/cfn-redis-coordination/dist/types.d.ts.map +1 -0
  164. package/.claude/skills/cfn-redis-coordination/dist/types.js +81 -0
  165. package/.claude/skills/cfn-redis-coordination/dist/types.js.map +1 -0
  166. package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts +86 -0
  167. package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts.map +1 -0
  168. package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.js +419 -0
  169. package/.claude/skills/cfn-redis-coordination/dist/waiting-coordinator.js.map +1 -0
  170. package/.claude/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +553 -0
  171. package/.claude/skills/cfn-redis-coordination/jest.config.js +23 -0
  172. package/.claude/skills/cfn-redis-coordination/package-lock.json +5272 -0
  173. package/.claude/skills/cfn-redis-coordination/package.json +45 -0
  174. package/.claude/skills/cfn-redis-coordination/redis-cli-wrapper.sh +21 -8
  175. package/.claude/skills/cfn-redis-coordination/src/agent-logger.ts +446 -0
  176. package/.claude/skills/cfn-redis-coordination/src/agent-recovery.ts +454 -0
  177. package/.claude/skills/cfn-redis-coordination/src/completion-reporter.ts +396 -0
  178. package/.claude/skills/cfn-redis-coordination/src/context-manager.ts +327 -0
  179. package/.claude/skills/cfn-redis-coordination/src/index.ts +82 -0
  180. package/.claude/skills/cfn-redis-coordination/src/mode-detector.ts +155 -0
  181. package/.claude/skills/cfn-redis-coordination/src/redis/redis-client.ts +305 -0
  182. package/.claude/skills/cfn-redis-coordination/src/redis/redis-functions.ts +283 -0
  183. package/.claude/skills/cfn-redis-coordination/src/redis-client.ts +654 -0
  184. package/.claude/skills/cfn-redis-coordination/src/result-collector.ts +437 -0
  185. package/.claude/skills/cfn-redis-coordination/src/swarm-manager.ts +494 -0
  186. package/.claude/skills/cfn-redis-coordination/src/task-analyzer.ts +404 -0
  187. package/.claude/skills/cfn-redis-coordination/src/task-executor.ts +423 -0
  188. package/.claude/skills/cfn-redis-coordination/src/types.ts +235 -0
  189. package/.claude/skills/cfn-redis-coordination/src/waiting-coordinator.ts +587 -0
  190. package/.claude/skills/cfn-redis-coordination/test-connection-attempts.js +70 -0
  191. package/.claude/skills/cfn-redis-coordination/test-mode-simple.js +121 -0
  192. package/.claude/skills/cfn-redis-coordination/test-redis-check.js +84 -0
  193. package/.claude/skills/cfn-redis-coordination/test-task-mode-redis.cjs +391 -0
  194. package/.claude/skills/cfn-redis-coordination/tests/coordination.test.ts +788 -0
  195. package/.claude/skills/cfn-redis-coordination/tsconfig.json +31 -0
  196. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +13 -72
  197. package/claude-assets/agents/cfn-dev-team/coordinators/cfn-v3-coordinator.md +172 -62
  198. package/claude-assets/agents/cfn-dev-team/coordinators/consensus-builder.md +465 -508
  199. package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +733 -743
  200. package/claude-assets/agents/cfn-dev-team/coordinators/multi-sprint-coordinator.md +13 -79
  201. package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +13 -18
  202. package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +13 -18
  203. package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +13 -18
  204. package/claude-assets/agents/cfn-dev-team/developers/backend-developer.md +15 -17
  205. package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +15 -17
  206. package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +15 -14
  207. package/claude-assets/agents/cfn-dev-team/developers/frontend/mobile-dev.md +15 -17
  208. package/claude-assets/agents/cfn-dev-team/developers/frontend/react-frontend-engineer.md +15 -17
  209. package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +15 -17
  210. package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +23 -30
  211. package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +13 -18
  212. package/claude-assets/agents/cfn-dev-team/developers/rust-developer.md +13 -18
  213. package/claude-assets/agents/cfn-dev-team/reviewers/code-reviewer.md +312 -317
  214. package/claude-assets/agents/cfn-dev-team/reviewers/quality/code-quality-validator.md +23 -20
  215. package/claude-assets/agents/cfn-dev-team/reviewers/quality/perf-analyzer.md +23 -20
  216. package/claude-assets/agents/cfn-dev-team/reviewers/quality/performance-benchmarker.md +23 -20
  217. package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +23 -20
  218. package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +16 -21
  219. package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +15 -20
  220. package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +718 -737
  221. package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +817 -828
  222. package/claude-assets/agents/cfn-dev-team/testers/interaction-tester.md +15 -20
  223. package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +8 -9
  224. package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +668 -684
  225. package/claude-assets/agents/cfn-dev-team/testers/playwright-tester.md +15 -20
  226. package/claude-assets/agents/cfn-dev-team/testers/tester.md +248 -253
  227. package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +13 -18
  228. package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +13 -18
  229. package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +13 -18
  230. package/claude-assets/agents/custom/cfn-redis-operations.md +530 -0
  231. package/claude-assets/agents/custom/cfn-system-expert.md +77 -0
  232. package/claude-assets/cfn-extras/.gs-api-quota.json +16 -0
  233. package/claude-assets/cfn-extras/.gs-progress-state.json +22 -0
  234. package/claude-assets/cfn-extras/GOOGLE_SHEETS_IMPLEMENTATION_SUMMARY.md +414 -0
  235. package/claude-assets/cfn-extras/agents/google-sheets/README.md +114 -0
  236. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-advanced-analytics-specialist.md +288 -0
  237. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-api-integrator.md +127 -0
  238. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-automation-scripting-specialist.md +195 -0
  239. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-business-validator.md +179 -0
  240. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-collaboration-security-specialist.md +240 -0
  241. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-coordinator.md +214 -0
  242. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-transformer.md +127 -0
  243. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-validation-quality-specialist.md +177 -0
  244. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-validator.md +119 -0
  245. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-data-visualization-specialist.md +135 -0
  246. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-design-layout-specialist.md +109 -0
  247. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-formula-engineer.md +127 -0
  248. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-formula-engineering-specialist.md +138 -0
  249. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-formula-validator.md +128 -0
  250. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-generalist.md +645 -0
  251. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-integration-api-specialist.md +258 -0
  252. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-performance-analyst.md +125 -0
  253. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-performance-optimization-specialist.md +211 -0
  254. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-schema-designer.md +130 -0
  255. package/claude-assets/cfn-extras/agents/google-sheets/google-sheets-template-architecture-specialist.md +259 -0
  256. package/claude-assets/cfn-extras/docs/GOOGLE_SHEETS_CFN_LOOP.md +617 -0
  257. package/claude-assets/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +453 -0
  258. package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +272 -0
  259. package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/api-call.sh +254 -0
  260. package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/test.sh +174 -0
  261. package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/validate.sh +98 -0
  262. package/claude-assets/cfn-extras/skills/google-sheets-decomposition/SKILL.md +269 -0
  263. package/claude-assets/cfn-extras/skills/google-sheets-decomposition/decompose.sh +313 -0
  264. package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +237 -0
  265. package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/build-formula.sh +220 -0
  266. package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/test.sh +172 -0
  267. package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/validate.sh +98 -0
  268. package/claude-assets/cfn-extras/skills/google-sheets-progress/SKILL.md +287 -0
  269. package/claude-assets/cfn-extras/skills/google-sheets-progress/test.sh +385 -0
  270. package/claude-assets/cfn-extras/skills/google-sheets-progress/track-progress.sh +516 -0
  271. package/claude-assets/cfn-extras/skills/google-sheets-progress/validate.sh +119 -0
  272. package/claude-assets/cfn-extras/skills/google-sheets-sprint-order/SKILL.md +277 -0
  273. package/claude-assets/cfn-extras/skills/google-sheets-sprint-order/order-sprints.sh +233 -0
  274. package/claude-assets/cfn-extras/skills/google-sheets-validation/SKILL.md +352 -0
  275. package/claude-assets/cfn-extras/skills/google-sheets-validation/test.sh +355 -0
  276. package/claude-assets/cfn-extras/skills/google-sheets-validation/validate-state.sh +374 -0
  277. package/claude-assets/cfn-extras/skills/google-sheets-validation/validate.sh +128 -0
  278. package/claude-assets/commands/cfn-context.md +10 -0
  279. package/claude-assets/commands/cfn-loop-cli.md +36 -15
  280. package/claude-assets/commands/google-sheets/google-sheets-loop.md +289 -0
  281. package/claude-assets/hooks/cfn-pre-execution/SESSION_START_README.md +87 -0
  282. package/claude-assets/hooks/cfn-pre-execution/TEST_SESSION_START.md +128 -0
  283. package/claude-assets/hooks/cfn-pre-execution/session-start-context.sh +111 -0
  284. package/claude-assets/skills/cfn-agent-selection-with-fallback/INTEGRATION_EXAMPLE.md +209 -0
  285. package/claude-assets/skills/cfn-agent-selection-with-fallback/README.md +130 -0
  286. package/claude-assets/skills/cfn-agent-selection-with-fallback/SKILL.md +243 -0
  287. package/claude-assets/skills/cfn-agent-selection-with-fallback/agent-mappings.json +142 -0
  288. package/claude-assets/skills/cfn-agent-selection-with-fallback/select-agents.sh +173 -0
  289. package/claude-assets/skills/cfn-agent-selection-with-fallback/task-classifier.sh +71 -0
  290. package/claude-assets/skills/cfn-agent-selection-with-fallback/test-agent-selection.sh +282 -0
  291. package/claude-assets/skills/cfn-agent-selector/SKILL.md +143 -0
  292. package/claude-assets/skills/cfn-agent-selector/select-agents.sh +94 -0
  293. package/claude-assets/skills/cfn-agent-spawning/get-agent-provider-env.sh +22 -2
  294. package/claude-assets/skills/cfn-docker-agent-spawning/spawn-agent.sh +21 -2
  295. package/claude-assets/skills/cfn-docker-coordination/.eslintrc.json +33 -0
  296. package/claude-assets/skills/cfn-docker-coordination/README.md +349 -0
  297. package/claude-assets/skills/cfn-docker-coordination/docker-helpers.sh +433 -0
  298. package/claude-assets/skills/cfn-docker-coordination/jest.config.js +25 -0
  299. package/claude-assets/skills/cfn-docker-coordination/package-lock.json +6827 -0
  300. package/claude-assets/skills/cfn-docker-coordination/package.json +38 -0
  301. package/claude-assets/skills/cfn-docker-coordination/src/agent-container.ts +471 -0
  302. package/claude-assets/skills/cfn-docker-coordination/src/docker-client.ts +483 -0
  303. package/claude-assets/skills/cfn-docker-coordination/src/health-checker.ts +418 -0
  304. package/claude-assets/skills/cfn-docker-coordination/src/index.ts +45 -0
  305. package/claude-assets/skills/cfn-docker-coordination/src/network-manager.ts +377 -0
  306. package/claude-assets/skills/cfn-docker-coordination/src/types.ts +412 -0
  307. package/claude-assets/skills/cfn-docker-coordination/src/volume-manager.ts +389 -0
  308. package/claude-assets/skills/cfn-docker-coordination/tests/agent-container.test.ts +379 -0
  309. package/claude-assets/skills/cfn-docker-coordination/tests/docker-client.test.ts +345 -0
  310. package/claude-assets/skills/cfn-docker-coordination/tests/health-checker.test.ts +535 -0
  311. package/claude-assets/skills/cfn-docker-coordination/tests/integration.test.ts +193 -0
  312. package/claude-assets/skills/cfn-docker-coordination/tests/network-manager.test.ts +352 -0
  313. package/claude-assets/skills/cfn-docker-coordination/tests/setup.ts +36 -0
  314. package/claude-assets/skills/cfn-docker-coordination/tsconfig.json +29 -0
  315. package/claude-assets/skills/cfn-docker-logging/INTEGRATION.md +268 -0
  316. package/claude-assets/skills/cfn-docker-logging/SAMPLE_OUTPUTS.md +237 -0
  317. package/claude-assets/skills/cfn-docker-logging/SKILL.md +442 -0
  318. package/claude-assets/skills/cfn-docker-logging/capture-container-logs.sh +120 -0
  319. package/claude-assets/skills/cfn-docker-logging/enable-logging.sh +430 -0
  320. package/claude-assets/skills/cfn-docker-logging/init-hybrid-logging.sh +210 -0
  321. package/claude-assets/skills/cfn-docker-logging/queries/analytics-summary.sh +87 -0
  322. package/claude-assets/skills/cfn-docker-logging/queries/query-agent-timeline.sh +51 -0
  323. package/claude-assets/skills/cfn-docker-logging/queries/query-consensus-history.sh +56 -0
  324. package/claude-assets/skills/cfn-docker-logging/queries/query-coordination-timeline.sh +39 -0
  325. package/claude-assets/skills/cfn-docker-logging/queries/query-failed-containers.sh +40 -0
  326. package/claude-assets/skills/cfn-docker-logging/queries/query-gate-checks.sh +39 -0
  327. package/claude-assets/skills/cfn-docker-logging/schema.sql +111 -0
  328. package/claude-assets/skills/cfn-docker-logging/sqlite-helpers.sh +240 -0
  329. package/claude-assets/skills/cfn-docker-logging/test-hybrid-logging.sh +331 -0
  330. package/claude-assets/skills/cfn-docker-loop-orchestration/orchestrate.sh +11 -5
  331. package/claude-assets/skills/cfn-docker-redis-coordination/MIGRATION_SUMMARY.md +348 -0
  332. package/claude-assets/skills/cfn-docker-redis-coordination/README.md +294 -0
  333. package/claude-assets/skills/cfn-docker-redis-coordination/jest.config.js +37 -0
  334. package/claude-assets/skills/cfn-docker-redis-coordination/package-lock.json +5259 -0
  335. package/claude-assets/skills/cfn-docker-redis-coordination/package.json +40 -0
  336. package/claude-assets/skills/cfn-docker-redis-coordination/src/coordinator.ts +801 -0
  337. package/claude-assets/skills/cfn-docker-redis-coordination/src/index.ts +42 -0
  338. package/claude-assets/skills/cfn-docker-redis-coordination/src/types.ts +351 -0
  339. package/claude-assets/skills/cfn-docker-redis-coordination/tests/coordinator.test.ts +1464 -0
  340. package/claude-assets/skills/cfn-docker-redis-coordination/tsconfig.json +30 -0
  341. package/claude-assets/skills/cfn-error-logging/.eslintrc.json +57 -0
  342. package/claude-assets/skills/cfn-error-logging/.prettierrc.json +10 -0
  343. package/claude-assets/skills/cfn-error-logging/MIGRATION_SUMMARY.md +485 -0
  344. package/claude-assets/skills/cfn-error-logging/package.json +47 -0
  345. package/claude-assets/skills/cfn-error-logging/src/error-logger.ts +1042 -0
  346. package/claude-assets/skills/cfn-error-logging/src/index.ts +12 -0
  347. package/claude-assets/skills/cfn-error-logging/src/types.ts +456 -0
  348. package/claude-assets/skills/cfn-error-logging/tests/error-logger.test.ts +1302 -0
  349. package/claude-assets/skills/cfn-error-logging/tsconfig.json +38 -0
  350. package/claude-assets/skills/cfn-loop-orchestration/.eslintrc.js +56 -0
  351. package/claude-assets/skills/cfn-loop-orchestration/.prettierrc.json +18 -0
  352. package/claude-assets/skills/cfn-loop-orchestration/README.md +149 -41
  353. package/claude-assets/skills/cfn-loop-orchestration/helpers/gate-check.sh +39 -577
  354. package/claude-assets/skills/cfn-loop-orchestration/helpers/parse-test-results.sh +49 -270
  355. package/claude-assets/skills/cfn-loop-orchestration/jest.config.js +67 -0
  356. package/claude-assets/skills/cfn-loop-orchestration/orchestrate-wrapper.sh +268 -0
  357. package/claude-assets/skills/cfn-loop-orchestration/orchestrate.sh +91 -8
  358. package/claude-assets/skills/cfn-loop-orchestration/package-lock.json +5470 -0
  359. package/claude-assets/skills/cfn-loop-orchestration/package.json +49 -0
  360. package/claude-assets/skills/cfn-loop-orchestration/src/agent-spawner/agent-spawner.ts +34 -0
  361. package/claude-assets/skills/cfn-loop-orchestration/src/gate-checker/gate-checker.ts +36 -0
  362. package/claude-assets/skills/cfn-loop-orchestration/src/helpers/gate-check.ts +115 -0
  363. package/claude-assets/skills/cfn-loop-orchestration/src/helpers/parse-test-results.ts +372 -0
  364. package/claude-assets/skills/cfn-loop-orchestration/src/index.ts +14 -0
  365. package/claude-assets/skills/cfn-loop-orchestration/src/orchestrator/orchestrator.ts +31 -0
  366. package/claude-assets/skills/cfn-loop-orchestration/src/redis/redis-coordinator.ts +72 -0
  367. package/claude-assets/skills/cfn-loop-orchestration/src/types.ts +188 -0
  368. package/claude-assets/skills/cfn-loop-orchestration/src/utils/logger.ts +32 -0
  369. package/claude-assets/skills/cfn-loop-orchestration/tests/consensus.test.ts +142 -0
  370. package/claude-assets/skills/cfn-loop-orchestration/tests/deliverable-verifier.test.ts +199 -0
  371. package/claude-assets/skills/cfn-loop-orchestration/tests/gate-check.test.ts +325 -0
  372. package/claude-assets/skills/cfn-loop-orchestration/tests/iteration-manager.test.ts +132 -0
  373. package/claude-assets/skills/cfn-loop-orchestration/tests/parse-test-results.test.ts +382 -0
  374. package/claude-assets/skills/cfn-loop-orchestration/tests/setup.ts +22 -0
  375. package/claude-assets/skills/cfn-loop-orchestration/tests/timeout-calculator.test.ts +118 -0
  376. package/claude-assets/skills/cfn-loop-orchestration/tests/types.test.ts +132 -0
  377. package/claude-assets/skills/cfn-loop-orchestration/tsconfig.json +54 -0
  378. package/claude-assets/skills/cfn-redis-coordination/bash-wrappers/store-context.sh +23 -0
  379. package/claude-assets/skills/cfn-redis-coordination/coverage/clover.xml +1447 -0
  380. package/claude-assets/skills/cfn-redis-coordination/coverage/coverage-final.json +13 -0
  381. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/agent-logger.ts.html +1423 -0
  382. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/agent-recovery.ts.html +1447 -0
  383. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/base.css +224 -0
  384. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/block-navigation.js +87 -0
  385. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/completion-reporter.ts.html +1273 -0
  386. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/context-manager.ts.html +1066 -0
  387. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/favicon.png +0 -0
  388. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/index.html +281 -0
  389. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/mode-detector.ts.html +550 -0
  390. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/prettify.css +1 -0
  391. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/prettify.js +2 -0
  392. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/redis-client.ts.html +2047 -0
  393. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/result-collector.ts.html +1396 -0
  394. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  395. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/sorter.js +210 -0
  396. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/swarm-manager.ts.html +1567 -0
  397. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/task-analyzer.ts.html +1297 -0
  398. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/task-executor.ts.html +1354 -0
  399. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/types.ts.html +790 -0
  400. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov-report/waiting-coordinator.ts.html +1846 -0
  401. package/claude-assets/skills/cfn-redis-coordination/coverage/lcov.info +2650 -0
  402. package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.d.ts +92 -0
  403. package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.d.ts.map +1 -0
  404. package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.js +329 -0
  405. package/claude-assets/skills/cfn-redis-coordination/dist/agent-logger.js.map +1 -0
  406. package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.d.ts +75 -0
  407. package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.d.ts.map +1 -0
  408. package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.js +302 -0
  409. package/claude-assets/skills/cfn-redis-coordination/dist/agent-recovery.js.map +1 -0
  410. package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.d.ts +58 -0
  411. package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.d.ts.map +1 -0
  412. package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.js +237 -0
  413. package/claude-assets/skills/cfn-redis-coordination/dist/completion-reporter.js.map +1 -0
  414. package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.d.ts +63 -0
  415. package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.d.ts.map +1 -0
  416. package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.js +230 -0
  417. package/claude-assets/skills/cfn-redis-coordination/dist/context-manager.js.map +1 -0
  418. package/claude-assets/skills/cfn-redis-coordination/dist/index.d.ts +45 -0
  419. package/claude-assets/skills/cfn-redis-coordination/dist/index.d.ts.map +1 -0
  420. package/claude-assets/skills/cfn-redis-coordination/dist/index.js +114 -0
  421. package/claude-assets/skills/cfn-redis-coordination/dist/index.js.map +1 -0
  422. package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.d.ts +31 -0
  423. package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.d.ts.map +1 -0
  424. package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.js +185 -0
  425. package/claude-assets/skills/cfn-redis-coordination/dist/mode-detector.js.map +1 -0
  426. package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.d.ts +191 -0
  427. package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.d.ts.map +1 -0
  428. package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.js +509 -0
  429. package/claude-assets/skills/cfn-redis-coordination/dist/redis-client.js.map +1 -0
  430. package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.d.ts +75 -0
  431. package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.d.ts.map +1 -0
  432. package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.js +281 -0
  433. package/claude-assets/skills/cfn-redis-coordination/dist/result-collector.js.map +1 -0
  434. package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.d.ts +75 -0
  435. package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.d.ts.map +1 -0
  436. package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.js +354 -0
  437. package/claude-assets/skills/cfn-redis-coordination/dist/swarm-manager.js.map +1 -0
  438. package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.d.ts +62 -0
  439. package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.d.ts.map +1 -0
  440. package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.js +305 -0
  441. package/claude-assets/skills/cfn-redis-coordination/dist/task-analyzer.js.map +1 -0
  442. package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.d.ts +97 -0
  443. package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.d.ts.map +1 -0
  444. package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.js +283 -0
  445. package/claude-assets/skills/cfn-redis-coordination/dist/task-executor.js.map +1 -0
  446. package/claude-assets/skills/cfn-redis-coordination/dist/types.d.ts +176 -0
  447. package/claude-assets/skills/cfn-redis-coordination/dist/types.d.ts.map +1 -0
  448. package/claude-assets/skills/cfn-redis-coordination/dist/types.js +81 -0
  449. package/claude-assets/skills/cfn-redis-coordination/dist/types.js.map +1 -0
  450. package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts +86 -0
  451. package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.d.ts.map +1 -0
  452. package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.js +419 -0
  453. package/claude-assets/skills/cfn-redis-coordination/dist/waiting-coordinator.js.map +1 -0
  454. package/claude-assets/skills/cfn-redis-coordination/docs/migration/PHASE_3_REDIS_COORDINATION_COMPLETION_REPORT.md +553 -0
  455. package/claude-assets/skills/cfn-redis-coordination/jest.config.js +23 -0
  456. package/claude-assets/skills/cfn-redis-coordination/package-lock.json +5272 -0
  457. package/claude-assets/skills/cfn-redis-coordination/package.json +45 -0
  458. package/claude-assets/skills/cfn-redis-coordination/redis-cli-wrapper.sh +21 -8
  459. package/claude-assets/skills/cfn-redis-coordination/src/agent-logger.ts +446 -0
  460. package/claude-assets/skills/cfn-redis-coordination/src/agent-recovery.ts +454 -0
  461. package/claude-assets/skills/cfn-redis-coordination/src/completion-reporter.ts +396 -0
  462. package/claude-assets/skills/cfn-redis-coordination/src/context-manager.ts +327 -0
  463. package/claude-assets/skills/cfn-redis-coordination/src/index.ts +82 -0
  464. package/claude-assets/skills/cfn-redis-coordination/src/mode-detector.ts +155 -0
  465. package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-client.ts +305 -0
  466. package/claude-assets/skills/cfn-redis-coordination/src/redis/redis-functions.ts +283 -0
  467. package/claude-assets/skills/cfn-redis-coordination/src/redis-client.ts +654 -0
  468. package/claude-assets/skills/cfn-redis-coordination/src/result-collector.ts +437 -0
  469. package/claude-assets/skills/cfn-redis-coordination/src/swarm-manager.ts +494 -0
  470. package/claude-assets/skills/cfn-redis-coordination/src/task-analyzer.ts +404 -0
  471. package/claude-assets/skills/cfn-redis-coordination/src/task-executor.ts +423 -0
  472. package/claude-assets/skills/cfn-redis-coordination/src/types.ts +235 -0
  473. package/claude-assets/skills/cfn-redis-coordination/src/waiting-coordinator.ts +587 -0
  474. package/claude-assets/skills/cfn-redis-coordination/test-connection-attempts.js +70 -0
  475. package/claude-assets/skills/cfn-redis-coordination/test-mode-simple.js +121 -0
  476. package/claude-assets/skills/cfn-redis-coordination/test-redis-check.js +84 -0
  477. package/claude-assets/skills/cfn-redis-coordination/test-task-mode-redis.cjs +391 -0
  478. package/claude-assets/skills/cfn-redis-coordination/tests/coordination.test.ts +788 -0
  479. package/claude-assets/skills/cfn-redis-coordination/tsconfig.json +31 -0
  480. package/claude-assets/skills/cfn-skill-propagation/README.md +233 -0
  481. package/claude-assets/skills/cfn-skill-propagation/package-lock.json +5174 -0
  482. package/claude-assets/skills/cfn-skill-propagation/package.json +52 -0
  483. package/claude-assets/skills/cfn-skill-propagation/propagate-skill-update.sh +32 -0
  484. package/claude-assets/skills/cfn-skill-propagation/src/cli.ts +75 -0
  485. package/claude-assets/skills/cfn-skill-propagation/src/database-adapter.ts +239 -0
  486. package/claude-assets/skills/cfn-skill-propagation/src/file-system-adapter.ts +113 -0
  487. package/claude-assets/skills/cfn-skill-propagation/src/index.ts +72 -0
  488. package/claude-assets/skills/cfn-skill-propagation/src/logger.ts +43 -0
  489. package/claude-assets/skills/cfn-skill-propagation/src/metadata-parser.ts +154 -0
  490. package/claude-assets/skills/cfn-skill-propagation/src/skill-propagator.ts +274 -0
  491. package/claude-assets/skills/cfn-skill-propagation/src/skill-validator.ts +179 -0
  492. package/claude-assets/skills/cfn-skill-propagation/src/types.ts +143 -0
  493. package/claude-assets/skills/cfn-skill-propagation/src/version-manager.ts +118 -0
  494. package/claude-assets/skills/cfn-skill-propagation/tests/file-system-adapter.test.ts +91 -0
  495. package/claude-assets/skills/cfn-skill-propagation/tests/metadata-parser.test.ts +176 -0
  496. package/claude-assets/skills/cfn-skill-propagation/tests/skill-propagator.test.ts +209 -0
  497. package/claude-assets/skills/cfn-skill-propagation/tests/skill-validator.test.ts +203 -0
  498. package/claude-assets/skills/cfn-skill-propagation/tests/version-manager.test.ts +115 -0
  499. package/claude-assets/skills/cfn-skill-propagation/tsconfig.json +34 -0
  500. package/claude-assets/skills/task-classifier/SKILL.md +81 -0
  501. package/claude-assets/skills/task-classifier/classify-task.sh +62 -0
  502. package/claude-assets/skills/workflow-codification/package-lock.json +5170 -0
  503. package/claude-assets/skills/workflow-codification/package.json +30 -0
  504. package/claude-assets/skills/workflow-codification/src/index.ts +24 -0
  505. package/claude-assets/skills/workflow-codification/src/pattern-analyzer.ts +537 -0
  506. package/claude-assets/skills/workflow-codification/src/types.ts +180 -0
  507. package/claude-assets/skills/workflow-codification/tests/pattern-analyzer.test.ts +960 -0
  508. package/claude-assets/skills/workflow-codification/tsconfig.json +34 -0
  509. package/claude-assets/skills/workflow-codification/workflow-codification.db +0 -0
  510. package/dist/agent-spawner/agent-spawner.js +448 -0
  511. package/dist/agent-spawner/agent-spawner.js.map +1 -0
  512. package/dist/agent-spawner/index.js +10 -0
  513. package/dist/agent-spawner/index.js.map +1 -0
  514. package/dist/agent-spawner/types.js +14 -0
  515. package/dist/agent-spawner/types.js.map +1 -0
  516. package/dist/cli/agent-executor.js +47 -1
  517. package/dist/cli/agent-executor.js.map +1 -1
  518. package/dist/cli/agent-spawn.js +4 -1
  519. package/dist/cli/agent-spawn.js.map +1 -1
  520. package/dist/cli/config-manager.js +91 -109
  521. package/dist/cli/config-manager.js.map +1 -1
  522. package/dist/cli/tool-executor.js +3 -1
  523. package/dist/cli/tool-executor.js.map +1 -1
  524. package/dist/gate-checker/gate-checker.js +292 -0
  525. package/dist/gate-checker/gate-checker.js.map +1 -0
  526. package/dist/gate-checker/types.js +94 -0
  527. package/dist/gate-checker/types.js.map +1 -0
  528. package/dist/lib/database-service/connection-pool-manager.js +2 -1
  529. package/dist/lib/database-service/connection-pool-manager.js.map +1 -1
  530. package/dist/orchestrator/index.js +10 -0
  531. package/dist/orchestrator/index.js.map +1 -0
  532. package/dist/orchestrator/orchestrate.js +496 -0
  533. package/dist/orchestrator/orchestrate.js.map +1 -0
  534. package/dist/orchestrator/types.js +58 -0
  535. package/dist/orchestrator/types.js.map +1 -0
  536. package/package.json +1 -1
  537. package/scripts/clean-agent-profiles.sh +112 -0
  538. package/scripts/switch-api.sh +142 -4
  539. package/scripts/verify-no-secrets.sh +6 -13
  540. package/tests/README.md +175 -58
@@ -0,0 +1,1464 @@
1
+ /**
2
+ * Redis Coordinator Test Suite
3
+ *
4
+ * Comprehensive tests for RedisCoordinator with 90%+ code coverage
5
+ * Tests include:
6
+ * - Initialization and configuration
7
+ * - Agent registration and status management
8
+ * - Confidence tracking and completion signaling
9
+ * - Loop waiting and timeout handling
10
+ * - Consensus collection
11
+ * - Error handling and validation
12
+ * - Redis connection failures
13
+ * - Security validation
14
+ *
15
+ * @module cfn-docker-redis-coordination/tests/coordinator.test.ts
16
+ */
17
+
18
+ import { RedisCoordinator } from '../src/coordinator';
19
+ import {
20
+ CoordinatorConfig,
21
+ IRedisClient,
22
+ ILogger,
23
+ ValidationError,
24
+ SecurityError,
25
+ TimeoutError,
26
+ RedisConnectionError,
27
+ } from '../src/types';
28
+
29
+ // Mock Redis Client
30
+ class MockRedisClient implements IRedisClient {
31
+ private data: Record<string, Record<string, string>> = {};
32
+ private lists: Record<string, string[]> = {};
33
+ private sets: Record<string, Set<string>> = {};
34
+ private expirations: Map<string, number> = new Map();
35
+
36
+ async exists(key: string): Promise<boolean> {
37
+ return key in this.data || key in this.lists || key in this.sets;
38
+ }
39
+
40
+ async del(key: string): Promise<number> {
41
+ let deleted = 0;
42
+ if (key in this.data) {
43
+ delete this.data[key];
44
+ deleted++;
45
+ }
46
+ if (key in this.lists) {
47
+ delete this.lists[key];
48
+ deleted++;
49
+ }
50
+ if (key in this.sets) {
51
+ delete this.sets[key];
52
+ deleted++;
53
+ }
54
+ this.expirations.delete(key);
55
+ return deleted;
56
+ }
57
+
58
+ async keys(pattern: string): Promise<string[]> {
59
+ const regex = new RegExp(`^${pattern.replace(/\*/g, '.*')}$`);
60
+ const allKeys = [
61
+ ...Object.keys(this.data),
62
+ ...Object.keys(this.lists),
63
+ ...Object.keys(this.sets),
64
+ ];
65
+ return allKeys.filter((key) => regex.test(key));
66
+ }
67
+
68
+ async dbsize(): Promise<number> {
69
+ const allKeys = new Set([
70
+ ...Object.keys(this.data),
71
+ ...Object.keys(this.lists),
72
+ ...Object.keys(this.sets),
73
+ ]);
74
+ return allKeys.size;
75
+ }
76
+
77
+ async flushdb(): Promise<string> {
78
+ this.data = {};
79
+ this.lists = {};
80
+ this.sets = {};
81
+ this.expirations.clear();
82
+ return 'OK';
83
+ }
84
+
85
+ async get(key: string): Promise<string | null> {
86
+ // Get first value from hash (simplified)
87
+ const hash = this.data[key];
88
+ return hash ? Object.values(hash)[0] || null : null;
89
+ }
90
+
91
+ async set(key: string, value: string): Promise<string> {
92
+ if (!this.data[key]) {
93
+ this.data[key] = {};
94
+ }
95
+ this.data[key]['value'] = value;
96
+ return 'OK';
97
+ }
98
+
99
+ async setex(
100
+ key: string,
101
+ seconds: number,
102
+ value: string
103
+ ): Promise<string> {
104
+ await this.set(key, value);
105
+ await this.expire(key, seconds);
106
+ return 'OK';
107
+ }
108
+
109
+ async hget(key: string, field: string): Promise<string | null> {
110
+ const hash = this.data[key];
111
+ return hash ? (hash[field] || null) : null;
112
+ }
113
+
114
+ async hset(
115
+ key: string,
116
+ fields: Record<string, string | number | boolean>
117
+ ): Promise<number> {
118
+ if (!this.data[key]) {
119
+ this.data[key] = {};
120
+ }
121
+ const hash = this.data[key];
122
+ let count = 0;
123
+ for (const [field, value] of Object.entries(fields)) {
124
+ hash[field] = String(value);
125
+ count++;
126
+ }
127
+ return count;
128
+ }
129
+
130
+ async hmset(
131
+ key: string,
132
+ fields: Record<string, string | number | boolean>
133
+ ): Promise<string> {
134
+ await this.hset(key, fields);
135
+ return 'OK';
136
+ }
137
+
138
+ async hgetall(key: string): Promise<Record<string, string>> {
139
+ return this.data[key] || {};
140
+ }
141
+
142
+ async hkeys(key: string): Promise<string[]> {
143
+ const hash = this.data[key];
144
+ return hash ? Object.keys(hash) : [];
145
+ }
146
+
147
+ async hvals(key: string): Promise<string[]> {
148
+ const hash = this.data[key];
149
+ return hash ? Object.values(hash) : [];
150
+ }
151
+
152
+ async lpush(key: string, values: string[]): Promise<number> {
153
+ if (!this.lists[key]) {
154
+ this.lists[key] = [];
155
+ }
156
+ this.lists[key].unshift(...values);
157
+ return this.lists[key].length;
158
+ }
159
+
160
+ async rpush(key: string, values: string[]): Promise<number> {
161
+ if (!this.lists[key]) {
162
+ this.lists[key] = [];
163
+ }
164
+ this.lists[key].push(...values);
165
+ return this.lists[key].length;
166
+ }
167
+
168
+ async blpop(
169
+ keys: string[],
170
+ timeout: number
171
+ ): Promise<[string, string] | null> {
172
+ for (const key of keys) {
173
+ const list = this.lists[key];
174
+ if (list && list.length > 0) {
175
+ const value = list.pop();
176
+ if (value) {
177
+ return [key, value];
178
+ }
179
+ }
180
+ }
181
+ return null;
182
+ }
183
+
184
+ async lrange(key: string, start: number, stop: number): Promise<string[]> {
185
+ const list = this.lists[key];
186
+ if (!list) return [];
187
+ // Handle negative indices
188
+ const len = list.length;
189
+ let actualStart = start < 0 ? Math.max(0, len + start) : start;
190
+ let actualStop = stop < 0 ? Math.max(-1, len + stop) : stop;
191
+
192
+ actualStart = Math.max(0, Math.min(actualStart, len - 1));
193
+ actualStop = Math.max(-1, Math.min(actualStop, len - 1));
194
+
195
+ if (actualStart > actualStop) return [];
196
+ return list.slice(actualStart, actualStop + 1);
197
+ }
198
+
199
+ async sadd(key: string, members: string[]): Promise<number> {
200
+ if (!this.sets[key]) {
201
+ this.sets[key] = new Set();
202
+ }
203
+ let count = 0;
204
+ for (const member of members) {
205
+ if (!this.sets[key].has(member)) {
206
+ this.sets[key].add(member);
207
+ count++;
208
+ }
209
+ }
210
+ return count;
211
+ }
212
+
213
+ async smembers(key: string): Promise<string[]> {
214
+ const set = this.sets[key];
215
+ return set ? Array.from(set) : [];
216
+ }
217
+
218
+ async scard(key: string): Promise<number> {
219
+ const set = this.sets[key];
220
+ return set ? set.size : 0;
221
+ }
222
+
223
+ async expire(key: string, seconds: number): Promise<number> {
224
+ if (await this.exists(key)) {
225
+ this.expirations.set(key, Date.now() + seconds * 1000);
226
+ return 1;
227
+ }
228
+ return 0;
229
+ }
230
+
231
+ async pexpire(key: string, milliseconds: number): Promise<number> {
232
+ if (await this.exists(key)) {
233
+ this.expirations.set(key, Date.now() + milliseconds);
234
+ return 1;
235
+ }
236
+ return 0;
237
+ }
238
+
239
+ async ttl(key: string): Promise<number> {
240
+ const expiration = this.expirations.get(key);
241
+ if (!expiration) return -1;
242
+ const remaining = Math.floor((expiration - Date.now()) / 1000);
243
+ return remaining > 0 ? remaining : -2;
244
+ }
245
+
246
+ async ping(): Promise<string> {
247
+ return 'PONG';
248
+ }
249
+
250
+ async info(section?: string): Promise<string> {
251
+ if (section === 'memory') {
252
+ return '# Memory\nused_memory_human:1M\n';
253
+ }
254
+ return '# Server\nredis_version:6.0.0\n';
255
+ }
256
+
257
+ async quit(): Promise<void> {
258
+ this.data = {};
259
+ this.lists = {};
260
+ this.sets = {};
261
+ this.expirations.clear();
262
+ }
263
+ }
264
+
265
+ // Mock Logger
266
+ class MockLogger implements ILogger {
267
+ public logs: Array<{ level: string; message: string }> = [];
268
+
269
+ log(message: string): void {
270
+ this.logs.push({ level: 'log', message });
271
+ }
272
+
273
+ info(message: string): void {
274
+ this.logs.push({ level: 'info', message });
275
+ }
276
+
277
+ warn(message: string): void {
278
+ this.logs.push({ level: 'warn', message });
279
+ }
280
+
281
+ error(message: string): void {
282
+ this.logs.push({ level: 'error', message });
283
+ }
284
+
285
+ debug(message: string): void {
286
+ this.logs.push({ level: 'debug', message });
287
+ }
288
+
289
+ clear(): void {
290
+ this.logs = [];
291
+ }
292
+ }
293
+
294
+ describe('RedisCoordinator', () => {
295
+ let coordinator: RedisCoordinator;
296
+ let mockRedis: MockRedisClient;
297
+ let mockLogger: MockLogger;
298
+ let config: CoordinatorConfig;
299
+
300
+ beforeEach(async () => {
301
+ mockRedis = new MockRedisClient();
302
+ mockLogger = new MockLogger();
303
+ config = {
304
+ redis: {
305
+ host: 'localhost',
306
+ port: 6379,
307
+ db: 0,
308
+ },
309
+ taskId: 'test-task-001',
310
+ defaultTimeout: 30,
311
+ defaultTTL: 3600,
312
+ mode: 'standard',
313
+ };
314
+
315
+ coordinator = new RedisCoordinator(config, mockLogger, mockRedis);
316
+ });
317
+
318
+ afterEach(async () => {
319
+ await mockRedis.flushdb();
320
+ });
321
+
322
+ describe('Constructor', () => {
323
+ it('should create coordinator with valid config', () => {
324
+ expect(coordinator).toBeDefined();
325
+ });
326
+
327
+ it('should throw ValidationError for invalid task ID', () => {
328
+ const invalidConfig = {
329
+ ...config,
330
+ taskId: 'invalid-task-with-special-chars!@#',
331
+ };
332
+
333
+ expect(
334
+ () => new RedisCoordinator(invalidConfig, mockLogger, mockRedis)
335
+ ).toThrow(ValidationError);
336
+ });
337
+
338
+ it('should throw ValidationError for empty task ID', () => {
339
+ const invalidConfig = {
340
+ ...config,
341
+ taskId: '',
342
+ };
343
+
344
+ expect(
345
+ () => new RedisCoordinator(invalidConfig, mockLogger, mockRedis)
346
+ ).toThrow(ValidationError);
347
+ });
348
+
349
+ it('should throw ValidationError for task ID exceeding max length', () => {
350
+ const invalidConfig = {
351
+ ...config,
352
+ taskId: 'a'.repeat(257),
353
+ };
354
+
355
+ expect(
356
+ () => new RedisCoordinator(invalidConfig, mockLogger, mockRedis)
357
+ ).toThrow(ValidationError);
358
+ });
359
+ });
360
+
361
+ describe('initTask', () => {
362
+ it('should initialize task without context', async () => {
363
+ await coordinator.initTask();
364
+
365
+ const exists = await mockRedis.exists('cfn_docker:task:test-task-001:meta');
366
+ expect(exists).toBe(true);
367
+
368
+ const meta = await mockRedis.hgetall('cfn_docker:task:test-task-001:meta');
369
+ expect(meta.created_by).toBe('cfn-docker-redis-coordination');
370
+ expect(meta.mode).toBe('standard');
371
+ });
372
+
373
+ it('should initialize task with context', async () => {
374
+ const context = {
375
+ branch: 'main',
376
+ iteration: 1,
377
+ };
378
+
379
+ await coordinator.initTask(context);
380
+
381
+ const contextData = await mockRedis.hgetall('cfn_docker:task:test-task-001:context');
382
+ expect(contextData.branch).toBe('main');
383
+ expect(contextData.iteration).toBe('1');
384
+ });
385
+
386
+ it('should set TTL on task metadata', async () => {
387
+ await coordinator.initTask();
388
+
389
+ const ttl = await mockRedis.ttl('cfn_docker:task:test-task-001:meta');
390
+ expect(ttl).toBeGreaterThan(0);
391
+ expect(ttl).toBeLessThanOrEqual(3600);
392
+ });
393
+
394
+ it('should throw SecurityError for oversized context value', async () => {
395
+ const coordinator2 = new RedisCoordinator(config, mockLogger, mockRedis);
396
+
397
+ const largeContext = {
398
+ oversized: 'x'.repeat(1024 * 1024 + 1), // Exceeds 1MB limit
399
+ };
400
+
401
+ await expect(coordinator2.initTask(largeContext)).rejects.toThrow(
402
+ SecurityError
403
+ );
404
+ });
405
+ });
406
+
407
+ describe('storeContext', () => {
408
+ it('should store context successfully', async () => {
409
+ const context = { key1: 'value1', key2: 'value2' };
410
+
411
+ await coordinator.storeContext(context);
412
+
413
+ const stored = await mockRedis.hgetall('cfn_docker:task:test-task-001:context');
414
+ expect(stored.key1).toBe('value1');
415
+ expect(stored.key2).toBe('value2');
416
+ });
417
+
418
+ it('should set TTL on context', async () => {
419
+ await coordinator.storeContext({ test: 'value' });
420
+
421
+ const ttl = await mockRedis.ttl('cfn_docker:task:test-task-001:context');
422
+ expect(ttl).toBeGreaterThan(0);
423
+ });
424
+ });
425
+
426
+ describe('getContext', () => {
427
+ it('should retrieve stored context', async () => {
428
+ const context = { branch: 'develop', revision: '1a2b3c' };
429
+ await coordinator.storeContext(context);
430
+
431
+ const retrieved = await coordinator.getContext();
432
+
433
+ expect(retrieved.branch).toBe('develop');
434
+ expect(retrieved.revision).toBe('1a2b3c');
435
+ });
436
+
437
+ it('should throw ValidationError if context not found', async () => {
438
+ await expect(coordinator.getContext()).rejects.toThrow(ValidationError);
439
+ });
440
+ });
441
+
442
+ describe('registerAgent', () => {
443
+ it('should register agent successfully', async () => {
444
+ await coordinator.registerAgent('agent-001', 'backend-developer', 'container-123');
445
+
446
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-001');
447
+ expect(agentData.agent_id).toBe('agent-001');
448
+ expect(agentData.agent_type).toBe('backend-developer');
449
+ expect(agentData.container_id).toBe('container-123');
450
+ expect(agentData.status).toBe('spawning');
451
+ });
452
+
453
+ it('should register agent without container ID', async () => {
454
+ await coordinator.registerAgent('agent-002', 'frontend-developer');
455
+
456
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-002');
457
+ expect(agentData.agent_id).toBe('agent-002');
458
+ expect(agentData.container_id).toBe('');
459
+ });
460
+
461
+ it('should add agent to status history', async () => {
462
+ await coordinator.registerAgent('agent-003', 'tester');
463
+
464
+ const history = await mockRedis.lrange(
465
+ 'cfn_docker:agent:agent-003:status_history',
466
+ 0,
467
+ -1
468
+ );
469
+ expect(history.length).toBeGreaterThan(0);
470
+
471
+ const entry = JSON.parse(history[0]);
472
+ expect(entry.status).toBe('spawning');
473
+ expect(entry.timestamp).toBeDefined();
474
+ });
475
+
476
+ it('should throw ValidationError for invalid agent ID', async () => {
477
+ await expect(
478
+ coordinator.registerAgent('invalid@agent!', 'developer')
479
+ ).rejects.toThrow(ValidationError);
480
+ });
481
+
482
+ it('should throw ValidationError for empty agent ID', async () => {
483
+ await expect(coordinator.registerAgent('', 'developer')).rejects.toThrow(
484
+ ValidationError
485
+ );
486
+ });
487
+
488
+ it('should set TTL on agent data', async () => {
489
+ await coordinator.registerAgent('agent-004', 'developer');
490
+
491
+ const ttl = await mockRedis.ttl('cfn_docker:agent:agent-004');
492
+ expect(ttl).toBeGreaterThan(0);
493
+ });
494
+ });
495
+
496
+ describe('updateStatus', () => {
497
+ beforeEach(async () => {
498
+ await coordinator.registerAgent('agent-001', 'developer');
499
+ });
500
+
501
+ it('should update agent status to running', async () => {
502
+ await coordinator.updateStatus('agent-001', 'running', 1);
503
+
504
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-001');
505
+ expect(agentData.status).toBe('running');
506
+ expect(agentData.iteration).toBe('1');
507
+ });
508
+
509
+ it('should update agent status to completed', async () => {
510
+ await coordinator.updateStatus('agent-001', 'completed', 2);
511
+
512
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-001');
513
+ expect(agentData.status).toBe('completed');
514
+ expect(agentData.iteration).toBe('2');
515
+ });
516
+
517
+ it('should add status to history', async () => {
518
+ await coordinator.updateStatus('agent-001', 'running');
519
+
520
+ const history = await mockRedis.lrange(
521
+ 'cfn_docker:agent:agent-001:status_history',
522
+ 0,
523
+ -1
524
+ );
525
+ expect(history.length).toBeGreaterThanOrEqual(2); // Initial spawning + running
526
+ });
527
+
528
+ it('should throw ValidationError for invalid agent ID', async () => {
529
+ await expect(
530
+ coordinator.updateStatus('invalid@id', 'running')
531
+ ).rejects.toThrow(ValidationError);
532
+ });
533
+
534
+ it('should throw ValidationError for invalid status', async () => {
535
+ await expect(
536
+ coordinator.updateStatus('agent-001', 'invalid-status' as any)
537
+ ).rejects.toThrow(ValidationError);
538
+ });
539
+ });
540
+
541
+ describe('signalComplete', () => {
542
+ beforeEach(async () => {
543
+ await coordinator.registerAgent('agent-001', 'developer');
544
+ });
545
+
546
+ it('should signal completion with confidence', async () => {
547
+ await coordinator.signalComplete('agent-001', 0.85, 1);
548
+
549
+ const statusKey = 'cfn_docker:task:test-task-001:agent:agent-001:done';
550
+ const exists = await mockRedis.exists(statusKey);
551
+ expect(exists).toBe(true);
552
+
553
+ const confidenceKey =
554
+ 'cfn_docker:task:test-task-001:confidence:agent-001';
555
+ const confidenceData = await mockRedis.hgetall(confidenceKey);
556
+ expect(confidenceData.confidence).toBe('0.85');
557
+ expect(confidenceData.iteration).toBe('1');
558
+ expect(confidenceData.agent_type).toBe('developer');
559
+ });
560
+
561
+ it('should signal completion with confidence 1.0', async () => {
562
+ await coordinator.signalComplete('agent-001', 1.0, 1);
563
+
564
+ const confidenceKey =
565
+ 'cfn_docker:task:test-task-001:confidence:agent-001';
566
+ const confidenceData = await mockRedis.hgetall(confidenceKey);
567
+ expect(confidenceData.confidence).toBe('1');
568
+ });
569
+
570
+ it('should signal completion with confidence 0.0', async () => {
571
+ await coordinator.signalComplete('agent-001', 0.0, 1);
572
+
573
+ const confidenceKey =
574
+ 'cfn_docker:task:test-task-001:confidence:agent-001';
575
+ const confidenceData = await mockRedis.hgetall(confidenceKey);
576
+ expect(confidenceData.confidence).toBe('0');
577
+ });
578
+
579
+ it('should update agent status to completed', async () => {
580
+ await coordinator.signalComplete('agent-001', 0.85, 1);
581
+
582
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-001');
583
+ expect(agentData.status).toBe('completed');
584
+ });
585
+
586
+ it('should throw ValidationError for invalid confidence < 0', async () => {
587
+ await expect(
588
+ coordinator.signalComplete('agent-001', -0.1)
589
+ ).rejects.toThrow(ValidationError);
590
+ });
591
+
592
+ it('should throw ValidationError for invalid confidence > 1', async () => {
593
+ await expect(
594
+ coordinator.signalComplete('agent-001', 1.1)
595
+ ).rejects.toThrow(ValidationError);
596
+ });
597
+
598
+ it('should throw ValidationError for invalid agent ID', async () => {
599
+ await expect(
600
+ coordinator.signalComplete('invalid@id', 0.85)
601
+ ).rejects.toThrow(ValidationError);
602
+ });
603
+ });
604
+
605
+ describe('waitLoop', () => {
606
+ beforeEach(async () => {
607
+ await coordinator.registerAgent('agent-001', 'developer');
608
+ await coordinator.registerAgent('agent-002', 'developer');
609
+ });
610
+
611
+ it('should wait for loop completion when agents complete', async () => {
612
+ // Simulate agent completion
613
+ await coordinator.signalComplete('agent-001', 0.85);
614
+ await coordinator.signalComplete('agent-002', 0.90);
615
+
616
+ const result = await coordinator.waitLoop({
617
+ taskId: 'test-task-001',
618
+ loopNumber: 3,
619
+ agentCount: 2,
620
+ timeout: 5,
621
+ });
622
+
623
+ expect(result.success).toBe(true);
624
+ expect(result.completedAgents).toBe(2);
625
+ expect(result.expectedAgents).toBe(2);
626
+ });
627
+
628
+ it('should timeout when not all agents complete', async () => {
629
+ await coordinator.signalComplete('agent-001', 0.85);
630
+
631
+ const result = await coordinator.waitLoop({
632
+ taskId: 'test-task-001',
633
+ loopNumber: 3,
634
+ agentCount: 2,
635
+ timeout: 1,
636
+ });
637
+
638
+ expect(result.success).toBe(false);
639
+ expect(result.completedAgents).toBeLessThan(2);
640
+ expect(result.message).toContain('timeout');
641
+ });
642
+
643
+ it('should throw ValidationError for invalid task ID', async () => {
644
+ await expect(
645
+ coordinator.waitLoop({
646
+ taskId: 'invalid@task',
647
+ loopNumber: 3,
648
+ agentCount: 2,
649
+ })
650
+ ).rejects.toThrow(ValidationError);
651
+ });
652
+
653
+ it('should throw ValidationError for invalid loop number < 1', async () => {
654
+ await expect(
655
+ coordinator.waitLoop({
656
+ taskId: 'test-task-001',
657
+ loopNumber: 0,
658
+ agentCount: 2,
659
+ })
660
+ ).rejects.toThrow(ValidationError);
661
+ });
662
+
663
+ it('should throw ValidationError for invalid loop number > 4', async () => {
664
+ await expect(
665
+ coordinator.waitLoop({
666
+ taskId: 'test-task-001',
667
+ loopNumber: 5,
668
+ agentCount: 2,
669
+ })
670
+ ).rejects.toThrow(ValidationError);
671
+ });
672
+
673
+ it('should throw ValidationError for invalid agent count < 1', async () => {
674
+ await expect(
675
+ coordinator.waitLoop({
676
+ taskId: 'test-task-001',
677
+ loopNumber: 3,
678
+ agentCount: 0,
679
+ })
680
+ ).rejects.toThrow(ValidationError);
681
+ });
682
+
683
+ it('should throw ValidationError for timeout out of range', async () => {
684
+ await expect(
685
+ coordinator.waitLoop({
686
+ taskId: 'test-task-001',
687
+ loopNumber: 3,
688
+ agentCount: 2,
689
+ timeout: 0,
690
+ })
691
+ ).rejects.toThrow(ValidationError);
692
+ });
693
+
694
+ it('should throw ValidationError for timeout exceeding max', async () => {
695
+ await expect(
696
+ coordinator.waitLoop({
697
+ taskId: 'test-task-001',
698
+ loopNumber: 3,
699
+ agentCount: 2,
700
+ timeout: 4000,
701
+ })
702
+ ).rejects.toThrow(ValidationError);
703
+ });
704
+ });
705
+
706
+ describe('collectConsensus', () => {
707
+ beforeEach(async () => {
708
+ // Register validators and simulate completion
709
+ for (let i = 1; i <= 3; i++) {
710
+ await coordinator.registerAgent(`validator-${i}`, 'validator');
711
+ }
712
+ });
713
+
714
+ it('should collect consensus when threshold met', async () => {
715
+ await coordinator.signalComplete('validator-1', 0.95, 1);
716
+ await coordinator.signalComplete('validator-2', 0.90, 1);
717
+ await coordinator.signalComplete('validator-3', 0.92, 1);
718
+
719
+ const result = await coordinator.collectConsensus({
720
+ taskId: 'test-task-001',
721
+ loopNumber: 2,
722
+ requiredConsensus: 0.90,
723
+ timeout: 5,
724
+ });
725
+
726
+ expect(result.success).toBe(true);
727
+ expect(result.responsesReceived).toBe(3);
728
+ expect(result.averageConfidence).toBeGreaterThanOrEqual(0.90);
729
+ expect(result.consensusReached).toBe(true);
730
+ });
731
+
732
+ it('should return PROCEED decision for high confidence', async () => {
733
+ await coordinator.signalComplete('validator-1', 0.92, 1);
734
+ await coordinator.signalComplete('validator-2', 0.91, 1);
735
+
736
+ const result = await coordinator.collectConsensus({
737
+ taskId: 'test-task-001',
738
+ loopNumber: 2,
739
+ requiredConsensus: 0.90,
740
+ timeout: 5,
741
+ });
742
+
743
+ expect(result.decision).toBe('PROCEED');
744
+ });
745
+
746
+ it('should return COMPLETE decision for very high confidence', async () => {
747
+ await coordinator.signalComplete('validator-1', 0.98, 1);
748
+ await coordinator.signalComplete('validator-2', 0.96, 1);
749
+
750
+ const result = await coordinator.collectConsensus({
751
+ taskId: 'test-task-001',
752
+ loopNumber: 2,
753
+ requiredConsensus: 0.90,
754
+ timeout: 5,
755
+ });
756
+
757
+ expect(result.decision).toBe('COMPLETE');
758
+ });
759
+
760
+ it('should timeout when consensus not reached', async () => {
761
+ await coordinator.signalComplete('validator-1', 0.70, 1);
762
+
763
+ const result = await coordinator.collectConsensus({
764
+ taskId: 'test-task-001',
765
+ loopNumber: 2,
766
+ requiredConsensus: 0.90,
767
+ timeout: 1,
768
+ });
769
+
770
+ expect(result.success).toBe(false);
771
+ expect(result.consensusReached).toBe(false);
772
+ expect(result.decision).toBe('ABORT');
773
+ });
774
+
775
+ it('should throw ValidationError for invalid task ID', async () => {
776
+ await expect(
777
+ coordinator.collectConsensus({
778
+ taskId: 'invalid@task',
779
+ loopNumber: 2,
780
+ requiredConsensus: 0.90,
781
+ })
782
+ ).rejects.toThrow(ValidationError);
783
+ });
784
+
785
+ it('should throw ValidationError for invalid loop number', async () => {
786
+ await expect(
787
+ coordinator.collectConsensus({
788
+ taskId: 'test-task-001',
789
+ loopNumber: 0,
790
+ requiredConsensus: 0.90,
791
+ })
792
+ ).rejects.toThrow(ValidationError);
793
+ });
794
+
795
+ it('should throw ValidationError for invalid consensus < 0', async () => {
796
+ await expect(
797
+ coordinator.collectConsensus({
798
+ taskId: 'test-task-001',
799
+ loopNumber: 2,
800
+ requiredConsensus: -0.1,
801
+ })
802
+ ).rejects.toThrow(ValidationError);
803
+ });
804
+
805
+ it('should throw ValidationError for invalid consensus > 1', async () => {
806
+ await expect(
807
+ coordinator.collectConsensus({
808
+ taskId: 'test-task-001',
809
+ loopNumber: 2,
810
+ requiredConsensus: 1.1,
811
+ })
812
+ ).rejects.toThrow(ValidationError);
813
+ });
814
+
815
+ it('should throw ValidationError for timeout out of range', async () => {
816
+ await expect(
817
+ coordinator.collectConsensus({
818
+ taskId: 'test-task-001',
819
+ loopNumber: 2,
820
+ requiredConsensus: 0.90,
821
+ timeout: 0,
822
+ })
823
+ ).rejects.toThrow(ValidationError);
824
+ });
825
+ });
826
+
827
+ describe('healthCheck', () => {
828
+ it('should pass health check', async () => {
829
+ await expect(coordinator.healthCheck()).resolves.not.toThrow();
830
+ });
831
+
832
+ it('should log health check information', async () => {
833
+ mockLogger.clear();
834
+ await coordinator.healthCheck();
835
+
836
+ const logMessages = mockLogger.logs.map((l) => l.message);
837
+ expect(logMessages.some((msg) => msg.includes('health check'))).toBe(true);
838
+ });
839
+ });
840
+
841
+ describe('cleanup', () => {
842
+ it('should clean up task data', async () => {
843
+ await coordinator.initTask({ test: 'value' });
844
+ await coordinator.registerAgent('agent-001', 'developer');
845
+
846
+ await coordinator.cleanup();
847
+
848
+ const taskExists = await mockRedis.exists(
849
+ 'cfn_docker:task:test-task-001:meta'
850
+ );
851
+ expect(taskExists).toBe(false);
852
+ });
853
+ });
854
+
855
+ describe('disconnect', () => {
856
+ it('should disconnect from Redis', async () => {
857
+ await expect(coordinator.disconnect()).resolves.not.toThrow();
858
+ });
859
+ });
860
+
861
+ describe('Error handling', () => {
862
+ it('should handle Redis connection errors gracefully', async () => {
863
+ const failingRedis: IRedisClient = {
864
+ ...mockRedis,
865
+ exists: jest.fn().mockRejectedValue(new Error('Connection failed')),
866
+ };
867
+
868
+ const failingCoordinator = new RedisCoordinator(
869
+ config,
870
+ mockLogger,
871
+ failingRedis
872
+ );
873
+
874
+ await expect(failingCoordinator.getContext()).rejects.toThrow();
875
+ });
876
+
877
+ it('should catch and log errors in initTask', async () => {
878
+ const failingRedis: IRedisClient = {
879
+ ...mockRedis,
880
+ hset: jest.fn().mockRejectedValue(new Error('Storage failed')),
881
+ };
882
+
883
+ const failingCoordinator = new RedisCoordinator(
884
+ config,
885
+ mockLogger,
886
+ failingRedis
887
+ );
888
+
889
+ mockLogger.clear();
890
+ await expect(failingCoordinator.initTask()).rejects.toThrow();
891
+ expect(
892
+ mockLogger.logs.some((l) => l.level === 'error')
893
+ ).toBe(true);
894
+ });
895
+ });
896
+
897
+ describe('Confidence validation', () => {
898
+ beforeEach(async () => {
899
+ await coordinator.registerAgent('agent-001', 'developer');
900
+ });
901
+
902
+ it('should accept confidence of 0.0', async () => {
903
+ await expect(
904
+ coordinator.signalComplete('agent-001', 0.0)
905
+ ).resolves.not.toThrow();
906
+ });
907
+
908
+ it('should accept confidence of 1.0', async () => {
909
+ await expect(
910
+ coordinator.signalComplete('agent-001', 1.0)
911
+ ).resolves.not.toThrow();
912
+ });
913
+
914
+ it('should accept confidence of 0.5', async () => {
915
+ await expect(
916
+ coordinator.signalComplete('agent-001', 0.5)
917
+ ).resolves.not.toThrow();
918
+ });
919
+
920
+ it('should reject NaN confidence', async () => {
921
+ await expect(
922
+ coordinator.signalComplete('agent-001', NaN)
923
+ ).rejects.toThrow(ValidationError);
924
+ });
925
+
926
+ it('should reject Infinity confidence', async () => {
927
+ await expect(
928
+ coordinator.signalComplete('agent-001', Infinity)
929
+ ).rejects.toThrow(ValidationError);
930
+ });
931
+ });
932
+
933
+ describe('Agent ID validation', () => {
934
+ it('should accept alphanumeric agent IDs', async () => {
935
+ await expect(
936
+ coordinator.registerAgent('agent123', 'developer')
937
+ ).resolves.not.toThrow();
938
+ });
939
+
940
+ it('should accept agent IDs with hyphens', async () => {
941
+ await expect(
942
+ coordinator.registerAgent('agent-001-backend', 'developer')
943
+ ).resolves.not.toThrow();
944
+ });
945
+
946
+ it('should accept agent IDs with underscores', async () => {
947
+ await expect(
948
+ coordinator.registerAgent('agent_001_backend', 'developer')
949
+ ).resolves.not.toThrow();
950
+ });
951
+
952
+ it('should reject agent IDs with special characters', async () => {
953
+ await expect(
954
+ coordinator.registerAgent('agent@001!', 'developer')
955
+ ).rejects.toThrow(ValidationError);
956
+ });
957
+
958
+ it('should reject agent IDs with spaces', async () => {
959
+ await expect(
960
+ coordinator.registerAgent('agent 001', 'developer')
961
+ ).rejects.toThrow(ValidationError);
962
+ });
963
+
964
+ it('should reject overly long agent IDs', async () => {
965
+ const longId = 'a'.repeat(257);
966
+ await expect(
967
+ coordinator.registerAgent(longId, 'developer')
968
+ ).rejects.toThrow(ValidationError);
969
+ });
970
+ });
971
+
972
+ describe('Mode-specific behavior', () => {
973
+ it('should initialize with standard mode', () => {
974
+ const stdConfig = { ...config, mode: 'standard' as const };
975
+ const stdCoordinator = new RedisCoordinator(
976
+ stdConfig,
977
+ mockLogger,
978
+ mockRedis
979
+ );
980
+ expect(stdCoordinator).toBeDefined();
981
+ });
982
+
983
+ it('should initialize with MVP mode', () => {
984
+ const mvpConfig = { ...config, mode: 'mvp' as const };
985
+ const mvpCoordinator = new RedisCoordinator(
986
+ mvpConfig,
987
+ mockLogger,
988
+ mockRedis
989
+ );
990
+ expect(mvpCoordinator).toBeDefined();
991
+ });
992
+
993
+ it('should initialize with enterprise mode', () => {
994
+ const enterpriseConfig = { ...config, mode: 'enterprise' as const };
995
+ const enterpriseCoordinator = new RedisCoordinator(
996
+ enterpriseConfig,
997
+ mockLogger,
998
+ mockRedis
999
+ );
1000
+ expect(enterpriseCoordinator).toBeDefined();
1001
+ });
1002
+ });
1003
+
1004
+ describe('State persistence', () => {
1005
+ it('should persist agent registration across operations', async () => {
1006
+ await coordinator.registerAgent('agent-001', 'developer', 'container-123');
1007
+ await coordinator.updateStatus('agent-001', 'running');
1008
+
1009
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-001');
1010
+ expect(agentData.agent_id).toBe('agent-001');
1011
+ expect(agentData.status).toBe('running');
1012
+ });
1013
+
1014
+ it('should maintain confidence history', async () => {
1015
+ await coordinator.registerAgent('agent-001', 'developer');
1016
+ await coordinator.signalComplete('agent-001', 0.85);
1017
+ await coordinator.updateStatus('agent-001', 'running');
1018
+ await coordinator.signalComplete('agent-001', 0.90);
1019
+
1020
+ const history = await mockRedis.lrange(
1021
+ 'cfn_docker:agent:agent-001:status_history',
1022
+ 0,
1023
+ -1
1024
+ );
1025
+ expect(history.length).toBeGreaterThanOrEqual(3);
1026
+ });
1027
+ });
1028
+
1029
+ describe('Additional coverage tests', () => {
1030
+ it('should handle empty agent list in waitLoop', async () => {
1031
+ const result = await coordinator.waitLoop({
1032
+ taskId: 'test-task-001',
1033
+ loopNumber: 3,
1034
+ agentCount: 1,
1035
+ timeout: 1,
1036
+ });
1037
+
1038
+ expect(result.success).toBe(false);
1039
+ expect(result.completedAgents).toBe(0);
1040
+ });
1041
+
1042
+ it('should handle agents with special types', async () => {
1043
+ await coordinator.registerAgent('agent-001', 'tester');
1044
+ await coordinator.registerAgent('agent-002', 'validator');
1045
+ await coordinator.registerAgent('agent-003', 'product-owner');
1046
+
1047
+ await coordinator.signalComplete('agent-001', 0.88);
1048
+ await coordinator.signalComplete('agent-002', 0.91);
1049
+ await coordinator.signalComplete('agent-003', 0.87);
1050
+
1051
+ const agent1 = await mockRedis.hgetall('cfn_docker:agent:agent-001');
1052
+ expect(agent1.agent_type).toBe('tester');
1053
+
1054
+ const agent2 = await mockRedis.hgetall('cfn_docker:agent:agent-002');
1055
+ expect(agent2.agent_type).toBe('validator');
1056
+
1057
+ const agent3 = await mockRedis.hgetall('cfn_docker:agent:agent-003');
1058
+ expect(agent3.agent_type).toBe('product-owner');
1059
+ });
1060
+
1061
+ it('should handle multiple status updates in sequence', async () => {
1062
+ await coordinator.registerAgent('agent-001', 'developer');
1063
+
1064
+ const statuses: AgentStatus[] = ['running', 'working', 'completed'];
1065
+ for (let i = 0; i < statuses.length; i++) {
1066
+ await coordinator.updateStatus('agent-001', statuses[i], i + 1);
1067
+ }
1068
+
1069
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-001');
1070
+ expect(agentData.status).toBe('completed');
1071
+ expect(agentData.iteration).toBe('3');
1072
+ });
1073
+
1074
+ it('should correctly store and retrieve consensus with metadata', async () => {
1075
+ for (let i = 1; i <= 5; i++) {
1076
+ await coordinator.registerAgent(`validator-${i}`, 'validator');
1077
+ const confidence = 0.85 + i * 0.02;
1078
+ await coordinator.signalComplete(`validator-${i}`, confidence);
1079
+ }
1080
+
1081
+ const result = await coordinator.collectConsensus({
1082
+ taskId: 'test-task-001',
1083
+ loopNumber: 2,
1084
+ requiredConsensus: 0.88,
1085
+ timeout: 5,
1086
+ });
1087
+
1088
+ expect(result.success).toBe(true);
1089
+ expect(result.responsesReceived).toBeGreaterThan(0);
1090
+ expect(result.averageConfidence).toBeGreaterThanOrEqual(0.88);
1091
+ });
1092
+
1093
+ it('should handle zero iteration in updateStatus', async () => {
1094
+ await coordinator.registerAgent('agent-001', 'developer');
1095
+ await coordinator.updateStatus('agent-001', 'running', 0);
1096
+
1097
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-001');
1098
+ expect(agentData.iteration).toBe('0');
1099
+ });
1100
+
1101
+ it('should handle large iteration numbers', async () => {
1102
+ await coordinator.registerAgent('agent-001', 'developer');
1103
+ const largeIteration = 99;
1104
+ await coordinator.updateStatus('agent-001', 'completed', largeIteration);
1105
+
1106
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-001');
1107
+ expect(agentData.iteration).toBe('99');
1108
+ });
1109
+
1110
+ it('should handle context with numeric and boolean values', async () => {
1111
+ const context = {
1112
+ branch: 'main',
1113
+ iteration: 5,
1114
+ success: true,
1115
+ failed: false,
1116
+ };
1117
+
1118
+ await coordinator.storeContext(context);
1119
+ const retrieved = await coordinator.getContext();
1120
+
1121
+ expect(retrieved.branch).toBe('main');
1122
+ expect(retrieved.iteration).toBe('5');
1123
+ expect(retrieved.success).toBe('true');
1124
+ expect(retrieved.failed).toBe('false');
1125
+ });
1126
+
1127
+ it('should handle consensus with single validator', async () => {
1128
+ await coordinator.registerAgent('validator-1', 'validator');
1129
+ await coordinator.signalComplete('validator-1', 0.95);
1130
+
1131
+ const result = await coordinator.collectConsensus({
1132
+ taskId: 'test-task-001',
1133
+ loopNumber: 2,
1134
+ requiredConsensus: 0.90,
1135
+ timeout: 5,
1136
+ });
1137
+
1138
+ expect(result.success).toBe(true);
1139
+ expect(result.responsesReceived).toBe(1);
1140
+ expect(result.averageConfidence).toBe(0.95);
1141
+ });
1142
+
1143
+ it('should handle partial consensus collection', async () => {
1144
+ await coordinator.registerAgent('validator-1', 'validator');
1145
+ await coordinator.registerAgent('validator-2', 'validator');
1146
+
1147
+ await coordinator.signalComplete('validator-1', 0.92);
1148
+
1149
+ const result = await coordinator.collectConsensus({
1150
+ taskId: 'test-task-001',
1151
+ loopNumber: 2,
1152
+ requiredConsensus: 0.85,
1153
+ timeout: 5,
1154
+ });
1155
+
1156
+ expect(result.success).toBe(true);
1157
+ expect(result.responsesReceived).toBe(1);
1158
+ });
1159
+
1160
+ it('should handle consensus below threshold', async () => {
1161
+ await coordinator.registerAgent('validator-1', 'validator');
1162
+ await coordinator.registerAgent('validator-2', 'validator');
1163
+
1164
+ await coordinator.signalComplete('validator-1', 0.70);
1165
+ await coordinator.signalComplete('validator-2', 0.72);
1166
+
1167
+ const result = await coordinator.collectConsensus({
1168
+ taskId: 'test-task-001',
1169
+ loopNumber: 2,
1170
+ requiredConsensus: 0.90,
1171
+ timeout: 1,
1172
+ });
1173
+
1174
+ expect(result.success).toBe(false);
1175
+ expect(result.consensusReached).toBe(false);
1176
+ expect(result.decision).toBe('ABORT');
1177
+ });
1178
+
1179
+ it('should log operations in verbose mode', async () => {
1180
+ const verboseConfig = { ...config, verbose: true };
1181
+ const verboseCoordinator = new RedisCoordinator(
1182
+ verboseConfig,
1183
+ mockLogger,
1184
+ mockRedis
1185
+ );
1186
+
1187
+ mockLogger.clear();
1188
+ await verboseCoordinator.registerAgent('agent-001', 'developer');
1189
+ expect(
1190
+ mockLogger.logs.some((l) => l.message.includes('Agent registered'))
1191
+ ).toBe(true);
1192
+ });
1193
+
1194
+ it('should handle agent registration without container ID', async () => {
1195
+ await coordinator.registerAgent('agent-001', 'developer');
1196
+
1197
+ const agentData = await mockRedis.hgetall('cfn_docker:agent:agent-001');
1198
+ expect(agentData.container_id).toBe('');
1199
+ });
1200
+
1201
+ it('should handle default timeout values', async () => {
1202
+ const defaultConfig: CoordinatorConfig = {
1203
+ redis: {
1204
+ host: 'localhost',
1205
+ port: 6379,
1206
+ db: 0,
1207
+ },
1208
+ taskId: 'test-task-default',
1209
+ };
1210
+
1211
+ const defaultCoordinator = new RedisCoordinator(
1212
+ defaultConfig,
1213
+ mockLogger,
1214
+ mockRedis
1215
+ );
1216
+
1217
+ await defaultCoordinator.registerAgent('agent-001', 'developer');
1218
+ expect(defaultCoordinator).toBeDefined();
1219
+ });
1220
+
1221
+ it('should handle confidence edge cases', async () => {
1222
+ await coordinator.registerAgent('agent-001', 'developer');
1223
+ await coordinator.registerAgent('agent-002', 'developer');
1224
+ await coordinator.registerAgent('agent-003', 'developer');
1225
+
1226
+ // Test edge confidence values
1227
+ await coordinator.signalComplete('agent-001', 0.0);
1228
+ await coordinator.signalComplete('agent-002', 0.5);
1229
+ await coordinator.signalComplete('agent-003', 1.0);
1230
+
1231
+ const result = await coordinator.collectConsensus({
1232
+ taskId: 'test-task-001',
1233
+ loopNumber: 2,
1234
+ requiredConsensus: 0.5,
1235
+ timeout: 5,
1236
+ });
1237
+
1238
+ expect(result.success).toBe(true);
1239
+ expect(result.averageConfidence).toBeCloseTo(0.5, 1);
1240
+ });
1241
+
1242
+ it('should correctly use mode configuration', async () => {
1243
+ const modes: ExecutionMode[] = ['mvp', 'standard', 'enterprise'];
1244
+
1245
+ for (const mode of modes) {
1246
+ const modeConfig: CoordinatorConfig = {
1247
+ redis: {
1248
+ host: 'localhost',
1249
+ port: 6379,
1250
+ db: 0,
1251
+ },
1252
+ taskId: `test-task-${mode}`,
1253
+ mode,
1254
+ };
1255
+
1256
+ const modeCoordinator = new RedisCoordinator(
1257
+ modeConfig,
1258
+ mockLogger,
1259
+ mockRedis
1260
+ );
1261
+
1262
+ await modeCoordinator.initTask();
1263
+ const meta = await mockRedis.hgetall(
1264
+ `cfn_docker:task:test-task-${mode}:meta`
1265
+ );
1266
+ expect(meta.mode).toBe(mode);
1267
+ }
1268
+ });
1269
+
1270
+ it('should handle initTask errors gracefully', async () => {
1271
+ const failingRedis: IRedisClient = {
1272
+ ...mockRedis,
1273
+ hset: jest.fn().mockRejectedValue(new Error('Storage error')),
1274
+ expire: jest.fn().mockResolvedValue(1),
1275
+ exists: jest.fn().mockResolvedValue(false),
1276
+ };
1277
+
1278
+ const errorCoordinator = new RedisCoordinator(config, mockLogger, failingRedis);
1279
+
1280
+ await expect(errorCoordinator.initTask()).rejects.toThrow();
1281
+ expect(
1282
+ mockLogger.logs.some((l) => l.level === 'error')
1283
+ ).toBe(true);
1284
+ });
1285
+
1286
+ it('should handle storeContext errors gracefully', async () => {
1287
+ const failingRedis: IRedisClient = {
1288
+ ...mockRedis,
1289
+ hset: jest.fn().mockRejectedValue(new Error('Storage error')),
1290
+ expire: jest.fn().mockResolvedValue(1),
1291
+ exists: jest.fn().mockResolvedValue(false),
1292
+ };
1293
+
1294
+ const errorCoordinator = new RedisCoordinator(config, mockLogger, failingRedis);
1295
+
1296
+ await expect(
1297
+ errorCoordinator.storeContext({ test: 'value' })
1298
+ ).rejects.toThrow();
1299
+ });
1300
+
1301
+ it('should handle registerAgent errors gracefully', async () => {
1302
+ const failingRedis: IRedisClient = {
1303
+ ...mockRedis,
1304
+ hset: jest.fn().mockRejectedValue(new Error('Registration error')),
1305
+ lpush: jest.fn().mockResolvedValue(1),
1306
+ expire: jest.fn().mockResolvedValue(1),
1307
+ exists: jest.fn().mockResolvedValue(false),
1308
+ };
1309
+
1310
+ const errorCoordinator = new RedisCoordinator(config, mockLogger, failingRedis);
1311
+
1312
+ await expect(
1313
+ errorCoordinator.registerAgent('agent-001', 'developer')
1314
+ ).rejects.toThrow();
1315
+ });
1316
+
1317
+ it('should handle updateStatus errors gracefully', async () => {
1318
+ const failingRedis: IRedisClient = {
1319
+ ...mockRedis,
1320
+ hset: jest.fn().mockRejectedValue(new Error('Status update error')),
1321
+ lpush: jest.fn().mockResolvedValue(1),
1322
+ exists: jest.fn().mockResolvedValue(false),
1323
+ };
1324
+
1325
+ const errorCoordinator = new RedisCoordinator(config, mockLogger, failingRedis);
1326
+
1327
+ await coordinator.registerAgent('agent-001', 'developer');
1328
+ await expect(
1329
+ errorCoordinator.updateStatus('agent-001', 'running')
1330
+ ).rejects.toThrow();
1331
+ });
1332
+
1333
+ it('should handle signalComplete errors gracefully', async () => {
1334
+ await coordinator.registerAgent('agent-001', 'developer');
1335
+
1336
+ const failingRedis: IRedisClient = {
1337
+ ...mockRedis,
1338
+ lpush: jest.fn().mockRejectedValue(new Error('Signal error')),
1339
+ hget: jest.fn().mockResolvedValue('developer'),
1340
+ hset: jest.fn().mockResolvedValue(1),
1341
+ expire: jest.fn().mockResolvedValue(1),
1342
+ exists: jest.fn().mockResolvedValue(true),
1343
+ };
1344
+
1345
+ const errorCoordinator = new RedisCoordinator(config, mockLogger, failingRedis);
1346
+
1347
+ await expect(
1348
+ errorCoordinator.signalComplete('agent-001', 0.85)
1349
+ ).rejects.toThrow();
1350
+ });
1351
+
1352
+ it('should handle storeContext with very large values', async () => {
1353
+ const largeValue = 'x'.repeat(1024 * 1024 + 1); // 1MB + 1 byte
1354
+ const context = { large: largeValue };
1355
+
1356
+ await expect(coordinator.storeContext(context)).rejects.toThrow(
1357
+ SecurityError
1358
+ );
1359
+ });
1360
+
1361
+ it('should handle negative confidence values', async () => {
1362
+ await coordinator.registerAgent('agent-001', 'developer');
1363
+
1364
+ await expect(
1365
+ coordinator.signalComplete('agent-001', -0.001)
1366
+ ).rejects.toThrow(ValidationError);
1367
+ });
1368
+
1369
+ it('should handle consensus timeout with no responses', async () => {
1370
+ const result = await coordinator.collectConsensus({
1371
+ taskId: 'test-task-001',
1372
+ loopNumber: 2,
1373
+ requiredConsensus: 0.90,
1374
+ timeout: 1,
1375
+ });
1376
+
1377
+ expect(result.success).toBe(false);
1378
+ expect(result.responsesReceived).toBe(0);
1379
+ expect(result.decision).toBe('ABORT');
1380
+ });
1381
+
1382
+ it('should handle cleanup with non-existent task', async () => {
1383
+ const nonExistentConfig: CoordinatorConfig = {
1384
+ redis: {
1385
+ host: 'localhost',
1386
+ port: 6379,
1387
+ db: 0,
1388
+ },
1389
+ taskId: 'non-existent-task',
1390
+ };
1391
+
1392
+ const cleanupCoordinator = new RedisCoordinator(
1393
+ nonExistentConfig,
1394
+ mockLogger,
1395
+ mockRedis
1396
+ );
1397
+
1398
+ await cleanupCoordinator.cleanup();
1399
+ expect(
1400
+ mockLogger.logs.some((l) => l.message.includes('Cleanup completed'))
1401
+ ).toBe(true);
1402
+ });
1403
+
1404
+ it('should handle healthCheck with mocked Redis', async () => {
1405
+ mockLogger.clear();
1406
+ await coordinator.healthCheck();
1407
+
1408
+ const healthLogs = mockLogger.logs.filter((l) =>
1409
+ l.message.includes('health')
1410
+ );
1411
+ expect(healthLogs.length).toBeGreaterThan(0);
1412
+ });
1413
+
1414
+ it('should validate agent status types', async () => {
1415
+ await coordinator.registerAgent('agent-001', 'developer');
1416
+
1417
+ const validStatuses: AgentStatus[] = [
1418
+ 'spawning',
1419
+ 'running',
1420
+ 'working',
1421
+ 'completed',
1422
+ 'failed',
1423
+ 'timeout',
1424
+ ];
1425
+
1426
+ for (const status of validStatuses) {
1427
+ await expect(
1428
+ coordinator.updateStatus('agent-001', status)
1429
+ ).resolves.not.toThrow();
1430
+ }
1431
+ });
1432
+
1433
+ it('should handle consensus with fractional values', async () => {
1434
+ await coordinator.registerAgent('validator-1', 'validator');
1435
+ await coordinator.registerAgent('validator-2', 'validator');
1436
+
1437
+ await coordinator.signalComplete('validator-1', 0.333);
1438
+ await coordinator.signalComplete('validator-2', 0.667);
1439
+
1440
+ const result = await coordinator.collectConsensus({
1441
+ taskId: 'test-task-001',
1442
+ loopNumber: 2,
1443
+ requiredConsensus: 0.5,
1444
+ timeout: 5,
1445
+ });
1446
+
1447
+ expect(result.success).toBe(true);
1448
+ expect(result.averageConfidence).toBeCloseTo(0.5, 0);
1449
+ });
1450
+
1451
+ it('should handle very small timeout values', async () => {
1452
+ await coordinator.registerAgent('agent-001', 'developer');
1453
+
1454
+ const result = await coordinator.waitLoop({
1455
+ taskId: 'test-task-001',
1456
+ loopNumber: 3,
1457
+ agentCount: 1,
1458
+ timeout: 1,
1459
+ });
1460
+
1461
+ expect(result).toBeDefined();
1462
+ });
1463
+ });
1464
+ });