@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 @@
1
+ {"version":3,"file":"ui-server.js","sourceRoot":"","sources":["../../../src/extensions/mcp/ui-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAmD,MAAM,WAAW,CAAC;AAC5E,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAE,gCAAgC,EAA4B,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAExH,OAAO,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EACN,0BAA0B,EAC1B,mBAAmB,EACnB,8BAA8B,EAC9B,gBAAgB,GAchB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACjH,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAE/E,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AACtC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,oBAAoB,GAAG,KAAK,CAAC;AACnC,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAC/B,MAAM,0BAA0B,GAAG,IAAI,CAAC;AACxC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,IAAI,sBAAsB,GAAG,0BAA0B,CAAC;AAgDxD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAwB,EAA2B;IACtF,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,UAAU,EAAE,CAAC;IAC1D,MAAM,eAAe,GAAG,UAAU,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC;QACxB,SAAS,EAAE,UAAU;QACrB,MAAM,EAAE,OAAO,CAAC,UAAU;QAC1B,IAAI,EAAE,OAAO,CAAC,QAAQ;QACtB,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;KACjC,CAAC,CAAC;IAEH,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAEhC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACjC,IAAI,QAAQ,GAA0B,IAAI,CAAC;IAC3C,IAAI,kBAAkB,GAAkB,OAAO,CAAC,WAAW,EAAE,WAAW,IAAI,QAAQ,CAAC;IACrF,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,MAAM,QAAQ,GAA0D,EAAE,CAAC;IAC3E,IAAI,uBAA2C,CAAC;IAChD,IAAI,aAA0C,CAAC;IAE/C,uCAAuC;IACvC,MAAM,eAAe,GAAsB;QAC1C,OAAO,EAAE,EAAE;QACX,aAAa,EAAE,EAAE;QACjB,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,EAAE;KACZ,CAAC;IAEF,MAAM,WAAW,GAAkB;QAClC,WAAW,EAAE,kBAAkB;QAC/B,qBAAqB,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAC;QACtD,QAAQ,EAAE,SAAS;QACnB,GAAG,OAAO,CAAC,WAAW;QACtB,iFAAiF;QACjF,iEAAiE;KACjE,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC7D,IAAI,oBAAoB,IAAI,OAAO,oBAAoB,KAAK,QAAQ,EAAE,CAAC;QACtE,MAAM,QAAQ,GAAI,oBAA+C,CAAC,QAAQ,CAAC;QAC3E,MAAM,IAAI,GAAI,oBAA2C,CAAC,IAAI,CAAC;QAC/D,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,cAAc,CAAC,EAAE,CAAC;YACnF,aAAa,GAAG;gBACf,QAAQ;gBACR,IAAI;gBACJ,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,EAAE;aACV,CAAC;QACH,CAAC;IACF,CAAC;IAED,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAW,EAAE,CAAC;QACpD,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO;aACpC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC;YAClC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QACjD,IAAI,CAAC,cAAc;YAAE,OAAO,KAAK,CAAC;QAClC,MAAM,UAAU,GAAG,uBAAuB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACjE,OAAO,qBAAqB,CAAC,UAAU,CAAC,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAAA,CAChF,CAAC;IAEF,MAAM,eAAe,GAAG,KAAK,EAAE,SAA0B,EAAiB,EAAE,CAAC;QAC5E,MAAM,UAAU,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAElD,+DAA2D;QAC3D,qDAAqD;QACrD,IAAI,UAAU,EAAE,CAAC;YAChB,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACzC,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;aAAM,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YAC5D,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC;YAC1C,IAAI,UAAU,EAAE,CAAC;gBAChB,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC;oBAC5B,MAAM,EAAE,UAAU;oBAClB,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACvE,CAAC,CAAC;gBACH,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;YACzD,CAAC;QACF,CAAC;aAAM,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YAC7D,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC;YAC3C,IAAI,UAAU,EAAE,CAAC;gBAChB,eAAe,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC/C,GAAG,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACrE,CAAC;QACF,CAAC;QAED,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC,CAAC;IAAA,CACrC,CAAC;IAEF,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC;QAC5B,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAAA,CAC7B,CAAC;IAEF,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,OAAgB,EAAE,EAAE,CAAC;QAClE,MAAM,QAAQ,GAAG,8BAA8B,CAC7C,OAAkD,EAAE,iBAAiB,CACtE,CAAC;QACF,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,IAAI,QAAQ,CAAC,SAAS,KAAK,YAAY,IAAI,QAAQ,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;YAC3E,uBAAuB,GAAG,OAAO,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,aAAa,EAAE,CAAC;YACpB,aAAa,GAAG;gBACf,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,EAAE;aACV,CAAC;QACH,CAAC;QACD,aAAa,CAAC,MAAM,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpD,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC;QACD,aAAa,CAAC,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC5C,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS;YAAE,aAAa,CAAC,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC;;YAC5E,OAAO,aAAa,CAAC,WAAW,CAAC;IAAA,CACtC,CAAC;IAEF,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,IAAY,EAAE,OAAgB,EAAU,EAAE,CAAC;QACnF,OAAO,OAAO,OAAO,YAAY,IAAI,WAAW,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;IAAA,CAC9E,CAAC;IAEF,MAAM,wBAAwB,GAAG,GAAG,EAAE,CAAC;QACtC,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,uBAAuB,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,IAAI,uBAAuB,GAAG,YAAY;YAChH,OAAO,CAAC,CAAC,CAAC;QACX,OAAO,uBAAuB,GAAG,YAAY,CAAC;IAAA,CAC9C,CAAC;IAEF,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC;QAC3B,IAAI,QAAQ,CAAC,MAAM,IAAI,aAAa;YAAE,OAAO;QAC7C,MAAM,qBAAqB,GAAG,wBAAwB,EAAE,CAAC;QAEzD,IAAI,qBAAqB,GAAG,CAAC,EAAE,CAAC;YAC/B,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,aAAa,EAAE,CAAC;YACrC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC;QACrD,CAAC;IAAA,CACD,CAAC;IAEF,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,OAAgB,EAAE,EAAE,CAAC;QACrD,IAAI,SAAS;YAAE,OAAO;QACtB,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9C,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,aAAa,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACrD,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC;gBACJ,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACR,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3B,CAAC;QACF,CAAC;IAAA,CACD,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,GAAmB,EAAE,iBAAiC,EAAE,EAAE,CAAC;QAChF,MAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;QAChF,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC;YACnD,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,YAAY,CAAC;YACrD,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;gBACP,MAAM,qBAAqB,GAAG,wBAAwB,EAAE,CAAC;gBACzD,OAAO,qBAAqB,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAA,CACrF,CAAC,EAAE,CAAC;QAEP,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACpC,IAAI,CAAC;gBACJ,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAChE,CAAC;YAAC,MAAM,CAAC;gBACR,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACvB,OAAO;YACR,CAAC;QACF,CAAC;IAAA,CACD,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC;QACtB,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;YACjC,IAAI,CAAC;gBACJ,MAAM,CAAC,GAAG,EAAE,CAAC;YACd,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACX,CAAC;QACD,UAAU,CAAC,KAAK,EAAE,CAAC;IAAA,CACnB,CAAC;IAEF,MAAM,YAAY,GAAG,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,aAAa,CAAC,QAAQ,CAAC,CAAC;QACxB,QAAQ,GAAG,IAAI,CAAC;IAAA,CAChB,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC;QACzC,IAAI,SAAS;YAAE,OAAO;QACtB,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3C,SAAS,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1C,SAAS,GAAG,IAAI,CAAC;QACjB,YAAY,EAAE,CAAC;QACf,OAAO,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,CAAC;IAAA,CAC7B,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;QACpD,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC;YACnC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC;YACpC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,UAAU,UAAU,IAAI,WAAW,EAAE,CAAC,CAAC;YAC3E,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9D,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC;gBACnC,OAAO;YACR,CAAC;YAED,IAAI,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;gBAC/C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;gBACnE,GAAG,CAAC,GAAG,EAAE,CAAC;gBACV,OAAO;YACR,CAAC;YAED,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;gBAC9C,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;oBACtC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC,CAAC;oBAChG,GAAG,CAAC,GAAG,CACN,+EAA+E;wBAC9E,8EAA8E,CAC/E,CAAC;oBACF,OAAO;gBACR,CAAC;gBACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,CAAC;oBAAE,OAAO;gBACxD,cAAc,EAAE,CAAC;gBAEjB,MAAM,IAAI,GAAG,qBAAqB,CAAC;oBAClC,YAAY;oBACZ,eAAe;oBACf,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;oBAC1B,cAAc,EAAE,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;oBACtE,kBAAkB,EAAE,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC;oBAC7E,gBAAgB,EAAE,OAAO,CAAC,cAAc,CAAC,kBAAkB,EAAE;oBAC7D,WAAW;iBACX,CAAC,CAAC;gBAEH,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;oBAClB,cAAc,EAAE,0BAA0B;oBAC1C,eAAe,EAAE,UAAU;iBAC3B,CAAC,CAAC;gBACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACd,OAAO;YACR,CAAC;YAED,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACpD,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,CAAC;oBAAE,OAAO;gBACxD,cAAc,EAAE,CAAC;gBACjB,GAAG,CAAC,KAAK,CAAC,sBAAsB,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;gBACxE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;oBAClB,cAAc,EAAE,mBAAmB;oBACnC,eAAe,EAAE,wBAAwB;oBACzC,UAAU,EAAE,YAAY;oBACxB,mBAAmB,EAAE,IAAI;iBACzB,CAAC,CAAC;gBACH,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBAC7B,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACpB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBAC9F,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC;oBACrB,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAAA,CACvB,CAAC,CAAC;gBACH,OAAO;YACR,CAAC;YAED,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACpD,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,CAAC;oBAAE,OAAO;gBACxD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC5D,OAAO;YACR,CAAC;YAED,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACpD,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,UAAU,CAAC;oBAAE,OAAO;gBACvE,cAAc,EAAE,CAAC;gBACjB,kFAAkF;gBAClF,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAClE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;oBAClB,cAAc,EAAE,0BAA0B;oBAC1C,eAAe,EAAE,UAAU;oBAC3B,yBAAyB,EAAE,UAAU;iBACrC,CAAC,CAAC;gBACH,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC/B,OAAO;YACR,CAAC;YAED,IAAI,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,uBAAuB,EAAE,CAAC;gBAClE,yCAAyC;gBACzC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;gBAC1E,IAAI,CAAC;oBACJ,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;oBACvD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;wBAClB,cAAc,EAAE,wBAAwB;wBACxC,eAAe,EAAE,0BAA0B;qBAC3C,CAAC,CAAC;oBACH,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAClB,CAAC;gBAAC,MAAM,CAAC;oBACR,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC9D,CAAC;gBACD,OAAO;YACR,CAAC;YAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACvB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;gBACtD,OAAO;YACR,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YACvC,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,CAAC;gBAAE,OAAO;YACxD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;YACjC,cAAc,EAAE,CAAC;YAEjB,IAAI,GAAG,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;gBAC1C,OAAO,CAAC,cAAc,CAAC,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAC1D,MAAM,UAAU,GAAG,MAAmC,CAAC;gBACvD,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;oBACnF,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;oBACtE,OAAO;gBACR,CAAC;gBAED,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACrE,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;oBACtD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,OAAO,CAAC,UAAU,oBAAoB,EAAE,CAAC,CAAC;oBAC5F,OAAO;gBACR,CAAC;gBACD,IACC,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;oBAChE,gBAAgB,CAAC,UAAU,CAAC,UAAU,CAAC,EACtC,CAAC;oBACF,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,OAAO,CAAC,UAAU,eAAe,EAAE,CAAC,CAAC;oBACvF,OAAO;gBACR,CAAC;gBAED,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChF,MAAM,cAAc,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC;gBACrF,IAAI,CAAC,cAAc,EAAE,CAAC;oBACrB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,UAAU,CAAC,IAAI,2BAA2B,EAAE,CAAC,CAAC;oBAClG,OAAO;gBACR,CAAC;gBACD,MAAM,YAAY,GAAG,uBAAuB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;gBACnE,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,EAAE,CAAC;oBAC1C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,UAAU,CAAC,IAAI,2BAA2B,EAAE,CAAC,CAAC;oBAClG,OAAO;gBACR,CAAC;gBAED,IAAI,mBAA4C,CAAC;gBACjD,IAAI,CAAC;oBACJ,mBAAmB,GAAG,sBAAsB,CAC3C,UAAU,CAAC,SAAS,EACpB,SAAS,UAAU,CAAC,IAAI,aAAa,CACrC,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBAChB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBACjG,OAAO;gBACR,CAAC;gBACD,MAAM,QAAQ,GAAG;oBAChB,IAAI,EAAE,UAAU,CAAC,IAAI;oBACrB,SAAS,EAAE,mBAAmB;iBAC9B,CAAC;gBACF,MAAM,QAAQ,GAAG;oBAChB,IAAI,EAAE,UAAU,CAAC,IAAI;oBACrB,YAAY,EAAE,UAAU,CAAC,IAAI;oBAC7B,WAAW,EAAE,cAAc,EAAE,WAAW,IAAI,EAAE;oBAC9C,GAAG,CAAC,cAAc,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,cAAc,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjG,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACvD,CAAC;gBACF,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;gBAC9D,MAAM,UAAU,GACf,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACxG,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE;oBACxC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;wBAClC,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,YAAY,EAAE,IAAI,CAAC,IAAI;wBACvB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;qBACnC,CAAC,CAAC;oBACH,GAAG,CAAC,UAAU,EAAE,eAAe,KAAK,KAAK;wBACxC,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;4BAC/C,MAAM,YAAY,GAAG,QAAQ,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;4BACrE,OAAO;gCACN,IAAI,EAAE,YAAY;gCAClB,YAAY;gCACZ,WAAW,EAAE,QAAQ,CAAC,WAAW,IAAI,kBAAkB,QAAQ,CAAC,GAAG,EAAE;6BACrE,CAAC;wBAAA,CACF,CAAC;wBACH,CAAC,CAAC,EAAE,CAAC;iBACN,CAAC,CAAC;gBACH,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK;oBAC7B,CAAC,CAAC,MAAM,sBAAsB,CAC5B,OAAO,CAAC,KAAK,EACb,OAAO,CAAC,UAAU,EAClB,QAAQ,EACR,QAAQ,CAAC,SAAS,EAClB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAC3B,QAAQ,EACR,gBAAgB,CAChB;oBACF,CAAC,CAAC,OAAO,CAAC,MAAM;wBACd,0BAA0B,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,EAAE,gBAAgB,CAAC;wBAC3F,CAAC,CAAC,EAAE,EAAE,EAAE,KAAc,EAAE,MAAM,EAAE,4BAAqC,EAAE;wBACvE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAa,EAAE,CAAC;gBAC1B,IAAI,QAAQ,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;oBAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC;oBAC5C,MAAM,OAAO,GAAG,MAAM;wBACrB,CAAC,CAAC,+CAA+C,UAAU,CAAC,IAAI,gBAAgB,OAAO,CAAC,UAAU,IAAI;wBACtG,CAAC,CAAC,aAAa,UAAU,CAAC,IAAI,gBAAgB,OAAO,CAAC,UAAU,0DAA0D,CAAC;oBAC5H,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;wBAClB,EAAE,EAAE,IAAI;wBACR,MAAM,EAAE;4BACP,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;4BACnD,OAAO,EAAE;gCACR,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,mBAAmB;gCACvD,MAAM,EAAE,OAAO,CAAC,UAAU;gCAC1B,IAAI,EAAE,UAAU,CAAC,IAAI;6BACrB;yBACD;qBACD,CAAC,CAAC;oBACH,OAAO;gBACR,CAAC;gBAED,IAAI,CAAC;oBACJ,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;oBAC1C,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;oBACtD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;wBAC5B,CAAC,CAAC,MAAM,mBAAmB,CACzB;4BACC,OAAO,EAAE,OAAO,CAAC,OAAO;4BACxB,MAAM,EAAE,OAAO,CAAC,MAAM;4BACtB,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;yBACpE,EACD,OAAO,CAAC,UAAU,EAClB,CAAC,IAAI,EAAE,EAAE,CACR,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CACxF;wBACF,CAAC,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;oBACvG,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC1C,CAAC;wBAAS,CAAC;oBACV,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;oBACtD,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAC3C,CAAC;gBACD,OAAO;YACR,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;gBAC1C,MAAM,QAAQ,GAAG,CAAC,CAAE,MAAiC,CAAC,QAAQ,CAAC;gBAC/D,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;gBACtE,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACvD,OAAO;YACR,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,sCAAsC,EAAE,CAAC;gBAC7D,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;gBACvE,IAAI,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;oBACjC,GAAG,CAAC,KAAK,CAAC,6CAA6C,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpE,CAAC;qBAAM,CAAC;oBACP,MAAM,eAAe,CAAC;wBACrB,IAAI,EAAE,QAAQ;wBACd,MAAM,EAAE,WAAW;wBACnB,MAAM,EAAE;4BACP,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;4BACvC,GAAG,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;4BAC1E,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;yBACpE;qBACD,CAAC,CAAC;gBACJ,CAAC;gBACD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC7C,OAAO;YACR,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;gBAC1C,MAAM,eAAe,CAAC,MAAyB,CAAC,CAAC;gBACjD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC7C,OAAO;YACR,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;gBAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;gBAC/B,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC;gBACnD,IACC,CAAC,OAAO,KAAK,SAAS;oBACrB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;oBACpG,CAAC,iBAAiB,KAAK,SAAS;wBAC/B,CAAC,CAAC,iBAAiB,IAAI,OAAO,iBAAiB,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAClG,CAAC;oBACF,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC,CAAC;oBAChF,OAAO;gBACR,CAAC;gBACD,MAAM,SAAS,GAAyB;oBACvC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAuD,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACtG,GAAG,CAAC,iBAAiB,KAAK,SAAS;wBAClC,CAAC,CAAC,EAAE,iBAAiB,EAAE,iBAA4C,EAAE;wBACrE,CAAC,CAAC,EAAE,CAAC;iBACN,CAAC;gBACF,MAAM,MAAM,GAAG,0BAA0B,CAAC,SAAS,CAAC,CAAC;gBACrD,IAAI,MAAM,EAAE,CAAC;oBACZ,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBACtC,OAAO,eAAe,CAAC,QAAQ,CAAC,MAAM,GAAG,mBAAmB,EAAE,CAAC;wBAC9D,eAAe,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;oBAClC,CAAC;gBACF,CAAC;gBACD,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;gBACzF,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,SAAS,CAAC,CAAC;gBAC3C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC7C,OAAO;YACR,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,qBAAqB,EAAE,CAAC;gBAC5C,MAAM,UAAU,GAAG,MAA0B,CAAC;gBAC9C,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,OAAO,UAAU,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;oBAC5D,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;oBACrE,OAAO;gBACR,CAAC;gBACD,IAAI,MAAM,GAAqB,EAAE,CAAC;gBAClC,IAAI,CAAC;oBACJ,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBAC5C,IACC,CAAC,WAAW,CAAC,QAAQ,KAAK,OAAO,IAAI,WAAW,CAAC,QAAQ,KAAK,QAAQ,CAAC;wBACvE,WAAW,CAAC,QAAQ;wBACpB,WAAW,CAAC,QAAQ,EACnB,CAAC;wBACF,MAAM,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;oBAC5B,CAAC;gBACF,CAAC;gBAAC,MAAM,CAAC;oBACR,MAAM,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gBAC5B,CAAC;gBACD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBACzC,OAAO;YACR,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,yBAAyB,EAAE,CAAC;gBAChD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC5D,OAAO;YACR,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,gCAAgC,EAAE,CAAC;gBACvD,MAAM,aAAa,GAAG,MAA8B,CAAC;gBACrD,MAAM,SAAS,GAAG,aAAa,EAAE,IAAI,CAAC;gBACtC,MAAM,SAAS,GAAG,WAAW,CAAC,qBAAqB,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAClE,IAAI,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;oBAChD,kBAAkB,GAAG,SAAS,CAAC;gBAChC,CAAC;gBACD,WAAW,CAAC,WAAW,GAAG,kBAAkB,CAAC;gBAC7C,SAAS,CAAC,cAAc,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC/D,MAAM,MAAM,GAAwB,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC;gBACjE,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;gBACzC,OAAO;YACR,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,qBAAqB,EAAE,CAAC;gBAC5C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC7C,OAAO;YACR,CAAC;YAED,IAAI,GAAG,CAAC,QAAQ,KAAK,oBAAoB,EAAE,CAAC;gBAC3C,MAAM,MAAM,GACX,OAAQ,MAA8B,CAAC,MAAM,KAAK,QAAQ;oBACzD,CAAC,CAAE,MAA8B,CAAC,MAAO;oBACzC,CAAC,CAAC,MAAM,CAAC;gBACX,aAAa,CAAC,MAAM,CAAC,CAAC;gBACtB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC7C,UAAU,CAAC,GAAG,EAAE,CAAC;oBAChB,IAAI,CAAC;wBACJ,MAAM,CAAC,KAAK,EAAE,CAAC;oBAChB,CAAC;oBAAC,MAAM,CAAC,CAAA,CAAC;oBACV,QAAQ,EAAE,CAAC;gBAAA,CACX,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;gBACf,OAAO;YACR,CAAC;YAED,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,KAAK,YAAY,gCAAgC,EAAE,CAAC;gBACvD,MAAM,QAAQ,GAAG,WAAW,OAAO,CAAC,UAAU,6EAA6E,OAAO,CAAC,UAAU,2CAA2C,OAAO,CAAC,UAAU,mCAAmC,CAAC;gBAC9O,MAAM,OAAO,GACZ,KAAK,CAAC,WAAW;oBACjB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,yBAAyB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBACvG,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBAClD,OAAO;YACR,CAAC;YACD,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzF,MAAM,MAAM,GAAG,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC7E,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACpB,GAAG,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAChF,CAAC;YACD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;IAAA,CACD,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAClC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAChC,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,EAC5C,CAAC,KAAK,EAAE,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtE,SAAS,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QAAA,CACxC,CACD,CAAC;IACH,CAAC;IAED,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,SAAS;YAAE,OAAO;QACtB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,IAAI,kBAAkB;YAAE,OAAO;QAC/D,aAAa,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,CAAC;YACJ,MAAM,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,QAAQ,EAAE,CAAC;IAAA,CACX,EAAE,oBAAoB,CAAC,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,CAAC;IAEjB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;QACvC,MAAM,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QAAA,CACpE,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,KAA4B,EAAE,EAAE,CAAC;YACjD,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACrC,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,cAAc,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3E,cAAc,IAAI,CAAC,CAAC;gBACpB,MAAM,EAAE,CAAC;gBACT,OAAO;YACR,CAAC;YACD,GAAG,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;YACxC,MAAM,CACL,IAAI,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE;gBAC9B,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,KAAK,EAAE,KAAK;aACZ,CAAC,CACF,CAAC;QAAA,CACF,CAAC;QAEF,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC7C,MAAM,GAAG,GAAG,IAAI,WAAW,CAAC,iBAAiB,CAAC,CAAC;gBAC/C,GAAG,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;gBACzC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACZ,OAAO;YACR,CAAC;YAED,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACpD,0BAA0B,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAEzC,MAAM,MAAM,GAAmB;gBAC9B,GAAG,EAAE,oBAAoB,OAAO,CAAC,IAAI,aAAa,YAAY,EAAE;gBAChE,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,YAAY;gBACZ,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,KAAK,EAAE,CAAC,MAAe,EAAE,EAAE,CAAC;oBAC3B,aAAa,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC;oBAClC,IAAI,CAAC;wBACJ,MAAM,CAAC,KAAK,EAAE,CAAC;oBAChB,CAAC;oBAAC,MAAM,CAAC,CAAA,CAAC;oBACV,QAAQ,EAAE,CAAC;gBAAA,CACX;gBACD,aAAa,EAAE,CAAC,IAA6B,EAAE,EAAE,CAAC;oBACjD,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAAA,CAC7C;gBACD,cAAc,EAAE,CAAC,MAAsB,EAAE,EAAE,CAAC;oBAC3C,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;gBAAA,CACjC;gBACD,eAAe,EAAE,CAAC,MAAsB,EAAE,EAAE,CAAC;oBAC5C,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;gBAAA,CAClC;gBACD,iBAAiB,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC;oBACtC,SAAS,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBAAA,CACxC;gBACD,eAAe,EAAE,CAAC,OAAsB,EAAE,EAAE,CAAC;oBAC5C,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;oBACpC,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;gBAAA,CACnC;gBACD,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,eAAe,EAAE,CAAC;gBAClD,gBAAgB,EAAE,GAAG,EAAE,CACtB,aAAa,CAAC,CAAC,CAAC,EAAE,GAAG,aAAa,EAAE,MAAM,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;aACpF,CAAC;YAEF,OAAO,CAAC,MAAM,CAAC,CAAC;QAAA,CAChB,CAAC;QAEF,MAAM,EAAE,CAAC;IAAA,CACT,CAAC,CAAC;AAAA,CACH;AAED,KAAK,UAAU,SAAS,CACvB,GAAoB,EACpB,GAAmB,EAC2C;IAC9D,IAAI,CAAC;QACJ,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;YACjE,OAAO,IAAI,CAAC;QACb,CAAC;QACD,OAAO,IAAmD,CAAC;IAC5D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;QAClG,OAAO,IAAI,CAAC;IACb,CAAC;AAAA,CACD;AAED,SAAS,QAAQ,CAAC,GAAoB,EAAoB;IACzD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;QACvC,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC;YACjC,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YACrB,IAAI,IAAI,GAAG,aAAa,EAAE,CAAC;gBAC1B,GAAG,CAAC,OAAO,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;gBAC5C,OAAO;YACR,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAA,CACnB,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC;YACnB,IAAI,CAAC;gBACJ,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC9D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC;QAAA,CACD,CAAC,CAAC;QAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAAA,CACxB,CAAC,CAAC;AAAA,CACH;AAED,SAAS,qBAAqB,CAAC,IAAwB,EAAY;IAClE,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,wBAAwB,GAAG,0BAA0B,GAAG,CAAC,CAAC;IACxE,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC;QAClD,MAAM,SAAS,GACd,0BAA0B,GAAG,CAAC,CAAC,sBAAsB,GAAG,0BAA0B,GAAG,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC;QACvG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IACD,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnB,OAAO,UAAU,CAAC;AAAA,CAClB;AAED,SAAS,0BAA0B,CAAC,IAAY,EAAQ;IACvD,IAAI,IAAI,GAAG,0BAA0B,IAAI,IAAI,GAAG,wBAAwB;QAAE,OAAO;IACjF,sBAAsB,GAAG,IAAI,IAAI,wBAAwB,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;AAAA,CAClG;AAED,SAAS,aAAa,CAAC,QAAgB,EAAW;IACjD,OAAO,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,OAAO,CAAC;AAAA,CACpF;AAED,SAAS,kBAAkB,CAAC,GAAQ,EAAE,QAAgB,EAAE,GAAmB,EAAE,SAAS,GAAG,SAAS,EAAW;IAC5G,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,SAAS,iBAAiB,CACzB,IAAiD,EACjD,QAAgB,EAChB,GAAmB,EACT;IACV,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC7B,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAC5D,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED,SAAS,QAAQ,CAAI,GAAmB,EAAE,MAAc,EAAE,OAAyB,EAAQ;IAC1F,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE;QACrB,cAAc,EAAE,iCAAiC;QACjD,eAAe,EAAE,UAAU;KAC3B,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AAAA,CACjC;AAED,SAAS,QAAQ,CAAC,GAAmB,EAAE,MAAc,EAAE,IAAY,EAAQ;IAC1E,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE;QACrB,cAAc,EAAE,2BAA2B;QAC3C,eAAe,EAAE,UAAU;KAC3B,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAAA,CACd","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport http, { type IncomingMessage, type ServerResponse } from \"node:http\";\nimport path from \"node:path\";\nimport type { CallToolRequest, CallToolResult } from \"@modelcontextprotocol/client\";\nimport { ContentBlockSchema } from \"@modelcontextprotocol/core\";\nimport type { ConsentManager } from \"./consent-manager.ts\";\nimport { ServerError, wrapError } from \"./errors.ts\";\nimport { buildCspMetaContent, buildHostHtmlTemplate } from \"./host-html-template.ts\";\nimport { logger } from \"./logger.ts\";\nimport { resourceNameToToolName } from \"./resource-tools.ts\";\nimport type { McpServerManager } from \"./server-manager.ts\";\nimport { SessionRecoveryAuthRequiredError, type SessionRecoveryDeps, withSessionRecovery } from \"./session-recovery.ts\";\nimport type { McpExtensionState } from \"./state.ts\";\nimport { ensureToolCallApproved, isToolCallApprovalRequired } from \"./tool-approval.ts\";\nimport {\n\tcreateUiModelContextUpdate,\n\textractUiPromptText,\n\tgetVisualizationStreamEnvelope,\n\tisServerDisabled,\n\ttype McpConfig,\n\ttype UiDisplayMode,\n\ttype UiDisplayModeRequest,\n\ttype UiDisplayModeResult,\n\ttype UiHostContext,\n\ttype UiMessageParams,\n\ttype UiModelContextParams,\n\ttype UiOpenLinkResult,\n\ttype UiProxyRequestBody,\n\ttype UiProxyResult,\n\ttype UiResourceContent,\n\ttype UiSessionMessages,\n\ttype UiStreamSummary,\n} from \"./types.ts\";\nimport { buildAllowAttribute } from \"./ui-app-bridge-helpers.ts\";\nimport { extractUiToolVisibility, isUiToolCallableByApp, isUiToolVisibleToModel } from \"./ui-tool-visibility.ts\";\nimport { formatAuthRequiredMessage, normalizeToolArguments } from \"./utils.ts\";\n\nconst MAX_BODY_SIZE = 2 * 1024 * 1024;\nconst ABANDONED_GRACE_MS = 60_000;\nconst WATCHDOG_INTERVAL_MS = 5_000;\nconst MAX_EVENT_LOG = 128;\nconst MAX_CONTEXT_UPDATES = 20;\nconst MOSHI_DISCOVERY_PORT_START = 8377;\nconst MOSHI_DISCOVERY_PORT_END = 8396;\nlet nextMoshiDiscoveryPort = MOSHI_DISCOVERY_PORT_START;\n\nexport interface UiServerOptions {\n\tserverName: string;\n\ttoolName: string;\n\ttoolArgs: Record<string, unknown>;\n\tresource: UiResourceContent;\n\tmanager: McpServerManager;\n\t/**\n\t * Live extension config, used to re-read the server definition when\n\t * recovering a terminated Streamable HTTP session (see\n\t * session-recovery.ts). Optional so existing embedders/tests that don't\n\t * need session recovery aren't forced to supply it; without it, proxied\n\t * tool calls run without recovery (unchanged pre-existing behavior).\n\t */\n\tconfig?: McpConfig;\n\t/** Live state enables TUI approval prompts for iframe-originated tool calls. */\n\tstate?: McpExtensionState;\n\tonNeedsAuth?: SessionRecoveryDeps[\"onNeedsAuth\"];\n\tconsentManager: ConsentManager;\n\thostContext?: UiHostContext;\n\tinitialResultPromise?: Promise<CallToolResult>;\n\tsessionToken?: string;\n\tport?: number;\n\tonMessage?: (params: UiMessageParams) => Promise<void> | void;\n\tonContextUpdate?: (params: UiModelContextParams) => Promise<void> | void;\n\tonComplete?: (reason: string) => void;\n}\n\nexport interface UiServerHandle {\n\turl: string;\n\tport: number;\n\tsessionToken: string;\n\tserverName: string;\n\ttoolName: string;\n\tviewer?: \"browser\" | \"glimpse\" | \"suppressed\";\n\twindowOpen?: boolean;\n\tclose: (reason?: string) => void;\n\tsendToolInput: (args: Record<string, unknown>) => void;\n\tsendToolResult: (result: CallToolResult) => void;\n\tsendResultPatch: (result: CallToolResult) => void;\n\tsendToolCancelled: (reason: string) => void;\n\tsendHostContext: (context: UiHostContext) => void;\n\t/** Get accumulated messages from this session */\n\tgetSessionMessages: () => UiSessionMessages;\n\tgetStreamSummary: () => UiStreamSummary | undefined;\n}\n\nexport async function startUiServer(options: UiServerOptions): Promise<UiServerHandle> {\n\tconst sessionToken = options.sessionToken ?? randomUUID();\n\tconst uiResourceToken = randomUUID();\n\tconst log = logger.child({\n\t\tcomponent: \"UiServer\",\n\t\tserver: options.serverName,\n\t\ttool: options.toolName,\n\t\tsession: sessionToken.slice(0, 8),\n\t});\n\n\tlog.debug(\"Starting UI server\");\n\n\tconst sseClients = new Set<ServerResponse>();\n\tlet completed = false;\n\tlet lastHeartbeatAt = Date.now();\n\tlet watchdog: NodeJS.Timeout | null = null;\n\tlet currentDisplayMode: UiDisplayMode = options.hostContext?.displayMode ?? \"inline\";\n\tlet nextEventId = 1;\n\tconst eventLog: Array<{ id: number; name: string; payload: unknown }> = [];\n\tlet latestCheckpointEventId: number | undefined;\n\tlet streamSummary: UiStreamSummary | undefined;\n\n\t// Track messages from UI for retrieval\n\tconst sessionMessages: UiSessionMessages = {\n\t\tprompts: [],\n\t\tnotifications: [],\n\t\tintents: [],\n\t\tcontexts: [],\n\t};\n\n\tconst hostContext: UiHostContext = {\n\t\tdisplayMode: currentDisplayMode,\n\t\tavailableDisplayModes: [\"inline\", \"fullscreen\", \"pip\"],\n\t\tplatform: \"desktop\",\n\t\t...options.hostContext,\n\t\t// Only include toolInfo if caller provides full tool definition with inputSchema\n\t\t// The App validates toolInfo.tool.inputSchema as required object\n\t};\n\n\tconst initialStreamContext = hostContext[\"nexus-mcp/stream\"];\n\tif (initialStreamContext && typeof initialStreamContext === \"object\") {\n\t\tconst streamId = (initialStreamContext as { streamId?: unknown }).streamId;\n\t\tconst mode = (initialStreamContext as { mode?: unknown }).mode;\n\t\tif (typeof streamId === \"string\" && (mode === \"eager\" || mode === \"stream-first\")) {\n\t\t\tstreamSummary = {\n\t\t\t\tstreamId,\n\t\t\t\tmode,\n\t\t\t\tframes: 0,\n\t\t\t\tphases: [],\n\t\t\t};\n\t\t}\n\t}\n\n\tconst isAppOnlyTool = (toolName: string): boolean => {\n\t\tconst toolDefinition = options.manager\n\t\t\t.getConnection(options.serverName)\n\t\t\t?.tools?.find((tool) => tool.name === toolName);\n\t\tif (!toolDefinition) return false;\n\t\tconst visibility = extractUiToolVisibility(toolDefinition._meta);\n\t\treturn isUiToolCallableByApp(visibility) && !isUiToolVisibleToModel(visibility);\n\t};\n\n\tconst recordUiMessage = async (msgParams: UiMessageParams): Promise<void> => {\n\t\tconst promptText = extractUiPromptText(msgParams);\n\n\t\t// Track messages by type (order: prompt → intent → notify)\n\t\t// Must match the order in index.ts onMessage handler\n\t\tif (promptText) {\n\t\t\tsessionMessages.prompts.push(promptText);\n\t\t\tlog.debug(\"UI prompt received\", { prompt: promptText.slice(0, 100) });\n\t\t} else if (msgParams.type === \"intent\" || msgParams.intent) {\n\t\t\tconst intentName = msgParams.intent ?? \"\";\n\t\t\tif (intentName) {\n\t\t\t\tsessionMessages.intents.push({\n\t\t\t\t\tintent: intentName,\n\t\t\t\t\t...(msgParams.params !== undefined ? { params: msgParams.params } : {}),\n\t\t\t\t});\n\t\t\t\tlog.debug(\"UI intent received\", { intent: intentName });\n\t\t\t}\n\t\t} else if (msgParams.type === \"notify\" || msgParams.message) {\n\t\t\tconst notifyText = msgParams.message ?? \"\";\n\t\t\tif (notifyText) {\n\t\t\t\tsessionMessages.notifications.push(notifyText);\n\t\t\t\tlog.debug(\"UI notification\", { message: notifyText.slice(0, 100) });\n\t\t\t}\n\t\t}\n\n\t\tawait options.onMessage?.(msgParams);\n\t};\n\n\tconst touchHeartbeat = () => {\n\t\tlastHeartbeatAt = Date.now();\n\t};\n\n\tconst updateStreamSummary = (eventId: number, payload: unknown) => {\n\t\tconst envelope = getVisualizationStreamEnvelope(\n\t\t\t(payload as { structuredContent?: unknown } | null)?.structuredContent,\n\t\t);\n\t\tif (!envelope) return;\n\t\tif (envelope.frameType === \"checkpoint\" || envelope.frameType === \"final\") {\n\t\t\tlatestCheckpointEventId = eventId;\n\t\t}\n\t\tif (!streamSummary) {\n\t\t\tstreamSummary = {\n\t\t\t\tstreamId: envelope.streamId,\n\t\t\t\tmode: \"eager\",\n\t\t\t\tframes: 0,\n\t\t\t\tphases: [],\n\t\t\t};\n\t\t}\n\t\tstreamSummary.frames += 1;\n\t\tif (!streamSummary.phases.includes(envelope.phase)) {\n\t\t\tstreamSummary.phases.push(envelope.phase);\n\t\t}\n\t\tstreamSummary.finalStatus = envelope.status;\n\t\tif (envelope.message !== undefined) streamSummary.lastMessage = envelope.message;\n\t\telse delete streamSummary.lastMessage;\n\t};\n\n\tconst serializeEvent = (eventId: number, name: string, payload: unknown): string => {\n\t\treturn `id: ${eventId}\\nevent: ${name}\\ndata: ${JSON.stringify(payload)}\\n\\n`;\n\t};\n\n\tconst getLatestCheckpointIndex = () => {\n\t\tconst firstEventId = eventLog[0]?.id;\n\t\tif (latestCheckpointEventId === undefined || firstEventId === undefined || latestCheckpointEventId < firstEventId)\n\t\t\treturn -1;\n\t\treturn latestCheckpointEventId - firstEventId;\n\t};\n\n\tconst pruneEventLog = () => {\n\t\tif (eventLog.length <= MAX_EVENT_LOG) return;\n\t\tconst latestCheckpointIndex = getLatestCheckpointIndex();\n\n\t\tif (latestCheckpointIndex > 0) {\n\t\t\teventLog.splice(0, latestCheckpointIndex);\n\t\t}\n\n\t\tif (eventLog.length > MAX_EVENT_LOG) {\n\t\t\teventLog.splice(0, eventLog.length - MAX_EVENT_LOG);\n\t\t}\n\t};\n\n\tconst pushEvent = (name: string, payload: unknown) => {\n\t\tif (completed) return;\n\t\tconst eventId = nextEventId++;\n\t\teventLog.push({ id: eventId, name, payload });\n\t\tupdateStreamSummary(eventId, payload);\n\t\tpruneEventLog();\n\t\tconst chunk = serializeEvent(eventId, name, payload);\n\t\tfor (const client of sseClients) {\n\t\t\ttry {\n\t\t\t\tclient.write(chunk);\n\t\t\t} catch {\n\t\t\t\tsseClients.delete(client);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst replayEvents = (res: ServerResponse, lastEventIdHeader?: string | null) => {\n\t\tconst parsedLastId = lastEventIdHeader ? Number(lastEventIdHeader) : Number.NaN;\n\t\tconst eventsToReplay = Number.isFinite(parsedLastId)\n\t\t\t? eventLog.filter((entry) => entry.id > parsedLastId)\n\t\t\t: (() => {\n\t\t\t\t\tconst latestCheckpointIndex = getLatestCheckpointIndex();\n\t\t\t\t\treturn latestCheckpointIndex >= 0 ? eventLog.slice(latestCheckpointIndex) : eventLog;\n\t\t\t\t})();\n\n\t\tfor (const entry of eventsToReplay) {\n\t\t\ttry {\n\t\t\t\tres.write(serializeEvent(entry.id, entry.name, entry.payload));\n\t\t\t} catch {\n\t\t\t\tsseClients.delete(res);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst closeSse = () => {\n\t\tfor (const client of sseClients) {\n\t\t\ttry {\n\t\t\t\tclient.end();\n\t\t\t} catch {}\n\t\t}\n\t\tsseClients.clear();\n\t};\n\n\tconst stopWatchdog = () => {\n\t\tif (!watchdog) return;\n\t\tclearInterval(watchdog);\n\t\twatchdog = null;\n\t};\n\n\tconst markCompleted = (reason: string) => {\n\t\tif (completed) return;\n\t\tlog.debug(\"Session completed\", { reason });\n\t\tpushEvent(\"session-complete\", { reason });\n\t\tcompleted = true;\n\t\tstopWatchdog();\n\t\toptions.onComplete?.(reason);\n\t};\n\n\tconst server = http.createServer(async (req, res) => {\n\t\ttry {\n\t\t\tconst method = req.method || \"GET\";\n\t\t\tconst hostHeader = req.headers.host;\n\t\t\tconst url = new URL(req.url || \"/\", `http://${hostHeader || \"127.0.0.1\"}`);\n\t\t\tif (hostHeader !== undefined && !isAllowedHost(url.hostname)) {\n\t\t\t\tsendText(res, 403, \"Invalid host\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (method === \"HEAD\" && url.pathname === \"/\") {\n\t\t\t\tres.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\tres.end();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (method === \"GET\" && url.pathname === \"/\") {\n\t\t\t\tif (!url.searchParams.has(\"session\")) {\n\t\t\t\t\tres.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\", \"Cache-Control\": \"no-store\" });\n\t\t\t\t\tres.end(\n\t\t\t\t\t\t'<!doctype html><html><head><meta charset=\"utf-8\"><title>MCP UI</title></head>' +\n\t\t\t\t\t\t\t\"<body><p>Open the authenticated MCP UI URL shown by Nexus.</p></body></html>\",\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!validateTokenQuery(url, sessionToken, res)) return;\n\t\t\t\ttouchHeartbeat();\n\n\t\t\t\tconst html = buildHostHtmlTemplate({\n\t\t\t\t\tsessionToken,\n\t\t\t\t\tuiResourceToken,\n\t\t\t\t\tserverName: options.serverName,\n\t\t\t\t\ttoolName: options.toolName,\n\t\t\t\t\ttoolArgs: options.toolArgs,\n\t\t\t\t\tresource: options.resource,\n\t\t\t\t\tallowAttribute: buildAllowAttribute(options.resource.meta.permissions),\n\t\t\t\t\trequireToolConsent: options.consentManager.requiresPrompt(options.serverName),\n\t\t\t\t\tcacheToolConsent: options.consentManager.shouldCacheConsent(),\n\t\t\t\t\thostContext,\n\t\t\t\t});\n\n\t\t\t\tres.writeHead(200, {\n\t\t\t\t\t\"Content-Type\": \"text/html; charset=utf-8\",\n\t\t\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t\t});\n\t\t\t\tres.end(html);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (method === \"GET\" && url.pathname === \"/events\") {\n\t\t\t\tif (!validateTokenQuery(url, sessionToken, res)) return;\n\t\t\t\ttouchHeartbeat();\n\t\t\t\tlog.debug(\"SSE client connected\", { clientCount: sseClients.size + 1 });\n\t\t\t\tres.writeHead(200, {\n\t\t\t\t\t\"Content-Type\": \"text/event-stream\",\n\t\t\t\t\t\"Cache-Control\": \"no-cache, no-transform\",\n\t\t\t\t\tConnection: \"keep-alive\",\n\t\t\t\t\t\"X-Accel-Buffering\": \"no\",\n\t\t\t\t});\n\t\t\t\tres.write(\": connected\\n\\n\");\n\t\t\t\tsseClients.add(res);\n\t\t\t\treplayEvents(res, req.headers[\"last-event-id\"] ? String(req.headers[\"last-event-id\"]) : null);\n\t\t\t\treq.on(\"close\", () => {\n\t\t\t\t\tsseClients.delete(res);\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (method === \"GET\" && url.pathname === \"/health\") {\n\t\t\t\tif (!validateTokenQuery(url, sessionToken, res)) return;\n\t\t\t\tsendJson(res, 200, { ok: true, result: { healthy: true } });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (method === \"GET\" && url.pathname === \"/ui-app\") {\n\t\t\t\tif (!validateTokenQuery(url, uiResourceToken, res, \"resource\")) return;\n\t\t\t\ttouchHeartbeat();\n\t\t\t\t// Enforce host metadata independently of where app HTML places its document head.\n\t\t\t\tconst cspContent = buildCspMetaContent(options.resource.meta.csp);\n\t\t\t\tres.writeHead(200, {\n\t\t\t\t\t\"Content-Type\": \"text/html; charset=utf-8\",\n\t\t\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t\t\t\"Content-Security-Policy\": cspContent,\n\t\t\t\t});\n\t\t\t\tres.end(options.resource.html);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (method === \"GET\" && url.pathname === \"/app-bridge.bundle.js\") {\n\t\t\t\t// Serve the pre-bundled AppBridge module\n\t\t\t\tconst bundlePath = path.join(import.meta.dirname, \"app-bridge.bundle.js\");\n\t\t\t\ttry {\n\t\t\t\t\tconst content = await fs.readFile(bundlePath, \"utf-8\");\n\t\t\t\t\tres.writeHead(200, {\n\t\t\t\t\t\t\"Content-Type\": \"application/javascript\",\n\t\t\t\t\t\t\"Cache-Control\": \"public, max-age=31536000\",\n\t\t\t\t\t});\n\t\t\t\t\tres.end(content);\n\t\t\t\t} catch {\n\t\t\t\t\tsendJson(res, 500, { ok: false, error: \"Bundle not found\" });\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (method !== \"POST\") {\n\t\t\t\tsendJson(res, 404, { ok: false, error: \"Not found\" });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst body = await parseBody(req, res);\n\t\t\tif (!body) return;\n\t\t\tif (!validateTokenBody(body, sessionToken, res)) return;\n\t\t\tconst params = body.params ?? {};\n\t\t\ttouchHeartbeat();\n\n\t\t\tif (url.pathname === \"/proxy/tools/call\") {\n\t\t\t\toptions.consentManager.ensureApproved(options.serverName);\n\t\t\t\tconst callParams = params as CallToolRequest[\"params\"];\n\t\t\t\tif (!callParams || typeof callParams.name !== \"string\" || !callParams.name.trim()) {\n\t\t\t\t\tsendJson(res, 400, { ok: false, error: \"Invalid tools/call params\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst connection = options.manager.getConnection(options.serverName);\n\t\t\t\tif (!connection || connection.status !== \"connected\") {\n\t\t\t\t\tsendJson(res, 503, { ok: false, error: `Server \"${options.serverName}\" is not connected` });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tisServerDisabled(options.config?.mcpServers[options.serverName]) ||\n\t\t\t\t\tisServerDisabled(connection.definition)\n\t\t\t\t) {\n\t\t\t\t\tsendJson(res, 503, { ok: false, error: `Server \"${options.serverName}\" is disabled` });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst toolDefinitions = Array.isArray(connection.tools) ? connection.tools : [];\n\t\t\t\tconst toolDefinition = toolDefinitions.find((tool) => tool.name === callParams.name);\n\t\t\t\tif (!toolDefinition) {\n\t\t\t\t\tsendJson(res, 403, { ok: false, error: `MCP tool \"${callParams.name}\" is not callable by apps` });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst uiVisibility = extractUiToolVisibility(toolDefinition._meta);\n\t\t\t\tif (!isUiToolCallableByApp(uiVisibility)) {\n\t\t\t\t\tsendJson(res, 403, { ok: false, error: `MCP tool \"${callParams.name}\" is not callable by apps` });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet normalizedArguments: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tnormalizedArguments = normalizeToolArguments(\n\t\t\t\t\t\tcallParams.arguments,\n\t\t\t\t\t\t`tool \"${callParams.name}\" arguments`,\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tsendJson(res, 400, { ok: false, error: error instanceof Error ? error.message : String(error) });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst callArgs = {\n\t\t\t\t\tname: callParams.name,\n\t\t\t\t\targuments: normalizedArguments,\n\t\t\t\t};\n\t\t\t\tconst toolMeta = {\n\t\t\t\t\tname: callParams.name,\n\t\t\t\t\toriginalName: callParams.name,\n\t\t\t\t\tdescription: toolDefinition?.description ?? \"\",\n\t\t\t\t\t...(toolDefinition?.inputSchema !== undefined ? { inputSchema: toolDefinition.inputSchema } : {}),\n\t\t\t\t\t...(uiVisibility !== undefined ? { uiVisibility } : {}),\n\t\t\t\t};\n\t\t\t\tconst approvalMetadata = new Map(options.state?.toolMetadata);\n\t\t\t\tconst definition =\n\t\t\t\t\toptions.config?.mcpServers[options.serverName] ?? options.state?.config.mcpServers[options.serverName];\n\t\t\t\tapprovalMetadata.set(options.serverName, [\n\t\t\t\t\t...connection.tools.map((tool) => ({\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\toriginalName: tool.name,\n\t\t\t\t\t\tdescription: tool.description ?? \"\",\n\t\t\t\t\t})),\n\t\t\t\t\t...(definition?.exposeResources !== false\n\t\t\t\t\t\t? (connection.resources ?? []).map((resource) => {\n\t\t\t\t\t\t\t\tconst originalName = `read_${resourceNameToToolName(resource.name)}`;\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tname: originalName,\n\t\t\t\t\t\t\t\t\toriginalName,\n\t\t\t\t\t\t\t\t\tdescription: resource.description ?? `Read resource: ${resource.uri}`,\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: []),\n\t\t\t\t]);\n\t\t\t\tconst approval = options.state\n\t\t\t\t\t? await ensureToolCallApproved(\n\t\t\t\t\t\t\toptions.state,\n\t\t\t\t\t\t\toptions.serverName,\n\t\t\t\t\t\t\ttoolMeta,\n\t\t\t\t\t\t\tcallArgs.arguments,\n\t\t\t\t\t\t\toptions.state.owner?.signal,\n\t\t\t\t\t\t\t\"iframe\",\n\t\t\t\t\t\t\tapprovalMetadata,\n\t\t\t\t\t\t)\n\t\t\t\t\t: options.config &&\n\t\t\t\t\t\t\tisToolCallApprovalRequired(options.config, options.serverName, toolMeta, approvalMetadata)\n\t\t\t\t\t\t? { ok: false as const, reason: \"approval_required_headless\" as const }\n\t\t\t\t\t\t: { ok: true as const };\n\t\t\t\tif (approval.ok === false) {\n\t\t\t\t\tconst denied = approval.reason === \"denied\";\n\t\t\t\t\tconst message = denied\n\t\t\t\t\t\t? `The user declined approval to run MCP tool \"${callParams.name}\" on server \"${options.serverName}\".`\n\t\t\t\t\t\t: `MCP tool \"${callParams.name}\" on server \"${options.serverName}\" is approval-gated and requires an interactive session.`;\n\t\t\t\t\tsendJson(res, 200, {\n\t\t\t\t\t\tok: true,\n\t\t\t\t\t\tresult: {\n\t\t\t\t\t\t\tcontent: [{ type: \"text\" as const, text: message }],\n\t\t\t\t\t\t\tdetails: {\n\t\t\t\t\t\t\t\terror: denied ? \"approval_denied\" : \"approval_required\",\n\t\t\t\t\t\t\t\tserver: options.serverName,\n\t\t\t\t\t\t\t\ttool: callParams.name,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\toptions.manager.touch(options.serverName);\n\t\t\t\t\toptions.manager.incrementInFlight(options.serverName);\n\t\t\t\t\tconst result = options.config\n\t\t\t\t\t\t? await withSessionRecovery(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tmanager: options.manager,\n\t\t\t\t\t\t\t\t\tconfig: options.config,\n\t\t\t\t\t\t\t\t\t...(options.onNeedsAuth ? { onNeedsAuth: options.onNeedsAuth } : {}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\toptions.serverName,\n\t\t\t\t\t\t\t\t(conn) =>\n\t\t\t\t\t\t\t\t\tconn.client.callTool(callArgs, options.manager.getRequestOptions?.(options.serverName)),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: await connection.client.callTool(callArgs, options.manager.getRequestOptions?.(options.serverName));\n\t\t\t\t\tsendJson(res, 200, { ok: true, result });\n\t\t\t\t} finally {\n\t\t\t\t\toptions.manager.decrementInFlight(options.serverName);\n\t\t\t\t\toptions.manager.touch(options.serverName);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.pathname === \"/proxy/ui/consent\") {\n\t\t\t\tconst approved = !!(params as { approved?: boolean }).approved;\n\t\t\t\toptions.consentManager.registerDecision(options.serverName, approved);\n\t\t\t\tsendJson(res, 200, { ok: true, result: { approved } });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.pathname === \"/proxy/ui/generated-tool-call-intent\") {\n\t\t\t\tconst tool = typeof params.tool === \"string\" ? params.tool : undefined;\n\t\t\t\tif (tool && isAppOnlyTool(tool)) {\n\t\t\t\t\tlog.debug(\"Ignored generated app-only tool call intent\", { tool });\n\t\t\t\t} else {\n\t\t\t\t\tawait recordUiMessage({\n\t\t\t\t\t\ttype: \"intent\",\n\t\t\t\t\t\tintent: \"call_tool\",\n\t\t\t\t\t\tparams: {\n\t\t\t\t\t\t\t...(tool !== undefined ? { tool } : {}),\n\t\t\t\t\t\t\t...(params.arguments !== undefined ? { arguments: params.arguments } : {}),\n\t\t\t\t\t\t\t...(params.isError !== undefined ? { isError: params.isError } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tsendJson(res, 200, { ok: true, result: {} });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.pathname === \"/proxy/ui/message\") {\n\t\t\t\tawait recordUiMessage(params as UiMessageParams);\n\t\t\t\tsendJson(res, 200, { ok: true, result: {} });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.pathname === \"/proxy/ui/context\") {\n\t\t\t\tconst content = params.content;\n\t\t\t\tconst structuredContent = params.structuredContent;\n\t\t\t\tif (\n\t\t\t\t\t(content !== undefined &&\n\t\t\t\t\t\t(!Array.isArray(content) || content.some((block) => !ContentBlockSchema.safeParse(block).success))) ||\n\t\t\t\t\t(structuredContent !== undefined &&\n\t\t\t\t\t\t(!structuredContent || typeof structuredContent !== \"object\" || Array.isArray(structuredContent)))\n\t\t\t\t) {\n\t\t\t\t\tsendJson(res, 400, { ok: false, error: \"Invalid update-model-context params\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst ctxParams: UiModelContextParams = {\n\t\t\t\t\t...(content !== undefined ? { content: content as NonNullable<UiModelContextParams[\"content\"]> } : {}),\n\t\t\t\t\t...(structuredContent !== undefined\n\t\t\t\t\t\t? { structuredContent: structuredContent as Record<string, unknown> }\n\t\t\t\t\t\t: {}),\n\t\t\t\t};\n\t\t\t\tconst update = createUiModelContextUpdate(ctxParams);\n\t\t\t\tif (update) {\n\t\t\t\t\tsessionMessages.contexts.push(update);\n\t\t\t\t\twhile (sessionMessages.contexts.length > MAX_CONTEXT_UPDATES) {\n\t\t\t\t\t\tsessionMessages.contexts.shift();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlog.debug(\"UI context update\", { hasContent: !!ctxParams.content, hasUpdate: !!update });\n\t\t\t\tawait options.onContextUpdate?.(ctxParams);\n\t\t\t\tsendJson(res, 200, { ok: true, result: {} });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.pathname === \"/proxy/ui/open-link\") {\n\t\t\t\tconst openParams = params as { url?: string };\n\t\t\t\tif (!openParams?.url || typeof openParams.url !== \"string\") {\n\t\t\t\t\tsendJson(res, 400, { ok: false, error: \"Invalid open-link params\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet result: UiOpenLinkResult = {};\n\t\t\t\ttry {\n\t\t\t\t\tconst externalUrl = new URL(openParams.url);\n\t\t\t\t\tif (\n\t\t\t\t\t\t(externalUrl.protocol !== \"http:\" && externalUrl.protocol !== \"https:\") ||\n\t\t\t\t\t\texternalUrl.username ||\n\t\t\t\t\t\texternalUrl.password\n\t\t\t\t\t) {\n\t\t\t\t\t\tresult = { isError: true };\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tresult = { isError: true };\n\t\t\t\t}\n\t\t\t\tsendJson(res, 200, { ok: true, result });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.pathname === \"/proxy/ui/download-file\") {\n\t\t\t\tsendJson(res, 200, { ok: true, result: { isError: true } });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.pathname === \"/proxy/ui/request-display-mode\") {\n\t\t\t\tconst displayParams = params as UiDisplayModeRequest;\n\t\t\t\tconst requested = displayParams?.mode;\n\t\t\t\tconst available = hostContext.availableDisplayModes ?? [\"inline\"];\n\t\t\t\tif (requested && available.includes(requested)) {\n\t\t\t\t\tcurrentDisplayMode = requested;\n\t\t\t\t}\n\t\t\t\thostContext.displayMode = currentDisplayMode;\n\t\t\t\tpushEvent(\"host-context\", { displayMode: currentDisplayMode });\n\t\t\t\tconst result: UiDisplayModeResult = { mode: currentDisplayMode };\n\t\t\t\tsendJson(res, 200, { ok: true, result });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.pathname === \"/proxy/ui/heartbeat\") {\n\t\t\t\tsendJson(res, 200, { ok: true, result: {} });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (url.pathname === \"/proxy/ui/complete\") {\n\t\t\t\tconst reason =\n\t\t\t\t\ttypeof (params as { reason?: string }).reason === \"string\"\n\t\t\t\t\t\t? (params as { reason?: string }).reason!\n\t\t\t\t\t\t: \"done\";\n\t\t\t\tmarkCompleted(reason);\n\t\t\t\tsendJson(res, 200, { ok: true, result: {} });\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tserver.close();\n\t\t\t\t\t} catch {}\n\t\t\t\t\tcloseSse();\n\t\t\t\t}, 20).unref();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsendJson(res, 404, { ok: false, error: \"Not found\" });\n\t\t} catch (error) {\n\t\t\tif (error instanceof SessionRecoveryAuthRequiredError) {\n\t\t\t\tconst fallback = `Server \"${options.serverName}\" requires OAuth authentication. Run mcp({ action: \"auth-start\", server: \"${options.serverName}\" }) to get a browser URL, or /mcp-auth ${options.serverName} in an interactive local session.`;\n\t\t\t\tconst message =\n\t\t\t\t\terror.authMessage ??\n\t\t\t\t\t(options.config ? formatAuthRequiredMessage(options.config, options.serverName, fallback) : fallback);\n\t\t\t\tsendJson(res, 401, { ok: false, error: message });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst wrapped = wrapError(error, { server: options.serverName, tool: options.toolName });\n\t\t\tconst status = /approval required|denied/i.test(wrapped.message) ? 403 : 500;\n\t\t\tif (status === 500) {\n\t\t\t\tlog.error(\"Request handler error\", error instanceof Error ? error : undefined);\n\t\t\t}\n\t\t\tsendJson(res, status, { ok: false, error: wrapped.message });\n\t\t}\n\t});\n\n\tif (options.initialResultPromise) {\n\t\toptions.initialResultPromise.then(\n\t\t\t(result) => pushEvent(\"tool-result\", result),\n\t\t\t(error) => {\n\t\t\t\tconst reason = error instanceof Error ? error.message : String(error);\n\t\t\t\tpushEvent(\"tool-cancelled\", { reason });\n\t\t\t},\n\t\t);\n\t}\n\n\twatchdog = setInterval(() => {\n\t\tif (completed) return;\n\t\tif (Date.now() - lastHeartbeatAt <= ABANDONED_GRACE_MS) return;\n\t\tmarkCompleted(\"stale\");\n\t\ttry {\n\t\t\tserver.close();\n\t\t} catch {}\n\t\tcloseSse();\n\t}, WATCHDOG_INTERVAL_MS);\n\twatchdog.unref();\n\n\treturn new Promise((resolve, reject) => {\n\t\tconst candidates = resolvePortCandidates(options.port);\n\t\tlet candidateIndex = 0;\n\n\t\tconst listen = () => {\n\t\t\tserver.once(\"error\", onError);\n\t\t\tserver.listen(candidates[candidateIndex], \"127.0.0.1\", onListening);\n\t\t};\n\n\t\tconst onError = (error: NodeJS.ErrnoException) => {\n\t\t\tserver.off(\"listening\", onListening);\n\t\t\tif (error.code === \"EADDRINUSE\" && candidateIndex < candidates.length - 1) {\n\t\t\t\tcandidateIndex += 1;\n\t\t\t\tlisten();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlog.error(\"Failed to start server\", error);\n\t\t\tconst port = candidates[candidateIndex];\n\t\t\treject(\n\t\t\t\tnew ServerError(error.message, {\n\t\t\t\t\t...(port !== undefined ? { port } : {}),\n\t\t\t\t\tcause: error,\n\t\t\t\t}),\n\t\t\t);\n\t\t};\n\n\t\tconst onListening = () => {\n\t\t\tserver.off(\"error\", onError);\n\t\t\tconst address = server.address();\n\t\t\tif (!address || typeof address === \"string\") {\n\t\t\t\tconst err = new ServerError(\"invalid address\");\n\t\t\t\tlog.error(\"Invalid server address\", err);\n\t\t\t\treject(err);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlog.debug(\"Server started\", { port: address.port });\n\t\t\trememberMoshiDiscoveryPort(address.port);\n\n\t\t\tconst handle: UiServerHandle = {\n\t\t\t\turl: `http://localhost:${address.port}/?session=${sessionToken}`,\n\t\t\t\tport: address.port,\n\t\t\t\tsessionToken,\n\t\t\t\tserverName: options.serverName,\n\t\t\t\ttoolName: options.toolName,\n\t\t\t\tclose: (reason?: string) => {\n\t\t\t\t\tmarkCompleted(reason ?? \"closed\");\n\t\t\t\t\ttry {\n\t\t\t\t\t\tserver.close();\n\t\t\t\t\t} catch {}\n\t\t\t\t\tcloseSse();\n\t\t\t\t},\n\t\t\t\tsendToolInput: (args: Record<string, unknown>) => {\n\t\t\t\t\tpushEvent(\"tool-input\", { arguments: args });\n\t\t\t\t},\n\t\t\t\tsendToolResult: (result: CallToolResult) => {\n\t\t\t\t\tpushEvent(\"tool-result\", result);\n\t\t\t\t},\n\t\t\t\tsendResultPatch: (result: CallToolResult) => {\n\t\t\t\t\tpushEvent(\"result-patch\", result);\n\t\t\t\t},\n\t\t\t\tsendToolCancelled: (reason: string) => {\n\t\t\t\t\tpushEvent(\"tool-cancelled\", { reason });\n\t\t\t\t},\n\t\t\t\tsendHostContext: (context: UiHostContext) => {\n\t\t\t\t\tObject.assign(hostContext, context);\n\t\t\t\t\tpushEvent(\"host-context\", context);\n\t\t\t\t},\n\t\t\t\tgetSessionMessages: () => ({ ...sessionMessages }),\n\t\t\t\tgetStreamSummary: () =>\n\t\t\t\t\tstreamSummary ? { ...streamSummary, phases: [...streamSummary.phases] } : undefined,\n\t\t\t};\n\n\t\t\tresolve(handle);\n\t\t};\n\n\t\tlisten();\n\t});\n}\n\nasync function parseBody(\n\treq: IncomingMessage,\n\tres: ServerResponse,\n): Promise<UiProxyRequestBody<Record<string, unknown>> | null> {\n\ttry {\n\t\tconst body = await readBody(req);\n\t\tif (!body || typeof body !== \"object\") {\n\t\t\tsendJson(res, 400, { ok: false, error: \"Invalid request body\" });\n\t\t\treturn null;\n\t\t}\n\t\treturn body as UiProxyRequestBody<Record<string, unknown>>;\n\t} catch (error) {\n\t\tsendJson(res, 400, { ok: false, error: error instanceof Error ? error.message : \"Invalid body\" });\n\t\treturn null;\n\t}\n}\n\nfunction readBody(req: IncomingMessage): Promise<unknown> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet size = 0;\n\t\tconst chunks: Buffer[] = [];\n\n\t\treq.on(\"data\", (chunk: Buffer) => {\n\t\t\tsize += chunk.length;\n\t\t\tif (size > MAX_BODY_SIZE) {\n\t\t\t\treq.destroy();\n\t\t\t\treject(new Error(\"Request body too large\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tchunks.push(chunk);\n\t\t});\n\n\t\treq.on(\"end\", () => {\n\t\t\ttry {\n\t\t\t\tresolve(JSON.parse(Buffer.concat(chunks).toString(\"utf-8\")));\n\t\t\t} catch (error) {\n\t\t\t\treject(error);\n\t\t\t}\n\t\t});\n\n\t\treq.on(\"error\", reject);\n\t});\n}\n\nfunction resolvePortCandidates(port: number | undefined): number[] {\n\tif (port !== undefined) return [port];\n\tconst candidates: number[] = [];\n\tconst count = MOSHI_DISCOVERY_PORT_END - MOSHI_DISCOVERY_PORT_START + 1;\n\tfor (let offset = 0; offset < count; offset += 1) {\n\t\tconst candidate =\n\t\t\tMOSHI_DISCOVERY_PORT_START + ((nextMoshiDiscoveryPort - MOSHI_DISCOVERY_PORT_START + offset) % count);\n\t\tcandidates.push(candidate);\n\t}\n\tcandidates.push(0);\n\treturn candidates;\n}\n\nfunction rememberMoshiDiscoveryPort(port: number): void {\n\tif (port < MOSHI_DISCOVERY_PORT_START || port > MOSHI_DISCOVERY_PORT_END) return;\n\tnextMoshiDiscoveryPort = port >= MOSHI_DISCOVERY_PORT_END ? MOSHI_DISCOVERY_PORT_START : port + 1;\n}\n\nfunction isAllowedHost(hostname: string): boolean {\n\treturn hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\";\n}\n\nfunction validateTokenQuery(url: URL, expected: string, res: ServerResponse, parameter = \"session\"): boolean {\n\tconst token = url.searchParams.get(parameter);\n\tif (token !== expected) {\n\t\tsendJson(res, 403, { ok: false, error: \"Invalid session\" });\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nfunction validateTokenBody(\n\tbody: UiProxyRequestBody<Record<string, unknown>>,\n\texpected: string,\n\tres: ServerResponse,\n): boolean {\n\tif (body.token !== expected) {\n\t\tsendJson(res, 403, { ok: false, error: \"Invalid session\" });\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nfunction sendJson<T>(res: ServerResponse, status: number, payload: UiProxyResult<T>): void {\n\tres.writeHead(status, {\n\t\t\"Content-Type\": \"application/json; charset=utf-8\",\n\t\t\"Cache-Control\": \"no-store\",\n\t});\n\tres.end(JSON.stringify(payload));\n}\n\nfunction sendText(res: ServerResponse, status: number, text: string): void {\n\tres.writeHead(status, {\n\t\t\"Content-Type\": \"text/plain; charset=utf-8\",\n\t\t\"Cache-Control\": \"no-store\",\n\t});\n\tres.end(text);\n}\n"]}
@@ -0,0 +1,40 @@
1
+ import { type CallToolResult } from "@modelcontextprotocol/client";
2
+ import type { SessionRecoveryDeps } from "./session-recovery.ts";
3
+ import type { McpExtensionState } from "./state.ts";
4
+ import { type UiStreamMode } from "./types.ts";
5
+ export interface UiSessionRequest {
6
+ serverName: string;
7
+ toolName: string;
8
+ toolArgs: Record<string, unknown>;
9
+ uiResourceUri: string;
10
+ streamMode?: UiStreamMode;
11
+ signal?: AbortSignal;
12
+ onNeedsAuth?: SessionRecoveryDeps["onNeedsAuth"];
13
+ }
14
+ export type UiSessionViewer = "browser" | "glimpse" | "suppressed";
15
+ export interface UiSessionRuntime {
16
+ serverName: string;
17
+ toolName: string;
18
+ reused: boolean;
19
+ streamId?: string;
20
+ streamToken?: string;
21
+ streamMode?: UiStreamMode;
22
+ requestMeta?: Record<string, unknown>;
23
+ url: string;
24
+ viewer: UiSessionViewer;
25
+ windowOpen: boolean;
26
+ isActive: () => boolean;
27
+ sendToolResult: (result: CallToolResult) => void;
28
+ sendResultPatch: (result: CallToolResult) => void;
29
+ sendToolCancelled: (reason: string) => void;
30
+ close: (reason?: string) => void;
31
+ }
32
+ export interface UiSessionResultSummary {
33
+ message: string;
34
+ uiOpen: boolean;
35
+ uiViewer?: UiSessionViewer;
36
+ uiUrl?: string;
37
+ }
38
+ export declare function summarizeUiSessionResult(uiSession: UiSessionRuntime | null): UiSessionResultSummary;
39
+ export declare function maybeStartUiSession(state: McpExtensionState, request: UiSessionRequest): Promise<UiSessionRuntime | null>;
40
+ //# sourceMappingURL=ui-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui-session.d.ts","sourceRoot":"","sources":["../../../src/extensions/mcp/ui-session.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAA+B,MAAM,8BAA8B,CAAC;AAKhG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EASN,KAAK,YAAY,EACjB,MAAM,YAAY,CAAC;AAKpB,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,WAAW,CAAC,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAAC;CACjD;AAED,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;AAEnE,MAAM,WAAW,gBAAgB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,eAAe,CAAC;IACxB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,OAAO,CAAC;IACxB,cAAc,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACjD,eAAe,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI,GAAG,sBAAsB,CA0BnG;AA+GD,wBAAsB,mBAAmB,CACxC,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAoYlC","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"]}