monomind 2.5.4 → 2.5.6

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 (74) hide show
  1. package/README.md +10 -3
  2. package/package.json +1 -1
  3. package/packages/@monomind/cli/.claude/commands/mastermind/topology.md +121 -0
  4. package/packages/@monomind/cli/.claude/commands/mastermind.md +121 -102
  5. package/packages/@monomind/cli/.claude/helpers/control-start.cjs +22 -2
  6. package/packages/@monomind/cli/.claude/helpers/control-stop.cjs +95 -0
  7. package/packages/@monomind/cli/.claude/helpers/graphify-freshen.cjs +6 -0
  8. package/packages/@monomind/cli/.claude/helpers/hook-handler.cjs +13 -5
  9. package/packages/@monomind/cli/.claude/helpers/utils/monograph.cjs +33 -10
  10. package/packages/@monomind/cli/.claude/helpers/utils/system-pressure.cjs +46 -0
  11. package/packages/@monomind/cli/.claude/settings.json +448 -0
  12. package/packages/@monomind/cli/README.md +10 -3
  13. package/packages/@monomind/cli/bin/cli.js +16 -6
  14. package/packages/@monomind/cli/bin/mcp-server.js +17 -8
  15. package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.js +1 -1
  16. package/packages/@monomind/cli/dist/src/commands/agent-ops.js +1 -1
  17. package/packages/@monomind/cli/dist/src/commands/cleanup.js +53 -1
  18. package/packages/@monomind/cli/dist/src/commands/config.js +1 -1
  19. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +1 -1
  20. package/packages/@monomind/cli/dist/src/commands/hooks.js +1 -1
  21. package/packages/@monomind/cli/dist/src/commands/index.js +4 -0
  22. package/packages/@monomind/cli/dist/src/commands/init-wizard.js +3 -3
  23. package/packages/@monomind/cli/dist/src/commands/init.js +2 -2
  24. package/packages/@monomind/cli/dist/src/commands/mcp.js +2 -2
  25. package/packages/@monomind/cli/dist/src/commands/memory-admin.js +8 -7
  26. package/packages/@monomind/cli/dist/src/commands/memory-list.js +2 -2
  27. package/packages/@monomind/cli/dist/src/commands/memory.d.ts +1 -1
  28. package/packages/@monomind/cli/dist/src/commands/memory.js +4 -4
  29. package/packages/@monomind/cli/dist/src/commands/neural-core.js +1 -1
  30. package/packages/@monomind/cli/dist/src/commands/performance.js +8 -9
  31. package/packages/@monomind/cli/dist/src/commands/status.js +2 -2
  32. package/packages/@monomind/cli/dist/src/commands/swarm.js +1 -1
  33. package/packages/@monomind/cli/dist/src/index.js +1 -1
  34. package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +2 -2
  35. package/packages/@monomind/cli/dist/src/init/executor.js +13 -6
  36. package/packages/@monomind/cli/dist/src/init/helpers-generator.js +66 -3
  37. package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.d.ts +1 -1
  38. package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.js +1 -1
  39. package/packages/@monomind/cli/dist/src/init/statusline-generator.d.ts +1 -1
  40. package/packages/@monomind/cli/dist/src/init/statusline-generator.js +2 -2
  41. package/packages/@monomind/cli/dist/src/init/types.d.ts +1 -1
  42. package/packages/@monomind/cli/dist/src/knowledge/document-pipeline.d.ts +1 -1
  43. package/packages/@monomind/cli/dist/src/knowledge/document-pipeline.js +3 -3
  44. package/packages/@monomind/cli/dist/src/mcp-client.d.ts +13 -51
  45. package/packages/@monomind/cli/dist/src/mcp-client.js +79 -134
  46. package/packages/@monomind/cli/dist/src/mcp-server.js +4 -3
  47. package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.js +45 -19
  48. package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +1 -1
  49. package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +2 -2
  50. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.js +2 -2
  51. package/packages/@monomind/cli/dist/src/mcp-tools/knowledge-tools.js +1 -1
  52. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.js +2 -2
  53. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +22 -9
  54. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.d.ts +1 -1
  55. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +3 -3
  56. package/packages/@monomind/cli/dist/src/mcp-tools/system-tools.js +1 -1
  57. package/packages/@monomind/cli/dist/src/memory/embedding-operations.js +2 -2
  58. package/packages/@monomind/cli/dist/src/memory/hnsw-operations.js +53 -26
  59. package/packages/@monomind/cli/dist/src/memory/intelligence.js +2 -2
  60. package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +7 -3
  61. package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +24 -10
  62. package/packages/@monomind/cli/dist/src/memory/memory-crud.js +2 -2
  63. package/packages/@monomind/cli/dist/src/memory/memory-initializer.d.ts +2 -2
  64. package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +6 -6
  65. package/packages/@monomind/cli/dist/src/memory/memory-read.js +4 -4
  66. package/packages/@monomind/cli/dist/src/orgrt/daemon.js +12 -6
  67. package/packages/@monomind/cli/dist/src/orgrt/mailbox.d.ts +1 -0
  68. package/packages/@monomind/cli/dist/src/orgrt/mailbox.js +4 -0
  69. package/packages/@monomind/cli/dist/src/orgrt/policy.js +1 -1
  70. package/packages/@monomind/cli/dist/src/orgrt/server.js +25 -0
  71. package/packages/@monomind/cli/dist/src/ui/dashboard.html +327 -611
  72. package/packages/@monomind/cli/dist/src/ui/server.mjs +165 -22
  73. package/packages/@monomind/cli/package.json +1 -1
  74. package/scripts/growth-content-calendar.mjs +140 -0
@@ -41,22 +41,31 @@ process.stdin.on('data', async (chunk) => {
41
41
 
42
42
  for (const line of lines) {
43
43
  if (line.trim()) {
44
+ let parsed;
44
45
  try {
45
- const message = JSON.parse(line);
46
- const response = await handleMessage(message);
46
+ parsed = JSON.parse(line);
47
+ } catch {
48
+ console.log(JSON.stringify({
49
+ jsonrpc: '2.0',
50
+ id: null,
51
+ error: { code: -32700, message: 'Parse error' },
52
+ }));
53
+ continue;
54
+ }
55
+ try {
56
+ const response = await handleMessage(parsed);
47
57
  if (response) {
48
58
  console.log(JSON.stringify(response));
49
59
  }
50
60
  } catch (error) {
51
61
  console.error(
52
- `[${new Date().toISOString()}] ERROR [monomind-mcp] Failed to parse:`,
62
+ `[${new Date().toISOString()}] ERROR [monomind-mcp] handler error:`,
53
63
  error instanceof Error ? error.message : String(error)
54
64
  );
55
- // Send parse error response
56
65
  console.log(JSON.stringify({
57
66
  jsonrpc: '2.0',
58
- id: null,
59
- error: { code: -32700, message: 'Parse error' },
67
+ id: parsed.id ?? null,
68
+ error: { code: -32603, message: error instanceof Error ? error.message : 'Internal error' },
60
69
  }));
61
70
  }
62
71
  }
@@ -122,7 +131,7 @@ async function handleMessage(message) {
122
131
  }
123
132
 
124
133
  case 'tools/list': {
125
- const tools = listMCPTools();
134
+ const tools = await listMCPTools();
126
135
  return {
127
136
  jsonrpc: '2.0',
128
137
  id: message.id,
@@ -140,7 +149,7 @@ async function handleMessage(message) {
140
149
  const toolName = params.name;
141
150
  const toolParams = params.arguments || {};
142
151
 
143
- if (!hasTool(toolName)) {
152
+ if (!await hasTool(toolName)) {
144
153
  return {
145
154
  jsonrpc: '2.0',
146
155
  id: message.id,
@@ -44,7 +44,7 @@ export const AGENT_TYPES = [
44
44
  { value: 'optimizer', label: 'Optimizer', hint: 'Performance optimization and bottleneck analysis' },
45
45
  { value: 'security-architect', label: 'Security Architect', hint: 'Security architecture and threat modeling' },
46
46
  { value: 'security-auditor', label: 'Security Auditor', hint: 'CVE remediation and security testing' },
47
- { value: 'memory-specialist', label: 'Memory Specialist', hint: 'LanceDB ANN search (150x-12,500x faster)' },
47
+ { value: 'memory-specialist', label: 'Memory Specialist', hint: 'SQLite-backed ANN search (150x-12,500x faster)' },
48
48
  { value: 'swarm-specialist', label: 'Swarm Specialist', hint: 'Unified coordination engine' },
49
49
  { value: 'performance-engineer', label: 'Performance Engineer', hint: '2.49x-7.47x optimization targets' },
50
50
  { value: 'core-architect', label: 'Core Architect', hint: 'Domain-driven design restructure' },
@@ -58,7 +58,7 @@ export const metricsCommand = {
58
58
  note: totalAgents === 0 ? 'No agents spawned yet. Use: agent spawn -t coder' : undefined,
59
59
  },
60
60
  byType,
61
- performance: { memoryEntries: `${vectorCount} entries`, searchBackend: vectorCount > 0 ? 'LanceDB' : 'none' },
61
+ performance: { memoryEntries: `${vectorCount} entries`, searchBackend: vectorCount > 0 ? 'SQLite' : 'none' },
62
62
  };
63
63
  if (ctx.flags.format === 'json') {
64
64
  output.printJson(metrics);
@@ -5,7 +5,7 @@
5
5
  * github.com/monoes/monomind
6
6
  */
7
7
  import { output } from '../output.js';
8
- import { existsSync, lstatSync, rmSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
8
+ import { existsSync, lstatSync, rmSync, readdirSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, statSync } from 'fs';
9
9
  import { join, dirname } from 'path';
10
10
  /**
11
11
  * Artifact directories and files that monomind/monomind may create
@@ -374,6 +374,58 @@ export const cleanupCommand = {
374
374
  output.writeln();
375
375
  return { success: true, message: `Removed ${removed} stale scratch file(s)`, data: { found: stale, removedCount: removed, removedSize, dryRun } };
376
376
  }
377
+ // Kill background processes before removing their state files
378
+ if (force) {
379
+ // Guard against a stale PID file outliving its process and the OS
380
+ // recycling that PID for an unrelated process — verify the live
381
+ // process actually looks like ours before signaling it.
382
+ const looksLikeOurProcess = (pid) => {
383
+ try {
384
+ const { execSync } = require('child_process');
385
+ const cmd = execSync(`ps -p ${pid} -o command=`, { timeout: 2000, encoding: 'utf-8' }).trim();
386
+ // Covers direct `node ...` spawns as well as the npx fallback in
387
+ // control-start.cjs's findCliPath(), which shows up in `ps` as
388
+ // "npm exec ..." / "npx ..." with no literal "node".
389
+ const looksLikeNode = cmd.includes('node') || cmd.includes('npx') || cmd.includes('npm exec');
390
+ return looksLikeNode && (cmd.includes('monomind') || cmd.includes(cwd));
391
+ }
392
+ catch {
393
+ return false;
394
+ }
395
+ };
396
+ const controlPath = join(cwd, '.monomind', 'control.json');
397
+ try {
398
+ if (existsSync(controlPath) && statSync(controlPath).size <= 4096) {
399
+ const status = JSON.parse(readFileSync(controlPath, 'utf-8'));
400
+ if (status?.pid && Number.isInteger(status.pid) && status.pid > 0 && looksLikeOurProcess(status.pid)) {
401
+ process.kill(status.pid, 'SIGTERM');
402
+ output.writeln(output.info(` Stopped dashboard server (pid ${status.pid})`));
403
+ }
404
+ try {
405
+ unlinkSync(controlPath);
406
+ }
407
+ catch { }
408
+ }
409
+ }
410
+ catch { /* already gone */ }
411
+ for (const pidName of ['monograph.watch.pid', 'monograph-watch.pid']) {
412
+ try {
413
+ const pp = join(cwd, '.monomind', pidName);
414
+ if (!existsSync(pp) || statSync(pp).size > 32)
415
+ continue;
416
+ const pid = parseInt(readFileSync(pp, 'utf-8').trim(), 10);
417
+ if (Number.isInteger(pid) && pid > 0 && looksLikeOurProcess(pid)) {
418
+ process.kill(pid, 'SIGTERM');
419
+ output.writeln(output.info(` Stopped monograph watcher (pid ${pid})`));
420
+ }
421
+ try {
422
+ unlinkSync(pp);
423
+ }
424
+ catch { }
425
+ }
426
+ catch { /* already gone */ }
427
+ }
428
+ }
377
429
  output.writeln();
378
430
  output.writeln(output.bold(dryRun
379
431
  ? 'Monomind Cleanup (dry run)'
@@ -140,7 +140,7 @@ const setCommand = {
140
140
  ],
141
141
  examples: [
142
142
  { command: 'monomind config set swarm.maxAgents 20', description: 'Set max agents' },
143
- { command: 'monomind config set -k memory.backend -v lancedb', description: 'Set memory backend' }
143
+ { command: 'monomind config set -k memory.backend -v sqlite', description: 'Set memory backend' }
144
144
  ],
145
145
  action: async (ctx) => {
146
146
  const key = (ctx.flags.key || ctx.args[0] || '').slice(0, 256);
@@ -400,7 +400,7 @@ export const statuslineCommand = {
400
400
  const mcpColor = mcpStats.enabled > 0 ? c.brightGreen : c.dim;
401
401
  const sizeDisplay = memoryStats.dbSizeKB >= 1024 ? `${(memoryStats.dbSizeKB / 1024).toFixed(1)}MB` : `${memoryStats.dbSizeKB}KB`;
402
402
  const hnswIndicator = memoryStats.hasHnsw ? `${c.brightGreen}⚡${c.reset}` : '';
403
- const line4 = `${c.brightCyan}📊 LanceDB${c.reset} ` +
403
+ const line4 = `${c.brightCyan}📊 SQLite${c.reset} ` +
404
404
  `${c.cyan}Vectors${c.reset} ${vectorColor}●~${memoryStats.vectorCount}${hnswIndicator}${c.reset} ${c.dim}│${c.reset} ` +
405
405
  `${c.cyan}Size${c.reset} ${c.brightWhite}${sizeDisplay}${c.reset} ${c.dim}│${c.reset} ` +
406
406
  `${c.cyan}Tests${c.reset} ${testColor}●${testStats.testFiles}${c.reset} ${c.dim}(~${testStats.testCases} est.)${c.reset} ${c.dim}│${c.reset} ` +
@@ -486,7 +486,7 @@ export const hooksCommand = {
486
486
  output.printList([
487
487
  '🧠 Trajectory + outcome logging',
488
488
  '🎯 Keyword routing + route-outcome measurement',
489
- '🔍 LanceDB integration (ANN vector search)',
489
+ '🔍 SQLite-backed vector search (ANN)',
490
490
  '🎯 32.3% token reduction',
491
491
  '👥 Agent Teams integration (auto task assignment)'
492
492
  ]);
@@ -144,6 +144,7 @@ export const commandsByCategory = {
144
144
  statusCommand,
145
145
  agentCommand,
146
146
  swarmCommand,
147
+ orgCommand,
147
148
  memoryCommand,
148
149
  docCommand,
149
150
  taskCommand,
@@ -156,11 +157,14 @@ export const commandsByCategory = {
156
157
  performanceCommand,
157
158
  guidanceCommand,
158
159
  autopilotCommand,
160
+ designCommand,
159
161
  ],
160
162
  utility: [
161
163
  configCommand,
162
164
  doctorCommand,
163
165
  completionsCommand,
166
+ reportCrashCommand,
167
+ crashReportingCommand,
164
168
  ],
165
169
  analysis: [
166
170
  analyzeCommand,
@@ -60,7 +60,7 @@ export const wizardCommand = {
60
60
  message: 'Select skill sets:',
61
61
  options: [
62
62
  { value: 'core', label: 'Core', hint: 'Swarm, memory skills', selected: true },
63
- { value: 'memory', label: 'Memory (LanceDB)', hint: 'Vector database skills', selected: true },
63
+ { value: 'memory', label: 'Memory (SQLite)', hint: 'Vector database skills', selected: true },
64
64
  { value: 'github', label: 'GitHub', hint: 'GitHub integration skills', selected: true },
65
65
  ],
66
66
  });
@@ -111,8 +111,8 @@ export const wizardCommand = {
111
111
  const memoryBackend = await select({
112
112
  message: 'Select memory backend:',
113
113
  options: [
114
- { value: 'hybrid', label: 'Hybrid', hint: 'SQLite + LanceDB (recommended)' },
115
- { value: 'lancedb', label: 'LanceDB', hint: '150x faster vector search' },
114
+ { value: 'hybrid', label: 'Hybrid', hint: 'SQLite with vector search (recommended)' },
115
+ { value: 'lancedb', label: 'LanceDB (legacy alias)', hint: 'Historical name now backed by SQLite' },
116
116
  { value: 'sqlite', label: 'SQLite', hint: 'Standard SQL storage' },
117
117
  { value: 'memory', label: 'In-Memory', hint: 'Fast but non-persistent' },
118
118
  ],
@@ -94,7 +94,7 @@ const initAction = async (ctx) => {
94
94
  if (!noWatch) {
95
95
  try {
96
96
  const { spawn } = await import('child_process');
97
- const pidFile = path.join(ctx.cwd, '.monomind', 'monograph-watch.pid');
97
+ const pidFile = path.join(ctx.cwd, '.monomind', 'monograph.watch.pid');
98
98
  let alreadyRunning = false;
99
99
  if (fs.existsSync(pidFile) && fs.statSync(pidFile).size <= 32) {
100
100
  const existingPid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
@@ -107,7 +107,7 @@ const initAction = async (ctx) => {
107
107
  }
108
108
  }
109
109
  if (!alreadyRunning) {
110
- const logPath = path.join(ctx.cwd, '.monomind', 'monograph-watch.log');
110
+ const logPath = path.join(ctx.cwd, '.monomind', 'monograph.watch.log');
111
111
  const { openSync } = fs;
112
112
  const logFd = openSync(logPath, 'a');
113
113
  const proc = spawn(process.execPath, [process.argv[1], 'monograph', 'watch'], {
@@ -364,7 +364,7 @@ const toolsCommand = {
364
364
  // Use local tool registry
365
365
  let tools;
366
366
  // Get tools from local registry
367
- const registeredTools = listMCPTools(category);
367
+ const registeredTools = await listMCPTools(category);
368
368
  if (registeredTools.length > 0) {
369
369
  tools = registeredTools.map(tool => ({
370
370
  name: tool.name,
@@ -542,7 +542,7 @@ const execCommand = {
542
542
  }
543
543
  try {
544
544
  // Execute through local MCP tool registry
545
- if (!hasTool(tool)) {
545
+ if (!await hasTool(tool)) {
546
546
  output.printError(`Tool not found: ${tool}`);
547
547
  return { success: false, exitCode: 1 };
548
548
  }
@@ -7,16 +7,16 @@ import { select, confirm } from '../prompt.js';
7
7
  import { configManager } from '../services/config-file-manager.js';
8
8
  // Memory backends (needed for configureCommand)
9
9
  const BACKENDS = [
10
- { value: 'lancedb', label: 'LanceDB', hint: 'Vector database with ANN indexing' },
10
+ { value: 'lancedb', label: 'LanceDB (legacy alias)', hint: 'Historical name now backed by SQLite' },
11
11
  { value: 'sqlite', label: 'SQLite', hint: 'Lightweight local storage' },
12
- { value: 'hybrid', label: 'Hybrid', hint: 'SQLite + LanceDB (recommended)' },
12
+ { value: 'hybrid', label: 'Hybrid', hint: 'SQLite with vector search (recommended)' },
13
13
  { value: 'memory', label: 'In-Memory', hint: 'Fast but non-persistent' }
14
14
  ];
15
15
  // Delete command
16
16
  export const deleteCommand = {
17
17
  name: 'delete',
18
18
  aliases: ['rm'],
19
- description: 'Delete a memory entry (LanceDB, Memory Palace, or knowledge chunk)',
19
+ description: 'Delete a memory entry (SQLite-backed, Memory Palace, or knowledge chunk)',
20
20
  options: [
21
21
  {
22
22
  name: 'key',
@@ -189,16 +189,17 @@ export const statsCommand = {
189
189
  const memoryConfig = configManager.get(ctx.cwd, 'memory');
190
190
  const configuredBackend = memoryConfig?.backend || 'hybrid';
191
191
  // The actual storage engine currently in use for reads/writes is always
192
- // LanceDB (memory-bridge.ts) report the real on-disk path, not the
193
- // configured (but not-yet-wired) backend's path.
192
+ // SQLite (better-sqlite3, sql.js WASM fallback see memory-bridge.ts)
193
+ // report the real on-disk path, not the configured (but not-yet-wired)
194
+ // backend's path.
194
195
  const backendStats = await bridgeGetBackendStats();
195
196
  const realLocation = bridgeGetDbPath();
196
197
  const statsResult = {
197
198
  totalEntries: entries.length,
198
199
  totalSize: totalBytes >= 1048576 ? `${(totalBytes / 1048576).toFixed(1)} MB`
199
200
  : totalBytes >= 1024 ? `${(totalBytes / 1024).toFixed(1)} KB` : `${totalBytes} B`,
200
- version: 'lancedb',
201
- backend: `LanceDB (configured: ${configuredBackend})`,
201
+ version: 'sqlite',
202
+ backend: `SQLite (configured: ${configuredBackend})`,
202
203
  location: realLocation,
203
204
  oldestEntry: times[0] ? new Date(times[0]).toISOString() : null,
204
205
  newestEntry: times.length ? new Date(times[times.length - 1]).toISOString() : null,
@@ -103,7 +103,7 @@ export const listCommand = {
103
103
  // Edit command
104
104
  export const editCommand = {
105
105
  name: 'edit',
106
- description: 'Edit a memory entry (LanceDB, Memory Palace, or knowledge chunk)',
106
+ description: 'Edit a memory entry (SQLite-backed, Memory Palace, or knowledge chunk)',
107
107
  options: [
108
108
  { name: 'key', short: 'k', description: 'Storage key', type: 'string' },
109
109
  { name: 'namespace', short: 'n', description: 'Memory namespace', type: 'string', default: 'default' },
@@ -112,7 +112,7 @@ export const editCommand = {
112
112
  { name: 'id', description: 'Entry ID (palace/knowledge)', type: 'string' }
113
113
  ],
114
114
  examples: [
115
- { command: 'monomind memory edit -k "pattern/auth" --value "updated content"', description: 'Edit LanceDB entry' },
115
+ { command: 'monomind memory edit -k "pattern/auth" --value "updated content"', description: 'Edit SQLite-backed entry' },
116
116
  { command: 'monomind memory edit --source palace --id "abc123" --value "new content"', description: 'Edit Memory Palace drawer' },
117
117
  { command: 'monomind memory edit --source knowledge --id "chunk-42" --value "updated"', description: 'Edit knowledge chunk' }
118
118
  ],
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * CLI Memory Command
3
- * Memory operations for LanceDB integration
3
+ * Memory operations SQLite-backed (better-sqlite3, sql.js WASM fallback)
4
4
  *
5
5
  * Split into sub-modules:
6
6
  * memory-crud.ts — store, retrieve, search
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * CLI Memory Command
3
- * Memory operations for LanceDB integration
3
+ * Memory operations SQLite-backed (better-sqlite3, sql.js WASM fallback)
4
4
  *
5
5
  * Split into sub-modules:
6
6
  * memory-crud.ts — store, retrieve, search
@@ -59,7 +59,7 @@ const initMemoryCommand = {
59
59
  ],
60
60
  examples: [
61
61
  { command: 'monomind memory init', description: 'Initialize hybrid backend with all features' },
62
- { command: 'monomind memory init -b lancedb', description: 'Initialize LanceDB backend' },
62
+ { command: 'monomind memory init -b lancedb', description: 'Initialize memory backend (legacy "lancedb" alias, now SQLite-backed)' },
63
63
  { command: 'monomind memory init -p ./data/memory.db --force', description: 'Reinitialize at custom path' },
64
64
  { command: 'monomind memory init --verbose --verify', description: 'Initialize with full verification' }
65
65
  ],
@@ -264,11 +264,11 @@ export const memoryCommand = {
264
264
  output.printList([
265
265
  `${output.highlight('init')} - Initialize memory database (sql.js)`,
266
266
  `${output.highlight('store')} - Store data in memory`,
267
- `${output.highlight('edit')} - Edit an entry (LanceDB, palace, knowledge)`,
267
+ `${output.highlight('edit')} - Edit an entry (SQLite-backed, palace, knowledge)`,
268
268
  `${output.highlight('retrieve')} - Retrieve data from memory`,
269
269
  `${output.highlight('search')} - Semantic/vector search`,
270
270
  `${output.highlight('list')} - List memory entries`,
271
- `${output.highlight('delete')} - Delete an entry (LanceDB, palace, knowledge)`,
271
+ `${output.highlight('delete')} - Delete an entry (SQLite-backed, palace, knowledge)`,
272
272
  `${output.highlight('templates')} - Show best-practice entry templates`,
273
273
  `${output.highlight('stats')} - Show statistics`,
274
274
  `${output.highlight('configure')} - Configure backend`,
@@ -52,7 +52,7 @@ export const statusCommand = {
52
52
  component: 'Pattern Index',
53
53
  status: hnswStatus.available ? output.success('Ready') : output.dim('Empty'),
54
54
  details: hnswStatus.available
55
- ? `${hnswStatus.entryCount} vectors, ${hnswStatus.dimensions}-dim (ANN via LanceDB)`
55
+ ? `${hnswStatus.entryCount} vectors, ${hnswStatus.dimensions}-dim (ANN via SQLite)`
56
56
  : 'No vectors indexed yet',
57
57
  },
58
58
  {
@@ -554,17 +554,16 @@ const bottleneckCommand = {
554
554
  }
555
555
  catch { /* ok */ }
556
556
  }
557
- const memoryDir = '.monomind/memory';
558
- if (fs.existsSync(memoryDir)) {
559
- try {
560
- const stat = fs.statSync(path.join(memoryDir, 'lance.db')).size ?? 0;
561
- const sizeMB = stat / 1024 / 1024;
562
- if (sizeMB > 100) {
563
- findings.push({ component: 'Memory DB', bottleneck: `LanceDB ${sizeMB.toFixed(0)}MB`, severity: output.warning('Medium'), solution: 'Run: monomind memory compact' });
564
- }
557
+ try {
558
+ const { bridgeGetDbPath } = await import('../memory/memory-bridge.js');
559
+ const dbFile = path.join(bridgeGetDbPath(), 'memory.db');
560
+ const stat = fs.statSync(dbFile).size ?? 0;
561
+ const sizeMB = stat / 1024 / 1024;
562
+ if (sizeMB > 100) {
563
+ findings.push({ component: 'Memory DB', bottleneck: `SQLite ${sizeMB.toFixed(0)}MB`, severity: output.warning('Medium'), solution: 'Run: monomind memory compact' });
565
564
  }
566
- catch { /* no lance.db */ }
567
565
  }
566
+ catch { /* no memory.db yet */ }
568
567
  const network = (perf.network ?? {});
569
568
  if (!network.batching) {
570
569
  findings.push({ component: 'Network', bottleneck: 'No request batching', severity: output.info('Low'), solution: 'Run: monomind performance optimize --apply -t latency' });
@@ -83,7 +83,7 @@ async function getSystemStatus() {
83
83
  const memoryStatus = {
84
84
  entries: 0,
85
85
  size: 0,
86
- backend: 'lancedb',
86
+ backend: 'sqlite',
87
87
  performance: { avgSearchTime: 0, cacheHitRate: 0 },
88
88
  };
89
89
  // Get task status
@@ -507,7 +507,7 @@ const memoryCommand = {
507
507
  const entries = listed?.success ? listed.entries : [];
508
508
  const totalBytes = entries.reduce((s, e) => s + (e.content || '').length, 0);
509
509
  const result = {
510
- backend: 'LanceDB',
510
+ backend: 'SQLite',
511
511
  entries: entries.length,
512
512
  size: totalBytes,
513
513
  };
@@ -289,7 +289,7 @@ const initCommand = {
289
289
  output.writeln(output.dim(' Initializing memory namespace...'));
290
290
  output.writeln(output.dim(' Setting up communication channels...'));
291
291
  if (v1Mode) {
292
- output.writeln(output.dim(' Configuring LanceDB integration (ANN)....'));
292
+ output.writeln(output.dim(' Configuring SQLite-backed vector search (ANN)....'));
293
293
  output.writeln(output.dim(' Initializing keyword routing + outcome measurement...'));
294
294
  }
295
295
  output.writeln();
@@ -310,7 +310,7 @@ export class CLI {
310
310
  this.output.writeln(this.output.bold('V1 FEATURES:'));
311
311
  this.output.printList([
312
312
  '15-agent hierarchical mesh coordination',
313
- 'LanceDB with ANN vector indexing',
313
+ 'SQLite-backed ANN vector indexing',
314
314
  'Keyword routing + route-outcome measurement',
315
315
  'Unified SwarmCoordinator engine',
316
316
  'Event-sourced state management',
@@ -192,7 +192,7 @@ function cliCommandsTable() {
192
192
  | \`init\` | 5 | Project initialization |
193
193
  | \`agent\` | 7 | Agent lifecycle management |
194
194
  | \`swarm\` | 6 | Multi-agent swarm coordination |
195
- | \`memory\` | 12 | LanceDB memory with ANN search |
195
+ | \`memory\` | 12 | SQLite memory with ANN search |
196
196
  | \`task\` | 5 | Task creation and lifecycle |
197
197
  | \`session\` | 6 | Session state management |
198
198
  | \`hooks\` | 29 | Self-learning hooks + 15 background workers${unavailNote(avail.hooks)} |
@@ -371,7 +371,7 @@ function intelligenceSystem() {
371
371
 
372
372
  - **Keyword routing**: Deterministic task→agent routing via \`createKeywordRouter\`
373
373
  - **Outcome measurement**: Route and command outcomes are recorded and scored to surface routing accuracy over time
374
- - **Pattern search**: LanceDB ANN vector search for finding similar past patterns
374
+ - **Pattern search**: SQLite-backed ANN vector search for finding similar past patterns
375
375
 
376
376
  Routing and learning are JS-only — no native engine is required. Outcomes
377
377
  feed back into the recorded metrics so routing quality is measured, not assumed.`;
@@ -1617,7 +1617,7 @@ async function writeCapabilitiesDoc(targetDir, options, result) {
1617
1617
  Monomind is a domain-driven design architecture for multi-agent AI coordination with:
1618
1618
 
1619
1619
  - **15-Agent Swarm Coordination** with hierarchical and mesh topologies
1620
- - **ANN Vector Search** - indexed pattern retrieval via LanceDB
1620
+ - **ANN Vector Search** - indexed pattern retrieval via SQLite (better-sqlite3, sql.js WASM fallback)
1621
1621
  - **Keyword Routing** - deterministic task→agent routing with outcome measurement
1622
1622
  - **Byzantine Fault Tolerance** - Queen-led consensus mechanisms
1623
1623
  - **MCP Server Integration** - Model Context Protocol support
@@ -1712,7 +1712,7 @@ npx monomind@latest swarm monitor
1712
1712
  | \`init\` | 5 | Project initialization |
1713
1713
  | \`agent\` | 7 | Agent lifecycle management |
1714
1714
  | \`swarm\` | 6 | Multi-agent coordination |
1715
- | \`memory\` | 12 | LanceDB with ANN vector search |
1715
+ | \`memory\` | 12 | SQLite with ANN vector search |
1716
1716
  | \`mcp\` | 9 | MCP server management |
1717
1717
  | \`task\` | 5 | Task assignment |
1718
1718
  | \`session\` | 6 | Session persistence |
@@ -1819,7 +1819,7 @@ session start when their output is >6h old; run on demand with
1819
1819
 
1820
1820
  ### Intelligence System
1821
1821
  - **Keyword routing**: Deterministic task→agent routing with outcome measurement
1822
- - **ANN pattern search**: Indexed vector search via LanceDB
1822
+ - **ANN pattern search**: Indexed vector search via SQLite
1823
1823
  - **ReasoningBank**: Stores learned patterns and trajectories for retrieval
1824
1824
  - **Int8 Quantization**: ~4x memory reduction for stored embeddings
1825
1825
 
@@ -1891,7 +1891,7 @@ npx monomind@latest memory init --force
1891
1891
 
1892
1892
  | Metric | Target | Status |
1893
1893
  |--------|--------|--------|
1894
- | ANN Search | Indexed vector search | ✅ Implemented (LanceDB) |
1894
+ | ANN Search | Indexed vector search | ✅ Implemented (SQLite) |
1895
1895
  | Memory Reduction | 50-75% | ✅ Implemented (~4x via Int8 quantization) |
1896
1896
  | Pattern Learning | Recorded + retrievable | ✅ Implemented (ReasoningBank) |
1897
1897
  | MCP Response | <100ms | ✅ Achieved |
@@ -1909,7 +1909,7 @@ npx monomind@latest memory init --force
1909
1909
  ### Integrated Packages
1910
1910
  | Package | Version | Purpose |
1911
1911
  |---------|---------|---------|
1912
- | @lancedb/lancedb | latest | Vector database (ANN search) |
1912
+ | better-sqlite3 (sql.js WASM fallback) | latest | SQLite vector database (ANN search) |
1913
1913
 
1914
1914
  ### Optional Integrations
1915
1915
  | Package | Command |
@@ -1994,7 +1994,8 @@ async function writeClaudeMd(targetDir, options, result) {
1994
1994
  '# Monomind Integration (auto-generated by monomind init)',
1995
1995
  'When working on multi-file tasks or complex features, use ToolSearch to find and invoke monomind MCP tools.',
1996
1996
  'Key tools: memory_store, memory_search, hooks_route, swarm_init, agent_spawn.',
1997
- 'Check system-reminder tags for [INTELLIGENCE] pattern suggestions before starting work.',
1997
+ '**Code navigation**: ALWAYS call `mcp__monomind__monograph_query` BEFORE grep/rg/find for code exploration — it returns file path + line number from a pre-built knowledge graph. Call `mcp__monomind__monograph_suggest` with a task description for multi-file tasks. Only fall back to grep if monograph returns 0 results or the DB is not built.',
1998
+ 'Check system-reminder tags for [INTELLIGENCE] pattern suggestions and [MONOGRAPH] context before starting work.',
1998
1999
  '',
1999
2000
  ].join('\n');
2000
2001
  try {
@@ -2007,6 +2008,12 @@ async function writeClaudeMd(targetDir, options, result) {
2007
2008
  fs.appendFileSync(globalClaudeMd, monomindBlock);
2008
2009
  result.created.files.push('~/.claude/CLAUDE.md (appended monomind block)');
2009
2010
  }
2011
+ else if (!existing.includes('monograph_query')) {
2012
+ // Upgrade existing block to include monograph instructions
2013
+ const updated = existing.replace(/# Monomind Integration[^\n]*\n(?:(?!^#).+\n)*/m, monomindBlock.trimStart() + '\n');
2014
+ atomicWriteFile(globalClaudeMd, updated);
2015
+ result.created.files.push('~/.claude/CLAUDE.md (upgraded monomind block)');
2016
+ }
2010
2017
  }
2011
2018
  else {
2012
2019
  atomicWriteFile(globalClaudeMd, monomindBlock.trimStart());
@@ -487,12 +487,33 @@ export function generateHookHandler() {
487
487
  ' },',
488
488
  '',
489
489
  " 'pre-bash': () => {",
490
- ' // Graph-assisted grep: resolve patterns via monograph DB before grep runs',
491
490
  ' var cmd = (hookInput.toolInput || hookInput.tool_input || {}).command || hookInput.command || "";',
492
491
  ' if (typeof cmd !== "string") cmd = "";',
493
- ' if (!/\\b(?:grep|rg|ag)\\b/.test(cmd)) return;',
492
+ ' var isGrep = /\\b(?:grep|rg|ag|find|fd)\\b/.test(cmd);',
493
+ ' if (!isGrep) return;',
494
+ ' // Graph gate: remind to use monograph before grep',
495
+ ' var dbPath = path.join(process.cwd(), ".monomind", "monograph.db");',
496
+ ' if (fs.existsSync(dbPath)) {',
497
+ ' var stateFile = path.join(process.cwd(), ".monomind", "graph-gate-state.json");',
498
+ ' var gateState = {};',
499
+ ' try { gateState = JSON.parse(fs.readFileSync(stateFile, "utf-8")); } catch(e) {}',
500
+ ' var sessions = (gateState && typeof gateState.sessions === "object") ? gateState.sessions : {};',
501
+ ' var sessId = hookInput.sessionId || hookInput.session_id || "";',
502
+ ' if (sessId) {',
503
+ ' var s = sessions[sessId] || { queried: false, blockedOnce: false };',
504
+ ' if (!s.queried && !s.blockedOnce) {',
505
+ ' s.blockedOnce = true; s.ts = Date.now(); sessions[sessId] = s;',
506
+ ' try { fs.mkdirSync(path.join(process.cwd(), ".monomind"), { recursive: true }); fs.writeFileSync(stateFile, JSON.stringify({ sessions: sessions })); } catch(e) {}',
507
+ ' process.stderr.write(JSON.stringify({ decision: "block", reason: "[graph-gate] Call mcp__monomind__monograph_query or monograph_suggest before grep/find. This blocks once per session." }) + "\\n");',
508
+ ' process.exitCode = 2; return;',
509
+ ' }',
510
+ ' if (!s.queried) {',
511
+ ' console.log("[MONOGRAPH_REMINDER] monograph_query/suggest not yet called this session — try monograph first for faster results.");',
512
+ ' }',
513
+ ' }',
514
+ ' }',
515
+ ' // Graph-assisted grep: resolve patterns via monograph DB',
494
516
  ' try {',
495
- ' var dbPath = path.join(process.cwd(), ".monomind", "monograph.db");',
496
517
  ' if (!fs.existsSync(dbPath)) return;',
497
518
  ' var Database;',
498
519
  ' try { Database = require("better-sqlite3"); } catch(e) {',
@@ -518,6 +539,33 @@ export function generateHookHandler() {
518
539
  ' } catch (e) { /* non-fatal */ }',
519
540
  ' },',
520
541
  '',
542
+ " 'pre-search': () => {",
543
+ ' // Graph gate for Grep/Glob tools (same logic as pre-bash)',
544
+ ' var dbPath = path.join(process.cwd(), ".monomind", "monograph.db");',
545
+ ' if (!fs.existsSync(dbPath)) return;',
546
+ ' var stateFile = path.join(process.cwd(), ".monomind", "graph-gate-state.json");',
547
+ ' var gateState = {};',
548
+ ' try { gateState = JSON.parse(fs.readFileSync(stateFile, "utf-8")); } catch(e) {}',
549
+ ' var sessions = (gateState && typeof gateState.sessions === "object") ? gateState.sessions : {};',
550
+ ' var sessId = hookInput.sessionId || hookInput.session_id || "";',
551
+ ' if (sessId) {',
552
+ ' var s = sessions[sessId] || { queried: false, blockedOnce: false };',
553
+ ' if (!s.queried && !s.blockedOnce) {',
554
+ ' s.blockedOnce = true; s.ts = Date.now(); sessions[sessId] = s;',
555
+ ' try { fs.writeFileSync(stateFile, JSON.stringify({ sessions: sessions })); } catch(e) {}',
556
+ ' process.stderr.write(JSON.stringify({ decision: "block", reason: "[graph-gate] Call mcp__monomind__monograph_query or monograph_suggest before Grep/Glob. This blocks once per session." }) + "\\n");',
557
+ ' process.exitCode = 2; return;',
558
+ ' }',
559
+ ' if (!s.queried) {',
560
+ ' console.log("[MONOGRAPH_REMINDER] monograph_query/suggest not yet called this session.");',
561
+ ' }',
562
+ ' }',
563
+ ' },',
564
+ '',
565
+ " 'pre-write': () => {",
566
+ ' // Stub — real implementation in the full hook-handler.cjs',
567
+ ' },',
568
+ '',
521
569
  " 'post-edit': () => {",
522
570
  ' if (session && session.metric) {',
523
571
  " try { session.metric('edits'); } catch (e) { /* no active session */ }",
@@ -563,6 +611,21 @@ export function generateHookHandler() {
563
611
  ' }',
564
612
  ' },',
565
613
  '',
614
+ " 'post-graph-tool': () => {",
615
+ ' // Clear the graph gate when a real monograph tool is called',
616
+ ' var sessId = hookInput.sessionId || hookInput.session_id || "";',
617
+ ' if (!sessId) return;',
618
+ ' var stateFile = path.join(process.cwd(), ".monomind", "graph-gate-state.json");',
619
+ ' try {',
620
+ ' var gateState = {};',
621
+ ' try { gateState = JSON.parse(fs.readFileSync(stateFile, "utf-8")); } catch(e) {}',
622
+ ' var sessions = (gateState && typeof gateState.sessions === "object") ? gateState.sessions : {};',
623
+ ' var s = sessions[sessId] || { blockedOnce: false };',
624
+ ' s.queried = true; s.ts = Date.now(); sessions[sessId] = s;',
625
+ ' fs.writeFileSync(stateFile, JSON.stringify({ sessions: sessions }));',
626
+ ' } catch(e) {}',
627
+ ' },',
628
+ '',
566
629
  " 'session-end': () => {",
567
630
  ' if (intelligence && intelligence.consolidate) {',
568
631
  ' try {',
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Auto-detects project profile and generates:
5
5
  * 1. .agents/shared_instructions.md — prepended to every agent prompt
6
- * 2. Memory seeds — pre-loaded into LanceDB so agents start with project best practices
6
+ * 2. Memory seeds — pre-loaded into SQLite so agents start with project best practices
7
7
  */
8
8
  import type { InitResult } from './types.js';
9
9
  export interface ProjectProfile {