pi-lens 4.3.0 → 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 (650) hide show
  1. package/CHANGELOG.md +1064 -0
  2. package/README.md +115 -25
  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 +16456 -8335
  125. package/dist/mcp/analyze-cli.js +186 -232
  126. package/dist/mcp/cli.js +137 -98
  127. package/dist/mcp/server.js +22589 -1573
  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/agent-guide.md +13 -4
  133. package/docs/agent-tools.md +42 -0
  134. package/docs/ast-grep_rules_catalog.md +3 -2
  135. package/docs/configuration.md +20 -1
  136. package/docs/environment-variables.md +52 -2
  137. package/docs/features.md +8 -4
  138. package/docs/globalconfig.md +1 -0
  139. package/docs/io-bridge-v2-migration.md +94 -0
  140. package/docs/lsp-capability-matrix.md +36 -4
  141. package/docs/lsp-idle-eviction.md +124 -0
  142. package/docs/mcp.md +21 -5
  143. package/docs/merge-queue-rollout.md +77 -0
  144. package/docs/pi-lens-fixer.md +156 -88
  145. package/docs/pi-lens-investigator.md +74 -26
  146. package/docs/pi-lens-merge-policy.md +694 -0
  147. package/docs/pi-lens-monitor.md +73 -7
  148. package/docs/pi-lens-retro.md +6 -4
  149. package/docs/pi-lens-reviewer.md +188 -48
  150. package/docs/pi-lens-subagent.md +246 -45
  151. package/docs/pi-lens-warden.md +18 -7
  152. package/docs/public-api-stability.md +55 -0
  153. package/docs/release-qa-baseline.md +84 -17
  154. package/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
  155. package/docs/servercapabilities.md +53 -49
  156. package/docs/settings.md +1 -0
  157. package/docs/usage.md +5 -1
  158. package/grammars/tree-sitter-bash.wasm +0 -0
  159. package/grammars/tree-sitter-bash.wasm.json +3 -3
  160. package/package.json +19 -7
  161. package/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  162. package/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  163. package/scripts/analyze-pi-lens-logs.mjs +1275 -62
  164. package/scripts/download-grammars.js +5 -0
  165. package/scripts/grammars.lock.json +6 -1
  166. package/scripts/install-selftest.mjs +33 -34
  167. package/scripts/lib/host-provided-deps.mjs +13 -4
  168. package/scripts/lib/web-tree-sitter-dir.mjs +18 -0
  169. package/dist/clients/actionable-warnings-logger.js +0 -35
  170. package/dist/clients/actionable-warnings.js +0 -1610
  171. package/dist/clients/advisory-provenance.js +0 -593
  172. package/dist/clients/agent-behavior-client.js +0 -147
  173. package/dist/clients/agent-nudge.js +0 -325
  174. package/dist/clients/analysed-root.js +0 -1
  175. package/dist/clients/ast-grep-client.js +0 -731
  176. package/dist/clients/ast-grep-rule-manager.js +0 -146
  177. package/dist/clients/ast-grep-tool-logger.js +0 -118
  178. package/dist/clients/ast-grep-types.js +0 -10
  179. package/dist/clients/ast-grep-yaml-synth.js +0 -154
  180. package/dist/clients/atomic-write-staging.js +0 -75
  181. package/dist/clients/atomic-write.js +0 -189
  182. package/dist/clients/availability-probe-flight.js +0 -12
  183. package/dist/clients/bash-file-access.js +0 -1056
  184. package/dist/clients/biome-client.js +0 -357
  185. package/dist/clients/blocker-freshness.js +0 -837
  186. package/dist/clients/blocker-past-eof.js +0 -129
  187. package/dist/clients/bootstrap.js +0 -569
  188. package/dist/clients/bounded-cache.js +0 -190
  189. package/dist/clients/bounded-pid-file-lock.js +0 -202
  190. package/dist/clients/bounded-telemetry.js +0 -295
  191. package/dist/clients/build-identity.js +0 -95
  192. package/dist/clients/bundled-resource-health.js +0 -113
  193. package/dist/clients/bus-events-logger.js +0 -105
  194. package/dist/clients/bus-publish.js +0 -171
  195. package/dist/clients/cache/rule-cache.js +0 -190
  196. package/dist/clients/cache-manager.js +0 -524
  197. package/dist/clients/cache-observability.js +0 -1313
  198. package/dist/clients/call-graph.js +0 -852
  199. package/dist/clients/cargo-manifest.js +0 -422
  200. package/dist/clients/cascade-budget.js +0 -196
  201. package/dist/clients/cascade-format.js +0 -315
  202. package/dist/clients/cascade-logger.js +0 -31
  203. package/dist/clients/cascade-types.js +0 -9
  204. package/dist/clients/child-unref.js +0 -124
  205. package/dist/clients/code-quality-warnings.js +0 -286
  206. package/dist/clients/codebase-model.js +0 -173
  207. package/dist/clients/collateral-test-role.js +0 -40
  208. package/dist/clients/complexity-client.js +0 -462
  209. package/dist/clients/config-core/deny.js +0 -221
  210. package/dist/clients/config-core/index.js +0 -50
  211. package/dist/clients/config-core/merge.js +0 -357
  212. package/dist/clients/config-core/normalize.js +0 -340
  213. package/dist/clients/config-core/process-spec.js +0 -248
  214. package/dist/clients/config-core/provenance.js +0 -164
  215. package/dist/clients/config-core/records.js +0 -218
  216. package/dist/clients/config-core/resolve.js +0 -125
  217. package/dist/clients/config-core/safe-object.js +0 -78
  218. package/dist/clients/config-core/schema.js +0 -165
  219. package/dist/clients/config-diagnostic-codes.js +0 -285
  220. package/dist/clients/config-locations.js +0 -388
  221. package/dist/clients/config-resolve.js +0 -798
  222. package/dist/clients/config-schema.js +0 -251
  223. package/dist/clients/config-warn.js +0 -407
  224. package/dist/clients/console-guard-install.js +0 -26
  225. package/dist/clients/cooperative-budget.js +0 -42
  226. package/dist/clients/dead-code-client.js +0 -510
  227. package/dist/clients/dead-code-logger.js +0 -30
  228. package/dist/clients/deadline-utils.js +0 -280
  229. package/dist/clients/debug-handles.js +0 -211
  230. package/dist/clients/debug-heap.js +0 -174
  231. package/dist/clients/deferred-lsp-work.js +0 -106
  232. package/dist/clients/degradation-ledger.js +0 -426
  233. package/dist/clients/demoted-finding-render.js +0 -169
  234. package/dist/clients/dependency-checker.js +0 -885
  235. package/dist/clients/deps/ast-grep-napi.js +0 -22
  236. package/dist/clients/deps/js-yaml.js +0 -9
  237. package/dist/clients/deps/minimatch.js +0 -4
  238. package/dist/clients/deps/pi-tui.js +0 -14
  239. package/dist/clients/deps/typebox.js +0 -14
  240. package/dist/clients/deps/vscode-jsonrpc.js +0 -1
  241. package/dist/clients/deps/web-tree-sitter.js +0 -24
  242. package/dist/clients/diagnostic-dispositions.js +0 -630
  243. package/dist/clients/diagnostic-line-freshness.js +0 -305
  244. package/dist/clients/diagnostic-logger.js +0 -73
  245. package/dist/clients/diagnostic-tracker.js +0 -105
  246. package/dist/clients/diagnostics-publish.js +0 -230
  247. package/dist/clients/dispatch/ast-grep-catalog.js +0 -65
  248. package/dist/clients/dispatch/auxiliary-lsp.js +0 -343
  249. package/dist/clients/dispatch/collect-later-tier.js +0 -35
  250. package/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
  251. package/dist/clients/dispatch/dispatcher.js +0 -1269
  252. package/dist/clients/dispatch/fact-provider-types.js +0 -1
  253. package/dist/clients/dispatch/fact-rule-runner.js +0 -17
  254. package/dist/clients/dispatch/fact-runner.js +0 -30
  255. package/dist/clients/dispatch/fact-scheduler.js +0 -68
  256. package/dist/clients/dispatch/fact-store.js +0 -377
  257. package/dist/clients/dispatch/facts/comment-facts.js +0 -22
  258. package/dist/clients/dispatch/facts/file-content.js +0 -19
  259. package/dist/clients/dispatch/facts/function-facts.js +0 -348
  260. package/dist/clients/dispatch/facts/import-facts.js +0 -204
  261. package/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
  262. package/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
  263. package/dist/clients/dispatch/finding-policy.js +0 -339
  264. package/dist/clients/dispatch/indent-detect.js +0 -417
  265. package/dist/clients/dispatch/inline-suppressions.js +0 -89
  266. package/dist/clients/dispatch/integration.js +0 -2377
  267. package/dist/clients/dispatch/lazy.js +0 -11
  268. package/dist/clients/dispatch/pending-runner-findings.js +0 -87
  269. package/dist/clients/dispatch/plan.js +0 -278
  270. package/dist/clients/dispatch/priorities.js +0 -20
  271. package/dist/clients/dispatch/rule-id-normalize.js +0 -50
  272. package/dist/clients/dispatch/rule-ignores.js +0 -69
  273. package/dist/clients/dispatch/rule-policy.js +0 -135
  274. package/dist/clients/dispatch/rules/async-noise.js +0 -40
  275. package/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  276. package/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
  277. package/dist/clients/dispatch/rules/error-obscuring.js +0 -32
  278. package/dist/clients/dispatch/rules/error-swallowing.js +0 -31
  279. package/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
  280. package/dist/clients/dispatch/rules/high-complexity.js +0 -72
  281. package/dist/clients/dispatch/rules/high-fan-out.js +0 -74
  282. package/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
  283. package/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
  284. package/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
  285. package/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
  286. package/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  287. package/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
  288. package/dist/clients/dispatch/runner-context.js +0 -52
  289. package/dist/clients/dispatch/runners/actionlint.js +0 -111
  290. package/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
  291. package/dist/clients/dispatch/runners/biome-check.js +0 -296
  292. package/dist/clients/dispatch/runners/cpp-check.js +0 -219
  293. package/dist/clients/dispatch/runners/credo.js +0 -82
  294. package/dist/clients/dispatch/runners/cue-vet.js +0 -416
  295. package/dist/clients/dispatch/runners/dart-analyze.js +0 -183
  296. package/dist/clients/dispatch/runners/detekt.js +0 -176
  297. package/dist/clients/dispatch/runners/dotnet-build.js +0 -164
  298. package/dist/clients/dispatch/runners/elixir-check.js +0 -195
  299. package/dist/clients/dispatch/runners/eslint.js +0 -137
  300. package/dist/clients/dispatch/runners/fact-rules.js +0 -29
  301. package/dist/clients/dispatch/runners/fish-indent.js +0 -69
  302. package/dist/clients/dispatch/runners/gleam-check.js +0 -167
  303. package/dist/clients/dispatch/runners/go-vet.js +0 -104
  304. package/dist/clients/dispatch/runners/golangci-lint.js +0 -135
  305. package/dist/clients/dispatch/runners/hadolint.js +0 -91
  306. package/dist/clients/dispatch/runners/helm-lint.js +0 -171
  307. package/dist/clients/dispatch/runners/helm-render.js +0 -940
  308. package/dist/clients/dispatch/runners/htmlhint.js +0 -117
  309. package/dist/clients/dispatch/runners/index.js +0 -108
  310. package/dist/clients/dispatch/runners/javac.js +0 -99
  311. package/dist/clients/dispatch/runners/ktlint.js +0 -110
  312. package/dist/clients/dispatch/runners/lsp.js +0 -379
  313. package/dist/clients/dispatch/runners/markdownlint.js +0 -167
  314. package/dist/clients/dispatch/runners/mypy.js +0 -102
  315. package/dist/clients/dispatch/runners/oxlint.js +0 -414
  316. package/dist/clients/dispatch/runners/php-lint.js +0 -85
  317. package/dist/clients/dispatch/runners/phpstan.js +0 -120
  318. package/dist/clients/dispatch/runners/prisma-validate.js +0 -62
  319. package/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
  320. package/dist/clients/dispatch/runners/pyright.js +0 -169
  321. package/dist/clients/dispatch/runners/rubocop.js +0 -99
  322. package/dist/clients/dispatch/runners/ruff.js +0 -88
  323. package/dist/clients/dispatch/runners/rust-clippy.js +0 -256
  324. package/dist/clients/dispatch/runners/shellcheck.js +0 -173
  325. package/dist/clients/dispatch/runners/shfmt.js +0 -102
  326. package/dist/clients/dispatch/runners/spellcheck.js +0 -128
  327. package/dist/clients/dispatch/runners/spotbugs.js +0 -259
  328. package/dist/clients/dispatch/runners/sqlfluff.js +0 -183
  329. package/dist/clients/dispatch/runners/stylelint.js +0 -166
  330. package/dist/clients/dispatch/runners/swiftlint.js +0 -163
  331. package/dist/clients/dispatch/runners/taplo.js +0 -174
  332. package/dist/clients/dispatch/runners/terragrunt.js +0 -168
  333. package/dist/clients/dispatch/runners/tflint.js +0 -125
  334. package/dist/clients/dispatch/runners/tree-sitter.js +0 -643
  335. package/dist/clients/dispatch/runners/trivy-config.js +0 -253
  336. package/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
  337. package/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
  338. package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
  339. package/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
  340. package/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
  341. package/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
  342. package/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
  343. package/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
  344. package/dist/clients/dispatch/runners/utils.js +0 -15
  345. package/dist/clients/dispatch/runners/vale.js +0 -128
  346. package/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
  347. package/dist/clients/dispatch/runners/yamllint.js +0 -95
  348. package/dist/clients/dispatch/runners/zig-check.js +0 -79
  349. package/dist/clients/dispatch/suppress-writer.js +0 -79
  350. package/dist/clients/dispatch/tool-profile.js +0 -30
  351. package/dist/clients/dispatch/types.js +0 -21
  352. package/dist/clients/dispatch/utils/format-utils.js +0 -45
  353. package/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
  354. package/dist/clients/disposition-logger.js +0 -32
  355. package/dist/clients/disposition-publish.js +0 -124
  356. package/dist/clients/durable-store.js +0 -97
  357. package/dist/clients/effective-config.js +0 -415
  358. package/dist/clients/env-utils.js +0 -83
  359. package/dist/clients/error-class.js +0 -23
  360. package/dist/clients/eval-timestamp.js +0 -17
  361. package/dist/clients/event-loop-hold.js +0 -274
  362. package/dist/clients/event-loop-monitor.js +0 -250
  363. package/dist/clients/extension-log.js +0 -504
  364. package/dist/clients/extension-mode.js +0 -73
  365. package/dist/clients/feature-hints.js +0 -103
  366. package/dist/clients/file-kinds.js +0 -412
  367. package/dist/clients/file-role.js +0 -134
  368. package/dist/clients/file-time.js +0 -160
  369. package/dist/clients/file-utils.js +0 -1032
  370. package/dist/clients/finding-delivery-gate.js +0 -494
  371. package/dist/clients/finding-identity.js +0 -88
  372. package/dist/clients/fix-worklog.js +0 -103
  373. package/dist/clients/format-events-publish.js +0 -343
  374. package/dist/clients/format-service.js +0 -222
  375. package/dist/clients/formatters-lazy.js +0 -9
  376. package/dist/clients/formatters.js +0 -2032
  377. package/dist/clients/freshness-cadence.js +0 -17
  378. package/dist/clients/freshness.js +0 -38
  379. package/dist/clients/generated-artifacts.js +0 -394
  380. package/dist/clients/generation-guard.js +0 -215
  381. package/dist/clients/git-guard.js +0 -1136
  382. package/dist/clients/git-tracked-ignore.js +0 -243
  383. package/dist/clients/gitleaks-client.js +0 -509
  384. package/dist/clients/go-client.js +0 -104
  385. package/dist/clients/govulncheck-client.js +0 -605
  386. package/dist/clients/gradle-ktfmt-style.js +0 -348
  387. package/dist/clients/grammar-source.js +0 -465
  388. package/dist/clients/gzip-stage-write.js +0 -135
  389. package/dist/clients/hashline-anchor.js +0 -424
  390. package/dist/clients/hook-budgets.js +0 -76
  391. package/dist/clients/host-edit-normalize.js +0 -140
  392. package/dist/clients/host-ports.js +0 -39
  393. package/dist/clients/indent-retarget.js +0 -154
  394. package/dist/clients/inline-blocker-dispositions.js +0 -186
  395. package/dist/clients/install-diagnostics.js +0 -156
  396. package/dist/clients/installer/index.js +0 -5416
  397. package/dist/clients/installer/managed-tool-refresh-session.js +0 -58
  398. package/dist/clients/installer/managed-tool-refresh.js +0 -783
  399. package/dist/clients/instance-reaper-state.js +0 -7
  400. package/dist/clients/instance-reaper.js +0 -1137
  401. package/dist/clients/instance-registry-lock.js +0 -145
  402. package/dist/clients/instance-registry.js +0 -773
  403. package/dist/clients/jscpd-client.js +0 -378
  404. package/dist/clients/json-cache-read.js +0 -65
  405. package/dist/clients/knip-client.js +0 -788
  406. package/dist/clients/language-policy.js +0 -252
  407. package/dist/clients/language-profile.js +0 -361
  408. package/dist/clients/language-registry.js +0 -603
  409. package/dist/clients/latency-logger.js +0 -727
  410. package/dist/clients/lazy-import.js +0 -21
  411. package/dist/clients/ledger-bounds.js +0 -54
  412. package/dist/clients/lens-config.js +0 -404
  413. package/dist/clients/lens-engine.js +0 -358
  414. package/dist/clients/lens-events.js +0 -125
  415. package/dist/clients/lens-flag-registry.js +0 -467
  416. package/dist/clients/lens-map.js +0 -1156
  417. package/dist/clients/live-bus-emitter.js +0 -74
  418. package/dist/clients/log-cleanup.js +0 -222
  419. package/dist/clients/lsp/aggregation.js +0 -178
  420. package/dist/clients/lsp/cascade-tier.js +0 -421
  421. package/dist/clients/lsp/client.js +0 -4593
  422. package/dist/clients/lsp/config.js +0 -691
  423. package/dist/clients/lsp/content-limits.js +0 -41
  424. package/dist/clients/lsp/diagnostic-binding.js +0 -225
  425. package/dist/clients/lsp/document-drift.js +0 -467
  426. package/dist/clients/lsp/edits.js +0 -1219
  427. package/dist/clients/lsp/index.js +0 -8305
  428. package/dist/clients/lsp/inferred-project.js +0 -216
  429. package/dist/clients/lsp/jvm-runtime.js +0 -298
  430. package/dist/clients/lsp/language.js +0 -63
  431. package/dist/clients/lsp/launch.js +0 -746
  432. package/dist/clients/lsp/lombok.js +0 -158
  433. package/dist/clients/lsp/path-utils.js +0 -5
  434. package/dist/clients/lsp/pending-aux-coverage.js +0 -251
  435. package/dist/clients/lsp/position-encoding.js +0 -61
  436. package/dist/clients/lsp/ruby-drive-dirs.js +0 -83
  437. package/dist/clients/lsp/server.js +0 -3290
  438. package/dist/clients/lsp/session-roots.js +0 -192
  439. package/dist/clients/lsp/spawn-history.js +0 -17
  440. package/dist/clients/lsp/sync-kind.js +0 -56
  441. package/dist/clients/lsp/tsserver-sync.js +0 -332
  442. package/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  443. package/dist/clients/lsp/wait-policy/classification.js +0 -85
  444. package/dist/clients/lsp/wait-policy/index.js +0 -10
  445. package/dist/clients/lsp/wait-policy/strategies.js +0 -392
  446. package/dist/clients/lsp/watch-queue.js +0 -61
  447. package/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
  448. package/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
  449. package/dist/clients/lsp/workspace-sweep-hold.js +0 -184
  450. package/dist/clients/lsp-budget.js +0 -186
  451. package/dist/clients/lsp-document-symbols.js +0 -110
  452. package/dist/clients/lsp-lazy.js +0 -9
  453. package/dist/clients/lsp-mutation.js +0 -396
  454. package/dist/clients/lsp-status.js +0 -59
  455. package/dist/clients/map-with-concurrency.js +0 -40
  456. package/dist/clients/mcp/analyze.js +0 -420
  457. package/dist/clients/mcp/host-shim.js +0 -31
  458. package/dist/clients/mcp/ipc.js +0 -523
  459. package/dist/clients/mcp/review.js +0 -197
  460. package/dist/clients/mcp/session.js +0 -412
  461. package/dist/clients/memory-sampler.js +0 -208
  462. package/dist/clients/message-end-attribution.js +0 -30
  463. package/dist/clients/metrics-client.js +0 -107
  464. package/dist/clients/metrics-history.js +0 -327
  465. package/dist/clients/middle-man-analysis.js +0 -263
  466. package/dist/clients/model-provider.js +0 -53
  467. package/dist/clients/module-report-lsp.js +0 -189
  468. package/dist/clients/module-report.js +0 -2150
  469. package/dist/clients/mutating-tool.js +0 -651
  470. package/dist/clients/mutation-attribution.js +0 -368
  471. package/dist/clients/mutation-bridge.js +0 -240
  472. package/dist/clients/ndjson-logger.js +0 -734
  473. package/dist/clients/observed-mutation-sources.js +0 -101
  474. package/dist/clients/observed-mutation.js +0 -1253
  475. package/dist/clients/oldtext-autopatch.js +0 -128
  476. package/dist/clients/opaque-mutation-scan.js +0 -496
  477. package/dist/clients/opengrep-client.js +0 -333
  478. package/dist/clients/opengrep-config.js +0 -76
  479. package/dist/clients/package-manager.js +0 -607
  480. package/dist/clients/package-root.js +0 -38
  481. package/dist/clients/partial-edit-apply.js +0 -439
  482. package/dist/clients/path-attribution-telemetry.js +0 -43
  483. package/dist/clients/path-keyed-map.js +0 -108
  484. package/dist/clients/path-utils.js +0 -1244
  485. package/dist/clients/performance-report.js +0 -331
  486. package/dist/clients/persist-debounce.js +0 -70
  487. package/dist/clients/persistent-reverify.js +0 -271
  488. package/dist/clients/php-cs-fixer-config.js +0 -119
  489. package/dist/clients/pipeline.js +0 -1480
  490. package/dist/clients/post-autofix-notice.js +0 -37
  491. package/dist/clients/print-mode.js +0 -21
  492. package/dist/clients/probe-home-state.js +0 -228
  493. package/dist/clients/process-bridge.js +0 -66
  494. package/dist/clients/process-singletons.js +0 -210
  495. package/dist/clients/process-snapshot.js +0 -68
  496. package/dist/clients/project-changes.js +0 -181
  497. package/dist/clients/project-conventions.js +0 -171
  498. package/dist/clients/project-diagnostics/cache.js +0 -137
  499. package/dist/clients/project-diagnostics/extractors.js +0 -109
  500. package/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
  501. package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
  502. package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
  503. package/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
  504. package/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
  505. package/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
  506. package/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
  507. package/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
  508. package/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
  509. package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
  510. package/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
  511. package/dist/clients/project-diagnostics/scanner.js +0 -520
  512. package/dist/clients/project-diagnostics/types.js +0 -1
  513. package/dist/clients/project-lens-config.js +0 -807
  514. package/dist/clients/project-report.js +0 -701
  515. package/dist/clients/project-scale.js +0 -237
  516. package/dist/clients/project-scan-policy.js +0 -11
  517. package/dist/clients/project-snapshot-fingerprint.js +0 -48
  518. package/dist/clients/project-snapshot-persist-worker.js +0 -20
  519. package/dist/clients/project-snapshot.js +0 -1653
  520. package/dist/clients/project-trust.js +0 -181
  521. package/dist/clients/python-environment.js +0 -217
  522. package/dist/clients/python-provenance.js +0 -639
  523. package/dist/clients/quiet-window-config.js +0 -47
  524. package/dist/clients/quiet-window.js +0 -236
  525. package/dist/clients/read-bridge.js +0 -139
  526. package/dist/clients/read-expansion.js +0 -266
  527. package/dist/clients/read-guard-logger.js +0 -251
  528. package/dist/clients/read-guard-tool-lines.js +0 -1306
  529. package/dist/clients/read-guard.js +0 -1561
  530. package/dist/clients/recent-touches.js +0 -240
  531. package/dist/clients/redact/secrets.js +0 -449
  532. package/dist/clients/resource-sampler.js +0 -628
  533. package/dist/clients/reverse-deps.js +0 -270
  534. package/dist/clients/review-graph/builder.js +0 -5126
  535. package/dist/clients/review-graph/format.js +0 -33
  536. package/dist/clients/review-graph/git-identity.js +0 -163
  537. package/dist/clients/review-graph/import-resolvers.js +0 -481
  538. package/dist/clients/review-graph/persist-worker.js +0 -10
  539. package/dist/clients/review-graph/query.js +0 -244
  540. package/dist/clients/review-graph/revision-drift.js +0 -21
  541. package/dist/clients/review-graph/service.js +0 -96
  542. package/dist/clients/review-graph/shared-extraction-ir.js +0 -82
  543. package/dist/clients/review-graph/symbol-id.js +0 -103
  544. package/dist/clients/review-graph/tsconfig-paths.js +0 -299
  545. package/dist/clients/review-graph/types.js +0 -1
  546. package/dist/clients/review-graph/workspace-modules.js +0 -449
  547. package/dist/clients/review-graph-logger.js +0 -81
  548. package/dist/clients/ruff-client.js +0 -179
  549. package/dist/clients/rules-scanner.js +0 -131
  550. package/dist/clients/run-duration.js +0 -55
  551. package/dist/clients/runtime-agent-end.js +0 -746
  552. package/dist/clients/runtime-config.js +0 -77
  553. package/dist/clients/runtime-context.js +0 -211
  554. package/dist/clients/runtime-coordinator.js +0 -1324
  555. package/dist/clients/runtime-session.js +0 -2485
  556. package/dist/clients/runtime-tool-call.js +0 -1295
  557. package/dist/clients/runtime-tool-result.js +0 -2049
  558. package/dist/clients/runtime-turn.js +0 -3767
  559. package/dist/clients/rust-client.js +0 -97
  560. package/dist/clients/safe-spawn.js +0 -2357
  561. package/dist/clients/sanitize.js +0 -286
  562. package/dist/clients/scan-utils.js +0 -25
  563. package/dist/clients/scratch-tree-policy.js +0 -165
  564. package/dist/clients/search-read-registration.js +0 -94
  565. package/dist/clients/secret-findings.js +0 -114
  566. package/dist/clients/security-scan-client.js +0 -352
  567. package/dist/clients/session-event-guard.js +0 -297
  568. package/dist/clients/session-lifecycle.js +0 -484
  569. package/dist/clients/session-start-observability.js +0 -94
  570. package/dist/clients/session-state-store.js +0 -101
  571. package/dist/clients/session-summary.js +0 -15
  572. package/dist/clients/sessionstart-logger.js +0 -27
  573. package/dist/clients/sg-runner.js +0 -876
  574. package/dist/clients/sgconfig.js +0 -347
  575. package/dist/clients/shared-checkout-guard.js +0 -338
  576. package/dist/clients/single-flight.js +0 -158
  577. package/dist/clients/situational-tool-telemetry.js +0 -108
  578. package/dist/clients/skills-resolver.js +0 -141
  579. package/dist/clients/slow-fs.js +0 -138
  580. package/dist/clients/smells-rollup.js +0 -231
  581. package/dist/clients/source-filter.js +0 -596
  582. package/dist/clients/source-walker.js +0 -211
  583. package/dist/clients/spawn-output-cap.js +0 -120
  584. package/dist/clients/spawn-timeout-cooldown.js +0 -110
  585. package/dist/clients/stale-marker.js +0 -17
  586. package/dist/clients/startup-scan.js +0 -400
  587. package/dist/clients/startup-timing.js +0 -130
  588. package/dist/clients/string-utils.js +0 -33
  589. package/dist/clients/subagent-mode.js +0 -111
  590. package/dist/clients/symbol-containment.js +0 -24
  591. package/dist/clients/symbol-types.js +0 -5
  592. package/dist/clients/test-runner-client.js +0 -2507
  593. package/dist/clients/test-runner-delivery.js +0 -287
  594. package/dist/clients/todo-scanner.js +0 -229
  595. package/dist/clients/tool-agreement.js +0 -423
  596. package/dist/clients/tool-config.js +0 -249
  597. package/dist/clients/tool-cwd.js +0 -270
  598. package/dist/clients/tool-definition.js +0 -47
  599. package/dist/clients/tool-event.js +0 -105
  600. package/dist/clients/tool-policy.js +0 -2755
  601. package/dist/clients/tool-probe.js +0 -53
  602. package/dist/clients/tool-render.js +0 -156
  603. package/dist/clients/tool-set-policy.js +0 -118
  604. package/dist/clients/tree-sitter-cache.js +0 -364
  605. package/dist/clients/tree-sitter-client.js +0 -4195
  606. package/dist/clients/tree-sitter-logger.js +0 -100
  607. package/dist/clients/tree-sitter-navigator.js +0 -269
  608. package/dist/clients/tree-sitter-query-loader.js +0 -569
  609. package/dist/clients/tree-sitter-shared.js +0 -158
  610. package/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
  611. package/dist/clients/trivy-client.js +0 -467
  612. package/dist/clients/tui-fit.js +0 -50
  613. package/dist/clients/turn-context.js +0 -52
  614. package/dist/clients/turn-end/lane.js +0 -51
  615. package/dist/clients/turn-end/lanes/govulncheck.js +0 -112
  616. package/dist/clients/turn-end/lanes/secrets.js +0 -204
  617. package/dist/clients/turn-summary-render.js +0 -72
  618. package/dist/clients/turn-summary.js +0 -132
  619. package/dist/clients/typos-config.js +0 -29
  620. package/dist/clients/user-notify.js +0 -51
  621. package/dist/clients/vanished-instance-marker.js +0 -57
  622. package/dist/clients/warm-attach.js +0 -305
  623. package/dist/clients/widget-state.js +0 -1808
  624. package/dist/clients/word-index-logger.js +0 -49
  625. package/dist/clients/word-index-store.js +0 -459
  626. package/dist/clients/word-index.js +0 -2080
  627. package/dist/clients/workspace-topology.js +0 -443
  628. package/dist/clients/write-ordering-guard.js +0 -65
  629. package/dist/clients/zizmor-config.js +0 -340
  630. package/dist/i18n.js +0 -69
  631. package/dist/mcp/build-staleness.js +0 -124
  632. package/dist/scripts/lib/process-scan.mjs +0 -583
  633. package/dist/scripts/lib/skills-predicate.mjs +0 -129
  634. package/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
  635. package/dist/tools/activate-tools.js +0 -87
  636. package/dist/tools/ast-grep-outline.js +0 -137
  637. package/dist/tools/ast-grep-replace.js +0 -244
  638. package/dist/tools/ast-grep-search.js +0 -762
  639. package/dist/tools/effective-config.js +0 -90
  640. package/dist/tools/lens-diagnostic-mark.js +0 -375
  641. package/dist/tools/lens-diagnostics.js +0 -2571
  642. package/dist/tools/lsp-diagnostics.js +0 -1745
  643. package/dist/tools/lsp-navigation.js +0 -1367
  644. package/dist/tools/lsp-structured-output.js +0 -294
  645. package/dist/tools/module-report.js +0 -382
  646. package/dist/tools/project-report.js +0 -86
  647. package/dist/tools/render-compact.js +0 -374
  648. package/dist/tools/scan-progress.js +0 -53
  649. package/dist/tools/shared.js +0 -29
  650. package/dist/tools/symbol-search.js +0 -155
@@ -1,101 +0,0 @@
1
- import { LEDGER_FIELD_MAX } from "../../../ledger-bounds.js";
2
- import { truncatedByOutputCap } from "../../../spawn-output-cap.js";
3
- /**
4
- * The first non-empty line of a tool's output, bounded.
5
- *
6
- * Replaces six hand-rolled copies that spelled the same idea two ways —
7
- * `text.trim().split("\n")[0]` and `(text ?? "").trim().split("\n")[0] ||
8
- * fallback` — with differing (or absent) length caps. Two behaviours the
9
- * copies got wrong and this does not: a leading blank line no longer yields an
10
- * empty "first line", and `\r\n` output no longer keeps its carriage return.
11
- *
12
- * Returns `""` when the text is empty or all-whitespace, so callers keep using
13
- * `firstOutputLine(x) || fallback`.
14
- */
15
- export function firstOutputLine(text, max = LEDGER_FIELD_MAX) {
16
- for (const line of String(text ?? "").split(/\r?\n/)) {
17
- const trimmed = line.trim();
18
- if (!trimmed)
19
- continue;
20
- return trimmed.length > max ? `${trimmed.slice(0, max)}…` : trimmed;
21
- }
22
- return "";
23
- }
24
- /**
25
- * Decide whether a tool ran, and if not, why (#1816).
26
- *
27
- * The defect this closes (the #1736 class): a runner that reads only its
28
- * parsed diagnostics reports a CLEAN file whenever the parse yields nothing —
29
- * including when the tool exited non-zero on an unknown flag, was killed by a
30
- * signal, or never spawned at all. An empty result must distinguish clean from
31
- * errored.
32
- *
33
- * Classification order, most specific first:
34
- * 1. `result.error` or a signal — the process never completed. `did-not-run`.
35
- * 2. `status === null` with no error — no exit status ever arrived, so no
36
- * analysis can be claimed. `did-not-run`.
37
- * 3. `reportMissing` — an artifact tool wrote no report. Nonzero exit means
38
- * `report-missing`; exit 0 means a genuinely clean run that had nothing
39
- * to write.
40
- * 4. A nonzero status outside the caller's declared `ran` table.
41
- * `rejected-invocation`.
42
- * 5. A nonzero status with nothing to parse. `did-not-run` — a tool that
43
- * analysed the file says SOMETHING, so silence plus failure is evidence
44
- * it never got that far.
45
- * Everything else ran.
46
- *
47
- * Note what is deliberately NOT a non-ran path: a nonzero status WITH output
48
- * and no contradicting table. Most linters exit non-zero precisely because
49
- * they found something, and their findings are on stdout.
50
- */
51
- export function classifyRunOutcome(input) {
52
- const { result, exitCodes, reportMissing } = input;
53
- const status = result.status ?? null;
54
- const signal = result.signal ?? null;
55
- const output = input.output ?? result.stdout;
56
- const base = {
57
- status,
58
- signal,
59
- firstOutputLine: firstOutputLine(result.stderr) ||
60
- firstOutputLine(result.stdout) ||
61
- firstOutputLine(result.error?.message),
62
- // Evidence carried alongside the verdict, never part of deciding it — the
63
- // branches below are byte-for-byte the pre-#2100 rules.
64
- outputCapped: truncatedByOutputCap(result),
65
- };
66
- if (result.error || signal)
67
- return { kind: "did-not-run", ...base };
68
- if (status === null)
69
- return { kind: "did-not-run", ...base };
70
- if (reportMissing) {
71
- return status === 0
72
- ? { kind: "ran", ...base }
73
- : { kind: "report-missing", ...base };
74
- }
75
- if (status !== 0 && exitCodes && !exitCodes.ran.includes(status)) {
76
- return { kind: "rejected-invocation", ...base };
77
- }
78
- if (status !== 0 && !output?.trim()) {
79
- return { kind: "did-not-run", ...base };
80
- }
81
- return { kind: "ran", ...base };
82
- }
83
- /**
84
- * True when a tool both failed and produced nothing to parse — it never got as
85
- * far as linting the file. Callers map this to `skipped`, never `succeeded`.
86
- *
87
- * Kept as its own export because callers outside the dispatch runners use it
88
- * (`dead-code-client.ts`, `knip-client.ts`). It now DELEGATES to
89
- * `classifyRunOutcome` rather than restating the rule, but keeps its exact
90
- * historical semantics: the `!output.trim()` conjunct stays here so a spawn
91
- * error that still produced partial output keeps reaching the parser, which is
92
- * what today's callers depend on. `classifyRunOutcome` is the stricter,
93
- * outcome-typed reading; migrate callers to it deliberately, not by accident.
94
- *
95
- * `output` defaults to stdout. Runners that parse stderr too pass the exact
96
- * string they are about to hand the parser, so "nothing to parse" means both
97
- * streams rather than just one.
98
- */
99
- export function spawnFailedWithNoOutput(result, output = result.stdout) {
100
- return (classifyRunOutcome({ result, output }).kind !== "ran" && !output?.trim());
101
- }
@@ -1,235 +0,0 @@
1
- /**
2
- * One wording for a tool that produced no usable result, and the runner gate
3
- * that emits it to the degradation ledger (#1816).
4
- */
5
- import { incrementDegradationCount } from "../../../degradation-ledger.js";
6
- import { truncateForLedger } from "../../../ledger-bounds.js";
7
- import { classifyRunOutcome, firstOutputLine, } from "./spawn-outcome.js";
8
- /**
9
- * What ended this run, as one clause, most specific cause first.
10
- *
11
- * A signal is a stronger explanation than the exit status, so it displaces a
12
- * `null` one rather than sitting beside it. Our own output cap is stronger
13
- * still: the signal it killed with is a detail of OUR decision, and naming that
14
- * signal alone reads as the tool misbehaving (#2100).
15
- */
16
- function describeEnding(input) {
17
- if (input.outputCapped)
18
- return "was stopped at its output cap";
19
- if (input.signal)
20
- return `was killed by ${input.signal}`;
21
- if (input.status === null)
22
- return "did not run (spawn failure)";
23
- return `exited ${input.status}`;
24
- }
25
- /**
26
- * One wording for "this tool did not produce a usable result" (#1816).
27
- *
28
- * Before this, five reason builders spelled the same sentence five ways and
29
- * twelve sites truncated with their own literal, and NONE of them named the
30
- * signal — so a SIGKILLed tool read exactly like a clean exit 0. The wording
31
- * here is fixed, the truncation is the ledger's own `LEDGER_FIELD_MAX` policy
32
- * applied once at the end, and the signal is always named when present.
33
- *
34
- * Shape: `tool (k=v, k=v) <what happened> with <what was missing>: <detail>`
35
- */
36
- export function formatToolFailure(input) {
37
- const entries = Object.entries(input.fields ?? {}).filter(([, value]) => value !== undefined && value !== "");
38
- const identity = entries.length
39
- ? `${input.tool} (${entries.map(([key, value]) => `${key}=${value}`).join(", ")})`
40
- : input.tool;
41
- const what = describeEnding(input);
42
- const missing = input.reportMissing ? "no report file" : "no output";
43
- const detail = firstOutputLine(input.stderr) ||
44
- firstOutputLine(input.stdout) ||
45
- "no stderr";
46
- return truncateForLedger(`${identity} ${what} with ${missing}: ${detail}`);
47
- }
48
- /**
49
- * `formatToolFailure` fed straight from a `classifyRunOutcome` verdict — the
50
- * path every migrated runner takes, so the outcome and the wording can never
51
- * disagree about the status or the signal.
52
- */
53
- export function formatRunOutcomeFailure(tool, outcome, fields) {
54
- return formatToolFailure({
55
- tool,
56
- status: outcome.status,
57
- signal: outcome.signal,
58
- outputCapped: outcome.outputCapped,
59
- stderr: outcome.firstOutputLine,
60
- reportMissing: outcome.kind === "report-missing",
61
- fields: { outcome: outcome.kind, ...fields },
62
- });
63
- }
64
- /**
65
- * The migrated runners' one call: classify the spawn, and when the tool did
66
- * NOT run, record a bounded `runner-empty-result` row and hand back the
67
- * `skipped` verdict. Returns `null` when the tool ran, meaning "carry on and
68
- * parse".
69
- *
70
- * `incrementDegradationCount` keeps the record bounded — one latest-reason
71
- * entry per (kind, subject) with an exact event tally — so a permanently
72
- * broken tool costs one ledger row, not one per dispatched file. `subject` is
73
- * the tool id, which is the discriminating identity a reader needs: WHICH tool
74
- * is silently contributing nothing.
75
- */
76
- export function skipUnlessToolRan(tool, input, fields) {
77
- const outcome = classifyRunOutcome(input);
78
- if (outcome.kind === "ran")
79
- return null;
80
- incrementDegradationCount({
81
- kind: "runner-empty-result",
82
- subject: tool,
83
- reason: formatRunOutcomeFailure(tool, outcome, fields),
84
- });
85
- return { status: "skipped", diagnostics: [], semantic: "none" };
86
- }
87
- /**
88
- * The record a runner leaves when its parser read NOTHING out of output the
89
- * tool did produce (#1948).
90
- *
91
- * `skipUnlessToolRan` covers the adjacent case: the tool produced no output at
92
- * all. The hole it leaves is the one that hid five parser bugs for months —
93
- * vale (#1933), taplo, stylelint, phpstan (#1946), sqlfluff. Each received a
94
- * real report, extracted zero diagnostics from it, and reported "succeeded, 0
95
- * diagnostics", which is byte-for-byte what a genuinely clean file records.
96
- * A reader could not answer "is this file clean, or did the parser fail?".
97
- *
98
- * THE RULE: record only when the exit status is NONZERO, the output handed to
99
- * the parser is non-empty, and the parse yielded zero diagnostics. A nonzero
100
- * exit is the tool asserting something is wrong; extracting nothing from that
101
- * assertion means our reader disagrees with the tool, and one of the two is
102
- * broken.
103
- *
104
- * Exit 0 with zero parsed is deliberately NOT recorded, even with non-empty
105
- * output: that is the overwhelmingly common clean save. Linters print summary
106
- * banners, empty JSON arrays, and progress noise on a clean run, so a row per
107
- * clean save would drown the ledger and bury the real signal.
108
- *
109
- * FALSE NEGATIVES this rule accepts, stated plainly:
110
- * - A tool that reports findings under exit 0. `swiftlint` is the live
111
- * example among the adopters: a warning-only run exits 0 and still writes
112
- * a full JSON array, so a swiftlint parser break that never trips a
113
- * nonzero exit stays invisible here. (`vale` also exits 0 on findings by
114
- * default, but its actual #1933 break exited 1, so it is not the example.)
115
- * This gap is deliberate and is NOT closed by adding an output-length
116
- * threshold for exit 0. That class belongs to the captured-fixture lane —
117
- * `tests/clients/dispatch/runners/captured-real-output.test.ts` pins each
118
- * parser against real recorded binary output, which catches a broken
119
- * parser directly instead of guessing from output size. A length
120
- * threshold here would fire on every clean run of every tool that prints
121
- * a summary banner.
122
- * - A tool whose parser breaks only for a SUBSET of findings still reports
123
- * the ones it can read, so `parsedCount` is nonzero and nothing records.
124
- *
125
- * FALSE POSITIVES it accepts: a runner that legitimately parses zero
126
- * diagnostics out of a failing run — `go-vet` exits nonzero for a SIBLING
127
- * file's problem and then filters to the edited file, and `terragrunt` does
128
- * the same across a unit directory. Such runners stay off this helper rather
129
- * than being special-cased inside it; see the runner-family registries in
130
- * `tests/clients/dispatch/runners/parsed-nothing-sweep.test.ts`.
131
- *
132
- * Bounded by `incrementDegradationCount`: one latest-reason entry per
133
- * (kind, subject) with an exact tally, so a permanently broken parser costs
134
- * ONE ledger row and not one per dispatched file. `subject` is the tool id
135
- * because a parser break is a property of the tool and our reader of it, not
136
- * of the project it ran in; aggregating on the tool keeps exactly the identity
137
- * a reader needs ("which tool is stuck") while staying bounded across every
138
- * workspace in the session.
139
- *
140
- * @returns true when a row was recorded.
141
- */
142
- export function recordParsedNothing(input) {
143
- const { tool, status, output, parsedCount } = input;
144
- // Three conjuncts, one per clause of the rule above. Each is separately
145
- // load-bearing and separately tested: `parsedCount` keeps a run that DID
146
- // yield findings silent, `status` keeps the clean-save case silent (0 and a
147
- // never-arrived null alike — neither is a tool asserting a problem), and
148
- // `output` keeps "the tool said nothing at all" with `runner-empty-result`
149
- // rather than double-recording it here.
150
- if (parsedCount > 0)
151
- return false;
152
- if (!status)
153
- return false;
154
- const text = output ?? "";
155
- if (!text.trim())
156
- return false;
157
- const entries = Object.entries(input.fields ?? {}).filter(([, value]) => value !== undefined && value !== "");
158
- const identity = entries.length
159
- ? `${tool} (${entries.map(([key, value]) => `${key}=${value}`).join(", ")})`
160
- : tool;
161
- incrementDegradationCount({
162
- kind: "runner-parsed-nothing",
163
- subject: tool,
164
- reason: truncateForLedger(`${identity} exited ${status} with ${text.length} chars of output but the parser read 0 diagnostics: ${firstOutputLine(text) || "no first line"}`),
165
- });
166
- return true;
167
- }
168
- /**
169
- * The one seam a runner uses to go from a spawn result to diagnostics (#1948).
170
- *
171
- * It composes the two gates that must BOTH hold before a runner may claim a
172
- * clean file: `skipUnlessToolRan` (the tool produced nothing — #1816) and
173
- * `recordParsedNothing` (the tool produced something the parser could not
174
- * read). Runners call this instead of calling `skipUnlessToolRan` and then
175
- * parsing on their own, so the second gate cannot be forgotten by whoever
176
- * writes runner 53. `tests/clients/dispatch/runners/parsed-nothing-sweep.test.ts`
177
- * enforces that.
178
- */
179
- export function parseToolRun(tool, input, parse, options = {}) {
180
- const skipped = skipUnlessToolRan(tool, input, options.fields);
181
- if (skipped)
182
- return { skipped, diagnostics: [], parsedNothing: false };
183
- const output = options.parseOutput ?? input.output ?? input.result.stdout ?? "";
184
- const diagnostics = [...parse(output)];
185
- const parsedNothing = recordParsedNothing({
186
- tool,
187
- status: input.result.status ?? null,
188
- output,
189
- parsedCount: diagnostics.length,
190
- fields: options.fields,
191
- });
192
- if (parsedNothing && options.skipWhenParsedNothing) {
193
- return {
194
- skipped: { status: "skipped", diagnostics: [], semantic: "none" },
195
- diagnostics: [],
196
- parsedNothing,
197
- };
198
- }
199
- return { skipped: null, diagnostics, parsedNothing };
200
- }
201
- export function finishParsedRun(input) {
202
- const raw = `${input.result.stdout ?? ""}${input.result.stderr ?? ""}`;
203
- const status = input.result.status ?? null;
204
- if (input.diagnostics.length === 0) {
205
- if (status !== 0 && raw.trim().length > 0) {
206
- return {
207
- status: "failed",
208
- diagnostics: [
209
- {
210
- id: `${input.tool}:parse-error:1`,
211
- message: `${input.tool} exited ${status} but its output could not be parsed`,
212
- filePath: input.ctx.filePath,
213
- line: 1,
214
- column: 1,
215
- severity: "warning",
216
- semantic: "warning",
217
- tool: input.tool,
218
- },
219
- ],
220
- semantic: "warning",
221
- };
222
- }
223
- return { status: "succeeded", diagnostics: [], semantic: "none" };
224
- }
225
- const mapped = input.classify?.(input.diagnostics);
226
- if (mapped) {
227
- return { ...mapped, diagnostics: input.diagnostics };
228
- }
229
- const hasBlocking = input.diagnostics.some((d) => d.semantic === "blocking");
230
- return {
231
- status: hasBlocking ? "failed" : "succeeded",
232
- diagnostics: input.diagnostics,
233
- semantic: hasBlocking ? "blocking" : "warning",
234
- };
235
- }
@@ -1,169 +0,0 @@
1
- /**
2
- * Shared toolchain-availability lifecycle (#1476 Sonar follow-up).
3
- *
4
- * `candidate-probe.ts` factored out the PATH sweep the Go and Rust clients ran,
5
- * but the LIFECYCLE around it stayed written twice: the transient-aware latch,
6
- * the in-flight dedupe that keeps concurrent first-time callers to one sweep,
7
- * the path memo, and the two `availability_decision` records. Two copies of one
8
- * rule is how #1467's fix missed seven sites, so the rule lives here once and
9
- * each client contributes only its configuration.
10
- *
11
- * Callers keep their own public method names — `isGoAvailableAsync`,
12
- * `findCargoPathAsync` — because other modules call them; only the body moves.
13
- */
14
- import { createAvailabilityLatch, logAvailabilityDecision, } from "./availability-policy.js";
15
- import { probeAvailabilityCandidates } from "./candidate-probe.js";
16
- import { createAvailabilityProbeFlight } from "../../../availability-probe-flight.js";
17
- import { createGenerationSource } from "../../../generation-guard.js";
18
- import { createSingleFlight } from "../../../single-flight.js";
19
- /**
20
- * Session generation for toolchain-availability resets (#2455 fix round 3, F2).
21
- *
22
- * `reset()` clears the memo and the latch, but a probe that was ALREADY in
23
- * flight when it ran knows nothing about that. Without a generation, a
24
- * post-reset caller joins the pre-reset flight and, worse, that flight's own
25
- * settlement writes its stale verdict back into the freshly cleared latch — so
26
- * a tool installed between sessions still read "missing" for the whole new
27
- * session. That is #1674's defect read from both the sharing side and the
28
- * settle side, and the reason `SingleFlightOptions.generation` exists.
29
- *
30
- * This is the repo's extracted primitive (`clients/generation-guard.ts`, #1754)
31
- * rather than a hand-rolled counter (#2455 fix round 4, F1). Two things come
32
- * with it that the hand-rolled form did not have: the source is declared by
33
- * construction, so the #1754 ratchet can see it; and `guardedWrite` puts every
34
- * superseded write in the degradation ledger as a bounded
35
- * `generation-guard-stale-write` record per (source, subject), so a dogfood
36
- * session can tell "the guard is working" from "the guard never fires" instead
37
- * of watching superseded writes vanish silently (F4).
38
- *
39
- * A module-level source rather than a per-instance one, deliberately. It is a
40
- * counter, so nothing has to be hand-maintained and no flight is retained for
41
- * the sake of superseding it. And `toolchainProbeFlights` is itself shared
42
- * ACROSS instances (#2131: two clients probing the same candidate list run one
43
- * sweep), so its supersede signal cannot live on any one instance. The cost is
44
- * that resetting one toolchain also supersedes another's in-flight sweep; that
45
- * is at worst one extra probe, never a wrong verdict, and every registered
46
- * reset fires in the same `session_start` block anyway.
47
- */
48
- const toolchainGenerations = createGenerationSource("toolchain-availability");
49
- const toolchainProbeFlights = createAvailabilityProbeFlight({ generation: toolchainGenerations.current });
50
- /**
51
- * Own one toolchain's availability: sweep the platform candidate list, memoize
52
- * the path that answered, and park the verdict behind the shared latch so a
53
- * timed-out probe expires instead of latching "the toolchain is not installed"
54
- * for the life of the process.
55
- */
56
- export function createToolchainAvailability(config) {
57
- const availabilityLatch = createAvailabilityLatch();
58
- let toolPath = null;
59
- /** Classification of the candidate sweep, for the retry decision. */
60
- let sweepSawTransient = false;
61
- let sweepTransientCause = "probe-timeout";
62
- let sweepHostStallMs = 0;
63
- /** What the last classified candidate returned, for the decision record. */
64
- let sweepEvidence;
65
- const ensureFlight = createSingleFlight({
66
- generation: toolchainGenerations.current,
67
- });
68
- async function findPath() {
69
- if (toolPath)
70
- return toolPath;
71
- const paths = process.platform === "win32" ? config.windowsPaths : config.unixPaths;
72
- const handle = toolchainGenerations.capture();
73
- const shared = toolchainProbeFlights.run(`toolchain:${config.tool}|${config.probeArgs.join("|")}|${config.windowsPaths.join("|")}|${config.unixPaths.join("|")}`, () => probeAvailabilityCandidates(paths, config.probeArgs, config.budgetMs));
74
- const sweep = await shared.promise;
75
- // A reset may have landed while this sweep was running. Its answer then
76
- // describes the session that just ended, so it must not write itself back
77
- // into the memo `reset()` just cleared, nor into the classification fields
78
- // the replacement flight reads to build ITS verdict. The memo is the
79
- // sharper half: a superseded sweep that writes `foundPath` latches a path
80
- // the reset may have been called BECAUSE it went away, so the seam that
81
- // exists to un-latch a false "missing" would instead latch a false
82
- // "found". Callers already holding this promise still get what the sweep
83
- // actually found.
84
- handle.guardedWrite(`findPath:${config.tool}`, () => {
85
- sweepSawTransient = sweep.sawTransient;
86
- sweepTransientCause = sweep.transientCause;
87
- sweepHostStallMs = sweep.hostStallMs;
88
- sweepEvidence = sweep.evidence;
89
- if (sweep.foundPath)
90
- toolPath = sweep.foundPath;
91
- });
92
- return sweep.foundPath;
93
- }
94
- async function resolveAvailability() {
95
- const startedAt = Date.now();
96
- const handle = toolchainGenerations.capture();
97
- const resolvedPath = await findPath();
98
- const found = resolvedPath !== null;
99
- // #2455 fix round 3, F2: a reset during the probe opened a NEW session.
100
- // This flight answers the OLD one, so writing its verdict into the
101
- // freshly cleared latch would re-latch a stale "missing" for the whole
102
- // new session — the bug the reset exists to prevent, reintroduced by the
103
- // reset's own timing. Report the verdict to this flight's own callers;
104
- // do not latch it, and say so in the decision record's `latched`.
105
- const superseded = !handle.isCurrent();
106
- if (found) {
107
- handle.guardedWrite(`latch:${config.tool}`, () => availabilityLatch.noteAvailable());
108
- // The RESOLVED path, not the memo (#2455 fix round 4, F6). A superseded
109
- // sweep is forbidden from writing `toolPath`, so reading the memo here
110
- // logged `Go found: null` on exactly the branch this line exists to
111
- // explain.
112
- config.log(`${config.label} found: ${resolvedPath}`);
113
- logAvailabilityDecision({
114
- tool: config.tool,
115
- verdict: "available",
116
- outcome: "success",
117
- cause: "ok",
118
- elapsedMs: Date.now() - startedAt,
119
- latched: !superseded,
120
- hostStallMs: sweepHostStallMs,
121
- budgetMs: config.budgetMs,
122
- classifiedBy: "probe",
123
- ...(sweepEvidence !== undefined && { evidence: sweepEvidence }),
124
- });
125
- return true;
126
- }
127
- // A timed-out version probe is evidence about this moment, not about
128
- // whether the toolchain is installed; it expires instead of latching.
129
- const outcome = sweepSawTransient ? "transient" : "missing";
130
- const cause = sweepSawTransient ? sweepTransientCause : "not-found";
131
- const retryAfterMs = handle.guardedWrite(`latch:${config.tool}`, () => availabilityLatch.noteUnavailable(outcome, cause)) ?? 0;
132
- logAvailabilityDecision({
133
- tool: config.tool,
134
- verdict: "unavailable",
135
- outcome,
136
- cause,
137
- elapsedMs: Date.now() - startedAt,
138
- latched: !superseded && outcome !== "transient",
139
- hostStallMs: sweepHostStallMs,
140
- ...(retryAfterMs > 0 && { retryAfterMs }),
141
- budgetMs: config.budgetMs,
142
- // Derived from the sweep's own candidate probes, and carrying what the
143
- // last of them returned (#1500).
144
- classifiedBy: "probe",
145
- ...(sweepEvidence !== undefined && { evidence: sweepEvidence }),
146
- });
147
- return false;
148
- }
149
- async function isAvailable() {
150
- // `read()` returns null when the last verdict was transient and its
151
- // cooldown expired, which re-enters the candidate sweep (#1476).
152
- const memo = availabilityLatch.read();
153
- if (memo !== null)
154
- return memo;
155
- return ensureFlight.run("availability", resolveAvailability);
156
- }
157
- function reset() {
158
- toolPath = null;
159
- availabilityLatch.reset();
160
- // Supersede every sweep and availability flight already running, in this
161
- // instance and in the shared registry. No `clear()`: the generation bump
162
- // is what makes a stale flight unjoinable and unable to re-latch, and
163
- // `SingleFlight.release`'s identity check already stops it from evicting
164
- // its successor. Clearing the SHARED registry here would additionally
165
- // drop another toolchain's live claim and cost it a duplicate sweep.
166
- toolchainGenerations.bump();
167
- }
168
- return { findPath, isAvailable, reset };
169
- }
@@ -1,15 +0,0 @@
1
- /**
2
- * Shared utilities for runners
3
- */
4
- import * as fs from "node:fs";
5
- /**
6
- * Read file content, returning undefined if it can't be read
7
- */
8
- export function readFileContent(filePath) {
9
- try {
10
- return fs.readFileSync(filePath, "utf-8");
11
- }
12
- catch {
13
- return undefined;
14
- }
15
- }
@@ -1,128 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import { pathsEqual } from "../../path-utils.js";
4
- import { safeSpawnAsync } from "../../safe-spawn.js";
5
- import { resolveRunnerCwd } from "../../tool-cwd.js";
6
- import { PRIORITY } from "../priorities.js";
7
- import { createAvailabilityChecker, resolveToolCommandWithInstallFallback, } from "./utils/runner-helpers.js";
8
- import { parseToolRun } from "./utils/tool-failure.js";
9
- const vale = createAvailabilityChecker("vale", ".exe");
10
- /**
11
- * Check for a .vale.ini config file in cwd or parent dirs.
12
- */
13
- function findValeConfig(cwd) {
14
- const local = path.join(cwd, ".vale.ini");
15
- if (fs.existsSync(local))
16
- return local;
17
- let current = path.resolve(cwd);
18
- while (true) {
19
- const candidate = path.join(current, ".vale.ini");
20
- if (fs.existsSync(candidate))
21
- return candidate;
22
- const parent = path.dirname(current);
23
- if (parent === current)
24
- break;
25
- current = parent;
26
- }
27
- return undefined;
28
- }
29
- export function parseValeOutput(raw, filePath, cwd) {
30
- const diagnostics = [];
31
- if (!raw.trim())
32
- return diagnostics;
33
- const absTarget = path.resolve(cwd, filePath);
34
- try {
35
- const parsed = JSON.parse(raw);
36
- if (!parsed || typeof parsed !== "object")
37
- return diagnostics;
38
- // #3295: vale's top level is keyed BY the linted file's path — the only
39
- // place the reported path appears. `Object.values` dropped it, so a
40
- // `.vale.ini` glob or a directory argv charged a second file's alerts to
41
- // the dispatched one.
42
- for (const [reported, alerts] of Object.entries(parsed)) {
43
- if (!Array.isArray(alerts))
44
- continue;
45
- if (reported && !pathsEqual(path.resolve(cwd, reported), absTarget))
46
- continue;
47
- for (const alert of alerts) {
48
- if (!alert.Message)
49
- continue;
50
- const severityMap = {
51
- error: "error",
52
- warning: "warning",
53
- info: "info",
54
- suggestion: "info",
55
- };
56
- const severity = severityMap[alert.Severity?.toLowerCase() ?? ""] ?? "warning";
57
- diagnostics.push({
58
- id: `vale-${alert.Line}-${alert.Check ?? "unknown"}`,
59
- message: `[${alert.Check ?? "vale"}] ${alert.Message}`,
60
- filePath,
61
- line: alert.Line ?? 1,
62
- column: alert.Span?.[0] ?? 1,
63
- severity,
64
- semantic: severity === "error" ? "blocking" : "warning",
65
- tool: "vale",
66
- rule: alert.Check ?? "vale",
67
- fixable: false,
68
- });
69
- }
70
- }
71
- }
72
- catch {
73
- // JSON parse failed, return empty
74
- return diagnostics;
75
- }
76
- return diagnostics;
77
- }
78
- const valeRunner = {
79
- id: "vale",
80
- appliesTo: ["markdown"],
81
- priority: PRIORITY.DOC_QUALITY,
82
- skipTestFiles: false,
83
- async run(ctx) {
84
- const cwd = resolveRunnerCwd(ctx, "vale");
85
- // Config-gated: skip unless a .vale.ini is found
86
- if (!findValeConfig(cwd)) {
87
- return { status: "skipped", diagnostics: [], semantic: "none" };
88
- }
89
- let cmd = null;
90
- if (await vale.isAvailableAsync(cwd)) {
91
- cmd = vale.getCommand(cwd);
92
- }
93
- else {
94
- cmd = await resolveToolCommandWithInstallFallback(cwd, "vale");
95
- }
96
- if (!cmd)
97
- return { status: "skipped", diagnostics: [], semantic: "none" };
98
- // Vale exits 0 even on findings, non-zero only on errors
99
- const result = await safeSpawnAsync(cmd, ["--output", "JSON", ctx.filePath], { cwd, timeout: 15000 });
100
- // #1816: this runner read `result.status` zero times, so a Vale that
101
- // rejected its config exited nonzero with an empty stdout, parsed to
102
- // zero alerts, and reported clean prose. No exit-code table: Vale's
103
- // nonzero codes vary with --minAlertLevel, so the conservative
104
- // nothing-to-parse rule is the only safe discriminator here.
105
- //
106
- // #1948: `parseToolRun` adds the second gate. Vale's `Data.Files`
107
- // envelope bug produced exactly this shape — exit 1, a full JSON
108
- // report on stdout, zero alerts parsed — and left no record.
109
- const run = parseToolRun("vale", {
110
- result,
111
- // EXIT TABLE (Vale 3.9.6 docs https://vale.sh/docs/topics/metrics/): 0 clean; 1 findings; 2 error; other nonzero rejected.
112
- exitCodes: { ran: [1, 2] },
113
- }, (raw) => parseValeOutput(raw, ctx.filePath, cwd));
114
- if (run.skipped)
115
- return run.skipped;
116
- const diagnostics = run.diagnostics;
117
- if (diagnostics.length === 0) {
118
- return { status: "succeeded", diagnostics: [], semantic: "none" };
119
- }
120
- const hasBlocking = diagnostics.some((d) => d.semantic === "blocking");
121
- return {
122
- status: hasBlocking ? "failed" : "succeeded",
123
- diagnostics,
124
- semantic: hasBlocking ? "blocking" : "warning",
125
- };
126
- },
127
- };
128
- export default valeRunner;