@ashx-j/lunr-dev 0.2.16-dev.9.1 → 0.2.19-dev.10.1

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 (255) hide show
  1. package/CHANGELOG.md +32 -1
  2. package/README.md +7 -1
  3. package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -0
  4. package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-thinking.js +44 -19
  6. package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
  7. package/dist/builtin-extensions/index.d.ts.map +1 -1
  8. package/dist/builtin-extensions/index.js +1 -0
  9. package/dist/builtin-extensions/index.js.map +1 -1
  10. package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
  11. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
  12. package/dist/builtin-extensions/lunr-computer-use.js +157 -0
  13. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
  14. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  15. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +10 -3
  16. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  17. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts +5 -1
  18. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts.map +1 -1
  19. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js +26 -4
  20. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js.map +1 -1
  21. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  22. package/dist/builtin-extensions/pi-mcp-adapter/index.js +37 -27
  23. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  24. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts +6 -1
  25. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  26. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +33 -8
  27. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  28. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  29. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +52 -23
  30. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  32. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +6 -2
  33. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  34. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts +1 -1
  35. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  36. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +5 -2
  37. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  38. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts +10 -0
  39. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts.map +1 -0
  40. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js +38 -0
  41. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js.map +1 -0
  42. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  43. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +3 -16
  44. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  45. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  46. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  47. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
  48. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  49. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -0
  50. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  51. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +70 -30
  52. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  53. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  54. package/dist/builtin-extensions/pi-web-access/index.js +103 -102
  55. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  56. package/dist/core/agent-session-services.d.ts.map +1 -1
  57. package/dist/core/agent-session-services.js +1 -1
  58. package/dist/core/agent-session-services.js.map +1 -1
  59. package/dist/core/computer-use/adapter.d.ts +23 -0
  60. package/dist/core/computer-use/adapter.d.ts.map +1 -0
  61. package/dist/core/computer-use/adapter.js +116 -0
  62. package/dist/core/computer-use/adapter.js.map +1 -0
  63. package/dist/core/computer-use/lease.d.ts +18 -0
  64. package/dist/core/computer-use/lease.d.ts.map +1 -0
  65. package/dist/core/computer-use/lease.js +129 -0
  66. package/dist/core/computer-use/lease.js.map +1 -0
  67. package/dist/core/computer-use/macos-runtime.d.ts +14 -0
  68. package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
  69. package/dist/core/computer-use/macos-runtime.js +148 -0
  70. package/dist/core/computer-use/macos-runtime.js.map +1 -0
  71. package/dist/core/computer-use/policy.d.ts +19 -0
  72. package/dist/core/computer-use/policy.d.ts.map +1 -0
  73. package/dist/core/computer-use/policy.js +66 -0
  74. package/dist/core/computer-use/policy.js.map +1 -0
  75. package/dist/core/computer-use/release.generated.d.ts +31 -0
  76. package/dist/core/computer-use/release.generated.d.ts.map +1 -0
  77. package/dist/core/computer-use/release.generated.js +36 -0
  78. package/dist/core/computer-use/release.generated.js.map +1 -0
  79. package/dist/core/computer-use/runtime.d.ts +13 -0
  80. package/dist/core/computer-use/runtime.d.ts.map +1 -0
  81. package/dist/core/computer-use/runtime.js +158 -0
  82. package/dist/core/computer-use/runtime.js.map +1 -0
  83. package/dist/core/computer-use/schemas.d.ts +88 -0
  84. package/dist/core/computer-use/schemas.d.ts.map +1 -0
  85. package/dist/core/computer-use/schemas.js +80 -0
  86. package/dist/core/computer-use/schemas.js.map +1 -0
  87. package/dist/core/computer-use/windows-desktop.d.ts +3 -0
  88. package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
  89. package/dist/core/computer-use/windows-desktop.js +48 -0
  90. package/dist/core/computer-use/windows-desktop.js.map +1 -0
  91. package/dist/core/computer-use/workflow.d.ts +24 -0
  92. package/dist/core/computer-use/workflow.d.ts.map +1 -0
  93. package/dist/core/computer-use/workflow.js +330 -0
  94. package/dist/core/computer-use/workflow.js.map +1 -0
  95. package/dist/core/keybindings.d.ts +2 -2
  96. package/dist/core/keybindings.d.ts.map +1 -1
  97. package/dist/core/keybindings.js +2 -2
  98. package/dist/core/keybindings.js.map +1 -1
  99. package/dist/core/model-runtime.d.ts +0 -3
  100. package/dist/core/model-runtime.d.ts.map +1 -1
  101. package/dist/core/model-runtime.js +1 -10
  102. package/dist/core/model-runtime.js.map +1 -1
  103. package/dist/core/package-manager.d.ts.map +1 -1
  104. package/dist/core/package-manager.js +1 -1
  105. package/dist/core/package-manager.js.map +1 -1
  106. package/dist/core/permissions.d.ts +1 -1
  107. package/dist/core/permissions.d.ts.map +1 -1
  108. package/dist/core/permissions.js +23 -7
  109. package/dist/core/permissions.js.map +1 -1
  110. package/dist/core/plan-mode.d.ts.map +1 -1
  111. package/dist/core/plan-mode.js +9 -0
  112. package/dist/core/plan-mode.js.map +1 -1
  113. package/dist/core/rollback.d.ts.map +1 -1
  114. package/dist/core/rollback.js +13 -90
  115. package/dist/core/rollback.js.map +1 -1
  116. package/dist/core/session-manager.d.ts +0 -1
  117. package/dist/core/session-manager.d.ts.map +1 -1
  118. package/dist/core/session-manager.js +21 -79
  119. package/dist/core/session-manager.js.map +1 -1
  120. package/dist/core/settings-manager.d.ts +6 -0
  121. package/dist/core/settings-manager.d.ts.map +1 -1
  122. package/dist/core/settings-manager.js +19 -0
  123. package/dist/core/settings-manager.js.map +1 -1
  124. package/dist/dev-cli.js +0 -0
  125. package/dist/gateway/agent-bridge.d.ts +6 -1
  126. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  127. package/dist/gateway/agent-bridge.js +23 -6
  128. package/dist/gateway/agent-bridge.js.map +1 -1
  129. package/dist/gateway/cron.d.ts +1 -1
  130. package/dist/gateway/cron.d.ts.map +1 -1
  131. package/dist/gateway/cron.js +23 -7
  132. package/dist/gateway/cron.js.map +1 -1
  133. package/dist/modes/interactive/components/footer.d.ts +4 -2
  134. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  135. package/dist/modes/interactive/components/footer.js +23 -32
  136. package/dist/modes/interactive/components/footer.js.map +1 -1
  137. package/dist/modes/interactive/components/processes-selector.d.ts +2 -3
  138. package/dist/modes/interactive/components/processes-selector.d.ts.map +1 -1
  139. package/dist/modes/interactive/components/processes-selector.js +5 -10
  140. package/dist/modes/interactive/components/processes-selector.js.map +1 -1
  141. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  142. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  143. package/dist/modes/interactive/components/settings-selector.js +20 -0
  144. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  145. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  146. package/dist/modes/interactive/interactive-mode.js +18 -8
  147. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  148. package/dist/modes/interactive/thinking-level-slash.d.ts +4 -0
  149. package/dist/modes/interactive/thinking-level-slash.d.ts.map +1 -0
  150. package/dist/modes/interactive/thinking-level-slash.js +23 -0
  151. package/dist/modes/interactive/thinking-level-slash.js.map +1 -0
  152. package/dist/node-runtime/adapter-AZMY335J.js +279 -0
  153. package/dist/node-runtime/{agent-session-services-IFJMSX7Z.js → agent-session-services-RSGP5GDN.js} +15 -12
  154. package/dist/node-runtime/{builtin-extensions-LYZ3BFWQ.js → builtin-extensions-7STLFW3A.js} +4 -3
  155. package/dist/node-runtime/chunk-2IDTZAG5.js +1415 -0
  156. package/dist/node-runtime/{chunk-7NBZ5P7I.js → chunk-4SJWFTUP.js} +1 -1
  157. package/dist/node-runtime/{chunk-AJX357CL.js → chunk-5NWQCSKR.js} +20 -1013
  158. package/dist/node-runtime/chunk-5OLJGVCB.js +68 -0
  159. package/dist/node-runtime/chunk-5Q45AVQG.js +108 -0
  160. package/dist/node-runtime/{chunk-TQNSPERU.js → chunk-5SQDLSZJ.js} +1 -1
  161. package/dist/node-runtime/{chunk-F4VQFJI2.js → chunk-6SPPH4FY.js} +4 -4
  162. package/dist/node-runtime/{chunk-PBC2Y6GS.js → chunk-6UB6NKA3.js} +29 -72
  163. package/dist/node-runtime/{chunk-A2KQXUJD.js → chunk-7AFOFSDY.js} +1 -1
  164. package/dist/node-runtime/chunk-BKAZ6BKX.js +2185 -0
  165. package/dist/node-runtime/{chunk-AHSTJBIB.js → chunk-EH2LJQPM.js} +4 -4
  166. package/dist/node-runtime/{chunk-N77MY65L.js → chunk-FLYMHKCS.js} +25 -25
  167. package/dist/node-runtime/{chunk-5P7PZMRU.js → chunk-HRS4HMDX.js} +1 -1
  168. package/dist/node-runtime/{chunk-IPA627GP.js → chunk-ISQDQIZN.js} +4 -4
  169. package/dist/node-runtime/{chunk-WJVFOIB5.js → chunk-J7QGQD45.js} +1 -1
  170. package/dist/node-runtime/{chunk-WOVTOV5P.js → chunk-JT6YCS5B.js} +29 -34
  171. package/dist/node-runtime/chunk-JZHEUQRL.js +180 -0
  172. package/dist/node-runtime/{chunk-ZKMFUD3Q.js → chunk-K72NVGUB.js} +3 -3
  173. package/dist/node-runtime/{chunk-ECD5L7YI.js → chunk-LCACDWHJ.js} +389 -15
  174. package/dist/node-runtime/{chunk-2QKLKMKC.js → chunk-LTXUQJI4.js} +1 -1
  175. package/dist/node-runtime/{chunk-MKKH27PH.js → chunk-LWJXTA6Z.js} +274 -2416
  176. package/dist/node-runtime/{chunk-EDBJNRSM.js → chunk-MGSB2C3M.js} +1 -1
  177. package/dist/node-runtime/{chunk-CDFZEWPU.js → chunk-MUMMMTW4.js} +6 -2
  178. package/dist/node-runtime/{chunk-YF63P5ZT.js → chunk-OTT6JMPU.js} +10 -67
  179. package/dist/node-runtime/{chunk-PGAJ5MO5.js → chunk-T5GM5BFH.js} +1 -1
  180. package/dist/node-runtime/{chunk-PCGNAY2O.js → chunk-TAP7QTUT.js} +38 -16
  181. package/dist/node-runtime/{chunk-4TLO4PO2.js → chunk-U6C7VTR5.js} +7 -1401
  182. package/dist/node-runtime/chunk-URD2SLIT.js +1019 -0
  183. package/dist/node-runtime/{chunk-QH42CDX3.js → chunk-W7S2REEG.js} +111 -84
  184. package/dist/node-runtime/{chunk-LZAW4ZX3.js → chunk-ZRDIMBEQ.js} +27 -9
  185. package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-ZSEZY3II.js} +5 -100
  186. package/dist/node-runtime/cli-runtime.js +1 -1
  187. package/dist/node-runtime/{command-L3LAHDIH.js → command-6UXQ6XZN.js} +1 -1
  188. package/dist/node-runtime/{commands-RL5YBW5I.js → commands-LGR5VT5X.js} +6 -4
  189. package/dist/node-runtime/{direct-tool-executor-JVDXTO7A.js → direct-tool-executor-TDJS7TBD.js} +9 -6
  190. package/dist/node-runtime/{export-html-KR26FOUZ.js → export-html-E4DT6ZJQ.js} +1 -1
  191. package/dist/node-runtime/{extract-XLQSJN4V.js → extract-IUCVZCWC.js} +2 -2
  192. package/dist/node-runtime/{gateway-X2TI5X7F.js → gateway-3OLC4GQN.js} +22 -367
  193. package/dist/node-runtime/{gemini-search-U7SUMPQA.js → gemini-search-NCIDF7NE.js} +1 -1
  194. package/dist/node-runtime/{gemini-url-context-PXWCBQHK.js → gemini-url-context-OKIN7AIP.js} +2 -2
  195. package/dist/node-runtime/image-resize-6ZPBFMWW.js +11 -0
  196. package/dist/node-runtime/index.js +53 -49
  197. package/dist/node-runtime/{init-NJV2T55N.js → init-EKE277AG.js} +6 -4
  198. package/dist/node-runtime/{interactive-mode-KOM35YF2.js → interactive-mode-S5M26CQ7.js} +20 -17
  199. package/dist/node-runtime/{interactive-view-U6OILKF3.js → interactive-view-N6F4KUIT.js} +3 -5
  200. package/dist/node-runtime/lunr-computer-use-4X3KUNF4.js +206 -0
  201. package/dist/node-runtime/{lunr-cron-YJ5UHYRD.js → lunr-cron-KKBOGAEF.js} +7 -1
  202. package/dist/node-runtime/main.js +24 -21
  203. package/dist/node-runtime/{mcp-auth-flow-QIXHW6QN.js → mcp-auth-flow-YL6RWPYG.js} +2 -1
  204. package/dist/node-runtime/{package-manager-cli-TZZHJCVI.js → package-manager-cli-C4EJOO5Q.js} +8 -6
  205. package/dist/node-runtime/{pi-mcp-adapter-QFB37AVN.js → pi-mcp-adapter-DPTJGAAL.js} +33 -27
  206. package/dist/node-runtime/{pi-subagents-7XJ4H53P.js → pi-subagents-VKCLYIBY.js} +103 -76
  207. package/dist/node-runtime/{pi-web-access-DPGAVKOA.js → pi-web-access-BV6DSZOP.js} +72 -69
  208. package/dist/node-runtime/{proxy-modes-HEEFK4KC.js → proxy-modes-R64LU6WZ.js} +12 -9
  209. package/dist/node-runtime/rpc-entry.js +24 -21
  210. package/dist/node-runtime/runtime-3SB5ATHQ.js +21 -0
  211. package/dist/node-runtime/{runtime-bridges-PPHNBFWL.js → runtime-bridges-UJ5WJJLN.js} +3 -3
  212. package/dist/node-runtime/{session-manager-MQNBYACL.js → session-manager-QEMZBMTM.js} +3 -5
  213. package/dist/node-runtime/{session-selector-5AZLJS6U.js → session-selector-URVJLOTK.js} +2 -2
  214. package/dist/node-runtime/{settings-manager-5LF2VQWC.js → settings-manager-K6IPIQTI.js} +3 -1
  215. package/dist/node-runtime/{src-Y7JSCK64.js → src-GPFAU3N6.js} +30 -10
  216. package/dist/node-runtime/{subagent-executor-5RNDEPIJ.js → subagent-executor-EFLTO32A.js} +39 -21
  217. package/dist/node-runtime/{update-cli-A253SZ7P.js → update-cli-I6OVDRPL.js} +3 -1
  218. package/dist/node-runtime/{video-extract-OYT5WKS5.js → video-extract-ETA5RA7U.js} +2 -2
  219. package/dist/node-runtime/workflow-SA34S4VX.js +325 -0
  220. package/dist/node-runtime/{youtube-extract-TQYKGFGS.js → youtube-extract-SRVGNN26.js} +2 -2
  221. package/dist/rpc.d.ts +3 -0
  222. package/dist/rpc.d.ts.map +1 -0
  223. package/dist/rpc.js +18 -0
  224. package/dist/rpc.js.map +1 -0
  225. package/dist/startup/interactive-view.d.ts.map +1 -1
  226. package/dist/startup/interactive-view.js +1 -2
  227. package/dist/startup/interactive-view.js.map +1 -1
  228. package/docs/computer-use.md +277 -0
  229. package/docs/development.md +0 -32
  230. package/docs/features.md +2 -2
  231. package/docs/interactive-startup.md +10 -3
  232. package/docs/keybindings.md +2 -2
  233. package/docs/terminal-setup.md +1 -1
  234. package/docs/usage.md +1 -1
  235. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  236. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  237. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  238. package/examples/extensions/gondolin/package-lock.json +2 -2
  239. package/examples/extensions/gondolin/package.json +1 -1
  240. package/examples/extensions/hidden-thinking-label.ts +1 -1
  241. package/examples/extensions/sandbox/package-lock.json +2 -2
  242. package/examples/extensions/sandbox/package.json +1 -1
  243. package/examples/extensions/with-deps/package-lock.json +2 -2
  244. package/examples/extensions/with-deps/package.json +1 -1
  245. package/install-lock/package-lock.json +3827 -0
  246. package/install-lock/package.json +18 -0
  247. package/native/computer-use/LICENSE.md +21 -0
  248. package/npm-shrinkwrap.json +3808 -0
  249. package/package.json +16 -10
  250. package/dist/startup/interactive-shell.d.ts +0 -55
  251. package/dist/startup/interactive-shell.d.ts.map +0 -1
  252. package/dist/startup/interactive-shell.js +0 -264
  253. package/dist/startup/interactive-shell.js.map +0 -1
  254. package/dist/node-runtime/{chunk-YSKSB3BJ.js → chunk-CH6OL6P2.js} +2 -2
  255. package/dist/node-runtime/{chunk-VSELYKWU.js → chunk-EHMBW7FA.js} +3 -3
@@ -0,0 +1,2185 @@
1
+ import { createRequire as __lunrRequire } from "node:module"; const require = __lunrRequire(import.meta.url);
2
+ import {
3
+ abortable,
4
+ computeServerHash,
5
+ extractToolUiStreamMode,
6
+ getMetadataCachePath,
7
+ getMissingConfiguredDirectToolServers,
8
+ interpolateEnvRecord,
9
+ isServerCacheValid,
10
+ loadMcpConfig,
11
+ loadMetadataCache,
12
+ openUrl,
13
+ parallelLimit,
14
+ reconstructToolMetadata,
15
+ resolveBearerToken,
16
+ resolveConfigPath,
17
+ saveMetadataCache,
18
+ serializeResources,
19
+ serializeTools,
20
+ throwIfAborted,
21
+ truncateAtWord
22
+ } from "./chunk-EHMBW7FA.js";
23
+ import {
24
+ formatToolName,
25
+ isToolExcluded,
26
+ resourceNameToToolName,
27
+ serverStreamResultPatchNotificationSchema
28
+ } from "./chunk-ARC4KOTI.js";
29
+ import {
30
+ AjvJsonSchemaValidator,
31
+ Client,
32
+ StdioClientTransport
33
+ } from "./chunk-LWJXTA6Z.js";
34
+ import {
35
+ McpOAuthProvider,
36
+ StreamableHTTPClientTransport,
37
+ UnauthorizedError,
38
+ auth,
39
+ createFetchWithInit,
40
+ createParser,
41
+ extractOAuthConfig,
42
+ extractWWWAuthenticateParams,
43
+ normalizeHeaders,
44
+ supportsOAuth
45
+ } from "./chunk-U6C7VTR5.js";
46
+ import {
47
+ getAgentPath
48
+ } from "./chunk-4HXHDDCF.js";
49
+ import {
50
+ CallToolResultSchema,
51
+ ContentBlockSchema,
52
+ CreateMessageRequestSchema,
53
+ ElicitRequestSchema,
54
+ ElicitationCompleteNotificationSchema,
55
+ EmbeddedResourceSchema,
56
+ ErrorCode,
57
+ ImplementationSchema,
58
+ JSONRPCMessageSchema,
59
+ McpError,
60
+ RequestIdSchema,
61
+ ResourceLinkSchema,
62
+ ToolSchema,
63
+ UrlElicitationRequiredError
64
+ } from "./chunk-2IDTZAG5.js";
65
+ import {
66
+ external_exports
67
+ } from "./chunk-BI3DHYCN.js";
68
+ import {
69
+ __require
70
+ } from "./chunk-BRJX2PRC.js";
71
+
72
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/init.js
73
+ import { existsSync as existsSync2 } from "node:fs";
74
+
75
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/errors.js
76
+ var McpUiError = class extends Error {
77
+ code;
78
+ context;
79
+ recoveryHint;
80
+ cause;
81
+ constructor(message, options) {
82
+ super(message), this.name = "McpUiError", this.code = options.code, this.context = options.context ?? {}, this.recoveryHint = options.recoveryHint, this.cause = options.cause, Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
83
+ }
84
+ toJSON() {
85
+ return {
86
+ name: this.name,
87
+ code: this.code,
88
+ message: this.message,
89
+ context: this.context,
90
+ recoveryHint: this.recoveryHint,
91
+ stack: this.stack
92
+ };
93
+ }
94
+ }, ResourceFetchError = class extends McpUiError {
95
+ constructor(uri, reason, options) {
96
+ super(`Failed to fetch UI resource "${uri}": ${reason}`, {
97
+ code: "RESOURCE_FETCH_ERROR",
98
+ context: { uri, server: options?.server },
99
+ recoveryHint: "Check that the MCP server is connected and the resource URI is valid.",
100
+ cause: options?.cause
101
+ }), this.name = "ResourceFetchError";
102
+ }
103
+ }, ResourceParseError = class extends McpUiError {
104
+ constructor(uri, reason, options) {
105
+ super(`Invalid UI resource "${uri}": ${reason}`, {
106
+ code: "RESOURCE_PARSE_ERROR",
107
+ context: { uri, server: options?.server, mimeType: options?.mimeType },
108
+ recoveryHint: "Ensure the resource returns valid HTML with the correct MIME type."
109
+ }), this.name = "ResourceParseError";
110
+ }
111
+ };
112
+ var ConsentError = class extends McpUiError {
113
+ denied;
114
+ constructor(server, options) {
115
+ let message = options.denied ? `Tool calls for "${server}" were denied for this session` : `Tool call approval required for "${server}"`;
116
+ super(message, {
117
+ code: options.denied ? "CONSENT_DENIED" : "CONSENT_REQUIRED",
118
+ context: { server },
119
+ recoveryHint: options.denied ? "The user denied tool access. Start a new session to try again." : "Prompt the user for consent before calling tools."
120
+ }), this.name = "ConsentError", this.denied = options.denied ?? !1;
121
+ }
122
+ };
123
+ var ServerError = class extends McpUiError {
124
+ constructor(reason, options) {
125
+ super(`UI server error: ${reason}`, {
126
+ code: "SERVER_ERROR",
127
+ context: { port: options?.port },
128
+ recoveryHint: "Check if the port is available. Another process may be using it.",
129
+ cause: options?.cause
130
+ }), this.name = "ServerError";
131
+ }
132
+ };
133
+ function wrapError(error, context) {
134
+ if (error instanceof McpUiError)
135
+ return new McpUiError(error.message, {
136
+ code: error.code,
137
+ context: { ...error.context, ...context },
138
+ recoveryHint: error.recoveryHint,
139
+ cause: error.cause
140
+ });
141
+ let cause = error instanceof Error ? error : void 0, message = error instanceof Error ? error.message : String(error);
142
+ return new McpUiError(message, {
143
+ code: "UNKNOWN_ERROR",
144
+ context,
145
+ cause
146
+ });
147
+ }
148
+
149
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/logger.js
150
+ var LEVEL_PRIORITY = {
151
+ debug: 0,
152
+ info: 1,
153
+ warn: 2,
154
+ error: 3
155
+ }, LEVEL_PREFIX = {
156
+ debug: "[MCP-UI:DEBUG]",
157
+ info: "[MCP-UI]",
158
+ warn: "[MCP-UI:WARN]",
159
+ error: "[MCP-UI:ERROR]"
160
+ }, Logger = class {
161
+ minLevel = "info";
162
+ handlers = [];
163
+ defaultContext = {};
164
+ setLevel(level) {
165
+ this.minLevel = level;
166
+ }
167
+ setDefaultContext(context) {
168
+ this.defaultContext = context;
169
+ }
170
+ addHandler(handler) {
171
+ this.handlers.push(handler);
172
+ }
173
+ clearHandlers() {
174
+ this.handlers = [];
175
+ }
176
+ shouldLog(level) {
177
+ return LEVEL_PRIORITY[level] >= LEVEL_PRIORITY[this.minLevel];
178
+ }
179
+ emit(level, message, context, error) {
180
+ if (!this.shouldLog(level))
181
+ return;
182
+ let entry = {
183
+ level,
184
+ message,
185
+ context: { ...this.defaultContext, ...context },
186
+ error,
187
+ timestamp: /* @__PURE__ */ new Date()
188
+ }, prefix = LEVEL_PREFIX[level], contextStr = formatContext(entry.context), fullMessage = contextStr ? `${prefix} ${message} ${contextStr}` : `${prefix} ${message}`;
189
+ level === "error" ? console.error(fullMessage, error ?? "") : level === "warn" ? console.warn(fullMessage) : level === "debug" ? console.debug(fullMessage) : console.log(fullMessage);
190
+ for (let handler of this.handlers)
191
+ try {
192
+ handler(entry);
193
+ } catch {
194
+ }
195
+ }
196
+ debug(message, context) {
197
+ this.emit("debug", message, context);
198
+ }
199
+ info(message, context) {
200
+ this.emit("info", message, context);
201
+ }
202
+ warn(message, context) {
203
+ this.emit("warn", message, context);
204
+ }
205
+ error(message, error, context) {
206
+ this.emit("error", message, context, error);
207
+ }
208
+ /**
209
+ * Create a child logger with additional default context.
210
+ */
211
+ child(context) {
212
+ return new ChildLogger(this, context);
213
+ }
214
+ }, ChildLogger = class _ChildLogger {
215
+ parent;
216
+ context;
217
+ constructor(parent, context) {
218
+ this.parent = parent, this.context = context;
219
+ }
220
+ debug(message, context) {
221
+ this.parent.debug(message, { ...this.context, ...context });
222
+ }
223
+ info(message, context) {
224
+ this.parent.info(message, { ...this.context, ...context });
225
+ }
226
+ warn(message, context) {
227
+ this.parent.warn(message, { ...this.context, ...context });
228
+ }
229
+ error(message, error, context) {
230
+ this.parent.error(message, error, { ...this.context, ...context });
231
+ }
232
+ child(context) {
233
+ return new _ChildLogger(this.parent, { ...this.context, ...context });
234
+ }
235
+ };
236
+ function formatContext(context) {
237
+ if (!context || Object.keys(context).length === 0)
238
+ return "";
239
+ let parts = [];
240
+ for (let [key, value] of Object.entries(context))
241
+ value != null && parts.push(`${key}=${typeof value == "string" ? value : JSON.stringify(value)}`);
242
+ return parts.length > 0 ? `(${parts.join(", ")})` : "";
243
+ }
244
+ var logger = new Logger();
245
+ (process.env.MCP_UI_DEBUG === "1" || process.env.MCP_UI_DEBUG === "true") && logger.setLevel("debug");
246
+
247
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/consent-manager.js
248
+ var ConsentManager = class {
249
+ mode;
250
+ approvedServers = /* @__PURE__ */ new Set();
251
+ deniedServers = /* @__PURE__ */ new Set();
252
+ log = logger.child({ component: "ConsentManager" });
253
+ constructor(mode = "once-per-server") {
254
+ this.mode = mode, this.log.debug("Initialized", { mode });
255
+ }
256
+ requiresPrompt(serverName) {
257
+ return this.mode === "never" ? !1 : this.deniedServers.has(serverName) || this.mode === "always" ? !0 : !this.approvedServers.has(serverName);
258
+ }
259
+ shouldCacheConsent() {
260
+ return this.mode !== "always";
261
+ }
262
+ registerDecision(serverName, approved) {
263
+ if (this.deniedServers.delete(serverName), this.approvedServers.delete(serverName), approved) {
264
+ this.approvedServers.add(serverName), this.log.debug("Consent granted", { server: serverName });
265
+ return;
266
+ }
267
+ this.deniedServers.add(serverName), this.log.debug("Consent denied", { server: serverName });
268
+ }
269
+ ensureApproved(serverName) {
270
+ if (this.mode !== "never") {
271
+ if (this.deniedServers.has(serverName))
272
+ throw new ConsentError(serverName, { denied: !0 });
273
+ if (!this.approvedServers.has(serverName))
274
+ throw new ConsentError(serverName, { requiresApproval: !0 });
275
+ this.mode === "always" && this.approvedServers.delete(serverName);
276
+ }
277
+ }
278
+ clear(serverName) {
279
+ if (serverName) {
280
+ this.approvedServers.delete(serverName), this.deniedServers.delete(serverName), this.log.debug("Cleared consent for server", { server: serverName });
281
+ return;
282
+ }
283
+ this.approvedServers.clear(), this.deniedServers.clear(), this.log.debug("Cleared all consent records");
284
+ }
285
+ };
286
+
287
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/lifecycle.js
288
+ var McpLifecycleManager = class {
289
+ manager;
290
+ keepAliveServers = /* @__PURE__ */ new Map();
291
+ allServers = /* @__PURE__ */ new Map();
292
+ serverSettings = /* @__PURE__ */ new Map();
293
+ globalIdleTimeout = 600 * 1e3;
294
+ healthCheckInterval;
295
+ onReconnect;
296
+ onIdleShutdown;
297
+ constructor(manager) {
298
+ this.manager = manager;
299
+ }
300
+ /**
301
+ * Set callback to be invoked after a successful auto-reconnect.
302
+ * Use this to update tool metadata when a server reconnects.
303
+ */
304
+ setReconnectCallback(callback) {
305
+ this.onReconnect = callback;
306
+ }
307
+ markKeepAlive(name, definition) {
308
+ this.keepAliveServers.set(name, definition);
309
+ }
310
+ registerServer(name, definition, settings) {
311
+ this.allServers.set(name, definition), settings?.idleTimeout !== void 0 && this.serverSettings.set(name, settings);
312
+ }
313
+ setGlobalIdleTimeout(minutes) {
314
+ this.globalIdleTimeout = minutes * 60 * 1e3;
315
+ }
316
+ setIdleShutdownCallback(callback) {
317
+ this.onIdleShutdown = callback;
318
+ }
319
+ startHealthChecks(intervalMs = 3e4) {
320
+ this.healthCheckInterval = setInterval(() => {
321
+ this.checkConnections();
322
+ }, intervalMs), this.healthCheckInterval.unref();
323
+ }
324
+ async checkConnections() {
325
+ for (let [name, definition] of this.keepAliveServers) {
326
+ let connection = this.manager.getConnection(name);
327
+ if (!connection || connection.status !== "connected")
328
+ try {
329
+ await this.manager.connect(name, definition), logger.debug(`Reconnected to ${name}`), this.onReconnect?.(name);
330
+ } catch (error) {
331
+ console.error(`MCP: Failed to reconnect to ${name}:`, error);
332
+ }
333
+ }
334
+ for (let [name] of this.allServers) {
335
+ if (this.keepAliveServers.has(name))
336
+ continue;
337
+ let timeout = this.getIdleTimeout(name);
338
+ timeout > 0 && this.manager.isIdle(name, timeout) && (await this.manager.close(name), this.onIdleShutdown?.(name));
339
+ }
340
+ }
341
+ getIdleTimeout(name) {
342
+ let perServer = this.serverSettings.get(name)?.idleTimeout;
343
+ return perServer !== void 0 ? perServer * 60 * 1e3 : this.globalIdleTimeout;
344
+ }
345
+ async gracefulShutdown() {
346
+ this.healthCheckInterval && clearInterval(this.healthCheckInterval), await this.manager.closeAll();
347
+ }
348
+ };
349
+
350
+ // node_modules/eventsource/dist/index.js
351
+ var ErrorEvent = class extends Event {
352
+ /**
353
+ * Constructs a new `ErrorEvent` instance. This is typically not called directly,
354
+ * but rather emitted by the `EventSource` object when an error occurs.
355
+ *
356
+ * @param type - The type of the event (should be "error")
357
+ * @param errorEventInitDict - Optional properties to include in the error event
358
+ */
359
+ constructor(type, errorEventInitDict) {
360
+ var _a, _b;
361
+ super(type), this.code = (_a = errorEventInitDict?.code) != null ? _a : void 0, this.message = (_b = errorEventInitDict?.message) != null ? _b : void 0;
362
+ }
363
+ /**
364
+ * Node.js "hides" the `message` and `code` properties of the `ErrorEvent` instance,
365
+ * when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,
366
+ * we explicitly include the properties in the `inspect` method.
367
+ *
368
+ * This is automatically called by Node.js when you `console.log` an instance of this class.
369
+ *
370
+ * @param _depth - The current depth
371
+ * @param options - The options passed to `util.inspect`
372
+ * @param inspect - The inspect function to use (prevents having to import it from `util`)
373
+ * @returns A string representation of the error
374
+ */
375
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")](_depth, options, inspect) {
376
+ return inspect(inspectableError(this), options);
377
+ }
378
+ /**
379
+ * Deno "hides" the `message` and `code` properties of the `ErrorEvent` instance,
380
+ * when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,
381
+ * we explicitly include the properties in the `inspect` method.
382
+ *
383
+ * This is automatically called by Deno when you `console.log` an instance of this class.
384
+ *
385
+ * @param inspect - The inspect function to use (prevents having to import it from `util`)
386
+ * @param options - The options passed to `Deno.inspect`
387
+ * @returns A string representation of the error
388
+ */
389
+ [/* @__PURE__ */ Symbol.for("Deno.customInspect")](inspect, options) {
390
+ return inspect(inspectableError(this), options);
391
+ }
392
+ };
393
+ function syntaxError(message) {
394
+ let DomException = globalThis.DOMException;
395
+ return typeof DomException == "function" ? new DomException(message, "SyntaxError") : new SyntaxError(message);
396
+ }
397
+ function flattenError(err) {
398
+ return err instanceof Error ? "errors" in err && Array.isArray(err.errors) ? err.errors.map(flattenError).join(", ") : "cause" in err && err.cause instanceof Error ? `${err}: ${flattenError(err.cause)}` : err.message : `${err}`;
399
+ }
400
+ function inspectableError(err) {
401
+ return {
402
+ type: err.type,
403
+ message: err.message,
404
+ code: err.code,
405
+ defaultPrevented: err.defaultPrevented,
406
+ cancelable: err.cancelable,
407
+ timeStamp: err.timeStamp
408
+ };
409
+ }
410
+ var __typeError = (msg) => {
411
+ throw TypeError(msg);
412
+ }, __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg), __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)), __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value), __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value), __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method), _readyState, _url, _redirectUrl, _withCredentials, _fetch, _reconnectInterval, _reconnectTimer, _lastEventId, _controller, _parser, _onError, _onMessage, _onOpen, _EventSource_instances, connect_fn, _onFetchResponse, _onFetchError, getRequestOptions_fn, _onEvent, _onRetryChange, failConnection_fn, scheduleReconnect_fn, _reconnect, EventSource = class extends EventTarget {
413
+ constructor(url, eventSourceInitDict) {
414
+ var _a, _b;
415
+ super(), __privateAdd(this, _EventSource_instances), this.CONNECTING = 0, this.OPEN = 1, this.CLOSED = 2, __privateAdd(this, _readyState), __privateAdd(this, _url), __privateAdd(this, _redirectUrl), __privateAdd(this, _withCredentials), __privateAdd(this, _fetch), __privateAdd(this, _reconnectInterval), __privateAdd(this, _reconnectTimer), __privateAdd(this, _lastEventId, null), __privateAdd(this, _controller), __privateAdd(this, _parser), __privateAdd(this, _onError, null), __privateAdd(this, _onMessage, null), __privateAdd(this, _onOpen, null), __privateAdd(this, _onFetchResponse, async (response) => {
416
+ var _a2;
417
+ __privateGet(this, _parser).reset();
418
+ let { body, redirected, status, headers } = response;
419
+ if (status === 204) {
420
+ __privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Server sent HTTP 204, not reconnecting", 204), this.close();
421
+ return;
422
+ }
423
+ if (redirected ? __privateSet(this, _redirectUrl, new URL(response.url)) : __privateSet(this, _redirectUrl, void 0), status !== 200) {
424
+ __privateMethod(this, _EventSource_instances, failConnection_fn).call(this, `Non-200 status code (${status})`, status);
425
+ return;
426
+ }
427
+ if (!(headers.get("content-type") || "").startsWith("text/event-stream")) {
428
+ __privateMethod(this, _EventSource_instances, failConnection_fn).call(this, 'Invalid content type, expected "text/event-stream"', status);
429
+ return;
430
+ }
431
+ if (__privateGet(this, _readyState) === this.CLOSED)
432
+ return;
433
+ __privateSet(this, _readyState, this.OPEN);
434
+ let openEvent = new Event("open");
435
+ if ((_a2 = __privateGet(this, _onOpen)) == null || _a2.call(this, openEvent), this.dispatchEvent(openEvent), typeof body != "object" || !body || !("getReader" in body)) {
436
+ __privateMethod(this, _EventSource_instances, failConnection_fn).call(this, "Invalid response body, expected a web ReadableStream", status), this.close();
437
+ return;
438
+ }
439
+ let decoder = new TextDecoder(), reader = body.getReader(), open2 = !0;
440
+ do {
441
+ let { done, value } = await reader.read();
442
+ value && __privateGet(this, _parser).feed(decoder.decode(value, { stream: !done })), done && (open2 = !1, __privateGet(this, _parser).reset(), __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this));
443
+ } while (open2);
444
+ }), __privateAdd(this, _onFetchError, (err) => {
445
+ __privateSet(this, _controller, void 0), !(err.name === "AbortError" || err.type === "aborted") && __privateMethod(this, _EventSource_instances, scheduleReconnect_fn).call(this, flattenError(err));
446
+ }), __privateAdd(this, _onEvent, (event) => {
447
+ typeof event.id == "string" && __privateSet(this, _lastEventId, event.id);
448
+ let messageEvent = new MessageEvent(event.event || "message", {
449
+ data: event.data,
450
+ origin: __privateGet(this, _redirectUrl) ? __privateGet(this, _redirectUrl).origin : __privateGet(this, _url).origin,
451
+ lastEventId: event.id || ""
452
+ });
453
+ __privateGet(this, _onMessage) && (!event.event || event.event === "message") && __privateGet(this, _onMessage).call(this, messageEvent), this.dispatchEvent(messageEvent);
454
+ }), __privateAdd(this, _onRetryChange, (value) => {
455
+ __privateSet(this, _reconnectInterval, value);
456
+ }), __privateAdd(this, _reconnect, () => {
457
+ __privateSet(this, _reconnectTimer, void 0), __privateGet(this, _readyState) === this.CONNECTING && __privateMethod(this, _EventSource_instances, connect_fn).call(this);
458
+ });
459
+ try {
460
+ if (url instanceof URL)
461
+ __privateSet(this, _url, url);
462
+ else if (typeof url == "string")
463
+ __privateSet(this, _url, new URL(url, getBaseURL()));
464
+ else
465
+ throw new Error("Invalid URL");
466
+ } catch {
467
+ throw syntaxError("An invalid or illegal string was specified");
468
+ }
469
+ __privateSet(this, _parser, createParser({
470
+ onEvent: __privateGet(this, _onEvent),
471
+ onRetry: __privateGet(this, _onRetryChange)
472
+ })), __privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _reconnectInterval, 3e3), __privateSet(this, _fetch, (_a = eventSourceInitDict?.fetch) != null ? _a : globalThis.fetch), __privateSet(this, _withCredentials, (_b = eventSourceInitDict?.withCredentials) != null ? _b : !1), __privateMethod(this, _EventSource_instances, connect_fn).call(this);
473
+ }
474
+ /**
475
+ * Returns the state of this EventSource object's connection. It can have the values described below.
476
+ *
477
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)
478
+ *
479
+ * Note: typed as `number` instead of `0 | 1 | 2` for compatibility with the `EventSource` interface,
480
+ * defined in the TypeScript `dom` library.
481
+ *
482
+ * @public
483
+ */
484
+ get readyState() {
485
+ return __privateGet(this, _readyState);
486
+ }
487
+ /**
488
+ * Returns the URL providing the event stream.
489
+ *
490
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)
491
+ *
492
+ * @public
493
+ */
494
+ get url() {
495
+ return __privateGet(this, _url).href;
496
+ }
497
+ /**
498
+ * Returns true if the credentials mode for connection requests to the URL providing the event stream is set to "include", and false otherwise.
499
+ *
500
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)
501
+ */
502
+ get withCredentials() {
503
+ return __privateGet(this, _withCredentials);
504
+ }
505
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */
506
+ get onerror() {
507
+ return __privateGet(this, _onError);
508
+ }
509
+ set onerror(value) {
510
+ __privateSet(this, _onError, value);
511
+ }
512
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */
513
+ get onmessage() {
514
+ return __privateGet(this, _onMessage);
515
+ }
516
+ set onmessage(value) {
517
+ __privateSet(this, _onMessage, value);
518
+ }
519
+ /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */
520
+ get onopen() {
521
+ return __privateGet(this, _onOpen);
522
+ }
523
+ set onopen(value) {
524
+ __privateSet(this, _onOpen, value);
525
+ }
526
+ addEventListener(type, listener, options) {
527
+ let listen = listener;
528
+ super.addEventListener(type, listen, options);
529
+ }
530
+ removeEventListener(type, listener, options) {
531
+ let listen = listener;
532
+ super.removeEventListener(type, listen, options);
533
+ }
534
+ /**
535
+ * Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.
536
+ *
537
+ * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)
538
+ *
539
+ * @public
540
+ */
541
+ close() {
542
+ __privateGet(this, _reconnectTimer) && clearTimeout(__privateGet(this, _reconnectTimer)), __privateGet(this, _readyState) !== this.CLOSED && (__privateGet(this, _controller) && __privateGet(this, _controller).abort(), __privateSet(this, _readyState, this.CLOSED), __privateSet(this, _controller, void 0));
543
+ }
544
+ };
545
+ _readyState = /* @__PURE__ */ new WeakMap(), _url = /* @__PURE__ */ new WeakMap(), _redirectUrl = /* @__PURE__ */ new WeakMap(), _withCredentials = /* @__PURE__ */ new WeakMap(), _fetch = /* @__PURE__ */ new WeakMap(), _reconnectInterval = /* @__PURE__ */ new WeakMap(), _reconnectTimer = /* @__PURE__ */ new WeakMap(), _lastEventId = /* @__PURE__ */ new WeakMap(), _controller = /* @__PURE__ */ new WeakMap(), _parser = /* @__PURE__ */ new WeakMap(), _onError = /* @__PURE__ */ new WeakMap(), _onMessage = /* @__PURE__ */ new WeakMap(), _onOpen = /* @__PURE__ */ new WeakMap(), _EventSource_instances = /* @__PURE__ */ new WeakSet(), /**
546
+ * Connect to the given URL and start receiving events
547
+ *
548
+ * @internal
549
+ */
550
+ connect_fn = function() {
551
+ __privateSet(this, _readyState, this.CONNECTING), __privateSet(this, _controller, new AbortController()), __privateGet(this, _fetch)(__privateGet(this, _url), __privateMethod(this, _EventSource_instances, getRequestOptions_fn).call(this)).then(__privateGet(this, _onFetchResponse)).catch(__privateGet(this, _onFetchError));
552
+ }, _onFetchResponse = /* @__PURE__ */ new WeakMap(), _onFetchError = /* @__PURE__ */ new WeakMap(), /**
553
+ * Get request options for the `fetch()` request
554
+ *
555
+ * @returns The request options
556
+ * @internal
557
+ */
558
+ getRequestOptions_fn = function() {
559
+ var _a;
560
+ let init = {
561
+ // [spec] Let `corsAttributeState` be `Anonymous`…
562
+ // [spec] …will have their mode set to "cors"…
563
+ mode: "cors",
564
+ redirect: "follow",
565
+ headers: { Accept: "text/event-stream", ...__privateGet(this, _lastEventId) ? { "Last-Event-ID": __privateGet(this, _lastEventId) } : void 0 },
566
+ cache: "no-store",
567
+ signal: (_a = __privateGet(this, _controller)) == null ? void 0 : _a.signal
568
+ };
569
+ return "window" in globalThis && (init.credentials = this.withCredentials ? "include" : "same-origin"), init;
570
+ }, _onEvent = /* @__PURE__ */ new WeakMap(), _onRetryChange = /* @__PURE__ */ new WeakMap(), /**
571
+ * Handles the process referred to in the EventSource specification as "failing a connection".
572
+ *
573
+ * @param error - The error causing the connection to fail
574
+ * @param code - The HTTP status code, if available
575
+ * @internal
576
+ */
577
+ failConnection_fn = function(message, code) {
578
+ var _a;
579
+ __privateGet(this, _readyState) !== this.CLOSED && __privateSet(this, _readyState, this.CLOSED);
580
+ let errorEvent = new ErrorEvent("error", { code, message });
581
+ (_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent);
582
+ }, /**
583
+ * Schedules a reconnection attempt against the EventSource endpoint.
584
+ *
585
+ * @param message - The error causing the connection to fail
586
+ * @param code - The HTTP status code, if available
587
+ * @internal
588
+ */
589
+ scheduleReconnect_fn = function(message, code) {
590
+ var _a;
591
+ if (__privateGet(this, _readyState) === this.CLOSED)
592
+ return;
593
+ __privateSet(this, _readyState, this.CONNECTING);
594
+ let errorEvent = new ErrorEvent("error", { code, message });
595
+ (_a = __privateGet(this, _onError)) == null || _a.call(this, errorEvent), this.dispatchEvent(errorEvent), __privateSet(this, _reconnectTimer, setTimeout(__privateGet(this, _reconnect), __privateGet(this, _reconnectInterval)));
596
+ }, _reconnect = /* @__PURE__ */ new WeakMap(), /**
597
+ * ReadyState representing an EventSource currently trying to connect
598
+ *
599
+ * @public
600
+ */
601
+ EventSource.CONNECTING = 0, /**
602
+ * ReadyState representing an EventSource connection that is open (eg connected)
603
+ *
604
+ * @public
605
+ */
606
+ EventSource.OPEN = 1, /**
607
+ * ReadyState representing an EventSource connection that is closed (eg disconnected)
608
+ *
609
+ * @public
610
+ */
611
+ EventSource.CLOSED = 2;
612
+ function getBaseURL() {
613
+ let doc = "document" in globalThis ? globalThis.document : void 0;
614
+ return doc && typeof doc == "object" && "baseURI" in doc && typeof doc.baseURI == "string" ? doc.baseURI : void 0;
615
+ }
616
+
617
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js
618
+ var SseError = class extends Error {
619
+ constructor(code, message, event) {
620
+ super(`SSE error: ${message}`), this.code = code, this.event = event;
621
+ }
622
+ }, SSEClientTransport = class {
623
+ constructor(url, opts) {
624
+ this._url = url, this._resourceMetadataUrl = void 0, this._scope = void 0, this._eventSourceInit = opts?.eventSourceInit, this._requestInit = opts?.requestInit, this._authProvider = opts?.authProvider, this._fetch = opts?.fetch, this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
625
+ }
626
+ async _authThenStart() {
627
+ if (!this._authProvider)
628
+ throw new UnauthorizedError("No auth provider");
629
+ let result;
630
+ try {
631
+ result = await auth(this._authProvider, {
632
+ serverUrl: this._url,
633
+ resourceMetadataUrl: this._resourceMetadataUrl,
634
+ scope: this._scope,
635
+ fetchFn: this._fetchWithInit
636
+ });
637
+ } catch (error) {
638
+ throw this.onerror?.(error), error;
639
+ }
640
+ if (result !== "AUTHORIZED")
641
+ throw new UnauthorizedError();
642
+ return await this._startOrAuth();
643
+ }
644
+ async _commonHeaders() {
645
+ let headers = {};
646
+ if (this._authProvider) {
647
+ let tokens = await this._authProvider.tokens();
648
+ tokens && (headers.Authorization = `Bearer ${tokens.access_token}`);
649
+ }
650
+ this._protocolVersion && (headers["mcp-protocol-version"] = this._protocolVersion);
651
+ let extraHeaders = normalizeHeaders(this._requestInit?.headers);
652
+ return new Headers({
653
+ ...headers,
654
+ ...extraHeaders
655
+ });
656
+ }
657
+ _startOrAuth() {
658
+ let fetchImpl = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
659
+ return new Promise((resolve2, reject) => {
660
+ this._eventSource = new EventSource(this._url.href, {
661
+ ...this._eventSourceInit,
662
+ fetch: async (url, init) => {
663
+ let headers = await this._commonHeaders();
664
+ headers.set("Accept", "text/event-stream");
665
+ let response = await fetchImpl(url, {
666
+ ...init,
667
+ headers
668
+ });
669
+ if (response.status === 401 && response.headers.has("www-authenticate")) {
670
+ let { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
671
+ this._resourceMetadataUrl = resourceMetadataUrl, this._scope = scope;
672
+ }
673
+ return response;
674
+ }
675
+ }), this._abortController = new AbortController(), this._eventSource.onerror = (event) => {
676
+ if (event.code === 401 && this._authProvider) {
677
+ this._authThenStart().then(resolve2, reject);
678
+ return;
679
+ }
680
+ let error = new SseError(event.code, event.message, event);
681
+ reject(error), this.onerror?.(error);
682
+ }, this._eventSource.onopen = () => {
683
+ }, this._eventSource.addEventListener("endpoint", (event) => {
684
+ let messageEvent = event;
685
+ try {
686
+ if (this._endpoint = new URL(messageEvent.data, this._url), this._endpoint.origin !== this._url.origin)
687
+ throw new Error(`Endpoint origin does not match connection origin: ${this._endpoint.origin}`);
688
+ } catch (error) {
689
+ reject(error), this.onerror?.(error), this.close();
690
+ return;
691
+ }
692
+ resolve2();
693
+ }), this._eventSource.onmessage = (event) => {
694
+ let messageEvent = event, message;
695
+ try {
696
+ message = JSONRPCMessageSchema.parse(JSON.parse(messageEvent.data));
697
+ } catch (error) {
698
+ this.onerror?.(error);
699
+ return;
700
+ }
701
+ this.onmessage?.(message);
702
+ };
703
+ });
704
+ }
705
+ async start() {
706
+ if (this._eventSource)
707
+ throw new Error("SSEClientTransport already started! If using Client class, note that connect() calls start() automatically.");
708
+ return await this._startOrAuth();
709
+ }
710
+ /**
711
+ * Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.
712
+ */
713
+ async finishAuth(authorizationCode) {
714
+ if (!this._authProvider)
715
+ throw new UnauthorizedError("No auth provider");
716
+ if (await auth(this._authProvider, {
717
+ serverUrl: this._url,
718
+ authorizationCode,
719
+ resourceMetadataUrl: this._resourceMetadataUrl,
720
+ scope: this._scope,
721
+ fetchFn: this._fetchWithInit
722
+ }) !== "AUTHORIZED")
723
+ throw new UnauthorizedError("Failed to authorize");
724
+ }
725
+ async close() {
726
+ this._abortController?.abort(), this._eventSource?.close(), this.onclose?.();
727
+ }
728
+ async send(message) {
729
+ if (!this._endpoint)
730
+ throw new Error("Not connected");
731
+ try {
732
+ let headers = await this._commonHeaders();
733
+ headers.set("content-type", "application/json");
734
+ let init = {
735
+ ...this._requestInit,
736
+ method: "POST",
737
+ headers,
738
+ body: JSON.stringify(message),
739
+ signal: this._abortController?.signal
740
+ }, response = await (this._fetch ?? fetch)(this._endpoint, init);
741
+ if (!response.ok) {
742
+ let text = await response.text().catch(() => null);
743
+ if (response.status === 401 && this._authProvider) {
744
+ let { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
745
+ if (this._resourceMetadataUrl = resourceMetadataUrl, this._scope = scope, await auth(this._authProvider, {
746
+ serverUrl: this._url,
747
+ resourceMetadataUrl: this._resourceMetadataUrl,
748
+ scope: this._scope,
749
+ fetchFn: this._fetchWithInit
750
+ }) !== "AUTHORIZED")
751
+ throw new UnauthorizedError();
752
+ return this.send(message);
753
+ }
754
+ throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);
755
+ }
756
+ await response.body?.cancel();
757
+ } catch (error) {
758
+ throw this.onerror?.(error), error;
759
+ }
760
+ }
761
+ setProtocolVersion(version) {
762
+ this._protocolVersion = version;
763
+ }
764
+ };
765
+
766
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/npx-resolver.js
767
+ import { existsSync, readFileSync, realpathSync, readdirSync, statSync, writeFileSync, renameSync, mkdirSync, openSync, readSync, closeSync } from "node:fs";
768
+ import { join, dirname, extname, resolve, sep } from "node:path";
769
+ import { spawn, spawnSync } from "node:child_process";
770
+ var CACHE_VERSION = 1, CACHE_TTL_MS = 1440 * 60 * 1e3;
771
+ async function resolveNpxBinary(command, args) {
772
+ let parsed = command === "npx" ? parseNpxArgs(args) : command === "npm" ? parseNpmExecArgs(args) : null;
773
+ if (!parsed)
774
+ return null;
775
+ let cacheKey = JSON.stringify([command, ...args]), cached = loadCache()?.entries?.[cacheKey];
776
+ if (cached && Date.now() - cached.resolvedAt < CACHE_TTL_MS && existsSync(cached.resolvedBin))
777
+ return { binPath: cached.resolvedBin, extraArgs: parsed.extraArgs, isJs: cached.isJs };
778
+ let resolved = resolveFromNpmCache(parsed.packageSpec, parsed.binName);
779
+ if (resolved)
780
+ return saveCacheEntry(cacheKey, resolved), { binPath: resolved.resolvedBin, extraArgs: parsed.extraArgs, isJs: resolved.isJs };
781
+ await forceNpxCache(parsed.packageSpec);
782
+ let resolvedAfterInstall = resolveFromNpmCache(parsed.packageSpec, parsed.binName);
783
+ return resolvedAfterInstall ? (saveCacheEntry(cacheKey, resolvedAfterInstall), { binPath: resolvedAfterInstall.resolvedBin, extraArgs: parsed.extraArgs, isJs: resolvedAfterInstall.isJs }) : null;
784
+ }
785
+ function parseNpxArgs(args) {
786
+ let separatorIndex = args.indexOf("--"), before = separatorIndex >= 0 ? args.slice(0, separatorIndex) : args, after = separatorIndex >= 0 ? args.slice(separatorIndex + 1) : [], positionals = [], packageSpec, sawPackageFlag = !1, foundFirstPositional = !1;
787
+ for (let i2 = 0; i2 < before.length; i2++) {
788
+ let arg = before[i2];
789
+ if (foundFirstPositional) {
790
+ positionals.push(arg);
791
+ continue;
792
+ }
793
+ if (!(arg === "-y" || arg === "--yes")) {
794
+ if (arg === "-p" || arg === "--package") {
795
+ let value = before[i2 + 1];
796
+ if (!value || value.startsWith("-"))
797
+ return null;
798
+ packageSpec || (packageSpec = value), sawPackageFlag = !0, i2++;
799
+ continue;
800
+ }
801
+ if (arg.startsWith("--package=")) {
802
+ let value = arg.slice(10);
803
+ if (!value)
804
+ return null;
805
+ packageSpec || (packageSpec = value), sawPackageFlag = !0;
806
+ continue;
807
+ }
808
+ if (arg.startsWith("-"))
809
+ return null;
810
+ positionals.push(arg), foundFirstPositional = !0;
811
+ }
812
+ }
813
+ let separatedAfter = separatorIndex >= 0 && after.length > 0 ? ["--", ...after] : after;
814
+ if (sawPackageFlag) {
815
+ let binName = positionals[0];
816
+ if (!packageSpec || !binName)
817
+ return null;
818
+ let extraArgs2 = positionals.slice(1).concat(separatedAfter);
819
+ return { packageSpec, binName, extraArgs: extraArgs2 };
820
+ }
821
+ let packagePositional = positionals[0];
822
+ if (!packagePositional)
823
+ return null;
824
+ let extraArgs = positionals.slice(1).concat(separatedAfter);
825
+ return { packageSpec: packagePositional, extraArgs };
826
+ }
827
+ function parseNpmExecArgs(args) {
828
+ if (args[0] !== "exec")
829
+ return null;
830
+ let execArgs = args.slice(1), separatorIndex = execArgs.indexOf("--");
831
+ if (separatorIndex < 0)
832
+ return null;
833
+ let before = execArgs.slice(0, separatorIndex), after = execArgs.slice(separatorIndex + 1), packageSpec;
834
+ for (let i2 = 0; i2 < before.length; i2++) {
835
+ let arg = before[i2];
836
+ if (!(arg === "-y" || arg === "--yes")) {
837
+ if (arg === "--package") {
838
+ let value = before[i2 + 1];
839
+ if (!value || value.startsWith("-"))
840
+ return null;
841
+ packageSpec || (packageSpec = value), i2++;
842
+ continue;
843
+ }
844
+ if (arg.startsWith("--package=")) {
845
+ let value = arg.slice(10);
846
+ if (!value)
847
+ return null;
848
+ packageSpec || (packageSpec = value);
849
+ continue;
850
+ }
851
+ if (arg.startsWith("-"))
852
+ return null;
853
+ }
854
+ }
855
+ let binName = after[0];
856
+ if (!packageSpec || !binName)
857
+ return null;
858
+ let extraArgs = after.slice(1);
859
+ return { packageSpec, binName, extraArgs };
860
+ }
861
+ function resolveFromNpmCache(packageSpec, binName) {
862
+ let cacheDir = getNpmCacheDir();
863
+ if (!cacheDir)
864
+ return null;
865
+ let packageName = extractPackageName(packageSpec);
866
+ if (!packageName)
867
+ return null;
868
+ let packageDir = findCachedPackageDir(cacheDir, packageName);
869
+ if (!packageDir)
870
+ return null;
871
+ let packageJsonPath = join(packageDir, "package.json");
872
+ if (!existsSync(packageJsonPath))
873
+ return null;
874
+ let pkg = null;
875
+ try {
876
+ pkg = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
877
+ } catch {
878
+ return null;
879
+ }
880
+ let binField = pkg?.bin;
881
+ if (!binField)
882
+ return null;
883
+ let candidates = buildBinCandidates(packageName, binName), chosenBinName, binRel;
884
+ if (typeof binField == "string")
885
+ chosenBinName = defaultBinName(packageName), binRel = binField;
886
+ else {
887
+ for (let candidate of candidates)
888
+ if (binField[candidate]) {
889
+ chosenBinName = candidate, binRel = binField[candidate];
890
+ break;
891
+ }
892
+ if (!binRel) {
893
+ let firstEntry = Object.entries(binField)[0];
894
+ firstEntry && (chosenBinName = firstEntry[0], binRel = firstEntry[1]);
895
+ }
896
+ }
897
+ if (!binRel)
898
+ return null;
899
+ let nodeModulesDir = findNodeModulesDir(packageDir), binLink = chosenBinName ? join(nodeModulesDir, ".bin", chosenBinName) : null, resolvedBin = binLink && existsSync(binLink) ? safeRealpath(binLink) : "";
900
+ if (!resolvedBin && (resolvedBin = resolve(packageDir, binRel), !existsSync(resolvedBin)))
901
+ return null;
902
+ let isJs = detectJsBinary(resolvedBin);
903
+ return {
904
+ resolvedBin,
905
+ resolvedAt: Date.now(),
906
+ packageVersion: pkg?.version,
907
+ isJs
908
+ };
909
+ }
910
+ var FORCE_CACHE_TIMEOUT_MS = 3e4;
911
+ async function forceNpxCache(packageSpec) {
912
+ try {
913
+ await new Promise((resolve2, reject) => {
914
+ let proc = spawn("npm", ["exec", "--yes", "--package", packageSpec, "--", "node", "-e", "1"], { stdio: "ignore" }), timer = setTimeout(() => {
915
+ proc.kill(), reject(new Error("timeout"));
916
+ }, FORCE_CACHE_TIMEOUT_MS);
917
+ timer.unref(), proc.on("close", () => {
918
+ clearTimeout(timer), resolve2();
919
+ }), proc.on("error", (err) => {
920
+ clearTimeout(timer), reject(err);
921
+ });
922
+ });
923
+ } catch {
924
+ }
925
+ }
926
+ function buildBinCandidates(packageName, explicitBin) {
927
+ let candidates = [];
928
+ if (explicitBin && candidates.push(explicitBin), packageName.startsWith("@")) {
929
+ let namePart = packageName.split("/")[1] ?? "", scopePart = packageName.split("/")[0]?.replace("@", "") ?? "";
930
+ namePart && candidates.push(namePart), scopePart && namePart && candidates.push(`${scopePart}-${namePart}`);
931
+ } else
932
+ candidates.push(packageName);
933
+ return [...new Set(candidates.filter(Boolean))];
934
+ }
935
+ function extractPackageName(spec) {
936
+ let trimmed = spec.trim();
937
+ if (!trimmed)
938
+ return null;
939
+ if (trimmed.startsWith("@")) {
940
+ let slashIndex = trimmed.indexOf("/");
941
+ if (slashIndex < 0)
942
+ return null;
943
+ let atIndex2 = trimmed.lastIndexOf("@");
944
+ return atIndex2 > slashIndex ? trimmed.slice(0, atIndex2) : trimmed;
945
+ }
946
+ let atIndex = trimmed.indexOf("@");
947
+ return atIndex >= 0 ? trimmed.slice(0, atIndex) : trimmed;
948
+ }
949
+ function defaultBinName(packageName) {
950
+ return packageName.startsWith("@") ? packageName.split("/")[1] ?? packageName.replace("@", "").replace("/", "-") : packageName;
951
+ }
952
+ function findCachedPackageDir(cacheDir, packageName) {
953
+ let npxDir = join(cacheDir, "_npx");
954
+ if (!existsSync(npxDir))
955
+ return null;
956
+ let packagePathParts = packageName.startsWith("@") ? packageName.split("/") : [packageName], candidates = readdirSync(npxDir, { withFileTypes: !0 }).filter((entry) => entry.isDirectory()).map((entry) => {
957
+ let full = join(npxDir, entry.name), mtime = safeStatMtime(full);
958
+ return { name: entry.name, mtime };
959
+ }).sort((a2, b2) => b2.mtime - a2.mtime);
960
+ for (let entry of candidates) {
961
+ let pkgDir = join(npxDir, entry.name, "node_modules", ...packagePathParts);
962
+ if (existsSync(join(pkgDir, "package.json")))
963
+ return pkgDir;
964
+ }
965
+ return null;
966
+ }
967
+ function findNodeModulesDir(packageDir) {
968
+ let parts = packageDir.split(sep), idx = parts.lastIndexOf("node_modules");
969
+ return idx >= 0 ? parts.slice(0, idx + 1).join(sep) : join(packageDir, "..");
970
+ }
971
+ function detectJsBinary(binPath) {
972
+ let ext = extname(binPath).toLowerCase();
973
+ if (ext === ".js" || ext === ".mjs" || ext === ".cjs")
974
+ return !0;
975
+ try {
976
+ let fd = openSync(binPath, "r");
977
+ try {
978
+ let buf = Buffer.alloc(256);
979
+ readSync(fd, buf, 0, 256, 0);
980
+ let firstLine = buf.toString("utf-8").split(`
981
+ `)[0] ?? "";
982
+ return firstLine.startsWith("#!") && firstLine.includes("node");
983
+ } finally {
984
+ closeSync(fd);
985
+ }
986
+ } catch {
987
+ return !1;
988
+ }
989
+ }
990
+ var npmCacheDirCached;
991
+ function getNpmCacheDir() {
992
+ if (npmCacheDirCached !== void 0)
993
+ return npmCacheDirCached;
994
+ if (process.env.NPM_CONFIG_CACHE)
995
+ return npmCacheDirCached = process.env.NPM_CONFIG_CACHE, npmCacheDirCached;
996
+ try {
997
+ let result = spawnSync("npm", ["config", "get", "cache"], { encoding: "utf-8" });
998
+ if (result.status === 0)
999
+ return npmCacheDirCached = String(result.stdout).trim() || null, npmCacheDirCached;
1000
+ } catch {
1001
+ return npmCacheDirCached = null, null;
1002
+ }
1003
+ return npmCacheDirCached = null, null;
1004
+ }
1005
+ function getNpxCachePath() {
1006
+ return getAgentPath("mcp-npx-cache.json");
1007
+ }
1008
+ function loadCache() {
1009
+ let cachePath = getNpxCachePath();
1010
+ if (!existsSync(cachePath))
1011
+ return null;
1012
+ try {
1013
+ let raw = JSON.parse(readFileSync(cachePath, "utf-8"));
1014
+ return !raw || typeof raw != "object" || raw.version !== CACHE_VERSION || !raw.entries || typeof raw.entries != "object" ? null : raw;
1015
+ } catch {
1016
+ return null;
1017
+ }
1018
+ }
1019
+ function saveCacheEntry(key, entry) {
1020
+ let cachePath = getNpxCachePath(), dir = dirname(cachePath);
1021
+ mkdirSync(dir, { recursive: !0 });
1022
+ let merged = { version: CACHE_VERSION, entries: {} };
1023
+ try {
1024
+ if (existsSync(cachePath)) {
1025
+ let existing = JSON.parse(readFileSync(cachePath, "utf-8"));
1026
+ existing && existing.version === CACHE_VERSION && existing.entries && (merged.entries = { ...existing.entries });
1027
+ }
1028
+ } catch {
1029
+ }
1030
+ merged.entries[key] = entry;
1031
+ let tmpPath = `${cachePath}.${process.pid}.tmp`;
1032
+ writeFileSync(tmpPath, JSON.stringify(merged, null, 2), "utf-8"), renameSync(tmpPath, cachePath);
1033
+ }
1034
+ function safeRealpath(path) {
1035
+ try {
1036
+ return realpathSync(path);
1037
+ } catch {
1038
+ return "";
1039
+ }
1040
+ }
1041
+ function safeStatMtime(path) {
1042
+ try {
1043
+ return statSync(path).mtimeMs;
1044
+ } catch {
1045
+ return 0;
1046
+ }
1047
+ }
1048
+
1049
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/sampling-handler.js
1050
+ import { complete } from "@ashx-j/lunr-ai/compat";
1051
+ function registerSamplingHandler(client, options) {
1052
+ client.setRequestHandler(CreateMessageRequestSchema, (request) => handleSamplingRequest(options, request));
1053
+ }
1054
+ async function handleSamplingRequest(options, request) {
1055
+ let params = request.params;
1056
+ if ("task" in params && params.task)
1057
+ throw new Error("MCP sampling tasks are not supported");
1058
+ if (params.includeContext && params.includeContext !== "none")
1059
+ throw new Error("MCP sampling context inclusion is not supported");
1060
+ if (params.tools?.length)
1061
+ throw new Error("MCP sampling tool use is not supported");
1062
+ if (params.toolChoice)
1063
+ throw new Error("MCP sampling tool choice is not supported");
1064
+ if (params.stopSequences?.length)
1065
+ throw new Error("MCP sampling stop sequences are not supported");
1066
+ let messages = params.messages.map(convertSamplingMessage), { model, apiKey, headers } = await resolveSamplingModel(options, params.modelPreferences);
1067
+ await confirmSampling(options, "Approve MCP sampling request", formatRequestApproval(options.serverName, `${model.provider}/${model.id}`, params.systemPrompt, messages));
1068
+ let result = await complete(model, {
1069
+ systemPrompt: params.systemPrompt,
1070
+ messages
1071
+ }, {
1072
+ apiKey,
1073
+ headers,
1074
+ maxTokens: params.maxTokens,
1075
+ temperature: params.temperature,
1076
+ metadata: params.metadata,
1077
+ signal: options.getSignal()
1078
+ }), converted = convertAssistantResult(result);
1079
+ return await confirmSampling(options, "Return MCP sampling response", formatResponseApproval(options.serverName, converted)), converted;
1080
+ }
1081
+ function formatRequestApproval(serverName, modelName, systemPrompt, messages) {
1082
+ let lines = [`${serverName} wants to sample ${messages.length} message${messages.length === 1 ? "" : "s"} with ${modelName}.`];
1083
+ systemPrompt && lines.push(`System: ${truncateAtWord(systemPrompt, 400)}`);
1084
+ for (let [index, message] of messages.entries())
1085
+ lines.push(`${index + 1}. ${message.role}: ${truncateAtWord(messageText(message), 400)}`);
1086
+ return lines.join(`
1087
+
1088
+ `);
1089
+ }
1090
+ function formatResponseApproval(serverName, response) {
1091
+ let text = response.content.type === "text" ? response.content.text : `[${response.content.type} content]`;
1092
+ return `${serverName} will receive this response from ${response.model}:
1093
+
1094
+ ${truncateAtWord(text, 1e3)}`;
1095
+ }
1096
+ function messageText(message) {
1097
+ return typeof message.content == "string" ? message.content : message.content.map((block) => block.type === "text" ? block.text : block.type === "image" ? `[image: ${block.mimeType}]` : block.type === "thinking" ? "[thinking]" : block.type === "toolCall" ? `[tool call: ${block.name}]` : "[content]").join(`
1098
+ `);
1099
+ }
1100
+ async function resolveSamplingModel(options, modelPreferences) {
1101
+ let candidates = [], availableModels = options.modelRegistry.getAvailable();
1102
+ for (let hint of modelPreferences?.hints ?? []) {
1103
+ let normalizedHint = hint.name?.trim().toLowerCase();
1104
+ if (normalizedHint)
1105
+ for (let model of availableModels)
1106
+ [`${model.provider}/${model.id}`, model.id, model.name].some((name) => name.toLowerCase().includes(normalizedHint)) && addSamplingCandidate(candidates, model);
1107
+ }
1108
+ let currentModel = options.getCurrentModel();
1109
+ currentModel && addSamplingCandidate(candidates, currentModel);
1110
+ for (let model of availableModels)
1111
+ addSamplingCandidate(candidates, model);
1112
+ let errors = [];
1113
+ for (let model of candidates) {
1114
+ let auth2 = await options.modelRegistry.getApiKeyAndHeaders(model);
1115
+ if (auth2.ok === !1) {
1116
+ errors.push(`${model.provider}/${model.id}: ${auth2.error}`);
1117
+ continue;
1118
+ }
1119
+ return { model, apiKey: auth2.apiKey, headers: auth2.headers };
1120
+ }
1121
+ throw errors.length > 0 ? new Error(`No configured auth for MCP sampling model. ${errors.join("; ")}`) : new Error("No Pi model is available for MCP sampling");
1122
+ }
1123
+ function addSamplingCandidate(candidates, model) {
1124
+ candidates.some((candidate) => candidate.provider === model.provider && candidate.id === model.id) || candidates.push(model);
1125
+ }
1126
+ async function confirmSampling(options, title, message) {
1127
+ if (options.autoApprove)
1128
+ return;
1129
+ if (!options.ui)
1130
+ throw new Error("MCP sampling requires interactive approval. Set settings.samplingAutoApprove to true to allow it without UI.");
1131
+ if (!await options.ui.confirm(title, message))
1132
+ throw new Error("MCP sampling request was declined");
1133
+ }
1134
+ function convertSamplingMessage(message) {
1135
+ let blocks = Array.isArray(message.content) ? message.content : [message.content];
1136
+ return message.role === "user" ? {
1137
+ role: "user",
1138
+ content: blocks.map(convertUserContent),
1139
+ timestamp: Date.now()
1140
+ } : {
1141
+ role: "assistant",
1142
+ content: blocks.map(convertAssistantContent),
1143
+ api: "mcp-sampling",
1144
+ provider: "mcp",
1145
+ model: "sampling-request",
1146
+ usage: zeroUsage(),
1147
+ stopReason: "stop",
1148
+ timestamp: Date.now()
1149
+ };
1150
+ }
1151
+ function convertUserContent(block) {
1152
+ if (block.type === "text")
1153
+ return { type: "text", text: block.text };
1154
+ throw new Error(`MCP sampling ${block.type} content is not supported`);
1155
+ }
1156
+ function convertAssistantContent(block) {
1157
+ if (block.type === "text")
1158
+ return { type: "text", text: block.text };
1159
+ throw new Error(`MCP sampling assistant ${block.type} content is not supported`);
1160
+ }
1161
+ function convertAssistantResult(message) {
1162
+ if (message.stopReason === "error")
1163
+ throw new Error(message.errorMessage ?? "MCP sampling model call failed");
1164
+ if (message.stopReason === "aborted")
1165
+ throw new Error(message.errorMessage ?? "MCP sampling model call was aborted");
1166
+ let text = message.content.map((block) => {
1167
+ if (block.type === "text")
1168
+ return block.text;
1169
+ if (block.type !== "thinking")
1170
+ throw new Error(`MCP sampling result ${block.type} content is not supported`);
1171
+ }).filter((value) => value !== void 0).join(`
1172
+
1173
+ `).trim();
1174
+ if (!text)
1175
+ throw new Error("MCP sampling result did not contain text content");
1176
+ return {
1177
+ role: "assistant",
1178
+ content: { type: "text", text },
1179
+ model: `${message.provider}/${message.model}`,
1180
+ stopReason: mapStopReason(message.stopReason)
1181
+ };
1182
+ }
1183
+ function mapStopReason(reason) {
1184
+ return reason === "stop" ? "endTurn" : reason === "length" ? "maxTokens" : reason === "toolUse" ? "toolUse" : reason;
1185
+ }
1186
+ function zeroUsage() {
1187
+ return {
1188
+ input: 0,
1189
+ output: 0,
1190
+ cacheRead: 0,
1191
+ cacheWrite: 0,
1192
+ totalTokens: 0,
1193
+ cost: {
1194
+ input: 0,
1195
+ output: 0,
1196
+ cacheRead: 0,
1197
+ cacheWrite: 0,
1198
+ total: 0
1199
+ }
1200
+ };
1201
+ }
1202
+
1203
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/elicitation-handler.js
1204
+ import open from "open";
1205
+ function registerElicitationHandler(client, options) {
1206
+ client.setRequestHandler(ElicitRequestSchema, (request) => handleElicitationRequest(options, request));
1207
+ }
1208
+ async function handleElicitationRequest(options, request) {
1209
+ return request.params.mode === "url" ? handleUrlElicitation(options, request.params) : handleFormElicitation(options, request.params);
1210
+ }
1211
+ async function handleFormElicitation(options, params) {
1212
+ let decision = await options.ui.select(`MCP Input Request
1213
+ Server: ${options.serverName}
1214
+
1215
+ ${params.message}`, ["Continue", "Decline"]);
1216
+ if (decision === void 0)
1217
+ return { action: "cancel" };
1218
+ if (decision === "Decline")
1219
+ return { action: "decline" };
1220
+ let values = {}, properties = Object.entries(params.requestedSchema.properties);
1221
+ for (let [name, schema] of properties) {
1222
+ let value = await collectValidField(options.ui, params, name, schema);
1223
+ if (!("value" in value))
1224
+ return { action: "cancel" };
1225
+ values[name] = value.value;
1226
+ }
1227
+ for (; ; ) {
1228
+ let content = coerceAndValidateFormValues(params, values), action = await options.ui.select(formatReview(options.serverName, properties, content), properties.length > 0 ? ["Submit", "Edit", "Decline"] : ["Submit", "Decline"]);
1229
+ if (action === void 0)
1230
+ return { action: "cancel" };
1231
+ if (action === "Decline")
1232
+ return { action: "decline" };
1233
+ if (action === "Submit")
1234
+ return { action: "accept", content };
1235
+ let labels = properties.map(([name2, schema2]) => `${schema2.title ?? humanizeName(name2)} (${name2})`), selected = await options.ui.select("Choose a field to edit", labels);
1236
+ if (selected === void 0)
1237
+ return { action: "cancel" };
1238
+ let property = properties[labels.indexOf(selected)];
1239
+ if (!property)
1240
+ continue;
1241
+ let [name, schema] = property, value = await collectValidField(options.ui, params, name, schema, values[name]);
1242
+ if (!("value" in value))
1243
+ return { action: "cancel" };
1244
+ values[name] = value.value;
1245
+ }
1246
+ }
1247
+ async function collectValidField(ui, params, name, schema, current) {
1248
+ let required = params.requestedSchema.required?.includes(name) === !0;
1249
+ for (; ; ) {
1250
+ let result = await collectField(ui, params, name, schema, current);
1251
+ if (!("value" in result))
1252
+ return result;
1253
+ try {
1254
+ return coerceAndValidateFormValues({
1255
+ ...params,
1256
+ requestedSchema: {
1257
+ type: "object",
1258
+ properties: { [name]: schema },
1259
+ ...required ? { required: [name] } : {}
1260
+ }
1261
+ }, { [name]: result.value }), result;
1262
+ } catch (error) {
1263
+ ui.notify(error instanceof Error ? error.message : String(error), "error"), current = result.value;
1264
+ }
1265
+ }
1266
+ }
1267
+ async function collectField(ui, params, name, schema, current) {
1268
+ let required = params.requestedSchema.required?.includes(name) === !0, title = [schema.title ?? humanizeName(name), required ? "(required)" : "", schema.description].filter(Boolean).join(" ");
1269
+ if (schema.type === "string" && ("enum" in schema || "oneOf" in schema)) {
1270
+ let choices = "oneOf" in schema ? schema.oneOf.map((option) => ({ value: option.const, display: formatChoice(option.const, option.title) })) : schema.enum.map((value, index) => ({
1271
+ value,
1272
+ display: formatChoice(value, "enumNames" in schema ? schema.enumNames?.[index] : void 0)
1273
+ })), displays = uniqueLabels(choices.map((choice) => choice.display)), actions2 = [...displays], useDefault = schema.default === void 0 ? void 0 : uniqueAction("Use default", actions2);
1274
+ useDefault && actions2.push(useDefault);
1275
+ let omit = required ? void 0 : uniqueAction("Omit", actions2);
1276
+ omit && actions2.push(omit);
1277
+ let action2 = await ui.select(title, actions2);
1278
+ return action2 === void 0 ? { cancelled: !0 } : action2 === useDefault ? { cancelled: !1, value: schema.default } : action2 === omit ? { cancelled: !1, value: void 0 } : { cancelled: !1, value: choices[displays.indexOf(action2)]?.value };
1279
+ }
1280
+ if (schema.type === "boolean") {
1281
+ let actions2 = ["Yes", "No"];
1282
+ schema.default !== void 0 && actions2.push("Use default"), required || actions2.push("Omit");
1283
+ let action2 = await ui.select(title, actions2);
1284
+ return action2 === void 0 ? { cancelled: !0 } : action2 === "Use default" ? { cancelled: !1, value: schema.default } : action2 === "Omit" ? { cancelled: !1, value: void 0 } : { cancelled: !1, value: action2 === "Yes" };
1285
+ }
1286
+ if (schema.type === "array") {
1287
+ let actions2 = ["Choose values"];
1288
+ schema.default !== void 0 && actions2.push("Use default"), required || actions2.push("Omit");
1289
+ let action2 = await ui.select(title, actions2);
1290
+ if (action2 === void 0)
1291
+ return { cancelled: !0 };
1292
+ if (action2 === "Use default")
1293
+ return { cancelled: !1, value: schema.default };
1294
+ if (action2 === "Omit")
1295
+ return { cancelled: !1, value: void 0 };
1296
+ let choices = extractMultiSelectOptions(schema), selected = new Set(Array.isArray(current) ? current : []);
1297
+ for (; ; ) {
1298
+ let displays = uniqueLabels(choices.map((choice2) => selected.has(choice2.value) ? `\u2713 ${choice2.display}` : choice2.display)), done = uniqueAction("Done", displays), picked = await ui.select(title, [...displays, done]);
1299
+ if (picked === void 0)
1300
+ return { cancelled: !0 };
1301
+ if (picked === done)
1302
+ return { cancelled: !1, value: [...selected] };
1303
+ let choice = choices[displays.indexOf(picked)];
1304
+ choice && (selected.has(choice.value) ? selected.delete(choice.value) : selected.add(choice.value));
1305
+ }
1306
+ }
1307
+ let actions = ["Enter value"];
1308
+ schema.default !== void 0 && actions.push("Use default"), required || actions.push("Omit");
1309
+ let action = await ui.select(title, actions);
1310
+ if (action === void 0)
1311
+ return { cancelled: !0 };
1312
+ if (action === "Use default")
1313
+ return { cancelled: !1, value: schema.default };
1314
+ if (action === "Omit")
1315
+ return { cancelled: !1, value: void 0 };
1316
+ let entered = await ui.input(title, current === void 0 ? void 0 : String(current));
1317
+ return entered === void 0 ? { cancelled: !0 } : { cancelled: !1, value: entered };
1318
+ }
1319
+ function coerceAndValidateFormValues(params, values) {
1320
+ let output = {}, required = new Set(params.requestedSchema.required ?? []);
1321
+ for (let [name, schema] of Object.entries(params.requestedSchema.properties)) {
1322
+ let value = values[name];
1323
+ if (value === void 0) {
1324
+ if (required.has(name))
1325
+ throw new Error(`Missing required elicitation field: ${name}`);
1326
+ continue;
1327
+ }
1328
+ if (schema.type === "string") {
1329
+ let stringValue = String(value), limits = schema;
1330
+ if (limits.minLength !== void 0 && stringValue.length < limits.minLength)
1331
+ throw new Error(`Elicitation field ${name} is shorter than minimum length ${limits.minLength}`);
1332
+ if (limits.maxLength !== void 0 && stringValue.length > limits.maxLength)
1333
+ throw new Error(`Elicitation field ${name} is longer than maximum length ${limits.maxLength}`);
1334
+ if ("enum" in schema && !schema.enum.includes(stringValue))
1335
+ throw new Error(`Elicitation field ${name} is not an allowed value`);
1336
+ if ("oneOf" in schema && !schema.oneOf.some((option) => option.const === stringValue))
1337
+ throw new Error(`Elicitation field ${name} is not an allowed value`);
1338
+ output[name] = stringValue;
1339
+ continue;
1340
+ }
1341
+ if (schema.type === "number" || schema.type === "integer") {
1342
+ if (typeof value == "string" && value.trim() === "")
1343
+ throw new Error(`Elicitation field ${name} must be a number`);
1344
+ let numberValue = typeof value == "number" ? value : Number(value);
1345
+ if (!Number.isFinite(numberValue))
1346
+ throw new Error(`Elicitation field ${name} must be a number`);
1347
+ if (schema.type === "integer" && !Number.isInteger(numberValue))
1348
+ throw new Error(`Elicitation field ${name} must be an integer`);
1349
+ if (schema.minimum !== void 0 && numberValue < schema.minimum)
1350
+ throw new Error(`Elicitation field ${name} is below minimum ${schema.minimum}`);
1351
+ if (schema.maximum !== void 0 && numberValue > schema.maximum)
1352
+ throw new Error(`Elicitation field ${name} is above maximum ${schema.maximum}`);
1353
+ output[name] = numberValue;
1354
+ continue;
1355
+ }
1356
+ if (schema.type === "boolean") {
1357
+ output[name] = typeof value == "boolean" ? value : value === "true";
1358
+ continue;
1359
+ }
1360
+ if (schema.type === "array") {
1361
+ if (!Array.isArray(value))
1362
+ throw new Error(`Elicitation field ${name} must be a list`);
1363
+ let allowed = new Set(extractMultiSelectOptions(schema).map((option) => option.value)), arrayValue = value.map(String);
1364
+ if (schema.minItems !== void 0 && arrayValue.length < schema.minItems)
1365
+ throw new Error(`Elicitation field ${name} has fewer than ${schema.minItems} selections`);
1366
+ if (schema.maxItems !== void 0 && arrayValue.length > schema.maxItems)
1367
+ throw new Error(`Elicitation field ${name} has more than ${schema.maxItems} selections`);
1368
+ if (arrayValue.some((item) => !allowed.has(item)))
1369
+ throw new Error(`Elicitation field ${name} contains an invalid selection`);
1370
+ output[name] = arrayValue;
1371
+ }
1372
+ }
1373
+ let validation = new AjvJsonSchemaValidator().getValidator(params.requestedSchema)(output);
1374
+ if (!validation.valid)
1375
+ throw new Error(`Invalid elicitation response: ${validation.errorMessage}`);
1376
+ return output;
1377
+ }
1378
+ function formatChoice(value, title) {
1379
+ return title && title !== value ? `${title} (${value})` : value;
1380
+ }
1381
+ function uniqueLabels(labels) {
1382
+ let used = /* @__PURE__ */ new Set();
1383
+ return labels.map((label) => {
1384
+ let unique = label;
1385
+ for (; used.has(unique); )
1386
+ unique += "\u2026";
1387
+ return used.add(unique), unique;
1388
+ });
1389
+ }
1390
+ function uniqueAction(label, choices) {
1391
+ let unique = label;
1392
+ for (; choices.includes(unique); )
1393
+ unique += "\u2026";
1394
+ return unique;
1395
+ }
1396
+ function extractMultiSelectOptions(schema) {
1397
+ let items = schema.items;
1398
+ return items.anyOf ? items.anyOf.map((option) => ({ value: option.const, display: formatChoice(option.const, option.title) })) : (items.enum ?? []).map((value) => ({ value, display: value }));
1399
+ }
1400
+ function formatReview(serverName, properties, content) {
1401
+ let rows = properties.map(([name, schema]) => `${schema.title ?? humanizeName(name)}: ${content[name] === void 0 ? "(omitted)" : String(content[name])}`);
1402
+ return [`Review input for ${serverName}`, "", ...rows].join(`
1403
+ `);
1404
+ }
1405
+ async function handleUrlElicitation(options, params) {
1406
+ if (!options.allowUrl)
1407
+ throw new McpError(ErrorCode.InvalidParams, "URL elicitation is not supported");
1408
+ let parsed;
1409
+ try {
1410
+ parsed = new URL(params.url);
1411
+ } catch {
1412
+ throw new McpError(ErrorCode.InvalidParams, "URL elicitation supplied an invalid URL");
1413
+ }
1414
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
1415
+ throw new McpError(ErrorCode.InvalidParams, "URL elicitation only supports HTTP and HTTPS URLs");
1416
+ let decision = await options.ui.select([
1417
+ "MCP Browser Request",
1418
+ `Server: ${options.serverName}`,
1419
+ "",
1420
+ params.message,
1421
+ "",
1422
+ `Host: ${parsed.host}`,
1423
+ `Full URL: ${params.url}`,
1424
+ "",
1425
+ "Open this URL in your browser?"
1426
+ ].join(`
1427
+ `), ["Open", "Decline"]);
1428
+ if (decision === void 0)
1429
+ return { action: "cancel" };
1430
+ if (decision === "Decline")
1431
+ return { action: "decline" };
1432
+ try {
1433
+ await open(params.url);
1434
+ } catch (error) {
1435
+ return options.ui.notify(`Could not open MCP elicitation URL: ${error instanceof Error ? error.message : String(error)}`, "error"), { action: "cancel" };
1436
+ }
1437
+ return options.onUrlAccepted?.(params.elicitationId), options.ui.notify("Opened browser for MCP elicitation.", "info"), { action: "accept" };
1438
+ }
1439
+ function humanizeName(name) {
1440
+ return name.replace(/[_-]+/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^./, (char) => char.toUpperCase());
1441
+ }
1442
+
1443
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/server-manager.js
1444
+ var McpServerManager = class {
1445
+ defaultCwd;
1446
+ connections = /* @__PURE__ */ new Map();
1447
+ connectPromises = /* @__PURE__ */ new Map();
1448
+ pendingConnections = /* @__PURE__ */ new Map();
1449
+ closing = !1;
1450
+ uiStreamListeners = /* @__PURE__ */ new Map();
1451
+ samplingConfig;
1452
+ elicitationConfig;
1453
+ acceptedUrlElicitations = /* @__PURE__ */ new Map();
1454
+ defaultRequestTimeoutMs;
1455
+ /** Default cwd for stdio servers without an explicit config `cwd`. */
1456
+ constructor(defaultCwd) {
1457
+ this.defaultCwd = defaultCwd;
1458
+ }
1459
+ setSamplingConfig(config) {
1460
+ this.samplingConfig = config;
1461
+ }
1462
+ setElicitationConfig(config) {
1463
+ this.elicitationConfig = config;
1464
+ }
1465
+ setDefaultRequestTimeoutMs(timeoutMs) {
1466
+ this.defaultRequestTimeoutMs = normalizeRequestTimeoutMs(timeoutMs);
1467
+ }
1468
+ getRequestOptions(name, signal) {
1469
+ let connection = this.connections.get(name);
1470
+ return this.buildRequestOptions(connection?.definition, signal);
1471
+ }
1472
+ getResolvedRequestTimeoutMs(definition) {
1473
+ return definition?.requestTimeoutMs !== void 0 ? normalizeRequestTimeoutMs(definition.requestTimeoutMs) : this.defaultRequestTimeoutMs;
1474
+ }
1475
+ buildRequestOptions(definition, signal) {
1476
+ let timeout = this.getResolvedRequestTimeoutMs(definition);
1477
+ if (!(!signal && timeout === void 0))
1478
+ return {
1479
+ ...signal ? { signal } : {},
1480
+ ...timeout !== void 0 ? { timeout } : {}
1481
+ };
1482
+ }
1483
+ async connect(name, definition, signal) {
1484
+ if (throwIfAborted(signal), this.closing)
1485
+ throw new Error("MCP server manager is closed");
1486
+ if (this.connectPromises.has(name))
1487
+ return abortable(this.connectPromises.get(name), signal);
1488
+ let existing = this.connections.get(name);
1489
+ if (existing?.status === "connected")
1490
+ return existing.lastUsedAt = Date.now(), existing;
1491
+ let promise = this.createConnection(name, definition, signal).then(async (connection) => {
1492
+ if (this.closing || signal?.aborted)
1493
+ throw await this.disposeConnection(connection), throwIfAborted(signal), new Error("MCP server manager closed during connection");
1494
+ return this.connections.set(name, connection), connection;
1495
+ });
1496
+ this.connectPromises.set(name, promise);
1497
+ try {
1498
+ return await promise;
1499
+ } finally {
1500
+ this.connectPromises.get(name) === promise && this.connectPromises.delete(name);
1501
+ }
1502
+ }
1503
+ async createConnection(name, definition, signal) {
1504
+ throwIfAborted(signal);
1505
+ let client = this.createClient(name), transport;
1506
+ if (definition.command) {
1507
+ let command = definition.command, args = definition.args ?? [];
1508
+ if (command === "npx" || command === "npm") {
1509
+ let resolved = await resolveNpxBinary(command, args);
1510
+ resolved && (command = resolved.isJs ? "node" : resolved.binPath, args = resolved.isJs ? [resolved.binPath, ...resolved.extraArgs] : resolved.extraArgs, logger.debug(`${name} resolved to ${resolved.binPath} (skipping npm parent)`));
1511
+ }
1512
+ transport = new StdioClientTransport({
1513
+ command,
1514
+ args,
1515
+ env: resolveEnv(definition.env),
1516
+ cwd: resolveConfigPath(definition.cwd) ?? this.defaultCwd,
1517
+ stderr: definition.debug ? "inherit" : "ignore"
1518
+ });
1519
+ } else if (definition.url)
1520
+ transport = await this.createHttpTransport(definition, name, signal);
1521
+ else
1522
+ throw new Error(`Server ${name} has no command or url`);
1523
+ let requestOptions = this.buildRequestOptions(definition, signal), pending = { client, transport };
1524
+ this.pendingConnections.set(name, pending);
1525
+ try {
1526
+ await client.connect(transport, requestOptions), this.attachAdapterNotificationHandlers(name, client);
1527
+ let [tools, resources] = await Promise.all([
1528
+ this.fetchAllTools(client, requestOptions),
1529
+ this.fetchAllResources(client, requestOptions)
1530
+ ]);
1531
+ return {
1532
+ client,
1533
+ transport,
1534
+ definition,
1535
+ tools,
1536
+ resources,
1537
+ lastUsedAt: Date.now(),
1538
+ inFlight: 0,
1539
+ status: "connected"
1540
+ };
1541
+ } catch (error) {
1542
+ if (error instanceof UnauthorizedError && supportsOAuth(definition))
1543
+ return await client.close().catch(() => {
1544
+ }), await transport.close().catch(() => {
1545
+ }), {
1546
+ client,
1547
+ transport,
1548
+ definition,
1549
+ tools: [],
1550
+ resources: [],
1551
+ lastUsedAt: Date.now(),
1552
+ inFlight: 0,
1553
+ status: "needs-auth"
1554
+ };
1555
+ throw await client.close().catch(() => {
1556
+ }), await transport.close().catch(() => {
1557
+ }), error;
1558
+ } finally {
1559
+ this.pendingConnections.get(name) === pending && this.pendingConnections.delete(name);
1560
+ }
1561
+ }
1562
+ buildClientCapabilities() {
1563
+ return {
1564
+ ...this.samplingConfig ? { sampling: {} } : {},
1565
+ ...this.elicitationConfig ? {
1566
+ elicitation: {
1567
+ form: {},
1568
+ ...this.elicitationConfig.allowUrl ? { url: {} } : {}
1569
+ }
1570
+ } : {}
1571
+ };
1572
+ }
1573
+ createClient(serverName) {
1574
+ let capabilities = this.buildClientCapabilities(), client = new Client({ name: `pi-mcp-${serverName}`, version: "1.0.0" }, Object.keys(capabilities).length > 0 ? { capabilities } : void 0);
1575
+ return this.samplingConfig && registerSamplingHandler(client, { ...this.samplingConfig, serverName }), this.elicitationConfig && (registerElicitationHandler(client, {
1576
+ ...this.elicitationConfig,
1577
+ serverName,
1578
+ onUrlAccepted: (elicitationId) => this.rememberUrlElicitation(serverName, elicitationId)
1579
+ }), this.elicitationConfig.allowUrl && client.setNotificationHandler(ElicitationCompleteNotificationSchema, (notification) => {
1580
+ this.acceptedUrlElicitations.get(serverName)?.delete(notification.params.elicitationId) && this.elicitationConfig?.ui.notify(`MCP browser interaction for ${serverName} completed. You can retry the tool now.`, "info");
1581
+ })), client;
1582
+ }
1583
+ async handleUrlElicitationRequired(serverName, error) {
1584
+ if (!this.elicitationConfig?.allowUrl)
1585
+ return "cancel";
1586
+ for (let params of error.elicitations) {
1587
+ let result = await handleUrlElicitation({
1588
+ ...this.elicitationConfig,
1589
+ serverName,
1590
+ onUrlAccepted: (elicitationId) => this.rememberUrlElicitation(serverName, elicitationId)
1591
+ }, params);
1592
+ if (result.action !== "accept")
1593
+ return result.action;
1594
+ }
1595
+ return "accept";
1596
+ }
1597
+ rememberUrlElicitation(serverName, elicitationId) {
1598
+ let accepted = this.acceptedUrlElicitations.get(serverName);
1599
+ accepted || (accepted = /* @__PURE__ */ new Set(), this.acceptedUrlElicitations.set(serverName, accepted)), accepted.add(elicitationId);
1600
+ }
1601
+ async createHttpTransport(definition, serverName, signal) {
1602
+ throwIfAborted(signal);
1603
+ let url = new URL(definition.url), headers = resolveHeaders(definition.headers) ?? {};
1604
+ if (definition.auth === "bearer") {
1605
+ let token = resolveBearerToken(definition);
1606
+ token && (headers.Authorization = `Bearer ${token}`);
1607
+ }
1608
+ let requestInit = Object.keys(headers).length > 0 ? { headers } : void 0, authProvider;
1609
+ if (supportsOAuth(definition)) {
1610
+ let oauthConfig = extractOAuthConfig(definition);
1611
+ authProvider = new McpOAuthProvider(serverName, definition.url, oauthConfig, {
1612
+ onRedirect: async (_authUrl) => {
1613
+ }
1614
+ });
1615
+ }
1616
+ let streamableTransport = new StreamableHTTPClientTransport(url, {
1617
+ requestInit,
1618
+ authProvider
1619
+ });
1620
+ try {
1621
+ let testClient = new Client({ name: "pi-mcp-probe", version: "2.1.2" });
1622
+ return await testClient.connect(streamableTransport, this.buildRequestOptions(definition, signal)), await testClient.close().catch(() => {
1623
+ }), await streamableTransport.close().catch(() => {
1624
+ }), new StreamableHTTPClientTransport(url, { requestInit, authProvider });
1625
+ } catch (error) {
1626
+ if (await streamableTransport.close().catch(() => {
1627
+ }), signal?.aborted && throwIfAborted(signal), error instanceof UnauthorizedError)
1628
+ throw error;
1629
+ return new SSEClientTransport(url, { requestInit, authProvider });
1630
+ }
1631
+ }
1632
+ async fetchAllTools(client, requestOptions) {
1633
+ let allTools = [], cursor;
1634
+ do {
1635
+ let result = await client.listTools(cursor ? { cursor } : void 0, requestOptions);
1636
+ allTools.push(...result.tools ?? []), cursor = result.nextCursor;
1637
+ } while (cursor);
1638
+ return allTools;
1639
+ }
1640
+ async fetchAllResources(client, requestOptions) {
1641
+ try {
1642
+ let allResources = [], cursor;
1643
+ do {
1644
+ let result = await client.listResources(cursor ? { cursor } : void 0, requestOptions);
1645
+ allResources.push(...result.resources ?? []), cursor = result.nextCursor;
1646
+ } while (cursor);
1647
+ return allResources;
1648
+ } catch {
1649
+ return requestOptions?.signal?.aborted && throwIfAborted(requestOptions.signal), [];
1650
+ }
1651
+ }
1652
+ attachAdapterNotificationHandlers(serverName, client) {
1653
+ client.setNotificationHandler(serverStreamResultPatchNotificationSchema, (notification) => {
1654
+ let listener = this.uiStreamListeners.get(notification.params.streamToken);
1655
+ listener && listener(serverName, notification.params);
1656
+ });
1657
+ }
1658
+ registerUiStreamListener(streamToken, listener) {
1659
+ this.uiStreamListeners.set(streamToken, listener);
1660
+ }
1661
+ removeUiStreamListener(streamToken) {
1662
+ this.uiStreamListeners.delete(streamToken);
1663
+ }
1664
+ async readResource(name, uri, signal) {
1665
+ let connection = this.connections.get(name);
1666
+ if (!connection || connection.status !== "connected")
1667
+ throw new Error(`Server "${name}" is not connected`);
1668
+ try {
1669
+ return this.touch(name), this.incrementInFlight(name), await connection.client.readResource({ uri }, this.getRequestOptions(name, signal));
1670
+ } finally {
1671
+ this.decrementInFlight(name), this.touch(name);
1672
+ }
1673
+ }
1674
+ async disposeConnection(connection) {
1675
+ await connection.client.close().catch(() => {
1676
+ }), await connection.transport.close().catch(() => {
1677
+ });
1678
+ }
1679
+ async close(name) {
1680
+ let connection = this.connections.get(name);
1681
+ connection && (connection.status = "closed", this.connections.delete(name), this.acceptedUrlElicitations.delete(name), await this.disposeConnection(connection));
1682
+ }
1683
+ async closeAll() {
1684
+ this.closing = !0;
1685
+ let names = [...this.connections.keys()], pending = [...this.pendingConnections.values()];
1686
+ await Promise.all([
1687
+ ...names.map((name) => this.close(name)),
1688
+ ...pending.map((connection) => this.disposeConnection(connection))
1689
+ ]);
1690
+ }
1691
+ getConnection(name) {
1692
+ return this.connections.get(name);
1693
+ }
1694
+ getAllConnections() {
1695
+ return new Map(this.connections);
1696
+ }
1697
+ touch(name) {
1698
+ let connection = this.connections.get(name);
1699
+ connection && (connection.lastUsedAt = Date.now());
1700
+ }
1701
+ incrementInFlight(name) {
1702
+ let connection = this.connections.get(name);
1703
+ connection && (connection.inFlight = (connection.inFlight ?? 0) + 1);
1704
+ }
1705
+ decrementInFlight(name) {
1706
+ let connection = this.connections.get(name);
1707
+ connection && connection.inFlight && connection.inFlight--;
1708
+ }
1709
+ isIdle(name, timeoutMs) {
1710
+ let connection = this.connections.get(name);
1711
+ return !connection || connection.status !== "connected" || connection.inFlight > 0 ? !1 : Date.now() - connection.lastUsedAt > timeoutMs;
1712
+ }
1713
+ };
1714
+ function resolveEnv(env) {
1715
+ let resolved = {};
1716
+ for (let [key, value] of Object.entries(process.env))
1717
+ value !== void 0 && (resolved[key] = value);
1718
+ if (!env)
1719
+ return resolved;
1720
+ let overrides = interpolateEnvRecord(env);
1721
+ return overrides ? { ...resolved, ...overrides } : resolved;
1722
+ }
1723
+ function resolveHeaders(headers) {
1724
+ return interpolateEnvRecord(headers);
1725
+ }
1726
+ function normalizeRequestTimeoutMs(timeoutMs) {
1727
+ return typeof timeoutMs == "number" && Number.isFinite(timeoutMs) && timeoutMs > 0 ? timeoutMs : void 0;
1728
+ }
1729
+
1730
+ // node_modules/@modelcontextprotocol/ext-apps/dist/src/app-bridge.js
1731
+ var ZQ = ((X) => typeof __require < "u" ? __require : typeof Proxy < "u" ? new Proxy(X, { get: (Y, Z) => (typeof __require < "u" ? __require : Y)[Z] }) : X)(function(X) {
1732
+ if (typeof __require < "u") return __require.apply(this, arguments);
1733
+ throw Error('Dynamic require of "' + X + '" is not supported');
1734
+ });
1735
+ var r = external_exports.union([external_exports.literal("light"), external_exports.literal("dark")]).describe("Color theme preference for the host environment."), B = external_exports.union([external_exports.literal("inline"), external_exports.literal("fullscreen"), external_exports.literal("pip")]).describe("Display mode for UI presentation."), HQ = external_exports.union([external_exports.literal("--color-background-primary"), external_exports.literal("--color-background-secondary"), external_exports.literal("--color-background-tertiary"), external_exports.literal("--color-background-inverse"), external_exports.literal("--color-background-ghost"), external_exports.literal("--color-background-info"), external_exports.literal("--color-background-danger"), external_exports.literal("--color-background-success"), external_exports.literal("--color-background-warning"), external_exports.literal("--color-background-disabled"), external_exports.literal("--color-text-primary"), external_exports.literal("--color-text-secondary"), external_exports.literal("--color-text-tertiary"), external_exports.literal("--color-text-inverse"), external_exports.literal("--color-text-ghost"), external_exports.literal("--color-text-info"), external_exports.literal("--color-text-danger"), external_exports.literal("--color-text-success"), external_exports.literal("--color-text-warning"), external_exports.literal("--color-text-disabled"), external_exports.literal("--color-border-primary"), external_exports.literal("--color-border-secondary"), external_exports.literal("--color-border-tertiary"), external_exports.literal("--color-border-inverse"), external_exports.literal("--color-border-ghost"), external_exports.literal("--color-border-info"), external_exports.literal("--color-border-danger"), external_exports.literal("--color-border-success"), external_exports.literal("--color-border-warning"), external_exports.literal("--color-border-disabled"), external_exports.literal("--color-ring-primary"), external_exports.literal("--color-ring-secondary"), external_exports.literal("--color-ring-inverse"), external_exports.literal("--color-ring-info"), external_exports.literal("--color-ring-danger"), external_exports.literal("--color-ring-success"), external_exports.literal("--color-ring-warning"), external_exports.literal("--font-sans"), external_exports.literal("--font-mono"), external_exports.literal("--font-weight-normal"), external_exports.literal("--font-weight-medium"), external_exports.literal("--font-weight-semibold"), external_exports.literal("--font-weight-bold"), external_exports.literal("--font-text-xs-size"), external_exports.literal("--font-text-sm-size"), external_exports.literal("--font-text-md-size"), external_exports.literal("--font-text-lg-size"), external_exports.literal("--font-heading-xs-size"), external_exports.literal("--font-heading-sm-size"), external_exports.literal("--font-heading-md-size"), external_exports.literal("--font-heading-lg-size"), external_exports.literal("--font-heading-xl-size"), external_exports.literal("--font-heading-2xl-size"), external_exports.literal("--font-heading-3xl-size"), external_exports.literal("--font-text-xs-line-height"), external_exports.literal("--font-text-sm-line-height"), external_exports.literal("--font-text-md-line-height"), external_exports.literal("--font-text-lg-line-height"), external_exports.literal("--font-heading-xs-line-height"), external_exports.literal("--font-heading-sm-line-height"), external_exports.literal("--font-heading-md-line-height"), external_exports.literal("--font-heading-lg-line-height"), external_exports.literal("--font-heading-xl-line-height"), external_exports.literal("--font-heading-2xl-line-height"), external_exports.literal("--font-heading-3xl-line-height"), external_exports.literal("--border-radius-xs"), external_exports.literal("--border-radius-sm"), external_exports.literal("--border-radius-md"), external_exports.literal("--border-radius-lg"), external_exports.literal("--border-radius-xl"), external_exports.literal("--border-radius-full"), external_exports.literal("--border-width-regular"), external_exports.literal("--shadow-hairline"), external_exports.literal("--shadow-sm"), external_exports.literal("--shadow-md"), external_exports.literal("--shadow-lg")]).describe("CSS variable keys available to MCP apps for theming."), RQ = external_exports.record(HQ.describe(`Style variables for theming MCP apps.
1736
+
1737
+ Individual style keys are optional - hosts may provide any subset of these values.
1738
+ Values are strings containing CSS values (colors, sizes, font stacks, etc.).
1739
+
1740
+ Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
1741
+ for compatibility with Zod schema generation. Both are functionally equivalent for validation.`), external_exports.union([external_exports.string(), external_exports.undefined()]).describe(`Style variables for theming MCP apps.
1742
+
1743
+ Individual style keys are optional - hosts may provide any subset of these values.
1744
+ Values are strings containing CSS values (colors, sizes, font stacks, etc.).
1745
+
1746
+ Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
1747
+ for compatibility with Zod schema generation. Both are functionally equivalent for validation.`)).describe(`Style variables for theming MCP apps.
1748
+
1749
+ Individual style keys are optional - hosts may provide any subset of these values.
1750
+ Values are strings containing CSS values (colors, sizes, font stacks, etc.).
1751
+
1752
+ Note: This type uses \`Record<K, string | undefined>\` rather than \`Partial<Record<K, string>>\`
1753
+ for compatibility with Zod schema generation. Both are functionally equivalent for validation.`), L = external_exports.object({ method: external_exports.literal("ui/open-link"), params: external_exports.object({ url: external_exports.string().describe("URL to open in the host's browser") }) }), P = external_exports.object({ isError: external_exports.boolean().optional().describe("True if the host failed to open the URL (e.g., due to security policy).") }).passthrough(), A = external_exports.object({ isError: external_exports.boolean().optional().describe("True if the download failed (e.g., user cancelled or host denied).") }).passthrough(), U = external_exports.object({ isError: external_exports.boolean().optional().describe("True if the host rejected or failed to deliver the message.") }).passthrough(), w = external_exports.object({ method: external_exports.literal("ui/notifications/sandbox-proxy-ready"), params: external_exports.object({}) }), O = external_exports.object({ connectDomains: external_exports.array(external_exports.string()).optional().describe(`Origins for network requests (fetch/XHR/WebSocket).
1754
+
1755
+ - Maps to CSP \`connect-src\` directive
1756
+ - Empty or omitted \u2192 no network connections (secure default)`), resourceDomains: external_exports.array(external_exports.string()).optional().describe("Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted \u2192 no network resources (secure default)"), frameDomains: external_exports.array(external_exports.string()).optional().describe("Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted \u2192 no nested iframes allowed (`frame-src 'none'`)"), baseUriDomains: external_exports.array(external_exports.string()).optional().describe("Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted \u2192 only same origin allowed (`base-uri 'self'`)") }), z = external_exports.object({ camera: external_exports.object({}).optional().describe("Request camera access.\n\nMaps to Permission Policy `camera` feature."), microphone: external_exports.object({}).optional().describe("Request microphone access.\n\nMaps to Permission Policy `microphone` feature."), geolocation: external_exports.object({}).optional().describe("Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature."), clipboardWrite: external_exports.object({}).optional().describe("Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.") }), H = external_exports.object({ method: external_exports.literal("ui/notifications/size-changed"), params: external_exports.object({ width: external_exports.number().optional().describe("New width in pixels."), height: external_exports.number().optional().describe("New height in pixels.") }) }), R = external_exports.object({ method: external_exports.literal("ui/notifications/tool-input"), params: external_exports.object({ arguments: external_exports.record(external_exports.string(), external_exports.unknown().describe("Complete tool call arguments as key-value pairs.")).optional().describe("Complete tool call arguments as key-value pairs.") }) }), T = external_exports.object({ method: external_exports.literal("ui/notifications/tool-input-partial"), params: external_exports.object({ arguments: external_exports.record(external_exports.string(), external_exports.unknown().describe("Partial tool call arguments (incomplete, may change).")).optional().describe("Partial tool call arguments (incomplete, may change).") }) }), M = external_exports.object({ method: external_exports.literal("ui/notifications/tool-cancelled"), params: external_exports.object({ reason: external_exports.string().optional().describe('Optional reason for the cancellation (e.g., "user action", "timeout").') }) }), o = external_exports.object({ fonts: external_exports.string().optional() }), s = external_exports.object({ variables: RQ.optional().describe("CSS variables for theming the app."), css: o.optional().describe("CSS blocks that apps can inject.") }), C = external_exports.object({ method: external_exports.literal("ui/resource-teardown"), params: external_exports.object({}) }), S = external_exports.record(external_exports.string(), external_exports.unknown()), F = external_exports.object({ text: external_exports.object({}).optional().describe("Host supports text content blocks."), image: external_exports.object({}).optional().describe("Host supports image content blocks."), audio: external_exports.object({}).optional().describe("Host supports audio content blocks."), resource: external_exports.object({}).optional().describe("Host supports resource content blocks."), resourceLink: external_exports.object({}).optional().describe("Host supports resource link content blocks."), structuredContent: external_exports.object({}).optional().describe("Host supports structured content.") }), q = external_exports.object({ method: external_exports.literal("ui/notifications/request-teardown"), params: external_exports.object({}).optional() }), t = external_exports.object({ experimental: external_exports.object({}).optional().describe("Experimental features (structure TBD)."), openLinks: external_exports.object({}).optional().describe("Host supports opening external URLs."), downloadFile: external_exports.object({}).optional().describe("Host supports file downloads via ui/download-file."), serverTools: external_exports.object({ listChanged: external_exports.boolean().optional().describe("Host supports tools/list_changed notifications.") }).optional().describe("Host can proxy tool calls to the MCP server."), serverResources: external_exports.object({ listChanged: external_exports.boolean().optional().describe("Host supports resources/list_changed notifications.") }).optional().describe("Host can proxy resource reads to the MCP server."), logging: external_exports.object({}).optional().describe("Host accepts log messages."), sandbox: external_exports.object({ permissions: z.optional().describe("Permissions granted by the host (camera, microphone, geolocation)."), csp: O.optional().describe("CSP domains approved by the host.") }).optional().describe("Sandbox configuration applied by the host."), updateModelContext: F.optional().describe("Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns."), message: F.optional().describe("Host supports receiving content messages (ui/message) from the view."), sampling: external_exports.object({ tools: external_exports.object({}).optional().describe("Host supports tool use via `tools` and `toolChoice` parameters.") }).optional().describe("Host supports LLM sampling (sampling/createMessage) from the view.\nMirrors the MCP `ClientCapabilities.sampling` shape so hosts can pass it through.") }), a = external_exports.object({ experimental: external_exports.object({}).optional().describe("Experimental features (structure TBD)."), tools: external_exports.object({ listChanged: external_exports.boolean().optional().describe("App supports tools/list_changed notifications.") }).optional().describe("App exposes MCP-style tools that the host can call."), availableDisplayModes: external_exports.array(B).optional().describe("Display modes the app supports.") }), y = external_exports.object({ method: external_exports.literal("ui/notifications/initialized"), params: external_exports.object({}).optional() }), TQ = external_exports.object({ csp: O.optional().describe("Content Security Policy configuration for UI resources."), permissions: z.optional().describe("Sandbox permissions requested by the UI resource."), domain: external_exports.string().optional().describe(`Dedicated origin for view sandbox.
1757
+
1758
+ Useful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.
1759
+
1760
+ **Host-dependent:** The format and validation rules for this field are determined by each host. Servers MUST consult host-specific documentation for the expected domain format. Common patterns include:
1761
+ - Hash-based subdomains (e.g., \`{hash}.claudemcpcontent.com\`)
1762
+ - URL-derived subdomains (e.g., \`www-example-com.oaiusercontent.com\`)
1763
+
1764
+ If omitted, host uses default sandbox origin (typically per-conversation).`), prefersBorder: external_exports.boolean().optional().describe(`Visual boundary preference - true if view prefers a visible border.
1765
+
1766
+ Boolean requesting whether a visible border and background is provided by the host. Specifying an explicit value for this is recommended because hosts' defaults may vary.
1767
+
1768
+ - \`true\`: request visible border + background
1769
+ - \`false\`: request no visible border + background
1770
+ - omitted: host decides border`) }), I = external_exports.object({ method: external_exports.literal("ui/request-display-mode"), params: external_exports.object({ mode: B.describe("The display mode being requested.") }) }), g = external_exports.object({ mode: B.describe("The display mode that was actually set. May differ from requested if not supported.") }).passthrough(), e = external_exports.union([external_exports.literal("model"), external_exports.literal("app")]).describe("Tool visibility scope - who can access the tool."), MQ = external_exports.object({ resourceUri: external_exports.string().optional(), visibility: external_exports.array(e).optional().describe(`Who can access this tool. Default: ["model", "app"]
1771
+ - "model": Tool visible to and callable by the agent
1772
+ - "app": Tool callable by the app from this server only`), csp: external_exports.never().optional(), permissions: external_exports.never().optional() }), OX = external_exports.object({ mimeTypes: external_exports.array(external_exports.string()).optional().describe('Array of supported MIME types for UI resources.\nMust include `"text/html;profile=mcp-app"` for MCP Apps support.') }), f = external_exports.object({ method: external_exports.literal("ui/download-file"), params: external_exports.object({ contents: external_exports.array(external_exports.union([EmbeddedResourceSchema, ResourceLinkSchema])).describe("Resource contents to download \u2014 embedded (inline data) or linked (host fetches). Uses standard MCP resource types.") }) }), k = external_exports.object({ method: external_exports.literal("ui/message"), params: external_exports.object({ role: external_exports.literal("user").describe('Message role, currently only "user" is supported.'), content: external_exports.array(ContentBlockSchema).describe("Message content blocks (text, image, etc.).") }) }), CQ = external_exports.object({ method: external_exports.literal("ui/notifications/sandbox-resource-ready"), params: external_exports.object({ html: external_exports.string().describe("HTML content to load into the inner iframe."), sandbox: external_exports.string().optional().describe("Optional override for the inner iframe's sandbox attribute."), csp: O.optional().describe("CSP configuration from resource metadata."), permissions: z.optional().describe("Sandbox permissions from resource metadata.") }) }), v = external_exports.object({ method: external_exports.literal("ui/notifications/tool-result"), params: CallToolResultSchema.describe("Standard MCP tool execution result.") }), x = external_exports.object({ toolInfo: external_exports.object({ id: RequestIdSchema.optional().describe("JSON-RPC id of the tools/call request."), tool: ToolSchema.describe("Tool definition including name, inputSchema, etc.") }).optional().describe("Metadata of the tool call that instantiated this App."), theme: r.optional().describe("Current color theme preference."), styles: s.optional().describe("Style configuration for theming the app."), displayMode: B.optional().describe("How the UI is currently displayed."), availableDisplayModes: external_exports.array(B).optional().describe("Display modes the host supports."), containerDimensions: external_exports.union([external_exports.object({ height: external_exports.number().describe("Fixed container height in pixels.") }), external_exports.object({ maxHeight: external_exports.union([external_exports.number(), external_exports.undefined()]).optional().describe("Maximum container height in pixels.") })]).and(external_exports.union([external_exports.object({ width: external_exports.number().describe("Fixed container width in pixels.") }), external_exports.object({ maxWidth: external_exports.union([external_exports.number(), external_exports.undefined()]).optional().describe("Maximum container width in pixels.") })])).optional().describe(`Container dimensions. Represents the dimensions of the iframe or other
1773
+ container holding the app. Specify either width or maxWidth, and either height or maxHeight.`), locale: external_exports.string().optional().describe("User's language and region preference in BCP 47 format."), timeZone: external_exports.string().optional().describe("User's timezone in IANA format."), userAgent: external_exports.string().optional().describe("Host application identifier."), platform: external_exports.union([external_exports.literal("web"), external_exports.literal("desktop"), external_exports.literal("mobile")]).optional().describe("Platform type for responsive design decisions."), deviceCapabilities: external_exports.object({ touch: external_exports.boolean().optional().describe("Whether the device supports touch input."), hover: external_exports.boolean().optional().describe("Whether the device supports hover interactions.") }).optional().describe("Device input capabilities."), safeAreaInsets: external_exports.object({ top: external_exports.number().describe("Top safe area inset in pixels."), right: external_exports.number().describe("Right safe area inset in pixels."), bottom: external_exports.number().describe("Bottom safe area inset in pixels."), left: external_exports.number().describe("Left safe area inset in pixels.") }).optional().describe("Mobile safe area boundaries in pixels.") }).passthrough(), b = external_exports.object({ method: external_exports.literal("ui/notifications/host-context-changed"), params: x.describe("Partial context update containing only changed fields.") }), d = external_exports.object({ method: external_exports.literal("ui/update-model-context"), params: external_exports.object({ content: external_exports.array(ContentBlockSchema).optional().describe("Context content blocks (text, image, etc.)."), structuredContent: external_exports.record(external_exports.string(), external_exports.unknown().describe("Structured content for machine-readable context data.")).optional().describe("Structured content for machine-readable context data.") }) }), u = external_exports.object({ method: external_exports.literal("ui/initialize"), params: external_exports.object({ appInfo: ImplementationSchema.describe("App identification (name and version)."), appCapabilities: a.describe("Features and capabilities this app provides."), protocolVersion: external_exports.string().describe("Protocol version this app supports.") }) }), h = external_exports.object({ protocolVersion: external_exports.string().describe('Negotiated protocol version string (e.g., "2025-11-21").'), hostInfo: ImplementationSchema.describe("Host application identification and version."), hostCapabilities: t.describe("Features and capabilities provided by the host."), hostContext: x.describe("Rich context about the host environment.") }).passthrough();
1774
+ var i = "ui/resourceUri", pQ = "text/html;profile=mcp-app";
1775
+ function FZ(X) {
1776
+ let Z = X._meta?.ui?.resourceUri;
1777
+ if (Z === void 0 && (Z = X._meta?.[i]), typeof Z == "string" && Z.startsWith("ui://")) return Z;
1778
+ if (Z !== void 0) throw Error(`Invalid UI resource URI: ${JSON.stringify(Z)}`);
1779
+ }
1780
+ function AZ(X) {
1781
+ if (!X) return "";
1782
+ let Y = [];
1783
+ return X.camera && Y.push("camera"), X.microphone && Y.push("microphone"), X.geolocation && Y.push("geolocation"), X.clipboardWrite && Y.push("clipboard-write"), Y.join("; ");
1784
+ }
1785
+
1786
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/tool-metadata.js
1787
+ function buildToolMetadata(tools, resources, definition, serverName, prefix) {
1788
+ let metadata = [], failedTools = [];
1789
+ for (let tool of tools) {
1790
+ if (!tool?.name) {
1791
+ failedTools.push("(unnamed)");
1792
+ continue;
1793
+ }
1794
+ if (isToolExcluded(tool.name, serverName, prefix, definition.excludeTools))
1795
+ continue;
1796
+ let uiResourceUri;
1797
+ try {
1798
+ uiResourceUri = FZ({ _meta: tool._meta });
1799
+ } catch {
1800
+ failedTools.push(tool.name);
1801
+ }
1802
+ metadata.push({
1803
+ name: formatToolName(tool.name, serverName, prefix),
1804
+ originalName: tool.name,
1805
+ description: tool.description ?? "",
1806
+ inputSchema: tool.inputSchema,
1807
+ uiResourceUri,
1808
+ uiStreamMode: extractToolUiStreamMode(tool._meta)
1809
+ });
1810
+ }
1811
+ if (definition.exposeResources !== !1)
1812
+ for (let resource of resources) {
1813
+ let baseName = `get_${resourceNameToToolName(resource.name)}`;
1814
+ isToolExcluded(baseName, serverName, prefix, definition.excludeTools) || metadata.push({
1815
+ name: formatToolName(baseName, serverName, prefix),
1816
+ originalName: baseName,
1817
+ description: resource.description ?? `Read resource: ${resource.uri}`,
1818
+ resourceUri: resource.uri
1819
+ });
1820
+ }
1821
+ return { metadata, failedTools };
1822
+ }
1823
+ function getToolNames(state, serverName) {
1824
+ return state.toolMetadata.get(serverName)?.map((m) => m.name) ?? [];
1825
+ }
1826
+ function totalToolCount(state) {
1827
+ let count = 0;
1828
+ for (let metadata of state.toolMetadata.values())
1829
+ count += metadata.length;
1830
+ return count;
1831
+ }
1832
+ function findToolByName(metadata, toolName) {
1833
+ if (!metadata)
1834
+ return;
1835
+ let exact = metadata.find((m) => m.name === toolName);
1836
+ if (exact)
1837
+ return exact;
1838
+ let normalized = toolName.replace(/-/g, "_");
1839
+ return metadata.find((m) => m.name.replace(/-/g, "_") === normalized);
1840
+ }
1841
+ function formatSchema(schema, indent = " ") {
1842
+ if (!schema || typeof schema != "object" || Array.isArray(schema))
1843
+ return `${indent}(no schema)`;
1844
+ let s2 = schema;
1845
+ if (s2.type === "object" && s2.properties && typeof s2.properties == "object" && !Array.isArray(s2.properties)) {
1846
+ let props = s2.properties, required = Array.isArray(s2.required) ? s2.required.filter((name) => typeof name == "string") : [];
1847
+ if (Object.keys(props).length === 0)
1848
+ return `${indent}(no parameters)`;
1849
+ let lines2 = [];
1850
+ for (let [name, propSchema] of Object.entries(props))
1851
+ lines2.push(...formatProperty(name, propSchema, required.includes(name), indent));
1852
+ return lines2.join(`
1853
+ `);
1854
+ }
1855
+ let lines = formatNestedSchema(s2, indent);
1856
+ if (lines.length > 0)
1857
+ return lines.join(`
1858
+ `);
1859
+ let typeStr = formatType(s2);
1860
+ return typeStr ? `${indent}(${typeStr})` : `${indent}(complex schema)`;
1861
+ }
1862
+ function formatProperty(name, schema, required, indent) {
1863
+ if (!schema || typeof schema != "object" || Array.isArray(schema))
1864
+ return [`${indent}${name}${required ? " *required*" : ""}`];
1865
+ let s2 = schema, parts = [`${indent}${name}`], typeStr = formatType(s2);
1866
+ return typeStr && parts.push(`(${typeStr})`), required && parts.push("*required*"), appendSchemaAnnotations(parts, s2), [parts.join(" "), ...formatNestedSchema(s2, `${indent} `)];
1867
+ }
1868
+ function formatNestedSchema(schema, indent) {
1869
+ let lines = [];
1870
+ if (Array.isArray(schema.anyOf) && lines.push(...formatVariants("anyOf", schema.anyOf, indent)), Array.isArray(schema.oneOf) && lines.push(...formatVariants("oneOf", schema.oneOf, indent)), schema.items !== void 0 && lines.push(...formatProperty("items", schema.items, !1, indent)), schema.properties && typeof schema.properties == "object" && !Array.isArray(schema.properties)) {
1871
+ let required = Array.isArray(schema.required) ? schema.required.filter((name) => typeof name == "string") : [];
1872
+ for (let [name, propSchema] of Object.entries(schema.properties))
1873
+ lines.push(...formatProperty(name, propSchema, required.includes(name), indent));
1874
+ }
1875
+ return lines;
1876
+ }
1877
+ function formatVariants(keyword, variants, indent) {
1878
+ let lines = [`${indent}${keyword}:`];
1879
+ for (let variant of variants) {
1880
+ if (!variant || typeof variant != "object" || Array.isArray(variant)) {
1881
+ lines.push(`${indent} - ${JSON.stringify(variant)}`);
1882
+ continue;
1883
+ }
1884
+ let s2 = variant, typeStr = formatType(s2) || "schema", parts = [`${indent} - ${typeStr}`];
1885
+ appendSchemaAnnotations(parts, s2), lines.push(parts.join(" ")), lines.push(...formatNestedSchema(s2, `${indent} `));
1886
+ }
1887
+ return lines;
1888
+ }
1889
+ function formatType(schema) {
1890
+ return Object.hasOwn(schema, "const") ? `const ${JSON.stringify(schema.const)}` : Array.isArray(schema.enum) ? `enum: ${schema.enum.map((v2) => JSON.stringify(v2)).join(", ")}` : Array.isArray(schema.type) ? schema.type.map((type) => String(type)).join(" | ") : schema.type ? String(schema.type) : schema.properties && typeof schema.properties == "object" && !Array.isArray(schema.properties) ? "object" : schema.items !== void 0 ? "array" : "";
1891
+ }
1892
+ function appendSchemaAnnotations(parts, schema) {
1893
+ schema.description && typeof schema.description == "string" && parts.push(`- ${schema.description}`);
1894
+ for (let key of ["minLength", "maxLength", "minimum", "maximum", "minItems", "maxItems", "format", "pattern"])
1895
+ schema[key] !== void 0 && parts.push(`[${key}: ${JSON.stringify(schema[key])}]`);
1896
+ schema.default !== void 0 && parts.push(`[default: ${JSON.stringify(schema.default)}]`);
1897
+ }
1898
+
1899
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/ui-resource-handler.js
1900
+ var UiResourceHandler = class {
1901
+ manager;
1902
+ log = logger.child({ component: "UiResourceHandler" });
1903
+ constructor(manager) {
1904
+ this.manager = manager;
1905
+ }
1906
+ async readUiResource(serverName, uri) {
1907
+ let log = this.log.child({ server: serverName, uri });
1908
+ if (!uri.startsWith("ui://"))
1909
+ throw new ResourceParseError(uri, "URI must start with ui://", { server: serverName });
1910
+ log.debug("Fetching UI resource");
1911
+ let result;
1912
+ try {
1913
+ result = await this.manager.readResource(serverName, uri);
1914
+ } catch (error) {
1915
+ if (error instanceof UrlElicitationRequiredError)
1916
+ throw error;
1917
+ let message = error instanceof Error ? error.message : String(error);
1918
+ throw log.error("Failed to read resource", error instanceof Error ? error : void 0), new ResourceFetchError(uri, message, {
1919
+ server: serverName,
1920
+ cause: error instanceof Error ? error : void 0
1921
+ });
1922
+ }
1923
+ let content = selectContent(result, uri), mimeType = content.mimeType;
1924
+ if (mimeType && !isHtmlMimeType(mimeType))
1925
+ throw log.warn("Unsupported MIME type", { mimeType }), new ResourceParseError(uri, `unsupported MIME type "${mimeType}" (expected text/html or ${pQ})`, { server: serverName, mimeType });
1926
+ let html = toHtml(content);
1927
+ if (!html.trim())
1928
+ throw log.warn("Resource content is empty"), new ResourceParseError(uri, "content is empty", { server: serverName });
1929
+ let contentMeta = extractUiMeta(content._meta), listMeta = extractUiMeta(this.getListResourceMeta(serverName, uri));
1930
+ return log.debug("Resource loaded successfully", {
1931
+ contentLength: html.length,
1932
+ hasCsp: !!contentMeta.csp || !!listMeta.csp
1933
+ }), {
1934
+ uri: content.uri ?? uri,
1935
+ html,
1936
+ mimeType: mimeType ?? pQ,
1937
+ meta: {
1938
+ csp: contentMeta.csp ?? listMeta.csp,
1939
+ permissions: contentMeta.permissions ?? listMeta.permissions,
1940
+ domain: contentMeta.domain ?? listMeta.domain,
1941
+ prefersBorder: contentMeta.prefersBorder ?? listMeta.prefersBorder
1942
+ }
1943
+ };
1944
+ }
1945
+ getListResourceMeta(serverName, uri) {
1946
+ let connection = this.manager.getConnection(serverName);
1947
+ if (!connection?.resources?.length)
1948
+ return;
1949
+ let resource = connection.resources.find((entry) => entry.uri === uri);
1950
+ if (!(!resource || !resource._meta || typeof resource._meta != "object"))
1951
+ return resource._meta;
1952
+ }
1953
+ };
1954
+ function selectContent(result, preferredUri) {
1955
+ let contents = result.contents ?? [];
1956
+ if (contents.length === 0)
1957
+ throw new Error(`No contents returned for UI resource: ${preferredUri}`);
1958
+ let byUri = contents.find((content) => content.uri === preferredUri);
1959
+ if (byUri)
1960
+ return byUri;
1961
+ let byHtmlMime = contents.find((content) => content.mimeType && isHtmlMimeType(content.mimeType));
1962
+ return byHtmlMime || contents[0];
1963
+ }
1964
+ function isHtmlMimeType(mimeType) {
1965
+ let normalized = mimeType.toLowerCase();
1966
+ return normalized.startsWith("text/html") || normalized === pQ.toLowerCase();
1967
+ }
1968
+ function toHtml(content) {
1969
+ if (typeof content.text == "string")
1970
+ return content.text;
1971
+ if (typeof content.blob == "string")
1972
+ return Buffer.from(content.blob, "base64").toString("utf-8");
1973
+ throw new Error(`UI resource ${content.uri ?? "(unknown)"} did not include text or blob content`);
1974
+ }
1975
+ function extractUiMeta(meta) {
1976
+ if (!meta || typeof meta != "object")
1977
+ return {};
1978
+ let ui = meta.ui;
1979
+ if (!ui || typeof ui != "object")
1980
+ return {};
1981
+ let out = {};
1982
+ return ui.csp && typeof ui.csp == "object" && (out.csp = ui.csp), ui.permissions && typeof ui.permissions == "object" && (out.permissions = ui.permissions), typeof ui.domain == "string" && (out.domain = ui.domain), typeof ui.prefersBorder == "boolean" && (out.prefersBorder = ui.prefersBorder), out;
1983
+ }
1984
+
1985
+ // packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/init.js
1986
+ var FAILURE_BACKOFF_MS = 60 * 1e3;
1987
+ function isTuiMode(ctx) {
1988
+ return ctx.hasUI && ctx.mode === "tui";
1989
+ }
1990
+ async function initializeMcp(pi, ctx, options = {}) {
1991
+ let signal = options.signal ?? ctx.signal;
1992
+ throwIfAborted(signal);
1993
+ let configPath = pi.getFlag("mcp-config"), config = loadMcpConfig(configPath, ctx.cwd), manager = new McpServerManager(ctx.cwd);
1994
+ manager.setDefaultRequestTimeoutMs(config.settings?.requestTimeoutMs);
1995
+ let samplingAutoApprove = config.settings?.samplingAutoApprove === !0;
1996
+ config.settings?.sampling !== !1 && (ctx.hasUI || samplingAutoApprove) && manager.setSamplingConfig({
1997
+ autoApprove: samplingAutoApprove,
1998
+ ui: ctx.hasUI ? ctx.ui : void 0,
1999
+ modelRegistry: ctx.modelRegistry,
2000
+ getCurrentModel: () => ctx.model,
2001
+ getSignal: () => ctx.signal
2002
+ }), config.settings?.elicitation !== !1 && ctx.hasUI && manager.setElicitationConfig({
2003
+ ui: ctx.ui,
2004
+ allowUrl: isTuiMode(ctx)
2005
+ });
2006
+ let lifecycle = new McpLifecycleManager(manager), toolMetadata = /* @__PURE__ */ new Map(), failureTracker = /* @__PURE__ */ new Map(), uiResourceHandler = new UiResourceHandler(manager), consentManager = new ConsentManager("once-per-server"), ui = ctx.hasUI ? ctx.ui : void 0, state = {
2007
+ manager,
2008
+ lifecycle,
2009
+ toolMetadata,
2010
+ config,
2011
+ failureTracker,
2012
+ uiResourceHandler,
2013
+ consentManager,
2014
+ uiServer: null,
2015
+ completedUiSessions: [],
2016
+ openBrowser: (url) => openUrl(pi, url, process.env.BROWSER),
2017
+ ui,
2018
+ sendMessage: (message, options2) => pi.sendMessage(message, options2)
2019
+ };
2020
+ options.onState?.(state);
2021
+ let serverEntries = Object.entries(config.mcpServers);
2022
+ if (serverEntries.length === 0)
2023
+ return state;
2024
+ let idleSetting = typeof config.settings?.idleTimeout == "number" ? config.settings.idleTimeout : 10;
2025
+ lifecycle.setGlobalIdleTimeout(idleSetting);
2026
+ let cachePath = getMetadataCachePath(), cacheFileExists = existsSync2(cachePath), cache = loadMetadataCache(), bootstrapAll = !1;
2027
+ cacheFileExists ? cache || (cache = { version: 1, servers: {} }, saveMetadataCache(cache)) : (bootstrapAll = !0, saveMetadataCache({ version: 1, servers: {} }));
2028
+ let prefix = config.settings?.toolPrefix ?? "server";
2029
+ for (let [name, definition] of serverEntries) {
2030
+ let lifecycleMode = definition.lifecycle ?? "lazy", idleOverride = definition.idleTimeout ?? (lifecycleMode === "eager" ? 0 : void 0);
2031
+ if (lifecycle.registerServer(name, definition, idleOverride !== void 0 ? { idleTimeout: idleOverride } : void 0), lifecycleMode === "keep-alive" && lifecycle.markKeepAlive(name, definition), cache?.servers?.[name] && isServerCacheValid(cache.servers[name], definition)) {
2032
+ let metadata = reconstructToolMetadata(name, cache.servers[name], prefix, definition);
2033
+ toolMetadata.set(name, metadata);
2034
+ }
2035
+ }
2036
+ let startupServers = bootstrapAll ? serverEntries : serverEntries.filter(([, definition]) => {
2037
+ let mode = definition.lifecycle ?? "lazy";
2038
+ return mode === "keep-alive" || mode === "eager";
2039
+ });
2040
+ ctx.hasUI && startupServers.length > 0 && ctx.ui.setStatus("mcp", `MCP: connecting to ${startupServers.length} servers...`);
2041
+ let results = await parallelLimit(startupServers, 10, async ([name, definition]) => {
2042
+ try {
2043
+ throwIfAborted(signal);
2044
+ let connection = await manager.connect(name, definition, signal);
2045
+ return connection.status === "needs-auth" ? { name, definition, connection: null, error: `OAuth authentication required. Run /mcp-auth ${name}.` } : { name, definition, connection, error: null };
2046
+ } catch (error) {
2047
+ let message = error instanceof Error ? error.message : String(error);
2048
+ return { name, definition, connection: null, error: message };
2049
+ }
2050
+ });
2051
+ throwIfAborted(signal);
2052
+ for (let { name, definition, connection, error } of results) {
2053
+ if (error || !connection) {
2054
+ ctx.hasUI && ctx.ui.notify(`MCP: Failed to connect to ${name}: ${error}`, "error"), console.error(`MCP: Failed to connect to ${name}: ${error}`);
2055
+ continue;
2056
+ }
2057
+ let { metadata, failedTools } = buildToolMetadata(connection.tools, connection.resources, definition, name, prefix);
2058
+ toolMetadata.set(name, metadata), updateMetadataCache(state, name), failedTools.length > 0 && ctx.hasUI && ctx.ui.notify(`MCP: ${name} - ${failedTools.length} tools skipped`, "warning");
2059
+ }
2060
+ let connectedCount = results.filter((r2) => r2.connection).length, failedCount = results.filter((r2) => r2.error).length;
2061
+ if (ctx.hasUI && connectedCount > 0) {
2062
+ let totalTools = totalToolCount(state), msg = failedCount > 0 ? `MCP: ${connectedCount}/${startupServers.length} servers connected (${totalTools} tools)` : `MCP: ${connectedCount} servers connected (${totalTools} tools)`;
2063
+ ctx.ui.notify(msg, "info");
2064
+ }
2065
+ if (process.env.MCP_DIRECT_TOOLS !== "__none__") {
2066
+ let currentCache = loadMetadataCache(), missingCacheServers = getMissingConfiguredDirectToolServers(config, currentCache);
2067
+ if (missingCacheServers.length > 0) {
2068
+ let bootstrapResults = await parallelLimit(missingCacheServers.filter((name) => !results.some((r2) => r2.name === name && r2.connection)), 10, async (name) => {
2069
+ let definition = config.mcpServers[name];
2070
+ try {
2071
+ throwIfAborted(signal);
2072
+ let connection = await manager.connect(name, definition, signal);
2073
+ if (connection.status === "needs-auth")
2074
+ return { name, ok: !1 };
2075
+ let { metadata } = buildToolMetadata(connection.tools, connection.resources, definition, name, prefix);
2076
+ return toolMetadata.set(name, metadata), updateMetadataCache(state, name), { name, ok: !0 };
2077
+ } catch (error) {
2078
+ let message = error instanceof Error ? error.message : String(error);
2079
+ return logger.debug(`MCP: direct-tools bootstrap failed for ${name}: ${message}`), { name, ok: !1 };
2080
+ }
2081
+ });
2082
+ throwIfAborted(signal);
2083
+ let bootstrapped = bootstrapResults.filter((r2) => r2.ok).map((r2) => r2.name);
2084
+ bootstrapped.length > 0 && ctx.hasUI && ctx.ui.notify(`MCP: direct tools for ${bootstrapped.join(", ")} will be available after restart`, "info");
2085
+ }
2086
+ }
2087
+ return lifecycle.setReconnectCallback((serverName) => {
2088
+ updateServerMetadata(state, serverName), updateMetadataCache(state, serverName), state.failureTracker.delete(serverName), updateStatusBar(state);
2089
+ }), lifecycle.setIdleShutdownCallback((serverName) => {
2090
+ let idleMinutes = getEffectiveIdleTimeoutMinutes(state, serverName);
2091
+ logger.debug(`${serverName} shut down (idle ${idleMinutes}m)`), updateStatusBar(state);
2092
+ }), lifecycle.startHealthChecks(), state;
2093
+ }
2094
+ function updateServerMetadata(state, serverName) {
2095
+ let connection = state.manager.getConnection(serverName);
2096
+ if (!connection || connection.status !== "connected")
2097
+ return;
2098
+ let definition = state.config.mcpServers[serverName];
2099
+ if (!definition)
2100
+ return;
2101
+ let prefix = state.config.settings?.toolPrefix ?? "server", { metadata } = buildToolMetadata(connection.tools, connection.resources, definition, serverName, prefix);
2102
+ state.toolMetadata.set(serverName, metadata);
2103
+ }
2104
+ function updateMetadataCache(state, serverName) {
2105
+ let connection = state.manager.getConnection(serverName);
2106
+ if (!connection || connection.status !== "connected")
2107
+ return;
2108
+ let definition = state.config.mcpServers[serverName];
2109
+ if (!definition)
2110
+ return;
2111
+ let configHash = computeServerHash(definition), existingEntry = loadMetadataCache()?.servers?.[serverName], tools = serializeTools(connection.tools), resources = definition.exposeResources === !1 ? [] : serializeResources(connection.resources);
2112
+ definition.exposeResources !== !1 && resources.length === 0 && existingEntry?.resources?.length && existingEntry.configHash === configHash && (resources = existingEntry.resources);
2113
+ let entry = {
2114
+ configHash,
2115
+ tools,
2116
+ resources,
2117
+ cachedAt: Date.now()
2118
+ };
2119
+ saveMetadataCache({ version: 1, servers: { [serverName]: entry } });
2120
+ }
2121
+ function flushMetadataCache(state) {
2122
+ for (let [name, connection] of state.manager.getAllConnections())
2123
+ connection.status === "connected" && updateMetadataCache(state, name);
2124
+ }
2125
+ function updateStatusBar(state) {
2126
+ let ui = state.ui;
2127
+ if (!ui)
2128
+ return;
2129
+ let total = Object.keys(state.config.mcpServers).length;
2130
+ if (total === 0) {
2131
+ ui.setStatus("mcp", void 0);
2132
+ return;
2133
+ }
2134
+ let connectedCount = state.manager.getAllConnections().size;
2135
+ ui.setStatus("mcp", ui.theme.fg("accent", `MCP: ${connectedCount}/${total} servers`));
2136
+ }
2137
+ function getFailureAgeSeconds(state, serverName) {
2138
+ let failedAt = state.failureTracker.get(serverName);
2139
+ if (!failedAt)
2140
+ return null;
2141
+ let ageMs = Date.now() - failedAt;
2142
+ return ageMs > FAILURE_BACKOFF_MS ? null : Math.round(ageMs / 1e3);
2143
+ }
2144
+ async function lazyConnect(state, serverName, signal) {
2145
+ let connection = state.manager.getConnection(serverName);
2146
+ if (connection?.status === "needs-auth")
2147
+ return !1;
2148
+ if (connection?.status === "connected")
2149
+ return updateServerMetadata(state, serverName), !0;
2150
+ if (getFailureAgeSeconds(state, serverName) !== null)
2151
+ return !1;
2152
+ let definition = state.config.mcpServers[serverName];
2153
+ if (!definition)
2154
+ return !1;
2155
+ try {
2156
+ return state.ui && state.ui.setStatus("mcp", `MCP: connecting to ${serverName}...`), (await state.manager.connect(serverName, definition, signal)).status === "needs-auth" ? !1 : (state.failureTracker.delete(serverName), updateServerMetadata(state, serverName), updateMetadataCache(state, serverName), updateStatusBar(state), !0);
2157
+ } catch (error) {
2158
+ signal?.aborted && throwIfAborted(signal), state.failureTracker.set(serverName, Date.now());
2159
+ let message = error instanceof Error ? error.message : String(error);
2160
+ return logger.debug(`MCP: lazy connect failed for ${serverName}: ${message}`), updateStatusBar(state), !1;
2161
+ }
2162
+ }
2163
+ function getEffectiveIdleTimeoutMinutes(state, serverName) {
2164
+ let definition = state.config.mcpServers[serverName];
2165
+ return definition ? typeof definition.idleTimeout == "number" ? definition.idleTimeout : (definition.lifecycle ?? "lazy") === "eager" ? 0 : typeof state.config.settings?.idleTimeout == "number" ? state.config.settings.idleTimeout : 10 : typeof state.config.settings?.idleTimeout == "number" ? state.config.settings.idleTimeout : 10;
2166
+ }
2167
+
2168
+ export {
2169
+ ServerError,
2170
+ wrapError,
2171
+ logger,
2172
+ AZ,
2173
+ buildToolMetadata,
2174
+ getToolNames,
2175
+ findToolByName,
2176
+ formatSchema,
2177
+ isTuiMode,
2178
+ initializeMcp,
2179
+ updateServerMetadata,
2180
+ updateMetadataCache,
2181
+ flushMetadataCache,
2182
+ updateStatusBar,
2183
+ getFailureAgeSeconds,
2184
+ lazyConnect
2185
+ };