@monoes/monomindcli 1.10.8 → 1.10.10

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.
@@ -25,6 +25,178 @@ function _requireMonograph() {
25
25
  return null;
26
26
  }
27
27
 
28
+ // ── Monograph LLM-context helpers ──────────────────────────────────────────────
29
+ // Used by route (pre-resolve), pre-search (Grep/Glob redirect), and post-read
30
+ // (neighbor footer). All calls are best-effort; failures are silent.
31
+
32
+ function _openMonographDb() {
33
+ try {
34
+ var dbPath = path.join(CWD, '.monomind', 'monograph.db');
35
+ if (!fs.existsSync(dbPath)) return null;
36
+ var mod = _requireMonograph();
37
+ if (!mod || !mod.openDb) return null;
38
+ return mod.openDb(dbPath);
39
+ } catch (e) { return null; }
40
+ }
41
+
42
+ function getMonographSuggestions(taskText, limit) {
43
+ if (!taskText || typeof taskText !== "string") return [];
44
+ var db = _openMonographDb();
45
+ if (!db) return [];
46
+ try {
47
+ var words = String(taskText).toLowerCase().match(/[a-z][a-z0-9_-]{3,}/g) || [];
48
+ var stop = { "this":1,"that":1,"with":1,"from":1,"have":1,"into":1,"their":1,"what":1,"when":1,"where":1,"which":1,"should":1,"would":1,"could":1,"make":1,"just":1,"also":1,"them":1,"they":1,"will":1,"been":1,"were":1,"because":1,"about":1,"does":1,"work":1,"else":1,"more":1,"some":1,"like":1,"need":1,"want":1,"used":1,"using":1,"please":1,"thanks":1,"good":1,"great":1,"nice":1,"thing":1,"things":1,"better":1,"again":1,"first":1,"then":1,"only":1,"even":1 };
49
+ var uniq = {};
50
+ for (var i = 0; i < words.length; i++) if (!stop[words[i]]) uniq[words[i]] = 1;
51
+ var keys = Object.keys(uniq).slice(0, 8);
52
+ // Smart filter: free-form prompts need ≥2 content words to avoid noise.
53
+ // Single-word inputs are allowed only when they look like a symbol/search
54
+ // (entire string is ≤30 chars and contains letters+separators only).
55
+ var isSymbolLookup = taskText.length <= 30 && /^[a-zA-Z0-9_\-./:]+$/.test(taskText.trim());
56
+ if (keys.length === 0) return [];
57
+ if (keys.length < 2 && !isSymbolLookup) return [];
58
+
59
+ var ftsQuery = keys.map(function(k){ return '"' + k.replace(/"/g, "") + '"'; }).join(" OR ");
60
+ var lim = Math.max(1, limit || 5);
61
+ var rows = [];
62
+ try {
63
+ // BM25 ranks better than degree for keyword relevance; tie-break by deg.
64
+ // File/Function/Class outrank Section so navigable nodes win.
65
+ rows = db.prepare(
66
+ "SELECT n.id, n.name, n.label, n.file_path AS file, " +
67
+ "bm25(nodes_fts) AS bm25_score, " +
68
+ "(SELECT COUNT(*) FROM edges WHERE source_id=n.id OR target_id=n.id) AS deg, " +
69
+ "CASE n.label WHEN 'File' THEN 3 WHEN 'Function' THEN 3 WHEN 'Class' THEN 3 " +
70
+ " WHEN 'Method' THEN 2 WHEN 'Interface' THEN 2 ELSE 1 END AS label_rank " +
71
+ "FROM nodes_fts f JOIN nodes n ON f.rowid = n.rowid " +
72
+ "WHERE nodes_fts MATCH ? AND n.file_path IS NOT NULL AND n.file_path != '' " +
73
+ "AND n.label NOT IN ('Concept') " +
74
+ "ORDER BY label_rank DESC, bm25_score ASC, deg DESC LIMIT ?"
75
+ ).all(ftsQuery, lim);
76
+ } catch (e) {
77
+ var likeFrag = keys.map(function(){ return "lower(n.name) LIKE ?"; }).join(" OR ");
78
+ var likeArgs = keys.map(function(k){ return "%" + k + "%"; });
79
+ var stmt = db.prepare(
80
+ "SELECT n.id, n.name, n.label, n.file_path AS file, " +
81
+ "(SELECT COUNT(*) FROM edges WHERE source_id=n.id OR target_id=n.id) AS deg " +
82
+ "FROM nodes n WHERE (" + likeFrag + ") AND n.file_path IS NOT NULL AND n.file_path != '' " +
83
+ "AND n.label NOT IN ('Concept') " +
84
+ "ORDER BY deg DESC LIMIT ?"
85
+ );
86
+ rows = stmt.all.apply(stmt, likeArgs.concat([lim]));
87
+ }
88
+ return rows || [];
89
+ } catch (e) { return []; }
90
+ finally { try { db.close(); } catch (_) {} }
91
+ }
92
+
93
+ function getMonographNeighbors(filePath) {
94
+ if (!filePath) return null;
95
+ var db = _openMonographDb();
96
+ if (!db) return null;
97
+ try {
98
+ var rel = filePath;
99
+ if (filePath.indexOf(CWD) === 0) rel = filePath.slice(CWD.length + 1);
100
+ var node = db.prepare(
101
+ "SELECT id, name FROM nodes WHERE label='File' AND (file_path=? OR file_path=? OR name=? OR name=?) LIMIT 1"
102
+ ).get(filePath, rel, filePath, rel);
103
+ if (!node) return null;
104
+
105
+ var imports = db.prepare(
106
+ "SELECT DISTINCT n.name FROM edges e JOIN nodes n ON e.target_id = n.id " +
107
+ "WHERE e.source_id=? AND e.relation IN ('IMPORTS','CALLS','DEPENDS_ON','CONTAINS','DEFINES') " +
108
+ "AND n.file_path IS NOT NULL AND n.file_path != '' LIMIT 6"
109
+ ).all(node.id).map(function(r){ return r.name; });
110
+ var importedBy = db.prepare(
111
+ "SELECT DISTINCT n.name FROM edges e JOIN nodes n ON e.source_id = n.id " +
112
+ "WHERE e.target_id=? AND e.relation IN ('IMPORTS','CALLS','DEPENDS_ON','CONTAINS','DEFINES') " +
113
+ "AND n.file_path IS NOT NULL AND n.file_path != '' LIMIT 6"
114
+ ).all(node.id).map(function(r){ return r.name; });
115
+
116
+ return { imports: imports, importedBy: importedBy };
117
+ } catch (e) { return null; }
118
+ finally { try { db.close(); } catch (_) {} }
119
+ }
120
+
121
+ // Rough per-event token + USD cost estimates. Tuned to Sonnet input pricing
122
+ // ($3/M tokens) — adjust if needed. Used by the statusline to surface savings.
123
+ var _TOKEN_PER_EVENT = {
124
+ monograph_call: 300, // typical monograph_query result size
125
+ grep_call: 2000, // typical Grep tool output across many files
126
+ glob_call: 800,
127
+ bash_grep_call: 2000,
128
+ bash_find_call: 800,
129
+ };
130
+ var _DOLLAR_PER_1M_TOKENS = 3.0;
131
+
132
+ function _recordGraphTelemetry(event) {
133
+ try {
134
+ var metricsDir = path.join(CWD, ".monomind", "metrics");
135
+ var f = path.join(metricsDir, "graph-usage.json");
136
+ fs.mkdirSync(metricsDir, { recursive: true });
137
+ var d = {};
138
+ try { d = JSON.parse(fs.readFileSync(f, "utf-8")); } catch (e) {}
139
+ if (typeof d !== "object" || d === null) d = {};
140
+ d[event] = (d[event] || 0) + 1;
141
+
142
+ // Token-saved estimator: each monograph_call avoids a grep equivalent
143
+ // (~2000 tokens) at a cost of ~300 tokens — net ~1700 saved.
144
+ if (event === 'monograph_call') {
145
+ var saved = (_TOKEN_PER_EVENT.grep_call - _TOKEN_PER_EVENT.monograph_call);
146
+ d.tokens_saved = (d.tokens_saved || 0) + saved;
147
+ d.dollars_saved = ((d.tokens_saved / 1000000) * _DOLLAR_PER_1M_TOKENS);
148
+ }
149
+ // Each unprompted grep/bash_grep "wastes" the same amount vs the graph alternative.
150
+ if (event === 'grep_call' || event === 'bash_grep_call') {
151
+ var wasted = (_TOKEN_PER_EVENT.grep_call - _TOKEN_PER_EVENT.monograph_call);
152
+ d.tokens_wasted = (d.tokens_wasted || 0) + wasted;
153
+ }
154
+
155
+ d.lastUpdated = Date.now();
156
+ fs.writeFileSync(f, JSON.stringify(d));
157
+ } catch (e) { /* non-fatal */ }
158
+ }
159
+
160
+ // Auto-rebuild the monograph after N writes — graph staleness during heavy
161
+ // editing is the main reason suggestions go cold. Triggered by post-edit.
162
+ function _maybeRebuildMonograph() {
163
+ try {
164
+ var metricsDir = path.join(CWD, ".monomind", "metrics");
165
+ fs.mkdirSync(metricsDir, { recursive: true });
166
+ var f = path.join(metricsDir, "graph-rebuild.json");
167
+ var d = {};
168
+ try { d = JSON.parse(fs.readFileSync(f, "utf-8")); } catch (_) {}
169
+ if (typeof d !== "object" || d === null) d = {};
170
+ d.writesSinceRebuild = (d.writesSinceRebuild || 0) + 1;
171
+ d.lastWriteAt = Date.now();
172
+ var THRESHOLD = 20;
173
+ var MIN_INTERVAL_MS = 5 * 60 * 1000; // never more often than every 5 min
174
+ var dueByCount = d.writesSinceRebuild >= THRESHOLD;
175
+ var dueByTime = !d.lastRebuildAt || (Date.now() - d.lastRebuildAt) > MIN_INTERVAL_MS;
176
+ if (dueByCount && dueByTime) {
177
+ // Reset counter immediately so concurrent post-edits don't all fire.
178
+ d.writesSinceRebuild = 0;
179
+ d.lastRebuildAt = Date.now();
180
+ fs.writeFileSync(f, JSON.stringify(d));
181
+ // Fire-and-forget background freshen script (same one used by SessionStart).
182
+ try {
183
+ var freshenScript = path.join(CWD, '.claude', 'helpers', 'graphify-freshen.cjs');
184
+ if (fs.existsSync(freshenScript)) {
185
+ var spawn = require('child_process').spawn;
186
+ var child = spawn(process.execPath, [freshenScript], {
187
+ detached: true,
188
+ stdio: 'ignore',
189
+ cwd: CWD,
190
+ });
191
+ child.unref();
192
+ }
193
+ } catch (_) {}
194
+ } else {
195
+ fs.writeFileSync(f, JSON.stringify(d));
196
+ }
197
+ } catch (e) { /* non-fatal */ }
198
+ }
199
+
28
200
  function safeRequire(modulePath) {
29
201
  try {
30
202
  if (fs.existsSync(modulePath)) {
@@ -691,7 +863,21 @@ const handlers = {
691
863
  } catch (e) { /* ignore */ }
692
864
  }
693
865
  if (nodeCount > 100) {
694
- console.log('\n[MONOGRAPH] ' + nodeCount + ' nodes indexed. For this task, call mcp__monomind__monograph_suggest first to find the right files without grepping.');
866
+ // Pre-resolve top-5 relevant files for the user's prompt the LLM
867
+ // sees the answer inline instead of being told to call a tool.
868
+ var suggestions = getMonographSuggestions(prompt, 5);
869
+ if (suggestions.length > 0) {
870
+ console.log('\n[MONOGRAPH] ' + nodeCount + ' nodes indexed. Top files for this task (pre-resolved from graph):');
871
+ for (var si = 0; si < suggestions.length; si++) {
872
+ var s = suggestions[si];
873
+ console.log(' · ' + s.name + ' [' + s.label + '] — ' + (s.file || '') + ' (deg ' + s.deg + ')');
874
+ }
875
+ console.log(' Use mcp__monomind__monograph_query / monograph_impact for deeper drill-down.');
876
+ _recordGraphTelemetry('preresolve_hit');
877
+ } else {
878
+ console.log('\n[MONOGRAPH] ' + nodeCount + ' nodes indexed. Call mcp__monomind__monograph_suggest first to find relevant files without grepping.');
879
+ _recordGraphTelemetry('preresolve_miss');
880
+ }
695
881
  }
696
882
  } catch(e) {}
697
883
 
@@ -777,7 +963,8 @@ const handlers = {
777
963
 
778
964
  'pre-bash': () => {
779
965
  var _rawCmd = hookInput.command || prompt;
780
- var cmd = (typeof _rawCmd === 'string' ? _rawCmd : String(_rawCmd || '')).toLowerCase();
966
+ var rawCmdStr = (typeof _rawCmd === 'string' ? _rawCmd : String(_rawCmd || ''));
967
+ var cmd = rawCmdStr.toLowerCase();
781
968
  var dangerous = ['rm -rf /', 'rm -rf/', 'format c:', 'del /s /q c:\\', ':(){:|:&};:'];
782
969
  for (var i = 0; i < dangerous.length; i++) {
783
970
  if (cmd.includes(dangerous[i])) {
@@ -785,9 +972,85 @@ const handlers = {
785
972
  process.exit(1);
786
973
  }
787
974
  }
975
+
976
+ // Intercept Bash-side grep/rg/find/ag — close the loophole where LLM
977
+ // bypasses the Grep tool by shelling out. Same monograph hint shape as pre-search.
978
+ try {
979
+ // Match: grep <flags> <pattern>, rg <flags> <pattern>, ag <pattern>, find . -name <pattern>
980
+ var grepMatch = rawCmdStr.match(/\b(?:grep|rg|ag)\b(?:\s+-[a-zA-Z]+)*\s+(?:"([^"]+)"|'([^']+)'|([^\s|;&<>]+))/);
981
+ var findMatch = rawCmdStr.match(/\bfind\b.*?-name\s+(?:"([^"]+)"|'([^']+)'|([^\s|;&<>]+))/);
982
+ var pattern = '';
983
+ if (grepMatch) {
984
+ pattern = grepMatch[1] || grepMatch[2] || grepMatch[3] || '';
985
+ _recordGraphTelemetry('bash_grep_call');
986
+ } else if (findMatch) {
987
+ pattern = findMatch[1] || findMatch[2] || findMatch[3] || '';
988
+ _recordGraphTelemetry('bash_find_call');
989
+ }
990
+ if (pattern && pattern.length >= 3) {
991
+ var clean = pattern.replace(/[\\^$.*+?()\[\]{}|]/g, ' ').trim();
992
+ if (clean.length >= 3) {
993
+ var hits = getMonographSuggestions(clean, 5);
994
+ if (hits.length > 0) {
995
+ console.log('[MONOGRAPH_HIT] Graph has ' + hits.length + ' file(s) for "' + clean.slice(0, 40) + '" — consider monograph_query instead of shell grep:');
996
+ for (var j = 0; j < hits.length; j++) {
997
+ var h = hits[j];
998
+ console.log(' · ' + h.name + ' [' + h.label + '] — ' + (h.file || ''));
999
+ }
1000
+ }
1001
+ }
1002
+ }
1003
+ } catch (e) { /* non-fatal */ }
1004
+
788
1005
  console.log('[OK] Command validated');
789
1006
  },
790
1007
 
1008
+ // Intercept Grep/Glob: run monograph_query on the same pattern first and
1009
+ // surface graph hits so the LLM can read file:line directly without paying
1010
+ // for a full Grep scan when the graph already knows the answer.
1011
+ 'pre-search': () => {
1012
+ try {
1013
+ _recordGraphTelemetry(toolName === 'Grep' ? 'grep_call' : 'glob_call');
1014
+ var pattern = toolInput.pattern || toolInput.path || '';
1015
+ if (typeof pattern !== 'string' || pattern.length < 3) return;
1016
+ var clean = pattern.replace(/[\\^$.*+?()\[\]{}|]/g, ' ').trim();
1017
+ if (clean.length < 3) return;
1018
+ var suggestions = getMonographSuggestions(clean, 5);
1019
+ if (suggestions.length === 0) return;
1020
+ console.log('[MONOGRAPH_HIT] Graph already knows ' + suggestions.length + ' file(s) matching "' + clean.slice(0, 40) + '":');
1021
+ for (var i = 0; i < suggestions.length; i++) {
1022
+ var s = suggestions[i];
1023
+ console.log(' · ' + s.name + ' [' + s.label + '] — ' + (s.file || '') + ' (deg ' + s.deg + ')');
1024
+ }
1025
+ console.log(' Prefer mcp__monomind__monograph_query for symbol lookup (file:line, no scan).');
1026
+ } catch (e) { /* non-fatal */ }
1027
+ },
1028
+
1029
+ // After Read: append a graph neighbor footer so the LLM gets free
1030
+ // architectural context — what imports this file and what it imports.
1031
+ 'post-read': () => {
1032
+ try {
1033
+ var filePath = toolInput.file_path || toolInput.path || '';
1034
+ if (!filePath || typeof filePath !== 'string') return;
1035
+ var n = getMonographNeighbors(filePath);
1036
+ if (!n) return;
1037
+ var parts = [];
1038
+ if (n.importedBy.length > 0) parts.push('imported-by: ' + n.importedBy.slice(0, 4).join(', '));
1039
+ if (n.imports.length > 0) parts.push('imports: ' + n.imports.slice(0, 4).join(', '));
1040
+ if (parts.length === 0) return;
1041
+ console.log('[MONOGRAPH_NEIGHBORS] ' + parts.join(' · '));
1042
+ } catch (e) { /* non-fatal */ }
1043
+ },
1044
+
1045
+ // PostToolUse for monograph_* — increment graph usage counter for telemetry.
1046
+ 'post-graph-tool': () => {
1047
+ try {
1048
+ if (toolName && toolName.indexOf('monograph_') !== -1) {
1049
+ _recordGraphTelemetry('monograph_call');
1050
+ }
1051
+ } catch (e) {}
1052
+ },
1053
+
791
1054
  'post-edit': async () => {
792
1055
  if (session && session.metric) {
793
1056
  try { session.metric('edits'); } catch (e) { /* no active session */ }
@@ -799,6 +1062,8 @@ const handlers = {
799
1062
  intelligence.recordEdit(file);
800
1063
  } catch (e) { /* non-fatal */ }
801
1064
  }
1065
+ // Increment write counter and rebuild monograph when threshold hit.
1066
+ _maybeRebuildMonograph();
802
1067
  // ── Security-Sensitive File Auto-Alert ────────────────────────────────
803
1068
  // When editing auth, security, crypto, or env-related files, flag it
804
1069
  try {
@@ -998,9 +1263,12 @@ const handlers = {
998
1263
  var mgNodeCount = mgDb.prepare('SELECT COUNT(*) AS c FROM nodes').get().c;
999
1264
  var mgEdgeCount = mgDb.prepare('SELECT COUNT(*) AS c FROM edges').get().c;
1000
1265
  var mgGodNodes = mgDb.prepare(
1001
- 'SELECT n.name, n.label, n.file_path, ' +
1002
- '(SELECT COUNT(*) FROM edges WHERE source_id=n.id OR target_id=n.id) AS deg ' +
1003
- 'FROM nodes n ORDER BY deg DESC LIMIT 12'
1266
+ "SELECT n.name, n.label, n.file_path, " +
1267
+ "(SELECT COUNT(*) FROM edges WHERE source_id=n.id OR target_id=n.id) AS deg " +
1268
+ "FROM nodes n " +
1269
+ "WHERE n.label NOT IN ('Concept') " +
1270
+ "AND n.file_path IS NOT NULL AND n.file_path != '' " +
1271
+ "ORDER BY deg DESC LIMIT 12"
1004
1272
  ).all();
1005
1273
  if (mgGodNodes.length > 0) {
1006
1274
  var mgGodStr = mgGodNodes.slice(0, 8).map(function(n) {
@@ -1726,6 +1994,47 @@ const handlers = {
1726
1994
  'utf-8'
1727
1995
  );
1728
1996
  } catch (e) { /* non-fatal — never block a subagent from starting */ }
1997
+
1998
+ // Subagent context inheritance — inject graph god nodes + parent's last
1999
+ // pre-resolved suggestions so the spawned agent inherits spatial map
2000
+ // instead of starting blind.
2001
+ try {
2002
+ var subDb = _openMonographDb();
2003
+ if (subDb) {
2004
+ try {
2005
+ var godRows = subDb.prepare(
2006
+ "SELECT n.name, n.label, n.file_path AS file, " +
2007
+ "(SELECT COUNT(*) FROM edges WHERE source_id=n.id OR target_id=n.id) AS deg " +
2008
+ "FROM nodes n " +
2009
+ "WHERE n.label NOT IN ('Concept') AND n.file_path IS NOT NULL AND n.file_path != '' " +
2010
+ "ORDER BY deg DESC LIMIT 5"
2011
+ ).all();
2012
+ if (godRows.length > 0) {
2013
+ console.log('[MONOGRAPH_SUBAGENT_CTX] Graph map inherited from parent:');
2014
+ for (var gi = 0; gi < godRows.length; gi++) {
2015
+ var gr = godRows[gi];
2016
+ console.log(' · ' + gr.name + ' [' + gr.label + '] — ' + (gr.file || '') + ' (deg ' + gr.deg + ')');
2017
+ }
2018
+ // Also forward parent's last routing suggestion text if any
2019
+ try {
2020
+ var subAgentDesc = hookInput.description || hookInput.prompt_description || '';
2021
+ if (subAgentDesc && subAgentDesc.length > 8) {
2022
+ var subHints = getMonographSuggestions(subAgentDesc, 3);
2023
+ if (subHints.length > 0) {
2024
+ console.log(' Top files for this subagent task:');
2025
+ for (var si2 = 0; si2 < subHints.length; si2++) {
2026
+ var sh = subHints[si2];
2027
+ console.log(' · ' + sh.name + ' [' + sh.label + '] — ' + (sh.file || ''));
2028
+ }
2029
+ }
2030
+ }
2031
+ } catch (_) {}
2032
+ console.log(' Use mcp__monomind__monograph_suggest / monograph_query in this subagent before grepping.');
2033
+ }
2034
+ } finally { try { subDb.close(); } catch (_) {} }
2035
+ }
2036
+ } catch (e) { /* non-fatal */ }
2037
+
1729
2038
  console.log('[OK] Agent registered');
1730
2039
  },
1731
2040
 
@@ -696,6 +696,26 @@ function getGraphifyStats() {
696
696
  return { nodes: 0, edges: 0, exists: false };
697
697
  }
698
698
 
699
+ // Graph usage telemetry — ratio of monograph_* vs Grep/Glob, plus $ saved
700
+ function getGraphUsage() {
701
+ const usagePath = path.join(CWD, '.monomind', 'metrics', 'graph-usage.json');
702
+ try {
703
+ if (!fs.existsSync(usagePath)) return null;
704
+ const d = JSON.parse(fs.readFileSync(usagePath, 'utf-8'));
705
+ const monograph = d.monograph_call || 0;
706
+ const search = (d.grep_call || 0) + (d.glob_call || 0)
707
+ + (d.bash_grep_call || 0) + (d.bash_find_call || 0);
708
+ const total = monograph + search;
709
+ if (total === 0) return null;
710
+ return {
711
+ monograph,
712
+ search,
713
+ pct: Math.round((monograph / total) * 100),
714
+ dollarsSaved: d.dollars_saved || 0,
715
+ };
716
+ } catch { return null; }
717
+ }
718
+
699
719
  // Graph freshness — compare graph build time against most recent commit
700
720
  // Returns: { commitsBehind, stale } where stale = >5 commits or never built
701
721
  function getGraphFreshness() {
@@ -1239,7 +1259,18 @@ function generateDashboard() {
1239
1259
  loopStr = `${x.slate}🔄 no active loops${x.reset}`;
1240
1260
  }
1241
1261
 
1242
- lines.push(`${x.purple}🤖 AGENT${x.reset} ${agentStr} ${DIV} ${loopStr}`);
1262
+ // Graph usage ratio + $ saved — show only when there's data
1263
+ const usage = getGraphUsage();
1264
+ let usageStr = '';
1265
+ if (usage) {
1266
+ const col = usage.pct >= 40 ? x.green : usage.pct >= 15 ? x.gold : x.coral;
1267
+ const saved = usage.dollarsSaved > 0
1268
+ ? ` ${x.green}💰 +$${usage.dollarsSaved.toFixed(2)}${x.reset}`
1269
+ : '';
1270
+ usageStr = ` ${DIV} ${col}📊 graph ${usage.pct}%${x.reset}${x.slate} · grep ${100 - usage.pct}%${x.reset}${saved}`;
1271
+ }
1272
+
1273
+ lines.push(`${x.purple}🤖 AGENT${x.reset} ${agentStr} ${DIV} ${loopStr}${usageStr}`);
1243
1274
  lines.push(SEP);
1244
1275
 
1245
1276
  // ── Row 2: Graph freshness + Pending HIL ─────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"settings-generator.d.ts","sourceRoot":"","sources":["../../../src/init/settings-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAA6B,MAAM,YAAY,CAAC;AAGzE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAmJ7D;AA+RD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAGjE"}
1
+ {"version":3,"file":"settings-generator.d.ts","sourceRoot":"","sources":["../../../src/init/settings-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAA6B,MAAM,YAAY,CAAC;AAGzE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAmJ7D;AAgUD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAGjE"}
@@ -233,6 +233,17 @@ function generateHooksConfig(config, graphify = true) {
233
233
  },
234
234
  ],
235
235
  },
236
+ // Grep/Glob → monograph_query intercept (saves tokens vs full scan)
237
+ {
238
+ matcher: 'Grep|Glob',
239
+ hooks: [
240
+ {
241
+ type: 'command',
242
+ command: hookHandlerCmd('pre-search'),
243
+ timeout: 4000,
244
+ },
245
+ ],
246
+ },
236
247
  ];
237
248
  }
238
249
  // PostToolUse — record edits and commands for session metrics / learning
@@ -258,6 +269,28 @@ function generateHooksConfig(config, graphify = true) {
258
269
  },
259
270
  ],
260
271
  },
272
+ // Read → graph neighbor footer
273
+ {
274
+ matcher: 'Read',
275
+ hooks: [
276
+ {
277
+ type: 'command',
278
+ command: hookHandlerCmd('post-read'),
279
+ timeout: 4000,
280
+ },
281
+ ],
282
+ },
283
+ // monograph_* tool calls → telemetry counter
284
+ {
285
+ matcher: 'mcp__monomind__monograph_.*',
286
+ hooks: [
287
+ {
288
+ type: 'command',
289
+ command: hookHandlerCmd('post-graph-tool'),
290
+ timeout: 2000,
291
+ },
292
+ ],
293
+ },
261
294
  ];
262
295
  }
263
296
  // UserPromptSubmit — intelligent task routing
@@ -1 +1 @@
1
- {"version":3,"file":"settings-generator.js","sourceRoot":"","sources":["../../../src/init/settings-generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings-generator.js","sourceRoot":"","sources":["../../../src/init/settings-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAoB;IACnD,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAE7C,uBAAuB;IACvB,IAAI,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QAChC,QAAQ,CAAC,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACnF,CAAC;IAED,0CAA0C;IAC1C,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAC/B,QAAQ,CAAC,UAAU,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,kBAAkB;IAClB,0CAA0C;IAC1C,uEAAuE;IACvE,0EAA0E;IAC1E,2EAA2E;IAC3E,mDAAmD;IACnD,QAAQ,CAAC,WAAW,GAAG;QACrB,KAAK,EAAE;YACL,uBAAuB;YACvB,sBAAsB;YACtB,yBAAyB;YACzB,sBAAsB;YACtB,8BAA8B;YAC9B,mBAAmB;SACpB;QACD,IAAI,EAAE;YACJ,cAAc;YACd,gBAAgB;SACjB;KACF,CAAC;IAEF,mDAAmD;IACnD,QAAQ,CAAC,WAAW,GAAG;QACrB,MAAM,EAAE,iDAAiD;QACzD,EAAE,EAAE,qEAAqE;KAC1E,CAAC;IAEF,kEAAkE;IAClE,4DAA4D;IAC5D,iGAAiG;IAEjG,uDAAuD;IACvD,QAAQ,CAAC,GAAG,GAAG;QACb,8DAA8D;QAC9D,oCAAoC,EAAE,GAAG;QACzC,gCAAgC;QAChC,mBAAmB,EAAE,MAAM;QAC3B,sBAAsB,EAAE,MAAM;KAC/B,CAAC;IAEF,mDAAmD;IACnD,MAAM,QAAQ,GAAG,cAAc,EAAE,CAAC;IAElC,2BAA2B;IAC3B,QAAQ,CAAC,QAAQ,GAAG;QAClB,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE;YACR,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,KAAK,EAAE,QAAQ,CAAC,KAAK;SACtB;QACD,gBAAgB,EAAE;YAChB,OAAO,EAAE,iBAAiB;YAC1B,OAAO,EAAE,2BAA2B;SACrC;QACD,UAAU,EAAE;YACV,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,MAAM,EAAE,iCAAiC;YACvD,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,IAAI;YACpB,YAAY,EAAE;gBACZ,gBAAgB,EAAE,IAAI,EAAQ,kDAAkD;gBAChF,uBAAuB,EAAE,IAAI,EAAE,4CAA4C;gBAC3E,oBAAoB,EAAE,IAAI,EAAI,uCAAuC;gBACrE,qBAAqB,EAAE,aAAa,EAAE,yCAAyC;aAChF;YACD,KAAK,EAAE;gBACL,YAAY,EAAE;oBACZ,OAAO,EAAE,IAAI;oBACb,UAAU,EAAE,IAAI;oBAChB,aAAa,EAAE,IAAI;iBACpB;gBACD,aAAa,EAAE;oBACb,OAAO,EAAE,IAAI;oBACb,aAAa,EAAE,IAAI;oBACnB,UAAU,EAAE,IAAI;iBACjB;aACF;SACF;QACD,KAAK,EAAE;YACL,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ;YAClC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS;SACrC;QACD,MAAM,EAAE;YACN,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,aAAa;YACtC,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,UAAU;YACtC,cAAc,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,oBAAoB,IAAI,IAAI,EAAE;YACzE,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,iBAAiB,IAAI,IAAI,EAAE;YACnE,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,iBAAiB,IAAI,IAAI,EAAE;SACpE;QACD,MAAM,EAAE;YACN,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,YAAY;SACtC;QACD,MAAM,EAAE;YACN,SAAS,EAAE,KAAK,EAAG,qEAAqE;YACxF,OAAO,EAAE;gBACP,KAAK,EAAY,mBAAmB;gBACpC,OAAO,EAAU,wCAAwC;gBACzD,UAAU,EAAO,2CAA2C;aAC7D;YACD,SAAS,EAAE;gBACT,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE;gBAC/C,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE;aAC/C;SACF;QACD,QAAQ,EAAE;YACR,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,CAAC,cAAc,EAAE,cAAc,EAAE,YAAY,CAAC;YACxD,SAAS,EAAE;gBACT,SAAS,EAAE,KAAK;gBAChB,QAAQ,EAAE,KAAK;aAChB;SACF;QACD,GAAG,EAAE;YACH,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,WAAW;YACtB,QAAQ,EAAE,MAAM;SACjB;QACD,GAAG,EAAE;YACH,YAAY,EAAE,IAAI;YAClB,uBAAuB,EAAE,IAAI;YAC7B,SAAS,EAAE,WAAW;SACvB;QACD,QAAQ,EAAE;YACR,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,IAAI;YAChB,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,IAAI;SAClB;KACF,CAAC;IAEF,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;AAEhD;;;;;;GAMG;AACH,SAAS,OAAO,CAAC,MAAc,EAAE,UAAkB;IACjD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,oCAAoC,MAAM,IAAI,UAAU,EAAE,CAAC,IAAI,EAAE,CAAC;IAC3E,CAAC;IACD,uEAAuE;IACvE,qEAAqE;IACrE,uDAAuD;IACvD,MAAM,GAAG,GAAG,0BAA0B,CAAC;IACvC,OAAO,qBAAqB,GAAG,IAAI,MAAM,KAAK,UAAU,GAAG,CAAC;AAC9D,CAAC;AAED,8CAA8C;AAC9C,SAAS,cAAc,CAAC,UAAkB;IACxC,OAAO,OAAO,CAAC,kCAAkC,EAAE,UAAU,CAAC,CAAC;AACjE,CAAC;AAED,kDAAkD;AAClD,SAAS,aAAa,CAAC,UAAkB;IACvC,OAAO,OAAO,CAAC,sCAAsC,EAAE,UAAU,CAAC,CAAC;AACrE,CAAC;AAED,kEAAkE;AAClE,SAAS,mBAAmB,CAAC,MAAc;IACzC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,oDAAoD,MAAM,EAAE,CAAC;IACtE,CAAC;IACD,uDAAuD;IACvD,MAAM,GAAG,GAAG,0BAA0B,CAAC;IACvC,OAAO,qBAAqB,GAAG,oBAAoB,MAAM,IAAI,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,SAAS,wBAAwB,CAAC,QAAqB;IACrD,+DAA+D;IAC/D,mDAAmD;IACnD,kEAAkE;IAClE,yEAAyE;IACzE,0EAA0E;IAC1E,uDAAuD;IACvD,MAAM,GAAG,GAAG,0BAA0B,CAAC;IACvC,OAAO;QACL,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,qBAAqB,GAAG,mCAAmC;KACrE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,MAAmB,EAAE,QAAQ,GAAG,IAAI;IAC/D,MAAM,KAAK,GAA8B,EAAE,CAAC;IAE5C,0DAA0D;IAC1D,gFAAgF;IAEhF,4DAA4D;IAC5D,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,KAAK,CAAC,UAAU,GAAG;YACjB;gBACE,OAAO,EAAE,MAAM;gBACf,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,UAAU,CAAC;wBACnC,OAAO,EAAE,MAAM,CAAC,OAAO;qBACxB;iBACF;aACF;YACD;gBACE,OAAO,EAAE,sBAAsB;gBAC/B,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,UAAU,CAAC;wBACnC,OAAO,EAAE,MAAM,CAAC,OAAO;qBACxB;iBACF;aACF;YACD,oEAAoE;YACpE;gBACE,OAAO,EAAE,WAAW;gBACpB,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,YAAY,CAAC;wBACrC,OAAO,EAAE,IAAI;qBACd;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACvB,KAAK,CAAC,WAAW,GAAG;YAClB;gBACE,OAAO,EAAE,sBAAsB;gBAC/B,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,WAAW,CAAC;wBACpC,OAAO,EAAE,KAAK;qBACf;iBACF;aACF;YACD;gBACE,OAAO,EAAE,MAAM;gBACf,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,WAAW,CAAC;wBACpC,OAAO,EAAE,MAAM,CAAC,OAAO;qBACxB;iBACF;aACF;YACD,+BAA+B;YAC/B;gBACE,OAAO,EAAE,MAAM;gBACf,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,WAAW,CAAC;wBACpC,OAAO,EAAE,IAAI;qBACd;iBACF;aACF;YACD,6CAA6C;YAC7C;gBACE,OAAO,EAAE,6BAA6B;gBACtC,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,iBAAiB,CAAC;wBAC1C,OAAO,EAAE,IAAI;qBACd;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,8CAA8C;IAC9C,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;QAC5B,KAAK,CAAC,gBAAgB,GAAG;YACvB;gBACE,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC;wBAChC,OAAO,EAAE,KAAK;qBACf;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,oFAAoF;IACpF,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,MAAM,iBAAiB,GAAa;YAClC;gBACE,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,cAAc,CAAC,iBAAiB,CAAC;gBAC1C,OAAO,EAAE,KAAK;aACf;YACD;gBACE,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC;gBAChC,OAAO,EAAE,IAAI;aACd;SACF,CAAC;QAEF,IAAI,QAAQ,EAAE,CAAC;YACb,iBAAiB,CAAC,IAAI,CAAC;gBACrB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,mBAAmB,CAAC,sBAAsB,CAAC;gBACpD,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;QACL,CAAC;QAED,iBAAiB,CAAC,IAAI,CAAC;YACrB,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,mBAAmB,CAAC,mBAAmB,CAAC;YACjD,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,KAAK,CAAC,YAAY,GAAG,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,qCAAqC;IACrC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,KAAK,CAAC,UAAU,GAAG;YACjB;gBACE,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC;wBACtC,OAAO,EAAE,KAAK;qBACf;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,kCAAkC;IAClC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,GAAG;YACX;gBACE,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC;wBAC9B,OAAO,EAAE,KAAK;qBACf;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,kDAAkD;IAClD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,KAAK,CAAC,UAAU,GAAG;YACjB;gBACE,OAAO,EAAE,QAAQ;gBACjB,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,gBAAgB,CAAC;qBAC1C;oBACD;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC;wBACtC,OAAO,EAAE,IAAI;qBACd;iBACF;aACF;YACD;gBACE,OAAO,EAAE,MAAM;gBACf,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,cAAc,CAAC;qBACxC;oBACD;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC;wBACtC,OAAO,EAAE,IAAI;qBACd;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,4DAA4D;IAC5D,KAAK,CAAC,aAAa,GAAG;QACpB;YACE,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,cAAc,CAAC,QAAQ,CAAC;oBACjC,OAAO,EAAE,IAAI;iBACd;aACF;SACF;KACF,CAAC;IAEF,oDAAoD;IACpD,8DAA8D;IAC9D,KAAK,CAAC,YAAY,GAAG;QACnB;YACE,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,cAAc,CAAC,WAAW,CAAC;oBACpC,OAAO,EAAE,IAAI;iBACd;aACF;SACF;KACF,CAAC;IAEF,+DAA+D;IAC/D,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACxB,KAAK,CAAC,YAAY,GAAG;YACnB;gBACE,KAAK,EAAE;oBACL;wBACE,IAAI,EAAE,SAAS;wBACf,OAAO,EAAE,cAAc,CAAC,QAAQ,CAAC;wBACjC,OAAO,EAAE,IAAI;qBACd;iBACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,+EAA+E;IAC/E,uEAAuE;IAEvE,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAoB;IACvD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"statusline-generator.d.ts","sourceRoot":"","sources":["../../../src/init/statusline-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAonCrE;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA8BnE"}
1
+ {"version":3,"file":"statusline-generator.d.ts","sourceRoot":"","sources":["../../../src/init/statusline-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA8oCrE;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA8BnE"}
@@ -828,6 +828,21 @@ function getTriggerStats() {
828
828
  } catch { return { triggers: 0, agents: 0 }; }
829
829
  }
830
830
 
831
+ // Graph usage telemetry — ratio of monograph_* vs Grep/Glob/Bash-grep, + $ saved
832
+ function getGraphUsage() {
833
+ const usagePath = path.join(CWD, '.monomind', 'metrics', 'graph-usage.json');
834
+ try {
835
+ if (!fs.existsSync(usagePath)) return null;
836
+ const d = JSON.parse(fs.readFileSync(usagePath, 'utf-8'));
837
+ const monograph = d.monograph_call || 0;
838
+ const search = (d.grep_call || 0) + (d.glob_call || 0)
839
+ + (d.bash_grep_call || 0) + (d.bash_find_call || 0);
840
+ const total = monograph + search;
841
+ if (total === 0) return null;
842
+ return { monograph: monograph, search: search, pct: Math.round((monograph / total) * 100), dollarsSaved: d.dollars_saved || 0 };
843
+ } catch { return null; }
844
+ }
845
+
831
846
  // Graph freshness — compare last build time vs commits since
832
847
  function getGraphFreshness() {
833
848
  const lockPath = path.join(CWD, '.monomind', 'graph', '.rebuild-lock');
@@ -1070,7 +1085,18 @@ function generateDashboard() {
1070
1085
  loopStr = \`\${x.slate}🔄 no active loops\${x.reset}\`;
1071
1086
  }
1072
1087
 
1073
- lines.push(\`\${x.purple}🤖 AGENT\${x.reset} \${agentStr} \${DIV} \${loopStr}\`);
1088
+ // Graph usage ratio + $ saved — show only when there's data
1089
+ const usage = getGraphUsage();
1090
+ let usageStr = '';
1091
+ if (usage) {
1092
+ const col = usage.pct >= 40 ? x.green : usage.pct >= 15 ? x.gold : x.coral;
1093
+ const saved = usage.dollarsSaved > 0
1094
+ ? \` \${x.green}💰 +$\${usage.dollarsSaved.toFixed(2)}\${x.reset}\`
1095
+ : '';
1096
+ usageStr = \` \${DIV} \${col}📊 graph \${usage.pct}%\${x.reset}\${x.slate} · grep \${100 - usage.pct}%\${x.reset}\${saved}\`;
1097
+ }
1098
+
1099
+ lines.push(\`\${x.purple}🤖 AGENT\${x.reset} \${agentStr} \${DIV} \${loopStr}\${usageStr}\`);
1074
1100
  lines.push(SEP);
1075
1101
 
1076
1102
  // ── Row 2: Graph freshness + Pending HIL ─────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"statusline-generator.js","sourceRoot":"","sources":["../../../src/init/statusline-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAoB;IAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;IAC5C,OAAO;;;;;;;;;;;;;;;;;;;;;;;eAuBM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0lCvB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAoB;IACzD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAChC,OAAO,sCAAsC,CAAC;IAChD,CAAC;IAED,OAAO;;;;;;;;;;;;;;;;;;;;;;;;CAwBR,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"statusline-generator.js","sourceRoot":"","sources":["../../../src/init/statusline-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAoB;IAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;IAC5C,OAAO;;;;;;;;;;;;;;;;;;;;;;;eAuBM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAonCvB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAoB;IACzD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAChC,OAAO,sCAAsC,CAAC;IAChD,CAAC;IAED,OAAO;;;;;;;;;;;;;;;;;;;;;;;;CAwBR,CAAC;AACF,CAAC"}