@monoes/monomindcli 1.10.29 โ 1.10.31
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/auto-memory-hook.mjs +39 -4
- package/.claude/helpers/handlers/adr-draft-handler.cjs +64 -0
- package/.claude/helpers/handlers/agent-start-handler.cjs +99 -0
- package/.claude/helpers/handlers/edit-handler.cjs +145 -0
- package/.claude/helpers/handlers/graph-status-handler.cjs +38 -0
- package/.claude/helpers/handlers/route-handler.cjs +393 -0
- package/.claude/helpers/handlers/session-handler.cjs +167 -0
- package/.claude/helpers/handlers/session-restore-handler.cjs +348 -0
- package/.claude/helpers/handlers/task-handler.cjs +329 -0
- package/.claude/helpers/hook-handler.cjs +120 -2431
- package/.claude/helpers/intelligence.cjs +21 -2
- package/.claude/helpers/learning-service.mjs +166 -8
- package/.claude/helpers/memory-palace.cjs +72 -12
- package/.claude/helpers/router.cjs +79 -5
- package/.claude/helpers/statusline.cjs +193 -399
- package/.claude/helpers/utils/micro-agents.cjs +338 -0
- package/.claude/helpers/utils/monograph.cjs +349 -0
- package/.claude/helpers/utils/telemetry.cjs +144 -0
- package/.claude/skills/agent-browser-testing/SKILL.md +3 -2
- package/.claude/skills/monomind/browse-agentcore.md +116 -0
- package/.claude/skills/monomind/browse-electron.md +189 -0
- package/.claude/skills/monomind/browse-qa.md +229 -0
- package/.claude/skills/monomind/browse-references/authentication.md +162 -0
- package/.claude/skills/monomind/browse-references/trust-boundaries.md +41 -0
- package/.claude/skills/monomind/browse-references/video-recording.md +84 -0
- package/.claude/skills/monomind/browse-slack.md +189 -0
- package/.claude/skills/monomind/browse-vercel.md +240 -0
- package/.claude/skills/monomind/browse.md +724 -0
- package/dist/src/browser/actions.d.ts +28 -0
- package/dist/src/browser/actions.d.ts.map +1 -0
- package/dist/src/browser/actions.js +292 -0
- package/dist/src/browser/actions.js.map +1 -0
- package/dist/src/browser/batch.d.ts +13 -0
- package/dist/src/browser/batch.d.ts.map +1 -0
- package/dist/src/browser/batch.js +11 -0
- package/dist/src/browser/batch.js.map +1 -0
- package/dist/src/browser/browser.d.ts +14 -0
- package/dist/src/browser/browser.d.ts.map +1 -0
- package/dist/src/browser/browser.js +198 -0
- package/dist/src/browser/browser.js.map +1 -0
- package/dist/src/browser/cdp.d.ts +17 -0
- package/dist/src/browser/cdp.d.ts.map +1 -0
- package/dist/src/browser/cdp.js +106 -0
- package/dist/src/browser/cdp.js.map +1 -0
- package/dist/src/browser/console-log.d.ts +22 -0
- package/dist/src/browser/console-log.d.ts.map +1 -0
- package/dist/src/browser/console-log.js +55 -0
- package/dist/src/browser/console-log.js.map +1 -0
- package/dist/src/browser/dialog.d.ts +11 -0
- package/dist/src/browser/dialog.d.ts.map +1 -0
- package/dist/src/browser/dialog.js +36 -0
- package/dist/src/browser/dialog.js.map +1 -0
- package/dist/src/browser/emulation.d.ts +15 -0
- package/dist/src/browser/emulation.d.ts.map +1 -0
- package/dist/src/browser/emulation.js +62 -0
- package/dist/src/browser/emulation.js.map +1 -0
- package/dist/src/browser/find.d.ts +21 -0
- package/dist/src/browser/find.d.ts.map +1 -0
- package/dist/src/browser/find.js +118 -0
- package/dist/src/browser/find.js.map +1 -0
- package/dist/src/browser/index.d.ts +18 -0
- package/dist/src/browser/index.d.ts.map +1 -0
- package/dist/src/browser/index.js +18 -0
- package/dist/src/browser/index.js.map +1 -0
- package/dist/src/browser/network.d.ts +11 -0
- package/dist/src/browser/network.d.ts.map +1 -0
- package/dist/src/browser/network.js +81 -0
- package/dist/src/browser/network.js.map +1 -0
- package/dist/src/browser/pdf.d.ts +15 -0
- package/dist/src/browser/pdf.d.ts.map +1 -0
- package/dist/src/browser/pdf.js +27 -0
- package/dist/src/browser/pdf.js.map +1 -0
- package/dist/src/browser/screenshot.d.ts +15 -0
- package/dist/src/browser/screenshot.d.ts.map +1 -0
- package/dist/src/browser/screenshot.js +36 -0
- package/dist/src/browser/screenshot.js.map +1 -0
- package/dist/src/browser/session.d.ts +8 -0
- package/dist/src/browser/session.d.ts.map +1 -0
- package/dist/src/browser/session.js +50 -0
- package/dist/src/browser/session.js.map +1 -0
- package/dist/src/browser/snapshot.d.ts +12 -0
- package/dist/src/browser/snapshot.d.ts.map +1 -0
- package/dist/src/browser/snapshot.js +147 -0
- package/dist/src/browser/snapshot.js.map +1 -0
- package/dist/src/browser/storage.d.ts +11 -0
- package/dist/src/browser/storage.d.ts.map +1 -0
- package/dist/src/browser/storage.js +43 -0
- package/dist/src/browser/storage.js.map +1 -0
- package/dist/src/browser/tabs.d.ts +8 -0
- package/dist/src/browser/tabs.d.ts.map +1 -0
- package/dist/src/browser/tabs.js +25 -0
- package/dist/src/browser/tabs.js.map +1 -0
- package/dist/src/browser/types.d.ts +109 -0
- package/dist/src/browser/types.d.ts.map +1 -0
- package/dist/src/browser/types.js +16 -0
- package/dist/src/browser/types.js.map +1 -0
- package/dist/src/browser/wait.d.ts +4 -0
- package/dist/src/browser/wait.d.ts.map +1 -0
- package/dist/src/browser/wait.js +122 -0
- package/dist/src/browser/wait.js.map +1 -0
- package/dist/src/commands/browse.d.ts +8 -0
- package/dist/src/commands/browse.d.ts.map +1 -0
- package/dist/src/commands/browse.js +1494 -0
- package/dist/src/commands/browse.js.map +1 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +2 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/ui/dashboard-v2.html +1857 -0
- package/dist/src/ui/server.mjs +71 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
|
@@ -28,11 +28,13 @@ const CWD = process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
|
28
28
|
|
|
29
29
|
// Read monomind version โ check global install first, then CWD package.json
|
|
30
30
|
function getVersion() {
|
|
31
|
-
// 1.
|
|
31
|
+
// 1. Monomind global install: script lives at <install>/packages/@monomind/cli/dist/src/init/
|
|
32
|
+
// or user project: .claude/helpers/statusline.cjs
|
|
33
|
+
// Walk up to find a monomind package.json (has "name":"monomind" or "@monomind/cli")
|
|
32
34
|
const scriptDir = path.dirname(__filename);
|
|
33
35
|
const walkCandidates = [
|
|
34
|
-
path.join(scriptDir, '..', '..', 'package.json'),
|
|
35
|
-
path.join(scriptDir, '..', '..', '..', 'package.json'),
|
|
36
|
+
path.join(scriptDir, '..', '..', 'package.json'), // dist/src -> @monomind/cli
|
|
37
|
+
path.join(scriptDir, '..', '..', '..', 'package.json'), // -> monomind umbrella
|
|
36
38
|
path.join(scriptDir, '..', '..', '..', '..', 'package.json'),
|
|
37
39
|
];
|
|
38
40
|
for (const p of walkCandidates) {
|
|
@@ -45,6 +47,7 @@ function getVersion() {
|
|
|
45
47
|
}
|
|
46
48
|
// 2. Fallback: npm global prefix
|
|
47
49
|
try {
|
|
50
|
+
const { execSync } = require('child_process');
|
|
48
51
|
const prefix = execSync('npm config get prefix', { encoding: 'utf-8', timeout: 2000 }).trim();
|
|
49
52
|
const pkg = JSON.parse(fs.readFileSync(path.join(prefix, 'lib', 'node_modules', 'monomind', 'package.json'), 'utf-8'));
|
|
50
53
|
if (pkg.version) return `v${pkg.version}`;
|
|
@@ -104,6 +107,16 @@ function safeStat(filePath) {
|
|
|
104
107
|
return null;
|
|
105
108
|
}
|
|
106
109
|
|
|
110
|
+
// Shared settings cache โ read once, used by multiple functions
|
|
111
|
+
let _settingsCache = undefined;
|
|
112
|
+
function getSettings() {
|
|
113
|
+
if (_settingsCache !== undefined) return _settingsCache;
|
|
114
|
+
_settingsCache = readJSON(path.join(CWD, '.claude', 'settings.json'))
|
|
115
|
+
|| readJSON(path.join(CWD, '.claude', 'settings.local.json'))
|
|
116
|
+
|| null;
|
|
117
|
+
return _settingsCache;
|
|
118
|
+
}
|
|
119
|
+
|
|
107
120
|
// Project identifier โ github owner/repo from git remote, else folder name
|
|
108
121
|
function getProjectName() {
|
|
109
122
|
try {
|
|
@@ -116,16 +129,6 @@ function getProjectName() {
|
|
|
116
129
|
return path.basename(CWD);
|
|
117
130
|
}
|
|
118
131
|
|
|
119
|
-
// Shared settings cache โ read once, used by multiple functions
|
|
120
|
-
let _settingsCache = undefined;
|
|
121
|
-
function getSettings() {
|
|
122
|
-
if (_settingsCache !== undefined) return _settingsCache;
|
|
123
|
-
_settingsCache = readJSON(path.join(CWD, '.claude', 'settings.json'))
|
|
124
|
-
|| readJSON(path.join(CWD, '.claude', 'settings.local.json'))
|
|
125
|
-
|| null;
|
|
126
|
-
return _settingsCache;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
132
|
// โโโ Data Collection (all pure-Node.js or single-exec) โโโโโโโโโโ
|
|
130
133
|
|
|
131
134
|
// Get all git info in ONE shell call
|
|
@@ -385,7 +388,6 @@ function getSwarmStatus() {
|
|
|
385
388
|
activeAgents: liveCount,
|
|
386
389
|
maxAgents: CONFIG.maxAgents,
|
|
387
390
|
coordinationActive: true,
|
|
388
|
-
lastActive: liveCount,
|
|
389
391
|
};
|
|
390
392
|
}
|
|
391
393
|
} catch { /* fall through */ }
|
|
@@ -398,12 +400,10 @@ function getSwarmStatus() {
|
|
|
398
400
|
const updatedAt = swarmState.updatedAt || swarmState.startedAt;
|
|
399
401
|
const age = updatedAt ? now - new Date(updatedAt).getTime() : Infinity;
|
|
400
402
|
if (age < staleThresholdMs) {
|
|
401
|
-
const sc = swarmState.agents?.length || swarmState.agentCount || 0;
|
|
402
403
|
return {
|
|
403
|
-
activeAgents:
|
|
404
|
+
activeAgents: swarmState.agents?.length || swarmState.agentCount || 0,
|
|
404
405
|
maxAgents: swarmState.maxAgents || CONFIG.maxAgents,
|
|
405
406
|
coordinationActive: true,
|
|
406
|
-
lastActive: sc,
|
|
407
407
|
};
|
|
408
408
|
}
|
|
409
409
|
}
|
|
@@ -418,23 +418,11 @@ function getSwarmStatus() {
|
|
|
418
418
|
activeAgents: activityData.swarm.agent_count || 0,
|
|
419
419
|
maxAgents: CONFIG.maxAgents,
|
|
420
420
|
coordinationActive: activityData.swarm.coordination_active || activityData.swarm.active || false,
|
|
421
|
-
lastActive: activityData.swarm.lastActive || 0,
|
|
422
421
|
};
|
|
423
422
|
}
|
|
424
|
-
// Only show lastActive if data is recent enough (< 1 hour) and plausible (โค maxAgents)
|
|
425
|
-
const displayTtlMs = 60 * 60 * 1000;
|
|
426
|
-
const lastActive = (age < displayTtlMs)
|
|
427
|
-
? Math.min(activityData.swarm.lastActive || 0, CONFIG.maxAgents)
|
|
428
|
-
: 0;
|
|
429
|
-
return {
|
|
430
|
-
activeAgents: 0,
|
|
431
|
-
maxAgents: CONFIG.maxAgents,
|
|
432
|
-
coordinationActive: false,
|
|
433
|
-
lastActive,
|
|
434
|
-
};
|
|
435
423
|
}
|
|
436
424
|
|
|
437
|
-
return { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false
|
|
425
|
+
return { activeAgents: 0, maxAgents: CONFIG.maxAgents, coordinationActive: false };
|
|
438
426
|
}
|
|
439
427
|
|
|
440
428
|
// System metrics (uses process.memoryUsage() โ no shell spawn)
|
|
@@ -565,7 +553,6 @@ function getActiveAgent() {
|
|
|
565
553
|
category: data.category || null,
|
|
566
554
|
confidence: data.confidence || 0,
|
|
567
555
|
activated: data.activated || false, // true = manually loaded extras agent
|
|
568
|
-
extrasMatches: data.extrasMatches || [],
|
|
569
556
|
};
|
|
570
557
|
} catch { return null; }
|
|
571
558
|
}
|
|
@@ -577,56 +564,26 @@ function getAgentDBStats() {
|
|
|
577
564
|
let namespaces = 0;
|
|
578
565
|
let hasHnsw = false;
|
|
579
566
|
|
|
580
|
-
// Count
|
|
581
|
-
// 0. Palace drawers
|
|
582
|
-
const drawersPath = path.join(CWD, '.monomind', 'palace', 'drawers.jsonl');
|
|
583
|
-
const drawersStat = safeStat(drawersPath);
|
|
584
|
-
if (drawersStat) {
|
|
585
|
-
dbSizeKB += drawersStat.size / 1024;
|
|
586
|
-
try {
|
|
587
|
-
vectorCount += fs.readFileSync(drawersPath, 'utf-8').split('\n').filter(Boolean).length;
|
|
588
|
-
} catch { /* ignore */ }
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// 1. Palace closets
|
|
592
|
-
const closetsPath = path.join(CWD, '.monomind', 'palace', 'closets.jsonl');
|
|
593
|
-
const closetsStat = safeStat(closetsPath);
|
|
594
|
-
if (closetsStat) {
|
|
595
|
-
dbSizeKB += closetsStat.size / 1024;
|
|
596
|
-
try {
|
|
597
|
-
vectorCount += fs.readFileSync(closetsPath, 'utf-8').split('\n').filter(Boolean).length;
|
|
598
|
-
} catch { /* ignore */ }
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// 2. Knowledge chunks
|
|
602
|
-
const chunksPath = path.join(CWD, '.monomind', 'knowledge', 'chunks.jsonl');
|
|
603
|
-
const chunksStat = safeStat(chunksPath);
|
|
604
|
-
if (chunksStat) {
|
|
605
|
-
dbSizeKB += chunksStat.size / 1024;
|
|
606
|
-
try {
|
|
607
|
-
vectorCount += fs.readFileSync(chunksPath, 'utf-8').split('\n').filter(Boolean).length;
|
|
608
|
-
} catch { /* ignore */ }
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// 3. Auto-memory store (intelligence layer)
|
|
567
|
+
// 1. Count real entries from auto-memory-store.json
|
|
612
568
|
const storePath = path.join(CWD, '.monomind', 'data', 'auto-memory-store.json');
|
|
613
569
|
const storeStat = safeStat(storePath);
|
|
614
570
|
if (storeStat) {
|
|
615
571
|
dbSizeKB += storeStat.size / 1024;
|
|
616
572
|
try {
|
|
617
573
|
const store = JSON.parse(fs.readFileSync(storePath, 'utf-8'));
|
|
618
|
-
|
|
619
|
-
|
|
574
|
+
if (Array.isArray(store)) vectorCount += store.length;
|
|
575
|
+
else if (store?.entries) vectorCount += store.entries.length;
|
|
576
|
+
} catch { /* fall back to size estimate */ }
|
|
620
577
|
}
|
|
621
578
|
|
|
622
|
-
//
|
|
579
|
+
// 2. Count entries from ranked-context.json
|
|
623
580
|
const rankedPath = path.join(CWD, '.monomind', 'data', 'ranked-context.json');
|
|
624
581
|
try {
|
|
625
582
|
const ranked = readJSON(rankedPath);
|
|
626
|
-
if (ranked?.entries?.length) vectorCount
|
|
583
|
+
if (ranked?.entries?.length > vectorCount) vectorCount = ranked.entries.length;
|
|
627
584
|
} catch { /* ignore */ }
|
|
628
585
|
|
|
629
|
-
//
|
|
586
|
+
// 3. Add DB file sizes
|
|
630
587
|
const dbFiles = [
|
|
631
588
|
path.join(CWD, 'data', 'memory.db'),
|
|
632
589
|
path.join(CWD, '.monomind', 'memory.db'),
|
|
@@ -634,17 +591,31 @@ function getAgentDBStats() {
|
|
|
634
591
|
];
|
|
635
592
|
for (const f of dbFiles) {
|
|
636
593
|
const stat = safeStat(f);
|
|
637
|
-
if (stat) {
|
|
594
|
+
if (stat) {
|
|
595
|
+
dbSizeKB += stat.size / 1024;
|
|
596
|
+
namespaces++;
|
|
597
|
+
}
|
|
638
598
|
}
|
|
639
599
|
|
|
640
|
-
//
|
|
600
|
+
// 4. Check for graph data
|
|
601
|
+
const graphPath = path.join(CWD, 'data', 'memory.graph');
|
|
602
|
+
const graphStat = safeStat(graphPath);
|
|
603
|
+
if (graphStat) dbSizeKB += graphStat.size / 1024;
|
|
604
|
+
|
|
605
|
+
// 5. HNSW index
|
|
641
606
|
const hnswPaths = [
|
|
642
607
|
path.join(CWD, '.swarm', 'hnsw.index'),
|
|
643
608
|
path.join(CWD, '.monomind', 'hnsw.index'),
|
|
644
609
|
];
|
|
645
610
|
for (const p of hnswPaths) {
|
|
646
|
-
|
|
611
|
+
const stat = safeStat(p);
|
|
612
|
+
if (stat) {
|
|
613
|
+
hasHnsw = true;
|
|
614
|
+
break;
|
|
615
|
+
}
|
|
647
616
|
}
|
|
617
|
+
|
|
618
|
+
// HNSW is available if memory package is present
|
|
648
619
|
if (!hasHnsw) {
|
|
649
620
|
const memPkgPaths = [
|
|
650
621
|
path.join(CWD, 'packages', '@monomind', 'memory', 'dist'),
|
|
@@ -658,234 +629,6 @@ function getAgentDBStats() {
|
|
|
658
629
|
return { vectorCount, dbSizeKB: Math.floor(dbSizeKB), namespaces, hasHnsw };
|
|
659
630
|
}
|
|
660
631
|
|
|
661
|
-
// Graphify knowledge graph stats
|
|
662
|
-
// Sources, in priority order:
|
|
663
|
-
// 1. .monomind/graph/stats.json โ explicit cached stats
|
|
664
|
-
// 2. .monomind/monograph.db โ live SQLite (read counts via sqlite3)
|
|
665
|
-
// 3. .monomind/graph/graph.json โ legacy JSON dump
|
|
666
|
-
function getGraphifyStats() {
|
|
667
|
-
const statsPath = path.join(CWD, '.monomind', 'graph', 'stats.json');
|
|
668
|
-
const dbPath = path.join(CWD, '.monomind', 'monograph.db');
|
|
669
|
-
const graphPath = path.join(CWD, '.monomind', 'graph', 'graph.json');
|
|
670
|
-
|
|
671
|
-
try {
|
|
672
|
-
const s = readJSON(statsPath);
|
|
673
|
-
if (s && s.nodes !== undefined) return { nodes: s.nodes, edges: s.edges || 0, exists: true };
|
|
674
|
-
} catch { /* ignore */ }
|
|
675
|
-
|
|
676
|
-
// Live monograph.db โ single SQLite call, strict 1s timeout
|
|
677
|
-
try {
|
|
678
|
-
if (fs.existsSync(dbPath)) {
|
|
679
|
-
const out = safeExec(`sqlite3 "${dbPath}" "SELECT (SELECT COUNT(*) FROM nodes), (SELECT COUNT(*) FROM edges);"`, 1000);
|
|
680
|
-
if (out) {
|
|
681
|
-
const [n, e] = out.split('|').map(v => parseInt(v, 10) || 0);
|
|
682
|
-
if (n > 0) return { nodes: n, edges: e, exists: true };
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
} catch { /* ignore */ }
|
|
686
|
-
|
|
687
|
-
try {
|
|
688
|
-
const stat = safeStat(graphPath);
|
|
689
|
-
if (stat && stat.size < 10 * 1024 * 1024) {
|
|
690
|
-
const g = JSON.parse(fs.readFileSync(graphPath, 'utf-8'));
|
|
691
|
-
const nodes = Array.isArray(g.nodes) ? g.nodes.length : 0;
|
|
692
|
-
const edges = (Array.isArray(g.edges) ? g.edges : (Array.isArray(g.links) ? g.links : [])).length;
|
|
693
|
-
return { nodes, edges, exists: true };
|
|
694
|
-
}
|
|
695
|
-
} catch { /* ignore */ }
|
|
696
|
-
return { nodes: 0, edges: 0, exists: false };
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
// Hook latency โ sum of mean times for hooks that fire on every prompt.
|
|
700
|
-
function getHookLatency() {
|
|
701
|
-
const p = path.join(CWD, '.monomind', 'metrics', 'hook-latency.json');
|
|
702
|
-
try {
|
|
703
|
-
if (!fs.existsSync(p)) return null;
|
|
704
|
-
const d = JSON.parse(fs.readFileSync(p, 'utf-8'));
|
|
705
|
-
// Hooks that run per-prompt: route, pre-search, post-read, post-edit
|
|
706
|
-
const perPrompt = ['route'];
|
|
707
|
-
let totalMs = 0;
|
|
708
|
-
let count = 0;
|
|
709
|
-
for (const h of perPrompt) {
|
|
710
|
-
if (d[h] && d[h].mean) { totalMs += d[h].mean; count++; }
|
|
711
|
-
}
|
|
712
|
-
if (count === 0) return null;
|
|
713
|
-
// Find slowest hook
|
|
714
|
-
let slowest = null;
|
|
715
|
-
for (const k of Object.keys(d)) {
|
|
716
|
-
if (k === 'lastUpdated' || !d[k] || typeof d[k] !== 'object') continue;
|
|
717
|
-
if (!slowest || d[k].mean > slowest.mean) slowest = { name: k, mean: d[k].mean };
|
|
718
|
-
}
|
|
719
|
-
return { perPromptMs: totalMs, slowest };
|
|
720
|
-
} catch { return null; }
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
// Graph usage telemetry โ counts ALL graph wins (MCP calls + silent assists)
|
|
724
|
-
// vs greps that got no graph help. "graph %" reflects how often the graph
|
|
725
|
-
// actually touched the LLM's flow, not just how often the LLM invoked MCP.
|
|
726
|
-
function getGraphUsage() {
|
|
727
|
-
const usagePath = path.join(CWD, '.monomind', 'metrics', 'graph-usage.json');
|
|
728
|
-
try {
|
|
729
|
-
if (!fs.existsSync(usagePath)) return null;
|
|
730
|
-
const d = JSON.parse(fs.readFileSync(usagePath, 'utf-8'));
|
|
731
|
-
const graphWins =
|
|
732
|
-
(d.monograph_call || 0) // LLM-initiated MCP monograph tool call
|
|
733
|
-
+ (d.preresolve_hit || 0) // route hook injected pre-resolved files
|
|
734
|
-
+ (d.graph_assist_search || 0) // pre-search / pre-bash injected hits
|
|
735
|
-
+ (d.graph_assist_neighbors || 0); // post-read neighbor footer
|
|
736
|
-
const searches = (d.grep_call || 0) + (d.glob_call || 0)
|
|
737
|
-
+ (d.bash_grep_call || 0) + (d.bash_find_call || 0);
|
|
738
|
-
const total = graphWins + searches;
|
|
739
|
-
if (total === 0) return null;
|
|
740
|
-
return {
|
|
741
|
-
graphWins,
|
|
742
|
-
searches,
|
|
743
|
-
pct: Math.round((graphWins / total) * 100),
|
|
744
|
-
dollarsSaved: d.dollars_saved || 0,
|
|
745
|
-
};
|
|
746
|
-
} catch { return null; }
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
// Graph freshness โ compare graph build time against most recent commit
|
|
750
|
-
// Returns: { commitsBehind, stale } where stale = >5 commits or never built
|
|
751
|
-
function getGraphFreshness() {
|
|
752
|
-
const lockPath = path.join(CWD, '.monomind', 'graph', '.rebuild-lock');
|
|
753
|
-
const dbPath = path.join(CWD, '.monomind', 'monograph.db');
|
|
754
|
-
|
|
755
|
-
let buildMs = 0;
|
|
756
|
-
try {
|
|
757
|
-
const lockStat = safeStat(lockPath);
|
|
758
|
-
const dbStat = safeStat(dbPath);
|
|
759
|
-
buildMs = Math.max(lockStat?.mtimeMs || 0, dbStat?.mtimeMs || 0);
|
|
760
|
-
} catch { /* ignore */ }
|
|
761
|
-
if (!buildMs) return { commitsBehind: -1, stale: true, fresh: false };
|
|
762
|
-
|
|
763
|
-
// Count commits since the graph was last built
|
|
764
|
-
const buildIso = new Date(buildMs).toISOString();
|
|
765
|
-
const out = safeExec(`git rev-list --count --since='${buildIso}' HEAD 2>/dev/null`, 1500);
|
|
766
|
-
const commitsBehind = parseInt(out, 10) || 0;
|
|
767
|
-
return {
|
|
768
|
-
commitsBehind,
|
|
769
|
-
stale: commitsBehind > 5,
|
|
770
|
-
fresh: commitsBehind === 0,
|
|
771
|
-
};
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
// Active loops โ scan .monomind/loops/*.json
|
|
775
|
-
// Filters: skip *-hil*.json, skip stale (>6h since lastRunAt)
|
|
776
|
-
function getLoopStatus() {
|
|
777
|
-
const loopsDir = path.join(CWD, '.monomind', 'loops');
|
|
778
|
-
if (!fs.existsSync(loopsDir)) return { count: 0, loops: [] };
|
|
779
|
-
const STALE_MS = 6 * 60 * 60 * 1000;
|
|
780
|
-
const now = Date.now();
|
|
781
|
-
let loops = [];
|
|
782
|
-
try {
|
|
783
|
-
const files = fs.readdirSync(loopsDir).filter(f =>
|
|
784
|
-
f.endsWith('.json') && !f.includes('-hil') && !f.endsWith('.stop'));
|
|
785
|
-
for (const f of files) {
|
|
786
|
-
const d = readJSON(path.join(loopsDir, f));
|
|
787
|
-
if (!d || !d.command) continue;
|
|
788
|
-
const last = d.lastRunAt || d.nextRunAt || d.startedAt || 0;
|
|
789
|
-
if (last && (now - last) > STALE_MS) continue;
|
|
790
|
-
loops.push({
|
|
791
|
-
cmd: d.command.replace(/^\//,''),
|
|
792
|
-
type: d.type || 'repeat',
|
|
793
|
-
rep: d.currentRep || 0,
|
|
794
|
-
max: d.maxReps || 0,
|
|
795
|
-
status: d.status || 'running',
|
|
796
|
-
});
|
|
797
|
-
}
|
|
798
|
-
} catch { /* ignore */ }
|
|
799
|
-
return { count: loops.length, loops };
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
// HIL pending โ count <id>-hil.md files with no human response yet
|
|
803
|
-
function getHILPending() {
|
|
804
|
-
const loopsDir = path.join(CWD, '.monomind', 'loops');
|
|
805
|
-
if (!fs.existsSync(loopsDir)) return { pending: 0 };
|
|
806
|
-
let pending = 0;
|
|
807
|
-
try {
|
|
808
|
-
const files = fs.readdirSync(loopsDir).filter(f => f.endsWith('-hil.md'));
|
|
809
|
-
for (const f of files) {
|
|
810
|
-
try {
|
|
811
|
-
const txt = fs.readFileSync(path.join(loopsDir, f), 'utf-8');
|
|
812
|
-
// A response is a line starting with "> " followed by non-whitespace
|
|
813
|
-
const answered = /^[ \t]*>[ \t]+\S/m.test(txt);
|
|
814
|
-
if (!answered) pending++;
|
|
815
|
-
} catch { /* ignore */ }
|
|
816
|
-
}
|
|
817
|
-
} catch { /* ignore */ }
|
|
818
|
-
return { pending };
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
// Memory Palace stats โ drawers.jsonl + kg.json (the real persistent memory)
|
|
822
|
-
function getMemoryPalaceStats() {
|
|
823
|
-
const palaceDir = path.join(CWD, '.monomind', 'palace');
|
|
824
|
-
let drawers = 0, triples = 0, palaceSizeKB = 0;
|
|
825
|
-
|
|
826
|
-
try {
|
|
827
|
-
const drawersPath = path.join(palaceDir, 'drawers.jsonl');
|
|
828
|
-
if (fs.existsSync(drawersPath)) {
|
|
829
|
-
const stat = safeStat(drawersPath);
|
|
830
|
-
if (stat) palaceSizeKB += stat.size / 1024;
|
|
831
|
-
drawers = fs.readFileSync(drawersPath, 'utf-8').split('\n').filter(Boolean).length;
|
|
832
|
-
}
|
|
833
|
-
} catch { /* ignore */ }
|
|
834
|
-
|
|
835
|
-
try {
|
|
836
|
-
const kgPath = path.join(palaceDir, 'kg.json');
|
|
837
|
-
const kg = readJSON(kgPath);
|
|
838
|
-
if (kg?.triples) {
|
|
839
|
-
triples = kg.triples.length;
|
|
840
|
-
const kgStat = safeStat(kgPath);
|
|
841
|
-
if (kgStat) palaceSizeKB += kgStat.size / 1024;
|
|
842
|
-
}
|
|
843
|
-
} catch { /* ignore */ }
|
|
844
|
-
|
|
845
|
-
return { drawers, triples, palaceSizeKB: Math.floor(palaceSizeKB) };
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
// Auto-memory file stats โ reads ~/.claude/projects/<slug>/memory/*.md
|
|
849
|
-
function getAutoMemoryStats() {
|
|
850
|
-
const homeDir = os.homedir();
|
|
851
|
-
const slug = path.resolve(CWD).replace(/\//g, '-');
|
|
852
|
-
const memDir = path.join(homeDir, '.claude', 'projects', slug, 'memory');
|
|
853
|
-
let files = [];
|
|
854
|
-
try {
|
|
855
|
-
files = fs.readdirSync(memDir).filter(f => f.endsWith('.md') && f !== 'MEMORY.md');
|
|
856
|
-
} catch { /* dir may not exist */ }
|
|
857
|
-
|
|
858
|
-
const byType = {};
|
|
859
|
-
for (const fname of files) {
|
|
860
|
-
let type = 'project';
|
|
861
|
-
try {
|
|
862
|
-
const raw = fs.readFileSync(path.join(memDir, fname), 'utf-8').replace(/\r\n/g, '\n');
|
|
863
|
-
const m = raw.match(/^---\n[\s\S]*?type:\s*(\S+)/);
|
|
864
|
-
if (m) type = m[1].trim();
|
|
865
|
-
} catch { /* ignore */ }
|
|
866
|
-
byType[type] = (byType[type] || 0) + 1;
|
|
867
|
-
}
|
|
868
|
-
return { count: files.length, byType };
|
|
869
|
-
}
|
|
870
|
-
|
|
871
|
-
// Token summary โ reads cache written by session-restore hook.
|
|
872
|
-
// Valid for the entire UTC day it was written; expires at midnight UTC.
|
|
873
|
-
function getTokenStats() {
|
|
874
|
-
const cachePath = path.join(CWD, '.monomind', 'metrics', 'token-summary.json');
|
|
875
|
-
const data = readJSON(cachePath);
|
|
876
|
-
if (!data) return null;
|
|
877
|
-
// Reject only if cache is from a different UTC day (midnight boundary)
|
|
878
|
-
const cachedDay = (data.cachedAt || '').slice(0, 10); // "2026-04-15"
|
|
879
|
-
const todayUTC = new Date().toISOString().slice(0, 10);
|
|
880
|
-
if (cachedDay && cachedDay !== todayUTC) return null;
|
|
881
|
-
return {
|
|
882
|
-
todayCost: data.todayCost || 0,
|
|
883
|
-
todayCalls: data.todayCalls || 0,
|
|
884
|
-
monthCost: data.monthCost || 0,
|
|
885
|
-
monthCalls: data.monthCalls || 0,
|
|
886
|
-
};
|
|
887
|
-
}
|
|
888
|
-
|
|
889
632
|
// Test stats (count files only โ NO reading file contents)
|
|
890
633
|
function getTestStats() {
|
|
891
634
|
let testFiles = 0;
|
|
@@ -1062,6 +805,143 @@ function getTriggerStats() {
|
|
|
1062
805
|
} catch { return { triggers: 0, agents: 0 }; }
|
|
1063
806
|
}
|
|
1064
807
|
|
|
808
|
+
// Hook latency โ surface slow per-prompt hooks in the statusline.
|
|
809
|
+
function getHookLatency() {
|
|
810
|
+
const p = path.join(CWD, '.monomind', 'metrics', 'hook-latency.json');
|
|
811
|
+
try {
|
|
812
|
+
if (!fs.existsSync(p)) return null;
|
|
813
|
+
const d = JSON.parse(fs.readFileSync(p, 'utf-8'));
|
|
814
|
+
const perPrompt = ['route'];
|
|
815
|
+
let totalMs = 0; let count = 0;
|
|
816
|
+
for (const h of perPrompt) {
|
|
817
|
+
if (d[h] && d[h].mean) { totalMs += d[h].mean; count++; }
|
|
818
|
+
}
|
|
819
|
+
if (count === 0) return null;
|
|
820
|
+
let slowest = null;
|
|
821
|
+
for (const k of Object.keys(d)) {
|
|
822
|
+
if (k === 'lastUpdated' || !d[k] || typeof d[k] !== 'object') continue;
|
|
823
|
+
if (!slowest || d[k].mean > slowest.mean) slowest = { name: k, mean: d[k].mean };
|
|
824
|
+
}
|
|
825
|
+
return { perPromptMs: totalMs, slowest: slowest };
|
|
826
|
+
} catch { return null; }
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
// Graph usage telemetry โ counts ALL graph wins (MCP calls + silent assists)
|
|
830
|
+
// vs greps that got no graph help.
|
|
831
|
+
function getGraphUsage() {
|
|
832
|
+
const usagePath = path.join(CWD, '.monomind', 'metrics', 'graph-usage.json');
|
|
833
|
+
try {
|
|
834
|
+
if (!fs.existsSync(usagePath)) return null;
|
|
835
|
+
const d = JSON.parse(fs.readFileSync(usagePath, 'utf-8'));
|
|
836
|
+
const graphWins = (d.monograph_call || 0) + (d.preresolve_hit || 0)
|
|
837
|
+
+ (d.graph_assist_search || 0) + (d.graph_assist_neighbors || 0);
|
|
838
|
+
const searches = (d.grep_call || 0) + (d.glob_call || 0)
|
|
839
|
+
+ (d.bash_grep_call || 0) + (d.bash_find_call || 0);
|
|
840
|
+
const total = graphWins + searches;
|
|
841
|
+
if (total === 0) return null;
|
|
842
|
+
return { graphWins: graphWins, searches: searches, pct: Math.round((graphWins / total) * 100), dollarsSaved: d.dollars_saved || 0 };
|
|
843
|
+
} catch { return null; }
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
// Graph freshness โ compare last build time vs commits since
|
|
847
|
+
function getGraphFreshness() {
|
|
848
|
+
const lockPath = path.join(CWD, '.monomind', 'graph', '.rebuild-lock');
|
|
849
|
+
const dbPath = path.join(CWD, '.monomind', 'monograph.db');
|
|
850
|
+
let buildMs = 0;
|
|
851
|
+
try {
|
|
852
|
+
const lockStat = safeStat(lockPath);
|
|
853
|
+
const dbStat = safeStat(dbPath);
|
|
854
|
+
buildMs = Math.max(lockStat?.mtimeMs || 0, dbStat?.mtimeMs || 0);
|
|
855
|
+
} catch { /* ignore */ }
|
|
856
|
+
if (!buildMs) return { commitsBehind: -1, stale: true, fresh: false };
|
|
857
|
+
const buildIso = new Date(buildMs).toISOString();
|
|
858
|
+
const out = safeExec(`git rev-list --count --since='${buildIso}' HEAD 2>/dev/null`, 1500);
|
|
859
|
+
const commitsBehind = parseInt(out, 10) || 0;
|
|
860
|
+
return { commitsBehind, stale: commitsBehind > 5, fresh: commitsBehind === 0 };
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
// Active loops โ scan .monomind/loops/*.json, skip stale (>6h)
|
|
864
|
+
function getLoopStatus() {
|
|
865
|
+
const loopsDir = path.join(CWD, '.monomind', 'loops');
|
|
866
|
+
if (!fs.existsSync(loopsDir)) return { count: 0, loops: [] };
|
|
867
|
+
const STALE_MS = 6 * 60 * 60 * 1000;
|
|
868
|
+
const now = Date.now();
|
|
869
|
+
const loops = [];
|
|
870
|
+
try {
|
|
871
|
+
const files = fs.readdirSync(loopsDir).filter(f =>
|
|
872
|
+
f.endsWith('.json') && !f.includes('-hil') && !f.endsWith('.stop'));
|
|
873
|
+
for (const f of files) {
|
|
874
|
+
const d = readJSON(path.join(loopsDir, f));
|
|
875
|
+
if (!d || !d.command) continue;
|
|
876
|
+
const last = d.lastRunAt || d.nextRunAt || d.startedAt || 0;
|
|
877
|
+
if (last && (now - last) > STALE_MS) continue;
|
|
878
|
+
loops.push({
|
|
879
|
+
cmd: String(d.command).replace(/^\//,''),
|
|
880
|
+
type: d.type || 'repeat',
|
|
881
|
+
rep: d.currentRep || 0,
|
|
882
|
+
max: d.maxReps || 0,
|
|
883
|
+
status: d.status || 'running',
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
} catch { /* ignore */ }
|
|
887
|
+
return { count: loops.length, loops };
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// HIL pending โ count <id>-hil.md files with no human response yet
|
|
891
|
+
function getHILPending() {
|
|
892
|
+
const loopsDir = path.join(CWD, '.monomind', 'loops');
|
|
893
|
+
if (!fs.existsSync(loopsDir)) return { pending: 0 };
|
|
894
|
+
let pending = 0;
|
|
895
|
+
try {
|
|
896
|
+
const files = fs.readdirSync(loopsDir).filter(f => f.endsWith('-hil.md'));
|
|
897
|
+
for (const f of files) {
|
|
898
|
+
try {
|
|
899
|
+
const txt = fs.readFileSync(path.join(loopsDir, f), 'utf-8');
|
|
900
|
+
const answered = /^[ \t]*>[ \t]+\S/m.test(txt);
|
|
901
|
+
if (!answered) pending++;
|
|
902
|
+
} catch { /* ignore */ }
|
|
903
|
+
}
|
|
904
|
+
} catch { /* ignore */ }
|
|
905
|
+
return { pending };
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
// Monograph knowledge graph stats
|
|
909
|
+
// Sources, in priority order:
|
|
910
|
+
// 1. .monomind/graph/stats.json โ explicit cached stats
|
|
911
|
+
// 2. .monomind/monograph.db โ live SQLite (read counts via sqlite3)
|
|
912
|
+
// 3. .monomind/graph/graph.json โ legacy JSON dump
|
|
913
|
+
function getGraphifyStats() {
|
|
914
|
+
const statsPath = path.join(CWD, '.monomind', 'graph', 'stats.json');
|
|
915
|
+
const dbPath = path.join(CWD, '.monomind', 'monograph.db');
|
|
916
|
+
const graphPath = path.join(CWD, '.monomind', 'graph', 'graph.json');
|
|
917
|
+
|
|
918
|
+
try {
|
|
919
|
+
const s = readJSON(statsPath);
|
|
920
|
+
if (s && s.nodes !== undefined) return { nodes: s.nodes, edges: s.edges || 0, exists: true };
|
|
921
|
+
} catch { /* ignore */ }
|
|
922
|
+
|
|
923
|
+
try {
|
|
924
|
+
if (fs.existsSync(dbPath)) {
|
|
925
|
+
const out = safeExec(`sqlite3 "${dbPath}" "SELECT (SELECT COUNT(*) FROM nodes), (SELECT COUNT(*) FROM edges);"`, 1000);
|
|
926
|
+
if (out) {
|
|
927
|
+
const [n, e] = out.split('|').map(v => parseInt(v, 10) || 0);
|
|
928
|
+
if (n > 0) return { nodes: n, edges: e, exists: true };
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
} catch { /* ignore */ }
|
|
932
|
+
|
|
933
|
+
try {
|
|
934
|
+
const stat = safeStat(graphPath);
|
|
935
|
+
if (stat && stat.size < 10 * 1024 * 1024) {
|
|
936
|
+
const g = JSON.parse(fs.readFileSync(graphPath, 'utf-8'));
|
|
937
|
+
const nodes = Array.isArray(g.nodes) ? g.nodes.length : 0;
|
|
938
|
+
const edges = (Array.isArray(g.edges) ? g.edges : (Array.isArray(g.links) ? g.links : [])).length;
|
|
939
|
+
return { nodes, edges, exists: true };
|
|
940
|
+
}
|
|
941
|
+
} catch { /* ignore */ }
|
|
942
|
+
return { nodes: 0, edges: 0, exists: false };
|
|
943
|
+
}
|
|
944
|
+
|
|
1065
945
|
function getSIBudget() {
|
|
1066
946
|
const SI_LIMIT = 1500;
|
|
1067
947
|
const siPath = path.join(CWD, '.agents', 'shared_instructions.md');
|
|
@@ -1072,22 +952,6 @@ function getSIBudget() {
|
|
|
1072
952
|
} catch { return null; }
|
|
1073
953
|
}
|
|
1074
954
|
|
|
1075
|
-
// Control server status (Neural Control Room web UI)
|
|
1076
|
-
function getControlStatus() {
|
|
1077
|
-
const statusPath = path.join(CWD, '.monomind', 'control.json');
|
|
1078
|
-
try {
|
|
1079
|
-
if (!fs.existsSync(statusPath)) return { running: false, port: null };
|
|
1080
|
-
const data = JSON.parse(fs.readFileSync(statusPath, 'utf-8'));
|
|
1081
|
-
if (!data || !data.pid) return { running: false, port: null };
|
|
1082
|
-
try {
|
|
1083
|
-
process.kill(data.pid, 0);
|
|
1084
|
-
return { running: true, port: data.port || 4242, url: data.url };
|
|
1085
|
-
} catch {
|
|
1086
|
-
return { running: false, port: null };
|
|
1087
|
-
}
|
|
1088
|
-
} catch { return { running: false, port: null }; }
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
955
|
// โโ Single-line statusline (compact) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
1092
956
|
function generateStatusline() {
|
|
1093
957
|
const git = getGitInfo();
|
|
@@ -1096,15 +960,11 @@ function generateStatusline() {
|
|
|
1096
960
|
const hooks = getHooksStatus();
|
|
1097
961
|
const knowledge = getKnowledgeStats();
|
|
1098
962
|
const triggers = getTriggerStats();
|
|
1099
|
-
const palace = getMemoryPalaceStats();
|
|
1100
|
-
const tokens = getTokenStats();
|
|
1101
963
|
const parts = [];
|
|
1102
964
|
|
|
1103
|
-
// Brand +
|
|
965
|
+
// Brand + swarm dot
|
|
1104
966
|
const swarmDot = swarm.coordinationActive ? `${x.green}โ${x.reset}` : `${x.slate}โ${x.reset}`;
|
|
1105
|
-
|
|
1106
|
-
const cwdBase = path.basename(CWD);
|
|
1107
|
-
parts.push(`${x.bold}${x.purple}โ MonoMind${x.reset} ${x.teal}${projName}${x.reset} ${swarmDot} ${x.dim}โ ${cwdBase}${x.reset}`);
|
|
967
|
+
parts.push(`${x.bold}${x.purple}โ Monomind${x.reset} ${swarmDot}`);
|
|
1108
968
|
|
|
1109
969
|
// Git branch + changes (compact)
|
|
1110
970
|
if (git.gitBranch) {
|
|
@@ -1122,58 +982,28 @@ function generateStatusline() {
|
|
|
1122
982
|
// Active agent
|
|
1123
983
|
const activeAgent = getActiveAgent();
|
|
1124
984
|
if (activeAgent) {
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
const first = activeAgent.extrasMatches[0];
|
|
1129
|
-
parts.push(`${x.sky}๐ค ${x.bold}${first.name}${x.reset}`);
|
|
1130
|
-
} else if (!isExtras) {
|
|
1131
|
-
const col = activeAgent.activated ? x.green : x.sky;
|
|
1132
|
-
const icon = activeAgent.activated ? 'โ' : '';
|
|
1133
|
-
parts.push(icon
|
|
1134
|
-
? `${col}${icon} ${x.bold}${activeAgent.name}${x.reset}`
|
|
1135
|
-
: `${col}๐ค ${x.bold}${activeAgent.name}${x.reset}`);
|
|
1136
|
-
}
|
|
1137
|
-
// else: suppress extras with no matches
|
|
985
|
+
const col = activeAgent.activated ? x.green : x.sky;
|
|
986
|
+
const icon = activeAgent.activated ? 'โ' : 'โ';
|
|
987
|
+
parts.push(`${col}${icon} ${x.bold}${activeAgent.name}${x.reset}`);
|
|
1138
988
|
}
|
|
1139
989
|
|
|
1140
990
|
// Intelligence
|
|
1141
991
|
const ic = pctColor(system.intelligencePct);
|
|
1142
992
|
parts.push(`${ic}๐ก ${system.intelligencePct}%${x.reset}`);
|
|
1143
993
|
|
|
1144
|
-
//
|
|
1145
|
-
const autoMemCompact = getAutoMemoryStats();
|
|
1146
|
-
if (autoMemCompact.count > 0) {
|
|
1147
|
-
const typeOrder = ['handoff', 'user', 'feedback', 'project', 'reference'];
|
|
1148
|
-
const typeColors = { user: x.sky, feedback: x.gold, project: x.teal, reference: x.violet, handoff: x.coral };
|
|
1149
|
-
const typeParts = typeOrder
|
|
1150
|
-
.filter(t => autoMemCompact.byType[t] > 0)
|
|
1151
|
-
.map(t => `${typeColors[t] || x.slate}${autoMemCompact.byType[t]}${t.slice(0,1)}${x.reset}`);
|
|
1152
|
-
const typeSuffix = typeParts.length > 0 ? ` ${typeParts.join(' ')}` : '';
|
|
1153
|
-
parts.push(`${x.purple}๐ง ${autoMemCompact.count}m${x.reset}${typeSuffix}`);
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
// Knowledge chunks โ show when populated
|
|
994
|
+
// Knowledge chunks (Task 28) โ show when populated
|
|
1157
995
|
if (knowledge.chunks > 0) {
|
|
1158
996
|
parts.push(`${x.teal}๐ ${knowledge.chunks}k${x.reset}`);
|
|
1159
997
|
}
|
|
1160
998
|
|
|
1161
|
-
//
|
|
1162
|
-
const gfCompact = getGraphifyStats();
|
|
1163
|
-
if (gfCompact.exists) {
|
|
1164
|
-
parts.push(`${x.sky}๐ ${gfCompact.nodes}n ${gfCompact.edges}e${x.reset}`);
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
// Triggers โ show when populated
|
|
999
|
+
// Triggers (Task 32) โ show when populated
|
|
1168
1000
|
if (triggers.triggers > 0) {
|
|
1169
1001
|
parts.push(`${x.mint}๐ฏ ${triggers.triggers}t${x.reset}`);
|
|
1170
1002
|
}
|
|
1171
1003
|
|
|
1172
|
-
// Swarm agents
|
|
1004
|
+
// Swarm agents (only when active)
|
|
1173
1005
|
if (swarm.activeAgents > 0) {
|
|
1174
1006
|
parts.push(`${x.gold}๐ ${swarm.activeAgents}/${swarm.maxAgents}${x.reset}`);
|
|
1175
|
-
} else if ((swarm.lastActive || 0) > 0) {
|
|
1176
|
-
parts.push(`${x.slate}๐ ${swarm.lastActive}โ${x.reset}`);
|
|
1177
1007
|
}
|
|
1178
1008
|
|
|
1179
1009
|
// Hooks
|
|
@@ -1181,18 +1011,6 @@ function generateStatusline() {
|
|
|
1181
1011
|
parts.push(`${x.mint}โก ${hooks.enabled}h${x.reset}`);
|
|
1182
1012
|
}
|
|
1183
1013
|
|
|
1184
|
-
// Token cost today (from cache)
|
|
1185
|
-
if (tokens && tokens.todayCost > 0) {
|
|
1186
|
-
const todayFmt = tokens.todayCost >= 100 ? `$${tokens.todayCost.toFixed(2)}` : tokens.todayCost >= 1 ? `$${tokens.todayCost.toFixed(3)}` : `$${tokens.todayCost.toFixed(4)}`;
|
|
1187
|
-
parts.push(`${x.gold}๐ฐ ${todayFmt}${x.reset}`);
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
// Control server (Neural Control Room)
|
|
1191
|
-
const ctrl = getControlStatus();
|
|
1192
|
-
if (ctrl.running) {
|
|
1193
|
-
parts.push(`${x.teal}๐๏ธ :${ctrl.port}${x.reset}`);
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
1014
|
return parts.join(` ${DIV} `);
|
|
1197
1015
|
}
|
|
1198
1016
|
|
|
@@ -1204,7 +1022,7 @@ function generateDashboard() {
|
|
|
1204
1022
|
const security = getSecurityStatus();
|
|
1205
1023
|
const swarm = getSwarmStatus();
|
|
1206
1024
|
const system = getSystemMetrics();
|
|
1207
|
-
|
|
1025
|
+
const adrs = getADRStatus();
|
|
1208
1026
|
const hooks = getHooksStatus();
|
|
1209
1027
|
const agentdb = getAgentDBStats();
|
|
1210
1028
|
const tests = getTestStats();
|
|
@@ -1213,9 +1031,6 @@ function generateDashboard() {
|
|
|
1213
1031
|
const knowledge = getKnowledgeStats();
|
|
1214
1032
|
const triggers = getTriggerStats();
|
|
1215
1033
|
const si = getSIBudget();
|
|
1216
|
-
const palace = getMemoryPalaceStats();
|
|
1217
|
-
const autoMem = getAutoMemoryStats();
|
|
1218
|
-
const tokens = getTokenStats();
|
|
1219
1034
|
const sec = secBadge(security.status);
|
|
1220
1035
|
const activeAgent = getActiveAgent();
|
|
1221
1036
|
const lines = [];
|
|
@@ -1224,7 +1039,7 @@ function generateDashboard() {
|
|
|
1224
1039
|
const swarmDot = swarm.coordinationActive ? `${x.green}โ LIVE${x.reset}` : `${x.slate}โ IDLE${x.reset}`;
|
|
1225
1040
|
const projName = getProjectName();
|
|
1226
1041
|
const cwdName = path.basename(CWD);
|
|
1227
|
-
let hdr = `${x.bold}${x.purple}โ
|
|
1042
|
+
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}`;
|
|
1228
1043
|
|
|
1229
1044
|
if (git.gitBranch) {
|
|
1230
1045
|
hdr += ` ${DIV} ${x.sky}โ ${x.bold}${git.gitBranch}${x.reset}`;
|
|
@@ -1238,35 +1053,16 @@ function generateDashboard() {
|
|
|
1238
1053
|
hdr += ` ${DIV} ๐ค ${x.violet}${x.bold}${modelName}${x.reset}`;
|
|
1239
1054
|
if (session.duration) hdr += ` ${x.dim}โฑ ${session.duration}${x.reset}`;
|
|
1240
1055
|
|
|
1241
|
-
// Control server (Neural Control Room)
|
|
1242
|
-
const ctrl = getControlStatus();
|
|
1243
|
-
if (ctrl.running) {
|
|
1244
|
-
hdr += ` ${DIV} ${x.teal}${x.bold}๐๏ธ CTRL${x.reset}${x.teal} :${ctrl.port}${x.reset}`;
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
if (tokens) {
|
|
1248
|
-
const todayFmt = tokens.todayCost >= 100 ? `$${tokens.todayCost.toFixed(2)}` : tokens.todayCost >= 1 ? `$${tokens.todayCost.toFixed(3)}` : `$${tokens.todayCost.toFixed(4)}`;
|
|
1249
|
-
hdr += ` ${DIV} ${x.gold}๐ฐ ${x.bold}${todayFmt}${x.reset}${x.slate} today ยท ${tokens.todayCalls} calls${x.reset}`;
|
|
1250
|
-
}
|
|
1251
|
-
|
|
1252
1056
|
lines.push(hdr);
|
|
1253
1057
|
lines.push(SEP);
|
|
1254
1058
|
|
|
1255
1059
|
// โโ Row 1: Active agent + Loop status โโโโโโโโโโโโโโโโโโโโโโโโ
|
|
1256
1060
|
let agentStr;
|
|
1257
1061
|
if (activeAgent) {
|
|
1258
|
-
const
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
} else if (isExtras) {
|
|
1263
|
-
agentStr = `${x.slate}๐ค no agent routed${x.reset}`;
|
|
1264
|
-
} else {
|
|
1265
|
-
const col = activeAgent.activated ? x.green : x.sky;
|
|
1266
|
-
const mark = activeAgent.activated ? `${col}${x.bold}โ ACTIVE${x.reset} ` : '';
|
|
1267
|
-
const conf = activeAgent.activated ? '' : ` ${x.slate}${(activeAgent.confidence * 100).toFixed(0)}%${x.reset}`;
|
|
1268
|
-
agentStr = `${mark}${col}๐ค ${x.bold}${activeAgent.name}${x.reset}${conf}`;
|
|
1269
|
-
}
|
|
1062
|
+
const col = activeAgent.activated ? x.green : x.sky;
|
|
1063
|
+
const mark = activeAgent.activated ? `${col}${x.bold}โ ACTIVE${x.reset} ` : '';
|
|
1064
|
+
const conf = activeAgent.activated ? '' : ` ${x.slate}${(activeAgent.confidence * 100).toFixed(0)}%${x.reset}`;
|
|
1065
|
+
agentStr = `${mark}${col}๐ค ${x.bold}${activeAgent.name}${x.reset}${conf}`;
|
|
1270
1066
|
} else {
|
|
1271
1067
|
agentStr = `${x.slate}๐ค no agent routed${x.reset}`;
|
|
1272
1068
|
}
|
|
@@ -1350,8 +1146,6 @@ function generateJSON() {
|
|
|
1350
1146
|
adrs: getADRStatus(),
|
|
1351
1147
|
hooks: getHooksStatus(),
|
|
1352
1148
|
agentdb: getAgentDBStats(),
|
|
1353
|
-
palace: getMemoryPalaceStats(),
|
|
1354
|
-
tokens: getTokenStats(),
|
|
1355
1149
|
tests: getTestStats(),
|
|
1356
1150
|
git: { modified: git.modified, untracked: git.untracked, staged: git.staged, ahead: git.ahead, behind: git.behind },
|
|
1357
1151
|
lastUpdated: new Date().toISOString(),
|