@memlab/mcp-server 2.18.1 → 2.86.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 (374) hide show
  1. package/README.md +30 -16
  2. package/bin/.eslintrc.js +26 -0
  3. package/bin/memlab-cli.js +313 -0
  4. package/dist/anonymized-snapshot.d.ts +75 -0
  5. package/dist/anonymized-snapshot.d.ts.map +1 -0
  6. package/dist/anonymized-snapshot.js +101 -0
  7. package/dist/anonymized-snapshot.js.map +1 -0
  8. package/dist/artifact-classes.d.ts +86 -0
  9. package/dist/artifact-classes.d.ts.map +1 -0
  10. package/dist/artifact-classes.js +261 -0
  11. package/dist/artifact-classes.js.map +1 -0
  12. package/dist/capture-mode.d.ts +60 -0
  13. package/dist/capture-mode.d.ts.map +1 -0
  14. package/dist/capture-mode.js +39 -0
  15. package/dist/capture-mode.js.map +1 -0
  16. package/dist/eval-hints.d.ts +41 -0
  17. package/dist/eval-hints.d.ts.map +1 -0
  18. package/dist/eval-hints.js +115 -0
  19. package/dist/eval-hints.js.map +1 -0
  20. package/dist/guardrail.d.ts.map +1 -1
  21. package/dist/guardrail.js +13 -0
  22. package/dist/guardrail.js.map +1 -1
  23. package/dist/heap-budget.d.ts +32 -0
  24. package/dist/heap-budget.d.ts.map +1 -0
  25. package/dist/heap-budget.js +90 -0
  26. package/dist/heap-budget.js.map +1 -0
  27. package/dist/heap-shapes.d.ts +148 -0
  28. package/dist/heap-shapes.d.ts.map +1 -0
  29. package/dist/heap-shapes.js +193 -0
  30. package/dist/heap-shapes.js.map +1 -0
  31. package/dist/heap-state.d.ts +109 -2
  32. package/dist/heap-state.d.ts.map +1 -1
  33. package/dist/heap-state.js +194 -3
  34. package/dist/heap-state.js.map +1 -1
  35. package/dist/index.js +102 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/progress.d.ts +25 -0
  38. package/dist/progress.d.ts.map +1 -0
  39. package/dist/progress.js +46 -0
  40. package/dist/progress.js.map +1 -0
  41. package/dist/react-shapes.d.ts +42 -0
  42. package/dist/react-shapes.d.ts.map +1 -0
  43. package/dist/react-shapes.js +149 -0
  44. package/dist/react-shapes.js.map +1 -0
  45. package/dist/result-handles.d.ts +11 -0
  46. package/dist/result-handles.d.ts.map +1 -0
  47. package/dist/result-handles.js +77 -0
  48. package/dist/result-handles.js.map +1 -0
  49. package/dist/server-version.d.ts +19 -0
  50. package/dist/server-version.d.ts.map +1 -0
  51. package/dist/server-version.js +19 -0
  52. package/dist/server-version.js.map +1 -0
  53. package/dist/snapshot-borrow.d.ts +67 -0
  54. package/dist/snapshot-borrow.d.ts.map +1 -0
  55. package/dist/snapshot-borrow.js +113 -0
  56. package/dist/snapshot-borrow.js.map +1 -0
  57. package/dist/string-index.d.ts +55 -0
  58. package/dist/string-index.d.ts.map +1 -0
  59. package/dist/string-index.js +99 -0
  60. package/dist/string-index.js.map +1 -0
  61. package/dist/tool-registry.d.ts +42 -0
  62. package/dist/tool-registry.d.ts.map +1 -0
  63. package/dist/tool-registry.js +20 -0
  64. package/dist/tool-registry.js.map +1 -0
  65. package/dist/tools/analyze-run.d.ts +12 -0
  66. package/dist/tools/analyze-run.d.ts.map +1 -0
  67. package/dist/tools/analyze-run.js +404 -0
  68. package/dist/tools/analyze-run.js.map +1 -0
  69. package/dist/tools/anonymize-snapshot.d.ts +12 -0
  70. package/dist/tools/anonymize-snapshot.d.ts.map +1 -0
  71. package/dist/tools/anonymize-snapshot.js +159 -0
  72. package/dist/tools/anonymize-snapshot.js.map +1 -0
  73. package/dist/tools/app-config.d.ts +12 -0
  74. package/dist/tools/app-config.d.ts.map +1 -0
  75. package/dist/tools/app-config.js +217 -0
  76. package/dist/tools/app-config.js.map +1 -0
  77. package/dist/tools/app-heap.d.ts +30 -0
  78. package/dist/tools/app-heap.d.ts.map +1 -0
  79. package/dist/tools/app-heap.js +106 -0
  80. package/dist/tools/app-heap.js.map +1 -0
  81. package/dist/tools/artifact-budget.d.ts +12 -0
  82. package/dist/tools/artifact-budget.d.ts.map +1 -0
  83. package/dist/tools/artifact-budget.js +219 -0
  84. package/dist/tools/artifact-budget.js.map +1 -0
  85. package/dist/tools/async-census.d.ts +12 -0
  86. package/dist/tools/async-census.d.ts.map +1 -0
  87. package/dist/tools/async-census.js +243 -0
  88. package/dist/tools/async-census.js.map +1 -0
  89. package/dist/tools/auto-investigate.d.ts.map +1 -1
  90. package/dist/tools/auto-investigate.js +54 -5
  91. package/dist/tools/auto-investigate.js.map +1 -1
  92. package/dist/tools/batch.d.ts +12 -0
  93. package/dist/tools/batch.d.ts.map +1 -0
  94. package/dist/tools/batch.js +196 -0
  95. package/dist/tools/batch.js.map +1 -0
  96. package/dist/tools/cache-analysis.d.ts +15 -0
  97. package/dist/tools/cache-analysis.d.ts.map +1 -1
  98. package/dist/tools/cache-analysis.js +240 -14
  99. package/dist/tools/cache-analysis.js.map +1 -1
  100. package/dist/tools/census-diff.d.ts +55 -0
  101. package/dist/tools/census-diff.d.ts.map +1 -0
  102. package/dist/tools/census-diff.js +228 -0
  103. package/dist/tools/census-diff.js.map +1 -0
  104. package/dist/tools/chain-walk.d.ts +12 -0
  105. package/dist/tools/chain-walk.d.ts.map +1 -0
  106. package/dist/tools/chain-walk.js +184 -0
  107. package/dist/tools/chain-walk.js.map +1 -0
  108. package/dist/tools/class-histogram.d.ts.map +1 -1
  109. package/dist/tools/class-histogram.js +14 -3
  110. package/dist/tools/class-histogram.js.map +1 -1
  111. package/dist/tools/collection-diff.d.ts +44 -0
  112. package/dist/tools/collection-diff.d.ts.map +1 -0
  113. package/dist/tools/collection-diff.js +343 -0
  114. package/dist/tools/collection-diff.js.map +1 -0
  115. package/dist/tools/collection-trend.d.ts +55 -0
  116. package/dist/tools/collection-trend.d.ts.map +1 -0
  117. package/dist/tools/collection-trend.js +315 -0
  118. package/dist/tools/collection-trend.js.map +1 -0
  119. package/dist/tools/detached-dom.d.ts +5 -0
  120. package/dist/tools/detached-dom.d.ts.map +1 -1
  121. package/dist/tools/detached-dom.js +368 -22
  122. package/dist/tools/detached-dom.js.map +1 -1
  123. package/dist/tools/dev-artifacts.d.ts +62 -6
  124. package/dist/tools/dev-artifacts.d.ts.map +1 -1
  125. package/dist/tools/dev-artifacts.js +685 -24
  126. package/dist/tools/dev-artifacts.js.map +1 -1
  127. package/dist/tools/diff-snapshots.d.ts.map +1 -1
  128. package/dist/tools/diff-snapshots.js +18 -2
  129. package/dist/tools/diff-snapshots.js.map +1 -1
  130. package/dist/tools/dom-audit.d.ts +37 -0
  131. package/dist/tools/dom-audit.d.ts.map +1 -0
  132. package/dist/tools/dom-audit.js +247 -0
  133. package/dist/tools/dom-audit.js.map +1 -0
  134. package/dist/tools/dominator-attribution.d.ts +12 -0
  135. package/dist/tools/dominator-attribution.d.ts.map +1 -0
  136. package/dist/tools/dominator-attribution.js +189 -0
  137. package/dist/tools/dominator-attribution.js.map +1 -0
  138. package/dist/tools/dominator-chain.d.ts +12 -0
  139. package/dist/tools/dominator-chain.d.ts.map +1 -0
  140. package/dist/tools/dominator-chain.js +92 -0
  141. package/dist/tools/dominator-chain.js.map +1 -0
  142. package/dist/tools/duplicate-objects.d.ts +12 -0
  143. package/dist/tools/duplicate-objects.d.ts.map +1 -0
  144. package/dist/tools/duplicate-objects.js +172 -0
  145. package/dist/tools/duplicate-objects.js.map +1 -0
  146. package/dist/tools/duplicated-strings.d.ts.map +1 -1
  147. package/dist/tools/duplicated-strings.js +49 -40
  148. package/dist/tools/duplicated-strings.js.map +1 -1
  149. package/dist/tools/eval-across.d.ts +12 -0
  150. package/dist/tools/eval-across.d.ts.map +1 -0
  151. package/dist/tools/eval-across.js +135 -0
  152. package/dist/tools/eval-across.js.map +1 -0
  153. package/dist/tools/eval.d.ts +79 -0
  154. package/dist/tools/eval.d.ts.map +1 -1
  155. package/dist/tools/eval.js +2523 -197
  156. package/dist/tools/eval.js.map +1 -1
  157. package/dist/tools/event-listener-leaks.d.ts.map +1 -1
  158. package/dist/tools/event-listener-leaks.js +42 -17
  159. package/dist/tools/event-listener-leaks.js.map +1 -1
  160. package/dist/tools/event-registry.d.ts.map +1 -1
  161. package/dist/tools/event-registry.js +42 -8
  162. package/dist/tools/event-registry.js.map +1 -1
  163. package/dist/tools/explain-delta.d.ts +12 -0
  164. package/dist/tools/explain-delta.d.ts.map +1 -0
  165. package/dist/tools/explain-delta.js +221 -0
  166. package/dist/tools/explain-delta.js.map +1 -0
  167. package/dist/tools/find-nodes-by-class.d.ts.map +1 -1
  168. package/dist/tools/find-nodes-by-class.js +112 -13
  169. package/dist/tools/find-nodes-by-class.js.map +1 -1
  170. package/dist/tools/finding-index.d.ts +203 -0
  171. package/dist/tools/finding-index.d.ts.map +1 -0
  172. package/dist/tools/finding-index.js +566 -0
  173. package/dist/tools/finding-index.js.map +1 -0
  174. package/dist/tools/for-each.d.ts.map +1 -1
  175. package/dist/tools/for-each.js +15 -3
  176. package/dist/tools/for-each.js.map +1 -1
  177. package/dist/tools/get-referrers.d.ts.map +1 -1
  178. package/dist/tools/get-referrers.js +17 -0
  179. package/dist/tools/get-referrers.js.map +1 -1
  180. package/dist/tools/get-value.d.ts +16 -0
  181. package/dist/tools/get-value.d.ts.map +1 -1
  182. package/dist/tools/get-value.js +96 -2
  183. package/dist/tools/get-value.js.map +1 -1
  184. package/dist/tools/hunt-report.d.ts +12 -0
  185. package/dist/tools/hunt-report.d.ts.map +1 -0
  186. package/dist/tools/hunt-report.js +186 -0
  187. package/dist/tools/hunt-report.js.map +1 -0
  188. package/dist/tools/hypothesis.d.ts +12 -0
  189. package/dist/tools/hypothesis.d.ts.map +1 -0
  190. package/dist/tools/hypothesis.js +280 -0
  191. package/dist/tools/hypothesis.js.map +1 -0
  192. package/dist/tools/id-space-audit.d.ts +12 -0
  193. package/dist/tools/id-space-audit.d.ts.map +1 -0
  194. package/dist/tools/id-space-audit.js +262 -0
  195. package/dist/tools/id-space-audit.js.map +1 -0
  196. package/dist/tools/identify.d.ts +12 -0
  197. package/dist/tools/identify.d.ts.map +1 -0
  198. package/dist/tools/identify.js +205 -0
  199. package/dist/tools/identify.js.map +1 -0
  200. package/dist/tools/identity-diff.d.ts +12 -0
  201. package/dist/tools/identity-diff.d.ts.map +1 -0
  202. package/dist/tools/identity-diff.js +188 -0
  203. package/dist/tools/identity-diff.js.map +1 -0
  204. package/dist/tools/intern-opportunities.d.ts.map +1 -1
  205. package/dist/tools/intern-opportunities.js +116 -50
  206. package/dist/tools/intern-opportunities.js.map +1 -1
  207. package/dist/tools/ladder-probe.d.ts +65 -0
  208. package/dist/tools/ladder-probe.d.ts.map +1 -0
  209. package/dist/tools/ladder-probe.js +445 -0
  210. package/dist/tools/ladder-probe.js.map +1 -0
  211. package/dist/tools/ladder.d.ts +33 -0
  212. package/dist/tools/ladder.d.ts.map +1 -0
  213. package/dist/tools/ladder.js +266 -0
  214. package/dist/tools/ladder.js.map +1 -0
  215. package/dist/tools/largest-objects.d.ts.map +1 -1
  216. package/dist/tools/largest-objects.js +6 -2
  217. package/dist/tools/largest-objects.js.map +1 -1
  218. package/dist/tools/leak-report.d.ts +35 -0
  219. package/dist/tools/leak-report.d.ts.map +1 -0
  220. package/dist/tools/leak-report.js +398 -0
  221. package/dist/tools/leak-report.js.map +1 -0
  222. package/dist/tools/load-snapshot.d.ts +29 -0
  223. package/dist/tools/load-snapshot.d.ts.map +1 -1
  224. package/dist/tools/load-snapshot.js +294 -23
  225. package/dist/tools/load-snapshot.js.map +1 -1
  226. package/dist/tools/map-entries.d.ts +12 -0
  227. package/dist/tools/map-entries.d.ts.map +1 -0
  228. package/dist/tools/map-entries.js +139 -0
  229. package/dist/tools/map-entries.js.map +1 -0
  230. package/dist/tools/match-object.d.ts +12 -0
  231. package/dist/tools/match-object.d.ts.map +1 -0
  232. package/dist/tools/match-object.js +165 -0
  233. package/dist/tools/match-object.js.map +1 -0
  234. package/dist/tools/metric.d.ts +13 -0
  235. package/dist/tools/metric.d.ts.map +1 -0
  236. package/dist/tools/metric.js +185 -0
  237. package/dist/tools/metric.js.map +1 -0
  238. package/dist/tools/module-attribution.d.ts +36 -0
  239. package/dist/tools/module-attribution.d.ts.map +1 -0
  240. package/dist/tools/module-attribution.js +235 -0
  241. package/dist/tools/module-attribution.js.map +1 -0
  242. package/dist/tools/next-measurement.d.ts +26 -0
  243. package/dist/tools/next-measurement.d.ts.map +1 -0
  244. package/dist/tools/next-measurement.js +149 -0
  245. package/dist/tools/next-measurement.js.map +1 -0
  246. package/dist/tools/object-cost-breakdown.d.ts.map +1 -1
  247. package/dist/tools/object-cost-breakdown.js +64 -0
  248. package/dist/tools/object-cost-breakdown.js.map +1 -1
  249. package/dist/tools/object-shape.d.ts.map +1 -1
  250. package/dist/tools/object-shape.js +53 -5
  251. package/dist/tools/object-shape.js.map +1 -1
  252. package/dist/tools/population-diff.d.ts +57 -0
  253. package/dist/tools/population-diff.d.ts.map +1 -0
  254. package/dist/tools/population-diff.js +338 -0
  255. package/dist/tools/population-diff.js.map +1 -0
  256. package/dist/tools/population-vs-owners.d.ts +12 -0
  257. package/dist/tools/population-vs-owners.d.ts.map +1 -0
  258. package/dist/tools/population-vs-owners.js +183 -0
  259. package/dist/tools/population-vs-owners.js.map +1 -0
  260. package/dist/tools/property-names.d.ts +29 -0
  261. package/dist/tools/property-names.d.ts.map +1 -0
  262. package/dist/tools/property-names.js +131 -0
  263. package/dist/tools/property-names.js.map +1 -0
  264. package/dist/tools/quick-diagnosis.d.ts.map +1 -1
  265. package/dist/tools/quick-diagnosis.js +7 -1
  266. package/dist/tools/quick-diagnosis.js.map +1 -1
  267. package/dist/tools/react-owners.d.ts +12 -0
  268. package/dist/tools/react-owners.d.ts.map +1 -0
  269. package/dist/tools/react-owners.js +167 -0
  270. package/dist/tools/react-owners.js.map +1 -0
  271. package/dist/tools/react-update-queues.d.ts +12 -0
  272. package/dist/tools/react-update-queues.d.ts.map +1 -0
  273. package/dist/tools/react-update-queues.js +173 -0
  274. package/dist/tools/react-update-queues.js.map +1 -0
  275. package/dist/tools/replicate.d.ts +49 -0
  276. package/dist/tools/replicate.d.ts.map +1 -0
  277. package/dist/tools/replicate.js +241 -0
  278. package/dist/tools/replicate.js.map +1 -0
  279. package/dist/tools/retainer-diff.d.ts +12 -0
  280. package/dist/tools/retainer-diff.d.ts.map +1 -0
  281. package/dist/tools/retainer-diff.js +168 -0
  282. package/dist/tools/retainer-diff.js.map +1 -0
  283. package/dist/tools/retainer-layers.d.ts +23 -0
  284. package/dist/tools/retainer-layers.d.ts.map +1 -0
  285. package/dist/tools/retainer-layers.js +179 -0
  286. package/dist/tools/retainer-layers.js.map +1 -0
  287. package/dist/tools/retainer-summary.d.ts +18 -0
  288. package/dist/tools/retainer-summary.d.ts.map +1 -1
  289. package/dist/tools/retainer-summary.js +210 -51
  290. package/dist/tools/retainer-summary.js.map +1 -1
  291. package/dist/tools/retainer-trace.d.ts.map +1 -1
  292. package/dist/tools/retainer-trace.js +14 -2
  293. package/dist/tools/retainer-trace.js.map +1 -1
  294. package/dist/tools/round-audit.d.ts +66 -0
  295. package/dist/tools/round-audit.d.ts.map +1 -0
  296. package/dist/tools/round-audit.js +258 -0
  297. package/dist/tools/round-audit.js.map +1 -0
  298. package/dist/tools/round-digest.d.ts +12 -0
  299. package/dist/tools/round-digest.d.ts.map +1 -0
  300. package/dist/tools/round-digest.js +190 -0
  301. package/dist/tools/round-digest.js.map +1 -0
  302. package/dist/tools/script-census.d.ts +12 -0
  303. package/dist/tools/script-census.d.ts.map +1 -0
  304. package/dist/tools/script-census.js +182 -0
  305. package/dist/tools/script-census.js.map +1 -0
  306. package/dist/tools/search-nodes.d.ts.map +1 -1
  307. package/dist/tools/search-nodes.js +5 -1
  308. package/dist/tools/search-nodes.js.map +1 -1
  309. package/dist/tools/search-strings.d.ts.map +1 -1
  310. package/dist/tools/search-strings.js +53 -7
  311. package/dist/tools/search-strings.js.map +1 -1
  312. package/dist/tools/sequence-analysis.d.ts +53 -0
  313. package/dist/tools/sequence-analysis.d.ts.map +1 -1
  314. package/dist/tools/sequence-analysis.js +313 -89
  315. package/dist/tools/sequence-analysis.js.map +1 -1
  316. package/dist/tools/server-status.d.ts.map +1 -1
  317. package/dist/tools/server-status.js +4 -1
  318. package/dist/tools/server-status.js.map +1 -1
  319. package/dist/tools/settle-check.d.ts +12 -0
  320. package/dist/tools/settle-check.d.ts.map +1 -0
  321. package/dist/tools/settle-check.js +188 -0
  322. package/dist/tools/settle-check.js.map +1 -0
  323. package/dist/tools/shape-histogram.d.ts.map +1 -1
  324. package/dist/tools/shape-histogram.js +9 -2
  325. package/dist/tools/shape-histogram.js.map +1 -1
  326. package/dist/tools/sliced-strings.d.ts.map +1 -1
  327. package/dist/tools/sliced-strings.js +2 -1
  328. package/dist/tools/sliced-strings.js.map +1 -1
  329. package/dist/tools/snapshots.d.ts.map +1 -1
  330. package/dist/tools/snapshots.js +24 -6
  331. package/dist/tools/snapshots.js.map +1 -1
  332. package/dist/tools/sparse-elements.d.ts +12 -0
  333. package/dist/tools/sparse-elements.d.ts.map +1 -0
  334. package/dist/tools/sparse-elements.js +215 -0
  335. package/dist/tools/sparse-elements.js.map +1 -0
  336. package/dist/tools/stale-collections.d.ts +17 -0
  337. package/dist/tools/stale-collections.d.ts.map +1 -1
  338. package/dist/tools/stale-collections.js +28 -0
  339. package/dist/tools/stale-collections.js.map +1 -1
  340. package/dist/tools/string-patterns.d.ts.map +1 -1
  341. package/dist/tools/string-patterns.js +7 -5
  342. package/dist/tools/string-patterns.js.map +1 -1
  343. package/dist/tools/tools-index.d.ts +12 -0
  344. package/dist/tools/tools-index.d.ts.map +1 -0
  345. package/dist/tools/tools-index.js +492 -0
  346. package/dist/tools/tools-index.js.map +1 -0
  347. package/dist/tools/trace-all.d.ts +42 -0
  348. package/dist/tools/trace-all.d.ts.map +1 -0
  349. package/dist/tools/trace-all.js +263 -0
  350. package/dist/tools/trace-all.js.map +1 -0
  351. package/dist/tools/unit-cost.d.ts +12 -0
  352. package/dist/tools/unit-cost.d.ts.map +1 -0
  353. package/dist/tools/unit-cost.js +219 -0
  354. package/dist/tools/unit-cost.js.map +1 -0
  355. package/dist/tools/verify-fix.d.ts +23 -0
  356. package/dist/tools/verify-fix.d.ts.map +1 -0
  357. package/dist/tools/verify-fix.js +219 -0
  358. package/dist/tools/verify-fix.js.map +1 -0
  359. package/dist/tools/weakmap-entries.d.ts.map +1 -1
  360. package/dist/tools/weakmap-entries.js +6 -1
  361. package/dist/tools/weakmap-entries.js.map +1 -1
  362. package/dist/tools/weakref-census.d.ts +15 -0
  363. package/dist/tools/weakref-census.d.ts.map +1 -0
  364. package/dist/tools/weakref-census.js +147 -0
  365. package/dist/tools/weakref-census.js.map +1 -0
  366. package/dist/tools/what-if.d.ts +12 -0
  367. package/dist/tools/what-if.d.ts.map +1 -0
  368. package/dist/tools/what-if.js +285 -0
  369. package/dist/tools/what-if.js.map +1 -0
  370. package/dist/utils.d.ts +238 -3
  371. package/dist/utils.d.ts.map +1 -1
  372. package/dist/utils.js +507 -15
  373. package/dist/utils.js.map +1 -1
  374. package/package.json +7 -6
@@ -0,0 +1,86 @@
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
+ /**
11
+ * Registry of heap classes whose growth is a MEASUREMENT artifact rather than an
12
+ * application leak.
13
+ *
14
+ * Motivation: across a six-round leak hunt, every single class reported at the
15
+ * top of `sequence_analysis` as "↑ every step (LEAK signal)" belonged to one of
16
+ * the families below — CDP inspector bookkeeping, V8 JIT warmup, or captured
17
+ * error stacks. None was ever a leak. An agent that does not already know this
18
+ * list reads the label and reports a false leak, which is exactly what happened
19
+ * repeatedly before the families were catalogued.
20
+ *
21
+ * These are deliberately matched on CLASS NAME only. Name matching cannot prove
22
+ * that a given instance is an artifact, so the classification is used to
23
+ * annotate and down-rank rows — never to hide them outright (callers can always
24
+ * pass `include_artifacts: true`). Anything that is genuinely ambiguous is left
25
+ * unclassified on purpose: a false "this is an artifact" is far more damaging
26
+ * than a false "this might be a leak".
27
+ */
28
+ export type ArtifactKind = 'warmup' | 'ax' | 'cdp-network' | 'cdp-perf' | 'cdp-console' | 'stack-capture';
29
+ export declare function artifactLabel(kind: ArtifactKind): string;
30
+ export declare function artifactNote(kind: ArtifactKind): string;
31
+ /**
32
+ * Where a non-production string came from. Both kinds are equally unshippable,
33
+ * but they call for different follow-up: `harness` means re-run without the
34
+ * bridge attached to measure the app cleanly, `dev-build` means measure a
35
+ * production build.
36
+ */
37
+ export type NonProductionStringKind = 'harness' | 'dev-build';
38
+ /**
39
+ * Classify a string VALUE as non-production (harness-injected or DEV-build
40
+ * only), or null when it is app content that really does ship.
41
+ */
42
+ export declare function classifyNonProductionString(value: string): {
43
+ kind: NonProductionStringKind;
44
+ what: string;
45
+ } | null;
46
+ /**
47
+ * Back-compatible wrapper returning just the description. Prefer
48
+ * {@link classifyNonProductionString} when the caller can act on the kind.
49
+ */
50
+ export declare function classifyHarnessString(value: string): string | null;
51
+ /**
52
+ * React Fast Refresh module-scope registries, by the edge name that binds each
53
+ * one. These live in the refresh runtime's closure and are reachable only
54
+ * through compiled-code constant pools, so a retainer-root scan does not find
55
+ * them and they classify as `production` unless matched by name here. See
56
+ * `tools/dev-artifacts` for the measured cost of missing them.
57
+ */
58
+ export declare const REACT_REFRESH_REGISTRY_EDGE_NAMES: ReadonlySet<string>;
59
+ /**
60
+ * The rarest property of the react-refresh signature record. Callers gate on
61
+ * this before confirming the full shape, so a scan stays one name compare per
62
+ * edge on everything else.
63
+ */
64
+ export declare const REACT_REFRESH_SIGNATURE_GATE_PROP = "getCustomHooks";
65
+ /**
66
+ * Recognize the per-type signature record react-refresh stores via
67
+ * `setSignature(type, key, forceReset, getCustomHooks)` — the value side of
68
+ * `allSignaturesByType`, shaped `{forceReset, ownKey, fullKey, getCustomHooks}`.
69
+ */
70
+ export declare function isReactRefreshSignatureShape(propNames: Iterable<string>): boolean;
71
+ /**
72
+ * Recognize the parent object SHAPE of an MCP/devtools tool manifest entry.
73
+ *
74
+ * The bridge's tool definitions carry long `.description` strings — one per tool
75
+ * — and a per-load intern pool would happily "save" them. The shape is
76
+ * distinctive enough to match directly, and matching the shape (rather than the
77
+ * description text) keeps app strings that merely have a `description` property
78
+ * out of it.
79
+ */
80
+ export declare function isHarnessToolManifestShape(propNames: ReadonlyArray<string>): boolean;
81
+ /**
82
+ * Classify a class NAME as a known measurement artifact, or null when it is a
83
+ * genuine leak candidate.
84
+ */
85
+ export declare function classifyArtifact(name: string): ArtifactKind | null;
86
+ //# sourceMappingURL=artifact-classes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-classes.d.ts","sourceRoot":"","sources":["../src/artifact-classes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,YAAY,GACpB,QAAQ,GACR,IAAI,GACJ,aAAa,GACb,UAAU,GACV,aAAa,GACb,eAAe,CAAC;AAwGpB,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAExD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAEvD;AAED;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,WAAW,CAAC;AAkE9D;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,GACZ;IAAC,IAAI,EAAE,uBAAuB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,GAAG,IAAI,CAKtD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAElE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iCAAiC,EAAE,WAAW,CAAC,MAAM,CAWhE,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,mBAAmB,CAAC;AASlE;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,GAC1B,OAAO,CAOT;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,GAC/B,OAAO,CAQT;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CASlE"}
@@ -0,0 +1,261 @@
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
+ /**
11
+ * V8 internal structures emitted while JIT-compiling and warming up code paths.
12
+ * Exercising NEW interactions during a hunt compiles new functions, so this
13
+ * whole family climbs "every step" without being an app leak.
14
+ *
15
+ * Note what is deliberately NOT here: `PropertyArray`, `DescriptorArray`,
16
+ * `(object elements)`, `(object properties)`, `Context`. Those grow with real
17
+ * application objects and suppressing them would hide genuine leaks.
18
+ */
19
+ const WARMUP_CLASS_NAMES = new Set([
20
+ 'InstructionStream',
21
+ 'Code',
22
+ 'CodeDataContainer',
23
+ 'CodeWrapper',
24
+ 'BytecodeArray',
25
+ 'BytecodeWrapper',
26
+ 'FeedbackVector',
27
+ 'FeedbackMetadata',
28
+ 'FeedbackCell',
29
+ 'ClosureFeedbackCellArray',
30
+ 'ScopeInfo',
31
+ 'SharedFunctionInfo',
32
+ 'SharedFunctionInfoWrapper',
33
+ 'UncompiledDataWithoutPreparseData',
34
+ 'UncompiledDataWithPreparseData',
35
+ 'InterpreterData',
36
+ 'TrustedByteArray',
37
+ 'ProtectedFixedArray',
38
+ 'TrustedWeakFixedArray',
39
+ 'WeakArrayList',
40
+ 'LoadHandler',
41
+ 'StoreHandler',
42
+ 'AllocationSite',
43
+ 'ConstantPool',
44
+ '(constant pool)',
45
+ 'ObjectBoilerplateDescription',
46
+ ]);
47
+ /**
48
+ * Blink accessibility caches, materialized by CDP-driven automation.
49
+ */
50
+ const AX_NAME_RE = /AXObjectCache|AXNodeObject|AXDirtyObject|AXComputedObject|blink::AX/;
51
+ /**
52
+ * The attached inspector's network log. Every request the page makes while CDP
53
+ * is attached is retained by `blink::InspectorNetworkAgent` for the lifetime of
54
+ * the session, so on a dev build that polls (hot reload, long-poll transports)
55
+ * this climbs forever. Retained by the DevToolsSession, not by the app.
56
+ */
57
+ const CDP_NETWORK_NAME_RE = /NetworkResourcesData|XHRReplayData|InspectorNetworkAgent|PerformanceResourceTiming|^URI$/;
58
+ /**
59
+ * The inspector's performance timeline. Long-task/layout-shift/script-timing
60
+ * entries accumulate only because something is observing them.
61
+ */
62
+ const CDP_PERF_NAME_RE = /PerformanceLongTaskTiming|PerformanceLongAnimationFrameTiming|PerformanceScriptTiming|TaskAttributionTiming|ScriptTimingInfo|^LayoutShift$|LayoutShiftAttribution/;
63
+ /**
64
+ * Console message storage held by the inspector. Distinct from
65
+ * `dev_artifacts`' console detection, which works on retainer edges: this
66
+ * catches the native message objects by class name.
67
+ */
68
+ const CDP_CONSOLE_NAME_RE = /ConsoleMessage/;
69
+ /**
70
+ * Captured error stacks. `StackFrameInfo` / `ErrorStackData` balloon when
71
+ * something constructs `Error`s at high frequency — most often React's DEV-only
72
+ * `_debugStack` owner stacks (see the `reactDebugStack` detector in
73
+ * `dev-artifacts`), or dev-build logging that captures a stack per record.
74
+ *
75
+ * Flagged as `stack-capture` rather than asserted dev-only: a production build
76
+ * can legitimately grow these, so the annotation points at the likely cause
77
+ * instead of dismissing the row.
78
+ */
79
+ const STACK_CAPTURE_NAME_RE = /StackFrameInfo|ErrorStackData/;
80
+ const KIND_LABEL = {
81
+ warmup: '⚙ JIT/compile warmup (not a leak)',
82
+ ax: '♿ a11y/CDP cache (automation artifact)',
83
+ 'cdp-network': '🔌 CDP network-inspector retention (artifact)',
84
+ 'cdp-perf': '🔌 CDP performance-timeline retention (artifact)',
85
+ 'cdp-console': '🔌 CDP console retention (artifact)',
86
+ 'stack-capture': '🧵 captured Error stacks (often React DEV _debugStack)',
87
+ };
88
+ const KIND_NOTE = {
89
+ warmup: '⚙️ V8 **compilation-warmup** structures (`Code`, `BytecodeArray`, `FeedbackVector`, `ScopeInfo`, `InstructionStream`, …) are growing. Exercising new code paths during a hunt JIT-compiles them, so they climb every step without being an app leak.',
90
+ ax: '♿ Blink **accessibility caches** (`AXObjectCacheImpl` / `AXNodeObject` / `AXDirtyObject`) are growing. These are inflated by CDP-driven automation building the a11y tree, and they co-retain detached DOM, so retainer traces can route through them and mislead.',
91
+ 'cdp-network': '🔌 The attached inspector is retaining the **network log** (`blink::NetworkResourcesData` / `XHRReplayData` / `PerformanceResourceTiming`). Every request made while CDP is attached is held by `blink::DevToolsSession → InspectorNetworkAgent` for the session, so a dev build that polls (hot reload, long-poll transports) grows this forever. Not app memory.',
92
+ 'cdp-perf': '🔌 The attached inspector is retaining the **performance timeline** (long-task / layout-shift / script-timing entries). These accumulate because something is observing them, not because the app leaks.',
93
+ 'cdp-console': '🔌 The attached inspector is retaining **console messages**. Cross-check with `memlab_dev_artifacts`, which also detects console retention by retainer edge.',
94
+ 'stack-capture': '🧵 **Captured Error stacks** (`StackFrameInfo` / `ErrorStackData`) are growing. The usual cause is React DEV `_debugStack` owner stacks or dev-build logging that captures a stack per record — both dev-build-only. `memlab_dev_artifacts` reports the `React DEV owner stack` category when that is the source.',
95
+ };
96
+ export function artifactLabel(kind) {
97
+ return KIND_LABEL[kind];
98
+ }
99
+ export function artifactNote(kind) {
100
+ return KIND_NOTE[kind];
101
+ }
102
+ /**
103
+ * Content signatures of strings that do NOT ship: the CDP-driven bridge the
104
+ * agent injects to observe the page (browser MCP plugin, browser-tools
105
+ * extension, Puppeteer helpers), and DEV-build-only framework machinery.
106
+ *
107
+ * Why this needs its own classifier, separate from `classifyArtifact`: these are
108
+ * matched on string CONTENT, not on a class name, and they are not reachable
109
+ * from a dev *global*, so neither the class-name registry above nor
110
+ * `dev_artifacts`' root scan sees them.
111
+ *
112
+ * Why it matters: on a measured WA Web round the injected bridge bundle appeared
113
+ * as 64 copies of one 235.6 KB string — 14.7 MB total, the single largest entry
114
+ * in `duplicated_strings` and the single largest "opportunity" in
115
+ * `intern_opportunities`. Interning it would save the application nothing,
116
+ * because none of it ships. Reporting it as a win is worse than not reporting it
117
+ * at all: it sends a fix author after the test rig. The React DEV entries below
118
+ * were the same story a round later: 4,529 `_debugStack` Error stacks, 3.0 MB,
119
+ * none of which exist in a production build.
120
+ *
121
+ * Every pattern here has to be specific enough that application source cannot
122
+ * match it — a false "this doesn't ship" hides a real win, which is the more
123
+ * expensive direction to be wrong in for THIS classifier (the opposite of
124
+ * `classifyArtifact`, where a false artifact hides a real leak).
125
+ */
126
+ const NON_PRODUCTION_STRING_SIGNATURES = [
127
+ {
128
+ // The UMD/CommonJS prologue every bundled bridge is wrapped in. Anchored at
129
+ // the start and required to reach `commonjsGlobal` within the prologue, so
130
+ // ordinary application source strings do not match.
131
+ re: /^\(function\s*\(exports\)\s*\{[\s\S]{0,400}commonjsGlobal/,
132
+ kind: 'harness',
133
+ what: 'injected CommonJS bundle (automation/devtools bridge)',
134
+ },
135
+ {
136
+ re: /^\s*at (?:Object\.)?__PUPPETEER|puppeteer_evaluation_script/,
137
+ kind: 'harness',
138
+ what: 'Puppeteer evaluation frame',
139
+ },
140
+ {
141
+ // react-dom DEV names the frames it inserts into owner stacks
142
+ // `react-stack-top-frame` / `react-stack-bottom-frame`, in hyphenated and
143
+ // underscored spellings depending on the build. BOTH ends must be matched:
144
+ // measured on one 2.5M-node capture, `react-stack-top-frame` appears 56
145
+ // times and `react_stack_bottom_frame` twice, so a bottom-only pattern
146
+ // misses the dominant form and classifies most DEV owner stacks as
147
+ // production. The hyphenated spelling cannot be a JS identifier, so it only
148
+ // ever appears inside a captured stack string.
149
+ re: /react[-_]stack[-_](?:top|bottom)[-_]frame/,
150
+ kind: 'dev-build',
151
+ what: 'React DEV owner stack (_debugStack) — not captured in production',
152
+ },
153
+ {
154
+ // A compiled DEV module's Fast Refresh epilogue. Requires the call form, so
155
+ // a string that merely mentions the identifier does not match.
156
+ re: /\$RefreshReg\$\(|\$RefreshSig\$\(/,
157
+ kind: 'dev-build',
158
+ what: 'React Fast Refresh instrumentation in compiled source (DEV bundle only)',
159
+ },
160
+ ];
161
+ /**
162
+ * Classify a string VALUE as non-production (harness-injected or DEV-build
163
+ * only), or null when it is app content that really does ship.
164
+ */
165
+ export function classifyNonProductionString(value) {
166
+ for (const { re, kind, what } of NON_PRODUCTION_STRING_SIGNATURES) {
167
+ if (re.test(value))
168
+ return { kind, what };
169
+ }
170
+ return null;
171
+ }
172
+ /**
173
+ * Back-compatible wrapper returning just the description. Prefer
174
+ * {@link classifyNonProductionString} when the caller can act on the kind.
175
+ */
176
+ export function classifyHarnessString(value) {
177
+ return classifyNonProductionString(value)?.what ?? null;
178
+ }
179
+ /**
180
+ * React Fast Refresh module-scope registries, by the edge name that binds each
181
+ * one. These live in the refresh runtime's closure and are reachable only
182
+ * through compiled-code constant pools, so a retainer-root scan does not find
183
+ * them and they classify as `production` unless matched by name here. See
184
+ * `tools/dev-artifacts` for the measured cost of missing them.
185
+ */
186
+ export const REACT_REFRESH_REGISTRY_EDGE_NAMES = new Set([
187
+ 'allFamiliesByID',
188
+ 'allFamiliesByType',
189
+ 'allSignaturesByType',
190
+ 'updatedFamiliesByType',
191
+ 'pendingUpdates',
192
+ 'helpersByRendererID',
193
+ 'helpersByRoot',
194
+ 'mountedRoots',
195
+ 'failedRoots',
196
+ 'rootElements',
197
+ ]);
198
+ /**
199
+ * The rarest property of the react-refresh signature record. Callers gate on
200
+ * this before confirming the full shape, so a scan stays one name compare per
201
+ * edge on everything else.
202
+ */
203
+ export const REACT_REFRESH_SIGNATURE_GATE_PROP = 'getCustomHooks';
204
+ const REACT_REFRESH_SIGNATURE_PROPS = [
205
+ 'forceReset',
206
+ 'ownKey',
207
+ 'fullKey',
208
+ 'getCustomHooks',
209
+ ];
210
+ /**
211
+ * Recognize the per-type signature record react-refresh stores via
212
+ * `setSignature(type, key, forceReset, getCustomHooks)` — the value side of
213
+ * `allSignaturesByType`, shaped `{forceReset, ownKey, fullKey, getCustomHooks}`.
214
+ */
215
+ export function isReactRefreshSignatureShape(propNames) {
216
+ const seen = new Set();
217
+ for (const name of propNames) {
218
+ if (REACT_REFRESH_SIGNATURE_PROPS.includes(name))
219
+ seen.add(name);
220
+ if (seen.size === REACT_REFRESH_SIGNATURE_PROPS.length)
221
+ return true;
222
+ }
223
+ return false;
224
+ }
225
+ /**
226
+ * Recognize the parent object SHAPE of an MCP/devtools tool manifest entry.
227
+ *
228
+ * The bridge's tool definitions carry long `.description` strings — one per tool
229
+ * — and a per-load intern pool would happily "save" them. The shape is
230
+ * distinctive enough to match directly, and matching the shape (rather than the
231
+ * description text) keeps app strings that merely have a `description` property
232
+ * out of it.
233
+ */
234
+ export function isHarnessToolManifestShape(propNames) {
235
+ const props = new Set(propNames);
236
+ return (props.has('description') &&
237
+ props.has('inputSchema') &&
238
+ (props.has('call') || props.has('handler')) &&
239
+ props.has('name'));
240
+ }
241
+ /**
242
+ * Classify a class NAME as a known measurement artifact, or null when it is a
243
+ * genuine leak candidate.
244
+ */
245
+ export function classifyArtifact(name) {
246
+ const bare = name.replace(/^system \/ /, '');
247
+ if (WARMUP_CLASS_NAMES.has(bare))
248
+ return 'warmup';
249
+ if (AX_NAME_RE.test(name))
250
+ return 'ax';
251
+ if (CDP_NETWORK_NAME_RE.test(bare))
252
+ return 'cdp-network';
253
+ if (CDP_PERF_NAME_RE.test(bare))
254
+ return 'cdp-perf';
255
+ if (CDP_CONSOLE_NAME_RE.test(bare))
256
+ return 'cdp-console';
257
+ if (STACK_CAPTURE_NAME_RE.test(bare))
258
+ return 'stack-capture';
259
+ return null;
260
+ }
261
+ //# sourceMappingURL=artifact-classes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-classes.js","sourceRoot":"","sources":["../src/artifact-classes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
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 { SnapshotEnv } from './heap-state.js';
11
+ /**
12
+ * Was this snapshot captured with numeric-value capture on?
13
+ *
14
+ * Background: `heap number` is a perennial top grower, and the standing advice
15
+ * was "that is probably a capture artifact — check whether you captured with
16
+ * numeric values on". That advice pushed a decision onto the caller that the
17
+ * caller usually cannot answer (the snapshot may be days old, or captured by
18
+ * someone else), and it rested on a mechanism that was never measured.
19
+ *
20
+ * It was measured for this change, with matched pairs — the same program/page,
21
+ * two snapshots differing ONLY in the `captureNumericValue` CDP flag:
22
+ *
23
+ * - **Node.js** (`inspector` → `HeapProfiler.takeHeapSnapshot`): the flag adds
24
+ * `smi number` nodes and nothing else. Off: 10,100 number nodes, zero of them
25
+ * `smi number`. On: 10,390, of which 290 `smi number`. `heap number` was
26
+ * IDENTICAL at 10,100 in both. Smis are immediate values, not heap objects,
27
+ * so they only become graph nodes when the flag asks V8 to materialize them —
28
+ * which makes their presence a sound detector here.
29
+ * - **Chrome**: no detectable difference at all. On a page holding 20,000
30
+ * objects each with a double and a Smi field, on and off produced the same
31
+ * populations to the node: 40,026 `heap number`, 20,000 `smi number`, 1,063
32
+ * `int`. Chrome emits `smi number` either way, so the Node detector does not
33
+ * transfer, and no other field varies.
34
+ *
35
+ * Neither environment ever encodes the numeric VALUE in the node name (0
36
+ * value-named number nodes across all four snapshots), so name-based detection
37
+ * — the approach a previous round tried and rejected — cannot work in principle.
38
+ *
39
+ * Two consequences, both of which change what the tools should say:
40
+ * 1. For a BROWSER snapshot the question is not merely unanswerable, it is
41
+ * moot: the flag changes nothing, so `heap number` growth in a browser
42
+ * capture is never a numeric-capture artifact and must be investigated as
43
+ * real.
44
+ * 2. The old claim that the mode "emits one node per distinct number and ~3x
45
+ * inflates the graph" is not what was measured in either environment.
46
+ */
47
+ export type NumericCaptureMode = 'on' | 'off' | 'not-applicable' | 'unknown';
48
+ export interface NumericCaptureVerdict {
49
+ mode: NumericCaptureMode;
50
+ /** One sentence stating the answer, for direct inclusion in a tool result. */
51
+ note: string;
52
+ }
53
+ /**
54
+ * @param env which runtime produced the snapshot
55
+ * @param hasSmiNumberNodes whether any `smi number` node is present
56
+ */
57
+ export declare function classifyNumericCapture(env: SnapshotEnv, hasSmiNumberNodes: boolean): NumericCaptureVerdict;
58
+ /** Class-histogram key for the marker node type, as `type::name`. */
59
+ export declare const SMI_NUMBER_CLASS_KEY = "number::smi number";
60
+ //# sourceMappingURL=capture-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-mode.d.ts","sourceRoot":"","sources":["../src/capture-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,iBAAiB,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,KAAK,GAAG,gBAAgB,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,kBAAkB,CAAC;IACzB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,WAAW,EAChB,iBAAiB,EAAE,OAAO,GACzB,qBAAqB,CAsBvB;AAED,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,uBAAuB,CAAC"}
@@ -0,0 +1,39 @@
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
+ /**
11
+ * @param env which runtime produced the snapshot
12
+ * @param hasSmiNumberNodes whether any `smi number` node is present
13
+ */
14
+ export function classifyNumericCapture(env, hasSmiNumberNodes) {
15
+ if (env === 'browser') {
16
+ return {
17
+ mode: 'not-applicable',
18
+ note: 'This is a **browser** capture, where `capture_numeric_value` makes no difference to the snapshot: a matched pair taken with the flag on and off produced identical number-node populations (40,026 `heap number` / 20,000 `smi number` in both). So `heap number` growth here is **not** a numeric-capture artifact — treat it as real and trace it with `memlab_retainer_summary` on `heap number`.',
19
+ };
20
+ }
21
+ if (env === 'node') {
22
+ return hasSmiNumberNodes
23
+ ? {
24
+ mode: 'on',
25
+ note: 'This **Node.js** capture was taken with **numeric-value capture ON** — `smi number` nodes are present, and V8 only materializes Smis as graph nodes in that mode. `smi number` growth is therefore a capture artifact. `heap number` is emitted either way (a matched pair had an identical `heap number` count with the flag on and off), so `heap number` growth is still worth investigating.',
26
+ }
27
+ : {
28
+ mode: 'off',
29
+ note: 'This **Node.js** capture was taken with **numeric-value capture OFF** (no `smi number` nodes present). `heap number` nodes are therefore ordinary boxed doubles that V8 allocates anyway — this growth may be real, so investigate it rather than dismissing it.',
30
+ };
31
+ }
32
+ return {
33
+ mode: 'unknown',
34
+ note: 'The runtime that produced this snapshot could not be identified, so the numeric-capture mode cannot be stated. In browser captures the flag makes no difference; in Node.js captures it adds `smi number` nodes.',
35
+ };
36
+ }
37
+ /** Class-histogram key for the marker node type, as `type::name`. */
38
+ export const SMI_NUMBER_CLASS_KEY = 'number::smi number';
39
+ //# sourceMappingURL=capture-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture-mode.js","sourceRoot":"","sources":["../src/capture-mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgDH;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,GAAgB,EAChB,iBAA0B;IAE1B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,sYAAsY;SAC7Y,CAAC;IACJ,CAAC;IACD,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACnB,OAAO,iBAAiB;YACtB,CAAC,CAAC;gBACE,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,kYAAkY;aACzY;YACH,CAAC,CAAC;gBACE,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE,kQAAkQ;aACzQ,CAAC;IACR,CAAC;IACD,OAAO;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,kNAAkN;KACzN,CAAC;AACJ,CAAC;AAED,qEAAqE;AACrE,MAAM,CAAC,MAAM,oBAAoB,GAAG,oBAAoB,CAAC"}
@@ -0,0 +1,41 @@
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
+ /**
11
+ * Recognise an eval that is re-implementing a tool that already exists, and say
12
+ * so alongside the result.
13
+ *
14
+ * The discoverability problem this addresses is measured, not hypothetical: in
15
+ * one long session `memlab_eval_across`, `memlab_population_diff`,
16
+ * `memlab_event_registry`, `memlab_collection_trend` and `memlab_verify_fix`
17
+ * all existed, all would have saved work, and none was called — while the same
18
+ * questions were answered with hand-written evals, several times each. The
19
+ * operator had even read the warning about exactly this and still did not open
20
+ * the catalogue, because under time pressure writing the eval is the shorter
21
+ * path and nothing in that path mentions the alternative.
22
+ *
23
+ * So the hint is attached to the RESULT of the call that made the mistake,
24
+ * which is the one moment the caller is guaranteed to read. Two rules keep it
25
+ * from becoming noise:
26
+ *
27
+ * - **Never suppress or alter the result.** The eval ran; the hint is a
28
+ * footnote. A hint that blocked or replaced output would be worse than the
29
+ * duplication it is trying to prevent.
30
+ * - **Match on structure, not vocabulary.** A pattern fires only when the code
31
+ * shows the SHAPE of the built-in's job (a `{callback, context}` census, a
32
+ * per-class count keyed by snapshot, a detached-node distribution), not
33
+ * merely because it mentions a word.
34
+ */
35
+ export interface EvalHint {
36
+ tool: string;
37
+ why: string;
38
+ }
39
+ export declare function hintsForEval(code: string): EvalHint[];
40
+ export declare function formatEvalHints(hints: EvalHint[]): string | null;
41
+ //# sourceMappingURL=eval-hints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-hints.d.ts","sourceRoot":"","sources":["../src/eval-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAkGD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CASrD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,GAAG,IAAI,CAKhE"}
@@ -0,0 +1,115 @@
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
+ const RULES = [
11
+ {
12
+ tool: 'memlab_event_registry',
13
+ why: 'counts `{callback, context}` listener records by event and host directly',
14
+ // `callback` and `context` are two of the most common identifiers in
15
+ // JavaScript, so matching them alone fires on evals that have nothing to do
16
+ // with listeners. Require the SHAPE as well: both read as properties off
17
+ // the same record, and the eval is accumulating or iterating over them.
18
+ all: [
19
+ /[.[]['"]?callback\b|\bcallback\s*:/,
20
+ /[.[]['"]?context\b|\bcontext\s*:/,
21
+ /&&|\+\+|\+= ?1|\|\| ?0\) ?\+ ?1|\?\? ?0\) ?\+ ?1|\.push\(|\bfor\b/,
22
+ ],
23
+ // Already going through the census tool, or bucketing something else.
24
+ none: [/memlab_event_registry/],
25
+ },
26
+ {
27
+ tool: 'memlab_detached_dom',
28
+ why: 'reports the detached-node population and its per-class distribution, using the same pinned/GC-eligible split the other tools use',
29
+ all: [/is_detached|isRealDetached|Detached </],
30
+ none: [/memlab_detached_dom/],
31
+ },
32
+ {
33
+ tool: 'memlab_census_diff',
34
+ why: 'takes the detached and listener census on BOTH rungs and diffs them per class in one call — no manual map-building or unload/reload cycle',
35
+ all: [
36
+ /is_detached|isRealDetached|Detached </,
37
+ /\bbaseline\b|\bbefore\b|\bprev\b/,
38
+ ],
39
+ none: [/memlab_census_diff/],
40
+ },
41
+ {
42
+ tool: 'memlab_class_histogram',
43
+ why: 'produces the per-class count/size table without a hand-written walk',
44
+ // Deliberately not keyed to the identifier `node`: the callback parameter
45
+ // is as often `n`, and requiring the long spelling made the rule silently
46
+ // never fire on the shape it exists to catch.
47
+ all: [
48
+ /snapshot\.nodes\.forEach|for\s*\(\s*const\s+\w+\s+of\s+snapshot\.nodes/,
49
+ /\.name\b/,
50
+ /\+\+|\+= ?1|\|\| ?0\) ?\+ ?1|\?\? ?0\) ?\+ ?1/,
51
+ ],
52
+ none: [/memlab_class_histogram|helpers\.classCounts/],
53
+ },
54
+ {
55
+ tool: 'memlab_ladder_probe',
56
+ why: 'runs ONE numeric probe across an ordered ladder and returns the series, the per-cycle rate and r² — loading one rung at a time, so it works on captures too large to hold simultaneously',
57
+ all: [/helpers\.(save|load)\(|__rung|perRung|per_rung/],
58
+ none: [/memlab_ladder_probe/],
59
+ },
60
+ {
61
+ tool: 'memlab_duplicate_objects',
62
+ why: 'is a ready-made dedup report over object content signatures',
63
+ all: [/shapeSignature|objectContentSignature/, /\bMap\b|\bSet\b/],
64
+ none: [/memlab_duplicate_objects/],
65
+ },
66
+ {
67
+ // One canonical tool name per hint. The pair used to be crammed into this
68
+ // single field, which rendered as one backticked identifier containing a
69
+ // slash and spaces — not a name any caller or renderer can resolve. The
70
+ // sibling tool goes in `why`, as prose, where it belongs.
71
+ tool: 'memlab_map_entries',
72
+ why: 'enumerates collection entries without the backing-store walk (see `memlab_weakmap_entries` for WeakMaps)',
73
+ all: [/table|backing/i, /\bMap\b|\bWeakMap\b/],
74
+ none: [
75
+ /helpers\.mapEntries|helpers\.weakmapEntries/,
76
+ /memlab_map_entries|memlab_weakmap_entries/,
77
+ ],
78
+ },
79
+ {
80
+ tool: 'memlab_retainer_trace',
81
+ why: 'walks retainer paths with framework filtering and path collapsing already applied',
82
+ all: [
83
+ /\.referrers\b/,
84
+ /while\s*\(|for\s*\(/,
85
+ /pathEdge|dominatorNode|\.referrers\[0\]/,
86
+ ],
87
+ none: [/memlab_retainer_trace|helpers\.pathBetween/],
88
+ },
89
+ ];
90
+ /**
91
+ * At most this many hints per call. Beyond two the footnote stops being a
92
+ * pointer and starts being a second result the caller has to read.
93
+ */
94
+ const MAX_HINTS = 2;
95
+ export function hintsForEval(code) {
96
+ const hints = [];
97
+ for (const rule of RULES) {
98
+ if (hints.length >= MAX_HINTS)
99
+ break;
100
+ if (rule.none?.some(re => re.test(code)))
101
+ continue;
102
+ if (!rule.all.every(re => re.test(code)))
103
+ continue;
104
+ hints.push({ tool: rule.tool, why: rule.why });
105
+ }
106
+ return hints;
107
+ }
108
+ export function formatEvalHints(hints) {
109
+ if (hints.length === 0)
110
+ return null;
111
+ return hints
112
+ .map(h => `note: \`${h.tool}\` does this directly — it ${h.why}.`)
113
+ .join('\n');
114
+ }
115
+ //# sourceMappingURL=eval-hints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval-hints.js","sourceRoot":"","sources":["../src/eval-hints.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"guardrail.d.ts","sourceRoot":"","sources":["../src/guardrail.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAYvE;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2ChE"}
1
+ {"version":3,"file":"guardrail.d.ts","sourceRoot":"","sources":["../src/guardrail.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAavE;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwDhE"}