@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,1269 +0,0 @@
1
- /**
2
- * Declarative Tool Dispatcher for pi-lens
3
- *
4
- * Redesigned to handle the full complexity of pi-lens's tool_result handler:
5
- * - Multiple tools with different semantics (blocking, warning, silent)
6
- * - Delta mode (baseline tracking)
7
- * - Autofix handling
8
- * - Output aggregation and formatting
9
- *
10
- * Key abstractions:
11
- * - RunnerDefinition: A tool that can be run
12
- * - Diagnostic: Structured issue representation
13
- * - OutputSemantic: How to display (blocking, warning, silent, etc.)
14
- * - BaselineStore: Track pre-existing issues for delta mode
15
- */
16
- import { logExtension } from "../extension-log.js";
17
- import * as fs from "node:fs";
18
- import * as path from "node:path";
19
- import { recordRunner } from "../widget-state.js";
20
- import { incrementDegradationCount, recordDegradationOnce, } from "../degradation-ledger.js";
21
- import { detectFileKind } from "../file-kinds.js";
22
- import { detectFileRole } from "../file-role.js";
23
- import { classifyGeneratedOrArtifactDetailed, } from "../generated-artifacts.js";
24
- import { isTestFile } from "../file-utils.js";
25
- import { getPrimaryDispatchGroup } from "../language-policy.js";
26
- import { resolveLanguageRootForFile } from "../language-profile.js";
27
- import { logLatency, phaseFinished, phaseStarted } from "../latency-logger.js";
28
- import { isSpawnableCommand } from "../installer/index.js";
29
- import { isAbsoluteFilePath, isWindowsPath, normalizeEphemeralMapKey, normalizeMapKey, } from "../path-utils.js";
30
- import { loadPiLensProjectConfig } from "../project-lens-config.js";
31
- import { RUNTIME_CONFIG, getRunnerTimeoutFloorMs } from "../runtime-config.js";
32
- import { probeToolAsync } from "../tool-probe.js";
33
- import { classifyDiagnostic } from "./diagnostic-taxonomy.js";
34
- import { classifyProbeFailure, logAvailabilityDecision, startHostStallSampler, transientRetryDelayMs, } from "./runners/utils/availability-policy.js";
35
- import { recordAvailabilityProbeOverrun, getDispatchAvailabilityGeneration, } from "./runners/utils/runner-helpers.js";
36
- import { createAvailabilityProbeFlight } from "../availability-probe-flight.js";
37
- import { applyDispositions } from "../diagnostic-dispositions.js";
38
- import { applyInlineSuppressions } from "./inline-suppressions.js";
39
- import { getToolPlan } from "./plan.js";
40
- import { resolveRunnerPath } from "./runner-context.js";
41
- import { classifyObservedRunner, COLLECT_LATER_THRESHOLD_MS, observeRunnerLatency, } from "./collect-later-tier.js";
42
- import { deferRunnerFindings } from "./pending-runner-findings.js";
43
- import { applyRulePolicy, rulePolicyMapFromConfig } from "./rule-policy.js";
44
- import { getToolProfile } from "./tool-profile.js";
45
- import { isRunnerSkipReason } from "./types.js";
46
- const dispatcherProbeFlights = createAvailabilityProbeFlight({ generation: () => getDispatchAvailabilityGeneration() });
47
- import { formatDiagnostics } from "./utils/format-utils.js";
48
- // --- Runner Registry ---
49
- export class RunnerRegistry {
50
- runners = new Map();
51
- register(runner) {
52
- if (this.runners.has(runner.id))
53
- return;
54
- this.runners.set(runner.id, runner);
55
- }
56
- get(id) {
57
- return this.runners.get(id);
58
- }
59
- getForKind(kind, filePath) {
60
- const matching = [];
61
- const isTest = filePath ? isTestFile(filePath) : false;
62
- for (const runner of this.runners.values()) {
63
- if (isTest && runner.skipTestFiles)
64
- continue;
65
- if (runnerAppliesToKind(runner, kind)) {
66
- matching.push(runner);
67
- }
68
- }
69
- return matching.sort((a, b) => a.priority - b.priority);
70
- }
71
- list() {
72
- return Array.from(this.runners.values());
73
- }
74
- clear() {
75
- this.runners.clear();
76
- }
77
- }
78
- function runnerAppliesToKind(runner, kind) {
79
- return (runner.appliesTo.length === 0 ||
80
- (kind !== undefined && runner.appliesTo.includes(kind)));
81
- }
82
- // --- Tool Availability Cache ---
83
- /**
84
- * Normalize a command name to a FactStore session key.
85
- * Strips .cmd/.exe suffixes (case-insensitive) and lowercases,
86
- * then prefixes with "session.toolCache.".
87
- */
88
- export function normalizeCacheKey(cmd) {
89
- const normalized = cmd.replace(/\.(cmd|exe)$/i, "").toLowerCase();
90
- return `session.toolCache.${normalized}`;
91
- }
92
- /** Probe budget for the generic `hasTool` availability check, ms. */
93
- const TOOL_PROBE_TIMEOUT_MS = 5000;
94
- /**
95
- * Session fact holding the epoch ms after which a TRANSIENT verdict for a
96
- * command may be re-probed. Kept beside the boolean fact so both share the
97
- * session's lifetime — no second global to reset (#1476).
98
- */
99
- function transientRetryKey(command) {
100
- return `${normalizeCacheKey(command)}.retryAt`;
101
- }
102
- /**
103
- * Consecutive transient verdicts for a command, so the cooldown ESCALATES the
104
- * way the policy documents (30 s, 60 s, 120 s … capped at 5 min) instead of
105
- * sitting flat at 30 s.
106
- *
107
- * This is the highest-traffic availability consumer in the product. A flat
108
- * cooldown here means a permanently sick host is re-probed every 30 s per
109
- * command for the whole session — ten times the storm the policy claims to
110
- * bound, and the one place the bound matters most. `createAvailabilityChecker`
111
- * tracks the same counter; this keeps the two seams telling one story.
112
- */
113
- function transientAttemptsKey(command) {
114
- return `${normalizeCacheKey(command)}.transientAttempts`;
115
- }
116
- /**
117
- * Is `command` usable right now? Cached per session.
118
- *
119
- * Latch policy (#1467/#1476): a `false` from a genuine absence is durable and
120
- * is remembered for the session. A `false` from a TIMED-OUT probe is not — this
121
- * is the highest-traffic availability consumer in the codebase, and caching a
122
- * host stall here silently disabled a healthy tool for every later dispatch in
123
- * the session. A transient verdict instead holds only for a bounded cooldown,
124
- * which also stops a sick host from being re-probed on every dispatch.
125
- */
126
- export async function checkToolAvailability(command, facts) {
127
- const key = normalizeCacheKey(command);
128
- const cached = facts.getSessionFact(key);
129
- if (cached !== undefined) {
130
- return cached;
131
- }
132
- const retryAt = facts.getSessionFact(transientRetryKey(command));
133
- if (retryAt !== undefined && Date.now() < retryAt)
134
- return false;
135
- // A command that isn't even on disk can't pass a --version probe; the ~μs
136
- // stat/PATH walk saves a guaranteed-to-fail spawn round-trip per cold tool.
137
- if (!(await isSpawnableCommand(command))) {
138
- facts.setSessionFact(key, false);
139
- return false;
140
- }
141
- try {
142
- // The budget is enforced by a HOST-side timer, so measure the loop stall
143
- // that overlapped the window and let the shared classifier read it.
144
- const sampler = startHostStallSampler();
145
- const startedAt = Date.now();
146
- let result;
147
- let hostStallMs;
148
- let probeJoined = false;
149
- try {
150
- const shared = dispatcherProbeFlights.run(`dispatcher:${key}`, () => probeToolAsync(command, ["--version"], {
151
- timeout: TOOL_PROBE_TIMEOUT_MS,
152
- }));
153
- probeJoined = shared.joined;
154
- result = await shared.promise;
155
- }
156
- finally {
157
- hostStallMs = sampler.stop();
158
- }
159
- const elapsedMs = Date.now() - startedAt;
160
- recordAvailabilityProbeOverrun(command, key, elapsedMs, TOOL_PROBE_TIMEOUT_MS, result.failure);
161
- if (result.status === 0) {
162
- facts.setSessionFact(key, true);
163
- // The tool answered: retire the cooldown facts rather than leaving a
164
- // stale retry deadline behind a `true`.
165
- facts.setSessionFact(transientRetryKey(command), 0);
166
- facts.setSessionFact(transientAttemptsKey(command), 0);
167
- logAvailabilityDecision({
168
- tool: command,
169
- verdict: "available",
170
- outcome: "success",
171
- cause: "ok",
172
- elapsedMs,
173
- latched: true,
174
- classifiedBy: probeJoined ? "joined" : "probe",
175
- hostStallMs,
176
- budgetMs: TOOL_PROBE_TIMEOUT_MS,
177
- });
178
- return true;
179
- }
180
- // `missing` for anything unclassified preserves the pre-#1476 meaning of
181
- // a non-zero exit: durable, cached for the session.
182
- const { outcome, cause, evidence } = classifyProbeFailure(result, {
183
- hostStallMs,
184
- unclassifiedFailureOutcome: "missing",
185
- });
186
- let retryAfterMs;
187
- if (outcome === "transient") {
188
- const attempts = (facts.getSessionFact(transientAttemptsKey(command)) ?? 0) + 1;
189
- facts.setSessionFact(transientAttemptsKey(command), attempts);
190
- retryAfterMs = transientRetryDelayMs(attempts, cause);
191
- facts.setSessionFact(transientRetryKey(command), Date.now() + retryAfterMs);
192
- }
193
- else {
194
- facts.setSessionFact(key, false);
195
- facts.setSessionFact(transientAttemptsKey(command), 0);
196
- }
197
- logAvailabilityDecision({
198
- tool: command,
199
- verdict: "unavailable",
200
- outcome,
201
- cause,
202
- elapsedMs,
203
- latched: outcome !== "transient",
204
- hostStallMs,
205
- ...(retryAfterMs !== undefined && { retryAfterMs }),
206
- budgetMs: TOOL_PROBE_TIMEOUT_MS,
207
- classifiedBy: probeJoined ? "joined" : "probe",
208
- evidence,
209
- });
210
- return false;
211
- }
212
- catch {
213
- facts.setSessionFact(key, false);
214
- return false;
215
- }
216
- }
217
- // --- Dispatch Context Factory ---
218
- function readFilePrefix(filePath, maxBytes = 4096) {
219
- let fd;
220
- try {
221
- fd = fs.openSync(filePath, "r");
222
- const buffer = Buffer.alloc(maxBytes);
223
- const bytesRead = fs.readSync(fd, buffer, 0, maxBytes, 0);
224
- return buffer.subarray(0, bytesRead).toString("utf8");
225
- }
226
- catch {
227
- return undefined;
228
- }
229
- finally {
230
- if (fd !== undefined) {
231
- try {
232
- fs.closeSync(fd);
233
- }
234
- catch {
235
- // ignore close errors
236
- }
237
- }
238
- }
239
- }
240
- export function createDispatchContext(filePath, cwd, pi, facts, blockingOnly, modifiedRanges,
241
- /** Authoritative workspace root; `cwd` may be a nested language root. */
242
- projectRoot,
243
- /** Ordered per-file pipeline token, when this is a post-write dispatch. */
244
- writeIndex,
245
- /** Runtime telemetry identity, when known (#1448) — threaded to the
246
- * worklog append; see DispatchContext.telemetryModel's doc. */
247
- telemetryModel, telemetryProvider) {
248
- const absoluteFilePath = resolveRunnerPath(cwd, filePath);
249
- const normalizedProjectRoot = normalizeMapKey(path.resolve(projectRoot ?? cwd));
250
- const normalizedCwd = normalizeMapKey(resolveLanguageRootForFile(absoluteFilePath, cwd));
251
- const normalizedFilePath = normalizeMapKey(absoluteFilePath);
252
- // `resolveRunnerPath` intentionally normalizes map keys, which folds a
253
- // literal POSIX backslash into a separator. Preserve that one proven
254
- // classifier distinction while still resolving relative inputs from `cwd`.
255
- const kindFilePath = !isWindowsPath(filePath) && filePath.includes("\\")
256
- ? path.resolve(cwd, filePath)
257
- : absoluteFilePath;
258
- const kind = detectFileKind(kindFilePath);
259
- const contentPrefix = readFilePrefix(normalizedFilePath);
260
- const fileRole = detectFileRole(normalizedFilePath, contentPrefix);
261
- // Captured once here so the generated short-circuit below can emit a
262
- // `dispatch_skipped_generated` record carrying the deciding evidence tier
263
- // and the measured line-shape statistic — without re-reading the file
264
- // (refs #2346). The content passed is the same 4096-byte prefix already
265
- // read for role detection, so this classification costs no extra I/O.
266
- const generatedDetail = fileRole === "generated"
267
- ? classifyGeneratedOrArtifactDetailed(normalizedFilePath, {
268
- content: contentPrefix,
269
- includeDeclarations: false,
270
- })
271
- : undefined;
272
- const projectConfig = loadPiLensProjectConfig(normalizedCwd);
273
- return {
274
- filePath: normalizedFilePath,
275
- projectRoot: normalizedProjectRoot,
276
- cwd: normalizedCwd,
277
- kind,
278
- fileRole,
279
- generatedEvidence: generatedDetail?.evidence,
280
- generatedLineShapeMean: generatedDetail?.lineShapeMean,
281
- pi,
282
- autofix: false,
283
- deltaMode: !pi.getFlag("no-delta"),
284
- facts,
285
- projectConfig,
286
- blockingOnly,
287
- modifiedRanges,
288
- writeIndex,
289
- telemetryModel,
290
- telemetryProvider,
291
- toolCwdMemo: {},
292
- async hasTool(command) {
293
- return checkToolAvailability(command, facts);
294
- },
295
- log(message, level) {
296
- // #1333: pi owns the terminal — a runner advisory must never be a raw
297
- // write. Every DispatchContext.log line lands in extension.log instead.
298
- logExtension({
299
- subsystem: "dispatch",
300
- // exactOptionalPropertyTypes: an omitted level must stay omitted.
301
- ...(level !== undefined && { level }),
302
- message,
303
- metadata: { filePath: normalizedFilePath, kind },
304
- });
305
- },
306
- };
307
- }
308
- // --- Delta Mode Logic ---
309
- /**
310
- * Filter diagnostics to only show NEW issues (delta mode)
311
- */
312
- function filterDelta(after, before, keyFn) {
313
- const beforeSet = new Set((before ?? []).map(keyFn));
314
- const afterSet = new Set(after.map(keyFn));
315
- const fixed = (before ?? []).filter((d) => !afterSet.has(keyFn(d)));
316
- const newItems = after.filter((d) => !beforeSet.has(keyFn(d)));
317
- return { new: newItems, fixed };
318
- }
319
- function semanticRank(semantic) {
320
- if (semantic === "blocking")
321
- return 4;
322
- if (semantic === "warning")
323
- return 3;
324
- if (semantic === "fixed")
325
- return 2;
326
- if (semantic === "silent")
327
- return 1;
328
- return 0;
329
- }
330
- function toolPriority(tool, defectClass) {
331
- return getToolProfile(tool, defectClass).dedupPriority;
332
- }
333
- function dedupeOverlappingDiagnostics(diagnostics) {
334
- const byKey = new Map();
335
- for (const d of diagnostics) {
336
- const defectClass = d.defectClass ?? classifyDiagnostic(d);
337
- const line = d.line ?? 1;
338
- const column = d.column ?? 1;
339
- const ruleKey = d.rule || d.id || "unknown";
340
- const key = `${d.filePath}:${line}:${column}:${defectClass}:${ruleKey}`;
341
- const current = byKey.get(key);
342
- if (!current) {
343
- byKey.set(key, { ...d, defectClass });
344
- continue;
345
- }
346
- const currScore = semanticRank(current.semantic) * 100 +
347
- toolPriority(current.tool, defectClass);
348
- const nextScore = semanticRank(d.semantic) * 100 + toolPriority(d.tool, defectClass);
349
- if (nextScore > currScore) {
350
- byKey.set(key, { ...d, defectClass });
351
- }
352
- }
353
- return [...byKey.values()];
354
- }
355
- function suppressLintOverlapsWithLsp(diagnostics) {
356
- const lspBySpanClass = new Set();
357
- const lspByLine = new Set();
358
- const isLintTool = (tool) => {
359
- return getToolProfile(tool).lintLike;
360
- };
361
- for (const d of diagnostics) {
362
- if (d.tool !== "lsp")
363
- continue;
364
- const line = d.line ?? 1;
365
- const defectClass = d.defectClass ?? classifyDiagnostic(d);
366
- lspBySpanClass.add(`${d.filePath}:${line}:${defectClass}`);
367
- lspByLine.add(`${d.filePath}:${line}`);
368
- }
369
- if (lspByLine.size === 0)
370
- return diagnostics;
371
- return diagnostics.filter((d) => {
372
- if (d.tool === "lsp")
373
- return true;
374
- if (!isLintTool(d.tool))
375
- return true;
376
- if (d.semantic === "blocking" || d.severity === "error")
377
- return true;
378
- const line = d.line ?? 1;
379
- const defectClass = d.defectClass ?? classifyDiagnostic(d);
380
- const key = `${d.filePath}:${line}:${defectClass}`;
381
- if (lspBySpanClass.has(key))
382
- return false;
383
- // Conservative fallback for unclassified overlap at same line.
384
- if (defectClass === "unknown") {
385
- return !lspByLine.has(`${d.filePath}:${line}`);
386
- }
387
- return true;
388
- });
389
- }
390
- /**
391
- * Dockerfile overlap dedup (#131 Mode 2): hadolint and `trivy config` both flag
392
- * a few of the same Dockerfile issues (e.g. `:latest`, running as root) with
393
- * different rule ids, which the rule-keyed `dedupeOverlappingDiagnostics` can't
394
- * collapse. Keep hadolint authoritative on the lines it covers and drop the
395
- * trivy-config finding there — trivy still contributes the security checks
396
- * hadolint lacks (on other lines), and all Kubernetes findings (no hadolint
397
- * diagnostics exist for YAML, so none are suppressed). Exported for unit tests.
398
- */
399
- export function suppressTrivyConfigDockerOverlap(diagnostics) {
400
- const hadolintLines = new Set();
401
- for (const d of diagnostics) {
402
- if (d.tool === "hadolint") {
403
- hadolintLines.add(`${d.filePath}:${d.line ?? 1}`);
404
- }
405
- }
406
- if (hadolintLines.size === 0)
407
- return diagnostics;
408
- return diagnostics.filter((d) => d.tool !== "trivy-config" ||
409
- !hadolintLines.has(`${d.filePath}:${d.line ?? 1}`));
410
- }
411
- function isUnusedValueDiagnostic(d) {
412
- const raw = `${d.id ?? ""} ${d.rule ?? ""} ${d.message ?? ""}`.toLowerCase();
413
- if (raw.includes("no-unused"))
414
- return true;
415
- if (/\b(6133|6192|6196)\b/.test(raw))
416
- return true;
417
- const rule = String(d.rule ?? "").toLowerCase();
418
- if (rule.includes("unused"))
419
- return true;
420
- const message = d.message.toLowerCase();
421
- return (message.includes("is declared but its value is never read") ||
422
- message.includes("is assigned a value but never used") ||
423
- message.includes("declared but never used") ||
424
- message.includes("unused"));
425
- }
426
- function promoteDeltaUnusedToBlockers(diagnostics) {
427
- return diagnostics.map((d) => {
428
- if (!isUnusedValueDiagnostic(d))
429
- return d;
430
- if (d.semantic === "blocking" || d.severity === "error")
431
- return d;
432
- return {
433
- ...d,
434
- severity: "error",
435
- semantic: "blocking",
436
- fixSuggestion: d.fixSuggestion ??
437
- "Remove the unused declaration or rename with '_' prefix if intentionally unused.",
438
- };
439
- });
440
- }
441
- function buildCoverageNotice(ctx, runnerLatencies) {
442
- if (!ctx.kind)
443
- return undefined;
444
- const lspEnabled = !ctx.pi.getFlag("no-lsp");
445
- const primary = getPrimaryDispatchGroup(ctx.kind, lspEnabled);
446
- if (!primary || primary.runnerIds.length === 0)
447
- return undefined;
448
- const relevant = runnerLatencies.filter((r) => primary.runnerIds.includes(r.runnerId));
449
- if (relevant.length === 0)
450
- return undefined;
451
- // #1867 catalog shape 4: this is correlation, not classification. The LSP
452
- // touch already decided which scanner publications were absent for these
453
- // bytes; the runner and latency assembly only preserve that exact set.
454
- const unconfirmedServerIds = [
455
- ...new Set(relevant.flatMap((r) => r.unconfirmedServerIds ?? [])),
456
- ];
457
- if (unconfirmedServerIds.length > 0) {
458
- const deferredIds = new Set(relevant.flatMap((r) => r.deferredServerIds ?? []));
459
- const markerFor = (ids) => {
460
- const shown = ids.slice(0, 4);
461
- const remainder = ids.length - shown.length;
462
- return `${shown.join(", ")}${remainder > 0 ? ` +${remainder}` : ""}`;
463
- };
464
- const deferredServerIds = unconfirmedServerIds.filter((id) => deferredIds.has(id));
465
- const silentServerIds = unconfirmedServerIds.filter((id) => !deferredIds.has(id));
466
- // The marker describes this exact scanner set. A scanner can recover
467
- // while another goes dark on the same file, so the set belongs in the
468
- // session dedupe identity rather than only kind and path.
469
- // #2016: these are SCANNER IDS, not filesystem paths. `normalizeMapKey`
470
- // would realpath each one; on Windows that fails, falls through to
471
- // `resolveNonExisting`, and resolves the id against the CURRENT process
472
- // cwd, so the dedupe key differed by platform and by cwd (the #2219
473
- // non-path-sentinel class). The cheap syntactic fold is what this
474
- // session-scoped dedupe key actually needs. Code-unit comparator: the
475
- // sorted set is a KEY, so ordering must be deterministic across locales
476
- // — localeCompare is not.
477
- const dedupeSet = (ids) => [...new Set(ids)]
478
- .map(normalizeEphemeralMapKey)
479
- .sort((a, b) => Number(a > b) - Number(a < b))
480
- .join(",");
481
- // #2810 round 4: the PARTITION is part of the identity, not just the
482
- // scanner set. The same scanner can be silent on one edit and marked for
483
- // late delivery on the next; keying on the unconfirmed set alone showed
484
- // the session whichever message came first and suppressed the other, so a
485
- // scanner that recovered a delivery path (or lost one) kept the stale
486
- // wording for the rest of the session.
487
- const onceKey = `${ctx.kind}:${ctx.filePath}:${dedupeSet(silentServerIds)}|${dedupeSet(deferredServerIds)}`;
488
- if (coverageNoticeSeen.has(onceKey))
489
- return undefined;
490
- coverageNoticeSeen.add(onceKey);
491
- const coverageParts = [];
492
- if (deferredServerIds.length > 0) {
493
- coverageParts.push(`coverage: ${markerFor(deferredServerIds)} deferred — diagnostics are incomplete; findings arrive at turn end if the scan lands.`);
494
- }
495
- if (silentServerIds.length > 0) {
496
- coverageParts.push(`coverage: ${markerFor(silentServerIds)} silent — diagnostics are incomplete (not a clean result).`);
497
- }
498
- return {
499
- id: `coverage-partial:${ctx.kind}:${path.basename(ctx.filePath)}`,
500
- message: coverageParts.join("\n"),
501
- filePath: ctx.filePath,
502
- severity: "warning",
503
- semantic: "warning",
504
- tool: "pi-lens",
505
- };
506
- }
507
- // Check primary runners first
508
- const primaryHasCoverage = relevant.some((r) => r.status === "succeeded" || r.status === "failed");
509
- if (primaryHasCoverage)
510
- return undefined;
511
- const allPrimarySkipped = relevant.every((r) => r.status === "skipped" ||
512
- r.status === "when_skipped" ||
513
- r.status === "test_file_skipped");
514
- if (!allPrimarySkipped)
515
- return undefined;
516
- const plan = getToolPlan(ctx.kind);
517
- const fallbackRunnerIds = new Set((plan?.groups ?? [])
518
- .filter((group) => !group.runnerIds.every((runnerId) => primary.runnerIds.includes(runnerId)))
519
- .flatMap((group) => group.runnerIds)
520
- .filter((runnerId) => !primary.runnerIds.includes(runnerId)));
521
- // Structural-only runners (tree-sitter, ast-grep) are not substitutes
522
- // for real linters — don't suppress the notice if only they ran.
523
- const STRUCTURAL_RUNNERS = new Set([
524
- "tree-sitter",
525
- "ast-grep-napi",
526
- "spellcheck",
527
- "fact-rules",
528
- "opengrep",
529
- ]);
530
- const anyLinterHasCoverage = runnerLatencies.some((r) => fallbackRunnerIds.has(r.runnerId) &&
531
- !STRUCTURAL_RUNNERS.has(r.runnerId) &&
532
- (r.status === "succeeded" || r.status === "failed"));
533
- if (anyLinterHasCoverage)
534
- return undefined;
535
- const onceKey = `${ctx.kind}:${ctx.filePath}`;
536
- if (coverageNoticeSeen.has(onceKey))
537
- return undefined;
538
- coverageNoticeSeen.add(onceKey);
539
- return {
540
- id: `coverage-unavailable:${ctx.kind}:${path.basename(ctx.filePath)}`,
541
- message: `Pi-lens ${ctx.kind} analysis unavailable — language tools are missing or the LSP server isn't ready yet, so this file was not fully checked (not a clean result).`,
542
- filePath: ctx.filePath,
543
- severity: "warning",
544
- semantic: "warning",
545
- tool: "pi-lens",
546
- };
547
- }
548
- const latencyReports = [];
549
- const coverageNoticeSeen = new Set();
550
- // One `dispatch_skipped_generated` phase record per file per process (refs
551
- // #2346): a generated file dispatched repeatedly must not spam latency.log,
552
- // so only the first skip of each file emits the row; the degradation ledger
553
- // below still tallies every repetition with a bounded per-subject count.
554
- const generatedSkipRecorded = new Set();
555
- export function getLatencyReports() {
556
- return [...latencyReports];
557
- }
558
- export function clearLatencyReports() {
559
- latencyReports.length = 0;
560
- }
561
- export function clearCoverageNoticeState() {
562
- coverageNoticeSeen.clear();
563
- generatedSkipRecorded.clear();
564
- }
565
- export function formatLatencyReport(report) {
566
- const lines = [];
567
- lines.push(`\n═══════════════════════════════════════════════════════════════`);
568
- lines.push(`📊 DISPATCH LATENCY REPORT: ${report.filePath.split("/").pop()}`);
569
- lines.push(` Kind: ${report.fileKind || "unknown"} | Total: ${report.totalDurationMs}ms`);
570
- lines.push(`───────────────────────────────────────────────────────────────`);
571
- lines.push(`Runner Duration Status Issues Semantic`);
572
- lines.push(`───────────────────────────────────────────────────────────────`);
573
- for (const r of report.runners) {
574
- const name = r.runnerId.padEnd(30);
575
- const dur = `${r.durationMs}ms`.padStart(8);
576
- const status = r.status.padStart(9);
577
- const issues = String(r.diagnosticCount).padStart(6);
578
- const sem = r.semantic.padStart(8);
579
- const slowMarker = r.durationMs > 500 ? " 🔥" : r.durationMs > 100 ? " ⚡" : "";
580
- lines.push(`${name}${dur}${status}${issues}${sem}${slowMarker}`);
581
- }
582
- lines.push(`───────────────────────────────────────────────────────────────`);
583
- lines.push(`Total: ${report.runners.length} runners | Stopped early: ${report.stoppedEarly}`);
584
- lines.push(`Diagnostics: ${report.totalDiagnostics} (${report.blockers} blockers, ${report.warnings} warnings)`);
585
- // Show top 3 slowest
586
- const sorted = [...report.runners].sort((a, b) => b.durationMs - a.durationMs);
587
- if (sorted.length > 0 && sorted[0].durationMs > 100) {
588
- lines.push(`\n🐌 Slowest runners:`);
589
- for (const r of sorted.slice(0, 3)) {
590
- if (r.durationMs > 50) {
591
- lines.push(` ${r.runnerId}: ${r.durationMs}ms (${r.status})`);
592
- }
593
- }
594
- }
595
- lines.push(`═══════════════════════════════════════════════════════════════`);
596
- return lines.join("\n");
597
- }
598
- /**
599
- * Execute all runners in a single group.
600
- *
601
- * - mode "fallback": run runners sequentially and stop at the first
602
- * one that succeeds (returns status !== "skipped").
603
- * - mode "all" (default): run all runners in the group sequentially
604
- * and collect every diagnostic.
605
- *
606
- * Groups themselves are run in parallel by dispatchForFile, so this
607
- * function must NOT mutate shared state.
608
- */
609
- async function runGroup(ctx, group, registry, onRunnerResult) {
610
- const diagnostics = [];
611
- const latencies = [];
612
- let hadBlocker = false;
613
- // Filter runners by kind if specified
614
- const runnerIds = group.filterKinds
615
- ? group.runnerIds.filter((id) => {
616
- const runner = registry.get(id);
617
- return runner && ctx.kind && group.filterKinds?.includes(ctx.kind);
618
- })
619
- : group.runnerIds;
620
- const semantic = group.semantic ?? "warning";
621
- for (const runnerId of runnerIds) {
622
- const runnerStart = Date.now();
623
- const runner = registry.get(runnerId);
624
- if (!runner) {
625
- latencies.push({
626
- runnerId,
627
- startTime: runnerStart,
628
- endTime: Date.now(),
629
- durationMs: 0,
630
- status: "skipped",
631
- diagnosticCount: 0,
632
- semantic: "unknown",
633
- });
634
- logLatency({
635
- type: "runner",
636
- filePath: ctx.filePath,
637
- runnerId,
638
- durationMs: 0,
639
- status: "not_registered",
640
- diagnosticCount: 0,
641
- semantic: "unknown",
642
- });
643
- continue;
644
- }
645
- // Same skipTestFiles gate RunnerRegistry.getForKind applies for the
646
- // per-edit path (#2337): the plan/group path resolves runners by id via
647
- // registry.get() instead, which bypasses getForKind entirely, so a
648
- // runner declaring skipTestFiles never had it enforced here.
649
- if (runner.skipTestFiles && isTestFile(ctx.filePath)) {
650
- latencies.push({
651
- runnerId,
652
- startTime: runnerStart,
653
- endTime: Date.now(),
654
- durationMs: Date.now() - runnerStart,
655
- status: "test_file_skipped",
656
- diagnosticCount: 0,
657
- semantic: "none",
658
- });
659
- logLatency({
660
- type: "runner",
661
- filePath: ctx.filePath,
662
- runnerId,
663
- durationMs: 0,
664
- status: "test_file_skipped",
665
- diagnosticCount: 0,
666
- semantic: "none",
667
- });
668
- continue;
669
- }
670
- // Keep explicit groups aligned with RunnerRegistry.getForKind(): an empty
671
- // appliesTo list means every kind, while a populated list must contain the
672
- // current kind. A filtered runner remains visible as skipped telemetry so
673
- // language mismatches cannot be mistaken for runner failures.
674
- const appliesToCurrentKind = runnerAppliesToKind(runner, ctx.kind);
675
- if (!appliesToCurrentKind) {
676
- const runnerEnd = Date.now();
677
- latencies.push({
678
- runnerId,
679
- startTime: runnerStart,
680
- endTime: runnerEnd,
681
- durationMs: 0,
682
- status: "skipped",
683
- diagnosticCount: 0,
684
- semantic: "unknown",
685
- });
686
- logLatency({
687
- type: "runner",
688
- filePath: ctx.filePath,
689
- runnerId,
690
- durationMs: 0,
691
- status: "skipped",
692
- diagnosticCount: 0,
693
- semantic: "unknown",
694
- metadata: { reason: "applies_to", kind: ctx.kind },
695
- });
696
- continue;
697
- }
698
- // Check preconditions
699
- let shouldRun = true;
700
- if (runner.when) {
701
- try {
702
- shouldRun = await runner.when(ctx);
703
- }
704
- catch (error) {
705
- ctx.log(`Runner ${runner.id} precondition failed: ${error}`);
706
- shouldRun = false;
707
- }
708
- }
709
- if (!shouldRun) {
710
- latencies.push({
711
- runnerId,
712
- startTime: runnerStart,
713
- endTime: Date.now(),
714
- durationMs: Date.now() - runnerStart,
715
- status: "when_skipped",
716
- diagnosticCount: 0,
717
- semantic: runner.id,
718
- });
719
- logLatency({
720
- type: "runner",
721
- filePath: ctx.filePath,
722
- runnerId,
723
- durationMs: 0,
724
- status: "when_skipped",
725
- diagnosticCount: 0,
726
- semantic: "when_condition",
727
- });
728
- continue;
729
- }
730
- const projectRoot = ctx.projectRoot ?? ctx.cwd;
731
- // Only post-write dispatches participate. Project scans and direct API
732
- // callers must retain their existing synchronous semantics.
733
- const observedTier = ctx.writeIndex === undefined
734
- ? "inline"
735
- : classifyObservedRunner(projectRoot, runner.id);
736
- if (observedTier === "collect-later") {
737
- const markedAtMs = Date.now();
738
- const deferred = runRunner(ctx, runner, semantic).then((result) => {
739
- const durationMs = Date.now() - markedAtMs;
740
- const tier = observeRunnerLatency({
741
- projectRoot,
742
- runnerId: runner.id,
743
- durationMs,
744
- timedOut: result.failureKind === "timeout",
745
- });
746
- if (tier !== observedTier) {
747
- logLatency({
748
- type: "phase",
749
- filePath: ctx.filePath,
750
- phase: "runner_collect_later_tier_flip",
751
- durationMs: 0,
752
- metadata: {
753
- runnerId: runner.id,
754
- from: observedTier,
755
- to: tier,
756
- projectRoot,
757
- },
758
- });
759
- }
760
- if (tier === "collect-later") {
761
- incrementDegradationCount({
762
- kind: "runner-collect-later",
763
- subject: `${projectRoot}:${runner.id}`,
764
- reason: `observed ${durationMs}ms, threshold ${COLLECT_LATER_THRESHOLD_MS}ms`,
765
- });
766
- }
767
- logLatency({
768
- type: "runner",
769
- filePath: ctx.filePath,
770
- runnerId: runner.id,
771
- startedAt: new Date(markedAtMs).toISOString(),
772
- durationMs,
773
- status: result.status,
774
- diagnosticCount: result.diagnostics.length,
775
- semantic: result.semantic ?? semantic,
776
- metadata: { tier: "collect-later", delivered: "turn_end" },
777
- });
778
- return result;
779
- });
780
- deferRunnerFindings({
781
- filePath: ctx.filePath,
782
- cwd: ctx.cwd,
783
- projectRoot,
784
- runnerId: runner.id,
785
- markedAtMs,
786
- writeIndex: ctx.writeIndex,
787
- promise: deferred,
788
- });
789
- // A deferred runner is still an observed runner. Keep it visible in
790
- // both the edit latency report and the widget until its turn-end result
791
- // replaces this pending state (#2122 F1).
792
- latencies.push({
793
- runnerId: runner.id,
794
- startTime: runnerStart,
795
- endTime: runnerStart,
796
- durationMs: 0,
797
- status: "pending",
798
- diagnosticCount: 0,
799
- semantic: semantic,
800
- });
801
- recordRunner(ctx.filePath, runner.id, "pending", 0, 0, ctx.writeIndex);
802
- logLatency({
803
- type: "runner",
804
- filePath: ctx.filePath,
805
- runnerId: runner.id,
806
- durationMs: 0,
807
- status: "pending",
808
- diagnosticCount: 0,
809
- semantic,
810
- metadata: { tier: "collect-later", delivered: "turn_end" },
811
- });
812
- continue;
813
- }
814
- const result = await runRunner(ctx, runner, semantic);
815
- onRunnerResult?.(runnerId, result);
816
- const runnerEnd = Date.now();
817
- const duration = runnerEnd - runnerStart;
818
- const tier = ctx.writeIndex === undefined
819
- ? "inline"
820
- : observeRunnerLatency({
821
- projectRoot,
822
- runnerId: runner.id,
823
- durationMs: duration,
824
- timedOut: result.failureKind === "timeout",
825
- });
826
- if (tier !== observedTier) {
827
- logLatency({
828
- type: "phase",
829
- filePath: ctx.filePath,
830
- phase: "runner_collect_later_tier_flip",
831
- durationMs: 0,
832
- metadata: {
833
- runnerId: runner.id,
834
- from: observedTier,
835
- to: tier,
836
- projectRoot,
837
- },
838
- });
839
- }
840
- if (tier === "collect-later") {
841
- incrementDegradationCount({
842
- kind: "runner-collect-later",
843
- subject: `${projectRoot}:${runner.id}`,
844
- reason: `observed ${duration}ms, threshold ${COLLECT_LATER_THRESHOLD_MS}ms`,
845
- });
846
- }
847
- // Runner definitions are a typed API, but embedders/plugins can still
848
- // return untyped objects at runtime. Admit only the closed taxonomy and
849
- // only on actual skips so free text cannot enter durable latency metadata.
850
- const skipReason = result.status === "skipped" && isRunnerSkipReason(result.skipReason)
851
- ? result.skipReason
852
- : undefined;
853
- latencies.push({
854
- runnerId,
855
- startTime: runnerStart,
856
- endTime: runnerEnd,
857
- durationMs: duration,
858
- status: result.status,
859
- diagnosticCount: result.diagnostics.length,
860
- semantic: result.semantic ?? semantic,
861
- ...(skipReason !== undefined && {
862
- skipReason,
863
- }),
864
- ...(result.unconfirmedServerIds !== undefined && {
865
- unconfirmedServerIds: result.unconfirmedServerIds,
866
- }),
867
- ...(result.deferredServerIds !== undefined && {
868
- deferredServerIds: result.deferredServerIds,
869
- }),
870
- });
871
- logLatency({
872
- type: "runner",
873
- filePath: ctx.filePath,
874
- runnerId,
875
- startedAt: new Date(runnerStart).toISOString(),
876
- durationMs: duration,
877
- status: result.status,
878
- diagnosticCount: result.diagnostics.length,
879
- semantic: result.semantic ?? semantic,
880
- diagnostics: result.diagnostics.length > 0
881
- ? result.diagnostics.map((d) => ({
882
- rule: d.rule,
883
- message: d.message.slice(0, 120),
884
- line: d.line,
885
- semantic: d.semantic,
886
- }))
887
- : undefined,
888
- metadata: result.status === "failed" && result.failureKind
889
- ? {
890
- failureKind: result.failureKind,
891
- failureMessage: result.failureMessage,
892
- }
893
- : skipReason
894
- ? { skipReason }
895
- : undefined,
896
- });
897
- recordRunner(ctx.filePath, runnerId, result.status, result.diagnostics.length, duration, ctx.writeIndex);
898
- diagnostics.push(...result.diagnostics);
899
- const resultSemantic = result.semantic ?? semantic;
900
- if ((resultSemantic === "blocking" && result.diagnostics.length > 0) ||
901
- result.diagnostics.some((d) => d.semantic === "blocking")) {
902
- hadBlocker = true;
903
- }
904
- // mode:"fallback" — stop at first successful runner
905
- if (group.mode === "fallback" && result.status === "succeeded") {
906
- break;
907
- }
908
- }
909
- return { diagnostics, latencies, hadBlocker };
910
- }
911
- // --- Main Dispatch Function ---
912
- export async function dispatchForFile(ctx, groups, registry, onRunnerResult) {
913
- const _overallStart = Date.now();
914
- if (ctx.fileRole === "generated") {
915
- // The generated short-circuit (refs #2346): never ran before this fix
916
- // for name-less machine-emitted files (a scraped/minified page has no
917
- // `.min.js` pattern to catch it), so the classification now also has a
918
- // content-shape tier. The skip is observable — one `dispatch_skipped_generated`
919
- // phase record per file per process carrying the deciding evidence tier
920
- // and the measured line-shape statistic. Deliberately NOT a degradation
921
- // ledger entry: skipping a generated file is healthy behavior working
922
- // as designed, and the ledger's bounded kind slots are reserved for
923
- // genuine degradations (#2348 review F3 — the ledger precedent at the
924
- // collect-later tier flip below records an actual capability loss).
925
- const evidence = ctx.generatedEvidence;
926
- const lineShapeMean = ctx.generatedLineShapeMean;
927
- if (!generatedSkipRecorded.has(ctx.filePath)) {
928
- generatedSkipRecorded.add(ctx.filePath);
929
- logLatency({
930
- type: "phase",
931
- filePath: ctx.filePath,
932
- phase: "dispatch_skipped_generated",
933
- durationMs: 0,
934
- metadata: {
935
- evidence: evidence ?? "unknown",
936
- ...(lineShapeMean !== undefined && { lineShapeMean }),
937
- },
938
- });
939
- }
940
- return {
941
- diagnostics: [],
942
- blockers: [],
943
- warnings: [],
944
- baselineWarningCount: 0,
945
- fixed: [],
946
- resolvedCount: 0,
947
- output: "",
948
- blockerOutput: "",
949
- hasBlockers: false,
950
- };
951
- }
952
- const allDiagnostics = [];
953
- let stopped = false;
954
- const runnerLatencies = [];
955
- // Debug logging goes to latency log only (not console - avoid noise)
956
- const allRunnerIds = groups.flatMap((g) => g.runnerIds);
957
- logLatency({
958
- type: "phase",
959
- filePath: ctx.filePath,
960
- phase: "dispatch_start",
961
- durationMs: 0,
962
- metadata: {
963
- groupCount: groups.length,
964
- kind: ctx.kind,
965
- runners: allRunnerIds.join(","),
966
- },
967
- });
968
- // Run all groups in parallel — they are independent and don't depend on
969
- // each other's results. Within each group, mode:"fallback" semantics are
970
- // preserved (sequential first-success). Results are merged in original
971
- // group order so output is deterministic.
972
- const groupResults = await Promise.all(groups.map((group) => runGroup(ctx, group, registry, onRunnerResult)));
973
- // Count baseline warnings before filtering (for delta count display)
974
- //
975
- // #2489: `ctx.filePath` is `createDispatchContext`'s `normalizedFilePath`
976
- // (`resolveRunnerPath` -> `path.resolve` -> `normalizeMapKey`), which is
977
- // ALWAYS absolute — the #2016 invariant this seam already relies on. A
978
- // prior relative-path fallback key (`session.baseline.<path relative to
979
- // ctx.cwd>`) existed here for self-consistency across the abs/rel read
980
- // and write, but on `ctx.facts` singletons that outlive one project root
981
- // (`dispatch/integration.ts`'s module-scope `sessionFacts`, reached by
982
- // the warm `pilens_analyze` MCP route across any number of cwds) two
983
- // different projects dispatching files that share a relative path (e.g.
984
- // both have `src/index.ts`) collided on that fallback key, so project
985
- // B's first-ever delta baseline read could silently return project A's
986
- // stored diagnostics. Since the absolute key can never collide across
987
- // projects (an absolute path is unique on the filesystem) and both
988
- // writes always land together, the relative fallback is both unneeded
989
- // and the sole source of the collision — removed rather than cwd-scoped
990
- // (`cwd` is not a stable identity across this seam's callers, #2494).
991
- //
992
- // #2489 round 2: the #2016 invariant above is enforced by
993
- // `createDispatchContext`, the sole real constructor, but nothing enforced
994
- // it AT THIS SEAM — a hand-built `DispatchContext` (test scaffolding, a
995
- // future caller) carrying a relative `filePath` would silently key the
996
- // baseline under a value the constructor could never produce, and every
997
- // subsequent same-session dispatch of the real (absolute-keyed) file would
998
- // read back `undefined`, never the collision itself. Mirrors the sibling
999
- // guard `recordEntitySnapshotDiff` already enforces for the entity-snapshot
1000
- // seam (`clients/review-graph/service.ts`, #2477): reject visibly and skip
1001
- // the baseline read/write for this dispatch rather than compute one under
1002
- // an unreachable key.
1003
- const baselinePathSafe = isAbsoluteFilePath(ctx.filePath);
1004
- if (ctx.deltaMode && !baselinePathSafe) {
1005
- recordDegradationOnce({
1006
- kind: "dispatch-non-absolute-baseline-path",
1007
- subject: ctx.filePath,
1008
- reason: "dispatchForFile requires an absolute ctx.filePath to key the delta baseline (refs #2489)",
1009
- });
1010
- }
1011
- const baselineAbsKey = `session.baseline.${ctx.filePath}`;
1012
- const previousBaseline = ctx.deltaMode && baselinePathSafe
1013
- ? ctx.facts.getBoundedSessionFact(baselineAbsKey)
1014
- : undefined;
1015
- const baselineWarnings = previousBaseline?.filter((d) => d.semantic === "warning" || d.semantic === "none");
1016
- const baselineWarningCount = baselineWarnings?.length ?? 0;
1017
- for (const { diagnostics: groupDiags, latencies, hadBlocker, } of groupResults) {
1018
- runnerLatencies.push(...latencies);
1019
- allDiagnostics.push(...groupDiags);
1020
- if (hadBlocker)
1021
- stopped = true;
1022
- }
1023
- // Apply delta mode ONCE across the full diagnostic set.
1024
- // This avoids partial-baseline corruption when processing multiple groups.
1025
- const dedupedDiagnostics = dedupeOverlappingDiagnostics(allDiagnostics);
1026
- const fileContent = ctx.facts.getFileFact(ctx.filePath, "file.content") ?? "";
1027
- // Project rule policy (`.pi-lens.json` `rules.<id>.disable`/`select`).
1028
- //
1029
- // Resolved from `ctx.projectRoot` (falling back to `ctx.cwd`), NOT
1030
- // `ctx.projectConfig` — `ctx.projectConfig` is loaded from the nested
1031
- // LANGUAGE root (`resolveLanguageRootForFile`), so in a monorepo where a
1032
- // package directory has its own `.pi-lens.json`, `discoverPiLensProjectConfig`'s
1033
- // upward walk stops there and never sees a repo-root policy.
1034
- // `lens_diagnostics` loads its policy map from `runtime.projectRoot`; using
1035
- // the same root here keeps the two surfaces in agreement. `ctx.projectConfig`
1036
- // itself is untouched — thresholds and mutation flags keep their existing
1037
- // language-root resolution.
1038
- const rulePolicy = rulePolicyMapFromConfig(loadPiLensProjectConfig(ctx.projectRoot ?? ctx.cwd).rules);
1039
- // The output-only filter pipeline: LSP/docker overlap suppression + inline
1040
- // `pi-lens-ignore` + agent/user dispositions + project rule policy. Applied
1041
- // AFTER dedupe so the pi renderer, widget, and delta all see one filtered
1042
- // set. #690: dispositions drop false-positive/suppress marks and anything
1043
- // deferred this session (flagged marks stay; lens_diagnostics tags them at
1044
- // render time). #1030: the disposition anchor + store MUST key off the
1045
- // PROJECT ROOT, not ctx.cwd — the mark tool writes dispositions under
1046
- // runtime.projectRoot, so reading from ctx.cwd (the nested language root in
1047
- // a monorepo) opened a different diagnostic-dispositions.json and silently
1048
- // no-op'd every mark under a nested marker.
1049
- //
1050
- // #1087: "silencing is not fixing" applies to the WHOLE class, not just the
1051
- // policy member. This single pipeline is applied identically to the live set
1052
- // AND (below) to the delta baseline, so a finding persistently dropped by
1053
- // ANY layer — overlap, inline suppression, disposition, or policy — is
1054
- // absent from both sides of the delta and never oscillates into `fixed`
1055
- // (which `trackAgentFixed` would otherwise inflate forever). The stored
1056
- // baseline remains the unfiltered `dedupedDiagnostics`, so editing a
1057
- // project's policy/suppressions never resets or corrupts the user-authored
1058
- // delta baseline — the filtering is re-derived on read for both sides.
1059
- const applyOutputFilters = (diags) => {
1060
- const dockerOverlap = suppressTrivyConfigDockerOverlap(diags);
1061
- const overlap = suppressLintOverlapsWithLsp(dockerOverlap);
1062
- const inline = applyInlineSuppressions(overlap, fileContent);
1063
- const disposition = applyDispositions(inline, ctx.projectRoot ?? ctx.cwd, ctx.filePath, fileContent);
1064
- return applyRulePolicy(disposition, rulePolicy);
1065
- };
1066
- let visibleDiagnostics = applyOutputFilters(dedupedDiagnostics);
1067
- let resolvedCount = 0;
1068
- if (ctx.deltaMode && previousBaseline) {
1069
- // Silencing a rule is not fixing it. The stored baseline is deliberately
1070
- // unfiltered (below), so compare against a fully-filtered view of it
1071
- // through the SAME pipeline — otherwise every persistently-suppressed
1072
- // finding sits in `fixed` on every dispatch and inflates the agent's
1073
- // resolved tally (trackAgentFixed) forever. Only `fixed` changes:
1074
- // filtered-out ids are absent from `after` either way.
1075
- const filtered = filterDelta(visibleDiagnostics, applyOutputFilters(previousBaseline), (d) => d.id);
1076
- visibleDiagnostics = promoteDeltaUnusedToBlockers(filtered.new);
1077
- resolvedCount = filtered.fixed.length;
1078
- }
1079
- // Persist full current snapshot for next run (not delta-filtered subset).
1080
- // Gated on `baselinePathSafe` too: a non-absolute `ctx.filePath` already
1081
- // skipped the read above (the degradation record fired there), and writing
1082
- // under that same unreachable key here would just seed a baseline no real
1083
- // reader (always absolute) could ever read back.
1084
- if (ctx.deltaMode && baselinePathSafe) {
1085
- ctx.facts.setBoundedSessionFact(baselineAbsKey, [...dedupedDiagnostics]);
1086
- }
1087
- // Categorize results
1088
- const blockers = visibleDiagnostics.filter((d) => d.semantic === "blocking");
1089
- const warnings = visibleDiagnostics.filter((d) => d.semantic === "warning" || d.semantic === "none");
1090
- const fixedItems = visibleDiagnostics.filter((d) => d.semantic === "fixed");
1091
- // Append fixed and fixable diagnostics to the persistent worklog, attributed
1092
- // to the runtime's active model/provider when known (#1448).
1093
- const worklogIdentity = {
1094
- model: ctx.telemetryModel,
1095
- provider: ctx.telemetryProvider,
1096
- };
1097
- if (fixedItems.length > 0) {
1098
- import("../fix-worklog.js")
1099
- .then(({ appendToWorklog }) => {
1100
- appendToWorklog(ctx.cwd, fixedItems, true, worklogIdentity);
1101
- })
1102
- .catch(() => { });
1103
- }
1104
- const fixableWarnings = warnings.filter((d) => d.fixable);
1105
- if (fixableWarnings.length > 0) {
1106
- import("../fix-worklog.js")
1107
- .then(({ appendToWorklog }) => {
1108
- appendToWorklog(ctx.cwd, fixableWarnings, false, worklogIdentity);
1109
- })
1110
- .catch(() => { });
1111
- }
1112
- const inlineBlockers = blockers;
1113
- const inlineFixed = fixedItems;
1114
- const coverageNotice = buildCoverageNotice(ctx, runnerLatencies);
1115
- // Format output — only blocking issues shown inline
1116
- // Warnings tracked but not shown (noise) — surfaced via lens_diagnostics
1117
- const blockerOutput = formatDiagnostics(inlineBlockers, "blocking");
1118
- let output = blockerOutput;
1119
- output += formatDiagnostics(inlineFixed, "fixed");
1120
- if (coverageNotice) {
1121
- output += formatDiagnostics([coverageNotice], "warning", 1);
1122
- warnings.push(coverageNotice);
1123
- }
1124
- const pendingRunners = runnerLatencies
1125
- .filter((runner) => runner.status === "pending")
1126
- .map((runner) => runner.runnerId);
1127
- if (pendingRunners.length > 0) {
1128
- output += `\n⏳ Pending runners (reported at turn end): ${pendingRunners.join(", ")}\n`;
1129
- }
1130
- // Generate and store latency report
1131
- const overallEnd = Date.now();
1132
- const latencyReport = {
1133
- filePath: ctx.filePath,
1134
- fileKind: ctx.kind,
1135
- overallStartMs: _overallStart,
1136
- overallEndMs: overallEnd,
1137
- totalDurationMs: overallEnd - _overallStart,
1138
- runners: runnerLatencies,
1139
- stoppedEarly: stopped,
1140
- totalDiagnostics: visibleDiagnostics.length,
1141
- blockers: blockers.length,
1142
- warnings: warnings.length,
1143
- };
1144
- // Store for later analysis
1145
- latencyReports.push(latencyReport);
1146
- // Keep only last 100 reports to prevent memory bloat
1147
- if (latencyReports.length > 100) {
1148
- latencyReports.shift();
1149
- }
1150
- // Runner latencies already logged immediately after execution (line ~329)
1151
- // The runnerLatencies array is stored in latencyReport for aggregate analysis
1152
- // No need to log again here - would create duplicates in the log
1153
- // Log summary to latency log only (not console - avoid noise)
1154
- const sumMs = runnerLatencies.reduce((s, r) => s + r.durationMs, 0);
1155
- const wallClockMs = latencyReport.totalDurationMs;
1156
- logLatency({
1157
- type: "tool_result",
1158
- filePath: ctx.filePath,
1159
- durationMs: wallClockMs,
1160
- wallClockMs,
1161
- sumMs,
1162
- parallelGainMs: Math.max(0, sumMs - wallClockMs),
1163
- result: "dispatch_complete",
1164
- metadata: {
1165
- runners: runnerLatencies.map((r) => ({
1166
- id: r.runnerId,
1167
- startedAt: new Date(r.startTime).toISOString(),
1168
- duration: r.durationMs,
1169
- status: r.status,
1170
- })),
1171
- totalDiagnostics: visibleDiagnostics.length,
1172
- blockers: blockers.length,
1173
- // #2489 round 2: distinguishes a delta baseline HIT (a prior snapshot
1174
- // was read for this file this session) from a MISS (first dispatch, or
1175
- // the non-absolute-path guard above skipped the read) — `dispatch_start`
1176
- // (above, `metadata: { groupCount, kind, runners }`) fires before the
1177
- // baseline read ever runs and cannot carry either value.
1178
- baselineHit: previousBaseline !== undefined,
1179
- baselineWarningCount,
1180
- },
1181
- });
1182
- return {
1183
- diagnostics: visibleDiagnostics,
1184
- blockers,
1185
- warnings,
1186
- baselineWarningCount,
1187
- fixed: fixedItems,
1188
- resolvedCount,
1189
- output,
1190
- blockerOutput,
1191
- hasBlockers: blockers.length > 0,
1192
- };
1193
- }
1194
- // --- Run Single Runner ---
1195
- /** Maximum wall-clock time a single runner may take before we abort it. */
1196
- const RUNNER_TIMEOUT_MS = RUNTIME_CONFIG.dispatch.runnerTimeoutMs;
1197
- function looksLikeDiagnosticCodePath(value) {
1198
- if (!value)
1199
- return false;
1200
- const text = value.trim();
1201
- if (!text)
1202
- return false;
1203
- const base = path.basename(text.replace(/\\/g, "/"));
1204
- if (/^lsp:\d+(?::\d+)?$/i.test(text) || /^lsp:\d+(?::\d+)?$/i.test(base)) {
1205
- return true;
1206
- }
1207
- if (/^similarity[-:]/i.test(text) || /^similarity[-:]/i.test(base)) {
1208
- return true;
1209
- }
1210
- if (/^[a-z-]+:\d+(?::\d+)?$/i.test(text) ||
1211
- /^[a-z-]+:\d+(?::\d+)?$/i.test(base)) {
1212
- return true;
1213
- }
1214
- return false;
1215
- }
1216
- function normalizeDiagnosticFilePath(ctx, rawPath) {
1217
- if (typeof rawPath === "string" && looksLikeDiagnosticCodePath(rawPath)) {
1218
- ctx.log(`runner path normalization: ignored diagnostic code-like path '${rawPath}', using current file`);
1219
- return resolveRunnerPath(ctx.cwd, ctx.filePath);
1220
- }
1221
- return resolveRunnerPath(ctx.cwd, rawPath || ctx.filePath);
1222
- }
1223
- async function runRunner(ctx, runner, defaultSemantic) {
1224
- const timeoutMs = Math.max(runner.timeoutMs ?? RUNNER_TIMEOUT_MS, getRunnerTimeoutFloorMs());
1225
- let timer;
1226
- // #1723: mark this runner as the in-flight phase for the WHOLE race below,
1227
- // not just the runner's own promise — a synchronous CPU hog inside
1228
- // `runner.run` (ast-grep-napi, tree-sitter, …) blocks the event loop before
1229
- // it ever gets to log its own completion, so `recentPhases` (which only
1230
- // records FINISHED phases) can't name it. `phaseFinished` clears on every
1231
- // exit from this race (success, runner error, or timeout) via try/finally,
1232
- // so a `loop_block` sampled after this call returns never sees a stale
1233
- // pointer. See `phaseStarted`'s doc comment for the identity-token
1234
- // reasoning and the cost note (negligible next to a runner invocation).
1235
- const phaseToken = phaseStarted(runner.id);
1236
- try {
1237
- const result = await Promise.race([
1238
- runner.run(ctx).finally(() => clearTimeout(timer)),
1239
- new Promise((_, reject) => {
1240
- timer = setTimeout(() => reject(new Error(`Runner ${runner.id} timed out after ${timeoutMs}ms`)), timeoutMs);
1241
- }),
1242
- ]);
1243
- const diagnostics = result.diagnostics.map((d) => ({
1244
- ...d,
1245
- filePath: normalizeDiagnosticFilePath(ctx, d.filePath),
1246
- }));
1247
- return {
1248
- ...result,
1249
- diagnostics,
1250
- semantic: result.semantic ?? defaultSemantic,
1251
- };
1252
- }
1253
- catch (error) {
1254
- clearTimeout(timer);
1255
- ctx.log(`Runner ${runner.id} failed: ${error}`);
1256
- const message = error instanceof Error ? error.message : String(error);
1257
- return {
1258
- status: "failed",
1259
- diagnostics: [],
1260
- semantic: defaultSemantic,
1261
- failureKind: message.includes("timed out") ? "timeout" : "exception",
1262
- failureMessage: message.slice(0, 200),
1263
- };
1264
- }
1265
- finally {
1266
- phaseFinished(phaseToken);
1267
- }
1268
- }
1269
- // --- Simple Integration Helper ---