@memlab/mcp-server 2.1.0 → 2.3.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 (162) hide show
  1. package/README.md +88 -3
  2. package/dist/analysis-budget.d.ts +71 -0
  3. package/dist/analysis-budget.d.ts.map +1 -0
  4. package/dist/analysis-budget.js +118 -0
  5. package/dist/analysis-budget.js.map +1 -0
  6. package/dist/guardrail.d.ts +24 -0
  7. package/dist/guardrail.d.ts.map +1 -0
  8. package/dist/guardrail.js +65 -0
  9. package/dist/guardrail.js.map +1 -0
  10. package/dist/heap-state.d.ts +46 -1
  11. package/dist/heap-state.d.ts.map +1 -1
  12. package/dist/heap-state.js +142 -10
  13. package/dist/heap-state.js.map +1 -1
  14. package/dist/index.js +36 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/tools/array-group-by.d.ts +12 -0
  17. package/dist/tools/array-group-by.d.ts.map +1 -0
  18. package/dist/tools/array-group-by.js +191 -0
  19. package/dist/tools/array-group-by.js.map +1 -0
  20. package/dist/tools/auto-investigate.d.ts.map +1 -1
  21. package/dist/tools/auto-investigate.js +999 -37
  22. package/dist/tools/auto-investigate.js.map +1 -1
  23. package/dist/tools/cache-analysis.d.ts.map +1 -1
  24. package/dist/tools/cache-analysis.js +438 -21
  25. package/dist/tools/cache-analysis.js.map +1 -1
  26. package/dist/tools/check-health.d.ts.map +1 -1
  27. package/dist/tools/check-health.js +261 -1
  28. package/dist/tools/check-health.js.map +1 -1
  29. package/dist/tools/class-histogram.d.ts.map +1 -1
  30. package/dist/tools/class-histogram.js +142 -33
  31. package/dist/tools/class-histogram.js.map +1 -1
  32. package/dist/tools/closure-inspection.d.ts.map +1 -1
  33. package/dist/tools/closure-inspection.js +238 -25
  34. package/dist/tools/closure-inspection.js.map +1 -1
  35. package/dist/tools/detached-dom.d.ts.map +1 -1
  36. package/dist/tools/detached-dom.js +25 -3
  37. package/dist/tools/detached-dom.js.map +1 -1
  38. package/dist/tools/dev-artifacts.d.ts +33 -0
  39. package/dist/tools/dev-artifacts.d.ts.map +1 -0
  40. package/dist/tools/dev-artifacts.js +165 -0
  41. package/dist/tools/dev-artifacts.js.map +1 -0
  42. package/dist/tools/diff-snapshots.d.ts.map +1 -1
  43. package/dist/tools/diff-snapshots.js +113 -18
  44. package/dist/tools/diff-snapshots.js.map +1 -1
  45. package/dist/tools/duplicated-strings.d.ts.map +1 -1
  46. package/dist/tools/duplicated-strings.js +74 -12
  47. package/dist/tools/duplicated-strings.js.map +1 -1
  48. package/dist/tools/eval.d.ts.map +1 -1
  49. package/dist/tools/eval.js +189 -10
  50. package/dist/tools/eval.js.map +1 -1
  51. package/dist/tools/event-listener-leaks.d.ts.map +1 -1
  52. package/dist/tools/event-listener-leaks.js +235 -13
  53. package/dist/tools/event-listener-leaks.js.map +1 -1
  54. package/dist/tools/event-registry.d.ts +12 -0
  55. package/dist/tools/event-registry.d.ts.map +1 -0
  56. package/dist/tools/event-registry.js +183 -0
  57. package/dist/tools/event-registry.js.map +1 -0
  58. package/dist/tools/find-by-property.d.ts.map +1 -1
  59. package/dist/tools/find-by-property.js +113 -31
  60. package/dist/tools/find-by-property.js.map +1 -1
  61. package/dist/tools/find-by-shape.d.ts +12 -0
  62. package/dist/tools/find-by-shape.d.ts.map +1 -0
  63. package/dist/tools/find-by-shape.js +178 -0
  64. package/dist/tools/find-by-shape.js.map +1 -0
  65. package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
  66. package/dist/tools/find-nodes-by-class.js +50 -6
  67. package/dist/tools/find-nodes-by-class.js.map +1 -1
  68. package/dist/tools/for-each.d.ts.map +1 -1
  69. package/dist/tools/for-each.js +1 -1
  70. package/dist/tools/for-each.js.map +1 -1
  71. package/dist/tools/get-node.d.ts.map +1 -1
  72. package/dist/tools/get-node.js +6 -0
  73. package/dist/tools/get-node.js.map +1 -1
  74. package/dist/tools/get-string.d.ts +12 -0
  75. package/dist/tools/get-string.d.ts.map +1 -0
  76. package/dist/tools/get-string.js +223 -0
  77. package/dist/tools/get-string.js.map +1 -0
  78. package/dist/tools/get-value.d.ts +12 -0
  79. package/dist/tools/get-value.d.ts.map +1 -0
  80. package/dist/tools/get-value.js +152 -0
  81. package/dist/tools/get-value.js.map +1 -0
  82. package/dist/tools/global-variables.d.ts.map +1 -1
  83. package/dist/tools/global-variables.js +54 -34
  84. package/dist/tools/global-variables.js.map +1 -1
  85. package/dist/tools/growth-signals.d.ts +12 -0
  86. package/dist/tools/growth-signals.d.ts.map +1 -0
  87. package/dist/tools/growth-signals.js +211 -0
  88. package/dist/tools/growth-signals.js.map +1 -0
  89. package/dist/tools/intern-opportunities.d.ts +12 -0
  90. package/dist/tools/intern-opportunities.d.ts.map +1 -0
  91. package/dist/tools/intern-opportunities.js +289 -0
  92. package/dist/tools/intern-opportunities.js.map +1 -0
  93. package/dist/tools/load-snapshot.d.ts +10 -0
  94. package/dist/tools/load-snapshot.d.ts.map +1 -1
  95. package/dist/tools/load-snapshot.js +152 -15
  96. package/dist/tools/load-snapshot.js.map +1 -1
  97. package/dist/tools/object-cost-breakdown.d.ts +12 -0
  98. package/dist/tools/object-cost-breakdown.d.ts.map +1 -0
  99. package/dist/tools/object-cost-breakdown.js +439 -0
  100. package/dist/tools/object-cost-breakdown.js.map +1 -0
  101. package/dist/tools/object-shape.d.ts.map +1 -1
  102. package/dist/tools/object-shape.js +95 -2
  103. package/dist/tools/object-shape.js.map +1 -1
  104. package/dist/tools/pinch-points.d.ts.map +1 -1
  105. package/dist/tools/pinch-points.js +9 -9
  106. package/dist/tools/pinch-points.js.map +1 -1
  107. package/dist/tools/property-distribution.d.ts +12 -0
  108. package/dist/tools/property-distribution.d.ts.map +1 -0
  109. package/dist/tools/property-distribution.js +168 -0
  110. package/dist/tools/property-distribution.js.map +1 -0
  111. package/dist/tools/quick-diagnosis.d.ts.map +1 -1
  112. package/dist/tools/quick-diagnosis.js +56 -19
  113. package/dist/tools/quick-diagnosis.js.map +1 -1
  114. package/dist/tools/retainer-summary.d.ts.map +1 -1
  115. package/dist/tools/retainer-summary.js +90 -5
  116. package/dist/tools/retainer-summary.js.map +1 -1
  117. package/dist/tools/retainer-trace.d.ts.map +1 -1
  118. package/dist/tools/retainer-trace.js +74 -22
  119. package/dist/tools/retainer-trace.js.map +1 -1
  120. package/dist/tools/search-nodes.d.ts.map +1 -1
  121. package/dist/tools/search-nodes.js +10 -3
  122. package/dist/tools/search-nodes.js.map +1 -1
  123. package/dist/tools/search-strings.d.ts +12 -0
  124. package/dist/tools/search-strings.d.ts.map +1 -0
  125. package/dist/tools/search-strings.js +182 -0
  126. package/dist/tools/search-strings.js.map +1 -0
  127. package/dist/tools/sequence-analysis.d.ts +12 -0
  128. package/dist/tools/sequence-analysis.d.ts.map +1 -0
  129. package/dist/tools/sequence-analysis.js +234 -0
  130. package/dist/tools/sequence-analysis.js.map +1 -0
  131. package/dist/tools/server-status.d.ts +12 -0
  132. package/dist/tools/server-status.d.ts.map +1 -0
  133. package/dist/tools/server-status.js +41 -0
  134. package/dist/tools/server-status.js.map +1 -0
  135. package/dist/tools/shape-histogram.d.ts.map +1 -1
  136. package/dist/tools/shape-histogram.js +61 -16
  137. package/dist/tools/shape-histogram.js.map +1 -1
  138. package/dist/tools/sliced-strings.d.ts.map +1 -1
  139. package/dist/tools/sliced-strings.js +16 -11
  140. package/dist/tools/sliced-strings.js.map +1 -1
  141. package/dist/tools/snapshot-summary.d.ts.map +1 -1
  142. package/dist/tools/snapshot-summary.js +55 -13
  143. package/dist/tools/snapshot-summary.js.map +1 -1
  144. package/dist/tools/snapshots.d.ts +12 -0
  145. package/dist/tools/snapshots.d.ts.map +1 -0
  146. package/dist/tools/snapshots.js +93 -0
  147. package/dist/tools/snapshots.js.map +1 -0
  148. package/dist/tools/stale-collections.d.ts.map +1 -1
  149. package/dist/tools/stale-collections.js +248 -7
  150. package/dist/tools/stale-collections.js.map +1 -1
  151. package/dist/tools/trace-dominators.d.ts.map +1 -1
  152. package/dist/tools/trace-dominators.js +28 -1
  153. package/dist/tools/trace-dominators.js.map +1 -1
  154. package/dist/tools/weakmap-entries.d.ts +12 -0
  155. package/dist/tools/weakmap-entries.d.ts.map +1 -0
  156. package/dist/tools/weakmap-entries.js +156 -0
  157. package/dist/tools/weakmap-entries.js.map +1 -0
  158. package/dist/utils.d.ts +81 -2
  159. package/dist/utils.d.ts.map +1 -1
  160. package/dist/utils.js +303 -35
  161. package/dist/utils.js.map +1 -1
  162. package/package.json +3 -3
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import { z } from 'zod';
11
11
  import { getSnapshot, getSnapshotMetadata } from '../heap-state.js';
12
- import { isNodeWorthInspecting, formatBytes, formatNumber, markdownTable, truncateNodeName, errorResult, toolResult, } from '../utils.js';
12
+ import { isNodeWorthInspecting, formatBytes, formatNumber, markdownTable, truncateNodeName, errorResult, toolResult, suggestionsSuppressed, } from '../utils.js';
13
13
  export function registerPinchPoints(server) {
14
14
  server.tool('memlab_pinch_points', 'Find "pinch points" — small objects that retain disproportionately large subtrees in the dominator tree. These are the most impactful objects to free: a single cache, map, or closure whose removal would reclaim the most memory. Returns objects ranked by retained_size/self_size ratio, filtered to actionable user-code objects (excludes V8 internals).', {
15
15
  limit: z
@@ -20,13 +20,13 @@ export function registerPinchPoints(server) {
20
20
  min_retained_size: z
21
21
  .number()
22
22
  .optional()
23
- .default(1048576)
24
- .describe('Minimum retained size in bytes to consider (default 1 MB). Increase for large snapshots.'),
23
+ .default(524288)
24
+ .describe('Minimum retained size in bytes to consider (default 512 KB). Increase for large snapshots.'),
25
25
  min_ratio: z
26
26
  .number()
27
27
  .optional()
28
- .default(100)
29
- .describe('Minimum retained_size/self_size ratio (default 100). Higher values find more extreme pinch points.'),
28
+ .default(50)
29
+ .describe('Minimum retained_size/self_size ratio (default 50). Higher values find more extreme pinch points.'),
30
30
  }, async ({ limit, min_retained_size, min_ratio }) => {
31
31
  try {
32
32
  const snapshot = getSnapshot();
@@ -109,11 +109,11 @@ export function registerPinchPoints(server) {
109
109
  markdownTable(headers, rows, rightCols),
110
110
  '',
111
111
  '**Interpretation:** Each row is a small object retaining a large subtree. Freeing it (e.g., clearing a cache, removing an event listener) would reclaim the retained size.',
112
- '',
113
- '**Suggested next steps:**',
114
112
  ];
115
- const top = candidates[0];
116
- lines.push(`- Inspect top pinch point: \`memlab_get_node(${top.nodeId})\` → \`memlab_object_shape(${top.nodeId})\``, `- See what it retains: \`memlab_dominator_subtree(${top.nodeId})\``, `- Trace how it's kept alive: \`memlab_retainer_trace(${top.nodeId})\``);
113
+ if (!suggestionsSuppressed()) {
114
+ const top = candidates[0];
115
+ lines.push('', '**Suggested next steps:**', `- Inspect top pinch point: \`memlab_get_node(${top.nodeId})\` → \`memlab_object_shape(${top.nodeId})\``, `- See what it retains: \`memlab_dominator_subtree(${top.nodeId})\``, `- Trace how it's kept alive: \`memlab_retainer_trace(${top.nodeId})\``);
116
+ }
117
117
  return toolResult(lines.join('\n'));
118
118
  }
119
119
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"pinch-points.js","sourceRoot":"","sources":["../../src/tools/pinch-points.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pinch-points.js","sourceRoot":"","sources":["../../src/tools/pinch-points.ts"],"names":[],"mappings":"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"}
@@ -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 registerPropertyDistribution(server: McpServer): void;
12
+ //# sourceMappingURL=property-distribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"property-distribution.d.ts","sourceRoot":"","sources":["../../src/tools/property-distribution.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAmCvE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyJpE"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import { z } from 'zod';
11
+ import { getSnapshot, getSnapshotMetadata } from '../heap-state.js';
12
+ import { formatBytes, formatNumber, markdownTable, errorResult, toolResult, } from '../utils.js';
13
+ function readPropertyValue(target) {
14
+ if (target.isString) {
15
+ const s = target.toStringNode();
16
+ const v = s ? s.stringValue : target.name;
17
+ return v.length > 120 ? v.slice(0, 120) + '…' : v;
18
+ }
19
+ // Inline SMI: value is encoded as id >> 1 with self_size 0.
20
+ if (target.name === 'smi number' && target.self_size === 0) {
21
+ return String(target.id >> 1);
22
+ }
23
+ if (target.name === 'heap number')
24
+ return '(heap number)';
25
+ if (target.name === 'true' || target.name === 'false')
26
+ return target.name;
27
+ if (target.name === 'null' || target.name === 'undefined')
28
+ return target.name;
29
+ // Object/array values: summarize by class, not identity.
30
+ return `<${target.name} (${target.type})>`;
31
+ }
32
+ export function registerPropertyDistribution(server) {
33
+ server.tool('memlab_property_distribution', "For a given object class/shape and property, report the value cardinality plus the top-K most frequent values with their counts. The key tool for diagnosing cardinality explosions (e.g., an OpenTelemetry metric attribute, a cache key, or a per-record field whose unbounded distinct values blow up memory). Complements memlab_shape_histogram (which groups by property *names*) by showing the distribution of a single property's *values*.", {
34
+ property: z
35
+ .string()
36
+ .describe('The property name to analyze the value distribution of.'),
37
+ class_name: z
38
+ .string()
39
+ .optional()
40
+ .default('Object')
41
+ .describe('Constructor name of the objects to scan (default "Object"). Use the class shown by class_histogram/shape_histogram.'),
42
+ shape: z
43
+ .array(z.string())
44
+ .optional()
45
+ .describe('Optional exact property-name set to restrict to one shape (as reported by shape_histogram). Only objects whose property names match this set are counted.'),
46
+ top_k: z
47
+ .number()
48
+ .optional()
49
+ .default(15)
50
+ .describe('Number of most-frequent values to show (default 15).'),
51
+ min_count: z
52
+ .number()
53
+ .optional()
54
+ .default(1)
55
+ .describe('Only show values occurring at least this many times.'),
56
+ }, async ({ property, class_name, shape, top_k, min_count }) => {
57
+ try {
58
+ const snapshot = getSnapshot();
59
+ const meta = getSnapshotMetadata();
60
+ const totalSize = meta?.totalSize ?? 0;
61
+ const shapeSet = shape ? new Set(shape) : null;
62
+ const values = new Map();
63
+ let matched = 0;
64
+ let withProp = 0;
65
+ let totalValueBytes = 0;
66
+ snapshot.nodes.forEach(node => {
67
+ if (node.id <= 3 || node.type !== 'object')
68
+ return;
69
+ if (node.name !== class_name)
70
+ return;
71
+ // Collect property names + locate the target property in one pass.
72
+ let target = null;
73
+ const propNames = [];
74
+ for (const edge of node.references) {
75
+ if (edge.type !== 'property')
76
+ continue;
77
+ const pName = String(edge.name_or_index);
78
+ propNames.push(pName);
79
+ if (pName === property)
80
+ target = edge.toNode;
81
+ }
82
+ if (shapeSet) {
83
+ if (propNames.length !== shapeSet.size)
84
+ return;
85
+ for (const p of propNames)
86
+ if (!shapeSet.has(p))
87
+ return;
88
+ }
89
+ matched++;
90
+ if (!target)
91
+ return;
92
+ withProp++;
93
+ const key = readPropertyValue(target);
94
+ const bytes = target.isString ? target.self_size : 0;
95
+ totalValueBytes += bytes;
96
+ const existing = values.get(key);
97
+ if (existing) {
98
+ existing.count++;
99
+ existing.approxBytes += bytes;
100
+ }
101
+ else {
102
+ values.set(key, {
103
+ count: 1,
104
+ exampleNodeId: node.id,
105
+ approxBytes: bytes,
106
+ });
107
+ }
108
+ });
109
+ if (matched === 0) {
110
+ return toolResult(`No \`${class_name}\` objects${shapeSet ? ' matching that shape' : ''} found. Check the class name with memlab_class_histogram or shape with memlab_shape_histogram.`);
111
+ }
112
+ const cardinality = values.size;
113
+ const sorted = [...values.entries()]
114
+ .filter(([, v]) => v.count >= min_count)
115
+ .sort((a, b) => b[1].count - a[1].count)
116
+ .slice(0, top_k);
117
+ const lines = [
118
+ `## Value distribution of \`${property}\` on \`${class_name}\`${shapeSet ? ' (shape-filtered)' : ''}`,
119
+ '',
120
+ `Objects scanned: ${formatNumber(matched)} | with property: ${formatNumber(withProp)} | distinct values: **${formatNumber(cardinality)}**` +
121
+ (totalValueBytes > 0
122
+ ? ` | string value bytes: ${formatBytes(totalValueBytes)}` +
123
+ (totalSize > 0
124
+ ? ` (${Math.min(100, (totalValueBytes / totalSize) * 100).toFixed(1)}% of heap)`
125
+ : '')
126
+ : ''),
127
+ '',
128
+ ];
129
+ // Cardinality interpretation.
130
+ const ratio = withProp > 0 ? cardinality / withProp : 0;
131
+ if (cardinality === 1) {
132
+ lines.push(`_Single constant value across all instances — strong candidate for interning or dropping the field._`);
133
+ }
134
+ else if (ratio > 0.9 && withProp >= 100) {
135
+ lines.push(`_Nearly all values are unique (${(ratio * 100).toFixed(0)}% distinct) — a high-cardinality field. If this feeds a metric dimension or cache key, that is likely the cardinality-explosion root cause._`);
136
+ }
137
+ else if (cardinality <= 20) {
138
+ lines.push(`_Low cardinality (${cardinality} values) — can usually be bucketed/filtered at the source or interned._`);
139
+ }
140
+ lines.push('');
141
+ const headers = [
142
+ 'Value',
143
+ 'Count',
144
+ '% of instances',
145
+ 'Str bytes',
146
+ 'Example',
147
+ ];
148
+ const rightCols = new Set([1, 2, 3]);
149
+ const rows = sorted.map(([val, v]) => [
150
+ val.length > 60 ? val.slice(0, 57) + '…' : val,
151
+ formatNumber(v.count),
152
+ withProp > 0 ? ((v.count / withProp) * 100).toFixed(1) + '%' : '-',
153
+ v.approxBytes > 0 ? formatBytes(v.approxBytes) : '-',
154
+ `@${v.exampleNodeId}`,
155
+ ]);
156
+ lines.push(markdownTable(headers, rows, rightCols));
157
+ if (cardinality > sorted.length) {
158
+ lines.push('');
159
+ lines.push(`… and ${formatNumber(cardinality - sorted.length)} more distinct value(s). Increase top_k to see more.`);
160
+ }
161
+ return toolResult(lines.join('\n'));
162
+ }
163
+ catch (err) {
164
+ return errorResult(err);
165
+ }
166
+ });
167
+ }
168
+ //# sourceMappingURL=property-distribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"property-distribution.js","sourceRoot":"","sources":["../../src/tools/property-distribution.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"quick-diagnosis.d.ts","sourceRoot":"","sources":["../../src/tools/quick-diagnosis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAoDvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4O9D"}
1
+ {"version":3,"file":"quick-diagnosis.d.ts","sourceRoot":"","sources":["../../src/tools/quick-diagnosis.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAoDvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2S9D"}
@@ -41,7 +41,8 @@ function getContentPreview(node) {
41
41
  return '';
42
42
  }
43
43
  export function registerQuickDiagnosis(server) {
44
- server.tool('memlab_quick_diagnosis', 'Combined diagnosis tool that returns snapshot summary, top objects by retained size, class histogram, and duplicated strings in a single call. Saves 3-4 round trips and reduces token overhead from repeated headers. Use this as the first analysis tool after memlab_load_snapshot for an immediate comprehensive overview.', {
44
+ server.tool('memlab_quick_diagnosis', 'Combined diagnosis tool that returns snapshot summary, top objects by retained size, class histogram, and duplicated strings in a single call. Saves 3-4 round trips and reduces token overhead from repeated headers. Use this as the first analysis tool after memlab_load_snapshot for an immediate comprehensive overview. ' +
45
+ 'By DEFAULT every section runs in a single O(N) pass (the class histogram reports retained size as a lower/upper-bound range rather than the exact dominator-deduped value), so it is safe on large heaps. Pass `exact_retained_size:true` ONLY when the user explicitly wants exact per-class retained sizes — that adds a per-class dominator walk that can stall or OOM the server on snapshots with millions of nodes.', {
45
46
  top_objects: z
46
47
  .number()
47
48
  .optional()
@@ -57,7 +58,12 @@ export function registerQuickDiagnosis(server) {
57
58
  .optional()
58
59
  .default(10)
59
60
  .describe('Number of top duplicated strings (default 10)'),
60
- }, async ({ top_objects, top_classes, top_strings }) => {
61
+ exact_retained_size: z
62
+ .boolean()
63
+ .optional()
64
+ .default(false)
65
+ .describe('Compute EXACT dominator-deduped retained size for the class histogram via aggregateDominatorMetrics. DEFAULT false: the class histogram shows a retained-size range (lower = self size, upper = Σ raw retained) computed in the O(N) pass. Set true ONLY on explicit user request — the exact walk can be very slow or time out on huge heaps.'),
66
+ }, async ({ top_objects, top_classes, top_strings, exact_retained_size }) => {
61
67
  try {
62
68
  const snapshot = getSnapshot();
63
69
  const meta = getSnapshotMetadata();
@@ -125,47 +131,61 @@ export function registerQuickDiagnosis(server) {
125
131
  if (entry) {
126
132
  entry.count++;
127
133
  entry.total_self_size += node.self_size;
128
- entry.node_ids.add(node.id);
134
+ entry.raw_retained += node.retainedSize;
135
+ if (entry.node_ids)
136
+ entry.node_ids.add(node.id);
129
137
  }
130
138
  else {
131
139
  classMap.set(key, {
132
140
  count: 1,
133
141
  total_self_size: node.self_size,
134
- node_ids: new NumericSet([node.id]),
142
+ raw_retained: node.retainedSize,
143
+ // Per-node ids are only needed for the opt-in exact dominator walk.
144
+ node_ids: exact_retained_size ? new NumericSet([node.id]) : null,
135
145
  type: node.type,
136
146
  });
137
147
  }
138
148
  });
139
149
  const classEntries = [...classMap.entries()].filter(([, v]) => v.count >= 1);
150
+ // By DEFAULT skip the exact dominator walk (the part that stalls the
151
+ // server on huge heaps) and rank by the upper-bound raw retained sum;
152
+ // only compute exact dominator-deduped retained when explicitly asked.
140
153
  const withRetained = classEntries.map(([key, v]) => {
141
- const retainedSize = utils.aggregateDominatorMetrics(v.node_ids, snapshot, () => true, (node) => node.retainedSize);
142
- return { key, ...v, retained_size: retainedSize };
154
+ let exact = null;
155
+ if (exact_retained_size && v.node_ids) {
156
+ exact = utils.aggregateDominatorMetrics(v.node_ids, snapshot, () => true, (node) => node.retainedSize);
157
+ }
158
+ const rank = exact ?? v.raw_retained;
159
+ return { key, ...v, exact, rank };
143
160
  });
144
- // Use total heap size as denominator so cumulative % reflects each
145
- // class's share of the entire heap, not just the displayed classes.
146
161
  const totalClassRetained = meta?.totalSize ?? 0;
147
162
  const classSorted = withRetained
148
- .sort((a, b) => b.retained_size - a.retained_size)
163
+ .sort((a, b) => b.rank - a.rank)
149
164
  .slice(0, top_classes);
150
- let cumRetained = 0;
151
- const classHeaders = ['Class', 'Type', 'Count', 'Retained', 'Cum %'];
165
+ const classHeaders = exact_retained_size
166
+ ? ['Class', 'Type', 'Count', 'Retained', '% Heap']
167
+ : ['Class', 'Type', 'Count', 'Retained ≤ (upper)', '% Heap ≤'];
152
168
  const classRightCols = new Set([2, 3, 4]);
153
169
  const classRows = classSorted.map(v => {
154
170
  const rawName = v.key.split('::').slice(1).join('::');
155
171
  const name = truncateNodeName(rawName, v.type, Math.round(v.total_self_size / v.count), 80);
156
- cumRetained += v.retained_size;
157
- const cumPct = totalClassRetained > 0
158
- ? ((cumRetained / totalClassRetained) * 100).toFixed(1) + '%'
172
+ const pct = totalClassRetained > 0
173
+ ? ((v.rank / totalClassRetained) * 100).toFixed(1) + '%'
159
174
  : '-';
160
175
  return [
161
176
  name,
162
177
  v.type,
163
178
  formatNumber(v.count),
164
- formatBytes(v.retained_size),
165
- cumPct,
179
+ exact_retained_size
180
+ ? formatBytes(v.exact ?? 0)
181
+ : `≤ ${formatBytes(v.raw_retained)}`,
182
+ exact_retained_size ? pct : `≤ ${pct}`,
166
183
  ];
167
184
  });
168
185
  lines.push(`## Class Histogram (top ${classRows.length})`, '', markdownTable(classHeaders, classRows, classRightCols), '');
186
+ if (!exact_retained_size) {
187
+ lines.push("_Class `Retained` is an **upper bound** (Σ each instance's retained size, which double-counts shared subtrees); the lower bound is the class self size. The exact dominator-deduped value needs a per-class dominator walk (slow / can time out on large heaps) — pass `exact_retained_size:true` for it._", '');
188
+ }
169
189
  // --- Section 4: Duplicated Strings ---
170
190
  const stringMap = new Map();
171
191
  snapshot.nodes.forEach(node => {
@@ -191,17 +211,34 @@ export function registerQuickDiagnosis(server) {
191
211
  .sort((a, b) => b[1].total_size - a[1].total_size)
192
212
  .slice(0, top_strings);
193
213
  if (duplicated.length > 0) {
194
- const strHeaders = ['Value', 'Copies', 'Total Size'];
195
- const strRightCols = new Set([1, 2]);
214
+ const strHeaders = ['Value', 'Copies', 'Total Size', 'Savings'];
215
+ const strRightCols = new Set([1, 2, 3]);
196
216
  const strRows = duplicated.map(([value, stats]) => {
197
217
  const display = value.length > 50 ? value.slice(0, 50) + '…' : value;
218
+ const perCopy = stats.count > 0 ? stats.total_size / stats.count : 0;
219
+ const savings = (stats.count - 1) * perCopy;
198
220
  return [
199
221
  sanitizeForTable(display),
200
222
  formatNumber(stats.count),
201
223
  formatBytes(stats.total_size),
224
+ formatBytes(savings),
202
225
  ];
203
226
  });
204
- lines.push(`## Duplicated Strings (top ${strRows.length})`, '', markdownTable(strHeaders, strRows, strRightCols), '');
227
+ const totalDupSavings = duplicated.reduce((sum, [, stats]) => {
228
+ const perCopy = stats.count > 0 ? stats.total_size / stats.count : 0;
229
+ return sum + (stats.count - 1) * perCopy;
230
+ }, 0);
231
+ lines.push(`## Duplicated Strings (top ${strRows.length})`, '', markdownTable(strHeaders, strRows, strRightCols), '', `**Total interning savings: ${formatBytes(totalDupSavings)}** (if each string stored once)`, '');
232
+ }
233
+ // --- Section 5: String-to-Object Ratio Flag (Feedback #11) ---
234
+ const stringCount = typeStats.get('string')?.count ?? 0;
235
+ const objectCount = typeStats.get('object')?.count ?? 0;
236
+ const heavyDupCount = duplicated.filter(([, stats]) => stats.count >= 100_000).length;
237
+ if (objectCount > 0 &&
238
+ stringCount / objectCount > 2 &&
239
+ heavyDupCount > 0) {
240
+ const ratio = (stringCount / objectCount).toFixed(1);
241
+ lines.push('## ⚠️ High String Duplication Ratio', '', `**${formatNumber(stringCount)} strings / ${formatNumber(objectCount)} objects = ${ratio}:1 ratio** with ${heavyDupCount} string(s) having >100K copies.`, '', 'This pattern strongly indicates JSON.parse output or API response data where column values are not interned. String interning at the parse boundary could save significant memory.', '', '**Next step:** `memlab_intern_opportunities` to see savings grouped by property × parent shape.', '');
205
242
  }
206
243
  return toolResult(lines.join('\n'));
207
244
  }
@@ -1 +1 @@
1
- {"version":3,"file":"quick-diagnosis.js","sourceRoot":"","sources":["../../src/tools/quick-diagnosis.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"quick-diagnosis.js","sourceRoot":"","sources":["../../src/tools/quick-diagnosis.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"retainer-summary.d.ts","sourceRoot":"","sources":["../../src/tools/retainer-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAoIvE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmR/D"}
1
+ {"version":3,"file":"retainer-summary.d.ts","sourceRoot":"","sources":["../../src/tools/retainer-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AA2IvE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuX/D"}
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import { z } from 'zod';
11
11
  import { getSnapshot } from '../heap-state.js';
12
- import { filterLargestObjects, formatBytes, errorResult, toolResult, } from '../utils.js';
12
+ import { filterLargestObjects, formatBytes, truncateDomToTag, errorResult, toolResult, } from '../utils.js';
13
13
  const FRAMEWORK_PATTERNS = new Set([
14
14
  'system / Context',
15
15
  'system / PromiseReaction',
@@ -79,6 +79,12 @@ function traceToKey(steps, frameworkFilter) {
79
79
  .join(' ');
80
80
  }
81
81
  function shortenPath(name) {
82
+ const isDomLike = name.includes('class="') ||
83
+ name.includes('aria-') ||
84
+ name.startsWith('<') ||
85
+ name.startsWith('Detached <');
86
+ if (isDomLike)
87
+ return truncateDomToTag(name);
82
88
  if (name.length <= 40)
83
89
  return name;
84
90
  const parts = name.split('/');
@@ -127,6 +133,13 @@ export function registerRetainerSummary(server) {
127
133
  .string()
128
134
  .optional()
129
135
  .describe('Match nodes whose name starts with this prefix (e.g., "Detached" matches all detached DOM nodes regardless of element type). Use instead of class_name when the exact name varies.'),
136
+ shape: z
137
+ .array(z.string())
138
+ .optional()
139
+ .describe('Find objects by property shape — objects that have ALL of these property names. ' +
140
+ 'Use instead of class_name when constructor is "Object" and you know the property ' +
141
+ 'structure (e.g., ["callback", "context"]). Matches the {prop1, prop2} naming ' +
142
+ 'from shape_histogram output.'),
130
143
  node_ids: z
131
144
  .array(z.number())
132
145
  .optional()
@@ -150,7 +163,14 @@ export function registerRetainerSummary(server) {
150
163
  .optional()
151
164
  .default(false)
152
165
  .describe('Exclude known V8/Node.js framework internals (system / Context, PromiseReaction, module cache patterns) from retainer paths. Helps surface application-level retention.'),
153
- }, async ({ class_name, name_prefix, node_ids, sample, max_depth, compact, framework_filter, }) => {
166
+ include_properties: z
167
+ .boolean()
168
+ .optional()
169
+ .default(false)
170
+ .describe('For each sampled node, also show its direct property edges (name -> target type/name). ' +
171
+ 'Combines "where is it retained?" with "what does it contain?" in one call. ' +
172
+ 'Saves a follow-up memlab_object_shape call per node.'),
173
+ }, async ({ class_name, name_prefix, shape, node_ids, sample, max_depth, compact, framework_filter, include_properties, }) => {
154
174
  try {
155
175
  const snapshot = getSnapshot();
156
176
  let nodes;
@@ -164,6 +184,23 @@ export function registerRetainerSummary(server) {
164
184
  }
165
185
  label = `${nodes.length} specified node(s)`;
166
186
  }
187
+ else if (shape && shape.length > 0) {
188
+ const requiredProps = new Set(shape);
189
+ nodes = filterLargestObjects(snapshot, node => {
190
+ if (node.type !== 'object' || node.id <= 3)
191
+ return false;
192
+ const foundProps = new Set();
193
+ for (const edge of node.references) {
194
+ if (edge.type === 'property') {
195
+ const name = String(edge.name_or_index);
196
+ if (requiredProps.has(name))
197
+ foundProps.add(name);
198
+ }
199
+ }
200
+ return foundProps.size === requiredProps.size;
201
+ }, sample);
202
+ label = `shape {${shape.join(', ')}}`;
203
+ }
167
204
  else if (name_prefix) {
168
205
  nodes = filterLargestObjects(snapshot, node => node.name.startsWith(name_prefix), sample);
169
206
  label = `prefix "${name_prefix}"`;
@@ -179,10 +216,14 @@ export function registerRetainerSummary(server) {
179
216
  label = `"${class_name}"`;
180
217
  }
181
218
  else {
182
- return errorResult(new Error('Either class_name, name_prefix, or node_ids must be provided.'));
219
+ return errorResult(new Error('Either class_name, name_prefix, shape, or node_ids must be provided.'));
183
220
  }
184
221
  if (nodes.length === 0) {
185
- return toolResult(`No objects found for ${label}`);
222
+ const suggestions = [`No objects found for ${label}.`, ''];
223
+ if (class_name) {
224
+ suggestions.push(`**Possible reasons:**`, `- The class name may not match exactly — V8 uses constructor names, not class declarations`, `- For DOM nodes, try \`name_prefix: "Detached"\` instead of class_name`, `- For shape-based queries, use \`memlab_find_by_shape\` with property names instead`, '', `**Try instead:**`, `- \`memlab_search_nodes\` with a regex pattern to find partial matches`, `- \`memlab_class_histogram\` to see all class names in the snapshot`, `- \`memlab_find_by_property\` if you know a property name on the target objects`);
225
+ }
226
+ return toolResult(suggestions.join('\n'));
186
227
  }
187
228
  const patterns = new Map();
188
229
  let noTrace = 0;
@@ -292,10 +333,54 @@ export function registerRetainerSummary(server) {
292
333
  : formatFn(displaySteps));
293
334
  lines.push('');
294
335
  lines.push(`Example nodes: ${p.example_ids.map(id => `@${id}`).join(', ')}`);
336
+ if (include_properties) {
337
+ for (const exId of p.example_ids.slice(0, 2)) {
338
+ const exNode = snapshot.getNodeById(exId);
339
+ if (!exNode)
340
+ continue;
341
+ const props = [];
342
+ for (const edge of exNode.references) {
343
+ if (edge.type === 'property' ||
344
+ edge.type === 'element' ||
345
+ edge.type === 'context') {
346
+ const target = edge.toNode;
347
+ if (target.id <= 3)
348
+ continue;
349
+ let valPreview;
350
+ if (target.isString) {
351
+ const strNode = target.toStringNode();
352
+ const sv = strNode?.stringValue ?? target.name;
353
+ valPreview = `"${sv.length > 30 ? sv.slice(0, 27) + '...' : sv}"`;
354
+ }
355
+ else {
356
+ valPreview = `${target.name} (${target.type})`;
357
+ }
358
+ props.push(`${String(edge.name_or_index)}: ${valPreview}`);
359
+ if (props.length >= 8)
360
+ break;
361
+ }
362
+ }
363
+ if (props.length > 0) {
364
+ lines.push(` @${exId} properties: {${props.join(', ')}}`);
365
+ }
366
+ }
367
+ }
295
368
  lines.push('');
296
369
  }
297
370
  if (noTrace > 0) {
298
- lines.push(`(${noTrace} instance(s) had no retainer path — root or unreachable nodes)`);
371
+ const noTraceNodes = nodes.filter(n => !n.hasPathEdge);
372
+ const withReferrers = noTraceNodes.filter(n => n.numOfReferrers > 0).length;
373
+ const noReferrers = noTrace - withReferrers;
374
+ const parts = [
375
+ `${noTrace} instance(s) had no retainer path:`,
376
+ ];
377
+ if (noReferrers > 0) {
378
+ parts.push(`${noReferrers} with no referrers (GC-eligible, safe to ignore)`);
379
+ }
380
+ if (withReferrers > 0) {
381
+ parts.push(`${withReferrers} with referrers but no GC root path (possibly weak-only retention — use \`memlab_get_referrers\` to inspect)`);
382
+ }
383
+ lines.push(`(${parts.join('; ')})`);
299
384
  }
300
385
  return toolResult(lines.join('\n'));
301
386
  }