@memlab/mcp-server 2.3.0 → 2.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -14
- package/bin/.eslintrc.js +26 -0
- package/bin/memlab-cli.js +313 -0
- package/dist/artifact-classes.d.ts +86 -0
- package/dist/artifact-classes.d.ts.map +1 -0
- package/dist/artifact-classes.js +261 -0
- package/dist/artifact-classes.js.map +1 -0
- package/dist/capture-mode.d.ts +60 -0
- package/dist/capture-mode.d.ts.map +1 -0
- package/dist/capture-mode.js +39 -0
- package/dist/capture-mode.js.map +1 -0
- package/dist/guardrail.d.ts.map +1 -1
- package/dist/guardrail.js +13 -0
- package/dist/guardrail.js.map +1 -1
- package/dist/heap-state.d.ts +96 -2
- package/dist/heap-state.d.ts.map +1 -1
- package/dist/heap-state.js +197 -2
- package/dist/heap-state.js.map +1 -1
- package/dist/index.js +41 -1
- package/dist/index.js.map +1 -1
- package/dist/progress.d.ts +25 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +46 -0
- package/dist/progress.js.map +1 -0
- package/dist/result-handles.d.ts +11 -0
- package/dist/result-handles.d.ts.map +1 -0
- package/dist/result-handles.js +77 -0
- package/dist/result-handles.js.map +1 -0
- package/dist/string-index.d.ts +55 -0
- package/dist/string-index.d.ts.map +1 -0
- package/dist/string-index.js +91 -0
- package/dist/string-index.js.map +1 -0
- package/dist/tool-registry.d.ts +42 -0
- package/dist/tool-registry.d.ts.map +1 -0
- package/dist/tool-registry.js +20 -0
- package/dist/tool-registry.js.map +1 -0
- package/dist/tools/analyze-run.d.ts +12 -0
- package/dist/tools/analyze-run.d.ts.map +1 -0
- package/dist/tools/analyze-run.js +343 -0
- package/dist/tools/analyze-run.js.map +1 -0
- package/dist/tools/app-heap.d.ts +12 -0
- package/dist/tools/app-heap.d.ts.map +1 -0
- package/dist/tools/app-heap.js +140 -0
- package/dist/tools/app-heap.js.map +1 -0
- package/dist/tools/auto-investigate.d.ts.map +1 -1
- package/dist/tools/auto-investigate.js +91 -49
- package/dist/tools/auto-investigate.js.map +1 -1
- package/dist/tools/batch.d.ts +12 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +168 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/cache-analysis.d.ts.map +1 -1
- package/dist/tools/cache-analysis.js +156 -5
- package/dist/tools/cache-analysis.js.map +1 -1
- package/dist/tools/class-histogram.d.ts.map +1 -1
- package/dist/tools/class-histogram.js +14 -3
- package/dist/tools/class-histogram.js.map +1 -1
- package/dist/tools/collection-trend.d.ts +55 -0
- package/dist/tools/collection-trend.d.ts.map +1 -0
- package/dist/tools/collection-trend.js +315 -0
- package/dist/tools/collection-trend.js.map +1 -0
- package/dist/tools/detached-dom.d.ts +2 -0
- package/dist/tools/detached-dom.d.ts.map +1 -1
- package/dist/tools/detached-dom.js +291 -20
- package/dist/tools/detached-dom.js.map +1 -1
- package/dist/tools/dev-artifacts.d.ts +62 -6
- package/dist/tools/dev-artifacts.d.ts.map +1 -1
- package/dist/tools/dev-artifacts.js +466 -23
- package/dist/tools/dev-artifacts.js.map +1 -1
- package/dist/tools/diff-snapshots.d.ts.map +1 -1
- package/dist/tools/diff-snapshots.js +101 -44
- package/dist/tools/diff-snapshots.js.map +1 -1
- package/dist/tools/dominator-attribution.d.ts +12 -0
- package/dist/tools/dominator-attribution.d.ts.map +1 -0
- package/dist/tools/dominator-attribution.js +189 -0
- package/dist/tools/dominator-attribution.js.map +1 -0
- package/dist/tools/dominator-chain.d.ts +12 -0
- package/dist/tools/dominator-chain.d.ts.map +1 -0
- package/dist/tools/dominator-chain.js +92 -0
- package/dist/tools/dominator-chain.js.map +1 -0
- package/dist/tools/duplicate-objects.d.ts +12 -0
- package/dist/tools/duplicate-objects.d.ts.map +1 -0
- package/dist/tools/duplicate-objects.js +172 -0
- package/dist/tools/duplicate-objects.js.map +1 -0
- package/dist/tools/duplicated-strings.d.ts.map +1 -1
- package/dist/tools/duplicated-strings.js +46 -38
- package/dist/tools/duplicated-strings.js.map +1 -1
- package/dist/tools/eval.d.ts +1 -0
- package/dist/tools/eval.d.ts.map +1 -1
- package/dist/tools/eval.js +787 -30
- package/dist/tools/eval.js.map +1 -1
- package/dist/tools/explain-delta.d.ts +12 -0
- package/dist/tools/explain-delta.d.ts.map +1 -0
- package/dist/tools/explain-delta.js +170 -0
- package/dist/tools/explain-delta.js.map +1 -0
- package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
- package/dist/tools/find-nodes-by-class.js +112 -13
- package/dist/tools/find-nodes-by-class.js.map +1 -1
- package/dist/tools/finding-index.d.ts +22 -0
- package/dist/tools/finding-index.d.ts.map +1 -0
- package/dist/tools/finding-index.js +247 -0
- package/dist/tools/finding-index.js.map +1 -0
- package/dist/tools/for-each.d.ts.map +1 -1
- package/dist/tools/for-each.js +15 -3
- package/dist/tools/for-each.js.map +1 -1
- package/dist/tools/get-references.d.ts.map +1 -1
- package/dist/tools/get-references.js +35 -6
- package/dist/tools/get-references.js.map +1 -1
- package/dist/tools/get-referrers.d.ts.map +1 -1
- package/dist/tools/get-referrers.js +52 -6
- package/dist/tools/get-referrers.js.map +1 -1
- package/dist/tools/hunt-report.d.ts +12 -0
- package/dist/tools/hunt-report.d.ts.map +1 -0
- package/dist/tools/hunt-report.js +186 -0
- package/dist/tools/hunt-report.js.map +1 -0
- package/dist/tools/hypothesis.d.ts +12 -0
- package/dist/tools/hypothesis.d.ts.map +1 -0
- package/dist/tools/hypothesis.js +221 -0
- package/dist/tools/hypothesis.js.map +1 -0
- package/dist/tools/intern-opportunities.d.ts.map +1 -1
- package/dist/tools/intern-opportunities.js +721 -75
- package/dist/tools/intern-opportunities.js.map +1 -1
- package/dist/tools/ladder.d.ts +33 -0
- package/dist/tools/ladder.d.ts.map +1 -0
- package/dist/tools/ladder.js +266 -0
- package/dist/tools/ladder.js.map +1 -0
- package/dist/tools/largest-objects.d.ts.map +1 -1
- package/dist/tools/largest-objects.js +43 -16
- package/dist/tools/largest-objects.js.map +1 -1
- package/dist/tools/leak-report.d.ts +12 -0
- package/dist/tools/leak-report.d.ts.map +1 -0
- package/dist/tools/leak-report.js +256 -0
- package/dist/tools/leak-report.js.map +1 -0
- package/dist/tools/load-snapshot.d.ts +78 -0
- package/dist/tools/load-snapshot.d.ts.map +1 -1
- package/dist/tools/load-snapshot.js +519 -29
- package/dist/tools/load-snapshot.js.map +1 -1
- package/dist/tools/map-entries.d.ts +12 -0
- package/dist/tools/map-entries.d.ts.map +1 -0
- package/dist/tools/map-entries.js +139 -0
- package/dist/tools/map-entries.js.map +1 -0
- package/dist/tools/match-object.d.ts +12 -0
- package/dist/tools/match-object.d.ts.map +1 -0
- package/dist/tools/match-object.js +165 -0
- package/dist/tools/match-object.js.map +1 -0
- package/dist/tools/object-shape.d.ts.map +1 -1
- package/dist/tools/object-shape.js +92 -30
- package/dist/tools/object-shape.js.map +1 -1
- package/dist/tools/population-diff.d.ts +57 -0
- package/dist/tools/population-diff.d.ts.map +1 -0
- package/dist/tools/population-diff.js +338 -0
- package/dist/tools/population-diff.js.map +1 -0
- package/dist/tools/quick-diagnosis.d.ts.map +1 -1
- package/dist/tools/quick-diagnosis.js +12 -4
- package/dist/tools/quick-diagnosis.js.map +1 -1
- package/dist/tools/retainer-layers.d.ts +23 -0
- package/dist/tools/retainer-layers.d.ts.map +1 -0
- package/dist/tools/retainer-layers.js +179 -0
- package/dist/tools/retainer-layers.js.map +1 -0
- package/dist/tools/retainer-summary.d.ts +1 -0
- package/dist/tools/retainer-summary.d.ts.map +1 -1
- package/dist/tools/retainer-summary.js +128 -32
- package/dist/tools/retainer-summary.js.map +1 -1
- package/dist/tools/retainer-trace.d.ts.map +1 -1
- package/dist/tools/retainer-trace.js +105 -25
- package/dist/tools/retainer-trace.js.map +1 -1
- package/dist/tools/search-nodes.d.ts.map +1 -1
- package/dist/tools/search-nodes.js +5 -1
- package/dist/tools/search-nodes.js.map +1 -1
- package/dist/tools/search-strings.d.ts.map +1 -1
- package/dist/tools/search-strings.js +53 -7
- package/dist/tools/search-strings.js.map +1 -1
- package/dist/tools/sequence-analysis.d.ts +49 -0
- package/dist/tools/sequence-analysis.d.ts.map +1 -1
- package/dist/tools/sequence-analysis.js +268 -78
- package/dist/tools/sequence-analysis.js.map +1 -1
- package/dist/tools/shape-histogram.d.ts.map +1 -1
- package/dist/tools/shape-histogram.js +9 -2
- package/dist/tools/shape-histogram.js.map +1 -1
- package/dist/tools/sliced-strings.d.ts.map +1 -1
- package/dist/tools/sliced-strings.js +22 -4
- package/dist/tools/sliced-strings.js.map +1 -1
- package/dist/tools/snapshot-header.d.ts +28 -0
- package/dist/tools/snapshot-header.d.ts.map +1 -0
- package/dist/tools/snapshot-header.js +111 -0
- package/dist/tools/snapshot-header.js.map +1 -0
- package/dist/tools/string-patterns.d.ts.map +1 -1
- package/dist/tools/string-patterns.js +5 -4
- package/dist/tools/string-patterns.js.map +1 -1
- package/dist/tools/tools-index.d.ts +12 -0
- package/dist/tools/tools-index.d.ts.map +1 -0
- package/dist/tools/tools-index.js +342 -0
- package/dist/tools/tools-index.js.map +1 -0
- package/dist/tools/verify-fix.d.ts +23 -0
- package/dist/tools/verify-fix.d.ts.map +1 -0
- package/dist/tools/verify-fix.js +211 -0
- package/dist/tools/verify-fix.js.map +1 -0
- package/dist/tools/weakmap-entries.d.ts.map +1 -1
- package/dist/tools/weakmap-entries.js +6 -1
- package/dist/tools/weakmap-entries.js.map +1 -1
- package/dist/utils.d.ts +204 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +478 -8
- package/dist/utils.js.map +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,91 @@
|
|
|
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 { getEvalScratch } from './heap-state.js';
|
|
11
|
+
// Bounded so the index cannot grow with instance count; 20 is what the
|
|
12
|
+
// deepest consumer (intern_opportunities' referrer sampling) needs.
|
|
13
|
+
const MAX_EXAMPLE_IDS = 20;
|
|
14
|
+
const CACHE_KEY = '__memlabStringIndex';
|
|
15
|
+
/**
|
|
16
|
+
* Build (or reuse) the per-value string duplication index for a snapshot.
|
|
17
|
+
*
|
|
18
|
+
* `memlab_duplicated_strings` and `memlab_intern_opportunities` were each doing
|
|
19
|
+
* their own full pass over every string node to build the same value → {count,
|
|
20
|
+
* size, ids} map, and both are commonly run back to back on the same snapshot —
|
|
21
|
+
* so the second one re-walked millions of nodes to recompute what the first had
|
|
22
|
+
* already produced. The scan is cached in the per-snapshot eval scratch, which
|
|
23
|
+
* already has exactly the lifecycle this needs: keyed by the active handle, and
|
|
24
|
+
* dropped when that snapshot is replaced or unloaded, so a stale index can never
|
|
25
|
+
* outlive the graph its node ids refer to.
|
|
26
|
+
*
|
|
27
|
+
* `withDevOnly` gates the dev/automation reachability pass, which is a whole-
|
|
28
|
+
* graph walk that only `intern_opportunities` needs. A cached index built
|
|
29
|
+
* without it is UPGRADED (rebuilt once) rather than silently returned, since
|
|
30
|
+
* `devOnlyCount: -1` would otherwise be read as "no dev-only copies".
|
|
31
|
+
*/
|
|
32
|
+
export function buildStringIndex(snapshot, opts = {}) {
|
|
33
|
+
const scratch = getEvalScratch();
|
|
34
|
+
const cached = scratch[CACHE_KEY];
|
|
35
|
+
const wantDevOnly = opts.withDevOnly === true;
|
|
36
|
+
if (cached && (!wantDevOnly || cached.hasDevOnly)) {
|
|
37
|
+
return cached;
|
|
38
|
+
}
|
|
39
|
+
const isDevOnly = wantDevOnly ? opts.isDevOnlyNode : undefined;
|
|
40
|
+
const byValue = new Map();
|
|
41
|
+
let concatStringCount = 0;
|
|
42
|
+
let concatStringSize = 0;
|
|
43
|
+
snapshot.nodes.forEach(node => {
|
|
44
|
+
if (node.name === '(concatenated string)') {
|
|
45
|
+
concatStringCount++;
|
|
46
|
+
concatStringSize += node.self_size;
|
|
47
|
+
}
|
|
48
|
+
if (node.type !== 'string')
|
|
49
|
+
return;
|
|
50
|
+
// Sliced strings share a parent's storage, so they are not independent
|
|
51
|
+
// duplicates and counting them would overstate any interning win.
|
|
52
|
+
if (node.name === 'system / SlicedString')
|
|
53
|
+
return;
|
|
54
|
+
const strNode = node.toStringNode();
|
|
55
|
+
if (!strNode)
|
|
56
|
+
return;
|
|
57
|
+
const value = strNode.stringValue;
|
|
58
|
+
const devOnly = isDevOnly != null && isDevOnly(node);
|
|
59
|
+
const entry = byValue.get(value);
|
|
60
|
+
if (entry) {
|
|
61
|
+
entry.count++;
|
|
62
|
+
entry.totalSize += node.retainedSize;
|
|
63
|
+
if (devOnly)
|
|
64
|
+
entry.devOnlyCount++;
|
|
65
|
+
if (entry.exampleIds.length < MAX_EXAMPLE_IDS) {
|
|
66
|
+
entry.exampleIds.push(node.id);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
byValue.set(value, {
|
|
71
|
+
count: 1,
|
|
72
|
+
totalSize: node.retainedSize,
|
|
73
|
+
exampleIds: [node.id],
|
|
74
|
+
devOnlyCount: isDevOnly == null ? -1 : devOnly ? 1 : 0,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
const index = {
|
|
79
|
+
byValue,
|
|
80
|
+
hasDevOnly: isDevOnly != null,
|
|
81
|
+
concatStringCount,
|
|
82
|
+
concatStringSize,
|
|
83
|
+
};
|
|
84
|
+
scratch[CACHE_KEY] = index;
|
|
85
|
+
return index;
|
|
86
|
+
}
|
|
87
|
+
/** True when this snapshot's string index is already built and resident. */
|
|
88
|
+
export function stringIndexIsCached() {
|
|
89
|
+
return getEvalScratch()[CACHE_KEY] != null;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=string-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string-index.js","sourceRoot":"","sources":["../src/string-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
/**
|
|
11
|
+
* Name -> handler index of every registered tool, so one tool can dispatch to
|
|
12
|
+
* another in-process (see `memlab_batch`).
|
|
13
|
+
*
|
|
14
|
+
* Populated from the same `server.tool` monkey-patch the wall-clock guardrail
|
|
15
|
+
* installs, which is the one place every registration already funnels through —
|
|
16
|
+
* so no call site has to opt in and the index cannot drift from the real tool
|
|
17
|
+
* list.
|
|
18
|
+
*
|
|
19
|
+
* The RAW (pre-guardrail) handler is stored on purpose. The wrapped handler arms
|
|
20
|
+
* an analysis budget per call, and a batch is itself running inside one; nesting
|
|
21
|
+
* `beginAnalysisBudget` would let an inner step's `endAnalysisBudget` retire the
|
|
22
|
+
* outer batch's budget early. Storing the raw handler keeps exactly one budget
|
|
23
|
+
* per MCP call — the batch's own, which callers can size with `timeout_ms`.
|
|
24
|
+
*/
|
|
25
|
+
type RawToolHandler = (...args: unknown[]) => unknown;
|
|
26
|
+
/**
|
|
27
|
+
* The raw handler expects arguments the SDK has ALREADY validated against the
|
|
28
|
+
* tool's zod shape, which is where `.default()` values are materialized. A
|
|
29
|
+
* caller that invokes the raw handler with a plain object therefore gets
|
|
30
|
+
* `undefined` for every omitted optional — and an omitted `min_count` silently
|
|
31
|
+
* turns a scan into "no results found" rather than an error. So the shape is
|
|
32
|
+
* stored next to the handler and re-applied by the dispatcher.
|
|
33
|
+
*/
|
|
34
|
+
export interface RegisteredTool {
|
|
35
|
+
handler: RawToolHandler;
|
|
36
|
+
shape: Record<string, unknown> | null;
|
|
37
|
+
}
|
|
38
|
+
export declare function recordToolHandler(name: string, handler: RawToolHandler, shape: Record<string, unknown> | null): void;
|
|
39
|
+
export declare function getRegisteredTool(name: string): RegisteredTool | undefined;
|
|
40
|
+
export declare function listToolNames(): string[];
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=tool-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;GAcG;AAEH,KAAK,cAAc,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACvC;AAID,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACpC,IAAI,CAEN;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE1E;AAED,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
const tools = new Map();
|
|
11
|
+
export function recordToolHandler(name, handler, shape) {
|
|
12
|
+
tools.set(name, { handler, shape });
|
|
13
|
+
}
|
|
14
|
+
export function getRegisteredTool(name) {
|
|
15
|
+
return tools.get(name);
|
|
16
|
+
}
|
|
17
|
+
export function listToolNames() {
|
|
18
|
+
return [...tools.keys()].sort();
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=tool-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAiCH,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEhD,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,OAAuB,EACvB,KAAqC;IAErC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -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 registerAnalyzeRun(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=analyze-run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-run.d.ts","sourceRoot":"","sources":["../../src/tools/analyze-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AA6KvE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8U1D"}
|
|
@@ -0,0 +1,343 @@
|
|
|
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 fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import memlabHeapAnalysis from '@memlab/heap-analysis';
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { getRegisteredTool } from '../tool-registry.js';
|
|
15
|
+
import { activeElapsedMs, activeTimeoutMs_, beginAnalysisBudget, endAnalysisBudget, ScanTimeoutError, } from '../analysis-budget.js';
|
|
16
|
+
import { clearAllSnapshots, listSnapshots, setCurrentSnapshot, setSnapshot, } from '../heap-state.js';
|
|
17
|
+
import { artifactLabel } from '../artifact-classes.js';
|
|
18
|
+
import { errorResult, formatBytes, formatNumber, markdownTable, toolResult, } from '../utils.js';
|
|
19
|
+
import { computeSequenceTrends } from './sequence-analysis.js';
|
|
20
|
+
const { getFullHeapFromFile } = memlabHeapAnalysis;
|
|
21
|
+
/**
|
|
22
|
+
* Run one already-registered tool in-process against the current snapshot.
|
|
23
|
+
*
|
|
24
|
+
* Same dispatch `memlab_batch` uses, and for the same reason: the analysis is a
|
|
25
|
+
* fixed sequence of existing tools, and re-implementing any of them here would
|
|
26
|
+
* let the protocol's answer drift from the answer the operator gets by hand.
|
|
27
|
+
* Failures are captured as text rather than thrown — one missing section must
|
|
28
|
+
* not cost the whole write-up.
|
|
29
|
+
*
|
|
30
|
+
* Each step gets its OWN wall clock, armed through the server's COOPERATIVE
|
|
31
|
+
* budget rather than a timer. That distinction is the whole design: a heap walk
|
|
32
|
+
* is synchronous, so it blocks the event loop and a `setTimeout` racing it can
|
|
33
|
+
* never fire — a timer-based budget bounds nothing and only looks like it does.
|
|
34
|
+
* Measured while building this: with a 90s timer-based step budget, the deep
|
|
35
|
+
* dive on a 3-rung / 700 MB ladder was still running at 14 minutes with no
|
|
36
|
+
* output. `beginAnalysisBudget` instead makes `tickAnalysis()`, which the
|
|
37
|
+
* snapshot's patched `forEach` already calls, throw from INSIDE the walk.
|
|
38
|
+
*
|
|
39
|
+
* A step that overruns is reported as UNANALYZED — the same contract the rest
|
|
40
|
+
* of this tool holds itself to — and the protocol moves on.
|
|
41
|
+
*
|
|
42
|
+
* The outer budget is restored afterwards so the remaining steps still run
|
|
43
|
+
* under the caller's overall `timeout_ms`.
|
|
44
|
+
*/
|
|
45
|
+
async function runTool(name, args, budgetMs, unanalyzed) {
|
|
46
|
+
const entry = getRegisteredTool(name);
|
|
47
|
+
if (entry == null)
|
|
48
|
+
return `_(${name} is not registered on this server)_`;
|
|
49
|
+
const outerRemaining = Math.max(0, activeTimeoutMs_() - activeElapsedMs());
|
|
50
|
+
const outerTimeout = activeTimeoutMs_();
|
|
51
|
+
beginAnalysisBudget(budgetMs);
|
|
52
|
+
try {
|
|
53
|
+
const res = await entry.handler(args, {});
|
|
54
|
+
const content = res?.content;
|
|
55
|
+
const text = Array.isArray(content)
|
|
56
|
+
? content.map(c => c.text ?? '').join('\n')
|
|
57
|
+
: String(res);
|
|
58
|
+
// A tool that fails does NOT throw: every handler catches its own errors
|
|
59
|
+
// and returns an `isError` envelope, budget overruns included. Treating
|
|
60
|
+
// only exceptions as failures is how this write-up printed "every step of
|
|
61
|
+
// the protocol ran" underneath a step that had aborted mid-walk — the exact
|
|
62
|
+
// false clean-bill this tool exists to prevent. (`memlab_batch` learned the
|
|
63
|
+
// same lesson; see `isErrorResult` there.)
|
|
64
|
+
if (res?.isError === true) {
|
|
65
|
+
const overran = /budget|timed? ?out|exceeded/i.test(text);
|
|
66
|
+
unanalyzed.push(overran
|
|
67
|
+
? `${name} exceeded its ${Math.round(budgetMs / 1000)}s step budget`
|
|
68
|
+
: `${name} failed`);
|
|
69
|
+
return overran
|
|
70
|
+
? `_(${name} exceeded its ${Math.round(budgetMs / 1000)}s step budget and was aborted mid-walk — raise \`step_timeout_s\`, or run it directly against the resident snapshots.)_\n\n${text}`
|
|
71
|
+
: text;
|
|
72
|
+
}
|
|
73
|
+
return text.trim() || '_(no output)_';
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
77
|
+
const timedOut = err instanceof ScanTimeoutError || /timed? ?out|budget/i.test(msg);
|
|
78
|
+
unanalyzed.push(timedOut
|
|
79
|
+
? `${name} exceeded its ${Math.round(budgetMs / 1000)}s step budget`
|
|
80
|
+
: `${name} failed`);
|
|
81
|
+
return timedOut
|
|
82
|
+
? `_(${name} exceeded its ${Math.round(budgetMs / 1000)}s step budget and was aborted mid-walk. Run it directly against the resident snapshots with a larger \`timeout_ms\`, or raise \`step_timeout_s\`.)_`
|
|
83
|
+
: `_(${name} failed: ${msg})_`;
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
// Restore the caller's budget, minus what this step consumed, so the
|
|
87
|
+
// remaining steps still run under the overall timeout rather than getting
|
|
88
|
+
// a fresh one each.
|
|
89
|
+
if (outerTimeout > 0) {
|
|
90
|
+
beginAnalysisBudget(Math.max(1, outerRemaining));
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
endAnalysisBudget();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Load a snapshot file and register it under `alias`, keeping the others. */
|
|
98
|
+
async function loadRung(filePath, alias) {
|
|
99
|
+
const snapshot = await getFullHeapFromFile(filePath);
|
|
100
|
+
let nodeCount = 0;
|
|
101
|
+
let totalSize = 0;
|
|
102
|
+
snapshot.nodes.forEach(n => {
|
|
103
|
+
nodeCount++;
|
|
104
|
+
totalSize += n.self_size;
|
|
105
|
+
});
|
|
106
|
+
let edgeCount = 0;
|
|
107
|
+
snapshot.edges.forEach(() => {
|
|
108
|
+
edgeCount++;
|
|
109
|
+
});
|
|
110
|
+
setSnapshot(snapshot, filePath, {
|
|
111
|
+
fileName: path.basename(filePath),
|
|
112
|
+
nodeCount,
|
|
113
|
+
edgeCount,
|
|
114
|
+
totalSize,
|
|
115
|
+
env: 'browser',
|
|
116
|
+
}, { alias, replace: false });
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* One-line, non-empty label for a class in a table or a sentence.
|
|
120
|
+
*
|
|
121
|
+
* V8 leaves anonymous arrays and closures unnamed, and value-named string
|
|
122
|
+
* "classes" carry their whole (often multi-line) value — both of which render as
|
|
123
|
+
* a blank cell or a broken paragraph if passed through unchanged.
|
|
124
|
+
*/
|
|
125
|
+
function classLabel(name, type, maxLen = 38) {
|
|
126
|
+
const flat = name.replace(/\s+/g, ' ').trim();
|
|
127
|
+
if (flat.length === 0)
|
|
128
|
+
return `(unnamed ${type})`;
|
|
129
|
+
return flat.length > maxLen ? `${flat.slice(0, maxLen - 1)}…` : flat;
|
|
130
|
+
}
|
|
131
|
+
export function registerAnalyzeRun(server) {
|
|
132
|
+
server.tool('memlab_analyze_run', "Point at a leak hunt's `run.json` and get the whole analysis protocol executed in one call: ladder trend, owner attribution for the growth, a detached-DOM population comparison between the first and last rung, dev/automation-artifact classification, and a per-grower adjudication — plus the run's own caveats (gating, relink seams, stall) carried into the write-up. " +
|
|
133
|
+
'`memlab_hunt_report` renders the run and `memlab_leak_report` analyses the ladder; nothing chained them, so how thorough a round got depended on how thorough the operator felt like being, which is the single largest source of variance between rounds. This runs the same sequence every time and states explicitly which steps did not run. ' +
|
|
134
|
+
'Cost: it loads the ladder transiently for the trend, then holds the FIRST and LAST rung resident together for the attribution and population steps — size `timeout_ms` accordingly (600000+ for a multi-hundred-MB ladder), and expect several minutes. ' +
|
|
135
|
+
'KNOWN LIMITATION, measured on two apps: the `dev_artifacts` step reliably exceeds a 200-240s step budget here (aborting at ~10.8M nodes scanned) while the same tool returns in 2-5s when called directly on the same snapshot. Unloading the baseline first does NOT change it, so residency is not the cause and the cause is not yet identified. The step is reported as UNANALYZED rather than waited out; run `memlab_dev_artifacts` yourself against the final rung, or raise `step_timeout_s`, to complete that part of the protocol.', {
|
|
136
|
+
run_json: z
|
|
137
|
+
.string()
|
|
138
|
+
.describe('Path to a run.json written by hunt_runner (or to the run directory containing it).'),
|
|
139
|
+
cycles_between_rungs: z
|
|
140
|
+
.number()
|
|
141
|
+
.optional()
|
|
142
|
+
.describe('Override the interaction cycles between consecutive rungs. Defaults to the per-rung `cycles` recorded in the manifest.'),
|
|
143
|
+
top: z
|
|
144
|
+
.number()
|
|
145
|
+
.optional()
|
|
146
|
+
.default(12)
|
|
147
|
+
.describe('How many growing classes to adjudicate (default 12).'),
|
|
148
|
+
skip_deep_dive: z
|
|
149
|
+
.boolean()
|
|
150
|
+
.optional()
|
|
151
|
+
.default(false)
|
|
152
|
+
.describe('Run only the ladder trend, skipping the two-snapshot-resident steps (owner attribution, population diff, artifacts). Use on a ladder too large to hold two rungs in memory at once.'),
|
|
153
|
+
step_timeout_s: z
|
|
154
|
+
.number()
|
|
155
|
+
.optional()
|
|
156
|
+
.default(240)
|
|
157
|
+
.describe('Wall clock for EACH deep-dive step (default 240s). A step that overruns is reported as UNANALYZED instead of being waited out — several whole-heap steps chained behind one budget is how a protocol turns into a hung session. Raise it for very large ladders.'),
|
|
158
|
+
max_file_size_mb: z
|
|
159
|
+
.number()
|
|
160
|
+
.optional()
|
|
161
|
+
.describe('Per-file size limit override (MB).'),
|
|
162
|
+
}, async ({ run_json, cycles_between_rungs, top, skip_deep_dive, step_timeout_s, max_file_size_mb, }) => {
|
|
163
|
+
try {
|
|
164
|
+
let manifestPath = run_json;
|
|
165
|
+
if (fs.existsSync(manifestPath) &&
|
|
166
|
+
fs.statSync(manifestPath).isDirectory()) {
|
|
167
|
+
manifestPath = path.join(manifestPath, 'run.json');
|
|
168
|
+
}
|
|
169
|
+
if (!fs.existsSync(manifestPath)) {
|
|
170
|
+
return errorResult(`No run.json at ${manifestPath}.`);
|
|
171
|
+
}
|
|
172
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
173
|
+
const rungs = (manifest.rungs ?? []).filter(r => fs.existsSync(r.path));
|
|
174
|
+
const missing = (manifest.rungs ?? []).length - rungs.length;
|
|
175
|
+
if (rungs.length < 2) {
|
|
176
|
+
return errorResult(`The run has ${rungs.length} readable rung(s); the protocol needs at least 2. ` +
|
|
177
|
+
(missing > 0
|
|
178
|
+
? `${missing} rung file(s) listed in the manifest are missing from disk — snapshots are usually written to /tmp and may have been cleaned up.`
|
|
179
|
+
: 'Capture more rungs, or analyze the single snapshot directly with memlab_load_snapshot + memlab_auto_investigate.'));
|
|
180
|
+
}
|
|
181
|
+
// The steps that did NOT run are part of the result. A protocol whose
|
|
182
|
+
// gaps are invisible reads as a complete analysis, which is how a round
|
|
183
|
+
// gets published with a step quietly missing.
|
|
184
|
+
const unanalyzed = [];
|
|
185
|
+
const stepBudgetMs = Math.max(1, step_timeout_s) * 1000;
|
|
186
|
+
if (missing > 0) {
|
|
187
|
+
unanalyzed.push(`${missing} rung file(s) from the manifest are missing on disk and were excluded.`);
|
|
188
|
+
}
|
|
189
|
+
const paths = rungs.map(r => r.path);
|
|
190
|
+
const first = rungs[0];
|
|
191
|
+
const last = rungs[rungs.length - 1];
|
|
192
|
+
const perRungCycles = cycles_between_rungs ??
|
|
193
|
+
(rungs.length > 1
|
|
194
|
+
? Math.round((last.cycles - first.cycles) / (rungs.length - 1))
|
|
195
|
+
: 0);
|
|
196
|
+
const out = [
|
|
197
|
+
`# Leak-hunt analysis — ${manifest.run_id ?? path.basename(path.dirname(manifestPath))}`,
|
|
198
|
+
'',
|
|
199
|
+
`Combos: ${(manifest.config?.combos ?? []).join(', ') || '(unrecorded)'} · cycles driven: ${formatNumber(manifest.totals?.cycles ?? last.cycles)} (ok ${formatNumber(manifest.totals?.ok ?? 0)} / fail ${formatNumber(manifest.totals?.fail ?? 0)}) · ${rungs.length} rungs · ~${formatNumber(perRungCycles)} cycles between rungs`,
|
|
200
|
+
manifest.stop_reason ? `Stop reason: ${manifest.stop_reason}` : '',
|
|
201
|
+
'',
|
|
202
|
+
'## Ladder',
|
|
203
|
+
'',
|
|
204
|
+
markdownTable(['Rung', 'Cycles', 'Post-GC heap', 'Reason'], rungs.map(r => [
|
|
205
|
+
String(r.index),
|
|
206
|
+
formatNumber(r.cycles),
|
|
207
|
+
`${r.post_gc_heap_mb.toFixed(1)} MB`,
|
|
208
|
+
r.reason ?? '',
|
|
209
|
+
]), new Set([0, 1, 2])),
|
|
210
|
+
'',
|
|
211
|
+
].filter(Boolean);
|
|
212
|
+
const heapDelta = last.post_gc_heap_mb - first.post_gc_heap_mb;
|
|
213
|
+
out.push(`Aggregate post-GC heap moved **${heapDelta >= 0 ? '+' : ''}${heapDelta.toFixed(1)} MB** across the run. Aggregate heap is the weakest signal here and is reported for completeness only: a measured round found a real leak (+6.25 undo entries/cycle, linear across five rungs) while aggregate heap FELL 8.9 MB. The per-class trend below is what decides.`, '');
|
|
214
|
+
// ---- Step 1: ladder trend (transient loads, one graph at a time) ----
|
|
215
|
+
out.push('## 1. Per-class trend across the ladder', '');
|
|
216
|
+
let growers = [];
|
|
217
|
+
try {
|
|
218
|
+
const trends = await computeSequenceTrends(paths, {
|
|
219
|
+
minGrowthCount: 1,
|
|
220
|
+
maxFileSizeMB: max_file_size_mb,
|
|
221
|
+
toolName: 'memlab_analyze_run',
|
|
222
|
+
});
|
|
223
|
+
growers = trends.rows.slice(0, top).map(r => ({
|
|
224
|
+
name: r.name,
|
|
225
|
+
type: r.type,
|
|
226
|
+
netCount: r.netCount,
|
|
227
|
+
netSize: r.netSize,
|
|
228
|
+
trend: r.trend,
|
|
229
|
+
artifact: r.artifact,
|
|
230
|
+
}));
|
|
231
|
+
if (growers.length === 0) {
|
|
232
|
+
out.push('No class grew across the ladder. That is a RESULT, not a failed analysis — record the round as no-leak for these combos rather than re-running until something appears.', '');
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
out.push(markdownTable([
|
|
236
|
+
'Class',
|
|
237
|
+
'Type',
|
|
238
|
+
'Δ count',
|
|
239
|
+
'Δ/cycle',
|
|
240
|
+
'Δ size',
|
|
241
|
+
'Adjudication',
|
|
242
|
+
], growers.map(g => [
|
|
243
|
+
classLabel(g.name, g.type),
|
|
244
|
+
g.type,
|
|
245
|
+
`+${formatNumber(g.netCount)}`,
|
|
246
|
+
perRungCycles > 0
|
|
247
|
+
? (g.netCount /
|
|
248
|
+
(perRungCycles * (rungs.length - 1))).toFixed(2)
|
|
249
|
+
: '—',
|
|
250
|
+
`${g.netSize >= 0 ? '+' : ''}${formatBytes(g.netSize)}`,
|
|
251
|
+
g.artifact != null
|
|
252
|
+
? artifactLabel(g.artifact)
|
|
253
|
+
: g.trend === 'monotonic-up'
|
|
254
|
+
? '↑ every rung — LEAK CANDIDATE'
|
|
255
|
+
: 'grew net (noisy) — weak',
|
|
256
|
+
]), new Set([2, 3, 4])), '');
|
|
257
|
+
const candidates = growers.filter(g => g.artifact == null && g.trend === 'monotonic-up');
|
|
258
|
+
out.push(candidates.length > 0
|
|
259
|
+
? `**${candidates.length} leak candidate(s)** after artifact classification: ${candidates.map(c => `\`${classLabel(c.name, c.type, 28)}\``).join(', ')}. A candidate is not a verdict — the retainer evidence below is what promotes it.`
|
|
260
|
+
: '**No leak candidates** survived artifact classification: every grower is either a known measurement-artifact family or non-monotonic.', '');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
out.push(`_Trend step FAILED: ${err instanceof Error ? err.message : String(err)}_`, '');
|
|
265
|
+
unanalyzed.push('per-class ladder trend');
|
|
266
|
+
}
|
|
267
|
+
// ---- Step 2+: two rungs resident ----
|
|
268
|
+
if (skip_deep_dive) {
|
|
269
|
+
unanalyzed.push('owner attribution, detached-DOM population diff and artifact classification (skip_deep_dive was set)');
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
// Start from a clean slate: the deep dive needs exactly two graphs
|
|
273
|
+
// resident, and anything left over from an earlier call is both
|
|
274
|
+
// memory pressure and a chance to attribute against the wrong pair.
|
|
275
|
+
clearAllSnapshots();
|
|
276
|
+
let loaded = false;
|
|
277
|
+
try {
|
|
278
|
+
await loadRung(first.path, 'run_first');
|
|
279
|
+
await loadRung(last.path, 'run_last');
|
|
280
|
+
loaded = true;
|
|
281
|
+
}
|
|
282
|
+
catch (err) {
|
|
283
|
+
out.push(`_Could not hold both rungs resident: ${err instanceof Error ? err.message : String(err)}. Re-run with skip_deep_dive to get the trend alone._`, '');
|
|
284
|
+
unanalyzed.push('owner attribution, population diff and artifact classification (both rungs would not load)');
|
|
285
|
+
}
|
|
286
|
+
if (loaded) {
|
|
287
|
+
setCurrentSnapshot('run_last');
|
|
288
|
+
out.push('## 2. Who owns the growth', '', await runTool('memlab_explain_delta', {
|
|
289
|
+
baseline_handle: 'run_first',
|
|
290
|
+
target_handle: 'run_last',
|
|
291
|
+
limit: 12,
|
|
292
|
+
min_delta_bytes: 65536,
|
|
293
|
+
include_artifacts: false,
|
|
294
|
+
}, stepBudgetMs, unanalyzed), '', '## 3. Detached DOM — same population, or the same count?', '', await runTool('memlab_population_diff', {
|
|
295
|
+
baseline_handle: 'run_first',
|
|
296
|
+
target_handle: 'run_last',
|
|
297
|
+
population: 'detached',
|
|
298
|
+
group_by: 'owner',
|
|
299
|
+
limit: 15,
|
|
300
|
+
min_delta: 0,
|
|
301
|
+
}, stepBudgetMs, unanalyzed), '', await runTool('memlab_detached_dom', {
|
|
302
|
+
output_mode: 'full',
|
|
303
|
+
group_by: 'dominator',
|
|
304
|
+
limit: 8,
|
|
305
|
+
offset: 0,
|
|
306
|
+
classify_dev_only: true,
|
|
307
|
+
only_with_retainer_path: false,
|
|
308
|
+
}, stepBudgetMs, unanalyzed), '', '## 4. Is it real? (dev/automation artifacts on the final rung)', '', await runTool('memlab_dev_artifacts', {}, stepBudgetMs, unanalyzed), '');
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// ---- Provenance and caveats ----
|
|
312
|
+
out.push('## Round provenance and caveats', '');
|
|
313
|
+
const gating = manifest.gating_verified ?? {};
|
|
314
|
+
const gatingKeys = Object.keys(gating);
|
|
315
|
+
out.push(gatingKeys.length > 0
|
|
316
|
+
? `Gating: ${gatingKeys.length} ABProp(s) verified in-page. ${gatingKeys
|
|
317
|
+
.map(k => `\`${k}\`=${JSON.stringify(gating[k])}`)
|
|
318
|
+
.join(', ')}`
|
|
319
|
+
: '⚠ **No verified gating recorded in this run.** A round driven without its gating manifest re-discovers already-fixed leaks and cannot be compared with a gated round — treat every finding above as provisional.', '');
|
|
320
|
+
const caveats = manifest.caveats ?? [];
|
|
321
|
+
if (caveats.length > 0) {
|
|
322
|
+
out.push('**Caveats recorded by the runner** (these constrain what the analysis above can claim):', ...caveats.map(c => `- ${c}`), '');
|
|
323
|
+
}
|
|
324
|
+
if (unanalyzed.length > 0) {
|
|
325
|
+
out.push('**UNANALYZED** — these protocol steps did not run, so the round is not a clean no-leak result:', ...unanalyzed.map(u => `- ${u}`), '');
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
out.push('_Every step of the protocol ran. "No leak candidates" from a complete run is a genuine no-leak result; the same words from a run with UNANALYZED steps are not._', '');
|
|
329
|
+
}
|
|
330
|
+
const resident = listSnapshots()
|
|
331
|
+
.map(m => m.handle)
|
|
332
|
+
.join(', ');
|
|
333
|
+
if (resident) {
|
|
334
|
+
out.push(`_Resident snapshots: ${resident}. Follow up on a specific object with \`memlab_dominator_chain\` / \`memlab_retainer_trace\`, or unload them with \`memlab_snapshots\`._`);
|
|
335
|
+
}
|
|
336
|
+
return toolResult(out.join('\n'));
|
|
337
|
+
}
|
|
338
|
+
catch (err) {
|
|
339
|
+
return errorResult(err);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=analyze-run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze-run.js","sourceRoot":"","sources":["../../src/tools/analyze-run.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,kBAAkB,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAC,aAAa,EAAoB,MAAM,wBAAwB,CAAC;AACxE,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,qBAAqB,EAAC,MAAM,wBAAwB,CAAC;AAE7D,MAAM,EAAC,mBAAmB,EAAC,GAAG,kBAAkB,CAAC;AAqBjD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,KAAK,UAAU,OAAO,CACpB,IAAY,EACZ,IAA6B,EAC7B,QAAgB,EAChB,UAAoB;IAEpB,MAAM,KAAK,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,KAAK,IAAI,qCAAqC,CAAC;IACzE,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,gBAAgB,EAAE,GAAG,eAAe,EAAE,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,gBAAgB,EAAE,CAAC;IACxC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAI,GAA0C,EAAE,OAAO,CAAC;QACrE,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YACjC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YAC3C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChB,yEAAyE;QACzE,wEAAwE;QACxE,0EAA0E;QAC1E,4EAA4E;QAC5E,4EAA4E;QAC5E,2CAA2C;QAC3C,IAAK,GAA2B,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;YACnD,MAAM,OAAO,GAAG,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1D,UAAU,CAAC,IAAI,CACb,OAAO;gBACL,CAAC,CAAC,GAAG,IAAI,iBAAiB,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe;gBACpE,CAAC,CAAC,GAAG,IAAI,SAAS,CACrB,CAAC;YACF,OAAO,OAAO;gBACZ,CAAC,CAAC,KAAK,IAAI,iBAAiB,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,8HAA8H,IAAI,EAAE;gBAC3L,CAAC,CAAC,IAAI,CAAC;QACX,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,QAAQ,GACZ,GAAG,YAAY,gBAAgB,IAAI,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrE,UAAU,CAAC,IAAI,CACb,QAAQ;YACN,CAAC,CAAC,GAAG,IAAI,iBAAiB,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,eAAe;YACpE,CAAC,CAAC,GAAG,IAAI,SAAS,CACrB,CAAC;QACF,OAAO,QAAQ;YACb,CAAC,CAAC,KAAK,IAAI,iBAAiB,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,qJAAqJ;YAC5M,CAAC,CAAC,KAAK,IAAI,YAAY,GAAG,IAAI,CAAC;IACnC,CAAC;YAAS,CAAC;QACT,qEAAqE;QACrE,0EAA0E;QAC1E,oBAAoB;QACpB,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,iBAAiB,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,KAAK,UAAU,QAAQ,CAAC,QAAgB,EAAE,KAAa;IACrD,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACrD,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;QACzB,SAAS,EAAE,CAAC;QACZ,SAAS,IAAI,CAAC,CAAC,SAAS,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC1B,SAAS,EAAE,CAAC;IACd,CAAC,CAAC,CAAC;IACH,WAAW,CACT,QAAQ,EACR,QAAQ,EACR;QACE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACjC,SAAS;QACT,SAAS;QACT,SAAS;QACT,GAAG,EAAE,SAAS;KACf,EACD,EAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAC,CACxB,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,IAAY,EAAE,IAAY,EAAE,MAAM,GAAG,EAAE;IACzD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,YAAY,IAAI,GAAG,CAAC;IAClD,OAAO,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,gXAAgX;QAC9W,mVAAmV;QACnV,0PAA0P;QAC1P,8gBAA8gB,EAChhB;QACE,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,CACP,oFAAoF,CACrF;QACH,oBAAoB,EAAE,CAAC;aACpB,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wHAAwH,CACzH;QACH,GAAG,EAAE,CAAC;aACH,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,OAAO,CAAC,EAAE,CAAC;aACX,QAAQ,CAAC,sDAAsD,CAAC;QACnE,cAAc,EAAE,CAAC;aACd,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,OAAO,CAAC,KAAK,CAAC;aACd,QAAQ,CACP,qLAAqL,CACtL;QACH,cAAc,EAAE,CAAC;aACd,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,OAAO,CAAC,GAAG,CAAC;aACZ,QAAQ,CACP,kQAAkQ,CACnQ;QACH,gBAAgB,EAAE,CAAC;aAChB,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,oCAAoC,CAAC;KAClD,EACD,KAAK,EAAE,EACL,QAAQ,EACR,oBAAoB,EACpB,GAAG,EACH,cAAc,EACd,cAAc,EACd,gBAAgB,GACjB,EAAE,EAAE;QACH,IAAI,CAAC;YACH,IAAI,YAAY,GAAG,QAAQ,CAAC;YAC5B,IACE,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;gBAC3B,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,EACvC,CAAC;gBACD,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACjC,OAAO,WAAW,CAAC,kBAAkB,YAAY,GAAG,CAAC,CAAC;YACxD,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACzB,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CACvB,CAAC;YACjB,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACxE,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAC7D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,WAAW,CAChB,eAAe,KAAK,CAAC,MAAM,oDAAoD;oBAC7E,CAAC,OAAO,GAAG,CAAC;wBACV,CAAC,CAAC,GAAG,OAAO,kIAAkI;wBAC9I,CAAC,CAAC,kHAAkH,CAAC,CAC1H,CAAC;YACJ,CAAC;YAED,sEAAsE;YACtE,wEAAwE;YACxE,8CAA8C;YAC9C,MAAM,UAAU,GAAa,EAAE,CAAC;YAChC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,IAAI,CAAC;YACxD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAChB,UAAU,CAAC,IAAI,CACb,GAAG,OAAO,wEAAwE,CACnF,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrC,MAAM,aAAa,GACjB,oBAAoB;gBACpB,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;oBACf,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;oBAC/D,CAAC,CAAC,CAAC,CAAC,CAAC;YAET,MAAM,GAAG,GAAa;gBACpB,0BAA0B,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE;gBACxF,EAAE;gBACF,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,cAAc,qBAAqB,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC,WAAW,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,MAAM,aAAa,YAAY,CAAC,aAAa,CAAC,uBAAuB;gBACnU,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE;gBAClE,EAAE;gBACF,WAAW;gBACX,EAAE;gBACF,aAAa,CACX,CAAC,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,CAAC,EAC5C,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBACb,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;oBACf,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;oBACtB,GAAG,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;oBACpC,CAAC,CAAC,MAAM,IAAI,EAAE;iBACf,CAAC,EACF,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CACnB;gBACD,EAAE;aACH,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAElB,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,eAAe,CAAC;YAC/D,GAAG,CAAC,IAAI,CACN,kCAAkC,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,6QAA6Q,EAC/V,EAAE,CACH,CAAC;YAEF,wEAAwE;YACxE,GAAG,CAAC,IAAI,CAAC,yCAAyC,EAAE,EAAE,CAAC,CAAC;YACxD,IAAI,OAAO,GAON,EAAE,CAAC;YACR,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,KAAK,EAAE;oBAChD,cAAc,EAAE,CAAC;oBACjB,aAAa,EAAE,gBAAgB;oBAC/B,QAAQ,EAAE,oBAAoB;iBAC/B,CAAC,CAAC;gBACH,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBAC5C,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,QAAQ,EAAE,CAAC,CAAC,QAAQ;iBACrB,CAAC,CAAC,CAAC;gBACJ,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACzB,GAAG,CAAC,IAAI,CACN,yKAAyK,EACzK,EAAE,CACH,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,IAAI,CACN,aAAa,CACX;wBACE,OAAO;wBACP,MAAM;wBACN,SAAS;wBACT,SAAS;wBACT,QAAQ;wBACR,cAAc;qBACf,EACD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;wBACf,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;wBAC1B,CAAC,CAAC,IAAI;wBACN,IAAI,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE;wBAC9B,aAAa,GAAG,CAAC;4BACf,CAAC,CAAC,CACE,CAAC,CAAC,QAAQ;gCACV,CAAC,aAAa,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CACrC,CAAC,OAAO,CAAC,CAAC,CAAC;4BACd,CAAC,CAAC,GAAG;wBACP,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE;wBACvD,CAAC,CAAC,QAAQ,IAAI,IAAI;4BAChB,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC;4BAC3B,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,cAAc;gCAC1B,CAAC,CAAC,+BAA+B;gCACjC,CAAC,CAAC,yBAAyB;qBAChC,CAAC,EACF,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CACnB,EACD,EAAE,CACH,CAAC;oBACF,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAC/B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,cAAc,CACtD,CAAC;oBACF,GAAG,CAAC,IAAI,CACN,UAAU,CAAC,MAAM,GAAG,CAAC;wBACnB,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,uDAAuD,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mFAAmF;wBACzO,CAAC,CAAC,uIAAuI,EAC3I,EAAE,CACH,CAAC;gBACJ,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CACN,uBAAuB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAC1E,EAAE,CACH,CAAC;gBACF,UAAU,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YAC5C,CAAC;YAED,wCAAwC;YACxC,IAAI,cAAc,EAAE,CAAC;gBACnB,UAAU,CAAC,IAAI,CACb,sGAAsG,CACvG,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,mEAAmE;gBACnE,gEAAgE;gBAChE,oEAAoE;gBACpE,iBAAiB,EAAE,CAAC;gBACpB,IAAI,MAAM,GAAG,KAAK,CAAC;gBACnB,IAAI,CAAC;oBACH,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;oBACxC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;oBACtC,MAAM,GAAG,IAAI,CAAC;gBAChB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,GAAG,CAAC,IAAI,CACN,wCAAwC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,uDAAuD,EAC/I,EAAE,CACH,CAAC;oBACF,UAAU,CAAC,IAAI,CACb,4FAA4F,CAC7F,CAAC;gBACJ,CAAC;gBAED,IAAI,MAAM,EAAE,CAAC;oBACX,kBAAkB,CAAC,UAAU,CAAC,CAAC;oBAC/B,GAAG,CAAC,IAAI,CACN,2BAA2B,EAC3B,EAAE,EACF,MAAM,OAAO,CACX,sBAAsB,EACtB;wBACE,eAAe,EAAE,WAAW;wBAC5B,aAAa,EAAE,UAAU;wBACzB,KAAK,EAAE,EAAE;wBACT,eAAe,EAAE,KAAK;wBACtB,iBAAiB,EAAE,KAAK;qBACzB,EACD,YAAY,EACZ,UAAU,CACX,EACD,EAAE,EACF,0DAA0D,EAC1D,EAAE,EACF,MAAM,OAAO,CACX,wBAAwB,EACxB;wBACE,eAAe,EAAE,WAAW;wBAC5B,aAAa,EAAE,UAAU;wBACzB,UAAU,EAAE,UAAU;wBACtB,QAAQ,EAAE,OAAO;wBACjB,KAAK,EAAE,EAAE;wBACT,SAAS,EAAE,CAAC;qBACb,EACD,YAAY,EACZ,UAAU,CACX,EACD,EAAE,EACF,MAAM,OAAO,CACX,qBAAqB,EACrB;wBACE,WAAW,EAAE,MAAM;wBACnB,QAAQ,EAAE,WAAW;wBACrB,KAAK,EAAE,CAAC;wBACR,MAAM,EAAE,CAAC;wBACT,iBAAiB,EAAE,IAAI;wBACvB,uBAAuB,EAAE,KAAK;qBAC/B,EACD,YAAY,EACZ,UAAU,CACX,EACD,EAAE,EACF,gEAAgE,EAChE,EAAE,EACF,MAAM,OAAO,CACX,sBAAsB,EACtB,EAAE,EACF,YAAY,EACZ,UAAU,CACX,EACD,EAAE,CACH,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,mCAAmC;YACnC,GAAG,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,QAAQ,CAAC,eAAe,IAAI,EAAE,CAAC;YAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvC,GAAG,CAAC,IAAI,CACN,UAAU,CAAC,MAAM,GAAG,CAAC;gBACnB,CAAC,CAAC,WAAW,UAAU,CAAC,MAAM,gCAAgC,UAAU;qBACnE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;qBACjD,IAAI,CAAC,IAAI,CAAC,EAAE;gBACjB,CAAC,CAAC,kNAAkN,EACtN,EAAE,CACH,CAAC;YACF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;YACvC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,GAAG,CAAC,IAAI,CACN,yFAAyF,EACzF,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAC7B,EAAE,CACH,CAAC;YACJ,CAAC;YACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,GAAG,CAAC,IAAI,CACN,gGAAgG,EAChG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAChC,EAAE,CACH,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,IAAI,CACN,kKAAkK,EAClK,EAAE,CACH,CAAC;YACJ,CAAC;YACD,MAAM,QAAQ,GAAG,aAAa,EAAE;iBAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;iBAClB,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,IAAI,QAAQ,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CACN,wBAAwB,QAAQ,0IAA0I,CAC3K,CAAC;YACJ,CAAC;YACD,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -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 registerAppHeap(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=app-heap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-heap.d.ts","sourceRoot":"","sources":["../../src/tools/app-heap.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAsCvE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqIvD"}
|