@herbertgao/pi-extensions 2026.9.0 → 2026.9.2

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/node_modules/@czottmann/pi-automode/CHANGELOG.md +13 -1
  2. package/node_modules/@czottmann/pi-automode/README.md +20 -0
  3. package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +1 -1
  4. package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +2 -1
  5. package/node_modules/@czottmann/pi-automode/docs/defaults.md +3 -2
  6. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +38 -2
  7. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +5 -3
  8. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +11 -3
  9. package/node_modules/@czottmann/pi-automode/package.json +1 -1
  10. package/node_modules/@narumitw/pi-btw/README.md +57 -141
  11. package/node_modules/@narumitw/pi-btw/dist/index.ts +466 -41
  12. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +4 -4
  13. package/node_modules/@narumitw/pi-btw/docs/workflows.md +74 -0
  14. package/node_modules/@narumitw/pi-btw/package.json +2 -1
  15. package/node_modules/@narumitw/pi-btw/src/btw.ts +15 -1
  16. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +32 -2
  17. package/node_modules/@narumitw/pi-btw/src/keybindings.ts +330 -0
  18. package/node_modules/@narumitw/pi-btw/src/menu.ts +136 -19
  19. package/node_modules/@narumitw/pi-btw/src/settings.ts +32 -0
  20. package/node_modules/@narumitw/pi-btw/src/side-thread.ts +57 -5
  21. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +52 -30
  22. package/node_modules/@pi-plugins/fast-mode/README.md +5 -3
  23. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
  24. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +20 -55
  25. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
  26. package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
  27. package/node_modules/pi-lens/CHANGELOG.md +1072 -0
  28. package/node_modules/pi-lens/README.md +3 -0
  29. package/node_modules/pi-lens/config/biome/core.jsonc +11 -2
  30. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +13 -1
  31. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -9
  32. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +927 -80
  33. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +1 -1
  34. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +13 -4
  35. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +123 -3
  36. package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +60 -5
  37. package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +2 -9
  38. package/node_modules/pi-lens/dist/clients/ast-grep-types.js +2 -0
  39. package/node_modules/pi-lens/dist/clients/bash-file-access.js +133 -3
  40. package/node_modules/pi-lens/dist/clients/biome-client.js +9 -2
  41. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +14 -6
  42. package/node_modules/pi-lens/dist/clients/bootstrap.js +509 -73
  43. package/node_modules/pi-lens/dist/clients/bounded-cache.js +152 -12
  44. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +1 -1
  45. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +59 -9
  46. package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +113 -0
  47. package/node_modules/pi-lens/dist/clients/bus-events-logger.js +3 -11
  48. package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +31 -4
  49. package/node_modules/pi-lens/dist/clients/cache-manager.js +105 -6
  50. package/node_modules/pi-lens/dist/clients/cache-observability.js +40 -19
  51. package/node_modules/pi-lens/dist/clients/cargo-manifest.js +422 -0
  52. package/node_modules/pi-lens/dist/clients/cascade-logger.js +2 -9
  53. package/node_modules/pi-lens/dist/clients/child-unref.js +1 -19
  54. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +13 -3
  55. package/node_modules/pi-lens/dist/clients/complexity-client.js +16 -5
  56. package/node_modules/pi-lens/dist/clients/config-core/deny.js +221 -0
  57. package/node_modules/pi-lens/dist/clients/config-core/index.js +50 -0
  58. package/node_modules/pi-lens/dist/clients/config-core/merge.js +357 -0
  59. package/node_modules/pi-lens/dist/clients/config-core/normalize.js +340 -0
  60. package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +248 -0
  61. package/node_modules/pi-lens/dist/clients/config-core/provenance.js +164 -0
  62. package/node_modules/pi-lens/dist/clients/config-core/records.js +218 -0
  63. package/node_modules/pi-lens/dist/clients/config-core/resolve.js +125 -0
  64. package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +78 -0
  65. package/node_modules/pi-lens/dist/clients/config-core/schema.js +165 -0
  66. package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +281 -0
  67. package/node_modules/pi-lens/dist/clients/config-locations.js +160 -0
  68. package/node_modules/pi-lens/dist/clients/config-resolve.js +789 -0
  69. package/node_modules/pi-lens/dist/clients/config-schema.js +234 -0
  70. package/node_modules/pi-lens/dist/clients/config-warn.js +407 -0
  71. package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -14
  72. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +2 -6
  73. package/node_modules/pi-lens/dist/clients/deadline-utils.js +178 -0
  74. package/node_modules/pi-lens/dist/clients/debug-handles.js +2 -2
  75. package/node_modules/pi-lens/dist/clients/debug-heap.js +3 -3
  76. package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +106 -0
  77. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +113 -7
  78. package/node_modules/pi-lens/dist/clients/dependency-checker.js +8 -19
  79. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +1 -1
  80. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +12 -9
  81. package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +15 -5
  82. package/node_modules/pi-lens/dist/clients/dispatch/collect-later-tier.js +0 -4
  83. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +162 -44
  84. package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +97 -0
  85. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +27 -8
  86. package/node_modules/pi-lens/dist/clients/dispatch/lazy.js +0 -6
  87. package/node_modules/pi-lens/dist/clients/dispatch/pending-runner-findings.js +1 -1
  88. package/node_modules/pi-lens/dist/clients/dispatch/plan.js +0 -3
  89. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-complexity.js +2 -2
  90. package/node_modules/pi-lens/dist/clients/dispatch/rules/high-fan-out.js +1 -1
  91. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -1
  92. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +383 -27
  93. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -1
  94. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +4 -1
  95. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -1
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -1
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -1
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -1
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -1
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -1
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -1
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -1
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -1
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -1
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +1 -3
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -1
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -1
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -1
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +1 -2
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -1
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -1
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -1
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -1
  114. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -1
  115. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -1
  116. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +14 -18
  117. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -1
  118. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -1
  119. package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -1
  120. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +6 -3
  121. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +7 -4
  122. package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -1
  123. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +1 -2
  124. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -3
  125. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +1 -2
  126. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -1
  127. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +4 -3
  128. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -1
  129. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -1
  130. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -1
  131. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -1
  132. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -1
  133. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -1
  134. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -1
  135. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -1
  136. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -1
  137. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +3 -0
  138. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +3 -67
  139. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +194 -80
  140. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +84 -15
  141. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils.js +0 -21
  142. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -1
  143. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +2 -20
  144. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +1 -1
  145. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -1
  146. package/node_modules/pi-lens/dist/clients/dispatch/utils/format-utils.js +2 -2
  147. package/node_modules/pi-lens/dist/clients/disposition-logger.js +3 -10
  148. package/node_modules/pi-lens/dist/clients/effective-config.js +403 -0
  149. package/node_modules/pi-lens/dist/clients/error-class.js +23 -0
  150. package/node_modules/pi-lens/dist/clients/event-loop-hold.js +274 -0
  151. package/node_modules/pi-lens/dist/clients/event-loop-monitor.js +2 -2
  152. package/node_modules/pi-lens/dist/clients/extension-log.js +2 -2
  153. package/node_modules/pi-lens/dist/clients/feature-hints.js +2 -1
  154. package/node_modules/pi-lens/dist/clients/file-kinds.js +1 -38
  155. package/node_modules/pi-lens/dist/clients/file-time.js +7 -2
  156. package/node_modules/pi-lens/dist/clients/file-utils.js +117 -10
  157. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +50 -13
  158. package/node_modules/pi-lens/dist/clients/format-service.js +6 -2
  159. package/node_modules/pi-lens/dist/clients/formatters.js +385 -104
  160. package/node_modules/pi-lens/dist/clients/freshness-cadence.js +17 -0
  161. package/node_modules/pi-lens/dist/clients/generated-artifacts.js +116 -22
  162. package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -9
  163. package/node_modules/pi-lens/dist/clients/git-guard.js +6 -1
  164. package/node_modules/pi-lens/dist/clients/go-client.js +39 -0
  165. package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +252 -0
  166. package/node_modules/pi-lens/dist/clients/grammar-source.js +3 -3
  167. package/node_modules/pi-lens/dist/clients/hashline-anchor.js +424 -0
  168. package/node_modules/pi-lens/dist/clients/hook-budgets.js +76 -0
  169. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +5 -2
  170. package/node_modules/pi-lens/dist/clients/host-ports.js +1 -1
  171. package/node_modules/pi-lens/dist/clients/installer/index.js +289 -59
  172. package/node_modules/pi-lens/dist/clients/installer/managed-tool-refresh.js +84 -18
  173. package/node_modules/pi-lens/dist/clients/instance-reaper.js +110 -236
  174. package/node_modules/pi-lens/dist/clients/instance-registry.js +6 -3
  175. package/node_modules/pi-lens/dist/clients/language-profile.js +0 -9
  176. package/node_modules/pi-lens/dist/clients/language-registry.js +599 -0
  177. package/node_modules/pi-lens/dist/clients/latency-logger.js +165 -9
  178. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +34 -1
  179. package/node_modules/pi-lens/dist/clients/lens-config.js +160 -30
  180. package/node_modules/pi-lens/dist/clients/lens-engine.js +33 -41
  181. package/node_modules/pi-lens/dist/clients/lens-events.js +1 -1
  182. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +77 -6
  183. package/node_modules/pi-lens/dist/clients/lens-map.js +1 -1
  184. package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -38
  185. package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +3 -1
  186. package/node_modules/pi-lens/dist/clients/lsp/client.js +172 -33
  187. package/node_modules/pi-lens/dist/clients/lsp/config.js +484 -158
  188. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +1 -1
  189. package/node_modules/pi-lens/dist/clients/lsp/document-drift.js +1 -1
  190. package/node_modules/pi-lens/dist/clients/lsp/edits.js +18 -5
  191. package/node_modules/pi-lens/dist/clients/lsp/index.js +892 -96
  192. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +1 -1
  193. package/node_modules/pi-lens/dist/clients/lsp/language.js +18 -177
  194. package/node_modules/pi-lens/dist/clients/lsp/launch.js +2 -1
  195. package/node_modules/pi-lens/dist/clients/lsp/path-utils.js +1 -1
  196. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +5 -18
  197. package/node_modules/pi-lens/dist/clients/lsp/server.js +284 -147
  198. package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +116 -23
  199. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +2 -7
  200. package/node_modules/pi-lens/dist/clients/lsp/sync-kind.js +0 -1
  201. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +14 -7
  202. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/classification.js +6 -0
  203. package/node_modules/pi-lens/dist/clients/lsp/wait-policy/strategies.js +2 -1
  204. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +1 -1
  205. package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -1
  206. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +163 -21
  207. package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +36 -0
  208. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +33 -4
  209. package/node_modules/pi-lens/dist/clients/mcp/session.js +5 -16
  210. package/node_modules/pi-lens/dist/clients/memory-sampler.js +8 -3
  211. package/node_modules/pi-lens/dist/clients/metrics-history.js +28 -107
  212. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +3 -5
  213. package/node_modules/pi-lens/dist/clients/module-report.js +21 -46
  214. package/node_modules/pi-lens/dist/clients/mutating-tool.js +651 -0
  215. package/node_modules/pi-lens/dist/clients/mutation-attribution.js +368 -0
  216. package/node_modules/pi-lens/dist/clients/mutation-bridge.js +240 -0
  217. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +247 -24
  218. package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +101 -0
  219. package/node_modules/pi-lens/dist/clients/observed-mutation.js +1215 -0
  220. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +70 -28
  221. package/node_modules/pi-lens/dist/clients/opengrep-config.js +5 -1
  222. package/node_modules/pi-lens/dist/clients/package-manager.js +195 -26
  223. package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +359 -80
  224. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +23 -7
  225. package/node_modules/pi-lens/dist/clients/path-keyed-map.js +21 -2
  226. package/node_modules/pi-lens/dist/clients/path-utils.js +451 -15
  227. package/node_modules/pi-lens/dist/clients/performance-report.js +2 -2
  228. package/node_modules/pi-lens/dist/clients/persist-debounce.js +8 -1
  229. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +114 -0
  230. package/node_modules/pi-lens/dist/clients/pipeline.js +79 -18
  231. package/node_modules/pi-lens/dist/clients/probe-home-state.js +228 -0
  232. package/node_modules/pi-lens/dist/clients/process-bridge.js +66 -0
  233. package/node_modules/pi-lens/dist/clients/process-snapshot.js +68 -0
  234. package/node_modules/pi-lens/dist/clients/project-changes.js +1 -1
  235. package/node_modules/pi-lens/dist/clients/project-diagnostics/extractors.js +1 -1
  236. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +4 -3
  237. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/jscpd.js +1 -1
  238. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/knip.js +1 -1
  239. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/madge.js +1 -1
  240. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/opengrep.js +1 -1
  241. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +28 -4
  242. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +51 -20
  243. package/node_modules/pi-lens/dist/clients/project-lens-config.js +438 -122
  244. package/node_modules/pi-lens/dist/clients/project-scan-policy.js +3 -51
  245. package/node_modules/pi-lens/dist/clients/project-snapshot.js +52 -24
  246. package/node_modules/pi-lens/dist/clients/python-environment.js +217 -0
  247. package/node_modules/pi-lens/dist/clients/python-provenance.js +639 -0
  248. package/node_modules/pi-lens/dist/clients/quiet-window.js +6 -1
  249. package/node_modules/pi-lens/dist/clients/read-bridge.js +13 -21
  250. package/node_modules/pi-lens/dist/clients/read-expansion.js +9 -46
  251. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +16 -5
  252. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +364 -212
  253. package/node_modules/pi-lens/dist/clients/read-guard.js +26 -2
  254. package/node_modules/pi-lens/dist/clients/recent-touches.js +2 -2
  255. package/node_modules/pi-lens/dist/clients/resource-sampler.js +195 -96
  256. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +155 -114
  257. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +1 -1
  258. package/node_modules/pi-lens/dist/clients/review-graph/service.js +55 -3
  259. package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +7 -15
  260. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +10 -74
  261. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +9 -3
  262. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +19 -3
  263. package/node_modules/pi-lens/dist/clients/runtime-context.js +49 -16
  264. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +25 -6
  265. package/node_modules/pi-lens/dist/clients/runtime-session.js +184 -32
  266. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +179 -36
  267. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +797 -243
  268. package/node_modules/pi-lens/dist/clients/runtime-turn.js +1028 -53
  269. package/node_modules/pi-lens/dist/clients/rust-client.js +31 -0
  270. package/node_modules/pi-lens/dist/clients/safe-spawn.js +33 -10
  271. package/node_modules/pi-lens/dist/clients/sanitize.js +7 -12
  272. package/node_modules/pi-lens/dist/clients/scan-utils.js +1 -56
  273. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +1 -3
  274. package/node_modules/pi-lens/dist/clients/security-scan-client.js +3 -0
  275. package/node_modules/pi-lens/dist/clients/session-lifecycle.js +1 -1
  276. package/node_modules/pi-lens/dist/clients/session-start-observability.js +79 -0
  277. package/node_modules/pi-lens/dist/clients/session-summary.js +0 -24
  278. package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +12 -3
  279. package/node_modules/pi-lens/dist/clients/sgconfig.js +7 -6
  280. package/node_modules/pi-lens/dist/clients/shared-checkout-guard.js +1 -1
  281. package/node_modules/pi-lens/dist/clients/skills-resolver.js +105 -0
  282. package/node_modules/pi-lens/dist/clients/smells-rollup.js +4 -4
  283. package/node_modules/pi-lens/dist/clients/startup-scan.js +2 -10
  284. package/node_modules/pi-lens/dist/clients/string-utils.js +13 -0
  285. package/node_modules/pi-lens/dist/clients/subagent-mode.js +17 -4
  286. package/node_modules/pi-lens/dist/clients/test-runner-client.js +176 -39
  287. package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +244 -0
  288. package/node_modules/pi-lens/dist/clients/tool-definition.js +41 -1
  289. package/node_modules/pi-lens/dist/clients/tool-policy.js +92 -22
  290. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +40 -40
  291. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +87 -100
  292. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
  293. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +81 -1
  294. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +51 -46
  295. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +28 -0
  296. package/node_modules/pi-lens/dist/clients/tui-fit.js +0 -4
  297. package/node_modules/pi-lens/dist/clients/typos-config.js +5 -0
  298. package/node_modules/pi-lens/dist/clients/user-notify.js +6 -6
  299. package/node_modules/pi-lens/dist/clients/widget-state.js +191 -26
  300. package/node_modules/pi-lens/dist/clients/word-index-logger.js +2 -9
  301. package/node_modules/pi-lens/dist/clients/word-index-store.js +23 -12
  302. package/node_modules/pi-lens/dist/clients/word-index.js +252 -47
  303. package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -1
  304. package/node_modules/pi-lens/dist/clients/zizmor-config.js +4 -1
  305. package/node_modules/pi-lens/dist/index.js +65899 -55340
  306. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -1
  307. package/node_modules/pi-lens/dist/mcp/build-staleness.js +1 -1
  308. package/node_modules/pi-lens/dist/mcp/server.js +127 -5
  309. package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +583 -0
  310. package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +129 -0
  311. package/node_modules/pi-lens/dist/tools/effective-config.js +89 -0
  312. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +96 -25
  313. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +104 -86
  314. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +37 -16
  315. package/node_modules/pi-lens/dist/tools/lsp-structured-output.js +3 -3
  316. package/node_modules/pi-lens/dist/tools/render-compact.js +1 -1
  317. package/node_modules/pi-lens/dist/tools/shared.js +0 -1
  318. package/node_modules/pi-lens/dist/tools/symbol-search.js +1 -2
  319. package/node_modules/pi-lens/docs/agent-guide.md +64 -1
  320. package/node_modules/pi-lens/docs/configuration.md +222 -0
  321. package/node_modules/pi-lens/docs/dependencies.md +3 -3
  322. package/node_modules/pi-lens/docs/features.md +44 -5
  323. package/node_modules/pi-lens/docs/globalconfig.md +20 -0
  324. package/node_modules/pi-lens/docs/language-coverage.md +2 -2
  325. package/node_modules/pi-lens/docs/lsp-capability-matrix.md +9 -1
  326. package/node_modules/pi-lens/docs/pi-lens-fixer.md +25 -0
  327. package/node_modules/pi-lens/docs/pi-lens-investigator.md +25 -0
  328. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +33 -0
  329. package/node_modules/pi-lens/docs/pi-lens-subagent.md +49 -0
  330. package/node_modules/pi-lens/docs/pi-lens-warden.md +55 -0
  331. package/node_modules/pi-lens/docs/public-api-stability.md +359 -0
  332. package/node_modules/pi-lens/docs/release-qa-baseline.md +190 -0
  333. package/node_modules/pi-lens/docs/servercapabilities.md +7 -3
  334. package/node_modules/pi-lens/docs/subagent-compat.md +110 -30
  335. package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +2 -2
  336. package/node_modules/pi-lens/docs/word-index.md +1 -1
  337. package/node_modules/pi-lens/package.json +18 -35
  338. package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
  339. package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
  340. package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
  341. package/node_modules/pi-lens/rules/typos/_typos.toml +4 -2
  342. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +192 -1
  343. package/node_modules/pi-lens/scripts/install-selftest.mjs +58 -2
  344. package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +129 -0
  345. package/node_modules/pi-lens/scripts/lib/warm-loader-cache.mjs +1 -1
  346. package/node_modules/pi-lens/scripts/rpc-load-check.mjs +3 -1
  347. package/node_modules/pi-lens/scripts/warm-loader-cache.mjs +4 -2
  348. package/node_modules/pi-web-access/CHANGELOG.md +28 -0
  349. package/node_modules/pi-web-access/README.md +62 -15
  350. package/node_modules/pi-web-access/curator-page.ts +3 -1
  351. package/node_modules/pi-web-access/curator-server.ts +5 -1
  352. package/node_modules/pi-web-access/gemini-search.ts +8 -4
  353. package/node_modules/pi-web-access/github-extract.ts +242 -1
  354. package/node_modules/pi-web-access/index.ts +118 -64
  355. package/node_modules/pi-web-access/mistral-search.ts +281 -0
  356. package/node_modules/pi-web-access/package.json +2 -2
  357. package/node_modules/pi-web-access/perplexity.ts +14 -1
  358. package/node_modules/pi-web-access/utils.ts +23 -6
  359. package/node_modules/pi-web-access/xai-search.ts +96 -33
  360. package/package.json +6 -6
@@ -0,0 +1,222 @@
1
+ # Configuring pi-lens
2
+
3
+ There are **two** pi-lens config files:
4
+
5
+ | File | Scope | Notes |
6
+ | --- | --- | --- |
7
+ | `.pi-lens.json` | the project | Committed or not, your call. Nearest one wins **per field** — a package can override one setting without restating the repo root's. |
8
+ | `~/.pi-lens/config.json` | the machine | Your defaults across every project. `PI_LENS_CONFIG_PATH` relocates it. |
9
+
10
+ Both files have the same shape, with one exception noted below the example:
11
+ everything LSP-related lives under an `lsp` namespace inside them.
12
+
13
+ ```jsonc
14
+ {
15
+ "$schema": "https://raw.githubusercontent.com/apmantza/pi-lens/master/docs/schema/pi-lens-config-v1.json",
16
+ "ignore": ["dist/**"],
17
+ "maxProjectFiles": 8000,
18
+ "rules": { "high-complexity": { "threshold": 25 } },
19
+ "lsp": {
20
+ "disabledServers": ["typos"],
21
+ "warmFiles": ["src/main.rs"],
22
+ "servers": {
23
+ "my-server": {
24
+ "name": "My Custom LSP",
25
+ "extensions": [".myext"],
26
+ "command": "my-lsp-server",
27
+ "args": ["--stdio"]
28
+ }
29
+ },
30
+ "serverOverrides": {
31
+ "rust": {
32
+ "initializationOptions": { "check": { "command": "clippy" } }
33
+ }
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ **Some settings are global-only.** A handful of switches — `lsp.enabled`
40
+ (`--no-lsp`), `tests.enabled`, `delta.enabled` and the other session-wide
41
+ toggles — are decided once for the machine, not per project, so writing one in a
42
+ `.pi-lens.json` does nothing. It is not ignored quietly: the project loader says
43
+ so, naming the key. `docs/settings.md` lists which flags are which.
44
+
45
+ ## Which file wins
46
+
47
+ One order, lowest precedence first. A later tier replaces an earlier tier's
48
+ value **for that field only** — objects are merged field-wise, never replaced
49
+ whole, so setting one key never silently drops the rest of a section.
50
+
51
+ 1. **global** — `~/.pi-lens/config.json`.
52
+ 2. **project root** — the outermost `.pi-lens.json` at or above your working
53
+ directory.
54
+ 3. **nested-project** — every `.pi-lens.json` between that root and your working
55
+ directory, outermost first. The nearest file wins, per field.
56
+
57
+ Those three are the tiers the config **files** resolve through, and they are the
58
+ only ones this resolution populates. Four more tiers are reserved in the
59
+ precedence table — `builtin` below them, and `env`, `cli`, `host` above — and
60
+ nothing writes into them yet; #2427 (env/CLI) and #2416 (host and project trust)
61
+ are what fill them in.
62
+
63
+ Until they do, environment variables and CLI flags are read by their own
64
+ accessors rather than through this resolution, and their effective precedence
65
+ for a pi-lens toggle is:
66
+
67
+ 1. a `PI_LENS_*` environment variable set to `1` — checked first, and it wins
68
+ outright;
69
+ 2. the matching `--lens-*` / `--no-*` CLI flag;
70
+ 3. the nearest project `.pi-lens.json`, then the outer ones (project-scoped
71
+ settings only);
72
+ 4. `~/.pi-lens/config.json`;
73
+ 5. the built-in default.
74
+
75
+ Subsystem-specific env overrides follow the same shape: a
76
+ `PI_LENS_REVIEW_GRAPH_MAX_FILES` beats a `.pi-lens.json`'s
77
+ `reviewGraph.maxFiles`. `docs/environment-variables.md` and `docs/settings.md`
78
+ are the per-setting references.
79
+
80
+ ### One exception: `lsp.disabledServers` is a denial, not a value
81
+
82
+ Ordinary settings are last-tier-wins. A **denial** is not, because the tier
83
+ that made it is usually the one you control and the tier that would override it
84
+ is usually one that arrived with somebody else's checkout.
85
+
86
+ `lsp.disabledServers` resolves as the **union of every tier's entries**. A
87
+ project `.pi-lens.json` can add to it and can never subtract from it, so a
88
+ repository cannot re-enable a server you turned off in
89
+ `~/.pi-lens/config.json`. There is no vocabulary for un-denying an entry: if
90
+ you change your mind, edit the file that denied. The provenance reports, per
91
+ denied server, the tier that contributed it.
92
+
93
+ ```console
94
+ $ # which servers run for this file, and why
95
+ $ pilens_effective_config file=src/main.rs
96
+ ✗ typos — disabled-by-config (global ~/.pi-lens/config.json → /lsp/disabledServers/0)
97
+ ```
98
+
99
+ The union spans **both spellings**: a document's deprecated root keys
100
+ (`servers`, `serverOverrides`, `disabledServers`, `warmFiles`) are read
101
+ into the `lsp` namespace before any tier is merged, so one setting is resolved
102
+ once no matter which spelling each file uses. Migrating does not change the
103
+ answer, staying un-migrated is not a way around the denial, and a half-migrated
104
+ pair of files merges rather than one clobbering the other.
105
+
106
+ Two rules make the rest of the table unambiguous:
107
+
108
+ - **The search stops at `$HOME`.** pi-lens never reads a config file in your
109
+ home directory or above it. A stray `pi-lens.json` in `$HOME` (or at `C:\`)
110
+ is not adopted by every project on the machine. The machine-global file is
111
+ read by its own path, so it is unaffected.
112
+ - **The canonical spelling wins.** Where a legacy file or a legacy key means the
113
+ same thing as the canonical one, the canonical one is used — otherwise the
114
+ migration below could never be completed.
115
+
116
+ ## Legacy locations (still read; being removed)
117
+
118
+ These are read for their deprecation window and then **removed**. Each one you
119
+ still have produces one warning per setting, naming exactly where to move it —
120
+ carrying the stable code `PILENS_CFG_0003` (a deprecated file) or
121
+ `PILENS_CFG_0002` (a deprecated key), so you can match or suppress on the code
122
+ rather than on the prose.
123
+
124
+ | Legacy | Move it to | Code |
125
+ | --- | --- | --- |
126
+ | `.pi-lens/lsp.json` | `.pi-lens.json` → `lsp.*` | `PILENS_CFG_0003` |
127
+ | `pi-lsp.json` | `.pi-lens.json` → `lsp.*` | `PILENS_CFG_0003` |
128
+ | `pi-lens.json` (undotted) | `.pi-lens.json` | `PILENS_CFG_0003` |
129
+ | `~/.pi-lens/lsp.json` | `~/.pi-lens/config.json` → `lsp.*` | `PILENS_CFG_0003` |
130
+ | `servers` at the file root | `lsp.servers` | `PILENS_CFG_0002` |
131
+ | `serverOverrides` at the file root | `lsp.serverOverrides` | `PILENS_CFG_0002` |
132
+ | `disabledServers` at the file root | `lsp.disabledServers` | `PILENS_CFG_0002` |
133
+ | `warmFiles` at the file root | `lsp.warmFiles` | `PILENS_CFG_0002` |
134
+
135
+ **Deprecated since 4.1.4. Read for the last time before 5.0.0.** The window is
136
+ declared as data in `clients/config-diagnostic-codes.ts`
137
+ (`DEPRECATED_CONFIG_SURFACES`) and enforced by test, so the schedule above and
138
+ the code cannot drift apart. `docs/public-api-stability.md` describes the policy
139
+ these dates instantiate.
140
+
141
+ A `.pi-lens.json` that mixes both spellings is fine while you migrate: the
142
+ canonical key wins, and the keys you have not moved yet keep working.
143
+
144
+ Only keys pi-lens actually recognizes get "move it to …" advice. A key in a
145
+ legacy file that is not a pi-lens setting at all — a typo, or a leftover from
146
+ another tool — cannot be migrated anywhere, so it gets the ordinary
147
+ unrecognized-key notice (`PILENS_CFG_0001`) and is counted in ONE whole-file
148
+ `PILENS_CFG_0003` notice for the file rather than being told to move.
149
+
150
+ ## When a config is ignored
151
+
152
+ A file that cannot be read or parsed is **ignored, never partially applied** —
153
+ pi-lens runs on defaults for it and says so once, with the code
154
+ `PILENS_CFG_0001`. A field whose value does not match its declared type is
155
+ dropped on its own (`PILENS_CFG_0005`), and an unrecognized field is dropped
156
+ with a message naming the key (`PILENS_CFG_0004`). If resolving a file fails
157
+ internally the whole file is ignored and said so under its own code
158
+ (`PILENS_CFG_0008`), so "one field went missing" and "none of this file is in
159
+ effect" are never the same code. Nothing about your config is ever ignored
160
+ silently.
161
+
162
+ The number of notices one file can produce is bounded PER NOTICE LIST, because
163
+ the number of keys in a file is not. There are two lists, split by who composes
164
+ them rather than by what they say — both are about values that were rejected:
165
+
166
+ - what **resolving** the file produced — the per-field rejections
167
+ (`PILENS_CFG_0004`, `PILENS_CFG_0005`, `PILENS_CFG_0006`) together with the
168
+ deprecation notices (`PILENS_CFG_0002`, `PILENS_CFG_0003`), which share this
169
+ list;
170
+ - what the **loader** reading the file produced on its own — unknown top-level
171
+ keys and settings it refused (`PILENS_CFG_0001`).
172
+
173
+ Each list is bounded at 20 records: up to 19 notices plus, when the bound bit,
174
+ a single `PILENS_CFG_0007` summary giving the count that was suppressed, so a
175
+ truncated list always says that it is truncated. That summary is about the
176
+ LIST, not about the file: a config whose every setting was applied can still
177
+ overflow the bound, so it is worded and recorded as a summary rather than as an
178
+ ignored config.
179
+
180
+ One notice is never suppressed by that bound: `PILENS_CFG_0008`, which says the
181
+ whole file is out of effect. It is not one more rejected key competing for a
182
+ slot — it is what tells you the rejections above it are no longer the whole
183
+ story — so it is kept however full the list already was.
184
+
185
+ ## Asking what is actually in effect
186
+
187
+ You never have to reconstruct the table above by hand. `pilens_effective_config`
188
+ (MCP) and `effective_config` (pi) return the resolved configuration with the
189
+ provenance of **every** leaf — the tier, the file, the key, and the trust
190
+ decision that applied — plus, for a file you name, its language, every LSP
191
+ server with the reason it was selected or denied, and the runners that would
192
+ dispatch. That is the answer to "why is this running" and to "why is this *not*
193
+ running", without reading a log.
194
+
195
+ Naming a `file` resolves the configuration **at that file's own directory**,
196
+ which is where the runtime decides from — so a nested `repo/sub/.pi-lens.json`
197
+ layer contributes to the answer, appears in the reported document list, and is
198
+ named as the file behind any decision it made. The walk runs upward and is
199
+ **confined to `cwd`**: a `file` that resolves outside `cwd` — including a
200
+ sibling package in the same monorepo — is rejected rather than answered from
201
+ its own unrelated tree, because the per-file answer is only ever correct when
202
+ it is a superset of the workspace's own; the rejection names the `cwd` it was
203
+ measured against and the remedy is to re-query with `cwd` set to that file's
204
+ own workspace. A confined `file` always passes back through the workspace's
205
+ own documents on its way up, so they are always included too.
206
+
207
+ It reports **sources, never values**. Environment values never appear, a custom
208
+ server's command line is cut to the binary itself, and every path is rewritten
209
+ `~`-relative. There is no un-redacted mode: the un-redacted data is the config
210
+ file you already have.
211
+
212
+ `pilens_health` embeds the same provenance as **counts per tier** — how many
213
+ settings each source decided, and which `PILENS_CFG_*` notices the resolution
214
+ produced — so a session's config posture is visible without the detail.
215
+
216
+ ## See also
217
+
218
+ - `docs/globalconfig.md` — every key of `~/.pi-lens/config.json`, in detail.
219
+ - `docs/settings.md` — the CLI flags and what they map to.
220
+ - `docs/environment-variables.md` — the `PI_LENS_*` tier.
221
+ - `docs/public-api-stability.md` — what `x-stability`, the `PILENS_CFG_*` codes,
222
+ and the deprecation windows commit pi-lens to.
@@ -40,9 +40,9 @@ Auto-install behavior depends on gate type:
40
40
  | `intelephense` | PHP LSP | Yes | Flow-gated |
41
41
  | `bash-language-server` | Bash LSP | Yes | Language-default |
42
42
  | `yaml-language-server` | YAML LSP | Yes | Language-default |
43
- | `vscode-langservers-extracted` | JSON/ESLint/CSS/HTML LSP | Yes | Language-default |
44
- | `vscode-css-languageserver` | CSS LSP | Yes | Language-default |
45
- | `vscode-html-languageserver-bin` | HTML LSP | Yes | Language-default |
43
+ | `vscode-json-language-server` | JSON LSP (`vscode-langservers-extracted`) | Yes | Language-default |
44
+ | `vscode-css-languageserver` | CSS LSP (`vscode-langservers-extracted`) | Yes | Language-default |
45
+ | `vscode-html-languageserver-bin` | HTML LSP (`vscode-langservers-extracted`) | Yes | Language-default |
46
46
  | `svelte-language-server` | Svelte LSP | Yes | Flow-gated |
47
47
  | `@vue/language-server` | Vue LSP | Yes | Flow-gated |
48
48
  | `opengrep` | Experimental security dispatch | Auto-install | Local config / explicit opt-in |
@@ -53,6 +53,43 @@ so the final state is formatter-stable. A `write` immediately followed by an
53
53
  deferred too. See `clients/pipeline.ts`, `clients/runtime-tool-result.ts`, and
54
54
  `clients/runtime-agent-end.ts`.
55
55
 
56
+ A tool pi-lens does not name is classified by the SHAPE of its arguments
57
+ (`clients/mutating-tool.ts`). A host or extension edit tool called `replace` or
58
+ `insert` therefore gets a turn-state entry, a change-log receipt attributed to
59
+ the tool itself, and the deferred autofix and format pass — the same chain
60
+ `edit` gets. Its lines are resolved when the anchor is unambiguous (roughly
61
+ two-thirds of anchors in practice — `clients/hashline-anchor.ts`); otherwise
62
+ the mutation is recorded whole-file with lines unknown, and the
63
+ read-before-edit guard takes its no-line-info arm rather than guessing.
64
+ Deferred is the default for any edit-shaped tool pi-lens cannot place, because
65
+ formatting between the calls of a multi-step rewrite fights the tool that is
66
+ still writing. A tool whose SHAPE is unrecognized too is caught by observation:
67
+ pi-lens takes a bounded snapshot of the path that call names — and only that
68
+ path, so a change to a neighbouring file is never blamed on it — replays
69
+ whatever actually changed through the same chain, then remembers that tool as
70
+ mutating for the session, and on disk under the project's data directory once a
71
+ second observation confirms it, so later sessions classify it by name with no
72
+ snapshot at all. A tool that names no file is caught at `agent_settled` by an
73
+ incremental content check over the files pi-lens has already read, written,
74
+ diagnosed or opened on a language server: a rotating window of the set each
75
+ turn, reading only the files whose size or timestamp actually moved, so the
76
+ check stays affordable as the set grows. A file it has never seen has no
77
+ baseline and is therefore not covered, and a file it cannot verify is named
78
+ rather than reformatted on a timestamp alone
79
+ (`clients/observed-mutation.ts`).
80
+
81
+ **Bundled fallback lint configs stay conservative.** When a project ships no
82
+ tool config, the package-owned fallback configs set the rules (`config/biome/core.jsonc`,
83
+ `config/ruff/core.toml`, `config/markdownlint/core.json`). The biome fallback
84
+ disables `useImportType`: its safe fix rewrites a value import used only in
85
+ type positions into `import type`, which erases the runtime binding that
86
+ experimental decorator metadata (`emitDecoratorMetadata`) still needs and
87
+ breaks decorator-based dependency injection (refs #2385). Every other
88
+ recommended rule stays on, and an explicit project `biome.json(c)` remains
89
+ authoritative: if you enable `useImportType` there, pi-lens does not override
90
+ it. The ruff fallback selects no flake8-type-checking (TC) rules and applies
91
+ only safe fixes, so it never hoists imports into `TYPE_CHECKING` blocks.
92
+
56
93
  Deferred formatting (the `agent_end` default) runs with **bounded
57
94
  concurrency**: at most three formatter subprocesses in flight at once, with
58
95
  results applied in admission order and cooperative yields between files, so a
@@ -140,12 +177,14 @@ pi-lens MCP server expose the same shape to Claude Code / any MCP client.
140
177
 
141
178
  ### Actionable Warnings
142
179
 
143
- At `turn_end`, pi-lens writes `.pi-lens/cache/actionable-warnings.json` summarizing fixable warnings introduced by the current turn. This powers the optional conservative autofix at `agent_end`.
180
+ 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
+
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).
144
183
 
145
184
  **Report contents:**
146
185
 
147
186
  - Warnings are delta-only by default: only diagnostics in lines touched during the current turn are included. Pass `--lens-actionable-warning-all` to report all warnings regardless of location
148
- - Each warning carries a stable `aw:<hash>` ID derived from file, rule, and message, so suppression state persists across turns in `.pi-lens/cache/actionable-warning-state.json`
187
+ - Each warning carries a stable `aw:<hash>` ID derived from file, rule, and message, so suppression state persists across turns in `<project-data-dir>/cache/actionable-warning-state.json`
149
188
  - Sources: pipeline `fixable` diagnostics (always included) and LSP code-action warnings when `--lens-actionable-warning-actions` is set
150
189
  - When warnings are present, a concise advisory is injected into the agent context (no blocker language)
151
190
 
@@ -354,14 +393,14 @@ pi-lens ships an MCP (Model Context Protocol) server so Claude Code — or any M
354
393
 
355
394
  **Why a second host:** the pi extension's tools are registered via the host SDK and run on pi's event loop. Claude Code lives in a different process with no SDK access. The MCP server sits in that gap, speaking JSON-RPC over stdio (or a warm Unix socket / Windows named pipe side-channel for the Claude Code PostToolUse hook). It's the easiest way to live-test, debug, and dogfood pi-lens — including running a **review loop** where Claude commits to pi-lens and re-measures.
356
395
 
357
- **16 tools, grouped by lifecycle layer** (the same three layers the pi agent hooks use):
396
+ **18 tools, grouped by lifecycle layer** (the same three layers the pi agent hooks use):
358
397
 
359
398
  | Layer | MCP tools | What they expose |
360
399
  |---|---|---|
361
- | **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. |
400
+ | **Per-edit** | `pilens_analyze`, `pilens_lsp_diagnostics`, `pilens_lsp_navigation`, `pilens_ast_grep_search`, `pilens_ast_grep_replace`, `pilens_module_report`, `pilens_read_symbol`, `pilens_read_enclosing` | 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. |
362
401
  | **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`. |
363
402
  | **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. |
364
- | **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. |
403
+ | **Project / observability** | `pilens_project_scan`, `pilens_project_report`, `pilens_diagnostics`, `pilens_health`, `pilens_latency`, `pilens_symbol_search`, `pilens_effective_config` | 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. `pilens_effective_config` answers **“why is X running / why is X not running”** from one query — the resolved configuration with the provenance of every setting, and for a file you name, its language plus every LSP server with the reason it was selected or denied and the runners that would dispatch. It reports sources, never values. |
365
404
  | **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`. |
366
405
 
367
406
  **Honest limits** (live-tested, documented in `mcp.md`):
@@ -27,6 +27,20 @@ Each runtime toggle is settable from the CLI *and* from `config.json`. The two a
27
27
  | `--lens-compact-tool-line` | `ui.compactToolLine` | `false` |
28
28
  | `--no-lazy-tools` | `tools.lazy` | `true` |
29
29
  | `--lens-turn-end-madge` | `turnEnd.madge.enabled` | `false` |
30
+ | `--no-knip` | `knip.enabled` | `true` |
31
+ | `--no-jscpd` | `jscpd.enabled` | `true` |
32
+ | `--no-madge` | `madge.enabled` | `true` |
33
+ | `--no-gitleaks` | `gitleaks.enabled` | `true` |
34
+ | `--no-govulncheck` | `govulncheck.enabled` | `true` |
35
+ | `--no-dead-code` | `deadCode.enabled` | `true` |
36
+ | `--no-complexity` | `complexity.enabled` | `true` |
37
+
38
+ ## Startup controls
39
+
40
+ | Configuration key | Default | Accepted values |
41
+ | --- | --- | --- |
42
+ | `startup.mode` | `full` | `quick`, `full`, or `minimal`; `PI_LENS_STARTUP_MODE` wins |
43
+ | `startup.scans.enabled` | `true` | `true` or `false` |
30
44
 
31
45
  By default pi-lens registers six situational tools (the `ast_grep_*` family,
32
46
  `lsp_navigation`, `lens_diagnostic_mark`) inactive and exposes a small loader,
@@ -249,6 +263,12 @@ Explicit override for the review graph's own file budget (#775), for monorepos t
249
263
 
250
264
  ### Schema rules
251
265
 
266
+ Session-start analyzer keys default to `true` and work in both the global
267
+ config and `.pi-lens.json`. Set one to `false` to skip that analyzer; pi-lens
268
+ records the disabled skip. `startup.mode` accepts `quick`, `full`, or
269
+ `minimal`, and `startup.scans.enabled: false` disables background startup scans
270
+ while leaving diagnostics and LSP active. `PI_LENS_STARTUP_MODE` still wins.
271
+
252
272
  - Unknown rule ids are ignored (forward-compat). Unrecognized **top-level** keys are logged once and then ignored — never fatal to the parse. The LSP namespaces a shared file legitimately carries (`servers`, `serverOverrides`, `disabledServers`, `warmFiles`) and `$schema` are tolerated silently; a user-level-only lens key placed here (e.g. `lsp`, `tests`, `delta`) is logged as "not honored at project scope"; anything else is logged as a likely typo. The raw parsed JSON is still exposed for forward-compat consumers regardless.
253
273
  - Every toggle key in the table above must be a boolean, and its containing section must be an object. A wrong type is logged once and the key is treated as absent, so the flag falls through to its default rather than the whole file being rejected.
254
274
  - 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.
@@ -17,8 +17,8 @@ Dispatch is diagnostics-oriented: automatic formatting and safe autofix happen i
17
17
  | Shell | ✓ | lsp, shellcheck | shfmt |
18
18
  | Fish | ✓ (fish-lsp) | lsp, fish-indent | fish_indent |
19
19
  | CSS/SCSS/Less | ✓ | lsp, stylelint | biome, prettier |
20
- | HTML | ✓ | lsp, htmlhint | prettier |
21
- | YAML | ✓ | lsp, yamllint, actionlint (GitHub workflows), trivy-config (opt-in; Kubernetes manifests, CloudFormation) | prettier |
20
+ | HTML | ✓ | lsp, htmlhint | prettier (with project config) |
21
+ | YAML | ✓ | lsp, yamllint, actionlint (GitHub workflows), trivy-config (opt-in; Kubernetes manifests, CloudFormation) | prettier (with project config) |
22
22
  | JSON | ✓ | lsp, trivy-config (opt-in; CloudFormation templates only) | biome, prettier |
23
23
  | Svelte | ✓ | lsp | oxfmt (needs `svelte` pkg installed + config `svelte: true`) |
24
24
  | Vue | ✓ | lsp | prettier, oxfmt |
@@ -35,11 +35,19 @@ they share a server id but not a verified clean-signal behavior.
35
35
  | **2 — push, publishes-versioned** | `publishDiagnostics([])` **with version** on every scan, incl. clean→clean | YES, currency-proven via version | ast-grep |
36
36
  | **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 |
37
37
  | **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 |
38
+ | **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 |
38
39
 
39
40
  Detection is **cached** at `initialize` (`detectWorkspaceDiagnosticsSupport` →
40
41
  `state.workspaceDiagnosticsSupport.mode`, upgraded on `client/registerCapability`),
41
42
  so the tier is free at collection time — no per-edit probe.
42
43
 
44
+ Custom servers without a pull provider begin with one bounded first-contact
45
+ probe. The probe uses the smaller of the server's push-wait budget and the live
46
+ hook deadline. If the hook cuts it off first, the result remains unconfirmed and
47
+ the next touch probes again. Only silence through the full push budget latches
48
+ that server id as navigation-only for the service session. A publish upgrades it
49
+ to the ordinary push-wait policy.
50
+
43
51
  ## Matrix (dev box + CI nightly; mode last refreshed 2026-06-17 from run 27713958681, clean-behavior probed on the dev box 2026-07-08 — #460)
44
52
 
45
53
  `mode` from cached capabilities; `clean-behavior` from the phase-aware publish-trace
@@ -74,7 +82,7 @@ classification standing.
74
82
  | toml | taplo | push-only | publishes-unversioned | 2* | dev+ci |
75
83
  | terraform | terraform-ls | push-only | TBD | 2/3? | dev+ci |
76
84
  | prisma | @prisma/language-server | push-only | publishes-unversioned | 2* | dev+ci |
77
- | php | intelephense | push-only | TBD | 2/3? | dev |
85
+ | php | intelephense | push-only | TBD | 2/3? | dev+ci |
78
86
  | zig | zls | push-only | publishes-unversioned | 2* | dev+ci |
79
87
  | vue | @vue/language-server | push-only | TBD | 2/3? | dev+ci |
80
88
  | dart | dart language-server | push-only | publishes-unversioned | 2* | ci |
@@ -0,0 +1,25 @@
1
+ # Fixer contract
2
+
3
+ Deliver a root-caused fix with red proof and a reviewable handoff.
4
+
5
+ Read the issue, repository instructions, shared delegated worker contract, and
6
+ relevant architecture before editing. Reuse the shared seam and existing
7
+ machinery. Keep the change localized and compatible with concurrent branches.
8
+
9
+ Build the smallest faithful reproduction first. Preserve its pre-fix failure
10
+ output. After fixing, prove every new guard mutation-sensitive. Run a pattern
11
+ sweep and a population sweep for the defect class. Record per-member verdicts,
12
+ the blast radius, and bounded observability. Add a changelog fragment for a code
13
+ change.
14
+
15
+ ## Tautological tests considered harmful
16
+
17
+ Do not assert a value that the test setup already supplied, duplicate the source
18
+ predicate in the test, or replace a real in-process seam with a fake to keep the
19
+ test green. Drive the production path and assert an independent observable. If
20
+ the test passes after deleting the guard, it is tautological and must be
21
+ redesigned before the fix is complete.
22
+
23
+ Verify the build and every targeted or sibling suite required by repository
24
+ policy. Follow the shared contract's Git authority. Report what ran, what was
25
+ skipped, and why. Use active, plain prose.
@@ -0,0 +1,25 @@
1
+ # Investigator contract
2
+
3
+ Root-cause runtime behavior from reproducible and durable evidence.
4
+
5
+ Define the symptom as a question that evidence can answer. Name the time window,
6
+ sessions, and build in scope. Prefer a tight reproduction loop before code
7
+ reading. Correlate records by stable identifiers, not time alone. Read each
8
+ record's producer before trusting its labels. Count a representative population,
9
+ and separate worker behavior from daemon behavior.
10
+
11
+ Keep the investigation read-only. Rank falsifiable hypotheses with evidence for
12
+ and against each hypothesis and the observation that would settle it. Sweep the
13
+ tree for the root-cause pattern and every member of the affected population.
14
+ State the blast radius and any missing or unbounded observability.
15
+
16
+ Deliver a proven diagnosis and a concrete next step. If the task expands to an
17
+ implementation, stop and return it to the orchestrator for a fixer delegation.
18
+ Use concise, active, plain prose.
19
+
20
+ ## Tautological tests considered harmful
21
+
22
+ Treat a probe as evidence only when it can distinguish the competing hypotheses.
23
+ Do not seed the asserted outcome, mirror the production predicate, or rely on a
24
+ mock where the real in-process seam is available. Record the observation that
25
+ would turn the hypothesis red, and preserve that distinction in the handoff.
@@ -0,0 +1,33 @@
1
+ # Reviewer contract
2
+
3
+ Adversarially verify a change before merge and report proven findings.
4
+
5
+ Assume the implementation's claims are incomplete. Read the issue, full diff,
6
+ repository instructions, shared delegated worker contract, PR body, and merge
7
+ state. Keep the review read-only.
8
+
9
+ Diff the change from its merge base (`git diff origin/master...HEAD`, or
10
+ `git diff $(git merge-base origin/master HEAD)..HEAD`), never a two-dot diff
11
+ against `origin/master`: a checkout cut before another lane merged shows that
12
+ merge in reverse as deletions and produces a false HIGH (2026-09-08, #2730
13
+ round 2 and #2747 round 1).
14
+
15
+ Reproduce the build and targeted tests. Verify quoted red-first evidence by
16
+ keeping the tests and removing the source fix. Mutate every new guard and demand
17
+ a red test. Probe inversions, concurrency, input channels, trust boundaries,
18
+ strict consumers, and durable-record compatibility. Repeat the pattern and
19
+ population sweeps. Check the stated blast radius, bounded observability,
20
+ changelog fragment, commit shape, and PR conventions.
21
+
22
+ Report `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`, then `NITPICK` findings. Give the
23
+ file and line, a concrete failure, evidence, and a suggested fix. Separate issue
24
+ acceptance findings from repository-standard findings. List cleared categories,
25
+ then record one verdict: merge as-is, merge after fixes, or redesign. Never
26
+ merge or silently repair the author's branch. Use short, active, plain prose.
27
+
28
+ ## Tautological tests considered harmful
29
+
30
+ Check that each regression test reaches the real seam and observes an independent
31
+ effect. Remove or mutate the claimed guard and require the test to fail for the
32
+ intended reason. Flag tests that restate the implementation, assert setup data,
33
+ or swap a real in-process store, sink, coordinator, or registry for a fake.
@@ -0,0 +1,49 @@
1
+ # Delegated worker delivery contract
2
+
3
+ This contract applies to every delegated pi-lens worker, regardless of the
4
+ agent runner or model. Pair it with exactly one role contract: fixer, reviewer,
5
+ or investigator.
6
+
7
+ Work only in the assigned worktree. Before editing, verify its absolute path,
8
+ registered worktree entry, branch, and base. Preserve junctioned dependencies.
9
+ Never switch another checkout's branch, and never use `git stash`. Save a patch
10
+ before temporarily reverting work.
11
+
12
+ Treat the acceptance criteria as the contract. For a regression, prove the new
13
+ test red before the fix and green after it. Mutating or removing a new guard
14
+ must make at least one test fail. Sweep the whole tree for the same code pattern
15
+ and every member of any enumerable population. Record both sweeps.
16
+
17
+ State the blast radius, including callers, durable shapes, strict parsers, and
18
+ tool surfaces. Add bounded observability for every new failure path. Include the
19
+ required changelog fragment for a code change. Report verification honestly.
20
+ Write active, direct prose with short sentences and consistent terms.
21
+
22
+ ## Tautological tests considered harmful
23
+
24
+ A test must observe behavior through the real seam, not repeat the implementation
25
+ or feed the expected answer in through setup. Keep the red-first failure tied to
26
+ the defect, and mutate the guard or filter to prove the test can detect its loss.
27
+ Mocks belong only at true process or host boundaries. When a test can use the
28
+ real store, sink, coordinator, or registry, use it and assert the durable result.
29
+
30
+ Git authority is separate from the role. Commit, push, or open a PR only when
31
+ the delegation explicitly grants that authority after worktree verification.
32
+ Otherwise, edit and test with the assigned worktree as the command working
33
+ directory, leave every change uncommitted, and write two handoff files at the
34
+ worktree root: `PR_BODY.md` (the full PR body, transcripts pasted) and
35
+ `COMMIT_MSG.txt` (subject, body, issue ref, trailers). Name any path inside the
36
+ worktree that must not be committed. The orchestrator commits from those files;
37
+ they are never committed themselves. Never merge.
38
+
39
+ A sandboxed worker may find the shared `.git` and the linked `node_modules`
40
+ read-only and the network absent (the codex `workspace-write` sandbox does
41
+ this; see plegma#311). Run Vitest as
42
+ `node_modules/.bin/vitest run <files> --configLoader runner`, and if the
43
+ tree-sitter grammar prefetch hangs offline, verify through direct probes of the
44
+ built code and say so; the orchestrator re-runs the files outside the sandbox.
45
+
46
+ When Git authority is granted, use one logical commit with an imperative,
47
+ conventional-prefix subject of at most 50 characters, a blank line, and a
48
+ 72-column body that states what and why. Reference the issue. Open a PR, do not
49
+ merge it, and report its URL.
@@ -0,0 +1,55 @@
1
+ # PR warden contract
2
+
3
+ Keep every pull request moving through review, fix, verification, and merge.
4
+
5
+ The warden is a read-only workflow controller. It does not investigate code,
6
+ judge review findings, implement fixes, or replace the reviewer. Read the
7
+ repository instructions and shared delegated worker contract before every
8
+ audit.
9
+
10
+ Build the ledger from GitHub and registered worktree evidence. For every pull
11
+ request, record the exact head SHA, matching worktree, dirty or unpushed state,
12
+ mergeability, required checks on that SHA, review outcome, active owner, and
13
+ next action. Use one state from this closed set:
14
+
15
+ - `UNREVIEWED`
16
+ - `REVIEW_FINDINGS`
17
+ - `FIXING`
18
+ - `AWAITING_VERIFY`
19
+ - `AWAITING_COMMIT_PUSH`
20
+ - `CI_PENDING`
21
+ - `CI_REAL_FAILURE`
22
+ - `CI_INFRA_FAILURE`
23
+ - `READY_AUTOMERGE`
24
+ - `MERGED`
25
+
26
+ A worker result becomes durable workflow evidence only when the orchestrator
27
+ records its role, exact head or working-tree identity, verdict, dispositions,
28
+ and next owner on the pull request or another shared ledger. Chat-only results
29
+ cannot drive a later audit. Flag a missing durable handoff record instead of
30
+ guessing that review passed.
31
+
32
+ Assign an owner and next action whenever the state changes. Reuse the same
33
+ fixer for correction rounds and the same reviewer for verification rounds. A
34
+ completed handoff without a triggered next owner is an orchestration defect;
35
+ report it before lower-priority work.
36
+
37
+ Run the audit after every worker completion, push, review verdict, CI verdict,
38
+ merge, and user status request. Poll GitHub and persistent external-worker
39
+ handles when completion notifications are unavailable. Never infer completion
40
+ from a quiet worker or clean worktree.
41
+
42
+ Classify required CI from its log and exact head. Treat assertion failures and
43
+ `[mem-watch] done. exitCode=1` as real. Apply the repository's exit-137 rules
44
+ before calling a failure infrastructure. Do not treat SonarCloud or another
45
+ advisory lane as a merge gate. A skipped required job is not green.
46
+
47
+ Mark `READY_AUTOMERGE` only when the actual final head has passed required CI
48
+ and adversarial review, every material finding has a disposition, and every
49
+ substantive fix has passed the same-reviewer verification loop. The
50
+ orchestrator, not the warden, commits, pushes, comments, enables automerge, or
51
+ merges.
52
+
53
+ Return a compact transition table followed by a priority queue. Name
54
+ orchestration breaches separately. Provide exact safe commands when they help
55
+ the orchestrator, but make no repository or GitHub mutation.