pi-lens 4.3.0 → 4.4.1

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 (659) hide show
  1. package/CHANGELOG.md +1159 -0
  2. package/README.md +116 -25
  3. package/config/dependency-cruiser-eager-allowlist.json +6 -2
  4. package/dist/chunk-2BEMIWEW.js +51 -0
  5. package/dist/chunk-2EECBNC5.js +89 -0
  6. package/dist/chunk-2FQ62SPM.js +83 -0
  7. package/dist/chunk-2UMYMRI3.js +118 -0
  8. package/dist/chunk-34OCDWOS.js +48 -0
  9. package/dist/chunk-3FERWMCH.js +144 -0
  10. package/dist/chunk-3JL6IFD7.js +97 -0
  11. package/dist/chunk-3JSEWUWI.js +327 -0
  12. package/dist/chunk-3MED75HT.js +37 -0
  13. package/dist/chunk-3MRXIJ6I.js +79 -0
  14. package/dist/chunk-3P4PF2BX.js +2250 -0
  15. package/dist/chunk-3PNFWVHT.js +201 -0
  16. package/dist/chunk-3TTPKMEF.js +162 -0
  17. package/dist/chunk-5JHXUETW.js +326 -0
  18. package/dist/chunk-5W3R6LFT.js +24 -0
  19. package/dist/chunk-64LU2OVH.js +341 -0
  20. package/dist/chunk-6B5I6ICN.js +44 -0
  21. package/dist/chunk-6P54TMWL.js +274 -0
  22. package/dist/chunk-6UYA642J.js +145 -0
  23. package/dist/chunk-6XX5HCLK.js +398 -0
  24. package/dist/chunk-7AXO3ZDF.js +30 -0
  25. package/dist/chunk-7BX5DWSA.js +1907 -0
  26. package/dist/chunk-7ELY2CSM.js +902 -0
  27. package/dist/chunk-7M4T5N3V.js +38 -0
  28. package/dist/chunk-7U2IDNXN.js +37 -0
  29. package/dist/chunk-ABBOA7UD.js +157 -0
  30. package/dist/chunk-AFZYMAIV.js +756 -0
  31. package/dist/chunk-ALQRYH6O.js +112 -0
  32. package/dist/chunk-AXKPQ6ZI.js +1610 -0
  33. package/dist/chunk-BHWHXMQ2.js +62 -0
  34. package/dist/chunk-BJF25SUG.js +22 -0
  35. package/dist/chunk-BNKLYOOO.js +18 -0
  36. package/dist/chunk-BW5KFIQC.js +59 -0
  37. package/dist/chunk-CBD2B5CP.js +599 -0
  38. package/dist/chunk-CFYISHUW.js +42 -0
  39. package/dist/chunk-CMU4RMJB.js +30 -0
  40. package/dist/chunk-CULQYFLU.js +14 -0
  41. package/dist/chunk-D65GOCJB.js +289 -0
  42. package/dist/chunk-D6YF5HKX.js +59 -0
  43. package/dist/chunk-DMS52BEP.js +342 -0
  44. package/dist/chunk-ELVWJYRV.js +211 -0
  45. package/dist/chunk-EUT3B22Y.js +27 -0
  46. package/dist/chunk-F5VLZHUW.js +146 -0
  47. package/dist/chunk-FC4RP4I2.js +12 -0
  48. package/dist/chunk-FGALODG3.js +55 -0
  49. package/dist/chunk-G3RLJYA2.js +2358 -0
  50. package/dist/chunk-GAYGGICG.js +32 -0
  51. package/dist/chunk-H2W2AXD3.js +419 -0
  52. package/dist/chunk-H5EV3VMF.js +114 -0
  53. package/dist/chunk-HREZQCT3.js +106 -0
  54. package/dist/chunk-HSIRMK2D.js +517 -0
  55. package/dist/chunk-IMSQR4WO.js +184 -0
  56. package/dist/chunk-IQZXOZ7S.js +4816 -0
  57. package/dist/chunk-IR6XFA5P.js +37 -0
  58. package/dist/chunk-IUKPRZER.js +78 -0
  59. package/dist/chunk-IUR76K6A.js +262 -0
  60. package/dist/chunk-J3FZR3YY.js +98 -0
  61. package/dist/chunk-J6DFZDFA.js +562 -0
  62. package/dist/chunk-J7WJZ6W7.js +50 -0
  63. package/dist/chunk-JONGANYH.js +202 -0
  64. package/dist/chunk-KJCWXUUS.js +425 -0
  65. package/dist/chunk-KJN4IOEJ.js +17 -0
  66. package/dist/chunk-KMGPUKFD.js +25 -0
  67. package/dist/chunk-LD7WFTRX.js +4533 -0
  68. package/dist/chunk-LJDODBBZ.js +78 -0
  69. package/dist/chunk-LNOMA3MP.js +169 -0
  70. package/dist/chunk-MGIWSROG.js +2334 -0
  71. package/dist/chunk-MQA2YBAH.js +308 -0
  72. package/dist/chunk-MTDRLSI7.js +21720 -0
  73. package/dist/chunk-N2IRDBZI.js +2355 -0
  74. package/dist/chunk-N77WFUL7.js +50 -0
  75. package/dist/chunk-N7YNJE5R.js +466 -0
  76. package/dist/chunk-NABLC7W3.js +148 -0
  77. package/dist/chunk-NFXP47RV.js +999 -0
  78. package/dist/chunk-NJF2X5XF.js +45 -0
  79. package/dist/chunk-NXL4FFQQ.js +47 -0
  80. package/dist/chunk-O7HZX7CA.js +309 -0
  81. package/dist/chunk-OC7LYAU5.js +708 -0
  82. package/dist/chunk-OEX24ECI.js +348 -0
  83. package/dist/chunk-OYOB3ZFG.js +78 -0
  84. package/dist/chunk-OYTMZXRF.js +41 -0
  85. package/dist/chunk-OZJINN4O.js +84 -0
  86. package/dist/chunk-PCHDGUKT.js +23 -0
  87. package/dist/chunk-QOZXJ4NA.js +3364 -0
  88. package/dist/chunk-QYF5S6P6.js +45 -0
  89. package/dist/chunk-RJFED73B.js +79 -0
  90. package/dist/chunk-RTQNRM5X.js +27 -0
  91. package/dist/chunk-S6AMWKPC.js +189 -0
  92. package/dist/chunk-T4QZ6FEH.js +308 -0
  93. package/dist/chunk-T54VJRAD.js +5456 -0
  94. package/dist/chunk-TA5L5KWQ.js +167 -0
  95. package/dist/chunk-TQFBZVCG.js +27 -0
  96. package/dist/chunk-U52SAGRM.js +62 -0
  97. package/dist/chunk-UEAHAMEI.js +5814 -0
  98. package/dist/chunk-UGSMCQ4D.js +327 -0
  99. package/dist/chunk-UOPVJQ4N.js +103 -0
  100. package/dist/chunk-USHG4DLH.js +459 -0
  101. package/dist/chunk-UXVNL3D7.js +23 -0
  102. package/dist/chunk-V5MEBST3.js +4139 -0
  103. package/dist/chunk-VGEVL5EQ.js +29 -0
  104. package/dist/chunk-VPWKF3GN.js +87 -0
  105. package/dist/chunk-VSMJK3ZJ.js +1250 -0
  106. package/dist/chunk-VYKKMYVT.js +560 -0
  107. package/dist/chunk-VZHJS6DR.js +442 -0
  108. package/dist/chunk-WATC3IQR.js +213 -0
  109. package/dist/chunk-WPE5FPGR.js +54 -0
  110. package/dist/chunk-WSEWKCXU.js +188 -0
  111. package/dist/chunk-WW5BLB74.js +659 -0
  112. package/dist/chunk-XGUL4SLQ.js +406 -0
  113. package/dist/chunk-XHSCVSOL.js +170 -0
  114. package/dist/chunk-XIMYZ3JA.js +27 -0
  115. package/dist/chunk-YLN4K6WD.js +385 -0
  116. package/dist/chunk-Z3CCVDUB.js +76 -0
  117. package/dist/chunk-Z54ZSOBZ.js +61 -0
  118. package/dist/chunk-Z6BB4JLQ.js +478 -0
  119. package/dist/chunk-Z7QQA2KT.js +27 -0
  120. package/dist/chunk-ZETYB3XG.js +2626 -0
  121. package/dist/chunk-ZMOMPX2Z.js +87 -0
  122. package/dist/chunk-ZOEYVXSV.js +149 -0
  123. package/dist/chunk-ZZUFZUQZ.js +12120 -0
  124. package/dist/index.js +39712 -29876
  125. package/dist/mcp/analyze-cli.js +186 -232
  126. package/dist/mcp/cli.js +137 -98
  127. package/dist/mcp/server.js +22688 -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 +5 -4
  135. package/docs/configuration.md +28 -2
  136. package/docs/custom-rules.md +25 -2
  137. package/docs/environment-variables.md +86 -8
  138. package/docs/features.md +45 -5
  139. package/docs/globalconfig.md +2 -1
  140. package/docs/io-bridge-v2-migration.md +94 -0
  141. package/docs/lsp-capability-matrix.md +37 -4
  142. package/docs/lsp-idle-eviction.md +124 -0
  143. package/docs/mcp.md +21 -5
  144. package/docs/merge-queue-rollout.md +77 -0
  145. package/docs/pi-lens-fixer.md +160 -88
  146. package/docs/pi-lens-investigator.md +74 -26
  147. package/docs/pi-lens-merge-policy.md +736 -0
  148. package/docs/pi-lens-monitor.md +75 -7
  149. package/docs/pi-lens-retro.md +6 -4
  150. package/docs/pi-lens-reviewer.md +189 -48
  151. package/docs/pi-lens-subagent.md +246 -45
  152. package/docs/pi-lens-warden.md +18 -7
  153. package/docs/public-api-stability.md +55 -0
  154. package/docs/release-qa-baseline.md +84 -17
  155. package/docs/rfcs/3654-unified-io-bridge-v2.md +316 -0
  156. package/docs/schema/pi-lens-config-v1.json +530 -0
  157. package/docs/servercapabilities.md +56 -49
  158. package/docs/settings.md +1 -0
  159. package/docs/usage.md +5 -1
  160. package/docs/word-index.md +6 -0
  161. package/grammars/tree-sitter-bash.wasm +0 -0
  162. package/grammars/tree-sitter-bash.wasm.json +3 -3
  163. package/package.json +19 -7
  164. package/rules/ast-grep-rules/rule-tests/advisory-registry-subset-test.yml +41 -0
  165. package/rules/ast-grep-rules/rule-tests/no-identity-operator-on-literals-test.yml +12 -2
  166. package/rules/ast-grep-rules/rule-tests/throw-new-error-js-test.yml +2 -0
  167. package/rules/ast-grep-rules/rule-tests/throw-new-error-test.yml +2 -0
  168. package/rules/ast-grep-rules/rules/advisory-registry-subset.yml +50 -0
  169. package/rules/ast-grep-rules/rules/no-identity-operator-on-literals.yml +20 -12
  170. package/rules/ast-grep-rules/rules/throw-new-error-js.yml +2 -2
  171. package/rules/ast-grep-rules/rules/throw-new-error.yml +2 -2
  172. package/scripts/analyze-pi-lens-logs.mjs +1275 -62
  173. package/scripts/download-grammars.js +5 -0
  174. package/scripts/grammars.lock.json +6 -1
  175. package/scripts/install-selftest.mjs +33 -34
  176. package/scripts/lib/host-provided-deps.mjs +13 -4
  177. package/scripts/lib/web-tree-sitter-dir.mjs +18 -0
  178. package/dist/clients/actionable-warnings-logger.js +0 -35
  179. package/dist/clients/actionable-warnings.js +0 -1610
  180. package/dist/clients/advisory-provenance.js +0 -593
  181. package/dist/clients/agent-behavior-client.js +0 -147
  182. package/dist/clients/agent-nudge.js +0 -325
  183. package/dist/clients/analysed-root.js +0 -1
  184. package/dist/clients/ast-grep-client.js +0 -731
  185. package/dist/clients/ast-grep-rule-manager.js +0 -146
  186. package/dist/clients/ast-grep-tool-logger.js +0 -118
  187. package/dist/clients/ast-grep-types.js +0 -10
  188. package/dist/clients/ast-grep-yaml-synth.js +0 -154
  189. package/dist/clients/atomic-write-staging.js +0 -75
  190. package/dist/clients/atomic-write.js +0 -189
  191. package/dist/clients/availability-probe-flight.js +0 -12
  192. package/dist/clients/bash-file-access.js +0 -1056
  193. package/dist/clients/biome-client.js +0 -357
  194. package/dist/clients/blocker-freshness.js +0 -837
  195. package/dist/clients/blocker-past-eof.js +0 -129
  196. package/dist/clients/bootstrap.js +0 -569
  197. package/dist/clients/bounded-cache.js +0 -190
  198. package/dist/clients/bounded-pid-file-lock.js +0 -202
  199. package/dist/clients/bounded-telemetry.js +0 -295
  200. package/dist/clients/build-identity.js +0 -95
  201. package/dist/clients/bundled-resource-health.js +0 -113
  202. package/dist/clients/bus-events-logger.js +0 -105
  203. package/dist/clients/bus-publish.js +0 -171
  204. package/dist/clients/cache/rule-cache.js +0 -190
  205. package/dist/clients/cache-manager.js +0 -524
  206. package/dist/clients/cache-observability.js +0 -1313
  207. package/dist/clients/call-graph.js +0 -852
  208. package/dist/clients/cargo-manifest.js +0 -422
  209. package/dist/clients/cascade-budget.js +0 -196
  210. package/dist/clients/cascade-format.js +0 -315
  211. package/dist/clients/cascade-logger.js +0 -31
  212. package/dist/clients/cascade-types.js +0 -9
  213. package/dist/clients/child-unref.js +0 -124
  214. package/dist/clients/code-quality-warnings.js +0 -286
  215. package/dist/clients/codebase-model.js +0 -173
  216. package/dist/clients/collateral-test-role.js +0 -40
  217. package/dist/clients/complexity-client.js +0 -462
  218. package/dist/clients/config-core/deny.js +0 -221
  219. package/dist/clients/config-core/index.js +0 -50
  220. package/dist/clients/config-core/merge.js +0 -357
  221. package/dist/clients/config-core/normalize.js +0 -340
  222. package/dist/clients/config-core/process-spec.js +0 -248
  223. package/dist/clients/config-core/provenance.js +0 -164
  224. package/dist/clients/config-core/records.js +0 -218
  225. package/dist/clients/config-core/resolve.js +0 -125
  226. package/dist/clients/config-core/safe-object.js +0 -78
  227. package/dist/clients/config-core/schema.js +0 -165
  228. package/dist/clients/config-diagnostic-codes.js +0 -285
  229. package/dist/clients/config-locations.js +0 -388
  230. package/dist/clients/config-resolve.js +0 -798
  231. package/dist/clients/config-schema.js +0 -251
  232. package/dist/clients/config-warn.js +0 -407
  233. package/dist/clients/console-guard-install.js +0 -26
  234. package/dist/clients/cooperative-budget.js +0 -42
  235. package/dist/clients/dead-code-client.js +0 -510
  236. package/dist/clients/dead-code-logger.js +0 -30
  237. package/dist/clients/deadline-utils.js +0 -280
  238. package/dist/clients/debug-handles.js +0 -211
  239. package/dist/clients/debug-heap.js +0 -174
  240. package/dist/clients/deferred-lsp-work.js +0 -106
  241. package/dist/clients/degradation-ledger.js +0 -426
  242. package/dist/clients/demoted-finding-render.js +0 -169
  243. package/dist/clients/dependency-checker.js +0 -885
  244. package/dist/clients/deps/ast-grep-napi.js +0 -22
  245. package/dist/clients/deps/js-yaml.js +0 -9
  246. package/dist/clients/deps/minimatch.js +0 -4
  247. package/dist/clients/deps/pi-tui.js +0 -14
  248. package/dist/clients/deps/typebox.js +0 -14
  249. package/dist/clients/deps/vscode-jsonrpc.js +0 -1
  250. package/dist/clients/deps/web-tree-sitter.js +0 -24
  251. package/dist/clients/diagnostic-dispositions.js +0 -630
  252. package/dist/clients/diagnostic-line-freshness.js +0 -305
  253. package/dist/clients/diagnostic-logger.js +0 -73
  254. package/dist/clients/diagnostic-tracker.js +0 -105
  255. package/dist/clients/diagnostics-publish.js +0 -230
  256. package/dist/clients/dispatch/ast-grep-catalog.js +0 -65
  257. package/dist/clients/dispatch/auxiliary-lsp.js +0 -343
  258. package/dist/clients/dispatch/collect-later-tier.js +0 -35
  259. package/dist/clients/dispatch/diagnostic-taxonomy.js +0 -66
  260. package/dist/clients/dispatch/dispatcher.js +0 -1269
  261. package/dist/clients/dispatch/fact-provider-types.js +0 -1
  262. package/dist/clients/dispatch/fact-rule-runner.js +0 -17
  263. package/dist/clients/dispatch/fact-runner.js +0 -30
  264. package/dist/clients/dispatch/fact-scheduler.js +0 -68
  265. package/dist/clients/dispatch/fact-store.js +0 -377
  266. package/dist/clients/dispatch/facts/comment-facts.js +0 -22
  267. package/dist/clients/dispatch/facts/file-content.js +0 -19
  268. package/dist/clients/dispatch/facts/function-facts.js +0 -348
  269. package/dist/clients/dispatch/facts/import-facts.js +0 -204
  270. package/dist/clients/dispatch/facts/tree-sitter-facts.js +0 -34
  271. package/dist/clients/dispatch/facts/try-catch-facts.js +0 -119
  272. package/dist/clients/dispatch/finding-policy.js +0 -339
  273. package/dist/clients/dispatch/indent-detect.js +0 -417
  274. package/dist/clients/dispatch/inline-suppressions.js +0 -89
  275. package/dist/clients/dispatch/integration.js +0 -2377
  276. package/dist/clients/dispatch/lazy.js +0 -11
  277. package/dist/clients/dispatch/pending-runner-findings.js +0 -87
  278. package/dist/clients/dispatch/plan.js +0 -278
  279. package/dist/clients/dispatch/priorities.js +0 -20
  280. package/dist/clients/dispatch/rule-id-normalize.js +0 -50
  281. package/dist/clients/dispatch/rule-ignores.js +0 -69
  282. package/dist/clients/dispatch/rule-policy.js +0 -135
  283. package/dist/clients/dispatch/rules/async-noise.js +0 -40
  284. package/dist/clients/dispatch/rules/async-unnecessary-wrapper.js +0 -27
  285. package/dist/clients/dispatch/rules/cors-wildcard.js +0 -54
  286. package/dist/clients/dispatch/rules/error-obscuring.js +0 -32
  287. package/dist/clients/dispatch/rules/error-swallowing.js +0 -31
  288. package/dist/clients/dispatch/rules/framework-call-noise.js +0 -67
  289. package/dist/clients/dispatch/rules/high-complexity.js +0 -72
  290. package/dist/clients/dispatch/rules/high-fan-out.js +0 -74
  291. package/dist/clients/dispatch/rules/high-import-coupling.js +0 -37
  292. package/dist/clients/dispatch/rules/missing-error-propagation.js +0 -62
  293. package/dist/clients/dispatch/rules/no-commented-credentials.js +0 -52
  294. package/dist/clients/dispatch/rules/pass-through-wrappers.js +0 -42
  295. package/dist/clients/dispatch/rules/placeholder-comments.js +0 -40
  296. package/dist/clients/dispatch/rules/unsafe-boundary.js +0 -126
  297. package/dist/clients/dispatch/runner-context.js +0 -52
  298. package/dist/clients/dispatch/runners/actionlint.js +0 -111
  299. package/dist/clients/dispatch/runners/ast-grep-napi.js +0 -1196
  300. package/dist/clients/dispatch/runners/biome-check.js +0 -296
  301. package/dist/clients/dispatch/runners/cpp-check.js +0 -219
  302. package/dist/clients/dispatch/runners/credo.js +0 -82
  303. package/dist/clients/dispatch/runners/cue-vet.js +0 -416
  304. package/dist/clients/dispatch/runners/dart-analyze.js +0 -183
  305. package/dist/clients/dispatch/runners/detekt.js +0 -176
  306. package/dist/clients/dispatch/runners/dotnet-build.js +0 -164
  307. package/dist/clients/dispatch/runners/elixir-check.js +0 -195
  308. package/dist/clients/dispatch/runners/eslint.js +0 -137
  309. package/dist/clients/dispatch/runners/fact-rules.js +0 -29
  310. package/dist/clients/dispatch/runners/fish-indent.js +0 -69
  311. package/dist/clients/dispatch/runners/gleam-check.js +0 -167
  312. package/dist/clients/dispatch/runners/go-vet.js +0 -104
  313. package/dist/clients/dispatch/runners/golangci-lint.js +0 -135
  314. package/dist/clients/dispatch/runners/hadolint.js +0 -91
  315. package/dist/clients/dispatch/runners/helm-lint.js +0 -171
  316. package/dist/clients/dispatch/runners/helm-render.js +0 -940
  317. package/dist/clients/dispatch/runners/htmlhint.js +0 -117
  318. package/dist/clients/dispatch/runners/index.js +0 -108
  319. package/dist/clients/dispatch/runners/javac.js +0 -99
  320. package/dist/clients/dispatch/runners/ktlint.js +0 -110
  321. package/dist/clients/dispatch/runners/lsp.js +0 -379
  322. package/dist/clients/dispatch/runners/markdownlint.js +0 -167
  323. package/dist/clients/dispatch/runners/mypy.js +0 -102
  324. package/dist/clients/dispatch/runners/oxlint.js +0 -414
  325. package/dist/clients/dispatch/runners/php-lint.js +0 -85
  326. package/dist/clients/dispatch/runners/phpstan.js +0 -120
  327. package/dist/clients/dispatch/runners/prisma-validate.js +0 -62
  328. package/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -445
  329. package/dist/clients/dispatch/runners/pyright.js +0 -169
  330. package/dist/clients/dispatch/runners/rubocop.js +0 -99
  331. package/dist/clients/dispatch/runners/ruff.js +0 -88
  332. package/dist/clients/dispatch/runners/rust-clippy.js +0 -256
  333. package/dist/clients/dispatch/runners/shellcheck.js +0 -173
  334. package/dist/clients/dispatch/runners/shfmt.js +0 -102
  335. package/dist/clients/dispatch/runners/spellcheck.js +0 -128
  336. package/dist/clients/dispatch/runners/spotbugs.js +0 -259
  337. package/dist/clients/dispatch/runners/sqlfluff.js +0 -183
  338. package/dist/clients/dispatch/runners/stylelint.js +0 -166
  339. package/dist/clients/dispatch/runners/swiftlint.js +0 -163
  340. package/dist/clients/dispatch/runners/taplo.js +0 -174
  341. package/dist/clients/dispatch/runners/terragrunt.js +0 -168
  342. package/dist/clients/dispatch/runners/tflint.js +0 -125
  343. package/dist/clients/dispatch/runners/tree-sitter.js +0 -643
  344. package/dist/clients/dispatch/runners/trivy-config.js +0 -253
  345. package/dist/clients/dispatch/runners/utils/availability-policy.js +0 -496
  346. package/dist/clients/dispatch/runners/utils/candidate-probe.js +0 -90
  347. package/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -95
  348. package/dist/clients/dispatch/runners/utils/lazy-installer.js +0 -274
  349. package/dist/clients/dispatch/runners/utils/runner-helpers.js +0 -1701
  350. package/dist/clients/dispatch/runners/utils/spawn-outcome.js +0 -101
  351. package/dist/clients/dispatch/runners/utils/tool-failure.js +0 -235
  352. package/dist/clients/dispatch/runners/utils/toolchain-availability.js +0 -169
  353. package/dist/clients/dispatch/runners/utils.js +0 -15
  354. package/dist/clients/dispatch/runners/vale.js +0 -128
  355. package/dist/clients/dispatch/runners/yaml-rule-parser.js +0 -242
  356. package/dist/clients/dispatch/runners/yamllint.js +0 -95
  357. package/dist/clients/dispatch/runners/zig-check.js +0 -79
  358. package/dist/clients/dispatch/suppress-writer.js +0 -79
  359. package/dist/clients/dispatch/tool-profile.js +0 -30
  360. package/dist/clients/dispatch/types.js +0 -21
  361. package/dist/clients/dispatch/utils/format-utils.js +0 -45
  362. package/dist/clients/dispatch/utils/lsp-diagnostics.js +0 -35
  363. package/dist/clients/disposition-logger.js +0 -32
  364. package/dist/clients/disposition-publish.js +0 -124
  365. package/dist/clients/durable-store.js +0 -97
  366. package/dist/clients/effective-config.js +0 -415
  367. package/dist/clients/env-utils.js +0 -83
  368. package/dist/clients/error-class.js +0 -23
  369. package/dist/clients/eval-timestamp.js +0 -17
  370. package/dist/clients/event-loop-hold.js +0 -274
  371. package/dist/clients/event-loop-monitor.js +0 -250
  372. package/dist/clients/extension-log.js +0 -504
  373. package/dist/clients/extension-mode.js +0 -73
  374. package/dist/clients/feature-hints.js +0 -103
  375. package/dist/clients/file-kinds.js +0 -412
  376. package/dist/clients/file-role.js +0 -134
  377. package/dist/clients/file-time.js +0 -160
  378. package/dist/clients/file-utils.js +0 -1032
  379. package/dist/clients/finding-delivery-gate.js +0 -494
  380. package/dist/clients/finding-identity.js +0 -88
  381. package/dist/clients/fix-worklog.js +0 -103
  382. package/dist/clients/format-events-publish.js +0 -343
  383. package/dist/clients/format-service.js +0 -222
  384. package/dist/clients/formatters-lazy.js +0 -9
  385. package/dist/clients/formatters.js +0 -2032
  386. package/dist/clients/freshness-cadence.js +0 -17
  387. package/dist/clients/freshness.js +0 -38
  388. package/dist/clients/generated-artifacts.js +0 -394
  389. package/dist/clients/generation-guard.js +0 -215
  390. package/dist/clients/git-guard.js +0 -1136
  391. package/dist/clients/git-tracked-ignore.js +0 -243
  392. package/dist/clients/gitleaks-client.js +0 -509
  393. package/dist/clients/go-client.js +0 -104
  394. package/dist/clients/govulncheck-client.js +0 -605
  395. package/dist/clients/gradle-ktfmt-style.js +0 -348
  396. package/dist/clients/grammar-source.js +0 -465
  397. package/dist/clients/gzip-stage-write.js +0 -135
  398. package/dist/clients/hashline-anchor.js +0 -424
  399. package/dist/clients/hook-budgets.js +0 -76
  400. package/dist/clients/host-edit-normalize.js +0 -140
  401. package/dist/clients/host-ports.js +0 -39
  402. package/dist/clients/indent-retarget.js +0 -154
  403. package/dist/clients/inline-blocker-dispositions.js +0 -186
  404. package/dist/clients/install-diagnostics.js +0 -156
  405. package/dist/clients/installer/index.js +0 -5416
  406. package/dist/clients/installer/managed-tool-refresh-session.js +0 -58
  407. package/dist/clients/installer/managed-tool-refresh.js +0 -783
  408. package/dist/clients/instance-reaper-state.js +0 -7
  409. package/dist/clients/instance-reaper.js +0 -1137
  410. package/dist/clients/instance-registry-lock.js +0 -145
  411. package/dist/clients/instance-registry.js +0 -773
  412. package/dist/clients/jscpd-client.js +0 -378
  413. package/dist/clients/json-cache-read.js +0 -65
  414. package/dist/clients/knip-client.js +0 -788
  415. package/dist/clients/language-policy.js +0 -252
  416. package/dist/clients/language-profile.js +0 -361
  417. package/dist/clients/language-registry.js +0 -603
  418. package/dist/clients/latency-logger.js +0 -727
  419. package/dist/clients/lazy-import.js +0 -21
  420. package/dist/clients/ledger-bounds.js +0 -54
  421. package/dist/clients/lens-config.js +0 -404
  422. package/dist/clients/lens-engine.js +0 -358
  423. package/dist/clients/lens-events.js +0 -125
  424. package/dist/clients/lens-flag-registry.js +0 -467
  425. package/dist/clients/lens-map.js +0 -1156
  426. package/dist/clients/live-bus-emitter.js +0 -74
  427. package/dist/clients/log-cleanup.js +0 -222
  428. package/dist/clients/lsp/aggregation.js +0 -178
  429. package/dist/clients/lsp/cascade-tier.js +0 -421
  430. package/dist/clients/lsp/client.js +0 -4593
  431. package/dist/clients/lsp/config.js +0 -691
  432. package/dist/clients/lsp/content-limits.js +0 -41
  433. package/dist/clients/lsp/diagnostic-binding.js +0 -225
  434. package/dist/clients/lsp/document-drift.js +0 -467
  435. package/dist/clients/lsp/edits.js +0 -1219
  436. package/dist/clients/lsp/index.js +0 -8305
  437. package/dist/clients/lsp/inferred-project.js +0 -216
  438. package/dist/clients/lsp/jvm-runtime.js +0 -298
  439. package/dist/clients/lsp/language.js +0 -63
  440. package/dist/clients/lsp/launch.js +0 -746
  441. package/dist/clients/lsp/lombok.js +0 -158
  442. package/dist/clients/lsp/path-utils.js +0 -5
  443. package/dist/clients/lsp/pending-aux-coverage.js +0 -251
  444. package/dist/clients/lsp/position-encoding.js +0 -61
  445. package/dist/clients/lsp/ruby-drive-dirs.js +0 -83
  446. package/dist/clients/lsp/server.js +0 -3290
  447. package/dist/clients/lsp/session-roots.js +0 -192
  448. package/dist/clients/lsp/spawn-history.js +0 -17
  449. package/dist/clients/lsp/sync-kind.js +0 -56
  450. package/dist/clients/lsp/tsserver-sync.js +0 -332
  451. package/dist/clients/lsp/wait-policy/capability-snapshot.js +0 -1
  452. package/dist/clients/lsp/wait-policy/classification.js +0 -85
  453. package/dist/clients/lsp/wait-policy/index.js +0 -10
  454. package/dist/clients/lsp/wait-policy/strategies.js +0 -392
  455. package/dist/clients/lsp/watch-queue.js +0 -61
  456. package/dist/clients/lsp/workspace-diagnostics-cache.js +0 -639
  457. package/dist/clients/lsp/workspace-diagnostics-session.js +0 -30
  458. package/dist/clients/lsp/workspace-sweep-hold.js +0 -184
  459. package/dist/clients/lsp-budget.js +0 -186
  460. package/dist/clients/lsp-document-symbols.js +0 -110
  461. package/dist/clients/lsp-lazy.js +0 -9
  462. package/dist/clients/lsp-mutation.js +0 -396
  463. package/dist/clients/lsp-status.js +0 -59
  464. package/dist/clients/map-with-concurrency.js +0 -40
  465. package/dist/clients/mcp/analyze.js +0 -420
  466. package/dist/clients/mcp/host-shim.js +0 -31
  467. package/dist/clients/mcp/ipc.js +0 -523
  468. package/dist/clients/mcp/review.js +0 -197
  469. package/dist/clients/mcp/session.js +0 -412
  470. package/dist/clients/memory-sampler.js +0 -208
  471. package/dist/clients/message-end-attribution.js +0 -30
  472. package/dist/clients/metrics-client.js +0 -107
  473. package/dist/clients/metrics-history.js +0 -327
  474. package/dist/clients/middle-man-analysis.js +0 -263
  475. package/dist/clients/model-provider.js +0 -53
  476. package/dist/clients/module-report-lsp.js +0 -189
  477. package/dist/clients/module-report.js +0 -2150
  478. package/dist/clients/mutating-tool.js +0 -651
  479. package/dist/clients/mutation-attribution.js +0 -368
  480. package/dist/clients/mutation-bridge.js +0 -240
  481. package/dist/clients/ndjson-logger.js +0 -734
  482. package/dist/clients/observed-mutation-sources.js +0 -101
  483. package/dist/clients/observed-mutation.js +0 -1253
  484. package/dist/clients/oldtext-autopatch.js +0 -128
  485. package/dist/clients/opaque-mutation-scan.js +0 -496
  486. package/dist/clients/opengrep-client.js +0 -333
  487. package/dist/clients/opengrep-config.js +0 -76
  488. package/dist/clients/package-manager.js +0 -607
  489. package/dist/clients/package-root.js +0 -38
  490. package/dist/clients/partial-edit-apply.js +0 -439
  491. package/dist/clients/path-attribution-telemetry.js +0 -43
  492. package/dist/clients/path-keyed-map.js +0 -108
  493. package/dist/clients/path-utils.js +0 -1244
  494. package/dist/clients/performance-report.js +0 -331
  495. package/dist/clients/persist-debounce.js +0 -70
  496. package/dist/clients/persistent-reverify.js +0 -271
  497. package/dist/clients/php-cs-fixer-config.js +0 -119
  498. package/dist/clients/pipeline.js +0 -1480
  499. package/dist/clients/post-autofix-notice.js +0 -37
  500. package/dist/clients/print-mode.js +0 -21
  501. package/dist/clients/probe-home-state.js +0 -228
  502. package/dist/clients/process-bridge.js +0 -66
  503. package/dist/clients/process-singletons.js +0 -210
  504. package/dist/clients/process-snapshot.js +0 -68
  505. package/dist/clients/project-changes.js +0 -181
  506. package/dist/clients/project-conventions.js +0 -171
  507. package/dist/clients/project-diagnostics/cache.js +0 -137
  508. package/dist/clients/project-diagnostics/extractors.js +0 -109
  509. package/dist/clients/project-diagnostics/fresh-fetch.js +0 -668
  510. package/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +0 -118
  511. package/dist/clients/project-diagnostics/runner-adapters/dead-code.js +0 -47
  512. package/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +0 -40
  513. package/dist/clients/project-diagnostics/runner-adapters/govulncheck.js +0 -34
  514. package/dist/clients/project-diagnostics/runner-adapters/jscpd.js +0 -38
  515. package/dist/clients/project-diagnostics/runner-adapters/knip.js +0 -47
  516. package/dist/clients/project-diagnostics/runner-adapters/madge.js +0 -48
  517. package/dist/clients/project-diagnostics/runner-adapters/opengrep.js +0 -40
  518. package/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +0 -127
  519. package/dist/clients/project-diagnostics/runner-adapters/trivy.js +0 -81
  520. package/dist/clients/project-diagnostics/scanner.js +0 -520
  521. package/dist/clients/project-diagnostics/types.js +0 -1
  522. package/dist/clients/project-lens-config.js +0 -807
  523. package/dist/clients/project-report.js +0 -701
  524. package/dist/clients/project-scale.js +0 -237
  525. package/dist/clients/project-scan-policy.js +0 -11
  526. package/dist/clients/project-snapshot-fingerprint.js +0 -48
  527. package/dist/clients/project-snapshot-persist-worker.js +0 -20
  528. package/dist/clients/project-snapshot.js +0 -1653
  529. package/dist/clients/project-trust.js +0 -181
  530. package/dist/clients/python-environment.js +0 -217
  531. package/dist/clients/python-provenance.js +0 -639
  532. package/dist/clients/quiet-window-config.js +0 -47
  533. package/dist/clients/quiet-window.js +0 -236
  534. package/dist/clients/read-bridge.js +0 -139
  535. package/dist/clients/read-expansion.js +0 -266
  536. package/dist/clients/read-guard-logger.js +0 -251
  537. package/dist/clients/read-guard-tool-lines.js +0 -1306
  538. package/dist/clients/read-guard.js +0 -1561
  539. package/dist/clients/recent-touches.js +0 -240
  540. package/dist/clients/redact/secrets.js +0 -449
  541. package/dist/clients/resource-sampler.js +0 -628
  542. package/dist/clients/reverse-deps.js +0 -270
  543. package/dist/clients/review-graph/builder.js +0 -5126
  544. package/dist/clients/review-graph/format.js +0 -33
  545. package/dist/clients/review-graph/git-identity.js +0 -163
  546. package/dist/clients/review-graph/import-resolvers.js +0 -481
  547. package/dist/clients/review-graph/persist-worker.js +0 -10
  548. package/dist/clients/review-graph/query.js +0 -244
  549. package/dist/clients/review-graph/revision-drift.js +0 -21
  550. package/dist/clients/review-graph/service.js +0 -96
  551. package/dist/clients/review-graph/shared-extraction-ir.js +0 -82
  552. package/dist/clients/review-graph/symbol-id.js +0 -103
  553. package/dist/clients/review-graph/tsconfig-paths.js +0 -299
  554. package/dist/clients/review-graph/types.js +0 -1
  555. package/dist/clients/review-graph/workspace-modules.js +0 -449
  556. package/dist/clients/review-graph-logger.js +0 -81
  557. package/dist/clients/ruff-client.js +0 -179
  558. package/dist/clients/rules-scanner.js +0 -131
  559. package/dist/clients/run-duration.js +0 -55
  560. package/dist/clients/runtime-agent-end.js +0 -746
  561. package/dist/clients/runtime-config.js +0 -77
  562. package/dist/clients/runtime-context.js +0 -211
  563. package/dist/clients/runtime-coordinator.js +0 -1324
  564. package/dist/clients/runtime-session.js +0 -2485
  565. package/dist/clients/runtime-tool-call.js +0 -1295
  566. package/dist/clients/runtime-tool-result.js +0 -2049
  567. package/dist/clients/runtime-turn.js +0 -3767
  568. package/dist/clients/rust-client.js +0 -97
  569. package/dist/clients/safe-spawn.js +0 -2357
  570. package/dist/clients/sanitize.js +0 -286
  571. package/dist/clients/scan-utils.js +0 -25
  572. package/dist/clients/scratch-tree-policy.js +0 -165
  573. package/dist/clients/search-read-registration.js +0 -94
  574. package/dist/clients/secret-findings.js +0 -114
  575. package/dist/clients/security-scan-client.js +0 -352
  576. package/dist/clients/session-event-guard.js +0 -297
  577. package/dist/clients/session-lifecycle.js +0 -484
  578. package/dist/clients/session-start-observability.js +0 -94
  579. package/dist/clients/session-state-store.js +0 -101
  580. package/dist/clients/session-summary.js +0 -15
  581. package/dist/clients/sessionstart-logger.js +0 -27
  582. package/dist/clients/sg-runner.js +0 -876
  583. package/dist/clients/sgconfig.js +0 -347
  584. package/dist/clients/shared-checkout-guard.js +0 -338
  585. package/dist/clients/single-flight.js +0 -158
  586. package/dist/clients/situational-tool-telemetry.js +0 -108
  587. package/dist/clients/skills-resolver.js +0 -141
  588. package/dist/clients/slow-fs.js +0 -138
  589. package/dist/clients/smells-rollup.js +0 -231
  590. package/dist/clients/source-filter.js +0 -596
  591. package/dist/clients/source-walker.js +0 -211
  592. package/dist/clients/spawn-output-cap.js +0 -120
  593. package/dist/clients/spawn-timeout-cooldown.js +0 -110
  594. package/dist/clients/stale-marker.js +0 -17
  595. package/dist/clients/startup-scan.js +0 -400
  596. package/dist/clients/startup-timing.js +0 -130
  597. package/dist/clients/string-utils.js +0 -33
  598. package/dist/clients/subagent-mode.js +0 -111
  599. package/dist/clients/symbol-containment.js +0 -24
  600. package/dist/clients/symbol-types.js +0 -5
  601. package/dist/clients/test-runner-client.js +0 -2507
  602. package/dist/clients/test-runner-delivery.js +0 -287
  603. package/dist/clients/todo-scanner.js +0 -229
  604. package/dist/clients/tool-agreement.js +0 -423
  605. package/dist/clients/tool-config.js +0 -249
  606. package/dist/clients/tool-cwd.js +0 -270
  607. package/dist/clients/tool-definition.js +0 -47
  608. package/dist/clients/tool-event.js +0 -105
  609. package/dist/clients/tool-policy.js +0 -2755
  610. package/dist/clients/tool-probe.js +0 -53
  611. package/dist/clients/tool-render.js +0 -156
  612. package/dist/clients/tool-set-policy.js +0 -118
  613. package/dist/clients/tree-sitter-cache.js +0 -364
  614. package/dist/clients/tree-sitter-client.js +0 -4195
  615. package/dist/clients/tree-sitter-logger.js +0 -100
  616. package/dist/clients/tree-sitter-navigator.js +0 -269
  617. package/dist/clients/tree-sitter-query-loader.js +0 -569
  618. package/dist/clients/tree-sitter-shared.js +0 -158
  619. package/dist/clients/tree-sitter-symbol-extractor.js +0 -1265
  620. package/dist/clients/trivy-client.js +0 -467
  621. package/dist/clients/tui-fit.js +0 -50
  622. package/dist/clients/turn-context.js +0 -52
  623. package/dist/clients/turn-end/lane.js +0 -51
  624. package/dist/clients/turn-end/lanes/govulncheck.js +0 -112
  625. package/dist/clients/turn-end/lanes/secrets.js +0 -204
  626. package/dist/clients/turn-summary-render.js +0 -72
  627. package/dist/clients/turn-summary.js +0 -132
  628. package/dist/clients/typos-config.js +0 -29
  629. package/dist/clients/user-notify.js +0 -51
  630. package/dist/clients/vanished-instance-marker.js +0 -57
  631. package/dist/clients/warm-attach.js +0 -305
  632. package/dist/clients/widget-state.js +0 -1808
  633. package/dist/clients/word-index-logger.js +0 -49
  634. package/dist/clients/word-index-store.js +0 -459
  635. package/dist/clients/word-index.js +0 -2080
  636. package/dist/clients/workspace-topology.js +0 -443
  637. package/dist/clients/write-ordering-guard.js +0 -65
  638. package/dist/clients/zizmor-config.js +0 -340
  639. package/dist/i18n.js +0 -69
  640. package/dist/mcp/build-staleness.js +0 -124
  641. package/dist/scripts/lib/process-scan.mjs +0 -583
  642. package/dist/scripts/lib/skills-predicate.mjs +0 -129
  643. package/dist/scripts/lib/web-tree-sitter-dir.mjs +0 -123
  644. package/dist/tools/activate-tools.js +0 -87
  645. package/dist/tools/ast-grep-outline.js +0 -137
  646. package/dist/tools/ast-grep-replace.js +0 -244
  647. package/dist/tools/ast-grep-search.js +0 -762
  648. package/dist/tools/effective-config.js +0 -90
  649. package/dist/tools/lens-diagnostic-mark.js +0 -375
  650. package/dist/tools/lens-diagnostics.js +0 -2571
  651. package/dist/tools/lsp-diagnostics.js +0 -1745
  652. package/dist/tools/lsp-navigation.js +0 -1367
  653. package/dist/tools/lsp-structured-output.js +0 -294
  654. package/dist/tools/module-report.js +0 -382
  655. package/dist/tools/project-report.js +0 -86
  656. package/dist/tools/render-compact.js +0 -374
  657. package/dist/tools/scan-progress.js +0 -53
  658. package/dist/tools/shared.js +0 -29
  659. package/dist/tools/symbol-search.js +0 -155
package/docs/features.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ### LSP Support
4
4
 
5
- pi-lens includes **46 language server definitions** (including four cross-cutting *auxiliary* scanners that attach alongside the file's language server — Opengrep, ast-grep, zizmor, and typos — see below). LSP is **enabled by default**; use `--no-lsp` to disable it for a session. Servers are auto-discovered from PATH, project `node_modules`, and managed installs. When a server is not installed, pi-lens offers an interactive install prompt.
5
+ pi-lens includes **48 language server definitions** (including four cross-cutting *auxiliary* scanners that attach alongside the file's language server — Opengrep, ast-grep, zizmor, and typos — see below). LSP is **enabled by default**; use `--no-lsp` to disable it for a session. Servers are auto-discovered from PATH, project `node_modules`, and managed installs. When a server is not installed, pi-lens offers an interactive install prompt.
6
6
 
7
7
  **LSP Idle Management:** LSP servers shut down after 240 seconds of inactivity (no files modified) to free resources. The timer resets when you resume editing, preventing cold-start penalties during active development.
8
8
 
@@ -19,7 +19,7 @@ pi-lens includes **46 language server definitions** (including four cross-cuttin
19
19
  - **`capabilities`** — shows which operations are supported by the active LSP server(s) for a file, read directly from the cached `initialize` response (no round-trip).
20
20
  - **Symbol column resolution** — passing `symbol: "myFunc"` instead of an exact `character` position resolves the correct column automatically. Use `symbol: "foo#2"` for the second occurrence of `foo` on the line.
21
21
 
22
- LSP servers for: TypeScript, Deno, Python (pyright/basedpyright + jedi), Go, Rust, Ruby (ruby-lsp + solargraph), PHP, PowerShell, C# (omnisharp), F#, Java (JDT LS, with Lombok javaagent support when a Lombok jar is available), Kotlin, Swift, Dart, Lua, C/C++, Zig, Haskell, Elixir, Gleam, Typst (tinymist), Markdown (marksman), OCaml, Clojure, CUE (syntax and parse diagnostics; evaluation errors via the cue-vet auxiliary runner), Terraform, Nix, Bash, Fish, CMake, Docker, YAML, JSON, HTML, TOML, Prisma, Vue, Svelte, CSS.
22
+ LSP servers for: TypeScript, Deno, Python (pyright/basedpyright + jedi), Go, Rust, Ruby (ruby-lsp + solargraph), PHP, PowerShell, C# (omnisharp), F#, Java (JDT LS, with Lombok javaagent support when a Lombok jar is available), Kotlin, Swift, Dart, Lua, C/C++, Zig, Haskell, Elixir, Gleam, Typst (tinymist), Markdown (marksman), OCaml, Clojure, CUE (syntax and parse diagnostics; evaluation errors via the cue-vet auxiliary runner), Terraform, Nix, Bash, Shuck (zsh-aware shell language server), Fish, CMake, Docker, YAML, JSON, HTML, TOML, Prisma, Vue, Svelte, CSS.
23
23
 
24
24
  ### Formatters
25
25
 
@@ -109,6 +109,10 @@ the full behavior and honest limits.
109
109
 
110
110
  pi-lens builds a review graph (`file → symbol → dependency`) during session and uses it at turn end to render an impact cascade: which files were affected by a change and how diagnostics propagated through the dependency graph. Nodes track kind, language, and export status; edges track contains/imports/calls/references.
111
111
 
112
+ ### Knip at turn end and linked worktrees
113
+
114
+ knip follows git ignore rules (`.gitignore` and `.git/info/exclude`) and nothing else, so linked worktrees that live inside the project (for example `.worktrees/*`) are walked as project files: on a pi-lens clone with six of them, 83 percent of the project paths knip saw were worktree files, and a scan took 10.9 s cold and 3.1 s warm instead of 2.6 s and 0.6 s. pi-lens drops their issues from the verdict, runs knip in the worktree that owns an edit, and stops waiting for a root whose last two scans both outlasted the turn_end budget (the knip row then reads `reason: "scan-exceeds-budget"` and the ledger counts `turn-end-knip-nested-worktrees`). It does not edit your repository: to remove the cost, add `/.worktrees/` (or your worktree directory) to the project's `.gitignore`.
115
+
112
116
  ### Read-Before-Edit Guard
113
117
 
114
118
  pi-lens enforces a **read-before-edit** policy on all file writes and edits. Before allowing a `write` or `edit` tool call on an existing file, it verifies that the agent has previously read sufficient context:
@@ -118,7 +122,7 @@ pi-lens enforces a **read-before-edit** policy on all file writes and edits. Bef
118
122
  - **Out-of-range block** — blocks if the edit target lines fall outside the ranges previously read, ensuring the agent cannot modify code it hasn't seen
119
123
  - **Snapshot validation** — covered edit ranges are hash-checked against the lines the agent actually saw at read time; stale-range edits are rejected even when range coverage exists. Hash capture covers reads up to 3 000 lines
120
124
 
121
- Coverage is tracked across multiple reads: two reads of lines 1–100 and 101–200 together satisfy a full-file write. Symbol-expanded reads (small reads silently widened to the enclosing symbol via tree-sitter) count toward coverage at the symbol level. Markdown files generate a warning instead of blocking (edits outside the section-expanded read range are warned, not silently passed). Plain-text (`.txt`) and log (`.log`) files remain fully exempt.
125
+ Coverage is tracked across multiple reads: two reads of lines 1–100 and 101–200 together satisfy a full-file write. Symbol-expanded reads (small reads widened to the enclosing symbol via tree-sitter, labelled with a leading note) count toward coverage at the symbol level. Markdown files generate a warning instead of blocking (edits outside the section-expanded read range are warned, not silently passed). Plain-text (`.txt`) and log (`.log`) files remain fully exempt.
122
126
 
123
127
  Override for a single edit: `/lens-allow-edit <path>`
124
128
 
@@ -179,7 +183,7 @@ pi-lens MCP server expose the same shape to Claude Code / any MCP client.
179
183
 
180
184
  At `turn_end`, pi-lens writes `<project-data-dir>/cache/actionable-warnings.json` summarizing fixable warnings introduced by the current turn. This powers the optional conservative autofix at `agent_end`.
181
185
 
182
- `<project-data-dir>` is whatever `getProjectDataDir(cwd)` resolves to: `<project>/.pi-lens` only when that legacy directory already exists, otherwise `~/.pi-lens/projects/<project-slug>` (or a `PILENS_DATA_DIR` location). The turn-end advisory points at `lens_diagnostics mode=delta` first and names the resolved file second, so you never have to work the layout out by hand (#2521).
186
+ `<project-data-dir>` is whatever `getProjectDataDir(cwd)` resolves to: `<project>/.pi-lens` only when that legacy directory already exists when the process first resolves the root (a `.pi-lens` created mid-process takes effect at the next process start), otherwise `~/.pi-lens/projects/<project-slug>` (or a `PILENS_DATA_DIR` location). The turn-end advisory points at `lens_diagnostics mode=delta` first and names the resolved file second, so you never have to work the layout out by hand (#2521).
183
187
 
184
188
  **Report contents:**
185
189
 
@@ -230,6 +234,42 @@ One event per logical write batch (not per file) — e.g. a single eslint `--fix
230
234
 
231
235
  **Kill switch:** `PI_LENS_BUS_PUBLISH=0` disables publishing entirely (see `docs/environment-variables.md`). Publishing is fire-and-forget — a disabled/unavailable/throwing bus never affects the write path's own success or latency.
232
236
 
237
+ ### Bus Events — `pilens:format:*` (#673)
238
+
239
+ Deferred formatting has a separate lifecycle on the same `pi.events` bus:
240
+
241
+ ```
242
+ pilens:format:queued { v: 1, source: "pi-lens", filePath, cwd, tool, kinds,
243
+ ownerSessionId?, turnIndex?, batchId? }
244
+ pilens:format:start { v: 1, source: "pi-lens", cwd, paths, fileCount, kinds,
245
+ ownerSessionId?, turnIndex?, batchId? }
246
+ pilens:format:done { v: 1, source: "pi-lens", cwd, paths, fileCount, kinds,
247
+ ownerSessionId?, turnIndex?, batchId?, settled? }
248
+ ```
249
+
250
+ Paths and `cwd` are absolute, normalized strings. `queued` is emitted when a
251
+ file first enters the deferred queue; `start` is emitted when a non-empty
252
+ claimed format batch begins; and `done` is emitted after all formatters in that
253
+ batch and any late-write resyncs have settled. `paths: []` on `done` means the
254
+ batch changed no bytes. `batchId` is process-unique and monotonic across
255
+ coordinator generations, so
256
+ two same-millisecond reloads cannot share a lifecycle identity. A normal
257
+ `pilens:format:done` has `settled: true` (or omits the additive field for old
258
+ producers). If the formatter remains unsettled after the bounded hook/format
259
+ drain, pi-lens emits one terminal `pilens:format:done` with `settled: false`
260
+ and the still-pending paths, and records one `deferred-format-unsettled`
261
+ degradation for that batch. A later formatter write is resynced by the late
262
+ continuation and does not emit a second done event.
263
+ The session and turn fields let a listener match the lifecycle to its own
264
+ session and turn; consumers must not infer ownership from paths or timing.
265
+
266
+ These are visibility events, not a flush API. They are fire-and-forget and can
267
+ be absent when the bus is disabled, unwired, stale, or throws. Replaced-session
268
+ and aborted drains publish only for work they actually claim and finish; work
269
+ requeued for its owner is not
270
+ announced as done by the replacing session. The events are additive v1 schemas
271
+ and may gain optional fields without a version bump.
272
+
233
273
  **Fix provenance (#502):** `FilesTouchedPayload` gained an additive, optional `fixes` field so a diff/review consumer can distinguish a pi-lens-mechanical hunk from an agent edit:
234
274
 
235
275
  ```
@@ -294,7 +334,7 @@ Late-joiners are a non-problem in-process — extensions activate at `session_st
294
334
 
295
335
  ### Opportunistic Read Expansion
296
336
 
297
- When the agent reads a small slice of a file (≤ 60 lines), pi-lens transparently expands the read to the full enclosing symbol (function, method, or class) using the tree-sitter AST. The agent receives the full symbol as context, and the read guard records symbol-level coverage so edits anywhere within that symbol pass without requiring the agent to have read every line individually. Expansion runs within a 200 ms budget and falls back silently on unsupported file types or parse failures.
337
+ When the agent reads a small slice of a file (≤ 100 lines), pi-lens expands the read to the full enclosing symbol (function, method, or class) using the tree-sitter AST, or to the enclosing heading section of a Markdown file. The result starts with a `[pi-lens: read widened ...]` note naming the requested and the returned lines; a `limit` above 100 reads the exact range. Expansion is off with the read guard (`--no-read-guard` or `readGuard.enabled=false`). The agent receives the full symbol as context, and the read guard records symbol-level coverage so edits anywhere within that symbol pass without requiring the agent to have read every line individually. Expansion runs within a 200 ms budget and falls back silently on unsupported file types or parse failures.
298
338
 
299
339
  Supported: TypeScript, TSX, JavaScript, JSX, Python, Go, Rust, Ruby, Java, Kotlin, Dart, Elixir, C, C++, C#, PHP, Swift, Lua, OCaml, Zig, Bash.
300
340
 
@@ -33,6 +33,7 @@ Each runtime toggle is settable from the CLI *and* from `config.json`. The two a
33
33
  | `--lens-compact-tool-line` | `ui.compactToolLine` | `false` |
34
34
  | `--lens-compact-lsp-status` | `ui.compactLspStatus` | `false` |
35
35
  | `--lens-hide-lsp-status` | `ui.hideLspStatus` | `false` |
36
+ | `--lens-compact-widget` | `ui.compactWidget` | `false` |
36
37
  | `--no-lazy-tools` | `tools.lazy` | `true` |
37
38
  | `--lens-turn-end-madge` | `turnEnd.madge.enabled` | `false` |
38
39
  | `--no-knip` | `knip.enabled` | `true` |
@@ -262,7 +263,7 @@ not corrupt delta baselines.
262
263
 
263
264
  ### `maxProjectFiles`
264
265
 
265
- Single scale knob (default `2000`) that a large-but-healthy repo can raise to scale five independent size budgets together instead of tripping each one separately: the project-diagnostics scanner (0.25×, default 500 files), the review graph (0.5× up to a point, default 1,000 files — see below), the startup scan (1×, default 2,000 source files), jscpd (3×, default 6,000 directory entries), and the word index (3×, default 6,000 files). Raising it (e.g. to `5000`) scales all five proportionally. Each subsystem's own environment-variable override (e.g. `PI_LENS_REVIEW_GRAPH_MAX_FILES`, `PI_LENS_STARTUP_SCAN_MAX_ENTRIES`) still takes precedence over this knob when set, and a separate `PI_LENS_MAX_PROJECT_FILES` environment variable sits below `maxProjectFiles` but above the built-in default. See `clients/project-scale.ts` for the full ratio table and precedence order.
266
+ Single scale knob (default `2000`) that a large-but-healthy repo can raise to scale five independent size budgets together instead of tripping each one separately: the project-diagnostics scanner (0.25×, default 500 files), the review graph (0.5× up to a point, default 1,000 files — see below), the startup scan (1.25×, default 2,500 source files), jscpd (3×, default 6,000 directory entries), and the word index (3×, default 6,000 files). Raising it (e.g. to `5000`) scales all five proportionally. Each subsystem's own environment-variable override (e.g. `PI_LENS_REVIEW_GRAPH_MAX_FILES`, `PI_LENS_STARTUP_SCAN_MAX_ENTRIES`) still takes precedence over this knob when set, and a separate `PI_LENS_MAX_PROJECT_FILES` environment variable sits below `maxProjectFiles` but above the built-in default. See `clients/project-scale.ts` for the full ratio table and precedence order.
266
267
 
267
268
  Unlike the other four, the review graph's budget stops scaling flatly at 0.5× once `maxProjectFiles` climbs past 4,000 — it tapers toward a 5,000-file ceiling instead of growing unbounded (#775). Its higher per-file cold-build cost bounds this default file budget independently of the graph's disk-persist circuit-breaker, whose measured default is now 500,000 elements (#936; override with `PI_LENS_GRAPH_PERSIST_MAX_ELEMENTS`). An over-cap graph persists a centrality-ranked partial snapshot with explicit total-versus-persisted coverage; read-only orientation may use it, but incremental builds never reuse it as a complete base. Below the 4,000 threshold (which covers every typical/default-sized project) it's the same flat 0.5× ratio as before. See `reviewGraph.maxFiles` below for an explicit opt-in past the taper.
268
269
 
@@ -0,0 +1,94 @@
1
+ # Migration Guide: File I/O Lifecycle Bridge v1 → v2
2
+
3
+ **Tracking RFC:** [RFC 3654](rfcs/3654-unified-io-bridge-v2.md)
4
+ **Tracking Issue:** [apmantza/pi-lens#3654](https://github.com/apmantza/pi-lens/issues/3654)
5
+ **Applicability:** Producers interacting with pi-lens via `Symbol.for("pi-lens:read-bridge")` or `Symbol.for("pi-lens:mutation-bridge")`.
6
+
7
+ ---
8
+
9
+ ## 1. Who is Affected
10
+
11
+ This guide applies to authors and maintainers of pi coding-agent extensions, tools, and integrations that report file read or mutation events to `pi-lens` out-of-band:
12
+ - Multi-file editing extensions and hash-anchor tools.
13
+ - Custom LSP or code-generation harnesses operating outside native pi tool hooks.
14
+ - Internal callers transitioning from dual legacy bridge invocations to the unified v2 bridge.
15
+
16
+ ---
17
+
18
+ ## 2. What Remains Unchanged (Frozen v1 Compatibility)
19
+
20
+ Under **Decision D14** (Backward-Compatible Refinement):
21
+ - **Symbol Availability**: `Symbol.for("pi-lens:read-bridge")` and `Symbol.for("pi-lens:mutation-bridge")` continue to be mounted alongside v2 in the same first-wins pass.
22
+ - **Return Conventions**:
23
+ - `readBridge.recordRead(...)` returns `void`.
24
+ - `mutationBridge.recordMutation(...)` returns `boolean` (`true` if recorded, `false` if rejected).
25
+ - **Semantics & Keying**:
26
+ - Path arguments are accepted as strings without clobbering caller display paths.
27
+ - Map keys in `ReadGuard` and `CacheManager` are derived identically.
28
+ - No v1-valid call is re-keyed by upgrading `pi-lens`, and every v1 call keeps its return value.
29
+ - **Two recorded differences** (the v1 read shim now runs v2's `disk`-evidence read):
30
+ - A read of a file that is absent when the call lands records nothing; v1 recorded coverage for it. The drop is an `io-bridge-read-dropped` ledger row.
31
+ - A zero-line read (`requestedLimit: 0`) of a non-empty or unreadable file is still dropped, but its ledger row is `io-bridge-read-dropped` (subject `<consumer>:bookkeeping-error`) instead of `read-bridge-zero-line-dropped`.
32
+
33
+ ---
34
+
35
+ ## 3. Call-to-Call Mapping
36
+
37
+ | Operation | v1 Legacy Call | v2 Unified Call |
38
+ |---|---|---|
39
+ | **Read File Window** | `readBridge.recordRead({ filePath, requestedOffset: 10, requestedLimit: 20, consumer: "my-tool" })` | `ioBridge.record({ filePath, consumer: "my-tool", read: { ranges: [[10, 29]], evidence: "disk" } })` |
40
+ | **Read Entire File** | `readBridge.recordRead({ filePath, requestedOffset: 1, consumer: "my-tool" })` | `ioBridge.record({ filePath, consumer: "my-tool", read: { ranges: [[1, lineCount]], content: inMemoryText } })` |
41
+ | **Partial Edit** | `mutationBridge.recordMutation({ filePath, editRanges: [[12, 15]], kind: "edit", importsChanged: false })` | `ioBridge.record({ filePath, mutate: { kind: "edit", ranges: [[12, 15]], importsChanged: false } })` |
42
+ | **Whole-File Write** | `mutationBridge.recordMutation({ filePath, kind: "write" })` | `ioBridge.record({ filePath, mutate: { kind: "write" } })` |
43
+ | **Atomic Edit + Read** | *Requires 2 separate calls to two different global symbols* | `ioBridge.record({ filePath, mutate: { kind: "edit", ranges: [[10, 15]] }, read: { ranges: [[5, 25]], content: previewText } })` |
44
+ | **File Deletion** | *Not supported in v1* | `ioBridge.record({ filePath, mutate: { kind: "delete" } })` |
45
+
46
+ ---
47
+
48
+ ## 4. Refinements in v2
49
+
50
+ | Feature | Category | Description |
51
+ |---|---|---|
52
+ | **Atomic Mutate-Before-Read** | `COMPATIBLE` | Compound `{ mutate, read }` calls guarantee `mutate` runs before `read`, so the preview read stays outstanding: a write marks the file's earlier reads consumed (evictable on idle), and the read that follows it is not. |
53
+ | **In-Memory Hash Evidence** | `OPT-IN` | Passing `content` (or `lineHashes`) hashes in memory, eliminating two synchronous `fs.readFileSync` calls per read (#3651). |
54
+ | **Coverage-Only Reads** | `OPT-IN` | Default `evidence: "caller"` records line range coverage in `ReadGuard` without reading or hashing disk. |
55
+ | **Explicit Zero-Line Reads** | `COMPATIBLE` | `ranges: []` records an empty/0-byte read without tripping staleness checks (#3652). |
56
+ | **Lifecycle Deletion** | `OPT-IN` | `mutate: { kind: "delete" }` verifies the file is absent from disk, evicts `readGuard` records, and notifies LSP DidClose / FileChangeType 3 without corrupting session state. |
57
+ | **Deferred Format Event Bus Parity** | `COMPATIBLE` | When `deferAutofix !== false`, queuing deferred formatting reliably emits `pilens:format:queued` on `pi.events`, warning in-process listeners before `agent_settled` rewrites. |
58
+
59
+ ---
60
+
61
+ ## 5. Recommended Migration Steps
62
+
63
+ 1. **Feature-Detect v2**:
64
+ ```typescript
65
+ import { getIOBridge, IO_BRIDGE_SYMBOL } from "pi-lens/clients/io-bridge"; // or via Symbol.for("pi-lens:io-bridge")
66
+
67
+ const ioBridge = (globalThis as any)[Symbol.for("pi-lens:io-bridge")];
68
+ if (ioBridge && ioBridge.version === 2) {
69
+ ioBridge.record({
70
+ filePath,
71
+ mutate: { kind: "edit", ranges: [[10, 20]] },
72
+ read: { ranges: [[1, 50]], content: fileBuffer },
73
+ });
74
+ } else {
75
+ // Graceful fallback to legacy v1 symbols
76
+ const mutBridge = (globalThis as any)[Symbol.for("pi-lens:mutation-bridge")];
77
+ mutBridge?.recordMutation({ filePath, editRanges: [[10, 20]], kind: "edit" });
78
+ const readBridge = (globalThis as any)[Symbol.for("pi-lens:read-bridge")];
79
+ readBridge?.recordRead({ filePath, requestedOffset: 1, requestedLimit: 50 });
80
+ }
81
+ ```
82
+
83
+ 2. **Leverage In-Memory Content**:
84
+ When reading or previewing diffs, supply `content: previewBuffer` in the `read` facet. This avoids redundant disk reads and makes preview verification resilient to external file timestamp drift.
85
+
86
+ 3. **Handle Deletions Explicitly**:
87
+ When removing a file, delete the file from the filesystem first, then record `mutate: { kind: "delete" }` to prevent zombie records in `ReadGuard`.
88
+
89
+ ---
90
+
91
+ ## 6. Drift Policy & Stability Guarantees
92
+
93
+ - **Shim Immutability**: The v1 shims mounted at `Symbol.for("pi-lens:read-bridge")` and `Symbol.for("pi-lens:mutation-bridge")` are strictly frozen compatibility layers. They will never adopt breaking changes or alter return types.
94
+ - **Process Singleton Guarantee**: The bridge is registered via `registerProcessBridge` (`clients/process-bridge.ts`), enforcing first-wins registration and `Object.freeze`. A running process cannot have its bridge mutated or replaced midway through a session.
@@ -77,7 +77,7 @@ refresh cannot merge until the marker is updated with it.
77
77
  |---|---|---|---|
78
78
  | **1 — pull** | `textDocument/diagnostic` returns an authoritative report (empty = clean) | YES, deterministic | rust-analyzer |
79
79
  | **2 — push, publishes-versioned** | `publishDiagnostics([])` **with version** on every scan, incl. clean→clean | YES, currency-proven via version | ast-grep |
80
- | **2\* — push, publishes-unversioned** | re-publishes on a clean scan but **version-less** — the wait still early-returns (the client accepts a version-less publish as fresh: it can't be proven stale), but currency is only *temporally correlated*, not proven | YES at runtime, with a staleness-risk caveat (not a latency cost) | opengrep |
80
+ | **2\* — push, publishes-unversioned** | re-publishes on a clean scan but **version-less** — the wait still early-returns (the client accepts a version-less publish as fresh: it can't be proven stale), but currency is only *temporally correlated*, not proven. Since #3484 the client fences a server measured to answer a `documentSymbol` fence before it publishes (`diagnosticsFence: "reply-first"`: yaml, intelephense): a pre-edit publish is dropped until the fence's reply. Every other 2\* server (docker publishes before answering; prisma, taplo, zls, dart, gleam, clojure unmarked) keeps this behaviour | YES at runtime, with a staleness-risk caveat (not a latency cost) | opengrep |
81
81
  | **3 — push, silent on clean** | server publishes nothing when nothing changed | **NO** — budget-wait floor (safe; a timeout is *not* a false clean). **This tier is #458's learned-deadline target set.** | typescript-language-server |
82
82
  | **Navigation-only — custom, no evidence** | custom `lsp.servers.*` entry has no pull provider and has not published in this session | **NO** — diagnostics are unsupported; skip the wait and report navigation-only | Dexter |
83
83
 
@@ -107,6 +107,28 @@ nightly steps, **dev** = the dev box (a row measured on both reads `dev+ci`).
107
107
  Merges never blank a prior good value, so a CI non-result leaves the dev
108
108
  classification standing.
109
109
 
110
+ Two bounded guards keep that preservation from hiding a dead instrument
111
+ (#3401). A `direct` `first-publish` cell whose axis the nightly probe does not
112
+ re-observe is stamped once with the date of its first miss and degrades to
113
+ `unknown` once five calendar days have elapsed since it (skipped nights do not
114
+ stall it, and a re-observation clears the stamp). `empty-first` cells are never
115
+ expired: they back the live `emptyFirstPublish` markers (php, terraform) and
116
+ expiring one would erase the measurement behind a marker. A `clean-behavior`/
117
+ `tier` change is written only after two consecutive nightly runs observe the
118
+ same new value, so one flapping nightly (ast-grep went 2 → 2* → 3 → 2* across
119
+ four runs) cannot rewrite a cell; a night that measured nothing for the lang
120
+ resets the hold. A subset probe (`probe-clean-signal.mjs <langs>`) leaves the
121
+ bookkeeping of the langs it did not probe untouched.
122
+
123
+ The bookkeeping lives in the generated `## Capability matrix refresh state`
124
+ section at the end of this doc, the only state the refresh persists. The clock
125
+ is the nightly run, not the bot PR's merge: each nightly starts from the last
126
+ `bot/lsp-docs-refresh` doc when that branch is ahead of master and was built on
127
+ master's current doc (`scripts/seed-matrix-from-bot-branch.mjs`), and from
128
+ master's doc otherwise (branch absent, squash-merged, or master edited the doc
129
+ since). Closing the bot PR unmerged does not reset the bookkeeping: the branch
130
+ is kept and keeps seeding, so only deleting `bot/lsp-docs-refresh` resets it.
131
+
110
132
  `vue`'s `clean-behavior` was hand-reset to `unknown` (#3390): its
111
133
  `publishes-unversioned` cell came from 58/45 publishes that the shared
112
134
  `extension.log` window had attributed to vue but that belonged to `tinymist`.
@@ -121,7 +143,7 @@ carries the named admission until then.
121
143
  | json | vscode-json-language-server | pull | — | n/a (pull) | 1 | dev+ci |
122
144
  | css | vscode-css-language-server | pull | — | n/a (pull) | 1 | dev+ci |
123
145
  | html | vscode-html-language-server | pull | — | n/a (pull) | 1 | dev+ci |
124
- | rust | rust-analyzer | pull | — | n/a (pull) | 1 | dev |
146
+ | rust | rust-analyzer | pull | — | n/a (pull) | 1 | dev+ci |
125
147
  | svelte | svelte-language-server | pull | — | n/a (pull) | 1 | dev+ci |
126
148
  | deno | deno (alt of typescript) | pull | — | n/a (pull) | 1 | dev+ci |
127
149
  | ruby | ruby-lsp | pull | — | n/a (pull) | 1 | ci |
@@ -134,12 +156,13 @@ carries the named admission until then.
134
156
  | yaml | yaml-language-server | push-only | publishes-unversioned | direct | 2* | dev+ci |
135
157
  | shell | bash-language-server | push-only | publishes-versioned | direct | 2 | dev+ci |
136
158
  | dockerfile | docker-langserver | push-only | publishes-unversioned | direct | 2* | dev+ci |
159
+ | dockerfile-official | docker-language-server (official) | push-only | unknown | empty-only | ? | dev+ci |
137
160
  | toml | taplo | push-only | publishes-unversioned | direct | 2* | dev+ci |
138
- | terraform | terraform-ls | push-only | TBD | TBD | 2/3? | dev+ci |
161
+ | terraform | terraform-ls | push-only | publishes-unversioned | empty-first | 2* | dev+ci |
139
162
  | prisma | @prisma/language-server | push-only | publishes-unversioned | direct | 2* | dev+ci |
140
163
  | php | intelephense | push-only | publishes-unversioned | empty-first | 2* | dev+ci |
141
164
  | zig | zls | push-only | publishes-unversioned | direct | 2* | dev+ci |
142
- | vue | @vue/language-server | push-only | unknown | direct | 2/3? | dev+ci |
165
+ | vue | @vue/language-server | push-only | unknown | unknown | 2/3? | dev+ci |
143
166
  | dart | dart language-server | push-only | publishes-unversioned | direct | 2* | ci |
144
167
  | gleam | gleam lsp | push-only | publishes-unversioned | direct | 2* | ci |
145
168
  | clojure | clojure-lsp | push-only | publishes-unversioned | direct | 2* | ci |
@@ -230,3 +253,13 @@ marker; a mismatch means the marker may need a human update (#529). `unknown`
230
253
  observations are never compared (a slow/absent server is not evidence either way).
231
254
 
232
255
  _None observed as of the last probe run._
256
+
257
+ ## Capability matrix refresh state (nightly-generated)
258
+
259
+ Bookkeeping for the date-based `direct` `first-publish` expiry (#3401), the
260
+ two-run `clean-behavior` hysteresis and the consecutive-night `idle-eviction`
261
+ counts (#3989). Regenerated every run; never a measurement.
262
+
263
+ ```json
264
+ {"clean-behavior":{"dockerfile-official":{"pendingBehavior":"publishes-versioned","pendingTier":"2","runs":1}},"idle-eviction":{"docker":{"nights":[{"day":"2026-10-07","rssMb":64,"coldMs":566}]},"json":{"nights":[{"day":"2026-10-07","rssMb":67,"coldMs":1116}]},"powershell":{"nights":[{"day":"2026-10-07","rssMb":155,"coldMs":2601}]},"python-jedi":{"nights":[{"day":"2026-10-07","rssMb":51,"coldMs":1796}]},"zizmor":{"nights":[{"day":"2026-10-07","rssMb":58,"coldMs":608}]}}}
265
+ ```
@@ -0,0 +1,124 @@
1
+ # LSP idle-eviction measurement
2
+
3
+ Per-server cost and safety of releasing an idle language-server client, measured
4
+ by the nightly so each server's `idleEviction` declaration in
5
+ `clients/lsp/server.ts` can be made from evidence (#3645). Generated by
6
+ `node scripts/measure-lsp-idle-eviction.mjs [--install]` (requires
7
+ `npm run build:dist`); it changes no server's policy.
8
+
9
+ For each registry server the probe spawns the server on its smoke fixture,
10
+ records the first diagnostics, then makes the server evictable in the probe
11
+ process only and lets the real idle-eviction timer release it. The next request
12
+ respawns it through the ordinary path. A server is `eligible` only when the
13
+ respawned server reports every finding it reported before eviction; the
14
+ `coverage` column is that comparison, and for an auxiliary scanner it is the
15
+ content-bound coverage check the auxiliary freeze depends on. A server that
16
+ cannot demonstrate it is never proposed for eviction on perf grounds alone.
17
+
18
+ _Last generated: 2026-10-07 on linux; 48 registry servers: 32 eligible, 0 vetoed, 2 inconclusive, 14 unavailable (0 not reached: budget)._
19
+
20
+ ## Per-server rows
21
+
22
+ Only stable columns are committed, so the nightly refresh changes this file
23
+ only when a server's outcome changes. The measured init duration, resident
24
+ memory of the server's process tree and post-eviction cold start are in the
25
+ nightly run's step log and job summary, one row per server. `n/a` means not
26
+ measured, never zero: **respawn** is whether the next request after eviction
27
+ brought the server back, **coverage** is whether the respawned server kept
28
+ every baseline finding.
29
+
30
+ A server that reports extra findings after the respawn (`widened`) still reads
31
+ `preserved`, because nothing was lost, but a first scan that grows on respawn
32
+ is a sign the baseline was partial. Any policy flip needs `preserved` on
33
+ several nights, not one; a `widened` disclosure is per run and is shown in the
34
+ step log only, because it flaps.
35
+
36
+ | server | role | declared | result | reason | respawn | coverage |
37
+ |---|---|---|---|---|---|---|
38
+ | ast-grep | auxiliary | unmeasured | eligible | · | ok | preserved |
39
+ | bash | primary | transparent | eligible | · | ok | preserved |
40
+ | clojure | primary | transparent | eligible | · | ok | preserved |
41
+ | cmake | primary | unmeasured | inconclusive | no-baseline | n/a | unproven |
42
+ | cpp | primary | transparent | eligible | · | ok | preserved |
43
+ | csharp | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
44
+ | css | primary | transparent | eligible | · | ok | preserved |
45
+ | cue | primary | unmeasured | eligible | · | ok | preserved |
46
+ | dart | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
47
+ | deno | primary | transparent | eligible | · | ok | preserved |
48
+ | docker | primary | unmeasured | eligible | · | ok | preserved |
49
+ | docker-official | primary | unmeasured | eligible | · | ok | preserved |
50
+ | elixir | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
51
+ | expert | primary | unmeasured | eligible | · | ok | preserved |
52
+ | fish | primary | transparent | eligible | · | ok | preserved |
53
+ | fsharp | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
54
+ | gleam | primary | unmeasured | eligible | · | ok | preserved |
55
+ | go | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
56
+ | haskell | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
57
+ | html | primary | transparent | eligible | · | ok | preserved |
58
+ | java | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
59
+ | json | primary | unmeasured | eligible | · | ok | preserved |
60
+ | kotlin | primary | unmeasured | eligible | · | ok | preserved |
61
+ | lua | primary | unmeasured | eligible | · | ok | preserved |
62
+ | marksman | primary | transparent | eligible | · | ok | preserved |
63
+ | nix | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
64
+ | ocaml | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
65
+ | omnisharp | primary | unmeasured | unavailable | no-fixture | n/a | n/a |
66
+ | opengrep | auxiliary | transparent | eligible | · | ok | preserved |
67
+ | php | primary | transparent | eligible | · | ok | preserved |
68
+ | powershell | primary | unmeasured | eligible | · | ok | preserved |
69
+ | prisma | primary | transparent | eligible | · | ok | preserved |
70
+ | python | primary | transparent | eligible | · | ok | preserved |
71
+ | python-jedi | primary | unmeasured | eligible | · | ok | preserved |
72
+ | ruby | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
73
+ | rust | primary | unmeasured | eligible | · | ok | preserved |
74
+ | shuck | primary | unmeasured | unavailable | server-not-started | n/a | n/a |
75
+ | svelte | primary | unmeasured | eligible | · | ok | preserved |
76
+ | swift | primary | unmeasured | unavailable | tool-unavailable | n/a | n/a |
77
+ | terraform | primary | unmeasured | eligible | · | ok | preserved |
78
+ | tinymist | primary | unmeasured | eligible | · | ok | preserved |
79
+ | toml | primary | unmeasured | eligible | · | ok | preserved |
80
+ | typescript | primary | transparent | eligible | · | ok | preserved |
81
+ | typos | auxiliary | unmeasured | eligible | · | ok | preserved |
82
+ | vue | primary | unmeasured | inconclusive | no-baseline | n/a | unproven |
83
+ | yaml | primary | transparent | eligible | · | ok | preserved |
84
+ | zig | primary | unmeasured | eligible | · | ok | preserved |
85
+ | zizmor | auxiliary | unmeasured | eligible | · | ok | preserved |
86
+
87
+ ## Declared versus measured
88
+
89
+ `drift` means the registry evicts a server the measurement vetoes. A `proposal`
90
+ or `info` line is for a maintainer to act on in a follow-up; this run changed
91
+ nothing.
92
+
93
+ - **ast-grep** [proposal] declared unmeasured but eviction and respawn preserved its findings
94
+ - **cue** [proposal] declared unmeasured but eviction and respawn preserved its findings
95
+ - **docker** [proposal] declared unmeasured but eviction and respawn preserved its findings
96
+ - **expert** [proposal] declared unmeasured but eviction and respawn preserved its findings
97
+ - **gleam** [proposal] declared unmeasured but eviction and respawn preserved its findings
98
+ - **json** [proposal] declared unmeasured but eviction and respawn preserved its findings
99
+ - **kotlin** [proposal] declared unmeasured but eviction and respawn preserved its findings
100
+ - **lua** [proposal] declared unmeasured but eviction and respawn preserved its findings
101
+ - **powershell** [proposal] declared unmeasured but eviction and respawn preserved its findings
102
+ - **python-jedi** [proposal] declared unmeasured but eviction and respawn preserved its findings
103
+ - **rust** [proposal] declared unmeasured but eviction and respawn preserved its findings
104
+ - **svelte** [proposal] declared unmeasured but eviction and respawn preserved its findings
105
+ - **terraform** [proposal] declared unmeasured but eviction and respawn preserved its findings
106
+ - **tinymist** [proposal] declared unmeasured but eviction and respawn preserved its findings
107
+ - **toml** [proposal] declared unmeasured but eviction and respawn preserved its findings
108
+ - **typos** [proposal] declared unmeasured but eviction and respawn preserved its findings
109
+ - **zig** [proposal] declared unmeasured but eviction and respawn preserved its findings
110
+ - **zizmor** [proposal] declared unmeasured but eviction and respawn preserved its findings
111
+
112
+ ## Reasons
113
+
114
+ - `no-fixture`: No smoke fixture routes to this server, so there is nothing to spawn.
115
+ - `tool-unavailable`: A tool this server's fixture needs could not be installed or found on the generating host.
116
+ - `setup-failed`: The fixture's workspace setup step failed.
117
+ - `server-not-started`: The fixture ran but this server never became a live client.
118
+ - `budget-exhausted`: The run's wall-clock budget ended before this server was reached.
119
+ - `probe-error`: The probe itself threw before it had a baseline.
120
+ - `no-baseline`: The server produced no finding on the fixture, so nothing can show its coverage survives eviction.
121
+ - `not-evicted`: The idle-eviction timer did not release the client within the bound.
122
+ - `client-died`: The client went away without an idle-eviction record, so the release was a crash, not the eviction path.
123
+ - `respawn-failed`: After eviction the next request could not bring the server back.
124
+ - `findings-narrowed`: After the respawn the server reported fewer findings than before eviction.
package/docs/mcp.md CHANGED
@@ -112,7 +112,7 @@ New files:
112
112
 
113
113
  | tool | maps to | purpose |
114
114
  |------|---------|---------|
115
- | `pilens_analyze` | `analyzeFile` (warm) / worker (fresh) | run the per-edit pipeline on a file; returns diagnostics + timing. `mode: warm\|fresh`. **Correctness + mechanism probe.** |
115
+ | `pilens_analyze` | `analyzeFile` (warm) / worker (fresh) | run the per-edit pipeline on a file; returns diagnostics + timing. `mode: warm\|fresh`. **Correctness + mechanism probe.** Each `latency.runners[]` row carries `failureKind` when the runner set one: `failed` + `blocking_diagnostics` is a run whose findings failed the check; `failed` with any other kind, or none, is a runner that produced no usable result. |
116
116
  | `pilens_ast_grep_search` | `ast_grep_search` | AST-aware structural search. |
117
117
  | `pilens_ast_grep_replace` | `ast_grep_replace` | AST-aware structural replace. |
118
118
  | `pilens_diagnostics` | `lens_diagnostics` | session or LSP diagnostics, selected by `source`, `scope`, and `severity`. |
@@ -131,6 +131,17 @@ New files:
131
131
  | `pilens_symbol_search` | `symbol_search` | search the persisted symbol index. |
132
132
  | `pilens_turn_end` | turn lifecycle | settle turn-end work and return findings. |
133
133
 
134
+ Every tool's `inputSchema` (from `tools/list`) is also the set of argument keys
135
+ the dispatcher accepts without comment: an undeclared key is reported in the
136
+ result (a leading `Ignored unknown argument(s) ...` line, plus
137
+ `structuredContent.ignoredArguments`). An ignored key that leaves a required
138
+ input missing, or that is a declared parameter the call did not send written
139
+ another way (`pilens_diagnostics {"filePath": ...}` for `path`; predicate in
140
+ [public-api-stability.md](public-api-stability.md)), turns the call into an error
141
+ instead of a run on defaults; a looser "did you mean" stays a warning (#3749;
142
+ details in [agent-tools.md](agent-tools.md)). The check is the one seam in
143
+ `mcp/server.ts` `tools/call`, through `mcp/tool-arguments.ts`.
144
+
134
145
  ## Packaging / wiring
135
146
 
136
147
  - `package.json`: add `"bin": { "pi-lens-mcp": "./dist/mcp/server.js" }`; add
@@ -383,9 +394,14 @@ be exercised + debugged directly through Claude Code without running pi.
383
394
  hook (reads the tool payload from stdin → `tool_input.path`/`file_path` + cwd)
384
395
  AND as a plain CLI (`--file=`). Defaults to `no-lsp` (FAST: ~1-2s, the cold
385
396
  LSP would cost ~5s/edit and under-report anyway — pull `pilens_analyze` on the
386
- warm server for type errors). Silent on clean files; advisory (always exit 0).
387
- `--hook` emits a PostToolUse `additionalContext` envelope; plain mode prints a
388
- report. 4 bin tests (CLI, --hook envelope, clean-file silence, stdin payload).
397
+ warm server for type errors). Silent on clean files. Clean scans and findings
398
+ exit 0; an invocation that cannot run reports its failure on stdout and stderr.
399
+ Plain CLI failures exit 2. `--hook`, stdin hook payloads, and `--turn-end` stay
400
+ advisory and exit 0, including on failure. `--hook` emits a PostToolUse
401
+ `additionalContext` envelope; plain mode and Stop hooks print text.
402
+ `pilens_health` reports failed invocation counts and the last operation,
403
+ timestamp, and bounded, redacted reason from the workspace status record.
404
+ These counters are best-effort history, not a current readiness verdict.
389
405
 
390
406
  Wire it in Claude Code `settings.json`:
391
407
 
@@ -443,7 +459,7 @@ be exercised + debugged directly through Claude Code without running pi.
443
459
  in the server, and concurrent turn-ends cannot race the turn-state clear.
444
460
  **Warm-only, no cold fallback**: only the server process owns the session state
445
461
  and pending turn work, so a local pass would report a false clean — no warm
446
- server means one stderr line, silent stdout, exit 0.
462
+ server means a skip reason on stdout and stderr, exit 0.
447
463
  The client waits 55s so it gives up inside Claude Code's 60s hook timeout.
448
464
  `SubagentStop` is deliberately NOT registered: subagent edits already fire
449
465
  PostToolUse into the shared turn-state, the consume bridges are one-shot (a
@@ -0,0 +1,77 @@
1
+ # Merge queue rollout
2
+
3
+ Adopting GitHub's merge queue for `master` (#3754). The repository side is in
4
+ the same change as this page; the settings below are the maintainer's step and
5
+ are deliberately not applied by any script or workflow.
6
+
7
+ ## Why
8
+
9
+ Every master move forced `gh pr update-branch` and a full CI re-run on every
10
+ open PR. A queue tests each PR merged onto the latest master, in order, so
11
+ neither is needed. Sharded Unit tests (#3753) keep one queue run short.
12
+
13
+ ## Repository side (already in this change)
14
+
15
+ - `ci.yml` and `lint.yml` run on `merge_group` (`types: [checks_requested]`).
16
+ Together they produce every required check: `Lint & type-check`,
17
+ `Unit tests`, `Install test (ubuntu-latest)`, `Install test (windows-latest)`,
18
+ `Install test (macos-latest)`, `knip`, `oxfmt format check`, `TLA+ models`.
19
+ - PR-only jobs (PR title, PR body, changelog fast-fail, targeted advisory) are
20
+ guarded by `github.event_name == 'pull_request'` and are skipped on
21
+ `merge_group`; none of them is required.
22
+ - `tests/config/merge-queue-workflows.test.ts` pins the trigger, the required
23
+ job names, and that no required job (or a job it `needs:`) is gated off on
24
+ `merge_group`.
25
+ - `scripts/ci-verdict.mjs` reports a queued PR as kind `in-queue` (exit 3) and
26
+ a failed queue run as a FAIL event.
27
+
28
+ ## Maintainer settings (Settings, Rules, Rulesets, New branch ruleset)
29
+
30
+ | Setting | Value | Why |
31
+ | --- | --- | --- |
32
+ | Ruleset name | `master merge queue` | |
33
+ | Enforcement status | Active | |
34
+ | Target branches | Include default branch (`master`) | |
35
+ | Require status checks to pass | the eight names above, source GitHub Actions | unchanged from branch protection today |
36
+ | Require branches to be up to date | off | the queue replaces it |
37
+ | Require merge queue | on | |
38
+ | Merge method | Merge commit | repo convention (`gh pr merge --merge`) |
39
+ | Build concurrency (maximum pull requests to build) | 3 | queue builds run three required-check sets at once on hosted runners |
40
+ | Minimum pull requests to merge | 1 | never hold a green PR waiting for company |
41
+ | Maximum pull requests to merge | 3 | a failing group costs at most three re-tests |
42
+ | Wait time to meet minimum group size | 1 minute | |
43
+ | Only merge non-failing pull requests | All commits must pass (`ALLGREEN`) | a red group member ejects only itself |
44
+ | Status check timeout | 30 minutes | the required set took about 10 minutes at the median and about 12 at the maximum over 30 runs before sharding; 30 minutes is 2.5x that |
45
+
46
+ Branch protection on `master` today is classic (no ruleset exists).
47
+ `scripts/ci-verdict.mjs` reads the live required-check names from classic
48
+ branch protection; if you move the required checks into the ruleset it falls
49
+ back to the static list (`Unit tests`, `Lint & type-check`) and still gates on
50
+ every non-advisory check-run from a PR/push run it discovers. Either keep the classic rule
51
+ (enable "Require merge queue" there) or accept the narrower absent-check
52
+ detection.
53
+
54
+ ## Rollout steps
55
+
56
+ 1. Merge #3753 (sharded Unit tests) first, then this change.
57
+ 2. Create the ruleset above.
58
+ 3. Enqueue one low-risk PR: `gh pr merge <N> --merge`.
59
+ 4. Confirm in `gh run list --event merge_group` that `CI` and `Lint` ran on the
60
+ `gh-readonly-queue/master/pr-<N>-<sha>` ref and that all seven required
61
+ checks reported there. A required check that never reports stalls the queue
62
+ until the 30-minute timeout.
63
+ 5. Stop using `gh pr update-branch` and "re-arm" pushes; both are moot and a
64
+ push to a queued PR ejects it.
65
+
66
+ ## Rollback
67
+
68
+ Disable the ruleset's "Require merge queue" rule. PRs merge directly again;
69
+ nothing in the repository needs reverting, because `merge_group` triggers and
70
+ the ci-verdict queue reads are inert without a queue.
71
+
72
+ ## Known remainder
73
+
74
+ The `train:approved` lane that merged through the REST merge API was retired
75
+ (#3837), so no competing lane holds a merge the queue would refuse. Every
76
+ merge goes through `gh pr merge` (auto-merge or direct), which the queue
77
+ intercepts when the base branch requires one.