@herbertgao/pi-extensions 2026.8.4 → 2026.8.6

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 (360) hide show
  1. package/README.md +5 -5
  2. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +11 -3
  3. package/node_modules/@herbertgao/pi-cc-extensions/README.md +11 -3
  4. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +24 -0
  5. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +91 -1
  6. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +7 -3
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +74 -5
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +7 -6
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +21 -12
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +4 -5
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +53 -14
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +22 -12
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +2 -4
  14. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  15. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +18 -0
  16. package/node_modules/@herbertgao/pi-subagents/package.json +8 -4
  17. package/node_modules/@herbertgao/pi-subagents/src/agent-color.ts +72 -67
  18. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +255 -0
  19. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +191 -3
  20. package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +20 -4
  21. package/node_modules/@herbertgao/pi-subagents/src/index.ts +289 -113
  22. package/node_modules/@herbertgao/pi-subagents/src/output-file.ts +24 -1
  23. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +24 -2
  24. package/node_modules/@herbertgao/pi-subagents/src/ui/fleet-list.ts +15 -6
  25. package/node_modules/@herbertgao/pi-subagents/src/ui/schedule-menu.ts +9 -8
  26. package/node_modules/@herbertgao/pi-subagents/src/ui/select-item.ts +48 -0
  27. package/node_modules/@herbertgao/pi-subagents/src/worktree.ts +9 -5
  28. package/node_modules/@juicesharp/rpiv-ask-user-question/README.md +2 -0
  29. package/node_modules/@juicesharp/rpiv-ask-user-question/ask-user-question.ts +20 -0
  30. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/hosts.md +6 -0
  31. package/node_modules/@juicesharp/rpiv-ask-user-question/docs/keyboard.md +7 -0
  32. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  33. package/node_modules/@juicesharp/rpiv-ask-user-question/state/build-questionnaire.ts +7 -0
  34. package/node_modules/@juicesharp/rpiv-ask-user-question/state/key-router.ts +16 -5
  35. package/node_modules/@juicesharp/rpiv-ask-user-question/state/questionnaire-session.ts +4 -2
  36. package/node_modules/@narumitw/pi-btw/README.md +32 -24
  37. package/node_modules/@narumitw/pi-btw/package.json +6 -6
  38. package/node_modules/@narumitw/pi-btw/src/btw.ts +4 -2
  39. package/node_modules/@narumitw/pi-btw/src/menu.ts +34 -13
  40. package/node_modules/@narumitw/pi-btw/src/settings.ts +22 -2
  41. package/node_modules/pi-lens/CHANGELOG.md +2535 -954
  42. package/node_modules/pi-lens/README.md +13 -0
  43. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +73 -18
  44. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +314 -0
  45. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +21 -4
  46. package/node_modules/pi-lens/dist/clients/agent-nudge.js +14 -7
  47. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +68 -16
  48. package/node_modules/pi-lens/dist/clients/ast-grep-types.js +0 -1
  49. package/node_modules/pi-lens/dist/clients/ast-grep-yaml-synth.js +37 -10
  50. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +63 -0
  51. package/node_modules/pi-lens/dist/clients/atomic-write.js +114 -14
  52. package/node_modules/pi-lens/dist/clients/bash-file-access.js +193 -23
  53. package/node_modules/pi-lens/dist/clients/biome-client.js +136 -24
  54. package/node_modules/pi-lens/dist/clients/bootstrap.js +11 -2
  55. package/node_modules/pi-lens/dist/clients/bounded-cache.js +34 -0
  56. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +192 -0
  57. package/node_modules/pi-lens/dist/clients/bus-events-logger.js +62 -6
  58. package/node_modules/pi-lens/dist/clients/bus-publish.js +19 -4
  59. package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +47 -5
  60. package/node_modules/pi-lens/dist/clients/cache-manager.js +97 -9
  61. package/node_modules/pi-lens/dist/clients/cache-observability.js +301 -14
  62. package/node_modules/pi-lens/dist/clients/call-graph.js +449 -117
  63. package/node_modules/pi-lens/dist/clients/cascade-format.js +57 -2
  64. package/node_modules/pi-lens/dist/clients/child-unref.js +85 -0
  65. package/node_modules/pi-lens/dist/clients/codebase-model.js +52 -23
  66. package/node_modules/pi-lens/dist/clients/collateral-test-role.js +40 -0
  67. package/node_modules/pi-lens/dist/clients/complexity-client.js +2 -1
  68. package/node_modules/pi-lens/dist/clients/console-guard-install.js +26 -0
  69. package/node_modules/pi-lens/dist/clients/cooperative-budget.js +42 -0
  70. package/node_modules/pi-lens/dist/clients/dead-code-client.js +137 -31
  71. package/node_modules/pi-lens/dist/clients/debug-handles.js +206 -0
  72. package/node_modules/pi-lens/dist/clients/debug-heap.js +167 -0
  73. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +153 -0
  74. package/node_modules/pi-lens/dist/clients/dependency-checker.js +361 -77
  75. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +65 -13
  76. package/node_modules/pi-lens/dist/clients/diagnostics-publish.js +18 -4
  77. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +176 -29
  78. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +23 -7
  79. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +8 -18
  80. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +8 -5
  81. package/node_modules/pi-lens/dist/clients/dispatch/indent-detect.js +35 -0
  82. package/node_modules/pi-lens/dist/clients/dispatch/inline-suppressions.js +17 -8
  83. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +1172 -683
  84. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +14 -0
  85. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +11 -1
  86. package/node_modules/pi-lens/dist/clients/dispatch/rule-id-normalize.js +50 -0
  87. package/node_modules/pi-lens/dist/clients/dispatch/rule-policy.js +135 -0
  88. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +23 -5
  89. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +5 -9
  90. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +3 -2
  91. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +2 -1
  92. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +154 -0
  93. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +3 -2
  94. package/node_modules/pi-lens/dist/clients/dispatch/runners/index.js +5 -1
  95. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +47 -6
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +4 -9
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +9 -5
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +4 -8
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +2 -3
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +2 -3
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +2 -1
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +2 -1
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +163 -0
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +37 -5
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +3 -1
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +13 -7
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +226 -0
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +69 -0
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/lazy-installer.js +3 -0
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +473 -42
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/spawn-outcome.js +22 -0
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +97 -0
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +5 -4
  114. package/node_modules/pi-lens/dist/clients/disposition-publish.js +18 -4
  115. package/node_modules/pi-lens/dist/clients/durable-store.js +97 -0
  116. package/node_modules/pi-lens/dist/clients/eval-timestamp.js +17 -0
  117. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +94 -3
  118. package/node_modules/pi-lens/dist/clients/extension-log.js +432 -0
  119. package/node_modules/pi-lens/dist/clients/extension-mode.js +73 -0
  120. package/node_modules/pi-lens/dist/clients/file-kinds.js +57 -0
  121. package/node_modules/pi-lens/dist/clients/file-role.js +18 -3
  122. package/node_modules/pi-lens/dist/clients/file-utils.js +56 -34
  123. package/node_modules/pi-lens/dist/clients/fix-worklog.js +5 -1
  124. package/node_modules/pi-lens/dist/clients/format-events-publish.js +51 -7
  125. package/node_modules/pi-lens/dist/clients/format-service.js +24 -8
  126. package/node_modules/pi-lens/dist/clients/formatters-lazy.js +8 -0
  127. package/node_modules/pi-lens/dist/clients/formatters.js +358 -61
  128. package/node_modules/pi-lens/dist/clients/generated-artifacts.js +148 -15
  129. package/node_modules/pi-lens/dist/clients/git-guard.js +678 -11
  130. package/node_modules/pi-lens/dist/clients/git-tracked-ignore.js +4 -0
  131. package/node_modules/pi-lens/dist/clients/go-client.js +23 -40
  132. package/node_modules/pi-lens/dist/clients/govulncheck-client.js +124 -7
  133. package/node_modules/pi-lens/dist/clients/grammar-source.js +12 -4
  134. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +21 -3
  135. package/node_modules/pi-lens/dist/clients/host-ports.js +31 -0
  136. package/node_modules/pi-lens/dist/clients/installer/index.js +395 -100
  137. package/node_modules/pi-lens/dist/clients/instance-reaper.js +142 -172
  138. package/node_modules/pi-lens/dist/clients/jscpd-client.js +27 -55
  139. package/node_modules/pi-lens/dist/clients/knip-client.js +58 -42
  140. package/node_modules/pi-lens/dist/clients/language-policy.js +14 -2
  141. package/node_modules/pi-lens/dist/clients/language-profile.js +13 -7
  142. package/node_modules/pi-lens/dist/clients/latency-logger.js +72 -1
  143. package/node_modules/pi-lens/dist/clients/lens-config.js +12 -1
  144. package/node_modules/pi-lens/dist/clients/lens-engine.js +86 -17
  145. package/node_modules/pi-lens/dist/clients/lens-events.js +63 -9
  146. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +16 -0
  147. package/node_modules/pi-lens/dist/clients/lens-map.js +94 -19
  148. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +73 -0
  149. package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -1
  150. package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +30 -4
  151. package/node_modules/pi-lens/dist/clients/lsp/cascade-tier.js +59 -14
  152. package/node_modules/pi-lens/dist/clients/lsp/client.js +662 -56
  153. package/node_modules/pi-lens/dist/clients/lsp/config.js +13 -2
  154. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +115 -0
  155. package/node_modules/pi-lens/dist/clients/lsp/edits.js +1012 -121
  156. package/node_modules/pi-lens/dist/clients/lsp/index.js +2025 -800
  157. package/node_modules/pi-lens/dist/clients/lsp/launch.js +32 -26
  158. package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
  159. package/node_modules/pi-lens/dist/clients/lsp/ruby-drive-dirs.js +83 -0
  160. package/node_modules/pi-lens/dist/clients/lsp/server.js +437 -86
  161. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +96 -0
  162. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +21 -5
  163. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +18 -3
  164. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +28 -4
  165. package/node_modules/pi-lens/dist/clients/lsp-lazy.js +8 -0
  166. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +248 -0
  167. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +127 -32
  168. package/node_modules/pi-lens/dist/clients/mcp/ipc.js +157 -24
  169. package/node_modules/pi-lens/dist/clients/mcp/session.js +235 -14
  170. package/node_modules/pi-lens/dist/clients/memory-sampler.js +115 -0
  171. package/node_modules/pi-lens/dist/clients/metrics-client.js +2 -1
  172. package/node_modules/pi-lens/dist/clients/metrics-history.js +2 -1
  173. package/node_modules/pi-lens/dist/clients/model-provider.js +53 -0
  174. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +5 -0
  175. package/node_modules/pi-lens/dist/clients/module-report.js +168 -3
  176. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +319 -118
  177. package/node_modules/pi-lens/dist/clients/opengrep-client.js +1 -1
  178. package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +120 -5
  179. package/node_modules/pi-lens/dist/clients/path-utils.js +110 -9
  180. package/node_modules/pi-lens/dist/clients/pipeline.js +76 -15
  181. package/node_modules/pi-lens/dist/clients/print-mode.js +21 -0
  182. package/node_modules/pi-lens/dist/clients/project-changes.js +40 -0
  183. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +3 -2
  184. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +1 -1
  185. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +8 -0
  186. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +23 -2
  187. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +21 -1
  188. package/node_modules/pi-lens/dist/clients/project-lens-config.js +86 -9
  189. package/node_modules/pi-lens/dist/clients/project-report.js +27 -13
  190. package/node_modules/pi-lens/dist/clients/project-snapshot.js +175 -20
  191. package/node_modules/pi-lens/dist/clients/project-trust.js +181 -0
  192. package/node_modules/pi-lens/dist/clients/quiet-window.js +18 -4
  193. package/node_modules/pi-lens/dist/clients/read-bridge.js +147 -0
  194. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +159 -1
  195. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +150 -29
  196. package/node_modules/pi-lens/dist/clients/read-guard.js +185 -4
  197. package/node_modules/pi-lens/dist/clients/resource-sampler.js +70 -84
  198. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +1122 -221
  199. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +2 -1
  200. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +21 -10
  201. package/node_modules/pi-lens/dist/clients/review-graph/query.js +24 -0
  202. package/node_modules/pi-lens/dist/clients/review-graph/symbol-id.js +46 -0
  203. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +57 -6
  204. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +51 -3
  205. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +30 -1
  206. package/node_modules/pi-lens/dist/clients/ruff-client.js +27 -44
  207. package/node_modules/pi-lens/dist/clients/run-duration.js +55 -0
  208. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +257 -77
  209. package/node_modules/pi-lens/dist/clients/runtime-context.js +129 -12
  210. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +242 -26
  211. package/node_modules/pi-lens/dist/clients/runtime-session.js +428 -117
  212. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +71 -48
  213. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +342 -33
  214. package/node_modules/pi-lens/dist/clients/runtime-turn.js +619 -93
  215. package/node_modules/pi-lens/dist/clients/rust-client.js +23 -38
  216. package/node_modules/pi-lens/dist/clients/safe-spawn.js +777 -62
  217. package/node_modules/pi-lens/dist/clients/security-scan-client.js +90 -6
  218. package/node_modules/pi-lens/dist/clients/session-state-store.js +3 -2
  219. package/node_modules/pi-lens/dist/clients/sg-runner.js +424 -196
  220. package/node_modules/pi-lens/dist/clients/slow-fs.js +2 -1
  221. package/node_modules/pi-lens/dist/clients/smells-rollup.js +231 -0
  222. package/node_modules/pi-lens/dist/clients/source-filter.js +184 -20
  223. package/node_modules/pi-lens/dist/clients/source-walker.js +66 -10
  224. package/node_modules/pi-lens/dist/clients/startup-scan.js +15 -16
  225. package/node_modules/pi-lens/dist/clients/startup-timing.js +7 -1
  226. package/node_modules/pi-lens/dist/clients/test-runner-client.js +469 -32
  227. package/node_modules/pi-lens/dist/clients/tool-event.js +35 -0
  228. package/node_modules/pi-lens/dist/clients/tool-policy.js +390 -39
  229. package/node_modules/pi-lens/dist/clients/tool-render.js +155 -0
  230. package/node_modules/pi-lens/dist/clients/tool-set-policy.js +76 -0
  231. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +6 -1
  232. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +419 -50
  233. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +21 -0
  234. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +7 -1
  235. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +7 -2
  236. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +44 -7
  237. package/node_modules/pi-lens/dist/clients/user-notify.js +51 -0
  238. package/node_modules/pi-lens/dist/clients/vanished-instance-marker.js +57 -0
  239. package/node_modules/pi-lens/dist/clients/warm-attach.js +50 -13
  240. package/node_modules/pi-lens/dist/clients/widget-state.js +300 -43
  241. package/node_modules/pi-lens/dist/clients/word-index.js +680 -81
  242. package/node_modules/pi-lens/dist/clients/workspace-topology.js +89 -6
  243. package/node_modules/pi-lens/dist/index.js +51785 -36118
  244. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +182 -29
  245. package/node_modules/pi-lens/dist/mcp/server.js +219 -46
  246. package/node_modules/pi-lens/dist/tools/activate-tools.js +17 -5
  247. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +9 -4
  248. package/node_modules/pi-lens/dist/tools/ast-grep-search.js +93 -27
  249. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +5 -2
  250. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +203 -38
  251. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +210 -42
  252. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +46 -3
  253. package/node_modules/pi-lens/dist/tools/module-report.js +9 -0
  254. package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -1
  255. package/node_modules/pi-lens/docs/agent-guide.md +40 -15
  256. package/node_modules/pi-lens/docs/agent-tools.md +21 -10
  257. package/node_modules/pi-lens/docs/analysisall.md +192 -0
  258. package/node_modules/pi-lens/docs/api-ports-inventory.md +165 -0
  259. package/node_modules/pi-lens/docs/ast-grep_rules_catalog.md +14 -3
  260. package/node_modules/pi-lens/docs/durable-store-audit-1202.md +32 -0
  261. package/node_modules/pi-lens/docs/environment-variables.md +44 -0
  262. package/node_modules/pi-lens/docs/fable.md +27 -0
  263. package/node_modules/pi-lens/docs/features.md +45 -3
  264. package/node_modules/pi-lens/docs/globalconfig.md +56 -1
  265. package/node_modules/pi-lens/docs/language-coverage.md +4 -3
  266. package/node_modules/pi-lens/docs/lsp-capability-matrix.md +2 -2
  267. package/node_modules/pi-lens/docs/mcp.md +37 -4
  268. package/node_modules/pi-lens/docs/servercapabilities.md +3 -3
  269. package/node_modules/pi-lens/docs/settings.md +18 -1
  270. package/node_modules/pi-lens/docs/tools.md +4 -1
  271. package/node_modules/pi-lens/docs/usage.md +41 -5
  272. package/node_modules/pi-lens/docs/word-index.md +35 -0
  273. package/node_modules/pi-lens/package.json +10 -10
  274. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-except-test.yml +49 -0
  275. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-bare-host-path-in-win32-branch-test.yml +87 -0
  276. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-chained-type-assertions-test.yml +8 -0
  277. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-js-test.yml +9 -0
  278. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-conditional-empty-object-spread-test.yml +9 -0
  279. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-nested-links-test.yml +11 -1
  280. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-raw-json-store-write-test.yml +17 -0
  281. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-js-test.yml +7 -0
  282. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-apply-test.yml +7 -0
  283. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-js-test.yml +8 -0
  284. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-reflect-get-test.yml +8 -0
  285. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-unknown-laundering-test.yml +11 -0
  286. package/node_modules/pi-lens/rules/ast-grep-rules/rule-tests/no-win32-isabsolute-for-qualification-test.yml +16 -0
  287. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-except.yml +3 -15
  288. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-bare-host-path-in-win32-branch.yml +25 -0
  289. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-chained-type-assertions.yml +21 -0
  290. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread-js.yml +21 -0
  291. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-conditional-empty-object-spread.yml +29 -0
  292. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-nested-links.yml +7 -0
  293. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-raw-json-store-write.yml +30 -0
  294. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply-js.yml +9 -0
  295. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-apply.yml +9 -0
  296. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get-js.yml +13 -0
  297. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-reflect-get.yml +16 -0
  298. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-unknown-laundering.yml +27 -0
  299. package/node_modules/pi-lens/rules/ast-grep-rules/rules/no-win32-isabsolute-for-qualification.yml +23 -0
  300. package/node_modules/pi-lens/rules/tree-sitter-queries/tsx/no-nested-links.yml +4 -6
  301. package/node_modules/pi-lens/rules/tree-sitter-queries/typescript/duplicate-function-arg.yml +2 -2
  302. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +134 -2
  303. package/node_modules/pi-lens/skills/pi-lens-ast-grep/SKILL.md +10 -11
  304. package/node_modules/pi-lens/skills/pi-lens-lsp-navigation/SKILL.md +22 -22
  305. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/SKILL.md +8 -114
  306. package/node_modules/pi-lens/skills/pi-lens-write-ast-grep-rule/reference.md +129 -0
  307. package/node_modules/pi-lens/skills/pi-lens-write-tree-sitter-rule/SKILL.md +3 -1
  308. package/node_modules/pi-mcp-adapter/CHANGELOG.md +38 -0
  309. package/node_modules/pi-mcp-adapter/README.md +38 -4
  310. package/node_modules/pi-mcp-adapter/agent-dir.ts +12 -4
  311. package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +1 -1
  312. package/node_modules/pi-mcp-adapter/cli.js +25 -4
  313. package/node_modules/pi-mcp-adapter/commands.ts +15 -7
  314. package/node_modules/pi-mcp-adapter/config.ts +4 -4
  315. package/node_modules/pi-mcp-adapter/direct-tools.ts +58 -8
  316. package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -8
  317. package/node_modules/pi-mcp-adapter/index.ts +8 -3
  318. package/node_modules/pi-mcp-adapter/init.ts +29 -5
  319. package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -4
  320. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +1 -2
  321. package/node_modules/pi-mcp-adapter/mcp-auth.ts +60 -2
  322. package/node_modules/pi-mcp-adapter/mcp-panel.ts +45 -9
  323. package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +22 -20
  324. package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +2 -1
  325. package/node_modules/pi-mcp-adapter/metadata-cache.ts +37 -4
  326. package/node_modules/pi-mcp-adapter/npx-resolver.ts +81 -26
  327. package/node_modules/pi-mcp-adapter/package.json +4 -3
  328. package/node_modules/pi-mcp-adapter/proxy-modes.ts +108 -26
  329. package/node_modules/pi-mcp-adapter/request-headers-command.ts +336 -0
  330. package/node_modules/pi-mcp-adapter/search-ranking.ts +86 -7
  331. package/node_modules/pi-mcp-adapter/server-manager.ts +41 -7
  332. package/node_modules/pi-mcp-adapter/session-recovery.ts +8 -2
  333. package/node_modules/pi-mcp-adapter/tool-approval.ts +48 -7
  334. package/node_modules/pi-mcp-adapter/tool-metadata.ts +62 -4
  335. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +138 -12
  336. package/node_modules/pi-mcp-adapter/types.ts +176 -27
  337. package/node_modules/pi-mcp-adapter/ui-server.ts +20 -1
  338. package/node_modules/pi-web-access/CHANGELOG.md +14 -0
  339. package/node_modules/pi-web-access/README.md +18 -12
  340. package/node_modules/pi-web-access/auth-fetch.ts +148 -0
  341. package/node_modules/pi-web-access/chrome-cookies.ts +110 -23
  342. package/node_modules/pi-web-access/curator-page.ts +5 -3
  343. package/node_modules/pi-web-access/curator-server.ts +2 -1
  344. package/node_modules/pi-web-access/extract.ts +106 -34
  345. package/node_modules/pi-web-access/fetch-params.ts +17 -3
  346. package/node_modules/pi-web-access/firecrawl.ts +172 -12
  347. package/node_modules/pi-web-access/gemini-search.ts +18 -4
  348. package/node_modules/pi-web-access/index.ts +120 -48
  349. package/node_modules/pi-web-access/package.json +2 -2
  350. package/node_modules/pi-web-access/summary-review.ts +11 -5
  351. package/node_modules/pi-web-access/youtube-extract.ts +2 -2
  352. package/package.json +12 -13
  353. package/node_modules/pi-lens/dist/clients/ast-grep-parser.js +0 -86
  354. package/node_modules/pi-lens/dist/clients/lsp/interactive-install.js +0 -367
  355. package/node_modules/pi-lens/dist/clients/lsp/lsp-index.js +0 -10
  356. package/node_modules/pi-lens/dist/clients/lsp/server-strategies.js +0 -5
  357. package/node_modules/pi-lens/dist/clients/project-metadata.js +0 -690
  358. package/node_modules/pi-lens/dist/clients/source-groups.js +0 -96
  359. package/node_modules/pi-lens/dist/clients/startup-marker.js +0 -6
  360. package/node_modules/pi-lens/dist/clients/types.js +0 -11
@@ -2,7 +2,7 @@
2
2
 
3
3
  <!-- GENERATED by scripts/gen-rule-catalogs.mjs — do not edit by hand. Run `npm run docs:rule-catalogs` after changing rules. -->
4
4
 
5
- pi-lens bundles **435 enabled** ast-grep rules (251 pi-lens-authored + 184 vendored from CodeRabbit) across **16 languages**, plus 16 disabled.
5
+ pi-lens bundles **446 enabled** ast-grep rules (262 pi-lens-authored + 184 vendored from CodeRabbit) across **16 languages**, plus 16 disabled.
6
6
 
7
7
  See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `rules/ast-grep-rules/rules/` (pi-lens), `rules/ast-grep-rules/coderabbit/rules/` (vendored).
8
8
 
@@ -133,7 +133,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
133
133
  | `use-of-sha1-java` | warning | CodeRabbit | Detected SHA1 hash algorithm which is considered insecure. SHA1 is not collision resistant and is therefore not suitable as a cryptographic… |
134
134
  | `weak-ssl-context-java` | warning | CodeRabbit | 'An insecure SSL context was detected. TLS versions 1.0, 1.1, and all SSL versions are considered weak encryption and are deprecated. Use S… |
135
135
 
136
- ### JavaScript (76)
136
+ ### JavaScript (79)
137
137
 
138
138
  | Rule | Severity | Source | Description |
139
139
  |---|---|---|---|
@@ -161,6 +161,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
161
161
  | `no-case-declarations-js` | error | pi-lens | Unexpected lexical declaration in case block — wrap in braces to restrict scope |
162
162
  | `no-compare-neg-zero-js` | error | pi-lens | Disallow comparing against -0 |
163
163
  | `no-cond-assign-js` | error | pi-lens | Expected a conditional expression and instead saw an assignment. |
164
+ | `no-conditional-empty-object-spread-js` | hint | pi-lens | Conditional empty-object spread — use an explicit if/else to omit fields |
164
165
  | `no-console-except-error-js` | warning | pi-lens | Avoid console.log/debug/warn in production code — use a logger or console.error inside catch only |
165
166
  | `no-constant-condition-js` | error | pi-lens | Unexpected constant condition |
166
167
  | `no-discarded-error-js` | error | pi-lens | new Error() result discarded — add 'throw' or assign to a variable |
@@ -180,6 +181,8 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
180
181
  | `no-new-wrappers-js` | error | pi-lens | Do not use 'new' with wrapper objects — use literal primitives instead |
181
182
  | `no-open-redirect-js` | error | pi-lens | Potential open redirect vulnerability — validate redirect URLs |
182
183
  | `no-prototype-builtins-js` | error | pi-lens | Use Object.hasOwn() or Object.prototype.hasOwnProperty.call() instead of calling methods directly on the object |
184
+ | `no-reflect-apply-js` | warning | pi-lens | Reflect.apply() — use a typed call (fn.apply(...) or fn(...args)) instead |
185
+ | `no-reflect-get-js` | warning | pi-lens | Reflect.get(obj, key) — use a typed property access (obj.prop or obj[key]) instead |
183
186
  | `no-single-promise-in-promise-methods-js` | warning | pi-lens | Promise.all/race with a single promise is unnecessary — await it directly |
184
187
  | `no-sql-in-code-js` | error | pi-lens | Raw SQL string in code — use query builder or ORM |
185
188
  | `no-throw-string-js` | error | pi-lens | Throw Error objects, not strings |
@@ -401,7 +404,7 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
401
404
  | `redundant-usestate-type` | info | pi-lens | `useState<TYPE>(...)` where TYPE is a primitive redundant — TS can infer it from the initial value |
402
405
  | `unnecessary-react-hook` | warning | pi-lens | Function with a `use*` name does not call any other React hook — rename to a plain function |
403
406
 
404
- ### TypeScript (117)
407
+ ### TypeScript (125)
405
408
 
406
409
  | Rule | Severity | Source | Description |
407
410
  |---|---|---|---|
@@ -429,9 +432,12 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
429
432
  | `no-await-expression-member` | hint | pi-lens | Unnecessary parentheses around await — write await expr.prop directly |
430
433
  | `no-await-in-promise-all` | error | pi-lens | Avoid await inside Promise.all — use Promise.all with an array of promises instead |
431
434
  | `no-await-in-promise-methods` | warning | pi-lens | Do not await inside Promise.all/allSettled — pass the promises directly |
435
+ | `no-bare-host-path-in-win32-branch` | warning | pi-lens | Use win32 path operations inside a branch committed to Windows path semantics |
432
436
  | `no-case-declarations` | error | pi-lens | Unexpected lexical declaration in case block — wrap in braces to restrict scope |
437
+ | `no-chained-type-assertions` | warning | pi-lens | Chained type assertion (x as A as B) — stacking assertions with no runtime check between them |
433
438
  | `no-compare-neg-zero` | error | pi-lens | Disallow comparing against -0 |
434
439
  | `no-cond-assign` | error | pi-lens | Expected a conditional expression and instead saw an assignment. |
440
+ | `no-conditional-empty-object-spread` | hint | pi-lens | Conditional empty-object spread — use an explicit if/else to omit fields |
435
441
  | `no-console-except-error` | warning | pi-lens | Avoid console.log/debug/warn in production code — use a logger or console.error inside catch only |
436
442
  | `no-constant-condition` | error | pi-lens | Unexpected constant condition |
437
443
  | `no-demeter-message-chain` | warning | pi-lens | Message chain (Law of Demeter) — navigating 3+ deep through accessors couples the caller to the whole path. |
@@ -456,6 +462,9 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
456
462
  | `no-open-redirect` | error | pi-lens | Potential open redirect vulnerability — validate redirect URLs |
457
463
  | `no-prototype-builtins` | error | pi-lens | Use Object.hasOwn() or Object.prototype.hasOwnProperty.call() instead of calling methods directly on the object |
458
464
  | `no-prototype-builtins-native` | hint | pi-lens | Use Object.hasOwn() instead of hasOwnProperty() — ES2022 standard |
465
+ | `no-raw-json-store-write` | warning | pi-lens | Use the atomic write seam for JSON stores instead of writeFileSync |
466
+ | `no-reflect-apply` | warning | pi-lens | Reflect.apply() — use a typed call (fn.apply(...) or fn(...args)) instead |
467
+ | `no-reflect-get` | warning | pi-lens | Reflect.get(obj, key) — use a typed property access (obj.prop or obj[key]) instead |
459
468
  | `no-relative-cross-package-import` | info | pi-lens | Avoid relative imports across package boundaries (../../). Use absolute imports (@app/..., @components/...) for better agent reasoning abou… |
460
469
  | `no-return-await` | warning | pi-lens | Unnecessary 'await' in return statement — use direct return instead |
461
470
  | `no-single-promise-in-promise-methods` | warning | pi-lens | Promise.all/race with a single promise is unnecessary — await it directly |
@@ -464,10 +473,12 @@ See [`docs/custom-rules.md`](custom-rules.md) to add your own. Rule sources: `ru
464
473
  | `no-throw-string` | error | pi-lens | Throw Error objects, not strings |
465
474
  | `no-typeof-undefined` | hint | pi-lens | Use === undefined instead of typeof x === 'undefined' |
466
475
  | `no-unimplemented-stub` | warning | pi-lens | Unimplemented stub — function was scaffolded but never completed |
476
+ | `no-unknown-laundering` | warning | pi-lens | type alias to bare 'unknown' — give the alias real shape or inline 'unknown' at the one call site that needs it |
467
477
  | `no-unnecessary-array-flat-depth` | hint | pi-lens | .flat(1) is the default depth — just use .flat() |
468
478
  | `no-useless-length-check` | warning | pi-lens | Use .some() instead of .filter().length check — short-circuits at first match |
469
479
  | `no-useless-promise-resolve-reject` | warning | pi-lens | Unnecessary Promise.resolve/reject wrapping — return the value directly |
470
480
  | `no-useless-rest-spread` | warning | pi-lens | Redundant spread into same container type — remove the extra spread |
481
+ | `no-win32-isabsolute-for-qualification` | warning | pi-lens | Use isFullyQualified for path qualification instead of win32.isAbsolute |
471
482
  | `node-rsa-weak-key-typescript` | warning | CodeRabbit | Use of RSA-$BITS, which is considered weak. Based on NIST standards, RSA keys should be at least 2048 bits. |
472
483
  | `node-sequelize-empty-password-argument-typescript` | warning | CodeRabbit | The application creates a database connection with an empty password. This can lead to unauthorized access by either an internal or externa… |
473
484
  | `node-sequelize-hardcoded-secret-argument-typescript` | warning | CodeRabbit | A secret is hard-coded in the application. Secrets stored in source code, such as credentials, identifiers, and other types of sensitive da… |
@@ -0,0 +1,32 @@
1
+ # Durable-store cross-process audit (#1202)
2
+
3
+ Atomic rename prevents torn files; it does not serialize read-modify-write. This
4
+ audit classifies stores reachable by extension, MCP, CLI, and subagent processes.
5
+ `<project>` means `getProjectDataDir(cwd)` and `<global>` means
6
+ `getGlobalPiLensDir()`.
7
+
8
+ | Store and path | Racing writers | Semantics | Risk | Existing mitigation / decision |
9
+ |---|---|---|---|---|
10
+ | Turn state — `<project>/turn-state.json` | extension, MCP, CLI; subagents use distinct owners | read-modify-write worklist | (a) impossible | **fixed here:** deferred-format writes now carry the pi session owner, and `clearTurnState` / `incrementTurnCycle` reject a foreign live owner just like `addModifiedRange`; MCP turn-end operations are FIFO-serialized. |
11
+ | Scanner caches — `<project>/cache/{scanner}.json` + `{scanner}.meta.json` | extension, MCP, CLI, subagents | overwrite-only scan result + freshness metadata | (b) possible, benign | none; a losing cache publication is recoverable on the next scan. Data is written before metadata, so interruption cannot make old data newly fresh; concurrent last-finisher wins. |
12
+ | Rule cache — `<project>/cache/{language}-rules-3.json` | all analysis processes | overwrite-only, content-hash validated | (a) impossible | rule hash rejects a cache for different inputs. |
13
+ | Workspace diagnostics — `<project>/cache/lsp-workspace-diagnostics.json` | extension/MCP/CLI sweeps and subagents | read-merge-overwrite cache | (b) possible, benign | mtime/content/dependency freshness rejects stale entries; a lost entry causes a rescan. Accepted benign. |
14
+ | Call graph — `<project>/cache/call-graph.json` + `.meta.json` | extension/MCP/CLI graph builds, subagents | overwrite-only derived graph | (b) possible, benign | source freshness validation; a loss rebuilds from source. Accepted benign. |
15
+ | Codebase model — `<project>/cache/codebase-model.json` + `.meta.json` | extension/MCP/CLI builds, subagents | overwrite-only derived model | (b) possible, benign | source/file-set validation; a loss rebuilds. Accepted benign. |
16
+ | Actionable-warning state — `<project>/cache/actionable-warning-state.json` | dispatches in every process | read-merge-overwrite behavior gate | (c) possible, harmful | **fixed here:** bounded exclusive pid lock, in-lock disk re-read, and per-warning merge preserve concurrent suppression fields before atomic replacement. |
17
+ | Actionable-warning history — `<project>/actionable-warnings.jsonl` | every dispatcher | append-only telemetry | (b) possible, benign | one append call per batch; malformed/truncated telemetry lines are ignored. Accepted benign. |
18
+ | Metrics history — `<project>/metrics-history.json` | session scans and `/lens-metrics` in every process | read-modify-overwrite trend cache | (c) possible, harmful | **accepted loss:** telemetry only; a race can leave a user-visible gap in trend history, but gaps are self-healing after the next scan restores the latest snapshot. Locking every passive capture or restructuring the established bounded JSON format is disproportionate to advisory history. |
19
+ | Project diagnostics — `<project>/cache/project-diagnostics.json` and `project-diagnostics-delta.json` | extension/MCP/CLI scans, subagents | overwrite-only derived snapshots | (b) possible, benign | per-file mtime filtering; next scan replaces loss. Accepted benign. |
20
+ | Worklog — `<project>/worklog.jsonl` | all dispatchers | append-only best-effort telemetry | (b) possible, benign | OS append operation per batch; readers skip malformed lines. Accepted benign. |
21
+ | Widget/read-guard session state — `<project>/sessions/{sessionId}.json` | one extension host per stable session id | overwrite-only session snapshot | (a) impossible | session-id sharding; read guard and widget are co-snapshotted atomically. |
22
+ | Diagnostic dispositions — `<project>/cache/diagnostic-dispositions.json` | extension, MCP, CLI tools, subagents | read-modify-write behavior gate | (c) possible, harmful | **fixed here:** exclusive pid lock, in-lock disk re-read, and per-anchor merge refuse stale whole-file promotion. |
23
+ | Recent touches — `<project>/recent-touches.json` | every extension/subagent publisher | read-append-overwrite bounded attribution ring | (b) possible, benign | explicitly best-effort nudge attribution; lost entries do not gate edits/checks and later touches replenish it. Accepted benign. |
24
+ | Instance registry — `<global>/instances.json` | every host/MCP/subagent process and reaper | read-modify-overwrite observability registry | (b) possible, benign | explicitly best-effort. Backstop orphan reaping intentionally kills untracked managed processes on dead-parent confirmation; missing registry entries allow this (intentional, #1267-adjacent; no fix needed). |
25
+ | Project snapshot — `<project>/cache/project-snapshot.json.gz` + `.meta.json` | extension/MCP/CLI builders, subagents | monotonic derived snapshot | (a) impossible | durable project sequence/source identity and generation-gated staged promotion; body embeds its seq so mismatched metadata is rejected. |
26
+ | Review graph + checkpoint — `<project>/cache/review-graph.json.gz`, `review-graph.checkpoint.json.gz` | extension/MCP/CLI builders, subagents | overwrite-only derived graph | (a) impossible | source signature/project-seq validation plus staged, generation-gated promotion; stale content is rejected on load. |
27
+ | Probe cache — `<global>/probe-cache.json` | every installer/prober | read-modify-write tool availability | (a) impossible | existing bounded cross-process lock + in-lock re-read/change merge (#1263). |
28
+ | Stop-hook status — OS temp `pi-lens-turn-end-*.json` | concurrent CLI Stop hooks | read-modify-overwrite counters | (b) possible, benign | atomic publication; explicitly bounded best-effort telemetry. Accepted benign. |
29
+
30
+ The grammar/WASM destination files are immutable content assets, not shared
31
+ mutable stores. Atomic staging artifacts are covered separately by the bounded
32
+ session-start stage GC and are not authoritative stores.
@@ -195,6 +195,33 @@ honored.
195
195
  Node cap for `/lens-map` (default 500). Graphs with more files keep only the
196
196
  highest-degree ones and render a visible truncation note.
197
197
 
198
+ ## Memory / idle eviction
199
+
200
+ Several in-memory caches release their contents after a period of inactivity so a
201
+ long-running session does not retain hydrated state indefinitely. Each has an
202
+ env-tunable window; all default to 20 minutes (`1200000` ms).
203
+
204
+ ### `PI_LENS_TS_IDLE_EVICT_MS`
205
+
206
+ Idle window (ms) after which TypeScript language-service clients release their
207
+ hydrated program and shut down, rebuilding transparently on the next request.
208
+ **Default:** 20 minutes (`1200000`).
209
+
210
+ ### `PI_LENS_WORD_INDEX_IDLE_EVICT_MS`
211
+
212
+ Idle window (ms) after which the persisted word index (`symbol_search`'s BM25
213
+ index) is released from memory. **Default:** 20 minutes (`1200000`).
214
+
215
+ ### `PI_LENS_PROJECT_SNAPSHOT_IDLE_EVICT_MS`
216
+
217
+ Idle window (ms) after which the cached project snapshot is released from
218
+ memory. **Default:** 20 minutes (`1200000`).
219
+
220
+ ### `PI_LENS_REVIEW_GRAPH_IDLE_EVICT_MS`
221
+
222
+ Idle window (ms) after which the in-memory review graph (`file → symbol →
223
+ dependency`) is released. **Default:** 20 minutes (`1200000`).
224
+
198
225
  ## Bus events
199
226
 
200
227
  ### `PI_LENS_BUS_PUBLISH`
@@ -213,6 +240,23 @@ misbehaves.
213
240
  Set to `1` for verbose installer/debug logging (same as `--debug`). Off by
214
241
  default.
215
242
 
243
+ ### `PI_LENS_DEBUG_HANDLES`
244
+
245
+ Set to `1` **before starting pi** to enable the handle-origin tracer
246
+ (institutionalized from the #1097 hand-rolled `async_hooks` investigation
247
+ that root-caused a leaked `setTimeout` keeping a `--print --no-session`
248
+ process alive). Read once at extension load — toggling it mid-session has no
249
+ effect. When set, pi-lens dumps `process.getActiveResourcesInfo()` counts by
250
+ resource type (plus per-type creation-site stack attribution, since the
251
+ `async_hooks` tracker only installs when the flag was already on at startup)
252
+ to `~/.pi-lens/debug-handles.log` at two points: `agent_settled` (after
253
+ quiet-window work is scheduled) and `session_shutdown` (after teardown —
254
+ whatever is still alive at that point is the leak). Off by default, and a
255
+ true no-op when unset — no writer, no `async_hooks` hook, zero overhead. Use
256
+ it to diagnose a pi process that won't exit: run once with the flag set,
257
+ reproduce the hang, then check `debug-handles.log`'s `session_shutdown`
258
+ entry for what's still holding the loop open.
259
+
216
260
  ### `PI_LENS_LOG_RETENTION_DAYS`
217
261
 
218
262
  Days to keep rotated logs before cleanup. **Default:** `7`.
@@ -138,3 +138,30 @@ inventory earning nothing. Feeding transitive impact into cascade neighbor
138
138
  selection is probably the highest-leverage *feature* work available — ideally
139
139
  paired with the #202 structural-hash short-circuit so the expansion prunes
140
140
  when a changed file's exported interface is unchanged.
141
+
142
+ ## OS-agnostic paths: classification is centralized, transformation isn't (#1193)
143
+
144
+ The path-*shape* layer is genuinely unified — `isWindowsPath`, the
145
+ `win32`-vs-`posix` shape-conditional idiom (confined to 4 files), `realpathSync`
146
+ (confined to `path-utils.ts`), `PathKeyedMap`, the `walkUpDirs` family, and the
147
+ `uriToPath`/`uriToDiskPath` LSP ingest boundary are all single-source and
148
+ defensively documented. The path-*transformation* layer is not: slash-folding
149
+ (`.replace(/\\/g, "/")`) is hand-rolled **138× across 83 files** with no shared
150
+ helper, `\r\n`-folding re-implements `normalizeToLF` in five files, and ephemeral
151
+ case/slash key-normalizers are copy-pasted in four (one of which case-folds but
152
+ forgets to slash-fold). That gap is why the *same* shape-2 defect keeps re-filing
153
+ under new numbers — #1150 → #1152 → #1161 → #1163 → #1194. Per-site
154
+ `isWindowsPath ? win32 : posix` conditionals treat symptoms; every new interior
155
+ `dirname`/`relative`/`isAbsolute` on a potentially-cross-shaped value is a fresh
156
+ latent instance. The tell: LSP URIs are the one axis with a real *ingest*
157
+ primitive, and the one axis not generating monthly bugs.
158
+
159
+ Highest-leverage move (**P1**, tracked in #1193): ship a `toPosix()` slash-fold
160
+ primitive and make it the only sanctioned form — it funnels the 138 sites *and*
161
+ makes a shape-2 ast-grep rule **possible** for the first time (today the idiom and
162
+ the bug are byte-identical, so #1158 can't distinguish them; an *un-migrated*
163
+ `.replace` after the primitive exists is detectable). Then push normalization to
164
+ the four ingest boundaries — **persisted-key rehydrate** (snapshot / word-index /
165
+ call-graph / review-graph symbol keys written on Windows, read on Linux CI) is the
166
+ hot one — so interior code can once again trust host-default `path` fns. Full P1–P5
167
+ plan + enforcement in #1193; the latest missed member fixed in #1194.
@@ -40,6 +40,34 @@ Repositories can disable all immediate and deferred auto-format mutations with
40
40
  keeping formatter detection, lint dispatch, LSP synchronization, and
41
41
  diagnostics available.
42
42
 
43
+ **Auto-fix timing depends on the tool.** A `write` (new file, full overwrite,
44
+ or a bash-authored write like `sed -i`/a redirect) still gets pipeline autofix
45
+ immediately, in the same tool result; when it changes the file, the result
46
+ carries the full authoritative post-fix content (capped at 2 MiB per file, one
47
+ shared budget across a multi-file bash write — past that it degrades to a
48
+ re-read warning). An `edit` defers autofix to `agent_end`, where it joins the
49
+ same per-file deferred-mutation queue as deferred formatting — one coalesced
50
+ record per file (`kinds: {autofix, format}`), autofix draining before format
51
+ so the final state is formatter-stable. A `write` immediately followed by an
52
+ `edit` on the same file in the same turn demotes the write's autofix to
53
+ deferred too. See `clients/pipeline.ts`, `clients/runtime-tool-result.ts`, and
54
+ `clients/runtime-agent-end.ts`.
55
+
56
+ Deferred formatting (the `agent_end` default) runs with **bounded
57
+ concurrency**: at most three formatter subprocesses in flight at once, with
58
+ results applied in admission order and cooperative yields between files, so a
59
+ large batch of queued files can't stall the event loop or the turn-end pass.
60
+
61
+ ### Commit/Push Guard (Experimental)
62
+
63
+ `--lens-guard` (also `guard.enabled: true` in `~/.pi-lens/config.json`) opts
64
+ into blocking `git commit`/`git push` while unresolved pi-lens blockers exist.
65
+ Detection covers normalized wrapper launchers, shell-escaped and
66
+ keyword/combined-flag verb forms, and shell substitutions, while literal text
67
+ in non-executing contexts remains allowed. Off by default; see
68
+ [docs/agent-guide.md](agent-guide.md) and [docs/settings.md](settings.md) for
69
+ the full behavior and honest limits.
70
+
43
71
  ### Review Graph - Cascade Diagnostics
44
72
 
45
73
  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.
@@ -140,7 +168,7 @@ When `actionableWarnings.autoFix.enabled` is set in global or project config (or
140
168
 
141
169
  ### Bus Events — `pilens:files:touched` (#482)
142
170
 
143
- pi-lens writes files **outside the agent's own tool calls**: dispatch autofix (biome/ruff/eslint/stylelint/sqlfluff/rubocop/ktlint/rust-clippy/dart-fix/golangci-lint/detekt/ktfmt/markdownlint/oxlint --fix) and formatter runs (immediate or deferred-at-`agent_end`) both mutate files after the fact, and the conservative actionable-warnings autofix above applies LSP quickfixes the same way. Other extensions in the same session that track file mutations are otherwise blind to those writes.
171
+ pi-lens writes files **outside the agent's own tool calls**: dispatch autofix (biome/ruff/eslint/stylelint/sqlfluff/rubocop/ktlint/ktfmt/rust-clippy/dart-fix/golangci-lint/detekt/markdownlint/oxlint --fix) mutates the file immediately for a `write` and at `agent_end` for a deferred `edit` (see "Formatters" above); formatter runs (immediate or deferred-at-`agent_end`) do the same; and the conservative actionable-warnings autofix above applies LSP quickfixes at `agent_end` the same way. Other extensions in the same session that track file mutations are otherwise blind to those writes — this event, published either way, is how they find out.
144
172
 
145
173
  pi-lens broadcasts them on pi's shared in-process event bus (`pi.events`, exposed to every extension via the `ExtensionAPI`) as a single named event:
146
174
 
@@ -317,9 +345,9 @@ pi-lens ships an MCP (Model Context Protocol) server so Claude Code — or any M
317
345
  | Layer | MCP tools | What they expose |
318
346
  |---|---|---|
319
347
  | **Per-edit** | `pilens_analyze`, `pilens_lsp_diagnostics`, `pilens_lsp_navigation`, `pilens_ast_grep_search`, `pilens_ast_grep_replace`, `pilens_module_report`, `pilens_read_symbol` | The fast pipeline (format → autofix → LSP diagnostics → parallel runners) plus the structured read-substitute pair. `analyze` accepts `mode: warm \| fresh` — `warm` reuses the server's in-process LSP, `fresh` forks a worker that loads freshly-built code from disk so the result reflects the latest commit. |
320
- | **Per-turn** | `pilens_turn_end` | Drives the **real** `handleTurnEnd` (knip incremental, jscpd delta, dep-circular, cascade, tests, actionable+code-quality warnings) — not a re-implementation. Caller-supplied edited files are auto-registered into turn-state via `addModifiedRange`. |
348
+ | **Per-turn** | `pilens_turn_end` | Drives the **real** `handleTurnEnd` (knip incremental, dep-circular, cascade, tests, actionable+code-quality warnings) — not a re-implementation. Caller-supplied edited files are auto-registered into turn-state via `addModifiedRange`. |
321
349
  | **Per-session** | `pilens_session_start` | Drives the **real** `handleSessionStart` — full jscpd/knip/madge/govulncheck/gitleaks/trivy scans + complexity baselines + LSP warm. The error-debt baseline is not currently populated by the production session-start path. |
322
- | **Project / observability** | `pilens_project_scan`, `pilens_diagnostics`, `pilens_health`, `pilens_latency`, `pilens_symbol_search` | Cheap project-wide scans, cached diagnostic state, latency telemetry, ranked identifier search (BM25 over the persisted word index — see [docs/word-index.md](word-index.md)). Cross-file blast radius now lives in `pilens_module_report`'s `blastRadius` option. |
350
+ | **Project / observability** | `pilens_project_scan`, `pilens_diagnostics`, `pilens_health`, `pilens_latency`, `pilens_symbol_search` | Cheap project-wide scans, cached diagnostic state, latency telemetry, ranked identifier search (BM25 over the persisted word index — see [docs/word-index.md](word-index.md)). Cross-file blast radius now lives in `pilens_module_report`'s `blastRadius` option. `pilens_health` (and its pi-side `/lens-health` counterpart) also reports a bounded, process-local **degradation ledger** — trust refusals, mode suppressions, LSP breaker trips, formatter skips/failures, TypeScript/word-index/review-graph/project-snapshot idle evictions, WASM aborts, and diagnostics-timeout tallies — so silently degraded behavior stays visible instead of vanishing into a log. |
323
351
  | **Lifecycle / loop** | `pilens_rebuild` | Runs `npm run build:dist` so `pilens_analyze mode=fresh` reflects the latest commit. Makes the review loop self-contained: commit → `pilens_rebuild` → `pilens_analyze mode=fresh` → `pilens_latency`. |
324
352
 
325
353
  **Honest limits** (live-tested, documented in `mcp.md`):
@@ -342,4 +370,18 @@ claude mcp add --scope user pi-lens \
342
370
  -- node <repo>/dist/mcp/server.js
343
371
  ```
344
372
 
373
+ **Hooks** (`settings.json`) close the loop: PostToolUse = per-edit, Stop = per-turn.
374
+
375
+ ```json
376
+ { "hooks": {
377
+ "PostToolUse": [
378
+ { "matcher": "Edit|Write",
379
+ "hooks": [ { "type": "command", "command": "pi-lens-analyze --hook" } ] } ],
380
+ "Stop": [
381
+ { "hooks": [ { "type": "command", "command": "pi-lens-analyze --turn-end", "timeout": 60 } ] } ]
382
+ } }
383
+ ```
384
+
385
+ The per-edit hook falls back to a cold local analysis when no server is up; the `Stop` hook is **warm-server-only** because only the server process owns the session state and pending turn work. It skips with a single stderr line when unavailable. Workspace IPC requests are ordered, so a timed-out PostToolUse client cannot let `Stop` overtake analysis still running in the server. `SubagentStop` is deliberately not registered because subagent edits already reach turn-state through PostToolUse.
386
+
345
387
  The full design + tier-by-tier progress (and known limits) lives in [`docs/mcp.md`](docs/mcp.md). Status: **experimental** — the foundation is solid (transport, warm LSP, lifecycle handlers wired), but the surface is still maturing. Use the pi extension for production agent work; reach for the MCP server for debugging, dogfooding, and direct Claude Code access.
@@ -24,6 +24,18 @@ Each runtime toggle is settable from the CLI *and* from `config.json`. The two a
24
24
  | `--lens-actionable-warning-actions` | `actionableWarnings.includeLspCodeActions` | `false` |
25
25
  | `--lens-actionable-warning-autofix` | `actionableWarnings.autoFix.enabled` | `false` |
26
26
  | `--lens-actionable-warning-all` | `actionableWarnings.deltaOnly` (`false`) | `true` |
27
+ | `--lens-compact-tool-line` | `ui.compactToolLine` | `false` |
28
+ | `--no-lazy-tools` | `tools.lazy` | `true` |
29
+
30
+ By default pi-lens registers six situational tools (the `ast_grep_*` family,
31
+ `lsp_navigation`, `lens_diagnostic_mark`) inactive and exposes a small loader,
32
+ `pi_lens_activate_tools`, that the model calls to activate the ones it needs.
33
+ `--no-lazy-tools` turns that off: every pi-lens tool is active from the first
34
+ turn and pi-lens never changes the tool list. Use it if you would rather spend
35
+ the tokens of a longer tool list than have the list change mid-session. The
36
+ loader tool is still registered and still describes itself as activating
37
+ inactive tools; under this flag those tools are already active, so calling it
38
+ does nothing.
27
39
 
28
40
  Keys are positive (`"enabled": true` means the feature runs), so a `--no-*` flag corresponds to setting its key `false`. A `no-*` flag on the command line is a one-way switch: it can disable, never re-enable, so `--no-lsp` wins over `lsp.enabled: true` but nothing on the CLI overrides `lsp.enabled: false`. Set the key back to `true` to re-enable.
29
41
 
@@ -167,10 +179,52 @@ Note: `maxProjectFiles` (below) is discovered differently — via an upward walk
167
179
 
168
180
  ### `rules`
169
181
 
170
- Per-rule threshold overrides. Currently honored:
182
+ Per-rule threshold overrides and policy filters. Currently honored:
171
183
 
172
184
  - `high-complexity.threshold` — cyclomatic complexity (default `15`)
173
185
  - `high-fan-out.threshold` — distinct function calls (default `20`)
186
+ - `<id>.disable` — disable diagnostics for the listed rule ids (output-only
187
+ filter). Same rule-id normalization as `pi-lens-ignore`: a user lists
188
+ `no-eval` once and the filter covers `no-eval`, `ast-grep:no-eval`, and
189
+ `no-eval-js`. Side effect: a rule whose real name genuinely ends in `-js`
190
+ (e.g. `prefer-js`) is conflated with its stem (`prefer`) — disabling or
191
+ selecting one also disables or selects the other.
192
+ - `<id>.select` — allowlist of rule ids; only the listed rule ids survive
193
+ filtering. Disable wins over select project-wide, even when the two lists
194
+ are configured under different keys.
195
+
196
+ The `<id>` key is a grouping label only — it does not scope which rules the
197
+ `disable`/`select` list underneath it can match. Matching is **project-wide**:
198
+ every `disable` list across every key is unioned into one drop list, and
199
+ every `select` list across every key is unioned into one allowlist. So
200
+ `"security": { "disable": ["no-eval"] }` disables `no-eval` regardless of
201
+ `security` being the rule's own id, and two keys can each contribute to the
202
+ same select union.
203
+
204
+ ```json
205
+ {
206
+ "rules": {
207
+ "high-complexity": { "threshold": 25 },
208
+ "high-fan-out": { "threshold": 30 },
209
+ "no-eval": { "disable": ["no-eval", "no-eval-js", "ast-grep:no-eval"] },
210
+ "my-rule-set": { "select": ["rule-a", "rule-b"] }
211
+ }
212
+ }
213
+ ```
214
+
215
+ **Warning:** because select is project-wide, a non-empty `select` list
216
+ *anywhere* in `rules` silences every rule not in that list, across the whole
217
+ project — including tsc/eslint findings, not just the rule types you're
218
+ thinking about when you write it. It's a big hammer; reach for `disable`
219
+ instead unless you actually want an allowlist over everything. Findings that
220
+ carry no rule id at all (an eslint parse error, for example) are exempt from
221
+ select, so an allowlist can never hide them.
222
+
223
+ Disable and select are output-only filters applied AFTER inline suppression,
224
+ disposition, and dedup — the project-level policy never widens the trusted
225
+ surface area (widget state, baseline, dedup cache stay authoritative). The
226
+ baseline still records the full unfiltered set so a project-config edit does
227
+ not corrupt delta baselines.
174
228
 
175
229
  ### `maxProjectFiles`
176
230
 
@@ -197,5 +251,6 @@ Explicit override for the review graph's own file budget (#775), for monorepos t
197
251
  - A malformed JSON file is logged once and treated as "no config" — your diagnostics never get blocked by a syntax error in your own config.
198
252
  - Rule thresholds must be positive finite numbers; invalid, zero, or negative values are logged once and ignored.
199
253
  - Mutation-control `enabled` values must be booleans; invalid values are logged once and ignored.
254
+ - `rules.<id>.disable` and `rules.<id>.select` must each be a non-empty array of non-empty strings; a non-array value, an empty array, or an all-whitespace array is logged once and the entry is dropped. A policy-only entry (no `threshold`) is honored. A policy entry with an invalid value still keeps any valid `threshold` alongside it.
200
255
  - The depth sub-threshold of `high-complexity` (default `6`) is intentionally not exposed; only the cyclomatic-complexity knob ships today to keep the schema tight.
201
256
  - The file is mtime-cached, so editing it takes effect on the next scan without restarting the agent.
@@ -20,8 +20,8 @@ Dispatch is diagnostics-oriented: automatic formatting and safe autofix happen i
20
20
  | HTML | ✓ | lsp, htmlhint | prettier |
21
21
  | YAML | ✓ | lsp, yamllint, actionlint (GitHub workflows) | prettier |
22
22
  | JSON | ✓ | lsp | biome, prettier |
23
- | Svelte | ✓ | lsp | — |
24
- | Vue | ✓ | lsp | — |
23
+ | Svelte | ✓ | lsp | oxfmt (needs `svelte` pkg installed + config `svelte: true`) |
24
+ | Vue | ✓ | lsp | prettier, oxfmt |
25
25
  | SQL | — | sqlfluff | sqlfluff |
26
26
  | Markdown | — | spellcheck, markdownlint, vale | prettier |
27
27
  | Docker | ✓ | lsp, hadolint | — |
@@ -42,7 +42,8 @@ Dispatch is diagnostics-oriented: automatic formatting and safe autofix happen i
42
42
  | Gleam | ✓ | lsp, gleam-check | gleam format |
43
43
  | OCaml | ✓ | lsp | ocamlformat |
44
44
  | Clojure | ✓ | lsp | cljfmt |
45
- | Terraform | ✓ | lsp, tflint | terraform fmt |
45
+ | Terraform | ✓ | lsp, tflint, trivy-config (opt-in) | terraform fmt |
46
+ | Terragrunt | — | terragrunt | terragrunt hcl fmt |
46
47
  | Nix | ✓ | lsp | nixfmt |
47
48
  | TOML | ✓ | lsp, taplo | taplo |
48
49
  | CMake | ✓ (cmake-language-server) | lsp | cmake-format |
@@ -18,7 +18,7 @@ regenerated docs — so this file self-populates from CI without manual copy-pas
18
18
 
19
19
  `probe-clean-signal.mjs` also runs a **drift check** (#529): it compares each
20
20
  probed server's observed `clean-behavior` against the hand-set `silentOnClean`
21
- marker in `clients/lsp/server-strategies.ts` and writes any mismatch to the
21
+ marker in `clients/lsp/wait-policy/strategies.ts` and writes any mismatch to the
22
22
  `## silentOnClean drift` section below. This is telemetry only — never a CI
23
23
  gate — because the probe is a timing-based negative observation; a mismatch
24
24
  just tells a human the marker may need updating. `unknown` observations are
@@ -150,7 +150,7 @@ the rest fill in as the nightly reaches them.
150
150
  ## silentOnClean drift (nightly-generated)
151
151
 
152
152
  Telemetry only — never a CI gate. Compares each probed server's observed
153
- `clean-behavior` against `clients/lsp/server-strategies.ts`'s `silentOnClean`
153
+ `clean-behavior` against `clients/lsp/wait-policy/strategies.ts`'s `silentOnClean`
154
154
  marker; a mismatch means the marker may need a human update (#529). `unknown`
155
155
  observations are never compared (a slow/absent server is not evidence either way).
156
156
 
@@ -378,13 +378,18 @@ be exercised + debugged directly through Claude Code without running pi.
378
378
  Wire it in Claude Code `settings.json`:
379
379
 
380
380
  ```json
381
- { "hooks": { "PostToolUse": [
382
- { "matcher": "Edit|Write",
383
- "hooks": [ { "type": "command", "command": "pi-lens-analyze --hook" } ] } ] } }
381
+ { "hooks": {
382
+ "PostToolUse": [
383
+ { "matcher": "Edit|Write",
384
+ "hooks": [ { "type": "command", "command": "pi-lens-analyze --hook" } ] } ],
385
+ "Stop": [
386
+ { "hooks": [ { "type": "command", "command": "pi-lens-analyze --turn-end", "timeout": 60 } ] } ]
387
+ } }
384
388
  ```
385
389
 
386
390
  (the cold-LSP fix means the type-check is honestly reported as skipped, not a
387
- false clean; the agent pulls `pilens_analyze` warm when it wants types.)
391
+ false clean; the agent pulls `pilens_analyze` warm when it wants types. The
392
+ `Stop` half is the per-turn pass — see the bullet below.)
388
393
 
389
394
  - [ ] **booboo** full-codebase review tool (`/lens-booboo` → handleBooboo:
390
395
  complexity, AI-slop, TODOs, dead-code, dupes, type-coverage).
@@ -410,6 +415,34 @@ be exercised + debugged directly through Claude Code without running pi.
410
415
  project. 5 IPC unit tests (path stability, named-pipe round-trip, no-server +
411
416
  error → undefined fallback); live-proven (server "warm analyze" log fired,
412
417
  bin returned the diagnostic). Removes the one real weakness of the push half.
418
+ - [x] **Stop hook → per-turn pass** (#538) — the `pi-lens-analyze` bin gains a
419
+ turn-end mode (`--turn-end`, or a Claude Code `Stop` payload on stdin), the
420
+ analogue of pi's `agent_end`: incremental knip/madge, dep-circular,
421
+ cascade-to-dependents, tests, actionable-warnings aggregation. PostToolUse has
422
+ already accumulated the edited files into turn-state by the time `Stop` fires,
423
+ so the hook passes no files and clears any inherited pi `sessionId` — turn-
424
+ end's stale-session eviction leaves the registered worklist alone. The request is a
425
+ tagged route (`{route:"turn-end"}`, own schema version) on the **workspace**
426
+ socket, not the PID-scoped one: a Stop hook knows its cwd, never the server's
427
+ pid. It rides in ahead of the parse, so it inherits the #535 build-staleness
428
+ gate for free, and an untagged analyze request on the same socket is byte-for-
429
+ byte unchanged. All workspace IPC requests share one server-side queue, so a
430
+ timed-out PostToolUse client cannot let `Stop` overtake analysis still running
431
+ in the server, and concurrent turn-ends cannot race the turn-state clear.
432
+ **Warm-only, no cold fallback**: only the server process owns the session state
433
+ and pending turn work, so a local pass would report a false clean — no warm
434
+ server means one stderr line, silent stdout, exit 0.
435
+ The client waits 55s so it gives up inside Claude Code's 60s hook timeout.
436
+ `SubagentStop` is deliberately NOT registered: subagent edits already fire
437
+ PostToolUse into the shared turn-state, the consume bridges are one-shot (a
438
+ subagent pass would eat the main agent's findings into a transcript nobody
439
+ reads), and the fan-out would multiply the heavy pass. Visibility, honestly:
440
+ Stop-hook stdout is user-visible in transcript mode (Ctrl-R), NOT model
441
+ context — blockers still gate commits through the retained lens-guard record,
442
+ and a `decision:"block"` render is a follow-up. Tests run fire-and-forget
443
+ inside turn-end, so the `Tests:` section you see is the *previous* turn's
444
+ failures. Unit, bin, and live-route smoke tests cover transport, ordering,
445
+ rendering, and spawned-server behavior.
413
446
 
414
447
  ## Transport decision — RESOLVED: hand-roll (zero new deps)
415
448
 
@@ -6,7 +6,7 @@ server's `initialize` handshake. Generated by `node scripts/server-capabilities.
6
6
  absent on the generating host are listed under *Unavailable* — run in a
7
7
  provisioned environment (the nightly) to capture those rows.
8
8
 
9
- _Last generated: 2026-08-01 on linux; 29 servers captured, 14 unavailable._
9
+ _Last generated: 2026-08-15 on linux; 29 servers captured, 14 unavailable._
10
10
 
11
11
  ## Diagnostic mode + navigation/edit operations
12
12
 
@@ -19,7 +19,7 @@ Legend: ✓ advertised, · not. **mode** = document diagnostics (`pull` = `textD
19
19
  | clojure | push-only | · | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 62 |
20
20
  | csharp | pull | ✓ | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 0 |
21
21
  | css | pull | · | ✓ | · | · | ✓ | ✓ | · | ✓ | · | ✓ | ✓ | · | · | 0 |
22
- | dart | push-only | · | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 16 |
22
+ | dart | push-only | · | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 18 |
23
23
  | deno | pull | · | ✓ | ✓ | · | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | 2 |
24
24
  | docker | push-only | · | ✓ | · | · | · | ✓ | ✓ | ✓ | · | · | ✓ | · | · | 0 |
25
25
  | expert | push-only | · | ✓ | · | · | ✓ | ✓ | · | ✓ | ✓ | ✓ | · | · | · | 2 |
@@ -89,7 +89,7 @@ surface, including providers pi-lens does not yet consume.
89
89
 
90
90
  - **ast-grep** (1): ast-grep.applyAllFixes
91
91
  - **clojure** (62): add-import-to-namespace, add-missing-import, add-missing-libspec, add-require-suggestion, as-to-refer, backward, backward-barf, backward-select, backward-slurp, change-coll, clean-ns, cond->if-refactor, create-function, create-test, cursor-info, cycle-coll, cycle-keyword-auto-resolve, cycle-privacy, demote-fn, destructure-keys, drag-backward, drag-forward, drag-param-backward, drag-param-forward, expand-let, extract-function, extract-to-def, forward, forward-barf, forward-select, forward-slurp, get-in-all, get-in-less, get-in-more, get-in-none, if->cond-refactor, inline-function, inline-symbol, introduce-let, kill-sexp, …
92
- - **dart** (16): dart.edit.codeAction.apply, dart.edit.sortMembers, dart.edit.organizeImports, dart.edit.fixAll, dart.edit.fixAllInWorkspace.preview, dart.edit.fixAllInWorkspace, dart.edit.sendWorkspaceEdit, refactor.perform, refactor.validate, dart.logAction, dart.refactor.add_constructor_name, dart.refactor.convert_all_formal_parameters_to_named, dart.refactor.convert_selected_formal_parameters_to_named, dart.refactor.move_selected_formal_parameters_left, dart.refactor.move_top_level_to_file, dart.refactor.remove_constructor_name
92
+ - **dart** (18): dart.edit.codeAction.apply, dart.edit.sortMembers, dart.edit.organizeImports, dart.edit.fixAll, dart.edit.fixAllInWorkspace.preview, dart.edit.fixAllInWorkspace, dart.edit.sendWorkspaceEdit, refactor.perform, refactor.validate, dart.logAction, dart.refactor.add_constructor_name, dart.refactor_add.import_prefix, dart.refactor.convert_all_formal_parameters_to_named, dart.refactor.convert_selected_formal_parameters_to_named, dart.refactor.move_selected_formal_parameters_left, dart.refactor.move_top_level_to_file, dart.refactor.remove_constructor_name, dart.refactor.remove_import_prefix
93
93
  - **deno** (2): deno.cache, deno.reloadImportRegistries
94
94
  - **expert** (2): Reindex, connectionDetails
95
95
  - **go** (47): gopls.add_dependency, gopls.add_import, gopls.add_telemetry_counters, gopls.add_test, gopls.apply_fix, gopls.assembly, gopls.change_signature, gopls.check_upgrades, gopls.client_open_url, gopls.diagnose_files, gopls.doc, gopls.edit_go_directive, gopls.extract_to_new_file, gopls.fetch_vulncheck_result, gopls.free_symbols, gopls.gc_details, gopls.generate, gopls.go_get_package, gopls.implement_interface, gopls.list_imports, gopls.list_known_packages, gopls.lsp, gopls.maybe_prompt_for_telemetry, gopls.mem_stats, gopls.modify_tags, gopls.modules, gopls.move_type, gopls.package_symbols, gopls.packages, gopls.regenerate_cgo, gopls.remove_dependency, gopls.reset_go_mod_diagnostics, gopls.run_go_work_command, gopls.run_govulncheck, gopls.run_tests, gopls.scan_imports, gopls.split_package, gopls.start_debugging, gopls.start_profile, gopls.stop_profile, …
@@ -60,6 +60,7 @@ column is the effective behavior when nothing is set.
60
60
  | `--no-tests` | `tests.enabled` | global | test runner **on** |
61
61
  | `--no-delta` | `delta.enabled` | global | delta mode **on** (new diagnostics only) |
62
62
  | `--lens-guard` | `guard.enabled` | global | **off** |
63
+
63
64
  | `--no-opengrep` | `opengrep.enabled` | global | Opengrep scanner **on** |
64
65
  | `--no-read-guard` | `readGuard.enabled` | global | read-before-edit monitor **on** |
65
66
  | `--no-lens-context` | `contextInjection.enabled` | global | context injection **on** |
@@ -68,6 +69,19 @@ column is the effective behavior when nothing is set.
68
69
  | `--lens-actionable-warning-actions` | `actionableWarnings.includeLspCodeActions` | global | **off** |
69
70
  | `--lens-actionable-warning-autofix` | `actionableWarnings.autoFix.enabled` | project | **off** |
70
71
  | `--lens-actionable-warning-all` | `actionableWarnings.deltaOnly` (`false`) | global | `deltaOnly` **on** (report this turn only) |
72
+ | `--lens-compact-tool-line` | `ui.compactToolLine` | global | **off** (two-row tool rendering) |
73
+ | `--no-lazy-tools` | `tools.lazy` | global | lazy tools **on** (six situational tools start inactive) |
74
+
75
+ `--no-lazy-tools` keeps every pi-lens tool active for the whole session, so the
76
+ advertised tool list never changes. The `pi_lens_activate_tools` loader stays
77
+ registered and keeps its usual description; under this flag the tools it names
78
+ are already active, so calling it is a no-op.
79
+
80
+ `--lens-guard` is **EXPERIMENTAL and strictly opt-in**. When enabled, actual
81
+ `git commit`/`git push` commands are blocked only for current, structured
82
+ blocking findings (including blocking test failures); advisory/no-action-required
83
+ findings do not block. Stale, malformed, or ambiguous persisted state blocks
84
+ conservatively until checks run again.
71
85
 
72
86
  `--immediate-format` and `--lens-actionable-warning-all` are not `--no-*` flags,
73
87
  so they set a value rather than flipping a boolean off.
@@ -87,6 +101,8 @@ field docs.
87
101
  | `actionableWarnings.autoFix.maxFixes` | global | `5` | Cap on quickfixes applied per turn (`0` = report only) |
88
102
  | `rules.high-complexity.threshold` | project | `15` | Cyclomatic-complexity threshold |
89
103
  | `rules.high-fan-out.threshold` | project | `20` | Distinct-function-call threshold |
104
+ | `rules.<id>.disable` | project | absent | Disable diagnostics for a rule (output-only filter, project-wide; same normalization as `pi-lens-ignore`) |
105
+ | `rules.<id>.select` | project | absent | Allowlist of rule ids (output-only filter, project-wide across every key; disable wins over select) |
90
106
  | `maxProjectFiles` | project | `2000` | Base scale knob; derives five subsystem size budgets |
91
107
  | `reviewGraph.maxFiles` | project | derived (clamped `100`–`20000`) | Explicit review-graph file budget |
92
108
  | `trivy.enabled` / `trivy.minSeverity` | project | off | Opt-in Trivy vulnerability scanning |
@@ -140,7 +156,8 @@ tolerated without warning; anything else is logged once as a likely typo.
140
156
  "ignore": ["**/*.test.ts", "vendor/**"],
141
157
  "rules": {
142
158
  "high-complexity": { "threshold": 25 },
143
- "high-fan-out": { "threshold": 30 }
159
+ "high-fan-out": { "threshold": 30 },
160
+ "no-eval": { "disable": ["no-eval", "ast-grep:no-eval", "no-eval-js"] }
144
161
  },
145
162
  "maxProjectFiles": 5000,
146
163
  "format": { "enabled": false }
@@ -5,7 +5,10 @@ pi-lens registers the following slash commands with the pi host:
5
5
  - `/lens-toggle` — toggle pi-lens on/off for the current session without restarting
6
6
  - `/lens-context-toggle` — toggle automatic context injection on/off for the session (tools/LSP/read-guard/formatting stay active)
7
7
  - `/lens-widget-toggle` — show/hide the pi-lens diagnostics widget below the editor
8
- - `/lens-health` — runtime health, latency, and diagnostic telemetry
8
+ - `/lens-health` — runtime health, latency, and diagnostic telemetry, including
9
+ bounded per-session degradation counts (trust refusals, LSP breakers,
10
+ formatter skips/failures, idle evictions, WASM aborts, timeout tallies, and
11
+ more)
9
12
  - `/lens-perf` — independent top-five p50 and p99 rankings for the current process session and machine-wide active latency-log window
10
13
  - `/lens-allow-edit <path>` — override the read-before-edit guard for a single edit
11
14
  - `/lens-tools` — tool installation status: globally installed, auto-installed, or npx fallback