@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.
- package/README.md +323 -0
- package/__tests__/hooks/bash-safety.test.ts +289 -0
- package/__tests__/hooks/file-organization.test.ts +335 -0
- package/__tests__/hooks/git-commit.test.ts +336 -0
- package/__tests__/hooks/index.ts +23 -0
- package/__tests__/hooks/session-hooks.test.ts +357 -0
- package/__tests__/hooks/task-hooks.test.ts +193 -0
- package/docs/EVENTS_IMPLEMENTATION_SUMMARY.md +388 -0
- package/docs/EVENTS_QUICK_REFERENCE.md +470 -0
- package/docs/EVENTS_README.md +352 -0
- package/package.json +39 -0
- package/src/core/config/defaults.ts +207 -0
- package/src/core/config/index.ts +15 -0
- package/src/core/config/loader.ts +271 -0
- package/src/core/config/schema.ts +188 -0
- package/src/core/config/validator.ts +209 -0
- package/src/core/event-bus.ts +236 -0
- package/src/core/index.ts +22 -0
- package/src/core/interfaces/agent.interface.ts +251 -0
- package/src/core/interfaces/coordinator.interface.ts +363 -0
- package/src/core/interfaces/event.interface.ts +267 -0
- package/src/core/interfaces/index.ts +19 -0
- package/src/core/interfaces/memory.interface.ts +332 -0
- package/src/core/interfaces/task.interface.ts +223 -0
- package/src/core/orchestrator/event-coordinator.ts +122 -0
- package/src/core/orchestrator/health-monitor.ts +214 -0
- package/src/core/orchestrator/index.ts +89 -0
- package/src/core/orchestrator/lifecycle-manager.ts +263 -0
- package/src/core/orchestrator/session-manager.ts +279 -0
- package/src/core/orchestrator/task-manager.ts +317 -0
- package/src/events/domain-events.ts +584 -0
- package/src/events/event-store.test.ts +387 -0
- package/src/events/event-store.ts +588 -0
- package/src/events/example-usage.ts +293 -0
- package/src/events/index.ts +90 -0
- package/src/events/projections.ts +561 -0
- package/src/events/state-reconstructor.ts +349 -0
- package/src/events.ts +367 -0
- package/src/hooks/INTEGRATION.md +658 -0
- package/src/hooks/README.md +532 -0
- package/src/hooks/example-usage.ts +499 -0
- package/src/hooks/executor.ts +379 -0
- package/src/hooks/hooks.test.ts +421 -0
- package/src/hooks/index.ts +131 -0
- package/src/hooks/registry.ts +333 -0
- package/src/hooks/safety/bash-safety.ts +604 -0
- package/src/hooks/safety/file-organization.ts +473 -0
- package/src/hooks/safety/git-commit.ts +623 -0
- package/src/hooks/safety/index.ts +46 -0
- package/src/hooks/session-hooks.ts +559 -0
- package/src/hooks/task-hooks.ts +513 -0
- package/src/hooks/types.ts +357 -0
- package/src/hooks/verify-exports.test.ts +125 -0
- package/src/index.ts +195 -0
- package/src/mcp/connection-pool.ts +438 -0
- package/src/mcp/index.ts +183 -0
- package/src/mcp/server.ts +774 -0
- package/src/mcp/session-manager.ts +428 -0
- package/src/mcp/tool-registry.ts +566 -0
- package/src/mcp/transport/http.ts +557 -0
- package/src/mcp/transport/index.ts +294 -0
- package/src/mcp/transport/stdio.ts +324 -0
- package/src/mcp/transport/websocket.ts +484 -0
- package/src/mcp/types.ts +565 -0
- package/src/plugin-interface.ts +663 -0
- package/src/plugin-loader.ts +638 -0
- package/src/plugin-registry.ts +604 -0
- package/src/plugins/index.ts +34 -0
- package/src/plugins/official/hive-mind-plugin.ts +330 -0
- package/src/plugins/official/index.ts +24 -0
- package/src/plugins/official/maestro-plugin.ts +508 -0
- package/src/plugins/types.ts +108 -0
- package/src/resilience/bulkhead.ts +277 -0
- package/src/resilience/circuit-breaker.ts +326 -0
- package/src/resilience/index.ts +26 -0
- package/src/resilience/rate-limiter.ts +420 -0
- package/src/resilience/retry.ts +224 -0
- package/src/security/index.ts +39 -0
- package/src/security/input-validation.ts +265 -0
- package/src/security/secure-random.ts +159 -0
- package/src/services/index.ts +16 -0
- package/src/services/v3-progress.service.ts +505 -0
- package/src/types/agent.types.ts +144 -0
- package/src/types/index.ts +22 -0
- package/src/types/mcp.types.ts +300 -0
- package/src/types/memory.types.ts +263 -0
- package/src/types/swarm.types.ts +255 -0
- package/src/types/task.types.ts +205 -0
- package/src/types.ts +367 -0
- package/src/utils/secure-logger.d.ts +69 -0
- package/src/utils/secure-logger.d.ts.map +1 -0
- package/src/utils/secure-logger.js +208 -0
- package/src/utils/secure-logger.js.map +1 -0
- package/src/utils/secure-logger.ts +257 -0
- package/tmp.json +0 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V3 Hooks System - Hook Registry
|
|
3
|
+
*
|
|
4
|
+
* Central registry for managing hook definitions and lifecycle.
|
|
5
|
+
* Provides registration, unregistration, and discovery of hooks.
|
|
6
|
+
*
|
|
7
|
+
* @module v3/shared/hooks/registry
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
HookEvent,
|
|
12
|
+
HookPriority,
|
|
13
|
+
HookHandler,
|
|
14
|
+
HookDefinition,
|
|
15
|
+
HookStats,
|
|
16
|
+
} from './types.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Hook registry implementation
|
|
20
|
+
*/
|
|
21
|
+
export class HookRegistry {
|
|
22
|
+
private hooks = new Map<HookEvent, HookDefinition[]>();
|
|
23
|
+
private hooksById = new Map<string, HookDefinition>();
|
|
24
|
+
private hookIdCounter = 0;
|
|
25
|
+
|
|
26
|
+
// Statistics tracking
|
|
27
|
+
private stats = {
|
|
28
|
+
executions: 0,
|
|
29
|
+
failures: 0,
|
|
30
|
+
totalExecutionTime: 0,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Register a new hook
|
|
35
|
+
*
|
|
36
|
+
* @param event - Hook event type
|
|
37
|
+
* @param handler - Hook handler function
|
|
38
|
+
* @param priority - Hook priority (default: Normal)
|
|
39
|
+
* @param options - Additional hook options
|
|
40
|
+
* @returns Hook ID for later unregistration
|
|
41
|
+
*/
|
|
42
|
+
register(
|
|
43
|
+
event: HookEvent,
|
|
44
|
+
handler: HookHandler,
|
|
45
|
+
priority: HookPriority = HookPriority.Normal,
|
|
46
|
+
options: {
|
|
47
|
+
name?: string;
|
|
48
|
+
timeout?: number;
|
|
49
|
+
enabled?: boolean;
|
|
50
|
+
metadata?: Record<string, unknown>;
|
|
51
|
+
} = {}
|
|
52
|
+
): string {
|
|
53
|
+
// Generate unique hook ID
|
|
54
|
+
const id = `hook_${++this.hookIdCounter}_${Date.now()}`;
|
|
55
|
+
|
|
56
|
+
// Create hook definition
|
|
57
|
+
const definition: HookDefinition = {
|
|
58
|
+
id,
|
|
59
|
+
event,
|
|
60
|
+
handler,
|
|
61
|
+
priority,
|
|
62
|
+
name: options.name,
|
|
63
|
+
enabled: options.enabled ?? true,
|
|
64
|
+
timeout: options.timeout,
|
|
65
|
+
metadata: options.metadata,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Add to event-specific list
|
|
69
|
+
let eventHooks = this.hooks.get(event);
|
|
70
|
+
if (!eventHooks) {
|
|
71
|
+
eventHooks = [];
|
|
72
|
+
this.hooks.set(event, eventHooks);
|
|
73
|
+
}
|
|
74
|
+
eventHooks.push(definition);
|
|
75
|
+
|
|
76
|
+
// Sort by priority (highest first)
|
|
77
|
+
eventHooks.sort((a, b) => b.priority - a.priority);
|
|
78
|
+
|
|
79
|
+
// Add to ID map
|
|
80
|
+
this.hooksById.set(id, definition);
|
|
81
|
+
|
|
82
|
+
return id;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Unregister a hook by ID
|
|
87
|
+
*
|
|
88
|
+
* @param hookId - Hook ID to unregister
|
|
89
|
+
* @returns Whether hook was found and removed
|
|
90
|
+
*/
|
|
91
|
+
unregister(hookId: string): boolean {
|
|
92
|
+
const definition = this.hooksById.get(hookId);
|
|
93
|
+
if (!definition) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Remove from event-specific list
|
|
98
|
+
const eventHooks = this.hooks.get(definition.event);
|
|
99
|
+
if (eventHooks) {
|
|
100
|
+
const index = eventHooks.findIndex(h => h.id === hookId);
|
|
101
|
+
if (index !== -1) {
|
|
102
|
+
eventHooks.splice(index, 1);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Clean up empty arrays
|
|
106
|
+
if (eventHooks.length === 0) {
|
|
107
|
+
this.hooks.delete(definition.event);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Remove from ID map
|
|
112
|
+
this.hooksById.delete(hookId);
|
|
113
|
+
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Unregister all hooks for an event
|
|
119
|
+
*
|
|
120
|
+
* @param event - Event type to clear hooks for
|
|
121
|
+
* @returns Number of hooks removed
|
|
122
|
+
*/
|
|
123
|
+
unregisterAll(event?: HookEvent): number {
|
|
124
|
+
if (event) {
|
|
125
|
+
const eventHooks = this.hooks.get(event) || [];
|
|
126
|
+
const count = eventHooks.length;
|
|
127
|
+
|
|
128
|
+
// Remove from ID map
|
|
129
|
+
for (const hook of eventHooks) {
|
|
130
|
+
this.hooksById.delete(hook.id);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Clear event hooks
|
|
134
|
+
this.hooks.delete(event);
|
|
135
|
+
|
|
136
|
+
return count;
|
|
137
|
+
} else {
|
|
138
|
+
// Clear all hooks
|
|
139
|
+
const count = this.hooksById.size;
|
|
140
|
+
this.hooks.clear();
|
|
141
|
+
this.hooksById.clear();
|
|
142
|
+
this.hookIdCounter = 0;
|
|
143
|
+
return count;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get all hooks for a specific event (sorted by priority)
|
|
149
|
+
*
|
|
150
|
+
* @param event - Event type
|
|
151
|
+
* @param includeDisabled - Whether to include disabled hooks
|
|
152
|
+
* @returns Array of hook definitions
|
|
153
|
+
*/
|
|
154
|
+
getHandlers(event: HookEvent, includeDisabled = false): HookDefinition[] {
|
|
155
|
+
const eventHooks = this.hooks.get(event) || [];
|
|
156
|
+
|
|
157
|
+
if (includeDisabled) {
|
|
158
|
+
return [...eventHooks];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return eventHooks.filter(h => h.enabled);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Get a hook by ID
|
|
166
|
+
*
|
|
167
|
+
* @param hookId - Hook ID
|
|
168
|
+
* @returns Hook definition or undefined
|
|
169
|
+
*/
|
|
170
|
+
getHook(hookId: string): HookDefinition | undefined {
|
|
171
|
+
return this.hooksById.get(hookId);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Enable a hook
|
|
176
|
+
*
|
|
177
|
+
* @param hookId - Hook ID
|
|
178
|
+
* @returns Whether hook was found and enabled
|
|
179
|
+
*/
|
|
180
|
+
enable(hookId: string): boolean {
|
|
181
|
+
const hook = this.hooksById.get(hookId);
|
|
182
|
+
if (hook) {
|
|
183
|
+
hook.enabled = true;
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Disable a hook
|
|
191
|
+
*
|
|
192
|
+
* @param hookId - Hook ID
|
|
193
|
+
* @returns Whether hook was found and disabled
|
|
194
|
+
*/
|
|
195
|
+
disable(hookId: string): boolean {
|
|
196
|
+
const hook = this.hooksById.get(hookId);
|
|
197
|
+
if (hook) {
|
|
198
|
+
hook.enabled = false;
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* List all registered hooks
|
|
206
|
+
*
|
|
207
|
+
* @param filter - Optional filter options
|
|
208
|
+
* @returns Array of hook definitions
|
|
209
|
+
*/
|
|
210
|
+
listHooks(filter?: {
|
|
211
|
+
event?: HookEvent;
|
|
212
|
+
enabled?: boolean;
|
|
213
|
+
minPriority?: HookPriority;
|
|
214
|
+
}): HookDefinition[] {
|
|
215
|
+
let hooks: HookDefinition[];
|
|
216
|
+
|
|
217
|
+
if (filter?.event) {
|
|
218
|
+
hooks = this.hooks.get(filter.event) || [];
|
|
219
|
+
} else {
|
|
220
|
+
hooks = Array.from(this.hooksById.values());
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// Apply filters
|
|
224
|
+
if (filter?.enabled !== undefined) {
|
|
225
|
+
hooks = hooks.filter(h => h.enabled === filter.enabled);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (filter?.minPriority !== undefined) {
|
|
229
|
+
const minPriority = filter.minPriority;
|
|
230
|
+
hooks = hooks.filter(h => h.priority >= minPriority);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return hooks;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Get all event types with registered hooks
|
|
238
|
+
*
|
|
239
|
+
* @returns Array of event types
|
|
240
|
+
*/
|
|
241
|
+
getEventTypes(): HookEvent[] {
|
|
242
|
+
return Array.from(this.hooks.keys());
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Get count of hooks for an event
|
|
247
|
+
*
|
|
248
|
+
* @param event - Event type (optional)
|
|
249
|
+
* @returns Hook count
|
|
250
|
+
*/
|
|
251
|
+
count(event?: HookEvent): number {
|
|
252
|
+
if (event) {
|
|
253
|
+
return this.hooks.get(event)?.length || 0;
|
|
254
|
+
}
|
|
255
|
+
return this.hooksById.size;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Record hook execution statistics
|
|
260
|
+
*
|
|
261
|
+
* @param success - Whether execution succeeded
|
|
262
|
+
* @param executionTime - Execution time in ms
|
|
263
|
+
*/
|
|
264
|
+
recordExecution(success: boolean, executionTime: number): void {
|
|
265
|
+
this.stats.executions++;
|
|
266
|
+
this.stats.totalExecutionTime += executionTime;
|
|
267
|
+
if (!success) {
|
|
268
|
+
this.stats.failures++;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Get hook statistics
|
|
274
|
+
*
|
|
275
|
+
* @returns Hook statistics
|
|
276
|
+
*/
|
|
277
|
+
getStats(): HookStats {
|
|
278
|
+
const byEvent: Record<HookEvent, number> = {} as any;
|
|
279
|
+
|
|
280
|
+
for (const [event, hooks] of this.hooks) {
|
|
281
|
+
byEvent[event] = hooks.filter(h => h.enabled).length;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return {
|
|
285
|
+
totalHooks: this.hooksById.size,
|
|
286
|
+
byEvent,
|
|
287
|
+
totalExecutions: this.stats.executions,
|
|
288
|
+
totalFailures: this.stats.failures,
|
|
289
|
+
avgExecutionTime: this.stats.executions > 0
|
|
290
|
+
? this.stats.totalExecutionTime / this.stats.executions
|
|
291
|
+
: 0,
|
|
292
|
+
totalExecutionTime: this.stats.totalExecutionTime,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Reset statistics
|
|
298
|
+
*/
|
|
299
|
+
resetStats(): void {
|
|
300
|
+
this.stats = {
|
|
301
|
+
executions: 0,
|
|
302
|
+
failures: 0,
|
|
303
|
+
totalExecutionTime: 0,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Check if a hook exists
|
|
309
|
+
*
|
|
310
|
+
* @param hookId - Hook ID
|
|
311
|
+
* @returns Whether hook exists
|
|
312
|
+
*/
|
|
313
|
+
has(hookId: string): boolean {
|
|
314
|
+
return this.hooksById.has(hookId);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Clear all hooks and reset state
|
|
319
|
+
*/
|
|
320
|
+
clear(): void {
|
|
321
|
+
this.hooks.clear();
|
|
322
|
+
this.hooksById.clear();
|
|
323
|
+
this.hookIdCounter = 0;
|
|
324
|
+
this.resetStats();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Create a new hook registry
|
|
330
|
+
*/
|
|
331
|
+
export function createHookRegistry(): HookRegistry {
|
|
332
|
+
return new HookRegistry();
|
|
333
|
+
}
|