@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,1480 +0,0 @@
1
- /**
2
- * Post-write pipeline for pi-lens
3
- *
4
- * Extracted from index.ts tool_result handler.
5
- * Runs sequentially on every file write/edit:
6
- * 1. Secrets scan (blocking — early exit)
7
- * 2. Auto-format (Biome, Prettier, Ruff, gofmt, etc.)
8
- * 3. Auto-fix (Biome --write, Ruff --fix, ESLint --fix)
9
- * 4. LSP file sync (open/update in LSP servers)
10
- * 5. Dispatch lint (type errors, security rules)
11
- * 6. Test runner (run corresponding test file)
12
- * 7. Cascade diagnostics (other files with errors, LSP only)
13
- */
14
- import { createHash } from "node:crypto";
15
- import * as nodeFs from "node:fs";
16
- import * as nodeCrypto from "node:crypto";
17
- import * as path from "node:path";
18
- import { findNearestContaining, normalizeEphemeralMapKey, } from "./path-utils.js";
19
- import { recordFromDispatchDiagnostic, } from "./actionable-warnings.js";
20
- import { recordFromCodeQualityDiagnostic, } from "./code-quality-warnings.js";
21
- import { admitWidgetDiagnosticsWrite, recordDiagnostics, } from "./widget-state.js";
22
- import { getDiagnosticLogger } from "./diagnostic-logger.js";
23
- import { getDiagnosticTracker } from "./diagnostic-tracker.js";
24
- import { loadDispatchIntegration } from "./dispatch/lazy.js";
25
- import { toRunnerDisplayPath } from "./dispatch/runner-context.js";
26
- import { classifyProbeFailure, createAvailabilityChecker, createAvailabilityLatch, describeProbeEvidence, logAvailabilityDecision, startHostStallSampler, resolveAvailableOrInstall, resolveCommandArgsWithInstallFallback, resolveToolCommand, resolveToolCommandWithInstallFallback, } from "./dispatch/runners/utils/runner-helpers.js";
27
- import { findDetektConfig } from "./dispatch/runners/detekt.js";
28
- import { formatDiagnostics } from "./dispatch/utils/format-utils.js";
29
- import { detectFileKind, getFileKindLabel } from "./file-kinds.js";
30
- import { detectFileChangedAfterCommand, getProjectIgnoreMatcher, isExcludedDirName, } from "./file-utils.js";
31
- import { logLatency } from "./latency-logger.js";
32
- import { emitLensAnalysisComplete } from "./lens-events.js";
33
- import { publishFilesTouched } from "./bus-publish.js";
34
- import { publishDiagnostics, wasPreviouslyReportedDirty, } from "./diagnostics-publish.js";
35
- import { loadLspService } from "./lsp-lazy.js";
36
- import { clearGraphCache } from "./review-graph/builder.js";
37
- import { BoundedLruCache } from "./bounded-cache.js";
38
- import { RUNTIME_CONFIG } from "./runtime-config.js";
39
- import { getAmbientAbortSignal, safeSpawnAsync } from "./safe-spawn.js";
40
- import { probeToolAsync } from "./tool-probe.js";
41
- import { bounded } from "./deadline-utils.js";
42
- import { HOOK_WALL_BUDGET_MS } from "./hook-budgets.js";
43
- import { enabledAuxiliaryLspServerIds } from "./dispatch/auxiliary-lsp.js";
44
- import { incrementDegradationCount, recordDegradationOnce, } from "./degradation-ledger.js";
45
- import { establishToolAgreement } from "./tool-agreement.js";
46
- import { dropFindingsForMissingPaths } from "./advisory-provenance.js";
47
- import { getAutofixPolicyForFile, getPreferredAutofixTools, getRubocopCommand, hasBiomeConfig, hasDetektConfig, hasEslintConfig, hasGolangciConfig, hasKtfmtConfig, hasKtlintConfig, hasOxlintConfig, hasRubocopConfig, hasSqlfluffConfig, hasStylelintConfig, markdownlintConfigArgs, } from "./tool-policy.js";
48
- import { exceedsLspSyncLimits } from "./lsp/content-limits.js";
49
- const LSP_SPAWN_BUDGET_MS = RUNTIME_CONFIG.pipeline.lspSpawnBudgetMs;
50
- const AUTOFIX_CHANGED_FILE_SCAN_LIMIT = 5000;
51
- /**
52
- * Hard ceiling for the pre-dispatch LSP sync (`resyncLspFile`). The sync sends a
53
- * didChange/didOpen; that write can backpressure indefinitely when the language
54
- * server's stdin isn't being drained (a wedged/CPU-bound server), which would
55
- * hang the whole edit with no per-call bound — client acquisition is capped, but
56
- * the notify write is not. So the sync is abandoned after this budget (the edit
57
- * proceeds; the dispatch LSP runner, which has its own 30s cap, still tries).
58
- */
59
- function lspSyncBudgetMs() {
60
- const raw = Number(process.env.PI_LENS_LSP_SYNC_BUDGET_MS);
61
- return Number.isFinite(raw) && raw > 0 ? raw : 3000;
62
- }
63
- // Files stat'd between event-loop yields. The walk stays on the tool_result
64
- // hot path; yielding every N keeps its longest synchronous stretch well under
65
- // the <50ms hook-burst budget even at the AUTOFIX_CHANGED_FILE_SCAN_LIMIT cap.
66
- const SNAPSHOT_YIELD_EVERY = 500;
67
- // Scan one directory's entries into `snapshot`, pushing walkable subdirs onto
68
- // `stack`. Yields to the event loop every SNAPSHOT_YIELD_EVERY files (shared
69
- // `counter`) so a single huge directory can't hold the loop. Excluded/ignored
70
- // dirs are not descended; ignored/vanished files are skipped.
71
- async function snapshotDirInto(dir, ignoreMatcher, stack, snapshot, counter) {
72
- let entries;
73
- try {
74
- // Async (#1137): a synchronous per-directory read blocks the loop for the
75
- // whole stall on a slow cloud-backed (OneDrive) directory; fs.promises
76
- // keeps this tool_result-path walk off the event loop.
77
- entries = await nodeFs.promises.readdir(dir, { withFileTypes: true });
78
- }
79
- catch {
80
- return;
81
- }
82
- for (const entry of entries) {
83
- const fullPath = path.join(dir, entry.name);
84
- if (entry.isDirectory()) {
85
- if (!isExcludedDirName(entry.name) &&
86
- !ignoreMatcher.isIgnored(fullPath, true)) {
87
- stack.push(fullPath);
88
- }
89
- continue;
90
- }
91
- if (!entry.isFile())
92
- continue;
93
- if (ignoreMatcher.isIgnored(fullPath, false))
94
- continue;
95
- try {
96
- const stat = await nodeFs.promises.stat(fullPath);
97
- snapshot.set(path.resolve(fullPath), {
98
- mtimeMs: stat.mtimeMs,
99
- size: stat.size,
100
- });
101
- }
102
- catch {
103
- // ignore vanished files
104
- }
105
- if (++counter.n % SNAPSHOT_YIELD_EVERY === 0) {
106
- await new Promise((resolve) => setImmediate(resolve));
107
- }
108
- }
109
- }
110
- // Exported for the event-loop occupancy guard (#361/#368): an O(files) walk on
111
- // the tool_result autofix path, bounded by AUTOFIX_CHANGED_FILE_SCAN_LIMIT and
112
- // chunk-yielding every SNAPSHOT_YIELD_EVERY files so it never blocks the TUI.
113
- export async function snapshotProjectFiles(root) {
114
- const snapshot = new Map();
115
- const projectRoot = path.resolve(root);
116
- const ignoreMatcher = getProjectIgnoreMatcher(projectRoot);
117
- // #703: prime the tracked-files set once before the walk so a tracked file
118
- // matching a `.gitignore`/global pattern still shows up in the autofix
119
- // snapshot. Fail-open on no-git/spawn failure.
120
- await ignoreMatcher.ensureTrackedIndex();
121
- const stack = [projectRoot];
122
- const counter = { n: 0 };
123
- while (stack.length > 0 && snapshot.size < AUTOFIX_CHANGED_FILE_SCAN_LIMIT) {
124
- await snapshotDirInto(stack.pop(), ignoreMatcher, stack, snapshot, counter);
125
- }
126
- return snapshot;
127
- }
128
- async function diffProjectSnapshot(root, before) {
129
- const after = await snapshotProjectFiles(root);
130
- const changed = new Set();
131
- for (const [filePath, next] of after) {
132
- const prev = before.get(filePath);
133
- if (prev?.mtimeMs !== next.mtimeMs || prev?.size !== next.size) {
134
- changed.add(filePath);
135
- }
136
- }
137
- for (const filePath of before.keys()) {
138
- if (!after.has(filePath))
139
- changed.add(filePath);
140
- }
141
- return [...changed].sort((a, b) => a.localeCompare(b));
142
- }
143
- function createPhaseTracker(toolName, filePath) {
144
- const phases = [];
145
- return {
146
- start(name) {
147
- phases.push({ name, startTime: Date.now(), ended: false });
148
- },
149
- end(name, metadata) {
150
- const p = phases.find((x) => x.name === name && !x.ended);
151
- if (p) {
152
- p.ended = true;
153
- logLatency({
154
- type: "phase",
155
- toolName,
156
- filePath,
157
- phase: name,
158
- durationMs: Date.now() - p.startTime,
159
- metadata,
160
- });
161
- }
162
- },
163
- };
164
- }
165
- // --- ESLint autofix helpers ---
166
- export { hasEslintConfig, hasSqlfluffConfig, hasStylelintConfig };
167
- /**
168
- * eslint autofix availability, per cwd + PATH. The verdict is owned by the
169
- * shared availability latch (#1494): a `missing` / `non-installable` outcome
170
- * sticks for the session, a timeout expires on a cooldown and is re-probed, so
171
- * one stalled probe cannot silently stop autofixing a project's JS/TS.
172
- */
173
- const ESLINT_FIX_PROBE_BUDGET_MS = 5000;
174
- const _eslintCache = new BoundedLruCache(32);
175
- /**
176
- * Run eslint --fix on a file. Runs a single spawn and diffs the file before/after,
177
- * same idiom as the other autofix helpers below. Exit code 1 (unfixable problems
178
- * remain) is allowed because fixes may still have been applied; only exit code 2
179
- * (config/fatal error) is treated as failure.
180
- * Returns 1 if the file changed, 0 if ESLint is not configured / not available /
181
- * made no changes.
182
- */
183
- async function tryEslintFix(filePath, cwd) {
184
- const userHasConfig = hasEslintConfig(cwd);
185
- if (!userHasConfig)
186
- return 0;
187
- // PATH is part of command resolution; include it so an install or PATH
188
- // refresh cannot leave a negative eslint result live for the session.
189
- const cacheKey = `${path.resolve(cwd)}|${process.env.PATH ?? ""}`;
190
- let cached = _eslintCache.get(cacheKey);
191
- if (!cached) {
192
- cached = { latch: createAvailabilityLatch(), bin: null };
193
- _eslintCache.set(cacheKey, cached);
194
- }
195
- if (cached.latch.read() === null) {
196
- const candidate = resolveToolCommand(cwd, "eslint") ?? "eslint";
197
- // The budget is enforced by a HOST-side timer, so a stalled event loop
198
- // expires it while eslint is still healthy. Measure the overlapping stall
199
- // and hand it to the classifier, exactly like the runner path: without it a
200
- // host-stall timeout is re-caused as `probe-timeout` and gets the escalating
201
- // 30s→300s cooldown instead of the 5s host-stall one (#1467).
202
- const stallSampler = startHostStallSampler();
203
- const startedAt = Date.now();
204
- let check;
205
- let hostStallMs;
206
- try {
207
- check = await safeSpawnAsync(candidate, ["--version"], {
208
- timeout: ESLINT_FIX_PROBE_BUDGET_MS,
209
- cwd,
210
- });
211
- }
212
- finally {
213
- hostStallMs = stallSampler.stop();
214
- }
215
- const elapsedMs = Date.now() - startedAt;
216
- const decisionCwd = path.resolve(cwd);
217
- if (!check.error && check.status === 0) {
218
- cached.bin = candidate;
219
- cached.latch.noteAvailable();
220
- logAvailabilityDecision({
221
- tool: "eslint",
222
- verdict: "available",
223
- outcome: "success",
224
- cause: "ok",
225
- elapsedMs,
226
- latched: true,
227
- hostStallMs,
228
- budgetMs: ESLINT_FIX_PROBE_BUDGET_MS,
229
- classifiedBy: "probe",
230
- evidence: describeProbeEvidence(check, "eslint"),
231
- }, decisionCwd);
232
- }
233
- else {
234
- cached.bin = null;
235
- const { outcome, cause, evidence } = classifyProbeFailure(check, {
236
- hostStallMs,
237
- command: "eslint",
238
- });
239
- const retryAfterMs = cached.latch.noteUnavailable(outcome, cause);
240
- logAvailabilityDecision({
241
- tool: "eslint",
242
- verdict: "unavailable",
243
- outcome,
244
- cause,
245
- elapsedMs,
246
- latched: retryAfterMs === 0,
247
- hostStallMs,
248
- ...(retryAfterMs > 0 && { retryAfterMs }),
249
- budgetMs: ESLINT_FIX_PROBE_BUDGET_MS,
250
- classifiedBy: "probe",
251
- evidence,
252
- }, decisionCwd);
253
- }
254
- }
255
- if (cached.latch.read() !== true || !cached.bin)
256
- return 0;
257
- const cmd = cached.bin;
258
- return detectFileChangedAfterCommand(filePath, cmd, ["--fix", "--no-error-on-unmatched-pattern", filePath], cwd, [1]);
259
- }
260
- async function tryStylelintFix(filePath, cwd) {
261
- const cmd = await resolveToolCommandWithInstallFallback(cwd, "stylelint");
262
- if (!cmd)
263
- return 0;
264
- return detectFileChangedAfterCommand(filePath, cmd, ["--fix", "--allow-empty-input", filePath], cwd, [2]);
265
- }
266
- async function trySqlfluffFix(filePath, cwd) {
267
- const cmd = await resolveToolCommandWithInstallFallback(cwd, "sqlfluff");
268
- if (!cmd)
269
- return 0;
270
- const args = ["fix", "--force", filePath];
271
- if (!hasSqlfluffConfig(cwd)) {
272
- args.splice(2, 0, "--dialect", "ansi");
273
- }
274
- return detectFileChangedAfterCommand(filePath, cmd, args, cwd);
275
- }
276
- async function tryRubocopFix(filePath, cwd) {
277
- const resolved = await resolveCommandArgsWithInstallFallback(getRubocopCommand(cwd), "rubocop", cwd, ["--version"], 10000);
278
- if (!resolved)
279
- return 0;
280
- return detectFileChangedAfterCommand(filePath, resolved.cmd, [...resolved.args, "-a", "--no-color", filePath], cwd, [1]);
281
- }
282
- async function tryKtlintFix(filePath, cwd) {
283
- const cmd = await resolveToolCommandWithInstallFallback(cwd, "ktlint");
284
- if (!cmd)
285
- return 0;
286
- return detectFileChangedAfterCommand(filePath, cmd, ["-F", filePath], cwd, [1]);
287
- }
288
- // golangci-lint/detekt/ktfmt have no TOOL_COMMAND_SPEC; resolve via availability
289
- // checkers like their runners do.
290
- const golangciAutofixChecker = createAvailabilityChecker("golangci-lint", ".exe");
291
- const detektAutofixChecker = createAvailabilityChecker("detekt", ".bat");
292
- const ktfmtAutofixChecker = createAvailabilityChecker("ktfmt", ".bat");
293
- async function tryKtfmtFix(filePath, cwd) {
294
- // Config-first: the autofix policy only reaches here when the project opted
295
- // into ktfmt, so resolveAvailableOrInstall honors that gate. ktfmt writes the
296
- // formatted file in place and exits 0; treat any byte change as the fix.
297
- const cmd = await resolveAvailableOrInstall(ktfmtAutofixChecker, "ktfmt", cwd);
298
- if (!cmd)
299
- return 0;
300
- const absPath = path.resolve(cwd, filePath);
301
- return detectFileChangedAfterCommand(filePath, cmd, [absPath], cwd, [0]);
302
- }
303
- async function tryGolangciLintFix(filePath, cwd) {
304
- // Config-first: the autofix policy only reaches here when a .golangci.* config
305
- // exists. resolveAvailableOrInstall honors that gate (won't auto-install a
306
- // config-first tool). golangci-lint exits non-zero when issues remain after
307
- // --fix, so allow its issue-found codes.
308
- const cmd = await resolveAvailableOrInstall(golangciAutofixChecker, "golangci-lint", cwd);
309
- if (!cmd)
310
- return 0;
311
- return detectFileChangedAfterCommand(filePath, cmd, ["run", "--fix", filePath], cwd, [1, 7]);
312
- }
313
- async function tryDetektFix(filePath, cwd) {
314
- const configPath = findDetektConfig(cwd);
315
- if (!configPath)
316
- return 0;
317
- if (!(await detektAutofixChecker.isAvailableAsync(cwd)))
318
- return 0;
319
- const cmd = detektAutofixChecker.getCommand(cwd);
320
- if (!cmd)
321
- return 0;
322
- const absPath = path.resolve(cwd, filePath);
323
- return detectFileChangedAfterCommand(filePath, cmd, ["--auto-correct", "--input", absPath, "--config", configPath], cwd, [1, 2]);
324
- }
325
- async function tryMarkdownlintFix(filePath, cwd) {
326
- const cmd = await resolveToolCommandWithInstallFallback(cwd, "markdownlint");
327
- if (!cmd)
328
- return 0;
329
- // Shared config-args seam (#1247): the lint runner consumes the same
330
- // builder, so the bare --fix here can never fall back to markdownlint's
331
- // default all-rules-on config again (the whole-file CHANGELOG/AGENTS
332
- // reformat + `#946` → `# 946` corruption).
333
- // markdownlint-cli2 --fix exits non-zero when unfixable violations remain.
334
- return detectFileChangedAfterCommand(filePath, cmd, [...markdownlintConfigArgs(cwd), "--fix", filePath], cwd, [1]);
335
- }
336
- async function tryOxlintFix(filePath, cwd) {
337
- const cmd = await resolveToolCommandWithInstallFallback(cwd, "oxlint");
338
- if (!cmd)
339
- return 0;
340
- return detectFileChangedAfterCommand(filePath, cmd, ["--fix", filePath], cwd, [1]);
341
- }
342
- async function tryRustClippyFix(filePath) {
343
- const check = await probeToolAsync("cargo", ["--version"], { timeout: 5000 });
344
- if (check.error || check.status !== 0)
345
- return [];
346
- const cargoDir = findNearestContaining(path.dirname(path.resolve(filePath)), [
347
- "Cargo.toml",
348
- ]);
349
- if (!cargoDir)
350
- return [];
351
- const before = await snapshotProjectFiles(cargoDir);
352
- const result = await safeSpawnAsync("cargo", ["clippy", "--fix", "--allow-dirty", "--allow-staged", "-q"], { timeout: 30000, cwd: cargoDir });
353
- if (result.error || result.status !== 0)
354
- return [];
355
- return diffProjectSnapshot(cargoDir, before);
356
- }
357
- async function tryDartFix(filePath) {
358
- const check = await probeToolAsync("dart", ["--version"], { timeout: 5000 });
359
- if (check.error || check.status !== 0)
360
- return [];
361
- const pubspecDir = findNearestContaining(path.dirname(path.resolve(filePath)), ["pubspec.yaml"]);
362
- if (!pubspecDir)
363
- return [];
364
- const before = await snapshotProjectFiles(pubspecDir);
365
- const result = await safeSpawnAsync("dart", ["fix", "--apply"], {
366
- timeout: 30000,
367
- cwd: pubspecDir,
368
- });
369
- if (result.error || result.status !== 0)
370
- return [];
371
- return diffProjectSnapshot(pubspecDir, before);
372
- }
373
- // --- Pipeline phase helpers ---
374
- export async function runAutofix(filePath, cwd, getFlag, dbg, deps, getFlagSource) {
375
- const { biomeClient, ruffClient, fixedThisTurn } = deps;
376
- const noAutofix = getFlag("no-autofix", filePath);
377
- let fixedCount = 0;
378
- const autofixTools = [];
379
- const attemptedTools = [];
380
- const changedFiles = new Set();
381
- const markTargetChanged = () => changedFiles.add(path.resolve(filePath));
382
- let needsContentRefresh = false;
383
- if (fixedThisTurn.has(filePath)) {
384
- dbg(`autofix: skipped for ${filePath} (already fixed this turn)`);
385
- return {
386
- fixedCount,
387
- autofixTools,
388
- attemptedTools,
389
- changedFiles: [],
390
- needsContentRefresh,
391
- skipReason: "already_fixed_this_turn",
392
- };
393
- }
394
- if (noAutofix) {
395
- const source = getFlagSource?.("no-autofix", filePath);
396
- dbg(`autofix: skipped for ${filePath} (--no-autofix${source ? `, source=${source}` : ""})`);
397
- return {
398
- fixedCount,
399
- autofixTools,
400
- attemptedTools,
401
- changedFiles: [],
402
- needsContentRefresh,
403
- skipReason: "disabled_by_flag",
404
- };
405
- }
406
- const autofixContext = {
407
- hasEslintConfig: hasEslintConfig(cwd),
408
- hasStylelintConfig: hasStylelintConfig(cwd),
409
- hasSqlfluffConfig: hasSqlfluffConfig(cwd),
410
- hasRubocopConfig: hasRubocopConfig(cwd),
411
- hasBiomeConfig: hasBiomeConfig(cwd),
412
- hasGolangciConfig: hasGolangciConfig(cwd),
413
- hasDetektConfig: hasDetektConfig(cwd),
414
- hasKtfmtConfig: hasKtfmtConfig(cwd),
415
- hasKtlintConfig: hasKtlintConfig(cwd),
416
- hasOxlintConfig: hasOxlintConfig(cwd),
417
- };
418
- const autofixPolicy = getAutofixPolicyForFile(filePath, autofixContext);
419
- const preferredAutofixTools = autofixPolicy?.safe
420
- ? getPreferredAutofixTools(filePath, autofixContext)
421
- : [];
422
- dbg(`autofix: policy for ${filePath} -> ${autofixPolicy?.defaultTool ?? "none"} ` +
423
- `(preferred: ${preferredAutofixTools.join(",") || "none"}, gate: ${autofixPolicy?.gate ?? "none"}, safe: ${autofixPolicy?.safe ? "yes" : "no"})`);
424
- if (!autofixPolicy) {
425
- dbg(`autofix: no policy for ${filePath}`);
426
- return {
427
- fixedCount,
428
- autofixTools,
429
- attemptedTools,
430
- changedFiles: [],
431
- needsContentRefresh,
432
- skipReason: "no_policy",
433
- };
434
- }
435
- if (!autofixPolicy.safe || preferredAutofixTools.length === 0) {
436
- dbg(`autofix: no safe preferred tools for ${filePath}`);
437
- return {
438
- fixedCount,
439
- autofixTools,
440
- attemptedTools,
441
- changedFiles: [],
442
- needsContentRefresh,
443
- skipReason: "no_safe_tools",
444
- };
445
- }
446
- for (const toolName of preferredAutofixTools) {
447
- attemptedTools.push(toolName);
448
- const agreement = establishToolAgreement(toolName, cwd);
449
- if (agreement.decision === "decline") {
450
- const reason = agreement.reason;
451
- dbg(`autofix: ${toolName} declined (${reason})`);
452
- recordDegradationOnce({
453
- kind: "autofix-agreement-unavailable",
454
- subject: agreement.subject,
455
- reason,
456
- });
457
- continue;
458
- }
459
- if (toolName === "ruff") {
460
- const ruffReady = ruffClient.isPythonFile(filePath)
461
- ? await ruffClient.ensureAvailable()
462
- : false;
463
- if (!ruffReady) {
464
- dbg(`autofix: ruff unavailable for ${filePath}`);
465
- continue;
466
- }
467
- const result = await ruffClient.fixFileAsync(filePath, cwd);
468
- if (result.success && result.fixed > 0) {
469
- fixedCount += result.fixed;
470
- autofixTools.push(`ruff:${result.fixed}`);
471
- fixedThisTurn.add(filePath);
472
- markTargetChanged();
473
- dbg(`autofix: ruff fixed ${result.fixed} issue(s) in ${filePath}`);
474
- needsContentRefresh = true;
475
- }
476
- continue;
477
- }
478
- if (toolName === "biome") {
479
- const biomeReady = biomeClient.isSupportedFile(filePath)
480
- ? await biomeClient.ensureAvailable()
481
- : false;
482
- if (!biomeReady) {
483
- dbg(`autofix: biome unavailable or unsupported for ${filePath}`);
484
- continue;
485
- }
486
- const result = await biomeClient.fixFileAsync(filePath, cwd);
487
- if (result.success && result.fixed > 0) {
488
- fixedCount += result.fixed;
489
- autofixTools.push(`biome:${result.fixed}`);
490
- fixedThisTurn.add(filePath);
491
- markTargetChanged();
492
- dbg(`autofix: biome fixed ${result.fixed} issue(s) in ${filePath}`);
493
- needsContentRefresh = true;
494
- }
495
- continue;
496
- }
497
- if (toolName === "eslint") {
498
- const eslintFixed = await tryEslintFix(filePath, cwd);
499
- if (eslintFixed > 0) {
500
- fixedCount += eslintFixed;
501
- autofixTools.push(`eslint:${eslintFixed}`);
502
- fixedThisTurn.add(filePath);
503
- markTargetChanged();
504
- dbg(`autofix: eslint fixed ${eslintFixed} issue(s) in ${filePath}`);
505
- needsContentRefresh = true;
506
- }
507
- continue;
508
- }
509
- if (toolName === "stylelint") {
510
- const stylelintFixed = await tryStylelintFix(filePath, cwd);
511
- if (stylelintFixed > 0) {
512
- fixedCount += stylelintFixed;
513
- autofixTools.push(`stylelint:${stylelintFixed}`);
514
- fixedThisTurn.add(filePath);
515
- markTargetChanged();
516
- dbg(`autofix: stylelint fixed ${stylelintFixed} issue(s) in ${filePath}`);
517
- needsContentRefresh = true;
518
- }
519
- continue;
520
- }
521
- if (toolName === "sqlfluff") {
522
- const sqlfluffFixed = await trySqlfluffFix(filePath, cwd);
523
- if (sqlfluffFixed > 0) {
524
- fixedCount += sqlfluffFixed;
525
- autofixTools.push(`sqlfluff:${sqlfluffFixed}`);
526
- fixedThisTurn.add(filePath);
527
- markTargetChanged();
528
- dbg(`autofix: sqlfluff fixed ${sqlfluffFixed} issue(s) in ${filePath}`);
529
- needsContentRefresh = true;
530
- }
531
- continue;
532
- }
533
- if (toolName === "rubocop") {
534
- const rubocopFixed = await tryRubocopFix(filePath, cwd);
535
- if (rubocopFixed > 0) {
536
- fixedCount += rubocopFixed;
537
- autofixTools.push(`rubocop:${rubocopFixed}`);
538
- fixedThisTurn.add(filePath);
539
- markTargetChanged();
540
- dbg(`autofix: rubocop fixed ${rubocopFixed} issue(s) in ${filePath}`);
541
- needsContentRefresh = true;
542
- }
543
- continue;
544
- }
545
- if (toolName === "ktlint") {
546
- const ktlintFixed = await tryKtlintFix(filePath, cwd);
547
- if (ktlintFixed > 0) {
548
- fixedCount += ktlintFixed;
549
- autofixTools.push(`ktlint:${ktlintFixed}`);
550
- fixedThisTurn.add(filePath);
551
- markTargetChanged();
552
- dbg(`autofix: ktlint fixed ${ktlintFixed} issue(s) in ${filePath}`);
553
- needsContentRefresh = true;
554
- }
555
- continue;
556
- }
557
- if (toolName === "rust-clippy") {
558
- const clippyChangedFiles = await tryRustClippyFix(filePath);
559
- if (clippyChangedFiles.length > 0) {
560
- fixedCount += clippyChangedFiles.length;
561
- autofixTools.push(`rust-clippy:${clippyChangedFiles.length}`);
562
- fixedThisTurn.add(filePath);
563
- for (const changedFile of clippyChangedFiles)
564
- changedFiles.add(changedFile);
565
- dbg(`autofix: rust-clippy changed ${clippyChangedFiles.length} file(s) from ${filePath}`);
566
- needsContentRefresh = true;
567
- }
568
- continue;
569
- }
570
- if (toolName === "dart-analyze") {
571
- const dartChangedFiles = await tryDartFix(filePath);
572
- if (dartChangedFiles.length > 0) {
573
- fixedCount += dartChangedFiles.length;
574
- autofixTools.push(`dart-analyze:${dartChangedFiles.length}`);
575
- fixedThisTurn.add(filePath);
576
- for (const changedFile of dartChangedFiles)
577
- changedFiles.add(changedFile);
578
- dbg(`autofix: dart fix changed ${dartChangedFiles.length} file(s) from ${filePath}`);
579
- needsContentRefresh = true;
580
- }
581
- continue;
582
- }
583
- if (toolName === "golangci-lint") {
584
- const fixed = await tryGolangciLintFix(filePath, cwd);
585
- if (fixed > 0) {
586
- fixedCount += fixed;
587
- autofixTools.push(`golangci-lint:${fixed}`);
588
- fixedThisTurn.add(filePath);
589
- markTargetChanged();
590
- dbg(`autofix: golangci-lint fixed ${filePath}`);
591
- needsContentRefresh = true;
592
- }
593
- continue;
594
- }
595
- if (toolName === "detekt") {
596
- const fixed = await tryDetektFix(filePath, cwd);
597
- if (fixed > 0) {
598
- fixedCount += fixed;
599
- autofixTools.push(`detekt:${fixed}`);
600
- fixedThisTurn.add(filePath);
601
- markTargetChanged();
602
- dbg(`autofix: detekt --auto-correct fixed ${filePath}`);
603
- needsContentRefresh = true;
604
- }
605
- continue;
606
- }
607
- if (toolName === "ktfmt") {
608
- const fixed = await tryKtfmtFix(filePath, cwd);
609
- if (fixed > 0) {
610
- fixedCount += fixed;
611
- autofixTools.push(`ktfmt:${fixed}`);
612
- fixedThisTurn.add(filePath);
613
- markTargetChanged();
614
- dbg(`autofix: ktfmt formatted ${filePath}`);
615
- needsContentRefresh = true;
616
- }
617
- continue;
618
- }
619
- if (toolName === "markdownlint") {
620
- const fixed = await tryMarkdownlintFix(filePath, cwd);
621
- if (fixed > 0) {
622
- fixedCount += fixed;
623
- autofixTools.push(`markdownlint:${fixed}`);
624
- fixedThisTurn.add(filePath);
625
- markTargetChanged();
626
- dbg(`autofix: markdownlint --fix fixed ${filePath}`);
627
- needsContentRefresh = true;
628
- }
629
- continue;
630
- }
631
- if (toolName === "oxlint") {
632
- const fixed = await tryOxlintFix(filePath, cwd);
633
- if (fixed > 0) {
634
- fixedCount += fixed;
635
- autofixTools.push(`oxlint:${fixed}`);
636
- fixedThisTurn.add(filePath);
637
- markTargetChanged();
638
- dbg(`autofix: oxlint --fix fixed ${filePath}`);
639
- needsContentRefresh = true;
640
- }
641
- }
642
- }
643
- if (attemptedTools.length > 0 && autofixTools.length === 0) {
644
- dbg(`autofix: attempted ${attemptedTools.join(",")} for ${filePath}, but no fixes were applied`);
645
- }
646
- return {
647
- fixedCount,
648
- autofixTools,
649
- attemptedTools,
650
- changedFiles: [...changedFiles],
651
- needsContentRefresh,
652
- };
653
- }
654
- export async function resyncLspFile(filePath, fileContent, needsContentRefresh, lspSyncCompleted, getFlag, dbg) {
655
- if (getFlag("no-lsp"))
656
- return;
657
- if (!needsContentRefresh && lspSyncCompleted)
658
- return;
659
- // #3405 r2: the bound is `clients/lsp/content-limits.ts` now, shared with the
660
- // dispatch runner and the didSave payload. THIS call stays: a file past the
661
- // bound is not synced to the server AT ALL, which is a stricter policy than
662
- // the save seam's (drop the redundant text, still send the save) and the one
663
- // a post-write sync owes — removing it would start writing whole-file
664
- // didOpen frames for files this pipeline has always refused.
665
- const limitCheck = exceedsLspSyncLimits(fileContent);
666
- if (limitCheck.tooLarge)
667
- return;
668
- try {
669
- const lspService = (await loadLspService()).getLSPService();
670
- if (lspService.supportsLSP(filePath)) {
671
- // Push the final post-format/post-fix content through touchFile (not the
672
- // bare openFile) so it registers in the touch-debounce map via
673
- // markTouched. The dispatch-lsp-runner's touchFile fires ~80ms later with
674
- // identical content; registering this push makes its shouldSkipNotify
675
- // return true, so it reuses the diagnostics THIS push triggers instead of
676
- // re-clearing the cache and forcing the server to recompute from scratch —
677
- // the dominant per-edit LSP latency (#203). diagnostics:"none" keeps this
678
- // call non-blocking; the dispatch runner owns the diagnostics wait. We let
679
- // the cache clear (no preserveDiagnostics) so the wait resolves on fresh,
680
- // correctly-positioned diagnostics rather than stale pre-edit ones — the
681
- // didChange triggers a server recompute regardless of cache preservation.
682
- //
683
- // The touch is client-wait-capped, but its didChange/didOpen *write* can
684
- // backpressure forever on a wedged server (stdin not drained), which would
685
- // hang the whole edit with no bound and — until this — no log. Race it
686
- // against a hard budget + the turn's abort signal (Escape): whichever wins,
687
- // the edit proceeds. A wedged server no longer parks the pipeline.
688
- const budgetMs = lspSyncBudgetMs();
689
- const abort = getAmbientAbortSignal();
690
- if (abort?.aborted)
691
- return;
692
- const startedAt = Date.now();
693
- const touch = lspService
694
- .touchFile(filePath, fileContent, {
695
- diagnostics: "none",
696
- source: "lsp_sync",
697
- clientScope: "primary",
698
- maxClientWaitMs: LSP_SPAWN_BUDGET_MS,
699
- // #3405: pi-lens just wrote these bytes to disk, so this is the one
700
- // touch that is a save. A save-triggered server (Expert recompiles
701
- // the project on didSave and on nothing else) publishes for the edit
702
- // only because of this flag.
703
- saved: true,
704
- })
705
- .then(() => "done")
706
- .catch((err) => {
707
- dbg(`LSP resync after autofix error: ${err}`);
708
- return "done";
709
- });
710
- // #2540: Kick off auxiliary server acquisition concurrently and unawaited
711
- // with the ambient turn signal so auxiliary warmup overlaps with the primary
712
- // server during resync. Leaves the single-occupancy deferred slot (#2509)
713
- // free for actionable-warnings while Escape mid-turn abandons the wait.
714
- //
715
- // #2582 F3 — the #1766 F3 invariant re-opened for a different method.
716
- // #2540 placed this kick-off BEFORE the primary touch, inside
717
- // resyncLspFile's swallow-all catch, so anything that threw out of
718
- // auxiliary acquisition abandoned the PRIMARY sync before it started:
719
- // no touchFile, and no lsp_sync_abandoned record for the stall.
720
- // Auxiliary warmup is a best-effort OVERLAP, never a precondition:
721
- // the primary touch is already in flight above, and the async IIFE
722
- // turns a synchronous throw out of the call into a rejection so
723
- // `.catch` covers both failure directions. Order and containment are
724
- // the invariant; do not hoist this back above the touch.
725
- const auxServerIds = enabledAuxiliaryLspServerIds(getFlag);
726
- if (auxServerIds.length > 0) {
727
- void (async () => lspService.getAuxiliaryClientsForFile(filePath, new Set(auxServerIds), undefined, LSP_SPAWN_BUDGET_MS, abort, "tool_result_edit"))().catch(() => { });
728
- }
729
- // #2523 slice 2: this was `combineAbortSignals(abort,
730
- // AbortSignal.timeout(budgetMs))` fed into a hand-rolled
731
- // `Promise.race` — a private fifth copy of "deadline AND signal".
732
- // `bounded()` is the same thing with the abandonment recorded, and
733
- // without the composite signal that #2530 review F4 measured
734
- // accumulating on the SOURCE.
735
- //
736
- // `touch` never rejects (it catches above) and never resolves
737
- // `undefined`, so `undefined` here means exactly "a bound fired".
738
- const outcome = await bounded(touch, {
739
- ms: budgetMs,
740
- // The ambient turn signal: set for the whole tool_result path and
741
- // absent only in a bare unit harness, where the wall budget is
742
- // still live (`bounded()` reads a missing signal as one that
743
- // never aborts).
744
- signal: abort,
745
- hook: "tool_result_edit",
746
- label: "resyncLspFile",
747
- });
748
- if (outcome === undefined) {
749
- // Abandon the still-pending write; the edit continues. Log it so this
750
- // stall — previously an invisible hang — is queryable in latency.log.
751
- //
752
- // #1766: a resync deadline can expire while the target server's FIRST
753
- // spawn is still in flight (cold spawn > budget). That is not the same
754
- // state as a running server that stalled on a write — the server the
755
- // old wording blamed as "slow/wedged" did not exist yet. Distinguish
756
- // the two via a fresh, synchronous inFlight lookup so the record keeps
757
- // the discriminating identity (which server, which lifecycle state).
758
- // #2592: the `typeof lspService.isSpawnInFlight === "function"`
759
- // hedge that used to wrap this call is GONE. It existed for one
760
- // reason — 19 hand-rolled `getLSPService` doubles that lacked the
761
- // method, whose TypeError would have landed in the catch below and
762
- // suppressed this record entirely (#1766 F3) — and that population
763
- // is now zero: every double is seeded from
764
- // `makeLspServiceDouble`, `tests/support/lsp-double-baseline.json`
765
- // is `{}`, and `tests/config/lsp-service-double-sweep.test.ts` reds
766
- // on a fresh hand-rolled one. The real `LSPService` has always had
767
- // the method (clients/lsp/index.ts), so the fallback was a test
768
- // shape leaking into production — AGENTS.md shape 7.
769
- const spawnInFlight = !abort?.aborted && lspService.isSpawnInFlight(filePath);
770
- const reason = abort?.aborted
771
- ? "aborted"
772
- : spawnInFlight
773
- ? "spawn-in-flight"
774
- : "timeout";
775
- logLatency({
776
- type: "phase",
777
- phase: "lsp_sync_abandoned",
778
- filePath,
779
- durationMs: Date.now() - startedAt,
780
- metadata: {
781
- source: "lsp_sync",
782
- reason,
783
- budgetMs,
784
- },
785
- });
786
- const cause = abort?.aborted
787
- ? "aborted (Escape)"
788
- : spawnInFlight
789
- ? `timed out after ${budgetMs}ms; reason: spawn-in-flight (server still cold-spawning)`
790
- : `timed out after ${budgetMs}ms; server slow/wedged`;
791
- dbg(`LSP resync ${cause} for ${filePath}`);
792
- }
793
- }
794
- }
795
- catch (err) {
796
- dbg(`LSP resync after autofix error: ${err}`);
797
- }
798
- }
799
- /** Maps a dispatch `Diagnostic` (clients/dispatch/types.ts) to the #502 bus payload shape. */
800
- function toPilensDiagnosticEntry(d) {
801
- const entry = {
802
- severity: d.severity,
803
- message: d.message,
804
- tool: d.tool,
805
- };
806
- if (d.rule !== undefined)
807
- entry.ruleId = d.rule;
808
- if (d.line !== undefined)
809
- entry.line = d.line;
810
- if (d.column !== undefined)
811
- entry.col = d.column;
812
- if (d.fixable !== undefined)
813
- entry.fixable = d.fixable;
814
- return entry;
815
- }
816
- function buildAllClearOutput(_dispatchResult, elapsed, filePath) {
817
- const kind = detectFileKind(filePath);
818
- const langLabel = kind ? getFileKindLabel(kind) : path.extname(filePath);
819
- const parts = [];
820
- if (kind) {
821
- parts.push(`${langLabel} clean`);
822
- }
823
- parts.push(`${elapsed}ms`);
824
- return `checkmark ${parts.join(" · ")}`.replace("checkmark", "\u2713");
825
- }
826
- export async function runFormatPhase(filePath, getFormatService, dbg, signal, budgetMs = HOOK_WALL_BUDGET_MS.tool_result_edit, hook = "tool_result_edit") {
827
- let formatChanged = false;
828
- let formattersUsed = [];
829
- const formatFailures = [];
830
- const formatUnavailable = [];
831
- let fileContent;
832
- const formatService = getFormatService();
833
- try {
834
- formatService.recordRead(filePath);
835
- const result = await formatService.formatFile(filePath, {
836
- signal,
837
- budgetMs,
838
- hook,
839
- });
840
- // An unavailable tool is NOT a formatter that ran (#2413): keep it out of
841
- // `formattersUsed` (which drives change bookkeeping / turn summaries) and
842
- // out of `formatFailures` (which requeues). Record it once, distinctly.
843
- for (const f of result.formatters) {
844
- if (f.outcome !== "unavailable")
845
- continue;
846
- if (f.error?.includes("project tool agreement could not be established"))
847
- continue;
848
- const reason = f.error ?? "formatter executable not found";
849
- formatUnavailable.push({ formatter: f.name, reason });
850
- recordDegradationOnce({
851
- kind: "formatter-unavailable",
852
- subject: `${f.name}:${path.basename(filePath)}`,
853
- reason,
854
- });
855
- }
856
- formattersUsed = result.formatters
857
- .filter((f) => f.outcome !== "unavailable")
858
- .map((f) => f.name);
859
- if (result.anyChanged) {
860
- formatChanged = true;
861
- dbg("autoformat: " +
862
- result.formatters
863
- .map((f) => f.name + "(" + (f.changed ? "changed" : "unchanged") + ")")
864
- .join(", "));
865
- }
866
- if (!result.allSucceeded) {
867
- const failures = result.formatters.filter((f) => !f.success);
868
- for (const failure of failures) {
869
- recordDegradationOnce({
870
- kind: "formatter-failure",
871
- subject: `${failure.name}:${path.basename(filePath)}`,
872
- reason: failure.error ?? "unknown error",
873
- });
874
- }
875
- formatFailures.push(...failures.map((f) => `${f.name}: ${f.error ?? "unknown error"}`));
876
- dbg("autoformat: " +
877
- failures
878
- .map((f) => f.name + " failed: " + (f.error ?? "unknown error"))
879
- .join("; "));
880
- }
881
- }
882
- catch (err) {
883
- const message = err instanceof Error ? err.message : String(err);
884
- recordDegradationOnce({
885
- kind: "formatter-failure",
886
- subject: `format-service:${path.basename(filePath)}`,
887
- reason: message,
888
- });
889
- formatFailures.push(message);
890
- dbg(`autoformat error: ${err}`);
891
- }
892
- try {
893
- fileContent = nodeFs.readFileSync(filePath, "utf-8");
894
- }
895
- catch {
896
- fileContent = undefined;
897
- }
898
- return {
899
- formatChanged,
900
- formattersUsed,
901
- formatFailures,
902
- formatUnavailable,
903
- fileContent,
904
- };
905
- }
906
- /**
907
- * Build the 🔴 STOP blocker output with an inline code snippet for each
908
- * diagnostic so the agent can see the exact line it wrote without re-reading
909
- * the file.
910
- *
911
- * Example:
912
- * L4: 'randomInt' is declared but its value is never read.
913
- * → const randomInt = Math.floor(result);
914
- */
915
- function buildEnrichedBlockerOutput(blockers, fileContent = "") {
916
- // #3188: no blockers, no banner. The delivery gate above can retract every
917
- // blocker (all cited files deleted), and the header interpolates the count,
918
- // so without this the agent reads "🔴 STOP — 0 issue(s) must be fixed:" with
919
- // nothing under it. Same guard, same reason, as `formatDiagnostics` in
920
- // dispatch/utils/format-utils.ts — it belongs to the renderer, not to each
921
- // call site, because the #2028 branch below cannot gate on the count without
922
- // falling through to the UNGATED raw output.
923
- if (blockers.length === 0)
924
- return "";
925
- // Empty fileContent (readback failed, e.g. deleted-file race) still
926
- // renders the gated blocker list - just without per-line snippets.
927
- const fileLines = fileContent ? fileContent.split("\n") : [];
928
- const MAX_SNIPPET = 120; // chars — keep it tight in context
929
- let out = `\n\n🔴 STOP — ${blockers.length} issue(s) must be fixed:\n`;
930
- const shown = blockers.slice(0, 10);
931
- for (const d of shown) {
932
- const lineNo = d.line ?? 1;
933
- const nodeCtx = d.astNodeType ? ` (${d.astNodeType})` : "";
934
- out += ` L${lineNo}: ${d.message}${nodeCtx}\n`;
935
- // Prefer the exact matched node text (tree-sitter); fall back to the
936
- // full source line (LSP / other runners).
937
- const snippet = d.matchedText
938
- ? d.matchedText.trim().split("\n")[0]?.slice(0, MAX_SNIPPET)
939
- : fileLines[lineNo - 1]?.trim().slice(0, MAX_SNIPPET);
940
- if (snippet)
941
- out += ` → ${snippet}\n`;
942
- if (d.fixSuggestion)
943
- out += ` 💡 ${d.fixSuggestion}\n`;
944
- }
945
- if (blockers.length > 10) {
946
- out += ` ... and ${blockers.length - 10} more\n`;
947
- }
948
- return out;
949
- }
950
- // --- Main Pipeline ---
951
- export async function runPipeline(ctx, deps) {
952
- const { filePath, cwd, toolName, getFlag, getFlagSource, dbg } = ctx;
953
- const { getFormatService } = deps;
954
- const allowAutonomousWriters = ctx.allowAutonomousWriters !== false;
955
- if (!allowAutonomousWriters) {
956
- incrementDegradationCount({
957
- kind: "opaque-mutation-ownership-boundary",
958
- subject: "pipeline",
959
- reason: `observed mutation is not evidence of agent authorship (${filePath})`,
960
- });
961
- }
962
- admitWidgetDiagnosticsWrite(filePath, ctx.telemetry?.writeIndex);
963
- const phase = createPhaseTracker(toolName, filePath);
964
- const pipelineStart = Date.now();
965
- clearGraphCache();
966
- phase.start("total");
967
- // --- 1. Read file content ---
968
- phase.start("read_file");
969
- let fileContent;
970
- try {
971
- fileContent = nodeFs.readFileSync(filePath, "utf-8");
972
- }
973
- catch {
974
- // File may not exist (e.g., deleted)
975
- }
976
- phase.end("read_file");
977
- // --- 2. Auto-format ---
978
- phase.start("format");
979
- let formatChanged = false;
980
- let formattersUsed = [];
981
- let formatFailures = [];
982
- const piChangedFiles = new Set();
983
- const autoformatDisabled = !!getFlag("no-autoformat", filePath);
984
- const immediateFormat = !!getFlag("immediate-format");
985
- const formatDeferred = allowAutonomousWriters &&
986
- !autoformatDisabled &&
987
- !immediateFormat &&
988
- !!fileContent;
989
- if (allowAutonomousWriters &&
990
- !autoformatDisabled &&
991
- immediateFormat &&
992
- fileContent) {
993
- const formatResult = await runFormatPhase(filePath, getFormatService, dbg, ctx.signal);
994
- formatChanged = formatResult.formatChanged;
995
- formattersUsed = formatResult.formattersUsed;
996
- formatFailures = formatResult.formatFailures;
997
- fileContent = formatResult.fileContent;
998
- if (formatChanged) {
999
- const absPath = path.resolve(filePath);
1000
- piChangedFiles.add(absPath);
1001
- publishFilesTouched({
1002
- reason: "format",
1003
- paths: [absPath],
1004
- cwd,
1005
- dbg,
1006
- fixes: formattersUsed.map((tool) => ({
1007
- path: absPath,
1008
- tool,
1009
- kind: "format",
1010
- })),
1011
- });
1012
- }
1013
- }
1014
- else if (formatDeferred) {
1015
- dbg(`autoformat: deferred until agent_end for ${filePath}`);
1016
- }
1017
- else if (!allowAutonomousWriters) {
1018
- dbg(`autoformat: skipped for ${filePath} (mutation ownership is unproven)`);
1019
- }
1020
- else if (autoformatDisabled) {
1021
- const source = getFlagSource?.("no-autoformat", filePath);
1022
- dbg(`autoformat: skipped for ${filePath} (--no-autoformat${source ? `, source=${source}` : ""})`);
1023
- }
1024
- phase.end("format", {
1025
- formattersUsed,
1026
- formatChanged,
1027
- deferred: formatDeferred,
1028
- });
1029
- // --- 3. Auto-fix ---
1030
- phase.start("autofix");
1031
- let fixedCount = 0;
1032
- let autofixTools = [];
1033
- let attemptedTools = [];
1034
- let autofixChangedFiles = [];
1035
- let fixRefresh = false;
1036
- let autofixSkipReason;
1037
- if (!allowAutonomousWriters) {
1038
- autofixSkipReason = "mutation_ownership_unproven";
1039
- dbg(`autofix: skipped for ${filePath} (mutation ownership is unproven)`);
1040
- }
1041
- else if (ctx.autofixMode === "deferred") {
1042
- autofixSkipReason = "deferred_to_agent_end";
1043
- dbg(`autofix: deferred until agent_end for ${filePath}`);
1044
- }
1045
- else
1046
- ({
1047
- fixedCount,
1048
- autofixTools,
1049
- attemptedTools,
1050
- changedFiles: autofixChangedFiles,
1051
- needsContentRefresh: fixRefresh,
1052
- skipReason: autofixSkipReason,
1053
- } = await runAutofix(filePath, cwd, getFlag, dbg, deps, getFlagSource));
1054
- for (const changedFile of autofixChangedFiles) {
1055
- piChangedFiles.add(path.resolve(changedFile));
1056
- }
1057
- if (autofixChangedFiles.length > 0) {
1058
- // autofixTools entries are "tool:count" (e.g. "ruff:3"); runAutofix runs
1059
- // against ONE target filePath per call, so every tool that fired in this
1060
- // batch applies to every file the batch changed — best-effort attribution
1061
- // (not per-file precision) since the underlying tool runners don't report
1062
- // per-changed-file breakdown. Good enough for the "was this hunk
1063
- // mechanical" use case the fix-provenance field exists for.
1064
- const absChangedFiles = autofixChangedFiles.map((f) => path.resolve(f));
1065
- const toolNames = autofixTools.map((t) => t.split(":")[0]);
1066
- publishFilesTouched({
1067
- reason: "autofix",
1068
- paths: absChangedFiles,
1069
- cwd,
1070
- dbg,
1071
- fixes: absChangedFiles.flatMap((p) => toolNames.map((tool) => ({ path: p, tool, kind: "autofix" }))),
1072
- });
1073
- }
1074
- if (fixRefresh) {
1075
- try {
1076
- fileContent = nodeFs.readFileSync(filePath, "utf-8");
1077
- }
1078
- catch {
1079
- fileContent = undefined;
1080
- }
1081
- }
1082
- phase.end("autofix", {
1083
- fixedCount,
1084
- tools: autofixTools,
1085
- attemptedTools,
1086
- skipReason: autofixSkipReason,
1087
- });
1088
- // Capture the target's bytes immediately after pi-lens writes and before any
1089
- // awaitable LSP or dispatch work. `fileModified` also covers side-effect
1090
- // files, so target membership is the discriminator for pipeline ownership
1091
- // (#2499).
1092
- const fileModified = formatChanged || fixedCount > 0;
1093
- const targetFileModified = piChangedFiles.has(path.resolve(filePath));
1094
- const postWriteStateHash = fileModified && targetFileModified
1095
- ? (() => {
1096
- try {
1097
- return nodeCrypto
1098
- .createHash("sha256")
1099
- .update(nodeFs.readFileSync(filePath))
1100
- .digest("hex");
1101
- }
1102
- catch (error) {
1103
- recordDegradationOnce({
1104
- kind: "pipeline-post-write-hash-unavailable",
1105
- subject: filePath,
1106
- reason: error instanceof Error ? error.message : String(error),
1107
- });
1108
- return undefined;
1109
- }
1110
- })()
1111
- : undefined;
1112
- // --- 4. LSP file sync ---
1113
- // Sync once with final post-format/post-fix content so dispatch and cascade
1114
- // diagnostics do not observe stale pre-format text.
1115
- phase.start("lsp_sync");
1116
- let lspSyncCompleted = false;
1117
- if (fileContent) {
1118
- await resyncLspFile(filePath, fileContent, true, false, getFlag, dbg);
1119
- lspSyncCompleted = true;
1120
- }
1121
- phase.end("lsp_sync", { completed: lspSyncCompleted, finalContent: true });
1122
- // --- 5. Dispatch lint ---
1123
- phase.start("dispatch_lint");
1124
- dbg(`dispatch: running lint tools for ${filePath}`);
1125
- const piApi = {
1126
- getFlag: getFlag,
1127
- };
1128
- const { dispatchLintWithResult, computeCascadeForFile } = await loadDispatchIntegration();
1129
- // Capture the bytes the pipeline presents to analysis before the dispatch
1130
- // promise can yield to another writer. The blocker evidence below belongs to
1131
- // this analysis input, not to whatever happens to be on disk when the whole
1132
- // pipeline returns.
1133
- const inlineBlockerFileContent = fileContent
1134
- ? (() => {
1135
- const content = Buffer.from(fileContent, "utf8");
1136
- return content.byteLength <= 2 * 1024 * 1024
1137
- ? {
1138
- size: content.byteLength,
1139
- sha256: createHash("sha256").update(content).digest("hex"),
1140
- }
1141
- : undefined;
1142
- })()
1143
- : undefined;
1144
- const dispatchResult = await dispatchLintWithResult(filePath, cwd, piApi, ctx.modifiedRanges, {
1145
- model: ctx.telemetry?.model ?? "unknown",
1146
- sessionId: ctx.telemetry?.sessionId ?? "unknown",
1147
- turnIndex: ctx.telemetry?.turnIndex ?? 0,
1148
- writeIndex: ctx.telemetry?.writeIndex ?? 0,
1149
- }, {
1150
- projectRoot: ctx.projectRoot,
1151
- writeIndex: ctx.telemetry?.writeIndex,
1152
- telemetryModel: ctx.telemetry?.modelId,
1153
- telemetryProvider: ctx.telemetry?.provider,
1154
- });
1155
- recordDiagnostics(filePath, dispatchResult.diagnostics, ctx.telemetry?.writeIndex);
1156
- // #502: emit the write batch's FINAL diagnostic state immediately after
1157
- // recordDiagnostics commits it — this call site runs after format,
1158
- // autofix, and dispatch have all completed for this batch (see the phase
1159
- // order above), so dispatchResult.diagnostics IS the latest post-batch
1160
- // picture, not an intermediate runner result. Full-replace semantics: we
1161
- // always pass the complete current set for this file, including an
1162
- // explicit `[]` on the transition from a previously-reported-dirty state
1163
- // to clean (see clients/diagnostics-publish.ts for the contract).
1164
- {
1165
- const absPath = path.resolve(filePath);
1166
- const wasDirty = wasPreviouslyReportedDirty(absPath);
1167
- if (dispatchResult.diagnostics.length > 0 || wasDirty) {
1168
- publishDiagnostics({
1169
- cwd,
1170
- files: [
1171
- {
1172
- path: absPath,
1173
- diagnostics: dispatchResult.diagnostics.map(toPilensDiagnosticEntry),
1174
- },
1175
- ],
1176
- dbg,
1177
- });
1178
- }
1179
- }
1180
- // Opaque recovery is a valid analysis input, but its bytes are not an agent
1181
- // authored surface. Keep diagnostics and advisory output visible while
1182
- // withholding the edit-directed channels that would tell the agent to mutate
1183
- // the observed artifact (#3226).
1184
- const hasBlockers = allowAutonomousWriters && dispatchResult.hasBlockers;
1185
- const actionableWarnings = allowAutonomousWriters
1186
- ? dispatchResult.warnings
1187
- .map((diagnostic) => recordFromDispatchDiagnostic(diagnostic, cwd))
1188
- .filter((warning) => Boolean(warning))
1189
- : [];
1190
- const codeQualityWarnings = dispatchResult.warnings
1191
- .map((diagnostic) => recordFromCodeQualityDiagnostic(diagnostic, cwd))
1192
- .filter((warning) => Boolean(warning));
1193
- if (dispatchResult.diagnostics.length > 0) {
1194
- const tracker = getDiagnosticTracker();
1195
- tracker.trackShown(dispatchResult.diagnostics);
1196
- }
1197
- if (fixedCount > 0)
1198
- getDiagnosticTracker().trackAutoFixed(fixedCount);
1199
- if (dispatchResult.resolvedCount > 0)
1200
- getDiagnosticTracker().trackAgentFixed(dispatchResult.resolvedCount);
1201
- let output = "";
1202
- // #2028: the 🔴 STOP block is an agent-facing delivery surface
1203
- // (finding-delivery-gate.ts's `tool-call:stop-blocker`), so it routes through
1204
- // the shared deleted-path gate before rendering: a blocker whose cited file
1205
- // no longer exists has no remediation the agent can perform (the finding IS
1206
- // the deleted file's content), so it is dropped here rather than re-asserted.
1207
- // One bounded stat per unique cited path, only when blockers exist — zero
1208
- // cost on the clean/fast paths.
1209
- const deliverableBlockers = hasBlockers
1210
- ? dropFindingsForMissingPaths({
1211
- store: "stop-blocker",
1212
- findings: dispatchResult.blockers,
1213
- cwd,
1214
- citedPath: (b) => b.filePath || undefined,
1215
- })
1216
- : [];
1217
- // #3190: ONE gate, applied once here, for EVERY surface. The durable record
1218
- // this function hands `runtime.recordInlineBlockers` (and through it the
1219
- // turn-end `Unresolved from this turn` re-serve) used to be built from the
1220
- // UNGATED `dispatchResult.blockerOutput`/`blockers`, so a blocker retracted
1221
- // from the tool result above was re-delivered at turn end — and the ungated
1222
- // verdict still latched the commit gate through `updateGitGuardStatus`. It is
1223
- // exactly `hasBlockers && nothing-survived-the-gate` inverted: the gate
1224
- // returns `[]` whenever `hasBlockers` is false, so this one expression is the
1225
- // whole condition.
1226
- const hasDeliverableBlockers = deliverableBlockers.length > 0;
1227
- if (dispatchResult.diagnostics.length > 0) {
1228
- const logger = getDiagnosticLogger();
1229
- const toKey = (d) => [
1230
- d.tool || "",
1231
- d.id || "",
1232
- d.rule || "",
1233
- d.filePath || "",
1234
- d.line || 0,
1235
- d.column || 0,
1236
- ].join("|");
1237
- const inlineKeys = new Set([...deliverableBlockers, ...dispatchResult.fixed].map(toKey));
1238
- for (const d of dispatchResult.diagnostics) {
1239
- logger.logCaught(d, {
1240
- model: ctx.telemetry?.model ?? "unknown",
1241
- sessionId: ctx.telemetry?.sessionId ?? "unknown",
1242
- turnIndex: ctx.telemetry?.turnIndex ?? 0,
1243
- writeIndex: ctx.telemetry?.writeIndex ?? 0,
1244
- }, inlineKeys.has(toKey(d)));
1245
- }
1246
- }
1247
- const deliveredOutput = !allowAutonomousWriters && dispatchResult.hasBlockers
1248
- ? dispatchResult.output.slice(dispatchResult.blockerOutput.length)
1249
- : dispatchResult.output;
1250
- if (hasBlockers && fileContent) {
1251
- // Enrich blocker output with a code snippet so the agent can see the
1252
- // exact line it wrote that caused each violation — no re-read needed.
1253
- if (deliverableBlockers.length > 0) {
1254
- output += buildEnrichedBlockerOutput(deliverableBlockers, fileContent);
1255
- }
1256
- // Append fixed/coverage parts from the original output (slice off the
1257
- // blocker section we're replacing).
1258
- const rest = dispatchResult.output.slice(dispatchResult.blockerOutput.length);
1259
- if (rest)
1260
- output += rest;
1261
- }
1262
- else if (deliveredOutput) {
1263
- // #2028 review P3: this path fires when readback FAILED - raw output
1264
- // still cites possibly-deleted files. Re-render from the gated set
1265
- // (no snippets without fileContent) and keep the post-blocker slice.
1266
- if (hasBlockers &&
1267
- deliverableBlockers.length !== dispatchResult.blockers.length) {
1268
- let gatedOut = buildEnrichedBlockerOutput(deliverableBlockers);
1269
- const rest = dispatchResult.output.slice(dispatchResult.blockerOutput.length);
1270
- if (rest)
1271
- gatedOut += rest;
1272
- // #3188: every blocker retracted and nothing after the blocker
1273
- // section leaves nothing to say — appending the separator alone would
1274
- // still deliver a (whitespace-only) tool-result block, because
1275
- // `handleToolResult` decides delivery on `output` truthiness.
1276
- if (gatedOut)
1277
- output += `\n\n${gatedOut}`;
1278
- }
1279
- else {
1280
- output += `\n\n${deliveredOutput}`;
1281
- }
1282
- }
1283
- if (fixedCount > 0) {
1284
- const detail = autofixTools.length > 0 ? ` (${autofixTools.join(", ")})` : "";
1285
- output += `\n\n✅ Auto-fixed ${fixedCount} issue(s)${detail}`;
1286
- }
1287
- if (formatFailures.length > 0) {
1288
- const details = formatFailures.slice(0, 3).join("; ");
1289
- const suffix = formatFailures.length > 3
1290
- ? `; ... and ${formatFailures.length - 3} more`
1291
- : "";
1292
- output += `\n\n⚠️ Auto-format failed: ${details}${suffix}`;
1293
- }
1294
- // #1590: the notice sentence itself is NOT rendered here. This layer cannot
1295
- // see the attachment cap or the aggregate budget, so it hands the display
1296
- // paths to `handleToolResult`, which owns the decision and renders the one
1297
- // sentence with `renderPostAutofixNotice`.
1298
- const postAutofixNotice = formatChanged || fixedCount > 0
1299
- ? {
1300
- targetPath: toRunnerDisplayPath(cwd, filePath),
1301
- changedFiles: [...piChangedFiles].map((changedFile) => toRunnerDisplayPath(cwd, changedFile)),
1302
- }
1303
- : undefined;
1304
- phase.end("dispatch_lint", {
1305
- hasOutput: !!dispatchResult.output,
1306
- diagnosticCount: dispatchResult.diagnostics.length,
1307
- });
1308
- // --- 6. Cascade diagnostics (LSP only) ---
1309
- // Kicked off UNAWAITED so the graph rebuild + neighbor LSP pulls run
1310
- // concurrently after the edit returns rather than blocking it (#450). The
1311
- // result is never shown inline — settled (bounded) and surfaced at turn_end.
1312
- // The stored promise must never reject: an unhandled rejection is fatal, so a
1313
- // failing compute resolves to an "error" skip-run instead.
1314
- const cascadeOrigin = {
1315
- turnSeq: ctx.telemetry?.turnIndex,
1316
- writeSeq: ctx.telemetry?.writeIndex,
1317
- projectSeq: ctx.seqState?.projectSeq(),
1318
- };
1319
- const cascadePromise = getFlag("no-lsp")
1320
- ? undefined
1321
- : computeCascadeForFile(filePath, cwd, {
1322
- hasBlockers,
1323
- dbg,
1324
- turnSeq: ctx.telemetry?.turnIndex,
1325
- writeSeq: ctx.telemetry?.writeIndex,
1326
- // #3157: `cwd` here is the LANGUAGE root. The cascade's display
1327
- // filter reads the disposition store and the `.pi-lens.json` rule
1328
- // policy, both written under the PROJECT root (#1030) — the same
1329
- // pair the dispatcher is handed above.
1330
- projectRoot: ctx.projectRoot,
1331
- seqState: ctx.seqState,
1332
- turnEndCascadeSettleStart: ctx.turnEndCascadeSettleStart,
1333
- fileContent,
1334
- wordIndex: ctx.wordIndex,
1335
- onWordIndexUpdated: ctx.onWordIndexUpdated,
1336
- })
1337
- .then((run) => ({ ...run, origin: cascadeOrigin }))
1338
- .catch((err) => {
1339
- dbg(`cascade compute failed for ${filePath}: ${err}`);
1340
- return {
1341
- filePath,
1342
- origin: cascadeOrigin,
1343
- result: undefined,
1344
- neighborCount: 0,
1345
- diagnosticCount: 0,
1346
- skipReason: "error",
1347
- // #1023: a thrown compute is ALSO "couldn't compute downstream
1348
- // impact" — carry an indeterminate marker so turn_end surfaces an
1349
- // honest advisory instead of the error skip being logs-only.
1350
- indeterminate: {
1351
- reason: "error",
1352
- detail: "cascade computation failed",
1353
- },
1354
- };
1355
- });
1356
- // --- Final timing + all-clear ---
1357
- const elapsed = Date.now() - pipelineStart;
1358
- // #1590: `postAutofixNotice` is output this run produces, just rendered a
1359
- // layer up. Treat it as output here, or a format-only change would newly
1360
- // gain an "all clear" line it never had while the sentence lived inline.
1361
- if (!output && !postAutofixNotice) {
1362
- output = buildAllClearOutput(dispatchResult, elapsed, filePath);
1363
- }
1364
- phase.end("total", { hasOutput: !!output });
1365
- const changedFiles = [...piChangedFiles];
1366
- emitLensAnalysisComplete({
1367
- cwd,
1368
- filePath,
1369
- toolName,
1370
- model: ctx.telemetry?.model ?? "unknown",
1371
- sessionId: ctx.telemetry?.sessionId ?? "unknown",
1372
- turnIndex: ctx.telemetry?.turnIndex ?? 0,
1373
- writeIndex: ctx.telemetry?.writeIndex ?? 0,
1374
- diagnostics: dispatchResult.diagnostics,
1375
- blockers: hasBlockers ? dispatchResult.blockers : [],
1376
- warnings: dispatchResult.warnings,
1377
- fixed: dispatchResult.fixed,
1378
- resolvedCount: dispatchResult.resolvedCount,
1379
- hasBlockers,
1380
- fileModified,
1381
- changedFiles,
1382
- durationMs: elapsed,
1383
- });
1384
- return {
1385
- output,
1386
- // #3190: the verdict every consumer reads — `updateGitGuardStatus`'s commit
1387
- // latch above all — is what was DELIVERED, not what the dispatch found. The
1388
- // two disagreed whenever the deleted-path gate retracted every blocker: the
1389
- // tool result said `✓ clean` while the commit gate stayed latched, its
1390
- // summary falling back to that very all-clear line. `emitLensAnalysisComplete`
1391
- // above deliberately keeps the raw dispatch counts — it records what was
1392
- // observed, not what was served.
1393
- hasBlockers: hasDeliverableBlockers,
1394
- cascadePromise,
1395
- isError: false,
1396
- fileModified,
1397
- postWriteStateHash,
1398
- changedFiles,
1399
- // #3190: re-rendered from the GATED set with `formatDiagnostics(...,
1400
- // "blocking")` — the very expression `dispatcher.ts:1409` builds
1401
- // `blockerOutput` with, over a subset of the very array it rendered. When
1402
- // the gate drops nothing the two are byte-identical (same renderer, same
1403
- // array, same display cap), so an unretracted record is unchanged; when it
1404
- // drops something the stored text can no longer disagree with the tool
1405
- // result, and `inline-blocker-dispositions.ts`' re-render at turn end still
1406
- // matches this string exactly.
1407
- inlineBlockerSummary: hasDeliverableBlockers
1408
- ? formatDiagnostics(deliverableBlockers, "blocking").trim() || undefined
1409
- : undefined,
1410
- // #1561 F1: taken from the very diagnostics `blockerOutput` was rendered
1411
- // from, so the provenance can never disagree with the text it guards. An
1412
- // untagged diagnostic contributes the literal "unknown", which no verdict
1413
- // claims coverage for — it pins the entry rather than silently widening
1414
- // what an LSP check is allowed to clear.
1415
- inlineBlockerSources: hasDeliverableBlockers
1416
- ? [
1417
- ...new Set(deliverableBlockers.map((d) => d.tool?.trim() || "unknown")),
1418
- ]
1419
- : undefined,
1420
- inlineBlockerLines: hasDeliverableBlockers
1421
- ? deliverableBlockers
1422
- // #1641 review F2: the blocker array (#3190: the deliverable subset
1423
- // of `dispatchResult.blockers`) is NOT guaranteed to be
1424
- // scoped to THIS file — a chart-wide runner (helm-lint, helm-render)
1425
- // reports blocking diagnostics against other files in the chart
1426
- // (e.g. `values.yaml`) alongside `ctx.filePath`. The precedent every
1427
- // per-file runner already follows (dotnet-build.ts, javac.ts) is to
1428
- // drop cross-file rows before they reach a per-file record; this is
1429
- // that same filter applied at the aggregation point instead, since
1430
- // `blockers` is pooled across every runner dispatched for this file.
1431
- // Without it, a cross-file line count gets attributed to THIS
1432
- // file's past-EOF check and can demote an in-bounds, fully valid
1433
- // blocker for content the diagnostic never described.
1434
- //
1435
- // #1641 review round 2 (LOW): `path.resolve` equality doesn't fold
1436
- // case, and an LSP-sourced diagnostic's `filePath` is stamped with
1437
- // realpath canonical casing (dispatch/runners/lsp.ts ->
1438
- // normalizeMapKey) while `ctx.filePath` can arrive lowercase-drive
1439
- // on Windows — the drive-letter class from #1139/#1150. A bare
1440
- // `path.resolve` equality then drops EVERY LSP blocker line and
1441
- // this record silently skips the past-EOF gate (fail-open, but
1442
- // exactly the pre-fix behavior on the surface #1641 targets).
1443
- // `normalizeEphemeralMapKey` slash-folds and (on win32)
1444
- // lowercase-folds both sides with no filesystem I/O — cheap enough
1445
- // for this per-blocker hot-path filter. `pathsEqual` was
1446
- // deliberately NOT used here: it calls `realpathSync` per
1447
- // comparison, which this filter cannot afford per blocker.
1448
- .filter((d) => normalizeEphemeralMapKey(d.filePath) ===
1449
- normalizeEphemeralMapKey(filePath))
1450
- .map((d) => d.line)
1451
- .filter((line) => typeof line === "number")
1452
- : undefined,
1453
- actionableWarnings,
1454
- codeQualityWarnings,
1455
- diagnostics: dispatchResult.diagnostics,
1456
- formattersUsed,
1457
- fixedCount,
1458
- autofixTools,
1459
- postAutofixNotice,
1460
- postMutation: ctx.autofixMode !== "deferred" &&
1461
- autofixChangedFiles.some((f) => path.resolve(f) === path.resolve(filePath)) &&
1462
- fileContent !== undefined
1463
- ? {
1464
- filePath: path.resolve(filePath),
1465
- content: fileContent,
1466
- source: "autofix",
1467
- }
1468
- : undefined,
1469
- inlineBlockerFileContent: hasBlockers
1470
- ? inlineBlockerFileContent
1471
- : undefined,
1472
- // #3246: the very array `blockerOutput` above was rendered from, so the
1473
- // turn-end policy filter and its re-render can never disagree with the
1474
- // text they guard — the same provenance argument `inlineBlockerSources`
1475
- // makes one field up.
1476
- inlineBlockerDiagnostics: hasDeliverableBlockers
1477
- ? deliverableBlockers
1478
- : undefined,
1479
- };
1480
- }