claude-flow 1.0.0

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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +612 -0
  3. package/bin/claude-flow +0 -0
  4. package/bin/claude-flow-simple +0 -0
  5. package/bin/claude-flow-typecheck +0 -0
  6. package/deno.json +84 -0
  7. package/package.json +45 -0
  8. package/scripts/check-links.ts +274 -0
  9. package/scripts/check-performance-regression.ts +168 -0
  10. package/scripts/claude-sparc.sh +562 -0
  11. package/scripts/coverage-report.ts +692 -0
  12. package/scripts/demo-task-system.ts +224 -0
  13. package/scripts/install.js +72 -0
  14. package/scripts/test-batch-tasks.ts +29 -0
  15. package/scripts/test-coordination-features.ts +238 -0
  16. package/scripts/test-mcp.ts +251 -0
  17. package/scripts/test-runner.ts +571 -0
  18. package/scripts/validate-examples.ts +288 -0
  19. package/src/cli/cli-core.ts +273 -0
  20. package/src/cli/commands/agent.ts +83 -0
  21. package/src/cli/commands/config.ts +442 -0
  22. package/src/cli/commands/help.ts +765 -0
  23. package/src/cli/commands/index.ts +963 -0
  24. package/src/cli/commands/mcp.ts +191 -0
  25. package/src/cli/commands/memory.ts +74 -0
  26. package/src/cli/commands/monitor.ts +403 -0
  27. package/src/cli/commands/session.ts +595 -0
  28. package/src/cli/commands/start.ts +156 -0
  29. package/src/cli/commands/status.ts +345 -0
  30. package/src/cli/commands/task.ts +79 -0
  31. package/src/cli/commands/workflow.ts +763 -0
  32. package/src/cli/completion.ts +553 -0
  33. package/src/cli/formatter.ts +310 -0
  34. package/src/cli/index.ts +211 -0
  35. package/src/cli/main.ts +23 -0
  36. package/src/cli/repl.ts +1050 -0
  37. package/src/cli/simple-cli.js +211 -0
  38. package/src/cli/simple-cli.ts +211 -0
  39. package/src/coordination/README.md +400 -0
  40. package/src/coordination/advanced-scheduler.ts +487 -0
  41. package/src/coordination/circuit-breaker.ts +366 -0
  42. package/src/coordination/conflict-resolution.ts +490 -0
  43. package/src/coordination/dependency-graph.ts +475 -0
  44. package/src/coordination/index.ts +63 -0
  45. package/src/coordination/manager.ts +460 -0
  46. package/src/coordination/messaging.ts +290 -0
  47. package/src/coordination/metrics.ts +585 -0
  48. package/src/coordination/resources.ts +322 -0
  49. package/src/coordination/scheduler.ts +390 -0
  50. package/src/coordination/work-stealing.ts +224 -0
  51. package/src/core/config.ts +627 -0
  52. package/src/core/event-bus.ts +186 -0
  53. package/src/core/json-persistence.ts +183 -0
  54. package/src/core/logger.ts +262 -0
  55. package/src/core/orchestrator-fixed.ts +312 -0
  56. package/src/core/orchestrator.ts +1234 -0
  57. package/src/core/persistence.ts +276 -0
  58. package/src/mcp/auth.ts +438 -0
  59. package/src/mcp/claude-flow-tools.ts +1280 -0
  60. package/src/mcp/load-balancer.ts +510 -0
  61. package/src/mcp/router.ts +240 -0
  62. package/src/mcp/server.ts +548 -0
  63. package/src/mcp/session-manager.ts +418 -0
  64. package/src/mcp/tools.ts +180 -0
  65. package/src/mcp/transports/base.ts +21 -0
  66. package/src/mcp/transports/http.ts +457 -0
  67. package/src/mcp/transports/stdio.ts +254 -0
  68. package/src/memory/backends/base.ts +22 -0
  69. package/src/memory/backends/markdown.ts +283 -0
  70. package/src/memory/backends/sqlite.ts +329 -0
  71. package/src/memory/cache.ts +238 -0
  72. package/src/memory/indexer.ts +238 -0
  73. package/src/memory/manager.ts +572 -0
  74. package/src/terminal/adapters/base.ts +29 -0
  75. package/src/terminal/adapters/native.ts +504 -0
  76. package/src/terminal/adapters/vscode.ts +340 -0
  77. package/src/terminal/manager.ts +308 -0
  78. package/src/terminal/pool.ts +271 -0
  79. package/src/terminal/session.ts +250 -0
  80. package/src/terminal/vscode-bridge.ts +242 -0
  81. package/src/utils/errors.ts +231 -0
  82. package/src/utils/helpers.ts +476 -0
  83. package/src/utils/types.ts +493 -0
@@ -0,0 +1,585 @@
1
+ /**
2
+ * Metrics and monitoring for coordination performance
3
+ */
4
+
5
+ import { ILogger } from '../core/logger.ts';
6
+ import { IEventBus } from '../core/event-bus.ts';
7
+ import { SystemEvents } from '../utils/types.ts';
8
+
9
+ export interface CoordinationMetrics {
10
+ timestamp: Date;
11
+
12
+ // Task metrics
13
+ taskMetrics: {
14
+ totalTasks: number;
15
+ activeTasks: number;
16
+ completedTasks: number;
17
+ failedTasks: number;
18
+ cancelledTasks: number;
19
+ avgTaskDuration: number;
20
+ taskThroughput: number; // tasks/minute
21
+ tasksByPriority: Record<string, number>;
22
+ tasksByType: Record<string, number>;
23
+ };
24
+
25
+ // Agent metrics
26
+ agentMetrics: {
27
+ totalAgents: number;
28
+ activeAgents: number;
29
+ idleAgents: number;
30
+ busyAgents: number;
31
+ agentUtilization: number; // percentage
32
+ avgTasksPerAgent: number;
33
+ agentsByType: Record<string, number>;
34
+ };
35
+
36
+ // Resource metrics
37
+ resourceMetrics: {
38
+ totalResources: number;
39
+ lockedResources: number;
40
+ freeResources: number;
41
+ resourceUtilization: number; // percentage
42
+ avgLockDuration: number;
43
+ lockContention: number; // waiting requests
44
+ deadlockCount: number;
45
+ };
46
+
47
+ // Coordination metrics
48
+ coordinationMetrics: {
49
+ messagesSent: number;
50
+ messagesReceived: number;
51
+ messageLatency: number; // avg ms
52
+ conflictsDetected: number;
53
+ conflictsResolved: number;
54
+ workStealingEvents: number;
55
+ circuitBreakerTrips: number;
56
+ };
57
+
58
+ // Performance metrics
59
+ performanceMetrics: {
60
+ coordinationLatency: number; // avg ms
61
+ schedulingLatency: number; // avg ms
62
+ memoryUsage: number; // MB
63
+ cpuUsage: number; // percentage
64
+ errorRate: number; // errors/minute
65
+ };
66
+ }
67
+
68
+ export interface MetricsSample {
69
+ timestamp: Date;
70
+ metric: string;
71
+ value: number;
72
+ tags?: Record<string, string>;
73
+ }
74
+
75
+ /**
76
+ * Metrics collector for coordination system
77
+ */
78
+ export class CoordinationMetricsCollector {
79
+ private samples: MetricsSample[] = [];
80
+ private taskStartTimes = new Map<string, Date>();
81
+ private messageStartTimes = new Map<string, Date>();
82
+ private lockStartTimes = new Map<string, Date>();
83
+ private collectionInterval?: number;
84
+
85
+ // Counters
86
+ private counters = {
87
+ totalTasks: 0,
88
+ completedTasks: 0,
89
+ failedTasks: 0,
90
+ cancelledTasks: 0,
91
+ messagesSent: 0,
92
+ messagesReceived: 0,
93
+ conflictsDetected: 0,
94
+ conflictsResolved: 0,
95
+ workStealingEvents: 0,
96
+ circuitBreakerTrips: 0,
97
+ deadlockCount: 0,
98
+ errors: 0,
99
+ };
100
+
101
+ // Gauges
102
+ private gauges = {
103
+ activeTasks: 0,
104
+ activeAgents: 0,
105
+ idleAgents: 0,
106
+ busyAgents: 0,
107
+ lockedResources: 0,
108
+ freeResources: 0,
109
+ lockContention: 0,
110
+ };
111
+
112
+ // Histograms (for calculating averages)
113
+ private histograms = {
114
+ taskDurations: [] as number[],
115
+ messageDurations: [] as number[],
116
+ lockDurations: [] as number[],
117
+ coordinationLatencies: [] as number[],
118
+ schedulingLatencies: [] as number[],
119
+ };
120
+
121
+ constructor(
122
+ private logger: ILogger,
123
+ private eventBus: IEventBus,
124
+ private collectionIntervalMs = 30000, // 30 seconds
125
+ ) {
126
+ this.setupEventHandlers();
127
+ }
128
+
129
+ /**
130
+ * Start metrics collection
131
+ */
132
+ start(): void {
133
+ this.logger.info('Starting coordination metrics collection');
134
+
135
+ this.collectionInterval = setInterval(() => {
136
+ this.collectMetrics();
137
+ }, this.collectionIntervalMs);
138
+ }
139
+
140
+ /**
141
+ * Stop metrics collection
142
+ */
143
+ stop(): void {
144
+ if (this.collectionInterval) {
145
+ clearInterval(this.collectionInterval);
146
+ delete this.collectionInterval;
147
+ }
148
+
149
+ this.logger.info('Stopped coordination metrics collection');
150
+ }
151
+
152
+ /**
153
+ * Record a metric sample
154
+ */
155
+ recordMetric(metric: string, value: number, tags?: Record<string, string>): void {
156
+ const sample: MetricsSample = {
157
+ timestamp: new Date(),
158
+ metric,
159
+ value,
160
+ };
161
+
162
+ if (tags !== undefined) {
163
+ sample.tags = tags;
164
+ }
165
+
166
+ this.samples.push(sample);
167
+
168
+ // Keep only last 10000 samples to prevent memory bloat
169
+ if (this.samples.length > 10000) {
170
+ this.samples = this.samples.slice(-5000);
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Get current metrics snapshot
176
+ */
177
+ getCurrentMetrics(): CoordinationMetrics {
178
+ const now = new Date();
179
+ const minuteAgo = new Date(now.getTime() - 60000);
180
+
181
+ // Calculate throughput (items per minute)
182
+ const recentSamples = this.samples.filter(s => s.timestamp >= minuteAgo);
183
+ const taskCompletions = recentSamples.filter(s => s.metric === 'task.completed').length;
184
+ const errorCount = recentSamples.filter(s => s.metric === 'error').length;
185
+
186
+ return {
187
+ timestamp: now,
188
+
189
+ taskMetrics: {
190
+ totalTasks: this.counters.totalTasks,
191
+ activeTasks: this.gauges.activeTasks,
192
+ completedTasks: this.counters.completedTasks,
193
+ failedTasks: this.counters.failedTasks,
194
+ cancelledTasks: this.counters.cancelledTasks,
195
+ avgTaskDuration: this.average(this.histograms.taskDurations),
196
+ taskThroughput: taskCompletions,
197
+ tasksByPriority: this.getTasksByPriority(),
198
+ tasksByType: this.getTasksByType(),
199
+ },
200
+
201
+ agentMetrics: {
202
+ totalAgents: this.gauges.activeAgents + this.gauges.idleAgents,
203
+ activeAgents: this.gauges.activeAgents,
204
+ idleAgents: this.gauges.idleAgents,
205
+ busyAgents: this.gauges.busyAgents,
206
+ agentUtilization: this.calculateAgentUtilization(),
207
+ avgTasksPerAgent: this.calculateAvgTasksPerAgent(),
208
+ agentsByType: this.getAgentsByType(),
209
+ },
210
+
211
+ resourceMetrics: {
212
+ totalResources: this.gauges.lockedResources + this.gauges.freeResources,
213
+ lockedResources: this.gauges.lockedResources,
214
+ freeResources: this.gauges.freeResources,
215
+ resourceUtilization: this.calculateResourceUtilization(),
216
+ avgLockDuration: this.average(this.histograms.lockDurations),
217
+ lockContention: this.gauges.lockContention,
218
+ deadlockCount: this.counters.deadlockCount,
219
+ },
220
+
221
+ coordinationMetrics: {
222
+ messagesSent: this.counters.messagesSent,
223
+ messagesReceived: this.counters.messagesReceived,
224
+ messageLatency: this.average(this.histograms.messageDurations),
225
+ conflictsDetected: this.counters.conflictsDetected,
226
+ conflictsResolved: this.counters.conflictsResolved,
227
+ workStealingEvents: this.counters.workStealingEvents,
228
+ circuitBreakerTrips: this.counters.circuitBreakerTrips,
229
+ },
230
+
231
+ performanceMetrics: {
232
+ coordinationLatency: this.average(this.histograms.coordinationLatencies),
233
+ schedulingLatency: this.average(this.histograms.schedulingLatencies),
234
+ memoryUsage: this.getMemoryUsage(),
235
+ cpuUsage: this.getCpuUsage(),
236
+ errorRate: errorCount,
237
+ },
238
+ };
239
+ }
240
+
241
+ /**
242
+ * Get metric history for a specific metric
243
+ */
244
+ getMetricHistory(metric: string, since?: Date): MetricsSample[] {
245
+ const cutoff = since || new Date(Date.now() - 3600000); // 1 hour ago
246
+
247
+ return this.samples.filter(s =>
248
+ s.metric === metric && s.timestamp >= cutoff
249
+ );
250
+ }
251
+
252
+ /**
253
+ * Get top metrics by value
254
+ */
255
+ getTopMetrics(limit = 10): Array<{ metric: string; value: number; timestamp: Date }> {
256
+ const recent = this.samples.filter(s =>
257
+ s.timestamp >= new Date(Date.now() - 300000) // 5 minutes
258
+ );
259
+
260
+ const byMetric = new Map<string, number>();
261
+ const timestamps = new Map<string, Date>();
262
+
263
+ for (const sample of recent) {
264
+ byMetric.set(sample.metric, (byMetric.get(sample.metric) || 0) + sample.value);
265
+ timestamps.set(sample.metric, sample.timestamp);
266
+ }
267
+
268
+ return Array.from(byMetric.entries())
269
+ .sort((a, b) => b[1] - a[1])
270
+ .slice(0, limit)
271
+ .map(([metric, value]) => ({
272
+ metric,
273
+ value,
274
+ timestamp: timestamps.get(metric)!,
275
+ }));
276
+ }
277
+
278
+ /**
279
+ * Set up event handlers to collect metrics
280
+ */
281
+ private setupEventHandlers(): void {
282
+ // Task events
283
+ this.eventBus.on(SystemEvents.TASK_CREATED, () => {
284
+ this.counters.totalTasks++;
285
+ this.recordMetric('task.created', 1);
286
+ });
287
+
288
+ this.eventBus.on(SystemEvents.TASK_STARTED, (data: any) => {
289
+ this.taskStartTimes.set(data.taskId, new Date());
290
+ this.gauges.activeTasks++;
291
+ this.recordMetric('task.started', 1);
292
+ });
293
+
294
+ this.eventBus.on(SystemEvents.TASK_COMPLETED, (data: any) => {
295
+ this.counters.completedTasks++;
296
+ this.gauges.activeTasks = Math.max(0, this.gauges.activeTasks - 1);
297
+
298
+ const startTime = this.taskStartTimes.get(data.taskId);
299
+ if (startTime) {
300
+ const duration = new Date().getTime() - startTime.getTime();
301
+ this.histograms.taskDurations.push(duration);
302
+ this.taskStartTimes.delete(data.taskId);
303
+ }
304
+
305
+ this.recordMetric('task.completed', 1);
306
+ });
307
+
308
+ this.eventBus.on(SystemEvents.TASK_FAILED, (data: any) => {
309
+ this.counters.failedTasks++;
310
+ this.gauges.activeTasks = Math.max(0, this.gauges.activeTasks - 1);
311
+ this.taskStartTimes.delete(data.taskId);
312
+ this.recordMetric('task.failed', 1);
313
+ });
314
+
315
+ this.eventBus.on(SystemEvents.TASK_CANCELLED, (data: any) => {
316
+ this.counters.cancelledTasks++;
317
+ this.gauges.activeTasks = Math.max(0, this.gauges.activeTasks - 1);
318
+ this.taskStartTimes.delete(data.taskId);
319
+ this.recordMetric('task.cancelled', 1);
320
+ });
321
+
322
+ // Agent events
323
+ this.eventBus.on(SystemEvents.AGENT_SPAWNED, () => {
324
+ this.gauges.activeAgents++;
325
+ this.recordMetric('agent.spawned', 1);
326
+ });
327
+
328
+ this.eventBus.on(SystemEvents.AGENT_TERMINATED, () => {
329
+ this.gauges.activeAgents = Math.max(0, this.gauges.activeAgents - 1);
330
+ this.recordMetric('agent.terminated', 1);
331
+ });
332
+
333
+ this.eventBus.on(SystemEvents.AGENT_IDLE, () => {
334
+ this.gauges.idleAgents++;
335
+ this.gauges.busyAgents = Math.max(0, this.gauges.busyAgents - 1);
336
+ this.recordMetric('agent.idle', 1);
337
+ });
338
+
339
+ this.eventBus.on(SystemEvents.AGENT_ACTIVE, () => {
340
+ this.gauges.busyAgents++;
341
+ this.gauges.idleAgents = Math.max(0, this.gauges.idleAgents - 1);
342
+ this.recordMetric('agent.active', 1);
343
+ });
344
+
345
+ // Resource events
346
+ this.eventBus.on(SystemEvents.RESOURCE_ACQUIRED, (data: any) => {
347
+ this.lockStartTimes.set(data.resourceId, new Date());
348
+ this.gauges.lockedResources++;
349
+ this.gauges.freeResources = Math.max(0, this.gauges.freeResources - 1);
350
+ this.recordMetric('resource.acquired', 1);
351
+ });
352
+
353
+ this.eventBus.on(SystemEvents.RESOURCE_RELEASED, (data: any) => {
354
+ this.gauges.freeResources++;
355
+ this.gauges.lockedResources = Math.max(0, this.gauges.lockedResources - 1);
356
+
357
+ const startTime = this.lockStartTimes.get(data.resourceId);
358
+ if (startTime) {
359
+ const duration = new Date().getTime() - startTime.getTime();
360
+ this.histograms.lockDurations.push(duration);
361
+ this.lockStartTimes.delete(data.resourceId);
362
+ }
363
+
364
+ this.recordMetric('resource.released', 1);
365
+ });
366
+
367
+ // Deadlock events
368
+ this.eventBus.on(SystemEvents.DEADLOCK_DETECTED, () => {
369
+ this.counters.deadlockCount++;
370
+ this.recordMetric('deadlock.detected', 1);
371
+ });
372
+
373
+ // Message events
374
+ this.eventBus.on(SystemEvents.MESSAGE_SENT, (data: any) => {
375
+ this.counters.messagesSent++;
376
+ this.messageStartTimes.set(data.message.id, new Date());
377
+ this.recordMetric('message.sent', 1);
378
+ });
379
+
380
+ this.eventBus.on(SystemEvents.MESSAGE_RECEIVED, (data: any) => {
381
+ this.counters.messagesReceived++;
382
+
383
+ const startTime = this.messageStartTimes.get(data.message.id);
384
+ if (startTime) {
385
+ const duration = new Date().getTime() - startTime.getTime();
386
+ this.histograms.messageDurations.push(duration);
387
+ this.messageStartTimes.delete(data.message.id);
388
+ }
389
+
390
+ this.recordMetric('message.received', 1);
391
+ });
392
+
393
+ // Conflict events
394
+ this.eventBus.on('conflict:resource', () => {
395
+ this.counters.conflictsDetected++;
396
+ this.recordMetric('conflict.detected', 1);
397
+ });
398
+
399
+ this.eventBus.on('conflict:resolved', () => {
400
+ this.counters.conflictsResolved++;
401
+ this.recordMetric('conflict.resolved', 1);
402
+ });
403
+
404
+ // Work stealing events
405
+ this.eventBus.on('workstealing:request', () => {
406
+ this.counters.workStealingEvents++;
407
+ this.recordMetric('workstealing.event', 1);
408
+ });
409
+
410
+ // Circuit breaker events
411
+ this.eventBus.on('circuitbreaker:state-change', (data: any) => {
412
+ if (data.to === 'open') {
413
+ this.counters.circuitBreakerTrips++;
414
+ this.recordMetric('circuitbreaker.trip', 1);
415
+ }
416
+ });
417
+
418
+ // Error events
419
+ this.eventBus.on(SystemEvents.SYSTEM_ERROR, () => {
420
+ this.counters.errors++;
421
+ this.recordMetric('error', 1);
422
+ });
423
+ }
424
+
425
+ /**
426
+ * Collect comprehensive metrics
427
+ */
428
+ private collectMetrics(): void {
429
+ const metrics = this.getCurrentMetrics();
430
+
431
+ // Emit metrics event
432
+ this.eventBus.emit('metrics:coordination', metrics);
433
+
434
+ // Log summary
435
+ this.logger.debug('Coordination metrics collected', {
436
+ activeTasks: metrics.taskMetrics.activeTasks,
437
+ activeAgents: metrics.agentMetrics.activeAgents,
438
+ lockedResources: metrics.resourceMetrics.lockedResources,
439
+ taskThroughput: metrics.taskMetrics.taskThroughput,
440
+ });
441
+ }
442
+
443
+ /**
444
+ * Calculate average from array of numbers
445
+ */
446
+ private average(values: number[]): number {
447
+ if (values.length === 0) return 0;
448
+ return values.reduce((sum, val) => sum + val, 0) / values.length;
449
+ }
450
+
451
+ /**
452
+ * Get tasks grouped by priority
453
+ */
454
+ private getTasksByPriority(): Record<string, number> {
455
+ const priorities = ['low', 'medium', 'high', 'critical'];
456
+ const result: Record<string, number> = {};
457
+
458
+ for (const priority of priorities) {
459
+ result[priority] = this.samples.filter(s =>
460
+ s.metric === 'task.created' && s.tags?.priority === priority
461
+ ).length;
462
+ }
463
+
464
+ return result;
465
+ }
466
+
467
+ /**
468
+ * Get tasks grouped by type
469
+ */
470
+ private getTasksByType(): Record<string, number> {
471
+ const types = new Set<string>();
472
+
473
+ for (const sample of this.samples) {
474
+ if (sample.metric === 'task.created' && sample.tags?.type) {
475
+ types.add(sample.tags.type);
476
+ }
477
+ }
478
+
479
+ const result: Record<string, number> = {};
480
+ for (const type of types) {
481
+ result[type] = this.samples.filter(s =>
482
+ s.metric === 'task.created' && s.tags?.type === type
483
+ ).length;
484
+ }
485
+
486
+ return result;
487
+ }
488
+
489
+ /**
490
+ * Get agents grouped by type
491
+ */
492
+ private getAgentsByType(): Record<string, number> {
493
+ const types = new Set<string>();
494
+
495
+ for (const sample of this.samples) {
496
+ if (sample.metric === 'agent.spawned' && sample.tags?.type) {
497
+ types.add(sample.tags.type);
498
+ }
499
+ }
500
+
501
+ const result: Record<string, number> = {};
502
+ for (const type of types) {
503
+ result[type] = this.samples.filter(s =>
504
+ s.metric === 'agent.spawned' && s.tags?.type === type
505
+ ).length;
506
+ }
507
+
508
+ return result;
509
+ }
510
+
511
+ /**
512
+ * Calculate agent utilization percentage
513
+ */
514
+ private calculateAgentUtilization(): number {
515
+ const totalAgents = this.gauges.activeAgents + this.gauges.idleAgents;
516
+ if (totalAgents === 0) return 0;
517
+ return (this.gauges.busyAgents / totalAgents) * 100;
518
+ }
519
+
520
+ /**
521
+ * Calculate average tasks per agent
522
+ */
523
+ private calculateAvgTasksPerAgent(): number {
524
+ const totalAgents = this.gauges.activeAgents + this.gauges.idleAgents;
525
+ if (totalAgents === 0) return 0;
526
+ return this.gauges.activeTasks / totalAgents;
527
+ }
528
+
529
+ /**
530
+ * Calculate resource utilization percentage
531
+ */
532
+ private calculateResourceUtilization(): number {
533
+ const totalResources = this.gauges.lockedResources + this.gauges.freeResources;
534
+ if (totalResources === 0) return 0;
535
+ return (this.gauges.lockedResources / totalResources) * 100;
536
+ }
537
+
538
+ /**
539
+ * Get current memory usage in MB
540
+ */
541
+ private getMemoryUsage(): number {
542
+ if (typeof process !== 'undefined' && process.memoryUsage) {
543
+ return process.memoryUsage().heapUsed / 1024 / 1024;
544
+ }
545
+ return 0;
546
+ }
547
+
548
+ /**
549
+ * Get current CPU usage percentage
550
+ */
551
+ private getCpuUsage(): number {
552
+ if (typeof process !== 'undefined' && process.cpuUsage) {
553
+ const usage = process.cpuUsage();
554
+ return (usage.user + usage.system) / 1000000; // Convert to seconds
555
+ }
556
+ return 0;
557
+ }
558
+
559
+ /**
560
+ * Clear all metrics data
561
+ */
562
+ clearMetrics(): void {
563
+ this.samples = [];
564
+ this.taskStartTimes.clear();
565
+ this.messageStartTimes.clear();
566
+ this.lockStartTimes.clear();
567
+
568
+ // Reset counters
569
+ for (const key in this.counters) {
570
+ (this.counters as any)[key] = 0;
571
+ }
572
+
573
+ // Reset gauges
574
+ for (const key in this.gauges) {
575
+ (this.gauges as any)[key] = 0;
576
+ }
577
+
578
+ // Clear histograms
579
+ for (const key in this.histograms) {
580
+ (this.histograms as any)[key] = [];
581
+ }
582
+
583
+ this.logger.info('Coordination metrics cleared');
584
+ }
585
+ }