@monoes/monomindcli 1.6.0 → 1.6.2
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/commands/monomind-do.md +41 -0
- package/.claude/commands/monomind-repeat.md +55 -1
- package/dist/src/mcp-tools/agent-tools.js +12 -1
- package/dist/src/mcp-tools/hive-mind-tools.js +18 -1
- package/dist/src/mcp-tools/hooks-tools.js +11 -1
- package/dist/src/mcp-tools/swarm-tools.js +11 -1
- package/dist/src/ui/collector.mjs +98 -9
- package/dist/src/ui/dashboard.html +1173 -511
- package/dist/src/ui/server.mjs +168 -3
- package/package.json +1 -1
package/dist/src/ui/server.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import fs from 'fs';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import os from 'os';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
|
-
import { collectAll, getWatchPaths, collectProject, collectSessions, collectSwarm, collectAgents, collectTokens, collectHooks, collectKnowledge, collectMetrics, collectMemory, collectMemoryFiles, collectSystem } from './collector.mjs';
|
|
6
|
+
import { collectAll, getWatchPaths, collectProject, collectSessions, collectSwarm, collectSwarmHistory, appendSwarmHistory, collectSwarmEvents, getSwarmDataSize, cleanSwarmData, collectAgents, collectTokens, collectHooks, collectKnowledge, collectMetrics, collectMemory, collectMemoryFiles, collectSystem } from './collector.mjs';
|
|
7
7
|
|
|
8
8
|
const JSONL_SIZE_CAP = 10 * 1024 * 1024; // 10 MB — skip files larger than this in /api/graph
|
|
9
9
|
|
|
@@ -104,7 +104,7 @@ function buildSectionData(name, dir) {
|
|
|
104
104
|
const d = path.resolve(dir);
|
|
105
105
|
switch (name) {
|
|
106
106
|
case 'sessions': return { sessions: collectSessions(d) };
|
|
107
|
-
case 'swarm': return { swarm: collectSwarm(d), agents: collectAgents(d) };
|
|
107
|
+
case 'swarm': return { swarm: collectSwarm(d), swarmHistory: collectSwarmHistory(d), agents: collectAgents(d) };
|
|
108
108
|
case 'agents': return { agents: collectAgents(d) };
|
|
109
109
|
case 'tokens': return { tokens: collectTokens(d) };
|
|
110
110
|
case 'hooks': return { hooks: collectHooks(d) };
|
|
@@ -187,7 +187,7 @@ function bindServer(server, port) {
|
|
|
187
187
|
let attempt = 0;
|
|
188
188
|
|
|
189
189
|
function tryPort(p) {
|
|
190
|
-
server.listen(p,
|
|
190
|
+
server.listen(p, () => resolve(p));
|
|
191
191
|
server.once('error', (err) => {
|
|
192
192
|
if (err.code === 'EADDRINUSE' && attempt < maxTries) {
|
|
193
193
|
attempt += 1;
|
|
@@ -277,6 +277,65 @@ export async function startServer({ port = 4242, projectDir, openBrowser = true
|
|
|
277
277
|
return;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
// ------------------------------------------------------- GET /api/session-journal
|
|
281
|
+
if (req.method === 'GET' && url === '/api/session-journal') {
|
|
282
|
+
try {
|
|
283
|
+
const qs = new URL(req.url, 'http://localhost').searchParams;
|
|
284
|
+
const dir = qs.get('dir') || projectDir;
|
|
285
|
+
const d = path.resolve(dir || process.cwd());
|
|
286
|
+
const slug = d.replace(/\//g, '-');
|
|
287
|
+
const projectClaudeDir = path.join(os.homedir(), '.claude', 'projects', slug);
|
|
288
|
+
|
|
289
|
+
let sessionFiles = [];
|
|
290
|
+
try {
|
|
291
|
+
sessionFiles = fs.readdirSync(projectClaudeDir)
|
|
292
|
+
.filter(f => f.endsWith('.jsonl'))
|
|
293
|
+
.map(f => { try { return { f, mtime: fs.statSync(path.join(projectClaudeDir, f)).mtimeMs }; } catch { return null; } })
|
|
294
|
+
.filter(Boolean)
|
|
295
|
+
.sort((a, b) => b.mtime - a.mtime)
|
|
296
|
+
.slice(0, 15);
|
|
297
|
+
} catch {}
|
|
298
|
+
|
|
299
|
+
const sessions = [];
|
|
300
|
+
for (const { f, mtime } of sessionFiles) {
|
|
301
|
+
const fp = path.join(projectClaudeDir, f);
|
|
302
|
+
const id = f.replace('.jsonl', '');
|
|
303
|
+
let lastPrompt = '', summaries = [], totalDurationMs = 0, totalMessages = 0, firstTs = null, lastTs = null;
|
|
304
|
+
try {
|
|
305
|
+
const lines = fs.readFileSync(fp, 'utf8').split('\n').filter(Boolean);
|
|
306
|
+
let pendingCompact = false;
|
|
307
|
+
for (const line of lines) {
|
|
308
|
+
let e; try { e = JSON.parse(line); } catch { continue; }
|
|
309
|
+
if (e.timestamp) { if (!firstTs) firstTs = e.timestamp; lastTs = e.timestamp; }
|
|
310
|
+
if (e.type === 'last-prompt' && e.lastPrompt) lastPrompt = e.lastPrompt;
|
|
311
|
+
if (e.type === 'system' && e.subtype === 'compact_boundary') pendingCompact = true;
|
|
312
|
+
if (pendingCompact && e.type === 'user') {
|
|
313
|
+
const msg = e.message || {};
|
|
314
|
+
const ct = msg.content || [];
|
|
315
|
+
let text = '';
|
|
316
|
+
if (Array.isArray(ct)) { for (const b of ct) { if (b && b.type === 'text') { text = b.text; break; } } }
|
|
317
|
+
else if (typeof ct === 'string') text = ct;
|
|
318
|
+
const m = text.match(/Summary:\s*([\s\S]+)/);
|
|
319
|
+
if (m) summaries.push({ ts: e.timestamp, text: m[1].trim() });
|
|
320
|
+
pendingCompact = false;
|
|
321
|
+
}
|
|
322
|
+
if (e.type === 'system' && e.subtype === 'turn_duration') {
|
|
323
|
+
totalDurationMs += e.durationMs || 0;
|
|
324
|
+
if ((e.messageCount || 0) > totalMessages) totalMessages = e.messageCount;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
} catch {}
|
|
328
|
+
sessions.push({ id, mtime, firstTs, lastTs, lastPrompt, summaries, totalDurationMs, totalMessages });
|
|
329
|
+
}
|
|
330
|
+
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-cache' });
|
|
331
|
+
res.end(JSON.stringify({ sessions }));
|
|
332
|
+
} catch (err) {
|
|
333
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
334
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
335
|
+
}
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
280
339
|
// ------------------------------------------------------- GET /api/palace
|
|
281
340
|
if (req.method === 'GET' && url === '/api/palace') {
|
|
282
341
|
try {
|
|
@@ -416,6 +475,47 @@ export async function startServer({ port = 4242, projectDir, openBrowser = true
|
|
|
416
475
|
return;
|
|
417
476
|
}
|
|
418
477
|
|
|
478
|
+
// ---------------------------------------------------------- GET /api/loops
|
|
479
|
+
if (req.method === 'GET' && url === '/api/loops') {
|
|
480
|
+
try {
|
|
481
|
+
const loopsDir = path.join(projectDir || process.cwd(), '.monomind', 'loops');
|
|
482
|
+
let loops = [];
|
|
483
|
+
try {
|
|
484
|
+
const files = fs.readdirSync(loopsDir).filter(f => f.endsWith('.json'));
|
|
485
|
+
const stopFiles = new Set(fs.readdirSync(loopsDir).filter(f => f.endsWith('.stop')).map(f => f.replace('.stop', '')));
|
|
486
|
+
for (const file of files) {
|
|
487
|
+
try {
|
|
488
|
+
const data = JSON.parse(fs.readFileSync(path.join(loopsDir, file), 'utf-8'));
|
|
489
|
+
data.stopRequested = stopFiles.has(data.id);
|
|
490
|
+
loops.push(data);
|
|
491
|
+
} catch {}
|
|
492
|
+
}
|
|
493
|
+
} catch (e) { if (e.code !== 'ENOENT') throw e; }
|
|
494
|
+
loops.sort((a, b) => (b.startedAt || 0) - (a.startedAt || 0));
|
|
495
|
+
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-cache' });
|
|
496
|
+
res.end(JSON.stringify({ loops }));
|
|
497
|
+
} catch (err) { res.writeHead(500); res.end(JSON.stringify({ error: err.message })); }
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// ---------------------------------------------------------- POST /api/loops/stop
|
|
502
|
+
if (req.method === 'POST' && url === '/api/loops/stop') {
|
|
503
|
+
let body = '';
|
|
504
|
+
req.on('data', chunk => { body += chunk; });
|
|
505
|
+
req.on('end', () => {
|
|
506
|
+
try {
|
|
507
|
+
const { id } = JSON.parse(body);
|
|
508
|
+
if (!id) { res.writeHead(400); res.end(JSON.stringify({ error: 'id required' })); return; }
|
|
509
|
+
const loopsDir = path.join(projectDir || process.cwd(), '.monomind', 'loops');
|
|
510
|
+
fs.mkdirSync(loopsDir, { recursive: true });
|
|
511
|
+
fs.writeFileSync(path.join(loopsDir, `${id}.stop`), `stop-requested-${Date.now()}`);
|
|
512
|
+
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
|
|
513
|
+
res.end(JSON.stringify({ ok: true }));
|
|
514
|
+
} catch (err) { res.writeHead(500); res.end(JSON.stringify({ error: err.message })); }
|
|
515
|
+
});
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
|
|
419
519
|
// ------------------------------------------------------- DELETE /api/knowledge-chunk
|
|
420
520
|
if (req.method === 'DELETE' && url === '/api/knowledge-chunk') {
|
|
421
521
|
let body = '';
|
|
@@ -726,6 +826,71 @@ export async function startServer({ port = 4242, projectDir, openBrowser = true
|
|
|
726
826
|
return;
|
|
727
827
|
}
|
|
728
828
|
|
|
829
|
+
// ------------------------------------------------- GET /api/swarm-history
|
|
830
|
+
if (req.method === 'GET' && url === '/api/swarm-history') {
|
|
831
|
+
try {
|
|
832
|
+
const qs = new URL(req.url, 'http://localhost').searchParams;
|
|
833
|
+
const dir = qs.get('dir') || projectDir || process.cwd();
|
|
834
|
+
const entries = collectSwarmHistory(path.resolve(dir));
|
|
835
|
+
res.writeHead(200, {
|
|
836
|
+
'Content-Type': 'application/json',
|
|
837
|
+
'Access-Control-Allow-Origin': '*',
|
|
838
|
+
'Cache-Control': 'no-cache',
|
|
839
|
+
});
|
|
840
|
+
res.end(JSON.stringify({ entries }));
|
|
841
|
+
} catch (err) {
|
|
842
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
843
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
844
|
+
}
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// ------------------------------------------------- GET /api/swarm-events
|
|
849
|
+
if (req.method === 'GET' && url === '/api/swarm-events') {
|
|
850
|
+
try {
|
|
851
|
+
const qs = new URL(req.url, 'http://localhost').searchParams;
|
|
852
|
+
const dir = qs.get('dir') || projectDir || process.cwd();
|
|
853
|
+
const swarmId = qs.get('swarmId') || undefined;
|
|
854
|
+
const agentId = qs.get('agentId') || undefined;
|
|
855
|
+
const last = qs.get('last') ? parseInt(qs.get('last')) : undefined;
|
|
856
|
+
const events = collectSwarmEvents(path.resolve(dir), { swarmId, agentId, last });
|
|
857
|
+
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-cache' });
|
|
858
|
+
res.end(JSON.stringify({ events, count: events.length }));
|
|
859
|
+
} catch (err) {
|
|
860
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
861
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
862
|
+
}
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// ------------------------------------------------- GET /api/swarm-data-size
|
|
867
|
+
if (req.method === 'GET' && url === '/api/swarm-data-size') {
|
|
868
|
+
try {
|
|
869
|
+
const dir = new URL(req.url, 'http://localhost').searchParams.get('dir') || projectDir || process.cwd();
|
|
870
|
+
const size = getSwarmDataSize(path.resolve(dir));
|
|
871
|
+
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
|
|
872
|
+
res.end(JSON.stringify(size));
|
|
873
|
+
} catch (err) {
|
|
874
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
875
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
876
|
+
}
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// ------------------------------------------------- DELETE /api/swarm-clean
|
|
881
|
+
if (req.method === 'DELETE' && url === '/api/swarm-clean') {
|
|
882
|
+
try {
|
|
883
|
+
const dir = new URL(req.url, 'http://localhost').searchParams.get('dir') || projectDir || process.cwd();
|
|
884
|
+
const result = cleanSwarmData(path.resolve(dir));
|
|
885
|
+
res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
|
|
886
|
+
res.end(JSON.stringify({ success: true, ...result }));
|
|
887
|
+
} catch (err) {
|
|
888
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
889
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
890
|
+
}
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
|
|
729
894
|
// ------------------------------------------------------- GET /api/section
|
|
730
895
|
if (req.method === 'GET' && url === '/api/section') {
|
|
731
896
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monoes/monomindcli",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|