@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.
Files changed (205) hide show
  1. package/README.md +18 -14
  2. package/bin/.eslintrc.js +26 -0
  3. package/bin/memlab-cli.js +313 -0
  4. package/dist/artifact-classes.d.ts +86 -0
  5. package/dist/artifact-classes.d.ts.map +1 -0
  6. package/dist/artifact-classes.js +261 -0
  7. package/dist/artifact-classes.js.map +1 -0
  8. package/dist/capture-mode.d.ts +60 -0
  9. package/dist/capture-mode.d.ts.map +1 -0
  10. package/dist/capture-mode.js +39 -0
  11. package/dist/capture-mode.js.map +1 -0
  12. package/dist/guardrail.d.ts.map +1 -1
  13. package/dist/guardrail.js +13 -0
  14. package/dist/guardrail.js.map +1 -1
  15. package/dist/heap-state.d.ts +96 -2
  16. package/dist/heap-state.d.ts.map +1 -1
  17. package/dist/heap-state.js +197 -2
  18. package/dist/heap-state.js.map +1 -1
  19. package/dist/index.js +41 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/progress.d.ts +25 -0
  22. package/dist/progress.d.ts.map +1 -0
  23. package/dist/progress.js +46 -0
  24. package/dist/progress.js.map +1 -0
  25. package/dist/result-handles.d.ts +11 -0
  26. package/dist/result-handles.d.ts.map +1 -0
  27. package/dist/result-handles.js +77 -0
  28. package/dist/result-handles.js.map +1 -0
  29. package/dist/string-index.d.ts +55 -0
  30. package/dist/string-index.d.ts.map +1 -0
  31. package/dist/string-index.js +91 -0
  32. package/dist/string-index.js.map +1 -0
  33. package/dist/tool-registry.d.ts +42 -0
  34. package/dist/tool-registry.d.ts.map +1 -0
  35. package/dist/tool-registry.js +20 -0
  36. package/dist/tool-registry.js.map +1 -0
  37. package/dist/tools/analyze-run.d.ts +12 -0
  38. package/dist/tools/analyze-run.d.ts.map +1 -0
  39. package/dist/tools/analyze-run.js +343 -0
  40. package/dist/tools/analyze-run.js.map +1 -0
  41. package/dist/tools/app-heap.d.ts +12 -0
  42. package/dist/tools/app-heap.d.ts.map +1 -0
  43. package/dist/tools/app-heap.js +140 -0
  44. package/dist/tools/app-heap.js.map +1 -0
  45. package/dist/tools/auto-investigate.d.ts.map +1 -1
  46. package/dist/tools/auto-investigate.js +91 -49
  47. package/dist/tools/auto-investigate.js.map +1 -1
  48. package/dist/tools/batch.d.ts +12 -0
  49. package/dist/tools/batch.d.ts.map +1 -0
  50. package/dist/tools/batch.js +168 -0
  51. package/dist/tools/batch.js.map +1 -0
  52. package/dist/tools/cache-analysis.d.ts.map +1 -1
  53. package/dist/tools/cache-analysis.js +156 -5
  54. package/dist/tools/cache-analysis.js.map +1 -1
  55. package/dist/tools/class-histogram.d.ts.map +1 -1
  56. package/dist/tools/class-histogram.js +14 -3
  57. package/dist/tools/class-histogram.js.map +1 -1
  58. package/dist/tools/collection-trend.d.ts +55 -0
  59. package/dist/tools/collection-trend.d.ts.map +1 -0
  60. package/dist/tools/collection-trend.js +315 -0
  61. package/dist/tools/collection-trend.js.map +1 -0
  62. package/dist/tools/detached-dom.d.ts +2 -0
  63. package/dist/tools/detached-dom.d.ts.map +1 -1
  64. package/dist/tools/detached-dom.js +291 -20
  65. package/dist/tools/detached-dom.js.map +1 -1
  66. package/dist/tools/dev-artifacts.d.ts +62 -6
  67. package/dist/tools/dev-artifacts.d.ts.map +1 -1
  68. package/dist/tools/dev-artifacts.js +466 -23
  69. package/dist/tools/dev-artifacts.js.map +1 -1
  70. package/dist/tools/diff-snapshots.d.ts.map +1 -1
  71. package/dist/tools/diff-snapshots.js +101 -44
  72. package/dist/tools/diff-snapshots.js.map +1 -1
  73. package/dist/tools/dominator-attribution.d.ts +12 -0
  74. package/dist/tools/dominator-attribution.d.ts.map +1 -0
  75. package/dist/tools/dominator-attribution.js +189 -0
  76. package/dist/tools/dominator-attribution.js.map +1 -0
  77. package/dist/tools/dominator-chain.d.ts +12 -0
  78. package/dist/tools/dominator-chain.d.ts.map +1 -0
  79. package/dist/tools/dominator-chain.js +92 -0
  80. package/dist/tools/dominator-chain.js.map +1 -0
  81. package/dist/tools/duplicate-objects.d.ts +12 -0
  82. package/dist/tools/duplicate-objects.d.ts.map +1 -0
  83. package/dist/tools/duplicate-objects.js +172 -0
  84. package/dist/tools/duplicate-objects.js.map +1 -0
  85. package/dist/tools/duplicated-strings.d.ts.map +1 -1
  86. package/dist/tools/duplicated-strings.js +46 -38
  87. package/dist/tools/duplicated-strings.js.map +1 -1
  88. package/dist/tools/eval.d.ts +1 -0
  89. package/dist/tools/eval.d.ts.map +1 -1
  90. package/dist/tools/eval.js +787 -30
  91. package/dist/tools/eval.js.map +1 -1
  92. package/dist/tools/explain-delta.d.ts +12 -0
  93. package/dist/tools/explain-delta.d.ts.map +1 -0
  94. package/dist/tools/explain-delta.js +170 -0
  95. package/dist/tools/explain-delta.js.map +1 -0
  96. package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
  97. package/dist/tools/find-nodes-by-class.js +112 -13
  98. package/dist/tools/find-nodes-by-class.js.map +1 -1
  99. package/dist/tools/finding-index.d.ts +22 -0
  100. package/dist/tools/finding-index.d.ts.map +1 -0
  101. package/dist/tools/finding-index.js +247 -0
  102. package/dist/tools/finding-index.js.map +1 -0
  103. package/dist/tools/for-each.d.ts.map +1 -1
  104. package/dist/tools/for-each.js +15 -3
  105. package/dist/tools/for-each.js.map +1 -1
  106. package/dist/tools/get-references.d.ts.map +1 -1
  107. package/dist/tools/get-references.js +35 -6
  108. package/dist/tools/get-references.js.map +1 -1
  109. package/dist/tools/get-referrers.d.ts.map +1 -1
  110. package/dist/tools/get-referrers.js +52 -6
  111. package/dist/tools/get-referrers.js.map +1 -1
  112. package/dist/tools/hunt-report.d.ts +12 -0
  113. package/dist/tools/hunt-report.d.ts.map +1 -0
  114. package/dist/tools/hunt-report.js +186 -0
  115. package/dist/tools/hunt-report.js.map +1 -0
  116. package/dist/tools/hypothesis.d.ts +12 -0
  117. package/dist/tools/hypothesis.d.ts.map +1 -0
  118. package/dist/tools/hypothesis.js +221 -0
  119. package/dist/tools/hypothesis.js.map +1 -0
  120. package/dist/tools/intern-opportunities.d.ts.map +1 -1
  121. package/dist/tools/intern-opportunities.js +721 -75
  122. package/dist/tools/intern-opportunities.js.map +1 -1
  123. package/dist/tools/ladder.d.ts +33 -0
  124. package/dist/tools/ladder.d.ts.map +1 -0
  125. package/dist/tools/ladder.js +266 -0
  126. package/dist/tools/ladder.js.map +1 -0
  127. package/dist/tools/largest-objects.d.ts.map +1 -1
  128. package/dist/tools/largest-objects.js +43 -16
  129. package/dist/tools/largest-objects.js.map +1 -1
  130. package/dist/tools/leak-report.d.ts +12 -0
  131. package/dist/tools/leak-report.d.ts.map +1 -0
  132. package/dist/tools/leak-report.js +256 -0
  133. package/dist/tools/leak-report.js.map +1 -0
  134. package/dist/tools/load-snapshot.d.ts +78 -0
  135. package/dist/tools/load-snapshot.d.ts.map +1 -1
  136. package/dist/tools/load-snapshot.js +519 -29
  137. package/dist/tools/load-snapshot.js.map +1 -1
  138. package/dist/tools/map-entries.d.ts +12 -0
  139. package/dist/tools/map-entries.d.ts.map +1 -0
  140. package/dist/tools/map-entries.js +139 -0
  141. package/dist/tools/map-entries.js.map +1 -0
  142. package/dist/tools/match-object.d.ts +12 -0
  143. package/dist/tools/match-object.d.ts.map +1 -0
  144. package/dist/tools/match-object.js +165 -0
  145. package/dist/tools/match-object.js.map +1 -0
  146. package/dist/tools/object-shape.d.ts.map +1 -1
  147. package/dist/tools/object-shape.js +92 -30
  148. package/dist/tools/object-shape.js.map +1 -1
  149. package/dist/tools/population-diff.d.ts +57 -0
  150. package/dist/tools/population-diff.d.ts.map +1 -0
  151. package/dist/tools/population-diff.js +338 -0
  152. package/dist/tools/population-diff.js.map +1 -0
  153. package/dist/tools/quick-diagnosis.d.ts.map +1 -1
  154. package/dist/tools/quick-diagnosis.js +12 -4
  155. package/dist/tools/quick-diagnosis.js.map +1 -1
  156. package/dist/tools/retainer-layers.d.ts +23 -0
  157. package/dist/tools/retainer-layers.d.ts.map +1 -0
  158. package/dist/tools/retainer-layers.js +179 -0
  159. package/dist/tools/retainer-layers.js.map +1 -0
  160. package/dist/tools/retainer-summary.d.ts +1 -0
  161. package/dist/tools/retainer-summary.d.ts.map +1 -1
  162. package/dist/tools/retainer-summary.js +128 -32
  163. package/dist/tools/retainer-summary.js.map +1 -1
  164. package/dist/tools/retainer-trace.d.ts.map +1 -1
  165. package/dist/tools/retainer-trace.js +105 -25
  166. package/dist/tools/retainer-trace.js.map +1 -1
  167. package/dist/tools/search-nodes.d.ts.map +1 -1
  168. package/dist/tools/search-nodes.js +5 -1
  169. package/dist/tools/search-nodes.js.map +1 -1
  170. package/dist/tools/search-strings.d.ts.map +1 -1
  171. package/dist/tools/search-strings.js +53 -7
  172. package/dist/tools/search-strings.js.map +1 -1
  173. package/dist/tools/sequence-analysis.d.ts +49 -0
  174. package/dist/tools/sequence-analysis.d.ts.map +1 -1
  175. package/dist/tools/sequence-analysis.js +268 -78
  176. package/dist/tools/sequence-analysis.js.map +1 -1
  177. package/dist/tools/shape-histogram.d.ts.map +1 -1
  178. package/dist/tools/shape-histogram.js +9 -2
  179. package/dist/tools/shape-histogram.js.map +1 -1
  180. package/dist/tools/sliced-strings.d.ts.map +1 -1
  181. package/dist/tools/sliced-strings.js +22 -4
  182. package/dist/tools/sliced-strings.js.map +1 -1
  183. package/dist/tools/snapshot-header.d.ts +28 -0
  184. package/dist/tools/snapshot-header.d.ts.map +1 -0
  185. package/dist/tools/snapshot-header.js +111 -0
  186. package/dist/tools/snapshot-header.js.map +1 -0
  187. package/dist/tools/string-patterns.d.ts.map +1 -1
  188. package/dist/tools/string-patterns.js +5 -4
  189. package/dist/tools/string-patterns.js.map +1 -1
  190. package/dist/tools/tools-index.d.ts +12 -0
  191. package/dist/tools/tools-index.d.ts.map +1 -0
  192. package/dist/tools/tools-index.js +342 -0
  193. package/dist/tools/tools-index.js.map +1 -0
  194. package/dist/tools/verify-fix.d.ts +23 -0
  195. package/dist/tools/verify-fix.d.ts.map +1 -0
  196. package/dist/tools/verify-fix.js +211 -0
  197. package/dist/tools/verify-fix.js.map +1 -0
  198. package/dist/tools/weakmap-entries.d.ts.map +1 -1
  199. package/dist/tools/weakmap-entries.js +6 -1
  200. package/dist/tools/weakmap-entries.js.map +1 -1
  201. package/dist/utils.d.ts +204 -1
  202. package/dist/utils.d.ts.map +1 -1
  203. package/dist/utils.js +478 -8
  204. package/dist/utils.js.map +1 -1
  205. package/package.json +5 -4
@@ -0,0 +1,315 @@
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 memlabCore from '@memlab/core';
12
+ import { z } from 'zod';
13
+ import { enumerateMapEntries, enumerateSetElements, errorResult, formatNumber, markdownTable, toolResult, } from '../utils.js';
14
+ import { resolveLadderPaths } from './ladder.js';
15
+ import { resolveMaxFileSizeMB, resolveSnapshotPath } from './load-snapshot.js';
16
+ const { utils: memlabUtils } = memlabCore;
17
+ export function parseLocator(spec) {
18
+ const parts = spec
19
+ .split('.')
20
+ .map(s => s.trim())
21
+ .filter(s => s.length > 0);
22
+ if (parts.length < 2) {
23
+ throw new Error(`Locator "${spec}" must be "<OwnerClass>.<property>" (optionally deeper, e.g. "Store.cache.entries").`);
24
+ }
25
+ return { ownerClass: parts[0], path: parts.slice(1), raw: spec };
26
+ }
27
+ /**
28
+ * Follow one named edge. Hidden-class and other internal bookkeeping edges are
29
+ * skipped so a user property named like an internal slot still resolves; a
30
+ * `table` / `backing_store` edge is NOT followed here because the collection
31
+ * enumerators below do that themselves.
32
+ */
33
+ function stepEdge(node, name) {
34
+ for (const edge of node.references) {
35
+ if (edge.type === 'hidden')
36
+ continue;
37
+ if (String(edge.name_or_index) !== name)
38
+ continue;
39
+ const target = edge.toNode;
40
+ if (target.id <= 3)
41
+ return null;
42
+ return target;
43
+ }
44
+ return null;
45
+ }
46
+ export function resolvePath(owner, path) {
47
+ let cur = owner;
48
+ for (const seg of path) {
49
+ if (cur == null)
50
+ return null;
51
+ cur = stepEdge(cur, seg);
52
+ }
53
+ return cur;
54
+ }
55
+ /**
56
+ * Number of entries held by a collection node, by V8 kind.
57
+ *
58
+ * Returns null when the node is not a container — reported as "not a
59
+ * collection" rather than as 0 entries, because those two read identically in a
60
+ * table and mean opposite things (an empty cache vs a mistyped locator).
61
+ */
62
+ export function countEntries(node) {
63
+ const name = node.name;
64
+ if (name === 'Map' || name === 'WeakMap') {
65
+ return enumerateMapEntries(node).length;
66
+ }
67
+ if (name === 'Set' || name === 'WeakSet') {
68
+ return enumerateSetElements(node).length;
69
+ }
70
+ if (name === 'Array' || node.type === 'array') {
71
+ // Element edges hang off either the array node itself or its
72
+ // `(object elements)` backing store, depending on the V8 elements kind, so
73
+ // both are counted. An element lives in exactly one of the two, so summing
74
+ // cannot double-count. (On the Chromium captures checked here the direct
75
+ // form was used throughout; the backing-store branch is for the kinds that
76
+ // are not, and an empty array's shared `elements` store contributes 0.)
77
+ let n = 0;
78
+ let backing = null;
79
+ for (const edge of node.references) {
80
+ if (edge.type === 'element')
81
+ n++;
82
+ else if (String(edge.name_or_index) === 'elements')
83
+ backing = edge.toNode;
84
+ }
85
+ if (backing != null) {
86
+ for (const edge of backing.references) {
87
+ if (edge.type === 'element')
88
+ n++;
89
+ }
90
+ }
91
+ return n;
92
+ }
93
+ if (node.type === 'object') {
94
+ let n = 0;
95
+ for (const edge of node.references) {
96
+ if (edge.type === 'property' &&
97
+ String(edge.name_or_index) !== '__proto__') {
98
+ n++;
99
+ }
100
+ }
101
+ return n;
102
+ }
103
+ return null;
104
+ }
105
+ export function measureLocators(snapshot, locators) {
106
+ const byClass = new Map();
107
+ for (const loc of locators) {
108
+ const list = byClass.get(loc.ownerClass);
109
+ if (list)
110
+ list.push(loc);
111
+ else
112
+ byClass.set(loc.ownerClass, [loc]);
113
+ }
114
+ const out = new Map();
115
+ for (const loc of locators) {
116
+ out.set(loc.raw, {
117
+ owners: 0,
118
+ resolved: 0,
119
+ entries: 0,
120
+ maxEntries: 0,
121
+ nonCollection: false,
122
+ });
123
+ }
124
+ snapshot.nodes.forEach(node => {
125
+ if (node.id <= 3)
126
+ return;
127
+ const locs = byClass.get(node.name);
128
+ if (!locs)
129
+ return;
130
+ for (const loc of locs) {
131
+ const m = out.get(loc.raw);
132
+ if (!m)
133
+ continue;
134
+ m.owners++;
135
+ const target = resolvePath(node, loc.path);
136
+ if (target == null)
137
+ continue;
138
+ const n = countEntries(target);
139
+ if (n == null) {
140
+ m.nonCollection = true;
141
+ continue;
142
+ }
143
+ m.resolved++;
144
+ m.entries += n;
145
+ if (n > m.maxEntries)
146
+ m.maxEntries = n;
147
+ }
148
+ });
149
+ return out;
150
+ }
151
+ /**
152
+ * Load each rung, measure the locators, drop the graph. Uses the LIGHT parse:
153
+ * entry counts come from backing-store edges, so the dominator/retained-size
154
+ * pass this tool would otherwise pay for on every rung buys nothing (measured
155
+ * on a 380 MB capture: 18s → 8s per rung).
156
+ */
157
+ export async function measureLadder(paths, locators, maxFileSizeMB) {
158
+ const labels = [];
159
+ const perRung = [];
160
+ for (const p of paths) {
161
+ let local;
162
+ let fetchedFrom = null;
163
+ try {
164
+ const r = resolveSnapshotPath(p);
165
+ local = r.localPath;
166
+ fetchedFrom = r.fetchedFrom;
167
+ }
168
+ catch (e) {
169
+ throw new Error(`Failed to resolve "${p}": ${e instanceof Error ? e.message : String(e)}`);
170
+ }
171
+ if (!fs.existsSync(local))
172
+ throw new Error(`File not found: ${local}`);
173
+ const sizeMB = fs.statSync(local).size / (1024 * 1024);
174
+ const limit = resolveMaxFileSizeMB(maxFileSizeMB, fetchedFrom != null);
175
+ if (sizeMB > limit) {
176
+ throw new Error(`${p} is ${sizeMB.toFixed(0)} MB — exceeds the ${limit} MB per-file safety limit. Raise it with max_file_size_mb: ${Math.ceil(sizeMB + 100)}.`);
177
+ }
178
+ const snapshot = await memlabUtils.getSnapshotFromFile(local, {
179
+ buildNodeIdIndex: true,
180
+ verbose: false,
181
+ });
182
+ labels.push(fetchedFrom ?? p.replace(/^.*\//, ''));
183
+ perRung.push(measureLocators(snapshot, locators));
184
+ }
185
+ return { labels, perRung };
186
+ }
187
+ function trendOf(series) {
188
+ let up = true;
189
+ for (let i = 1; i < series.length; i++) {
190
+ if (series[i] <= series[i - 1])
191
+ up = false;
192
+ }
193
+ const net = series[series.length - 1] - series[0];
194
+ if (up && net > 0)
195
+ return 'up-every-rung';
196
+ if (net > 0)
197
+ return 'grew-net';
198
+ return 'flat-or-mixed';
199
+ }
200
+ export function registerCollectionTrend(server) {
201
+ server.tool('memlab_collection_trend', 'Track named collections ACROSS a snapshot ladder: entry counts per rung, with per-cycle growth. memlab_cache_analysis, memlab_stale_collections and memlab_growth_signals all answer "how big is this collection now?" on one snapshot; the question that separates a leak from a cache that has simply filled is "did it grow at every rung, and by how much per interaction?" — which needs the ladder. ' +
202
+ 'Collections are named by OWNER CLASS and property path ("LoggerImpl.logs", "Store.cache.entries"), never by node id: ids are per-capture, so an id would track a different object at each rung. Every instance of the owner class is measured, so both a singleton\'s collection and a per-instance one are visible (totals and the largest single instance are reported separately). ' +
203
+ 'Measured examples from one hunt: undoStack 5 → 2,205, allFamiliesByID 3 → 16,367, LoggerImpl.logs 8,790 → 20,700 — all invisible to a single-snapshot view. ' +
204
+ 'Loads each rung transiently in LIGHT mode (one graph resident at a time), so it is safe on ladders too large to hold in memory at once.', {
205
+ paths: z
206
+ .array(z.string())
207
+ .describe('Ordered snapshot paths, OLDEST FIRST. A single ["ladder:<name>"] element expands to a saved ladder (see memlab_ladder).'),
208
+ locators: z
209
+ .array(z.string())
210
+ .describe('Collections to track, as "<OwnerClass>.<property>" (deeper paths allowed: "Store.cache.entries"). The owner class is the node class name as it appears in memlab_class_histogram.'),
211
+ cycles: z
212
+ .number()
213
+ .optional()
214
+ .describe('Interaction cycles driven BETWEEN consecutive rungs. When given, growth is also reported per cycle — the figure that says whether a fix has to bound the collection or merely size it.'),
215
+ max_file_size_mb: z
216
+ .number()
217
+ .optional()
218
+ .describe('Per-file size limit override (MB).'),
219
+ }, async ({ paths, locators, cycles, max_file_size_mb }) => {
220
+ try {
221
+ const { paths: resolvedPaths, ladder } = resolveLadderPaths(paths);
222
+ if (resolvedPaths.length < 2) {
223
+ return errorResult(`memlab_collection_trend needs at least 2 snapshots; got ${resolvedPaths.length}. A trend cannot be read from one rung — use memlab_cache_analysis for a single snapshot.`);
224
+ }
225
+ if (locators.length === 0) {
226
+ return errorResult('locators is empty — pass at least one "<OwnerClass>.<property>".');
227
+ }
228
+ const parsed = locators.map(parseLocator);
229
+ const effectiveCycles = cycles ??
230
+ (ladder?.cycles != null && resolvedPaths.length > 1
231
+ ? ladder.cycles / (resolvedPaths.length - 1)
232
+ : undefined);
233
+ const { labels, perRung } = await measureLadder(resolvedPaths, parsed, max_file_size_mb);
234
+ const n = perRung.length;
235
+ const headers = [
236
+ 'Collection',
237
+ ...labels.map((l, i) => `r${i}: ${l.length > 18 ? l.slice(0, 15) + '…' : l}`),
238
+ 'Δ total',
239
+ ...(effectiveCycles ? ['Δ/cycle'] : []),
240
+ 'Trend',
241
+ ];
242
+ const rows = [];
243
+ const notes = [];
244
+ for (const loc of parsed) {
245
+ const series = perRung.map(m => m.get(loc.raw)?.entries ?? 0);
246
+ const owners = perRung.map(m => m.get(loc.raw)?.owners ?? 0);
247
+ const resolved = perRung.map(m => m.get(loc.raw)?.resolved ?? 0);
248
+ const net = series[n - 1] - series[0];
249
+ const trend = trendOf(series);
250
+ rows.push([
251
+ loc.raw,
252
+ ...series.map(v => formatNumber(v)),
253
+ `${net >= 0 ? '+' : '−'}${formatNumber(Math.abs(net))}`,
254
+ ...(effectiveCycles
255
+ ? [
256
+ (net / (effectiveCycles * (n - 1))).toFixed(Math.abs(net / (effectiveCycles * (n - 1))) < 10 ? 2 : 0),
257
+ ]
258
+ : []),
259
+ trend === 'up-every-rung'
260
+ ? '↑ every rung'
261
+ : trend === 'grew-net'
262
+ ? '↑ net'
263
+ : 'flat/mixed',
264
+ ]);
265
+ if (owners.every(o => o === 0)) {
266
+ notes.push(`- ⚠ \`${loc.raw}\`: no node of class \`${loc.ownerClass}\` exists in any rung. Check the class name against \`memlab_class_histogram\` — this row's zeros mean "not found", not "empty".`);
267
+ }
268
+ else if (resolved.every(r => r === 0)) {
269
+ notes.push(`- ⚠ \`${loc.raw}\`: \`${loc.ownerClass}\` exists but the path \`.${loc.path.join('.')}\` never resolved to a collection. Inspect one instance with \`memlab_object_shape\`.`);
270
+ }
271
+ else {
272
+ const maxAtEnd = perRung[n - 1].get(loc.raw);
273
+ if (maxAtEnd && maxAtEnd.resolved > 1) {
274
+ const firstMax = perRung[0].get(loc.raw)?.maxEntries ?? 0;
275
+ const ownersGrew = net > 0 && maxAtEnd.maxEntries <= firstMax * 1.2;
276
+ notes.push(`- \`${loc.raw}\`: ${formatNumber(maxAtEnd.resolved)} instance(s) at the last rung; largest single collection holds ${formatNumber(maxAtEnd.maxEntries)} entries.` +
277
+ (ownersGrew
278
+ ? ` The total grew while the largest instance did not — the OWNERS are accumulating, not the collection. Track \`${loc.ownerClass}\` itself with \`memlab_sequence_analysis\`.`
279
+ : ''));
280
+ }
281
+ if (maxAtEnd?.nonCollection) {
282
+ notes.push(`- ⚠ \`${loc.raw}\`: at least one instance resolved to something that is not a container; those instances are excluded from the counts.`);
283
+ }
284
+ }
285
+ }
286
+ const lines = [
287
+ `## Collection trend across ${n} rung(s)`,
288
+ '',
289
+ markdownTable(headers, rows, new Set(headers
290
+ .map((_, i) => i)
291
+ .filter(i => i > 0 && i < headers.length - 1))),
292
+ ];
293
+ if (effectiveCycles) {
294
+ lines.push('', `_Δ/cycle assumes ${formatNumber(Math.round(effectiveCycles))} interaction cycle(s) between consecutive rungs${cycles == null ? ' (from the saved ladder)' : ''}._`);
295
+ }
296
+ else {
297
+ lines.push('', '_Pass `cycles` (interactions driven between rungs) to get per-cycle growth — the number that distinguishes a collection that must be BOUNDED from one that merely needs a bigger initial size._');
298
+ }
299
+ if (notes.length > 0)
300
+ lines.push('', ...notes);
301
+ const growers = parsed.filter(loc => {
302
+ const series = perRung.map(m => m.get(loc.raw)?.entries ?? 0);
303
+ return trendOf(series) === 'up-every-rung';
304
+ });
305
+ lines.push('', growers.length > 0
306
+ ? `**${formatNumber(growers.length)} collection(s) grew at EVERY rung** (${growers.map(g => `\`${g.raw}\``).join(', ')}) — monotonic growth under a repeated interaction is the signature of an unbounded collection. Confirm the entries are distinct (not one object re-added) with \`memlab_map_entries\`, then \`memlab_retainer_trace\` the owner.`
307
+ : '**No collection grew at every rung.** Net growth without monotonicity is usually a cache filling toward its cap; re-run with more rungs, or check `memlab_cache_analysis` for the cap.');
308
+ return toolResult(lines.join('\n'));
309
+ }
310
+ catch (err) {
311
+ return errorResult(err);
312
+ }
313
+ });
314
+ }
315
+ //# sourceMappingURL=collection-trend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection-trend.js","sourceRoot":"","sources":["../../src/tools/collection-trend.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,UAAU,MAAM,cAAc,CAAC;AACtC,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAC,oBAAoB,EAAE,mBAAmB,EAAC,MAAM,oBAAoB,CAAC;AAE7E,MAAM,EAAC,KAAK,EAAE,WAAW,EAAC,GAAG,UAAU,CAAC;AAiBxC,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,KAAK,GAAG,IAAI;SACf,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SAClB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,sFAAsF,CACvG,CAAC;IACJ,CAAC;IACD,OAAO,EAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,IAAe,EAAE,IAAY;IAC7C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACnC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,SAAS;QACrC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,IAAI;YAAE,SAAS;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,MAAM,CAAC,EAAE,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,KAAgB,EAChB,IAAc;IAEd,IAAI,GAAG,GAAqB,KAAK,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;QAC7B,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,IAAe;IAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACzC,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAC1C,CAAC;IACD,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACzC,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAC3C,CAAC;IACD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC9C,6DAA6D;QAC7D,2EAA2E;QAC3E,2EAA2E;QAC3E,yEAAyE;QACzE,2EAA2E;QAC3E,wEAAwE;QACxE,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,IAAI,OAAO,GAAqB,IAAI,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;gBAAE,CAAC,EAAE,CAAC;iBAC5B,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,UAAU;gBAAE,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5E,CAAC;QACD,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;gBACtC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;oBAAE,CAAC,EAAE,CAAC;YACnC,CAAC;QACH,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACnC,IACE,IAAI,CAAC,IAAI,KAAK,UAAU;gBACxB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,WAAW,EAC1C,CAAC;gBACD,CAAC,EAAE,CAAC;YACN,CAAC;QACH,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAgBD,MAAM,UAAU,eAAe,CAC7B,QAAuB,EACvB,QAAmB;IAEnB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC7C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;;YACpB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,EAA8B,CAAC;IAClD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE;YACf,MAAM,EAAE,CAAC;YACT,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,CAAC;YACV,UAAU,EAAE,CAAC;YACb,aAAa,EAAE,KAAK;SACrB,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAC5B,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC;YAAE,OAAO;QACzB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,CAAC,CAAC;gBAAE,SAAS;YACjB,CAAC,CAAC,MAAM,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,MAAM,IAAI,IAAI;gBAAE,SAAS;YAC7B,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YAC/B,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;gBACd,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,CAAC,CAAC,QAAQ,EAAE,CAAC;YACb,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU;gBAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAe,EACf,QAAmB,EACnB,aAAsB;IAEtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAsC,EAAE,CAAC;IACtD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,KAAa,CAAC;QAClB,IAAI,WAAW,GAAkB,IAAI,CAAC;QACtC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;YACjC,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC;YACpB,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;QAC9B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACb,sBAAsB,CAAC,MAAM,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC1E,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,EAAE,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,oBAAoB,CAAC,aAAa,EAAE,WAAW,IAAI,IAAI,CAAC,CAAC;QACvE,IAAI,MAAM,GAAG,KAAK,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,GAAG,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,KAAK,8DAA8D,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,CAC/I,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,mBAAmB,CAAC,KAAK,EAAE;YAC5D,gBAAgB,EAAE,IAAI;YACtB,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC;AAC3B,CAAC;AAED,SAAS,OAAO,CACd,MAAgB;IAEhB,IAAI,EAAE,GAAG,IAAI,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;YAAE,EAAE,GAAG,KAAK,CAAC;IAC7C,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAClD,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,eAAe,CAAC;IAC1C,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,UAAU,CAAC;IAC/B,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,IAAI,CACT,yBAAyB,EACzB,4YAA4Y;QAC1Y,wXAAwX;QACxX,8JAA8J;QAC9J,yIAAyI,EAC3I;QACE,KAAK,EAAE,CAAC;aACL,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,CACP,yHAAyH,CAC1H;QACH,QAAQ,EAAE,CAAC;aACR,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aACjB,QAAQ,CACP,mLAAmL,CACpL;QACH,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,wLAAwL,CACzL;QACH,gBAAgB,EAAE,CAAC;aAChB,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,oCAAoC,CAAC;KAClD,EACD,KAAK,EAAE,EAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAC,EAAE,EAAE;QACpD,IAAI,CAAC;YACH,MAAM,EAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YACjE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,OAAO,WAAW,CAChB,2DAA2D,aAAa,CAAC,MAAM,2FAA2F,CAC3K,CAAC;YACJ,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,WAAW,CAChB,kEAAkE,CACnE,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC1C,MAAM,eAAe,GACnB,MAAM;gBACN,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;oBACjD,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;oBAC5C,CAAC,CAAC,SAAS,CAAC,CAAC;YAEjB,MAAM,EAAC,MAAM,EAAE,OAAO,EAAC,GAAG,MAAM,aAAa,CAC3C,aAAa,EACb,MAAM,EACN,gBAAgB,CACjB,CAAC;YACF,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;YAEzB,MAAM,OAAO,GAAG;gBACd,YAAY;gBACZ,GAAG,MAAM,CAAC,GAAG,CACX,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAC/D;gBACD,SAAS;gBACT,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,OAAO;aACR,CAAC;YACF,MAAM,IAAI,GAAe,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;gBAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC,CAAC,CAAC;gBAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC,CAAC;gBACjE,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACtC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC9B,IAAI,CAAC,IAAI,CAAC;oBACR,GAAG,CAAC,GAAG;oBACP,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBACnC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;oBACvD,GAAG,CAAC,eAAe;wBACjB,CAAC,CAAC;4BACE,CAAC,GAAG,GAAG,CAAC,eAAe,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CACzC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,eAAe,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACzD;yBACF;wBACH,CAAC,CAAC,EAAE,CAAC;oBACP,KAAK,KAAK,eAAe;wBACvB,CAAC,CAAC,cAAc;wBAChB,CAAC,CAAC,KAAK,KAAK,UAAU;4BACpB,CAAC,CAAC,OAAO;4BACT,CAAC,CAAC,YAAY;iBACnB,CAAC,CAAC;gBAEH,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBAC/B,KAAK,CAAC,IAAI,CACR,SAAS,GAAG,CAAC,GAAG,0BAA0B,GAAG,CAAC,UAAU,kIAAkI,CAC3L,CAAC;gBACJ,CAAC;qBAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;oBACxC,KAAK,CAAC,IAAI,CACR,SAAS,GAAG,CAAC,GAAG,SAAS,GAAG,CAAC,UAAU,6BAA6B,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,uFAAuF,CAC9K,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAC7C,IAAI,QAAQ,IAAI,QAAQ,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;wBACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,UAAU,IAAI,CAAC,CAAC;wBAC1D,MAAM,UAAU,GACd,GAAG,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,IAAI,QAAQ,GAAG,GAAG,CAAC;wBACnD,KAAK,CAAC,IAAI,CACR,OAAO,GAAG,CAAC,GAAG,OAAO,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,kEAAkE,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW;4BAChK,CAAC,UAAU;gCACT,CAAC,CAAC,iHAAiH,GAAG,CAAC,UAAU,8CAA8C;gCAC/K,CAAC,CAAC,EAAE,CAAC,CACV,CAAC;oBACJ,CAAC;oBACD,IAAI,QAAQ,EAAE,aAAa,EAAE,CAAC;wBAC5B,KAAK,CAAC,IAAI,CACR,SAAS,GAAG,CAAC,GAAG,wHAAwH,CACzI,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,KAAK,GAAa;gBACtB,8BAA8B,CAAC,UAAU;gBACzC,EAAE;gBACF,aAAa,CACX,OAAO,EACP,IAAI,EACJ,IAAI,GAAG,CACL,OAAO;qBACJ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;qBAChB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAChD,CACF;aACF,CAAC;YACF,IAAI,eAAe,EAAE,CAAC;gBACpB,KAAK,CAAC,IAAI,CACR,EAAE,EACF,oBAAoB,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,kDAAkD,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE,IAAI,CACpK,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CACR,EAAE,EACF,iMAAiM,CAClM,CAAC;YACJ,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,KAAK,CAAC,CAAC;YAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;gBAClC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;gBAC9D,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,eAAe,CAAC;YAC7C,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CACR,EAAE,EACF,OAAO,CAAC,MAAM,GAAG,CAAC;gBAChB,CAAC,CAAC,KAAK,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,wCAAwC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,kOAAkO;gBACxV,CAAC,CAAC,wLAAwL,CAC7L,CAAC;YACF,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -8,5 +8,7 @@
8
8
  * @oncall memory_lab
9
9
  */
10
10
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
11
+ import type { IHeapNode } from '@memlab/core';
12
+ export declare function getFirstNonFrameworkRetainer(node: IHeapNode): string;
11
13
  export declare function registerDetachedDom(server: McpServer): void;
12
14
  //# sourceMappingURL=detached-dom.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detached-dom.d.ts","sourceRoot":"","sources":["../../src/tools/detached-dom.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AA4EvE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoM3D"}
1
+ {"version":3,"file":"detached-dom.d.ts","sourceRoot":"","sources":["../../src/tools/detached-dom.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAGvE,OAAO,KAAK,EAAC,SAAS,EAA2B,MAAM,cAAc,CAAC;AAgGtE,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAmCpE;AAuGD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2X3D"}