@memlab/mcp-server 2.3.0 → 2.52.0
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/README.md +18 -14
- package/bin/.eslintrc.js +26 -0
- package/bin/memlab-cli.js +313 -0
- package/dist/artifact-classes.d.ts +86 -0
- package/dist/artifact-classes.d.ts.map +1 -0
- package/dist/artifact-classes.js +261 -0
- package/dist/artifact-classes.js.map +1 -0
- package/dist/capture-mode.d.ts +60 -0
- package/dist/capture-mode.d.ts.map +1 -0
- package/dist/capture-mode.js +39 -0
- package/dist/capture-mode.js.map +1 -0
- package/dist/guardrail.d.ts.map +1 -1
- package/dist/guardrail.js +13 -0
- package/dist/guardrail.js.map +1 -1
- package/dist/heap-state.d.ts +96 -2
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +197 -2
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +41 -1
- package/dist/index.js.map +1 -1
- package/dist/progress.d.ts +25 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +46 -0
- package/dist/progress.js.map +1 -0
- package/dist/result-handles.d.ts +11 -0
- package/dist/result-handles.d.ts.map +1 -0
- package/dist/result-handles.js +77 -0
- package/dist/result-handles.js.map +1 -0
- package/dist/string-index.d.ts +55 -0
- package/dist/string-index.d.ts.map +1 -0
- package/dist/string-index.js +91 -0
- package/dist/string-index.js.map +1 -0
- package/dist/tool-registry.d.ts +42 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +20 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/analyze-run.d.ts +12 -0
- package/dist/tools/analyze-run.d.ts.map +1 -0
- package/dist/tools/analyze-run.js +343 -0
- package/dist/tools/analyze-run.js.map +1 -0
- package/dist/tools/app-heap.d.ts +12 -0
- package/dist/tools/app-heap.d.ts.map +1 -0
- package/dist/tools/app-heap.js +140 -0
- package/dist/tools/app-heap.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +91 -49
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/batch.d.ts +12 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +168 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +156 -5
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/class-histogram.d.ts.map +1 -1
- package/dist/tools/class-histogram.js +14 -3
- package/dist/tools/class-histogram.js.map +1 -1
- package/dist/tools/collection-trend.d.ts +55 -0
- package/dist/tools/collection-trend.d.ts.map +1 -0
- package/dist/tools/collection-trend.js +315 -0
- package/dist/tools/collection-trend.js.map +1 -0
- package/dist/tools/detached-dom.d.ts +2 -0
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +291 -20
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts +62 -6
- package/dist/tools/dev-artifacts.d.ts.map +1 -1
- package/dist/tools/dev-artifacts.js +466 -23
- package/dist/tools/dev-artifacts.js.map +1 -1
- package/dist/tools/diff-snapshots.d.ts.map +1 -1
- package/dist/tools/diff-snapshots.js +101 -44
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/dominator-attribution.d.ts +12 -0
- package/dist/tools/dominator-attribution.d.ts.map +1 -0
- package/dist/tools/dominator-attribution.js +189 -0
- package/dist/tools/dominator-attribution.js.map +1 -0
- package/dist/tools/dominator-chain.d.ts +12 -0
- package/dist/tools/dominator-chain.d.ts.map +1 -0
- package/dist/tools/dominator-chain.js +92 -0
- package/dist/tools/dominator-chain.js.map +1 -0
- package/dist/tools/duplicate-objects.d.ts +12 -0
- package/dist/tools/duplicate-objects.d.ts.map +1 -0
- package/dist/tools/duplicate-objects.js +172 -0
- package/dist/tools/duplicate-objects.js.map +1 -0
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +46 -38
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval.d.ts +1 -0
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +787 -30
- package/dist/tools/eval.js.map +1 -1
- package/dist/tools/explain-delta.d.ts +12 -0
- package/dist/tools/explain-delta.d.ts.map +1 -0
- package/dist/tools/explain-delta.js +170 -0
- package/dist/tools/explain-delta.js.map +1 -0
- package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
- package/dist/tools/find-nodes-by-class.js +112 -13
- package/dist/tools/find-nodes-by-class.js.map +1 -1
- package/dist/tools/finding-index.d.ts +22 -0
- package/dist/tools/finding-index.d.ts.map +1 -0
- package/dist/tools/finding-index.js +247 -0
- package/dist/tools/finding-index.js.map +1 -0
- package/dist/tools/for-each.d.ts.map +1 -1
- package/dist/tools/for-each.js +15 -3
- package/dist/tools/for-each.js.map +1 -1
- package/dist/tools/get-references.d.ts.map +1 -1
- package/dist/tools/get-references.js +35 -6
- package/dist/tools/get-references.js.map +1 -1
- package/dist/tools/get-referrers.d.ts.map +1 -1
- package/dist/tools/get-referrers.js +52 -6
- package/dist/tools/get-referrers.js.map +1 -1
- package/dist/tools/hunt-report.d.ts +12 -0
- package/dist/tools/hunt-report.d.ts.map +1 -0
- package/dist/tools/hunt-report.js +186 -0
- package/dist/tools/hunt-report.js.map +1 -0
- package/dist/tools/hypothesis.d.ts +12 -0
- package/dist/tools/hypothesis.d.ts.map +1 -0
- package/dist/tools/hypothesis.js +221 -0
- package/dist/tools/hypothesis.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -1
- package/dist/tools/intern-opportunities.js +721 -75
- package/dist/tools/intern-opportunities.js.map +1 -1
- package/dist/tools/ladder.d.ts +33 -0
- package/dist/tools/ladder.d.ts.map +1 -0
- package/dist/tools/ladder.js +266 -0
- package/dist/tools/ladder.js.map +1 -0
- package/dist/tools/largest-objects.d.ts.map +1 -1
- package/dist/tools/largest-objects.js +43 -16
- package/dist/tools/largest-objects.js.map +1 -1
- package/dist/tools/leak-report.d.ts +12 -0
- package/dist/tools/leak-report.d.ts.map +1 -0
- package/dist/tools/leak-report.js +256 -0
- package/dist/tools/leak-report.js.map +1 -0
- package/dist/tools/load-snapshot.d.ts +78 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +519 -29
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/map-entries.d.ts +12 -0
- package/dist/tools/map-entries.d.ts.map +1 -0
- package/dist/tools/map-entries.js +139 -0
- package/dist/tools/map-entries.js.map +1 -0
- package/dist/tools/match-object.d.ts +12 -0
- package/dist/tools/match-object.d.ts.map +1 -0
- package/dist/tools/match-object.js +165 -0
- package/dist/tools/match-object.js.map +1 -0
- package/dist/tools/object-shape.d.ts.map +1 -1
- package/dist/tools/object-shape.js +92 -30
- package/dist/tools/object-shape.js.map +1 -1
- package/dist/tools/population-diff.d.ts +57 -0
- package/dist/tools/population-diff.d.ts.map +1 -0
- package/dist/tools/population-diff.js +338 -0
- package/dist/tools/population-diff.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +12 -4
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/retainer-layers.d.ts +23 -0
- package/dist/tools/retainer-layers.d.ts.map +1 -0
- package/dist/tools/retainer-layers.js +179 -0
- package/dist/tools/retainer-layers.js.map +1 -0
- package/dist/tools/retainer-summary.d.ts +1 -0
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +128 -32
- package/dist/tools/retainer-summary.js.map +1 -1
- package/dist/tools/retainer-trace.d.ts.map +1 -1
- package/dist/tools/retainer-trace.js +105 -25
- package/dist/tools/retainer-trace.js.map +1 -1
- package/dist/tools/search-nodes.d.ts.map +1 -1
- package/dist/tools/search-nodes.js +5 -1
- package/dist/tools/search-nodes.js.map +1 -1
- package/dist/tools/search-strings.d.ts.map +1 -1
- package/dist/tools/search-strings.js +53 -7
- package/dist/tools/search-strings.js.map +1 -1
- package/dist/tools/sequence-analysis.d.ts +49 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -1
- package/dist/tools/sequence-analysis.js +268 -78
- package/dist/tools/sequence-analysis.js.map +1 -1
- package/dist/tools/shape-histogram.d.ts.map +1 -1
- package/dist/tools/shape-histogram.js +9 -2
- package/dist/tools/shape-histogram.js.map +1 -1
- package/dist/tools/sliced-strings.d.ts.map +1 -1
- package/dist/tools/sliced-strings.js +22 -4
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshot-header.d.ts +28 -0
- package/dist/tools/snapshot-header.d.ts.map +1 -0
- package/dist/tools/snapshot-header.js +111 -0
- package/dist/tools/snapshot-header.js.map +1 -0
- package/dist/tools/string-patterns.d.ts.map +1 -1
- package/dist/tools/string-patterns.js +5 -4
- package/dist/tools/string-patterns.js.map +1 -1
- package/dist/tools/tools-index.d.ts +12 -0
- package/dist/tools/tools-index.d.ts.map +1 -0
- package/dist/tools/tools-index.js +342 -0
- package/dist/tools/tools-index.js.map +1 -0
- package/dist/tools/verify-fix.d.ts +23 -0
- package/dist/tools/verify-fix.d.ts.map +1 -0
- package/dist/tools/verify-fix.js +211 -0
- package/dist/tools/verify-fix.js.map +1 -0
- package/dist/tools/weakmap-entries.d.ts.map +1 -1
- package/dist/tools/weakmap-entries.js +6 -1
- package/dist/tools/weakmap-entries.js.map +1 -1
- package/dist/utils.d.ts +204 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +478 -8
- package/dist/utils.js.map +1 -1
- package/package.json +5 -4
|
@@ -11,8 +11,12 @@ import fs from 'fs';
|
|
|
11
11
|
import { z } from 'zod';
|
|
12
12
|
import memlabHeapAnalysis from '@memlab/heap-analysis';
|
|
13
13
|
const { getFullHeapFromFile } = memlabHeapAnalysis;
|
|
14
|
-
import { resolveSnapshotPath } from './load-snapshot.js';
|
|
14
|
+
import { LOCAL_FILE_SIZE_LIMIT_MB, MANIFOLD_FETCH_SIZE_LIMIT_MB, resolveMaxFileSizeMB, resolveSnapshotPath, } from './load-snapshot.js';
|
|
15
15
|
import { formatBytes, formatNumber, markdownTable, errorResult, toolResult, } from '../utils.js';
|
|
16
|
+
import { resolveLadderPaths } from './ladder.js';
|
|
17
|
+
import { resetEmittedNotes, shouldEmitNote } from '../heap-state.js';
|
|
18
|
+
import { artifactLabel, artifactNote, classifyArtifact, } from '../artifact-classes.js';
|
|
19
|
+
import { classifyNumericCapture, SMI_NUMBER_CLASS_KEY } from '../capture-mode.js';
|
|
16
20
|
// A class key is "<type>::<name>". Value-named string "classes" (literal
|
|
17
21
|
// values used as the name, e.g. "554", "1780525701808.81", "o:10,add") are
|
|
18
22
|
// noise across a sequence — drop them like diff_snapshots does (§10).
|
|
@@ -25,6 +29,15 @@ function isNoiseClass(type, name) {
|
|
|
25
29
|
return true;
|
|
26
30
|
return false;
|
|
27
31
|
}
|
|
32
|
+
// V8 names per-instance Context/scope objects with a trailing " @<node-id>"
|
|
33
|
+
// (e.g. "system / Context / scope @706909"). Those ids differ per capture, so
|
|
34
|
+
// without normalization every scope is a distinct "class" that appears "new
|
|
35
|
+
// since baseline" and floods the report (observed: ~9,900 such keys, ~133k
|
|
36
|
+
// nodes, in a single Ads snapshot). Collapse the id so they aggregate into one
|
|
37
|
+
// comparable class across the sequence.
|
|
38
|
+
export function normalizeClassName(name) {
|
|
39
|
+
return name.replace(/ @\d+$/, ' @…');
|
|
40
|
+
}
|
|
28
41
|
function buildHistogram(snapshot) {
|
|
29
42
|
const hist = new Map();
|
|
30
43
|
let nodeCount = 0;
|
|
@@ -34,7 +47,7 @@ function buildHistogram(snapshot) {
|
|
|
34
47
|
totalSize += node.self_size;
|
|
35
48
|
if (node.id <= 3)
|
|
36
49
|
return;
|
|
37
|
-
const key = `${node.type}::${node.name}`;
|
|
50
|
+
const key = `${node.type}::${normalizeClassName(node.name)}`;
|
|
38
51
|
const e = hist.get(key);
|
|
39
52
|
if (e) {
|
|
40
53
|
e.count++;
|
|
@@ -64,12 +77,137 @@ function classifyTrend(counts) {
|
|
|
64
77
|
return 'grew-net';
|
|
65
78
|
return 'flat-or-mixed';
|
|
66
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Load an ordered ladder of snapshots and compute per-class growth trends.
|
|
82
|
+
*
|
|
83
|
+
* Extracted from the `memlab_sequence_analysis` handler so it can be composed
|
|
84
|
+
* (see `memlab_leak_report`) instead of re-implemented: the loop that loads each
|
|
85
|
+
* rung, histograms it, and drops the graph before the next is both the expensive
|
|
86
|
+
* part and the part that is easy to get subtly wrong (resolution, size guard,
|
|
87
|
+
* one-graph-resident-at-a-time).
|
|
88
|
+
*
|
|
89
|
+
* Failures THROW rather than returning an MCP error envelope — the callers are
|
|
90
|
+
* tool handlers that already wrap their body in try/catch, and a composed caller
|
|
91
|
+
* needs a failure it cannot accidentally treat as a result.
|
|
92
|
+
*/
|
|
93
|
+
export async function computeSequenceTrends(paths, opts) {
|
|
94
|
+
const toolName = opts.toolName ?? 'memlab_sequence_analysis';
|
|
95
|
+
const steps = [];
|
|
96
|
+
// `paths: ["ladder:<name>"]` expands to a saved ladder (see ladder.ts), so a
|
|
97
|
+
// six-rung trend call is one token instead of six absolute paths.
|
|
98
|
+
const { paths: resolvedPaths } = resolveLadderPaths(paths);
|
|
99
|
+
// The >=2 requirement is enforced here rather than in the schema: a ladder
|
|
100
|
+
// reference is a SINGLE array element that expands to many, so a schema-level
|
|
101
|
+
// `.min(2)` rejects `["ladder:name"]` before it can be expanded.
|
|
102
|
+
if (resolvedPaths.length < 2) {
|
|
103
|
+
throw new Error(`${toolName} needs at least 2 snapshots; got ${resolvedPaths.length}. ` +
|
|
104
|
+
(paths.length === 1 && paths[0].startsWith('ladder:')
|
|
105
|
+
? 'That ladder has fewer than 2 rungs — check it with memlab_ladder({action:"show"}).'
|
|
106
|
+
: 'Pass an ordered list of paths, or a single ["ladder:<name>"] reference.'));
|
|
107
|
+
}
|
|
108
|
+
for (const p of resolvedPaths) {
|
|
109
|
+
let local;
|
|
110
|
+
let fetchedFrom = null;
|
|
111
|
+
try {
|
|
112
|
+
const r = resolveSnapshotPath(p);
|
|
113
|
+
local = r.localPath;
|
|
114
|
+
fetchedFrom = r.fetchedFrom;
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
throw new Error(`Failed to resolve "${p}": ${e instanceof Error ? e.message : String(e)}`);
|
|
118
|
+
}
|
|
119
|
+
if (!fs.existsSync(local)) {
|
|
120
|
+
throw new Error(`File not found: ${local}`);
|
|
121
|
+
}
|
|
122
|
+
const sizeMB = fs.statSync(local).size / (1024 * 1024);
|
|
123
|
+
const effectiveMaxFileSizeMB = resolveMaxFileSizeMB(opts.maxFileSizeMB, fetchedFrom != null);
|
|
124
|
+
if (sizeMB > effectiveMaxFileSizeMB) {
|
|
125
|
+
throw new Error(`${p} is ${sizeMB.toFixed(0)} MB — exceeds the ${effectiveMaxFileSizeMB} MB per-file safety limit. ` +
|
|
126
|
+
`Raise it with ${toolName}({max_file_size_mb: ${Math.ceil(sizeMB + 100)}}), ` +
|
|
127
|
+
`or restart the MCP server with more memory (NODE_OPTIONS="--max-old-space-size=8192") if it isn't already provisioned.`);
|
|
128
|
+
}
|
|
129
|
+
// Load sequentially and drop the graph before the next one so only
|
|
130
|
+
// one full graph is resident at a time (memory-safe for big heaps).
|
|
131
|
+
const snapshot = await getFullHeapFromFile(local);
|
|
132
|
+
const { hist, nodeCount, totalSize } = buildHistogram(snapshot);
|
|
133
|
+
steps.push({
|
|
134
|
+
label: fetchedFrom ?? p.replace(/^.*\//, ''),
|
|
135
|
+
localPath: local,
|
|
136
|
+
hist,
|
|
137
|
+
nodeCount,
|
|
138
|
+
totalSize,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const n = steps.length;
|
|
142
|
+
// Union of non-noise class keys.
|
|
143
|
+
const keys = new Set();
|
|
144
|
+
for (const s of steps) {
|
|
145
|
+
for (const k of s.hist.keys()) {
|
|
146
|
+
const sep = k.indexOf('::');
|
|
147
|
+
const type = k.slice(0, sep);
|
|
148
|
+
const name = k.slice(sep + 2);
|
|
149
|
+
if (!isNoiseClass(type, name))
|
|
150
|
+
keys.add(k);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const rows = [];
|
|
154
|
+
for (const k of keys) {
|
|
155
|
+
const counts = steps.map(s => s.hist.get(k)?.count ?? 0);
|
|
156
|
+
const sizes = steps.map(s => s.hist.get(k)?.selfSize ?? 0);
|
|
157
|
+
const netCount = counts[n - 1] - counts[0];
|
|
158
|
+
const netSize = sizes[n - 1] - sizes[0];
|
|
159
|
+
if (netCount < opts.minGrowthCount)
|
|
160
|
+
continue;
|
|
161
|
+
const trend = classifyTrend(counts);
|
|
162
|
+
if (opts.monotonicOnly && trend !== 'monotonic-up')
|
|
163
|
+
continue;
|
|
164
|
+
if (trend !== 'monotonic-up' && trend !== 'grew-net')
|
|
165
|
+
continue;
|
|
166
|
+
const sep = k.indexOf('::');
|
|
167
|
+
const name = k.slice(sep + 2);
|
|
168
|
+
rows.push({
|
|
169
|
+
key: k,
|
|
170
|
+
type: k.slice(0, sep),
|
|
171
|
+
name,
|
|
172
|
+
counts,
|
|
173
|
+
netCount,
|
|
174
|
+
netSize,
|
|
175
|
+
trend,
|
|
176
|
+
artifact: classifyArtifact(name),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
// Real growers first: genuine classes ahead of known artifacts, then
|
|
180
|
+
// monotonic ahead of noisy, then by net size delta.
|
|
181
|
+
rows.sort((a, b) => {
|
|
182
|
+
const aArt = a.artifact != null;
|
|
183
|
+
const bArt = b.artifact != null;
|
|
184
|
+
if (aArt !== bArt)
|
|
185
|
+
return aArt ? 1 : -1;
|
|
186
|
+
if (a.trend !== b.trend)
|
|
187
|
+
return a.trend === 'monotonic-up' ? -1 : 1;
|
|
188
|
+
return b.netSize - a.netSize;
|
|
189
|
+
});
|
|
190
|
+
return { steps, rows, keys };
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Artifact-family explanations are long and identical on every call. Print the
|
|
194
|
+
* full note once per session and a one-line pointer afterwards; the COUNTS that
|
|
195
|
+
* accompany it are per-call data and are always shown by the caller.
|
|
196
|
+
*/
|
|
197
|
+
function pushArtifactNote(lines, kind) {
|
|
198
|
+
if (shouldEmitNote(`artifact:${kind}`)) {
|
|
199
|
+
lines.push('', `> ${artifactNote(kind)}`);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
lines.push('', `> ${artifactLabel(kind)} — explained earlier this session.`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
67
205
|
export function registerSequenceAnalysis(server) {
|
|
68
206
|
server.tool('memlab_sequence_analysis', 'Trend analysis across an ORDERED sequence of >=2 heap snapshots (the canonical "is anything growing unboundedly?" tool). Loads each snapshot transiently (does NOT change your active snapshot), builds per-class histograms, and reports each class\'s value at every step plus a growth verdict: "monotonic-up" (grew every step — strongest leak signal) vs "grew-net" (grew overall but not every step — often GC/navigation noise) vs flat/shrank. Also lists classes new since the baseline. Paths may be local, manifold:// URLs, or bare filenames.', {
|
|
69
207
|
paths: z
|
|
70
208
|
.array(z.string())
|
|
71
|
-
.min(
|
|
72
|
-
.describe('Ordered list of >=2 snapshot paths (oldest first)
|
|
209
|
+
.min(1)
|
|
210
|
+
.describe('Ordered list of >=2 snapshot paths (oldest first): local absolute paths, manifold:// URLs, or bare snapshot filenames. A single ["ladder:<name>"] entry expands to a ladder saved with memlab_ladder.'),
|
|
73
211
|
limit: z
|
|
74
212
|
.number()
|
|
75
213
|
.optional()
|
|
@@ -85,79 +223,45 @@ export function registerSequenceAnalysis(server) {
|
|
|
85
223
|
.optional()
|
|
86
224
|
.default(false)
|
|
87
225
|
.describe('Report only classes that grew at EVERY step (default false: include grew-net too, flagged).'),
|
|
226
|
+
cycles: z
|
|
227
|
+
.number()
|
|
228
|
+
.optional()
|
|
229
|
+
.describe('Number of interaction cycles driven between the FIRST and LAST snapshot. When provided, a "Δ/cycle" column is reported. A per-cycle rate — not a total — is what tells you whether growth scales with interaction, and it is the number a leak hunt actually reasons about.'),
|
|
230
|
+
include_artifacts: z
|
|
231
|
+
.boolean()
|
|
232
|
+
.optional()
|
|
233
|
+
.default(false)
|
|
234
|
+
.describe('Include classes that are known measurement artifacts (CDP inspector network/performance/console retention, V8 JIT warmup, Blink a11y caches, captured Error stacks). Default false: they are collapsed into a one-line summary instead of filling the table, because in practice they dominate the top of the list and none of them is an app leak.'),
|
|
235
|
+
repeat_notes: z
|
|
236
|
+
.boolean()
|
|
237
|
+
.optional()
|
|
238
|
+
.default(false)
|
|
239
|
+
.describe('Re-print the standing explanatory notes (artifact-family write-ups, capture-mode caveats, the "candidate, not verdict" paragraph) that are otherwise emitted once per server session. The per-call DATA — which classes grew, how many artifacts were suppressed — is always shown; only the unchanging prose is deduplicated.'),
|
|
88
240
|
max_file_size_mb: z
|
|
89
241
|
.number()
|
|
90
242
|
.optional()
|
|
91
|
-
.
|
|
92
|
-
|
|
93
|
-
}, async ({ paths, limit, min_growth_count, monotonic_only, max_file_size_mb, }) => {
|
|
243
|
+
.describe(`Per-file size ceiling in MB to avoid OOM. Matches memlab_load_snapshot's by-source defaults — ${LOCAL_FILE_SIZE_LIMIT_MB} for local files and ${MANIFOLD_FETCH_SIZE_LIMIT_MB} for snapshots fetched from Manifold (server captures routinely exceed the local limit); pass an explicit value to override. Snapshots are loaded one at a time and dropped before the next, so a ladder of large files is safe as long as each single file is under the ceiling.`),
|
|
244
|
+
}, async ({ paths, limit, min_growth_count, monotonic_only, cycles, include_artifacts, repeat_notes, max_file_size_mb, }) => {
|
|
94
245
|
try {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
fetchedFrom = r.fetchedFrom;
|
|
103
|
-
}
|
|
104
|
-
catch (e) {
|
|
105
|
-
return errorResult(new Error(`Failed to resolve "${p}": ${e instanceof Error ? e.message : String(e)}`));
|
|
106
|
-
}
|
|
107
|
-
if (!fs.existsSync(local)) {
|
|
108
|
-
return errorResult(new Error(`File not found: ${local}`));
|
|
109
|
-
}
|
|
110
|
-
const sizeMB = fs.statSync(local).size / (1024 * 1024);
|
|
111
|
-
if (sizeMB > max_file_size_mb) {
|
|
112
|
-
return errorResult(new Error(`${p} is ${sizeMB.toFixed(0)} MB — exceeds max_file_size_mb (${max_file_size_mb}).`));
|
|
113
|
-
}
|
|
114
|
-
// Load sequentially and drop the graph before the next one so only
|
|
115
|
-
// one full graph is resident at a time (memory-safe for big heaps).
|
|
116
|
-
const snapshot = await getFullHeapFromFile(local);
|
|
117
|
-
const { hist, nodeCount, totalSize } = buildHistogram(snapshot);
|
|
118
|
-
steps.push({
|
|
119
|
-
label: fetchedFrom ?? p.replace(/^.*\//, ''),
|
|
120
|
-
hist,
|
|
121
|
-
nodeCount,
|
|
122
|
-
totalSize,
|
|
123
|
-
});
|
|
124
|
-
}
|
|
246
|
+
if (repeat_notes)
|
|
247
|
+
resetEmittedNotes();
|
|
248
|
+
const { steps, rows, keys } = await computeSequenceTrends(paths, {
|
|
249
|
+
minGrowthCount: min_growth_count,
|
|
250
|
+
monotonicOnly: monotonic_only,
|
|
251
|
+
maxFileSizeMB: max_file_size_mb,
|
|
252
|
+
});
|
|
125
253
|
const n = steps.length;
|
|
126
254
|
const first = steps[0].hist;
|
|
127
255
|
const last = steps[n - 1].hist;
|
|
128
|
-
//
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
const rows = [];
|
|
140
|
-
for (const k of keys) {
|
|
141
|
-
const counts = steps.map(s => s.hist.get(k)?.count ?? 0);
|
|
142
|
-
const sizes = steps.map(s => s.hist.get(k)?.selfSize ?? 0);
|
|
143
|
-
const netCount = counts[n - 1] - counts[0];
|
|
144
|
-
const netSize = sizes[n - 1] - sizes[0];
|
|
145
|
-
if (netCount < min_growth_count)
|
|
146
|
-
continue;
|
|
147
|
-
const trend = classifyTrend(counts);
|
|
148
|
-
if (monotonic_only && trend !== 'monotonic-up')
|
|
149
|
-
continue;
|
|
150
|
-
if (trend !== 'monotonic-up' && trend !== 'grew-net')
|
|
151
|
-
continue;
|
|
152
|
-
rows.push({ key: k, counts, netCount, netSize, trend });
|
|
153
|
-
}
|
|
154
|
-
// Monotonic growers first, then by net size delta.
|
|
155
|
-
rows.sort((a, b) => {
|
|
156
|
-
if (a.trend !== b.trend)
|
|
157
|
-
return a.trend === 'monotonic-up' ? -1 : 1;
|
|
158
|
-
return b.netSize - a.netSize;
|
|
159
|
-
});
|
|
160
|
-
const top = rows.slice(0, limit);
|
|
256
|
+
// Known artifacts dominate the top of this table in practice and none
|
|
257
|
+
// of them is an app leak, so by default they are summarized rather than
|
|
258
|
+
// listed. They are still counted, and `include_artifacts` brings them
|
|
259
|
+
// back — suppression must never be silent.
|
|
260
|
+
const artifactRows = rows.filter(r => r.artifact != null);
|
|
261
|
+
const candidateRows = include_artifacts
|
|
262
|
+
? rows
|
|
263
|
+
: rows.filter(r => r.artifact == null);
|
|
264
|
+
const top = candidateRows.slice(0, limit);
|
|
161
265
|
const lines = [
|
|
162
266
|
`## Sequence / Trend Analysis (${n} snapshots)`,
|
|
163
267
|
'',
|
|
@@ -173,16 +277,28 @@ export function registerSequenceAnalysis(server) {
|
|
|
173
277
|
lines.push(markdownTable(totalHeaders, totalRows, new Set([2, 3])));
|
|
174
278
|
const heapNet = steps[n - 1].totalSize - steps[0].totalSize;
|
|
175
279
|
lines.push('', `Overall heap self-size ${heapNet >= 0 ? 'grew' : 'shrank'} by ${formatBytes(Math.abs(heapNet))} across the sequence.`, '');
|
|
280
|
+
// With exactly two rungs "grew at every step" is the same statement as
|
|
281
|
+
// "grew overall", so the monotonic verdict carries no extra information
|
|
282
|
+
// and cannot distinguish a trend from a GC-band sample. Measured case: a
|
|
283
|
+
// 2-rung ladder read as a confident +154 KB/cycle retained leak, and a
|
|
284
|
+
// third and fourth rung showed the heap falling back below where it
|
|
285
|
+
// started — the band was ~25 MB wide, easily enough to fake a linear
|
|
286
|
+
// slope. Say so rather than letting the label imply a trend.
|
|
287
|
+
if (n === 2) {
|
|
288
|
+
lines.push('> ⚠️ **Only 2 snapshots: "↑ every step" is monotonic by construction** and cannot separate a real trend from a single GC-band sample. Capture at least a third rung (and prefer a targeted-retainer count over aggregate heap) before treating anything here as a leak.', '');
|
|
289
|
+
}
|
|
176
290
|
if (top.length === 0) {
|
|
177
291
|
lines.push(`No classes grew by >= ${formatNumber(min_growth_count)} instances across the sequence. Heap looks flat-to-shrinking — no unbounded-growth signal.`);
|
|
178
292
|
return toolResult(lines.join('\n'));
|
|
179
293
|
}
|
|
180
294
|
lines.push('### Growing classes', '');
|
|
295
|
+
const perCycle = cycles != null && cycles > 0;
|
|
181
296
|
const headers = [
|
|
182
297
|
'Class',
|
|
183
298
|
'Type',
|
|
184
299
|
...steps.map((_, i) => `#${i + 1}`),
|
|
185
300
|
'Δ count',
|
|
301
|
+
...(perCycle ? ['Δ/cycle'] : []),
|
|
186
302
|
'Δ size',
|
|
187
303
|
'Verdict',
|
|
188
304
|
];
|
|
@@ -190,17 +306,18 @@ export function registerSequenceAnalysis(server) {
|
|
|
190
306
|
for (let i = 2; i < headers.length - 1; i++)
|
|
191
307
|
rightCols.add(i);
|
|
192
308
|
const tableRows = top.map(r => {
|
|
193
|
-
const
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
309
|
+
const { type, name } = r;
|
|
310
|
+
const verdict = r.artifact != null
|
|
311
|
+
? artifactLabel(r.artifact)
|
|
312
|
+
: r.trend === 'monotonic-up'
|
|
313
|
+
? '↑ every step (LEAK candidate)'
|
|
314
|
+
: 'grew net (noisy)';
|
|
199
315
|
return [
|
|
200
316
|
name.length > 36 ? name.slice(0, 33) + '…' : name,
|
|
201
317
|
type,
|
|
202
318
|
...r.counts.map(c => formatNumber(c)),
|
|
203
319
|
`+${formatNumber(r.netCount)}`,
|
|
320
|
+
...(perCycle ? [(r.netCount / cycles).toFixed(2)] : []),
|
|
204
321
|
`${r.netSize >= 0 ? '+' : ''}${formatBytes(r.netSize)}`,
|
|
205
322
|
verdict,
|
|
206
323
|
];
|
|
@@ -213,7 +330,11 @@ export function registerSequenceAnalysis(server) {
|
|
|
213
330
|
const c = last.get(k)?.count ?? 0;
|
|
214
331
|
if (c >= min_growth_count) {
|
|
215
332
|
const sep = k.indexOf('::');
|
|
216
|
-
|
|
333
|
+
const name = k.slice(sep + 2);
|
|
334
|
+
// Don't clutter the list with known JIT/automation artifacts.
|
|
335
|
+
if (classifyArtifact(name) != null)
|
|
336
|
+
continue;
|
|
337
|
+
newClasses.push(`${name} (${formatNumber(c)})`);
|
|
217
338
|
}
|
|
218
339
|
}
|
|
219
340
|
}
|
|
@@ -223,7 +344,76 @@ export function registerSequenceAnalysis(server) {
|
|
|
223
344
|
? `, … +${newClasses.length - 20} more`
|
|
224
345
|
: ''));
|
|
225
346
|
}
|
|
226
|
-
|
|
347
|
+
// `heap number` growth is a capture artifact when the snapshot was
|
|
348
|
+
// taken with numeric-value capture on (Chrome's captureNumericValue /
|
|
349
|
+
// the browser MCP's capture_numeric_value): that mode emits one graph
|
|
350
|
+
// node per distinct number and ~3x inflates the graph. With it off,
|
|
351
|
+
// these are ordinary boxed doubles that V8 allocates anyway, and growth
|
|
352
|
+
// can be a REAL signal.
|
|
353
|
+
//
|
|
354
|
+
// We deliberately do NOT try to auto-detect which mode produced the
|
|
355
|
+
// snapshot. The obvious signal — value-named nodes of type `number` —
|
|
356
|
+
// does not separate the two: a snapshot captured with
|
|
357
|
+
// capture_numeric_value:false was measured with 47,874 `heap number`
|
|
358
|
+
// nodes AND 165,193 value-named numeric nodes, so any threshold on that
|
|
359
|
+
// count mislabels it. Stating a conditional the caller can resolve from
|
|
360
|
+
// their own capture settings beats asserting a mode we cannot verify;
|
|
361
|
+
// the previous copy declared this "almost always a capture artifact"
|
|
362
|
+
// unconditionally, which trains readers to dismiss a grower that may be
|
|
363
|
+
// real.
|
|
364
|
+
if (top.some(r => r.key === 'number::heap number')) {
|
|
365
|
+
// State the answer instead of asking the caller for it. The runtime
|
|
366
|
+
// and the numeric-capture mode are both derivable from the histograms
|
|
367
|
+
// already built above, at no extra cost: `smi number` is the marker
|
|
368
|
+
// node type, and a `Window …` class means a browser capture. See
|
|
369
|
+
// capture-mode.ts for the matched-pair measurements behind this.
|
|
370
|
+
const last = steps[n - 1].hist;
|
|
371
|
+
const isBrowser = [...last.keys()].some(k => k.startsWith('object::Window '));
|
|
372
|
+
const isNode = !isBrowser && [...last.keys()].some(k => k === 'object::Module');
|
|
373
|
+
const verdict = classifyNumericCapture(isBrowser ? 'browser' : isNode ? 'node' : 'unknown', last.has(SMI_NUMBER_CLASS_KEY));
|
|
374
|
+
lines.push('', shouldEmitNote('seq:heap-number')
|
|
375
|
+
? `> ⚠️ \`heap number\` is growing. ${verdict.note}`
|
|
376
|
+
: '> ⚠️ `heap number` is growing (capture-mode caveat already stated this session).');
|
|
377
|
+
}
|
|
378
|
+
// `smi number` growth in a Node capture is pure capture overhead — those
|
|
379
|
+
// nodes do not exist unless the flag asked for them.
|
|
380
|
+
if (top.some(r => r.key === SMI_NUMBER_CLASS_KEY) &&
|
|
381
|
+
![...steps[n - 1].hist.keys()].some(k => k.startsWith('object::Window '))) {
|
|
382
|
+
lines.push('', shouldEmitNote('seq:smi-number')
|
|
383
|
+
? '> ⚠️ `smi number` is growing in a Node.js capture. Those nodes only exist because the snapshot was taken with numeric-value capture ON; they are capture overhead, not application memory. Re-capture without it to remove them from the trend.'
|
|
384
|
+
: '> ⚠️ `smi number` is growing — capture overhead (note already stated this session).');
|
|
385
|
+
}
|
|
386
|
+
// Known-artifact families: either annotate the rows that were shown,
|
|
387
|
+
// or account for the ones that were collapsed. Either way the caller is
|
|
388
|
+
// told what was set aside and why.
|
|
389
|
+
const shownKinds = new Set();
|
|
390
|
+
for (const r of top)
|
|
391
|
+
if (r.artifact != null)
|
|
392
|
+
shownKinds.add(r.artifact);
|
|
393
|
+
const suppressedByKind = new Map();
|
|
394
|
+
if (!include_artifacts) {
|
|
395
|
+
for (const r of artifactRows) {
|
|
396
|
+
suppressedByKind.set(r.artifact, (suppressedByKind.get(r.artifact) ?? 0) + 1);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
if (suppressedByKind.size > 0) {
|
|
400
|
+
const parts = [...suppressedByKind.entries()]
|
|
401
|
+
.sort((a, b) => b[1] - a[1])
|
|
402
|
+
.map(([kind, count]) => `${kind} ${count}`);
|
|
403
|
+
lines.push('', `> 🧹 **${artifactRows.length} growing class(es) suppressed as known measurement artifacts** (${parts.join(', ')}). None of these families is an application leak; pass \`include_artifacts: true\` to see them.`);
|
|
404
|
+
for (const kind of suppressedByKind.keys()) {
|
|
405
|
+
pushArtifactNote(lines, kind);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
for (const kind of shownKinds) {
|
|
409
|
+
pushArtifactNote(lines, kind);
|
|
410
|
+
}
|
|
411
|
+
if (shouldEmitNote('seq:candidate-not-verdict')) {
|
|
412
|
+
lines.push('', '_"↑ every step (LEAK candidate)" is the strong unbounded-growth signal — it is a candidate, not a verdict: confirm with `memlab_dev_artifacts` and a `memlab_retainer_trace` before calling it a leak; "grew net (noisy)" often reflects GC timing or navigation and warrants a closer look before treating as a leak. Object-identity matching across snapshots is not available (node ids differ per capture) — to localize a specific growing collection, load the last snapshot and use `memlab_cache_analysis` / `memlab_event_listener_leaks` / `memlab_growth_signals`._');
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
lines.push('', '_"↑ every step" is a candidate, not a verdict — see the first `memlab_sequence_analysis` result this session for the full caveat, or pass `repeat_notes: true`._');
|
|
416
|
+
}
|
|
227
417
|
return toolResult(lines.join('\n'));
|
|
228
418
|
}
|
|
229
419
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequence-analysis.js","sourceRoot":"","sources":["../../src/tools/sequence-analysis.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sequence-analysis.js","sourceRoot":"","sources":["../../src/tools/sequence-analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shape-histogram.d.ts","sourceRoot":"","sources":["../../src/tools/shape-histogram.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"shape-histogram.d.ts","sourceRoot":"","sources":["../../src/tools/shape-histogram.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAoCvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoM9D"}
|
|
@@ -11,7 +11,7 @@ import memlabCore from '@memlab/core';
|
|
|
11
11
|
const { utils, NumericSet } = memlabCore;
|
|
12
12
|
import { z } from 'zod';
|
|
13
13
|
import { getSnapshot } from '../heap-state.js';
|
|
14
|
-
import { formatBytes, formatNumber, errorResult, toolResult, suggestionsSuppressed, } from '../utils.js';
|
|
14
|
+
import { formatBytes, formatNumber, errorResult, toolResult, suggestionsSuppressed, makeNamePatternTest, } from '../utils.js';
|
|
15
15
|
function getPropertyNames(node) {
|
|
16
16
|
const names = [];
|
|
17
17
|
for (const edge of node.references) {
|
|
@@ -45,6 +45,10 @@ export function registerShapeHistogram(server) {
|
|
|
45
45
|
.string()
|
|
46
46
|
.optional()
|
|
47
47
|
.describe('Filter to objects with this constructor name (e.g., "Object"). If omitted, includes all object-type nodes.'),
|
|
48
|
+
name_pattern: z
|
|
49
|
+
.string()
|
|
50
|
+
.optional()
|
|
51
|
+
.describe('Filter constructor names by pattern before grouping by shape — a case-insensitive regular expression, or a plain substring when the pattern is not valid regex (e.g. "blink::UndoStep", "Detached", "^WA"). Answering "is class X present?" this way costs one row instead of a whole table.'),
|
|
48
52
|
sort_by: z
|
|
49
53
|
.enum(['retained_size', 'retained', 'count', 'self_size', 'self'])
|
|
50
54
|
.optional()
|
|
@@ -55,7 +59,7 @@ export function registerShapeHistogram(server) {
|
|
|
55
59
|
.optional()
|
|
56
60
|
.default(false)
|
|
57
61
|
.describe('Compute the EXACT dominator-deduped retained size per shape via aggregateDominatorMetrics. DEFAULT false: report a retained-size range instead (lower = Σ self size, upper = Σ raw retained) from the O(N) pass; sorting/filtering by retained uses the upper bound. Set true ONLY on explicit user request — the exact walk can be very slow or time out on huge heaps.'),
|
|
58
|
-
}, async ({ limit, min_count, min_retained_size, class_name, sort_by, exact_retained_size, }) => {
|
|
62
|
+
}, async ({ limit, min_count, min_retained_size, class_name, name_pattern, sort_by, exact_retained_size, }) => {
|
|
59
63
|
try {
|
|
60
64
|
// Normalize sort aliases so the vocabulary matches other tools.
|
|
61
65
|
const sort = sort_by === 'retained'
|
|
@@ -64,6 +68,7 @@ export function registerShapeHistogram(server) {
|
|
|
64
68
|
? 'self_size'
|
|
65
69
|
: sort_by;
|
|
66
70
|
const snapshot = getSnapshot();
|
|
71
|
+
const nameMatches = makeNamePatternTest(name_pattern);
|
|
67
72
|
const shapeMap = new Map();
|
|
68
73
|
snapshot.nodes.forEach(node => {
|
|
69
74
|
if (node.type !== 'object')
|
|
@@ -72,6 +77,8 @@ export function registerShapeHistogram(server) {
|
|
|
72
77
|
return;
|
|
73
78
|
if (class_name && node.name !== class_name)
|
|
74
79
|
return;
|
|
80
|
+
if (!nameMatches(node.name))
|
|
81
|
+
return;
|
|
75
82
|
const props = getPropertyNames(node);
|
|
76
83
|
if (!props)
|
|
77
84
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shape-histogram.js","sourceRoot":"","sources":["../../src/tools/shape-histogram.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,MAAM,EAAC,KAAK,EAAE,UAAU,EAAC,GAAG,UAAU,CAAC;AACvC,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,UAAU,EACV,qBAAqB,
|
|
1
|
+
{"version":3,"file":"shape-histogram.js","sourceRoot":"","sources":["../../src/tools/shape-histogram.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sliced-strings.d.ts","sourceRoot":"","sources":["../../src/tools/sliced-strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAqBvE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"sliced-strings.d.ts","sourceRoot":"","sources":["../../src/tools/sliced-strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAqBvE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuK7D"}
|
|
@@ -80,11 +80,26 @@ export function registerSlicedStrings(server) {
|
|
|
80
80
|
if (slicedCount === 0 && concatCount === 0) {
|
|
81
81
|
return toolResult('No sliced or concatenated strings found in the snapshot.');
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
const allParents = [...parentMap.values()];
|
|
84
|
+
const totalPinnedBytes = allParents.reduce((sum, p) => sum + p.self_size, 0);
|
|
85
|
+
// Don't go silent when `min_parent_size` filters everything out. On the
|
|
86
|
+
// common "many medium parents" case (each parent sub-MB but thousands of
|
|
87
|
+
// them, e.g. ~250 KB JSON records) the filter used to hide every row and
|
|
88
|
+
// the tool reported nothing actionable. Fall back to the largest parents
|
|
89
|
+
// with a note, and ALWAYS report the aggregate bytes pinned so the "lots
|
|
90
|
+
// of small parents" case is visible (Feedback round 4 §3a).
|
|
91
|
+
let parents = allParents;
|
|
92
|
+
let filteredNote = '';
|
|
84
93
|
if (min_parent_size != null) {
|
|
85
|
-
|
|
94
|
+
const filtered = allParents.filter(p => p.self_size >= min_parent_size);
|
|
95
|
+
if (filtered.length > 0) {
|
|
96
|
+
parents = filtered;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
filteredNote = ` (no parent ≥ ${formatBytes(min_parent_size)}; showing the largest instead)`;
|
|
100
|
+
}
|
|
86
101
|
}
|
|
87
|
-
parents.sort((a, b) => b.self_size - a.self_size);
|
|
102
|
+
parents = [...parents].sort((a, b) => b.self_size - a.self_size);
|
|
88
103
|
const topParents = parents.slice(0, limit);
|
|
89
104
|
const lines = [];
|
|
90
105
|
lines.push(`**Sliced strings:** ${formatNumber(slicedCount)} nodes (${formatBytes(slicedTotalSize)} self size)`);
|
|
@@ -92,6 +107,9 @@ export function registerSlicedStrings(server) {
|
|
|
92
107
|
lines.push(`**Concatenated strings:** ${formatNumber(concatCount)} nodes (${formatBytes(concatTotalSize)} self size)`);
|
|
93
108
|
}
|
|
94
109
|
lines.push(`**Unique parent strings referenced:** ${formatNumber(parentMap.size)}`);
|
|
110
|
+
if (allParents.length > 0) {
|
|
111
|
+
lines.push(`**Total parent bytes pinned by slices:** ${formatBytes(totalPinnedBytes)} across ${formatNumber(allParents.length)} parent string(s) — substrings keep these alive even when each individual parent is small.`);
|
|
112
|
+
}
|
|
95
113
|
lines.push('');
|
|
96
114
|
if (topParents.length > 0) {
|
|
97
115
|
const headers = [
|
|
@@ -111,7 +129,7 @@ export function registerSlicedStrings(server) {
|
|
|
111
129
|
formatNumber(p.sliced_ref_count),
|
|
112
130
|
formatBytes(p.sliced_total_size),
|
|
113
131
|
]);
|
|
114
|
-
lines.push(
|
|
132
|
+
lines.push(`### Top parent strings (keeping slices alive)${filteredNote}`);
|
|
115
133
|
lines.push('');
|
|
116
134
|
lines.push(markdownTable(headers, rows, rightCols));
|
|
117
135
|
const largeMB = topParents.filter(p => p.self_size >= 1024 * 1024);
|