@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,6 +1,7 @@
1
1
  import type { AgentToolResult, ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
2
  import { Box, Text, truncateToWidth, type KeyId } from "@earendil-works/pi-tui";
3
3
  import { Type } from "typebox";
4
+ import pLimit from "p-limit";
4
5
  import { StringEnum, type ImageContent, type TextContent } from "@earendil-works/pi-ai/compat";
5
6
  import type { ExtractedContent, ExtractOptions } from "./extract.ts";
6
7
  import { normalizeFetchContentParams } from "./fetch-params.ts";
@@ -64,6 +65,7 @@ import { isSearXNGAvailable } from "./searxng.ts";
64
65
  import { isDuckDuckGoAvailable } from "./duckduckgo.ts";
65
66
  import { isAnySearchAvailable } from "./anysearch.ts";
66
67
  import { isXaiSearchAvailable } from "./xai-search.ts";
68
+ import { isMistralAvailable } from "./mistral-search.ts";
67
69
  import { isKimiSearchAvailable } from "./kimi-search.ts";
68
70
  import { isBrightDataAvailable } from "./brightdata.ts";
69
71
  import { isSerpBaseAvailable } from "./serpbase.ts";
@@ -229,6 +231,23 @@ const DEFAULT_CURATOR_TIMEOUT_SECONDS = 20;
229
231
  const DEFAULT_REMOTE_CURATOR_TIMEOUT_SECONDS = 60;
230
232
  const MAX_CURATOR_TIMEOUT_SECONDS = 600;
231
233
  const MAX_SUMMARY_GENERATION_DEADLINE_MS = 600_000;
234
+ const SEARCH_QUERY_CONCURRENCY = 3;
235
+
236
+ // Limit each batch independently so separate Pi tool calls can still run in parallel.
237
+ function runSearchQueries<T>(queries: string[], run: (query: string, index: number) => Promise<T>): Promise<T[]> {
238
+ const limit = pLimit(SEARCH_QUERY_CONCURRENCY);
239
+ return Promise.all(queries.map((query, index) => limit(() => run(query, index))));
240
+ }
241
+
242
+ // Keep primary query indexes stable for curator slots, then interleave additional
243
+ // provider entries deterministically instead of assigning by completion order.
244
+ function curatorResultIndex(queryIndex: number, entryIndex: number, queryCount: number): number {
245
+ return entryIndex * queryCount + queryIndex;
246
+ }
247
+
248
+ function curatorResultIndexCapacity(queryCount: number): number {
249
+ return queryCount * RESOLVED_SEARCH_PROVIDERS.length;
250
+ }
232
251
 
233
252
  function searchProviderSchema(description: string) {
234
253
  return Type.Union([
@@ -423,6 +442,7 @@ async function getProviderAvailability(ctx: ExtensionContext): Promise<ProviderA
423
442
  anysearch: isAnySearchAvailable(),
424
443
  xcrawl: isXcrawlAvailable(),
425
444
  xai: await isXaiSearchAvailable(ctx),
445
+ mistral: isMistralAvailable(),
426
446
  brightdata: isBrightDataAvailable(),
427
447
  serpbase: isSerpBaseAvailable(),
428
448
  serper: isSerperAvailable(),
@@ -1069,7 +1089,8 @@ export default function (pi: ExtensionAPI) {
1069
1089
  const fetchId = generateId();
1070
1090
  const controller = new AbortController();
1071
1091
  pendingFetches.set(fetchId, controller);
1072
- runWithProxy(proxy, () => fetchAllContent(urls, controller.signal, withRegisteredFetchOptions(undefined, registeredToolNames, proxy)))
1092
+ Promise.resolve()
1093
+ .then(() => runWithProxy(proxy, () => fetchAllContent(urls, controller.signal, withRegisteredFetchOptions(undefined, registeredToolNames, proxy))))
1073
1094
  .then((fetched) => {
1074
1095
  if (!sessionActive || !pendingFetches.has(fetchId)) return;
1075
1096
  const data = {
@@ -1340,7 +1361,7 @@ export default function (pi: ExtensionAPI) {
1340
1361
  }
1341
1362
 
1342
1363
  const selected = filterByQueryIndices(payload.selectedQueryIndices, resultsByIndex).results;
1343
- const fallbackResults = selected.length > 0 ? selected : [...resultsByIndex.values()];
1364
+ const fallbackResults = selected.length > 0 ? selected : orderedSearchResults(resultsByIndex);
1344
1365
  const deterministic = buildDeterministicSummary(fallbackResults);
1345
1366
  return {
1346
1367
  approvedSummary: deterministic.summary,
@@ -1395,6 +1416,11 @@ export default function (pi: ExtensionAPI) {
1395
1416
 
1396
1417
  const searchId = storeAndPublishSearch(opts.results);
1397
1418
  const isBackgroundFetch = fetchId !== null && !hasInlineReady;
1419
+ // The model only sees `content`, not `details`: surface the id it needs to
1420
+ // call get_search_content, the same way fetch_content does.
1421
+ if (getSearchContentEnabled && !hasApprovedSummary) {
1422
+ output += `\n---\nResults stored as responseId "${searchId}". Use ${toolNames.getSearchContent}({ responseId: "${searchId}", queryIndex: 0 }) to retrieve them.`;
1423
+ }
1398
1424
 
1399
1425
  return {
1400
1426
  content: [{ type: "text", text: output.trim() }],
@@ -1452,8 +1478,14 @@ export default function (pi: ExtensionAPI) {
1452
1478
  return { results: filteredResults, urls: filteredUrls };
1453
1479
  }
1454
1480
 
1481
+ function orderedSearchResults(resultsByIndex: Map<number, QueryResultData>): QueryResultData[] {
1482
+ return [...resultsByIndex.entries()]
1483
+ .sort(([leftIndex], [rightIndex]) => leftIndex - rightIndex)
1484
+ .map(([, result]) => result);
1485
+ }
1486
+
1455
1487
  function collectAllResultsAndUrls(resultsByIndex: Map<number, QueryResultData>) {
1456
- const results = [...resultsByIndex.values()];
1488
+ const results = orderedSearchResults(resultsByIndex);
1457
1489
  const urls: string[] = [];
1458
1490
  for (const result of results) {
1459
1491
  for (const source of result.results) {
@@ -1492,6 +1524,7 @@ export default function (pi: ExtensionAPI) {
1492
1524
  handle = await startCuratorServer(
1493
1525
  {
1494
1526
  queries: pc.queryList,
1527
+ initialResultIndexCapacity: curatorResultIndexCapacity(pc.queryList.length),
1495
1528
  sessionToken,
1496
1529
  timeout: pc.timeoutSeconds,
1497
1530
  availableProviders: pc.availableProviders,
@@ -1573,7 +1606,7 @@ export default function (pi: ExtensionAPI) {
1573
1606
  } else {
1574
1607
  const conn = activeCurators.get(callId)?.getConnectionState();
1575
1608
  pc.finish(buildCurationCancelledReturn(reason, {
1576
- queries: Array.from(pc.searchResults.values()),
1609
+ queries: orderedSearchResults(pc.searchResults),
1577
1610
  queryCount: pc.queryList.length,
1578
1611
  browserConnected: conn?.browserConnected,
1579
1612
  lastHeartbeatAgeMs: conn?.lastHeartbeatAgeMs,
@@ -1750,19 +1783,19 @@ export default function (pi: ExtensionAPI) {
1750
1783
  name: toolNames.webSearch,
1751
1784
  label: "Web Search",
1752
1785
  description:
1753
- `Search the web using OpenAI, Brave, Parallel, Parallel MCP, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Bocha, Ollama, SearXNG, DuckDuckGo, Exa, Perplexity, Gemini, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, or Serper. Pass a provider array to search only those providers simultaneously, or use provider "all" to search every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, and Serper. Returns an AI-synthesized answer with source citations. OpenAI search uses a Codex subscription or OpenAI API key; Kimi search uses a Kimi Code Plan authenticated through /login kimi-coding; xAI search uses a SuperGrok/X Premium subscription or xAI API key. Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, and Serper are available only when explicitly selected. For comprehensive research, prefer queries (plural) with 2-4 varied angles over a single query — each query gets its own synthesized answer, so varying phrasing and scope gives much broader coverage. When includeContent is true, full page content is fetched in the background. Searches auto-open the interactive browser curator and stream results live; set workflow to "none" to skip curation or "auto-summary" for a model-generated summary without the browser curator. The configured provider is used when provider is omitted or set to auto; omit provider unless explicitly overriding it. Without a configured provider, SearXNG is preferred first for local/private search. When the active Pi model is openai-codex, Codex-backed OpenAI search is preferred next. Otherwise Exa is preferred before OpenAI, then Brave, Parallel, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Bocha, Ollama, Perplexity, Gemini API, or Gemini Web.`,
1786
+ `Search the web using OpenAI, Brave, Parallel, Parallel MCP, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Bocha, Ollama, SearXNG, DuckDuckGo, Exa, Perplexity, Gemini, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, or Serper. Pass a provider array to search only those providers simultaneously, or use provider "all" to search every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, and Serper. Returns an AI-synthesized answer with source citations. OpenAI search uses a Codex subscription or OpenAI API key; Kimi search uses a Kimi Code Plan authenticated through /login kimi-coding; xAI search uses a SuperGrok/X Premium subscription or xAI API key; Mistral search uses a Mistral API key. Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, and Serper are available only when explicitly selected. For comprehensive research, prefer queries (plural) with 2-4 varied angles over a single query — each query gets its own synthesized answer, so varying phrasing and scope gives much broader coverage. When includeContent is true, full page content is fetched in the background. Searches auto-open the interactive browser curator and stream results live; set workflow to "none" to skip curation or "auto-summary" for a model-generated summary without the browser curator. The configured provider is used when provider is omitted or set to auto; omit provider unless explicitly overriding it. Without a configured provider, SearXNG is preferred first for local/private search. When the active Pi model is openai-codex, Codex-backed OpenAI search is preferred next. Otherwise Exa is preferred before OpenAI, then Brave, Parallel, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Bocha, Ollama, Perplexity, Gemini API, or Gemini Web.`,
1754
1787
  promptSnippet:
1755
1788
  "Use for web research questions. Prefer {queries:[...]} with 2-4 varied angles over a single query for broader coverage. Omit provider unless explicitly overriding the configured default.",
1756
1789
  parameters: Type.Object({
1757
1790
  query: Type.Optional(Type.String({ description: "Single search query. For research tasks, prefer 'queries' with multiple varied angles instead." })),
1758
- queries: Type.Optional(Type.Array(Type.String(), { description: "Multiple queries searched in sequence, each returning its own synthesized answer. Prefer this for research — vary phrasing, scope, and angle across 2-4 queries to maximize coverage. Good: ['React vs Vue performance benchmarks 2026', 'React vs Vue developer experience comparison', 'React ecosystem size vs Vue ecosystem']. Bad: ['React vs Vue', 'React vs Vue comparison', 'React vs Vue review'] (too similar, redundant results)." })),
1791
+ queries: Type.Optional(Type.Array(Type.String(), { description: "Multiple queries searched concurrently (up to three at a time), each returning its own synthesized answer. Prefer this for research — vary phrasing, scope, and angle across 2-4 queries to maximize coverage. Good: ['React vs Vue performance benchmarks 2026', 'React vs Vue developer experience comparison', 'React ecosystem size vs Vue ecosystem']. Bad: ['React vs Vue', 'React vs Vue comparison', 'React vs Vue review'] (too similar, redundant results)." })),
1759
1792
  numResults: Type.Optional(Type.Integer({ minimum: 1, maximum: 20, description: "Results per query (default: 5, max: 20)" })),
1760
1793
  includeContent: Type.Optional(Type.Boolean({ description: "Fetch full page content (async)" })),
1761
1794
  recencyFilter: Type.Optional(
1762
1795
  StringEnum(["day", "week", "month", "year"], { description: "Filter by recency" }),
1763
1796
  ),
1764
1797
  domainFilter: Type.Optional(Type.Array(Type.String(), { description: "Limit to domains (prefix with - to exclude)" })),
1765
- provider: Type.Optional(searchProviderSchema("Search provider or non-empty list of providers to search simultaneously; use all to search every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, and Serper, omit this field to use the configured provider, or use auto when none is configured")),
1798
+ provider: Type.Optional(searchProviderSchema("Search provider or non-empty list of providers to search simultaneously; use all to search every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, and Serper, omit this field to use the configured provider, or use auto when none is configured")),
1766
1799
  workflow: Type.Optional(
1767
1800
  StringEnum(["none", "summary-review", "auto-summary"], {
1768
1801
  description: "Search workflow mode: none = no curator, summary-review = open curator with auto summary draft (default), auto-summary = generate summary without opening curator",
@@ -1809,7 +1842,6 @@ export default function (pi: ExtensionAPI) {
1809
1842
  const searchResults = new Map<number, QueryResultData>();
1810
1843
  const resultSlots = new Map<number, number>();
1811
1844
  const allInlineContent: ExtractedContent[] = [];
1812
- let nextResultIndex = queryList.length;
1813
1845
  const searchAbort = new AbortController();
1814
1846
  const searchSignal = signal
1815
1847
  ? AbortSignal.any([signal, searchAbort.signal])
@@ -1876,7 +1908,7 @@ export default function (pi: ExtensionAPI) {
1876
1908
  if (cancelled) return;
1877
1909
  const conn = activeCurators.get(callId)?.getConnectionState();
1878
1910
  finish(buildCurationCancelledReturn(reason, {
1879
- queries: Array.from(searchResults.values()),
1911
+ queries: orderedSearchResults(searchResults),
1880
1912
  queryCount: queryList.length,
1881
1913
  browserConnected: conn?.browserConnected,
1882
1914
  lastHeartbeatAgeMs: conn?.lastHeartbeatAgeMs,
@@ -1893,15 +1925,16 @@ export default function (pi: ExtensionAPI) {
1893
1925
  signal?.addEventListener("abort", onAbort, { once: true });
1894
1926
  pc.browserPromise = openCuratorBrowser(callId, pc, ctx, false);
1895
1927
 
1896
- for (let qi = 0; qi < queryList.length; qi++) {
1897
- if (signal?.aborted || cancelled || searchAbort.signal.aborted) break;
1928
+ let completedSearches = 0;
1929
+ await runSearchQueries(queryList, async (query, qi) => {
1930
+ if (signal?.aborted || cancelled || searchAbort.signal.aborted) return;
1898
1931
  onUpdate?.({
1899
- content: [{ type: "text", text: `Searching ${qi + 1}/${queryList.length}: "${queryList[qi]}"...` }],
1900
- details: { phase: "searching", progress: qi / queryList.length, currentQuery: queryList[qi] },
1932
+ content: [{ type: "text", text: `Searching "${query}" (${completedSearches}/${queryList.length} complete)...` }],
1933
+ details: { phase: "searching", progress: completedSearches / queryList.length, currentQuery: query },
1901
1934
  });
1902
1935
  const requestedProvider = pc.searchProvider;
1903
1936
  try {
1904
- const response = await search(queryList[qi], {
1937
+ const response = await search(query, {
1905
1938
  provider: requestedProvider,
1906
1939
  numResults: params.numResults,
1907
1940
  recencyFilter,
@@ -1910,40 +1943,48 @@ export default function (pi: ExtensionAPI) {
1910
1943
  signal: searchSignal,
1911
1944
  extensionContext: ctx,
1912
1945
  });
1913
- if (signal?.aborted || cancelled || searchAbort.signal.aborted) break;
1946
+ if (signal?.aborted || cancelled || searchAbort.signal.aborted) return;
1914
1947
  if (response.inlineContent) allInlineContent.push(...response.inlineContent);
1915
1948
  const entries = toCuratorSearchEntries(response);
1916
1949
  const curator = activeCurators.get(callId);
1917
1950
  for (let entryIndex = 0; entryIndex < entries.length; entryIndex++) {
1918
1951
  const entry = entries[entryIndex];
1919
- const resultIndex = entryIndex === 0 ? qi : nextResultIndex++;
1952
+ const resultIndex = curatorResultIndex(qi, entryIndex, queryList.length);
1920
1953
  const indexedEntry: IndexedCuratorSearchEntry = {
1921
1954
  ...entry,
1922
1955
  queryIndex: resultIndex,
1923
- query: queryList[qi],
1956
+ query,
1924
1957
  };
1925
1958
  searchResults.set(resultIndex, indexedCuratorEntryToQueryResult(indexedEntry));
1926
1959
  resultSlots.set(resultIndex, qi);
1927
1960
  if (curator) {
1928
1961
  if (entry.error) {
1929
- curator.pushError(resultIndex, entry.error, entry.provider, { query: queryList[qi], slotIndex: qi });
1962
+ curator.pushError(resultIndex, entry.error, entry.provider, { query, slotIndex: qi });
1930
1963
  } else {
1931
- curator.pushResult(resultIndex, { ...entry, query: queryList[qi], slotIndex: qi });
1964
+ curator.pushResult(resultIndex, { ...entry, query, slotIndex: qi });
1932
1965
  }
1933
1966
  }
1934
1967
  }
1935
1968
  } catch (err) {
1936
- if (signal?.aborted || cancelled || searchAbort.signal.aborted) break;
1969
+ if (signal?.aborted || cancelled || searchAbort.signal.aborted) return;
1937
1970
  const message = err instanceof Error ? err.message : String(err);
1938
1971
  const failedProvider = toCuratorProvider(requestedProvider);
1939
- searchResults.set(qi, { query: queryList[qi], answer: "", results: [], error: message, provider: failedProvider });
1972
+ searchResults.set(qi, { query, answer: "", results: [], error: message, provider: failedProvider });
1940
1973
  resultSlots.set(qi, qi);
1941
1974
  const curator = activeCurators.get(callId);
1942
1975
  if (curator) {
1943
- curator.pushError(qi, message, failedProvider, { query: queryList[qi], slotIndex: qi });
1976
+ curator.pushError(qi, message, failedProvider, { query, slotIndex: qi });
1977
+ }
1978
+ } finally {
1979
+ completedSearches++;
1980
+ if (!signal?.aborted && !cancelled && !searchAbort.signal.aborted) {
1981
+ onUpdate?.({
1982
+ content: [{ type: "text", text: `Completed ${completedSearches}/${queryList.length} searches.` }],
1983
+ details: { phase: "searching", progress: completedSearches / queryList.length, currentQuery: query },
1984
+ });
1944
1985
  }
1945
1986
  }
1946
- }
1987
+ });
1947
1988
 
1948
1989
  if (signal?.aborted || cancelled || searchAbort.signal.aborted) {
1949
1990
  cancel();
@@ -1983,17 +2024,16 @@ export default function (pi: ExtensionAPI) {
1983
2024
  return promise;
1984
2025
  }
1985
2026
 
1986
- const searchResults: QueryResultData[] = [];
2027
+ let completedSearches = 0;
1987
2028
  const allUrls: string[] = [];
1988
2029
  const allInlineContent: ExtractedContent[] = [];
1989
2030
  const resolvedProvider = resolveRequestedProvider(params.provider);
1990
2031
 
1991
- for (let i = 0; i < queryList.length; i++) {
1992
- const query = queryList[i];
1993
-
2032
+ const queryResponses = await runSearchQueries(queryList, async (query) => {
2033
+ signal?.throwIfAborted();
1994
2034
  onUpdate?.({
1995
- content: [{ type: "text", text: `Searching ${i + 1}/${queryList.length}: "${query}"...` }],
1996
- details: { phase: "search", progress: i / queryList.length, currentQuery: query },
2035
+ content: [{ type: "text", text: `Searching "${query}" (${completedSearches}/${queryList.length} complete)...` }],
2036
+ details: { phase: "search", progress: completedSearches / queryList.length, currentQuery: query },
1997
2037
  });
1998
2038
 
1999
2039
  try {
@@ -2007,19 +2047,31 @@ export default function (pi: ExtensionAPI) {
2007
2047
  extensionContext: ctx,
2008
2048
  });
2009
2049
 
2010
- searchResults.push({ query, answer, results, error: null, provider });
2011
- for (const r of results) {
2012
- if (!allUrls.includes(r.url)) {
2013
- allUrls.push(r.url);
2014
- }
2015
- }
2016
- if (inlineContent) allInlineContent.push(...inlineContent);
2050
+ return { result: { query, answer, results, error: null, provider } satisfies QueryResultData, inlineContent };
2017
2051
  } catch (err) {
2018
2052
  if (signal?.aborted || isAbortError(err)) throw err;
2019
2053
  const message = err instanceof Error ? err.message : String(err);
2020
2054
  const requestedProvider = toCuratorProvider(resolvedProvider);
2021
- searchResults.push({ query, answer: "", results: [], error: message, provider: requestedProvider });
2055
+ return {
2056
+ result: { query, answer: "", results: [], error: message, provider: requestedProvider } satisfies QueryResultData,
2057
+ inlineContent: undefined,
2058
+ };
2059
+ } finally {
2060
+ completedSearches++;
2061
+ if (!signal?.aborted) {
2062
+ onUpdate?.({
2063
+ content: [{ type: "text", text: `Completed ${completedSearches}/${queryList.length} searches.` }],
2064
+ details: { phase: "search", progress: completedSearches / queryList.length, currentQuery: query },
2065
+ });
2066
+ }
2022
2067
  }
2068
+ });
2069
+ const searchResults = queryResponses.map(response => response.result);
2070
+ for (const response of queryResponses) {
2071
+ for (const result of response.result.results) {
2072
+ if (!allUrls.includes(result.url)) allUrls.push(result.url);
2073
+ }
2074
+ if (response.inlineContent) allInlineContent.push(...response.inlineContent);
2023
2075
  }
2024
2076
 
2025
2077
  let approvedSummary: string | undefined;
@@ -2337,7 +2389,7 @@ export default function (pi: ExtensionAPI) {
2337
2389
  fetchContent: Type.Optional(Type.Boolean({ description: "Fetch up to 5 result pages for exact passage extraction." })),
2338
2390
  recencyFilter: Type.Optional(StringEnum(["day", "week", "month", "year"], { description: "Filter by recency." })),
2339
2391
  domainFilter: Type.Optional(Type.Array(Type.String(), { description: "Limit to domains; prefix with - to exclude." })),
2340
- provider: Type.Optional(searchProviderSchema("Search provider or non-empty list of providers to search simultaneously; all searches every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Bright Data, SerpBase, and Serper")),
2392
+ provider: Type.Optional(searchProviderSchema("Search provider or non-empty list of providers to search simultaneously; all searches every eligible provider except Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, Valyu, xAI, Mistral, Bright Data, SerpBase, and Serper")),
2341
2393
  proxy: Type.Optional(Type.String({
2342
2394
  description: "http(s) proxy URL (e.g. http://host:port) used for every outbound request in this call (search APIs and result-page fetches). Empty string forces direct access.",
2343
2395
  })),
@@ -3163,6 +3215,7 @@ export default function (pi: ExtensionAPI) {
3163
3215
  const handle = await startCuratorServer(
3164
3216
  {
3165
3217
  queries,
3218
+ initialResultIndexCapacity: curatorResultIndexCapacity(queries.length),
3166
3219
  sessionToken,
3167
3220
  timeout: curatorTimeoutSeconds,
3168
3221
  availableProviders,
@@ -3244,19 +3297,21 @@ export default function (pi: ExtensionAPI) {
3244
3297
  }
3245
3298
  },
3246
3299
  async onAddSearch(query, provider) {
3247
- if (commandHandle && !isCommandActive()) {
3248
- throw new Error("Curator session is no longer active.");
3249
- }
3250
- const requestedProvider = resolveCuratorSearchProvider(provider, currentSearchProvider);
3251
- const response = await search(query, {
3252
- provider: requestedProvider,
3253
- signal: searchAbort.signal,
3254
- extensionContext: ctx,
3300
+ return runWithProxy(undefined, async () => {
3301
+ if (commandHandle && !isCommandActive()) {
3302
+ throw new Error("Curator session is no longer active.");
3303
+ }
3304
+ const requestedProvider = resolveCuratorSearchProvider(provider, currentSearchProvider);
3305
+ const response = await search(query, {
3306
+ provider: requestedProvider,
3307
+ signal: searchAbort.signal,
3308
+ extensionContext: ctx,
3309
+ });
3310
+ if (commandHandle && !isCommandActive()) {
3311
+ throw new Error("Curator session is no longer active.");
3312
+ }
3313
+ return toCuratorSearchEntries(response);
3255
3314
  });
3256
- if (commandHandle && !isCommandActive()) {
3257
- throw new Error("Curator session is no longer active.");
3258
- }
3259
- return toCuratorSearchEntries(response);
3260
3315
  },
3261
3316
  onAddSearchResults(entries) {
3262
3317
  if (commandHandle && !isCommandActive()) return;
@@ -3315,41 +3370,40 @@ export default function (pi: ExtensionAPI) {
3315
3370
 
3316
3371
  if (queries.length > 0) {
3317
3372
  (async () => {
3318
- let nextResultIndex = queries.length;
3319
- for (let qi = 0; qi < queries.length; qi++) {
3320
- if (aborted || !isCommandActive()) break;
3373
+ await runSearchQueries(queries, async (query, qi) => {
3374
+ if (aborted || !isCommandActive()) return;
3321
3375
  const requestedProvider = currentSearchProvider;
3322
3376
  try {
3323
- const response = await search(queries[qi], {
3377
+ const response = await runWithProxy(undefined, () => search(query, {
3324
3378
  provider: requestedProvider,
3325
3379
  signal: searchAbort.signal,
3326
3380
  extensionContext: ctx,
3327
- });
3328
- if (aborted || !isCommandActive()) break;
3381
+ }));
3382
+ if (aborted || !isCommandActive()) return;
3329
3383
  const entries = toCuratorSearchEntries(response);
3330
3384
  for (let entryIndex = 0; entryIndex < entries.length; entryIndex++) {
3331
3385
  const entry = entries[entryIndex];
3332
- const resultIndex = entryIndex === 0 ? qi : nextResultIndex++;
3386
+ const resultIndex = curatorResultIndex(qi, entryIndex, queries.length);
3333
3387
  const indexedEntry: IndexedCuratorSearchEntry = {
3334
3388
  ...entry,
3335
3389
  queryIndex: resultIndex,
3336
- query: queries[qi],
3390
+ query,
3337
3391
  };
3338
3392
  collected.set(resultIndex, indexedCuratorEntryToQueryResult(indexedEntry));
3339
3393
  if (entry.error) {
3340
- handle.pushError(resultIndex, entry.error, entry.provider, { query: queries[qi], slotIndex: qi });
3394
+ handle.pushError(resultIndex, entry.error, entry.provider, { query, slotIndex: qi });
3341
3395
  } else {
3342
- handle.pushResult(resultIndex, { ...entry, query: queries[qi], slotIndex: qi });
3396
+ handle.pushResult(resultIndex, { ...entry, query, slotIndex: qi });
3343
3397
  }
3344
3398
  }
3345
3399
  } catch (err) {
3346
- if (aborted || !isCommandActive()) break;
3400
+ if (aborted || !isCommandActive()) return;
3347
3401
  const message = err instanceof Error ? err.message : String(err);
3348
3402
  const failedProvider = toCuratorProvider(requestedProvider);
3349
- handle.pushError(qi, message, failedProvider, { query: queries[qi], slotIndex: qi });
3350
- collected.set(qi, { query: queries[qi], answer: "", results: [], error: message, provider: failedProvider });
3403
+ handle.pushError(qi, message, failedProvider, { query, slotIndex: qi });
3404
+ collected.set(qi, { query, answer: "", results: [], error: message, provider: failedProvider });
3351
3405
  }
3352
- }
3406
+ });
3353
3407
  if (!aborted && isCommandActive()) handle.searchesDone();
3354
3408
  })();
3355
3409
  } else {