@claude-flow/shared 3.0.0-alpha.7 → 3.0.0-alpha.8

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 (195) hide show
  1. package/.claude-flow/daemon-state.json +135 -0
  2. package/.claude-flow/data/pending-insights.jsonl +2 -0
  3. package/.claude-flow/data/ranked-context.json +5 -0
  4. package/.claude-flow/logs/daemon.log +45 -0
  5. package/.claude-flow/logs/headless/audit_1777379186972_h5un5x_prompt.log +3210 -0
  6. package/.claude-flow/logs/headless/audit_1777379186972_h5un5x_result.log +117 -0
  7. package/.claude-flow/logs/headless/audit_1777379816437_w0eaul_prompt.log +3210 -0
  8. package/.claude-flow/logs/headless/audit_1777379816437_w0eaul_result.log +53 -0
  9. package/.claude-flow/logs/headless/audit_1777380440097_621y8m_prompt.log +3210 -0
  10. package/.claude-flow/logs/headless/audit_1777380440097_621y8m_result.log +75 -0
  11. package/.claude-flow/logs/headless/optimize_1777379306973_an4lmy_prompt.log +3504 -0
  12. package/.claude-flow/logs/headless/optimize_1777379306973_an4lmy_result.log +166 -0
  13. package/.claude-flow/logs/headless/optimize_1777380274732_apxz3s_prompt.log +3504 -0
  14. package/.claude-flow/logs/headless/optimize_1777380274732_apxz3s_result.log +219 -0
  15. package/.claude-flow/logs/headless/testgaps_1777379546969_dvf2a1_prompt.log +3189 -0
  16. package/.claude-flow/logs/headless/testgaps_1777379546969_dvf2a1_result.log +155 -0
  17. package/.claude-flow/metrics/codebase-map.json +11 -0
  18. package/.claude-flow/metrics/consolidation.json +6 -0
  19. package/.claude-flow/sessions/current.json +13 -0
  20. package/.swarm/hnsw.index +0 -0
  21. package/.swarm/hnsw.metadata.json +1 -0
  22. package/.swarm/memory.db +0 -0
  23. package/.swarm/memory.db-shm +0 -0
  24. package/.swarm/memory.db-wal +0 -0
  25. package/.swarm/schema.sql +305 -0
  26. package/dist/core/config/schema.d.ts +96 -96
  27. package/dist/events/event-store.d.ts.map +1 -1
  28. package/dist/events/event-store.js +20 -9
  29. package/dist/events/event-store.js.map +1 -1
  30. package/dist/hooks/executor.d.ts.map +1 -1
  31. package/dist/hooks/executor.js +7 -4
  32. package/dist/hooks/executor.js.map +1 -1
  33. package/dist/hooks/verify-exports.test.js +6 -6
  34. package/dist/hooks/verify-exports.test.js.map +1 -1
  35. package/dist/mcp/server.d.ts.map +1 -1
  36. package/dist/mcp/server.js +3 -6
  37. package/dist/mcp/server.js.map +1 -1
  38. package/dist/mcp/types.d.ts +4 -6
  39. package/dist/mcp/types.d.ts.map +1 -1
  40. package/dist/mcp/types.js.map +1 -1
  41. package/package.json +3 -2
  42. package/ruvector.db +0 -0
  43. package/src/events/event-store.ts +18 -9
  44. package/src/hooks/executor.ts +7 -5
  45. package/src/hooks/verify-exports.test.ts +6 -6
  46. package/src/mcp/server.ts +3 -6
  47. package/src/mcp/types.ts +4 -6
  48. package/tsconfig.tsbuildinfo +1 -1
  49. package/.agentic-flow/intelligence.json +0 -16
  50. package/__tests__/coverage/base.css +0 -224
  51. package/__tests__/coverage/block-navigation.js +0 -87
  52. package/__tests__/coverage/coverage-final.json +0 -50
  53. package/__tests__/coverage/favicon.png +0 -0
  54. package/__tests__/coverage/index.html +0 -326
  55. package/__tests__/coverage/lcov-report/base.css +0 -224
  56. package/__tests__/coverage/lcov-report/block-navigation.js +0 -87
  57. package/__tests__/coverage/lcov-report/favicon.png +0 -0
  58. package/__tests__/coverage/lcov-report/index.html +0 -326
  59. package/__tests__/coverage/lcov-report/prettify.css +0 -1
  60. package/__tests__/coverage/lcov-report/prettify.js +0 -2
  61. package/__tests__/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  62. package/__tests__/coverage/lcov-report/sorter.js +0 -210
  63. package/__tests__/coverage/lcov-report/src/core/config/defaults.ts.html +0 -706
  64. package/__tests__/coverage/lcov-report/src/core/config/index.html +0 -161
  65. package/__tests__/coverage/lcov-report/src/core/config/loader.ts.html +0 -898
  66. package/__tests__/coverage/lcov-report/src/core/config/schema.ts.html +0 -649
  67. package/__tests__/coverage/lcov-report/src/core/config/validator.ts.html +0 -712
  68. package/__tests__/coverage/lcov-report/src/core/event-bus.ts.html +0 -793
  69. package/__tests__/coverage/lcov-report/src/core/index.html +0 -116
  70. package/__tests__/coverage/lcov-report/src/core/interfaces/event.interface.ts.html +0 -886
  71. package/__tests__/coverage/lcov-report/src/core/interfaces/index.html +0 -116
  72. package/__tests__/coverage/lcov-report/src/core/orchestrator/event-coordinator.ts.html +0 -451
  73. package/__tests__/coverage/lcov-report/src/core/orchestrator/health-monitor.ts.html +0 -727
  74. package/__tests__/coverage/lcov-report/src/core/orchestrator/index.html +0 -176
  75. package/__tests__/coverage/lcov-report/src/core/orchestrator/lifecycle-manager.ts.html +0 -874
  76. package/__tests__/coverage/lcov-report/src/core/orchestrator/session-manager.ts.html +0 -922
  77. package/__tests__/coverage/lcov-report/src/core/orchestrator/task-manager.ts.html +0 -1036
  78. package/__tests__/coverage/lcov-report/src/events/domain-events.ts.html +0 -1837
  79. package/__tests__/coverage/lcov-report/src/events/event-store.ts.html +0 -1849
  80. package/__tests__/coverage/lcov-report/src/events/example-usage.ts.html +0 -964
  81. package/__tests__/coverage/lcov-report/src/events/index.html +0 -176
  82. package/__tests__/coverage/lcov-report/src/events/projections.ts.html +0 -1768
  83. package/__tests__/coverage/lcov-report/src/events/state-reconstructor.ts.html +0 -1132
  84. package/__tests__/coverage/lcov-report/src/events.ts.html +0 -1186
  85. package/__tests__/coverage/lcov-report/src/hooks/example-usage.ts.html +0 -1582
  86. package/__tests__/coverage/lcov-report/src/hooks/executor.ts.html +0 -1222
  87. package/__tests__/coverage/lcov-report/src/hooks/index.html +0 -191
  88. package/__tests__/coverage/lcov-report/src/hooks/registry.ts.html +0 -1084
  89. package/__tests__/coverage/lcov-report/src/hooks/safety/bash-safety.ts.html +0 -1897
  90. package/__tests__/coverage/lcov-report/src/hooks/safety/file-organization.ts.html +0 -1504
  91. package/__tests__/coverage/lcov-report/src/hooks/safety/git-commit.ts.html +0 -1954
  92. package/__tests__/coverage/lcov-report/src/hooks/safety/index.html +0 -146
  93. package/__tests__/coverage/lcov-report/src/hooks/session-hooks.ts.html +0 -1762
  94. package/__tests__/coverage/lcov-report/src/hooks/task-hooks.ts.html +0 -1624
  95. package/__tests__/coverage/lcov-report/src/hooks/types.ts.html +0 -1156
  96. package/__tests__/coverage/lcov-report/src/index.html +0 -176
  97. package/__tests__/coverage/lcov-report/src/mcp/connection-pool.ts.html +0 -1399
  98. package/__tests__/coverage/lcov-report/src/mcp/index.html +0 -176
  99. package/__tests__/coverage/lcov-report/src/mcp/server.ts.html +0 -2407
  100. package/__tests__/coverage/lcov-report/src/mcp/session-manager.ts.html +0 -1369
  101. package/__tests__/coverage/lcov-report/src/mcp/tool-registry.ts.html +0 -1783
  102. package/__tests__/coverage/lcov-report/src/mcp/transport/http.ts.html +0 -1756
  103. package/__tests__/coverage/lcov-report/src/mcp/transport/index.html +0 -146
  104. package/__tests__/coverage/lcov-report/src/mcp/transport/stdio.ts.html +0 -1057
  105. package/__tests__/coverage/lcov-report/src/mcp/transport/websocket.ts.html +0 -1537
  106. package/__tests__/coverage/lcov-report/src/mcp/types.ts.html +0 -1780
  107. package/__tests__/coverage/lcov-report/src/plugin-interface.ts.html +0 -2074
  108. package/__tests__/coverage/lcov-report/src/plugin-loader.ts.html +0 -1999
  109. package/__tests__/coverage/lcov-report/src/plugin-registry.ts.html +0 -1897
  110. package/__tests__/coverage/lcov-report/src/plugins/official/hive-mind-plugin.ts.html +0 -1075
  111. package/__tests__/coverage/lcov-report/src/plugins/official/index.html +0 -131
  112. package/__tests__/coverage/lcov-report/src/plugins/official/maestro-plugin.ts.html +0 -1609
  113. package/__tests__/coverage/lcov-report/src/resilience/bulkhead.ts.html +0 -916
  114. package/__tests__/coverage/lcov-report/src/resilience/circuit-breaker.ts.html +0 -1063
  115. package/__tests__/coverage/lcov-report/src/resilience/index.html +0 -161
  116. package/__tests__/coverage/lcov-report/src/resilience/rate-limiter.ts.html +0 -1345
  117. package/__tests__/coverage/lcov-report/src/resilience/retry.ts.html +0 -757
  118. package/__tests__/coverage/lcov-report/src/security/index.html +0 -131
  119. package/__tests__/coverage/lcov-report/src/security/input-validation.ts.html +0 -880
  120. package/__tests__/coverage/lcov-report/src/security/secure-random.ts.html +0 -562
  121. package/__tests__/coverage/lcov-report/src/types/index.html +0 -131
  122. package/__tests__/coverage/lcov-report/src/types/swarm.types.ts.html +0 -850
  123. package/__tests__/coverage/lcov-report/src/types/task.types.ts.html +0 -700
  124. package/__tests__/coverage/lcov-report/src/types.ts.html +0 -1186
  125. package/__tests__/coverage/lcov-report/src/utils/index.html +0 -116
  126. package/__tests__/coverage/lcov-report/src/utils/secure-logger.ts.html +0 -856
  127. package/__tests__/coverage/lcov.info +0 -19877
  128. package/__tests__/coverage/prettify.css +0 -1
  129. package/__tests__/coverage/prettify.js +0 -2
  130. package/__tests__/coverage/sort-arrow-sprite.png +0 -0
  131. package/__tests__/coverage/sorter.js +0 -210
  132. package/__tests__/coverage/src/core/config/defaults.ts.html +0 -706
  133. package/__tests__/coverage/src/core/config/index.html +0 -161
  134. package/__tests__/coverage/src/core/config/loader.ts.html +0 -898
  135. package/__tests__/coverage/src/core/config/schema.ts.html +0 -649
  136. package/__tests__/coverage/src/core/config/validator.ts.html +0 -712
  137. package/__tests__/coverage/src/core/event-bus.ts.html +0 -793
  138. package/__tests__/coverage/src/core/index.html +0 -116
  139. package/__tests__/coverage/src/core/interfaces/event.interface.ts.html +0 -886
  140. package/__tests__/coverage/src/core/interfaces/index.html +0 -116
  141. package/__tests__/coverage/src/core/orchestrator/event-coordinator.ts.html +0 -451
  142. package/__tests__/coverage/src/core/orchestrator/health-monitor.ts.html +0 -727
  143. package/__tests__/coverage/src/core/orchestrator/index.html +0 -176
  144. package/__tests__/coverage/src/core/orchestrator/lifecycle-manager.ts.html +0 -874
  145. package/__tests__/coverage/src/core/orchestrator/session-manager.ts.html +0 -922
  146. package/__tests__/coverage/src/core/orchestrator/task-manager.ts.html +0 -1036
  147. package/__tests__/coverage/src/events/domain-events.ts.html +0 -1837
  148. package/__tests__/coverage/src/events/event-store.ts.html +0 -1849
  149. package/__tests__/coverage/src/events/example-usage.ts.html +0 -964
  150. package/__tests__/coverage/src/events/index.html +0 -176
  151. package/__tests__/coverage/src/events/projections.ts.html +0 -1768
  152. package/__tests__/coverage/src/events/state-reconstructor.ts.html +0 -1132
  153. package/__tests__/coverage/src/events.ts.html +0 -1186
  154. package/__tests__/coverage/src/hooks/example-usage.ts.html +0 -1582
  155. package/__tests__/coverage/src/hooks/executor.ts.html +0 -1222
  156. package/__tests__/coverage/src/hooks/index.html +0 -191
  157. package/__tests__/coverage/src/hooks/registry.ts.html +0 -1084
  158. package/__tests__/coverage/src/hooks/safety/bash-safety.ts.html +0 -1897
  159. package/__tests__/coverage/src/hooks/safety/file-organization.ts.html +0 -1504
  160. package/__tests__/coverage/src/hooks/safety/git-commit.ts.html +0 -1954
  161. package/__tests__/coverage/src/hooks/safety/index.html +0 -146
  162. package/__tests__/coverage/src/hooks/session-hooks.ts.html +0 -1762
  163. package/__tests__/coverage/src/hooks/task-hooks.ts.html +0 -1624
  164. package/__tests__/coverage/src/hooks/types.ts.html +0 -1156
  165. package/__tests__/coverage/src/index.html +0 -176
  166. package/__tests__/coverage/src/mcp/connection-pool.ts.html +0 -1399
  167. package/__tests__/coverage/src/mcp/index.html +0 -176
  168. package/__tests__/coverage/src/mcp/server.ts.html +0 -2407
  169. package/__tests__/coverage/src/mcp/session-manager.ts.html +0 -1369
  170. package/__tests__/coverage/src/mcp/tool-registry.ts.html +0 -1783
  171. package/__tests__/coverage/src/mcp/transport/http.ts.html +0 -1756
  172. package/__tests__/coverage/src/mcp/transport/index.html +0 -146
  173. package/__tests__/coverage/src/mcp/transport/stdio.ts.html +0 -1057
  174. package/__tests__/coverage/src/mcp/transport/websocket.ts.html +0 -1537
  175. package/__tests__/coverage/src/mcp/types.ts.html +0 -1780
  176. package/__tests__/coverage/src/plugin-interface.ts.html +0 -2074
  177. package/__tests__/coverage/src/plugin-loader.ts.html +0 -1999
  178. package/__tests__/coverage/src/plugin-registry.ts.html +0 -1897
  179. package/__tests__/coverage/src/plugins/official/hive-mind-plugin.ts.html +0 -1075
  180. package/__tests__/coverage/src/plugins/official/index.html +0 -131
  181. package/__tests__/coverage/src/plugins/official/maestro-plugin.ts.html +0 -1609
  182. package/__tests__/coverage/src/resilience/bulkhead.ts.html +0 -916
  183. package/__tests__/coverage/src/resilience/circuit-breaker.ts.html +0 -1063
  184. package/__tests__/coverage/src/resilience/index.html +0 -161
  185. package/__tests__/coverage/src/resilience/rate-limiter.ts.html +0 -1345
  186. package/__tests__/coverage/src/resilience/retry.ts.html +0 -757
  187. package/__tests__/coverage/src/security/index.html +0 -131
  188. package/__tests__/coverage/src/security/input-validation.ts.html +0 -880
  189. package/__tests__/coverage/src/security/secure-random.ts.html +0 -562
  190. package/__tests__/coverage/src/types/index.html +0 -131
  191. package/__tests__/coverage/src/types/swarm.types.ts.html +0 -850
  192. package/__tests__/coverage/src/types/task.types.ts.html +0 -700
  193. package/__tests__/coverage/src/types.ts.html +0 -1186
  194. package/__tests__/coverage/src/utils/index.html +0 -116
  195. package/__tests__/coverage/src/utils/secure-logger.ts.html +0 -856
@@ -0,0 +1,3504 @@
1
+ [2026-04-28T12:44:34.736Z] PROMPT
2
+ ============================================================
3
+ Analyze this codebase for performance optimizations:
4
+ - Identify N+1 query patterns
5
+ - Find unnecessary re-renders in React
6
+ - Suggest caching opportunities
7
+ - Identify memory leaks
8
+ - Find redundant computations
9
+
10
+ Provide actionable suggestions with code examples.
11
+
12
+ ## Codebase Context
13
+
14
+ --- src/core/config/defaults.ts ---
15
+ /**
16
+ * V3 Default Configuration Values
17
+ */
18
+
19
+ import type {
20
+ AgentConfig,
21
+ TaskConfig,
22
+ SwarmConfig,
23
+ MemoryConfig,
24
+ MCPServerConfig,
25
+ OrchestratorConfig,
26
+ SystemConfig,
27
+ } from './schema.js';
28
+
29
+ /**
30
+ * Default agent configuration
31
+ */
32
+ export const defaultAgentConfig: Partial<AgentConfig> = {
33
+ capabilities: [],
34
+ maxConcurrentTasks: 5,
35
+ priority: 50,
36
+ retryPolicy: {
37
+ maxRetries: 3,
38
+ backoffMs: 1000,
39
+ backoffMultiplier: 2,
40
+ },
41
+ };
42
+
43
+ /**
44
+ * Default task configuration
45
+ */
46
+ export const defaultTaskConfig: Partial<TaskConfig> = {
47
+ priority: 50,
48
+ metadata: {
49
+ maxRetries: 3,
50
+ },
51
+ };
52
+
53
+ /**
54
+ * Default swarm configuration (core version)
55
+ */
56
+ export const defaultSwarmConfigCore: SwarmConfig = {
57
+ topology: 'hierarchical-mesh',
58
+ maxAgents: 20,
59
+ autoScale: {
60
+ enabled: false,
61
+ minAgents: 1,
62
+ maxAgents: 20,
63
+ scaleUpThreshold: 0.8,
64
+ scaleDownThreshold: 0.3,
65
+ },
66
+ coordination: {
67
+ consensusRequired: false,
68
+ timeoutMs: 10000,
69
+ retryPolicy: {
70
+ maxRetries: 3,
71
+ backoffMs: 500,
72
+ },
73
+ },
74
+ communication: {
75
+ protocol: 'events',
76
+ batchSize: 10,
77
+ flushIntervalMs: 100,
78
+ },
79
+ };
80
+
81
+ /**
82
+ * Default memory configuration (hybrid backend - ADR-009)
83
+ */
84
+ export const defaultMemoryConfig: MemoryConfig = {
85
+ type: 'hybrid',
86
+ path: './data/memory',
87
+ sqlite: {
88
+ inMemory: false,
89
+ wal: true,
90
+ },
91
+ agentdb: {
92
+ dimensions: 1536,
93
+ indexType: 'hnsw',
94
+ efConstruction: 200,
95
+ m: 16,
96
+ quantization: 'none',
97
+ },
98
+ hybrid: {
99
+ vectorThreshold: 100,
100
+ },
101
+ };
102
+
103
+ /**
104
+ * Default MCP server configuration
105
+ */
106
+ export const defaultMCPServerConfig: MCPServerConfig = {
107
+ name: 'claude-flow',
108
+ version: '3.0.0',
109
+ transport: {
110
+ type: 'stdio',
111
+ },
112
+ capabilities: {
113
+ tools: true,
114
+ resources: true,
115
+ prompts: true,
116
+ logging: true,
117
+ },
118
+ };
119
+
120
+ /**
121
+ * Default orchestrator configuration
122
+ */
123
+ export const defaultOrchestratorConfig: OrchestratorConfig = {
124
+ session: {
125
+ persistSessions: true,
126
+ dataDir: './data',
127
+ sessionRetentionMs: 3600000, // 1 hour
128
+ },
129
+ health: {
130
+ checkInterval: 30000, // 30 seconds
131
+ historyLimit: 100,
132
+ degradedThreshold: 1,
133
+ unhealthyThreshold: 2,
134
+ },
135
+ lifecycle: {
136
+ maxConcurrentAgents: 20,
137
+ spawnTimeout: 30000, // 30 seconds
138
+ terminateTimeout: 10000, // 10 seconds
139
+ maxSpawnRetries: 3,
140
+ },
141
+ };
142
+
143
+ /**
144
+ * Default full system configuration
145
+ */
146
+ export const defaultSystemConfig: SystemConfig = {
147
+ orchestrator: defaultOrchestratorConfig,
148
+ memory: defaultMemoryConfig,
149
+ mcp: defaultMCPServerConfig,
150
+ swarm: defaultSwarmConfigCore,
151
+ };
152
+
153
+ /**
154
+ * Agent type presets
155
+ */
156
+ export const agentTypePresets: Record<string, Partial<AgentConfig>> = {
157
+ coder: {
158
+ type: 'coder',
159
+ capabilities: ['code', 'debug', 'refactor', 'test'],
160
+ maxConcurrentTasks: 3,
161
+ priority: 70,
162
+ },
163
+ reviewer: {
164
+ type: 'reviewer',
165
+ capabilities: ['review', 'analyze', 'suggest'],
166
+ maxConcurrentTasks: 5,
167
+ priority: 60,
168
+ },
169
+ tester: {
170
+ type: 'tester',
171
+ capabilities: ['test', 'validate', 'benchmark'],
172
+ maxConcurrentTasks: 4,
173
+ priority: 65,
174
+ },
175
+ researcher: {
176
+ type: 'researcher',
177
+ capabilities: ['research', 'analyze', 'summarize'],
178
+ maxConcurrentTasks: 3,
179
+ priority: 50,
180
+ },
181
+ planner: {
182
+ type: 'planner',
183
+ capabilities: ['plan', 'organize', 'decompose'],
184
+ maxConcurrentTasks: 2,
185
+ priority: 80,
186
+ },
187
+ architect: {
188
+ type: 'architect',
189
+ capabilities: ['design', 'architecture', 'patterns'],
190
+ maxConcurrentTasks: 2,
191
+ priority: 85,
192
+ },
193
+ coordinator: {
194
+ type: 'coordinator',
195
+ capabilities: ['coordinate', 'delegate', 'monitor'],
196
+ maxConcurrentTasks: 10,
197
+ priority: 90,
198
+ },
199
+ security: {
200
+ type: 'security',
201
+ capabilities: ['audit', 'scan', 'validate', 'secure'],
202
+ maxConcurrentTasks: 3,
203
+ priority: 95,
204
+ },
205
+ performance: {
206
+ type: 'performance',
207
+ capabilities: ['benchmark', 'optimize', 'profile'],
208
+ maxConcurrentTasks: 2,
209
+ priority: 70,
210
+ },
211
+ };
212
+
213
+ /**
214
+ * Get merged configuration with defaults
215
+ */
216
+ export function mergeWithDefaults<T extends Record<string, unknown>>(
217
+ config: Partial<T>,
218
+ defaults: T,
219
+ ): T {
220
+ return { ...defaults, ...config } as T;
221
+ }
222
+
223
+
224
+ --- src/core/config/index.ts ---
225
+ /**
226
+ * V3 Configuration - Public API
227
+ */
228
+
229
+ // Schemas
230
+ export * from './schema.js';
231
+
232
+ // Validation
233
+ export * from './validator.js';
234
+
235
+ // Defaults
236
+ export * from './defaults.js';
237
+
238
+ // Loader
239
+ export * from './loader.js';
240
+
241
+
242
+ --- src/core/config/loader.ts (truncated) ---
243
+ /**
244
+ * V3 Configuration Loader
245
+ * Load configuration from various sources
246
+ */
247
+
248
+ import { readFile } from 'fs/promises';
249
+ import { join, resolve } from 'path';
250
+ import { existsSync } from 'fs';
251
+ import type { SystemConfig } from './schema.js';
252
+ import { validateSystemConfig, type ValidationResult } from './validator.js';
253
+ import { defaultSystemConfig, mergeWithDefaults } from './defaults.js';
254
+
255
+ /**
256
+ * Configuration source type
257
+ */
258
+ export type ConfigSource = 'file' | 'env' | 'default' | 'merged';
259
+
260
+ /**
261
+ * Loaded configuration with metadata
262
+ */
263
+ export interface LoadedConfig {
264
+ config: SystemConfig;
265
+ source: ConfigSource;
266
+ path?: string;
267
+ warnings?: string[];
268
+ }
269
+
270
+ /**
271
+ * Configuration file names to search for
272
+ */
273
+ const CONFIG_FILE_NAMES = [
274
+ 'claude-flow.config.json',
275
+ 'claude-flow.config.js',
276
+ 'claude-flow.json',
277
+ '.claude-flow.json',
278
+ ];
279
+
280
+ /**
281
+ * Find configuration file in directory
282
+ */
283
+ async function findConfigFile(directory: string): Promise<string | null> {
284
+ for (const name of CONFIG_FILE_NAMES) {
285
+ const path = join(directory, name);
286
+ if (existsSync(path)) {
287
+ return path;
288
+ }
289
+ }
290
+ return null;
291
+ }
292
+
293
+ /**
294
+ * Load configuration from JSON file
295
+ */
296
+ async function loadJsonConfig(path: string): Promise<unknown> {
297
+ const content = await readFile(path, 'utf8');
298
+ return JSON.parse(content);
299
+ }
300
+
301
+ /**
302
+ * Load configuration from environment variables
303
+ */
304
+ function loadEnvConfig(): Partial<SystemConfig> {
305
+ const config: Partial<SystemConfig> = {};
306
+
307
+ // Orchestrator settings
308
+ if (process.env.CLAUDE_FLOW_MAX_AGENTS) {
309
+ config.orchestrator = {
310
+ ...defaultSystemConfig.orchestrator,
311
+ lifecycle: {
312
+ ...defaultSystemConfig.orchestrator.lifecycle,
313
+ maxConcurrentAgents: parseInt(process.env.CLAUDE_FLOW_MAX_AGENTS, 10),
314
+ },
315
+ };
316
+ }
317
+
318
+ // Data directory
319
+ if (process.env.CLAUDE_FLOW_DATA_DIR) {
320
+ config.orchestrator = {
321
+ ...config.orchestrator,
322
+ ...defaultSystemConfig.orchestrator,
323
+ session: {
324
+ ...defaultSystemConfig.orchestrator.session,
325
+ dataDir: process.env.CLAUDE_FLOW_DATA_DIR,
326
+ },
327
+ };
328
+ }
329
+
330
+ // Memory type
331
+ if (process.env.CLAUDE_FLOW_MEMORY_TYPE) {
332
+ const memoryType = process.env.CLAUDE_FLOW_MEMORY_TYPE as NonNullable<SystemConfig['memory']>['type'];
333
+ if (['sqlite', 'agentdb', 'hybrid', 'redis', 'memory'].includes(memoryType)) {
334
+ config.memory = {
335
+ ...(defaultSystemConfig.memory ?? { type: 'hybrid' }),
336
+ type: memoryType,
337
+ };
338
+ }
339
+ }
340
+
341
+ // MCP transport
342
+ const defaultMcp = defaultSystemConfig.mcp ?? { name: 'claude-flow', version: '3.0.0', transport: { type: 'stdio' as const } };
343
+ if (process.env.CLAUDE_FLOW_MCP_TRANSPORT) {
344
+ const transport = process.env.CLAUDE_FLOW_MCP_TRANSPORT as 'stdio' | 'http' | 'websocket';
345
+ if (['stdio', 'http', 'websocket'].includes(transport)) {
346
+ config.mcp = {
347
+ ...defaultMcp,
348
+ transport: {
349
+ ...defaultMcp.transport,
350
+ type: transport,
351
+ },
352
+ };
353
+ }
354
+ }
355
+
356
+ if (process.env.CLAUDE_FLOW_MCP_PORT) {
357
+ config.mcp = {
358
+ ...config.mcp,
359
+ ...defaultMcp,
360
+ transport: {
361
+ ...config.mcp?.transport,
362
+ ...defaultMcp.transport,
363
+ port: parseInt(process.env.CLAUDE_FLOW_MCP_PORT, 10),
364
+ },
365
+ };
366
+ }
367
+
368
+ // Swarm topology
369
+ const defaultSwarm = defaultSystemConfig.swarm ?? { topology: 'hierarchical-mesh' as const, maxAgents: 20 };
370
+ if (process.env.CLAUDE_FLOW_SWARM_TOPOLOGY) {
371
+ const topology = process.env.CLAUDE_FLOW_SWARM_TOPOLOGY as NonNullable<SystemConfig['swarm']>['topology'];
372
+ if (['hierarchical', 'mesh', 'ring', 'star', 'adaptive', 'hierarchical-mesh'].includes(topology)) {
373
+ config.swarm = {
374
+ ...defaultSwarm,
375
+ topology,
376
+ };
377
+ }
378
+ }
379
+
380
+ return config;
381
+ }
382
+
383
+ /**
384
+ * Configuration loader class
385
+ */
386
+ export class ConfigLoader {
387
+ private searchPaths: string[] = [];
388
+
389
+ constructor(additionalPaths?: string[]) {
390
+ // Default search paths
391
+ this.searchPaths = [
392
+ process.cwd(),
393
+ resolve(process.cwd(), '..'),
394
+ resolve(process.env.HOME ?? '', '.claude-flow'),
395
+ ];
396
+
397
+ if (additionalPaths) {
398
+ this.searchPaths.push(...additionalPaths);
399
+ }
400
+ }
401
+
402
+ /**
403
+ * Load configuration from all sources
404
+ */
405
+ async load(): Promise<LoadedConfig> {
406
+ const warnings: string[] = [];
407
+
408
+ // Start with defaults
409
+ let config: SystemConfig = { ...defaultSystemConfig };
410
+ let source: ConfigSource = 'default';
411
+ let path: string | undefined;
412
+
413
+ // Try to load from file
414
+ for (const searchPath of this.searchPaths) {
415
+ const configPath = await findConfigFile(searchPath);
416
+ if (configPath) {
417
+ try {
418
+ const fileConfig = await loadJsonConfig(configPath);
419
+ const validation = validateSystemConfig(fileConfig);
420
+
421
+ if (validation.success) {
422
+ config = mergeWithDefaults(validation.data!, defaultSystemConfig) as SystemConfig;
423
+ source = 'file';
424
+ path = configPath;
425
+ break;
426
+ } else {
427
+
428
+
429
+ --- src/core/config/schema.ts (truncated) ---
430
+ /**
431
+ * V3 Configuration Schemas
432
+ * Zod schemas for all configuration types
433
+ */
434
+
435
+ import { z } from 'zod';
436
+
437
+ /**
438
+ * Agent configuration schema
439
+ */
440
+ export const AgentConfigSchema = z.object({
441
+ id: z.string().min(1),
442
+ name: z.string().min(1),
443
+ type: z.string().min(1),
444
+ capabilities: z.array(z.string()).default([]),
445
+ maxConcurrentTasks: z.number().int().min(1).default(5),
446
+ priority: z.number().int().min(0).max(100).default(50),
447
+ timeout: z.number().int().positive().optional(),
448
+ retryPolicy: z.object({
449
+ maxRetries: z.number().int().min(0).default(3),
450
+ backoffMs: z.number().int().positive().default(1000),
451
+ backoffMultiplier: z.number().positive().default(2),
452
+ }).optional(),
453
+ resources: z.object({
454
+ maxMemoryMb: z.number().int().positive().optional(),
455
+ maxCpuPercent: z.number().min(0).max(100).optional(),
456
+ }).optional(),
457
+ metadata: z.record(z.unknown()).optional(),
458
+ });
459
+
460
+ /**
461
+ * Task configuration schema
462
+ */
463
+ export const TaskConfigSchema = z.object({
464
+ type: z.string().min(1),
465
+ description: z.string().min(1),
466
+ priority: z.number().int().min(0).max(100).default(50),
467
+ timeout: z.number().int().positive().optional(),
468
+ assignedAgent: z.string().optional(),
469
+ input: z.record(z.unknown()).optional(),
470
+ metadata: z.object({
471
+ requiredCapabilities: z.array(z.string()).optional(),
472
+ retryCount: z.number().int().min(0).optional(),
473
+ maxRetries: z.number().int().min(0).optional(),
474
+ critical: z.boolean().optional(),
475
+ parentTaskId: z.string().optional(),
476
+ childTaskIds: z.array(z.string()).optional(),
477
+ tags: z.array(z.string()).optional(),
478
+ }).optional(),
479
+ });
480
+
481
+ /**
482
+ * Swarm configuration schema
483
+ */
484
+ export const SwarmConfigSchema = z.object({
485
+ topology: z.enum(['hierarchical', 'mesh', 'ring', 'star', 'adaptive', 'hierarchical-mesh']),
486
+ maxAgents: z.number().int().positive().default(20),
487
+ autoScale: z.object({
488
+ enabled: z.boolean().default(false),
489
+ minAgents: z.number().int().min(0).default(1),
490
+ maxAgents: z.number().int().positive().default(20),
491
+ scaleUpThreshold: z.number().min(0).max(1).default(0.8),
492
+ scaleDownThreshold: z.number().min(0).max(1).default(0.3),
493
+ }).optional(),
494
+ coordination: z.object({
495
+ consensusRequired: z.boolean().default(false),
496
+ timeoutMs: z.number().int().positive().default(10000),
497
+ retryPolicy: z.object({
498
+ maxRetries: z.number().int().min(0).default(3),
499
+ backoffMs: z.number().int().positive().default(500),
500
+ }),
501
+ }).optional(),
502
+ communication: z.object({
503
+ protocol: z.enum(['events', 'messages', 'shared-memory']).default('events'),
504
+ batchSize: z.number().int().positive().default(10),
505
+ flushIntervalMs: z.number().int().positive().default(100),
506
+ }).optional(),
507
+ metadata: z.record(z.unknown()).optional(),
508
+ });
509
+
510
+ /**
511
+ * Memory configuration schema
512
+ */
513
+ export const MemoryConfigSchema = z.object({
514
+ type: z.enum(['sqlite', 'agentdb', 'hybrid', 'redis', 'memory']).default('hybrid'),
515
+ path: z.string().optional(),
516
+ maxSize: z.number().int().positive().optional(),
517
+ ttlMs: z.number().int().positive().optional(),
518
+ sqlite: z.object({
519
+ filename: z.string().optional(),
520
+ inMemory: z.boolean().default(false),
521
+ wal: z.boolean().default(true),
522
+ }).optional(),
523
+ agentdb: z.object({
524
+ dimensions: z.number().int().positive().default(1536),
525
+ indexType: z.enum(['hnsw', 'flat', 'ivf']).default('hnsw'),
526
+ efConstruction: z.number().int().positive().default(200),
527
+ m: z.number().int().positive().default(16),
528
+ quantization: z.enum(['none', 'scalar', 'product']).default('none'),
529
+ }).optional(),
530
+ redis: z.object({
531
+ host: z.string().default('localhost'),
532
+ port: z.number().int().positive().default(6379),
533
+ password: z.string().optional(),
534
+ db: z.number().int().min(0).default(0),
535
+ keyPrefix: z.string().default('claude-flow:'),
536
+ }).optional(),
537
+ hybrid: z.object({
538
+ vectorThreshold: z.number().int().positive().default(100),
539
+ }).optional(),
540
+ });
541
+
542
+ /**
543
+ * MCP server configuration schema
544
+ */
545
+ export const MCPServerConfigSchema = z.object({
546
+ name: z.string().min(1).default('claude-flow'),
547
+ version: z.string().min(1).default('3.0.0'),
548
+ transport: z.object({
549
+ type: z.enum(['stdio', 'http', 'websocket']).default('stdio'),
550
+ port: z.number().int().positive().optional(),
551
+ host: z.string().optional(),
552
+ path: z.string().optional(),
553
+ }),
554
+ capabilities: z.object({
555
+ tools: z.boolean().default(true),
556
+ resources: z.boolean().default(true),
557
+ prompts: z.boolean().default(true),
558
+ logging: z.boolean().default(true),
559
+ experimental: z.record(z.boolean()).optional(),
560
+ }).optional(),
561
+ });
562
+
563
+ /**
564
+ * Orchestrator configuration schema
565
+ */
566
+ export const OrchestratorConfigSchema = z.object({
567
+ session: z.object({
568
+ persistSessions: z.boolean().default(true),
569
+ dataDir: z.string().default('./data'),
570
+ sessionRetentionMs: z.number().int().positive().default(3600000),
571
+ }),
572
+ health: z.object({
573
+ checkInterval: z.number().int().positive().default(30000),
574
+ historyLimit: z.number().int().positive()
575
+
576
+ --- src/core/config/validator.ts ---
577
+ /**
578
+ * V3 Configuration Validator
579
+ * Validation logic using Zod schemas
580
+ */
581
+
582
+ import { z, type ZodError } from 'zod';
583
+ import {
584
+ AgentConfigSchema,
585
+ TaskConfigSchema,
586
+ SwarmConfigSchema,
587
+ MemoryConfigSchema,
588
+ MCPServerConfigSchema,
589
+ OrchestratorConfigSchema,
590
+ SystemConfigSchema,
591
+ type AgentConfig,
592
+ type TaskConfig,
593
+ type SwarmConfig,
594
+ type MemoryConfig,
595
+ type MCPServerConfig,
596
+ type OrchestratorConfig,
597
+ type SystemConfig,
598
+ } from './schema.js';
599
+
600
+ /**
601
+ * Validation result
602
+ */
603
+ export interface ValidationResult<T> {
604
+ success: boolean;
605
+ data?: T;
606
+ errors?: ValidationError[];
607
+ }
608
+
609
+ /**
610
+ * Validation error
611
+ */
612
+ export interface ValidationError {
613
+ path: string;
614
+ message: string;
615
+ code: string;
616
+ }
617
+
618
+ /**
619
+ * Convert Zod error to validation errors
620
+ */
621
+ function zodErrorToValidationErrors(error: ZodError): ValidationError[] {
622
+ return error.errors.map((e) => ({
623
+ path: e.path.join('.'),
624
+ message: e.message,
625
+ code: e.code,
626
+ }));
627
+ }
628
+
629
+ /**
630
+ * Generic validation function
631
+ * Uses parse + try/catch to get output types with defaults applied
632
+ */
633
+ function validate<TInput, TOutput>(
634
+ schema: z.ZodType<TOutput, z.ZodTypeDef, TInput>,
635
+ data: unknown
636
+ ): ValidationResult<TOutput> {
637
+ try {
638
+ const parsed = schema.parse(data);
639
+ return {
640
+ success: true,
641
+ data: parsed,
642
+ };
643
+ } catch (error) {
644
+ if (error instanceof z.ZodError) {
645
+ return {
646
+ success: false,
647
+ errors: zodErrorToValidationErrors(error),
648
+ };
649
+ }
650
+ throw error;
651
+ }
652
+ }
653
+
654
+ /**
655
+ * Validate agent configuration
656
+ */
657
+ export function validateAgentConfig(data: unknown): ValidationResult<AgentConfig> {
658
+ return validate(AgentConfigSchema, data);
659
+ }
660
+
661
+ /**
662
+ * Validate task configuration
663
+ */
664
+ export function validateTaskConfig(data: unknown): ValidationResult<TaskConfig> {
665
+ return validate(TaskConfigSchema, data);
666
+ }
667
+
668
+ /**
669
+ * Validate swarm configuration
670
+ */
671
+ export function validateSwarmConfig(data: unknown): ValidationResult<SwarmConfig> {
672
+ return validate(SwarmConfigSchema, data);
673
+ }
674
+
675
+ /**
676
+ * Validate memory configuration
677
+ */
678
+ export function validateMemoryConfig(data: unknown): ValidationResult<MemoryConfig> {
679
+ return validate(MemoryConfigSchema, data);
680
+ }
681
+
682
+ /**
683
+ * Validate MCP server configuration
684
+ */
685
+ export function validateMCPServerConfig(data: unknown): ValidationResult<MCPServerConfig> {
686
+ return validate(MCPServerConfigSchema, data);
687
+ }
688
+
689
+ /**
690
+ * Validate orchestrator configuration
691
+ */
692
+ export function validateOrchestratorConfig(data: unknown): ValidationResult<OrchestratorConfig> {
693
+ return validate(OrchestratorConfigSchema, data);
694
+ }
695
+
696
+ /**
697
+ * Validate full system configuration
698
+ */
699
+ export function validateSystemConfig(data: unknown): ValidationResult<SystemConfig> {
700
+ return validate(SystemConfigSchema, data);
701
+ }
702
+
703
+ /**
704
+ * Configuration validator class
705
+ */
706
+ export class ConfigValidator {
707
+ /**
708
+ * Validate and throw on error
709
+ */
710
+ static validateOrThrow<TInput, TOutput>(
711
+ schema: z.ZodType<TOutput, z.ZodTypeDef, TInput>,
712
+ data: unknown,
713
+ configName: string
714
+ ): TOutput {
715
+ const result = validate(schema, data);
716
+
717
+ if (!result.success) {
718
+ const errorMessages = result.errors
719
+ ?.map((e) => ` - ${e.path}: ${e.message}`)
720
+ .join('\n');
721
+ throw new Error(`Invalid ${configName} configuration:\n${errorMessages}`);
722
+ }
723
+
724
+ return result.data!;
725
+ }
726
+
727
+ /**
728
+ * Validate agent config or throw
729
+ */
730
+ static validateAgentOrThrow(data: unknown): AgentConfig {
731
+ return this.validateOrThrow(AgentConfigSchema, data, 'agent');
732
+ }
733
+
734
+ /**
735
+ * Validate task config or throw
736
+ */
737
+ static validateTaskOrThrow(data: unknown): TaskConfig {
738
+ return this.validateOrThrow(TaskConfigSchema, data, 'task');
739
+ }
740
+
741
+ /**
742
+ * Validate swarm config or throw
743
+ */
744
+ static validateSwarmOrThrow(data: unknown): SwarmConfig {
745
+ return this.validateOrThrow(SwarmConfigSchema, data, 'swarm');
746
+ }
747
+
748
+ /**
749
+ * Validate memory config or throw
750
+ */
751
+ static validateMemoryOrThrow(data: unknown): MemoryConfig {
752
+ return this.validateOrThrow(MemoryConfigSchema, data, 'memory');
753
+ }
754
+
755
+ /**
756
+ * Validate MCP server config or throw
757
+ */
758
+ static validateMCPServerOrThrow(data: unknown): MCPServerConfig {
759
+ return this.validateOrThrow(MCPServerConfigSchema, data, 'MCP server');
760
+ }
761
+
762
+ /**
763
+ * Validate orchestrator config or throw
764
+ */
765
+ static validateOrchestratorOrThrow(data: unknown): OrchestratorConfig {
766
+ return this.validateOrThrow(OrchestratorConfigSchema, data, 'orchestrator');
767
+ }
768
+
769
+ /**
770
+ * Validate system config or throw
771
+ */
772
+ static validateSystemOrThrow(data: unknown): SystemConfig {
773
+ return this.validateOrThrow(SystemConfigSchema, data, 'system');
774
+ }
775
+
776
+ /**
777
+ * Check if data matches schema
778
+ */
779
+ static isValid<TInput, TOutput>(
780
+ schema: z.ZodType<TOutput, z.ZodTypeDef, TInput>,
781
+ data: unknown
782
+ ): boolean {
783
+ return validate(schema, data).success;
784
+ }
785
+ }
786
+
787
+
788
+ --- src/core/event-bus.ts (truncated) ---
789
+ /**
790
+ * V3 Event Bus
791
+ * Core event pub/sub implementation
792
+ */
793
+
794
+ import type {
795
+ IEvent,
796
+ IEventBus,
797
+ IEventCreate,
798
+ IEventHandler,
799
+ IEventSubscription,
800
+ IEventFilter,
801
+ } from './interfaces/event.interface.js';
802
+ import { randomBytes } from 'crypto';
803
+
804
+ // Secure event ID generation
805
+ function generateSecureEventId(): string {
806
+ const timestamp = Date.now().toString(36);
807
+ const random = randomBytes(12).toString('hex');
808
+ return `evt_${timestamp}_${random}`;
809
+ }
810
+
811
+ /**
812
+ * Event subscription implementation
813
+ */
814
+ class EventSubscription implements IEventSubscription {
815
+ private active = true;
816
+ private paused = false;
817
+
818
+ constructor(
819
+ readonly id: string,
820
+ readonly filter: IEventFilter,
821
+ private removeCallback: () => void,
822
+ ) {}
823
+
824
+ unsubscribe(): void {
825
+ this.active = false;
826
+ this.removeCallback();
827
+ }
828
+
829
+ pause(): void {
830
+ this.paused = true;
831
+ }
832
+
833
+ resume(): void {
834
+ this.paused = false;
835
+ }
836
+
837
+ isActive(): boolean {
838
+ return this.active && !this.paused;
839
+ }
840
+ }
841
+
842
+ /**
843
+ * Event bus implementation
844
+ */
845
+ export class EventBus implements IEventBus {
846
+ private handlers = new Map<string, Set<IEventHandler>>();
847
+ private subscriptions = new Map<string, { filter: IEventFilter; handler: IEventHandler; subscription: EventSubscription }>();
848
+ private subscriptionId = 0;
849
+
850
+ emit<T = unknown>(type: string, payload: T, options?: Partial<IEventCreate<T>>): void {
851
+ const event = this.createEvent(type, payload, options);
852
+ this.dispatchEvent(event);
853
+ }
854
+
855
+ async emitAsync<T = unknown>(type: string, payload: T, options?: Partial<IEventCreate<T>>): Promise<void> {
856
+ const event = this.createEvent(type, payload, options);
857
+ await this.dispatchEventAsync(event);
858
+ }
859
+
860
+ on<T = unknown>(type: string, handler: IEventHandler<T>): IEventSubscription {
861
+ return this.subscribe({ types: [type] }, handler);
862
+ }
863
+
864
+ subscribe<T = unknown>(filter: IEventFilter, handler: IEventHandler<T>): IEventSubscription {
865
+ const id = `sub_${++this.subscriptionId}`;
866
+
867
+ // Register for all matching types
868
+ const types = filter.types ?? ['*'];
869
+ for (const type of types) {
870
+ let handlers = this.handlers.get(type);
871
+ if (!handlers) {
872
+ handlers = new Set();
873
+ this.handlers.set(type, handlers);
874
+ }
875
+ handlers.add(handler as IEventHandler);
876
+ }
877
+
878
+ const subscription = new EventSubscription(id, filter, () => {
879
+ this.removeSubscription(id);
880
+ });
881
+
882
+ this.subscriptions.set(id, { filter, handler: handler as IEventHandler, subscription });
883
+
884
+ return subscription;
885
+ }
886
+
887
+ once<T = unknown>(type: string, handler: IEventHandler<T>): IEventSubscription {
888
+ const wrappedHandler: IEventHandler<T> = async (event) => {
889
+ subscription.unsubscribe();
890
+ await handler(event);
891
+ };
892
+
893
+ const subscription = this.on(type, wrappedHandler);
894
+ return subscription;
895
+ }
896
+
897
+ off(type: string, handler: IEventHandler): void {
898
+ const handlers = this.handlers.get(type);
899
+ if (handlers) {
900
+ handlers.delete(handler);
901
+ if (handlers.size === 0) {
902
+ this.handlers.delete(type);
903
+ }
904
+ }
905
+ }
906
+
907
+ removeAllListeners(type?: string): void {
908
+ if (type) {
909
+ this.handlers.delete(type);
910
+ } else {
911
+ this.handlers.clear();
912
+ }
913
+ }
914
+
915
+ listenerCount(type: string): number {
916
+ return this.handlers.get(type)?.size ?? 0;
917
+ }
918
+
919
+ eventNames(): string[] {
920
+ return Array.from(this.handlers.keys());
921
+ }
922
+
923
+ private createEvent<T>(type: string, payload: T, options?: Partial<IEventCreate<T>>): IEvent<T> {
924
+ return {
925
+ id: generateSecureEventId(),
926
+ type,
927
+ timestamp: new Date(),
928
+ source: options?.source ?? 'event-bus',
929
+ payload,
930
+ priority: options?.priority,
931
+ correlationId: options?.correlationId,
932
+ causationId: options?.causationId,
933
+ metadata: options?.metadata,
934
+ };
935
+ }
936
+
937
+ private dispatchEvent<T>(event: IEvent<T>): void {
938
+ // Get handlers for specific type
939
+ const typeHandlers = this.handlers.get(event.type);
940
+
941
+ // Get wildcard handlers
942
+ const wildcardHandlers = this.handlers.get('*');
943
+
944
+ const allHandlers = new Set<IEventHandler>();
945
+
946
+ if (typeHandlers) {
947
+ for (const handler of typeHandlers) {
948
+ allHandlers.add(handler);
949
+ }
950
+ }
951
+
952
+ if (wildcardHandlers) {
953
+ for (const handler of wildcardHandlers) {
954
+ allHandlers.add(handler);
955
+ }
956
+ }
957
+
958
+ for (const handler of allHandlers) {
959
+ try {
960
+ const result = handler(event);
961
+ if (result instanceof Promise) {
962
+ result.catch((error) => {
963
+ console.error(`Error in async event handler for ${event.type}:`, error);
964
+ });
965
+ }
966
+ } catch (error) {
967
+ console.error(`Error in event handler for ${event.type}:`, error);
968
+ }
969
+ }
970
+ }
971
+
972
+ private async dispatchEventAsync<T>(event: IEvent<T>): Promise<void> {
973
+ const typeHandlers = this.handlers.get(event.type);
974
+ const wildcardHandlers = this.handlers.get('*');
975
+
976
+ const allHandlers = new Set<IEventHandler>();
977
+
978
+ if (typeHandlers) {
979
+ for (const handler
980
+
981
+ --- src/core/index.ts ---
982
+ /**
983
+ * V3 Core Module - Public API
984
+ * Domain-Driven Design with Clean Architecture
985
+ *
986
+ * This module provides the core architecture for claude-flow v3:
987
+ * - Decomposed orchestrator (task, session, health, lifecycle management)
988
+ * - Event-driven architecture with event bus and coordinator
989
+ * - Type-safe configuration with Zod validation
990
+ * - Clean interfaces following DDD principles
991
+ */
992
+
993
+ // Interfaces (Domain contracts)
994
+ export * from './interfaces/index.js';
995
+
996
+ // Event system
997
+ export { EventBus, createEventBus } from './event-bus.js';
998
+
999
+ // Orchestrator components (decomposed)
1000
+ export * from './orchestrator/index.js';
1001
+
1002
+ // Configuration
1003
+ export * from './config/index.js';
1004
+
1005
+
1006
+ --- src/core/interfaces/agent.interface.ts ---
1007
+ /**
1008
+ * V3 Agent Interfaces
1009
+ * Domain-Driven Design - Agent Lifecycle Bounded Context
1010
+ */
1011
+
1012
+ /**
1013
+ * Agent status in the system
1014
+ */
1015
+ export type AgentStatus = 'spawning' | 'active' | 'idle' | 'busy' | 'error' | 'terminated';
1016
+
1017
+ /**
1018
+ * Agent type classification
1019
+ */
1020
+ export type AgentType =
1021
+ | 'coder'
1022
+ | 'reviewer'
1023
+ | 'tester'
1024
+ | 'researcher'
1025
+ | 'planner'
1026
+ | 'architect'
1027
+ | 'coordinator'
1028
+ | 'security'
1029
+ | 'performance'
1030
+ | 'custom';
1031
+
1032
+ /**
1033
+ * Agent capability declaration
1034
+ */
1035
+ export interface IAgentCapability {
1036
+ name: string;
1037
+ level: 'basic' | 'intermediate' | 'advanced' | 'expert';
1038
+ description?: string;
1039
+ }
1040
+
1041
+ /**
1042
+ * Agent configuration for spawning
1043
+ */
1044
+ export interface IAgentConfig {
1045
+ readonly id: string;
1046
+ readonly name: string;
1047
+ readonly type: AgentType | string;
1048
+
1049
+ capabilities: string[];
1050
+ maxConcurrentTasks: number;
1051
+ priority: number;
1052
+
1053
+ timeout?: number;
1054
+ retryPolicy?: {
1055
+ maxRetries: number;
1056
+ backoffMs: number;
1057
+ backoffMultiplier: number;
1058
+ };
1059
+
1060
+ resources?: {
1061
+ maxMemoryMb?: number;
1062
+ maxCpuPercent?: number;
1063
+ };
1064
+
1065
+ metadata?: Record<string, unknown>;
1066
+ }
1067
+
1068
+ /**
1069
+ * Core agent entity
1070
+ */
1071
+ export interface IAgent {
1072
+ readonly id: string;
1073
+ readonly name: string;
1074
+ readonly type: AgentType | string;
1075
+ readonly config: IAgentConfig;
1076
+ readonly createdAt: Date;
1077
+
1078
+ status: AgentStatus;
1079
+ currentTaskCount: number;
1080
+ lastActivity: Date;
1081
+
1082
+ sessionId?: string;
1083
+ terminalId?: string;
1084
+ memoryBankId?: string;
1085
+
1086
+ metrics?: {
1087
+ tasksCompleted: number;
1088
+ tasksFailed: number;
1089
+ avgTaskDuration: number;
1090
+ errorCount: number;
1091
+ uptime: number;
1092
+ };
1093
+
1094
+ health?: {
1095
+ status: 'healthy' | 'degraded' | 'unhealthy';
1096
+ lastCheck: Date;
1097
+ issues?: string[];
1098
+ };
1099
+ }
1100
+
1101
+ /**
1102
+ * Agent session for tracking active work
1103
+ */
1104
+ export interface IAgentSession {
1105
+ readonly id: string;
1106
+ readonly agentId: string;
1107
+ readonly startTime: Date;
1108
+
1109
+ status: 'active' | 'idle' | 'terminated';
1110
+ terminalId: string;
1111
+ memoryBankId: string;
1112
+
1113
+ lastActivity: Date;
1114
+ endTime?: Date;
1115
+
1116
+ metadata?: Record<string, unknown>;
1117
+ }
1118
+
1119
+ /**
1120
+ * Agent pool for managing multiple agents
1121
+ */
1122
+ export interface IAgentPool {
1123
+ /**
1124
+ * Add an agent to the pool
1125
+ */
1126
+ add(agent: IAgent): void;
1127
+
1128
+ /**
1129
+ * Remove an agent from the pool
1130
+ */
1131
+ remove(agentId: string): boolean;
1132
+
1133
+ /**
1134
+ * Get an agent by ID
1135
+ */
1136
+ get(agentId: string): IAgent | undefined;
1137
+
1138
+ /**
1139
+ * Get all agents in the pool
1140
+ */
1141
+ getAll(): IAgent[];
1142
+
1143
+ /**
1144
+ * Get agents by status
1145
+ */
1146
+ getByStatus(status: AgentStatus): IAgent[];
1147
+
1148
+ /**
1149
+ * Get agents by type
1150
+ */
1151
+ getByType(type: AgentType | string): IAgent[];
1152
+
1153
+ /**
1154
+ * Get available agents (can accept more tasks)
1155
+ */
1156
+ getAvailable(): IAgent[];
1157
+
1158
+ /**
1159
+ * Get pool size
1160
+ */
1161
+ size(): number;
1162
+
1163
+ /**
1164
+ * Check if pool has capacity
1165
+ */
1166
+ hasCapacity(maxSize: number): boolean;
1167
+
1168
+ /**
1169
+ * Clear all agents
1170
+ */
1171
+ clear(): void;
1172
+ }
1173
+
1174
+ /**
1175
+ * Agent lifecycle manager interface
1176
+ */
1177
+ export interface IAgentLifecycleManager {
1178
+ /**
1179
+ * Spawn a new agent
1180
+ */
1181
+ spawn(config: IAgentConfig): Promise<IAgent>;
1182
+
1183
+ /**
1184
+ * Spawn multiple agents in parallel
1185
+ */
1186
+ spawnBatch(configs: IAgentConfig[]): Promise<Map<string, IAgent>>;
1187
+
1188
+ /**
1189
+ * Terminate an agent
1190
+ */
1191
+ terminate(agentId: string, reason?: string): Promise<void>;
1192
+
1193
+ /**
1194
+ * Terminate all agents
1195
+ */
1196
+ terminateAll(reason?: string): Promise<void>;
1197
+
1198
+ /**
1199
+ * Restart an agent
1200
+ */
1201
+ restart(agentId: string): Promise<IAgent>;
1202
+
1203
+ /**
1204
+ * Update agent configuration
1205
+ */
1206
+ updateConfig(agentId: string, config: Partial<IAgentConfig>): Promise<void>;
1207
+
1208
+ /**
1209
+ * Get agent by ID
1210
+ */
1211
+ getAgent(agentId: string): IAgent | undefined;
1212
+
1213
+ /**
1214
+ * Get all agents
1215
+ */
1216
+ getAllAgents(): IAgent[];
1217
+
1218
+ /**
1219
+ * Get active agents count
1220
+ */
1221
+ getActiveCount(): number;
1222
+
1223
+ /**
1224
+ * Check agent health
1225
+ */
1226
+ checkHealth(agentId: string): Promise<IAgent['health']>;
1227
+ }
1228
+
1229
+ /**
1230
+ * Agent registry for type definitions
1231
+ */
1232
+ export interface IAgentRegistry {
1233
+ /**
1234
+ * Register an agent type with default config
1235
+ */
1236
+ register(type: string, defaultConfig: Partial<IAgentConfig>): void;
1237
+
1238
+ /**
1239
+ * Unregister an agent type
1240
+ */
1241
+ unregister(type: string): boolean;
1242
+
1243
+ /**
1244
+ * Get default config for a type
1245
+ */
1246
+ getDefaultConfig(type: string): Partial<IAgentConfig> | undefined;
1247
+
1248
+ /**
1249
+ * Get all registered types
1250
+ */
1251
+ getRegisteredTypes(): string[];
1252
+
1253
+ /**
1254
+ * Check if a type is registered
1255
+ */
1256
+ isRegistered(type: string): boolean;
1257
+ }
1258
+
1259
+
1260
+ --- src/core/interfaces/coordinator.interface.ts (truncated) ---
1261
+ /**
1262
+ * V3 Coordinator Interfaces
1263
+ * Domain-Driven Design - Coordination Bounded Context
1264
+ * Aligned with ADR-003 (Single Coordination Engine)
1265
+ */
1266
+
1267
+ import type { ITask, ITaskResult } from './task.interface.js';
1268
+ import type { IAgent, IAgentConfig } from './agent.interface.js';
1269
+
1270
+ /**
1271
+ * Swarm topology types
1272
+ */
1273
+ export type SwarmTopology =
1274
+ | 'hierarchical'
1275
+ | 'mesh'
1276
+ | 'ring'
1277
+ | 'star'
1278
+ | 'adaptive'
1279
+ | 'hierarchical-mesh';
1280
+
1281
+ /**
1282
+ * Coordination status
1283
+ */
1284
+ export type CoordinationStatus =
1285
+ | 'initializing'
1286
+ | 'ready'
1287
+ | 'coordinating'
1288
+ | 'degraded'
1289
+ | 'error'
1290
+ | 'shutdown';
1291
+
1292
+ /**
1293
+ * Swarm configuration
1294
+ */
1295
+ export interface ISwarmConfig {
1296
+ topology: SwarmTopology;
1297
+ maxAgents: number;
1298
+
1299
+ autoScale?: {
1300
+ enabled: boolean;
1301
+ minAgents: number;
1302
+ maxAgents: number;
1303
+ scaleUpThreshold: number;
1304
+ scaleDownThreshold: number;
1305
+ };
1306
+
1307
+ coordination?: {
1308
+ consensusRequired: boolean;
1309
+ timeoutMs: number;
1310
+ retryPolicy: {
1311
+ maxRetries: number;
1312
+ backoffMs: number;
1313
+ };
1314
+ };
1315
+
1316
+ communication?: {
1317
+ protocol: 'events' | 'messages' | 'shared-memory';
1318
+ batchSize: number;
1319
+ flushIntervalMs: number;
1320
+ };
1321
+
1322
+ metadata?: Record<string, unknown>;
1323
+ }
1324
+
1325
+ /**
1326
+ * Swarm state
1327
+ */
1328
+ export interface ISwarmState {
1329
+ readonly id: string;
1330
+ readonly topology: SwarmTopology;
1331
+ readonly createdAt: Date;
1332
+
1333
+ status: CoordinationStatus;
1334
+ agentCount: number;
1335
+ taskCount: number;
1336
+
1337
+ metrics?: {
1338
+ throughput: number;
1339
+ latencyMs: number;
1340
+ successRate: number;
1341
+ resourceUtilization: number;
1342
+ };
1343
+ }
1344
+
1345
+ /**
1346
+ * Coordinator interface - unified coordination engine
1347
+ */
1348
+ export interface ICoordinator {
1349
+ /**
1350
+ * Initialize the coordinator
1351
+ */
1352
+ initialize(): Promise<void>;
1353
+
1354
+ /**
1355
+ * Shutdown the coordinator
1356
+ */
1357
+ shutdown(): Promise<void>;
1358
+
1359
+ /**
1360
+ * Initialize a swarm with configuration
1361
+ */
1362
+ initializeSwarm(config: ISwarmConfig): Promise<ISwarmState>;
1363
+
1364
+ /**
1365
+ * Get swarm state
1366
+ */
1367
+ getSwarmState(): ISwarmState | undefined;
1368
+
1369
+ /**
1370
+ * Assign a task to an agent
1371
+ */
1372
+ assignTask(task: ITask, agentId: string): Promise<void>;
1373
+
1374
+ /**
1375
+ * Get tasks assigned to an agent
1376
+ */
1377
+ getAgentTasks(agentId: string): Promise<ITask[]>;
1378
+
1379
+ /**
1380
+ * Get task count for an agent
1381
+ */
1382
+ getAgentTaskCount(agentId: string): Promise<number>;
1383
+
1384
+ /**
1385
+ * Cancel a task
1386
+ */
1387
+ cancelTask(taskId: string): Promise<void>;
1388
+
1389
+ /**
1390
+ * Report task completion
1391
+ */
1392
+ reportTaskComplete(taskId: string, result: ITaskResult): Promise<void>;
1393
+
1394
+ /**
1395
+ * Get coordination health status
1396
+ */
1397
+ getHealthStatus(): Promise<{ healthy: boolean; error?: string; metrics?: Record<string, number> }>;
1398
+
1399
+ /**
1400
+ * Perform maintenance tasks
1401
+ */
1402
+ performMaintenance(): Promise<void>;
1403
+ }
1404
+
1405
+ /**
1406
+ * Coordination manager interface - higher-level orchestration
1407
+ */
1408
+ export interface ICoordinationManager extends ICoordinator {
1409
+ /**
1410
+ * Register an agent with the coordinator
1411
+ */
1412
+ registerAgent(agent: IAgent): Promise<void>;
1413
+
1414
+ /**
1415
+ * Unregister an agent
1416
+ */
1417
+ unregisterAgent(agentId: string): Promise<void>;
1418
+
1419
+ /**
1420
+ * Get all registered agents
1421
+ */
1422
+ getRegisteredAgents(): IAgent[];
1423
+
1424
+ /**
1425
+ * Request agent consensus on a decision
1426
+ */
1427
+ requestConsensus(topic: string, options: unknown[], timeout?: number): Promise<unknown>;
1428
+
1429
+ /**
1430
+ * Broadcast message to all agents
1431
+ */
1432
+ broadcast(message: unknown): Promise<void>;
1433
+
1434
+ /**
1435
+ * Send message to specific agent
1436
+ */
1437
+ sendToAgent(agentId: string, message: unknown): Promise<void>;
1438
+
1439
+ /**
1440
+ * Acquire a distributed lock
1441
+ */
1442
+ acquireLock(resourceId: string, agentId: string, timeout?: number): Promise<boolean>;
1443
+
1444
+ /**
1445
+ * Release a distributed lock
1446
+ */
1447
+ releaseLock(resourceId: string, agentId: string): Promise<void>;
1448
+
1449
+ /**
1450
+ * Check for deadlocks
1451
+ */
1452
+ detectDeadlocks(): Promise<{ detected: boolean; agents?: string[]; resources?: string[] }>;
1453
+ }
1454
+
1455
+ /**
1456
+ * Health status for components
1457
+ */
1458
+ export interface IHealthStatus {
1459
+ status: 'healthy' | 'degraded' | 'unhealthy';
1460
+ components: Record<string, IComponentHealth>;
1461
+ timestamp: Date;
1462
+ }
1463
+
1464
+ /**
1465
+ * Component health details
1466
+ */
1467
+ export interface IComponentHealth {
1468
+ name: string;
1469
+ status: 'healthy' | 'degraded' | 'unhealthy';
1470
+ lastCheck: Date;
1471
+ error?: string;
1472
+ metrics?: Record<string, number>;
1473
+ }
1474
+
1475
+ /**
1476
+ * Health monitor interface
1477
+ */
1478
+ export interface IHealthMonitor {
1479
+ /**
1480
+ * Start health monitoring
1481
+ */
1482
+ start(): void;
1483
+
1484
+ /**
1485
+ * Stop health monitoring
1486
+ */
1487
+ stop(): void;
1488
+
1489
+ /**
1490
+ * Get current health status
1491
+ */
1492
+ getStatus(): Promise<IHealthStatus>;
1493
+
1494
+ /**
1495
+ * Register a health check
1496
+ */
1497
+ registerCheck(
1498
+ name: string,
1499
+ check: () => Promise<{ healthy: boolean; error?: string; metrics?: Record<string, number> }>
1500
+ ): void;
1501
+
1502
+ /**
1503
+ * Unregister a health check
1504
+ */
1505
+ unregisterCheck(name: string): void;
1506
+
1507
+ /**
1508
+ * Get health history
1509
+ */
1510
+ getHistory(limit?: number): IHealthStatus[];
1511
+
1512
+ /**
1513
+ * Subscribe to health changes
1514
+ */
1515
+ onHealthChange(callback: (status: IHealthStatus) => void): () => void;
1516
+ }
1517
+
1518
+ /**
1519
+ * Metrics co
1520
+
1521
+ --- src/core/interfaces/event.interface.ts (truncated) ---
1522
+ /**
1523
+ * V3 Event Interfaces
1524
+ * Domain-Driven Design - Event Sourcing Pattern (ADR-007)
1525
+ */
1526
+
1527
+ /**
1528
+ * Event priority levels
1529
+ */
1530
+ export type EventPriority = 'critical' | 'high' | 'normal' | 'low';
1531
+
1532
+ /**
1533
+ * Core event structure
1534
+ */
1535
+ export interface IEvent<T = unknown> {
1536
+ readonly id: string;
1537
+ readonly type: string;
1538
+ readonly timestamp: Date;
1539
+ readonly source: string;
1540
+
1541
+ payload: T;
1542
+ priority?: EventPriority;
1543
+ correlationId?: string;
1544
+ causationId?: string;
1545
+
1546
+ metadata?: {
1547
+ version?: number;
1548
+ userId?: string;
1549
+ sessionId?: string;
1550
+ [key: string]: unknown;
1551
+ };
1552
+ }
1553
+
1554
+ /**
1555
+ * Event creation parameters
1556
+ */
1557
+ export interface IEventCreate<T = unknown> {
1558
+ type: string;
1559
+ payload: T;
1560
+ source?: string;
1561
+ priority?: EventPriority;
1562
+ correlationId?: string;
1563
+ causationId?: string;
1564
+ metadata?: IEvent['metadata'];
1565
+ }
1566
+
1567
+ /**
1568
+ * Event handler function type
1569
+ */
1570
+ export type IEventHandler<T = unknown> = (event: IEvent<T>) => void | Promise<void>;
1571
+
1572
+ /**
1573
+ * Event filter for subscriptions
1574
+ */
1575
+ export interface IEventFilter {
1576
+ types?: string[];
1577
+ sources?: string[];
1578
+ priority?: EventPriority[];
1579
+ correlationId?: string;
1580
+ }
1581
+
1582
+ /**
1583
+ * Event subscription handle
1584
+ */
1585
+ export interface IEventSubscription {
1586
+ readonly id: string;
1587
+ readonly filter: IEventFilter;
1588
+
1589
+ /**
1590
+ * Unsubscribe from events
1591
+ */
1592
+ unsubscribe(): void;
1593
+
1594
+ /**
1595
+ * Pause subscription
1596
+ */
1597
+ pause(): void;
1598
+
1599
+ /**
1600
+ * Resume subscription
1601
+ */
1602
+ resume(): void;
1603
+
1604
+ /**
1605
+ * Check if subscription is active
1606
+ */
1607
+ isActive(): boolean;
1608
+ }
1609
+
1610
+ /**
1611
+ * Event bus interface for pub/sub communication
1612
+ */
1613
+ export interface IEventBus {
1614
+ /**
1615
+ * Emit an event to all subscribers
1616
+ */
1617
+ emit<T = unknown>(type: string, payload: T, options?: Partial<IEventCreate<T>>): void;
1618
+
1619
+ /**
1620
+ * Emit an event and wait for all handlers
1621
+ */
1622
+ emitAsync<T = unknown>(type: string, payload: T, options?: Partial<IEventCreate<T>>): Promise<void>;
1623
+
1624
+ /**
1625
+ * Subscribe to events matching a type pattern
1626
+ */
1627
+ on<T = unknown>(type: string, handler: IEventHandler<T>): IEventSubscription;
1628
+
1629
+ /**
1630
+ * Subscribe to events with filter
1631
+ */
1632
+ subscribe<T = unknown>(filter: IEventFilter, handler: IEventHandler<T>): IEventSubscription;
1633
+
1634
+ /**
1635
+ * Subscribe to a single event occurrence
1636
+ */
1637
+ once<T = unknown>(type: string, handler: IEventHandler<T>): IEventSubscription;
1638
+
1639
+ /**
1640
+ * Remove a specific handler
1641
+ */
1642
+ off(type: string, handler: IEventHandler): void;
1643
+
1644
+ /**
1645
+ * Remove all handlers for a type
1646
+ */
1647
+ removeAllListeners(type?: string): void;
1648
+
1649
+ /**
1650
+ * Get count of listeners for a type
1651
+ */
1652
+ listenerCount(type: string): number;
1653
+
1654
+ /**
1655
+ * Get all event types with active listeners
1656
+ */
1657
+ eventNames(): string[];
1658
+ }
1659
+
1660
+ /**
1661
+ * System event types enumeration
1662
+ */
1663
+ export const SystemEventTypes = {
1664
+ // System lifecycle
1665
+ SYSTEM_READY: 'system:ready',
1666
+ SYSTEM_SHUTDOWN: 'system:shutdown',
1667
+ SYSTEM_ERROR: 'system:error',
1668
+ SYSTEM_HEALTHCHECK: 'system:healthcheck',
1669
+
1670
+ // Agent lifecycle
1671
+ AGENT_SPAWNED: 'agent:spawned',
1672
+ AGENT_TERMINATED: 'agent:terminated',
1673
+ AGENT_ERROR: 'agent:error',
1674
+ AGENT_IDLE: 'agent:idle',
1675
+ AGENT_BUSY: 'agent:busy',
1676
+ AGENT_HEALTH_CHANGED: 'agent:health:changed',
1677
+
1678
+ // Task lifecycle
1679
+ TASK_CREATED: 'task:created',
1680
+ TASK_ASSIGNED: 'task:assigned',
1681
+ TASK_STARTED: 'task:started',
1682
+ TASK_COMPLETED: 'task:completed',
1683
+ TASK_FAILED: 'task:failed',
1684
+ TASK_CANCELLED: 'task:cancelled',
1685
+ TASK_TIMEOUT: 'task:timeout',
1686
+ TASK_RETRY: 'task:retry',
1687
+
1688
+ // Session lifecycle
1689
+ SESSION_CREATED: 'session:created',
1690
+ SESSION_RESTORED: 'session:restored',
1691
+ SESSION_TERMINATED: 'session:terminated',
1692
+ SESSION_PERSISTED: 'session:persisted',
1693
+
1694
+ // Memory events
1695
+ MEMORY_STORED: 'memory:stored',
1696
+ MEMORY_RETRIEVED: 'memory:retrieved',
1697
+ MEMORY_CLEARED: 'memory:cleared',
1698
+
1699
+ // Coordination events
1700
+ COORDINATION_STARTED: 'coordination:started',
1701
+ COORDINATION_COMPLETED: 'coordination:completed',
1702
+ DEADLOCK_DETECTED: 'coordination:deadlock',
1703
+
1704
+ // Metrics events
1705
+ METRICS_COLLECTED: 'metrics:collected',
1706
+ } as const;
1707
+
1708
+ export type SystemEventType = typeof SystemEventTypes[keyof typeof SystemEventTypes];
1709
+
1710
+ /**
1711
+ * Event store interface for event sourcing
1712
+ */
1713
+ export interface IEventStore {
1714
+ /**
1715
+ * Append an event to the store
1716
+ */
1717
+ append(event: IEvent): Promise<void>;
1718
+
1719
+ /**
1720
+ * Get events by aggregate ID
1721
+ */
1722
+ getByAggregateId(aggregateId: string, fromVersion?: number): Promise<IEvent[]>;
1723
+
1724
+ /**
1725
+ * Get events by type
1726
+ */
1727
+ getByType(type: string, options?: { limit?: number; offset?: number }): Promise<IEvent[]>;
1728
+
1729
+ /**
1730
+ * Get events in time range
1731
+ */
1732
+ getByTimeRange(start: Date, end: Date): Promise<IEvent[]>;
1733
+
1734
+ /**
1735
+ * Get events by correlation ID
1736
+ */
1737
+ getByCorrelationId(correlationId: string): Promise<IEvent[]>;
1738
+
1739
+ /**
1740
+ * Get all events (paginated)
1741
+ */
1742
+ getAll(options?: { limit?: number; offset?: number }): Promise<IEvent[]>;
1743
+
1744
+ /**
1745
+ * Get event count
1746
+ */
1747
+ count(filter?: IEventFilter): Promise<number>;
1748
+
1749
+ /**
1750
+ * Clear old events
1751
+ */
1752
+ prune(olderThan: Date): P
1753
+
1754
+ --- src/core/interfaces/index.ts ---
1755
+ /**
1756
+ * V3 Core Interfaces - Public API
1757
+ * Domain-Driven Design with Clean Architecture
1758
+ */
1759
+
1760
+ // Task interfaces
1761
+ export * from './task.interface.js';
1762
+
1763
+ // Agent interfaces
1764
+ export * from './agent.interface.js';
1765
+
1766
+ // Event interfaces
1767
+ export * from './event.interface.js';
1768
+
1769
+ // Memory interfaces
1770
+ export * from './memory.interface.js';
1771
+
1772
+ // Coordinator interfaces
1773
+ export * from './coordinator.interface.js';
1774
+
1775
+
1776
+ --- src/core/interfaces/memory.interface.ts (truncated) ---
1777
+ /**
1778
+ * V3 Memory Interfaces
1779
+ * Domain-Driven Design - Memory Management Bounded Context
1780
+ * Aligned with ADR-006 (Unified Memory Service) and ADR-009 (Hybrid Memory Backend)
1781
+ */
1782
+
1783
+ /**
1784
+ * Memory entry types
1785
+ */
1786
+ export type MemoryType = 'session' | 'persistent' | 'vector' | 'cache' | 'pattern';
1787
+
1788
+ /**
1789
+ * Memory entry structure
1790
+ */
1791
+ export interface IMemoryEntry {
1792
+ readonly id: string;
1793
+ readonly key: string;
1794
+ readonly type: MemoryType;
1795
+ readonly createdAt: Date;
1796
+
1797
+ value: unknown;
1798
+ updatedAt: Date;
1799
+ expiresAt?: Date;
1800
+
1801
+ metadata?: {
1802
+ source?: string;
1803
+ agentId?: string;
1804
+ sessionId?: string;
1805
+ version?: number;
1806
+ tags?: string[];
1807
+ embedding?: number[];
1808
+ [key: string]: unknown;
1809
+ };
1810
+ }
1811
+
1812
+ /**
1813
+ * Memory entry creation parameters
1814
+ */
1815
+ export interface IMemoryEntryCreate {
1816
+ key: string;
1817
+ value: unknown;
1818
+ type?: MemoryType;
1819
+ expiresAt?: Date;
1820
+ ttlMs?: number;
1821
+ metadata?: IMemoryEntry['metadata'];
1822
+ }
1823
+
1824
+ /**
1825
+ * Vector search parameters
1826
+ */
1827
+ export interface IVectorSearchParams {
1828
+ embedding: number[];
1829
+ k?: number;
1830
+ threshold?: number;
1831
+ filter?: {
1832
+ type?: MemoryType;
1833
+ tags?: string[];
1834
+ agentId?: string;
1835
+ };
1836
+ }
1837
+
1838
+ /**
1839
+ * Vector search result
1840
+ */
1841
+ export interface IVectorSearchResult {
1842
+ entry: IMemoryEntry;
1843
+ score: number;
1844
+ distance: number;
1845
+ }
1846
+
1847
+ /**
1848
+ * Memory backend interface for storage operations
1849
+ */
1850
+ export interface IMemoryBackend {
1851
+ /**
1852
+ * Initialize the backend
1853
+ */
1854
+ initialize(): Promise<void>;
1855
+
1856
+ /**
1857
+ * Shutdown the backend
1858
+ */
1859
+ shutdown(): Promise<void>;
1860
+
1861
+ /**
1862
+ * Store a memory entry
1863
+ */
1864
+ store(entry: IMemoryEntryCreate): Promise<IMemoryEntry>;
1865
+
1866
+ /**
1867
+ * Retrieve a memory entry by key
1868
+ */
1869
+ retrieve(key: string): Promise<IMemoryEntry | undefined>;
1870
+
1871
+ /**
1872
+ * Retrieve by ID
1873
+ */
1874
+ retrieveById(id: string): Promise<IMemoryEntry | undefined>;
1875
+
1876
+ /**
1877
+ * Update a memory entry
1878
+ */
1879
+ update(key: string, value: unknown, metadata?: Partial<IMemoryEntry['metadata']>): Promise<IMemoryEntry | undefined>;
1880
+
1881
+ /**
1882
+ * Delete a memory entry
1883
+ */
1884
+ delete(key: string): Promise<boolean>;
1885
+
1886
+ /**
1887
+ * Check if a key exists
1888
+ */
1889
+ exists(key: string): Promise<boolean>;
1890
+
1891
+ /**
1892
+ * List all keys matching a pattern
1893
+ */
1894
+ keys(pattern?: string): Promise<string[]>;
1895
+
1896
+ /**
1897
+ * Get all entries matching filter
1898
+ */
1899
+ list(filter?: { type?: MemoryType; tags?: string[] }): Promise<IMemoryEntry[]>;
1900
+
1901
+ /**
1902
+ * Clear all entries
1903
+ */
1904
+ clear(): Promise<void>;
1905
+
1906
+ /**
1907
+ * Get entry count
1908
+ */
1909
+ count(): Promise<number>;
1910
+
1911
+ /**
1912
+ * Prune expired entries
1913
+ */
1914
+ prune(): Promise<number>;
1915
+
1916
+ /**
1917
+ * Get health status
1918
+ */
1919
+ getHealthStatus(): Promise<{ healthy: boolean; error?: string; metrics?: Record<string, number> }>;
1920
+ }
1921
+
1922
+ /**
1923
+ * Vector memory backend for similarity search
1924
+ */
1925
+ export interface IVectorMemoryBackend extends IMemoryBackend {
1926
+ /**
1927
+ * Store with embedding
1928
+ */
1929
+ storeVector(entry: IMemoryEntryCreate & { embedding: number[] }): Promise<IMemoryEntry>;
1930
+
1931
+ /**
1932
+ * Search by vector similarity
1933
+ */
1934
+ search(params: IVectorSearchParams): Promise<IVectorSearchResult[]>;
1935
+
1936
+ /**
1937
+ * Update embedding for an entry
1938
+ */
1939
+ updateEmbedding(key: string, embedding: number[]): Promise<boolean>;
1940
+
1941
+ /**
1942
+ * Build or rebuild index
1943
+ */
1944
+ buildIndex(): Promise<void>;
1945
+
1946
+ /**
1947
+ * Get index statistics
1948
+ */
1949
+ getIndexStats(): Promise<{
1950
+ vectorCount: number;
1951
+ dimensions: number;
1952
+ indexType: string;
1953
+ memoryUsageMb: number;
1954
+ }>;
1955
+ }
1956
+
1957
+ /**
1958
+ * Memory bank for agent-specific storage
1959
+ */
1960
+ export interface IMemoryBank {
1961
+ readonly id: string;
1962
+ readonly agentId: string;
1963
+ readonly createdAt: Date;
1964
+
1965
+ /**
1966
+ * Store in bank
1967
+ */
1968
+ store(key: string, value: unknown, options?: Partial<IMemoryEntryCreate>): Promise<IMemoryEntry>;
1969
+
1970
+ /**
1971
+ * Retrieve from bank
1972
+ */
1973
+ retrieve(key: string): Promise<IMemoryEntry | undefined>;
1974
+
1975
+ /**
1976
+ * Delete from bank
1977
+ */
1978
+ delete(key: string): Promise<boolean>;
1979
+
1980
+ /**
1981
+ * List all entries in bank
1982
+ */
1983
+ list(): Promise<IMemoryEntry[]>;
1984
+
1985
+ /**
1986
+ * Clear all entries in bank
1987
+ */
1988
+ clear(): Promise<void>;
1989
+
1990
+ /**
1991
+ * Get bank size
1992
+ */
1993
+ size(): Promise<number>;
1994
+
1995
+ /**
1996
+ * Close the bank
1997
+ */
1998
+ close(): Promise<void>;
1999
+ }
2000
+
2001
+ /**
2002
+ * Memory manager interface
2003
+ */
2004
+ export interface IMemoryManager {
2005
+ /**
2006
+ * Initialize the manager
2007
+ */
2008
+ initialize(): Promise<void>;
2009
+
2010
+ /**
2011
+ * Shutdown the manager
2012
+ */
2013
+ shutdown(): Promise<void>;
2014
+
2015
+ /**
2016
+ * Create a memory bank for an agent
2017
+ */
2018
+ createBank(agentId: string): Promise<string>;
2019
+
2020
+ /**
2021
+ * Get a memory bank
2022
+ */
2023
+ getBank(bankId: string): IMemoryBank | undefined;
2024
+
2025
+ /**
2026
+ * Close a memory bank
2027
+ */
2028
+ closeBank(bankId: string): Promise<void>;
2029
+
2030
+ /**
2031
+ * Store in global memory
2032
+ */
2033
+ store(entry: IMemoryEntryCreate): Promise<IMemoryEntry>;
2034
+
2035
+ /**
2036
+ * Retrieve from global memory
2037
+ */
2038
+ retrieve(key: string): Promise<IMemoryEntry | undefined>;
2039
+
2040
+ /**
2041
+ * Search vectors (if vector backend available)
2042
+ */
2043
+ searchVectors?(params: IVectorSearchParams): Promise<IVectorSearchResult[]>;
2044
+
2045
+ /**
2046
+
2047
+
2048
+ --- src/core/interfaces/task.interface.ts ---
2049
+ /**
2050
+ * V3 Task Interfaces
2051
+ * Domain-Driven Design - Task Bounded Context
2052
+ */
2053
+
2054
+ /**
2055
+ * Task priority levels
2056
+ */
2057
+ export type TaskPriority = 'critical' | 'high' | 'medium' | 'low';
2058
+
2059
+ /**
2060
+ * Task status throughout its lifecycle
2061
+ */
2062
+ export type TaskStatus =
2063
+ | 'pending'
2064
+ | 'queued'
2065
+ | 'assigned'
2066
+ | 'running'
2067
+ | 'completed'
2068
+ | 'failed'
2069
+ | 'cancelled'
2070
+ | 'timeout';
2071
+
2072
+ /**
2073
+ * Core task entity
2074
+ */
2075
+ export interface ITask {
2076
+ readonly id: string;
2077
+ readonly type: string;
2078
+ readonly description: string;
2079
+ readonly priority: number;
2080
+ readonly createdAt: Date;
2081
+
2082
+ status: TaskStatus;
2083
+ assignedAgent?: string;
2084
+ startedAt?: Date;
2085
+ completedAt?: Date;
2086
+ timeout?: number;
2087
+
2088
+ input?: Record<string, unknown>;
2089
+ output?: Record<string, unknown>;
2090
+ error?: Error;
2091
+
2092
+ metadata?: {
2093
+ requiredCapabilities?: string[];
2094
+ retryCount?: number;
2095
+ maxRetries?: number;
2096
+ critical?: boolean;
2097
+ parentTaskId?: string;
2098
+ childTaskIds?: string[];
2099
+ tags?: string[];
2100
+ [key: string]: unknown;
2101
+ };
2102
+ }
2103
+
2104
+ /**
2105
+ * Task creation parameters
2106
+ */
2107
+ export interface ITaskCreate {
2108
+ type: string;
2109
+ description: string;
2110
+ priority?: number;
2111
+ timeout?: number;
2112
+ assignedAgent?: string;
2113
+ input?: Record<string, unknown>;
2114
+ metadata?: ITask['metadata'];
2115
+ }
2116
+
2117
+ /**
2118
+ * Task result after completion
2119
+ */
2120
+ export interface ITaskResult {
2121
+ taskId: string;
2122
+ success: boolean;
2123
+ output?: Record<string, unknown>;
2124
+ error?: Error;
2125
+ duration: number;
2126
+ agentId?: string;
2127
+ metrics?: {
2128
+ tokensUsed?: number;
2129
+ memoryPeakMb?: number;
2130
+ retryCount?: number;
2131
+ };
2132
+ }
2133
+
2134
+ /**
2135
+ * Task queue interface for managing task ordering and processing
2136
+ */
2137
+ export interface ITaskQueue {
2138
+ /**
2139
+ * Add a task to the queue
2140
+ */
2141
+ enqueue(task: ITask): Promise<void>;
2142
+
2143
+ /**
2144
+ * Remove and return the highest priority task
2145
+ */
2146
+ dequeue(): Promise<ITask | undefined>;
2147
+
2148
+ /**
2149
+ * Peek at the next task without removing it
2150
+ */
2151
+ peek(): Promise<ITask | undefined>;
2152
+
2153
+ /**
2154
+ * Get the current queue size
2155
+ */
2156
+ size(): number;
2157
+
2158
+ /**
2159
+ * Check if the queue is empty
2160
+ */
2161
+ isEmpty(): boolean;
2162
+
2163
+ /**
2164
+ * Clear all tasks from the queue
2165
+ */
2166
+ clear(): Promise<void>;
2167
+
2168
+ /**
2169
+ * Get all queued tasks (for inspection)
2170
+ */
2171
+ getAll(): Promise<ITask[]>;
2172
+
2173
+ /**
2174
+ * Remove a specific task by ID
2175
+ */
2176
+ remove(taskId: string): Promise<boolean>;
2177
+
2178
+ /**
2179
+ * Update task priority
2180
+ */
2181
+ updatePriority(taskId: string, priority: number): Promise<boolean>;
2182
+ }
2183
+
2184
+ /**
2185
+ * Task manager interface for lifecycle management
2186
+ */
2187
+ export interface ITaskManager {
2188
+ /**
2189
+ * Create a new task
2190
+ */
2191
+ createTask(params: ITaskCreate): Promise<ITask>;
2192
+
2193
+ /**
2194
+ * Get a task by ID
2195
+ */
2196
+ getTask(taskId: string): ITask | undefined;
2197
+
2198
+ /**
2199
+ * Get all tasks matching optional filter
2200
+ */
2201
+ getTasks(filter?: Partial<Pick<ITask, 'status' | 'type' | 'assignedAgent'>>): ITask[];
2202
+
2203
+ /**
2204
+ * Assign a task to an agent
2205
+ */
2206
+ assignTask(taskId: string, agentId: string): Promise<void>;
2207
+
2208
+ /**
2209
+ * Start task execution
2210
+ */
2211
+ startTask(taskId: string): Promise<void>;
2212
+
2213
+ /**
2214
+ * Complete a task with result
2215
+ */
2216
+ completeTask(taskId: string, result: ITaskResult): Promise<void>;
2217
+
2218
+ /**
2219
+ * Fail a task with error
2220
+ */
2221
+ failTask(taskId: string, error: Error): Promise<void>;
2222
+
2223
+ /**
2224
+ * Cancel a task
2225
+ */
2226
+ cancelTask(taskId: string, reason?: string): Promise<void>;
2227
+
2228
+ /**
2229
+ * Retry a failed task
2230
+ */
2231
+ retryTask(taskId: string): Promise<void>;
2232
+
2233
+ /**
2234
+ * Get task metrics
2235
+ */
2236
+ getMetrics(): TaskManagerMetrics;
2237
+
2238
+ /**
2239
+ * Clean up old completed/failed tasks
2240
+ */
2241
+ cleanup(olderThan: Date): Promise<number>;
2242
+ }
2243
+
2244
+ /**
2245
+ * Task manager metrics
2246
+ */
2247
+ export interface TaskManagerMetrics {
2248
+ totalTasks: number;
2249
+ pendingTasks: number;
2250
+ runningTasks: number;
2251
+ completedTasks: number;
2252
+ failedTasks: number;
2253
+ cancelledTasks: number;
2254
+ avgDuration: number;
2255
+ avgWaitTime: number;
2256
+ }
2257
+
2258
+ /**
2259
+ * Task assignment strategy interface
2260
+ */
2261
+ export interface ITaskAssignmentStrategy {
2262
+ /**
2263
+ * Select the best agent for a task
2264
+ */
2265
+ selectAgent(task: ITask, availableAgents: string[]): Promise<string | undefined>;
2266
+
2267
+ /**
2268
+ * Score an agent for a task (higher is better)
2269
+ */
2270
+ scoreAgent(task: ITask, agentId: string): Promise<number>;
2271
+ }
2272
+
2273
+
2274
+ --- src/core/orchestrator/event-coordinator.ts ---
2275
+ /**
2276
+ * V3 Event Coordinator
2277
+ * Decomposed from orchestrator.ts - Event routing
2278
+ * ~100 lines (target achieved)
2279
+ */
2280
+
2281
+ import type {
2282
+ IEvent,
2283
+ IEventBus,
2284
+ IEventHandler,
2285
+ IEventCoordinator,
2286
+ } from '../interfaces/event.interface.js';
2287
+ import { SystemEventTypes } from '../interfaces/event.interface.js';
2288
+
2289
+ /**
2290
+ * Event coordinator implementation
2291
+ */
2292
+ export class EventCoordinator implements IEventCoordinator {
2293
+ private handlers = new Map<string, Set<IEventHandler>>();
2294
+ private initialized = false;
2295
+
2296
+ constructor(private eventBus: IEventBus) {}
2297
+
2298
+ async initialize(): Promise<void> {
2299
+ if (this.initialized) {
2300
+ return;
2301
+ }
2302
+
2303
+ // Register default system event handlers
2304
+ this.registerSystemHandlers();
2305
+
2306
+ this.initialized = true;
2307
+ }
2308
+
2309
+ async shutdown(): Promise<void> {
2310
+ // Clear all handlers
2311
+ this.handlers.clear();
2312
+ this.initialized = false;
2313
+ }
2314
+
2315
+ async route(event: IEvent): Promise<void> {
2316
+ const handlers = this.handlers.get(event.type);
2317
+ if (!handlers || handlers.size === 0) {
2318
+ return;
2319
+ }
2320
+
2321
+ const handlerPromises = Array.from(handlers).map(async handler => {
2322
+ try {
2323
+ await handler(event);
2324
+ } catch (error) {
2325
+ // Log error but don't throw
2326
+ console.error(`Error in event handler for ${event.type}:`, error);
2327
+ }
2328
+ });
2329
+
2330
+ await Promise.allSettled(handlerPromises);
2331
+ }
2332
+
2333
+ registerHandler(type: string, handler: IEventHandler): void {
2334
+ let handlers = this.handlers.get(type);
2335
+ if (!handlers) {
2336
+ handlers = new Set();
2337
+ this.handlers.set(type, handlers);
2338
+ }
2339
+ handlers.add(handler);
2340
+
2341
+ // Also register with event bus
2342
+ this.eventBus.on(type, handler);
2343
+ }
2344
+
2345
+ unregisterHandler(type: string, handler: IEventHandler): void {
2346
+ const handlers = this.handlers.get(type);
2347
+ if (handlers) {
2348
+ handlers.delete(handler);
2349
+ if (handlers.size === 0) {
2350
+ this.handlers.delete(type);
2351
+ }
2352
+ }
2353
+
2354
+ // Also unregister from event bus
2355
+ this.eventBus.off(type, handler);
2356
+ }
2357
+
2358
+ getEventBus(): IEventBus {
2359
+ return this.eventBus;
2360
+ }
2361
+
2362
+ private registerSystemHandlers(): void {
2363
+ // Error handling
2364
+ this.eventBus.on(SystemEventTypes.SYSTEM_ERROR, (event: IEvent) => {
2365
+ const { error, component } = event.payload as { error: Error; component: string };
2366
+ console.error(`System error in ${component}:`, error);
2367
+ });
2368
+
2369
+ // Deadlock detection
2370
+ this.eventBus.on(SystemEventTypes.DEADLOCK_DETECTED, (event: IEvent) => {
2371
+ const { agents, resources } = event.payload as { agents: string[]; resources: string[] };
2372
+ console.warn('Deadlock detected:', { agents, resources });
2373
+ });
2374
+ }
2375
+
2376
+ /**
2377
+ * Get registered handler count for a type
2378
+ */
2379
+ getHandlerCount(type: string): number {
2380
+ return this.handlers.get(type)?.size ?? 0;
2381
+ }
2382
+
2383
+ /**
2384
+ * Get all registered event types
2385
+ */
2386
+ getRegisteredTypes(): string[] {
2387
+ return Array.from(this.handlers.keys());
2388
+ }
2389
+
2390
+ /**
2391
+ * Check if coordinator is initialized
2392
+ */
2393
+ isInitialized(): boolean {
2394
+ return this.initialized;
2395
+ }
2396
+ }
2397
+
2398
+
2399
+ --- src/core/orchestrator/health-monitor.ts (truncated) ---
2400
+ /**
2401
+ * V3 Health Monitor
2402
+ * Decomposed from orchestrator.ts - Agent health checks
2403
+ * ~150 lines (target achieved)
2404
+ */
2405
+
2406
+ import type {
2407
+ IHealthMonitor,
2408
+ IHealthStatus,
2409
+ IComponentHealth,
2410
+ } from '../interfaces/coordinator.interface.js';
2411
+ import type { IEventBus } from '../interfaces/event.interface.js';
2412
+ import { SystemEventTypes } from '../interfaces/event.interface.js';
2413
+
2414
+ /**
2415
+ * Health check function type
2416
+ */
2417
+ export type HealthCheckFn = () => Promise<{
2418
+ healthy: boolean;
2419
+ error?: string;
2420
+ metrics?: Record<string, number>;
2421
+ }>;
2422
+
2423
+ /**
2424
+ * Health monitor configuration
2425
+ */
2426
+ export interface HealthMonitorConfig {
2427
+ checkInterval: number;
2428
+ historyLimit: number;
2429
+ degradedThreshold: number;
2430
+ unhealthyThreshold: number;
2431
+ }
2432
+
2433
+ /**
2434
+ * Health monitor implementation
2435
+ */
2436
+ export class HealthMonitor implements IHealthMonitor {
2437
+ private checks = new Map<string, HealthCheckFn>();
2438
+ private history: IHealthStatus[] = [];
2439
+ private interval?: ReturnType<typeof setInterval>;
2440
+ private listeners: Array<(status: IHealthStatus) => void> = [];
2441
+ private running = false;
2442
+
2443
+ constructor(
2444
+ private eventBus: IEventBus,
2445
+ private config: HealthMonitorConfig = {
2446
+ checkInterval: 30000,
2447
+ historyLimit: 100,
2448
+ degradedThreshold: 1,
2449
+ unhealthyThreshold: 2,
2450
+ },
2451
+ ) {}
2452
+
2453
+ start(): void {
2454
+ if (this.running) {
2455
+ return;
2456
+ }
2457
+
2458
+ this.running = true;
2459
+ this.interval = setInterval(async () => {
2460
+ const status = await this.getStatus();
2461
+ this.addToHistory(status);
2462
+ this.notifyListeners(status);
2463
+ this.eventBus.emit(SystemEventTypes.SYSTEM_HEALTHCHECK, { status });
2464
+ }, this.config.checkInterval);
2465
+ }
2466
+
2467
+ stop(): void {
2468
+ if (this.interval) {
2469
+ clearInterval(this.interval);
2470
+ this.interval = undefined;
2471
+ }
2472
+ this.running = false;
2473
+ }
2474
+
2475
+ async getStatus(): Promise<IHealthStatus> {
2476
+ const components: Record<string, IComponentHealth> = {};
2477
+ let unhealthyCount = 0;
2478
+ let degradedCount = 0;
2479
+
2480
+ const checkPromises = Array.from(this.checks.entries()).map(
2481
+ async ([name, check]) => {
2482
+ try {
2483
+ const result = await Promise.race([
2484
+ check(),
2485
+ this.timeout(5000, 'Health check timeout'),
2486
+ ]);
2487
+
2488
+ const health: IComponentHealth = {
2489
+ name,
2490
+ status: result.healthy ? 'healthy' : 'unhealthy',
2491
+ lastCheck: new Date(),
2492
+ error: result.error,
2493
+ metrics: result.metrics,
2494
+ };
2495
+
2496
+ return { name, health };
2497
+ } catch (error) {
2498
+ return {
2499
+ name,
2500
+ health: {
2501
+ name,
2502
+ status: 'unhealthy' as const,
2503
+ lastCheck: new Date(),
2504
+ error: error instanceof Error ? error.message : 'Unknown error',
2505
+ },
2506
+ };
2507
+ }
2508
+ },
2509
+ );
2510
+
2511
+ const results = await Promise.allSettled(checkPromises);
2512
+
2513
+ for (const result of results) {
2514
+ if (result.status === 'fulfilled') {
2515
+ const { name, health } = result.value;
2516
+ components[name] = health;
2517
+
2518
+ if (health.status === 'unhealthy') {
2519
+ unhealthyCount++;
2520
+ } else if (health.status === 'degraded') {
2521
+ degradedCount++;
2522
+ }
2523
+ }
2524
+ }
2525
+
2526
+ let overallStatus: IHealthStatus['status'] = 'healthy';
2527
+ if (unhealthyCount >= this.config.unhealthyThreshold) {
2528
+ overallStatus = 'unhealthy';
2529
+ } else if (
2530
+ unhealthyCount > 0 ||
2531
+ degradedCount >= this.config.degradedThreshold
2532
+ ) {
2533
+ overallStatus = 'degraded';
2534
+ }
2535
+
2536
+ return {
2537
+ status: overallStatus,
2538
+ components,
2539
+ timestamp: new Date(),
2540
+ };
2541
+ }
2542
+
2543
+ registerCheck(name: string, check: HealthCheckFn): void {
2544
+ this.checks.set(name, check);
2545
+ }
2546
+
2547
+ unregisterCheck(name: string): void {
2548
+ this.checks.delete(name);
2549
+ }
2550
+
2551
+ getHistory(limit?: number): IHealthStatus[] {
2552
+ const count = limit ?? this.config.historyLimit;
2553
+ return this.history.slice(-count);
2554
+ }
2555
+
2556
+ onHealthChange(callback: (status: IHealthStatus) => void): () => void {
2557
+ this.listeners.push(callback);
2558
+ return () => {
2559
+ const index = this.listeners.indexOf(callback);
2560
+ if (index !== -1) {
2561
+ this.listeners.splice(index, 1);
2562
+ }
2563
+ };
2564
+ }
2565
+
2566
+ private addToHistory(status: IHealthStatus): void {
2567
+ this.history.push(status);
2568
+
2569
+ // Trim history to limit
2570
+ if (this.history.length > this.config.historyLimit) {
2571
+ this.history = this.history.slice(-this.config.historyLimit);
2572
+ }
2573
+ }
2574
+
2575
+ private notifyListeners(status: IHealthStatus): void {
2576
+ for (const listener of this.listeners) {
2577
+ try {
2578
+ listener(status);
2579
+ } catch {
2580
+ // Ignore listener errors
2581
+ }
2582
+ }
2583
+ }
2584
+
2585
+ private timeout(ms: number, message: string): Promise<never> {
2586
+ return new Promise((_, reject) => {
2587
+ setTimeout(() => reject(new Error(message)), ms);
2588
+ });
2589
+ }
2590
+
2591
+ /**
2592
+ * Get component health by name
2593
+ */
2594
+ async getComponentHealth(name: string): Promise<IComponentHealth | undefined> {
2595
+ const status = await this.getStatus();
2596
+
2597
+
2598
+ --- src/core/orchestrator/index.ts ---
2599
+ /**
2600
+ * V3 Orchestrator Facade
2601
+ * Unified interface to decomposed orchestrator components
2602
+ * ~50 lines (target achieved)
2603
+ */
2604
+
2605
+ import type { IOrchestrator, IHealthStatus, IOrchestratorMetrics } from '../interfaces/coordinator.interface.js';
2606
+ import type { ITask, ITaskCreate, ITaskResult } from '../interfaces/task.interface.js';
2607
+ import type { IAgent, IAgentConfig } from '../interfaces/agent.interface.js';
2608
+ import type { IEventBus } from '../interfaces/event.interface.js';
2609
+
2610
+ import { TaskManager } from './task-manager.js';
2611
+ import { SessionManager, type ISessionManager, type SessionManagerConfig } from './session-manager.js';
2612
+ import { HealthMonitor, type HealthMonitorConfig } from './health-monitor.js';
2613
+ import { LifecycleManager, type LifecycleManagerConfig } from './lifecycle-manager.js';
2614
+ import { EventCoordinator } from './event-coordinator.js';
2615
+ import { EventBus } from '../event-bus.js';
2616
+
2617
+ export * from './task-manager.js';
2618
+ export * from './session-manager.js';
2619
+ export * from './health-monitor.js';
2620
+ export * from './lifecycle-manager.js';
2621
+ export * from './event-coordinator.js';
2622
+
2623
+ /**
2624
+ * Orchestrator facade configuration
2625
+ * (Note: For schema-validated config, use OrchestratorConfig from config/schema.ts)
2626
+ */
2627
+ export interface OrchestratorFacadeConfig {
2628
+ session: SessionManagerConfig;
2629
+ health: HealthMonitorConfig;
2630
+ lifecycle: LifecycleManagerConfig;
2631
+ }
2632
+
2633
+ /**
2634
+ * Default orchestrator facade configuration
2635
+ */
2636
+ export const defaultOrchestratorFacadeConfig: OrchestratorFacadeConfig = {
2637
+ session: {
2638
+ persistSessions: true,
2639
+ dataDir: './data',
2640
+ sessionRetentionMs: 3600000,
2641
+ },
2642
+ health: {
2643
+ checkInterval: 30000,
2644
+ historyLimit: 100,
2645
+ degradedThreshold: 1,
2646
+ unhealthyThreshold: 2,
2647
+ },
2648
+ lifecycle: {
2649
+ maxConcurrentAgents: 20,
2650
+ spawnTimeout: 30000,
2651
+ terminateTimeout: 10000,
2652
+ maxSpawnRetries: 3,
2653
+ },
2654
+ };
2655
+
2656
+ /**
2657
+ * Create orchestrator components
2658
+ */
2659
+ export function createOrchestrator(config: Partial<OrchestratorFacadeConfig> = {}) {
2660
+ const mergedConfig: OrchestratorFacadeConfig = {
2661
+ session: { ...defaultOrchestratorFacadeConfig.session, ...config.session },
2662
+ health: { ...defaultOrchestratorFacadeConfig.health, ...config.health },
2663
+ lifecycle: { ...defaultOrchestratorFacadeConfig.lifecycle, ...config.lifecycle },
2664
+ };
2665
+
2666
+ const eventBus = new EventBus();
2667
+ const taskManager = new TaskManager(eventBus);
2668
+ const sessionManager = new SessionManager(eventBus, mergedConfig.session);
2669
+ const healthMonitor = new HealthMonitor(eventBus, mergedConfig.health);
2670
+ const lifecycleManager = new LifecycleManager(eventBus, mergedConfig.lifecycle);
2671
+ const eventCoordinator = new EventCoordinator(eventBus);
2672
+
2673
+ return {
2674
+ eventBus,
2675
+ taskManager,
2676
+ sessionManager,
2677
+ healthMonitor,
2678
+ lifecycleManager,
2679
+ eventCoordinator,
2680
+ config: mergedConfig,
2681
+ };
2682
+ }
2683
+
2684
+ /**
2685
+ * Orchestrator type for facade
2686
+ */
2687
+ export type OrchestratorComponents = ReturnType<typeof createOrchestrator>;
2688
+
2689
+
2690
+ --- src/core/orchestrator/lifecycle-manager.ts (truncated) ---
2691
+ /**
2692
+ * V3 Lifecycle Manager
2693
+ * Decomposed from orchestrator.ts - Agent spawn/terminate
2694
+ * ~150 lines (target achieved)
2695
+ */
2696
+
2697
+ import type {
2698
+ IAgent,
2699
+ IAgentConfig,
2700
+ IAgentLifecycleManager,
2701
+ IAgentPool,
2702
+ AgentStatus,
2703
+ } from '../interfaces/agent.interface.js';
2704
+ import type { IEventBus } from '../interfaces/event.interface.js';
2705
+ import { SystemEventTypes } from '../interfaces/event.interface.js';
2706
+
2707
+ /**
2708
+ * Agent pool implementation
2709
+ */
2710
+ export class AgentPool implements IAgentPool {
2711
+ private agents = new Map<string, IAgent>();
2712
+
2713
+ add(agent: IAgent): void {
2714
+ this.agents.set(agent.id, agent);
2715
+ }
2716
+
2717
+ remove(agentId: string): boolean {
2718
+ return this.agents.delete(agentId);
2719
+ }
2720
+
2721
+ get(agentId: string): IAgent | undefined {
2722
+ return this.agents.get(agentId);
2723
+ }
2724
+
2725
+ getAll(): IAgent[] {
2726
+ return Array.from(this.agents.values());
2727
+ }
2728
+
2729
+ getByStatus(status: AgentStatus): IAgent[] {
2730
+ return this.getAll().filter(agent => agent.status === status);
2731
+ }
2732
+
2733
+ getByType(type: string): IAgent[] {
2734
+ return this.getAll().filter(agent => agent.type === type);
2735
+ }
2736
+
2737
+ getAvailable(): IAgent[] {
2738
+ return this.getAll().filter(
2739
+ agent =>
2740
+ (agent.status === 'active' || agent.status === 'idle') &&
2741
+ agent.currentTaskCount < agent.config.maxConcurrentTasks,
2742
+ );
2743
+ }
2744
+
2745
+ size(): number {
2746
+ return this.agents.size;
2747
+ }
2748
+
2749
+ hasCapacity(maxSize: number): boolean {
2750
+ return this.agents.size < maxSize;
2751
+ }
2752
+
2753
+ clear(): void {
2754
+ this.agents.clear();
2755
+ }
2756
+ }
2757
+
2758
+ /**
2759
+ * Lifecycle manager configuration
2760
+ */
2761
+ export interface LifecycleManagerConfig {
2762
+ maxConcurrentAgents: number;
2763
+ spawnTimeout: number;
2764
+ terminateTimeout: number;
2765
+ maxSpawnRetries: number;
2766
+ }
2767
+
2768
+ /**
2769
+ * Lifecycle manager implementation
2770
+ */
2771
+ export class LifecycleManager implements IAgentLifecycleManager {
2772
+ private pool: IAgentPool;
2773
+
2774
+ constructor(
2775
+ private eventBus: IEventBus,
2776
+ private config: LifecycleManagerConfig,
2777
+ pool?: IAgentPool,
2778
+ ) {
2779
+ this.pool = pool ?? new AgentPool();
2780
+ }
2781
+
2782
+ async spawn(config: IAgentConfig): Promise<IAgent> {
2783
+ // Validate capacity
2784
+ if (!this.pool.hasCapacity(this.config.maxConcurrentAgents)) {
2785
+ throw new Error('Maximum concurrent agents reached');
2786
+ }
2787
+
2788
+ // Validate agent doesn't already exist
2789
+ if (this.pool.get(config.id)) {
2790
+ throw new Error(`Agent with ID ${config.id} already exists`);
2791
+ }
2792
+
2793
+ const agent: IAgent = {
2794
+ id: config.id,
2795
+ name: config.name,
2796
+ type: config.type,
2797
+ config,
2798
+ createdAt: new Date(),
2799
+ status: 'spawning',
2800
+ currentTaskCount: 0,
2801
+ lastActivity: new Date(),
2802
+ metrics: {
2803
+ tasksCompleted: 0,
2804
+ tasksFailed: 0,
2805
+ avgTaskDuration: 0,
2806
+ errorCount: 0,
2807
+ uptime: 0,
2808
+ },
2809
+ };
2810
+
2811
+ // Add to pool
2812
+ this.pool.add(agent);
2813
+
2814
+ // Mark as active
2815
+ agent.status = 'active';
2816
+
2817
+ this.eventBus.emit(SystemEventTypes.AGENT_SPAWNED, {
2818
+ agentId: agent.id,
2819
+ profile: config,
2820
+ sessionId: undefined,
2821
+ });
2822
+
2823
+ return agent;
2824
+ }
2825
+
2826
+ async spawnBatch(configs: IAgentConfig[]): Promise<Map<string, IAgent>> {
2827
+ const results = new Map<string, IAgent>();
2828
+
2829
+ // Check total capacity
2830
+ if (this.pool.size() + configs.length > this.config.maxConcurrentAgents) {
2831
+ throw new Error('Batch would exceed maximum concurrent agents');
2832
+ }
2833
+
2834
+ // Spawn in parallel
2835
+ const spawnPromises = configs.map(async config => {
2836
+ try {
2837
+ const agent = await this.spawn(config);
2838
+ return { id: config.id, agent, error: null };
2839
+ } catch (error) {
2840
+ return { id: config.id, agent: null, error };
2841
+ }
2842
+ });
2843
+
2844
+ const settled = await Promise.allSettled(spawnPromises);
2845
+
2846
+ for (const result of settled) {
2847
+ if (result.status === 'fulfilled' && result.value.agent) {
2848
+ results.set(result.value.id, result.value.agent);
2849
+ }
2850
+ }
2851
+
2852
+ return results;
2853
+ }
2854
+
2855
+ async terminate(agentId: string, reason?: string): Promise<void> {
2856
+ const agent = this.pool.get(agentId);
2857
+ if (!agent) {
2858
+ throw new Error(`Agent not found: ${agentId}`);
2859
+ }
2860
+
2861
+ agent.status = 'terminated';
2862
+
2863
+ // Remove from pool
2864
+ this.pool.remove(agentId);
2865
+
2866
+ this.eventBus.emit(SystemEventTypes.AGENT_TERMINATED, {
2867
+ agentId,
2868
+ reason: reason ?? 'User requested',
2869
+ });
2870
+ }
2871
+
2872
+ async terminateAll(reason?: string): Promise<void> {
2873
+ const agents = this.pool.getAll();
2874
+ await Promise.allSettled(
2875
+ agents.map(agent => this.terminate(agent.id, reason)),
2876
+ );
2877
+ }
2878
+
2879
+ async restart(agentId: string): Promise<IAgent> {
2880
+ const agent = this.pool.get(agentId);
2881
+ if (!agent) {
2882
+ throw new Error(`Agent not found: ${agentId}`);
2883
+ }
2884
+
2885
+ const config = agent.config;
2886
+ await this.terminate(agentId, 'Restart requested');
2887
+ return this.spawn(config);
2888
+ }
2889
+
2890
+ async updateConfig(agentId: string, config: Partial<IAgentConfig>): Promise<void> {
2891
+ const agent = this.pool.get(agentId);
2892
+ if (!agent) {
2893
+ throw new Error(`Agent not found: ${agentId}`);
2894
+ }
2895
+
2896
+ Object.assign(agent.config,
2897
+
2898
+ --- src/core/orchestrator/session-manager.ts (truncated) ---
2899
+ /**
2900
+ * V3 Session Manager
2901
+ * Decomposed from orchestrator.ts - Session handling
2902
+ * ~200 lines (target achieved)
2903
+ */
2904
+
2905
+ import type { IAgentSession } from '../interfaces/agent.interface.js';
2906
+ import type { IEventBus } from '../interfaces/event.interface.js';
2907
+ import { SystemEventTypes } from '../interfaces/event.interface.js';
2908
+ import type { AgentProfile } from '../../types/agent.types.js';
2909
+ import { mkdir, writeFile, readFile } from 'fs/promises';
2910
+ import { join, dirname } from 'path';
2911
+ import { randomBytes } from 'crypto';
2912
+
2913
+ // Secure session ID generation
2914
+ function generateSecureSessionId(): string {
2915
+ const timestamp = Date.now().toString(36);
2916
+ const random = randomBytes(12).toString('hex');
2917
+ return `session_${timestamp}_${random}`;
2918
+ }
2919
+
2920
+ /**
2921
+ * Session persistence structure
2922
+ */
2923
+ export interface SessionPersistence {
2924
+ sessions: Array<IAgentSession & { profile: AgentProfile }>;
2925
+ metrics: {
2926
+ completedTasks: number;
2927
+ failedTasks: number;
2928
+ totalTaskDuration: number;
2929
+ };
2930
+ savedAt: Date;
2931
+ }
2932
+
2933
+ /**
2934
+ * Session manager configuration
2935
+ */
2936
+ export interface SessionManagerConfig {
2937
+ persistSessions: boolean;
2938
+ dataDir: string;
2939
+ sessionRetentionMs?: number;
2940
+ }
2941
+
2942
+ /**
2943
+ * Session manager interface
2944
+ */
2945
+ export interface ISessionManager {
2946
+ createSession(profile: AgentProfile, terminalId: string, memoryBankId: string): Promise<IAgentSession>;
2947
+ getSession(sessionId: string): IAgentSession | undefined;
2948
+ getActiveSessions(): IAgentSession[];
2949
+ getSessionsByAgent(agentId: string): IAgentSession[];
2950
+ terminateSession(sessionId: string): Promise<void>;
2951
+ terminateAllSessions(): Promise<void>;
2952
+ persistSessions(): Promise<void>;
2953
+ restoreSessions(): Promise<SessionPersistence | null>;
2954
+ removeSession(sessionId: string): void;
2955
+ updateSessionActivity(sessionId: string): void;
2956
+ }
2957
+
2958
+ /**
2959
+ * Session manager implementation
2960
+ */
2961
+ export class SessionManager implements ISessionManager {
2962
+ private sessions = new Map<string, IAgentSession>();
2963
+ private sessionProfiles = new Map<string, AgentProfile>();
2964
+ private persistencePath: string;
2965
+
2966
+ constructor(
2967
+ private eventBus: IEventBus,
2968
+ private config: SessionManagerConfig,
2969
+ ) {
2970
+ this.persistencePath = join(config.dataDir || './data', 'sessions.json');
2971
+ }
2972
+
2973
+ async createSession(
2974
+ profile: AgentProfile,
2975
+ terminalId: string,
2976
+ memoryBankId: string,
2977
+ ): Promise<IAgentSession> {
2978
+ const session: IAgentSession = {
2979
+ id: generateSecureSessionId(),
2980
+ agentId: profile.id,
2981
+ terminalId,
2982
+ startTime: new Date(),
2983
+ status: 'active',
2984
+ lastActivity: new Date(),
2985
+ memoryBankId,
2986
+ };
2987
+
2988
+ this.sessions.set(session.id, session);
2989
+ this.sessionProfiles.set(session.id, profile);
2990
+
2991
+ this.eventBus.emit(SystemEventTypes.SESSION_CREATED, {
2992
+ sessionId: session.id,
2993
+ agentId: profile.id,
2994
+ terminalId,
2995
+ memoryBankId,
2996
+ });
2997
+
2998
+ // Persist sessions asynchronously
2999
+ this.persistSessions().catch(() => {
3000
+ // Silently ignore persistence errors
3001
+ });
3002
+
3003
+ return session;
3004
+ }
3005
+
3006
+ getSession(sessionId: string): IAgentSession | undefined {
3007
+ return this.sessions.get(sessionId);
3008
+ }
3009
+
3010
+ getActiveSessions(): IAgentSession[] {
3011
+ return Array.from(this.sessions.values()).filter(
3012
+ session => session.status === 'active' || session.status === 'idle',
3013
+ );
3014
+ }
3015
+
3016
+ getSessionsByAgent(agentId: string): IAgentSession[] {
3017
+ return Array.from(this.sessions.values()).filter(
3018
+ session => session.agentId === agentId,
3019
+ );
3020
+ }
3021
+
3022
+ async terminateSession(sessionId: string): Promise<void> {
3023
+ const session = this.sessions.get(sessionId);
3024
+ if (!session) {
3025
+ throw new Error(`Session not found: ${sessionId}`);
3026
+ }
3027
+
3028
+ session.status = 'terminated';
3029
+ session.endTime = new Date();
3030
+
3031
+ const duration = session.endTime.getTime() - session.startTime.getTime();
3032
+
3033
+ this.eventBus.emit(SystemEventTypes.SESSION_TERMINATED, {
3034
+ sessionId,
3035
+ agentId: session.agentId,
3036
+ duration,
3037
+ });
3038
+
3039
+ // Clean up profile reference
3040
+ this.sessionProfiles.delete(sessionId);
3041
+
3042
+ // Persist sessions asynchronously
3043
+ this.persistSessions().catch(() => {
3044
+ // Silently ignore persistence errors
3045
+ });
3046
+ }
3047
+
3048
+ async terminateAllSessions(): Promise<void> {
3049
+ const sessions = this.getActiveSessions();
3050
+ const batchSize = 5;
3051
+
3052
+ for (let i = 0; i < sessions.length; i += batchSize) {
3053
+ const batch = sessions.slice(i, i + batchSize);
3054
+ await Promise.allSettled(
3055
+ batch.map(session => this.terminateSession(session.id)),
3056
+ );
3057
+ }
3058
+ }
3059
+
3060
+ removeSession(sessionId: string): void {
3061
+ this.sessions.delete(sessionId);
3062
+ this.sessionProfiles.delete(sessionId);
3063
+ }
3064
+
3065
+ updateSessionActivity(sessionId: string): void {
3066
+ const session = this.sessions.get(sessionId);
3067
+ if (session) {
3068
+ session.lastActivity = new Date();
3069
+ }
3070
+ }
3071
+
3072
+ async persistSessions(): Promise<void> {
3073
+ if (!this.config.persistSessions) {
3074
+ return;
3075
+ }
3076
+
3077
+ try {
3078
+ const data: SessionPersistence = {
3079
+ sessions: Array.from(this.sessions.valu
3080
+
3081
+ --- src/core/orchestrator/task-manager.ts (truncated) ---
3082
+ /**
3083
+ * V3 Task Manager
3084
+ * Decomposed from orchestrator.ts - Task lifecycle management
3085
+ * ~200 lines (target achieved)
3086
+ */
3087
+
3088
+ import type {
3089
+ ITask,
3090
+ ITaskCreate,
3091
+ ITaskResult,
3092
+ ITaskManager,
3093
+ ITaskQueue,
3094
+ TaskManagerMetrics,
3095
+ TaskStatus,
3096
+ } from '../interfaces/task.interface.js';
3097
+ import type { IEventBus, SystemEventType } from '../interfaces/event.interface.js';
3098
+ import { SystemEventTypes } from '../interfaces/event.interface.js';
3099
+ import { randomBytes } from 'crypto';
3100
+
3101
+ // Secure task ID generation
3102
+ function generateSecureTaskId(): string {
3103
+ const timestamp = Date.now().toString(36);
3104
+ const random = randomBytes(12).toString('hex');
3105
+ return `task_${timestamp}_${random}`;
3106
+ }
3107
+
3108
+ /**
3109
+ * Priority queue implementation for tasks
3110
+ */
3111
+ export class TaskQueue implements ITaskQueue {
3112
+ private tasks: ITask[] = [];
3113
+
3114
+ async enqueue(task: ITask): Promise<void> {
3115
+ this.tasks.push(task);
3116
+ this.tasks.sort((a, b) => b.priority - a.priority);
3117
+ }
3118
+
3119
+ async dequeue(): Promise<ITask | undefined> {
3120
+ return this.tasks.shift();
3121
+ }
3122
+
3123
+ async peek(): Promise<ITask | undefined> {
3124
+ return this.tasks[0];
3125
+ }
3126
+
3127
+ size(): number {
3128
+ return this.tasks.length;
3129
+ }
3130
+
3131
+ isEmpty(): boolean {
3132
+ return this.tasks.length === 0;
3133
+ }
3134
+
3135
+ async clear(): Promise<void> {
3136
+ this.tasks = [];
3137
+ }
3138
+
3139
+ async getAll(): Promise<ITask[]> {
3140
+ return [...this.tasks];
3141
+ }
3142
+
3143
+ async remove(taskId: string): Promise<boolean> {
3144
+ const index = this.tasks.findIndex(t => t.id === taskId);
3145
+ if (index !== -1) {
3146
+ this.tasks.splice(index, 1);
3147
+ return true;
3148
+ }
3149
+ return false;
3150
+ }
3151
+
3152
+ async updatePriority(taskId: string, priority: number): Promise<boolean> {
3153
+ const task = this.tasks.find(t => t.id === taskId);
3154
+ if (task) {
3155
+ (task as { priority: number }).priority = priority;
3156
+ this.tasks.sort((a, b) => b.priority - a.priority);
3157
+ return true;
3158
+ }
3159
+ return false;
3160
+ }
3161
+ }
3162
+
3163
+ /**
3164
+ * Task manager implementation
3165
+ */
3166
+ export class TaskManager implements ITaskManager {
3167
+ private tasks = new Map<string, ITask>();
3168
+ private queue: ITaskQueue;
3169
+ private metrics = {
3170
+ totalTasks: 0,
3171
+ completedTasks: 0,
3172
+ failedTasks: 0,
3173
+ cancelledTasks: 0,
3174
+ totalDuration: 0,
3175
+ totalWaitTime: 0,
3176
+ };
3177
+
3178
+ constructor(
3179
+ private eventBus: IEventBus,
3180
+ queue?: ITaskQueue,
3181
+ ) {
3182
+ this.queue = queue ?? new TaskQueue();
3183
+ }
3184
+
3185
+ async createTask(params: ITaskCreate): Promise<ITask> {
3186
+ const task: ITask = {
3187
+ id: generateSecureTaskId(),
3188
+ type: params.type,
3189
+ description: params.description,
3190
+ priority: params.priority ?? 50,
3191
+ createdAt: new Date(),
3192
+ status: 'pending',
3193
+ timeout: params.timeout,
3194
+ assignedAgent: params.assignedAgent,
3195
+ input: params.input,
3196
+ metadata: params.metadata,
3197
+ };
3198
+
3199
+ this.tasks.set(task.id, task);
3200
+ this.metrics.totalTasks++;
3201
+
3202
+ this.eventBus.emit(SystemEventTypes.TASK_CREATED, { task });
3203
+
3204
+ return task;
3205
+ }
3206
+
3207
+ getTask(taskId: string): ITask | undefined {
3208
+ return this.tasks.get(taskId);
3209
+ }
3210
+
3211
+ getTasks(filter?: Partial<Pick<ITask, 'status' | 'type' | 'assignedAgent'>>): ITask[] {
3212
+ let tasks = Array.from(this.tasks.values());
3213
+
3214
+ if (filter) {
3215
+ if (filter.status) {
3216
+ tasks = tasks.filter(t => t.status === filter.status);
3217
+ }
3218
+ if (filter.type) {
3219
+ tasks = tasks.filter(t => t.type === filter.type);
3220
+ }
3221
+ if (filter.assignedAgent) {
3222
+ tasks = tasks.filter(t => t.assignedAgent === filter.assignedAgent);
3223
+ }
3224
+ }
3225
+
3226
+ return tasks;
3227
+ }
3228
+
3229
+ async assignTask(taskId: string, agentId: string): Promise<void> {
3230
+ const task = this.tasks.get(taskId);
3231
+ if (!task) {
3232
+ throw new Error(`Task not found: ${taskId}`);
3233
+ }
3234
+
3235
+ task.assignedAgent = agentId;
3236
+ task.status = 'assigned';
3237
+
3238
+ this.eventBus.emit(SystemEventTypes.TASK_ASSIGNED, {
3239
+ taskId,
3240
+ agentId,
3241
+ });
3242
+ }
3243
+
3244
+ async startTask(taskId: string): Promise<void> {
3245
+ const task = this.tasks.get(taskId);
3246
+ if (!task) {
3247
+ throw new Error(`Task not found: ${taskId}`);
3248
+ }
3249
+
3250
+ task.status = 'running';
3251
+ task.startedAt = new Date();
3252
+
3253
+ // Calculate wait time
3254
+ const waitTime = task.startedAt.getTime() - task.createdAt.getTime();
3255
+ this.metrics.totalWaitTime += waitTime;
3256
+
3257
+ this.eventBus.emit(SystemEventTypes.TASK_STARTED, {
3258
+ taskId,
3259
+ agentId: task.assignedAgent,
3260
+ startTime: task.startedAt,
3261
+ });
3262
+ }
3263
+
3264
+ async completeTask(taskId: string, result: ITaskResult): Promise<void> {
3265
+ const task = this.tasks.get(taskId);
3266
+ if (!task) {
3267
+ throw new Error(`Task not found: ${taskId}`);
3268
+ }
3269
+
3270
+ task.status = 'completed';
3271
+ task.completedAt = new Date();
3272
+ task.output = result.output;
3273
+
3274
+ this.metrics.completedTasks++;
3275
+ this.metrics.totalDuration += result.duration;
3276
+
3277
+ this.eventBus.emit(SystemEventTypes.TASK_COMPLETED, {
3278
+ taskId,
3279
+ result,
3280
+ });
3281
+ }
3282
+
3283
+ async failTask(taskId: string, error: Error): Promise<void> {
3284
+ const task = this.tasks.get(taskId);
3285
+ if (!task) {
3286
+ throw new Error(`Task n
3287
+
3288
+ --- src/events/domain-events.ts (truncated) ---
3289
+ /**
3290
+ * Domain Events for Event Sourcing (ADR-007)
3291
+ *
3292
+ * Defines all domain events for the V3 system:
3293
+ * - Agent lifecycle events (spawned, started, stopped, failed)
3294
+ * - Task execution events (created, started, completed, failed)
3295
+ * - Memory operations events (stored, retrieved, deleted)
3296
+ * - Swarm coordination events (initialized, scaled, terminated)
3297
+ *
3298
+ * @module v3/shared/events/domain-events
3299
+ */
3300
+
3301
+ import { AgentId, TaskId, EventType, SwarmEvent } from '../types.js';
3302
+
3303
+ // =============================================================================
3304
+ // Base Domain Event Interface
3305
+ // =============================================================================
3306
+
3307
+ export interface DomainEvent {
3308
+ /** Unique event identifier */
3309
+ id: string;
3310
+
3311
+ /** Event type discriminator */
3312
+ type: string;
3313
+
3314
+ /** Aggregate ID (entity the event belongs to) */
3315
+ aggregateId: string;
3316
+
3317
+ /** Aggregate type (agent, task, memory, swarm) */
3318
+ aggregateType: 'agent' | 'task' | 'memory' | 'swarm';
3319
+
3320
+ /** Event version for ordering */
3321
+ version: number;
3322
+
3323
+ /** Timestamp when event occurred */
3324
+ timestamp: number;
3325
+
3326
+ /** Event source (agent or swarm system) */
3327
+ source: AgentId | 'swarm';
3328
+
3329
+ /** Event payload data */
3330
+ payload: Record<string, unknown>;
3331
+
3332
+ /** Optional metadata */
3333
+ metadata?: Record<string, unknown>;
3334
+
3335
+ /** Optional causation ID (event that caused this event) */
3336
+ causationId?: string;
3337
+
3338
+ /** Optional correlation ID (groups related events) */
3339
+ correlationId?: string;
3340
+ }
3341
+
3342
+ // =============================================================================
3343
+ // Agent Lifecycle Events
3344
+ // =============================================================================
3345
+
3346
+ export interface AgentSpawnedEvent extends DomainEvent {
3347
+ type: 'agent:spawned';
3348
+ aggregateType: 'agent';
3349
+ payload: {
3350
+ agentId: AgentId;
3351
+ role: string;
3352
+ domain: string;
3353
+ capabilities: string[];
3354
+ };
3355
+ }
3356
+
3357
+ export interface AgentStartedEvent extends DomainEvent {
3358
+ type: 'agent:started';
3359
+ aggregateType: 'agent';
3360
+ payload: {
3361
+ agentId: AgentId;
3362
+ startedAt: number;
3363
+ };
3364
+ }
3365
+
3366
+ export interface AgentStoppedEvent extends DomainEvent {
3367
+ type: 'agent:stopped';
3368
+ aggregateType: 'agent';
3369
+ payload: {
3370
+ agentId: AgentId;
3371
+ reason: string;
3372
+ stoppedAt: number;
3373
+ };
3374
+ }
3375
+
3376
+ export interface AgentFailedEvent extends DomainEvent {
3377
+ type: 'agent:failed';
3378
+ aggregateType: 'agent';
3379
+ payload: {
3380
+ agentId: AgentId;
3381
+ error: string;
3382
+ stack?: string;
3383
+ failedAt: number;
3384
+ };
3385
+ }
3386
+
3387
+ export interface AgentStatusChangedEvent extends DomainEvent {
3388
+ type: 'agent:status-changed';
3389
+ aggregateType: 'agent';
3390
+ payload: {
3391
+ agentId: AgentId;
3392
+ previousStatus: string;
3393
+ newStatus: string;
3394
+ };
3395
+ }
3396
+
3397
+ export interface AgentTaskAssignedEvent extends DomainEvent {
3398
+ type: 'agent:task-assigned';
3399
+ aggregateType: 'agent';
3400
+ payload: {
3401
+ agentId: AgentId;
3402
+ taskId: TaskId;
3403
+ assignedAt: number;
3404
+ };
3405
+ }
3406
+
3407
+ export interface AgentTaskCompletedEvent extends DomainEvent {
3408
+ type: 'agent:task-completed';
3409
+ aggregateType: 'agent';
3410
+ payload: {
3411
+ agentId: AgentId;
3412
+ taskId: TaskId;
3413
+ result: unknown;
3414
+ completedAt: number;
3415
+ duration: number;
3416
+ };
3417
+ }
3418
+
3419
+ // =============================================================================
3420
+ // Task Execution Events
3421
+ // =============================================================================
3422
+
3423
+ export interface TaskCreatedEvent extends DomainEvent {
3424
+ type: 'task:created';
3425
+ aggregateType: 'task';
3426
+ payload: {
3427
+ taskId: TaskId;
3428
+ taskType: string;
3429
+ title: string;
3430
+ description: string;
3431
+ priority: string;
3432
+ dependencies: TaskId[];
3433
+ createdAt: number;
3434
+ };
3435
+ }
3436
+
3437
+ export interface TaskStartedEvent extends DomainEvent {
3438
+ type: 'task:started';
3439
+ aggregateType: 'task';
3440
+ payload: {
3441
+ taskId: TaskId;
3442
+ agentId: AgentId;
3443
+ startedAt: number;
3444
+ };
3445
+ }
3446
+
3447
+ export interface TaskCompletedEvent extends DomainEvent {
3448
+ type: 'task:completed';
3449
+ aggregateType: 'task';
3450
+ payload: {
3451
+ taskId: TaskId;
3452
+ result: unknown;
3453
+ completedAt: number;
3454
+ duration: number;
3455
+ };
3456
+ }
3457
+
3458
+ export interface TaskFailedEvent extends DomainEvent {
3459
+ type: 'task:failed';
3460
+ aggregateType: 'task';
3461
+ payload: {
3462
+ taskId: TaskId;
3463
+ error: string;
3464
+ stack?: string;
3465
+ failedAt: number;
3466
+ retryCount: number;
3467
+ };
3468
+ }
3469
+
3470
+ export interface TaskBlockedEvent extends DomainEvent {
3471
+ type: 'task:blocked';
3472
+ aggregateType: 'task';
3473
+ payload: {
3474
+ taskId: TaskId;
3475
+ blockedBy: TaskId[];
3476
+ blockedAt: number;
3477
+ };
3478
+ }
3479
+
3480
+ export interface TaskQueuedEvent extends DomainEvent {
3481
+ type: 'task:queued';
3482
+ aggregateType: 'task';
3483
+ payload: {
3484
+ taskId: TaskId;
3485
+ priority: string;
3486
+ queuedAt: number;
3487
+ };
3488
+ }
3489
+
3490
+ // =============================================================================
3491
+ // Memory Operations Events
3492
+ // =============================================================================
3493
+
3494
+ export interface MemoryStoredEvent extends DomainEvent {
3495
+ type: 'memory:stored';
3496
+ aggregateType: 'memory';
3497
+ payload: {
3498
+ memoryId: string;
3499
+ namespace: string;
3500
+ key: s
3501
+
3502
+ ## Instructions
3503
+
3504
+ Analyze the above codebase context and provide your response following the format specified in the task.