@monoes/monomindcli 2.7.4 → 2.7.5
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/bin/cli.js +17 -1
- package/dist/src/commands/doctor-project-checks.d.ts +3 -0
- package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
- package/dist/src/commands/doctor-project-checks.js +81 -8
- package/dist/src/commands/doctor-project-checks.js.map +1 -1
- package/dist/src/commands/doctor.d.ts.map +1 -1
- package/dist/src/commands/doctor.js +16 -2
- package/dist/src/commands/doctor.js.map +1 -1
- package/dist/src/commands/memory-crud.d.ts.map +1 -1
- package/dist/src/commands/memory-crud.js +15 -5
- package/dist/src/commands/memory-crud.js.map +1 -1
- package/dist/src/commands/security-misc.d.ts.map +1 -1
- package/dist/src/commands/security-misc.js +7 -2
- package/dist/src/commands/security-misc.js.map +1 -1
- package/dist/src/init/helpers-generator.d.ts.map +1 -1
- package/dist/src/init/helpers-generator.js +5 -0
- package/dist/src/init/helpers-generator.js.map +1 -1
- package/dist/src/mcp-client.d.ts.map +1 -1
- package/dist/src/mcp-client.js +0 -2
- package/dist/src/mcp-client.js.map +1 -1
- package/dist/src/mcp-tools/agent-tools.js +1 -1
- package/dist/src/mcp-tools/agent-tools.js.map +1 -1
- package/dist/src/mcp-tools/embeddings-tools.d.ts +2 -0
- package/dist/src/mcp-tools/embeddings-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/embeddings-tools.js +11 -1
- package/dist/src/mcp-tools/embeddings-tools.js.map +1 -1
- package/dist/src/mcp-tools/guidance-tools.js +17 -17
- package/dist/src/mcp-tools/guidance-tools.js.map +1 -1
- package/dist/src/mcp-tools/hive-mind-tools.d.ts +2 -0
- package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/hive-mind-tools.js +14 -2
- package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -1
- package/dist/src/mcp-tools/index.d.ts +0 -1
- package/dist/src/mcp-tools/index.d.ts.map +1 -1
- package/dist/src/mcp-tools/index.js +0 -1
- package/dist/src/mcp-tools/index.js.map +1 -1
- package/dist/src/mcp-tools/monograph-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/monograph-tools.js +1 -2
- package/dist/src/mcp-tools/monograph-tools.js.map +1 -1
- package/dist/src/mcp-tools/neural-tools.js +1 -1
- package/dist/src/mcp-tools/neural-tools.js.map +1 -1
- package/dist/src/mcp-tools/swarm-tools.js +2 -2
- package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
- package/dist/src/mcp-tools/transfer-tools.d.ts +2 -0
- package/dist/src/mcp-tools/transfer-tools.d.ts.map +1 -1
- package/dist/src/mcp-tools/transfer-tools.js +11 -1
- package/dist/src/mcp-tools/transfer-tools.js.map +1 -1
- package/dist/src/ui/dashboard.html +44 -618
- package/dist/src/ui/server.mjs +0 -275
- package/dist/src/utils/cosine-similarity.d.ts +2 -2
- package/dist/src/utils/cosine-similarity.js +2 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/src/mcp-tools/coherence/causal-infer.d.ts +0 -15
- package/dist/src/mcp-tools/coherence/causal-infer.d.ts.map +0 -1
- package/dist/src/mcp-tools/coherence/causal-infer.js +0 -333
- package/dist/src/mcp-tools/coherence/causal-infer.js.map +0 -1
- package/dist/src/mcp-tools/coherence/coherence-check.d.ts +0 -15
- package/dist/src/mcp-tools/coherence/coherence-check.d.ts.map +0 -1
- package/dist/src/mcp-tools/coherence/coherence-check.js +0 -188
- package/dist/src/mcp-tools/coherence/coherence-check.js.map +0 -1
- package/dist/src/mcp-tools/coherence/consensus-verify.d.ts +0 -14
- package/dist/src/mcp-tools/coherence/consensus-verify.d.ts.map +0 -1
- package/dist/src/mcp-tools/coherence/consensus-verify.js +0 -305
- package/dist/src/mcp-tools/coherence/consensus-verify.js.map +0 -1
- package/dist/src/mcp-tools/coherence/memory-gate.d.ts +0 -16
- package/dist/src/mcp-tools/coherence/memory-gate.d.ts.map +0 -1
- package/dist/src/mcp-tools/coherence/memory-gate.js +0 -279
- package/dist/src/mcp-tools/coherence/memory-gate.js.map +0 -1
- package/dist/src/mcp-tools/coherence/quantum-topology.d.ts +0 -15
- package/dist/src/mcp-tools/coherence/quantum-topology.d.ts.map +0 -1
- package/dist/src/mcp-tools/coherence/quantum-topology.js +0 -400
- package/dist/src/mcp-tools/coherence/quantum-topology.js.map +0 -1
- package/dist/src/mcp-tools/coherence/spectral-analyze.d.ts +0 -14
- package/dist/src/mcp-tools/coherence/spectral-analyze.d.ts.map +0 -1
- package/dist/src/mcp-tools/coherence/spectral-analyze.js +0 -312
- package/dist/src/mcp-tools/coherence/spectral-analyze.js.map +0 -1
- package/dist/src/mcp-tools/coherence/types.d.ts +0 -430
- package/dist/src/mcp-tools/coherence/types.d.ts.map +0 -1
- package/dist/src/mcp-tools/coherence/types.js +0 -144
- package/dist/src/mcp-tools/coherence/types.js.map +0 -1
- package/dist/src/mcp-tools/coherence-tools.d.ts +0 -9
- package/dist/src/mcp-tools/coherence-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/coherence-tools.js +0 -25
- package/dist/src/mcp-tools/coherence-tools.js.map +0 -1
- package/dist/src/mcp-tools/daa-tools.d.ts +0 -13
- package/dist/src/mcp-tools/daa-tools.d.ts.map +0 -1
- package/dist/src/mcp-tools/daa-tools.js +0 -553
- package/dist/src/mcp-tools/daa-tools.js.map +0 -1
package/dist/src/ui/server.mjs
CHANGED
|
@@ -1874,22 +1874,6 @@ export async function startServer({ port = 4242, projectDir, openBrowser = true
|
|
|
1874
1874
|
return;
|
|
1875
1875
|
}
|
|
1876
1876
|
|
|
1877
|
-
// GET /api/adr-file?file=<name>&dir=<dir> — read a single ADR markdown file
|
|
1878
|
-
if (req.method === 'GET' && url === '/api/adr-file') {
|
|
1879
|
-
try {
|
|
1880
|
-
const qs = new URL(req.url, 'http://localhost').searchParams;
|
|
1881
|
-
const dir = qs.get('dir') || projectDir || process.cwd();
|
|
1882
|
-
const fname = (qs.get('file') || '').replace(/[/\\]/g, '');
|
|
1883
|
-
if (!fname || !fname.endsWith('.md')) { res.writeHead(400); res.end('{"error":"invalid file"}'); return; }
|
|
1884
|
-
const fpath = path.join(path.resolve(dir), 'docs', 'adrs', fname);
|
|
1885
|
-
if (!fs.existsSync(fpath)) { res.writeHead(404); res.end('{"error":"not found"}'); return; }
|
|
1886
|
-
const content = fs.readFileSync(fpath, 'utf8');
|
|
1887
|
-
res.writeHead(200, { 'Content-Type': 'application/json', ...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}) });
|
|
1888
|
-
res.end(JSON.stringify({ file: fname, content }));
|
|
1889
|
-
} catch (err) { res.writeHead(500); res.end(JSON.stringify({ error: err.message })); }
|
|
1890
|
-
return;
|
|
1891
|
-
}
|
|
1892
|
-
|
|
1893
1877
|
// ------------------------------------------------------- GET /api/memory-files
|
|
1894
1878
|
if (req.method === 'GET' && url === '/api/memory-files') {
|
|
1895
1879
|
try {
|
|
@@ -6331,265 +6315,6 @@ new Sigma(g,document.getElementById('g'),{renderEdgeLabels:false,labelColor:{col
|
|
|
6331
6315
|
return;
|
|
6332
6316
|
}
|
|
6333
6317
|
|
|
6334
|
-
// GET /api/second-brain-metrics — aggregated injection analytics from second-brain.jsonl
|
|
6335
|
-
if (req.method === 'GET' && url === '/api/second-brain-metrics') {
|
|
6336
|
-
try {
|
|
6337
|
-
const metricsFile = path.join(projectDir || process.cwd(), '.monomind', 'metrics', 'second-brain.jsonl');
|
|
6338
|
-
if (!fs.existsSync(metricsFile)) {
|
|
6339
|
-
res.writeHead(200, { 'Content-Type': 'application/json', ...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}) });
|
|
6340
|
-
res.end(JSON.stringify({ total: 0, injected: 0, hitRate: 0, methods: {}, avgScore: 0, sparkline: [], scores: [] }));
|
|
6341
|
-
return;
|
|
6342
|
-
}
|
|
6343
|
-
const raw = fs.readFileSync(metricsFile, 'utf8');
|
|
6344
|
-
const entries = raw.split('\n').filter(Boolean).map(l => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean);
|
|
6345
|
-
const total = entries.length;
|
|
6346
|
-
const injectedCount = entries.filter(e => e.injected).length;
|
|
6347
|
-
const hitRate = total > 0 ? injectedCount / total : 0;
|
|
6348
|
-
// Method distribution
|
|
6349
|
-
const methods = {};
|
|
6350
|
-
for (const e of entries) { const m = e.method || 'unknown'; methods[m] = (methods[m] || 0) + 1; }
|
|
6351
|
-
// Average top score (only for entries with hits)
|
|
6352
|
-
const withScores = entries.filter(e => typeof e.topScore === 'number' && e.topScore !== null);
|
|
6353
|
-
const avgScore = withScores.length > 0 ? withScores.reduce((s, e) => s + e.topScore, 0) / withScores.length : 0;
|
|
6354
|
-
// Score distribution buckets
|
|
6355
|
-
const scoreBuckets = [0, 0, 0, 0, 0]; // <0.3, 0.3-0.5, 0.5-0.7, 0.7-0.9, 0.9+
|
|
6356
|
-
for (const e of withScores) {
|
|
6357
|
-
const s = e.topScore;
|
|
6358
|
-
if (s < 0.3) scoreBuckets[0]++;
|
|
6359
|
-
else if (s < 0.5) scoreBuckets[1]++;
|
|
6360
|
-
else if (s < 0.7) scoreBuckets[2]++;
|
|
6361
|
-
else if (s < 0.9) scoreBuckets[3]++;
|
|
6362
|
-
else scoreBuckets[4]++;
|
|
6363
|
-
}
|
|
6364
|
-
// Sparkline: group by hour for last 24h, then by day for older
|
|
6365
|
-
const now = Date.now();
|
|
6366
|
-
const h24 = now - 86400000;
|
|
6367
|
-
const sparkline = [];
|
|
6368
|
-
// Last 24 hours in 2h buckets
|
|
6369
|
-
for (let t = h24; t < now; t += 7200000) {
|
|
6370
|
-
const bucket = entries.filter(e => e.ts >= t && e.ts < t + 7200000);
|
|
6371
|
-
const inj = bucket.filter(e => e.injected).length;
|
|
6372
|
-
sparkline.push({ t, total: bucket.length, injected: inj });
|
|
6373
|
-
}
|
|
6374
|
-
// Top sources from recent entries (last 200)
|
|
6375
|
-
const recentSlice = entries.slice(-200);
|
|
6376
|
-
const misses = recentSlice.filter(e => !e.injected).length;
|
|
6377
|
-
// Route overrides (misroute counts)
|
|
6378
|
-
let routeOverrides = {};
|
|
6379
|
-
try {
|
|
6380
|
-
const overridesFile = path.join(projectDir || process.cwd(), '.monomind', 'metrics', 'route-overrides.json');
|
|
6381
|
-
if (fs.existsSync(overridesFile)) routeOverrides = JSON.parse(fs.readFileSync(overridesFile, 'utf8'));
|
|
6382
|
-
} catch {}
|
|
6383
|
-
res.writeHead(200, { 'Content-Type': 'application/json', ...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}) });
|
|
6384
|
-
res.end(JSON.stringify({ total, injected: injectedCount, hitRate: +hitRate.toFixed(3), methods, avgScore: +avgScore.toFixed(3), sparkline, scoreBuckets, recentMisses: misses, recentTotal: recentSlice.length, routeOverrides }));
|
|
6385
|
-
} catch (err) {
|
|
6386
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
6387
|
-
res.end(JSON.stringify({ error: err.message }));
|
|
6388
|
-
}
|
|
6389
|
-
return;
|
|
6390
|
-
}
|
|
6391
|
-
|
|
6392
|
-
// POST /api/second-brain-route — show query router decision for a given query
|
|
6393
|
-
if (req.method === 'POST' && url === '/api/second-brain-route') {
|
|
6394
|
-
let body = '';
|
|
6395
|
-
req.on('data', c => { body += c; if (body.length > 65536) { req.destroy(); return; } });
|
|
6396
|
-
req.on('end', async () => {
|
|
6397
|
-
try {
|
|
6398
|
-
const { query } = JSON.parse(body || '{}');
|
|
6399
|
-
if (!query) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end('{"error":"query required"}'); return; }
|
|
6400
|
-
const routerMod = await import('../memory/query-router.js');
|
|
6401
|
-
const route = routerMod.routeQuery(String(query).slice(0, 2000));
|
|
6402
|
-
const overrides = routerMod.getRouteOverrides(true);
|
|
6403
|
-
res.writeHead(200, { 'Content-Type': 'application/json', ...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}) });
|
|
6404
|
-
res.end(JSON.stringify({ route, overrides }));
|
|
6405
|
-
} catch (err) {
|
|
6406
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
6407
|
-
res.end(JSON.stringify({ error: err.message }));
|
|
6408
|
-
}
|
|
6409
|
-
});
|
|
6410
|
-
return;
|
|
6411
|
-
}
|
|
6412
|
-
|
|
6413
|
-
// GET/PUT /api/second-brain-config — read/write Second Brain config (.monomind/second-brain.json)
|
|
6414
|
-
if ((req.method === 'GET' || req.method === 'PUT') && url === '/api/second-brain-config') {
|
|
6415
|
-
const configFile = path.join(projectDir || process.cwd(), '.monomind', 'second-brain.json');
|
|
6416
|
-
if (req.method === 'GET') {
|
|
6417
|
-
try {
|
|
6418
|
-
let config = { relevanceFloor: 0.35, injectionLimit: 5 };
|
|
6419
|
-
try { config = { ...config, ...JSON.parse(fs.readFileSync(configFile, 'utf8')) }; } catch {}
|
|
6420
|
-
// Auto-tune suggestion: analyze telemetry to suggest optimal floor
|
|
6421
|
-
let suggestion = null;
|
|
6422
|
-
try {
|
|
6423
|
-
const metricsFile = path.join(projectDir || process.cwd(), '.monomind', 'metrics', 'second-brain.jsonl');
|
|
6424
|
-
if (fs.existsSync(metricsFile)) {
|
|
6425
|
-
const entries = fs.readFileSync(metricsFile, 'utf8').split('\n').filter(Boolean)
|
|
6426
|
-
.map(l => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean);
|
|
6427
|
-
const withScores = entries.filter(e => typeof e.topScore === 'number' && e.topScore !== null);
|
|
6428
|
-
if (withScores.length >= 20) {
|
|
6429
|
-
const scores = withScores.map(e => e.topScore).sort((a, b) => a - b);
|
|
6430
|
-
const p25 = scores[Math.floor(scores.length * 0.25)];
|
|
6431
|
-
const hitRate = entries.filter(e => e.injected).length / entries.length;
|
|
6432
|
-
// If hit rate is very low (<30%), suggest lowering floor
|
|
6433
|
-
// If hit rate is very high (>80%) with low avg scores, suggest raising
|
|
6434
|
-
if (hitRate < 0.3 && p25 > 0.2) suggestion = { floor: +(p25 - 0.05).toFixed(2), reason: 'Low hit rate (' + (hitRate * 100).toFixed(0) + '%) — lowering floor may surface more relevant results' };
|
|
6435
|
-
else if (hitRate > 0.8 && scores[Math.floor(scores.length * 0.1)] < 0.35) suggestion = { floor: 0.4, reason: 'High hit rate with low-quality matches — raising floor filters noise' };
|
|
6436
|
-
}
|
|
6437
|
-
}
|
|
6438
|
-
} catch {}
|
|
6439
|
-
res.writeHead(200, { 'Content-Type': 'application/json', ...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}) });
|
|
6440
|
-
res.end(JSON.stringify({ config, suggestion }));
|
|
6441
|
-
} catch (err) {
|
|
6442
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
6443
|
-
res.end(JSON.stringify({ error: err.message }));
|
|
6444
|
-
}
|
|
6445
|
-
return;
|
|
6446
|
-
}
|
|
6447
|
-
if (req.method === 'PUT') {
|
|
6448
|
-
let body = '';
|
|
6449
|
-
req.on('data', c => { body += c; if (body.length > 4096) { req.destroy(); return; } });
|
|
6450
|
-
req.on('end', () => {
|
|
6451
|
-
try {
|
|
6452
|
-
const raw = JSON.parse(body || '{}');
|
|
6453
|
-
const updates = {};
|
|
6454
|
-
if (typeof raw.relevanceFloor === 'number' && raw.relevanceFloor >= 0 && raw.relevanceFloor <= 1) updates.relevanceFloor = raw.relevanceFloor;
|
|
6455
|
-
if (typeof raw.injectionLimit === 'number' && raw.injectionLimit >= 1 && raw.injectionLimit <= 50) updates.injectionLimit = Math.floor(raw.injectionLimit);
|
|
6456
|
-
if (Object.keys(updates).length === 0) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end('{"error":"no valid fields to update"}'); return; }
|
|
6457
|
-
let config = {};
|
|
6458
|
-
try { config = JSON.parse(fs.readFileSync(configFile, 'utf8')); } catch {}
|
|
6459
|
-
config = { ...config, ...updates };
|
|
6460
|
-
fs.mkdirSync(path.dirname(configFile), { recursive: true });
|
|
6461
|
-
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
|
|
6462
|
-
res.writeHead(200, { 'Content-Type': 'application/json', ...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}) });
|
|
6463
|
-
res.end(JSON.stringify({ ok: true, config }));
|
|
6464
|
-
} catch (err) {
|
|
6465
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
6466
|
-
res.end(JSON.stringify({ error: err.message }));
|
|
6467
|
-
}
|
|
6468
|
-
});
|
|
6469
|
-
return;
|
|
6470
|
-
}
|
|
6471
|
-
}
|
|
6472
|
-
|
|
6473
|
-
// GET /api/second-brain-docs — document-level view from doc-metadata.jsonl
|
|
6474
|
-
if (req.method === 'GET' && url === '/api/second-brain-docs') {
|
|
6475
|
-
try {
|
|
6476
|
-
const d = path.resolve(projectDir || process.cwd());
|
|
6477
|
-
const metaFile = path.join(d, '.monomind', 'knowledge', 'doc-metadata.jsonl');
|
|
6478
|
-
// Also check global brain
|
|
6479
|
-
const globalDir = process.env.MONOMIND_GLOBAL_BRAIN_DIR || path.join(os.homedir(), '.monomind', 'global-brain');
|
|
6480
|
-
const globalMetaFile = path.join(globalDir, '.monomind', 'knowledge', 'doc-metadata.jsonl');
|
|
6481
|
-
const docs = [];
|
|
6482
|
-
let totalSize = 0, totalChunks = 0;
|
|
6483
|
-
for (const [file, scope] of [[metaFile, 'project'], [globalMetaFile, 'global']]) {
|
|
6484
|
-
if (!fs.existsSync(file)) continue;
|
|
6485
|
-
const latest = new Map();
|
|
6486
|
-
for (const l of fs.readFileSync(file, 'utf8').split('\n')) {
|
|
6487
|
-
if (!l.trim()) continue;
|
|
6488
|
-
try {
|
|
6489
|
-
const m = JSON.parse(l);
|
|
6490
|
-
latest.set(m.filePath + ' ' + m.scope, m);
|
|
6491
|
-
} catch {}
|
|
6492
|
-
}
|
|
6493
|
-
for (const m of latest.values()) {
|
|
6494
|
-
if (m.chunkCount < 0) continue;
|
|
6495
|
-
const exists = fs.existsSync(m.filePath);
|
|
6496
|
-
docs.push({ ...m, brainScope: scope, exists, name: path.basename(m.filePath) });
|
|
6497
|
-
totalSize += m.size || 0;
|
|
6498
|
-
totalChunks += m.chunkCount || 0;
|
|
6499
|
-
}
|
|
6500
|
-
}
|
|
6501
|
-
docs.sort((a, b) => (b.indexedAt || '').localeCompare(a.indexedAt || ''));
|
|
6502
|
-
const globalCount = docs.filter(d => d.brainScope === 'global').length;
|
|
6503
|
-
res.writeHead(200, { 'Content-Type': 'application/json', ...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}) });
|
|
6504
|
-
res.end(JSON.stringify({ docs, totalDocs: docs.length, totalSize, totalChunks, globalCount, projectCount: docs.length - globalCount }));
|
|
6505
|
-
} catch (err) {
|
|
6506
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
6507
|
-
res.end(JSON.stringify({ error: err.message }));
|
|
6508
|
-
}
|
|
6509
|
-
return;
|
|
6510
|
-
}
|
|
6511
|
-
|
|
6512
|
-
// GET /api/second-brain-ingest-stream — SSE stream tailing doc-metadata.jsonl for live ingest events
|
|
6513
|
-
if (req.method === 'GET' && url === '/api/second-brain-ingest-stream') {
|
|
6514
|
-
res.writeHead(200, {
|
|
6515
|
-
'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive',
|
|
6516
|
-
...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {})
|
|
6517
|
-
});
|
|
6518
|
-
res.write('data: {"type":"connected"}\n\n');
|
|
6519
|
-
const metaFile = path.join(projectDir || process.cwd(), '.monomind', 'knowledge', 'doc-metadata.jsonl');
|
|
6520
|
-
let lastSize = 0;
|
|
6521
|
-
try { lastSize = fs.statSync(metaFile).size; } catch {}
|
|
6522
|
-
function _sseTailFile(filePath, lastSizeRef, eventType, transform) {
|
|
6523
|
-
try {
|
|
6524
|
-
const stat = fs.statSync(filePath);
|
|
6525
|
-
if (stat.size < lastSizeRef.v) { lastSizeRef.v = 0; }
|
|
6526
|
-
if (stat.size > lastSizeRef.v) {
|
|
6527
|
-
let fd;
|
|
6528
|
-
try {
|
|
6529
|
-
fd = fs.openSync(filePath, 'r');
|
|
6530
|
-
const buf = Buffer.alloc(stat.size - lastSizeRef.v);
|
|
6531
|
-
fs.readSync(fd, buf, 0, buf.length, lastSizeRef.v);
|
|
6532
|
-
lastSizeRef.v = stat.size;
|
|
6533
|
-
const lines = buf.toString('utf8').split('\n').filter(Boolean);
|
|
6534
|
-
for (const l of lines) {
|
|
6535
|
-
try { const parsed = JSON.parse(l); res.write('data: ' + JSON.stringify(transform(parsed)) + '\n\n'); } catch {}
|
|
6536
|
-
}
|
|
6537
|
-
} finally { if (fd !== undefined) fs.closeSync(fd); }
|
|
6538
|
-
}
|
|
6539
|
-
} catch {}
|
|
6540
|
-
}
|
|
6541
|
-
const metaSize = { v: lastSize };
|
|
6542
|
-
const interval = setInterval(() => _sseTailFile(metaFile, metaSize, 'ingest', m => ({ type: 'ingest', doc: { ...m, name: path.basename(m.filePath || '') } })), 2000);
|
|
6543
|
-
const metricsFile = path.join(projectDir || process.cwd(), '.monomind', 'metrics', 'second-brain.jsonl');
|
|
6544
|
-
const metricsSize = { v: 0 };
|
|
6545
|
-
try { metricsSize.v = fs.statSync(metricsFile).size; } catch {}
|
|
6546
|
-
const metricsInterval = setInterval(() => _sseTailFile(metricsFile, metricsSize, 'injection', e => ({ type: 'injection', event: e })), 3000);
|
|
6547
|
-
req.on('close', () => { clearInterval(interval); clearInterval(metricsInterval); });
|
|
6548
|
-
return;
|
|
6549
|
-
}
|
|
6550
|
-
|
|
6551
|
-
// GET /api/second-brain-kg — knowledge graph triplets + stats for the KG explorer
|
|
6552
|
-
if (req.method === 'GET' && url === '/api/second-brain-kg') {
|
|
6553
|
-
try {
|
|
6554
|
-
const qs = new URL(req.url, 'http://localhost').searchParams;
|
|
6555
|
-
const query = (qs.get('q') || '').slice(0, 200);
|
|
6556
|
-
const limit = Math.min(parseInt(qs.get('limit') || '50', 10), 200);
|
|
6557
|
-
const monoDir = path.join(projectDir || process.cwd(), '.monomind');
|
|
6558
|
-
const dbPath = path.join(monoDir, 'memory');
|
|
6559
|
-
let stats = { nodes: 0, edges: 0 }, triplets = [], glossary = [];
|
|
6560
|
-
try {
|
|
6561
|
-
const kg = await import('../memory/memory-kg.js');
|
|
6562
|
-
stats = await kg.kgStats({ dbPath });
|
|
6563
|
-
glossary = await kg.kgGlossary({ dbPath, limit: 30 });
|
|
6564
|
-
if (query) {
|
|
6565
|
-
const searchResult = await kg.kgSearch({ query, limit, dbPath });
|
|
6566
|
-
triplets = searchResult.triplets || searchResult || [];
|
|
6567
|
-
} else {
|
|
6568
|
-
const searchResult = await kg.kgSearch({ query: '*', limit, dbPath }).catch(() => null);
|
|
6569
|
-
triplets = searchResult ? (searchResult.triplets || searchResult) : [];
|
|
6570
|
-
}
|
|
6571
|
-
} catch {}
|
|
6572
|
-
// Also check palace kg.json as fallback
|
|
6573
|
-
if (triplets.length === 0) {
|
|
6574
|
-
try {
|
|
6575
|
-
const palaceDir = path.join(monoDir, 'palace');
|
|
6576
|
-
const kgData = JSON.parse(fs.readFileSync(path.join(palaceDir, 'kg.json'), 'utf8'));
|
|
6577
|
-
if (Array.isArray(kgData)) {
|
|
6578
|
-
triplets = kgData.slice(0, limit);
|
|
6579
|
-
stats.nodes = new Set(kgData.flatMap(t => [t.subject || t.s, t.object || t.o])).size;
|
|
6580
|
-
stats.edges = kgData.length;
|
|
6581
|
-
}
|
|
6582
|
-
} catch {}
|
|
6583
|
-
}
|
|
6584
|
-
res.writeHead(200, { 'Content-Type': 'application/json', ...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}) });
|
|
6585
|
-
res.end(JSON.stringify({ stats, triplets, glossary }));
|
|
6586
|
-
} catch (err) {
|
|
6587
|
-
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
6588
|
-
res.end(JSON.stringify({ error: err.message }));
|
|
6589
|
-
}
|
|
6590
|
-
return;
|
|
6591
|
-
}
|
|
6592
|
-
|
|
6593
6318
|
// GET /api/mastermind/metrics — aggregate system metrics from token-summary and swarm-activity
|
|
6594
6319
|
if (req.method === 'GET' && url === '/api/mastermind/metrics') {
|
|
6595
6320
|
try {
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* - memory/intelligence.ts (ReasoningBank.cosineSim)
|
|
6
6
|
* - mcp-tools/neural-tools.ts (cosineSimilarity)
|
|
7
7
|
* - mcp-tools/embeddings-tools.ts (cosineSimilarity)
|
|
8
|
-
* - mcp-tools/coherence/types.ts (
|
|
9
|
-
*
|
|
8
|
+
* - mcp-tools/coherence/types.ts + coherence-check.ts (both since deleted
|
|
9
|
+
* along with the rest of the uncalled coherence_* family)
|
|
10
10
|
*
|
|
11
11
|
* This is the single canonical implementation. Accepts number[] or
|
|
12
12
|
* Float32Array. Handles dimension mismatches gracefully (uses the shorter
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* - memory/intelligence.ts (ReasoningBank.cosineSim)
|
|
6
6
|
* - mcp-tools/neural-tools.ts (cosineSimilarity)
|
|
7
7
|
* - mcp-tools/embeddings-tools.ts (cosineSimilarity)
|
|
8
|
-
* - mcp-tools/coherence/types.ts (
|
|
9
|
-
*
|
|
8
|
+
* - mcp-tools/coherence/types.ts + coherence-check.ts (both since deleted
|
|
9
|
+
* along with the rest of the uncalled coherence_* family)
|
|
10
10
|
*
|
|
11
11
|
* This is the single canonical implementation. Accepts number[] or
|
|
12
12
|
* Float32Array. Handles dimension mismatches gracefully (uses the shorter
|