@memlab/mcp-server 2.0.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 +285 -0
- package/bin/memlab-mcp.js +3 -0
- package/dist/heap-state.d.ts +14 -0
- package/dist/heap-state.d.ts.map +1 -0
- package/dist/heap-state.js +25 -0
- package/dist/heap-state.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/aggregate-nodes.d.ts +12 -0
- package/dist/tools/aggregate-nodes.d.ts.map +1 -0
- package/dist/tools/aggregate-nodes.js +136 -0
- package/dist/tools/aggregate-nodes.js.map +1 -0
- package/dist/tools/class-histogram.d.ts +12 -0
- package/dist/tools/class-histogram.d.ts.map +1 -0
- package/dist/tools/class-histogram.js +94 -0
- package/dist/tools/class-histogram.js.map +1 -0
- package/dist/tools/closure-inspection.d.ts +12 -0
- package/dist/tools/closure-inspection.d.ts.map +1 -0
- package/dist/tools/closure-inspection.js +107 -0
- package/dist/tools/closure-inspection.js.map +1 -0
- package/dist/tools/detached-dom.d.ts +12 -0
- package/dist/tools/detached-dom.d.ts.map +1 -0
- package/dist/tools/detached-dom.js +53 -0
- package/dist/tools/detached-dom.js.map +1 -0
- package/dist/tools/dominator-subtree.d.ts +12 -0
- package/dist/tools/dominator-subtree.d.ts.map +1 -0
- package/dist/tools/dominator-subtree.js +77 -0
- package/dist/tools/dominator-subtree.js.map +1 -0
- package/dist/tools/duplicated-strings.d.ts +12 -0
- package/dist/tools/duplicated-strings.d.ts.map +1 -0
- package/dist/tools/duplicated-strings.js +78 -0
- package/dist/tools/duplicated-strings.js.map +1 -0
- package/dist/tools/eval.d.ts +12 -0
- package/dist/tools/eval.d.ts.map +1 -0
- package/dist/tools/eval.js +119 -0
- package/dist/tools/eval.js.map +1 -0
- package/dist/tools/find-by-property.d.ts +12 -0
- package/dist/tools/find-by-property.d.ts.map +1 -0
- package/dist/tools/find-by-property.js +77 -0
- package/dist/tools/find-by-property.js.map +1 -0
- package/dist/tools/find-nodes-by-class.d.ts +12 -0
- package/dist/tools/find-nodes-by-class.d.ts.map +1 -0
- package/dist/tools/find-nodes-by-class.js +38 -0
- package/dist/tools/find-nodes-by-class.js.map +1 -0
- package/dist/tools/for-each.d.ts +12 -0
- package/dist/tools/for-each.d.ts.map +1 -0
- package/dist/tools/for-each.js +185 -0
- package/dist/tools/for-each.js.map +1 -0
- package/dist/tools/get-node.d.ts +12 -0
- package/dist/tools/get-node.d.ts.map +1 -0
- package/dist/tools/get-node.js +51 -0
- package/dist/tools/get-node.js.map +1 -0
- package/dist/tools/get-property.d.ts +12 -0
- package/dist/tools/get-property.d.ts.map +1 -0
- package/dist/tools/get-property.js +88 -0
- package/dist/tools/get-property.js.map +1 -0
- package/dist/tools/get-references.d.ts +12 -0
- package/dist/tools/get-references.d.ts.map +1 -0
- package/dist/tools/get-references.js +61 -0
- package/dist/tools/get-references.js.map +1 -0
- package/dist/tools/get-referrers.d.ts +12 -0
- package/dist/tools/get-referrers.d.ts.map +1 -0
- package/dist/tools/get-referrers.js +61 -0
- package/dist/tools/get-referrers.js.map +1 -0
- package/dist/tools/global-variables.d.ts +12 -0
- package/dist/tools/global-variables.d.ts.map +1 -0
- package/dist/tools/global-variables.js +331 -0
- package/dist/tools/global-variables.js.map +1 -0
- package/dist/tools/largest-objects.d.ts +12 -0
- package/dist/tools/largest-objects.d.ts.map +1 -0
- package/dist/tools/largest-objects.js +32 -0
- package/dist/tools/largest-objects.js.map +1 -0
- package/dist/tools/load-snapshot.d.ts +12 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -0
- package/dist/tools/load-snapshot.js +39 -0
- package/dist/tools/load-snapshot.js.map +1 -0
- package/dist/tools/object-shape.d.ts +12 -0
- package/dist/tools/object-shape.d.ts.map +1 -0
- package/dist/tools/object-shape.js +86 -0
- package/dist/tools/object-shape.js.map +1 -0
- package/dist/tools/reports.d.ts +12 -0
- package/dist/tools/reports.d.ts.map +1 -0
- package/dist/tools/reports.js +540 -0
- package/dist/tools/reports.js.map +1 -0
- package/dist/tools/retainer-trace.d.ts +12 -0
- package/dist/tools/retainer-trace.d.ts.map +1 -0
- package/dist/tools/retainer-trace.js +68 -0
- package/dist/tools/retainer-trace.js.map +1 -0
- package/dist/tools/search-nodes.d.ts +12 -0
- package/dist/tools/search-nodes.d.ts.map +1 -0
- package/dist/tools/search-nodes.js +85 -0
- package/dist/tools/search-nodes.js.map +1 -0
- package/dist/tools/snapshot-summary.d.ts +12 -0
- package/dist/tools/snapshot-summary.d.ts.map +1 -0
- package/dist/tools/snapshot-summary.js +73 -0
- package/dist/tools/snapshot-summary.js.map +1 -0
- package/dist/tools/stale-collections.d.ts +12 -0
- package/dist/tools/stale-collections.d.ts.map +1 -0
- package/dist/tools/stale-collections.js +97 -0
- package/dist/tools/stale-collections.js.map +1 -0
- package/dist/utils.d.ts +82 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +220 -0
- package/dist/utils.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { getSnapshot } from '../heap-state.js';
|
|
12
|
+
import { formatBytes, formatNumber, markdownTable, isNodeWorthInspecting, filterLargestObjects, serializeNodeSummary, formatNodeSummaryTable, queryNodes, formatQueryNodesResult, errorResult, textResult, } from '../utils.js';
|
|
13
|
+
// --- Detached DOM analysis ---
|
|
14
|
+
function isDetachedDOMNode(node) {
|
|
15
|
+
if (node.id <= 3)
|
|
16
|
+
return false;
|
|
17
|
+
if (node.is_detached)
|
|
18
|
+
return true;
|
|
19
|
+
return node.name.startsWith('Detached ');
|
|
20
|
+
}
|
|
21
|
+
function runDetachedDom(limit) {
|
|
22
|
+
const snapshot = getSnapshot();
|
|
23
|
+
const result = queryNodes(snapshot, isDetachedDOMNode, {
|
|
24
|
+
limit,
|
|
25
|
+
offset: 0,
|
|
26
|
+
outputMode: 'full',
|
|
27
|
+
});
|
|
28
|
+
return `## Detached DOM Nodes\n\n${formatQueryNodesResult(result)}`;
|
|
29
|
+
}
|
|
30
|
+
// --- Duplicated Strings analysis ---
|
|
31
|
+
function runDuplicatedStrings(limit) {
|
|
32
|
+
const snapshot = getSnapshot();
|
|
33
|
+
const stringMap = new Map();
|
|
34
|
+
snapshot.nodes.forEach(node => {
|
|
35
|
+
if (node.type !== 'string')
|
|
36
|
+
return;
|
|
37
|
+
if (node.name === 'system / SlicedString')
|
|
38
|
+
return;
|
|
39
|
+
const strNode = node.toStringNode();
|
|
40
|
+
if (!strNode)
|
|
41
|
+
return;
|
|
42
|
+
const value = strNode.stringValue;
|
|
43
|
+
const entry = stringMap.get(value);
|
|
44
|
+
if (entry) {
|
|
45
|
+
entry.count++;
|
|
46
|
+
entry.total_size += node.retainedSize;
|
|
47
|
+
if (entry.example_node_ids.length < 3) {
|
|
48
|
+
entry.example_node_ids.push(node.id);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
stringMap.set(value, {
|
|
53
|
+
count: 1,
|
|
54
|
+
total_size: node.retainedSize,
|
|
55
|
+
example_node_ids: [node.id],
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const duplicated = Array.from(stringMap.entries())
|
|
60
|
+
.filter(([, stats]) => stats.count > 1)
|
|
61
|
+
.sort((a, b) => b[1].total_size - a[1].total_size)
|
|
62
|
+
.slice(0, limit)
|
|
63
|
+
.map(([value, stats]) => ({
|
|
64
|
+
value: value.length > 80 ? value.slice(0, 80) + '...' : value,
|
|
65
|
+
count: stats.count,
|
|
66
|
+
total_size_formatted: formatBytes(stats.total_size),
|
|
67
|
+
example_node_ids: stats.example_node_ids,
|
|
68
|
+
}));
|
|
69
|
+
if (duplicated.length === 0) {
|
|
70
|
+
return '## Duplicated Strings\n\nNo duplicated strings found.';
|
|
71
|
+
}
|
|
72
|
+
const lines = duplicated.map((d, i) => {
|
|
73
|
+
const nodeIds = d.example_node_ids.map(id => `@${id}`).join(', ');
|
|
74
|
+
return `${i + 1}. "${d.value}" x ${d.count} copies, ${d.total_size_formatted} total (nodes: ${nodeIds})`;
|
|
75
|
+
});
|
|
76
|
+
return `## Duplicated Strings\n\n${duplicated.length} entries:\n\n${lines.join('\n')}`;
|
|
77
|
+
}
|
|
78
|
+
// --- Stale Collections analysis ---
|
|
79
|
+
const COLLECTION_NAMES = new Set(['Map', 'Set', 'WeakMap', 'WeakSet', 'Array']);
|
|
80
|
+
function isCollectionNode(node) {
|
|
81
|
+
return node.type === 'object' && COLLECTION_NAMES.has(node.name);
|
|
82
|
+
}
|
|
83
|
+
function isStaleNode(node) {
|
|
84
|
+
return node.is_detached || node.name.startsWith('Detached ');
|
|
85
|
+
}
|
|
86
|
+
function getCollectionChildren(node) {
|
|
87
|
+
if (node.name === 'Map' || node.name === 'Set') {
|
|
88
|
+
const tableEdge = node.references.find(e => e.name_or_index === 'table');
|
|
89
|
+
if (tableEdge) {
|
|
90
|
+
return tableEdge.toNode.references;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return node.references;
|
|
94
|
+
}
|
|
95
|
+
function runStaleCollections(limit) {
|
|
96
|
+
const snapshot = getSnapshot();
|
|
97
|
+
const results = [];
|
|
98
|
+
snapshot.nodes.forEach(node => {
|
|
99
|
+
if (!isCollectionNode(node))
|
|
100
|
+
return;
|
|
101
|
+
const children = getCollectionChildren(node);
|
|
102
|
+
let staleCount = 0;
|
|
103
|
+
let staleRetainedSize = 0;
|
|
104
|
+
let totalChildren = 0;
|
|
105
|
+
for (const edge of children) {
|
|
106
|
+
totalChildren++;
|
|
107
|
+
if (isStaleNode(edge.toNode)) {
|
|
108
|
+
staleCount++;
|
|
109
|
+
staleRetainedSize += edge.toNode.retainedSize;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (staleCount > 0) {
|
|
113
|
+
results.push({
|
|
114
|
+
collection: node,
|
|
115
|
+
stale_item_count: staleCount,
|
|
116
|
+
stale_retained_size: staleRetainedSize,
|
|
117
|
+
total_children: totalChildren,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
results.sort((a, b) => b.stale_retained_size - a.stale_retained_size);
|
|
122
|
+
const topResults = results.slice(0, limit);
|
|
123
|
+
if (topResults.length === 0) {
|
|
124
|
+
return '## Stale Collections\n\nNo stale collections found.';
|
|
125
|
+
}
|
|
126
|
+
const headers = ['Collection ID', 'Name', 'Stale / Total', 'Stale Retained'];
|
|
127
|
+
const rightCols = new Set([2, 3]);
|
|
128
|
+
const rows = topResults.map(r => [
|
|
129
|
+
`@${r.collection.id}`,
|
|
130
|
+
r.collection.name,
|
|
131
|
+
`${formatNumber(r.stale_item_count)} / ${formatNumber(r.total_children)}`,
|
|
132
|
+
formatBytes(r.stale_retained_size),
|
|
133
|
+
]);
|
|
134
|
+
return `## Stale Collections\n\n${topResults.length} found\n\n${markdownTable(headers, rows, rightCols)}`;
|
|
135
|
+
}
|
|
136
|
+
// --- Global Variables analysis ---
|
|
137
|
+
const BUILTIN_GLOBALS = new Set([
|
|
138
|
+
'undefined',
|
|
139
|
+
'NaN',
|
|
140
|
+
'Infinity',
|
|
141
|
+
'globalThis',
|
|
142
|
+
'self',
|
|
143
|
+
'window',
|
|
144
|
+
'document',
|
|
145
|
+
'navigator',
|
|
146
|
+
'location',
|
|
147
|
+
'history',
|
|
148
|
+
'screen',
|
|
149
|
+
'performance',
|
|
150
|
+
'localStorage',
|
|
151
|
+
'sessionStorage',
|
|
152
|
+
'caches',
|
|
153
|
+
'crypto',
|
|
154
|
+
'indexedDB',
|
|
155
|
+
'console',
|
|
156
|
+
'alert',
|
|
157
|
+
'confirm',
|
|
158
|
+
'prompt',
|
|
159
|
+
'close',
|
|
160
|
+
'open',
|
|
161
|
+
'print',
|
|
162
|
+
'top',
|
|
163
|
+
'parent',
|
|
164
|
+
'frames',
|
|
165
|
+
'frameElement',
|
|
166
|
+
'opener',
|
|
167
|
+
'devicePixelRatio',
|
|
168
|
+
'innerHeight',
|
|
169
|
+
'innerWidth',
|
|
170
|
+
'outerHeight',
|
|
171
|
+
'outerWidth',
|
|
172
|
+
'scrollX',
|
|
173
|
+
'scrollY',
|
|
174
|
+
'pageXOffset',
|
|
175
|
+
'pageYOffset',
|
|
176
|
+
'screenX',
|
|
177
|
+
'screenY',
|
|
178
|
+
'screenLeft',
|
|
179
|
+
'screenTop',
|
|
180
|
+
'visualViewport',
|
|
181
|
+
'styleMedia',
|
|
182
|
+
'addEventListener',
|
|
183
|
+
'removeEventListener',
|
|
184
|
+
'dispatchEvent',
|
|
185
|
+
'onclick',
|
|
186
|
+
'onload',
|
|
187
|
+
'onerror',
|
|
188
|
+
'onmessage',
|
|
189
|
+
'onresize',
|
|
190
|
+
'onscroll',
|
|
191
|
+
'onbeforeunload',
|
|
192
|
+
'onunload',
|
|
193
|
+
'onhashchange',
|
|
194
|
+
'onpopstate',
|
|
195
|
+
'onfocus',
|
|
196
|
+
'onblur',
|
|
197
|
+
'onkeydown',
|
|
198
|
+
'onkeyup',
|
|
199
|
+
'onkeypress',
|
|
200
|
+
'onmousedown',
|
|
201
|
+
'onmouseup',
|
|
202
|
+
'onmousemove',
|
|
203
|
+
'onmouseenter',
|
|
204
|
+
'onmouseleave',
|
|
205
|
+
'ontouchstart',
|
|
206
|
+
'ontouchend',
|
|
207
|
+
'ontouchmove',
|
|
208
|
+
'ontouchcancel',
|
|
209
|
+
'onanimationend',
|
|
210
|
+
'onanimationstart',
|
|
211
|
+
'onanimationiteration',
|
|
212
|
+
'ontransitionend',
|
|
213
|
+
'onpointerdown',
|
|
214
|
+
'onpointerup',
|
|
215
|
+
'onpointermove',
|
|
216
|
+
'setTimeout',
|
|
217
|
+
'clearTimeout',
|
|
218
|
+
'setInterval',
|
|
219
|
+
'clearInterval',
|
|
220
|
+
'requestAnimationFrame',
|
|
221
|
+
'cancelAnimationFrame',
|
|
222
|
+
'requestIdleCallback',
|
|
223
|
+
'cancelIdleCallback',
|
|
224
|
+
'fetch',
|
|
225
|
+
'XMLHttpRequest',
|
|
226
|
+
'WebSocket',
|
|
227
|
+
'EventSource',
|
|
228
|
+
'Request',
|
|
229
|
+
'Response',
|
|
230
|
+
'Headers',
|
|
231
|
+
'URL',
|
|
232
|
+
'URLSearchParams',
|
|
233
|
+
'AbortController',
|
|
234
|
+
'AbortSignal',
|
|
235
|
+
'Worker',
|
|
236
|
+
'SharedWorker',
|
|
237
|
+
'ServiceWorker',
|
|
238
|
+
'BroadcastChannel',
|
|
239
|
+
'MessageChannel',
|
|
240
|
+
'Image',
|
|
241
|
+
'Audio',
|
|
242
|
+
'MediaSource',
|
|
243
|
+
'MediaStream',
|
|
244
|
+
'MediaRecorder',
|
|
245
|
+
'AudioContext',
|
|
246
|
+
'OfflineAudioContext',
|
|
247
|
+
'SpeechSynthesis',
|
|
248
|
+
'Object',
|
|
249
|
+
'Function',
|
|
250
|
+
'Array',
|
|
251
|
+
'Number',
|
|
252
|
+
'String',
|
|
253
|
+
'Boolean',
|
|
254
|
+
'Symbol',
|
|
255
|
+
'Date',
|
|
256
|
+
'RegExp',
|
|
257
|
+
'Error',
|
|
258
|
+
'TypeError',
|
|
259
|
+
'RangeError',
|
|
260
|
+
'SyntaxError',
|
|
261
|
+
'ReferenceError',
|
|
262
|
+
'URIError',
|
|
263
|
+
'EvalError',
|
|
264
|
+
'Map',
|
|
265
|
+
'Set',
|
|
266
|
+
'WeakMap',
|
|
267
|
+
'WeakSet',
|
|
268
|
+
'WeakRef',
|
|
269
|
+
'FinalizationRegistry',
|
|
270
|
+
'Promise',
|
|
271
|
+
'Proxy',
|
|
272
|
+
'Reflect',
|
|
273
|
+
'ArrayBuffer',
|
|
274
|
+
'SharedArrayBuffer',
|
|
275
|
+
'DataView',
|
|
276
|
+
'Int8Array',
|
|
277
|
+
'Uint8Array',
|
|
278
|
+
'Uint8ClampedArray',
|
|
279
|
+
'Int16Array',
|
|
280
|
+
'Uint16Array',
|
|
281
|
+
'Int32Array',
|
|
282
|
+
'Uint32Array',
|
|
283
|
+
'Float32Array',
|
|
284
|
+
'Float64Array',
|
|
285
|
+
'BigInt64Array',
|
|
286
|
+
'BigUint64Array',
|
|
287
|
+
'JSON',
|
|
288
|
+
'Math',
|
|
289
|
+
'Intl',
|
|
290
|
+
'Atomics',
|
|
291
|
+
'BigInt',
|
|
292
|
+
'TextEncoder',
|
|
293
|
+
'TextDecoder',
|
|
294
|
+
'Blob',
|
|
295
|
+
'File',
|
|
296
|
+
'FileReader',
|
|
297
|
+
'FileList',
|
|
298
|
+
'FormData',
|
|
299
|
+
'ReadableStream',
|
|
300
|
+
'WritableStream',
|
|
301
|
+
'TransformStream',
|
|
302
|
+
'CompressionStream',
|
|
303
|
+
'DecompressionStream',
|
|
304
|
+
'MutationObserver',
|
|
305
|
+
'IntersectionObserver',
|
|
306
|
+
'ResizeObserver',
|
|
307
|
+
'PerformanceObserver',
|
|
308
|
+
'CustomEvent',
|
|
309
|
+
'Event',
|
|
310
|
+
'EventTarget',
|
|
311
|
+
'Element',
|
|
312
|
+
'HTMLElement',
|
|
313
|
+
'HTMLDivElement',
|
|
314
|
+
'HTMLSpanElement',
|
|
315
|
+
'HTMLInputElement',
|
|
316
|
+
'HTMLButtonElement',
|
|
317
|
+
'HTMLFormElement',
|
|
318
|
+
'HTMLAnchorElement',
|
|
319
|
+
'HTMLImageElement',
|
|
320
|
+
'HTMLCanvasElement',
|
|
321
|
+
'HTMLVideoElement',
|
|
322
|
+
'HTMLAudioElement',
|
|
323
|
+
'HTMLScriptElement',
|
|
324
|
+
'HTMLStyleElement',
|
|
325
|
+
'HTMLLinkElement',
|
|
326
|
+
'HTMLMetaElement',
|
|
327
|
+
'HTMLHeadElement',
|
|
328
|
+
'HTMLBodyElement',
|
|
329
|
+
'HTMLIFrameElement',
|
|
330
|
+
'HTMLSelectElement',
|
|
331
|
+
'HTMLOptionElement',
|
|
332
|
+
'HTMLTextAreaElement',
|
|
333
|
+
'HTMLTableElement',
|
|
334
|
+
'HTMLTableRowElement',
|
|
335
|
+
'HTMLTableCellElement',
|
|
336
|
+
'Document',
|
|
337
|
+
'DocumentFragment',
|
|
338
|
+
'Node',
|
|
339
|
+
'NodeList',
|
|
340
|
+
'NamedNodeMap',
|
|
341
|
+
'DOMParser',
|
|
342
|
+
'XMLSerializer',
|
|
343
|
+
'Range',
|
|
344
|
+
'Selection',
|
|
345
|
+
'TreeWalker',
|
|
346
|
+
'SVGElement',
|
|
347
|
+
'SVGSVGElement',
|
|
348
|
+
'CSS',
|
|
349
|
+
'CSSStyleSheet',
|
|
350
|
+
'CSSRule',
|
|
351
|
+
'CSSStyleDeclaration',
|
|
352
|
+
'getComputedStyle',
|
|
353
|
+
'matchMedia',
|
|
354
|
+
'atob',
|
|
355
|
+
'btoa',
|
|
356
|
+
'encodeURI',
|
|
357
|
+
'decodeURI',
|
|
358
|
+
'encodeURIComponent',
|
|
359
|
+
'decodeURIComponent',
|
|
360
|
+
'escape',
|
|
361
|
+
'unescape',
|
|
362
|
+
'eval',
|
|
363
|
+
'isFinite',
|
|
364
|
+
'isNaN',
|
|
365
|
+
'parseInt',
|
|
366
|
+
'parseFloat',
|
|
367
|
+
'queueMicrotask',
|
|
368
|
+
'structuredClone',
|
|
369
|
+
'reportError',
|
|
370
|
+
'createImageBitmap',
|
|
371
|
+
'postMessage',
|
|
372
|
+
]);
|
|
373
|
+
function runGlobalVariables(limit) {
|
|
374
|
+
const snapshot = getSnapshot();
|
|
375
|
+
const globals = [];
|
|
376
|
+
snapshot.nodes.forEach(node => {
|
|
377
|
+
if (!node.name.startsWith('Window '))
|
|
378
|
+
return;
|
|
379
|
+
for (const edge of node.references) {
|
|
380
|
+
const edgeName = String(edge.name_or_index);
|
|
381
|
+
if (BUILTIN_GLOBALS.has(edgeName))
|
|
382
|
+
continue;
|
|
383
|
+
if (edge.type === 'hidden' || edge.type === 'internal')
|
|
384
|
+
continue;
|
|
385
|
+
if (edgeName.startsWith('<symbol>'))
|
|
386
|
+
continue;
|
|
387
|
+
const target = edge.toNode;
|
|
388
|
+
if (target.type === 'hidden' ||
|
|
389
|
+
target.type === 'array' ||
|
|
390
|
+
target.type === 'number')
|
|
391
|
+
continue;
|
|
392
|
+
globals.push({
|
|
393
|
+
name: edgeName,
|
|
394
|
+
target_id: target.id,
|
|
395
|
+
target_name: target.name,
|
|
396
|
+
target_type: target.type,
|
|
397
|
+
retained_size: target.retainedSize,
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
globals.sort((a, b) => b.retained_size - a.retained_size);
|
|
402
|
+
const topGlobals = globals.slice(0, limit);
|
|
403
|
+
if (topGlobals.length === 0) {
|
|
404
|
+
return '## Global Variables\n\nNo non-built-in global variables found.';
|
|
405
|
+
}
|
|
406
|
+
const headers = ['Variable', 'Target ID', 'Target Name', 'Type', 'Retained'];
|
|
407
|
+
const rightCols = new Set([4]);
|
|
408
|
+
const rows = topGlobals.map(g => [
|
|
409
|
+
g.name,
|
|
410
|
+
`@${g.target_id}`,
|
|
411
|
+
g.target_name,
|
|
412
|
+
g.target_type,
|
|
413
|
+
formatBytes(g.retained_size),
|
|
414
|
+
]);
|
|
415
|
+
return `## Global Variables\n\n${topGlobals.length} found\n\n${markdownTable(headers, rows, rightCols)}`;
|
|
416
|
+
}
|
|
417
|
+
// --- Class Histogram analysis ---
|
|
418
|
+
function runClassHistogram(limit) {
|
|
419
|
+
const snapshot = getSnapshot();
|
|
420
|
+
const classMap = new Map();
|
|
421
|
+
snapshot.nodes.forEach(node => {
|
|
422
|
+
if (node.id <= 3)
|
|
423
|
+
return;
|
|
424
|
+
const key = `${node.type}::${node.name}`;
|
|
425
|
+
const entry = classMap.get(key);
|
|
426
|
+
if (entry) {
|
|
427
|
+
entry.count++;
|
|
428
|
+
entry.total_self_size += node.self_size;
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
classMap.set(key, {
|
|
432
|
+
count: 1,
|
|
433
|
+
total_self_size: node.self_size,
|
|
434
|
+
type: node.type,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
// Sort by total self size (avoids expensive dominator computation in the report)
|
|
439
|
+
const sorted = [...classMap.entries()]
|
|
440
|
+
.sort((a, b) => b[1].total_self_size - a[1].total_self_size)
|
|
441
|
+
.slice(0, limit);
|
|
442
|
+
const headers = ['Class', 'Type', 'Count', 'Self Size'];
|
|
443
|
+
const rightCols = new Set([2, 3]);
|
|
444
|
+
const rows = sorted.map(([key, v]) => {
|
|
445
|
+
const name = key.split('::').slice(1).join('::');
|
|
446
|
+
return [
|
|
447
|
+
name,
|
|
448
|
+
v.type,
|
|
449
|
+
formatNumber(v.count),
|
|
450
|
+
formatBytes(v.total_self_size),
|
|
451
|
+
];
|
|
452
|
+
});
|
|
453
|
+
return `## Class Histogram\n\n${formatNumber(classMap.size)} total classes, showing ${rows.length}\n\n${markdownTable(headers, rows, rightCols)}`;
|
|
454
|
+
}
|
|
455
|
+
// --- Largest Objects analysis ---
|
|
456
|
+
function runLargestObjects(limit) {
|
|
457
|
+
const snapshot = getSnapshot();
|
|
458
|
+
const nodes = filterLargestObjects(snapshot, isNodeWorthInspecting, limit);
|
|
459
|
+
const summaries = nodes.map(serializeNodeSummary);
|
|
460
|
+
return `## Largest Objects\n\nTop ${summaries.length} by retained size\n\n${formatNodeSummaryTable(summaries)}`;
|
|
461
|
+
}
|
|
462
|
+
const REPORTS = [
|
|
463
|
+
{
|
|
464
|
+
name: 'detached_dom',
|
|
465
|
+
description: 'Find detached DOM elements still retained in memory — common source of leaks',
|
|
466
|
+
run: runDetachedDom,
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
name: 'duplicated_strings',
|
|
470
|
+
description: 'Find duplicated string instances ranked by total size — common source of waste',
|
|
471
|
+
run: runDuplicatedStrings,
|
|
472
|
+
},
|
|
473
|
+
{
|
|
474
|
+
name: 'stale_collections',
|
|
475
|
+
description: 'Find Map/Set/Array collections holding references to detached or unmounted nodes',
|
|
476
|
+
run: runStaleCollections,
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
name: 'global_variables',
|
|
480
|
+
description: 'Find non-built-in global variables on Window, sorted by retained size',
|
|
481
|
+
run: runGlobalVariables,
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
name: 'class_histogram',
|
|
485
|
+
description: 'Show instance count and total self size per class/constructor name',
|
|
486
|
+
run: runClassHistogram,
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: 'largest_objects',
|
|
490
|
+
description: 'Find the top objects by retained size in the heap',
|
|
491
|
+
run: runLargestObjects,
|
|
492
|
+
},
|
|
493
|
+
];
|
|
494
|
+
const REPORT_NAMES = REPORTS.map(r => r.name);
|
|
495
|
+
function runList() {
|
|
496
|
+
const lines = REPORTS.map(r => `- **${r.name}**: ${r.description}`);
|
|
497
|
+
return `# Available Memory Reports\n\n${lines.join('\n')}\n\nUse \`report: "full_analysis"\` to run all reports at once, or pick an individual report by name.`;
|
|
498
|
+
}
|
|
499
|
+
export function registerReports(server) {
|
|
500
|
+
server.tool('memlab_reports', 'Run curated memory analysis reports — like Chrome DevTools Memory panel views. Use "list" to see available reports, pick one by name, or use "full_analysis" to run all reports for a comprehensive triage.', {
|
|
501
|
+
report: z
|
|
502
|
+
.enum(['list', 'full_analysis', ...REPORT_NAMES])
|
|
503
|
+
.optional()
|
|
504
|
+
.default('list')
|
|
505
|
+
.describe('Which report to run: "list" shows available reports, "full_analysis" runs all, or pick one by name'),
|
|
506
|
+
limit: z
|
|
507
|
+
.number()
|
|
508
|
+
.optional()
|
|
509
|
+
.default(10)
|
|
510
|
+
.describe('Maximum items per report section (default 10)'),
|
|
511
|
+
}, async ({ report, limit }) => {
|
|
512
|
+
try {
|
|
513
|
+
if (report === 'list') {
|
|
514
|
+
return textResult(runList());
|
|
515
|
+
}
|
|
516
|
+
if (report === 'full_analysis') {
|
|
517
|
+
const sections = REPORTS.map(r => {
|
|
518
|
+
try {
|
|
519
|
+
return r.run(limit);
|
|
520
|
+
}
|
|
521
|
+
catch (err) {
|
|
522
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
523
|
+
return `## ${r.name}\n\nError: ${msg}`;
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
return textResult(`# Full Memory Analysis\n\n${sections.join('\n\n---\n\n')}`);
|
|
527
|
+
}
|
|
528
|
+
// Individual report
|
|
529
|
+
const def = REPORTS.find(r => r.name === report);
|
|
530
|
+
if (!def) {
|
|
531
|
+
return textResult(`Unknown report "${report}". Use report: "list" to see available reports.`);
|
|
532
|
+
}
|
|
533
|
+
return textResult(def.run(limit));
|
|
534
|
+
}
|
|
535
|
+
catch (err) {
|
|
536
|
+
return errorResult(err);
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
//# sourceMappingURL=reports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/tools/reports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
export declare function registerRetainerTrace(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=retainer-trace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retainer-trace.d.ts","sourceRoot":"","sources":["../../src/tools/retainer-trace.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAMvE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwE7D"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import { z } from 'zod';
|
|
11
|
+
import { getSnapshot } from '../heap-state.js';
|
|
12
|
+
import { formatNodeInline, errorResult, textResult } from '../utils.js';
|
|
13
|
+
export function registerRetainerTrace(server) {
|
|
14
|
+
server.tool('memlab_retainer_trace', 'Get the shortest path from a GC root to a specific heap node. This shows why the object is retained in memory by walking the pathEdge chain.', {
|
|
15
|
+
node_id: z.number().describe('The numeric ID of the heap node'),
|
|
16
|
+
}, async ({ node_id }) => {
|
|
17
|
+
try {
|
|
18
|
+
const snapshot = getSnapshot();
|
|
19
|
+
const node = snapshot.getNodeById(node_id);
|
|
20
|
+
if (!node) {
|
|
21
|
+
return errorResult(`Node with id ${node_id} not found`);
|
|
22
|
+
}
|
|
23
|
+
if (!node.hasPathEdge) {
|
|
24
|
+
return textResult('No retainer path available for this node. It may be a root node or unreachable.');
|
|
25
|
+
}
|
|
26
|
+
const visited = new Set([node.id]);
|
|
27
|
+
let curNode = node;
|
|
28
|
+
// Collect path from target to root
|
|
29
|
+
const reverseItems = [{ node: curNode }];
|
|
30
|
+
while (curNode && curNode.hasPathEdge) {
|
|
31
|
+
const edge = curNode.pathEdge;
|
|
32
|
+
if (!edge)
|
|
33
|
+
break;
|
|
34
|
+
const fromNode = edge.fromNode;
|
|
35
|
+
if (visited.has(fromNode.id))
|
|
36
|
+
break; // cycle detection
|
|
37
|
+
visited.add(fromNode.id);
|
|
38
|
+
reverseItems.push({
|
|
39
|
+
node: fromNode,
|
|
40
|
+
edgeName: String(edge.name_or_index),
|
|
41
|
+
edgeType: edge.type,
|
|
42
|
+
});
|
|
43
|
+
curNode = fromNode;
|
|
44
|
+
}
|
|
45
|
+
// Reverse to get root-first order
|
|
46
|
+
reverseItems.reverse();
|
|
47
|
+
// Build visual chain
|
|
48
|
+
const parts = [];
|
|
49
|
+
for (let i = 0; i < reverseItems.length; i++) {
|
|
50
|
+
const item = reverseItems[i];
|
|
51
|
+
parts.push(formatNodeInline(item.node.id, item.node.name, item.node.type));
|
|
52
|
+
if (item.edgeName != null && i < reverseItems.length - 1) {
|
|
53
|
+
parts.push(` --${item.edgeName}--> `);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const lines = [
|
|
57
|
+
`Retainer trace for @${node_id} (${reverseItems.length} nodes):`,
|
|
58
|
+
'',
|
|
59
|
+
parts.join(''),
|
|
60
|
+
];
|
|
61
|
+
return textResult(lines.join('\n'));
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
return errorResult(err);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=retainer-trace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retainer-trace.js","sourceRoot":"","sources":["../../src/tools/retainer-trace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
* @oncall memory_lab
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
export declare function registerSearchNodes(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=search-nodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-nodes.d.ts","sourceRoot":"","sources":["../../src/tools/search-nodes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAYvE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0F3D"}
|