@memlab/mcp-server 2.1.1 → 2.18.1
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 +83 -3
- package/dist/analysis-budget.d.ts +71 -0
- package/dist/analysis-budget.d.ts.map +1 -0
- package/dist/analysis-budget.js +118 -0
- package/dist/analysis-budget.js.map +1 -0
- package/dist/guardrail.d.ts +24 -0
- package/dist/guardrail.d.ts.map +1 -0
- package/dist/guardrail.js +65 -0
- package/dist/guardrail.js.map +1 -0
- package/dist/heap-state.d.ts +53 -1
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +153 -10
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +38 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/array-group-by.d.ts +12 -0
- package/dist/tools/array-group-by.d.ts.map +1 -0
- package/dist/tools/array-group-by.js +191 -0
- package/dist/tools/array-group-by.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +1056 -52
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +438 -21
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/check-health.d.ts.map +1 -1
- package/dist/tools/check-health.js +261 -1
- package/dist/tools/check-health.js.map +1 -1
- package/dist/tools/class-histogram.d.ts.map +1 -1
- package/dist/tools/class-histogram.js +142 -33
- package/dist/tools/class-histogram.js.map +1 -1
- package/dist/tools/closure-inspection.d.ts.map +1 -1
- package/dist/tools/closure-inspection.js +238 -25
- package/dist/tools/closure-inspection.js.map +1 -1
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +25 -3
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts +33 -0
- package/dist/tools/dev-artifacts.d.ts.map +1 -0
- package/dist/tools/dev-artifacts.js +165 -0
- package/dist/tools/dev-artifacts.js.map +1 -0
- package/dist/tools/diff-snapshots.d.ts.map +1 -1
- package/dist/tools/diff-snapshots.js +200 -48
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +74 -12
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +189 -10
- package/dist/tools/eval.js.map +1 -1
- package/dist/tools/event-listener-leaks.d.ts.map +1 -1
- package/dist/tools/event-listener-leaks.js +235 -13
- package/dist/tools/event-listener-leaks.js.map +1 -1
- package/dist/tools/event-registry.d.ts +12 -0
- package/dist/tools/event-registry.d.ts.map +1 -0
- package/dist/tools/event-registry.js +183 -0
- package/dist/tools/event-registry.js.map +1 -0
- package/dist/tools/find-by-property.d.ts.map +1 -1
- package/dist/tools/find-by-property.js +113 -31
- package/dist/tools/find-by-property.js.map +1 -1
- package/dist/tools/find-by-shape.d.ts +12 -0
- package/dist/tools/find-by-shape.d.ts.map +1 -0
- package/dist/tools/find-by-shape.js +178 -0
- package/dist/tools/find-by-shape.js.map +1 -0
- package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
- package/dist/tools/find-nodes-by-class.js +50 -6
- package/dist/tools/find-nodes-by-class.js.map +1 -1
- package/dist/tools/for-each.d.ts.map +1 -1
- package/dist/tools/for-each.js +1 -1
- package/dist/tools/for-each.js.map +1 -1
- package/dist/tools/get-node.d.ts.map +1 -1
- package/dist/tools/get-node.js +6 -0
- package/dist/tools/get-node.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 +35 -6
- package/dist/tools/get-referrers.js.map +1 -1
- package/dist/tools/get-string.d.ts +12 -0
- package/dist/tools/get-string.d.ts.map +1 -0
- package/dist/tools/get-string.js +223 -0
- package/dist/tools/get-string.js.map +1 -0
- package/dist/tools/get-value.d.ts +12 -0
- package/dist/tools/get-value.d.ts.map +1 -0
- package/dist/tools/get-value.js +152 -0
- package/dist/tools/get-value.js.map +1 -0
- package/dist/tools/global-variables.d.ts.map +1 -1
- package/dist/tools/global-variables.js +54 -34
- package/dist/tools/global-variables.js.map +1 -1
- package/dist/tools/growth-signals.d.ts +12 -0
- package/dist/tools/growth-signals.d.ts.map +1 -0
- package/dist/tools/growth-signals.js +211 -0
- package/dist/tools/growth-signals.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts +12 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -0
- package/dist/tools/intern-opportunities.js +870 -0
- package/dist/tools/intern-opportunities.js.map +1 -0
- package/dist/tools/largest-objects.d.ts.map +1 -1
- package/dist/tools/largest-objects.js +37 -14
- package/dist/tools/largest-objects.js.map +1 -1
- package/dist/tools/load-snapshot.d.ts +70 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +446 -17
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/object-cost-breakdown.d.ts +12 -0
- package/dist/tools/object-cost-breakdown.d.ts.map +1 -0
- package/dist/tools/object-cost-breakdown.js +439 -0
- package/dist/tools/object-cost-breakdown.js.map +1 -0
- package/dist/tools/object-shape.d.ts.map +1 -1
- package/dist/tools/object-shape.js +109 -2
- package/dist/tools/object-shape.js.map +1 -1
- package/dist/tools/pinch-points.d.ts.map +1 -1
- package/dist/tools/pinch-points.js +9 -9
- package/dist/tools/pinch-points.js.map +1 -1
- package/dist/tools/property-distribution.d.ts +12 -0
- package/dist/tools/property-distribution.d.ts.map +1 -0
- package/dist/tools/property-distribution.js +168 -0
- package/dist/tools/property-distribution.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +65 -20
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +90 -5
- 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 +173 -43
- 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 +10 -3
- package/dist/tools/search-nodes.js.map +1 -1
- package/dist/tools/search-strings.d.ts +12 -0
- package/dist/tools/search-strings.d.ts.map +1 -0
- package/dist/tools/search-strings.js +182 -0
- package/dist/tools/search-strings.js.map +1 -0
- package/dist/tools/sequence-analysis.d.ts +12 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -0
- package/dist/tools/sequence-analysis.js +244 -0
- package/dist/tools/sequence-analysis.js.map +1 -0
- package/dist/tools/server-status.d.ts +12 -0
- package/dist/tools/server-status.d.ts.map +1 -0
- package/dist/tools/server-status.js +41 -0
- package/dist/tools/server-status.js.map +1 -0
- package/dist/tools/shape-histogram.d.ts.map +1 -1
- package/dist/tools/shape-histogram.js +61 -16
- 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 +38 -15
- 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/snapshot-summary.d.ts.map +1 -1
- package/dist/tools/snapshot-summary.js +55 -13
- package/dist/tools/snapshot-summary.js.map +1 -1
- package/dist/tools/snapshots.d.ts +12 -0
- package/dist/tools/snapshots.d.ts.map +1 -0
- package/dist/tools/snapshots.js +93 -0
- package/dist/tools/snapshots.js.map +1 -0
- package/dist/tools/stale-collections.d.ts.map +1 -1
- package/dist/tools/stale-collections.js +248 -7
- package/dist/tools/stale-collections.js.map +1 -1
- package/dist/tools/trace-dominators.d.ts.map +1 -1
- package/dist/tools/trace-dominators.js +28 -1
- package/dist/tools/trace-dominators.js.map +1 -1
- package/dist/tools/weakmap-entries.d.ts +12 -0
- package/dist/tools/weakmap-entries.d.ts.map +1 -0
- package/dist/tools/weakmap-entries.js +156 -0
- package/dist/tools/weakmap-entries.js.map +1 -0
- package/dist/utils.d.ts +139 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +448 -35
- package/dist/utils.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,156 @@
|
|
|
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, truncateNodeName, errorResult, toolResult, } from '../utils.js';
|
|
13
|
+
export function registerWeakMapEntries(server) {
|
|
14
|
+
server.tool('memlab_weakmap_entries', 'Enumerate the key-value pairs of ONE WeakMap (node_id is REQUIRED — this is not a global scan). WeakMaps back DataStore, private fields, and metadata caches; since keys are weakly held, their entries reveal which objects are associated and what metadata is stored. First locate a WeakMap with memlab_find_nodes_by_class("WeakMap") (or memlab_largest_objects), then pass its node id here.', {
|
|
15
|
+
node_id: z
|
|
16
|
+
.number()
|
|
17
|
+
.describe('REQUIRED. The numeric ID of a single WeakMap node. Find candidates with memlab_find_nodes_by_class("WeakMap"); there is no scan-all-WeakMaps mode.'),
|
|
18
|
+
limit: z
|
|
19
|
+
.number()
|
|
20
|
+
.optional()
|
|
21
|
+
.default(20)
|
|
22
|
+
.describe('Maximum number of entries to return (default 20)'),
|
|
23
|
+
sort_by: z
|
|
24
|
+
.enum(['retained_size', 'retained', 'key_name'])
|
|
25
|
+
.optional()
|
|
26
|
+
.default('retained_size')
|
|
27
|
+
.describe('Sort entries by key retained size ("retained_size", alias "retained") or key name ("key_name"). Default: retained_size.'),
|
|
28
|
+
}, async ({ node_id, limit, sort_by }) => {
|
|
29
|
+
try {
|
|
30
|
+
const snapshot = getSnapshot();
|
|
31
|
+
const node = snapshot.getNodeById(node_id);
|
|
32
|
+
if (!node) {
|
|
33
|
+
return errorResult(`Node with id ${node_id} not found`);
|
|
34
|
+
}
|
|
35
|
+
if (node.name !== 'WeakMap') {
|
|
36
|
+
return errorResult(`@${node_id} is a ${node.name} (${node.type}), not a WeakMap. ` +
|
|
37
|
+
`Use \`memlab_find_nodes_by_class("WeakMap")\` to find WeakMap instances.`);
|
|
38
|
+
}
|
|
39
|
+
const entries = [];
|
|
40
|
+
for (const edge of node.references) {
|
|
41
|
+
const eName = String(edge.name_or_index);
|
|
42
|
+
if (eName !== 'table' && eName !== 'backing_store')
|
|
43
|
+
continue;
|
|
44
|
+
const table = edge.toNode;
|
|
45
|
+
const tableRefs = [];
|
|
46
|
+
for (const te of table.references) {
|
|
47
|
+
if (te.type === 'internal' || te.type === 'hidden')
|
|
48
|
+
continue;
|
|
49
|
+
tableRefs.push(te.toNode);
|
|
50
|
+
}
|
|
51
|
+
// WeakMap tables store key-value pairs: [key1, val1, key2, val2, ...]
|
|
52
|
+
for (let i = 0; i < tableRefs.length - 1; i += 2) {
|
|
53
|
+
const key = tableRefs[i];
|
|
54
|
+
const value = tableRefs[i + 1];
|
|
55
|
+
if (key.id <= 3)
|
|
56
|
+
continue;
|
|
57
|
+
if (key.name === 'undefined' || key.name === 'the_hole')
|
|
58
|
+
continue;
|
|
59
|
+
entries.push({
|
|
60
|
+
key,
|
|
61
|
+
value,
|
|
62
|
+
keyRetained: key.retainedSize,
|
|
63
|
+
valueRetained: value.retainedSize,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
// Fallback: try to read entries from ephemeron edges (some V8 versions)
|
|
69
|
+
if (entries.length === 0) {
|
|
70
|
+
for (const edge of node.references) {
|
|
71
|
+
if (edge.type !== 'weak' &&
|
|
72
|
+
edge.type !== 'property' &&
|
|
73
|
+
edge.type !== 'element')
|
|
74
|
+
continue;
|
|
75
|
+
const target = edge.toNode;
|
|
76
|
+
if (target.id <= 3)
|
|
77
|
+
continue;
|
|
78
|
+
if (target.name === 'undefined' || target.name === 'the_hole')
|
|
79
|
+
continue;
|
|
80
|
+
// Each weak edge points to a key; the corresponding value
|
|
81
|
+
// is the next non-weak edge or accessible through the key's references
|
|
82
|
+
entries.push({
|
|
83
|
+
key: target,
|
|
84
|
+
value: target,
|
|
85
|
+
keyRetained: target.retainedSize,
|
|
86
|
+
valueRetained: 0,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (entries.length === 0) {
|
|
91
|
+
return toolResult(`WeakMap @${node_id} has no enumerable entries.\n\n` +
|
|
92
|
+
`**Note:** V8's WeakMap implementation uses an EphemeronHashTable ` +
|
|
93
|
+
`whose entries may not be fully exposed in the heap snapshot. ` +
|
|
94
|
+
`Try \`memlab_get_references(${node_id})\` to inspect the raw structure.`);
|
|
95
|
+
}
|
|
96
|
+
if (sort_by === 'retained_size' || sort_by === 'retained') {
|
|
97
|
+
entries.sort((a, b) => b.keyRetained +
|
|
98
|
+
b.valueRetained -
|
|
99
|
+
(a.keyRetained + a.valueRetained));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
entries.sort((a, b) => a.key.name.localeCompare(b.key.name));
|
|
103
|
+
}
|
|
104
|
+
const shown = entries.slice(0, limit);
|
|
105
|
+
const totalEntries = entries.length;
|
|
106
|
+
const totalKeyRetained = entries.reduce((s, e) => s + e.keyRetained, 0);
|
|
107
|
+
const totalValueRetained = entries.reduce((s, e) => s + e.valueRetained, 0);
|
|
108
|
+
const headers = [
|
|
109
|
+
'Key ID',
|
|
110
|
+
'Key',
|
|
111
|
+
'Key Retained',
|
|
112
|
+
'Value ID',
|
|
113
|
+
'Value',
|
|
114
|
+
'Value Retained',
|
|
115
|
+
];
|
|
116
|
+
const rightCols = new Set([2, 5]);
|
|
117
|
+
const rows = shown.map(e => {
|
|
118
|
+
const keyName = truncateNodeName(e.key.name, e.key.type, e.key.self_size, 40);
|
|
119
|
+
let valueName;
|
|
120
|
+
if (e.value === e.key) {
|
|
121
|
+
valueName = '(see key)';
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
valueName = truncateNodeName(e.value.name, e.value.type, e.value.self_size, 40);
|
|
125
|
+
if (e.value.isString) {
|
|
126
|
+
const strNode = e.value.toStringNode();
|
|
127
|
+
if (strNode) {
|
|
128
|
+
const val = strNode.stringValue;
|
|
129
|
+
valueName = `"${val.length > 35 ? val.slice(0, 35) + '...' : val}"`;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return [
|
|
134
|
+
`@${e.key.id}`,
|
|
135
|
+
`${keyName} (${e.key.type})`,
|
|
136
|
+
formatBytes(e.keyRetained),
|
|
137
|
+
`@${e.value.id}`,
|
|
138
|
+
`${valueName} (${e.value.type})`,
|
|
139
|
+
formatBytes(e.valueRetained),
|
|
140
|
+
];
|
|
141
|
+
});
|
|
142
|
+
const lines = [
|
|
143
|
+
`WeakMap @${node_id}: ${formatNumber(totalEntries)} entries` +
|
|
144
|
+
(totalEntries > limit ? ` (showing top ${limit})` : ''),
|
|
145
|
+
`Total key retained: ${formatBytes(totalKeyRetained)}, total value retained: ${formatBytes(totalValueRetained)}`,
|
|
146
|
+
'',
|
|
147
|
+
markdownTable(headers, rows, rightCols),
|
|
148
|
+
];
|
|
149
|
+
return toolResult(lines.join('\n'));
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
return errorResult(err);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=weakmap-entries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weakmap-entries.js","sourceRoot":"","sources":["../../src/tools/weakmap-entries.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* @format
|
|
8
8
|
* @oncall memory_lab
|
|
9
9
|
*/
|
|
10
|
-
import type { IHeapNode, IHeapEdge, IHeapSnapshot } from '@memlab/core';
|
|
10
|
+
import type { IHeapNode, IHeapEdge, IHeapSnapshot, HeapNodeIdSet } from '@memlab/core';
|
|
11
|
+
import { ScanTimeoutError, makeScanBudget } from './analysis-budget.js';
|
|
12
|
+
export { ScanTimeoutError, makeScanBudget };
|
|
11
13
|
export interface NodeSummary {
|
|
12
14
|
id: number;
|
|
13
15
|
name: string;
|
|
@@ -37,28 +39,157 @@ export interface OutgoingEdge extends EdgeSummary {
|
|
|
37
39
|
export interface IncomingEdge extends EdgeSummary {
|
|
38
40
|
from_node: NodeSummary;
|
|
39
41
|
}
|
|
40
|
-
export declare function
|
|
42
|
+
export declare function truncateDomToTag(name: string): string;
|
|
43
|
+
export declare function truncateNodeName(name: string, type: string, selfSize: number, maxLen?: number, aggressiveDom?: boolean): string;
|
|
41
44
|
export declare function serializeNodeSummary(node: IHeapNode): NodeSummary;
|
|
42
45
|
export declare function serializeNodeDetail(node: IHeapNode): NodeDetail;
|
|
43
46
|
export declare function serializeOutgoingEdge(edge: IHeapEdge): OutgoingEdge;
|
|
44
47
|
export declare function serializeIncomingEdge(edge: IHeapEdge): IncomingEdge;
|
|
45
48
|
export declare function isNodeWorthInspecting(node: IHeapNode): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Property names that mark a "freshness" timestamp on a TTL/warm cache wrapper
|
|
51
|
+
* object (e.g. `{entries, loadedAt}`, `{items, timestamp}`). Their presence next
|
|
52
|
+
* to a large array/Map means the collection was loaded as a point-in-time
|
|
53
|
+
* snapshot, not appended to over time. Shared by cache-analysis (to recognize
|
|
54
|
+
* the cache shape) and growth-signals (to suppress the append-only
|
|
55
|
+
* false-positive on load-once caches). Feedback round 4 §B/§C.
|
|
56
|
+
*/
|
|
57
|
+
export declare const FRESHNESS_TIMESTAMP_PROPS: ReadonlySet<string>;
|
|
58
|
+
/**
|
|
59
|
+
* True when `node` (typically a large Array/Map) is held by a wrapper object
|
|
60
|
+
* that also carries a freshness-timestamp sibling property — i.e. it is the data
|
|
61
|
+
* side of a `{entries, loadedAt}`-style TTL/warm cache, loaded once rather than
|
|
62
|
+
* grown unboundedly.
|
|
63
|
+
*/
|
|
64
|
+
export declare function hasFreshnessTimestampSibling(node: IHeapNode): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Heuristic: does a (JSON-ish) string look like a cached *failure* response?
|
|
67
|
+
* Cached error payloads are both wasted memory and a signal that an upstream
|
|
68
|
+
* dependency is failing — surfacing them links a memory finding to a likely
|
|
69
|
+
* correctness bug. Conservative: requires a JSON-object/array head plus an
|
|
70
|
+
* explicit failure marker. Feedback round 4 §D.
|
|
71
|
+
*/
|
|
72
|
+
export declare function looksLikeFailurePayload(value: string): boolean;
|
|
46
73
|
export declare function filterLargestObjects(snapshot: IHeapSnapshot, filter: (node: IHeapNode) => boolean, limit: number): IHeapNode[];
|
|
74
|
+
/**
|
|
75
|
+
* Collapse heap nodes that are merely different VIEWS of the same dominator
|
|
76
|
+
* subtree (e.g. on a single in-flight request: Client → Request → closure →
|
|
77
|
+
* Promise → Context → Map all reporting the SAME retained size). Without this,
|
|
78
|
+
* `largest_objects` returns ~20 rows that are all one subtree — pure noise and
|
|
79
|
+
* wasted tokens (feedback §A.2).
|
|
80
|
+
*
|
|
81
|
+
* Two nodes are treated as the same subtree ONLY when (a) their retained sizes
|
|
82
|
+
* are within `epsilon` of each other AND (b) one dominates the other within a
|
|
83
|
+
* bounded dominator walk — so unrelated objects that merely share a byte count
|
|
84
|
+
* are never collapsed. `candidates` must be pre-sorted by retained size desc;
|
|
85
|
+
* the highest dominator (ancestor) is kept as the representative, annotated with
|
|
86
|
+
* `mergedCount` = how many views were folded into it.
|
|
87
|
+
*/
|
|
88
|
+
export declare function collapseDominatorSubtrees(candidates: IHeapNode[], limit: number, opts?: {
|
|
89
|
+
epsilon?: number;
|
|
90
|
+
maxWalk?: number;
|
|
91
|
+
}): Array<{
|
|
92
|
+
node: IHeapNode;
|
|
93
|
+
mergedCount: number;
|
|
94
|
+
}>;
|
|
47
95
|
export type OutputMode = 'full' | 'count' | 'ids';
|
|
48
96
|
export interface QueryNodesResult {
|
|
49
97
|
total_count: number;
|
|
50
98
|
nodes?: NodeSummary[];
|
|
51
99
|
ids?: number[];
|
|
100
|
+
timed_out?: boolean;
|
|
52
101
|
}
|
|
53
102
|
export declare function queryNodes(snapshot: IHeapSnapshot, filter: (node: IHeapNode) => boolean, opts: {
|
|
54
103
|
limit: number;
|
|
55
104
|
offset: number;
|
|
56
105
|
outputMode: OutputMode;
|
|
106
|
+
budget?: {
|
|
107
|
+
tick: () => void;
|
|
108
|
+
};
|
|
57
109
|
}): QueryNodesResult;
|
|
110
|
+
/**
|
|
111
|
+
* Dominator-deduped retained size for a set of nodes, with a BOUNDED upward
|
|
112
|
+
* dominator walk (default 500 steps, mirroring auto-investigate's
|
|
113
|
+
* `isDominatorAncestor` maxWalk). For each node we walk up its dominator chain
|
|
114
|
+
* looking for another in-set ancestor; if one is found the node is dominated
|
|
115
|
+
* (its bytes are already counted by that ancestor) so we skip it, otherwise we
|
|
116
|
+
* add its retained size.
|
|
117
|
+
*
|
|
118
|
+
* Unlike `@memlab/core`'s `aggregateDominatorMetrics`, the walk is capped and
|
|
119
|
+
* allocates no per-node Set, so a pathological deep dominator chain (e.g. a long
|
|
120
|
+
* PromiseReaction linked list) cannot make this blow up. Trade-off: if a node's
|
|
121
|
+
* nearest in-set dominator is deeper than `maxWalk`, we conservatively KEEP it
|
|
122
|
+
* (treat it as maximal), which can OVER-count — so `exact` is returned `false`
|
|
123
|
+
* whenever any node's walk was truncated, letting callers mark the figure as an
|
|
124
|
+
* upper bound. Calls `tickAnalysis()` per node so it also honors the wall-clock
|
|
125
|
+
* guardrail.
|
|
126
|
+
*/
|
|
127
|
+
export declare function boundedDominatorRetainedSize(ids: HeapNodeIdSet, snapshot: IHeapSnapshot, maxWalk?: number): {
|
|
128
|
+
retained: number;
|
|
129
|
+
exact: boolean;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Best-effort detection of which app a Node snapshot came from, by tallying the
|
|
133
|
+
* `/app(s)/<name>/` segment in bundle paths embedded throughout the heap (string
|
|
134
|
+
* node values, function/script names). Returns the most common segment, or null
|
|
135
|
+
* if nothing decisive is found (Feedback round 3 §3d).
|
|
136
|
+
*/
|
|
137
|
+
export declare function detectAppName(snapshot: IHeapSnapshot): string | null;
|
|
138
|
+
/**
|
|
139
|
+
* Recognize retainer paths that route through runtime instrumentation — a
|
|
140
|
+
* patched global `console`, OpenTelemetry context chains, structured loggers,
|
|
141
|
+
* etc. Such paths are frequently reported as the GC owner even though the
|
|
142
|
+
* *logical* owner (a module cache, an OTel logger, a source-map cache) lives
|
|
143
|
+
* elsewhere and is only incidentally reachable via the instrumentation's
|
|
144
|
+
* captured-closure → `context` → `previous` → `Context` chain. Returns a short
|
|
145
|
+
* annotation when the path looks instrumentation-routed, else null
|
|
146
|
+
* (Feedback round 3 §3a).
|
|
147
|
+
*/
|
|
148
|
+
export declare function instrumentationRetainerNote(steps: Array<{
|
|
149
|
+
name: string;
|
|
150
|
+
edgeName?: string;
|
|
151
|
+
}>): string | null;
|
|
58
152
|
export declare function formatBytes(bytes: number): string;
|
|
59
153
|
export declare function formatNumber(n: number): string;
|
|
60
154
|
export declare function markdownTable(headers: string[], rows: string[][], alignRight?: Set<number>): string;
|
|
61
155
|
export declare function formatNodeInline(id: number, name: string, type: string, selfSize?: number): string;
|
|
156
|
+
/**
|
|
157
|
+
* One step of a retainer path, root-first. `edgeName` is the name of the edge
|
|
158
|
+
* that points INTO this node from its retainer (i.e. parent → this node, the
|
|
159
|
+
* property / element / context slot through which the parent holds this node).
|
|
160
|
+
* The GC root (first step) has no incoming edge. `collapsedBefore` records how
|
|
161
|
+
* many uninteresting internal nodes were elided immediately above this node.
|
|
162
|
+
*/
|
|
163
|
+
export interface RetainerTreeStep {
|
|
164
|
+
id: number;
|
|
165
|
+
name: string;
|
|
166
|
+
type: string;
|
|
167
|
+
retainedSize?: number;
|
|
168
|
+
selfSize?: number;
|
|
169
|
+
edgeName?: string;
|
|
170
|
+
collapsedBefore?: number;
|
|
171
|
+
collapsedNote?: string;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Render a retainer path so it reads in a single, unambiguous direction: the GC
|
|
175
|
+
* root is at the top, and **every node is retained by the one above it**. The
|
|
176
|
+
* edge that connects a parent to its child is embedded in the connector
|
|
177
|
+
* (`└─ .prop →` / `└─ [2] →`, ladder: `↓ .prop`), and sizes as `— <bytes>`.
|
|
178
|
+
*
|
|
179
|
+
* Shallow chains use a nested indented tree (one indent level = one hop).
|
|
180
|
+
* **Deep chains automatically switch to a flat `↓` ladder** (controlled by
|
|
181
|
+
* `maxTreeDepth`, default 8) so growing indentation never pushes the leaf node
|
|
182
|
+
* off the right edge of a narrow terminal.
|
|
183
|
+
*
|
|
184
|
+
* This deliberately avoids the older inline style that mixed `←` (retained-by)
|
|
185
|
+
* and `→` (references) arrows on the same line, which made the direction of a
|
|
186
|
+
* trace genuinely hard to read in analysis output and diff summaries. Always
|
|
187
|
+
* prefer this renderer when presenting a retainer chain to a human.
|
|
188
|
+
*/
|
|
189
|
+
export declare function formatRetainerTree(steps: RetainerTreeStep[], opts?: {
|
|
190
|
+
showSizes?: boolean;
|
|
191
|
+
maxTreeDepth?: number;
|
|
192
|
+
}): string;
|
|
62
193
|
export declare function formatNodeSummaryTable(nodes: NodeSummary[]): string;
|
|
63
194
|
export declare function formatQueryNodesResult(result: QueryNodesResult, offset?: number): string;
|
|
64
195
|
export declare function snapshotHeader(): string;
|
|
@@ -74,6 +205,12 @@ export declare function toolResult(text: string): {
|
|
|
74
205
|
text: string;
|
|
75
206
|
}[];
|
|
76
207
|
};
|
|
208
|
+
/**
|
|
209
|
+
* Whether tools should omit "Suggested next steps" / "How to fix" trailers.
|
|
210
|
+
* Honors the session-level `suppressSuggestions` config so callers can trim
|
|
211
|
+
* repeated boilerplate tokens across a long investigation.
|
|
212
|
+
*/
|
|
213
|
+
export declare function suggestionsSuppressed(): boolean;
|
|
77
214
|
export declare function jsonResult(data: unknown): {
|
|
78
215
|
content: {
|
|
79
216
|
type: "text";
|
package/dist/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACd,MAAM,cAAc,CAAC;AAStB,OAAO,EACL,gBAAgB,EAChB,cAAc,EAEf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAC,gBAAgB,EAAE,cAAc,EAAC,CAAC;AAE1C,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,SAAS,EAAE,WAAW,CAAC;CACxB;AA8BD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAuBrD;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,SAAM,EACZ,aAAa,UAAQ,GACpB,MAAM,CA4BR;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW,CAQjE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,UAAU,CAgC/D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,YAAY,CAMnE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,YAAY,CAMnE;AAiBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAW9D;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAexD,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAerE;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAS9D;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,EACpC,KAAK,EAAE,MAAM,GACZ,SAAS,EAAE,CAoBb;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,SAAS,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAM,GAC9C,KAAK,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,CAAC,CAkC/C;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,UAAU,CACxB,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,EACpC,IAAI,EAAE;IACJ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,IAAI,CAAA;KAAC,CAAC;CAC7B,GACA,gBAAgB,CAyDlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,aAAa,EAClB,QAAQ,EAAE,aAAa,EACvB,OAAO,SAAM,GACZ;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,CAgCpC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CA+BpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,GAC9C,MAAM,GAAG,IAAI,CAwBf;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,EAAE,MAAM,EAAE,EAAE,EAChB,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GACvB,MAAM,CAgCR;AAED,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAIR;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAqDD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,gBAAgB,EAAE,EACzB,IAAI,GAAE;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAM,GACtD,MAAM,CAoCR;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM,CAWnE;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,gBAAgB,EACxB,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,CAoBR;AAED,wBAAgB,cAAc,IAAI,MAAM,CAUvC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM;;;;;EAEtC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM;;;;;EAItC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO;;;;;EAEvC;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO;;;;;;EAMvC"}
|