@akon-labs/nexus-cli 0.1.8 → 0.1.10

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 (320) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +1 -0
  3. package/README.md +3 -2
  4. package/dist/app-bridge.bundle.js +67 -0
  5. package/dist/cli.js +19934 -1869
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +1 -1
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/auto-model.d.ts +1 -1
  10. package/dist/core/auto-model.d.ts.map +1 -1
  11. package/dist/core/auto-model.js +1 -1
  12. package/dist/core/auto-model.js.map +1 -1
  13. package/dist/core/model-resolver.d.ts +2 -2
  14. package/dist/core/model-resolver.d.ts.map +1 -1
  15. package/dist/core/model-resolver.js +3 -3
  16. package/dist/core/model-resolver.js.map +1 -1
  17. package/dist/core/package-manager.d.ts +15 -0
  18. package/dist/core/package-manager.d.ts.map +1 -1
  19. package/dist/core/package-manager.js +50 -0
  20. package/dist/core/package-manager.js.map +1 -1
  21. package/dist/core/sdk.d.ts.map +1 -1
  22. package/dist/core/sdk.js +1 -1
  23. package/dist/core/sdk.js.map +1 -1
  24. package/dist/core/slash-commands.d.ts.map +1 -1
  25. package/dist/core/slash-commands.js +3 -3
  26. package/dist/core/slash-commands.js.map +1 -1
  27. package/dist/core/system-prompt.d.ts.map +1 -1
  28. package/dist/core/system-prompt.js +1 -1
  29. package/dist/core/system-prompt.js.map +1 -1
  30. package/dist/core/tools/index.d.ts +1 -1
  31. package/dist/core/tools/index.d.ts.map +1 -1
  32. package/dist/core/tools/index.js +5 -5
  33. package/dist/core/tools/index.js.map +1 -1
  34. package/dist/core/tools/websearch.d.ts.map +1 -1
  35. package/dist/core/tools/websearch.js +3 -3
  36. package/dist/core/tools/websearch.js.map +1 -1
  37. package/dist/extensions/gitnexus/gateway.d.ts +6 -6
  38. package/dist/extensions/gitnexus/gateway.d.ts.map +1 -1
  39. package/dist/extensions/gitnexus/gateway.js +4 -4
  40. package/dist/extensions/gitnexus/gateway.js.map +1 -1
  41. package/dist/extensions/gitnexus/index.d.ts.map +1 -1
  42. package/dist/extensions/gitnexus/index.js +4 -2
  43. package/dist/extensions/gitnexus/index.js.map +1 -1
  44. package/dist/extensions/mcp/abort.d.ts +3 -0
  45. package/dist/extensions/mcp/abort.d.ts.map +1 -0
  46. package/dist/extensions/mcp/abort.js +41 -0
  47. package/dist/extensions/mcp/abort.js.map +1 -0
  48. package/dist/extensions/mcp/agent-dir.d.ts +6 -0
  49. package/dist/extensions/mcp/agent-dir.d.ts.map +1 -0
  50. package/dist/extensions/mcp/agent-dir.js +18 -0
  51. package/dist/extensions/mcp/agent-dir.js.map +1 -0
  52. package/dist/extensions/mcp/agent-plugin-loader.d.ts +9 -0
  53. package/dist/extensions/mcp/agent-plugin-loader.d.ts.map +1 -0
  54. package/dist/extensions/mcp/agent-plugin-loader.js +384 -0
  55. package/dist/extensions/mcp/agent-plugin-loader.js.map +1 -0
  56. package/dist/extensions/mcp/app-bridge.bundle.js +67 -0
  57. package/dist/extensions/mcp/commands.d.ts +27 -0
  58. package/dist/extensions/mcp/commands.d.ts.map +1 -0
  59. package/dist/extensions/mcp/commands.js +629 -0
  60. package/dist/extensions/mcp/commands.js.map +1 -0
  61. package/dist/extensions/mcp/config.d.ts +121 -38
  62. package/dist/extensions/mcp/config.d.ts.map +1 -1
  63. package/dist/extensions/mcp/config.js +1030 -70
  64. package/dist/extensions/mcp/config.js.map +1 -1
  65. package/dist/extensions/mcp/consent-manager.d.ts +14 -0
  66. package/dist/extensions/mcp/consent-manager.d.ts.map +1 -0
  67. package/dist/extensions/mcp/consent-manager.js +60 -0
  68. package/dist/extensions/mcp/consent-manager.js.map +1 -0
  69. package/dist/extensions/mcp/direct-tools.d.ts +11 -0
  70. package/dist/extensions/mcp/direct-tools.d.ts.map +1 -0
  71. package/dist/extensions/mcp/direct-tools.js +562 -0
  72. package/dist/extensions/mcp/direct-tools.js.map +1 -0
  73. package/dist/extensions/mcp/elicitation-handler.d.ts +18 -0
  74. package/dist/extensions/mcp/elicitation-handler.d.ts.map +1 -0
  75. package/dist/extensions/mcp/elicitation-handler.js +320 -0
  76. package/dist/extensions/mcp/elicitation-handler.js.map +1 -0
  77. package/dist/extensions/mcp/error-signal.d.ts +16 -0
  78. package/dist/extensions/mcp/error-signal.d.ts.map +1 -0
  79. package/dist/extensions/mcp/error-signal.js +22 -0
  80. package/dist/extensions/mcp/error-signal.js.map +1 -0
  81. package/dist/extensions/mcp/errors.d.ts +104 -0
  82. package/dist/extensions/mcp/errors.d.ts.map +1 -0
  83. package/dist/extensions/mcp/errors.js +171 -0
  84. package/dist/extensions/mcp/errors.js.map +1 -0
  85. package/dist/extensions/mcp/glimpse-ui.d.ts +10 -0
  86. package/dist/extensions/mcp/glimpse-ui.d.ts.map +1 -0
  87. package/dist/extensions/mcp/glimpse-ui.js +67 -0
  88. package/dist/extensions/mcp/glimpse-ui.js.map +1 -0
  89. package/dist/extensions/mcp/host-html-template.d.ts +17 -0
  90. package/dist/extensions/mcp/host-html-template.d.ts.map +1 -0
  91. package/dist/extensions/mcp/host-html-template.js +442 -0
  92. package/dist/extensions/mcp/host-html-template.js.map +1 -0
  93. package/dist/extensions/mcp/index.d.ts +20 -15
  94. package/dist/extensions/mcp/index.d.ts.map +1 -1
  95. package/dist/extensions/mcp/index.js +1064 -82
  96. package/dist/extensions/mcp/index.js.map +1 -1
  97. package/dist/extensions/mcp/init.d.ts +28 -0
  98. package/dist/extensions/mcp/init.d.ts.map +1 -0
  99. package/dist/extensions/mcp/init.js +631 -0
  100. package/dist/extensions/mcp/init.js.map +1 -0
  101. package/dist/extensions/mcp/json-schema-validator.d.ts +3 -0
  102. package/dist/extensions/mcp/json-schema-validator.d.ts.map +1 -0
  103. package/dist/extensions/mcp/json-schema-validator.js +53 -0
  104. package/dist/extensions/mcp/json-schema-validator.js.map +1 -0
  105. package/dist/extensions/mcp/lifecycle.d.ts +56 -0
  106. package/dist/extensions/mcp/lifecycle.d.ts.map +1 -0
  107. package/dist/extensions/mcp/lifecycle.js +395 -0
  108. package/dist/extensions/mcp/lifecycle.js.map +1 -0
  109. package/dist/extensions/mcp/logger.d.ts +52 -0
  110. package/dist/extensions/mcp/logger.d.ts.map +1 -0
  111. package/dist/extensions/mcp/logger.js +134 -0
  112. package/dist/extensions/mcp/logger.js.map +1 -0
  113. package/dist/extensions/mcp/mcp-auth-flow.d.ts +117 -0
  114. package/dist/extensions/mcp/mcp-auth-flow.d.ts.map +1 -0
  115. package/dist/extensions/mcp/mcp-auth-flow.js +869 -0
  116. package/dist/extensions/mcp/mcp-auth-flow.js.map +1 -0
  117. package/dist/extensions/mcp/mcp-auth.d.ts +162 -0
  118. package/dist/extensions/mcp/mcp-auth.d.ts.map +1 -0
  119. package/dist/extensions/mcp/mcp-auth.js +897 -0
  120. package/dist/extensions/mcp/mcp-auth.js.map +1 -0
  121. package/dist/extensions/mcp/mcp-bearer-store.d.ts +25 -0
  122. package/dist/extensions/mcp/mcp-bearer-store.d.ts.map +1 -0
  123. package/dist/extensions/mcp/mcp-bearer-store.js +350 -0
  124. package/dist/extensions/mcp/mcp-bearer-store.js.map +1 -0
  125. package/dist/extensions/mcp/mcp-callback-server.d.ts +54 -0
  126. package/dist/extensions/mcp/mcp-callback-server.d.ts.map +1 -0
  127. package/dist/extensions/mcp/mcp-callback-server.js +454 -0
  128. package/dist/extensions/mcp/mcp-callback-server.js.map +1 -0
  129. package/dist/extensions/mcp/mcp-code.d.ts +48 -0
  130. package/dist/extensions/mcp/mcp-code.d.ts.map +1 -0
  131. package/dist/extensions/mcp/mcp-code.js +358 -0
  132. package/dist/extensions/mcp/mcp-code.js.map +1 -0
  133. package/dist/extensions/mcp/mcp-keyring-helper.cjs +89 -0
  134. package/dist/extensions/mcp/mcp-oauth-provider.d.ts +135 -0
  135. package/dist/extensions/mcp/mcp-oauth-provider.d.ts.map +1 -0
  136. package/dist/extensions/mcp/mcp-oauth-provider.js +491 -0
  137. package/dist/extensions/mcp/mcp-oauth-provider.js.map +1 -0
  138. package/dist/extensions/mcp/mcp-output-guard.d.ts +59 -0
  139. package/dist/extensions/mcp/mcp-output-guard.d.ts.map +1 -0
  140. package/dist/extensions/mcp/mcp-output-guard.js +343 -0
  141. package/dist/extensions/mcp/mcp-output-guard.js.map +1 -0
  142. package/dist/extensions/mcp/mcp-panel.d.ts +71 -0
  143. package/dist/extensions/mcp/mcp-panel.d.ts.map +1 -0
  144. package/dist/extensions/mcp/mcp-panel.js +973 -0
  145. package/dist/extensions/mcp/mcp-panel.js.map +1 -0
  146. package/dist/extensions/mcp/mcp-probe.d.ts +7 -0
  147. package/dist/extensions/mcp/mcp-probe.d.ts.map +1 -0
  148. package/dist/extensions/mcp/mcp-probe.js +155 -0
  149. package/dist/extensions/mcp/mcp-probe.js.map +1 -0
  150. package/dist/extensions/mcp/mcp-script-worker.mjs +130 -0
  151. package/dist/extensions/mcp/mcp-setup-panel.d.ts +85 -0
  152. package/dist/extensions/mcp/mcp-setup-panel.d.ts.map +1 -0
  153. package/dist/extensions/mcp/mcp-setup-panel.js +618 -0
  154. package/dist/extensions/mcp/mcp-setup-panel.js.map +1 -0
  155. package/dist/extensions/mcp/mcp-status.d.ts +12 -0
  156. package/dist/extensions/mcp/mcp-status.d.ts.map +1 -0
  157. package/dist/extensions/mcp/mcp-status.js +98 -0
  158. package/dist/extensions/mcp/mcp-status.js.map +1 -0
  159. package/dist/extensions/mcp/mcp-trace.d.ts +95 -0
  160. package/dist/extensions/mcp/mcp-trace.d.ts.map +1 -0
  161. package/dist/extensions/mcp/mcp-trace.js +252 -0
  162. package/dist/extensions/mcp/mcp-trace.js.map +1 -0
  163. package/dist/extensions/mcp/metadata-cache.d.ts +20 -0
  164. package/dist/extensions/mcp/metadata-cache.d.ts.map +1 -0
  165. package/dist/extensions/mcp/metadata-cache.js +318 -0
  166. package/dist/extensions/mcp/metadata-cache.js.map +1 -0
  167. package/dist/extensions/mcp/npx-resolver.d.ts +7 -0
  168. package/dist/extensions/mcp/npx-resolver.d.ts.map +1 -0
  169. package/dist/extensions/mcp/npx-resolver.js +505 -0
  170. package/dist/extensions/mcp/npx-resolver.js.map +1 -0
  171. package/dist/extensions/mcp/oauth.d.ts +21 -0
  172. package/dist/extensions/mcp/oauth.d.ts.map +1 -0
  173. package/dist/extensions/mcp/oauth.js +15 -0
  174. package/dist/extensions/mcp/oauth.js.map +1 -0
  175. package/dist/extensions/mcp/onboarding-state.d.ts +13 -0
  176. package/dist/extensions/mcp/onboarding-state.d.ts.map +1 -0
  177. package/dist/extensions/mcp/onboarding-state.js +65 -0
  178. package/dist/extensions/mcp/onboarding-state.js.map +1 -0
  179. package/dist/extensions/mcp/package-mcp-loader.d.ts +3 -0
  180. package/dist/extensions/mcp/package-mcp-loader.d.ts.map +1 -0
  181. package/dist/extensions/mcp/package-mcp-loader.js +170 -0
  182. package/dist/extensions/mcp/package-mcp-loader.js.map +1 -0
  183. package/dist/extensions/mcp/panel-keys.d.ts +21 -0
  184. package/dist/extensions/mcp/panel-keys.d.ts.map +1 -0
  185. package/dist/extensions/mcp/panel-keys.js +29 -0
  186. package/dist/extensions/mcp/panel-keys.js.map +1 -0
  187. package/dist/extensions/mcp/prompts.d.ts +63 -0
  188. package/dist/extensions/mcp/prompts.d.ts.map +1 -0
  189. package/dist/extensions/mcp/prompts.js +297 -0
  190. package/dist/extensions/mcp/prompts.js.map +1 -0
  191. package/dist/extensions/mcp/proxy-modes.d.ts +15 -0
  192. package/dist/extensions/mcp/proxy-modes.d.ts.map +1 -0
  193. package/dist/extensions/mcp/proxy-modes.js +1421 -0
  194. package/dist/extensions/mcp/proxy-modes.js.map +1 -0
  195. package/dist/extensions/mcp/request-headers-command.d.ts +11 -0
  196. package/dist/extensions/mcp/request-headers-command.d.ts.map +1 -0
  197. package/dist/extensions/mcp/request-headers-command.js +334 -0
  198. package/dist/extensions/mcp/request-headers-command.js.map +1 -0
  199. package/dist/extensions/mcp/resource-tools.d.ts +2 -0
  200. package/dist/extensions/mcp/resource-tools.d.ts.map +1 -0
  201. package/dist/extensions/mcp/resource-tools.js +15 -0
  202. package/dist/extensions/mcp/resource-tools.js.map +1 -0
  203. package/dist/extensions/mcp/runtime-owner.d.ts +14 -0
  204. package/dist/extensions/mcp/runtime-owner.d.ts.map +1 -0
  205. package/dist/extensions/mcp/runtime-owner.js +84 -0
  206. package/dist/extensions/mcp/runtime-owner.js.map +1 -0
  207. package/dist/extensions/mcp/sampling-handler.d.ts +18 -0
  208. package/dist/extensions/mcp/sampling-handler.d.ts.map +1 -0
  209. package/dist/extensions/mcp/sampling-handler.js +229 -0
  210. package/dist/extensions/mcp/sampling-handler.js.map +1 -0
  211. package/dist/extensions/mcp/search-ranking.d.ts +25 -0
  212. package/dist/extensions/mcp/search-ranking.d.ts.map +1 -0
  213. package/dist/extensions/mcp/search-ranking.js +234 -0
  214. package/dist/extensions/mcp/search-ranking.js.map +1 -0
  215. package/dist/extensions/mcp/server-manager.d.ts +116 -0
  216. package/dist/extensions/mcp/server-manager.d.ts.map +1 -0
  217. package/dist/extensions/mcp/server-manager.js +1052 -0
  218. package/dist/extensions/mcp/server-manager.js.map +1 -0
  219. package/dist/extensions/mcp/session-recovery.d.ts +27 -0
  220. package/dist/extensions/mcp/session-recovery.d.ts.map +1 -0
  221. package/dist/extensions/mcp/session-recovery.js +140 -0
  222. package/dist/extensions/mcp/session-recovery.js.map +1 -0
  223. package/dist/extensions/mcp/skills/mcp-scripting/SKILL.md +38 -0
  224. package/dist/extensions/mcp/state.d.ts +62 -0
  225. package/dist/extensions/mcp/state.d.ts.map +1 -0
  226. package/dist/extensions/mcp/state.js +2 -0
  227. package/dist/extensions/mcp/state.js.map +1 -0
  228. package/dist/extensions/mcp/tool-approval.d.ts +11 -0
  229. package/dist/extensions/mcp/tool-approval.d.ts.map +1 -0
  230. package/dist/extensions/mcp/tool-approval.js +156 -0
  231. package/dist/extensions/mcp/tool-approval.js.map +1 -0
  232. package/dist/extensions/mcp/tool-metadata.d.ts +11 -0
  233. package/dist/extensions/mcp/tool-metadata.d.ts.map +1 -0
  234. package/dist/extensions/mcp/tool-metadata.js +264 -0
  235. package/dist/extensions/mcp/tool-metadata.js.map +1 -0
  236. package/dist/extensions/mcp/tool-registrar.d.ts +21 -0
  237. package/dist/extensions/mcp/tool-registrar.d.ts.map +1 -0
  238. package/dist/extensions/mcp/tool-registrar.js +229 -0
  239. package/dist/extensions/mcp/tool-registrar.js.map +1 -0
  240. package/dist/extensions/mcp/tool-result-renderer.d.ts +83 -0
  241. package/dist/extensions/mcp/tool-result-renderer.d.ts.map +1 -0
  242. package/dist/extensions/mcp/tool-result-renderer.js +345 -0
  243. package/dist/extensions/mcp/tool-result-renderer.js.map +1 -0
  244. package/dist/extensions/mcp/ts-shape.d.ts +3 -0
  245. package/dist/extensions/mcp/ts-shape.d.ts.map +1 -0
  246. package/dist/extensions/mcp/ts-shape.js +160 -0
  247. package/dist/extensions/mcp/ts-shape.js.map +1 -0
  248. package/dist/extensions/mcp/types.d.ts +521 -0
  249. package/dist/extensions/mcp/types.d.ts.map +1 -0
  250. package/dist/extensions/mcp/types.js +294 -0
  251. package/dist/extensions/mcp/types.js.map +1 -0
  252. package/dist/extensions/mcp/ui-app-bridge-helpers.d.ts +7 -0
  253. package/dist/extensions/mcp/ui-app-bridge-helpers.d.ts.map +1 -0
  254. package/dist/extensions/mcp/ui-app-bridge-helpers.js +37 -0
  255. package/dist/extensions/mcp/ui-app-bridge-helpers.js.map +1 -0
  256. package/dist/extensions/mcp/ui-resource-handler.d.ts +18 -0
  257. package/dist/extensions/mcp/ui-resource-handler.d.ts.map +1 -0
  258. package/dist/extensions/mcp/ui-resource-handler.js +210 -0
  259. package/dist/extensions/mcp/ui-resource-handler.js.map +1 -0
  260. package/dist/extensions/mcp/ui-server.d.ts +52 -0
  261. package/dist/extensions/mcp/ui-server.d.ts.map +1 -0
  262. package/dist/extensions/mcp/ui-server.js +740 -0
  263. package/dist/extensions/mcp/ui-server.js.map +1 -0
  264. package/dist/extensions/mcp/ui-session.d.ts +40 -0
  265. package/dist/extensions/mcp/ui-session.d.ts.map +1 -0
  266. package/dist/extensions/mcp/ui-session.js +477 -0
  267. package/dist/extensions/mcp/ui-session.js.map +1 -0
  268. package/dist/extensions/mcp/ui-stream-types.d.ts +105 -0
  269. package/dist/extensions/mcp/ui-stream-types.d.ts.map +1 -0
  270. package/dist/extensions/mcp/ui-stream-types.js +61 -0
  271. package/dist/extensions/mcp/ui-stream-types.js.map +1 -0
  272. package/dist/extensions/mcp/ui-tool-visibility.d.ts +5 -0
  273. package/dist/extensions/mcp/ui-tool-visibility.d.ts.map +1 -0
  274. package/dist/extensions/mcp/ui-tool-visibility.js +27 -0
  275. package/dist/extensions/mcp/ui-tool-visibility.js.map +1 -0
  276. package/dist/extensions/mcp/unix-socket-transport.d.ts +15 -0
  277. package/dist/extensions/mcp/unix-socket-transport.d.ts.map +1 -0
  278. package/dist/extensions/mcp/unix-socket-transport.js +85 -0
  279. package/dist/extensions/mcp/unix-socket-transport.js.map +1 -0
  280. package/dist/extensions/mcp/utils.d.ts +32 -0
  281. package/dist/extensions/mcp/utils.d.ts.map +1 -0
  282. package/dist/extensions/mcp/utils.js +336 -0
  283. package/dist/extensions/mcp/utils.js.map +1 -0
  284. package/dist/extensions/subagent/index.d.ts +62 -3
  285. package/dist/extensions/subagent/index.d.ts.map +1 -1
  286. package/dist/extensions/subagent/index.js +193 -58
  287. package/dist/extensions/subagent/index.js.map +1 -1
  288. package/dist/extensions/web-access.d.ts.map +1 -1
  289. package/dist/extensions/web-access.js +1 -1
  290. package/dist/extensions/web-access.js.map +1 -1
  291. package/dist/index.d.ts +2 -0
  292. package/dist/index.d.ts.map +1 -1
  293. package/dist/index.js +20074 -2004
  294. package/dist/index.js.map +1 -1
  295. package/dist/mcp-keyring-helper.cjs +89 -0
  296. package/dist/mcp-script-worker.mjs +130 -0
  297. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  298. package/dist/modes/interactive/components/model-selector.js +1 -1
  299. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  300. package/dist/modes/interactive/components/response-separator.d.ts +1 -1
  301. package/dist/modes/interactive/components/response-separator.d.ts.map +1 -1
  302. package/dist/modes/interactive/components/response-separator.js +1 -1
  303. package/dist/modes/interactive/components/response-separator.js.map +1 -1
  304. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  305. package/dist/modes/interactive/interactive-mode.js +7 -5
  306. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  307. package/dist/rpc-entry.js +19934 -1869
  308. package/dist/skills/mcp-scripting/SKILL.md +38 -0
  309. package/dist/vendor/ai.js +282 -207
  310. package/docs/mcp.md +178 -0
  311. package/docs/pi-subagents.md +75 -0
  312. package/docs/quickstart.md +1 -1
  313. package/docs/usage.md +2 -1
  314. package/examples/extensions/pi-subagents-worker-policy.ts +86 -0
  315. package/npm-shrinkwrap.json +763 -6
  316. package/package.json +15 -4
  317. package/dist/extensions/mcp/client.d.ts +0 -86
  318. package/dist/extensions/mcp/client.d.ts.map +0 -1
  319. package/dist/extensions/mcp/client.js +0 -275
  320. package/dist/extensions/mcp/client.js.map +0 -1
@@ -0,0 +1,477 @@
1
+ import { execFile } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+ import net from "node:net";
4
+ import { UrlElicitationRequiredError } from "@modelcontextprotocol/client";
5
+ import { throwIfAborted } from "./abort.js";
6
+ import { isGlimpseAvailable, openGlimpseWindow } from "./glimpse-ui.js";
7
+ import { logger } from "./logger.js";
8
+ import { combineAbortSignals, isAbortError } from "./runtime-owner.js";
9
+ import { createUiModelContextUpdate, extractUiPromptText, UI_STREAM_HOST_CONTEXT_KEY, UI_STREAM_REQUEST_META_KEY, UI_STREAM_STRUCTURED_CONTENT_KEY, } from "./types.js";
10
+ import { startUiServer } from "./ui-server.js";
11
+ let activeGlimpseWindow = null;
12
+ export function summarizeUiSessionResult(uiSession) {
13
+ if (!uiSession) {
14
+ return {
15
+ message: "Interactive UI was unavailable; returning the tool result inline.",
16
+ uiOpen: false,
17
+ };
18
+ }
19
+ if (!uiSession.windowOpen) {
20
+ const action = uiSession.reused ? "Updated the suppressed MCP UI session." : "MCP UI window was suppressed.";
21
+ return {
22
+ message: `${action} Open manually: ${uiSession.url}`,
23
+ uiOpen: false,
24
+ uiViewer: uiSession.viewer,
25
+ uiUrl: uiSession.url,
26
+ };
27
+ }
28
+ return {
29
+ message: uiSession.reused
30
+ ? "Updated the open UI."
31
+ : "Interactive UI is open. I'll respond to your prompts and intents as you interact with it.",
32
+ uiOpen: true,
33
+ uiViewer: uiSession.viewer,
34
+ uiUrl: uiSession.url,
35
+ };
36
+ }
37
+ const MAX_COMPLETED_SESSIONS = 10;
38
+ function withStreamEnvelope(result, streamId, sequence) {
39
+ if (!streamId) {
40
+ return result;
41
+ }
42
+ const structuredContent = result.structuredContent &&
43
+ typeof result.structuredContent === "object" &&
44
+ !Array.isArray(result.structuredContent)
45
+ ? { ...result.structuredContent }
46
+ : {};
47
+ const rawEnvelope = structuredContent[UI_STREAM_STRUCTURED_CONTENT_KEY];
48
+ const envelope = rawEnvelope && typeof rawEnvelope === "object" && !Array.isArray(rawEnvelope)
49
+ ? { ...rawEnvelope }
50
+ : {
51
+ frameType: "final",
52
+ phase: "settled",
53
+ status: result.isError ? "error" : "ok",
54
+ };
55
+ structuredContent[UI_STREAM_STRUCTURED_CONTENT_KEY] = {
56
+ ...envelope,
57
+ streamId,
58
+ sequence,
59
+ };
60
+ return {
61
+ ...result,
62
+ structuredContent,
63
+ };
64
+ }
65
+ async function openInBrowser(state, url, signal) {
66
+ throwIfAborted(signal);
67
+ try {
68
+ await state.openBrowser(url);
69
+ throwIfAborted(signal);
70
+ return null;
71
+ }
72
+ catch (error) {
73
+ if (isAbortError(error, signal))
74
+ throw error;
75
+ const message = error instanceof Error ? error.message : String(error);
76
+ if (state.owner?.isActive() === false)
77
+ return null;
78
+ state.ui?.notify(`MCP UI browser open failed: ${message}`, "warning");
79
+ return message;
80
+ }
81
+ }
82
+ function isRemoteSession() {
83
+ return Boolean(process.env.SSH_CONNECTION || process.env.SSH_TTY);
84
+ }
85
+ function hasActiveRemoteLogin() {
86
+ return new Promise((resolve) => {
87
+ execFile("who", { encoding: "utf8", timeout: 2000 }, (error, out) => {
88
+ if (error) {
89
+ resolve(false);
90
+ return;
91
+ }
92
+ resolve(/\(.+\)\s*$/m.test(out));
93
+ });
94
+ });
95
+ }
96
+ function probeMoshiGateway() {
97
+ return new Promise((resolve) => {
98
+ const socket = net.connect({ host: "127.0.0.1", port: 24543 });
99
+ const done = (ok) => {
100
+ socket.destroy();
101
+ resolve(ok);
102
+ };
103
+ socket.setTimeout(300);
104
+ socket.once("connect", () => done(true));
105
+ socket.once("timeout", () => done(false));
106
+ socket.once("error", () => done(false));
107
+ });
108
+ }
109
+ function remoteAccessHint(opts) {
110
+ const lines = [
111
+ opts.openError !== null
112
+ ? "Couldn't open MCP UI here. Open it from your own device:"
113
+ : opts.openedOnHost
114
+ ? "MCP UI opened on this host. If you're controlling this session remotely, open it from your own device:"
115
+ : "This looks like a remote session - if no MCP UI appeared, open it from your own device:",
116
+ ` ${opts.url}`,
117
+ ];
118
+ if (opts.openError !== null) {
119
+ lines.push(`Browser launch failed: ${opts.openError}`);
120
+ }
121
+ if (opts.moshi) {
122
+ lines.push("Moshi: tap the preview button in the terminal title bar and pick this MCP UI server.");
123
+ }
124
+ lines.push(`SSH: run \`ssh -L ${opts.port}:127.0.0.1:${opts.port} <this-host>\` on your local machine, then open the URL above.`, "mosh can't forward ports - run that ssh command in a separate terminal.");
125
+ return lines.join("\n");
126
+ }
127
+ export async function maybeStartUiSession(state, request) {
128
+ const log = logger.child({
129
+ component: "UiSession",
130
+ server: request.serverName,
131
+ tool: request.toolName,
132
+ });
133
+ const runtimeSignal = combineAbortSignals(state.owner?.signal, request.signal) ?? new AbortController().signal;
134
+ try {
135
+ throwIfAborted(runtimeSignal);
136
+ if (state.uiServer &&
137
+ state.uiServer.serverName === request.serverName &&
138
+ state.uiServer.toolName === request.toolName) {
139
+ const existingHandle = state.uiServer;
140
+ const streamMode = request.streamMode;
141
+ const streamId = streamMode ? randomUUID() : undefined;
142
+ const streamToken = streamMode ? randomUUID() : undefined;
143
+ let active = true;
144
+ let nextStreamSequence = 0;
145
+ const cleanupStreamListener = () => {
146
+ if (streamToken) {
147
+ state.manager.removeUiStreamListener(streamToken);
148
+ }
149
+ };
150
+ existingHandle.sendToolInput(request.toolArgs);
151
+ if (streamToken) {
152
+ state.manager.registerUiStreamListener(streamToken, (serverName, notification) => {
153
+ if (!active || state.uiServer !== existingHandle)
154
+ return;
155
+ if (serverName !== request.serverName)
156
+ return;
157
+ nextStreamSequence += 1;
158
+ existingHandle.sendResultPatch(withStreamEnvelope(notification.result, streamId, nextStreamSequence));
159
+ });
160
+ }
161
+ return {
162
+ serverName: request.serverName,
163
+ toolName: request.toolName,
164
+ reused: true,
165
+ ...(streamId !== undefined ? { streamId } : {}),
166
+ ...(streamToken !== undefined ? { streamToken } : {}),
167
+ ...(streamMode !== undefined ? { streamMode } : {}),
168
+ ...(streamToken ? { requestMeta: { [UI_STREAM_REQUEST_META_KEY]: streamToken } } : {}),
169
+ url: existingHandle.url,
170
+ viewer: existingHandle.viewer ?? "browser",
171
+ windowOpen: existingHandle.windowOpen ?? true,
172
+ isActive: () => active && state.uiServer === existingHandle,
173
+ sendToolResult: (result) => {
174
+ if (!active || state.uiServer !== existingHandle)
175
+ return;
176
+ nextStreamSequence += 1;
177
+ existingHandle.sendToolResult(withStreamEnvelope(result, streamId, nextStreamSequence));
178
+ },
179
+ sendResultPatch: (result) => {
180
+ if (!active || state.uiServer !== existingHandle)
181
+ return;
182
+ nextStreamSequence += 1;
183
+ existingHandle.sendResultPatch(withStreamEnvelope(result, streamId, nextStreamSequence));
184
+ },
185
+ sendToolCancelled: (reason) => {
186
+ if (!active || state.uiServer !== existingHandle)
187
+ return;
188
+ nextStreamSequence += 1;
189
+ existingHandle.sendToolResult(withStreamEnvelope({
190
+ isError: true,
191
+ content: [{ type: "text", text: reason }],
192
+ }, streamId, nextStreamSequence));
193
+ },
194
+ close: () => {
195
+ active = false;
196
+ cleanupStreamListener();
197
+ },
198
+ };
199
+ }
200
+ const resource = await state.uiResourceHandler.readUiResource(request.serverName, request.uiResourceUri, {
201
+ config: state.config,
202
+ signal: runtimeSignal,
203
+ onNeedsAuth: request.onNeedsAuth,
204
+ });
205
+ throwIfAborted(runtimeSignal);
206
+ if (state.uiServer) {
207
+ state.uiServer.close("replaced");
208
+ state.uiServer = null;
209
+ }
210
+ if (activeGlimpseWindow) {
211
+ activeGlimpseWindow.close();
212
+ activeGlimpseWindow = null;
213
+ }
214
+ const streamMode = request.streamMode;
215
+ const streamId = streamMode ? randomUUID() : undefined;
216
+ const streamToken = streamMode ? randomUUID() : undefined;
217
+ const hostContext = streamMode && streamId
218
+ ? {
219
+ [UI_STREAM_HOST_CONTEXT_KEY]: {
220
+ mode: streamMode,
221
+ streamId,
222
+ intermediateResultPatches: streamMode === "stream-first",
223
+ partialInput: false,
224
+ },
225
+ }
226
+ : undefined;
227
+ let active = true;
228
+ let nextStreamSequence = 0;
229
+ let handle;
230
+ const cleanupStreamListener = () => {
231
+ if (streamToken) {
232
+ state.manager.removeUiStreamListener(streamToken);
233
+ }
234
+ };
235
+ handle = await startUiServer({
236
+ serverName: request.serverName,
237
+ toolName: request.toolName,
238
+ toolArgs: streamMode === "stream-first" ? {} : request.toolArgs,
239
+ resource,
240
+ manager: state.manager,
241
+ config: state.config,
242
+ state,
243
+ ...(request.onNeedsAuth ? { onNeedsAuth: request.onNeedsAuth } : {}),
244
+ consentManager: state.consentManager,
245
+ ...(hostContext !== undefined ? { hostContext } : {}),
246
+ onMessage: (params) => {
247
+ const prompt = extractUiPromptText(params);
248
+ if (prompt) {
249
+ if (state.sendMessage) {
250
+ state.sendMessage({
251
+ customType: "mcp-ui-prompt",
252
+ content: [
253
+ { type: "text", text: `User sent prompt from ${request.serverName} UI: "${prompt}"` },
254
+ ],
255
+ display: `💬 UI Prompt: ${prompt}`,
256
+ details: { server: request.serverName, tool: request.toolName, prompt },
257
+ }, { triggerTurn: true });
258
+ log.debug("Triggered agent turn for UI prompt", { prompt: prompt.slice(0, 50) });
259
+ }
260
+ }
261
+ else if (params.type === "intent" || params.intent) {
262
+ const intent = params.intent ?? "";
263
+ const intentParams = params.params;
264
+ if (intent && state.sendMessage) {
265
+ const paramsStr = intentParams ? ` ${JSON.stringify(intentParams)}` : "";
266
+ state.sendMessage({
267
+ customType: "mcp-ui-intent",
268
+ content: [
269
+ {
270
+ type: "text",
271
+ text: `User triggered intent from ${request.serverName} UI: ${intent}${paramsStr}`,
272
+ },
273
+ ],
274
+ display: `🎯 UI Intent: ${intent}`,
275
+ details: { server: request.serverName, tool: request.toolName, intent, params: intentParams },
276
+ }, { triggerTurn: true });
277
+ log.debug("Triggered agent turn for UI intent", { intent });
278
+ }
279
+ }
280
+ else if (params.type === "notify" || params.message) {
281
+ const text = params.message ?? "";
282
+ if (text && state.ui) {
283
+ state.ui.notify(`[${request.serverName}] ${text}`, "info");
284
+ }
285
+ }
286
+ },
287
+ onContextUpdate: (params) => {
288
+ const update = createUiModelContextUpdate(params);
289
+ log.debug("Model context update from UI", {
290
+ hasContent: !!params.content,
291
+ hasStructured: !!params.structuredContent,
292
+ hasUpdate: !!update,
293
+ });
294
+ if (update && state.sendMessage) {
295
+ state.sendMessage({
296
+ customType: "mcp-ui-context",
297
+ content: [
298
+ {
299
+ type: "text",
300
+ text: `User submitted model context from ${request.serverName} UI:\n${update.summary}`,
301
+ },
302
+ ],
303
+ display: "UI Context submitted",
304
+ details: { server: request.serverName, tool: request.toolName, context: update },
305
+ }, { triggerTurn: true });
306
+ }
307
+ },
308
+ onComplete: (reason) => {
309
+ active = false;
310
+ cleanupStreamListener();
311
+ if (state.uiServer === handle) {
312
+ const messages = handle.getSessionMessages();
313
+ const stream = handle.getStreamSummary();
314
+ const hasContent = messages.prompts.length > 0 ||
315
+ messages.intents.length > 0 ||
316
+ messages.notifications.length > 0 ||
317
+ messages.contexts.length > 0 ||
318
+ !!stream;
319
+ if (hasContent) {
320
+ state.completedUiSessions.push({
321
+ serverName: handle.serverName,
322
+ toolName: handle.toolName,
323
+ completedAt: new Date(),
324
+ reason,
325
+ messages,
326
+ ...(stream !== undefined ? { stream } : {}),
327
+ });
328
+ while (state.completedUiSessions.length > MAX_COMPLETED_SESSIONS) {
329
+ state.completedUiSessions.shift();
330
+ }
331
+ log.debug("Session completed", {
332
+ reason,
333
+ prompts: messages.prompts.length,
334
+ intents: messages.intents.length,
335
+ notifications: messages.notifications.length,
336
+ contexts: messages.contexts.length,
337
+ streamFrames: stream?.frames ?? 0,
338
+ });
339
+ }
340
+ state.uiServer = null;
341
+ if (activeGlimpseWindow) {
342
+ activeGlimpseWindow.close();
343
+ activeGlimpseWindow = null;
344
+ }
345
+ }
346
+ },
347
+ });
348
+ if (state.owner?.isActive() === false || runtimeSignal.aborted) {
349
+ handle.close("runtime_owner_stopped");
350
+ throwIfAborted(runtimeSignal);
351
+ throw new Error("MCP UI session became stale before registration");
352
+ }
353
+ if (streamToken) {
354
+ state.manager.registerUiStreamListener(streamToken, (serverName, notification) => {
355
+ if (!active || state.uiServer !== handle)
356
+ return;
357
+ if (serverName !== request.serverName)
358
+ return;
359
+ nextStreamSequence += 1;
360
+ handle.sendResultPatch(withStreamEnvelope(notification.result, streamId, nextStreamSequence));
361
+ });
362
+ }
363
+ state.uiServer = handle;
364
+ const viewerPref = process.env.MCP_UI_VIEWER?.toLowerCase();
365
+ const uiSuppressed = viewerPref === "none" || viewerPref === "off" || viewerPref === "disabled";
366
+ let viewer = "browser";
367
+ let windowOpen = true;
368
+ const remoteByEnv = isRemoteSession();
369
+ if (uiSuppressed) {
370
+ viewer = "suppressed";
371
+ windowOpen = false;
372
+ state.ui?.notify(`MCP UI window suppressed (MCP_UI_VIEWER=${viewerPref}). Open manually: ${handle.url}`, "info");
373
+ log.info(`Suppressing MCP UI window (MCP_UI_VIEWER=${viewerPref})`, { url: handle.url });
374
+ }
375
+ else {
376
+ const remoteLikely = remoteByEnv || (await hasActiveRemoteLogin());
377
+ const emitRemoteHint = async (openError, openedOnHost = false) => {
378
+ state.ui?.notify(remoteAccessHint({
379
+ url: handle.url,
380
+ port: handle.port,
381
+ moshi: await probeMoshiGateway(),
382
+ openError,
383
+ openedOnHost,
384
+ }), openError === null ? "info" : "warning");
385
+ };
386
+ const glimpseDetected = !remoteByEnv && isGlimpseAvailable();
387
+ const useGlimpse = !remoteByEnv && (viewerPref === "glimpse" || (viewerPref !== "browser" && glimpseDetected));
388
+ if (useGlimpse) {
389
+ try {
390
+ const glimpseHtml = `<!DOCTYPE html><html><head><meta charset="utf-8"><style>body{margin:0;padding:0;width:100vw;height:100vh;overflow:hidden}iframe{width:100%;height:100%;border:none}</style></head><body><iframe src="${handle.url}"></iframe></body></html>`;
391
+ const glimpseWindow = await openGlimpseWindow(glimpseHtml, {
392
+ title: `MCP · ${request.serverName} · ${request.toolName}`,
393
+ width: 1000,
394
+ height: 800,
395
+ onClosed: () => {
396
+ if (active)
397
+ handle.close("glimpse-closed");
398
+ },
399
+ });
400
+ if (state.owner?.isActive() === false || runtimeSignal.aborted) {
401
+ glimpseWindow.close();
402
+ throwIfAborted(runtimeSignal);
403
+ throw new Error("MCP Glimpse window became stale before registration");
404
+ }
405
+ activeGlimpseWindow = glimpseWindow;
406
+ viewer = "glimpse";
407
+ if (remoteLikely) {
408
+ await emitRemoteHint(null, true);
409
+ }
410
+ }
411
+ catch (error) {
412
+ log.debug("Glimpse unavailable, using browser", {
413
+ error: error instanceof Error ? error.message : String(error),
414
+ });
415
+ const openError = await openInBrowser(state, handle.url, runtimeSignal);
416
+ if (openError !== null || remoteLikely) {
417
+ await emitRemoteHint(openError);
418
+ }
419
+ viewer = "browser";
420
+ }
421
+ }
422
+ else {
423
+ const openError = await openInBrowser(state, handle.url, runtimeSignal);
424
+ if (openError !== null || remoteLikely) {
425
+ await emitRemoteHint(openError);
426
+ }
427
+ }
428
+ }
429
+ throwIfAborted(runtimeSignal);
430
+ handle.viewer = viewer;
431
+ handle.windowOpen = windowOpen;
432
+ return {
433
+ serverName: request.serverName,
434
+ toolName: request.toolName,
435
+ reused: false,
436
+ ...(streamId !== undefined ? { streamId } : {}),
437
+ ...(streamToken !== undefined ? { streamToken } : {}),
438
+ ...(streamMode !== undefined ? { streamMode } : {}),
439
+ ...(streamToken ? { requestMeta: { [UI_STREAM_REQUEST_META_KEY]: streamToken } } : {}),
440
+ url: handle.url,
441
+ viewer,
442
+ windowOpen,
443
+ isActive: () => active && state.uiServer === handle,
444
+ sendToolResult: (result) => {
445
+ if (!active || state.uiServer !== handle)
446
+ return;
447
+ nextStreamSequence += 1;
448
+ handle.sendToolResult(withStreamEnvelope(result, streamId, nextStreamSequence));
449
+ },
450
+ sendResultPatch: (result) => {
451
+ if (!active || state.uiServer !== handle)
452
+ return;
453
+ nextStreamSequence += 1;
454
+ handle.sendResultPatch(withStreamEnvelope(result, streamId, nextStreamSequence));
455
+ },
456
+ sendToolCancelled: (reason) => {
457
+ if (!active || state.uiServer !== handle)
458
+ return;
459
+ handle.sendToolCancelled(reason);
460
+ },
461
+ close: (reason) => {
462
+ active = false;
463
+ cleanupStreamListener();
464
+ handle.close(reason);
465
+ },
466
+ };
467
+ }
468
+ catch (error) {
469
+ if (error instanceof UrlElicitationRequiredError || isAbortError(error, runtimeSignal))
470
+ throw error;
471
+ const message = error instanceof Error ? error.message : String(error);
472
+ log.error("Failed to start UI session", error instanceof Error ? error : undefined);
473
+ state.ui?.notify(`MCP UI unavailable for ${request.toolName} (${request.serverName}): ${message}`, "warning");
474
+ return null;
475
+ }
476
+ }
477
+ //# sourceMappingURL=ui-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-session.js","sourceRoot":"","sources":["../../../src/extensions/mcp/ui-session.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { randomUUID } from \"node:crypto\";\nimport net from \"node:net\";\nimport { type CallToolResult, UrlElicitationRequiredError } from \"@modelcontextprotocol/client\";\nimport { throwIfAborted } from \"./abort.ts\";\nimport { isGlimpseAvailable, openGlimpseWindow } from \"./glimpse-ui.ts\";\nimport { logger } from \"./logger.ts\";\nimport { combineAbortSignals, isAbortError } from \"./runtime-owner.ts\";\nimport type { SessionRecoveryDeps } from \"./session-recovery.ts\";\nimport type { McpExtensionState } from \"./state.ts\";\nimport {\n\tcreateUiModelContextUpdate,\n\textractUiPromptText,\n\tUI_STREAM_HOST_CONTEXT_KEY,\n\tUI_STREAM_REQUEST_META_KEY,\n\tUI_STREAM_STRUCTURED_CONTENT_KEY,\n\ttype UiHostContext,\n\ttype UiMessageParams,\n\ttype UiModelContextParams,\n\ttype UiStreamMode,\n} from \"./types.ts\";\nimport { startUiServer, type UiServerHandle } from \"./ui-server.ts\";\n\nlet activeGlimpseWindow: { close(): void } | null = null;\n\nexport interface UiSessionRequest {\n\tserverName: string;\n\ttoolName: string;\n\ttoolArgs: Record<string, unknown>;\n\tuiResourceUri: string;\n\tstreamMode?: UiStreamMode;\n\tsignal?: AbortSignal;\n\tonNeedsAuth?: SessionRecoveryDeps[\"onNeedsAuth\"];\n}\n\nexport type UiSessionViewer = \"browser\" | \"glimpse\" | \"suppressed\";\n\nexport interface UiSessionRuntime {\n\tserverName: string;\n\ttoolName: string;\n\treused: boolean;\n\tstreamId?: string;\n\tstreamToken?: string;\n\tstreamMode?: UiStreamMode;\n\trequestMeta?: Record<string, unknown>;\n\turl: string;\n\tviewer: UiSessionViewer;\n\twindowOpen: boolean;\n\tisActive: () => boolean;\n\tsendToolResult: (result: CallToolResult) => void;\n\tsendResultPatch: (result: CallToolResult) => void;\n\tsendToolCancelled: (reason: string) => void;\n\tclose: (reason?: string) => void;\n}\n\nexport interface UiSessionResultSummary {\n\tmessage: string;\n\tuiOpen: boolean;\n\tuiViewer?: UiSessionViewer;\n\tuiUrl?: string;\n}\n\nexport function summarizeUiSessionResult(uiSession: UiSessionRuntime | null): UiSessionResultSummary {\n\tif (!uiSession) {\n\t\treturn {\n\t\t\tmessage: \"Interactive UI was unavailable; returning the tool result inline.\",\n\t\t\tuiOpen: false,\n\t\t};\n\t}\n\n\tif (!uiSession.windowOpen) {\n\t\tconst action = uiSession.reused ? \"Updated the suppressed MCP UI session.\" : \"MCP UI window was suppressed.\";\n\t\treturn {\n\t\t\tmessage: `${action} Open manually: ${uiSession.url}`,\n\t\t\tuiOpen: false,\n\t\t\tuiViewer: uiSession.viewer,\n\t\t\tuiUrl: uiSession.url,\n\t\t};\n\t}\n\n\treturn {\n\t\tmessage: uiSession.reused\n\t\t\t? \"Updated the open UI.\"\n\t\t\t: \"Interactive UI is open. I'll respond to your prompts and intents as you interact with it.\",\n\t\tuiOpen: true,\n\t\tuiViewer: uiSession.viewer,\n\t\tuiUrl: uiSession.url,\n\t};\n}\n\nconst MAX_COMPLETED_SESSIONS = 10;\n\nfunction withStreamEnvelope(result: CallToolResult, streamId: string | undefined, sequence: number): CallToolResult {\n\tif (!streamId) {\n\t\treturn result;\n\t}\n\n\tconst structuredContent: Record<string, unknown> =\n\t\tresult.structuredContent &&\n\t\ttypeof result.structuredContent === \"object\" &&\n\t\t!Array.isArray(result.structuredContent)\n\t\t\t? { ...(result.structuredContent as Record<string, unknown>) }\n\t\t\t: {};\n\n\tconst rawEnvelope = structuredContent[UI_STREAM_STRUCTURED_CONTENT_KEY];\n\tconst envelope =\n\t\trawEnvelope && typeof rawEnvelope === \"object\" && !Array.isArray(rawEnvelope)\n\t\t\t? { ...(rawEnvelope as Record<string, unknown>) }\n\t\t\t: {\n\t\t\t\t\tframeType: \"final\",\n\t\t\t\t\tphase: \"settled\",\n\t\t\t\t\tstatus: result.isError ? \"error\" : \"ok\",\n\t\t\t\t};\n\n\tstructuredContent[UI_STREAM_STRUCTURED_CONTENT_KEY] = {\n\t\t...envelope,\n\t\tstreamId,\n\t\tsequence,\n\t};\n\n\treturn {\n\t\t...result,\n\t\tstructuredContent,\n\t};\n}\n\nasync function openInBrowser(state: McpExtensionState, url: string, signal: AbortSignal): Promise<string | null> {\n\tthrowIfAborted(signal);\n\ttry {\n\t\tawait state.openBrowser(url);\n\t\tthrowIfAborted(signal);\n\t\treturn null;\n\t} catch (error) {\n\t\tif (isAbortError(error, signal)) throw error;\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (state.owner?.isActive() === false) return null;\n\t\tstate.ui?.notify(`MCP UI browser open failed: ${message}`, \"warning\");\n\t\treturn message;\n\t}\n}\n\nfunction isRemoteSession(): boolean {\n\treturn Boolean(process.env.SSH_CONNECTION || process.env.SSH_TTY);\n}\n\nfunction hasActiveRemoteLogin(): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\texecFile(\"who\", { encoding: \"utf8\", timeout: 2000 }, (error, out) => {\n\t\t\tif (error) {\n\t\t\t\tresolve(false);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve(/\\(.+\\)\\s*$/m.test(out));\n\t\t});\n\t});\n}\n\nfunction probeMoshiGateway(): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = net.connect({ host: \"127.0.0.1\", port: 24543 });\n\t\tconst done = (ok: boolean) => {\n\t\t\tsocket.destroy();\n\t\t\tresolve(ok);\n\t\t};\n\t\tsocket.setTimeout(300);\n\t\tsocket.once(\"connect\", () => done(true));\n\t\tsocket.once(\"timeout\", () => done(false));\n\t\tsocket.once(\"error\", () => done(false));\n\t});\n}\n\nfunction remoteAccessHint(opts: {\n\turl: string;\n\tport: number;\n\tmoshi: boolean;\n\topenError: string | null;\n\topenedOnHost?: boolean;\n}): string {\n\tconst lines = [\n\t\topts.openError !== null\n\t\t\t? \"Couldn't open MCP UI here. Open it from your own device:\"\n\t\t\t: opts.openedOnHost\n\t\t\t\t? \"MCP UI opened on this host. If you're controlling this session remotely, open it from your own device:\"\n\t\t\t\t: \"This looks like a remote session - if no MCP UI appeared, open it from your own device:\",\n\t\t` ${opts.url}`,\n\t];\n\tif (opts.openError !== null) {\n\t\tlines.push(`Browser launch failed: ${opts.openError}`);\n\t}\n\tif (opts.moshi) {\n\t\tlines.push(\"Moshi: tap the preview button in the terminal title bar and pick this MCP UI server.\");\n\t}\n\tlines.push(\n\t\t`SSH: run \\`ssh -L ${opts.port}:127.0.0.1:${opts.port} <this-host>\\` on your local machine, then open the URL above.`,\n\t\t\"mosh can't forward ports - run that ssh command in a separate terminal.\",\n\t);\n\treturn lines.join(\"\\n\");\n}\n\nexport async function maybeStartUiSession(\n\tstate: McpExtensionState,\n\trequest: UiSessionRequest,\n): Promise<UiSessionRuntime | null> {\n\tconst log = logger.child({\n\t\tcomponent: \"UiSession\",\n\t\tserver: request.serverName,\n\t\ttool: request.toolName,\n\t});\n\tconst runtimeSignal = combineAbortSignals(state.owner?.signal, request.signal) ?? new AbortController().signal;\n\n\ttry {\n\t\tthrowIfAborted(runtimeSignal);\n\t\tif (\n\t\t\tstate.uiServer &&\n\t\t\tstate.uiServer.serverName === request.serverName &&\n\t\t\tstate.uiServer.toolName === request.toolName\n\t\t) {\n\t\t\tconst existingHandle = state.uiServer;\n\t\t\tconst streamMode = request.streamMode;\n\t\t\tconst streamId = streamMode ? randomUUID() : undefined;\n\t\t\tconst streamToken = streamMode ? randomUUID() : undefined;\n\t\t\tlet active = true;\n\t\t\tlet nextStreamSequence = 0;\n\n\t\t\tconst cleanupStreamListener = () => {\n\t\t\t\tif (streamToken) {\n\t\t\t\t\tstate.manager.removeUiStreamListener(streamToken);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\texistingHandle.sendToolInput(request.toolArgs);\n\n\t\t\tif (streamToken) {\n\t\t\t\tstate.manager.registerUiStreamListener(streamToken, (serverName, notification) => {\n\t\t\t\t\tif (!active || state.uiServer !== existingHandle) return;\n\t\t\t\t\tif (serverName !== request.serverName) return;\n\t\t\t\t\tnextStreamSequence += 1;\n\t\t\t\t\texistingHandle.sendResultPatch(\n\t\t\t\t\t\twithStreamEnvelope(notification.result as CallToolResult, streamId, nextStreamSequence),\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tserverName: request.serverName,\n\t\t\t\ttoolName: request.toolName,\n\t\t\t\treused: true,\n\t\t\t\t...(streamId !== undefined ? { streamId } : {}),\n\t\t\t\t...(streamToken !== undefined ? { streamToken } : {}),\n\t\t\t\t...(streamMode !== undefined ? { streamMode } : {}),\n\t\t\t\t...(streamToken ? { requestMeta: { [UI_STREAM_REQUEST_META_KEY]: streamToken } } : {}),\n\t\t\t\turl: existingHandle.url,\n\t\t\t\tviewer: existingHandle.viewer ?? \"browser\",\n\t\t\t\twindowOpen: existingHandle.windowOpen ?? true,\n\t\t\t\tisActive: () => active && state.uiServer === existingHandle,\n\t\t\t\tsendToolResult: (result: CallToolResult) => {\n\t\t\t\t\tif (!active || state.uiServer !== existingHandle) return;\n\t\t\t\t\tnextStreamSequence += 1;\n\t\t\t\t\texistingHandle.sendToolResult(withStreamEnvelope(result, streamId, nextStreamSequence));\n\t\t\t\t},\n\t\t\t\tsendResultPatch: (result: CallToolResult) => {\n\t\t\t\t\tif (!active || state.uiServer !== existingHandle) return;\n\t\t\t\t\tnextStreamSequence += 1;\n\t\t\t\t\texistingHandle.sendResultPatch(withStreamEnvelope(result, streamId, nextStreamSequence));\n\t\t\t\t},\n\t\t\t\tsendToolCancelled: (reason: string) => {\n\t\t\t\t\tif (!active || state.uiServer !== existingHandle) return;\n\t\t\t\t\tnextStreamSequence += 1;\n\t\t\t\t\texistingHandle.sendToolResult(\n\t\t\t\t\t\twithStreamEnvelope(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\t\t\tcontent: [{ type: \"text\", text: reason }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tstreamId,\n\t\t\t\t\t\t\tnextStreamSequence,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tclose: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t\tcleanupStreamListener();\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst resource = await state.uiResourceHandler.readUiResource(request.serverName, request.uiResourceUri, {\n\t\t\tconfig: state.config,\n\t\t\tsignal: runtimeSignal,\n\t\t\tonNeedsAuth: request.onNeedsAuth,\n\t\t});\n\t\tthrowIfAborted(runtimeSignal);\n\n\t\tif (state.uiServer) {\n\t\t\tstate.uiServer.close(\"replaced\");\n\t\t\tstate.uiServer = null;\n\t\t}\n\t\tif (activeGlimpseWindow) {\n\t\t\tactiveGlimpseWindow.close();\n\t\t\tactiveGlimpseWindow = null;\n\t\t}\n\n\t\tconst streamMode = request.streamMode;\n\t\tconst streamId = streamMode ? randomUUID() : undefined;\n\t\tconst streamToken = streamMode ? randomUUID() : undefined;\n\t\tconst hostContext: UiHostContext | undefined =\n\t\t\tstreamMode && streamId\n\t\t\t\t? {\n\t\t\t\t\t\t[UI_STREAM_HOST_CONTEXT_KEY]: {\n\t\t\t\t\t\t\tmode: streamMode,\n\t\t\t\t\t\t\tstreamId,\n\t\t\t\t\t\t\tintermediateResultPatches: streamMode === \"stream-first\",\n\t\t\t\t\t\t\tpartialInput: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t: undefined;\n\n\t\tlet active = true;\n\t\tlet nextStreamSequence = 0;\n\t\tlet handle: UiServerHandle;\n\n\t\tconst cleanupStreamListener = () => {\n\t\t\tif (streamToken) {\n\t\t\t\tstate.manager.removeUiStreamListener(streamToken);\n\t\t\t}\n\t\t};\n\n\t\thandle = await startUiServer({\n\t\t\tserverName: request.serverName,\n\t\t\ttoolName: request.toolName,\n\t\t\ttoolArgs: streamMode === \"stream-first\" ? {} : request.toolArgs,\n\t\t\tresource,\n\t\t\tmanager: state.manager,\n\t\t\tconfig: state.config,\n\t\t\tstate,\n\t\t\t...(request.onNeedsAuth ? { onNeedsAuth: request.onNeedsAuth } : {}),\n\t\t\tconsentManager: state.consentManager,\n\t\t\t...(hostContext !== undefined ? { hostContext } : {}),\n\n\t\t\tonMessage: (params: UiMessageParams) => {\n\t\t\t\tconst prompt = extractUiPromptText(params);\n\t\t\t\tif (prompt) {\n\t\t\t\t\tif (state.sendMessage) {\n\t\t\t\t\t\tstate.sendMessage(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcustomType: \"mcp-ui-prompt\",\n\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t{ type: \"text\", text: `User sent prompt from ${request.serverName} UI: \"${prompt}\"` },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tdisplay: `💬 UI Prompt: ${prompt}`,\n\t\t\t\t\t\t\t\tdetails: { server: request.serverName, tool: request.toolName, prompt },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ triggerTurn: true },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlog.debug(\"Triggered agent turn for UI prompt\", { prompt: prompt.slice(0, 50) });\n\t\t\t\t\t}\n\t\t\t\t} else if (params.type === \"intent\" || params.intent) {\n\t\t\t\t\tconst intent = params.intent ?? \"\";\n\t\t\t\t\tconst intentParams = params.params;\n\t\t\t\t\tif (intent && state.sendMessage) {\n\t\t\t\t\t\tconst paramsStr = intentParams ? ` ${JSON.stringify(intentParams)}` : \"\";\n\t\t\t\t\t\tstate.sendMessage(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcustomType: \"mcp-ui-intent\",\n\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\t\ttext: `User triggered intent from ${request.serverName} UI: ${intent}${paramsStr}`,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tdisplay: `🎯 UI Intent: ${intent}`,\n\t\t\t\t\t\t\t\tdetails: { server: request.serverName, tool: request.toolName, intent, params: intentParams },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{ triggerTurn: true },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tlog.debug(\"Triggered agent turn for UI intent\", { intent });\n\t\t\t\t\t}\n\t\t\t\t} else if (params.type === \"notify\" || params.message) {\n\t\t\t\t\tconst text = params.message ?? \"\";\n\t\t\t\t\tif (text && state.ui) {\n\t\t\t\t\t\tstate.ui.notify(`[${request.serverName}] ${text}`, \"info\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonContextUpdate: (params: UiModelContextParams) => {\n\t\t\t\tconst update = createUiModelContextUpdate(params);\n\t\t\t\tlog.debug(\"Model context update from UI\", {\n\t\t\t\t\thasContent: !!params.content,\n\t\t\t\t\thasStructured: !!params.structuredContent,\n\t\t\t\t\thasUpdate: !!update,\n\t\t\t\t});\n\t\t\t\tif (update && state.sendMessage) {\n\t\t\t\t\tstate.sendMessage(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcustomType: \"mcp-ui-context\",\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\ttext: `User submitted model context from ${request.serverName} UI:\\n${update.summary}`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdisplay: \"UI Context submitted\",\n\t\t\t\t\t\t\tdetails: { server: request.serverName, tool: request.toolName, context: update },\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ triggerTurn: true },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tonComplete: (reason: string) => {\n\t\t\t\tactive = false;\n\t\t\t\tcleanupStreamListener();\n\n\t\t\t\tif (state.uiServer === handle) {\n\t\t\t\t\tconst messages = handle.getSessionMessages();\n\t\t\t\t\tconst stream = handle.getStreamSummary();\n\t\t\t\t\tconst hasContent =\n\t\t\t\t\t\tmessages.prompts.length > 0 ||\n\t\t\t\t\t\tmessages.intents.length > 0 ||\n\t\t\t\t\t\tmessages.notifications.length > 0 ||\n\t\t\t\t\t\tmessages.contexts.length > 0 ||\n\t\t\t\t\t\t!!stream;\n\n\t\t\t\t\tif (hasContent) {\n\t\t\t\t\t\tstate.completedUiSessions.push({\n\t\t\t\t\t\t\tserverName: handle.serverName,\n\t\t\t\t\t\t\ttoolName: handle.toolName,\n\t\t\t\t\t\t\tcompletedAt: new Date(),\n\t\t\t\t\t\t\treason,\n\t\t\t\t\t\t\tmessages,\n\t\t\t\t\t\t\t...(stream !== undefined ? { stream } : {}),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\twhile (state.completedUiSessions.length > MAX_COMPLETED_SESSIONS) {\n\t\t\t\t\t\t\tstate.completedUiSessions.shift();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlog.debug(\"Session completed\", {\n\t\t\t\t\t\t\treason,\n\t\t\t\t\t\t\tprompts: messages.prompts.length,\n\t\t\t\t\t\t\tintents: messages.intents.length,\n\t\t\t\t\t\t\tnotifications: messages.notifications.length,\n\t\t\t\t\t\t\tcontexts: messages.contexts.length,\n\t\t\t\t\t\t\tstreamFrames: stream?.frames ?? 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tstate.uiServer = null;\n\t\t\t\t\tif (activeGlimpseWindow) {\n\t\t\t\t\t\tactiveGlimpseWindow.close();\n\t\t\t\t\t\tactiveGlimpseWindow = null;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\n\t\tif (state.owner?.isActive() === false || runtimeSignal.aborted) {\n\t\t\thandle.close(\"runtime_owner_stopped\");\n\t\t\tthrowIfAborted(runtimeSignal);\n\t\t\tthrow new Error(\"MCP UI session became stale before registration\");\n\t\t}\n\n\t\tif (streamToken) {\n\t\t\tstate.manager.registerUiStreamListener(streamToken, (serverName, notification) => {\n\t\t\t\tif (!active || state.uiServer !== handle) return;\n\t\t\t\tif (serverName !== request.serverName) return;\n\t\t\t\tnextStreamSequence += 1;\n\t\t\t\thandle.sendResultPatch(\n\t\t\t\t\twithStreamEnvelope(notification.result as CallToolResult, streamId, nextStreamSequence),\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\n\t\tstate.uiServer = handle;\n\n\t\tconst viewerPref = process.env.MCP_UI_VIEWER?.toLowerCase();\n\t\tconst uiSuppressed = viewerPref === \"none\" || viewerPref === \"off\" || viewerPref === \"disabled\";\n\n\t\tlet viewer: UiSessionViewer = \"browser\";\n\t\tlet windowOpen = true;\n\t\tconst remoteByEnv = isRemoteSession();\n\n\t\tif (uiSuppressed) {\n\t\t\tviewer = \"suppressed\";\n\t\t\twindowOpen = false;\n\t\t\tstate.ui?.notify(\n\t\t\t\t`MCP UI window suppressed (MCP_UI_VIEWER=${viewerPref}). Open manually: ${handle.url}`,\n\t\t\t\t\"info\",\n\t\t\t);\n\t\t\tlog.info(`Suppressing MCP UI window (MCP_UI_VIEWER=${viewerPref})`, { url: handle.url });\n\t\t} else {\n\t\t\tconst remoteLikely = remoteByEnv || (await hasActiveRemoteLogin());\n\t\t\tconst emitRemoteHint = async (openError: string | null, openedOnHost = false) => {\n\t\t\t\tstate.ui?.notify(\n\t\t\t\t\tremoteAccessHint({\n\t\t\t\t\t\turl: handle.url,\n\t\t\t\t\t\tport: handle.port,\n\t\t\t\t\t\tmoshi: await probeMoshiGateway(),\n\t\t\t\t\t\topenError,\n\t\t\t\t\t\topenedOnHost,\n\t\t\t\t\t}),\n\t\t\t\t\topenError === null ? \"info\" : \"warning\",\n\t\t\t\t);\n\t\t\t};\n\t\t\tconst glimpseDetected = !remoteByEnv && isGlimpseAvailable();\n\t\t\tconst useGlimpse = !remoteByEnv && (viewerPref === \"glimpse\" || (viewerPref !== \"browser\" && glimpseDetected));\n\n\t\t\tif (useGlimpse) {\n\t\t\t\ttry {\n\t\t\t\t\tconst glimpseHtml = `<!DOCTYPE html><html><head><meta charset=\"utf-8\"><style>body{margin:0;padding:0;width:100vw;height:100vh;overflow:hidden}iframe{width:100%;height:100%;border:none}</style></head><body><iframe src=\"${handle.url}\"></iframe></body></html>`;\n\t\t\t\t\tconst glimpseWindow = await openGlimpseWindow(glimpseHtml, {\n\t\t\t\t\t\ttitle: `MCP · ${request.serverName} · ${request.toolName}`,\n\t\t\t\t\t\twidth: 1000,\n\t\t\t\t\t\theight: 800,\n\t\t\t\t\t\tonClosed: () => {\n\t\t\t\t\t\t\tif (active) handle.close(\"glimpse-closed\");\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tif (state.owner?.isActive() === false || runtimeSignal.aborted) {\n\t\t\t\t\t\tglimpseWindow.close();\n\t\t\t\t\t\tthrowIfAborted(runtimeSignal);\n\t\t\t\t\t\tthrow new Error(\"MCP Glimpse window became stale before registration\");\n\t\t\t\t\t}\n\t\t\t\t\tactiveGlimpseWindow = glimpseWindow;\n\t\t\t\t\tviewer = \"glimpse\";\n\t\t\t\t\tif (remoteLikely) {\n\t\t\t\t\t\tawait emitRemoteHint(null, true);\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlog.debug(\"Glimpse unavailable, using browser\", {\n\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t});\n\t\t\t\t\tconst openError = await openInBrowser(state, handle.url, runtimeSignal);\n\t\t\t\t\tif (openError !== null || remoteLikely) {\n\t\t\t\t\t\tawait emitRemoteHint(openError);\n\t\t\t\t\t}\n\t\t\t\t\tviewer = \"browser\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst openError = await openInBrowser(state, handle.url, runtimeSignal);\n\t\t\t\tif (openError !== null || remoteLikely) {\n\t\t\t\t\tawait emitRemoteHint(openError);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrowIfAborted(runtimeSignal);\n\t\thandle.viewer = viewer;\n\t\thandle.windowOpen = windowOpen;\n\n\t\treturn {\n\t\t\tserverName: request.serverName,\n\t\t\ttoolName: request.toolName,\n\t\t\treused: false,\n\t\t\t...(streamId !== undefined ? { streamId } : {}),\n\t\t\t...(streamToken !== undefined ? { streamToken } : {}),\n\t\t\t...(streamMode !== undefined ? { streamMode } : {}),\n\t\t\t...(streamToken ? { requestMeta: { [UI_STREAM_REQUEST_META_KEY]: streamToken } } : {}),\n\t\t\turl: handle.url,\n\t\t\tviewer,\n\t\t\twindowOpen,\n\t\t\tisActive: () => active && state.uiServer === handle,\n\t\t\tsendToolResult: (result: CallToolResult) => {\n\t\t\t\tif (!active || state.uiServer !== handle) return;\n\t\t\t\tnextStreamSequence += 1;\n\t\t\t\thandle.sendToolResult(withStreamEnvelope(result, streamId, nextStreamSequence));\n\t\t\t},\n\t\t\tsendResultPatch: (result: CallToolResult) => {\n\t\t\t\tif (!active || state.uiServer !== handle) return;\n\t\t\t\tnextStreamSequence += 1;\n\t\t\t\thandle.sendResultPatch(withStreamEnvelope(result, streamId, nextStreamSequence));\n\t\t\t},\n\t\t\tsendToolCancelled: (reason: string) => {\n\t\t\t\tif (!active || state.uiServer !== handle) return;\n\t\t\t\thandle.sendToolCancelled(reason);\n\t\t\t},\n\t\t\tclose: (reason?: string) => {\n\t\t\t\tactive = false;\n\t\t\t\tcleanupStreamListener();\n\t\t\t\thandle.close(reason);\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tif (error instanceof UrlElicitationRequiredError || isAbortError(error, runtimeSignal)) throw error;\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tlog.error(\"Failed to start UI session\", error instanceof Error ? error : undefined);\n\t\tstate.ui?.notify(`MCP UI unavailable for ${request.toolName} (${request.serverName}): ${message}`, \"warning\");\n\t\treturn null;\n\t}\n}\n"]}