@herbertgao/pi-extensions 2026.8.1 → 2026.8.3

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 (403) hide show
  1. package/README.md +13 -3
  2. package/node_modules/@czottmann/pi-automode/README.md +16 -2
  3. package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +35 -0
  4. package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +18 -9
  5. package/node_modules/@czottmann/pi-automode/docs/defaults.md +6 -2
  6. package/node_modules/@czottmann/pi-automode/examples/automode.local.json +6 -0
  7. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +11 -7
  8. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +100 -0
  9. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +32 -0
  10. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +78 -3
  11. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +16 -4
  12. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +23 -1
  13. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +22 -1
  14. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/types.ts +18 -2
  15. package/node_modules/@czottmann/pi-automode/package.json +4 -4
  16. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +5 -0
  17. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +5 -0
  18. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +5 -0
  19. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-help.md +5 -0
  20. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +5 -0
  21. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +5 -0
  22. package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail-frontmatter.cjs +23 -0
  23. package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs +99 -0
  24. package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +30 -0
  25. package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +16 -0
  26. package/node_modules/@dietrichgebert/ponytail/AGENTS.md +32 -0
  27. package/node_modules/@dietrichgebert/ponytail/LICENSE +21 -0
  28. package/node_modules/@dietrichgebert/ponytail/README.es.md +298 -0
  29. package/node_modules/@dietrichgebert/ponytail/README.ko.md +315 -0
  30. package/node_modules/@dietrichgebert/ponytail/README.md +351 -0
  31. package/node_modules/@dietrichgebert/ponytail/assets/benchmark-3model.svg +21 -0
  32. package/node_modules/@dietrichgebert/ponytail/assets/benchmark-agentic.svg +62 -0
  33. package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.png +0 -0
  34. package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.svg +115 -0
  35. package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt-dark.svg +27 -0
  36. package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt.svg +27 -0
  37. package/node_modules/@dietrichgebert/ponytail/assets/logo.png +0 -0
  38. package/node_modules/@dietrichgebert/ponytail/assets/social-preview.png +0 -0
  39. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-es.png +0 -0
  40. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-ko.png +0 -0
  41. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner.png +0 -0
  42. package/node_modules/@dietrichgebert/ponytail/hooks/claude-codex-hooks.json +44 -0
  43. package/node_modules/@dietrichgebert/ponytail/hooks/copilot-hooks.json +21 -0
  44. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +96 -0
  45. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-config.js +169 -0
  46. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +98 -0
  47. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-mode-tracker.js +130 -0
  48. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-runtime.js +85 -0
  49. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.ps1 +24 -0
  50. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.sh +18 -0
  51. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-subagent.js +77 -0
  52. package/node_modules/@dietrichgebert/ponytail/hooks/qoder-hooks.json +26 -0
  53. package/node_modules/@dietrichgebert/ponytail/package.json +47 -0
  54. package/node_modules/@dietrichgebert/ponytail/pi-extension/index.js +211 -0
  55. package/node_modules/@dietrichgebert/ponytail/pi-extension/package.json +8 -0
  56. package/node_modules/@dietrichgebert/ponytail/scripts/uninstall.js +60 -0
  57. package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +120 -0
  58. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +41 -0
  59. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +44 -0
  60. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +50 -0
  61. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +71 -0
  62. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +57 -0
  63. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +6 -10
  64. package/node_modules/@herbertgao/pi-cc-extensions/README.md +5 -9
  65. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.en.svg +101 -0
  66. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +1 -17
  67. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +15 -9
  68. package/node_modules/@herbertgao/pi-cc-extensions/extensions/{utils/agent-summary.ts → feature/agent-summary/core.ts} +37 -35
  69. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-summary.ts → agent-summary/index.ts} +3 -3
  70. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +24 -83
  71. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +1 -1
  72. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference.ts → reference/index.ts} +1 -1
  73. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-autocomplete.ts → reference/subagent.ts} +19 -9
  74. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-startup-header.ts → shell/startup-header.ts} +1 -1
  75. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{working-message.ts → shell/working-message.ts} +5 -2
  76. package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +32 -28
  77. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +452 -94
  78. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +727 -0
  79. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +66 -776
  80. package/node_modules/@herbertgao/pi-cc-extensions/extensions/{feature → renderer}/markdown-enhance.ts +134 -11
  81. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +130 -0
  82. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-interaction.ts → mouse/interaction.ts} +90 -568
  83. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +144 -0
  84. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/packets.ts +143 -0
  85. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/scroll.ts +195 -0
  86. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ansi-utils.ts +56 -1
  87. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-renderer.ts +4 -4
  88. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/line-width-safety.ts +1 -1
  89. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-display-utils.ts +12 -0
  90. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/write-execution.ts +1 -2
  91. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-grouping.ts → tool/grouping.ts} +27 -10
  92. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-result.ts → tool/result.ts} +4 -13
  93. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/transcript-refresh.ts +91 -0
  94. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/fullscreen-detect.ts +0 -27
  95. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  96. package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-dark.json +1 -0
  97. package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-light.json +2 -2
  98. package/node_modules/@herbertgao/pi-stash/README.md +9 -9
  99. package/node_modules/@herbertgao/pi-stash/package.json +1 -1
  100. package/node_modules/@herbertgao/pi-stash/src/index.ts +2 -1
  101. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +20 -0
  102. package/node_modules/@herbertgao/pi-subagents/README.md +6 -2
  103. package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
  104. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +1 -0
  105. package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +3 -1
  106. package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +85 -11
  107. package/node_modules/@herbertgao/pi-subagents/src/index.ts +61 -39
  108. package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +26 -35
  109. package/node_modules/@herbertgao/pi-subagents/src/prompts.ts +15 -1
  110. package/node_modules/@herbertgao/pi-subagents/src/settings.ts +12 -0
  111. package/node_modules/@herbertgao/pi-subagents/src/types.ts +2 -0
  112. package/node_modules/@narumitw/pi-btw/LICENSE +21 -0
  113. package/node_modules/@narumitw/pi-btw/README.md +210 -0
  114. package/node_modules/@narumitw/pi-btw/package.json +53 -0
  115. package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +632 -0
  116. package/node_modules/@narumitw/pi-btw/src/btw.ts +996 -0
  117. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +339 -0
  118. package/node_modules/@narumitw/pi-btw/src/index.ts +1 -0
  119. package/node_modules/@narumitw/pi-btw/src/menu.ts +296 -0
  120. package/node_modules/@narumitw/pi-btw/src/settings.ts +237 -0
  121. package/node_modules/@narumitw/pi-btw/src/side-thread.ts +238 -0
  122. package/node_modules/@narumitw/pi-btw/src/text.ts +10 -0
  123. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +620 -0
  124. package/node_modules/@pi-plugins/fast-mode/LICENSE +21 -0
  125. package/node_modules/@pi-plugins/fast-mode/README.md +92 -0
  126. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts +6 -0
  127. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -0
  128. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +2026 -0
  129. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -0
  130. package/node_modules/@pi-plugins/fast-mode/package.json +73 -0
  131. package/node_modules/pi-mcp-adapter/CHANGELOG.md +78 -0
  132. package/node_modules/pi-mcp-adapter/README.md +80 -16
  133. package/node_modules/pi-mcp-adapter/agent-dir.ts +40 -0
  134. package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +377 -0
  135. package/node_modules/pi-mcp-adapter/commands.ts +21 -9
  136. package/node_modules/pi-mcp-adapter/config.ts +110 -49
  137. package/node_modules/pi-mcp-adapter/direct-tools.ts +40 -27
  138. package/node_modules/pi-mcp-adapter/elicitation-handler.ts +37 -36
  139. package/node_modules/pi-mcp-adapter/errors.ts +21 -17
  140. package/node_modules/pi-mcp-adapter/host-html-template.ts +13 -7
  141. package/node_modules/pi-mcp-adapter/index.ts +52 -17
  142. package/node_modules/pi-mcp-adapter/init.ts +9 -7
  143. package/node_modules/pi-mcp-adapter/json-schema-validator.ts +2 -2
  144. package/node_modules/pi-mcp-adapter/lifecycle.ts +8 -8
  145. package/node_modules/pi-mcp-adapter/logger.ts +1 -1
  146. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +122 -25
  147. package/node_modules/pi-mcp-adapter/mcp-auth.ts +120 -2
  148. package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +138 -61
  149. package/node_modules/pi-mcp-adapter/mcp-code.ts +13 -11
  150. package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +62 -17
  151. package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +15 -11
  152. package/node_modules/pi-mcp-adapter/mcp-panel.ts +34 -15
  153. package/node_modules/pi-mcp-adapter/mcp-probe.ts +131 -34
  154. package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +2 -2
  155. package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +7 -4
  156. package/node_modules/pi-mcp-adapter/mcp-trace.ts +59 -64
  157. package/node_modules/pi-mcp-adapter/metadata-cache.ts +34 -26
  158. package/node_modules/pi-mcp-adapter/npx-resolver.ts +6 -4
  159. package/node_modules/pi-mcp-adapter/oauth-handler.ts +1 -1
  160. package/node_modules/pi-mcp-adapter/oauth.ts +48 -0
  161. package/node_modules/pi-mcp-adapter/onboarding-state.ts +19 -11
  162. package/node_modules/pi-mcp-adapter/package.json +20 -9
  163. package/node_modules/pi-mcp-adapter/panel-keys.ts +20 -4
  164. package/node_modules/pi-mcp-adapter/prompts.ts +2 -2
  165. package/node_modules/pi-mcp-adapter/proxy-modes.ts +56 -21
  166. package/node_modules/pi-mcp-adapter/sampling-handler.ts +22 -15
  167. package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -1
  168. package/node_modules/pi-mcp-adapter/server-manager.ts +165 -113
  169. package/node_modules/pi-mcp-adapter/session-recovery.ts +11 -12
  170. package/node_modules/pi-mcp-adapter/skills/mcp-scripting/SKILL.md +3 -3
  171. package/node_modules/pi-mcp-adapter/state.ts +3 -1
  172. package/node_modules/pi-mcp-adapter/tool-approval.ts +67 -4
  173. package/node_modules/pi-mcp-adapter/tool-metadata.ts +6 -5
  174. package/node_modules/pi-mcp-adapter/tool-registrar.ts +187 -3
  175. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +14 -2
  176. package/node_modules/pi-mcp-adapter/ts-shape.ts +9 -2
  177. package/node_modules/pi-mcp-adapter/types.ts +111 -22
  178. package/node_modules/pi-mcp-adapter/ui-app-bridge-helpers.ts +40 -0
  179. package/node_modules/pi-mcp-adapter/ui-resource-handler.ts +28 -19
  180. package/node_modules/pi-mcp-adapter/ui-server.ts +90 -58
  181. package/node_modules/pi-mcp-adapter/ui-session.ts +16 -14
  182. package/node_modules/pi-mcp-adapter/unix-socket-transport.ts +4 -4
  183. package/node_modules/pi-mcp-adapter/utils.ts +23 -9
  184. package/node_modules/pi-web-access/CHANGELOG.md +45 -0
  185. package/node_modules/pi-web-access/README.md +104 -29
  186. package/node_modules/pi-web-access/bocha.ts +221 -0
  187. package/node_modules/pi-web-access/curator-page.ts +113 -12
  188. package/node_modules/pi-web-access/curator-server.ts +56 -20
  189. package/node_modules/pi-web-access/datalab-pdf-extract.ts +568 -0
  190. package/node_modules/pi-web-access/duckduckgo.ts +123 -0
  191. package/node_modules/pi-web-access/extract.ts +288 -143
  192. package/node_modules/pi-web-access/feature-config.ts +29 -0
  193. package/node_modules/pi-web-access/gemini-api.ts +4 -0
  194. package/node_modules/pi-web-access/gemini-search.ts +45 -12
  195. package/node_modules/pi-web-access/gemini-web.ts +68 -3
  196. package/node_modules/pi-web-access/index.ts +160 -71
  197. package/node_modules/pi-web-access/jina-search.ts +284 -0
  198. package/node_modules/pi-web-access/kagi.ts +12 -12
  199. package/node_modules/pi-web-access/openai-search.ts +12 -2
  200. package/node_modules/pi-web-access/package.json +4 -3
  201. package/node_modules/pi-web-access/pdf-extract.ts +327 -228
  202. package/node_modules/pi-web-access/storage.ts +440 -2
  203. package/node_modules/pi-web-access/summary-model-scope.ts +1 -1
  204. package/node_modules/pi-web-access/summary-review.ts +4 -2
  205. package/node_modules/pi-web-access/video-extract.ts +10 -8
  206. package/node_modules/pi-web-access/xai-search.ts +12 -2
  207. package/node_modules/pi-web-access/youtube-extract.ts +2 -1
  208. package/node_modules/remote-pi/LICENSE +21 -0
  209. package/node_modules/remote-pi/README.md +675 -0
  210. package/node_modules/remote-pi/dist/actions/handlers.d.ts +122 -0
  211. package/node_modules/remote-pi/dist/actions/handlers.js +160 -0
  212. package/node_modules/remote-pi/dist/actions/handlers.js.map +1 -0
  213. package/node_modules/remote-pi/dist/actions/registry.d.ts +39 -0
  214. package/node_modules/remote-pi/dist/actions/registry.js +58 -0
  215. package/node_modules/remote-pi/dist/actions/registry.js.map +1 -0
  216. package/node_modules/remote-pi/dist/bin/supervisord.d.ts +2 -0
  217. package/node_modules/remote-pi/dist/bin/supervisord.js +86 -0
  218. package/node_modules/remote-pi/dist/bin/supervisord.js.map +1 -0
  219. package/node_modules/remote-pi/dist/commands/builtin_mirror.d.ts +58 -0
  220. package/node_modules/remote-pi/dist/commands/builtin_mirror.js +71 -0
  221. package/node_modules/remote-pi/dist/commands/builtin_mirror.js.map +1 -0
  222. package/node_modules/remote-pi/dist/commands/list_commands.d.ts +60 -0
  223. package/node_modules/remote-pi/dist/commands/list_commands.js +73 -0
  224. package/node_modules/remote-pi/dist/commands/list_commands.js.map +1 -0
  225. package/node_modules/remote-pi/dist/config.d.ts +62 -0
  226. package/node_modules/remote-pi/dist/config.js +115 -0
  227. package/node_modules/remote-pi/dist/config.js.map +1 -0
  228. package/node_modules/remote-pi/dist/daemon/client.d.ts +20 -0
  229. package/node_modules/remote-pi/dist/daemon/client.js +131 -0
  230. package/node_modules/remote-pi/dist/daemon/client.js.map +1 -0
  231. package/node_modules/remote-pi/dist/daemon/control_protocol.d.ts +176 -0
  232. package/node_modules/remote-pi/dist/daemon/control_protocol.js +63 -0
  233. package/node_modules/remote-pi/dist/daemon/control_protocol.js.map +1 -0
  234. package/node_modules/remote-pi/dist/daemon/cron_log.d.ts +45 -0
  235. package/node_modules/remote-pi/dist/daemon/cron_log.js +72 -0
  236. package/node_modules/remote-pi/dist/daemon/cron_log.js.map +1 -0
  237. package/node_modules/remote-pi/dist/daemon/cron_registry.d.ts +80 -0
  238. package/node_modules/remote-pi/dist/daemon/cron_registry.js +194 -0
  239. package/node_modules/remote-pi/dist/daemon/cron_registry.js.map +1 -0
  240. package/node_modules/remote-pi/dist/daemon/id.d.ts +24 -0
  241. package/node_modules/remote-pi/dist/daemon/id.js +36 -0
  242. package/node_modules/remote-pi/dist/daemon/id.js.map +1 -0
  243. package/node_modules/remote-pi/dist/daemon/install.d.ts +170 -0
  244. package/node_modules/remote-pi/dist/daemon/install.js +547 -0
  245. package/node_modules/remote-pi/dist/daemon/install.js.map +1 -0
  246. package/node_modules/remote-pi/dist/daemon/registry.d.ts +63 -0
  247. package/node_modules/remote-pi/dist/daemon/registry.js +153 -0
  248. package/node_modules/remote-pi/dist/daemon/registry.js.map +1 -0
  249. package/node_modules/remote-pi/dist/daemon/rpc_child.d.ts +194 -0
  250. package/node_modules/remote-pi/dist/daemon/rpc_child.js +389 -0
  251. package/node_modules/remote-pi/dist/daemon/rpc_child.js.map +1 -0
  252. package/node_modules/remote-pi/dist/daemon/supervisor.d.ts +93 -0
  253. package/node_modules/remote-pi/dist/daemon/supervisor.js +596 -0
  254. package/node_modules/remote-pi/dist/daemon/supervisor.js.map +1 -0
  255. package/node_modules/remote-pi/dist/extension_ui_bridge.d.ts +26 -0
  256. package/node_modules/remote-pi/dist/extension_ui_bridge.js +341 -0
  257. package/node_modules/remote-pi/dist/extension_ui_bridge.js.map +1 -0
  258. package/node_modules/remote-pi/dist/index.d.ts +213 -0
  259. package/node_modules/remote-pi/dist/index.js +4996 -0
  260. package/node_modules/remote-pi/dist/index.js.map +1 -0
  261. package/node_modules/remote-pi/dist/mcp/mesh_result.d.ts +10 -0
  262. package/node_modules/remote-pi/dist/mcp/mesh_result.js +42 -0
  263. package/node_modules/remote-pi/dist/mcp/mesh_result.js.map +1 -0
  264. package/node_modules/remote-pi/dist/mcp/mesh_server.d.ts +16 -0
  265. package/node_modules/remote-pi/dist/mcp/mesh_server.js +327 -0
  266. package/node_modules/remote-pi/dist/mcp/mesh_server.js.map +1 -0
  267. package/node_modules/remote-pi/dist/mesh/canonical.d.ts +30 -0
  268. package/node_modules/remote-pi/dist/mesh/canonical.js +61 -0
  269. package/node_modules/remote-pi/dist/mesh/canonical.js.map +1 -0
  270. package/node_modules/remote-pi/dist/mesh/client.d.ts +18 -0
  271. package/node_modules/remote-pi/dist/mesh/client.js +125 -0
  272. package/node_modules/remote-pi/dist/mesh/client.js.map +1 -0
  273. package/node_modules/remote-pi/dist/mesh/encoding.d.ts +38 -0
  274. package/node_modules/remote-pi/dist/mesh/encoding.js +216 -0
  275. package/node_modules/remote-pi/dist/mesh/encoding.js.map +1 -0
  276. package/node_modules/remote-pi/dist/mesh/self_revoke.d.ts +73 -0
  277. package/node_modules/remote-pi/dist/mesh/self_revoke.js +401 -0
  278. package/node_modules/remote-pi/dist/mesh/self_revoke.js.map +1 -0
  279. package/node_modules/remote-pi/dist/mesh/siblings.d.ts +49 -0
  280. package/node_modules/remote-pi/dist/mesh/siblings.js +159 -0
  281. package/node_modules/remote-pi/dist/mesh/siblings.js.map +1 -0
  282. package/node_modules/remote-pi/dist/mesh/types.d.ts +34 -0
  283. package/node_modules/remote-pi/dist/mesh/types.js +11 -0
  284. package/node_modules/remote-pi/dist/mesh/types.js.map +1 -0
  285. package/node_modules/remote-pi/dist/mesh/verify.d.ts +17 -0
  286. package/node_modules/remote-pi/dist/mesh/verify.js +86 -0
  287. package/node_modules/remote-pi/dist/mesh/verify.js.map +1 -0
  288. package/node_modules/remote-pi/dist/pairing/crypto.d.ts +8 -0
  289. package/node_modules/remote-pi/dist/pairing/crypto.js +22 -0
  290. package/node_modules/remote-pi/dist/pairing/crypto.js.map +1 -0
  291. package/node_modules/remote-pi/dist/pairing/handshake.d.ts +28 -0
  292. package/node_modules/remote-pi/dist/pairing/handshake.js +113 -0
  293. package/node_modules/remote-pi/dist/pairing/handshake.js.map +1 -0
  294. package/node_modules/remote-pi/dist/pairing/noise-sha256.d.ts +16 -0
  295. package/node_modules/remote-pi/dist/pairing/noise-sha256.js +103 -0
  296. package/node_modules/remote-pi/dist/pairing/noise-sha256.js.map +1 -0
  297. package/node_modules/remote-pi/dist/pairing/qr.d.ts +59 -0
  298. package/node_modules/remote-pi/dist/pairing/qr.js +125 -0
  299. package/node_modules/remote-pi/dist/pairing/qr.js.map +1 -0
  300. package/node_modules/remote-pi/dist/pairing/storage.d.ts +120 -0
  301. package/node_modules/remote-pi/dist/pairing/storage.js +604 -0
  302. package/node_modules/remote-pi/dist/pairing/storage.js.map +1 -0
  303. package/node_modules/remote-pi/dist/protocol/codec.d.ts +7 -0
  304. package/node_modules/remote-pi/dist/protocol/codec.js +49 -0
  305. package/node_modules/remote-pi/dist/protocol/codec.js.map +1 -0
  306. package/node_modules/remote-pi/dist/protocol/types.d.ts +393 -0
  307. package/node_modules/remote-pi/dist/protocol/types.js +2 -0
  308. package/node_modules/remote-pi/dist/protocol/types.js.map +1 -0
  309. package/node_modules/remote-pi/dist/rooms.d.ts +29 -0
  310. package/node_modules/remote-pi/dist/rooms.js +57 -0
  311. package/node_modules/remote-pi/dist/rooms.js.map +1 -0
  312. package/node_modules/remote-pi/dist/session/address.d.ts +49 -0
  313. package/node_modules/remote-pi/dist/session/address.js +58 -0
  314. package/node_modules/remote-pi/dist/session/address.js.map +1 -0
  315. package/node_modules/remote-pi/dist/session/agent_bridge.d.ts +55 -0
  316. package/node_modules/remote-pi/dist/session/agent_bridge.js +146 -0
  317. package/node_modules/remote-pi/dist/session/agent_bridge.js.map +1 -0
  318. package/node_modules/remote-pi/dist/session/bridge.d.ts +37 -0
  319. package/node_modules/remote-pi/dist/session/bridge.js +130 -0
  320. package/node_modules/remote-pi/dist/session/bridge.js.map +1 -0
  321. package/node_modules/remote-pi/dist/session/broker.d.ts +189 -0
  322. package/node_modules/remote-pi/dist/session/broker.js +507 -0
  323. package/node_modules/remote-pi/dist/session/broker.js.map +1 -0
  324. package/node_modules/remote-pi/dist/session/broker_remote.d.ts +74 -0
  325. package/node_modules/remote-pi/dist/session/broker_remote.js +583 -0
  326. package/node_modules/remote-pi/dist/session/broker_remote.js.map +1 -0
  327. package/node_modules/remote-pi/dist/session/cwd_lock.d.ts +33 -0
  328. package/node_modules/remote-pi/dist/session/cwd_lock.js +126 -0
  329. package/node_modules/remote-pi/dist/session/cwd_lock.js.map +1 -0
  330. package/node_modules/remote-pi/dist/session/envelope.d.ts +33 -0
  331. package/node_modules/remote-pi/dist/session/envelope.js +117 -0
  332. package/node_modules/remote-pi/dist/session/envelope.js.map +1 -0
  333. package/node_modules/remote-pi/dist/session/global_config.d.ts +33 -0
  334. package/node_modules/remote-pi/dist/session/global_config.js +73 -0
  335. package/node_modules/remote-pi/dist/session/global_config.js.map +1 -0
  336. package/node_modules/remote-pi/dist/session/ipc.d.ts +27 -0
  337. package/node_modules/remote-pi/dist/session/ipc.js +22 -0
  338. package/node_modules/remote-pi/dist/session/ipc.js.map +1 -0
  339. package/node_modules/remote-pi/dist/session/leader_election.d.ts +32 -0
  340. package/node_modules/remote-pi/dist/session/leader_election.js +106 -0
  341. package/node_modules/remote-pi/dist/session/leader_election.js.map +1 -0
  342. package/node_modules/remote-pi/dist/session/local_config.d.ts +55 -0
  343. package/node_modules/remote-pi/dist/session/local_config.js +157 -0
  344. package/node_modules/remote-pi/dist/session/local_config.js.map +1 -0
  345. package/node_modules/remote-pi/dist/session/mesh_message.d.ts +20 -0
  346. package/node_modules/remote-pi/dist/session/mesh_message.js +28 -0
  347. package/node_modules/remote-pi/dist/session/mesh_message.js.map +1 -0
  348. package/node_modules/remote-pi/dist/session/mesh_node.d.ts +116 -0
  349. package/node_modules/remote-pi/dist/session/mesh_node.js +573 -0
  350. package/node_modules/remote-pi/dist/session/mesh_node.js.map +1 -0
  351. package/node_modules/remote-pi/dist/session/peer.d.ts +139 -0
  352. package/node_modules/remote-pi/dist/session/peer.js +451 -0
  353. package/node_modules/remote-pi/dist/session/peer.js.map +1 -0
  354. package/node_modules/remote-pi/dist/session/peer_inventory.d.ts +13 -0
  355. package/node_modules/remote-pi/dist/session/peer_inventory.js +48 -0
  356. package/node_modules/remote-pi/dist/session/peer_inventory.js.map +1 -0
  357. package/node_modules/remote-pi/dist/session/peer_limits.d.ts +9 -0
  358. package/node_modules/remote-pi/dist/session/peer_limits.js +21 -0
  359. package/node_modules/remote-pi/dist/session/peer_limits.js.map +1 -0
  360. package/node_modules/remote-pi/dist/session/setup_wizard.d.ts +39 -0
  361. package/node_modules/remote-pi/dist/session/setup_wizard.js +63 -0
  362. package/node_modules/remote-pi/dist/session/setup_wizard.js.map +1 -0
  363. package/node_modules/remote-pi/dist/session/tool_gate.d.ts +5 -0
  364. package/node_modules/remote-pi/dist/session/tool_gate.js +11 -0
  365. package/node_modules/remote-pi/dist/session/tool_gate.js.map +1 -0
  366. package/node_modules/remote-pi/dist/session/tools.d.ts +24 -0
  367. package/node_modules/remote-pi/dist/session/tools.js +252 -0
  368. package/node_modules/remote-pi/dist/session/tools.js.map +1 -0
  369. package/node_modules/remote-pi/dist/session/wizard.d.ts +13 -0
  370. package/node_modules/remote-pi/dist/session/wizard.js +20 -0
  371. package/node_modules/remote-pi/dist/session/wizard.js.map +1 -0
  372. package/node_modules/remote-pi/dist/settings.d.ts +15 -0
  373. package/node_modules/remote-pi/dist/settings.js +52 -0
  374. package/node_modules/remote-pi/dist/settings.js.map +1 -0
  375. package/node_modules/remote-pi/dist/transport/peer_channel.d.ts +37 -0
  376. package/node_modules/remote-pi/dist/transport/peer_channel.js +98 -0
  377. package/node_modules/remote-pi/dist/transport/peer_channel.js.map +1 -0
  378. package/node_modules/remote-pi/dist/transport/pi_forward_client.d.ts +29 -0
  379. package/node_modules/remote-pi/dist/transport/pi_forward_client.js +62 -0
  380. package/node_modules/remote-pi/dist/transport/pi_forward_client.js.map +1 -0
  381. package/node_modules/remote-pi/dist/transport/relay_client.d.ts +91 -0
  382. package/node_modules/remote-pi/dist/transport/relay_client.js +206 -0
  383. package/node_modules/remote-pi/dist/transport/relay_client.js.map +1 -0
  384. package/node_modules/remote-pi/dist/ui/footer.d.ts +32 -0
  385. package/node_modules/remote-pi/dist/ui/footer.js +34 -0
  386. package/node_modules/remote-pi/dist/ui/footer.js.map +1 -0
  387. package/node_modules/remote-pi/docs/daemon.md +289 -0
  388. package/node_modules/remote-pi/package.json +88 -0
  389. package/node_modules/remote-pi/service-templates/launchd.plist.template +35 -0
  390. package/node_modules/remote-pi/service-templates/systemd.service.template +19 -0
  391. package/node_modules/remote-pi/service-templates/task-launcher.vbs.template +10 -0
  392. package/node_modules/remote-pi/service-templates/task-scheduler.xml.template +38 -0
  393. package/node_modules/remote-pi/skills/agent-network/SKILL.md +310 -0
  394. package/package.json +37 -12
  395. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool-diff/write-display-utils.ts +0 -29
  396. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference-core.ts → reference/session.ts} +0 -0
  397. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-aliases.ts → shell/aliases.ts} +0 -0
  398. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ATTRIBUTION.md +0 -0
  399. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-presentation.ts +0 -0
  400. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/index.ts +0 -0
  401. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/render-utils.ts +0 -0
  402. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/shiki-highlight.ts +0 -0
  403. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/types.ts +0 -0
@@ -1,22 +1,22 @@
1
1
  import type { ExtensionUIContext } from "@earendil-works/pi-coding-agent";
2
- import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import type { Client } from "@modelcontextprotocol/client";
3
3
  import {
4
- ElicitRequestSchema,
5
- ErrorCode,
6
- McpError,
4
+ ProtocolError,
5
+ ProtocolErrorCode,
7
6
  type ElicitRequest,
8
7
  type ElicitRequestFormParams,
9
8
  type ElicitRequestURLParams,
10
9
  type ElicitResult,
11
- } from "@modelcontextprotocol/sdk/types.js";
12
- import { AjvJsonSchemaValidator } from "@modelcontextprotocol/sdk/validation/ajv";
13
- import type { JsonSchemaType } from "@modelcontextprotocol/sdk/validation/types.js";
10
+ } from "@modelcontextprotocol/client";
11
+ import { AjvJsonSchemaValidator } from "@modelcontextprotocol/client/validators/ajv";
12
+ import type { JsonSchemaType } from "@modelcontextprotocol/client";
14
13
  import open from "open";
15
14
 
16
15
  export type ElicitationValue = string | number | boolean | string[] | undefined;
17
16
  type FormProperty = ElicitRequestFormParams["requestedSchema"]["properties"][string];
17
+ type FieldCollectionResult = { status: "cancelled" } | { status: "collected"; value: ElicitationValue };
18
18
 
19
- export type ElicitationUIContext = ExtensionUIContext;
19
+ export type ElicitationUIContext = Pick<ExtensionUIContext, "select" | "input" | "notify">;
20
20
 
21
21
  export interface ElicitationHandlerOptions {
22
22
  serverName: string;
@@ -28,7 +28,7 @@ export interface ElicitationHandlerOptions {
28
28
  export type ServerElicitationConfig = Omit<ElicitationHandlerOptions, "serverName" | "onUrlAccepted">;
29
29
 
30
30
  export function registerElicitationHandler(client: Client, options: ElicitationHandlerOptions): void {
31
- client.setRequestHandler(ElicitRequestSchema, request =>
31
+ client.setRequestHandler("elicitation/create", request =>
32
32
  handleElicitationRequest(options, request));
33
33
  }
34
34
 
@@ -45,18 +45,19 @@ export async function handleFormElicitation(
45
45
  options: ElicitationHandlerOptions,
46
46
  params: ElicitRequestFormParams,
47
47
  ): Promise<ElicitResult> {
48
+ const properties = Object.entries(params.requestedSchema.properties);
48
49
  const decision = await options.ui.select(
49
50
  `MCP Input Request\nServer: ${options.serverName}\n\n${params.message}`,
50
51
  ["Continue", "Decline"],
51
52
  );
52
53
  if (decision === undefined) return { action: "cancel" };
53
54
  if (decision === "Decline") return { action: "decline" };
55
+ if (properties.length === 0) return { action: "accept", content: {} };
54
56
 
55
57
  const values: Record<string, ElicitationValue> = {};
56
- const properties = Object.entries(params.requestedSchema.properties);
57
58
  for (const [name, schema] of properties) {
58
59
  const value = await collectValidField(options.ui, params, name, schema);
59
- if (!("value" in value)) return { action: "cancel" };
60
+ if (value.status === "cancelled") return { action: "cancel" };
60
61
  values[name] = value.value;
61
62
  }
62
63
 
@@ -64,7 +65,7 @@ export async function handleFormElicitation(
64
65
  const content = coerceAndValidateFormValues(params, values);
65
66
  const action = await options.ui.select(
66
67
  formatReview(options.serverName, properties, content),
67
- properties.length > 0 ? ["Submit", "Edit", "Decline"] : ["Submit", "Decline"],
68
+ ["Submit", "Edit", "Decline"],
68
69
  );
69
70
  if (action === undefined) return { action: "cancel" };
70
71
  if (action === "Decline") return { action: "decline" };
@@ -77,7 +78,7 @@ export async function handleFormElicitation(
77
78
  if (!property) continue;
78
79
  const [name, schema] = property;
79
80
  const value = await collectValidField(options.ui, params, name, schema, values[name]);
80
- if (!("value" in value)) return { action: "cancel" };
81
+ if (value.status === "cancelled") return { action: "cancel" };
81
82
  values[name] = value.value;
82
83
  }
83
84
  }
@@ -88,11 +89,11 @@ async function collectValidField(
88
89
  name: string,
89
90
  schema: FormProperty,
90
91
  current?: ElicitationValue,
91
- ): Promise<{ cancelled: true } | { cancelled: false; value: ElicitationValue }> {
92
+ ): Promise<FieldCollectionResult> {
92
93
  const required = params.requestedSchema.required?.includes(name) === true;
93
94
  while (true) {
94
95
  const result = await collectField(ui, params, name, schema, current);
95
- if (!("value" in result)) return result;
96
+ if (result.status === "cancelled") return result;
96
97
  try {
97
98
  coerceAndValidateFormValues({
98
99
  ...params,
@@ -116,7 +117,7 @@ async function collectField(
116
117
  name: string,
117
118
  schema: FormProperty,
118
119
  current?: ElicitationValue,
119
- ): Promise<{ cancelled: true } | { cancelled: false; value: ElicitationValue }> {
120
+ ): Promise<FieldCollectionResult> {
120
121
  const required = params.requestedSchema.required?.includes(name) === true;
121
122
  const title = [schema.title ?? humanizeName(name), required ? "(required)" : "", schema.description]
122
123
  .filter(Boolean)
@@ -136,10 +137,10 @@ async function collectField(
136
137
  const omit = required ? undefined : uniqueAction("Omit", actions);
137
138
  if (omit) actions.push(omit);
138
139
  const action = await ui.select(title, actions);
139
- if (action === undefined) return { cancelled: true };
140
- if (action === useDefault) return { cancelled: false, value: schema.default };
141
- if (action === omit) return { cancelled: false, value: undefined };
142
- return { cancelled: false, value: choices[displays.indexOf(action)]?.value };
140
+ if (action === undefined) return { status: "cancelled" };
141
+ if (action === useDefault) return { status: "collected", value: schema.default };
142
+ if (action === omit) return { status: "collected", value: undefined };
143
+ return { status: "collected", value: choices[displays.indexOf(action)]?.value };
143
144
  }
144
145
 
145
146
  if (schema.type === "boolean") {
@@ -147,10 +148,10 @@ async function collectField(
147
148
  if (schema.default !== undefined) actions.push("Use default");
148
149
  if (!required) actions.push("Omit");
149
150
  const action = await ui.select(title, actions);
150
- if (action === undefined) return { cancelled: true };
151
- if (action === "Use default") return { cancelled: false, value: schema.default };
152
- if (action === "Omit") return { cancelled: false, value: undefined };
153
- return { cancelled: false, value: action === "Yes" };
151
+ if (action === undefined) return { status: "cancelled" };
152
+ if (action === "Use default") return { status: "collected", value: schema.default };
153
+ if (action === "Omit") return { status: "collected", value: undefined };
154
+ return { status: "collected", value: action === "Yes" };
154
155
  }
155
156
 
156
157
  if (schema.type === "array") {
@@ -158,9 +159,9 @@ async function collectField(
158
159
  if (schema.default !== undefined) actions.push("Use default");
159
160
  if (!required) actions.push("Omit");
160
161
  const action = await ui.select(title, actions);
161
- if (action === undefined) return { cancelled: true };
162
- if (action === "Use default") return { cancelled: false, value: schema.default };
163
- if (action === "Omit") return { cancelled: false, value: undefined };
162
+ if (action === undefined) return { status: "cancelled" };
163
+ if (action === "Use default") return { status: "collected", value: schema.default };
164
+ if (action === "Omit") return { status: "collected", value: undefined };
164
165
 
165
166
  const choices = extractMultiSelectOptions(schema);
166
167
  const selected = new Set(Array.isArray(current) ? current : []);
@@ -168,8 +169,8 @@ async function collectField(
168
169
  const displays = uniqueLabels(choices.map(choice => selected.has(choice.value) ? `✓ ${choice.display}` : choice.display));
169
170
  const done = uniqueAction("Done", displays);
170
171
  const picked = await ui.select(title, [...displays, done]);
171
- if (picked === undefined) return { cancelled: true };
172
- if (picked === done) return { cancelled: false, value: [...selected] };
172
+ if (picked === undefined) return { status: "cancelled" };
173
+ if (picked === done) return { status: "collected", value: [...selected] };
173
174
  const choice = choices[displays.indexOf(picked)];
174
175
  if (!choice) continue;
175
176
  if (selected.has(choice.value)) selected.delete(choice.value);
@@ -181,11 +182,11 @@ async function collectField(
181
182
  if (schema.default !== undefined) actions.push("Use default");
182
183
  if (!required) actions.push("Omit");
183
184
  const action = await ui.select(title, actions);
184
- if (action === undefined) return { cancelled: true };
185
- if (action === "Use default") return { cancelled: false, value: schema.default };
186
- if (action === "Omit") return { cancelled: false, value: undefined };
185
+ if (action === undefined) return { status: "cancelled" };
186
+ if (action === "Use default") return { status: "collected", value: schema.default };
187
+ if (action === "Omit") return { status: "collected", value: undefined };
187
188
  const entered = await ui.input(title, current === undefined ? undefined : String(current));
188
- return entered === undefined ? { cancelled: true } : { cancelled: false, value: entered };
189
+ return entered === undefined ? { status: "cancelled" } : { status: "collected", value: entered };
189
190
  }
190
191
 
191
192
  export function coerceAndValidateFormValues(
@@ -305,16 +306,16 @@ export async function handleUrlElicitation(
305
306
  options: ElicitationHandlerOptions,
306
307
  params: ElicitRequestURLParams,
307
308
  ): Promise<ElicitResult> {
308
- if (!options.allowUrl) throw new McpError(ErrorCode.InvalidParams, "URL elicitation is not supported");
309
+ if (!options.allowUrl) throw new ProtocolError(ProtocolErrorCode.InvalidParams, "URL elicitation is not supported");
309
310
 
310
311
  let parsed: URL;
311
312
  try {
312
313
  parsed = new URL(params.url);
313
314
  } catch {
314
- throw new McpError(ErrorCode.InvalidParams, "URL elicitation supplied an invalid URL");
315
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, "URL elicitation supplied an invalid URL");
315
316
  }
316
317
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
317
- throw new McpError(ErrorCode.InvalidParams, "URL elicitation only supports HTTP and HTTPS URLs");
318
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, "URL elicitation only supports HTTP and HTTPS URLs");
318
319
  }
319
320
 
320
321
  const decision = await options.ui.select([
@@ -17,8 +17,8 @@ export interface McpUiErrorContext {
17
17
  export class McpUiError extends Error {
18
18
  readonly code: string;
19
19
  readonly context: McpUiErrorContext;
20
- readonly recoveryHint?: string;
21
- readonly cause?: Error;
20
+ readonly recoveryHint: string | undefined;
21
+ readonly cause: Error | undefined;
22
22
 
23
23
  constructor(
24
24
  message: string,
@@ -65,9 +65,9 @@ export class ResourceFetchError extends McpUiError {
65
65
  ) {
66
66
  super(`Failed to fetch UI resource "${uri}": ${reason}`, {
67
67
  code: "RESOURCE_FETCH_ERROR",
68
- context: { uri, server: options?.server },
68
+ context: { uri, ...(options?.server !== undefined ? { server: options.server } : {}) },
69
69
  recoveryHint: "Check that the MCP server is connected and the resource URI is valid.",
70
- cause: options?.cause,
70
+ ...(options?.cause !== undefined ? { cause: options.cause } : {}),
71
71
  });
72
72
  this.name = "ResourceFetchError";
73
73
  }
@@ -84,7 +84,11 @@ export class ResourceParseError extends McpUiError {
84
84
  ) {
85
85
  super(`Invalid UI resource "${uri}": ${reason}`, {
86
86
  code: "RESOURCE_PARSE_ERROR",
87
- context: { uri, server: options?.server, mimeType: options?.mimeType },
87
+ context: {
88
+ uri,
89
+ ...(options?.server !== undefined ? { server: options.server } : {}),
90
+ ...(options?.mimeType !== undefined ? { mimeType: options.mimeType } : {}),
91
+ },
88
92
  recoveryHint: "Ensure the resource returns valid HTML with the correct MIME type.",
89
93
  });
90
94
  this.name = "ResourceParseError";
@@ -98,9 +102,9 @@ export class BridgeConnectionError extends McpUiError {
98
102
  constructor(reason: string, options?: { session?: string; cause?: Error }) {
99
103
  super(`AppBridge connection failed: ${reason}`, {
100
104
  code: "BRIDGE_CONNECTION_ERROR",
101
- context: { session: options?.session },
105
+ context: options?.session !== undefined ? { session: options.session } : {},
102
106
  recoveryHint: "Check browser console for detailed errors. The iframe may have failed to load.",
103
- cause: options?.cause,
107
+ ...(options?.cause !== undefined ? { cause: options.cause } : {}),
104
108
  });
105
109
  this.name = "BridgeConnectionError";
106
110
  }
@@ -142,9 +146,9 @@ export class SessionError extends McpUiError {
142
146
  ) {
143
147
  super(`Session error: ${reason}`, {
144
148
  code: "SESSION_ERROR",
145
- context: { session: options?.session },
149
+ context: options?.session !== undefined ? { session: options.session } : {},
146
150
  recoveryHint: "The session may have expired or been closed. Try opening the UI again.",
147
- cause: options?.cause,
151
+ ...(options?.cause !== undefined ? { cause: options.cause } : {}),
148
152
  });
149
153
  this.name = "SessionError";
150
154
  }
@@ -160,9 +164,9 @@ export class ServerError extends McpUiError {
160
164
  ) {
161
165
  super(`UI server error: ${reason}`, {
162
166
  code: "SERVER_ERROR",
163
- context: { port: options?.port },
167
+ context: options?.port !== undefined ? { port: options.port } : {},
164
168
  recoveryHint: "Check if the port is available. Another process may be using it.",
165
- cause: options?.cause,
169
+ ...(options?.cause !== undefined ? { cause: options.cause } : {}),
166
170
  });
167
171
  this.name = "ServerError";
168
172
  }
@@ -179,9 +183,9 @@ export class McpServerError extends McpUiError {
179
183
  ) {
180
184
  super(`MCP server "${server}" error: ${reason}`, {
181
185
  code: "MCP_SERVER_ERROR",
182
- context: { server, tool: options?.tool },
186
+ context: { server, ...(options?.tool !== undefined ? { tool: options.tool } : {}) },
183
187
  recoveryHint: "Check that the MCP server is running and responsive.",
184
- cause: options?.cause,
188
+ ...(options?.cause !== undefined ? { cause: options.cause } : {}),
185
189
  });
186
190
  this.name = "McpServerError";
187
191
  }
@@ -196,8 +200,8 @@ export function wrapError(error: unknown, context?: McpUiErrorContext): McpUiErr
196
200
  return new McpUiError(error.message, {
197
201
  code: error.code,
198
202
  context: { ...error.context, ...context },
199
- recoveryHint: error.recoveryHint,
200
- cause: error.cause,
203
+ ...(error.recoveryHint !== undefined ? { recoveryHint: error.recoveryHint } : {}),
204
+ ...(error.cause !== undefined ? { cause: error.cause } : {}),
201
205
  });
202
206
  }
203
207
 
@@ -206,8 +210,8 @@ export function wrapError(error: unknown, context?: McpUiErrorContext): McpUiErr
206
210
 
207
211
  return new McpUiError(message, {
208
212
  code: "UNKNOWN_ERROR",
209
- context,
210
- cause,
213
+ ...(context !== undefined ? { context } : {}),
214
+ ...(cause !== undefined ? { cause } : {}),
211
215
  });
212
216
  }
213
217
 
@@ -2,9 +2,11 @@ import type { UiHostContext, UiResourceContent, UiResourceCsp } from "./types.ts
2
2
 
3
3
  // Use locally bundled AppBridge to avoid CDN Zod bundling issues
4
4
  const DEFAULT_APP_BRIDGE_MODULE_URL = "/app-bridge.bundle.js";
5
+ const APP_SANDBOX = "allow-scripts allow-forms allow-modals allow-popups allow-downloads";
5
6
 
6
7
  export interface HostHtmlTemplateInput {
7
8
  sessionToken: string;
9
+ uiResourceToken: string;
8
10
  serverName: string;
9
11
  toolName: string;
10
12
  toolArgs: Record<string, unknown>;
@@ -20,6 +22,7 @@ export function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string {
20
22
  const hostContext = input.hostContext ?? {};
21
23
 
22
24
  const sessionToken = safeInlineJSON(input.sessionToken);
25
+ const uiResourceToken = safeInlineJSON(input.uiResourceToken);
23
26
  const toolArgs = safeInlineJSON(input.toolArgs);
24
27
  const serverName = safeInlineJSON(input.serverName);
25
28
  const toolName = safeInlineJSON(input.toolName);
@@ -109,7 +112,7 @@ export function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string {
109
112
  </div>
110
113
  </header>
111
114
  <main>
112
- <iframe id="mcp-app" sandbox="allow-scripts allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-downloads" referrerpolicy="no-referrer"></iframe>
115
+ <iframe id="mcp-app" sandbox="${APP_SANDBOX}" referrerpolicy="no-referrer"></iframe>
113
116
  </main>
114
117
  <div class="overlay" id="error-overlay">
115
118
  <div class="panel">
@@ -127,6 +130,7 @@ export function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string {
127
130
  import { AppBridge, PostMessageTransport } from ${moduleUrl};
128
131
 
129
132
  const SESSION_TOKEN = ${sessionToken};
133
+ const UI_RESOURCE_TOKEN = ${uiResourceToken};
130
134
  const SERVER_NAME = ${serverName};
131
135
  const TOOL_NAME = ${toolName};
132
136
  const TOOL_ARGS = ${toolArgs};
@@ -222,10 +226,10 @@ export function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string {
222
226
  }
223
227
  const result = await post("/proxy/tools/call", params);
224
228
  // Notify agent about the tool call
225
- await post("/proxy/ui/message", {
226
- type: "intent",
227
- intent: "call_tool",
228
- params: { tool: params.name, arguments: params.arguments, isError: result.isError }
229
+ await post("/proxy/ui/generated-tool-call-intent", {
230
+ tool: params.name,
231
+ arguments: params.arguments,
232
+ isError: result.isError
229
233
  }).catch(() => {});
230
234
  return result;
231
235
  };
@@ -236,6 +240,7 @@ export function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string {
236
240
  // Also listen for raw postMessage events with custom types (notify, prompt, intent, etc.)
237
241
  // These bypass the AppBridge protocol but are used by some MCP UI implementations
238
242
  window.addEventListener("message", async (event) => {
243
+ if (event.source !== iframe.contentWindow) return;
239
244
  const data = event.data;
240
245
  if (!data || typeof data !== "object") return;
241
246
 
@@ -300,7 +305,7 @@ export function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string {
300
305
 
301
306
  // Connect bridge BEFORE loading iframe to ensure we're listening when the app sends ui/initialize
302
307
  try {
303
- const transport = new PostMessageTransport(iframe.contentWindow, null);
308
+ const transport = new PostMessageTransport(iframe.contentWindow, iframe.contentWindow);
304
309
  await bridge.connect(transport);
305
310
  } catch (error) {
306
311
  console.error("[host] Bridge connection failed:", error);
@@ -310,7 +315,7 @@ export function buildHostHtmlTemplate(input: HostHtmlTemplateInput): string {
310
315
  const iframeLoaded = new Promise((resolve) => {
311
316
  iframe.onload = resolve;
312
317
  });
313
- iframe.src = "/ui-app?session=" + encodeURIComponent(SESSION_TOKEN);
318
+ iframe.src = "/ui-app?resource=" + encodeURIComponent(UI_RESOURCE_TOKEN);
314
319
  await iframeLoaded;
315
320
 
316
321
  const eventSource = new EventSource("/events?session=" + encodeURIComponent(SESSION_TOKEN));
@@ -399,6 +404,7 @@ export function buildCspMetaContent(csp: UiResourceCsp | undefined): string {
399
404
 
400
405
  return [
401
406
  "default-src 'none'",
407
+ `sandbox ${APP_SANDBOX}`,
402
408
  toDirective("script-src", ["'self'", "'unsafe-inline'"], resourceDomains),
403
409
  toDirective("style-src", ["'self'", "'unsafe-inline'"], resourceDomains),
404
410
  toDirective("font-src", ["'self'"], resourceDomains),
@@ -1,8 +1,9 @@
1
- import type { ExtensionAPI, ExtensionContext, ToolInfo } from "@earendil-works/pi-coding-agent";
1
+ import type { AgentToolUpdateCallback, ExtensionAPI, ExtensionContext, ToolInfo } from "@earendil-works/pi-coding-agent";
2
2
  import type { McpExtensionState } from "./state.ts";
3
3
  import type { DirectToolSpec, McpAdapterOptions, McpConfig, PromptMetadata } from "./types.ts";
4
4
  import type { McpOAuthRuntime } from "./mcp-auth-flow.ts";
5
5
  import { Type } from "typebox";
6
+ import type { TSchema } from "typebox";
6
7
  import { showStatus, showTools, showPrompts, reconnectServer, reconnectServers, authenticateServer, logoutServer, openMcpAuthPanel, openMcpPanel, openMcpSetup } from "./commands.ts";
7
8
  import { cloneMcpConfig, loadMcpConfig, writeProjectServerDisabledOverride } from "./config.ts";
8
9
  import { buildProxyDescription, createDirectToolExecutor, getMissingConfiguredDirectToolServers, resolveDirectTools } from "./direct-tools.ts";
@@ -18,14 +19,20 @@ import { toolErrorOverride } from "./error-signal.ts";
18
19
  import { createMcpRuntimeOwner, createOwnedUi, isAbortError, type McpRuntimeOwner } from "./runtime-owner.ts";
19
20
  import { publishMcpStatusShutdown } from "./mcp-status.ts";
20
21
  import { runMcpScript } from "./mcp-code.ts";
22
+ import { cleanupMaterializedBinaryResources } from "./tool-registrar.ts";
21
23
 
22
24
  export type { McpAdapterOptions } from "./types.ts";
23
25
  export {
24
26
  MCP_STATUS_EVENT,
25
27
  MCP_STATUS_SNAPSHOT_VERSION,
28
+ MCP_TOOL_APPROVAL_REQUEST_EVENT,
26
29
  type McpServerRuntimeStatus,
27
30
  type McpServerStatusSnapshot,
28
31
  type McpStatusSnapshot,
32
+ type McpToolApprovalDecision,
33
+ type McpToolApprovalHandler,
34
+ type McpToolApprovalOrigin,
35
+ type McpToolApprovalRequest,
29
36
  } from "./types.ts";
30
37
 
31
38
  const INIT_WAIT_TIMEOUT_MS = 30_000;
@@ -46,6 +53,18 @@ async function awaitWithTimeout<T>(promise: Promise<T>, timeoutMs: number): Prom
46
53
  }
47
54
  }
48
55
 
56
+ // TypeBox 1.x annotates raw objects passed to Type.Optional with an enumerable
57
+ // "~optional" key that survives serialization into provider tool schemas (Gemini
58
+ // rejects it with 400 INVALID_ARGUMENT). Prefer a real Type.Number schema; fall
59
+ // back to a plain raw schema for host TypeBox shims that omit Type.Number, since
60
+ // a property left out of `required` is optional by default.
61
+ function optionalNumber(options: { minimum?: number; description: string }): TSchema {
62
+ const number = (Type as { Number?: (opts: typeof options) => TSchema }).Number;
63
+ return typeof number === "function"
64
+ ? Type.Optional(number(options))
65
+ : ({ type: "number", ...options } as unknown as TSchema);
66
+ }
67
+
49
68
  function installMcpAdapter(pi: ExtensionAPI, options: McpAdapterOptions) {
50
69
  const sessionConfig = options.config !== undefined ? cloneMcpConfig(options.config) : undefined;
51
70
  const programmaticConfig = sessionConfig !== undefined;
@@ -150,13 +169,23 @@ function installMcpAdapter(pi: ExtensionAPI, options: McpAdapterOptions) {
150
169
  return resolveDirectTools(config, cache, prefix, envDirectToolOverride);
151
170
  }
152
171
 
172
+ function getActiveToolsIfReady(): string[] | undefined {
173
+ try {
174
+ return pi.getActiveTools?.();
175
+ } catch (error) {
176
+ if (error instanceof Error
177
+ && error.message.includes("Action methods cannot be called during extension loading")) return undefined;
178
+ throw error;
179
+ }
180
+ }
181
+
153
182
  function deactivateTools(toolNames: string[]): string[] {
154
183
  if (toolNames.length === 0) return [];
155
184
  const unregisterTool = (pi as ExtensionAPI & { unregisterTool?: (name: string) => boolean }).unregisterTool;
156
185
  const unregistered = toolNames.filter((toolName) => unregisterTool?.(toolName) === true);
157
186
  const fallbackNames = toolNames.filter((toolName) => !unregistered.includes(toolName));
158
187
  const remove = new Set(toolNames);
159
- const activeTools = pi.getActiveTools?.();
188
+ const activeTools = getActiveToolsIfReady();
160
189
  if (!activeTools || activeTools.length === 0) {
161
190
  for (const toolName of fallbackNames) fallbackDeactivatedTools.add(toolName);
162
191
  return unregistered;
@@ -188,7 +217,7 @@ function installMcpAdapter(pi: ExtensionAPI, options: McpAdapterOptions) {
188
217
  registerDirectTool(spec);
189
218
  registeredDirectTools.set(spec.prefixedName, fingerprint);
190
219
  if (fallbackDeactivatedTools.delete(spec.prefixedName)) {
191
- const activeTools = pi.getActiveTools?.();
220
+ const activeTools = getActiveToolsIfReady();
192
221
  if (activeTools && !activeTools.includes(spec.prefixedName)) {
193
222
  pi.setActiveTools([...activeTools, spec.prefixedName]);
194
223
  }
@@ -257,9 +286,13 @@ function installMcpAdapter(pi: ExtensionAPI, options: McpAdapterOptions) {
257
286
  });
258
287
 
259
288
  function startInitialization(ctx: ExtensionContext, owner: McpRuntimeOwner, oauthRuntime: McpOAuthRuntime, generation: number, staleReason: string): Promise<void> {
289
+ owner.addCleanup(() => cleanupMaterializedBinaryResources(owner.signal));
260
290
  const promise = initializeMcp(pi, ctx, owner, {
261
291
  ...(programmaticConfig || options.configPath !== undefined
262
- ? { configPath: earlyConfigPath, config: sessionConfig }
292
+ ? {
293
+ ...(earlyConfigPath !== undefined ? { configPath: earlyConfigPath } : {}),
294
+ ...(sessionConfig !== undefined ? { config: sessionConfig } : {}),
295
+ }
263
296
  : {}),
264
297
  oauthRuntime,
265
298
  statusEvents: pi.events,
@@ -427,7 +460,11 @@ function installMcpAdapter(pi: ExtensionAPI, options: McpAdapterOptions) {
427
460
  }
428
461
 
429
462
  const [, subcommand, argumentPrefix] = argumentMatch;
430
- if ((subcommand !== "reconnect" && subcommand !== "logout" && subcommand !== "disable" && subcommand !== "enable") || !state) return null;
463
+ if (
464
+ (subcommand !== "reconnect" && subcommand !== "logout" && subcommand !== "disable" && subcommand !== "enable")
465
+ || argumentPrefix === undefined
466
+ || !state
467
+ ) return null;
431
468
 
432
469
  const servers = Object.keys(state.config.mcpServers)
433
470
  .filter((serverName) => serverName.startsWith(argumentPrefix.trimStart()))
@@ -609,17 +646,16 @@ function installMcpAdapter(pi: ExtensionAPI, options: McpAdapterOptions) {
609
646
 
610
647
  if (earlyConfig.settings?.scriptMode !== false) {
611
648
  (pi.registerTool as (tool: unknown) => unknown)({
612
- name: "mcp_script",
649
+ name: "mcpScript",
613
650
  label: "MCP Script",
614
651
  description: "Run trusted JavaScript that makes multiple MCP tool calls in one request — loop, filter, chain, or fan out between calls. For a single MCP call, search, describe, status check, or auth action, use the mcp tool instead. Discover with await tools.search({ query }) — resolves to { items: [{ path, name, server, description? }], total, hasMore, nextOffset }, not an { ok, data } envelope. Inspect with await tools.describe({ path }) — resolves to the tool descriptor with inputTypeScript, or { path, error: { code, message, suggestions } }. Then call tools.call(path, args) — resolves to { ok: true, data } or { ok: false, error: { code, message } } — or use direct flat calls when the name is already known; use emit(value) for user-visible output. Load the mcp-scripting skill for the full workflow guide.",
615
652
  promptSnippet: "Batch multiple MCP tool calls in one JavaScript request (loop, filter, chain)",
616
653
  parameters: Type.Object({
617
654
  code: Type.String({ description: "Trusted JavaScript MCP script. Use tools.<prefixedToolName>(args) and emit(value)." }),
618
- // Raw JSON schema: host TypeBox shims may omit Type.Number (see index-lifecycle shim test).
619
- timeoutMs: Type.Optional({ type: "number", minimum: 1, description: "Execution timeout in milliseconds (default: 30000)" } as any),
655
+ timeoutMs: optionalNumber({ minimum: 1, description: "Execution timeout in milliseconds (default: 30000)" }),
620
656
  }),
621
657
  renderResult: renderMcpToolResult,
622
- async execute(_toolCallId, params: { code: string; timeoutMs?: number }, signal) {
658
+ async execute(_toolCallId: string, params: { code: string; timeoutMs?: number }, signal: AbortSignal | undefined) {
623
659
  const executeOwner = currentOwner;
624
660
  if (!state && initPromise) {
625
661
  try {
@@ -675,14 +711,13 @@ function installMcpAdapter(pi: ExtensionAPI, options: McpAdapterOptions) {
675
711
  search: Type.Optional(Type.String({ description: "Search tools by name/description" })),
676
712
  regex: Type.Optional(Type.Boolean({ description: "Treat search as regex (default: substring match)" })),
677
713
  includeSchemas: Type.Optional(Type.Boolean({ description: "Include parameter schemas in search results (default: true)" })),
678
- // Raw JSON schema: host TypeBox shims may omit Type.Number (see index-lifecycle shim test).
679
- limit: Type.Optional({ type: "number", minimum: 1, description: "Maximum search results to return (default: 12)" } as any),
680
- offset: Type.Optional({ type: "number", minimum: 0, description: "Search result offset (default: 0)" } as any),
714
+ limit: optionalNumber({ minimum: 1, description: "Maximum search results to return (default: 12)" }),
715
+ offset: optionalNumber({ minimum: 0, description: "Search result offset (default: 0)" }),
681
716
  server: Type.Optional(Type.String({ description: "Filter to specific server (also disambiguates tool calls)" })),
682
717
  action: Type.Optional(Type.String({ description: "Action: 'ui-messages', 'auth-start', or 'auth-complete'" })),
683
718
  }),
684
719
  renderResult: renderMcpToolResult,
685
- async execute(_toolCallId, params: {
720
+ async execute(_toolCallId: string, params: {
686
721
  tool?: string;
687
722
  args?: string | Record<string, unknown>;
688
723
  connect?: string;
@@ -695,7 +730,7 @@ function installMcpAdapter(pi: ExtensionAPI, options: McpAdapterOptions) {
695
730
  offset?: number;
696
731
  server?: string;
697
732
  action?: string;
698
- }, signal, _onUpdate, _ctx) {
733
+ }, signal: AbortSignal | undefined, _onUpdate: AgentToolUpdateCallback<Record<string, unknown>> | undefined, _ctx: ExtensionContext) {
699
734
  const executeOwner = currentOwner;
700
735
  let parsedArgs: Record<string, unknown> | undefined;
701
736
  if (params.args !== undefined && params.args !== "") {
@@ -824,7 +859,7 @@ function installMcpAdapter(pi: ExtensionAPI, options: McpAdapterOptions) {
824
859
  registerProxyTool(description);
825
860
  return;
826
861
  }
827
- const activeTools = pi.getActiveTools?.();
862
+ const activeTools = getActiveToolsIfReady();
828
863
  if (activeTools && !activeTools.includes("mcp")) {
829
864
  pi.setActiveTools([...activeTools, "mcp"]);
830
865
  }
@@ -849,8 +884,8 @@ export function createMcpAdapter(options: McpAdapterOptions = {}) {
849
884
  const factoryConfig = options.config !== undefined ? cloneMcpConfig(options.config) : undefined;
850
885
  return function mcpAdapter(pi: ExtensionAPI) {
851
886
  installMcpAdapter(pi, {
852
- configPath: options.configPath,
853
- config: factoryConfig !== undefined ? cloneMcpConfig(factoryConfig) : undefined,
887
+ ...(options.configPath !== undefined ? { configPath: options.configPath } : {}),
888
+ ...(factoryConfig !== undefined ? { config: cloneMcpConfig(factoryConfig) } : {}),
854
889
  });
855
890
  };
856
891
  }
@@ -124,7 +124,7 @@ export async function initializeMcp(
124
124
  if (config.settings?.sampling !== false && (hasUI || samplingAutoApprove)) {
125
125
  manager.setSamplingConfig({
126
126
  autoApprove: samplingAutoApprove,
127
- ui,
127
+ ...(ui !== undefined ? { ui } : {}),
128
128
  modelRegistry,
129
129
  getCurrentModel: () => owner.isActive() ? ctx.model : undefined,
130
130
  getSignal: () => owner.isActive()
@@ -166,6 +166,7 @@ export async function initializeMcp(
166
166
  failureTracker,
167
167
  failureMessages,
168
168
  approvedToolCalls,
169
+ approvalEvents: pi.events,
169
170
  uiResourceHandler,
170
171
  consentManager,
171
172
  uiServer: null,
@@ -175,12 +176,12 @@ export async function initializeMcp(
175
176
  await openUrl(pi, url, process.env.BROWSER, owner.signal);
176
177
  owner.throwIfInactive();
177
178
  },
178
- ui,
179
+ ...(ui !== undefined ? { ui } : {}),
179
180
  sendMessage: (message, options) => {
180
181
  if (!owner.isActive()) return;
181
182
  pi.sendMessage(message as unknown as Parameters<typeof pi.sendMessage>[0], options);
182
183
  },
183
- statusEvents: options.statusEvents,
184
+ ...(options.statusEvents !== undefined ? { statusEvents: options.statusEvents } : {}),
184
185
  };
185
186
  if (ownsOAuthRuntime) owner.addCleanup(() => shutdownOAuth(oauthRuntime));
186
187
  manager.setMetadataListChangedListener?.((serverName, reason) => {
@@ -345,8 +346,9 @@ export async function initializeMcp(
345
346
  missingCacheServers.filter(name => !results.some(r => r.name === name && r.connection)),
346
347
  10,
347
348
  async (name) => {
348
- const definition = config.mcpServers[name];
349
349
  try {
350
+ const definition = config.mcpServers[name];
351
+ if (!definition) throw new Error(`MCP server "${name}" is not configured`);
350
352
  const connection = await manager.connect(name, definition, runtimeSignal);
351
353
  if (connection.status === "needs-auth") {
352
354
  return { name, ok: false };
@@ -412,8 +414,8 @@ export async function initializeMcp(
412
414
 
413
415
  export function markKeepAliveAfterConnect(state: McpExtensionState, serverName: string): void {
414
416
  const definition = state.config.mcpServers[serverName];
415
- if (isServerDisabled(definition)) return;
416
- if ((definition?.lifecycle ?? "lazy") === "lazy-keep-alive") {
417
+ if (!definition || isServerDisabled(definition)) return;
418
+ if ((definition.lifecycle ?? "lazy") === "lazy-keep-alive") {
417
419
  state.lifecycle.markKeepAlive(serverName, definition);
418
420
  }
419
421
  }
@@ -485,7 +487,7 @@ export function updateMetadataCache(
485
487
  tools,
486
488
  resources,
487
489
  ...(prompts !== undefined ? { prompts } : {}),
488
- instructions: connection.instructions,
490
+ ...(connection.instructions !== undefined ? { instructions: connection.instructions } : {}),
489
491
  cachedAt: Date.now(),
490
492
  };
491
493
 
@@ -1,12 +1,12 @@
1
1
  import { Ajv } from "ajv";
2
2
  import Ajv2020Import from "ajv/dist/2020.js";
3
3
  import addFormatsImport from "ajv-formats";
4
- import { AjvJsonSchemaValidator } from "@modelcontextprotocol/sdk/validation/ajv";
4
+ import { AjvJsonSchemaValidator } from "@modelcontextprotocol/client/validators/ajv";
5
5
  import type {
6
6
  JsonSchemaType,
7
7
  JsonSchemaValidator,
8
8
  jsonSchemaValidator as JsonSchemaValidatorProvider,
9
- } from "@modelcontextprotocol/sdk/validation/types.js";
9
+ } from "@modelcontextprotocol/client";
10
10
 
11
11
  // ajv-formats types target its bundled ajv; the runtime accepts both instances.
12
12
  const addFormats = addFormatsImport as unknown as (instance: Ajv) => void;