@sparkleideas/shared 3.0.0-alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +323 -0
  2. package/__tests__/hooks/bash-safety.test.ts +289 -0
  3. package/__tests__/hooks/file-organization.test.ts +335 -0
  4. package/__tests__/hooks/git-commit.test.ts +336 -0
  5. package/__tests__/hooks/index.ts +23 -0
  6. package/__tests__/hooks/session-hooks.test.ts +357 -0
  7. package/__tests__/hooks/task-hooks.test.ts +193 -0
  8. package/docs/EVENTS_IMPLEMENTATION_SUMMARY.md +388 -0
  9. package/docs/EVENTS_QUICK_REFERENCE.md +470 -0
  10. package/docs/EVENTS_README.md +352 -0
  11. package/package.json +39 -0
  12. package/src/core/config/defaults.ts +207 -0
  13. package/src/core/config/index.ts +15 -0
  14. package/src/core/config/loader.ts +271 -0
  15. package/src/core/config/schema.ts +188 -0
  16. package/src/core/config/validator.ts +209 -0
  17. package/src/core/event-bus.ts +236 -0
  18. package/src/core/index.ts +22 -0
  19. package/src/core/interfaces/agent.interface.ts +251 -0
  20. package/src/core/interfaces/coordinator.interface.ts +363 -0
  21. package/src/core/interfaces/event.interface.ts +267 -0
  22. package/src/core/interfaces/index.ts +19 -0
  23. package/src/core/interfaces/memory.interface.ts +332 -0
  24. package/src/core/interfaces/task.interface.ts +223 -0
  25. package/src/core/orchestrator/event-coordinator.ts +122 -0
  26. package/src/core/orchestrator/health-monitor.ts +214 -0
  27. package/src/core/orchestrator/index.ts +89 -0
  28. package/src/core/orchestrator/lifecycle-manager.ts +263 -0
  29. package/src/core/orchestrator/session-manager.ts +279 -0
  30. package/src/core/orchestrator/task-manager.ts +317 -0
  31. package/src/events/domain-events.ts +584 -0
  32. package/src/events/event-store.test.ts +387 -0
  33. package/src/events/event-store.ts +588 -0
  34. package/src/events/example-usage.ts +293 -0
  35. package/src/events/index.ts +90 -0
  36. package/src/events/projections.ts +561 -0
  37. package/src/events/state-reconstructor.ts +349 -0
  38. package/src/events.ts +367 -0
  39. package/src/hooks/INTEGRATION.md +658 -0
  40. package/src/hooks/README.md +532 -0
  41. package/src/hooks/example-usage.ts +499 -0
  42. package/src/hooks/executor.ts +379 -0
  43. package/src/hooks/hooks.test.ts +421 -0
  44. package/src/hooks/index.ts +131 -0
  45. package/src/hooks/registry.ts +333 -0
  46. package/src/hooks/safety/bash-safety.ts +604 -0
  47. package/src/hooks/safety/file-organization.ts +473 -0
  48. package/src/hooks/safety/git-commit.ts +623 -0
  49. package/src/hooks/safety/index.ts +46 -0
  50. package/src/hooks/session-hooks.ts +559 -0
  51. package/src/hooks/task-hooks.ts +513 -0
  52. package/src/hooks/types.ts +357 -0
  53. package/src/hooks/verify-exports.test.ts +125 -0
  54. package/src/index.ts +195 -0
  55. package/src/mcp/connection-pool.ts +438 -0
  56. package/src/mcp/index.ts +183 -0
  57. package/src/mcp/server.ts +774 -0
  58. package/src/mcp/session-manager.ts +428 -0
  59. package/src/mcp/tool-registry.ts +566 -0
  60. package/src/mcp/transport/http.ts +557 -0
  61. package/src/mcp/transport/index.ts +294 -0
  62. package/src/mcp/transport/stdio.ts +324 -0
  63. package/src/mcp/transport/websocket.ts +484 -0
  64. package/src/mcp/types.ts +565 -0
  65. package/src/plugin-interface.ts +663 -0
  66. package/src/plugin-loader.ts +638 -0
  67. package/src/plugin-registry.ts +604 -0
  68. package/src/plugins/index.ts +34 -0
  69. package/src/plugins/official/hive-mind-plugin.ts +330 -0
  70. package/src/plugins/official/index.ts +24 -0
  71. package/src/plugins/official/maestro-plugin.ts +508 -0
  72. package/src/plugins/types.ts +108 -0
  73. package/src/resilience/bulkhead.ts +277 -0
  74. package/src/resilience/circuit-breaker.ts +326 -0
  75. package/src/resilience/index.ts +26 -0
  76. package/src/resilience/rate-limiter.ts +420 -0
  77. package/src/resilience/retry.ts +224 -0
  78. package/src/security/index.ts +39 -0
  79. package/src/security/input-validation.ts +265 -0
  80. package/src/security/secure-random.ts +159 -0
  81. package/src/services/index.ts +16 -0
  82. package/src/services/v3-progress.service.ts +505 -0
  83. package/src/types/agent.types.ts +144 -0
  84. package/src/types/index.ts +22 -0
  85. package/src/types/mcp.types.ts +300 -0
  86. package/src/types/memory.types.ts +263 -0
  87. package/src/types/swarm.types.ts +255 -0
  88. package/src/types/task.types.ts +205 -0
  89. package/src/types.ts +367 -0
  90. package/src/utils/secure-logger.d.ts +69 -0
  91. package/src/utils/secure-logger.d.ts.map +1 -0
  92. package/src/utils/secure-logger.js +208 -0
  93. package/src/utils/secure-logger.js.map +1 -0
  94. package/src/utils/secure-logger.ts +257 -0
  95. package/tmp.json +0 -0
  96. package/tsconfig.json +9 -0
@@ -0,0 +1,332 @@
1
+ /**
2
+ * V3 Memory Interfaces
3
+ * Domain-Driven Design - Memory Management Bounded Context
4
+ * Aligned with ADR-006 (Unified Memory Service) and ADR-009 (Hybrid Memory Backend)
5
+ */
6
+
7
+ /**
8
+ * Memory entry types
9
+ */
10
+ export type MemoryType = 'session' | 'persistent' | 'vector' | 'cache' | 'pattern';
11
+
12
+ /**
13
+ * Memory entry structure
14
+ */
15
+ export interface IMemoryEntry {
16
+ readonly id: string;
17
+ readonly key: string;
18
+ readonly type: MemoryType;
19
+ readonly createdAt: Date;
20
+
21
+ value: unknown;
22
+ updatedAt: Date;
23
+ expiresAt?: Date;
24
+
25
+ metadata?: {
26
+ source?: string;
27
+ agentId?: string;
28
+ sessionId?: string;
29
+ version?: number;
30
+ tags?: string[];
31
+ embedding?: number[];
32
+ [key: string]: unknown;
33
+ };
34
+ }
35
+
36
+ /**
37
+ * Memory entry creation parameters
38
+ */
39
+ export interface IMemoryEntryCreate {
40
+ key: string;
41
+ value: unknown;
42
+ type?: MemoryType;
43
+ expiresAt?: Date;
44
+ ttlMs?: number;
45
+ metadata?: IMemoryEntry['metadata'];
46
+ }
47
+
48
+ /**
49
+ * Vector search parameters
50
+ */
51
+ export interface IVectorSearchParams {
52
+ embedding: number[];
53
+ k?: number;
54
+ threshold?: number;
55
+ filter?: {
56
+ type?: MemoryType;
57
+ tags?: string[];
58
+ agentId?: string;
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Vector search result
64
+ */
65
+ export interface IVectorSearchResult {
66
+ entry: IMemoryEntry;
67
+ score: number;
68
+ distance: number;
69
+ }
70
+
71
+ /**
72
+ * Memory backend interface for storage operations
73
+ */
74
+ export interface IMemoryBackend {
75
+ /**
76
+ * Initialize the backend
77
+ */
78
+ initialize(): Promise<void>;
79
+
80
+ /**
81
+ * Shutdown the backend
82
+ */
83
+ shutdown(): Promise<void>;
84
+
85
+ /**
86
+ * Store a memory entry
87
+ */
88
+ store(entry: IMemoryEntryCreate): Promise<IMemoryEntry>;
89
+
90
+ /**
91
+ * Retrieve a memory entry by key
92
+ */
93
+ retrieve(key: string): Promise<IMemoryEntry | undefined>;
94
+
95
+ /**
96
+ * Retrieve by ID
97
+ */
98
+ retrieveById(id: string): Promise<IMemoryEntry | undefined>;
99
+
100
+ /**
101
+ * Update a memory entry
102
+ */
103
+ update(key: string, value: unknown, metadata?: Partial<IMemoryEntry['metadata']>): Promise<IMemoryEntry | undefined>;
104
+
105
+ /**
106
+ * Delete a memory entry
107
+ */
108
+ delete(key: string): Promise<boolean>;
109
+
110
+ /**
111
+ * Check if a key exists
112
+ */
113
+ exists(key: string): Promise<boolean>;
114
+
115
+ /**
116
+ * List all keys matching a pattern
117
+ */
118
+ keys(pattern?: string): Promise<string[]>;
119
+
120
+ /**
121
+ * Get all entries matching filter
122
+ */
123
+ list(filter?: { type?: MemoryType; tags?: string[] }): Promise<IMemoryEntry[]>;
124
+
125
+ /**
126
+ * Clear all entries
127
+ */
128
+ clear(): Promise<void>;
129
+
130
+ /**
131
+ * Get entry count
132
+ */
133
+ count(): Promise<number>;
134
+
135
+ /**
136
+ * Prune expired entries
137
+ */
138
+ prune(): Promise<number>;
139
+
140
+ /**
141
+ * Get health status
142
+ */
143
+ getHealthStatus(): Promise<{ healthy: boolean; error?: string; metrics?: Record<string, number> }>;
144
+ }
145
+
146
+ /**
147
+ * Vector memory backend for similarity search
148
+ */
149
+ export interface IVectorMemoryBackend extends IMemoryBackend {
150
+ /**
151
+ * Store with embedding
152
+ */
153
+ storeVector(entry: IMemoryEntryCreate & { embedding: number[] }): Promise<IMemoryEntry>;
154
+
155
+ /**
156
+ * Search by vector similarity
157
+ */
158
+ search(params: IVectorSearchParams): Promise<IVectorSearchResult[]>;
159
+
160
+ /**
161
+ * Update embedding for an entry
162
+ */
163
+ updateEmbedding(key: string, embedding: number[]): Promise<boolean>;
164
+
165
+ /**
166
+ * Build or rebuild index
167
+ */
168
+ buildIndex(): Promise<void>;
169
+
170
+ /**
171
+ * Get index statistics
172
+ */
173
+ getIndexStats(): Promise<{
174
+ vectorCount: number;
175
+ dimensions: number;
176
+ indexType: string;
177
+ memoryUsageMb: number;
178
+ }>;
179
+ }
180
+
181
+ /**
182
+ * Memory bank for agent-specific storage
183
+ */
184
+ export interface IMemoryBank {
185
+ readonly id: string;
186
+ readonly agentId: string;
187
+ readonly createdAt: Date;
188
+
189
+ /**
190
+ * Store in bank
191
+ */
192
+ store(key: string, value: unknown, options?: Partial<IMemoryEntryCreate>): Promise<IMemoryEntry>;
193
+
194
+ /**
195
+ * Retrieve from bank
196
+ */
197
+ retrieve(key: string): Promise<IMemoryEntry | undefined>;
198
+
199
+ /**
200
+ * Delete from bank
201
+ */
202
+ delete(key: string): Promise<boolean>;
203
+
204
+ /**
205
+ * List all entries in bank
206
+ */
207
+ list(): Promise<IMemoryEntry[]>;
208
+
209
+ /**
210
+ * Clear all entries in bank
211
+ */
212
+ clear(): Promise<void>;
213
+
214
+ /**
215
+ * Get bank size
216
+ */
217
+ size(): Promise<number>;
218
+
219
+ /**
220
+ * Close the bank
221
+ */
222
+ close(): Promise<void>;
223
+ }
224
+
225
+ /**
226
+ * Memory manager interface
227
+ */
228
+ export interface IMemoryManager {
229
+ /**
230
+ * Initialize the manager
231
+ */
232
+ initialize(): Promise<void>;
233
+
234
+ /**
235
+ * Shutdown the manager
236
+ */
237
+ shutdown(): Promise<void>;
238
+
239
+ /**
240
+ * Create a memory bank for an agent
241
+ */
242
+ createBank(agentId: string): Promise<string>;
243
+
244
+ /**
245
+ * Get a memory bank
246
+ */
247
+ getBank(bankId: string): IMemoryBank | undefined;
248
+
249
+ /**
250
+ * Close a memory bank
251
+ */
252
+ closeBank(bankId: string): Promise<void>;
253
+
254
+ /**
255
+ * Store in global memory
256
+ */
257
+ store(entry: IMemoryEntryCreate): Promise<IMemoryEntry>;
258
+
259
+ /**
260
+ * Retrieve from global memory
261
+ */
262
+ retrieve(key: string): Promise<IMemoryEntry | undefined>;
263
+
264
+ /**
265
+ * Search vectors (if vector backend available)
266
+ */
267
+ searchVectors?(params: IVectorSearchParams): Promise<IVectorSearchResult[]>;
268
+
269
+ /**
270
+ * Perform maintenance
271
+ */
272
+ performMaintenance(): Promise<void>;
273
+
274
+ /**
275
+ * Get health status
276
+ */
277
+ getHealthStatus(): Promise<{ healthy: boolean; error?: string; metrics?: Record<string, number> }>;
278
+
279
+ /**
280
+ * Get memory usage statistics
281
+ */
282
+ getStats(): Promise<{
283
+ totalEntries: number;
284
+ memoryUsageMb: number;
285
+ banksCount: number;
286
+ cacheHitRate?: number;
287
+ }>;
288
+ }
289
+
290
+ /**
291
+ * Pattern storage for ReasoningBank integration
292
+ */
293
+ export interface IPatternStorage {
294
+ /**
295
+ * Store a learned pattern
296
+ */
297
+ storePattern(pattern: {
298
+ sessionId: string;
299
+ task: string;
300
+ input: string;
301
+ output: string;
302
+ reward: number;
303
+ success: boolean;
304
+ critique?: string;
305
+ tokensUsed?: number;
306
+ latencyMs?: number;
307
+ }): Promise<void>;
308
+
309
+ /**
310
+ * Search for similar patterns
311
+ */
312
+ searchPatterns(params: {
313
+ task: string;
314
+ k?: number;
315
+ minReward?: number;
316
+ onlyFailures?: boolean;
317
+ }): Promise<Array<{
318
+ task: string;
319
+ reward: number;
320
+ critique: string;
321
+ output: string;
322
+ }>>;
323
+
324
+ /**
325
+ * Get pattern statistics
326
+ */
327
+ getPatternStats(): Promise<{
328
+ totalPatterns: number;
329
+ avgReward: number;
330
+ successRate: number;
331
+ }>;
332
+ }
@@ -0,0 +1,223 @@
1
+ /**
2
+ * V3 Task Interfaces
3
+ * Domain-Driven Design - Task Bounded Context
4
+ */
5
+
6
+ /**
7
+ * Task priority levels
8
+ */
9
+ export type TaskPriority = 'critical' | 'high' | 'medium' | 'low';
10
+
11
+ /**
12
+ * Task status throughout its lifecycle
13
+ */
14
+ export type TaskStatus =
15
+ | 'pending'
16
+ | 'queued'
17
+ | 'assigned'
18
+ | 'running'
19
+ | 'completed'
20
+ | 'failed'
21
+ | 'cancelled'
22
+ | 'timeout';
23
+
24
+ /**
25
+ * Core task entity
26
+ */
27
+ export interface ITask {
28
+ readonly id: string;
29
+ readonly type: string;
30
+ readonly description: string;
31
+ readonly priority: number;
32
+ readonly createdAt: Date;
33
+
34
+ status: TaskStatus;
35
+ assignedAgent?: string;
36
+ startedAt?: Date;
37
+ completedAt?: Date;
38
+ timeout?: number;
39
+
40
+ input?: Record<string, unknown>;
41
+ output?: Record<string, unknown>;
42
+ error?: Error;
43
+
44
+ metadata?: {
45
+ requiredCapabilities?: string[];
46
+ retryCount?: number;
47
+ maxRetries?: number;
48
+ critical?: boolean;
49
+ parentTaskId?: string;
50
+ childTaskIds?: string[];
51
+ tags?: string[];
52
+ [key: string]: unknown;
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Task creation parameters
58
+ */
59
+ export interface ITaskCreate {
60
+ type: string;
61
+ description: string;
62
+ priority?: number;
63
+ timeout?: number;
64
+ assignedAgent?: string;
65
+ input?: Record<string, unknown>;
66
+ metadata?: ITask['metadata'];
67
+ }
68
+
69
+ /**
70
+ * Task result after completion
71
+ */
72
+ export interface ITaskResult {
73
+ taskId: string;
74
+ success: boolean;
75
+ output?: Record<string, unknown>;
76
+ error?: Error;
77
+ duration: number;
78
+ agentId?: string;
79
+ metrics?: {
80
+ tokensUsed?: number;
81
+ memoryPeakMb?: number;
82
+ retryCount?: number;
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Task queue interface for managing task ordering and processing
88
+ */
89
+ export interface ITaskQueue {
90
+ /**
91
+ * Add a task to the queue
92
+ */
93
+ enqueue(task: ITask): Promise<void>;
94
+
95
+ /**
96
+ * Remove and return the highest priority task
97
+ */
98
+ dequeue(): Promise<ITask | undefined>;
99
+
100
+ /**
101
+ * Peek at the next task without removing it
102
+ */
103
+ peek(): Promise<ITask | undefined>;
104
+
105
+ /**
106
+ * Get the current queue size
107
+ */
108
+ size(): number;
109
+
110
+ /**
111
+ * Check if the queue is empty
112
+ */
113
+ isEmpty(): boolean;
114
+
115
+ /**
116
+ * Clear all tasks from the queue
117
+ */
118
+ clear(): Promise<void>;
119
+
120
+ /**
121
+ * Get all queued tasks (for inspection)
122
+ */
123
+ getAll(): Promise<ITask[]>;
124
+
125
+ /**
126
+ * Remove a specific task by ID
127
+ */
128
+ remove(taskId: string): Promise<boolean>;
129
+
130
+ /**
131
+ * Update task priority
132
+ */
133
+ updatePriority(taskId: string, priority: number): Promise<boolean>;
134
+ }
135
+
136
+ /**
137
+ * Task manager interface for lifecycle management
138
+ */
139
+ export interface ITaskManager {
140
+ /**
141
+ * Create a new task
142
+ */
143
+ createTask(params: ITaskCreate): Promise<ITask>;
144
+
145
+ /**
146
+ * Get a task by ID
147
+ */
148
+ getTask(taskId: string): ITask | undefined;
149
+
150
+ /**
151
+ * Get all tasks matching optional filter
152
+ */
153
+ getTasks(filter?: Partial<Pick<ITask, 'status' | 'type' | 'assignedAgent'>>): ITask[];
154
+
155
+ /**
156
+ * Assign a task to an agent
157
+ */
158
+ assignTask(taskId: string, agentId: string): Promise<void>;
159
+
160
+ /**
161
+ * Start task execution
162
+ */
163
+ startTask(taskId: string): Promise<void>;
164
+
165
+ /**
166
+ * Complete a task with result
167
+ */
168
+ completeTask(taskId: string, result: ITaskResult): Promise<void>;
169
+
170
+ /**
171
+ * Fail a task with error
172
+ */
173
+ failTask(taskId: string, error: Error): Promise<void>;
174
+
175
+ /**
176
+ * Cancel a task
177
+ */
178
+ cancelTask(taskId: string, reason?: string): Promise<void>;
179
+
180
+ /**
181
+ * Retry a failed task
182
+ */
183
+ retryTask(taskId: string): Promise<void>;
184
+
185
+ /**
186
+ * Get task metrics
187
+ */
188
+ getMetrics(): TaskManagerMetrics;
189
+
190
+ /**
191
+ * Clean up old completed/failed tasks
192
+ */
193
+ cleanup(olderThan: Date): Promise<number>;
194
+ }
195
+
196
+ /**
197
+ * Task manager metrics
198
+ */
199
+ export interface TaskManagerMetrics {
200
+ totalTasks: number;
201
+ pendingTasks: number;
202
+ runningTasks: number;
203
+ completedTasks: number;
204
+ failedTasks: number;
205
+ cancelledTasks: number;
206
+ avgDuration: number;
207
+ avgWaitTime: number;
208
+ }
209
+
210
+ /**
211
+ * Task assignment strategy interface
212
+ */
213
+ export interface ITaskAssignmentStrategy {
214
+ /**
215
+ * Select the best agent for a task
216
+ */
217
+ selectAgent(task: ITask, availableAgents: string[]): Promise<string | undefined>;
218
+
219
+ /**
220
+ * Score an agent for a task (higher is better)
221
+ */
222
+ scoreAgent(task: ITask, agentId: string): Promise<number>;
223
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * V3 Event Coordinator
3
+ * Decomposed from orchestrator.ts - Event routing
4
+ * ~100 lines (target achieved)
5
+ */
6
+
7
+ import type {
8
+ IEvent,
9
+ IEventBus,
10
+ IEventHandler,
11
+ IEventCoordinator,
12
+ } from '../interfaces/event.interface.js';
13
+ import { SystemEventTypes } from '../interfaces/event.interface.js';
14
+
15
+ /**
16
+ * Event coordinator implementation
17
+ */
18
+ export class EventCoordinator implements IEventCoordinator {
19
+ private handlers = new Map<string, Set<IEventHandler>>();
20
+ private initialized = false;
21
+
22
+ constructor(private eventBus: IEventBus) {}
23
+
24
+ async initialize(): Promise<void> {
25
+ if (this.initialized) {
26
+ return;
27
+ }
28
+
29
+ // Register default system event handlers
30
+ this.registerSystemHandlers();
31
+
32
+ this.initialized = true;
33
+ }
34
+
35
+ async shutdown(): Promise<void> {
36
+ // Clear all handlers
37
+ this.handlers.clear();
38
+ this.initialized = false;
39
+ }
40
+
41
+ async route(event: IEvent): Promise<void> {
42
+ const handlers = this.handlers.get(event.type);
43
+ if (!handlers || handlers.size === 0) {
44
+ return;
45
+ }
46
+
47
+ const handlerPromises = Array.from(handlers).map(async handler => {
48
+ try {
49
+ await handler(event);
50
+ } catch (error) {
51
+ // Log error but don't throw
52
+ console.error(`Error in event handler for ${event.type}:`, error);
53
+ }
54
+ });
55
+
56
+ await Promise.allSettled(handlerPromises);
57
+ }
58
+
59
+ registerHandler(type: string, handler: IEventHandler): void {
60
+ let handlers = this.handlers.get(type);
61
+ if (!handlers) {
62
+ handlers = new Set();
63
+ this.handlers.set(type, handlers);
64
+ }
65
+ handlers.add(handler);
66
+
67
+ // Also register with event bus
68
+ this.eventBus.on(type, handler);
69
+ }
70
+
71
+ unregisterHandler(type: string, handler: IEventHandler): void {
72
+ const handlers = this.handlers.get(type);
73
+ if (handlers) {
74
+ handlers.delete(handler);
75
+ if (handlers.size === 0) {
76
+ this.handlers.delete(type);
77
+ }
78
+ }
79
+
80
+ // Also unregister from event bus
81
+ this.eventBus.off(type, handler);
82
+ }
83
+
84
+ getEventBus(): IEventBus {
85
+ return this.eventBus;
86
+ }
87
+
88
+ private registerSystemHandlers(): void {
89
+ // Error handling
90
+ this.eventBus.on(SystemEventTypes.SYSTEM_ERROR, (event: IEvent) => {
91
+ const { error, component } = event.payload as { error: Error; component: string };
92
+ console.error(`System error in ${component}:`, error);
93
+ });
94
+
95
+ // Deadlock detection
96
+ this.eventBus.on(SystemEventTypes.DEADLOCK_DETECTED, (event: IEvent) => {
97
+ const { agents, resources } = event.payload as { agents: string[]; resources: string[] };
98
+ console.warn('Deadlock detected:', { agents, resources });
99
+ });
100
+ }
101
+
102
+ /**
103
+ * Get registered handler count for a type
104
+ */
105
+ getHandlerCount(type: string): number {
106
+ return this.handlers.get(type)?.size ?? 0;
107
+ }
108
+
109
+ /**
110
+ * Get all registered event types
111
+ */
112
+ getRegisteredTypes(): string[] {
113
+ return Array.from(this.handlers.keys());
114
+ }
115
+
116
+ /**
117
+ * Check if coordinator is initialized
118
+ */
119
+ isInitialized(): boolean {
120
+ return this.initialized;
121
+ }
122
+ }