@memlab/mcp-server 2.52.0 → 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 (277) hide show
  1. package/README.md +22 -2
  2. package/dist/anonymized-snapshot.d.ts +75 -0
  3. package/dist/anonymized-snapshot.d.ts.map +1 -0
  4. package/dist/anonymized-snapshot.js +101 -0
  5. package/dist/anonymized-snapshot.js.map +1 -0
  6. package/dist/eval-hints.d.ts +41 -0
  7. package/dist/eval-hints.d.ts.map +1 -0
  8. package/dist/eval-hints.js +115 -0
  9. package/dist/eval-hints.js.map +1 -0
  10. package/dist/heap-budget.d.ts +32 -0
  11. package/dist/heap-budget.d.ts.map +1 -0
  12. package/dist/heap-budget.js +90 -0
  13. package/dist/heap-budget.js.map +1 -0
  14. package/dist/heap-shapes.d.ts +148 -0
  15. package/dist/heap-shapes.d.ts.map +1 -0
  16. package/dist/heap-shapes.js +193 -0
  17. package/dist/heap-shapes.js.map +1 -0
  18. package/dist/heap-state.d.ts +20 -0
  19. package/dist/heap-state.d.ts.map +1 -1
  20. package/dist/heap-state.js +8 -1
  21. package/dist/heap-state.js.map +1 -1
  22. package/dist/index.js +64 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/react-shapes.d.ts +42 -0
  25. package/dist/react-shapes.d.ts.map +1 -0
  26. package/dist/react-shapes.js +149 -0
  27. package/dist/react-shapes.js.map +1 -0
  28. package/dist/server-version.d.ts +19 -0
  29. package/dist/server-version.d.ts.map +1 -0
  30. package/dist/server-version.js +19 -0
  31. package/dist/server-version.js.map +1 -0
  32. package/dist/snapshot-borrow.d.ts +67 -0
  33. package/dist/snapshot-borrow.d.ts.map +1 -0
  34. package/dist/snapshot-borrow.js +113 -0
  35. package/dist/snapshot-borrow.js.map +1 -0
  36. package/dist/string-index.d.ts.map +1 -1
  37. package/dist/string-index.js +8 -0
  38. package/dist/string-index.js.map +1 -1
  39. package/dist/tools/analyze-run.d.ts.map +1 -1
  40. package/dist/tools/analyze-run.js +79 -18
  41. package/dist/tools/analyze-run.js.map +1 -1
  42. package/dist/tools/anonymize-snapshot.d.ts +12 -0
  43. package/dist/tools/anonymize-snapshot.d.ts.map +1 -0
  44. package/dist/tools/anonymize-snapshot.js +159 -0
  45. package/dist/tools/anonymize-snapshot.js.map +1 -0
  46. package/dist/tools/app-config.d.ts +12 -0
  47. package/dist/tools/app-config.d.ts.map +1 -0
  48. package/dist/tools/app-config.js +217 -0
  49. package/dist/tools/app-config.js.map +1 -0
  50. package/dist/tools/app-heap.d.ts +18 -0
  51. package/dist/tools/app-heap.d.ts.map +1 -1
  52. package/dist/tools/app-heap.js +12 -46
  53. package/dist/tools/app-heap.js.map +1 -1
  54. package/dist/tools/artifact-budget.d.ts +12 -0
  55. package/dist/tools/artifact-budget.d.ts.map +1 -0
  56. package/dist/tools/artifact-budget.js +219 -0
  57. package/dist/tools/artifact-budget.js.map +1 -0
  58. package/dist/tools/async-census.d.ts +12 -0
  59. package/dist/tools/async-census.d.ts.map +1 -0
  60. package/dist/tools/async-census.js +243 -0
  61. package/dist/tools/async-census.js.map +1 -0
  62. package/dist/tools/auto-investigate.d.ts.map +1 -1
  63. package/dist/tools/auto-investigate.js +54 -5
  64. package/dist/tools/auto-investigate.js.map +1 -1
  65. package/dist/tools/batch.d.ts.map +1 -1
  66. package/dist/tools/batch.js +33 -5
  67. package/dist/tools/batch.js.map +1 -1
  68. package/dist/tools/cache-analysis.d.ts +15 -0
  69. package/dist/tools/cache-analysis.d.ts.map +1 -1
  70. package/dist/tools/cache-analysis.js +85 -10
  71. package/dist/tools/cache-analysis.js.map +1 -1
  72. package/dist/tools/census-diff.d.ts +55 -0
  73. package/dist/tools/census-diff.d.ts.map +1 -0
  74. package/dist/tools/census-diff.js +228 -0
  75. package/dist/tools/census-diff.js.map +1 -0
  76. package/dist/tools/chain-walk.d.ts +12 -0
  77. package/dist/tools/chain-walk.d.ts.map +1 -0
  78. package/dist/tools/chain-walk.js +184 -0
  79. package/dist/tools/chain-walk.js.map +1 -0
  80. package/dist/tools/collection-diff.d.ts +44 -0
  81. package/dist/tools/collection-diff.d.ts.map +1 -0
  82. package/dist/tools/collection-diff.js +343 -0
  83. package/dist/tools/collection-diff.js.map +1 -0
  84. package/dist/tools/collection-trend.d.ts.map +1 -1
  85. package/dist/tools/collection-trend.js +2 -2
  86. package/dist/tools/collection-trend.js.map +1 -1
  87. package/dist/tools/detached-dom.d.ts +3 -0
  88. package/dist/tools/detached-dom.d.ts.map +1 -1
  89. package/dist/tools/detached-dom.js +78 -3
  90. package/dist/tools/detached-dom.js.map +1 -1
  91. package/dist/tools/dev-artifacts.d.ts.map +1 -1
  92. package/dist/tools/dev-artifacts.js +221 -3
  93. package/dist/tools/dev-artifacts.js.map +1 -1
  94. package/dist/tools/diff-snapshots.d.ts.map +1 -1
  95. package/dist/tools/diff-snapshots.js +18 -2
  96. package/dist/tools/diff-snapshots.js.map +1 -1
  97. package/dist/tools/dom-audit.d.ts +37 -0
  98. package/dist/tools/dom-audit.d.ts.map +1 -0
  99. package/dist/tools/dom-audit.js +247 -0
  100. package/dist/tools/dom-audit.js.map +1 -0
  101. package/dist/tools/duplicated-strings.d.ts.map +1 -1
  102. package/dist/tools/duplicated-strings.js +3 -2
  103. package/dist/tools/duplicated-strings.js.map +1 -1
  104. package/dist/tools/eval-across.d.ts +12 -0
  105. package/dist/tools/eval-across.d.ts.map +1 -0
  106. package/dist/tools/eval-across.js +135 -0
  107. package/dist/tools/eval-across.js.map +1 -0
  108. package/dist/tools/eval.d.ts +78 -0
  109. package/dist/tools/eval.d.ts.map +1 -1
  110. package/dist/tools/eval.js +2270 -701
  111. package/dist/tools/eval.js.map +1 -1
  112. package/dist/tools/event-listener-leaks.d.ts.map +1 -1
  113. package/dist/tools/event-listener-leaks.js +42 -17
  114. package/dist/tools/event-listener-leaks.js.map +1 -1
  115. package/dist/tools/event-registry.d.ts.map +1 -1
  116. package/dist/tools/event-registry.js +42 -8
  117. package/dist/tools/event-registry.js.map +1 -1
  118. package/dist/tools/explain-delta.d.ts.map +1 -1
  119. package/dist/tools/explain-delta.js +61 -10
  120. package/dist/tools/explain-delta.js.map +1 -1
  121. package/dist/tools/finding-index.d.ts +181 -0
  122. package/dist/tools/finding-index.d.ts.map +1 -1
  123. package/dist/tools/finding-index.js +343 -24
  124. package/dist/tools/finding-index.js.map +1 -1
  125. package/dist/tools/get-value.d.ts +16 -0
  126. package/dist/tools/get-value.d.ts.map +1 -1
  127. package/dist/tools/get-value.js +96 -2
  128. package/dist/tools/get-value.js.map +1 -1
  129. package/dist/tools/hypothesis.d.ts.map +1 -1
  130. package/dist/tools/hypothesis.js +117 -58
  131. package/dist/tools/hypothesis.js.map +1 -1
  132. package/dist/tools/id-space-audit.d.ts +12 -0
  133. package/dist/tools/id-space-audit.d.ts.map +1 -0
  134. package/dist/tools/id-space-audit.js +262 -0
  135. package/dist/tools/id-space-audit.js.map +1 -0
  136. package/dist/tools/identify.d.ts +12 -0
  137. package/dist/tools/identify.d.ts.map +1 -0
  138. package/dist/tools/identify.js +205 -0
  139. package/dist/tools/identify.js.map +1 -0
  140. package/dist/tools/identity-diff.d.ts +12 -0
  141. package/dist/tools/identity-diff.d.ts.map +1 -0
  142. package/dist/tools/identity-diff.js +188 -0
  143. package/dist/tools/identity-diff.js.map +1 -0
  144. package/dist/tools/intern-opportunities.d.ts.map +1 -1
  145. package/dist/tools/intern-opportunities.js +4 -3
  146. package/dist/tools/intern-opportunities.js.map +1 -1
  147. package/dist/tools/ladder-probe.d.ts +65 -0
  148. package/dist/tools/ladder-probe.d.ts.map +1 -0
  149. package/dist/tools/ladder-probe.js +445 -0
  150. package/dist/tools/ladder-probe.js.map +1 -0
  151. package/dist/tools/ladder.d.ts.map +1 -1
  152. package/dist/tools/ladder.js +5 -5
  153. package/dist/tools/ladder.js.map +1 -1
  154. package/dist/tools/leak-report.d.ts +23 -0
  155. package/dist/tools/leak-report.d.ts.map +1 -1
  156. package/dist/tools/leak-report.js +153 -11
  157. package/dist/tools/leak-report.js.map +1 -1
  158. package/dist/tools/load-snapshot.d.ts +11 -0
  159. package/dist/tools/load-snapshot.d.ts.map +1 -1
  160. package/dist/tools/load-snapshot.js +83 -10
  161. package/dist/tools/load-snapshot.js.map +1 -1
  162. package/dist/tools/metric.d.ts +13 -0
  163. package/dist/tools/metric.d.ts.map +1 -0
  164. package/dist/tools/metric.js +185 -0
  165. package/dist/tools/metric.js.map +1 -0
  166. package/dist/tools/module-attribution.d.ts +36 -0
  167. package/dist/tools/module-attribution.d.ts.map +1 -0
  168. package/dist/tools/module-attribution.js +235 -0
  169. package/dist/tools/module-attribution.js.map +1 -0
  170. package/dist/tools/next-measurement.d.ts +26 -0
  171. package/dist/tools/next-measurement.d.ts.map +1 -0
  172. package/dist/tools/next-measurement.js +149 -0
  173. package/dist/tools/next-measurement.js.map +1 -0
  174. package/dist/tools/object-cost-breakdown.d.ts.map +1 -1
  175. package/dist/tools/object-cost-breakdown.js +64 -0
  176. package/dist/tools/object-cost-breakdown.js.map +1 -1
  177. package/dist/tools/population-vs-owners.d.ts +12 -0
  178. package/dist/tools/population-vs-owners.d.ts.map +1 -0
  179. package/dist/tools/population-vs-owners.js +183 -0
  180. package/dist/tools/population-vs-owners.js.map +1 -0
  181. package/dist/tools/property-names.d.ts +29 -0
  182. package/dist/tools/property-names.d.ts.map +1 -0
  183. package/dist/tools/property-names.js +131 -0
  184. package/dist/tools/property-names.js.map +1 -0
  185. package/dist/tools/quick-diagnosis.d.ts.map +1 -1
  186. package/dist/tools/quick-diagnosis.js +7 -1
  187. package/dist/tools/quick-diagnosis.js.map +1 -1
  188. package/dist/tools/react-owners.d.ts +12 -0
  189. package/dist/tools/react-owners.d.ts.map +1 -0
  190. package/dist/tools/react-owners.js +167 -0
  191. package/dist/tools/react-owners.js.map +1 -0
  192. package/dist/tools/react-update-queues.d.ts +12 -0
  193. package/dist/tools/react-update-queues.d.ts.map +1 -0
  194. package/dist/tools/react-update-queues.js +173 -0
  195. package/dist/tools/react-update-queues.js.map +1 -0
  196. package/dist/tools/replicate.d.ts +49 -0
  197. package/dist/tools/replicate.d.ts.map +1 -0
  198. package/dist/tools/replicate.js +241 -0
  199. package/dist/tools/replicate.js.map +1 -0
  200. package/dist/tools/retainer-diff.d.ts +12 -0
  201. package/dist/tools/retainer-diff.d.ts.map +1 -0
  202. package/dist/tools/retainer-diff.js +168 -0
  203. package/dist/tools/retainer-diff.js.map +1 -0
  204. package/dist/tools/retainer-summary.d.ts +17 -0
  205. package/dist/tools/retainer-summary.d.ts.map +1 -1
  206. package/dist/tools/retainer-summary.js +85 -22
  207. package/dist/tools/retainer-summary.js.map +1 -1
  208. package/dist/tools/retainer-trace.d.ts.map +1 -1
  209. package/dist/tools/retainer-trace.js +11 -1
  210. package/dist/tools/retainer-trace.js.map +1 -1
  211. package/dist/tools/round-audit.d.ts +66 -0
  212. package/dist/tools/round-audit.d.ts.map +1 -0
  213. package/dist/tools/round-audit.js +258 -0
  214. package/dist/tools/round-audit.js.map +1 -0
  215. package/dist/tools/round-digest.d.ts +12 -0
  216. package/dist/tools/round-digest.d.ts.map +1 -0
  217. package/dist/tools/round-digest.js +190 -0
  218. package/dist/tools/round-digest.js.map +1 -0
  219. package/dist/tools/script-census.d.ts +12 -0
  220. package/dist/tools/script-census.d.ts.map +1 -0
  221. package/dist/tools/script-census.js +182 -0
  222. package/dist/tools/script-census.js.map +1 -0
  223. package/dist/tools/sequence-analysis.d.ts +4 -0
  224. package/dist/tools/sequence-analysis.d.ts.map +1 -1
  225. package/dist/tools/sequence-analysis.js +53 -9
  226. package/dist/tools/sequence-analysis.js.map +1 -1
  227. package/dist/tools/server-status.d.ts.map +1 -1
  228. package/dist/tools/server-status.js +4 -1
  229. package/dist/tools/server-status.js.map +1 -1
  230. package/dist/tools/settle-check.d.ts +12 -0
  231. package/dist/tools/settle-check.d.ts.map +1 -0
  232. package/dist/tools/settle-check.js +188 -0
  233. package/dist/tools/settle-check.js.map +1 -0
  234. package/dist/tools/sliced-strings.d.ts.map +1 -1
  235. package/dist/tools/sliced-strings.js +2 -1
  236. package/dist/tools/sliced-strings.js.map +1 -1
  237. package/dist/tools/snapshots.d.ts.map +1 -1
  238. package/dist/tools/snapshots.js +24 -6
  239. package/dist/tools/snapshots.js.map +1 -1
  240. package/dist/tools/sparse-elements.d.ts +12 -0
  241. package/dist/tools/sparse-elements.d.ts.map +1 -0
  242. package/dist/tools/sparse-elements.js +215 -0
  243. package/dist/tools/sparse-elements.js.map +1 -0
  244. package/dist/tools/stale-collections.d.ts +17 -0
  245. package/dist/tools/stale-collections.d.ts.map +1 -1
  246. package/dist/tools/stale-collections.js +28 -0
  247. package/dist/tools/stale-collections.js.map +1 -1
  248. package/dist/tools/string-patterns.d.ts.map +1 -1
  249. package/dist/tools/string-patterns.js +2 -1
  250. package/dist/tools/string-patterns.js.map +1 -1
  251. package/dist/tools/tools-index.d.ts.map +1 -1
  252. package/dist/tools/tools-index.js +155 -5
  253. package/dist/tools/tools-index.js.map +1 -1
  254. package/dist/tools/trace-all.d.ts +42 -0
  255. package/dist/tools/trace-all.d.ts.map +1 -0
  256. package/dist/tools/trace-all.js +263 -0
  257. package/dist/tools/trace-all.js.map +1 -0
  258. package/dist/tools/unit-cost.d.ts +12 -0
  259. package/dist/tools/unit-cost.d.ts.map +1 -0
  260. package/dist/tools/unit-cost.js +219 -0
  261. package/dist/tools/unit-cost.js.map +1 -0
  262. package/dist/tools/verify-fix.d.ts.map +1 -1
  263. package/dist/tools/verify-fix.js +11 -3
  264. package/dist/tools/verify-fix.js.map +1 -1
  265. package/dist/tools/weakref-census.d.ts +15 -0
  266. package/dist/tools/weakref-census.d.ts.map +1 -0
  267. package/dist/tools/weakref-census.js +147 -0
  268. package/dist/tools/weakref-census.js.map +1 -0
  269. package/dist/tools/what-if.d.ts +12 -0
  270. package/dist/tools/what-if.d.ts.map +1 -0
  271. package/dist/tools/what-if.js +285 -0
  272. package/dist/tools/what-if.js.map +1 -0
  273. package/dist/utils.d.ts +92 -2
  274. package/dist/utils.d.ts.map +1 -1
  275. package/dist/utils.js +172 -5
  276. package/dist/utils.js.map +1 -1
  277. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"app-heap.js","sourceRoot":"","sources":["../../src/tools/app-heap.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,WAAW,EAAE,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AAClE,OAAO,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,WAAW,EACX,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EACL,eAAe,EACf,+BAA+B,GAChC,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,GAAwB,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE1D,6EAA6E;AAC7E,qDAAqD;AACrD,MAAM,cAAc,GAClB,qMAAqM,CAAC;AAExM,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,gMAAgM;QAC9L,0XAA0X;QAC1X,2IAA2I,EAC7I;QACE,cAAc,EAAE,CAAC;aACd,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,OAAO,CAAC,IAAI,CAAC;aACb,QAAQ,CACP,sIAAsI,CACvI;KACJ,EACD,KAAK,EAAE,EAAC,cAAc,EAAC,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;YAEnC,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,OAAO,GACX,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;gBACpB,CAAC,CAAC,+BAA+B,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBACrD,CAAC,CAAC,IAAI,CAAC;YAEX,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,IAAI,MAAM,GAAG,CAAC,CAAC;YACf,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,IAAI,QAAQ,GAAG,CAAC,CAAC;YAEjB,MAAM,SAAS,GAAG,CAAC,IAAe,EAAW,EAAE,CAC7C,OAAO,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAEnD,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;gBAC5B,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC;oBAAE,OAAO;gBACzB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC5B,KAAK,IAAI,IAAI,CAAC;gBACd,mEAAmE;gBACnE,iDAAiD;gBACjD,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpB,OAAO,IAAI,IAAI,CAAC;oBAChB,OAAO;gBACT,CAAC;gBACD,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC9B,IAAI,IAAI,IAAI,CAAC;oBACb,OAAO;gBACT,CAAC;gBACD,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnC,MAAM,IAAI,IAAI,CAAC;oBACf,OAAO;gBACT,CAAC;gBACD,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;oBACxC,QAAQ,IAAI,IAAI,CAAC;oBACjB,OAAO;gBACT,CAAC;gBACD,GAAG,IAAI,IAAI,CAAC;gBACZ,QAAQ,EAAE,CAAC;YACb,CAAC,CAAC,CAAC;YAEH,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAChC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAEzD,MAAM,KAAK,GAAa;gBACtB,0BAA0B;gBAC1B,EAAE;gBACF,KAAK,WAAW,CAAC,GAAG,CAAC,OAAO,WAAW,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,oCAAoC,YAAY,CAAC,QAAQ,CAAC,QAAQ;oBAC3H,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxC,GAAG;gBACL,EAAE;aACH,CAAC;YAEF,IAAI,cAAc,EAAE,CAAC;gBACnB,KAAK,CAAC,IAAI,CACR,aAAa,CACX,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC,EAClD;oBACE;wBACE,KAAK;wBACL,WAAW,CAAC,GAAG,CAAC;wBAChB,GAAG,CAAC,GAAG,CAAC;wBACR,gCAAgC;qBACjC;oBACD;wBACE,sBAAsB;wBACtB,WAAW,CAAC,MAAM,CAAC;wBACnB,GAAG,CAAC,MAAM,CAAC;wBACX,4DAA4D;qBAC7D;oBACD;wBACE,iBAAiB;wBACjB,WAAW,CAAC,IAAI,CAAC;wBACjB,GAAG,CAAC,IAAI,CAAC;wBACT,oDAAoD;qBACrD;oBACD;wBACE,yBAAyB;wBACzB,WAAW,CAAC,OAAO,CAAC;wBACpB,GAAG,CAAC,OAAO,CAAC;wBACZ,wDAAwD;qBACzD;oBACD;wBACE,iBAAiB;wBACjB,WAAW,CAAC,QAAQ,CAAC;wBACrB,GAAG,CAAC,QAAQ,CAAC;wBACb,0BAA0B;qBAC3B;iBACF,EACD,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAChB,EACD,EAAE,CACH,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC;YAC3B,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;gBACtC,KAAK,CAAC,IAAI,CACR,UAAU,GAAG,CAAC,MAAM,CAAC,+OAA+O,CACrQ,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CACR,EAAE,EACF,+MAA+M,CAChN,CAAC;YACF,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"}
1
+ {"version":3,"file":"app-heap.js","sourceRoot":"","sources":["../../src/tools/app-heap.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,WAAW,EAAE,mBAAmB,EAAC,MAAM,kBAAkB,CAAC;AAClE,OAAO,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,WAAW,EACX,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,gMAAgM;QAC9L,0XAA0X;QAC1X,2IAA2I,EAC7I;QACE,cAAc,EAAE,CAAC;aACd,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,OAAO,CAAC,IAAI,CAAC;aACb,QAAQ,CACP,sIAAsI,CACvI;QACH,YAAY,EAAE,CAAC;aACZ,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,OAAO,CAAC,KAAK,CAAC;aACd,QAAQ,CACP,uPAAuP,CACxP;KACJ,EACD,KAAK,EAAE,EAAC,cAAc,EAAE,YAAY,EAAC,EAAE,EAAE;QACvC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,mBAAmB,EAAE,CAAC;YAEnC,MAAM,EAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAC,GAC3D,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAE9B,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAChC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAEzD,MAAM,KAAK,GAAa;gBACtB,0BAA0B;gBAC1B,EAAE;gBACF,KAAK,WAAW,CAAC,GAAG,CAAC,OAAO,WAAW,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,oCAAoC,YAAY,CAAC,QAAQ,CAAC,QAAQ;oBAC3H,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxC,GAAG;gBACL,EAAE;aACH,CAAC;YAEF,IAAI,cAAc,IAAI,CAAC,YAAY,EAAE,CAAC;gBACpC,KAAK,CAAC,IAAI,CACR,aAAa,CACX,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,CAAC,EAClD;oBACE;wBACE,KAAK;wBACL,WAAW,CAAC,GAAG,CAAC;wBAChB,GAAG,CAAC,GAAG,CAAC;wBACR,gCAAgC;qBACjC;oBACD;wBACE,sBAAsB;wBACtB,WAAW,CAAC,MAAM,CAAC;wBACnB,GAAG,CAAC,MAAM,CAAC;wBACX,4DAA4D;qBAC7D;oBACD;wBACE,iBAAiB;wBACjB,WAAW,CAAC,IAAI,CAAC;wBACjB,GAAG,CAAC,IAAI,CAAC;wBACT,oDAAoD;qBACrD;oBACD;wBACE,yBAAyB;wBACzB,WAAW,CAAC,OAAO,CAAC;wBACpB,GAAG,CAAC,OAAO,CAAC;wBACZ,wDAAwD;qBACzD;oBACD;wBACE,iBAAiB;wBACjB,WAAW,CAAC,QAAQ,CAAC;wBACrB,GAAG,CAAC,QAAQ,CAAC;wBACb,0BAA0B;qBAC3B;iBACF,EACD,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAChB,EACD,EAAE,CACH,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC;YAC3B,IAAI,KAAK,GAAG,CAAC,IAAI,MAAM,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;gBACtC,KAAK,CAAC,IAAI,CACR,UAAU,GAAG,CAAC,MAAM,CAAC,+OAA+O,CACrQ,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CACR,EAAE,EACF,+MAA+M,CAChN,CAAC;YACF,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 registerArtifactBudget(server: McpServer): void;
12
+ //# sourceMappingURL=artifact-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-budget.d.ts","sourceRoot":"","sources":["../../src/tools/artifact-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAkEvE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmO9D"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import { z } from 'zod';
11
+ import { artifactLabel } from '../artifact-classes.js';
12
+ import { computeHeapBudget, devFamilyBytes } from '../heap-budget.js';
13
+ import { armScanBudgetFor, resolveRungs, scaledTimeoutMs, withSnapshotAt, } from '../snapshot-borrow.js';
14
+ import { errorResult, formatBytes, formatNumber, markdownTable, pathsHeader, toolResult, } from '../utils.js';
15
+ /**
16
+ * One call for "how much of this heap is not the app, and did the app itself
17
+ * move?"
18
+ *
19
+ * The structural baseline currently requires composing three tools by hand —
20
+ * `app_heap` for the bundle/code/app split, `dev_artifacts` for the React DEV /
21
+ * Fast Refresh / console / a11y families, and `explain_delta --include-artifacts`
22
+ * for JIT warmup, which `dev_artifacts` deliberately does not count. Skipping any
23
+ * of the three produces a confident wrong answer rather than a gap: one measured
24
+ * round showed +67 MB of aggregate growth that was ~85-90% React DEV tooling
25
+ * with app memory flat, and the artifact share across a single sweep ranged from
26
+ * 2.0% to 18.5%. Reported without the composition, that round is a leak.
27
+ *
28
+ * The `app_delta` is therefore the headline, not the total delta: it is the only
29
+ * number in the report that a production build would also show.
30
+ */
31
+ const DEV_FAMILY_LABEL = {
32
+ console: 'DevTools console (CDP inspector)',
33
+ a11y: 'a11y / CDP automation cache',
34
+ devGlobal: 'dev/extension global',
35
+ reactDebugStack: 'React DEV owner stack (_debugStack)',
36
+ reactFastRefresh: 'React Fast Refresh registry ($RefreshSig$)',
37
+ harness: 'automation/devtools bridge (test harness)',
38
+ };
39
+ function budgetRows(budget) {
40
+ const pct = (n) => budget.total > 0 ? `${((n / budget.total) * 100).toFixed(1)}%` : '—';
41
+ return [
42
+ ['App', formatBytes(budget.app), pct(budget.app)],
43
+ ['Bundle / source text', formatBytes(budget.bundle), pct(budget.bundle)],
44
+ ['Code / bytecode', formatBytes(budget.code), pct(budget.code)],
45
+ [
46
+ 'Dev/automation-retained',
47
+ formatBytes(budget.devOnly),
48
+ pct(budget.devOnly),
49
+ ],
50
+ ['Known artifacts', formatBytes(budget.artifact), pct(budget.artifact)],
51
+ ];
52
+ }
53
+ function signed(n) {
54
+ return `${n >= 0 ? '+' : '-'}${formatBytes(Math.abs(n))}`;
55
+ }
56
+ export function registerArtifactBudget(server) {
57
+ server.tool('memlab_artifact_budget', 'ONE number for "how much of this heap is not the application", broken down by source — and, with a baseline, how much of the growth was the app rather than the tooling. ' +
58
+ 'Composes what otherwise takes three separate tools and a manual reconciliation: `memlab_app_heap` (bundle/code/app split), `memlab_dev_artifacts` (React DEV, Fast Refresh, CDP console, a11y) and the JIT-warmup family that `dev_artifacts` explicitly does NOT count.\n\n' +
59
+ 'Run it before quoting any growth number. Composing only two of the three produces a confident wrong answer, not a visible gap: one measured round showed +67 MB of aggregate growth that was ~85-90% React DEV tooling with app memory flat, and across a single sweep the artifact share ranged from 2.0% to 18.5%. ' +
60
+ 'With `baseline` set, **app_delta is the headline** — it is the only figure in the report that a production build would also show.', {
61
+ target: z
62
+ .string()
63
+ .describe('Snapshot to budget. Local path, manifold:// URL, or bare filename.'),
64
+ baseline: z
65
+ .string()
66
+ .optional()
67
+ .describe('Earlier rung. When given, every bucket is diffed and the APP delta is reported separately from the total — the difference between "the heap grew 67 MB" and "the app grew 4 MB".'),
68
+ max_file_size_mb: z
69
+ .number()
70
+ .optional()
71
+ .describe('Per-file size ceiling, matching memlab_load_snapshot.'),
72
+ }, async ({ target, baseline, max_file_size_mb }) => {
73
+ try {
74
+ const paths = baseline != null ? [baseline, target] : [target];
75
+ const { rungs, largestMB } = resolveRungs(paths, max_file_size_mb);
76
+ const targetRung = rungs[rungs.length - 1];
77
+ const baseRung = baseline != null ? rungs[0] : null;
78
+ // `computeHeapBudget` walks every node, so it is subject to the same
79
+ // 90s scan guardrail as any other full-heap tool. Scale it from the
80
+ // capture size rather than losing a large snapshot to the default.
81
+ const scanBudgetMs = scaledTimeoutMs(largestMB);
82
+ let baseBudget = null;
83
+ if (baseRung != null) {
84
+ armScanBudgetFor(scanBudgetMs);
85
+ baseBudget = await withSnapshotAt(baseRung.localPath, computeHeapBudget);
86
+ }
87
+ armScanBudgetFor(scanBudgetMs);
88
+ const budget = await withSnapshotAt(targetRung.localPath, computeHeapBudget);
89
+ const nonApp = budget.total - budget.app;
90
+ const nonAppPct = budget.total > 0 ? (nonApp / budget.total) * 100 : 0;
91
+ const lines = [];
92
+ lines.push('## Artifact budget');
93
+ lines.push('');
94
+ lines.push(`**${nonAppPct.toFixed(1)}% of \`${targetRung.label}\` is not the application** ` +
95
+ `(${formatBytes(nonApp)} of ${formatBytes(budget.total)}); ` +
96
+ `app-attributable is ${formatBytes(budget.app)} across ${formatNumber(budget.appNodes)} nodes.`);
97
+ lines.push('');
98
+ if (baseBudget != null && baseRung != null) {
99
+ const rows = [
100
+ ['App', 'app', baseBudget.app, budget.app],
101
+ [
102
+ 'Bundle / source text',
103
+ 'bundle',
104
+ baseBudget.bundle,
105
+ budget.bundle,
106
+ ],
107
+ ['Code / bytecode', 'code', baseBudget.code, budget.code],
108
+ [
109
+ 'Dev/automation-retained',
110
+ 'devOnly',
111
+ baseBudget.devOnly,
112
+ budget.devOnly,
113
+ ],
114
+ [
115
+ 'Known artifacts',
116
+ 'artifact',
117
+ baseBudget.artifact,
118
+ budget.artifact,
119
+ ],
120
+ ['TOTAL', 'total', baseBudget.total, budget.total],
121
+ ];
122
+ lines.push(markdownTable(['Bucket', baseRung.label, targetRung.label, 'Δ'], rows.map(([label, , b, t]) => [
123
+ label,
124
+ formatBytes(b),
125
+ formatBytes(t),
126
+ signed(t - b),
127
+ ]), new Set([1, 2, 3])));
128
+ lines.push('');
129
+ const appDelta = budget.app - baseBudget.app;
130
+ const totalDelta = budget.total - baseBudget.total;
131
+ // A share only means anything when the two move the SAME way. On a
132
+ // real Ads Manager ladder the total fell 46.8 MB while the app grew
133
+ // 6.3 MB — JIT code being discarded masking real app growth — and
134
+ // `appDelta/totalDelta` rendered that as "-14% of the -46.8 MB
135
+ // total", which reads like the app shrank. That inversion is the
136
+ // exact misreading this tool exists to prevent, so name it instead.
137
+ const sameDirection = (appDelta >= 0 && totalDelta > 0) ||
138
+ (appDelta <= 0 && totalDelta < 0);
139
+ // Same direction is not enough. A share above 100% is arithmetically
140
+ // fine and semantically nonsense: one measured round printed
141
+ // "app_delta: +2.6 MB — 693% of the +386.5 KB total" because
142
+ // code/bytecode shrank 8.5 MB underneath a growing app. "693% of the
143
+ // total" is not a share of anything, and a reader who takes it as one
144
+ // concludes the app is 7x the heap. Same cause as the inversion
145
+ // below — a bucket moving the other way — so it gets the same
146
+ // treatment rather than a number.
147
+ const shareIsMeaningful = sameDirection && Math.abs(appDelta) <= Math.abs(totalDelta);
148
+ const share = totalDelta !== 0 && shareIsMeaningful
149
+ ? ` — ${Math.abs((appDelta / totalDelta) * 100).toFixed(0)}% of the ${signed(totalDelta)} total`
150
+ : '';
151
+ lines.push(`**app_delta: ${signed(appDelta)}**${share}.`);
152
+ if (totalDelta !== 0 && sameDirection && !shareIsMeaningful) {
153
+ lines.push('');
154
+ lines.push(`> ⚠️ **The app moved MORE than the total**: the app ` +
155
+ `${appDelta >= 0 ? 'grew' : 'shrank'} ${formatBytes(Math.abs(appDelta))} while the total only ` +
156
+ `${totalDelta >= 0 ? 'grew' : 'fell'} ${formatBytes(Math.abs(totalDelta))}, so another bucket ` +
157
+ `moved the opposite way and no share of the total is meaningful. Quote ` +
158
+ `**${signed(appDelta)}** and read the per-bucket table for what offset it.`);
159
+ }
160
+ if (totalDelta !== 0 && !sameDirection) {
161
+ lines.push('');
162
+ lines.push(`> ⚠️ **The app and the total moved in OPPOSITE directions**: the app ` +
163
+ `${appDelta >= 0 ? 'GREW' : 'shrank'} ${formatBytes(Math.abs(appDelta))} while the total ` +
164
+ `${totalDelta >= 0 ? 'grew' : 'fell'} ${formatBytes(Math.abs(totalDelta))}. Reading the total here ` +
165
+ `would give exactly the wrong answer — quote **${signed(appDelta)}**.`);
166
+ }
167
+ if (totalDelta > 0 && appDelta / totalDelta < 0.25) {
168
+ lines.push('');
169
+ lines.push(`> ⚠️ **Most of this growth is not the app.** Quoting ${signed(totalDelta)} as the leak ` +
170
+ `would overstate it by ${formatBytes(totalDelta - appDelta)}. Report ${signed(appDelta)}.`);
171
+ }
172
+ }
173
+ else {
174
+ lines.push(markdownTable(['Bucket', 'Self size', '% of heap'], budgetRows(budget), new Set([1, 2])));
175
+ }
176
+ lines.push('');
177
+ const devFamilies = devFamilyBytes(budget);
178
+ lines.push('### Dev/automation, by family');
179
+ lines.push('');
180
+ if (devFamilies.length === 0) {
181
+ lines.push('No dev/automation roots found. On a dev build driven over CDP that is itself ' +
182
+ 'suspicious — it usually means the families this looks for are not present under ' +
183
+ 'the names it knows, not that the capture is clean. Cross-check `memlab_dev_artifacts`.');
184
+ }
185
+ else {
186
+ lines.push(markdownTable(['Family', 'Nodes', 'Self size'], devFamilies.map(f => [
187
+ DEV_FAMILY_LABEL[f.family] ?? f.family,
188
+ formatNumber(f.nodes),
189
+ formatBytes(f.selfBytes),
190
+ ]), new Set([1, 2])));
191
+ }
192
+ lines.push('');
193
+ lines.push('### Known-artifact families');
194
+ lines.push('');
195
+ const kinds = [...budget.artifactByKind.entries()].sort((a, b) => b[1] - a[1]);
196
+ if (kinds.length === 0) {
197
+ lines.push('None.');
198
+ }
199
+ else {
200
+ lines.push(markdownTable(['Family', 'Self size'], kinds.map(([kind, bytes]) => [
201
+ artifactLabel(kind),
202
+ formatBytes(bytes),
203
+ ]), new Set([1])));
204
+ lines.push('');
205
+ lines.push('_JIT warmup (`Code`/`BytecodeArray`/`FeedbackVector`/…) is counted here and NOT by ' +
206
+ '`memlab_dev_artifacts`. It climbs at every rung of any hunt that drives new interactions, ' +
207
+ 'because new code paths compile — which is why a warmup-heavy ladder reads as a linear leak._');
208
+ }
209
+ lines.push('');
210
+ lines.push('_Buckets are mutually exclusive self sizes and sum to the total; each node lands in the most ' +
211
+ 'specific bucket explaining why it is not app memory. Retained sizes overlap and would not sum._');
212
+ return toolResult(lines.join('\n'), pathsHeader(rungs.map(r => r.label)));
213
+ }
214
+ catch (e) {
215
+ return errorResult(e instanceof Error ? e : new Error(String(e)));
216
+ }
217
+ });
218
+ }
219
+ //# sourceMappingURL=artifact-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-budget.js","sourceRoot":"","sources":["../../src/tools/artifact-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AACtB,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAC,iBAAiB,EAAE,cAAc,EAAC,MAAM,mBAAmB,CAAC;AAEpE,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,WAAW,EACX,WAAW,EACX,YAAY,EACZ,aAAa,EACb,WAAW,EACX,UAAU,GACX,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,gBAAgB,GAA2B;IAC/C,OAAO,EAAE,kCAAkC;IAC3C,IAAI,EAAE,6BAA6B;IACnC,SAAS,EAAE,sBAAsB;IACjC,eAAe,EAAE,qCAAqC;IACtD,gBAAgB,EAAE,4CAA4C;IAC9D,OAAO,EAAE,2CAA2C;CACrD,CAAC;AAEF,SAAS,UAAU,CAAC,MAAkB;IACpC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAU,EAAE,CAChC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACvE,OAAO;QACL,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjD,CAAC,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxE,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/D;YACE,yBAAyB;YACzB,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC;YAC3B,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;SACpB;QACD,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;KACxE,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,CAAS;IACvB,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,2KAA2K;QACzK,8QAA8Q;QAC9Q,uTAAuT;QACvT,mIAAmI,EACrI;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,CACP,oEAAoE,CACrE;QACH,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,kLAAkL,CACnL;QACH,gBAAgB,EAAE,CAAC;aAChB,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,uDAAuD,CAAC;KACrE,EACD,KAAK,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAC,EAAE,EAAE;QAC7C,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC/D,MAAM,EAAC,KAAK,EAAE,SAAS,EAAC,GAAG,YAAY,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;YACjE,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC3C,MAAM,QAAQ,GAAG,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACpD,qEAAqE;YACrE,oEAAoE;YACpE,mEAAmE;YACnE,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;YAEhD,IAAI,UAAU,GAAG,IAAI,CAAC;YACtB,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;gBACrB,gBAAgB,CAAC,YAAY,CAAC,CAAC;gBAC/B,UAAU,GAAG,MAAM,cAAc,CAC/B,QAAQ,CAAC,SAAS,EAClB,iBAAiB,CAClB,CAAC;YACJ,CAAC;YACD,gBAAgB,CAAC,YAAY,CAAC,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,cAAc,CACjC,UAAU,CAAC,SAAS,EACpB,iBAAiB,CAClB,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC;YACzC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAEvE,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CACR,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,UAAU,CAAC,KAAK,8BAA8B;gBAC/E,IAAI,WAAW,CAAC,MAAM,CAAC,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK;gBAC5D,uBAAuB,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAClG,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,IAAI,UAAU,IAAI,IAAI,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;gBAC3C,MAAM,IAAI,GAAG;oBACX,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC;oBAC1C;wBACE,sBAAsB;wBACtB,QAAQ;wBACR,UAAU,CAAC,MAAM;wBACjB,MAAM,CAAC,MAAM;qBACd;oBACD,CAAC,iBAAiB,EAAE,MAAM,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;oBACzD;wBACE,yBAAyB;wBACzB,SAAS;wBACT,UAAU,CAAC,OAAO;wBAClB,MAAM,CAAC,OAAO;qBACf;oBACD;wBACE,iBAAiB;wBACjB,UAAU;wBACV,UAAU,CAAC,QAAQ;wBACnB,MAAM,CAAC,QAAQ;qBAChB;oBACD,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;iBACR,CAAC;gBAC7C,KAAK,CAAC,IAAI,CACR,aAAa,CACX,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,EACjD,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,AAAD,EAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;oBAC5B,KAAK;oBACL,WAAW,CAAC,CAAC,CAAC;oBACd,WAAW,CAAC,CAAC,CAAC;oBACd,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;iBACd,CAAC,EACF,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CACnB,CACF,CAAC;gBACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACf,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC;gBAC7C,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;gBACnD,mEAAmE;gBACnE,oEAAoE;gBACpE,kEAAkE;gBAClE,+DAA+D;gBAC/D,iEAAiE;gBACjE,oEAAoE;gBACpE,MAAM,aAAa,GACjB,CAAC,QAAQ,IAAI,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC;oBACjC,CAAC,QAAQ,IAAI,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC;gBACpC,qEAAqE;gBACrE,6DAA6D;gBAC7D,6DAA6D;gBAC7D,qEAAqE;gBACrE,sEAAsE;gBACtE,gEAAgE;gBAChE,8DAA8D;gBAC9D,kCAAkC;gBAClC,MAAM,iBAAiB,GACrB,aAAa,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBAC9D,MAAM,KAAK,GACT,UAAU,KAAK,CAAC,IAAI,iBAAiB;oBACnC,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,MAAM,CAAC,UAAU,CAAC,QAAQ;oBAChG,CAAC,CAAC,EAAE,CAAC;gBACT,KAAK,CAAC,IAAI,CAAC,gBAAgB,MAAM,CAAC,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC;gBAC1D,IAAI,UAAU,KAAK,CAAC,IAAI,aAAa,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACf,KAAK,CAAC,IAAI,CACR,sDAAsD;wBACpD,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,wBAAwB;wBAC/F,GAAG,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,sBAAsB;wBAC/F,wEAAwE;wBACxE,KAAK,MAAM,CAAC,QAAQ,CAAC,sDAAsD,CAC9E,CAAC;gBACJ,CAAC;gBACD,IAAI,UAAU,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;oBACvC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACf,KAAK,CAAC,IAAI,CACR,uEAAuE;wBACrE,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,mBAAmB;wBAC1F,GAAG,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,2BAA2B;wBACpG,iDAAiD,MAAM,CAAC,QAAQ,CAAC,KAAK,CACzE,CAAC;gBACJ,CAAC;gBACD,IAAI,UAAU,GAAG,CAAC,IAAI,QAAQ,GAAG,UAAU,GAAG,IAAI,EAAE,CAAC;oBACnD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACf,KAAK,CAAC,IAAI,CACR,wDAAwD,MAAM,CAAC,UAAU,CAAC,eAAe;wBACvF,yBAAyB,WAAW,CAAC,UAAU,GAAG,QAAQ,CAAC,YAAY,MAAM,CAAC,QAAQ,CAAC,GAAG,CAC7F,CAAC;gBACJ,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CACR,aAAa,CACX,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,EACpC,UAAU,CAAC,MAAM,CAAC,EAClB,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAChB,CACF,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;YAC3C,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;YAC5C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CACR,+EAA+E;oBAC7E,kFAAkF;oBAClF,wFAAwF,CAC3F,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CACR,aAAa,CACX,CAAC,QAAQ,EAAE,OAAO,EAAE,WAAW,CAAC,EAChC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnB,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM;oBACtC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;oBACrB,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;iBACzB,CAAC,EACF,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAChB,CACF,CAAC;YACJ,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEf,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CACrD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CACtB,CAAC;YACF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CACR,aAAa,CACX,CAAC,QAAQ,EAAE,WAAW,CAAC,EACvB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;oBAC3B,aAAa,CAAC,IAAI,CAAC;oBACnB,WAAW,CAAC,KAAK,CAAC;iBACnB,CAAC,EACF,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CACb,CACF,CAAC;gBACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACf,KAAK,CAAC,IAAI,CACR,qFAAqF;oBACnF,4FAA4F;oBAC5F,8FAA8F,CACjG,CAAC;YACJ,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CACR,+FAA+F;gBAC7F,iGAAiG,CACpG,CAAC;YAEF,OAAO,UAAU,CACf,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAChB,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CACrC,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,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 registerAsyncCensus(server: McpServer): void;
12
+ //# sourceMappingURL=async-census.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-census.d.ts","sourceRoot":"","sources":["../../src/tools/async-census.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAsEvE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoO3D"}
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @format
8
+ * @oncall memory_lab
9
+ */
10
+ import { z } from 'zod';
11
+ import { getSnapshot } from '../heap-state.js';
12
+ import { errorResult, formatNumber, markdownTable, toolResult, } from '../utils.js';
13
+ /**
14
+ * Pending async work — scheduler tasks, timer callbacks and unsettled promises —
15
+ * as one census.
16
+ *
17
+ * These are grouped because they are one question ("what work is queued, and
18
+ * what is it holding alive?") and because each half was hand-rolled during real
19
+ * hunts, more than once, with different definitions each time.
20
+ *
21
+ * The scheduler half found a real defect that no existing tool reports. React's
22
+ * scheduler keeps its pending work in an ARRAY-BASED MIN-HEAP, and
23
+ * `unstable_cancelCallback` cannot remove an arbitrary node from one — it sets
24
+ * `task.callback = null` and leaves the record in place, to be discarded only
25
+ * when it reaches the root. With a delayed-task queue ordered by `startTime`, a
26
+ * single long-delay task at the root blocks every dead record behind it.
27
+ * Measured on one app: 88 -> 650 tasks over 200 interactions with 65% of them
28
+ * already cancelled, and 1,212 tasks at 44% cancelled on another surface.
29
+ *
30
+ * A cancelled-share above a quarter is the signal; the absolute count is not,
31
+ * because a healthy queue is also allowed to be long.
32
+ */
33
+ /** React scheduler task record. */
34
+ const SCHEDULER_TASK_PROPS = [
35
+ 'callback',
36
+ 'expirationTime',
37
+ 'priorityLevel',
38
+ 'sortIndex',
39
+ 'startTime',
40
+ ];
41
+ const CANCELLED_SHARE_WARN = 0.25;
42
+ function shapeKeys(node) {
43
+ const out = new Set();
44
+ for (const edge of node.references) {
45
+ if (edge.type !== 'property')
46
+ continue;
47
+ const n = String(edge.name_or_index);
48
+ if (n === '__proto__')
49
+ continue;
50
+ out.add(n);
51
+ }
52
+ return out;
53
+ }
54
+ function propTarget(node, name) {
55
+ for (const edge of node.references) {
56
+ if (edge.type !== 'property')
57
+ continue;
58
+ if (String(edge.name_or_index) !== name)
59
+ continue;
60
+ return edge.toNode ?? null;
61
+ }
62
+ return null;
63
+ }
64
+ /** A scheduler task is cancelled when its callback slot holds null/undefined. */
65
+ function isCancelledTask(node) {
66
+ const cb = propTarget(node, 'callback');
67
+ if (cb == null)
68
+ return true;
69
+ const n = cb.name;
70
+ return n === 'null' || n === 'undefined' || n === 'system / Oddball';
71
+ }
72
+ export function registerAsyncCensus(server) {
73
+ server.tool('memlab_async_census', 'Census PENDING ASYNC WORK: React-scheduler task queues (with a live-vs-cancelled split), timer callback closures, and unsettled Promises with their owner shapes. ' +
74
+ "Timer and scheduler accumulation is a common cross-app leak family with no dedicated tool — it was hand-rolled during hunts, differently each time. The scheduler split in particular finds a defect nothing else reports: React's scheduler queues are ARRAY-BASED MIN-HEAPS, so `cancelCallback` only nulls the callback and the dead record stays until it reaches the root; a long-delay task at the root blocks everything behind it. Measured: 88 -> 650 tasks over 200 interactions, 65% already cancelled. " +
75
+ 'A cancelled share above 25% is the signal; a long queue on its own is not.', {
76
+ limit: z
77
+ .number()
78
+ .optional()
79
+ .default(15)
80
+ .describe('Maximum rows per section (default 15).'),
81
+ min_count: z
82
+ .number()
83
+ .optional()
84
+ .default(10)
85
+ .describe('Ignore groups smaller than this (default 10).'),
86
+ }, async ({ limit, min_count }) => {
87
+ try {
88
+ const snapshot = getSnapshot();
89
+ if (!snapshot) {
90
+ return errorResult('No heap snapshot loaded. Use memlab_load_snapshot first.');
91
+ }
92
+ let tasksLive = 0;
93
+ let tasksCancelled = 0;
94
+ // Queue array id -> counts, so the actual container is nameable.
95
+ const queues = new Map();
96
+ let promisesPending = 0;
97
+ let promisesSettled = 0;
98
+ const promiseOwners = new Map();
99
+ const timerClosures = new Map();
100
+ snapshot.nodes.forEach((node) => {
101
+ if (node.id <= 3)
102
+ return;
103
+ if (node.name === 'Promise' && node.type === 'object') {
104
+ // An unsettled promise still points at its reaction list; a settled
105
+ // one points at the result value.
106
+ let pending = false;
107
+ for (const edge of node.references) {
108
+ const t = edge.toNode;
109
+ if (t != null && t.name === 'system / PromiseReaction') {
110
+ pending = true;
111
+ break;
112
+ }
113
+ }
114
+ if (pending)
115
+ promisesPending++;
116
+ else
117
+ promisesSettled++;
118
+ if (pending) {
119
+ for (const edge of node.referrers) {
120
+ const from = edge.fromNode;
121
+ if (from == null || from.id <= 3)
122
+ continue;
123
+ if (String(edge.name_or_index) === '__proto__')
124
+ continue;
125
+ const keys = [...shapeKeys(from)].sort();
126
+ if (keys.length === 0)
127
+ continue;
128
+ const sig = `{${keys.slice(0, 6).join(', ')}}`;
129
+ promiseOwners.set(sig, (promiseOwners.get(sig) ?? 0) + 1);
130
+ break;
131
+ }
132
+ }
133
+ return;
134
+ }
135
+ if (node.type === 'object' && node.name === 'Object') {
136
+ const keys = shapeKeys(node);
137
+ let isTask = true;
138
+ for (const p of SCHEDULER_TASK_PROPS) {
139
+ if (!keys.has(p)) {
140
+ isTask = false;
141
+ break;
142
+ }
143
+ }
144
+ if (isTask) {
145
+ const cancelled = isCancelledTask(node);
146
+ if (cancelled)
147
+ tasksCancelled++;
148
+ else
149
+ tasksLive++;
150
+ for (const edge of node.referrers) {
151
+ const from = edge.fromNode;
152
+ if (from == null || from.name !== 'Array')
153
+ continue;
154
+ const q = queues.get(from.id) ?? {
155
+ live: 0,
156
+ cancelled: 0,
157
+ slots: from.edge_count,
158
+ };
159
+ if (cancelled)
160
+ q.cancelled++;
161
+ else
162
+ q.live++;
163
+ queues.set(from.id, q);
164
+ break;
165
+ }
166
+ }
167
+ return;
168
+ }
169
+ // Timer callbacks: closures held by a scheduler/timeout wrapper.
170
+ if (node.type === 'closure') {
171
+ const n = node.name;
172
+ if (n.startsWith('setTimeout') ||
173
+ n.startsWith('setInterval') ||
174
+ n.includes('scheduleDelayedCallback') ||
175
+ n.includes('requestIdleCallback')) {
176
+ timerClosures.set(n, (timerClosures.get(n) ?? 0) + 1);
177
+ }
178
+ }
179
+ });
180
+ const lines = ['## Pending async work', ''];
181
+ const tasksTotal = tasksLive + tasksCancelled;
182
+ if (tasksTotal > 0) {
183
+ const share = tasksCancelled / tasksTotal;
184
+ lines.push('### Scheduler task queues', '', `**${formatNumber(tasksTotal)} scheduler task record(s)** — ${formatNumber(tasksLive)} live, **${formatNumber(tasksCancelled)} cancelled (${(share * 100).toFixed(0)}%)**.`);
185
+ if (share >= CANCELLED_SHARE_WARN) {
186
+ lines.push('', `⚠ More than ${(CANCELLED_SHARE_WARN * 100).toFixed(0)}% of the queue is dead records. React's scheduler uses an array-based min-heap, so a cancelled task is only nulled — it is discarded when it reaches the ROOT of the heap, and a long-delay task sitting at the root blocks everything behind it. This costs O(n) heap operations per schedule and holds the records' memory until the queue drains.`);
187
+ }
188
+ const qRows = [...queues.entries()]
189
+ .sort((a, b) => b[1].live + b[1].cancelled - (a[1].live + a[1].cancelled))
190
+ .slice(0, limit)
191
+ .filter(([, q]) => q.live + q.cancelled >= min_count);
192
+ if (qRows.length > 0) {
193
+ lines.push('', markdownTable([
194
+ 'Queue',
195
+ 'Tasks',
196
+ 'Live',
197
+ 'Cancelled',
198
+ '% dead',
199
+ 'Array slots',
200
+ ], qRows.map(([id, q]) => [
201
+ `@${id}`,
202
+ formatNumber(q.live + q.cancelled),
203
+ formatNumber(q.live),
204
+ formatNumber(q.cancelled),
205
+ `${((q.cancelled / Math.max(1, q.live + q.cancelled)) * 100).toFixed(0)}%`,
206
+ formatNumber(q.slots),
207
+ ]), new Set([1, 2, 3, 4, 5])), '', '_`memlab_retainer_trace` a queue id to name the module that owns it — the strong retainer is usually a single closure `context` edge, with the rest weak._');
208
+ }
209
+ lines.push('');
210
+ }
211
+ if (timerClosures.size > 0) {
212
+ const rows = [...timerClosures.entries()]
213
+ .filter(([, c]) => c >= min_count)
214
+ .sort((a, b) => b[1] - a[1])
215
+ .slice(0, limit);
216
+ if (rows.length > 0) {
217
+ lines.push('### Timer / delayed-callback closures', '', markdownTable(['Closure', 'Count'], rows.map(([n, c]) => [n, formatNumber(c)]), new Set([1])), '');
218
+ }
219
+ }
220
+ const pTotal = promisesPending + promisesSettled;
221
+ if (pTotal > 0) {
222
+ lines.push('### Promises', '', `**${formatNumber(pTotal)} Promise(s)** — **${formatNumber(promisesPending)} UNSETTLED** (reaction list attached, no result), ${formatNumber(promisesSettled)} settled.`);
223
+ const owners = [...promiseOwners.entries()]
224
+ .filter(([, c]) => c >= min_count)
225
+ .sort((a, b) => b[1] - a[1])
226
+ .slice(0, limit);
227
+ if (owners.length > 0) {
228
+ lines.push('', 'Owner shapes holding an unsettled promise:', markdownTable(['Owner shape', 'Count'], owners.map(([s, c]) => [s, formatNumber(c)]), new Set([1])), '', '_An owner shaped `{abort, promise}` accumulating is the signature of abortable operations whose promises never settle — a robustness smell as much as a memory one. Promises are individually small, so check the aggregate retained (`memlab_eval` + `helpers.aggregateRetained`) before ranking this against a byte-sized finding._');
229
+ }
230
+ lines.push('');
231
+ }
232
+ if (tasksTotal === 0 && pTotal === 0 && timerClosures.size === 0) {
233
+ lines.push('_No scheduler tasks, timer closures or promises found. That is a genuine negative for this family; it does not cover `requestAnimationFrame` callbacks or native timers with no JS-visible record._');
234
+ }
235
+ lines.push('_Counts are per-snapshot. Whether a queue is DRAINING or ACCUMULATING needs a ladder — run this on two rungs, or track the queue with `memlab_collection_trend` once you have named its owner._');
236
+ return toolResult(lines.join('\n'));
237
+ }
238
+ catch (error) {
239
+ return errorResult(`Failed to census async work: ${error instanceof Error ? error.message : String(error)}`);
240
+ }
241
+ });
242
+ }
243
+ //# sourceMappingURL=async-census.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-census.js","sourceRoot":"","sources":["../../src/tools/async-census.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auto-investigate.d.ts","sourceRoot":"","sources":["../../src/tools/auto-investigate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AA49CvE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0tB/D"}
1
+ {"version":3,"file":"auto-investigate.d.ts","sourceRoot":"","sources":["../../src/tools/auto-investigate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,yCAAyC,CAAC;AAq+CvE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+wB/D"}