@herbertgao/pi-extensions 2026.10.0 → 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 (769) hide show
  1. package/README.md +16 -12
  2. package/THIRD_PARTY_NOTICES.md +3 -3
  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/.opencode/plugins/index.js +4 -0
  10. package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail-frontmatter.cjs +43 -3
  11. package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs +142 -59
  12. package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +21 -21
  13. package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +1 -1
  14. package/node_modules/@dietrichgebert/ponytail/AGENTS.md +21 -21
  15. package/node_modules/@dietrichgebert/ponytail/README.md +52 -242
  16. package/node_modules/@dietrichgebert/ponytail/hooks/claude-codex-hooks.json +3 -3
  17. package/node_modules/@dietrichgebert/ponytail/hooks/copilot-hooks.json +4 -4
  18. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +70 -16
  19. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-config.js +8 -7
  20. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +30 -30
  21. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-map.js +103 -0
  22. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-mode-tracker.js +46 -23
  23. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-runtime.js +39 -7
  24. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-subagent.js +20 -3
  25. package/node_modules/@dietrichgebert/ponytail/hooks/qoder-hooks.json +3 -3
  26. package/node_modules/@dietrichgebert/ponytail/package.json +3 -3
  27. package/node_modules/@dietrichgebert/ponytail/pi-extension/index.js +47 -17
  28. package/node_modules/@dietrichgebert/ponytail/scripts/uninstall.js +21 -7
  29. package/node_modules/@dietrichgebert/ponytail/skills/plugin.json +5 -0
  30. package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +33 -101
  31. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +89 -27
  32. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +13 -12
  33. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +21 -18
  34. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +12 -13
  35. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +96 -52
  36. package/node_modules/@herbertgao/pi-agency/LICENSE +21 -0
  37. package/node_modules/@herbertgao/pi-agency/README.md +40 -0
  38. package/node_modules/@herbertgao/pi-agency/package.json +53 -0
  39. package/node_modules/@herbertgao/pi-agency/src/index.ts +441 -0
  40. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +12 -12
  41. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +30 -6
  42. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +15 -9
  43. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +27 -9
  44. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +4 -1
  45. package/node_modules/@herbertgao/pi-cc-extensions/package.json +2 -2
  46. package/node_modules/@narumitw/pi-caffeinate/package.json +4 -4
  47. package/node_modules/@tifan/pi-mermaid-open/package.json +5 -1
  48. package/node_modules/@tifan/pi-mermaid-open/src/index.ts +26 -9
  49. package/node_modules/@tifan/pi-recap/package.json +1 -1
  50. package/node_modules/@tifan/pi-recap/src/index.ts +104 -20
  51. package/node_modules/@tifan/pi-recap/src/models.ts +46 -4
  52. package/node_modules/pi-antigravity/README.md +23 -2
  53. package/node_modules/pi-antigravity/package.json +5 -3
  54. package/node_modules/pi-antigravity/src/diagnostics/diagnostics.ts +3 -2
  55. package/node_modules/pi-antigravity/src/features/generate-image.ts +72 -0
  56. package/node_modules/pi-antigravity/src/features/google-search.ts +71 -0
  57. package/node_modules/pi-antigravity/src/image/image.ts +86 -47
  58. package/node_modules/pi-antigravity/src/image/native.ts +69 -0
  59. package/node_modules/pi-antigravity/src/index.ts +52 -137
  60. package/node_modules/pi-antigravity/src/search/search.ts +130 -31
  61. package/node_modules/pi-antigravity/src/stream/stream.ts +162 -113
  62. package/node_modules/pi-antigravity/src/types/enums.ts +1 -0
  63. package/node_modules/pi-antigravity/src/types/types.ts +1 -1
  64. package/node_modules/pi-antigravity/src/utils/security.ts +47 -1
  65. package/node_modules/pi-antigravity/src/utils/util.ts +38 -6
  66. package/node_modules/pi-lens/CHANGELOG.md +1064 -0
  67. package/node_modules/pi-lens/README.md +115 -25
  68. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +6 -2
  69. package/node_modules/pi-lens/dist/chunk-22AVIGXS.js +560 -0
  70. package/node_modules/pi-lens/dist/chunk-27BBHSZC.js +106 -0
  71. package/node_modules/pi-lens/dist/chunk-2BEMIWEW.js +51 -0
  72. package/node_modules/pi-lens/dist/chunk-2EECBNC5.js +89 -0
  73. package/node_modules/pi-lens/dist/chunk-34U7PLGE.js +23 -0
  74. package/node_modules/pi-lens/dist/chunk-3I5QFT3N.js +181 -0
  75. package/node_modules/pi-lens/dist/chunk-3MED75HT.js +37 -0
  76. package/node_modules/pi-lens/dist/chunk-47D2BO4S.js +87 -0
  77. package/node_modules/pi-lens/dist/chunk-4RERDEXR.js +348 -0
  78. package/node_modules/pi-lens/dist/chunk-4W2PLC4J.js +27 -0
  79. package/node_modules/pi-lens/dist/chunk-52H5B5TC.js +202 -0
  80. package/node_modules/pi-lens/dist/chunk-54B42YRX.js +27 -0
  81. package/node_modules/pi-lens/dist/chunk-5RXBNSW2.js +266 -0
  82. package/node_modules/pi-lens/dist/chunk-5THXD6X5.js +201 -0
  83. package/node_modules/pi-lens/dist/chunk-5W3R6LFT.js +24 -0
  84. package/node_modules/pi-lens/dist/chunk-5ZEJHV35.js +341 -0
  85. package/node_modules/pi-lens/dist/chunk-6P62QVEA.js +118 -0
  86. package/node_modules/pi-lens/dist/chunk-6QIUX4EP.js +459 -0
  87. package/node_modules/pi-lens/dist/chunk-6VCD4VKZ.js +78 -0
  88. package/node_modules/pi-lens/dist/chunk-7F72PXY2.js +326 -0
  89. package/node_modules/pi-lens/dist/chunk-7FBF7NPR.js +998 -0
  90. package/node_modules/pi-lens/dist/chunk-7U2IDNXN.js +37 -0
  91. package/node_modules/pi-lens/dist/chunk-ABBOA7UD.js +157 -0
  92. package/node_modules/pi-lens/dist/chunk-AHDW3GPE.js +50 -0
  93. package/node_modules/pi-lens/dist/chunk-AJ3QXTRQ.js +756 -0
  94. package/node_modules/pi-lens/dist/chunk-AJVLWNFN.js +1610 -0
  95. package/node_modules/pi-lens/dist/chunk-AJXODZY6.js +112 -0
  96. package/node_modules/pi-lens/dist/chunk-ARFCXG7S.js +84 -0
  97. package/node_modules/pi-lens/dist/chunk-AS44CFQ4.js +708 -0
  98. package/node_modules/pi-lens/dist/chunk-AWE5TMPO.js +38 -0
  99. package/node_modules/pi-lens/dist/chunk-B3I2UUT4.js +4692 -0
  100. package/node_modules/pi-lens/dist/chunk-BRJKOBZP.js +331 -0
  101. package/node_modules/pi-lens/dist/chunk-BW5KFIQC.js +59 -0
  102. package/node_modules/pi-lens/dist/chunk-C2AUYXQH.js +149 -0
  103. package/node_modules/pi-lens/dist/chunk-CGGAIP7J.js +29 -0
  104. package/node_modules/pi-lens/dist/chunk-D6QS3U6M.js +30 -0
  105. package/node_modules/pi-lens/dist/chunk-DFVMIKMQ.js +349 -0
  106. package/node_modules/pi-lens/dist/chunk-DIULIWKU.js +169 -0
  107. package/node_modules/pi-lens/dist/chunk-DQ2NZ7C4.js +2317 -0
  108. package/node_modules/pi-lens/dist/chunk-E2WFBRHM.js +213 -0
  109. package/node_modules/pi-lens/dist/chunk-E4MAEDPM.js +50 -0
  110. package/node_modules/pi-lens/dist/chunk-EOKRQ3SA.js +30 -0
  111. package/node_modules/pi-lens/dist/chunk-F3AU2TMM.js +2626 -0
  112. package/node_modules/pi-lens/dist/chunk-F3P7VQ7H.js +170 -0
  113. package/node_modules/pi-lens/dist/chunk-FC4RP4I2.js +12 -0
  114. package/node_modules/pi-lens/dist/chunk-FJNKANOS.js +32 -0
  115. package/node_modules/pi-lens/dist/chunk-GUOGVTCQ.js +146 -0
  116. package/node_modules/pi-lens/dist/chunk-GVXA6CCE.js +18 -0
  117. package/node_modules/pi-lens/dist/chunk-HHYAELLJ.js +2334 -0
  118. package/node_modules/pi-lens/dist/chunk-HMFXILPV.js +83 -0
  119. package/node_modules/pi-lens/dist/chunk-HVUZXSWK.js +421 -0
  120. package/node_modules/pi-lens/dist/chunk-HWBZIGMJ.js +62 -0
  121. package/node_modules/pi-lens/dist/chunk-I3R7GKDR.js +17 -0
  122. package/node_modules/pi-lens/dist/chunk-I7SPGOWI.js +55 -0
  123. package/node_modules/pi-lens/dist/chunk-IIXOAGHR.js +38 -0
  124. package/node_modules/pi-lens/dist/chunk-IVP5KAB7.js +2250 -0
  125. package/node_modules/pi-lens/dist/chunk-IXEBJSUE.js +22 -0
  126. package/node_modules/pi-lens/dist/chunk-JOLITGCC.js +27 -0
  127. package/node_modules/pi-lens/dist/chunk-K6VYLB2U.js +145 -0
  128. package/node_modules/pi-lens/dist/chunk-LJDODBBZ.js +78 -0
  129. package/node_modules/pi-lens/dist/chunk-LNAKEO63.js +78 -0
  130. package/node_modules/pi-lens/dist/chunk-LSMJ6KBE.js +4139 -0
  131. package/node_modules/pi-lens/dist/chunk-LW6XKDZQ.js +5565 -0
  132. package/node_modules/pi-lens/dist/chunk-N3YQJI6O.js +899 -0
  133. package/node_modules/pi-lens/dist/chunk-NABLC7W3.js +148 -0
  134. package/node_modules/pi-lens/dist/chunk-NKOUFPQF.js +659 -0
  135. package/node_modules/pi-lens/dist/chunk-NL5GLMFI.js +211 -0
  136. package/node_modules/pi-lens/dist/chunk-NMABWBZN.js +327 -0
  137. package/node_modules/pi-lens/dist/chunk-NTHH2J74.js +27 -0
  138. package/node_modules/pi-lens/dist/chunk-NTUJEGDZ.js +59 -0
  139. package/node_modules/pi-lens/dist/chunk-NXL4FFQQ.js +47 -0
  140. package/node_modules/pi-lens/dist/chunk-NXPS2L6U.js +466 -0
  141. package/node_modules/pi-lens/dist/chunk-O5WILGMI.js +42 -0
  142. package/node_modules/pi-lens/dist/chunk-O6TQT6RI.js +48 -0
  143. package/node_modules/pi-lens/dist/chunk-OAXNDZJ7.js +323 -0
  144. package/node_modules/pi-lens/dist/chunk-ODEEOXPH.js +44 -0
  145. package/node_modules/pi-lens/dist/chunk-OQGFCZJ4.js +4533 -0
  146. package/node_modules/pi-lens/dist/chunk-ORTMY4Q4.js +282 -0
  147. package/node_modules/pi-lens/dist/chunk-OS32RNR2.js +442 -0
  148. package/node_modules/pi-lens/dist/chunk-PAK6IDME.js +189 -0
  149. package/node_modules/pi-lens/dist/chunk-PWFHBTSF.js +406 -0
  150. package/node_modules/pi-lens/dist/chunk-Q5U6FMDI.js +2352 -0
  151. package/node_modules/pi-lens/dist/chunk-QOZXJ4NA.js +3364 -0
  152. package/node_modules/pi-lens/dist/chunk-QYF5S6P6.js +45 -0
  153. package/node_modules/pi-lens/dist/chunk-RIISMHKN.js +36 -0
  154. package/node_modules/pi-lens/dist/chunk-RPD4ZSB7.js +25 -0
  155. package/node_modules/pi-lens/dist/chunk-RPD5K5NC.js +79 -0
  156. package/node_modules/pi-lens/dist/chunk-RUOG5D2C.js +262 -0
  157. package/node_modules/pi-lens/dist/chunk-T4ERT73Y.js +599 -0
  158. package/node_modules/pi-lens/dist/chunk-T6D4Q4AQ.js +54 -0
  159. package/node_modules/pi-lens/dist/chunk-TGPXLY2J.js +391 -0
  160. package/node_modules/pi-lens/dist/chunk-TLGFBM3F.js +12116 -0
  161. package/node_modules/pi-lens/dist/chunk-TO6WL3GM.js +88 -0
  162. package/node_modules/pi-lens/dist/chunk-TT22N74J.js +517 -0
  163. package/node_modules/pi-lens/dist/chunk-TVN5N6GY.js +21216 -0
  164. package/node_modules/pi-lens/dist/chunk-U3VGR4VU.js +308 -0
  165. package/node_modules/pi-lens/dist/chunk-UK3CMEAL.js +1250 -0
  166. package/node_modules/pi-lens/dist/chunk-UOPVJQ4N.js +103 -0
  167. package/node_modules/pi-lens/dist/chunk-UXVNL3D7.js +23 -0
  168. package/node_modules/pi-lens/dist/chunk-UY752QSN.js +45 -0
  169. package/node_modules/pi-lens/dist/chunk-V5PXFSZK.js +188 -0
  170. package/node_modules/pi-lens/dist/chunk-V7R425XG.js +398 -0
  171. package/node_modules/pi-lens/dist/chunk-VCSRSYLF.js +81 -0
  172. package/node_modules/pi-lens/dist/chunk-VD4JQCQC.js +162 -0
  173. package/node_modules/pi-lens/dist/chunk-VDBPVIKD.js +62 -0
  174. package/node_modules/pi-lens/dist/chunk-VHQLPIRJ.js +114 -0
  175. package/node_modules/pi-lens/dist/chunk-VN2AXLEX.js +5414 -0
  176. package/node_modules/pi-lens/dist/chunk-VNMT7C64.js +478 -0
  177. package/node_modules/pi-lens/dist/chunk-WONERJTP.js +309 -0
  178. package/node_modules/pi-lens/dist/chunk-XECLWQZN.js +85 -0
  179. package/node_modules/pi-lens/dist/chunk-XIMYZ3JA.js +27 -0
  180. package/node_modules/pi-lens/dist/chunk-XK4CIILI.js +144 -0
  181. package/node_modules/pi-lens/dist/chunk-Y4T27COV.js +562 -0
  182. package/node_modules/pi-lens/dist/chunk-YGVYKNSN.js +1860 -0
  183. package/node_modules/pi-lens/dist/chunk-YLF3PPT5.js +308 -0
  184. package/node_modules/pi-lens/dist/chunk-YSNFMJKN.js +14 -0
  185. package/node_modules/pi-lens/dist/chunk-Z3CCVDUB.js +76 -0
  186. package/node_modules/pi-lens/dist/chunk-Z54ZSOBZ.js +61 -0
  187. package/node_modules/pi-lens/dist/chunk-ZAWW3AF6.js +97 -0
  188. package/node_modules/pi-lens/dist/chunk-ZMOL6RQC.js +167 -0
  189. package/node_modules/pi-lens/dist/index.js +16456 -8335
  190. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +186 -232
  191. package/node_modules/pi-lens/dist/mcp/cli.js +137 -98
  192. package/node_modules/pi-lens/dist/mcp/server.js +22589 -1573
  193. package/node_modules/pi-lens/dist/mcp/worker.js +97 -38
  194. package/node_modules/pi-lens/dist/probes/installer.js +135 -0
  195. package/node_modules/pi-lens/dist/workers/project-snapshot-persist-worker.js +22 -0
  196. package/node_modules/pi-lens/dist/workers/review-graph-persist-worker.js +15 -0
  197. package/node_modules/pi-lens/docs/agent-guide.md +13 -4
  198. package/node_modules/pi-lens/docs/agent-tools.md +42 -0
  199. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +3 -2
  200. package/node_modules/pi-lens/docs/configuration.md +20 -1
  201. package/node_modules/pi-lens/docs/environment-variables.md +52 -2
  202. package/node_modules/pi-lens/docs/features.md +8 -4
  203. package/node_modules/pi-lens/docs/globalconfig.md +1 -0
  204. package/node_modules/pi-lens/docs/io-bridge-v2-migration.md +94 -0
  205. package/node_modules/pi-lens/docs/lsp-capability-matrix.md +36 -4
  206. package/node_modules/pi-lens/docs/lsp-idle-eviction.md +124 -0
  207. package/node_modules/pi-lens/docs/mcp.md +21 -5
  208. package/node_modules/pi-lens/docs/merge-queue-rollout.md +77 -0
  209. package/node_modules/pi-lens/docs/pi-lens-fixer.md +156 -88
  210. package/node_modules/pi-lens/docs/pi-lens-investigator.md +74 -26
  211. package/node_modules/pi-lens/docs/pi-lens-merge-policy.md +694 -0
  212. package/node_modules/pi-lens/docs/pi-lens-monitor.md +73 -7
  213. package/node_modules/pi-lens/docs/pi-lens-retro.md +6 -4
  214. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +188 -48
  215. package/node_modules/pi-lens/docs/pi-lens-subagent.md +246 -45
  216. package/node_modules/pi-lens/docs/pi-lens-warden.md +18 -7
  217. package/node_modules/pi-lens/docs/public-api-stability.md +55 -0
  218. package/node_modules/pi-lens/docs/release-qa-baseline.md +84 -17
  219. package/node_modules/pi-lens/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
  220. package/node_modules/pi-lens/docs/servercapabilities.md +53 -49
  221. package/node_modules/pi-lens/docs/settings.md +1 -0
  222. package/node_modules/pi-lens/docs/usage.md +5 -1
  223. package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm +0 -0
  224. package/node_modules/pi-lens/grammars/tree-sitter-bash.wasm.json +3 -3
  225. package/node_modules/pi-lens/package.json +18 -6
  226. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  227. package/node_modules/pi-lens/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  228. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +1275 -62
  229. package/node_modules/pi-lens/scripts/download-grammars.js +5 -0
  230. package/node_modules/pi-lens/scripts/grammars.lock.json +6 -1
  231. package/node_modules/pi-lens/scripts/install-selftest.mjs +33 -34
  232. package/node_modules/pi-lens/scripts/lib/host-provided-deps.mjs +13 -4
  233. package/node_modules/pi-lens/scripts/lib/web-tree-sitter-dir.mjs +18 -0
  234. package/node_modules/pi-typesafe/README.md +1 -1
  235. package/node_modules/pi-typesafe/dist/backends.d.ts +15 -5
  236. package/node_modules/pi-typesafe/dist/backends.js +18 -0
  237. package/node_modules/pi-typesafe/dist/client.d.ts +4 -3
  238. package/node_modules/pi-typesafe/dist/client.js +22 -7
  239. package/node_modules/pi-typesafe/dist/index.d.ts +2 -2
  240. package/node_modules/pi-typesafe/dist/index.js +1 -1
  241. package/node_modules/pi-typesafe/dist/usage.d.ts +14 -4
  242. package/node_modules/pi-typesafe/dist/usage.js +147 -42
  243. package/node_modules/pi-typesafe/package.json +1 -1
  244. package/node_modules/pi-web-access/CHANGELOG.md +48 -0
  245. package/node_modules/pi-web-access/README.md +57 -11
  246. package/node_modules/pi-web-access/brave-rate-limit.ts +8 -2
  247. package/node_modules/pi-web-access/curator-page.ts +5 -1
  248. package/node_modules/pi-web-access/curator-server.ts +2 -0
  249. package/node_modules/pi-web-access/declared-web-links.ts +2 -2
  250. package/node_modules/pi-web-access/degoog.ts +323 -0
  251. package/node_modules/pi-web-access/dist/index.js +3483 -2745
  252. package/node_modules/pi-web-access/dist/mcp-cli.js +27443 -0
  253. package/node_modules/pi-web-access/exa.ts +5 -1
  254. package/node_modules/pi-web-access/extract.ts +41 -3
  255. package/node_modules/pi-web-access/firecrawl.ts +35 -4
  256. package/node_modules/pi-web-access/gemini-search.ts +34 -11
  257. package/node_modules/pi-web-access/gemini-web.ts +14 -9
  258. package/node_modules/pi-web-access/index.ts +153 -1202
  259. package/node_modules/pi-web-access/keenable.ts +221 -0
  260. package/node_modules/pi-web-access/mcp-cli.ts +40 -0
  261. package/node_modules/pi-web-access/mcp-server.ts +81 -0
  262. package/node_modules/pi-web-access/mcp-tool-definitions.ts +117 -0
  263. package/node_modules/pi-web-access/openai-search.ts +34 -1
  264. package/node_modules/pi-web-access/package.json +23 -5
  265. package/node_modules/pi-web-access/perplexity.ts +64 -56
  266. package/node_modules/pi-web-access/tool-arguments.ts +20 -0
  267. package/node_modules/pi-web-access/video-extract.ts +1 -1
  268. package/node_modules/pi-web-access/web-tool-contract.ts +86 -0
  269. package/node_modules/pi-web-access/web-tool-core.ts +1502 -0
  270. package/node_modules/pi-web-access/youtube-extract.ts +2 -5
  271. package/package.json +17 -12
  272. package/node_modules/@dietrichgebert/ponytail/README.es.md +0 -329
  273. package/node_modules/@dietrichgebert/ponytail/README.ko.md +0 -346
  274. package/node_modules/@dietrichgebert/ponytail/assets/benchmark-3model.svg +0 -21
  275. package/node_modules/@dietrichgebert/ponytail/assets/benchmark-agentic.svg +0 -62
  276. package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.png +0 -0
  277. package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.svg +0 -115
  278. package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt-dark.svg +0 -27
  279. package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt.svg +0 -27
  280. package/node_modules/@dietrichgebert/ponytail/assets/logo.png +0 -0
  281. package/node_modules/@dietrichgebert/ponytail/assets/retriever-icon.png +0 -0
  282. package/node_modules/@dietrichgebert/ponytail/assets/retriever-logo-dark.svg +0 -4
  283. package/node_modules/@dietrichgebert/ponytail/assets/retriever-logo-light.svg +0 -4
  284. package/node_modules/@dietrichgebert/ponytail/assets/social-preview.png +0 -0
  285. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-es.png +0 -0
  286. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-ko.png +0 -0
  287. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner.png +0 -0
  288. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +0 -35
  289. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +0 -1610
  290. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +0 -593
  291. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +0 -147
  292. package/node_modules/pi-lens/dist/clients/agent-nudge.js +0 -325
  293. package/node_modules/pi-lens/dist/clients/analysed-root.js +0 -1
  294. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +0 -731
  295. package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +0 -146
  296. package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +0 -118
  297. package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -10
  298. package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +0 -154
  299. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +0 -75
  300. package/node_modules/pi-lens/dist/clients/atomic-write.js +0 -189
  301. package/node_modules/pi-lens/dist/clients/availability-probe-flight.js +0 -12
  302. package/node_modules/pi-lens/dist/clients/bash-file-access.js +0 -1056
  303. package/node_modules/pi-lens/dist/clients/biome-client.js +0 -357
  304. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +0 -837
  305. package/node_modules/pi-lens/dist/clients/blocker-past-eof.js +0 -129
  306. package/node_modules/pi-lens/dist/clients/bootstrap.js +0 -569
  307. package/node_modules/pi-lens/dist/clients/bounded-cache.js +0 -190
  308. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +0 -202
  309. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +0 -295
  310. package/node_modules/pi-lens/dist/clients/build-identity.js +0 -95
  311. package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +0 -113
  312. package/node_modules/pi-lens/dist/clients/bus-events-logger.js +0 -105
  313. package/node_modules/pi-lens/dist/clients/bus-publish.js +0 -171
  314. package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +0 -190
  315. package/node_modules/pi-lens/dist/clients/cache-manager.js +0 -524
  316. package/node_modules/pi-lens/dist/clients/cache-observability.js +0 -1313
  317. package/node_modules/pi-lens/dist/clients/call-graph.js +0 -852
  318. package/node_modules/pi-lens/dist/clients/cargo-manifest.js +0 -422
  319. package/node_modules/pi-lens/dist/clients/cascade-budget.js +0 -196
  320. package/node_modules/pi-lens/dist/clients/cascade-format.js +0 -315
  321. package/node_modules/pi-lens/dist/clients/cascade-logger.js +0 -31
  322. package/node_modules/pi-lens/dist/clients/cascade-types.js +0 -9
  323. package/node_modules/pi-lens/dist/clients/child-unref.js +0 -124
  324. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +0 -286
  325. package/node_modules/pi-lens/dist/clients/codebase-model.js +0 -173
  326. package/node_modules/pi-lens/dist/clients/collateral-test-role.js +0 -40
  327. package/node_modules/pi-lens/dist/clients/complexity-client.js +0 -462
  328. package/node_modules/pi-lens/dist/clients/config-core/deny.js +0 -221
  329. package/node_modules/pi-lens/dist/clients/config-core/index.js +0 -50
  330. package/node_modules/pi-lens/dist/clients/config-core/merge.js +0 -357
  331. package/node_modules/pi-lens/dist/clients/config-core/normalize.js +0 -340
  332. package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +0 -248
  333. package/node_modules/pi-lens/dist/clients/config-core/provenance.js +0 -164
  334. package/node_modules/pi-lens/dist/clients/config-core/records.js +0 -218
  335. package/node_modules/pi-lens/dist/clients/config-core/resolve.js +0 -125
  336. package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +0 -78
  337. package/node_modules/pi-lens/dist/clients/config-core/schema.js +0 -165
  338. package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +0 -285
  339. package/node_modules/pi-lens/dist/clients/config-locations.js +0 -388
  340. package/node_modules/pi-lens/dist/clients/config-resolve.js +0 -798
  341. package/node_modules/pi-lens/dist/clients/config-schema.js +0 -251
  342. package/node_modules/pi-lens/dist/clients/config-warn.js +0 -407
  343. package/node_modules/pi-lens/dist/clients/console-guard-install.js +0 -26
  344. package/node_modules/pi-lens/dist/clients/cooperative-budget.js +0 -42
  345. package/node_modules/pi-lens/dist/clients/dead-code-client.js +0 -510
  346. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +0 -30
  347. package/node_modules/pi-lens/dist/clients/deadline-utils.js +0 -280
  348. package/node_modules/pi-lens/dist/clients/debug-handles.js +0 -211
  349. package/node_modules/pi-lens/dist/clients/debug-heap.js +0 -174
  350. package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +0 -106
  351. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +0 -426
  352. package/node_modules/pi-lens/dist/clients/demoted-finding-render.js +0 -169
  353. package/node_modules/pi-lens/dist/clients/dependency-checker.js +0 -885
  354. package/node_modules/pi-lens/dist/clients/deps/ast-grep-napi.js +0 -22
  355. package/node_modules/pi-lens/dist/clients/deps/js-yaml.js +0 -9
  356. package/node_modules/pi-lens/dist/clients/deps/minimatch.js +0 -4
  357. package/node_modules/pi-lens/dist/clients/deps/pi-tui.js +0 -14
  358. package/node_modules/pi-lens/dist/clients/deps/typebox.js +0 -14
  359. package/node_modules/pi-lens/dist/clients/deps/vscode-jsonrpc.js +0 -1
  360. package/node_modules/pi-lens/dist/clients/deps/web-tree-sitter.js +0 -24
  361. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +0 -630
  362. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +0 -305
  363. package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +0 -73
  364. package/node_modules/pi-lens/dist/clients/diagnostic-tracker.js +0 -105
  365. package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +0 -230
  366. package/node_modules/pi-lens/dist/clients/dispatch/ast-grep-catalog.js +0 -65
  367. package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +0 -343
  368. package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -35
  369. package/node_modules/pi-lens/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
  370. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +0 -1269
  371. package/node_modules/pi-lens/dist/clients/dispatch/fact-provider-types.js +0 -1
  372. package/node_modules/pi-lens/dist/clients/dispatch/fact-rule-runner.js +0 -17
  373. package/node_modules/pi-lens/dist/clients/dispatch/fact-runner.js +0 -30
  374. package/node_modules/pi-lens/dist/clients/dispatch/fact-scheduler.js +0 -68
  375. package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +0 -377
  376. package/node_modules/pi-lens/dist/clients/dispatch/facts/comment-facts.js +0 -22
  377. package/node_modules/pi-lens/dist/clients/dispatch/facts/file-content.js +0 -19
  378. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +0 -348
  379. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +0 -204
  380. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
  381. package/node_modules/pi-lens/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
  382. package/node_modules/pi-lens/dist/clients/dispatch/finding-policy.js +0 -339
  383. package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +0 -417
  384. package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +0 -89
  385. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +0 -2377
  386. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -11
  387. package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +0 -87
  388. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -278
  389. package/node_modules/pi-lens/dist/clients/dispatch/priorities.js +0 -20
  390. package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +0 -50
  391. package/node_modules/pi-lens/dist/clients/dispatch/rule-ignores.js +0 -69
  392. package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +0 -135
  393. package/node_modules/pi-lens/dist/clients/dispatch/rules/async-noise.js +0 -40
  394. package/node_modules/pi-lens/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  395. package/node_modules/pi-lens/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
  396. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-obscuring.js +0 -32
  397. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +0 -31
  398. package/node_modules/pi-lens/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
  399. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +0 -72
  400. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +0 -74
  401. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
  402. package/node_modules/pi-lens/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
  403. package/node_modules/pi-lens/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
  404. package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
  405. package/node_modules/pi-lens/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  406. package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
  407. package/node_modules/pi-lens/dist/clients/dispatch/runner-context.js +0 -52
  408. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -111
  409. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
  410. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -296
  411. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +0 -219
  412. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -82
  413. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -416
  414. package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -183
  415. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -176
  416. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -164
  417. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -195
  418. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -137
  419. package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -29
  420. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -69
  421. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -167
  422. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +0 -104
  423. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -135
  424. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -91
  425. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -171
  426. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +0 -940
  427. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -117
  428. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +0 -108
  429. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -99
  430. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -110
  431. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -379
  432. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -167
  433. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -102
  434. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +0 -414
  435. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -85
  436. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -120
  437. package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -62
  438. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
  439. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +0 -169
  440. package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -99
  441. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +0 -88
  442. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +0 -256
  443. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +0 -173
  444. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -102
  445. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +0 -128
  446. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -259
  447. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -183
  448. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -166
  449. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -163
  450. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -174
  451. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -168
  452. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -125
  453. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -643
  454. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -253
  455. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
  456. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
  457. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
  458. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
  459. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
  460. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
  461. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
  462. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
  463. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -15
  464. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -128
  465. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
  466. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +0 -95
  467. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -79
  468. package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +0 -79
  469. package/node_modules/pi-lens/dist/clients/dispatch/tool-profile.js +0 -30
  470. package/node_modules/pi-lens/dist/clients/dispatch/types.js +0 -21
  471. package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +0 -45
  472. package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
  473. package/node_modules/pi-lens/dist/clients/disposition-logger.js +0 -32
  474. package/node_modules/pi-lens/dist/clients/disposition-publish.js +0 -124
  475. package/node_modules/pi-lens/dist/clients/durable-store.js +0 -97
  476. package/node_modules/pi-lens/dist/clients/effective-config.js +0 -415
  477. package/node_modules/pi-lens/dist/clients/env-utils.js +0 -83
  478. package/node_modules/pi-lens/dist/clients/error-class.js +0 -23
  479. package/node_modules/pi-lens/dist/clients/eval-timestamp.js +0 -17
  480. package/node_modules/pi-lens/dist/clients/event-loop-hold.js +0 -274
  481. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +0 -250
  482. package/node_modules/pi-lens/dist/clients/extension-log.js +0 -504
  483. package/node_modules/pi-lens/dist/clients/extension-mode.js +0 -73
  484. package/node_modules/pi-lens/dist/clients/feature-hints.js +0 -103
  485. package/node_modules/pi-lens/dist/clients/file-kinds.js +0 -412
  486. package/node_modules/pi-lens/dist/clients/file-role.js +0 -134
  487. package/node_modules/pi-lens/dist/clients/file-time.js +0 -160
  488. package/node_modules/pi-lens/dist/clients/file-utils.js +0 -1032
  489. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +0 -494
  490. package/node_modules/pi-lens/dist/clients/finding-identity.js +0 -88
  491. package/node_modules/pi-lens/dist/clients/fix-worklog.js +0 -103
  492. package/node_modules/pi-lens/dist/clients/format-events-publish.js +0 -343
  493. package/node_modules/pi-lens/dist/clients/format-service.js +0 -222
  494. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +0 -9
  495. package/node_modules/pi-lens/dist/clients/formatters.js +0 -2032
  496. package/node_modules/pi-lens/dist/clients/freshness-cadence.js +0 -17
  497. package/node_modules/pi-lens/dist/clients/freshness.js +0 -38
  498. package/node_modules/pi-lens/dist/clients/generated-artifacts.js +0 -394
  499. package/node_modules/pi-lens/dist/clients/generation-guard.js +0 -215
  500. package/node_modules/pi-lens/dist/clients/git-guard.js +0 -1136
  501. package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +0 -243
  502. package/node_modules/pi-lens/dist/clients/gitleaks-client.js +0 -509
  503. package/node_modules/pi-lens/dist/clients/go-client.js +0 -104
  504. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +0 -605
  505. package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +0 -348
  506. package/node_modules/pi-lens/dist/clients/grammar-source.js +0 -465
  507. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +0 -135
  508. package/node_modules/pi-lens/dist/clients/hashline-anchor.js +0 -424
  509. package/node_modules/pi-lens/dist/clients/hook-budgets.js +0 -76
  510. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +0 -140
  511. package/node_modules/pi-lens/dist/clients/host-ports.js +0 -39
  512. package/node_modules/pi-lens/dist/clients/indent-retarget.js +0 -154
  513. package/node_modules/pi-lens/dist/clients/inline-blocker-dispositions.js +0 -186
  514. package/node_modules/pi-lens/dist/clients/install-diagnostics.js +0 -156
  515. package/node_modules/pi-lens/dist/clients/installer/index.js +0 -5416
  516. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh-session.js +0 -58
  517. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +0 -783
  518. package/node_modules/pi-lens/dist/clients/instance-reaper-state.js +0 -7
  519. package/node_modules/pi-lens/dist/clients/instance-reaper.js +0 -1137
  520. package/node_modules/pi-lens/dist/clients/instance-registry-lock.js +0 -145
  521. package/node_modules/pi-lens/dist/clients/instance-registry.js +0 -773
  522. package/node_modules/pi-lens/dist/clients/jscpd-client.js +0 -378
  523. package/node_modules/pi-lens/dist/clients/json-cache-read.js +0 -65
  524. package/node_modules/pi-lens/dist/clients/knip-client.js +0 -788
  525. package/node_modules/pi-lens/dist/clients/language-policy.js +0 -252
  526. package/node_modules/pi-lens/dist/clients/language-profile.js +0 -361
  527. package/node_modules/pi-lens/dist/clients/language-registry.js +0 -603
  528. package/node_modules/pi-lens/dist/clients/latency-logger.js +0 -727
  529. package/node_modules/pi-lens/dist/clients/lazy-import.js +0 -21
  530. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +0 -54
  531. package/node_modules/pi-lens/dist/clients/lens-config.js +0 -404
  532. package/node_modules/pi-lens/dist/clients/lens-engine.js +0 -358
  533. package/node_modules/pi-lens/dist/clients/lens-events.js +0 -125
  534. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +0 -467
  535. package/node_modules/pi-lens/dist/clients/lens-map.js +0 -1156
  536. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +0 -74
  537. package/node_modules/pi-lens/dist/clients/log-cleanup.js +0 -222
  538. package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +0 -178
  539. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +0 -421
  540. package/node_modules/pi-lens/dist/clients/lsp/client.js +0 -4593
  541. package/node_modules/pi-lens/dist/clients/lsp/config.js +0 -691
  542. package/node_modules/pi-lens/dist/clients/lsp/content-limits.js +0 -41
  543. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +0 -225
  544. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +0 -467
  545. package/node_modules/pi-lens/dist/clients/lsp/edits.js +0 -1219
  546. package/node_modules/pi-lens/dist/clients/lsp/index.js +0 -8305
  547. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +0 -216
  548. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +0 -298
  549. package/node_modules/pi-lens/dist/clients/lsp/language.js +0 -63
  550. package/node_modules/pi-lens/dist/clients/lsp/launch.js +0 -746
  551. package/node_modules/pi-lens/dist/clients/lsp/lombok.js +0 -158
  552. package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +0 -5
  553. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +0 -251
  554. package/node_modules/pi-lens/dist/clients/lsp/position-encoding.js +0 -61
  555. package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +0 -83
  556. package/node_modules/pi-lens/dist/clients/lsp/server.js +0 -3290
  557. package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +0 -192
  558. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +0 -17
  559. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -56
  560. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +0 -332
  561. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  562. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +0 -85
  563. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/index.js +0 -10
  564. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +0 -392
  565. package/node_modules/pi-lens/dist/clients/lsp/watch-queue.js +0 -61
  566. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
  567. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
  568. package/node_modules/pi-lens/dist/clients/lsp/workspace-sweep-hold.js +0 -184
  569. package/node_modules/pi-lens/dist/clients/lsp-budget.js +0 -186
  570. package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +0 -110
  571. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +0 -9
  572. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +0 -396
  573. package/node_modules/pi-lens/dist/clients/lsp-status.js +0 -59
  574. package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +0 -40
  575. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +0 -420
  576. package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +0 -31
  577. package/node_modules/pi-lens/dist/clients/mcp/ipc.js +0 -523
  578. package/node_modules/pi-lens/dist/clients/mcp/review.js +0 -197
  579. package/node_modules/pi-lens/dist/clients/mcp/session.js +0 -412
  580. package/node_modules/pi-lens/dist/clients/memory-sampler.js +0 -208
  581. package/node_modules/pi-lens/dist/clients/message-end-attribution.js +0 -30
  582. package/node_modules/pi-lens/dist/clients/metrics-client.js +0 -107
  583. package/node_modules/pi-lens/dist/clients/metrics-history.js +0 -327
  584. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +0 -263
  585. package/node_modules/pi-lens/dist/clients/model-provider.js +0 -53
  586. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +0 -189
  587. package/node_modules/pi-lens/dist/clients/module-report.js +0 -2150
  588. package/node_modules/pi-lens/dist/clients/mutating-tool.js +0 -651
  589. package/node_modules/pi-lens/dist/clients/mutation-attribution.js +0 -368
  590. package/node_modules/pi-lens/dist/clients/mutation-bridge.js +0 -240
  591. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +0 -734
  592. package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +0 -101
  593. package/node_modules/pi-lens/dist/clients/observed-mutation.js +0 -1253
  594. package/node_modules/pi-lens/dist/clients/oldtext-autopatch.js +0 -128
  595. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +0 -496
  596. package/node_modules/pi-lens/dist/clients/opengrep-client.js +0 -333
  597. package/node_modules/pi-lens/dist/clients/opengrep-config.js +0 -76
  598. package/node_modules/pi-lens/dist/clients/package-manager.js +0 -607
  599. package/node_modules/pi-lens/dist/clients/package-root.js +0 -38
  600. package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +0 -439
  601. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +0 -43
  602. package/node_modules/pi-lens/dist/clients/path-keyed-map.js +0 -108
  603. package/node_modules/pi-lens/dist/clients/path-utils.js +0 -1244
  604. package/node_modules/pi-lens/dist/clients/performance-report.js +0 -331
  605. package/node_modules/pi-lens/dist/clients/persist-debounce.js +0 -70
  606. package/node_modules/pi-lens/dist/clients/persistent-reverify.js +0 -271
  607. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +0 -119
  608. package/node_modules/pi-lens/dist/clients/pipeline.js +0 -1480
  609. package/node_modules/pi-lens/dist/clients/post-autofix-notice.js +0 -37
  610. package/node_modules/pi-lens/dist/clients/print-mode.js +0 -21
  611. package/node_modules/pi-lens/dist/clients/probe-home-state.js +0 -228
  612. package/node_modules/pi-lens/dist/clients/process-bridge.js +0 -66
  613. package/node_modules/pi-lens/dist/clients/process-singletons.js +0 -210
  614. package/node_modules/pi-lens/dist/clients/process-snapshot.js +0 -68
  615. package/node_modules/pi-lens/dist/clients/project-changes.js +0 -181
  616. package/node_modules/pi-lens/dist/clients/project-conventions.js +0 -171
  617. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +0 -137
  618. package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +0 -109
  619. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
  620. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
  621. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
  622. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
  623. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
  624. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
  625. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
  626. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
  627. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
  628. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
  629. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
  630. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +0 -520
  631. package/node_modules/pi-lens/dist/clients/project-diagnostics/types.js +0 -1
  632. package/node_modules/pi-lens/dist/clients/project-lens-config.js +0 -807
  633. package/node_modules/pi-lens/dist/clients/project-report.js +0 -701
  634. package/node_modules/pi-lens/dist/clients/project-scale.js +0 -237
  635. package/node_modules/pi-lens/dist/clients/project-scan-policy.js +0 -11
  636. package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +0 -48
  637. package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +0 -20
  638. package/node_modules/pi-lens/dist/clients/project-snapshot.js +0 -1653
  639. package/node_modules/pi-lens/dist/clients/project-trust.js +0 -181
  640. package/node_modules/pi-lens/dist/clients/python-environment.js +0 -217
  641. package/node_modules/pi-lens/dist/clients/python-provenance.js +0 -639
  642. package/node_modules/pi-lens/dist/clients/quiet-window-config.js +0 -47
  643. package/node_modules/pi-lens/dist/clients/quiet-window.js +0 -236
  644. package/node_modules/pi-lens/dist/clients/read-bridge.js +0 -139
  645. package/node_modules/pi-lens/dist/clients/read-expansion.js +0 -266
  646. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +0 -251
  647. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +0 -1306
  648. package/node_modules/pi-lens/dist/clients/read-guard.js +0 -1561
  649. package/node_modules/pi-lens/dist/clients/recent-touches.js +0 -240
  650. package/node_modules/pi-lens/dist/clients/redact/secrets.js +0 -449
  651. package/node_modules/pi-lens/dist/clients/resource-sampler.js +0 -628
  652. package/node_modules/pi-lens/dist/clients/reverse-deps.js +0 -270
  653. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +0 -5126
  654. package/node_modules/pi-lens/dist/clients/review-graph/format.js +0 -33
  655. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +0 -163
  656. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +0 -481
  657. package/node_modules/pi-lens/dist/clients/review-graph/persist-worker.js +0 -10
  658. package/node_modules/pi-lens/dist/clients/review-graph/query.js +0 -244
  659. package/node_modules/pi-lens/dist/clients/review-graph/revision-drift.js +0 -21
  660. package/node_modules/pi-lens/dist/clients/review-graph/service.js +0 -96
  661. package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +0 -82
  662. package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +0 -103
  663. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +0 -299
  664. package/node_modules/pi-lens/dist/clients/review-graph/types.js +0 -1
  665. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +0 -449
  666. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +0 -81
  667. package/node_modules/pi-lens/dist/clients/ruff-client.js +0 -179
  668. package/node_modules/pi-lens/dist/clients/rules-scanner.js +0 -131
  669. package/node_modules/pi-lens/dist/clients/run-duration.js +0 -55
  670. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +0 -746
  671. package/node_modules/pi-lens/dist/clients/runtime-config.js +0 -77
  672. package/node_modules/pi-lens/dist/clients/runtime-context.js +0 -211
  673. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +0 -1324
  674. package/node_modules/pi-lens/dist/clients/runtime-session.js +0 -2485
  675. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +0 -1295
  676. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +0 -2049
  677. package/node_modules/pi-lens/dist/clients/runtime-turn.js +0 -3767
  678. package/node_modules/pi-lens/dist/clients/rust-client.js +0 -97
  679. package/node_modules/pi-lens/dist/clients/safe-spawn.js +0 -2357
  680. package/node_modules/pi-lens/dist/clients/sanitize.js +0 -286
  681. package/node_modules/pi-lens/dist/clients/scan-utils.js +0 -25
  682. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +0 -165
  683. package/node_modules/pi-lens/dist/clients/search-read-registration.js +0 -94
  684. package/node_modules/pi-lens/dist/clients/secret-findings.js +0 -114
  685. package/node_modules/pi-lens/dist/clients/security-scan-client.js +0 -352
  686. package/node_modules/pi-lens/dist/clients/session-event-guard.js +0 -297
  687. package/node_modules/pi-lens/dist/clients/session-lifecycle.js +0 -484
  688. package/node_modules/pi-lens/dist/clients/session-start-observability.js +0 -94
  689. package/node_modules/pi-lens/dist/clients/session-state-store.js +0 -101
  690. package/node_modules/pi-lens/dist/clients/session-summary.js +0 -15
  691. package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +0 -27
  692. package/node_modules/pi-lens/dist/clients/sg-runner.js +0 -876
  693. package/node_modules/pi-lens/dist/clients/sgconfig.js +0 -347
  694. package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +0 -338
  695. package/node_modules/pi-lens/dist/clients/single-flight.js +0 -158
  696. package/node_modules/pi-lens/dist/clients/situational-tool-telemetry.js +0 -108
  697. package/node_modules/pi-lens/dist/clients/skills-resolver.js +0 -141
  698. package/node_modules/pi-lens/dist/clients/slow-fs.js +0 -138
  699. package/node_modules/pi-lens/dist/clients/smells-rollup.js +0 -231
  700. package/node_modules/pi-lens/dist/clients/source-filter.js +0 -596
  701. package/node_modules/pi-lens/dist/clients/source-walker.js +0 -211
  702. package/node_modules/pi-lens/dist/clients/spawn-output-cap.js +0 -120
  703. package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +0 -110
  704. package/node_modules/pi-lens/dist/clients/stale-marker.js +0 -17
  705. package/node_modules/pi-lens/dist/clients/startup-scan.js +0 -400
  706. package/node_modules/pi-lens/dist/clients/startup-timing.js +0 -130
  707. package/node_modules/pi-lens/dist/clients/string-utils.js +0 -33
  708. package/node_modules/pi-lens/dist/clients/subagent-mode.js +0 -111
  709. package/node_modules/pi-lens/dist/clients/symbol-containment.js +0 -24
  710. package/node_modules/pi-lens/dist/clients/symbol-types.js +0 -5
  711. package/node_modules/pi-lens/dist/clients/test-runner-client.js +0 -2507
  712. package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +0 -287
  713. package/node_modules/pi-lens/dist/clients/todo-scanner.js +0 -229
  714. package/node_modules/pi-lens/dist/clients/tool-agreement.js +0 -423
  715. package/node_modules/pi-lens/dist/clients/tool-config.js +0 -249
  716. package/node_modules/pi-lens/dist/clients/tool-cwd.js +0 -270
  717. package/node_modules/pi-lens/dist/clients/tool-definition.js +0 -47
  718. package/node_modules/pi-lens/dist/clients/tool-event.js +0 -105
  719. package/node_modules/pi-lens/dist/clients/tool-policy.js +0 -2755
  720. package/node_modules/pi-lens/dist/clients/tool-probe.js +0 -53
  721. package/node_modules/pi-lens/dist/clients/tool-render.js +0 -156
  722. package/node_modules/pi-lens/dist/clients/tool-set-policy.js +0 -118
  723. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +0 -364
  724. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +0 -4195
  725. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +0 -100
  726. package/node_modules/pi-lens/dist/clients/tree-sitter-navigator.js +0 -269
  727. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +0 -569
  728. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +0 -158
  729. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
  730. package/node_modules/pi-lens/dist/clients/trivy-client.js +0 -467
  731. package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -50
  732. package/node_modules/pi-lens/dist/clients/turn-context.js +0 -52
  733. package/node_modules/pi-lens/dist/clients/turn-end/lane.js +0 -51
  734. package/node_modules/pi-lens/dist/clients/turn-end/lanes/govulncheck.js +0 -112
  735. package/node_modules/pi-lens/dist/clients/turn-end/lanes/secrets.js +0 -204
  736. package/node_modules/pi-lens/dist/clients/turn-summary-render.js +0 -72
  737. package/node_modules/pi-lens/dist/clients/turn-summary.js +0 -132
  738. package/node_modules/pi-lens/dist/clients/typos-config.js +0 -29
  739. package/node_modules/pi-lens/dist/clients/user-notify.js +0 -51
  740. package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +0 -57
  741. package/node_modules/pi-lens/dist/clients/warm-attach.js +0 -305
  742. package/node_modules/pi-lens/dist/clients/widget-state.js +0 -1808
  743. package/node_modules/pi-lens/dist/clients/word-index-logger.js +0 -49
  744. package/node_modules/pi-lens/dist/clients/word-index-store.js +0 -459
  745. package/node_modules/pi-lens/dist/clients/word-index.js +0 -2080
  746. package/node_modules/pi-lens/dist/clients/workspace-topology.js +0 -443
  747. package/node_modules/pi-lens/dist/clients/write-ordering-guard.js +0 -65
  748. package/node_modules/pi-lens/dist/clients/zizmor-config.js +0 -340
  749. package/node_modules/pi-lens/dist/i18n.js +0 -69
  750. package/node_modules/pi-lens/dist/mcp/build-staleness.js +0 -124
  751. package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +0 -583
  752. package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +0 -129
  753. package/node_modules/pi-lens/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
  754. package/node_modules/pi-lens/dist/tools/activate-tools.js +0 -87
  755. package/node_modules/pi-lens/dist/tools/ast-grep-outline.js +0 -137
  756. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +0 -244
  757. package/node_modules/pi-lens/dist/tools/ast-grep-search.js +0 -762
  758. package/node_modules/pi-lens/dist/tools/effective-config.js +0 -90
  759. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +0 -375
  760. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +0 -2571
  761. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +0 -1745
  762. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +0 -1367
  763. package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +0 -294
  764. package/node_modules/pi-lens/dist/tools/module-report.js +0 -382
  765. package/node_modules/pi-lens/dist/tools/project-report.js +0 -86
  766. package/node_modules/pi-lens/dist/tools/render-compact.js +0 -374
  767. package/node_modules/pi-lens/dist/tools/scan-progress.js +0 -53
  768. package/node_modules/pi-lens/dist/tools/shared.js +0 -29
  769. package/node_modules/pi-lens/dist/tools/symbol-search.js +0 -155
@@ -1,1324 +0,0 @@
1
- import { randomBytes } from "node:crypto";
2
- import * as fs from "node:fs";
3
- import * as path from "node:path";
4
- import { logCascade } from "./cascade-logger.js";
5
- import { appendProjectChange, } from "./project-changes.js";
6
- import { normalizeMapKey, pathsEqual } from "./path-utils.js";
7
- import { PathKeyedMap } from "./path-keyed-map.js";
8
- import { BoundedLruCache } from "./bounded-cache.js";
9
- import { PartialApplyRecordStore } from "./partial-edit-apply.js";
10
- import { ReadGuard } from "./read-guard.js";
11
- import { RUNTIME_CONFIG } from "./runtime-config.js";
12
- import { TurnSummaryCollector } from "./turn-summary.js";
13
- import { deriveProviderFromModelId } from "./model-provider.js";
14
- import { beginTurnContext, setTurnContextSession } from "./turn-context.js";
15
- import { recordDegradationOnce } from "./degradation-ledger.js";
16
- /** Keep deferred cascade admission bounded without dropping late findings. */
17
- export const MAX_PENDING_CASCADE_RUNS = 32;
18
- /**
19
- * Bounded receipt ring capacity (defect shape 9: bound the axis that grows —
20
- * per-mutation receipts are unbounded across a long session). Oldest receipts
21
- * evict first; eviction is counted and surfaced via
22
- * {@link RuntimeCoordinator.droppedMutationReceiptCount} so a consumer that
23
- * needs a complete window knows the answer was truncated, never silently
24
- * incomplete (#936 honesty rule).
25
- */
26
- const MAX_MUTATION_RECEIPTS = 512;
27
- /**
28
- * Bound on in-flight tool_call → tool_result correlations. A tool_result
29
- * follows its tool_call almost immediately, so this only needs to cover
30
- * calls genuinely in flight; sized generously above any realistic
31
- * in-flight-batch width so a slow paired result is never evicted before use.
32
- */
33
- const TOOL_CALL_ATTRIBUTION_CAPACITY = 256;
34
- /**
35
- * A recorded attribution older than this is treated as expired (as if it
36
- * were never recorded) rather than trusted — defense in depth against a host
37
- * that reuses a call id, or a pathologically delayed/duplicated tool_result,
38
- * outliving the LRU capacity bound. Generous relative to any real tool
39
- * round-trip; only guards against genuine identity reuse, not slow tools.
40
- */
41
- const TOOL_CALL_ATTRIBUTION_TTL_MS = 5 * 60_000;
42
- export class RuntimeCoordinator {
43
- _projectRoot = normalizeMapKey(process.cwd());
44
- _sessionGeneration = 0;
45
- _sessionStartedAt = Date.now();
46
- _errorDebtBaseline = null;
47
- _pipelineCrashCounts = new Map();
48
- _cachedExports = new Map();
49
- _startupScansInFlight = new Map();
50
- _cascadeRuns = [];
51
- _turnEndCascadeSettleStarts = new Map();
52
- _nextCascadeSettleToken = 0;
53
- // Cascade computes are kicked off unawaited by the pipeline (#450); their
54
- // promises park here until turn_end drains them via settleCascadeRuns. Each is
55
- // guaranteed non-rejecting by the pipeline's .catch.
56
- _pendingCascadeRuns = [];
57
- _cascadeSessionStats = {
58
- runs: 0,
59
- diagnosticsSurfaced: 0,
60
- coldSnapshotTouches: 0,
61
- };
62
- _complexityBaselines = new Map();
63
- _fixedThisTurn = new PathKeyedMap(normalizeMapKey);
64
- _writtenThisTurn = new PathKeyedMap(normalizeMapKey);
65
- _autofixDemotedThisTurn = new PathKeyedMap(normalizeMapKey);
66
- _reportedThisTurn = new Set();
67
- _mutationReceipts = [];
68
- _droppedMutationReceipts = 0;
69
- _projectRulesScan = {
70
- rules: [],
71
- hasCustomRules: false,
72
- };
73
- _telemetrySessionId = `lens-${Date.now().toString(36)}`;
74
- _lifecycleReason;
75
- _hasStableSessionId = false;
76
- _telemetryModel = "unknown";
77
- // Raw model/provider identity, separate from the combined `provider/model`
78
- // display string above — worklog/disposition attribution (#1448) wants the
79
- // two fields apart, blank when the host never supplied them. `_telemetryProvider`
80
- // is the explicit host value when given, else derived from the model id
81
- // (deriveProviderFromModelId, blank on ambiguity — never guessed).
82
- _telemetryModelId = "";
83
- _telemetryProvider = "";
84
- // True once a host has supplied an explicit provider this session. An
85
- // explicit provider is never downgraded by a derivation from a later
86
- // model-only call; a DERIVED provider, by contrast, is re-derived on
87
- // every model-only call so a mid-session model switch (e.g. gpt-5-mini →
88
- // claude-sonnet-4-5) doesn't leave a stale provider from the old model.
89
- _telemetryProviderIsExplicit = false;
90
- _turnIndex = 0;
91
- _writeIndex = 0;
92
- _projectSeq = 0;
93
- _turnStartProjectSeq = 0;
94
- _fileSeq = new Map();
95
- // File key → the projectSeq value at that file's most recent bump (#451). Lets
96
- // the review-graph builder ask "which files changed since I last built?" and
97
- // skip its per-build O(project) walk+stat sweep when only pi-observed edits
98
- // occurred. Keyed identically to _fileSeq (normalizeMapKey + path.resolve).
99
- _fileLastProjectSeq = new Map();
100
- _gitGuardHasBlockers = false;
101
- _gitGuardSummary = "";
102
- _gitGuardCacheUnknownReason;
103
- callGraph = null;
104
- wordIndex = null;
105
- _readGuard = null;
106
- _pendingDeferredMutations = new PathKeyedMap(normalizeMapKey);
107
- /** tool_call → tool_result path-attribution correlation (#1642). */
108
- _toolCallAttributions = new BoundedLruCache(TOOL_CALL_ATTRIBUTION_CAPACITY);
109
- _lspReadWarmState = new Map();
110
- _pendingInlineBlockers = new PathKeyedMap(normalizeMapKey);
111
- _actionableWarningsThisTurn = new Map();
112
- _codeQualityWarningsThisTurn = new Map();
113
- // #484: opt-in per-RUN summary of diagnostics/autofixes/formats,
114
- // accumulated across the run's turns and consumed once at the
115
- // agent_settled quiet window. The collector itself is always constructed
116
- // (cheap, empty Map) but callers gate recording behind the
117
- // `lens-turn-summary` flag so it's a true no-op when the feature is off.
118
- _turnSummary = new TurnSummaryCollector();
119
- // #2402/#1053: session-scoped applied-edit records for exact-retry
120
- // recognition. Both producers (partial-apply commit, full native-edit
121
- // success) write here; the preflight consults it before declaring an
122
- // oldText miss, so an identical retry never re-executes a committed write.
123
- partialApplyRecords = new PartialApplyRecordStore();
124
- resetForSession(startedAt = Date.now()) {
125
- this._sessionGeneration += 1;
126
- this._sessionStartedAt = startedAt;
127
- this._complexityBaselines.clear();
128
- this._pipelineCrashCounts.clear();
129
- this._cachedExports.clear();
130
- this.wordIndex = null;
131
- this._startupScansInFlight.clear();
132
- this._cascadeRuns = [];
133
- this._pendingCascadeRuns = [];
134
- this._turnEndCascadeSettleStarts.clear();
135
- this._cascadeSessionStats = {
136
- runs: 0,
137
- diagnosticsSurfaced: 0,
138
- coldSnapshotTouches: 0,
139
- };
140
- this._fixedThisTurn.clear();
141
- this._writtenThisTurn.clear();
142
- this._autofixDemotedThisTurn.clear();
143
- this._reportedThisTurn.clear();
144
- this._mutationReceipts = [];
145
- this._droppedMutationReceipts = 0;
146
- this._telemetrySessionId = `lens-${Date.now().toString(36)}-${randomBytes(4).toString("hex")}`;
147
- this._hasStableSessionId = false;
148
- this._telemetryModel = "unknown";
149
- this._telemetryModelId = "";
150
- this._telemetryProvider = "";
151
- this._telemetryProviderIsExplicit = false;
152
- this._turnIndex = 0;
153
- this._writeIndex = 0;
154
- this._projectSeq = 0;
155
- this._turnStartProjectSeq = 0;
156
- this._fileSeq.clear();
157
- this._fileLastProjectSeq.clear();
158
- this._gitGuardHasBlockers = false;
159
- this._gitGuardSummary = "";
160
- this._gitGuardCacheUnknownReason = undefined;
161
- this._readGuard = null;
162
- this._pendingDeferredMutations.clear();
163
- // #1642 F5: every sibling correlation/state map is cleared here. A
164
- // per-session-numbered host reusing tool-call ids across sessions must
165
- // not let a NEW session inherit a DEAD session's recorded skip verdict.
166
- this._toolCallAttributions.clear();
167
- this._lspReadWarmState.clear();
168
- this._pendingInlineBlockers.clear();
169
- this._actionableWarningsThisTurn.clear();
170
- this._codeQualityWarningsThisTurn.clear();
171
- this._turnSummary.clear();
172
- // #2402: an applied-edit record is a fact about the session that applied
173
- // it; a new session must re-resolve identical payloads from content.
174
- this.partialApplyRecords.clear();
175
- }
176
- get sessionStartedAt() {
177
- return this._sessionStartedAt;
178
- }
179
- get cascadeSessionStats() {
180
- return this._cascadeSessionStats;
181
- }
182
- recordCascadeRun(diagnosticsSurfaced, coldSnapshotTouches) {
183
- this._cascadeSessionStats.runs += 1;
184
- this._cascadeSessionStats.diagnosticsSurfaced += diagnosticsSurfaced;
185
- this._cascadeSessionStats.coldSnapshotTouches += coldSnapshotTouches;
186
- }
187
- /**
188
- * Record the turn-end policy verdict on every live inline-blocker record
189
- * (#3248): `true` for a file whose every blocker the policy suppressed,
190
- * `false` for every other record in the map.
191
- *
192
- * ONE writer, rewriting the WHOLE axis each turn end, so the verdict can
193
- * never outlive the pass that made it: a record demoted since, or one whose
194
- * survivors came back because the file's bytes moved under a content-bound
195
- * anchor, is cleared by the same call that sets its sibling. A fresh
196
- * dispatch replaces the record wholesale (`recordInlineBlockers`), so a NEW
197
- * blocker is never born pre-suppressed (#1198 ordering).
198
- *
199
- * @returns how many records this call CHANGED — 0 means the gate's view of
200
- * the map is already what the policy just decided.
201
- */
202
- applyInlineBlockerPolicyVerdicts(suppressedFilePaths) {
203
- const suppressed = new Set(suppressedFilePaths.map((filePath) => path.resolve(filePath)));
204
- let changed = 0;
205
- for (const [key, entry] of this._pendingInlineBlockers.entries()) {
206
- const policySuppressed = suppressed.has(path.resolve(entry.filePath));
207
- if (!!entry.policySuppressed === policySuppressed)
208
- continue;
209
- this._pendingInlineBlockers.set(key, { ...entry, policySuppressed });
210
- changed += 1;
211
- }
212
- return changed;
213
- }
214
- updateGitGuardStatus(hasBlockers, output) {
215
- // The status is an aggregate over the current per-file map. A clean B
216
- // result must not erase an unresolved A result; the pipeline records/clears
217
- // the edited file immediately before this method runs.
218
- // #3248: every live record except one whose whole blocker set the
219
- // turn-end disposition policy suppressed. The record itself stays in the
220
- // map — the policy is content-bound and re-derived from the record's
221
- // diagnostics at every turn end, so dropping it there would be silencing
222
- // rather than filtering (AGENTS.md shape 10); it just stops counting for
223
- // the gate the agent was shown nothing for.
224
- const blocking = this.getInlineBlockersSnapshot().filter((entry) => !entry.policySuppressed);
225
- this._gitGuardHasBlockers = hasBlockers || blocking.length > 0;
226
- if (!this._gitGuardHasBlockers) {
227
- this._gitGuardSummary = "";
228
- return;
229
- }
230
- const firstLine = output
231
- .split("\n")
232
- .map((line) => line.trim())
233
- .find((line) => line.length > 0);
234
- const summaries = blocking
235
- .map((entry) => entry.summary.trim())
236
- .filter(Boolean);
237
- this._gitGuardSummary = (summaries[0] ??
238
- firstLine ??
239
- "Unresolved blockers detected").slice(0, 160);
240
- }
241
- get gitGuardHasBlockers() {
242
- return this._gitGuardHasBlockers;
243
- }
244
- get gitGuardSummary() {
245
- return this._gitGuardSummary;
246
- }
247
- markGitGuardCacheUnknown(reason) {
248
- this._gitGuardCacheUnknownReason = reason;
249
- }
250
- clearGitGuardCacheUnknown() {
251
- this._gitGuardCacheUnknownReason = undefined;
252
- }
253
- get gitGuardCacheUnknownReason() {
254
- return this._gitGuardCacheUnknownReason;
255
- }
256
- beginTurn() {
257
- // #1443: runs sitting here at turn_start were appended AFTER the last
258
- // turn_end drained them (consumeCascadeRuns) — the quiet-window reconcile's
259
- // late re-injection (`onResolvedFound`, clients/lsp/cascade-tier.ts) lands
260
- // in exactly that window. Wiping them dead-ended that delivery path: the
261
- // finding was computed, formatted, appended, and then deleted before any
262
- // turn_end could render it. Carry them into THIS turn instead, exactly
263
- // once: `carriedTurns` is stamped on the way through and a run that the
264
- // next turn_end still did not consume is dropped here with a log line
265
- // rather than queued forever (a stale finding must not outlive the state
266
- // it describes, and an unbounded queue would replay it every turn).
267
- this._cascadeRuns = this._cascadeRuns.flatMap((run) => {
268
- const carriedTurns = (run.carriedTurns ?? 0) + 1;
269
- if (carriedTurns > 1) {
270
- logCascade({
271
- phase: "cascade_carry_over_drop",
272
- filePath: run.filePath,
273
- neighborCount: run.neighborCount,
274
- diagnosticCount: run.diagnosticCount,
275
- metadata: { carriedTurns, turnIndex: this._turnIndex },
276
- });
277
- return [];
278
- }
279
- return [{ ...run, carriedTurns }];
280
- });
281
- // _pendingCascadeRuns is deliberately NOT cleared here: a cascade compute
282
- // still in flight past last turn_end's settle cap (fresh graph builds have
283
- // measured up to ~19s) must surface on the NEXT turn_end, not be dropped —
284
- // pre-#450 those findings were always awaited, never lost. Session reset
285
- // still clears it.
286
- // Inline blockers are session-scoped per-file state. They are cleared only
287
- // when that file is re-analyzed clean or the session resets; a new turn must
288
- // not let a clean unrelated file erase an unresolved blocker.
289
- this._actionableWarningsThisTurn.clear();
290
- this._codeQualityWarningsThisTurn.clear();
291
- // _turnSummary is deliberately NOT cleared here (#484 rework): the
292
- // summary entry is emitted once per RUN at the agent_settled quiet
293
- // window (sendMessage during a live stream would STEER the agent, and
294
- // turn_end can fire mid-stream), so the collector must accumulate
295
- // across the run's turns. It is cleared only by consume() at emit and
296
- // by resetForSession().
297
- this._turnStartProjectSeq = this._projectSeq;
298
- this._turnIndex += 1;
299
- beginTurnContext(this._telemetrySessionId);
300
- this._writeIndex = 0;
301
- this._reportedThisTurn.clear();
302
- this._writtenThisTurn.clear();
303
- this._autofixDemotedThisTurn.clear();
304
- }
305
- /**
306
- * THE one mutation seam. Every producer of an in-project file mutation —
307
- * native write/edit, recognized bash writes, format/autofix, LSP workspace
308
- * edits, and (phase 2) opaque script-write recovery — records through here,
309
- * once: it bumps the seq store (`bumpFileSeq`), appends a bounded attributed
310
- * receipt, and optionally appends the durable change-log entry. Consumers
311
- * derive from `getFilesChangedSince` / `getMutationsSince`; no producer or
312
- * consumer may hand-roll a parallel bump+log pairing (#2000 phase 1).
313
- *
314
- * Receipt recording never throws; change-log append failures route to
315
- * `onAppendError` (default: swallowed) so telemetry cannot break dispatch.
316
- */
317
- recordProjectMutation(args) {
318
- const { projectSeq, fileSeq, key } = this.bumpFileSeq(args.filePath);
319
- if (this._mutationReceipts.length >= MAX_MUTATION_RECEIPTS) {
320
- this._mutationReceipts.shift();
321
- this._droppedMutationReceipts += 1;
322
- }
323
- this._mutationReceipts.push({
324
- seq: projectSeq,
325
- // Reuse the bump's normalized key (a realpath syscall: ~200us on
326
- // Windows, ~1.8us on POSIX since #3098) — never re-derive it here.
327
- filePath: key,
328
- source: args.source,
329
- turnIndex: this._turnIndex,
330
- ts: Date.now(),
331
- });
332
- if (args.cwd !== undefined) {
333
- try {
334
- appendProjectChange(args.cwd, {
335
- seq: projectSeq,
336
- timestamp: new Date().toISOString(),
337
- sessionId: this.telemetrySessionId,
338
- turnIndex: this.turnIndex,
339
- source: args.source,
340
- filePath: path.resolve(args.filePath),
341
- fileSeq,
342
- changedRange: args.changedRange,
343
- });
344
- }
345
- catch (err) {
346
- args.onAppendError?.(err);
347
- }
348
- }
349
- return { projectSeq, fileSeq };
350
- }
351
- /**
352
- * Attributed mutations whose seq is strictly after `seq` — the receipt-level
353
- * counterpart of {@link getFilesChangedSince}. Bounded: entries evicted by
354
- * the ring cap are gone; compare `droppedMutationReceiptCount` against zero
355
- * before treating the result as a complete window.
356
- */
357
- getMutationsSince(seq) {
358
- // Shallow copies: a consumer mutating a returned receipt must not
359
- // corrupt the ring's internal state.
360
- return this._mutationReceipts
361
- .filter((r) => r.seq > seq)
362
- .map((r) => ({ ...r }));
363
- }
364
- get droppedMutationReceiptCount() {
365
- return this._droppedMutationReceipts;
366
- }
367
- /**
368
- * Atomically records write/edit ordering before debounce can coalesce it.
369
- *
370
- * Takes the classified {@link MutationKind}, not a raw tool name (#2423):
371
- * an edit-shaped tool pi-lens does not name still demotes this file to the
372
- * deferred pass, which is the safe timing.
373
- */
374
- recordMutationToolReceipt(filePath, kind) {
375
- if (kind === "write") {
376
- this._writtenThisTurn.set(filePath, true);
377
- }
378
- else if (this._writtenThisTurn.has(filePath)) {
379
- this._autofixDemotedThisTurn.set(filePath, true);
380
- // A later edit establishes a new final state that must be eligible for
381
- // the deferred pass even if the preceding write was fixed immediately.
382
- this._fixedThisTurn.delete(filePath);
383
- }
384
- return {
385
- autofixMode: kind === "edit" || this._autofixDemotedThisTurn.has(filePath)
386
- ? "deferred"
387
- : "immediate",
388
- };
389
- }
390
- get reportedThisTurn() {
391
- return this._reportedThisTurn;
392
- }
393
- nextWriteIndex() {
394
- this._writeIndex += 1;
395
- return this._writeIndex;
396
- }
397
- peekWriteIndex() {
398
- return this._writeIndex;
399
- }
400
- setTelemetryIdentity(identity) {
401
- if (identity.sessionId && identity.sessionId.trim()) {
402
- this._telemetrySessionId = identity.sessionId.trim();
403
- setTurnContextSession(this._telemetrySessionId);
404
- }
405
- const model = identity.model?.trim();
406
- const provider = identity.provider?.trim();
407
- if (model && provider) {
408
- this._telemetryModel = `${provider}/${model}`;
409
- }
410
- else if (model) {
411
- this._telemetryModel = model;
412
- }
413
- else if (provider) {
414
- this._telemetryModel = provider;
415
- }
416
- if (model)
417
- this._telemetryModelId = model;
418
- if (provider) {
419
- this._telemetryProvider = provider;
420
- this._telemetryProviderIsExplicit = true;
421
- }
422
- else if (model && !this._telemetryProviderIsExplicit) {
423
- // No explicit provider has ever been reported this session, so the
424
- // provider is (still) a derivation — re-derive it from the CURRENT
425
- // model id every time. Without this, a stale derived provider from
426
- // an earlier model would survive a mid-session model switch (e.g.
427
- // gpt-5-mini → claude-sonnet-4-5 with no explicit provider on
428
- // either call) because the old "has any provider ever been set"
429
- // guard treated the derived value as sticky. An explicit provider,
430
- // once set, is never touched here regardless of later model calls.
431
- this._telemetryProvider = deriveProviderFromModelId(model);
432
- }
433
- }
434
- get telemetrySessionId() {
435
- return this._telemetrySessionId;
436
- }
437
- /**
438
- * Pin the session identity to pi's STABLE session id and record why this
439
- * session started (#190). Called AFTER {@link resetForSession} (which assigns
440
- * a fresh random id), so the stable id — when pi provides one via
441
- * `ctx.sessionManager.getSessionId()` — wins and survives a quit→resume.
442
- */
443
- setSessionLifecycle(args) {
444
- if (args.sessionId && args.sessionId.trim()) {
445
- this._telemetrySessionId = args.sessionId.trim();
446
- this._hasStableSessionId = true;
447
- }
448
- this._lifecycleReason = args.reason;
449
- }
450
- /** Why the current session started: new | resume | fork | reload | startup. */
451
- get sessionLifecycleReason() {
452
- return this._lifecycleReason;
453
- }
454
- /** True once a stable pi session id has been pinned (vs the random fallback). */
455
- get hasStableSessionId() {
456
- return this._hasStableSessionId;
457
- }
458
- get telemetryModel() {
459
- return this._telemetryModel;
460
- }
461
- /** Raw model id (never the combined `provider/model` display string), blank
462
- * when the host hasn't reported one this session. Worklog/disposition
463
- * attribution (#1448) reads this, not {@link telemetryModel}. */
464
- get telemetryModelId() {
465
- return this._telemetryModelId;
466
- }
467
- /** Explicit host-reported provider, or a conservative derivation from the
468
- * model id (see clients/model-provider.ts), blank when neither is known. */
469
- get telemetryProviderId() {
470
- return this._telemetryProvider;
471
- }
472
- get turnIndex() {
473
- return this._turnIndex;
474
- }
475
- get projectSeq() {
476
- return this._projectSeq;
477
- }
478
- get turnStartProjectSeq() {
479
- return this._turnStartProjectSeq;
480
- }
481
- seedProjectSequence(projectSeq, fileSeqByPath) {
482
- this._projectSeq = Math.max(0, Math.floor(projectSeq));
483
- this._turnStartProjectSeq = this._projectSeq;
484
- this._fileSeq.clear();
485
- // Seeded per-file counters carry no projectSeq provenance, so start the
486
- // changed-since map empty; the graph fast path simply won't fire until an
487
- // in-process bump records a seq-stamped change (safe: falls back to sweep).
488
- this._fileLastProjectSeq.clear();
489
- for (const [filePath, seq] of fileSeqByPath ?? []) {
490
- this._fileSeq.set(normalizeMapKey(path.resolve(filePath)), Math.max(0, seq));
491
- }
492
- }
493
- bumpFileSeq(filePath) {
494
- // normalizeMapKey costs a realpath syscall per call — ~200us on Windows,
495
- // ~1.8us on POSIX since #3098; every caller that also needs the key must
496
- // reuse this one instead of paying it twice.
497
- const key = normalizeMapKey(path.resolve(filePath));
498
- this._projectSeq += 1;
499
- const fileSeq = (this._fileSeq.get(key) ?? 0) + 1;
500
- this._fileSeq.set(key, fileSeq);
501
- this._fileLastProjectSeq.set(key, this._projectSeq);
502
- return { projectSeq: this._projectSeq, fileSeq, key };
503
- }
504
- /**
505
- * Files whose most recent bump happened AFTER `seq` — i.e. every file the
506
- * review graph would need to re-ingest to catch up from a build taken at
507
- * projectSeq `seq` (#451). Returns NORMALIZED keys (normalizeMapKey +
508
- * path.resolve), the same form the builder's fileSignatures map uses, so the
509
- * caller can compare without re-normalizing.
510
- */
511
- getFilesChangedSince(seq) {
512
- const changed = [];
513
- for (const [key, lastSeq] of this._fileLastProjectSeq) {
514
- if (lastSeq > seq)
515
- changed.push(key);
516
- }
517
- return changed;
518
- }
519
- getFileSeq(filePath) {
520
- return this._fileSeq.get(normalizeMapKey(path.resolve(filePath))) ?? 0;
521
- }
522
- getFileSeqEntries() {
523
- return [...this._fileSeq.entries()];
524
- }
525
- get sessionGeneration() {
526
- return this._sessionGeneration;
527
- }
528
- isCurrentSession(generation) {
529
- return this._sessionGeneration === generation;
530
- }
531
- markStartupScanInFlight(name, generation) {
532
- this._startupScansInFlight.set(name, generation);
533
- }
534
- clearStartupScanInFlight(name, generation) {
535
- const owner = this._startupScansInFlight.get(name);
536
- if (owner === generation) {
537
- this._startupScansInFlight.delete(name);
538
- }
539
- }
540
- isStartupScanInFlight(name) {
541
- return this._startupScansInFlight.has(name);
542
- }
543
- formatPipelineCrashNotice(filePath, err) {
544
- const key = path.resolve(filePath);
545
- const count = (this._pipelineCrashCounts.get(key) ?? 0) + 1;
546
- this._pipelineCrashCounts.set(key, count);
547
- const message = err instanceof Error ? err.message : String(err);
548
- const shortMessage = message.split("\n")[0].slice(0, 220);
549
- const shouldSurface = count <= RUNTIME_CONFIG.crashNotice.alwaysShowFirstN ||
550
- count % RUNTIME_CONFIG.crashNotice.showEveryNth === 0;
551
- if (!shouldSurface)
552
- return "";
553
- return [
554
- "⚠️ pi-lens pipeline crashed while analyzing this write.",
555
- `File: ${path.basename(filePath)} | crash count this session: ${count}`,
556
- `Error: ${shortMessage}`,
557
- "Recovery: LSP service was reset. If this repeats, rerun with --no-lsp and report the file + stack.",
558
- ].join("\n");
559
- }
560
- getCrashEntries() {
561
- return Array.from(this._pipelineCrashCounts.entries());
562
- }
563
- get projectRoot() {
564
- return this._projectRoot;
565
- }
566
- set projectRoot(value) {
567
- this._projectRoot = normalizeMapKey(value);
568
- }
569
- get errorDebtBaseline() {
570
- return this._errorDebtBaseline;
571
- }
572
- set errorDebtBaseline(value) {
573
- this._errorDebtBaseline = value;
574
- }
575
- get cachedExports() {
576
- return this._cachedExports;
577
- }
578
- appendCascadeRun(run) {
579
- this._cascadeRuns.push(run);
580
- }
581
- appendCascadePromise(p) {
582
- if (this._pendingCascadeRuns.length < MAX_PENDING_CASCADE_RUNS) {
583
- this._pendingCascadeRuns.push(p);
584
- return;
585
- }
586
- // Preserve delivery for overflow rather than growing the per-edit array.
587
- // The settled run enters the same accumulator off-hook and is therefore
588
- // visible to the next turn-end drain.
589
- recordDegradationOnce({
590
- kind: "cascade-pending-cap",
591
- subject: "runtime-coordinator",
592
- reason: `deferred cascade admission capped at ${MAX_PENDING_CASCADE_RUNS}`,
593
- });
594
- void p
595
- .then((run) => this.appendCascadeRun(run))
596
- .catch(() => {
597
- // Pipeline promises are normally non-rejecting; preserve the existing
598
- // failure sink if a caller violates that contract.
599
- });
600
- }
601
- /**
602
- * The active turn_end settle clock, or undefined outside that wait.
603
- *
604
- * #1462 review F-F: every cascade compute in flight on this coordinator
605
- * reads the SAME clock. `_turnEndCascadeSettleStarts` is keyed by settle
606
- * token so `settleCascadeRuns` can distinguish its own drain from a nested
607
- * one, but this getter always answers with the latest active window —
608
- * there is one turn_end per runtime, not one per caller. A cascade begun
609
- * moments before turn_end and one begun long before it both measure elapsed
610
- * time against the same start, which is correct: they are racing the same
611
- * settle wait and share its deadline, not separate ones.
612
- */
613
- getTurnEndCascadeSettleStart() {
614
- let latest;
615
- for (const start of this._turnEndCascadeSettleStarts.values())
616
- latest = start;
617
- return latest;
618
- }
619
- /**
620
- * Drain the deferred cascade computes kicked off this turn (#450), racing them
621
- * against a bounded wait. Fulfilled runs feed the same accumulator as inline
622
- * runs (appendCascadeRun). A promise still pending at the cap is retained so a
623
- * late-resolving compute is picked up on the next turn_end rather than lost.
624
- * The stored promises never reject (pipeline guarantees an "error" skip-run).
625
- */
626
- async settleCascadeRuns(maxWaitMs, settleOptions = {}) {
627
- const pending = this._pendingCascadeRuns;
628
- if (pending.length === 0)
629
- return { settled: 0, timedOut: 0 };
630
- this._pendingCascadeRuns = [];
631
- const settleToken = settleOptions.trackTurnEndClock
632
- ? ++this._nextCascadeSettleToken
633
- : undefined;
634
- if (settleToken !== undefined) {
635
- this._turnEndCascadeSettleStarts.set(settleToken, Date.now());
636
- }
637
- try {
638
- // Track per-promise settlement so promises still in flight at the cap can be
639
- // carried over. A settled entry records its run; an unsettled one is re-parked.
640
- const tracked = pending.map((p) => {
641
- const entry = { done: false, promise: p };
642
- entry.promise = p.then((run) => {
643
- entry.done = true;
644
- entry.run = run;
645
- return run;
646
- });
647
- return entry;
648
- });
649
- const timeout = new Promise((resolve) => {
650
- setTimeout(resolve, maxWaitMs).unref?.();
651
- });
652
- await Promise.race([
653
- Promise.allSettled(tracked.map((t) => t.promise)),
654
- timeout,
655
- ]);
656
- let settled = 0;
657
- let timedOut = 0;
658
- for (const entry of tracked) {
659
- if (entry.done && entry.run) {
660
- this.appendCascadeRun(entry.run);
661
- settled += 1;
662
- }
663
- else {
664
- this._pendingCascadeRuns.push(entry.promise);
665
- timedOut += 1;
666
- }
667
- }
668
- return { settled, timedOut };
669
- }
670
- finally {
671
- if (settleToken !== undefined) {
672
- this._turnEndCascadeSettleStarts.delete(settleToken);
673
- }
674
- }
675
- }
676
- consumeCascadeRuns() {
677
- const runs = this._cascadeRuns;
678
- this._cascadeRuns = [];
679
- return runs;
680
- }
681
- /**
682
- * R1 (#1443 follow-up): non-destructive peek used by turn_end's read-only
683
- * fast path. A carried cascade run (or one still in flight) represents a
684
- * DELIVERY OPPORTUNITY, not turn activity — an agent that answers a question
685
- * without editing anything must still get yesterday's late finding. Before
686
- * this, the files-empty early return skipped `settleCascadeRuns` /
687
- * `consumeCascadeRuns` entirely on a read-only turn, so `beginTurn`'s next
688
- * carry pass saw the run as having survived a turn_start with no offsetting
689
- * drain and dropped it — burning the one-turn carry allowance on a turn that
690
- * never had a chance to deliver.
691
- */
692
- hasCascadeRuns() {
693
- // Carried, ALREADY-BUILT runs only. Pending (still-settling) computes are
694
- // deliberately excluded: a read-only turn that fell through for a pending
695
- // run would block on the full settle cap — every turn, forever, when the
696
- // compute never resolves (re-review finding F1). A pending run loses
697
- // nothing by waiting: settleCascadeRuns re-parks it and the next turn
698
- // that actually settles it delivers it.
699
- return this._cascadeRuns.length > 0;
700
- }
701
- recordInlineBlockers(filePath, summary, writeIndex, sources, lines, contentBaseline, diagnostics) {
702
- const recordedAtMs = Date.now();
703
- this._pendingInlineBlockers.set(path.resolve(filePath), {
704
- filePath,
705
- summary,
706
- writeIndex,
707
- sources,
708
- lines,
709
- diagnostics,
710
- recordedAtMs,
711
- stale: false,
712
- ...(contentBaseline
713
- ? {
714
- recordedSize: contentBaseline.size,
715
- recordedHash: contentBaseline.sha256,
716
- }
717
- : {}),
718
- });
719
- return recordedAtMs;
720
- }
721
- clearInlineBlockers(filePath) {
722
- this._pendingInlineBlockers.delete(path.resolve(filePath));
723
- }
724
- /**
725
- * #1631: demote a cached blocker to stale without dropping it (#1419
726
- * demote-not-drop). Called by the turn-boundary freshness sweep when the
727
- * file or one of its forward imports drifted on disk after the verdict.
728
- * Idempotent: re-marking an already-stale entry (for ANY reason) is a
729
- * no-op — a `"past-eof"` demotion already took this record out of the
730
- * authoritative channel, and `sweepInlineBlockerFreshness` re-checks next
731
- * turn once that heals. Returns true only when this call transitioned the
732
- * entry to stale, so a caller can log the demotion exactly once.
733
- */
734
- markInlineBlockerStale(filePath, reason = "dependency-drift") {
735
- const key = path.resolve(filePath);
736
- const existing = this._pendingInlineBlockers.get(key);
737
- if (!existing || existing.stale)
738
- return false;
739
- this._pendingInlineBlockers.set(key, {
740
- ...existing,
741
- stale: true,
742
- staleReason: reason,
743
- });
744
- return true;
745
- }
746
- /**
747
- * #1641: re-derive the past-EOF demotion for one inline-blocker record.
748
- * Unlike {@link markInlineBlockerStale} (a one-way latch for the
749
- * dependency-drift gate), this RE-ARMS: called every turn end with the
750
- * gate's freshly-computed verdict, it can both demote (rising edge) and
751
- * heal (falling edge — a transient shrink-then-restore of the file). Never
752
- * touches a record a sibling gate demoted (`staleReason !== "past-eof"`
753
- * while `stale`) — composing with #1631's dependency-drift gate means each
754
- * gate only heals its own demotions. Returns true only on an actual
755
- * transition, so the caller logs/resyncs exactly once per edge.
756
- */
757
- setInlineBlockerPastEofStale(filePath, isPastEof) {
758
- const key = path.resolve(filePath);
759
- const existing = this._pendingInlineBlockers.get(key);
760
- if (!existing)
761
- return false;
762
- if (existing.stale && existing.staleReason !== "past-eof")
763
- return false;
764
- const currentlyPastEof = !!existing.stale && existing.staleReason === "past-eof";
765
- if (currentlyPastEof === isPastEof)
766
- return false;
767
- this._pendingInlineBlockers.set(key, {
768
- ...existing,
769
- stale: isPastEof,
770
- staleReason: isPastEof ? "past-eof" : undefined,
771
- });
772
- return true;
773
- }
774
- /**
775
- * #2982: re-derive the self-drift demotion for one inline-blocker record.
776
- *
777
- * Modelled on {@link setInlineBlockerPastEofStale}, not on
778
- * {@link markInlineBlockerStale}: it RE-ARMS rather than latching, so a
779
- * file whose bytes drift and then come back (a checkout, a revert, an
780
- * editor writing the original content) un-demotes on the next sweep
781
- * instead of staying demoted for the session. That re-arm is what lets
782
- * this axis skip the #1950 delivery cap entirely — a record that can heal
783
- * needs no bounded-noise retirement, and applying the cap here would walk
784
- * an ast-grep or tree-sitter security finding out of turn-end rendering
785
- * permanently (#2982 review).
786
- *
787
- * Composes with the sibling gates the same way they compose with each
788
- * other: it never touches a record another gate demoted, and never heals a
789
- * demotion it did not make. Returns true only on an actual transition, so
790
- * the caller counts exactly one edge.
791
- */
792
- setInlineBlockerSelfDriftStale(filePath, isSelfDrift) {
793
- const key = path.resolve(filePath);
794
- const existing = this._pendingInlineBlockers.get(key);
795
- if (!existing)
796
- return false;
797
- if (existing.stale && existing.staleReason !== "self-drift")
798
- return false;
799
- const currentlySelfDrift = !!existing.stale && existing.staleReason === "self-drift";
800
- if (currentlySelfDrift === isSelfDrift)
801
- return false;
802
- // Omit the key rather than assigning `undefined` to it: under
803
- // `exactOptionalPropertyTypes` those are different, and writing the
804
- // `undefined` is a strictness spike the ratchet counts. Healing has to
805
- // drop `staleReason` off the rebuilt record, so destructure it away
806
- // instead of letting `...existing` carry the old value through.
807
- const { staleReason: _cleared, ...rest } = existing;
808
- this._pendingInlineBlockers.set(key, {
809
- ...rest,
810
- stale: isSelfDrift,
811
- ...(isSelfDrift ? { staleReason: "self-drift" } : {}),
812
- });
813
- return true;
814
- }
815
- /**
816
- * #1944: retire a past-EOF demotion after its ONE degraded delivery.
817
- *
818
- * The past-EOF gate demotes and re-arms, but nothing ever retired the
819
- * record, so a blocker whose file shrank past the cited lines re-served on
820
- * every turn end for the rest of the session — measured live at 80+
821
- * minutes on session 01a0234c. The re-serve is unbounded, not the six
822
- * turns the first evidence window suggested.
823
- *
824
- * It is unbounded because the record cannot resolve itself. The two
825
- * clearing events (`clearInlineBlockers` on a later dispatch of the same
826
- * path, `retireInlineBlockerOnConfirmedClean` on a fresh clean verdict)
827
- * both need the file to be looked at again, and the agent has no reason to
828
- * look: the coordinates it was handed do not exist. "Re-run to confirm" is
829
- * an instruction this record makes impossible to follow.
830
- *
831
- * So the delivery surface retires it after serving it once, degraded. That
832
- * is a DROP, which #1419's demote-not-drop rule normally forbids; the
833
- * exception is narrow and stated here. The finding was already delivered
834
- * this turn with its dead coordinates annotated, and what remains is a
835
- * message pinned to a line the file does not have. `deadLines` is required
836
- * and must be non-empty, so a record stale for any OTHER reason, or
837
- * past-EOF with no identified dead line, still stands.
838
- *
839
- * @returns true when an entry was retired — the caller records it, so the
840
- * suppression is never silent (#1432 Gap 1).
841
- */
842
- retireDemotedPastEofBlocker(filePath, deadLines) {
843
- if (deadLines.length === 0)
844
- return false;
845
- const key = path.resolve(filePath);
846
- const existing = this._pendingInlineBlockers.get(key);
847
- if (!existing)
848
- return false;
849
- // Only this gate's own demotion. A dependency-drift demotion (#1631)
850
- // keeps in-bounds coordinates the agent CAN re-run against, so it stays
851
- // in the store until a fresh verdict clears it.
852
- if (!existing.stale)
853
- return false;
854
- if ((existing.staleReason ?? "past-eof") !== "past-eof")
855
- return false;
856
- this._pendingInlineBlockers.delete(key);
857
- return true;
858
- }
859
- /**
860
- * #1950 fix-round F1: read the current delivery count WITHOUT committing
861
- * an increment. `runtime-turn.ts` needs the count a delivery would reach
862
- * BEFORE it knows whether that delivery will actually reach the agent —
863
- * the turn-end signature dedupe (`turn-end-findings-last`) can suppress a
864
- * turn whose rendered content is identical to the last one, and a
865
- * suppressed turn must not advance the counter (the agent never saw it).
866
- * The caller peeks, renders the tentative body, and only calls
867
- * {@link incrementInlineBlockerStaleDelivery} once it knows the turn's
868
- * content is NOT being suppressed.
869
- */
870
- peekInlineBlockerStaleDeliveryCount(filePath) {
871
- const key = path.resolve(filePath);
872
- return this._pendingInlineBlockers.get(key)?.staleDeliveryCount ?? 0;
873
- }
874
- /**
875
- * #1950: commit one more turn end that re-served this record while
876
- * `stale`. The caller (`runtime-turn.ts`) only calls this for a
877
- * `"dependency-drift"` demotion — a `"past-eof"` demotion retires after
878
- * its own single delivery (#1944, `retireDemotedPastEofBlocker`) and
879
- * never accumulates a count — and only AFTER confirming the turn's
880
- * content will not be suppressed by the signature dedupe (see
881
- * {@link peekInlineBlockerStaleDeliveryCount}), so this counts ACTUAL
882
- * deliveries the agent saw, not turn-end loop iterations. Returns the new
883
- * count, or 0 when there is no entry to count against (already retired,
884
- * or never recorded).
885
- */
886
- incrementInlineBlockerStaleDelivery(filePath) {
887
- const key = path.resolve(filePath);
888
- const existing = this._pendingInlineBlockers.get(key);
889
- if (!existing)
890
- return 0;
891
- const next = (existing.staleDeliveryCount ?? 0) + 1;
892
- this._pendingInlineBlockers.set(key, {
893
- ...existing,
894
- staleDeliveryCount: next,
895
- });
896
- return next;
897
- }
898
- /**
899
- * #1950: retire a dependency-drift demotion once it has been delivered
900
- * `DEPENDENCY_DRIFT_MAX_DELIVERIES` times with no re-run confirming or
901
- * clearing it. Unlike {@link retireDemotedPastEofBlocker}, the record is
902
- * NOT provably unrecoverable — its coordinates are still in bounds, and a
903
- * fresh dispatch of the file could still confirm or clear it. This is a
904
- * bounded-noise cap, not a "this can never resolve" verdict, and the
905
- * caller's ledger reason must say so (`demoted-finding-retired`'s "capped,
906
- * re-run can still confirm" vs. past-EOF's "retired, unrecoverable").
907
- *
908
- * Only ever touches this gate's OWN demotion (`staleReason ===
909
- * "dependency-drift"`) — a past-EOF demotion on the same file is that
910
- * gate's own record to retire, not this one's.
911
- *
912
- * @returns true when an entry was retired — the caller records it, so the
913
- * suppression is never silent (#1432 Gap 1).
914
- */
915
- retireDemotedDependencyDriftBlocker(filePath) {
916
- const key = path.resolve(filePath);
917
- const existing = this._pendingInlineBlockers.get(key);
918
- if (!existing)
919
- return false;
920
- if (!existing.stale)
921
- return false;
922
- if (existing.staleReason !== "dependency-drift")
923
- return false;
924
- this._pendingInlineBlockers.delete(key);
925
- return true;
926
- }
927
- /**
928
- * Retire a file's inline blocker because a FRESH, content-bound diagnostic
929
- * verdict proved it gone (#1561).
930
- *
931
- * The map was invalidated by exactly two events: a later dispatch of the
932
- * SAME path returning no blockers, and that path ceasing to exist (#1245).
933
- * Neither covers the common case that produced #1561 — a blocker on file F
934
- * whose cause lives in file G. Fixing G re-dispatches G, not F, so F's
935
- * verdict was never re-taken and "Unresolved from this turn" was re-injected
936
- * for the rest of the session. In the live case the agent then ran
937
- * `lsp_diagnostics` on F, pi-lens answered "confirmed clean", and the
938
- * blocker was STILL re-served on the next three turn ends: #571 wired that
939
- * tool's confirmed result into the widget footer and stopped there.
940
- *
941
- * This is the seam #1198 invariant 4 left undecided, decided: an affirmative
942
- * clean from the authoritative current view retires the stale verdict.
943
- *
944
- * Ordering (#1198 invariants 1-2). Both stores draw from the same
945
- * `nextWriteIndex()` counter, so when both sides are stamped the retire
946
- * requires the clean verdict to be strictly NEWER. A slow old clean that
947
- * settles after a fresh dispatch found real blockers must not erase them.
948
- * When either side is unstamped the two cannot be ordered at all; the fresh
949
- * confirmed verdict wins, because it is the only one of the two backed by an
950
- * actual observation of current content. Only production's single record site
951
- * is stamped, so in practice the unstamped branch is legacy callers/tests.
952
- *
953
- * COVERAGE (#1561 F1). A blocker is retired only by a verdict that can speak
954
- * for the tools that raised it. Inline blockers come from the whole dispatch,
955
- * not just the language server: `dispatcher.ts` collects every
956
- * `semantic === "blocking"` diagnostic across all runners, so eslint,
957
- * biome-check, actionlint, elixir/gleam-check and ast-grep security rules all
958
- * land in this map. A language-server check knows nothing about any of them,
959
- * so `coveredSources` must be a SUPERSET of the recorded sources or the entry
960
- * stands. This is a commit gate: a record whose provenance is unknown (no
961
- * `sources`) fails CLOSED and is never retired, because "we don't know what
962
- * raised this" must not resolve to "an LSP check can clear it".
963
- *
964
- * @returns true when an entry was retired — the caller logs it, so an
965
- * eviction is never silent (#1432 Gap 1).
966
- */
967
- retireInlineBlockerOnConfirmedClean(filePath, confirmedAtWriteIndex, coveredSources) {
968
- const key = path.resolve(filePath);
969
- const existing = this._pendingInlineBlockers.get(key);
970
- if (!existing)
971
- return false;
972
- if (existing.writeIndex !== undefined &&
973
- confirmedAtWriteIndex !== undefined &&
974
- confirmedAtWriteIndex <= existing.writeIndex) {
975
- return false;
976
- }
977
- // Fail closed on unknown provenance, and on any source the fresh verdict
978
- // did not consult. An eslint-origin blocker outliving an LSP-only clean is
979
- // the correct outcome — the next dispatch of that file is what clears it.
980
- if (!existing.sources || existing.sources.length === 0)
981
- return false;
982
- const covered = new Set(coveredSources ?? []);
983
- if (!existing.sources.every((source) => covered.has(source)))
984
- return false;
985
- this._pendingInlineBlockers.delete(key);
986
- return true;
987
- }
988
- reconcileInlineBlockers() {
989
- // Rebuild, never delete-in-place: `PathKeyedMap.delete()` re-normalizes
990
- // the key, and `normalizeMapKey` realpaths a live file but lowercases
991
- // the tail of a deleted one — so on Windows a mixed-case filename gets
992
- // a DIFFERENT delete-time key than its set-time key and the delete
993
- // misses (#1245, verified live: `MyCase.ts` survived reconcile).
994
- // Existence-checking the display path and rebuilding survivors avoids
995
- // the key-mismatch entirely; live survivors re-set to identical keys
996
- // (both realpath), so only the stale entries are dropped.
997
- const survivors = [];
998
- for (const [displayPath, value] of this._pendingInlineBlockers.entries()) {
999
- if (fs.existsSync(displayPath))
1000
- survivors.push([displayPath, value]);
1001
- }
1002
- if (survivors.length !== this._pendingInlineBlockers.size) {
1003
- this._pendingInlineBlockers.clear();
1004
- for (const [displayPath, value] of survivors) {
1005
- this._pendingInlineBlockers.set(displayPath, value);
1006
- }
1007
- }
1008
- }
1009
- /**
1010
- * Stale-entry reconcile (#1245): a blocker recorded for a file that has
1011
- * since been deleted can never be cleared — `clearInlineBlockers` fires
1012
- * only on a LATER dispatch of the same path, which a deleted file never
1013
- * gets. Every read of the blocker map (turn_end injection, git-guard
1014
- * size/summary, `syncGitGuardRecord`) therefore drops entries whose file no
1015
- * longer exists on disk: a blocker for a deleted file is stale by
1016
- * definition (the agent cannot fix it), so it must not re-surface every
1017
- * turn or gate a commit. The map is tiny (per-turn blockers) and reads are
1018
- * bounded (once per turn_end / tool_result), so the probe cost is
1019
- * negligible.
1020
- */
1021
- getInlineBlockersSnapshot() {
1022
- this.reconcileInlineBlockers();
1023
- return [...this._pendingInlineBlockers.values()];
1024
- }
1025
- consumeInlineBlockers() {
1026
- const entries = this.getInlineBlockersSnapshot();
1027
- this._pendingInlineBlockers.clear();
1028
- return entries;
1029
- }
1030
- recordActionableWarnings(warnings) {
1031
- for (const warning of warnings) {
1032
- this._actionableWarningsThisTurn.set(warning.id, warning);
1033
- }
1034
- }
1035
- peekActionableWarnings() {
1036
- return [...this._actionableWarningsThisTurn.values()];
1037
- }
1038
- clearActionableWarnings() {
1039
- this._actionableWarningsThisTurn.clear();
1040
- }
1041
- recordCodeQualityWarnings(warnings) {
1042
- for (const warning of warnings) {
1043
- this._codeQualityWarningsThisTurn.set(warning.id, warning);
1044
- }
1045
- }
1046
- peekCodeQualityWarnings() {
1047
- return [...this._codeQualityWarningsThisTurn.values()];
1048
- }
1049
- clearCodeQualityWarnings() {
1050
- this._codeQualityWarningsThisTurn.clear();
1051
- }
1052
- /** #484: the per-run diagnostics/autofix/format collector (accumulates
1053
- * across turns; consumed once at the agent_settled quiet window). Always
1054
- * present; callers gate recording behind the `lens-turn-summary` opt-in
1055
- * flag. */
1056
- get turnSummary() {
1057
- return this._turnSummary;
1058
- }
1059
- get complexityBaselines() {
1060
- return this._complexityBaselines;
1061
- }
1062
- get fixedThisTurn() {
1063
- // Self-referencing local so chained add() returns the same facade
1064
- // instead of re-entering this getter and allocating a new one per call
1065
- // (sonar S7725).
1066
- const facade = {
1067
- add: (filePath) => {
1068
- this._fixedThisTurn.set(filePath, true);
1069
- return facade;
1070
- },
1071
- has: (filePath) => this._fixedThisTurn.has(filePath),
1072
- delete: (filePath) => this._fixedThisTurn.delete(filePath),
1073
- clear: () => this._fixedThisTurn.clear(),
1074
- };
1075
- return facade;
1076
- }
1077
- get projectRulesScan() {
1078
- return this._projectRulesScan;
1079
- }
1080
- set projectRulesScan(value) {
1081
- this._projectRulesScan = value;
1082
- }
1083
- get readGuard() {
1084
- this._readGuard ??= new ReadGuard(this._telemetrySessionId);
1085
- return this._readGuard;
1086
- }
1087
- /**
1088
- * Record the canonical target `tool_call` resolved for `toolCallId`
1089
- * (#1642). The paired `tool_result` claims this exactly once via
1090
- * {@link takeToolCallAttribution} instead of re-deriving a path from its
1091
- * own diff metadata.
1092
- */
1093
- recordToolCallAttribution(toolCallId, attribution) {
1094
- this._toolCallAttributions.set(toolCallId, {
1095
- ...attribution,
1096
- recordedAt: Date.now(),
1097
- });
1098
- }
1099
- /**
1100
- * One-shot claim of a previously recorded tool-call attribution. Removed
1101
- * on read: a given `tool_call`/`tool_result` pair correlates exactly once,
1102
- * and leaving it behind would let a later, unrelated `tool_result` that
1103
- * happens to reuse a stale id inherit a stranger's resolved path.
1104
- *
1105
- * An expired entry (older than `TOOL_CALL_ATTRIBUTION_TTL_MS`) is treated
1106
- * as a miss and removed rather than returned — see the constant's doc.
1107
- */
1108
- takeToolCallAttribution(toolCallId) {
1109
- const attribution = this._toolCallAttributions.get(toolCallId);
1110
- if (attribution === undefined)
1111
- return undefined;
1112
- this._toolCallAttributions.delete(toolCallId);
1113
- if (Date.now() - attribution.recordedAt > TOOL_CALL_ATTRIBUTION_TTL_MS) {
1114
- return undefined;
1115
- }
1116
- return attribution;
1117
- }
1118
- /**
1119
- * Queue one mutation kind for `filePath` at `agent_end`. Returns `true`
1120
- * when this call created a pending entry or added a new kind, and `false`
1121
- * for a same-kind re-touch. Callers publish each kind's first transition
1122
- * without spamming repeated edits before `agent_end`.
1123
- */
1124
- deferMutation(filePath, cwd,
1125
- /** Host tool name; any mutating tool, not just `write`/`edit` (#2423). */
1126
- toolName, turnStateCwd, kind, ownerSessionId, originCwd) {
1127
- const key = path.resolve(filePath);
1128
- const now = Date.now();
1129
- const resolvedOriginCwd = originCwd ?? turnStateCwd;
1130
- const existing = this._pendingDeferredMutations.get(key);
1131
- if (existing) {
1132
- const addedKind = !existing.kinds.has(kind);
1133
- existing.lastTouchedAt = now;
1134
- existing.cwd = cwd;
1135
- existing.turnStateCwd = turnStateCwd;
1136
- existing.toolNames.add(toolName);
1137
- existing.kinds.add(kind);
1138
- existing.queuedTurnIndex = this._turnIndex;
1139
- existing.queuedTurnId = `${this._telemetrySessionId}:${this._turnIndex}`;
1140
- existing.ownerSessionId = ownerSessionId;
1141
- existing.originCwd = resolvedOriginCwd;
1142
- return addedKind;
1143
- }
1144
- this._pendingDeferredMutations.set(key, {
1145
- filePath: key,
1146
- cwd,
1147
- turnStateCwd,
1148
- firstTouchedAt: now,
1149
- lastTouchedAt: now,
1150
- toolNames: new Set([toolName]),
1151
- kinds: new Set([kind]),
1152
- queuedTurnIndex: this._turnIndex,
1153
- queuedTurnId: `${this._telemetrySessionId}:${this._turnIndex}`,
1154
- ownerSessionId,
1155
- originCwd: resolvedOriginCwd,
1156
- });
1157
- return true;
1158
- }
1159
- deferFormat(filePath, cwd,
1160
- /** Host tool name; any mutating tool, not just `write`/`edit` (#2423). */
1161
- toolName, turnStateCwd, ownerSessionId, originCwd) {
1162
- return this.deferMutation(filePath, cwd, toolName, turnStateCwd, "format", ownerSessionId, originCwd);
1163
- }
1164
- get pendingDeferredFormatCount() {
1165
- return this._pendingDeferredMutations.size;
1166
- }
1167
- get pendingDeferredMutationCount() {
1168
- return this._pendingDeferredMutations.size;
1169
- }
1170
- /**
1171
- * Legacy unconditional drain — still exposed for any caller that
1172
- * genuinely wants "everything, no ownership check" (and for tests). New
1173
- * flush call sites should prefer {@link claimDeferredFormatFiles}.
1174
- */
1175
- consumeDeferredFormatFiles() {
1176
- const records = [...this._pendingDeferredMutations.values()];
1177
- this._pendingDeferredMutations.clear();
1178
- return records;
1179
- }
1180
- /**
1181
- * Ownership-filtered drain (#791). Claims and removes only the records
1182
- * this flush is entitled to:
1183
- * - `ownerSessionId` unset on the record, OR `currentSessionId` unset, OR
1184
- * they match → claimed as "same session" (the common case, and the
1185
- * fail-safe default when either side lacks a stable session id).
1186
- * - otherwise (both known, and they differ) the record belongs to a
1187
- * DIFFERENT session (e.g. a concurrent in-process secondary/subagent)
1188
- * and is left queued for its owner's own flush — UNLESS it has sat
1189
- * unclaimed longer than `staleAfterMs` (the owner presumably died), in
1190
- * which case this flush claims it as an orphan-recovery fallback ONLY
1191
- * when `currentOriginCwd` (this flush's own workspace/worktree) exactly
1192
- * matches the record's `originCwd` (the cwd it was actually queued
1193
- * under, #1642 F3 — NOT `turnStateCwd`, which is always the workspace
1194
- * root by design and so would match every session unconditionally). A
1195
- * mismatch means the record belongs to a DIFFERENT checkout/worktree
1196
- * than the one now running `agent_end` — claiming it across that
1197
- * boundary is exactly how a worktree's queued edit got formatted onto
1198
- * the parent checkout in the reported incident. It is left queued
1199
- * (NOT deleted) and logged instead: a legitimate crashed-session
1200
- * orphan from, say, a monorepo subdir must still be claimable later by
1201
- * a flush whose origin actually matches, or stay visible for
1202
- * observability — deleting it here would drop it forever with no
1203
- * origin ever able to reclaim it.
1204
- *
1205
- * Returns the claimed records, the left-queued mismatched-origin records,
1206
- * and per-skipped record why it was left behind — callers use this for
1207
- * `agent_end`'s latency-log provenance and for the "stale fallback
1208
- * fired"/"orphan mismatch" log lines.
1209
- */
1210
- claimDeferredFormatFiles(currentSessionId, now, staleAfterMs, currentOriginCwd) {
1211
- const claimed = [];
1212
- const staleClaimed = [];
1213
- const deferredToOwner = [];
1214
- const droppedOrphans = [];
1215
- for (const [key, record] of this._pendingDeferredMutations) {
1216
- const sameSession = record.ownerSessionId === undefined ||
1217
- currentSessionId === undefined ||
1218
- record.ownerSessionId === currentSessionId;
1219
- if (sameSession) {
1220
- claimed.push(record);
1221
- this._pendingDeferredMutations.delete(key);
1222
- continue;
1223
- }
1224
- const age = now - record.lastTouchedAt;
1225
- if (age > staleAfterMs) {
1226
- // #1642 F3: origin identity is required before an orphan-recovery
1227
- // claim, not just staleness. `currentOriginCwd === undefined`
1228
- // means the caller can't state its own origin — fail-safe as
1229
- // "can't prove different" (same posture as the sameSession check
1230
- // above), not as a free pass to claim across a KNOWN mismatch.
1231
- const originMatches = currentOriginCwd === undefined ||
1232
- pathsEqual(record.originCwd, currentOriginCwd);
1233
- if (originMatches) {
1234
- this._pendingDeferredMutations.delete(key);
1235
- staleClaimed.push(record);
1236
- }
1237
- else {
1238
- // Left queued — see the doc above for why this must not be
1239
- // deleted. Reported once per claim attempt; a genuinely
1240
- // abandoned origin will keep surfacing here, which is the
1241
- // intended, safer trade-off over silent, permanent loss.
1242
- droppedOrphans.push(record);
1243
- }
1244
- continue;
1245
- }
1246
- deferredToOwner.push(record);
1247
- }
1248
- return { claimed, staleClaimed, deferredToOwner, droppedOrphans };
1249
- }
1250
- /** Return claimed records that were never started by an aborted drain. */
1251
- requeueDeferredFormatFiles(records) {
1252
- for (const record of records) {
1253
- const key = path.resolve(record.filePath);
1254
- const existing = this._pendingDeferredMutations.get(key);
1255
- if (existing) {
1256
- for (const kind of record.kinds)
1257
- existing.kinds.add(kind);
1258
- for (const toolName of record.toolNames)
1259
- existing.toolNames.add(toolName);
1260
- continue;
1261
- }
1262
- this._pendingDeferredMutations.set(key, {
1263
- ...record,
1264
- kinds: new Set(record.kinds),
1265
- toolNames: new Set(record.toolNames),
1266
- });
1267
- }
1268
- }
1269
- claimDeferredMutations(currentSessionId, now, staleAfterMs, currentOriginCwd) {
1270
- return this.claimDeferredFormatFiles(currentSessionId, now, staleAfterMs, currentOriginCwd);
1271
- }
1272
- requeueDeferredMutations(records) {
1273
- this.requeueDeferredFormatFiles(records);
1274
- }
1275
- shouldWarmLspOnRead(filePath, maxAgeMs = 120_000) {
1276
- const state = this._lspReadWarmState.get(path.resolve(filePath));
1277
- if (!state)
1278
- return true;
1279
- if (state.status === "warming")
1280
- return false;
1281
- return Date.now() - state.ts > maxAgeMs;
1282
- }
1283
- markLspReadWarmStarted(filePath) {
1284
- this._lspReadWarmState.set(path.resolve(filePath), {
1285
- status: "warming",
1286
- ts: Date.now(),
1287
- });
1288
- }
1289
- markLspReadWarmCompleted(filePath) {
1290
- this._lspReadWarmState.set(path.resolve(filePath), {
1291
- status: "ready",
1292
- ts: Date.now(),
1293
- });
1294
- }
1295
- clearLspReadWarmState(filePath) {
1296
- this._lspReadWarmState.delete(path.resolve(filePath));
1297
- }
1298
- }
1299
- /**
1300
- * Read the live model identity off a pi extension context (#1655 item 2).
1301
- *
1302
- * `ExtensionContext.model` is `AgentSession.model`, projected through a lazy
1303
- * getter guarded by `assertActive()`
1304
- * (`@earendil-works/pi-coding-agent/dist/core/extensions/runner.js:488-491`;
1305
- * `dist/core/agent-session.js:580-582`). The value is a `Model` with `id` and
1306
- * `provider` (`@earendil-works/pi-ai/dist/types.d.ts:661-667`), or `undefined`
1307
- * when no model is selected.
1308
- *
1309
- * Because the getter is lazy and guarded, reading it on a REPLACED runner
1310
- * throws. Telemetry identity is advisory; a stale ctx must degrade to "no
1311
- * identity", never take down the event handler that happened to carry it.
1312
- */
1313
- export function readHostModelIdentity(ctx) {
1314
- try {
1315
- const model = ctx?.model;
1316
- return {
1317
- model: typeof model?.id === "string" ? model.id : undefined,
1318
- provider: typeof model?.provider === "string" ? model.provider : undefined,
1319
- };
1320
- }
1321
- catch {
1322
- return {};
1323
- }
1324
- }