@memlab/mcp-server 2.52.0 → 2.86.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 +22 -2
- package/dist/anonymized-snapshot.d.ts +75 -0
- package/dist/anonymized-snapshot.d.ts.map +1 -0
- package/dist/anonymized-snapshot.js +101 -0
- package/dist/anonymized-snapshot.js.map +1 -0
- package/dist/eval-hints.d.ts +41 -0
- package/dist/eval-hints.d.ts.map +1 -0
- package/dist/eval-hints.js +115 -0
- package/dist/eval-hints.js.map +1 -0
- package/dist/heap-budget.d.ts +32 -0
- package/dist/heap-budget.d.ts.map +1 -0
- package/dist/heap-budget.js +90 -0
- package/dist/heap-budget.js.map +1 -0
- package/dist/heap-shapes.d.ts +148 -0
- package/dist/heap-shapes.d.ts.map +1 -0
- package/dist/heap-shapes.js +193 -0
- package/dist/heap-shapes.js.map +1 -0
- package/dist/heap-state.d.ts +20 -0
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +8 -1
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +64 -1
- package/dist/index.js.map +1 -1
- package/dist/react-shapes.d.ts +42 -0
- package/dist/react-shapes.d.ts.map +1 -0
- package/dist/react-shapes.js +149 -0
- package/dist/react-shapes.js.map +1 -0
- package/dist/server-version.d.ts +19 -0
- package/dist/server-version.d.ts.map +1 -0
- package/dist/server-version.js +19 -0
- package/dist/server-version.js.map +1 -0
- package/dist/snapshot-borrow.d.ts +67 -0
- package/dist/snapshot-borrow.d.ts.map +1 -0
- package/dist/snapshot-borrow.js +113 -0
- package/dist/snapshot-borrow.js.map +1 -0
- package/dist/string-index.d.ts.map +1 -1
- package/dist/string-index.js +8 -0
- package/dist/string-index.js.map +1 -1
- package/dist/tools/analyze-run.d.ts.map +1 -1
- package/dist/tools/analyze-run.js +79 -18
- package/dist/tools/analyze-run.js.map +1 -1
- package/dist/tools/anonymize-snapshot.d.ts +12 -0
- package/dist/tools/anonymize-snapshot.d.ts.map +1 -0
- package/dist/tools/anonymize-snapshot.js +159 -0
- package/dist/tools/anonymize-snapshot.js.map +1 -0
- package/dist/tools/app-config.d.ts +12 -0
- package/dist/tools/app-config.d.ts.map +1 -0
- package/dist/tools/app-config.js +217 -0
- package/dist/tools/app-config.js.map +1 -0
- package/dist/tools/app-heap.d.ts +18 -0
- package/dist/tools/app-heap.d.ts.map +1 -1
- package/dist/tools/app-heap.js +12 -46
- package/dist/tools/app-heap.js.map +1 -1
- package/dist/tools/artifact-budget.d.ts +12 -0
- package/dist/tools/artifact-budget.d.ts.map +1 -0
- package/dist/tools/artifact-budget.js +219 -0
- package/dist/tools/artifact-budget.js.map +1 -0
- package/dist/tools/async-census.d.ts +12 -0
- package/dist/tools/async-census.d.ts.map +1 -0
- package/dist/tools/async-census.js +243 -0
- package/dist/tools/async-census.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +54 -5
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/batch.d.ts.map +1 -1
- package/dist/tools/batch.js +33 -5
- package/dist/tools/batch.js.map +1 -1
- package/dist/tools/cache-analysis.d.ts +15 -0
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +85 -10
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/census-diff.d.ts +55 -0
- package/dist/tools/census-diff.d.ts.map +1 -0
- package/dist/tools/census-diff.js +228 -0
- package/dist/tools/census-diff.js.map +1 -0
- package/dist/tools/chain-walk.d.ts +12 -0
- package/dist/tools/chain-walk.d.ts.map +1 -0
- package/dist/tools/chain-walk.js +184 -0
- package/dist/tools/chain-walk.js.map +1 -0
- package/dist/tools/collection-diff.d.ts +44 -0
- package/dist/tools/collection-diff.d.ts.map +1 -0
- package/dist/tools/collection-diff.js +343 -0
- package/dist/tools/collection-diff.js.map +1 -0
- package/dist/tools/collection-trend.d.ts.map +1 -1
- package/dist/tools/collection-trend.js +2 -2
- package/dist/tools/collection-trend.js.map +1 -1
- package/dist/tools/detached-dom.d.ts +3 -0
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +78 -3
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts.map +1 -1
- package/dist/tools/dev-artifacts.js +221 -3
- 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 +18 -2
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/dom-audit.d.ts +37 -0
- package/dist/tools/dom-audit.d.ts.map +1 -0
- package/dist/tools/dom-audit.js +247 -0
- package/dist/tools/dom-audit.js.map +1 -0
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +3 -2
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval-across.d.ts +12 -0
- package/dist/tools/eval-across.d.ts.map +1 -0
- package/dist/tools/eval-across.js +135 -0
- package/dist/tools/eval-across.js.map +1 -0
- package/dist/tools/eval.d.ts +78 -0
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +2270 -701
- 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 +42 -17
- package/dist/tools/event-listener-leaks.js.map +1 -1
- package/dist/tools/event-registry.d.ts.map +1 -1
- package/dist/tools/event-registry.js +42 -8
- package/dist/tools/event-registry.js.map +1 -1
- package/dist/tools/explain-delta.d.ts.map +1 -1
- package/dist/tools/explain-delta.js +61 -10
- package/dist/tools/explain-delta.js.map +1 -1
- package/dist/tools/finding-index.d.ts +181 -0
- package/dist/tools/finding-index.d.ts.map +1 -1
- package/dist/tools/finding-index.js +343 -24
- package/dist/tools/finding-index.js.map +1 -1
- package/dist/tools/get-value.d.ts +16 -0
- package/dist/tools/get-value.d.ts.map +1 -1
- package/dist/tools/get-value.js +96 -2
- package/dist/tools/get-value.js.map +1 -1
- package/dist/tools/hypothesis.d.ts.map +1 -1
- package/dist/tools/hypothesis.js +117 -58
- package/dist/tools/hypothesis.js.map +1 -1
- package/dist/tools/id-space-audit.d.ts +12 -0
- package/dist/tools/id-space-audit.d.ts.map +1 -0
- package/dist/tools/id-space-audit.js +262 -0
- package/dist/tools/id-space-audit.js.map +1 -0
- package/dist/tools/identify.d.ts +12 -0
- package/dist/tools/identify.d.ts.map +1 -0
- package/dist/tools/identify.js +205 -0
- package/dist/tools/identify.js.map +1 -0
- package/dist/tools/identity-diff.d.ts +12 -0
- package/dist/tools/identity-diff.d.ts.map +1 -0
- package/dist/tools/identity-diff.js +188 -0
- package/dist/tools/identity-diff.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -1
- package/dist/tools/intern-opportunities.js +4 -3
- package/dist/tools/intern-opportunities.js.map +1 -1
- package/dist/tools/ladder-probe.d.ts +65 -0
- package/dist/tools/ladder-probe.d.ts.map +1 -0
- package/dist/tools/ladder-probe.js +445 -0
- package/dist/tools/ladder-probe.js.map +1 -0
- package/dist/tools/ladder.d.ts.map +1 -1
- package/dist/tools/ladder.js +5 -5
- package/dist/tools/ladder.js.map +1 -1
- package/dist/tools/leak-report.d.ts +23 -0
- package/dist/tools/leak-report.d.ts.map +1 -1
- package/dist/tools/leak-report.js +153 -11
- package/dist/tools/leak-report.js.map +1 -1
- package/dist/tools/load-snapshot.d.ts +11 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +83 -10
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/metric.d.ts +13 -0
- package/dist/tools/metric.d.ts.map +1 -0
- package/dist/tools/metric.js +185 -0
- package/dist/tools/metric.js.map +1 -0
- package/dist/tools/module-attribution.d.ts +36 -0
- package/dist/tools/module-attribution.d.ts.map +1 -0
- package/dist/tools/module-attribution.js +235 -0
- package/dist/tools/module-attribution.js.map +1 -0
- package/dist/tools/next-measurement.d.ts +26 -0
- package/dist/tools/next-measurement.d.ts.map +1 -0
- package/dist/tools/next-measurement.js +149 -0
- package/dist/tools/next-measurement.js.map +1 -0
- package/dist/tools/object-cost-breakdown.d.ts.map +1 -1
- package/dist/tools/object-cost-breakdown.js +64 -0
- package/dist/tools/object-cost-breakdown.js.map +1 -1
- package/dist/tools/population-vs-owners.d.ts +12 -0
- package/dist/tools/population-vs-owners.d.ts.map +1 -0
- package/dist/tools/population-vs-owners.js +183 -0
- package/dist/tools/population-vs-owners.js.map +1 -0
- package/dist/tools/property-names.d.ts +29 -0
- package/dist/tools/property-names.d.ts.map +1 -0
- package/dist/tools/property-names.js +131 -0
- package/dist/tools/property-names.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +7 -1
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/react-owners.d.ts +12 -0
- package/dist/tools/react-owners.d.ts.map +1 -0
- package/dist/tools/react-owners.js +167 -0
- package/dist/tools/react-owners.js.map +1 -0
- package/dist/tools/react-update-queues.d.ts +12 -0
- package/dist/tools/react-update-queues.d.ts.map +1 -0
- package/dist/tools/react-update-queues.js +173 -0
- package/dist/tools/react-update-queues.js.map +1 -0
- package/dist/tools/replicate.d.ts +49 -0
- package/dist/tools/replicate.d.ts.map +1 -0
- package/dist/tools/replicate.js +241 -0
- package/dist/tools/replicate.js.map +1 -0
- package/dist/tools/retainer-diff.d.ts +12 -0
- package/dist/tools/retainer-diff.d.ts.map +1 -0
- package/dist/tools/retainer-diff.js +168 -0
- package/dist/tools/retainer-diff.js.map +1 -0
- package/dist/tools/retainer-summary.d.ts +17 -0
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +85 -22
- 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 +11 -1
- package/dist/tools/retainer-trace.js.map +1 -1
- package/dist/tools/round-audit.d.ts +66 -0
- package/dist/tools/round-audit.d.ts.map +1 -0
- package/dist/tools/round-audit.js +258 -0
- package/dist/tools/round-audit.js.map +1 -0
- package/dist/tools/round-digest.d.ts +12 -0
- package/dist/tools/round-digest.d.ts.map +1 -0
- package/dist/tools/round-digest.js +190 -0
- package/dist/tools/round-digest.js.map +1 -0
- package/dist/tools/script-census.d.ts +12 -0
- package/dist/tools/script-census.d.ts.map +1 -0
- package/dist/tools/script-census.js +182 -0
- package/dist/tools/script-census.js.map +1 -0
- package/dist/tools/sequence-analysis.d.ts +4 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -1
- package/dist/tools/sequence-analysis.js +53 -9
- package/dist/tools/sequence-analysis.js.map +1 -1
- package/dist/tools/server-status.d.ts.map +1 -1
- package/dist/tools/server-status.js +4 -1
- package/dist/tools/server-status.js.map +1 -1
- package/dist/tools/settle-check.d.ts +12 -0
- package/dist/tools/settle-check.d.ts.map +1 -0
- package/dist/tools/settle-check.js +188 -0
- package/dist/tools/settle-check.js.map +1 -0
- package/dist/tools/sliced-strings.d.ts.map +1 -1
- package/dist/tools/sliced-strings.js +2 -1
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshots.d.ts.map +1 -1
- package/dist/tools/snapshots.js +24 -6
- package/dist/tools/snapshots.js.map +1 -1
- package/dist/tools/sparse-elements.d.ts +12 -0
- package/dist/tools/sparse-elements.d.ts.map +1 -0
- package/dist/tools/sparse-elements.js +215 -0
- package/dist/tools/sparse-elements.js.map +1 -0
- package/dist/tools/stale-collections.d.ts +17 -0
- package/dist/tools/stale-collections.d.ts.map +1 -1
- package/dist/tools/stale-collections.js +28 -0
- package/dist/tools/stale-collections.js.map +1 -1
- package/dist/tools/string-patterns.d.ts.map +1 -1
- package/dist/tools/string-patterns.js +2 -1
- package/dist/tools/string-patterns.js.map +1 -1
- package/dist/tools/tools-index.d.ts.map +1 -1
- package/dist/tools/tools-index.js +155 -5
- package/dist/tools/tools-index.js.map +1 -1
- package/dist/tools/trace-all.d.ts +42 -0
- package/dist/tools/trace-all.d.ts.map +1 -0
- package/dist/tools/trace-all.js +263 -0
- package/dist/tools/trace-all.js.map +1 -0
- package/dist/tools/unit-cost.d.ts +12 -0
- package/dist/tools/unit-cost.d.ts.map +1 -0
- package/dist/tools/unit-cost.js +219 -0
- package/dist/tools/unit-cost.js.map +1 -0
- package/dist/tools/verify-fix.d.ts.map +1 -1
- package/dist/tools/verify-fix.js +11 -3
- package/dist/tools/verify-fix.js.map +1 -1
- package/dist/tools/weakref-census.d.ts +15 -0
- package/dist/tools/weakref-census.d.ts.map +1 -0
- package/dist/tools/weakref-census.js +147 -0
- package/dist/tools/weakref-census.js.map +1 -0
- package/dist/tools/what-if.d.ts +12 -0
- package/dist/tools/what-if.d.ts.map +1 -0
- package/dist/tools/what-if.js +285 -0
- package/dist/tools/what-if.js.map +1 -0
- package/dist/utils.d.ts +92 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +172 -5
- package/dist/utils.js.map +1 -1
- package/package.json +3 -3
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* @oncall memory_lab
|
|
9
9
|
*/
|
|
10
10
|
import { z } from 'zod';
|
|
11
|
-
import { getSnapshotByHandle, getMetadataByHandle, getCurrentHandle, listSnapshots, } from '../heap-state.js';
|
|
11
|
+
import { getSnapshotByHandle, getMetadataByHandle, getCurrentHandle, listSnapshots, findResidentByPath, } from '../heap-state.js';
|
|
12
|
+
import { getRegisteredTool } from '../tool-registry.js';
|
|
12
13
|
import { formatBytes, formatNumber, markdownTable, errorResult, toolResult, } from '../utils.js';
|
|
13
14
|
import { classifyArtifact } from '../artifact-classes.js';
|
|
14
15
|
import { normalizeClassName } from './sequence-analysis.js';
|
|
@@ -54,13 +55,46 @@ function attributeByOwner(snapshot) {
|
|
|
54
55
|
});
|
|
55
56
|
return { byOwner, totalSelf };
|
|
56
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a `baseline` that turned out to be a file path by loading it into the
|
|
60
|
+
* session (keeping whatever is already resident), and return its handle.
|
|
61
|
+
*
|
|
62
|
+
* Dispatches to the registered `memlab_load_snapshot` handler rather than
|
|
63
|
+
* duplicating its guards — the ceilings, the memory-headroom check and the
|
|
64
|
+
* already-resident fast path all still apply.
|
|
65
|
+
*/
|
|
66
|
+
async function loadSnapshotByPath(filePath) {
|
|
67
|
+
const already = findResidentByPath(filePath);
|
|
68
|
+
if (already != null)
|
|
69
|
+
return already.handle;
|
|
70
|
+
const entry = getRegisteredTool('memlab_load_snapshot');
|
|
71
|
+
if (entry == null)
|
|
72
|
+
return null;
|
|
73
|
+
try {
|
|
74
|
+
const args = entry.shape != null
|
|
75
|
+
? z
|
|
76
|
+
.object(entry.shape)
|
|
77
|
+
.parse({ file_path: filePath, keep_previous: true })
|
|
78
|
+
: { file_path: filePath, keep_previous: true };
|
|
79
|
+
await entry.handler(args, {});
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return findResidentByPath(filePath)?.handle ?? null;
|
|
85
|
+
}
|
|
57
86
|
export function registerExplainDelta(server) {
|
|
58
87
|
server.tool('memlab_explain_delta', 'Explain WHERE a heap grew between two loaded snapshots, attributed by dominator (who owns the new bytes) rather than by class (what the new bytes are). ' +
|
|
59
88
|
'"Object grew by 99,418 instances" does not tell you what to fix; "the bytes hanging off CometStyleXSheet grew by 12 MB" does. Every node\'s SELF size is attributed to its immediate dominator\'s class and the two attributions are differenced, so the numbers partition the heap and add up — unlike a per-class sum of retained sizes, which double-counts nested objects and can exceed the heap. ' +
|
|
60
89
|
'Known measurement-artifact owners (JIT warmup, CDP inspector, a11y caches, captured Error stacks) are flagged so an inspector-driven delta is not read as an application regression. Both snapshots must be resident: load them with keep_previous:true.', {
|
|
61
90
|
baseline_handle: z
|
|
62
91
|
.string()
|
|
63
|
-
.
|
|
92
|
+
.optional()
|
|
93
|
+
.describe('Handle of the earlier snapshot (memlab_snapshots lists them). Its siblings memlab_artifact_budget and memlab_census_diff take a `baseline` PATH instead, so `baseline` is accepted here as an alias — a batch authored against the recipe used to fail argument validation on this one parameter alone.'),
|
|
94
|
+
baseline: z
|
|
95
|
+
.string()
|
|
96
|
+
.optional()
|
|
97
|
+
.describe('Alias for `baseline_handle`. Accepts a resident handle, or a file path — which is auto-loaded with keep_previous so the whole batch does not have to be re-authored.'),
|
|
64
98
|
target_handle: z
|
|
65
99
|
.string()
|
|
66
100
|
.optional()
|
|
@@ -80,29 +114,46 @@ export function registerExplainDelta(server) {
|
|
|
80
114
|
.optional()
|
|
81
115
|
.default(false)
|
|
82
116
|
.describe('Include owners that are known measurement artifacts (default false: counted in a one-line summary instead).'),
|
|
83
|
-
}, async ({ baseline_handle, target_handle, limit, min_delta_bytes, include_artifacts, }) => {
|
|
117
|
+
}, async ({ baseline_handle, baseline: baselineAlias, target_handle, limit, min_delta_bytes, include_artifacts, }) => {
|
|
84
118
|
try {
|
|
119
|
+
let baselineRef = baseline_handle ?? baselineAlias;
|
|
120
|
+
if (baselineRef == null) {
|
|
121
|
+
return errorResult('Pass `baseline_handle` (a resident snapshot handle) or `baseline` (a handle or a file path).');
|
|
122
|
+
}
|
|
123
|
+
// A path where a handle was expected is the documented sibling spelling,
|
|
124
|
+
// not a mistake: `artifact_budget` and `census_diff` both take paths.
|
|
125
|
+
// Loading it is exactly what the "must be resident" error tells the
|
|
126
|
+
// caller to go and do by hand, and a re-authored batch costs a reload of
|
|
127
|
+
// every rung.
|
|
128
|
+
if (getSnapshotByHandle(baselineRef) == null &&
|
|
129
|
+
/[/\\.]/.test(baselineRef)) {
|
|
130
|
+
const loaded = await loadSnapshotByPath(baselineRef);
|
|
131
|
+
if (loaded == null) {
|
|
132
|
+
return errorResult(`\`baseline\` "${baselineRef}" is neither a resident handle nor a readable snapshot file.`);
|
|
133
|
+
}
|
|
134
|
+
baselineRef = loaded;
|
|
135
|
+
}
|
|
85
136
|
const targetHandle = target_handle ?? getCurrentHandle();
|
|
86
137
|
if (targetHandle == null) {
|
|
87
138
|
return errorResult('No current snapshot; pass target_handle.');
|
|
88
139
|
}
|
|
89
|
-
if (targetHandle ===
|
|
140
|
+
if (targetHandle === baselineRef) {
|
|
90
141
|
return errorResult('baseline_handle and target_handle are the same snapshot.');
|
|
91
142
|
}
|
|
92
|
-
const
|
|
143
|
+
const baselineSnapshot = getSnapshotByHandle(baselineRef);
|
|
93
144
|
const target = getSnapshotByHandle(targetHandle);
|
|
94
|
-
if (
|
|
145
|
+
if (baselineSnapshot == null || target == null) {
|
|
95
146
|
const available = listSnapshots()
|
|
96
147
|
.map(m => m.handle)
|
|
97
148
|
.join(', ');
|
|
98
|
-
return errorResult(`Both snapshots must be resident. Missing: ${
|
|
149
|
+
return errorResult(`Both snapshots must be resident. Missing: ${baselineSnapshot == null ? baselineRef : targetHandle}. Resident: ${available || '(none)'}. Load with memlab_load_snapshot({file_path, keep_previous: true}).`);
|
|
99
150
|
}
|
|
100
|
-
for (const h of [
|
|
151
|
+
for (const h of [baselineRef, targetHandle]) {
|
|
101
152
|
if (getMetadataByHandle(h)?.light) {
|
|
102
153
|
return errorResult(`Snapshot "${h}" was loaded in LIGHT mode and has no dominator tree, which this attribution requires. Reload it without light.`);
|
|
103
154
|
}
|
|
104
155
|
}
|
|
105
|
-
const a = attributeByOwner(
|
|
156
|
+
const a = attributeByOwner(baselineSnapshot);
|
|
106
157
|
const b = attributeByOwner(target);
|
|
107
158
|
const rows = [];
|
|
108
159
|
const owners = new Set([...a.byOwner.keys(), ...b.byOwner.keys()]);
|
|
@@ -123,7 +174,7 @@ export function registerExplainDelta(server) {
|
|
|
123
174
|
}
|
|
124
175
|
const totalDelta = b.totalSelf - a.totalSelf;
|
|
125
176
|
const lines = [
|
|
126
|
-
`## Heap delta by owner: "${
|
|
177
|
+
`## Heap delta by owner: "${baselineRef}" → "${targetHandle}"`,
|
|
127
178
|
'',
|
|
128
179
|
`Total self size ${totalDelta >= 0 ? 'grew' : 'shrank'} by **${formatBytes(Math.abs(totalDelta))}** (${formatBytes(a.totalSelf)} → ${formatBytes(b.totalSelf)}).`,
|
|
129
180
|
'',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain-delta.js","sourceRoot":"","sources":["../../src/tools/explain-delta.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,
|
|
1
|
+
{"version":3,"file":"explain-delta.js","sourceRoot":"","sources":["../../src/tools/explain-delta.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,98 @@
|
|
|
8
8
|
* @oncall memory_lab
|
|
9
9
|
*/
|
|
10
10
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
/**
|
|
13
|
+
* A cross-round index of leak findings, keyed by a normalized retainer-path
|
|
14
|
+
* signature.
|
|
15
|
+
*
|
|
16
|
+
* The problem this solves is the most expensive one a hunt hits: rounds
|
|
17
|
+
* re-discover leaks that are already known or already fixed. One measured round
|
|
18
|
+
* produced three findings — a listener accumulation, a completion-map grower and
|
|
19
|
+
* a module-registry grower — all three of which were known, two already fixed
|
|
20
|
+
* behind gates, and the first only visible because the gated fixes were not
|
|
21
|
+
* enabled. That is an entire round spent re-deriving history.
|
|
22
|
+
*
|
|
23
|
+
* Why a retainer-path signature rather than the class name: the class that grows
|
|
24
|
+
* is rarely distinctive (`Object`, `Array`, `(object properties)` are the top
|
|
25
|
+
* growers in almost every heap), while the PATH that retains it is. Node ids,
|
|
26
|
+
* array indices and per-instance scope ids differ per capture, so they are
|
|
27
|
+
* stripped; what remains — the ordered edge names and class names — is stable
|
|
28
|
+
* across captures of the same leak and different between different leaks.
|
|
29
|
+
*
|
|
30
|
+
* Deliberately local (a JSON file), not a service: the index is only useful if
|
|
31
|
+
* it is written by default on every round, and anything requiring a backend
|
|
32
|
+
* would not be. It is seeded from prior runs' manifests.
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Where the index lives, most specific wins.
|
|
36
|
+
*
|
|
37
|
+
* The default is a per-machine home directory, and that default is the reason
|
|
38
|
+
* the tool has already produced a wrong verdict: an index with no history
|
|
39
|
+
* answers `check` with **NEW** for a finding that is fully documented and
|
|
40
|
+
* already has a fix diff. A home-dir file cannot be shared, does not survive a
|
|
41
|
+
* host change, and is empty on every new devserver — so the failure recurs for
|
|
42
|
+
* every operator rather than once.
|
|
43
|
+
*
|
|
44
|
+
* `MEMLAB_FINDINGS_INDEX` therefore points at a checked-in, shared file, and
|
|
45
|
+
* `workstream` scopes several of them side by side. The home-dir path is kept as
|
|
46
|
+
* the fallback so nothing that already works breaks.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveIndexPath(workstream?: string): string;
|
|
49
|
+
interface Finding {
|
|
50
|
+
fingerprint: string;
|
|
51
|
+
signature: string;
|
|
52
|
+
growing_classes: string[];
|
|
53
|
+
first_seen_round: string;
|
|
54
|
+
last_seen_round: string;
|
|
55
|
+
status: 'new' | 'known' | 'fixed';
|
|
56
|
+
fixed_behind?: string;
|
|
57
|
+
note?: string;
|
|
58
|
+
seen_count: number;
|
|
59
|
+
}
|
|
60
|
+
interface FindingIndex {
|
|
61
|
+
version: number;
|
|
62
|
+
findings: Record<string, Finding>;
|
|
63
|
+
combos_driven: Record<string, string[]>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Findings accepted by `action: "import"`.
|
|
67
|
+
*
|
|
68
|
+
* Loose on purpose: the source is a hand-maintained team document or a previous
|
|
69
|
+
* round's notes, and rejecting a row for a missing optional field would mean the
|
|
70
|
+
* bootstrap does not happen at all — which is the status quo this fixes.
|
|
71
|
+
*/
|
|
72
|
+
declare const IMPORTED_FINDING_SCHEMA: z.ZodObject<{
|
|
73
|
+
retainer_path: z.ZodOptional<z.ZodString>;
|
|
74
|
+
signature: z.ZodOptional<z.ZodString>;
|
|
75
|
+
growing_classes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
76
|
+
round: z.ZodOptional<z.ZodString>;
|
|
77
|
+
status: z.ZodOptional<z.ZodEnum<["new", "known", "fixed"]>>;
|
|
78
|
+
fixed_behind: z.ZodOptional<z.ZodString>;
|
|
79
|
+
note: z.ZodOptional<z.ZodString>;
|
|
80
|
+
}, "strip", z.ZodTypeAny, {
|
|
81
|
+
status?: "fixed" | "new" | "known" | undefined;
|
|
82
|
+
note?: string | undefined;
|
|
83
|
+
retainer_path?: string | undefined;
|
|
84
|
+
signature?: string | undefined;
|
|
85
|
+
growing_classes?: string[] | undefined;
|
|
86
|
+
round?: string | undefined;
|
|
87
|
+
fixed_behind?: string | undefined;
|
|
88
|
+
}, {
|
|
89
|
+
status?: "fixed" | "new" | "known" | undefined;
|
|
90
|
+
note?: string | undefined;
|
|
91
|
+
retainer_path?: string | undefined;
|
|
92
|
+
signature?: string | undefined;
|
|
93
|
+
growing_classes?: string[] | undefined;
|
|
94
|
+
round?: string | undefined;
|
|
95
|
+
fixed_behind?: string | undefined;
|
|
96
|
+
}>;
|
|
97
|
+
type ImportedFinding = z.infer<typeof IMPORTED_FINDING_SCHEMA>;
|
|
98
|
+
export declare function importFindings(index: FindingIndex, incoming: ImportedFinding[]): {
|
|
99
|
+
imported: number;
|
|
100
|
+
updated: number;
|
|
101
|
+
skipped: string[];
|
|
102
|
+
};
|
|
11
103
|
/**
|
|
12
104
|
* Normalize a retainer path into a signature that is stable across captures.
|
|
13
105
|
*
|
|
@@ -18,5 +110,94 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
18
110
|
*/
|
|
19
111
|
export declare function normalizeRetainerPath(raw: string): string;
|
|
20
112
|
export declare function fingerprintOf(signature: string, classes: string[]): string;
|
|
113
|
+
/**
|
|
114
|
+
* Artifact families every hunt re-derives, seeded into a fresh index.
|
|
115
|
+
*
|
|
116
|
+
* An empty index answers NEW to everything — including populations that are
|
|
117
|
+
* documented, well understood, and not app memory at all. That makes the first
|
|
118
|
+
* `check` of a workstream actively misleading rather than merely unhelpful, and
|
|
119
|
+
* hand-seeding never happens because it is a step nobody is prompted to take.
|
|
120
|
+
*
|
|
121
|
+
* These entries are deliberately the GENERIC, tool-detectable families (the
|
|
122
|
+
* same taxonomy `artifact-classes.ts` classifies, plus the two dev-build
|
|
123
|
+
* registries `dev_artifacts` detects). They are marked `known` rather than
|
|
124
|
+
* `fixed`: they are not defects to be fixed, they are populations a hunt must
|
|
125
|
+
* subtract. Anything app-specific belongs in a real `action: "import"`.
|
|
126
|
+
*/
|
|
127
|
+
export declare function builtinSeedFindings(): ImportedFinding[];
|
|
128
|
+
/**
|
|
129
|
+
* Known entries that share a growing class with the candidate.
|
|
130
|
+
*
|
|
131
|
+
* The fingerprint is an EXACT match on signature + class set, which is right for
|
|
132
|
+
* "have we filed this before" and useless for "is this population a known
|
|
133
|
+
* artifact". Measured against a freshly-seeded index: a realistic check —
|
|
134
|
+
* retainer path `(GC roots) > (Global handles) > Object.allSignaturesByType`,
|
|
135
|
+
* growing class `allSignaturesByType` — returned NEW, even though the React Fast
|
|
136
|
+
* Refresh registry entry naming that exact class was sitting in the index. A
|
|
137
|
+
* caller has to reproduce the seeded signature string verbatim to get a hit,
|
|
138
|
+
* which nobody will ever do, so without this the seeding is decorative.
|
|
139
|
+
*
|
|
140
|
+
* Reported ALONGSIDE the NEW verdict rather than replacing it: a class overlap
|
|
141
|
+
* is a lead, not an identification, and silently converting NEW to KNOWN on one
|
|
142
|
+
* shared class name would suppress real findings.
|
|
143
|
+
*/
|
|
144
|
+
export declare function relatedByClass(index: FindingIndex, classes: readonly string[], excludeFingerprint: string): Finding[];
|
|
145
|
+
/**
|
|
146
|
+
* Does the index hold anything beyond the generic built-in artifact families?
|
|
147
|
+
*
|
|
148
|
+
* `loadIndex` seeds a fresh index with those families, so a plain
|
|
149
|
+
* `Object.keys(findings).length === 0` is never true and every "is this index
|
|
150
|
+
* usable" guard built on it silently never fires. The question that actually
|
|
151
|
+
* matters is whether the index carries history for THIS app; built-in entries
|
|
152
|
+
* are stamped `first_seen_round: 'builtin'` and say nothing about it.
|
|
153
|
+
*/
|
|
154
|
+
export declare function hasAppHistory(index: {
|
|
155
|
+
findings: Record<string, {
|
|
156
|
+
first_seen_round: string;
|
|
157
|
+
}>;
|
|
158
|
+
}): boolean;
|
|
159
|
+
/**
|
|
160
|
+
* Fingerprint a candidate and look it up, for callers that are not the
|
|
161
|
+
* `memlab_finding_index` tool itself.
|
|
162
|
+
*
|
|
163
|
+
* Exists because the index only prevents re-discovery if somebody remembers to
|
|
164
|
+
* consult it, and in practice nobody does: a measured session produced three
|
|
165
|
+
* findings that were all already fixed behind gates, and never called `check`
|
|
166
|
+
* once. The tools that actually surface findings — `auto_investigate`,
|
|
167
|
+
* `leak_report` — now annotate inline instead of relying on that recall.
|
|
168
|
+
*
|
|
169
|
+
* Returns `indexEmpty` so the caller can say the verdict means nothing rather
|
|
170
|
+
* than printing a confident NEW from an index that has never been seeded.
|
|
171
|
+
*/
|
|
172
|
+
export type FindingLookup = {
|
|
173
|
+
verdict: 'NEW' | 'KNOWN' | 'KNOWN-AND-FIXED';
|
|
174
|
+
fixedBehind?: string;
|
|
175
|
+
note?: string;
|
|
176
|
+
round?: string;
|
|
177
|
+
related: string[];
|
|
178
|
+
indexEmpty: boolean;
|
|
179
|
+
indexPath: string;
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* The index, read once, for callers that look up many candidates in a row.
|
|
183
|
+
*
|
|
184
|
+
* `lookupFinding` reads and parses the index file on every call, which is
|
|
185
|
+
* fine for a one-off check and wasteful inside a report loop that annotates
|
|
186
|
+
* every finding — that turns one read into N reads of the same file.
|
|
187
|
+
*/
|
|
188
|
+
export type LoadedFindingIndex = {
|
|
189
|
+
index: FindingIndex;
|
|
190
|
+
indexPath: string;
|
|
191
|
+
};
|
|
192
|
+
export declare function loadFindingIndex(workstream?: string): LoadedFindingIndex;
|
|
193
|
+
export declare function lookupFinding(retainerPath: string, classes: readonly string[], workstream?: string): FindingLookup;
|
|
194
|
+
export declare function lookupFindingIn(loaded: LoadedFindingIndex, retainerPath: string, classes: readonly string[]): FindingLookup;
|
|
195
|
+
/** One-line renderer for an inline verdict badge. */
|
|
196
|
+
export declare function renderFindingVerdict(l: FindingLookup): string;
|
|
197
|
+
/**
|
|
198
|
+
* The banner to print once per report when the index cannot support a verdict.
|
|
199
|
+
*/
|
|
200
|
+
export declare function findingIndexEmptyBanner(indexPath: string): string;
|
|
21
201
|
export declare function registerFindingIndex(server: McpServer): void;
|
|
202
|
+
export {};
|
|
22
203
|
//# sourceMappingURL=finding-index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"finding-index.d.ts","sourceRoot":"","sources":["../../src/tools/finding-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"finding-index.d.ts","sourceRoot":"","sources":["../../src/tools/finding-index.ts"],"names":[],"mappings":"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"}
|