@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,236 @@
1
+ /**
2
+ * V3 Event Bus
3
+ * Core event pub/sub implementation
4
+ */
5
+
6
+ import type {
7
+ IEvent,
8
+ IEventBus,
9
+ IEventCreate,
10
+ IEventHandler,
11
+ IEventSubscription,
12
+ IEventFilter,
13
+ } from './interfaces/event.interface.js';
14
+ import { randomBytes } from 'crypto';
15
+
16
+ // Secure event ID generation
17
+ function generateSecureEventId(): string {
18
+ const timestamp = Date.now().toString(36);
19
+ const random = randomBytes(12).toString('hex');
20
+ return `evt_${timestamp}_${random}`;
21
+ }
22
+
23
+ /**
24
+ * Event subscription implementation
25
+ */
26
+ class EventSubscription implements IEventSubscription {
27
+ private active = true;
28
+ private paused = false;
29
+
30
+ constructor(
31
+ readonly id: string,
32
+ readonly filter: IEventFilter,
33
+ private removeCallback: () => void,
34
+ ) {}
35
+
36
+ unsubscribe(): void {
37
+ this.active = false;
38
+ this.removeCallback();
39
+ }
40
+
41
+ pause(): void {
42
+ this.paused = true;
43
+ }
44
+
45
+ resume(): void {
46
+ this.paused = false;
47
+ }
48
+
49
+ isActive(): boolean {
50
+ return this.active && !this.paused;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Event bus implementation
56
+ */
57
+ export class EventBus implements IEventBus {
58
+ private handlers = new Map<string, Set<IEventHandler>>();
59
+ private subscriptions = new Map<string, { filter: IEventFilter; handler: IEventHandler; subscription: EventSubscription }>();
60
+ private subscriptionId = 0;
61
+
62
+ emit<T = unknown>(type: string, payload: T, options?: Partial<IEventCreate<T>>): void {
63
+ const event = this.createEvent(type, payload, options);
64
+ this.dispatchEvent(event);
65
+ }
66
+
67
+ async emitAsync<T = unknown>(type: string, payload: T, options?: Partial<IEventCreate<T>>): Promise<void> {
68
+ const event = this.createEvent(type, payload, options);
69
+ await this.dispatchEventAsync(event);
70
+ }
71
+
72
+ on<T = unknown>(type: string, handler: IEventHandler<T>): IEventSubscription {
73
+ return this.subscribe({ types: [type] }, handler);
74
+ }
75
+
76
+ subscribe<T = unknown>(filter: IEventFilter, handler: IEventHandler<T>): IEventSubscription {
77
+ const id = `sub_${++this.subscriptionId}`;
78
+
79
+ // Register for all matching types
80
+ const types = filter.types ?? ['*'];
81
+ for (const type of types) {
82
+ let handlers = this.handlers.get(type);
83
+ if (!handlers) {
84
+ handlers = new Set();
85
+ this.handlers.set(type, handlers);
86
+ }
87
+ handlers.add(handler as IEventHandler);
88
+ }
89
+
90
+ const subscription = new EventSubscription(id, filter, () => {
91
+ this.removeSubscription(id);
92
+ });
93
+
94
+ this.subscriptions.set(id, { filter, handler: handler as IEventHandler, subscription });
95
+
96
+ return subscription;
97
+ }
98
+
99
+ once<T = unknown>(type: string, handler: IEventHandler<T>): IEventSubscription {
100
+ const wrappedHandler: IEventHandler<T> = async (event) => {
101
+ subscription.unsubscribe();
102
+ await handler(event);
103
+ };
104
+
105
+ const subscription = this.on(type, wrappedHandler);
106
+ return subscription;
107
+ }
108
+
109
+ off(type: string, handler: IEventHandler): void {
110
+ const handlers = this.handlers.get(type);
111
+ if (handlers) {
112
+ handlers.delete(handler);
113
+ if (handlers.size === 0) {
114
+ this.handlers.delete(type);
115
+ }
116
+ }
117
+ }
118
+
119
+ removeAllListeners(type?: string): void {
120
+ if (type) {
121
+ this.handlers.delete(type);
122
+ } else {
123
+ this.handlers.clear();
124
+ }
125
+ }
126
+
127
+ listenerCount(type: string): number {
128
+ return this.handlers.get(type)?.size ?? 0;
129
+ }
130
+
131
+ eventNames(): string[] {
132
+ return Array.from(this.handlers.keys());
133
+ }
134
+
135
+ private createEvent<T>(type: string, payload: T, options?: Partial<IEventCreate<T>>): IEvent<T> {
136
+ return {
137
+ id: generateSecureEventId(),
138
+ type,
139
+ timestamp: new Date(),
140
+ source: options?.source ?? 'event-bus',
141
+ payload,
142
+ priority: options?.priority,
143
+ correlationId: options?.correlationId,
144
+ causationId: options?.causationId,
145
+ metadata: options?.metadata,
146
+ };
147
+ }
148
+
149
+ private dispatchEvent<T>(event: IEvent<T>): void {
150
+ // Get handlers for specific type
151
+ const typeHandlers = this.handlers.get(event.type);
152
+
153
+ // Get wildcard handlers
154
+ const wildcardHandlers = this.handlers.get('*');
155
+
156
+ const allHandlers = new Set<IEventHandler>();
157
+
158
+ if (typeHandlers) {
159
+ for (const handler of typeHandlers) {
160
+ allHandlers.add(handler);
161
+ }
162
+ }
163
+
164
+ if (wildcardHandlers) {
165
+ for (const handler of wildcardHandlers) {
166
+ allHandlers.add(handler);
167
+ }
168
+ }
169
+
170
+ for (const handler of allHandlers) {
171
+ try {
172
+ const result = handler(event);
173
+ if (result instanceof Promise) {
174
+ result.catch((error) => {
175
+ console.error(`Error in async event handler for ${event.type}:`, error);
176
+ });
177
+ }
178
+ } catch (error) {
179
+ console.error(`Error in event handler for ${event.type}:`, error);
180
+ }
181
+ }
182
+ }
183
+
184
+ private async dispatchEventAsync<T>(event: IEvent<T>): Promise<void> {
185
+ const typeHandlers = this.handlers.get(event.type);
186
+ const wildcardHandlers = this.handlers.get('*');
187
+
188
+ const allHandlers = new Set<IEventHandler>();
189
+
190
+ if (typeHandlers) {
191
+ for (const handler of typeHandlers) {
192
+ allHandlers.add(handler);
193
+ }
194
+ }
195
+
196
+ if (wildcardHandlers) {
197
+ for (const handler of wildcardHandlers) {
198
+ allHandlers.add(handler);
199
+ }
200
+ }
201
+
202
+ const promises = Array.from(allHandlers).map(async (handler) => {
203
+ try {
204
+ await handler(event);
205
+ } catch (error) {
206
+ console.error(`Error in event handler for ${event.type}:`, error);
207
+ }
208
+ });
209
+
210
+ await Promise.allSettled(promises);
211
+ }
212
+
213
+ private removeSubscription(id: string): void {
214
+ const sub = this.subscriptions.get(id);
215
+ if (sub) {
216
+ const types = sub.filter.types ?? ['*'];
217
+ for (const type of types) {
218
+ const handlers = this.handlers.get(type);
219
+ if (handlers) {
220
+ handlers.delete(sub.handler);
221
+ if (handlers.size === 0) {
222
+ this.handlers.delete(type);
223
+ }
224
+ }
225
+ }
226
+ this.subscriptions.delete(id);
227
+ }
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Create a new event bus instance
233
+ */
234
+ export function createEventBus(): IEventBus {
235
+ return new EventBus();
236
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * V3 Core Module - Public API
3
+ * Domain-Driven Design with Clean Architecture
4
+ *
5
+ * This module provides the core architecture for @sparkleideas/claude-flow v3:
6
+ * - Decomposed orchestrator (task, session, health, lifecycle management)
7
+ * - Event-driven architecture with event bus and coordinator
8
+ * - Type-safe configuration with Zod validation
9
+ * - Clean interfaces following DDD principles
10
+ */
11
+
12
+ // Interfaces (Domain contracts)
13
+ export * from './interfaces/index.js';
14
+
15
+ // Event system
16
+ export { EventBus, createEventBus } from './event-bus.js';
17
+
18
+ // Orchestrator components (decomposed)
19
+ export * from './orchestrator/index.js';
20
+
21
+ // Configuration
22
+ export * from './config/index.js';
@@ -0,0 +1,251 @@
1
+ /**
2
+ * V3 Agent Interfaces
3
+ * Domain-Driven Design - Agent Lifecycle Bounded Context
4
+ */
5
+
6
+ /**
7
+ * Agent status in the system
8
+ */
9
+ export type AgentStatus = 'spawning' | 'active' | 'idle' | 'busy' | 'error' | 'terminated';
10
+
11
+ /**
12
+ * Agent type classification
13
+ */
14
+ export type AgentType =
15
+ | 'coder'
16
+ | 'reviewer'
17
+ | 'tester'
18
+ | 'researcher'
19
+ | 'planner'
20
+ | 'architect'
21
+ | 'coordinator'
22
+ | 'security'
23
+ | 'performance'
24
+ | 'custom';
25
+
26
+ /**
27
+ * Agent capability declaration
28
+ */
29
+ export interface IAgentCapability {
30
+ name: string;
31
+ level: 'basic' | 'intermediate' | 'advanced' | 'expert';
32
+ description?: string;
33
+ }
34
+
35
+ /**
36
+ * Agent configuration for spawning
37
+ */
38
+ export interface IAgentConfig {
39
+ readonly id: string;
40
+ readonly name: string;
41
+ readonly type: AgentType | string;
42
+
43
+ capabilities: string[];
44
+ maxConcurrentTasks: number;
45
+ priority: number;
46
+
47
+ timeout?: number;
48
+ retryPolicy?: {
49
+ maxRetries: number;
50
+ backoffMs: number;
51
+ backoffMultiplier: number;
52
+ };
53
+
54
+ resources?: {
55
+ maxMemoryMb?: number;
56
+ maxCpuPercent?: number;
57
+ };
58
+
59
+ metadata?: Record<string, unknown>;
60
+ }
61
+
62
+ /**
63
+ * Core agent entity
64
+ */
65
+ export interface IAgent {
66
+ readonly id: string;
67
+ readonly name: string;
68
+ readonly type: AgentType | string;
69
+ readonly config: IAgentConfig;
70
+ readonly createdAt: Date;
71
+
72
+ status: AgentStatus;
73
+ currentTaskCount: number;
74
+ lastActivity: Date;
75
+
76
+ sessionId?: string;
77
+ terminalId?: string;
78
+ memoryBankId?: string;
79
+
80
+ metrics?: {
81
+ tasksCompleted: number;
82
+ tasksFailed: number;
83
+ avgTaskDuration: number;
84
+ errorCount: number;
85
+ uptime: number;
86
+ };
87
+
88
+ health?: {
89
+ status: 'healthy' | 'degraded' | 'unhealthy';
90
+ lastCheck: Date;
91
+ issues?: string[];
92
+ };
93
+ }
94
+
95
+ /**
96
+ * Agent session for tracking active work
97
+ */
98
+ export interface IAgentSession {
99
+ readonly id: string;
100
+ readonly agentId: string;
101
+ readonly startTime: Date;
102
+
103
+ status: 'active' | 'idle' | 'terminated';
104
+ terminalId: string;
105
+ memoryBankId: string;
106
+
107
+ lastActivity: Date;
108
+ endTime?: Date;
109
+
110
+ metadata?: Record<string, unknown>;
111
+ }
112
+
113
+ /**
114
+ * Agent pool for managing multiple agents
115
+ */
116
+ export interface IAgentPool {
117
+ /**
118
+ * Add an agent to the pool
119
+ */
120
+ add(agent: IAgent): void;
121
+
122
+ /**
123
+ * Remove an agent from the pool
124
+ */
125
+ remove(agentId: string): boolean;
126
+
127
+ /**
128
+ * Get an agent by ID
129
+ */
130
+ get(agentId: string): IAgent | undefined;
131
+
132
+ /**
133
+ * Get all agents in the pool
134
+ */
135
+ getAll(): IAgent[];
136
+
137
+ /**
138
+ * Get agents by status
139
+ */
140
+ getByStatus(status: AgentStatus): IAgent[];
141
+
142
+ /**
143
+ * Get agents by type
144
+ */
145
+ getByType(type: AgentType | string): IAgent[];
146
+
147
+ /**
148
+ * Get available agents (can accept more tasks)
149
+ */
150
+ getAvailable(): IAgent[];
151
+
152
+ /**
153
+ * Get pool size
154
+ */
155
+ size(): number;
156
+
157
+ /**
158
+ * Check if pool has capacity
159
+ */
160
+ hasCapacity(maxSize: number): boolean;
161
+
162
+ /**
163
+ * Clear all agents
164
+ */
165
+ clear(): void;
166
+ }
167
+
168
+ /**
169
+ * Agent lifecycle manager interface
170
+ */
171
+ export interface IAgentLifecycleManager {
172
+ /**
173
+ * Spawn a new agent
174
+ */
175
+ spawn(config: IAgentConfig): Promise<IAgent>;
176
+
177
+ /**
178
+ * Spawn multiple agents in parallel
179
+ */
180
+ spawnBatch(configs: IAgentConfig[]): Promise<Map<string, IAgent>>;
181
+
182
+ /**
183
+ * Terminate an agent
184
+ */
185
+ terminate(agentId: string, reason?: string): Promise<void>;
186
+
187
+ /**
188
+ * Terminate all agents
189
+ */
190
+ terminateAll(reason?: string): Promise<void>;
191
+
192
+ /**
193
+ * Restart an agent
194
+ */
195
+ restart(agentId: string): Promise<IAgent>;
196
+
197
+ /**
198
+ * Update agent configuration
199
+ */
200
+ updateConfig(agentId: string, config: Partial<IAgentConfig>): Promise<void>;
201
+
202
+ /**
203
+ * Get agent by ID
204
+ */
205
+ getAgent(agentId: string): IAgent | undefined;
206
+
207
+ /**
208
+ * Get all agents
209
+ */
210
+ getAllAgents(): IAgent[];
211
+
212
+ /**
213
+ * Get active agents count
214
+ */
215
+ getActiveCount(): number;
216
+
217
+ /**
218
+ * Check agent health
219
+ */
220
+ checkHealth(agentId: string): Promise<IAgent['health']>;
221
+ }
222
+
223
+ /**
224
+ * Agent registry for type definitions
225
+ */
226
+ export interface IAgentRegistry {
227
+ /**
228
+ * Register an agent type with default config
229
+ */
230
+ register(type: string, defaultConfig: Partial<IAgentConfig>): void;
231
+
232
+ /**
233
+ * Unregister an agent type
234
+ */
235
+ unregister(type: string): boolean;
236
+
237
+ /**
238
+ * Get default config for a type
239
+ */
240
+ getDefaultConfig(type: string): Partial<IAgentConfig> | undefined;
241
+
242
+ /**
243
+ * Get all registered types
244
+ */
245
+ getRegisteredTypes(): string[];
246
+
247
+ /**
248
+ * Check if a type is registered
249
+ */
250
+ isRegistered(type: string): boolean;
251
+ }