@herbertgao/pi-extensions 2026.8.11 → 2026.8.13

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 (476) hide show
  1. package/README.md +23 -10
  2. package/{node_modules/@herbertgao/pi-mermaid-open/LICENSE → THIRD_PARTY_NOTICES.md} +19 -1
  3. package/node_modules/@czottmann/pi-automode/CHANGELOG.md +15 -0
  4. package/node_modules/@czottmann/pi-automode/README.md +5 -3
  5. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-001-permission-precedence-and-trust-boundaries.md +2 -0
  6. package/node_modules/@czottmann/pi-automode/docs/adr/ADR-002-global-config-in-extension-data-directory.md +60 -0
  7. package/node_modules/@czottmann/pi-automode/docs/adr/INDEX.md +1 -0
  8. package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +4 -4
  9. package/node_modules/@czottmann/pi-automode/docs/configuration.md +20 -4
  10. package/node_modules/@czottmann/pi-automode/docs/observability-logging.md +1 -1
  11. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/bash.ts +692 -0
  12. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +181 -3
  13. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +4 -1
  14. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +143 -36
  15. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +103 -148
  16. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +32 -6
  17. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +344 -22
  18. package/node_modules/@czottmann/pi-automode/extensions/auto-mode.ts +1 -0
  19. package/node_modules/@czottmann/pi-automode/package.json +4 -1
  20. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +2 -1
  21. package/node_modules/@herbertgao/pi-cc-extensions/README.md +2 -1
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +4 -0
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +21 -1
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +1 -1
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +19 -19
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +4 -2
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +2 -1
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +10 -2
  29. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  30. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +10 -0
  31. package/node_modules/@herbertgao/pi-subagents/README.md +21 -15
  32. package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
  33. package/node_modules/@herbertgao/pi-subagents/src/agent-file-toggle.ts +11 -8
  34. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +184 -106
  35. package/node_modules/@herbertgao/pi-subagents/src/cross-extension-rpc.ts +31 -11
  36. package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +9 -1
  37. package/node_modules/@herbertgao/pi-subagents/src/index.ts +156 -31
  38. package/node_modules/@herbertgao/pi-subagents/src/invocation-config.ts +17 -0
  39. package/node_modules/@herbertgao/pi-subagents/src/model-resolver.ts +14 -0
  40. package/node_modules/@herbertgao/pi-subagents/src/schedule.ts +8 -0
  41. package/node_modules/@herbertgao/pi-subagents/src/settings.ts +32 -1
  42. package/node_modules/@herbertgao/pi-subagents/src/types.ts +17 -2
  43. package/node_modules/@herbertgao/pi-subagents/src/ui/agent-widget.ts +23 -2
  44. package/node_modules/@herbertgao/pi-subagents/src/ui/conversation-viewer.ts +259 -24
  45. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +2 -2
  46. package/node_modules/@luxusai/pi-hindsight/CHANGELOG.md +376 -0
  47. package/node_modules/@luxusai/pi-hindsight/README.md +92 -0
  48. package/node_modules/@luxusai/pi-hindsight/docs/adr/001-memory-lifecycle-and-scope.md +56 -0
  49. package/node_modules/@luxusai/pi-hindsight/docs/adr/002-explicit-routing-strategy-seam.md +169 -0
  50. package/node_modules/@luxusai/pi-hindsight/docs/adr/003-tui-memory-mode-vocabulary.md +107 -0
  51. package/node_modules/@luxusai/pi-hindsight/docs/adr/004-lifeos-dual-bank-design.md +89 -0
  52. package/node_modules/@luxusai/pi-hindsight/docs/adr/005-domain-banks-and-agent-first-surface.md +189 -0
  53. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark.webp +0 -0
  54. package/node_modules/@luxusai/pi-hindsight/docs/assets/logos/pi-hindsight-logo-dark@2x.webp +0 -0
  55. package/node_modules/@luxusai/pi-hindsight/docs/coding-memory-evaluation.md +54 -0
  56. package/node_modules/@luxusai/pi-hindsight/docs/compatibility.md +75 -0
  57. package/node_modules/@luxusai/pi-hindsight/docs/hindsight-core-functions.md +300 -0
  58. package/node_modules/@luxusai/pi-hindsight/docs/mission-and-mental-model-quality.md +158 -0
  59. package/node_modules/@luxusai/pi-hindsight/docs/next-opt-out-design.md +164 -0
  60. package/node_modules/@luxusai/pi-hindsight/docs/risky-memory-modes.md +139 -0
  61. package/node_modules/@luxusai/pi-hindsight/docs/starter-mental-model-suggestions.md +74 -0
  62. package/node_modules/@luxusai/pi-hindsight/docs/surface-reference.md +261 -0
  63. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-operations.ts +151 -0
  64. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-selection.ts +18 -0
  65. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-settings-presenter.ts +46 -0
  66. package/node_modules/@luxusai/pi-hindsight/extensions/banks/bank-templates.ts +383 -0
  67. package/node_modules/@luxusai/pi-hindsight/extensions/banks/banking.ts +240 -0
  68. package/node_modules/@luxusai/pi-hindsight/extensions/banks/knowledge-page-seed.ts +176 -0
  69. package/node_modules/@luxusai/pi-hindsight/extensions/banks/retain-strategies.ts +178 -0
  70. package/node_modules/@luxusai/pi-hindsight/extensions/client/client-retry.ts +41 -0
  71. package/node_modules/@luxusai/pi-hindsight/extensions/client/client.ts +386 -0
  72. package/node_modules/@luxusai/pi-hindsight/extensions/client/fetch-compat.ts +39 -0
  73. package/node_modules/@luxusai/pi-hindsight/extensions/client/timeout.ts +34 -0
  74. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-defaults.ts +140 -0
  75. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-model.ts +61 -0
  76. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-editing-registry.ts +925 -0
  77. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-field-paths.ts +247 -0
  78. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-normalize.ts +547 -0
  79. package/node_modules/@luxusai/pi-hindsight/extensions/config/config-writer.ts +480 -0
  80. package/node_modules/@luxusai/pi-hindsight/extensions/config/config.ts +182 -0
  81. package/node_modules/@luxusai/pi-hindsight/extensions/config/setup-gate.ts +86 -0
  82. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-execute.ts +1010 -0
  83. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-parse.ts +175 -0
  84. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-plan.ts +425 -0
  85. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-presentation.ts +210 -0
  86. package/node_modules/@luxusai/pi-hindsight/extensions/imports/import-sessions.ts +817 -0
  87. package/node_modules/@luxusai/pi-hindsight/extensions/index.ts +25 -0
  88. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/git-seed.ts +319 -0
  89. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-recall.ts +196 -0
  90. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-retain.ts +189 -0
  91. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle-runtime.ts +65 -0
  92. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/memory-lifecycle.ts +260 -0
  93. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/mental-models.ts +244 -0
  94. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/observation-scopes.ts +59 -0
  95. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-cleanup.ts +82 -0
  96. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall-visibility.ts +45 -0
  97. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/recall.ts +331 -0
  98. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-cursor.ts +354 -0
  99. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-job-builder.ts +66 -0
  100. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain-receipts.ts +132 -0
  101. package/node_modules/@luxusai/pi-hindsight/extensions/lifecycle/retain.ts +228 -0
  102. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-bank-template-operations.ts +74 -0
  103. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-config-operations.ts +16 -0
  104. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-control-operations.ts +648 -0
  105. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-diagnostics-operations.ts +105 -0
  106. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-identity.ts +68 -0
  107. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-service.ts +71 -0
  108. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-operation-types.ts +13 -0
  109. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-recall-operations.ts +162 -0
  110. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-retain-operations.ts +131 -0
  111. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-scope.ts +104 -0
  112. package/node_modules/@luxusai/pi-hindsight/extensions/operations/memory-session-operations.ts +37 -0
  113. package/node_modules/@luxusai/pi-hindsight/extensions/operations/operation-catalog.ts +893 -0
  114. package/node_modules/@luxusai/pi-hindsight/extensions/operations/reflect-presenter.ts +35 -0
  115. package/node_modules/@luxusai/pi-hindsight/extensions/operations/scope-migrate.ts +177 -0
  116. package/node_modules/@luxusai/pi-hindsight/extensions/operations/tools.ts +7 -0
  117. package/node_modules/@luxusai/pi-hindsight/extensions/queue/flush-presenter.ts +21 -0
  118. package/node_modules/@luxusai/pi-hindsight/extensions/queue/jsonl-queue-store.ts +112 -0
  119. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-delivery.ts +111 -0
  120. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-lock.ts +214 -0
  121. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue-operations.ts +70 -0
  122. package/node_modules/@luxusai/pi-hindsight/extensions/queue/queue.ts +392 -0
  123. package/node_modules/@luxusai/pi-hindsight/extensions/tui/bank-template-presentation.ts +45 -0
  124. package/node_modules/@luxusai/pi-hindsight/extensions/tui/commands.ts +9 -0
  125. package/node_modules/@luxusai/pi-hindsight/extensions/tui/guided-setup.ts +860 -0
  126. package/node_modules/@luxusai/pi-hindsight/extensions/tui/prefill-input.ts +105 -0
  127. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-flow.ts +189 -0
  128. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-server-probe.ts +299 -0
  129. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-actions.ts +201 -0
  130. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-facts.ts +47 -0
  131. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-render.ts +239 -0
  132. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui-types.ts +50 -0
  133. package/node_modules/@luxusai/pi-hindsight/extensions/tui/setup-tui.ts +259 -0
  134. package/node_modules/@luxusai/pi-hindsight/extensions/tui/tool-presenters.ts +77 -0
  135. package/node_modules/@luxusai/pi-hindsight/extensions/types.ts +534 -0
  136. package/node_modules/@luxusai/pi-hindsight/extensions/utils/diagnostics.ts +319 -0
  137. package/node_modules/@luxusai/pi-hindsight/extensions/utils/messages.ts +325 -0
  138. package/node_modules/@luxusai/pi-hindsight/extensions/utils/sanitize.ts +42 -0
  139. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-memory-meta.ts +244 -0
  140. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session-operations.ts +56 -0
  141. package/node_modules/@luxusai/pi-hindsight/extensions/utils/session.ts +50 -0
  142. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-fields.ts +167 -0
  143. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status-health.ts +207 -0
  144. package/node_modules/@luxusai/pi-hindsight/extensions/utils/status.ts +120 -0
  145. package/node_modules/@luxusai/pi-hindsight/extensions/version.ts +8 -0
  146. package/node_modules/@luxusai/pi-hindsight/package.json +118 -0
  147. package/node_modules/@luxusai/pi-hindsight/skills/hindsight-memory-doctor/SKILL.md +75 -0
  148. package/node_modules/@narumitw/pi-btw/dist/index.ts +143 -46
  149. package/node_modules/@narumitw/pi-btw/dist/index.ts.map +3 -3
  150. package/node_modules/@narumitw/pi-btw/package.json +6 -6
  151. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +136 -22
  152. package/node_modules/{@herbertgao → @tifan}/pi-copy-response/README.md +2 -4
  153. package/node_modules/{@herbertgao → @tifan}/pi-copy-response/package.json +5 -15
  154. package/node_modules/{@herbertgao → @tifan}/pi-handoff/README.md +4 -6
  155. package/node_modules/@tifan/pi-handoff/package.json +43 -0
  156. package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/index.ts +1 -1
  157. package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/README.md +2 -4
  158. package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/package.json +5 -15
  159. package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/README.md +5 -7
  160. package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/package.json +5 -19
  161. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/README.md +4 -6
  162. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/package.json +6 -16
  163. package/node_modules/{@herbertgao → @tifan}/pi-preferred-thinking/src/index.ts +1 -6
  164. package/node_modules/{@herbertgao → @tifan}/pi-recap/README.md +4 -6
  165. package/node_modules/@tifan/pi-recap/package.json +42 -0
  166. package/node_modules/{@herbertgao → @tifan}/pi-recap/src/models.ts +1 -6
  167. package/node_modules/{@herbertgao → @tifan}/pi-rename/README.md +13 -8
  168. package/node_modules/@tifan/pi-rename/package.json +47 -0
  169. package/node_modules/@tifan/pi-rename/src/herdr-label.ts +4 -0
  170. package/node_modules/{@herbertgao → @tifan}/pi-rename/src/index.ts +4 -16
  171. package/node_modules/{@herbertgao → @tifan}/pi-rename/src/models.ts +1 -6
  172. package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/README.md +2 -4
  173. package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/package.json +5 -15
  174. package/node_modules/pi-lens/CHANGELOG.md +96 -1
  175. package/node_modules/pi-lens/dist/clients/actionable-warnings-logger.js +2 -1
  176. package/node_modules/pi-lens/dist/clients/actionable-warnings.js +14 -5
  177. package/node_modules/pi-lens/dist/clients/advisory-provenance.js +48 -18
  178. package/node_modules/pi-lens/dist/clients/ast-grep-client.js +1 -3
  179. package/node_modules/pi-lens/dist/clients/atomic-write-staging.js +16 -4
  180. package/node_modules/pi-lens/dist/clients/bash-file-access.js +3 -1
  181. package/node_modules/pi-lens/dist/clients/biome-client.js +1 -3
  182. package/node_modules/pi-lens/dist/clients/blocker-freshness.js +21 -8
  183. package/node_modules/pi-lens/dist/clients/bounded-cache.js +24 -8
  184. package/node_modules/pi-lens/dist/clients/bounded-pid-file-lock.js +4 -3
  185. package/node_modules/pi-lens/dist/clients/cache-manager.js +6 -7
  186. package/node_modules/pi-lens/dist/clients/cache-observability.js +461 -66
  187. package/node_modules/pi-lens/dist/clients/call-graph.js +238 -63
  188. package/node_modules/pi-lens/dist/clients/codebase-model.js +13 -5
  189. package/node_modules/pi-lens/dist/clients/complexity-client.js +1 -3
  190. package/node_modules/pi-lens/dist/clients/dead-code-client.js +19 -8
  191. package/node_modules/pi-lens/dist/clients/dead-code-logger.js +1 -2
  192. package/node_modules/pi-lens/dist/clients/deadline-utils.js +3 -1
  193. package/node_modules/pi-lens/dist/clients/debug-heap.js +8 -1
  194. package/node_modules/pi-lens/dist/clients/degradation-ledger.js +1 -1
  195. package/node_modules/pi-lens/dist/clients/dependency-checker.js +11 -7
  196. package/node_modules/pi-lens/dist/clients/diagnostic-dispositions.js +39 -2
  197. package/node_modules/pi-lens/dist/clients/diagnostic-line-freshness.js +5 -1
  198. package/node_modules/pi-lens/dist/clients/dispatch/auxiliary-lsp.js +2 -3
  199. package/node_modules/pi-lens/dist/clients/dispatch/dispatcher.js +13 -1
  200. package/node_modules/pi-lens/dist/clients/dispatch/facts/function-facts.js +3 -1
  201. package/node_modules/pi-lens/dist/clients/dispatch/facts/import-facts.js +2 -1
  202. package/node_modules/pi-lens/dist/clients/dispatch/facts/tree-sitter-facts.js +1 -1
  203. package/node_modules/pi-lens/dist/clients/dispatch/integration.js +9 -4
  204. package/node_modules/pi-lens/dist/clients/dispatch/rules/error-swallowing.js +3 -1
  205. package/node_modules/pi-lens/dist/clients/dispatch/rules/pass-through-wrappers.js +6 -2
  206. package/node_modules/pi-lens/dist/clients/dispatch/rules/unsafe-boundary.js +31 -7
  207. package/node_modules/pi-lens/dist/clients/dispatch/runners/actionlint.js +5 -2
  208. package/node_modules/pi-lens/dist/clients/dispatch/runners/biome-check.js +10 -14
  209. package/node_modules/pi-lens/dist/clients/dispatch/runners/cpp-check.js +5 -1
  210. package/node_modules/pi-lens/dist/clients/dispatch/runners/dotnet-build.js +1 -1
  211. package/node_modules/pi-lens/dist/clients/dispatch/runners/elixir-check.js +3 -1
  212. package/node_modules/pi-lens/dist/clients/dispatch/runners/eslint.js +25 -6
  213. package/node_modules/pi-lens/dist/clients/dispatch/runners/fish-indent.js +1 -1
  214. package/node_modules/pi-lens/dist/clients/dispatch/runners/gleam-check.js +1 -1
  215. package/node_modules/pi-lens/dist/clients/dispatch/runners/golangci-lint.js +3 -1
  216. package/node_modules/pi-lens/dist/clients/dispatch/runners/hadolint.js +13 -8
  217. package/node_modules/pi-lens/dist/clients/dispatch/runners/helm-lint.js +4 -1
  218. package/node_modules/pi-lens/dist/clients/dispatch/runners/htmlhint.js +25 -10
  219. package/node_modules/pi-lens/dist/clients/dispatch/runners/javac.js +1 -1
  220. package/node_modules/pi-lens/dist/clients/dispatch/runners/ktlint.js +1 -1
  221. package/node_modules/pi-lens/dist/clients/dispatch/runners/lsp.js +1 -1
  222. package/node_modules/pi-lens/dist/clients/dispatch/runners/markdownlint.js +28 -4
  223. package/node_modules/pi-lens/dist/clients/dispatch/runners/mypy.js +6 -8
  224. package/node_modules/pi-lens/dist/clients/dispatch/runners/oxlint.js +212 -11
  225. package/node_modules/pi-lens/dist/clients/dispatch/runners/php-lint.js +1 -1
  226. package/node_modules/pi-lens/dist/clients/dispatch/runners/phpstan.js +8 -4
  227. package/node_modules/pi-lens/dist/clients/dispatch/runners/psscriptanalyzer.js +10 -6
  228. package/node_modules/pi-lens/dist/clients/dispatch/runners/pyright.js +23 -14
  229. package/node_modules/pi-lens/dist/clients/dispatch/runners/rust-clippy.js +1 -1
  230. package/node_modules/pi-lens/dist/clients/dispatch/runners/shellcheck.js +7 -9
  231. package/node_modules/pi-lens/dist/clients/dispatch/runners/shfmt.js +5 -2
  232. package/node_modules/pi-lens/dist/clients/dispatch/runners/sqlfluff.js +7 -7
  233. package/node_modules/pi-lens/dist/clients/dispatch/runners/stylelint.js +6 -8
  234. package/node_modules/pi-lens/dist/clients/dispatch/runners/terragrunt.js +13 -8
  235. package/node_modules/pi-lens/dist/clients/dispatch/runners/tflint.js +13 -8
  236. package/node_modules/pi-lens/dist/clients/dispatch/runners/tree-sitter.js +17 -3
  237. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/candidate-probe.js +7 -1
  238. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/runner-helpers.js +24 -1
  239. package/node_modules/pi-lens/dist/clients/dispatch/runners/utils/tool-failure.js +35 -0
  240. package/node_modules/pi-lens/dist/clients/dispatch/runners/yaml-rule-parser.js +1 -3
  241. package/node_modules/pi-lens/dist/clients/dispatch/runners/yamllint.js +6 -8
  242. package/node_modules/pi-lens/dist/clients/dispatch/runners/zig-check.js +1 -1
  243. package/node_modules/pi-lens/dist/clients/dispatch/suppress-writer.js +2 -1
  244. package/node_modules/pi-lens/dist/clients/dispatch/types.js +6 -1
  245. package/node_modules/pi-lens/dist/clients/dispatch/utils/lsp-diagnostics.js +6 -2
  246. package/node_modules/pi-lens/dist/clients/extension-log.js +5 -3
  247. package/node_modules/pi-lens/dist/clients/feature-hints.js +8 -1
  248. package/node_modules/pi-lens/dist/clients/file-kinds.js +34 -129
  249. package/node_modules/pi-lens/dist/clients/file-utils.js +17 -1
  250. package/node_modules/pi-lens/dist/clients/finding-delivery-gate.js +57 -2
  251. package/node_modules/pi-lens/dist/clients/formatters.js +144 -27
  252. package/node_modules/pi-lens/dist/clients/freshness.js +38 -0
  253. package/node_modules/pi-lens/dist/clients/git-guard.js +43 -13
  254. package/node_modules/pi-lens/dist/clients/go-client.js +1 -3
  255. package/node_modules/pi-lens/dist/clients/grammar-source.js +1 -1
  256. package/node_modules/pi-lens/dist/clients/gzip-stage-write.js +30 -4
  257. package/node_modules/pi-lens/dist/clients/host-edit-normalize.js +1 -3
  258. package/node_modules/pi-lens/dist/clients/install-diagnostics.js +4 -2
  259. package/node_modules/pi-lens/dist/clients/installer/index.js +86 -77
  260. package/node_modules/pi-lens/dist/clients/instance-reaper.js +5 -2
  261. package/node_modules/pi-lens/dist/clients/instance-registry.js +4 -2
  262. package/node_modules/pi-lens/dist/clients/jscpd-client.js +6 -1
  263. package/node_modules/pi-lens/dist/clients/knip-client.js +29 -15
  264. package/node_modules/pi-lens/dist/clients/language-profile.js +4 -1
  265. package/node_modules/pi-lens/dist/clients/latency-logger.js +13 -2
  266. package/node_modules/pi-lens/dist/clients/lens-config.js +1 -1
  267. package/node_modules/pi-lens/dist/clients/lens-map.js +8 -3
  268. package/node_modules/pi-lens/dist/clients/live-bus-emitter.js +1 -1
  269. package/node_modules/pi-lens/dist/clients/lsp/config.js +4 -6
  270. package/node_modules/pi-lens/dist/clients/lsp/edits.js +119 -32
  271. package/node_modules/pi-lens/dist/clients/lsp/index.js +94 -35
  272. package/node_modules/pi-lens/dist/clients/lsp/inferred-project.js +2 -1
  273. package/node_modules/pi-lens/dist/clients/lsp/jvm-runtime.js +4 -1
  274. package/node_modules/pi-lens/dist/clients/lsp/launch.js +11 -3
  275. package/node_modules/pi-lens/dist/clients/lsp/pending-aux-coverage.js +152 -0
  276. package/node_modules/pi-lens/dist/clients/lsp/server.js +19 -7
  277. package/node_modules/pi-lens/dist/clients/lsp/tsserver-sync.js +10 -2
  278. package/node_modules/pi-lens/dist/clients/lsp/workspace-diagnostics-cache.js +9 -4
  279. package/node_modules/pi-lens/dist/clients/lsp-document-symbols.js +1 -3
  280. package/node_modules/pi-lens/dist/clients/lsp-mutation.js +10 -20
  281. package/node_modules/pi-lens/dist/clients/mcp/host-shim.js +1 -1
  282. package/node_modules/pi-lens/dist/clients/memory-sampler.js +73 -7
  283. package/node_modules/pi-lens/dist/clients/metrics-client.js +1 -3
  284. package/node_modules/pi-lens/dist/clients/middle-man-analysis.js +8 -3
  285. package/node_modules/pi-lens/dist/clients/module-report-lsp.js +7 -1
  286. package/node_modules/pi-lens/dist/clients/module-report.js +14 -17
  287. package/node_modules/pi-lens/dist/clients/ndjson-logger.js +3 -5
  288. package/node_modules/pi-lens/dist/clients/opaque-mutation-scan.js +220 -0
  289. package/node_modules/pi-lens/dist/clients/package-manager.js +6 -1
  290. package/node_modules/pi-lens/dist/clients/pipeline.js +57 -9
  291. package/node_modules/pi-lens/dist/clients/project-conventions.js +2 -8
  292. package/node_modules/pi-lens/dist/clients/project-diagnostics/cache.js +10 -7
  293. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/call-graph-impact.js +2 -1
  294. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/gitleaks.js +3 -1
  295. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/runner-findings.js +13 -9
  296. package/node_modules/pi-lens/dist/clients/project-diagnostics/runner-adapters/trivy.js +3 -1
  297. package/node_modules/pi-lens/dist/clients/project-diagnostics/scanner.js +5 -2
  298. package/node_modules/pi-lens/dist/clients/project-lens-config.js +12 -5
  299. package/node_modules/pi-lens/dist/clients/project-snapshot-fingerprint.js +48 -0
  300. package/node_modules/pi-lens/dist/clients/project-snapshot-persist-worker.js +15 -1
  301. package/node_modules/pi-lens/dist/clients/project-snapshot.js +472 -66
  302. package/node_modules/pi-lens/dist/clients/read-expansion.js +12 -2
  303. package/node_modules/pi-lens/dist/clients/read-guard-logger.js +5 -4
  304. package/node_modules/pi-lens/dist/clients/read-guard-tool-lines.js +5 -2
  305. package/node_modules/pi-lens/dist/clients/read-guard.js +1 -1
  306. package/node_modules/pi-lens/dist/clients/resource-sampler.js +1 -1
  307. package/node_modules/pi-lens/dist/clients/reverse-deps.js +6 -5
  308. package/node_modules/pi-lens/dist/clients/review-graph/builder.js +42 -17
  309. package/node_modules/pi-lens/dist/clients/review-graph/git-identity.js +8 -2
  310. package/node_modules/pi-lens/dist/clients/review-graph/import-resolvers.js +10 -1
  311. package/node_modules/pi-lens/dist/clients/review-graph/query.js +2 -1
  312. package/node_modules/pi-lens/dist/clients/review-graph/tsconfig-paths.js +4 -2
  313. package/node_modules/pi-lens/dist/clients/review-graph/workspace-modules.js +2 -2
  314. package/node_modules/pi-lens/dist/clients/ruff-client.js +6 -5
  315. package/node_modules/pi-lens/dist/clients/runtime-agent-end.js +63 -31
  316. package/node_modules/pi-lens/dist/clients/runtime-context.js +12 -4
  317. package/node_modules/pi-lens/dist/clients/runtime-coordinator.js +83 -4
  318. package/node_modules/pi-lens/dist/clients/runtime-session.js +14 -0
  319. package/node_modules/pi-lens/dist/clients/runtime-tool-call.js +59 -3
  320. package/node_modules/pi-lens/dist/clients/runtime-tool-result.js +148 -34
  321. package/node_modules/pi-lens/dist/clients/runtime-turn.js +147 -6
  322. package/node_modules/pi-lens/dist/clients/rust-client.js +1 -3
  323. package/node_modules/pi-lens/dist/clients/safe-spawn.js +150 -11
  324. package/node_modules/pi-lens/dist/clients/security-scan-client.js +1 -3
  325. package/node_modules/pi-lens/dist/clients/session-summary.js +3 -1
  326. package/node_modules/pi-lens/dist/clients/sg-runner.js +1 -3
  327. package/node_modules/pi-lens/dist/clients/source-filter.js +10 -6
  328. package/node_modules/pi-lens/dist/clients/source-walker.js +1 -1
  329. package/node_modules/pi-lens/dist/clients/spawn-timeout-cooldown.js +96 -0
  330. package/node_modules/pi-lens/dist/clients/startup-scan.js +4 -1
  331. package/node_modules/pi-lens/dist/clients/tool-definition.js +7 -0
  332. package/node_modules/pi-lens/dist/clients/tool-policy.js +26 -11
  333. package/node_modules/pi-lens/dist/clients/tool-render.js +2 -1
  334. package/node_modules/pi-lens/dist/clients/tree-sitter-client.js +10 -4
  335. package/node_modules/pi-lens/dist/clients/tree-sitter-logger.js +2 -2
  336. package/node_modules/pi-lens/dist/clients/tree-sitter-symbol-extractor.js +12 -5
  337. package/node_modules/pi-lens/dist/clients/warm-attach.js +12 -5
  338. package/node_modules/pi-lens/dist/clients/widget-state.js +27 -11
  339. package/node_modules/pi-lens/dist/clients/word-index.js +3 -1
  340. package/node_modules/pi-lens/dist/clients/workspace-topology.js +8 -2
  341. package/node_modules/pi-lens/dist/clients/zizmor-config.js +9 -1
  342. package/node_modules/pi-lens/dist/i18n.js +13 -5
  343. package/node_modules/pi-lens/dist/index.js +10797 -8627
  344. package/node_modules/pi-lens/dist/mcp/server.js +3 -1
  345. package/node_modules/pi-lens/dist/tools/ast-grep-replace.js +68 -12
  346. package/node_modules/pi-lens/dist/tools/lens-diagnostic-mark.js +21 -7
  347. package/node_modules/pi-lens/dist/tools/lens-diagnostics.js +164 -35
  348. package/node_modules/pi-lens/dist/tools/lsp-diagnostics.js +24 -7
  349. package/node_modules/pi-lens/dist/tools/lsp-navigation.js +3 -1
  350. package/node_modules/pi-lens/dist/tools/module-report.js +1 -1
  351. package/node_modules/pi-lens/dist/tools/project-report.js +1 -1
  352. package/node_modules/pi-lens/dist/tools/symbol-search.js +5 -2
  353. package/node_modules/pi-lens/docs/durable-store-audit-1202.md +1 -1
  354. package/node_modules/pi-lens/docs/servercapabilities.md +1 -1
  355. package/node_modules/pi-lens/package.json +160 -156
  356. package/node_modules/pi-lens/rules/typos/_typos.toml +2 -2
  357. package/node_modules/pi-lens/scripts/analyze-pi-lens-logs.mjs +31 -13
  358. package/node_modules/pi-lens/scripts/download-grammars.js +9 -3
  359. package/node_modules/pi-lens/scripts/rpc-load-check.mjs +30 -9
  360. package/node_modules/pi-mcp-adapter/CHANGELOG.md +47 -0
  361. package/node_modules/pi-mcp-adapter/README.md +42 -13
  362. package/node_modules/pi-mcp-adapter/commands.ts +4 -2
  363. package/node_modules/pi-mcp-adapter/config.ts +45 -5
  364. package/node_modules/pi-mcp-adapter/direct-tools.ts +103 -92
  365. package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +10 -0
  366. package/node_modules/pi-mcp-adapter/dist/agent-dir.js +63 -0
  367. package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +1 -0
  368. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +8 -0
  369. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +356 -0
  370. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +1 -0
  371. package/node_modules/pi-mcp-adapter/dist/config.d.ts +123 -0
  372. package/node_modules/pi-mcp-adapter/dist/config.js +1087 -0
  373. package/node_modules/pi-mcp-adapter/dist/config.js.map +1 -0
  374. package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +19 -0
  375. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +319 -0
  376. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +1 -0
  377. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +2 -0
  378. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +156 -0
  379. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +1 -0
  380. package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +1 -0
  381. package/node_modules/pi-mcp-adapter/dist/resource-tools.js +15 -0
  382. package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +1 -0
  383. package/node_modules/pi-mcp-adapter/dist/types.d.ts +564 -0
  384. package/node_modules/pi-mcp-adapter/dist/types.js +287 -0
  385. package/node_modules/pi-mcp-adapter/dist/types.js.map +1 -0
  386. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +6 -0
  387. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +37 -0
  388. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +1 -0
  389. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +104 -0
  390. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +59 -0
  391. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +1 -0
  392. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +4 -0
  393. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +27 -0
  394. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +1 -0
  395. package/node_modules/pi-mcp-adapter/dist/utils.d.ts +32 -0
  396. package/node_modules/pi-mcp-adapter/dist/utils.js +338 -0
  397. package/node_modules/pi-mcp-adapter/dist/utils.js.map +1 -0
  398. package/node_modules/pi-mcp-adapter/failure-backoff.ts +23 -0
  399. package/node_modules/pi-mcp-adapter/index.ts +204 -82
  400. package/node_modules/pi-mcp-adapter/init.ts +41 -30
  401. package/node_modules/pi-mcp-adapter/lifecycle.ts +16 -8
  402. package/node_modules/pi-mcp-adapter/mcp-code.ts +2 -0
  403. package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +66 -16
  404. package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +95 -7
  405. package/node_modules/pi-mcp-adapter/mcp-probe.ts +18 -4
  406. package/node_modules/pi-mcp-adapter/mcp-references.ts +368 -0
  407. package/node_modules/pi-mcp-adapter/mcp-status.ts +8 -19
  408. package/node_modules/pi-mcp-adapter/metadata-cache.ts +20 -12
  409. package/node_modules/pi-mcp-adapter/namespace-tools.ts +276 -0
  410. package/node_modules/pi-mcp-adapter/package.json +24 -6
  411. package/node_modules/pi-mcp-adapter/proxy-modes.ts +66 -10
  412. package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -0
  413. package/node_modules/pi-mcp-adapter/server-manager.ts +63 -12
  414. package/node_modules/pi-mcp-adapter/state.ts +1 -3
  415. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +16 -2
  416. package/node_modules/pi-mcp-adapter/types.ts +48 -1
  417. package/node_modules/pi-mcp-adapter/ui-server.ts +3 -19
  418. package/node_modules/pi-mcp-adapter/ui-session.ts +2 -1
  419. package/node_modules/pi-mcp-adapter/utils.ts +21 -19
  420. package/node_modules/pi-web-access/CHANGELOG.md +26 -0
  421. package/node_modules/pi-web-access/README.md +71 -14
  422. package/node_modules/pi-web-access/chrome-cookies.ts +115 -35
  423. package/node_modules/pi-web-access/credential-source.ts +6 -2
  424. package/node_modules/pi-web-access/curator-page.ts +5 -3
  425. package/node_modules/pi-web-access/curator-server.ts +2 -1
  426. package/node_modules/pi-web-access/extract.ts +89 -9
  427. package/node_modules/pi-web-access/fetch-params.ts +13 -0
  428. package/node_modules/pi-web-access/gemini-adc.ts +298 -0
  429. package/node_modules/pi-web-access/gemini-api.ts +59 -15
  430. package/node_modules/pi-web-access/gemini-search.ts +58 -18
  431. package/node_modules/pi-web-access/gemini-url-context.ts +3 -2
  432. package/node_modules/pi-web-access/gemini-web-config.ts +57 -7
  433. package/node_modules/pi-web-access/gemini-web.ts +9 -3
  434. package/node_modules/pi-web-access/github-api.ts +5 -4
  435. package/node_modules/pi-web-access/github-issue-pr.ts +700 -0
  436. package/node_modules/pi-web-access/index.ts +403 -297
  437. package/node_modules/pi-web-access/kimi-search.ts +234 -0
  438. package/node_modules/pi-web-access/openai-search.ts +118 -21
  439. package/node_modules/pi-web-access/package.json +3 -2
  440. package/node_modules/pi-web-access/ssrf-protection.ts +4 -1
  441. package/node_modules/pi-web-access/utils.ts +307 -1
  442. package/node_modules/pi-web-access/youtube-extract.ts +2 -2
  443. package/package.json +46 -37
  444. package/node_modules/@herbertgao/pi-copy-response/CHANGELOG.md +0 -49
  445. package/node_modules/@herbertgao/pi-copy-response/LICENSE +0 -22
  446. package/node_modules/@herbertgao/pi-handoff/CHANGELOG.md +0 -83
  447. package/node_modules/@herbertgao/pi-handoff/LICENSE +0 -22
  448. package/node_modules/@herbertgao/pi-handoff/package.json +0 -60
  449. package/node_modules/@herbertgao/pi-inline-skills/CHANGELOG.md +0 -57
  450. package/node_modules/@herbertgao/pi-inline-skills/LICENSE +0 -22
  451. package/node_modules/@herbertgao/pi-mermaid-open/CHANGELOG.md +0 -39
  452. package/node_modules/@herbertgao/pi-preferred-thinking/CHANGELOG.md +0 -63
  453. package/node_modules/@herbertgao/pi-preferred-thinking/LICENSE +0 -22
  454. package/node_modules/@herbertgao/pi-recap/CHANGELOG.md +0 -101
  455. package/node_modules/@herbertgao/pi-recap/LICENSE +0 -22
  456. package/node_modules/@herbertgao/pi-recap/package.json +0 -55
  457. package/node_modules/@herbertgao/pi-rename/CHANGELOG.md +0 -49
  458. package/node_modules/@herbertgao/pi-rename/LICENSE +0 -22
  459. package/node_modules/@herbertgao/pi-rename/package.json +0 -63
  460. package/node_modules/@herbertgao/pi-titlebar-spinner/CHANGELOG.md +0 -25
  461. package/node_modules/@herbertgao/pi-titlebar-spinner/LICENSE +0 -22
  462. /package/node_modules/{@herbertgao → @tifan}/pi-copy-response/src/index.ts +0 -0
  463. /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/complete-text.ts +0 -0
  464. /package/node_modules/{@herbertgao → @tifan}/pi-handoff/src/session-query.ts +0 -0
  465. /package/node_modules/{@herbertgao → @tifan}/pi-inline-skills/src/index.ts +0 -0
  466. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/herdr-plugin.toml +0 -0
  467. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/herdr-plugin/viewer.mjs +0 -0
  468. /package/node_modules/{@herbertgao → @tifan}/pi-mermaid-open/src/index.ts +0 -0
  469. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/index.ts +0 -0
  470. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/model-picker.ts +0 -0
  471. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/sanitize.ts +0 -0
  472. /package/node_modules/{@herbertgao → @tifan}/pi-recap/src/tui.ts +0 -0
  473. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/model-picker.ts +0 -0
  474. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/naming.ts +0 -0
  475. /package/node_modules/{@herbertgao → @tifan}/pi-rename/src/sanitize.ts +0 -0
  476. /package/node_modules/{@herbertgao → @tifan}/pi-titlebar-spinner/src/index.ts +0 -0
@@ -0,0 +1,234 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
3
+ import { activityMonitor } from "./activity.ts";
4
+ import { redactCredential } from "./credential-source.ts";
5
+ import type { SearchOptions, SearchResponse, SearchResult } from "./perplexity.ts";
6
+
7
+ const KIMI_SEARCH_URL = "https://api.kimi.com/coding/v1/search";
8
+ const KIMI_PROVIDERS = ["kimi-coding", "kimi-code"] as const;
9
+ const SEARCH_TIMEOUT_MS = 30_000;
10
+
11
+ type ProviderHeaders = Record<string, string | null>;
12
+
13
+ interface KimiAuth {
14
+ apiKey: string;
15
+ headers: ProviderHeaders;
16
+ }
17
+
18
+ interface NormalizedDomainFilters {
19
+ allowed: string[];
20
+ blocked: string[];
21
+ }
22
+
23
+ function buildRequestHeaders(auth: KimiAuth): Headers {
24
+ const headers = new Headers();
25
+ for (const [name, value] of Object.entries(auth.headers)) {
26
+ if (value !== null) headers.set(name, value);
27
+ }
28
+ headers.set("Authorization", `Bearer ${auth.apiKey}`);
29
+ headers.set("Content-Type", "application/json");
30
+ headers.set("X-Msh-Tool-Call-Id", randomUUID());
31
+ return headers;
32
+ }
33
+
34
+ function bearerToken(headers: ProviderHeaders): string | undefined {
35
+ for (const [name, value] of Object.entries(headers)) {
36
+ if (name.toLowerCase() !== "authorization" || typeof value !== "string") continue;
37
+ const match = /^Bearer\s+(.+)$/i.exec(value.trim());
38
+ if (match?.[1]) return match[1];
39
+ }
40
+ return undefined;
41
+ }
42
+
43
+ async function resolveKimiAuth(ctx?: ExtensionContext): Promise<KimiAuth | undefined> {
44
+ if (!ctx) return undefined;
45
+
46
+ const models = ctx.modelRegistry.getAll();
47
+ let firstError: unknown;
48
+
49
+ for (const provider of KIMI_PROVIDERS) {
50
+ for (const model of models) {
51
+ if (model.provider !== provider) continue;
52
+ let resolved: Awaited<ReturnType<typeof ctx.modelRegistry.getApiKeyAndHeaders>>;
53
+ try {
54
+ resolved = await ctx.modelRegistry.getApiKeyAndHeaders(model);
55
+ } catch (err) {
56
+ firstError ??= err;
57
+ continue;
58
+ }
59
+ if (!resolved.ok) continue;
60
+ const headers = resolved.headers ?? {};
61
+ const apiKey = resolved.apiKey || bearerToken(headers);
62
+ if (apiKey) return { apiKey, headers };
63
+ }
64
+ }
65
+ if (firstError) throw firstError;
66
+ return undefined;
67
+ }
68
+
69
+ function normalizeCount(value: number | undefined): number {
70
+ if (typeof value !== "number" || !Number.isFinite(value)) return 5;
71
+ return Math.max(1, Math.min(Math.floor(value), 20));
72
+ }
73
+
74
+ function normalizeDomain(value: string): string | null {
75
+ let input = value.trim().toLowerCase();
76
+ if (!input) return null;
77
+ if (input.startsWith("-")) input = input.slice(1).trim();
78
+ if (!input) return null;
79
+ try {
80
+ const parsed = input.includes("://") ? new URL(input) : new URL(`https://${input}`);
81
+ input = parsed.hostname;
82
+ } catch {
83
+ input = input.split("/")[0]?.split(":")[0] ?? "";
84
+ }
85
+ input = input.replace(/^\.+|\.+$/g, "");
86
+ return /^[a-z0-9][a-z0-9.-]*\.[a-z]{2,}$/i.test(input) ? input : null;
87
+ }
88
+
89
+ function normalizeDomainFilters(domainFilter: string[] | undefined): NormalizedDomainFilters {
90
+ const filters: NormalizedDomainFilters = { allowed: [], blocked: [] };
91
+ if (!domainFilter?.length) return filters;
92
+
93
+ for (const raw of domainFilter) {
94
+ const domain = normalizeDomain(raw);
95
+ if (!domain) continue;
96
+ const target = raw.trim().startsWith("-") ? filters.blocked : filters.allowed;
97
+ if (!target.includes(domain)) target.push(domain);
98
+ }
99
+ return filters;
100
+ }
101
+
102
+ function hostMatchesDomain(hostname: string, domain: string): boolean {
103
+ return hostname === domain || hostname.endsWith(`.${domain}`);
104
+ }
105
+
106
+ function matchesDomainFilters(url: string, filters: NormalizedDomainFilters): boolean {
107
+ if (filters.allowed.length === 0 && filters.blocked.length === 0) return true;
108
+
109
+ let hostname = "";
110
+ try {
111
+ hostname = new URL(url).hostname.toLowerCase();
112
+ } catch {
113
+ return false;
114
+ }
115
+ if (filters.allowed.length > 0 && !filters.allowed.some((domain) => hostMatchesDomain(hostname, domain))) {
116
+ return false;
117
+ }
118
+ return !filters.blocked.some((domain) => hostMatchesDomain(hostname, domain));
119
+ }
120
+
121
+ function normalizeResultUrl(value: unknown): string | null {
122
+ if (typeof value !== "string") return null;
123
+ const input = value.trim();
124
+ if (!input) return null;
125
+ try {
126
+ const url = new URL(input);
127
+ if (url.protocol !== "http:" && url.protocol !== "https:") return null;
128
+ return url.href;
129
+ } catch {
130
+ return null;
131
+ }
132
+ }
133
+
134
+ function parseResults(value: unknown, options: SearchOptions): SearchResult[] {
135
+ if (!value || typeof value !== "object" || !Array.isArray((value as { search_results?: unknown }).search_results)) {
136
+ throw new Error("Kimi Code search API returned an invalid response: search_results must be an array");
137
+ }
138
+
139
+ const filters = normalizeDomainFilters(options.domainFilter);
140
+ const numResults = normalizeCount(options.numResults);
141
+ const results: SearchResult[] = [];
142
+ for (const item of (value as { search_results: unknown[] }).search_results) {
143
+ if (!item || typeof item !== "object") continue;
144
+ const record = item as Record<string, unknown>;
145
+ const url = normalizeResultUrl(record.url);
146
+ if (!url || !matchesDomainFilters(url, filters)) continue;
147
+ results.push({
148
+ title: typeof record.title === "string" && record.title.trim() ? record.title : url,
149
+ url,
150
+ snippet: typeof record.snippet === "string" ? record.snippet : "",
151
+ });
152
+ if (results.length >= numResults) break;
153
+ }
154
+ return results;
155
+ }
156
+
157
+ function formatAnswer(results: SearchResult[]): string {
158
+ return results
159
+ .map((result) => result.snippet
160
+ ? `${result.snippet}\nSource: ${result.title} (${result.url})`
161
+ : `Source: ${result.title} (${result.url})`)
162
+ .join("\n\n");
163
+ }
164
+
165
+ export async function isKimiSearchAvailable(ctx?: ExtensionContext): Promise<boolean> {
166
+ try {
167
+ return !!(await resolveKimiAuth(ctx));
168
+ } catch {
169
+ return false;
170
+ }
171
+ }
172
+
173
+ export async function searchWithKimi(
174
+ query: string,
175
+ options: SearchOptions = {},
176
+ ctx?: ExtensionContext,
177
+ ): Promise<SearchResponse> {
178
+ const auth = await resolveKimiAuth(ctx);
179
+ if (!auth) {
180
+ throw new Error("Kimi Code web search unavailable. Run /login kimi-coding to authenticate a Kimi Code Plan account.");
181
+ }
182
+
183
+ const activityId = activityMonitor.logStart({ type: "api", query });
184
+ const timeoutSignal = AbortSignal.timeout(SEARCH_TIMEOUT_MS);
185
+ const requestSignal = options.signal
186
+ ? AbortSignal.any([timeoutSignal, options.signal])
187
+ : timeoutSignal;
188
+ try {
189
+ const response = await fetch(KIMI_SEARCH_URL, {
190
+ method: "POST",
191
+ headers: buildRequestHeaders(auth),
192
+ body: JSON.stringify({ text_query: query }),
193
+ signal: requestSignal,
194
+ });
195
+
196
+ if (!response.ok) {
197
+ activityMonitor.logError(activityId, `HTTP ${response.status}`);
198
+ const errorText = redactCredential(await response.text(), auth.apiKey);
199
+ throw new Error(`Kimi Code search API error ${response.status}: ${errorText.slice(0, 300)}`);
200
+ }
201
+
202
+ let parsed: unknown;
203
+ try {
204
+ parsed = await response.json();
205
+ } catch (err) {
206
+ const message = err instanceof Error ? err.message : String(err);
207
+ throw new Error(`Kimi Code search API returned invalid JSON: ${message}`);
208
+ }
209
+ const results = parseResults(parsed, options);
210
+ if (results.length === 0) {
211
+ throw new Error("Kimi Code search API returned no results");
212
+ }
213
+
214
+ activityMonitor.logComplete(activityId, response.status);
215
+ return { answer: formatAnswer(results), results };
216
+ } catch (err) {
217
+ const message = err instanceof Error ? err.message : String(err);
218
+ const redactedMessage = redactCredential(message, auth.apiKey);
219
+ if (options.signal?.aborted) {
220
+ activityMonitor.logComplete(activityId, 0);
221
+ } else if (timeoutSignal.aborted || (err instanceof Error && err.name === "TimeoutError")) {
222
+ activityMonitor.logError(activityId, "Kimi Code search API timed out");
223
+ throw new Error("Kimi Code search API timed out");
224
+ } else if (redactedMessage.toLowerCase().includes("abort")) {
225
+ activityMonitor.logComplete(activityId, 0);
226
+ } else {
227
+ activityMonitor.logError(activityId, redactedMessage);
228
+ }
229
+ if (redactedMessage === message) throw err;
230
+ const redactedError = new Error(redactedMessage);
231
+ if (err instanceof Error) redactedError.name = err.name;
232
+ throw redactedError;
233
+ }
234
+ }
@@ -47,6 +47,47 @@ interface OpenAIAuth {
47
47
  model: string;
48
48
  headers: ProviderHeaders;
49
49
  responsesUrl: string;
50
+ useCodexEndpoint?: boolean;
51
+ }
52
+
53
+ type CurrentModel = NonNullable<ExtensionContext["model"]>;
54
+
55
+ interface CurrentModelSearchTarget {
56
+ responsesUrl: string;
57
+ useCodexEndpoint: boolean;
58
+ }
59
+
60
+ function resolveCurrentModelSearchTarget(model: CurrentModel): CurrentModelSearchTarget {
61
+ const url = new URL(model.baseUrl);
62
+ if (url.protocol !== "https:") throw new Error("Current model base URL must use HTTPS");
63
+
64
+ if (model.provider === "openai" && model.api === "openai-responses" && url.hostname.toLowerCase() === "api.openai.com") {
65
+ const pathname = url.pathname.replace(/\/+$/u, "");
66
+ url.pathname = `${pathname}/responses`;
67
+ return { responsesUrl: url.toString(), useCodexEndpoint: false };
68
+ }
69
+
70
+ if (
71
+ model.provider === "openai-codex" &&
72
+ model.api === "openai-codex-responses" &&
73
+ url.hostname.toLowerCase() === "chatgpt.com" &&
74
+ url.pathname.replace(/\/+$/u, "") === "/backend-api"
75
+ ) {
76
+ return { responsesUrl: CODEX_RESPONSES_URL, useCodexEndpoint: true };
77
+ }
78
+
79
+ throw new Error("Current model is not backed by an official OpenAI Responses endpoint");
80
+ }
81
+
82
+ export function isCurrentModelHostedSearchEligible(ctx?: Pick<ExtensionContext, "model">): boolean {
83
+ const model = ctx?.model;
84
+ if (!model || !/^gpt-/iu.test(model.id)) return false;
85
+ try {
86
+ resolveCurrentModelSearchTarget(model);
87
+ return true;
88
+ } catch {
89
+ return false;
90
+ }
50
91
  }
51
92
 
52
93
  interface NormalizedDomainFilters {
@@ -240,6 +281,26 @@ export async function isOpenAISearchAvailable(ctx?: ExtensionContext): Promise<b
240
281
  });
241
282
  }
242
283
 
284
+ async function resolveCurrentModelAuth(ctx: ExtensionContext, signal?: AbortSignal): Promise<OpenAIAuth> {
285
+ const model = ctx.model;
286
+ if (!model || !isCurrentModelHostedSearchEligible(ctx)) {
287
+ throw new Error("Current model is not eligible for official OpenAI Hosted web search");
288
+ }
289
+ const target = resolveCurrentModelSearchTarget(model);
290
+ const resolved = await ctx.modelRegistry.getApiKeyAndHeaders(model);
291
+ if (signal?.aborted) signal.throwIfAborted();
292
+ if (!resolved.ok) throw new Error(`OpenAI current model authentication failed: ${resolved.error}`);
293
+ if (!resolved.apiKey) throw new Error("OpenAI current model authentication failed: API key unavailable");
294
+ return {
295
+ provider: "openai",
296
+ apiKey: resolved.apiKey,
297
+ model: model.id,
298
+ headers: resolved.headers ?? {},
299
+ responsesUrl: target.responsesUrl,
300
+ useCodexEndpoint: target.useCodexEndpoint,
301
+ };
302
+ }
303
+
243
304
  function buildInstructions(options: SearchOptions): string {
244
305
  const lines = [
245
306
  "Search the web and return a concise answer grounded only in the web results.",
@@ -279,14 +340,26 @@ function buildWebSearchTool(options: SearchOptions): Record<string, unknown> {
279
340
  return tool;
280
341
  }
281
342
 
282
- async function parseOpenAIResponse(response: Response): Promise<Record<string, unknown>> {
343
+ interface ParsedOpenAIResponse {
344
+ payload: Record<string, unknown>;
345
+ webSearchCallSeen: boolean;
346
+ }
347
+
348
+ function isWebSearchCall(item: unknown): boolean {
349
+ return !!item && typeof item === "object" && (item as { type?: unknown }).type === "web_search_call";
350
+ }
351
+
352
+ async function parseOpenAIResponse(response: Response): Promise<ParsedOpenAIResponse> {
283
353
  const text = await response.text();
284
354
  const trimmed = text.trim();
285
355
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
286
356
  try {
287
357
  const parsed = JSON.parse(trimmed);
288
- if (Array.isArray(parsed)) return { output: parsed };
289
- return parsed && typeof parsed === "object" ? parsed as Record<string, unknown> : { output: [] };
358
+ const payload = Array.isArray(parsed)
359
+ ? { output: parsed }
360
+ : parsed && typeof parsed === "object" ? parsed as Record<string, unknown> : { output: [] };
361
+ const output = Array.isArray(payload.output) ? payload.output : [];
362
+ return { payload, webSearchCallSeen: output.some(isWebSearchCall) };
290
363
  } catch (err) {
291
364
  const message = err instanceof Error ? err.message : String(err);
292
365
  throw new Error(`OpenAI API returned invalid JSON: ${message}`);
@@ -295,13 +368,18 @@ async function parseOpenAIResponse(response: Response): Promise<Record<string, u
295
368
 
296
369
  const outputItems: unknown[] = [];
297
370
  let completedResponse: Record<string, unknown> | null = null;
371
+ let webSearchCallSeen = false;
298
372
  for (const line of text.split("\n")) {
299
373
  if (!line.startsWith("data: ")) continue;
300
374
  const data = line.slice(6).trim();
301
375
  if (!data || data === "[DONE]") continue;
302
376
  try {
303
377
  const parsed = JSON.parse(data) as Record<string, unknown>;
304
- if (parsed.type === "response.output_item.done" && parsed.item) outputItems.push(parsed.item);
378
+ if (typeof parsed.type === "string" && parsed.type.startsWith("response.web_search_call")) webSearchCallSeen = true;
379
+ if (parsed.type === "response.output_item.done" && parsed.item) {
380
+ outputItems.push(parsed.item);
381
+ webSearchCallSeen ||= isWebSearchCall(parsed.item);
382
+ }
305
383
  if ((parsed.type === "response.done" || parsed.type === "response.completed") && parsed.response && typeof parsed.response === "object") {
306
384
  completedResponse = parsed.response as Record<string, unknown>;
307
385
  }
@@ -311,9 +389,10 @@ async function parseOpenAIResponse(response: Response): Promise<Record<string, u
311
389
 
312
390
  if (completedResponse) {
313
391
  const output = Array.isArray(completedResponse.output) ? completedResponse.output : [];
314
- return output.length > 0 ? completedResponse : { ...completedResponse, output: outputItems };
392
+ const payload = output.length > 0 ? completedResponse : { ...completedResponse, output: outputItems };
393
+ return { payload, webSearchCallSeen: webSearchCallSeen || output.some(isWebSearchCall) };
315
394
  }
316
- if (outputItems.length > 0) return { output: outputItems };
395
+ if (outputItems.length > 0) return { payload: { output: outputItems }, webSearchCallSeen: webSearchCallSeen || outputItems.some(isWebSearchCall) };
317
396
  throw new Error("OpenAI API returned no parseable response output");
318
397
  }
319
398
 
@@ -411,21 +490,11 @@ function extractAnswer(output: unknown[]): string {
411
490
  return parts.join("\n").trim();
412
491
  }
413
492
 
414
- export async function searchWithOpenAI(
493
+ async function runOpenAISearch(
415
494
  query: string,
416
- options: SearchOptions = {},
417
- ctx?: ExtensionContext,
495
+ options: SearchOptions,
496
+ auth: OpenAIAuth,
418
497
  ): Promise<SearchResponse> {
419
- const auth = await resolveOpenAIAuth(ctx, options.signal);
420
- if (!auth) {
421
- throw new Error(
422
- "OpenAI web search unavailable. Either:\n" +
423
- " 1. Use /login to sign in with a Codex subscription\n" +
424
- ` 2. Create ${CONFIG_PATH} with { "openaiApiKey": "your-key" }\n` +
425
- " 3. Set OPENAI_API_KEY environment variable",
426
- );
427
- }
428
-
429
498
  const activityId = activityMonitor.logStart({ type: "api", query });
430
499
  const headers: Record<string, string> = {
431
500
  ...toRequestHeaders(auth.headers),
@@ -433,7 +502,7 @@ export async function searchWithOpenAI(
433
502
  "Content-Type": "application/json",
434
503
  "OpenAI-Beta": "responses=experimental",
435
504
  };
436
- const useCodexEndpoint = auth.provider === "openai-codex" || isCodexJwt(auth.apiKey);
505
+ const useCodexEndpoint = auth.useCodexEndpoint ?? (auth.provider === "openai-codex" || isCodexJwt(auth.apiKey));
437
506
  if (useCodexEndpoint) {
438
507
  const accountId = extractAccountId(auth.apiKey);
439
508
  if (accountId) headers["chatgpt-account-id"] = accountId;
@@ -469,7 +538,8 @@ export async function searchWithOpenAI(
469
538
  }
470
539
 
471
540
  const parsed = await parseOpenAIResponse(response);
472
- const output = Array.isArray(parsed.output) ? parsed.output : [];
541
+ const output = Array.isArray(parsed.payload.output) ? parsed.payload.output : [];
542
+ if (!parsed.webSearchCallSeen) throw new Error("OpenAI web_search returned no web_search_call");
473
543
  const answer = extractAnswer(output);
474
544
  const results = extractSearchResults(output, options.numResults);
475
545
 
@@ -493,3 +563,30 @@ export async function searchWithOpenAI(
493
563
  throw redactedError;
494
564
  }
495
565
  }
566
+
567
+ export async function searchWithOpenAI(
568
+ query: string,
569
+ options: SearchOptions = {},
570
+ ctx?: ExtensionContext,
571
+ ): Promise<SearchResponse> {
572
+ const auth = await resolveOpenAIAuth(ctx, options.signal);
573
+ if (!auth) {
574
+ throw new Error(
575
+ "OpenAI web search unavailable. Either:\n" +
576
+ " 1. Use /login to sign in with a Codex subscription\n" +
577
+ ` 2. Create ${CONFIG_PATH} with { "openaiApiKey": "your-key" }\n` +
578
+ " 3. Set OPENAI_API_KEY environment variable",
579
+ );
580
+ }
581
+ return runOpenAISearch(query, options, auth);
582
+ }
583
+
584
+ export async function searchWithCurrentModelOpenAI(
585
+ query: string,
586
+ options: SearchOptions = {},
587
+ ctx?: ExtensionContext,
588
+ ): Promise<SearchResponse> {
589
+ if (!ctx) throw new Error("OpenAI current-model search requires an extension context");
590
+ const auth = await resolveCurrentModelAuth(ctx, options.signal);
591
+ return runOpenAISearch(query, options, auth);
592
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-web-access",
3
- "version": "0.24.2",
4
- "description": "Web search, URL fetching, GitHub repo cloning, PDF extraction, YouTube video understanding, and local video analysis for Pi coding agent. Supports OpenAI, Brave, Parallel, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Ollama, AnySearch, Bright Data SERP, SerpBase, SearXNG, Exa, Perplexity, and Gemini.",
3
+ "version": "0.25.0",
4
+ "description": "Web search, URL fetching, GitHub repo cloning, PDF extraction, YouTube video understanding, and local video analysis for Pi coding agent. Supports OpenAI, Brave, Parallel, TinyFish, Search1API, Searchinfinity, Querit, Tavily, Firecrawl, Jina, SERPdive, Kagi, Ollama, AnySearch, Bright Data SERP, SerpBase, SearXNG, Exa, Perplexity, Gemini, and Kimi.",
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "test": "node --test",
@@ -45,6 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@mozilla/readability": "^0.6.0",
48
+ "defuddle": "0.19.3",
48
49
  "linkedom": "^0.16.0",
49
50
  "p-limit": "^6.1.0",
50
51
  "promise.try": "^2.0.1",
@@ -1,7 +1,7 @@
1
1
  import { lookup as dnsLookup } from "node:dns/promises";
2
2
  import { existsSync, readFileSync, statSync } from "node:fs";
3
3
  import net from "node:net";
4
- import { getWebSearchConfigPath } from "./utils.ts";
4
+ import { getActiveProxy, getWebSearchConfigPath, hasScopedProxyDecision, isProxyBypassedUrl } from "./utils.ts";
5
5
 
6
6
  const DEFAULT_MAX_REDIRECTS = 5;
7
7
  const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
@@ -329,6 +329,9 @@ function hostnameMatchesNoProxy(hostname: string, port: string, entry: string):
329
329
 
330
330
  function shouldTrustEnvProxy(url: URL, enabled: boolean): boolean {
331
331
  if (!enabled || !getProxyForProtocol(url.protocol)) return false;
332
+ if (hasScopedProxyDecision()) return false;
333
+ const activeProxy = getActiveProxy();
334
+ if (activeProxy && !isProxyBypassedUrl(url)) return false;
332
335
  const hostname = normalizeHostname(url.hostname);
333
336
  const port = url.port || (url.protocol === "https:" ? "443" : "80");
334
337
  const noProxy = process.env.NO_PROXY || process.env.no_proxy || "";