claude-flow 2.0.0-alpha.71 → 2.0.0-alpha.73

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 (79) hide show
  1. package/.claude/agents/MIGRATION_SUMMARY.md +215 -0
  2. package/.claude/agents/README.md +82 -0
  3. package/.claude/agents/analysis/code-review/analyze-code-quality.md +180 -0
  4. package/.claude/agents/architecture/system-design/arch-system-design.md +156 -0
  5. package/.claude/agents/base-template-generator.md +42 -0
  6. package/.claude/agents/consensus/README.md +246 -0
  7. package/.claude/agents/consensus/byzantine-coordinator.md +63 -0
  8. package/.claude/agents/consensus/crdt-synchronizer.md +997 -0
  9. package/.claude/agents/consensus/gossip-coordinator.md +63 -0
  10. package/.claude/agents/consensus/performance-benchmarker.md +851 -0
  11. package/.claude/agents/consensus/quorum-manager.md +823 -0
  12. package/.claude/agents/consensus/raft-manager.md +63 -0
  13. package/.claude/agents/consensus/security-manager.md +622 -0
  14. package/.claude/agents/core/coder.md +211 -0
  15. package/.claude/agents/core/planner.md +116 -0
  16. package/.claude/agents/core/researcher.md +136 -0
  17. package/.claude/agents/core/reviewer.md +272 -0
  18. package/.claude/agents/core/tester.md +266 -0
  19. package/.claude/agents/data/ml/data-ml-model.md +193 -0
  20. package/.claude/agents/development/backend/dev-backend-api.md +142 -0
  21. package/.claude/agents/devops/ci-cd/ops-cicd-github.md +164 -0
  22. package/.claude/agents/documentation/api-docs/docs-api-openapi.md +174 -0
  23. package/.claude/agents/github/code-review-swarm.md +538 -0
  24. package/.claude/agents/github/github-modes.md +173 -0
  25. package/.claude/agents/github/issue-tracker.md +319 -0
  26. package/.claude/agents/github/multi-repo-swarm.md +553 -0
  27. package/.claude/agents/github/pr-manager.md +191 -0
  28. package/.claude/agents/github/project-board-sync.md +509 -0
  29. package/.claude/agents/github/release-manager.md +367 -0
  30. package/.claude/agents/github/release-swarm.md +583 -0
  31. package/.claude/agents/github/repo-architect.md +398 -0
  32. package/.claude/agents/github/swarm-issue.md +573 -0
  33. package/.claude/agents/github/swarm-pr.md +428 -0
  34. package/.claude/agents/github/sync-coordinator.md +452 -0
  35. package/.claude/agents/github/workflow-automation.md +635 -0
  36. package/.claude/agents/hive-mind/collective-intelligence-coordinator.md +82 -0
  37. package/.claude/agents/hive-mind/consensus-builder.md +102 -0
  38. package/.claude/agents/hive-mind/swarm-memory-manager.md +120 -0
  39. package/.claude/agents/optimization/README.md +243 -0
  40. package/.claude/agents/optimization/benchmark-suite.md +658 -0
  41. package/.claude/agents/optimization/load-balancer.md +424 -0
  42. package/.claude/agents/optimization/performance-monitor.md +665 -0
  43. package/.claude/agents/optimization/resource-allocator.md +667 -0
  44. package/.claude/agents/optimization/topology-optimizer.md +801 -0
  45. package/.claude/agents/sparc/architecture.md +472 -0
  46. package/.claude/agents/sparc/pseudocode.md +318 -0
  47. package/.claude/agents/sparc/refinement.md +525 -0
  48. package/.claude/agents/sparc/specification.md +276 -0
  49. package/.claude/agents/specialized/mobile/spec-mobile-react-native.md +226 -0
  50. package/.claude/agents/swarm/README.md +183 -0
  51. package/.claude/agents/swarm/adaptive-coordinator.md +396 -0
  52. package/.claude/agents/swarm/hierarchical-coordinator.md +256 -0
  53. package/.claude/agents/swarm/mesh-coordinator.md +392 -0
  54. package/.claude/agents/templates/automation-smart-agent.md +205 -0
  55. package/.claude/agents/templates/coordinator-swarm-init.md +90 -0
  56. package/.claude/agents/templates/github-pr-manager.md +177 -0
  57. package/.claude/agents/templates/implementer-sparc-coder.md +259 -0
  58. package/.claude/agents/templates/memory-coordinator.md +187 -0
  59. package/.claude/agents/templates/migration-plan.md +746 -0
  60. package/.claude/agents/templates/orchestrator-task.md +139 -0
  61. package/.claude/agents/templates/performance-analyzer.md +199 -0
  62. package/.claude/agents/templates/sparc-coordinator.md +183 -0
  63. package/.claude/agents/testing/unit/tdd-london-swarm.md +244 -0
  64. package/.claude/agents/testing/validation/production-validator.md +395 -0
  65. package/.claude/settings.json +20 -0
  66. package/.claude/settings.local.json +5 -1
  67. package/bin/claude-flow +1 -1
  68. package/package.json +1 -1
  69. package/src/cli/help-text.js +2 -2
  70. package/src/cli/simple-cli.js +1 -1
  71. package/src/cli/simple-commands/init/agent-copier.js +217 -0
  72. package/src/cli/simple-commands/init/index.js +23 -0
  73. package/src/cli/simple-commands/init/templates/CLAUDE.md +293 -14
  74. package/src/cli/simple-commands/init/templates/settings.json +24 -4
  75. package/src/swarm/advanced-orchestrator.ts +1200 -0
  76. package/src/swarm/claude-code-interface.ts +1268 -0
  77. package/src/swarm/hive-mind-integration.ts +1127 -0
  78. package/src/swarm/mcp-integration-wrapper.ts +860 -0
  79. package/src/swarm/result-aggregator.ts +1046 -0
@@ -0,0 +1,1268 @@
1
+ /**
2
+ * Claude Code Coordination Interface
3
+ *
4
+ * This module provides the interface layer for coordinating with Claude Code
5
+ * instances, managing agent spawning through the claude CLI, handling process
6
+ * lifecycle, and enabling seamless communication between the swarm system
7
+ * and individual Claude agents.
8
+ */
9
+
10
+ import { EventEmitter } from 'node:events';
11
+ import { spawn, ChildProcess } from 'node:child_process';
12
+ import { performance } from 'node:perf_hooks';
13
+ import * as path from 'node:path';
14
+ import * as fs from 'node:fs/promises';
15
+ import { Logger } from '../core/logger.js';
16
+ import { generateId } from '../utils/helpers.js';
17
+ import { MemoryManager } from '../memory/manager.js';
18
+ import TaskExecutor, {
19
+ ClaudeExecutionOptions,
20
+ ExecutionResult,
21
+ ExecutionContext
22
+ } from './executor.js';
23
+ import {
24
+ SwarmAgent,
25
+ SwarmTask,
26
+ TaskDefinition,
27
+ AgentState,
28
+ AgentCapabilities,
29
+ TaskResult,
30
+ SwarmExecutionContext,
31
+ } from './types.js';
32
+
33
+ export interface ClaudeCodeConfig {
34
+ claudeExecutablePath: string;
35
+ defaultModel: string;
36
+ maxTokens: number;
37
+ temperature: number;
38
+ timeout: number;
39
+ maxConcurrentAgents: number;
40
+ enableStreaming: boolean;
41
+ enableLogging: boolean;
42
+ workingDirectory: string;
43
+ environmentVariables: Record<string, string>;
44
+ agentPoolSize: number;
45
+ processRecycling: boolean;
46
+ healthCheckInterval: number;
47
+ }
48
+
49
+ export interface ClaudeAgent {
50
+ id: string;
51
+ processId: number;
52
+ process: ChildProcess;
53
+ type: string;
54
+ capabilities: string[];
55
+ status: 'initializing' | 'idle' | 'busy' | 'error' | 'terminated';
56
+ currentTask?: string;
57
+ spawnedAt: Date;
58
+ lastActivity: Date;
59
+ totalTasks: number;
60
+ totalDuration: number;
61
+ metrics: ClaudeAgentMetrics;
62
+ }
63
+
64
+ export interface ClaudeAgentMetrics {
65
+ tasksCompleted: number;
66
+ tasksFailed: number;
67
+ averageResponseTime: number;
68
+ totalTokensUsed: number;
69
+ memoryUsage: number;
70
+ cpuUsage: number;
71
+ errorRate: number;
72
+ successRate: number;
73
+ }
74
+
75
+ export interface ClaudeTaskExecution {
76
+ id: string;
77
+ taskId: string;
78
+ agentId: string;
79
+ startTime: Date;
80
+ endTime?: Date;
81
+ status: 'queued' | 'running' | 'completed' | 'failed' | 'cancelled';
82
+ input: any;
83
+ output?: any;
84
+ error?: string;
85
+ duration?: number;
86
+ tokensUsed?: number;
87
+ retryCount: number;
88
+ maxRetries: number;
89
+ }
90
+
91
+ export interface ClaudeSpawnOptions {
92
+ type: string;
93
+ name?: string;
94
+ capabilities?: string[];
95
+ systemPrompt?: string;
96
+ model?: string;
97
+ maxTokens?: number;
98
+ temperature?: number;
99
+ workingDirectory?: string;
100
+ environment?: Record<string, string>;
101
+ tools?: string[];
102
+ priority?: number;
103
+ }
104
+
105
+ export interface ProcessPool {
106
+ idle: ClaudeAgent[];
107
+ busy: ClaudeAgent[];
108
+ failed: ClaudeAgent[];
109
+ totalSpawned: number;
110
+ totalTerminated: number;
111
+ recyclingEnabled: boolean;
112
+ maxAge: number;
113
+ maxTasks: number;
114
+ }
115
+
116
+ export class ClaudeCodeInterface extends EventEmitter {
117
+ private logger: Logger;
118
+ private config: ClaudeCodeConfig;
119
+ private memoryManager: MemoryManager;
120
+ private processPool: ProcessPool;
121
+ private activeExecutions: Map<string, ClaudeTaskExecution> = new Map();
122
+ private agents: Map<string, ClaudeAgent> = new Map();
123
+ private taskExecutor: TaskExecutor;
124
+ private healthCheckInterval?: NodeJS.Timeout;
125
+ private isInitialized: boolean = false;
126
+
127
+ constructor(
128
+ config: Partial<ClaudeCodeConfig> = {},
129
+ memoryManager: MemoryManager
130
+ ) {
131
+ super();
132
+
133
+ this.logger = new Logger('ClaudeCodeInterface');
134
+ this.config = this.createDefaultConfig(config);
135
+ this.memoryManager = memoryManager;
136
+ this.processPool = this.initializeProcessPool();
137
+
138
+ this.taskExecutor = new TaskExecutor({
139
+ timeoutMs: this.config.timeout,
140
+ enableMetrics: true,
141
+ captureOutput: true,
142
+ streamOutput: this.config.enableStreaming,
143
+ });
144
+
145
+ this.setupEventHandlers();
146
+ }
147
+
148
+ /**
149
+ * Initialize the Claude Code interface
150
+ */
151
+ async initialize(): Promise<void> {
152
+ if (this.isInitialized) {
153
+ this.logger.warn('Claude Code interface already initialized');
154
+ return;
155
+ }
156
+
157
+ this.logger.info('Initializing Claude Code interface...');
158
+
159
+ try {
160
+ // Verify Claude executable exists
161
+ await this.verifyClaudeExecutable();
162
+
163
+ // Initialize task executor
164
+ await this.taskExecutor.initialize();
165
+
166
+ // Pre-warm agent pool if configured
167
+ if (this.config.agentPoolSize > 0) {
168
+ await this.prewarmAgentPool();
169
+ }
170
+
171
+ // Start health checks
172
+ this.startHealthChecks();
173
+
174
+ this.isInitialized = true;
175
+ this.logger.info('Claude Code interface initialized successfully', {
176
+ poolSize: this.processPool.idle.length,
177
+ maxConcurrent: this.config.maxConcurrentAgents,
178
+ });
179
+
180
+ this.emit('initialized');
181
+
182
+ } catch (error) {
183
+ this.logger.error('Failed to initialize Claude Code interface', error);
184
+ throw error;
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Shutdown the interface gracefully
190
+ */
191
+ async shutdown(): Promise<void> {
192
+ if (!this.isInitialized) return;
193
+
194
+ this.logger.info('Shutting down Claude Code interface...');
195
+
196
+ try {
197
+ // Stop health checks
198
+ if (this.healthCheckInterval) {
199
+ clearInterval(this.healthCheckInterval);
200
+ }
201
+
202
+ // Cancel active executions
203
+ const cancellationPromises = Array.from(this.activeExecutions.keys())
204
+ .map(executionId => this.cancelExecution(executionId, 'Interface shutdown'));
205
+
206
+ await Promise.allSettled(cancellationPromises);
207
+
208
+ // Terminate all agents
209
+ await this.terminateAllAgents();
210
+
211
+ // Shutdown task executor
212
+ await this.taskExecutor.shutdown();
213
+
214
+ this.isInitialized = false;
215
+ this.logger.info('Claude Code interface shut down successfully');
216
+ this.emit('shutdown');
217
+
218
+ } catch (error) {
219
+ this.logger.error('Error during Claude Code interface shutdown', error);
220
+ throw error;
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Spawn a new Claude agent with specified configuration
226
+ */
227
+ async spawnAgent(options: ClaudeSpawnOptions): Promise<string> {
228
+ this.logger.info('Spawning Claude agent', {
229
+ type: options.type,
230
+ name: options.name,
231
+ capabilities: options.capabilities,
232
+ });
233
+
234
+ try {
235
+ // Check if we can spawn more agents
236
+ if (this.getTotalActiveAgents() >= this.config.maxConcurrentAgents) {
237
+ throw new Error('Maximum concurrent agents limit reached');
238
+ }
239
+
240
+ // Build Claude command
241
+ const command = this.buildClaudeCommand(options);
242
+
243
+ // Spawn process
244
+ const process = spawn(command.executable, command.args, {
245
+ cwd: options.workingDirectory || this.config.workingDirectory,
246
+ env: {
247
+ ...process.env,
248
+ ...this.config.environmentVariables,
249
+ ...options.environment,
250
+ },
251
+ stdio: ['pipe', 'pipe', 'pipe'],
252
+ detached: false,
253
+ });
254
+
255
+ if (!process.pid) {
256
+ throw new Error('Failed to spawn Claude process');
257
+ }
258
+
259
+ // Create agent record
260
+ const agentId = generateId('claude-agent');
261
+ const agent: ClaudeAgent = {
262
+ id: agentId,
263
+ processId: process.pid,
264
+ process,
265
+ type: options.type,
266
+ capabilities: options.capabilities || [],
267
+ status: 'initializing',
268
+ spawnedAt: new Date(),
269
+ lastActivity: new Date(),
270
+ totalTasks: 0,
271
+ totalDuration: 0,
272
+ metrics: this.initializeAgentMetrics(),
273
+ };
274
+
275
+ this.agents.set(agentId, agent);
276
+ this.processPool.idle.push(agent);
277
+ this.processPool.totalSpawned++;
278
+
279
+ // Setup process event handlers
280
+ this.setupProcessEventHandlers(agent);
281
+
282
+ // Wait for agent to be ready
283
+ await this.waitForAgentReady(agent);
284
+
285
+ agent.status = 'idle';
286
+ agent.lastActivity = new Date();
287
+
288
+ this.logger.info('Claude agent spawned successfully', {
289
+ agentId,
290
+ processId: process.pid,
291
+ type: options.type,
292
+ });
293
+
294
+ this.emit('agent:spawned', {
295
+ agentId,
296
+ type: options.type,
297
+ processId: process.pid,
298
+ });
299
+
300
+ return agentId;
301
+
302
+ } catch (error) {
303
+ this.logger.error('Failed to spawn Claude agent', {
304
+ type: options.type,
305
+ error: error instanceof Error ? error.message : String(error),
306
+ });
307
+ throw error;
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Execute a task using a Claude agent
313
+ */
314
+ async executeTask(
315
+ taskDefinition: TaskDefinition,
316
+ agentId?: string,
317
+ options: Partial<ClaudeExecutionOptions> = {}
318
+ ): Promise<ClaudeTaskExecution> {
319
+ const executionId = generateId('claude-execution');
320
+
321
+ this.logger.info('Executing task with Claude agent', {
322
+ executionId,
323
+ taskId: taskDefinition.id.id,
324
+ agentId,
325
+ });
326
+
327
+ try {
328
+ // Get or select agent
329
+ const agent = agentId ? this.agents.get(agentId) : await this.selectOptimalAgent(taskDefinition);
330
+
331
+ if (!agent) {
332
+ throw new Error(agentId ? `Agent not found: ${agentId}` : 'No suitable agent available');
333
+ }
334
+
335
+ if (agent.status !== 'idle') {
336
+ throw new Error(`Agent ${agent.id} is not available (status: ${agent.status})`);
337
+ }
338
+
339
+ // Create execution record
340
+ const execution: ClaudeTaskExecution = {
341
+ id: executionId,
342
+ taskId: taskDefinition.id.id,
343
+ agentId: agent.id,
344
+ startTime: new Date(),
345
+ status: 'queued',
346
+ input: {
347
+ task: taskDefinition,
348
+ options,
349
+ },
350
+ retryCount: 0,
351
+ maxRetries: options.maxRetries || 3,
352
+ };
353
+
354
+ this.activeExecutions.set(executionId, execution);
355
+
356
+ // Update agent status
357
+ agent.status = 'busy';
358
+ agent.currentTask = executionId;
359
+ agent.lastActivity = new Date();
360
+
361
+ // Move agent from idle to busy pool
362
+ this.moveAgentToBusyPool(agent);
363
+
364
+ // Execute task
365
+ execution.status = 'running';
366
+ const result = await this.executeTaskWithAgent(agent, taskDefinition, options);
367
+
368
+ // Update execution record
369
+ execution.endTime = new Date();
370
+ execution.duration = execution.endTime.getTime() - execution.startTime.getTime();
371
+ execution.output = result.result;
372
+ execution.tokensUsed = result.metadata?.tokensUsed;
373
+
374
+ if (result.success) {
375
+ execution.status = 'completed';
376
+ agent.metrics.tasksCompleted++;
377
+ } else {
378
+ execution.status = 'failed';
379
+ execution.error = result.error;
380
+ agent.metrics.tasksFailed++;
381
+ }
382
+
383
+ // Update agent metrics
384
+ this.updateAgentMetrics(agent, execution);
385
+
386
+ // Return agent to idle pool
387
+ this.returnAgentToIdlePool(agent);
388
+
389
+ this.logger.info('Task execution completed', {
390
+ executionId,
391
+ success: result.success,
392
+ duration: execution.duration,
393
+ tokensUsed: execution.tokensUsed,
394
+ });
395
+
396
+ this.emit('task:completed', {
397
+ executionId,
398
+ taskId: taskDefinition.id.id,
399
+ agentId: agent.id,
400
+ success: result.success,
401
+ duration: execution.duration,
402
+ });
403
+
404
+ return execution;
405
+
406
+ } catch (error) {
407
+ const execution = this.activeExecutions.get(executionId);
408
+ if (execution) {
409
+ execution.status = 'failed';
410
+ execution.error = error instanceof Error ? error.message : String(error);
411
+ execution.endTime = new Date();
412
+ execution.duration = execution.endTime.getTime() - execution.startTime.getTime();
413
+
414
+ // Return agent to pool if it was assigned
415
+ const agent = this.agents.get(execution.agentId);
416
+ if (agent) {
417
+ this.returnAgentToIdlePool(agent);
418
+ }
419
+ }
420
+
421
+ this.logger.error('Task execution failed', {
422
+ executionId,
423
+ error: error instanceof Error ? error.message : String(error),
424
+ });
425
+
426
+ throw error;
427
+ } finally {
428
+ this.activeExecutions.delete(executionId);
429
+ }
430
+ }
431
+
432
+ /**
433
+ * Cancel a running task execution
434
+ */
435
+ async cancelExecution(executionId: string, reason: string): Promise<void> {
436
+ const execution = this.activeExecutions.get(executionId);
437
+ if (!execution) {
438
+ throw new Error(`Execution not found: ${executionId}`);
439
+ }
440
+
441
+ this.logger.info('Cancelling task execution', {
442
+ executionId,
443
+ reason,
444
+ taskId: execution.taskId,
445
+ agentId: execution.agentId,
446
+ });
447
+
448
+ try {
449
+ execution.status = 'cancelled';
450
+ execution.error = reason;
451
+ execution.endTime = new Date();
452
+ execution.duration = execution.endTime.getTime() - execution.startTime.getTime();
453
+
454
+ // Cancel agent task if running
455
+ const agent = this.agents.get(execution.agentId);
456
+ if (agent && agent.currentTask === executionId) {
457
+ await this.cancelAgentTask(agent);
458
+ this.returnAgentToIdlePool(agent);
459
+ }
460
+
461
+ this.emit('task:cancelled', {
462
+ executionId,
463
+ reason,
464
+ taskId: execution.taskId,
465
+ agentId: execution.agentId,
466
+ });
467
+
468
+ } finally {
469
+ this.activeExecutions.delete(executionId);
470
+ }
471
+ }
472
+
473
+ /**
474
+ * Terminate a specific agent
475
+ */
476
+ async terminateAgent(agentId: string, reason: string = 'Manual termination'): Promise<void> {
477
+ const agent = this.agents.get(agentId);
478
+ if (!agent) {
479
+ throw new Error(`Agent not found: ${agentId}`);
480
+ }
481
+
482
+ this.logger.info('Terminating Claude agent', {
483
+ agentId,
484
+ processId: agent.processId,
485
+ reason,
486
+ });
487
+
488
+ try {
489
+ // Cancel current task if any
490
+ if (agent.currentTask) {
491
+ await this.cancelExecution(agent.currentTask, 'Agent termination');
492
+ }
493
+
494
+ // Update status
495
+ agent.status = 'terminated';
496
+
497
+ // Terminate process
498
+ await this.terminateProcess(agent.process);
499
+
500
+ // Remove from pools and agents map
501
+ this.removeAgentFromPools(agent);
502
+ this.agents.delete(agentId);
503
+ this.processPool.totalTerminated++;
504
+
505
+ this.logger.info('Claude agent terminated successfully', {
506
+ agentId,
507
+ reason,
508
+ totalTasks: agent.totalTasks,
509
+ totalDuration: agent.totalDuration,
510
+ });
511
+
512
+ this.emit('agent:terminated', {
513
+ agentId,
514
+ reason,
515
+ metrics: agent.metrics,
516
+ });
517
+
518
+ } catch (error) {
519
+ this.logger.error('Error terminating agent', {
520
+ agentId,
521
+ error: error instanceof Error ? error.message : String(error),
522
+ });
523
+ throw error;
524
+ }
525
+ }
526
+
527
+ /**
528
+ * Get agent status and metrics
529
+ */
530
+ getAgentStatus(agentId: string): ClaudeAgent | null {
531
+ return this.agents.get(agentId) || null;
532
+ }
533
+
534
+ /**
535
+ * Get all active agents
536
+ */
537
+ getAllAgents(): ClaudeAgent[] {
538
+ return Array.from(this.agents.values());
539
+ }
540
+
541
+ /**
542
+ * Get execution status
543
+ */
544
+ getExecutionStatus(executionId: string): ClaudeTaskExecution | null {
545
+ return this.activeExecutions.get(executionId) || null;
546
+ }
547
+
548
+ /**
549
+ * Get comprehensive interface metrics
550
+ */
551
+ getInterfaceMetrics(): {
552
+ agents: {
553
+ total: number;
554
+ idle: number;
555
+ busy: number;
556
+ failed: number;
557
+ terminated: number;
558
+ };
559
+ executions: {
560
+ active: number;
561
+ completed: number;
562
+ failed: number;
563
+ cancelled: number;
564
+ };
565
+ performance: {
566
+ averageResponseTime: number;
567
+ totalTokensUsed: number;
568
+ successRate: number;
569
+ throughput: number;
570
+ };
571
+ pool: {
572
+ totalSpawned: number;
573
+ totalTerminated: number;
574
+ recyclingEnabled: boolean;
575
+ poolUtilization: number;
576
+ };
577
+ } {
578
+ const agents = Array.from(this.agents.values());
579
+ const executions = Array.from(this.activeExecutions.values());
580
+
581
+ const totalCompleted = agents.reduce((sum, a) => sum + a.metrics.tasksCompleted, 0);
582
+ const totalFailed = agents.reduce((sum, a) => sum + a.metrics.tasksFailed, 0);
583
+ const totalTokens = agents.reduce((sum, a) => sum + a.metrics.totalTokensUsed, 0);
584
+ const avgResponseTime = agents.length > 0
585
+ ? agents.reduce((sum, a) => sum + a.metrics.averageResponseTime, 0) / agents.length
586
+ : 0;
587
+
588
+ return {
589
+ agents: {
590
+ total: agents.length,
591
+ idle: this.processPool.idle.length,
592
+ busy: this.processPool.busy.length,
593
+ failed: this.processPool.failed.length,
594
+ terminated: this.processPool.totalTerminated,
595
+ },
596
+ executions: {
597
+ active: executions.filter(e => e.status === 'running').length,
598
+ completed: totalCompleted,
599
+ failed: totalFailed,
600
+ cancelled: executions.filter(e => e.status === 'cancelled').length,
601
+ },
602
+ performance: {
603
+ averageResponseTime: avgResponseTime,
604
+ totalTokensUsed: totalTokens,
605
+ successRate: totalCompleted + totalFailed > 0 ? totalCompleted / (totalCompleted + totalFailed) : 0,
606
+ throughput: this.calculateThroughput(),
607
+ },
608
+ pool: {
609
+ totalSpawned: this.processPool.totalSpawned,
610
+ totalTerminated: this.processPool.totalTerminated,
611
+ recyclingEnabled: this.processPool.recyclingEnabled,
612
+ poolUtilization: this.calculatePoolUtilization(),
613
+ },
614
+ };
615
+ }
616
+
617
+ // Private methods
618
+
619
+ private async verifyClaudeExecutable(): Promise<void> {
620
+ try {
621
+ const { spawn } = await import('node:child_process');
622
+ const process = spawn(this.config.claudeExecutablePath, ['--version'], {
623
+ stdio: ['ignore', 'pipe', 'pipe'],
624
+ });
625
+
626
+ return new Promise((resolve, reject) => {
627
+ let output = '';
628
+
629
+ process.stdout?.on('data', (data) => {
630
+ output += data.toString();
631
+ });
632
+
633
+ process.on('close', (code) => {
634
+ if (code === 0) {
635
+ this.logger.info('Claude executable verified', {
636
+ path: this.config.claudeExecutablePath,
637
+ version: output.trim(),
638
+ });
639
+ resolve();
640
+ } else {
641
+ reject(new Error(`Claude executable verification failed with code ${code}`));
642
+ }
643
+ });
644
+
645
+ process.on('error', reject);
646
+ });
647
+
648
+ } catch (error) {
649
+ throw new Error(`Claude executable not found: ${this.config.claudeExecutablePath}`);
650
+ }
651
+ }
652
+
653
+ private async prewarmAgentPool(): Promise<void> {
654
+ this.logger.info('Pre-warming agent pool', {
655
+ targetSize: this.config.agentPoolSize,
656
+ });
657
+
658
+ const promises: Promise<string>[] = [];
659
+
660
+ for (let i = 0; i < this.config.agentPoolSize; i++) {
661
+ promises.push(this.spawnAgent({
662
+ type: 'general',
663
+ name: `pool-agent-${i}`,
664
+ capabilities: ['general'],
665
+ }));
666
+ }
667
+
668
+ const results = await Promise.allSettled(promises);
669
+ const successful = results.filter(r => r.status === 'fulfilled').length;
670
+ const failed = results.filter(r => r.status === 'rejected').length;
671
+
672
+ this.logger.info('Agent pool pre-warming completed', {
673
+ successful,
674
+ failed,
675
+ targetSize: this.config.agentPoolSize,
676
+ });
677
+ }
678
+
679
+ private buildClaudeCommand(options: ClaudeSpawnOptions): {
680
+ executable: string;
681
+ args: string[];
682
+ } {
683
+ const args: string[] = [];
684
+
685
+ // Add model
686
+ args.push('--model', options.model || this.config.defaultModel);
687
+
688
+ // Add max tokens
689
+ args.push('--max-tokens', String(options.maxTokens || this.config.maxTokens));
690
+
691
+ // Add temperature
692
+ args.push('--temperature', String(options.temperature || this.config.temperature));
693
+
694
+ // Add system prompt if provided
695
+ if (options.systemPrompt) {
696
+ args.push('--system', options.systemPrompt);
697
+ }
698
+
699
+ // Add tools if specified
700
+ if (options.tools && options.tools.length > 0) {
701
+ args.push('--allowedTools', options.tools.join(','));
702
+ }
703
+
704
+ // Enable streaming if configured
705
+ if (this.config.enableStreaming) {
706
+ args.push('--stream');
707
+ }
708
+
709
+ // Skip permissions for swarm execution
710
+ args.push('--dangerously-skip-permissions');
711
+
712
+ return {
713
+ executable: this.config.claudeExecutablePath,
714
+ args,
715
+ };
716
+ }
717
+
718
+ private setupProcessEventHandlers(agent: ClaudeAgent): void {
719
+ const { process } = agent;
720
+
721
+ process.on('exit', (code, signal) => {
722
+ this.logger.info('Claude agent process exited', {
723
+ agentId: agent.id,
724
+ processId: agent.processId,
725
+ code,
726
+ signal,
727
+ });
728
+
729
+ if (agent.status !== 'terminated') {
730
+ agent.status = 'error';
731
+ this.moveAgentToFailedPool(agent);
732
+ }
733
+
734
+ this.emit('agent:exited', {
735
+ agentId: agent.id,
736
+ code,
737
+ signal,
738
+ });
739
+ });
740
+
741
+ process.on('error', (error) => {
742
+ this.logger.error('Claude agent process error', {
743
+ agentId: agent.id,
744
+ processId: agent.processId,
745
+ error: error.message,
746
+ });
747
+
748
+ agent.status = 'error';
749
+ this.moveAgentToFailedPool(agent);
750
+
751
+ this.emit('agent:error', {
752
+ agentId: agent.id,
753
+ error: error.message,
754
+ });
755
+ });
756
+
757
+ // Handle stdout/stderr if needed
758
+ if (this.config.enableLogging) {
759
+ process.stdout?.on('data', (data) => {
760
+ this.logger.debug('Agent stdout', {
761
+ agentId: agent.id,
762
+ data: data.toString().trim(),
763
+ });
764
+ });
765
+
766
+ process.stderr?.on('data', (data) => {
767
+ this.logger.debug('Agent stderr', {
768
+ agentId: agent.id,
769
+ data: data.toString().trim(),
770
+ });
771
+ });
772
+ }
773
+ }
774
+
775
+ private async waitForAgentReady(agent: ClaudeAgent, timeout: number = 30000): Promise<void> {
776
+ return new Promise((resolve, reject) => {
777
+ const startTime = Date.now();
778
+ const checkInterval = 1000; // 1 second
779
+
780
+ const checkReady = () => {
781
+ const elapsed = Date.now() - startTime;
782
+
783
+ if (elapsed > timeout) {
784
+ reject(new Error(`Agent ${agent.id} failed to become ready within ${timeout}ms`));
785
+ return;
786
+ }
787
+
788
+ // Check if process is still running
789
+ if (agent.process.killed || agent.process.exitCode !== null) {
790
+ reject(new Error(`Agent ${agent.id} process terminated during initialization`));
791
+ return;
792
+ }
793
+
794
+ // For now, assume agent is ready after a short delay
795
+ // In a real implementation, you might check for specific output or response
796
+ if (elapsed > 2000) { // 2 seconds
797
+ resolve();
798
+ } else {
799
+ setTimeout(checkReady, checkInterval);
800
+ }
801
+ };
802
+
803
+ checkReady();
804
+ });
805
+ }
806
+
807
+ private async selectOptimalAgent(taskDefinition: TaskDefinition): Promise<ClaudeAgent | null> {
808
+ const availableAgents = this.processPool.idle.filter(agent => agent.status === 'idle');
809
+
810
+ if (availableAgents.length === 0) {
811
+ // Try to spawn a new agent if under limit
812
+ if (this.getTotalActiveAgents() < this.config.maxConcurrentAgents) {
813
+ const agentId = await this.spawnAgent({
814
+ type: 'task-specific',
815
+ capabilities: taskDefinition.requirements.capabilities,
816
+ });
817
+ return this.agents.get(agentId) || null;
818
+ }
819
+ return null;
820
+ }
821
+
822
+ // Select agent based on capabilities and performance
823
+ const scoredAgents = availableAgents.map(agent => ({
824
+ agent,
825
+ score: this.calculateAgentScore(agent, taskDefinition),
826
+ }));
827
+
828
+ scoredAgents.sort((a, b) => b.score - a.score);
829
+ return scoredAgents[0].agent;
830
+ }
831
+
832
+ private calculateAgentScore(agent: ClaudeAgent, taskDefinition: TaskDefinition): number {
833
+ let score = 0;
834
+
835
+ // Capability match
836
+ const requiredCapabilities = taskDefinition.requirements.capabilities;
837
+ const matchingCapabilities = agent.capabilities.filter(cap =>
838
+ requiredCapabilities.includes(cap)
839
+ );
840
+ score += (matchingCapabilities.length / requiredCapabilities.length) * 100;
841
+
842
+ // Performance metrics
843
+ score += agent.metrics.successRate * 50;
844
+ score += Math.max(0, 50 - agent.metrics.averageResponseTime / 1000) * 10; // Prefer faster agents
845
+
846
+ // Load balancing - prefer agents with fewer completed tasks
847
+ const maxTasks = Math.max(...this.processPool.idle.map(a => a.totalTasks), 1);
848
+ score += (1 - agent.totalTasks / maxTasks) * 20;
849
+
850
+ return score;
851
+ }
852
+
853
+ private async executeTaskWithAgent(
854
+ agent: ClaudeAgent,
855
+ taskDefinition: TaskDefinition,
856
+ options: Partial<ClaudeExecutionOptions>
857
+ ): Promise<ExecutionResult> {
858
+ const startTime = performance.now();
859
+
860
+ try {
861
+ // Create execution context for the agent
862
+ const context: ExecutionContext = {
863
+ task: taskDefinition,
864
+ agent: this.convertToAgentState(agent),
865
+ workingDirectory: options.workingDirectory || this.config.workingDirectory,
866
+ tempDirectory: path.join(this.config.workingDirectory, 'temp', agent.id),
867
+ logDirectory: path.join(this.config.workingDirectory, 'logs', agent.id),
868
+ environment: {
869
+ ...this.config.environmentVariables,
870
+ CLAUDE_AGENT_ID: agent.id,
871
+ CLAUDE_TASK_ID: taskDefinition.id.id,
872
+ },
873
+ resources: {
874
+ maxMemory: taskDefinition.requirements.memoryRequired || 512 * 1024 * 1024,
875
+ maxCpuTime: taskDefinition.requirements.maxDuration || 300000,
876
+ maxDiskSpace: 1024 * 1024 * 1024,
877
+ maxNetworkConnections: 10,
878
+ maxFileHandles: 100,
879
+ priority: 1,
880
+ },
881
+ };
882
+
883
+ // Execute using task executor
884
+ const result = await this.taskExecutor.executeClaudeTask(
885
+ taskDefinition,
886
+ context.agent,
887
+ {
888
+ model: options.model || this.config.defaultModel,
889
+ maxTokens: options.maxTokens || this.config.maxTokens,
890
+ temperature: options.temperature || this.config.temperature,
891
+ timeout: options.timeout || this.config.timeout,
892
+ claudePath: this.config.claudeExecutablePath,
893
+ ...options,
894
+ }
895
+ );
896
+
897
+ const duration = performance.now() - startTime;
898
+
899
+ // Update agent activity
900
+ agent.lastActivity = new Date();
901
+ agent.totalTasks++;
902
+ agent.totalDuration += duration;
903
+
904
+ return result;
905
+
906
+ } catch (error) {
907
+ const duration = performance.now() - startTime;
908
+ agent.totalDuration += duration;
909
+
910
+ throw error;
911
+ }
912
+ }
913
+
914
+ private convertToAgentState(agent: ClaudeAgent): AgentState {
915
+ // Convert ClaudeAgent to AgentState for compatibility
916
+ return {
917
+ id: {
918
+ id: agent.id,
919
+ swarmId: 'claude-interface',
920
+ type: agent.type as any,
921
+ instance: 1,
922
+ },
923
+ name: `Claude-${agent.id}`,
924
+ type: agent.type as any,
925
+ status: agent.status as any,
926
+ capabilities: this.createAgentCapabilities(agent.capabilities),
927
+ metrics: {
928
+ tasksCompleted: agent.metrics.tasksCompleted,
929
+ tasksFailed: agent.metrics.tasksFailed,
930
+ averageExecutionTime: agent.metrics.averageResponseTime,
931
+ successRate: agent.metrics.successRate,
932
+ cpuUsage: agent.metrics.cpuUsage,
933
+ memoryUsage: agent.metrics.memoryUsage,
934
+ diskUsage: 0,
935
+ networkUsage: 0,
936
+ codeQuality: 0.8,
937
+ testCoverage: 0.7,
938
+ bugRate: 0.1,
939
+ userSatisfaction: 0.9,
940
+ totalUptime: Date.now() - agent.spawnedAt.getTime(),
941
+ lastActivity: agent.lastActivity,
942
+ responseTime: agent.metrics.averageResponseTime,
943
+ },
944
+ currentTask: agent.currentTask ? {
945
+ id: agent.currentTask,
946
+ swarmId: 'claude-interface',
947
+ sequence: 0,
948
+ priority: 1,
949
+ } : undefined,
950
+ workload: agent.status === 'busy' ? 1 : 0,
951
+ health: agent.status === 'error' ? 0 : 1,
952
+ config: {
953
+ autonomyLevel: 0.8,
954
+ learningEnabled: false,
955
+ adaptationEnabled: false,
956
+ maxTasksPerHour: 60,
957
+ maxConcurrentTasks: 1,
958
+ timeoutThreshold: this.config.timeout,
959
+ reportingInterval: 10000,
960
+ heartbeatInterval: 5000,
961
+ permissions: ['read', 'write', 'execute'],
962
+ trustedAgents: [],
963
+ expertise: {},
964
+ preferences: {},
965
+ },
966
+ environment: {
967
+ runtime: 'claude',
968
+ version: '1.0.0',
969
+ workingDirectory: this.config.workingDirectory,
970
+ tempDirectory: path.join(this.config.workingDirectory, 'temp', agent.id),
971
+ logDirectory: path.join(this.config.workingDirectory, 'logs', agent.id),
972
+ apiEndpoints: {},
973
+ credentials: {},
974
+ availableTools: agent.capabilities,
975
+ toolConfigs: {},
976
+ },
977
+ endpoints: [],
978
+ lastHeartbeat: agent.lastActivity,
979
+ taskHistory: [],
980
+ errorHistory: [],
981
+ parentAgent: undefined,
982
+ childAgents: [],
983
+ collaborators: [],
984
+ };
985
+ }
986
+
987
+ private createAgentCapabilities(capabilities: string[]): AgentCapabilities {
988
+ return {
989
+ codeGeneration: capabilities.includes('coding') || capabilities.includes('codeGeneration'),
990
+ codeReview: capabilities.includes('review') || capabilities.includes('codeReview'),
991
+ testing: capabilities.includes('testing'),
992
+ documentation: capabilities.includes('documentation'),
993
+ research: capabilities.includes('research'),
994
+ analysis: capabilities.includes('analysis'),
995
+ webSearch: capabilities.includes('webSearch'),
996
+ apiIntegration: capabilities.includes('apiIntegration'),
997
+ fileSystem: capabilities.includes('fileSystem'),
998
+ terminalAccess: capabilities.includes('terminal'),
999
+ languages: capabilities.filter(c => ['javascript', 'typescript', 'python', 'java'].includes(c)),
1000
+ frameworks: capabilities.filter(c => ['react', 'node', 'express'].includes(c)),
1001
+ domains: capabilities.filter(c => ['web', 'api', 'database'].includes(c)),
1002
+ tools: capabilities.filter(c => ['bash', 'git', 'npm'].includes(c)),
1003
+ maxConcurrentTasks: 1,
1004
+ maxMemoryUsage: 512 * 1024 * 1024,
1005
+ maxExecutionTime: this.config.timeout,
1006
+ reliability: 0.9,
1007
+ speed: 1.0,
1008
+ quality: 0.8,
1009
+ };
1010
+ }
1011
+
1012
+ private async cancelAgentTask(agent: ClaudeAgent): Promise<void> {
1013
+ if (agent.process && !agent.process.killed) {
1014
+ // Send interrupt signal
1015
+ agent.process.kill('SIGINT');
1016
+
1017
+ // Wait briefly for graceful shutdown
1018
+ await new Promise(resolve => setTimeout(resolve, 1000));
1019
+
1020
+ // Force kill if still running
1021
+ if (!agent.process.killed) {
1022
+ agent.process.kill('SIGKILL');
1023
+ }
1024
+ }
1025
+
1026
+ agent.currentTask = undefined;
1027
+ agent.status = 'idle';
1028
+ agent.lastActivity = new Date();
1029
+ }
1030
+
1031
+ private async terminateProcess(process: ChildProcess): Promise<void> {
1032
+ if (process.killed || process.exitCode !== null) {
1033
+ return;
1034
+ }
1035
+
1036
+ // Send termination signal
1037
+ process.kill('SIGTERM');
1038
+
1039
+ // Wait for graceful shutdown
1040
+ await new Promise(resolve => setTimeout(resolve, 2000));
1041
+
1042
+ // Force kill if still running
1043
+ if (!process.killed && process.exitCode === null) {
1044
+ process.kill('SIGKILL');
1045
+ }
1046
+ }
1047
+
1048
+ private async terminateAllAgents(): Promise<void> {
1049
+ const terminationPromises = Array.from(this.agents.keys())
1050
+ .map(agentId => this.terminateAgent(agentId, 'Interface shutdown'));
1051
+
1052
+ await Promise.allSettled(terminationPromises);
1053
+ }
1054
+
1055
+ private moveAgentToBusyPool(agent: ClaudeAgent): void {
1056
+ const idleIndex = this.processPool.idle.indexOf(agent);
1057
+ if (idleIndex !== -1) {
1058
+ this.processPool.idle.splice(idleIndex, 1);
1059
+ this.processPool.busy.push(agent);
1060
+ }
1061
+ }
1062
+
1063
+ private returnAgentToIdlePool(agent: ClaudeAgent): void {
1064
+ agent.status = 'idle';
1065
+ agent.currentTask = undefined;
1066
+ agent.lastActivity = new Date();
1067
+
1068
+ const busyIndex = this.processPool.busy.indexOf(agent);
1069
+ if (busyIndex !== -1) {
1070
+ this.processPool.busy.splice(busyIndex, 1);
1071
+ this.processPool.idle.push(agent);
1072
+ }
1073
+ }
1074
+
1075
+ private moveAgentToFailedPool(agent: ClaudeAgent): void {
1076
+ // Remove from other pools
1077
+ this.removeAgentFromPools(agent);
1078
+ this.processPool.failed.push(agent);
1079
+ }
1080
+
1081
+ private removeAgentFromPools(agent: ClaudeAgent): void {
1082
+ const idleIndex = this.processPool.idle.indexOf(agent);
1083
+ if (idleIndex !== -1) {
1084
+ this.processPool.idle.splice(idleIndex, 1);
1085
+ }
1086
+
1087
+ const busyIndex = this.processPool.busy.indexOf(agent);
1088
+ if (busyIndex !== -1) {
1089
+ this.processPool.busy.splice(busyIndex, 1);
1090
+ }
1091
+
1092
+ const failedIndex = this.processPool.failed.indexOf(agent);
1093
+ if (failedIndex !== -1) {
1094
+ this.processPool.failed.splice(failedIndex, 1);
1095
+ }
1096
+ }
1097
+
1098
+ private updateAgentMetrics(agent: ClaudeAgent, execution: ClaudeTaskExecution): void {
1099
+ const metrics = agent.metrics;
1100
+
1101
+ // Update averages
1102
+ const totalTasks = metrics.tasksCompleted + metrics.tasksFailed;
1103
+ if (execution.duration) {
1104
+ metrics.averageResponseTime = totalTasks > 0
1105
+ ? ((metrics.averageResponseTime * (totalTasks - 1)) + execution.duration) / totalTasks
1106
+ : execution.duration;
1107
+ }
1108
+
1109
+ // Update success rate
1110
+ metrics.successRate = totalTasks > 0
1111
+ ? metrics.tasksCompleted / totalTasks
1112
+ : 0;
1113
+
1114
+ // Update error rate
1115
+ metrics.errorRate = 1 - metrics.successRate;
1116
+
1117
+ // Update token usage if available
1118
+ if (execution.tokensUsed) {
1119
+ metrics.totalTokensUsed += execution.tokensUsed;
1120
+ }
1121
+ }
1122
+
1123
+ private getTotalActiveAgents(): number {
1124
+ return this.processPool.idle.length + this.processPool.busy.length;
1125
+ }
1126
+
1127
+ private calculateThroughput(): number {
1128
+ const agents = Array.from(this.agents.values());
1129
+ const totalTasks = agents.reduce((sum, a) => sum + a.totalTasks, 0);
1130
+ const totalTime = agents.reduce((sum, a) => sum + a.totalDuration, 0);
1131
+
1132
+ return totalTime > 0 ? (totalTasks / totalTime) * 60000 : 0; // tasks per minute
1133
+ }
1134
+
1135
+ private calculatePoolUtilization(): number {
1136
+ const total = this.getTotalActiveAgents();
1137
+ const busy = this.processPool.busy.length;
1138
+
1139
+ return total > 0 ? busy / total : 0;
1140
+ }
1141
+
1142
+ private startHealthChecks(): void {
1143
+ this.healthCheckInterval = setInterval(() => {
1144
+ this.performHealthCheck();
1145
+ }, this.config.healthCheckInterval);
1146
+ }
1147
+
1148
+ private performHealthCheck(): void {
1149
+ const now = Date.now();
1150
+
1151
+ for (const agent of this.agents.values()) {
1152
+ // Check for stalled agents
1153
+ const inactiveTime = now - agent.lastActivity.getTime();
1154
+
1155
+ if (agent.status === 'busy' && inactiveTime > this.config.timeout * 2) {
1156
+ this.logger.warn('Agent appears stalled', {
1157
+ agentId: agent.id,
1158
+ inactiveTime,
1159
+ currentTask: agent.currentTask,
1160
+ });
1161
+
1162
+ // Try to recover the agent
1163
+ this.recoverStalledAgent(agent);
1164
+ }
1165
+
1166
+ // Check for failed processes
1167
+ if (agent.process.killed || agent.process.exitCode !== null) {
1168
+ if (agent.status !== 'terminated') {
1169
+ this.logger.warn('Agent process died unexpectedly', {
1170
+ agentId: agent.id,
1171
+ exitCode: agent.process.exitCode,
1172
+ });
1173
+
1174
+ agent.status = 'error';
1175
+ this.moveAgentToFailedPool(agent);
1176
+ }
1177
+ }
1178
+ }
1179
+ }
1180
+
1181
+ private async recoverStalledAgent(agent: ClaudeAgent): Promise<void> {
1182
+ try {
1183
+ if (agent.currentTask) {
1184
+ await this.cancelExecution(agent.currentTask, 'Agent recovery');
1185
+ }
1186
+
1187
+ this.returnAgentToIdlePool(agent);
1188
+
1189
+ this.logger.info('Agent recovered from stalled state', {
1190
+ agentId: agent.id,
1191
+ });
1192
+
1193
+ } catch (error) {
1194
+ this.logger.error('Failed to recover stalled agent', {
1195
+ agentId: agent.id,
1196
+ error: error instanceof Error ? error.message : String(error),
1197
+ });
1198
+
1199
+ // Terminate the problematic agent
1200
+ await this.terminateAgent(agent.id, 'Recovery failed');
1201
+ }
1202
+ }
1203
+
1204
+ private initializeProcessPool(): ProcessPool {
1205
+ return {
1206
+ idle: [],
1207
+ busy: [],
1208
+ failed: [],
1209
+ totalSpawned: 0,
1210
+ totalTerminated: 0,
1211
+ recyclingEnabled: this.config.processRecycling,
1212
+ maxAge: 3600000, // 1 hour
1213
+ maxTasks: 100,
1214
+ };
1215
+ }
1216
+
1217
+ private initializeAgentMetrics(): ClaudeAgentMetrics {
1218
+ return {
1219
+ tasksCompleted: 0,
1220
+ tasksFailed: 0,
1221
+ averageResponseTime: 0,
1222
+ totalTokensUsed: 0,
1223
+ memoryUsage: 0,
1224
+ cpuUsage: 0,
1225
+ errorRate: 0,
1226
+ successRate: 0,
1227
+ };
1228
+ }
1229
+
1230
+ private createDefaultConfig(config: Partial<ClaudeCodeConfig>): ClaudeCodeConfig {
1231
+ return {
1232
+ claudeExecutablePath: 'claude',
1233
+ defaultModel: 'claude-3-5-sonnet-20241022',
1234
+ maxTokens: 4096,
1235
+ temperature: 0.7,
1236
+ timeout: 300000, // 5 minutes
1237
+ maxConcurrentAgents: 10,
1238
+ enableStreaming: false,
1239
+ enableLogging: true,
1240
+ workingDirectory: process.cwd(),
1241
+ environmentVariables: {},
1242
+ agentPoolSize: 0,
1243
+ processRecycling: true,
1244
+ healthCheckInterval: 30000, // 30 seconds
1245
+ ...config,
1246
+ };
1247
+ }
1248
+
1249
+ private setupEventHandlers(): void {
1250
+ this.on('agent:spawned', (data) => {
1251
+ this.logger.info('Agent spawned event', data);
1252
+ });
1253
+
1254
+ this.on('agent:terminated', (data) => {
1255
+ this.logger.info('Agent terminated event', data);
1256
+ });
1257
+
1258
+ this.on('task:completed', (data) => {
1259
+ this.logger.info('Task completed event', data);
1260
+ });
1261
+
1262
+ this.on('task:cancelled', (data) => {
1263
+ this.logger.warn('Task cancelled event', data);
1264
+ });
1265
+ }
1266
+ }
1267
+
1268
+ export default ClaudeCodeInterface;