claude-flow-novice 2.0.3 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/dist/src/cli/commands/guidance.js +487 -668
  2. package/dist/src/cli/commands/index-validate.js +18 -29
  3. package/dist/src/cli/commands/mcp-troubleshoot.js +230 -282
  4. package/dist/src/cli/commands/neural-goal-init.js +92 -125
  5. package/dist/src/cli/commands/swarm-exec.js +317 -393
  6. package/dist/src/cli/commands/swarm.js +1 -1
  7. package/dist/src/cli/commands/validate-framework.js +983 -1100
  8. package/dist/src/cli/commands/validate.js +144 -223
  9. package/dist/src/cli/simple-commands/__tests__/agent.test.js +265 -277
  10. package/dist/src/cli/simple-commands/__tests__/memory.test.js +6 -7
  11. package/dist/src/cli/simple-commands/__tests__/swarm.test.js +373 -356
  12. package/dist/src/cli/simple-commands/__tests__/task.test.js +6 -7
  13. package/dist/src/cli/simple-commands/agent.js +157 -193
  14. package/dist/src/cli/simple-commands/analysis.js +336 -446
  15. package/dist/src/cli/simple-commands/automation-executor.js +1095 -1339
  16. package/dist/src/cli/simple-commands/automation.js +481 -469
  17. package/dist/src/cli/simple-commands/batch-manager.js +261 -313
  18. package/dist/src/cli/simple-commands/claude-telemetry.js +241 -267
  19. package/dist/src/cli/simple-commands/claude-track.js +68 -90
  20. package/dist/src/cli/simple-commands/concurrent-display.js +266 -320
  21. package/dist/src/cli/simple-commands/config.js +245 -290
  22. package/dist/src/cli/simple-commands/coordination.js +182 -234
  23. package/dist/src/cli/simple-commands/enhanced-ui-views.js +812 -615
  24. package/dist/src/cli/simple-commands/enhanced-webui-complete.js +922 -981
  25. package/dist/src/cli/simple-commands/fix-hook-variables.js +274 -294
  26. package/dist/src/cli/simple-commands/github/gh-coordinator.js +378 -457
  27. package/dist/src/cli/simple-commands/github/github-api.js +535 -574
  28. package/dist/src/cli/simple-commands/github/init.js +276 -303
  29. package/dist/src/cli/simple-commands/github.js +222 -247
  30. package/dist/src/cli/simple-commands/goal.js +51 -63
  31. package/dist/src/cli/simple-commands/hive-mind/auto-save-middleware.js +208 -278
  32. package/dist/src/cli/simple-commands/hive-mind/communication.js +601 -696
  33. package/dist/src/cli/simple-commands/hive-mind/core.js +907 -979
  34. package/dist/src/cli/simple-commands/hive-mind/db-optimizer.js +406 -655
  35. package/dist/src/cli/simple-commands/hive-mind/mcp-wrapper.js +1125 -1245
  36. package/dist/src/cli/simple-commands/hive-mind/memory.js +854 -1090
  37. package/dist/src/cli/simple-commands/hive-mind/performance-optimizer.js +459 -574
  38. package/dist/src/cli/simple-commands/hive-mind/performance-test.js +263 -347
  39. package/dist/src/cli/simple-commands/hive-mind/queen.js +727 -768
  40. package/dist/src/cli/simple-commands/hive-mind/session-manager.js +745 -1049
  41. package/dist/src/cli/simple-commands/hive-mind-optimize.js +227 -283
  42. package/dist/src/cli/simple-commands/hive-mind-wizard.js +174 -217
  43. package/dist/src/cli/simple-commands/hive-mind.js +1842 -2283
  44. package/dist/src/cli/simple-commands/hive.js +90 -79
  45. package/dist/src/cli/simple-commands/hook-safety.js +431 -521
  46. package/dist/src/cli/simple-commands/hooks/session-start-soul.js +203 -254
  47. package/dist/src/cli/simple-commands/hooks.js +1064 -1204
  48. package/dist/src/cli/simple-commands/init/agent-copier.js +294 -319
  49. package/dist/src/cli/simple-commands/init/batch-init.js +496 -562
  50. package/dist/src/cli/simple-commands/init/claude-commands/claude-flow-commands.js +13 -19
  51. package/dist/src/cli/simple-commands/init/claude-commands/optimized-claude-flow-commands.js +13 -19
  52. package/dist/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +61 -88
  53. package/dist/src/cli/simple-commands/init/claude-commands/optimized-sparc-commands.js +125 -150
  54. package/dist/src/cli/simple-commands/init/claude-commands/slash-commands.js +42 -49
  55. package/dist/src/cli/simple-commands/init/claude-commands/sparc-commands.js +43 -61
  56. package/dist/src/cli/simple-commands/init/copy-revised-templates.js +141 -147
  57. package/dist/src/cli/simple-commands/init/executable-wrapper.js +31 -44
  58. package/dist/src/cli/simple-commands/init/gitignore-updater.js +64 -90
  59. package/dist/src/cli/simple-commands/init/help.js +104 -107
  60. package/dist/src/cli/simple-commands/init/hive-mind-init.js +509 -528
  61. package/dist/src/cli/simple-commands/init/index.js +1510 -1759
  62. package/dist/src/cli/simple-commands/init/performance-monitor.js +234 -317
  63. package/dist/src/cli/simple-commands/init/rollback/backup-manager.js +441 -504
  64. package/dist/src/cli/simple-commands/init/rollback/index.js +289 -364
  65. package/dist/src/cli/simple-commands/init/rollback/recovery-manager.js +652 -728
  66. package/dist/src/cli/simple-commands/init/rollback/rollback-executor.js +416 -481
  67. package/dist/src/cli/simple-commands/init/rollback/state-tracker.js +369 -448
  68. package/dist/src/cli/simple-commands/init/sparc/roo-readme.js +1 -2
  69. package/dist/src/cli/simple-commands/init/sparc/roomodes-config.js +122 -99
  70. package/dist/src/cli/simple-commands/init/sparc/workflows.js +32 -37
  71. package/dist/src/cli/simple-commands/init/sparc-structure.js +55 -62
  72. package/dist/src/cli/simple-commands/init/template-copier.js +421 -533
  73. package/dist/src/cli/simple-commands/init/templates/coordination-md.js +3 -6
  74. package/dist/src/cli/simple-commands/init/templates/enhanced-templates.js +344 -318
  75. package/dist/src/cli/simple-commands/init/templates/github-safe-enhanced.js +173 -218
  76. package/dist/src/cli/simple-commands/init/templates/github-safe.js +65 -75
  77. package/dist/src/cli/simple-commands/init/templates/memory-bank-md.js +3 -6
  78. package/dist/src/cli/simple-commands/init/templates/readme-files.js +2 -4
  79. package/dist/src/cli/simple-commands/init/templates/safe-hook-patterns.js +187 -230
  80. package/dist/src/cli/simple-commands/init/templates/sparc-modes.js +53 -80
  81. package/dist/src/cli/simple-commands/init/templates/verification-claude-md.js +101 -85
  82. package/dist/src/cli/simple-commands/init/validation/config-validator.js +283 -330
  83. package/dist/src/cli/simple-commands/init/validation/health-checker.js +495 -561
  84. package/dist/src/cli/simple-commands/init/validation/index.js +302 -358
  85. package/dist/src/cli/simple-commands/init/validation/mode-validator.js +308 -359
  86. package/dist/src/cli/simple-commands/init/validation/post-init-validator.js +389 -366
  87. package/dist/src/cli/simple-commands/init/validation/pre-init-validator.js +270 -268
  88. package/dist/src/cli/simple-commands/init/validation/test-runner.js +427 -447
  89. package/dist/src/cli/simple-commands/init.js +1 -2
  90. package/dist/src/cli/simple-commands/mcp-health.js +131 -158
  91. package/dist/src/cli/simple-commands/mcp-integration-layer.js +533 -634
  92. package/dist/src/cli/simple-commands/mcp.js +345 -400
  93. package/dist/src/cli/simple-commands/memory-consolidation.js +426 -537
  94. package/dist/src/cli/simple-commands/memory.js +247 -311
  95. package/dist/src/cli/simple-commands/migrate-hooks.js +39 -46
  96. package/dist/src/cli/simple-commands/monitor.js +294 -363
  97. package/dist/src/cli/simple-commands/neural.js +51 -65
  98. package/dist/src/cli/simple-commands/pair-autofix-only.js +538 -662
  99. package/dist/src/cli/simple-commands/pair-basic.js +528 -656
  100. package/dist/src/cli/simple-commands/pair-old.js +430 -543
  101. package/dist/src/cli/simple-commands/pair-working.js +615 -751
  102. package/dist/src/cli/simple-commands/pair.js +615 -751
  103. package/dist/src/cli/simple-commands/performance-hooks.js +83 -111
  104. package/dist/src/cli/simple-commands/performance-metrics.js +348 -433
  105. package/dist/src/cli/simple-commands/process-ui-enhanced.js +708 -787
  106. package/dist/src/cli/simple-commands/process-ui.js +230 -254
  107. package/dist/src/cli/simple-commands/realtime-update-system.js +525 -611
  108. package/dist/src/cli/simple-commands/sparc/architecture.js +1704 -1530
  109. package/dist/src/cli/simple-commands/sparc/commands.js +438 -516
  110. package/dist/src/cli/simple-commands/sparc/completion.js +1224 -1481
  111. package/dist/src/cli/simple-commands/sparc/coordinator.js +913 -978
  112. package/dist/src/cli/simple-commands/sparc/index.js +241 -298
  113. package/dist/src/cli/simple-commands/sparc/phase-base.js +314 -390
  114. package/dist/src/cli/simple-commands/sparc/pseudocode.js +965 -869
  115. package/dist/src/cli/simple-commands/sparc/refinement.js +980 -1273
  116. package/dist/src/cli/simple-commands/sparc/specification.js +559 -645
  117. package/dist/src/cli/simple-commands/sparc-modes/architect.js +1 -1
  118. package/dist/src/cli/simple-commands/sparc-modes/ask.js +1 -1
  119. package/dist/src/cli/simple-commands/sparc-modes/code.js +1 -1
  120. package/dist/src/cli/simple-commands/sparc-modes/debug.js +1 -1
  121. package/dist/src/cli/simple-commands/sparc-modes/devops.js +1 -1
  122. package/dist/src/cli/simple-commands/sparc-modes/docs-writer.js +1 -1
  123. package/dist/src/cli/simple-commands/sparc-modes/generic.js +1 -1
  124. package/dist/src/cli/simple-commands/sparc-modes/index.js +47 -55
  125. package/dist/src/cli/simple-commands/sparc-modes/integration.js +1 -1
  126. package/dist/src/cli/simple-commands/sparc-modes/mcp.js +1 -1
  127. package/dist/src/cli/simple-commands/sparc-modes/monitoring.js +1 -1
  128. package/dist/src/cli/simple-commands/sparc-modes/optimization.js +1 -1
  129. package/dist/src/cli/simple-commands/sparc-modes/security-review.js +1 -1
  130. package/dist/src/cli/simple-commands/sparc-modes/sparc-orchestrator.js +1 -1
  131. package/dist/src/cli/simple-commands/sparc-modes/spec-pseudocode.js +1 -1
  132. package/dist/src/cli/simple-commands/sparc-modes/supabase-admin.js +1 -1
  133. package/dist/src/cli/simple-commands/sparc-modes/swarm.js +101 -87
  134. package/dist/src/cli/simple-commands/sparc-modes/tdd.js +1 -1
  135. package/dist/src/cli/simple-commands/sparc-modes/tutorial.js +1 -1
  136. package/dist/src/cli/simple-commands/sparc.js +465 -493
  137. package/dist/src/cli/simple-commands/start-ui.js +108 -132
  138. package/dist/src/cli/simple-commands/start-wrapper.js +240 -268
  139. package/dist/src/cli/simple-commands/start.js +1 -1
  140. package/dist/src/cli/simple-commands/status.js +254 -275
  141. package/dist/src/cli/simple-commands/stream-chain-clean.js +128 -171
  142. package/dist/src/cli/simple-commands/stream-chain-fixed.js +61 -82
  143. package/dist/src/cli/simple-commands/stream-chain-real.js +267 -331
  144. package/dist/src/cli/simple-commands/stream-chain-working.js +211 -263
  145. package/dist/src/cli/simple-commands/stream-chain.js +260 -318
  146. package/dist/src/cli/simple-commands/stream-processor.js +290 -315
  147. package/dist/src/cli/simple-commands/swarm-executor.js +189 -222
  148. package/dist/src/cli/simple-commands/swarm-metrics-integration.js +208 -300
  149. package/dist/src/cli/simple-commands/swarm-ui.js +623 -703
  150. package/dist/src/cli/simple-commands/swarm-webui-integration.js +258 -286
  151. package/dist/src/cli/simple-commands/swarm.js +887 -1082
  152. package/dist/src/cli/simple-commands/task.js +161 -206
  153. package/dist/src/cli/simple-commands/timestamp-fix.js +59 -89
  154. package/dist/src/cli/simple-commands/token-tracker.js +258 -316
  155. package/dist/src/cli/simple-commands/tool-execution-framework.js +433 -519
  156. package/dist/src/cli/simple-commands/train-and-stream.js +275 -331
  157. package/dist/src/cli/simple-commands/training-pipeline.js +619 -725
  158. package/dist/src/cli/simple-commands/training.js +170 -227
  159. package/dist/src/cli/simple-commands/verification-hooks.js +261 -284
  160. package/dist/src/cli/simple-commands/verification-integration.js +389 -417
  161. package/dist/src/cli/simple-commands/verification-training-integration.js +486 -606
  162. package/dist/src/cli/simple-commands/verification.js +493 -513
  163. package/dist/src/cli/simple-commands/web-server.js +766 -836
  164. package/dist/src/cli/simple-commands/webui-validator.js +106 -124
  165. package/dist/src/coordination/event-bus/demo-wasm-integration.js +212 -251
  166. package/dist/src/coordination/event-bus/qe-event-bus.js +608 -748
  167. package/dist/src/coordination/event-bus/qe-event-bus.test.js +379 -454
  168. package/dist/src/coordination/iteration-tracker.js +363 -454
  169. package/dist/src/enterprise/analytics-manager.js +1135 -0
  170. package/dist/src/enterprise/audit-manager.js +1115 -0
  171. package/dist/src/enterprise/cloud-manager.js +891 -0
  172. package/dist/src/enterprise/deployment-manager.js +966 -0
  173. package/dist/src/enterprise/index.js +6 -0
  174. package/dist/src/enterprise/project-manager.js +584 -0
  175. package/dist/src/enterprise/security-manager.js +991 -0
  176. package/dist/src/index.js +1 -1
  177. package/dist/src/mcp/DEPRECATED.js +46 -60
  178. package/dist/src/mcp/fixes/mcp-error-fixes.js +115 -134
  179. package/dist/src/mcp/implementations/agent-tracker.js +114 -128
  180. package/dist/src/mcp/implementations/daa-tools.js +292 -350
  181. package/dist/src/mcp/implementations/workflow-tools.js +329 -361
  182. package/dist/src/mcp/mcp-config-manager.js +1183 -1331
  183. package/dist/src/mcp/mcp-server-novice-simplified.js +11 -17
  184. package/dist/src/mcp/mcp-server-novice.js +11 -17
  185. package/dist/src/mcp/mcp-server-sdk.js +11 -17
  186. package/dist/src/mcp/mcp-server.js +1620 -1484
  187. package/dist/src/mcp/ruv-swarm-wrapper.js +209 -239
  188. package/dist/src/memory/advanced-serializer.js +609 -589
  189. package/dist/src/memory/enhanced-examples.js +220 -305
  190. package/dist/src/memory/enhanced-memory.js +295 -336
  191. package/dist/src/memory/enhanced-session-serializer.js +408 -492
  192. package/dist/src/memory/fallback-memory-system.js +900 -1021
  193. package/dist/src/memory/fallback-store.js +93 -131
  194. package/dist/src/memory/high-performance-serialization.js +592 -730
  195. package/dist/src/memory/in-memory-store.js +161 -213
  196. package/dist/src/memory/index.js +123 -157
  197. package/dist/src/memory/lock-free-structures.js +578 -764
  198. package/dist/src/memory/memory-mapped-persistence.js +585 -766
  199. package/dist/src/memory/memory-pressure-manager.js +569 -707
  200. package/dist/src/memory/migration.js +358 -445
  201. package/dist/src/memory/shared-memory.js +641 -768
  202. package/dist/src/memory/sqlite-store.js +245 -325
  203. package/dist/src/memory/sqlite-wrapper.js +122 -151
  204. package/dist/src/memory/swarm-memory.js +470 -603
  205. package/dist/src/memory/test-example.js +126 -134
  206. package/dist/src/memory/ultra-fast-memory-store.js +622 -821
  207. package/dist/src/memory/unified-memory-manager.js +356 -437
  208. package/dist/src/migration/index.js +92 -0
  209. package/dist/src/migration/logger.js +121 -0
  210. package/dist/src/migration/migration-analyzer.js +268 -0
  211. package/dist/src/migration/migration-runner.js +522 -0
  212. package/dist/src/migration/migration-validator.js +285 -0
  213. package/dist/src/migration/progress-reporter.js +150 -0
  214. package/dist/src/migration/rollback-manager.js +321 -0
  215. package/dist/src/migration/tests/migration-system.test.js +7 -0
  216. package/dist/src/migration/types.js +3 -0
  217. package/dist/src/swarm/CodeRefactoringSwarm.js +777 -952
  218. package/dist/src/swarm/__tests__/integration.test.js +227 -0
  219. package/dist/src/swarm/__tests__/prompt-copier.test.js +344 -0
  220. package/dist/src/swarm/advanced-orchestrator.js +1095 -0
  221. package/dist/src/swarm/claude-code-interface.js +961 -0
  222. package/dist/src/swarm/claude-flow-executor.js +229 -0
  223. package/dist/src/swarm/consensus-coordinator.js +475 -0
  224. package/dist/src/swarm/coordinator.js +2993 -0
  225. package/dist/src/swarm/direct-executor.js +1180 -0
  226. package/dist/src/swarm/error-recovery/advanced-error-detection.js +691 -0
  227. package/dist/src/swarm/error-recovery/automated-recovery-workflows.js +998 -0
  228. package/dist/src/swarm/error-recovery/error-recovery-coordinator.js +1197 -0
  229. package/dist/src/swarm/error-recovery/recovery-monitoring.js +772 -0
  230. package/dist/src/swarm/error-recovery/resilience-architecture.js +714 -0
  231. package/dist/src/swarm/error-recovery/self-healing-mechanisms.js +1319 -0
  232. package/dist/src/swarm/error-recovery/test-error-recovery-effectiveness.js +808 -0
  233. package/dist/src/swarm/executor-v2.js +322 -0
  234. package/dist/src/swarm/executor.js +815 -0
  235. package/dist/src/swarm/hive-mind-integration.js +703 -0
  236. package/dist/src/swarm/index.js +41 -0
  237. package/dist/src/swarm/json-output-aggregator.js +267 -0
  238. package/dist/src/swarm/large-scale-coordinator.js +542 -0
  239. package/dist/src/swarm/mcp-integration-wrapper.js +628 -0
  240. package/dist/src/swarm/memory.js +1117 -0
  241. package/dist/src/swarm/optimizations/__tests__/optimization.test.js +348 -0
  242. package/dist/src/swarm/optimizations/async-file-manager.js +285 -0
  243. package/dist/src/swarm/optimizations/circular-buffer.js +162 -0
  244. package/dist/src/swarm/optimizations/connection-pool.js +244 -0
  245. package/dist/src/swarm/optimizations/index.js +28 -0
  246. package/dist/src/swarm/optimizations/optimized-executor.js +320 -0
  247. package/dist/src/swarm/optimizations/ttl-map.js +234 -0
  248. package/dist/src/swarm/prompt-cli.js +200 -0
  249. package/dist/src/swarm/prompt-copier-enhanced.js +202 -0
  250. package/dist/src/swarm/prompt-copier.js +381 -0
  251. package/dist/src/swarm/prompt-manager.js +295 -0
  252. package/dist/src/swarm/prompt-utils.js +310 -0
  253. package/dist/src/swarm/result-aggregator.js +718 -0
  254. package/dist/src/swarm/sparc-executor.js +1568 -0
  255. package/dist/src/swarm/strategies/auto.js +758 -0
  256. package/dist/src/swarm/strategies/base.js +128 -0
  257. package/dist/src/swarm/strategies/research.js +914 -0
  258. package/dist/src/swarm/strategies/strategy-metrics-patch.js +2 -0
  259. package/dist/src/swarm/types.js +52 -0
  260. package/dist/src/swarm/workers/copy-worker.js +56 -0
  261. package/dist/src/utils/__tests__/github-cli-safety-wrapper.test.js +332 -400
  262. package/dist/src/utils/github-cli-safe.js +56 -64
  263. package/dist/src/utils/github-cli-safety-wrapper.js +451 -546
  264. package/dist/src/utils/npx-isolated-cache.js +104 -119
  265. package/dist/src/utils/preference-manager.js +622 -652
  266. package/dist/src/utils/timezone-utils.js +86 -105
  267. package/dist/src/validators/epic-config-schema.js +214 -0
  268. package/dist/src/validators/index.js +10 -0
  269. package/dist/src/validators/swarm-init-validator.js +259 -0
  270. package/dist/src/validators/todowrite-batching-validator.js +215 -0
  271. package/dist/src/validators/todowrite-integration.js +187 -0
  272. package/package.json +2 -2
@@ -0,0 +1,2993 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ import { EventEmitter } from "events";
15
+ import { promises as fs } from "node:fs";
16
+ import { Logger } from "../core/logger.js";
17
+ import { generateId } from "../utils/helpers.js";
18
+ import { SWARM_CONSTANTS } from "./types.js";
19
+ import { AutoStrategy } from "./strategies/auto.js";
20
+ import { getClaudeFlowRoot, getClaudeFlowBin } from "../utils/paths.js";
21
+ import { SwarmJsonOutputAggregator } from "./json-output-aggregator.js";
22
+ export class SwarmCoordinator extends EventEmitter {
23
+ // ===== LIFECYCLE MANAGEMENT =====
24
+ async initialize() {
25
+ if (this._isRunning) {
26
+ throw new Error('Swarm coordinator already running');
27
+ }
28
+ this.logger.info('Initializing swarm coordinator...');
29
+ this.status = 'initializing';
30
+ try {
31
+ // Validate configuration
32
+ const validation = await this.validateConfiguration();
33
+ if (!validation.valid) {
34
+ throw new Error(`Configuration validation failed: ${validation.errors.map((e)=>e.message).join(', ')}`);
35
+ }
36
+ // Initialize subsystems
37
+ await this.initializeSubsystems();
38
+ // Start background processes
39
+ this.startBackgroundProcesses();
40
+ this._isRunning = true;
41
+ this.startTime = new Date();
42
+ this.status = 'executing';
43
+ this.emitSwarmEvent({
44
+ id: generateId('event'),
45
+ timestamp: new Date(),
46
+ type: 'swarm.started',
47
+ source: this.swarmId.id,
48
+ data: {
49
+ swarmId: this.swarmId
50
+ },
51
+ broadcast: true,
52
+ processed: false
53
+ });
54
+ this.logger.info('Swarm coordinator initialized successfully');
55
+ } catch (error) {
56
+ this.status = 'failed';
57
+ this.logger.error('Failed to initialize swarm coordinator', {
58
+ error
59
+ });
60
+ throw error;
61
+ }
62
+ }
63
+ async shutdown() {
64
+ if (!this._isRunning) {
65
+ return;
66
+ }
67
+ this.logger.info('Shutting down swarm coordinator...');
68
+ this.status = 'paused';
69
+ try {
70
+ // Stop background processes
71
+ this.stopBackgroundProcesses();
72
+ // Gracefully stop all agents
73
+ await this.stopAllAgents();
74
+ // Complete any running tasks
75
+ await this.completeRunningTasks();
76
+ // Save final state
77
+ await this.saveState();
78
+ this._isRunning = false;
79
+ this.endTime = new Date();
80
+ this.status = 'completed';
81
+ this.emitSwarmEvent({
82
+ id: generateId('event'),
83
+ timestamp: new Date(),
84
+ type: 'swarm.completed',
85
+ source: this.swarmId.id,
86
+ data: {
87
+ swarmId: this.swarmId,
88
+ metrics: this.metrics,
89
+ duration: this.endTime.getTime() - (this.startTime?.getTime() || 0)
90
+ },
91
+ broadcast: true,
92
+ processed: false
93
+ });
94
+ this.logger.info('Swarm coordinator shut down successfully');
95
+ } catch (error) {
96
+ this.logger.error('Error during swarm coordinator shutdown', {
97
+ error
98
+ });
99
+ throw error;
100
+ }
101
+ }
102
+ async pause() {
103
+ if (!this._isRunning || this.status === 'paused') {
104
+ return;
105
+ }
106
+ this.logger.info('Pausing swarm coordinator...');
107
+ this.status = 'paused';
108
+ // Pause all agents
109
+ for (const agent of this.agents.values()){
110
+ if (agent.status === 'busy') {
111
+ await this.pauseAgent(agent.id);
112
+ }
113
+ }
114
+ this.emitSwarmEvent({
115
+ id: generateId('event'),
116
+ timestamp: new Date(),
117
+ type: 'swarm.paused',
118
+ source: this.swarmId.id,
119
+ data: {
120
+ swarmId: this.swarmId
121
+ },
122
+ broadcast: true,
123
+ processed: false
124
+ });
125
+ }
126
+ async resume() {
127
+ if (!this._isRunning || this.status !== 'paused') {
128
+ return;
129
+ }
130
+ this.logger.info('Resuming swarm coordinator...');
131
+ this.status = 'executing';
132
+ // Resume all paused agents
133
+ for (const agent of this.agents.values()){
134
+ if (agent.status === 'paused') {
135
+ await this.resumeAgent(agent.id);
136
+ }
137
+ }
138
+ this.emitSwarmEvent({
139
+ id: generateId('event'),
140
+ timestamp: new Date(),
141
+ type: 'swarm.resumed',
142
+ source: this.swarmId.id,
143
+ data: {
144
+ swarmId: this.swarmId
145
+ },
146
+ broadcast: true,
147
+ processed: false
148
+ });
149
+ }
150
+ // ===== OBJECTIVE MANAGEMENT =====
151
+ async createObjective(name, description, strategy = 'auto', requirements = {}) {
152
+ const objectiveId = generateId('objective');
153
+ const objective = {
154
+ id: objectiveId,
155
+ name,
156
+ description,
157
+ strategy,
158
+ mode: this.config.mode,
159
+ requirements: {
160
+ minAgents: 1,
161
+ maxAgents: this.config.maxAgents,
162
+ agentTypes: this.determineRequiredAgentTypes(strategy),
163
+ estimatedDuration: 60 * 60 * 1000,
164
+ maxDuration: 4 * 60 * 60 * 1000,
165
+ qualityThreshold: this.config.qualityThreshold,
166
+ reviewCoverage: 0.8,
167
+ testCoverage: 0.7,
168
+ reliabilityTarget: 0.95,
169
+ ...requirements
170
+ },
171
+ constraints: {
172
+ minQuality: this.config.qualityThreshold,
173
+ requiredApprovals: [],
174
+ allowedFailures: Math.floor(this.config.maxAgents * 0.1),
175
+ recoveryTime: 5 * 60 * 1000,
176
+ milestones: []
177
+ },
178
+ tasks: [],
179
+ dependencies: [],
180
+ status: 'planning',
181
+ progress: this.initializeProgress(),
182
+ createdAt: new Date(),
183
+ metrics: this.initializeMetrics()
184
+ };
185
+ // Decompose objective into tasks using optimized AUTO strategy
186
+ if (objective.strategy === 'auto') {
187
+ const decompositionResult = await this.autoStrategy.decomposeObjective(objective);
188
+ objective.tasks = decompositionResult.tasks;
189
+ objective.dependencies = this.convertDependenciesToTaskDependencies(decompositionResult.dependencies);
190
+ } else {
191
+ objective.tasks = await this.decomposeObjective(objective);
192
+ objective.dependencies = this.analyzeDependencies(objective.tasks);
193
+ }
194
+ this.objectives.set(objectiveId, objective);
195
+ this.logger.info('Created objective', {
196
+ objectiveId,
197
+ name,
198
+ strategy,
199
+ taskCount: objective.tasks.length
200
+ });
201
+ return objectiveId;
202
+ }
203
+ async executeObjective(objectiveId) {
204
+ const objective = this.objectives.get(objectiveId);
205
+ if (!objective) {
206
+ throw new Error(`Objective not found: ${objectiveId}`);
207
+ }
208
+ if (objective.status !== 'planning') {
209
+ throw new Error(`Objective already ${objective.status}`);
210
+ }
211
+ this.logger.info('Executing objective', {
212
+ objectiveId,
213
+ name: objective.name
214
+ });
215
+ objective.status = 'executing';
216
+ objective.startedAt = new Date();
217
+ try {
218
+ // Ensure we have required agents
219
+ await this.ensureRequiredAgents(objective);
220
+ // Schedule initial tasks
221
+ await this.scheduleInitialTasks(objective);
222
+ // Start task execution loop
223
+ this.startTaskExecutionLoop(objective);
224
+ } catch (error) {
225
+ objective.status = 'failed';
226
+ this.logger.error('Failed to execute objective', {
227
+ objectiveId,
228
+ error
229
+ });
230
+ throw error;
231
+ }
232
+ }
233
+ // ===== AGENT MANAGEMENT =====
234
+ async registerAgent(name, type, capabilities = {}) {
235
+ const agentId = {
236
+ id: generateId('agent'),
237
+ swarmId: this.swarmId.id,
238
+ type,
239
+ instance: this.getNextInstanceNumber(type)
240
+ };
241
+ const agentState = {
242
+ id: agentId,
243
+ name,
244
+ type,
245
+ status: 'initializing',
246
+ capabilities: {
247
+ // Default capabilities
248
+ codeGeneration: false,
249
+ codeReview: false,
250
+ testing: false,
251
+ documentation: false,
252
+ research: false,
253
+ analysis: false,
254
+ webSearch: false,
255
+ apiIntegration: false,
256
+ fileSystem: true,
257
+ terminalAccess: true,
258
+ languages: [],
259
+ frameworks: [],
260
+ domains: [],
261
+ tools: [],
262
+ maxConcurrentTasks: 3,
263
+ maxMemoryUsage: SWARM_CONSTANTS.DEFAULT_MEMORY_LIMIT,
264
+ maxExecutionTime: SWARM_CONSTANTS.DEFAULT_TASK_TIMEOUT,
265
+ reliability: 0.8,
266
+ speed: 1.0,
267
+ quality: 0.8,
268
+ ...capabilities
269
+ },
270
+ metrics: {
271
+ tasksCompleted: 0,
272
+ tasksFailed: 0,
273
+ averageExecutionTime: 0,
274
+ successRate: 0,
275
+ cpuUsage: 0,
276
+ memoryUsage: 0,
277
+ diskUsage: 0,
278
+ networkUsage: 0,
279
+ codeQuality: 0,
280
+ testCoverage: 0,
281
+ bugRate: 0,
282
+ userSatisfaction: 0,
283
+ totalUptime: 0,
284
+ lastActivity: new Date(),
285
+ responseTime: 0
286
+ },
287
+ workload: 0,
288
+ health: 1.0,
289
+ config: {
290
+ autonomyLevel: 0.7,
291
+ learningEnabled: true,
292
+ adaptationEnabled: true,
293
+ maxTasksPerHour: 10,
294
+ maxConcurrentTasks: capabilities.maxConcurrentTasks || 3,
295
+ timeoutThreshold: SWARM_CONSTANTS.DEFAULT_TASK_TIMEOUT,
296
+ reportingInterval: 30000,
297
+ heartbeatInterval: SWARM_CONSTANTS.DEFAULT_HEARTBEAT_INTERVAL,
298
+ permissions: this.getDefaultPermissions(type),
299
+ trustedAgents: [],
300
+ expertise: {},
301
+ preferences: {}
302
+ },
303
+ environment: {
304
+ runtime: 'deno',
305
+ version: '1.0.0',
306
+ workingDirectory: `/tmp/swarm/${this.swarmId.id}/agents/${agentId.id}`,
307
+ tempDirectory: `/tmp/swarm/${this.swarmId.id}/agents/${agentId.id}/temp`,
308
+ logDirectory: `/tmp/swarm/${this.swarmId.id}/agents/${agentId.id}/logs`,
309
+ apiEndpoints: {},
310
+ credentials: {},
311
+ availableTools: [],
312
+ toolConfigs: {}
313
+ },
314
+ endpoints: [],
315
+ lastHeartbeat: new Date(),
316
+ taskHistory: [],
317
+ errorHistory: [],
318
+ childAgents: [],
319
+ collaborators: []
320
+ };
321
+ this.agents.set(agentId.id, agentState);
322
+ // Track agent in JSON output if enabled
323
+ this.trackAgentInJsonOutput(agentState);
324
+ // Initialize agent capabilities based on type
325
+ await this.initializeAgentCapabilities(agentState);
326
+ // Start agent
327
+ await this.startAgent(agentId.id);
328
+ this.logger.info('Registered agent', {
329
+ agentId: agentId.id,
330
+ name,
331
+ type,
332
+ capabilities: Object.keys(capabilities)
333
+ });
334
+ this.emitSwarmEvent({
335
+ id: generateId('event'),
336
+ timestamp: new Date(),
337
+ type: 'agent.created',
338
+ source: agentId.id,
339
+ data: {
340
+ agent: agentState
341
+ },
342
+ broadcast: false,
343
+ processed: false
344
+ });
345
+ return agentId.id;
346
+ }
347
+ async unregisterAgent(agentId) {
348
+ const agent = this.agents.get(agentId);
349
+ if (!agent) {
350
+ return;
351
+ }
352
+ this.logger.info('Unregistering agent', {
353
+ agentId,
354
+ name: agent.name
355
+ });
356
+ // Stop agent gracefully
357
+ await this.stopAgent(agentId);
358
+ // Reassign any active tasks
359
+ if (agent.currentTask) {
360
+ await this.reassignTask(agent.currentTask.id);
361
+ }
362
+ // Remove from agents map
363
+ this.agents.delete(agentId);
364
+ this.emitSwarmEvent({
365
+ id: generateId('event'),
366
+ timestamp: new Date(),
367
+ type: 'agent.stopped',
368
+ source: agentId,
369
+ data: {
370
+ agentId
371
+ },
372
+ broadcast: false,
373
+ processed: false
374
+ });
375
+ }
376
+ async startAgent(agentId) {
377
+ const agent = this.agents.get(agentId);
378
+ if (!agent) {
379
+ throw new Error(`Agent not found: ${agentId}`);
380
+ }
381
+ if (agent.status !== 'initializing' && agent.status !== 'offline') {
382
+ return;
383
+ }
384
+ this.logger.info('Starting agent', {
385
+ agentId,
386
+ name: agent.name
387
+ });
388
+ try {
389
+ // Initialize agent environment
390
+ await this.initializeAgentEnvironment(agent);
391
+ // Start agent heartbeat
392
+ this.startAgentHeartbeat(agent);
393
+ agent.status = 'idle';
394
+ agent.lastHeartbeat = new Date();
395
+ this.emitSwarmEvent({
396
+ id: generateId('event'),
397
+ timestamp: new Date(),
398
+ type: 'agent.started',
399
+ source: agentId,
400
+ data: {
401
+ agent
402
+ },
403
+ broadcast: false,
404
+ processed: false
405
+ });
406
+ } catch (error) {
407
+ agent.status = 'error';
408
+ agent.errorHistory.push({
409
+ timestamp: new Date(),
410
+ type: 'startup_error',
411
+ message: error instanceof Error ? error.message : String(error),
412
+ stack: error.stack,
413
+ context: {
414
+ agentId
415
+ },
416
+ severity: 'high',
417
+ resolved: false
418
+ });
419
+ this.logger.error('Failed to start agent', {
420
+ agentId,
421
+ error
422
+ });
423
+ throw error;
424
+ }
425
+ }
426
+ async stopAgent(agentId) {
427
+ const agent = this.agents.get(agentId);
428
+ if (!agent) {
429
+ return;
430
+ }
431
+ if (agent.status === 'offline' || agent.status === 'terminated') {
432
+ return;
433
+ }
434
+ this.logger.info('Stopping agent', {
435
+ agentId,
436
+ name: agent.name
437
+ });
438
+ agent.status = 'terminating';
439
+ try {
440
+ // Cancel current task if any
441
+ if (agent.currentTask) {
442
+ await this.cancelTask(agent.currentTask.id, 'Agent stopping');
443
+ }
444
+ // Stop heartbeat
445
+ this.stopAgentHeartbeat(agent);
446
+ // Cleanup agent environment
447
+ await this.cleanupAgentEnvironment(agent);
448
+ agent.status = 'terminated';
449
+ } catch (error) {
450
+ agent.status = 'error';
451
+ this.logger.error('Error stopping agent', {
452
+ agentId,
453
+ error
454
+ });
455
+ }
456
+ }
457
+ async pauseAgent(agentId) {
458
+ const agent = this.agents.get(agentId);
459
+ if (!agent || agent.status !== 'busy') {
460
+ return;
461
+ }
462
+ agent.status = 'paused';
463
+ this.logger.info('Paused agent', {
464
+ agentId
465
+ });
466
+ }
467
+ async resumeAgent(agentId) {
468
+ const agent = this.agents.get(agentId);
469
+ if (!agent || agent.status !== 'paused') {
470
+ return;
471
+ }
472
+ agent.status = 'busy';
473
+ this.logger.info('Resumed agent', {
474
+ agentId
475
+ });
476
+ }
477
+ // ===== TASK MANAGEMENT =====
478
+ async createTask(type, name, description, instructions, options = {}) {
479
+ const taskId = {
480
+ id: generateId('task'),
481
+ swarmId: this.swarmId.id,
482
+ sequence: this.tasks.size + 1,
483
+ priority: 1
484
+ };
485
+ const task = {
486
+ id: taskId,
487
+ type,
488
+ name,
489
+ description,
490
+ instructions,
491
+ requirements: {
492
+ capabilities: this.getRequiredCapabilities(type),
493
+ tools: this.getRequiredTools(type),
494
+ permissions: this.getRequiredPermissions(type),
495
+ ...options.requirements
496
+ },
497
+ constraints: {
498
+ dependencies: [],
499
+ dependents: [],
500
+ conflicts: [],
501
+ maxRetries: SWARM_CONSTANTS.MAX_RETRIES,
502
+ timeoutAfter: SWARM_CONSTANTS.DEFAULT_TASK_TIMEOUT,
503
+ ...options.constraints
504
+ },
505
+ priority: 'normal',
506
+ input: options.input || {},
507
+ context: options.context || {},
508
+ examples: options.examples || [],
509
+ status: 'created',
510
+ createdAt: new Date(),
511
+ updatedAt: new Date(),
512
+ attempts: [],
513
+ statusHistory: [
514
+ {
515
+ timestamp: new Date(),
516
+ from: 'created',
517
+ to: 'created',
518
+ reason: 'Task created',
519
+ triggeredBy: 'system'
520
+ }
521
+ ],
522
+ ...options
523
+ };
524
+ this.tasks.set(taskId.id, task);
525
+ // Track task in JSON output if enabled
526
+ this.trackTaskInJsonOutput(task);
527
+ this.logger.info('Created task', {
528
+ taskId: taskId.id,
529
+ type,
530
+ name,
531
+ priority: task.priority
532
+ });
533
+ this.emitSwarmEvent({
534
+ id: generateId('event'),
535
+ timestamp: new Date(),
536
+ type: 'task.created',
537
+ source: this.swarmId.id,
538
+ data: {
539
+ task
540
+ },
541
+ broadcast: false,
542
+ processed: false
543
+ });
544
+ return taskId.id;
545
+ }
546
+ async assignTask(taskId, agentId) {
547
+ const task = this.tasks.get(taskId);
548
+ if (!task) {
549
+ throw new Error(`Task not found: ${taskId}`);
550
+ }
551
+ if (task.status !== 'created' && task.status !== 'queued') {
552
+ throw new Error(`Task cannot be assigned, current status: ${task.status}`);
553
+ }
554
+ // Select agent if not specified
555
+ if (!agentId) {
556
+ agentId = await this.selectAgentForTask(task);
557
+ if (!agentId) {
558
+ throw new Error('No suitable agent available for task');
559
+ }
560
+ }
561
+ const agent = this.agents.get(agentId);
562
+ if (!agent) {
563
+ throw new Error(`Agent not found: ${agentId}`);
564
+ }
565
+ if (agent.status !== 'idle') {
566
+ throw new Error(`Agent not available: ${agent.status}`);
567
+ }
568
+ // Assign task
569
+ task.assignedTo = agent.id;
570
+ task.assignedAt = new Date();
571
+ task.status = 'assigned';
572
+ agent.currentTask = task.id;
573
+ agent.status = 'busy';
574
+ // Update status history
575
+ task.statusHistory.push({
576
+ timestamp: new Date(),
577
+ from: task.statusHistory[task.statusHistory.length - 1].to,
578
+ to: 'assigned',
579
+ reason: `Assigned to agent ${agent.name}`,
580
+ triggeredBy: 'system'
581
+ });
582
+ this.logger.info('Assigned task', {
583
+ taskId,
584
+ agentId,
585
+ agentName: agent.name
586
+ });
587
+ this.emitSwarmEvent({
588
+ id: generateId('event'),
589
+ timestamp: new Date(),
590
+ type: 'task.assigned',
591
+ source: agentId,
592
+ data: {
593
+ task,
594
+ agent
595
+ },
596
+ broadcast: false,
597
+ processed: false
598
+ });
599
+ // Start task execution
600
+ await this.startTaskExecution(task);
601
+ }
602
+ async startTaskExecution(task) {
603
+ if (!task.assignedTo) {
604
+ throw new Error('Task not assigned to any agent');
605
+ }
606
+ const agent = this.agents.get(task.assignedTo.id);
607
+ if (!agent) {
608
+ throw new Error(`Agent not found: ${task.assignedTo.id}`);
609
+ }
610
+ this.logger.info('Starting task execution', {
611
+ taskId: task.id.id,
612
+ agentId: agent.id.id
613
+ });
614
+ task.status = 'running';
615
+ task.startedAt = new Date();
616
+ // Create attempt record
617
+ const attempt = {
618
+ attemptNumber: task.attempts.length + 1,
619
+ agent: agent.id,
620
+ startedAt: new Date(),
621
+ status: 'running',
622
+ resourcesUsed: {}
623
+ };
624
+ task.attempts.push(attempt);
625
+ // Update status history
626
+ task.statusHistory.push({
627
+ timestamp: new Date(),
628
+ from: 'assigned',
629
+ to: 'running',
630
+ reason: 'Task execution started',
631
+ triggeredBy: agent.id
632
+ });
633
+ this.emitSwarmEvent({
634
+ id: generateId('event'),
635
+ timestamp: new Date(),
636
+ type: 'task.started',
637
+ source: agent.id.id,
638
+ data: {
639
+ task,
640
+ agent,
641
+ attempt
642
+ },
643
+ broadcast: false,
644
+ processed: false
645
+ });
646
+ try {
647
+ // Execute task (this would spawn actual Claude process)
648
+ const result = await this.executeTaskWithAgent(task, agent);
649
+ await this.completeTask(task.id.id, result);
650
+ } catch (error) {
651
+ await this.failTask(task.id.id, error);
652
+ }
653
+ }
654
+ async completeTask(taskId, result) {
655
+ const task = this.tasks.get(taskId);
656
+ if (!task) {
657
+ throw new Error(`Task not found: ${taskId}`);
658
+ }
659
+ const agent = task.assignedTo ? this.agents.get(task.assignedTo.id) : null;
660
+ if (!agent) {
661
+ throw new Error('Task not assigned to any agent');
662
+ }
663
+ this.logger.info('Completing task', {
664
+ taskId,
665
+ agentId: agent.id.id
666
+ });
667
+ task.status = 'completed';
668
+ task.completedAt = new Date();
669
+ task.result = {
670
+ output: result,
671
+ artifacts: {},
672
+ metadata: {},
673
+ quality: this.assessTaskQuality(task, result),
674
+ completeness: 1.0,
675
+ accuracy: 1.0,
676
+ executionTime: task.completedAt.getTime() - (task.startedAt?.getTime() || 0),
677
+ resourcesUsed: {},
678
+ validated: false
679
+ };
680
+ // Update attempt
681
+ const currentAttempt = task.attempts[task.attempts.length - 1];
682
+ if (currentAttempt) {
683
+ currentAttempt.completedAt = new Date();
684
+ currentAttempt.status = 'completed';
685
+ currentAttempt.result = task.result;
686
+ }
687
+ // Update agent state
688
+ agent.status = 'idle';
689
+ agent.currentTask = undefined;
690
+ agent.metrics.tasksCompleted++;
691
+ agent.metrics.lastActivity = new Date();
692
+ agent.taskHistory.push(task.id);
693
+ // Update agent metrics
694
+ this.updateAgentMetrics(agent, task);
695
+ // Update status history
696
+ task.statusHistory.push({
697
+ timestamp: new Date(),
698
+ from: 'running',
699
+ to: 'completed',
700
+ reason: 'Task completed successfully',
701
+ triggeredBy: agent.id
702
+ });
703
+ this.emitSwarmEvent({
704
+ id: generateId('event'),
705
+ timestamp: new Date(),
706
+ type: 'task.completed',
707
+ source: agent.id.id,
708
+ data: {
709
+ task,
710
+ agent,
711
+ result: task.result
712
+ },
713
+ broadcast: false,
714
+ processed: false
715
+ });
716
+ // Check for dependent tasks
717
+ await this.processDependentTasks(task);
718
+ }
719
+ async failTask(taskId, error) {
720
+ const task = this.tasks.get(taskId);
721
+ if (!task) {
722
+ throw new Error(`Task not found: ${taskId}`);
723
+ }
724
+ const agent = task.assignedTo ? this.agents.get(task.assignedTo.id) : null;
725
+ if (!agent) {
726
+ throw new Error('Task not assigned to any agent');
727
+ }
728
+ this.logger.warn('Task failed', {
729
+ taskId,
730
+ agentId: agent.id.id,
731
+ error: error instanceof Error ? error.message : String(error)
732
+ });
733
+ task.error = {
734
+ type: error.constructor.name,
735
+ message: error instanceof Error ? error.message : String(error),
736
+ code: error.code,
737
+ stack: error.stack,
738
+ context: {
739
+ taskId,
740
+ agentId: agent.id.id
741
+ },
742
+ recoverable: this.isRecoverableError(error),
743
+ retryable: this.isRetryableError(error)
744
+ };
745
+ // Update attempt
746
+ const currentAttempt = task.attempts[task.attempts.length - 1];
747
+ if (currentAttempt) {
748
+ currentAttempt.completedAt = new Date();
749
+ currentAttempt.status = 'failed';
750
+ currentAttempt.error = task.error;
751
+ }
752
+ // Update agent state
753
+ agent.status = 'idle';
754
+ agent.currentTask = undefined;
755
+ agent.metrics.tasksFailed++;
756
+ agent.metrics.lastActivity = new Date();
757
+ // Add to error history
758
+ agent.errorHistory.push({
759
+ timestamp: new Date(),
760
+ type: 'task_failure',
761
+ message: error instanceof Error ? error.message : String(error),
762
+ stack: error.stack,
763
+ context: {
764
+ taskId
765
+ },
766
+ severity: 'medium',
767
+ resolved: false
768
+ });
769
+ // Determine if we should retry
770
+ const shouldRetry = task.error.retryable && task.attempts.length < (task.constraints.maxRetries || SWARM_CONSTANTS.MAX_RETRIES);
771
+ if (shouldRetry) {
772
+ task.status = 'retrying';
773
+ task.assignedTo = undefined;
774
+ // Update status history
775
+ task.statusHistory.push({
776
+ timestamp: new Date(),
777
+ from: 'running',
778
+ to: 'retrying',
779
+ reason: `Task failed, will retry: ${error instanceof Error ? error.message : String(error)}`,
780
+ triggeredBy: agent.id
781
+ });
782
+ this.emitSwarmEvent({
783
+ id: generateId('event'),
784
+ timestamp: new Date(),
785
+ type: 'task.retried',
786
+ source: agent.id.id,
787
+ data: {
788
+ task,
789
+ error: task.error,
790
+ attempt: task.attempts.length
791
+ },
792
+ broadcast: false,
793
+ processed: false
794
+ });
795
+ // Schedule retry with exponential backoff
796
+ const retryDelay = Math.pow(2, task.attempts.length) * 1000;
797
+ setTimeout(()=>{
798
+ this.assignTask(taskId).catch((retryError)=>{
799
+ this.logger.error('Failed to retry task', {
800
+ taskId,
801
+ retryError
802
+ });
803
+ });
804
+ }, retryDelay);
805
+ } else {
806
+ task.status = 'failed';
807
+ task.completedAt = new Date();
808
+ // Update status history
809
+ task.statusHistory.push({
810
+ timestamp: new Date(),
811
+ from: 'running',
812
+ to: 'failed',
813
+ reason: `Task failed permanently: ${error instanceof Error ? error.message : String(error)}`,
814
+ triggeredBy: agent.id
815
+ });
816
+ this.emitSwarmEvent({
817
+ id: generateId('event'),
818
+ timestamp: new Date(),
819
+ type: 'task.failed',
820
+ source: agent.id.id,
821
+ data: {
822
+ task,
823
+ error: task.error
824
+ },
825
+ broadcast: false,
826
+ processed: false
827
+ });
828
+ // Handle failure cascade
829
+ await this.handleTaskFailureCascade(task);
830
+ }
831
+ }
832
+ async cancelTask(taskId, reason) {
833
+ const task = this.tasks.get(taskId);
834
+ if (!task) {
835
+ throw new Error(`Task not found: ${taskId}`);
836
+ }
837
+ const agent = task.assignedTo ? this.agents.get(task.assignedTo.id) : null;
838
+ this.logger.info('Cancelling task', {
839
+ taskId,
840
+ reason
841
+ });
842
+ task.status = 'cancelled';
843
+ task.completedAt = new Date();
844
+ if (agent) {
845
+ agent.status = 'idle';
846
+ agent.currentTask = undefined;
847
+ }
848
+ // Update status history
849
+ task.statusHistory.push({
850
+ timestamp: new Date(),
851
+ from: task.statusHistory[task.statusHistory.length - 1].to,
852
+ to: 'cancelled',
853
+ reason: `Task cancelled: ${reason}`,
854
+ triggeredBy: 'system'
855
+ });
856
+ this.emitSwarmEvent({
857
+ id: generateId('event'),
858
+ timestamp: new Date(),
859
+ type: 'task.cancelled',
860
+ source: this.swarmId.id,
861
+ data: {
862
+ task,
863
+ reason
864
+ },
865
+ broadcast: false,
866
+ processed: false
867
+ });
868
+ }
869
+ // ===== ADVANCED FEATURES =====
870
+ async selectAgentForTask(task) {
871
+ const availableAgents = Array.from(this.agents.values()).filter((agent)=>agent.status === 'idle' && this.agentCanHandleTask(agent, task));
872
+ if (availableAgents.length === 0) {
873
+ return null;
874
+ }
875
+ // Score agents based on multiple criteria
876
+ const scoredAgents = availableAgents.map((agent)=>({
877
+ agent,
878
+ score: this.calculateAgentScore(agent, task)
879
+ }));
880
+ // Sort by score (highest first)
881
+ scoredAgents.sort((a, b)=>b.score - a.score);
882
+ return scoredAgents[0].agent.id.id;
883
+ }
884
+ calculateAgentScore(agent, task) {
885
+ let score = 0;
886
+ // Capability match (40% weight)
887
+ const capabilityMatch = this.calculateCapabilityMatch(agent, task);
888
+ score += capabilityMatch * 0.4;
889
+ // Performance history (30% weight)
890
+ const performanceScore = agent.metrics.successRate * agent.capabilities.reliability;
891
+ score += performanceScore * 0.3;
892
+ // Current workload (20% weight)
893
+ const workloadScore = 1 - agent.workload;
894
+ score += workloadScore * 0.2;
895
+ // Quality rating (10% weight)
896
+ score += agent.capabilities.quality * 0.1;
897
+ return score;
898
+ }
899
+ calculateCapabilityMatch(agent, task) {
900
+ const requiredCapabilities = task.requirements.capabilities;
901
+ let matches = 0;
902
+ let total = requiredCapabilities.length;
903
+ for (const capability of requiredCapabilities){
904
+ if (this.agentHasCapability(agent, capability)) {
905
+ matches++;
906
+ }
907
+ }
908
+ return total > 0 ? matches / total : 1.0;
909
+ }
910
+ agentHasCapability(agent, capability) {
911
+ const caps = agent.capabilities;
912
+ switch(capability){
913
+ case 'code-generation':
914
+ return caps.codeGeneration;
915
+ case 'code-review':
916
+ return caps.codeReview;
917
+ case 'testing':
918
+ return caps.testing;
919
+ case 'documentation':
920
+ return caps.documentation;
921
+ case 'research':
922
+ return caps.research;
923
+ case 'analysis':
924
+ return caps.analysis;
925
+ case 'web-search':
926
+ return caps.webSearch;
927
+ case 'api-integration':
928
+ return caps.apiIntegration;
929
+ case 'file-system':
930
+ return caps.fileSystem;
931
+ case 'terminal-access':
932
+ return caps.terminalAccess;
933
+ case 'validation':
934
+ return caps.testing; // Validation is part of testing capability
935
+ default:
936
+ return caps.domains.includes(capability) || caps.languages.includes(capability) || caps.frameworks.includes(capability) || caps.tools.includes(capability);
937
+ }
938
+ }
939
+ agentCanHandleTask(agent, task) {
940
+ // Check if agent type is suitable
941
+ if (task.requirements.agentType && agent.type !== task.requirements.agentType) {
942
+ return false;
943
+ }
944
+ // Check if agent has required capabilities
945
+ for (const capability of task.requirements.capabilities){
946
+ if (!this.agentHasCapability(agent, capability)) {
947
+ return false;
948
+ }
949
+ }
950
+ // Check reliability requirement
951
+ if (task.requirements.minReliability && agent.capabilities.reliability < task.requirements.minReliability) {
952
+ return false;
953
+ }
954
+ // Check if agent has capacity
955
+ if (agent.workload >= 1.0) {
956
+ return false;
957
+ }
958
+ return true;
959
+ }
960
+ // ===== HELPER METHODS =====
961
+ generateSwarmId() {
962
+ return {
963
+ id: generateId('swarm'),
964
+ timestamp: Date.now(),
965
+ namespace: 'default'
966
+ };
967
+ }
968
+ mergeWithDefaults(config) {
969
+ return {
970
+ name: 'Unnamed Swarm',
971
+ description: 'Auto-generated swarm',
972
+ version: '1.0.0',
973
+ mode: 'centralized',
974
+ strategy: 'auto',
975
+ coordinationStrategy: {
976
+ name: 'default',
977
+ description: 'Default coordination strategy',
978
+ agentSelection: 'capability-based',
979
+ taskScheduling: 'priority',
980
+ loadBalancing: 'work-stealing',
981
+ faultTolerance: 'retry',
982
+ communication: 'event-driven'
983
+ },
984
+ maxAgents: 10,
985
+ maxTasks: 100,
986
+ maxDuration: 4 * 60 * 60 * 1000,
987
+ resourceLimits: {
988
+ memory: SWARM_CONSTANTS.DEFAULT_MEMORY_LIMIT,
989
+ cpu: SWARM_CONSTANTS.DEFAULT_CPU_LIMIT,
990
+ disk: SWARM_CONSTANTS.DEFAULT_DISK_LIMIT
991
+ },
992
+ qualityThreshold: SWARM_CONSTANTS.DEFAULT_QUALITY_THRESHOLD,
993
+ reviewRequired: true,
994
+ testingRequired: true,
995
+ monitoring: {
996
+ metricsEnabled: true,
997
+ loggingEnabled: true,
998
+ tracingEnabled: false,
999
+ metricsInterval: 10000,
1000
+ heartbeatInterval: SWARM_CONSTANTS.DEFAULT_HEARTBEAT_INTERVAL,
1001
+ healthCheckInterval: 30000,
1002
+ retentionPeriod: 24 * 60 * 60 * 1000,
1003
+ maxLogSize: 100 * 1024 * 1024,
1004
+ maxMetricPoints: 10000,
1005
+ alertingEnabled: true,
1006
+ alertThresholds: {
1007
+ errorRate: 0.1,
1008
+ responseTime: 5000,
1009
+ memoryUsage: 0.8,
1010
+ cpuUsage: 0.8
1011
+ },
1012
+ exportEnabled: false,
1013
+ exportFormat: 'json',
1014
+ exportDestination: '/tmp/swarm-metrics'
1015
+ },
1016
+ memory: {
1017
+ namespace: 'default',
1018
+ partitions: [],
1019
+ permissions: {
1020
+ read: 'swarm',
1021
+ write: 'team',
1022
+ delete: 'private',
1023
+ share: 'team'
1024
+ },
1025
+ persistent: true,
1026
+ backupEnabled: true,
1027
+ distributed: false,
1028
+ consistency: 'eventual',
1029
+ cacheEnabled: true,
1030
+ compressionEnabled: false
1031
+ },
1032
+ security: {
1033
+ authenticationRequired: false,
1034
+ authorizationRequired: false,
1035
+ encryptionEnabled: false,
1036
+ defaultPermissions: [
1037
+ 'read',
1038
+ 'write'
1039
+ ],
1040
+ adminRoles: [
1041
+ 'admin',
1042
+ 'coordinator'
1043
+ ],
1044
+ auditEnabled: true,
1045
+ auditLevel: 'info',
1046
+ inputValidation: true,
1047
+ outputSanitization: true
1048
+ },
1049
+ performance: {
1050
+ maxConcurrency: 10,
1051
+ defaultTimeout: SWARM_CONSTANTS.DEFAULT_TASK_TIMEOUT,
1052
+ cacheEnabled: true,
1053
+ cacheSize: 100,
1054
+ cacheTtl: 3600000,
1055
+ optimizationEnabled: true,
1056
+ adaptiveScheduling: true,
1057
+ predictiveLoading: false,
1058
+ resourcePooling: true,
1059
+ connectionPooling: true,
1060
+ memoryPooling: false
1061
+ },
1062
+ ...config
1063
+ };
1064
+ }
1065
+ initializeMetrics() {
1066
+ return {
1067
+ throughput: 0,
1068
+ latency: 0,
1069
+ efficiency: 0,
1070
+ reliability: 0,
1071
+ averageQuality: 0,
1072
+ defectRate: 0,
1073
+ reworkRate: 0,
1074
+ resourceUtilization: {},
1075
+ costEfficiency: 0,
1076
+ agentUtilization: 0,
1077
+ agentSatisfaction: 0,
1078
+ collaborationEffectiveness: 0,
1079
+ scheduleVariance: 0,
1080
+ deadlineAdherence: 0
1081
+ };
1082
+ }
1083
+ initializeProgress() {
1084
+ return {
1085
+ totalTasks: 0,
1086
+ completedTasks: 0,
1087
+ failedTasks: 0,
1088
+ runningTasks: 0,
1089
+ estimatedCompletion: new Date(),
1090
+ timeRemaining: 0,
1091
+ percentComplete: 0,
1092
+ averageQuality: 0,
1093
+ passedReviews: 0,
1094
+ passedTests: 0,
1095
+ resourceUtilization: {},
1096
+ costSpent: 0,
1097
+ activeAgents: 0,
1098
+ idleAgents: 0,
1099
+ busyAgents: 0
1100
+ };
1101
+ }
1102
+ // ===== EVENT HANDLING =====
1103
+ setupEventHandlers() {
1104
+ // Handle agent heartbeats
1105
+ this.on('agent.heartbeat', (data)=>{
1106
+ const agent = this.agents.get(data.agentId);
1107
+ if (agent) {
1108
+ agent.lastHeartbeat = new Date();
1109
+ agent.health = data.health || 1.0;
1110
+ agent.metrics = {
1111
+ ...agent.metrics,
1112
+ ...data.metrics
1113
+ };
1114
+ }
1115
+ });
1116
+ // Handle task completion events
1117
+ this.on('task.completed', (data)=>{
1118
+ this.updateSwarmMetrics();
1119
+ this.checkObjectiveCompletion();
1120
+ });
1121
+ // Handle task failure events
1122
+ this.on('task.failed', (data)=>{
1123
+ this.updateSwarmMetrics();
1124
+ this.checkObjectiveFailure(data.task);
1125
+ });
1126
+ // Handle agent errors
1127
+ this.on('agent.error', (data)=>{
1128
+ this.handleAgentError(data.agentId, data.error);
1129
+ });
1130
+ }
1131
+ // ===== SWARM EVENT EMITTER IMPLEMENTATION =====
1132
+ emitSwarmEvent(event) {
1133
+ this.events.push(event);
1134
+ // Limit event history
1135
+ if (this.events.length > 1000) {
1136
+ this.events = this.events.slice(-500);
1137
+ }
1138
+ return this.emit(event.type, event);
1139
+ }
1140
+ emitSwarmEvents(events) {
1141
+ let success = true;
1142
+ for (const event of events){
1143
+ if (!this.emitSwarmEvent(event)) {
1144
+ success = false;
1145
+ }
1146
+ }
1147
+ return success;
1148
+ }
1149
+ onSwarmEvent(type, handler) {
1150
+ return this.on(type, handler);
1151
+ }
1152
+ offSwarmEvent(type, handler) {
1153
+ return this.off(type, handler);
1154
+ }
1155
+ filterEvents(predicate) {
1156
+ return this.events.filter(predicate);
1157
+ }
1158
+ correlateEvents(correlationId) {
1159
+ return this.events.filter((event)=>event.correlationId === correlationId);
1160
+ }
1161
+ // ===== PUBLIC API METHODS =====
1162
+ getSwarmId() {
1163
+ return this.swarmId;
1164
+ }
1165
+ getStatus() {
1166
+ return this.status;
1167
+ }
1168
+ getAgents() {
1169
+ return Array.from(this.agents.values());
1170
+ }
1171
+ getAgent(agentId) {
1172
+ return this.agents.get(agentId);
1173
+ }
1174
+ getTasks() {
1175
+ return Array.from(this.tasks.values());
1176
+ }
1177
+ getTask(taskId) {
1178
+ return this.tasks.get(taskId);
1179
+ }
1180
+ getObjectives() {
1181
+ return Array.from(this.objectives.values());
1182
+ }
1183
+ getObjective(objectiveId) {
1184
+ return this.objectives.get(objectiveId);
1185
+ }
1186
+ getMetrics() {
1187
+ return {
1188
+ ...this.metrics
1189
+ };
1190
+ }
1191
+ getEvents() {
1192
+ return [
1193
+ ...this.events
1194
+ ];
1195
+ }
1196
+ isRunning() {
1197
+ return this._isRunning;
1198
+ }
1199
+ getUptime() {
1200
+ if (!this.startTime) return 0;
1201
+ const endTime = this.endTime || new Date();
1202
+ return endTime.getTime() - this.startTime.getTime();
1203
+ }
1204
+ getSwarmStatus() {
1205
+ const tasks = Array.from(this.tasks.values());
1206
+ const completedTasks = tasks.filter((t)=>t.status === 'completed').length;
1207
+ const failedTasks = tasks.filter((t)=>t.status === 'failed').length;
1208
+ return {
1209
+ status: this.status,
1210
+ objectives: this.objectives.size,
1211
+ tasks: {
1212
+ completed: completedTasks,
1213
+ failed: failedTasks,
1214
+ total: tasks.length
1215
+ },
1216
+ agents: {
1217
+ total: this.agents.size
1218
+ }
1219
+ };
1220
+ }
1221
+ // ===== STUB METHODS (TO BE IMPLEMENTED) =====
1222
+ async validateConfiguration() {
1223
+ // Implementation needed
1224
+ return {
1225
+ valid: true,
1226
+ errors: [],
1227
+ warnings: [],
1228
+ validatedAt: new Date(),
1229
+ validator: 'SwarmCoordinator',
1230
+ context: {}
1231
+ };
1232
+ }
1233
+ async initializeSubsystems() {
1234
+ // Implementation needed
1235
+ }
1236
+ startBackgroundProcesses() {
1237
+ // Start heartbeat monitoring
1238
+ this.heartbeatTimer = setInterval(()=>{
1239
+ this.processHeartbeats();
1240
+ }, this.config.monitoring.heartbeatInterval);
1241
+ // Start performance monitoring
1242
+ this.monitoringTimer = setInterval(()=>{
1243
+ this.updateSwarmMetrics();
1244
+ }, this.config.monitoring.metricsInterval);
1245
+ // Start cleanup process
1246
+ this.cleanupTimer = setInterval(()=>{
1247
+ this.performCleanup();
1248
+ }, 60000); // Every minute
1249
+ }
1250
+ stopBackgroundProcesses() {
1251
+ if (this.heartbeatTimer) {
1252
+ clearInterval(this.heartbeatTimer);
1253
+ this.heartbeatTimer = undefined;
1254
+ }
1255
+ if (this.monitoringTimer) {
1256
+ clearInterval(this.monitoringTimer);
1257
+ this.monitoringTimer = undefined;
1258
+ }
1259
+ if (this.cleanupTimer) {
1260
+ clearInterval(this.cleanupTimer);
1261
+ this.cleanupTimer = undefined;
1262
+ }
1263
+ // Stop all execution intervals
1264
+ if (this.executionIntervals) {
1265
+ for (const [objectiveId, interval] of this.executionIntervals){
1266
+ clearInterval(interval);
1267
+ }
1268
+ this.executionIntervals.clear();
1269
+ }
1270
+ }
1271
+ async stopAllAgents() {
1272
+ const stopPromises = Array.from(this.agents.keys()).map((agentId)=>this.stopAgent(agentId));
1273
+ await Promise.allSettled(stopPromises);
1274
+ }
1275
+ async completeRunningTasks() {
1276
+ const runningTasks = Array.from(this.tasks.values()).filter((task)=>task.status === 'running');
1277
+ // Wait for tasks to complete or timeout
1278
+ const timeout = 30000; // 30 seconds
1279
+ const deadline = Date.now() + timeout;
1280
+ while(runningTasks.some((task)=>task.status === 'running') && Date.now() < deadline){
1281
+ await new Promise((resolve)=>setTimeout(resolve, 1000));
1282
+ }
1283
+ // Cancel any remaining running tasks
1284
+ for (const task of runningTasks){
1285
+ if (task.status === 'running') {
1286
+ await this.cancelTask(task.id.id, 'Swarm shutdown');
1287
+ }
1288
+ }
1289
+ }
1290
+ async saveState() {
1291
+ // Implementation needed - save swarm state to persistence layer
1292
+ }
1293
+ determineRequiredAgentTypes(strategy) {
1294
+ switch(strategy){
1295
+ case 'research':
1296
+ return [
1297
+ 'researcher',
1298
+ 'analyst'
1299
+ ];
1300
+ case 'development':
1301
+ return [
1302
+ 'coder',
1303
+ 'tester',
1304
+ 'reviewer'
1305
+ ];
1306
+ case 'analysis':
1307
+ return [
1308
+ 'analyst',
1309
+ 'researcher'
1310
+ ];
1311
+ case 'testing':
1312
+ return [
1313
+ 'tester',
1314
+ 'coder'
1315
+ ];
1316
+ case 'optimization':
1317
+ return [
1318
+ 'analyst',
1319
+ 'coder'
1320
+ ];
1321
+ case 'maintenance':
1322
+ return [
1323
+ 'coder',
1324
+ 'monitor'
1325
+ ];
1326
+ default:
1327
+ return [
1328
+ 'coordinator',
1329
+ 'coder',
1330
+ 'analyst'
1331
+ ];
1332
+ }
1333
+ }
1334
+ getAgentTypeInstructions(agentType) {
1335
+ switch(agentType){
1336
+ case 'coder':
1337
+ return '- Focus on implementation, code quality, and best practices\n- Create clean, maintainable code\n- Consider architecture and design patterns';
1338
+ case 'tester':
1339
+ return '- Focus on testing, edge cases, and quality assurance\n- Create comprehensive test suites\n- Identify potential bugs and issues';
1340
+ case 'analyst':
1341
+ return '- Focus on analysis, research, and understanding\n- Break down complex problems\n- Provide insights and recommendations';
1342
+ case 'researcher':
1343
+ return '- Focus on gathering information and best practices\n- Research existing solutions and patterns\n- Document findings and recommendations';
1344
+ case 'reviewer':
1345
+ return '- Focus on code review and quality checks\n- Identify improvements and optimizations\n- Ensure standards compliance';
1346
+ case 'coordinator':
1347
+ return '- Focus on coordination and integration\n- Ensure all parts work together\n- Manage dependencies and interfaces';
1348
+ case 'monitor':
1349
+ return '- Focus on monitoring and observability\n- Set up logging and metrics\n- Ensure system health tracking';
1350
+ default:
1351
+ return '- Execute the task to the best of your ability\n- Follow best practices for your domain';
1352
+ }
1353
+ }
1354
+ getAgentCapabilities(agentType) {
1355
+ switch(agentType){
1356
+ case 'coder':
1357
+ return [
1358
+ 'code-generation',
1359
+ 'file-system',
1360
+ 'debugging'
1361
+ ];
1362
+ case 'tester':
1363
+ return [
1364
+ 'testing',
1365
+ 'code-generation',
1366
+ 'analysis'
1367
+ ];
1368
+ case 'analyst':
1369
+ return [
1370
+ 'analysis',
1371
+ 'documentation',
1372
+ 'research'
1373
+ ];
1374
+ case 'researcher':
1375
+ return [
1376
+ 'research',
1377
+ 'documentation',
1378
+ 'analysis'
1379
+ ];
1380
+ case 'reviewer':
1381
+ return [
1382
+ 'code-review',
1383
+ 'analysis',
1384
+ 'documentation'
1385
+ ];
1386
+ case 'coordinator':
1387
+ return [
1388
+ 'coordination',
1389
+ 'analysis',
1390
+ 'documentation'
1391
+ ];
1392
+ case 'monitor':
1393
+ return [
1394
+ 'monitoring',
1395
+ 'analysis',
1396
+ 'documentation'
1397
+ ];
1398
+ default:
1399
+ return [
1400
+ 'analysis',
1401
+ 'documentation'
1402
+ ];
1403
+ }
1404
+ }
1405
+ async decomposeObjective(objective) {
1406
+ // Decompose objective into tasks with clear instructions for Claude
1407
+ this.logger.info('Decomposing objective', {
1408
+ objectiveId: objective.id,
1409
+ description: objective.description
1410
+ });
1411
+ const tasks = [];
1412
+ // Extract target directory from objective
1413
+ const targetDirMatch = objective.description.match(/(?:in|to|at)\s+([^\s]+\/[^\s]+)|([^\s]+\/[^\s]+)$/);
1414
+ const targetDir = targetDirMatch ? targetDirMatch[1] || targetDirMatch[2] : null;
1415
+ const targetPath = targetDir ? targetDir.startsWith('/') ? targetDir : `${getClaudeFlowRoot()}/${targetDir}` : null;
1416
+ // Check if objective requests "each agent" or "each agent type" for parallel execution
1417
+ const eachAgentPattern = /\beach\s+agent(?:\s+type)?\b/i;
1418
+ const requestsParallelAgents = eachAgentPattern.test(objective.description);
1419
+ // Create tasks with specific prompts for Claude
1420
+ if (requestsParallelAgents && this.config.mode === 'parallel') {
1421
+ // Create parallel tasks for each agent type
1422
+ const agentTypes = this.determineRequiredAgentTypes(objective.strategy);
1423
+ this.logger.info('Creating parallel tasks for each agent type', {
1424
+ agentTypes,
1425
+ mode: this.config.mode
1426
+ });
1427
+ for (const agentType of agentTypes){
1428
+ const taskId = this.createTaskForObjective(`${agentType}-task`, agentType, {
1429
+ title: `${agentType.charAt(0).toUpperCase() + agentType.slice(1)} Agent Task`,
1430
+ description: `${agentType} agent executing: ${objective.description}`,
1431
+ instructions: `You are a ${agentType} agent. Please execute the following task from your perspective:
1432
+
1433
+ ${objective.description}
1434
+
1435
+ ${targetPath ? `Target Directory: ${targetPath}` : ''}
1436
+
1437
+ As a ${agentType} agent, focus on aspects relevant to your role:
1438
+ ${this.getAgentTypeInstructions(agentType)}
1439
+
1440
+ Work independently but be aware that other agents are working on this same objective from their perspectives.`,
1441
+ priority: 'high',
1442
+ estimatedDuration: 10 * 60 * 1000,
1443
+ requiredCapabilities: this.getAgentCapabilities(agentType)
1444
+ });
1445
+ tasks.push(taskId);
1446
+ }
1447
+ } else if (objective.strategy === 'development') {
1448
+ // Task 1: Analyze and Plan
1449
+ const task1 = this.createTaskForObjective('analyze-requirements', 'analysis', {
1450
+ title: 'Analyze Requirements and Plan Implementation',
1451
+ description: `Analyze the requirements and create a plan for: ${objective.description}`,
1452
+ instructions: `Please analyze the following request and create a detailed implementation plan:
1453
+
1454
+ Request: ${objective.description}
1455
+
1456
+ Target Directory: ${targetPath || 'Not specified - determine appropriate location'}
1457
+
1458
+ Your analysis should include:
1459
+ 1. Understanding of what needs to be built
1460
+ 2. Technology choices and rationale
1461
+ 3. Project structure and file organization
1462
+ 4. Key components and their responsibilities
1463
+ 5. Any external dependencies needed
1464
+
1465
+ Please provide a clear, structured plan that the next tasks can follow.`,
1466
+ priority: 'high',
1467
+ estimatedDuration: 5 * 60 * 1000,
1468
+ requiredCapabilities: [
1469
+ 'analysis',
1470
+ 'documentation'
1471
+ ]
1472
+ });
1473
+ tasks.push(task1);
1474
+ // Task 2: Implementation
1475
+ const task2 = this.createTaskForObjective('create-implementation', 'coding', {
1476
+ title: 'Implement the Solution',
1477
+ description: `Create the implementation for: ${objective.description}`,
1478
+ instructions: `Please implement the following request:
1479
+
1480
+ Request: ${objective.description}
1481
+
1482
+ Target Directory: ${targetPath || 'Create in an appropriate location'}
1483
+
1484
+ Based on the analysis from the previous task, please:
1485
+ 1. Create all necessary files and directories
1486
+ 2. Implement the core functionality as requested
1487
+ 3. Ensure the code is well-structured and follows best practices
1488
+ 4. Include appropriate error handling
1489
+ 5. Add any necessary configuration files (package.json, requirements.txt, etc.)
1490
+
1491
+ Focus on creating a working implementation that matches the user's request exactly.`,
1492
+ priority: 'high',
1493
+ estimatedDuration: 10 * 60 * 1000,
1494
+ requiredCapabilities: [
1495
+ 'code-generation',
1496
+ 'file-system'
1497
+ ],
1498
+ dependencies: [
1499
+ task1.id.id
1500
+ ]
1501
+ });
1502
+ tasks.push(task2);
1503
+ // Task 3: Testing
1504
+ const task3 = this.createTaskForObjective('write-tests', 'testing', {
1505
+ title: 'Create Tests',
1506
+ description: `Write tests for the implementation`,
1507
+ instructions: `Please create comprehensive tests for the implementation created in the previous task.
1508
+
1509
+ Target Directory: ${targetPath || 'Use the same directory as the implementation'}
1510
+
1511
+ Create appropriate test files that:
1512
+ 1. Test the main functionality
1513
+ 2. Cover edge cases
1514
+ 3. Ensure the implementation works as expected
1515
+ 4. Use appropriate testing frameworks for the technology stack
1516
+ 5. Include both unit tests and integration tests where applicable`,
1517
+ priority: 'medium',
1518
+ estimatedDuration: 5 * 60 * 1000,
1519
+ requiredCapabilities: [
1520
+ 'testing',
1521
+ 'code-generation'
1522
+ ],
1523
+ dependencies: [
1524
+ task2.id.id
1525
+ ]
1526
+ });
1527
+ tasks.push(task3);
1528
+ // Task 4: Documentation
1529
+ const task4 = this.createTaskForObjective('create-documentation', 'documentation', {
1530
+ title: 'Create Documentation',
1531
+ description: `Document the implementation`,
1532
+ instructions: `Please create comprehensive documentation for the implemented solution.
1533
+
1534
+ Target Directory: ${targetPath || 'Use the same directory as the implementation'}
1535
+
1536
+ Create documentation that includes:
1537
+ 1. README.md with project overview, setup instructions, and usage examples
1538
+ 2. API documentation (if applicable)
1539
+ 3. Configuration options
1540
+ 4. Architecture overview
1541
+ 5. Deployment instructions (if applicable)
1542
+ 6. Any other relevant documentation
1543
+
1544
+ Make sure the documentation is clear, complete, and helps users understand and use the implementation.`,
1545
+ priority: 'medium',
1546
+ estimatedDuration: 5 * 60 * 1000,
1547
+ requiredCapabilities: [
1548
+ 'documentation'
1549
+ ],
1550
+ dependencies: [
1551
+ task2.id.id
1552
+ ]
1553
+ });
1554
+ tasks.push(task4);
1555
+ } else {
1556
+ // For other strategies, create a comprehensive single task
1557
+ tasks.push(this.createTaskForObjective('execute-objective', 'generic', {
1558
+ title: 'Execute Objective',
1559
+ description: objective.description,
1560
+ instructions: `Please complete the following request:
1561
+
1562
+ ${objective.description}
1563
+
1564
+ ${targetPath ? `Target Directory: ${targetPath}` : ''}
1565
+
1566
+ Please analyze what is being requested and implement it appropriately. This may involve:
1567
+ - Creating files and directories
1568
+ - Writing code
1569
+ - Setting up configurations
1570
+ - Creating documentation
1571
+ - Any other tasks necessary to fulfill the request
1572
+
1573
+ Ensure your implementation is complete, well-structured, and follows best practices.`,
1574
+ priority: 'high',
1575
+ estimatedDuration: 15 * 60 * 1000,
1576
+ requiredCapabilities: [
1577
+ 'code-generation',
1578
+ 'file-system',
1579
+ 'documentation'
1580
+ ]
1581
+ }));
1582
+ }
1583
+ this.logger.info('Objective decomposed', {
1584
+ objectiveId: objective.id,
1585
+ taskCount: tasks.length
1586
+ });
1587
+ return tasks;
1588
+ }
1589
+ createTaskForObjective(id, type, params) {
1590
+ const taskId = {
1591
+ id: generateId('task'),
1592
+ swarmId: this.swarmId.id,
1593
+ sequence: this.tasks.size + 1,
1594
+ priority: 1
1595
+ };
1596
+ return {
1597
+ id: taskId,
1598
+ type,
1599
+ name: params.title,
1600
+ description: params.description,
1601
+ instructions: params.description,
1602
+ requirements: {
1603
+ capabilities: params.requiredCapabilities || [],
1604
+ tools: this.getRequiredTools(type),
1605
+ permissions: this.getRequiredPermissions(type)
1606
+ },
1607
+ constraints: {
1608
+ dependencies: params.dependencies || [],
1609
+ dependents: [],
1610
+ conflicts: [],
1611
+ maxRetries: SWARM_CONSTANTS.MAX_RETRIES,
1612
+ timeoutAfter: params.estimatedDuration || SWARM_CONSTANTS.DEFAULT_TASK_TIMEOUT
1613
+ },
1614
+ priority: params.priority || 'medium',
1615
+ input: {
1616
+ description: params.description,
1617
+ objective: params.description
1618
+ },
1619
+ context: {
1620
+ objectiveId: id,
1621
+ targetDir: params.targetDir
1622
+ },
1623
+ examples: [],
1624
+ status: 'created',
1625
+ createdAt: new Date(),
1626
+ updatedAt: new Date(),
1627
+ attempts: [],
1628
+ statusHistory: [
1629
+ {
1630
+ timestamp: new Date(),
1631
+ from: 'created',
1632
+ to: 'created',
1633
+ reason: 'Task created',
1634
+ triggeredBy: 'system'
1635
+ }
1636
+ ]
1637
+ };
1638
+ }
1639
+ analyzeDependencies(tasks) {
1640
+ // Implementation needed - analyze task dependencies
1641
+ return [];
1642
+ }
1643
+ convertDependenciesToTaskDependencies(dependencies) {
1644
+ // Convert decomposition dependencies to task dependencies format
1645
+ const result = [];
1646
+ dependencies.forEach((deps, taskId)=>{
1647
+ deps.forEach((dependsOn)=>{
1648
+ result.push({
1649
+ taskId,
1650
+ dependsOn,
1651
+ type: 'sequential'
1652
+ });
1653
+ });
1654
+ });
1655
+ return result;
1656
+ }
1657
+ async ensureRequiredAgents(objective) {
1658
+ // Implementation needed - ensure required agents are available
1659
+ }
1660
+ async scheduleInitialTasks(objective) {
1661
+ this.logger.info('Scheduling initial tasks for objective', {
1662
+ objectiveId: objective.id,
1663
+ taskCount: objective.tasks.length
1664
+ });
1665
+ // Extract target directory from objective description
1666
+ const targetDirPatterns = [
1667
+ /in\s+([^\s]+\/?)$/i,
1668
+ /(?:in|to|at)\s+([^\s]+\/[^\s]+)/i,
1669
+ /([^\s]+\/[^\s]+)$/,
1670
+ /examples\/[^\s]+/i
1671
+ ];
1672
+ let objectiveTargetDir = null;
1673
+ for (const pattern of targetDirPatterns){
1674
+ const match = objective.description.match(pattern);
1675
+ if (match) {
1676
+ objectiveTargetDir = match[1] || match[0];
1677
+ break;
1678
+ }
1679
+ }
1680
+ // Add all tasks to the tasks map
1681
+ for (const task of objective.tasks){
1682
+ task.context.objectiveId = objective.id;
1683
+ // Propagate target directory to all tasks
1684
+ if (objectiveTargetDir && !task.context.targetDir) {
1685
+ task.context.targetDir = objectiveTargetDir;
1686
+ }
1687
+ this.tasks.set(task.id.id, task);
1688
+ // Track task in JSON output if enabled
1689
+ this.trackTaskInJsonOutput(task);
1690
+ }
1691
+ // Find tasks with no dependencies and queue them
1692
+ const initialTasks = objective.tasks.filter((task)=>!task.constraints.dependencies || task.constraints.dependencies.length === 0);
1693
+ this.logger.info('Found initial tasks without dependencies', {
1694
+ count: initialTasks.length,
1695
+ tasks: initialTasks.map((t)=>({
1696
+ id: t.id.id,
1697
+ name: t.name
1698
+ }))
1699
+ });
1700
+ // Queue initial tasks for execution
1701
+ for (const task of initialTasks){
1702
+ task.status = 'queued';
1703
+ task.updatedAt = new Date();
1704
+ // Update status history
1705
+ task.statusHistory.push({
1706
+ timestamp: new Date(),
1707
+ from: 'created',
1708
+ to: 'queued',
1709
+ reason: 'Task queued for execution',
1710
+ triggeredBy: 'system'
1711
+ });
1712
+ // Emit task queued event
1713
+ this.emitSwarmEvent({
1714
+ id: generateId('event'),
1715
+ timestamp: new Date(),
1716
+ type: 'task.queued',
1717
+ source: this.swarmId.id,
1718
+ data: {
1719
+ task
1720
+ },
1721
+ broadcast: false,
1722
+ processed: false
1723
+ });
1724
+ }
1725
+ // Update objective progress
1726
+ objective.progress.totalTasks = objective.tasks.length;
1727
+ objective.progress.runningTasks = 0;
1728
+ objective.progress.completedTasks = 0;
1729
+ objective.progress.failedTasks = 0;
1730
+ }
1731
+ startTaskExecutionLoop(objective) {
1732
+ this.logger.info('Starting task execution loop for objective', {
1733
+ objectiveId: objective.id
1734
+ });
1735
+ // Create an interval to process queued tasks
1736
+ const executionInterval = setInterval(async ()=>{
1737
+ try {
1738
+ // Check if objective is still executing
1739
+ if (objective.status !== 'executing') {
1740
+ clearInterval(executionInterval);
1741
+ return;
1742
+ }
1743
+ // Find queued tasks
1744
+ const queuedTasks = Array.from(this.tasks.values()).filter((task)=>task.context?.objectiveId === objective.id && task.status === 'queued');
1745
+ // Find idle agents
1746
+ const idleAgents = Array.from(this.agents.values()).filter((agent)=>agent.status === 'idle');
1747
+ if (queuedTasks.length > 0 && idleAgents.length > 0) {
1748
+ this.logger.debug('Processing queued tasks', {
1749
+ queuedTasks: queuedTasks.length,
1750
+ idleAgents: idleAgents.length
1751
+ });
1752
+ }
1753
+ // Assign tasks to idle agents
1754
+ for (const task of queuedTasks){
1755
+ if (idleAgents.length === 0) break;
1756
+ // Find suitable agent
1757
+ const suitableAgents = idleAgents.filter((agent)=>this.agentCanHandleTask(agent, task));
1758
+ if (suitableAgents.length > 0) {
1759
+ // Assign to first suitable agent
1760
+ await this.assignTask(task.id.id, suitableAgents[0].id.id);
1761
+ // Remove agent from idle list
1762
+ const agentIndex = idleAgents.findIndex((a)=>a.id.id === suitableAgents[0].id.id);
1763
+ if (agentIndex >= 0) {
1764
+ idleAgents.splice(agentIndex, 1);
1765
+ }
1766
+ }
1767
+ }
1768
+ // Check for completed tasks and process dependencies
1769
+ const completedTasks = Array.from(this.tasks.values()).filter((task)=>task.context?.objectiveId === objective.id && task.status === 'completed');
1770
+ // Find tasks that can now be queued (dependencies met)
1771
+ const pendingTasks = Array.from(this.tasks.values()).filter((task)=>task.context?.objectiveId === objective.id && task.status === 'created' && this.taskDependenciesMet(task, completedTasks));
1772
+ // Queue tasks with met dependencies
1773
+ for (const task of pendingTasks){
1774
+ task.status = 'queued';
1775
+ task.updatedAt = new Date();
1776
+ task.statusHistory.push({
1777
+ timestamp: new Date(),
1778
+ from: 'created',
1779
+ to: 'queued',
1780
+ reason: 'Dependencies met, task queued',
1781
+ triggeredBy: 'system'
1782
+ });
1783
+ this.emitSwarmEvent({
1784
+ id: generateId('event'),
1785
+ timestamp: new Date(),
1786
+ type: 'task.queued',
1787
+ source: this.swarmId.id,
1788
+ data: {
1789
+ task
1790
+ },
1791
+ broadcast: false,
1792
+ processed: false
1793
+ });
1794
+ }
1795
+ // Check for stuck/timed out tasks
1796
+ const runningTasks = Array.from(this.tasks.values()).filter((task)=>task.context?.objectiveId === objective.id && task.status === 'running');
1797
+ const now = Date.now();
1798
+ for (const task of runningTasks){
1799
+ if (task.startedAt) {
1800
+ const runtime = now - task.startedAt.getTime();
1801
+ const timeout = task.constraints?.timeoutAfter || SWARM_CONSTANTS.DEFAULT_TASK_TIMEOUT;
1802
+ if (runtime > timeout) {
1803
+ this.logger.warn('Task timed out', {
1804
+ taskId: task.id.id,
1805
+ runtime: Math.round(runtime / 1000),
1806
+ timeout: Math.round(timeout / 1000)
1807
+ });
1808
+ // Mark task as failed due to timeout
1809
+ task.status = 'failed';
1810
+ task.completedAt = new Date();
1811
+ task.error = {
1812
+ type: 'TimeoutError',
1813
+ message: `Task exceeded timeout of ${timeout}ms`,
1814
+ code: 'TASK_TIMEOUT',
1815
+ context: {
1816
+ taskId: task.id.id,
1817
+ runtime
1818
+ },
1819
+ recoverable: true,
1820
+ retryable: true
1821
+ };
1822
+ // Update agent state if assigned
1823
+ if (task.assignedTo) {
1824
+ const agent = this.agents.get(task.assignedTo.id);
1825
+ if (agent) {
1826
+ agent.status = 'idle';
1827
+ agent.currentTask = undefined;
1828
+ agent.metrics.tasksFailed++;
1829
+ }
1830
+ }
1831
+ // Emit timeout event
1832
+ this.emitSwarmEvent({
1833
+ id: generateId('event'),
1834
+ timestamp: new Date(),
1835
+ type: 'task.failed',
1836
+ source: this.swarmId.id,
1837
+ data: {
1838
+ task,
1839
+ reason: 'timeout'
1840
+ },
1841
+ broadcast: false,
1842
+ processed: false
1843
+ });
1844
+ }
1845
+ }
1846
+ }
1847
+ // Update objective progress
1848
+ const allTasks = Array.from(this.tasks.values()).filter((task)=>task.context?.objectiveId === objective.id);
1849
+ objective.progress.totalTasks = allTasks.length;
1850
+ objective.progress.completedTasks = allTasks.filter((t)=>t.status === 'completed').length;
1851
+ objective.progress.failedTasks = allTasks.filter((t)=>t.status === 'failed').length;
1852
+ objective.progress.runningTasks = allTasks.filter((t)=>t.status === 'running').length;
1853
+ objective.progress.percentComplete = objective.progress.totalTasks > 0 ? objective.progress.completedTasks / objective.progress.totalTasks * 100 : 0;
1854
+ // Check if objective is complete
1855
+ if (objective.progress.completedTasks + objective.progress.failedTasks === objective.progress.totalTasks) {
1856
+ objective.status = objective.progress.failedTasks === 0 ? 'completed' : 'failed';
1857
+ objective.completedAt = new Date();
1858
+ clearInterval(executionInterval);
1859
+ this.logger.info('Objective completed', {
1860
+ objectiveId: objective.id,
1861
+ status: objective.status,
1862
+ completedTasks: objective.progress.completedTasks,
1863
+ failedTasks: objective.progress.failedTasks
1864
+ });
1865
+ this.emitSwarmEvent({
1866
+ id: generateId('event'),
1867
+ timestamp: new Date(),
1868
+ type: objective.status === 'completed' ? 'objective.completed' : 'objective.failed',
1869
+ source: this.swarmId.id,
1870
+ data: {
1871
+ objective
1872
+ },
1873
+ broadcast: true,
1874
+ processed: false
1875
+ });
1876
+ }
1877
+ } catch (error) {
1878
+ this.logger.error('Error in task execution loop', {
1879
+ error
1880
+ });
1881
+ }
1882
+ }, 2000); // Check every 2 seconds
1883
+ // Store interval reference for cleanup
1884
+ if (!this.executionIntervals) {
1885
+ this.executionIntervals = new Map();
1886
+ }
1887
+ this.executionIntervals.set(objective.id, executionInterval);
1888
+ }
1889
+ taskDependenciesMet(task, completedTasks) {
1890
+ if (!task.constraints.dependencies || task.constraints.dependencies.length === 0) {
1891
+ return true;
1892
+ }
1893
+ const completedTaskIds = completedTasks.map((t)=>t.id.id);
1894
+ return task.constraints.dependencies.every((dep)=>{
1895
+ // Handle both string and TaskId object dependencies
1896
+ const depId = typeof dep === 'string' ? dep : dep.id;
1897
+ return completedTaskIds.includes(depId);
1898
+ });
1899
+ }
1900
+ getNextInstanceNumber(type) {
1901
+ const agentsOfType = Array.from(this.agents.values()).filter((agent)=>agent.type === type);
1902
+ return agentsOfType.length + 1;
1903
+ }
1904
+ getDefaultPermissions(type) {
1905
+ switch(type){
1906
+ case 'coordinator':
1907
+ return [
1908
+ 'read',
1909
+ 'write',
1910
+ 'execute',
1911
+ 'admin'
1912
+ ];
1913
+ case 'coder':
1914
+ return [
1915
+ 'read',
1916
+ 'write',
1917
+ 'execute'
1918
+ ];
1919
+ case 'tester':
1920
+ return [
1921
+ 'read',
1922
+ 'execute'
1923
+ ];
1924
+ case 'reviewer':
1925
+ return [
1926
+ 'read',
1927
+ 'write'
1928
+ ];
1929
+ default:
1930
+ return [
1931
+ 'read'
1932
+ ];
1933
+ }
1934
+ }
1935
+ async initializeAgentCapabilities(agent) {
1936
+ // Set capabilities based on agent type
1937
+ switch(agent.type){
1938
+ case 'coordinator':
1939
+ agent.capabilities.codeGeneration = false;
1940
+ agent.capabilities.codeReview = true;
1941
+ agent.capabilities.testing = false;
1942
+ agent.capabilities.documentation = true;
1943
+ agent.capabilities.research = true;
1944
+ agent.capabilities.analysis = true;
1945
+ break;
1946
+ case 'coder':
1947
+ agent.capabilities.codeGeneration = true;
1948
+ agent.capabilities.codeReview = true;
1949
+ agent.capabilities.testing = true;
1950
+ agent.capabilities.documentation = true;
1951
+ break;
1952
+ case 'researcher':
1953
+ agent.capabilities.research = true;
1954
+ agent.capabilities.analysis = true;
1955
+ agent.capabilities.webSearch = true;
1956
+ agent.capabilities.documentation = true;
1957
+ break;
1958
+ case 'analyst':
1959
+ agent.capabilities.analysis = true;
1960
+ agent.capabilities.research = true;
1961
+ agent.capabilities.documentation = true;
1962
+ break;
1963
+ case 'reviewer':
1964
+ agent.capabilities.codeReview = true;
1965
+ agent.capabilities.testing = true;
1966
+ agent.capabilities.documentation = true;
1967
+ break;
1968
+ case 'tester':
1969
+ agent.capabilities.testing = true;
1970
+ agent.capabilities.codeReview = true;
1971
+ break;
1972
+ }
1973
+ }
1974
+ async initializeAgentEnvironment(agent) {
1975
+ // Implementation needed - setup agent environment
1976
+ }
1977
+ startAgentHeartbeat(agent) {
1978
+ // Implementation needed - start agent heartbeat
1979
+ }
1980
+ stopAgentHeartbeat(agent) {
1981
+ // Implementation needed - stop agent heartbeat
1982
+ }
1983
+ async cleanupAgentEnvironment(agent) {
1984
+ // Implementation needed - cleanup agent environment
1985
+ }
1986
+ getRequiredCapabilities(type) {
1987
+ switch(type){
1988
+ case 'coding':
1989
+ return [
1990
+ 'code-generation',
1991
+ 'file-system'
1992
+ ];
1993
+ case 'testing':
1994
+ return [
1995
+ 'testing',
1996
+ 'code-review'
1997
+ ];
1998
+ case 'research':
1999
+ return [
2000
+ 'research',
2001
+ 'web-search'
2002
+ ];
2003
+ case 'analysis':
2004
+ return [
2005
+ 'analysis',
2006
+ 'documentation'
2007
+ ];
2008
+ case 'review':
2009
+ return [
2010
+ 'code-review',
2011
+ 'documentation'
2012
+ ];
2013
+ case 'documentation':
2014
+ return [
2015
+ 'documentation'
2016
+ ];
2017
+ default:
2018
+ return [];
2019
+ }
2020
+ }
2021
+ getRequiredTools(type) {
2022
+ switch(type){
2023
+ case 'coding':
2024
+ return [
2025
+ 'editor',
2026
+ 'compiler',
2027
+ 'debugger'
2028
+ ];
2029
+ case 'testing':
2030
+ return [
2031
+ 'test-runner',
2032
+ 'coverage-tool'
2033
+ ];
2034
+ case 'research':
2035
+ return [
2036
+ 'web-browser',
2037
+ 'search-engine'
2038
+ ];
2039
+ case 'analysis':
2040
+ return [
2041
+ 'data-tools',
2042
+ 'visualization'
2043
+ ];
2044
+ default:
2045
+ return [];
2046
+ }
2047
+ }
2048
+ getRequiredPermissions(type) {
2049
+ switch(type){
2050
+ case 'coding':
2051
+ return [
2052
+ 'read',
2053
+ 'write',
2054
+ 'execute'
2055
+ ];
2056
+ case 'testing':
2057
+ return [
2058
+ 'read',
2059
+ 'execute'
2060
+ ];
2061
+ case 'research':
2062
+ return [
2063
+ 'read',
2064
+ 'network'
2065
+ ];
2066
+ default:
2067
+ return [
2068
+ 'read'
2069
+ ];
2070
+ }
2071
+ }
2072
+ async executeTaskWithAgent(task, agent) {
2073
+ this.logger.info('Executing task with agent', {
2074
+ taskId: task.id.id,
2075
+ taskName: task.name,
2076
+ agentId: agent.id.id,
2077
+ agentName: agent.name
2078
+ });
2079
+ // Extract target directory from task
2080
+ const targetDir = this.extractTargetDirectory(task);
2081
+ try {
2082
+ // Use Claude Flow executor for full SPARC system in non-interactive mode
2083
+ const { ClaudeFlowExecutor } = await import("./claude-flow-executor.ts");
2084
+ const executor = new ClaudeFlowExecutor({
2085
+ logger: this.logger,
2086
+ claudeFlowPath: getClaudeFlowBin(),
2087
+ enableSparc: true,
2088
+ verbose: this.config.logging?.level === 'debug',
2089
+ timeoutMinutes: this.config.taskTimeoutMinutes
2090
+ });
2091
+ const result = await executor.executeTask(task, agent, targetDir);
2092
+ this.logger.info('Task execution completed', {
2093
+ taskId: task.id.id,
2094
+ success: true,
2095
+ outputLength: JSON.stringify(result).length
2096
+ });
2097
+ return result;
2098
+ } catch (error) {
2099
+ this.logger.error('Task execution failed', {
2100
+ taskId: task.id.id,
2101
+ error: error instanceof Error ? error.message : String(error)
2102
+ });
2103
+ throw error;
2104
+ }
2105
+ }
2106
+ createExecutionPrompt(task) {
2107
+ // Create a prompt that Claude will understand
2108
+ let prompt = `# Swarm Task Execution\n\n`;
2109
+ prompt += `## Task: ${task.name}\n\n`;
2110
+ prompt += `${task.instructions || task.description}\n\n`;
2111
+ // Add working directory information if available
2112
+ const targetDir = this.extractTargetDirectory(task);
2113
+ if (targetDir) {
2114
+ prompt += `## Working Directory\n`;
2115
+ prompt += `Please create all files in: ${targetDir}\n\n`;
2116
+ }
2117
+ if (task.input && Object.keys(task.input).length > 0) {
2118
+ prompt += `## Additional Input\n`;
2119
+ prompt += `${JSON.stringify(task.input, null, 2)}\n\n`;
2120
+ }
2121
+ if (task.context && Object.keys(task.context).length > 0) {
2122
+ prompt += `## Context\n`;
2123
+ prompt += `${JSON.stringify(task.context, null, 2)}\n\n`;
2124
+ }
2125
+ // Add execution guidelines
2126
+ prompt += `## Guidelines\n`;
2127
+ prompt += `- Focus on completing this specific task\n`;
2128
+ prompt += `- Create all necessary files and directories\n`;
2129
+ prompt += `- Follow best practices for the technology being used\n`;
2130
+ prompt += `- Ensure the implementation is complete and functional\n`;
2131
+ return prompt;
2132
+ }
2133
+ extractTargetDirectory(task) {
2134
+ // Try multiple patterns to find the target directory
2135
+ const patterns = [
2136
+ /in\s+([^\s]+\/?)$/i,
2137
+ /(?:in|to|at)\s+([^\s]+\/[^\s]+)/i,
2138
+ /([^\s]+\/[^\s]+)$/,
2139
+ /examples\/[^\s]+/i
2140
+ ];
2141
+ let targetDir = null;
2142
+ // First check task description and input
2143
+ for (const pattern of patterns){
2144
+ const descMatch = task.description.match(pattern);
2145
+ const inputMatch = task.input?.objective?.match(pattern);
2146
+ if (descMatch || inputMatch) {
2147
+ targetDir = (descMatch || inputMatch)[descMatch ? 1 : 0];
2148
+ break;
2149
+ }
2150
+ }
2151
+ // If not found and task has context with targetDir, use that
2152
+ if (!targetDir && task.context?.targetDir) {
2153
+ targetDir = task.context.targetDir;
2154
+ }
2155
+ // If still not found, check objective description from context
2156
+ if (!targetDir && task.context?.objectiveId) {
2157
+ const objective = this.objectives.get(task.context.objectiveId);
2158
+ if (objective) {
2159
+ for (const pattern of patterns){
2160
+ const match = objective.description.match(pattern);
2161
+ if (match) {
2162
+ targetDir = match[1] || match[0];
2163
+ break;
2164
+ }
2165
+ }
2166
+ }
2167
+ }
2168
+ if (targetDir) {
2169
+ // Clean up the target directory
2170
+ targetDir = targetDir.replace(/\s+.*$/, '');
2171
+ // Resolve relative to current directory
2172
+ if (!targetDir.startsWith('/')) {
2173
+ targetDir = `${getClaudeFlowRoot()}/${targetDir}`;
2174
+ }
2175
+ }
2176
+ return targetDir;
2177
+ }
2178
+ async executeClaudeTask(task, agent, prompt, targetDir) {
2179
+ // Create unique instance ID for this execution
2180
+ const instanceId = `swarm-${this.swarmId.id}-${task.id.id}-${Date.now()}`;
2181
+ // Build Claude arguments for non-interactive execution
2182
+ const claudeArgs = [
2183
+ prompt
2184
+ ];
2185
+ // Always skip permissions for swarm automation
2186
+ claudeArgs.push('--dangerously-skip-permissions');
2187
+ // Add non-interactive flags for automation
2188
+ claudeArgs.push('-p'); // Print mode
2189
+ claudeArgs.push('--output-format', 'stream-json');
2190
+ claudeArgs.push('--verbose'); // Required when using stream-json with -p
2191
+ // Set working directory if specified
2192
+ if (targetDir) {
2193
+ // Ensure directory exists
2194
+ await Deno.mkdir(targetDir, {
2195
+ recursive: true
2196
+ });
2197
+ // Add directory context to prompt
2198
+ const enhancedPrompt = `${prompt}\n\n## Important: Working Directory\nPlease ensure all files are created in: ${targetDir}`;
2199
+ claudeArgs[0] = enhancedPrompt;
2200
+ }
2201
+ try {
2202
+ // Check if claude command exists
2203
+ const checkCommand = new Deno.Command('which', {
2204
+ args: [
2205
+ 'claude'
2206
+ ],
2207
+ stdout: 'piped',
2208
+ stderr: 'piped'
2209
+ });
2210
+ const checkResult = await checkCommand.output();
2211
+ if (!checkResult.success) {
2212
+ throw new Error('Claude CLI not found. Please ensure claude is installed and in PATH.');
2213
+ }
2214
+ // Execute Claude with the prompt
2215
+ const command = new Deno.Command('claude', {
2216
+ args: claudeArgs,
2217
+ cwd: targetDir || process.cwd(),
2218
+ env: {
2219
+ ...Deno.env.toObject(),
2220
+ CLAUDE_INSTANCE_ID: instanceId,
2221
+ CLAUDE_SWARM_MODE: 'true',
2222
+ CLAUDE_SWARM_ID: this.swarmId.id,
2223
+ CLAUDE_TASK_ID: task.id.id,
2224
+ CLAUDE_AGENT_ID: agent.id.id,
2225
+ CLAUDE_WORKING_DIRECTORY: targetDir || process.cwd(),
2226
+ CLAUDE_FLOW_MEMORY_ENABLED: 'true',
2227
+ CLAUDE_FLOW_MEMORY_NAMESPACE: `swarm-${this.swarmId.id}`
2228
+ },
2229
+ stdin: 'null',
2230
+ stdout: 'piped',
2231
+ stderr: 'piped'
2232
+ });
2233
+ this.logger.info('Spawning Claude agent for task', {
2234
+ taskId: task.id.id,
2235
+ agentId: agent.id.id,
2236
+ instanceId,
2237
+ targetDir
2238
+ });
2239
+ const child = command.spawn();
2240
+ const { code, stdout, stderr } = await child.output();
2241
+ if (code === 0) {
2242
+ const output = new TextDecoder().decode(stdout);
2243
+ this.logger.info('Claude agent completed task successfully', {
2244
+ taskId: task.id.id,
2245
+ outputLength: output.length
2246
+ });
2247
+ return {
2248
+ success: true,
2249
+ output,
2250
+ instanceId,
2251
+ targetDir
2252
+ };
2253
+ } else {
2254
+ const errorOutput = new TextDecoder().decode(stderr);
2255
+ this.logger.error(`Claude agent failed with code ${code}`, {
2256
+ taskId: task.id.id,
2257
+ error: errorOutput
2258
+ });
2259
+ throw new Error(`Claude execution failed: ${errorOutput}`);
2260
+ }
2261
+ } catch (error) {
2262
+ this.logger.error('Failed to execute Claude agent', {
2263
+ taskId: task.id.id,
2264
+ error: error instanceof Error ? error.message : String(error)
2265
+ });
2266
+ throw error;
2267
+ }
2268
+ }
2269
+ determineToolsForTask(task, agent) {
2270
+ const tools = new Set();
2271
+ // Basic tools for all tasks
2272
+ tools.add('View');
2273
+ tools.add('Edit');
2274
+ tools.add('Bash');
2275
+ // Add tools based on task type
2276
+ switch(task.type){
2277
+ case 'coding':
2278
+ tools.add('Create');
2279
+ tools.add('Write');
2280
+ tools.add('MultiEdit');
2281
+ tools.add('Test');
2282
+ break;
2283
+ case 'testing':
2284
+ tools.add('Test');
2285
+ tools.add('View');
2286
+ break;
2287
+ case 'documentation':
2288
+ tools.add('Write');
2289
+ tools.add('Create');
2290
+ break;
2291
+ case 'analysis':
2292
+ tools.add('Analyze');
2293
+ tools.add('Search');
2294
+ break;
2295
+ case 'research':
2296
+ tools.add('WebSearch');
2297
+ tools.add('Search');
2298
+ break;
2299
+ }
2300
+ // Add tools based on agent capabilities
2301
+ if (agent.capabilities.fileSystem) {
2302
+ tools.add('FileSystem');
2303
+ }
2304
+ if (agent.capabilities.terminalAccess) {
2305
+ tools.add('Terminal');
2306
+ }
2307
+ if (agent.capabilities.webSearch) {
2308
+ tools.add('WebSearch');
2309
+ }
2310
+ if (agent.capabilities.apiIntegration) {
2311
+ tools.add('API');
2312
+ }
2313
+ return Array.from(tools);
2314
+ }
2315
+ async simulateTaskExecution(task, agent, prompt) {
2316
+ // Simulate different task types with actual file operations
2317
+ // Check if task has a target directory in the description or context
2318
+ let workDir = `/tmp/swarm/${this.swarmId.id}/work`;
2319
+ // Extract target directory from task description or input
2320
+ // Try multiple patterns to find the target directory
2321
+ const patterns = [
2322
+ /in\s+([^\s]+\/?)$/i,
2323
+ /(?:in|to|at)\s+([^\s]+\/[^\s]+)/i,
2324
+ /([^\s]+\/[^\s]+)$/,
2325
+ /examples\/[^\s]+/i
2326
+ ];
2327
+ let targetDir = null;
2328
+ for (const pattern of patterns){
2329
+ const descMatch = task.description.match(pattern);
2330
+ const inputMatch = task.input?.objective?.match(pattern);
2331
+ if (descMatch || inputMatch) {
2332
+ targetDir = (descMatch || inputMatch)[descMatch ? 1 : 0];
2333
+ break;
2334
+ }
2335
+ }
2336
+ if (targetDir) {
2337
+ // Clean up the target directory (remove trailing words if needed)
2338
+ targetDir = targetDir.replace(/\s+.*$/, '');
2339
+ // Use absolute path or resolve relative to current directory
2340
+ workDir = targetDir.startsWith('/') ? targetDir : `${getClaudeFlowRoot()}/${targetDir}`;
2341
+ this.logger.debug('Extracted target directory', {
2342
+ original: task.description,
2343
+ targetDir,
2344
+ workDir
2345
+ });
2346
+ }
2347
+ try {
2348
+ // Ensure work directory exists
2349
+ await Deno.mkdir(workDir, {
2350
+ recursive: true
2351
+ });
2352
+ switch(task.type){
2353
+ case 'coding':
2354
+ return await this.executeCodeGenerationTask(task, workDir, agent);
2355
+ case 'analysis':
2356
+ return await this.executeAnalysisTask(task, workDir, agent);
2357
+ case 'documentation':
2358
+ return await this.executeDocumentationTask(task, workDir, agent);
2359
+ case 'testing':
2360
+ return await this.executeTestingTask(task, workDir, agent);
2361
+ default:
2362
+ return await this.executeGenericTask(task, workDir, agent);
2363
+ }
2364
+ } catch (error) {
2365
+ throw new Error(`Task execution failed: ${error instanceof Error ? error.message : String(error)}`);
2366
+ }
2367
+ }
2368
+ async executeCodeGenerationTask(task, workDir, agent) {
2369
+ this.logger.info('Executing code generation task', {
2370
+ taskId: task.id.id
2371
+ });
2372
+ // Detect technology from description
2373
+ const description = task.description.toLowerCase();
2374
+ const isGradio = description.includes('gradio');
2375
+ const isPython = isGradio || description.includes('python') || description.includes('fastapi') || description.includes('django');
2376
+ const isHelloWorld = description.includes('hello') && description.includes('world');
2377
+ const isRestAPI = description.includes('rest api') || description.includes('api');
2378
+ if (isGradio) {
2379
+ // Create a Gradio application
2380
+ return await this.createGradioApp(task, workDir);
2381
+ } else if (isPython && isRestAPI) {
2382
+ // Create a Python REST API (FastAPI)
2383
+ return await this.createPythonRestAPI(task, workDir);
2384
+ } else if (isRestAPI) {
2385
+ // Create a REST API application
2386
+ const projectName = 'rest-api';
2387
+ const projectDir = `${workDir}/${projectName}`;
2388
+ await Deno.mkdir(projectDir, {
2389
+ recursive: true
2390
+ });
2391
+ // Create main API file
2392
+ const apiCode = `const express = require('express');
2393
+ const app = express();
2394
+ const port = process.env.PORT || 3000;
2395
+
2396
+ // Middleware
2397
+ app.use(express.json());
2398
+ app.use(express.urlencoded({ extended: true }));
2399
+
2400
+ // Health check endpoint
2401
+ app.get('/health', (req, res) => {
2402
+ res.json({
2403
+ status: 'healthy',
2404
+ service: 'REST API',
2405
+ swarmId: '${this.swarmId.id}',
2406
+ created: '${new Date().toISOString()}'
2407
+ });
2408
+ });
2409
+
2410
+ // Sample endpoints
2411
+ app.get('/api/v1/items', (req, res) => {
2412
+ res.json({
2413
+ items: [
2414
+ { id: 1, name: 'Item 1', description: 'First item' },
2415
+ { id: 2, name: 'Item 2', description: 'Second item' }
2416
+ ],
2417
+ total: 2
2418
+ });
2419
+ });
2420
+
2421
+ app.get('/api/v1/items/:id', (req, res) => {
2422
+ const id = parseInt(req.params.id);
2423
+ res.json({
2424
+ id,
2425
+ name: \`Item \${id}\`,
2426
+ description: \`Description for item \${id}\`
2427
+ });
2428
+ });
2429
+
2430
+ app.post('/api/v1/items', (req, res) => {
2431
+ const newItem = {
2432
+ id: Date.now(),
2433
+ ...req.body,
2434
+ createdAt: new Date().toISOString()
2435
+ };
2436
+ res.status(201).json(newItem);
2437
+ });
2438
+
2439
+ app.put('/api/v1/items/:id', (req, res) => {
2440
+ const id = parseInt(req.params.id);
2441
+ const updatedItem = {
2442
+ id,
2443
+ ...req.body,
2444
+ updatedAt: new Date().toISOString()
2445
+ };
2446
+ res.json(updatedItem);
2447
+ });
2448
+
2449
+ app.delete('/api/v1/items/:id', (req, res) => {
2450
+ const id = parseInt(req.params.id);
2451
+ res.json({ message: \`Item \${id} deleted successfully\` });
2452
+ });
2453
+
2454
+ // Error handling middleware
2455
+ app.use((err, req, res, next) => {
2456
+ console.error(err.stack);
2457
+ res.status(500).json({ error: 'Internal server error' });
2458
+ });
2459
+
2460
+ // Start server
2461
+ app.listen(port, () => {
2462
+ console.log(\`REST API server running on port \${port}\`);
2463
+ console.log('Created by Claude Flow Swarm');
2464
+ });
2465
+
2466
+ module.exports = app;
2467
+ `;
2468
+ await fs.writeFile(`${projectDir}/server.js`, apiCode);
2469
+ // Create package.json
2470
+ const packageJson = {
2471
+ name: projectName,
2472
+ version: '1.0.0',
2473
+ description: 'REST API created by Claude Flow Swarm',
2474
+ main: 'server.js',
2475
+ scripts: {
2476
+ start: 'node server.js',
2477
+ dev: 'nodemon server.js',
2478
+ test: 'jest'
2479
+ },
2480
+ keywords: [
2481
+ 'rest',
2482
+ 'api',
2483
+ 'swarm',
2484
+ 'claude-flow'
2485
+ ],
2486
+ author: 'Claude Flow Swarm',
2487
+ license: 'MIT',
2488
+ dependencies: {
2489
+ express: '^4.18.2'
2490
+ },
2491
+ devDependencies: {
2492
+ nodemon: '^3.0.1',
2493
+ jest: '^29.7.0',
2494
+ supertest: '^6.3.3'
2495
+ },
2496
+ swarmMetadata: {
2497
+ swarmId: this.swarmId.id,
2498
+ taskId: task.id.id,
2499
+ agentId: agent.id.id,
2500
+ created: new Date().toISOString()
2501
+ }
2502
+ };
2503
+ await fs.writeFile(`${projectDir}/package.json`, JSON.stringify(packageJson, null, 2));
2504
+ // Create README
2505
+ const readme = `# REST API
2506
+
2507
+ This REST API was created by the Claude Flow Swarm system.
2508
+
2509
+ ## Swarm Details
2510
+ - Swarm ID: ${this.swarmId.id}
2511
+ - Task: ${task.name}
2512
+ - Agent: ${agent.name}
2513
+ - Generated: ${new Date().toISOString()}
2514
+
2515
+ ## Installation
2516
+
2517
+ \`\`\`bash
2518
+ npm install
2519
+ \`\`\`
2520
+
2521
+ ## Usage
2522
+
2523
+ Start the server:
2524
+ \`\`\`bash
2525
+ npm start
2526
+ \`\`\`
2527
+
2528
+ Development mode with auto-reload:
2529
+ \`\`\`bash
2530
+ npm run dev
2531
+ \`\`\`
2532
+
2533
+ ## API Endpoints
2534
+
2535
+ - \`GET /health\` - Health check
2536
+ - \`GET /api/v1/items\` - Get all items
2537
+ - \`GET /api/v1/items/:id\` - Get item by ID
2538
+ - \`POST /api/v1/items\` - Create new item
2539
+ - \`PUT /api/v1/items/:id\` - Update item
2540
+ - \`DELETE /api/v1/items/:id\` - Delete item
2541
+
2542
+ ## Description
2543
+ ${task.description}
2544
+
2545
+ ---
2546
+ Created by Claude Flow Swarm
2547
+ `;
2548
+ await fs.writeFile(`${projectDir}/README.md`, readme);
2549
+ // Create .gitignore
2550
+ const gitignore = `node_modules/
2551
+ .env
2552
+ *.log
2553
+ .DS_Store
2554
+ coverage/
2555
+ `;
2556
+ await fs.writeFile(`${projectDir}/.gitignore`, gitignore);
2557
+ return {
2558
+ success: true,
2559
+ output: {
2560
+ message: 'REST API created successfully',
2561
+ location: projectDir,
2562
+ files: [
2563
+ 'server.js',
2564
+ 'package.json',
2565
+ 'README.md',
2566
+ '.gitignore'
2567
+ ]
2568
+ },
2569
+ artifacts: {
2570
+ mainFile: `${projectDir}/server.js`,
2571
+ packageFile: `${projectDir}/package.json`,
2572
+ readmeFile: `${projectDir}/README.md`
2573
+ }
2574
+ };
2575
+ } else if (isHelloWorld) {
2576
+ // Create a simple hello world application
2577
+ const projectDir = `${workDir}/hello-world`;
2578
+ await Deno.mkdir(projectDir, {
2579
+ recursive: true
2580
+ });
2581
+ // Create main application file
2582
+ const mainCode = `#!/usr/bin/env node
2583
+
2584
+ // Hello World Application
2585
+ // Generated by Claude Flow Swarm
2586
+
2587
+ console.log('Hello, World!');
2588
+ console.log('This application was created by the Claude Flow Swarm system.');
2589
+ console.log('Swarm ID: ${this.swarmId.id}');
2590
+ console.log('Task: ${task.name}');
2591
+ console.log('Generated at: ${new Date().toISOString()}');
2592
+
2593
+ // Export for testing
2594
+ if (typeof module !== 'undefined' && module.exports) {
2595
+ module.exports = { message: 'Hello, World!' };
2596
+ }
2597
+ `;
2598
+ await fs.writeFile(`${projectDir}/index.js`, mainCode);
2599
+ // Create package.json
2600
+ const packageJson = {
2601
+ name: 'hello-world',
2602
+ version: '1.0.0',
2603
+ description: 'Hello World application created by Claude Flow Swarm',
2604
+ main: 'index.js',
2605
+ scripts: {
2606
+ start: 'node index.js',
2607
+ test: 'node test.js'
2608
+ },
2609
+ keywords: [
2610
+ 'hello-world',
2611
+ 'swarm',
2612
+ 'claude-flow'
2613
+ ],
2614
+ author: 'Claude Flow Swarm',
2615
+ license: 'MIT'
2616
+ };
2617
+ await fs.writeFile(`${projectDir}/package.json`, JSON.stringify(packageJson, null, 2));
2618
+ // Create README
2619
+ const readme = `# Hello World
2620
+
2621
+ This application was created by the Claude Flow Swarm system.
2622
+
2623
+ ## Swarm Details
2624
+ - Swarm ID: ${this.swarmId.id}
2625
+ - Task: ${task.name}
2626
+ - Generated: ${new Date().toISOString()}
2627
+
2628
+ ## Usage
2629
+
2630
+ \`\`\`bash
2631
+ npm start
2632
+ \`\`\`
2633
+
2634
+ ## Description
2635
+ ${task.description}
2636
+ `;
2637
+ await fs.writeFile(`${projectDir}/README.md`, readme);
2638
+ return {
2639
+ success: true,
2640
+ output: {
2641
+ message: 'Hello World application created successfully',
2642
+ location: projectDir,
2643
+ files: [
2644
+ 'index.js',
2645
+ 'package.json',
2646
+ 'README.md'
2647
+ ]
2648
+ },
2649
+ artifacts: {
2650
+ mainFile: `${projectDir}/index.js`,
2651
+ packageFile: `${projectDir}/package.json`,
2652
+ readmeFile: `${projectDir}/README.md`
2653
+ }
2654
+ };
2655
+ }
2656
+ // For other code generation tasks, create a basic structure
2657
+ const projectDir = `${workDir}/generated-code`;
2658
+ await Deno.mkdir(projectDir, {
2659
+ recursive: true
2660
+ });
2661
+ const code = `// Generated code for: ${task.name}
2662
+ // ${task.description}
2663
+
2664
+ function main() {
2665
+ console.log('Executing task: ${task.name}');
2666
+ // Implementation would go here
2667
+ }
2668
+
2669
+ main();
2670
+ `;
2671
+ await fs.writeFile(`${projectDir}/main.js`, code);
2672
+ return {
2673
+ success: true,
2674
+ output: {
2675
+ message: 'Code generated successfully',
2676
+ location: projectDir,
2677
+ files: [
2678
+ 'main.js'
2679
+ ]
2680
+ }
2681
+ };
2682
+ }
2683
+ async executeAnalysisTask(task, workDir, agent) {
2684
+ this.logger.info('Executing analysis task', {
2685
+ taskId: task.id.id
2686
+ });
2687
+ const analysisDir = `${workDir}/analysis`;
2688
+ await Deno.mkdir(analysisDir, {
2689
+ recursive: true
2690
+ });
2691
+ const analysis = {
2692
+ task: task.name,
2693
+ description: task.description,
2694
+ timestamp: new Date().toISOString(),
2695
+ findings: [
2696
+ 'Analysis point 1: Task objectives are clear',
2697
+ 'Analysis point 2: Resources are allocated',
2698
+ 'Analysis point 3: Implementation path is defined'
2699
+ ],
2700
+ recommendations: [
2701
+ 'Proceed with implementation',
2702
+ 'Monitor progress regularly',
2703
+ 'Adjust resources as needed'
2704
+ ]
2705
+ };
2706
+ await fs.writeFile(`${analysisDir}/analysis-report.json`, JSON.stringify(analysis, null, 2));
2707
+ return {
2708
+ success: true,
2709
+ output: analysis,
2710
+ artifacts: {
2711
+ report: `${analysisDir}/analysis-report.json`
2712
+ }
2713
+ };
2714
+ }
2715
+ async executeDocumentationTask(task, workDir, agent) {
2716
+ this.logger.info('Executing documentation task', {
2717
+ taskId: task.id.id
2718
+ });
2719
+ const docsDir = `${workDir}/docs`;
2720
+ await Deno.mkdir(docsDir, {
2721
+ recursive: true
2722
+ });
2723
+ const documentation = `# ${task.name}
2724
+
2725
+ ${task.description}
2726
+
2727
+ ## Overview
2728
+ This documentation was generated by the Claude Flow Swarm system.
2729
+
2730
+ ## Details
2731
+ - Task ID: ${task.id.id}
2732
+ - Generated: ${new Date().toISOString()}
2733
+ - Swarm ID: ${this.swarmId.id}
2734
+
2735
+ ## Instructions
2736
+ ${task.instructions}
2737
+
2738
+ ## Implementation Notes
2739
+ - This is an automated documentation generated by the swarm
2740
+ - Further details would be added based on actual implementation
2741
+ `;
2742
+ await fs.writeFile(`${docsDir}/documentation.md`, documentation);
2743
+ return {
2744
+ success: true,
2745
+ output: {
2746
+ message: 'Documentation created successfully',
2747
+ location: docsDir,
2748
+ files: [
2749
+ 'documentation.md'
2750
+ ]
2751
+ },
2752
+ artifacts: {
2753
+ documentation: `${docsDir}/documentation.md`
2754
+ }
2755
+ };
2756
+ }
2757
+ async executeTestingTask(task, workDir, agent) {
2758
+ this.logger.info('Executing testing task', {
2759
+ taskId: task.id.id
2760
+ });
2761
+ const testDir = `${workDir}/tests`;
2762
+ await Deno.mkdir(testDir, {
2763
+ recursive: true
2764
+ });
2765
+ const testCode = `// Test suite for: ${task.name}
2766
+ // ${task.description}
2767
+
2768
+ const assert = require('assert');
2769
+
2770
+ describe('${task.name}', () => {
2771
+ it('should pass basic test', () => {
2772
+ assert.strictEqual(1 + 1, 2);
2773
+ });
2774
+
2775
+ it('should validate implementation', () => {
2776
+ // Test implementation would go here
2777
+ assert.ok(true, 'Implementation validated');
2778
+ });
2779
+ });
2780
+
2781
+ console.log('Tests completed for: ${task.name}');
2782
+ `;
2783
+ await fs.writeFile(`${testDir}/test.js`, testCode);
2784
+ return {
2785
+ success: true,
2786
+ output: {
2787
+ message: 'Test suite created successfully',
2788
+ location: testDir,
2789
+ files: [
2790
+ 'test.js'
2791
+ ],
2792
+ testsPassed: 2,
2793
+ testsFailed: 0
2794
+ },
2795
+ artifacts: {
2796
+ testFile: `${testDir}/test.js`
2797
+ }
2798
+ };
2799
+ }
2800
+ async executeGenericTask(task, workDir, agent) {
2801
+ this.logger.info('Executing generic task', {
2802
+ taskId: task.id.id
2803
+ });
2804
+ const outputDir = `${workDir}/output`;
2805
+ await Deno.mkdir(outputDir, {
2806
+ recursive: true
2807
+ });
2808
+ const output = {
2809
+ task: task.name,
2810
+ type: task.type,
2811
+ description: task.description,
2812
+ status: 'completed',
2813
+ timestamp: new Date().toISOString(),
2814
+ result: 'Task executed successfully'
2815
+ };
2816
+ await fs.writeFile(`${outputDir}/result.json`, JSON.stringify(output, null, 2));
2817
+ return {
2818
+ success: true,
2819
+ output,
2820
+ artifacts: {
2821
+ result: `${outputDir}/result.json`
2822
+ }
2823
+ };
2824
+ }
2825
+ assessTaskQuality(task, result) {
2826
+ // Implementation needed - assess task quality
2827
+ return 0.8;
2828
+ }
2829
+ updateAgentMetrics(agent, task) {
2830
+ // Update agent performance metrics
2831
+ const executionTime = task.completedAt.getTime() - (task.startedAt?.getTime() || 0);
2832
+ agent.metrics.averageExecutionTime = (agent.metrics.averageExecutionTime * agent.metrics.tasksCompleted + executionTime) / (agent.metrics.tasksCompleted + 1);
2833
+ agent.metrics.successRate = agent.metrics.tasksCompleted / (agent.metrics.tasksCompleted + agent.metrics.tasksFailed);
2834
+ }
2835
+ async processDependentTasks(task) {
2836
+ // Implementation needed - process tasks that depend on this one
2837
+ }
2838
+ isRecoverableError(error) {
2839
+ // Implementation needed - determine if error is recoverable
2840
+ return true;
2841
+ }
2842
+ isRetryableError(error) {
2843
+ // Implementation needed - determine if error is retryable
2844
+ return true;
2845
+ }
2846
+ async handleTaskFailureCascade(task) {
2847
+ // Implementation needed - handle failure cascade
2848
+ }
2849
+ async reassignTask(taskId) {
2850
+ // Implementation needed - reassign task to different agent
2851
+ }
2852
+ processHeartbeats() {
2853
+ const now = new Date();
2854
+ const timeout = this.config.monitoring.heartbeatInterval * 10; // Increased multiplier for long-running Claude tasks
2855
+ for (const agent of this.agents.values()){
2856
+ if (agent.status === 'offline' || agent.status === 'terminated') {
2857
+ continue;
2858
+ }
2859
+ const timeSinceHeartbeat = now.getTime() - agent.lastHeartbeat.getTime();
2860
+ if (timeSinceHeartbeat > timeout) {
2861
+ this.logger.warn('Agent heartbeat timeout', {
2862
+ agentId: agent.id.id,
2863
+ timeSinceHeartbeat
2864
+ });
2865
+ agent.status = 'error';
2866
+ agent.health = 0;
2867
+ }
2868
+ }
2869
+ }
2870
+ updateSwarmMetrics() {
2871
+ // Implementation needed - update swarm-level metrics
2872
+ }
2873
+ performCleanup() {
2874
+ // Implementation needed - perform periodic cleanup
2875
+ }
2876
+ checkObjectiveCompletion() {
2877
+ // Implementation needed - check if objectives are complete
2878
+ }
2879
+ checkObjectiveFailure(task) {
2880
+ // Implementation needed - check if objective has failed
2881
+ }
2882
+ handleAgentError(agentId, error) {
2883
+ const agent = this.agents.get(agentId);
2884
+ if (agent) {
2885
+ agent.status = 'error';
2886
+ agent.health = 0;
2887
+ this.logger.error('Agent error', {
2888
+ agentId,
2889
+ error
2890
+ });
2891
+ // Track error in JSON output if enabled
2892
+ if (this.jsonOutputAggregator) {
2893
+ this.jsonOutputAggregator.addAgentError(agentId, error instanceof Error ? error.message : String(error));
2894
+ }
2895
+ }
2896
+ }
2897
+ // ===== JSON OUTPUT METHODS =====
2898
+ /**
2899
+ * Enable JSON output collection for non-interactive mode
2900
+ */ enableJsonOutput(objective) {
2901
+ if (!this.jsonOutputAggregator) {
2902
+ this.jsonOutputAggregator = new SwarmJsonOutputAggregator(this.swarmId.id, objective, this.config);
2903
+ this.logger.info('JSON output aggregation enabled', {
2904
+ swarmId: this.swarmId.id
2905
+ });
2906
+ }
2907
+ }
2908
+ /**
2909
+ * Get the final JSON output for the swarm
2910
+ */ getJsonOutput(status = 'completed') {
2911
+ if (!this.jsonOutputAggregator) {
2912
+ return null;
2913
+ }
2914
+ return this.jsonOutputAggregator.getJsonOutput(status);
2915
+ }
2916
+ /**
2917
+ * Save JSON output to file
2918
+ */ async saveJsonOutput(filePath, status = 'completed') {
2919
+ if (!this.jsonOutputAggregator) {
2920
+ throw new Error('JSON output aggregation not enabled');
2921
+ }
2922
+ await this.jsonOutputAggregator.saveToFile(filePath, status);
2923
+ }
2924
+ /**
2925
+ * Track agent activity in JSON output
2926
+ */ trackAgentInJsonOutput(agent) {
2927
+ if (this.jsonOutputAggregator) {
2928
+ this.jsonOutputAggregator.addAgent(agent);
2929
+ }
2930
+ }
2931
+ /**
2932
+ * Track task activity in JSON output
2933
+ */ trackTaskInJsonOutput(task) {
2934
+ if (this.jsonOutputAggregator) {
2935
+ this.jsonOutputAggregator.addTask(task);
2936
+ }
2937
+ }
2938
+ /**
2939
+ * Add output to JSON aggregator
2940
+ */ addOutputToJsonAggregator(agentId, output) {
2941
+ if (this.jsonOutputAggregator) {
2942
+ this.jsonOutputAggregator.addAgentOutput(agentId, output);
2943
+ }
2944
+ }
2945
+ /**
2946
+ * Add insight to JSON aggregator
2947
+ */ addInsight(insight) {
2948
+ if (this.jsonOutputAggregator) {
2949
+ this.jsonOutputAggregator.addInsight(insight);
2950
+ }
2951
+ }
2952
+ /**
2953
+ * Add artifact to JSON aggregator
2954
+ */ addArtifact(key, artifact) {
2955
+ if (this.jsonOutputAggregator) {
2956
+ this.jsonOutputAggregator.addArtifact(key, artifact);
2957
+ }
2958
+ }
2959
+ constructor(config = {}){
2960
+ super(), _define_property(this, "logger", void 0), _define_property(this, "config", void 0), _define_property(this, "swarmId", void 0), // Core state management
2961
+ _define_property(this, "agents", new Map()), _define_property(this, "tasks", new Map()), _define_property(this, "objectives", new Map()), // Execution state
2962
+ _define_property(this, "_isRunning", false), _define_property(this, "status", 'planning'), _define_property(this, "startTime", void 0), _define_property(this, "endTime", void 0), // Performance tracking
2963
+ _define_property(this, "metrics", void 0), _define_property(this, "events", []), _define_property(this, "lastHeartbeat", new Date()), // JSON output aggregation (optional)
2964
+ _define_property(this, "jsonOutputAggregator", void 0), // Background processes
2965
+ _define_property(this, "heartbeatTimer", void 0), _define_property(this, "monitoringTimer", void 0), _define_property(this, "cleanupTimer", void 0), _define_property(this, "executionIntervals", void 0), // Strategy instances
2966
+ _define_property(this, "autoStrategy", void 0);
2967
+ // Configure logger based on config or default to quiet mode
2968
+ const logLevel = config.logging?.level || 'error';
2969
+ const logFormat = config.logging?.format || 'text';
2970
+ const logDestination = config.logging?.destination || 'console';
2971
+ this.logger = new Logger({
2972
+ level: logLevel,
2973
+ format: logFormat,
2974
+ destination: logDestination
2975
+ }, {
2976
+ component: 'SwarmCoordinator'
2977
+ });
2978
+ this.swarmId = this.generateSwarmId();
2979
+ // Initialize configuration with defaults
2980
+ this.config = this.mergeWithDefaults(config);
2981
+ // Initialize metrics
2982
+ this.metrics = this.initializeMetrics();
2983
+ // Initialize strategy instances
2984
+ this.autoStrategy = new AutoStrategy(config);
2985
+ // Setup event handlers
2986
+ this.setupEventHandlers();
2987
+ this.logger.info('SwarmCoordinator initialized', {
2988
+ swarmId: this.swarmId.id,
2989
+ mode: this.config.mode,
2990
+ strategy: this.config.strategy
2991
+ });
2992
+ }
2993
+ }