@herbertgao/pi-extensions 2026.9.0 → 2026.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) 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/@pi-plugins/fast-mode/README.md +5 -3
  11. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -1
  12. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +20 -55
  13. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -1
  14. package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
  15. package/node_modules/pi-lens/CHANGELOG.md +988 -0
  16. package/node_modules/pi-lens/README.md +3 -0
  17. package/node_modules/pi-lens/config/biome/core.jsonc +11 -2
  18. package/node_modules/pi-lens/config/dependency-cruiser-eager-allowlist.json +13 -1
  19. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -2
  20. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +927 -80
  21. package/node_modules/pi-lens/dist/clients/agent-behavior-client.js +13 -4
  22. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +123 -3
  23. package/node_modules/pi-lens/dist/clients/ast-grep-rule-manager.js +60 -5
  24. package/node_modules/pi-lens/dist/clients/ast-grep-tool-logger.js +2 -2
  25. package/node_modules/pi-lens/dist/clients/bash-file-access.js +1 -3
  26. package/node_modules/pi-lens/dist/clients/biome-client.js +9 -2
  27. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +14 -0
  28. package/node_modules/pi-lens/dist/clients/bootstrap.js +509 -73
  29. package/node_modules/pi-lens/dist/clients/bounded-cache.js +152 -12
  30. package/node_modules/pi-lens/dist/clients/bounded-telemetry.js +59 -4
  31. package/node_modules/pi-lens/dist/clients/bundled-resource-health.js +113 -0
  32. package/node_modules/pi-lens/dist/clients/bus-events-logger.js +2 -2
  33. package/node_modules/pi-lens/dist/clients/cache/rule-cache.js +31 -4
  34. package/node_modules/pi-lens/dist/clients/cache-manager.js +105 -6
  35. package/node_modules/pi-lens/dist/clients/cache-observability.js +44 -18
  36. package/node_modules/pi-lens/dist/clients/cargo-manifest.js +422 -0
  37. package/node_modules/pi-lens/dist/clients/cascade-logger.js +2 -2
  38. package/node_modules/pi-lens/dist/clients/code-quality-warnings.js +13 -3
  39. package/node_modules/pi-lens/dist/clients/complexity-client.js +16 -5
  40. package/node_modules/pi-lens/dist/clients/config-core/deny.js +221 -0
  41. package/node_modules/pi-lens/dist/clients/config-core/index.js +47 -0
  42. package/node_modules/pi-lens/dist/clients/config-core/merge.js +357 -0
  43. package/node_modules/pi-lens/dist/clients/config-core/normalize.js +340 -0
  44. package/node_modules/pi-lens/dist/clients/config-core/process-spec.js +248 -0
  45. package/node_modules/pi-lens/dist/clients/config-core/provenance.js +171 -0
  46. package/node_modules/pi-lens/dist/clients/config-core/records.js +218 -0
  47. package/node_modules/pi-lens/dist/clients/config-core/resolve.js +125 -0
  48. package/node_modules/pi-lens/dist/clients/config-core/safe-object.js +78 -0
  49. package/node_modules/pi-lens/dist/clients/config-core/schema.js +167 -0
  50. package/node_modules/pi-lens/dist/clients/config-diagnostic-codes.js +281 -0
  51. package/node_modules/pi-lens/dist/clients/config-locations.js +160 -0
  52. package/node_modules/pi-lens/dist/clients/config-resolve.js +789 -0
  53. package/node_modules/pi-lens/dist/clients/config-schema.js +197 -0
  54. package/node_modules/pi-lens/dist/clients/config-warn.js +407 -0
  55. package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -14
  56. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +2 -2
  57. package/node_modules/pi-lens/dist/clients/deadline-utils.js +178 -0
  58. package/node_modules/pi-lens/dist/clients/debug-handles.js +2 -2
  59. package/node_modules/pi-lens/dist/clients/debug-heap.js +3 -3
  60. package/node_modules/pi-lens/dist/clients/deferred-lsp-work.js +106 -0
  61. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +113 -7
  62. package/node_modules/pi-lens/dist/clients/dependency-checker.js +8 -19
  63. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +12 -9
  64. package/node_modules/pi-lens/dist/clients/diagnostic-logger.js +14 -4
  65. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +162 -18
  66. package/node_modules/pi-lens/dist/clients/dispatch/fact-store.js +97 -0
  67. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -7
  68. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +0 -1
  69. package/node_modules/pi-lens/dist/clients/dispatch/runners/ast-grep-napi.js +380 -26
  70. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +0 -1
  71. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +0 -1
  72. package/node_modules/pi-lens/dist/clients/dispatch/runners/credo.js +0 -1
  73. package/node_modules/pi-lens/dist/clients/dispatch/runners/cue-vet.js +0 -1
  74. package/node_modules/pi-lens/dist/clients/dispatch/runners/dart-analyze.js +0 -1
  75. package/node_modules/pi-lens/dist/clients/dispatch/runners/detekt.js +0 -1
  76. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +0 -1
  77. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +0 -1
  78. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +0 -1
  79. package/node_modules/pi-lens/dist/clients/dispatch/runners/fact-rules.js +0 -1
  80. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +0 -1
  81. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +0 -1
  82. package/node_modules/pi-lens/dist/clients/dispatch/runners/go-vet.js +1 -3
  83. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +0 -1
  84. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +0 -1
  85. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +0 -1
  86. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-render.js +0 -1
  87. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +0 -1
  88. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +0 -1
  89. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +0 -1
  90. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +0 -1
  91. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +0 -1
  92. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +0 -1
  93. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +13 -18
  94. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +0 -1
  95. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +0 -1
  96. package/node_modules/pi-lens/dist/clients/dispatch/runners/prisma-validate.js +0 -1
  97. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +0 -1
  98. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +7 -4
  99. package/node_modules/pi-lens/dist/clients/dispatch/runners/rubocop.js +0 -1
  100. package/node_modules/pi-lens/dist/clients/dispatch/runners/ruff.js +0 -1
  101. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -3
  102. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +0 -1
  103. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +0 -1
  104. package/node_modules/pi-lens/dist/clients/dispatch/runners/spellcheck.js +0 -1
  105. package/node_modules/pi-lens/dist/clients/dispatch/runners/spotbugs.js +0 -1
  106. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +0 -1
  107. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +0 -1
  108. package/node_modules/pi-lens/dist/clients/dispatch/runners/swiftlint.js +0 -1
  109. package/node_modules/pi-lens/dist/clients/dispatch/runners/taplo.js +0 -1
  110. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +0 -1
  111. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +0 -1
  112. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +0 -1
  113. package/node_modules/pi-lens/dist/clients/dispatch/runners/trivy-config.js +0 -1
  114. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/availability-policy.js +3 -0
  115. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/diagnostic-parsers.js +3 -4
  116. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +194 -80
  117. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/toolchain-availability.js +84 -15
  118. package/node_modules/pi-lens/dist/clients/dispatch/runners/vale.js +0 -1
  119. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +0 -1
  120. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +0 -1
  121. package/node_modules/pi-lens/dist/clients/disposition-logger.js +3 -3
  122. package/node_modules/pi-lens/dist/clients/effective-config.js +403 -0
  123. package/node_modules/pi-lens/dist/clients/error-class.js +23 -0
  124. package/node_modules/pi-lens/dist/clients/event-loop-hold.js +274 -0
  125. package/node_modules/pi-lens/dist/clients/extension-log.js +2 -2
  126. package/node_modules/pi-lens/dist/clients/feature-hints.js +2 -1
  127. package/node_modules/pi-lens/dist/clients/file-time.js +6 -1
  128. package/node_modules/pi-lens/dist/clients/file-utils.js +112 -9
  129. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +50 -13
  130. package/node_modules/pi-lens/dist/clients/format-service.js +6 -1
  131. package/node_modules/pi-lens/dist/clients/formatters.js +276 -102
  132. package/node_modules/pi-lens/dist/clients/freshness-cadence.js +17 -0
  133. package/node_modules/pi-lens/dist/clients/generated-artifacts.js +114 -19
  134. package/node_modules/pi-lens/dist/clients/generation-guard.js +4 -9
  135. package/node_modules/pi-lens/dist/clients/git-guard.js +1 -1
  136. package/node_modules/pi-lens/dist/clients/go-client.js +39 -0
  137. package/node_modules/pi-lens/dist/clients/gradle-ktfmt-style.js +252 -0
  138. package/node_modules/pi-lens/dist/clients/hashline-anchor.js +424 -0
  139. package/node_modules/pi-lens/dist/clients/hook-budgets.js +76 -0
  140. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +5 -2
  141. package/node_modules/pi-lens/dist/clients/host-ports.js +1 -1
  142. package/node_modules/pi-lens/dist/clients/installer/index.js +71 -52
  143. package/node_modules/pi-lens/dist/clients/instance-reaper.js +104 -230
  144. package/node_modules/pi-lens/dist/clients/instance-registry.js +6 -3
  145. package/node_modules/pi-lens/dist/clients/language-registry.js +595 -0
  146. package/node_modules/pi-lens/dist/clients/latency-logger.js +160 -2
  147. package/node_modules/pi-lens/dist/clients/ledger-bounds.js +13 -0
  148. package/node_modules/pi-lens/dist/clients/lens-config.js +141 -30
  149. package/node_modules/pi-lens/dist/clients/lens-engine.js +30 -37
  150. package/node_modules/pi-lens/dist/clients/lens-flag-registry.js +59 -6
  151. package/node_modules/pi-lens/dist/clients/log-cleanup.js +2 -2
  152. package/node_modules/pi-lens/dist/clients/lsp/aggregation.js +3 -1
  153. package/node_modules/pi-lens/dist/clients/lsp/client.js +168 -30
  154. package/node_modules/pi-lens/dist/clients/lsp/config.js +483 -158
  155. package/node_modules/pi-lens/dist/clients/lsp/diagnostic-binding.js +1 -1
  156. package/node_modules/pi-lens/dist/clients/lsp/edits.js +15 -2
  157. package/node_modules/pi-lens/dist/clients/lsp/index.js +676 -71
  158. package/node_modules/pi-lens/dist/clients/lsp/language.js +18 -169
  159. package/node_modules/pi-lens/dist/clients/lsp/launch.js +2 -1
  160. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +5 -16
  161. package/node_modules/pi-lens/dist/clients/lsp/server.js +284 -147
  162. package/node_modules/pi-lens/dist/clients/lsp/session-roots.js +116 -23
  163. package/node_modules/pi-lens/dist/clients/lsp/spawn-history.js +2 -7
  164. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +9 -2
  165. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +1 -1
  166. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +163 -21
  167. package/node_modules/pi-lens/dist/clients/map-with-concurrency.js +36 -0
  168. package/node_modules/pi-lens/dist/clients/mcp/analyze.js +33 -4
  169. package/node_modules/pi-lens/dist/clients/mcp/session.js +5 -16
  170. package/node_modules/pi-lens/dist/clients/memory-sampler.js +8 -3
  171. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +2 -4
  172. package/node_modules/pi-lens/dist/clients/module-report.js +20 -45
  173. package/node_modules/pi-lens/dist/clients/mutating-tool.js +651 -0
  174. package/node_modules/pi-lens/dist/clients/mutation-attribution.js +368 -0
  175. package/node_modules/pi-lens/dist/clients/mutation-bridge.js +240 -0
  176. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +247 -20
  177. package/node_modules/pi-lens/dist/clients/observed-mutation-sources.js +101 -0
  178. package/node_modules/pi-lens/dist/clients/observed-mutation.js +1215 -0
  179. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +68 -22
  180. package/node_modules/pi-lens/dist/clients/opengrep-config.js +4 -0
  181. package/node_modules/pi-lens/dist/clients/package-manager.js +195 -26
  182. package/node_modules/pi-lens/dist/clients/partial-edit-apply.js +359 -80
  183. package/node_modules/pi-lens/dist/clients/path-attribution-telemetry.js +23 -7
  184. package/node_modules/pi-lens/dist/clients/path-keyed-map.js +21 -2
  185. package/node_modules/pi-lens/dist/clients/path-utils.js +428 -13
  186. package/node_modules/pi-lens/dist/clients/persist-debounce.js +8 -1
  187. package/node_modules/pi-lens/dist/clients/php-cs-fixer-config.js +114 -0
  188. package/node_modules/pi-lens/dist/clients/pipeline.js +77 -16
  189. package/node_modules/pi-lens/dist/clients/probe-home-state.js +228 -0
  190. package/node_modules/pi-lens/dist/clients/process-bridge.js +66 -0
  191. package/node_modules/pi-lens/dist/clients/process-snapshot.js +68 -0
  192. package/node_modules/pi-lens/dist/clients/project-diagnostics/fresh-fetch.js +4 -3
  193. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +27 -3
  194. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +51 -20
  195. package/node_modules/pi-lens/dist/clients/project-lens-config.js +393 -122
  196. package/node_modules/pi-lens/dist/clients/project-snapshot.js +52 -24
  197. package/node_modules/pi-lens/dist/clients/python-environment.js +217 -0
  198. package/node_modules/pi-lens/dist/clients/python-provenance.js +639 -0
  199. package/node_modules/pi-lens/dist/clients/quiet-window.js +6 -1
  200. package/node_modules/pi-lens/dist/clients/read-bridge.js +13 -21
  201. package/node_modules/pi-lens/dist/clients/read-expansion.js +9 -46
  202. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +15 -4
  203. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +364 -212
  204. package/node_modules/pi-lens/dist/clients/read-guard.js +21 -0
  205. package/node_modules/pi-lens/dist/clients/resource-sampler.js +195 -96
  206. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +152 -109
  207. package/node_modules/pi-lens/dist/clients/review-graph/service.js +55 -3
  208. package/node_modules/pi-lens/dist/clients/review-graph/shared-extraction-ir.js +7 -15
  209. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +10 -74
  210. package/node_modules/pi-lens/dist/clients/review-graph-logger.js +9 -3
  211. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +18 -2
  212. package/node_modules/pi-lens/dist/clients/runtime-context.js +49 -16
  213. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +25 -6
  214. package/node_modules/pi-lens/dist/clients/runtime-session.js +139 -22
  215. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +168 -35
  216. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +797 -243
  217. package/node_modules/pi-lens/dist/clients/runtime-turn.js +1028 -53
  218. package/node_modules/pi-lens/dist/clients/rust-client.js +31 -0
  219. package/node_modules/pi-lens/dist/clients/safe-spawn.js +33 -10
  220. package/node_modules/pi-lens/dist/clients/sanitize.js +7 -1
  221. package/node_modules/pi-lens/dist/clients/scratch-tree-policy.js +1 -3
  222. package/node_modules/pi-lens/dist/clients/security-scan-client.js +3 -0
  223. package/node_modules/pi-lens/dist/clients/session-lifecycle.js +1 -1
  224. package/node_modules/pi-lens/dist/clients/session-start-observability.js +79 -0
  225. package/node_modules/pi-lens/dist/clients/sessionstart-logger.js +12 -3
  226. package/node_modules/pi-lens/dist/clients/sgconfig.js +6 -1
  227. package/node_modules/pi-lens/dist/clients/skills-resolver.js +105 -0
  228. package/node_modules/pi-lens/dist/clients/smells-rollup.js +2 -2
  229. package/node_modules/pi-lens/dist/clients/string-utils.js +13 -0
  230. package/node_modules/pi-lens/dist/clients/subagent-mode.js +17 -4
  231. package/node_modules/pi-lens/dist/clients/test-runner-client.js +176 -39
  232. package/node_modules/pi-lens/dist/clients/test-runner-delivery.js +239 -0
  233. package/node_modules/pi-lens/dist/clients/tool-definition.js +41 -1
  234. package/node_modules/pi-lens/dist/clients/tool-policy.js +91 -21
  235. package/node_modules/pi-lens/dist/clients/tree-sitter-cache.js +40 -40
  236. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +86 -48
  237. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
  238. package/node_modules/pi-lens/dist/clients/tree-sitter-query-loader.js +81 -1
  239. package/node_modules/pi-lens/dist/clients/tree-sitter-shared.js +51 -46
  240. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +28 -0
  241. package/node_modules/pi-lens/dist/clients/typos-config.js +5 -0
  242. package/node_modules/pi-lens/dist/clients/user-notify.js +6 -2
  243. package/node_modules/pi-lens/dist/clients/widget-state.js +191 -26
  244. package/node_modules/pi-lens/dist/clients/word-index-logger.js +2 -2
  245. package/node_modules/pi-lens/dist/clients/word-index-store.js +20 -5
  246. package/node_modules/pi-lens/dist/clients/word-index.js +243 -31
  247. package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -1
  248. package/node_modules/pi-lens/dist/clients/zizmor-config.js +3 -0
  249. package/node_modules/pi-lens/dist/index.js +64335 -54300
  250. package/node_modules/pi-lens/dist/mcp/analyze-cli.js +3 -1
  251. package/node_modules/pi-lens/dist/mcp/server.js +127 -5
  252. package/node_modules/pi-lens/dist/scripts/lib/process-scan.mjs +583 -0
  253. package/node_modules/pi-lens/dist/scripts/lib/skills-predicate.mjs +129 -0
  254. package/node_modules/pi-lens/dist/tools/effective-config.js +89 -0
  255. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +95 -24
  256. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +67 -80
  257. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +37 -16
  258. package/node_modules/pi-lens/dist/tools/shared.js +0 -1
  259. package/node_modules/pi-lens/docs/agent-guide.md +64 -1
  260. package/node_modules/pi-lens/docs/configuration.md +222 -0
  261. package/node_modules/pi-lens/docs/dependencies.md +3 -3
  262. package/node_modules/pi-lens/docs/features.md +44 -5
  263. package/node_modules/pi-lens/docs/language-coverage.md +2 -2
  264. package/node_modules/pi-lens/docs/pi-lens-fixer.md +25 -0
  265. package/node_modules/pi-lens/docs/pi-lens-investigator.md +25 -0
  266. package/node_modules/pi-lens/docs/pi-lens-reviewer.md +27 -0
  267. package/node_modules/pi-lens/docs/pi-lens-subagent.md +38 -0
  268. package/node_modules/pi-lens/docs/pi-lens-warden.md +55 -0
  269. package/node_modules/pi-lens/docs/public-api-stability.md +359 -0
  270. package/node_modules/pi-lens/docs/release-qa-baseline.md +182 -0
  271. package/node_modules/pi-lens/docs/subagent-compat.md +110 -30
  272. package/node_modules/pi-lens/docs/tree-sitter_rules_catalog.md +2 -2
  273. package/node_modules/pi-lens/package.json +15 -23
  274. package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-cross-language-method.yml +3 -3
  275. package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-hallucinated-import.yml +2 -2
  276. package/node_modules/pi-lens/rules/tree-sitter-queries/python/python-sql-injection.yml +12 -2
  277. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +192 -1
  278. package/node_modules/pi-lens/scripts/install-selftest.mjs +58 -2
  279. package/node_modules/pi-lens/scripts/lib/skills-predicate.mjs +129 -0
  280. package/node_modules/pi-lens/scripts/rpc-load-check.mjs +3 -1
  281. package/node_modules/pi-web-access/CHANGELOG.md +28 -0
  282. package/node_modules/pi-web-access/README.md +62 -15
  283. package/node_modules/pi-web-access/curator-page.ts +3 -1
  284. package/node_modules/pi-web-access/curator-server.ts +5 -1
  285. package/node_modules/pi-web-access/gemini-search.ts +8 -4
  286. package/node_modules/pi-web-access/github-extract.ts +242 -1
  287. package/node_modules/pi-web-access/index.ts +118 -64
  288. package/node_modules/pi-web-access/mistral-search.ts +281 -0
  289. package/node_modules/pi-web-access/package.json +2 -2
  290. package/node_modules/pi-web-access/perplexity.ts +14 -1
  291. package/node_modules/pi-web-access/utils.ts +23 -6
  292. package/node_modules/pi-web-access/xai-search.ts +96 -33
  293. package/package.json +5 -5
@@ -1,10 +1,12 @@
1
1
  import * as nodeFs from "node:fs";
2
2
  import * as path from "node:path";
3
- import { loadBootstrapClients } from "./bootstrap.js";
3
+ import { loadBootstrapClients, requestBootstrapClients } from "./bootstrap.js";
4
+ import { getAmbientAbortSignal } from "./safe-spawn.js";
4
5
  import { recordDegradationOnce } from "./degradation-ledger.js";
5
6
  import { detectFileKind } from "./file-kinds.js";
6
7
  import { isPathIgnoredByProject } from "./file-utils.js";
7
8
  import { evaluateGitGuard, isGitCommitOrPushAttempt } from "./git-guard.js";
9
+ import { dropHashlineAnchorMemo } from "./hashline-anchor.js";
8
10
  import { evaluateSharedCheckoutGuard } from "./shared-checkout-guard.js";
9
11
  import { logLatency } from "./latency-logger.js";
10
12
  import { normalizeMapKey } from "./path-utils.js";
@@ -12,6 +14,10 @@ import { captureFileStats, getOpaqueBaselineStore, isGitWorktree, } from "./opaq
12
14
  import { normalizeForGuardMatch } from "./host-edit-normalize.js";
13
15
  import { retargetReplacementIndentation } from "./indent-retarget.js";
14
16
  import { LANGUAGE_POLICY } from "./language-policy.js";
17
+ import { isComplexitySupportedFile } from "./tree-sitter-shared.js";
18
+ import { classifyMutatingTool, readMutationPathField, } from "./mutating-tool.js";
19
+ import { isProvisionalLearnedAttribution } from "./mutation-attribution.js";
20
+ import { armObservedMutation } from "./observed-mutation.js";
15
21
  import { getLSPService } from "./lsp/index.js";
16
22
  import { findDocumentSymbolAtLine, getOpenDocumentSymbols, lspSymbolKindName, qualifiedLspSymbolName, } from "./lsp-document-symbols.js";
17
23
  import { computeTrailingWhitespaceOldTextPatch, findUniqueMatchLineRange, } from "./oldtext-autopatch.js";
@@ -19,21 +25,45 @@ import { applyPartiallyApplicableEdits } from "./partial-edit-apply.js";
19
25
  import { isExternalOrVendorFile, resolveHostPathVariants, resolveHostToolPath, } from "./path-utils.js";
20
26
  import { EXPANSION_BUDGET_MS, EXPANSION_LIMIT_LINES, tryExpandRead, } from "./read-expansion.js";
21
27
  import { boundedIndexesForCount, createReadGuardEditBatchSummary, getReadGuardCorrelationId, logReadGuardEvent, } from "./read-guard-logger.js";
22
- import { countFileLines, getTouchedLinesForGuard, relocateEditRange, tryCorrectIndentationMismatch, tryCorrectIndentationMismatchFromContent, } from "./read-guard-tool-lines.js";
28
+ import { countFileLines, formatAlreadyAppliedNotes, getTouchedLinesForGuard, relocateEditRange, tryCorrectIndentationMismatch, tryCorrectIndentationMismatchFromContent, } from "./read-guard-tool-lines.js";
23
29
  import { handleToolResult } from "./runtime-tool-result.js";
24
- import { isToolCallEventType, resolveToolCallCorrelationId, } from "./tool-event.js";
30
+ import { resolveToolCallCorrelationId } from "./tool-event.js";
25
31
  import { getSharedTreeSitterClient } from "./tree-sitter-shared.js";
26
32
  const LSP_TOOLCALL_NAV_TOUCH_BUDGET_MS = Math.max(0, Number.parseInt(process.env.PI_LENS_TOOLCALL_NAV_TOUCH_MS ??
27
33
  process.env.PI_LENS_LSP_NAV_CLIENT_WAIT_MS ??
28
34
  "1500", 10) || 1500);
29
35
  const LSP_TOOLCALL_TOUCH_BUDGET_MS = Math.max(0, Number.parseInt(process.env.PI_LENS_TOOLCALL_TOUCH_MS ?? "750", 10) || 750);
36
+ /**
37
+ * Composes the final block reason for a partial apply whose commit landed
38
+ * (#2402). The committed bytes lead the message; the preflight's per-edit
39
+ * failure bodies follow UNCHANGED, so they still describe exactly the edits
40
+ * that were NOT applied. The preflight header (🔄/🛑) is never reused here —
41
+ * relabelling committed edits as a retryable oldText miss is the #2402 defect.
42
+ */
43
+ function composePartialApplyReason(args) {
44
+ const parts = [];
45
+ const editSuffix = args.appliedCount === 1 ? "" : "s";
46
+ parts.push(args.postEditStatus === "failed"
47
+ ? `⚠️ PARTIAL APPLY — ${args.appliedCount} edit${editSuffix} committed (${args.appliedIndices}). Post-edit analysis failed after the commit; the committed bytes stand and were not reverted. Do NOT resubmit the applied edits.`
48
+ : `⚠️ PARTIAL APPLY — ${args.appliedCount} edit${editSuffix} committed (${args.appliedIndices}). Do NOT resubmit the applied edits.`);
49
+ if (args.preflightDetails && args.preflightDetails.length > 0) {
50
+ parts.push(args.preflightDetails.join("\n\n"));
51
+ }
52
+ const alreadyNotes = formatAlreadyAppliedNotes(args.alreadyAppliedEdits);
53
+ if (alreadyNotes)
54
+ parts.push(alreadyNotes.trimStart());
55
+ if (args.postEditOutput && args.postEditStatus === "succeeded") {
56
+ parts.push(`Post-apply analysis:\n${args.postEditOutput}`);
57
+ }
58
+ return parts.join("\n\n");
59
+ }
30
60
  function getToolCallRawFilePath(toolName, event) {
31
61
  const inputObj = (event.input ?? {});
32
- if (isToolCallEventType("write", event) ||
33
- isToolCallEventType("edit", event)) {
34
- const filePath = event.input.path;
35
- return typeof filePath === "string" ? filePath : undefined;
36
- }
62
+ // #2423: the seam owns "does this tool target a file it mutates". No ctx is
63
+ // passed — the path is not resolved yet, so adapters must not log here.
64
+ const mutation = classifyMutatingTool({ ...event, toolName });
65
+ if (mutation)
66
+ return mutation.path;
37
67
  if (toolName === "read") {
38
68
  if (typeof inputObj.path === "string")
39
69
  return inputObj.path;
@@ -163,11 +193,12 @@ function isIndentationOnlyChange(before, after) {
163
193
  return beforeLines.every((line, index) => line.trim() === afterLines[index].trim());
164
194
  }
165
195
  function getNewContentFromToolCall(event) {
166
- if (isToolCallEventType("write", event)) {
196
+ const mutation = classifyMutatingTool(event);
197
+ if (mutation?.kind === "write") {
167
198
  return event.input
168
199
  .content;
169
200
  }
170
- if (isToolCallEventType("edit", event)) {
201
+ if (mutation?.kind === "edit") {
171
202
  const edits = event.input.edits;
172
203
  return edits?.map((edit) => edit.newText ?? "").join("\n");
173
204
  }
@@ -274,10 +305,20 @@ export async function handleToolCall(deps) {
274
305
  }
275
306
  async function handleToolCallImpl(deps) {
276
307
  const { event, ctx, lensEnabled, getFlag, dbg, runtime, cacheManager, ensureLSPConfigInitialized, updateLspStatus, resetLSPService, getTreeSitterClient = getSharedTreeSitterClient, } = deps;
308
+ // #2423 review round 4, finding F5: the hashline anchor memo is keyed by
309
+ // mtime+size, which a same-size rewrite inside one mtime tick cannot
310
+ // distinguish from stale content. It only ever needs to survive the
311
+ // several `classifyMutatingTool` asks WITHIN this one tool_call, so drop
312
+ // it here at the boundary rather than trusting mtime+size across calls.
313
+ dropHashlineAnchorMemo();
277
314
  const readGuardCorrelationId = getReadGuardCorrelationId(event);
278
315
  let filePath;
279
316
  const logToolReadGuardEvent = (entry) => logReadGuardEvent({ ...entry, correlationId: readGuardCorrelationId });
280
317
  const toolName = event.toolName ?? "";
318
+ // #2423: one classification per tool_call, reused by every branch below that
319
+ // used to compare `toolName` to the `"write"` / `"edit"` literals. No ctx —
320
+ // `filePath` is not resolved yet, and adapters stay silent without one.
321
+ const mutation = classifyMutatingTool(event);
281
322
  const editInputForTelemetry = event.input;
282
323
  // #1655 item 3: SNAPSHOT the requested batch width here, at handler entry.
283
324
  // `input` is a live, mutable, extension-ordered object — pi types it
@@ -291,12 +332,12 @@ async function handleToolCallImpl(deps) {
291
332
  // object hundreds of lines and several `await`s later, so a batch that
292
333
  // changed width in between produced an internally inconsistent summary —
293
334
  // indexes from the call-time array, totals from the mutated one.
294
- const requestedEditIndexes = toolName === "write"
335
+ const requestedEditIndexes = mutation?.kind === "write"
295
336
  ? [0]
296
337
  : Array.isArray(editInputForTelemetry?.edits)
297
338
  ? boundedIndexesForCount(editInputForTelemetry.edits.length)
298
339
  : [0];
299
- const requestedEditTotal = toolName === "write"
340
+ const requestedEditTotal = mutation?.kind === "write"
300
341
  ? 1
301
342
  : Array.isArray(editInputForTelemetry?.edits)
302
343
  ? editInputForTelemetry.edits.length
@@ -374,6 +415,46 @@ async function handleToolCallImpl(deps) {
374
415
  }
375
416
  }
376
417
  }
418
+ // #2430: the observational net. A call the seam could NOT classify, whose
419
+ // input still names a file, gets a bounded pre-snapshot so the tool_result
420
+ // side can see whether it actually wrote anything. `bash` is excluded
421
+ // because it already has its own (wider, git-first) baseline above, and a
422
+ // classified mutation never reaches here at all — that is what keeps the
423
+ // cost of a plain write/edit at zero.
424
+ //
425
+ // `isProvisionalLearnedAttribution` is the ONE exception (#2449 review round
426
+ // 2, F2): a tool attributed from a single observation IS classified from
427
+ // here on, but its attribution has not earned persistence yet, and the only
428
+ // thing that can earn it is a second real disk diff. Without this clause the
429
+ // tool is classified on call two and never observed again, so
430
+ // `PERSIST_AFTER_OBSERVATIONS = 2` is unreachable and nothing is ever
431
+ // written to disk for the next session to learn from.
432
+ //
433
+ // The eligibility check inside `armObservedMutation` is a map lookup, so an
434
+ // ineligible tool (durably attributed, or twice observed clean) pays that
435
+ // and nothing else. The universe is the TARGET PATH alone, so an armed call
436
+ // costs one stat plus one hash of the file it named — not a directory walk.
437
+ if ((mutation === undefined || isProvisionalLearnedAttribution(toolName)) &&
438
+ toolName !== "bash" &&
439
+ !getFlag("no-read-guard")) {
440
+ const observedRawPath = readMutationPathField(event);
441
+ const observedPath = observedRawPath
442
+ ? resolveToolCallFilePath(observedRawPath, ctx.cwd, runtime.projectRoot)
443
+ ?.path
444
+ : undefined;
445
+ if (observedPath) {
446
+ await armObservedMutation({
447
+ toolCallId: resolveToolCallCorrelationId(event),
448
+ toolName,
449
+ targetPath: observedPath,
450
+ cwd: ctx.cwd ?? runtime.projectRoot,
451
+ sessionGeneration: runtime.sessionGeneration,
452
+ turnIndex: runtime.turnIndex,
453
+ signal: ctx.signal,
454
+ dbg,
455
+ });
456
+ }
457
+ }
377
458
  if (getFlag("lens-guard") &&
378
459
  isGitCommitOrPushAttempt(toolName, event.input)) {
379
460
  const guard = evaluateGitGuard(runtime, cacheManager, ctx.cwd ?? runtime.projectRoot);
@@ -419,7 +500,7 @@ async function handleToolCallImpl(deps) {
419
500
  return;
420
501
  dbg(`tool_call fired for: ${filePath} (exists: ${nodeFs.existsSync(filePath)})`);
421
502
  const toolCallId = resolveToolCallCorrelationId(event);
422
- const attributesMutationTarget = toolCallId !== undefined && (toolName === "write" || toolName === "edit");
503
+ const attributesMutationTarget = toolCallId !== undefined && mutation !== undefined;
423
504
  const targetMissing = !nodeFs.existsSync(filePath);
424
505
  // #1642 F1: a brand-new file's WRITE is never a "skip" — `tool_call`
425
506
  // fires PRE-execution, so `existsSync` is false for every path a write
@@ -457,7 +538,7 @@ async function handleToolCallImpl(deps) {
457
538
  // those paths have no quote and no AM/PM, so every stage-2 candidate
458
539
  // collapses onto the base path and nothing is "tried". `unresolved` is
459
540
  // the whole condition; the tried list is detail for the reason string.
460
- if (toolName !== "write" && pathResolution?.unresolved) {
541
+ if (mutation?.kind !== "write" && pathResolution?.unresolved) {
461
542
  const tried = pathResolution.triedVariants.length > 0
462
543
  ? `tried ${pathResolution.triedVariants.join(", ")}`
463
544
  : "no variant differed from the resolved path";
@@ -480,8 +561,7 @@ async function handleToolCallImpl(deps) {
480
561
  const shouldWarmReadLsp = toolName === "read" &&
481
562
  lspAutoTouchEligible &&
482
563
  runtime.shouldWarmLspOnRead(filePath);
483
- const shouldAutoTouch = (toolName === "write" ||
484
- toolName === "edit" ||
564
+ const shouldAutoTouch = (mutation !== undefined ||
485
565
  toolName === "lsp_navigation" ||
486
566
  shouldWarmReadLsp) &&
487
567
  !getFlag("no-lsp") &&
@@ -675,13 +755,41 @@ async function handleToolCallImpl(deps) {
675
755
  timestamp: Date.now(),
676
756
  });
677
757
  }
678
- const { complexityClient } = await loadBootstrapClients();
679
758
  // Record complexity baseline for historical tracking (booboo/tdi).
680
759
  // Not shown inline - just captured for delta analysis.
760
+ //
761
+ // #2467: every client-free guard runs FIRST, so a tool call that cannot
762
+ // produce a baseline never loads the analyzer graph. This await used to sit
763
+ // above them and fire on EVERY tool_call — a bash command, a grep, a read
764
+ // of a vendored file, a second read of an already-baselined file all paid
765
+ // the seventeen-module load.
766
+ //
767
+ // `isComplexitySupportedFile` is the LAST of those guards and the one that
768
+ // matters most in a real repo: complexity has node mappings for six
769
+ // grammars, so every .md/.json/.yaml/.css/.java/.sh read is unsupported.
770
+ // Asking the CLIENT (`isSupportedFile`) would mean loading the graph to
771
+ // learn the answer is no — and because only a produced baseline memoizes
772
+ // the file, the same read would pay it again on every repeat. The predicate
773
+ // is the client's own answer, hoisted into `tree-sitter-shared.ts` where it
774
+ // needs nothing but the extension registry; `ComplexityClient.isSupportedFile`
775
+ // delegates to it, so this is not a second copy.
681
776
  if (!isExternalOrVendor &&
682
- complexityClient.isSupportedFile(filePath) &&
683
- !runtime.complexityBaselines.has(filePath)) {
684
- const baseline = await complexityClient.analyzeFile(filePath);
777
+ filePath &&
778
+ !runtime.complexityBaselines.has(filePath) &&
779
+ isComplexitySupportedFile(filePath)) {
780
+ // Fail open: no clients means no baseline for this call, counted once in
781
+ // the ledger. A complexity baseline is delta-analysis bookkeeping — it
782
+ // must never be the reason a user's tool call fails or stalls.
783
+ const complexityClient = (await requestBootstrapClients({
784
+ reason: "tool-call-complexity-baseline",
785
+ // The pre-dispatch hook. It carries no wall budget in #2523's
786
+ // contract, which is why `LedgerHookKey` names it alongside the
787
+ // budgeted families rather than leaving this site to spell its
788
+ // own axis value (#2557 review F7).
789
+ hook: "tool_call",
790
+ signal: getAmbientAbortSignal(),
791
+ }))?.complexityClient;
792
+ const baseline = await complexityClient?.analyzeFile(filePath);
685
793
  if (baseline) {
686
794
  runtime.complexityBaselines.set(filePath, baseline);
687
795
  const { captureSnapshot } = await import("./metrics-history.js");
@@ -698,8 +806,8 @@ async function handleToolCallImpl(deps) {
698
806
  // --- Read-Before-Edit Guard: check edits ---
699
807
  // write = full replacement; no prior read needed (you're starting fresh).
700
808
  // edit = partial modification; guard enforced to prevent blind overwrites.
701
- const isEditOnly = isToolCallEventType("edit", event);
702
- const isWriteOrEdit = isToolCallEventType("write", event) || isEditOnly;
809
+ const isEditOnly = mutation?.kind === "edit";
810
+ const isWriteOrEdit = mutation !== undefined;
703
811
  // Track any Write so recordWritten can inject a synthetic read afterward.
704
812
  // The agent authored the content (new or overwritten), so it trivially "knows" the file.
705
813
  if (!isEditOnly && isWriteOrEdit && filePath && !getFlag("no-read-guard")) {
@@ -912,7 +1020,7 @@ async function handleToolCallImpl(deps) {
912
1020
  const isExistingFile = typeof readGuard?.isNewFile !== "function" ||
913
1021
  !readGuard.isNewFile(filePath);
914
1022
  if (readGuard && isExistingFile && !isExternalOrVendor) {
915
- const { touchedLines, editRanges, preflightError, partiallyApplicable, contentMatchValidated, editBatchSummary, } = getTouchedLinesForGuard(event, filePath, runtime.telemetrySessionId, readGuardCorrelationId);
1023
+ const { touchedLines, editRanges, preflightError, preflightDetails, alreadyAppliedEdits, partiallyApplicable, contentMatchValidated, editBatchSummary, } = getTouchedLinesForGuard(event, filePath, runtime.telemetrySessionId, readGuardCorrelationId, runtime.partialApplyRecords);
916
1024
  if (preflightError) {
917
1025
  if (partiallyApplicable && partiallyApplicable.length > 0) {
918
1026
  try {
@@ -921,6 +1029,7 @@ async function handleToolCallImpl(deps) {
921
1029
  edits: partiallyApplicable,
922
1030
  summary: editBatchSummary,
923
1031
  correlationId: readGuardCorrelationId,
1032
+ recordStore: runtime.partialApplyRecords,
924
1033
  afterWrite: async () => {
925
1034
  const { biomeClient, ruffClient, metricsClient, agentBehaviorClient, } = await loadBootstrapClients();
926
1035
  const result = await handleToolResult({
@@ -962,10 +1071,32 @@ async function handleToolCallImpl(deps) {
962
1071
  .join("\n\n");
963
1072
  },
964
1073
  });
1074
+ if (partial.rejected) {
1075
+ // Nothing was written and no post-edit dispatch ran. The
1076
+ // preflight verdict still describes the whole batch; append
1077
+ // the structured rejection so the agent rebuilds from a
1078
+ // fresh read instead of retrying the stale payload.
1079
+ if (!editBatchSummary)
1080
+ logBlockedEditSummary("preflight");
1081
+ return {
1082
+ block: true,
1083
+ reason: `${preflightError}\n\n🛑 Batch not applied: ${partial.rejected.detail}`,
1084
+ };
1085
+ }
965
1086
  if (partial.postEditStatus === "failed") {
1087
+ // The commit stands; the post-edit analysis does not. The
1088
+ // committed bytes must never be re-labelled by the preflight
1089
+ // header (a RETRYABLE/RE-READ line here sends the agent into
1090
+ // the #2402 retry loop against already-applied edits).
966
1091
  return {
967
1092
  block: true,
968
- reason: `${preflightError}\n\nPartial apply pipeline failed after ${partial.appliedCount} edit${partial.appliedCount === 1 ? "" : "s"} committed.`,
1093
+ reason: composePartialApplyReason({
1094
+ appliedCount: partial.appliedCount,
1095
+ appliedIndices: partial.appliedIndices,
1096
+ postEditStatus: "failed",
1097
+ preflightDetails,
1098
+ alreadyAppliedEdits,
1099
+ }),
969
1100
  };
970
1101
  }
971
1102
  if (partial.appliedCount > 0) {
@@ -977,23 +1108,25 @@ async function handleToolCallImpl(deps) {
977
1108
  appliedCount: partial.appliedCount,
978
1109
  appliedTotal: partial.appliedTotal,
979
1110
  appliedIndices: partial.appliedIndices,
980
- skippedCount: partial.skippedCount ?? 0,
981
- skippedTotal: partial.skippedTotal ?? 0,
982
- skippedIndices: partial.skippedIndices ?? "",
983
- indexesTruncated: partial.indexesTruncated ?? false,
984
1111
  editBatchSummary: partial.summary,
985
1112
  routedThroughPostEditPipeline: true,
986
1113
  },
987
1114
  });
988
- let reason = preflightError.replace("🔄 RETRYABLE — Edit target not found", `⚠️ PARTIAL APPLY — ${partial.appliedCount} edit${partial.appliedCount !== 1 ? "s" : ""} applied (${partial.appliedIndices})`);
989
- if (partial.postEditOutput) {
990
- reason += `\n\nPost-apply analysis:\n${partial.postEditOutput}`;
991
- }
992
- return { block: true, reason };
1115
+ return {
1116
+ block: true,
1117
+ reason: composePartialApplyReason({
1118
+ appliedCount: partial.appliedCount,
1119
+ appliedIndices: partial.appliedIndices,
1120
+ postEditStatus: "succeeded",
1121
+ postEditOutput: partial.postEditOutput,
1122
+ preflightDetails,
1123
+ alreadyAppliedEdits,
1124
+ }),
1125
+ };
993
1126
  }
994
1127
  }
995
1128
  catch {
996
- // fall through to full block
1129
+ // commit write failure — fall through to the full preflight block
997
1130
  }
998
1131
  }
999
1132
  if (!editBatchSummary)
@@ -1005,7 +1138,7 @@ async function handleToolCallImpl(deps) {
1005
1138
  sessionId: runtime.telemetrySessionId,
1006
1139
  filePath,
1007
1140
  metadata: {
1008
- tool: isToolCallEventType("write", event) ? "write" : "edit",
1141
+ tool: mutation?.kind ?? "edit",
1009
1142
  touchedLines: touchedLines ?? null,
1010
1143
  isExistingFile,
1011
1144
  },