@herbertgao/pi-extensions 2026.10.1 → 2026.10.2

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 (707) hide show
  1. package/README.md +13 -9
  2. package/THIRD_PARTY_NOTICES.md +2 -2
  3. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +2 -2
  4. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +2 -2
  5. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +1 -1
  6. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-help.md +1 -1
  7. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +2 -2
  8. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +1 -1
  9. package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +21 -21
  10. package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +1 -1
  11. package/node_modules/@dietrichgebert/ponytail/AGENTS.md +21 -21
  12. package/node_modules/@dietrichgebert/ponytail/README.md +68 -72
  13. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +7 -0
  14. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +30 -30
  15. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-map.js +103 -0
  16. package/node_modules/@dietrichgebert/ponytail/package.json +2 -2
  17. package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +33 -101
  18. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +89 -32
  19. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +13 -12
  20. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +17 -16
  21. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +9 -10
  22. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +96 -57
  23. package/node_modules/@herbertgao/pi-agency/LICENSE +21 -0
  24. package/node_modules/@herbertgao/pi-agency/README.md +40 -0
  25. package/node_modules/@herbertgao/pi-agency/package.json +53 -0
  26. package/node_modules/@herbertgao/pi-agency/src/index.ts +441 -0
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +12 -12
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +30 -6
  29. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +15 -9
  30. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +27 -9
  31. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +4 -1
  32. package/node_modules/@herbertgao/pi-cc-extensions/package.json +2 -2
  33. package/node_modules/@narumitw/pi-caffeinate/package.json +3 -3
  34. package/node_modules/@tifan/pi-mermaid-open/package.json +5 -1
  35. package/node_modules/@tifan/pi-mermaid-open/src/index.ts +26 -9
  36. package/node_modules/@tifan/pi-recap/package.json +1 -1
  37. package/node_modules/@tifan/pi-recap/src/index.ts +104 -20
  38. package/node_modules/@tifan/pi-recap/src/models.ts +46 -4
  39. package/node_modules/pi-antigravity/README.md +23 -2
  40. package/node_modules/pi-antigravity/package.json +5 -3
  41. package/node_modules/pi-antigravity/src/diagnostics/diagnostics.ts +3 -2
  42. package/node_modules/pi-antigravity/src/features/generate-image.ts +72 -0
  43. package/node_modules/pi-antigravity/src/features/google-search.ts +71 -0
  44. package/node_modules/pi-antigravity/src/image/image.ts +86 -47
  45. package/node_modules/pi-antigravity/src/image/native.ts +69 -0
  46. package/node_modules/pi-antigravity/src/index.ts +52 -137
  47. package/node_modules/pi-antigravity/src/search/search.ts +130 -31
  48. package/node_modules/pi-antigravity/src/stream/stream.ts +162 -113
  49. package/node_modules/pi-antigravity/src/types/enums.ts +1 -0
  50. package/node_modules/pi-antigravity/src/types/types.ts +1 -1
  51. package/node_modules/pi-antigravity/src/utils/security.ts +47 -1
  52. package/node_modules/pi-antigravity/src/utils/util.ts +38 -6
  53. package/node_modules/pi-lens/CHANGELOG.md +1064 -0
  54. package/node_modules/pi-lens/README.md +115 -25
  55. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +6 -2
  56. package/node_modules/pi-lens/dist/chunk-22AVIGXS.js +560 -0
  57. package/node_modules/pi-lens/dist/chunk-27BBHSZC.js +106 -0
  58. package/node_modules/pi-lens/dist/chunk-2BEMIWEW.js +51 -0
  59. package/node_modules/pi-lens/dist/chunk-2EECBNC5.js +89 -0
  60. package/node_modules/pi-lens/dist/chunk-34U7PLGE.js +23 -0
  61. package/node_modules/pi-lens/dist/chunk-3I5QFT3N.js +181 -0
  62. package/node_modules/pi-lens/dist/chunk-3MED75HT.js +37 -0
  63. package/node_modules/pi-lens/dist/chunk-47D2BO4S.js +87 -0
  64. package/node_modules/pi-lens/dist/chunk-4RERDEXR.js +348 -0
  65. package/node_modules/pi-lens/dist/chunk-4W2PLC4J.js +27 -0
  66. package/node_modules/pi-lens/dist/chunk-52H5B5TC.js +202 -0
  67. package/node_modules/pi-lens/dist/chunk-54B42YRX.js +27 -0
  68. package/node_modules/pi-lens/dist/chunk-5RXBNSW2.js +266 -0
  69. package/node_modules/pi-lens/dist/chunk-5THXD6X5.js +201 -0
  70. package/node_modules/pi-lens/dist/chunk-5W3R6LFT.js +24 -0
  71. package/node_modules/pi-lens/dist/chunk-5ZEJHV35.js +341 -0
  72. package/node_modules/pi-lens/dist/chunk-6P62QVEA.js +118 -0
  73. package/node_modules/pi-lens/dist/chunk-6QIUX4EP.js +459 -0
  74. package/node_modules/pi-lens/dist/chunk-6VCD4VKZ.js +78 -0
  75. package/node_modules/pi-lens/dist/chunk-7F72PXY2.js +326 -0
  76. package/node_modules/pi-lens/dist/chunk-7FBF7NPR.js +998 -0
  77. package/node_modules/pi-lens/dist/chunk-7U2IDNXN.js +37 -0
  78. package/node_modules/pi-lens/dist/chunk-ABBOA7UD.js +157 -0
  79. package/node_modules/pi-lens/dist/chunk-AHDW3GPE.js +50 -0
  80. package/node_modules/pi-lens/dist/chunk-AJ3QXTRQ.js +756 -0
  81. package/node_modules/pi-lens/dist/chunk-AJVLWNFN.js +1610 -0
  82. package/node_modules/pi-lens/dist/chunk-AJXODZY6.js +112 -0
  83. package/node_modules/pi-lens/dist/chunk-ARFCXG7S.js +84 -0
  84. package/node_modules/pi-lens/dist/chunk-AS44CFQ4.js +708 -0
  85. package/node_modules/pi-lens/dist/chunk-AWE5TMPO.js +38 -0
  86. package/node_modules/pi-lens/dist/chunk-B3I2UUT4.js +4692 -0
  87. package/node_modules/pi-lens/dist/chunk-BRJKOBZP.js +331 -0
  88. package/node_modules/pi-lens/dist/chunk-BW5KFIQC.js +59 -0
  89. package/node_modules/pi-lens/dist/chunk-C2AUYXQH.js +149 -0
  90. package/node_modules/pi-lens/dist/chunk-CGGAIP7J.js +29 -0
  91. package/node_modules/pi-lens/dist/chunk-D6QS3U6M.js +30 -0
  92. package/node_modules/pi-lens/dist/chunk-DFVMIKMQ.js +349 -0
  93. package/node_modules/pi-lens/dist/chunk-DIULIWKU.js +169 -0
  94. package/node_modules/pi-lens/dist/chunk-DQ2NZ7C4.js +2317 -0
  95. package/node_modules/pi-lens/dist/chunk-E2WFBRHM.js +213 -0
  96. package/node_modules/pi-lens/dist/chunk-E4MAEDPM.js +50 -0
  97. package/node_modules/pi-lens/dist/chunk-EOKRQ3SA.js +30 -0
  98. package/node_modules/pi-lens/dist/chunk-F3AU2TMM.js +2626 -0
  99. package/node_modules/pi-lens/dist/chunk-F3P7VQ7H.js +170 -0
  100. package/node_modules/pi-lens/dist/chunk-FC4RP4I2.js +12 -0
  101. package/node_modules/pi-lens/dist/chunk-FJNKANOS.js +32 -0
  102. package/node_modules/pi-lens/dist/chunk-GUOGVTCQ.js +146 -0
  103. package/node_modules/pi-lens/dist/chunk-GVXA6CCE.js +18 -0
  104. package/node_modules/pi-lens/dist/chunk-HHYAELLJ.js +2334 -0
  105. package/node_modules/pi-lens/dist/chunk-HMFXILPV.js +83 -0
  106. package/node_modules/pi-lens/dist/chunk-HVUZXSWK.js +421 -0
  107. package/node_modules/pi-lens/dist/chunk-HWBZIGMJ.js +62 -0
  108. package/node_modules/pi-lens/dist/chunk-I3R7GKDR.js +17 -0
  109. package/node_modules/pi-lens/dist/chunk-I7SPGOWI.js +55 -0
  110. package/node_modules/pi-lens/dist/chunk-IIXOAGHR.js +38 -0
  111. package/node_modules/pi-lens/dist/chunk-IVP5KAB7.js +2250 -0
  112. package/node_modules/pi-lens/dist/chunk-IXEBJSUE.js +22 -0
  113. package/node_modules/pi-lens/dist/chunk-JOLITGCC.js +27 -0
  114. package/node_modules/pi-lens/dist/chunk-K6VYLB2U.js +145 -0
  115. package/node_modules/pi-lens/dist/chunk-LJDODBBZ.js +78 -0
  116. package/node_modules/pi-lens/dist/chunk-LNAKEO63.js +78 -0
  117. package/node_modules/pi-lens/dist/chunk-LSMJ6KBE.js +4139 -0
  118. package/node_modules/pi-lens/dist/chunk-LW6XKDZQ.js +5565 -0
  119. package/node_modules/pi-lens/dist/chunk-N3YQJI6O.js +899 -0
  120. package/node_modules/pi-lens/dist/chunk-NABLC7W3.js +148 -0
  121. package/node_modules/pi-lens/dist/chunk-NKOUFPQF.js +659 -0
  122. package/node_modules/pi-lens/dist/chunk-NL5GLMFI.js +211 -0
  123. package/node_modules/pi-lens/dist/chunk-NMABWBZN.js +327 -0
  124. package/node_modules/pi-lens/dist/chunk-NTHH2J74.js +27 -0
  125. package/node_modules/pi-lens/dist/chunk-NTUJEGDZ.js +59 -0
  126. package/node_modules/pi-lens/dist/chunk-NXL4FFQQ.js +47 -0
  127. package/node_modules/pi-lens/dist/chunk-NXPS2L6U.js +466 -0
  128. package/node_modules/pi-lens/dist/chunk-O5WILGMI.js +42 -0
  129. package/node_modules/pi-lens/dist/chunk-O6TQT6RI.js +48 -0
  130. package/node_modules/pi-lens/dist/chunk-OAXNDZJ7.js +323 -0
  131. package/node_modules/pi-lens/dist/chunk-ODEEOXPH.js +44 -0
  132. package/node_modules/pi-lens/dist/chunk-OQGFCZJ4.js +4533 -0
  133. package/node_modules/pi-lens/dist/chunk-ORTMY4Q4.js +282 -0
  134. package/node_modules/pi-lens/dist/chunk-OS32RNR2.js +442 -0
  135. package/node_modules/pi-lens/dist/chunk-PAK6IDME.js +189 -0
  136. package/node_modules/pi-lens/dist/chunk-PWFHBTSF.js +406 -0
  137. package/node_modules/pi-lens/dist/chunk-Q5U6FMDI.js +2352 -0
  138. package/node_modules/pi-lens/dist/chunk-QOZXJ4NA.js +3364 -0
  139. package/node_modules/pi-lens/dist/chunk-QYF5S6P6.js +45 -0
  140. package/node_modules/pi-lens/dist/chunk-RIISMHKN.js +36 -0
  141. package/node_modules/pi-lens/dist/chunk-RPD4ZSB7.js +25 -0
  142. package/node_modules/pi-lens/dist/chunk-RPD5K5NC.js +79 -0
  143. package/node_modules/pi-lens/dist/chunk-RUOG5D2C.js +262 -0
  144. package/node_modules/pi-lens/dist/chunk-T4ERT73Y.js +599 -0
  145. package/node_modules/pi-lens/dist/chunk-T6D4Q4AQ.js +54 -0
  146. package/node_modules/pi-lens/dist/chunk-TGPXLY2J.js +391 -0
  147. package/node_modules/pi-lens/dist/chunk-TLGFBM3F.js +12116 -0
  148. package/node_modules/pi-lens/dist/chunk-TO6WL3GM.js +88 -0
  149. package/node_modules/pi-lens/dist/chunk-TT22N74J.js +517 -0
  150. package/node_modules/pi-lens/dist/chunk-TVN5N6GY.js +21216 -0
  151. package/node_modules/pi-lens/dist/chunk-U3VGR4VU.js +308 -0
  152. package/node_modules/pi-lens/dist/chunk-UK3CMEAL.js +1250 -0
  153. package/node_modules/pi-lens/dist/chunk-UOPVJQ4N.js +103 -0
  154. package/node_modules/pi-lens/dist/chunk-UXVNL3D7.js +23 -0
  155. package/node_modules/pi-lens/dist/chunk-UY752QSN.js +45 -0
  156. package/node_modules/pi-lens/dist/chunk-V5PXFSZK.js +188 -0
  157. package/node_modules/pi-lens/dist/chunk-V7R425XG.js +398 -0
  158. package/node_modules/pi-lens/dist/chunk-VCSRSYLF.js +81 -0
  159. package/node_modules/pi-lens/dist/chunk-VD4JQCQC.js +162 -0
  160. package/node_modules/pi-lens/dist/chunk-VDBPVIKD.js +62 -0
  161. package/node_modules/pi-lens/dist/chunk-VHQLPIRJ.js +114 -0
  162. package/node_modules/pi-lens/dist/chunk-VN2AXLEX.js +5414 -0
  163. package/node_modules/pi-lens/dist/chunk-VNMT7C64.js +478 -0
  164. package/node_modules/pi-lens/dist/chunk-WONERJTP.js +309 -0
  165. package/node_modules/pi-lens/dist/chunk-XECLWQZN.js +85 -0
  166. package/node_modules/pi-lens/dist/chunk-XIMYZ3JA.js +27 -0
  167. package/node_modules/pi-lens/dist/chunk-XK4CIILI.js +144 -0
  168. package/node_modules/pi-lens/dist/chunk-Y4T27COV.js +562 -0
  169. package/node_modules/pi-lens/dist/chunk-YGVYKNSN.js +1860 -0
  170. package/node_modules/pi-lens/dist/chunk-YLF3PPT5.js +308 -0
  171. package/node_modules/pi-lens/dist/chunk-YSNFMJKN.js +14 -0
  172. package/node_modules/pi-lens/dist/chunk-Z3CCVDUB.js +76 -0
  173. package/node_modules/pi-lens/dist/chunk-Z54ZSOBZ.js +61 -0
  174. package/node_modules/pi-lens/dist/chunk-ZAWW3AF6.js +97 -0
  175. package/node_modules/pi-lens/dist/chunk-ZMOL6RQC.js +167 -0
  176. package/node_modules/pi-lens/dist/index.js +16456 -8335
  177. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +186 -232
  178. package/node_modules/pi-lens/dist/mcp/cli.js +137 -98
  179. package/node_modules/pi-lens/dist/mcp/server.js +22589 -1573
  180. package/node_modules/pi-lens/dist/mcp/worker.js +97 -38
  181. package/node_modules/pi-lens/dist/probes/installer.js +135 -0
  182. package/node_modules/pi-lens/dist/workers/project-snapshot-persist-worker.js +22 -0
  183. package/node_modules/pi-lens/dist/workers/review-graph-persist-worker.js +15 -0
  184. package/node_modules/pi-lens/docs/agent-guide.md +13 -4
  185. package/node_modules/pi-lens/docs/agent-tools.md +42 -0
  186. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +3 -2
  187. package/node_modules/pi-lens/docs/configuration.md +20 -1
  188. package/node_modules/pi-lens/docs/environment-variables.md +52 -2
  189. package/node_modules/pi-lens/docs/features.md +8 -4
  190. package/node_modules/pi-lens/docs/globalconfig.md +1 -0
  191. package/node_modules/pi-lens/docs/io-bridge-v2-migration.md +94 -0
  192. package/node_modules/pi-lens/docs/lsp-capability-matrix.md +36 -4
  193. package/node_modules/pi-lens/docs/lsp-idle-eviction.md +124 -0
  194. package/node_modules/pi-lens/docs/mcp.md +21 -5
  195. package/node_modules/pi-lens/docs/merge-queue-rollout.md +77 -0
  196. package/node_modules/pi-lens/docs/pi-lens-fixer.md +156 -88
  197. package/node_modules/pi-lens/docs/pi-lens-investigator.md +74 -26
  198. package/node_modules/pi-lens/docs/pi-lens-merge-policy.md +694 -0
  199. package/node_modules/pi-lens/docs/pi-lens-monitor.md +73 -7
  200. package/node_modules/pi-lens/docs/pi-lens-retro.md +6 -4
  201. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +188 -48
  202. package/node_modules/pi-lens/docs/pi-lens-subagent.md +246 -45
  203. package/node_modules/pi-lens/docs/pi-lens-warden.md +18 -7
  204. package/node_modules/pi-lens/docs/public-api-stability.md +55 -0
  205. package/node_modules/pi-lens/docs/release-qa-baseline.md +84 -17
  206. package/node_modules/pi-lens/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
  207. package/node_modules/pi-lens/docs/servercapabilities.md +53 -49
  208. package/node_modules/pi-lens/docs/settings.md +1 -0
  209. package/node_modules/pi-lens/docs/usage.md +5 -1
  210. package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm +0 -0
  211. package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm.json +3 -3
  212. package/node_modules/pi-lens/package.json +18 -6
  213. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  214. package/node_modules/pi-lens/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  215. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +1275 -62
  216. package/node_modules/pi-lens/scripts/download-grammars.js +5 -0
  217. package/node_modules/pi-lens/scripts/grammars.lock.json +6 -1
  218. package/node_modules/pi-lens/scripts/install-selftest.mjs +33 -34
  219. package/node_modules/pi-lens/scripts/lib/host-provided-deps.mjs +13 -4
  220. package/node_modules/pi-lens/scripts/lib/web-tree-sitter-dir.mjs +18 -0
  221. package/package.json +15 -10
  222. package/node_modules/@dietrichgebert/ponytail/README.es.md +0 -212
  223. package/node_modules/@dietrichgebert/ponytail/README.ja.md +0 -212
  224. package/node_modules/@dietrichgebert/ponytail/README.ko.md +0 -212
  225. package/node_modules/@dietrichgebert/ponytail/README.zh-CN.md +0 -212
  226. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +0 -35
  227. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +0 -1610
  228. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +0 -593
  229. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +0 -147
  230. package/node_modules/pi-lens/dist/clients/agent-nudge.js +0 -325
  231. package/node_modules/pi-lens/dist/clients/analysed-root.js +0 -1
  232. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +0 -731
  233. package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +0 -146
  234. package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +0 -118
  235. package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -10
  236. package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +0 -154
  237. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +0 -75
  238. package/node_modules/pi-lens/dist/clients/atomic-write.js +0 -189
  239. package/node_modules/pi-lens/dist/clients/availability-probe-flight.js +0 -12
  240. package/node_modules/pi-lens/dist/clients/bash-file-access.js +0 -1056
  241. package/node_modules/pi-lens/dist/clients/biome-client.js +0 -357
  242. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +0 -837
  243. package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +0 -129
  244. package/node_modules/pi-lens/dist/clients/bootstrap.js +0 -569
  245. package/node_modules/pi-lens/dist/clients/bounded-cache.js +0 -190
  246. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +0 -202
  247. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +0 -295
  248. package/node_modules/pi-lens/dist/clients/build-identity.js +0 -95
  249. package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +0 -113
  250. package/node_modules/pi-lens/dist/clients/bus-events-logger.js +0 -105
  251. package/node_modules/pi-lens/dist/clients/bus-publish.js +0 -171
  252. package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +0 -190
  253. package/node_modules/pi-lens/dist/clients/cache-manager.js +0 -524
  254. package/node_modules/pi-lens/dist/clients/cache-observability.js +0 -1313
  255. package/node_modules/pi-lens/dist/clients/call-graph.js +0 -852
  256. package/node_modules/pi-lens/dist/clients/cargo-manifest.js +0 -422
  257. package/node_modules/pi-lens/dist/clients/cascade-budget.js +0 -196
  258. package/node_modules/pi-lens/dist/clients/cascade-format.js +0 -315
  259. package/node_modules/pi-lens/dist/clients/cascade-logger.js +0 -31
  260. package/node_modules/pi-lens/dist/clients/cascade-types.js +0 -9
  261. package/node_modules/pi-lens/dist/clients/child-unref.js +0 -124
  262. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +0 -286
  263. package/node_modules/pi-lens/dist/clients/codebase-model.js +0 -173
  264. package/node_modules/pi-lens/dist/clients/collateral-test-role.js +0 -40
  265. package/node_modules/pi-lens/dist/clients/complexity-client.js +0 -462
  266. package/node_modules/pi-lens/dist/clients/config-core/deny.js +0 -221
  267. package/node_modules/pi-lens/dist/clients/config-core/index.js +0 -50
  268. package/node_modules/pi-lens/dist/clients/config-core/merge.js +0 -357
  269. package/node_modules/pi-lens/dist/clients/config-core/normalize.js +0 -340
  270. package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +0 -248
  271. package/node_modules/pi-lens/dist/clients/config-core/provenance.js +0 -164
  272. package/node_modules/pi-lens/dist/clients/config-core/records.js +0 -218
  273. package/node_modules/pi-lens/dist/clients/config-core/resolve.js +0 -125
  274. package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +0 -78
  275. package/node_modules/pi-lens/dist/clients/config-core/schema.js +0 -165
  276. package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +0 -285
  277. package/node_modules/pi-lens/dist/clients/config-locations.js +0 -388
  278. package/node_modules/pi-lens/dist/clients/config-resolve.js +0 -798
  279. package/node_modules/pi-lens/dist/clients/config-schema.js +0 -251
  280. package/node_modules/pi-lens/dist/clients/config-warn.js +0 -407
  281. package/node_modules/pi-lens/dist/clients/console-guard-install.js +0 -26
  282. package/node_modules/pi-lens/dist/clients/cooperative-budget.js +0 -42
  283. package/node_modules/pi-lens/dist/clients/dead-code-client.js +0 -510
  284. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +0 -30
  285. package/node_modules/pi-lens/dist/clients/deadline-utils.js +0 -280
  286. package/node_modules/pi-lens/dist/clients/debug-handles.js +0 -211
  287. package/node_modules/pi-lens/dist/clients/debug-heap.js +0 -174
  288. package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +0 -106
  289. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +0 -426
  290. package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +0 -169
  291. package/node_modules/pi-lens/dist/clients/dependency-checker.js +0 -885
  292. package/node_modules/pi-lens/dist/clients/deps/ast-grep-napi.js +0 -22
  293. package/node_modules/pi-lens/dist/clients/deps/js-yaml.js +0 -9
  294. package/node_modules/pi-lens/dist/clients/deps/minimatch.js +0 -4
  295. package/node_modules/pi-lens/dist/clients/deps/pi-tui.js +0 -14
  296. package/node_modules/pi-lens/dist/clients/deps/typebox.js +0 -14
  297. package/node_modules/pi-lens/dist/clients/deps/vscode-jsonrpc.js +0 -1
  298. package/node_modules/pi-lens/dist/clients/deps/web-tree-sitter.js +0 -24
  299. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +0 -630
  300. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +0 -305
  301. package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +0 -73
  302. package/node_modules/pi-lens/dist/clients/diagnostic-tracker.js +0 -105
  303. package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +0 -230
  304. package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +0 -65
  305. package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +0 -343
  306. package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -35
  307. package/node_modules/pi-lens/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
  308. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +0 -1269
  309. package/node_modules/pi-lens/dist/clients/dispatch/fact-provider-types.js +0 -1
  310. package/node_modules/pi-lens/dist/clients/dispatch/fact-rule-runner.js +0 -17
  311. package/node_modules/pi-lens/dist/clients/dispatch/fact-runner.js +0 -30
  312. package/node_modules/pi-lens/dist/clients/dispatch/fact-scheduler.js +0 -68
  313. package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +0 -377
  314. package/node_modules/pi-lens/dist/clients/dispatch/facts/comment-facts.js +0 -22
  315. package/node_modules/pi-lens/dist/clients/dispatch/facts/file-content.js +0 -19
  316. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +0 -348
  317. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +0 -204
  318. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
  319. package/node_modules/pi-lens/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
  320. package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +0 -339
  321. package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +0 -417
  322. package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +0 -89
  323. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +0 -2377
  324. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -11
  325. package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +0 -87
  326. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -278
  327. package/node_modules/pi-lens/dist/clients/dispatch/priorities.js +0 -20
  328. package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +0 -50
  329. package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +0 -69
  330. package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +0 -135
  331. package/node_modules/pi-lens/dist/clients/dispatch/rules/async-noise.js +0 -40
  332. package/node_modules/pi-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  333. package/node_modules/pi-lens/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
  334. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-obscuring.js +0 -32
  335. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +0 -31
  336. package/node_modules/pi-lens/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
  337. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +0 -72
  338. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +0 -74
  339. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
  340. package/node_modules/pi-lens/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
  341. package/node_modules/pi-lens/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
  342. package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
  343. package/node_modules/pi-lens/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  344. package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
  345. package/node_modules/pi-lens/dist/clients/dispatch/runner-context.js +0 -52
  346. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -111
  347. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
  348. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -296
  349. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +0 -219
  350. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -82
  351. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -416
  352. package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -183
  353. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -176
  354. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -164
  355. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -195
  356. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -137
  357. package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -29
  358. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -69
  359. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -167
  360. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +0 -104
  361. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -135
  362. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -91
  363. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -171
  364. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +0 -940
  365. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -117
  366. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +0 -108
  367. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -99
  368. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -110
  369. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -379
  370. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -167
  371. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -102
  372. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +0 -414
  373. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -85
  374. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -120
  375. package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -62
  376. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
  377. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +0 -169
  378. package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -99
  379. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +0 -88
  380. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +0 -256
  381. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +0 -173
  382. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -102
  383. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +0 -128
  384. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -259
  385. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -183
  386. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -166
  387. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -163
  388. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -174
  389. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -168
  390. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -125
  391. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -643
  392. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -253
  393. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
  394. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
  395. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
  396. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
  397. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
  398. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
  399. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
  400. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
  401. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -15
  402. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -128
  403. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
  404. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +0 -95
  405. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -79
  406. package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +0 -79
  407. package/node_modules/pi-lens/dist/clients/dispatch/tool-profile.js +0 -30
  408. package/node_modules/pi-lens/dist/clients/dispatch/types.js +0 -21
  409. package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +0 -45
  410. package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
  411. package/node_modules/pi-lens/dist/clients/disposition-logger.js +0 -32
  412. package/node_modules/pi-lens/dist/clients/disposition-publish.js +0 -124
  413. package/node_modules/pi-lens/dist/clients/durable-store.js +0 -97
  414. package/node_modules/pi-lens/dist/clients/effective-config.js +0 -415
  415. package/node_modules/pi-lens/dist/clients/env-utils.js +0 -83
  416. package/node_modules/pi-lens/dist/clients/error-class.js +0 -23
  417. package/node_modules/pi-lens/dist/clients/eval-timestamp.js +0 -17
  418. package/node_modules/pi-lens/dist/clients/event-loop-hold.js +0 -274
  419. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +0 -250
  420. package/node_modules/pi-lens/dist/clients/extension-log.js +0 -504
  421. package/node_modules/pi-lens/dist/clients/extension-mode.js +0 -73
  422. package/node_modules/pi-lens/dist/clients/feature-hints.js +0 -103
  423. package/node_modules/pi-lens/dist/clients/file-kinds.js +0 -412
  424. package/node_modules/pi-lens/dist/clients/file-role.js +0 -134
  425. package/node_modules/pi-lens/dist/clients/file-time.js +0 -160
  426. package/node_modules/pi-lens/dist/clients/file-utils.js +0 -1032
  427. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +0 -494
  428. package/node_modules/pi-lens/dist/clients/finding-identity.js +0 -88
  429. package/node_modules/pi-lens/dist/clients/fix-worklog.js +0 -103
  430. package/node_modules/pi-lens/dist/clients/format-events-publish.js +0 -343
  431. package/node_modules/pi-lens/dist/clients/format-service.js +0 -222
  432. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +0 -9
  433. package/node_modules/pi-lens/dist/clients/formatters.js +0 -2032
  434. package/node_modules/pi-lens/dist/clients/freshness-cadence.js +0 -17
  435. package/node_modules/pi-lens/dist/clients/freshness.js +0 -38
  436. package/node_modules/pi-lens/dist/clients/generated-artifacts.js +0 -394
  437. package/node_modules/pi-lens/dist/clients/generation-guard.js +0 -215
  438. package/node_modules/pi-lens/dist/clients/git-guard.js +0 -1136
  439. package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +0 -243
  440. package/node_modules/pi-lens/dist/clients/gitleaks-client.js +0 -509
  441. package/node_modules/pi-lens/dist/clients/go-client.js +0 -104
  442. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +0 -605
  443. package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +0 -348
  444. package/node_modules/pi-lens/dist/clients/grammar-source.js +0 -465
  445. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +0 -135
  446. package/node_modules/pi-lens/dist/clients/hashline-anchor.js +0 -424
  447. package/node_modules/pi-lens/dist/clients/hook-budgets.js +0 -76
  448. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +0 -140
  449. package/node_modules/pi-lens/dist/clients/host-ports.js +0 -39
  450. package/node_modules/pi-lens/dist/clients/indent-retarget.js +0 -154
  451. package/node_modules/pi-lens/dist/clients/inline-blocker-dispositions.js +0 -186
  452. package/node_modules/pi-lens/dist/clients/install-diagnostics.js +0 -156
  453. package/node_modules/pi-lens/dist/clients/installer/index.js +0 -5416
  454. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +0 -58
  455. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +0 -783
  456. package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +0 -7
  457. package/node_modules/pi-lens/dist/clients/instance-reaper.js +0 -1137
  458. package/node_modules/pi-lens/dist/clients/instance-registry-lock.js +0 -145
  459. package/node_modules/pi-lens/dist/clients/instance-registry.js +0 -773
  460. package/node_modules/pi-lens/dist/clients/jscpd-client.js +0 -378
  461. package/node_modules/pi-lens/dist/clients/json-cache-read.js +0 -65
  462. package/node_modules/pi-lens/dist/clients/knip-client.js +0 -788
  463. package/node_modules/pi-lens/dist/clients/language-policy.js +0 -252
  464. package/node_modules/pi-lens/dist/clients/language-profile.js +0 -361
  465. package/node_modules/pi-lens/dist/clients/language-registry.js +0 -603
  466. package/node_modules/pi-lens/dist/clients/latency-logger.js +0 -727
  467. package/node_modules/pi-lens/dist/clients/lazy-import.js +0 -21
  468. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +0 -54
  469. package/node_modules/pi-lens/dist/clients/lens-config.js +0 -404
  470. package/node_modules/pi-lens/dist/clients/lens-engine.js +0 -358
  471. package/node_modules/pi-lens/dist/clients/lens-events.js +0 -125
  472. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +0 -467
  473. package/node_modules/pi-lens/dist/clients/lens-map.js +0 -1156
  474. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +0 -74
  475. package/node_modules/pi-lens/dist/clients/log-cleanup.js +0 -222
  476. package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +0 -178
  477. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +0 -421
  478. package/node_modules/pi-lens/dist/clients/lsp/client.js +0 -4593
  479. package/node_modules/pi-lens/dist/clients/lsp/config.js +0 -691
  480. package/node_modules/pi-lens/dist/clients/lsp/content-limits.js +0 -41
  481. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +0 -225
  482. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +0 -467
  483. package/node_modules/pi-lens/dist/clients/lsp/edits.js +0 -1219
  484. package/node_modules/pi-lens/dist/clients/lsp/index.js +0 -8305
  485. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +0 -216
  486. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +0 -298
  487. package/node_modules/pi-lens/dist/clients/lsp/language.js +0 -63
  488. package/node_modules/pi-lens/dist/clients/lsp/launch.js +0 -746
  489. package/node_modules/pi-lens/dist/clients/lsp/lombok.js +0 -158
  490. package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +0 -5
  491. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +0 -251
  492. package/node_modules/pi-lens/dist/clients/lsp/position-encoding.js +0 -61
  493. package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +0 -83
  494. package/node_modules/pi-lens/dist/clients/lsp/server.js +0 -3290
  495. package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +0 -192
  496. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +0 -17
  497. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -56
  498. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +0 -332
  499. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  500. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +0 -85
  501. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/index.js +0 -10
  502. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +0 -392
  503. package/node_modules/pi-lens/dist/clients/lsp/watch-queue.js +0 -61
  504. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
  505. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
  506. package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +0 -184
  507. package/node_modules/pi-lens/dist/clients/lsp-budget.js +0 -186
  508. package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +0 -110
  509. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +0 -9
  510. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +0 -396
  511. package/node_modules/pi-lens/dist/clients/lsp-status.js +0 -59
  512. package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +0 -40
  513. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +0 -420
  514. package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +0 -31
  515. package/node_modules/pi-lens/dist/clients/mcp/ipc.js +0 -523
  516. package/node_modules/pi-lens/dist/clients/mcp/review.js +0 -197
  517. package/node_modules/pi-lens/dist/clients/mcp/session.js +0 -412
  518. package/node_modules/pi-lens/dist/clients/memory-sampler.js +0 -208
  519. package/node_modules/pi-lens/dist/clients/message-end-attribution.js +0 -30
  520. package/node_modules/pi-lens/dist/clients/metrics-client.js +0 -107
  521. package/node_modules/pi-lens/dist/clients/metrics-history.js +0 -327
  522. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +0 -263
  523. package/node_modules/pi-lens/dist/clients/model-provider.js +0 -53
  524. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +0 -189
  525. package/node_modules/pi-lens/dist/clients/module-report.js +0 -2150
  526. package/node_modules/pi-lens/dist/clients/mutating-tool.js +0 -651
  527. package/node_modules/pi-lens/dist/clients/mutation-attribution.js +0 -368
  528. package/node_modules/pi-lens/dist/clients/mutation-bridge.js +0 -240
  529. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +0 -734
  530. package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +0 -101
  531. package/node_modules/pi-lens/dist/clients/observed-mutation.js +0 -1253
  532. package/node_modules/pi-lens/dist/clients/oldtext-autopatch.js +0 -128
  533. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +0 -496
  534. package/node_modules/pi-lens/dist/clients/opengrep-client.js +0 -333
  535. package/node_modules/pi-lens/dist/clients/opengrep-config.js +0 -76
  536. package/node_modules/pi-lens/dist/clients/package-manager.js +0 -607
  537. package/node_modules/pi-lens/dist/clients/package-root.js +0 -38
  538. package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +0 -439
  539. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +0 -43
  540. package/node_modules/pi-lens/dist/clients/path-keyed-map.js +0 -108
  541. package/node_modules/pi-lens/dist/clients/path-utils.js +0 -1244
  542. package/node_modules/pi-lens/dist/clients/performance-report.js +0 -331
  543. package/node_modules/pi-lens/dist/clients/persist-debounce.js +0 -70
  544. package/node_modules/pi-lens/dist/clients/persistent-reverify.js +0 -271
  545. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +0 -119
  546. package/node_modules/pi-lens/dist/clients/pipeline.js +0 -1480
  547. package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +0 -37
  548. package/node_modules/pi-lens/dist/clients/print-mode.js +0 -21
  549. package/node_modules/pi-lens/dist/clients/probe-home-state.js +0 -228
  550. package/node_modules/pi-lens/dist/clients/process-bridge.js +0 -66
  551. package/node_modules/pi-lens/dist/clients/process-singletons.js +0 -210
  552. package/node_modules/pi-lens/dist/clients/process-snapshot.js +0 -68
  553. package/node_modules/pi-lens/dist/clients/project-changes.js +0 -181
  554. package/node_modules/pi-lens/dist/clients/project-conventions.js +0 -171
  555. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +0 -137
  556. package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +0 -109
  557. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
  558. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
  559. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
  560. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
  561. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
  562. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
  563. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
  564. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
  565. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
  566. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
  567. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
  568. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +0 -520
  569. package/node_modules/pi-lens/dist/clients/project-diagnostics/types.js +0 -1
  570. package/node_modules/pi-lens/dist/clients/project-lens-config.js +0 -807
  571. package/node_modules/pi-lens/dist/clients/project-report.js +0 -701
  572. package/node_modules/pi-lens/dist/clients/project-scale.js +0 -237
  573. package/node_modules/pi-lens/dist/clients/project-scan-policy.js +0 -11
  574. package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +0 -48
  575. package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +0 -20
  576. package/node_modules/pi-lens/dist/clients/project-snapshot.js +0 -1653
  577. package/node_modules/pi-lens/dist/clients/project-trust.js +0 -181
  578. package/node_modules/pi-lens/dist/clients/python-environment.js +0 -217
  579. package/node_modules/pi-lens/dist/clients/python-provenance.js +0 -639
  580. package/node_modules/pi-lens/dist/clients/quiet-window-config.js +0 -47
  581. package/node_modules/pi-lens/dist/clients/quiet-window.js +0 -236
  582. package/node_modules/pi-lens/dist/clients/read-bridge.js +0 -139
  583. package/node_modules/pi-lens/dist/clients/read-expansion.js +0 -266
  584. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +0 -251
  585. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +0 -1306
  586. package/node_modules/pi-lens/dist/clients/read-guard.js +0 -1561
  587. package/node_modules/pi-lens/dist/clients/recent-touches.js +0 -240
  588. package/node_modules/pi-lens/dist/clients/redact/secrets.js +0 -449
  589. package/node_modules/pi-lens/dist/clients/resource-sampler.js +0 -628
  590. package/node_modules/pi-lens/dist/clients/reverse-deps.js +0 -270
  591. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +0 -5126
  592. package/node_modules/pi-lens/dist/clients/review-graph/format.js +0 -33
  593. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +0 -163
  594. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +0 -481
  595. package/node_modules/pi-lens/dist/clients/review-graph/persist-worker.js +0 -10
  596. package/node_modules/pi-lens/dist/clients/review-graph/query.js +0 -244
  597. package/node_modules/pi-lens/dist/clients/review-graph/revision-drift.js +0 -21
  598. package/node_modules/pi-lens/dist/clients/review-graph/service.js +0 -96
  599. package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +0 -82
  600. package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +0 -103
  601. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +0 -299
  602. package/node_modules/pi-lens/dist/clients/review-graph/types.js +0 -1
  603. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +0 -449
  604. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +0 -81
  605. package/node_modules/pi-lens/dist/clients/ruff-client.js +0 -179
  606. package/node_modules/pi-lens/dist/clients/rules-scanner.js +0 -131
  607. package/node_modules/pi-lens/dist/clients/run-duration.js +0 -55
  608. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +0 -746
  609. package/node_modules/pi-lens/dist/clients/runtime-config.js +0 -77
  610. package/node_modules/pi-lens/dist/clients/runtime-context.js +0 -211
  611. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +0 -1324
  612. package/node_modules/pi-lens/dist/clients/runtime-session.js +0 -2485
  613. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +0 -1295
  614. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +0 -2049
  615. package/node_modules/pi-lens/dist/clients/runtime-turn.js +0 -3767
  616. package/node_modules/pi-lens/dist/clients/rust-client.js +0 -97
  617. package/node_modules/pi-lens/dist/clients/safe-spawn.js +0 -2357
  618. package/node_modules/pi-lens/dist/clients/sanitize.js +0 -286
  619. package/node_modules/pi-lens/dist/clients/scan-utils.js +0 -25
  620. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +0 -165
  621. package/node_modules/pi-lens/dist/clients/search-read-registration.js +0 -94
  622. package/node_modules/pi-lens/dist/clients/secret-findings.js +0 -114
  623. package/node_modules/pi-lens/dist/clients/security-scan-client.js +0 -352
  624. package/node_modules/pi-lens/dist/clients/session-event-guard.js +0 -297
  625. package/node_modules/pi-lens/dist/clients/session-lifecycle.js +0 -484
  626. package/node_modules/pi-lens/dist/clients/session-start-observability.js +0 -94
  627. package/node_modules/pi-lens/dist/clients/session-state-store.js +0 -101
  628. package/node_modules/pi-lens/dist/clients/session-summary.js +0 -15
  629. package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +0 -27
  630. package/node_modules/pi-lens/dist/clients/sg-runner.js +0 -876
  631. package/node_modules/pi-lens/dist/clients/sgconfig.js +0 -347
  632. package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +0 -338
  633. package/node_modules/pi-lens/dist/clients/single-flight.js +0 -158
  634. package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +0 -108
  635. package/node_modules/pi-lens/dist/clients/skills-resolver.js +0 -141
  636. package/node_modules/pi-lens/dist/clients/slow-fs.js +0 -138
  637. package/node_modules/pi-lens/dist/clients/smells-rollup.js +0 -231
  638. package/node_modules/pi-lens/dist/clients/source-filter.js +0 -596
  639. package/node_modules/pi-lens/dist/clients/source-walker.js +0 -211
  640. package/node_modules/pi-lens/dist/clients/spawn-output-cap.js +0 -120
  641. package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +0 -110
  642. package/node_modules/pi-lens/dist/clients/stale-marker.js +0 -17
  643. package/node_modules/pi-lens/dist/clients/startup-scan.js +0 -400
  644. package/node_modules/pi-lens/dist/clients/startup-timing.js +0 -130
  645. package/node_modules/pi-lens/dist/clients/string-utils.js +0 -33
  646. package/node_modules/pi-lens/dist/clients/subagent-mode.js +0 -111
  647. package/node_modules/pi-lens/dist/clients/symbol-containment.js +0 -24
  648. package/node_modules/pi-lens/dist/clients/symbol-types.js +0 -5
  649. package/node_modules/pi-lens/dist/clients/test-runner-client.js +0 -2507
  650. package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +0 -287
  651. package/node_modules/pi-lens/dist/clients/todo-scanner.js +0 -229
  652. package/node_modules/pi-lens/dist/clients/tool-agreement.js +0 -423
  653. package/node_modules/pi-lens/dist/clients/tool-config.js +0 -249
  654. package/node_modules/pi-lens/dist/clients/tool-cwd.js +0 -270
  655. package/node_modules/pi-lens/dist/clients/tool-definition.js +0 -47
  656. package/node_modules/pi-lens/dist/clients/tool-event.js +0 -105
  657. package/node_modules/pi-lens/dist/clients/tool-policy.js +0 -2755
  658. package/node_modules/pi-lens/dist/clients/tool-probe.js +0 -53
  659. package/node_modules/pi-lens/dist/clients/tool-render.js +0 -156
  660. package/node_modules/pi-lens/dist/clients/tool-set-policy.js +0 -118
  661. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +0 -364
  662. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +0 -4195
  663. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +0 -100
  664. package/node_modules/pi-lens/dist/clients/tree-sitter-navigator.js +0 -269
  665. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +0 -569
  666. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +0 -158
  667. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
  668. package/node_modules/pi-lens/dist/clients/trivy-client.js +0 -467
  669. package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -50
  670. package/node_modules/pi-lens/dist/clients/turn-context.js +0 -52
  671. package/node_modules/pi-lens/dist/clients/turn-end/lane.js +0 -51
  672. package/node_modules/pi-lens/dist/clients/turn-end/lanes/govulncheck.js +0 -112
  673. package/node_modules/pi-lens/dist/clients/turn-end/lanes/secrets.js +0 -204
  674. package/node_modules/pi-lens/dist/clients/turn-summary-render.js +0 -72
  675. package/node_modules/pi-lens/dist/clients/turn-summary.js +0 -132
  676. package/node_modules/pi-lens/dist/clients/typos-config.js +0 -29
  677. package/node_modules/pi-lens/dist/clients/user-notify.js +0 -51
  678. package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +0 -57
  679. package/node_modules/pi-lens/dist/clients/warm-attach.js +0 -305
  680. package/node_modules/pi-lens/dist/clients/widget-state.js +0 -1808
  681. package/node_modules/pi-lens/dist/clients/word-index-logger.js +0 -49
  682. package/node_modules/pi-lens/dist/clients/word-index-store.js +0 -459
  683. package/node_modules/pi-lens/dist/clients/word-index.js +0 -2080
  684. package/node_modules/pi-lens/dist/clients/workspace-topology.js +0 -443
  685. package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +0 -65
  686. package/node_modules/pi-lens/dist/clients/zizmor-config.js +0 -340
  687. package/node_modules/pi-lens/dist/i18n.js +0 -69
  688. package/node_modules/pi-lens/dist/mcp/build-staleness.js +0 -124
  689. package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +0 -583
  690. package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +0 -129
  691. package/node_modules/pi-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
  692. package/node_modules/pi-lens/dist/tools/activate-tools.js +0 -87
  693. package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +0 -137
  694. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +0 -244
  695. package/node_modules/pi-lens/dist/tools/ast-grep-search.js +0 -762
  696. package/node_modules/pi-lens/dist/tools/effective-config.js +0 -90
  697. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +0 -375
  698. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +0 -2571
  699. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +0 -1745
  700. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +0 -1367
  701. package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +0 -294
  702. package/node_modules/pi-lens/dist/tools/module-report.js +0 -382
  703. package/node_modules/pi-lens/dist/tools/project-report.js +0 -86
  704. package/node_modules/pi-lens/dist/tools/render-compact.js +0 -374
  705. package/node_modules/pi-lens/dist/tools/scan-progress.js +0 -53
  706. package/node_modules/pi-lens/dist/tools/shared.js +0 -29
  707. package/node_modules/pi-lens/dist/tools/symbol-search.js +0 -155
@@ -1,727 +0,0 @@
1
- import * as path from "node:path";
2
- import { isTestMode } from "./env-utils.js";
3
- import { getGlobalPiLensLogDir } from "./probe-home-state.js";
4
- import { createNdjsonLogger } from "./ndjson-logger.js";
5
- import { getMaxLogSizeMB } from "./log-cleanup.js";
6
- import { normalizeLoggedPath } from "./path-utils.js";
7
- import { getTurnId } from "./turn-context.js";
8
- const LATENCY_LOG_DIR = getGlobalPiLensLogDir();
9
- const LATENCY_LOG_FILE = path.join(LATENCY_LOG_DIR, "latency.log");
10
- const writer = createNdjsonLogger({
11
- filePath: LATENCY_LOG_FILE,
12
- maxBytes: getMaxLogSizeMB() * 1024 * 1024,
13
- });
14
- /** Bound on the `recentPhases` ring below — keeps the attribution record small. */
15
- export const RECENT_PHASE_CAP = 5;
16
- /**
17
- * Most recent non-`loop_block` phases seen by `logLatency`, newest first, for
18
- * cheap block attribution (#1122 / #1123 item 1, widened #1723): the
19
- * event-loop-block probe fires at turn_end and cannot see *what* stalled the
20
- * loop, so it stamps the phases that ran as a starting point for root-causing
21
- * a genuine block. A single `lastPhase` pointer names only the phase that
22
- * finished right before the block — useless when the CPU hog itself never got
23
- * to log a completion (it was busy blocking the loop). Keeping a short,
24
- * bounded ring instead gives the block's neighborhood, not just one frame of
25
- * it, while staying O(1) per call and fixed-size in memory. Tracked before the
26
- * test-mode guard so it is deterministic and unit-testable.
27
- */
28
- let recentPhases = [];
29
- /**
30
- * Phases excluded from `lastPhase` attribution alongside `loop_block`.
31
- * #1412 L3: `lsp_typescript_project_identity` is the classic-TS first-open
32
- * project-identity probe (tsserver-sync.ts) — a detached, best-effort
33
- * telemetry sample fired on every first didOpen, not genuine work. Letting it
34
- * win `lastPhase` would overwrite the real stall attribution for a
35
- * loop_block that happens to land right after a first open.
36
- * #1432 review: `advisory_provenance_decision`,
37
- * `authoritative_content_attachment_decision`, and
38
- * `agent_end_deferred_mutation_drain` are the same shape — zero-duration
39
- * decision telemetry, not genuine work — so they get the same exclusion.
40
- * `agent_end_deferred_mutation_requeue` (S2d gap 4's per-requeue record) and
41
- * `session_end_bus_rollup` (S2d gap 5's session-end rollup) are new
42
- * zero-duration siblings of the same shape, added alongside them.
43
- *
44
- * `lsp_aux_wait_outcome` (#1458) is DIFFERENT from every entry above: its
45
- * `durationMs` is a REAL bounded wait, not zero-duration decision telemetry.
46
- * WHICH wait depends on the row's `waitShape` (#1533), so read that field before
47
- * comparing two rows: `"aux_grace"` measures only the post-primary auxiliary
48
- * grace (up to a few seconds), while `"aggregate"` — the `clientScope: "all"`
49
- * producer, which arms no grace of its own — measures the whole diagnostics wait
50
- * from before the primaries settled. The `"aggregate"` number is therefore
51
- * systematically larger for the same auxiliary; it is not a regression. It is
52
- * still
53
- * excluded because it is a WAIT-OUTCOME RECORD written after the aux wait
54
- * already completed, not the stall itself — that wait ran inside the
55
- * `lsp_touch_file`/diagnostics phase surrounding it, so letting this summary
56
- * row win `lastPhase` would misattribute a `loop_block` to the record instead
57
- * of to whatever phase is actually stalled when the block fires.
58
- * #1453: `tool_set_mutation` records an active-tool-set rewrite (zero-duration
59
- * bookkeeping, and it fires during session_start where a real stall must stay
60
- * attributed to the work around it), so it is excluded for the same reason.
61
- * #1467: `availability_decision` records a tool-probe verdict. Its `durationMs`
62
- * is the child's own probe time (often zero for a fast path or a cached
63
- * decision) and the record is bookkeeping ABOUT a probe, not host work — a
64
- * loop_block landing next to one must stay attributed to whatever really
65
- * stalled the loop, which is frequently the very thing that expired the probe.
66
- *
67
- * #1461 slice 1: `finding_dead_path_drop` is the same shape — the record a
68
- * delivery seam writes when it drops findings whose cited path no longer
69
- * exists. #1622 adds `finding_stale_line_demote`, its sibling for findings
70
- * whose cited file was edited after the scan.
71
- *
72
- * #1459: the three scanner-coverage records are summary rows written from inside
73
- * `lsp_touch_file`, and two of them carry ANOTHER write's age as `durationMs`
74
- * (`lsp_notify_resync_deferred`, `lsp_notify_write_late_landed`) rather than
75
- * their own work. `lsp_scanner_coverage_gap` reports the touch's elapsed time for
76
- * joinability. Letting any of them win `lastPhase` would attribute a `loop_block`
77
- * to the record instead of to the touch that is actually stalled.
78
- *
79
- * #1996: `cache_usage_summary` is a zero-duration session rollup over earlier
80
- * usage records. It reports no new work and therefore cannot own last-phase
81
- * stall attribution.
82
- *
83
- * #2249: `concurrent_session_bind_rollup` is the same shape as
84
- * `session_end_bus_rollup`/`path_attribution_verified_rollup` above — a
85
- * zero-duration session-end summary of records already logged individually,
86
- * not new work of its own.
87
- *
88
- * #3310: `lsp_empty_first_publish_held` is the same shape as the #1459
89
- * scanner-coverage rows — a decision record written from inside a live
90
- * `lsp_touch_file` wait whose `durationMs` is ANOTHER write's age (how long
91
- * after `didOpen` the server's pre-index empty publish arrived), not its own
92
- * work. The touch it fires inside owns any real stall.
93
- *
94
- * #2044: `test_runner_failed_target_state` is a zero-duration decision after a
95
- * bounded filesystem probe. The surrounding turn-end test-selection phase owns
96
- * any real work, so this row must not replace it in stall attribution.
97
- */
98
- const LAST_PHASE_EXCLUDED = new Set([
99
- "loop_block",
100
- "lsp_typescript_project_identity",
101
- "advisory_provenance_decision",
102
- "authoritative_content_attachment_decision",
103
- "agent_end_deferred_mutation_drain",
104
- "agent_end_deferred_mutation_requeue",
105
- "session_end_bus_rollup",
106
- "cache_usage_summary",
107
- "test_runner_failed_target_state",
108
- "lsp_aux_wait_outcome",
109
- "tool_set_mutation",
110
- "availability_decision",
111
- "finding_dead_path_drop",
112
- "finding_stale_line_demote",
113
- "finding_path_stat_budget_exhausted",
114
- "lsp_scanner_coverage_gap",
115
- "lsp_notify_resync_deferred",
116
- "lsp_notify_write_late_landed",
117
- "lsp_notify_stall_cpu_busy",
118
- "degradation_ledger",
119
- "path_attribution_verified_rollup",
120
- "concurrent_session_bind_rollup",
121
- "auxiliary_readiness",
122
- "lsp_empty_first_publish_held",
123
- ]);
124
- /**
125
- * The last non-`loop_block` phase logged, or undefined if none yet. Carries its
126
- * own `ts` so a consumer can gauge staleness: it is intentionally NOT cleared at
127
- * turn/window boundaries, so on a turn that logged no phase of its own it may
128
- * point at a prior turn's phase — compare `ts` against the block time before
129
- * trusting it as the cause (it is a breadcrumb, not proof).
130
- */
131
- export function getLastLoggedPhase() {
132
- return recentPhases[0];
133
- }
134
- /**
135
- * The last `limit` non-`loop_block` phases logged, newest first (#1723).
136
- * Bounded to `RECENT_PHASE_CAP` regardless of `limit` — a caller cannot
137
- * request an unbounded ring. Same staleness caveat as `getLastLoggedPhase`:
138
- * these are breadcrumbs from whatever ran most recently, not proof of cause.
139
- */
140
- export function getRecentLoggedPhases(limit = RECENT_PHASE_CAP) {
141
- return recentPhases.slice(0, Math.min(limit, RECENT_PHASE_CAP));
142
- }
143
- /**
144
- * Test-only: the ring's actual storage length, bypassing the read-side
145
- * `Math.min` clamp in `getRecentLoggedPhases` entirely. Needed because that
146
- * clamp and the write-side `.slice(0, RECENT_PHASE_CAP)` in `logLatency` are
147
- * a compensating pair — as long as ONE of them is intact, the other's
148
- * deletion is invisible to any test that only observes
149
- * `getRecentLoggedPhases()` output length. This pins the write-side guard
150
- * specifically: if its `.slice` is deleted, storage grows past the cap and
151
- * this returns the unclamped size regardless of what the read side does.
152
- */
153
- export function _recentPhasesStorageLengthForTest() {
154
- return recentPhases.length;
155
- }
156
- /**
157
- * Test-only: seed the ring directly, bypassing the write-side cap in
158
- * `logLatency`. Lets a test put the ring in a state the normal write path can
159
- * never produce (more than `RECENT_PHASE_CAP` entries), so the read-side
160
- * clamp in `getRecentLoggedPhases` can be pinned independently of the
161
- * write-side guard (see `_recentPhasesStorageLengthForTest` above for why
162
- * that independence matters).
163
- */
164
- export function _setRecentPhasesForTest(entries) {
165
- recentPhases = entries;
166
- }
167
- /**
168
- * Phases currently executing, keyed by their own start token (#1723 review
169
- * round: this replaces an earlier single-slot design that broke two ways.
170
- * `dispatchForFile` runs its runner groups in PARALLEL (`Promise.all`,
171
- * dispatcher.ts), so overlap is the NORMAL case, not an edge case:
172
- * F1 — a single slot holds only the LAST starter. A cheap idle runner
173
- * starting after a CPU hog wins the slot outright; a block gets
174
- * attributed to the innocent idle runner while the hog stays
175
- * anonymous.
176
- * F2 — the inverse: a quick sibling that starts SECOND but FINISHES FIRST
177
- * clears the slot the moment its own `finally` runs, wiping out the
178
- * still-running long phase's attribution — the identity-token check
179
- * only guarded the OTHER stale-clear direction (an EARLIER phase's
180
- * late finish clobbering a LATER phase), not this one.
181
- * A `Map` keyed by the token itself (not by phase name — two calls can share
182
- * a name) fixes both: every bracket owns its own entry regardless of what
183
- * else is live, and `phaseFinished` only ever removes ITS OWN entry. `Map`
184
- * iteration order is insertion order, so the oldest surviving entry — read by
185
- * `getCurrentPhase` — is the longest-running phase still open: the one most
186
- * likely to own a long block.
187
- */
188
- const liveBrackets = new Map();
189
- /**
190
- * Recently CLOSED brackets, newest first, bounded to `RECENT_PHASE_CAP`
191
- * (#1723 review round, F3 — the decisive finding). `phaseFinished` runs
192
- * inside a `finally`, which resumes as a MICROTASK, while the host schedules
193
- * `turn_end` as a MACROTASK — and microtasks always fully drain before the
194
- * next macrotask runs. For the motivating SYNCHRONOUS block, this means the
195
- * offending phase has ALREADY closed (its `finally` already ran) by the time
196
- * `turn_end` gets to sample: `liveBrackets` alone reads EMPTY for exactly the
197
- * case this feature exists to catch. Keeping a short history of recently
198
- * closed brackets lets `getPhaseForWindow` below check whether a block's time
199
- * window overlaps a bracket that already closed, not only ones still open.
200
- */
201
- let closedBrackets = [];
202
- /**
203
- * Mark a phase as started. Returns a token the caller must pass back to
204
- * `phaseFinished` — the token itself is the map key, so it identifies this
205
- * bracket uniquely even against a same-named sibling running concurrently.
206
- * Cost per call: one object allocation, one `Date.now()`/`toISOString()`
207
- * call, and one `Map.set` (O(1), no scan of any collection) — negligible
208
- * next to the runner/phase work it brackets. Measured against this PR's own
209
- * call site (dispatcher.ts's per-runner `runRunner`): a native ast-grep or
210
- * tree-sitter scan, or a subprocess spawn, is orders of magnitude more
211
- * expensive than one map insert.
212
- */
213
- export function phaseStarted(phase) {
214
- const token = { phase, startedAt: new Date().toISOString() };
215
- liveBrackets.set(token, true);
216
- return token;
217
- }
218
- /**
219
- * Close a bracket: removes it from `liveBrackets` (one `Map.delete`, O(1))
220
- * and records it on the closed-bracket ring, bounded to `RECENT_PHASE_CAP`
221
- * with the oldest entry dropped first — see the `closedBrackets` doc comment
222
- * above for why a closed history is load-bearing, not just nice-to-have
223
- * (#1723 review F3). `Map.delete` reports whether it actually removed
224
- * anything, so a stale or duplicate `phaseFinished` call (the token isn't
225
- * live — already closed, or never was) is a no-op and can't push a phantom
226
- * entry onto the closed ring.
227
- *
228
- * Callers MUST pair this with `phaseStarted` via try/finally — an exception
229
- * or an abandoned promise that skips this call leaves a phantom entry in
230
- * `liveBrackets` forever, silently misattributing every LATER loop_block to
231
- * stale work (catalog: a bracket that must clear on finish, never left to a
232
- * process-lifetime latch). `resetCurrentPhaseForSession` is the session-
233
- * boundary backstop for the case where even try/finally doesn't run (a torn-
234
- * down activation whose in-flight phase never gets a chance to unwind).
235
- *
236
- * #1723 review round 3 (N3) — the honest residual: a bracket leaked this way
237
- * (e.g. a torn-down concurrent secondary, see `resetCurrentPhaseForSession`)
238
- * has no age or size cap of its own and sits in `liveBrackets` until the next
239
- * FULL session start clears it. It does NOT go unnoticed in the meantime: a
240
- * leaked bracket is old by construction, so its `elapsedMs` is large, and
241
- * `getPhaseForWindow`'s tie-break below prefers the SMALLER-`elapsedMs`
242
- * candidate on an overlap tie — a genuine culprit whose own lifetime roughly
243
- * matches the block window beats a stale bracket that merely contains it.
244
- * The leak is real; it is demoted, not silently trusted.
245
- */
246
- export function phaseFinished(token) {
247
- if (!liveBrackets.delete(token))
248
- return;
249
- closedBrackets = [
250
- {
251
- phase: token.phase,
252
- startedAt: token.startedAt,
253
- closedAt: new Date().toISOString(),
254
- },
255
- ...closedBrackets,
256
- ].slice(0, RECENT_PHASE_CAP);
257
- }
258
- /**
259
- * The OLDEST phase still executing, if any — the longest-running open
260
- * bracket. #1723 review round 3: this has NO production consumer — `turn_end`
261
- * (index.ts) reads `getPhaseForWindow` below instead, since this function
262
- * alone cannot see a phase that already closed, which is exactly what
263
- * happens for a synchronous block by the time anything samples it (F3).
264
- * Kept deliberately as a TEST SEAM: several regression tests assert "which
265
- * phase is currently open" directly, without constructing a window, which is
266
- * simpler to read and still exercises the same `liveBrackets` map the
267
- * production path shares. Remove if it stops earning its keep.
268
- */
269
- export function getCurrentPhase() {
270
- const oldest = liveBrackets.keys().next();
271
- return oldest.done ? undefined : oldest.value;
272
- }
273
- /**
274
- * A candidate bracket is ignored outright if its OWN lifetime (`elapsedMs`)
275
- * is under this fraction of the window's length (#1723 review round 3, N4).
276
- * Overlap alone is not enough: the bounded closed-bracket ring can churn a
277
- * real culprit out (busy siblings filling `RECENT_PHASE_CAP`), leaving only
278
- * a 1ms bracket that happens to have SOME positive overlap with an 18-second
279
- * window — reporting it would be a CONFIDENT WRONG ANSWER, worse than no
280
- * answer. 5%: a genuine cause's own duration should be a meaningful fraction
281
- * of the block it explains, not a sliver of it. Below that, absent-but-honest
282
- * (return `undefined`) beats present-but-wrong.
283
- */
284
- const MIN_PLAUSIBLE_ELAPSED_FRACTION = 0.05;
285
- /**
286
- * Attribute a block's time window `[windowStartMs, windowEndMs]` to whichever
287
- * bracket — live OR recently closed — best explains it (#1723 review, F3:
288
- * the decisive finding). A live bracket's end, for overlap purposes, is
289
- * "now" (it is still running); a closed bracket's end is its own `closedAt`.
290
- *
291
- * Ranked by CONTAINMENT FRACTION (`overlapMs / max(elapsedMs, windowLengthMs)`),
292
- * not raw overlap (#1723 review round 4, N1 — after round 3's elapsedMs
293
- * tie-break turned out not to engage in practice). Raw overlap is capped at
294
- * the window's own length, and a LIVE bracket's end is always `nowMs` — the
295
- * window's own end — so a long-lived, still-running INNOCENT bracket always
296
- * scores the maximum possible raw overlap. A genuine CLOSED culprit can only
297
- * match that by closing at the exact sample instant, which `turn_end` never
298
- * does: it samples milliseconds AFTER the culprit's `finally` runs, so the
299
- * culprit's raw overlap is always slightly short of the window's full length
300
- * — round 3's "exact tie" tie-break never engaged, and the innocent bracket
301
- * won every time on raw overlap alone. Fraction fixes this structurally: a
302
- * culprit whose own lifetime roughly IS the window scores close to 1.0
303
- * regardless of a few milliseconds of sampling lag, while a long-lived
304
- * innocent bracket that merely CONTAINS the window scores meaningfully
305
- * lower (its `elapsedMs` denominator is bigger).
306
- *
307
- * The denominator is `max(elapsedMs, windowLengthMs)`, not bare `elapsedMs`
308
- * (#1723 review round 5, R1 — the fraction metric's own blind spot). A bare
309
- * `elapsedMs` denominator meant a SHORT bracket wholly INSIDE the window
310
- * scored a perfect, undeserved 1.0 (`overlapMs === elapsedMs` whenever a
311
- * bracket never spills past either window edge) and beat a real culprit
312
- * whose bracket spans slightly MORE than the window — e.g. a 1s innocent
313
- * bracket fully inside an 18.27s window outscored a genuine 19.27s-lifetime
314
- * culprit that explains the whole window and then some. Using the WINDOW's
315
- * length as a floor on the denominator caps the achievable fraction at
316
- * `overlapMs / windowLengthMs` for any bracket no bigger than the window
317
- * itself, so a small bracket can no longer out-rank a big one purely by
318
- * being small; a bracket LARGER than the window still divides by its own
319
- * `elapsedMs`, so the round-4 sampling-lag fix (a big bracket's fraction
320
- * tracks how much of ITS OWN lifetime overlaps) is unaffected. Free
321
- * improvement noted while verifying this: it also further demotes an N3
322
- * leaked bracket when something is competing against it (its `elapsedMs`
323
- * denominator, already large, only grows).
324
- *
325
- * The round-3 elapsedMs comparison is kept as the tie-break for a genuine
326
- * FRACTION tie (two candidates scoring identically) — still reachable under
327
- * this metric: two brackets that both partially overlap the window by the
328
- * SAME amount (`overlapMs` equal) but have different lifetimes both share the
329
- * `windowLengthMs` denominator (since both are ≤ the window), so their
330
- * fractions tie while their `elapsedMs` differs. See
331
- * `tests/clients/latency-logger.test.ts` for a constructed example.
332
- *
333
- * The tie-break compares within an EPSILON band (`FRACTION_TIE_EPSILON` =
334
- * `1e-4`), not exact `===` equality (#1723 review round 6, R3). Co-starting
335
- * — two brackets opening with the identical `startedAt` millisecond string
336
- * — is the NORMAL path, not an edge case: `dispatchForFile` launches its
337
- * runner groups via `Promise.all`, and a runner's `when` precondition awaits
338
- * only microtasks, so this happens routinely. Closed form for a culprit
339
- * that closes `lag` ms before the sample versus a co-started bracket that
340
- * stays live: the culprit scores `1 - lag/W`, the co-started bracket scores
341
- * `1/(1 + lag/W)` — the co-started bracket wins by `(lag/W)^2`, which at a
342
- * real `W` = 18 270ms and `lag` = 5ms is ~7e-8 — far below millisecond
343
- * timestamp resolution, so an EXACT tie never actually engages and the
344
- * "winner" becomes floating-point rounding noise instead. `1e-4` is well
345
- * above any realistic `(lag/W)^2` term (a co-started pair collapses into it)
346
- * and well below the gap between two genuinely different candidates in every
347
- * test/probe this module has been checked against.
348
- *
349
- * The tie-break is a TWO-PASS selection over every candidate, not a
350
- * single-pass streaming comparison (#1723 review round 7, S1 — a blocker).
351
- * A single running `bestFraction`, reassigned on every accepted candidate
352
- * INCLUDING a tie-win, chains: "near" is not transitive, so three candidates
353
- * at fractions 0.600000 / 0.600080 / 0.600160 (adjacent gaps inside the
354
- * epsilon band, but the OUTER gap between the first and third outside it)
355
- * let the running best walk across the whole band one hop at a time — the
356
- * final answer then depends on SCAN ORDER, reachable at roughly 1.5ms of
357
- * overlap difference in an 18s window, which is routine under `Promise.all`
358
- * co-start with three or more candidates. Reseeding `bestFraction` via
359
- * `Math.max(...)` alone does not fix this — the defect is the chaining
360
- * itself, not the seed value. The fix: pass 1 finds the maximum fraction
361
- * across ALL candidates (a plain reduction, immune to order); pass 2 keeps
362
- * only the candidates within the epsilon band OF THAT MAXIMUM — not of each
363
- * other, and not of a running value that could itself have drifted — and
364
- * picks the smallest `elapsedMs` among them. Order-independent by
365
- * construction: the three-candidate example above always excludes the
366
- * first candidate (its gap from the true maximum exceeds the epsilon, even
367
- * though its gap from its immediate neighbor does not), regardless of scan
368
- * order.
369
- *
370
- * Composes with N4's plausibility floor below in the natural order: the
371
- * floor FILTERS candidates (an implausibly short bracket is never even a
372
- * candidate for fraction ranking, and never enters the `candidates` array at
373
- * all); fraction then RANKS the survivors via the two passes above. A
374
- * bracket that clears the floor always has a well-defined fraction in (0, 1].
375
- *
376
- * A candidate needs a STRICTLY POSITIVE overlap: `if (fraction <= 0) return;`
377
- * enforces that explicitly, before the candidate is even collected — pass 1's
378
- * `maxFraction` is seeded at 0 and only ever updated by a STRICTLY GREATER
379
- * value, so without this guard a lone zero-or-negative-fraction candidate
380
- * would sit "within the epsilon band of the seeded 0" in pass 2 and be
381
- * wrongly attributed. #1723 review N2 deleted an EARLIER version of this
382
- * guard as dead code under the round-2 single-pass design, where a strict
383
- * `>` comparison against a 0-seeded running best already excluded it with no
384
- * help needed — that reasoning does not carry over to the two-pass shape,
385
- * where pass 2's job is specifically to find candidates NEAR a seed value.
386
- *
387
- * This is the seam that makes the SYNCHRONOUS motivating case attributable at
388
- * all: the offending phase's `finally` (a microtask) always runs before
389
- * `turn_end` (a macrotask) samples, so by the time this is called the
390
- * bracket has typically already moved from `liveBrackets` to
391
- * `closedBrackets` — checking only the live set reads empty for exactly that
392
- * case, which is why `getCurrentPhase` alone was not enough.
393
- *
394
- * KNOWN RESIDUAL (#1723 review round 4, stated not fixed): a leaked bracket
395
- * (see `phaseFinished`'s doc comment on N3) with NO competing candidate still
396
- * wins any window it fully contains, however many times over its own
397
- * lifetime exceeds the window — fraction ranking only demotes a leak when
398
- * something else is competing for the same window. A ceiling on elapsedMs
399
- * relative to the window length (e.g. reject a candidate whose lifetime is
400
- * some large multiple of the window) would close this, at the cost of a
401
- * second magic number; left open pending a concrete false-positive to size
402
- * it against.
403
- *
404
- * Caveat for an automated consumer (e.g. #1549's loop_block ↔
405
- * lsp_diagnostics_timeout correlation): the window's own end is `now` at
406
- * SAMPLE time, which assumes the block ended right when `turn_end` read
407
- * `getEventLoopStats()` — a reasonable approximation, not a measured fact.
408
- * `startedAt`/`elapsedMs`/`stillRunning` on the returned attribution let a
409
- * human reader judge that assumption per-record; an automated correlation
410
- * should account for the same slack rather than treating the window edges as
411
- * exact.
412
- */
413
- /**
414
- * #1723 review round 6, R3 / round 7, S1: how close two fractions must be to
415
- * count as the SAME answer rather than a genuinely different one. See
416
- * `getPhaseForWindow`'s doc comment for the closed-form derivation (a
417
- * co-started bracket's fraction gap from the true culprit is order
418
- * `(lag/W)^2`, ~7e-8 at production scale) and why a single-pass streaming
419
- * comparison against this band is NOT enough on its own (S1, below).
420
- */
421
- const FRACTION_TIE_EPSILON = 1e-4;
422
- export function getPhaseForWindow(windowStartMs, windowEndMs) {
423
- const nowMs = Date.now();
424
- const windowLengthMs = windowEndMs - windowStartMs;
425
- const minPlausibleElapsedMs = windowLengthMs * MIN_PLAUSIBLE_ELAPSED_FRACTION;
426
- const candidates = [];
427
- const consider = (phase, startedAt, endMs, stillRunning) => {
428
- const startMs = Date.parse(startedAt);
429
- const elapsedMs = endMs - startMs;
430
- if (elapsedMs < minPlausibleElapsedMs)
431
- return; // N4: implausibly short to be the cause
432
- const overlapMs = Math.min(endMs, windowEndMs) - Math.max(startMs, windowStartMs);
433
- // #1723 review round 5, R1: divide by max(elapsedMs, windowLengthMs), not
434
- // elapsedMs alone — see the function doc comment for why a bare
435
- // elapsedMs denominator let a short bracket wholly INSIDE the window
436
- // score a perfect, undeserved 1.0.
437
- const fraction = overlapMs / Math.max(elapsedMs, windowLengthMs);
438
- if (fraction <= 0)
439
- return; // no meaningful overlap — never a candidate
440
- candidates.push({ phase, startedAt, stillRunning, elapsedMs, fraction });
441
- };
442
- for (const token of liveBrackets.keys()) {
443
- consider(token.phase, token.startedAt, nowMs, true);
444
- }
445
- for (const closed of closedBrackets) {
446
- consider(closed.phase, closed.startedAt, Date.parse(closed.closedAt), false);
447
- }
448
- if (candidates.length === 0)
449
- return undefined;
450
- // #1723 review round 7, S1 (blocker): a single-pass streaming comparison
451
- // against `FRACTION_TIE_EPSILON` (round 6's shape) CHAINS — each accepted
452
- // candidate becomes the new `bestFraction`, including a tie-win, and
453
- // "near" is not transitive. A chain of near-ties whose adjacent gaps sit
454
- // inside the epsilon band but whose OUTER gap does not (e.g. three
455
- // candidates at fractions 0.600000 / 0.600080 / 0.600160, an 18s window)
456
- // lets the running "best" walk across the whole band one hop at a time,
457
- // so the final answer depends on SCAN ORDER — reachable at roughly 1.5ms
458
- // of overlap difference in an 18s window, routine under `Promise.all`
459
- // co-start. `bestFraction = Math.max(...)` alone does NOT fix this: the
460
- // bug is the CHAINING, not the seed value.
461
- //
462
- // Fixed with two independent passes instead, order-independent by
463
- // construction:
464
- // Pass 1 finds the MAXIMUM fraction across every candidate — a plain
465
- // reduction, immune to scan order.
466
- // Pass 2 keeps only the candidates within `FRACTION_TIE_EPSILON` OF
467
- // THAT MAXIMUM (not of each other, and not of a running "best" that
468
- // could itself have already drifted) and picks the smallest
469
- // `elapsedMs` among THEM. In the three-candidate example above, only
470
- // the two candidates within the band of the true maximum (0.600160)
471
- // compete; the third, whose gap from the maximum exceeds the epsilon
472
- // even though its gap from its IMMEDIATE neighbor does not, is
473
- // correctly excluded regardless of which order the three were
474
- // scanned in.
475
- let maxFraction = 0;
476
- for (const candidate of candidates) {
477
- if (candidate.fraction > maxFraction)
478
- maxFraction = candidate.fraction;
479
- }
480
- let best;
481
- for (const candidate of candidates) {
482
- if (Math.abs(candidate.fraction - maxFraction) > FRACTION_TIE_EPSILON)
483
- continue;
484
- if (best === undefined || candidate.elapsedMs < best.elapsedMs)
485
- best = candidate;
486
- }
487
- if (best === undefined)
488
- return undefined;
489
- return {
490
- phase: best.phase,
491
- startedAt: best.startedAt,
492
- stillRunning: best.stillRunning,
493
- elapsedMs: best.elapsedMs,
494
- };
495
- }
496
- /**
497
- * Test-only: the closed-bracket ring's actual storage length, mirroring
498
- * `_recentPhasesStorageLengthForTest` above — pins that `phaseFinished`'s
499
- * `.slice(0, RECENT_PHASE_CAP)` guard is intact independent of any
500
- * read-side behavior (#1723 review: "ring unbounded" mutation).
501
- */
502
- export function _closedBracketsStorageLengthForTest() {
503
- return closedBrackets.length;
504
- }
505
- /**
506
- * Session-boundary backstop: unconditionally clears BOTH the live-bracket map
507
- * and the closed-bracket ring. `phaseFinished` is the normal clear path
508
- * (paired via try/finally at each call site), but this module's state is
509
- * process-lifetime, not session-scoped, so a phase abandoned mid-flight by a
510
- * torn-down activation (an abort that skips straight past the `finally`, a
511
- * session replaced mid-scan) would otherwise leave a phantom bracket live
512
- * forever — misattributing every loop_block in every LATER session to that
513
- * one stale phase.
514
- *
515
- * #1723 review F4 — placement is deliberate, and DIFFERENT from
516
- * `warmDispatchAtSessionStart()`: call this only once `session_start` has
517
- * confirmed it is running a FULL session start (`decideSessionStart(...)
518
- * .runFullSessionStart`), i.e. from BEHIND the #473 concurrent-secondary
519
- * gate, not before it. The reason is the opposite of what an unconditional,
520
- * "re-arm on every session_start" placement would give: this module's state
521
- * is process-shared across every concurrently-live activation in the same
522
- * process, exactly like the LSP fleet / runtime generation #473 already
523
- * protects — a concurrent secondary's `session_start` firing while the
524
- * PARENT activation has genuinely in-flight brackets must not wipe the
525
- * parent's live attribution out from under it. Only a real sequential
526
- * session replacement (new/resume/fork/reload confirmed by
527
- * `decideSessionStart`) may safely assume no other activation still owns
528
- * live brackets in this process. A concurrent secondary's OWN torn-down
529
- * brackets are still covered: each caller's `phaseFinished` runs in its own
530
- * try/finally, and if that activation is torn down hard enough to skip even
531
- * that, the accepted cost is a stale bracket that the NEXT full session start
532
- * clears — not a wrong clear of a sibling that is still working.
533
- */
534
- export function resetCurrentPhaseForSession() {
535
- liveBrackets.clear();
536
- closedBrackets = [];
537
- }
538
- /**
539
- * Phases already written ONCE for the current session (#2526).
540
- *
541
- * Session-scoped telemetry bookkeeping, which is this module's own domain —
542
- * the same reason `liveBrackets` and `recentPhases` live here rather than in
543
- * each producer. A producer that is called many times per session but whose
544
- * record is a SESSION fact (`config_resolved`: `loadLSPConfig` runs at session
545
- * start, per served root, and on the first edit, all resolving the same
546
- * config) asks here instead of keeping its own latch, so the "one row per
547
- * session" a log reader counts against is a property of the logger rather than
548
- * a convention each producer re-implements.
549
- */
550
- const oncePerSessionPhases = new Set();
551
- /**
552
- * The identity every once-per-session record of THIS session is stamped with
553
- * (#2526 review round 2, F2).
554
- *
555
- * A line-oriented log reader cannot join two files by adjacency: sessionstart.
556
- * log's start lines and latency.log's phase rows interleave differently, rotate
557
- * independently, and (for the warm MCP server) can span days. The first round
558
- * therefore SUBTRACTED row counts from start-line counts, which silently
559
- * assumed the two counted the same population — they do not, and the
560
- * mismatch both masked total silence and manufactured a permanent false
561
- * deficit. An id makes the join explicit: `handleSessionStart` publishes it
562
- * beside its expectation, the record carries it, and the analyzer matches.
563
- *
564
- * It is minted HERE, beside the claim set it identifies, so "which session is
565
- * this record from" and "has this session already recorded" can never answer
566
- * from different sessions.
567
- *
568
- * Minted at module load too, not only on re-arm: the warm MCP server resolves
569
- * config through `ensureReady` without any session boundary of its own, and a
570
- * record with no id at all would be unjoinable rather than merely unmatched.
571
- */
572
- let sessionRecordSeq = 0;
573
- function mintSessionRecordId() {
574
- sessionRecordSeq += 1;
575
- return `${process.pid.toString(36)}-${Date.now().toString(36)}-${sessionRecordSeq.toString(36)}`;
576
- }
577
- let sessionRecordId = mintSessionRecordId();
578
- /**
579
- * The current session's record identity — an opaque, process-local token.
580
- *
581
- * Deliberately NOT the host's session id: that is user-facing conversation
582
- * identity pi-lens does not otherwise write to disk, and the join only needs
583
- * "the same session", not "which conversation".
584
- */
585
- export function currentSessionRecordId() {
586
- return sessionRecordId;
587
- }
588
- /**
589
- * The claim key. A phase is claimed per SCOPE (#2526 review round 2, F3):
590
- * `config_resolved` is a fact about a (session, project root) pair, and the
591
- * warm MCP server serves N roots from one process — keying on the phase name
592
- * alone recorded the first root's documents and silently dropped every other
593
- * root's, so a legacy config in project B could never surface its smell.
594
- *
595
- * `scope` is REQUIRED (#2526 review round 3, S3 — narrowed from optional):
596
- * the one production caller always passes one, and an unscoped claim is the
597
- * exact shape F3 found unsafe — a phase-only key recording the first caller
598
- * and silently dropping every later one under a different scope. A future
599
- * producer with no natural scope can pass a constant string; that is still an
600
- * explicit choice, not a silently-defaulted one.
601
- */
602
- function claimKey(phase, scope) {
603
- return `${phase}\0${scope}`;
604
- }
605
- /**
606
- * Claim the session's one record for `phase` within `scope`.
607
- *
608
- * Returns true exactly once per session and scope; every later call for the
609
- * same pair returns false until {@link resetOncePerSessionPhases} re-arms it.
610
- * Callers should claim BEFORE building the payload, so a claim that loses the
611
- * race costs nothing.
612
- */
613
- export function claimPhaseOncePerSession(phase, scope) {
614
- const key = claimKey(phase, scope);
615
- if (oncePerSessionPhases.has(key))
616
- return false;
617
- oncePerSessionPhases.add(key);
618
- return true;
619
- }
620
- /**
621
- * Release ONE scope's claim for `phase` — the narrow sibling of
622
- * {@link releaseOncePerSessionPhase}, which releases every scope of a phase.
623
- *
624
- * #2518 review F1. A claim is a promise that this session's record for the
625
- * (phase, scope) pair has already been written, which holds only while the
626
- * state that record described is still there. When that state is DROPPED —
627
- * the session-root registry evicting a root, taking its resolved LSP config
628
- * with it — the next load for that scope is a genuine SECOND resolution, and
629
- * its row is the only thing that says what the reloaded config was. So the
630
- * claim is released with the state it described; a claim outliving its state
631
- * silences the record for the rest of the session, which is catalog shape 17
632
- * pointed at a positive-observability record.
633
- *
634
- * Bounded by the caller: releases are as frequent as the evictions that cause
635
- * them, and those are counted (`lsp-session-root-evicted`).
636
- */
637
- export function releasePhaseClaim(phase, scope) {
638
- oncePerSessionPhases.delete(claimKey(phase, scope));
639
- }
640
- /**
641
- * Release every scope's claim for ONE phase, without touching the others
642
- * (#2526 review round 2, S1).
643
- *
644
- * A producer's own `resetForTests` needs its own phase re-armed, not a blanket
645
- * clear of a shared session-scoped structure: the blanket call reached into
646
- * claims other producers own and, worse, re-minted the session identity as a
647
- * side effect of an unrelated module's reset.
648
- */
649
- export function releaseOncePerSessionPhase(phase) {
650
- const prefix = `${phase}\0`;
651
- for (const key of oncePerSessionPhases) {
652
- if (key.startsWith(prefix))
653
- oncePerSessionPhases.delete(key);
654
- }
655
- }
656
- /**
657
- * Re-arm every once-per-session phase claim for a new session, and mint the
658
- * new session's record identity.
659
- *
660
- * PLACEMENT (#2526 review round 2, F1): this is called from index.ts's
661
- * `session_start` closure, from BEHIND the #473 concurrent-secondary gate,
662
- * beside `resetCurrentPhaseForSession` — and NOT from inside
663
- * `handleSessionStart`. index.ts resolves this session's config in
664
- * `ensureLSPConfigInitialized` BEFORE it calls the handler, so a re-arm inside
665
- * the handler fires between the session's own two resolutions: the ensure
666
- * writes a row, the handler wipes the claim, and the deferred `loadLSPConfig`
667
- * writes a second row for the same session. The first session of a process got
668
- * two rows and every later one (whose ensure the process-lifetime
669
- * `_lspConfigInitializedCwds` memo short-circuits) got one, which is
670
- * unrecoverable for any per-session count.
671
- *
672
- * A latch that is never re-armed silences its record for the rest of the
673
- * PROCESS (AGENTS.md catalog shape 17), which for a positive-observability
674
- * record is the exact silence it exists to end — so the re-arm must exist; it
675
- * just has to sit ahead of the session's first resolution rather than in the
676
- * middle of them.
677
- *
678
- * The warm MCP server (`clients/mcp/session.ts` calls `handleSessionStart`
679
- * directly, never through index.ts) therefore keeps ONE identity for the life
680
- * of the process. That is the honest answer for it: a warm server has no
681
- * session boundary, its "session" is the process, and F3's per-root scoping is
682
- * what gives it one record per served root.
683
- */
684
- export function resetOncePerSessionPhases() {
685
- oncePerSessionPhases.clear();
686
- sessionRecordId = mintSessionRecordId();
687
- }
688
- export function logLatency(entry) {
689
- const ts = new Date().toISOString();
690
- if (entry.type === "phase" &&
691
- entry.phase &&
692
- !LAST_PHASE_EXCLUDED.has(entry.phase)) {
693
- recentPhases = [
694
- { phase: entry.phase, ts, metadata: entry.metadata },
695
- ...recentPhases,
696
- ].slice(0, RECENT_PHASE_CAP);
697
- }
698
- if (isTestMode()) {
699
- return;
700
- }
701
- // #2219 (the #2141 class): `filePath` mixes raw `path.resolve()`/`cwd`
702
- // values (module-report.ts) with already-normalized ones
703
- // (dispatcher.ts-derived `ctx.filePath`) AND non-path labels ("<pi-lens>",
704
- // a tool name, a shell command) that several call sites deliberately use
705
- // as a coarse identity — see bounded-telemetry.ts's comment on this field.
706
- // `normalizeLoggedPath` normalizes only values that are already
707
- // fully-qualified paths, leaving every label/command untouched.
708
- writer.log({
709
- ...entry,
710
- ts,
711
- pid: process.pid,
712
- turnId: entry.turnId ?? getTurnId(),
713
- filePath: normalizeLoggedPath(entry.filePath),
714
- });
715
- }
716
- export function getLatencyLogPath() {
717
- return LATENCY_LOG_FILE;
718
- }
719
- /** Resolve once all enqueued latency writes are on disk (tests/shutdown). */
720
- export function flushLatencyLog() {
721
- return writer.flush();
722
- }
723
- export function clearLatencyLog() {
724
- // Enqueue the truncate in the same serialized queue so a clear cannot race a
725
- // pending drain. Await flushLatencyLog() if you need the file empty on disk.
726
- writer.truncate();
727
- }