@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
@@ -4,6 +4,7 @@ import { fileURLToPath } from "node:url";
4
4
  import { Worker } from "node:worker_threads";
5
5
  import { gunzipSync, gzipSync } from "node:zlib";
6
6
  import { writeFileAtomic } from "./atomic-write.js";
7
+ import { BoundedFifoMap } from "./bounded-cache.js";
7
8
  import { getProjectDataDir } from "./file-utils.js";
8
9
  import { incrementDegradationCount } from "./degradation-ledger.js";
9
10
  import { readJsonCache } from "./json-cache-read.js";
@@ -130,14 +131,14 @@ export function readProjectSnapshotMeta(cwd) {
130
131
  export function isProjectSnapshotMetaStale(meta, currentProjectSeq) {
131
132
  return (meta.version !== PROJECT_SNAPSHOT_VERSION || meta.seq !== currentProjectSeq);
132
133
  }
133
- const SNAPSHOT_PARSE_CACHE_MAX = 4;
134
+ export const SNAPSHOT_PARSE_CACHE_MAX = 4;
134
135
  // #957 review: the cache exists to avoid re-parsing NORMAL snapshots within a
135
136
  // session. A 112MB-class body parses to hundreds of MB of heap — pinning that
136
137
  // for process lifetime inverts the win, so oversized bodies are simply never
137
138
  // cached (they re-parse per read, exactly the pre-#947 behavior). Measured
138
139
  // against the UNCOMPRESSED body size, never the (much smaller) gz file size.
139
140
  const SNAPSHOT_PARSE_CACHE_MAX_BYTES = 24 * 1024 * 1024;
140
- const snapshotParseCache = new Map();
141
+ const snapshotParseCache = new BoundedFifoMap(SNAPSHOT_PARSE_CACHE_MAX);
141
142
  function withoutWordIndex(snapshot) {
142
143
  if (!snapshot?.wordIndex)
143
144
  return snapshot;
@@ -145,18 +146,13 @@ function withoutWordIndex(snapshot) {
145
146
  return stripped;
146
147
  }
147
148
  function cacheParsedSnapshot(snapshotPath, entry) {
148
- // Refresh recency (Map preserves insertion order).
149
+ // Refresh recency (delete then set moves the key to the newest position;
150
+ // BoundedFifoMap itself never reorders an already-present key on set()).
149
151
  snapshotParseCache.delete(snapshotPath);
150
152
  snapshotParseCache.set(snapshotPath, entry);
151
- while (snapshotParseCache.size > SNAPSHOT_PARSE_CACHE_MAX) {
152
- const oldest = snapshotParseCache.keys().next().value;
153
- if (oldest === undefined)
154
- break;
155
- snapshotParseCache.delete(oldest);
156
- }
157
153
  }
158
154
  const authoritativeSnapshots = new Map();
159
- const PROJECT_SNAPSHOT_MAX_WARM_ROOTS = 8;
155
+ export const PROJECT_SNAPSHOT_MAX_WARM_ROOTS = 8;
160
156
  const PROJECT_SNAPSHOT_IDLE_EVICT_MS_DEFAULT = 20 * 60_000;
161
157
  function projectSnapshotIdleEvictMs() {
162
158
  const value = Number.parseInt(process.env.PI_LENS_PROJECT_SNAPSHOT_IDLE_EVICT_MS ?? "", 10);
@@ -620,8 +616,8 @@ export function loadProjectSnapshotWithoutWordIndex(cwd) {
620
616
  return loadProjectSnapshotInternal(cwd, false);
621
617
  }
622
618
  const _snapshotGenerationStates = new Map();
623
- const _successfulSnapshotPersists = new Map();
624
- const _failedSnapshotPersists = new Map();
619
+ const _successfulSnapshotPersists = new BoundedFifoMap(PROJECT_SNAPSHOT_MAX_WARM_ROOTS);
620
+ const _failedSnapshotPersists = new BoundedFifoMap(PROJECT_SNAPSHOT_MAX_WARM_ROOTS);
625
621
  const _activeSnapshotPersists = new Map();
626
622
  const _queuedSnapshotPersists = new Map();
627
623
  const _snapshotWorkerRequests = new Map();
@@ -648,12 +644,6 @@ function pendingSnapshotIsCurrent(pending) {
648
644
  function rememberSuccessfulSnapshotPersist(key, record) {
649
645
  _successfulSnapshotPersists.delete(key);
650
646
  _successfulSnapshotPersists.set(key, record);
651
- while (_successfulSnapshotPersists.size > PROJECT_SNAPSHOT_MAX_WARM_ROOTS) {
652
- const oldest = _successfulSnapshotPersists.keys().next().value;
653
- if (oldest === undefined)
654
- break;
655
- _successfulSnapshotPersists.delete(oldest);
656
- }
657
647
  }
658
648
  function assessSnapshotBodyIntegrity(meta, body) {
659
649
  if (meta.gzBytes === undefined) {
@@ -808,12 +798,6 @@ function recordSnapshotPersistFailure(pending, error, bodyPersisted = false) {
808
798
  seq: pending.snapshot.seq,
809
799
  generation: pending.generation,
810
800
  });
811
- while (_failedSnapshotPersists.size > PROJECT_SNAPSHOT_MAX_WARM_ROOTS) {
812
- const oldest = _failedSnapshotPersists.keys().next().value;
813
- if (oldest === undefined)
814
- break;
815
- _failedSnapshotPersists.delete(oldest);
816
- }
817
801
  deleteAuthoritativeSnapshot(pending.key);
818
802
  logLatency({
819
803
  type: "phase",
@@ -1492,6 +1476,50 @@ export function setProjectSnapshotPromotionSeamForTests(seam) {
1492
1476
  export function getProjectSnapshotPersistErrorForTests() {
1493
1477
  return _lastSnapshotPersistErrorForTests;
1494
1478
  }
1479
+ // ── #2442 test-only seams: exercise the three BoundedFifoMap-backed caches ──
1480
+ // through the exact same write path production uses (cacheParsedSnapshot /
1481
+ // rememberSuccessfulSnapshotPersist's delete+set refresh, and a direct write
1482
+ // mirroring recordSnapshotPersistFailure's), without the real gzip/worker
1483
+ // persistence pipeline or a full ProjectSnapshot fixture.
1484
+ /** Test-only: seed the parse cache exactly as `cacheParsedSnapshot` would. */
1485
+ export function _seedSnapshotParseCacheForTests(key, entry) {
1486
+ cacheParsedSnapshot(key, entry);
1487
+ }
1488
+ export function _snapshotParseCacheKeysForTests() {
1489
+ return [...snapshotParseCache.keys()];
1490
+ }
1491
+ /**
1492
+ * #2442 test-only: the exact `snapshotParseCache.get(key)` the production
1493
+ * read at {@link loadProjectSnapshot}'s parse-cache hit performs. A `.has()`
1494
+ * would not do — `.has()` reorders nothing on either bounded class, so a
1495
+ * has-based test cannot tell FIFO from LRU, which is the axis these bounded
1496
+ * tests exist to pin (#2442 review F4).
1497
+ */
1498
+ export function _snapshotParseCacheGetForTests(key) {
1499
+ return snapshotParseCache.get(key) !== undefined;
1500
+ }
1501
+ /** Test-only: seed the successful-persist cache exactly as production would. */
1502
+ export function _seedSuccessfulSnapshotPersistForTests(key, record) {
1503
+ rememberSuccessfulSnapshotPersist(key, record);
1504
+ }
1505
+ export function _successfulSnapshotPersistKeysForTests() {
1506
+ return [..._successfulSnapshotPersists.keys()];
1507
+ }
1508
+ /** #2442 test-only: the same `_successfulSnapshotPersists.get(key)` the
1509
+ * persist-dedupe read and `getProjectSnapshotPersistStateForTests` perform.
1510
+ * See {@link _snapshotParseCacheGetForTests} for why `.has()` will not do. */
1511
+ export function _successfulSnapshotPersistGetForTests(key) {
1512
+ return _successfulSnapshotPersists.get(key) !== undefined;
1513
+ }
1514
+ /** Test-only: seed the failed-persist cache with the same write
1515
+ * `recordSnapshotPersistFailure` performs, without its side effects
1516
+ * (deleteAuthoritativeSnapshot / logLatency) or a full PendingSnapshotBody. */
1517
+ export function _seedFailedSnapshotPersistForTests(key, record) {
1518
+ _failedSnapshotPersists.set(key, record);
1519
+ }
1520
+ export function _failedSnapshotPersistKeysForTests() {
1521
+ return [..._failedSnapshotPersists.keys()];
1522
+ }
1495
1523
  export function buildProjectSnapshotFromRuntime(args) {
1496
1524
  return {
1497
1525
  version: PROJECT_SNAPSHOT_VERSION,
@@ -0,0 +1,217 @@
1
+ import { access, readFile } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { extractTomlTableSection, hasTomlTable, parseTomlStringArray, } from "./cargo-manifest.js";
5
+ import { isAtOrAboveHomeDir, matchesWorkspaceMemberPattern, toPosix, UV_WORKSPACE_EXCLUDE_DIALECT, UV_WORKSPACE_MEMBERS_DIALECT, walkUpDirs, } from "./path-utils.js";
6
+ const UV_WORKSPACE_TABLE = "tool\\.uv\\.workspace";
7
+ /**
8
+ * Resolve the uv workspace root using the same discovery shape as uv:
9
+ * start at the nearest pyproject, then continue upward for an explicit
10
+ * `[tool.uv.workspace]` declaration. A nearest pyproject without that table
11
+ * is an implicit single-project workspace.
12
+ *
13
+ * The walk stops AT `homeDir` (`isAtOrAboveHomeDir`, the shared ceiling
14
+ * primitive from #625) so a `pyproject.toml` sitting in `/tmp`, `/home`, or
15
+ * `$HOME` itself cannot supply the environment for every project beneath it.
16
+ * `homeDir` is injected rather than read from `os.homedir()` inside the walk
17
+ * for the same reason every sibling walker takes it (#2536, #2544 F2): the
18
+ * ceiling is otherwise untestable.
19
+ */
20
+ async function findUvWorkspace(startDir, homeDir) {
21
+ const resolvedStart = path.resolve(startDir);
22
+ let nearestProject;
23
+ for (const dir of walkUpDirs(startDir)) {
24
+ if (isAtOrAboveHomeDir(dir, homeDir))
25
+ break;
26
+ let content;
27
+ try {
28
+ content = await readFile(path.join(dir, "pyproject.toml"), "utf8");
29
+ }
30
+ catch {
31
+ continue;
32
+ }
33
+ if (!nearestProject)
34
+ nearestProject = dir;
35
+ if (hasTomlTable(content, UV_WORKSPACE_TABLE)) {
36
+ const workspaceTable = extractTomlTableSection(content, UV_WORKSPACE_TABLE);
37
+ return {
38
+ root: dir,
39
+ explicit: true,
40
+ projectRoot: nearestProject,
41
+ isStartDir: nearestProject === resolvedStart,
42
+ members: parseTomlStringArray(workspaceTable, "members"),
43
+ exclude: parseTomlStringArray(workspaceTable, "exclude"),
44
+ };
45
+ }
46
+ }
47
+ return nearestProject
48
+ ? {
49
+ root: nearestProject,
50
+ explicit: false,
51
+ projectRoot: nearestProject,
52
+ isStartDir: nearestProject === resolvedStart,
53
+ members: [],
54
+ exclude: [],
55
+ }
56
+ : undefined;
57
+ }
58
+ /**
59
+ * Apply uv's explicit-workspace membership rules before inheriting its root
60
+ * environment. The workspace root is always a member; descendants must match
61
+ * a declared member glob and must not match an exclusion glob.
62
+ *
63
+ * The glob dialects are pinned to uv 3c979abda4530fe9bf3d92e9bcf5c5575e3b3126,
64
+ * `crates/uv-workspace/src/workspace.rs`, and live beside the ONE shared
65
+ * workspace-member matcher (#2591) instead of as a minimatch options block
66
+ * here: `UV_WORKSPACE_MEMBERS_DIALECT` for `members`
67
+ * (`is_included_in_workspace` — `MatchOptions { require_literal_separator:
68
+ * true, ..MatchOptions::new() }`) and `UV_WORKSPACE_EXCLUDE_DIALECT` for
69
+ * `exclude` (`WorkspaceExclusions::matches` — `Pattern::matches_path`, i.e.
70
+ * `MatchOptions::new()` defaults, where `require_literal_separator` is FALSE
71
+ * and a `*` therefore crosses `/`). Both normalize the pattern first
72
+ * (`normalize_path`, so a leading `./` is not part of the pattern) and are
73
+ * case-SENSITIVE on every platform with no literal-leading-dot requirement.
74
+ *
75
+ * That `exclude` option set used to be a documented limitation rather than
76
+ * behavior: minimatch cannot express a separator-crossing `*`, so
77
+ * `exclude = ['packages/a*c']` did not exclude `packages/a/b/c`. A dialect
78
+ * object can, so #2591 implements it — the one intentional answer change in
79
+ * that fold.
80
+ */
81
+ function isUvWorkspaceMember(workspace, projectRoot) {
82
+ // No `projectRoot === workspace.root` shortcut. uv treats the workspace
83
+ // root as a member of its own workspace, but only in its capacity as a
84
+ // PROJECT — and a project already gets uv's settings through `isStartDir`,
85
+ // with its own `<root>/.venv` reached by the ordinary project candidate at
86
+ // the very same path. Answering "member" on directory equality made every
87
+ // non-project subdirectory of the workspace root inherit the workspace
88
+ // `.venv`, `exclude` included, because equality was tested before the
89
+ // walk result was consulted (review round 3, S2). The relative-path guard
90
+ // below returns false for the root itself, which is the intended answer.
91
+ const relative = toPosix(path.relative(workspace.root, projectRoot));
92
+ if (relative.length === 0 ||
93
+ relative === ".." ||
94
+ relative.startsWith("../") ||
95
+ path.isAbsolute(relative)) {
96
+ return false;
97
+ }
98
+ const matches = (dialect) => (pattern) => matchesWorkspaceMemberPattern(pattern, relative, dialect);
99
+ return (!workspace.exclude.some(matches(UV_WORKSPACE_EXCLUDE_DIALECT)) &&
100
+ workspace.members.some(matches(UV_WORKSPACE_MEMBERS_DIALECT)));
101
+ }
102
+ /**
103
+ * Resolve the interpreter and executable directory for the project's Python
104
+ * environment without activating it or invoking a package manager.
105
+ */
106
+ export async function detectPythonEnvironment(projectRoot, homeDir = os.homedir()) {
107
+ // `path.resolve` once at the seam entry so `isStartDir` below compares like
108
+ // with like: `walkUpDirs` resolves its input, a caller's argument need not
109
+ // be normalized.
110
+ const root = path.resolve(projectRoot);
111
+ const uvWorkspace = await findUvWorkspace(root, homeDir);
112
+ // `UV_PROJECT_ENVIRONMENT` and the workspace `.venv` are uv PROJECT
113
+ // settings. uv applies them to a directory only when that directory IS the
114
+ // project — a `pyproject.toml` merely sitting somewhere ABOVE it makes it a
115
+ // subdirectory of a project, not a project, and nothing below a project
116
+ // root inherits from it (the F3 decision, applied consistently). Exporting
117
+ // `UV_PROJECT_ENVIRONMENT` process-wide is uv's own documented CI/Docker
118
+ // recipe, so a gate on "a pyproject exists at or above root" lets one
119
+ // image-level variable capture every subdirectory on the box that happens
120
+ // to sit under some Python project.
121
+ const isProjectRoot = uvWorkspace?.isStartDir === true;
122
+ // A declared, non-excluded member of an EXPLICIT workspace is itself a
123
+ // project root, so this is a strict refinement of `isProjectRoot`: it adds
124
+ // the workspace `.venv` candidate and re-anchors a relative
125
+ // `UV_PROJECT_ENVIRONMENT` at the workspace root.
126
+ const memberWorkspaceRoot = isProjectRoot &&
127
+ uvWorkspace.explicit &&
128
+ isUvWorkspaceMember(uvWorkspace, root)
129
+ ? uvWorkspace.root
130
+ : undefined;
131
+ const uvEnvironmentRoot = isProjectRoot
132
+ ? (memberWorkspaceRoot ?? uvWorkspace.projectRoot)
133
+ : undefined;
134
+ const uvProjectEnvironment = process.env.UV_PROJECT_ENVIRONMENT;
135
+ // PEP 723 `uv run --script` environments are cache-keyed by script content;
136
+ // without a stable project marker or explicit path, they remain undiscoverable.
137
+ const candidates = [
138
+ ...(uvEnvironmentRoot !== undefined && uvProjectEnvironment
139
+ ? [
140
+ {
141
+ // `path.resolve` leaves an absolute value untouched and
142
+ // anchors a relative one at the project's workspace root.
143
+ root: path.resolve(uvEnvironmentRoot, uvProjectEnvironment),
144
+ source: "uv-project-environment",
145
+ },
146
+ ]
147
+ : []),
148
+ ...(memberWorkspaceRoot !== undefined
149
+ ? [
150
+ {
151
+ root: path.join(memberWorkspaceRoot, ".venv"),
152
+ source: "uv-workspace",
153
+ },
154
+ ]
155
+ : []),
156
+ { root: process.env.VIRTUAL_ENV, source: "virtual-env" },
157
+ { root: process.env.CONDA_PREFIX, source: "conda" },
158
+ { root: path.join(root, ".venv"), source: "project-dot-venv" },
159
+ { root: path.join(root, "venv"), source: "project-venv" },
160
+ ];
161
+ for (const candidate of candidates) {
162
+ if (!candidate.root)
163
+ continue;
164
+ const binDir = path.join(candidate.root, process.platform === "win32" ? "Scripts" : "bin");
165
+ const pythonPath = path.join(binDir, process.platform === "win32" ? "python.exe" : "python");
166
+ try {
167
+ await access(pythonPath);
168
+ return {
169
+ root: candidate.root,
170
+ binDir,
171
+ pythonPath,
172
+ source: candidate.source,
173
+ };
174
+ }
175
+ catch {
176
+ // The marker can outlive its environment. Continue to the next candidate.
177
+ }
178
+ }
179
+ return undefined;
180
+ }
181
+ /** Preserve the existing interpreter-only API used by LSP initialization. */
182
+ export async function detectPythonVenv(projectRoot) {
183
+ return (await detectPythonEnvironment(projectRoot))?.pythonPath;
184
+ }
185
+ /**
186
+ * Build a child-only environment for Python tools. The host process remains
187
+ * unchanged, so another project can resolve a different environment.
188
+ */
189
+ export function augmentPythonEnvironment(baseEnvironment, environment) {
190
+ if (!environment)
191
+ return baseEnvironment;
192
+ const inheritedPath = baseEnvironment.PATH ?? baseEnvironment.Path ?? baseEnvironment.path ?? "";
193
+ const augmentedPath = inheritedPath
194
+ ? `${environment.binDir}${path.delimiter}${inheritedPath}`
195
+ : environment.binDir;
196
+ const childEnvironment = {
197
+ ...baseEnvironment,
198
+ PATH: augmentedPath,
199
+ VIRTUAL_ENV: environment.root,
200
+ };
201
+ if (process.platform === "win32")
202
+ childEnvironment.Path = augmentedPath;
203
+ return childEnvironment;
204
+ }
205
+ /** Return explicit project-environment candidates before a bare PATH fallback. */
206
+ export function pythonEnvironmentToolCandidates(environment, command) {
207
+ if (!environment)
208
+ return [];
209
+ if (process.platform !== "win32") {
210
+ return [path.join(environment.binDir, command)];
211
+ }
212
+ return [
213
+ path.join(environment.binDir, `${command}.exe`),
214
+ path.join(environment.binDir, `${command}.cmd`),
215
+ path.join(environment.binDir, command),
216
+ ];
217
+ }