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,607 +0,0 @@
1
- /**
2
- * Node.js package-manager resolution and command building.
3
- *
4
- * Single source of truth for "which package manager should we use here, and how
5
- * do we spell each command (run script / install / exec / global bin) for it".
6
- * Supports npm, pnpm, yarn and bun so pi-lens works on whatever manager the
7
- * machine actually ships.
8
- *
9
- * Resolution order (see `resolveNodePackageManager`):
10
- * 1. What the project declares — lockfile, then the corepack `packageManager`
11
- * field — *if that manager is actually installed*.
12
- * 2. Otherwise the first installed manager in `PREFERENCE` (npm first for
13
- * maximum compatibility, bun last).
14
- * 3. `npm` as a final fallback so callers always get a usable value.
15
- */
16
- import * as fs from "node:fs";
17
- import * as os from "node:os";
18
- import * as path from "node:path";
19
- import { classifyProbeFailure, createAvailabilityLatch, isTransientDecision, logAvailabilityDecision, startHostStallSampler, } from "./dispatch/runners/utils/availability-policy.js";
20
- import { safeSpawnAsync } from "./safe-spawn.js";
21
- import { probeToolAsync } from "./tool-probe.js";
22
- import { createAvailabilityProbeFlight } from "./availability-probe-flight.js";
23
- import { createGenerationSource, } from "./generation-guard.js";
24
- import { isAtOrAboveHomeDir, walkUpDirs } from "./path-utils.js";
25
- /**
26
- * Fallback preference when nothing is declared (or the declared manager is
27
- * missing). npm first for maximum compatibility; bun last. A project lockfile
28
- * always overrides this order.
29
- */
30
- const PREFERENCE = [
31
- "npm",
32
- "pnpm",
33
- "yarn",
34
- "bun",
35
- ];
36
- const packageManagerProbeFlights = createAvailabilityProbeFlight();
37
- function onWindows() {
38
- return process.platform === "win32";
39
- }
40
- function isNodePackageManager(value) {
41
- return (value === "npm" || value === "pnpm" || value === "yarn" || value === "bun");
42
- }
43
- // ============================================================================
44
- // DETECTION
45
- // ============================================================================
46
- /**
47
- * Detect the package manager a Node.js project declares, without checking
48
- * whether it is installed. Lockfiles win over the corepack `packageManager`
49
- * field. Returns `undefined` when the project makes no declaration.
50
- */
51
- export function detectNodePackageManager(targetPath) {
52
- if (fs.existsSync(path.join(targetPath, "bun.lockb")) ||
53
- fs.existsSync(path.join(targetPath, "bun.lock"))) {
54
- return "bun";
55
- }
56
- if (fs.existsSync(path.join(targetPath, "pnpm-lock.yaml"))) {
57
- return "pnpm";
58
- }
59
- if (fs.existsSync(path.join(targetPath, "yarn.lock"))) {
60
- return "yarn";
61
- }
62
- if (fs.existsSync(path.join(targetPath, "package-lock.json"))) {
63
- return "npm";
64
- }
65
- return readPackageManagerField(targetPath);
66
- }
67
- /** Read the corepack `"packageManager": "pnpm@8.15.0"` field from package.json. */
68
- function readPackageManagerField(targetPath) {
69
- try {
70
- const pkgPath = path.join(targetPath, "package.json");
71
- if (!fs.existsSync(pkgPath))
72
- return undefined;
73
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
74
- if (typeof pkg.packageManager !== "string")
75
- return undefined;
76
- const name = pkg.packageManager.split("@")[0].trim().toLowerCase();
77
- return isNodePackageManager(name) ? name : undefined;
78
- }
79
- catch {
80
- return undefined;
81
- }
82
- }
83
- // ============================================================================
84
- // AVAILABILITY (cached per process; reset in tests)
85
- // ============================================================================
86
- /**
87
- * Budget for the `where`/`which <pm>` probe. Matches the previous
88
- * `isCommandAvailableAsync` default so the observable timing is unchanged.
89
- */
90
- const PROBE_TIMEOUT_MS = 5_000;
91
- /**
92
- * A timed-out probe used to be memoized as a permanent `false` — the process
93
- * would silently downgrade a declared pnpm/yarn manager to npm for its whole
94
- * life. The blast radius was internal: this resolver only serves installs
95
- * into pi-lens's own managed tools directory and `pilens_rebuild` on a
96
- * pi-lens source checkout, never a user project's lockfile (#1496). Each
97
- * manager now sits behind the shared transient-aware latch (#1467/#1476):
98
- * only a genuine absence (`where`/`which` exits non-zero, or ENOENT) latches;
99
- * a timeout, abort or host stall expires on a cooldown and is re-probed.
100
- */
101
- const availabilityLatches = new Map();
102
- function getLatch(pm) {
103
- let latch = availabilityLatches.get(pm);
104
- if (!latch) {
105
- latch = createAvailabilityLatch();
106
- availabilityLatches.set(pm, latch);
107
- }
108
- return latch;
109
- }
110
- async function probeAvailability(pm) {
111
- const latch = getLatch(pm);
112
- const startedAt = Date.now();
113
- const finder = onWindows() ? "where" : "which";
114
- const sampler = startHostStallSampler();
115
- let result;
116
- let hostStallMs;
117
- try {
118
- result = await probeToolAsync(finder, [pm], { timeout: PROBE_TIMEOUT_MS });
119
- }
120
- finally {
121
- hostStallMs = sampler.stop();
122
- }
123
- const elapsedMs = Date.now() - startedAt;
124
- if (result.status === 0 && !result.error) {
125
- latch.noteAvailable();
126
- logAvailabilityDecision({
127
- tool: pm,
128
- verdict: "available",
129
- outcome: "success",
130
- cause: "ok",
131
- elapsedMs,
132
- latched: true,
133
- hostStallMs,
134
- budgetMs: PROBE_TIMEOUT_MS,
135
- classifiedBy: "probe",
136
- });
137
- return true;
138
- }
139
- const { outcome, cause, evidence } = classifyProbeFailure(result, {
140
- hostStallMs,
141
- // Preserve pre-#1496 meaning for anything the classifier can't place: a
142
- // present manager that rejects its probe is durable, same as before.
143
- unclassifiedFailureOutcome: "missing",
144
- });
145
- const retryAfterMs = latch.noteUnavailable(outcome, cause);
146
- logAvailabilityDecision({
147
- tool: pm,
148
- verdict: "unavailable",
149
- outcome,
150
- cause,
151
- elapsedMs,
152
- latched: outcome !== "transient",
153
- hostStallMs,
154
- ...(retryAfterMs > 0 && { retryAfterMs }),
155
- budgetMs: PROBE_TIMEOUT_MS,
156
- classifiedBy: "probe",
157
- evidence,
158
- });
159
- return false;
160
- }
161
- /**
162
- * Resolve whether `pm` is available. `onTransient`, when given, fires
163
- * whenever the resolved `false` came from a probe that never got a fair
164
- * hearing (a stall, an abort, a host-level failure classified `transient` by
165
- * `classifyProbeFailure`) rather than a genuine absence — including when that
166
- * verdict is served from the latch's own cooldown-bounded memo, not just on a
167
- * fresh probe (#1585).
168
- *
169
- * Before this, the return type was a bare boolean: a caller like
170
- * `allAvailableGlobalBinDirs` could not tell "pnpm isn't installed" from
171
- * "the `where pnpm` probe stalled", so a transient miss silently dropped
172
- * pnpm's global bin dir with no way to flag the result as provisional —
173
- * exactly the boolean-collapse `getToolPath`'s `onTransient` plumbing (#1569)
174
- * was built to avoid, one layer up.
175
- */
176
- function isAvailable(pm, onTransient) {
177
- const latch = getLatch(pm);
178
- const reportIfTransient = (result) => {
179
- if (!result && isTransientDecision({ outcome: latch.getOutcome() })) {
180
- onTransient?.();
181
- }
182
- return result;
183
- };
184
- const memo = latch.read();
185
- if (memo !== null)
186
- return Promise.resolve(reportIfTransient(memo));
187
- // A verdict can now expire, so concurrent callers arriving just after a
188
- // cooldown must share ONE probe rather than each spawning their own.
189
- const shared = packageManagerProbeFlights.run(`package-manager:${pm}`, () => probeAvailability(pm));
190
- return shared.promise.then(reportIfTransient);
191
- }
192
- /**
193
- * Clear the process-wide availability cache: pnpm/yarn/bun/npm each sit
194
- * behind their own module-local `AvailabilityLatch` in `availabilityLatches`,
195
- * so `resetDispatchAvailabilityState`'s generation counter (the mechanism
196
- * most dispatch runners inherit) never reaches them — the same shape as
197
- * psscriptanalyzer's (#1490) and zizmor's (#1535) module-local latches.
198
- * Without this wired into `session_start`, a genuine "pnpm is missing"
199
- * verdict from one session stayed latched into the next: install pnpm mid
200
- * day, start a fresh session, pi-lens still reports it missing until a
201
- * process restart (#1653). Called from `handleSessionStart`'s per-session
202
- * reset block beside `resetZizmorTokenAvailability()` /
203
- * `resetPsScriptAnalyzerAvailability()`; also used directly by tests. Also
204
- * clears `globalBinDirCache`, whose memo lifetime rides the same reset — it
205
- * must not outlive the availability verdicts it was derived from (#1602).
206
- */
207
- export function _resetPackageManagerCache() {
208
- packageManagerCacheGeneration.bump();
209
- availabilityLatches.clear();
210
- packageManagerProbeFlights.clear();
211
- globalBinDirCache.clear();
212
- globalBinDirProbeFlights.clear();
213
- }
214
- // ============================================================================
215
- // RESOLUTION
216
- // ============================================================================
217
- /**
218
- * Resolve which package manager to use for `cwd`: the project's declared manager
219
- * if installed, otherwise the first installed manager in `PREFERENCE`, otherwise
220
- * `npm`.
221
- */
222
- export async function resolveNodePackageManager(cwd = process.cwd()) {
223
- const declared = detectNodePackageManager(cwd);
224
- if (declared && (await isAvailable(declared))) {
225
- return declared;
226
- }
227
- for (const pm of PREFERENCE) {
228
- if (await isAvailable(pm))
229
- return pm;
230
- }
231
- return "npm";
232
- }
233
- // ============================================================================
234
- // COMMAND BUILDERS
235
- // ============================================================================
236
- /** Platform-specific executable name (`.cmd`/`.exe` on Windows). */
237
- export function pmBinary(pm) {
238
- if (!onWindows())
239
- return pm;
240
- return pm === "bun" ? "bun.exe" : `${pm}.cmd`;
241
- }
242
- /** Args to run a package.json script — `run <script>` works for all managers. */
243
- export function runScriptArgs(script) {
244
- return ["run", script];
245
- }
246
- /** Human-readable "run script" command for display (bare manager name). */
247
- export function formatRunScript(pm, script) {
248
- return `${pm} run ${script}`;
249
- }
250
- /**
251
- * Args to install a single package. npm uses `install`; pnpm/yarn/bun use `add`.
252
- * `--legacy-peer-deps` is npm-only and silently dropped for other managers.
253
- */
254
- export function installArgs(pm, pkg, options = {}) {
255
- const args = [pm === "npm" ? "install" : "add"];
256
- if (options.ignoreScripts)
257
- args.push("--ignore-scripts");
258
- if (options.legacyPeerDeps && pm === "npm")
259
- args.push("--legacy-peer-deps");
260
- args.push(pkg);
261
- return args;
262
- }
263
- /**
264
- * Args to re-resolve an already-declared dependency to the newest version its
265
- * recorded range still permits. npm/pnpm/bun spell this `update`; yarn classic
266
- * spells it `upgrade`.
267
- *
268
- * This is the command that repairs a dependency frozen by its own lockfile.
269
- * `installArgs` re-runs the install, and a lockfile entry that already
270
- * satisfies the range makes that a no-op: pi-lens's managed tools tree stayed
271
- * on the version written at first install for the life of the machine even
272
- * though the declared caret range permitted 28 newer minors (#1730).
273
- */
274
- export function updateArgs(pm, pkg, options = {}) {
275
- const args = [pm === "yarn" ? "upgrade" : "update"];
276
- if (options.ignoreScripts)
277
- args.push("--ignore-scripts");
278
- args.push(pkg);
279
- return args;
280
- }
281
- /**
282
- * Args to install a single package **globally** (`-g`). npm/pnpm/bun spell this
283
- * `install -g` / `add -g`; yarn uses `global add` (yarn classic — Berry removed
284
- * global installs, but pi-lens's manager resolution prefers npm/pnpm first, so
285
- * yarn is only chosen when it is the declared/only manager). The resulting
286
- * binary is found again by `allAvailableGlobalBinDirs`, which covers every
287
- * manager's global bin dir.
288
- */
289
- export function globalInstallArgs(pm, pkg) {
290
- switch (pm) {
291
- case "yarn":
292
- return ["global", "add", pkg];
293
- case "npm":
294
- return ["install", "-g", pkg];
295
- default: // pnpm, bun
296
- return ["add", "-g", pkg];
297
- }
298
- }
299
- /**
300
- * Command + args to run a package's binary without a global install — the
301
- * `npx --no <pkg>` equivalent for each manager (`bun x`, `pnpm dlx`, `yarn dlx`).
302
- */
303
- export function execArgs(pm, pkg, args = []) {
304
- switch (pm) {
305
- case "bun":
306
- return { command: pmBinary("bun"), args: ["x", pkg, ...args] };
307
- case "pnpm":
308
- return { command: pmBinary("pnpm"), args: ["dlx", pkg, ...args] };
309
- case "yarn":
310
- return { command: pmBinary("yarn"), args: ["dlx", pkg, ...args] };
311
- default:
312
- // --no prevents silently downloading an uncached package.
313
- return {
314
- command: onWindows() ? "npx.cmd" : "npx",
315
- args: ["--no", pkg, ...args],
316
- };
317
- }
318
- }
319
- // ============================================================================
320
- // GLOBAL BIN DISCOVERY
321
- // ============================================================================
322
- /**
323
- * Per-manager global bin dir, memoized for the process (cleared alongside
324
- * `availabilityLatches` in `_resetPackageManagerCache`). Only a SUCCESSFUL
325
- * lookup is cached: a spawn failure here is evidence about this call, not
326
- * about the manager (the manager already passed `isAvailable`'s own probe),
327
- * so it must not latch an empty result the way a genuine absence would. The
328
- * generation guard owns post-await cache publication, so a probe crossing
329
- * a session reset cannot repopulate the fresh memo. Reset clears the flight
330
- * map separately, so later callers cannot share the pre-reset probe.
331
- */
332
- const globalBinDirCache = new Map();
333
- const packageManagerCacheGeneration = createGenerationSource("package-manager-global-bin");
334
- const globalBinDirProbeFlights = createAvailabilityProbeFlight();
335
- /** Directories where a given manager installs global binaries. */
336
- async function globalBinDirsFor(pm) {
337
- const cached = globalBinDirCache.get(pm);
338
- if (cached)
339
- return cached;
340
- const generation = packageManagerCacheGeneration.capture();
341
- // Concurrent callers (dispatch runs several tools per edit) must share ONE
342
- // probe rather than each spawning their own `npm config get prefix` (#1602).
343
- const shared = globalBinDirProbeFlights.run(pm, () => probeGlobalBinDirs(pm, generation));
344
- return shared.promise;
345
- }
346
- async function probeGlobalBinDirs(pm, generation) {
347
- if (pm === "bun") {
348
- // bun has no per-call query cost — the global bin dir is deterministic.
349
- const base = process.env.BUN_INSTALL || path.join(os.homedir(), ".bun");
350
- const dirs = [path.join(base, "bin")];
351
- generation.guardedWrite(pm, () => {
352
- globalBinDirCache.set(pm, dirs);
353
- });
354
- return dirs;
355
- }
356
- const query = pm === "npm"
357
- ? ["config", "get", "prefix"]
358
- : pm === "pnpm"
359
- ? ["bin", "-g"]
360
- : ["global", "bin"]; // yarn
361
- const res = await safeSpawnAsync(pmBinary(pm), query, { timeout: 5000 });
362
- if (res.status !== 0 || res.error)
363
- return [];
364
- const out = res.stdout.trim();
365
- if (!out)
366
- return [];
367
- // npm reports a prefix; binaries live in `<prefix>/bin` on Unix, `<prefix>`
368
- // on Windows. pnpm/yarn already print the bin dir directly.
369
- const dirs = pm === "npm" ? [onWindows() ? out : path.join(out, "bin")] : [out];
370
- generation.guardedWrite(pm, () => {
371
- globalBinDirCache.set(pm, dirs);
372
- });
373
- return dirs;
374
- }
375
- /**
376
- * Global bin directories for every installed manager, deduped. Used to locate a
377
- * globally-installed tool binary when PATH is stale (e.g. right after an
378
- * `install -g`) or when the tool was installed via a non-npm manager.
379
- *
380
- * `onTransient`, when given, fires once per manager whose `isAvailable` probe
381
- * was transient (stalled/unspawnable, not a genuine absence) — the boolean
382
- * `allAvailableGlobalBinDirs` returns can't itself distinguish "not
383
- * installed" from "couldn't tell", so a caller that persists this result
384
- * needs the callback to know the answer may be incomplete (#1585).
385
- */
386
- export async function allAvailableGlobalBinDirs(onTransient) {
387
- const dirs = [];
388
- const seen = new Set();
389
- for (const pm of PREFERENCE) {
390
- if (!(await isAvailable(pm, onTransient)))
391
- continue;
392
- for (const dir of await globalBinDirsFor(pm)) {
393
- const normalized = path.resolve(dir);
394
- if (seen.has(normalized))
395
- continue;
396
- seen.add(normalized);
397
- dirs.push(normalized);
398
- }
399
- }
400
- return dirs;
401
- }
402
- /**
403
- * Locate a globally-installed tool binary across every installed manager's
404
- * global bin dir (npm/pnpm/yarn/bun) by direct file lookup — no spawn, no PATH
405
- * reliance. Returns the full path, or `undefined` if not found.
406
- *
407
- * This is the manager-agnostic replacement for a bare `<tool> --version` PATH
408
- * probe: it finds tools installed via `pnpm add -g` / `bun add -g` (whose bin
409
- * dirs are often not on PATH) and survives the PATH-cache staleness that follows
410
- * an `install -g`. On Windows it checks the `.cmd` shim, then `.exe`, then the
411
- * bare name; on Unix just the bare name.
412
- */
413
- export async function findGlobalBinary(command, windowsExt = ".cmd") {
414
- const candidates = onWindows()
415
- ? [`${command}${windowsExt}`, `${command}.exe`, command]
416
- : [command];
417
- try {
418
- for (const binDir of await allAvailableGlobalBinDirs()) {
419
- for (const name of candidates) {
420
- const full = path.join(binDir, name);
421
- if (fs.existsSync(full))
422
- return full;
423
- }
424
- }
425
- }
426
- catch {
427
- // Manager probes can fail (missing binary, spawn error) — treat as "not
428
- // found" so callers fall through to their next resolution step.
429
- }
430
- return undefined;
431
- }
432
- /**
433
- * The three project-local bin-directory shapes in this repo, most-preferred
434
- * first. Exported so every caller passes the SAME constant instead of
435
- * re-listing the directory names next to its own copy of the walk — the venv
436
- * list alone had three independent spellings before #2544 review F1
437
- * (`formatters.ts`, `runner-helpers.ts`'s `createVenvFinder`,
438
- * `dead-code-client.ts`'s `venvCandidates`).
439
- *
440
- * `VENV_BIN_DIRS` lists BOTH the POSIX (`bin`) and Windows (`Scripts`) layouts
441
- * unconditionally rather than branching on `process.platform` at module load:
442
- * a module-load platform constant cannot be forced per test, so the other
443
- * branch is never exercised on the ubuntu lane (defect shape 30). The extra
444
- * two `existsSync` calls per directory are the price of a testable list, and
445
- * a `.venv/Scripts` on Linux (or `.venv/bin` under msys) resolves correctly
446
- * instead of being invisible.
447
- */
448
- export const NODE_MODULES_BIN_DIRS = [
449
- path.join("node_modules", ".bin"),
450
- ];
451
- export const VENDOR_BIN_DIRS = [path.join("vendor", "bin")];
452
- export const VENV_BIN_DIRS = [
453
- path.join(".venv", "bin"),
454
- path.join("venv", "bin"),
455
- path.join(".venv", "Scripts"),
456
- path.join("venv", "Scripts"),
457
- ];
458
- /**
459
- * THE project-local tool-bin walk: yields every `<binDir>/<tool>` that exists
460
- * in `startDir` or one of its ancestors, nearest first, stopping at the HOME
461
- * ceiling (never the fs root — see below).
462
- *
463
- * A generator on purpose. {@link findLocalBinUpwards} takes the first match and
464
- * the walk suspends there — no ancestor above the hit is ever stat'd, which is
465
- * what a per-edit resolver needs — while {@link findLocalBinsUpwards} drains it
466
- * for the ast-grep probe sweep, the one caller that legitimately wants every
467
- * candidate above `startDir`. One walk body, two arities, no "collect-all"
468
- * flag whose disabled half nothing can observe.
469
- * `ceiling: false` opts a walk out of the HOME stop entirely (own-install
470
- * trees only, see {@link LocalBinWalkOptions.ceiling}); {@link findLocalBinsAt}
471
- * / {@link findLocalBinAt} below are the non-walking sibling for callers that
472
- * must check exactly one directory and never climb (`createVenvFinder`,
473
- * vulture's `venvCandidates`).
474
- *
475
- * `tools` is a LIST because the sweep callers probe several spellings of the
476
- * same tool and the preference order is per-directory: all of a directory's
477
- * candidates, in `tools` order, before the parent directory is looked at.
478
- *
479
- * `binDirs` makes this the ONLY such walker in the repo. Before #2544 there
480
- * were SIX copies of this loop — `formatters.ts`'s `findInNodeModules` /
481
- * `findInVendorBin` / `findInVenv`, `oxlint.ts`'s `resolveLocalVp`,
482
- * `runner-helpers.ts`'s `findNodeBinRoots` and `resolveVendorToolCommand` —
483
- * and they had drifted apart: only this one resolved a relative `startDir`,
484
- * only this one had the #2514 HOME ceiling, and `vp` was resolved with
485
- * OPPOSITE ceiling policies depending on whether `formatters.ts` or `oxlint.ts`
486
- * asked (#2544 review F1). They all delegate here now.
487
- *
488
- * Candidate order is EXT-OUTER, DIR-INNER: on Windows every `binDir` is tried
489
- * with `windowsExt` before any is tried with the bare name, matching what the
490
- * `.venv/Scripts` walker did before the fold.
491
- */
492
- /**
493
- * Expand `tools` into the actual candidate file names for one directory,
494
- * EXT-OUTER: on Windows every tool's extended name is tried before any tool's
495
- * bare name (`windowsExt === ""` means the caller already spelled every name
496
- * it wants — the ast-grep sweep passes `ast-grep.cmd`/`ast-grep.exe`/`ast-grep`
497
- * itself in a shell-dependent order this option cannot express).
498
- */
499
- function expandCandidateNames(tools, windowsExt, isWindows) {
500
- return isWindows && windowsExt !== ""
501
- ? tools.flatMap((tool) => [`${tool}${windowsExt}`, tool])
502
- : [...tools];
503
- }
504
- /** Every `<dir>/<binDir>/<name>` that exists, for exactly `dir` — no walk. */
505
- function* matchesInDir(dir, names, binDirs) {
506
- for (const name of names) {
507
- for (const binDir of binDirs) {
508
- const full = path.join(dir, binDir, name);
509
- if (fs.existsSync(full))
510
- yield full;
511
- }
512
- }
513
- }
514
- function* localBinMatches(tools, startDir, options) {
515
- const { windowsExt = ".cmd", homeDir = os.homedir(), binDirs = NODE_MODULES_BIN_DIRS, isWindows = onWindows(), ceiling = true, } = options;
516
- const names = expandCandidateNames(tools, windowsExt, isWindows);
517
- for (const dir of walkUpDirs(startDir)) {
518
- // Tool-resolution walker, not a config lookup (#2514/#2517 policy):
519
- // escaping the project upward past HOME means STOP, not keep reading. A
520
- // config-file lookup (`findLocalToolConfig`) keeps climbing past HOME
521
- // because the underlying tool would find a legitimate global config
522
- // there too; a `node_modules/.bin` match found at or above HOME can
523
- // never be THIS project's own installed dependency — it is some
524
- // unrelated home-level manifest (the pi-extensions bin shim, #2514).
525
- // Default-on (not opt-in like `findLocalToolConfig`'s `options.homeDir`)
526
- // because there is no legitimate case for this resolver to hand back a
527
- // bin from outside the project tree. `ceiling: false` (own-install
528
- // walk only, #2544 round 4 F1) skips this check entirely.
529
- if (ceiling && isAtOrAboveHomeDir(dir, homeDir))
530
- return;
531
- yield* matchesInDir(dir, names, binDirs);
532
- }
533
- }
534
- /**
535
- * The nearest project-local `<binDir>/<tool>` at or above `startDir`, or
536
- * `undefined`. See {@link localBinMatches} for the walk itself.
537
- *
538
- * Exported so callers that must NOT pay for global-bin discovery can reuse this
539
- * walk instead of copying it. `findNodeToolBinary` below adds `findGlobalBinary`,
540
- * which spawns a probe per package manager; a caller resolving a command on
541
- * every run (knip, #1721) needs the filesystem half only.
542
- */
543
- export function findLocalBinUpwards(tool, startDir, options = {}) {
544
- // `.next().value`, not a `for…of` that returns on its first iteration: the
545
- // latter is a single-iteration loop (SonarCloud S1751, and it reads as one
546
- // too). The generator is simply left suspended after the first match — it
547
- // holds no resource that needs closing, which is exactly why the walk above
548
- // never stats an ancestor beyond the hit.
549
- return localBinMatches([tool], startDir, options).next().value;
550
- }
551
- /**
552
- * EVERY project-local match for `tools` at or above `startDir`, nearest first.
553
- *
554
- * For the ast-grep availability sweep (`runner-helpers.ts`'s `buildSgLocalBins`,
555
- * which spawns `--version` against each candidate until one answers, both for
556
- * the project walk and — with `ceiling: false` — pi-lens's own install-tree
557
- * walk), which previously hand-rolled its own unceilinged climb precisely
558
- * because the singular `findLocalBinUpwards` could not express "all of them"
559
- * (#2544 review F1).
560
- *
561
- * NOT for a "project's own venv/vendor-bin first" resolver: `createVenvFinder`
562
- * and vulture's `venvCandidates` looked like this walk's other two callers in
563
- * round 3, but that was an unrequested behaviour change (round 3 introduced
564
- * ancestor climbing where a single cwd/root lookup existed before, with no
565
- * #2514 defect behind it) — reverted in round 4 F2 to {@link findLocalBinsAt}.
566
- */
567
- export function findLocalBinsUpwards(tools, startDir, options = {}) {
568
- return [...localBinMatches(tools, startDir, options)];
569
- }
570
- /**
571
- * EVERY `<dir>/<binDir>/<tool>` that exists for exactly `dir` — no ancestor
572
- * walk, so the HOME ceiling is moot (a single directory can never climb past
573
- * it).
574
- *
575
- * For the "project's own venv/vendor-bin first" resolvers that must NOT climb
576
- * to a parent project (#2544 round 4 F2): `createVenvFinder` and vulture's
577
- * `venvCandidates` were fixed `cwd`/`root` lookups before #2544 review round 3
578
- * converted them into ancestor walks with no reported defect behind the
579
- * conversion (an unrelated sibling project's interpreter at `~/code/.venv`
580
- * could then outrank PATH for `~/code/app`, which has no venv of its own).
581
- * Reverted here; `binDirs`/`windowsExt` stay shared with the walking helpers
582
- * above so the three directory shapes have exactly one spelling.
583
- */
584
- export function findLocalBinsAt(tools, dir, options = {}) {
585
- const { windowsExt = ".cmd", binDirs = NODE_MODULES_BIN_DIRS, isWindows = onWindows(), } = options;
586
- const names = expandCandidateNames(tools, windowsExt, isWindows);
587
- return [...matchesInDir(path.resolve(dir), names, binDirs)];
588
- }
589
- /** The nearest — i.e. first-listed — `<dir>/<binDir>/<tool>` match, or `undefined`. */
590
- export function findLocalBinAt(tool, dir, options = {}) {
591
- return findLocalBinsAt([tool], dir, options)[0];
592
- }
593
- /**
594
- * Locate a Node CLI tool's binary, preferring a local `node_modules/.bin`
595
- * (walking up from `cwd`) then any installed package manager's global bin dir
596
- * (npm/pnpm/yarn/bun). Returns the absolute path, or `undefined` so the caller
597
- * can fall back to its own `npx` invocation.
598
- *
599
- * This is the shared "widen the global-bin lookup" step from #375: the client
600
- * resolvers that previously jumped straight from a local check to `npx <tool>`
601
- * now find tools installed via `pnpm add -g` / `bun add -g` (off PATH) too,
602
- * without changing their npx fallback semantics.
603
- */
604
- export async function findNodeToolBinary(tool, cwd, windowsExt = ".cmd") {
605
- return (findLocalBinUpwards(tool, cwd, { windowsExt }) ??
606
- (await findGlobalBinary(tool, windowsExt)));
607
- }
@@ -1,38 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- const packageRootCache = new Map();
5
- /**
6
- * Resolve the installed package root for the current module.
7
- * Walks upward from the caller until it finds the nearest package.json.
8
- *
9
- * This is the correct alternative to process.cwd() for resolving
10
- * pi-lens's own assets (rules, grammars, configs) when installed
11
- * globally — cwd is the user's project, not the extension root.
12
- *
13
- * Credit: alexx-ftw (PR #1)
14
- */
15
- export function getPackageRoot(importMetaUrl) {
16
- const cached = packageRootCache.get(importMetaUrl);
17
- if (cached)
18
- return cached;
19
- let current = path.dirname(fileURLToPath(importMetaUrl));
20
- while (true) {
21
- if (fs.existsSync(path.join(current, "package.json"))) {
22
- packageRootCache.set(importMetaUrl, current);
23
- return current;
24
- }
25
- const parent = path.dirname(current);
26
- if (parent === current) {
27
- packageRootCache.set(importMetaUrl, current);
28
- return current;
29
- }
30
- current = parent;
31
- }
32
- }
33
- /**
34
- * Resolve a path relative to the installed package root.
35
- */
36
- export function resolvePackagePath(importMetaUrl, ...segments) {
37
- return path.join(getPackageRoot(importMetaUrl), ...segments);
38
- }