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
@@ -3,11 +3,13 @@
3
3
  * Comprehensive initialization for Monomind with Claude Code integration
4
4
  */
5
5
  import { output } from '../output.js';
6
- import { confirm, select, multiSelect, input } from '../prompt.js';
6
+ import { confirm } from '../prompt.js';
7
7
  import * as fs from 'fs';
8
8
  import * as path from 'path';
9
- import { executeInit, executeUpgrade, executeUpgradeWithMissing, findMonomindProjects, DEFAULT_INIT_OPTIONS, MINIMAL_INIT_OPTIONS, FULL_INIT_OPTIONS, } from '../init/index.js';
10
- // Check if project is already initialized
9
+ import { executeInit, DEFAULT_INIT_OPTIONS, MINIMAL_INIT_OPTIONS, FULL_INIT_OPTIONS, } from '../init/index.js';
10
+ import { wizardCommand } from './init-wizard.js';
11
+ import { upgradeCommand } from './init-upgrade.js';
12
+ import { checkCommand, skillsCommand, hooksCommand } from './init-subcommands.js';
11
13
  function isInitialized(cwd) {
12
14
  const claudePath = path.join(cwd, '.claude', 'settings.json');
13
15
  const monomindPath = path.join(cwd, '.monomind', 'config.yaml');
@@ -16,7 +18,6 @@ function isInitialized(cwd) {
16
18
  monomind: fs.existsSync(monomindPath),
17
19
  };
18
20
  }
19
- // Init subcommand (default)
20
21
  const initAction = async (ctx) => {
21
22
  const force = ctx.flags.force;
22
23
  const minimal = ctx.flags.minimal;
@@ -24,7 +25,6 @@ const initAction = async (ctx) => {
24
25
  const skipClaude = ctx.flags['skip-claude'];
25
26
  const onlyClaude = ctx.flags['only-claude'];
26
27
  const cwd = ctx.cwd;
27
- // Check if already initialized
28
28
  const initialized = isInitialized(cwd);
29
29
  const hasExisting = initialized.claude || initialized.monomind;
30
30
  if (hasExisting && !force) {
@@ -51,7 +51,6 @@ const initAction = async (ctx) => {
51
51
  output.writeln();
52
52
  output.writeln(output.bold('Initializing Monomind'));
53
53
  output.writeln();
54
- // Build init options based on flags
55
54
  let options;
56
55
  if (minimal) {
57
56
  options = { ...MINIMAL_INIT_OPTIONS, targetDir: cwd, force };
@@ -62,7 +61,6 @@ const initAction = async (ctx) => {
62
61
  else {
63
62
  options = { ...DEFAULT_INIT_OPTIONS, targetDir: cwd, force };
64
63
  }
65
- // Handle --skip-claude and --only-claude flags
66
64
  if (skipClaude) {
67
65
  options.components.settings = false;
68
66
  options.components.skills = false;
@@ -76,11 +74,9 @@ const initAction = async (ctx) => {
76
74
  if (onlyClaude) {
77
75
  options.components.runtime = false;
78
76
  }
79
- // Create spinner
80
77
  const spinner = output.createSpinner({ text: 'Initializing...' });
81
78
  spinner.start();
82
79
  try {
83
- // Execute initialization
84
80
  const result = await executeInit(options);
85
81
  if (!result.success) {
86
82
  spinner.fail('Initialization failed');
@@ -132,7 +128,6 @@ const initAction = async (ctx) => {
132
128
  }
133
129
  }
134
130
  output.writeln();
135
- // Display summary
136
131
  const summary = [];
137
132
  if (result.created.directories.length > 0) {
138
133
  summary.push(`Directories: ${result.created.directories.length} created`);
@@ -145,7 +140,6 @@ const initAction = async (ctx) => {
145
140
  }
146
141
  output.printBox(summary.join('\n'), 'Summary');
147
142
  output.writeln();
148
- // Show what was created
149
143
  if (options.components.claudeMd || options.components.settings || options.components.skills || options.components.commands || options.components.agents) {
150
144
  output.printBox([
151
145
  options.components.claudeMd ? `CLAUDE.md: Swarm guidance & configuration` : '',
@@ -167,19 +161,16 @@ const initAction = async (ctx) => {
167
161
  ].join('\n'), 'v1 Runtime');
168
162
  output.writeln();
169
163
  }
170
- // Hooks summary
171
164
  if (result.summary.hooksEnabled > 0) {
172
165
  output.printInfo(`Hooks: ${result.summary.hooksEnabled} hook types enabled in settings.json`);
173
166
  output.writeln();
174
167
  }
175
- // Handle --start-all or --start-daemon
176
168
  const startAll = ctx.flags['start-all'] || ctx.flags.startAll;
177
169
  const startDaemon = ctx.flags['start-daemon'] || ctx.flags.startDaemon || startAll;
178
170
  if (startDaemon || startAll) {
179
171
  output.writeln();
180
172
  output.printInfo('Starting services...');
181
173
  const { execSync, spawn: spawnChild } = await import('child_process');
182
- // Initialize memory database
183
174
  if (startAll) {
184
175
  try {
185
176
  output.writeln(output.dim(' Initializing memory database...'));
@@ -194,7 +185,6 @@ const initAction = async (ctx) => {
194
185
  output.writeln(output.dim(' Memory database already exists'));
195
186
  }
196
187
  }
197
- // Start daemon
198
188
  if (startDaemon) {
199
189
  try {
200
190
  output.writeln(output.dim(' Starting daemon...'));
@@ -206,7 +196,6 @@ const initAction = async (ctx) => {
206
196
  output.writeln(output.warning(' Daemon may already be running'));
207
197
  }
208
198
  }
209
- // Initialize swarm
210
199
  if (startAll) {
211
200
  try {
212
201
  output.writeln(output.dim(' Initializing swarm...'));
@@ -224,7 +213,6 @@ const initAction = async (ctx) => {
224
213
  output.writeln();
225
214
  output.printSuccess('All services started');
226
215
  }
227
- // Handle --with-embeddings
228
216
  const withEmbeddings = ctx.flags['with-embeddings'] || ctx.flags.withEmbeddings;
229
217
  const embeddingModel = (ctx.flags['embedding-model'] || ctx.flags.embeddingModel || 'Xenova/all-MiniLM-L6-v2');
230
218
  if (withEmbeddings) {
@@ -247,12 +235,11 @@ const initAction = async (ctx) => {
247
235
  output.writeln(output.success(' ✓ Embeddings initialized'));
248
236
  output.writeln(output.dim(' Run "embeddings init --download" to download model'));
249
237
  }
250
- catch (err) {
238
+ catch {
251
239
  output.writeln(output.warning(' Embedding initialization skipped (run manually)'));
252
240
  }
253
241
  }
254
242
  if (!startDaemon && !startAll) {
255
- // Next steps (only if not auto-starting)
256
243
  output.writeln(output.bold('Next steps:'));
257
244
  output.printList([
258
245
  `Run ${output.highlight('monomind daemon start')} to start background workers`,
@@ -262,7 +249,6 @@ const initAction = async (ctx) => {
262
249
  options.components.settings ? `Review ${output.highlight('.claude/settings.json')} for hook configurations` : '',
263
250
  ].filter(Boolean));
264
251
  }
265
- // Recommend semantic enrichment — prominent callout, not buried tip
266
252
  output.writeln('');
267
253
  output.writeln(output.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
268
254
  output.writeln(output.bold(' Run /mastermind:understand next'));
@@ -285,609 +271,6 @@ const initAction = async (ctx) => {
285
271
  return { success: false, exitCode: 1 };
286
272
  }
287
273
  };
288
- // Wizard subcommand for interactive setup
289
- const wizardCommand = {
290
- name: 'wizard',
291
- description: 'Interactive setup wizard for comprehensive configuration',
292
- action: async (ctx) => {
293
- output.writeln();
294
- output.writeln(output.bold('Monomind Setup Wizard'));
295
- output.writeln(output.dim('Answer questions to configure your project'));
296
- output.writeln();
297
- try {
298
- // Start with base options
299
- const options = { ...DEFAULT_INIT_OPTIONS, targetDir: ctx.cwd };
300
- // Configuration preset
301
- const preset = await select({
302
- message: 'Select configuration preset:',
303
- options: [
304
- { value: 'default', label: 'Default', hint: 'Recommended settings for most projects' },
305
- { value: 'minimal', label: 'Minimal', hint: 'Core features only' },
306
- { value: 'full', label: 'Full', hint: 'All features enabled' },
307
- { value: 'custom', label: 'Custom', hint: 'Choose each component' },
308
- ],
309
- });
310
- if (preset === 'minimal') {
311
- Object.assign(options, MINIMAL_INIT_OPTIONS);
312
- options.targetDir = ctx.cwd;
313
- }
314
- else if (preset === 'full') {
315
- Object.assign(options, FULL_INIT_OPTIONS);
316
- options.targetDir = ctx.cwd;
317
- }
318
- else if (preset === 'custom') {
319
- // Component selection
320
- const components = await multiSelect({
321
- message: 'Select components to initialize:',
322
- options: [
323
- { value: 'claudeMd', label: 'CLAUDE.md', hint: 'Swarm guidance and project configuration', selected: true },
324
- { value: 'settings', label: 'settings.json', hint: 'Claude Code hooks configuration', selected: true },
325
- { value: 'skills', label: 'Skills', hint: 'Claude Code skills in .claude/skills/', selected: true },
326
- { value: 'commands', label: 'Commands', hint: 'Claude Code commands in .claude/commands/', selected: true },
327
- { value: 'agents', label: 'Agents', hint: 'Agent definitions in .claude/agents/', selected: true },
328
- { value: 'helpers', label: 'Helpers', hint: 'Utility scripts in .claude/helpers/', selected: true },
329
- { value: 'statusline', label: 'Statusline', hint: 'Shell statusline integration', selected: false },
330
- { value: 'mcp', label: 'MCP', hint: '.mcp.json for MCP server configuration', selected: true },
331
- { value: 'runtime', label: 'Runtime', hint: '.monomind/ directory for v1 runtime', selected: true },
332
- ],
333
- });
334
- options.components.claudeMd = components.includes('claudeMd');
335
- options.components.settings = components.includes('settings');
336
- options.components.skills = components.includes('skills');
337
- options.components.commands = components.includes('commands');
338
- options.components.agents = components.includes('agents');
339
- options.components.helpers = components.includes('helpers');
340
- options.components.statusline = components.includes('statusline');
341
- options.components.mcp = components.includes('mcp');
342
- options.components.runtime = components.includes('runtime');
343
- // Skills selection
344
- if (options.components.skills) {
345
- const skillSets = await multiSelect({
346
- message: 'Select skill sets:',
347
- options: [
348
- { value: 'core', label: 'Core', hint: 'Swarm, memory, SPARC skills', selected: true },
349
- { value: 'memory', label: 'Memory (LanceDB)', hint: 'Vector database skills', selected: true },
350
- { value: 'github', label: 'GitHub', hint: 'GitHub integration skills', selected: true },
351
- ],
352
- });
353
- options.skills.core = skillSets.includes('core');
354
- options.skills.memory = skillSets.includes('memory');
355
- options.skills.github = skillSets.includes('github');
356
- }
357
- // Hooks selection
358
- if (options.components.settings) {
359
- const hooks = await multiSelect({
360
- message: 'Select hooks to enable:',
361
- options: [
362
- { value: 'preToolUse', label: 'PreToolUse', hint: 'Before tool execution', selected: true },
363
- { value: 'postToolUse', label: 'PostToolUse', hint: 'After tool execution', selected: true },
364
- { value: 'userPromptSubmit', label: 'UserPromptSubmit', hint: 'Task routing', selected: true },
365
- { value: 'sessionStart', label: 'SessionStart', hint: 'Session initialization', selected: true },
366
- { value: 'stop', label: 'Stop', hint: 'Task completion evaluation', selected: true },
367
- { value: 'notification', label: 'Notification', hint: 'Swarm notifications', selected: true },
368
- { value: 'permissionRequest', label: 'PermissionRequest', hint: 'Auto-allow monomind tools', selected: true },
369
- ],
370
- });
371
- options.hooks.preToolUse = hooks.includes('preToolUse');
372
- options.hooks.postToolUse = hooks.includes('postToolUse');
373
- options.hooks.userPromptSubmit = hooks.includes('userPromptSubmit');
374
- options.hooks.sessionStart = hooks.includes('sessionStart');
375
- options.hooks.stop = hooks.includes('stop');
376
- options.hooks.notification = hooks.includes('notification');
377
- }
378
- }
379
- // Swarm topology (for all presets)
380
- const topology = await select({
381
- message: 'Select swarm topology:',
382
- options: [
383
- { value: 'hierarchical-mesh', label: 'Hierarchical Mesh', hint: 'Best for complex projects (recommended)' },
384
- { value: 'mesh', label: 'Mesh', hint: 'Peer-to-peer coordination' },
385
- { value: 'hierarchical', label: 'Hierarchical', hint: 'Tree-based coordination' },
386
- { value: 'adaptive', label: 'Adaptive', hint: 'Dynamic topology switching' },
387
- ],
388
- });
389
- options.runtime.topology = topology;
390
- // Max agents
391
- const maxAgents = await input({
392
- message: 'Maximum concurrent agents:',
393
- default: String(options.runtime.maxAgents),
394
- validate: (v) => {
395
- const n = parseInt(v);
396
- return (!isNaN(n) && n > 0 && n <= 50) || 'Enter a number between 1 and 50';
397
- },
398
- });
399
- options.runtime.maxAgents = parseInt(maxAgents);
400
- // Memory backend
401
- const memoryBackend = await select({
402
- message: 'Select memory backend:',
403
- options: [
404
- { value: 'hybrid', label: 'Hybrid', hint: 'SQLite + LanceDB (recommended)' },
405
- { value: 'lancedb', label: 'LanceDB', hint: '150x faster vector search' },
406
- { value: 'sqlite', label: 'SQLite', hint: 'Standard SQL storage' },
407
- { value: 'memory', label: 'In-Memory', hint: 'Fast but non-persistent' },
408
- ],
409
- });
410
- options.runtime.memoryBackend = memoryBackend;
411
- // HNSW indexing
412
- if (memoryBackend === 'lancedb' || memoryBackend === 'hybrid') {
413
- const enableHNSW = await confirm({
414
- message: 'Enable HNSW indexing for faster vector search?',
415
- default: true,
416
- });
417
- options.runtime.enableHNSW = enableHNSW;
418
- }
419
- // Neural learning
420
- const enableNeural = await confirm({
421
- message: 'Enable neural pattern learning?',
422
- default: options.runtime.enableNeural,
423
- });
424
- options.runtime.enableNeural = enableNeural;
425
- // ADR-049: Self-Learning Memory capabilities
426
- if (memoryBackend === 'lancedb' || memoryBackend === 'hybrid') {
427
- const enableSelfLearning = await confirm({
428
- message: 'Enable self-learning memory? (LearningBridge + Knowledge Graph + Agent Scopes)',
429
- default: true,
430
- });
431
- options.runtime.enableLearningBridge = enableSelfLearning && enableNeural;
432
- options.runtime.enableMemoryGraph = enableSelfLearning;
433
- options.runtime.enableAgentScopes = enableSelfLearning;
434
- }
435
- else {
436
- options.runtime.enableLearningBridge = false;
437
- options.runtime.enableMemoryGraph = false;
438
- options.runtime.enableAgentScopes = false;
439
- }
440
- // Embeddings configuration
441
- const enableEmbeddings = await confirm({
442
- message: 'Enable ONNX embedding system with hyperbolic support?',
443
- default: true,
444
- });
445
- let embeddingModel = 'Xenova/all-MiniLM-L6-v2';
446
- if (enableEmbeddings) {
447
- embeddingModel = await select({
448
- message: 'Select embedding model:',
449
- options: [
450
- { value: 'Xenova/all-MiniLM-L6-v2', label: 'MiniLM L6 (384d)', hint: 'Fast, good quality (recommended)' },
451
- { value: 'Xenova/all-mpnet-base-v2', label: 'MPNet Base (768d)', hint: 'Higher quality, more memory' },
452
- ],
453
- });
454
- }
455
- // Execute initialization
456
- output.writeln();
457
- const spinner = output.createSpinner({ text: 'Initializing...' });
458
- spinner.start();
459
- const result = await executeInit(options);
460
- if (!result.success) {
461
- spinner.fail('Initialization failed');
462
- for (const error of result.errors) {
463
- output.printError(error);
464
- }
465
- return { success: false, exitCode: 1 };
466
- }
467
- spinner.succeed('Setup complete!');
468
- // Initialize embeddings if enabled
469
- let embeddingsInitialized = false;
470
- if (enableEmbeddings) {
471
- output.writeln();
472
- output.printInfo('Initializing ONNX embedding subsystem...');
473
- const ALLOWED_MODELS = /^[\w\-./]+$/;
474
- if (!ALLOWED_MODELS.test(embeddingModel)) {
475
- output.writeln(output.error('Invalid model identifier. Only alphanumeric characters, hyphens, dots, and slashes are allowed.'));
476
- return { success: false, exitCode: 1 };
477
- }
478
- const { execFileSync } = await import('child_process');
479
- try {
480
- execFileSync(process.platform === 'win32' ? 'npx.cmd' : 'npx', ['@monomind/cli@latest', 'embeddings', 'init', '--model', embeddingModel, '--no-download', '--force'], {
481
- stdio: 'pipe',
482
- cwd: ctx.cwd,
483
- timeout: 30000
484
- });
485
- output.writeln(output.success(' ✓ Embeddings configured'));
486
- embeddingsInitialized = true;
487
- }
488
- catch {
489
- output.writeln(output.dim(' Embeddings will be configured on first use'));
490
- }
491
- }
492
- // Enforcement gates opt-in
493
- const enableGates = await confirm({
494
- message: 'Enable enforcement gates? (blocks destructive commands + secrets in writes)',
495
- default: true,
496
- });
497
- let gatesEnabled = false;
498
- if (enableGates) {
499
- try {
500
- const { execFileSync } = await import('child_process');
501
- execFileSync(process.platform === 'win32' ? 'npx.cmd' : 'npx', ['@monomind/cli@latest', 'guidance', 'setup', '--project-dir', ctx.cwd], { stdio: 'pipe', cwd: ctx.cwd, timeout: 10000 });
502
- gatesEnabled = true;
503
- output.writeln(output.success(' ✓ Enforcement gates wired'));
504
- }
505
- catch {
506
- output.writeln(output.dim(' Gates setup skipped (run `monomind guidance setup` manually)'));
507
- }
508
- }
509
- output.writeln();
510
- // Summary table
511
- output.printTable({
512
- columns: [
513
- { key: 'setting', header: 'Setting', width: 20 },
514
- { key: 'value', header: 'Value', width: 40 },
515
- ],
516
- data: [
517
- { setting: 'Preset', value: preset },
518
- { setting: 'Topology', value: options.runtime.topology },
519
- { setting: 'Max Agents', value: String(options.runtime.maxAgents) },
520
- { setting: 'Memory Backend', value: options.runtime.memoryBackend },
521
- { setting: 'HNSW Indexing', value: options.runtime.enableHNSW ? 'Enabled' : 'Disabled' },
522
- { setting: 'Neural Learning', value: options.runtime.enableNeural ? 'Enabled' : 'Disabled' },
523
- { setting: 'Self-Learning', value: options.runtime.enableLearningBridge ? 'LearningBridge + Graph + Scopes' : 'Disabled' },
524
- { setting: 'Embeddings', value: enableEmbeddings ? `${embeddingModel} (hyperbolic)` : 'Disabled' },
525
- { setting: 'Skills', value: `${result.summary.skillsCount} installed` },
526
- { setting: 'Commands', value: `${result.summary.commandsCount} installed` },
527
- { setting: 'Agents', value: `${result.summary.agentsCount} installed` },
528
- { setting: 'Hooks', value: `${result.summary.hooksEnabled} enabled` },
529
- { setting: 'Enforcement Gates', value: gatesEnabled ? 'Enabled' : 'Disabled' },
530
- ],
531
- });
532
- return { success: true, data: result };
533
- }
534
- catch (error) {
535
- if (error instanceof Error && error.message === 'User cancelled') {
536
- output.printInfo('Setup cancelled');
537
- return { success: true };
538
- }
539
- throw error;
540
- }
541
- },
542
- };
543
- // Check subcommand
544
- const checkCommand = {
545
- name: 'check',
546
- description: 'Check if MonoMind is initialized',
547
- action: async (ctx) => {
548
- const initialized = isInitialized(ctx.cwd);
549
- const result = {
550
- initialized: initialized.claude || initialized.monomind,
551
- claude: initialized.claude,
552
- monomind: initialized.monomind,
553
- paths: {
554
- claudeSettings: initialized.claude ? path.join(ctx.cwd, '.claude', 'settings.json') : null,
555
- monomindConfig: initialized.monomind ? path.join(ctx.cwd, '.monomind', 'config.yaml') : null,
556
- },
557
- };
558
- if (ctx.flags.format === 'json') {
559
- output.printJson(result);
560
- return { success: true, data: result };
561
- }
562
- if (result.initialized) {
563
- output.printSuccess('MonoMind is initialized');
564
- if (initialized.claude) {
565
- output.printInfo(` Claude Code: .claude/settings.json`);
566
- }
567
- if (initialized.monomind) {
568
- output.printInfo(` Runtime: .monomind/config.yaml`);
569
- }
570
- }
571
- else {
572
- output.printWarning('MonoMind is not initialized in this directory');
573
- output.printInfo('Run "monomind init" to initialize');
574
- }
575
- return { success: true, data: result };
576
- },
577
- };
578
- // Skills subcommand
579
- const skillsCommand = {
580
- name: 'skills',
581
- description: 'Initialize only skills',
582
- options: [
583
- { name: 'all', description: 'Install all skills', type: 'boolean', default: false },
584
- { name: 'core', description: 'Install core skills', type: 'boolean', default: true },
585
- { name: 'memory', description: 'Install memory skills', type: 'boolean', default: false },
586
- { name: 'github', description: 'Install GitHub skills', type: 'boolean', default: false },
587
- ],
588
- action: async (ctx) => {
589
- const options = {
590
- ...MINIMAL_INIT_OPTIONS,
591
- targetDir: ctx.cwd,
592
- force: ctx.flags.force,
593
- components: {
594
- settings: false,
595
- skills: true,
596
- commands: false,
597
- agents: false,
598
- helpers: false,
599
- statusline: false,
600
- mcp: false,
601
- runtime: false,
602
- claudeMd: false,
603
- graphify: false,
604
- },
605
- skills: {
606
- all: ctx.flags.all,
607
- core: ctx.flags.core,
608
- memory: ctx.flags.memory,
609
- github: ctx.flags.github,
610
- browser: false,
611
- advanced: false,
612
- },
613
- };
614
- const spinner = output.createSpinner({ text: 'Installing skills...' });
615
- spinner.start();
616
- const result = await executeInit(options);
617
- if (result.success) {
618
- spinner.succeed(`Installed ${result.summary.skillsCount} skills`);
619
- }
620
- else {
621
- spinner.fail('Failed to install skills');
622
- for (const error of result.errors) {
623
- output.printError(error);
624
- }
625
- }
626
- return { success: result.success, data: result };
627
- },
628
- };
629
- // Hooks subcommand
630
- const hooksCommand = {
631
- name: 'hooks',
632
- description: 'Initialize only hooks configuration',
633
- options: [
634
- { name: 'all', description: 'Enable all hooks', type: 'boolean', default: true },
635
- { name: 'minimal', description: 'Enable only essential hooks', type: 'boolean', default: false },
636
- ],
637
- action: async (ctx) => {
638
- const minimal = ctx.flags.minimal;
639
- const options = {
640
- ...DEFAULT_INIT_OPTIONS,
641
- targetDir: ctx.cwd,
642
- force: ctx.flags.force,
643
- components: {
644
- settings: true,
645
- skills: false,
646
- commands: false,
647
- agents: false,
648
- helpers: false,
649
- statusline: false,
650
- mcp: false,
651
- runtime: false,
652
- claudeMd: false,
653
- graphify: false,
654
- },
655
- hooks: minimal
656
- ? {
657
- preToolUse: true,
658
- postToolUse: true,
659
- userPromptSubmit: false,
660
- sessionStart: false,
661
- stop: false,
662
- preCompact: false,
663
- notification: false,
664
- teammateIdle: false,
665
- taskCompleted: false,
666
- timeout: 5000,
667
- continueOnError: true,
668
- }
669
- : DEFAULT_INIT_OPTIONS.hooks,
670
- };
671
- const spinner = output.createSpinner({ text: 'Creating hooks configuration...' });
672
- spinner.start();
673
- const result = await executeInit(options);
674
- if (result.success) {
675
- spinner.succeed(`Created settings.json with ${result.summary.hooksEnabled} hooks enabled`);
676
- }
677
- else {
678
- spinner.fail('Failed to create hooks configuration');
679
- for (const error of result.errors) {
680
- output.printError(error);
681
- }
682
- }
683
- return { success: result.success, data: result };
684
- },
685
- };
686
- // Upgrade subcommand - updates helpers without losing user data
687
- const upgradeCommand = {
688
- name: 'upgrade',
689
- description: 'Update statusline and helpers while preserving existing data',
690
- options: [
691
- {
692
- name: 'verbose',
693
- short: 'v',
694
- description: 'Show detailed output',
695
- type: 'boolean',
696
- default: false,
697
- },
698
- {
699
- name: 'add-missing',
700
- short: 'a',
701
- description: 'Add any new skills, agents, and commands that are missing',
702
- type: 'boolean',
703
- default: false,
704
- },
705
- {
706
- name: 'settings',
707
- short: 's',
708
- description: 'Merge new settings (Agent Teams, hooks) into existing settings.json',
709
- type: 'boolean',
710
- default: false,
711
- },
712
- {
713
- name: 'all',
714
- description: 'Upgrade all known monomind projects on this machine (scans ~/Desktop, ~/projects, etc.)',
715
- type: 'boolean',
716
- default: false,
717
- },
718
- ],
719
- action: async (ctx) => {
720
- const addMissing = (ctx.flags['add-missing'] || ctx.flags.addMissing);
721
- const upgradeSettings = (ctx.flags.settings);
722
- const upgradeAll = (ctx.flags.all);
723
- // ── --all: scan for every monomind project and upgrade each ──────────────
724
- if (upgradeAll) {
725
- output.writeln();
726
- output.writeln(output.bold('Upgrading all monomind projects'));
727
- output.writeln(output.dim('Scanning ~/Desktop, ~/projects, ~/code… (this may take a moment)'));
728
- output.writeln();
729
- const projects = findMonomindProjects();
730
- if (projects.length === 0) {
731
- output.printInfo('No monomind projects found. Install monomind in a project first: npx monomind init');
732
- return { success: true, exitCode: 0 };
733
- }
734
- output.printInfo(`Found ${projects.length} project(s). Upgrading…`);
735
- output.writeln();
736
- let succeeded = 0;
737
- let failed = 0;
738
- // Try to read control URL for dashboard progress events (best-effort)
739
- let controlUrl = 'http://localhost:4242';
740
- try {
741
- const ctrlPath = path.join(process.cwd(), '.monomind', 'control.json');
742
- if (fs.existsSync(ctrlPath) && fs.statSync(ctrlPath).size <= 4096) {
743
- const ctrlCfg = JSON.parse(fs.readFileSync(ctrlPath, 'utf-8'));
744
- // Only allow localhost/127.0.0.1 URLs to prevent SSRF via attacker-controlled control.json
745
- if (typeof ctrlCfg.url === 'string' && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?(\/|$)/.test(ctrlCfg.url)) {
746
- controlUrl = ctrlCfg.url;
747
- }
748
- }
749
- }
750
- catch { }
751
- const emitUpgradeProgress = async (projDir, status, current, total) => {
752
- try {
753
- const { default: http } = await import('http');
754
- const payload = JSON.stringify({ type: 'upgrade:progress', project: projDir, status, current, total, ts: Date.now() });
755
- const url = new URL(controlUrl + '/api/mastermind/event');
756
- const req = http.request({ hostname: url.hostname, port: parseInt(url.port || '4242'), path: url.pathname, method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload) } });
757
- req.write(payload);
758
- req.end();
759
- req.on('error', () => { });
760
- }
761
- catch { }
762
- };
763
- for (const projDir of projects) {
764
- const projIdx = projects.indexOf(projDir) + 1;
765
- const spinner = output.createSpinner({ text: `[${projIdx}/${projects.length}] ${projDir}` });
766
- spinner.start();
767
- try {
768
- const res = addMissing
769
- ? await executeUpgradeWithMissing(projDir, upgradeSettings)
770
- : await executeUpgrade(projDir, upgradeSettings);
771
- if (res.success) {
772
- spinner.succeed(projDir + ' (' + res.updated.length + ' updated)');
773
- succeeded++;
774
- emitUpgradeProgress(projDir, 'success', projIdx, projects.length);
775
- }
776
- else {
777
- spinner.fail(projDir + ' — ' + (res.errors[0] || 'unknown error'));
778
- failed++;
779
- emitUpgradeProgress(projDir, 'failed', projIdx, projects.length);
780
- }
781
- }
782
- catch (e) {
783
- spinner.fail(projDir + ' — ' + (e instanceof Error ? e.message : String(e)));
784
- failed++;
785
- emitUpgradeProgress(projDir, 'failed', projIdx, projects.length);
786
- }
787
- }
788
- output.writeln();
789
- output.printInfo(`Done: ${succeeded} upgraded, ${failed} failed out of ${projects.length} projects.`);
790
- return { success: failed === 0, exitCode: failed > 0 ? 1 : 0 };
791
- }
792
- output.writeln();
793
- output.writeln(output.bold('Upgrading MonoMind'));
794
- if (addMissing && upgradeSettings) {
795
- output.writeln(output.dim('Updates helpers, settings, and adds any missing skills/agents/commands'));
796
- }
797
- else if (addMissing) {
798
- output.writeln(output.dim('Updates helpers and adds any missing skills/agents/commands'));
799
- }
800
- else if (upgradeSettings) {
801
- output.writeln(output.dim('Updates helpers and merges new settings (Agent Teams, hooks)'));
802
- }
803
- else {
804
- output.writeln(output.dim('Updates helpers while preserving your existing data'));
805
- }
806
- output.writeln();
807
- const spinnerText = upgradeSettings
808
- ? 'Upgrading helpers and settings...'
809
- : (addMissing ? 'Upgrading and adding missing assets...' : 'Upgrading...');
810
- const spinner = output.createSpinner({ text: spinnerText });
811
- spinner.start();
812
- try {
813
- const result = addMissing
814
- ? await executeUpgradeWithMissing(ctx.cwd, upgradeSettings)
815
- : await executeUpgrade(ctx.cwd, upgradeSettings);
816
- if (!result.success) {
817
- spinner.fail('Upgrade failed');
818
- for (const error of result.errors) {
819
- output.printError(error);
820
- }
821
- return { success: false, exitCode: 1 };
822
- }
823
- spinner.succeed('Upgrade complete!');
824
- output.writeln();
825
- // Show what was updated
826
- if (result.updated.length > 0) {
827
- output.printBox(result.updated.map(f => `✓ ${f}`).join('\n'), 'Updated (latest version)');
828
- output.writeln();
829
- }
830
- // Show what was created
831
- if (result.created.length > 0) {
832
- output.printBox(result.created.map(f => `+ ${f}`).join('\n'), 'Created (new files)');
833
- output.writeln();
834
- }
835
- // Show what was preserved
836
- if (result.preserved.length > 0 && ctx.flags.verbose) {
837
- output.printBox(result.preserved.map(f => `• ${f}`).join('\n'), 'Preserved (existing data kept)');
838
- output.writeln();
839
- }
840
- else if (result.preserved.length > 0) {
841
- output.printInfo(`Preserved ${result.preserved.length} existing data files`);
842
- output.writeln();
843
- }
844
- // Show added assets (when --add-missing flag is used)
845
- if (result.addedSkills && result.addedSkills.length > 0) {
846
- output.printBox(result.addedSkills.map(s => `+ ${s}`).join('\n'), `Added Skills (${result.addedSkills.length} new)`);
847
- output.writeln();
848
- }
849
- if (result.addedAgents && result.addedAgents.length > 0) {
850
- output.printBox(result.addedAgents.map(a => `+ ${a}`).join('\n'), `Added Agents (${result.addedAgents.length} new)`);
851
- output.writeln();
852
- }
853
- if (result.addedCommands && result.addedCommands.length > 0) {
854
- output.printBox(result.addedCommands.map(c => `+ ${c}`).join('\n'), `Added Commands (${result.addedCommands.length} new)`);
855
- output.writeln();
856
- }
857
- // Show settings updates
858
- if (result.settingsUpdated && result.settingsUpdated.length > 0) {
859
- output.printBox(result.settingsUpdated.map(s => `+ ${s}`).join('\n'), 'Settings Updated');
860
- output.writeln();
861
- }
862
- output.printSuccess('Your statusline helper has been updated to the latest version');
863
- output.printInfo('Existing metrics and learning data were preserved');
864
- // Show settings summary
865
- if (upgradeSettings && result.settingsUpdated && result.settingsUpdated.length > 0) {
866
- output.printSuccess('Settings.json updated with new Agent Teams configuration');
867
- }
868
- // Show summary for --add-missing
869
- if (addMissing) {
870
- const totalAdded = (result.addedSkills?.length || 0) + (result.addedAgents?.length || 0) + (result.addedCommands?.length || 0);
871
- if (totalAdded > 0) {
872
- output.printSuccess(`Added ${totalAdded} missing assets to your project`);
873
- }
874
- else {
875
- output.printInfo('All skills, agents, and commands are already up to date');
876
- }
877
- }
878
- if (ctx.flags.format === 'json') {
879
- output.printJson(result);
880
- }
881
- return { success: true, data: result };
882
- }
883
- catch (error) {
884
- spinner.fail('Upgrade failed');
885
- output.printError(`Failed to upgrade: ${error instanceof Error ? error.message : String(error)}`);
886
- return { success: false, exitCode: 1 };
887
- }
888
- },
889
- };
890
- // Main init command
891
274
  export const initCommand = {
892
275
  name: 'init',
893
276
  description: 'Initialize MonoMind in the current directory',