skybridge 0.0.0-dev.fcccc51 → 0.0.0-dev.fcff71e

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 (481) hide show
  1. package/README.md +153 -0
  2. package/bin/run.js +0 -4
  3. package/dist/cli/build-helpers.d.ts +11 -0
  4. package/dist/cli/build-helpers.js +102 -0
  5. package/dist/cli/build-helpers.js.map +1 -0
  6. package/dist/cli/build-helpers.test.js +119 -0
  7. package/dist/cli/build-helpers.test.js.map +1 -0
  8. package/dist/cli/build-steps.d.ts +2 -0
  9. package/dist/cli/build-steps.js +73 -0
  10. package/dist/cli/build-steps.js.map +1 -0
  11. package/dist/cli/build-steps.test.js +52 -0
  12. package/dist/cli/build-steps.test.js.map +1 -0
  13. package/dist/cli/detect-port.d.ts +18 -0
  14. package/dist/cli/detect-port.js +50 -0
  15. package/dist/cli/detect-port.js.map +1 -0
  16. package/dist/cli/header.d.ts +1 -1
  17. package/dist/cli/header.js +1 -1
  18. package/dist/cli/header.js.map +1 -1
  19. package/dist/cli/resolve-views-dir.d.ts +1 -0
  20. package/dist/cli/resolve-views-dir.js +17 -0
  21. package/dist/cli/resolve-views-dir.js.map +1 -0
  22. package/dist/cli/run-command.js.map +1 -1
  23. package/dist/cli/run-plain.d.ts +18 -0
  24. package/dist/cli/run-plain.js +89 -0
  25. package/dist/cli/run-plain.js.map +1 -0
  26. package/dist/cli/telemetry.d.ts +7 -0
  27. package/dist/cli/telemetry.js +123 -0
  28. package/dist/cli/telemetry.js.map +1 -0
  29. package/dist/cli/tunnel-control-server.d.ts +9 -0
  30. package/dist/cli/tunnel-control-server.js +31 -0
  31. package/dist/cli/tunnel-control-server.js.map +1 -0
  32. package/dist/cli/tunnel-control-server.test.js +39 -0
  33. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  34. package/dist/cli/tunnel-handler.d.ts +3 -0
  35. package/dist/cli/tunnel-handler.js +48 -0
  36. package/dist/cli/tunnel-handler.js.map +1 -0
  37. package/dist/cli/tunnel-handler.test.d.ts +1 -0
  38. package/dist/cli/tunnel-handler.test.js +105 -0
  39. package/dist/cli/tunnel-handler.test.js.map +1 -0
  40. package/dist/cli/tunnel.d.ts +57 -0
  41. package/dist/cli/tunnel.js +154 -0
  42. package/dist/cli/tunnel.js.map +1 -0
  43. package/dist/cli/tunnel.test.d.ts +1 -0
  44. package/dist/cli/tunnel.test.js +190 -0
  45. package/dist/cli/tunnel.test.js.map +1 -0
  46. package/dist/cli/types.d.ts +5 -0
  47. package/dist/cli/types.js +2 -0
  48. package/dist/cli/types.js.map +1 -0
  49. package/dist/cli/use-execute-steps.d.ts +3 -2
  50. package/dist/cli/use-execute-steps.js +6 -1
  51. package/dist/cli/use-execute-steps.js.map +1 -1
  52. package/dist/cli/use-messages.d.ts +3 -0
  53. package/dist/cli/use-messages.js +11 -0
  54. package/dist/cli/use-messages.js.map +1 -0
  55. package/dist/cli/use-nodemon.d.ts +16 -0
  56. package/dist/cli/use-nodemon.js +84 -0
  57. package/dist/cli/use-nodemon.js.map +1 -0
  58. package/dist/cli/use-open-browser.d.ts +1 -0
  59. package/dist/cli/use-open-browser.js +44 -0
  60. package/dist/cli/use-open-browser.js.map +1 -0
  61. package/dist/cli/use-tunnel.d.ts +14 -0
  62. package/dist/cli/use-tunnel.js +131 -0
  63. package/dist/cli/use-tunnel.js.map +1 -0
  64. package/dist/cli/use-typescript-check.d.ts +15 -0
  65. package/dist/cli/use-typescript-check.js +97 -0
  66. package/dist/cli/use-typescript-check.js.map +1 -0
  67. package/dist/commands/build.d.ts +0 -3
  68. package/dist/commands/build.js +3 -16
  69. package/dist/commands/build.js.map +1 -1
  70. package/dist/commands/create.d.ts +9 -0
  71. package/dist/commands/create.js +30 -0
  72. package/dist/commands/create.js.map +1 -0
  73. package/dist/commands/dev.d.ts +7 -1
  74. package/dist/commands/dev.js +117 -9
  75. package/dist/commands/dev.js.map +1 -1
  76. package/dist/commands/start.d.ts +3 -1
  77. package/dist/commands/start.js +37 -15
  78. package/dist/commands/start.js.map +1 -1
  79. package/dist/commands/telemetry/disable.d.ts +5 -0
  80. package/dist/commands/telemetry/disable.js +14 -0
  81. package/dist/commands/telemetry/disable.js.map +1 -0
  82. package/dist/commands/telemetry/enable.d.ts +5 -0
  83. package/dist/commands/telemetry/enable.js +14 -0
  84. package/dist/commands/telemetry/enable.js.map +1 -0
  85. package/dist/commands/telemetry/status.d.ts +5 -0
  86. package/dist/commands/telemetry/status.js +14 -0
  87. package/dist/commands/telemetry/status.js.map +1 -0
  88. package/dist/server/asset-base-url-transform-plugin.d.ts +11 -0
  89. package/dist/server/asset-base-url-transform-plugin.js +48 -0
  90. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  91. package/dist/server/asset-base-url-transform-plugin.test.d.ts +1 -0
  92. package/dist/server/asset-base-url-transform-plugin.test.js +134 -0
  93. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  94. package/dist/server/auth/discovery.d.ts +32 -0
  95. package/dist/server/auth/discovery.js +56 -0
  96. package/dist/server/auth/discovery.js.map +1 -0
  97. package/dist/server/auth/discovery.test.d.ts +1 -0
  98. package/dist/server/auth/discovery.test.js +93 -0
  99. package/dist/server/auth/discovery.test.js.map +1 -0
  100. package/dist/server/auth/index.d.ts +18 -0
  101. package/dist/server/auth/index.js +2 -0
  102. package/dist/server/auth/index.js.map +1 -0
  103. package/dist/server/auth/providers/auth0.d.ts +18 -0
  104. package/dist/server/auth/providers/auth0.js +31 -0
  105. package/dist/server/auth/providers/auth0.js.map +1 -0
  106. package/dist/server/auth/providers/auth0.test.d.ts +1 -0
  107. package/dist/server/auth/providers/auth0.test.js +48 -0
  108. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  109. package/dist/server/auth/providers/clerk.d.ts +14 -0
  110. package/dist/server/auth/providers/clerk.js +16 -0
  111. package/dist/server/auth/providers/clerk.js.map +1 -0
  112. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  113. package/dist/server/auth/providers/clerk.test.js +28 -0
  114. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  115. package/dist/server/auth/providers/custom.d.ts +30 -0
  116. package/dist/server/auth/providers/custom.js +40 -0
  117. package/dist/server/auth/providers/custom.js.map +1 -0
  118. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  119. package/dist/server/auth/providers/custom.test.js +128 -0
  120. package/dist/server/auth/providers/custom.test.js.map +1 -0
  121. package/dist/server/auth/providers/descope.d.ts +15 -0
  122. package/dist/server/auth/providers/descope.js +35 -0
  123. package/dist/server/auth/providers/descope.js.map +1 -0
  124. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  125. package/dist/server/auth/providers/descope.test.js +39 -0
  126. package/dist/server/auth/providers/descope.test.js.map +1 -0
  127. package/dist/server/auth/providers/shared.d.ts +2 -0
  128. package/dist/server/auth/providers/shared.js +6 -0
  129. package/dist/server/auth/providers/shared.js.map +1 -0
  130. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  131. package/dist/server/auth/providers/shared.test.js +10 -0
  132. package/dist/server/auth/providers/shared.test.js.map +1 -0
  133. package/dist/server/auth/providers/stytch.d.ts +12 -0
  134. package/dist/server/auth/providers/stytch.js +13 -0
  135. package/dist/server/auth/providers/stytch.js.map +1 -0
  136. package/dist/server/auth/providers/workos.d.ts +11 -0
  137. package/dist/server/auth/providers/workos.js +12 -0
  138. package/dist/server/auth/providers/workos.js.map +1 -0
  139. package/dist/server/auth/setup.d.ts +4 -0
  140. package/dist/server/auth/setup.js +51 -0
  141. package/dist/server/auth/setup.js.map +1 -0
  142. package/dist/server/auth/setup.test.d.ts +1 -0
  143. package/dist/server/auth/setup.test.js +185 -0
  144. package/dist/server/auth/setup.test.js.map +1 -0
  145. package/dist/server/auth/verify.d.ts +12 -0
  146. package/dist/server/auth/verify.js +38 -0
  147. package/dist/server/auth/verify.js.map +1 -0
  148. package/dist/server/auth/verify.test.d.ts +1 -0
  149. package/dist/server/auth/verify.test.js +100 -0
  150. package/dist/server/auth/verify.test.js.map +1 -0
  151. package/dist/server/auth.d.ts +20 -0
  152. package/dist/server/auth.js +28 -0
  153. package/dist/server/auth.js.map +1 -0
  154. package/dist/server/build-manifest.test.d.ts +1 -0
  155. package/dist/server/build-manifest.test.js +27 -0
  156. package/dist/server/build-manifest.test.js.map +1 -0
  157. package/dist/server/content-helpers.d.ts +67 -0
  158. package/dist/server/content-helpers.js +79 -0
  159. package/dist/server/content-helpers.js.map +1 -0
  160. package/dist/server/content-helpers.test.d.ts +1 -0
  161. package/dist/server/content-helpers.test.js +70 -0
  162. package/dist/server/content-helpers.test.js.map +1 -0
  163. package/dist/server/express.d.ts +11 -0
  164. package/dist/server/express.js +101 -0
  165. package/dist/server/express.js.map +1 -0
  166. package/dist/server/express.test.d.ts +1 -0
  167. package/dist/server/express.test.js +491 -0
  168. package/dist/server/express.test.js.map +1 -0
  169. package/dist/server/file-ref.d.ts +28 -0
  170. package/dist/server/file-ref.js +27 -0
  171. package/dist/server/file-ref.js.map +1 -0
  172. package/dist/server/index.d.ts +15 -3
  173. package/dist/server/index.js +12 -2
  174. package/dist/server/index.js.map +1 -1
  175. package/dist/server/inferUtilityTypes.d.ts +6 -6
  176. package/dist/server/inferUtilityTypes.js.map +1 -1
  177. package/dist/server/metric.d.ts +14 -0
  178. package/dist/server/metric.js +62 -0
  179. package/dist/server/metric.js.map +1 -0
  180. package/dist/server/middleware.d.ts +137 -0
  181. package/dist/server/middleware.js +93 -0
  182. package/dist/server/middleware.js.map +1 -0
  183. package/dist/server/middleware.test-d.d.ts +1 -0
  184. package/dist/server/middleware.test-d.js +75 -0
  185. package/dist/server/middleware.test-d.js.map +1 -0
  186. package/dist/server/middleware.test.d.ts +1 -0
  187. package/dist/server/middleware.test.js +493 -0
  188. package/dist/server/middleware.test.js.map +1 -0
  189. package/dist/server/requestOrigin.d.ts +7 -0
  190. package/dist/server/requestOrigin.js +25 -0
  191. package/dist/server/requestOrigin.js.map +1 -0
  192. package/dist/server/server.d.ts +387 -57
  193. package/dist/server/server.js +618 -82
  194. package/dist/server/server.js.map +1 -1
  195. package/dist/server/skills-integration.test.d.ts +1 -0
  196. package/dist/server/skills-integration.test.js +63 -0
  197. package/dist/server/skills-integration.test.js.map +1 -0
  198. package/dist/server/skills.d.ts +23 -0
  199. package/dist/server/skills.js +178 -0
  200. package/dist/server/skills.js.map +1 -0
  201. package/dist/server/skills.test.d.ts +1 -0
  202. package/dist/server/skills.test.js +210 -0
  203. package/dist/server/skills.test.js.map +1 -0
  204. package/dist/server/templateHelper.d.ts +5 -7
  205. package/dist/server/templateHelper.js +3 -22
  206. package/dist/server/templateHelper.js.map +1 -1
  207. package/dist/server/templates.generated.d.ts +4 -0
  208. package/dist/server/templates.generated.js +47 -0
  209. package/dist/server/templates.generated.js.map +1 -0
  210. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  211. package/dist/server/tunnel-proxy-router.js +110 -0
  212. package/dist/server/tunnel-proxy-router.js.map +1 -0
  213. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  214. package/dist/server/tunnel-proxy-router.test.js +229 -0
  215. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  216. package/dist/server/view-name.test-d.d.ts +1 -0
  217. package/dist/server/view-name.test-d.js +8 -0
  218. package/dist/server/view-name.test-d.js.map +1 -0
  219. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  220. package/dist/server/view-resource-resolution.test.js +171 -0
  221. package/dist/server/view-resource-resolution.test.js.map +1 -0
  222. package/dist/server/viewsDevServer.d.ts +14 -0
  223. package/dist/server/viewsDevServer.js +45 -0
  224. package/dist/server/viewsDevServer.js.map +1 -0
  225. package/dist/test/utils.d.ts +13 -21
  226. package/dist/test/utils.js +42 -37
  227. package/dist/test/utils.js.map +1 -1
  228. package/dist/test/view.test.d.ts +1 -0
  229. package/dist/test/view.test.js +536 -0
  230. package/dist/test/view.test.js.map +1 -0
  231. package/dist/version.d.ts +1 -0
  232. package/dist/version.js +3 -0
  233. package/dist/version.js.map +1 -0
  234. package/dist/web/bridges/adaptor.d.ts +51 -0
  235. package/dist/web/bridges/adaptor.js +330 -0
  236. package/dist/web/bridges/adaptor.js.map +1 -0
  237. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  238. package/dist/web/bridges/adaptor.test.js +208 -0
  239. package/dist/web/bridges/adaptor.test.js.map +1 -0
  240. package/dist/web/bridges/apps-sdk/bridge.d.ts +15 -0
  241. package/dist/web/bridges/{apps-sdk-bridge.js → apps-sdk/bridge.js} +17 -5
  242. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  243. package/dist/web/bridges/apps-sdk/index.d.ts +4 -0
  244. package/dist/web/bridges/apps-sdk/index.js +4 -0
  245. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  246. package/dist/web/bridges/apps-sdk/types.d.ts +133 -0
  247. package/dist/web/bridges/apps-sdk/types.js +10 -0
  248. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  249. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +13 -0
  250. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +18 -0
  251. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  252. package/dist/web/bridges/get-adaptor.d.ts +9 -0
  253. package/dist/web/bridges/get-adaptor.js +10 -0
  254. package/dist/web/bridges/get-adaptor.js.map +1 -0
  255. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  256. package/dist/web/bridges/get-adaptor.test.js +32 -0
  257. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  258. package/dist/web/bridges/index.d.ts +5 -4
  259. package/dist/web/bridges/index.js +5 -4
  260. package/dist/web/bridges/index.js.map +1 -1
  261. package/dist/web/bridges/mcp-app/bridge.d.ts +39 -0
  262. package/dist/web/bridges/mcp-app/bridge.js +166 -0
  263. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  264. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  265. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  266. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  267. package/dist/web/bridges/mcp-app/index.d.ts +3 -0
  268. package/dist/web/bridges/mcp-app/index.js +3 -0
  269. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  270. package/dist/web/bridges/mcp-app/types.d.ts +8 -0
  271. package/dist/web/bridges/mcp-app/types.js +2 -0
  272. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  273. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +19 -0
  274. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +19 -0
  275. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  276. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.d.ts +1 -0
  277. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +26 -0
  278. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  279. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  280. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  281. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  282. package/dist/web/bridges/types.d.ts +187 -34
  283. package/dist/web/bridges/types.js +14 -1
  284. package/dist/web/bridges/types.js.map +1 -1
  285. package/dist/web/bridges/types.test.d.ts +1 -0
  286. package/dist/web/bridges/types.test.js +19 -0
  287. package/dist/web/bridges/types.test.js.map +1 -0
  288. package/dist/web/bridges/use-host-context.d.ts +7 -0
  289. package/dist/web/bridges/use-host-context.js +13 -0
  290. package/dist/web/bridges/use-host-context.js.map +1 -0
  291. package/dist/web/components/modal-provider.d.ts +4 -0
  292. package/dist/web/components/modal-provider.js +46 -0
  293. package/dist/web/components/modal-provider.js.map +1 -0
  294. package/dist/web/create-store.d.ts +26 -0
  295. package/dist/web/create-store.js +43 -3
  296. package/dist/web/create-store.js.map +1 -1
  297. package/dist/web/create-store.test.js +34 -25
  298. package/dist/web/create-store.test.js.map +1 -1
  299. package/dist/web/data-llm.d.ts +35 -2
  300. package/dist/web/data-llm.js +31 -3
  301. package/dist/web/data-llm.js.map +1 -1
  302. package/dist/web/data-llm.test.js +50 -36
  303. package/dist/web/data-llm.test.js.map +1 -1
  304. package/dist/web/generate-helpers.d.ts +24 -19
  305. package/dist/web/generate-helpers.js +22 -18
  306. package/dist/web/generate-helpers.js.map +1 -1
  307. package/dist/web/generate-helpers.test-d.js +30 -28
  308. package/dist/web/generate-helpers.test-d.js.map +1 -1
  309. package/dist/web/generate-helpers.test.js.map +1 -1
  310. package/dist/web/helpers/state.d.ts +2 -2
  311. package/dist/web/helpers/state.js +11 -11
  312. package/dist/web/helpers/state.js.map +1 -1
  313. package/dist/web/helpers/state.test.js +9 -9
  314. package/dist/web/helpers/state.test.js.map +1 -1
  315. package/dist/web/hooks/index.d.ts +7 -3
  316. package/dist/web/hooks/index.js +6 -2
  317. package/dist/web/hooks/index.js.map +1 -1
  318. package/dist/web/hooks/test/utils.d.ts +6 -2
  319. package/dist/web/hooks/test/utils.js +17 -2
  320. package/dist/web/hooks/test/utils.js.map +1 -1
  321. package/dist/web/hooks/use-call-tool.d.ts +48 -2
  322. package/dist/web/hooks/use-call-tool.js +29 -1
  323. package/dist/web/hooks/use-call-tool.js.map +1 -1
  324. package/dist/web/hooks/use-call-tool.test-d.js +1 -1
  325. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
  326. package/dist/web/hooks/use-call-tool.test.js +65 -30
  327. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  328. package/dist/web/hooks/use-display-mode.d.ts +23 -3
  329. package/dist/web/hooks/use-display-mode.js +22 -3
  330. package/dist/web/hooks/use-display-mode.js.map +1 -1
  331. package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
  332. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  333. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  334. package/dist/web/hooks/use-display-mode.test.js +56 -20
  335. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  336. package/dist/web/hooks/use-download.d.ts +5 -0
  337. package/dist/web/hooks/use-download.js +8 -0
  338. package/dist/web/hooks/use-download.js.map +1 -0
  339. package/dist/web/hooks/use-download.test.d.ts +1 -0
  340. package/dist/web/hooks/use-download.test.js +103 -0
  341. package/dist/web/hooks/use-download.test.js.map +1 -0
  342. package/dist/web/hooks/use-files.d.ts +35 -6
  343. package/dist/web/hooks/use-files.js +37 -2
  344. package/dist/web/hooks/use-files.js.map +1 -1
  345. package/dist/web/hooks/use-files.test.js +36 -3
  346. package/dist/web/hooks/use-files.test.js.map +1 -1
  347. package/dist/web/hooks/use-layout.d.ts +4 -2
  348. package/dist/web/hooks/use-layout.js +6 -4
  349. package/dist/web/hooks/use-layout.js.map +1 -1
  350. package/dist/web/hooks/use-layout.test.js +65 -31
  351. package/dist/web/hooks/use-layout.test.js.map +1 -1
  352. package/dist/web/hooks/use-open-external.d.ts +20 -1
  353. package/dist/web/hooks/use-open-external.js +17 -1
  354. package/dist/web/hooks/use-open-external.js.map +1 -1
  355. package/dist/web/hooks/use-open-external.test.js +39 -14
  356. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  357. package/dist/web/hooks/use-register-view-tool.d.ts +38 -0
  358. package/dist/web/hooks/use-register-view-tool.js +50 -0
  359. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  360. package/dist/web/hooks/use-request-close.d.ts +16 -0
  361. package/dist/web/hooks/use-request-close.js +21 -0
  362. package/dist/web/hooks/use-request-close.js.map +1 -0
  363. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  364. package/dist/web/hooks/use-request-close.test.js +47 -0
  365. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  366. package/dist/web/hooks/use-request-modal.d.ts +18 -3
  367. package/dist/web/hooks/use-request-modal.js +25 -8
  368. package/dist/web/hooks/use-request-modal.js.map +1 -1
  369. package/dist/web/hooks/use-request-modal.test.js +15 -1
  370. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  371. package/dist/web/hooks/use-request-size.d.ts +20 -0
  372. package/dist/web/hooks/use-request-size.js +24 -0
  373. package/dist/web/hooks/use-request-size.js.map +1 -0
  374. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  375. package/dist/web/hooks/use-request-size.test.js +47 -0
  376. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  377. package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -1
  378. package/dist/web/hooks/use-send-follow-up-message.js +19 -2
  379. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  380. package/dist/web/hooks/use-set-open-in-app-url.d.ts +18 -0
  381. package/dist/web/hooks/use-set-open-in-app-url.js +25 -0
  382. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  383. package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
  384. package/dist/web/hooks/use-set-open-in-app-url.test.js +63 -0
  385. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  386. package/dist/web/hooks/use-tool-info.d.ts +53 -2
  387. package/dist/web/hooks/use-tool-info.js +34 -11
  388. package/dist/web/hooks/use-tool-info.js.map +1 -1
  389. package/dist/web/hooks/use-tool-info.test-d.js +11 -29
  390. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  391. package/dist/web/hooks/use-tool-info.test.js +45 -35
  392. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  393. package/dist/web/hooks/use-user.d.ts +3 -1
  394. package/dist/web/hooks/use-user.js +22 -4
  395. package/dist/web/hooks/use-user.js.map +1 -1
  396. package/dist/web/hooks/use-user.test.js +104 -29
  397. package/dist/web/hooks/use-user.test.js.map +1 -1
  398. package/dist/web/hooks/use-view-state.d.ts +25 -0
  399. package/dist/web/hooks/use-view-state.js +32 -0
  400. package/dist/web/hooks/use-view-state.js.map +1 -0
  401. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  402. package/dist/web/hooks/use-view-state.test.js +181 -0
  403. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  404. package/dist/web/index.d.ts +1 -2
  405. package/dist/web/index.js +1 -2
  406. package/dist/web/index.js.map +1 -1
  407. package/dist/web/mount-view.d.ts +20 -0
  408. package/dist/web/mount-view.js +46 -0
  409. package/dist/web/mount-view.js.map +1 -0
  410. package/dist/web/plugin/data-llm.test.js.map +1 -1
  411. package/dist/web/plugin/plugin.d.ts +32 -1
  412. package/dist/web/plugin/plugin.js +167 -18
  413. package/dist/web/plugin/plugin.js.map +1 -1
  414. package/dist/web/plugin/scan-views.d.ts +16 -0
  415. package/dist/web/plugin/scan-views.js +88 -0
  416. package/dist/web/plugin/scan-views.js.map +1 -0
  417. package/dist/web/plugin/scan-views.test.d.ts +1 -0
  418. package/dist/web/plugin/scan-views.test.js +99 -0
  419. package/dist/web/plugin/scan-views.test.js.map +1 -0
  420. package/dist/web/plugin/transform-data-llm.js +1 -1
  421. package/dist/web/plugin/transform-data-llm.js.map +1 -1
  422. package/dist/web/plugin/transform-data-llm.test.js.map +1 -1
  423. package/dist/web/plugin/validate-view.d.ts +1 -0
  424. package/dist/web/plugin/validate-view.js +9 -0
  425. package/dist/web/plugin/validate-view.js.map +1 -0
  426. package/dist/web/plugin/validate-view.test.d.ts +1 -0
  427. package/dist/web/plugin/validate-view.test.js +24 -0
  428. package/dist/web/plugin/validate-view.test.js.map +1 -0
  429. package/dist/web/proxy.js +0 -1
  430. package/dist/web/proxy.js.map +1 -1
  431. package/dist/web/types.d.ts +4 -133
  432. package/dist/web/types.js +0 -9
  433. package/dist/web/types.js.map +1 -1
  434. package/package.json +60 -31
  435. package/tsconfig.base.json +33 -0
  436. package/dist/server/templates/development.hbs +0 -66
  437. package/dist/server/templates/production.hbs +0 -7
  438. package/dist/server/widgetsDevServer.d.ts +0 -12
  439. package/dist/server/widgetsDevServer.js +0 -47
  440. package/dist/server/widgetsDevServer.js.map +0 -1
  441. package/dist/test/widget.test.js +0 -234
  442. package/dist/test/widget.test.js.map +0 -1
  443. package/dist/web/bridges/adaptors/apps-sdk-adaptor.d.ts +0 -14
  444. package/dist/web/bridges/adaptors/apps-sdk-adaptor.js +0 -39
  445. package/dist/web/bridges/adaptors/apps-sdk-adaptor.js.map +0 -1
  446. package/dist/web/bridges/adaptors/mcp-app-adaptor.d.ts +0 -19
  447. package/dist/web/bridges/adaptors/mcp-app-adaptor.js +0 -145
  448. package/dist/web/bridges/adaptors/mcp-app-adaptor.js.map +0 -1
  449. package/dist/web/bridges/apps-sdk-bridge.d.ts +0 -10
  450. package/dist/web/bridges/apps-sdk-bridge.js.map +0 -1
  451. package/dist/web/bridges/hooks/get-adaptor.d.ts +0 -2
  452. package/dist/web/bridges/hooks/get-adaptor.js +0 -8
  453. package/dist/web/bridges/hooks/get-adaptor.js.map +0 -1
  454. package/dist/web/bridges/hooks/use-apps-sdk-bridge.d.ts +0 -2
  455. package/dist/web/bridges/hooks/use-apps-sdk-bridge.js +0 -7
  456. package/dist/web/bridges/hooks/use-apps-sdk-bridge.js.map +0 -1
  457. package/dist/web/bridges/hooks/use-bridge.d.ts +0 -2
  458. package/dist/web/bridges/hooks/use-bridge.js +0 -8
  459. package/dist/web/bridges/hooks/use-bridge.js.map +0 -1
  460. package/dist/web/bridges/hooks/use-mcp-app-bridge.d.ts +0 -5
  461. package/dist/web/bridges/hooks/use-mcp-app-bridge.js +0 -7
  462. package/dist/web/bridges/hooks/use-mcp-app-bridge.js.map +0 -1
  463. package/dist/web/bridges/hooks/use-mcp-app-bridge.test.js +0 -57
  464. package/dist/web/bridges/hooks/use-mcp-app-bridge.test.js.map +0 -1
  465. package/dist/web/bridges/mcp-app-bridge.d.ts +0 -49
  466. package/dist/web/bridges/mcp-app-bridge.js +0 -256
  467. package/dist/web/bridges/mcp-app-bridge.js.map +0 -1
  468. package/dist/web/hooks/use-openai-global.d.ts +0 -3
  469. package/dist/web/hooks/use-openai-global.js +0 -6
  470. package/dist/web/hooks/use-openai-global.js.map +0 -1
  471. package/dist/web/hooks/use-widget-state.d.ts +0 -4
  472. package/dist/web/hooks/use-widget-state.js +0 -32
  473. package/dist/web/hooks/use-widget-state.js.map +0 -1
  474. package/dist/web/hooks/use-widget-state.test.js +0 -61
  475. package/dist/web/hooks/use-widget-state.test.js.map +0 -1
  476. package/dist/web/mount-widget.d.ts +0 -1
  477. package/dist/web/mount-widget.js +0 -19
  478. package/dist/web/mount-widget.js.map +0 -1
  479. /package/dist/{test/widget.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  480. /package/dist/{web/bridges/hooks/use-mcp-app-bridge.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  481. /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gCAAgC,CAAC;AACrD,OAAO,EAEL,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAczB,SAAS,cAAc,CACrB,MAAoB,EACpB,IAAU,EACV,eAAkD;IAElD,IAAI,WAA0B,CAAC;IAC/B,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;QACjC,WAAW,EAAE,GAAG,EAAE;YAChB,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAChC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CACvB,CAAC;YACvB,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;YAC1C,IAAI,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,CAAC;gBAC/D,OAAO,WAAW,CAAC;YACrB,CAAC;YACD,WAAW,GAAG,QAAQ,CAAC;YACvB,OAAO,QAAQ,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,qGAAqG;AACrG,MAAM,OAAO,YAAY;IACf,MAAM,CAAC,QAAQ,GAAwB,IAAI,CAAC;IAC7C,OAAO,GAAkB;QAC9B,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE,IAAI;KACjB,CAAC;IACM,SAAS,GAAG,IAAI,GAAG,EAAqC,CAAC;IACzD,GAAG,CAAM;IACT,cAAc,CAAgB;IAEtC,YAAY,OAAoC;QAC9C,IAAI,CAAC,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAEtE,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;YAC9D,KAAK,EAAE,EAAE;SACV,CAAC,CAAC,CAAC;QAEJ,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,CAAC,MAAM,EAAE,EAAE;YAChC,IAAI,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,kBAAkB,GAAG,CAAC,MAAM,EAAE,EAAE;YACvC,IAAI,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,MAAM,EAAE,EAAE;YACjC,IAAI,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7C,CAAC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,eAAe,GAAG,CAAC,MAAM,EAAE,EAAE;YACpC,IAAI,CAAC,aAAa,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,oBAAoB,GAAG,CAAC,MAAM,EAAE,EAAE;YACzC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC,CAAC;QAEF,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,OAAO;QACnB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YAC9C,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,MAAM;QACjB,MAAM,IAAI,CAAC,cAAc,CAAC;QAC1B,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC;IAEM,gBAAgB,CACrB,MAAsB,EACtB,OAA2B;QAE3B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW;YACpC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;YAC9B,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAEjB,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CACtC,MAAM,CAAC,IAAI,EACX;YACE,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS;gBAClC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE;gBACrC,CAAC,CAAC,EAAE,CAAC;YACP,WAAW;YACX,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnE,EACD,OAAO,CACR,CAAC;QAEF,OAAO,GAAG,EAAE;YACV,UAAU,CAAC,MAAM,EAAE,CAAC;QACtB,CAAC,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,WAAW,CACvB,OAA8C;QAE9C,IAAI,YAAY,CAAC,QAAQ,IAAI,OAAO,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CACV,oEAAoE,CACrE,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC3B,MAAM,cAAc,GAAG;gBACrB,OAAO,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE;aACrD,CAAC;YACF,YAAY,CAAC,QAAQ,GAAG,IAAI,YAAY,CAAC;gBACvC,GAAG,cAAc;gBACjB,GAAG,OAAO;aACX,CAAC,CAAC;QACL,CAAC;QACD,OAAO,YAAY,CAAC,QAAQ,CAAC;IAC/B,CAAC;IAIM,SAAS,CACd,SAAyD;QAEzD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAChE,OAAO,CAAC,QAAoB,EAAE,EAAE;YAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,SAAS,CAAC,GAAG,CAChB,GAAG,EACH,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,CACxD,CAAC;YACJ,CAAC;YACD,OAAO,GAAG,EAAE;gBACV,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;IAEM,WAAW,CAAgC,GAAM;QACtD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAEM,mBAAmB;QAWxB,OAAO;YACL,KAAK,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,OAAO,CAAC;YACvE,MAAM,EAAE,cAAc,CACpB,IAAI,EACJ,CAAC,QAAQ,CAAC,EACV,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,IAAI,OAAO,CAClC;YACD,QAAQ,EAAE,cAAc,CACtB,IAAI,EACJ,CAAC,gBAAgB,CAAC,EAClB,CAAC,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC;gBACvB,MAAM,EAAE,cAAc,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;aACnE,CAAC,CACH;YACD,WAAW,EAAE,cAAc,CACzB,IAAI,EACJ,CAAC,aAAa,CAAC,EACf,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,WAAW,IAAI,QAAQ,CAC7C;YACD,SAAS,EAAE,cAAc,CACvB,IAAI,EACJ,CAAC,qBAAqB,CAAC,EACvB,CAAC,EAAE,mBAAmB,EAAE,EAAE,EAAE;gBAC1B,IAAI,mBAAmB,IAAI,WAAW,IAAI,mBAAmB,EAAE,CAAC;oBAC9D,OAAO,mBAAmB,CAAC,SAAS,CAAC;gBACvC,CAAC;gBACD,OAAO,SAAS,CAAC;YACnB,CAAC,CACF;YACD,SAAS,EAAE,cAAc,CACvB,IAAI,EACJ,CAAC,UAAU,EAAE,oBAAoB,CAAC,EAClC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,EAAE,EAAE,CAAC,CAAC;gBACrC,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,SAAS,CAAC;iBAC/D;gBACD,YAAY,EAAE;oBACZ,KAAK,EAAE,IAAI;oBACX,KAAK,EAAE,IAAI;oBACX,GAAG,kBAAkB;iBACtB;aACF,CAAC,CACH;YACD,SAAS,EAAE,cAAc,CACvB,IAAI,EACJ,CAAC,WAAW,CAAC,EACb,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,SAAS,IAAI,IAAI,CACrC;YACD,UAAU,EAAE,cAAc,CACxB,IAAI,EACJ,CAAC,YAAY,CAAC,EACd,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,iBAAiB,IAAI,IAAI,CAC1D;YACD,oBAAoB,EAAE,cAAc,CAClC,IAAI,EACJ,CAAC,YAAY,CAAC,EACd,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,EAAE,KAAK,IAAI,IAAI,CAC9C;SACF,CAAC;IACJ,CAAC;IAEM,OAAO,GAAG,GAAG,EAAE;QACpB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC,CAAC;IAEK,MAAM,CAAC,aAAa;QACzB,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC1B,YAAY,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAChC,YAAY,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC/B,CAAC;IACH,CAAC;IAEO,IAAI,CAAC,GAAqB;QAChC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC5C,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,OAA+B;QACnD,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;QAC/C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC","sourcesContent":["import { App } from \"@modelcontextprotocol/ext-apps\";\nimport {\n type Implementation,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { dequal } from \"dequal/lite\";\nimport * as z from \"zod\";\nimport type {\n AnyViewToolHandler,\n Bridge,\n HostContextStore,\n Subscribe,\n ViewToolConfig,\n} from \"../types.js\";\nimport type { McpAppContext, McpAppContextKey } from \"./types.js\";\n\ntype PickContext<K extends readonly McpAppContextKey[]> = {\n [P in K[number]]: McpAppContext[P];\n};\n\nfunction createMcpStore<const Keys extends readonly McpAppContextKey[], R>(\n bridge: McpAppBridge,\n keys: Keys,\n computeSnapshot: (context: PickContext<Keys>) => R,\n) {\n let cachedValue: R | undefined;\n return {\n subscribe: bridge.subscribe(keys),\n getSnapshot: () => {\n const context = Object.fromEntries(\n keys.map((k) => [k, bridge.getSnapshot(k)]),\n ) as PickContext<Keys>;\n const newValue = computeSnapshot(context);\n if (cachedValue !== undefined && dequal(cachedValue, newValue)) {\n return cachedValue;\n }\n cachedValue = newValue;\n return newValue;\n },\n };\n}\n\n/** @internal Singleton bridge over the `ext-apps` JSON-RPC App connection. Used by `HostAdaptor`. */\nexport class McpAppBridge implements Bridge<McpAppContext> {\n private static instance: McpAppBridge | null = null;\n public context: McpAppContext = {\n toolInput: null,\n toolCancelled: null,\n toolResult: null,\n };\n private listeners = new Map<McpAppContextKey, Set<() => void>>();\n private app: App;\n private connectPromise: Promise<void>;\n\n constructor(options: { appInfo: Implementation }) {\n this.app = new App(options.appInfo, { tools: { listChanged: true } });\n\n this.app.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [],\n }));\n\n this.app.ontoolinput = (params) => {\n this.updateContext({ toolInput: params.arguments ?? {} });\n };\n\n this.app.ontoolinputpartial = (params) => {\n this.updateContext({ toolInput: params.arguments ?? {} });\n };\n\n this.app.ontoolresult = (params) => {\n this.updateContext({ toolResult: params });\n };\n\n this.app.ontoolcancelled = (params) => {\n this.updateContext({ toolCancelled: params });\n };\n\n this.app.onhostcontextchanged = (params) => {\n this.updateContext(params);\n };\n\n this.connectPromise = this.connect();\n }\n\n private async connect() {\n try {\n await this.app.connect();\n const hostContext = this.app.getHostContext();\n if (hostContext) {\n this.updateContext(hostContext);\n }\n } catch (err) {\n console.error(err);\n }\n }\n\n public async getApp(): Promise<App> {\n await this.connectPromise;\n return this.app;\n }\n\n public registerViewTool(\n config: ViewToolConfig,\n handler: AnyViewToolHandler,\n ): () => void {\n const inputSchema = config.inputSchema\n ? z.object(config.inputSchema)\n : z.object({});\n\n const registered = this.app.registerTool(\n config.name,\n {\n ...(config.title !== undefined ? { title: config.title } : {}),\n ...(config.description !== undefined\n ? { description: config.description }\n : {}),\n inputSchema,\n ...(config.annotations ? { annotations: config.annotations } : {}),\n },\n handler,\n );\n\n return () => {\n registered.remove();\n };\n }\n\n public static getInstance(\n options?: Partial<{ appInfo: Implementation }>,\n ): McpAppBridge {\n if (McpAppBridge.instance && options) {\n console.warn(\n \"McpAppBridge.getInstance: options ignored, instance already exists\",\n );\n }\n if (!McpAppBridge.instance) {\n const defaultOptions = {\n appInfo: { name: \"skybridge-app\", version: \"0.0.1\" },\n };\n McpAppBridge.instance = new McpAppBridge({\n ...defaultOptions,\n ...options,\n });\n }\n return McpAppBridge.instance;\n }\n\n public subscribe(key: McpAppContextKey): Subscribe;\n public subscribe(keys: readonly McpAppContextKey[]): Subscribe;\n public subscribe(\n keyOrKeys: McpAppContextKey | readonly McpAppContextKey[],\n ): Subscribe {\n const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];\n return (onChange: () => void) => {\n for (const key of keys) {\n this.listeners.set(\n key,\n new Set([...(this.listeners.get(key) || []), onChange]),\n );\n }\n return () => {\n for (const key of keys) {\n this.listeners.get(key)?.delete(onChange);\n }\n };\n };\n }\n\n public getSnapshot<K extends keyof McpAppContext>(key: K): McpAppContext[K] {\n return this.context[key];\n }\n\n public createContextStores(): {\n theme: HostContextStore<\"theme\">;\n locale: HostContextStore<\"locale\">;\n safeArea: HostContextStore<\"safeArea\">;\n displayMode: HostContextStore<\"displayMode\">;\n maxHeight: HostContextStore<\"maxHeight\">;\n userAgent: HostContextStore<\"userAgent\">;\n toolInput: HostContextStore<\"toolInput\">;\n toolOutput: HostContextStore<\"toolOutput\">;\n toolResponseMetadata: HostContextStore<\"toolResponseMetadata\">;\n } {\n return {\n theme: createMcpStore(this, [\"theme\"], ({ theme }) => theme ?? \"light\"),\n locale: createMcpStore(\n this,\n [\"locale\"],\n ({ locale }) => locale ?? \"en-US\",\n ),\n safeArea: createMcpStore(\n this,\n [\"safeAreaInsets\"],\n ({ safeAreaInsets }) => ({\n insets: safeAreaInsets ?? { top: 0, right: 0, bottom: 0, left: 0 },\n }),\n ),\n displayMode: createMcpStore(\n this,\n [\"displayMode\"],\n ({ displayMode }) => displayMode ?? \"inline\",\n ),\n maxHeight: createMcpStore(\n this,\n [\"containerDimensions\"],\n ({ containerDimensions }) => {\n if (containerDimensions && \"maxHeight\" in containerDimensions) {\n return containerDimensions.maxHeight;\n }\n return undefined;\n },\n ),\n userAgent: createMcpStore(\n this,\n [\"platform\", \"deviceCapabilities\"],\n ({ platform, deviceCapabilities }) => ({\n device: {\n type: platform === \"web\" ? \"desktop\" : (platform ?? \"unknown\"),\n },\n capabilities: {\n hover: true,\n touch: true,\n ...deviceCapabilities,\n },\n }),\n ),\n toolInput: createMcpStore(\n this,\n [\"toolInput\"],\n ({ toolInput }) => toolInput ?? null,\n ),\n toolOutput: createMcpStore(\n this,\n [\"toolResult\"],\n ({ toolResult }) => toolResult?.structuredContent ?? null,\n ),\n toolResponseMetadata: createMcpStore(\n this,\n [\"toolResult\"],\n ({ toolResult }) => toolResult?._meta ?? null,\n ),\n };\n }\n\n public cleanup = () => {\n this.listeners.clear();\n };\n\n public static resetInstance(): void {\n if (McpAppBridge.instance) {\n McpAppBridge.instance.cleanup();\n McpAppBridge.instance = null;\n }\n }\n\n private emit(key: McpAppContextKey) {\n this.listeners.get(key)?.forEach((listener) => {\n listener();\n });\n }\n\n private updateContext(context: Partial<McpAppContext>) {\n this.context = { ...this.context, ...context };\n for (const key of Object.keys(context)) {\n this.emit(key);\n }\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { McpAppBridge } from "./bridge.js";
3
+ describe("McpAppBridge.getInstance", () => {
4
+ beforeEach(() => {
5
+ McpAppBridge.resetInstance();
6
+ vi.stubGlobal("parent", { postMessage: vi.fn() });
7
+ });
8
+ afterEach(() => {
9
+ vi.unstubAllGlobals();
10
+ McpAppBridge.resetInstance();
11
+ });
12
+ it("instantiates regardless of injected hostType", () => {
13
+ vi.stubGlobal("skybridge", { hostType: "apps-sdk" });
14
+ expect(() => McpAppBridge.getInstance()).not.toThrow();
15
+ });
16
+ });
17
+ //# sourceMappingURL=bridge.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.test.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/bridge.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,UAAU,CAAC,GAAG,EAAE;QACd,YAAY,CAAC,aAAa,EAAE,CAAC;QAC7B,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IACH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,YAAY,CAAC,aAAa,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { McpAppBridge } from \"./bridge.js\";\n\ndescribe(\"McpAppBridge.getInstance\", () => {\n beforeEach(() => {\n McpAppBridge.resetInstance();\n vi.stubGlobal(\"parent\", { postMessage: vi.fn() });\n });\n afterEach(() => {\n vi.unstubAllGlobals();\n McpAppBridge.resetInstance();\n });\n\n it(\"instantiates regardless of injected hostType\", () => {\n vi.stubGlobal(\"skybridge\", { hostType: \"apps-sdk\" });\n expect(() => McpAppBridge.getInstance()).not.toThrow();\n });\n});\n"]}
@@ -0,0 +1,3 @@
1
+ export { McpAppBridge } from "./bridge.js";
2
+ export type { McpAppContext, McpAppContextKey, McpToolState, } from "./types.js";
3
+ export { useMcpAppContext } from "./use-mcp-app-context.js";
@@ -0,0 +1,3 @@
1
+ export { McpAppBridge } from "./bridge.js";
2
+ export { useMcpAppContext } from "./use-mcp-app-context.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC","sourcesContent":["export { McpAppBridge } from \"./bridge.js\";\nexport type {\n McpAppContext,\n McpAppContextKey,\n McpToolState,\n} from \"./types.js\";\nexport { useMcpAppContext } from \"./use-mcp-app-context.js\";\n"]}
@@ -0,0 +1,8 @@
1
+ import type { McpUiHostContext, McpUiToolCancelledNotification, McpUiToolInputNotification, McpUiToolResultNotification } from "@modelcontextprotocol/ext-apps";
2
+ export type McpToolState = {
3
+ toolInput: NonNullable<McpUiToolInputNotification["params"]["arguments"]> | null;
4
+ toolResult: McpUiToolResultNotification["params"] | null;
5
+ toolCancelled: McpUiToolCancelledNotification["params"] | null;
6
+ };
7
+ export type McpAppContext = McpUiHostContext & McpToolState;
8
+ export type McpAppContextKey = keyof McpAppContext;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n McpUiHostContext,\n McpUiToolCancelledNotification,\n McpUiToolInputNotification,\n McpUiToolResultNotification,\n} from \"@modelcontextprotocol/ext-apps\";\n\nexport type McpToolState = {\n toolInput: NonNullable<\n McpUiToolInputNotification[\"params\"][\"arguments\"]\n > | null;\n toolResult: McpUiToolResultNotification[\"params\"] | null;\n toolCancelled: McpUiToolCancelledNotification[\"params\"] | null;\n};\n\nexport type McpAppContext = McpUiHostContext & McpToolState;\n\nexport type McpAppContextKey = keyof McpAppContext;\n"]}
@@ -0,0 +1,19 @@
1
+ import type { Implementation } from "@modelcontextprotocol/sdk/types.js";
2
+ import type { McpAppContext } from "./types.js";
3
+ type McpAppInitializationOptions = {
4
+ appInfo: Implementation;
5
+ };
6
+ /**
7
+ * Read a single key from the raw MCP Apps (`ext-apps`) bridge context.
8
+ *
9
+ * Advanced escape hatch — prefer the cross-host hooks (`useToolInfo`,
10
+ * `useLayout`, etc.) which work in both MCP Apps and Apps SDK. Reach for this
11
+ * when you need protocol-level fields not surfaced by the public hooks.
12
+ *
13
+ * `options.appInfo` is honored only on the first call that creates the
14
+ * underlying bridge; subsequent calls reuse the singleton.
15
+ *
16
+ * @see https://docs.skybridge.tech/api-reference/use-mcp-app-context
17
+ */
18
+ export declare function useMcpAppContext<K extends keyof McpAppContext>(key: K, options?: Partial<McpAppInitializationOptions>): McpAppContext[K];
19
+ export {};
@@ -0,0 +1,19 @@
1
+ import { useSyncExternalStore } from "react";
2
+ import { McpAppBridge } from "./bridge.js";
3
+ /**
4
+ * Read a single key from the raw MCP Apps (`ext-apps`) bridge context.
5
+ *
6
+ * Advanced escape hatch — prefer the cross-host hooks (`useToolInfo`,
7
+ * `useLayout`, etc.) which work in both MCP Apps and Apps SDK. Reach for this
8
+ * when you need protocol-level fields not surfaced by the public hooks.
9
+ *
10
+ * `options.appInfo` is honored only on the first call that creates the
11
+ * underlying bridge; subsequent calls reuse the singleton.
12
+ *
13
+ * @see https://docs.skybridge.tech/api-reference/use-mcp-app-context
14
+ */
15
+ export function useMcpAppContext(key, options) {
16
+ const bridge = McpAppBridge.getInstance(options);
17
+ return useSyncExternalStore(bridge.subscribe(key), () => bridge.getSnapshot(key));
18
+ }
19
+ //# sourceMappingURL=use-mcp-app-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-mcp-app-context.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/use-mcp-app-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAC9B,GAAM,EACN,OAA8C;IAE9C,MAAM,MAAM,GAAG,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CACtD,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CACxB,CAAC;AACJ,CAAC","sourcesContent":["import type { Implementation } from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { useSyncExternalStore } from \"react\";\nimport { McpAppBridge } from \"./bridge.js\";\nimport type { McpAppContext } from \"./types.js\";\n\ntype McpAppInitializationOptions = {\n appInfo: Implementation;\n};\n\n/**\n * Read a single key from the raw MCP Apps (`ext-apps`) bridge context.\n *\n * Advanced escape hatch — prefer the cross-host hooks (`useToolInfo`,\n * `useLayout`, etc.) which work in both MCP Apps and Apps SDK. Reach for this\n * when you need protocol-level fields not surfaced by the public hooks.\n *\n * `options.appInfo` is honored only on the first call that creates the\n * underlying bridge; subsequent calls reuse the singleton.\n *\n * @see https://docs.skybridge.tech/api-reference/use-mcp-app-context\n */\nexport function useMcpAppContext<K extends keyof McpAppContext>(\n key: K,\n options?: Partial<McpAppInitializationOptions>,\n): McpAppContext[K] {\n const bridge = McpAppBridge.getInstance(options);\n return useSyncExternalStore(bridge.subscribe(key), () =>\n bridge.getSnapshot(key),\n );\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import { renderHook, waitFor } from "@testing-library/react";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { getMcpAppHostPostMessageMock, MockResizeObserver, } from "../../hooks/test/utils.js";
4
+ import { McpAppBridge } from "./bridge.js";
5
+ import { useMcpAppContext } from "./use-mcp-app-context.js";
6
+ describe("useMcpAppContext", () => {
7
+ beforeEach(async () => {
8
+ vi.stubGlobal("skybridge", { hostType: "mcp-app" });
9
+ vi.stubGlobal("ResizeObserver", MockResizeObserver);
10
+ McpAppBridge.resetInstance();
11
+ });
12
+ afterEach(() => {
13
+ vi.unstubAllGlobals();
14
+ vi.clearAllMocks();
15
+ });
16
+ it("should return the theme value from host context and update on notification", async () => {
17
+ vi.stubGlobal("parent", {
18
+ postMessage: getMcpAppHostPostMessageMock({ theme: "light" }),
19
+ });
20
+ const { result } = renderHook(() => useMcpAppContext("theme"));
21
+ await waitFor(() => {
22
+ expect(result.current).toBe("light");
23
+ });
24
+ });
25
+ });
26
+ //# sourceMappingURL=use-mcp-app-context.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-mcp-app-context.test.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/use-mcp-app-context.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QACpD,EAAE,CAAC,UAAU,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;QACpD,YAAY,CAAC,aAAa,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC1F,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;YACtB,WAAW,EAAE,4BAA4B,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;SAC9D,CAAC,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;QAE/D,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { renderHook, waitFor } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport {\n getMcpAppHostPostMessageMock,\n MockResizeObserver,\n} from \"../../hooks/test/utils.js\";\nimport { McpAppBridge } from \"./bridge.js\";\nimport { useMcpAppContext } from \"./use-mcp-app-context.js\";\n\ndescribe(\"useMcpAppContext\", () => {\n beforeEach(async () => {\n vi.stubGlobal(\"skybridge\", { hostType: \"mcp-app\" });\n vi.stubGlobal(\"ResizeObserver\", MockResizeObserver);\n McpAppBridge.resetInstance();\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.clearAllMocks();\n });\n\n it(\"should return the theme value from host context and update on notification\", async () => {\n vi.stubGlobal(\"parent\", {\n postMessage: getMcpAppHostPostMessageMock({ theme: \"light\" }),\n });\n const { result } = renderHook(() => useMcpAppContext(\"theme\"));\n\n await waitFor(() => {\n expect(result.current).toBe(\"light\");\n });\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,143 @@
1
+ import { waitFor } from "@testing-library/react";
2
+ import { act } from "react";
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
+ import * as z from "zod";
5
+ import { MockResizeObserver } from "../../hooks/test/utils.js";
6
+ import { HostAdaptor } from "../adaptor.js";
7
+ import { McpAppBridge } from "./bridge.js";
8
+ const outgoing = [];
9
+ /**
10
+ * Stand-in MCP Apps host: replies to `ui/initialize` and records every message
11
+ * the app posts so tests can assert on responses and notifications.
12
+ */
13
+ function installHostMock() {
14
+ outgoing.length = 0;
15
+ const postMessage = vi.fn((message) => {
16
+ outgoing.push(message);
17
+ if (message.method === "ui/initialize" && message.id !== undefined) {
18
+ act(() => {
19
+ window.dispatchEvent(new MessageEvent("message", {
20
+ source: window.parent,
21
+ data: {
22
+ jsonrpc: "2.0",
23
+ id: message.id,
24
+ result: {
25
+ protocolVersion: "2025-06-18",
26
+ hostInfo: { name: "test-host", version: "1.0.0" },
27
+ hostCapabilities: {},
28
+ hostContext: {},
29
+ },
30
+ },
31
+ }));
32
+ });
33
+ }
34
+ });
35
+ vi.stubGlobal("parent", { postMessage });
36
+ }
37
+ let nextId = 1000;
38
+ /** Send a host → app JSON-RPC request and resolve with the full response (result or error). */
39
+ async function callHost(method, params = {}) {
40
+ const id = ++nextId;
41
+ act(() => {
42
+ window.dispatchEvent(new MessageEvent("message", {
43
+ source: window.parent,
44
+ data: { jsonrpc: "2.0", id, method, params },
45
+ }));
46
+ });
47
+ await waitFor(() => {
48
+ expect(outgoing.some((m) => m.id === id)).toBe(true);
49
+ });
50
+ return outgoing.find((m) => m.id === id);
51
+ }
52
+ describe("McpApp view tools", () => {
53
+ beforeEach(() => {
54
+ vi.stubGlobal("skybridge", { hostType: "mcp-app" });
55
+ vi.stubGlobal("ResizeObserver", MockResizeObserver);
56
+ McpAppBridge.resetInstance();
57
+ installHostMock();
58
+ });
59
+ afterEach(() => {
60
+ vi.unstubAllGlobals();
61
+ vi.clearAllMocks();
62
+ });
63
+ it("advertises the tools capability during ui/initialize", async () => {
64
+ await McpAppBridge.getInstance().getApp();
65
+ const init = outgoing.find((m) => m.method === "ui/initialize");
66
+ expect(init?.params?.appCapabilities).toMatchObject({
67
+ tools: { listChanged: true },
68
+ });
69
+ });
70
+ it("lists a registered view tool with its input schema", async () => {
71
+ const adaptor = new HostAdaptor();
72
+ await McpAppBridge.getInstance().getApp();
73
+ adaptor.registerViewTool({
74
+ name: "chess_make_move",
75
+ description: "Play a move",
76
+ inputSchema: { san: z.string() },
77
+ annotations: { readOnlyHint: false },
78
+ }, () => ({ content: [{ type: "text", text: "ok" }] }));
79
+ const response = await callHost("tools/list");
80
+ const tools = response?.result?.tools;
81
+ expect(tools).toHaveLength(1);
82
+ const [tool] = tools;
83
+ expect(tool?.name).toBe("chess_make_move");
84
+ expect(tool?.description).toBe("Play a move");
85
+ expect(tool?.inputSchema.properties).toHaveProperty("san");
86
+ expect(tool?.annotations?.readOnlyHint).toBe(false);
87
+ });
88
+ it("invokes the handler with validated args and returns its result", async () => {
89
+ const adaptor = new HostAdaptor();
90
+ await McpAppBridge.getInstance().getApp();
91
+ const handler = vi.fn(({ san }) => ({
92
+ content: [{ type: "text", text: `played ${san}` }],
93
+ structuredContent: { lastMove: san },
94
+ }));
95
+ adaptor.registerViewTool({ name: "chess_make_move", inputSchema: { san: z.string() } }, handler);
96
+ const response = await callHost("tools/call", {
97
+ name: "chess_make_move",
98
+ arguments: { san: "e4" },
99
+ });
100
+ const result = response?.result;
101
+ // ext-apps invokes the callback as `(args, extra)`; assert on the args only.
102
+ expect(handler.mock.calls[0]?.[0]).toEqual({ san: "e4" });
103
+ expect(result?.structuredContent).toEqual({ lastMove: "e4" });
104
+ expect(result?.isError).toBeFalsy();
105
+ expect(result?.content).toEqual([{ type: "text", text: "played e4" }]);
106
+ });
107
+ it("rejects the call without invoking the handler when args are invalid", async () => {
108
+ const adaptor = new HostAdaptor();
109
+ await McpAppBridge.getInstance().getApp();
110
+ const handler = vi.fn(() => ({ content: [] }));
111
+ adaptor.registerViewTool({ name: "chess_make_move", inputSchema: { san: z.string() } }, handler);
112
+ // ext-apps validates input against the schema and rejects with a JSON-RPC
113
+ // error before the handler runs.
114
+ const response = await callHost("tools/call", {
115
+ name: "chess_make_move",
116
+ arguments: { san: 42 },
117
+ });
118
+ expect(handler).not.toHaveBeenCalled();
119
+ expect(response?.error).toBeDefined();
120
+ });
121
+ it("rejects a call to an unknown tool", async () => {
122
+ await McpAppBridge.getInstance().getApp();
123
+ const response = await callHost("tools/call", {
124
+ name: "nope",
125
+ arguments: {},
126
+ });
127
+ expect(response?.error).toBeDefined();
128
+ });
129
+ it("removes the tool and notifies the host when unregistered", async () => {
130
+ const adaptor = new HostAdaptor();
131
+ await McpAppBridge.getInstance().getApp();
132
+ const unregister = adaptor.registerViewTool({ name: "chess_reset" }, () => ({ content: [{ type: "text", text: "reset" }] }));
133
+ await waitFor(() => {
134
+ expect(outgoing.some((m) => m.method === "notifications/tools/list_changed")).toBe(true);
135
+ });
136
+ let listed = await callHost("tools/list");
137
+ expect(listed?.result?.tools).toHaveLength(1);
138
+ unregister();
139
+ listed = await callHost("tools/list");
140
+ expect(listed?.result?.tools).toHaveLength(0);
141
+ });
142
+ });
143
+ //# sourceMappingURL=view-tools.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-tools.test.js","sourceRoot":"","sources":["../../../../src/web/bridges/mcp-app/view-tools.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { waitFor } from \"@testing-library/react\";\nimport { act } from \"react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport * as z from \"zod\";\nimport { MockResizeObserver } from \"../../hooks/test/utils.js\";\nimport { HostAdaptor } from \"../adaptor.js\";\nimport { McpAppBridge } from \"./bridge.js\";\n\ntype JsonRpcMessage = {\n jsonrpc: \"2.0\";\n id?: number;\n method?: string;\n params?: Record<string, unknown>;\n result?: Record<string, unknown>;\n error?: { message: string };\n};\n\nconst outgoing: JsonRpcMessage[] = [];\n\n/**\n * Stand-in MCP Apps host: replies to `ui/initialize` and records every message\n * the app posts so tests can assert on responses and notifications.\n */\nfunction installHostMock() {\n outgoing.length = 0;\n const postMessage = vi.fn((message: JsonRpcMessage) => {\n outgoing.push(message);\n if (message.method === \"ui/initialize\" && message.id !== undefined) {\n act(() => {\n window.dispatchEvent(\n new MessageEvent(\"message\", {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n id: message.id,\n result: {\n protocolVersion: \"2025-06-18\",\n hostInfo: { name: \"test-host\", version: \"1.0.0\" },\n hostCapabilities: {},\n hostContext: {},\n },\n },\n }),\n );\n });\n }\n });\n vi.stubGlobal(\"parent\", { postMessage });\n}\n\nlet nextId = 1000;\n\n/** Send a host → app JSON-RPC request and resolve with the full response (result or error). */\nasync function callHost(method: string, params: Record<string, unknown> = {}) {\n const id = ++nextId;\n act(() => {\n window.dispatchEvent(\n new MessageEvent(\"message\", {\n source: window.parent,\n data: { jsonrpc: \"2.0\", id, method, params },\n }),\n );\n });\n await waitFor(() => {\n expect(outgoing.some((m) => m.id === id)).toBe(true);\n });\n return outgoing.find((m) => m.id === id);\n}\n\ndescribe(\"McpApp view tools\", () => {\n beforeEach(() => {\n vi.stubGlobal(\"skybridge\", { hostType: \"mcp-app\" });\n vi.stubGlobal(\"ResizeObserver\", MockResizeObserver);\n McpAppBridge.resetInstance();\n installHostMock();\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.clearAllMocks();\n });\n\n it(\"advertises the tools capability during ui/initialize\", async () => {\n await McpAppBridge.getInstance().getApp();\n const init = outgoing.find((m) => m.method === \"ui/initialize\");\n expect(init?.params?.appCapabilities).toMatchObject({\n tools: { listChanged: true },\n });\n });\n\n it(\"lists a registered view tool with its input schema\", async () => {\n const adaptor = new HostAdaptor();\n await McpAppBridge.getInstance().getApp();\n\n adaptor.registerViewTool(\n {\n name: \"chess_make_move\",\n description: \"Play a move\",\n inputSchema: { san: z.string() },\n annotations: { readOnlyHint: false },\n },\n () => ({ content: [{ type: \"text\", text: \"ok\" }] }),\n );\n\n const response = await callHost(\"tools/list\");\n const tools = response?.result?.tools as Array<{\n name: string;\n description?: string;\n inputSchema: { properties?: Record<string, unknown> };\n annotations?: { readOnlyHint?: boolean };\n }>;\n expect(tools).toHaveLength(1);\n const [tool] = tools;\n expect(tool?.name).toBe(\"chess_make_move\");\n expect(tool?.description).toBe(\"Play a move\");\n expect(tool?.inputSchema.properties).toHaveProperty(\"san\");\n expect(tool?.annotations?.readOnlyHint).toBe(false);\n });\n\n it(\"invokes the handler with validated args and returns its result\", async () => {\n const adaptor = new HostAdaptor();\n await McpAppBridge.getInstance().getApp();\n\n const handler = vi.fn(({ san }: { san: string }) => ({\n content: [{ type: \"text\" as const, text: `played ${san}` }],\n structuredContent: { lastMove: san },\n }));\n\n adaptor.registerViewTool(\n { name: \"chess_make_move\", inputSchema: { san: z.string() } },\n handler as never,\n );\n\n const response = await callHost(\"tools/call\", {\n name: \"chess_make_move\",\n arguments: { san: \"e4\" },\n });\n const result = response?.result;\n\n // ext-apps invokes the callback as `(args, extra)`; assert on the args only.\n expect(handler.mock.calls[0]?.[0]).toEqual({ san: \"e4\" });\n expect(result?.structuredContent).toEqual({ lastMove: \"e4\" });\n expect(result?.isError).toBeFalsy();\n expect(result?.content).toEqual([{ type: \"text\", text: \"played e4\" }]);\n });\n\n it(\"rejects the call without invoking the handler when args are invalid\", async () => {\n const adaptor = new HostAdaptor();\n await McpAppBridge.getInstance().getApp();\n\n const handler = vi.fn(() => ({ content: [] }));\n adaptor.registerViewTool(\n { name: \"chess_make_move\", inputSchema: { san: z.string() } },\n handler as never,\n );\n\n // ext-apps validates input against the schema and rejects with a JSON-RPC\n // error before the handler runs.\n const response = await callHost(\"tools/call\", {\n name: \"chess_make_move\",\n arguments: { san: 42 },\n });\n\n expect(handler).not.toHaveBeenCalled();\n expect(response?.error).toBeDefined();\n });\n\n it(\"rejects a call to an unknown tool\", async () => {\n await McpAppBridge.getInstance().getApp();\n const response = await callHost(\"tools/call\", {\n name: \"nope\",\n arguments: {},\n });\n expect(response?.error).toBeDefined();\n });\n\n it(\"removes the tool and notifies the host when unregistered\", async () => {\n const adaptor = new HostAdaptor();\n await McpAppBridge.getInstance().getApp();\n\n const unregister = adaptor.registerViewTool(\n { name: \"chess_reset\" },\n () => ({ content: [{ type: \"text\", text: \"reset\" }] }),\n );\n\n await waitFor(() => {\n expect(\n outgoing.some((m) => m.method === \"notifications/tools/list_changed\"),\n ).toBe(true);\n });\n\n let listed = await callHost(\"tools/list\");\n expect(listed?.result?.tools).toHaveLength(1);\n\n unregister();\n listed = await callHost(\"tools/list\");\n expect(listed?.result?.tools).toHaveLength(0);\n });\n});\n"]}
@@ -1,61 +1,214 @@
1
- import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
1
+ import type { SchemaOutput, ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js";
2
+ import type { CallToolResult, EmbeddedResource, ResourceLink, ToolAnnotations } from "@modelcontextprotocol/sdk/types.js";
2
3
  import type { useSyncExternalStore } from "react";
4
+ import type { ViewHostType } from "../../server/index.js";
5
+ /**
6
+ * Globals injected on `window.skybridge` by the host. Tells the view which
7
+ * runtime it's running under and where to reach the MCP server.
8
+ */
9
+ export type SkybridgeProperties = {
10
+ hostType: ViewHostType;
11
+ serverUrl: string;
12
+ };
13
+ declare global {
14
+ interface Window {
15
+ skybridge: SkybridgeProperties;
16
+ }
17
+ }
18
+ /** Arguments passed to a tool call. `null` for tools that take no input. */
3
19
  export type CallToolArgs = Record<string, unknown> | null;
20
+ /**
21
+ * Result of a tool call as surfaced to the view: MCP `content` blocks plus
22
+ * the typed `structuredContent` and optional `meta`. `isError` is set when
23
+ * the server marks the call as failed.
24
+ */
4
25
  export type CallToolResponse = {
5
26
  content: CallToolResult["content"];
6
27
  structuredContent: NonNullable<CallToolResult["structuredContent"]>;
7
28
  isError: NonNullable<CallToolResult["isError"]>;
8
- result: string;
9
- _meta?: CallToolResult["_meta"];
29
+ meta?: CallToolResult["_meta"];
10
30
  };
31
+ /**
32
+ * How the view is laid out by the host. `"modal"` is host-driven (see
33
+ * {@link useRequestModal}); `"pip"`, `"inline"`, and `"fullscreen"` are
34
+ * requestable via {@link useDisplayMode}.
35
+ */
11
36
  export type DisplayMode = "pip" | "inline" | "fullscreen" | "modal";
37
+ /** Subset of {@link DisplayMode} that the view can request from the host. */
38
+ export type RequestDisplayMode = Exclude<DisplayMode, "modal">;
39
+ /** Host theme. Mirror this in your view's styling for a native feel. */
40
+ export type Theme = "light" | "dark";
41
+ /** Coarse device class reported by the host. `"unknown"` when unavailable. */
12
42
  export type DeviceType = "mobile" | "tablet" | "desktop" | "unknown";
13
- export interface BridgeInterface {
14
- theme: "light" | "dark";
15
- locale: string;
16
- displayMode: DisplayMode;
17
- safeArea: {
18
- insets: {
19
- top: number;
20
- right: number;
21
- bottom: number;
22
- left: number;
23
- };
43
+ /** Pixel insets the view should keep clear of (notches, home indicators, etc.). */
44
+ export type SafeAreaInsets = {
45
+ top: number;
46
+ right: number;
47
+ bottom: number;
48
+ left: number;
49
+ };
50
+ /** Wrapper around {@link SafeAreaInsets} exposed via {@link useLayout}. */
51
+ export type SafeArea = {
52
+ insets: SafeAreaInsets;
53
+ };
54
+ /** Device and input-capability hints exposed via {@link useUser}. */
55
+ export type UserAgent = {
56
+ device: {
57
+ type: DeviceType;
24
58
  };
25
- maxHeight: number;
26
- userAgent: {
27
- device: {
28
- type: DeviceType;
29
- };
30
- capabilities: {
31
- hover: boolean;
32
- touch: boolean;
33
- };
59
+ capabilities: {
60
+ hover: boolean;
61
+ touch: boolean;
34
62
  };
63
+ };
64
+ /**
65
+ * Full snapshot of state the host exposes to the view. Most fields are
66
+ * better accessed through their dedicated hooks (`useLayout`, `useUser`,
67
+ * `useToolInfo`, etc.) — read this directly only for advanced cases.
68
+ */
69
+ export interface HostContext {
70
+ theme: Theme;
71
+ locale: string;
72
+ displayMode: DisplayMode;
73
+ safeArea: SafeArea;
74
+ maxHeight: number | undefined;
75
+ userAgent: UserAgent;
35
76
  toolInput: Record<string, unknown> | null;
36
77
  toolOutput: Record<string, unknown> | null;
37
78
  toolResponseMetadata: Record<string, unknown> | null;
38
- widgetState: Record<string, unknown> | null;
79
+ display: {
80
+ mode: DisplayMode;
81
+ params?: Record<string, unknown>;
82
+ };
83
+ viewState: Record<string, unknown> | null;
39
84
  }
85
+ /** @internal `useSyncExternalStore` subscribe signature, re-exported for bridge implementations. */
40
86
  export type Subscribe = Parameters<typeof useSyncExternalStore>[0];
87
+ /** @internal Bridge contract implemented by per-host bridge classes. */
41
88
  export interface Bridge<Context> {
42
89
  subscribe(key: keyof Context): Subscribe;
43
90
  subscribe(keys: readonly (keyof Context)[]): Subscribe;
44
91
  getSnapshot<K extends keyof Context>(key: K): Context[K] | undefined;
45
92
  }
46
- export type ExternalStore<K extends keyof BridgeInterface> = {
93
+ /** @internal Per-key snapshot store backing {@link useHostContext}. */
94
+ export type HostContextStore<K extends keyof HostContext> = {
47
95
  subscribe: Subscribe;
48
- getSnapshot: () => BridgeInterface[K];
96
+ getSnapshot: () => HostContext[K];
97
+ };
98
+ /** Persisted view state shape (a plain object). See {@link useViewState}. */
99
+ export type ViewState = Record<string, unknown>;
100
+ /** Updater form accepted when writing to view state. */
101
+ export type SetViewStateAction = ViewState | ((prevState: ViewState | null) => ViewState);
102
+ /** Reference to a host-managed file (returned by {@link useFiles}). */
103
+ export type FileMetadata = {
104
+ fileId: string;
105
+ fileName?: string;
106
+ mimeType?: string;
107
+ };
108
+ /** Options for {@link useFiles}'s `upload`. `library: true` saves into the user's library when supported. */
109
+ export type UploadFileOptions = {
110
+ library?: boolean;
49
111
  };
50
- export type WidgetState = Record<string, unknown>;
51
- export type SetWidgetStateAction = WidgetState | ((prevState: WidgetState | null) => WidgetState);
112
+ /** Options for {@link useRequestModal}'s `open` call. */
113
+ export type RequestModalOptions = {
114
+ title?: string;
115
+ params?: Record<string, unknown>;
116
+ template?: string;
117
+ anchor?: {
118
+ top?: number;
119
+ left?: number;
120
+ width?: number;
121
+ height?: number;
122
+ };
123
+ };
124
+ /**
125
+ * Options for {@link useOpenExternal}. Set `redirectUrl: false` to tell the
126
+ * host not to append its `?redirectUrl=…` tracking query parameter when
127
+ * opening allowlisted targets.
128
+ */
129
+ export type OpenExternalOptions = {
130
+ redirectUrl?: false;
131
+ };
132
+ /** Options for {@link useSendFollowUpMessage}. */
133
+ export type SendFollowUpMessageOptions = {
134
+ scrollToBottom?: boolean;
135
+ };
136
+ /** Options for {@link useRequestSize}. Omit a dimension to leave it unchanged. */
137
+ export type RequestSizeOptions = {
138
+ width?: number;
139
+ height?: number;
140
+ };
141
+ export type DownloadParams = {
142
+ contents: (EmbeddedResource | ResourceLink)[];
143
+ };
144
+ export type DownloadResult = {
145
+ isError?: boolean;
146
+ };
147
+ /**
148
+ * Args passed to a {@link ViewToolHandler}, inferred from the tool's
149
+ * `inputSchema` (optionality preserved). Mirrors the server's `registerTool`.
150
+ */
151
+ export type InferViewToolArgs<Shape extends ZodRawShapeCompat> = {
152
+ [K in keyof Shape as undefined extends SchemaOutput<Shape[K]> ? never : K]: SchemaOutput<Shape[K]>;
153
+ } & {
154
+ [K in keyof Shape as undefined extends SchemaOutput<Shape[K]> ? K : never]?: SchemaOutput<Shape[K]>;
155
+ };
156
+ /**
157
+ * Declares a tool the view exposes to the host/model (the MCP Apps
158
+ * "app-provided tools" feature). Mirrors the server-side `registerTool` config.
159
+ * Namespace `name` (e.g. `chess_make_move`) to avoid clashing with server tools.
160
+ */
161
+ export type ViewToolConfig<TInput extends ZodRawShapeCompat = ZodRawShapeCompat> = {
162
+ name: string;
163
+ title?: string;
164
+ description?: string;
165
+ inputSchema?: TInput;
166
+ annotations?: ToolAnnotations;
167
+ };
168
+ /**
169
+ * Value a {@link ViewToolHandler} returns — a standard MCP `CallToolResult`
170
+ * (`content` blocks plus optional `structuredContent` / `isError` / `_meta`),
171
+ * exactly as `ext-apps`' app tool callbacks return it.
172
+ */
173
+ export type ViewToolResult = CallToolResult;
174
+ /** Handler run when the host calls a view tool. Receives validated, typed args. */
175
+ export type ViewToolHandler<TInput extends ZodRawShapeCompat = ZodRawShapeCompat> = (args: InferViewToolArgs<TInput>) => ViewToolResult | Promise<ViewToolResult>;
176
+ /** @internal Untyped handler signature stored by the adaptor/bridge after type erasure. */
177
+ export type AnyViewToolHandler = (args: Record<string, unknown>) => ViewToolResult | Promise<ViewToolResult>;
178
+ /**
179
+ * @internal
180
+ * Low-level interface every host bridge implements. End-user code should use
181
+ * the React hooks (`useCallTool`, `useViewState`, `useFiles`, …) rather than
182
+ * calling this directly.
183
+ */
52
184
  export interface Adaptor {
53
- getExternalStore<K extends keyof BridgeInterface>(key: K): ExternalStore<K>;
185
+ getHostContextStore<K extends keyof HostContext>(key: K): HostContextStore<K>;
54
186
  callTool<ToolArgs extends CallToolArgs = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs): Promise<ToolResponse>;
55
- requestDisplayMode(mode: DisplayMode): Promise<{
56
- mode: DisplayMode;
187
+ requestDisplayMode(mode: RequestDisplayMode): Promise<{
188
+ mode: RequestDisplayMode;
189
+ }>;
190
+ requestClose(): Promise<void>;
191
+ requestSize(size: RequestSizeOptions): Promise<void>;
192
+ sendFollowUpMessage(prompt: string, options?: SendFollowUpMessageOptions): Promise<void>;
193
+ openExternal(href: string, options?: OpenExternalOptions): void;
194
+ download(params: DownloadParams): Promise<DownloadResult>;
195
+ setViewState(stateOrUpdater: SetViewStateAction): Promise<void>;
196
+ uploadFile(file: File, options?: UploadFileOptions): Promise<FileMetadata>;
197
+ getFileDownloadUrl(file: FileMetadata): Promise<{
198
+ downloadUrl: string;
57
199
  }>;
58
- sendFollowUpMessage(prompt: string): Promise<void>;
59
- openExternal(href: string): void;
60
- setWidgetState(stateOrUpdater: SetWidgetStateAction): Promise<void>;
200
+ selectFiles(): Promise<FileMetadata[]>;
201
+ openModal(options: RequestModalOptions): void;
202
+ setOpenInAppUrl(href: string): Promise<void>;
203
+ closeModal(): void;
204
+ registerViewTool(config: ViewToolConfig, handler: AnyViewToolHandler): () => void;
205
+ }
206
+ /**
207
+ * Thrown when a host bridge method is called in a runtime that doesn't
208
+ * support it (e.g. `uploadFile` outside the Apps SDK runtime).
209
+ */
210
+ export declare class NotSupportedError extends Error {
211
+ readonly method: string;
212
+ readonly reason?: string | undefined;
213
+ constructor(method: string, reason?: string | undefined);
61
214
  }
@@ -1,2 +1,15 @@
1
- export {};
1
+ /**
2
+ * Thrown when a host bridge method is called in a runtime that doesn't
3
+ * support it (e.g. `uploadFile` outside the Apps SDK runtime).
4
+ */
5
+ export class NotSupportedError extends Error {
6
+ method;
7
+ reason;
8
+ constructor(method, reason) {
9
+ super(`${method} is not supported in this runtime${reason ? `: ${reason}` : ""}`);
10
+ this.method = method;
11
+ this.reason = reason;
12
+ this.name = "NotSupportedError";
13
+ }
14
+ }
2
15
  //# sourceMappingURL=types.js.map