@monoes/monomindcli 1.10.6 → 1.10.7
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.
|
@@ -696,6 +696,78 @@ function getGraphifyStats() {
|
|
|
696
696
|
return { nodes: 0, edges: 0, exists: false };
|
|
697
697
|
}
|
|
698
698
|
|
|
699
|
+
// Graph freshness — compare graph build time against most recent commit
|
|
700
|
+
// Returns: { commitsBehind, stale } where stale = >5 commits or never built
|
|
701
|
+
function getGraphFreshness() {
|
|
702
|
+
const lockPath = path.join(CWD, '.monomind', 'graph', '.rebuild-lock');
|
|
703
|
+
const dbPath = path.join(CWD, '.monomind', 'monograph.db');
|
|
704
|
+
|
|
705
|
+
let buildMs = 0;
|
|
706
|
+
try {
|
|
707
|
+
const lockStat = safeStat(lockPath);
|
|
708
|
+
const dbStat = safeStat(dbPath);
|
|
709
|
+
buildMs = Math.max(lockStat?.mtimeMs || 0, dbStat?.mtimeMs || 0);
|
|
710
|
+
} catch { /* ignore */ }
|
|
711
|
+
if (!buildMs) return { commitsBehind: -1, stale: true, fresh: false };
|
|
712
|
+
|
|
713
|
+
// Count commits since the graph was last built
|
|
714
|
+
const buildIso = new Date(buildMs).toISOString();
|
|
715
|
+
const out = safeExec(`git rev-list --count --since='${buildIso}' HEAD 2>/dev/null`, 1500);
|
|
716
|
+
const commitsBehind = parseInt(out, 10) || 0;
|
|
717
|
+
return {
|
|
718
|
+
commitsBehind,
|
|
719
|
+
stale: commitsBehind > 5,
|
|
720
|
+
fresh: commitsBehind === 0,
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// Active loops — scan .monomind/loops/*.json
|
|
725
|
+
// Filters: skip *-hil*.json, skip stale (>6h since lastRunAt)
|
|
726
|
+
function getLoopStatus() {
|
|
727
|
+
const loopsDir = path.join(CWD, '.monomind', 'loops');
|
|
728
|
+
if (!fs.existsSync(loopsDir)) return { count: 0, loops: [] };
|
|
729
|
+
const STALE_MS = 6 * 60 * 60 * 1000;
|
|
730
|
+
const now = Date.now();
|
|
731
|
+
let loops = [];
|
|
732
|
+
try {
|
|
733
|
+
const files = fs.readdirSync(loopsDir).filter(f =>
|
|
734
|
+
f.endsWith('.json') && !f.includes('-hil') && !f.endsWith('.stop'));
|
|
735
|
+
for (const f of files) {
|
|
736
|
+
const d = readJSON(path.join(loopsDir, f));
|
|
737
|
+
if (!d || !d.command) continue;
|
|
738
|
+
const last = d.lastRunAt || d.nextRunAt || d.startedAt || 0;
|
|
739
|
+
if (last && (now - last) > STALE_MS) continue;
|
|
740
|
+
loops.push({
|
|
741
|
+
cmd: d.command.replace(/^\//,''),
|
|
742
|
+
type: d.type || 'repeat',
|
|
743
|
+
rep: d.currentRep || 0,
|
|
744
|
+
max: d.maxReps || 0,
|
|
745
|
+
status: d.status || 'running',
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
} catch { /* ignore */ }
|
|
749
|
+
return { count: loops.length, loops };
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
// HIL pending — count <id>-hil.md files with no human response yet
|
|
753
|
+
function getHILPending() {
|
|
754
|
+
const loopsDir = path.join(CWD, '.monomind', 'loops');
|
|
755
|
+
if (!fs.existsSync(loopsDir)) return { pending: 0 };
|
|
756
|
+
let pending = 0;
|
|
757
|
+
try {
|
|
758
|
+
const files = fs.readdirSync(loopsDir).filter(f => f.endsWith('-hil.md'));
|
|
759
|
+
for (const f of files) {
|
|
760
|
+
try {
|
|
761
|
+
const txt = fs.readFileSync(path.join(loopsDir, f), 'utf-8');
|
|
762
|
+
// A response is a line starting with "> " followed by non-whitespace
|
|
763
|
+
const answered = /^[ \t]*>[ \t]+\S/m.test(txt);
|
|
764
|
+
if (!answered) pending++;
|
|
765
|
+
} catch { /* ignore */ }
|
|
766
|
+
}
|
|
767
|
+
} catch { /* ignore */ }
|
|
768
|
+
return { pending };
|
|
769
|
+
}
|
|
770
|
+
|
|
699
771
|
// Memory Palace stats — drawers.jsonl + kg.json (the real persistent memory)
|
|
700
772
|
function getMemoryPalaceStats() {
|
|
701
773
|
const palaceDir = path.join(CWD, '.monomind', 'palace');
|
|
@@ -1130,158 +1202,68 @@ function generateDashboard() {
|
|
|
1130
1202
|
lines.push(hdr);
|
|
1131
1203
|
lines.push(SEP);
|
|
1132
1204
|
|
|
1133
|
-
// ── Row 1:
|
|
1134
|
-
|
|
1135
|
-
? `${x.teal}📚 ${x.bold}${knowledge.chunks}${x.reset}${x.slate} chunks${x.reset}`
|
|
1136
|
-
: `${x.slate}📚 no chunks${x.reset}`;
|
|
1137
|
-
|
|
1138
|
-
const skillStr = knowledge.skills > 0
|
|
1139
|
-
? ` ${x.mint}✦ ${knowledge.skills} skills${x.reset}`
|
|
1140
|
-
: '';
|
|
1141
|
-
|
|
1142
|
-
const patStr = progress.patternsLearned > 0
|
|
1143
|
-
? `${x.gold}${progress.patternsLearned >= 1000 ? (progress.patternsLearned / 1000).toFixed(1) + 'k' : progress.patternsLearned} patterns${x.reset}`
|
|
1144
|
-
: `${x.slate}0 patterns${x.reset}`;
|
|
1145
|
-
|
|
1146
|
-
const gf = getGraphifyStats();
|
|
1147
|
-
const gfStr = gf.exists
|
|
1148
|
-
? `${x.sky}🔗 ${x.bold}${gf.nodes}${x.reset}${x.slate} nodes · ${x.reset}${x.sky}${x.bold}${gf.edges}${x.reset}${x.slate} edges${x.reset}`
|
|
1149
|
-
: `${x.slate}🔗 no graph${x.reset}`;
|
|
1150
|
-
|
|
1151
|
-
lines.push(
|
|
1152
|
-
`${x.purple}💡 INTEL${x.reset} ` +
|
|
1153
|
-
`${knowStr}${skillStr} ${DIV} ` +
|
|
1154
|
-
`${patStr} ${DIV} ` +
|
|
1155
|
-
gfStr
|
|
1156
|
-
);
|
|
1157
|
-
lines.push(SEP);
|
|
1158
|
-
|
|
1159
|
-
// ── Row 2: Agents & Triggers ──────────────────────────────────
|
|
1160
|
-
const agentCol = swarm.activeAgents > 0 ? x.green : x.slate;
|
|
1161
|
-
const hookCol = hooks.enabled > 0 ? x.mint : x.slate;
|
|
1162
|
-
|
|
1163
|
-
// Triggers (Task 32)
|
|
1164
|
-
const trigStr = triggers.triggers > 0
|
|
1165
|
-
? `${x.mint}🎯 ${x.bold}${triggers.triggers}${x.reset}${x.slate} triggers · ${triggers.agents} agents${x.reset}`
|
|
1166
|
-
: `${x.slate}🎯 no triggers${x.reset}`;
|
|
1167
|
-
|
|
1168
|
-
// Active agent badge
|
|
1169
|
-
let agentBadge;
|
|
1205
|
+
// ── Row 1: Active agent + Loop status ────────────────────────
|
|
1206
|
+
let agentStr;
|
|
1170
1207
|
if (activeAgent) {
|
|
1171
1208
|
const isExtras = activeAgent.slug === 'extras' || activeAgent.name === 'Extras';
|
|
1172
1209
|
if (isExtras && activeAgent.extrasMatches && activeAgent.extrasMatches.length > 0) {
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
const badgeParts = specialists.map(s => `${x.sky}👤 ${x.bold}${s.name}${x.reset}`);
|
|
1176
|
-
agentBadge = badgeParts.join(`${x.slate} ${x.reset}`);
|
|
1210
|
+
const specialists = activeAgent.extrasMatches.slice(0, 3).map(s => s.name).join(', ');
|
|
1211
|
+
agentStr = `${x.sky}👤 ${x.bold}${specialists}${x.reset}`;
|
|
1177
1212
|
} else if (isExtras) {
|
|
1178
|
-
|
|
1179
|
-
agentBadge = `${x.slate}👤 no agent routed${x.reset}`;
|
|
1213
|
+
agentStr = `${x.slate}👤 no agent routed${x.reset}`;
|
|
1180
1214
|
} else {
|
|
1181
1215
|
const col = activeAgent.activated ? x.green : x.sky;
|
|
1182
|
-
const mark = activeAgent.activated ?
|
|
1216
|
+
const mark = activeAgent.activated ? `${col}${x.bold}● ACTIVE${x.reset} ` : '';
|
|
1183
1217
|
const conf = activeAgent.activated ? '' : ` ${x.slate}${(activeAgent.confidence * 100).toFixed(0)}%${x.reset}`;
|
|
1184
|
-
|
|
1185
|
-
agentBadge = mark
|
|
1186
|
-
? `${col}${x.bold}${mark}${x.reset} ${col}👤 ${x.bold}${activeAgent.name}${x.reset}${cat}${conf}`
|
|
1187
|
-
: `${col}👤 ${x.bold}${activeAgent.name}${x.reset}${cat}${conf}`;
|
|
1218
|
+
agentStr = `${mark}${col}👤 ${x.bold}${activeAgent.name}${x.reset}${conf}`;
|
|
1188
1219
|
}
|
|
1189
1220
|
} else {
|
|
1190
|
-
|
|
1221
|
+
agentStr = `${x.slate}👤 no agent routed${x.reset}`;
|
|
1191
1222
|
}
|
|
1192
1223
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
)
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
const cveStatus = security.totalCves === 0
|
|
1210
|
-
? (security.status === 'NONE' ? `${x.slate}not scanned${x.reset}` : `${x.green}✔ clean${x.reset}`)
|
|
1211
|
-
: `${x.coral}${security.cvesFixed}/${security.totalCves} fixed${x.reset}`;
|
|
1212
|
-
|
|
1213
|
-
lines.push(
|
|
1214
|
-
`${x.purple}🛡️ SECURITY${x.reset} ` +
|
|
1215
|
-
`${sec.col}${sec.label}${x.reset} ${DIV} ` +
|
|
1216
|
-
`CVE ${cveStatus}`
|
|
1217
|
-
);
|
|
1218
|
-
lines.push(SEP);
|
|
1219
|
-
|
|
1220
|
-
// ── Row 4: Memory & Tests ─────────────────────────────────────
|
|
1221
|
-
const testCol = tests.testFiles > 0 ? x.green : x.slate;
|
|
1222
|
-
const memCol = system.memoryMB > 200 ? x.orange : x.sky;
|
|
1223
|
-
|
|
1224
|
-
// Auto-memory files display
|
|
1225
|
-
const memFileCol = autoMem.count > 0 ? x.purple : x.slate;
|
|
1226
|
-
const memFileStr = autoMem.count > 0
|
|
1227
|
-
? `${memFileCol}${x.bold}${autoMem.count}${x.reset}${x.slate} memories${x.reset}`
|
|
1228
|
-
: `${x.slate}no memories${x.reset}`;
|
|
1229
|
-
const memTypeOrder = ['handoff', 'user', 'feedback', 'project', 'reference'];
|
|
1230
|
-
const typeColors = { user: x.sky, feedback: x.gold, project: x.teal, reference: x.violet, handoff: x.coral };
|
|
1231
|
-
const typeParts = memTypeOrder
|
|
1232
|
-
.filter(t => autoMem.byType[t] > 0)
|
|
1233
|
-
.map(t => `${typeColors[t] || x.slate}${autoMem.byType[t]}${t.slice(0,1)}${x.reset}`);
|
|
1234
|
-
const kgStr = typeParts.length > 0 ? ` ${typeParts.join(' ')}` : '';
|
|
1235
|
-
|
|
1236
|
-
// Total memory size (palace + agentdb)
|
|
1237
|
-
const totalSizeKB = agentdb.dbSizeKB + palace.palaceSizeKB;
|
|
1238
|
-
const sizeDisp = totalSizeKB >= 1024
|
|
1239
|
-
? `${(totalSizeKB / 1024).toFixed(1)} MB` : `${totalSizeKB} KB`;
|
|
1240
|
-
|
|
1241
|
-
// HNSW tag only meaningful if vectors exist
|
|
1242
|
-
const vecTotal = agentdb.vectorCount;
|
|
1243
|
-
const hnswTag = agentdb.hasHnsw ? ` ${x.green}⚡ HNSW${x.reset}` : '';
|
|
1244
|
-
|
|
1245
|
-
const chips = [];
|
|
1246
|
-
if (integration.mcpServers.total > 0) {
|
|
1247
|
-
const mc = integration.mcpServers.enabled === integration.mcpServers.total ? x.green
|
|
1248
|
-
: integration.mcpServers.enabled > 0 ? x.gold : x.coral;
|
|
1249
|
-
chips.push(`${mc}MCP ${integration.mcpServers.enabled}/${integration.mcpServers.total}${x.reset}`);
|
|
1224
|
+
const loopState = getLoopStatus();
|
|
1225
|
+
let loopStr;
|
|
1226
|
+
if (loopState.count > 0) {
|
|
1227
|
+
const parts = loopState.loops.slice(0, 2).map(l => {
|
|
1228
|
+
const status = l.status === 'hil:pending'
|
|
1229
|
+
? `${x.coral}⏳ HIL${x.reset}`
|
|
1230
|
+
: `${x.green}⟳${x.reset}`;
|
|
1231
|
+
const tag = l.type === 'tillend'
|
|
1232
|
+
? `${x.bold}${l.cmd}${x.reset}${x.slate} run ${l.rep}${x.reset}`
|
|
1233
|
+
: `${x.bold}${l.cmd}${x.reset}${x.slate} ${l.rep}/${l.max}${x.reset}`;
|
|
1234
|
+
return `${status} ${tag}`;
|
|
1235
|
+
});
|
|
1236
|
+
loopStr = `${x.gold}🔄${x.reset} ${parts.join(`${x.slate} · ${x.reset}`)}`;
|
|
1237
|
+
if (loopState.count > 2) loopStr += `${x.slate} +${loopState.count - 2} more${x.reset}`;
|
|
1238
|
+
} else {
|
|
1239
|
+
loopStr = `${x.slate}🔄 no active loops${x.reset}`;
|
|
1250
1240
|
}
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
const integStr = chips.length ? chips.join(' ') : `${x.slate}none${x.reset}`;
|
|
1254
|
-
|
|
1255
|
-
lines.push(
|
|
1256
|
-
`${x.teal}🗄️ MEMORY${x.reset} ` +
|
|
1257
|
-
`${memFileStr}${kgStr}${hnswTag} ${DIV} ` +
|
|
1258
|
-
`${x.white}${sizeDisp}${x.reset} ${DIV} ` +
|
|
1259
|
-
`${testCol}🧪 ${tests.testFiles} test files${x.reset} ${DIV} ` +
|
|
1260
|
-
integStr
|
|
1261
|
-
);
|
|
1241
|
+
|
|
1242
|
+
lines.push(`${x.purple}🤖 AGENT${x.reset} ${agentStr} ${DIV} ${loopStr}`);
|
|
1262
1243
|
lines.push(SEP);
|
|
1263
1244
|
|
|
1264
|
-
// ── Row
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1245
|
+
// ── Row 2: Graph freshness + Pending HIL ─────────────────────
|
|
1246
|
+
const gf = getGraphifyStats();
|
|
1247
|
+
const freshness = getGraphFreshness();
|
|
1248
|
+
let graphStr;
|
|
1249
|
+
if (gf.exists) {
|
|
1250
|
+
const nodesFmt = gf.nodes >= 1000 ? `${(gf.nodes / 1000).toFixed(0)}k` : `${gf.nodes}`;
|
|
1251
|
+
const freshTag = freshness.fresh
|
|
1252
|
+
? `${x.green}● fresh${x.reset}`
|
|
1253
|
+
: freshness.stale
|
|
1254
|
+
? `${x.coral}● ${freshness.commitsBehind} commits stale${x.reset}`
|
|
1255
|
+
: `${x.gold}● ${freshness.commitsBehind} behind${x.reset}`;
|
|
1256
|
+
graphStr = `${x.sky}🔗 ${x.bold}${nodesFmt}${x.reset}${x.slate} nodes${x.reset} ${freshTag}`;
|
|
1270
1257
|
} else {
|
|
1271
|
-
|
|
1258
|
+
graphStr = `${x.slate}🔗 no graph${x.reset}`;
|
|
1272
1259
|
}
|
|
1273
1260
|
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
lines.push(
|
|
1280
|
-
`${x.slate}📋 CONTEXT${x.reset} ` +
|
|
1281
|
-
`${siStr} ${DIV} ` +
|
|
1282
|
-
`${x.dim}💾 ${system.memoryMB} MB RAM${x.reset}` +
|
|
1283
|
-
monthStr
|
|
1284
|
-
);
|
|
1261
|
+
const hil = getHILPending();
|
|
1262
|
+
const hilStr = hil.pending > 0
|
|
1263
|
+
? `${x.coral}✨ ${x.bold}${hil.pending}${x.reset}${x.coral} HIL pending${x.reset}`
|
|
1264
|
+
: `${x.slate}✨ no pending HIL${x.reset}`;
|
|
1265
|
+
|
|
1266
|
+
lines.push(`${x.teal}🧠 CONTEXT${x.reset} ${graphStr} ${DIV} ${hilStr}`);
|
|
1285
1267
|
|
|
1286
1268
|
return lines.join('\n');
|
|
1287
1269
|
}
|
|
@@ -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,
|
|
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"}
|
|
@@ -828,6 +828,68 @@ function getTriggerStats() {
|
|
|
828
828
|
} catch { return { triggers: 0, agents: 0 }; }
|
|
829
829
|
}
|
|
830
830
|
|
|
831
|
+
// Graph freshness — compare last build time vs commits since
|
|
832
|
+
function getGraphFreshness() {
|
|
833
|
+
const lockPath = path.join(CWD, '.monomind', 'graph', '.rebuild-lock');
|
|
834
|
+
const dbPath = path.join(CWD, '.monomind', 'monograph.db');
|
|
835
|
+
let buildMs = 0;
|
|
836
|
+
try {
|
|
837
|
+
const lockStat = safeStat(lockPath);
|
|
838
|
+
const dbStat = safeStat(dbPath);
|
|
839
|
+
buildMs = Math.max(lockStat?.mtimeMs || 0, dbStat?.mtimeMs || 0);
|
|
840
|
+
} catch { /* ignore */ }
|
|
841
|
+
if (!buildMs) return { commitsBehind: -1, stale: true, fresh: false };
|
|
842
|
+
const buildIso = new Date(buildMs).toISOString();
|
|
843
|
+
const out = safeExec(\`git rev-list --count --since='\${buildIso}' HEAD 2>/dev/null\`, 1500);
|
|
844
|
+
const commitsBehind = parseInt(out, 10) || 0;
|
|
845
|
+
return { commitsBehind, stale: commitsBehind > 5, fresh: commitsBehind === 0 };
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// Active loops — scan .monomind/loops/*.json, skip stale (>6h)
|
|
849
|
+
function getLoopStatus() {
|
|
850
|
+
const loopsDir = path.join(CWD, '.monomind', 'loops');
|
|
851
|
+
if (!fs.existsSync(loopsDir)) return { count: 0, loops: [] };
|
|
852
|
+
const STALE_MS = 6 * 60 * 60 * 1000;
|
|
853
|
+
const now = Date.now();
|
|
854
|
+
const loops = [];
|
|
855
|
+
try {
|
|
856
|
+
const files = fs.readdirSync(loopsDir).filter(f =>
|
|
857
|
+
f.endsWith('.json') && !f.includes('-hil') && !f.endsWith('.stop'));
|
|
858
|
+
for (const f of files) {
|
|
859
|
+
const d = readJSON(path.join(loopsDir, f));
|
|
860
|
+
if (!d || !d.command) continue;
|
|
861
|
+
const last = d.lastRunAt || d.nextRunAt || d.startedAt || 0;
|
|
862
|
+
if (last && (now - last) > STALE_MS) continue;
|
|
863
|
+
loops.push({
|
|
864
|
+
cmd: String(d.command).replace(/^\\//,''),
|
|
865
|
+
type: d.type || 'repeat',
|
|
866
|
+
rep: d.currentRep || 0,
|
|
867
|
+
max: d.maxReps || 0,
|
|
868
|
+
status: d.status || 'running',
|
|
869
|
+
});
|
|
870
|
+
}
|
|
871
|
+
} catch { /* ignore */ }
|
|
872
|
+
return { count: loops.length, loops };
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// HIL pending — count <id>-hil.md files with no human response yet
|
|
876
|
+
function getHILPending() {
|
|
877
|
+
const loopsDir = path.join(CWD, '.monomind', 'loops');
|
|
878
|
+
if (!fs.existsSync(loopsDir)) return { pending: 0 };
|
|
879
|
+
let pending = 0;
|
|
880
|
+
try {
|
|
881
|
+
const files = fs.readdirSync(loopsDir).filter(f => f.endsWith('-hil.md'));
|
|
882
|
+
for (const f of files) {
|
|
883
|
+
try {
|
|
884
|
+
const txt = fs.readFileSync(path.join(loopsDir, f), 'utf-8');
|
|
885
|
+
const answered = /^[ \\t]*>[ \\t]+\\S/m.test(txt);
|
|
886
|
+
if (!answered) pending++;
|
|
887
|
+
} catch { /* ignore */ }
|
|
888
|
+
}
|
|
889
|
+
} catch { /* ignore */ }
|
|
890
|
+
return { pending };
|
|
891
|
+
}
|
|
892
|
+
|
|
831
893
|
// Monograph knowledge graph stats
|
|
832
894
|
// Sources, in priority order:
|
|
833
895
|
// 1. .monomind/graph/stats.json — explicit cached stats
|
|
@@ -979,144 +1041,60 @@ function generateDashboard() {
|
|
|
979
1041
|
lines.push(hdr);
|
|
980
1042
|
lines.push(SEP);
|
|
981
1043
|
|
|
982
|
-
// ── Row 1:
|
|
983
|
-
|
|
984
|
-
const intellBar = blockBar(system.intelligencePct, 100, 6);
|
|
985
|
-
|
|
986
|
-
// Knowledge (Task 28)
|
|
987
|
-
const knowStr = knowledge.chunks > 0
|
|
988
|
-
? \`\${x.teal}📚 \${x.bold}\${knowledge.chunks}\${x.reset}\${x.slate} chunks\${x.reset}\`
|
|
989
|
-
: \`\${x.slate}📚 no chunks\${x.reset}\`;
|
|
990
|
-
|
|
991
|
-
// Skills (Task 45)
|
|
992
|
-
const skillStr = knowledge.skills > 0
|
|
993
|
-
? \` \${x.mint}✦ \${knowledge.skills} skills\${x.reset}\`
|
|
994
|
-
: '';
|
|
995
|
-
|
|
996
|
-
// Patterns
|
|
997
|
-
const patStr = progress.patternsLearned > 0
|
|
998
|
-
? \`\${x.gold}\${progress.patternsLearned >= 1000 ? (progress.patternsLearned / 1000).toFixed(1) + 'k' : progress.patternsLearned} patterns\${x.reset}\`
|
|
999
|
-
: \`\${x.slate}0 patterns\${x.reset}\`;
|
|
1000
|
-
|
|
1001
|
-
// Graph (monograph)
|
|
1002
|
-
const graph = getGraphifyStats();
|
|
1003
|
-
const graphStr = graph.exists
|
|
1004
|
-
? \`\${x.sky}🔗 \${x.bold}\${graph.nodes}\${x.reset}\${x.slate} nodes · \${x.reset}\${x.sky}\${x.bold}\${graph.edges}\${x.reset}\${x.slate} edges\${x.reset}\`
|
|
1005
|
-
: \`\${x.slate}🔗 no graph\${x.reset}\`;
|
|
1006
|
-
|
|
1007
|
-
lines.push(
|
|
1008
|
-
\`\${x.purple}💡 INTEL\${x.reset} \` +
|
|
1009
|
-
\`\${intellCol}\${intellBar} \${x.bold}\${system.intelligencePct}%\${x.reset} \${DIV} \` +
|
|
1010
|
-
\`\${knowStr}\${skillStr} \${DIV} \` +
|
|
1011
|
-
\`\${patStr} \${DIV} \` +
|
|
1012
|
-
graphStr
|
|
1013
|
-
);
|
|
1014
|
-
lines.push(SEP);
|
|
1015
|
-
|
|
1016
|
-
// ── Row 2: Agents & Triggers ──────────────────────────────────
|
|
1017
|
-
const agentCol = swarm.activeAgents > 0 ? x.green : x.slate;
|
|
1018
|
-
const hookCol = hooks.enabled > 0 ? x.mint : x.slate;
|
|
1019
|
-
|
|
1020
|
-
// Triggers (Task 32)
|
|
1021
|
-
const trigStr = triggers.triggers > 0
|
|
1022
|
-
? \`\${x.mint}🎯 \${x.bold}\${triggers.triggers}\${x.reset}\${x.slate} triggers · \${triggers.agents} agents\${x.reset}\`
|
|
1023
|
-
: \`\${x.slate}🎯 no triggers\${x.reset}\`;
|
|
1024
|
-
|
|
1025
|
-
// Active agent badge
|
|
1026
|
-
let agentBadge;
|
|
1044
|
+
// ── Row 1: Active agent + Loop status ────────────────────────
|
|
1045
|
+
let agentStr;
|
|
1027
1046
|
if (activeAgent) {
|
|
1028
1047
|
const col = activeAgent.activated ? x.green : x.sky;
|
|
1029
|
-
const mark = activeAgent.activated ?
|
|
1048
|
+
const mark = activeAgent.activated ? \`\${col}\${x.bold}● ACTIVE\${x.reset} \` : '';
|
|
1030
1049
|
const conf = activeAgent.activated ? '' : \` \${x.slate}\${(activeAgent.confidence * 100).toFixed(0)}%\${x.reset}\`;
|
|
1031
|
-
|
|
1032
|
-
agentBadge = \`\${col}\${x.bold}\${mark}\${x.reset} \${col}👤 \${x.bold}\${activeAgent.name}\${x.reset}\${cat}\${conf}\`;
|
|
1050
|
+
agentStr = \`\${mark}\${col}👤 \${x.bold}\${activeAgent.name}\${x.reset}\${conf}\`;
|
|
1033
1051
|
} else {
|
|
1034
|
-
|
|
1052
|
+
agentStr = \`\${x.slate}👤 no agent routed\${x.reset}\`;
|
|
1035
1053
|
}
|
|
1036
1054
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
const dddCol = pctColor(progress.dddProgress);
|
|
1055
|
-
const dddBar = blockBar(progress.dddProgress, 100, 5);
|
|
1056
|
-
|
|
1057
|
-
const cveStatus = security.totalCves === 0
|
|
1058
|
-
? (security.status === 'NONE' ? \`\${x.slate}not scanned\${x.reset}\` : \`\${x.green}✔ clean\${x.reset}\`)
|
|
1059
|
-
: \`\${x.coral}\${security.cvesFixed}/\${security.totalCves} fixed\${x.reset}\`;
|
|
1060
|
-
|
|
1061
|
-
lines.push(
|
|
1062
|
-
\`\${x.purple}🧩 ARCH\${x.reset} \` +
|
|
1063
|
-
\`\${adrStr} \${DIV} \` +
|
|
1064
|
-
\`DDD \${dddBar} \${dddCol}\${x.bold}\${progress.dddProgress}%\${x.reset} \${DIV} \` +
|
|
1065
|
-
\`🛡️ \${sec.col}\${sec.label}\${x.reset} \${DIV} \` +
|
|
1066
|
-
\`CVE \${cveStatus}\`
|
|
1067
|
-
);
|
|
1068
|
-
lines.push(SEP);
|
|
1069
|
-
|
|
1070
|
-
// ── Row 4: Memory & Tests ─────────────────────────────────────
|
|
1071
|
-
const vecCol = agentdb.vectorCount > 0 ? x.green : x.slate;
|
|
1072
|
-
const hnswTag = agentdb.hasHnsw && agentdb.vectorCount > 0 ? \` \${x.green}⚡ HNSW\${x.reset}\` : '';
|
|
1073
|
-
const sizeDisp = agentdb.dbSizeKB >= 1024
|
|
1074
|
-
? \`\${(agentdb.dbSizeKB / 1024).toFixed(1)} MB\` : \`\${agentdb.dbSizeKB} KB\`;
|
|
1075
|
-
const testCol = tests.testFiles > 0 ? x.green : x.slate;
|
|
1076
|
-
const memCol = system.memoryMB > 200 ? x.orange : x.sky;
|
|
1077
|
-
|
|
1078
|
-
const chips = [];
|
|
1079
|
-
if (integration.mcpServers.total > 0) {
|
|
1080
|
-
const mc = integration.mcpServers.enabled === integration.mcpServers.total ? x.green
|
|
1081
|
-
: integration.mcpServers.enabled > 0 ? x.gold : x.coral;
|
|
1082
|
-
chips.push(\`\${mc}MCP \${integration.mcpServers.enabled}/\${integration.mcpServers.total}\${x.reset}\`);
|
|
1055
|
+
const loopState = getLoopStatus();
|
|
1056
|
+
let loopStr;
|
|
1057
|
+
if (loopState.count > 0) {
|
|
1058
|
+
const parts = loopState.loops.slice(0, 2).map(l => {
|
|
1059
|
+
const status = l.status === 'hil:pending'
|
|
1060
|
+
? \`\${x.coral}⏳ HIL\${x.reset}\`
|
|
1061
|
+
: \`\${x.green}⟳\${x.reset}\`;
|
|
1062
|
+
const tag = l.type === 'tillend'
|
|
1063
|
+
? \`\${x.bold}\${l.cmd}\${x.reset}\${x.slate} run \${l.rep}\${x.reset}\`
|
|
1064
|
+
: \`\${x.bold}\${l.cmd}\${x.reset}\${x.slate} \${l.rep}/\${l.max}\${x.reset}\`;
|
|
1065
|
+
return \`\${status} \${tag}\`;
|
|
1066
|
+
});
|
|
1067
|
+
loopStr = \`\${x.gold}🔄\${x.reset} \${parts.join(\`\${x.slate} · \${x.reset}\`)}\`;
|
|
1068
|
+
if (loopState.count > 2) loopStr += \`\${x.slate} +\${loopState.count - 2} more\${x.reset}\`;
|
|
1069
|
+
} else {
|
|
1070
|
+
loopStr = \`\${x.slate}🔄 no active loops\${x.reset}\`;
|
|
1083
1071
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
const integStr = chips.length ? chips.join(' ') : \`\${x.slate}none\${x.reset}\`;
|
|
1087
|
-
|
|
1088
|
-
lines.push(
|
|
1089
|
-
\`\${x.teal}🗄️ MEMORY\${x.reset} \` +
|
|
1090
|
-
\`\${vecCol}\${x.bold}\${agentdb.vectorCount}\${x.reset}\${x.slate} vectors\${x.reset}\${hnswTag} \${DIV} \` +
|
|
1091
|
-
\`\${x.white}\${sizeDisp}\${x.reset} \${DIV} \` +
|
|
1092
|
-
\`\${testCol}🧪 \${tests.testFiles} test files\${x.reset} \${DIV} \` +
|
|
1093
|
-
integStr
|
|
1094
|
-
);
|
|
1072
|
+
|
|
1073
|
+
lines.push(\`\${x.purple}🤖 AGENT\${x.reset} \${agentStr} \${DIV} \${loopStr}\`);
|
|
1095
1074
|
lines.push(SEP);
|
|
1096
1075
|
|
|
1097
|
-
// ── Row
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1076
|
+
// ── Row 2: Graph freshness + Pending HIL ─────────────────────
|
|
1077
|
+
const gf = getGraphifyStats();
|
|
1078
|
+
const freshness = getGraphFreshness();
|
|
1079
|
+
let graphStr;
|
|
1080
|
+
if (gf.exists) {
|
|
1081
|
+
const nodesFmt = gf.nodes >= 1000 ? \`\${(gf.nodes / 1000).toFixed(0)}k\` : \`\${gf.nodes}\`;
|
|
1082
|
+
const freshTag = freshness.fresh
|
|
1083
|
+
? \`\${x.green}● fresh\${x.reset}\`
|
|
1084
|
+
: freshness.stale
|
|
1085
|
+
? \`\${x.coral}● \${freshness.commitsBehind} commits stale\${x.reset}\`
|
|
1086
|
+
: \`\${x.gold}● \${freshness.commitsBehind} behind\${x.reset}\`;
|
|
1087
|
+
graphStr = \`\${x.sky}🔗 \${x.bold}\${nodesFmt}\${x.reset}\${x.slate} nodes\${x.reset} \${freshTag}\`;
|
|
1103
1088
|
} else {
|
|
1104
|
-
|
|
1089
|
+
graphStr = \`\${x.slate}🔗 no graph\${x.reset}\`;
|
|
1105
1090
|
}
|
|
1106
1091
|
|
|
1107
|
-
|
|
1108
|
-
const
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
lines.push(
|
|
1115
|
-
\`\${x.slate}📋 CONTEXT\${x.reset} \` +
|
|
1116
|
-
\`\${siStr} \${DIV} \` +
|
|
1117
|
-
\`\${x.teal}🏗 \${domBar} \${domCol}\${x.bold}\${progress.domainsCompleted}\${x.reset}\${x.slate}/\${x.reset}\${x.white}\${progress.totalDomains}\${x.reset} domains \${DIV} \` +
|
|
1118
|
-
\`\${x.dim}💾 \${system.memoryMB} MB RAM\${x.reset}\`
|
|
1119
|
-
);
|
|
1092
|
+
const hil = getHILPending();
|
|
1093
|
+
const hilStr = hil.pending > 0
|
|
1094
|
+
? \`\${x.coral}✨ \${x.bold}\${hil.pending}\${x.reset}\${x.coral} HIL pending\${x.reset}\`
|
|
1095
|
+
: \`\${x.slate}✨ no pending HIL\${x.reset}\`;
|
|
1096
|
+
|
|
1097
|
+
lines.push(\`\${x.teal}🧠 CONTEXT\${x.reset} \${graphStr} \${DIV} \${hilStr}\`);
|
|
1120
1098
|
|
|
1121
1099
|
return lines.join('\\n');
|
|
1122
1100
|
}
|
|
@@ -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
|
|
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"}
|