@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,4 +1,4 @@
1
- import { createDeadline, yieldIfOverBudget } from "./cooperative-budget.js";
1
+ import { createDeadline, yieldIfOverBudget, } from "./cooperative-budget.js";
2
2
  /**
3
3
  * Packed backing store for the word index's inverted postings (#2069).
4
4
  *
@@ -248,8 +248,20 @@ export function compactPostingsIntoArena(postings) {
248
248
  *
249
249
  * Each `adoptArena` copies and re-homes one list within a single synchronous
250
250
  * step, so readers never observe a partially written list.
251
+ *
252
+ * `options.deadline` and `options.beforeYield` are a test seam only (#2293):
253
+ * production always takes the default 8 ms wall-clock deadline. The #2117
254
+ * regression test used to prove the "grew during a yield" invariant by racing
255
+ * a real timer against a 40,000-list copy, which made the yield itself a
256
+ * scheduling accident — the copy sometimes finished inside the 8 ms budget
257
+ * and never yielded at all, so the test's own precondition went unmet under
258
+ * load. Injecting a deadline lets a test force a yield deterministically
259
+ * instead of hoping wall-clock crosses the budget; `beforeYield` runs
260
+ * in-line, immediately before the real cooperative pause, so a test can
261
+ * mutate a not-yet-adopted list at that exact point with no reliance on
262
+ * event-loop scheduling order.
251
263
  */
252
- export async function compactPostingsIntoArenaCooperatively(postings) {
264
+ export async function compactPostingsIntoArenaCooperatively(postings, options) {
253
265
  // Snapshot (token, list, width) in one synchronous pass; the arena is sized
254
266
  // from these widths and only unchanged lists are adopted, so the sum of the
255
267
  // widths actually written can never exceed the arena length.
@@ -264,15 +276,17 @@ export async function compactPostingsIntoArenaCooperatively(postings) {
264
276
  return;
265
277
  const arena = new Int32Array(lanes);
266
278
  let offset = 0;
267
- const deadline = createDeadline(8);
279
+ const deadline = options?.deadline ?? createDeadline(8);
268
280
  for (const plan of planned) {
269
281
  if (postings.get(plan.token) === plan.list &&
270
282
  plan.list.length * 2 === plan.width &&
271
283
  offset + plan.width <= arena.length) {
272
284
  offset = plan.list.adoptArena(arena, offset);
273
285
  }
274
- if (deadline.expired())
286
+ if (deadline.expired()) {
287
+ await options?.beforeYield?.();
275
288
  await yieldIfOverBudget(deadline);
289
+ }
276
290
  }
277
291
  }
278
292
  /**
@@ -375,7 +389,8 @@ export class WordForwardEntry {
375
389
  }
376
390
  /** Pack a tokenizer tally. Insertion order is preserved. */
377
391
  static fromTally(tally) {
378
- const tokenNames = new Array(tally.size);
392
+ const tokenNames = [];
393
+ tokenNames.length = tally.size;
379
394
  const lineCounts = new Int32Array(tally.size);
380
395
  let i = 0;
381
396
  for (const [token, count] of tally) {
@@ -888,7 +888,8 @@ export async function refreshWordIndexIncrementally(index, root, shouldContinue
888
888
  const statConcurrency = Number.isFinite(requestedConcurrency) && requestedConcurrency > 0
889
889
  ? Math.max(1, Math.floor(requestedConcurrency))
890
890
  : WORD_INDEX_STAT_CONCURRENCY;
891
- const statResults = new Array(walked.length);
891
+ const statResults = [];
892
+ statResults.length = walked.length;
892
893
  let cursor = 0;
893
894
  let superseded = false;
894
895
  const worker = async () => {
@@ -1391,6 +1392,22 @@ export function centralityFromReverseDeps(index, reverseDeps, normalizeKey = (fi
1391
1392
  }
1392
1393
  /** Persisted word-index serialization format version. Bump on breaking format changes. */
1393
1394
  export const WORD_INDEX_FORMAT_VERSION = 2;
1395
+ const WORD_INDEX_INT32_MAX = 2_147_483_647;
1396
+ // A file id and line fit in one exact Number key through this boundary.
1397
+ const WORD_INDEX_PACKED_FILE_ID_MAX = 4_194_303;
1398
+ function isCanonicalWordIndexNumber(value) {
1399
+ return (typeof value === "number" &&
1400
+ Number.isFinite(value) &&
1401
+ Number.isSafeInteger(value) &&
1402
+ !Object.is(value, -0));
1403
+ }
1404
+ function isCanonicalWordIndexToken(token) {
1405
+ return (typeof token === "string" &&
1406
+ token.length >= 2 &&
1407
+ token === token.toLowerCase() &&
1408
+ /^[a-z0-9_$]+$/.test(token) &&
1409
+ !STOPWORDS.has(token));
1410
+ }
1394
1411
  const serializedWordIndexCaches = new WeakMap();
1395
1412
  let _lastSerializeWork;
1396
1413
  /** Test-only: work stats for the most recent {@link serializeWordIndex} call. */
@@ -1585,10 +1602,25 @@ export function deserializeWordIndex(data) {
1585
1602
  !Array.isArray(data.files) ||
1586
1603
  !Array.isArray(data.postings) ||
1587
1604
  !Array.isArray(data.docLengths) ||
1588
- !Array.isArray(data.fileMtimes) ||
1589
- data.fileMtimes.length !== data.files.length) {
1605
+ !Array.isArray(data.fileMtimes)) {
1590
1606
  return null;
1591
1607
  }
1608
+ let canonical = data.docLengths.length === data.files.length &&
1609
+ data.fileMtimes.length === data.files.length;
1610
+ let needsDeepSanitize = !Array.isArray(data.forward);
1611
+ if (needsDeepSanitize)
1612
+ canonical = false;
1613
+ const fileKeys = new Set();
1614
+ for (const file of data.files) {
1615
+ if (typeof file !== "string")
1616
+ return null;
1617
+ const key = wordIndexKey(file);
1618
+ if (fileKeys.has(key)) {
1619
+ canonical = false;
1620
+ needsDeepSanitize = true;
1621
+ }
1622
+ fileKeys.add(key);
1623
+ }
1592
1624
  const docLengths = new PathKeyedMap(wordIndexKey);
1593
1625
  // Slot i of the wire `files` array becomes file id `fileIdBySlot[i]`. Two
1594
1626
  // slots whose spellings fold to one key share one id, exactly as a build
@@ -1596,33 +1628,94 @@ export function deserializeWordIndex(data) {
1596
1628
  // posting identities for one document.
1597
1629
  const fileTable = new WordIndexFileTable();
1598
1630
  const fileIdBySlot = data.files.map((file) => fileTable.intern(wordIndexKey(file), file));
1631
+ const slotByFileId = new Map();
1632
+ fileIdBySlot.forEach((fileId, slot) => {
1633
+ if (!slotByFileId.has(fileId))
1634
+ slotByFileId.set(fileId, slot);
1635
+ });
1599
1636
  const fileMtimes = new PathKeyedMap(wordIndexKey);
1600
1637
  const fileSizes = new PathKeyedMap(wordIndexKey);
1601
- data.files.forEach((file, i) => docLengths.set(file, data.docLengths[i] ?? 0));
1602
- data.files.forEach((file, i) => fileMtimes.set(file, data.fileMtimes[i] ?? 0));
1638
+ data.files.forEach((file, i) => {
1639
+ const value = data.docLengths[i];
1640
+ if (!isCanonicalWordIndexNumber(value) || value < 0)
1641
+ canonical = false;
1642
+ docLengths.set(file, isCanonicalWordIndexNumber(value) && value >= 0 ? value : 0);
1643
+ });
1644
+ data.files.forEach((file, i) => {
1645
+ const value = data.fileMtimes[i];
1646
+ if (typeof value !== "number" || !Number.isFinite(value))
1647
+ canonical = false;
1648
+ fileMtimes.set(file, typeof value === "number" && Number.isFinite(value) ? value : 0);
1649
+ });
1603
1650
  // #1105: `fileSizes` is optional on the wire (pre-#1105 snapshots omit it).
1604
1651
  // Only populate when the array is present AND parallel to `files`; otherwise
1605
1652
  // leave it empty so the refresh gate re-reads every file once to repopulate,
1606
1653
  // rather than trusting a bogus/misaligned size. Never treated as "current".
1607
1654
  if (Array.isArray(data.fileSizes) &&
1608
1655
  data.fileSizes.length === data.files.length) {
1609
- data.files.forEach((file, i) => fileSizes.set(file, data.fileSizes?.[i] ?? 0));
1656
+ data.files.forEach((file, i) => {
1657
+ const value = data.fileSizes?.[i];
1658
+ if (!isCanonicalWordIndexNumber(value) || value < 0)
1659
+ canonical = false;
1660
+ fileSizes.set(file, isCanonicalWordIndexNumber(value) && value >= 0 ? value : 0);
1661
+ });
1662
+ }
1663
+ else {
1664
+ canonical = false;
1610
1665
  }
1611
1666
  const postings = new Map();
1612
- for (const [token, flat] of data.postings) {
1613
- if (typeof token !== "string" || !Array.isArray(flat))
1667
+ const postingTokens = new Set();
1668
+ const postingFileCounts = new Map();
1669
+ for (const posting of data.postings) {
1670
+ if (!Array.isArray(posting) || posting.length !== 2) {
1671
+ canonical = false;
1672
+ needsDeepSanitize = true;
1673
+ continue;
1674
+ }
1675
+ const [token, flat] = posting;
1676
+ if (!isCanonicalWordIndexToken(token) ||
1677
+ postingTokens.has(token) ||
1678
+ !Array.isArray(flat) ||
1679
+ flat.length === 0 ||
1680
+ flat.length % 2 !== 0) {
1681
+ canonical = false;
1682
+ needsDeepSanitize = true;
1614
1683
  continue;
1684
+ }
1685
+ postingTokens.add(token);
1615
1686
  const lanes = [];
1616
- for (let i = 0; i + 1 < flat.length; i += 2) {
1617
- const fileId = fileIdBySlot[flat[i]];
1687
+ const seenPairs = new Set();
1688
+ const observedCounts = new Map();
1689
+ for (let i = 0; i < flat.length; i += 2) {
1690
+ const slot = flat[i];
1618
1691
  const line = flat[i + 1];
1619
- if (typeof fileId === "number" && typeof line === "number") {
1620
- lanes.push(fileId, line);
1692
+ if (!isCanonicalWordIndexNumber(slot) ||
1693
+ slot < 0 ||
1694
+ slot >= fileIdBySlot.length ||
1695
+ !isCanonicalWordIndexNumber(line) ||
1696
+ line < 1 ||
1697
+ line > WORD_INDEX_INT32_MAX) {
1698
+ canonical = false;
1699
+ needsDeepSanitize = true;
1700
+ continue;
1621
1701
  }
1702
+ const fileId = fileIdBySlot[slot];
1703
+ const pairKey = fileId <= WORD_INDEX_PACKED_FILE_ID_MAX
1704
+ ? fileId * (WORD_INDEX_INT32_MAX + 1) + line
1705
+ : `${fileId}:${line}`;
1706
+ if (seenPairs.has(pairKey)) {
1707
+ canonical = false;
1708
+ needsDeepSanitize = true;
1709
+ }
1710
+ seenPairs.add(pairKey);
1711
+ lanes.push(fileId, line);
1712
+ observedCounts.set(fileId, (observedCounts.get(fileId) ?? 0) + 1);
1622
1713
  }
1623
- if (lanes.length > 0) {
1624
- postings.set(token, WordPostingList.fromLanes(token, lanes));
1625
- }
1714
+ if (lanes.length === 0)
1715
+ continue;
1716
+ const list = WordPostingList.fromLanes(token, lanes);
1717
+ postings.set(token, list);
1718
+ postingFileCounts.set(token, observedCounts);
1626
1719
  }
1627
1720
  // Every list above was sized exactly from the wire payload, so there is no
1628
1721
  // growth slack to release — but the per-list `ArrayBuffer` headers are the
@@ -1631,34 +1724,128 @@ export function deserializeWordIndex(data) {
1631
1724
  compactPostingsIntoArena(postings);
1632
1725
  let forward;
1633
1726
  if (Array.isArray(data.forward)) {
1634
- forward = new PathKeyedMap(wordIndexKey);
1635
- for (const entry of data.forward) {
1636
- if (!Array.isArray(entry) || entry.length !== 2)
1727
+ const candidate = data.files.map(() => new Map());
1728
+ const forwardTotals = new Map();
1729
+ if (data.forward.length !== data.files.length)
1730
+ canonical = false;
1731
+ if (data.forward.length !== data.files.length)
1732
+ needsDeepSanitize = true;
1733
+ for (const [entryIndex, entry] of data.forward.entries()) {
1734
+ if (!Array.isArray(entry) || entry.length !== 2) {
1735
+ canonical = false;
1736
+ needsDeepSanitize = true;
1637
1737
  continue;
1738
+ }
1638
1739
  const [fileIdx, tokenCounts] = entry;
1639
- const file = data.files[fileIdx];
1640
- if (typeof file !== "string" || !Array.isArray(tokenCounts))
1740
+ if (!isCanonicalWordIndexNumber(fileIdx) ||
1741
+ fileIdx !== entryIndex ||
1742
+ fileIdx < 0 ||
1743
+ fileIdx >= data.files.length ||
1744
+ !Array.isArray(tokenCounts)) {
1745
+ canonical = false;
1746
+ needsDeepSanitize = true;
1641
1747
  continue;
1642
- const perToken = new Map();
1748
+ }
1643
1749
  for (const pair of tokenCounts) {
1644
- if (!Array.isArray(pair) || pair.length !== 2)
1750
+ if (!Array.isArray(pair) ||
1751
+ pair.length !== 2 ||
1752
+ !isCanonicalWordIndexToken(pair[0]) ||
1753
+ !isCanonicalWordIndexNumber(pair[1]) ||
1754
+ pair[1] < 1 ||
1755
+ pair[1] > WORD_INDEX_INT32_MAX ||
1756
+ candidate[fileIdx].has(pair[0])) {
1757
+ canonical = false;
1758
+ needsDeepSanitize = true;
1759
+ continue;
1760
+ }
1761
+ candidate[fileIdx].set(pair[0], pair[1]);
1762
+ forwardTotals.set(pair[0], (forwardTotals.get(pair[0]) ?? 0) + pair[1]);
1763
+ }
1764
+ }
1765
+ let forwardMatchesPostings = true;
1766
+ for (const [token, list] of postings) {
1767
+ if (forwardTotals.get(token) !== list.length) {
1768
+ forwardMatchesPostings = false;
1769
+ }
1770
+ const observed = postingFileCounts.get(token);
1771
+ if (!observed) {
1772
+ forwardMatchesPostings = false;
1773
+ continue;
1774
+ }
1775
+ for (const [fileId, count] of observed) {
1776
+ const slot = slotByFileId.get(fileId);
1777
+ if (slot === undefined || candidate[slot].get(token) !== count) {
1778
+ forwardMatchesPostings = false;
1779
+ }
1780
+ }
1781
+ }
1782
+ for (const token of forwardTotals.keys()) {
1783
+ if (!postingTokens.has(token))
1784
+ forwardMatchesPostings = false;
1785
+ }
1786
+ if (!forwardMatchesPostings)
1787
+ canonical = false;
1788
+ if (!forwardMatchesPostings)
1789
+ needsDeepSanitize = true;
1790
+ forward = new PathKeyedMap(wordIndexKey);
1791
+ for (let i = 0; i < data.files.length; i += 1) {
1792
+ forward.set(data.files[i], WordForwardEntry.fromTally(candidate[i]));
1793
+ }
1794
+ }
1795
+ else if (Object.prototype.hasOwnProperty.call(data, "forward")) {
1796
+ canonical = false;
1797
+ needsDeepSanitize = true;
1798
+ }
1799
+ if (needsDeepSanitize) {
1800
+ const actualForwardCounts = data.files.map(() => new Map());
1801
+ for (const [token, list] of postings) {
1802
+ const seenPairs = new Set();
1803
+ const sanitized = new WordPostingList(token, list.length);
1804
+ for (let i = 0; i < list.length; i += 1) {
1805
+ const fileId = list.fileIdAt(i);
1806
+ const line = list.lineAt(i);
1807
+ const pairKey = `${fileId}:${line}`;
1808
+ if (seenPairs.has(pairKey))
1645
1809
  continue;
1646
- const [token, count] = pair;
1647
- if (typeof token === "string" && typeof count === "number") {
1648
- // Point at the canonical instance the postings map holds, not
1649
- // this document’s own JSON.parse allocation (#2069).
1650
- perToken.set(postings.get(token)?.token ?? token, count);
1810
+ seenPairs.add(pairKey);
1811
+ sanitized.push(fileId, line);
1812
+ const slot = slotByFileId.get(fileId);
1813
+ if (slot !== undefined) {
1814
+ const counts = actualForwardCounts[slot];
1815
+ counts.set(token, (counts.get(token) ?? 0) + 1);
1651
1816
  }
1652
1817
  }
1653
- forward.set(file, WordForwardEntry.fromTally(perToken));
1818
+ postings.set(token, sanitized);
1819
+ }
1820
+ compactPostingsIntoArena(postings);
1821
+ if (Array.isArray(data.forward)) {
1822
+ forward = new PathKeyedMap(wordIndexKey);
1823
+ for (let i = 0; i < data.files.length; i += 1) {
1824
+ const canonicalSlot = slotByFileId.get(fileIdBySlot[i]) ?? i;
1825
+ forward.set(data.files[i], WordForwardEntry.fromTally(actualForwardCounts[canonicalSlot]));
1826
+ }
1654
1827
  }
1655
1828
  }
1656
- return {
1829
+ const expectedTotalTokens = [...docLengths.values()].reduce((total, length) => total + length, 0);
1830
+ const totalTokens = isCanonicalWordIndexNumber(expectedTotalTokens)
1831
+ ? expectedTotalTokens
1832
+ : 0;
1833
+ if (!isCanonicalWordIndexNumber(data.totalTokens) ||
1834
+ data.totalTokens !== totalTokens) {
1835
+ canonical = false;
1836
+ }
1837
+ if (typeof data.indexedFileCount !== "number" ||
1838
+ data.indexedFileCount !== docLengths.size) {
1839
+ canonical = false;
1840
+ }
1841
+ if (typeof data.truncated !== "boolean")
1842
+ canonical = false;
1843
+ const index = {
1657
1844
  postings,
1658
1845
  fileTable,
1659
1846
  docLengths,
1660
- totalTokens: typeof data.totalTokens === "number" ? data.totalTokens : 0,
1661
- docCount: data.files.length,
1847
+ totalTokens,
1848
+ docCount: docLengths.size,
1662
1849
  truncated: data.truncated === true,
1663
1850
  forward,
1664
1851
  fileMtimes,
@@ -1667,7 +1854,32 @@ export function deserializeWordIndex(data) {
1667
1854
  // starts from the exact post-compaction store count (#2117).
1668
1855
  postingStoreCount: countPostingBackingStores(postings),
1669
1856
  recompactFlight: createSingleFlight(),
1857
+ // A deserialized index is a fresh object distinct from whichever index
1858
+ // produced `data`. Without this, every per-edit dirty mark on a
1859
+ // session-start reload (#2068) is a no-op against `undefined`, and
1860
+ // serializeWordIndexIncrementally's `!dirty` branch then returns the
1861
+ // stale cached wire view forever, silently dropping every later edit
1862
+ // from the persisted snapshot.
1863
+ dirtyFiles: new Set(),
1670
1864
  };
1865
+ // Seed the wire cache from the snapshot just loaded so the FIRST persist
1866
+ // of a reloaded session (session-start's `snapshotSaveSyncMs`, #2068) also
1867
+ // takes the bounded incremental path instead of paying a full rebuild —
1868
+ // mirrors exactly what one priming `serializeWordIndex` call would cache.
1869
+ const tokensByFile = new Map();
1870
+ if (forward) {
1871
+ for (const file of data.files) {
1872
+ tokensByFile.set(wordIndexKey(file), new Set(forward.get(file)?.keys() ?? []));
1873
+ }
1874
+ }
1875
+ if (canonical) {
1876
+ serializedWordIndexCaches.set(index, {
1877
+ serialized: data,
1878
+ slotByFileId,
1879
+ tokensByFile,
1880
+ });
1881
+ }
1882
+ return index;
1671
1883
  }
1672
1884
  const buildStatuses = new Map();
1673
1885
  export function getWordIndexBuildStatus(cwd) {
@@ -39,11 +39,18 @@
39
39
  import * as fs from "node:fs";
40
40
  import * as os from "node:os";
41
41
  import * as path from "node:path";
42
+ import { PROJECT_CONFIG_BASENAMES } from "./config-locations.js";
42
43
  import { logLatency } from "./latency-logger.js";
43
44
  import { isAtOrAboveHomeDir, nameMatchesMarkerGlob, walkUpDirs, } from "./path-utils.js";
44
45
  /** Depth cap on any upward marker walk — mirrors `findNearestMarkerRoot`'s bound. */
45
46
  const MAX_WALK_DEPTH = 64;
46
- const PI_LENS_CONFIG_BASENAMES = [".pi-lens.json", "pi-lens.json"];
47
+ /**
48
+ * The project config basenames, canonical first — the SHARED table, not a
49
+ * fourth copy of the pair (#2426 review round 2). `config-locations.ts` derives
50
+ * it from the one location table the resolver walks, so a change there cannot
51
+ * leave this marker index preferring a different file than the loaders do.
52
+ */
53
+ const PI_LENS_CONFIG_BASENAMES = PROJECT_CONFIG_BASENAMES;
47
54
  /** Per-directory marker cache — the shared seam every consumer reads through. */
48
55
  const dirMarkerCache = new Map();
49
56
  /** Downstream memo clears that must follow the topology index reset. */
@@ -21,6 +21,9 @@ export const LOCAL_ZIZMOR_CONFIG_NAMES = [
21
21
  "zizmor.yml",
22
22
  "zizmor.yaml",
23
23
  ];
24
+ // Deliberately UNCEILINGED at $HOME (refs #2472 review round 3, F1): a
25
+ // user-level `~/zizmor.yml` (or `~/.github/zizmor.yml`) is a legitimate
26
+ // global config, not an escaped-workspace accident.
24
27
  export function findLocalZizmorConfig(startDir) {
25
28
  return findLocalToolConfig(startDir, LOCAL_ZIZMOR_CONFIG_NAMES);
26
29
  }