@sparkleideas/ruv-swarm 1.0.18-patch.1

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 (87) hide show
  1. package/README.md +1565 -0
  2. package/bin/ruv-swarm-clean.js +1872 -0
  3. package/bin/ruv-swarm-memory.js +119 -0
  4. package/bin/ruv-swarm-secure-heartbeat.js +1549 -0
  5. package/bin/ruv-swarm-secure.js +1689 -0
  6. package/package.json +221 -0
  7. package/src/agent.ts +342 -0
  8. package/src/benchmark.js +267 -0
  9. package/src/claude-flow-enhanced.js +839 -0
  10. package/src/claude-integration/advanced-commands.js +561 -0
  11. package/src/claude-integration/core.js +112 -0
  12. package/src/claude-integration/docs.js +1548 -0
  13. package/src/claude-integration/env-template.js +39 -0
  14. package/src/claude-integration/index.js +209 -0
  15. package/src/claude-integration/remote.js +408 -0
  16. package/src/cli-diagnostics.js +364 -0
  17. package/src/cognitive-pattern-evolution.js +1317 -0
  18. package/src/daa-cognition.js +977 -0
  19. package/src/daa-service.d.ts +298 -0
  20. package/src/daa-service.js +1116 -0
  21. package/src/diagnostics.js +533 -0
  22. package/src/errors.js +528 -0
  23. package/src/github-coordinator/README.md +193 -0
  24. package/src/github-coordinator/claude-hooks.js +162 -0
  25. package/src/github-coordinator/gh-cli-coordinator.js +260 -0
  26. package/src/hooks/cli.js +82 -0
  27. package/src/hooks/index.js +1900 -0
  28. package/src/index-enhanced.d.ts +371 -0
  29. package/src/index-enhanced.js +734 -0
  30. package/src/index.d.ts +287 -0
  31. package/src/index.js +405 -0
  32. package/src/index.ts +457 -0
  33. package/src/logger.js +182 -0
  34. package/src/logging-config.js +179 -0
  35. package/src/mcp-daa-tools.js +735 -0
  36. package/src/mcp-tools-benchmarks.js +328 -0
  37. package/src/mcp-tools-enhanced.js +2863 -0
  38. package/src/memory-config.js +42 -0
  39. package/src/meta-learning-framework.js +1359 -0
  40. package/src/neural-agent.js +830 -0
  41. package/src/neural-coordination-protocol.js +1363 -0
  42. package/src/neural-models/README.md +118 -0
  43. package/src/neural-models/autoencoder.js +543 -0
  44. package/src/neural-models/base.js +269 -0
  45. package/src/neural-models/cnn.js +497 -0
  46. package/src/neural-models/gnn.js +447 -0
  47. package/src/neural-models/gru.js +536 -0
  48. package/src/neural-models/index.js +273 -0
  49. package/src/neural-models/lstm.js +551 -0
  50. package/src/neural-models/neural-presets-complete.js +1306 -0
  51. package/src/neural-models/presets/graph.js +392 -0
  52. package/src/neural-models/presets/index.js +279 -0
  53. package/src/neural-models/presets/nlp.js +328 -0
  54. package/src/neural-models/presets/timeseries.js +368 -0
  55. package/src/neural-models/presets/vision.js +387 -0
  56. package/src/neural-models/resnet.js +534 -0
  57. package/src/neural-models/transformer.js +515 -0
  58. package/src/neural-models/vae.js +489 -0
  59. package/src/neural-network-manager.js +1938 -0
  60. package/src/neural-network.ts +296 -0
  61. package/src/neural.js +574 -0
  62. package/src/performance-benchmarks.js +898 -0
  63. package/src/performance.js +458 -0
  64. package/src/persistence-pooled.js +695 -0
  65. package/src/persistence.js +480 -0
  66. package/src/schemas.js +864 -0
  67. package/src/security.js +218 -0
  68. package/src/singleton-container.js +183 -0
  69. package/src/sqlite-pool.js +587 -0
  70. package/src/sqlite-worker.js +141 -0
  71. package/src/types.ts +164 -0
  72. package/src/utils.ts +286 -0
  73. package/src/wasm-loader.js +601 -0
  74. package/src/wasm-loader2.js +404 -0
  75. package/src/wasm-memory-optimizer.js +783 -0
  76. package/src/wasm-types.d.ts +63 -0
  77. package/wasm/README.md +347 -0
  78. package/wasm/neuro-divergent.wasm +0 -0
  79. package/wasm/package.json +18 -0
  80. package/wasm/ruv-fann.wasm +0 -0
  81. package/wasm/ruv_swarm_simd.wasm +0 -0
  82. package/wasm/ruv_swarm_wasm.d.ts +391 -0
  83. package/wasm/ruv_swarm_wasm.js +2164 -0
  84. package/wasm/ruv_swarm_wasm_bg.wasm +0 -0
  85. package/wasm/ruv_swarm_wasm_bg.wasm.d.ts +123 -0
  86. package/wasm/wasm-bindings-loader.mjs +435 -0
  87. package/wasm/wasm-updates.md +684 -0
@@ -0,0 +1,1549 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Production-ready @sparkleideas/ruv-swarm MCP server with security and stability
4
+ * Combines security fixes from Issue #107 with crash protection
5
+ */
6
+
7
+ import { spawn } from 'child_process';
8
+ import { setupClaudeIntegration, invokeClaudeWithSwarm } from '../src/claude-integration/index.js';
9
+ import { RuvSwarm } from '../src/index-enhanced.js';
10
+ import { EnhancedMCPTools } from '../src/mcp-tools-enhanced.js';
11
+ import { daaMcpTools } from '../src/mcp-daa-tools.js';
12
+ import mcpToolsEnhanced from '../src/mcp-tools-enhanced.js';
13
+ import { Logger } from '../src/logger.js';
14
+ import { CommandSanitizer, SecurityError } from '../src/security.js';
15
+ import { readFileSync } from 'fs';
16
+ import { fileURLToPath } from 'url';
17
+ import { dirname, join } from 'path';
18
+
19
+ // Get version from package.json
20
+ const __filename = fileURLToPath(import.meta.url);
21
+ const __dirname = dirname(__filename);
22
+
23
+ async function getVersion() {
24
+ try {
25
+ const packagePath = join(__dirname, '..', 'package.json');
26
+ const packageJson = JSON.parse(readFileSync(packagePath, 'utf8'));
27
+ return packageJson.version;
28
+ } catch (error) {
29
+ return 'unknown';
30
+ }
31
+ }
32
+
33
+ // Stability configuration
34
+ const MAX_RESTARTS = 10;
35
+ const RESTART_DELAY = 1000; // 1 second
36
+ const RESTART_RESET_TIME = 300000; // 5 minutes
37
+
38
+ let restartCount = 0;
39
+ let lastRestartTime = 0;
40
+ let isStabilityMode = false;
41
+ let childProcess = null;
42
+
43
+ // Input validation constants and functions
44
+ const VALID_TOPOLOGIES = ['mesh', 'hierarchical', 'ring', 'star'];
45
+ const VALID_AGENT_TYPES = ['researcher', 'coder', 'analyst', 'optimizer', 'coordinator', 'architect', 'tester'];
46
+ const MAX_AGENTS_LIMIT = 100;
47
+ const MIN_AGENTS_LIMIT = 1;
48
+
49
+ class ValidationError extends Error {
50
+ constructor(message, parameter = null) {
51
+ super(message);
52
+ this.name = 'ValidationError';
53
+ this.parameter = parameter;
54
+ }
55
+ }
56
+
57
+ function validateTopology(topology) {
58
+ if (!topology || typeof topology !== 'string') {
59
+ throw new ValidationError('Topology must be a non-empty string', 'topology');
60
+ }
61
+
62
+ if (!VALID_TOPOLOGIES.includes(topology.toLowerCase())) {
63
+ throw new ValidationError(
64
+ `Invalid topology '${topology}'. Valid topologies are: ${VALID_TOPOLOGIES.join(', ')}`,
65
+ 'topology'
66
+ );
67
+ }
68
+
69
+ return topology.toLowerCase();
70
+ }
71
+
72
+ function validateMaxAgents(maxAgents) {
73
+ // Handle string input
74
+ if (typeof maxAgents === 'string') {
75
+ const parsed = parseInt(maxAgents, 10);
76
+ if (isNaN(parsed)) {
77
+ throw new ValidationError(
78
+ `Invalid maxAgents '${maxAgents}'. Must be a number between ${MIN_AGENTS_LIMIT} and ${MAX_AGENTS_LIMIT}`,
79
+ 'maxAgents'
80
+ );
81
+ }
82
+ maxAgents = parsed;
83
+ }
84
+
85
+ if (!Number.isInteger(maxAgents) || maxAgents < MIN_AGENTS_LIMIT || maxAgents > MAX_AGENTS_LIMIT) {
86
+ throw new ValidationError(
87
+ `Invalid maxAgents '${maxAgents}'. Must be an integer between ${MIN_AGENTS_LIMIT} and ${MAX_AGENTS_LIMIT}`,
88
+ 'maxAgents'
89
+ );
90
+ }
91
+
92
+ return maxAgents;
93
+ }
94
+
95
+ function validateAgentType(type) {
96
+ if (!type || typeof type !== 'string') {
97
+ throw new ValidationError('Agent type must be a non-empty string', 'type');
98
+ }
99
+
100
+ if (!VALID_AGENT_TYPES.includes(type.toLowerCase())) {
101
+ throw new ValidationError(
102
+ `Invalid agent type '${type}'. Valid types are: ${VALID_AGENT_TYPES.join(', ')}`,
103
+ 'type'
104
+ );
105
+ }
106
+
107
+ return type.toLowerCase();
108
+ }
109
+
110
+ function validateAgentName(name) {
111
+ if (name !== null && name !== undefined) {
112
+ if (typeof name !== 'string') {
113
+ throw new ValidationError('Agent name must be a string', 'name');
114
+ }
115
+
116
+ if (name.length === 0) {
117
+ throw new ValidationError('Agent name cannot be empty', 'name');
118
+ }
119
+
120
+ if (name.length > 100) {
121
+ throw new ValidationError('Agent name cannot exceed 100 characters', 'name');
122
+ }
123
+
124
+ // Check for invalid characters
125
+ if (!/^[a-zA-Z0-9\s\-_\.]+$/.test(name)) {
126
+ throw new ValidationError(
127
+ 'Agent name can only contain letters, numbers, spaces, hyphens, underscores, and periods',
128
+ 'name'
129
+ );
130
+ }
131
+ }
132
+
133
+ return name;
134
+ }
135
+
136
+ function validateTaskDescription(task) {
137
+ if (!task || typeof task !== 'string') {
138
+ throw new ValidationError('Task description must be a non-empty string', 'task');
139
+ }
140
+
141
+ if (task.trim().length === 0) {
142
+ throw new ValidationError('Task description cannot be empty or only whitespace', 'task');
143
+ }
144
+
145
+ if (task.length > 1000) {
146
+ throw new ValidationError('Task description cannot exceed 1000 characters', 'task');
147
+ }
148
+
149
+ return task.trim();
150
+ }
151
+
152
+ function logValidationError(error, command) {
153
+ console.log(`āŒ Validation Error in '${command}' command:`);
154
+ console.log(` ${error.message}`);
155
+ if (error.parameter) {
156
+ console.log(` Parameter: ${error.parameter}`);
157
+ }
158
+ console.log(`\nšŸ’” For help with valid parameters, run: @sparkleideas/ruv-swarm help`);
159
+ }
160
+
161
+ function stabilityLog(message) {
162
+ const timestamp = new Date().toISOString();
163
+ console.error(`[${timestamp}] [STABILITY] ${message}`);
164
+ }
165
+
166
+ let globalRuvSwarm = null;
167
+ let globalMCPTools = null;
168
+ let globalLogger = null;
169
+
170
+ // Initialize logger based on environment
171
+ async function initializeLogger() {
172
+ if (!globalLogger) {
173
+ globalLogger = new Logger({
174
+ name: 'ruv-swarm-mcp',
175
+ level: process.env.LOG_LEVEL || (process.argv.includes('--debug') ? 'DEBUG' : 'INFO'),
176
+ enableStderr: true, // Always use stderr in MCP mode
177
+ enableFile: process.env.LOG_TO_FILE === 'true',
178
+ formatJson: process.env.LOG_FORMAT === 'json',
179
+ logDir: process.env.LOG_DIR || './logs',
180
+ metadata: {
181
+ pid: process.pid,
182
+ version: await getVersion(),
183
+ mode: 'mcp-stdio'
184
+ }
185
+ });
186
+
187
+ // Set up bulletproof error handlers - LOG but NEVER exit
188
+ process.on('uncaughtException', (error) => {
189
+ globalLogger.error('Uncaught exception - continuing operation', { error });
190
+ if (isStabilityMode) {
191
+ stabilityLog(`Uncaught exception: ${error.message} - continuing...`);
192
+ }
193
+ // DO NOT EXIT - bulletproof operation continues
194
+ });
195
+
196
+ process.on('unhandledRejection', (reason, promise) => {
197
+ globalLogger.error('Unhandled rejection - continuing operation', { reason, promise });
198
+ if (isStabilityMode) {
199
+ stabilityLog(`Unhandled rejection: ${reason} - continuing...`);
200
+ }
201
+ // DO NOT EXIT - bulletproof operation continues
202
+ });
203
+ }
204
+ return globalLogger;
205
+ }
206
+
207
+ async function initializeSystem() {
208
+ if (!globalRuvSwarm) {
209
+ // RuvSwarm.initialize already prints initialization messages
210
+ globalRuvSwarm = await RuvSwarm.initialize({
211
+ loadingStrategy: 'progressive',
212
+ enablePersistence: true,
213
+ enableNeuralNetworks: true,
214
+ enableForecasting: true,
215
+ useSIMD: RuvSwarm.detectSIMDSupport(),
216
+ debug: process.argv.includes('--debug')
217
+ });
218
+ }
219
+
220
+ if (!globalMCPTools) {
221
+ // Pass the already initialized RuvSwarm instance to avoid duplicate initialization
222
+ globalMCPTools = new EnhancedMCPTools(globalRuvSwarm);
223
+ await globalMCPTools.initialize(globalRuvSwarm);
224
+
225
+ // Initialize DAA MCP tools with the same instance
226
+ daaMcpTools.mcpTools = globalMCPTools;
227
+ await daaMcpTools.ensureInitialized();
228
+
229
+ // Add DAA tool methods to the MCP tools object
230
+ const daaToolNames = [
231
+ 'daa_init', 'daa_agent_create', 'daa_agent_adapt', 'daa_workflow_create',
232
+ 'daa_workflow_execute', 'daa_knowledge_share', 'daa_learning_status',
233
+ 'daa_cognitive_pattern', 'daa_meta_learning', 'daa_performance_metrics'
234
+ ];
235
+
236
+ for (const toolName of daaToolNames) {
237
+ if (typeof daaMcpTools[toolName] === 'function') {
238
+ globalMCPTools[toolName] = daaMcpTools[toolName].bind(daaMcpTools);
239
+ }
240
+ }
241
+ }
242
+
243
+ return { ruvSwarm: globalRuvSwarm, mcpTools: globalMCPTools };
244
+ }
245
+
246
+ async function handleInit(args) {
247
+ try {
248
+ const { mcpTools } = await initializeSystem();
249
+
250
+ // Filter out flags to get positional arguments
251
+ const positionalArgs = args.filter(arg => !arg.startsWith('--'));
252
+ const rawTopology = positionalArgs[0] || 'mesh';
253
+ const rawMaxAgents = positionalArgs[1] || '5';
254
+ const setupClaude = args.includes('--claude') || args.includes('--setup-claude');
255
+ const forceSetup = args.includes('--force');
256
+ const mergeSetup = args.includes('--merge');
257
+ const noInteractive = args.includes('--no-interactive');
258
+ const noBackup = args.includes('--no-backup');
259
+
260
+ // Validate inputs
261
+ const topology = validateTopology(rawTopology);
262
+ const maxAgents = validateMaxAgents(rawMaxAgents);
263
+
264
+ console.log('šŸš€ Initializing @sparkleideas/ruv-swarm...');
265
+
266
+ const result = await mcpTools.swarm_init({
267
+ topology,
268
+ maxAgents,
269
+ strategy: 'balanced',
270
+ enableCognitiveDiversity: true,
271
+ enableNeuralAgents: true,
272
+ enableForecasting: args.includes('--forecasting')
273
+ });
274
+
275
+ console.log('šŸ Swarm initialized:');
276
+ console.log(' ID: ' + result.id);
277
+ console.log(' Topology: ' + result.topology);
278
+ console.log(' Max Agents: ' + result.maxAgents);
279
+ console.log(' Features: ' + Object.entries(result.features).filter(([k,v]) => v).map(([k,v]) => k).join(', '));
280
+ console.log(' Performance: ' + result.performance.initialization_time_ms.toFixed(1) + 'ms');
281
+
282
+ // Setup Claude integration using modular approach
283
+ if (setupClaude || forceSetup || mergeSetup) {
284
+ console.log('\nšŸ“š Setting up modular Claude Code integration...');
285
+ try {
286
+ await setupClaudeIntegration({
287
+ autoSetup: setupClaude,
288
+ forceSetup: forceSetup,
289
+ mergeSetup: mergeSetup,
290
+ noBackup: noBackup,
291
+ interactive: !noInteractive,
292
+ workingDir: process.cwd(),
293
+ packageName: '@sparkleideas/ruv-swarm'
294
+ });
295
+ } catch (error) {
296
+ console.log('āš ļø Claude integration setup had issues:', error.message);
297
+ console.log('šŸ’” Manual setup: claude mcp add @sparkleideas/ruv-swarm npx @sparkleideas/ruv-swarm mcp start');
298
+ }
299
+ }
300
+
301
+ console.log('\nāœ… Initialization complete!');
302
+ console.log('\nšŸ”— Next steps:');
303
+ console.log(' 1. Test with MCP tools: mcp__ruv-swarm__agent_spawn');
304
+ console.log(' 2. Use wrapper scripts for remote execution');
305
+ console.log(' 3. Check .claude/commands/ for detailed guides');
306
+
307
+ if (forceSetup) {
308
+ console.log('\nšŸ”„ Files regenerated with --force flag');
309
+ } else if (mergeSetup) {
310
+ console.log('\nšŸ”„ Configuration merged with existing files');
311
+ }
312
+ } catch (error) {
313
+ if (error instanceof ValidationError) {
314
+ logValidationError(error, 'init');
315
+ return;
316
+ }
317
+ throw error;
318
+ }
319
+ }
320
+
321
+ async function handleSpawn(args) {
322
+ try {
323
+ const { mcpTools } = await initializeSystem();
324
+
325
+ const rawType = args[0] || 'researcher';
326
+ const rawName = args[1] || null;
327
+
328
+ // Validate inputs
329
+ const type = validateAgentType(rawType);
330
+ const name = validateAgentName(rawName);
331
+
332
+ const result = await mcpTools.agent_spawn({
333
+ type,
334
+ name,
335
+ enableNeuralNetwork: !args.includes('--no-neural')
336
+ });
337
+
338
+ console.log('šŸ¤– Agent spawned:');
339
+ console.log(' ID: ' + result.agent.id);
340
+ console.log(' Name: ' + result.agent.name);
341
+ console.log(' Type: ' + result.agent.type);
342
+ console.log(' Cognitive Pattern: ' + result.agent.cognitive_pattern);
343
+ if (result.agent.neural_network_id) {
344
+ console.log(' Neural Network: ' + result.agent.neural_network_id);
345
+ }
346
+ console.log(' Swarm Capacity: ' + result.swarm_info.capacity);
347
+ } catch (error) {
348
+ if (error instanceof ValidationError) {
349
+ logValidationError(error, 'spawn');
350
+ return;
351
+ }
352
+ throw error;
353
+ }
354
+ }
355
+
356
+ async function handleOrchestrate(args) {
357
+ try {
358
+ const { mcpTools } = await initializeSystem();
359
+
360
+ const rawTask = args.join(' ');
361
+ if (!rawTask) {
362
+ console.log('āŒ No task provided');
363
+ console.log('Usage: @sparkleideas/ruv-swarm orchestrate "task description"');
364
+ return;
365
+ }
366
+
367
+ // Validate task description
368
+ const task = validateTaskDescription(rawTask);
369
+
370
+ const result = await mcpTools.task_orchestrate({
371
+ task: task,
372
+ strategy: 'adaptive'
373
+ });
374
+
375
+ console.log('šŸ“‹ Task orchestrated:');
376
+ console.log(' ID: ' + result.taskId);
377
+ console.log(' Description: ' + result.description);
378
+ console.log(' Assigned Agents: ' + result.assigned_agents.length);
379
+ console.log(' Status: ' + result.status);
380
+ console.log(' Estimated Completion: ' + result.performance.estimated_completion_ms + 'ms');
381
+ } catch (error) {
382
+ if (error instanceof ValidationError) {
383
+ logValidationError(error, 'orchestrate');
384
+ return;
385
+ }
386
+ throw error;
387
+ }
388
+ }
389
+
390
+ async function handleClaudeInvoke(args) {
391
+ const prompt = args.join(' ');
392
+
393
+ if (!prompt.trim()) {
394
+ console.log('āŒ No prompt provided');
395
+ console.log('Usage: @sparkleideas/ruv-swarm claude-invoke "your swarm prompt"');
396
+ console.log('Note: Use --dangerously-skip-permissions explicitly if needed');
397
+ return;
398
+ }
399
+
400
+ // Security: validate prompt for dangerous patterns
401
+ try {
402
+ CommandSanitizer.validateArgument(prompt.trim());
403
+ } catch (error) {
404
+ if (error instanceof SecurityError) {
405
+ console.error('āŒ Security validation failed:', error.message);
406
+ return;
407
+ }
408
+ throw error;
409
+ }
410
+
411
+ console.log('šŸš€ Invoking Claude Code with @sparkleideas/ruv-swarm integration...');
412
+ console.log('Prompt: ' + prompt.trim());
413
+
414
+ try {
415
+ // Create orchestrator with secure mode
416
+ const { ClaudeIntegrationOrchestrator } = await import('../src/claude-integration/index.js');
417
+ const orchestrator = new ClaudeIntegrationOrchestrator({
418
+ workingDir: process.cwd()
419
+ });
420
+
421
+ // Use secure mode (no automatic permissions)
422
+ await orchestrator.core.invokeClaudeWithPrompt(prompt, { secure: true });
423
+ } catch (error) {
424
+ console.error('āŒ Claude invocation failed:', error.message);
425
+ console.error('Make sure Claude Code CLI is installed and in your PATH');
426
+ process.exit(1);
427
+ }
428
+ }
429
+
430
+ async function handleStatus(args) {
431
+ const { mcpTools } = await initializeSystem();
432
+
433
+ const verbose = args.includes('--verbose') || args.includes('-v');
434
+ const swarmId = args.find(arg => !arg.startsWith('-'));
435
+
436
+ const result = await mcpTools.swarm_status({ verbose });
437
+
438
+ if (swarmId) {
439
+ console.log(`šŸ Swarm Status (${swarmId}):`);
440
+ console.log(` Agents: ${result.agents.total} (${result.agents.active} active, ${result.agents.idle} idle)`);
441
+ console.log(` Tasks: ${result.tasks.total} (${result.tasks.pending} pending, ${result.tasks.in_progress} in progress)`);
442
+ } else {
443
+ console.log('🌐 Global Status:');
444
+ console.log(` Active Swarms: ${result.active_swarms}`);
445
+ console.log(` Total Agents: ${result.global_metrics.totalAgents}`);
446
+ console.log(` Total Tasks: ${result.global_metrics.totalTasks}`);
447
+ console.log(` Memory Usage: ${result.global_metrics.memoryUsage / (1024 * 1024)}MB`);
448
+
449
+ if (verbose) {
450
+ console.log('\nšŸ“Š WASM Modules:');
451
+ Object.entries(result.runtime_info.wasm_modules).forEach(([name, status]) => {
452
+ console.log(` ${name}: ${status.loaded ? 'āœ… Loaded' : 'ā³ Not loaded'} (${(status.size / 1024).toFixed(0)}KB)`);
453
+ });
454
+ }
455
+ }
456
+ }
457
+
458
+ async function handleMonitor(args) {
459
+ const { mcpTools } = await initializeSystem();
460
+
461
+ const duration = parseInt(args.find(arg => arg.match(/^\d+$/))) || 10000;
462
+
463
+ console.log(`šŸ“Š Monitoring for ${duration}ms...`);
464
+ console.log('Press Ctrl+C to stop\n');
465
+
466
+ const interval = setInterval(async () => {
467
+ const status = await mcpTools.swarm_status({ verbose: false });
468
+ process.stdout.write('\r');
469
+ process.stdout.write(`Swarms: ${status.active_swarms} | Agents: ${status.global_metrics.totalAgents} | Tasks: ${status.global_metrics.totalTasks} | Memory: ${(status.global_metrics.memoryUsage / (1024 * 1024)).toFixed(1)}MB`);
470
+ }, 1000);
471
+
472
+ setTimeout(() => {
473
+ clearInterval(interval);
474
+ console.log('\n\nāœ… Monitoring complete');
475
+ }, duration);
476
+ }
477
+
478
+ async function handleMcp(args) {
479
+ const subcommand = args[0] || 'help';
480
+
481
+ switch (subcommand) {
482
+ case 'start':
483
+ await startMcpServer(args.slice(1));
484
+ break;
485
+ case 'status':
486
+ await getMcpStatus();
487
+ break;
488
+ case 'stop':
489
+ await stopMcpServer();
490
+ break;
491
+ case 'tools':
492
+ await listMcpTools();
493
+ break;
494
+ case 'config':
495
+ await configureMcp(args.slice(1));
496
+ break;
497
+ case 'help':
498
+ default:
499
+ showMcpHelp();
500
+ }
501
+ }
502
+
503
+ async function startMcpServer(args) {
504
+ const protocol = args.find(arg => arg.startsWith('--protocol='))?.split('=')[1] || 'stdio';
505
+ const enableStability = args.includes('--stability') || process.env.MCP_STABILITY === 'true';
506
+
507
+ if (enableStability) {
508
+ isStabilityMode = true;
509
+ stabilityLog('Starting MCP server with stability mode enabled');
510
+ return startStableMcpServer(args);
511
+ }
512
+
513
+ // Initialize logger first
514
+ const logger = await initializeLogger();
515
+ const sessionId = logger.setCorrelationId();
516
+
517
+ try {
518
+ if (protocol === 'stdio') {
519
+ // In stdio mode, only JSON-RPC messages should go to stdout
520
+ logger.info('@sparkleideas/ruv-swarm MCP server starting in stdio mode', {
521
+ protocol,
522
+ sessionId,
523
+ nodeVersion: process.version,
524
+ platform: process.platform,
525
+ arch: process.arch
526
+ });
527
+
528
+ // Log connection establishment
529
+ logger.logConnection('established', sessionId, {
530
+ protocol: 'stdio',
531
+ transport: 'stdin/stdout',
532
+ timestamp: new Date().toISOString()
533
+ });
534
+
535
+ // Initialize WASM if needed
536
+ const initOpId = logger.startOperation('initialize-system');
537
+ const { ruvSwarm, mcpTools } = await initializeSystem();
538
+ logger.endOperation(initOpId, true, { modulesLoaded: true });
539
+
540
+ // Start stdio MCP server loop
541
+ process.stdin.setEncoding('utf8');
542
+
543
+ // Signal server readiness for testing
544
+ if (process.env.MCP_TEST_MODE === 'true') {
545
+ console.error('MCP server ready'); // Use stderr so it doesn't interfere with JSON-RPC
546
+ }
547
+
548
+ let buffer = '';
549
+ let messageCount = 0;
550
+
551
+ process.stdin.on('data', (chunk) => {
552
+ logger.trace('Received stdin data', { bytes: chunk.length });
553
+ buffer += chunk;
554
+
555
+ // Process complete JSON messages
556
+ const lines = buffer.split('\n');
557
+ buffer = lines.pop() || '';
558
+
559
+ for (const line of lines) {
560
+ if (line.trim()) {
561
+ messageCount++;
562
+ const messageId = `msg-${sessionId}-${messageCount}`;
563
+
564
+ try {
565
+ const request = JSON.parse(line);
566
+ logger.logMcp('in', request.method || 'unknown', {
567
+ method: request.method,
568
+ id: request.id,
569
+ params: request.params,
570
+ messageId
571
+ });
572
+
573
+ const opId = logger.startOperation(`mcp-${request.method}`, {
574
+ requestId: request.id,
575
+ messageId
576
+ });
577
+
578
+ handleMcpRequest(request, mcpTools, logger).then(response => {
579
+ logger.endOperation(opId, !response.error, {
580
+ hasError: !!response.error
581
+ });
582
+
583
+ logger.logMcp('out', request.method || 'response', {
584
+ method: request.method,
585
+ id: response.id,
586
+ result: response.result,
587
+ error: response.error,
588
+ messageId
589
+ });
590
+
591
+ try {
592
+ process.stdout.write(JSON.stringify(response) + '\n');
593
+ } catch (writeError) {
594
+ logger.error('Failed to write response to stdout', { writeError, response });
595
+ process.exit(1);
596
+ }
597
+ }).catch(error => {
598
+ logger.endOperation(opId, false, { error });
599
+ logger.error('Request handler error', { error, request });
600
+
601
+ const errorResponse = {
602
+ jsonrpc: '2.0',
603
+ error: {
604
+ code: -32603,
605
+ message: 'Internal error',
606
+ data: error.message
607
+ },
608
+ id: request.id
609
+ };
610
+ process.stdout.write(JSON.stringify(errorResponse) + '\n');
611
+ });
612
+ } catch (error) {
613
+ logger.error('JSON parse error', {
614
+ error,
615
+ line: line.substring(0, 100),
616
+ messageId
617
+ });
618
+
619
+ const errorResponse = {
620
+ jsonrpc: '2.0',
621
+ error: {
622
+ code: -32700,
623
+ message: 'Parse error',
624
+ data: error.message
625
+ },
626
+ id: null
627
+ };
628
+ process.stdout.write(JSON.stringify(errorResponse) + '\n');
629
+ }
630
+ }
631
+ }
632
+ });
633
+
634
+ // Set up connection monitoring
635
+ const monitorInterval = setInterval(() => {
636
+ logger.logMemoryUsage('mcp-server');
637
+ logger.debug('Connection metrics', logger.getConnectionMetrics());
638
+ }, 60000); // Every minute
639
+
640
+ // Handle stdin close
641
+ process.stdin.on('end', () => {
642
+ logger.logConnection('closed', sessionId, {
643
+ messagesProcessed: messageCount,
644
+ uptime: process.uptime()
645
+ });
646
+ logger.info('MCP: stdin closed, shutting down...');
647
+ clearInterval(monitorInterval);
648
+ process.exit(0);
649
+ });
650
+
651
+ process.stdin.on('error', (error) => {
652
+ logger.logConnection('failed', sessionId, { error });
653
+ logger.error('MCP: stdin error, but continuing operation...', { error });
654
+ // DO NOT exit - bulletproof operation continues
655
+ });
656
+
657
+ // Handle process termination signals gracefully
658
+ process.on('SIGTERM', () => {
659
+ logger.info('MCP: Received SIGTERM, shutting down gracefully...');
660
+ clearInterval(monitorInterval);
661
+ process.exit(0);
662
+ });
663
+
664
+ process.on('SIGINT', () => {
665
+ logger.info('MCP: Received SIGINT, shutting down gracefully...');
666
+ clearInterval(monitorInterval);
667
+ process.exit(0);
668
+ });
669
+
670
+ // Send initialization message
671
+ const version = await getVersion();
672
+ const initMessage = {
673
+ jsonrpc: '2.0',
674
+ method: 'server.initialized',
675
+ params: {
676
+ serverInfo: {
677
+ name: '@sparkleideas/ruv-swarm',
678
+ version: version,
679
+ capabilities: {
680
+ tools: true,
681
+ prompts: false,
682
+ resources: true
683
+ }
684
+ }
685
+ }
686
+ };
687
+ process.stdout.write(JSON.stringify(initMessage) + '\n');
688
+
689
+ // NO TIMEOUT MECHANISM - Bulletproof infinite runtime
690
+ // Security preserved, but NO heartbeats or timeouts whatsoever
691
+ logger.info('MCP server configured for infinite runtime', {
692
+ timeouts: 'DISABLED',
693
+ heartbeats: 'DISABLED',
694
+ mode: 'bulletproof-infinite'
695
+ });
696
+
697
+ } else {
698
+ logger.error('WebSocket protocol not yet implemented', { protocol });
699
+ console.log('āŒ WebSocket protocol not yet implemented in production version');
700
+ console.log('Use stdio mode for Claude Code integration');
701
+ }
702
+ } catch (error) {
703
+ logger.fatal('Failed to start MCP server', { error, protocol });
704
+ console.error('āŒ Failed to start MCP server:', error.message);
705
+ process.exit(1);
706
+ }
707
+ }
708
+
709
+ async function startStableMcpServer(args) {
710
+ const now = Date.now();
711
+
712
+ // Reset restart count if it's been more than 5 minutes
713
+ if (now - lastRestartTime > RESTART_RESET_TIME) {
714
+ restartCount = 0;
715
+ }
716
+
717
+ if (restartCount >= MAX_RESTARTS) {
718
+ stabilityLog(`Maximum restarts (${MAX_RESTARTS}) reached. Server may have persistent issues.`);
719
+ stabilityLog('Please check logs and restart manually if needed.');
720
+ return;
721
+ }
722
+
723
+ restartCount++;
724
+ lastRestartTime = now;
725
+
726
+ stabilityLog(`Starting MCP server (attempt ${restartCount}/${MAX_RESTARTS})`);
727
+
728
+ // Create new process args without --stability flag
729
+ const processArgs = ['mcp', 'start', ...args.filter(arg => arg !== '--stability')];
730
+
731
+ childProcess = spawn('node', [__filename, ...processArgs], {
732
+ stdio: ['inherit', 'inherit', 'inherit'],
733
+ env: { ...process.env, MCP_STABILITY: 'false' }
734
+ });
735
+
736
+ childProcess.on('exit', (code, signal) => {
737
+ if (code === 0) {
738
+ stabilityLog('MCP server exited normally');
739
+ return;
740
+ }
741
+
742
+ stabilityLog(`MCP server crashed with code ${code} and signal ${signal}`);
743
+ stabilityLog(`Restarting in ${RESTART_DELAY}ms...`);
744
+
745
+ setTimeout(() => {
746
+ startStableMcpServer(args);
747
+ }, RESTART_DELAY);
748
+ });
749
+
750
+ childProcess.on('error', (error) => {
751
+ stabilityLog(`Failed to start MCP server: ${error.message}`);
752
+ stabilityLog(`Restarting in ${RESTART_DELAY}ms...`);
753
+
754
+ setTimeout(() => {
755
+ startStableMcpServer(args);
756
+ }, RESTART_DELAY);
757
+ });
758
+
759
+ // Handle process termination signals
760
+ process.on('SIGTERM', () => {
761
+ stabilityLog('Received SIGTERM, shutting down...');
762
+ if (childProcess) {
763
+ childProcess.kill('SIGTERM');
764
+ }
765
+ process.exit(0);
766
+ });
767
+
768
+ process.on('SIGINT', () => {
769
+ stabilityLog('Received SIGINT, shutting down...');
770
+ if (childProcess) {
771
+ childProcess.kill('SIGINT');
772
+ }
773
+ process.exit(0);
774
+ });
775
+ }
776
+
777
+ async function getMcpStatus() {
778
+ console.log('šŸ” MCP Server Status:');
779
+ console.log(' Protocol: stdio (for Claude Code integration)');
780
+ console.log(' Status: Ready to start');
781
+ console.log(' Usage: npx @sparkleideas/ruv-swarm mcp start [--stability]');
782
+ console.log(' Runtime: Infinite (no timeouts)');
783
+ console.log(' Stability: Auto-restart on crashes (use --stability flag)');
784
+ }
785
+
786
+ async function stopMcpServer() {
787
+ if (childProcess) {
788
+ stabilityLog('Stopping MCP server...');
789
+ childProcess.kill('SIGTERM');
790
+ childProcess = null;
791
+ }
792
+ console.log('āœ… MCP server stopped');
793
+ }
794
+
795
+ async function listMcpTools() {
796
+ console.log('šŸ› ļø Available MCP Tools:');
797
+ console.log('\nšŸ“Š Core Swarm Tools:');
798
+ console.log(' mcp__ruv-swarm__swarm_init - Initialize a new swarm');
799
+ console.log(' mcp__ruv-swarm__agent_spawn - Spawn new agents');
800
+ console.log(' mcp__ruv-swarm__task_orchestrate - Orchestrate tasks');
801
+ console.log(' mcp__ruv-swarm__swarm_status - Get swarm status');
802
+ console.log(' ... and 11 more core tools');
803
+ console.log('\nšŸ¤– DAA (Decentralized Autonomous Agents) Tools:');
804
+ console.log(' mcp__ruv-swarm__daa_init - Initialize DAA service');
805
+ console.log(' mcp__ruv-swarm__daa_agent_create - Create autonomous agents');
806
+ console.log(' mcp__ruv-swarm__daa_workflow_create - Create DAA workflows');
807
+ console.log(' mcp__ruv-swarm__daa_learning_status - Get learning progress');
808
+ console.log(' ... and 6 more DAA tools');
809
+ console.log('\nFor full documentation, run: @sparkleideas/ruv-swarm init --claude');
810
+ }
811
+
812
+ function showMcpHelp() {
813
+ console.log(`
814
+ šŸ”Œ MCP (Model Context Protocol) Commands
815
+
816
+ Usage: @sparkleideas/ruv-swarm mcp <subcommand> [options]
817
+
818
+ Subcommands:
819
+ start [--protocol=stdio] [--stability] Start MCP server
820
+ status Show MCP server status
821
+ stop Stop MCP server
822
+ tools List available MCP tools
823
+ help Show this help message
824
+
825
+ Options:
826
+ --stability Enable auto-restart on crashes
827
+ --protocol=stdio Use stdio protocol (default)
828
+
829
+ Environment Variables:
830
+ LOG_LEVEL Log level (DEBUG, INFO, WARN, ERROR)
831
+ MCP_TEST_MODE Enable test mode (true/false)
832
+
833
+ Examples:
834
+ @sparkleideas/ruv-swarm mcp start # Start stdio MCP server (infinite runtime)
835
+ @sparkleideas/ruv-swarm mcp start --stability # Start with crash protection
836
+ LOG_LEVEL=DEBUG @sparkleideas/ruv-swarm mcp start # Enable debug logging
837
+ @sparkleideas/ruv-swarm mcp tools # List available tools
838
+
839
+ For Claude Code integration:
840
+ claude mcp add @sparkleideas/ruv-swarm npx @sparkleideas/ruv-swarm mcp start --stability
841
+ `);
842
+ }
843
+
844
+ async function configureMcp(args) {
845
+ console.log('šŸ”§ MCP configuration is managed through Claude Code');
846
+ console.log('Run: @sparkleideas/ruv-swarm init --claude');
847
+ }
848
+
849
+ async function getResourceContent(uri) {
850
+ const resources = {
851
+ 'swarm://docs/getting-started': {
852
+ contents: [{
853
+ uri,
854
+ mimeType: 'text/markdown',
855
+ text: `# Getting Started with @sparkleideas/ruv-swarm
856
+
857
+ ## Introduction
858
+ @sparkleideas/ruv-swarm is a powerful WASM-powered neural swarm orchestration system that enhances Claude Code's capabilities through intelligent agent coordination.
859
+
860
+ ## Quick Start
861
+
862
+ 1. **Initialize a swarm:**
863
+ \`\`\`bash
864
+ mcp__ruv-swarm__swarm_init { topology: "mesh", maxAgents: 5 }
865
+ \`\`\`
866
+
867
+ 2. **Spawn agents:**
868
+ \`\`\`bash
869
+ mcp__ruv-swarm__agent_spawn { type: "researcher", name: "Doc Analyzer" }
870
+ mcp__ruv-swarm__agent_spawn { type: "coder", name: "Implementation Expert" }
871
+ \`\`\`
872
+
873
+ 3. **Orchestrate tasks:**
874
+ \`\`\`bash
875
+ mcp__ruv-swarm__task_orchestrate { task: "Build a REST API", strategy: "adaptive" }
876
+ \`\`\`
877
+
878
+ ## Key Concepts
879
+
880
+ - **Agents**: Cognitive patterns that guide Claude Code's approach
881
+ - **Topologies**: Organizational structures for agent coordination
882
+ - **Memory**: Persistent state across sessions
883
+ - **Neural Training**: Continuous improvement through learning
884
+
885
+ ## Best Practices
886
+
887
+ 1. Always batch operations in a single message
888
+ 2. Use memory for cross-agent coordination
889
+ 3. Monitor progress with status tools
890
+ 4. Train neural patterns for better results`
891
+ }]
892
+ },
893
+ 'swarm://docs/stability': {
894
+ contents: [{
895
+ uri,
896
+ mimeType: 'text/markdown',
897
+ text: `# Stability Features
898
+
899
+ ## Auto-Restart Protection
900
+ The production version includes built-in crash protection:
901
+
902
+ - **Maximum restarts**: 10 attempts
903
+ - **Restart delay**: 1 second between attempts
904
+ - **Reset window**: 5 minutes (restart count resets)
905
+ - **Graceful shutdown**: SIGTERM/SIGINT handling
906
+
907
+ ## Usage
908
+ \`\`\`bash
909
+ # Enable stability mode
910
+ @sparkleideas/ruv-swarm mcp start --stability
911
+
912
+ # For Claude Code integration
913
+ claude mcp add @sparkleideas/ruv-swarm npx @sparkleideas/ruv-swarm mcp start --stability
914
+ \`\`\`
915
+
916
+ ## Features
917
+ - Automatic process restart on crashes
918
+ - Proper signal handling
919
+ - Detailed logging of restart attempts
920
+ - Circuit breaker pattern to prevent infinite loops`
921
+ }]
922
+ }
923
+ };
924
+
925
+ const resource = resources[uri];
926
+ if (!resource) {
927
+ throw new Error(`Resource not found: ${uri}`);
928
+ }
929
+
930
+ return resource;
931
+ }
932
+
933
+ async function handleMcpRequest(request, mcpTools, logger = null) {
934
+ const response = {
935
+ jsonrpc: '2.0',
936
+ id: request.id
937
+ };
938
+
939
+ // Use default logger if not provided
940
+ if (!logger) {
941
+ logger = await initializeLogger();
942
+ }
943
+
944
+ try {
945
+ logger.debug('Processing MCP request', {
946
+ method: request.method,
947
+ hasParams: !!request.params,
948
+ requestId: request.id
949
+ });
950
+
951
+ switch (request.method) {
952
+ case 'initialize':
953
+ const version = await getVersion();
954
+ response.result = {
955
+ protocolVersion: '2024-11-05',
956
+ capabilities: {
957
+ tools: {},
958
+ resources: {
959
+ list: true,
960
+ read: true
961
+ }
962
+ },
963
+ serverInfo: {
964
+ name: '@sparkleideas/ruv-swarm',
965
+ version: version
966
+ }
967
+ };
968
+ break;
969
+
970
+ case 'tools/list':
971
+ response.result = {
972
+ tools: [
973
+ {
974
+ name: 'swarm_init',
975
+ description: 'Initialize a new swarm with specified topology',
976
+ inputSchema: {
977
+ type: 'object',
978
+ properties: {
979
+ topology: { type: 'string', enum: ['mesh', 'hierarchical', 'ring', 'star'], description: 'Swarm topology type' },
980
+ maxAgents: { type: 'number', minimum: 1, maximum: 100, default: 5, description: 'Maximum number of agents' },
981
+ strategy: { type: 'string', enum: ['balanced', 'specialized', 'adaptive'], default: 'balanced', description: 'Distribution strategy' }
982
+ },
983
+ required: ['topology']
984
+ }
985
+ },
986
+ {
987
+ name: 'swarm_status',
988
+ description: 'Get current swarm status and agent information',
989
+ inputSchema: {
990
+ type: 'object',
991
+ properties: {
992
+ verbose: { type: 'boolean', default: false, description: 'Include detailed agent information' }
993
+ }
994
+ }
995
+ },
996
+ {
997
+ name: 'swarm_monitor',
998
+ description: 'Monitor swarm activity in real-time',
999
+ inputSchema: {
1000
+ type: 'object',
1001
+ properties: {
1002
+ duration: { type: 'number', default: 10, description: 'Monitoring duration in seconds' },
1003
+ interval: { type: 'number', default: 1, description: 'Update interval in seconds' }
1004
+ }
1005
+ }
1006
+ },
1007
+ {
1008
+ name: 'agent_spawn',
1009
+ description: 'Spawn a new agent in the swarm',
1010
+ inputSchema: {
1011
+ type: 'object',
1012
+ properties: {
1013
+ type: { type: 'string', enum: ['researcher', 'coder', 'analyst', 'optimizer', 'coordinator'], description: 'Agent type' },
1014
+ name: { type: 'string', description: 'Custom agent name' },
1015
+ capabilities: { type: 'array', items: { type: 'string' }, description: 'Agent capabilities' }
1016
+ },
1017
+ required: ['type']
1018
+ }
1019
+ },
1020
+ {
1021
+ name: 'agent_list',
1022
+ description: 'List all active agents in the swarm',
1023
+ inputSchema: {
1024
+ type: 'object',
1025
+ properties: {
1026
+ filter: { type: 'string', enum: ['all', 'active', 'idle', 'busy'], default: 'all', description: 'Filter agents by status' }
1027
+ }
1028
+ }
1029
+ },
1030
+ {
1031
+ name: 'agent_metrics',
1032
+ description: 'Get performance metrics for agents',
1033
+ inputSchema: {
1034
+ type: 'object',
1035
+ properties: {
1036
+ agentId: { type: 'string', description: 'Specific agent ID (optional)' },
1037
+ metric: { type: 'string', enum: ['all', 'cpu', 'memory', 'tasks', 'performance'], default: 'all' }
1038
+ }
1039
+ }
1040
+ },
1041
+ {
1042
+ name: 'task_orchestrate',
1043
+ description: 'Orchestrate a task across the swarm',
1044
+ inputSchema: {
1045
+ type: 'object',
1046
+ properties: {
1047
+ task: { type: 'string', description: 'Task description or instructions' },
1048
+ strategy: { type: 'string', enum: ['parallel', 'sequential', 'adaptive'], default: 'adaptive', description: 'Execution strategy' },
1049
+ priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium', description: 'Task priority' },
1050
+ maxAgents: { type: 'number', minimum: 1, maximum: 10, description: 'Maximum agents to use' }
1051
+ },
1052
+ required: ['task']
1053
+ }
1054
+ },
1055
+ {
1056
+ name: 'task_status',
1057
+ description: 'Check progress of running tasks',
1058
+ inputSchema: {
1059
+ type: 'object',
1060
+ properties: {
1061
+ taskId: { type: 'string', description: 'Specific task ID (optional)' },
1062
+ detailed: { type: 'boolean', default: false, description: 'Include detailed progress' }
1063
+ }
1064
+ }
1065
+ },
1066
+ {
1067
+ name: 'task_results',
1068
+ description: 'Retrieve results from completed tasks',
1069
+ inputSchema: {
1070
+ type: 'object',
1071
+ properties: {
1072
+ taskId: { type: 'string', description: 'Task ID to retrieve results for' },
1073
+ format: { type: 'string', enum: ['summary', 'detailed', 'raw'], default: 'summary', description: 'Result format' }
1074
+ },
1075
+ required: ['taskId']
1076
+ }
1077
+ },
1078
+ {
1079
+ name: 'benchmark_run',
1080
+ description: 'Execute performance benchmarks',
1081
+ inputSchema: {
1082
+ type: 'object',
1083
+ properties: {
1084
+ type: { type: 'string', enum: ['all', 'wasm', 'swarm', 'agent', 'task'], default: 'all', description: 'Benchmark type' },
1085
+ iterations: { type: 'number', minimum: 1, maximum: 100, default: 10, description: 'Number of iterations' }
1086
+ }
1087
+ }
1088
+ },
1089
+ {
1090
+ name: 'features_detect',
1091
+ description: 'Detect runtime features and capabilities',
1092
+ inputSchema: {
1093
+ type: 'object',
1094
+ properties: {
1095
+ category: { type: 'string', enum: ['all', 'wasm', 'simd', 'memory', 'platform'], default: 'all', description: 'Feature category' }
1096
+ }
1097
+ }
1098
+ },
1099
+ {
1100
+ name: 'memory_usage',
1101
+ description: 'Get current memory usage statistics',
1102
+ inputSchema: {
1103
+ type: 'object',
1104
+ properties: {
1105
+ detail: { type: 'string', enum: ['summary', 'detailed', 'by-agent'], default: 'summary', description: 'Detail level' }
1106
+ }
1107
+ }
1108
+ },
1109
+ {
1110
+ name: 'neural_status',
1111
+ description: 'Get neural agent status and performance metrics',
1112
+ inputSchema: {
1113
+ type: 'object',
1114
+ properties: {
1115
+ agentId: { type: 'string', description: 'Specific agent ID (optional)' }
1116
+ }
1117
+ }
1118
+ },
1119
+ {
1120
+ name: 'neural_train',
1121
+ description: 'Train neural agents with sample tasks',
1122
+ inputSchema: {
1123
+ type: 'object',
1124
+ properties: {
1125
+ agentId: { type: 'string', description: 'Specific agent ID to train (optional)' },
1126
+ iterations: { type: 'number', minimum: 1, maximum: 100, default: 10, description: 'Number of training iterations' }
1127
+ }
1128
+ }
1129
+ },
1130
+ {
1131
+ name: 'neural_patterns',
1132
+ description: 'Get cognitive pattern information',
1133
+ inputSchema: {
1134
+ type: 'object',
1135
+ properties: {
1136
+ pattern: { type: 'string', enum: ['all', 'convergent', 'divergent', 'lateral', 'systems', 'critical', 'abstract'], default: 'all', description: 'Cognitive pattern type' }
1137
+ }
1138
+ }
1139
+ },
1140
+ // Add DAA tools
1141
+ ...daaMcpTools.getToolDefinitions()
1142
+ ]
1143
+ };
1144
+ break;
1145
+
1146
+ case 'tools/call':
1147
+ const toolName = request.params.name;
1148
+ const toolArgs = request.params.arguments || {};
1149
+
1150
+ logger.info('Tool call requested', {
1151
+ tool: toolName,
1152
+ hasArgs: Object.keys(toolArgs).length > 0,
1153
+ requestId: request.id
1154
+ });
1155
+
1156
+ let result = null;
1157
+ let toolFound = false;
1158
+ const toolOpId = logger.startOperation(`tool-${toolName}`, {
1159
+ tool: toolName,
1160
+ requestId: request.id
1161
+ });
1162
+
1163
+ // Try regular MCP tools first (use mcpToolsEnhanced.tools)
1164
+ if (mcpToolsEnhanced.tools && typeof mcpToolsEnhanced.tools[toolName] === 'function') {
1165
+ try {
1166
+ logger.debug('Executing MCP tool', { tool: toolName, args: toolArgs });
1167
+ result = await mcpToolsEnhanced.tools[toolName](toolArgs);
1168
+ toolFound = true;
1169
+ logger.endOperation(toolOpId, true, { resultType: typeof result });
1170
+ } catch (error) {
1171
+ logger.endOperation(toolOpId, false, { error });
1172
+ logger.error('MCP tool execution failed', {
1173
+ tool: toolName,
1174
+ error,
1175
+ args: toolArgs
1176
+ });
1177
+ response.error = {
1178
+ code: -32603,
1179
+ message: `MCP tool error: ${error.message}`,
1180
+ data: { tool: toolName, error: error.message }
1181
+ };
1182
+ break;
1183
+ }
1184
+ }
1185
+ // Try DAA tools if not found in regular tools
1186
+ else if (typeof daaMcpTools[toolName] === 'function') {
1187
+ try {
1188
+ logger.debug('Executing DAA tool', { tool: toolName, args: toolArgs });
1189
+ result = await daaMcpTools[toolName](toolArgs);
1190
+ toolFound = true;
1191
+ logger.endOperation(toolOpId, true, { resultType: typeof result });
1192
+ } catch (error) {
1193
+ logger.endOperation(toolOpId, false, { error });
1194
+ logger.error('DAA tool execution failed', {
1195
+ tool: toolName,
1196
+ error,
1197
+ args: toolArgs
1198
+ });
1199
+ response.error = {
1200
+ code: -32603,
1201
+ message: `DAA tool error: ${error.message}`,
1202
+ data: { tool: toolName, error: error.message }
1203
+ };
1204
+ break;
1205
+ }
1206
+ }
1207
+
1208
+ if (toolFound) {
1209
+ // Format response with content array as required by Claude Code
1210
+ response.result = {
1211
+ content: [{
1212
+ type: 'text',
1213
+ text: typeof result === 'string' ? result : JSON.stringify(result, null, 2)
1214
+ }]
1215
+ };
1216
+ } else {
1217
+ response.error = {
1218
+ code: -32601,
1219
+ message: 'Method not found',
1220
+ data: `Unknown tool: ${toolName}`
1221
+ };
1222
+ }
1223
+ break;
1224
+
1225
+ case 'resources/list':
1226
+ response.result = {
1227
+ resources: [
1228
+ {
1229
+ uri: 'swarm://docs/getting-started',
1230
+ name: 'Getting Started Guide',
1231
+ description: 'Introduction to @sparkleideas/ruv-swarm and basic usage',
1232
+ mimeType: 'text/markdown'
1233
+ },
1234
+ {
1235
+ uri: 'swarm://docs/stability',
1236
+ name: 'Stability Features',
1237
+ description: 'Auto-restart and crash protection features',
1238
+ mimeType: 'text/markdown'
1239
+ }
1240
+ ]
1241
+ };
1242
+ break;
1243
+
1244
+ case 'resources/read':
1245
+ const resourceUri = request.params.uri;
1246
+ response.result = await getResourceContent(resourceUri);
1247
+ break;
1248
+
1249
+ default:
1250
+ response.error = {
1251
+ code: -32601,
1252
+ message: 'Method not found',
1253
+ data: `Unknown method: ${request.method}`
1254
+ };
1255
+ }
1256
+ } catch (error) {
1257
+ response.error = {
1258
+ code: -32603,
1259
+ message: 'Internal error',
1260
+ data: error.message
1261
+ };
1262
+ }
1263
+
1264
+ return response;
1265
+ }
1266
+
1267
+ async function handleHook(args) {
1268
+ // Hook handler for Claude Code integration
1269
+ const { main: hooksCLIMain } = await import('../src/hooks/cli.js');
1270
+
1271
+ // Pass through to hooks CLI with 'hook' already consumed
1272
+ process.argv = ['node', '@sparkleideas/ruv-swarm', 'hook', ...args];
1273
+
1274
+ return hooksCLIMain();
1275
+ }
1276
+
1277
+ async function handleNeural(args) {
1278
+ const { neuralCLI } = await import('../src/neural.js');
1279
+ const subcommand = args[0] || 'help';
1280
+
1281
+ try {
1282
+ switch (subcommand) {
1283
+ case 'status':
1284
+ return await neuralCLI.status(args.slice(1));
1285
+ case 'train':
1286
+ return await neuralCLI.train(args.slice(1));
1287
+ case 'patterns':
1288
+ return await neuralCLI.patterns(args.slice(1));
1289
+ case 'export':
1290
+ return await neuralCLI.export(args.slice(1));
1291
+ case 'help':
1292
+ default:
1293
+ console.log(`Neural Network Commands:
1294
+ neural status Show neural network status
1295
+ neural train [options] Train neural models
1296
+ neural patterns [model] View learned patterns
1297
+ neural export [options] Export neural weights
1298
+
1299
+ Examples:
1300
+ @sparkleideas/ruv-swarm neural status
1301
+ @sparkleideas/ruv-swarm neural train --model attention --iterations 100
1302
+ @sparkleideas/ruv-swarm neural patterns --model attention
1303
+ @sparkleideas/ruv-swarm neural export --model all --output ./weights.json`);
1304
+ break;
1305
+ }
1306
+ } catch (error) {
1307
+ console.error('āŒ Neural command error:', error.message);
1308
+ process.exit(1);
1309
+ }
1310
+ }
1311
+
1312
+ async function handleBenchmark(args) {
1313
+ const { benchmarkCLI } = await import('../src/benchmark.js');
1314
+ const subcommand = args[0] || 'help';
1315
+
1316
+ try {
1317
+ switch (subcommand) {
1318
+ case 'run':
1319
+ return await benchmarkCLI.run(args.slice(1));
1320
+ case 'compare':
1321
+ return await benchmarkCLI.compare(args.slice(1));
1322
+ case 'help':
1323
+ default:
1324
+ console.log(`Benchmark Commands:
1325
+ benchmark run [options] Run performance benchmarks
1326
+ benchmark compare [files] Compare benchmark results
1327
+
1328
+ Examples:
1329
+ @sparkleideas/ruv-swarm benchmark run --iterations 10
1330
+ @sparkleideas/ruv-swarm benchmark run --test swarm-coordination
1331
+ @sparkleideas/ruv-swarm benchmark compare results-1.json results-2.json`);
1332
+ break;
1333
+ }
1334
+ } catch (error) {
1335
+ console.error('āŒ Benchmark command error:', error.message);
1336
+ process.exit(1);
1337
+ }
1338
+ }
1339
+
1340
+ async function handlePerformance(args) {
1341
+ const { performanceCLI } = await import('../src/performance.js');
1342
+ const subcommand = args[0] || 'help';
1343
+
1344
+ try {
1345
+ switch (subcommand) {
1346
+ case 'analyze':
1347
+ return await performanceCLI.analyze(args.slice(1));
1348
+ case 'optimize':
1349
+ return await performanceCLI.optimize(args.slice(1));
1350
+ case 'suggest':
1351
+ return await performanceCLI.suggest(args.slice(1));
1352
+ case 'help':
1353
+ default:
1354
+ console.log(`Performance Commands:
1355
+ performance analyze [options] Analyze performance bottlenecks
1356
+ performance optimize [target] Optimize swarm configuration
1357
+ performance suggest Get optimization suggestions
1358
+
1359
+ Examples:
1360
+ @sparkleideas/ruv-swarm performance analyze --task-id recent
1361
+ @sparkleideas/ruv-swarm performance optimize --target speed
1362
+ @sparkleideas/ruv-swarm performance suggest`);
1363
+ break;
1364
+ }
1365
+ } catch (error) {
1366
+ console.error('āŒ Performance command error:', error.message);
1367
+ process.exit(1);
1368
+ }
1369
+ }
1370
+
1371
+ async function handleDiagnose(args) {
1372
+ const { diagnosticsCLI } = await import('../src/cli-diagnostics.js');
1373
+ return diagnosticsCLI(args);
1374
+ }
1375
+
1376
+ async function showHelp() {
1377
+ const version = await getVersion();
1378
+ console.log(`
1379
+ šŸ @sparkleideas/ruv-swarm v${version} - Production-ready WASM-powered neural swarm orchestration
1380
+
1381
+ Usage: @sparkleideas/ruv-swarm <command> [options]
1382
+
1383
+ Commands:
1384
+ init [topology] [maxAgents] Initialize swarm (--claude for integration)
1385
+ Options for --claude:
1386
+ --force Overwrite existing CLAUDE.md (creates backup)
1387
+ --merge Merge with existing CLAUDE.md content
1388
+ --no-backup Disable automatic backup creation
1389
+ --no-interactive Skip interactive prompts (fail on conflicts)
1390
+ spawn <type> [name] Spawn an agent (researcher, coder, analyst, etc.)
1391
+ orchestrate <task> Orchestrate a task across agents
1392
+ status [--verbose] Show swarm status
1393
+ monitor [duration] Monitor swarm activity
1394
+ mcp <subcommand> MCP server management
1395
+ Options for mcp start:
1396
+ --stability Enable auto-restart on crashes
1397
+ hook <type> [options] Claude Code hooks integration
1398
+ claude-invoke <prompt> Invoke Claude with swarm integration
1399
+ neural <subcommand> Neural network training and analysis
1400
+ benchmark <subcommand> Performance benchmarking tools
1401
+ performance <subcommand> Performance analysis and optimization
1402
+ diagnose <subcommand> Run diagnostics and analyze logs
1403
+ version Show version information
1404
+ help Show this help message
1405
+
1406
+ Examples:
1407
+ @sparkleideas/ruv-swarm init mesh 5 --claude # Create CLAUDE.md (fails if exists)
1408
+ @sparkleideas/ruv-swarm init mesh 5 --claude --force # Overwrite CLAUDE.md (creates backup)
1409
+ @sparkleideas/ruv-swarm spawn researcher "AI Research Specialist"
1410
+ @sparkleideas/ruv-swarm orchestrate "Build a REST API with authentication"
1411
+ @sparkleideas/ruv-swarm mcp start --stability # Start with crash protection
1412
+ @sparkleideas/ruv-swarm hook pre-edit --file app.js --ensure-coordination
1413
+ @sparkleideas/ruv-swarm claude-invoke "Create a development swarm for my project"
1414
+
1415
+ šŸ”’ Security Features:
1416
+ • Input validation and sanitization
1417
+ • Explicit permission control for Claude invocation
1418
+ • Command injection prevention
1419
+ • WASM integrity verification
1420
+
1421
+ šŸ›”ļø Stability Features:
1422
+ • Auto-restart on crashes (--stability flag)
1423
+ • Circuit breaker pattern
1424
+ • Graceful shutdown handling
1425
+ • Process supervision
1426
+
1427
+ Production Features:
1428
+ šŸ“š Automatic documentation generation
1429
+ 🌐 Cross-platform remote execution support
1430
+ šŸ¤– Seamless Claude Code MCP integration
1431
+ šŸ”§ Advanced hooks for automation
1432
+ 🧠 Neural pattern learning
1433
+ šŸ’¾ Cross-session memory persistence
1434
+ šŸ›”ļø Security and stability hardening
1435
+
1436
+ For detailed documentation, check .claude/commands/ after running init --claude
1437
+ `);
1438
+ }
1439
+
1440
+ async function main() {
1441
+ const args = process.argv.slice(2);
1442
+
1443
+ // Handle --version flag
1444
+ if (args.includes('--version') || args.includes('-v')) {
1445
+ const version = await getVersion();
1446
+ console.log(version);
1447
+ return;
1448
+ }
1449
+
1450
+ const command = args[0] || 'help';
1451
+
1452
+ try {
1453
+ switch (command) {
1454
+ case 'init':
1455
+ await handleInit(args.slice(1));
1456
+ break;
1457
+ case 'spawn':
1458
+ await handleSpawn(args.slice(1));
1459
+ break;
1460
+ case 'orchestrate':
1461
+ await handleOrchestrate(args.slice(1));
1462
+ break;
1463
+ case 'mcp':
1464
+ await handleMcp(args.slice(1));
1465
+ break;
1466
+ case 'status':
1467
+ await handleStatus(args.slice(1));
1468
+ break;
1469
+ case 'monitor':
1470
+ await handleMonitor(args.slice(1));
1471
+ break;
1472
+ case 'hook':
1473
+ await handleHook(args.slice(1));
1474
+ break;
1475
+ case 'claude-invoke':
1476
+ case 'claude':
1477
+ await handleClaudeInvoke(args.slice(1));
1478
+ break;
1479
+ case 'neural':
1480
+ await handleNeural(args.slice(1));
1481
+ break;
1482
+ case 'benchmark':
1483
+ await handleBenchmark(args.slice(1));
1484
+ break;
1485
+ case 'performance':
1486
+ await handlePerformance(args.slice(1));
1487
+ break;
1488
+ case 'diagnose':
1489
+ await handleDiagnose(args.slice(1));
1490
+ break;
1491
+ case 'version':
1492
+ const version = await getVersion();
1493
+ console.log('@sparkleideas/ruv-swarm v' + version);
1494
+ console.log('Production-ready WASM-powered neural swarm orchestration');
1495
+ console.log('Security & Stability Enhanced Edition');
1496
+ console.log('\nšŸ”’ Security Features:');
1497
+ console.log(' • Input validation and sanitization');
1498
+ console.log(' • Explicit permission control for Claude invocation');
1499
+ console.log(' • Command injection prevention');
1500
+ console.log(' • WASM integrity verification');
1501
+ console.log('\nšŸ›”ļø Stability Features:');
1502
+ console.log(' • Auto-restart on crashes (use --stability flag)');
1503
+ console.log(' • Circuit breaker pattern');
1504
+ console.log(' • Graceful shutdown handling');
1505
+ console.log(' • Process supervision');
1506
+ console.log('\nāœ… Security Status: All vulnerabilities from Issue #107 resolved');
1507
+ console.log('šŸš€ Production Status: Ready for deployment');
1508
+ break;
1509
+ case 'help':
1510
+ default:
1511
+ await showHelp();
1512
+ break;
1513
+ }
1514
+ } catch (error) {
1515
+ console.error('āŒ Error:', error.message);
1516
+ if (process.argv.includes('--debug')) {
1517
+ console.error(error.stack);
1518
+ }
1519
+ process.exit(1);
1520
+ }
1521
+ }
1522
+
1523
+ // Bulletproof error handling - LOG but NEVER exit
1524
+ process.on('uncaughtException', (error) => {
1525
+ console.error('āš ļø Uncaught Exception (continuing operation):', error.message);
1526
+ if (process.argv.includes('--debug')) {
1527
+ console.error(error.stack);
1528
+ }
1529
+ if (isStabilityMode) {
1530
+ stabilityLog(`Uncaught exception: ${error.message} - continuing...`);
1531
+ }
1532
+ // DO NOT EXIT - bulletproof operation continues
1533
+ });
1534
+
1535
+ process.on('unhandledRejection', (reason, promise) => {
1536
+ console.error('āš ļø Unhandled Rejection (continuing operation):', reason);
1537
+ if (process.argv.includes('--debug')) {
1538
+ console.error('Promise:', promise);
1539
+ }
1540
+ if (isStabilityMode) {
1541
+ stabilityLog(`Unhandled rejection: ${reason} - continuing...`);
1542
+ }
1543
+ // DO NOT EXIT - bulletproof operation continues
1544
+ });
1545
+
1546
+ // In ES modules, this file is always the main module when run directly
1547
+ main();
1548
+
1549
+ export { main, initializeSystem };