@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
@@ -1,6 +1,6 @@
1
1
  import { chmodSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { DEFAULT_BACKEND, TYPESAFE_KEY_ENV, backendConfig, usesTypesafeKey } from "./backends.js";
3
+ import { DEFAULT_BACKEND, TYPESAFE_KEY_ENV, resolveBackend, usesTypesafeKey } from "./backends.js";
4
4
  import { credentialsPath, keySituation, keySourceLabel, piTypesafeDir } from "./credentials.js";
5
5
  import { TypeSafeIntegrationError } from "./errors.js";
6
6
  const AUTH_VERSION = 1;
@@ -50,7 +50,11 @@ function writeState(path, state) {
50
50
  catch { /* best-effort cleanup only */ }
51
51
  }
52
52
  }
53
- /** What the key situation, the last outcome, and the clock add up to for one backend. Never throws. */
53
+ /**
54
+ * What the key situation, the last outcome, and the clock add up to for a valid backend; it never throws for one. An
55
+ * invalid backend throws the same `configuration` error as resolveBackend(), so validate a user-supplied endpoint
56
+ * with resolveBackend() first.
57
+ */
54
58
  export function authState(options = {}) {
55
59
  const path = options.path ?? authStatePath();
56
60
  const backend = options.backend ?? DEFAULT_BACKEND;
@@ -99,7 +103,7 @@ export function clearAuthState() {
99
103
  * state instead of reporting "enabled".
100
104
  */
101
105
  export function describeAuth(state = authState()) {
102
- const config = backendConfig(state.backend ?? DEFAULT_BACKEND);
106
+ const config = resolveBackend(state.backend);
103
107
  const label = `${config.label} key`;
104
108
  const since = state.lastFailure ? ` Last failure: ${state.lastFailure.message}${state.lastFailure.at ? ` (${state.lastFailure.at})` : ""}` : "";
105
109
  if (state.kind === "missing") {
@@ -1,6 +1,6 @@
1
- export type TypeSafeBackend = "typesafe" | "openrouter";
1
+ export type TypeSafeBackend = "typesafe" | "openrouter" | "commandcode";
2
2
  export interface BackendConfig {
3
- /** Human name for status lines: "TypeSafe", "OpenRouter". */
3
+ /** Human name for status lines: "TypeSafe", "OpenRouter", "Command Code". */
4
4
  label: string;
5
5
  host: string;
6
6
  /** The environment variable that carries this backend's key. Absent means the TypeSafe key resolution applies. */
@@ -16,11 +16,32 @@ export interface BackendConfig {
16
16
  /** Whether the model list checks the key. A public list accepts any key, so it proves nothing. Absent means it does. */
17
17
  modelsVerifyKey?: boolean;
18
18
  }
19
+ /** A caller-supplied endpoint that serves the Jev decisions protocol. Passed per call; never added to the registry. */
20
+ export interface BackendEndpoint extends BackendConfig {
21
+ /** Required. The environment variable with this endpoint's key. Must not be TYPESAFE_API_KEY. */
22
+ readonly keyEnv: string;
23
+ /** Model sent when the caller names none. Without it, `model` must be passed to createTypeSafe. */
24
+ readonly defaultModel?: string;
25
+ }
26
+ /** A registry name or a caller-supplied endpoint. */
27
+ export type BackendSpec = TypeSafeBackend | BackendEndpoint;
28
+ /** A backend resolved and validated: what the client will actually use. */
29
+ export interface ResolvedBackend extends BackendConfig {
30
+ /** Registry name, absent for a caller-supplied endpoint. */
31
+ readonly name?: TypeSafeBackend;
32
+ /** Origin only: scheme, host, and port. */
33
+ readonly host: string;
34
+ readonly keyEnv: string;
35
+ /** The model id sent when the caller names none, already in the backend's form. Absent when the endpoint names none. */
36
+ readonly defaultModel?: string;
37
+ /** Always explicit after resolution. */
38
+ readonly modelsVerifyKey: boolean;
39
+ }
19
40
  /** The backend every key and auth function assumes when none is named. */
20
41
  export declare const DEFAULT_BACKEND: TypeSafeBackend;
21
42
  /** The environment variable and login store that the default backend reads. */
22
43
  export declare const TYPESAFE_KEY_ENV = "TYPESAFE_API_KEY";
23
- /** Registry of known judgment backends. Extendable by callers. */
44
+ /** Registry of known judgment backends. Callers pass a `BackendEndpoint` for a host this registry does not name. */
24
45
  export declare const DECISIONS_BACKENDS: Record<TypeSafeBackend, BackendConfig>;
25
46
  /** The registry entry for a backend name; a `configuration` error for a name the registry does not know. */
26
47
  export declare function backendConfig(name: TypeSafeBackend): BackendConfig;
@@ -39,3 +60,12 @@ export declare function defaultModelId(backend: TypeSafeBackend): string;
39
60
  * its own environment variable. Only the TypeSafe backend has a login store; every other backend is environment-only.
40
61
  */
41
62
  export declare function usesTypesafeKey(backend: BackendConfig): boolean;
63
+ /**
64
+ * Resolve a registry name or a caller-supplied endpoint into the validated form the client uses. A name resolves to
65
+ * its registry entry unchanged; an endpoint is validated field by field and returned as a fresh object whose `host`
66
+ * is origin-only. Messages never quote a caller value — a host can carry credentials in its user info — except the
67
+ * label, and only after it is validated. Validation runs on every call; nothing is cached.
68
+ */
69
+ export declare function resolveBackend(backend?: BackendSpec): ResolvedBackend;
70
+ /** The destination host only — scheme, host, and port, e.g. `api.commandcode.ai` — for consent text. */
71
+ export declare function backendHost(backend?: BackendSpec): string;
@@ -3,7 +3,7 @@ import { TypeSafeIntegrationError } from "./errors.js";
3
3
  export const DEFAULT_BACKEND = "typesafe";
4
4
  /** The environment variable and login store that the default backend reads. */
5
5
  export const TYPESAFE_KEY_ENV = "TYPESAFE_API_KEY";
6
- /** Registry of known judgment backends. Extendable by callers. */
6
+ /** Registry of known judgment backends. Callers pass a `BackendEndpoint` for a host this registry does not name. */
7
7
  export const DECISIONS_BACKENDS = {
8
8
  typesafe: { label: "TypeSafe", host: "https://api.typesafe.ai", keyEnv: TYPESAFE_KEY_ENV },
9
9
  openrouter: {
@@ -16,6 +16,16 @@ export const DECISIONS_BACKENDS = {
16
16
  modelsIdField: "id",
17
17
  modelsVerifyKey: false,
18
18
  },
19
+ commandcode: {
20
+ label: "Command Code",
21
+ host: "https://api.commandcode.ai",
22
+ keyEnv: "COMMANDCODE_API_KEY",
23
+ path: "/provider/v1/systemone",
24
+ modelsPath: "/provider/v1/models",
25
+ modelsField: "data",
26
+ modelsIdField: "id",
27
+ modelsVerifyKey: false,
28
+ },
19
29
  };
20
30
  /** The registry entry for a backend name; a `configuration` error for a name the registry does not know. */
21
31
  export function backendConfig(name) {
@@ -28,6 +38,7 @@ export function backendConfig(name) {
28
38
  const DEFAULT_MODEL = {
29
39
  typesafe: "jev-latest",
30
40
  openrouter: "typesafe/jev-1.13",
41
+ commandcode: "typesafe/jev",
31
42
  };
32
43
  /**
33
44
  * The model id to send for a caller's `model` on this backend. OpenRouter routes a bare Jev id under the `typesafe`
@@ -57,3 +68,86 @@ export function defaultModelId(backend) {
57
68
  export function usesTypesafeKey(backend) {
58
69
  return (backend.keyEnv ?? TYPESAFE_KEY_ENV) === TYPESAFE_KEY_ENV;
59
70
  }
71
+ const KEY_ENV_MESSAGE = "Backend keyEnv must name an environment variable: letters, digits, and underscores, not starting with a digit.";
72
+ const HOST_MESSAGE = "Backend host must be an absolute https: URL with no user info, path, query, or fragment (http: is allowed only for localhost, 127.0.0.0/8, and [::1]).";
73
+ function refuse(message) {
74
+ throw new TypeSafeIntegrationError("configuration", message);
75
+ }
76
+ /** `https://gw.example.com?` and `https://gw.example.com#` parse clean, so the raw string itself must carry neither. */
77
+ function hasRawQueryOrFragment(value) {
78
+ return value.includes("?") || value.includes("#");
79
+ }
80
+ /**
81
+ * Resolve a registry name or a caller-supplied endpoint into the validated form the client uses. A name resolves to
82
+ * its registry entry unchanged; an endpoint is validated field by field and returned as a fresh object whose `host`
83
+ * is origin-only. Messages never quote a caller value — a host can carry credentials in its user info — except the
84
+ * label, and only after it is validated. Validation runs on every call; nothing is cached.
85
+ */
86
+ export function resolveBackend(backend) {
87
+ const spec = backend === undefined ? DEFAULT_BACKEND : backend;
88
+ if (typeof spec === "string") {
89
+ const entry = backendConfig(spec);
90
+ return {
91
+ ...entry,
92
+ name: spec,
93
+ host: entry.host,
94
+ keyEnv: entry.keyEnv ?? TYPESAFE_KEY_ENV,
95
+ defaultModel: defaultModelId(spec),
96
+ modelsVerifyKey: entry.modelsVerifyKey !== false,
97
+ };
98
+ }
99
+ if (spec === null || typeof spec !== "object") {
100
+ refuse("backend must be a registry name or a backend object.");
101
+ }
102
+ const label = typeof spec.label === "string" ? spec.label.trim() : "";
103
+ if (!label || label.length > 60)
104
+ refuse("Backend label must be a nonempty string of at most 60 characters.");
105
+ let host;
106
+ if (typeof spec.host !== "string" || hasRawQueryOrFragment(spec.host))
107
+ refuse(HOST_MESSAGE);
108
+ try {
109
+ host = new URL(spec.host);
110
+ }
111
+ catch {
112
+ refuse(HOST_MESSAGE);
113
+ }
114
+ const loopback = host.hostname === "localhost" || host.hostname === "[::1]" || /^127(?:\.\d{1,3}){3}$/.test(host.hostname);
115
+ if (host.protocol !== "https:" && !(host.protocol === "http:" && loopback))
116
+ refuse(HOST_MESSAGE);
117
+ if (host.username !== "" || host.password !== "" || host.pathname !== "/" || host.search !== "" || host.hash !== "")
118
+ refuse(HOST_MESSAGE);
119
+ for (const [field, message] of [["path", 'Backend path must be a string that starts with "/".'], ["modelsPath", 'Backend modelsPath must be a string that starts with "/".']]) {
120
+ const value = spec[field];
121
+ if (value !== undefined && (typeof value !== "string" || !value.startsWith("/") || hasRawQueryOrFragment(value)))
122
+ refuse(message);
123
+ }
124
+ if (spec.modelsField !== undefined && (typeof spec.modelsField !== "string" || !spec.modelsField))
125
+ refuse("Backend modelsField must be a nonempty string.");
126
+ if (spec.modelsIdField !== undefined && (typeof spec.modelsIdField !== "string" || !spec.modelsIdField))
127
+ refuse("Backend modelsIdField must be a nonempty string.");
128
+ if (spec.modelsVerifyKey !== undefined && typeof spec.modelsVerifyKey !== "boolean")
129
+ refuse("Backend modelsVerifyKey must be a boolean.");
130
+ if (typeof spec.keyEnv !== "string" || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(spec.keyEnv))
131
+ refuse(KEY_ENV_MESSAGE);
132
+ if (spec.keyEnv.toUpperCase() === TYPESAFE_KEY_ENV) {
133
+ refuse("Backend keyEnv must not be TYPESAFE_API_KEY: the TypeSafe key is only sent to the typesafe backend. Give this endpoint its own variable.");
134
+ }
135
+ if (spec.defaultModel !== undefined && (typeof spec.defaultModel !== "string" || !spec.defaultModel.trim() || spec.defaultModel.length > 100)) {
136
+ refuse("Backend defaultModel must be a nonempty string of at most 100 characters.");
137
+ }
138
+ return {
139
+ label,
140
+ host: host.origin,
141
+ keyEnv: spec.keyEnv,
142
+ modelsVerifyKey: spec.modelsVerifyKey === true,
143
+ ...(spec.path === undefined ? {} : { path: spec.path }),
144
+ ...(spec.modelsPath === undefined ? {} : { modelsPath: spec.modelsPath }),
145
+ ...(spec.modelsField === undefined ? {} : { modelsField: spec.modelsField }),
146
+ ...(spec.modelsIdField === undefined ? {} : { modelsIdField: spec.modelsIdField }),
147
+ ...(spec.defaultModel === undefined ? {} : { defaultModel: spec.defaultModel }),
148
+ };
149
+ }
150
+ /** The destination host only — scheme, host, and port, e.g. `api.commandcode.ai` — for consent text. */
151
+ export function backendHost(backend) {
152
+ return new URL(resolveBackend(backend).host).host;
153
+ }
@@ -1,14 +1,14 @@
1
1
  import type { Fetch, Questions, SystemOneRequest, SystemOneResult } from "@typesafe-ai/sdk";
2
- import type { TypeSafeBackend } from "./backends.js";
2
+ import type { BackendSpec } from "./backends.js";
3
3
  import type { BatchEvaluation, BatchOptions } from "./batch.js";
4
4
  import type { BlockedCap, SpendCaps, UsageLedger, UsageReport } from "./usage.js";
5
- export { DECISIONS_BACKENDS, DEFAULT_BACKEND } from "./backends.js";
6
- export type { BackendConfig, TypeSafeBackend } from "./backends.js";
5
+ export { backendHost, resolveBackend, DECISIONS_BACKENDS, DEFAULT_BACKEND } from "./backends.js";
6
+ export type { BackendConfig, BackendEndpoint, BackendSpec, ResolvedBackend, TypeSafeBackend } from "./backends.js";
7
7
  export interface TypeSafeOptions {
8
8
  /** Defaults to TYPESAFE_API_KEY, then the key saved by `/typesafe login`; never returned. */
9
9
  apiKey?: string;
10
- /** Judgment backend. When omitted, routes to the default TypeSafe host. */
11
- backend?: TypeSafeBackend;
10
+ /** Judgment backend: a registry name or a caller-supplied endpoint. When omitted, routes to the default TypeSafe host. */
11
+ backend?: BackendSpec;
12
12
  /** Defaults to the backend's own default (`jev-latest`, `typesafe/jev-1.13` on OpenRouter); a bare Jev id is mapped to the backend's id form before sending. No model is inferred from submitted content. */
13
13
  model?: string;
14
14
  /** Per request. Default: 15 seconds. No automatic retries. */
@@ -1,12 +1,12 @@
1
1
  import { TypeSafeClient } from "@typesafe-ai/sdk";
2
2
  import { recordAuthFailure, recordAuthVerified } from "./auth.js";
3
- import { DEFAULT_BACKEND, TYPESAFE_KEY_ENV, backendConfig, backendModelId, defaultModelId, usesTypesafeKey } from "./backends.js";
3
+ import { TYPESAFE_KEY_ENV, backendModelId, resolveBackend, usesTypesafeKey } from "./backends.js";
4
4
  import { evaluateAll, evaluateMany } from "./batch.js";
5
5
  import { keySituation } from "./credentials.js";
6
6
  import { TypeSafeIntegrationError, safeError } from "./errors.js";
7
7
  import { DEFAULT_MAX_INPUT_BYTES, assertWithinByteLimit, prepareEvaluationRequest } from "./schema.js";
8
8
  import { DEFAULT_USD_PER_MTOK, capsFromEnvironment, estimateUsd, mergeCaps, openUsageLedger } from "./usage.js";
9
- export { DECISIONS_BACKENDS, DEFAULT_BACKEND } from "./backends.js";
9
+ export { backendHost, resolveBackend, DECISIONS_BACKENDS, DEFAULT_BACKEND } from "./backends.js";
10
10
  /** The paths the SDK appends to whatever base URL it is given. */
11
11
  const SDK_PATH = "/v1/systemone";
12
12
  const SDK_MODELS_PATH = "/v1/models";
@@ -118,13 +118,14 @@ function capsDescription(caps) {
118
118
  }
119
119
  /** A bounded, server-side TypeSafe client independent of Pi's runtime. */
120
120
  export function createTypeSafe(options = {}) {
121
+ const backend = resolveBackend(options.backend);
121
122
  let apiKey = options.apiKey?.trim();
122
- const backendName = options.backend ?? DEFAULT_BACKEND;
123
- const backend = backendConfig(backendName);
124
123
  const baseURL = backend.host;
124
+ // Only a registry backend maps ids; a caller-supplied endpoint's model is sent as the caller wrote it.
125
+ const mapModel = (model) => (backend.name === undefined ? model : backendModelId(backend.name, model));
125
126
  if (!apiKey) {
126
127
  // The same resolution that authState() and ensureApiKey() report, so the status line and the request agree.
127
- const situation = keySituation(backendName);
128
+ const situation = keySituation(options.backend);
128
129
  if (situation.kind === "unusable")
129
130
  throw new TypeSafeIntegrationError("configuration", situation.reason);
130
131
  if (situation.kind === "environment" || situation.kind === "stored")
@@ -148,10 +149,12 @@ export function createTypeSafe(options = {}) {
148
149
  const transport = backend.path !== undefined || backend.modelsPath !== undefined ? backendFetch(backend, options.fetch) : options.fetch;
149
150
  // The caller's input is validated as written, then mapped to the backend's id form; omitting it sends the backend's
150
151
  // own default, which the mapping leaves unchanged.
151
- const requested = options.model ?? defaultModelId(backendName);
152
+ const requested = options.model ?? backend.defaultModel;
153
+ if (requested === undefined)
154
+ throw new TypeSafeIntegrationError("configuration", `Backend "${backend.label}" names no defaultModel; pass model to createTypeSafe.`);
152
155
  if (typeof requested !== "string" || !requested.trim() || requested.length > 100)
153
156
  throw new TypeSafeIntegrationError("configuration", "model must be a nonempty string of at most 100 characters.");
154
- const model = backendModelId(backendName, requested);
157
+ const model = mapModel(requested);
155
158
  // Do not inherit SDK debug logging or alternate destinations from the environment.
156
159
  const client = new TypeSafeClient({
157
160
  apiKey,
@@ -187,7 +190,7 @@ export function createTypeSafe(options = {}) {
187
190
  if (!Array.isArray(models))
188
191
  throw new TypeSafeIntegrationError("response", "TypeSafe returned an unexpected model list.");
189
192
  // A backend that serves its list publicly accepts any key, so a success there proves nothing about one.
190
- if (backend.modelsVerifyKey !== false && !verificationRecorded) {
193
+ if (backend.modelsVerifyKey && !verificationRecorded) {
191
194
  verificationRecorded = true;
192
195
  recordAuthVerified();
193
196
  }
@@ -200,7 +203,7 @@ export function createTypeSafe(options = {}) {
200
203
  async evaluate(input, callOptions = {}) {
201
204
  const validated = prepareEvaluationRequest(input, { maxInputBytes });
202
205
  // A per-request model meets the same mapping as the client default; the schema already limited the caller's own id.
203
- const body = JSON.stringify({ ...validated, model: validated.model === undefined ? model : backendModelId(backendName, validated.model) });
206
+ const body = JSON.stringify({ ...validated, model: validated.model === undefined ? model : mapModel(validated.model) });
204
207
  assertWithinByteLimit(body, maxInputBytes);
205
208
  if (callOptions.signal?.aborted)
206
209
  throw new TypeSafeIntegrationError("aborted", "TypeSafe request cancelled before submission.");
@@ -1,6 +1,9 @@
1
- import type { TypeSafeBackend } from "./backends.js";
1
+ import type { BackendSpec } from "./backends.js";
2
2
  export type KeySource = "environment" | "stored";
3
- /** The complete, never-throwing answer to "which key is in effect". */
3
+ /**
4
+ * The complete answer to "which key is in effect" for a valid backend: it never throws. An invalid backend — an
5
+ * unknown name or an endpoint object that fails validation — throws the same `configuration` error as resolveBackend.
6
+ */
4
7
  export type KeySituation =
5
8
  /** `keyEnv` names the variable that was read; absent means `TYPESAFE_API_KEY`. */
6
9
  {
@@ -30,21 +33,24 @@ export declare function normalizeApiKey(value: unknown): string;
30
33
  */
31
34
  export declare function readStoredApiKey(): string | undefined;
32
35
  /**
33
- * What the environment, the login store, and file permissions add up to right now for one judgment backend. Never
34
- * throws; the "unusable" kind carries the user-facing reason (a stored key that other local users can read).
36
+ * What the environment, the login store, and file permissions add up to right now for one judgment backend. A valid
37
+ * backend never throws: the "unusable" kind carries the user-facing reason (a stored key that other local users can
38
+ * read). An invalid backend — an unknown name or an endpoint object that fails validation — throws the same
39
+ * `configuration` error as resolveBackend(), so validate a user-supplied endpoint with resolveBackend() first.
35
40
  * The TypeSafe backend reads `TYPESAFE_API_KEY`, then the login store. Every other backend reads only its own
36
41
  * environment variable, because the store holds a TypeSafe key and a login verifies against api.typesafe.ai.
37
42
  */
38
- export declare function keySituation(backend?: TypeSafeBackend): KeySituation;
43
+ export declare function keySituation(backend?: BackendSpec): KeySituation;
39
44
  /** Short phrase naming the source; full sentences stay with the caller. */
40
45
  export declare function keySourceLabel(situation: KeySituation): string;
41
46
  /**
42
47
  * The pre-0.4.0 key interface, frozen for existing callers: environment first so CI and scripts stay explicit, the
43
48
  * stored key as the interactive default, `undefined` when no key is configured, and a `configuration` error when a
44
- * store must not be read. New code should call keySituation() instead: same precedence, never throws, and the
45
- * "must not be read" case arrives as `unusable` with the reason.
49
+ * store must not be read. New code should call keySituation() instead: same precedence, never throws for a valid
50
+ * backend (an invalid one throws resolveBackend's `configuration` error), and the "must not be read" case arrives as
51
+ * `unusable` with the reason.
46
52
  */
47
- export declare function resolveApiKey(backend?: TypeSafeBackend): {
53
+ export declare function resolveApiKey(backend?: BackendSpec): {
48
54
  key: string;
49
55
  source: KeySource;
50
56
  } | undefined;
@@ -1,7 +1,7 @@
1
1
  import { chmodSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { dirname, join } from "node:path";
4
- import { DEFAULT_BACKEND, TYPESAFE_KEY_ENV, backendConfig, usesTypesafeKey } from "./backends.js";
4
+ import { DEFAULT_BACKEND, TYPESAFE_KEY_ENV, resolveBackend, usesTypesafeKey } from "./backends.js";
5
5
  import { TypeSafeIntegrationError } from "./errors.js";
6
6
  /** Mirrors Pi's agent directory rule; every pi-typesafe file lives in this one directory. */
7
7
  export function piTypesafeDir() {
@@ -45,14 +45,16 @@ export function readStoredApiKey() {
45
45
  }
46
46
  }
47
47
  /**
48
- * What the environment, the login store, and file permissions add up to right now for one judgment backend. Never
49
- * throws; the "unusable" kind carries the user-facing reason (a stored key that other local users can read).
48
+ * What the environment, the login store, and file permissions add up to right now for one judgment backend. A valid
49
+ * backend never throws: the "unusable" kind carries the user-facing reason (a stored key that other local users can
50
+ * read). An invalid backend — an unknown name or an endpoint object that fails validation — throws the same
51
+ * `configuration` error as resolveBackend(), so validate a user-supplied endpoint with resolveBackend() first.
50
52
  * The TypeSafe backend reads `TYPESAFE_API_KEY`, then the login store. Every other backend reads only its own
51
53
  * environment variable, because the store holds a TypeSafe key and a login verifies against api.typesafe.ai.
52
54
  */
53
55
  export function keySituation(backend = DEFAULT_BACKEND) {
54
- const config = backendConfig(backend);
55
- const keyEnv = config.keyEnv ?? TYPESAFE_KEY_ENV;
56
+ const config = resolveBackend(backend);
57
+ const keyEnv = config.keyEnv;
56
58
  const fromEnvironment = process.env[keyEnv]?.trim();
57
59
  if (fromEnvironment)
58
60
  return { kind: "environment", key: fromEnvironment, keyEnv };
@@ -82,8 +84,9 @@ export function keySourceLabel(situation) {
82
84
  /**
83
85
  * The pre-0.4.0 key interface, frozen for existing callers: environment first so CI and scripts stay explicit, the
84
86
  * stored key as the interactive default, `undefined` when no key is configured, and a `configuration` error when a
85
- * store must not be read. New code should call keySituation() instead: same precedence, never throws, and the
86
- * "must not be read" case arrives as `unusable` with the reason.
87
+ * store must not be read. New code should call keySituation() instead: same precedence, never throws for a valid
88
+ * backend (an invalid one throws resolveBackend's `configuration` error), and the "must not be read" case arrives as
89
+ * `unusable` with the reason.
87
90
  */
88
91
  export function resolveApiKey(backend = DEFAULT_BACKEND) {
89
92
  const situation = keySituation(backend);
@@ -1,4 +1,4 @@
1
- import type { BackendConfig, TypeSafeBackend } from "./backends.js";
1
+ import type { BackendConfig, BackendSpec } from "./backends.js";
2
2
  export type IntegrationErrorCode = "configuration" | "validation" | "budget" | "aborted" | "timeout" | "http" | "connection" | "response";
3
3
  /**
4
4
  * Safe to display: never contains upstream bodies, keys, or submitted state. The only header value a message can
@@ -14,4 +14,4 @@ export declare class TypeSafeIntegrationError extends Error {
14
14
  * Classify an error into a message safe to display. `backend` names the key variable the 401 advice tells the user
15
15
  * to check and selects the 402 wording; omitting it keeps the one-argument call and assumes the default TypeSafe key.
16
16
  */
17
- export declare function safeError(error: unknown, backend?: TypeSafeBackend | BackendConfig): TypeSafeIntegrationError;
17
+ export declare function safeError(error: unknown, backend?: BackendSpec | BackendConfig): TypeSafeIntegrationError;
@@ -1,5 +1,5 @@
1
- export { createTypeSafe, DEFAULT_MAX_REQUESTS, DECISIONS_BACKENDS, DEFAULT_BACKEND } from "./client.js";
2
- export type { TypeSafe, TypeSafeOptions, EvaluationOptions, Evaluation, UsageSnapshot, SpendReport, TypeSafeBackend, BackendConfig, } from "./client.js";
1
+ export { createTypeSafe, backendHost, resolveBackend, DEFAULT_MAX_REQUESTS, DECISIONS_BACKENDS, DEFAULT_BACKEND } from "./client.js";
2
+ export type { TypeSafe, TypeSafeOptions, EvaluationOptions, Evaluation, UsageSnapshot, SpendReport, TypeSafeBackend, BackendConfig, BackendEndpoint, BackendSpec, ResolvedBackend, } from "./client.js";
3
3
  export { ask, DEFAULT_ASK_TIMEOUT_MS } from "./ask.js";
4
4
  export type { AskAnswer, AskOptions, Judge } from "./ask.js";
5
5
  export { fanOut, DEFAULT_CONCURRENCY, evaluateMany, evaluateAll, chunkEvaluationRequest } from "./batch.js";
@@ -1,4 +1,4 @@
1
- export { createTypeSafe, DEFAULT_MAX_REQUESTS, DECISIONS_BACKENDS, DEFAULT_BACKEND } from "./client.js";
1
+ export { createTypeSafe, backendHost, resolveBackend, DEFAULT_MAX_REQUESTS, DECISIONS_BACKENDS, DEFAULT_BACKEND } from "./client.js";
2
2
  export { ask, DEFAULT_ASK_TIMEOUT_MS } from "./ask.js";
3
3
  export { fanOut, DEFAULT_CONCURRENCY, evaluateMany, evaluateAll, chunkEvaluationRequest } from "./batch.js";
4
4
  export { authState, authStatePath, clearAuthState, describeAuth, recordAuthFailure, recordAuthVerified } from "./auth.js";
@@ -1,5 +1,5 @@
1
1
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
- import type { TypeSafeBackend } from "./backends.js";
2
+ import type { BackendSpec } from "./backends.js";
3
3
  import type { KeySource } from "./credentials.js";
4
4
  export interface LoginResult {
5
5
  /** Where the verified key was saved. */
@@ -29,5 +29,5 @@ export type EnsureApiKeyResult = {
29
29
  * the prompt would verify the key against the wrong service and store it where the TypeSafe key lives.
30
30
  */
31
31
  export declare function ensureApiKey(ctx: ExtensionCommandContext, options?: {
32
- backend?: TypeSafeBackend;
32
+ backend?: BackendSpec;
33
33
  }): Promise<EnsureApiKeyResult | undefined>;
@@ -1,4 +1,4 @@
1
- import { DEFAULT_BACKEND, backendConfig, usesTypesafeKey } from "./backends.js";
1
+ import { DEFAULT_BACKEND, resolveBackend, usesTypesafeKey } from "./backends.js";
2
2
  import { createTypeSafe } from "./client.js";
3
3
  import { keySituation, normalizeApiKey, storeApiKey } from "./credentials.js";
4
4
  import { TypeSafeIntegrationError } from "./errors.js";
@@ -38,7 +38,7 @@ export async function ensureApiKey(ctx, options = {}) {
38
38
  return { source: situation.kind };
39
39
  if (situation.kind === "unusable")
40
40
  throw new TypeSafeIntegrationError("configuration", situation.reason);
41
- const config = backendConfig(backend);
41
+ const config = resolveBackend(backend);
42
42
  if (!usesTypesafeKey(config)) {
43
43
  throw new TypeSafeIntegrationError("configuration", `No ${config.label} key. Set ${config.keyEnv} in the environment; /typesafe login stores a TypeSafe key only.`);
44
44
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-typesafe",
3
- "version": "0.7.4",
3
+ "version": "0.8.1",
4
4
  "description": "TypeSafe AI (Jev) decisions for Pi: batched Choice/Score/Noul evaluation tool, terminal playground, and a typed API other extensions build on.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -64,12 +64,12 @@
64
64
  "prepack": "npm run build"
65
65
  },
66
66
  "dependencies": {
67
- "@typesafe-ai/sdk": "^0.6.0",
68
- "typebox": "^1.3.31"
67
+ "@typesafe-ai/sdk": "^0.6.0"
69
68
  },
70
69
  "peerDependencies": {
71
- "@earendil-works/pi-coding-agent": ">=0.85.1 <1",
72
- "@earendil-works/pi-tui": ">=0.85.1 <1"
70
+ "@earendil-works/pi-coding-agent": "*",
71
+ "@earendil-works/pi-tui": "*",
72
+ "typebox": "*"
73
73
  },
74
74
  "peerDependenciesMeta": {
75
75
  "@earendil-works/pi-coding-agent": {
@@ -84,6 +84,7 @@
84
84
  "@earendil-works/pi-tui": "^0.86.1",
85
85
  "@types/node": "^22.0.0",
86
86
  "tsx": "^4.23.13",
87
+ "typebox": "^1.3.31",
87
88
  "typescript": "^7.0.2"
88
89
  }
89
90
  }
@@ -4,6 +4,78 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.34.0] - 2026-09-30
8
+
9
+ ### Highlights
10
+
11
+ - Turning on web tools no longer costs a prompt-cache miss on models like DeepSeek. New sessions now pick the activation style that suits the model.
12
+ - Search with Z.ai's GLM Coding Plan and use your plan quota instead of paying per call.
13
+ - `fetch_content` now gets past Cloudflare "Just a moment..." pages by handing off to your other fetch providers.
14
+ - Fetching works on networks where only your configured proxy can resolve hostnames.
15
+ - `undici` is updated to pick up fixes for known security advisories.
16
+
17
+ ### Added
18
+
19
+ - Search with Z.ai's GLM Coding Plan web search when you select `provider: "zai"`. Set `ZAI_API_KEY` or `zaiApiKey` to your plan key, and set `zaiEndpoint: "china"` if your key comes from bigmodel.cn. Searches use your plan quota instead of per-call billing. Thanks to [@nailuoGG](https://github.com/nailuoGG) for [issue #475](https://github.com/nicobailon/pi-web-access/issues/475) and for live-testing the China endpoint in [issue #479](https://github.com/nicobailon/pi-web-access/issues/479).
20
+
21
+ ### Changed
22
+
23
+ - `toolActivation` now defaults to `"auto"`. On models that can take tools added mid-conversation, new sessions start with `web_enable` as before. On other models, such as DeepSeek, every enabled web tool is available from the first request, so turning them on no longer makes Pi resend the whole conversation and miss the prompt cache. Set `"dynamic"` to always start with `web_enable`, or `"eager"` to never use it. Resumed sessions keep the tools they already had. The README's Tool activation section explains the trade-off. Thanks to [@tinoy1336](https://github.com/tinoy1336) for [issue #484](https://github.com/nicobailon/pi-web-access/issues/484) and [@jordi9](https://github.com/jordi9) for [issue #481](https://github.com/nicobailon/pi-web-access/issues/481).
24
+ - Keyed Exa searches with default options or `numResults: 5` now call Exa's `/search` endpoint instead of `/answer`, like every other keyed Exa search. Their answer text now comes from the search results instead of Exa's generated answer. If you route Exa through a custom `exaBaseUrl` gateway, it must support `/search`. Thanks to [@SuTang-vain](https://github.com/SuTang-vain) for [issue #470](https://github.com/nicobailon/pi-web-access/issues/470).
25
+ - When `fetch_content` can't get a page, its list of fallback options now explains how to turn on the keyless Jina Reader fallback. It names only the setting you still need and keeps your current or default provider order. The hint doesn't appear if Jina already ran for that fetch, and it warns that Jina's servers fetch the target URLs. Thanks to [@SuTang-vain](https://github.com/SuTang-vain) for [PR #471](https://github.com/nicobailon/pi-web-access/pull/471).
26
+
27
+ ### Fixed
28
+
29
+ - `fetch_content` now treats a Cloudflare "Just a moment..." challenge page returned with HTTP 200 as a failed fetch, so your configured fallback providers can retrieve the real page. Detection needs Cloudflare's `cf-mitigated: challenge` header or its challenge-page scripts, so a page that only says "Just a moment..." is unaffected. Raw mode still returns the response unchanged, and authenticated fetches report the challenge without falling back to other providers. Thanks to [@SuTang-vain](https://github.com/SuTang-vain) for [issue #472](https://github.com/nicobailon/pi-web-access/issues/472).
30
+ - With `ssrf.trustEnvProxy: true`, the `proxy` configured in `web-search.json` now resolves hostnames for web tools instead of your local DNS, so `fetch_content` works where only the proxy can resolve names. A per-call `proxy` with a different value is still checked against local DNS. When local resolution fails for a request going through the configured proxy, the error now names this setting. Thanks to [@ChenAuCarre](https://github.com/ChenAuCarre) for [issue #476](https://github.com/nicobailon/pi-web-access/issues/476).
31
+ - Exa results without a title are now labeled with their site's hostname, such as `cdn.jsdelivr.net`, instead of `Source N`. Results whose URL has no hostname, such as `mailto:` or `file:` links, still use `Source N`. Thanks to [@SuTang-vain](https://github.com/SuTang-vain) for [PR #469](https://github.com/nicobailon/pi-web-access/pull/469).
32
+ - `undici` is updated to 8.11.2. Earlier 8.x releases, including the 8.10.0 this package previously installed, have known security advisories such as decompression denial of service and a TLS certificate validation bypass. Thanks to [@setanta00](https://github.com/setanta00) for [issue #483](https://github.com/nicobailon/pi-web-access/issues/483).
33
+
34
+ ## [0.33.0] - 2026-09-27
35
+
36
+ ### Highlights
37
+
38
+ - Keep every web tool available from the first message with `"toolActivation": "eager"`, for models that rarely call `web_enable` on their own.
39
+ - Search with You.com when you select it explicitly.
40
+ - Give each Pi process its own fetched-page cache so parallel sessions stop evicting each other's pages.
41
+ - Model allowlists in `enabledModels` or `--models` now work with every pattern Pi accepts.
42
+ - Resumed older sessions keep the tools they had instead of gaining `web_enable`.
43
+
44
+ ### Added
45
+
46
+ - Set `"toolActivation": "eager"` in `web-search.json` to skip `web_enable` and keep every enabled web tool available from the first message. With the default `"dynamic"` setting, `web_enable` now tells the model to call it first whenever current, external, or linked information could help. Thanks to [@ackalker](https://github.com/ackalker) for [issue #458](https://github.com/nicobailon/pi-web-access/issues/458).
47
+ - Set `PI_WEB_ACCESS_CACHE_ROOT` to a directory to give a Pi process its own fetched-page cache. The cache goes in a `web-search-cache` folder inside that directory, and `web-search.json` stays where it is. Parallel sessions then stop evicting each other's cached pages. Thanks to [@goodman-b](https://github.com/goodman-b) for [issue #457](https://github.com/nicobailon/pi-web-access/issues/457).
48
+ - You.com is available as an optional search provider. Set `youApiKey` or `YDC_API_KEY`, then select `provider: "you"`, add it to a provider list, or list it in `searchRouting`. It also appears in the Curator. `auto` and `provider: "all"` never pick it. Thanks to [@mouse-value-add](https://github.com/mouse-value-add) for [PR #461](https://github.com/nicobailon/pi-web-access/pull/461).
49
+
50
+ ### Fixed
51
+
52
+ - Resuming a session that never had `web_enable`, for example one started before pi-web-access was installed or upgraded, no longer adds it partway through the conversation. The session keeps the tools it already had. Thanks to [@nilsoskar](https://github.com/nilsoskar) for [issue #462](https://github.com/nicobailon/pi-web-access/issues/462).
53
+ - Answer mode, query rewrite, and summaries now follow the model list Pi builds from `enabledModels` or `--models`, so every pattern Pi accepts works here too, including patterns such as `@(!(openai-codex))/*` and partial names such as `sonnet`. Before, an allowlist made of those patterns blocked every model. Thanks to [@IdrisGit](https://github.com/IdrisGit) for [issue #463](https://github.com/nicobailon/pi-web-access/issues/463) and [PR #464](https://github.com/nicobailon/pi-web-access/pull/464).
54
+ - `web_enable` now depends on the version of Pi you are running, not an older Pi package that may be installed next to the extension, so those setups no longer lose it. It needs Pi 0.86.0 or newer. On older Pi, every enabled web tool stays available from the start. Thanks to [@PhrZer](https://github.com/PhrZer) for [PR #456](https://github.com/nicobailon/pi-web-access/pull/456) and [@nguyenchiencong](https://github.com/nguyenchiencong) for [issue #444](https://github.com/nicobailon/pi-web-access/issues/444).
55
+
56
+ ## [0.32.0] - 2026-09-26
57
+
58
+ ### Highlights
59
+
60
+ - Spread Tavily searches across up to 20 API keys, with automatic failover when one runs out of quota.
61
+ - Use Gemini Web browser cookies on KDE Linux, where Chrome keeps its password in KWallet.
62
+ - Search with OpenAI through OpenCode and `opencode-go` without session errors or the wrong model.
63
+ - See full search queries and URLs in tool-call labels.
64
+ - Globally installed Pi no longer shows false version or duplicate TypeBox warnings.
65
+
66
+ ### Added
67
+
68
+ - Tavily can use a pool of up to 20 API keys. Set `TAVILY_API_KEY_1` through `TAVILY_API_KEY_20`, and when a key hits a quota or auth error the search moves on to the next one. `TAVILY_API_KEY_INDEX` picks the key to try first, and `TAVILY_API_KEY` / `tavilyApiKey` is tried last. Thanks to [@apoapostolov](https://github.com/apoapostolov) for [PR #430](https://github.com/nicobailon/pi-web-access/pull/430).
69
+
70
+ ### Fixed
71
+
72
+ - On KDE Linux, Chrome and Chromium cookies for Gemini Web now decrypt with the password stored in KWallet when Secret Service doesn't have it. Thanks to [@dianzuan](https://github.com/dianzuan) for [issue #436](https://github.com/nicobailon/pi-web-access/issues/436).
73
+ - OpenAI search requests to `opencode.ai` now include OpenCode's session headers, fixing `400 MissingSessionID` errors. Other destinations never receive these headers. Thanks to [@juliocc](https://github.com/juliocc) for [PR #445](https://github.com/nicobailon/pi-web-access/pull/445).
74
+ - When `openaiSearchModel` isn't set, OpenAI search through gateways such as `opencode-go` now picks the newest GPT model instead of a non-OpenAI model.
75
+ - Globally installed Pi no longer shows a false "requires Pi 0.86.1 or newer" warning, and dynamic tool activation now works there. Thanks to [@samsimsom](https://github.com/samsimsom) for [issue #428](https://github.com/nicobailon/pi-web-access/issues/428).
76
+ - TypeBox now comes from Pi instead of being installed separately, which avoids duplicate copies and Pi startup warnings. Thanks to [@ksreenivasan](https://github.com/ksreenivasan) for [issue #442](https://github.com/nicobailon/pi-web-access/issues/442) and [PR #443](https://github.com/nicobailon/pi-web-access/pull/443).
77
+ - Tool-call labels show full search queries and fetch URLs when the terminal is wide enough, instead of cutting them off at 60 characters. Thanks to [@TheBestPessimist](https://github.com/TheBestPessimist) for [issue #440](https://github.com/nicobailon/pi-web-access/issues/440).
78
+
7
79
  ## [0.31.0] - 2026-09-22
8
80
 
9
81
  ### Highlights