@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,25 @@
1
- import { complete, type Api, type AssistantMessage, type Message, type Model, type TextContent } from "@earendil-works/pi-ai";
1
+ import { complete } from "@earendil-works/pi-ai/compat";
2
+ import type { Api, AssistantMessage, Message, Model, ProviderHeaders, TextContent } from "@earendil-works/pi-ai";
2
3
  import { truncateAtWord } from "./utils.ts";
3
4
  import { throwIfAborted } from "./abort.ts";
4
5
  import type { ExtensionUIContext, ModelRegistry } from "@earendil-works/pi-coding-agent";
5
- import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
6
+ import type { Client } from "@modelcontextprotocol/client";
6
7
  import {
7
- CreateMessageRequestSchema,
8
8
  type CreateMessageRequest,
9
9
  type CreateMessageResult,
10
10
  type ModelPreferences,
11
11
  type SamplingMessage,
12
12
  type SamplingMessageContentBlock,
13
- } from "@modelcontextprotocol/sdk/types.js";
13
+ } from "@modelcontextprotocol/client";
14
+
15
+ export type SamplingUIContext = Pick<ExtensionUIContext, "confirm">;
16
+ export type SamplingModelRegistry = Pick<ModelRegistry, "getAvailable" | "getApiKeyAndHeaders">;
14
17
 
15
18
  export interface SamplingHandlerOptions {
16
19
  serverName: string;
17
20
  autoApprove: boolean;
18
- ui?: ExtensionUIContext;
19
- modelRegistry: ModelRegistry;
21
+ ui?: SamplingUIContext;
22
+ modelRegistry: SamplingModelRegistry;
20
23
  getCurrentModel: () => Model<Api> | undefined;
21
24
  getSignal: () => AbortSignal | undefined;
22
25
  }
@@ -24,7 +27,7 @@ export interface SamplingHandlerOptions {
24
27
  export type ServerSamplingConfig = Omit<SamplingHandlerOptions, "serverName">;
25
28
 
26
29
  export function registerSamplingHandler(client: Client, options: SamplingHandlerOptions): void {
27
- client.setRequestHandler(CreateMessageRequestSchema, request => {
30
+ client.setRequestHandler("sampling/createMessage", request => {
28
31
  return handleSamplingRequest(options, request);
29
32
  });
30
33
  }
@@ -66,16 +69,16 @@ export async function handleSamplingRequest(
66
69
  const result = await complete(
67
70
  model,
68
71
  {
69
- systemPrompt: params.systemPrompt,
72
+ ...(params.systemPrompt !== undefined ? { systemPrompt: params.systemPrompt } : {}),
70
73
  messages,
71
74
  },
72
75
  {
73
- apiKey,
74
- headers,
76
+ ...(apiKey !== undefined ? { apiKey } : {}),
77
+ ...(headers !== undefined ? { headers } : {}),
75
78
  maxTokens: params.maxTokens,
76
- temperature: params.temperature,
77
- metadata: params.metadata as Record<string, unknown> | undefined,
78
- signal,
79
+ ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),
80
+ ...(params.metadata !== undefined ? { metadata: params.metadata as Record<string, unknown> } : {}),
81
+ ...(signal ? { signal } : {}),
79
82
  },
80
83
  );
81
84
 
@@ -127,7 +130,7 @@ async function resolveSamplingModel(
127
130
  ): Promise<{
128
131
  model: Model<Api>;
129
132
  apiKey?: string;
130
- headers?: Record<string, string>;
133
+ headers?: ProviderHeaders;
131
134
  }> {
132
135
  const candidates: Model<Api>[] = [];
133
136
  const availableModels = options.modelRegistry.getAvailable();
@@ -160,7 +163,11 @@ async function resolveSamplingModel(
160
163
  errors.push(`${model.provider}/${model.id}: ${auth.error}`);
161
164
  continue;
162
165
  }
163
- return { model, apiKey: auth.apiKey, headers: auth.headers };
166
+ return {
167
+ model,
168
+ ...(auth.apiKey !== undefined ? { apiKey: auth.apiKey } : {}),
169
+ ...(auth.headers !== undefined ? { headers: auth.headers } : {}),
170
+ };
164
171
  }
165
172
 
166
173
  if (errors.length > 0) {
@@ -82,7 +82,8 @@ export function scoreToolMatch(tool: ToolMetadata, server: string, query: string
82
82
  if (!phraseMatched && (queryTokens.length <= 2 ? coverage !== 1 : coverage < 0.6)) return null;
83
83
 
84
84
  score += coverage === 1 ? 25 : Math.round(coverage * 10);
85
- if (tokenize(fields.name).includes(queryTokens[0])) score += 8;
85
+ const firstQueryToken = queryTokens[0];
86
+ if (firstQueryToken !== undefined && tokenize(fields.name).includes(firstQueryToken)) score += 8;
86
87
  if (wholeFieldExact) score += 20;
87
88
  return score;
88
89
  }
@@ -1,18 +1,17 @@
1
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
- import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
1
+ import { mkdirSync } from "node:fs";
4
2
  import {
3
+ Client,
4
+ SdkHttpError,
5
+ SSEClientTransport,
5
6
  StreamableHTTPClientTransport,
6
- StreamableHTTPError,
7
- } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
8
- import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
9
- import type { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
10
- import {
11
- ElicitationCompleteNotificationSchema,
7
+ UnauthorizedError,
12
8
  type GetPromptResult,
13
9
  type ReadResourceResult,
10
+ type RequestOptions,
14
11
  type UrlElicitationRequiredError,
15
- } from "@modelcontextprotocol/sdk/types.js";
12
+ type VersionNegotiationOptions,
13
+ } from "@modelcontextprotocol/client";
14
+ import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
16
15
  import { UnixSocketClientTransport } from "./unix-socket-transport.ts";
17
16
  import { probeMcpEndpoint } from "./mcp-probe.ts";
18
17
  import {
@@ -24,6 +23,7 @@ import {
24
23
  type ServerStreamResultPatchNotification,
25
24
  type Transport,
26
25
  type McpTraceSettings,
26
+ SERVER_STREAM_RESULT_PATCH_METHOD,
27
27
  serverStreamResultPatchNotificationSchema,
28
28
  } from "./types.ts";
29
29
  import { resolveNpxBinary } from "./npx-resolver.ts";
@@ -67,7 +67,26 @@ type HttpAuthProviderState =
67
67
  | { status: "implicit-challenged"; provider: McpOAuthProvider };
68
68
 
69
69
  function isUnauthorizedHttpError(error: unknown): boolean {
70
- return error instanceof UnauthorizedError || (error instanceof StreamableHTTPError && error.code === 401);
70
+ return error instanceof UnauthorizedError || (error instanceof SdkHttpError && error.status === 401);
71
+ }
72
+
73
+ function shouldFallbackToSse(error: unknown, definition: ServerDefinition): boolean {
74
+ if (definition.protocolVersion === "2026-07-28") return false;
75
+ return error instanceof SdkHttpError && [404, 405, 406, 415].includes(error.status);
76
+ }
77
+
78
+ function resolveVersionNegotiation(definition: ServerDefinition): VersionNegotiationOptions | undefined {
79
+ switch (definition.protocolVersion) {
80
+ case undefined:
81
+ case "legacy":
82
+ return undefined;
83
+ case "auto":
84
+ return { mode: "auto" };
85
+ case "2026-07-28":
86
+ return { mode: { pin: "2026-07-28" } };
87
+ default:
88
+ throw new Error(`Invalid MCP protocolVersion: ${String(definition.protocolVersion)}`);
89
+ }
71
90
  }
72
91
 
73
92
  function boundedStderrChunk(chunk: Buffer | string): Buffer {
@@ -307,7 +326,6 @@ export class McpServerManager {
307
326
  requestSignal?: AbortSignal,
308
327
  ): Promise<ServerConnection> {
309
328
  throwIfAborted(signal);
310
- const client = this.createClient(name);
311
329
 
312
330
  const tracingEnabled = isMcpTraceEnabled(definition, this.traceSettings);
313
331
  const traceWriter = tracingEnabled
@@ -317,7 +335,10 @@ export class McpServerManager {
317
335
  ? { record: event => traceWriter.write(event) }
318
336
  : undefined;
319
337
 
338
+ let client: Client;
320
339
  let transport: Transport;
340
+ let clientConnected = false;
341
+ let transportAlreadyTraced = false;
321
342
  let stderrTail: Buffer<ArrayBufferLike> = Buffer.alloc(0);
322
343
  const configuredTransports = [definition.command, definition.url, definition.socket]
323
344
  .filter(value => typeof value === "string" && value.length > 0);
@@ -325,7 +346,10 @@ export class McpServerManager {
325
346
  throw new Error(`Server ${name} must configure exactly one of command, url, or socket`);
326
347
  }
327
348
 
349
+ const requestOptions = this.buildRequestOptions(definition, requestSignal);
350
+
328
351
  if (definition.command) {
352
+ client = this.createClient(name, definition);
329
353
  let command = definition.command;
330
354
  let args = definition.args ?? [];
331
355
 
@@ -339,11 +363,13 @@ export class McpServerManager {
339
363
  }
340
364
  throwIfAborted(signal);
341
365
 
366
+ if (definition.pluginDataDir) mkdirSync(definition.pluginDataDir, { recursive: true });
367
+ const cwd = resolveConfigPath(definition.cwd) ?? this.defaultCwd;
342
368
  const stdioTransport = new StdioClientTransport({
343
369
  command,
344
370
  args,
345
- env: resolveEnv(definition.env, name),
346
- cwd: resolveConfigPath(definition.cwd) ?? this.defaultCwd,
371
+ env: resolveEnv(definition.env, name, definition.literalEnv === true),
372
+ ...(cwd !== undefined ? { cwd } : {}),
347
373
  stderr: definition.debug ? "inherit" : "pipe",
348
374
  });
349
375
  // Keep non-debug child diagnostics available for connection failures without
@@ -355,24 +381,48 @@ export class McpServerManager {
355
381
  }
356
382
  transport = stdioTransport;
357
383
  } else if (definition.url) {
358
- // HTTP transport with fallback
359
- transport = await this.createHttpTransport(definition, name, signal, requestSignal, traceObserver);
384
+ const httpConnection = await this.connectHttpClient(
385
+ definition,
386
+ name,
387
+ requestOptions,
388
+ signal,
389
+ traceObserver,
390
+ );
391
+ client = httpConnection.client;
392
+ transport = httpConnection.transport;
393
+ if (httpConnection.status === "needs-auth") {
394
+ return {
395
+ client,
396
+ transport,
397
+ definition,
398
+ tools: [],
399
+ resources: [],
400
+ prompts: [],
401
+ lastUsedAt: Date.now(),
402
+ inFlight: 0,
403
+ status: "needs-auth",
404
+ };
405
+ }
406
+ clientConnected = true;
407
+ transportAlreadyTraced = traceObserver !== undefined;
360
408
  } else {
409
+ client = this.createClient(name, definition);
361
410
  transport = new UnixSocketClientTransport(resolveConfigPath(definition.socket!)!);
362
411
  }
363
412
 
364
- if (traceObserver) {
413
+ if (traceObserver && !transportAlreadyTraced) {
365
414
  const traceTransportKindValue = traceTransportKind(definition, transport);
366
415
  transport = wrapTransportWithMcpTrace(transport, name, traceTransportKindValue, traceObserver);
367
416
  }
368
417
 
369
- throwIfAborted(signal);
370
- const requestOptions = this.buildRequestOptions(definition, requestSignal);
371
-
372
418
  try {
373
- await this.connectClientWithAbort(client, transport, requestOptions, signal);
419
+ throwIfAborted(signal);
420
+ if (!clientConnected) {
421
+ await this.connectClientWithAbort(client, transport, requestOptions, signal);
422
+ }
374
423
  this.attachAdapterNotificationHandlers(name, client);
375
424
 
425
+ const instructions = client.getInstructions?.();
376
426
  const connection: ServerConnection = {
377
427
  client,
378
428
  transport,
@@ -380,22 +430,15 @@ export class McpServerManager {
380
430
  tools: [],
381
431
  resources: [],
382
432
  prompts: [],
383
- instructions: client.getInstructions?.(),
433
+ ...(instructions !== undefined ? { instructions } : {}),
384
434
  lastUsedAt: Date.now(),
385
435
  inFlight: 0,
386
436
  status: "connected",
387
437
  };
388
438
 
389
439
  // Reflect the SDK's own close signal in connection status, guarded by
390
- // identity so a stale connection's late close (e.g. the old
391
- // connection from before a session-recovery reconnect) can never
392
- // clobber a fresh connection that has since taken its place in
393
- // `this.connections`. This intentionally uses `client.onclose`
394
- // (Protocol's public hook), not `transport.onclose` — the SDK's
395
- // Protocol takes ownership of that one internally for pending-request
396
- // rejection, and overwriting it would break that. `client.onerror` is
397
- // avoided too: it can fire on benign events (e.g. the optional GET
398
- // SSE stream failing) that don't mean the connection is closed.
440
+ // identity so a stale connection's late close can never clobber a fresh
441
+ // connection. The SDK client owns the transport callbacks.
399
442
  client.onclose = () => {
400
443
  if (this.connections.get(name) === connection) {
401
444
  connection.status = "closed";
@@ -417,8 +460,7 @@ export class McpServerManager {
417
460
  return connection;
418
461
  } catch (error) {
419
462
  // If connectClientWithAbort closed the transport, await that exact close.
420
- // Otherwise the SDK client owns its transport, so client.close() is the
421
- // single cleanup operation rather than closing the transport twice.
463
+ // Otherwise the SDK client owns its transport and performs cleanup once.
422
464
  const abortCleanup = abortCleanupPromises.get(transport);
423
465
  const abortCleanupFailed = error instanceof AggregateError && error.message === "MCP connection abort cleanup failed";
424
466
  const cleanupResults = abortCleanupFailed
@@ -432,8 +474,8 @@ export class McpServerManager {
432
474
  reportedError = new AggregateError([error, ...cleanupFailures], "MCP connection setup failed");
433
475
  }
434
476
 
435
- // Check for UnauthorizedError - server requires OAuth. A cleanup failure
436
- // remains a setup failure rather than being hidden behind needs-auth.
477
+ // A cleanup failure remains a setup failure rather than being hidden
478
+ // behind needs-auth.
437
479
  if (isUnauthorizedHttpError(error) && supportsOAuth(definition) && cleanupFailures.length === 0) {
438
480
  return {
439
481
  client,
@@ -515,13 +557,15 @@ export class McpServerManager {
515
557
  };
516
558
  }
517
559
 
518
- private createClient(serverName: string): Client {
560
+ private createClient(serverName: string, definition: ServerDefinition): Client {
519
561
  const capabilities = this.buildClientCapabilities();
562
+ const versionNegotiation = resolveVersionNegotiation(definition);
520
563
  let client: Client;
521
564
  client = new Client(
522
565
  { name: `pi-mcp-${serverName}`, version: "1.0.0" },
523
566
  {
524
567
  jsonSchemaValidator: createJsonSchemaValidator(),
568
+ ...(versionNegotiation ? { versionNegotiation } : {}),
525
569
  ...(Object.keys(capabilities).length > 0 ? { capabilities } : {}),
526
570
  listChanged: {
527
571
  tools: {
@@ -552,7 +596,7 @@ export class McpServerManager {
552
596
  onUrlAccepted: elicitationId => this.rememberUrlElicitation(serverName, elicitationId),
553
597
  });
554
598
  if (this.elicitationConfig.allowUrl) {
555
- client.setNotificationHandler(ElicitationCompleteNotificationSchema, notification => {
599
+ client.setNotificationHandler("notifications/elicitation/complete", notification => {
556
600
  if (this.runtimeSignal?.aborted) return;
557
601
  const accepted = this.acceptedUrlElicitations.get(serverName);
558
602
  if (!accepted?.delete(notification.params.elicitationId)) return;
@@ -644,18 +688,19 @@ export class McpServerManager {
644
688
  accepted.add(elicitationId);
645
689
  }
646
690
 
647
- private async createHttpTransport(
691
+ private async connectHttpClient(
648
692
  definition: ServerDefinition,
649
693
  serverName: string,
694
+ requestOptions: RequestOptions | undefined,
650
695
  signal?: AbortSignal,
651
- requestSignal?: AbortSignal,
652
696
  traceObserver?: McpTraceObserver,
653
- ): Promise<Transport> {
697
+ ): Promise<{ client: Client; transport: Transport; status: "connected" | "needs-auth" }> {
654
698
  throwIfAborted(signal);
655
699
  const serverUrl = resolveServerUrl(definition)!;
656
700
  const url = new URL(serverUrl);
657
701
 
658
- // Resolve secret commands only for this connection attempt, without mutating config.
702
+ // Resolve secret commands only for this connection attempt, without
703
+ // mutating the persisted configuration.
659
704
  const hasCommandHeader = Object.values(definition.headers ?? {})
660
705
  .some(value => value.startsWith("!") && !value.startsWith("!!"));
661
706
  const headers = resolveCommandSecretsRecord(
@@ -663,7 +708,8 @@ export class McpServerManager {
663
708
  key => `MCP server "${serverName}" HTTP header "${key}"`,
664
709
  ) ?? {};
665
710
 
666
- // For bearer auth, add the token to headers BEFORE creating requestInit
711
+ // Resolve bearer auth before creating requestInit so every attempted
712
+ // transport receives the same headers.
667
713
  const commandBearer = definition.bearerToken?.startsWith("!") && !definition.bearerToken.startsWith("!!")
668
714
  ? definition.bearerToken
669
715
  : undefined;
@@ -682,98 +728,94 @@ export class McpServerManager {
682
728
  }
683
729
  }
684
730
 
685
- // Create request init with headers (Authorization now included for bearer auth)
686
731
  const requestInit = Object.keys(headers).length > 0 ? { headers } : undefined;
687
732
  const createAuthProvider = (): McpOAuthProvider => new McpOAuthProvider(
688
733
  serverName,
689
734
  serverUrl,
690
735
  extractOAuthConfig(definition),
691
- {
692
- onRedirect: async (_authUrl) => {
693
- // URL is captured by startAuth, no need to log
694
- },
695
- },
736
+ { onRedirect: async () => {} },
696
737
  this.authStorageOptions,
697
738
  this.oauthRuntime?.signal,
698
739
  );
699
740
 
700
- // Explicit OAuth must check the secure credential store before connecting.
741
+ // Explicit OAuth checks secure storage immediately. Implicit OAuth defers
742
+ // provider construction until the server proves authentication is needed.
701
743
  let authState: HttpAuthProviderState = supportsOAuth(definition)
702
744
  ? definition.auth === undefined
703
745
  ? { status: "implicit-deferred" }
704
746
  : { status: "explicit", provider: createAuthProvider() }
705
747
  : { status: "disabled" };
706
748
 
707
- // Try StreamableHTTP first (modern MCP servers). For implicit OAuth, defer
708
- // creating the provider until the server proves that authentication is needed.
709
- for (;;) {
749
+ const attempt = async (
750
+ kind: "streamable-http" | "sse",
751
+ ): Promise<
752
+ | { status: "connected"; client: Client; transport: Transport }
753
+ | { status: "failed"; client: Client; transport: Transport; error: unknown }
754
+ > => {
710
755
  const authProvider = "provider" in authState ? authState.provider : undefined;
711
- const streamableTransport = new StreamableHTTPClientTransport(url, {
712
- requestInit,
713
- authProvider,
714
- });
715
- const probeTransport = traceObserver
716
- ? wrapTransportWithMcpTrace(streamableTransport, serverName, "streamable-http", traceObserver)
717
- : streamableTransport;
718
- const testClient = new Client({ name: "pi-mcp-probe", version: "2.1.2" });
719
- let probeCleanupAttempted = false;
720
- try {
721
- await this.connectClientWithAbort(
722
- testClient,
723
- probeTransport,
724
- this.buildRequestOptions(definition, requestSignal),
725
- signal,
726
- );
727
- probeCleanupAttempted = true;
728
- try {
729
- await testClient.close();
730
- } catch (cleanupError) {
731
- throw new AggregateError([cleanupError], "MCP HTTP probe cleanup failed");
732
- }
756
+ const transportOptions = {
757
+ ...(requestInit !== undefined ? { requestInit } : {}),
758
+ ...(authProvider !== undefined ? { authProvider } : {}),
759
+ ...(authProvider !== undefined
760
+ && definition.oauth !== false
761
+ && definition.oauth?.skipIssuerMetadataValidation === true
762
+ ? { skipIssuerMetadataValidation: true }
763
+ : {}),
764
+ };
765
+ const baseTransport: Transport = kind === "streamable-http"
766
+ ? new StreamableHTTPClientTransport(url, transportOptions)
767
+ : new SSEClientTransport(url, transportOptions);
768
+ const transport = traceObserver
769
+ ? wrapTransportWithMcpTrace(baseTransport, serverName, kind, traceObserver)
770
+ : baseTransport;
771
+ const client = this.createClient(serverName, definition);
733
772
 
734
- // StreamableHTTP works - create fresh transport for actual use
735
- return new StreamableHTTPClientTransport(url, { requestInit, authProvider });
773
+ try {
774
+ await this.connectClientWithAbort(client, transport, requestOptions, signal);
775
+ return { status: "connected", client, transport };
736
776
  } catch (error) {
737
- if (error instanceof AggregateError && (
738
- error.message === "MCP connection abort cleanup failed" ||
739
- error.message === "MCP HTTP probe cleanup failed"
740
- )) {
741
- throw error;
742
- }
743
-
744
- // StreamableHTTP failed, close through the SDK client and try SSE fallback.
745
- // If connectClientWithAbort already owned the close, await that operation
746
- // instead of closing the same transport twice.
747
- if (!probeCleanupAttempted) {
748
- probeCleanupAttempted = true;
777
+ const abortCleanupFailed = error instanceof AggregateError
778
+ && error.message === "MCP connection abort cleanup failed";
779
+ if (!abortCleanupFailed) {
749
780
  try {
750
- await (abortCleanupPromises.get(probeTransport) ?? testClient.close());
781
+ await (abortCleanupPromises.get(transport) ?? client.close());
751
782
  } catch (cleanupError) {
752
- throw new AggregateError([error, cleanupError], "MCP HTTP probe cleanup failed");
783
+ throw new AggregateError([error, cleanupError], "MCP HTTP connection cleanup failed");
753
784
  }
754
785
  }
786
+ return { status: "failed", client, transport, error };
787
+ }
788
+ };
755
789
 
756
- // Host cancellation is not transport capability evidence; do not fall
757
- // through to SSE when the caller is trying to cancel the connect.
758
- if (signal?.aborted) {
759
- throwIfAborted(signal);
760
- }
761
-
762
- // An implicit URL-only server gets a provider only after a real auth
763
- // challenge. This keeps unauthenticated servers independent of storage.
764
- if (authState.status === "implicit-deferred" && isUnauthorizedHttpError(error)) {
765
- authState = { status: "implicit-challenged", provider: createAuthProvider() };
766
- continue;
767
- }
790
+ // Connect the real client once. Retry Streamable HTTP only for an implicit
791
+ // OAuth challenge; use SSE only for definitive endpoint incompatibility.
792
+ // Agent Plugins set httpTransport, and their declared transport is used without fallback.
793
+ let kind: "streamable-http" | "sse" = definition.httpTransport ?? "streamable-http";
794
+ for (;;) {
795
+ const result = await attempt(kind);
796
+ if (result.status === "connected") return result;
797
+ if (result.error instanceof AggregateError
798
+ && result.error.message === "MCP connection abort cleanup failed") {
799
+ throw result.error;
800
+ }
801
+ if (signal?.aborted) throwIfAborted(signal);
768
802
 
769
- // If this was an UnauthorizedError, don't try SSE - the server needs auth
770
- if (isUnauthorizedHttpError(error)) {
771
- throw error;
803
+ if (authState.status === "implicit-deferred" && isUnauthorizedHttpError(result.error)) {
804
+ authState = { status: "implicit-challenged", provider: createAuthProvider() };
805
+ continue;
806
+ }
807
+ if (isUnauthorizedHttpError(result.error)) {
808
+ if (supportsOAuth(definition)) {
809
+ return { client: result.client, transport: result.transport, status: "needs-auth" };
772
810
  }
811
+ throw result.error;
812
+ }
773
813
 
774
- // SSE is the legacy transport
775
- return new SSEClientTransport(url, { requestInit, authProvider });
814
+ if (definition.httpTransport === undefined && kind === "streamable-http" && shouldFallbackToSse(result.error, definition)) {
815
+ kind = "sse";
816
+ continue;
776
817
  }
818
+ throw result.error;
777
819
  }
778
820
  }
779
821
 
@@ -839,11 +881,15 @@ export class McpServerManager {
839
881
  }
840
882
 
841
883
  private attachAdapterNotificationHandlers(serverName: string, client: Client): void {
842
- client.setNotificationHandler(serverStreamResultPatchNotificationSchema, notification => {
843
- const listener = this.uiStreamListeners.get(notification.params.streamToken);
844
- if (!listener) return;
845
- listener(serverName, notification.params);
846
- });
884
+ client.setNotificationHandler(
885
+ SERVER_STREAM_RESULT_PATCH_METHOD,
886
+ { params: serverStreamResultPatchNotificationSchema.shape.params },
887
+ params => {
888
+ const listener = this.uiStreamListeners.get(params.streamToken);
889
+ if (!listener) return;
890
+ listener(serverName, params);
891
+ },
892
+ );
847
893
  }
848
894
 
849
895
  registerUiStreamListener(streamToken: string, listener: UiStreamListener): void {
@@ -984,6 +1030,10 @@ export class McpServerManager {
984
1030
  return false;
985
1031
  }
986
1032
 
1033
+ isConnecting(name: string): boolean {
1034
+ return this.connectPromises.has(name);
1035
+ }
1036
+
987
1037
  getConnection(name: string): ServerConnection | undefined {
988
1038
  return this.connections.get(name);
989
1039
  }
@@ -1024,11 +1074,13 @@ export class McpServerManager {
1024
1074
  /**
1025
1075
  * Resolve environment variables with interpolation.
1026
1076
  */
1027
- function resolveEnv(env: Record<string, string> | undefined, serverName: string): Record<string, string> {
1077
+ function resolveEnv(env: Record<string, string> | undefined, serverName: string, literalEnv = false): Record<string, string> {
1028
1078
  const resolved: Record<string, string> = {};
1029
1079
  for (const [key, value] of Object.entries(process.env)) {
1030
1080
  if (value !== undefined) resolved[key] = value;
1031
1081
  }
1082
+ if (literalEnv) return env ? { ...resolved, ...env } : resolved;
1083
+
1032
1084
  const overrides = resolveCommandSecretsRecord(
1033
1085
  env,
1034
1086
  key => `MCP server "${serverName}" stdio env "${key}"`,
@@ -20,8 +20,7 @@
20
20
  // many things other than "your session is gone"
21
21
  // - treat generic -32000/ConnectionClosed errors as session expiry
22
22
  // - treat AbortError/cancellation as a session failure
23
- import { StreamableHTTPError } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
24
- import { ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
23
+ import { ProtocolError, SdkHttpError } from "@modelcontextprotocol/client";
25
24
  import { logger } from "./logger.ts";
26
25
  import { throwIfAborted } from "./abort.ts";
27
26
  import { isServerDisabled, type McpConfig } from "./types.ts";
@@ -34,25 +33,25 @@ import type { McpServerManager, ServerConnection } from "./server-manager.ts";
34
33
  * gate response some servers emit before dispatching to a handler.
35
34
  *
36
35
  * `hadSessionId` must reflect the transport's session id from *before* the
37
- * call that produced `err` was made. The installed SDK (1.30.0) does not
38
- * clear `transport.sessionId` on a 404 response, so callers must capture it
39
- * before the call rather than rely on catch-time transport state.
36
+ * call that produced `err` was made. Callers must capture it before the call
37
+ * rather than rely on catch-time transport state.
40
38
  */
39
+ const CONNECTION_CLOSED_PROTOCOL_CODE = -32000;
41
40
  const SERVER_NOT_INITIALIZED_MCP_MESSAGES = new Set([
42
- `MCP error ${ErrorCode.ConnectionClosed}: Server not initialized`,
43
- `MCP error ${ErrorCode.ConnectionClosed}: Bad Request: Server not initialized`,
41
+ "Server not initialized",
42
+ "Bad Request: Server not initialized",
44
43
  ]);
45
44
 
46
45
  export function isTerminatedSession(err: unknown, hadSessionId: boolean): boolean {
47
46
  if (!hadSessionId) return false;
48
- if (err instanceof StreamableHTTPError) {
49
- return err.code === 404
50
- || (err.code === 400
47
+ if (err instanceof SdkHttpError) {
48
+ return err.status === 404
49
+ || (err.status === 400
51
50
  && /"code"\s*:\s*-32000/.test(err.message)
52
51
  && /"message"\s*:\s*"Bad Request: Server not initialized"/.test(err.message));
53
52
  }
54
- return err instanceof McpError
55
- && err.code === ErrorCode.ConnectionClosed
53
+ return err instanceof ProtocolError
54
+ && err.code === CONNECTION_CLOSED_PROTOCOL_CODE
56
55
  && SERVER_NOT_INITIALIZED_MCP_MESSAGES.has(err.message);
57
56
  }
58
57
 
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: mcp-scripting
3
- description: Write mcp_script JavaScript for discovering, inspecting, and calling MCP tools.
3
+ description: Write mcpScript JavaScript for discovering, inspecting, and calling MCP tools.
4
4
  ---
5
5
 
6
6
  # MCP scripting
7
7
 
8
- For multi-call MCP work, write ordinary JavaScript with loops, filtering, chaining, fan-out, or other logic between calls. Run that source with `mcp_script`; it is the primary MCP orchestration surface. For a single MCP search, describe, status check, auth action, or tool call, use `mcp` instead.
8
+ For multi-call MCP work, write ordinary JavaScript with loops, filtering, chaining, fan-out, or other logic between calls. Run that source with `mcpScript`; it is the primary MCP orchestration surface. For a single MCP search, describe, status check, auth action, or tool call, use `mcp` instead.
9
9
 
10
- Write the source naturally, then pass it as `mcp_script`'s `code` argument:
10
+ Write the source naturally, then pass it as `mcpScript`'s `code` argument:
11
11
 
12
12
  ```js
13
13
  const { items } = await tools.search({ query: "search issues", server: "github" });
@@ -1,4 +1,4 @@
1
- import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
1
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
2
  import type { ConsentManager } from "./consent-manager.ts";
3
3
  import type { McpLifecycleManager } from "./lifecycle.ts";
4
4
  import type { McpServerManager } from "./server-manager.ts";
@@ -48,6 +48,8 @@ export interface McpExtensionState {
48
48
  failureMessages: Map<string, string>;
49
49
  /** Session-only approvals keyed by server and original tool name. */
50
50
  approvedToolCalls: Map<string, true>;
51
+ /** Shared event bus used by permission extensions to broker MCP approvals. */
52
+ approvalEvents?: ExtensionAPI["events"];
51
53
  uiResourceHandler: UiResourceHandler;
52
54
  consentManager: ConsentManager;
53
55
  uiServer: UiServerHandle | null;