@monoes/monomindcli 1.10.13 → 1.10.14

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.
@@ -81,11 +81,28 @@ try {
81
81
  // Write lock file; the build process removes it on completion
82
82
  try { fs.writeFileSync(lockPath, String(process.pid)); } catch { /* non-fatal */ }
83
83
 
84
- // Spawn a detached node process to run buildAsync from @monoes/monograph (ESM)
84
+ // Spawn a detached node process to run buildAsync from @monoes/monograph (ESM).
85
+ // After the build, VACUUM the DB if it has >50% bloat (reclaim space from
86
+ // delete/insert churn; opens are ~5x faster on a tight DB).
87
+ const dbPathStr = JSON.stringify(path.join(projectDir, '.monomind', 'monograph.db'));
85
88
  const script = `
86
89
  import { buildAsync } from ${JSON.stringify(pathToFileURL(entryPoint).href)};
87
- import { unlinkSync } from 'fs';
88
- try { await buildAsync(${JSON.stringify(projectDir)}); } finally {
90
+ import { unlinkSync, statSync } from 'fs';
91
+ import { execSync } from 'child_process';
92
+ try {
93
+ await buildAsync(${JSON.stringify(projectDir)});
94
+ // Vacuum if bloat ratio is high — keeps openDb fast over time.
95
+ try {
96
+ const dbPath = ${dbPathStr};
97
+ const fileMB = statSync(dbPath).size / 1024 / 1024;
98
+ const liveMB = parseInt(
99
+ execSync('sqlite3 "' + dbPath + '" "SELECT SUM(pgsize)/1024/1024 FROM dbstat;"',
100
+ { encoding: 'utf-8' }).trim(), 10);
101
+ if (fileMB > 100 && liveMB / fileMB < 0.5) {
102
+ execSync('sqlite3 "' + dbPath + '" "VACUUM;"', { timeout: 120000 });
103
+ }
104
+ } catch (_) {}
105
+ } finally {
89
106
  try { unlinkSync(${JSON.stringify(lockPath)}); } catch {}
90
107
  }`;
91
108
  const child = spawn(process.execPath, ['--input-type=module', '--eval', script], {
@@ -29,14 +29,20 @@ function _requireMonograph() {
29
29
  // Used by route (pre-resolve), pre-search (Grep/Glob redirect), and post-read
30
30
  // (neighbor footer). All calls are best-effort; failures are silent.
31
31
 
32
+ // Memoized at module scope — opening a multi-GB monograph.db can take 7-10s,
33
+ // and we call this 3+ times per route hook. Cache for the lifetime of this
34
+ // hook process. Callers should NOT close the returned handle.
35
+ var _cachedMonographDb = undefined;
32
36
  function _openMonographDb() {
37
+ if (_cachedMonographDb !== undefined) return _cachedMonographDb;
33
38
  try {
34
39
  var dbPath = path.join(CWD, '.monomind', 'monograph.db');
35
- if (!fs.existsSync(dbPath)) return null;
40
+ if (!fs.existsSync(dbPath)) { _cachedMonographDb = null; return null; }
36
41
  var mod = _requireMonograph();
37
- if (!mod || !mod.openDb) return null;
38
- return mod.openDb(dbPath);
39
- } catch (e) { return null; }
42
+ if (!mod || !mod.openDb) { _cachedMonographDb = null; return null; }
43
+ _cachedMonographDb = mod.openDb(dbPath);
44
+ return _cachedMonographDb;
45
+ } catch (e) { _cachedMonographDb = null; return null; }
40
46
  }
41
47
 
42
48
  function getMonographSuggestions(taskText, limit) {
@@ -91,7 +97,7 @@ function getMonographSuggestions(taskText, limit) {
91
97
  }
92
98
  return rows || [];
93
99
  } catch (e) { return []; }
94
- finally { try { db.close(); } catch (_) {} }
100
+ finally { /* db is shared/cached; do not close */ }
95
101
  }
96
102
 
97
103
  function getMonographNeighbors(filePath) {
@@ -119,7 +125,7 @@ function getMonographNeighbors(filePath) {
119
125
 
120
126
  return { imports: imports, importedBy: importedBy };
121
127
  } catch (e) { return null; }
122
- finally { try { db.close(); } catch (_) {} }
128
+ finally { /* db is shared/cached; do not close */ }
123
129
  }
124
130
 
125
131
  // Rough per-event token + USD cost estimates. Tuned to Sonnet input pricing
@@ -184,7 +190,7 @@ function _injectCompactGraphMap() {
184
190
  }
185
191
  console.log(' Use mcp__monomind__monograph_suggest first when navigating.');
186
192
  }
187
- } finally { try { db.close(); } catch (_) {} }
193
+ } finally { /* db is shared/cached; do not close */ }
188
194
  } catch (e) {}
189
195
  }
190
196
 
@@ -264,7 +270,7 @@ function _findAffectedTests(filePath) {
264
270
  ).all(filePath, rel);
265
271
  return rows.map(function(r) { return r.file_path; });
266
272
  } catch (e) { return []; }
267
- finally { try { db.close(); } catch (_) {} }
273
+ finally { /* db is shared/cached; do not close */ }
268
274
  }
269
275
 
270
276
  // ── Hook latency tracking ─────────────────────────────────────────────────────
@@ -629,9 +635,8 @@ function _autoIndexKnowledge(knowledgeDir) {
629
635
 
630
636
  if (fs.existsSync(mgDbPath2)) {
631
637
  try {
632
- var mgMod2 = _requireMonograph();
633
- if (mgMod2 && mgMod2.openDb) {
634
- var sumDb = mgMod2.openDb(mgDbPath2);
638
+ var sumDb = _openMonographDb();
639
+ if (sumDb) {
635
640
  try {
636
641
  var nodeC = sumDb.prepare('SELECT COUNT(*) AS c FROM nodes').get().c;
637
642
  var edgeC = sumDb.prepare('SELECT COUNT(*) AS c FROM edges').get().c;
@@ -661,9 +666,7 @@ function _autoIndexKnowledge(knowledgeDir) {
661
666
  ' mcp__monomind__monograph_impact({ name: "<file>" }) — upstream + downstream blast radius',
662
667
  ].join('\n');
663
668
  summaryMeta = { label: 'monograph-graph-summary', source: 'monograph.db', nodes: nodeC, edges: edgeC };
664
- } finally {
665
- try { sumDb.close(); } catch (_) {}
666
- }
669
+ } catch (e) { /* keep summaryText if partial */ }
667
670
  }
668
671
  } catch (e) { /* fall through to legacy */ }
669
672
  }
@@ -830,11 +833,22 @@ const handlers = {
830
833
  var output = [];
831
834
  output.push('[INFO] Routing task: ' + (prompt.substring(0, 80) || '(no prompt)'));
832
835
  output.push('');
833
- output.push('+------------- monomind | Primary Recommendation --------------+');
834
- output.push('| Agent: ' + (result.agent || 'unknown').substring(0, 54).padEnd(54) + '|');
835
- output.push('| Confidence: ' + ((result.confidence != null ? (result.confidence * 100).toFixed(1) : '?') + '%').padEnd(49) + '|');
836
- output.push('| Reason: ' + (result.reason || '').substring(0, 53).padEnd(53) + '|');
837
- output.push('+--------------------------------------------------------------+');
836
+ // Suppress the agent recommendation panel for low-confidence routes on
837
+ // short prompts the recommendation is almost always wrong (e.g.
838
+ // "what else can we do" marketing China E-Commerce). Saves ~150
839
+ // tokens per prompt. Skill matches and specific agents still render
840
+ // below when confidence is decent.
841
+ var conf = result.confidence != null ? result.confidence : 0;
842
+ var promptShort = (prompt || '').trim().length < 60;
843
+ var lowConf = conf < 0.70;
844
+ var suppressPanel = lowConf && promptShort;
845
+ if (!suppressPanel) {
846
+ output.push('+------------- monomind | Primary Recommendation --------------+');
847
+ output.push('| Agent: ' + (result.agent || 'unknown').substring(0, 54).padEnd(54) + '|');
848
+ output.push('| Confidence: ' + ((result.confidence != null ? (result.confidence * 100).toFixed(1) : '?') + '%').padEnd(49) + '|');
849
+ output.push('| Reason: ' + (result.reason || '').substring(0, 53).padEnd(53) + '|');
850
+ output.push('+--------------------------------------------------------------+');
851
+ }
838
852
 
839
853
  // ── Persist routing result for statusline display ─────────────
840
854
  try {
@@ -913,8 +927,9 @@ const handlers = {
913
927
  }
914
928
 
915
929
  // ── Specific agent panel ──────────────────────────────────────────────────
930
+ // Skip entirely on suppressed (low-confidence + short) prompts.
916
931
  var specificAgents = result.specificAgents || [];
917
- if (specificAgents.length > 0) {
932
+ if (specificAgents.length > 0 && !suppressPanel) {
918
933
  output.push('');
919
934
  var saHdr = '------- Specific Agents (' + specificAgents.length + ' available) ';
920
935
  output.push('+' + saHdr + '-'.repeat(Math.max(1, 62 - saHdr.length)) + '+');
@@ -934,7 +949,7 @@ const handlers = {
934
949
  // ── Specialist agents (non-dev domain) — only shown when specificAgents panel wasn't shown ──
935
950
  var extras = result.extrasMatches || [];
936
951
  var specificAgentsShown = (result.specificAgents || []).length > 0;
937
- if (extras.length > 0 && !specificAgentsShown) {
952
+ if (extras.length > 0 && !specificAgentsShown && !suppressPanel) {
938
953
  output.push('');
939
954
  var spHdr = '------- Specialist Agents (' + extras.length + ' matched) ';
940
955
  output.push('+' + spHdr + '-'.repeat(Math.max(1, 62 - spHdr.length)) + '+');
@@ -1007,14 +1022,9 @@ const handlers = {
1007
1022
  var nodeCount = 0;
1008
1023
  if (fs.existsSync(monographDb)) {
1009
1024
  try {
1010
- var mgMod = _requireMonograph();
1011
- if (mgMod && mgMod.openDb) {
1012
- var hintDb = mgMod.openDb(monographDb);
1013
- try {
1014
- nodeCount = hintDb.prepare('SELECT COUNT(*) AS c FROM nodes').get().c;
1015
- } finally {
1016
- try { hintDb.close(); } catch (_) {}
1017
- }
1025
+ var hintDb = _openMonographDb();
1026
+ if (hintDb) {
1027
+ nodeCount = hintDb.prepare('SELECT COUNT(*) AS c FROM nodes').get().c;
1018
1028
  }
1019
1029
  } catch (e) { /* ignore — fall back to legacy */ }
1020
1030
  }
@@ -1451,10 +1461,8 @@ const handlers = {
1451
1461
  try {
1452
1462
  var mgDbPath = path.join(CWD, '.monomind', 'monograph.db');
1453
1463
  if (fs.existsSync(mgDbPath)) {
1454
- var mgMod = null;
1455
- mgMod = _requireMonograph();
1456
- if (mgMod && mgMod.openDb) {
1457
- var mgDb = mgMod.openDb(mgDbPath);
1464
+ var mgDb = _openMonographDb();
1465
+ if (mgDb) {
1458
1466
  try {
1459
1467
  var mgNodeCount = mgDb.prepare('SELECT COUNT(*) AS c FROM nodes').get().c;
1460
1468
  var mgEdgeCount = mgDb.prepare('SELECT COUNT(*) AS c FROM edges').get().c;
@@ -1493,7 +1501,7 @@ const handlers = {
1493
1501
  fs.writeFileSync(mgChunksFile, mgExisting.join('\n') + '\n');
1494
1502
  } catch(e) {}
1495
1503
  }
1496
- } finally { if (mgMod.closeDb) mgMod.closeDb(mgDb); }
1504
+ } catch(e) { /* non-fatal */ }
1497
1505
  }
1498
1506
  }
1499
1507
  } catch(e) { /* non-fatal */ }
@@ -2226,7 +2234,7 @@ const handlers = {
2226
2234
  } catch (_) {}
2227
2235
  console.log(' Use mcp__monomind__monograph_suggest / monograph_query in this subagent before grepping.');
2228
2236
  }
2229
- } finally { try { subDb.close(); } catch (_) {} }
2237
+ } catch (e) { /* non-fatal */ }
2230
2238
  }
2231
2239
  } catch (e) { /* non-fatal */ }
2232
2240
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monoes/monomindcli",
3
- "version": "1.10.13",
3
+ "version": "1.10.14",
4
4
  "type": "module",
5
5
  "description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",