@herbertgao/pi-extensions 2026.9.17 → 2026.9.19

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 (307) hide show
  1. package/README.md +31 -33
  2. package/THIRD_PARTY_NOTICES.md +1 -1
  3. package/node_modules/@herbertgao/pi-bark/package.json +2 -2
  4. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +4 -1
  5. package/node_modules/@herbertgao/pi-cc-extensions/README.md +4 -1
  6. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/working-message.ts +21 -6
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +15 -4
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/index.ts +43 -7
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +7 -2
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +1 -1
  11. package/node_modules/@herbertgao/pi-cc-extensions/package.json +75 -75
  12. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +6 -0
  13. package/node_modules/@herbertgao/pi-subagents/package.json +7 -7
  14. package/node_modules/@herbertgao/resume-from/package.json +4 -2
  15. package/node_modules/@herbertgao/sol-pi/package.json +6 -6
  16. package/node_modules/@juicesharp/rpiv-ask-user-question/package.json +99 -99
  17. package/node_modules/@pi-plugins/fast-mode/package.json +1 -1
  18. package/node_modules/@tifan/pi-handoff/package.json +1 -1
  19. package/node_modules/@tifan/pi-handoff/src/index.ts +56 -26
  20. package/node_modules/@tifan/pi-mermaid-open/package.json +1 -1
  21. package/node_modules/@tifan/pi-preferred-thinking/package.json +1 -1
  22. package/node_modules/@tifan/pi-recap/package.json +1 -1
  23. package/node_modules/@tifan/pi-rename/package.json +1 -1
  24. package/node_modules/pi-antigravity/README.md +29 -6
  25. package/node_modules/pi-antigravity/package.json +14 -9
  26. package/node_modules/pi-antigravity/src/auth/accounts.ts +327 -0
  27. package/node_modules/pi-antigravity/src/auth/index.ts +9 -0
  28. package/node_modules/pi-antigravity/src/client/client.ts +1 -1
  29. package/node_modules/pi-antigravity/src/image/image.ts +4 -4
  30. package/node_modules/pi-antigravity/src/index.ts +203 -13
  31. package/node_modules/pi-antigravity/src/search/index.ts +1 -0
  32. package/node_modules/pi-antigravity/src/search/search.ts +325 -0
  33. package/node_modules/pi-antigravity/src/stream/stream.ts +191 -14
  34. package/node_modules/pi-antigravity/src/types/enums.ts +45 -36
  35. package/node_modules/pi-antigravity/src/types/types.ts +5 -12
  36. package/node_modules/pi-antigravity/src/utils/http.ts +7 -2
  37. package/node_modules/pi-antigravity/src/utils/util.ts +31 -3
  38. package/node_modules/pi-lens/package.json +158 -158
  39. package/node_modules/pi-multi-account/package.json +2 -2
  40. package/node_modules/pi-typesafe/README.md +3 -1
  41. package/node_modules/pi-typesafe/dist/auth.d.ts +9 -5
  42. package/node_modules/pi-typesafe/dist/auth.js +7 -3
  43. package/node_modules/pi-typesafe/dist/backends.d.ts +33 -3
  44. package/node_modules/pi-typesafe/dist/backends.js +95 -1
  45. package/node_modules/pi-typesafe/dist/client.d.ts +5 -5
  46. package/node_modules/pi-typesafe/dist/client.js +12 -9
  47. package/node_modules/pi-typesafe/dist/credentials.d.ts +14 -8
  48. package/node_modules/pi-typesafe/dist/credentials.js +10 -7
  49. package/node_modules/pi-typesafe/dist/errors.d.ts +2 -2
  50. package/node_modules/pi-typesafe/dist/index.d.ts +2 -2
  51. package/node_modules/pi-typesafe/dist/index.js +1 -1
  52. package/node_modules/pi-typesafe/dist/login.d.ts +2 -2
  53. package/node_modules/pi-typesafe/dist/login.js +2 -2
  54. package/node_modules/pi-typesafe/package.json +6 -5
  55. package/node_modules/pi-web-access/CHANGELOG.md +72 -0
  56. package/node_modules/pi-web-access/README.md +34 -13
  57. package/node_modules/pi-web-access/chrome-cookies.ts +79 -25
  58. package/node_modules/pi-web-access/curator-page.ts +5 -1
  59. package/node_modules/pi-web-access/curator-server.ts +2 -0
  60. package/node_modules/pi-web-access/dist/index.js +1337 -1009
  61. package/node_modules/pi-web-access/exa.ts +20 -52
  62. package/node_modules/pi-web-access/extract.ts +41 -4
  63. package/node_modules/pi-web-access/gemini-search.ts +12 -4
  64. package/node_modules/pi-web-access/index.ts +29 -37
  65. package/node_modules/pi-web-access/openai-search.ts +35 -7
  66. package/node_modules/pi-web-access/package.json +8 -7
  67. package/node_modules/pi-web-access/page-query.ts +2 -2
  68. package/node_modules/pi-web-access/query-rewrite.ts +2 -3
  69. package/node_modules/pi-web-access/ssrf-protection.ts +27 -10
  70. package/node_modules/pi-web-access/storage.ts +48 -77
  71. package/node_modules/pi-web-access/summary-model-scope.ts +6 -77
  72. package/node_modules/pi-web-access/summary-review.ts +3 -4
  73. package/node_modules/pi-web-access/tavily.ts +67 -20
  74. package/node_modules/pi-web-access/tool-activation.ts +53 -33
  75. package/node_modules/pi-web-access/utils.ts +1 -1
  76. package/node_modules/pi-web-access/you.ts +164 -0
  77. package/node_modules/pi-web-access/zai.ts +161 -0
  78. package/node_modules/remote-pi/package.json +5 -1
  79. package/package.json +19 -31
  80. package/node_modules/pi-mcp-adapter/CHANGELOG.md +0 -1013
  81. package/node_modules/pi-mcp-adapter/LICENSE +0 -21
  82. package/node_modules/pi-mcp-adapter/OAUTH.md +0 -369
  83. package/node_modules/pi-mcp-adapter/README.md +0 -1021
  84. package/node_modules/pi-mcp-adapter/abort.ts +0 -34
  85. package/node_modules/pi-mcp-adapter/agent-dir.ts +0 -68
  86. package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +0 -416
  87. package/node_modules/pi-mcp-adapter/agent-plugin-provenance.ts +0 -36
  88. package/node_modules/pi-mcp-adapter/app-bridge.bundle.js +0 -67
  89. package/node_modules/pi-mcp-adapter/banner.png +0 -0
  90. package/node_modules/pi-mcp-adapter/bearer-command-resolver.ts +0 -193
  91. package/node_modules/pi-mcp-adapter/claude-plugin-loader.ts +0 -365
  92. package/node_modules/pi-mcp-adapter/cli.js +0 -454
  93. package/node_modules/pi-mcp-adapter/commands.ts +0 -861
  94. package/node_modules/pi-mcp-adapter/config.ts +0 -1565
  95. package/node_modules/pi-mcp-adapter/consent-manager.ts +0 -95
  96. package/node_modules/pi-mcp-adapter/direct-tool-surface.ts +0 -244
  97. package/node_modules/pi-mcp-adapter/direct-tools.ts +0 -428
  98. package/node_modules/pi-mcp-adapter/dist/abort.d.ts +0 -2
  99. package/node_modules/pi-mcp-adapter/dist/abort.js +0 -36
  100. package/node_modules/pi-mcp-adapter/dist/abort.js.map +0 -1
  101. package/node_modules/pi-mcp-adapter/dist/agent-dir.d.ts +0 -10
  102. package/node_modules/pi-mcp-adapter/dist/agent-dir.js +0 -63
  103. package/node_modules/pi-mcp-adapter/dist/agent-dir.js.map +0 -1
  104. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.d.ts +0 -8
  105. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js +0 -398
  106. package/node_modules/pi-mcp-adapter/dist/agent-plugin-loader.js.map +0 -1
  107. package/node_modules/pi-mcp-adapter/dist/agent-plugin-provenance.d.ts +0 -1
  108. package/node_modules/pi-mcp-adapter/dist/agent-plugin-provenance.js +0 -31
  109. package/node_modules/pi-mcp-adapter/dist/agent-plugin-provenance.js.map +0 -1
  110. package/node_modules/pi-mcp-adapter/dist/bearer-command-resolver.d.ts +0 -6
  111. package/node_modules/pi-mcp-adapter/dist/bearer-command-resolver.js +0 -194
  112. package/node_modules/pi-mcp-adapter/dist/bearer-command-resolver.js.map +0 -1
  113. package/node_modules/pi-mcp-adapter/dist/claude-plugin-loader.d.ts +0 -9
  114. package/node_modules/pi-mcp-adapter/dist/claude-plugin-loader.js +0 -362
  115. package/node_modules/pi-mcp-adapter/dist/claude-plugin-loader.js.map +0 -1
  116. package/node_modules/pi-mcp-adapter/dist/config.d.ts +0 -134
  117. package/node_modules/pi-mcp-adapter/dist/config.js +0 -1361
  118. package/node_modules/pi-mcp-adapter/dist/config.js.map +0 -1
  119. package/node_modules/pi-mcp-adapter/dist/consent-manager.d.ts +0 -18
  120. package/node_modules/pi-mcp-adapter/dist/consent-manager.js +0 -88
  121. package/node_modules/pi-mcp-adapter/dist/consent-manager.js.map +0 -1
  122. package/node_modules/pi-mcp-adapter/dist/elicitation-handler.d.ts +0 -17
  123. package/node_modules/pi-mcp-adapter/dist/elicitation-handler.js +0 -316
  124. package/node_modules/pi-mcp-adapter/dist/elicitation-handler.js.map +0 -1
  125. package/node_modules/pi-mcp-adapter/dist/errors.d.ts +0 -131
  126. package/node_modules/pi-mcp-adapter/dist/errors.js +0 -278
  127. package/node_modules/pi-mcp-adapter/dist/errors.js.map +0 -1
  128. package/node_modules/pi-mcp-adapter/dist/http-ca.d.ts +0 -8
  129. package/node_modules/pi-mcp-adapter/dist/http-ca.js +0 -88
  130. package/node_modules/pi-mcp-adapter/dist/http-ca.js.map +0 -1
  131. package/node_modules/pi-mcp-adapter/dist/jev-client.d.ts +0 -14
  132. package/node_modules/pi-mcp-adapter/dist/jev-client.js +0 -367
  133. package/node_modules/pi-mcp-adapter/dist/jev-client.js.map +0 -1
  134. package/node_modules/pi-mcp-adapter/dist/jev-contracts.d.ts +0 -77
  135. package/node_modules/pi-mcp-adapter/dist/jev-contracts.js +0 -2
  136. package/node_modules/pi-mcp-adapter/dist/jev-contracts.js.map +0 -1
  137. package/node_modules/pi-mcp-adapter/dist/jev-key-store.d.ts +0 -51
  138. package/node_modules/pi-mcp-adapter/dist/jev-key-store.js +0 -205
  139. package/node_modules/pi-mcp-adapter/dist/jev-key-store.js.map +0 -1
  140. package/node_modules/pi-mcp-adapter/dist/json-schema-validator.d.ts +0 -2
  141. package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js +0 -68
  142. package/node_modules/pi-mcp-adapter/dist/json-schema-validator.js.map +0 -1
  143. package/node_modules/pi-mcp-adapter/dist/lifecycle.d.ts +0 -56
  144. package/node_modules/pi-mcp-adapter/dist/lifecycle.js +0 -410
  145. package/node_modules/pi-mcp-adapter/dist/lifecycle.js.map +0 -1
  146. package/node_modules/pi-mcp-adapter/dist/logger.d.ts +0 -51
  147. package/node_modules/pi-mcp-adapter/dist/logger.js +0 -131
  148. package/node_modules/pi-mcp-adapter/dist/logger.js.map +0 -1
  149. package/node_modules/pi-mcp-adapter/dist/mcp-auth-fetch.d.ts +0 -26
  150. package/node_modules/pi-mcp-adapter/dist/mcp-auth-fetch.js +0 -103
  151. package/node_modules/pi-mcp-adapter/dist/mcp-auth-fetch.js.map +0 -1
  152. package/node_modules/pi-mcp-adapter/dist/mcp-auth-flow.d.ts +0 -118
  153. package/node_modules/pi-mcp-adapter/dist/mcp-auth-flow.js +0 -1097
  154. package/node_modules/pi-mcp-adapter/dist/mcp-auth-flow.js.map +0 -1
  155. package/node_modules/pi-mcp-adapter/dist/mcp-auth.d.ts +0 -170
  156. package/node_modules/pi-mcp-adapter/dist/mcp-auth.js +0 -1142
  157. package/node_modules/pi-mcp-adapter/dist/mcp-auth.js.map +0 -1
  158. package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.d.ts +0 -24
  159. package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.js +0 -203
  160. package/node_modules/pi-mcp-adapter/dist/mcp-bearer-store.js.map +0 -1
  161. package/node_modules/pi-mcp-adapter/dist/mcp-callback-server.d.ts +0 -53
  162. package/node_modules/pi-mcp-adapter/dist/mcp-callback-server.js +0 -441
  163. package/node_modules/pi-mcp-adapter/dist/mcp-callback-server.js.map +0 -1
  164. package/node_modules/pi-mcp-adapter/dist/mcp-oauth-provider.d.ts +0 -148
  165. package/node_modules/pi-mcp-adapter/dist/mcp-oauth-provider.js +0 -689
  166. package/node_modules/pi-mcp-adapter/dist/mcp-oauth-provider.js.map +0 -1
  167. package/node_modules/pi-mcp-adapter/dist/mcp-probe.d.ts +0 -6
  168. package/node_modules/pi-mcp-adapter/dist/mcp-probe.js +0 -166
  169. package/node_modules/pi-mcp-adapter/dist/mcp-probe.js.map +0 -1
  170. package/node_modules/pi-mcp-adapter/dist/mcp-tasks.d.ts +0 -102
  171. package/node_modules/pi-mcp-adapter/dist/mcp-tasks.js +0 -369
  172. package/node_modules/pi-mcp-adapter/dist/mcp-tasks.js.map +0 -1
  173. package/node_modules/pi-mcp-adapter/dist/mcp-trace.d.ts +0 -95
  174. package/node_modules/pi-mcp-adapter/dist/mcp-trace.js +0 -242
  175. package/node_modules/pi-mcp-adapter/dist/mcp-trace.js.map +0 -1
  176. package/node_modules/pi-mcp-adapter/dist/metadata-cache.d.ts +0 -19
  177. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js +0 -301
  178. package/node_modules/pi-mcp-adapter/dist/metadata-cache.js.map +0 -1
  179. package/node_modules/pi-mcp-adapter/dist/npx-resolver.d.ts +0 -6
  180. package/node_modules/pi-mcp-adapter/dist/npx-resolver.js +0 -505
  181. package/node_modules/pi-mcp-adapter/dist/npx-resolver.js.map +0 -1
  182. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.d.ts +0 -2
  183. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js +0 -144
  184. package/node_modules/pi-mcp-adapter/dist/package-mcp-loader.js.map +0 -1
  185. package/node_modules/pi-mcp-adapter/dist/request-headers-command.d.ts +0 -10
  186. package/node_modules/pi-mcp-adapter/dist/request-headers-command.js +0 -312
  187. package/node_modules/pi-mcp-adapter/dist/request-headers-command.js.map +0 -1
  188. package/node_modules/pi-mcp-adapter/dist/resource-tools.d.ts +0 -1
  189. package/node_modules/pi-mcp-adapter/dist/resource-tools.js +0 -15
  190. package/node_modules/pi-mcp-adapter/dist/resource-tools.js.map +0 -1
  191. package/node_modules/pi-mcp-adapter/dist/runtime-owner.d.ts +0 -13
  192. package/node_modules/pi-mcp-adapter/dist/runtime-owner.js +0 -97
  193. package/node_modules/pi-mcp-adapter/dist/runtime-owner.js.map +0 -1
  194. package/node_modules/pi-mcp-adapter/dist/sampling-handler.d.ts +0 -17
  195. package/node_modules/pi-mcp-adapter/dist/sampling-handler.js +0 -203
  196. package/node_modules/pi-mcp-adapter/dist/sampling-handler.js.map +0 -1
  197. package/node_modules/pi-mcp-adapter/dist/secure-keyring.d.ts +0 -11
  198. package/node_modules/pi-mcp-adapter/dist/secure-keyring.js +0 -172
  199. package/node_modules/pi-mcp-adapter/dist/secure-keyring.js.map +0 -1
  200. package/node_modules/pi-mcp-adapter/dist/server-manager.d.ts +0 -157
  201. package/node_modules/pi-mcp-adapter/dist/server-manager.js +0 -1745
  202. package/node_modules/pi-mcp-adapter/dist/server-manager.js.map +0 -1
  203. package/node_modules/pi-mcp-adapter/dist/session-approvals.d.ts +0 -34
  204. package/node_modules/pi-mcp-adapter/dist/session-approvals.js +0 -140
  205. package/node_modules/pi-mcp-adapter/dist/session-approvals.js.map +0 -1
  206. package/node_modules/pi-mcp-adapter/dist/session-recovery.d.ts +0 -26
  207. package/node_modules/pi-mcp-adapter/dist/session-recovery.js +0 -142
  208. package/node_modules/pi-mcp-adapter/dist/session-recovery.js.map +0 -1
  209. package/node_modules/pi-mcp-adapter/dist/state.d.ts +0 -73
  210. package/node_modules/pi-mcp-adapter/dist/state.js +0 -2
  211. package/node_modules/pi-mcp-adapter/dist/state.js.map +0 -1
  212. package/node_modules/pi-mcp-adapter/dist/types.d.ts +0 -642
  213. package/node_modules/pi-mcp-adapter/dist/types.js +0 -331
  214. package/node_modules/pi-mcp-adapter/dist/types.js.map +0 -1
  215. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.d.ts +0 -6
  216. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js +0 -37
  217. package/node_modules/pi-mcp-adapter/dist/ui-app-bridge-helpers.js.map +0 -1
  218. package/node_modules/pi-mcp-adapter/dist/ui-resource-handler.d.ts +0 -17
  219. package/node_modules/pi-mcp-adapter/dist/ui-resource-handler.js +0 -219
  220. package/node_modules/pi-mcp-adapter/dist/ui-resource-handler.js.map +0 -1
  221. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.d.ts +0 -104
  222. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js +0 -59
  223. package/node_modules/pi-mcp-adapter/dist/ui-stream-types.js.map +0 -1
  224. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.d.ts +0 -4
  225. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js +0 -27
  226. package/node_modules/pi-mcp-adapter/dist/ui-tool-visibility.js.map +0 -1
  227. package/node_modules/pi-mcp-adapter/dist/unix-socket-transport.d.ts +0 -15
  228. package/node_modules/pi-mcp-adapter/dist/unix-socket-transport.js +0 -85
  229. package/node_modules/pi-mcp-adapter/dist/unix-socket-transport.js.map +0 -1
  230. package/node_modules/pi-mcp-adapter/dist/utils.d.ts +0 -41
  231. package/node_modules/pi-mcp-adapter/dist/utils.js +0 -417
  232. package/node_modules/pi-mcp-adapter/dist/utils.js.map +0 -1
  233. package/node_modules/pi-mcp-adapter/elicitation-handler.ts +0 -358
  234. package/node_modules/pi-mcp-adapter/error-signal.ts +0 -32
  235. package/node_modules/pi-mcp-adapter/errors.ts +0 -364
  236. package/node_modules/pi-mcp-adapter/examples/jev-accessibility-loop.mjs +0 -85
  237. package/node_modules/pi-mcp-adapter/examples/jev-semantic-filter.mjs +0 -34
  238. package/node_modules/pi-mcp-adapter/failure-backoff.ts +0 -23
  239. package/node_modules/pi-mcp-adapter/glimpse-ui.ts +0 -80
  240. package/node_modules/pi-mcp-adapter/host-html-template.ts +0 -515
  241. package/node_modules/pi-mcp-adapter/http-ca.ts +0 -84
  242. package/node_modules/pi-mcp-adapter/index.ts +0 -2106
  243. package/node_modules/pi-mcp-adapter/init.ts +0 -721
  244. package/node_modules/pi-mcp-adapter/jev-client.ts +0 -300
  245. package/node_modules/pi-mcp-adapter/jev-contracts.ts +0 -53
  246. package/node_modules/pi-mcp-adapter/jev-key-store.ts +0 -192
  247. package/node_modules/pi-mcp-adapter/json-schema-validator.ts +0 -83
  248. package/node_modules/pi-mcp-adapter/lazy-loader.ts +0 -7
  249. package/node_modules/pi-mcp-adapter/lifecycle.ts +0 -457
  250. package/node_modules/pi-mcp-adapter/logger.ts +0 -169
  251. package/node_modules/pi-mcp-adapter/mcp-auth-fetch.ts +0 -113
  252. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +0 -1296
  253. package/node_modules/pi-mcp-adapter/mcp-auth.ts +0 -1287
  254. package/node_modules/pi-mcp-adapter/mcp-bearer-store.ts +0 -250
  255. package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +0 -534
  256. package/node_modules/pi-mcp-adapter/mcp-code.ts +0 -495
  257. package/node_modules/pi-mcp-adapter/mcp-install.ts +0 -60
  258. package/node_modules/pi-mcp-adapter/mcp-keyring-helper.cjs +0 -89
  259. package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +0 -819
  260. package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +0 -511
  261. package/node_modules/pi-mcp-adapter/mcp-panel-theme.ts +0 -104
  262. package/node_modules/pi-mcp-adapter/mcp-panel.ts +0 -1099
  263. package/node_modules/pi-mcp-adapter/mcp-probe.ts +0 -201
  264. package/node_modules/pi-mcp-adapter/mcp-references.ts +0 -373
  265. package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +0 -137
  266. package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +0 -747
  267. package/node_modules/pi-mcp-adapter/mcp-status.ts +0 -105
  268. package/node_modules/pi-mcp-adapter/mcp-tasks.ts +0 -467
  269. package/node_modules/pi-mcp-adapter/mcp-trace.ts +0 -306
  270. package/node_modules/pi-mcp-adapter/metadata-cache.ts +0 -362
  271. package/node_modules/pi-mcp-adapter/namespace-tools.ts +0 -334
  272. package/node_modules/pi-mcp-adapter/npx-resolver.ts +0 -543
  273. package/node_modules/pi-mcp-adapter/oauth-handler.ts +0 -30
  274. package/node_modules/pi-mcp-adapter/oauth.ts +0 -52
  275. package/node_modules/pi-mcp-adapter/onboarding-state.ts +0 -76
  276. package/node_modules/pi-mcp-adapter/package-mcp-loader.ts +0 -156
  277. package/node_modules/pi-mcp-adapter/package.json +0 -219
  278. package/node_modules/pi-mcp-adapter/panel-keys.ts +0 -53
  279. package/node_modules/pi-mcp-adapter/prompts.ts +0 -385
  280. package/node_modules/pi-mcp-adapter/proxy-modes.ts +0 -1735
  281. package/node_modules/pi-mcp-adapter/request-headers-command.ts +0 -333
  282. package/node_modules/pi-mcp-adapter/resource-tools.ts +0 -17
  283. package/node_modules/pi-mcp-adapter/runtime-owner.ts +0 -106
  284. package/node_modules/pi-mcp-adapter/sampling-handler.ts +0 -261
  285. package/node_modules/pi-mcp-adapter/sandbox-proxy-template.ts +0 -144
  286. package/node_modules/pi-mcp-adapter/search-ranking.ts +0 -309
  287. package/node_modules/pi-mcp-adapter/secure-keyring.ts +0 -170
  288. package/node_modules/pi-mcp-adapter/semantic-search.ts +0 -186
  289. package/node_modules/pi-mcp-adapter/server-manager.ts +0 -2088
  290. package/node_modules/pi-mcp-adapter/session-approvals.ts +0 -201
  291. package/node_modules/pi-mcp-adapter/session-recovery.ts +0 -158
  292. package/node_modules/pi-mcp-adapter/skills/mcp-scripting/SKILL.md +0 -49
  293. package/node_modules/pi-mcp-adapter/state.ts +0 -71
  294. package/node_modules/pi-mcp-adapter/tool-approval.ts +0 -205
  295. package/node_modules/pi-mcp-adapter/tool-metadata.ts +0 -302
  296. package/node_modules/pi-mcp-adapter/tool-registrar.ts +0 -255
  297. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +0 -573
  298. package/node_modules/pi-mcp-adapter/ts-shape.ts +0 -149
  299. package/node_modules/pi-mcp-adapter/types.ts +0 -1120
  300. package/node_modules/pi-mcp-adapter/ui-app-bridge-helpers.ts +0 -40
  301. package/node_modules/pi-mcp-adapter/ui-resource-handler.ts +0 -266
  302. package/node_modules/pi-mcp-adapter/ui-server.ts +0 -993
  303. package/node_modules/pi-mcp-adapter/ui-session.ts +0 -624
  304. package/node_modules/pi-mcp-adapter/ui-stream-types.ts +0 -89
  305. package/node_modules/pi-mcp-adapter/ui-tool-visibility.ts +0 -25
  306. package/node_modules/pi-mcp-adapter/unix-socket-transport.ts +0 -85
  307. package/node_modules/pi-mcp-adapter/utils.ts +0 -464
@@ -16,11 +16,6 @@ interface WebSearchConfig {
16
16
  exaBaseUrl?: unknown;
17
17
  }
18
18
 
19
- interface ExaAnswerResponse {
20
- answer?: string;
21
- citations?: Array<{ url?: string; title?: string; text?: string; publishedDate?: string }>;
22
- }
23
-
24
19
  interface ExaSearchResponse {
25
20
  results?: Array<{
26
21
  title?: string;
@@ -146,6 +141,16 @@ function normalizeHighlights(value: unknown): string[] {
146
141
  return value.filter((item): item is string => typeof item === "string" && item.trim().length > 0);
147
142
  }
148
143
 
144
+ function fallbackSourceLabel(url: string | undefined, index: number): string {
145
+ try {
146
+ const hostname = url ? new URL(url).hostname : "";
147
+ if (hostname) return hostname;
148
+ } catch {
149
+ // Invalid URLs use the generic label.
150
+ }
151
+ return `Source ${index + 1}`;
152
+ }
153
+
149
154
  function buildAnswerFromSearchResults(results: ExaSearchResponse["results"]): string {
150
155
  if (!results?.length) return "";
151
156
  const parts: string[] = [];
@@ -157,20 +162,20 @@ function buildAnswerFromSearchResults(results: ExaSearchResponse["results"]): st
157
162
  ? highlights.join(" ")
158
163
  : typeof item.text === "string" ? item.text.trim().slice(0, 1000) : "";
159
164
  if (!content) continue;
160
- const sourceTitle = item.title || `Source ${i + 1}`;
165
+ const sourceTitle = item.title || fallbackSourceLabel(item.url, i);
161
166
  parts.push(`${content}\nSource: ${sourceTitle} (${item.url})`);
162
167
  }
163
168
  return parts.join("\n\n");
164
169
  }
165
170
 
166
- function mapResults(results: ExaSearchResponse["results"] | ExaAnswerResponse["citations"]): SearchResponse["results"] {
171
+ function mapResults(results: ExaSearchResponse["results"]): SearchResponse["results"] {
167
172
  if (!Array.isArray(results)) return [];
168
173
  const mapped: SearchResponse["results"] = [];
169
174
  for (let i = 0; i < results.length; i++) {
170
175
  const item = results[i];
171
176
  if (!item?.url) continue;
172
177
  mapped.push({
173
- title: item.title || `Source ${i + 1}`,
178
+ title: item.title || fallbackSourceLabel(item.url, i),
174
179
  url: item.url,
175
180
  snippet: "",
176
181
  });
@@ -180,15 +185,9 @@ function mapResults(results: ExaSearchResponse["results"] | ExaAnswerResponse["c
180
185
 
181
186
  function mapInlineContent(results: ExaSearchResponse["results"]): ExtractedContent[] {
182
187
  if (!results?.length) return [];
183
- return results
184
- .filter((r): r is NonNullable<ExaSearchResponse["results"]>[number] & { url: string; text: string } =>
185
- !!r?.url && typeof r.text === "string" && r.text.length > 0)
186
- .map(r => ({
187
- url: r.url,
188
- title: r.title || "",
189
- content: r.text,
190
- error: null,
191
- }));
188
+ return results.flatMap((r, i) => r?.url && typeof r.text === "string" && r.text.length > 0
189
+ ? [{ url: r.url, title: r.title || fallbackSourceLabel(r.url, i), content: r.text, error: null }]
190
+ : []);
192
191
  }
193
192
 
194
193
  function toSearchResponse(
@@ -318,21 +317,16 @@ function buildAnswerFromMcpResults(results: McpParsedResult[]): string {
318
317
  const result = results[i];
319
318
  const snippet = result.content.replace(/\s+/g, " ").trim().slice(0, 500);
320
319
  if (!snippet) continue;
321
- const sourceTitle = result.title || `Source ${i + 1}`;
320
+ const sourceTitle = result.title || fallbackSourceLabel(result.url, i);
322
321
  parts.push(`${snippet}\nSource: ${sourceTitle} (${result.url})`);
323
322
  }
324
323
  return parts.join("\n\n");
325
324
  }
326
325
 
327
326
  function mapMcpInlineContent(results: McpParsedResult[]): ExtractedContent[] {
328
- return results
329
- .filter(result => result.content.length > 0)
330
- .map(result => ({
331
- url: result.url,
332
- title: result.title,
333
- content: result.content,
334
- error: null,
335
- }));
327
+ return results.flatMap((result, i) => result.content.length > 0
328
+ ? [{ url: result.url, title: result.title || fallbackSourceLabel(result.url, i), content: result.content, error: null }]
329
+ : []);
336
330
  }
337
331
 
338
332
  function buildMcpQuery(query: string, options: ExaSearchOptions): string {
@@ -458,35 +452,9 @@ export async function searchWithExa(query: string, options: ExaSearchOptions = {
458
452
  }
459
453
 
460
454
  const apiBaseUrl = getApiBaseUrl();
461
- const useSearch = options.includeContent
462
- || !!options.recencyFilter
463
- || !!options.domainFilter?.length
464
- || !!(options.numResults && options.numResults !== 5);
465
-
466
455
  const activityId = activityMonitor.logStart({ type: "api", query });
467
456
 
468
457
  try {
469
- if (!useSearch) {
470
- const response = await fetchWithCredentialRedirects(`${apiBaseUrl}/answer`, {
471
- method: "POST",
472
- headers: exaApiHeaders(apiKey),
473
- body: JSON.stringify({ query }),
474
- signal: requestSignal(options.signal),
475
- }, ["x-api-key"]);
476
-
477
- if (!response.ok) {
478
- const errorText = redactCredential(await response.text(), apiKey);
479
- throw new Error(`Exa API error ${response.status}: ${errorText.slice(0, 300)}`);
480
- }
481
-
482
- const data = await response.json() as ExaAnswerResponse;
483
- activityMonitor.logComplete(activityId, response.status);
484
- return {
485
- answer: data.answer || "",
486
- results: mapResults(data.citations),
487
- };
488
- }
489
-
490
458
  const response = await fetchWithCredentialRedirects(`${apiBaseUrl}/search`, {
491
459
  method: "POST",
492
460
  headers: exaApiHeaders(apiKey),
@@ -173,13 +173,14 @@ const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
173
173
  async function fetchAuthenticatedRemoteUrl(
174
174
  url: string,
175
175
  init: RequestInit,
176
- validationOptions: { ssrf: SsrfConfig; domainPolicy: DomainPolicy; lookup?: Lookup },
176
+ validationOptions: { ssrf: SsrfConfig; domainPolicy: DomainPolicy; lookup?: Lookup; proxy?: string },
177
177
  profile: AuthFetchProfile,
178
178
  ): Promise<Response> {
179
179
  let current = await validateRemoteUrl(url, {
180
180
  allowRanges: validationOptions.ssrf.allowRanges,
181
181
  trustEnvProxy: validationOptions.ssrf.trustEnvProxy,
182
182
  domainPolicy: validationOptions.domainPolicy,
183
+ proxy: validationOptions.proxy,
183
184
  ...(validationOptions.lookup ? { lookup: validationOptions.lookup } : {}),
184
185
  });
185
186
  let requestInit = init;
@@ -196,6 +197,7 @@ async function fetchAuthenticatedRemoteUrl(
196
197
  allowRanges: validationOptions.ssrf.allowRanges,
197
198
  trustEnvProxy: validationOptions.ssrf.trustEnvProxy,
198
199
  domainPolicy: validationOptions.domainPolicy,
200
+ proxy: validationOptions.proxy,
199
201
  ...(validationOptions.lookup ? { lookup: validationOptions.lookup } : {}),
200
202
  });
201
203
  authFetchRedirectGuard(profile, from, current);
@@ -287,6 +289,21 @@ function notFoundGuidance(result: ExtractedContent, toolNames?: RegisteredToolNa
287
289
  return lines.join("\n");
288
290
  }
289
291
 
292
+
293
+ /** Fallback-list hint for the keyless Jina Reader. Returns null when Jina
294
+ * already ran for this fetch, and otherwise names only the config change still
295
+ * missing, so users keep their existing or default provider order. */
296
+ function jinaReaderGuidance(routing: FetchRouting, providerOrder: FetchProvider[], needsRemoteOptIn: boolean): string | null {
297
+ if (providerOrder.includes("jina")) return null;
298
+ const privacy = "target URLs are fetched through Jina's infrastructure";
299
+ const optInCaveat = "this also allows the other hosted providers in your fetch provider order";
300
+ if (routing.providers.includes("jina")) {
301
+ return ` • Enable the keyless Jina Reader fallback: set fetchRouting.allowRemoteHostedProviders to true in ${WEB_SEARCH_CONFIG_PATH} (Jina is already in your fetch provider order; ${optInCaveat}; ${privacy})`;
302
+ }
303
+ return needsRemoteOptIn
304
+ ? ` • Enable the keyless Jina Reader fallback: add "jina" to your existing fetchRouting.providers and set fetchRouting.allowRemoteHostedProviders to true in ${WEB_SEARCH_CONFIG_PATH} (${optInCaveat}; ${privacy})`
305
+ : ` • Enable the keyless Jina Reader fallback: add "jina" to your existing fetchRouting.providers in ${WEB_SEARCH_CONFIG_PATH} (${privacy})`;
306
+ }
290
307
  function abortedResult(url: string): ExtractedContent {
291
308
  return { url, title: "", content: "", error: "Aborted" };
292
309
  }
@@ -527,6 +544,7 @@ export async function extractContent(
527
544
  allowRanges: ssrf.allowRanges,
528
545
  trustEnvProxy: ssrf.trustEnvProxy,
529
546
  domainPolicy,
547
+ proxy: options?.proxy,
530
548
  ...(options?.lookup ? { lookup: options.lookup } : {}),
531
549
  });
532
550
  } catch (err) {
@@ -1020,6 +1038,7 @@ export async function extractContent(
1020
1038
  }
1021
1039
 
1022
1040
  const searchToolName = options?.toolNames?.webSearch;
1041
+ const jinaHint = jinaReaderGuidance(fetchRouting, providerOrder, Boolean(remoteUrl) && !fetchRouting.allowRemoteHostedProviders);
1023
1042
  const guidance = [
1024
1043
  finalHttpResult?.error ?? "No fetch_content provider returned content",
1025
1044
  ...(firecrawlError ? [`Firecrawl fallback failed: ${firecrawlError}`] : []),
@@ -1034,6 +1053,7 @@ export async function extractContent(
1034
1053
  ...(brightdataError ? [`Bright Data fallback failed: ${brightdataError}`] : []),
1035
1054
  "",
1036
1055
  "Fallback options:",
1056
+ ...(jinaHint ? [jinaHint] : []),
1037
1057
  ` • Set firecrawlBaseUrl in ${WEB_SEARCH_CONFIG_PATH} to a self-hosted Firecrawl instance`,
1038
1058
  ` • Set crawl4aiBaseUrl in ${WEB_SEARCH_CONFIG_PATH} to a self-hosted Crawl4AI instance`,
1039
1059
  ` • Set tinyfishApiKey in ${WEB_SEARCH_CONFIG_PATH} or TINYFISH_API_KEY`,
@@ -1050,6 +1070,18 @@ export async function extractContent(
1050
1070
  return { ...(finalHttpResult ?? { url, title: "", content: "", error: null }), error: guidance };
1051
1071
  }
1052
1072
 
1073
+ // Cloudflare interstitials served with HTTP 200. The header is authoritative for
1074
+ // any text response; the body check is HTML-only and needs both challenge-platform
1075
+ // markers so a generic "Just a moment..." page never matches.
1076
+ function isCloudflareChallenge(response: Response, text: string, isHTML: boolean): boolean {
1077
+ if (response.status !== 200) return false;
1078
+ if (response.headers.get("cf-mitigated") === "challenge") return true;
1079
+ return isHTML &&
1080
+ /<title>\s*Just a moment\.\.\.\s*<\/title>/i.test(text) &&
1081
+ text.includes("window._cf_chl_opt") &&
1082
+ text.includes("/cdn-cgi/challenge-platform/");
1083
+ }
1084
+
1053
1085
  function isLikelyJSRendered(html: string): boolean {
1054
1086
  const bodyMatch = html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
1055
1087
  if (!bodyMatch) return false;
@@ -1162,7 +1194,6 @@ async function extractViaHttp(
1162
1194
  const ssrf = loadSsrfConfig();
1163
1195
  const domainPolicy = loadFetchContentDomainPolicy();
1164
1196
  const authProfile = options?.authFetchProfile;
1165
- const trustEnvProxy = options?.proxy === undefined && ssrf.trustEnvProxy;
1166
1197
  const requestInit: ProxiedRequestInit = {
1167
1198
  signal: controller.signal,
1168
1199
  __proxy: options?.proxy,
@@ -1179,14 +1210,15 @@ async function extractViaHttp(
1179
1210
  },
1180
1211
  };
1181
1212
  const response = authProfile
1182
- ? await fetchAuthenticatedRemoteUrl(url, requestInit, { ssrf: { ...ssrf, trustEnvProxy }, domainPolicy, ...(options?.lookup ? { lookup: options.lookup } : {}) }, authProfile)
1213
+ ? await fetchAuthenticatedRemoteUrl(url, requestInit, { ssrf, domainPolicy, proxy: options?.proxy, ...(options?.lookup ? { lookup: options.lookup } : {}) }, authProfile)
1183
1214
  : await fetchRemoteUrl(
1184
1215
  url,
1185
1216
  requestInit,
1186
1217
  {
1187
1218
  allowRanges: ssrf.allowRanges,
1188
- trustEnvProxy,
1219
+ trustEnvProxy: ssrf.trustEnvProxy,
1189
1220
  domainPolicy,
1221
+ proxy: options?.proxy,
1190
1222
  ...(options?.lookup ? { lookup: options.lookup } : {}),
1191
1223
  },
1192
1224
  );
@@ -1310,6 +1342,11 @@ async function extractViaHttp(
1310
1342
  const text = await readTextResponseWithLimit(response, maxResponseSize);
1311
1343
  const isHTML = contentType.includes("text/html") || contentType.includes("application/xhtml+xml");
1312
1344
 
1345
+ if (isCloudflareChallenge(response, text, isHTML)) {
1346
+ activityMonitor.logComplete(activityId, response.status);
1347
+ return { url, title: "", content: "", error: `HTTP ${response.status}: Blocked by Cloudflare challenge page`, status: response.status };
1348
+ }
1349
+
1313
1350
  if (!isHTML) {
1314
1351
  activityMonitor.logComplete(activityId, response.status);
1315
1352
  const title = extractTextTitle(text, url);
@@ -22,6 +22,7 @@ import { isSearch1APIAvailable, searchWithSearch1API } from "./search1api.ts";
22
22
  import { isSearchinfinityAvailable, searchWithSearchinfinity } from "./searchinfinity.ts";
23
23
  import { isQueritAvailable, searchWithQuerit } from "./querit.ts";
24
24
  import { isTavilyAvailable, searchWithTavily } from "./tavily.ts";
25
+ import { isYouAvailable, searchWithYou } from "./you.ts";
25
26
  import { isFirecrawlAvailable, searchWithFirecrawl } from "./firecrawl.ts";
26
27
  import { isJinaSearchAvailable, searchWithJina } from "./jina-search.ts";
27
28
  import { isSerpdiveAvailable, searchWithSerpdive } from "./serpdive.ts";
@@ -39,12 +40,13 @@ import { isSerpApiAvailable, searchWithSerpApi } from "./serpapi.ts";
39
40
  import { isSerperAvailable, searchWithSerper } from "./serper.ts";
40
41
  import { isSerplyAvailable, searchWithSerply } from "./serply.ts";
41
42
  import { isBaizhiAvailable, searchWithBaizhi } from "./baizhi.ts";
43
+ import { isZaiAvailable, searchWithZai } from "./zai.ts";
42
44
  import { isValyuAvailable, searchWithValyu } from "./valyu.ts";
43
45
  import { isKimiSearchAvailable, searchWithKimi } from "./kimi-search.ts";
44
46
  import { isMistralAvailable, searchWithMistral } from "./mistral-search.ts";
45
47
  import { getWebSearchConfigPath } from "./utils.ts";
46
48
 
47
- export const RESOLVED_SEARCH_PROVIDERS = ["openai", "brave", "parallel", "parallel-mcp", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "firecrawl", "jina", "searxng", "duckduckgo", "perplexity", "gemini", "kimi", "exa", "serpdive", "kagi", "ollama", "anysearch", "xai", "mistral", "brightdata", "serpbase", "serpapi", "serper", "serply", "valyu", "bocha", "xcrawl", "baizhi"] as const;
49
+ export const RESOLVED_SEARCH_PROVIDERS = ["openai", "brave", "parallel", "parallel-mcp", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "you", "firecrawl", "jina", "searxng", "duckduckgo", "perplexity", "gemini", "kimi", "exa", "serpdive", "kagi", "ollama", "anysearch", "xai", "mistral", "brightdata", "serpbase", "serpapi", "serper", "serply", "valyu", "bocha", "xcrawl", "baizhi", "zai"] as const;
48
50
  export const SEARCH_PROVIDERS = ["auto", "all", ...RESOLVED_SEARCH_PROVIDERS] as const;
49
51
 
50
52
  export type ResolvedSearchProvider = typeof RESOLVED_SEARCH_PROVIDERS[number];
@@ -109,7 +111,7 @@ export interface AttributedSearchResponse extends SearchResponse {
109
111
 
110
112
  const CONFIG_PATH = getWebSearchConfigPath();
111
113
  const DEFAULT_SEARCH_MODEL = "gemini-3.6-flash";
112
- // Explicit-only providers (Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, Valyu) are deliberately absent:
114
+ // Explicit-only providers (Parallel MCP, DuckDuckGo, Kimi, AnySearch, XCrawl, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, You.com, Valyu, Baizhi, Z.ai) are deliberately absent:
113
115
  // `all` must never fan out to an opt-in or paid provider without the user asking for it.
114
116
  export const ALL_SEARCH_PROVIDERS: ResolvedSearchProvider[] = ["searxng", "openai", "exa", "brave", "parallel", "tinyfish", "search1api", "searchinfinity", "querit", "tavily", "firecrawl", "jina", "serpdive", "kagi", "ollama", "perplexity", "gemini", "bocha"];
115
117
  const VALID_ROUTING_KINDS = ["transient", "quota", "network", "invalid-response", "unsupported"] as const;
@@ -389,6 +391,7 @@ async function searchWithResolvedProvider(
389
391
  if (provider === "searchinfinity") return { ...(await searchWithSearchinfinity(query, options)), provider };
390
392
  if (provider === "querit") return { ...(await searchWithQuerit(query, options)), provider };
391
393
  if (provider === "tavily") return { ...(await searchWithTavily(query, options)), provider };
394
+ if (provider === "you") return { ...(await searchWithYou(query, options)), provider };
392
395
  if (provider === "firecrawl") return { ...(await searchWithFirecrawl(query, options)), provider };
393
396
  if (provider === "jina") return { ...(await searchWithJina(query, options)), provider };
394
397
  if (provider === "serpdive") return { ...(await searchWithSerpdive(query, options)), provider };
@@ -404,6 +407,7 @@ async function searchWithResolvedProvider(
404
407
  if (provider === "serper") return { ...(await searchWithSerper(query, options)), provider };
405
408
  if (provider === "serply") return { ...(await searchWithSerply(query, options)), provider };
406
409
  if (provider === "baizhi") return { ...(await searchWithBaizhi(query, options)), provider };
410
+ if (provider === "zai") return { ...(await searchWithZai(query, options)), provider };
407
411
  if (provider === "valyu") return { ...(await searchWithValyu(query, options)), provider };
408
412
  if (provider === "xcrawl") return { ...(await searchWithXCrawl(query, options)), provider };
409
413
  if (provider === "perplexity") return { ...(await searchWithPerplexity(query, options)), provider };
@@ -440,6 +444,7 @@ async function isResolvedProviderAvailable(provider: ResolvedSearchProvider, opt
440
444
  if (provider === "searchinfinity") return isSearchinfinityAvailable();
441
445
  if (provider === "querit") return isQueritAvailable();
442
446
  if (provider === "tavily") return isTavilyAvailable();
447
+ if (provider === "you") return isYouAvailable();
443
448
  if (provider === "firecrawl") return isFirecrawlAvailable();
444
449
  if (provider === "jina") return isJinaSearchAvailable();
445
450
  if (provider === "serpdive") return isSerpdiveAvailable();
@@ -455,6 +460,7 @@ async function isResolvedProviderAvailable(provider: ResolvedSearchProvider, opt
455
460
  if (provider === "serper") return isSerperAvailable();
456
461
  if (provider === "serply") return isSerplyAvailable();
457
462
  if (provider === "baizhi") return isBaizhiAvailable();
463
+ if (provider === "zai") return isZaiAvailable();
458
464
  if (provider === "valyu") return isValyuAvailable();
459
465
  if (provider === "xcrawl") return isXcrawlAvailable();
460
466
  if (provider === "perplexity") return isPerplexityAvailable();
@@ -496,7 +502,9 @@ export function providerLabel(provider: ResolvedSearchProvider): string {
496
502
  if (provider === "serpapi") return "SerpApi";
497
503
  if (provider === "serper") return "Serper";
498
504
  if (provider === "serply") return "Serply";
505
+ if (provider === "you") return "You.com";
499
506
  if (provider === "baizhi") return "Baizhi";
507
+ if (provider === "zai") return "Z.ai";
500
508
  if (provider === "valyu") return "Valyu";
501
509
  return provider.charAt(0).toUpperCase() + provider.slice(1);
502
510
  }
@@ -525,7 +533,7 @@ async function searchWithProviders(
525
533
  : await isResolvedProviderAvailable(provider, options),
526
534
  })))).filter((entry) => entry.available).map((entry) => entry.provider);
527
535
  if (providers.length === 0) {
528
- throw new Error("No configured search provider available for provider \"all\". Parallel MCP, DuckDuckGo, Kimi, AnySearch, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, Valyu, and XCrawl are excluded.");
536
+ throw new Error("No configured search provider available for provider \"all\". Parallel MCP, DuckDuckGo, Kimi, AnySearch, xAI, Mistral, Bright Data, SerpBase, SerpApi, Serper, Serply, You.com, Valyu, Baizhi, Z.ai, and XCrawl are excluded.");
529
537
  }
530
538
 
531
539
  const settled = await Promise.allSettled(
@@ -820,7 +828,7 @@ export async function search(query: string, options: FullSearchOptions = {}): Pr
820
828
  " 3. Set OPENAI_API_KEY, BRAVE_API_KEY, PARALLEL_API_KEY, TINYFISH_API_KEY, SEARCH1API_KEY, SEARCHINFINITY_API_KEY, QUERIT_API_KEY, TAVILY_API_KEY, FIRECRAWL_BASE_URL, JINA_API_KEY, SERPDIVE_API_KEY, KAGI_API_KEY, BOCHA_API_KEY, OLLAMA_API_KEY, SEARXNG_BASE_URL, EXA_API_KEY, PERPLEXITY_API_KEY, GEMINI_API_KEY, or CLOUDFLARE_API_KEY env vars\n" +
821
829
  " 4. Set GOOGLE_GEMINI_BASE_URL with CLOUDFLARE_API_KEY for Cloudflare AI Gateway routing\n" +
822
830
  " 5. Sign into gemini.google.com in a supported Chromium-based browser\n" +
823
- " 6. Explicitly select provider: \"anysearch\" for anonymous AnySearch, \"xcrawl\" for XCrawl, \"xai\" for Grok, \"mistral\" for Mistral Conversations web search, \"brightdata\" with brightdataSerpZone for paid Bright Data SERP, \"serpbase\", \"serpapi\", \"serper\", or \"serply\" for Google SERP, or \"valyu\" for research search"
831
+ " 6. Explicitly select provider: \"anysearch\" for anonymous AnySearch, \"xcrawl\" for XCrawl, \"xai\" for Grok, \"mistral\" for Mistral Conversations web search, \"brightdata\" with brightdataSerpZone for paid Bright Data SERP, \"serpbase\", \"serpapi\", \"serper\", or \"serply\" for Google SERP, \"you\" for You.com, \"zai\" for Z.ai GLM Coding Plan search, or \"valyu\" for research search"
824
832
  );
825
833
  }
826
834
 
@@ -55,6 +55,7 @@ import { isSearch1APIAvailable } from "./search1api.ts";
55
55
  import { isSearchinfinityAvailable } from "./searchinfinity.ts";
56
56
  import { isQueritAvailable } from "./querit.ts";
57
57
  import { isTavilyAvailable } from "./tavily.ts";
58
+ import { isYouAvailable } from "./you.ts";
58
59
  import { isFirecrawlAvailable } from "./firecrawl.ts";
59
60
  import { isJinaSearchAvailable } from "./jina-search.ts";
60
61
  import { isSerpdiveAvailable } from "./serpdive.ts";
@@ -73,10 +74,11 @@ import { isSerpApiAvailable } from "./serpapi.ts";
73
74
  import { isSerperAvailable } from "./serper.ts";
74
75
  import { isSerplyAvailable } from "./serply.ts";
75
76
  import { isBaizhiAvailable } from "./baizhi.ts";
77
+ import { isZaiAvailable } from "./zai.ts";
76
78
  import { isValyuAvailable } from "./valyu.ts";
77
79
  import { isXcrawlAvailable } from "./xcrawl.ts";
78
80
  import { buildSearchErrorPlan, type SearchErrorDetails, type SearchErrorPlan } from "./render-search-error.ts";
79
- import { findModelWithProviderRouting, loadEnabledModelPatterns, modelMatchesEnabledPatterns, splitThinkingSuffix } from "./summary-model-scope.ts";
81
+ import { findModelWithProviderRouting, isModelInScope, splitThinkingSuffix } from "./summary-model-scope.ts";
80
82
  import { registerCuratorRunLifecycle, resolveWebSearchWorkflow, type WebSearchWorkflow } from "./curator-run.ts";
81
83
  import {
82
84
  buildResearchArtifact,
@@ -86,7 +88,7 @@ import {
86
88
  type RecencyFilter,
87
89
  type ResearchArtifact,
88
90
  } from "./source-check.ts";
89
- import { registerWebToolActivation, type WebActivationTool } from "./tool-activation.ts";
91
+ import { registerWebToolActivation } from "./tool-activation.ts";
90
92
 
91
93
  // Match pi-ai's StringEnum without loading its compat barrel during registration.
92
94
  function StringEnum<T extends string[]>(values: T, options?: { description?: string; default?: T[number] }) {
@@ -157,7 +159,9 @@ interface WebSearchConfig {
157
159
  serpapiApiKey?: unknown;
158
160
  serperApiKey?: unknown;
159
161
  serplyApiKey?: unknown;
162
+ youApiKey?: unknown;
160
163
  baizhiApiKey?: unknown;
164
+ zaiApiKey?: unknown;
161
165
  tinyfishApiKey?: unknown;
162
166
  valyuApiKey?: unknown;
163
167
  xaiApiKey?: unknown;
@@ -179,6 +183,7 @@ interface WebSearchConfig {
179
183
  allowedProviders?: unknown;
180
184
  };
181
185
  tools?: Partial<Record<keyof ToolNames, { enabled?: boolean }>>;
186
+ toolActivation?: unknown;
182
187
  commands?: Partial<Record<"websearch" | "curator" | "search" | "google-account", { enabled?: boolean }>>;
183
188
  toolNames?: Partial<ToolNames>;
184
189
  shortcuts?: {
@@ -471,6 +476,7 @@ async function getProviderAvailability(ctx: ExtensionContext): Promise<ProviderA
471
476
  searchinfinity: allowedProviders.has("searchinfinity") && isSearchinfinityAvailable(),
472
477
  querit: allowedProviders.has("querit") && isQueritAvailable(),
473
478
  tavily: allowedProviders.has("tavily") && isTavilyAvailable(),
479
+ you: allowedProviders.has("you") && isYouAvailable(),
474
480
  firecrawl: allowedProviders.has("firecrawl") && isFirecrawlAvailable(),
475
481
  jina: allowedProviders.has("jina") && isJinaSearchAvailable(),
476
482
  serpdive: allowedProviders.has("serpdive") && isSerpdiveAvailable(),
@@ -493,6 +499,7 @@ async function getProviderAvailability(ctx: ExtensionContext): Promise<ProviderA
493
499
  serper: allowedProviders.has("serper") && isSerperAvailable(),
494
500
  serply: allowedProviders.has("serply") && isSerplyAvailable(),
495
501
  baizhi: allowedProviders.has("baizhi") && isBaizhiAvailable(),
502
+ zai: allowedProviders.has("zai") && isZaiAvailable(),
496
503
  valyu: allowedProviders.has("valyu") && isValyuAvailable(),
497
504
  };
498
505
  return {
@@ -1069,6 +1076,10 @@ function handleSessionChange(ctx: ExtensionContext): void {
1069
1076
  export default function (pi: ExtensionAPI) {
1070
1077
  const initConfig = loadConfigForExtensionInit();
1071
1078
  const fetchModeConfig = resolveFetchModeConfig(initConfig);
1079
+ const toolActivation = initConfig.toolActivation ?? "auto";
1080
+ if (toolActivation !== "auto" && toolActivation !== "dynamic" && toolActivation !== "eager") {
1081
+ throw new Error(`toolActivation in ${WEB_SEARCH_CONFIG_PATH} must be "auto", "dynamic", or "eager"`);
1082
+ }
1072
1083
  const allowedSearchProviders = initConfig.webSearch?.allowedProviders === undefined ? RESOLVED_SEARCH_PROVIDERS : getAllowedSearchProviders();
1073
1084
  const allEligibleProviders = allowedSearchProviders.filter(provider => ALL_SEARCH_PROVIDERS.includes(provider));
1074
1085
  const allExcludedProviders = allowedSearchProviders.filter(provider => !ALL_SEARCH_PROVIDERS.includes(provider));
@@ -1297,27 +1308,16 @@ export default function (pi: ExtensionAPI) {
1297
1308
  summaryModels.push({ value, label: value });
1298
1309
  };
1299
1310
 
1300
- let enabledModelPatterns: string[] | null = null;
1301
- let scopeLoaded = true;
1302
- try {
1303
- enabledModelPatterns = loadEnabledModelPatterns(summaryContext);
1304
- const availableModels = summaryContext.modelRegistry.getAvailable();
1305
- for (const model of availableModels) {
1306
- if (!modelMatchesEnabledPatterns(model, enabledModelPatterns)) continue;
1307
- const value = `${model.provider}/${model.id}`;
1308
- availableValues.add(value);
1309
- addModel(model.provider, model.id);
1310
- }
1311
- } catch (err) {
1312
- scopeLoaded = false;
1313
- const message = err instanceof Error ? err.message : String(err);
1314
- console.error(`Failed to load summary models: ${message}`);
1311
+ for (const model of summaryContext.modelRegistry.getAvailable()) {
1312
+ if (!isModelInScope(model, summaryContext.scopedModels)) continue;
1313
+ availableValues.add(`${model.provider}/${model.id}`);
1314
+ addModel(model.provider, model.id);
1315
1315
  }
1316
1316
 
1317
1317
  const currentModelValue = summaryContext.model
1318
1318
  ? `${summaryContext.model.provider}/${summaryContext.model.id}`
1319
1319
  : null;
1320
- if (scopeLoaded && summaryContext.model && currentModelValue && !seen.has(currentModelValue) && modelMatchesEnabledPatterns(summaryContext.model, enabledModelPatterns)) {
1320
+ if (summaryContext.model && currentModelValue && !seen.has(currentModelValue) && isModelInScope(summaryContext.model, summaryContext.scopedModels)) {
1321
1321
  addModel(summaryContext.model.provider, summaryContext.model.id);
1322
1322
  }
1323
1323
 
@@ -1352,12 +1352,12 @@ export default function (pi: ExtensionAPI) {
1352
1352
  };
1353
1353
 
1354
1354
  let defaultSummaryModel: string | null = null;
1355
- if (scopeLoaded && configuredSummaryModel.length > 0) {
1355
+ if (configuredSummaryModel.length > 0) {
1356
1356
  defaultSummaryModel = availableValues.has(configuredSummaryModel)
1357
1357
  ? configuredSummaryModel
1358
1358
  : resolveAvailableModelValue(configuredSummaryModel);
1359
1359
  }
1360
- if (scopeLoaded && !defaultSummaryModel) {
1360
+ if (!defaultSummaryModel) {
1361
1361
  for (const preferred of preferredDefaults) {
1362
1362
  const model = findModelWithProviderRouting(summaryContext.modelRegistry, preferred.provider, preferred.id);
1363
1363
  const value = model ? `${model.provider}/${model.id}` : null;
@@ -1913,8 +1913,7 @@ export default function (pi: ExtensionAPI) {
1913
1913
  model: ctx.model,
1914
1914
  modelRegistry: ctx.modelRegistry,
1915
1915
  sessionManager: ctx.sessionManager,
1916
- cwd: ctx.cwd,
1917
- isProjectTrusted: () => ctx.isProjectTrusted(),
1916
+ scopedModels: ctx.scopedModels,
1918
1917
  };
1919
1918
  const summaryModelChoices = await loadSummaryModelChoices(summaryContext);
1920
1919
 
@@ -2143,8 +2142,7 @@ export default function (pi: ExtensionAPI) {
2143
2142
  model: ctx.model,
2144
2143
  modelRegistry: ctx.modelRegistry,
2145
2144
  sessionManager: ctx.sessionManager,
2146
- cwd: ctx.cwd,
2147
- isProjectTrusted: () => ctx.isProjectTrusted(),
2145
+ scopedModels: ctx.scopedModels,
2148
2146
  };
2149
2147
  const summaryModelChoices = await loadSummaryModelChoices(summaryContext);
2150
2148
  const generated = await generateSummaryDraft(
@@ -2185,13 +2183,11 @@ export default function (pi: ExtensionAPI) {
2185
2183
  }
2186
2184
  if (queryList.length === 1) {
2187
2185
  const q = queryList[0];
2188
- const display = q.length > 60 ? q.slice(0, 57) + "..." : q;
2189
- return new Text(theme.fg("toolTitle", theme.bold("search ")) + theme.fg("accent", `"${display}"`), 0, 0);
2186
+ return new Text(theme.fg("toolTitle", theme.bold("search ")) + theme.fg("accent", `"${q}"`), 0, 0);
2190
2187
  }
2191
2188
  const lines = [theme.fg("toolTitle", theme.bold("search ")) + theme.fg("accent", `${queryList.length} queries`)];
2192
2189
  for (const q of queryList.slice(0, 5)) {
2193
- const display = q.length > 50 ? q.slice(0, 47) + "..." : q;
2194
- lines.push(theme.fg("muted", ` "${display}"`));
2190
+ lines.push(theme.fg("muted", ` "${q}"`));
2195
2191
  }
2196
2192
  if (queryList.length > 5) {
2197
2193
  lines.push(theme.fg("muted", ` ... and ${queryList.length - 5} more`));
@@ -2759,13 +2755,11 @@ export default function (pi: ExtensionAPI) {
2759
2755
  }
2760
2756
  const lines: string[] = [];
2761
2757
  if (urlList.length === 1) {
2762
- const display = urlList[0].length > 60 ? urlList[0].slice(0, 57) + "..." : urlList[0];
2763
- lines.push(theme.fg("toolTitle", theme.bold("fetch ")) + theme.fg("accent", display));
2758
+ lines.push(theme.fg("toolTitle", theme.bold("fetch ")) + theme.fg("accent", urlList[0]));
2764
2759
  } else {
2765
2760
  lines.push(theme.fg("toolTitle", theme.bold("fetch ")) + theme.fg("accent", `${urlList.length} URLs`));
2766
2761
  for (const u of urlList.slice(0, 5)) {
2767
- const display = u.length > 60 ? u.slice(0, 57) + "..." : u;
2768
- lines.push(theme.fg("muted", " " + display));
2762
+ lines.push(theme.fg("muted", " " + u));
2769
2763
  }
2770
2764
  if (urlList.length > 5) {
2771
2765
  lines.push(theme.fg("muted", ` ... and ${urlList.length - 5} more`));
@@ -3264,13 +3258,12 @@ export default function (pi: ExtensionAPI) {
3264
3258
  });
3265
3259
  }
3266
3260
 
3267
- const activationTools: WebActivationTool[] = [
3261
+ if (toolActivation !== "eager") registerWebToolActivation(pi, [
3268
3262
  ...(webSearchEnabled ? [{ name: toolNames.webSearch, capability: "search" as const }] : []),
3269
3263
  ...(sourceCheckEnabled ? [{ name: toolNames.sourceCheck, capability: "source-check" as const }] : []),
3270
3264
  ...(fetchContentEnabled ? [{ name: toolNames.fetchContent, capability: "fetch" as const }] : []),
3271
3265
  ...(getSearchContentEnabled ? [{ name: toolNames.getSearchContent, capability: "stored-content" as const }] : []),
3272
- ];
3273
- registerWebToolActivation(pi, activationTools);
3266
+ ], toolActivation);
3274
3267
 
3275
3268
  if (isCommandEnabled(initConfig, "websearch")) pi.registerCommand("websearch", {
3276
3269
  description: "Open web search curator",
@@ -3308,8 +3301,7 @@ export default function (pi: ExtensionAPI) {
3308
3301
  model: ctx.model,
3309
3302
  modelRegistry: ctx.modelRegistry,
3310
3303
  sessionManager: ctx.sessionManager,
3311
- cwd: ctx.cwd,
3312
- isProjectTrusted: () => ctx.isProjectTrusted(),
3304
+ scopedModels: ctx.scopedModels,
3313
3305
  };
3314
3306
  const summaryModelChoices = await loadSummaryModelChoices(summaryContext);
3315
3307