MCPcopy Create free account
hub / github.com/garrytan/gstack / formatSnapshotText

Function formatSnapshotText

browse/src/memory-command.ts:37–101  ·  view source on GitHub ↗

* Pretty-print the snapshot for terminal output. JSON mode (--json) goes * straight through JSON.stringify so the extension footer and any test * harness can consume it programmatically.

(s: MemorySnapshot)

Source from the content-addressed store, hash-verified

35 * harness can consume it programmatically.
36 */
37function formatSnapshotText(s: MemorySnapshot): string {
38 const lines: string[] = [];
39 lines.push(
40 `Bun server: RSS: ${formatBytes(s.bunServer.rss)} ` +
41 `heap: ${formatBytes(s.bunServer.heapUsed)} / ${formatBytes(s.bunServer.heapTotal)} ` +
42 `external: ${formatBytes(s.bunServer.external)}`,
43 );
44
45 if (s.processes && s.processes.length > 0) {
46 // Group by type so the user sees "renderer: 12" vs listing 12 separate rows.
47 const byType: Record<string, number> = {};
48 for (const p of s.processes) byType[p.type] = (byType[p.type] ?? 0) + 1;
49 const typeSummary = Object.entries(byType)
50 .map(([t, n]) => `${t}=${n}`)
51 .join(' ');
52 lines.push(`Chromium processes: ${s.processes.length} total (${typeSummary})`);
53 } else if (s.processes === null) {
54 lines.push('Chromium processes: (unavailable — see notes)');
55 } else {
56 lines.push('Chromium processes: 0');
57 }
58
59 if (s.tabs.length > 0) {
60 // Sort by JS heap descending; show top 10 plus "...N more" tail.
61 const sorted = [...s.tabs].sort((a, b) => b.jsHeapUsed - a.jsHeapUsed);
62 const shown = sorted.slice(0, 10);
63 lines.push(`Renderers: ${s.tabs.length} tabs (top by JS heap):`);
64 for (const t of shown) {
65 const urlShort = t.url.length > 80 ? t.url.slice(0, 77) + '...' : t.url;
66 lines.push(
67 ` [${formatBytes(t.jsHeapUsed).padStart(8)} JS, ` +
68 `${String(t.nodes).padStart(6)} nodes, ` +
69 `${String(t.listeners).padStart(5)} listeners] ` +
70 `tab #${t.id} — ${urlShort}`,
71 );
72 }
73 if (sorted.length > shown.length) {
74 lines.push(` ...and ${sorted.length - shown.length} more`);
75 }
76 } else {
77 lines.push('Renderers: (no tabs tracked)');
78 }
79
80 lines.push('─────────────────────────────────────────────────');
81 lines.push('In-memory structures (Bun side):');
82 const m = s.structures.modificationHistory;
83 lines.push(
84 ` modificationHistory: ${m.current} / ${m.cap} entries` +
85 (m.evicted > 0 ? ` (${m.evicted} evicted since reset)` : ''),
86 );
87 lines.push(` inspectorSubscribers: ${s.structures.inspectorSubscribers}`);
88 lines.push(` activitySubscribers: ${s.structures.activitySubscribers}`);
89 lines.push(` consoleBuffer: ${s.structures.consoleBufferLen} entries`);
90 lines.push(` networkBuffer: ${s.structures.networkBufferLen} entries`);
91 lines.push(` dialogBuffer: ${s.structures.dialogBufferLen} entries`);
92 lines.push(` captureBuffer: ${formatBytes(s.structures.captureBufferBytes)}`);
93
94 if (s.notes.length > 0) {

Callers 1

handleMemoryCommandFunction · 0.85

Calls 2

formatBytesFunction · 0.90
pushMethod · 0.45

Tested by

no test coverage detected