@memlab/mcp-server 2.18.1 โ†’ 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 (186) hide show
  1. package/README.md +8 -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 +89 -2
  16. package/dist/heap-state.d.ts.map +1 -1
  17. package/dist/heap-state.js +186 -2
  18. package/dist/heap-state.js.map +1 -1
  19. package/dist/index.js +39 -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/batch.d.ts +12 -0
  46. package/dist/tools/batch.d.ts.map +1 -0
  47. package/dist/tools/batch.js +168 -0
  48. package/dist/tools/batch.js.map +1 -0
  49. package/dist/tools/cache-analysis.d.ts.map +1 -1
  50. package/dist/tools/cache-analysis.js +156 -5
  51. package/dist/tools/cache-analysis.js.map +1 -1
  52. package/dist/tools/class-histogram.d.ts.map +1 -1
  53. package/dist/tools/class-histogram.js +14 -3
  54. package/dist/tools/class-histogram.js.map +1 -1
  55. package/dist/tools/collection-trend.d.ts +55 -0
  56. package/dist/tools/collection-trend.d.ts.map +1 -0
  57. package/dist/tools/collection-trend.js +315 -0
  58. package/dist/tools/collection-trend.js.map +1 -0
  59. package/dist/tools/detached-dom.d.ts +2 -0
  60. package/dist/tools/detached-dom.d.ts.map +1 -1
  61. package/dist/tools/detached-dom.js +291 -20
  62. package/dist/tools/detached-dom.js.map +1 -1
  63. package/dist/tools/dev-artifacts.d.ts +62 -6
  64. package/dist/tools/dev-artifacts.d.ts.map +1 -1
  65. package/dist/tools/dev-artifacts.js +466 -23
  66. package/dist/tools/dev-artifacts.js.map +1 -1
  67. package/dist/tools/dominator-attribution.d.ts +12 -0
  68. package/dist/tools/dominator-attribution.d.ts.map +1 -0
  69. package/dist/tools/dominator-attribution.js +189 -0
  70. package/dist/tools/dominator-attribution.js.map +1 -0
  71. package/dist/tools/dominator-chain.d.ts +12 -0
  72. package/dist/tools/dominator-chain.d.ts.map +1 -0
  73. package/dist/tools/dominator-chain.js +92 -0
  74. package/dist/tools/dominator-chain.js.map +1 -0
  75. package/dist/tools/duplicate-objects.d.ts +12 -0
  76. package/dist/tools/duplicate-objects.d.ts.map +1 -0
  77. package/dist/tools/duplicate-objects.js +172 -0
  78. package/dist/tools/duplicate-objects.js.map +1 -0
  79. package/dist/tools/duplicated-strings.d.ts.map +1 -1
  80. package/dist/tools/duplicated-strings.js +46 -38
  81. package/dist/tools/duplicated-strings.js.map +1 -1
  82. package/dist/tools/eval.d.ts +1 -0
  83. package/dist/tools/eval.d.ts.map +1 -1
  84. package/dist/tools/eval.js +785 -28
  85. package/dist/tools/eval.js.map +1 -1
  86. package/dist/tools/explain-delta.d.ts +12 -0
  87. package/dist/tools/explain-delta.d.ts.map +1 -0
  88. package/dist/tools/explain-delta.js +170 -0
  89. package/dist/tools/explain-delta.js.map +1 -0
  90. package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
  91. package/dist/tools/find-nodes-by-class.js +112 -13
  92. package/dist/tools/find-nodes-by-class.js.map +1 -1
  93. package/dist/tools/finding-index.d.ts +22 -0
  94. package/dist/tools/finding-index.d.ts.map +1 -0
  95. package/dist/tools/finding-index.js +247 -0
  96. package/dist/tools/finding-index.js.map +1 -0
  97. package/dist/tools/for-each.d.ts.map +1 -1
  98. package/dist/tools/for-each.js +15 -3
  99. package/dist/tools/for-each.js.map +1 -1
  100. package/dist/tools/get-referrers.d.ts.map +1 -1
  101. package/dist/tools/get-referrers.js +17 -0
  102. package/dist/tools/get-referrers.js.map +1 -1
  103. package/dist/tools/hunt-report.d.ts +12 -0
  104. package/dist/tools/hunt-report.d.ts.map +1 -0
  105. package/dist/tools/hunt-report.js +186 -0
  106. package/dist/tools/hunt-report.js.map +1 -0
  107. package/dist/tools/hypothesis.d.ts +12 -0
  108. package/dist/tools/hypothesis.d.ts.map +1 -0
  109. package/dist/tools/hypothesis.js +221 -0
  110. package/dist/tools/hypothesis.js.map +1 -0
  111. package/dist/tools/intern-opportunities.d.ts.map +1 -1
  112. package/dist/tools/intern-opportunities.js +112 -47
  113. package/dist/tools/intern-opportunities.js.map +1 -1
  114. package/dist/tools/ladder.d.ts +33 -0
  115. package/dist/tools/ladder.d.ts.map +1 -0
  116. package/dist/tools/ladder.js +266 -0
  117. package/dist/tools/ladder.js.map +1 -0
  118. package/dist/tools/largest-objects.d.ts.map +1 -1
  119. package/dist/tools/largest-objects.js +6 -2
  120. package/dist/tools/largest-objects.js.map +1 -1
  121. package/dist/tools/leak-report.d.ts +12 -0
  122. package/dist/tools/leak-report.d.ts.map +1 -0
  123. package/dist/tools/leak-report.js +256 -0
  124. package/dist/tools/leak-report.js.map +1 -0
  125. package/dist/tools/load-snapshot.d.ts +18 -0
  126. package/dist/tools/load-snapshot.d.ts.map +1 -1
  127. package/dist/tools/load-snapshot.js +211 -13
  128. package/dist/tools/load-snapshot.js.map +1 -1
  129. package/dist/tools/map-entries.d.ts +12 -0
  130. package/dist/tools/map-entries.d.ts.map +1 -0
  131. package/dist/tools/map-entries.js +139 -0
  132. package/dist/tools/map-entries.js.map +1 -0
  133. package/dist/tools/match-object.d.ts +12 -0
  134. package/dist/tools/match-object.d.ts.map +1 -0
  135. package/dist/tools/match-object.js +165 -0
  136. package/dist/tools/match-object.js.map +1 -0
  137. package/dist/tools/object-shape.d.ts.map +1 -1
  138. package/dist/tools/object-shape.js +53 -5
  139. package/dist/tools/object-shape.js.map +1 -1
  140. package/dist/tools/population-diff.d.ts +57 -0
  141. package/dist/tools/population-diff.d.ts.map +1 -0
  142. package/dist/tools/population-diff.js +338 -0
  143. package/dist/tools/population-diff.js.map +1 -0
  144. package/dist/tools/retainer-layers.d.ts +23 -0
  145. package/dist/tools/retainer-layers.d.ts.map +1 -0
  146. package/dist/tools/retainer-layers.js +179 -0
  147. package/dist/tools/retainer-layers.js.map +1 -0
  148. package/dist/tools/retainer-summary.d.ts +1 -0
  149. package/dist/tools/retainer-summary.d.ts.map +1 -1
  150. package/dist/tools/retainer-summary.js +128 -32
  151. package/dist/tools/retainer-summary.js.map +1 -1
  152. package/dist/tools/retainer-trace.d.ts.map +1 -1
  153. package/dist/tools/retainer-trace.js +4 -2
  154. package/dist/tools/retainer-trace.js.map +1 -1
  155. package/dist/tools/search-nodes.d.ts.map +1 -1
  156. package/dist/tools/search-nodes.js +5 -1
  157. package/dist/tools/search-nodes.js.map +1 -1
  158. package/dist/tools/search-strings.d.ts.map +1 -1
  159. package/dist/tools/search-strings.js +53 -7
  160. package/dist/tools/search-strings.js.map +1 -1
  161. package/dist/tools/sequence-analysis.d.ts +49 -0
  162. package/dist/tools/sequence-analysis.d.ts.map +1 -1
  163. package/dist/tools/sequence-analysis.js +266 -86
  164. package/dist/tools/sequence-analysis.js.map +1 -1
  165. package/dist/tools/shape-histogram.d.ts.map +1 -1
  166. package/dist/tools/shape-histogram.js +9 -2
  167. package/dist/tools/shape-histogram.js.map +1 -1
  168. package/dist/tools/string-patterns.d.ts.map +1 -1
  169. package/dist/tools/string-patterns.js +5 -4
  170. package/dist/tools/string-patterns.js.map +1 -1
  171. package/dist/tools/tools-index.d.ts +12 -0
  172. package/dist/tools/tools-index.d.ts.map +1 -0
  173. package/dist/tools/tools-index.js +342 -0
  174. package/dist/tools/tools-index.js.map +1 -0
  175. package/dist/tools/verify-fix.d.ts +23 -0
  176. package/dist/tools/verify-fix.d.ts.map +1 -0
  177. package/dist/tools/verify-fix.js +211 -0
  178. package/dist/tools/verify-fix.js.map +1 -0
  179. package/dist/tools/weakmap-entries.d.ts.map +1 -1
  180. package/dist/tools/weakmap-entries.js +6 -1
  181. package/dist/tools/weakmap-entries.js.map +1 -1
  182. package/dist/utils.d.ts +146 -1
  183. package/dist/utils.d.ts.map +1 -1
  184. package/dist/utils.js +335 -10
  185. package/dist/utils.js.map +1 -1
  186. package/package.json +5 -4
@@ -8,5 +8,54 @@
8
8
  * @oncall memory_lab
9
9
  */
10
10
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
11
+ import { type ArtifactKind } from '../artifact-classes.js';
12
+ interface ClassStats {
13
+ count: number;
14
+ selfSize: number;
15
+ }
16
+ export declare function normalizeClassName(name: string): string;
17
+ type Trend = 'monotonic-up' | 'monotonic-down' | 'grew-net' | 'flat-or-mixed';
18
+ export interface SequenceStep {
19
+ label: string;
20
+ localPath: string;
21
+ hist: Map<string, ClassStats>;
22
+ nodeCount: number;
23
+ totalSize: number;
24
+ }
25
+ export interface SequenceRow {
26
+ key: string;
27
+ type: string;
28
+ name: string;
29
+ counts: number[];
30
+ netCount: number;
31
+ netSize: number;
32
+ trend: Trend;
33
+ artifact: ArtifactKind | null;
34
+ }
35
+ export interface SequenceTrends {
36
+ steps: SequenceStep[];
37
+ rows: SequenceRow[];
38
+ keys: Set<string>;
39
+ }
40
+ /**
41
+ * Load an ordered ladder of snapshots and compute per-class growth trends.
42
+ *
43
+ * Extracted from the `memlab_sequence_analysis` handler so it can be composed
44
+ * (see `memlab_leak_report`) instead of re-implemented: the loop that loads each
45
+ * rung, histograms it, and drops the graph before the next is both the expensive
46
+ * part and the part that is easy to get subtly wrong (resolution, size guard,
47
+ * one-graph-resident-at-a-time).
48
+ *
49
+ * Failures THROW rather than returning an MCP error envelope โ€” the callers are
50
+ * tool handlers that already wrap their body in try/catch, and a composed caller
51
+ * needs a failure it cannot accidentally treat as a result.
52
+ */
53
+ export declare function computeSequenceTrends(paths: string[], opts: {
54
+ minGrowthCount: number;
55
+ monotonicOnly?: boolean;
56
+ maxFileSizeMB?: number;
57
+ toolName?: string;
58
+ }): Promise<SequenceTrends>;
11
59
  export declare function registerSequenceAnalysis(server: McpServer): void;
60
+ export {};
12
61
  //# sourceMappingURL=sequence-analysis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sequence-analysis.d.ts","sourceRoot":"","sources":["../../src/tools/sequence-analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAsEvE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2OhE"}
1
+ {"version":3,"file":"sequence-analysis.d.ts","sourceRoot":"","sources":["../../src/tools/sequence-analysis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAqBvE,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAGhC,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAkBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AA0BD,KAAK,KAAK,GAAG,cAAc,GAAG,gBAAgB,GAAG,UAAU,GAAG,eAAe,CAAC;AAgB9E,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IAGd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,YAAY,EAAE,CAAC;IAItB,IAAI,EAAE,WAAW,EAAE,CAAC;IAEpB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE;IACJ,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,cAAc,CAAC,CAyGzB;AAkBD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsShE"}
@@ -11,8 +11,12 @@ import fs from 'fs';
11
11
  import { z } from 'zod';
12
12
  import memlabHeapAnalysis from '@memlab/heap-analysis';
13
13
  const { getFullHeapFromFile } = memlabHeapAnalysis;
14
- import { resolveSnapshotPath } from './load-snapshot.js';
14
+ import { LOCAL_FILE_SIZE_LIMIT_MB, MANIFOLD_FETCH_SIZE_LIMIT_MB, resolveMaxFileSizeMB, resolveSnapshotPath, } from './load-snapshot.js';
15
15
  import { formatBytes, formatNumber, markdownTable, errorResult, toolResult, } from '../utils.js';
16
+ import { resolveLadderPaths } from './ladder.js';
17
+ import { resetEmittedNotes, shouldEmitNote } from '../heap-state.js';
18
+ import { artifactLabel, artifactNote, classifyArtifact, } from '../artifact-classes.js';
19
+ import { classifyNumericCapture, SMI_NUMBER_CLASS_KEY } from '../capture-mode.js';
16
20
  // A class key is "<type>::<name>". Value-named string "classes" (literal
17
21
  // values used as the name, e.g. "554", "1780525701808.81", "o:10,add") are
18
22
  // noise across a sequence โ€” drop them like diff_snapshots does (ยง10).
@@ -25,6 +29,15 @@ function isNoiseClass(type, name) {
25
29
  return true;
26
30
  return false;
27
31
  }
32
+ // V8 names per-instance Context/scope objects with a trailing " @<node-id>"
33
+ // (e.g. "system / Context / scope @706909"). Those ids differ per capture, so
34
+ // without normalization every scope is a distinct "class" that appears "new
35
+ // since baseline" and floods the report (observed: ~9,900 such keys, ~133k
36
+ // nodes, in a single Ads snapshot). Collapse the id so they aggregate into one
37
+ // comparable class across the sequence.
38
+ export function normalizeClassName(name) {
39
+ return name.replace(/ @\d+$/, ' @โ€ฆ');
40
+ }
28
41
  function buildHistogram(snapshot) {
29
42
  const hist = new Map();
30
43
  let nodeCount = 0;
@@ -34,7 +47,7 @@ function buildHistogram(snapshot) {
34
47
  totalSize += node.self_size;
35
48
  if (node.id <= 3)
36
49
  return;
37
- const key = `${node.type}::${node.name}`;
50
+ const key = `${node.type}::${normalizeClassName(node.name)}`;
38
51
  const e = hist.get(key);
39
52
  if (e) {
40
53
  e.count++;
@@ -64,12 +77,137 @@ function classifyTrend(counts) {
64
77
  return 'grew-net';
65
78
  return 'flat-or-mixed';
66
79
  }
80
+ /**
81
+ * Load an ordered ladder of snapshots and compute per-class growth trends.
82
+ *
83
+ * Extracted from the `memlab_sequence_analysis` handler so it can be composed
84
+ * (see `memlab_leak_report`) instead of re-implemented: the loop that loads each
85
+ * rung, histograms it, and drops the graph before the next is both the expensive
86
+ * part and the part that is easy to get subtly wrong (resolution, size guard,
87
+ * one-graph-resident-at-a-time).
88
+ *
89
+ * Failures THROW rather than returning an MCP error envelope โ€” the callers are
90
+ * tool handlers that already wrap their body in try/catch, and a composed caller
91
+ * needs a failure it cannot accidentally treat as a result.
92
+ */
93
+ export async function computeSequenceTrends(paths, opts) {
94
+ const toolName = opts.toolName ?? 'memlab_sequence_analysis';
95
+ const steps = [];
96
+ // `paths: ["ladder:<name>"]` expands to a saved ladder (see ladder.ts), so a
97
+ // six-rung trend call is one token instead of six absolute paths.
98
+ const { paths: resolvedPaths } = resolveLadderPaths(paths);
99
+ // The >=2 requirement is enforced here rather than in the schema: a ladder
100
+ // reference is a SINGLE array element that expands to many, so a schema-level
101
+ // `.min(2)` rejects `["ladder:name"]` before it can be expanded.
102
+ if (resolvedPaths.length < 2) {
103
+ throw new Error(`${toolName} needs at least 2 snapshots; got ${resolvedPaths.length}. ` +
104
+ (paths.length === 1 && paths[0].startsWith('ladder:')
105
+ ? 'That ladder has fewer than 2 rungs โ€” check it with memlab_ladder({action:"show"}).'
106
+ : 'Pass an ordered list of paths, or a single ["ladder:<name>"] reference.'));
107
+ }
108
+ for (const p of resolvedPaths) {
109
+ let local;
110
+ let fetchedFrom = null;
111
+ try {
112
+ const r = resolveSnapshotPath(p);
113
+ local = r.localPath;
114
+ fetchedFrom = r.fetchedFrom;
115
+ }
116
+ catch (e) {
117
+ throw new Error(`Failed to resolve "${p}": ${e instanceof Error ? e.message : String(e)}`);
118
+ }
119
+ if (!fs.existsSync(local)) {
120
+ throw new Error(`File not found: ${local}`);
121
+ }
122
+ const sizeMB = fs.statSync(local).size / (1024 * 1024);
123
+ const effectiveMaxFileSizeMB = resolveMaxFileSizeMB(opts.maxFileSizeMB, fetchedFrom != null);
124
+ if (sizeMB > effectiveMaxFileSizeMB) {
125
+ throw new Error(`${p} is ${sizeMB.toFixed(0)} MB โ€” exceeds the ${effectiveMaxFileSizeMB} MB per-file safety limit. ` +
126
+ `Raise it with ${toolName}({max_file_size_mb: ${Math.ceil(sizeMB + 100)}}), ` +
127
+ `or restart the MCP server with more memory (NODE_OPTIONS="--max-old-space-size=8192") if it isn't already provisioned.`);
128
+ }
129
+ // Load sequentially and drop the graph before the next one so only
130
+ // one full graph is resident at a time (memory-safe for big heaps).
131
+ const snapshot = await getFullHeapFromFile(local);
132
+ const { hist, nodeCount, totalSize } = buildHistogram(snapshot);
133
+ steps.push({
134
+ label: fetchedFrom ?? p.replace(/^.*\//, ''),
135
+ localPath: local,
136
+ hist,
137
+ nodeCount,
138
+ totalSize,
139
+ });
140
+ }
141
+ const n = steps.length;
142
+ // Union of non-noise class keys.
143
+ const keys = new Set();
144
+ for (const s of steps) {
145
+ for (const k of s.hist.keys()) {
146
+ const sep = k.indexOf('::');
147
+ const type = k.slice(0, sep);
148
+ const name = k.slice(sep + 2);
149
+ if (!isNoiseClass(type, name))
150
+ keys.add(k);
151
+ }
152
+ }
153
+ const rows = [];
154
+ for (const k of keys) {
155
+ const counts = steps.map(s => s.hist.get(k)?.count ?? 0);
156
+ const sizes = steps.map(s => s.hist.get(k)?.selfSize ?? 0);
157
+ const netCount = counts[n - 1] - counts[0];
158
+ const netSize = sizes[n - 1] - sizes[0];
159
+ if (netCount < opts.minGrowthCount)
160
+ continue;
161
+ const trend = classifyTrend(counts);
162
+ if (opts.monotonicOnly && trend !== 'monotonic-up')
163
+ continue;
164
+ if (trend !== 'monotonic-up' && trend !== 'grew-net')
165
+ continue;
166
+ const sep = k.indexOf('::');
167
+ const name = k.slice(sep + 2);
168
+ rows.push({
169
+ key: k,
170
+ type: k.slice(0, sep),
171
+ name,
172
+ counts,
173
+ netCount,
174
+ netSize,
175
+ trend,
176
+ artifact: classifyArtifact(name),
177
+ });
178
+ }
179
+ // Real growers first: genuine classes ahead of known artifacts, then
180
+ // monotonic ahead of noisy, then by net size delta.
181
+ rows.sort((a, b) => {
182
+ const aArt = a.artifact != null;
183
+ const bArt = b.artifact != null;
184
+ if (aArt !== bArt)
185
+ return aArt ? 1 : -1;
186
+ if (a.trend !== b.trend)
187
+ return a.trend === 'monotonic-up' ? -1 : 1;
188
+ return b.netSize - a.netSize;
189
+ });
190
+ return { steps, rows, keys };
191
+ }
192
+ /**
193
+ * Artifact-family explanations are long and identical on every call. Print the
194
+ * full note once per session and a one-line pointer afterwards; the COUNTS that
195
+ * accompany it are per-call data and are always shown by the caller.
196
+ */
197
+ function pushArtifactNote(lines, kind) {
198
+ if (shouldEmitNote(`artifact:${kind}`)) {
199
+ lines.push('', `> ${artifactNote(kind)}`);
200
+ }
201
+ else {
202
+ lines.push('', `> ${artifactLabel(kind)} โ€” explained earlier this session.`);
203
+ }
204
+ }
67
205
  export function registerSequenceAnalysis(server) {
68
206
  server.tool('memlab_sequence_analysis', 'Trend analysis across an ORDERED sequence of >=2 heap snapshots (the canonical "is anything growing unboundedly?" tool). Loads each snapshot transiently (does NOT change your active snapshot), builds per-class histograms, and reports each class\'s value at every step plus a growth verdict: "monotonic-up" (grew every step โ€” strongest leak signal) vs "grew-net" (grew overall but not every step โ€” often GC/navigation noise) vs flat/shrank. Also lists classes new since the baseline. Paths may be local, manifold:// URLs, or bare filenames.', {
69
207
  paths: z
70
208
  .array(z.string())
71
- .min(2)
72
- .describe('Ordered list of >=2 snapshot paths (oldest first). Each may be a local absolute path, a manifold:// URL, or a bare snapshot filename.'),
209
+ .min(1)
210
+ .describe('Ordered list of >=2 snapshot paths (oldest first): local absolute paths, manifold:// URLs, or bare snapshot filenames. A single ["ladder:<name>"] entry expands to a ladder saved with memlab_ladder.'),
73
211
  limit: z
74
212
  .number()
75
213
  .optional()
@@ -85,79 +223,45 @@ export function registerSequenceAnalysis(server) {
85
223
  .optional()
86
224
  .default(false)
87
225
  .describe('Report only classes that grew at EVERY step (default false: include grew-net too, flagged).'),
226
+ cycles: z
227
+ .number()
228
+ .optional()
229
+ .describe('Number of interaction cycles driven between the FIRST and LAST snapshot. When provided, a "ฮ”/cycle" column is reported. A per-cycle rate โ€” not a total โ€” is what tells you whether growth scales with interaction, and it is the number a leak hunt actually reasons about.'),
230
+ include_artifacts: z
231
+ .boolean()
232
+ .optional()
233
+ .default(false)
234
+ .describe('Include classes that are known measurement artifacts (CDP inspector network/performance/console retention, V8 JIT warmup, Blink a11y caches, captured Error stacks). Default false: they are collapsed into a one-line summary instead of filling the table, because in practice they dominate the top of the list and none of them is an app leak.'),
235
+ repeat_notes: z
236
+ .boolean()
237
+ .optional()
238
+ .default(false)
239
+ .describe('Re-print the standing explanatory notes (artifact-family write-ups, capture-mode caveats, the "candidate, not verdict" paragraph) that are otherwise emitted once per server session. The per-call DATA โ€” which classes grew, how many artifacts were suppressed โ€” is always shown; only the unchanging prose is deduplicated.'),
88
240
  max_file_size_mb: z
89
241
  .number()
90
242
  .optional()
91
- .default(900)
92
- .describe('Per-file size ceiling (default 900) to avoid OOM.'),
93
- }, async ({ paths, limit, min_growth_count, monotonic_only, max_file_size_mb, }) => {
243
+ .describe(`Per-file size ceiling in MB to avoid OOM. Matches memlab_load_snapshot's by-source defaults โ€” ${LOCAL_FILE_SIZE_LIMIT_MB} for local files and ${MANIFOLD_FETCH_SIZE_LIMIT_MB} for snapshots fetched from Manifold (server captures routinely exceed the local limit); pass an explicit value to override. Snapshots are loaded one at a time and dropped before the next, so a ladder of large files is safe as long as each single file is under the ceiling.`),
244
+ }, async ({ paths, limit, min_growth_count, monotonic_only, cycles, include_artifacts, repeat_notes, max_file_size_mb, }) => {
94
245
  try {
95
- const steps = [];
96
- for (const p of paths) {
97
- let local;
98
- let fetchedFrom = null;
99
- try {
100
- const r = resolveSnapshotPath(p);
101
- local = r.localPath;
102
- fetchedFrom = r.fetchedFrom;
103
- }
104
- catch (e) {
105
- return errorResult(new Error(`Failed to resolve "${p}": ${e instanceof Error ? e.message : String(e)}`));
106
- }
107
- if (!fs.existsSync(local)) {
108
- return errorResult(new Error(`File not found: ${local}`));
109
- }
110
- const sizeMB = fs.statSync(local).size / (1024 * 1024);
111
- if (sizeMB > max_file_size_mb) {
112
- return errorResult(new Error(`${p} is ${sizeMB.toFixed(0)} MB โ€” exceeds max_file_size_mb (${max_file_size_mb}).`));
113
- }
114
- // Load sequentially and drop the graph before the next one so only
115
- // one full graph is resident at a time (memory-safe for big heaps).
116
- const snapshot = await getFullHeapFromFile(local);
117
- const { hist, nodeCount, totalSize } = buildHistogram(snapshot);
118
- steps.push({
119
- label: fetchedFrom ?? p.replace(/^.*\//, ''),
120
- hist,
121
- nodeCount,
122
- totalSize,
123
- });
124
- }
246
+ if (repeat_notes)
247
+ resetEmittedNotes();
248
+ const { steps, rows, keys } = await computeSequenceTrends(paths, {
249
+ minGrowthCount: min_growth_count,
250
+ monotonicOnly: monotonic_only,
251
+ maxFileSizeMB: max_file_size_mb,
252
+ });
125
253
  const n = steps.length;
126
254
  const first = steps[0].hist;
127
255
  const last = steps[n - 1].hist;
128
- // Union of non-noise class keys.
129
- const keys = new Set();
130
- for (const s of steps) {
131
- for (const k of s.hist.keys()) {
132
- const sep = k.indexOf('::');
133
- const type = k.slice(0, sep);
134
- const name = k.slice(sep + 2);
135
- if (!isNoiseClass(type, name))
136
- keys.add(k);
137
- }
138
- }
139
- const rows = [];
140
- for (const k of keys) {
141
- const counts = steps.map(s => s.hist.get(k)?.count ?? 0);
142
- const sizes = steps.map(s => s.hist.get(k)?.selfSize ?? 0);
143
- const netCount = counts[n - 1] - counts[0];
144
- const netSize = sizes[n - 1] - sizes[0];
145
- if (netCount < min_growth_count)
146
- continue;
147
- const trend = classifyTrend(counts);
148
- if (monotonic_only && trend !== 'monotonic-up')
149
- continue;
150
- if (trend !== 'monotonic-up' && trend !== 'grew-net')
151
- continue;
152
- rows.push({ key: k, counts, netCount, netSize, trend });
153
- }
154
- // Monotonic growers first, then by net size delta.
155
- rows.sort((a, b) => {
156
- if (a.trend !== b.trend)
157
- return a.trend === 'monotonic-up' ? -1 : 1;
158
- return b.netSize - a.netSize;
159
- });
160
- const top = rows.slice(0, limit);
256
+ // Known artifacts dominate the top of this table in practice and none
257
+ // of them is an app leak, so by default they are summarized rather than
258
+ // listed. They are still counted, and `include_artifacts` brings them
259
+ // back โ€” suppression must never be silent.
260
+ const artifactRows = rows.filter(r => r.artifact != null);
261
+ const candidateRows = include_artifacts
262
+ ? rows
263
+ : rows.filter(r => r.artifact == null);
264
+ const top = candidateRows.slice(0, limit);
161
265
  const lines = [
162
266
  `## Sequence / Trend Analysis (${n} snapshots)`,
163
267
  '',
@@ -173,16 +277,28 @@ export function registerSequenceAnalysis(server) {
173
277
  lines.push(markdownTable(totalHeaders, totalRows, new Set([2, 3])));
174
278
  const heapNet = steps[n - 1].totalSize - steps[0].totalSize;
175
279
  lines.push('', `Overall heap self-size ${heapNet >= 0 ? 'grew' : 'shrank'} by ${formatBytes(Math.abs(heapNet))} across the sequence.`, '');
280
+ // With exactly two rungs "grew at every step" is the same statement as
281
+ // "grew overall", so the monotonic verdict carries no extra information
282
+ // and cannot distinguish a trend from a GC-band sample. Measured case: a
283
+ // 2-rung ladder read as a confident +154 KB/cycle retained leak, and a
284
+ // third and fourth rung showed the heap falling back below where it
285
+ // started โ€” the band was ~25 MB wide, easily enough to fake a linear
286
+ // slope. Say so rather than letting the label imply a trend.
287
+ if (n === 2) {
288
+ lines.push('> โš ๏ธ **Only 2 snapshots: "โ†‘ every step" is monotonic by construction** and cannot separate a real trend from a single GC-band sample. Capture at least a third rung (and prefer a targeted-retainer count over aggregate heap) before treating anything here as a leak.', '');
289
+ }
176
290
  if (top.length === 0) {
177
291
  lines.push(`No classes grew by >= ${formatNumber(min_growth_count)} instances across the sequence. Heap looks flat-to-shrinking โ€” no unbounded-growth signal.`);
178
292
  return toolResult(lines.join('\n'));
179
293
  }
180
294
  lines.push('### Growing classes', '');
295
+ const perCycle = cycles != null && cycles > 0;
181
296
  const headers = [
182
297
  'Class',
183
298
  'Type',
184
299
  ...steps.map((_, i) => `#${i + 1}`),
185
300
  'ฮ” count',
301
+ ...(perCycle ? ['ฮ”/cycle'] : []),
186
302
  'ฮ” size',
187
303
  'Verdict',
188
304
  ];
@@ -190,17 +306,18 @@ export function registerSequenceAnalysis(server) {
190
306
  for (let i = 2; i < headers.length - 1; i++)
191
307
  rightCols.add(i);
192
308
  const tableRows = top.map(r => {
193
- const sep = r.key.indexOf('::');
194
- const type = r.key.slice(0, sep);
195
- const name = r.key.slice(sep + 2);
196
- const verdict = r.trend === 'monotonic-up'
197
- ? 'โ†‘ every step (LEAK signal)'
198
- : 'grew net (noisy)';
309
+ const { type, name } = r;
310
+ const verdict = r.artifact != null
311
+ ? artifactLabel(r.artifact)
312
+ : r.trend === 'monotonic-up'
313
+ ? 'โ†‘ every step (LEAK candidate)'
314
+ : 'grew net (noisy)';
199
315
  return [
200
316
  name.length > 36 ? name.slice(0, 33) + 'โ€ฆ' : name,
201
317
  type,
202
318
  ...r.counts.map(c => formatNumber(c)),
203
319
  `+${formatNumber(r.netCount)}`,
320
+ ...(perCycle ? [(r.netCount / cycles).toFixed(2)] : []),
204
321
  `${r.netSize >= 0 ? '+' : ''}${formatBytes(r.netSize)}`,
205
322
  verdict,
206
323
  ];
@@ -213,7 +330,11 @@ export function registerSequenceAnalysis(server) {
213
330
  const c = last.get(k)?.count ?? 0;
214
331
  if (c >= min_growth_count) {
215
332
  const sep = k.indexOf('::');
216
- newClasses.push(`${k.slice(sep + 2)} (${formatNumber(c)})`);
333
+ const name = k.slice(sep + 2);
334
+ // Don't clutter the list with known JIT/automation artifacts.
335
+ if (classifyArtifact(name) != null)
336
+ continue;
337
+ newClasses.push(`${name} (${formatNumber(c)})`);
217
338
  }
218
339
  }
219
340
  }
@@ -223,17 +344,76 @@ export function registerSequenceAnalysis(server) {
223
344
  ? `, โ€ฆ +${newClasses.length - 20} more`
224
345
  : ''));
225
346
  }
226
- // "heap number" is V8's node for a captured numeric value. It only
227
- // appears when the snapshot was taken with numeric-value capture on
228
- // (Chrome's captureNumericValue / the browser MCP's capture_numeric_value
229
- // option). In that mode V8 emits one node per distinct number, which
230
- // both ~3x inflates the graph and shows up here as a top "โ†‘ every step"
231
- // grower โ€” a capture artifact, not a real leak. Flag it so it isn't
232
- // mistaken for the leak signal.
347
+ // `heap number` growth is a capture artifact when the snapshot was
348
+ // taken with numeric-value capture on (Chrome's captureNumericValue /
349
+ // the browser MCP's capture_numeric_value): that mode emits one graph
350
+ // node per distinct number and ~3x inflates the graph. With it off,
351
+ // these are ordinary boxed doubles that V8 allocates anyway, and growth
352
+ // can be a REAL signal.
353
+ //
354
+ // We deliberately do NOT try to auto-detect which mode produced the
355
+ // snapshot. The obvious signal โ€” value-named nodes of type `number` โ€”
356
+ // does not separate the two: a snapshot captured with
357
+ // capture_numeric_value:false was measured with 47,874 `heap number`
358
+ // nodes AND 165,193 value-named numeric nodes, so any threshold on that
359
+ // count mislabels it. Stating a conditional the caller can resolve from
360
+ // their own capture settings beats asserting a mode we cannot verify;
361
+ // the previous copy declared this "almost always a capture artifact"
362
+ // unconditionally, which trains readers to dismiss a grower that may be
363
+ // real.
233
364
  if (top.some(r => r.key === 'number::heap number')) {
234
- lines.push('', '> โš ๏ธ `heap number` is growing. This is almost always a **capture artifact** from taking snapshots with numeric-value capture enabled (one graph node per distinct number), not a real leak. Re-capture with numeric values OFF (browser MCP `capture_numeric_value: false`) for a ~3x smaller, faster, cleaner graph, and disregard `heap number` growth here.');
365
+ // State the answer instead of asking the caller for it. The runtime
366
+ // and the numeric-capture mode are both derivable from the histograms
367
+ // already built above, at no extra cost: `smi number` is the marker
368
+ // node type, and a `Window โ€ฆ` class means a browser capture. See
369
+ // capture-mode.ts for the matched-pair measurements behind this.
370
+ const last = steps[n - 1].hist;
371
+ const isBrowser = [...last.keys()].some(k => k.startsWith('object::Window '));
372
+ const isNode = !isBrowser && [...last.keys()].some(k => k === 'object::Module');
373
+ const verdict = classifyNumericCapture(isBrowser ? 'browser' : isNode ? 'node' : 'unknown', last.has(SMI_NUMBER_CLASS_KEY));
374
+ lines.push('', shouldEmitNote('seq:heap-number')
375
+ ? `> โš ๏ธ \`heap number\` is growing. ${verdict.note}`
376
+ : '> โš ๏ธ `heap number` is growing (capture-mode caveat already stated this session).');
377
+ }
378
+ // `smi number` growth in a Node capture is pure capture overhead โ€” those
379
+ // nodes do not exist unless the flag asked for them.
380
+ if (top.some(r => r.key === SMI_NUMBER_CLASS_KEY) &&
381
+ ![...steps[n - 1].hist.keys()].some(k => k.startsWith('object::Window '))) {
382
+ lines.push('', shouldEmitNote('seq:smi-number')
383
+ ? '> โš ๏ธ `smi number` is growing in a Node.js capture. Those nodes only exist because the snapshot was taken with numeric-value capture ON; they are capture overhead, not application memory. Re-capture without it to remove them from the trend.'
384
+ : '> โš ๏ธ `smi number` is growing โ€” capture overhead (note already stated this session).');
385
+ }
386
+ // Known-artifact families: either annotate the rows that were shown,
387
+ // or account for the ones that were collapsed. Either way the caller is
388
+ // told what was set aside and why.
389
+ const shownKinds = new Set();
390
+ for (const r of top)
391
+ if (r.artifact != null)
392
+ shownKinds.add(r.artifact);
393
+ const suppressedByKind = new Map();
394
+ if (!include_artifacts) {
395
+ for (const r of artifactRows) {
396
+ suppressedByKind.set(r.artifact, (suppressedByKind.get(r.artifact) ?? 0) + 1);
397
+ }
398
+ }
399
+ if (suppressedByKind.size > 0) {
400
+ const parts = [...suppressedByKind.entries()]
401
+ .sort((a, b) => b[1] - a[1])
402
+ .map(([kind, count]) => `${kind} ${count}`);
403
+ lines.push('', `> ๐Ÿงน **${artifactRows.length} growing class(es) suppressed as known measurement artifacts** (${parts.join(', ')}). None of these families is an application leak; pass \`include_artifacts: true\` to see them.`);
404
+ for (const kind of suppressedByKind.keys()) {
405
+ pushArtifactNote(lines, kind);
406
+ }
407
+ }
408
+ for (const kind of shownKinds) {
409
+ pushArtifactNote(lines, kind);
410
+ }
411
+ if (shouldEmitNote('seq:candidate-not-verdict')) {
412
+ lines.push('', '_"โ†‘ every step (LEAK candidate)" is the strong unbounded-growth signal โ€” it is a candidate, not a verdict: confirm with `memlab_dev_artifacts` and a `memlab_retainer_trace` before calling it a leak; "grew net (noisy)" often reflects GC timing or navigation and warrants a closer look before treating as a leak. Object-identity matching across snapshots is not available (node ids differ per capture) โ€” to localize a specific growing collection, load the last snapshot and use `memlab_cache_analysis` / `memlab_event_listener_leaks` / `memlab_growth_signals`._');
413
+ }
414
+ else {
415
+ lines.push('', '_"โ†‘ every step" is a candidate, not a verdict โ€” see the first `memlab_sequence_analysis` result this session for the full caveat, or pass `repeat_notes: true`._');
235
416
  }
236
- lines.push('', '_"โ†‘ every step" is the strong unbounded-growth signal; "grew net (noisy)" often reflects GC timing or navigation and warrants a closer look before treating as a leak. Object-identity matching across snapshots is not available (node ids differ per capture) โ€” to localize a specific growing collection, load the last snapshot and use `memlab_cache_analysis` / `memlab_event_listener_leaks` / `memlab_growth_signals`._');
237
417
  return toolResult(lines.join('\n'));
238
418
  }
239
419
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"sequence-analysis.js","sourceRoot":"","sources":["../../src/tools/sequence-analysis.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sequence-analysis.js","sourceRoot":"","sources":["../../src/tools/sequence-analysis.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"shape-histogram.d.ts","sourceRoot":"","sources":["../../src/tools/shape-histogram.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAmCvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2L9D"}
1
+ {"version":3,"file":"shape-histogram.d.ts","sourceRoot":"","sources":["../../src/tools/shape-histogram.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAoCvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoM9D"}
@@ -11,7 +11,7 @@ import memlabCore from '@memlab/core';
11
11
  const { utils, NumericSet } = memlabCore;
12
12
  import { z } from 'zod';
13
13
  import { getSnapshot } from '../heap-state.js';
14
- import { formatBytes, formatNumber, errorResult, toolResult, suggestionsSuppressed, } from '../utils.js';
14
+ import { formatBytes, formatNumber, errorResult, toolResult, suggestionsSuppressed, makeNamePatternTest, } from '../utils.js';
15
15
  function getPropertyNames(node) {
16
16
  const names = [];
17
17
  for (const edge of node.references) {
@@ -45,6 +45,10 @@ export function registerShapeHistogram(server) {
45
45
  .string()
46
46
  .optional()
47
47
  .describe('Filter to objects with this constructor name (e.g., "Object"). If omitted, includes all object-type nodes.'),
48
+ name_pattern: z
49
+ .string()
50
+ .optional()
51
+ .describe('Filter constructor names by pattern before grouping by shape โ€” a case-insensitive regular expression, or a plain substring when the pattern is not valid regex (e.g. "blink::UndoStep", "Detached", "^WA"). Answering "is class X present?" this way costs one row instead of a whole table.'),
48
52
  sort_by: z
49
53
  .enum(['retained_size', 'retained', 'count', 'self_size', 'self'])
50
54
  .optional()
@@ -55,7 +59,7 @@ export function registerShapeHistogram(server) {
55
59
  .optional()
56
60
  .default(false)
57
61
  .describe('Compute the EXACT dominator-deduped retained size per shape via aggregateDominatorMetrics. DEFAULT false: report a retained-size range instead (lower = ฮฃ self size, upper = ฮฃ raw retained) from the O(N) pass; sorting/filtering by retained uses the upper bound. Set true ONLY on explicit user request โ€” the exact walk can be very slow or time out on huge heaps.'),
58
- }, async ({ limit, min_count, min_retained_size, class_name, sort_by, exact_retained_size, }) => {
62
+ }, async ({ limit, min_count, min_retained_size, class_name, name_pattern, sort_by, exact_retained_size, }) => {
59
63
  try {
60
64
  // Normalize sort aliases so the vocabulary matches other tools.
61
65
  const sort = sort_by === 'retained'
@@ -64,6 +68,7 @@ export function registerShapeHistogram(server) {
64
68
  ? 'self_size'
65
69
  : sort_by;
66
70
  const snapshot = getSnapshot();
71
+ const nameMatches = makeNamePatternTest(name_pattern);
67
72
  const shapeMap = new Map();
68
73
  snapshot.nodes.forEach(node => {
69
74
  if (node.type !== 'object')
@@ -72,6 +77,8 @@ export function registerShapeHistogram(server) {
72
77
  return;
73
78
  if (class_name && node.name !== class_name)
74
79
  return;
80
+ if (!nameMatches(node.name))
81
+ return;
75
82
  const props = getPropertyNames(node);
76
83
  if (!props)
77
84
  return;