monomind 1.17.0 → 1.17.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 (91) hide show
  1. package/.claude/agents/engineering/engineering-security-engineer.md +1 -1
  2. package/.claude/commands/mastermind/_repeat.md +4 -0
  3. package/.claude/commands/mastermind/master.md +52 -1
  4. package/.claude/scheduled_tasks.lock +1 -1
  5. package/.claude/skills/mastermind/_repeat.md +2 -0
  6. package/package.json +1 -1
  7. package/packages/@monomind/cli/.claude/agents/engineering/engineering-security-engineer.md +1 -1
  8. package/packages/@monomind/cli/.claude/commands/mastermind/_repeat.md +4 -0
  9. package/packages/@monomind/cli/.claude/commands/mastermind/master.md +52 -1
  10. package/packages/@monomind/cli/.claude/skills/mastermind/_repeat.md +2 -0
  11. package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.js +42 -59
  12. package/packages/@monomind/cli/dist/src/browser/dashboard/server.js +18 -0
  13. package/packages/@monomind/cli/dist/src/browser/dashboard/ui.html +37 -125
  14. package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.d.ts +17 -0
  15. package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.js +320 -0
  16. package/packages/@monomind/cli/dist/src/commands/agent-ops.d.ts +9 -0
  17. package/packages/@monomind/cli/dist/src/commands/agent-ops.js +329 -0
  18. package/packages/@monomind/cli/dist/src/commands/agent.js +5 -907
  19. package/packages/@monomind/cli/dist/src/commands/analyze-ast.d.ts +26 -0
  20. package/packages/@monomind/cli/dist/src/commands/analyze-ast.js +284 -0
  21. package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.d.ts +14 -0
  22. package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.js +295 -0
  23. package/packages/@monomind/cli/dist/src/commands/analyze-diff.d.ts +8 -0
  24. package/packages/@monomind/cli/dist/src/commands/analyze-diff.js +395 -0
  25. package/packages/@monomind/cli/dist/src/commands/analyze-graph.d.ts +14 -0
  26. package/packages/@monomind/cli/dist/src/commands/analyze-graph.js +304 -0
  27. package/packages/@monomind/cli/dist/src/commands/analyze-imports.d.ts +11 -0
  28. package/packages/@monomind/cli/dist/src/commands/analyze-imports.js +287 -0
  29. package/packages/@monomind/cli/dist/src/commands/analyze-symbols.d.ts +14 -0
  30. package/packages/@monomind/cli/dist/src/commands/analyze-symbols.js +302 -0
  31. package/packages/@monomind/cli/dist/src/commands/analyze.d.ts +38 -0
  32. package/packages/@monomind/cli/dist/src/commands/analyze.js +12 -1827
  33. package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.d.ts +26 -0
  34. package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.js +189 -0
  35. package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +19 -0
  36. package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +388 -0
  37. package/packages/@monomind/cli/dist/src/commands/doctor.js +51 -942
  38. package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.d.ts +11 -0
  39. package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.js +242 -0
  40. package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.d.ts +35 -0
  41. package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.js +203 -0
  42. package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.d.ts +8 -0
  43. package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.js +233 -0
  44. package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.d.ts +12 -0
  45. package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.js +274 -0
  46. package/packages/@monomind/cli/dist/src/commands/hive-mind.js +10 -1129
  47. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +4 -4
  48. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +19 -819
  49. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.d.ts +7 -0
  50. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +334 -0
  51. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.d.ts +7 -0
  52. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.js +399 -0
  53. package/packages/@monomind/cli/dist/src/commands/init-subcommands.d.ts +8 -0
  54. package/packages/@monomind/cli/dist/src/commands/init-subcommands.js +156 -0
  55. package/packages/@monomind/cli/dist/src/commands/init-upgrade.d.ts +6 -0
  56. package/packages/@monomind/cli/dist/src/commands/init-upgrade.js +203 -0
  57. package/packages/@monomind/cli/dist/src/commands/init-wizard.d.ts +6 -0
  58. package/packages/@monomind/cli/dist/src/commands/init-wizard.js +246 -0
  59. package/packages/@monomind/cli/dist/src/commands/init.js +6 -623
  60. package/packages/@monomind/cli/dist/src/commands/memory-admin.d.ts +10 -0
  61. package/packages/@monomind/cli/dist/src/commands/memory-admin.js +433 -0
  62. package/packages/@monomind/cli/dist/src/commands/memory-crud.d.ts +9 -0
  63. package/packages/@monomind/cli/dist/src/commands/memory-crud.js +342 -0
  64. package/packages/@monomind/cli/dist/src/commands/memory-list.d.ts +10 -0
  65. package/packages/@monomind/cli/dist/src/commands/memory-list.js +321 -0
  66. package/packages/@monomind/cli/dist/src/commands/memory-transfer.d.ts +9 -0
  67. package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +372 -0
  68. package/packages/@monomind/cli/dist/src/commands/memory.d.ts +6 -0
  69. package/packages/@monomind/cli/dist/src/commands/memory.js +10 -1441
  70. package/packages/@monomind/cli/dist/src/commands/neural-core.d.ts +8 -0
  71. package/packages/@monomind/cli/dist/src/commands/neural-core.js +274 -0
  72. package/packages/@monomind/cli/dist/src/commands/neural-optimize.d.ts +7 -0
  73. package/packages/@monomind/cli/dist/src/commands/neural-optimize.js +332 -0
  74. package/packages/@monomind/cli/dist/src/commands/neural-registry.d.ts +7 -0
  75. package/packages/@monomind/cli/dist/src/commands/neural-registry.js +290 -0
  76. package/packages/@monomind/cli/dist/src/commands/neural.js +3 -974
  77. package/packages/@monomind/cli/dist/src/commands/platforms.js +327 -7
  78. package/packages/@monomind/cli/dist/src/commands/security-cve.d.ts +6 -0
  79. package/packages/@monomind/cli/dist/src/commands/security-cve.js +310 -0
  80. package/packages/@monomind/cli/dist/src/commands/security-misc.d.ts +9 -0
  81. package/packages/@monomind/cli/dist/src/commands/security-misc.js +293 -0
  82. package/packages/@monomind/cli/dist/src/commands/security-scan.d.ts +18 -0
  83. package/packages/@monomind/cli/dist/src/commands/security-scan.js +328 -0
  84. package/packages/@monomind/cli/dist/src/commands/security.js +3 -958
  85. package/packages/@monomind/cli/dist/src/commands/session.js +1 -1
  86. package/packages/@monomind/cli/dist/src/commands/swarm.js +23 -17
  87. package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +77 -0
  88. package/packages/@monomind/cli/dist/src/parser.js +11 -6
  89. package/packages/@monomind/cli/dist/src/routing/llm-caller.js +1 -2
  90. package/packages/@monomind/cli/package.json +2 -3
  91. package/packages/@monomind/cli/scripts/understand-analyze.mjs +1 -1
@@ -6,374 +6,21 @@
6
6
  * PR: Fix #955 - Implement --claude flag for hive-mind spawn command
7
7
  */
8
8
  import { output } from '../output.js';
9
- import { select, confirm, input } from '../prompt.js';
9
+ import { select } from '../prompt.js';
10
10
  import { callMCPTool, MCPClientError } from '../mcp-client.js';
11
- import { spawn as childSpawn, execSync } from 'child_process';
12
- import { mkdir, writeFile } from 'fs/promises';
13
- import { join, resolve as resolvePath, sep } from 'path';
14
- // Input length caps
15
- const MAX_OBJECTIVE_LEN = 2_000;
16
- const MAX_TASK_DESC_LEN = 4_000;
17
- const MAX_MESSAGE_LEN = 2_000;
18
- const MAX_KEY_LEN = 256;
19
- const MAX_VALUE_LEN = 65_536;
20
- const MAX_AGENT_ID_LEN = 128;
21
- // Hive topologies
22
- const TOPOLOGIES = [
23
- { value: 'hierarchical', label: 'Hierarchical', hint: 'Queen-led with worker agents' },
24
- { value: 'mesh', label: 'Mesh', hint: 'Peer-to-peer coordination' },
25
- { value: 'hierarchical-mesh', label: 'Hierarchical Mesh', hint: 'Queen + peer communication (recommended)' },
26
- { value: 'adaptive', label: 'Adaptive', hint: 'Dynamic topology based on task' }
27
- ];
28
- // Consensus strategies
29
- const CONSENSUS_STRATEGIES = [
30
- { value: 'byzantine', label: 'Byzantine Fault Tolerant', hint: '2/3 majority, handles malicious actors' },
31
- { value: 'raft', label: 'Raft', hint: 'Leader-based consensus' },
32
- { value: 'gossip', label: 'Gossip', hint: 'Eventually consistent, scalable' },
33
- { value: 'crdt', label: 'CRDT', hint: 'Conflict-free replicated data' },
34
- { value: 'quorum', label: 'Quorum', hint: 'Simple majority voting' }
35
- ];
36
- /**
37
- * Group workers by their type for prompt generation
38
- */
39
- function groupWorkersByType(workers) {
40
- const groups = {};
41
- for (const worker of workers) {
42
- const type = worker.type || worker.role || 'worker';
43
- if (!groups[type]) {
44
- groups[type] = [];
45
- }
46
- groups[type].push(worker);
47
- }
48
- return groups;
49
- }
50
- /**
51
- * Generate comprehensive Hive Mind prompt for Claude Code
52
- * Ported from v2.7.47 with enhancements for v1
53
- */
54
- function generateHiveMindPrompt(swarmId, swarmName, objective, workers, workerGroups, flags) {
55
- const currentTime = new Date().toISOString();
56
- const workerTypes = Object.keys(workerGroups);
57
- const queenType = flags.queenType || 'strategic';
58
- const consensusAlgorithm = flags.consensus || 'byzantine';
59
- const topology = flags.topology || 'hierarchical-mesh';
60
- return `🧠 HIVE MIND COLLECTIVE INTELLIGENCE SYSTEM
61
- ═══════════════════════════════════════════════
62
-
63
- You are the Queen coordinator of a Hive Mind swarm with collective intelligence capabilities.
64
-
65
- HIVE MIND CONFIGURATION:
66
- 📌 Swarm ID: ${swarmId}
67
- 📌 Swarm Name: ${swarmName}
68
- 🎯 Objective: ${objective}
69
- 👑 Queen Type: ${queenType}
70
- 🐝 Worker Count: ${workers.length}
71
- 🔗 Topology: ${topology}
72
- 🤝 Consensus Algorithm: ${consensusAlgorithm}
73
- ⏰ Initialized: ${currentTime}
74
-
75
- WORKER DISTRIBUTION:
76
- ${workerTypes.map(type => `• ${type}: ${workerGroups[type].length} agents`).join('\n')}
77
-
78
- 🔧 AVAILABLE MCP TOOLS FOR HIVE MIND COORDINATION:
79
-
80
- 1️⃣ **COLLECTIVE INTELLIGENCE**
81
- mcp__monomind__hive-mind_consensus - Democratic decision making
82
- mcp__monomind__hive-mind_memory - Share knowledge across the hive
83
- mcp__monomind__hive-mind_broadcast - Broadcast to all workers
84
- mcp__monomind__neural_patterns - Neural pattern recognition
85
-
86
- 2️⃣ **QUEEN COORDINATION**
87
- mcp__monomind__hive-mind_status - Monitor swarm health
88
- mcp__monomind__task_create - Create and delegate tasks
89
- mcp__monomind__coordination_orchestrate - Orchestrate task distribution
90
- mcp__monomind__agent_spawn - Spawn additional workers
91
-
92
- 3️⃣ **WORKER MANAGEMENT**
93
- mcp__monomind__agent_list - List all active agents
94
- mcp__monomind__agent_status - Check agent status
95
- mcp__monomind__agent_health - Check worker health
96
- mcp__monomind__hive-mind_join - Add agent to hive
97
- mcp__monomind__hive-mind_leave - Remove agent from hive
98
-
99
- 4️⃣ **TASK ORCHESTRATION**
100
- mcp__monomind__task_assign - Assign tasks to workers
101
- mcp__monomind__task_status - Track task progress
102
- mcp__monomind__task_complete - Mark tasks complete
103
- mcp__monomind__workflow_create - Create workflows
104
-
105
- 5️⃣ **MEMORY & LEARNING**
106
- mcp__monomind__memory_store - Store collective knowledge
107
- mcp__monomind__memory_retrieve - Access shared memory
108
- mcp__monomind__memory_search - Search memory patterns
109
- mcp__monomind__neural_train - Learn from experiences
110
- mcp__monomind__hooks_intelligence_pattern-store - Store patterns
111
-
112
- 📋 HIVE MIND EXECUTION PROTOCOL:
113
-
114
- 1. **INITIALIZATION PHASE**
115
- - Verify all workers are online and responsive
116
- - Establish communication channels
117
- - Load previous session state if available
118
- - Initialize shared memory space
119
-
120
- 2. **TASK DISTRIBUTION PHASE**
121
- - Analyze the objective and decompose into subtasks
122
- - Assign tasks based on worker specializations
123
- - Set up task dependencies and ordering
124
- - Monitor parallel execution
125
-
126
- 3. **COORDINATION PHASE**
127
- - Use consensus for critical decisions
128
- - Aggregate results from workers
129
- - Resolve conflicts using ${consensusAlgorithm} consensus
130
- - Share learnings across the hive
131
-
132
- 4. **COMPLETION PHASE**
133
- - Verify all subtasks are complete
134
- - Consolidate results
135
- - Store learnings in collective memory
136
- - Report final status
137
-
138
- 🎯 YOUR OBJECTIVE:
139
- ${objective}
140
-
141
- ⚠️ CRITICAL — TOOL PREFERENCE RULES (#1422):
142
- • You MUST use Monomind MCP tools (mcp__monomind__*) for ALL orchestration tasks
143
- • Do NOT use Claude native Task/Agent tools for swarm coordination — use mcp__monomind__agent_spawn, mcp__monomind__task_assign, etc.
144
- • Native Claude tools (Read, Write, Edit, Bash, Grep, Glob) should ONLY be used for file operations and shell commands
145
- • All agent spawning, task assignment, memory, and coordination MUST go through mcp__monomind__* tools
146
- • If a Monomind MCP tool exists for an operation, always prefer it over any native equivalent
147
-
148
- 💡 COORDINATION TIPS:
149
- • Use mcp__monomind__hive-mind_broadcast for swarm-wide announcements
150
- • Check worker status regularly with mcp__monomind__hive-mind_status
151
- • Store important decisions in shared memory for persistence
152
- • Use consensus for any decisions affecting multiple workers
153
- • Use mcp__monomind__task_assign to assign tasks to workers, then mcp__monomind__task_complete when done
154
-
155
- 🚀 BEGIN HIVE MIND COORDINATION NOW!
156
- Start by checking the current hive status and then proceed with the objective.
157
- `;
158
- }
159
- /**
160
- * Spawn Claude Code with Hive Mind coordination instructions
161
- * Ported from v2.7.47 spawnClaudeCodeInstances function
162
- */
163
- async function spawnClaudeCodeInstance(swarmId, swarmName, objective, workers, flags) {
164
- output.writeln();
165
- output.writeln(output.bold('🚀 Launching Claude Code with Hive Mind Coordination'));
166
- output.writeln(output.dim('─'.repeat(60)));
167
- const spinner = output.createSpinner({ text: 'Preparing Hive Mind coordination prompt...', spinner: 'dots' });
168
- spinner.start();
169
- try {
170
- // Generate comprehensive Hive Mind prompt
171
- const workerGroups = groupWorkersByType(workers);
172
- const hiveMindPrompt = generateHiveMindPrompt(swarmId, swarmName, objective, workers, workerGroups, flags);
173
- spinner.succeed('Hive Mind coordination prompt ready!');
174
- // Display coordination summary
175
- output.writeln();
176
- output.writeln(output.bold('🧠 Hive Mind Configuration'));
177
- output.writeln(output.dim('─'.repeat(60)));
178
- output.printList([
179
- `Swarm ID: ${output.highlight(swarmId)}`,
180
- `Objective: ${output.highlight(objective)}`,
181
- `Queen Type: ${output.highlight(flags.queenType || 'strategic')}`,
182
- `Worker Count: ${output.highlight(String(workers.length))}`,
183
- `Worker Types: ${output.highlight(Object.keys(workerGroups).join(', '))}`,
184
- `Consensus: ${output.highlight(flags.consensus || 'byzantine')}`,
185
- `MCP Tools: ${output.success('Full Monomind integration enabled')}`
186
- ]);
187
- // Ensure sessions directory exists (anchor to process.cwd() so relative paths
188
- // don't escape when the caller changes directory)
189
- const baseDir = resolvePath(process.cwd());
190
- const sessionsDir = resolvePath(baseDir, '.hive-mind', 'sessions');
191
- // Guard: sessions directory must stay inside cwd
192
- if (!sessionsDir.startsWith(baseDir + sep) && sessionsDir !== baseDir) {
193
- throw new Error('Sessions directory path traversal detected');
194
- }
195
- await mkdir(sessionsDir, { recursive: true });
196
- const safeSwarmId = swarmId.replace(/[^a-zA-Z0-9_-]/g, '_');
197
- const promptFile = join(sessionsDir, `hive-mind-prompt-${safeSwarmId}.txt`);
198
- // Guard: prompt file must stay inside sessions directory
199
- if (!resolvePath(promptFile).startsWith(sessionsDir + sep)) {
200
- throw new Error('Prompt file path traversal detected');
201
- }
202
- await writeFile(promptFile, hiveMindPrompt, 'utf8');
203
- output.writeln();
204
- output.printSuccess(`Hive Mind prompt saved to: ${promptFile}`);
205
- // Check if claude command exists
206
- let claudeAvailable = false;
207
- try {
208
- execSync('which claude', { stdio: 'ignore' });
209
- claudeAvailable = true;
210
- }
211
- catch {
212
- output.writeln();
213
- output.printWarning('Claude Code CLI not found in PATH');
214
- output.writeln(output.dim('Install it with: npm install -g @anthropic-ai/claude-code'));
215
- output.writeln(output.dim('Falling back to displaying instructions...'));
216
- }
217
- const dryRun = flags.dryRun || flags['dry-run'];
218
- if (claudeAvailable && !dryRun) {
219
- // Build arguments - flags first, then prompt
220
- const claudeArgs = [];
221
- // Check for non-interactive mode
222
- const isNonInteractive = flags['non-interactive'] || flags.nonInteractive;
223
- if (isNonInteractive) {
224
- claudeArgs.push('-p'); // Print mode
225
- claudeArgs.push('--output-format', 'stream-json');
226
- claudeArgs.push('--verbose');
227
- output.printInfo('Running in non-interactive mode');
228
- }
229
- // Add auto-permission flag only when explicitly requested
230
- const skipPermissions = flags['dangerously-skip-permissions'] === true && !flags['no-auto-permissions'];
231
- if (skipPermissions) {
232
- claudeArgs.push('--dangerously-skip-permissions');
233
- output.writeln(output.warning('WARNING: Running with --dangerously-skip-permissions: all file and shell operations will execute without prompts.'));
234
- }
235
- // '--' ends option parsing so the prompt cannot be interpreted as a flag
236
- claudeArgs.push('--');
237
- claudeArgs.push(hiveMindPrompt);
238
- output.writeln();
239
- output.printInfo('Launching Claude Code...');
240
- output.writeln(output.dim('Press Ctrl+C to pause the session'));
241
- // Spawn claude with properly ordered arguments
242
- const claudeProcess = childSpawn('claude', claudeArgs, {
243
- stdio: 'inherit',
244
- shell: false,
245
- });
246
- // Set up SIGINT handler for session management
247
- let isExiting = false;
248
- const sigintHandler = () => {
249
- if (isExiting)
250
- return;
251
- isExiting = true;
252
- output.writeln();
253
- output.writeln();
254
- output.printWarning('Pausing session and terminating Claude Code...');
255
- if (claudeProcess && !claudeProcess.killed) {
256
- claudeProcess.kill('SIGTERM');
257
- }
258
- output.writeln();
259
- output.printSuccess('Session paused');
260
- output.writeln(output.dim(`Prompt file saved at: ${promptFile}`));
261
- output.writeln(output.dim('To resume, run claude with the saved prompt file'));
262
- process.exit(0);
263
- };
264
- process.on('SIGINT', sigintHandler);
265
- process.on('SIGTERM', sigintHandler);
266
- // Handle process exit
267
- claudeProcess.on('exit', (code) => {
268
- // Clean up signal handlers
269
- process.removeListener('SIGINT', sigintHandler);
270
- process.removeListener('SIGTERM', sigintHandler);
271
- if (code === 0) {
272
- output.writeln();
273
- output.printSuccess('Claude Code completed successfully');
274
- }
275
- else if (code !== null) {
276
- output.writeln();
277
- output.printError(`Claude Code exited with code ${code}`);
278
- }
279
- });
280
- output.writeln();
281
- output.printSuccess('Claude Code launched with Hive Mind coordination');
282
- output.printInfo('The Queen coordinator will orchestrate all worker agents');
283
- output.writeln(output.dim(`Prompt file saved at: ${promptFile}`));
284
- return { success: true, promptFile };
285
- }
286
- else if (dryRun) {
287
- output.writeln();
288
- output.printInfo('Dry run - would execute Claude Code with prompt:');
289
- output.writeln(output.dim(`Prompt length: ${hiveMindPrompt.length} characters`));
290
- output.writeln();
291
- output.writeln(output.dim('First 500 characters of prompt:'));
292
- output.writeln(output.highlight(hiveMindPrompt.substring(0, 500) + '...'));
293
- output.writeln();
294
- output.writeln(output.dim(`Full prompt saved to: ${promptFile}`));
295
- return { success: true, promptFile };
296
- }
297
- else {
298
- // Claude not available - show instructions
299
- output.writeln();
300
- output.writeln(output.bold('📋 Manual Execution Instructions:'));
301
- output.writeln(output.dim('─'.repeat(50)));
302
- output.printList([
303
- 'Install Claude Code: npm install -g @anthropic-ai/claude-code',
304
- `Run with saved prompt: claude < ${promptFile}`,
305
- `Or copy manually: cat ${promptFile} | claude`,
306
- `With auto-permissions: claude --dangerously-skip-permissions < ${promptFile}`
307
- ]);
308
- return { success: true, promptFile };
309
- }
310
- }
311
- catch (error) {
312
- spinner.fail('Failed to prepare Claude Code coordination');
313
- const errorMessage = error instanceof Error ? error.message : String(error);
314
- output.printError(`Error: ${errorMessage}`);
315
- // Try to save prompt as fallback — write inside cwd to avoid path issues
316
- try {
317
- const safeSwarmIdFallback = swarmId.replace(/[^a-zA-Z0-9_-]/g, '_');
318
- const fallbackDir = resolvePath(process.cwd());
319
- const promptFile = join(fallbackDir, `hive-mind-prompt-${safeSwarmIdFallback}-fallback.txt`);
320
- if (!resolvePath(promptFile).startsWith(fallbackDir + sep)) {
321
- throw new Error('Fallback path traversal');
322
- }
323
- const workerGroups = groupWorkersByType(workers);
324
- const hiveMindPrompt = generateHiveMindPrompt(swarmId, swarmName, objective, workers, workerGroups, flags);
325
- await writeFile(promptFile, hiveMindPrompt, 'utf8');
326
- output.writeln();
327
- output.printSuccess(`Prompt saved to: ${promptFile}`);
328
- output.writeln(output.dim('You can run Claude Code manually with the saved prompt'));
329
- return { success: false, promptFile, error: errorMessage };
330
- }
331
- catch {
332
- return { success: false, error: errorMessage };
333
- }
334
- }
335
- }
336
- // Init subcommand
11
+ import { TOPOLOGIES, CONSENSUS_STRATEGIES } from './hive-mind-helpers.js';
12
+ import { spawnCommand } from './hive-mind-spawn.js';
13
+ import { statusCommand, taskCommand, optimizeMemoryCommand } from './hive-mind-ops.js';
14
+ import { joinCommand, leaveCommand, consensusCommand, broadcastCommand, memorySubCommand, shutdownCommand } from './hive-mind-comms.js';
337
15
  const initCommand = {
338
16
  name: 'init',
339
17
  description: 'Initialize a hive mind',
340
18
  options: [
341
- {
342
- name: 'topology',
343
- short: 't',
344
- description: 'Hive topology',
345
- type: 'string',
346
- choices: TOPOLOGIES.map(t => t.value),
347
- default: 'hierarchical-mesh'
348
- },
349
- {
350
- name: 'consensus',
351
- short: 'c',
352
- description: 'Consensus strategy',
353
- type: 'string',
354
- choices: CONSENSUS_STRATEGIES.map(s => s.value),
355
- default: 'byzantine'
356
- },
357
- {
358
- name: 'max-agents',
359
- short: 'm',
360
- description: 'Maximum agents',
361
- type: 'number',
362
- default: 15
363
- },
364
- {
365
- name: 'persist',
366
- short: 'p',
367
- description: 'Enable persistent state',
368
- type: 'boolean',
369
- default: true
370
- },
371
- {
372
- name: 'memory-backend',
373
- description: 'Memory backend (lancedb, sqlite, hybrid)',
374
- type: 'string',
375
- default: 'hybrid'
376
- }
19
+ { name: 'topology', short: 't', description: 'Hive topology', type: 'string', choices: TOPOLOGIES.map(t => t.value), default: 'hierarchical-mesh' },
20
+ { name: 'consensus', short: 'c', description: 'Consensus strategy', type: 'string', choices: CONSENSUS_STRATEGIES.map(s => s.value), default: 'byzantine' },
21
+ { name: 'max-agents', short: 'm', description: 'Maximum agents', type: 'number', default: 15 },
22
+ { name: 'persist', short: 'p', description: 'Enable persistent state', type: 'boolean', default: true },
23
+ { name: 'memory-backend', description: 'Memory backend (lancedb, sqlite, hybrid)', type: 'string', default: 'hybrid' }
377
24
  ],
378
25
  examples: [
379
26
  { command: 'monomind hive-mind init -t hierarchical-mesh', description: 'Init hierarchical mesh' },
@@ -442,709 +89,6 @@ const initCommand = {
442
89
  }
443
90
  }
444
91
  };
445
- // Spawn subcommand - UPDATED with --claude flag
446
- const spawnCommand = {
447
- name: 'spawn',
448
- description: 'Spawn worker agents into the hive (use --claude to launch Claude Code)',
449
- options: [
450
- {
451
- name: 'count',
452
- short: 'n',
453
- description: 'Number of workers to spawn',
454
- type: 'number',
455
- default: 1
456
- },
457
- {
458
- name: 'role',
459
- short: 'r',
460
- description: 'Worker role (worker, specialist, scout)',
461
- type: 'string',
462
- choices: ['worker', 'specialist', 'scout'],
463
- default: 'worker'
464
- },
465
- {
466
- name: 'type',
467
- short: 't',
468
- description: 'Agent type',
469
- type: 'string',
470
- default: 'worker'
471
- },
472
- {
473
- name: 'prefix',
474
- short: 'p',
475
- description: 'Prefix for worker IDs',
476
- type: 'string',
477
- default: 'hive-worker'
478
- },
479
- // NEW: --claude flag for launching Claude Code
480
- {
481
- name: 'claude',
482
- description: 'Launch Claude Code with hive-mind coordination prompt',
483
- type: 'boolean',
484
- default: false
485
- },
486
- {
487
- name: 'objective',
488
- short: 'o',
489
- description: 'Objective for the hive mind (used with --claude)',
490
- type: 'string'
491
- },
492
- {
493
- name: 'dangerously-skip-permissions',
494
- description: 'Skip permission prompts in Claude Code (use with caution)',
495
- type: 'boolean',
496
- default: false
497
- },
498
- {
499
- name: 'no-auto-permissions',
500
- description: 'Disable automatic permission skipping',
501
- type: 'boolean',
502
- default: false
503
- },
504
- {
505
- name: 'dry-run',
506
- description: 'Show what would be done without launching Claude Code',
507
- type: 'boolean',
508
- default: false
509
- },
510
- {
511
- name: 'non-interactive',
512
- description: 'Run Claude Code in non-interactive mode',
513
- type: 'boolean',
514
- default: false
515
- }
516
- ],
517
- examples: [
518
- { command: 'monomind hive-mind spawn -n 5', description: 'Spawn 5 workers' },
519
- { command: 'monomind hive-mind spawn -n 3 -r specialist', description: 'Spawn 3 specialists' },
520
- { command: 'monomind hive-mind spawn -t coder -p my-coder', description: 'Spawn coder with custom prefix' },
521
- { command: 'monomind hive-mind spawn --claude -o "Build a REST API"', description: 'Launch Claude Code with objective' },
522
- { command: 'monomind hive-mind spawn -n 5 --claude -o "Research AI patterns"', description: 'Spawn workers and launch Claude Code' }
523
- ],
524
- action: async (ctx) => {
525
- // Parse count with fallback to default
526
- const rawCount = ctx.flags.count || 1;
527
- const count = Number.isFinite(rawCount) ? Math.max(1, Math.min(rawCount, 50)) : 1;
528
- const role = ctx.flags.role || 'worker';
529
- const agentType = ctx.flags.type || 'worker';
530
- const prefix = ctx.flags.prefix || 'hive-worker';
531
- const launchClaude = ctx.flags.claude;
532
- let objective = (ctx.flags.objective || ctx.args.join(' ')).slice(0, MAX_OBJECTIVE_LEN);
533
- output.printInfo(`Spawning ${count} ${role} agent(s)...`);
534
- try {
535
- const result = await callMCPTool('hive-mind_spawn', {
536
- count,
537
- role,
538
- agentType,
539
- prefix,
540
- });
541
- // Check for errors from MCP tool
542
- if (!result.success) {
543
- output.printError(result.error || 'Failed to spawn workers');
544
- return { success: false, exitCode: 1 };
545
- }
546
- if (ctx.flags.format === 'json' && !launchClaude) {
547
- output.printJson(result);
548
- return { success: true, data: result };
549
- }
550
- output.writeln();
551
- // Transform workers array to display format
552
- const displayData = (result.workers || []).map(w => ({
553
- id: w.agentId,
554
- role: w.role,
555
- status: 'idle',
556
- joinedAt: new Date(w.joinedAt).toLocaleTimeString()
557
- }));
558
- output.printTable({
559
- columns: [
560
- { key: 'id', header: 'Agent ID', width: 30 },
561
- { key: 'role', header: 'Role', width: 12 },
562
- { key: 'status', header: 'Status', width: 10, format: formatAgentStatus },
563
- { key: 'joinedAt', header: 'Joined', width: 12 }
564
- ],
565
- data: displayData
566
- });
567
- output.writeln();
568
- output.printSuccess(`Spawned ${result.spawned} agent(s)`);
569
- output.writeln(output.dim(` Total workers in hive: ${result.totalWorkers}`));
570
- // NEW: Handle --claude flag
571
- if (launchClaude) {
572
- // Get objective if not provided
573
- if (!objective && ctx.interactive) {
574
- objective = await input({
575
- message: 'Enter the objective for the hive mind:',
576
- validate: (v) => v.length > 0 || 'Objective is required when using --claude'
577
- });
578
- }
579
- if (!objective) {
580
- output.writeln();
581
- output.printWarning('No objective provided. Using default objective.');
582
- objective = 'Coordinate the hive mind workers to complete tasks efficiently.';
583
- }
584
- // Get hive status for swarm info
585
- let swarmId = result.hiveId || 'default';
586
- let swarmName = 'Hive Mind Swarm';
587
- try {
588
- const statusResult = await callMCPTool('hive-mind_status', { includeWorkers: false });
589
- swarmId = statusResult.hiveId || swarmId;
590
- }
591
- catch {
592
- // Use defaults if status call fails
593
- }
594
- // Convert workers to expected format
595
- const workers = (result.workers || []).map(w => ({
596
- agentId: w.agentId,
597
- role: w.role,
598
- type: agentType,
599
- joinedAt: w.joinedAt
600
- }));
601
- // Launch Claude Code with hive mind prompt
602
- const claudeResult = await spawnClaudeCodeInstance(swarmId, swarmName, objective, workers, ctx.flags);
603
- if (!claudeResult.success) {
604
- return { success: false, exitCode: 1, data: { spawn: result, claude: claudeResult } };
605
- }
606
- return { success: true, data: { spawn: result, claude: claudeResult } };
607
- }
608
- return { success: true, data: result };
609
- }
610
- catch (error) {
611
- if (error instanceof MCPClientError) {
612
- output.printError(`Spawn error: ${error.message}`);
613
- }
614
- else {
615
- output.printError(`Unexpected error: ${String(error)}`);
616
- }
617
- return { success: false, exitCode: 1 };
618
- }
619
- }
620
- };
621
- // Status subcommand
622
- const statusCommand = {
623
- name: 'status',
624
- description: 'Show hive mind status',
625
- options: [
626
- {
627
- name: 'detailed',
628
- short: 'd',
629
- description: 'Show detailed metrics',
630
- type: 'boolean',
631
- default: false
632
- },
633
- {
634
- name: 'watch',
635
- short: 'w',
636
- description: 'Watch for changes',
637
- type: 'boolean',
638
- default: false
639
- }
640
- ],
641
- action: async (ctx) => {
642
- const detailed = ctx.flags.detailed;
643
- try {
644
- const result = await callMCPTool('hive-mind_status', {
645
- includeMetrics: detailed,
646
- includeWorkers: true,
647
- });
648
- if (ctx.flags.format === 'json') {
649
- output.printJson(result);
650
- return { success: true, data: result };
651
- }
652
- // Handle both simple and complex response formats - cast to flexible type
653
- const flexResult = result;
654
- const hiveId = result.hiveId ?? flexResult.id ?? 'default';
655
- const status = result.status ?? (flexResult.initialized ? 'running' : 'stopped');
656
- const queen = result.queen ?? { id: 'N/A', status: 'unknown', load: 0, tasksQueued: 0 };
657
- const flexQueen = queen;
658
- const queenId = typeof queen === 'object' ? (queen.id ?? flexQueen.agentId ?? 'N/A') : String(queen);
659
- const queenLoad = typeof queen === 'object' ? (queen.load ?? 0) : 0;
660
- const queenTasks = typeof queen === 'object' ? (queen.tasksQueued ?? 0) : 0;
661
- const queenStatus = typeof queen === 'object' ? (queen.status ?? 'active') : 'active';
662
- output.writeln();
663
- output.printBox([
664
- `Hive ID: ${hiveId}`,
665
- `Status: ${formatHiveStatus(String(status))}`,
666
- `Topology: ${result.topology ?? 'mesh'}`,
667
- `Consensus: ${result.consensus ?? 'byzantine'}`,
668
- '',
669
- `Queen: ${queenId}`,
670
- ` Status: ${formatAgentStatus(queenStatus)}`,
671
- ` Load: ${(queenLoad * 100).toFixed(1)}%`,
672
- ` Queued Tasks: ${queenTasks}`
673
- ].join('\n'), 'Hive Mind Status');
674
- // Handle workers array - could be worker objects or just IDs
675
- const workers = result.workers ?? [];
676
- const workerData = Array.isArray(workers) ? workers.map(w => {
677
- if (typeof w === 'string') {
678
- return { id: w, type: 'worker', status: 'idle', currentTask: '-', tasksCompleted: 0 };
679
- }
680
- const flexWorker = w;
681
- return {
682
- id: w.id ?? flexWorker.agentId ?? 'unknown',
683
- type: w.type ?? flexWorker.agentType ?? 'worker',
684
- status: w.status ?? 'idle',
685
- currentTask: w.currentTask ?? '-',
686
- tasksCompleted: w.tasksCompleted ?? 0
687
- };
688
- }) : [];
689
- output.writeln();
690
- output.writeln(output.bold('Worker Agents'));
691
- if (workerData.length === 0) {
692
- output.printInfo('No workers in hive. Use "monomind hive-mind spawn" to add workers.');
693
- }
694
- else {
695
- output.printTable({
696
- columns: [
697
- { key: 'id', header: 'ID', width: 20 },
698
- { key: 'type', header: 'Type', width: 12 },
699
- { key: 'status', header: 'Status', width: 10, format: formatAgentStatus },
700
- { key: 'currentTask', header: 'Current Task', width: 20, format: (v) => String(v || '-') },
701
- { key: 'tasksCompleted', header: 'Completed', width: 10, align: 'right' }
702
- ],
703
- data: workerData
704
- });
705
- }
706
- if (detailed) {
707
- const metrics = result.metrics ?? { totalTasks: 0, completedTasks: 0, failedTasks: 0, avgTaskTime: 0, consensusRounds: 0, memoryUsage: '0 MB' };
708
- output.writeln();
709
- output.writeln(output.bold('Metrics'));
710
- output.printTable({
711
- columns: [
712
- { key: 'metric', header: 'Metric', width: 20 },
713
- { key: 'value', header: 'Value', width: 15, align: 'right' }
714
- ],
715
- data: [
716
- { metric: 'Total Tasks', value: metrics.totalTasks ?? 0 },
717
- { metric: 'Completed', value: metrics.completedTasks ?? 0 },
718
- { metric: 'Failed', value: metrics.failedTasks ?? 0 },
719
- { metric: 'Avg Task Time', value: `${(metrics.avgTaskTime ?? 0).toFixed(1)}ms` },
720
- { metric: 'Consensus Rounds', value: metrics.consensusRounds ?? 0 },
721
- { metric: 'Memory Usage', value: metrics.memoryUsage ?? '0 MB' }
722
- ]
723
- });
724
- const health = result.health ?? { overall: 'healthy', queen: 'healthy', workers: 'healthy', consensus: 'healthy', memory: 'healthy' };
725
- output.writeln();
726
- output.writeln(output.bold('Health'));
727
- output.printList([
728
- `Overall: ${formatHealth(health.overall ?? 'healthy')}`,
729
- `Queen: ${formatHealth(health.queen ?? 'healthy')}`,
730
- `Workers: ${formatHealth(health.workers ?? 'healthy')}`,
731
- `Consensus: ${formatHealth(health.consensus ?? 'healthy')}`,
732
- `Memory: ${formatHealth(health.memory ?? 'healthy')}`
733
- ]);
734
- }
735
- return { success: true, data: result };
736
- }
737
- catch (error) {
738
- if (error instanceof MCPClientError) {
739
- output.printError(`Status error: ${error.message}`);
740
- }
741
- else {
742
- output.printError(`Unexpected error: ${String(error)}`);
743
- }
744
- return { success: false, exitCode: 1 };
745
- }
746
- }
747
- };
748
- // Task subcommand
749
- const taskCommand = {
750
- name: 'task',
751
- description: 'Submit tasks to the hive',
752
- options: [
753
- {
754
- name: 'description',
755
- short: 'd',
756
- description: 'Task description',
757
- type: 'string'
758
- },
759
- {
760
- name: 'priority',
761
- short: 'p',
762
- description: 'Task priority',
763
- type: 'string',
764
- choices: ['low', 'normal', 'high', 'critical'],
765
- default: 'normal'
766
- },
767
- {
768
- name: 'require-consensus',
769
- short: 'c',
770
- description: 'Require consensus for completion',
771
- type: 'boolean',
772
- default: false
773
- },
774
- {
775
- name: 'timeout',
776
- description: 'Task timeout in seconds',
777
- type: 'number',
778
- default: 300
779
- }
780
- ],
781
- examples: [
782
- { command: 'monomind hive-mind task -d "Implement auth module"', description: 'Submit task' },
783
- { command: 'monomind hive-mind task -d "Security review" -p critical -c', description: 'Critical task with consensus' }
784
- ],
785
- action: async (ctx) => {
786
- let description = (ctx.flags.description || ctx.args.join(' ')).slice(0, MAX_TASK_DESC_LEN);
787
- if (!description && ctx.interactive) {
788
- description = await input({
789
- message: 'Task description:',
790
- validate: (v) => v.length > 0 || 'Description is required'
791
- });
792
- description = description.slice(0, MAX_TASK_DESC_LEN);
793
- }
794
- if (!description) {
795
- output.printError('Task description is required');
796
- return { success: false, exitCode: 1 };
797
- }
798
- const priority = ctx.flags.priority;
799
- const requireConsensus = ctx.flags['require-consensus'];
800
- const timeout = ctx.flags.timeout;
801
- output.printInfo('Submitting task to hive...');
802
- try {
803
- const result = await callMCPTool('hive-mind_task', {
804
- description,
805
- priority,
806
- requireConsensus,
807
- timeout,
808
- });
809
- if (ctx.flags.format === 'json') {
810
- output.printJson(result);
811
- return { success: true, data: result };
812
- }
813
- output.writeln();
814
- output.printBox([
815
- `Task ID: ${result.taskId}`,
816
- `Status: ${formatAgentStatus(result.status)}`,
817
- `Priority: ${formatPriority(priority)}`,
818
- `Assigned: ${result.assignedTo.join(', ')}`,
819
- `Consensus: ${result.requiresConsensus ? 'Yes' : 'No'}`,
820
- `Est. Time: ${result.estimatedTime}`
821
- ].join('\n'), 'Task Submitted');
822
- output.writeln();
823
- output.printSuccess('Task submitted to hive');
824
- output.writeln(output.dim(` Track with: monomind hive-mind task-status ${result.taskId}`));
825
- return { success: true, data: result };
826
- }
827
- catch (error) {
828
- if (error instanceof MCPClientError) {
829
- output.printError(`Task submission error: ${error.message}`);
830
- }
831
- else {
832
- output.printError(`Unexpected error: ${String(error)}`);
833
- }
834
- return { success: false, exitCode: 1 };
835
- }
836
- }
837
- };
838
- // Optimize memory subcommand
839
- const optimizeMemoryCommand = {
840
- name: 'optimize-memory',
841
- description: 'Optimize hive memory and patterns',
842
- options: [
843
- {
844
- name: 'aggressive',
845
- short: 'a',
846
- description: 'Aggressive optimization',
847
- type: 'boolean',
848
- default: false
849
- },
850
- {
851
- name: 'threshold',
852
- description: 'Quality threshold for pattern retention',
853
- type: 'number',
854
- default: 0.7
855
- }
856
- ],
857
- action: async (ctx) => {
858
- const aggressive = ctx.flags.aggressive;
859
- const threshold = ctx.flags.threshold;
860
- output.printInfo('Optimizing hive memory...');
861
- const spinner = output.createSpinner({ text: 'Analyzing patterns...', spinner: 'dots' });
862
- spinner.start();
863
- try {
864
- const result = await callMCPTool('hive-mind_optimize-memory', {
865
- aggressive,
866
- qualityThreshold: threshold,
867
- });
868
- spinner.succeed('Memory optimized');
869
- if (ctx.flags.format === 'json') {
870
- output.printJson(result);
871
- return { success: true, data: result };
872
- }
873
- output.writeln();
874
- output.printTable({
875
- columns: [
876
- { key: 'metric', header: 'Metric', width: 20 },
877
- { key: 'before', header: 'Before', width: 15, align: 'right' },
878
- { key: 'after', header: 'After', width: 15, align: 'right' }
879
- ],
880
- data: [
881
- { metric: 'Patterns', before: result.before.patterns, after: result.after.patterns },
882
- { metric: 'Memory', before: result.before.memory, after: result.after.memory }
883
- ]
884
- });
885
- output.writeln();
886
- output.printList([
887
- `Patterns removed: ${result.removed}`,
888
- `Patterns consolidated: ${result.consolidated}`,
889
- `Optimization time: ${result.timeMs}ms`
890
- ]);
891
- return { success: true, data: result };
892
- }
893
- catch (error) {
894
- spinner.fail('Optimization failed');
895
- if (error instanceof MCPClientError) {
896
- output.printError(`Optimization error: ${error.message}`);
897
- }
898
- else {
899
- output.printError(`Unexpected error: ${String(error)}`);
900
- }
901
- return { success: false, exitCode: 1 };
902
- }
903
- }
904
- };
905
- // Join subcommand
906
- const joinCommand = {
907
- name: 'join',
908
- description: 'Join an agent to the hive mind',
909
- options: [
910
- { name: 'agent-id', short: 'a', description: 'Agent ID to join', type: 'string' },
911
- { name: 'role', short: 'r', description: 'Agent role (worker, specialist, scout)', type: 'string', default: 'worker' }
912
- ],
913
- action: async (ctx) => {
914
- const agentId = (ctx.args[0] || ctx.flags['agent-id'] || ctx.flags.agentId || '').slice(0, MAX_AGENT_ID_LEN);
915
- if (!agentId) {
916
- output.printError('Agent ID is required. Use --agent-id or -a flag, or provide as argument.');
917
- return { success: false, exitCode: 1 };
918
- }
919
- try {
920
- const result = await callMCPTool('hive-mind_join', { agentId, role: ctx.flags.role });
921
- if (!result.success) {
922
- output.printError(result.error || 'Failed');
923
- return { success: false, exitCode: 1 };
924
- }
925
- output.printSuccess(`Agent ${agentId} joined hive (${result.totalWorkers} workers)`);
926
- return { success: true, data: result };
927
- }
928
- catch (error) {
929
- output.printError(`Join error: ${error instanceof MCPClientError ? error.message : String(error)}`);
930
- return { success: false, exitCode: 1 };
931
- }
932
- }
933
- };
934
- // Leave subcommand
935
- const leaveCommand = {
936
- name: 'leave',
937
- description: 'Remove an agent from the hive mind',
938
- options: [{ name: 'agent-id', short: 'a', description: 'Agent ID to remove', type: 'string' }],
939
- action: async (ctx) => {
940
- const agentId = (ctx.args[0] || ctx.flags['agent-id'] || ctx.flags.agentId || '').slice(0, MAX_AGENT_ID_LEN);
941
- if (!agentId) {
942
- output.printError('Agent ID required.');
943
- return { success: false, exitCode: 1 };
944
- }
945
- try {
946
- const result = await callMCPTool('hive-mind_leave', { agentId });
947
- if (!result.success) {
948
- output.printError(result.error || 'Failed');
949
- return { success: false, exitCode: 1 };
950
- }
951
- output.printSuccess(`Agent ${agentId} left hive (${result.remainingWorkers} remaining)`);
952
- return { success: true, data: result };
953
- }
954
- catch (error) {
955
- output.printError(`Leave error: ${error instanceof MCPClientError ? error.message : String(error)}`);
956
- return { success: false, exitCode: 1 };
957
- }
958
- }
959
- };
960
- // Consensus subcommand
961
- const consensusCommand = {
962
- name: 'consensus',
963
- description: 'Manage consensus proposals and voting',
964
- options: [
965
- { name: 'action', short: 'a', description: 'Consensus action', type: 'string', choices: ['propose', 'vote', 'status', 'list'], default: 'list' },
966
- { name: 'proposal-id', short: 'p', description: 'Proposal ID', type: 'string' },
967
- { name: 'type', short: 't', description: 'Proposal type', type: 'string' },
968
- { name: 'value', description: 'Proposal value', type: 'string' },
969
- { name: 'vote', short: 'v', description: 'Vote (yes/no)', type: 'string' },
970
- { name: 'voter-id', description: 'Voter agent ID', type: 'string' }
971
- ],
972
- action: async (ctx) => {
973
- const action = ctx.flags.action || 'list';
974
- try {
975
- const result = await callMCPTool('hive-mind_consensus', { action, proposalId: ctx.flags['proposal-id'], type: ctx.flags.type, value: ctx.flags.value, vote: ctx.flags.vote === 'yes', voterId: ctx.flags['voter-id'] });
976
- if (ctx.flags.format === 'json') {
977
- output.printJson(result);
978
- return { success: true, data: result };
979
- }
980
- if (action === 'list') {
981
- output.writeln(output.bold('\nPending Proposals'));
982
- const pending = result.pending || [];
983
- if (pending.length === 0)
984
- output.printInfo('No pending proposals');
985
- else
986
- output.printTable({ columns: [{ key: 'proposalId', header: 'ID', width: 30 }, { key: 'type', header: 'Type', width: 12 }], data: pending });
987
- }
988
- else if (action === 'propose') {
989
- output.printSuccess(`Proposal created: ${result.proposalId}`);
990
- }
991
- else if (action === 'vote') {
992
- output.printSuccess(`Vote recorded (For: ${result.votesFor}, Against: ${result.votesAgainst})`);
993
- }
994
- return { success: true, data: result };
995
- }
996
- catch (error) {
997
- output.printError(`Consensus error: ${error instanceof MCPClientError ? error.message : String(error)}`);
998
- return { success: false, exitCode: 1 };
999
- }
1000
- }
1001
- };
1002
- // Broadcast subcommand
1003
- const broadcastCommand = {
1004
- name: 'broadcast',
1005
- description: 'Broadcast a message to all workers in the hive',
1006
- options: [
1007
- { name: 'message', short: 'm', description: 'Message to broadcast', type: 'string', required: true },
1008
- { name: 'priority', short: 'p', description: 'Message priority', type: 'string', choices: ['low', 'normal', 'high', 'critical'], default: 'normal' },
1009
- { name: 'from', short: 'f', description: 'Sender agent ID', type: 'string' }
1010
- ],
1011
- action: async (ctx) => {
1012
- const message = (ctx.args.join(' ') || ctx.flags.message || '').slice(0, MAX_MESSAGE_LEN);
1013
- if (!message) {
1014
- output.printError('Message required. Use --message or -m flag.');
1015
- return { success: false, exitCode: 1 };
1016
- }
1017
- try {
1018
- const result = await callMCPTool('hive-mind_broadcast', { message, priority: ctx.flags.priority, fromId: typeof ctx.flags.from === 'string' ? ctx.flags.from.slice(0, MAX_AGENT_ID_LEN) : undefined });
1019
- if (!result.success) {
1020
- output.printError(result.error || 'Failed');
1021
- return { success: false, exitCode: 1 };
1022
- }
1023
- output.printSuccess(`Message broadcast to ${result.recipients} workers (ID: ${result.messageId})`);
1024
- return { success: true, data: result };
1025
- }
1026
- catch (error) {
1027
- output.printError(`Broadcast error: ${error instanceof MCPClientError ? error.message : String(error)}`);
1028
- return { success: false, exitCode: 1 };
1029
- }
1030
- }
1031
- };
1032
- // Memory subcommand
1033
- const memorySubCommand = {
1034
- name: 'memory',
1035
- description: 'Access hive shared memory',
1036
- options: [
1037
- { name: 'action', short: 'a', description: 'Memory action', type: 'string', choices: ['get', 'set', 'delete', 'list'], default: 'list' },
1038
- { name: 'key', short: 'k', description: 'Memory key', type: 'string' },
1039
- { name: 'value', short: 'v', description: 'Value to store', type: 'string' }
1040
- ],
1041
- action: async (ctx) => {
1042
- const action = ctx.flags.action || 'list';
1043
- const key = typeof ctx.flags.key === 'string' ? ctx.flags.key.slice(0, MAX_KEY_LEN) : undefined;
1044
- const value = typeof ctx.flags.value === 'string' ? ctx.flags.value.slice(0, MAX_VALUE_LEN) : undefined;
1045
- if ((action === 'get' || action === 'delete') && !key) {
1046
- output.printError('Key required for get/delete.');
1047
- return { success: false, exitCode: 1 };
1048
- }
1049
- if (action === 'set' && (!key || value === undefined)) {
1050
- output.printError('Key and value required for set.');
1051
- return { success: false, exitCode: 1 };
1052
- }
1053
- try {
1054
- const result = await callMCPTool('hive-mind_memory', { action, key, value });
1055
- if (ctx.flags.format === 'json') {
1056
- output.printJson(result);
1057
- return { success: true, data: result };
1058
- }
1059
- if (action === 'list') {
1060
- const keys = result.keys || [];
1061
- output.writeln(output.bold(`\nShared Memory (${result.count} keys)`));
1062
- if (keys.length === 0)
1063
- output.printInfo('No keys in shared memory');
1064
- else
1065
- output.printList(keys.map(k => output.highlight(k)));
1066
- }
1067
- else if (action === 'get') {
1068
- output.writeln(output.bold(`\nKey: ${key}`));
1069
- output.writeln(result.exists ? `Value: ${JSON.stringify(result.value, null, 2)}` : 'Key not found');
1070
- }
1071
- else if (action === 'set') {
1072
- output.printSuccess(`Set ${key} in shared memory`);
1073
- }
1074
- else if (action === 'delete') {
1075
- output.printSuccess(result.deleted ? `Deleted ${key}` : `Key ${key} did not exist`);
1076
- }
1077
- return { success: true, data: result };
1078
- }
1079
- catch (error) {
1080
- output.printError(`Memory error: ${error instanceof MCPClientError ? error.message : String(error)}`);
1081
- return { success: false, exitCode: 1 };
1082
- }
1083
- }
1084
- };
1085
- // Shutdown subcommand
1086
- const shutdownCommand = {
1087
- name: 'shutdown',
1088
- description: 'Shutdown the hive mind',
1089
- options: [
1090
- {
1091
- name: 'force',
1092
- short: 'f',
1093
- description: 'Force shutdown',
1094
- type: 'boolean',
1095
- default: false
1096
- },
1097
- {
1098
- name: 'save-state',
1099
- short: 's',
1100
- description: 'Save state before shutdown',
1101
- type: 'boolean',
1102
- default: true
1103
- }
1104
- ],
1105
- action: async (ctx) => {
1106
- const force = ctx.flags.force;
1107
- const saveState = ctx.flags['save-state'];
1108
- if (!force && ctx.interactive) {
1109
- const confirmed = await confirm({
1110
- message: 'Shutdown the hive mind? All agents will be terminated.',
1111
- default: false
1112
- });
1113
- if (!confirmed) {
1114
- output.printInfo('Operation cancelled');
1115
- return { success: true };
1116
- }
1117
- }
1118
- output.printInfo('Shutting down hive mind...');
1119
- const spinner = output.createSpinner({ text: 'Graceful shutdown in progress...', spinner: 'dots' });
1120
- spinner.start();
1121
- try {
1122
- const result = await callMCPTool('hive-mind_shutdown', {
1123
- force,
1124
- saveState,
1125
- });
1126
- spinner.succeed('Hive mind shutdown complete');
1127
- output.writeln();
1128
- output.printList([
1129
- `Agents terminated: ${result.agentsTerminated}`,
1130
- `State saved: ${result.stateSaved ? 'Yes' : 'No'}`,
1131
- `Shutdown time: ${result.shutdownTime}`
1132
- ]);
1133
- return { success: true, data: result };
1134
- }
1135
- catch (error) {
1136
- spinner.fail('Shutdown failed');
1137
- if (error instanceof MCPClientError) {
1138
- output.printError(`Shutdown error: ${error.message}`);
1139
- }
1140
- else {
1141
- output.printError(`Unexpected error: ${String(error)}`);
1142
- }
1143
- return { success: false, exitCode: 1 };
1144
- }
1145
- }
1146
- };
1147
- // Main hive-mind command
1148
92
  export const hiveMindCommand = {
1149
93
  name: 'hive-mind',
1150
94
  aliases: ['hive'],
@@ -1194,68 +138,5 @@ export const hiveMindCommand = {
1194
138
  return { success: true };
1195
139
  }
1196
140
  };
1197
- // Helper functions
1198
- function formatAgentStatus(status) {
1199
- const statusStr = String(status);
1200
- switch (statusStr) {
1201
- case 'active':
1202
- case 'ready':
1203
- case 'running':
1204
- return output.success(statusStr);
1205
- case 'idle':
1206
- case 'waiting':
1207
- return output.dim(statusStr);
1208
- case 'busy':
1209
- return output.highlight(statusStr);
1210
- case 'error':
1211
- case 'failed':
1212
- return output.error(statusStr);
1213
- default:
1214
- return statusStr;
1215
- }
1216
- }
1217
- function formatHiveStatus(status) {
1218
- switch (status) {
1219
- case 'active':
1220
- return output.success(status);
1221
- case 'idle':
1222
- return output.dim(status);
1223
- case 'degraded':
1224
- return output.warning(status);
1225
- case 'offline':
1226
- return output.error(status);
1227
- default:
1228
- return status;
1229
- }
1230
- }
1231
- function formatHealth(health) {
1232
- switch (health) {
1233
- case 'healthy':
1234
- case 'good':
1235
- return output.success(health);
1236
- case 'warning':
1237
- case 'degraded':
1238
- return output.warning(health);
1239
- case 'critical':
1240
- case 'unhealthy':
1241
- return output.error(health);
1242
- default:
1243
- return health;
1244
- }
1245
- }
1246
- function formatPriority(priority) {
1247
- switch (priority) {
1248
- case 'critical':
1249
- return output.error(priority.toUpperCase());
1250
- case 'high':
1251
- return output.warning(priority);
1252
- case 'normal':
1253
- return priority;
1254
- case 'low':
1255
- return output.dim(priority);
1256
- default:
1257
- return priority;
1258
- }
1259
- }
1260
141
  export default hiveMindCommand;
1261
142
  //# sourceMappingURL=hive-mind.js.map