pi-lens 4.2.1 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (671) hide show
  1. package/CHANGELOG.md +1562 -0
  2. package/README.md +157 -24
  3. package/config/dependency-cruiser-eager-allowlist.json +6 -2
  4. package/dist/chunk-22AVIGXS.js +560 -0
  5. package/dist/chunk-27BBHSZC.js +106 -0
  6. package/dist/chunk-2BEMIWEW.js +51 -0
  7. package/dist/chunk-2EECBNC5.js +89 -0
  8. package/dist/chunk-34U7PLGE.js +23 -0
  9. package/dist/chunk-3I5QFT3N.js +181 -0
  10. package/dist/chunk-3MED75HT.js +37 -0
  11. package/dist/chunk-47D2BO4S.js +87 -0
  12. package/dist/chunk-4RERDEXR.js +348 -0
  13. package/dist/chunk-4W2PLC4J.js +27 -0
  14. package/dist/chunk-52H5B5TC.js +202 -0
  15. package/dist/chunk-54B42YRX.js +27 -0
  16. package/dist/chunk-5RXBNSW2.js +266 -0
  17. package/dist/chunk-5THXD6X5.js +201 -0
  18. package/dist/chunk-5W3R6LFT.js +24 -0
  19. package/dist/chunk-5ZEJHV35.js +341 -0
  20. package/dist/chunk-6P62QVEA.js +118 -0
  21. package/dist/chunk-6QIUX4EP.js +459 -0
  22. package/dist/chunk-6VCD4VKZ.js +78 -0
  23. package/dist/chunk-7F72PXY2.js +326 -0
  24. package/dist/chunk-7FBF7NPR.js +998 -0
  25. package/dist/chunk-7U2IDNXN.js +37 -0
  26. package/dist/chunk-ABBOA7UD.js +157 -0
  27. package/dist/chunk-AHDW3GPE.js +50 -0
  28. package/dist/chunk-AJ3QXTRQ.js +756 -0
  29. package/dist/chunk-AJVLWNFN.js +1610 -0
  30. package/dist/chunk-AJXODZY6.js +112 -0
  31. package/dist/chunk-ARFCXG7S.js +84 -0
  32. package/dist/chunk-AS44CFQ4.js +708 -0
  33. package/dist/chunk-AWE5TMPO.js +38 -0
  34. package/dist/chunk-B3I2UUT4.js +4692 -0
  35. package/dist/chunk-BRJKOBZP.js +331 -0
  36. package/dist/chunk-BW5KFIQC.js +59 -0
  37. package/dist/chunk-C2AUYXQH.js +149 -0
  38. package/dist/chunk-CGGAIP7J.js +29 -0
  39. package/dist/chunk-D6QS3U6M.js +30 -0
  40. package/dist/chunk-DFVMIKMQ.js +349 -0
  41. package/dist/chunk-DIULIWKU.js +169 -0
  42. package/dist/chunk-DQ2NZ7C4.js +2317 -0
  43. package/dist/chunk-E2WFBRHM.js +213 -0
  44. package/dist/chunk-E4MAEDPM.js +50 -0
  45. package/dist/chunk-EOKRQ3SA.js +30 -0
  46. package/dist/chunk-F3AU2TMM.js +2626 -0
  47. package/dist/chunk-F3P7VQ7H.js +170 -0
  48. package/dist/chunk-FC4RP4I2.js +12 -0
  49. package/dist/chunk-FJNKANOS.js +32 -0
  50. package/dist/chunk-GUOGVTCQ.js +146 -0
  51. package/dist/chunk-GVXA6CCE.js +18 -0
  52. package/dist/chunk-HHYAELLJ.js +2334 -0
  53. package/dist/chunk-HMFXILPV.js +83 -0
  54. package/dist/chunk-HVUZXSWK.js +421 -0
  55. package/dist/chunk-HWBZIGMJ.js +62 -0
  56. package/dist/chunk-I3R7GKDR.js +17 -0
  57. package/dist/chunk-I7SPGOWI.js +55 -0
  58. package/dist/chunk-IIXOAGHR.js +38 -0
  59. package/dist/chunk-IVP5KAB7.js +2250 -0
  60. package/dist/chunk-IXEBJSUE.js +22 -0
  61. package/dist/chunk-JOLITGCC.js +27 -0
  62. package/dist/chunk-K6VYLB2U.js +145 -0
  63. package/dist/chunk-LJDODBBZ.js +78 -0
  64. package/dist/chunk-LNAKEO63.js +78 -0
  65. package/dist/chunk-LSMJ6KBE.js +4139 -0
  66. package/dist/chunk-LW6XKDZQ.js +5565 -0
  67. package/dist/chunk-N3YQJI6O.js +899 -0
  68. package/dist/chunk-NABLC7W3.js +148 -0
  69. package/dist/chunk-NKOUFPQF.js +659 -0
  70. package/dist/chunk-NL5GLMFI.js +211 -0
  71. package/dist/chunk-NMABWBZN.js +327 -0
  72. package/dist/chunk-NTHH2J74.js +27 -0
  73. package/dist/chunk-NTUJEGDZ.js +59 -0
  74. package/dist/chunk-NXL4FFQQ.js +47 -0
  75. package/dist/chunk-NXPS2L6U.js +466 -0
  76. package/dist/chunk-O5WILGMI.js +42 -0
  77. package/dist/chunk-O6TQT6RI.js +48 -0
  78. package/dist/chunk-OAXNDZJ7.js +323 -0
  79. package/dist/chunk-ODEEOXPH.js +44 -0
  80. package/dist/chunk-OQGFCZJ4.js +4533 -0
  81. package/dist/chunk-ORTMY4Q4.js +282 -0
  82. package/dist/chunk-OS32RNR2.js +442 -0
  83. package/dist/chunk-PAK6IDME.js +189 -0
  84. package/dist/chunk-PWFHBTSF.js +406 -0
  85. package/dist/chunk-Q5U6FMDI.js +2352 -0
  86. package/dist/chunk-QOZXJ4NA.js +3364 -0
  87. package/dist/chunk-QYF5S6P6.js +45 -0
  88. package/dist/chunk-RIISMHKN.js +36 -0
  89. package/dist/chunk-RPD4ZSB7.js +25 -0
  90. package/dist/chunk-RPD5K5NC.js +79 -0
  91. package/dist/chunk-RUOG5D2C.js +262 -0
  92. package/dist/chunk-T4ERT73Y.js +599 -0
  93. package/dist/chunk-T6D4Q4AQ.js +54 -0
  94. package/dist/chunk-TGPXLY2J.js +391 -0
  95. package/dist/chunk-TLGFBM3F.js +12116 -0
  96. package/dist/chunk-TO6WL3GM.js +88 -0
  97. package/dist/chunk-TT22N74J.js +517 -0
  98. package/dist/chunk-TVN5N6GY.js +21216 -0
  99. package/dist/chunk-U3VGR4VU.js +308 -0
  100. package/dist/chunk-UK3CMEAL.js +1250 -0
  101. package/dist/chunk-UOPVJQ4N.js +103 -0
  102. package/dist/chunk-UXVNL3D7.js +23 -0
  103. package/dist/chunk-UY752QSN.js +45 -0
  104. package/dist/chunk-V5PXFSZK.js +188 -0
  105. package/dist/chunk-V7R425XG.js +398 -0
  106. package/dist/chunk-VCSRSYLF.js +81 -0
  107. package/dist/chunk-VD4JQCQC.js +162 -0
  108. package/dist/chunk-VDBPVIKD.js +62 -0
  109. package/dist/chunk-VHQLPIRJ.js +114 -0
  110. package/dist/chunk-VN2AXLEX.js +5414 -0
  111. package/dist/chunk-VNMT7C64.js +478 -0
  112. package/dist/chunk-WONERJTP.js +309 -0
  113. package/dist/chunk-XECLWQZN.js +85 -0
  114. package/dist/chunk-XIMYZ3JA.js +27 -0
  115. package/dist/chunk-XK4CIILI.js +144 -0
  116. package/dist/chunk-Y4T27COV.js +562 -0
  117. package/dist/chunk-YGVYKNSN.js +1860 -0
  118. package/dist/chunk-YLF3PPT5.js +308 -0
  119. package/dist/chunk-YSNFMJKN.js +14 -0
  120. package/dist/chunk-Z3CCVDUB.js +76 -0
  121. package/dist/chunk-Z54ZSOBZ.js +61 -0
  122. package/dist/chunk-ZAWW3AF6.js +97 -0
  123. package/dist/chunk-ZMOL6RQC.js +167 -0
  124. package/dist/index.js +19039 -8956
  125. package/dist/mcp/analyze-cli.js +186 -228
  126. package/dist/mcp/cli.js +137 -98
  127. package/dist/mcp/server.js +22592 -1564
  128. package/dist/mcp/worker.js +97 -38
  129. package/dist/probes/installer.js +135 -0
  130. package/dist/workers/project-snapshot-persist-worker.js +22 -0
  131. package/dist/workers/review-graph-persist-worker.js +15 -0
  132. package/docs/adr/0001-stale-advisory-live-arm.md +29 -0
  133. package/docs/adr/0002-workspace-hash-rendezvous.md +30 -0
  134. package/docs/adr/0003-git-guard-latch-writer.md +203 -0
  135. package/docs/adr/0004-disposition-policy-seam.md +38 -0
  136. package/docs/adr/0005-tool-availability-enforcement-seam.md +29 -0
  137. package/docs/adr/0006-derived-state-benchmark-first.md +31 -0
  138. package/docs/adr/0007-end-to-end-witness-per-seam-slice.md +38 -0
  139. package/docs/adr/0008-turn-end-lane-interface.md +165 -0
  140. package/docs/adr/0009-reported-path-attribution.md +114 -0
  141. package/docs/adr/README.md +26 -0
  142. package/docs/agent-guide.md +13 -4
  143. package/docs/agent-tools.md +60 -1
  144. package/docs/ast-grep_rules_catalog.md +6 -4
  145. package/docs/configuration.md +75 -2
  146. package/docs/engineering-principles.md +202 -0
  147. package/docs/environment-variables.md +113 -6
  148. package/docs/features.md +10 -6
  149. package/docs/globalconfig.md +7 -1
  150. package/docs/io-bridge-v2-migration.md +94 -0
  151. package/docs/language-coverage.md +17 -0
  152. package/docs/lsp-capability-matrix.md +131 -32
  153. package/docs/lsp-idle-eviction.md +124 -0
  154. package/docs/mcp.md +21 -5
  155. package/docs/merge-queue-rollout.md +77 -0
  156. package/docs/pi-lens-fixer.md +161 -39
  157. package/docs/pi-lens-investigator.md +77 -20
  158. package/docs/pi-lens-merge-policy.md +694 -0
  159. package/docs/pi-lens-monitor.md +73 -7
  160. package/docs/pi-lens-retro.md +6 -4
  161. package/docs/pi-lens-reviewer.md +190 -34
  162. package/docs/pi-lens-subagent.md +247 -37
  163. package/docs/pi-lens-warden.md +18 -7
  164. package/docs/public-api-stability.md +56 -0
  165. package/docs/release-qa-baseline.md +86 -17
  166. package/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
  167. package/docs/servercapabilities.md +66 -52
  168. package/docs/settings.md +13 -3
  169. package/docs/subagent-compat.md +1 -1
  170. package/docs/usage.md +5 -1
  171. package/grammars/tree-sitter-bash.wasm +0 -0
  172. package/grammars/tree-sitter-bash.wasm.json +3 -3
  173. package/package.json +23 -9
  174. package/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  175. package/rules/ast-grep-rules/rule-tests/no-assert-tuple-test.yml +13 -0
  176. package/rules/ast-grep-rules/rule-tests/no-boolean-in-except-test.yml +26 -0
  177. package/rules/ast-grep-rules/rule-tests/no-http-headers-bracket-access-test.yml +10 -0
  178. package/rules/ast-grep-rules/rule-tests/unchecked-numeric-parse-python-test.yml +18 -0
  179. package/rules/ast-grep-rules/rule-tests/unchecked-throwing-call-python-test.yml +4 -3
  180. package/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  181. package/rules/ast-grep-rules/rules/go-no-fmt-println.yml +2 -2
  182. package/rules/ast-grep-rules/rules/no-assert-tuple.yml +23 -13
  183. package/rules/ast-grep-rules/rules/no-boolean-in-except.yml +7 -3
  184. package/rules/ast-grep-rules/rules/no-console-except-error-js.yml +2 -2
  185. package/rules/ast-grep-rules/rules/no-console-except-error.yml +2 -2
  186. package/rules/ast-grep-rules/rules/no-http-headers-bracket-access.yml +12 -7
  187. package/rules/ast-grep-rules/rules/unchecked-numeric-parse-python.yml +44 -0
  188. package/rules/ast-grep-rules/rules/unchecked-throwing-call-python.yml +5 -3
  189. package/rules/tree-sitter-queries/typescript/console-statement.yml +2 -2
  190. package/scripts/analyze-pi-lens-logs.mjs +1275 -62
  191. package/scripts/download-grammars.js +5 -0
  192. package/scripts/grammars.lock.json +6 -1
  193. package/scripts/install-selftest.mjs +38 -35
  194. package/scripts/lib/host-provided-deps.mjs +13 -4
  195. package/scripts/lib/web-tree-sitter-dir.mjs +141 -0
  196. package/dist/clients/actionable-warnings-logger.js +0 -35
  197. package/dist/clients/actionable-warnings.js +0 -1594
  198. package/dist/clients/advisory-provenance.js +0 -457
  199. package/dist/clients/agent-behavior-client.js +0 -147
  200. package/dist/clients/agent-nudge.js +0 -325
  201. package/dist/clients/analysed-root.js +0 -1
  202. package/dist/clients/ast-grep-client.js +0 -731
  203. package/dist/clients/ast-grep-rule-manager.js +0 -146
  204. package/dist/clients/ast-grep-tool-logger.js +0 -118
  205. package/dist/clients/ast-grep-types.js +0 -10
  206. package/dist/clients/ast-grep-yaml-synth.js +0 -154
  207. package/dist/clients/atomic-write-staging.js +0 -75
  208. package/dist/clients/atomic-write.js +0 -189
  209. package/dist/clients/availability-probe-flight.js +0 -12
  210. package/dist/clients/bash-file-access.js +0 -1056
  211. package/dist/clients/biome-client.js +0 -357
  212. package/dist/clients/blocker-freshness.js +0 -837
  213. package/dist/clients/blocker-past-eof.js +0 -129
  214. package/dist/clients/bootstrap.js +0 -569
  215. package/dist/clients/bounded-cache.js +0 -190
  216. package/dist/clients/bounded-pid-file-lock.js +0 -202
  217. package/dist/clients/bounded-telemetry.js +0 -295
  218. package/dist/clients/build-identity.js +0 -95
  219. package/dist/clients/bundled-resource-health.js +0 -113
  220. package/dist/clients/bus-events-logger.js +0 -105
  221. package/dist/clients/bus-publish.js +0 -171
  222. package/dist/clients/cache/rule-cache.js +0 -190
  223. package/dist/clients/cache-manager.js +0 -465
  224. package/dist/clients/cache-observability.js +0 -1313
  225. package/dist/clients/call-graph.js +0 -852
  226. package/dist/clients/cargo-manifest.js +0 -422
  227. package/dist/clients/cascade-budget.js +0 -196
  228. package/dist/clients/cascade-format.js +0 -315
  229. package/dist/clients/cascade-logger.js +0 -31
  230. package/dist/clients/cascade-types.js +0 -9
  231. package/dist/clients/child-unref.js +0 -115
  232. package/dist/clients/code-quality-warnings.js +0 -286
  233. package/dist/clients/codebase-model.js +0 -173
  234. package/dist/clients/collateral-test-role.js +0 -40
  235. package/dist/clients/complexity-client.js +0 -462
  236. package/dist/clients/config-core/deny.js +0 -221
  237. package/dist/clients/config-core/index.js +0 -50
  238. package/dist/clients/config-core/merge.js +0 -357
  239. package/dist/clients/config-core/normalize.js +0 -340
  240. package/dist/clients/config-core/process-spec.js +0 -248
  241. package/dist/clients/config-core/provenance.js +0 -164
  242. package/dist/clients/config-core/records.js +0 -218
  243. package/dist/clients/config-core/resolve.js +0 -125
  244. package/dist/clients/config-core/safe-object.js +0 -78
  245. package/dist/clients/config-core/schema.js +0 -165
  246. package/dist/clients/config-diagnostic-codes.js +0 -283
  247. package/dist/clients/config-locations.js +0 -160
  248. package/dist/clients/config-resolve.js +0 -792
  249. package/dist/clients/config-schema.js +0 -251
  250. package/dist/clients/config-warn.js +0 -407
  251. package/dist/clients/console-guard-install.js +0 -26
  252. package/dist/clients/cooperative-budget.js +0 -42
  253. package/dist/clients/dead-code-client.js +0 -510
  254. package/dist/clients/dead-code-logger.js +0 -30
  255. package/dist/clients/deadline-utils.js +0 -280
  256. package/dist/clients/debug-handles.js +0 -211
  257. package/dist/clients/debug-heap.js +0 -174
  258. package/dist/clients/deferred-lsp-work.js +0 -106
  259. package/dist/clients/degradation-ledger.js +0 -396
  260. package/dist/clients/demoted-finding-render.js +0 -169
  261. package/dist/clients/dependency-checker.js +0 -862
  262. package/dist/clients/deps/ast-grep-napi.js +0 -22
  263. package/dist/clients/deps/js-yaml.js +0 -9
  264. package/dist/clients/deps/minimatch.js +0 -4
  265. package/dist/clients/deps/pi-tui.js +0 -14
  266. package/dist/clients/deps/typebox.js +0 -14
  267. package/dist/clients/deps/vscode-jsonrpc.js +0 -1
  268. package/dist/clients/deps/web-tree-sitter.js +0 -24
  269. package/dist/clients/diagnostic-dispositions.js +0 -594
  270. package/dist/clients/diagnostic-line-freshness.js +0 -305
  271. package/dist/clients/diagnostic-logger.js +0 -73
  272. package/dist/clients/diagnostic-tracker.js +0 -105
  273. package/dist/clients/diagnostics-publish.js +0 -230
  274. package/dist/clients/dispatch/ast-grep-catalog.js +0 -65
  275. package/dist/clients/dispatch/auxiliary-lsp.js +0 -343
  276. package/dist/clients/dispatch/collect-later-tier.js +0 -35
  277. package/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
  278. package/dist/clients/dispatch/dispatcher.js +0 -1269
  279. package/dist/clients/dispatch/fact-provider-types.js +0 -1
  280. package/dist/clients/dispatch/fact-rule-runner.js +0 -17
  281. package/dist/clients/dispatch/fact-runner.js +0 -30
  282. package/dist/clients/dispatch/fact-scheduler.js +0 -68
  283. package/dist/clients/dispatch/fact-store.js +0 -377
  284. package/dist/clients/dispatch/facts/comment-facts.js +0 -22
  285. package/dist/clients/dispatch/facts/file-content.js +0 -19
  286. package/dist/clients/dispatch/facts/function-facts.js +0 -348
  287. package/dist/clients/dispatch/facts/import-facts.js +0 -204
  288. package/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
  289. package/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
  290. package/dist/clients/dispatch/finding-policy.js +0 -222
  291. package/dist/clients/dispatch/indent-detect.js +0 -411
  292. package/dist/clients/dispatch/inline-suppressions.js +0 -70
  293. package/dist/clients/dispatch/integration.js +0 -2377
  294. package/dist/clients/dispatch/lazy.js +0 -11
  295. package/dist/clients/dispatch/pending-runner-findings.js +0 -87
  296. package/dist/clients/dispatch/plan.js +0 -278
  297. package/dist/clients/dispatch/priorities.js +0 -20
  298. package/dist/clients/dispatch/rule-id-normalize.js +0 -50
  299. package/dist/clients/dispatch/rule-ignores.js +0 -62
  300. package/dist/clients/dispatch/rule-policy.js +0 -135
  301. package/dist/clients/dispatch/rules/async-noise.js +0 -40
  302. package/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  303. package/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
  304. package/dist/clients/dispatch/rules/error-obscuring.js +0 -32
  305. package/dist/clients/dispatch/rules/error-swallowing.js +0 -31
  306. package/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
  307. package/dist/clients/dispatch/rules/high-complexity.js +0 -72
  308. package/dist/clients/dispatch/rules/high-fan-out.js +0 -74
  309. package/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
  310. package/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
  311. package/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
  312. package/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
  313. package/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  314. package/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
  315. package/dist/clients/dispatch/runner-context.js +0 -52
  316. package/dist/clients/dispatch/runners/actionlint.js +0 -113
  317. package/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
  318. package/dist/clients/dispatch/runners/biome-check.js +0 -283
  319. package/dist/clients/dispatch/runners/cpp-check.js +0 -236
  320. package/dist/clients/dispatch/runners/credo.js +0 -80
  321. package/dist/clients/dispatch/runners/cue-vet.js +0 -398
  322. package/dist/clients/dispatch/runners/dart-analyze.js +0 -202
  323. package/dist/clients/dispatch/runners/detekt.js +0 -169
  324. package/dist/clients/dispatch/runners/dotnet-build.js +0 -159
  325. package/dist/clients/dispatch/runners/elixir-check.js +0 -210
  326. package/dist/clients/dispatch/runners/eslint.js +0 -154
  327. package/dist/clients/dispatch/runners/fact-rules.js +0 -29
  328. package/dist/clients/dispatch/runners/fish-indent.js +0 -69
  329. package/dist/clients/dispatch/runners/gleam-check.js +0 -87
  330. package/dist/clients/dispatch/runners/go-vet.js +0 -90
  331. package/dist/clients/dispatch/runners/golangci-lint.js +0 -120
  332. package/dist/clients/dispatch/runners/hadolint.js +0 -79
  333. package/dist/clients/dispatch/runners/helm-lint.js +0 -171
  334. package/dist/clients/dispatch/runners/helm-render.js +0 -940
  335. package/dist/clients/dispatch/runners/htmlhint.js +0 -108
  336. package/dist/clients/dispatch/runners/index.js +0 -108
  337. package/dist/clients/dispatch/runners/javac.js +0 -89
  338. package/dist/clients/dispatch/runners/ktlint.js +0 -136
  339. package/dist/clients/dispatch/runners/lsp.js +0 -378
  340. package/dist/clients/dispatch/runners/markdownlint.js +0 -160
  341. package/dist/clients/dispatch/runners/mypy.js +0 -101
  342. package/dist/clients/dispatch/runners/oxlint.js +0 -398
  343. package/dist/clients/dispatch/runners/php-lint.js +0 -62
  344. package/dist/clients/dispatch/runners/phpstan.js +0 -120
  345. package/dist/clients/dispatch/runners/prisma-validate.js +0 -62
  346. package/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
  347. package/dist/clients/dispatch/runners/pyright.js +0 -169
  348. package/dist/clients/dispatch/runners/rubocop.js +0 -90
  349. package/dist/clients/dispatch/runners/ruff.js +0 -89
  350. package/dist/clients/dispatch/runners/rust-clippy.js +0 -251
  351. package/dist/clients/dispatch/runners/shellcheck.js +0 -169
  352. package/dist/clients/dispatch/runners/shfmt.js +0 -102
  353. package/dist/clients/dispatch/runners/spellcheck.js +0 -121
  354. package/dist/clients/dispatch/runners/spotbugs.js +0 -259
  355. package/dist/clients/dispatch/runners/sqlfluff.js +0 -174
  356. package/dist/clients/dispatch/runners/stylelint.js +0 -158
  357. package/dist/clients/dispatch/runners/swiftlint.js +0 -154
  358. package/dist/clients/dispatch/runners/taplo.js +0 -168
  359. package/dist/clients/dispatch/runners/terragrunt.js +0 -168
  360. package/dist/clients/dispatch/runners/tflint.js +0 -110
  361. package/dist/clients/dispatch/runners/tree-sitter.js +0 -620
  362. package/dist/clients/dispatch/runners/trivy-config.js +0 -247
  363. package/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
  364. package/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
  365. package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -85
  366. package/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
  367. package/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
  368. package/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
  369. package/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
  370. package/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
  371. package/dist/clients/dispatch/runners/utils.js +0 -15
  372. package/dist/clients/dispatch/runners/vale.js +0 -116
  373. package/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
  374. package/dist/clients/dispatch/runners/yamllint.js +0 -85
  375. package/dist/clients/dispatch/runners/zig-check.js +0 -91
  376. package/dist/clients/dispatch/suppress-writer.js +0 -69
  377. package/dist/clients/dispatch/tool-profile.js +0 -30
  378. package/dist/clients/dispatch/types.js +0 -21
  379. package/dist/clients/dispatch/utils/format-utils.js +0 -45
  380. package/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
  381. package/dist/clients/disposition-logger.js +0 -32
  382. package/dist/clients/disposition-publish.js +0 -124
  383. package/dist/clients/durable-store.js +0 -97
  384. package/dist/clients/effective-config.js +0 -413
  385. package/dist/clients/env-utils.js +0 -83
  386. package/dist/clients/error-class.js +0 -23
  387. package/dist/clients/eval-timestamp.js +0 -17
  388. package/dist/clients/event-loop-hold.js +0 -274
  389. package/dist/clients/event-loop-monitor.js +0 -250
  390. package/dist/clients/extension-log.js +0 -504
  391. package/dist/clients/extension-mode.js +0 -73
  392. package/dist/clients/feature-hints.js +0 -103
  393. package/dist/clients/file-kinds.js +0 -412
  394. package/dist/clients/file-role.js +0 -134
  395. package/dist/clients/file-time.js +0 -160
  396. package/dist/clients/file-utils.js +0 -1032
  397. package/dist/clients/finding-delivery-gate.js +0 -463
  398. package/dist/clients/finding-identity.js +0 -88
  399. package/dist/clients/fix-worklog.js +0 -103
  400. package/dist/clients/format-events-publish.js +0 -343
  401. package/dist/clients/format-service.js +0 -222
  402. package/dist/clients/formatters-lazy.js +0 -9
  403. package/dist/clients/formatters.js +0 -1994
  404. package/dist/clients/freshness-cadence.js +0 -17
  405. package/dist/clients/freshness.js +0 -38
  406. package/dist/clients/generated-artifacts.js +0 -394
  407. package/dist/clients/generation-guard.js +0 -215
  408. package/dist/clients/git-guard.js +0 -923
  409. package/dist/clients/git-tracked-ignore.js +0 -243
  410. package/dist/clients/gitleaks-client.js +0 -509
  411. package/dist/clients/go-client.js +0 -104
  412. package/dist/clients/govulncheck-client.js +0 -605
  413. package/dist/clients/gradle-ktfmt-style.js +0 -252
  414. package/dist/clients/grammar-source.js +0 -465
  415. package/dist/clients/gzip-stage-write.js +0 -135
  416. package/dist/clients/hashline-anchor.js +0 -424
  417. package/dist/clients/hook-budgets.js +0 -76
  418. package/dist/clients/host-edit-normalize.js +0 -140
  419. package/dist/clients/host-ports.js +0 -39
  420. package/dist/clients/indent-retarget.js +0 -154
  421. package/dist/clients/install-diagnostics.js +0 -143
  422. package/dist/clients/installer/index.js +0 -5167
  423. package/dist/clients/installer/managed-tool-refresh-session.js +0 -58
  424. package/dist/clients/installer/managed-tool-refresh.js +0 -783
  425. package/dist/clients/instance-reaper-state.js +0 -7
  426. package/dist/clients/instance-reaper.js +0 -1137
  427. package/dist/clients/instance-registry-lock.js +0 -145
  428. package/dist/clients/instance-registry.js +0 -773
  429. package/dist/clients/jscpd-client.js +0 -370
  430. package/dist/clients/json-cache-read.js +0 -65
  431. package/dist/clients/knip-client.js +0 -788
  432. package/dist/clients/language-policy.js +0 -252
  433. package/dist/clients/language-profile.js +0 -361
  434. package/dist/clients/language-registry.js +0 -603
  435. package/dist/clients/latency-logger.js +0 -719
  436. package/dist/clients/lazy-import.js +0 -21
  437. package/dist/clients/ledger-bounds.js +0 -54
  438. package/dist/clients/lens-config.js +0 -346
  439. package/dist/clients/lens-engine.js +0 -358
  440. package/dist/clients/lens-events.js +0 -125
  441. package/dist/clients/lens-flag-registry.js +0 -467
  442. package/dist/clients/lens-map.js +0 -1156
  443. package/dist/clients/live-bus-emitter.js +0 -74
  444. package/dist/clients/log-cleanup.js +0 -222
  445. package/dist/clients/lsp/aggregation.js +0 -178
  446. package/dist/clients/lsp/cascade-tier.js +0 -421
  447. package/dist/clients/lsp/client.js +0 -4465
  448. package/dist/clients/lsp/config.js +0 -689
  449. package/dist/clients/lsp/diagnostic-binding.js +0 -225
  450. package/dist/clients/lsp/document-drift.js +0 -467
  451. package/dist/clients/lsp/edits.js +0 -1219
  452. package/dist/clients/lsp/index.js +0 -8305
  453. package/dist/clients/lsp/inferred-project.js +0 -216
  454. package/dist/clients/lsp/jvm-runtime.js +0 -298
  455. package/dist/clients/lsp/language.js +0 -63
  456. package/dist/clients/lsp/launch.js +0 -725
  457. package/dist/clients/lsp/lombok.js +0 -158
  458. package/dist/clients/lsp/path-utils.js +0 -5
  459. package/dist/clients/lsp/pending-aux-coverage.js +0 -251
  460. package/dist/clients/lsp/position-encoding.js +0 -61
  461. package/dist/clients/lsp/ruby-drive-dirs.js +0 -83
  462. package/dist/clients/lsp/server.js +0 -3209
  463. package/dist/clients/lsp/session-roots.js +0 -192
  464. package/dist/clients/lsp/spawn-history.js +0 -17
  465. package/dist/clients/lsp/sync-kind.js +0 -42
  466. package/dist/clients/lsp/tsserver-sync.js +0 -332
  467. package/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  468. package/dist/clients/lsp/wait-policy/classification.js +0 -85
  469. package/dist/clients/lsp/wait-policy/index.js +0 -10
  470. package/dist/clients/lsp/wait-policy/strategies.js +0 -303
  471. package/dist/clients/lsp/watch-queue.js +0 -61
  472. package/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
  473. package/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
  474. package/dist/clients/lsp/workspace-sweep-hold.js +0 -184
  475. package/dist/clients/lsp-budget.js +0 -186
  476. package/dist/clients/lsp-document-symbols.js +0 -110
  477. package/dist/clients/lsp-lazy.js +0 -9
  478. package/dist/clients/lsp-mutation.js +0 -396
  479. package/dist/clients/lsp-status.js +0 -59
  480. package/dist/clients/map-with-concurrency.js +0 -40
  481. package/dist/clients/mcp/analyze.js +0 -420
  482. package/dist/clients/mcp/host-shim.js +0 -31
  483. package/dist/clients/mcp/ipc.js +0 -335
  484. package/dist/clients/mcp/review.js +0 -151
  485. package/dist/clients/mcp/session.js +0 -412
  486. package/dist/clients/memory-sampler.js +0 -208
  487. package/dist/clients/message-end-attribution.js +0 -30
  488. package/dist/clients/metrics-client.js +0 -107
  489. package/dist/clients/metrics-history.js +0 -327
  490. package/dist/clients/middle-man-analysis.js +0 -263
  491. package/dist/clients/model-provider.js +0 -53
  492. package/dist/clients/module-report-lsp.js +0 -189
  493. package/dist/clients/module-report.js +0 -2150
  494. package/dist/clients/mutating-tool.js +0 -651
  495. package/dist/clients/mutation-attribution.js +0 -368
  496. package/dist/clients/mutation-bridge.js +0 -240
  497. package/dist/clients/ndjson-logger.js +0 -734
  498. package/dist/clients/observed-mutation-sources.js +0 -101
  499. package/dist/clients/observed-mutation.js +0 -1253
  500. package/dist/clients/oldtext-autopatch.js +0 -128
  501. package/dist/clients/opaque-mutation-scan.js +0 -496
  502. package/dist/clients/opengrep-client.js +0 -328
  503. package/dist/clients/opengrep-config.js +0 -76
  504. package/dist/clients/package-manager.js +0 -607
  505. package/dist/clients/package-root.js +0 -38
  506. package/dist/clients/partial-edit-apply.js +0 -439
  507. package/dist/clients/path-attribution-telemetry.js +0 -43
  508. package/dist/clients/path-keyed-map.js +0 -108
  509. package/dist/clients/path-utils.js +0 -1244
  510. package/dist/clients/performance-report.js +0 -331
  511. package/dist/clients/persist-debounce.js +0 -70
  512. package/dist/clients/persistent-reverify.js +0 -271
  513. package/dist/clients/php-cs-fixer-config.js +0 -119
  514. package/dist/clients/pipeline.js +0 -1425
  515. package/dist/clients/post-autofix-notice.js +0 -37
  516. package/dist/clients/print-mode.js +0 -21
  517. package/dist/clients/probe-home-state.js +0 -228
  518. package/dist/clients/process-bridge.js +0 -66
  519. package/dist/clients/process-singletons.js +0 -210
  520. package/dist/clients/process-snapshot.js +0 -68
  521. package/dist/clients/project-changes.js +0 -181
  522. package/dist/clients/project-conventions.js +0 -171
  523. package/dist/clients/project-diagnostics/cache.js +0 -137
  524. package/dist/clients/project-diagnostics/extractors.js +0 -109
  525. package/dist/clients/project-diagnostics/fresh-fetch.js +0 -650
  526. package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
  527. package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
  528. package/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
  529. package/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
  530. package/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
  531. package/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
  532. package/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
  533. package/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
  534. package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
  535. package/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
  536. package/dist/clients/project-diagnostics/scanner.js +0 -520
  537. package/dist/clients/project-diagnostics/types.js +0 -1
  538. package/dist/clients/project-lens-config.js +0 -799
  539. package/dist/clients/project-report.js +0 -701
  540. package/dist/clients/project-scale.js +0 -237
  541. package/dist/clients/project-scan-policy.js +0 -11
  542. package/dist/clients/project-snapshot-fingerprint.js +0 -48
  543. package/dist/clients/project-snapshot-persist-worker.js +0 -20
  544. package/dist/clients/project-snapshot.js +0 -1653
  545. package/dist/clients/project-trust.js +0 -181
  546. package/dist/clients/python-environment.js +0 -217
  547. package/dist/clients/python-provenance.js +0 -639
  548. package/dist/clients/quiet-window-config.js +0 -47
  549. package/dist/clients/quiet-window.js +0 -236
  550. package/dist/clients/read-bridge.js +0 -139
  551. package/dist/clients/read-expansion.js +0 -266
  552. package/dist/clients/read-guard-logger.js +0 -251
  553. package/dist/clients/read-guard-tool-lines.js +0 -1306
  554. package/dist/clients/read-guard.js +0 -1561
  555. package/dist/clients/recent-touches.js +0 -240
  556. package/dist/clients/redact/secrets.js +0 -449
  557. package/dist/clients/resource-sampler.js +0 -628
  558. package/dist/clients/reverse-deps.js +0 -270
  559. package/dist/clients/review-graph/builder.js +0 -5118
  560. package/dist/clients/review-graph/format.js +0 -33
  561. package/dist/clients/review-graph/git-identity.js +0 -157
  562. package/dist/clients/review-graph/import-resolvers.js +0 -481
  563. package/dist/clients/review-graph/persist-worker.js +0 -10
  564. package/dist/clients/review-graph/query.js +0 -244
  565. package/dist/clients/review-graph/revision-drift.js +0 -21
  566. package/dist/clients/review-graph/service.js +0 -96
  567. package/dist/clients/review-graph/shared-extraction-ir.js +0 -82
  568. package/dist/clients/review-graph/symbol-id.js +0 -103
  569. package/dist/clients/review-graph/tsconfig-paths.js +0 -299
  570. package/dist/clients/review-graph/types.js +0 -1
  571. package/dist/clients/review-graph/workspace-modules.js +0 -449
  572. package/dist/clients/review-graph-logger.js +0 -81
  573. package/dist/clients/ruff-client.js +0 -152
  574. package/dist/clients/rules-scanner.js +0 -131
  575. package/dist/clients/run-duration.js +0 -55
  576. package/dist/clients/runtime-agent-end.js +0 -746
  577. package/dist/clients/runtime-config.js +0 -77
  578. package/dist/clients/runtime-context.js +0 -211
  579. package/dist/clients/runtime-coordinator.js +0 -1290
  580. package/dist/clients/runtime-session.js +0 -2485
  581. package/dist/clients/runtime-tool-call.js +0 -1284
  582. package/dist/clients/runtime-tool-result.js +0 -2034
  583. package/dist/clients/runtime-turn.js +0 -3600
  584. package/dist/clients/rust-client.js +0 -97
  585. package/dist/clients/safe-spawn.js +0 -2166
  586. package/dist/clients/sanitize.js +0 -286
  587. package/dist/clients/scan-utils.js +0 -25
  588. package/dist/clients/scratch-tree-policy.js +0 -165
  589. package/dist/clients/search-read-registration.js +0 -94
  590. package/dist/clients/secret-findings.js +0 -114
  591. package/dist/clients/security-scan-client.js +0 -352
  592. package/dist/clients/session-event-guard.js +0 -297
  593. package/dist/clients/session-lifecycle.js +0 -484
  594. package/dist/clients/session-start-observability.js +0 -94
  595. package/dist/clients/session-state-store.js +0 -101
  596. package/dist/clients/session-summary.js +0 -15
  597. package/dist/clients/sessionstart-logger.js +0 -27
  598. package/dist/clients/sg-runner.js +0 -876
  599. package/dist/clients/sgconfig.js +0 -347
  600. package/dist/clients/shared-checkout-guard.js +0 -338
  601. package/dist/clients/single-flight.js +0 -158
  602. package/dist/clients/situational-tool-telemetry.js +0 -108
  603. package/dist/clients/skills-resolver.js +0 -141
  604. package/dist/clients/slow-fs.js +0 -138
  605. package/dist/clients/smells-rollup.js +0 -231
  606. package/dist/clients/source-filter.js +0 -596
  607. package/dist/clients/source-walker.js +0 -211
  608. package/dist/clients/spawn-output-cap.js +0 -37
  609. package/dist/clients/spawn-timeout-cooldown.js +0 -110
  610. package/dist/clients/stale-marker.js +0 -17
  611. package/dist/clients/startup-scan.js +0 -400
  612. package/dist/clients/startup-timing.js +0 -130
  613. package/dist/clients/string-utils.js +0 -33
  614. package/dist/clients/subagent-mode.js +0 -111
  615. package/dist/clients/symbol-containment.js +0 -24
  616. package/dist/clients/symbol-types.js +0 -5
  617. package/dist/clients/test-runner-client.js +0 -2507
  618. package/dist/clients/test-runner-delivery.js +0 -287
  619. package/dist/clients/todo-scanner.js +0 -229
  620. package/dist/clients/tool-agreement.js +0 -423
  621. package/dist/clients/tool-config.js +0 -249
  622. package/dist/clients/tool-cwd.js +0 -270
  623. package/dist/clients/tool-definition.js +0 -47
  624. package/dist/clients/tool-event.js +0 -105
  625. package/dist/clients/tool-policy.js +0 -2755
  626. package/dist/clients/tool-probe.js +0 -53
  627. package/dist/clients/tool-render.js +0 -156
  628. package/dist/clients/tool-set-policy.js +0 -118
  629. package/dist/clients/tree-sitter-cache.js +0 -364
  630. package/dist/clients/tree-sitter-client.js +0 -4134
  631. package/dist/clients/tree-sitter-logger.js +0 -100
  632. package/dist/clients/tree-sitter-navigator.js +0 -269
  633. package/dist/clients/tree-sitter-query-loader.js +0 -569
  634. package/dist/clients/tree-sitter-shared.js +0 -158
  635. package/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
  636. package/dist/clients/trivy-client.js +0 -467
  637. package/dist/clients/tui-fit.js +0 -50
  638. package/dist/clients/turn-context.js +0 -52
  639. package/dist/clients/turn-summary-render.js +0 -72
  640. package/dist/clients/turn-summary.js +0 -132
  641. package/dist/clients/typos-config.js +0 -29
  642. package/dist/clients/user-notify.js +0 -51
  643. package/dist/clients/vanished-instance-marker.js +0 -57
  644. package/dist/clients/warm-attach.js +0 -246
  645. package/dist/clients/widget-state.js +0 -1677
  646. package/dist/clients/word-index-logger.js +0 -49
  647. package/dist/clients/word-index-store.js +0 -459
  648. package/dist/clients/word-index.js +0 -2080
  649. package/dist/clients/workspace-topology.js +0 -389
  650. package/dist/clients/write-ordering-guard.js +0 -65
  651. package/dist/clients/zizmor-config.js +0 -327
  652. package/dist/i18n.js +0 -69
  653. package/dist/mcp/build-staleness.js +0 -124
  654. package/dist/scripts/lib/process-scan.mjs +0 -583
  655. package/dist/scripts/lib/skills-predicate.mjs +0 -129
  656. package/dist/tools/activate-tools.js +0 -87
  657. package/dist/tools/ast-grep-outline.js +0 -137
  658. package/dist/tools/ast-grep-replace.js +0 -244
  659. package/dist/tools/ast-grep-search.js +0 -762
  660. package/dist/tools/effective-config.js +0 -90
  661. package/dist/tools/lens-diagnostic-mark.js +0 -375
  662. package/dist/tools/lens-diagnostics.js +0 -2544
  663. package/dist/tools/lsp-diagnostics.js +0 -1634
  664. package/dist/tools/lsp-navigation.js +0 -1367
  665. package/dist/tools/lsp-structured-output.js +0 -294
  666. package/dist/tools/module-report.js +0 -382
  667. package/dist/tools/project-report.js +0 -86
  668. package/dist/tools/render-compact.js +0 -374
  669. package/dist/tools/scan-progress.js +0 -53
  670. package/dist/tools/shared.js +0 -29
  671. package/dist/tools/symbol-search.js +0 -155
@@ -1,378 +0,0 @@
1
- /**
2
- * Unified LSP Runner for pi-lens
3
- *
4
- * Handles type checking for ALL LSP-supported languages:
5
- * - TypeScript/JavaScript (typescript-language-server)
6
- * - Python (pyright/pylsp)
7
- * - Go (gopls)
8
- * - Rust (rust-analyzer)
9
- * - Ruby, PHP, C#, Java, Kotlin, Swift, Dart, etc.
10
- *
11
- * Replaces language-specific runners (pyright, etc.) with a single
12
- * unified runner that delegates to the LSP service.
13
- */
14
- import { logExtension } from "../../extension-log.js";
15
- import { getLspCapableKinds } from "../../language-policy.js";
16
- import { touchCoverageGap } from "../../lsp/diagnostic-binding.js";
17
- import { getLSPService } from "../../lsp/index.js";
18
- import { LSP_SERVERS } from "../../lsp/server.js";
19
- import { RUNTIME_CONFIG } from "../../runtime-config.js";
20
- import { PRIORITY } from "../priorities.js";
21
- import { resolveRunnerPath } from "../runner-context.js";
22
- import { convertLspDiagnostics } from "../utils/lsp-diagnostics.js";
23
- import { demoteInferredProjectDiagnostics } from "../../lsp/inferred-project.js";
24
- import { enabledAuxiliaryLspServerIds, retagAuxiliaryDiagnostics, } from "../auxiliary-lsp.js";
25
- import { readFileContent } from "./utils.js";
26
- import { tryWarmAttachedCodeActions, tryWarmAttachedDiagnostics, } from "../../warm-attach.js";
27
- import { contentHash, WARM_CODE_ACTION_LOOKUP_LIMIT } from "../../mcp/ipc.js";
28
- const LSP_MAX_FILE_BYTES = RUNTIME_CONFIG.pipeline.lspMaxFileBytes;
29
- const LSP_MAX_FILE_LINES = RUNTIME_CONFIG.pipeline.lspMaxFileLines;
30
- const LSP_SPAWN_BUDGET_MS = RUNTIME_CONFIG.pipeline.lspSpawnBudgetMs;
31
- // Diagnostics-wait cap for the dispatch lsp-runner. Bounded so a slow LSP
32
- // (typescript-language-server on large monorepos has been observed >7 s)
33
- // can't dominate the per-edit pipeline budget. Diagnostics that arrive
34
- // after the cap still land in the client's cache and surface on the
35
- // next edit. Overridable via PI_LENS_LSP_DIAGNOSTICS_MAX_WAIT_MS.
36
- export const LSP_DIAGNOSTICS_WAIT_MS = 2500;
37
- const MAX_CODE_ACTION_TITLES = 3;
38
- /**
39
- * Fixed margin above the worst-case cold-spawn-plus-diagnostics wait, so
40
- * scheduling jitter alone can't reopen the F2 race below.
41
- */
42
- const LSP_COLD_SPAWN_MARGIN_MS = 5_000;
43
- /**
44
- * This runner's own dispatch wall-clock budget. `runRunner` in
45
- * `dispatcher.ts` races `runner.timeoutMs ?? RUNNER_TIMEOUT_MS` (30s)
46
- * against `runner.run()` for the WHOLE call — reading the file, waiting for
47
- * a client (bounded by `LSP_SPAWN_BUDGET_MS`, raised per-server via
48
- * `LSPServerInfo.clientWaitTimeoutMs`), then waiting for diagnostics
49
- * (`LSP_DIAGNOSTICS_WAIT_MS`).
50
- *
51
- * Left undeclared, this runner inherited the shared 30s default. A server
52
- * whose `clientWaitTimeoutMs` exceeds that — Prisma's 40s, Vue's 30s
53
- * (#2169, #2176) — could never actually use its own raised wait: the outer
54
- * race always fired first, at 30s, so raising a server's floor without also
55
- * raising this ceiling was a no-op on the real dispatch path (fix-round F2,
56
- * #2233). Derive the ceiling from the registry instead of a second
57
- * hand-picked literal, so the next slow server's `clientWaitTimeoutMs` keeps
58
- * this budget correct automatically: the highest declared
59
- * `clientWaitTimeoutMs` (or the shared 5s default, whichever is larger),
60
- * plus the diagnostics wait that still runs after a cold spawn succeeds,
61
- * plus a fixed margin.
62
- *
63
- * This raises the failure-detection latency for every OTHER language's
64
- * hung-server case too (30s -> the value below), not just the five servers
65
- * that need the headroom — the tradeoff is stated in PR #2233's body. It
66
- * remains well inside the spread other dispatch runners already use
67
- * (pyright 75s, golangci-lint/dotnet-build/rust-clippy 90s).
68
- */
69
- export const LSP_RUNNER_TIMEOUT_MS = Math.max(LSP_SPAWN_BUDGET_MS, ...LSP_SERVERS.map((server) => server.clientWaitTimeoutMs ?? 0)) +
70
- LSP_DIAGNOSTICS_WAIT_MS +
71
- LSP_COLD_SPAWN_MARGIN_MS;
72
- function normalizeActionTitle(title) {
73
- return title.replace(/\s+/g, " ").trim();
74
- }
75
- function buildCodeActionSuggestion(actions) {
76
- if (!actions.length)
77
- return undefined;
78
- const quickFixes = actions.filter((action) => action.kind?.startsWith("quickfix"));
79
- if (!quickFixes.length)
80
- return undefined;
81
- const titles = Array.from(new Set(quickFixes
82
- .map((action) => normalizeActionTitle(action.title))
83
- .filter((title) => title.length > 0))).slice(0, MAX_CODE_ACTION_TITLES);
84
- if (!titles.length)
85
- return undefined;
86
- return `LSP quick fixes: ${titles.join("; ")}`;
87
- }
88
- const lspRunner = {
89
- id: "lsp",
90
- // Derived from LANGUAGE_POLICY, never hand-maintained: the copy this
91
- // replaced had drifted (fish was lspCapable but absent, so getForKind
92
- // answered that no LSP runs on fish). Registering a language as lspCapable
93
- // is now the only step this seam needs (#1545).
94
- appliesTo: getLspCapableKinds(),
95
- priority: PRIORITY.LSP_PRIMARY,
96
- timeoutMs: LSP_RUNNER_TIMEOUT_MS,
97
- async run(ctx) {
98
- const diagnosticPath = resolveRunnerPath(ctx.cwd, ctx.filePath);
99
- // Only run if LSP is not disabled via --no-lsp
100
- if (ctx.pi.getFlag("no-lsp")) {
101
- return { status: "skipped", diagnostics: [], semantic: "none" };
102
- }
103
- const lspService = getLSPService();
104
- // Fast capability check only — actual client creation happens when we
105
- // open the file below.
106
- if (!lspService.supportsLSP(ctx.filePath)) {
107
- return { status: "skipped", diagnostics: [], semantic: "none" };
108
- }
109
- // Always sync current file content before reading diagnostics so dispatch
110
- // does not operate on stale LSP snapshots.
111
- let lspDiags = [];
112
- let serverFailed = false;
113
- // touchFile resolves to `undefined` when no LSP client was ready (a cold
114
- // spawn that didn't complete in the budget, or LSP unavailable for this
115
- // file) — distinct from `[]`, which means the server replied with zero.
116
- let lspClientReady = true;
117
- // True when touchFile ran but couldn't confirm its result within
118
- // budget (notify write and/or diagnostics wait timed out on at least
119
- // one spawned server) — an empty `lspDiags` in that case is NOT a
120
- // confirmed clean result and must not be reported as one (#570).
121
- let diagnosticsInconclusive = false;
122
- // #1470/#1493: server ids the touch carries no evidence for — an auxiliary
123
- // whose push wait our aux grace timer cut off (#1470), or one that stayed
124
- // silent with no stored publication for this content (#1493). The touch is
125
- // NOT inconclusive (the primary answered, and its findings below are real),
126
- // so this is tracked separately: the only claim it invalidates is "0
127
- // diagnostics means clean".
128
- let unconfirmedServerIds = [];
129
- let deferredServerIds = [];
130
- let usedWarmAttach = false;
131
- let failureReason = "";
132
- const content = readFileContent(ctx.filePath);
133
- if (!content) {
134
- return { status: "skipped", diagnostics: [], semantic: "none" };
135
- }
136
- const sizeBytes = Buffer.byteLength(content, "utf-8");
137
- const lineCount = content.split("\n").length;
138
- if (sizeBytes > LSP_MAX_FILE_BYTES || lineCount > LSP_MAX_FILE_LINES) {
139
- return { status: "skipped", diagnostics: [], semantic: "none" };
140
- }
141
- // Cross-cutting auxiliary scanners (opengrep, …) attach alongside the
142
- // primary language server when enabled — collected on the with-auxiliary
143
- // path so their warm diagnostics merge into this same result.
144
- const auxiliaryServerIds = enabledAuxiliaryLspServerIds((f) => ctx.pi.getFlag(f));
145
- try {
146
- const attached = await tryWarmAttachedDiagnostics(ctx.filePath, content, Math.max(LSP_SPAWN_BUDGET_MS, LSP_DIAGNOSTICS_WAIT_MS));
147
- usedWarmAttach = attached?.available === true;
148
- // #1179 (shape-5 structural fix): both branches normalize to the
149
- // `touchFile` wrapper shape. The warm-attach IPC branch resolves a plain
150
- // diagnostics array — `available` no longer implies a fully confirmed
151
- // answer: a `partial` confirmation (an auxiliary that never
152
- // reported — cut off by the grace timer, or silent) is served as
153
- // `available: true` too (the IPC gate at
154
- // `clients/mcp/ipc.ts:248` rejects only `inconclusive`). Carry the
155
- // incumbent's `unconfirmedServerIds` onto the wrapper so
156
- // `touchCoverageGap` below sees it — dropping it here is the same
157
- // false-clean defect already fixed at `clients/lsp/index.ts` (the
158
- // workspace sweep wrapper) and `tools/lsp-diagnostics.ts` (the tool
159
- // consumer); wrap it as `{ diags }`; the incumbent branch already
160
- // returns the wrapper.
161
- const touched = attached?.available
162
- ? {
163
- diags: attached.response.diagnostics,
164
- ...(attached.response.unconfirmedServerIds !== undefined && {
165
- unconfirmedServerIds: attached.response.unconfirmedServerIds,
166
- }),
167
- }
168
- : await lspService.touchFile(ctx.filePath, content, {
169
- diagnostics: "document",
170
- collectDiagnostics: true,
171
- clientScope: auxiliaryServerIds.length > 0 ? "with-auxiliary" : "primary",
172
- auxiliaryServerIds,
173
- maxClientWaitMs: LSP_SPAWN_BUDGET_MS,
174
- maxDiagnosticsWaitMs: LSP_DIAGNOSTICS_WAIT_MS,
175
- source: "dispatch-lsp-runner",
176
- });
177
- if (touched === undefined) {
178
- lspClientReady = false;
179
- }
180
- else {
181
- lspDiags = touched.diags;
182
- diagnosticsInconclusive = touched.inconclusive === true;
183
- unconfirmedServerIds = touchCoverageGap(touched);
184
- deferredServerIds = touched.deferredServerIds ?? [];
185
- }
186
- }
187
- catch (err) {
188
- serverFailed = true;
189
- failureReason = err instanceof Error ? err.message : String(err);
190
- if (failureReason.includes("spawn") ||
191
- failureReason.includes("exited") ||
192
- failureReason.includes("connection") ||
193
- failureReason.includes("JSON RPC")) {
194
- logExtension({
195
- subsystem: "lsp-runner",
196
- message: `LSP server failed for ${diagnosticPath}: ${failureReason}`,
197
- metadata: { filePath: diagnosticPath },
198
- });
199
- }
200
- }
201
- if (serverFailed) {
202
- return {
203
- status: "failed",
204
- failureKind: "server_error",
205
- failureMessage: failureReason.slice(0, 200),
206
- diagnostics: [
207
- {
208
- id: `lsp:server-error:0`,
209
- message: `LSP server failed: ${failureReason}`,
210
- filePath: diagnosticPath,
211
- line: 1,
212
- column: 1,
213
- severity: "error",
214
- semantic: "warning", // Don't block - fallback to other runners
215
- tool: "lsp",
216
- },
217
- ],
218
- semantic: "warning",
219
- };
220
- }
221
- if (!lspClientReady) {
222
- // No answer from the LSP — reporting "succeeded with 0 diagnostics"
223
- // would read as a clean bill of health when we simply didn't get a
224
- // reply. Report "skipped" so the coverage notice can flag the gap and
225
- // the next edit re-checks once the server has warmed; any diagnostics
226
- // published late still land in the client cache and surface then.
227
- return { status: "skipped", diagnostics: [], semantic: "none" };
228
- }
229
- if (diagnosticsInconclusive) {
230
- // The touch ran and a client was ready, but the notify write and/or
231
- // diagnostics wait hit their deadline before the server confirmed
232
- // completion — `lspDiags` (even if non-empty) is not a trustworthy
233
- // merged result. Same treatment as `!lspClientReady`: report
234
- // "skipped" rather than "succeeded" with a possibly-incomplete
235
- // diagnostics list, so the coverage notice flags the gap instead of
236
- // the footer reading this as a confirmed clean/partial result (#570).
237
- // Diagnostics that do arrive late still land in the client cache and
238
- // surface on the next edit.
239
- return { status: "skipped", diagnostics: [], semantic: "none" };
240
- }
241
- if (lspDiags.length === 0) {
242
- if (deferredServerIds.length > 0) {
243
- return {
244
- status: "deferred",
245
- diagnostics: [],
246
- semantic: "none",
247
- unconfirmedServerIds: [...unconfirmedServerIds],
248
- deferredServerIds: [...deferredServerIds],
249
- };
250
- }
251
- if (unconfirmedServerIds.length > 0) {
252
- // #1470/#1493: an auxiliary never reported — cut off by the aux grace
253
- // timer, or silent with nothing published for this content — so this
254
- // empty merged result is missing whatever that scanner would have said.
255
- // A hung OR silent opengrep must not read as a clean bill of health on
256
- // the security lane. The empty result remains skipped, while the correlated
257
- // server ids let the coverage notice name the missing scanners once. Nothing
258
- // is thrown away: the primary answered with zero findings, so there is nothing to
259
- // report; when it DOES have findings the branches below still report
260
- // them (see the non-empty path), which is how a trustworthy primary
261
- // stays trustworthy under an auxiliary that never reported.
262
- return {
263
- status: "skipped",
264
- diagnostics: [],
265
- semantic: "none",
266
- unconfirmedServerIds: [...unconfirmedServerIds],
267
- };
268
- }
269
- return {
270
- status: "succeeded",
271
- diagnostics: [],
272
- semantic: "none",
273
- rawOutput: "no-diagnostics",
274
- };
275
- }
276
- // Convert LSP diagnostics to our format
277
- // Defensive: filter out malformed diagnostics that may lack range
278
- const rawValidLspDiags = lspDiags.filter((d) => d.range?.start?.line !== undefined);
279
- // #1640: the per-edit path renders the same authority as the mode=full
280
- // sweep, so it applies the same demotion. Costs one bounded `projectInfo`
281
- // request, and only when the file already has a TypeScript ERROR — an edit
282
- // that type-checks clean pays nothing.
283
- //
284
- // #1645 review F2: NOT under warm attach. There, diagnostics came from an
285
- // already-running remote session over IPC and no local client exists — so
286
- // the probe would have to spawn a whole tsserver fleet to answer, breaking
287
- // this branch's spawn-free contract (see the comment below), and the
288
- // answer it spawned for would be the NEW server's project resolution, not
289
- // the warm session's. A meaningless answer bought with a process is worse
290
- // than no answer, so the warm-attach path keeps pre-#1640 rendering. This
291
- // is a known gap, recorded on the issue rather than papered over with an
292
- // "unverified" label that would fire on every warm-attach file including
293
- // the properly configured majority.
294
- const validLspDiags = usedWarmAttach
295
- ? rawValidLspDiags
296
- : await demoteInferredProjectDiagnostics(rawValidLspDiags, {
297
- filePath: diagnosticPath,
298
- cwd: ctx.cwd,
299
- service: lspService,
300
- });
301
- const fixSuggestionByIndex = new Map();
302
- // #1640: read severity off the RAW list. A demoted diagnostic is still
303
- // worth a quick-fix suggestion — the demotion changes its authority, not
304
- // whether tsserver can offer a fix. Indexes align 1:1 with `validLspDiags`.
305
- const blockingDiagIndexes = rawValidLspDiags
306
- .map((d, idx) => ({ d, idx }))
307
- .filter(({ d }) => d.severity === 1)
308
- .slice(0, WARM_CODE_ACTION_LOOKUP_LIMIT);
309
- if (usedWarmAttach) {
310
- // Diagnostics have already succeeded. Code actions are optional
311
- // enrichment, so ANY IPC failure degrades to today's skip without
312
- // promoting the attached session to a local LSP fleet.
313
- const ranges = blockingDiagIndexes.map(({ d }) => ({
314
- start: d.range.start,
315
- end: d.range.end ?? d.range.start,
316
- }));
317
- const result = await tryWarmAttachedCodeActions(ctx.filePath, contentHash(content), ranges, LSP_DIAGNOSTICS_WAIT_MS);
318
- if (result?.available) {
319
- result.response.actions.forEach((actions, responseIndex) => {
320
- const diagnosticIndex = blockingDiagIndexes[responseIndex]?.idx;
321
- const suggestion = buildCodeActionSuggestion(actions);
322
- if (diagnosticIndex !== undefined && suggestion) {
323
- fixSuggestionByIndex.set(diagnosticIndex, suggestion);
324
- }
325
- });
326
- }
327
- }
328
- else {
329
- await Promise.all(blockingDiagIndexes.map(async ({ d, idx }) => {
330
- try {
331
- const start = d.range.start;
332
- const end = d.range.end ?? d.range.start;
333
- const actions = await lspService.codeAction(ctx.filePath, start.line, start.character, end.line, end.character);
334
- const suggestion = buildCodeActionSuggestion(actions);
335
- if (suggestion) {
336
- fixSuggestionByIndex.set(idx, suggestion);
337
- }
338
- }
339
- catch {
340
- // Best-effort enrichment only; base diagnostics remain authoritative.
341
- }
342
- }));
343
- }
344
- const diagnostics = convertLspDiagnostics(validLspDiags, diagnosticPath, { fixSuggestionByIndex });
345
- // convertLspDiagnostics maps validLspDiags 1:1, so re-tag any
346
- // auxiliary-sourced diagnostics (opengrep emits source "Semgrep", …) with
347
- // their tool id + semantic policy — language-server diagnostics keep "lsp".
348
- // #692: shared with the scan/sweep reconcile paths (`retagAuxiliaryDiagnostics`
349
- // in `../auxiliary-lsp.js`) so a scan-reconciled aux finding gets identical
350
- // tool/semantic/defectClass tagging instead of keeping tool "lsp".
351
- const keptDiagnostics = retagAuxiliaryDiagnostics(diagnostics, validLspDiags, content, { cwd: ctx.cwd, fileRole: ctx.fileRole });
352
- const hasErrors = keptDiagnostics.some((d) => d.semantic === "blocking");
353
- const resultSemantic = hasErrors
354
- ? "blocking"
355
- : keptDiagnostics.length > 0
356
- ? "warning"
357
- : "none";
358
- return {
359
- status: hasErrors
360
- ? "failed"
361
- : deferredServerIds.length > 0
362
- ? "deferred"
363
- : "succeeded",
364
- // "failed" here means the file has blocking type errors — the check ran
365
- // fine. Tag it so the smell analyzer doesn't read it as a runner crash.
366
- failureKind: hasErrors ? "blocking_diagnostics" : undefined,
367
- diagnostics: keptDiagnostics,
368
- semantic: resultSemantic,
369
- ...(unconfirmedServerIds.length > 0 && {
370
- unconfirmedServerIds: [...unconfirmedServerIds],
371
- }),
372
- ...(deferredServerIds.length > 0 && {
373
- deferredServerIds: [...deferredServerIds],
374
- }),
375
- };
376
- },
377
- };
378
- export default lspRunner;
@@ -1,160 +0,0 @@
1
- import { safeSpawnAsync } from "../../safe-spawn.js";
2
- import { logRunnerAdvisoryOnce, resolveRunnerCwd } from "../../tool-cwd.js";
3
- import { getLinterPolicyForCwd, markdownlintConfigArgs, } from "../../tool-policy.js";
4
- import { PRIORITY } from "../priorities.js";
5
- import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
6
- import { parseToolRun } from "./utils/tool-failure.js";
7
- import { isInSpawnTimeoutCooldown, noteSpawnTimeout, } from "../../spawn-timeout-cooldown.js";
8
- import { finishParsedRun } from "./utils/tool-failure.js";
9
- const markdownlint = createAvailabilityChecker("markdownlint-cli2", ".cmd", [
10
- "--no-globs",
11
- "-",
12
- ]);
13
- // markdownlint-cli2 exit codes (its README's "Exit Codes" section): 0 = no
14
- // findings, 1 = lint findings, 2 = unexpected error (unreadable config, bad
15
- // glob, crash). Only 2 is a rejected invocation.
16
- const MARKDOWNLINT_EXIT_CODES = { ran: [1] };
17
- // markdownlint-cli2 text output does not include per-violation fixability,
18
- // so we keep a static allowlist of MD### rules whose --fix is deterministic.
19
- // Sourced from the rule pages in
20
- // https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md — every
21
- // entry below is documented as "Fixable: yes" (or equivalent). Update when
22
- // markdownlint adds or changes auto-fix support.
23
- const MARKDOWNLINT_FIXABLE_RULES = new Set([
24
- "MD001",
25
- "MD004",
26
- "MD005",
27
- "MD007",
28
- "MD009",
29
- "MD010",
30
- "MD011",
31
- "MD012",
32
- "MD014",
33
- "MD018",
34
- "MD019",
35
- "MD020",
36
- "MD021",
37
- "MD022",
38
- "MD023",
39
- "MD026",
40
- "MD027",
41
- "MD030",
42
- "MD031",
43
- "MD032",
44
- "MD034",
45
- "MD037",
46
- "MD038",
47
- "MD039",
48
- "MD044",
49
- "MD047",
50
- "MD049",
51
- "MD050",
52
- "MD053",
53
- "MD058",
54
- ]);
55
- // markdownlint-cli2 output: `path:line[:col] [error|warning] MD###/name[/name…] message`
56
- // Two things the original parser missed (→ silent 0 diagnostics, #212):
57
- // 1. cli2 emits a severity token (`error`/`warning`) between the col and the
58
- // rule code — older markdownlint-cli did not.
59
- // 2. some rules carry MULTIPLE slash-separated names (e.g.
60
- // `MD041/first-line-heading/first-line-h1`).
61
- // The severity token is optional so older/relative-path output still parses.
62
- function parseMarkdownlintOutput(raw, filePath) {
63
- const diagnostics = [];
64
- for (const line of raw.split(/\r?\n/)) {
65
- if (!line.trim())
66
- continue;
67
- // Rule code is MD### followed by one or more slash-joined names. Use a
68
- // single char class (`[\w/-]+`) rather than a nested quantifier
69
- // (`(?:/[\w-]+)+`) so there's no super-linear backtracking (S5852).
70
- const match = line.match(/^.*?:(\d+)(?::(\d+))?\s+(?:error|warning)?\s*(MD\d+\/[\w/-]+)\s+(.+)$/);
71
- if (!match)
72
- continue;
73
- const [, lineNum, col, ruleCode, message] = match;
74
- const ruleName = ruleCode.split("/")[0];
75
- const fixable = MARKDOWNLINT_FIXABLE_RULES.has(ruleName);
76
- diagnostics.push({
77
- id: `markdownlint-${lineNum}-${ruleName}`,
78
- message: `[${ruleCode}] ${message}`,
79
- filePath,
80
- line: Number(lineNum),
81
- column: col ? Number(col) : 1,
82
- severity: "warning",
83
- semantic: "warning",
84
- tool: "markdownlint",
85
- rule: ruleName,
86
- fixable,
87
- fixSuggestion: fixable
88
- ? "Run `markdownlint-cli2 --fix` to apply the deterministic auto-correction for this rule."
89
- : undefined,
90
- });
91
- }
92
- return diagnostics;
93
- }
94
- const markdownlintRunner = {
95
- id: "markdownlint",
96
- appliesTo: ["markdown"],
97
- priority: PRIORITY.DOC_QUALITY,
98
- skipTestFiles: false,
99
- async run(ctx) {
100
- const cwd = resolveRunnerCwd(ctx, "markdownlint");
101
- const policy = getLinterPolicyForCwd(ctx.filePath, cwd);
102
- if (policy && !policy.preferredRunners.includes("markdownlint")) {
103
- return { status: "skipped", diagnostics: [], semantic: "none" };
104
- }
105
- let cmd = null;
106
- if (await markdownlint.isAvailableAsync(cwd)) {
107
- cmd = markdownlint.getCommand(cwd);
108
- }
109
- else {
110
- cmd = await resolveToolCommandWithInstallFallback(cwd, "markdownlint");
111
- }
112
- if (!cmd)
113
- return { status: "skipped", diagnostics: [], semantic: "none" };
114
- // #1995: a command cooling down after a spawn timeout already consumed
115
- // its budget in another lane (availability verify, autofix --fix). Skip
116
- // without spawning — "not checked", never re-reported as clean.
117
- if (isInSpawnTimeoutCooldown(cmd)) {
118
- logRunnerAdvisoryOnce(ctx, "markdownlint", cwd, `markdownlint: ${cmd} is cooling down after a spawn timeout — skipping (one bounded failure budget per edit)`);
119
- return { status: "skipped", diagnostics: [], semantic: "none" };
120
- }
121
- // Shared config-args seam (#1247): the autofix path consumes the same
122
- // builder, so the package-owned fallback config can never drift.
123
- const configArgs = markdownlintConfigArgs(cwd);
124
- const result = await safeSpawnAsync(cmd, [...configArgs, ctx.filePath], {
125
- timeout: 15000,
126
- cwd,
127
- });
128
- // #1995: a timeout is negative runtime evidence. Arm the cooldown so
129
- // the autofix and availability lanes cannot hand this command a second
130
- // budget within the same session.
131
- if (result.failure === "timeout") {
132
- noteSpawnTimeout({
133
- tool: "markdownlint",
134
- command: cmd,
135
- phase: "lint",
136
- durationMs: 15000,
137
- teardown: result.timeoutTeardown,
138
- });
139
- }
140
- // #1816: this runner read `result.status` zero times, so an exit-2
141
- // config error with an empty stdout parsed to zero diagnostics and was
142
- // reported as a clean Markdown file. An empty result must distinguish
143
- // clean from errored.
144
- const raw = `${result.stdout ?? ""}${result.stderr ?? ""}`;
145
- // #1948: one seam for both gates — the tool produced nothing, and the
146
- // tool produced something the parser could not read.
147
- const run = parseToolRun("markdownlint", { result, output: raw, exitCodes: MARKDOWNLINT_EXIT_CODES }, (out) => parseMarkdownlintOutput(out, ctx.filePath));
148
- if (run.skipped)
149
- return run.skipped;
150
- const diagnostics = run.diagnostics;
151
- return finishParsedRun({
152
- tool: "markdownlint",
153
- ctx,
154
- result,
155
- diagnostics,
156
- classify: () => ({ status: "succeeded", semantic: "warning" }),
157
- });
158
- },
159
- };
160
- export default markdownlintRunner;
@@ -1,101 +0,0 @@
1
- import * as path from "node:path";
2
- import { safeSpawnAsync } from "../../safe-spawn.js";
3
- import { resolveRunnerCwd } from "../../tool-cwd.js";
4
- import { hasMypyConfig } from "../../tool-policy.js";
5
- import { PRIORITY } from "../priorities.js";
6
- import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
7
- import { parseToolRun } from "./utils/tool-failure.js";
8
- import { finishParsedRun } from "./utils/tool-failure.js";
9
- const mypy = createAvailabilityChecker("mypy", "");
10
- // mypy exit codes: 0 = no type errors, 1 = type errors found, 2 = a blocking
11
- // error. 2 is NOT a rejected invocation on its own — mypy reports a source
12
- // SYNTAX error under 2 and still writes a normal parsable diagnostic to stdout
13
- // (verified live against mypy 2.3.1: `syn.py:1: error: Invalid syntax
14
- // [syntax]`). A bad flag or unreadable config also exits 2, but writes its
15
- // message to STDERR and leaves stdout empty.
16
- //
17
- // So the exit code cannot separate the two, and the STREAM does: the gate below
18
- // judges "nothing to parse" on stdout alone, while the parser still reads both.
19
- // The table's remaining job is to reject any OTHER nonzero status.
20
- const MYPY_EXIT_CODES = { ran: [1, 2] };
21
- // mypy output: file.py:10: error: Incompatible types [assignment]
22
- //
23
- // mypy follows imports and reports errors in OTHER modules, not just the file
24
- // it was invoked on. Attribute each diagnostic to the file mypy names (group 1,
25
- // resolved against cwd) rather than blanket-stamping ctx.filePath — otherwise a
26
- // cross-file regression is mis-located onto the edited file (#265 A2). We do NOT
27
- // filter to the edited file: surfacing the cross-file impact is the point.
28
- export function parseMypyOutput(raw, fallbackPath, cwd) {
29
- const diagnostics = [];
30
- const linePattern = /^(.+?):(\d+)(?::(\d+))?:\s*(error|warning|note):\s*(.+?)(?:\s+\[([^\]]+)\])?$/gm;
31
- for (const match of raw.matchAll(linePattern)) {
32
- const [, file, lineNum, col, level, message, errorCode] = match;
33
- if (!lineNum || !level || !message)
34
- continue;
35
- if (level === "note")
36
- continue; // skip contextual notes
37
- const severity = level === "error" ? "error" : "warning";
38
- const rule = errorCode ?? "mypy";
39
- const filePath = file && file.trim()
40
- ? path.isAbsolute(file)
41
- ? file
42
- : path.resolve(cwd, file)
43
- : fallbackPath;
44
- diagnostics.push({
45
- id: `mypy-${lineNum}-${rule}`,
46
- message: errorCode ? `[${errorCode}] ${message}` : message,
47
- filePath,
48
- line: Number(lineNum),
49
- column: col ? Number(col) : 1,
50
- severity,
51
- semantic: severity === "error" ? "blocking" : "warning",
52
- tool: "mypy",
53
- rule,
54
- defectClass: "correctness",
55
- });
56
- }
57
- return diagnostics;
58
- }
59
- const mypyRunner = {
60
- id: "mypy",
61
- appliesTo: ["python"],
62
- priority: PRIORITY.GENERAL_ANALYSIS,
63
- skipTestFiles: false,
64
- async run(ctx) {
65
- const cwd = resolveRunnerCwd(ctx, "mypy");
66
- // Only run if mypy config exists — avoids false positives in untyped projects
67
- if (!hasMypyConfig(cwd)) {
68
- return { status: "skipped", diagnostics: [], semantic: "none" };
69
- }
70
- let cmd = null;
71
- if (await mypy.isAvailableAsync(cwd)) {
72
- cmd = mypy.getCommand(cwd);
73
- }
74
- else {
75
- cmd = await resolveToolCommandWithInstallFallback(cwd, "mypy");
76
- }
77
- if (!cmd)
78
- return { status: "skipped", diagnostics: [], semantic: "none" };
79
- const result = await safeSpawnAsync(cmd, ["--no-error-summary", "--show-column-numbers", ctx.filePath], { timeout: 30000, cwd });
80
- // #1816: this runner read `result.status` zero times, so an exit-2
81
- // config error reported the file as cleanly type-checked. The gate reads
82
- // stdout only (see MYPY_EXIT_CODES) so an exit-2 SYNTAX error, which
83
- // does write a diagnostic there, still reaches the parser.
84
- const raw = `${result.stdout ?? ""}${result.stderr ?? ""}`;
85
- // #1948: `parseOutput` keeps the split this runner already had — the gate
86
- // judges "did it run" on stdout alone, the parser still reads both
87
- // streams — so adding the parsed-nothing record does not widen the
88
- // did-it-run verdict.
89
- const run = parseToolRun("mypy", { result, output: result.stdout, exitCodes: MYPY_EXIT_CODES }, (out) => parseMypyOutput(out, ctx.filePath, cwd), { parseOutput: raw });
90
- if (run.skipped)
91
- return run.skipped;
92
- const diagnostics = run.diagnostics;
93
- return finishParsedRun({
94
- tool: "mypy",
95
- ctx,
96
- result,
97
- diagnostics,
98
- });
99
- },
100
- };
101
- export default mypyRunner;