@memlab/mcp-server 2.1.1 → 2.18.1

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 (175) hide show
  1. package/README.md +83 -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 +53 -1
  11. package/dist/heap-state.d.ts.map +1 -1
  12. package/dist/heap-state.js +153 -10
  13. package/dist/heap-state.js.map +1 -1
  14. package/dist/index.js +38 -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 +1056 -52
  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 +200 -48
  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-references.d.ts.map +1 -1
  75. package/dist/tools/get-references.js +35 -6
  76. package/dist/tools/get-references.js.map +1 -1
  77. package/dist/tools/get-referrers.d.ts.map +1 -1
  78. package/dist/tools/get-referrers.js +35 -6
  79. package/dist/tools/get-referrers.js.map +1 -1
  80. package/dist/tools/get-string.d.ts +12 -0
  81. package/dist/tools/get-string.d.ts.map +1 -0
  82. package/dist/tools/get-string.js +223 -0
  83. package/dist/tools/get-string.js.map +1 -0
  84. package/dist/tools/get-value.d.ts +12 -0
  85. package/dist/tools/get-value.d.ts.map +1 -0
  86. package/dist/tools/get-value.js +152 -0
  87. package/dist/tools/get-value.js.map +1 -0
  88. package/dist/tools/global-variables.d.ts.map +1 -1
  89. package/dist/tools/global-variables.js +54 -34
  90. package/dist/tools/global-variables.js.map +1 -1
  91. package/dist/tools/growth-signals.d.ts +12 -0
  92. package/dist/tools/growth-signals.d.ts.map +1 -0
  93. package/dist/tools/growth-signals.js +211 -0
  94. package/dist/tools/growth-signals.js.map +1 -0
  95. package/dist/tools/intern-opportunities.d.ts +12 -0
  96. package/dist/tools/intern-opportunities.d.ts.map +1 -0
  97. package/dist/tools/intern-opportunities.js +870 -0
  98. package/dist/tools/intern-opportunities.js.map +1 -0
  99. package/dist/tools/largest-objects.d.ts.map +1 -1
  100. package/dist/tools/largest-objects.js +37 -14
  101. package/dist/tools/largest-objects.js.map +1 -1
  102. package/dist/tools/load-snapshot.d.ts +70 -0
  103. package/dist/tools/load-snapshot.d.ts.map +1 -1
  104. package/dist/tools/load-snapshot.js +446 -17
  105. package/dist/tools/load-snapshot.js.map +1 -1
  106. package/dist/tools/object-cost-breakdown.d.ts +12 -0
  107. package/dist/tools/object-cost-breakdown.d.ts.map +1 -0
  108. package/dist/tools/object-cost-breakdown.js +439 -0
  109. package/dist/tools/object-cost-breakdown.js.map +1 -0
  110. package/dist/tools/object-shape.d.ts.map +1 -1
  111. package/dist/tools/object-shape.js +109 -2
  112. package/dist/tools/object-shape.js.map +1 -1
  113. package/dist/tools/pinch-points.d.ts.map +1 -1
  114. package/dist/tools/pinch-points.js +9 -9
  115. package/dist/tools/pinch-points.js.map +1 -1
  116. package/dist/tools/property-distribution.d.ts +12 -0
  117. package/dist/tools/property-distribution.d.ts.map +1 -0
  118. package/dist/tools/property-distribution.js +168 -0
  119. package/dist/tools/property-distribution.js.map +1 -0
  120. package/dist/tools/quick-diagnosis.d.ts.map +1 -1
  121. package/dist/tools/quick-diagnosis.js +65 -20
  122. package/dist/tools/quick-diagnosis.js.map +1 -1
  123. package/dist/tools/retainer-summary.d.ts.map +1 -1
  124. package/dist/tools/retainer-summary.js +90 -5
  125. package/dist/tools/retainer-summary.js.map +1 -1
  126. package/dist/tools/retainer-trace.d.ts.map +1 -1
  127. package/dist/tools/retainer-trace.js +173 -43
  128. package/dist/tools/retainer-trace.js.map +1 -1
  129. package/dist/tools/search-nodes.d.ts.map +1 -1
  130. package/dist/tools/search-nodes.js +10 -3
  131. package/dist/tools/search-nodes.js.map +1 -1
  132. package/dist/tools/search-strings.d.ts +12 -0
  133. package/dist/tools/search-strings.d.ts.map +1 -0
  134. package/dist/tools/search-strings.js +182 -0
  135. package/dist/tools/search-strings.js.map +1 -0
  136. package/dist/tools/sequence-analysis.d.ts +12 -0
  137. package/dist/tools/sequence-analysis.d.ts.map +1 -0
  138. package/dist/tools/sequence-analysis.js +244 -0
  139. package/dist/tools/sequence-analysis.js.map +1 -0
  140. package/dist/tools/server-status.d.ts +12 -0
  141. package/dist/tools/server-status.d.ts.map +1 -0
  142. package/dist/tools/server-status.js +41 -0
  143. package/dist/tools/server-status.js.map +1 -0
  144. package/dist/tools/shape-histogram.d.ts.map +1 -1
  145. package/dist/tools/shape-histogram.js +61 -16
  146. package/dist/tools/shape-histogram.js.map +1 -1
  147. package/dist/tools/sliced-strings.d.ts.map +1 -1
  148. package/dist/tools/sliced-strings.js +38 -15
  149. package/dist/tools/sliced-strings.js.map +1 -1
  150. package/dist/tools/snapshot-header.d.ts +28 -0
  151. package/dist/tools/snapshot-header.d.ts.map +1 -0
  152. package/dist/tools/snapshot-header.js +111 -0
  153. package/dist/tools/snapshot-header.js.map +1 -0
  154. package/dist/tools/snapshot-summary.d.ts.map +1 -1
  155. package/dist/tools/snapshot-summary.js +55 -13
  156. package/dist/tools/snapshot-summary.js.map +1 -1
  157. package/dist/tools/snapshots.d.ts +12 -0
  158. package/dist/tools/snapshots.d.ts.map +1 -0
  159. package/dist/tools/snapshots.js +93 -0
  160. package/dist/tools/snapshots.js.map +1 -0
  161. package/dist/tools/stale-collections.d.ts.map +1 -1
  162. package/dist/tools/stale-collections.js +248 -7
  163. package/dist/tools/stale-collections.js.map +1 -1
  164. package/dist/tools/trace-dominators.d.ts.map +1 -1
  165. package/dist/tools/trace-dominators.js +28 -1
  166. package/dist/tools/trace-dominators.js.map +1 -1
  167. package/dist/tools/weakmap-entries.d.ts +12 -0
  168. package/dist/tools/weakmap-entries.d.ts.map +1 -0
  169. package/dist/tools/weakmap-entries.js +156 -0
  170. package/dist/tools/weakmap-entries.js.map +1 -0
  171. package/dist/utils.d.ts +139 -2
  172. package/dist/utils.d.ts.map +1 -1
  173. package/dist/utils.js +448 -35
  174. package/dist/utils.js.map +1 -1
  175. package/package.json +3 -3
@@ -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 } from '../utils.js';
14
+ import { formatBytes, formatNumber, errorResult, toolResult, suggestionsSuppressed, } from '../utils.js';
15
15
  function getPropertyNames(node) {
16
16
  const names = [];
17
17
  for (const edge of node.references) {
@@ -25,7 +25,8 @@ function getPropertyNames(node) {
25
25
  return names;
26
26
  }
27
27
  export function registerShapeHistogram(server) {
28
- server.tool('memlab_shape_histogram', 'Group objects by their property structure (shape/hidden class). Objects with the same set of property names are grouped together, revealing distinct record types. Much more useful than class_histogram when most objects are generic "Object" — this tells you exactly what data structures exist and how much memory each shape consumes. Essential for data-heavy apps where millions of "Object" instances hide 3-5 distinct record shapes.', {
28
+ server.tool('memlab_shape_histogram', 'Group objects by their property structure (shape/hidden class). Objects with the same set of property names are grouped together, revealing distinct record types. Much more useful than class_histogram when most objects are generic "Object" — this tells you exactly what data structures exist and how much memory each shape consumes. Essential for data-heavy apps where millions of "Object" instances hide 3-5 distinct record shapes. ' +
29
+ 'By DEFAULT retained size per shape is reported as a cheap RANGE (lower = Σ self size, upper = Σ retained size) from a single O(N) pass; sorting/filtering by retained uses the upper bound. The exact dominator-deduped value needs a per-shape dominator walk that can stall/OOM the server on very large heaps — pass `exact_retained_size:true` ONLY when the user explicitly asks for it.', {
29
30
  limit: z
30
31
  .number()
31
32
  .optional()
@@ -44,8 +45,24 @@ export function registerShapeHistogram(server) {
44
45
  .string()
45
46
  .optional()
46
47
  .describe('Filter to objects with this constructor name (e.g., "Object"). If omitted, includes all object-type nodes.'),
47
- }, async ({ limit, min_count, min_retained_size, class_name }) => {
48
+ sort_by: z
49
+ .enum(['retained_size', 'retained', 'count', 'self_size', 'self'])
50
+ .optional()
51
+ .default('retained_size')
52
+ .describe('Sort order: "retained_size" (default; alias "retained" — uses the upper-bound retained unless exact_retained_size is set), "count" (instance count — find accumulation patterns), or "self_size" (alias "self").'),
53
+ exact_retained_size: z
54
+ .boolean()
55
+ .optional()
56
+ .default(false)
57
+ .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, }) => {
48
59
  try {
60
+ // Normalize sort aliases so the vocabulary matches other tools.
61
+ const sort = sort_by === 'retained'
62
+ ? 'retained_size'
63
+ : sort_by === 'self'
64
+ ? 'self_size'
65
+ : sort_by;
49
66
  const snapshot = getSnapshot();
50
67
  const shapeMap = new Map();
51
68
  snapshot.nodes.forEach(node => {
@@ -63,28 +80,47 @@ export function registerShapeHistogram(server) {
63
80
  if (existing) {
64
81
  existing.count++;
65
82
  existing.totalSelfSize += node.self_size;
66
- existing.nodeIds.add(node.id);
83
+ existing.rawRetained += node.retainedSize;
84
+ if (existing.nodeIds)
85
+ existing.nodeIds.add(node.id);
67
86
  }
68
87
  else {
69
88
  shapeMap.set(key, {
70
89
  properties: props,
71
90
  count: 1,
72
91
  totalSelfSize: node.self_size,
73
- nodeIds: new NumericSet([node.id]),
92
+ rawRetained: node.retainedSize,
93
+ // Per-node ids only needed for the opt-in exact dominator walk.
94
+ nodeIds: exact_retained_size ? new NumericSet([node.id]) : null,
74
95
  exampleNodeId: node.id,
75
96
  });
76
97
  }
77
98
  });
78
99
  const filtered = [...shapeMap.values()].filter(g => g.count >= min_count);
100
+ // By DEFAULT skip the exact dominator walk (the part that stalls the
101
+ // server on huge heaps) and rank/filter by the upper-bound raw retained
102
+ // sum; only compute exact dominator-deduped retained when asked.
79
103
  const withRetained = filtered.map(g => {
80
- const retainedSize = utils.aggregateDominatorMetrics(g.nodeIds, snapshot, () => true, (node) => node.retainedSize);
81
- return { ...g, retainedSize };
104
+ let exact = null;
105
+ if (exact_retained_size && g.nodeIds) {
106
+ exact = utils.aggregateDominatorMetrics(g.nodeIds, snapshot, () => true, (node) => node.retainedSize);
107
+ }
108
+ const retainedRank = exact ?? g.rawRetained;
109
+ return { ...g, exact, retainedRank };
82
110
  });
83
111
  let finalList = withRetained;
84
112
  if (min_retained_size != null) {
85
- finalList = finalList.filter(g => g.retainedSize >= min_retained_size);
113
+ finalList = finalList.filter(g => g.retainedRank >= min_retained_size);
114
+ }
115
+ if (sort === 'count') {
116
+ finalList.sort((a, b) => b.count - a.count);
117
+ }
118
+ else if (sort === 'self_size') {
119
+ finalList.sort((a, b) => b.totalSelfSize - a.totalSelfSize);
120
+ }
121
+ else {
122
+ finalList.sort((a, b) => b.retainedRank - a.retainedRank);
86
123
  }
87
- finalList.sort((a, b) => b.retainedSize - a.retainedSize);
88
124
  finalList = finalList.slice(0, limit);
89
125
  if (finalList.length === 0) {
90
126
  return toolResult('No object shapes found matching the criteria. Try lowering min_count or removing class_name filter.');
@@ -99,15 +135,24 @@ export function registerShapeHistogram(server) {
99
135
  const propsDisplay = g.properties.length <= 8
100
136
  ? `{${g.properties.join(', ')}}`
101
137
  : `{${g.properties.slice(0, 6).join(', ')}, … +${g.properties.length - 6} more}`;
102
- lines.push(`${i + 1}. **${propsDisplay}** — ${formatNumber(g.count)} instances, ${formatBytes(g.retainedSize)} retained, ${formatBytes(g.totalSelfSize)} self`);
138
+ const retainedStr = exact_retained_size
139
+ ? `${formatBytes(g.exact ?? 0)} retained, ${formatBytes(g.totalSelfSize)} self`
140
+ : `retained ∈ [${formatBytes(g.totalSelfSize)}, ≤ ${formatBytes(g.rawRetained)}]`;
141
+ lines.push(`${i + 1}. **${propsDisplay}** — ${formatNumber(g.count)} instances, ${retainedStr}`);
103
142
  lines.push(` Example: @${g.exampleNodeId}`);
104
143
  }
105
- lines.push('', '**Suggested next steps:**');
106
- const top = finalList[0];
107
- lines.push(`- Inspect example: \`memlab_object_shape(${top.exampleNodeId})\``);
108
- lines.push(`- Trace retention: \`memlab_retainer_trace(${top.exampleNodeId})\``);
109
- if (finalList.length > 1) {
110
- lines.push(`- Compare shapes: \`memlab_object_shape\` on examples from different shapes`);
144
+ if (!exact_retained_size) {
145
+ lines.push('', "_Retained shown as a range `[lower, ≤ upper]`: lower = Σ self size (objects' own bytes), upper = Σ retained size (double-counts subtrees shared between instances on the dominator tree). The exact dominator-deduped value needs a per-shape dominator walk that can stall or time out on large heaps — pass `exact_retained_size:true` for it._");
146
+ }
147
+ if (!suggestionsSuppressed()) {
148
+ lines.push('', '**Suggested next steps:**');
149
+ const top = finalList[0];
150
+ lines.push(`- Inspect example: \`memlab_object_shape(${top.exampleNodeId})\``);
151
+ lines.push(`- Distribution of a property's values: \`memlab_property_distribution\` (cardinality + top values)`);
152
+ lines.push(`- Trace retention: \`memlab_retainer_trace(${top.exampleNodeId})\``);
153
+ if (finalList.length > 1) {
154
+ lines.push(`- Compare shapes: \`memlab_object_shape\` on examples from different shapes`);
155
+ }
111
156
  }
112
157
  return toolResult(lines.join('\n'));
113
158
  }
@@ -1 +1 @@
1
- {"version":3,"file":"shape-histogram.js","sourceRoot":"","sources":["../../src/tools/shape-histogram.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shape-histogram.js","sourceRoot":"","sources":["../../src/tools/shape-histogram.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sliced-strings.d.ts","sourceRoot":"","sources":["../../src/tools/sliced-strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAsBvE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6I7D"}
1
+ {"version":3,"file":"sliced-strings.d.ts","sourceRoot":"","sources":["../../src/tools/sliced-strings.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAqBvE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuK7D"}
@@ -31,9 +31,12 @@ export function registerSlicedStrings(server) {
31
31
  // Map from parent node ID -> stats
32
32
  const parentMap = new Map();
33
33
  snapshot.nodes.forEach(node => {
34
- const isSliced = node.type === 'string' && node.name === 'system / SlicedString';
35
- const isConcat = node.type === 'concatenated string' ||
36
- (node.type === 'string' && node.name === 'system / ConsString');
34
+ // V8 represents these as distinct node *types*, not as `string`
35
+ // nodes with a special name. A sliced string shares the backing
36
+ // store of a parent; a concatenated (cons) string references two
37
+ // halves via `first`/`second`.
38
+ const isSliced = node.type === 'sliced string';
39
+ const isConcat = node.type === 'concatenated string';
37
40
  if (!isSliced && !isConcat)
38
41
  return;
39
42
  if (isSliced) {
@@ -44,17 +47,18 @@ export function registerSlicedStrings(server) {
44
47
  concatCount++;
45
48
  concatTotalSize += node.self_size;
46
49
  }
47
- // For sliced strings, follow the 'parent' edge to find the
48
- // backing string
50
+ // Only sliced strings keep a single large parent alive through the
51
+ // `parent` edge. (Cons strings split across two halves and rarely
52
+ // pin one oversized backing buffer, so they're counted but not
53
+ // attributed to a parent here.)
54
+ if (!isSliced)
55
+ return;
49
56
  for (const edge of node.references) {
50
- const target = edge.toNode;
51
- if (target.type !== 'string')
57
+ if (String(edge.name_or_index) !== 'parent')
52
58
  continue;
53
- // Skip other sliced/concat strings — find the actual parent
54
- if (target.name === 'system / SlicedString' ||
55
- target.name === 'system / ConsString') {
59
+ const target = edge.toNode;
60
+ if (!target.isString)
56
61
  continue;
57
- }
58
62
  const existing = parentMap.get(target.id);
59
63
  if (existing) {
60
64
  existing.sliced_ref_count++;
@@ -70,16 +74,32 @@ export function registerSlicedStrings(server) {
70
74
  sliced_total_size: node.self_size,
71
75
  });
72
76
  }
77
+ break;
73
78
  }
74
79
  });
75
80
  if (slicedCount === 0 && concatCount === 0) {
76
81
  return toolResult('No sliced or concatenated strings found in the snapshot.');
77
82
  }
78
- let parents = [...parentMap.values()];
83
+ const allParents = [...parentMap.values()];
84
+ const totalPinnedBytes = allParents.reduce((sum, p) => sum + p.self_size, 0);
85
+ // Don't go silent when `min_parent_size` filters everything out. On the
86
+ // common "many medium parents" case (each parent sub-MB but thousands of
87
+ // them, e.g. ~250 KB JSON records) the filter used to hide every row and
88
+ // the tool reported nothing actionable. Fall back to the largest parents
89
+ // with a note, and ALWAYS report the aggregate bytes pinned so the "lots
90
+ // of small parents" case is visible (Feedback round 4 §3a).
91
+ let parents = allParents;
92
+ let filteredNote = '';
79
93
  if (min_parent_size != null) {
80
- parents = parents.filter(p => p.self_size >= min_parent_size);
94
+ const filtered = allParents.filter(p => p.self_size >= min_parent_size);
95
+ if (filtered.length > 0) {
96
+ parents = filtered;
97
+ }
98
+ else {
99
+ filteredNote = ` (no parent ≥ ${formatBytes(min_parent_size)}; showing the largest instead)`;
100
+ }
81
101
  }
82
- parents.sort((a, b) => b.self_size - a.self_size);
102
+ parents = [...parents].sort((a, b) => b.self_size - a.self_size);
83
103
  const topParents = parents.slice(0, limit);
84
104
  const lines = [];
85
105
  lines.push(`**Sliced strings:** ${formatNumber(slicedCount)} nodes (${formatBytes(slicedTotalSize)} self size)`);
@@ -87,6 +107,9 @@ export function registerSlicedStrings(server) {
87
107
  lines.push(`**Concatenated strings:** ${formatNumber(concatCount)} nodes (${formatBytes(concatTotalSize)} self size)`);
88
108
  }
89
109
  lines.push(`**Unique parent strings referenced:** ${formatNumber(parentMap.size)}`);
110
+ if (allParents.length > 0) {
111
+ lines.push(`**Total parent bytes pinned by slices:** ${formatBytes(totalPinnedBytes)} across ${formatNumber(allParents.length)} parent string(s) — substrings keep these alive even when each individual parent is small.`);
112
+ }
90
113
  lines.push('');
91
114
  if (topParents.length > 0) {
92
115
  const headers = [
@@ -106,7 +129,7 @@ export function registerSlicedStrings(server) {
106
129
  formatNumber(p.sliced_ref_count),
107
130
  formatBytes(p.sliced_total_size),
108
131
  ]);
109
- lines.push('### Top parent strings (keeping slices alive)');
132
+ lines.push(`### Top parent strings (keeping slices alive)${filteredNote}`);
110
133
  lines.push('');
111
134
  lines.push(markdownTable(headers, rows, rightCols));
112
135
  const largeMB = topParents.filter(p => p.self_size >= 1024 * 1024);
@@ -1 +1 @@
1
- {"version":3,"file":"sliced-strings.js","sourceRoot":"","sources":["../../src/tools/sliced-strings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sliced-strings.js","sourceRoot":"","sources":["../../src/tools/sliced-strings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
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
+ /**
12
+ * memlab_snapshot_header — peek a snapshot's header WITHOUT the dominator pass.
13
+ *
14
+ * The expensive/risky part of memlab_load_snapshot is the dominator-tree
15
+ * computation (uninterruptible, super-linear, can wedge/OOM the server). This
16
+ * tool skips it entirely: it resolves + fetches the file (reusing any cached
17
+ * download, so a follow-up real load doesn't re-download), reads the node/edge
18
+ * counts and capture time from the file header, and reports whether the capture
19
+ * fits under the current auto-scaled load ceiling.
20
+ *
21
+ * The point is to end the "attempt load → refused on counts → hand-compute
22
+ * density → re-query Scuba for a smaller file → retry" loop that dominated a
23
+ * server-snapshot sweep (feedback round 7 §1/§2): peek a candidate, read its
24
+ * exact counts + this-app density + the estimated max-loadable file size, then
25
+ * pick the right capture in one step.
26
+ */
27
+ export declare function registerSnapshotHeader(server: McpServer): void;
28
+ //# sourceMappingURL=snapshot-header.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-header.d.ts","sourceRoot":"","sources":["../../src/tools/snapshot-header.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAcvE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwH9D"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ import { z } from 'zod';
13
+ import { resolveSnapshotPath, peekSnapshotCounts, computeDefaultCeilings, estimateMaxLoadableMB, extractCaptureTime, DEFAULT_MANIFOLD_BUCKET, } from './load-snapshot.js';
14
+ import { formatBytes, formatNumber, errorResult, textResult } from '../utils.js';
15
+ /**
16
+ * memlab_snapshot_header — peek a snapshot's header WITHOUT the dominator pass.
17
+ *
18
+ * The expensive/risky part of memlab_load_snapshot is the dominator-tree
19
+ * computation (uninterruptible, super-linear, can wedge/OOM the server). This
20
+ * tool skips it entirely: it resolves + fetches the file (reusing any cached
21
+ * download, so a follow-up real load doesn't re-download), reads the node/edge
22
+ * counts and capture time from the file header, and reports whether the capture
23
+ * fits under the current auto-scaled load ceiling.
24
+ *
25
+ * The point is to end the "attempt load → refused on counts → hand-compute
26
+ * density → re-query Scuba for a smaller file → retry" loop that dominated a
27
+ * server-snapshot sweep (feedback round 7 §1/§2): peek a candidate, read its
28
+ * exact counts + this-app density + the estimated max-loadable file size, then
29
+ * pick the right capture in one step.
30
+ */
31
+ export function registerSnapshotHeader(server) {
32
+ server.tool('memlab_snapshot_header', "Peek a .heapsnapshot's header (node/edge counts, capture time, file size) WITHOUT loading it — no dominator pass, so it can never wedge or OOM the server the way a full memlab_load_snapshot can. Reports whether the capture fits under the current auto-scaled load ceiling, this app's node/edge density, and — when it doesn't fit — the estimated largest same-app capture that WOULD fit, so you can select a loadable snapshot in one step instead of attempting an oversized load. Accepts a local absolute path, a manifold:// URL, or a bare snapshot filename (resolved against the nest_server_nodejs_heap_snapshots bucket and fetched automatically; the download is reused by a subsequent memlab_load_snapshot). Use this to triage which capture in a size band to load before committing to the expensive load.", {
33
+ file_path: z
34
+ .string()
35
+ .describe('A local absolute path to a .heapsnapshot file, a manifold:// URL (manifold://bucket/key), or a bare snapshot filename to fetch from the nest_server_nodejs_heap_snapshots bucket.'),
36
+ }, async ({ file_path }) => {
37
+ try {
38
+ let resolved;
39
+ let fetchedFrom = null;
40
+ try {
41
+ const r = resolveSnapshotPath(file_path);
42
+ resolved = r.localPath;
43
+ fetchedFrom = r.fetchedFrom;
44
+ }
45
+ catch (fetchErr) {
46
+ const msg = fetchErr instanceof Error ? fetchErr.message : String(fetchErr);
47
+ return errorResult(new Error(`Failed to fetch "${file_path}" from Manifold: ${msg}\n` +
48
+ `Ensure the 'manifold' CLI is installed and you have access to the bucket, ` +
49
+ `or pass a local absolute path instead.`));
50
+ }
51
+ if (!fs.existsSync(resolved)) {
52
+ return errorResult(new Error(`File not found: ${resolved}` +
53
+ (file_path.includes('/')
54
+ ? ''
55
+ : ` (also tried fetching "${file_path}" from the ${DEFAULT_MANIFOLD_BUCKET} bucket)`)));
56
+ }
57
+ const fileStat = fs.statSync(resolved);
58
+ const fileSizeMB = fileStat.size / (1024 * 1024);
59
+ const fileName = path.basename(fetchedFrom ?? file_path.replace(/^manifold:\/\//, ''));
60
+ const counts = peekSnapshotCounts(resolved);
61
+ const ceilings = computeDefaultCeilings();
62
+ const lines = [];
63
+ lines.push(`Snapshot header: ${fileName}`);
64
+ if (fetchedFrom)
65
+ lines.push(`Fetched from Manifold: ${fetchedFrom}`);
66
+ lines.push(`File size: ${formatBytes(fileStat.size)}`);
67
+ if (!counts) {
68
+ lines.push(`Node/edge counts: not found in the header prefix — cannot assess loadability without a full load.`);
69
+ return textResult(lines.join('\n'));
70
+ }
71
+ lines.push(`Nodes: ${formatNumber(counts.nodeCount)} Edges: ${formatNumber(counts.edgeCount)}`);
72
+ const captured = extractCaptureTime(fileName);
73
+ if (captured) {
74
+ const iso = captured.toISOString().slice(0, 10);
75
+ const ageDays = Math.max(0, Math.floor((Date.now() - captured.getTime()) / 86_400_000));
76
+ lines.push(`Captured ${iso} (${ageDays} day(s) ago) — if you find a candidate, verify the fix wasn't already deployed since then before writing one.`);
77
+ }
78
+ const heapNote = ceilings.heapLimitMB > 0
79
+ ? ` (server heap ~${formatNumber(ceilings.heapLimitMB)} MB via --max-old-space-size)`
80
+ : '';
81
+ lines.push(`Current load ceiling: ${formatNumber(ceilings.maxNodes)} nodes / ${formatNumber(ceilings.maxEdges)} edges${heapNote}.`);
82
+ const nodesPerMB = Math.round(counts.nodeCount / fileSizeMB);
83
+ const edgesPerMB = Math.round(counts.edgeCount / fileSizeMB);
84
+ const fitsNodes = counts.nodeCount <= ceilings.maxNodes;
85
+ const fitsEdges = counts.edgeCount <= ceilings.maxEdges;
86
+ if (fitsNodes && fitsEdges) {
87
+ lines.push(`✓ Loadable — under the ceiling on both nodes and edges. Load it with memlab_load_snapshot({file_path: "${file_path}"}); the fetched file is cached so it won't re-download.`);
88
+ }
89
+ else {
90
+ const over = !fitsNodes && !fitsEdges
91
+ ? 'nodes and edges'
92
+ : !fitsEdges
93
+ ? 'edges'
94
+ : 'nodes';
95
+ const estMB = estimateMaxLoadableMB(counts, fileSizeMB, {
96
+ maxNodes: ceilings.maxNodes,
97
+ maxEdges: ceilings.maxEdges,
98
+ });
99
+ lines.push(`✗ Over the ceiling on ${over}. Density: ${formatNumber(nodesPerMB)} nodes/MB, ${formatNumber(edgesPerMB)} edges/MB.` +
100
+ (estMB != null
101
+ ? ` For this app the ceiling corresponds to roughly a ≤${formatNumber(estMB)} MB capture — select a smaller snapshot below that size (then memlab_snapshot_header it to confirm), or force the load with memlab_load_snapshot({force: true}) accepting a long, uninterruptible dominator pass.`
102
+ : ` Select a smaller snapshot, or force the load with memlab_load_snapshot({force: true}).`));
103
+ }
104
+ return textResult(lines.join('\n'));
105
+ }
106
+ catch (err) {
107
+ return errorResult(err);
108
+ }
109
+ });
110
+ }
111
+ //# sourceMappingURL=snapshot-header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-header.js","sourceRoot":"","sources":["../../src/tools/snapshot-header.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot-summary.d.ts","sourceRoot":"","sources":["../../src/tools/snapshot-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAcvE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmI/D"}
1
+ {"version":3,"file":"snapshot-summary.d.ts","sourceRoot":"","sources":["../../src/tools/snapshot-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAevE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwL/D"}
@@ -9,10 +9,19 @@
9
9
  */
10
10
  import memlabCore from '@memlab/core';
11
11
  const { utils, NumericSet } = memlabCore;
12
+ import { z } from 'zod';
12
13
  import { getSnapshot, getFilePath } from '../heap-state.js';
13
- import { formatBytes, formatNumber, markdownTable, errorResult, toolResult, } from '../utils.js';
14
+ import { formatBytes, formatNumber, markdownTable, detectAppName, errorResult, toolResult, } from '../utils.js';
14
15
  export function registerSnapshotSummary(server) {
15
- server.tool('memlab_snapshot_summary', 'Get an overview of the loaded heap snapshot: total nodes, edges, size, and breakdown by node type with count, self size, and aggregate retained size (dominator-aware, no double-counting). Includes anomaly detection for high-count classes that may indicate leaks. Follow up with memlab_class_histogram for per-class breakdown, or memlab_duplicated_strings to find string duplication.', {}, async () => {
16
+ server.tool('memlab_snapshot_summary', 'Get an overview of the loaded heap snapshot: total nodes, edges, size, and per-node-type breakdown with count and self size. ' +
17
+ 'By DEFAULT retained size per type is reported as a cheap RANGE (lower bound = Σ self size, upper bound = Σ retained size) computed in a single O(N) pass — the exact dominator-deduped retained size needs a per-type dominator walk that can stall/OOM the server on very large heaps. Pass `exact_retained_size:true` ONLY when the user explicitly asks for the exact figure. ' +
18
+ 'Includes anomaly detection for high-count classes. Follow up with memlab_class_histogram for a per-class breakdown, or memlab_duplicated_strings to find string duplication.', {
19
+ exact_retained_size: z
20
+ .boolean()
21
+ .optional()
22
+ .default(false)
23
+ .describe('Compute the EXACT dominator-deduped retained size per node type via aggregateDominatorMetrics. DEFAULT false: report a range instead (lower = Σ self size, upper = Σ raw retained size), which is fast and safe on huge heaps. Set true ONLY on explicit user request — the exact walk can be very slow or time out on snapshots with millions of nodes and deep dominator chains.'),
24
+ }, async ({ exact_retained_size }) => {
16
25
  try {
17
26
  const snapshot = getSnapshot();
18
27
  let nodeCount = 0;
@@ -24,45 +33,78 @@ export function registerSnapshotSummary(server) {
24
33
  totalSelfSize += node.self_size;
25
34
  let stats = typeStats.get(node.type);
26
35
  if (!stats) {
27
- stats = { count: 0, self_size: 0, node_ids: new NumericSet() };
36
+ stats = {
37
+ count: 0,
38
+ self_size: 0,
39
+ raw_retained: 0,
40
+ // Only collect per-node ids for the exact dominator walk, which
41
+ // is opt-in — in the default range mode they would waste memory.
42
+ node_ids: exact_retained_size ? new NumericSet() : null,
43
+ };
28
44
  typeStats.set(node.type, stats);
29
45
  }
30
46
  stats.count++;
31
47
  stats.self_size += node.self_size;
32
- stats.node_ids.add(node.id);
48
+ stats.raw_retained += node.retainedSize;
49
+ if (stats.node_ids)
50
+ stats.node_ids.add(node.id);
33
51
  });
34
52
  snapshot.edges.forEach(() => {
35
53
  edgeCount++;
36
54
  });
37
- // Compute aggregate retained size per type using dominator-aware
38
- // aggregation. This deduplicates overlapping retained sizes in the
39
- // dominator tree so the result reflects how much memory would be freed
40
- // if all nodes of a given type were garbage-collected together.
55
+ // Retained size per type. By DEFAULT we do NOT run the exact
56
+ // dominator-aware aggregation (utils.aggregateDominatorMetrics): on
57
+ // large heaps with deep dominator chains it is the operation that
58
+ // stalls/OOMs the server. Instead we report a cheap range computed in
59
+ // the O(N) pass above:
60
+ // - lower bound = Σ self size (the objects' own bytes; never
61
+ // double-counts, but excludes everything they retain)
62
+ // - upper bound = Σ retained size (raw; double-counts memory shared
63
+ // between instances on the dominator tree)
64
+ // The true dominator-deduped value lies in [lower, upper]. Pass
65
+ // exact_retained_size:true to compute the exact figure anyway.
41
66
  const breakdown = [];
42
67
  for (const [type, stats] of typeStats) {
43
- const retainedSize = utils.aggregateDominatorMetrics(stats.node_ids, snapshot, () => true, (node) => node.retainedSize);
68
+ let exact = null;
69
+ if (exact_retained_size && stats.node_ids) {
70
+ exact = utils.aggregateDominatorMetrics(stats.node_ids, snapshot, () => true, (node) => node.retainedSize);
71
+ }
44
72
  breakdown.push({
45
73
  type,
46
74
  count: stats.count,
47
75
  self_size: stats.self_size,
48
- retained_size: retainedSize,
76
+ raw_retained: stats.raw_retained,
77
+ exact,
49
78
  });
50
79
  }
51
- breakdown.sort((a, b) => b.retained_size - a.retained_size);
80
+ breakdown.sort((a, b) => exact_retained_size
81
+ ? (b.exact ?? 0) - (a.exact ?? 0)
82
+ : b.raw_retained - a.raw_retained);
83
+ const appName = detectAppName(snapshot);
52
84
  const lines = [
53
85
  `**File:** ${getFilePath()}`,
86
+ ...(appName
87
+ ? [`**Detected app:** \`${appName}\` (from bundle paths)`]
88
+ : []),
54
89
  `**Nodes:** ${formatNumber(nodeCount)} | **Edges:** ${formatNumber(edgeCount)} | **Total Self Size:** ${formatBytes(totalSelfSize)}`,
55
90
  '',
56
91
  ];
57
- const headers = ['Type', 'Count', 'Self Size', 'Retained Size'];
92
+ const headers = exact_retained_size
93
+ ? ['Type', 'Count', 'Self Size', 'Retained Size']
94
+ : ['Type', 'Count', 'Self (lower)', 'Retained ≤ (upper)'];
58
95
  const rightCols = new Set([1, 2, 3]);
59
96
  const rows = breakdown.map(b => [
60
97
  b.type,
61
98
  formatNumber(b.count),
62
99
  formatBytes(b.self_size),
63
- formatBytes(b.retained_size),
100
+ exact_retained_size
101
+ ? formatBytes(b.exact ?? 0)
102
+ : `≤ ${formatBytes(b.raw_retained)}`,
64
103
  ]);
65
104
  lines.push(markdownTable(headers, rows, rightCols));
105
+ if (!exact_retained_size) {
106
+ lines.push('', "_Retained size is shown as a **range** to avoid an expensive dominator walk. The true dominator-deduped retained size of each type lies between the **lower bound** (`Self` = the objects' own bytes) and the **upper bound** (`Retained ≤` = Σ of each instance's retained size, which double-counts memory shared between instances on the dominator tree). Computing the exact value needs a per-type dominator walk — slow and, on large heaps with deep PromiseReaction/Context chains, prone to stalling or timing out. Pass `exact_retained_size:true` to compute it anyway._");
107
+ }
66
108
  // Anomaly detection: find classes with unusually high instance counts
67
109
  const classMap = new Map();
68
110
  snapshot.nodes.forEach(node => {
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot-summary.js","sourceRoot":"","sources":["../../src/tools/snapshot-summary.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"snapshot-summary.js","sourceRoot":"","sources":["../../src/tools/snapshot-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,MAAM,EAAC,KAAK,EAAE,UAAU,EAAC,GAAG,UAAU,CAAC;AACvC,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,WAAW,EAAE,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,IAAI,CACT,yBAAyB,EACzB,+HAA+H;QAC7H,mXAAmX;QACnX,8KAA8K,EAChL;QACE,mBAAmB,EAAE,CAAC;aACnB,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,OAAO,CAAC,KAAK,CAAC;aACd,QAAQ,CACP,oXAAoX,CACrX;KACJ,EACD,KAAK,EAAE,EAAC,mBAAmB,EAAC,EAAE,EAAE;QAC9B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAE/B,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,aAAa,GAAG,CAAC,CAAC;YACtB,MAAM,SAAS,GAAG,IAAI,GAAG,EAQtB,CAAC;YAEJ,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAC5B,SAAS,EAAE,CAAC;gBACZ,aAAa,IAAI,IAAI,CAAC,SAAS,CAAC;gBAChC,IAAI,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,KAAK,GAAG;wBACN,KAAK,EAAE,CAAC;wBACR,SAAS,EAAE,CAAC;wBACZ,YAAY,EAAE,CAAC;wBACf,gEAAgE;wBAChE,iEAAiE;wBACjE,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI;qBACxD,CAAC;oBACF,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAClC,CAAC;gBACD,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;gBAClC,KAAK,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC;gBACxC,IAAI,KAAK,CAAC,QAAQ;oBAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClD,CAAC,CAAC,CAAC;YACH,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC1B,SAAS,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,6DAA6D;YAC7D,oEAAoE;YACpE,kEAAkE;YAClE,sEAAsE;YACtE,uBAAuB;YACvB,+DAA+D;YAC/D,0DAA0D;YAC1D,sEAAsE;YACtE,+CAA+C;YAC/C,gEAAgE;YAChE,+DAA+D;YAC/D,MAAM,SAAS,GAMT,EAAE,CAAC;YAET,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;gBACtC,IAAI,KAAK,GAAkB,IAAI,CAAC;gBAChC,IAAI,mBAAmB,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBAC1C,KAAK,GAAG,KAAK,CAAC,yBAAyB,CACrC,KAAK,CAAC,QAAQ,EACd,QAAQ,EACR,GAAG,EAAE,CAAC,IAAI,EACV,CAAC,IAAe,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CACvC,CAAC;gBACJ,CAAC;gBACD,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI;oBACJ,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,YAAY,EAAE,KAAK,CAAC,YAAY;oBAChC,KAAK;iBACN,CAAC,CAAC;YACL,CAAC;YAED,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACtB,mBAAmB;gBACjB,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;gBACjC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CACpC,CAAC;YAEF,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;YACxC,MAAM,KAAK,GAAG;gBACZ,aAAa,WAAW,EAAE,EAAE;gBAC5B,GAAG,CAAC,OAAO;oBACT,CAAC,CAAC,CAAC,uBAAuB,OAAO,wBAAwB,CAAC;oBAC1D,CAAC,CAAC,EAAE,CAAC;gBACP,cAAc,YAAY,CAAC,SAAS,CAAC,iBAAiB,YAAY,CAAC,SAAS,CAAC,2BAA2B,WAAW,CAAC,aAAa,CAAC,EAAE;gBACpI,EAAE;aACH,CAAC;YAEF,MAAM,OAAO,GAAG,mBAAmB;gBACjC,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,eAAe,CAAC;gBACjD,CAAC,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,oBAAoB,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACrC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9B,CAAC,CAAC,IAAI;gBACN,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;gBACrB,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;gBACxB,mBAAmB;oBACjB,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;oBAC3B,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE;aACvC,CAAC,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;YACpD,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CACR,EAAE,EACF,sjBAAsjB,CACvjB,CAAC;YACJ,CAAC;YAED,sEAAsE;YACtE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyC,CAAC;YAClE,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAC5B,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC;oBAAE,OAAO;gBACzB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;oBAAE,OAAO;gBAC5D,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAChC,IAAI,KAAK,EAAE,CAAC;oBACV,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAC,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,CAAC,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;iBACtC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC;iBAClC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;iBACvC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAEf,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACf,KAAK,CAAC,IAAI,CACR,0DAA0D,CAC3D,CAAC;gBACF,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC;oBACjC,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACjD,KAAK,CAAC,IAAI,CAAC,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;gBACpE,CAAC;gBACD,yCAAyC;gBACzC,MAAM,cAAc,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAC7C,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACpC,CAAC;gBACF,IAAI,cAAc,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;oBAC/B,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;oBACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;oBACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;oBACrC,IAAI,QAAQ,IAAI,QAAQ,GAAG,GAAG,EAAE,CAAC;wBAC/B,KAAK,CAAC,IAAI,CACR,8DAA8D,CAC/D,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,KAAK,CAAC,IAAI,CACR,EAAE,EACF,uIAAuI,CACxI,CAAC;YACJ,CAAC;YAED,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -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 registerSnapshots(server: McpServer): void;
12
+ //# sourceMappingURL=snapshots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshots.d.ts","sourceRoot":"","sources":["../../src/tools/snapshots.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAYvE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyGzD"}