@monoes/monomindcli 2.7.14 → 2.7.16
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.
- package/.claude/helpers/control-start.cjs +17 -3
- package/.claude/helpers/handlers/route-handler.cjs +41 -29
- package/.claude/helpers/handlers/session-restore-handler.cjs +3 -3
- package/.claude/helpers/hook-handler.cjs +2 -2
- package/.claude/helpers/mastermind-activate.cjs +4 -0
- package/.claude/helpers/statusline.cjs +83 -33
- package/.claude/helpers/utils/monograph.cjs +4 -2
- package/dist/src/capabilities/cap-documents.d.ts.map +1 -1
- package/dist/src/capabilities/cap-documents.js +263 -35
- package/dist/src/capabilities/cap-documents.js.map +1 -1
- package/dist/src/capabilities/scanner.js +1 -1
- package/dist/src/capabilities/scanner.js.map +1 -1
- package/dist/src/commands/doc.js +1 -1
- package/dist/src/commands/doc.js.map +1 -1
- package/dist/src/commands/org-observe.d.ts +4 -2
- package/dist/src/commands/org-observe.d.ts.map +1 -1
- package/dist/src/commands/org-observe.js +105 -4
- package/dist/src/commands/org-observe.js.map +1 -1
- package/dist/src/commands/org.d.ts +2 -0
- package/dist/src/commands/org.d.ts.map +1 -1
- package/dist/src/commands/org.js +120 -4
- package/dist/src/commands/org.js.map +1 -1
- package/dist/src/init/claudemd-generator.js +1 -1
- package/dist/src/init/settings-generator.d.ts.map +1 -1
- package/dist/src/init/settings-generator.js +23 -9
- package/dist/src/init/settings-generator.js.map +1 -1
- package/dist/src/init/statusline-generator.d.ts.map +1 -1
- package/dist/src/init/statusline-generator.js +45 -1
- package/dist/src/init/statusline-generator.js.map +1 -1
- package/dist/src/knowledge/eval/model-presence.d.ts +5 -0
- package/dist/src/knowledge/eval/model-presence.d.ts.map +1 -1
- package/dist/src/knowledge/eval/model-presence.js +52 -6
- package/dist/src/knowledge/eval/model-presence.js.map +1 -1
- package/dist/src/knowledge/eval/signals.d.ts.map +1 -1
- package/dist/src/knowledge/eval/signals.js +24 -0
- package/dist/src/knowledge/eval/signals.js.map +1 -1
- package/dist/src/mcp-client.d.ts +10 -0
- package/dist/src/mcp-client.d.ts.map +1 -1
- package/dist/src/mcp-client.js +86 -4
- package/dist/src/mcp-client.js.map +1 -1
- package/dist/src/mcp-tools/index.d.ts +1 -1
- package/dist/src/mcp-tools/index.d.ts.map +1 -1
- package/dist/src/mcp-tools/index.js +1 -1
- package/dist/src/mcp-tools/index.js.map +1 -1
- package/dist/src/mcp-tools/monomind-tools.d.ts +14 -0
- package/dist/src/mcp-tools/monomind-tools.d.ts.map +1 -0
- package/dist/src/mcp-tools/monomind-tools.js +54 -0
- package/dist/src/mcp-tools/monomind-tools.js.map +1 -0
- package/dist/src/memory/memory-bridge.d.ts.map +1 -1
- package/dist/src/memory/memory-bridge.js +27 -7
- package/dist/src/memory/memory-bridge.js.map +1 -1
- package/dist/src/orgrt/broker.d.ts +4 -2
- package/dist/src/orgrt/broker.d.ts.map +1 -1
- package/dist/src/orgrt/broker.js +8 -6
- package/dist/src/orgrt/broker.js.map +1 -1
- package/dist/src/orgrt/bus.d.ts +1 -0
- package/dist/src/orgrt/bus.d.ts.map +1 -1
- package/dist/src/orgrt/bus.js +5 -1
- package/dist/src/orgrt/bus.js.map +1 -1
- package/dist/src/orgrt/daemon.d.ts +17 -2
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +179 -44
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/inbox.d.ts +1 -1
- package/dist/src/orgrt/inbox.d.ts.map +1 -1
- package/dist/src/orgrt/inbox.js +12 -3
- package/dist/src/orgrt/inbox.js.map +1 -1
- package/dist/src/orgrt/policy.d.ts.map +1 -1
- package/dist/src/orgrt/policy.js +84 -0
- package/dist/src/orgrt/policy.js.map +1 -1
- package/dist/src/orgrt/reporting.d.ts +2 -0
- package/dist/src/orgrt/reporting.d.ts.map +1 -1
- package/dist/src/orgrt/reporting.js +4 -1
- package/dist/src/orgrt/reporting.js.map +1 -1
- package/dist/src/orgrt/server.d.ts +4 -2
- package/dist/src/orgrt/server.d.ts.map +1 -1
- package/dist/src/orgrt/server.js +76 -73
- package/dist/src/orgrt/server.js.map +1 -1
- package/dist/src/orgrt/session.d.ts.map +1 -1
- package/dist/src/orgrt/session.js +63 -27
- package/dist/src/orgrt/session.js.map +1 -1
- package/dist/src/orgrt/test-loop.js +1 -1
- package/dist/src/orgrt/test-loop.js.map +1 -1
- package/dist/src/orgrt/types.d.ts +50 -1
- package/dist/src/orgrt/types.d.ts.map +1 -1
- package/dist/src/orgrt/types.js +33 -1
- package/dist/src/orgrt/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/dist/src/mcp-tools/neural-tools.d.ts +0 -15
- package/dist/src/mcp-tools/neural-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/neural-tools.js +0 -506
- package/dist/src/mcp-tools/neural-tools.js.map +0 -1
|
@@ -152,11 +152,25 @@ async function main() {
|
|
|
152
152
|
}
|
|
153
153
|
} catch { /* non-critical — proceed without check */ }
|
|
154
154
|
|
|
155
|
-
// If already running,
|
|
155
|
+
// If already running, check if it's serving THIS project and a current build.
|
|
156
156
|
const status = readStatus();
|
|
157
157
|
if (status && status.pid && isPidAlive(status.pid)) {
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
const live = await probeStatus(status.port);
|
|
159
|
+
const staleProject = live && live.dir && path.resolve(live.dir) !== path.resolve(CWD);
|
|
160
|
+
const startedMs = status.startedAt ? Date.now() - new Date(status.startedAt).getTime() : 0;
|
|
161
|
+
const staleBuild = startedMs > 7 * 24 * 3600_000; // older than 7 days
|
|
162
|
+
if (staleProject || staleBuild) {
|
|
163
|
+
const reason = staleProject
|
|
164
|
+
? `rooted in ${live.dir}, not ${CWD}`
|
|
165
|
+
: `started ${Math.round(startedMs / 86400_000)}d ago`;
|
|
166
|
+
process.stdout.write(`[control] restarting stale server (${reason})\n`);
|
|
167
|
+
try { process.kill(status.pid, 'SIGTERM'); } catch { /* already gone */ }
|
|
168
|
+
// Give it a moment to release the port
|
|
169
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
170
|
+
} else {
|
|
171
|
+
process.stdout.write(`[control] already running on port ${status.port} (pid ${status.pid})\n`);
|
|
172
|
+
process.exit(0);
|
|
173
|
+
}
|
|
160
174
|
}
|
|
161
175
|
|
|
162
176
|
// Adopt an already-listening server (e.g. started manually or by another session)
|
|
@@ -18,6 +18,17 @@
|
|
|
18
18
|
const path = require('path');
|
|
19
19
|
const fs = require('fs');
|
|
20
20
|
|
|
21
|
+
// ── Advisory output gate ────────────────────────────────────────────────────
|
|
22
|
+
// Set MONOMIND_HOOK_QUIET=1 to silence the per-prompt advisory blocks
|
|
23
|
+
// ([AUDIT], [CODEBASE], [MONOGRAPH], [INTELLIGENCE], [COST], etc.). Side-effects
|
|
24
|
+
// (file writes, telemetry counters, route mutations) are unchanged — only the
|
|
25
|
+
// stdout announcement is gated. Default (unset) keeps today's behavior.
|
|
26
|
+
var _HOOK_QUIET = String(process.env.MONOMIND_HOOK_QUIET || '').toLowerCase() === '1';
|
|
27
|
+
function advisoryLog() {
|
|
28
|
+
if (_HOOK_QUIET) return;
|
|
29
|
+
console.log.apply(console, arguments);
|
|
30
|
+
}
|
|
31
|
+
|
|
21
32
|
// ── Intelligence read-path bridge ───────────────────────────────────────────
|
|
22
33
|
// route-handler.cjs runs as a fresh node subprocess per invocation, but a
|
|
23
34
|
// single process may call handle() more than once (e.g. tests, or a daemon
|
|
@@ -98,12 +109,12 @@ module.exports = {
|
|
|
98
109
|
var bDb = hCtx._openMonographDb();
|
|
99
110
|
if (bDb) {
|
|
100
111
|
var bootstrapped = intelligence.bootstrapFromDb(bDb);
|
|
101
|
-
if (bootstrapped > 0)
|
|
112
|
+
if (bootstrapped > 0) advisoryLog('[INTELLIGENCE] Bootstrapped ' + bootstrapped + ' hub nodes from knowledge graph');
|
|
102
113
|
}
|
|
103
114
|
} catch (e) { /* non-fatal */ }
|
|
104
115
|
}
|
|
105
116
|
const ctx = intelligence.getContext(prompt);
|
|
106
|
-
if (ctx)
|
|
117
|
+
if (ctx) advisoryLog(ctx);
|
|
107
118
|
} catch (e) { /* non-fatal */ }
|
|
108
119
|
}
|
|
109
120
|
if (router && (router.routeTaskSemantic || router.routeTask)) {
|
|
@@ -174,7 +185,7 @@ module.exports = {
|
|
|
174
185
|
// Only override when the embedding match clearly beats the keyword
|
|
175
186
|
// route (0.1 margin) — otherwise just surface it as a signal.
|
|
176
187
|
if (intelConf > curConf + 0.1) {
|
|
177
|
-
|
|
188
|
+
advisoryLog('[INTELLIGENCE] Embedding suggestion overrides keyword routing: ' + topIntelAgent + ' (confidence ' + intelConf.toFixed(2) + ') vs keyword ' + curAgent + ' (' + curConf.toFixed(2) + ')');
|
|
178
189
|
result.keywordAgent = curAgent;
|
|
179
190
|
result.agent = topIntelAgent;
|
|
180
191
|
result.agentSlug = topIntelAgent;
|
|
@@ -182,7 +193,7 @@ module.exports = {
|
|
|
182
193
|
result.reason = 'Intelligence embedding match (SONA/ReasoningBank)' + (result.reason ? '; keyword route was: ' + result.reason : '');
|
|
183
194
|
result.enrichedFrom = 'intelligence-embedding';
|
|
184
195
|
} else {
|
|
185
|
-
|
|
196
|
+
advisoryLog('[INTELLIGENCE] Embedding suggestion: ' + topIntelAgent + ' (confidence ' + intelConf.toFixed(2) + ') — kept keyword route ' + curAgent);
|
|
186
197
|
}
|
|
187
198
|
}
|
|
188
199
|
}
|
|
@@ -210,7 +221,7 @@ module.exports = {
|
|
|
210
221
|
if (routedPattern && routedPattern.successRate < 50) {
|
|
211
222
|
var best = patterns.reduce(function(a, b) { return (b.wins/b.total) > (a.wins/a.total) ? b : a; });
|
|
212
223
|
if (best.wins / best.total > 0.8 && best.agent_type !== routedAgent) {
|
|
213
|
-
|
|
224
|
+
advisoryLog('[AGENT_PATTERN] Historical: ' + best.agent_type + ' (' + Math.round(best.wins/best.total*100) + '% success, n=' + best.total + ') outperforms ' + routedAgent + ' (' + routedPattern.successRate + '%)');
|
|
214
225
|
}
|
|
215
226
|
}
|
|
216
227
|
result.historicalPattern = patternMap;
|
|
@@ -240,7 +251,7 @@ module.exports = {
|
|
|
240
251
|
var successes = agentFeedback.filter(function(f) { return f === true; }).length;
|
|
241
252
|
var accuracy = Math.round(successes / agentFeedback.length * 100);
|
|
242
253
|
if (accuracy < 60) {
|
|
243
|
-
|
|
254
|
+
advisoryLog('[ROUTING] Warning: ' + routedAgent + ' routing accuracy ' + accuracy + '% over last ' + agentFeedback.length + ' sessions');
|
|
244
255
|
}
|
|
245
256
|
result.routingAccuracy = accuracy;
|
|
246
257
|
}
|
|
@@ -263,7 +274,7 @@ module.exports = {
|
|
|
263
274
|
var dispatchAge = Date.now() - new Date(lastDispatch.dispatchedAt || 0).getTime();
|
|
264
275
|
if (dispatchAge < 60000 && lastDispatch.agentType === (result.agentSlug || result.agent)) {
|
|
265
276
|
result.recentlyDispatched = true;
|
|
266
|
-
|
|
277
|
+
advisoryLog('[DISPATCH_DEDUP] ' + lastDispatch.agentType + ' was dispatched ' + Math.round(dispatchAge / 1000) + 's ago — consider a different specialist or direct implementation');
|
|
267
278
|
}
|
|
268
279
|
}
|
|
269
280
|
} catch (e) { /* non-fatal */ }
|
|
@@ -314,7 +325,8 @@ module.exports = {
|
|
|
314
325
|
}
|
|
315
326
|
}
|
|
316
327
|
|
|
317
|
-
|
|
328
|
+
// Skill suggestions are opt-in (MONOMIND_SKILL_AUTO=1) and still respect QUIET.
|
|
329
|
+
if (output.length > 0 && String(process.env.MONOMIND_SKILL_AUTO || '') === '1' && !_HOOK_QUIET) console.log(output.join('\n'));
|
|
318
330
|
|
|
319
331
|
// ── Second Brain: per-request knowledge injection ──────────────────
|
|
320
332
|
// When the project has an indexed knowledge base, surface the most
|
|
@@ -483,7 +495,7 @@ module.exports = {
|
|
|
483
495
|
sbLines.push(' • [' + sbSrc + (sbH.global ? ' · global' : '') + '] ' + sbText);
|
|
484
496
|
}
|
|
485
497
|
sbLines.push(' (deeper lookup: mcp__monomind__knowledge_search or `monomind doc search -q "..."`)');
|
|
486
|
-
|
|
498
|
+
advisoryLog(sbLines.join('\n'));
|
|
487
499
|
}
|
|
488
500
|
}
|
|
489
501
|
}
|
|
@@ -498,11 +510,11 @@ module.exports = {
|
|
|
498
510
|
if (budget && budget.alert) {
|
|
499
511
|
var tunedNote = budget.autoTuned ? ' (auto-tuned)' : '';
|
|
500
512
|
if (budget.spike && !budget.breached) {
|
|
501
|
-
|
|
513
|
+
advisoryLog('[BUDGET_SPIKE] Today $' + budget.todayCost.toFixed(2) + ' is >2x your rolling daily avg. Unusual spend — review .monomind/metrics/token-summary.json.');
|
|
502
514
|
} else if (budget.breached) {
|
|
503
|
-
|
|
515
|
+
advisoryLog('[BUDGET_BREACHED] Daily $' + budget.todayCost.toFixed(2) + '/$' + budget.dailyLimit + ' (' + budget.dailyPct + '%) · Monthly $' + budget.monthCost.toFixed(2) + '/$' + budget.monthlyLimit + ' (' + budget.monthlyPct + '%)' + tunedNote + '. Switch to Haiku with /model haiku or edit .monomind/budget.json.');
|
|
504
516
|
} else {
|
|
505
|
-
|
|
517
|
+
advisoryLog('[BUDGET_ALERT] Daily ' + budget.dailyPct + '% of $' + budget.dailyLimit + ' · Monthly ' + budget.monthlyPct + '% of $' + budget.monthlyLimit + tunedNote + '.');
|
|
506
518
|
}
|
|
507
519
|
}
|
|
508
520
|
} catch (e) {}
|
|
@@ -515,7 +527,7 @@ module.exports = {
|
|
|
515
527
|
if (fs.existsSync(latencyFile) && fs.statSync(latencyFile).size < 32768) {
|
|
516
528
|
var latencyData = JSON.parse(fs.readFileSync(latencyFile, 'utf-8'));
|
|
517
529
|
if (latencyData && latencyData.avgMs > 500) {
|
|
518
|
-
|
|
530
|
+
advisoryLog('[PERF] Hook latency avg ' + Math.round(latencyData.avgMs) + 'ms (target <500ms). Slowest: ' + (latencyData.slowest || 'unknown'));
|
|
519
531
|
}
|
|
520
532
|
}
|
|
521
533
|
// Token usage check — surface only when spend is high
|
|
@@ -523,7 +535,7 @@ module.exports = {
|
|
|
523
535
|
if (fs.existsSync(tokenFile) && fs.statSync(tokenFile).size < 32768) {
|
|
524
536
|
var tokenData = JSON.parse(fs.readFileSync(tokenFile, 'utf-8'));
|
|
525
537
|
if (tokenData && tokenData.todayCost > 50) {
|
|
526
|
-
|
|
538
|
+
advisoryLog('[COST] Today: $' + (tokenData.todayCost || 0).toFixed(2) + ' (' + (tokenData.todayCalls || 0) + ' calls)');
|
|
527
539
|
}
|
|
528
540
|
}
|
|
529
541
|
// Security audit findings
|
|
@@ -533,9 +545,9 @@ module.exports = {
|
|
|
533
545
|
if (secData && secData.findings && secData.findings.length > 0) {
|
|
534
546
|
var serious = secData.findings.filter(function (f) { return f && (f.severity === 'high' || f.severity === 'medium'); });
|
|
535
547
|
if (serious.length > 0) {
|
|
536
|
-
|
|
548
|
+
advisoryLog('[SECURITY] ' + serious.length + ' finding(s) from background scan. Review .monomind/metrics/security-audit.json');
|
|
537
549
|
} else {
|
|
538
|
-
|
|
550
|
+
advisoryLog('[AUDIT] ' + secData.findings.length + ' low-severity note(s) (architecture heuristics, not vulnerabilities) — .monomind/metrics/security-audit.json');
|
|
539
551
|
}
|
|
540
552
|
}
|
|
541
553
|
}
|
|
@@ -544,10 +556,10 @@ module.exports = {
|
|
|
544
556
|
if (fs.existsSync(mapFile) && fs.statSync(mapFile).size < 32768) {
|
|
545
557
|
var mapData = JSON.parse(fs.readFileSync(mapFile, 'utf-8'));
|
|
546
558
|
if (mapData && mapData.topFiles && mapData.topFiles.length > 0) {
|
|
547
|
-
|
|
559
|
+
advisoryLog('[CODEBASE] ' + mapData.topFiles.length + ' high-centrality files. Top: ' + (mapData.topFiles[0].ref || 'unknown') + ' (degree ' + (mapData.topFiles[0].degree || '?') + ')');
|
|
548
560
|
}
|
|
549
561
|
if (mapData && mapData.graphStaleness && mapData.graphStaleness.commitsBehind > 10) {
|
|
550
|
-
|
|
562
|
+
advisoryLog('[CODEBASE] Graph index ' + mapData.graphStaleness.commitsBehind + ' commits behind HEAD — run monograph build');
|
|
551
563
|
}
|
|
552
564
|
}
|
|
553
565
|
// Graph gate connectivity nudge — the pre-search/pre-bash gate
|
|
@@ -572,7 +584,7 @@ module.exports = {
|
|
|
572
584
|
} catch (e) { /* corrupt — warn again to be safe */ }
|
|
573
585
|
}
|
|
574
586
|
if (!alreadyWarnedMcp) {
|
|
575
|
-
|
|
587
|
+
advisoryLog('[MCP] The graph gate blocked a search but no monograph_query/monograph_suggest call followed — the monomind MCP server is likely not connected this session. Run `claude mcp add monomind -- npx monomind@latest mcp start` (then restart), or approve the .mcp.json trust prompt if one is pending.');
|
|
576
588
|
try {
|
|
577
589
|
fs.writeFileSync(mcpWarnFile, JSON.stringify({ sessionId: gateSessId, warnedAt: new Date().toISOString() }));
|
|
578
590
|
} catch (e) { /* non-fatal */ }
|
|
@@ -588,7 +600,7 @@ module.exports = {
|
|
|
588
600
|
var finding = ddData.findings[di];
|
|
589
601
|
if (finding.category === 'god_nodes' && finding.items && finding.items.length > 0) {
|
|
590
602
|
var topGod = finding.items[0];
|
|
591
|
-
|
|
603
|
+
advisoryLog('[DEEPDIVE] ' + finding.items.length + ' god nodes. Top: ' + (topGod.name || 'unknown') + ' (degree ' + (topGod.degree || '?') + ') in ' + (topGod.file || 'unknown'));
|
|
592
604
|
}
|
|
593
605
|
}
|
|
594
606
|
}
|
|
@@ -602,7 +614,7 @@ module.exports = {
|
|
|
602
614
|
var insight = ulData.insightsGained[ui];
|
|
603
615
|
if (insight.category === 'bridge_nodes' && insight.items && insight.items.length > 0) {
|
|
604
616
|
var topBridge = insight.items[0];
|
|
605
|
-
|
|
617
|
+
advisoryLog('[ARCHITECTURE] ' + insight.items.length + ' bridge nodes crossing community boundaries. Top: ' + (topBridge.name || 'unknown') + ' (' + (topBridge.crossCommunityEdges || '?') + ' cross-edges) in ' + (topBridge.location || 'unknown'));
|
|
606
618
|
}
|
|
607
619
|
}
|
|
608
620
|
}
|
|
@@ -615,7 +627,7 @@ module.exports = {
|
|
|
615
627
|
var rssBytes = perfData.workerProcessMemoryUsage.rss || 0;
|
|
616
628
|
var rssMB = Math.round(rssBytes / (1024 * 1024));
|
|
617
629
|
if (rssMB > 512) {
|
|
618
|
-
|
|
630
|
+
advisoryLog('[PERF] optimize worker RSS ' + rssMB + 'MB (>512MB threshold) at last run — reflects that one-shot process, not a persistent daemon');
|
|
619
631
|
}
|
|
620
632
|
}
|
|
621
633
|
}
|
|
@@ -624,7 +636,7 @@ module.exports = {
|
|
|
624
636
|
if (fs.existsSync(consolFile) && fs.statSync(consolFile).size < 32768) {
|
|
625
637
|
var consolData = JSON.parse(fs.readFileSync(consolFile, 'utf-8'));
|
|
626
638
|
if (consolData && consolData.patternsConsolidated > 0) {
|
|
627
|
-
|
|
639
|
+
advisoryLog('[MEMORY] ' + consolData.patternsConsolidated + ' patterns consolidated into ' + consolData.clustersCreated + ' RAPTOR clusters');
|
|
628
640
|
}
|
|
629
641
|
}
|
|
630
642
|
// Benchmark worker RSS (manual-trigger `daemon trigger -w benchmark`)
|
|
@@ -634,7 +646,7 @@ module.exports = {
|
|
|
634
646
|
if (benchData && benchData.benchmarks && benchData.benchmarks.memoryUsage) {
|
|
635
647
|
var benchRssMB = Math.round((benchData.benchmarks.memoryUsage.rss || 0) / (1024 * 1024));
|
|
636
648
|
if (benchRssMB > 512) {
|
|
637
|
-
|
|
649
|
+
advisoryLog('[PERF] Benchmark snapshot RSS ' + benchRssMB + 'MB (>512MB threshold) at last `daemon trigger -w benchmark` run');
|
|
638
650
|
}
|
|
639
651
|
}
|
|
640
652
|
}
|
|
@@ -699,7 +711,7 @@ module.exports = {
|
|
|
699
711
|
var ago = topMatches[mi].ts ? Math.round((Date.now() - topMatches[mi].ts) / 3600000) + 'h ago' : '';
|
|
700
712
|
memLines.push(' ' + topMatches[mi].summary.replace(/\n/g, ' ').trim() + (ago ? ' (' + ago + ')' : ''));
|
|
701
713
|
}
|
|
702
|
-
|
|
714
|
+
advisoryLog(memLines.join('\n'));
|
|
703
715
|
}
|
|
704
716
|
}
|
|
705
717
|
}
|
|
@@ -775,10 +787,10 @@ module.exports = {
|
|
|
775
787
|
if (fileLoc && s.startLine != null) fileLoc = fileLoc + ':' + s.startLine;
|
|
776
788
|
return s.name + ' [' + s.label + '] — ' + fileLoc + editTag;
|
|
777
789
|
});
|
|
778
|
-
|
|
790
|
+
advisoryLog('[MONOGRAPH] ' + nodeCount + ' nodes. Top files: ' + hintParts.join(' · '));
|
|
779
791
|
hCtx._recordGraphTelemetry('preresolve_hit');
|
|
780
792
|
} else {
|
|
781
|
-
|
|
793
|
+
advisoryLog('[MONOGRAPH] ' + nodeCount + ' nodes. Call mcp__monomind__monograph_suggest to find relevant files.');
|
|
782
794
|
hCtx._recordGraphTelemetry('preresolve_miss');
|
|
783
795
|
}
|
|
784
796
|
}
|
|
@@ -786,7 +798,7 @@ module.exports = {
|
|
|
786
798
|
|
|
787
799
|
// Swarm mode selection is available on-demand via /mastermind slash command.
|
|
788
800
|
} else {
|
|
789
|
-
|
|
801
|
+
advisoryLog('[INFO] Router not available, using default routing');
|
|
790
802
|
}
|
|
791
803
|
|
|
792
804
|
// Task 22: TeamRoutingModes — only log when an explicit swarm config is present
|
|
@@ -796,7 +808,7 @@ module.exports = {
|
|
|
796
808
|
var swarmCfgSt = fs.statSync(swarmCfgPath);
|
|
797
809
|
var topology22 = swarmCfgSt.size <= 1024 * 1024 ? (JSON.parse(fs.readFileSync(swarmCfgPath, 'utf-8')).topology || 'mesh') : 'mesh';
|
|
798
810
|
var mode22 = topology22 === 'hierarchical' ? 'route' : 'coordinate';
|
|
799
|
-
|
|
811
|
+
advisoryLog('[ROUTING_MODE] topology=' + topology22 + ' → mode=' + mode22);
|
|
800
812
|
}
|
|
801
813
|
} catch (e) { /* non-fatal */ }
|
|
802
814
|
}
|
|
@@ -333,12 +333,12 @@ module.exports = {
|
|
|
333
333
|
var kRetriever = new memoryMod.KnowledgeRetriever(kSearchFn, kStore);
|
|
334
334
|
var kResult = await kRetriever.retrieveForTask('shared', sessionCtx, 5);
|
|
335
335
|
if (kResult.excerpts.length > 0) {
|
|
336
|
-
console.log('[KNOWLEDGE_PRELOADED] ' + kResult.excerpts.length + ' excerpts (KnowledgeRetriever)');
|
|
336
|
+
if (String(process.env.MONOMIND_HOOK_QUIET || '') !== '1') console.log('[KNOWLEDGE_PRELOADED] ' + kResult.excerpts.length + ' excerpts (KnowledgeRetriever)');
|
|
337
337
|
}
|
|
338
338
|
} else {
|
|
339
339
|
var directResults = await kSearchFn(sessionCtx, { namespace: 'knowledge:shared', limit: 5, minScore: 0.3 });
|
|
340
340
|
if (directResults.length > 0) {
|
|
341
|
-
console.log('[KNOWLEDGE_PRELOADED] ' + directResults.length + ' excerpts (direct keyword search)');
|
|
341
|
+
if (String(process.env.MONOMIND_HOOK_QUIET || '') !== '1') console.log('[KNOWLEDGE_PRELOADED] ' + directResults.length + ' excerpts (direct keyword search)');
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
} catch (e) { /* non-fatal */ }
|
|
@@ -536,7 +536,7 @@ module.exports = {
|
|
|
536
536
|
var tokenTracker = require(path.join(helpersDir, 'token-tracker.cjs'));
|
|
537
537
|
var tokenSummary = tokenTracker.quickSummary();
|
|
538
538
|
if (tokenSummary) {
|
|
539
|
-
console.log(tokenSummary);
|
|
539
|
+
if (String(process.env.MONOMIND_HOOK_QUIET || '') !== '1') console.log(tokenSummary);
|
|
540
540
|
}
|
|
541
541
|
try {
|
|
542
542
|
var tokenData = tokenTracker.quickSummaryData();
|
|
@@ -443,7 +443,7 @@ const handlers = {
|
|
|
443
443
|
return;
|
|
444
444
|
}
|
|
445
445
|
if (gateResult === 'warn') {
|
|
446
|
-
console.log('[MONOGRAPH_REMINDER] monograph_query/suggest not yet called this session — graph has ' + (_getNodeCount() || '20k+') + ' indexed nodes. Try monograph first for faster, more precise results.');
|
|
446
|
+
if (String(process.env.MONOMIND_HOOK_QUIET || '') !== '1') console.log('[MONOGRAPH_REMINDER] monograph_query/suggest not yet called this session — graph has ' + (_getNodeCount() || '20k+') + ' indexed nodes. Try monograph first for faster, more precise results.');
|
|
447
447
|
}
|
|
448
448
|
var graphAssisted = false;
|
|
449
449
|
if (_isGraphFresh()) {
|
|
@@ -708,7 +708,7 @@ const handlers = {
|
|
|
708
708
|
return;
|
|
709
709
|
}
|
|
710
710
|
if (gateResult === 'warn') {
|
|
711
|
-
console.log('[MONOGRAPH_REMINDER] monograph_query/suggest not yet called this session — try monograph first for faster results.');
|
|
711
|
+
if (String(process.env.MONOMIND_HOOK_QUIET || '') !== '1') console.log('[MONOGRAPH_REMINDER] monograph_query/suggest not yet called this session — try monograph first for faster results.');
|
|
712
712
|
}
|
|
713
713
|
var graphResolved = false;
|
|
714
714
|
try {
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
// The routing table is the unique value — tells Claude which skill for which task.
|
|
6
6
|
// Full protocol loads on-demand via /mastermind.
|
|
7
7
|
|
|
8
|
+
// Opt-in: only emit the routing table when MONOMIND_MASTERMIND=1.
|
|
9
|
+
// Off by default to cut ~1.5K tokens of per-session injection; load on-demand via /mastermind.
|
|
10
|
+
if (String(process.env.MONOMIND_MASTERMIND || '') === '1') {
|
|
8
11
|
process.stdout.write(
|
|
9
12
|
'## Mastermind Skill Router\n\n' +
|
|
10
13
|
'Invoke the matching skill BEFORE responding. If unsure, check — invoking and finding it irrelevant costs less than skipping it.\n\n' +
|
|
@@ -33,3 +36,4 @@ process.stdout.write(
|
|
|
33
36
|
'Process skills (debug, idea, architect, research) set the approach. Execution skills (build, review, release) carry it out.\n' +
|
|
34
37
|
'Subagents with `<SUBAGENT-STOP>` gate skip this routing.\n'
|
|
35
38
|
);
|
|
39
|
+
}
|
|
@@ -1028,6 +1028,38 @@ function getGraphifyStats() {
|
|
|
1028
1028
|
return { nodes: 0, edges: 0, exists: false };
|
|
1029
1029
|
}
|
|
1030
1030
|
|
|
1031
|
+
// Document / knowledge stats — docs indexed + chunks + memory entries
|
|
1032
|
+
function getDocStats() {
|
|
1033
|
+
const docPath = path.join(CWD, '.monomind', 'knowledge', 'doc-metadata.jsonl');
|
|
1034
|
+
const chunksPath = path.join(CWD, '.monomind', 'knowledge', 'chunks.jsonl');
|
|
1035
|
+
const memDbPath = path.join(CWD, '.monomind', 'memory', 'memory.db');
|
|
1036
|
+
let docs = 0, chunks = 0, memories = 0, exists = false;
|
|
1037
|
+
try {
|
|
1038
|
+
const ds = safeStat(docPath);
|
|
1039
|
+
if (ds && ds.size > 0) {
|
|
1040
|
+
const buf = fs.readFileSync(docPath, 'utf-8');
|
|
1041
|
+
docs = buf.split('\n').filter(Boolean).length;
|
|
1042
|
+
exists = true;
|
|
1043
|
+
}
|
|
1044
|
+
} catch { /* ignore */ }
|
|
1045
|
+
try {
|
|
1046
|
+
const cs = safeStat(chunksPath);
|
|
1047
|
+
if (cs && cs.size > 0) {
|
|
1048
|
+
const buf = fs.readFileSync(chunksPath, 'utf-8');
|
|
1049
|
+
chunks = buf.split('\n').filter(Boolean).length;
|
|
1050
|
+
exists = true;
|
|
1051
|
+
}
|
|
1052
|
+
} catch { /* ignore */ }
|
|
1053
|
+
try {
|
|
1054
|
+
if (fs.existsSync(memDbPath)) {
|
|
1055
|
+
const result = spawnSync('sqlite3', [memDbPath, 'SELECT COUNT(*) FROM memory_entries;'], { encoding: 'utf-8', timeout: 1000 });
|
|
1056
|
+
const n = parseInt((result.stdout || '').trim(), 10) || 0;
|
|
1057
|
+
if (n > 0) { memories = n; exists = true; }
|
|
1058
|
+
}
|
|
1059
|
+
} catch { /* ignore */ }
|
|
1060
|
+
return { docs, chunks, memories, exists };
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1031
1063
|
function getSIBudget() {
|
|
1032
1064
|
const SI_LIMIT = 1500;
|
|
1033
1065
|
const siPath = path.join(CWD, '.agents', 'shared_instructions.md');
|
|
@@ -1177,18 +1209,18 @@ function generateDashboard() {
|
|
|
1177
1209
|
const swarmDot = swarm.coordinationActive ? `${x.green}● LIVE${x.reset}` : `${x.slate}○ IDLE${x.reset}`;
|
|
1178
1210
|
const projName = getProjectName();
|
|
1179
1211
|
const cwdName = path.basename(CWD);
|
|
1180
|
-
let hdr = `${x.bold}${x.purple}▊
|
|
1212
|
+
let hdr = `${x.bold}${x.purple}▊Monomind ${VERSION}${x.reset} ${swarmDot} ${x.teal}${x.bold}${projName}${x.reset} ${DIV} ${x.dim}◎${cwdName}${x.reset} ${DIV} ${x.violet}⬡${git.name}${x.reset}`;
|
|
1181
1213
|
|
|
1182
1214
|
if (git.gitBranch) {
|
|
1183
|
-
hdr += `
|
|
1184
|
-
if (git.staged > 0) hdr += `
|
|
1185
|
-
if (git.modified > 0) hdr += `
|
|
1186
|
-
if (git.untracked > 0) hdr += `
|
|
1187
|
-
if (git.ahead > 0) hdr += `
|
|
1188
|
-
if (git.behind > 0) hdr += `
|
|
1215
|
+
hdr += ` ${DIV} ${x.sky}⎇${x.bold}${git.gitBranch}${x.reset}`;
|
|
1216
|
+
if (git.staged > 0) hdr += ` ${x.green}+${git.staged}${x.reset}`;
|
|
1217
|
+
if (git.modified > 0) hdr += ` ${x.gold}~${git.modified}${x.reset}`;
|
|
1218
|
+
if (git.untracked > 0) hdr += ` ${x.slate}?${git.untracked}${x.reset}`;
|
|
1219
|
+
if (git.ahead > 0) hdr += ` ${x.green}↑${git.ahead}${x.reset}`;
|
|
1220
|
+
if (git.behind > 0) hdr += ` ${x.coral}↓${git.behind}${x.reset}`;
|
|
1189
1221
|
}
|
|
1190
1222
|
|
|
1191
|
-
if (session.duration) hdr += `
|
|
1223
|
+
if (session.duration) hdr += ` ${x.dim}⏱${session.duration}${x.reset}`;
|
|
1192
1224
|
|
|
1193
1225
|
lines.push(hdr);
|
|
1194
1226
|
lines.push(SEP);
|
|
@@ -1226,15 +1258,15 @@ function generateDashboard() {
|
|
|
1226
1258
|
const lat = getHookLatency();
|
|
1227
1259
|
let latStr = '';
|
|
1228
1260
|
if (lat && lat.perPromptMs > 500) {
|
|
1229
|
-
latStr = `
|
|
1261
|
+
latStr = ` ${DIV} ${x.coral}⚡${lat.perPromptMs}ms${x.reset}`;
|
|
1230
1262
|
} else if (lat && lat.perPromptMs > 0) {
|
|
1231
|
-
latStr = `
|
|
1263
|
+
latStr = ` ${DIV} ${x.dim}⚡${lat.perPromptMs}ms${x.reset}`;
|
|
1232
1264
|
}
|
|
1233
1265
|
|
|
1234
|
-
lines.push(`${x.purple}🤖
|
|
1266
|
+
lines.push(`${x.purple}🤖 AGENT${x.reset} ${agentStr} ${DIV} ${loopStr}${latStr}`);
|
|
1235
1267
|
lines.push(SEP);
|
|
1236
1268
|
|
|
1237
|
-
// ── Row 2: Graph
|
|
1269
|
+
// ── Row 2: Graph ─────────────────────────────────────────────
|
|
1238
1270
|
const gf = getGraphifyStats();
|
|
1239
1271
|
const freshness = getGraphFreshness();
|
|
1240
1272
|
let graphStr;
|
|
@@ -1242,54 +1274,72 @@ function generateDashboard() {
|
|
|
1242
1274
|
const nodesFmt = gf.nodes >= 1000 ? `${(gf.nodes / 1000).toFixed(0)}k` : `${gf.nodes}`;
|
|
1243
1275
|
const edgesFmt = gf.edges >= 1000 ? `${(gf.edges / 1000).toFixed(0)}k` : `${gf.edges}`;
|
|
1244
1276
|
const freshTag = freshness.fresh
|
|
1245
|
-
? `${x.green}●
|
|
1277
|
+
? `${x.green}●fresh${x.reset}`
|
|
1246
1278
|
: freshness.stale
|
|
1247
|
-
? `${x.coral}
|
|
1248
|
-
: `${x.gold}
|
|
1249
|
-
graphStr = `${x.sky}
|
|
1279
|
+
? `${x.coral}●${freshness.commitsBehind}stale${x.reset}`
|
|
1280
|
+
: `${x.gold}●${freshness.commitsBehind}behind${x.reset}`;
|
|
1281
|
+
graphStr = `${x.sky}🔗${x.bold}${nodesFmt}${x.reset}${x.slate}n${x.reset} ${x.bold}${edgesFmt}${x.reset}${x.slate}e${x.reset} ${freshTag}`;
|
|
1250
1282
|
} else {
|
|
1251
|
-
graphStr = `${x.slate}🔗
|
|
1283
|
+
graphStr = `${x.slate}🔗no graph${x.reset}`;
|
|
1252
1284
|
}
|
|
1253
1285
|
|
|
1254
1286
|
const hil = getHILPending();
|
|
1255
|
-
let contextLine = `${x.teal}🧠 CONTEXT${x.reset} ${graphStr}`;
|
|
1256
|
-
if (hil.pending > 0) {
|
|
1257
|
-
contextLine += ` ${DIV} ${x.coral}✨ ${x.bold}${hil.pending}${x.reset}${x.coral} HIL pending${x.reset}`;
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
// Graph usage ratio + $ saved
|
|
1261
1287
|
const usage = getGraphUsage();
|
|
1288
|
+
let contextLine = `${x.teal}🧠 CONTEXT${x.reset} ${graphStr}`;
|
|
1262
1289
|
if (usage) {
|
|
1263
1290
|
const col = usage.pct >= 40 ? x.green : usage.pct >= 15 ? x.gold : x.coral;
|
|
1264
1291
|
const savedCol = usage.dollarsSaved >= 0.10 ? x.green : x.slate;
|
|
1265
|
-
contextLine += `
|
|
1292
|
+
contextLine += ` ${DIV} ${col}📊${usage.pct}%${x.reset}${x.slate}·${100 - usage.pct}%grep${x.reset} ${savedCol}💰$${usage.dollarsSaved.toFixed(2)}${x.reset}`;
|
|
1293
|
+
}
|
|
1294
|
+
if (hil.pending > 0) {
|
|
1295
|
+
contextLine += ` ${DIV} ${x.coral}✨${x.bold}${hil.pending}${x.reset}${x.coral}HIL${x.reset}`;
|
|
1266
1296
|
}
|
|
1267
|
-
|
|
1268
|
-
// Token cost
|
|
1269
1297
|
const tokenCost = getTokenCostSummary();
|
|
1270
1298
|
if (tokenCost) {
|
|
1271
1299
|
if (tokenCost.isFresh && tokenCost.todayCost > 0) {
|
|
1272
1300
|
const col = tokenCost.todayCost > 50 ? x.coral : tokenCost.todayCost > 10 ? x.gold : x.mint;
|
|
1273
|
-
contextLine += `
|
|
1301
|
+
contextLine += ` ${DIV} ${col}${fmtCost(tokenCost.todayCost)}${x.reset}${x.dim}·${fmtCost(tokenCost.monthCost)}mo${x.reset}`;
|
|
1274
1302
|
} else if (tokenCost.monthCost > 0) {
|
|
1275
|
-
contextLine += `
|
|
1303
|
+
contextLine += ` ${DIV} ${x.slate}${fmtCost(tokenCost.monthCost)}mo${x.reset}`;
|
|
1276
1304
|
}
|
|
1277
1305
|
}
|
|
1278
|
-
|
|
1279
1306
|
lines.push(contextLine);
|
|
1280
1307
|
|
|
1281
|
-
// ── Row 3:
|
|
1308
|
+
// ── Row 3: Docs / knowledge ──────────────────────────────────
|
|
1309
|
+
const docStats = getDocStats();
|
|
1310
|
+
if (docStats.exists) {
|
|
1311
|
+
const parts = [];
|
|
1312
|
+
if (docStats.docs > 0) {
|
|
1313
|
+
const docFmt = docStats.docs >= 1000 ? `${(docStats.docs / 1000).toFixed(1)}k` : `${docStats.docs}`;
|
|
1314
|
+
parts.push(`${x.bold}${docFmt}${x.reset}${x.slate}docs${x.reset}`);
|
|
1315
|
+
}
|
|
1316
|
+
if (docStats.chunks > 0) parts.push(`${x.bold}${docStats.chunks}${x.reset}${x.slate}chunks${x.reset}`);
|
|
1317
|
+
if (docStats.memories > 0) parts.push(`${x.bold}${docStats.memories}${x.reset}${x.slate}mem${x.reset}`);
|
|
1318
|
+
// OKF export check
|
|
1319
|
+
const okfDir = path.join(CWD, '.monomind', 'exports');
|
|
1320
|
+
try {
|
|
1321
|
+
if (fs.existsSync(okfDir)) {
|
|
1322
|
+
const okfFiles = cleanEntries(okfDir, f => f.endsWith('.md') || f.endsWith('.json'));
|
|
1323
|
+
if (okfFiles.length > 0) parts.push(`${x.bold}${okfFiles.length}${x.reset}${x.slate}okf${x.reset}`);
|
|
1324
|
+
}
|
|
1325
|
+
} catch { /* ignore */ }
|
|
1326
|
+
if (parts.length) {
|
|
1327
|
+
lines.push(`${x.dim} 📄 ${parts.join(' ')}${x.reset}`);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
// ── Row 4: Active org runs ───────────────────────────────────
|
|
1282
1332
|
const orgStatus = getActiveOrgs();
|
|
1283
1333
|
if (orgStatus.count > 0) {
|
|
1284
1334
|
lines.push(SEP);
|
|
1285
1335
|
const orgParts = orgStatus.orgs.slice(0, 5).map(o => {
|
|
1286
1336
|
const ageMin = Math.floor(o.ageMs / 60000);
|
|
1287
|
-
const ageFmt = ageMin < 1 ? '
|
|
1337
|
+
const ageFmt = ageMin < 1 ? 'now' : ageMin < 60 ? `${ageMin}m` : `${Math.floor(ageMin / 60)}h`;
|
|
1288
1338
|
const col = o.running ? x.green : x.slate;
|
|
1289
1339
|
const dot2 = o.running ? `${x.green}●${x.reset}` : `${x.slate}◌${x.reset}`;
|
|
1290
|
-
return `${dot2}
|
|
1340
|
+
return `${dot2}${col}${x.bold}${o.name}${x.reset} ${x.dim}${ageFmt}${x.reset}`;
|
|
1291
1341
|
});
|
|
1292
|
-
lines.push(`${x.purple}🏛
|
|
1342
|
+
lines.push(`${x.purple}🏛 ORGS${x.reset} ${orgParts.join(` ${DIV} `)}`);
|
|
1293
1343
|
}
|
|
1294
1344
|
|
|
1295
1345
|
return lines.join('\n');
|
|
@@ -658,8 +658,10 @@ function injectGodNodesContext(CWD) {
|
|
|
658
658
|
var godStr = godNodes.slice(0, 8).map(function(n) {
|
|
659
659
|
return n.name + ' (' + n.label + ', ' + n.deg + ' links)';
|
|
660
660
|
}).join(', ');
|
|
661
|
-
|
|
662
|
-
|
|
661
|
+
if (String(process.env.MONOMIND_HOOK_QUIET || '') !== '1') {
|
|
662
|
+
console.log('[MONOGRAPH_CONTEXT] ' + nodeCount + ' nodes · ' + edgeCount + ' edges. Key nodes: ' + godStr + staleIndicator);
|
|
663
|
+
console.log('[MONOGRAPH_ACTIVE] Indexed knowledge graph available — prefer monograph_query / monograph_suggest over grep/find for symbol and definition lookups.');
|
|
664
|
+
}
|
|
663
665
|
|
|
664
666
|
// Write god nodes into knowledge/chunks.jsonl so semantic search finds them.
|
|
665
667
|
var knowledgeDir = path.join(CWD, '.monomind', 'knowledge');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cap-documents.d.ts","sourceRoot":"","sources":["../../../src/capabilities/cap-documents.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cap-documents.d.ts","sourceRoot":"","sources":["../../../src/capabilities/cap-documents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAEhB,SAAS,EAIV,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,cAAc,aASzB,CAAC;AA+GH,wBAAsB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CA8HlE;AAED,eAAO,MAAM,mBAAmB,EAAE,gBAsGjC,CAAC"}
|