claude-flow-novice 2.6.0 → 2.8.1

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 (364) hide show
  1. package/.claude/adaptive-context/cfn-v3-reflection.json +21 -0
  2. package/.claude/agents/AGENT_LIFECYCLE.md +495 -0
  3. package/.claude/agents/CLAUDE.md +1002 -995
  4. package/.claude/agents/accessibility-advocate.md +457 -0
  5. package/.claude/agents/agent-principles/README.md +226 -226
  6. package/.claude/agents/agent-principles/agent-type-guidelines.md +10 -0
  7. package/.claude/agents/agent-principles/format-selection.md +10 -0
  8. package/.claude/agents/agent-principles/phase4-template-optimization.md +502 -494
  9. package/.claude/agents/agent-principles/prompt-engineering.md +8 -0
  10. package/.claude/agents/agent-principles/quality-metrics.md +8 -0
  11. package/.claude/agents/analysis/code-analyzer.md +7 -17
  12. package/.claude/agents/analysis/code-review/analyze-code-quality.md +2 -104
  13. package/.claude/agents/analysis/perf-analyzer.md +2 -196
  14. package/.claude/agents/context/context-curator.md +78 -84
  15. package/.claude/agents/context/context-reflector.md +27 -81
  16. package/.claude/agents/coordinators/README.md +42 -0
  17. package/.claude/agents/coordinators/cfn-v3-coordinator.md +440 -0
  18. package/.claude/agents/{product-owner-team → coordinators}/cto-agent.md +154 -187
  19. package/.claude/agents/coordinators/multi-sprint-coordinator.md +50 -0
  20. package/.claude/agents/{product-owner-team → coordinators}/product-owner-agent.md +6 -39
  21. package/.claude/agents/{cfn-loop → coordinators}/product-owner.md +72 -17
  22. package/.claude/agents/core-agents/reviewer.md +114 -135
  23. package/.claude/agents/custom/agent-builder.md +637 -637
  24. package/.claude/agents/developers/README.md +69 -0
  25. package/.claude/agents/developers/backend-dev.md +77 -0
  26. package/.claude/agents/{core-agents → developers}/coder.md +131 -26
  27. package/.claude/agents/developers/react-frontend-engineer.md +121 -0
  28. package/.claude/agents/{frontend → developers}/state-architect.md +1 -0
  29. package/.claude/agents/{frontend → developers}/ui-designer.md +1 -0
  30. package/.claude/agents/development/backend/dev-backend-api.md +0 -29
  31. package/.claude/agents/development/npm-package-specialist.md +355 -347
  32. package/.claude/agents/documentation/api-docs/docs-api-openapi.md +8 -0
  33. package/.claude/agents/documentation/api-docs.md +8 -0
  34. package/.claude/agents/github/github-commit-agent.md +125 -117
  35. package/.claude/agents/goal/goal-planner.md +8 -0
  36. package/.claude/agents/infrastructure/README.md +100 -0
  37. package/.claude/agents/{specialized → infrastructure}/devops-engineer.md +131 -150
  38. package/.claude/agents/planners/README.md +94 -0
  39. package/.claude/agents/{core-agents → planners}/analyst.md +1 -22
  40. package/.claude/agents/{planning-team → planners}/api-designer-persona.md +8 -0
  41. package/.claude/agents/{core-agents → planners}/architect.md +7 -20
  42. package/.claude/agents/{core-agents → planners}/planner.md +0 -21
  43. package/.claude/agents/{planning-team → planners}/security-architect-persona.md +8 -28
  44. package/.claude/agents/{planning-team → planners}/system-architect-persona.md +6 -38
  45. package/.claude/agents/{architecture → planners}/system-architect.md +12 -17
  46. package/.claude/agents/product-owner-team/accessibility-advocate-persona.md +132 -161
  47. package/.claude/agents/product-owner-team/power-user-persona.md +149 -182
  48. package/.claude/agents/retrospective-analyst.md +84 -0
  49. package/.claude/agents/reviewers/README.md +58 -0
  50. package/.claude/agents/{analysis → reviewers}/code-quality-validator.md +8 -17
  51. package/.claude/agents/reviewers/reviewer.md +181 -0
  52. package/.claude/agents/sparc/architecture.md +6 -25
  53. package/.claude/agents/sparc/pseudocode.md +6 -0
  54. package/.claude/agents/sparc/refinement.md +6 -0
  55. package/.claude/agents/sparc/specification.md +1 -0
  56. package/.claude/agents/specialists/README.md +60 -0
  57. package/.claude/agents/{core-agents → specialists}/base-template-generator.md +8 -21
  58. package/.claude/agents/{specialized → specialists}/cli-agent-optimizer.md +1 -1
  59. package/.claude/agents/{specialized → specialists}/code-booster.md +1 -0
  60. package/.claude/agents/{consensus → specialists}/consensus-builder.md +1 -17
  61. package/.claude/agents/{specialized/mobile → specialists}/mobile-dev.md +0 -20
  62. package/.claude/agents/{core-agents → specialists}/performance-benchmarker.md +134 -148
  63. package/.claude/agents/{specialized → specialists}/rust-developer.md +1 -20
  64. package/.claude/agents/{specialized → specialists}/rust-enterprise-developer.md +1 -20
  65. package/.claude/agents/{specialized → specialists}/rust-mvp-developer.md +1 -20
  66. package/.claude/agents/{core-agents → specialists}/security-manager.md +68 -88
  67. package/.claude/agents/{security → specialists}/security-specialist-existing.md +6 -57
  68. package/.claude/agents/{security → specialists}/security-specialist.md +6 -30
  69. package/.claude/agents/{specialized/mobile → specialists}/spec-mobile-react-native.md +2 -21
  70. package/.claude/agents/testers/README.md +94 -0
  71. package/.claude/agents/{testing → testers}/e2e/playwright-agent.md +1 -20
  72. package/.claude/agents/{testing → testers}/interaction-tester.md +1 -20
  73. package/.claude/agents/{testing → testers}/playwright-tester.md +1 -1
  74. package/.claude/agents/testers/tester.md +139 -0
  75. package/.claude/agents/testers/unit/tdd-london-swarm.md +49 -0
  76. package/.claude/agents/testers/validation/production-validator.md +33 -0
  77. package/.claude/agents-ignore/cfn-loop-coordinator.md +157 -0
  78. package/.claude/agents-ignore/cfn-loop-coordinator.md.backup +156 -0
  79. package/.claude/agents-ignore/coordinator.md.backup +182 -0
  80. package/.claude/agents-ignore/cost-savings-cfn-loop-coordinator.md +760 -0
  81. package/.claude/agents-ignore/cost-savings-coordinator.md +173 -0
  82. package/.claude/artifacts/ace-reflections/REFLECT-001-summary.json +39 -0
  83. package/.claude/artifacts/ace-reflections/sprint-7_$(date -u +/"%Y%m%d_%H%M%S/").json" +47 -0
  84. package/.claude/commands/CFN_COORDINATOR_PARAMETERS.md +10 -10
  85. package/.claude/commands/cfn-loop-epic.md +3 -3
  86. package/.claude/commands/cfn-loop-single.md +3 -3
  87. package/.claude/commands/cfn-loop-sprints.md +1 -1
  88. package/.claude/commands/cfn-loop.md +3 -3
  89. package/.claude/commands/cfn-mode.md +20 -0
  90. package/.claude/commands/write-plan.md +104 -0
  91. package/.claude/data/cfn-loop.db +0 -0
  92. package/.claude/data/cfn_loop_logs.db +0 -0
  93. package/.claude/hooks/BACKUP_USAGE.md +243 -0
  94. package/.claude/hooks/post-edit-cfn-retrospective.sh +79 -0
  95. package/.claude/hooks/post-edit.sh +21 -0
  96. package/.claude/hooks/pre-edit-backup.sh +71 -0
  97. package/.claude/hooks/restore-from-backup.sh +37 -0
  98. package/.claude/prompts/cfn-loop-context.md +115 -0
  99. package/.claude/prompts/loop-specific/loop2.md +50 -0
  100. package/.claude/prompts/loop-specific/loop3.md +43 -0
  101. package/.claude/prompts/loop-specific/loop4.md +54 -0
  102. package/.claude/root-claude-distribute/CLAUDE.md +76 -2
  103. package/.claude/skills/ace-system/sprint-7-lessons.json +46 -0
  104. package/.claude/skills/ace-system/store-reflection.sh +33 -136
  105. package/.claude/skills/agent-discovery/SKILL.md +40 -0
  106. package/.claude/skills/agent-discovery/agents-registry-clean.json +0 -0
  107. package/.claude/skills/agent-discovery/agents-registry-fixed.json +19 -0
  108. package/.claude/skills/agent-discovery/agents-registry.json +718 -0
  109. package/.claude/skills/agent-discovery/discover-agents.py +175 -0
  110. package/.claude/skills/agent-discovery/discover-agents.sh +87 -0
  111. package/.claude/skills/agent-discovery/invoke-registry.sh +11 -0
  112. package/.claude/skills/agent-discovery/temp_script.py +0 -0
  113. package/.claude/skills/agent-output-processing/SKILL.md +359 -0
  114. package/.claude/skills/agent-selector/SKILL.md +90 -0
  115. package/.claude/skills/agent-selector/select-agents.sh +96 -0
  116. package/.claude/skills/agent-spawning/agent-selection-guide.md +1 -1
  117. package/.claude/skills/agent-swap/SKILL.md +36 -0
  118. package/.claude/skills/agent-swap/recommend-swap.sh +60 -0
  119. package/.claude/skills/api-validation/test-endpoints.sh +54 -0
  120. package/.claude/skills/automatic-memory-persistence/SKILL.md +73 -0
  121. package/.claude/skills/automatic-memory-persistence/persist-agent-output.sh +49 -0
  122. package/.claude/skills/automatic-memory-persistence/query-agent-history.sh +35 -0
  123. package/.claude/skills/automatic-memory-persistence/test-memory-persistence.sh +235 -0
  124. package/.claude/skills/cfn-loop-orchestration/README.md +41 -0
  125. package/.claude/skills/cfn-loop-orchestration/SKILL.md +299 -0
  126. package/.claude/skills/cfn-loop-orchestration/helpers/auto-tune-timeouts.sh +228 -0
  127. package/.claude/skills/cfn-loop-orchestration/helpers/consensus.sh +84 -0
  128. package/.claude/skills/cfn-loop-orchestration/helpers/deliverable-verifier.sh +71 -0
  129. package/.claude/skills/cfn-loop-orchestration/helpers/gate-check.sh +90 -0
  130. package/.claude/skills/cfn-loop-orchestration/helpers/iteration-manager.sh +87 -0
  131. package/.claude/skills/cfn-loop-orchestration/helpers/timeout-calculator.sh +51 -0
  132. package/.claude/skills/cfn-loop-orchestration/inject-loop-context.sh +41 -0
  133. package/.claude/skills/cfn-loop-orchestration/monitor-execution.sh +156 -0
  134. package/.claude/skills/cfn-loop-orchestration/orchestrate.sh +840 -0
  135. package/.claude/skills/cfn-loop-orchestration/security_utils.sh +99 -0
  136. package/.claude/skills/cfn-loop-orchestration/test-cfn-orchestration.sh +281 -0
  137. package/.claude/skills/cfn-loop-orchestration/test-edge-cases.sh +188 -0
  138. package/.claude/skills/cfn-loop-validation/SKILL.md +307 -217
  139. package/.claude/skills/complexity-estimator/SKILL.md +96 -0
  140. package/.claude/skills/complexity-estimator/estimate-complexity.sh +144 -0
  141. package/.claude/skills/context-pruner/SKILL.md +75 -0
  142. package/.claude/skills/context-pruner/prune-context.sh +73 -0
  143. package/.claude/skills/defense-in-depth/SKILL.md +133 -0
  144. package/.claude/skills/dependency-extractor/SKILL.md +35 -0
  145. package/.claude/skills/dependency-extractor/extract-dependencies.sh +66 -0
  146. package/.claude/skills/epic-decomposer/SKILL.md +44 -0
  147. package/.claude/skills/epic-decomposer/decompose-epic.sh +104 -0
  148. package/.claude/skills/improvement-recommender/SKILL.md +33 -0
  149. package/.claude/skills/improvement-recommender/recommend-improvements.sh +92 -0
  150. package/.claude/skills/intervention-detector/SKILL.md +39 -0
  151. package/.claude/skills/intervention-detector/detect-intervention.sh +111 -0
  152. package/.claude/skills/intervention-orchestrator/SKILL.md +43 -0
  153. package/.claude/skills/intervention-orchestrator/execute-intervention.sh +59 -0
  154. package/.claude/skills/loop2-output-processing/SKILL.md +163 -0
  155. package/.claude/skills/loop2-output-processing/execute-and-extract.sh +77 -0
  156. package/.claude/skills/loop2-output-processing/execute-and-extract.sh.backup +36 -0
  157. package/.claude/skills/loop2-output-processing/parse-feedback.sh +147 -0
  158. package/.claude/skills/loop2-output-processing/process-validator-output.sh +275 -0
  159. package/.claude/skills/loop2-output-processing/test-bug27-fix.sh +200 -0
  160. package/.claude/skills/loop2-output-processing/test-loop2-processing.sh +113 -0
  161. package/.claude/skills/loop3-output-processing/AGENT_COMPLETION_PROTOCOL.md +206 -0
  162. package/.claude/skills/loop3-output-processing/SKILL.md +421 -0
  163. package/.claude/skills/loop3-output-processing/calculate-confidence.sh +28 -0
  164. package/.claude/skills/loop3-output-processing/execute-and-extract.sh +85 -0
  165. package/.claude/skills/loop3-output-processing/parse-confidence.sh +31 -0
  166. package/.claude/skills/loop3-output-processing/test-agent-timeout.sh +327 -0
  167. package/.claude/skills/loop3-output-processing/test-loop3-processing.sh +155 -0
  168. package/.claude/skills/loop3-output-processing/verify-deliverables.sh +42 -0
  169. package/.claude/skills/pattern-extraction/SKILL.md +30 -0
  170. package/.claude/skills/pattern-extraction/extract-patterns.sh +80 -0
  171. package/.claude/skills/playbook/SKILL.md +113 -0
  172. package/.claude/skills/playbook/init-playbook.sh +54 -0
  173. package/.claude/skills/playbook/playbook.db +0 -0
  174. package/.claude/skills/playbook/query-playbook.sh +79 -0
  175. package/.claude/skills/playbook/update-playbook.sh +69 -0
  176. package/.claude/skills/playbook-auto-update/SKILL.md +29 -0
  177. package/.claude/skills/playbook-auto-update/auto-update-playbook.sh +86 -0
  178. package/.claude/skills/product-owner-decision/SKILL.md +332 -0
  179. package/.claude/skills/product-owner-decision/execute-decision.sh +176 -0
  180. package/.claude/skills/product-owner-decision/parse-decision.sh +66 -0
  181. package/.claude/skills/product-owner-decision/validate-deliverables.sh +82 -0
  182. package/.claude/skills/redis-coordination/LOGGING.md +260 -0
  183. package/.claude/skills/redis-coordination/README.md +30 -29
  184. package/.claude/skills/redis-coordination/SKILL.md +685 -83
  185. package/.claude/skills/redis-coordination/analyze-task-complexity.sh +277 -0
  186. package/.claude/skills/redis-coordination/cfn-loop-exec.sh +468 -0
  187. package/.claude/skills/redis-coordination/collect-confidence-scores.sh +179 -0
  188. package/.claude/skills/redis-coordination/collect-results.sh +75 -0
  189. package/.claude/skills/redis-coordination/data/cfn-loop.db +0 -0
  190. package/.claude/skills/redis-coordination/{test-orchestrator.sh → demos/test-orchestrator.sh} +25 -0
  191. package/.claude/skills/redis-coordination/execute-product-owner-decision.sh +258 -0
  192. package/.claude/skills/redis-coordination/get-agent-timeout.sh +176 -176
  193. package/.claude/skills/redis-coordination/invoke-waiting-mode.sh +93 -227
  194. package/.claude/skills/redis-coordination/invoke-waiting-mode.sh.backup-p7 +423 -0
  195. package/.claude/skills/redis-coordination/log-event.sh +109 -0
  196. package/.claude/skills/redis-coordination/monitor-cfn-violations.sh +391 -0
  197. package/.claude/skills/redis-coordination/orchestrate-cfn-loop-v3.sh +141 -0
  198. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh +31 -993
  199. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.backup +38 -0
  200. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.backup-1761167675 +1672 -0
  201. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.backup-p5 +1604 -0
  202. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.backup-phase1 +1550 -0
  203. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.backup-phase2 +1621 -0
  204. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.backup-phase3 +1621 -0
  205. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.bak +0 -0
  206. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.broken +1627 -0
  207. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.corrupted +80 -0
  208. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.deprecated +1864 -0
  209. package/.claude/skills/redis-coordination/query-logs.sh +103 -0
  210. package/.claude/skills/redis-coordination/retrieve-context.sh +58 -0
  211. package/.claude/skills/redis-coordination/select-specialist-agent.sh +371 -0
  212. package/.claude/skills/redis-coordination/semantic-match-tfidf.py +252 -0
  213. package/.claude/skills/redis-coordination/send-heartbeat.sh +164 -72
  214. package/.claude/skills/redis-coordination/signal.sh +38 -0
  215. package/.claude/skills/redis-coordination/store-context.sh +86 -0
  216. package/.claude/skills/redis-coordination/test-context-injection.sh +354 -0
  217. package/.claude/skills/redis-coordination/test-timeout-enforcement.sh +513 -0
  218. package/.claude/skills/redis-coordination/tests/convert-line-endings.sh +15 -0
  219. package/.claude/skills/redis-coordination/tests/dlq-functionality-test.sh +101 -101
  220. package/.claude/skills/redis-coordination/tests/edge-cases-test.sh +98 -98
  221. package/.claude/skills/redis-coordination/tests/integration-test.sh +169 -169
  222. package/.claude/skills/redis-coordination/tests/retry-mechanism-test.sh +81 -81
  223. package/.claude/skills/redis-coordination/tests/run-test-suite.sh +91 -91
  224. package/.claude/skills/redis-coordination/tests/run-tests.sh +4 -0
  225. package/.claude/skills/redis-coordination/tests/test-primitives.sh +166 -0
  226. package/.claude/skills/redis-coordination/tests/test-utils.sh +53 -121
  227. package/.claude/skills/redis-coordination/tests/test_coordination_primitives.sh.deprecated +20 -0
  228. package/.claude/skills/redis-coordination/tests/test_utils.sh +49 -0
  229. package/.claude/skills/redis-coordination/v2_modularization/core_orchestration.sh +76 -0
  230. package/.claude/skills/redis-coordination/validate-parameters.sh +492 -0
  231. package/.claude/skills/retrospective-report/SKILL.md +31 -0
  232. package/.claude/skills/retrospective-report/generate-report.sh +101 -0
  233. package/.claude/skills/run-all-skill-tests.sh +124 -0
  234. package/.claude/skills/scope-simplifier/SKILL.md +37 -0
  235. package/.claude/skills/scope-simplifier/simplify-scope.sh +68 -0
  236. package/.claude/skills/simplified-agent-lifecycle/COST_ANALYSIS.md +49 -0
  237. package/.claude/skills/simplified-agent-lifecycle/DESIGN.md +98 -0
  238. package/.claude/skills/simplified-agent-lifecycle/MIGRATION_PLAN.md +74 -0
  239. package/.claude/skills/specialist-injection/SKILL.md +41 -0
  240. package/.claude/skills/specialist-injection/recommend-specialist.sh +57 -0
  241. package/.claude/skills/sprint-execution/SKILL.md +27 -0
  242. package/.claude/skills/sprint-execution/execute-sprint-task.sh +59 -0
  243. package/.claude/skills/sprint-execution/execute-sprint.sh +65 -0
  244. package/.claude/skills/sprint-planner/SKILL.md +37 -0
  245. package/.claude/skills/sprint-planner/plan-sprint.sh +85 -0
  246. package/.claude/skills/standardized-error-handling/SKILL.md +56 -0
  247. package/.claude/skills/standardized-error-handling/capture-agent-error.sh +87 -0
  248. package/.claude/skills/standardized-error-handling/test-error-handling.sh +166 -0
  249. package/.claude/skills/task-classifier/SKILL.md +94 -0
  250. package/.claude/skills/task-classifier/classify-task.sh +115 -0
  251. package/.claude/skills/validation-templates/SKILL.md +47 -0
  252. package/.claude/skills/validation-templates/content.json +38 -0
  253. package/.claude/skills/validation-templates/data.json +38 -0
  254. package/.claude/skills/validation-templates/design.json +38 -0
  255. package/.claude/skills/validation-templates/infrastructure.json +38 -0
  256. package/.claude/skills/validation-templates/research.json +38 -0
  257. package/.claude/skills/validation-templates/software.json +38 -0
  258. package/.claude/skills/webapp-testing/README.md +142 -0
  259. package/.claude/skills/webapp-testing/SCREENSHOT_NAMING_CONVENTION.md +547 -0
  260. package/.claude/skills/webapp-testing/SKILL.md +877 -0
  261. package/.claude/skills/webapp-testing/capture-screenshot.sh +238 -0
  262. package/.claude/skills/webapp-testing/cfn-loop-integration.sh +265 -0
  263. package/.claude/skills/webapp-testing/compare-screenshots.sh +199 -0
  264. package/.claude/skills/webapp-testing/init-storage.sh +150 -0
  265. package/.claude/skills/webapp-testing/set-baseline.sh +196 -0
  266. package/.claude/skills/webapp-testing/test-webapp-testing.sh +233 -0
  267. package/.claude/spawn-pattern-examples.md +3 -3
  268. package/CLAUDE.md +319 -45
  269. package/README.md +598 -251
  270. package/dist/agents/agent-loader.js +146 -165
  271. package/dist/agents/agent-loader.js.map +1 -1
  272. package/dist/cli/agent-command.js +2 -0
  273. package/dist/cli/agent-command.js.map +1 -1
  274. package/dist/cli/agent-definition-parser.js +7 -0
  275. package/dist/cli/agent-definition-parser.js.map +1 -1
  276. package/dist/cli/agent-executor.js +145 -11
  277. package/dist/cli/agent-executor.js.map +1 -1
  278. package/dist/cli/agent-prompt-builder.js +81 -1
  279. package/dist/cli/agent-prompt-builder.js.map +1 -1
  280. package/dist/cli/agent-spawn.js +10 -1
  281. package/dist/cli/agent-spawn.js.map +1 -1
  282. package/dist/cli/anthropic-client.js +192 -13
  283. package/dist/cli/anthropic-client.js.map +1 -1
  284. package/dist/cli/cfn-context.js +150 -0
  285. package/dist/cli/cfn-context.js.map +1 -1
  286. package/dist/cli/cfn-fork.js +159 -0
  287. package/dist/cli/cfn-fork.js.map +1 -0
  288. package/dist/cli/cli-agent-context.js +8 -3
  289. package/dist/cli/cli-agent-context.js.map +1 -1
  290. package/dist/cli/config-manager.js +109 -91
  291. package/dist/cli/config-manager.js.map +1 -1
  292. package/dist/cli/conversation-fork.js +201 -0
  293. package/dist/cli/conversation-fork.js.map +1 -0
  294. package/dist/cli/index.js +4 -0
  295. package/dist/cli/index.js.map +1 -1
  296. package/dist/cli/tool-definitions.js +263 -0
  297. package/dist/cli/tool-definitions.js.map +1 -0
  298. package/dist/cli/tool-executor.js +247 -0
  299. package/dist/cli/tool-executor.js.map +1 -0
  300. package/dist/hello.js +8 -0
  301. package/dist/hello.js.map +1 -0
  302. package/package.json +14 -6
  303. package/scripts/README.md +68 -0
  304. package/scripts/cfn-intervention-example.sh +21 -0
  305. package/scripts/migrate-test-infrastructure.sh +40 -0
  306. package/scripts/validate-test-migration.sh +49 -0
  307. package/scripts/verify-no-secrets.sh +55 -0
  308. package/.claude/agents/architecture/system-architect.md.backup +0 -603
  309. package/.claude/agents/code-booster.md +0 -131
  310. package/.claude/agents/consensus/performance-benchmarker.md +0 -101
  311. package/.claude/agents/consensus/security-manager.md +0 -107
  312. package/.claude/agents/context-curator.md +0 -167
  313. package/.claude/agents/context-reflector.md +0 -65
  314. package/.claude/agents/core-agents/cfn-loop-coordinator.md +0 -134
  315. package/.claude/agents/core-agents/code-quality-validator.md +0 -149
  316. package/.claude/agents/core-agents/context-curator.md +0 -452
  317. package/.claude/agents/core-agents/context-reflector.md +0 -273
  318. package/.claude/agents/core-agents/cost-savings-cfn-loop-coordinator.md +0 -235
  319. package/.claude/agents/core-agents/tester.md +0 -170
  320. package/.claude/agents/development/backend-dev.md +0 -165
  321. package/.claude/agents/devops/devops-engineer.md +0 -148
  322. package/.claude/agents/frontend/interaction-tester.md +0 -139
  323. package/.claude/agents/frontend/react-frontend-engineer.md +0 -9
  324. package/.claude/agents/personas/accessibility-advocate-persona.md +0 -107
  325. package/.claude/agents/testing/production-validator.md +0 -179
  326. package/.claude/agents/testing/tdd-london-swarm.md +0 -209
  327. package/.claude/agents/testing/unit/tdd-london-swarm.md +0 -43
  328. package/.claude/agents/testing/validation/production-validator.md +0 -43
  329. package/.claude/api-configs/config-current-zai-config.env +0 -62
  330. package/.claude/api-configs/config-test-zai-config.env +0 -62
  331. package/.claude/api-configs/env-backups/before-anthropic-20251020-025404.env +0 -62
  332. package/.claude/api-configs/env-backups/before-restore-20251020-025431.env +0 -62
  333. package/.claude/skills/redis-coordination/orchestrate-cfn-loop.sh.backup-1760949407 +0 -933
  334. package/dist/cli/cli-agent-context.test.js +0 -451
  335. package/dist/cli/cli-agent-context.test.js.map +0 -1
  336. package/dist/coordination/fleet-manager.test.js +0 -141
  337. package/dist/coordination/fleet-manager.test.js.map +0 -1
  338. package/dist/middleware/transparency-middleware.test.js +0 -184
  339. package/dist/middleware/transparency-middleware.test.js.map +0 -1
  340. /package/.claude/agents/{core-agents → developers}/researcher.md +0 -0
  341. /package/.claude/agents/{consensus → specialists}/crdt-synchronizer.md +0 -0
  342. /package/.claude/agents/{consensus → specialists}/quorum-manager.md +0 -0
  343. /package/.claude/agents/{consensus → specialists}/raft-manager.md +0 -0
  344. /package/.claude/{agents/core-agents → agents-ignore}/coordinator.md +0 -0
  345. /package/.claude/{agents/core-agents/cost-savings-coordinator.md → agents-ignore/cost-savings-coordinator.md.backup} +0 -0
  346. /package/.claude/skills/redis-coordination/{phase4-wake-queue-test-report.md → demos/phase4-wake-queue-test-report.md} +0 -0
  347. /package/.claude/skills/redis-coordination/{test-bzpopmin-fix.sh → demos/test-bzpopmin-fix.sh} +0 -0
  348. /package/.claude/skills/redis-coordination/{test-cancel-swarm.sh → demos/test-cancel-swarm.sh} +0 -0
  349. /package/.claude/skills/redis-coordination/{test-dlq.sh → demos/test-dlq.sh} +0 -0
  350. /package/.claude/skills/redis-coordination/{test-iteration-feedback.sh → demos/test-iteration-feedback.sh} +0 -0
  351. /package/.claude/skills/redis-coordination/{test-priority-wake-phase4-unix.sh → demos/test-priority-wake-phase4-unix.sh} +0 -0
  352. /package/.claude/skills/redis-coordination/{test-priority-wake-phase4.sh → demos/test-priority-wake-phase4.sh} +0 -0
  353. /package/.claude/skills/redis-coordination/{test-priority-wake.sh → demos/test-priority-wake.sh} +0 -0
  354. /package/.claude/skills/redis-coordination/{test-quick-fix.sh → demos/test-quick-fix.sh} +0 -0
  355. /package/.claude/skills/redis-coordination/{test-quorum-absolute.sh → demos/test-quorum-absolute.sh} +0 -0
  356. /package/.claude/skills/redis-coordination/{test-quorum-fallback.sh → demos/test-quorum-fallback.sh} +0 -0
  357. /package/.claude/skills/redis-coordination/{test-quorum-percentage.sh → demos/test-quorum-percentage.sh} +0 -0
  358. /package/.claude/skills/redis-coordination/{test-quorum-with-retry.sh → demos/test-quorum-with-retry.sh} +0 -0
  359. /package/.claude/skills/redis-coordination/{test-quorum.sh → demos/test-quorum.sh} +0 -0
  360. /package/.claude/skills/redis-coordination/{test-shutdown-handling.sh → demos/test-shutdown-handling.sh} +0 -0
  361. /package/.claude/skills/redis-coordination/{test-shutdown.sh → demos/test-shutdown.sh} +0 -0
  362. /package/.claude/skills/redis-coordination/{test-utils-unix.sh → demos/test-utils-unix.sh} +0 -0
  363. /package/.claude/skills/redis-coordination/{test-utils.sh → demos/test-utils.sh} +0 -0
  364. /package/.claude/skills/redis-coordination/{test-waiting-mode.sh → demos/test-waiting-mode.sh} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/agent-spawn.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * Agent Spawning CLI - Direct agent process spawning\r\n *\r\n * Usage:\r\n * npx cfn-spawn agent <type> [options]\r\n * npx cfn-spawn <type> [options] (agent is implied)\r\n *\r\n * Examples:\r\n * npx cfn-spawn agent researcher --task-id task-123 --iteration 1\r\n * npx cfn-spawn researcher --task-id task-123 --iteration 1\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\nimport { resolve } from 'path';\r\n\r\ninterface AgentSpawnOptions {\r\n agentType: string;\r\n taskId?: string;\r\n iteration?: number;\r\n context?: string;\r\n mode?: string;\r\n priority?: number;\r\n parentTaskId?: string;\r\n}\r\n\r\n/**\r\n * Parse command line arguments for agent spawning\r\n */\r\nfunction parseAgentArgs(args: string[]): AgentSpawnOptions | null {\r\n // Handle both \"agent <type>\" and \"<type>\" patterns\r\n let agentType: string;\r\n let optionArgs: string[];\r\n\r\n if (args[0] === 'agent') {\r\n agentType = args[1];\r\n optionArgs = args.slice(2);\r\n } else {\r\n agentType = args[0];\r\n optionArgs = args.slice(1);\r\n }\r\n\r\n if (!agentType) {\r\n console.error('Error: Agent type is required');\r\n console.error('Usage: cfn-spawn agent <type> [options]');\r\n return null;\r\n }\r\n\r\n const options: AgentSpawnOptions = { agentType };\r\n\r\n // Parse optional parameters\r\n for (let i = 0; i < optionArgs.length; i += 2) {\r\n const key = optionArgs[i];\r\n const value = optionArgs[i + 1];\r\n\r\n switch (key) {\r\n case '--task-id':\r\n options.taskId = value;\r\n break;\r\n case '--iteration':\r\n options.iteration = parseInt(value, 10);\r\n break;\r\n case '--context':\r\n options.context = value;\r\n break;\r\n case '--mode':\r\n options.mode = value;\r\n break;\r\n case '--priority':\r\n options.priority = parseInt(value, 10);\r\n break;\r\n case '--parent-task':\r\n case '--parent-task-id':\r\n options.parentTaskId = value;\r\n break;\r\n default:\r\n console.warn(`Unknown option: ${key}`);\r\n }\r\n }\r\n\r\n return options;\r\n}\r\n\r\n/**\r\n * Spawn an agent process using npx claude-flow-novice agent\r\n *\r\n * This is a wrapper/alias for the existing claude-flow-novice agent spawning mechanism\r\n * Provides the cfn-spawn naming pattern while delegating to the working implementation\r\n */\r\nasync function spawnAgent(options: AgentSpawnOptions): Promise<void> {\r\n const { agentType, taskId, iteration, context, mode, priority, parentTaskId } = options;\r\n\r\n console.log(`[cfn-spawn] Spawning agent: ${agentType}`);\r\n if (taskId) console.log(`[cfn-spawn] Task ID: ${taskId}`);\r\n if (iteration) console.log(`[cfn-spawn] Iteration: ${iteration}`);\r\n if (context) console.log(`[cfn-spawn] Context: ${context}`);\r\n if (mode) console.log(`[cfn-spawn] Mode: ${mode}`);\r\n\r\n // Build command arguments for npx claude-flow-novice agent\r\n const claudeArgs = ['claude-flow-novice', 'agent', agentType];\r\n\r\n // Add optional parameters\r\n if (taskId) {\r\n claudeArgs.push('--task-id', taskId);\r\n }\r\n if (iteration) {\r\n claudeArgs.push('--iteration', iteration.toString());\r\n }\r\n if (context) {\r\n claudeArgs.push('--context', context);\r\n }\r\n if (mode) {\r\n claudeArgs.push('--mode', mode);\r\n }\r\n if (priority) {\r\n claudeArgs.push('--priority', priority.toString());\r\n }\r\n if (parentTaskId) {\r\n claudeArgs.push('--parent-task-id', parentTaskId);\r\n }\r\n\r\n // Fetch epic context from Redis if available\r\n let epicContext = '';\r\n let phaseContext = '';\r\n let successCriteria = '';\r\n\r\n if (taskId) {\r\n try {\r\n const { execSync } = await import('child_process');\r\n\r\n // Try to read epic-level context from Redis\r\n try {\r\n epicContext = execSync(`redis-cli get \"swarm:${taskId}:epic-context\"`, { encoding: 'utf8' }).trim();\r\n if (epicContext === '(nil)') epicContext = '';\r\n } catch (e) {\r\n // Redis not available or key doesn't exist\r\n }\r\n\r\n // Try to read phase-specific context\r\n try {\r\n phaseContext = execSync(`redis-cli get \"swarm:${taskId}:phase-context\"`, { encoding: 'utf8' }).trim();\r\n if (phaseContext === '(nil)') phaseContext = '';\r\n } catch (e) {\r\n // Redis not available or key doesn't exist\r\n }\r\n\r\n // Try to read success criteria\r\n try {\r\n successCriteria = execSync(`redis-cli get \"swarm:${taskId}:success-criteria\"`, { encoding: 'utf8' }).trim();\r\n if (successCriteria === '(nil)') successCriteria = '';\r\n } catch (e) {\r\n // Redis not available or key doesn't exist\r\n }\r\n\r\n if (epicContext) {\r\n console.log(`[cfn-spawn] Epic context loaded from Redis`);\r\n }\r\n } catch (err) {\r\n console.warn(`[cfn-spawn] Could not load epic context from Redis:`, err);\r\n }\r\n }\r\n\r\n // Add environment variables for agent context\r\n const env = {\r\n ...process.env,\r\n AGENT_TYPE: agentType,\r\n TASK_ID: taskId || '',\r\n ITERATION: iteration?.toString() || '1',\r\n CONTEXT: context || '',\r\n MODE: mode || 'cli',\r\n PRIORITY: priority?.toString() || '5',\r\n PARENT_TASK_ID: parentTaskId || '',\r\n // Epic-level context from Redis\r\n EPIC_CONTEXT: epicContext,\r\n PHASE_CONTEXT: phaseContext,\r\n SUCCESS_CRITERIA: successCriteria\r\n };\r\n\r\n console.log(`[cfn-spawn] Executing: npx ${claudeArgs.join(' ')}`);\r\n\r\n // Spawn the claude-flow-novice agent process\r\n const agentProcess = spawn('npx', claudeArgs, {\r\n stdio: 'inherit',\r\n env,\r\n cwd: process.cwd()\r\n });\r\n\r\n // Handle process exit\r\n agentProcess.on('exit', (code, signal) => {\r\n if (code === 0) {\r\n console.log(`[cfn-spawn] Agent ${agentType} completed successfully`);\r\n } else {\r\n console.error(`[cfn-spawn] Agent ${agentType} exited with code ${code}, signal ${signal}`);\r\n }\r\n process.exit(code || 0);\r\n });\r\n\r\n // Handle process errors\r\n agentProcess.on('error', (err) => {\r\n console.error(`[cfn-spawn] Failed to spawn agent ${agentType}:`, err.message);\r\n process.exit(1);\r\n });\r\n\r\n // Cleanup on parent exit\r\n process.on('SIGINT', () => {\r\n console.log('\\n[cfn-spawn] Received SIGINT, terminating agent...');\r\n agentProcess.kill('SIGINT');\r\n });\r\n\r\n process.on('SIGTERM', () => {\r\n console.log('\\n[cfn-spawn] Received SIGTERM, terminating agent...');\r\n agentProcess.kill('SIGTERM');\r\n });\r\n}\r\n\r\n/**\r\n * Build task description for the agent\r\n */\r\nfunction buildTaskDescription(\r\n agentType: string,\r\n taskId?: string,\r\n iteration?: number,\r\n context?: string\r\n): string {\r\n let desc = `Execute task as ${agentType} agent`;\r\n\r\n if (taskId) desc += ` for task ${taskId}`;\r\n if (iteration) desc += ` (iteration ${iteration})`;\r\n if (context) desc += `: ${context}`;\r\n\r\n return desc;\r\n}\r\n\r\n/**\r\n * Main CLI entry point\r\n */\r\nexport async function main(args: string[] = process.argv.slice(2)): Promise<void> {\r\n // Show help if requested\r\n if (args.includes('--help') || args.includes('-h')) {\r\n console.log(`\r\ncfn-spawn - Claude Flow Novice Agent Spawner\r\n\r\nUsage:\r\n cfn-spawn agent <type> [options]\r\n cfn-spawn <type> [options] (agent is implied)\r\n\r\nOptions:\r\n --task-id <id> Task identifier\r\n --iteration <n> Iteration number\r\n --context <text> Context description\r\n --mode <mode> Execution mode (cli, api, hybrid)\r\n --priority <1-10> Task priority\r\n --parent-task-id <id> Parent task identifier\r\n\r\nExamples:\r\n cfn-spawn agent researcher --task-id task-123 --iteration 1\r\n cfn-spawn coder --task-id auth-impl --context \"Implement JWT auth\"\r\n cfn-spawn reviewer --task-id auth-impl --iteration 2 --mode cli\r\n `);\r\n return;\r\n }\r\n\r\n // Parse arguments\r\n const options = parseAgentArgs(args);\r\n if (!options) {\r\n process.exit(1);\r\n }\r\n\r\n // Spawn the agent\r\n await spawnAgent(options);\r\n}\r\n\r\n// Run if called directly\r\n// ES module check - compare import.meta.url with the executed file\r\nconst isMainModule = import.meta.url.endsWith(process.argv[1]?.replace(/\\\\/g, '/') || '');\r\nif (isMainModule) {\r\n main().catch((err) => {\r\n console.error('[cfn-spawn] Fatal error:', err);\r\n process.exit(1);\r\n });\r\n}\r\n"],"names":["spawn","parseAgentArgs","args","agentType","optionArgs","slice","console","error","options","i","length","key","value","taskId","iteration","parseInt","context","mode","priority","parentTaskId","warn","spawnAgent","log","claudeArgs","push","toString","epicContext","phaseContext","successCriteria","execSync","encoding","trim","e","err","env","process","AGENT_TYPE","TASK_ID","ITERATION","CONTEXT","MODE","PRIORITY","PARENT_TASK_ID","EPIC_CONTEXT","PHASE_CONTEXT","SUCCESS_CRITERIA","join","agentProcess","stdio","cwd","on","code","signal","exit","message","kill","buildTaskDescription","desc","main","argv","includes","isMainModule","url","endsWith","replace","catch"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/cli/agent-spawn.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * Agent Spawning CLI - Direct agent process spawning\r\n *\r\n * Usage:\r\n * npx cfn-spawn agent <type> [options]\r\n * npx cfn-spawn <type> [options] (agent is implied)\r\n *\r\n * Examples:\r\n * npx cfn-spawn agent researcher --task-id task-123 --iteration 1\r\n * npx cfn-spawn researcher --task-id task-123 --iteration 1\r\n */\r\n\r\nimport { spawn } from 'child_process';\r\nimport { resolve } from 'path';\r\n\r\ninterface AgentSpawnOptions {\r\n agentType: string;\r\n agentId?: string;\r\n taskId?: string;\r\n iteration?: number;\r\n context?: string;\r\n mode?: string;\r\n priority?: number;\r\n parentTaskId?: string;\r\n}\r\n\r\n/**\r\n * Parse command line arguments for agent spawning\r\n */\r\nfunction parseAgentArgs(args: string[]): AgentSpawnOptions | null {\r\n // Handle both \"agent <type>\" and \"<type>\" patterns\r\n let agentType: string;\r\n let optionArgs: string[];\r\n\r\n if (args[0] === 'agent') {\r\n agentType = args[1];\r\n optionArgs = args.slice(2);\r\n } else {\r\n agentType = args[0];\r\n optionArgs = args.slice(1);\r\n }\r\n\r\n if (!agentType) {\r\n console.error('Error: Agent type is required');\r\n console.error('Usage: cfn-spawn agent <type> [options]');\r\n return null;\r\n }\r\n\r\n const options: AgentSpawnOptions = { agentType };\r\n\r\n // Parse optional parameters\r\n for (let i = 0; i < optionArgs.length; i += 2) {\r\n const key = optionArgs[i];\r\n const value = optionArgs[i + 1];\r\n\r\n switch (key) {\r\n case '--agent-id':\r\n options.agentId = value;\r\n break;\r\n case '--task-id':\r\n options.taskId = value;\r\n break;\r\n case '--iteration':\r\n options.iteration = parseInt(value, 10);\r\n break;\r\n case '--context':\r\n options.context = value;\r\n break;\r\n case '--mode':\r\n options.mode = value;\r\n break;\r\n case '--priority':\r\n options.priority = parseInt(value, 10);\r\n break;\r\n case '--parent-task':\r\n case '--parent-task-id':\r\n options.parentTaskId = value;\r\n break;\r\n default:\r\n console.warn(`Unknown option: ${key}`);\r\n }\r\n }\r\n\r\n return options;\r\n}\r\n\r\n/**\r\n * Spawn an agent process using npx claude-flow-novice agent\r\n *\r\n * This is a wrapper/alias for the existing claude-flow-novice agent spawning mechanism\r\n * Provides the cfn-spawn naming pattern while delegating to the working implementation\r\n */\r\nasync function spawnAgent(options: AgentSpawnOptions): Promise<void> {\r\n const { agentType, agentId, taskId, iteration, context, mode, priority, parentTaskId } = options;\r\n\r\n console.log(`[cfn-spawn] Spawning agent: ${agentType}`);\r\n if (agentId) console.log(`[cfn-spawn] Agent ID: ${agentId}`);\r\n if (taskId) console.log(`[cfn-spawn] Task ID: ${taskId}`);\r\n if (iteration) console.log(`[cfn-spawn] Iteration: ${iteration}`);\r\n if (context) console.log(`[cfn-spawn] Context: ${context}`);\r\n if (mode) console.log(`[cfn-spawn] Mode: ${mode}`);\r\n\r\n // Build command arguments for npx claude-flow-novice agent\r\n const claudeArgs = ['claude-flow-novice', 'agent', agentType];\r\n\r\n // Add optional parameters\r\n if (agentId) {\r\n claudeArgs.push('--agent-id', agentId);\r\n }\r\n if (taskId) {\r\n claudeArgs.push('--task-id', taskId);\r\n }\r\n if (iteration) {\r\n claudeArgs.push('--iteration', iteration.toString());\r\n }\r\n if (context) {\r\n claudeArgs.push('--context', context);\r\n }\r\n if (mode) {\r\n claudeArgs.push('--mode', mode);\r\n }\r\n if (priority) {\r\n claudeArgs.push('--priority', priority.toString());\r\n }\r\n if (parentTaskId) {\r\n claudeArgs.push('--parent-task-id', parentTaskId);\r\n }\r\n\r\n // Fetch epic context from Redis if available\r\n let epicContext = '';\r\n let phaseContext = '';\r\n let successCriteria = '';\r\n\r\n if (taskId) {\r\n try {\r\n const { execSync } = await import('child_process');\r\n\r\n // Try to read epic-level context from Redis\r\n try {\r\n epicContext = execSync(`redis-cli get \"swarm:${taskId}:epic-context\"`, { encoding: 'utf8' }).trim();\r\n if (epicContext === '(nil)') epicContext = '';\r\n } catch (e) {\r\n // Redis not available or key doesn't exist\r\n }\r\n\r\n // Try to read phase-specific context\r\n try {\r\n phaseContext = execSync(`redis-cli get \"swarm:${taskId}:phase-context\"`, { encoding: 'utf8' }).trim();\r\n if (phaseContext === '(nil)') phaseContext = '';\r\n } catch (e) {\r\n // Redis not available or key doesn't exist\r\n }\r\n\r\n // Try to read success criteria\r\n try {\r\n successCriteria = execSync(`redis-cli get \"swarm:${taskId}:success-criteria\"`, { encoding: 'utf8' }).trim();\r\n if (successCriteria === '(nil)') successCriteria = '';\r\n } catch (e) {\r\n // Redis not available or key doesn't exist\r\n }\r\n\r\n if (epicContext) {\r\n console.log(`[cfn-spawn] Epic context loaded from Redis`);\r\n }\r\n } catch (err) {\r\n console.warn(`[cfn-spawn] Could not load epic context from Redis:`, err);\r\n }\r\n }\r\n\r\n // Add environment variables for agent context\r\n const env = {\r\n ...process.env,\r\n AGENT_TYPE: agentType,\r\n TASK_ID: taskId || '',\r\n ITERATION: iteration?.toString() || '1',\r\n CONTEXT: context || '',\r\n MODE: mode || 'cli',\r\n PRIORITY: priority?.toString() || '5',\r\n PARENT_TASK_ID: parentTaskId || '',\r\n // Epic-level context from Redis\r\n EPIC_CONTEXT: epicContext,\r\n PHASE_CONTEXT: phaseContext,\r\n SUCCESS_CRITERIA: successCriteria\r\n };\r\n\r\n console.log(`[cfn-spawn] Executing: npx ${claudeArgs.join(' ')}`);\r\n\r\n // Spawn the claude-flow-novice agent process\r\n const agentProcess = spawn('npx', claudeArgs, {\r\n stdio: 'inherit',\r\n env,\r\n cwd: process.cwd()\r\n });\r\n\r\n // Handle process exit\r\n agentProcess.on('exit', (code, signal) => {\r\n if (code === 0) {\r\n console.log(`[cfn-spawn] Agent ${agentType} completed successfully`);\r\n } else {\r\n console.error(`[cfn-spawn] Agent ${agentType} exited with code ${code}, signal ${signal}`);\r\n }\r\n process.exit(code || 0);\r\n });\r\n\r\n // Handle process errors\r\n agentProcess.on('error', (err) => {\r\n console.error(`[cfn-spawn] Failed to spawn agent ${agentType}:`, err.message);\r\n process.exit(1);\r\n });\r\n\r\n // Cleanup on parent exit\r\n process.on('SIGINT', () => {\r\n console.log('\\n[cfn-spawn] Received SIGINT, terminating agent...');\r\n agentProcess.kill('SIGINT');\r\n });\r\n\r\n process.on('SIGTERM', () => {\r\n console.log('\\n[cfn-spawn] Received SIGTERM, terminating agent...');\r\n agentProcess.kill('SIGTERM');\r\n });\r\n}\r\n\r\n/**\r\n * Build task description for the agent\r\n */\r\nfunction buildTaskDescription(\r\n agentType: string,\r\n taskId?: string,\r\n iteration?: number,\r\n context?: string\r\n): string {\r\n let desc = `Execute task as ${agentType} agent`;\r\n\r\n if (taskId) desc += ` for task ${taskId}`;\r\n if (iteration) desc += ` (iteration ${iteration})`;\r\n if (context) desc += `: ${context}`;\r\n\r\n return desc;\r\n}\r\n\r\n/**\r\n * Main CLI entry point\r\n */\r\nexport async function main(args: string[] = process.argv.slice(2)): Promise<void> {\r\n // Show help if requested\r\n if (args.includes('--help') || args.includes('-h')) {\r\n console.log(`\r\ncfn-spawn - Claude Flow Novice Agent Spawner\r\n\r\nUsage:\r\n cfn-spawn agent <type> [options]\r\n cfn-spawn <type> [options] (agent is implied)\r\n\r\nOptions:\r\n --agent-id <id> Explicit agent identifier (overrides auto-generation)\r\n --task-id <id> Task identifier\r\n --iteration <n> Iteration number\r\n --context <text> Context description\r\n --mode <mode> Execution mode (cli, api, hybrid)\r\n --priority <1-10> Task priority\r\n --parent-task-id <id> Parent task identifier\r\n\r\nExamples:\r\n cfn-spawn agent researcher --task-id task-123 --iteration 1\r\n cfn-spawn coder --task-id auth-impl --context \"Implement JWT auth\"\r\n cfn-spawn reviewer --task-id auth-impl --iteration 2 --mode cli\r\n cfn-spawn tester --agent-id tester-1-1 --task-id test-phase --iteration 1\r\n `);\r\n return;\r\n }\r\n\r\n // Parse arguments\r\n const options = parseAgentArgs(args);\r\n if (!options) {\r\n process.exit(1);\r\n }\r\n\r\n // Spawn the agent\r\n await spawnAgent(options);\r\n}\r\n\r\n// Run if called directly\r\n// ES module check - compare import.meta.url with the executed file\r\nconst isMainModule = import.meta.url.endsWith(process.argv[1]?.replace(/\\\\/g, '/') || '');\r\nif (isMainModule) {\r\n main().catch((err) => {\r\n console.error('[cfn-spawn] Fatal error:', err);\r\n process.exit(1);\r\n });\r\n}\r\n"],"names":["spawn","parseAgentArgs","args","agentType","optionArgs","slice","console","error","options","i","length","key","value","agentId","taskId","iteration","parseInt","context","mode","priority","parentTaskId","warn","spawnAgent","log","claudeArgs","push","toString","epicContext","phaseContext","successCriteria","execSync","encoding","trim","e","err","env","process","AGENT_TYPE","TASK_ID","ITERATION","CONTEXT","MODE","PRIORITY","PARENT_TASK_ID","EPIC_CONTEXT","PHASE_CONTEXT","SUCCESS_CRITERIA","join","agentProcess","stdio","cwd","on","code","signal","exit","message","kill","buildTaskDescription","desc","main","argv","includes","isMainModule","url","endsWith","replace","catch"],"mappings":";AACA;;;;;;;;;;CAUC,GAED,SAASA,KAAK,QAAQ,gBAAgB;AActC;;CAEC,GACD,SAASC,eAAeC,IAAc;IACpC,mDAAmD;IACnD,IAAIC;IACJ,IAAIC;IAEJ,IAAIF,IAAI,CAAC,EAAE,KAAK,SAAS;QACvBC,YAAYD,IAAI,CAAC,EAAE;QACnBE,aAAaF,KAAKG,KAAK,CAAC;IAC1B,OAAO;QACLF,YAAYD,IAAI,CAAC,EAAE;QACnBE,aAAaF,KAAKG,KAAK,CAAC;IAC1B;IAEA,IAAI,CAACF,WAAW;QACdG,QAAQC,KAAK,CAAC;QACdD,QAAQC,KAAK,CAAC;QACd,OAAO;IACT;IAEA,MAAMC,UAA6B;QAAEL;IAAU;IAE/C,4BAA4B;IAC5B,IAAK,IAAIM,IAAI,GAAGA,IAAIL,WAAWM,MAAM,EAAED,KAAK,EAAG;QAC7C,MAAME,MAAMP,UAAU,CAACK,EAAE;QACzB,MAAMG,QAAQR,UAAU,CAACK,IAAI,EAAE;QAE/B,OAAQE;YACN,KAAK;gBACHH,QAAQK,OAAO,GAAGD;gBAClB;YACF,KAAK;gBACHJ,QAAQM,MAAM,GAAGF;gBACjB;YACF,KAAK;gBACHJ,QAAQO,SAAS,GAAGC,SAASJ,OAAO;gBACpC;YACF,KAAK;gBACHJ,QAAQS,OAAO,GAAGL;gBAClB;YACF,KAAK;gBACHJ,QAAQU,IAAI,GAAGN;gBACf;YACF,KAAK;gBACHJ,QAAQW,QAAQ,GAAGH,SAASJ,OAAO;gBACnC;YACF,KAAK;YACL,KAAK;gBACHJ,QAAQY,YAAY,GAAGR;gBACvB;YACF;gBACEN,QAAQe,IAAI,CAAC,CAAC,gBAAgB,EAAEV,KAAK;QACzC;IACF;IAEA,OAAOH;AACT;AAEA;;;;;CAKC,GACD,eAAec,WAAWd,OAA0B;IAClD,MAAM,EAAEL,SAAS,EAAEU,OAAO,EAAEC,MAAM,EAAEC,SAAS,EAAEE,OAAO,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,YAAY,EAAE,GAAGZ;IAEzFF,QAAQiB,GAAG,CAAC,CAAC,4BAA4B,EAAEpB,WAAW;IACtD,IAAIU,SAASP,QAAQiB,GAAG,CAAC,CAAC,wBAAwB,EAAEV,SAAS;IAC7D,IAAIC,QAAQR,QAAQiB,GAAG,CAAC,CAAC,uBAAuB,EAAET,QAAQ;IAC1D,IAAIC,WAAWT,QAAQiB,GAAG,CAAC,CAAC,yBAAyB,EAAER,WAAW;IAClE,IAAIE,SAASX,QAAQiB,GAAG,CAAC,CAAC,uBAAuB,EAAEN,SAAS;IAC5D,IAAIC,MAAMZ,QAAQiB,GAAG,CAAC,CAAC,oBAAoB,EAAEL,MAAM;IAEnD,2DAA2D;IAC3D,MAAMM,aAAa;QAAC;QAAsB;QAASrB;KAAU;IAE7D,0BAA0B;IAC1B,IAAIU,SAAS;QACXW,WAAWC,IAAI,CAAC,cAAcZ;IAChC;IACA,IAAIC,QAAQ;QACVU,WAAWC,IAAI,CAAC,aAAaX;IAC/B;IACA,IAAIC,WAAW;QACbS,WAAWC,IAAI,CAAC,eAAeV,UAAUW,QAAQ;IACnD;IACA,IAAIT,SAAS;QACXO,WAAWC,IAAI,CAAC,aAAaR;IAC/B;IACA,IAAIC,MAAM;QACRM,WAAWC,IAAI,CAAC,UAAUP;IAC5B;IACA,IAAIC,UAAU;QACZK,WAAWC,IAAI,CAAC,cAAcN,SAASO,QAAQ;IACjD;IACA,IAAIN,cAAc;QAChBI,WAAWC,IAAI,CAAC,oBAAoBL;IACtC;IAEA,6CAA6C;IAC7C,IAAIO,cAAc;IAClB,IAAIC,eAAe;IACnB,IAAIC,kBAAkB;IAEtB,IAAIf,QAAQ;QACV,IAAI;YACF,MAAM,EAAEgB,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC;YAElC,4CAA4C;YAC5C,IAAI;gBACFH,cAAcG,SAAS,CAAC,qBAAqB,EAAEhB,OAAO,cAAc,CAAC,EAAE;oBAAEiB,UAAU;gBAAO,GAAGC,IAAI;gBACjG,IAAIL,gBAAgB,SAASA,cAAc;YAC7C,EAAE,OAAOM,GAAG;YACV,2CAA2C;YAC7C;YAEA,qCAAqC;YACrC,IAAI;gBACFL,eAAeE,SAAS,CAAC,qBAAqB,EAAEhB,OAAO,eAAe,CAAC,EAAE;oBAAEiB,UAAU;gBAAO,GAAGC,IAAI;gBACnG,IAAIJ,iBAAiB,SAASA,eAAe;YAC/C,EAAE,OAAOK,GAAG;YACV,2CAA2C;YAC7C;YAEA,+BAA+B;YAC/B,IAAI;gBACFJ,kBAAkBC,SAAS,CAAC,qBAAqB,EAAEhB,OAAO,kBAAkB,CAAC,EAAE;oBAAEiB,UAAU;gBAAO,GAAGC,IAAI;gBACzG,IAAIH,oBAAoB,SAASA,kBAAkB;YACrD,EAAE,OAAOI,GAAG;YACV,2CAA2C;YAC7C;YAEA,IAAIN,aAAa;gBACfrB,QAAQiB,GAAG,CAAC,CAAC,4CAA4C,CAAC;YAC5D;QACF,EAAE,OAAOW,KAAK;YACZ5B,QAAQe,IAAI,CAAC,CAAC,qDAAqD,CAAC,EAAEa;QACxE;IACF;IAEA,8CAA8C;IAC9C,MAAMC,MAAM;QACV,GAAGC,QAAQD,GAAG;QACdE,YAAYlC;QACZmC,SAASxB,UAAU;QACnByB,WAAWxB,WAAWW,cAAc;QACpCc,SAASvB,WAAW;QACpBwB,MAAMvB,QAAQ;QACdwB,UAAUvB,UAAUO,cAAc;QAClCiB,gBAAgBvB,gBAAgB;QAChC,gCAAgC;QAChCwB,cAAcjB;QACdkB,eAAejB;QACfkB,kBAAkBjB;IACpB;IAEAvB,QAAQiB,GAAG,CAAC,CAAC,2BAA2B,EAAEC,WAAWuB,IAAI,CAAC,MAAM;IAEhE,6CAA6C;IAC7C,MAAMC,eAAehD,MAAM,OAAOwB,YAAY;QAC5CyB,OAAO;QACPd;QACAe,KAAKd,QAAQc,GAAG;IAClB;IAEA,sBAAsB;IACtBF,aAAaG,EAAE,CAAC,QAAQ,CAACC,MAAMC;QAC7B,IAAID,SAAS,GAAG;YACd9C,QAAQiB,GAAG,CAAC,CAAC,kBAAkB,EAAEpB,UAAU,uBAAuB,CAAC;QACrE,OAAO;YACLG,QAAQC,KAAK,CAAC,CAAC,kBAAkB,EAAEJ,UAAU,kBAAkB,EAAEiD,KAAK,SAAS,EAAEC,QAAQ;QAC3F;QACAjB,QAAQkB,IAAI,CAACF,QAAQ;IACvB;IAEA,wBAAwB;IACxBJ,aAAaG,EAAE,CAAC,SAAS,CAACjB;QACxB5B,QAAQC,KAAK,CAAC,CAAC,kCAAkC,EAAEJ,UAAU,CAAC,CAAC,EAAE+B,IAAIqB,OAAO;QAC5EnB,QAAQkB,IAAI,CAAC;IACf;IAEA,yBAAyB;IACzBlB,QAAQe,EAAE,CAAC,UAAU;QACnB7C,QAAQiB,GAAG,CAAC;QACZyB,aAAaQ,IAAI,CAAC;IACpB;IAEApB,QAAQe,EAAE,CAAC,WAAW;QACpB7C,QAAQiB,GAAG,CAAC;QACZyB,aAAaQ,IAAI,CAAC;IACpB;AACF;AAEA;;CAEC,GACD,SAASC,qBACPtD,SAAiB,EACjBW,MAAe,EACfC,SAAkB,EAClBE,OAAgB;IAEhB,IAAIyC,OAAO,CAAC,gBAAgB,EAAEvD,UAAU,MAAM,CAAC;IAE/C,IAAIW,QAAQ4C,QAAQ,CAAC,UAAU,EAAE5C,QAAQ;IACzC,IAAIC,WAAW2C,QAAQ,CAAC,YAAY,EAAE3C,UAAU,CAAC,CAAC;IAClD,IAAIE,SAASyC,QAAQ,CAAC,EAAE,EAAEzC,SAAS;IAEnC,OAAOyC;AACT;AAEA;;CAEC,GACD,OAAO,eAAeC,KAAKzD,OAAiBkC,QAAQwB,IAAI,CAACvD,KAAK,CAAC,EAAE;IAC/D,yBAAyB;IACzB,IAAIH,KAAK2D,QAAQ,CAAC,aAAa3D,KAAK2D,QAAQ,CAAC,OAAO;QAClDvD,QAAQiB,GAAG,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;IAqBb,CAAC;QACD;IACF;IAEA,kBAAkB;IAClB,MAAMf,UAAUP,eAAeC;IAC/B,IAAI,CAACM,SAAS;QACZ4B,QAAQkB,IAAI,CAAC;IACf;IAEA,kBAAkB;IAClB,MAAMhC,WAAWd;AACnB;AAEA,yBAAyB;AACzB,mEAAmE;AACnE,MAAMsD,eAAe,YAAYC,GAAG,CAACC,QAAQ,CAAC5B,QAAQwB,IAAI,CAAC,EAAE,EAAEK,QAAQ,OAAO,QAAQ;AACtF,IAAIH,cAAc;IAChBH,OAAOO,KAAK,CAAC,CAAChC;QACZ5B,QAAQC,KAAK,CAAC,4BAA4B2B;QAC1CE,QAAQkB,IAAI,CAAC;IACf;AACF"}
@@ -6,6 +6,10 @@
6
6
  */ import Anthropic from '@anthropic-ai/sdk';
7
7
  import fs from 'fs/promises';
8
8
  import path from 'path';
9
+ import { exec } from 'child_process';
10
+ import { promisify } from 'util';
11
+ import { executeTool } from './tool-executor.js';
12
+ const execAsync = promisify(exec);
9
13
  /**
10
14
  * Get API configuration from environment and config files
11
15
  */ export async function getAPIConfig() {
@@ -90,7 +94,7 @@ import path from 'path';
90
94
  const config = await getAPIConfig();
91
95
  // Primary model (glm-4.6 for Z.ai, Claude for Anthropic)
92
96
  let model = mapModelName(options.model, config.provider);
93
- const maxTokens = options.maxTokens || 4096;
97
+ const maxTokens = options.maxTokens || 16000; // Sprint 6: 16K hard limit for GLM-4.6 (agents target 10K for buffer)
94
98
  const temperature = options.temperature ?? 1.0;
95
99
  // Disable streaming for Z.ai (compatibility issue)
96
100
  const enableStreaming = options.stream && config.provider !== 'zai';
@@ -99,7 +103,11 @@ import path from 'path';
99
103
  console.log(`[anthropic-client] Max tokens: ${maxTokens}`);
100
104
  console.log(`[anthropic-client] Stream: ${enableStreaming ? 'enabled' : 'disabled'}`);
101
105
  console.log('');
102
- const messages = [
106
+ // Sprint 4: Use messages array if provided (conversation forking)
107
+ const messages = options.messages ? options.messages.map((m)=>({
108
+ role: m.role,
109
+ content: m.content
110
+ })) : [
103
111
  {
104
112
  role: 'user',
105
113
  content: options.prompt
@@ -197,29 +205,188 @@ import path from 'path';
197
205
  // Should never reach here
198
206
  throw lastError || new Error('All retry attempts failed');
199
207
  }
208
+ /**
209
+ * Execute agent with tool support (agentic loop)
210
+ *
211
+ * Handles:
212
+ * 1. Send message with tools
213
+ * 2. Get response
214
+ * 3. If tool_use blocks, execute tools and send results back
215
+ * 4. Repeat until final text response
216
+ */ async function executeWithTools(options, onChunk) {
217
+ const client = await createClient();
218
+ const config = await getAPIConfig();
219
+ const model = mapModelName(options.model, config.provider);
220
+ const maxTokens = options.maxTokens || 16000;
221
+ const temperature = options.temperature ?? 1.0;
222
+ // Build initial messages array
223
+ const messages = options.messages ? options.messages.map((m)=>({
224
+ role: m.role,
225
+ content: m.content
226
+ })) : [
227
+ {
228
+ role: 'user',
229
+ content: options.prompt
230
+ }
231
+ ];
232
+ let totalInputTokens = 0;
233
+ let totalOutputTokens = 0;
234
+ let fullTextContent = '';
235
+ const MAX_ITERATIONS = 10; // Prevent infinite loops
236
+ let iteration = 0;
237
+ while(iteration < MAX_ITERATIONS){
238
+ iteration++;
239
+ console.log(`[executeWithTools] Iteration ${iteration}`);
240
+ const requestParams = {
241
+ model,
242
+ max_tokens: maxTokens,
243
+ temperature,
244
+ messages
245
+ };
246
+ if (options.systemPrompt) {
247
+ requestParams.system = options.systemPrompt;
248
+ }
249
+ if (options.tools && options.tools.length > 0) {
250
+ requestParams.tools = options.tools;
251
+ }
252
+ // Make API request (non-streaming for now to handle tool_use)
253
+ const response = await client.messages.create(requestParams);
254
+ totalInputTokens += response.usage.input_tokens;
255
+ totalOutputTokens += response.usage.output_tokens;
256
+ // Extract content blocks
257
+ const textBlocks = response.content.filter((block)=>block.type === 'text');
258
+ const toolUseBlocks = response.content.filter((block)=>block.type === 'tool_use');
259
+ // Stream text output
260
+ for (const block of textBlocks){
261
+ if (block.type === 'text') {
262
+ const text = block.text;
263
+ fullTextContent += text;
264
+ if (onChunk) {
265
+ onChunk(text);
266
+ }
267
+ }
268
+ }
269
+ // If no tool uses, we're done
270
+ if (toolUseBlocks.length === 0) {
271
+ console.log(`[executeWithTools] No tool uses, completing`);
272
+ return {
273
+ content: fullTextContent,
274
+ usage: {
275
+ inputTokens: totalInputTokens,
276
+ outputTokens: totalOutputTokens
277
+ },
278
+ stopReason: response.stop_reason || 'end_turn'
279
+ };
280
+ }
281
+ // Execute tools
282
+ console.log(`[executeWithTools] Executing ${toolUseBlocks.length} tool(s)`);
283
+ const toolResults = [];
284
+ for (const toolUseBlock of toolUseBlocks){
285
+ if (toolUseBlock.type !== 'tool_use') continue;
286
+ const toolUse = {
287
+ type: 'tool_use',
288
+ id: toolUseBlock.id,
289
+ name: toolUseBlock.name,
290
+ input: toolUseBlock.input
291
+ };
292
+ console.log(`[executeWithTools] Tool: ${toolUse.name}`);
293
+ const result = await executeTool(toolUse);
294
+ toolResults.push(result);
295
+ // Stream tool result
296
+ if (onChunk) {
297
+ onChunk(`\n[Tool: ${toolUse.name}] ${result.content.substring(0, 100)}${result.content.length > 100 ? '...' : ''}\n`);
298
+ }
299
+ }
300
+ // Add assistant message with tool_use
301
+ messages.push({
302
+ role: 'assistant',
303
+ content: response.content
304
+ });
305
+ // Add tool results as user message
306
+ messages.push({
307
+ role: 'user',
308
+ content: toolResults
309
+ });
310
+ // Continue to next iteration
311
+ }
312
+ // Reached max iterations
313
+ console.warn(`[executeWithTools] Reached max iterations (${MAX_ITERATIONS})`);
314
+ return {
315
+ content: fullTextContent,
316
+ usage: {
317
+ inputTokens: totalInputTokens,
318
+ outputTokens: totalOutputTokens
319
+ },
320
+ stopReason: 'max_tokens'
321
+ };
322
+ }
200
323
  /**
201
324
  * Execute agent via API with full lifecycle
202
- */ export async function executeAgentAPI(agentType, agentId, model, prompt, systemPrompt) {
325
+ */ export async function executeAgentAPI(agentType, agentId, model, prompt, systemPrompt, messages, maxTokens, tools// Tool definitions for agent capabilities
326
+ ) {
327
+ // Start heartbeat monitoring (declare at function scope for error handling)
328
+ let heartbeatInterval = null;
329
+ const taskId = process.env.TASK_ID;
203
330
  try {
204
331
  console.log(`[anthropic-client] Executing agent: ${agentType}`);
205
332
  console.log(`[anthropic-client] Agent ID: ${agentId}`);
333
+ if (messages && messages.length > 1) {
334
+ console.log(`[anthropic-client] Continuing conversation (${messages.length} messages)`);
335
+ }
206
336
  console.log('');
337
+ if (taskId) {
338
+ heartbeatInterval = setInterval(async ()=>{
339
+ try {
340
+ await execAsync(`redis-cli hset "swarm:${taskId}:agent:${agentId}" heartbeat "${Date.now()}" status "working"`);
341
+ } catch (err) {
342
+ console.error('[heartbeat] Error sending heartbeat:', err);
343
+ }
344
+ }, 30000); // Every 30 seconds
345
+ console.log(`[heartbeat] Monitoring started for agent ${agentId} (30s interval)`);
346
+ }
207
347
  let fullOutput = '';
208
- const response = await sendMessage({
209
- model,
210
- prompt,
211
- systemPrompt,
212
- stream: true
213
- }, (chunk)=>{
214
- // Stream output in real-time
215
- process.stdout.write(chunk);
216
- fullOutput += chunk;
217
- });
348
+ // If tools provided, use agentic loop with tool execution
349
+ // Otherwise use simple streaming
350
+ let response;
351
+ if (tools && tools.length > 0) {
352
+ console.log(`[anthropic-client] Tools enabled: ${tools.map((t)=>t.name).join(', ')}`);
353
+ response = await executeWithTools({
354
+ model,
355
+ prompt,
356
+ systemPrompt,
357
+ messages,
358
+ maxTokens,
359
+ tools
360
+ }, (chunk)=>{
361
+ process.stdout.write(chunk);
362
+ fullOutput += chunk;
363
+ });
364
+ } else {
365
+ response = await sendMessage({
366
+ model,
367
+ prompt,
368
+ systemPrompt,
369
+ stream: true,
370
+ messages,
371
+ maxTokens
372
+ }, (chunk)=>{
373
+ process.stdout.write(chunk);
374
+ fullOutput += chunk;
375
+ });
376
+ }
218
377
  console.log('\n');
219
378
  console.log('=== Agent Execution Complete ===');
220
379
  console.log(`Input tokens: ${response.usage.inputTokens}`);
221
380
  console.log(`Output tokens: ${response.usage.outputTokens}`);
222
381
  console.log(`Stop reason: ${response.stopReason}`);
382
+ // Stop heartbeat and send final status
383
+ if (heartbeatInterval) {
384
+ clearInterval(heartbeatInterval);
385
+ if (taskId) {
386
+ await execAsync(`redis-cli hset "swarm:${taskId}:agent:${agentId}" heartbeat "${Date.now()}" status "complete"`);
387
+ console.log(`[heartbeat] Monitoring stopped - agent ${agentId} complete`);
388
+ }
389
+ }
223
390
  return {
224
391
  success: true,
225
392
  output: response.content,
@@ -227,6 +394,18 @@ import path from 'path';
227
394
  };
228
395
  } catch (error) {
229
396
  console.error('[anthropic-client] Error:', error);
397
+ // Stop heartbeat and send error status
398
+ if (heartbeatInterval) {
399
+ clearInterval(heartbeatInterval);
400
+ if (taskId) {
401
+ try {
402
+ await execAsync(`redis-cli hset "swarm:${taskId}:agent:${agentId}" heartbeat "${Date.now()}" status "error"`);
403
+ console.log(`[heartbeat] Monitoring stopped - agent ${agentId} error`);
404
+ } catch (err) {
405
+ // Ignore heartbeat errors during error handling
406
+ }
407
+ }
408
+ }
230
409
  return {
231
410
  success: false,
232
411
  output: '',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/anthropic-client.ts"],"sourcesContent":["/**\r\n * Anthropic API Client\r\n *\r\n * Handles communication with Claude API (Anthropic or z.ai provider).\r\n * Supports streaming responses and tool execution.\r\n */\r\n\r\nimport Anthropic from '@anthropic-ai/sdk';\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\n\r\nexport interface APIConfig {\r\n provider: 'anthropic' | 'zai';\r\n apiKey?: string;\r\n baseURL?: string;\r\n}\r\n\r\nexport interface MessageOptions {\r\n model: string;\r\n prompt: string;\r\n systemPrompt?: string;\r\n maxTokens?: number;\r\n temperature?: number;\r\n stream?: boolean;\r\n tools?: any[];\r\n}\r\n\r\nexport interface MessageResponse {\r\n content: string;\r\n usage: {\r\n inputTokens: number;\r\n outputTokens: number;\r\n };\r\n stopReason: string;\r\n}\r\n\r\n/**\r\n * Get API configuration from environment and config files\r\n */\r\nexport async function getAPIConfig(): Promise<APIConfig> {\r\n // Check environment variable\r\n const envProvider = process.env.CLAUDE_API_PROVIDER;\r\n if (envProvider === 'zai') {\r\n return {\r\n provider: 'zai',\r\n apiKey: process.env.ZAI_API_KEY || process.env.ANTHROPIC_API_KEY,\r\n baseURL: process.env.ZAI_BASE_URL || 'https://api.z.ai/api/anthropic',\r\n };\r\n }\r\n\r\n // Check config file\r\n try {\r\n const configPath = path.join('.claude', 'config', 'api-provider.json');\r\n const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));\r\n\r\n if (config.provider === 'zai' || config.provider === 'z.ai') {\r\n return {\r\n provider: 'zai',\r\n apiKey: config.apiKey || process.env.ZAI_API_KEY || process.env.ANTHROPIC_API_KEY,\r\n baseURL: config.baseURL || process.env.ZAI_BASE_URL || 'https://api.z.ai/api/anthropic',\r\n };\r\n }\r\n } catch {\r\n // Config file doesn't exist, use defaults\r\n }\r\n\r\n // Default to Anthropic\r\n return {\r\n provider: 'anthropic',\r\n apiKey: process.env.ANTHROPIC_API_KEY,\r\n };\r\n}\r\n\r\n/**\r\n * Create Anthropic client with appropriate configuration\r\n */\r\nexport async function createClient(): Promise<Anthropic> {\r\n const config = await getAPIConfig();\r\n\r\n if (!config.apiKey) {\r\n throw new Error(\r\n `API key not found. Set ${config.provider === 'zai' ? 'ZAI_API_KEY' : 'ANTHROPIC_API_KEY'} environment variable.`\r\n );\r\n }\r\n\r\n const clientOptions: any = {\r\n apiKey: config.apiKey,\r\n timeout: 120000, // 2 minutes (120 seconds)\r\n maxRetries: 2,\r\n };\r\n\r\n if (config.provider === 'zai' && config.baseURL) {\r\n clientOptions.baseURL = config.baseURL;\r\n }\r\n\r\n return new Anthropic(clientOptions);\r\n}\r\n\r\n/**\r\n * Map agent model name to API model ID (provider-specific)\r\n */\r\nexport function mapModelName(agentModel: string, provider: 'anthropic' | 'zai' = 'anthropic'): string {\r\n // Z.ai uses GLM models - try glm-4.6 first for all models\r\n if (provider === 'zai') {\r\n const zaiModelMap: Record<string, string> = {\r\n haiku: 'glm-4.6',\r\n sonnet: 'glm-4.6',\r\n opus: 'glm-4.6',\r\n };\r\n return zaiModelMap[agentModel] || 'glm-4.6';\r\n }\r\n\r\n // Anthropic uses Claude models\r\n const modelMap: Record<string, string> = {\r\n haiku: 'claude-3-5-haiku-20241022',\r\n sonnet: 'claude-3-5-sonnet-20241022',\r\n opus: 'claude-3-opus-20240229',\r\n };\r\n\r\n return modelMap[agentModel] || modelMap.haiku;\r\n}\r\n\r\n/**\r\n * Get fallback model for Z.ai (glm-4.6 -> glm-4.5-air)\r\n */\r\nfunction getFallbackModel(model: string): string | null {\r\n if (model === 'glm-4.6') {\r\n return 'glm-4.5-air';\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Send message to Claude API with streaming support and automatic fallback\r\n */\r\nexport async function sendMessage(\r\n options: MessageOptions,\r\n onChunk?: (text: string) => void\r\n): Promise<MessageResponse> {\r\n const client = await createClient();\r\n const config = await getAPIConfig();\r\n\r\n // Primary model (glm-4.6 for Z.ai, Claude for Anthropic)\r\n let model = mapModelName(options.model, config.provider);\r\n const maxTokens = options.maxTokens || 4096;\r\n const temperature = options.temperature ?? 1.0;\r\n\r\n // Disable streaming for Z.ai (compatibility issue)\r\n const enableStreaming = options.stream && config.provider !== 'zai';\r\n\r\n console.log(`[anthropic-client] Provider: ${config.provider}`);\r\n console.log(`[anthropic-client] Model: ${model}`);\r\n console.log(`[anthropic-client] Max tokens: ${maxTokens}`);\r\n console.log(`[anthropic-client] Stream: ${enableStreaming ? 'enabled' : 'disabled'}`);\r\n console.log('');\r\n\r\n const messages: Anthropic.MessageParam[] = [\r\n {\r\n role: 'user',\r\n content: options.prompt,\r\n },\r\n ];\r\n\r\n // Retry logic: Try primary model (glm-4.6), fall back to glm-4.5 on error\r\n let lastError: Error | null = null;\r\n let attempts = 0;\r\n const maxAttempts = 2; // Primary + fallback\r\n\r\n while (attempts < maxAttempts) {\r\n const currentModel = attempts === 0 ? model : getFallbackModel(model);\r\n\r\n if (!currentModel) {\r\n // No fallback available, throw last error\r\n throw lastError || new Error('No model available');\r\n }\r\n\r\n attempts++;\r\n\r\n if (attempts > 1) {\r\n console.log(`[anthropic-client] Retrying with fallback model: ${currentModel}`);\r\n }\r\n\r\n const requestParams: Anthropic.MessageCreateParams = {\r\n model: currentModel,\r\n max_tokens: maxTokens,\r\n temperature,\r\n messages,\r\n };\r\n\r\n if (options.systemPrompt) {\r\n requestParams.system = options.systemPrompt;\r\n }\r\n\r\n if (options.tools && options.tools.length > 0) {\r\n requestParams.tools = options.tools;\r\n }\r\n\r\n try {\r\n // Streaming response\r\n if (enableStreaming) {\r\n let fullContent = '';\r\n let inputTokens = 0;\r\n let outputTokens = 0;\r\n let stopReason = 'end_turn';\r\n\r\n console.log('[anthropic-client] Creating streaming request...');\r\n const stream = await client.messages.create({\r\n ...requestParams,\r\n stream: true,\r\n });\r\n\r\n console.log('[anthropic-client] Stream created, processing events...');\r\n for await (const event of stream) {\r\n console.log('[anthropic-client] Event type:', event.type);\r\n if (event.type === 'message_start') {\r\n // @ts-ignore - usage exists on message_start\r\n inputTokens = event.message.usage?.input_tokens || 0;\r\n } else if (event.type === 'content_block_delta') {\r\n // @ts-ignore - text exists on delta\r\n const text = event.delta?.text || '';\r\n fullContent += text;\r\n if (onChunk) {\r\n onChunk(text);\r\n }\r\n } else if (event.type === 'message_delta') {\r\n // @ts-ignore - usage exists on message_delta\r\n outputTokens = event.usage?.output_tokens || 0;\r\n // @ts-ignore - stop_reason exists on delta\r\n stopReason = event.delta?.stop_reason || 'end_turn';\r\n }\r\n }\r\n\r\n return {\r\n content: fullContent,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n },\r\n stopReason,\r\n };\r\n }\r\n\r\n // Non-streaming response\r\n const response = await client.messages.create(requestParams);\r\n\r\n const content =\r\n response.content\r\n .filter((block) => block.type === 'text')\r\n .map((block) => (block as any).text)\r\n .join('\\n') || '';\r\n\r\n return {\r\n content,\r\n usage: {\r\n inputTokens: response.usage.input_tokens,\r\n outputTokens: response.usage.output_tokens,\r\n },\r\n stopReason: response.stop_reason || 'end_turn',\r\n };\r\n } catch (error) {\r\n lastError = error instanceof Error ? error : new Error(String(error));\r\n console.error(`[anthropic-client] Error with model ${currentModel}:`, lastError.message);\r\n\r\n // If this was the last attempt, throw the error\r\n if (attempts >= maxAttempts) {\r\n throw lastError;\r\n }\r\n\r\n // Continue to next attempt with fallback model\r\n console.log('[anthropic-client] Will retry with fallback model...');\r\n }\r\n }\r\n\r\n // Should never reach here\r\n throw lastError || new Error('All retry attempts failed');\r\n}\r\n\r\n/**\r\n * Execute agent via API with full lifecycle\r\n */\r\nexport async function executeAgentAPI(\r\n agentType: string,\r\n agentId: string,\r\n model: string,\r\n prompt: string,\r\n systemPrompt?: string\r\n): Promise<{ success: boolean; output: string; usage: any; error?: string }> {\r\n try {\r\n console.log(`[anthropic-client] Executing agent: ${agentType}`);\r\n console.log(`[anthropic-client] Agent ID: ${agentId}`);\r\n console.log('');\r\n\r\n let fullOutput = '';\r\n\r\n const response = await sendMessage(\r\n {\r\n model,\r\n prompt,\r\n systemPrompt,\r\n stream: true,\r\n },\r\n (chunk) => {\r\n // Stream output in real-time\r\n process.stdout.write(chunk);\r\n fullOutput += chunk;\r\n }\r\n );\r\n\r\n console.log('\\n');\r\n console.log('=== Agent Execution Complete ===');\r\n console.log(`Input tokens: ${response.usage.inputTokens}`);\r\n console.log(`Output tokens: ${response.usage.outputTokens}`);\r\n console.log(`Stop reason: ${response.stopReason}`);\r\n\r\n return {\r\n success: true,\r\n output: response.content,\r\n usage: response.usage,\r\n };\r\n } catch (error) {\r\n console.error('[anthropic-client] Error:', error);\r\n return {\r\n success: false,\r\n output: '',\r\n usage: { inputTokens: 0, outputTokens: 0 },\r\n error: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n}\r\n"],"names":["Anthropic","fs","path","getAPIConfig","envProvider","process","env","CLAUDE_API_PROVIDER","provider","apiKey","ZAI_API_KEY","ANTHROPIC_API_KEY","baseURL","ZAI_BASE_URL","configPath","join","config","JSON","parse","readFile","createClient","Error","clientOptions","timeout","maxRetries","mapModelName","agentModel","zaiModelMap","haiku","sonnet","opus","modelMap","getFallbackModel","model","sendMessage","options","onChunk","client","maxTokens","temperature","enableStreaming","stream","console","log","messages","role","content","prompt","lastError","attempts","maxAttempts","currentModel","requestParams","max_tokens","systemPrompt","system","tools","length","fullContent","inputTokens","outputTokens","stopReason","create","event","type","message","usage","input_tokens","text","delta","output_tokens","stop_reason","response","filter","block","map","error","String","executeAgentAPI","agentType","agentId","fullOutput","chunk","stdout","write","success","output"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/cli/anthropic-client.ts"],"sourcesContent":["/**\r\n * Anthropic API Client\r\n *\r\n * Handles communication with Claude API (Anthropic or z.ai provider).\r\n * Supports streaming responses and tool execution.\r\n */\r\n\r\nimport Anthropic from '@anthropic-ai/sdk';\r\nimport fs from 'fs/promises';\r\nimport path from 'path';\r\nimport { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { executeTool, type ToolUse, type ToolResult } from './tool-executor.js';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\nexport interface APIConfig {\r\n provider: 'anthropic' | 'zai';\r\n apiKey?: string;\r\n baseURL?: string;\r\n}\r\n\r\nexport interface MessageOptions {\r\n model: string;\r\n prompt: string;\r\n systemPrompt?: string;\r\n maxTokens?: number;\r\n temperature?: number;\r\n stream?: boolean;\r\n tools?: any[];\r\n messages?: Array<{ role: string; content: string }>; // Sprint 4: Conversation forking\r\n}\r\n\r\nexport interface MessageResponse {\r\n content: string;\r\n usage: {\r\n inputTokens: number;\r\n outputTokens: number;\r\n };\r\n stopReason: string;\r\n}\r\n\r\n/**\r\n * Get API configuration from environment and config files\r\n */\r\nexport async function getAPIConfig(): Promise<APIConfig> {\r\n // Check environment variable\r\n const envProvider = process.env.CLAUDE_API_PROVIDER;\r\n if (envProvider === 'zai') {\r\n return {\r\n provider: 'zai',\r\n apiKey: process.env.ZAI_API_KEY || process.env.ANTHROPIC_API_KEY,\r\n baseURL: process.env.ZAI_BASE_URL || 'https://api.z.ai/api/anthropic',\r\n };\r\n }\r\n\r\n // Check config file\r\n try {\r\n const configPath = path.join('.claude', 'config', 'api-provider.json');\r\n const config = JSON.parse(await fs.readFile(configPath, 'utf-8'));\r\n\r\n if (config.provider === 'zai' || config.provider === 'z.ai') {\r\n return {\r\n provider: 'zai',\r\n apiKey: config.apiKey || process.env.ZAI_API_KEY || process.env.ANTHROPIC_API_KEY,\r\n baseURL: config.baseURL || process.env.ZAI_BASE_URL || 'https://api.z.ai/api/anthropic',\r\n };\r\n }\r\n } catch {\r\n // Config file doesn't exist, use defaults\r\n }\r\n\r\n // Default to Anthropic\r\n return {\r\n provider: 'anthropic',\r\n apiKey: process.env.ANTHROPIC_API_KEY,\r\n };\r\n}\r\n\r\n/**\r\n * Create Anthropic client with appropriate configuration\r\n */\r\nexport async function createClient(): Promise<Anthropic> {\r\n const config = await getAPIConfig();\r\n\r\n if (!config.apiKey) {\r\n throw new Error(\r\n `API key not found. Set ${config.provider === 'zai' ? 'ZAI_API_KEY' : 'ANTHROPIC_API_KEY'} environment variable.`\r\n );\r\n }\r\n\r\n const clientOptions: any = {\r\n apiKey: config.apiKey,\r\n timeout: 120000, // 2 minutes (120 seconds)\r\n maxRetries: 2,\r\n };\r\n\r\n if (config.provider === 'zai' && config.baseURL) {\r\n clientOptions.baseURL = config.baseURL;\r\n }\r\n\r\n return new Anthropic(clientOptions);\r\n}\r\n\r\n/**\r\n * Map agent model name to API model ID (provider-specific)\r\n */\r\nexport function mapModelName(agentModel: string, provider: 'anthropic' | 'zai' = 'anthropic'): string {\r\n // Z.ai uses GLM models - try glm-4.6 first for all models\r\n if (provider === 'zai') {\r\n const zaiModelMap: Record<string, string> = {\r\n haiku: 'glm-4.6',\r\n sonnet: 'glm-4.6',\r\n opus: 'glm-4.6',\r\n };\r\n return zaiModelMap[agentModel] || 'glm-4.6';\r\n }\r\n\r\n // Anthropic uses Claude models\r\n const modelMap: Record<string, string> = {\r\n haiku: 'claude-3-5-haiku-20241022',\r\n sonnet: 'claude-3-5-sonnet-20241022',\r\n opus: 'claude-3-opus-20240229',\r\n };\r\n\r\n return modelMap[agentModel] || modelMap.haiku;\r\n}\r\n\r\n/**\r\n * Get fallback model for Z.ai (glm-4.6 -> glm-4.5-air)\r\n */\r\nfunction getFallbackModel(model: string): string | null {\r\n if (model === 'glm-4.6') {\r\n return 'glm-4.5-air';\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Send message to Claude API with streaming support and automatic fallback\r\n */\r\nexport async function sendMessage(\r\n options: MessageOptions,\r\n onChunk?: (text: string) => void\r\n): Promise<MessageResponse> {\r\n const client = await createClient();\r\n const config = await getAPIConfig();\r\n\r\n // Primary model (glm-4.6 for Z.ai, Claude for Anthropic)\r\n let model = mapModelName(options.model, config.provider);\r\n const maxTokens = options.maxTokens || 16000; // Sprint 6: 16K hard limit for GLM-4.6 (agents target 10K for buffer)\r\n const temperature = options.temperature ?? 1.0;\r\n\r\n // Disable streaming for Z.ai (compatibility issue)\r\n const enableStreaming = options.stream && config.provider !== 'zai';\r\n\r\n console.log(`[anthropic-client] Provider: ${config.provider}`);\r\n console.log(`[anthropic-client] Model: ${model}`);\r\n console.log(`[anthropic-client] Max tokens: ${maxTokens}`);\r\n console.log(`[anthropic-client] Stream: ${enableStreaming ? 'enabled' : 'disabled'}`);\r\n console.log('');\r\n\r\n // Sprint 4: Use messages array if provided (conversation forking)\r\n const messages: Anthropic.MessageParam[] = options.messages\r\n ? options.messages.map(m => ({\r\n role: m.role as 'user' | 'assistant',\r\n content: m.content,\r\n }))\r\n : [\r\n {\r\n role: 'user',\r\n content: options.prompt,\r\n },\r\n ];\r\n\r\n // Retry logic: Try primary model (glm-4.6), fall back to glm-4.5 on error\r\n let lastError: Error | null = null;\r\n let attempts = 0;\r\n const maxAttempts = 2; // Primary + fallback\r\n\r\n while (attempts < maxAttempts) {\r\n const currentModel = attempts === 0 ? model : getFallbackModel(model);\r\n\r\n if (!currentModel) {\r\n // No fallback available, throw last error\r\n throw lastError || new Error('No model available');\r\n }\r\n\r\n attempts++;\r\n\r\n if (attempts > 1) {\r\n console.log(`[anthropic-client] Retrying with fallback model: ${currentModel}`);\r\n }\r\n\r\n const requestParams: Anthropic.MessageCreateParams = {\r\n model: currentModel,\r\n max_tokens: maxTokens,\r\n temperature,\r\n messages,\r\n };\r\n\r\n if (options.systemPrompt) {\r\n requestParams.system = options.systemPrompt;\r\n }\r\n\r\n if (options.tools && options.tools.length > 0) {\r\n requestParams.tools = options.tools;\r\n }\r\n\r\n try {\r\n // Streaming response\r\n if (enableStreaming) {\r\n let fullContent = '';\r\n let inputTokens = 0;\r\n let outputTokens = 0;\r\n let stopReason = 'end_turn';\r\n\r\n console.log('[anthropic-client] Creating streaming request...');\r\n const stream = await client.messages.create({\r\n ...requestParams,\r\n stream: true,\r\n });\r\n\r\n console.log('[anthropic-client] Stream created, processing events...');\r\n for await (const event of stream) {\r\n console.log('[anthropic-client] Event type:', event.type);\r\n if (event.type === 'message_start') {\r\n // @ts-ignore - usage exists on message_start\r\n inputTokens = event.message.usage?.input_tokens || 0;\r\n } else if (event.type === 'content_block_delta') {\r\n // @ts-ignore - text exists on delta\r\n const text = event.delta?.text || '';\r\n fullContent += text;\r\n if (onChunk) {\r\n onChunk(text);\r\n }\r\n } else if (event.type === 'message_delta') {\r\n // @ts-ignore - usage exists on message_delta\r\n outputTokens = event.usage?.output_tokens || 0;\r\n // @ts-ignore - stop_reason exists on delta\r\n stopReason = event.delta?.stop_reason || 'end_turn';\r\n }\r\n }\r\n\r\n return {\r\n content: fullContent,\r\n usage: {\r\n inputTokens,\r\n outputTokens,\r\n },\r\n stopReason,\r\n };\r\n }\r\n\r\n // Non-streaming response\r\n const response = await client.messages.create(requestParams);\r\n\r\n const content =\r\n response.content\r\n .filter((block) => block.type === 'text')\r\n .map((block) => (block as any).text)\r\n .join('\\n') || '';\r\n\r\n return {\r\n content,\r\n usage: {\r\n inputTokens: response.usage.input_tokens,\r\n outputTokens: response.usage.output_tokens,\r\n },\r\n stopReason: response.stop_reason || 'end_turn',\r\n };\r\n } catch (error) {\r\n lastError = error instanceof Error ? error : new Error(String(error));\r\n console.error(`[anthropic-client] Error with model ${currentModel}:`, lastError.message);\r\n\r\n // If this was the last attempt, throw the error\r\n if (attempts >= maxAttempts) {\r\n throw lastError;\r\n }\r\n\r\n // Continue to next attempt with fallback model\r\n console.log('[anthropic-client] Will retry with fallback model...');\r\n }\r\n }\r\n\r\n // Should never reach here\r\n throw lastError || new Error('All retry attempts failed');\r\n}\r\n\r\n/**\r\n * Execute agent with tool support (agentic loop)\r\n *\r\n * Handles:\r\n * 1. Send message with tools\r\n * 2. Get response\r\n * 3. If tool_use blocks, execute tools and send results back\r\n * 4. Repeat until final text response\r\n */\r\nasync function executeWithTools(\r\n options: MessageOptions,\r\n onChunk?: (text: string) => void\r\n): Promise<MessageResponse> {\r\n const client = await createClient();\r\n const config = await getAPIConfig();\r\n\r\n const model = mapModelName(options.model, config.provider);\r\n const maxTokens = options.maxTokens || 16000;\r\n const temperature = options.temperature ?? 1.0;\r\n\r\n // Build initial messages array\r\n const messages: Anthropic.MessageParam[] = options.messages\r\n ? options.messages.map(m => ({\r\n role: m.role as 'user' | 'assistant',\r\n content: m.content,\r\n }))\r\n : [\r\n {\r\n role: 'user',\r\n content: options.prompt,\r\n },\r\n ];\r\n\r\n let totalInputTokens = 0;\r\n let totalOutputTokens = 0;\r\n let fullTextContent = '';\r\n const MAX_ITERATIONS = 10; // Prevent infinite loops\r\n let iteration = 0;\r\n\r\n while (iteration < MAX_ITERATIONS) {\r\n iteration++;\r\n console.log(`[executeWithTools] Iteration ${iteration}`);\r\n\r\n const requestParams: Anthropic.MessageCreateParams = {\r\n model,\r\n max_tokens: maxTokens,\r\n temperature,\r\n messages,\r\n };\r\n\r\n if (options.systemPrompt) {\r\n requestParams.system = options.systemPrompt;\r\n }\r\n\r\n if (options.tools && options.tools.length > 0) {\r\n requestParams.tools = options.tools;\r\n }\r\n\r\n // Make API request (non-streaming for now to handle tool_use)\r\n const response = await client.messages.create(requestParams);\r\n\r\n totalInputTokens += response.usage.input_tokens;\r\n totalOutputTokens += response.usage.output_tokens;\r\n\r\n // Extract content blocks\r\n const textBlocks = response.content.filter(block => block.type === 'text');\r\n const toolUseBlocks = response.content.filter(block => block.type === 'tool_use');\r\n\r\n // Stream text output\r\n for (const block of textBlocks) {\r\n if (block.type === 'text') {\r\n const text = (block as any).text;\r\n fullTextContent += text;\r\n if (onChunk) {\r\n onChunk(text);\r\n }\r\n }\r\n }\r\n\r\n // If no tool uses, we're done\r\n if (toolUseBlocks.length === 0) {\r\n console.log(`[executeWithTools] No tool uses, completing`);\r\n return {\r\n content: fullTextContent,\r\n usage: {\r\n inputTokens: totalInputTokens,\r\n outputTokens: totalOutputTokens,\r\n },\r\n stopReason: response.stop_reason || 'end_turn',\r\n };\r\n }\r\n\r\n // Execute tools\r\n console.log(`[executeWithTools] Executing ${toolUseBlocks.length} tool(s)`);\r\n const toolResults: ToolResult[] = [];\r\n\r\n for (const toolUseBlock of toolUseBlocks) {\r\n if (toolUseBlock.type !== 'tool_use') continue;\r\n\r\n const toolUse: ToolUse = {\r\n type: 'tool_use',\r\n id: (toolUseBlock as any).id,\r\n name: (toolUseBlock as any).name,\r\n input: (toolUseBlock as any).input,\r\n };\r\n\r\n console.log(`[executeWithTools] Tool: ${toolUse.name}`);\r\n const result = await executeTool(toolUse);\r\n toolResults.push(result);\r\n\r\n // Stream tool result\r\n if (onChunk) {\r\n onChunk(`\\n[Tool: ${toolUse.name}] ${result.content.substring(0, 100)}${result.content.length > 100 ? '...' : ''}\\n`);\r\n }\r\n }\r\n\r\n // Add assistant message with tool_use\r\n messages.push({\r\n role: 'assistant',\r\n content: response.content as any,\r\n });\r\n\r\n // Add tool results as user message\r\n messages.push({\r\n role: 'user',\r\n content: toolResults as any,\r\n });\r\n\r\n // Continue to next iteration\r\n }\r\n\r\n // Reached max iterations\r\n console.warn(`[executeWithTools] Reached max iterations (${MAX_ITERATIONS})`);\r\n return {\r\n content: fullTextContent,\r\n usage: {\r\n inputTokens: totalInputTokens,\r\n outputTokens: totalOutputTokens,\r\n },\r\n stopReason: 'max_tokens',\r\n };\r\n}\r\n\r\n/**\r\n * Execute agent via API with full lifecycle\r\n */\r\nexport async function executeAgentAPI(\r\n agentType: string,\r\n agentId: string,\r\n model: string,\r\n prompt: string,\r\n systemPrompt?: string,\r\n messages?: Array<{ role: string; content: string }>, // Sprint 4: Conversation forking\r\n maxTokens?: number, // Sprint 6: Configurable token limit\r\n tools?: any[] // Tool definitions for agent capabilities\r\n): Promise<{ success: boolean; output: string; usage: any; error?: string }> {\r\n // Start heartbeat monitoring (declare at function scope for error handling)\r\n let heartbeatInterval: NodeJS.Timeout | null = null;\r\n const taskId = process.env.TASK_ID;\r\n\r\n try {\r\n console.log(`[anthropic-client] Executing agent: ${agentType}`);\r\n console.log(`[anthropic-client] Agent ID: ${agentId}`);\r\n if (messages && messages.length > 1) {\r\n console.log(`[anthropic-client] Continuing conversation (${messages.length} messages)`);\r\n }\r\n console.log('');\r\n\r\n if (taskId) {\r\n heartbeatInterval = setInterval(async () => {\r\n try {\r\n await execAsync(`redis-cli hset \"swarm:${taskId}:agent:${agentId}\" heartbeat \"${Date.now()}\" status \"working\"`);\r\n } catch (err) {\r\n console.error('[heartbeat] Error sending heartbeat:', err);\r\n }\r\n }, 30000); // Every 30 seconds\r\n\r\n console.log(`[heartbeat] Monitoring started for agent ${agentId} (30s interval)`);\r\n }\r\n\r\n let fullOutput = '';\r\n\r\n // If tools provided, use agentic loop with tool execution\r\n // Otherwise use simple streaming\r\n let response: MessageResponse;\r\n\r\n if (tools && tools.length > 0) {\r\n console.log(`[anthropic-client] Tools enabled: ${tools.map(t => t.name).join(', ')}`);\r\n response = await executeWithTools(\r\n {\r\n model,\r\n prompt,\r\n systemPrompt,\r\n messages,\r\n maxTokens,\r\n tools\r\n },\r\n (chunk) => {\r\n process.stdout.write(chunk);\r\n fullOutput += chunk;\r\n }\r\n );\r\n } else {\r\n response = await sendMessage(\r\n {\r\n model,\r\n prompt,\r\n systemPrompt,\r\n stream: true,\r\n messages,\r\n maxTokens,\r\n },\r\n (chunk) => {\r\n process.stdout.write(chunk);\r\n fullOutput += chunk;\r\n }\r\n );\r\n }\r\n\r\n console.log('\\n');\r\n console.log('=== Agent Execution Complete ===');\r\n console.log(`Input tokens: ${response.usage.inputTokens}`);\r\n console.log(`Output tokens: ${response.usage.outputTokens}`);\r\n console.log(`Stop reason: ${response.stopReason}`);\r\n\r\n // Stop heartbeat and send final status\r\n if (heartbeatInterval) {\r\n clearInterval(heartbeatInterval);\r\n\r\n if (taskId) {\r\n await execAsync(`redis-cli hset \"swarm:${taskId}:agent:${agentId}\" heartbeat \"${Date.now()}\" status \"complete\"`);\r\n console.log(`[heartbeat] Monitoring stopped - agent ${agentId} complete`);\r\n }\r\n }\r\n\r\n return {\r\n success: true,\r\n output: response.content,\r\n usage: response.usage,\r\n };\r\n } catch (error) {\r\n console.error('[anthropic-client] Error:', error);\r\n\r\n // Stop heartbeat and send error status\r\n if (heartbeatInterval) {\r\n clearInterval(heartbeatInterval);\r\n\r\n if (taskId) {\r\n try {\r\n await execAsync(`redis-cli hset \"swarm:${taskId}:agent:${agentId}\" heartbeat \"${Date.now()}\" status \"error\"`);\r\n console.log(`[heartbeat] Monitoring stopped - agent ${agentId} error`);\r\n } catch (err) {\r\n // Ignore heartbeat errors during error handling\r\n }\r\n }\r\n }\r\n\r\n return {\r\n success: false,\r\n output: '',\r\n usage: { inputTokens: 0, outputTokens: 0 },\r\n error: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n}\r\n"],"names":["Anthropic","fs","path","exec","promisify","executeTool","execAsync","getAPIConfig","envProvider","process","env","CLAUDE_API_PROVIDER","provider","apiKey","ZAI_API_KEY","ANTHROPIC_API_KEY","baseURL","ZAI_BASE_URL","configPath","join","config","JSON","parse","readFile","createClient","Error","clientOptions","timeout","maxRetries","mapModelName","agentModel","zaiModelMap","haiku","sonnet","opus","modelMap","getFallbackModel","model","sendMessage","options","onChunk","client","maxTokens","temperature","enableStreaming","stream","console","log","messages","map","m","role","content","prompt","lastError","attempts","maxAttempts","currentModel","requestParams","max_tokens","systemPrompt","system","tools","length","fullContent","inputTokens","outputTokens","stopReason","create","event","type","message","usage","input_tokens","text","delta","output_tokens","stop_reason","response","filter","block","error","String","executeWithTools","totalInputTokens","totalOutputTokens","fullTextContent","MAX_ITERATIONS","iteration","textBlocks","toolUseBlocks","toolResults","toolUseBlock","toolUse","id","name","input","result","push","substring","warn","executeAgentAPI","agentType","agentId","heartbeatInterval","taskId","TASK_ID","setInterval","Date","now","err","fullOutput","t","chunk","stdout","write","clearInterval","success","output"],"mappings":"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"}
@@ -1,4 +1,154 @@
1
1
  #!/usr/bin/env node
2
+ import { exec } from 'child_process';
3
+ import { promisify } from 'util';
4
+ const execAsync = promisify(exec);
5
+ // ============================================================================
6
+ // Redis Epic Context Functions
7
+ // ============================================================================
8
+ /**
9
+ * Load epic context from Redis
10
+ *
11
+ * Redis key: swarm:{taskId}:epic-context
12
+ */ export async function loadEpicContext(taskId) {
13
+ try {
14
+ const { stdout } = await execAsync(`redis-cli get "swarm:${taskId}:epic-context"`);
15
+ const result = stdout.trim();
16
+ if (result === '(nil)' || !result) {
17
+ return null;
18
+ }
19
+ return JSON.parse(result);
20
+ } catch (error) {
21
+ console.warn(`[cfn-context] Failed to load epic context for task ${taskId}:`, error);
22
+ return null;
23
+ }
24
+ }
25
+ /**
26
+ * Load phase context from Redis
27
+ *
28
+ * Redis key: swarm:{taskId}:phase-context
29
+ */ export async function loadPhaseContext(taskId) {
30
+ try {
31
+ const { stdout } = await execAsync(`redis-cli get "swarm:${taskId}:phase-context"`);
32
+ const result = stdout.trim();
33
+ if (result === '(nil)' || !result) {
34
+ return null;
35
+ }
36
+ return JSON.parse(result);
37
+ } catch (error) {
38
+ console.warn(`[cfn-context] Failed to load phase context for task ${taskId}:`, error);
39
+ return null;
40
+ }
41
+ }
42
+ /**
43
+ * Load success criteria from Redis
44
+ *
45
+ * Redis key: swarm:{taskId}:success-criteria
46
+ */ export async function loadSuccessCriteria(taskId) {
47
+ try {
48
+ const { stdout } = await execAsync(`redis-cli get "swarm:${taskId}:success-criteria"`);
49
+ const result = stdout.trim();
50
+ if (result === '(nil)' || !result) {
51
+ return null;
52
+ }
53
+ return JSON.parse(result);
54
+ } catch (error) {
55
+ console.warn(`[cfn-context] Failed to load success criteria for task ${taskId}:`, error);
56
+ return null;
57
+ }
58
+ }
59
+ /**
60
+ * Store epic context to Redis
61
+ *
62
+ * Redis key: swarm:{taskId}:epic-context
63
+ * TTL: 7 days
64
+ */ export async function storeEpicContext(taskId, context) {
65
+ try {
66
+ const contextJson = JSON.stringify(context);
67
+ await execAsync(`redis-cli setex "swarm:${taskId}:epic-context" 604800 '${contextJson.replace(/'/g, "\\'")}'`);
68
+ console.log(`[cfn-context] Stored epic context for task ${taskId}`);
69
+ return true;
70
+ } catch (error) {
71
+ console.error(`[cfn-context] Failed to store epic context for task ${taskId}:`, error);
72
+ return false;
73
+ }
74
+ }
75
+ /**
76
+ * Store phase context to Redis
77
+ *
78
+ * Redis key: swarm:{taskId}:phase-context
79
+ * TTL: 7 days
80
+ */ export async function storePhaseContext(taskId, context) {
81
+ try {
82
+ const contextJson = JSON.stringify(context);
83
+ await execAsync(`redis-cli setex "swarm:${taskId}:phase-context" 604800 '${contextJson.replace(/'/g, "\\'")}'`);
84
+ console.log(`[cfn-context] Stored phase context for task ${taskId}`);
85
+ return true;
86
+ } catch (error) {
87
+ console.error(`[cfn-context] Failed to store phase context for task ${taskId}:`, error);
88
+ return false;
89
+ }
90
+ }
91
+ /**
92
+ * Store success criteria to Redis
93
+ *
94
+ * Redis key: swarm:{taskId}:success-criteria
95
+ * TTL: 7 days
96
+ */ export async function storeSuccessCriteria(taskId, criteria) {
97
+ try {
98
+ const criteriaJson = JSON.stringify(criteria);
99
+ await execAsync(`redis-cli setex "swarm:${taskId}:success-criteria" 604800 '${criteriaJson.replace(/'/g, "\\'")}'`);
100
+ console.log(`[cfn-context] Stored success criteria for task ${taskId}`);
101
+ return true;
102
+ } catch (error) {
103
+ console.error(`[cfn-context] Failed to store success criteria for task ${taskId}:`, error);
104
+ return false;
105
+ }
106
+ }
107
+ /**
108
+ * Format epic context as markdown for system prompt
109
+ */ export function formatEpicContextForPrompt(epic) {
110
+ if (!epic.epicGoal && !epic.inScope && !epic.outOfScope) {
111
+ return '';
112
+ }
113
+ const sections = [];
114
+ sections.push('## Epic Context');
115
+ sections.push('');
116
+ if (epic.epicName) {
117
+ sections.push(`**Epic:** ${epic.epicName}`);
118
+ sections.push('');
119
+ }
120
+ if (epic.epicGoal) {
121
+ sections.push('**Goal:**');
122
+ sections.push(epic.epicGoal);
123
+ sections.push('');
124
+ }
125
+ if (epic.currentPhase) {
126
+ sections.push(`**Current Phase:** ${epic.currentPhase}`);
127
+ sections.push('');
128
+ }
129
+ if (epic.inScope && epic.inScope.length > 0) {
130
+ sections.push('**In Scope:**');
131
+ for (const item of epic.inScope){
132
+ sections.push(`- ${item}`);
133
+ }
134
+ sections.push('');
135
+ }
136
+ if (epic.outOfScope && epic.outOfScope.length > 0) {
137
+ sections.push('**Out of Scope:**');
138
+ for (const item of epic.outOfScope){
139
+ sections.push(`- ${item}`);
140
+ }
141
+ sections.push('');
142
+ }
143
+ if (epic.references && epic.references.length > 0) {
144
+ sections.push('**References:**');
145
+ for (const ref of epic.references){
146
+ sections.push(`- ${ref}`);
147
+ }
148
+ sections.push('');
149
+ }
150
+ return sections.join('\n');
151
+ }
2
152
  function parseArgs(args) {
3
153
  const subcommand = args[0] || 'stats';
4
154
  let query;