@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
@@ -0,0 +1,152 @@
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 } from '../heap-state.js';
12
+ import { formatBytes, formatNodeInline, errorResult, toolResult, suggestionsSuppressed, } from '../utils.js';
13
+ function decodeSmi(node) {
14
+ // V8 stores Small Integers (SMIs) with the value encoded in the node ID.
15
+ // SMI node IDs are odd numbers; the actual value is id >> 1.
16
+ // SMI nodes have type "number" and name "smi number" with self_size 0.
17
+ if (node.name === 'smi number' && node.self_size === 0) {
18
+ return node.id >> 1;
19
+ }
20
+ return null;
21
+ }
22
+ function decodeHeapNumber(node) {
23
+ // V8 stores heap numbers (doubles that don't fit in SMI range) as
24
+ // separate heap objects. The actual IEEE 754 value is not directly
25
+ // accessible via the heap snapshot API, but we can identify them.
26
+ if (node.name === 'heap number' ||
27
+ (node.type === 'number' && node.name !== 'smi number')) {
28
+ // Heap numbers have self_size of 12 or 16 bytes (object header + 8-byte double).
29
+ // The value itself is not exposed in the standard heap snapshot format,
30
+ // but we can check if it's referenced by a property edge to provide context.
31
+ return {
32
+ value: null,
33
+ raw: 'IEEE 754 double (value not stored in snapshot format)',
34
+ };
35
+ }
36
+ return { value: null, raw: null };
37
+ }
38
+ function getPropertyContext(node) {
39
+ const contexts = [];
40
+ for (const edge of node.referrers) {
41
+ if (edge.type === 'property' ||
42
+ edge.type === 'element' ||
43
+ edge.type === 'context') {
44
+ const from = edge.fromNode;
45
+ if (from.id <= 3)
46
+ continue;
47
+ contexts.push({
48
+ ownerName: from.name,
49
+ ownerType: from.type,
50
+ ownerId: from.id,
51
+ propertyName: String(edge.name_or_index),
52
+ });
53
+ if (contexts.length >= 10)
54
+ break;
55
+ }
56
+ }
57
+ return contexts;
58
+ }
59
+ export function registerGetValue(server) {
60
+ server.tool('memlab_get_value', 'Decode the actual numeric value of a V8 SMI (Small Integer) or heap number node. ' +
61
+ 'V8 stores numbers as either SMI nodes (value encoded as id >> 1, self_size 0) or ' +
62
+ 'heap number nodes (IEEE 754 doubles). This tool decodes them and shows which objects ' +
63
+ 'reference the number and via which property name, providing the context needed to ' +
64
+ 'understand what the number represents. Essential when inspecting numeric properties ' +
65
+ 'like counters, capacities, or sizes that appear as opaque "smi number" or "heap number" nodes.', {
66
+ node_id: z
67
+ .number()
68
+ .describe('The numeric ID of the number node to decode, OR (with property_name) the owner object whose numeric property should be decoded.'),
69
+ property_name: z
70
+ .string()
71
+ .optional()
72
+ .describe('Optional: decode this numeric property of node_id instead of node_id itself. Lets you decode an inline SMI/number property by (node_id, property_name) without first looking up the value node.'),
73
+ }, async ({ node_id, property_name }) => {
74
+ try {
75
+ const snapshot = getSnapshot();
76
+ const owner = snapshot.getNodeById(node_id);
77
+ if (!owner) {
78
+ return errorResult(`Node with id ${node_id} not found`);
79
+ }
80
+ let node = owner;
81
+ if (property_name != null) {
82
+ const edge = owner.references.find(e => e.type === 'property' &&
83
+ String(e.name_or_index) === property_name);
84
+ if (!edge) {
85
+ return errorResult(`Property "${property_name}" not found on @${node_id} (${owner.name}).`);
86
+ }
87
+ node = edge.toNode;
88
+ }
89
+ const lines = [];
90
+ if (property_name != null) {
91
+ lines.push(`**Property:** \`${property_name}\` on @${node_id} ${owner.name} (${owner.type})`);
92
+ }
93
+ lines.push(`**Node:** ${formatNodeInline(node.id, node.name, node.type, node.self_size)}`);
94
+ lines.push(`**Self Size:** ${formatBytes(node.self_size)} | **Retained Size:** ${formatBytes(node.retainedSize)}`);
95
+ lines.push('');
96
+ const smiValue = decodeSmi(node);
97
+ if (smiValue !== null) {
98
+ lines.push(`**Decoded SMI Value:** ${smiValue}`);
99
+ lines.push(`**Encoding:** SMI (Small Integer) — value = node_id >> 1 = ${node.id} >> 1 = ${smiValue}`);
100
+ }
101
+ else {
102
+ const heapNum = decodeHeapNumber(node);
103
+ if (heapNum.raw) {
104
+ lines.push(`**Type:** Heap Number (boxed double-precision float)`);
105
+ lines.push(`**Note:** ${heapNum.raw}`);
106
+ lines.push('');
107
+ lines.push('_The V8 heap snapshot format does not include the raw IEEE 754 value for heap numbers. Check the property name and owner context below to infer meaning._');
108
+ }
109
+ else if (node.type === 'number') {
110
+ lines.push(`**Type:** Number node (unrecognized encoding)`);
111
+ }
112
+ else {
113
+ lines.push(`**Note:** Node @${node.id} is not a number node (type: "${node.type}", name: "${node.name}").`);
114
+ lines.push('This tool is designed for "smi number" and "heap number" nodes.');
115
+ if (node.isString) {
116
+ const strNode = node.toStringNode();
117
+ if (strNode) {
118
+ const val = strNode.stringValue;
119
+ const numVal = Number(val);
120
+ if (!isNaN(numVal)) {
121
+ lines.push('');
122
+ lines.push(`However, this is a string node with numeric content: "${val.slice(0, 100)}" (parsed as ${numVal})`);
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ const contexts = getPropertyContext(node);
129
+ if (contexts.length > 0) {
130
+ lines.push('');
131
+ lines.push('**Referenced by:**');
132
+ for (const ctx of contexts) {
133
+ lines.push(`- \`${ctx.propertyName}\` on @${ctx.ownerId} \`${ctx.ownerName}\` (${ctx.ownerType})`);
134
+ }
135
+ }
136
+ if (!suggestionsSuppressed()) {
137
+ lines.push('');
138
+ lines.push('**Suggested next steps:**');
139
+ if (contexts.length > 0) {
140
+ lines.push(`- Inspect owner: \`memlab_object_shape(${contexts[0].ownerId})\``);
141
+ lines.push(`- Trace owner retention: \`memlab_retainer_trace(${contexts[0].ownerId})\``);
142
+ }
143
+ lines.push(`- For all number properties on an object, use \`memlab_object_shape\` — it decodes SMI values inline`);
144
+ }
145
+ return toolResult(lines.join('\n'));
146
+ }
147
+ catch (err) {
148
+ return errorResult(err);
149
+ }
150
+ });
151
+ }
152
+ //# sourceMappingURL=get-value.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-value.js","sourceRoot":"","sources":["../../src/tools/get-value.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"global-variables.d.ts","sourceRoot":"","sources":["../../src/tools/global-variables.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAsQvE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyF/D"}
1
+ {"version":3,"file":"global-variables.d.ts","sourceRoot":"","sources":["../../src/tools/global-variables.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAuQvE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+G/D"}
@@ -9,7 +9,7 @@
9
9
  */
10
10
  import { z } from 'zod';
11
11
  import { getSnapshot, getSnapshotEnv } from '../heap-state.js';
12
- import { formatBytes, markdownTable, errorResult, toolResult, } from '../utils.js';
12
+ import { formatBytes, markdownTable, errorResult, toolResult, makeScanBudget, ScanTimeoutError, } from '../utils.js';
13
13
  // Common built-in Window properties that should be excluded.
14
14
  // This is a subset of the ~780 known browser globals from MemLab's BuiltInGlobalVariables.
15
15
  const BUILTIN_GLOBALS = new Set([
@@ -261,54 +261,74 @@ const BUILTIN_GLOBALS = new Set([
261
261
  'postMessage',
262
262
  ]);
263
263
  export function registerGlobalVariables(server) {
264
- server.tool('memlab_global_variables', 'Find non-built-in global variables on the Window object (browser) or global object (Node.js), sorted by retained size. These are application-specific globals that may indicate memory issues.', {
264
+ server.tool('memlab_global_variables', 'Find non-built-in global variables on the Window object (browser) or global object (Node.js), sorted by retained size. These are application-specific globals that may indicate memory issues. ' +
265
+ '⚠ Full-heap scan — slow on very large heaps (millions of nodes).', {
265
266
  limit: z
266
267
  .number()
267
268
  .optional()
268
269
  .default(20)
269
270
  .describe('Maximum number of results (default 20)'),
270
- }, async ({ limit }) => {
271
+ timeout_ms: z
272
+ .number()
273
+ .optional()
274
+ .default(45000)
275
+ .describe('Wall-clock budget for the full-heap scan (default 45000). On very large browser heaps, returns partial results with a note instead of hanging.'),
276
+ }, async ({ limit, timeout_ms }) => {
271
277
  try {
272
278
  const snapshot = getSnapshot();
279
+ const budget = makeScanBudget(timeout_ms);
280
+ let timedOut = false;
273
281
  const globals = [];
274
282
  const env = getSnapshotEnv();
275
283
  const globalMatcher = env === 'node'
276
284
  ? (name) => name === 'global' || name === 'Global'
277
285
  : (name) => name.startsWith('Window ');
278
- snapshot.nodes.forEach(node => {
279
- if (!globalMatcher(node.name))
280
- return;
281
- for (const edge of node.references) {
282
- const edgeName = String(edge.name_or_index);
283
- // Skip built-in globals
284
- if (BUILTIN_GLOBALS.has(edgeName))
285
- continue;
286
- // Skip internal/hidden edges
287
- if (edge.type === 'hidden' || edge.type === 'internal')
288
- continue;
289
- // Skip symbol edges
290
- if (edgeName.startsWith('<symbol>'))
291
- continue;
292
- // Skip non-inspectable target types
293
- const target = edge.toNode;
294
- if (target.type === 'hidden' ||
295
- target.type === 'array' ||
296
- target.type === 'number')
297
- continue;
298
- globals.push({
299
- name: edgeName,
300
- target_id: target.id,
301
- target_name: target.name,
302
- target_type: target.type,
303
- retained_size: target.retainedSize,
304
- });
305
- }
306
- });
286
+ try {
287
+ snapshot.nodes.forEach(node => {
288
+ budget.tick();
289
+ if (!globalMatcher(node.name))
290
+ return;
291
+ for (const edge of node.references) {
292
+ const edgeName = String(edge.name_or_index);
293
+ // Skip built-in globals
294
+ if (BUILTIN_GLOBALS.has(edgeName))
295
+ continue;
296
+ // Skip internal/hidden edges
297
+ if (edge.type === 'hidden' || edge.type === 'internal')
298
+ continue;
299
+ // Skip symbol edges
300
+ if (edgeName.startsWith('<symbol>'))
301
+ continue;
302
+ // Skip non-inspectable target types
303
+ const target = edge.toNode;
304
+ if (target.type === 'hidden' ||
305
+ target.type === 'array' ||
306
+ target.type === 'number')
307
+ continue;
308
+ globals.push({
309
+ name: edgeName,
310
+ target_id: target.id,
311
+ target_name: target.name,
312
+ target_type: target.type,
313
+ retained_size: target.retainedSize,
314
+ });
315
+ }
316
+ });
317
+ }
318
+ catch (e) {
319
+ if (e instanceof ScanTimeoutError)
320
+ timedOut = true;
321
+ else
322
+ throw e;
323
+ }
307
324
  // Sort by retained size descending
308
325
  globals.sort((a, b) => b.retained_size - a.retained_size);
309
326
  const topGlobals = globals.slice(0, limit);
327
+ const timeoutNote = timedOut
328
+ ? `\n\n⚠ Scan hit the ${timeout_ms}ms budget and returned PARTIAL results (raise timeout_ms to scan the whole heap).`
329
+ : '';
310
330
  if (topGlobals.length === 0) {
311
- return toolResult('No non-built-in global variables found.');
331
+ return toolResult('No non-built-in global variables found.' + timeoutNote);
312
332
  }
313
333
  const headers = [
314
334
  'Variable',
@@ -325,7 +345,7 @@ export function registerGlobalVariables(server) {
325
345
  g.target_type,
326
346
  formatBytes(g.retained_size),
327
347
  ]);
328
- return toolResult(`Global variables (${topGlobals.length} found)\n\n${markdownTable(headers, rows, rightCols)}`);
348
+ return toolResult(`Global variables (${topGlobals.length} found)\n\n${markdownTable(headers, rows, rightCols)}${timeoutNote}`);
329
349
  }
330
350
  catch (err) {
331
351
  return errorResult(err);
@@ -1 +1 @@
1
- {"version":3,"file":"global-variables.js","sourceRoot":"","sources":["../../src/tools/global-variables.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"global-variables.js","sourceRoot":"","sources":["../../src/tools/global-variables.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 registerGrowthSignals(server: McpServer): void;
12
+ //# sourceMappingURL=growth-signals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"growth-signals.d.ts","sourceRoot":"","sources":["../../src/tools/growth-signals.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAoFvE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgJ7D"}
@@ -0,0 +1,211 @@
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, hasFreshnessTimestampSibling, } from '../utils.js';
13
+ const NOW_MS = 1_700_000_000_000; // ~2023; lower bound for plausible ms epoch
14
+ const FUTURE_MS = 4_100_000_000_000; // ~2099; upper bound
15
+ function looksLikeTimestamp(n) {
16
+ // ms epoch
17
+ if (n >= NOW_MS && n <= FUTURE_MS)
18
+ return true;
19
+ // s epoch
20
+ if (n >= NOW_MS / 1000 && n <= FUTURE_MS / 1000)
21
+ return true;
22
+ return false;
23
+ }
24
+ function classifyKeys(keys) {
25
+ if (keys.length < 3)
26
+ return null;
27
+ const nums = keys.map(k => Number(k)).filter(n => Number.isFinite(n));
28
+ if (nums.length < keys.length * 0.8)
29
+ return null; // mostly non-numeric → skip
30
+ const sorted = [...nums].sort((a, b) => a - b);
31
+ if (sorted.every(n => looksLikeTimestamp(n)))
32
+ return 'timestamp';
33
+ // sequential / monotonic integers (consecutive-ish)
34
+ let consecutive = 0;
35
+ for (let i = 1; i < sorted.length; i++) {
36
+ if (sorted[i] - sorted[i - 1] <= 2)
37
+ consecutive++;
38
+ }
39
+ if (consecutive >= (sorted.length - 1) * 0.7) {
40
+ return Number.isInteger(sorted[0]) && sorted[0] >= 0
41
+ ? 'sequential-int'
42
+ : 'monotonic-string';
43
+ }
44
+ return null;
45
+ }
46
+ function sampleMapKeys(node, max) {
47
+ const keys = [];
48
+ for (const edge of node.references) {
49
+ const n = String(edge.name_or_index);
50
+ if ((n === 'table' || n === 'backing_store') &&
51
+ (edge.toNode.type === 'array' || edge.toNode.type === 'hidden')) {
52
+ const refs = [];
53
+ for (const te of edge.toNode.references)
54
+ refs.push(te.toNode);
55
+ const step = node.name === 'Map' ? 2 : 1;
56
+ for (let i = 0; i < refs.length && keys.length < max; i += step) {
57
+ const k = refs[i];
58
+ if (!k || k.id <= 3)
59
+ continue;
60
+ if (k.name === 'undefined' || k.name === 'the_hole')
61
+ continue;
62
+ if (k.isString) {
63
+ const s = k.toStringNode();
64
+ keys.push(s ? s.stringValue : k.name);
65
+ }
66
+ else if (k.name === 'smi number' && k.self_size === 0) {
67
+ keys.push(String(k.id >> 1));
68
+ }
69
+ }
70
+ break;
71
+ }
72
+ }
73
+ return keys;
74
+ }
75
+ export function registerGrowthSignals(server) {
76
+ server.tool('memlab_growth_signals', 'Heuristically flag collections that look like they grow without bound, from a SINGLE snapshot (no baseline needed). Detects Maps/Sets keyed by timestamps or sequential integers (time-series / append-only logs) and large ever-growing Arrays. Use when you have only one snapshot and want to guess what is accumulating, before confirming with a diff against a later capture.', {
77
+ limit: z
78
+ .number()
79
+ .optional()
80
+ .default(15)
81
+ .describe('Maximum number of candidates to return (default 15).'),
82
+ min_entries: z
83
+ .number()
84
+ .optional()
85
+ .default(200)
86
+ .describe('Minimum entry/element count to consider (default 200).'),
87
+ min_retained_size: z
88
+ .number()
89
+ .optional()
90
+ .default(262144)
91
+ .describe('Minimum retained size in bytes (default 256 KB).'),
92
+ }, async ({ limit, min_entries, min_retained_size }) => {
93
+ try {
94
+ const snapshot = getSnapshot();
95
+ const meta = getSnapshotMetadata();
96
+ const totalSize = meta?.totalSize ?? 0;
97
+ const candidates = [];
98
+ // Count of large arrays skipped because they are the data side of a
99
+ // load-once `{entries, loadedAt}`-style TTL cache (a point-in-time
100
+ // snapshot, not append-only growth). Feedback round 4 §C.
101
+ let excludedLoadOnce = 0;
102
+ const insert = (c) => {
103
+ let i = 0;
104
+ for (; i < candidates.length; i++) {
105
+ if (c.retainedSize > candidates[i].retainedSize)
106
+ break;
107
+ }
108
+ candidates.splice(i, 0, c);
109
+ if (candidates.length > limit)
110
+ candidates.length = limit;
111
+ };
112
+ snapshot.nodes.forEach(node => {
113
+ if (node.id <= 3 || node.type !== 'object')
114
+ return;
115
+ if (node.retainedSize < min_retained_size)
116
+ return;
117
+ if (node.name === 'Map' || node.name === 'Set') {
118
+ const keys = sampleMapKeys(node, 60);
119
+ // Use the larger of sampled count and a table-based estimate.
120
+ if (keys.length < 3)
121
+ return;
122
+ const pattern = classifyKeys(keys);
123
+ if (!pattern)
124
+ return;
125
+ // Estimate entries from edge_count of the table.
126
+ let entries = keys.length;
127
+ for (const edge of node.references) {
128
+ const n = String(edge.name_or_index);
129
+ if (n === 'table' || n === 'backing_store') {
130
+ entries = Math.max(entries, node.name === 'Map'
131
+ ? Math.floor(edge.toNode.edge_count / 2)
132
+ : edge.toNode.edge_count);
133
+ break;
134
+ }
135
+ }
136
+ if (entries < min_entries)
137
+ return;
138
+ insert({
139
+ nodeId: node.id,
140
+ kind: `${node.name} (${pattern === 'timestamp' ? 'time-keyed' : 'sequentially-keyed'})`,
141
+ entryCount: entries,
142
+ retainedSize: node.retainedSize,
143
+ pattern,
144
+ sample: keys.slice(0, 3).join(', '),
145
+ });
146
+ }
147
+ else if (node.name === 'Array') {
148
+ const count = node.edge_count;
149
+ if (count < min_entries)
150
+ return;
151
+ // A large array held by a `{..., loadedAt/timestamp}` cache wrapper
152
+ // is a load-once snapshot refreshed wholesale, not append-only
153
+ // growth — don't flag it as a growth signal. Feedback round 4 §C.
154
+ if (hasFreshnessTimestampSibling(node)) {
155
+ excludedLoadOnce++;
156
+ return;
157
+ }
158
+ // Heuristic: large dense arrays are append-only growth candidates.
159
+ insert({
160
+ nodeId: node.id,
161
+ kind: 'Array (append-only candidate)',
162
+ entryCount: count,
163
+ retainedSize: node.retainedSize,
164
+ pattern: 'sequential-int',
165
+ sample: `${formatNumber(count)} elements`,
166
+ });
167
+ }
168
+ });
169
+ const loadOnceNote = excludedLoadOnce > 0
170
+ ? ` (${formatNumber(excludedLoadOnce)} large array(s) held by a \`{…, loadedAt/timestamp}\` cache wrapper were excluded as load-once snapshots, not append-only growth)`
171
+ : '';
172
+ if (candidates.length === 0) {
173
+ return toolResult(`No growth signals found (no timestamp/sequentially-keyed collections or large arrays >= ${formatNumber(min_entries)} entries and >= ${formatBytes(min_retained_size)})${loadOnceNote}. This is a single-snapshot heuristic — capture a second snapshot later and use memlab_diff_snapshots to confirm actual growth.`);
174
+ }
175
+ const headers = [
176
+ 'ID',
177
+ 'Kind',
178
+ 'Entries',
179
+ 'Retained',
180
+ '% Heap',
181
+ 'Sample keys',
182
+ ];
183
+ const rightCols = new Set([2, 3, 4]);
184
+ const rows = candidates.map(c => [
185
+ `@${c.nodeId}`,
186
+ c.kind,
187
+ formatNumber(c.entryCount),
188
+ formatBytes(c.retainedSize),
189
+ totalSize > 0
190
+ ? Math.min(100, (c.retainedSize / totalSize) * 100).toFixed(1) + '%'
191
+ : '-',
192
+ c.sample.length > 40 ? c.sample.slice(0, 37) + '…' : c.sample,
193
+ ]);
194
+ const lines = [
195
+ `## Growth Signals (single-snapshot heuristic)`,
196
+ '',
197
+ `${candidates.length} collection(s) that look like unbounded accumulation:`,
198
+ '',
199
+ markdownTable(headers, rows, rightCols),
200
+ '',
201
+ ...(loadOnceNote ? [`_Note:${loadOnceNote}_`, ''] : []),
202
+ '_Heuristic only — timestamp/sequential keys and large dense arrays *suggest* append-only growth but do not prove it. Confirm by capturing a later snapshot and running `memlab_diff_snapshots`, or trace one with `memlab_retainer_trace` to see what keeps it alive._',
203
+ ];
204
+ return toolResult(lines.join('\n'));
205
+ }
206
+ catch (err) {
207
+ return errorResult(err);
208
+ }
209
+ });
210
+ }
211
+ //# sourceMappingURL=growth-signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"growth-signals.js","sourceRoot":"","sources":["../../src/tools/growth-signals.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 registerInternOpportunities(server: McpServer): void;
12
+ //# sourceMappingURL=intern-opportunities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intern-opportunities.d.ts","sourceRoot":"","sources":["../../src/tools/intern-opportunities.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AA2BvE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgXnE"}