moflo 4.12.3 → 4.12.4-rc.2

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 (98) hide show
  1. package/.claude/agents/core/coder.md +2 -3
  2. package/.claude/agents/core/researcher.md +3 -4
  3. package/.claude/agents/core/reviewer.md +6 -8
  4. package/.claude/guidance/shipped/moflo-spell-engine.md +13 -10
  5. package/.claude/helpers/gate-hook.mjs +67 -2
  6. package/.claude/helpers/gate.cjs +173 -12
  7. package/.claude/helpers/hook-handler.cjs +0 -0
  8. package/.claude/helpers/prompt-hook.mjs +0 -0
  9. package/.claude/skills/connector-builder/SKILL.md +5 -4
  10. package/.claude/skills/fl/phases.md +1 -1
  11. package/.claude/skills/fl/sdd.md +1 -1
  12. package/.claude/skills/spell-builder/SKILL.md +5 -4
  13. package/.claude/skills/spell-builder/architecture.md +4 -4
  14. package/.claude/skills/spell-builder/connectors/github-cli/README.md +22 -17
  15. package/.claude/skills/spell-builder/connectors/http/README.md +18 -11
  16. package/.claude/skills/spell-builder/connectors/local-outlook/README.md +8 -7
  17. package/.claude/skills/spell-builder/connectors/playwright/README.md +10 -8
  18. package/.claude/skills/spell-builder/steps/agent/README.md +25 -21
  19. package/.claude/skills/verify/SKILL.md +24 -3
  20. package/bin/gate-hook.mjs +67 -2
  21. package/bin/gate.cjs +173 -12
  22. package/bin/generate-code-map.mjs +70 -17
  23. package/bin/index-all.mjs +38 -0
  24. package/bin/index-guidance.mjs +8 -41
  25. package/bin/index-patterns.mjs +2 -2
  26. package/bin/index-tests.mjs +6 -4
  27. package/bin/lib/guidance-config.mjs +119 -0
  28. package/bin/lib/index-fingerprint.mjs +0 -0
  29. package/dist/src/cli/commands/agent.js +1 -89
  30. package/dist/src/cli/commands/analyze.js +1 -1
  31. package/dist/src/cli/commands/benchmark.js +11 -8
  32. package/dist/src/cli/commands/claims.js +2 -2
  33. package/dist/src/cli/commands/completions.js +1 -1
  34. package/dist/src/cli/commands/config.js +256 -96
  35. package/dist/src/cli/commands/deployment.js +6 -6
  36. package/dist/src/cli/commands/diagnose.js +1 -1
  37. package/dist/src/cli/commands/doctor-checks-config.js +18 -22
  38. package/dist/src/cli/commands/doctor-checks-deep.js +1 -1
  39. package/dist/src/cli/commands/doctor-fixes.js +36 -11
  40. package/dist/src/cli/commands/doctor.js +1 -1
  41. package/dist/src/cli/commands/embeddings.js +64 -23
  42. package/dist/src/cli/commands/github.js +1 -1
  43. package/dist/src/cli/commands/guidance.js +10 -10
  44. package/dist/src/cli/commands/hive-mind.js +8 -70
  45. package/dist/src/cli/commands/hooks.js +32 -219
  46. package/dist/src/cli/commands/mcp.js +5 -2
  47. package/dist/src/cli/commands/memory.js +59 -46
  48. package/dist/src/cli/commands/neural.js +21 -21
  49. package/dist/src/cli/commands/performance.js +14 -7
  50. package/dist/src/cli/commands/plugins.js +2 -2
  51. package/dist/src/cli/commands/providers.js +2 -2
  52. package/dist/src/cli/commands/retire.js +1 -1
  53. package/dist/src/cli/commands/route.js +1 -1
  54. package/dist/src/cli/commands/security.js +4 -4
  55. package/dist/src/cli/commands/status.js +18 -13
  56. package/dist/src/cli/commands/task.js +8 -0
  57. package/dist/src/cli/config/cli-config-store.js +326 -0
  58. package/dist/src/cli/hooks/workers/index.js +15 -9
  59. package/dist/src/cli/index.js +43 -33
  60. package/dist/src/cli/init/claudemd-generator.js +3 -3
  61. package/dist/src/cli/init/helpers-generator.js +203 -20
  62. package/dist/src/cli/init/moflo-yaml-template.js +11 -3
  63. package/dist/src/cli/init/settings-generator.js +10 -2
  64. package/dist/src/cli/mcp-client.js +12 -2
  65. package/dist/src/cli/mcp-server.js +5 -23
  66. package/dist/src/cli/mcp-tools/analysis-tools.js +103 -0
  67. package/dist/src/cli/mcp-tools/coverage-tools.js +206 -0
  68. package/dist/src/cli/mcp-tools/hive-mind-tools.js +71 -0
  69. package/dist/src/cli/mcp-tools/hooks-tools.js +25 -9
  70. package/dist/src/cli/mcp-tools/memory-admin-tools.js +538 -0
  71. package/dist/src/cli/mcp-tools/memory-tools.js +26 -5
  72. package/dist/src/cli/mcp-tools/neural-tools.js +56 -87
  73. package/dist/src/cli/mcp-tools/performance-tools.js +76 -39
  74. package/dist/src/cli/mcp-tools/progress-tools.js +142 -0
  75. package/dist/src/cli/mcp-tools/security-tools.js +1 -1
  76. package/dist/src/cli/mcp-tools/session-tools.js +116 -0
  77. package/dist/src/cli/mcp-tools/synthetic.js +74 -0
  78. package/dist/src/cli/mcp-tools/system-tools.js +126 -78
  79. package/dist/src/cli/mcp-tools/task-tools.js +101 -1
  80. package/dist/src/cli/movector/coverage-router.js +48 -6
  81. package/dist/src/cli/movector/diff-classifier.js +8 -6
  82. package/dist/src/cli/movector/flash-attention.js +1 -1
  83. package/dist/src/cli/movector/vector-db.js +1 -1
  84. package/dist/src/cli/parser.js +81 -12
  85. package/dist/src/cli/services/daemon-lock.js +5 -2
  86. package/dist/src/cli/services/hook-block-hash.js +3 -1
  87. package/dist/src/cli/services/moflo-version.js +62 -0
  88. package/dist/src/cli/services/movector-training.js +1 -1
  89. package/dist/src/cli/services/spell-gate.js +6 -4
  90. package/dist/src/cli/services/worker-daemon.js +37 -7
  91. package/dist/src/cli/shared/utils/load-average.js +59 -0
  92. package/dist/src/cli/spells/commands/agent-command.js +55 -25
  93. package/dist/src/cli/suggest.js +1 -1
  94. package/dist/src/cli/swarm/swarm-persistence.js +112 -0
  95. package/dist/src/cli/swarm/unified-coordinator.js +118 -3
  96. package/dist/src/cli/version.js +1 -1
  97. package/package.json +5 -3
  98. package/dist/src/cli/mcp-tools/github-tools.js +0 -318
@@ -27,6 +27,41 @@ async function runFixCommand(cmd) {
27
27
  return false;
28
28
  }
29
29
  }
30
+ /**
31
+ * Fix the `Config File` check by creating the project's JSON config.
32
+ *
33
+ * The return value is derived from the file being on disk afterwards, NOT from
34
+ * the exit code of `config init`. That distinction is the whole fix: the
35
+ * command used to print "Creating claude-flow.config.json..." and exit 0
36
+ * without a single filesystem call, so `--fix` reported `applied: true` on
37
+ * every run while the warning it claimed to fix never cleared. An exit code is
38
+ * a claim; the file is the evidence.
39
+ *
40
+ * `deps` is injectable so tests can pin both branches without spawning npx —
41
+ * in particular the regression case, where the command "succeeds" and leaves
42
+ * nothing behind.
43
+ */
44
+ export async function fixConfigFile(deps = {}) {
45
+ try {
46
+ const root = deps.root ?? resolveStateRoot();
47
+ const run = deps.run ?? runFixCommand;
48
+ const { findCliConfigFile } = await import('../config/cli-config-store.js');
49
+ if (findCliConfigFile(root))
50
+ return true;
51
+ const cfDir = mofloDir(root);
52
+ if (!existsSync(cfDir))
53
+ mkdirSync(cfDir, { recursive: true });
54
+ await run('npx moflo config init');
55
+ return findCliConfigFile(root) !== null;
56
+ }
57
+ catch (e) {
58
+ // Leave a crumb rather than a bare `catch {}` — #854 is four versions of
59
+ // consumer-invisible breakage caused by exactly that shape in the launcher
60
+ // upgrade flow.
61
+ output.writeln(output.warning(` Config File fix failed: ${errorDetail(e)}`));
62
+ return false;
63
+ }
64
+ }
30
65
  /**
31
66
  * Fix Gate Health failures: bin/.claude-helpers gate.cjs drift AND missing
32
67
  * settings.json hook wiring. The check has three independent failure modes
@@ -458,17 +493,7 @@ export async function autoFixCheck(check) {
458
493
  return runFixCommand('npx moflo memory init --force');
459
494
  }
460
495
  },
461
- 'Config File': async () => {
462
- try {
463
- const cfDir = join(resolveStateRoot(), '.moflo');
464
- if (!existsSync(cfDir))
465
- mkdirSync(cfDir, { recursive: true });
466
- return runFixCommand('npx moflo config init');
467
- }
468
- catch {
469
- return false;
470
- }
471
- },
496
+ 'Config File': fixConfigFile,
472
497
  // moflo.yaml auto-create. The session-start launcher already runs
473
498
  // `ensureMofloYamlExists` (see bin/session-start-launcher.mjs § 3d-yaml-create,
474
499
  // #895) but it can miss when the launcher itself was old at upgrade time —
@@ -8,7 +8,7 @@
8
8
  * `doctor-registry.ts`; rendering helpers live in `doctor-render.ts`.
9
9
  * This file is orchestration only.
10
10
  *
11
- * Created with motailz.com
11
+ * Created with cielolimitada.com
12
12
  */
13
13
  import { output } from '../output.js';
14
14
  import { allChecks, componentMap, zombieScanCheck } from './doctor-registry.js';
@@ -10,8 +10,9 @@
10
10
  * - Neural substrate integration
11
11
  * - Persistent SQLite cache
12
12
  *
13
- * Created with ❤️ by motailz.com
13
+ * Created with ❤️ by cielolimitada.com
14
14
  */
15
+ import { readFileSync } from 'node:fs';
15
16
  import { output } from '../output.js';
16
17
  import { runEmbeddingsMigrationIfNeeded } from '../services/embeddings-migration.js';
17
18
  import { memoryDbPath, MEMORY_DB_FILE, MOFLO_DIR } from '../services/moflo-paths.js';
@@ -98,8 +99,8 @@ const searchCommand = {
98
99
  options: [
99
100
  { name: 'query', short: 'q', type: 'string', description: 'Search query', required: true },
100
101
  { name: 'collection', short: 'c', type: 'string', description: 'Namespace to search', default: 'default' },
101
- { name: 'limit', short: 'l', type: 'number', description: 'Max results', default: '10' },
102
- { name: 'threshold', short: 't', type: 'number', description: 'Similarity threshold (0-1)', default: '0.5' },
102
+ { name: 'limit', short: 'l', type: 'number', description: 'Max results', default: 10 },
103
+ { name: 'threshold', short: 't', type: 'number', description: 'Similarity threshold (0-1)', default: 0.5 },
103
104
  { name: 'db-path', type: 'string', description: 'Database path', default: DEFAULT_DB_PATH_FLAG },
104
105
  ],
105
106
  examples: [
@@ -448,8 +449,8 @@ const indexCommand = {
448
449
  options: [
449
450
  { name: 'action', short: 'a', type: 'string', description: 'Action: build, rebuild, status, optimize', default: 'status' },
450
451
  { name: 'collection', short: 'c', type: 'string', description: 'Collection/namespace name' },
451
- { name: 'ef-construction', type: 'number', description: 'HNSW ef_construction parameter', default: '200' },
452
- { name: 'm', type: 'number', description: 'HNSW M parameter', default: '16' },
452
+ { name: 'ef-construction', type: 'number', description: 'HNSW ef_construction parameter', default: 200 },
453
+ { name: 'm', type: 'number', description: 'HNSW M parameter', default: 16 },
453
454
  ],
454
455
  examples: [
455
456
  { command: 'flo embeddings index', description: 'Show index status' },
@@ -579,11 +580,11 @@ export const initCommand = {
579
580
  description: 'Initialize embedding subsystem with ONNX model and hyperbolic config',
580
581
  options: [
581
582
  { name: 'model', short: 'm', type: 'string', description: 'ONNX model ID', default: 'all-MiniLM-L6-v2' },
582
- { name: 'hyperbolic', type: 'boolean', description: 'Enable hyperbolic (Poincaré ball) embeddings', default: 'true' },
583
+ { name: 'hyperbolic', type: 'boolean', description: 'Enable hyperbolic (Poincaré ball) embeddings', default: true },
583
584
  { name: 'curvature', short: 'c', type: 'string', description: 'Poincaré ball curvature (use --curvature=-1 for negative)', default: '-1' },
584
- { name: 'download', short: 'd', type: 'boolean', description: 'Download model during init', default: 'true' },
585
+ { name: 'download', short: 'd', type: 'boolean', description: 'Download model during init', default: true },
585
586
  { name: 'cache-size', type: 'string', description: 'LRU cache entries', default: '256' },
586
- { name: 'force', short: 'f', type: 'boolean', description: 'Overwrite existing configuration', default: 'false' },
587
+ { name: 'force', short: 'f', type: 'boolean', description: 'Overwrite existing configuration', default: false },
587
588
  ],
588
589
  examples: [
589
590
  { command: 'flo embeddings init', description: 'Initialize with defaults' },
@@ -739,9 +740,13 @@ const chunkCommand = {
739
740
  name: 'chunk',
740
741
  description: 'Chunk text for embedding with overlap',
741
742
  options: [
742
- { name: 'text', short: 't', type: 'string', description: 'Text to chunk', required: true },
743
- { name: 'max-size', short: 's', type: 'number', description: 'Max chunk size in chars', default: '512' },
744
- { name: 'overlap', short: 'o', type: 'number', description: 'Overlap between chunks', default: '50' },
743
+ // Not `required`: --file is the documented alternative ("instead of
744
+ // text"), and a parser-level requirement made its own example
745
+ // (`chunk -f doc.txt`) impossible to run. The action validates that
746
+ // exactly one source was given.
747
+ { name: 'text', short: 't', type: 'string', description: 'Text to chunk' },
748
+ { name: 'max-size', short: 's', type: 'number', description: 'Max chunk size in chars', default: 512 },
749
+ { name: 'overlap', short: 'o', type: 'number', description: 'Overlap between chunks', default: 50 },
745
750
  { name: 'strategy', type: 'string', description: 'Strategy: character, sentence, paragraph, token', default: 'sentence' },
746
751
  { name: 'file', short: 'f', type: 'string', description: 'File to chunk (instead of text)' },
747
752
  ],
@@ -750,7 +755,40 @@ const chunkCommand = {
750
755
  { command: 'flo embeddings chunk -f doc.txt --strategy paragraph', description: 'Chunk file by paragraph' },
751
756
  ],
752
757
  action: async (ctx) => {
753
- const text = ctx.flags.text || '';
758
+ const file = ctx.flags.file;
759
+ // --file was declared, described as "instead of text", and given its own
760
+ // example — but never read here, so it chunked the empty string even once
761
+ // the parser let it through.
762
+ let text;
763
+ if (file) {
764
+ try {
765
+ // Read first and let ENOENT report the missing file, rather than
766
+ // stat-then-read: the existence check was both a second syscall and a
767
+ // TOCTOU window this catch already covers.
768
+ //
769
+ // Normalize CRLF → LF: `chunking.ts` splits paragraphs on /\n\n+/,
770
+ // which a Windows-authored file's \r\n\r\n does not match, so the same
771
+ // document would chunk differently depending on the platform it was
772
+ // written on. Normalizing here keeps `--file` platform-independent
773
+ // without touching the shared splitter, whose boundaries determine
774
+ // already-stored embeddings.
775
+ text = readFileSync(file, 'utf8').replace(/\r\n/g, '\n');
776
+ }
777
+ catch (err) {
778
+ const code = err.code;
779
+ output.printError(code === 'ENOENT'
780
+ ? `File not found: ${file}`
781
+ : `Could not read ${file}: ${err.message}`);
782
+ return { success: false, exitCode: 1 };
783
+ }
784
+ }
785
+ else {
786
+ text = ctx.flags.text || '';
787
+ }
788
+ if (!text) {
789
+ output.printError('Nothing to chunk — pass --text or --file');
790
+ return { success: false, exitCode: 1 };
791
+ }
754
792
  const maxSize = parseInt(ctx.flags.maxSize || '512', 10);
755
793
  const overlap = parseInt(ctx.flags.overlap || '50', 10);
756
794
  const strategy = ctx.flags.strategy || 'sentence';
@@ -775,7 +813,7 @@ const chunkCommand = {
775
813
  });
776
814
  output.writeln();
777
815
  output.writeln(output.dim(`Total: ${result.totalChunks} chunks from ${result.originalLength} chars`));
778
- return { success: true };
816
+ return { success: true, data: result };
779
817
  },
780
818
  };
781
819
  // Normalize subcommand
@@ -822,7 +860,7 @@ const hyperbolicCommand = {
822
860
  description: 'Hyperbolic embedding operations (Poincaré ball)',
823
861
  options: [
824
862
  { name: 'action', short: 'a', type: 'string', description: 'Action: convert, distance, centroid', default: 'convert' },
825
- { name: 'curvature', short: 'c', type: 'number', description: 'Hyperbolic curvature', default: '-1' },
863
+ { name: 'curvature', short: 'c', type: 'number', description: 'Hyperbolic curvature', default: -1 },
826
864
  { name: 'input', short: 'i', type: 'string', description: 'Input embedding(s) JSON' },
827
865
  ],
828
866
  examples: [
@@ -1072,7 +1110,7 @@ export const modelsCommand = {
1072
1110
  description: 'List and download embedding models',
1073
1111
  options: [
1074
1112
  { name: 'download', short: 'd', type: 'string', description: 'Model ID to download' },
1075
- { name: 'list', short: 'l', type: 'boolean', description: 'List available models', default: 'true' },
1113
+ { name: 'list', short: 'l', type: 'boolean', description: 'List available models', default: true },
1076
1114
  ],
1077
1115
  examples: [
1078
1116
  { command: 'flo embeddings models', description: 'List models' },
@@ -1254,8 +1292,8 @@ const warmupCommand = {
1254
1292
  name: 'warmup',
1255
1293
  description: 'Preload embedding model for faster subsequent operations',
1256
1294
  options: [
1257
- { name: 'background', short: 'b', type: 'boolean', description: 'Run warmup in background daemon', default: 'false' },
1258
- { name: 'test', short: 't', type: 'boolean', description: 'Run test embedding after warmup', default: 'true' },
1295
+ { name: 'background', short: 'b', type: 'boolean', description: 'Run warmup in background daemon', default: false },
1296
+ { name: 'test', short: 't', type: 'boolean', description: 'Run test embedding after warmup', default: true },
1259
1297
  ],
1260
1298
  examples: [
1261
1299
  { command: 'flo embeddings warmup', description: 'Preload model with test' },
@@ -1327,9 +1365,9 @@ const benchmarkCommand = {
1327
1365
  name: 'benchmark',
1328
1366
  description: 'Run embedding performance benchmarks',
1329
1367
  options: [
1330
- { name: 'iterations', short: 'n', type: 'number', description: 'Number of iterations', default: '10' },
1331
- { name: 'batch-size', short: 'b', type: 'number', description: 'Batch size for batch test', default: '5' },
1332
- { name: 'full', short: 'f', type: 'boolean', description: 'Run full benchmark suite', default: 'false' },
1368
+ { name: 'iterations', short: 'n', type: 'number', description: 'Number of iterations', default: 10 },
1369
+ { name: 'batch-size', short: 'b', type: 'number', description: 'Batch size for batch test', default: 5 },
1370
+ { name: 'full', short: 'f', type: 'boolean', description: 'Run full benchmark suite', default: false },
1333
1371
  ],
1334
1372
  examples: [
1335
1373
  { command: 'flo embeddings benchmark', description: 'Quick benchmark' },
@@ -1472,8 +1510,11 @@ const migrateCommand = {
1472
1510
  description: 'Re-embed existing vectors using the current neural model (runs automatically on session start if needed)',
1473
1511
  options: [
1474
1512
  { name: 'db', short: 'd', type: 'string', description: 'Path to memory DB', default: DEFAULT_DB_PATH_FLAG },
1475
- { name: 'batch-size', short: 'b', type: 'number', description: 'Batch size', default: '128' },
1476
- { name: 'verbose', short: 'v', type: 'boolean', description: 'Verbose output', default: 'false' },
1513
+ { name: 'batch-size', short: 'b', type: 'number', description: 'Batch size', default: 128 },
1514
+ // Boolean default, not the string 'false' — this option shadows the global
1515
+ // --verbose, so its default is the one the parser applies, and 'false' is
1516
+ // a truthy string that would turn verbose ON by default.
1517
+ { name: 'verbose', short: 'v', type: 'boolean', description: 'Verbose output', default: false },
1477
1518
  ],
1478
1519
  examples: [
1479
1520
  { command: 'flo embeddings migrate', description: `Migrate ${DEFAULT_DB_PATH_FLAG} to current version` },
@@ -1558,7 +1599,7 @@ export const embeddingsCommand = {
1558
1599
  'Hyperbolic: Better hierarchical representation',
1559
1600
  ]);
1560
1601
  output.writeln();
1561
- output.writeln(output.dim('Created with ❤️ by motailz.com'));
1602
+ output.writeln(output.dim('Created with ❤️ by cielolimitada.com'));
1562
1603
  return { success: true };
1563
1604
  },
1564
1605
  };
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Uses `gh` CLI for GitHub API calls and project detection from moflo.yaml.
6
6
  *
7
- * Created with motailz.com
7
+ * Created with cielolimitada.com
8
8
  */
9
9
  import { output } from '../output.js';
10
10
  import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
@@ -12,7 +12,7 @@ const compileCommand = {
12
12
  { name: 'root', short: 'r', type: 'string', description: 'Root guidance file path', default: './CLAUDE.md' },
13
13
  { name: 'local', short: 'l', type: 'string', description: 'Local guidance overlay file path' },
14
14
  { name: 'output', short: 'o', type: 'string', description: 'Output directory for compiled bundle' },
15
- { name: 'json', type: 'boolean', description: 'Output as JSON', default: 'false' },
15
+ { name: 'json', type: 'boolean', description: 'Output as JSON', default: false },
16
16
  ],
17
17
  examples: [
18
18
  { command: 'flo guidance compile', description: 'Compile default CLAUDE.md' },
@@ -84,9 +84,9 @@ const retrieveCommand = {
84
84
  { name: 'task', short: 't', type: 'string', description: 'Task description', required: true },
85
85
  { name: 'root', short: 'r', type: 'string', description: 'Root guidance file path', default: './CLAUDE.md' },
86
86
  { name: 'local', short: 'l', type: 'string', description: 'Local overlay file path' },
87
- { name: 'max-shards', short: 'n', type: 'number', description: 'Maximum number of shards to retrieve', default: '5' },
87
+ { name: 'max-shards', short: 'n', type: 'number', description: 'Maximum number of shards to retrieve', default: 5 },
88
88
  { name: 'intent', short: 'i', type: 'string', description: 'Override detected intent' },
89
- { name: 'json', type: 'boolean', description: 'Output as JSON', default: 'false' },
89
+ { name: 'json', type: 'boolean', description: 'Output as JSON', default: false },
90
90
  ],
91
91
  examples: [
92
92
  { command: 'flo guidance retrieve -t "Fix SQL injection in user search"', description: 'Retrieve guidance for a security task' },
@@ -172,7 +172,7 @@ const gatesCommand = {
172
172
  { name: 'command', short: 'c', type: 'string', description: 'Command to evaluate' },
173
173
  { name: 'content', type: 'string', description: 'Content to check for secrets' },
174
174
  { name: 'tool', short: 't', type: 'string', description: 'Tool name to check against allowlist' },
175
- { name: 'json', type: 'boolean', description: 'Output as JSON', default: 'false' },
175
+ { name: 'json', type: 'boolean', description: 'Output as JSON', default: false },
176
176
  ],
177
177
  examples: [
178
178
  { command: 'flo guidance gates -c "rm -rf /tmp"', description: 'Check if a command is destructive' },
@@ -256,7 +256,7 @@ const statusCommand = {
256
256
  name: 'status',
257
257
  description: 'Show guidance control plane status and metrics',
258
258
  options: [
259
- { name: 'json', type: 'boolean', description: 'Output as JSON', default: 'false' },
259
+ { name: 'json', type: 'boolean', description: 'Output as JSON', default: false },
260
260
  ],
261
261
  action: async (ctx) => {
262
262
  const jsonOutput = ctx.flags.json === true;
@@ -309,11 +309,11 @@ const optimizeCommand = {
309
309
  options: [
310
310
  { name: 'root', short: 'r', type: 'string', description: 'Root guidance file path', default: './CLAUDE.md' },
311
311
  { name: 'local', short: 'l', type: 'string', description: 'Local overlay file path' },
312
- { name: 'apply', short: 'a', type: 'boolean', description: 'Apply optimizations to the file', default: 'false' },
312
+ { name: 'apply', short: 'a', type: 'boolean', description: 'Apply optimizations to the file', default: false },
313
313
  { name: 'context-size', short: 's', type: 'string', description: 'Target context size: compact, standard, full', default: 'standard' },
314
- { name: 'target-score', type: 'number', description: 'Target composite score (0-100)', default: '90' },
315
- { name: 'max-iterations', type: 'number', description: 'Maximum optimization iterations', default: '5' },
316
- { name: 'json', type: 'boolean', description: 'Output as JSON', default: 'false' },
314
+ { name: 'target-score', type: 'number', description: 'Target composite score (0-100)', default: 90 },
315
+ { name: 'max-iterations', type: 'number', description: 'Maximum optimization iterations', default: 5 },
316
+ { name: 'json', type: 'boolean', description: 'Output as JSON', default: false },
317
317
  ],
318
318
  examples: [
319
319
  { command: 'flo guidance optimize', description: 'Analyze current CLAUDE.md and show suggestions' },
@@ -416,7 +416,7 @@ const abTestCommand = {
416
416
  { name: 'config-b', short: 'b', type: 'string', description: 'Path to Config B (candidate CLAUDE.md)', default: './CLAUDE.md' },
417
417
  { name: 'tasks', short: 't', type: 'string', description: 'Path to custom task JSON file (array of ABTask objects)' },
418
418
  { name: 'work-dir', short: 'w', type: 'string', description: 'Working directory for test execution' },
419
- { name: 'json', type: 'boolean', description: 'Output as JSON', default: 'false' },
419
+ { name: 'json', type: 'boolean', description: 'Output as JSON', default: false },
420
420
  ],
421
421
  examples: [
422
422
  { command: 'flo guidance ab-test', description: 'Run default A/B test (no guidance vs ./CLAUDE.md)' },
@@ -113,7 +113,6 @@ ${workerTypes.map(type => `• ${type}: ${workerGroups[type].length} agents`).jo
113
113
  mcp__moflo__memory_store - Store collective knowledge
114
114
  mcp__moflo__memory_retrieve - Access shared memory
115
115
  mcp__moflo__memory_search - Search memory patterns
116
- mcp__moflo__neural_train - Learn from experiences
117
116
  mcp__moflo__hooks_intelligence_pattern-store - Store patterns
118
117
 
119
118
  📋 HIVE MIND EXECUTION PROTOCOL:
@@ -789,6 +788,13 @@ const taskCommand = {
789
788
  requireConsensus,
790
789
  timeout,
791
790
  });
791
+ // An uninitialized hive comes back as { error }, not as a throw. Reading
792
+ // result.assignedTo.join() on that shape crashed with a TypeError
793
+ // instead of printing the actual problem (#1349).
794
+ if (result.error) {
795
+ output.printError(result.error);
796
+ return { success: false, exitCode: 1 };
797
+ }
792
798
  if (ctx.flags.format === 'json') {
793
799
  output.printJson(result);
794
800
  return { success: true, data: result };
@@ -818,73 +824,6 @@ const taskCommand = {
818
824
  }
819
825
  }
820
826
  };
821
- // Optimize memory subcommand
822
- const optimizeMemoryCommand = {
823
- name: 'optimize-memory',
824
- description: 'Optimize hive memory and patterns',
825
- options: [
826
- {
827
- name: 'aggressive',
828
- short: 'a',
829
- description: 'Aggressive optimization',
830
- type: 'boolean',
831
- default: false
832
- },
833
- {
834
- name: 'threshold',
835
- description: 'Quality threshold for pattern retention',
836
- type: 'number',
837
- default: 0.7
838
- }
839
- ],
840
- action: async (ctx) => {
841
- const aggressive = ctx.flags.aggressive;
842
- const threshold = ctx.flags.threshold;
843
- output.printInfo('Optimizing hive memory...');
844
- const spinner = output.createSpinner({ text: 'Analyzing patterns...', spinner: 'dots' });
845
- spinner.start();
846
- try {
847
- const result = await callMCPTool('hive-mind_optimize-memory', {
848
- aggressive,
849
- qualityThreshold: threshold,
850
- });
851
- spinner.succeed('Memory optimized');
852
- if (ctx.flags.format === 'json') {
853
- output.printJson(result);
854
- return { success: true, data: result };
855
- }
856
- output.writeln();
857
- output.printTable({
858
- columns: [
859
- { key: 'metric', header: 'Metric', width: 20 },
860
- { key: 'before', header: 'Before', width: 15, align: 'right' },
861
- { key: 'after', header: 'After', width: 15, align: 'right' }
862
- ],
863
- data: [
864
- { metric: 'Patterns', before: result.before.patterns, after: result.after.patterns },
865
- { metric: 'Memory', before: result.before.memory, after: result.after.memory }
866
- ]
867
- });
868
- output.writeln();
869
- output.printList([
870
- `Patterns removed: ${result.removed}`,
871
- `Patterns consolidated: ${result.consolidated}`,
872
- `Optimization time: ${result.timeMs}ms`
873
- ]);
874
- return { success: true, data: result };
875
- }
876
- catch (error) {
877
- spinner.fail('Optimization failed');
878
- if (error instanceof MCPClientError) {
879
- output.printError(`Optimization error: ${error.message}`);
880
- }
881
- else {
882
- output.printError(`Unexpected error: ${String(error)}`);
883
- }
884
- return { success: false, exitCode: 1 };
885
- }
886
- }
887
- };
888
827
  // Join subcommand
889
828
  const joinCommand = {
890
829
  name: 'join',
@@ -1132,7 +1071,7 @@ export const hiveMindCommand = {
1132
1071
  name: 'hive-mind',
1133
1072
  aliases: ['hive'],
1134
1073
  description: 'Queen-led consensus-based multi-agent coordination',
1135
- subcommands: [initCommand, spawnCommand, statusCommand, taskCommand, joinCommand, leaveCommand, consensusCommand, broadcastCommand, memorySubCommand, optimizeMemoryCommand, shutdownCommand],
1074
+ subcommands: [initCommand, spawnCommand, statusCommand, taskCommand, joinCommand, leaveCommand, consensusCommand, broadcastCommand, memorySubCommand, shutdownCommand],
1136
1075
  options: [],
1137
1076
  examples: [
1138
1077
  { command: 'flo hive-mind init -t hierarchical-mesh', description: 'Initialize hive' },
@@ -1157,7 +1096,6 @@ export const hiveMindCommand = {
1157
1096
  `${output.highlight('consensus')} - Manage consensus proposals`,
1158
1097
  `${output.highlight('broadcast')} - Broadcast message to workers`,
1159
1098
  `${output.highlight('memory')} - Access shared memory`,
1160
- `${output.highlight('optimize-memory')} - Optimize patterns and memory`,
1161
1099
  `${output.highlight('shutdown')} - Shutdown the hive`
1162
1100
  ]);
1163
1101
  output.writeln();