@monoes/monomindcli 1.10.37 → 1.10.39

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.
Files changed (57) hide show
  1. package/.claude/helpers/context-persistence-hook.mjs +1 -1
  2. package/.claude/helpers/utils/telemetry.cjs +1 -0
  3. package/dist/src/browser/actions.d.ts +1 -0
  4. package/dist/src/browser/actions.d.ts.map +1 -1
  5. package/dist/src/browser/actions.js +12 -5
  6. package/dist/src/browser/actions.js.map +1 -1
  7. package/dist/src/browser/batch.d.ts +0 -6
  8. package/dist/src/browser/batch.d.ts.map +1 -1
  9. package/dist/src/browser/batch.js.map +1 -1
  10. package/dist/src/browser/browser.d.ts.map +1 -1
  11. package/dist/src/browser/browser.js +37 -20
  12. package/dist/src/browser/browser.js.map +1 -1
  13. package/dist/src/browser/cdp.d.ts +1 -0
  14. package/dist/src/browser/cdp.d.ts.map +1 -1
  15. package/dist/src/browser/cdp.js +14 -4
  16. package/dist/src/browser/cdp.js.map +1 -1
  17. package/dist/src/browser/console-log.d.ts +4 -4
  18. package/dist/src/browser/console-log.d.ts.map +1 -1
  19. package/dist/src/browser/console-log.js +49 -16
  20. package/dist/src/browser/console-log.js.map +1 -1
  21. package/dist/src/browser/dialog.d.ts +2 -1
  22. package/dist/src/browser/dialog.d.ts.map +1 -1
  23. package/dist/src/browser/dialog.js +24 -10
  24. package/dist/src/browser/dialog.js.map +1 -1
  25. package/dist/src/browser/find.d.ts +1 -1
  26. package/dist/src/browser/find.d.ts.map +1 -1
  27. package/dist/src/browser/find.js +29 -10
  28. package/dist/src/browser/find.js.map +1 -1
  29. package/dist/src/browser/har.d.ts.map +1 -1
  30. package/dist/src/browser/har.js +3 -3
  31. package/dist/src/browser/har.js.map +1 -1
  32. package/dist/src/browser/network.d.ts +2 -0
  33. package/dist/src/browser/network.d.ts.map +1 -1
  34. package/dist/src/browser/network.js +64 -23
  35. package/dist/src/browser/network.js.map +1 -1
  36. package/dist/src/browser/profiler.d.ts.map +1 -1
  37. package/dist/src/browser/profiler.js +25 -15
  38. package/dist/src/browser/profiler.js.map +1 -1
  39. package/dist/src/browser/record.d.ts.map +1 -1
  40. package/dist/src/browser/record.js +7 -3
  41. package/dist/src/browser/record.js.map +1 -1
  42. package/dist/src/browser/session.d.ts.map +1 -1
  43. package/dist/src/browser/session.js +11 -7
  44. package/dist/src/browser/session.js.map +1 -1
  45. package/dist/src/browser/snapshot.js.map +1 -1
  46. package/dist/src/browser/trace.d.ts.map +1 -1
  47. package/dist/src/browser/trace.js +32 -17
  48. package/dist/src/browser/trace.js.map +1 -1
  49. package/dist/src/browser/wait.js +28 -14
  50. package/dist/src/browser/wait.js.map +1 -1
  51. package/dist/src/commands/browse.d.ts.map +1 -1
  52. package/dist/src/commands/browse.js +8 -14
  53. package/dist/src/commands/browse.js.map +1 -1
  54. package/dist/src/ui/dashboard-v2.html +563 -5
  55. package/dist/src/ui/server.mjs +140 -2
  56. package/dist/tsconfig.tsbuildinfo +1 -1
  57. package/package.json +1 -1
@@ -372,6 +372,7 @@ export async function startServer({ port = 4242, projectDir, openBrowser = true
372
372
  const id = f.replace('.jsonl', '');
373
373
  let lastPrompt = '', summaries = [], totalDurationMs = 0, totalMessages = 0, firstTs = null, lastTs = null, totalCost = 0, toolCalls = 0, userMessages = 0, cacheReadTokens = 0, totalInputTokens = 0;
374
374
  const modelBreakdown = {};
375
+ const filesTouchedSet = new Set();
375
376
  try {
376
377
  const lines = fs.readFileSync(fp, 'utf8').split('\n').filter(Boolean);
377
378
  let pendingCompact = false;
@@ -394,7 +395,12 @@ export async function startServer({ port = 4242, projectDir, openBrowser = true
394
395
  if (e.type === 'assistant') {
395
396
  const msg = e.message || {};
396
397
  for (const block of (msg.content || [])) {
397
- if (block && block.type === 'tool_use') toolCalls++;
398
+ if (block && block.type === 'tool_use') {
399
+ toolCalls++;
400
+ if (['Write','Edit','Read','MultiEdit'].includes(block.name) && block.input?.file_path) {
401
+ filesTouchedSet.add(path.basename(block.input.file_path));
402
+ }
403
+ }
398
404
  }
399
405
  if (msg.usage && msg.model) {
400
406
  const c = _sjCalcCost(msg.model, msg.usage);
@@ -415,7 +421,8 @@ export async function startServer({ port = 4242, projectDir, openBrowser = true
415
421
  }
416
422
  }
417
423
  } catch {}
418
- sessions.push({ id, mtime, firstTs, lastTs, lastPrompt, summaries, totalDurationMs, totalMessages, totalCost, toolCalls, userMessages, cacheReadTokens, totalInputTokens, modelBreakdown, file: fp });
424
+ const filesTouched = [...filesTouchedSet].slice(0, 20);
425
+ sessions.push({ id, mtime, firstTs, lastTs, lastPrompt, summaries, totalDurationMs, totalMessages, totalCost, toolCalls, userMessages, cacheReadTokens, totalInputTokens, modelBreakdown, filesTouched, file: fp });
419
426
  }
420
427
  res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-cache' });
421
428
  res.end(JSON.stringify({ sessions }));
@@ -534,6 +541,92 @@ export async function startServer({ port = 4242, projectDir, openBrowser = true
534
541
  return;
535
542
  }
536
543
 
544
+ // ------------------------------------------------------- GET /api/tool-ranking
545
+ if (req.method === 'GET' && url === '/api/tool-ranking') {
546
+ try {
547
+ const qs = new URL(req.url, 'http://localhost').searchParams;
548
+ const dir = qs.get('dir') || projectDir || process.cwd();
549
+ const d = path.resolve(dir || process.cwd());
550
+ const slug = d.replace(/\//g, '-');
551
+ const projectClaudeDir = path.join(os.homedir(), '.claude', 'projects', slug);
552
+ let sessionFiles = [];
553
+ try {
554
+ sessionFiles = fs.readdirSync(projectClaudeDir)
555
+ .filter(f => f.endsWith('.jsonl'))
556
+ .map(f => { try { return { f, mtime: fs.statSync(path.join(projectClaudeDir, f)).mtimeMs }; } catch { return null; } })
557
+ .filter(Boolean).sort((a,b) => b.mtime - a.mtime).slice(0, 30);
558
+ } catch {}
559
+ const toolCounts = {}, errorCounts = {};
560
+ for (const { f } of sessionFiles) {
561
+ const fp = path.join(projectClaudeDir, f);
562
+ try {
563
+ const lines = fs.readFileSync(fp, 'utf8').split('\n').filter(Boolean);
564
+ const toolIdMap = {};
565
+ for (const line of lines) {
566
+ let e; try { e = JSON.parse(line); } catch { continue; }
567
+ if (e.type === 'assistant') {
568
+ for (const b of (e.message?.content || [])) {
569
+ if (b && b.type === 'tool_use') { toolIdMap[b.id] = b.name; toolCounts[b.name] = (toolCounts[b.name] || 0) + 1; }
570
+ }
571
+ }
572
+ if (e.type === 'user') {
573
+ for (const b of (e.message?.content || [])) {
574
+ if (b && b.type === 'tool_result' && b.is_error) {
575
+ const name = toolIdMap[b.tool_use_id] || '?';
576
+ errorCounts[name] = (errorCounts[name] || 0) + 1;
577
+ }
578
+ }
579
+ }
580
+ }
581
+ } catch {}
582
+ }
583
+ const tools = Object.entries(toolCounts)
584
+ .map(([tool, count]) => ({ tool, count, errors: errorCounts[tool] || 0 }))
585
+ .sort((a,b) => b.count - a.count);
586
+ res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-cache' });
587
+ res.end(JSON.stringify({ tools }));
588
+ } catch (err) {
589
+ res.writeHead(500, { 'Content-Type': 'application/json' });
590
+ res.end(JSON.stringify({ error: err.message }));
591
+ }
592
+ return;
593
+ }
594
+
595
+ // ------------------------------------------------------- GET /api/project-costs
596
+ if (req.method === 'GET' && url === '/api/project-costs') {
597
+ try {
598
+ const projectsBase = path.join(os.homedir(), '.claude', 'projects');
599
+ let slugDirs = [];
600
+ try { slugDirs = fs.readdirSync(projectsBase, { withFileTypes: true }).filter(e => e.isDirectory()).map(e => e.name); } catch {}
601
+ const projectCosts = [];
602
+ for (const slug of slugDirs) {
603
+ const projDir = path.join(projectsBase, slug);
604
+ const projPath = '/' + slug.replace(/^-/, '').replace(/-/g, '/');
605
+ let sessionFiles = [];
606
+ try { sessionFiles = fs.readdirSync(projDir).filter(f => f.endsWith('.jsonl')).map(f => path.join(projDir, f)); } catch {}
607
+ if (!sessionFiles.length) continue;
608
+ let totalCost = 0;
609
+ for (const fp of sessionFiles) {
610
+ try {
611
+ const lines = fs.readFileSync(fp, 'utf8').split('\n').filter(Boolean);
612
+ for (const line of lines) {
613
+ let e; try { e = JSON.parse(line); } catch { continue; }
614
+ if (e.type === 'assistant' && e.message?.usage) { totalCost += _sjCalcCost(e.message.model || '', e.message.usage); }
615
+ }
616
+ } catch {}
617
+ }
618
+ if (totalCost > 0) projectCosts.push({ path: projPath, cost: totalCost, sessions: sessionFiles.length });
619
+ }
620
+ projectCosts.sort((a, b) => b.cost - a.cost);
621
+ res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', 'Cache-Control': 'no-cache' });
622
+ res.end(JSON.stringify({ projects: projectCosts }));
623
+ } catch (err) {
624
+ res.writeHead(500, { 'Content-Type': 'application/json' });
625
+ res.end(JSON.stringify({ error: err.message }));
626
+ }
627
+ return;
628
+ }
629
+
537
630
  // ------------------------------------------------------- GET /api/projects
538
631
  if (req.method === 'GET' && url === '/api/projects') {
539
632
  try {
@@ -892,6 +985,51 @@ export async function startServer({ port = 4242, projectDir, openBrowser = true
892
985
  return;
893
986
  }
894
987
 
988
+ // ---------------------------------------------------------- POST /api/loops/create
989
+ if (req.method === 'POST' && url === '/api/loops/create') {
990
+ let body = '';
991
+ req.on('data', chunk => { body += chunk; });
992
+ req.on('end', () => {
993
+ try {
994
+ const { name, prompt, interval, maxReps } = JSON.parse(body);
995
+ if (!prompt) { res.writeHead(400); res.end(JSON.stringify({ error: 'prompt required' })); return; }
996
+ const loopsDir = path.join(projectDir || process.cwd(), '.monomind', 'loops');
997
+ fs.mkdirSync(loopsDir, { recursive: true });
998
+ const id = `loop-${Date.now()}-${Math.random().toString(36).slice(2,7)}`;
999
+ const loop = { id, name: name || prompt.slice(0, 40), prompt, interval: interval || '1h', maxReps: maxReps || null, status: 'active', currentRep: 0, startedAt: new Date().toISOString(), lastRunAt: null };
1000
+ fs.writeFileSync(path.join(loopsDir, `${id}.json`), JSON.stringify(loop, null, 2));
1001
+ res.writeHead(200, { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*' });
1002
+ res.end(JSON.stringify({ ok: true, id }));
1003
+ } catch (err) { res.writeHead(500); res.end(JSON.stringify({ error: err.message })); }
1004
+ });
1005
+ return;
1006
+ }
1007
+
1008
+ // ---------------------------------------------------------- GET /api/events-stream (SSE)
1009
+ if (req.method === 'GET' && url.startsWith('/api/events-stream')) {
1010
+ const qs = new URL(req.url, 'http://localhost').searchParams;
1011
+ const d = path.resolve(qs.get('dir') || projectDir || process.cwd());
1012
+ const slug = d.replace(/\//g, '-');
1013
+ const projectClaudeDir = path.join(os.homedir(), '.claude', 'projects', slug);
1014
+ res.writeHead(200, {
1015
+ 'Content-Type': 'text/event-stream',
1016
+ 'Cache-Control': 'no-cache',
1017
+ 'Connection': 'keep-alive',
1018
+ 'Access-Control-Allow-Origin': '*',
1019
+ });
1020
+ const send = (ev, data) => { try { res.write(`event: ${ev}\ndata: ${JSON.stringify(data)}\n\n`); } catch {} };
1021
+ send('connected', { ts: Date.now() });
1022
+ let watcher = null;
1023
+ try {
1024
+ watcher = fs.watch(projectClaudeDir, { persistent: false }, (evtype) => {
1025
+ if (evtype === 'change' || evtype === 'rename') send('update', { ts: Date.now() });
1026
+ });
1027
+ } catch {}
1028
+ const pingInterval = setInterval(() => { try { res.write(': ping\n\n'); } catch {} }, 20000);
1029
+ req.on('close', () => { clearInterval(pingInterval); try { watcher?.close(); } catch {} });
1030
+ return;
1031
+ }
1032
+
895
1033
  // ------------------------------------------------------- DELETE /api/knowledge-chunk
896
1034
  if (req.method === 'DELETE' && url === '/api/knowledge-chunk') {
897
1035
  let body = '';