@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,658 @@
1
+ # V3 Hooks System - Integration Guide
2
+
3
+ This guide shows how to integrate the hooks system with V3's event bus, event store, and other core components.
4
+
5
+ ## Architecture Overview
6
+
7
+ ```
8
+ ┌─────────────────────────────────────────────────────────────┐
9
+ │ Application Layer │
10
+ ├─────────────────────────────────────────────────────────────┤
11
+ │ │
12
+ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
13
+ │ │ Tool Manager │───▶│ Hook Executor│───▶│ Event Bus │ │
14
+ │ └──────────────┘ └──────────────┘ └──────────────┘ │
15
+ │ │ │ │ │
16
+ │ │ │ ▼ │
17
+ │ │ │ ┌──────────────┐ │
18
+ │ │ │ │ Event Store │ │
19
+ │ │ │ │ (ADR-007) │ │
20
+ │ │ │ └──────────────┘ │
21
+ │ │ │ │
22
+ │ │ ▼ │
23
+ │ │ ┌──────────────┐ │
24
+ │ └───────────▶│Hook Registry │ │
25
+ │ └──────────────┘ │
26
+ │ │
27
+ └─────────────────────────────────────────────────────────────┘
28
+ ```
29
+
30
+ ## Integration with Event Bus
31
+
32
+ ### Step 1: Initialize Core Components
33
+
34
+ ```typescript
35
+ import { createEventBus } from '@claude-flow/shared/core';
36
+ import { createHookRegistry, createHookExecutor } from '@claude-flow/shared/hooks';
37
+ import { EventStore } from '@claude-flow/shared/events';
38
+
39
+ // Create core components
40
+ const eventBus = createEventBus();
41
+ const hookRegistry = createHookRegistry();
42
+ const hookExecutor = createHookExecutor(hookRegistry, eventBus);
43
+
44
+ // Optional: Event store for audit trail (ADR-007)
45
+ const eventStore = new EventStore({
46
+ databasePath: './data/events.db',
47
+ verbose: true,
48
+ });
49
+
50
+ await eventStore.initialize();
51
+ ```
52
+
53
+ ### Step 2: Subscribe to Hook Coordination Events
54
+
55
+ ```typescript
56
+ // Listen for hook execution start
57
+ eventBus.on('hooks:pre-execute', async (event) => {
58
+ console.log(`🎯 Executing ${event.payload.hookCount} hooks for ${event.payload.event}`);
59
+
60
+ // Store event in event store (ADR-007)
61
+ await eventStore.append({
62
+ id: `evt-${Date.now()}`,
63
+ type: 'hooks:pre-execute',
64
+ aggregateId: 'hook-system',
65
+ aggregateType: 'system',
66
+ version: 1,
67
+ timestamp: Date.now(),
68
+ source: 'hook-executor',
69
+ payload: event.payload,
70
+ });
71
+ });
72
+
73
+ // Listen for hook execution completion
74
+ eventBus.on('hooks:post-execute', async (event) => {
75
+ const { success, totalExecutionTime, hooksExecuted, hooksFailed } = event.payload;
76
+
77
+ console.log(`✅ Hooks completed: ${hooksExecuted} executed, ${hooksFailed} failed (${totalExecutionTime}ms)`);
78
+
79
+ // Store completion event
80
+ await eventStore.append({
81
+ id: `evt-${Date.now()}`,
82
+ type: 'hooks:post-execute',
83
+ aggregateId: 'hook-system',
84
+ aggregateType: 'system',
85
+ version: 1,
86
+ timestamp: Date.now(),
87
+ source: 'hook-executor',
88
+ payload: event.payload,
89
+ });
90
+ });
91
+
92
+ // Listen for hook errors
93
+ eventBus.on('hooks:error', async (event) => {
94
+ console.error(`❌ Hook error:`, event.payload.error);
95
+
96
+ // Store error event
97
+ await eventStore.append({
98
+ id: `evt-${Date.now()}`,
99
+ type: 'hooks:error',
100
+ aggregateId: 'hook-system',
101
+ aggregateType: 'system',
102
+ version: 1,
103
+ timestamp: Date.now(),
104
+ source: 'hook-executor',
105
+ payload: {
106
+ hookId: event.payload.hookId,
107
+ error: event.payload.error.message,
108
+ stack: event.payload.error.stack,
109
+ },
110
+ });
111
+ });
112
+ ```
113
+
114
+ ## Integration with Tool Execution
115
+
116
+ ### Example: File Read with Hooks
117
+
118
+ ```typescript
119
+ import { HookEvent, HookContext } from '@claude-flow/shared/hooks';
120
+ import { readFile } from 'fs/promises';
121
+
122
+ async function readFileWithHooks(filePath: string): Promise<string> {
123
+ // Create pre-read context
124
+ const preContext: HookContext = {
125
+ event: HookEvent.PreRead,
126
+ timestamp: new Date(),
127
+ file: {
128
+ path: filePath,
129
+ operation: 'read',
130
+ },
131
+ };
132
+
133
+ // Execute pre-read hooks
134
+ const preResult = await hookExecutor.execute(HookEvent.PreRead, preContext);
135
+
136
+ if (preResult.aborted) {
137
+ throw new Error('File read aborted by hooks');
138
+ }
139
+
140
+ // Perform actual read
141
+ const startTime = Date.now();
142
+ let content: string;
143
+ let success = true;
144
+ let error: Error | undefined;
145
+
146
+ try {
147
+ content = await readFile(filePath, 'utf-8');
148
+ } catch (err) {
149
+ success = false;
150
+ error = err instanceof Error ? err : new Error(String(err));
151
+ throw error;
152
+ } finally {
153
+ // Execute post-read hooks
154
+ const postContext: HookContext = {
155
+ event: HookEvent.PostRead,
156
+ timestamp: new Date(),
157
+ file: {
158
+ path: filePath,
159
+ operation: 'read',
160
+ size: content?.length || 0,
161
+ },
162
+ metadata: {
163
+ ...preResult.finalContext?.metadata,
164
+ success,
165
+ executionTime: Date.now() - startTime,
166
+ },
167
+ error: error ? {
168
+ error,
169
+ context: 'file-read',
170
+ severity: 'error',
171
+ recoverable: false,
172
+ } : undefined,
173
+ };
174
+
175
+ await hookExecutor.execute(HookEvent.PostRead, postContext);
176
+ }
177
+
178
+ return content;
179
+ }
180
+ ```
181
+
182
+ ### Example: Command Execution with Hooks
183
+
184
+ ```typescript
185
+ import { exec } from 'child_process';
186
+ import { promisify } from 'util';
187
+ import { HookEvent, HookContext } from '@claude-flow/shared/hooks';
188
+
189
+ const execAsync = promisify(exec);
190
+
191
+ async function executeCommandWithHooks(
192
+ command: string,
193
+ options: { cwd?: string; timeout?: number } = {}
194
+ ): Promise<{ stdout: string; stderr: string }> {
195
+ // Pre-command hooks
196
+ const preContext: HookContext = {
197
+ event: HookEvent.PreCommand,
198
+ timestamp: new Date(),
199
+ command: {
200
+ command,
201
+ cwd: options.cwd,
202
+ timeout: options.timeout,
203
+ isDestructive: /rm|del|format|dd/.test(command),
204
+ },
205
+ };
206
+
207
+ const preResult = await hookExecutor.execute(HookEvent.PreCommand, preContext);
208
+
209
+ if (preResult.aborted) {
210
+ throw new Error(`Command execution blocked by security hooks: ${command}`);
211
+ }
212
+
213
+ // Execute command
214
+ const startTime = Date.now();
215
+ let result: { stdout: string; stderr: string };
216
+ let success = true;
217
+ let error: Error | undefined;
218
+
219
+ try {
220
+ result = await execAsync(command, options);
221
+ } catch (err) {
222
+ success = false;
223
+ error = err instanceof Error ? err : new Error(String(err));
224
+ throw error;
225
+ } finally {
226
+ // Post-command hooks
227
+ const postContext: HookContext = {
228
+ event: HookEvent.PostCommand,
229
+ timestamp: new Date(),
230
+ command: {
231
+ command,
232
+ cwd: options.cwd,
233
+ timeout: options.timeout,
234
+ },
235
+ metadata: {
236
+ ...preResult.finalContext?.metadata,
237
+ success,
238
+ executionTime: Date.now() - startTime,
239
+ },
240
+ error: error ? {
241
+ error,
242
+ context: 'command-execution',
243
+ severity: 'error',
244
+ recoverable: false,
245
+ } : undefined,
246
+ };
247
+
248
+ await hookExecutor.execute(HookEvent.PostCommand, postContext);
249
+ }
250
+
251
+ return result;
252
+ }
253
+ ```
254
+
255
+ ## Integration with Agent Lifecycle
256
+
257
+ ```typescript
258
+ import { HookEvent, HookContext } from '@claude-flow/shared/hooks';
259
+
260
+ class AgentManager {
261
+ async spawnAgent(type: string, config: Record<string, unknown>) {
262
+ const agentId = `agent-${Date.now()}`;
263
+
264
+ // Pre-spawn hooks
265
+ const preContext: HookContext = {
266
+ event: HookEvent.PreAgentSpawn,
267
+ timestamp: new Date(),
268
+ agent: {
269
+ id: agentId,
270
+ type,
271
+ config,
272
+ },
273
+ };
274
+
275
+ const preResult = await hookExecutor.execute(HookEvent.PreAgentSpawn, preContext);
276
+
277
+ if (preResult.aborted) {
278
+ throw new Error(`Agent spawn aborted: ${type}`);
279
+ }
280
+
281
+ // Spawn agent
282
+ const agent = await this.createAgent(agentId, type, config);
283
+
284
+ // Post-spawn hooks
285
+ const postContext: HookContext = {
286
+ event: HookEvent.PostAgentSpawn,
287
+ timestamp: new Date(),
288
+ agent: {
289
+ id: agentId,
290
+ type,
291
+ config,
292
+ },
293
+ metadata: {
294
+ ...preResult.finalContext?.metadata,
295
+ success: true,
296
+ },
297
+ };
298
+
299
+ await hookExecutor.execute(HookEvent.PostAgentSpawn, postContext);
300
+
301
+ return agent;
302
+ }
303
+
304
+ async terminateAgent(agentId: string) {
305
+ // Pre-terminate hooks
306
+ const preContext: HookContext = {
307
+ event: HookEvent.PreAgentTerminate,
308
+ timestamp: new Date(),
309
+ agent: { id: agentId, type: 'unknown' },
310
+ };
311
+
312
+ await hookExecutor.execute(HookEvent.PreAgentTerminate, preContext);
313
+
314
+ // Terminate agent
315
+ await this.destroyAgent(agentId);
316
+
317
+ // Post-terminate hooks
318
+ const postContext: HookContext = {
319
+ event: HookEvent.PostAgentTerminate,
320
+ timestamp: new Date(),
321
+ agent: { id: agentId, type: 'unknown' },
322
+ metadata: { success: true },
323
+ };
324
+
325
+ await hookExecutor.execute(HookEvent.PostAgentTerminate, postContext);
326
+ }
327
+
328
+ private async createAgent(id: string, type: string, config: Record<string, unknown>) {
329
+ // Implementation
330
+ return { id, type, config };
331
+ }
332
+
333
+ private async destroyAgent(id: string) {
334
+ // Implementation
335
+ }
336
+ }
337
+ ```
338
+
339
+ ## Integration with Session Management
340
+
341
+ ```typescript
342
+ import { HookEvent, HookContext } from '@claude-flow/shared/hooks';
343
+
344
+ class SessionManager {
345
+ async startSession(userId?: string) {
346
+ const sessionId = `session-${Date.now()}`;
347
+
348
+ const context: HookContext = {
349
+ event: HookEvent.SessionStart,
350
+ timestamp: new Date(),
351
+ session: {
352
+ id: sessionId,
353
+ startTime: new Date(),
354
+ userId,
355
+ },
356
+ };
357
+
358
+ const result = await hookExecutor.execute(HookEvent.SessionStart, context);
359
+
360
+ // Emit system event
361
+ eventBus.emit('session:created', {
362
+ sessionId,
363
+ userId,
364
+ timestamp: Date.now(),
365
+ });
366
+
367
+ return { sessionId, context: result.finalContext };
368
+ }
369
+
370
+ async endSession(sessionId: string) {
371
+ const context: HookContext = {
372
+ event: HookEvent.SessionEnd,
373
+ timestamp: new Date(),
374
+ session: {
375
+ id: sessionId,
376
+ startTime: new Date(), // Would be loaded from state
377
+ endTime: new Date(),
378
+ },
379
+ };
380
+
381
+ await hookExecutor.execute(HookEvent.SessionEnd, context);
382
+
383
+ // Emit system event
384
+ eventBus.emit('session:terminated', {
385
+ sessionId,
386
+ timestamp: Date.now(),
387
+ });
388
+ }
389
+ }
390
+ ```
391
+
392
+ ## Plugin System Integration
393
+
394
+ Hooks can be registered via plugins (ADR-004):
395
+
396
+ ```typescript
397
+ // v3/plugins/security-hooks/index.ts
398
+ import { Plugin } from '@claude-flow/shared';
399
+ import { HookEvent, HookPriority } from '@claude-flow/shared/hooks';
400
+
401
+ export default {
402
+ name: 'security-hooks',
403
+ version: '1.0.0',
404
+
405
+ async initialize({ hookRegistry }) {
406
+ // Register security hooks
407
+ hookRegistry.register(
408
+ HookEvent.PreCommand,
409
+ async (context) => {
410
+ // Security validation
411
+ return { success: true };
412
+ },
413
+ HookPriority.Critical,
414
+ { name: 'Security: Command Validation' }
415
+ );
416
+
417
+ hookRegistry.register(
418
+ HookEvent.PreWrite,
419
+ async (context) => {
420
+ // File write validation
421
+ return { success: true };
422
+ },
423
+ HookPriority.Critical,
424
+ { name: 'Security: File Write Validation' }
425
+ );
426
+ },
427
+
428
+ async shutdown({ hookRegistry }) {
429
+ // Cleanup hooks
430
+ hookRegistry.unregisterAll();
431
+ },
432
+ } as Plugin;
433
+ ```
434
+
435
+ ## MCP Integration
436
+
437
+ Expose hooks via MCP tools:
438
+
439
+ ```typescript
440
+ // v3/@claude-flow/shared/src/mcp/tools/hooks.ts
441
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
442
+
443
+ export const registerHookTool: Tool = {
444
+ name: 'hooks_register',
445
+ description: 'Register a new hook for event interception',
446
+ inputSchema: {
447
+ type: 'object',
448
+ properties: {
449
+ event: {
450
+ type: 'string',
451
+ enum: Object.values(HookEvent),
452
+ description: 'Hook event type',
453
+ },
454
+ priority: {
455
+ type: 'string',
456
+ enum: ['critical', 'high', 'normal', 'low', 'lowest'],
457
+ description: 'Hook priority',
458
+ },
459
+ name: {
460
+ type: 'string',
461
+ description: 'Hook name',
462
+ },
463
+ },
464
+ required: ['event'],
465
+ },
466
+ };
467
+
468
+ export const listHooksTool: Tool = {
469
+ name: 'hooks_list',
470
+ description: 'List all registered hooks',
471
+ inputSchema: {
472
+ type: 'object',
473
+ properties: {
474
+ event: {
475
+ type: 'string',
476
+ enum: Object.values(HookEvent),
477
+ description: 'Filter by event type (optional)',
478
+ },
479
+ },
480
+ },
481
+ };
482
+
483
+ export const getHookStatsTool: Tool = {
484
+ name: 'hooks_stats',
485
+ description: 'Get hook execution statistics',
486
+ inputSchema: {
487
+ type: 'object',
488
+ properties: {},
489
+ },
490
+ };
491
+ ```
492
+
493
+ ## Event Sourcing Integration (ADR-007)
494
+
495
+ Store all hook executions for audit trail:
496
+
497
+ ```typescript
498
+ import { EventStore } from '@claude-flow/shared/events';
499
+
500
+ // Create event store
501
+ const eventStore = new EventStore({
502
+ databasePath: './data/hook-events.db',
503
+ });
504
+
505
+ await eventStore.initialize();
506
+
507
+ // Subscribe to all hook events
508
+ eventBus.on('hooks:pre-execute', async (event) => {
509
+ await eventStore.append({
510
+ id: `evt-${Date.now()}`,
511
+ type: 'hooks:pre-execute',
512
+ aggregateId: 'hook-system',
513
+ aggregateType: 'system',
514
+ version: 1,
515
+ timestamp: Date.now(),
516
+ source: 'hook-executor',
517
+ payload: event.payload,
518
+ });
519
+ });
520
+
521
+ // Query hook history
522
+ const hookEvents = await eventStore.getEventsByType('hooks:pre-execute');
523
+ console.log(`Total hook executions: ${hookEvents.length}`);
524
+
525
+ // Replay hook events
526
+ for await (const event of eventStore.replay()) {
527
+ if (event.type.startsWith('hooks:')) {
528
+ console.log(`Replaying hook event: ${event.type} at ${event.timestamp}`);
529
+ }
530
+ }
531
+ ```
532
+
533
+ ## Complete Example: Tool Manager with Hooks
534
+
535
+ ```typescript
536
+ import {
537
+ createEventBus,
538
+ createHookRegistry,
539
+ createHookExecutor,
540
+ HookEvent,
541
+ HookPriority,
542
+ HookContext,
543
+ } from '@claude-flow/shared';
544
+
545
+ class V3ToolManager {
546
+ private eventBus = createEventBus();
547
+ private hookRegistry = createHookRegistry();
548
+ private hookExecutor = createHookExecutor(this.hookRegistry, this.eventBus);
549
+
550
+ constructor() {
551
+ this.setupHooks();
552
+ }
553
+
554
+ private setupHooks() {
555
+ // Security hooks
556
+ this.hookRegistry.register(
557
+ HookEvent.PreToolUse,
558
+ async (context) => {
559
+ console.log(`Security check: ${context.tool?.name}`);
560
+ return { success: true };
561
+ },
562
+ HookPriority.Critical
563
+ );
564
+
565
+ // Performance tracking
566
+ this.hookRegistry.register(
567
+ HookEvent.PreToolUse,
568
+ async (context) => {
569
+ return {
570
+ success: true,
571
+ data: {
572
+ metadata: {
573
+ ...context.metadata,
574
+ startTime: Date.now(),
575
+ },
576
+ },
577
+ };
578
+ },
579
+ HookPriority.High
580
+ );
581
+
582
+ this.hookRegistry.register(
583
+ HookEvent.PostToolUse,
584
+ async (context) => {
585
+ const startTime = context.metadata?.startTime as number;
586
+ if (startTime) {
587
+ const duration = Date.now() - startTime;
588
+ console.log(`Tool ${context.tool?.name} took ${duration}ms`);
589
+ }
590
+ return { success: true };
591
+ },
592
+ HookPriority.Normal
593
+ );
594
+ }
595
+
596
+ async executeTool(name: string, parameters: Record<string, unknown>) {
597
+ const context: HookContext = {
598
+ event: HookEvent.PreToolUse,
599
+ timestamp: new Date(),
600
+ tool: { name, parameters },
601
+ };
602
+
603
+ // Execute pre-hooks
604
+ const preResult = await this.hookExecutor.execute(HookEvent.PreToolUse, context);
605
+
606
+ if (preResult.aborted) {
607
+ throw new Error(`Tool execution blocked: ${name}`);
608
+ }
609
+
610
+ // Execute tool (simulated)
611
+ const toolResult = await this.performToolExecution(name, parameters);
612
+
613
+ // Execute post-hooks
614
+ await this.hookExecutor.execute(HookEvent.PostToolUse, {
615
+ ...context,
616
+ event: HookEvent.PostToolUse,
617
+ metadata: {
618
+ ...preResult.finalContext?.metadata,
619
+ success: true,
620
+ },
621
+ });
622
+
623
+ return toolResult;
624
+ }
625
+
626
+ private async performToolExecution(name: string, parameters: Record<string, unknown>) {
627
+ // Tool execution implementation
628
+ return { result: 'success' };
629
+ }
630
+
631
+ getStats() {
632
+ return this.hookRegistry.getStats();
633
+ }
634
+ }
635
+
636
+ // Usage
637
+ const toolManager = new V3ToolManager();
638
+ await toolManager.executeTool('Read', { path: 'file.ts' });
639
+ const stats = toolManager.getStats();
640
+ console.log('Hook statistics:', stats);
641
+ ```
642
+
643
+ ## Best Practices
644
+
645
+ 1. **Always use event bus**: Connect hookExecutor to eventBus for coordination
646
+ 2. **Store critical events**: Use EventStore for audit trail (ADR-007)
647
+ 3. **Handle errors gracefully**: Set `continueOnError` based on severity
648
+ 4. **Use appropriate priorities**: Security hooks = Critical, monitoring = Low
649
+ 5. **Clean up resources**: Unregister hooks in plugin shutdown
650
+ 6. **Monitor performance**: Use hook statistics to identify bottlenecks
651
+ 7. **Test hooks thoroughly**: Use the provided test suite as a template
652
+
653
+ ## Next Steps
654
+
655
+ - See `hooks.test.ts` for comprehensive examples
656
+ - See `example-usage.ts` for practical use cases
657
+ - See `README.md` for API documentation
658
+ - Implement hooks in your domain modules (security, memory, swarm)