skybridge 0.0.0-dev.f06114a → 0.0.0-dev.f070d72

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 (329) hide show
  1. package/README.md +123 -124
  2. package/dist/cli/build-helpers.d.ts +7 -0
  3. package/dist/cli/build-helpers.js +82 -0
  4. package/dist/cli/build-helpers.js.map +1 -0
  5. package/dist/cli/build-helpers.test.d.ts +1 -0
  6. package/dist/cli/build-helpers.test.js +64 -0
  7. package/dist/cli/build-helpers.test.js.map +1 -0
  8. package/dist/cli/detect-port.d.ts +2 -2
  9. package/dist/cli/detect-port.js +9 -20
  10. package/dist/cli/detect-port.js.map +1 -1
  11. package/dist/cli/header.js.map +1 -1
  12. package/dist/cli/resolve-views-dir.d.ts +1 -0
  13. package/dist/cli/resolve-views-dir.js +17 -0
  14. package/dist/cli/resolve-views-dir.js.map +1 -0
  15. package/dist/cli/run-command.js.map +1 -1
  16. package/dist/cli/telemetry.js.map +1 -1
  17. package/dist/cli/tunnel-control-server.js.map +1 -1
  18. package/dist/cli/tunnel-control-server.test.js.map +1 -1
  19. package/dist/cli/tunnel-handler.js.map +1 -1
  20. package/dist/cli/tunnel-handler.test.js.map +1 -1
  21. package/dist/cli/tunnel.js.map +1 -1
  22. package/dist/cli/tunnel.test.js.map +1 -1
  23. package/dist/cli/types.js.map +1 -1
  24. package/dist/cli/use-execute-steps.js.map +1 -1
  25. package/dist/cli/use-messages.js.map +1 -1
  26. package/dist/cli/use-nodemon.js +11 -2
  27. package/dist/cli/use-nodemon.js.map +1 -1
  28. package/dist/cli/use-open-browser.js.map +1 -1
  29. package/dist/cli/use-tunnel.js.map +1 -1
  30. package/dist/cli/use-typescript-check.js +1 -1
  31. package/dist/cli/use-typescript-check.js.map +1 -1
  32. package/dist/commands/build.d.ts +0 -1
  33. package/dist/commands/build.js +18 -30
  34. package/dist/commands/build.js.map +1 -1
  35. package/dist/commands/create.d.ts +9 -0
  36. package/dist/commands/create.js +30 -0
  37. package/dist/commands/create.js.map +1 -0
  38. package/dist/commands/dev.js +16 -0
  39. package/dist/commands/dev.js.map +1 -1
  40. package/dist/commands/start.js +7 -1
  41. package/dist/commands/start.js.map +1 -1
  42. package/dist/commands/telemetry/disable.js.map +1 -1
  43. package/dist/commands/telemetry/enable.js.map +1 -1
  44. package/dist/commands/telemetry/status.js.map +1 -1
  45. package/dist/server/asset-base-url-transform-plugin.d.ts +1 -0
  46. package/dist/server/asset-base-url-transform-plugin.js +16 -1
  47. package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
  48. package/dist/server/asset-base-url-transform-plugin.test.js +51 -1
  49. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
  50. package/dist/server/auth/discovery.d.ts +32 -0
  51. package/dist/server/auth/discovery.js +56 -0
  52. package/dist/server/auth/discovery.js.map +1 -0
  53. package/dist/server/auth/discovery.test.d.ts +1 -0
  54. package/dist/server/auth/discovery.test.js +93 -0
  55. package/dist/server/auth/discovery.test.js.map +1 -0
  56. package/dist/server/auth/index.d.ts +18 -0
  57. package/dist/server/auth/index.js +2 -0
  58. package/dist/server/auth/index.js.map +1 -0
  59. package/dist/server/auth/providers/auth0.d.ts +18 -0
  60. package/dist/server/auth/providers/auth0.js +31 -0
  61. package/dist/server/auth/providers/auth0.js.map +1 -0
  62. package/dist/server/auth/providers/auth0.test.d.ts +1 -0
  63. package/dist/server/auth/providers/auth0.test.js +48 -0
  64. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  65. package/dist/server/auth/providers/clerk.d.ts +14 -0
  66. package/dist/server/auth/providers/clerk.js +16 -0
  67. package/dist/server/auth/providers/clerk.js.map +1 -0
  68. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  69. package/dist/server/auth/providers/clerk.test.js +28 -0
  70. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  71. package/dist/server/auth/providers/custom.d.ts +24 -0
  72. package/dist/server/auth/providers/custom.js +37 -0
  73. package/dist/server/auth/providers/custom.js.map +1 -0
  74. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  75. package/dist/server/auth/providers/custom.test.js +107 -0
  76. package/dist/server/auth/providers/custom.test.js.map +1 -0
  77. package/dist/server/auth/providers/descope.d.ts +15 -0
  78. package/dist/server/auth/providers/descope.js +33 -0
  79. package/dist/server/auth/providers/descope.js.map +1 -0
  80. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  81. package/dist/server/auth/providers/descope.test.js +37 -0
  82. package/dist/server/auth/providers/descope.test.js.map +1 -0
  83. package/dist/server/auth/providers/shared.d.ts +2 -0
  84. package/dist/server/auth/providers/shared.js +6 -0
  85. package/dist/server/auth/providers/shared.js.map +1 -0
  86. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  87. package/dist/server/auth/providers/shared.test.js +10 -0
  88. package/dist/server/auth/providers/shared.test.js.map +1 -0
  89. package/dist/server/auth/providers/stytch.d.ts +12 -0
  90. package/dist/server/auth/providers/stytch.js +13 -0
  91. package/dist/server/auth/providers/stytch.js.map +1 -0
  92. package/dist/server/auth/providers/workos.d.ts +11 -0
  93. package/dist/server/auth/providers/workos.js +12 -0
  94. package/dist/server/auth/providers/workos.js.map +1 -0
  95. package/dist/server/auth/setup.d.ts +4 -0
  96. package/dist/server/auth/setup.js +51 -0
  97. package/dist/server/auth/setup.js.map +1 -0
  98. package/dist/server/auth/setup.test.d.ts +1 -0
  99. package/dist/server/auth/setup.test.js +185 -0
  100. package/dist/server/auth/setup.test.js.map +1 -0
  101. package/dist/server/auth/verify.d.ts +12 -0
  102. package/dist/server/auth/verify.js +38 -0
  103. package/dist/server/auth/verify.js.map +1 -0
  104. package/dist/server/auth/verify.test.d.ts +1 -0
  105. package/dist/server/auth/verify.test.js +100 -0
  106. package/dist/server/auth/verify.test.js.map +1 -0
  107. package/dist/server/auth.d.ts +20 -0
  108. package/dist/server/auth.js +28 -0
  109. package/dist/server/auth.js.map +1 -0
  110. package/dist/server/build-manifest.test.d.ts +1 -0
  111. package/dist/server/build-manifest.test.js +27 -0
  112. package/dist/server/build-manifest.test.js.map +1 -0
  113. package/dist/server/content-helpers.d.ts +40 -0
  114. package/dist/server/content-helpers.js +33 -0
  115. package/dist/server/content-helpers.js.map +1 -1
  116. package/dist/server/content-helpers.test.js.map +1 -1
  117. package/dist/server/express.js.map +1 -1
  118. package/dist/server/express.test.js +61 -0
  119. package/dist/server/express.test.js.map +1 -1
  120. package/dist/server/file-ref.d.ts +28 -0
  121. package/dist/server/file-ref.js +27 -0
  122. package/dist/server/file-ref.js.map +1 -0
  123. package/dist/server/index.d.ts +11 -2
  124. package/dist/server/index.js +9 -1
  125. package/dist/server/index.js.map +1 -1
  126. package/dist/server/inferUtilityTypes.js.map +1 -1
  127. package/dist/server/metric.js.map +1 -1
  128. package/dist/server/middleware.d.ts +16 -3
  129. package/dist/server/middleware.js.map +1 -1
  130. package/dist/server/middleware.test-d.js.map +1 -1
  131. package/dist/server/middleware.test.js.map +1 -1
  132. package/dist/server/requestOrigin.d.ts +7 -0
  133. package/dist/server/requestOrigin.js +25 -0
  134. package/dist/server/requestOrigin.js.map +1 -0
  135. package/dist/server/server.d.ts +230 -7
  136. package/dist/server/server.js +325 -161
  137. package/dist/server/server.js.map +1 -1
  138. package/dist/server/templateHelper.js.map +1 -1
  139. package/dist/server/templates.generated.js.map +1 -1
  140. package/dist/server/tunnel-proxy-router.js.map +1 -1
  141. package/dist/server/tunnel-proxy-router.test.js.map +1 -1
  142. package/dist/server/view-name.test-d.d.ts +1 -0
  143. package/dist/server/view-name.test-d.js +8 -0
  144. package/dist/server/view-name.test-d.js.map +1 -0
  145. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  146. package/dist/server/view-resource-resolution.test.js +171 -0
  147. package/dist/server/view-resource-resolution.test.js.map +1 -0
  148. package/dist/server/viewsDevServer.js.map +1 -1
  149. package/dist/test/utils.js.map +1 -1
  150. package/dist/test/view.test.js +109 -96
  151. package/dist/test/view.test.js.map +1 -1
  152. package/dist/version.js.map +1 -1
  153. package/dist/web/bridges/adaptor.d.ts +51 -0
  154. package/dist/web/bridges/adaptor.js +310 -0
  155. package/dist/web/bridges/adaptor.js.map +1 -0
  156. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  157. package/dist/web/bridges/adaptor.test.js +197 -0
  158. package/dist/web/bridges/adaptor.test.js.map +1 -0
  159. package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -1
  160. package/dist/web/bridges/apps-sdk/bridge.js +15 -3
  161. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  162. package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
  163. package/dist/web/bridges/apps-sdk/index.js +0 -1
  164. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  165. package/dist/web/bridges/apps-sdk/types.d.ts +8 -1
  166. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  167. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
  168. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
  169. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  170. package/dist/web/bridges/get-adaptor.d.ts +7 -0
  171. package/dist/web/bridges/get-adaptor.js +9 -7
  172. package/dist/web/bridges/get-adaptor.js.map +1 -1
  173. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  174. package/dist/web/bridges/get-adaptor.test.js +32 -0
  175. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  176. package/dist/web/bridges/index.js.map +1 -1
  177. package/dist/web/bridges/mcp-app/bridge.d.ts +15 -2
  178. package/dist/web/bridges/mcp-app/bridge.js +68 -4
  179. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  180. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  181. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  182. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  183. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  184. package/dist/web/bridges/mcp-app/index.js +0 -1
  185. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  186. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  187. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +12 -0
  188. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +12 -0
  189. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  190. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  191. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  192. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  193. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  194. package/dist/web/bridges/types.d.ts +108 -3
  195. package/dist/web/bridges/types.js +14 -1
  196. package/dist/web/bridges/types.js.map +1 -1
  197. package/dist/web/bridges/types.test.d.ts +1 -0
  198. package/dist/web/bridges/types.test.js +19 -0
  199. package/dist/web/bridges/types.test.js.map +1 -0
  200. package/dist/web/bridges/use-host-context.d.ts +5 -0
  201. package/dist/web/bridges/use-host-context.js +5 -0
  202. package/dist/web/bridges/use-host-context.js.map +1 -1
  203. package/dist/web/components/modal-provider.js +4 -3
  204. package/dist/web/components/modal-provider.js.map +1 -1
  205. package/dist/web/create-store.d.ts +26 -0
  206. package/dist/web/create-store.js +26 -0
  207. package/dist/web/create-store.js.map +1 -1
  208. package/dist/web/create-store.test.js +8 -5
  209. package/dist/web/create-store.test.js.map +1 -1
  210. package/dist/web/data-llm.d.ts +33 -0
  211. package/dist/web/data-llm.js +28 -0
  212. package/dist/web/data-llm.js.map +1 -1
  213. package/dist/web/data-llm.test.js +9 -5
  214. package/dist/web/data-llm.test.js.map +1 -1
  215. package/dist/web/generate-helpers.d.ts +2 -0
  216. package/dist/web/generate-helpers.js +2 -0
  217. package/dist/web/generate-helpers.js.map +1 -1
  218. package/dist/web/generate-helpers.test-d.js +4 -2
  219. package/dist/web/generate-helpers.test-d.js.map +1 -1
  220. package/dist/web/generate-helpers.test.js.map +1 -1
  221. package/dist/web/helpers/state.js.map +1 -1
  222. package/dist/web/helpers/state.test.js.map +1 -1
  223. package/dist/web/hooks/index.d.ts +4 -0
  224. package/dist/web/hooks/index.js +4 -0
  225. package/dist/web/hooks/index.js.map +1 -1
  226. package/dist/web/hooks/test/utils.d.ts +6 -2
  227. package/dist/web/hooks/test/utils.js +13 -2
  228. package/dist/web/hooks/test/utils.js.map +1 -1
  229. package/dist/web/hooks/use-call-tool.d.ts +45 -0
  230. package/dist/web/hooks/use-call-tool.js +28 -0
  231. package/dist/web/hooks/use-call-tool.js.map +1 -1
  232. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
  233. package/dist/web/hooks/use-call-tool.test.js +62 -27
  234. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  235. package/dist/web/hooks/use-display-mode.d.ts +20 -0
  236. package/dist/web/hooks/use-display-mode.js +20 -0
  237. package/dist/web/hooks/use-display-mode.js.map +1 -1
  238. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
  239. package/dist/web/hooks/use-display-mode.test.js +56 -20
  240. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  241. package/dist/web/hooks/use-download.d.ts +5 -0
  242. package/dist/web/hooks/use-download.js +8 -0
  243. package/dist/web/hooks/use-download.js.map +1 -0
  244. package/dist/web/hooks/use-download.test.d.ts +1 -0
  245. package/dist/web/hooks/use-download.test.js +103 -0
  246. package/dist/web/hooks/use-download.test.js.map +1 -0
  247. package/dist/web/hooks/use-files.d.ts +32 -0
  248. package/dist/web/hooks/use-files.js +32 -0
  249. package/dist/web/hooks/use-files.js.map +1 -1
  250. package/dist/web/hooks/use-files.test.js +10 -2
  251. package/dist/web/hooks/use-files.test.js.map +1 -1
  252. package/dist/web/hooks/use-layout.d.ts +2 -0
  253. package/dist/web/hooks/use-layout.js +2 -0
  254. package/dist/web/hooks/use-layout.js.map +1 -1
  255. package/dist/web/hooks/use-layout.test.js +59 -26
  256. package/dist/web/hooks/use-layout.test.js.map +1 -1
  257. package/dist/web/hooks/use-open-external.d.ts +17 -0
  258. package/dist/web/hooks/use-open-external.js +16 -0
  259. package/dist/web/hooks/use-open-external.js.map +1 -1
  260. package/dist/web/hooks/use-open-external.test.js +13 -3
  261. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  262. package/dist/web/hooks/use-register-view-tool.d.ts +38 -0
  263. package/dist/web/hooks/use-register-view-tool.js +50 -0
  264. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  265. package/dist/web/hooks/use-request-close.d.ts +16 -0
  266. package/dist/web/hooks/use-request-close.js +21 -0
  267. package/dist/web/hooks/use-request-close.js.map +1 -0
  268. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  269. package/dist/web/hooks/use-request-close.test.js +47 -0
  270. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  271. package/dist/web/hooks/use-request-modal.d.ts +16 -1
  272. package/dist/web/hooks/use-request-modal.js +16 -1
  273. package/dist/web/hooks/use-request-modal.js.map +1 -1
  274. package/dist/web/hooks/use-request-modal.test.js +10 -0
  275. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  276. package/dist/web/hooks/use-request-size.d.ts +20 -0
  277. package/dist/web/hooks/use-request-size.js +24 -0
  278. package/dist/web/hooks/use-request-size.js.map +1 -0
  279. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  280. package/dist/web/hooks/use-request-size.test.js +47 -0
  281. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  282. package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -1
  283. package/dist/web/hooks/use-send-follow-up-message.js +19 -2
  284. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  285. package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
  286. package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
  287. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
  288. package/dist/web/hooks/use-set-open-in-app-url.test.js +28 -8
  289. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  290. package/dist/web/hooks/use-tool-info.d.ts +53 -2
  291. package/dist/web/hooks/use-tool-info.js +30 -7
  292. package/dist/web/hooks/use-tool-info.js.map +1 -1
  293. package/dist/web/hooks/use-tool-info.test-d.js +11 -29
  294. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  295. package/dist/web/hooks/use-tool-info.test.js +42 -32
  296. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  297. package/dist/web/hooks/use-user.d.ts +2 -0
  298. package/dist/web/hooks/use-user.js +2 -0
  299. package/dist/web/hooks/use-user.js.map +1 -1
  300. package/dist/web/hooks/use-user.test.js +81 -35
  301. package/dist/web/hooks/use-user.test.js.map +1 -1
  302. package/dist/web/hooks/use-view-state.d.ts +21 -0
  303. package/dist/web/hooks/use-view-state.js.map +1 -1
  304. package/dist/web/hooks/use-view-state.test.js +6 -2
  305. package/dist/web/hooks/use-view-state.test.js.map +1 -1
  306. package/dist/web/index.js.map +1 -1
  307. package/dist/web/mount-view.d.ts +19 -0
  308. package/dist/web/mount-view.js +19 -0
  309. package/dist/web/mount-view.js.map +1 -1
  310. package/dist/web/plugin/data-llm.test.js.map +1 -1
  311. package/dist/web/plugin/plugin.d.ts +28 -0
  312. package/dist/web/plugin/plugin.js +33 -0
  313. package/dist/web/plugin/plugin.js.map +1 -1
  314. package/dist/web/plugin/scan-views.js.map +1 -1
  315. package/dist/web/plugin/scan-views.test.js.map +1 -1
  316. package/dist/web/plugin/transform-data-llm.js.map +1 -1
  317. package/dist/web/plugin/transform-data-llm.test.js.map +1 -1
  318. package/dist/web/plugin/validate-view.js.map +1 -1
  319. package/dist/web/plugin/validate-view.test.js.map +1 -1
  320. package/dist/web/proxy.js.map +1 -1
  321. package/dist/web/types.d.ts +4 -0
  322. package/dist/web/types.js.map +1 -1
  323. package/package.json +22 -15
  324. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -24
  325. package/dist/web/bridges/apps-sdk/adaptor.js +0 -93
  326. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  327. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -48
  328. package/dist/web/bridges/mcp-app/adaptor.js +0 -268
  329. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-resource-resolution.test.js","sourceRoot":"","sources":["../../src/server/view-resource-resolution.test.ts"],"names":[],"mappings":"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","sourcesContent":["import http from \"node:http\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport type { RequestHandler } from \"express\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { __setBuildManifest, McpServer } from \"./index.js\";\n\nvi.mock(\"@skybridge/devtools\", () => ({\n devtoolsStaticServer: () =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\nvi.mock(\"./viewsDevServer.js\", () => ({\n viewsDevServer: (_httpServer: unknown) =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\n\n// Mirror what the Skybridge Vite plugin generates in `.skybridge/views.d.ts`:\n// narrow `ViewName` so `component: \"widget\"` typechecks against the registry.\ndeclare module \"./server.js\" {\n interface ViewNameRegistry {\n widget: true;\n }\n}\n\n// SKY-435: a view resource must resolve no matter the `?v=` query param value.\n// The version param is a content-derived cache key for external consumers\n// (it busts host/CDN caches when the bundle changes); it is not part of the\n// resource's identity, so a stale, absent, or arbitrary param must still serve\n// the underlying asset.\n\nasync function connect(register: (server: McpServer) => void) {\n const server = new McpServer({ name: \"test\", version: \"1.0.0\" });\n register(server);\n const client = new Client({ name: \"test-client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await server.connect(serverTransport);\n await client.connect(clientTransport);\n return {\n client,\n teardown: async () => {\n await client.close();\n await server.close();\n },\n };\n}\n\nlet openHttpServer: http.Server | undefined;\nafterEach(() => openHttpServer?.close());\n\n// Connect over real HTTP so forwarded proxy headers reach the resource handler.\nasync function connectHttp(\n register: (server: McpServer) => void,\n headers: Record<string, string>,\n) {\n const { createApp } = await import(\"./express.js\");\n const server = new McpServer({ name: \"test\", version: \"1.0.0\" });\n register(server);\n const httpServer = http.createServer();\n await createApp({ mcpServer: server, httpServer });\n const listening = http.createServer(server.express);\n await new Promise<void>((resolve) => listening.listen(0, resolve));\n openHttpServer = listening;\n const port = (listening.address() as { port: number }).port;\n\n const client = new Client({ name: \"test-client\", version: \"1.0.0\" });\n const transport = new StreamableHTTPClientTransport(\n new URL(`http://localhost:${port}/mcp`),\n { requestInit: { headers } },\n );\n await client.connect(transport);\n return {\n client,\n teardown: async () => {\n await client.close();\n await server.close();\n },\n };\n}\n\nfunction registerWidget(server: McpServer) {\n server.registerTool(\n { name: \"show\", description: \"show\", view: { component: \"widget\" } },\n () => ({ content: [{ type: \"text\" as const, text: \"ok\" }] }),\n );\n}\n\n/** Narrow a read-resource content entry to its text variant. */\nfunction textContent(contents: Array<{ uri: string }>): {\n uri: string;\n text: string;\n} {\n return contents[0] as { uri: string; text: string };\n}\n\ndescribe(\"view resource resolution (cache key)\", () => {\n afterEach(() => {\n delete process.env.NODE_ENV;\n });\n\n it(\"resolves regardless of the ?v= param and echoes the requested URI\", async () => {\n const { client, teardown } = await connect(registerWidget);\n\n const { resources } = await client.listResources();\n const listed = resources.find((r) =>\n r.uri.startsWith(\"ui://views/ext-apps/widget.html\"),\n );\n // Dev build advertises no cache key.\n expect(listed?.uri).toBe(\"ui://views/ext-apps/widget.html\");\n\n // A stale/arbitrary/absent param all resolve the same underlying asset,\n // and the response echoes the URI the consumer asked for (never rewritten).\n for (const uri of [\n \"ui://views/ext-apps/widget.html?v=stale123\",\n \"ui://views/ext-apps/widget.html?v=whatever-else\",\n \"ui://views/ext-apps/widget.html\",\n ]) {\n const { contents } = await client.readResource({ uri });\n expect(contents).toHaveLength(1);\n const content = textContent(contents);\n expect(typeof content.text).toBe(\"string\");\n expect(content.text.length).toBeGreaterThan(0);\n expect(content.uri).toBe(uri);\n }\n\n await teardown();\n });\n\n it(\"resolves a stale cache key when the canonical URI carries ?v= (prod)\", async () => {\n process.env.NODE_ENV = \"production\";\n __setBuildManifest({\n \"src/views/widget.tsx\": {\n isEntry: true,\n name: \"widget\",\n file: \"assets/widget-ABC123.js\",\n },\n \"style.css\": { file: \"assets/style-XYZ.css\" },\n } as unknown as Record<string, { file: string }>);\n\n const { client, teardown } = await connect(registerWidget);\n\n const { resources } = await client.listResources();\n const listed = resources.find((r) =>\n r.uri.startsWith(\"ui://views/ext-apps/widget.html\"),\n );\n // Production advertises a content-derived cache key.\n expect(listed?.uri).toMatch(\n /^ui:\\/\\/views\\/ext-apps\\/widget\\.html\\?v=[0-9a-f]{8}$/,\n );\n\n // A consumer holding a stale key still resolves the current asset.\n const staleUri = \"ui://views/ext-apps/widget.html?v=00000000\";\n const { contents } = await client.readResource({ uri: staleUri });\n expect(contents).toHaveLength(1);\n const content = textContent(contents);\n expect(typeof content.text).toBe(\"string\");\n expect(content.uri).toBe(staleUri);\n\n await teardown();\n });\n\n it(\"still throws for an unknown view path\", async () => {\n const { client, teardown } = await connect(registerWidget);\n\n await expect(\n client.readResource({ uri: \"ui://views/ext-apps/nope.html?v=1\" }),\n ).rejects.toThrow();\n\n await teardown();\n });\n\n // A proxy routing the request under a path prefix sends x-forwarded-prefix;\n // the view's asset URLs must carry that prefix (and the forwarded origin) so\n // they resolve back through the same routing. Per-request, so one process can\n // serve many hosts/prefixes at once.\n it(\"prefixes emitted asset URLs with x-forwarded-prefix (prod)\", async () => {\n process.env.NODE_ENV = \"production\";\n __setBuildManifest({\n \"src/views/widget.tsx\": {\n isEntry: true,\n name: \"widget\",\n file: \"assets/widget-ABC123.js\",\n },\n \"style.css\": { file: \"assets/style-XYZ.css\" },\n } as unknown as Record<string, { file: string }>);\n\n const { client, teardown } = await connectHttp(registerWidget, {\n \"x-forwarded-host\": \"foo.com\",\n \"x-forwarded-proto\": \"https\",\n \"x-forwarded-prefix\": \"/v1/canary\",\n });\n try {\n const { contents } = await client.readResource({\n uri: \"ui://views/ext-apps/widget.html\",\n });\n const { text } = textContent(contents);\n // Forwarded origin + prefix. (`assets/assets` is the existing layout: the\n // manifest `file` already carries `assets/` and the template prepends\n // `/assets/`; build.tsx's `_redirects` collapses it on the asset host.)\n expect(text).toContain(\n \"https://foo.com/v1/canary/assets/assets/widget-ABC123.js\",\n );\n expect(text).toContain(\n \"https://foo.com/v1/canary/assets/assets/style-XYZ.css\",\n );\n // No unprefixed asset URL leaks through.\n expect(text).not.toContain(\"foo.com/assets/\");\n } finally {\n await teardown();\n }\n });\n\n // Back-compat: older Skybridge advertised the view at `ui://views/apps-sdk/...`\n // via openai/outputTemplate. We no longer advertise it, but apps published then\n // have it cached, so the read must still resolve to the ext-apps content.\n it(\"resolves the legacy apps-sdk URL to the ext-apps content\", async () => {\n const { client, teardown } = await connect(registerWidget);\n\n const legacyUri = \"ui://views/apps-sdk/widget.html\";\n const { contents } = await client.readResource({ uri: legacyUri });\n\n expect(contents).toHaveLength(1);\n const content = contents[0] as {\n uri: string;\n text: string;\n mimeType: string;\n };\n expect(content.mimeType).toBe(\"text/html;profile=mcp-app\");\n expect(content.text.length).toBeGreaterThan(0);\n // The response echoes the requested (legacy) URI, never the canonical one.\n expect(content.uri).toBe(legacyUri);\n\n await teardown();\n });\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"viewsDevServer.js","sourceRoot":"","sources":["../../src/server/viewsDevServer.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,EAAE,EAAe,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AAEnF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,UAAuB,EACN,EAAE;IACnB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAElE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAErD,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAC3C,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EACzC,UAAU,EACV,IAAI,CACL,CAAC;IAEF,MAAM,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EAAE,WAAW,GAAG,EAAE,EACzB,GAAG,SAAS,EACb,GAAG,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;IAE/B,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC;QAC9B,GAAG,SAAS;QACZ,qEAAqE;QACrE,6CAA6C;QAC7C,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE;YACN,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;YACpB,GAAG,EAAE;gBACH,MAAM,EAAE,UAAU;aACnB;SACF;QACD,IAAI;QACJ,uEAAuE;QACvE,kDAAkD;QAClD,OAAO,EAAE,CAAC,GAAG,WAAW,EAAE,2BAA2B,EAAE,CAAC;KACzD,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
1
+ {"version":3,"file":"viewsDevServer.js","sourceRoot":"","sources":["../../src/server/viewsDevServer.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,EAAE,EAAe,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AAEnF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,UAAuB,EACN,EAAE;IACnB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAElE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAErD,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAC3C,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EACzC,UAAU,EACV,IAAI,CACL,CAAC;IAEF,MAAM,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EAAE,WAAW,GAAG,EAAE,EACzB,GAAG,SAAS,EACb,GAAG,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;IAE/B,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC;QAC9B,GAAG,SAAS;QACZ,qEAAqE;QACrE,6CAA6C;QAC7C,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE;YACN,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;YACpB,GAAG,EAAE;gBACH,MAAM,EAAE,UAAU;aACnB;SACF;QACD,IAAI;QACJ,uEAAuE;QACvE,kDAAkD;QAClD,OAAO,EAAE,CAAC,GAAG,WAAW,EAAE,2BAA2B,EAAE,CAAC;KACzD,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC","sourcesContent":["import type http from \"node:http\";\nimport path from \"node:path\";\nimport cors from \"cors\";\nimport express, { type Router } from \"express\";\nimport { assetBaseUrlTransformPlugin } from \"./asset-base-url-transform-plugin.js\";\n\n/**\n * Vite dev-server middleware for view assets.\n *\n * MUST be mounted at the Express app root so Vite can intercept\n * `/@vite/client`, `/@react-refresh`, and `/_skybridge/view/...` imports:\n *\n * const app = express();\n * if (env.NODE_ENV !== \"production\") {\n * app.use(await viewsDevServer(httpServer));\n * }\n */\nexport const viewsDevServer = async (\n httpServer: http.Server,\n): Promise<Router> => {\n const router = express.Router();\n\n const { createServer, loadConfigFromFile } = await import(\"vite\");\n\n const root = process.cwd();\n const configFile = path.join(root, \"vite.config.ts\");\n\n const configResult = await loadConfigFromFile(\n { command: \"serve\", mode: \"development\" },\n configFile,\n root,\n );\n\n const {\n build,\n preview,\n plugins: userPlugins = [],\n ...devConfig\n } = configResult?.config || {};\n\n const vite = await createServer({\n ...devConfig,\n // Pass `false` so Vite skips re-resolving a config file — we already\n // loaded and spread the user's config above.\n configFile: false,\n appType: \"custom\",\n server: {\n allowedHosts: true,\n middlewareMode: true,\n hmr: {\n server: httpServer,\n },\n },\n root,\n // optimizeDeps is set by the skybridge Vite plugin (entries + include)\n // so it can derive the view glob from `viewsDir`.\n plugins: [...userPlugins, assetBaseUrlTransformPlugin()],\n });\n\n router.use(cors());\n router.use(\"/\", vite.middlewares);\n\n return router;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { McpServer as McpServerBase } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { type MockInstance, vi } from \"vitest\";\nimport * as z from \"zod\";\nimport { McpServer, type ViewName } from \"../server/server.js\";\n\nexport function createMockMcpServer(): {\n server: McpServer;\n mockRegisterResource: MockInstance<McpServer[\"registerResource\"]>;\n mockRegisterTool: MockInstance;\n} {\n const server = new McpServer(\n {\n name: \"alpic-openai-app\",\n version: \"0.0.1\",\n },\n { capabilities: {} },\n );\n\n const mockRegisterResource = vi.spyOn(server, \"registerResource\");\n const mockRegisterTool = vi.spyOn(McpServerBase.prototype, \"registerTool\");\n\n return {\n server,\n mockRegisterResource,\n mockRegisterTool,\n };\n}\n\nexport function createTestServer() {\n return new McpServer({ name: \"test-app\", version: \"1.0.0\" }, {})\n .registerTool(\n {\n name: \"search-trip\",\n description: \"Search for trips\",\n inputSchema: {\n destination: z.string(),\n departureDate: z.string().optional(),\n maxPrice: z.number().optional(),\n },\n outputSchema: {\n results: z.array(\n z.object({\n id: z.string(),\n name: z.string(),\n price: z.number(),\n }),\n ),\n totalCount: z.number(),\n },\n view: { component: \"search-trip\" as ViewName },\n },\n async ({ destination }) => {\n return {\n content: [{ type: \"text\", text: `Found trips to ${destination}` }],\n structuredContent: {\n results: [{ id: \"1\", name: \"Trip\", price: 1000 }],\n totalCount: 1,\n },\n };\n },\n )\n .registerTool(\n {\n name: \"get-trip-details\",\n description: \"Get trip details\",\n inputSchema: {\n tripId: z.string(),\n },\n outputSchema: {\n name: z.string(),\n description: z.string(),\n images: z.array(z.string()),\n },\n view: { component: \"get-trip-details\" as ViewName },\n },\n async ({ tripId }) => {\n return {\n content: [{ type: \"text\", text: `Details for ${tripId}` }],\n structuredContent: {\n name: \"Trip\",\n description: \"A great trip\",\n images: [\"image1.jpg\"],\n },\n };\n },\n )\n .registerTool(\n {\n name: \"no-input-view\",\n description: \"View with no input\",\n inputSchema: {},\n outputSchema: {},\n view: { component: \"no-input-view\" as ViewName },\n },\n async () => {\n return {\n content: [{ type: \"text\", text: \"No input needed\" }],\n structuredContent: {},\n };\n },\n )\n .registerTool(\n {\n name: \"inferred-output-view\",\n description: \"View with output inferred from callback\",\n inputSchema: {\n query: z.string(),\n },\n view: { component: \"inferred-output-view\" as ViewName },\n },\n async ({ query }) => {\n return {\n content: [{ type: \"text\", text: `Query: ${query}` }],\n structuredContent: {\n inferredResults: [{ id: \"inferred-1\", score: 0.95 }],\n inferredCount: 1,\n },\n };\n },\n )\n .registerTool(\n {\n name: \"calculate-price\",\n description: \"Calculate trip price\",\n inputSchema: {\n tripId: z.string(),\n passengers: z.number(),\n },\n outputSchema: {\n totalPrice: z.number(),\n currency: z.string(),\n },\n },\n async ({ tripId, passengers }) => {\n return {\n content: [{ type: \"text\", text: `Price for ${tripId}` }],\n structuredContent: {\n totalPrice: 1000 * passengers,\n currency: \"USD\",\n },\n };\n },\n )\n .registerTool(\n {\n name: \"inferred-tool\",\n description: \"Tool with output inferred from callback\",\n inputSchema: {\n itemId: z.string(),\n },\n },\n async ({ itemId }) => {\n return {\n content: [{ type: \"text\", text: `Item: ${itemId}` }],\n structuredContent: {\n itemDetails: { name: \"Inferred Item\", available: true },\n fetchedAt: \"2024-01-01\",\n },\n };\n },\n )\n .registerTool(\n {\n name: \"view-with-metadata\",\n description: \"View that returns response metadata\",\n inputSchema: {\n resourceId: z.string(),\n },\n view: { component: \"view-with-metadata\" as ViewName },\n },\n async ({ resourceId }) => {\n return {\n content: [{ type: \"text\", text: `Resource: ${resourceId}` }],\n structuredContent: {\n data: { id: resourceId, loaded: true },\n },\n _meta: {\n requestId: \"req-123\",\n timestamp: 1704067200000,\n cached: false,\n },\n };\n },\n )\n .registerTool(\n {\n name: \"tool-with-metadata\",\n description: \"Tool that returns response metadata\",\n inputSchema: {\n query: z.string(),\n },\n },\n async ({ query }) => {\n return {\n content: [{ type: \"text\", text: `Query: ${query}` }],\n structuredContent: {\n results: [query],\n },\n _meta: {\n executionTime: 150,\n source: \"cache\",\n },\n };\n },\n )\n .registerTool(\n {\n name: \"view-with-mixed-returns\",\n description:\n \"View with mixed return paths (some with _meta, some without)\",\n inputSchema: {\n shouldSucceed: z.boolean(),\n },\n view: { component: \"view-with-mixed-returns\" as ViewName },\n },\n async ({ shouldSucceed }) => {\n if (!shouldSucceed) {\n return {\n content: [{ type: \"text\", text: \"Error occurred\" }],\n structuredContent: { error: \"Something went wrong\" },\n };\n }\n return {\n content: [{ type: \"text\", text: \"Success\" }],\n structuredContent: { data: \"result\" },\n _meta: {\n processedAt: 1704067200000,\n region: \"eu-west-1\",\n },\n };\n },\n );\n}\n\nexport function createMinimalTestServer() {\n return new McpServer({ name: \"test-app\", version: \"1.0.0\" }, {}).registerTool(\n {\n name: \"search-trip\",\n description: \"Search for trips\",\n inputSchema: {\n destination: z.string(),\n },\n outputSchema: {\n results: z.array(z.object({ id: z.string() })),\n },\n view: { component: \"search-trip\" as ViewName },\n },\n async ({ destination }) => {\n return {\n content: [{ type: \"text\", text: `Found trips to ${destination}` }],\n structuredContent: { results: [{ id: \"1\" }] },\n };\n },\n );\n}\n\ninterface InterfaceOutput {\n itemName: string;\n quantity: number;\n}\n\ninterface InterfaceMeta {\n processedBy: string;\n version: number;\n}\n\ninterface InterfaceReturnType {\n content: [{ type: \"text\"; text: string }];\n structuredContent: InterfaceOutput;\n _meta: InterfaceMeta;\n}\n\nexport function createInterfaceTestServer() {\n return new McpServer(\n { name: \"interface-test-app\", version: \"1.0.0\" },\n {},\n ).registerTool(\n {\n name: \"interface-view\" as const,\n description: \"View with interface-typed output\",\n inputSchema: {\n id: z.string(),\n },\n view: { component: \"interface-view\" as ViewName },\n },\n async ({ id }): Promise<InterfaceReturnType> => {\n return {\n content: [{ type: \"text\", text: `Item ${id}` }],\n structuredContent: {\n itemName: \"Test Item\",\n quantity: 42,\n },\n _meta: {\n processedBy: \"test\",\n version: 1,\n },\n };\n },\n );\n}\n\nexport function createMockExtra(\n host: string,\n options?: {\n headers?: Record<string, string | string[]>;\n url?: URL | string;\n },\n) {\n return {\n requestInfo: {\n headers: { host, ...(options?.headers ?? {}) },\n ...(options?.url ? { url: options.url } : {}),\n },\n };\n}\n\nexport function setTestEnv(env: Record<string, string>) {\n Object.assign(process.env, env);\n}\n\nexport function resetTestEnv() {\n delete process.env.NODE_ENV;\n}\n"]}
@@ -1,5 +1,8 @@
1
1
  import crypto from "node:crypto";
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
2
4
  import { afterEach, beforeEach, describe, expect, it, vi, } from "vitest";
5
+ import { McpServer as McpServerClass } from "../server/server.js";
3
6
  import { createMockExtra, createMockMcpServer, resetTestEnv, setTestEnv, } from "./utils.js";
4
7
  const mockManifest = {
5
8
  "skybridge:view:my-view": {
@@ -71,20 +74,24 @@ describe("McpServer.registerTool (unified API)", () => {
71
74
  const serverUrl = `http://${host}`;
72
75
  const hmrUrl = `ws://${host}`;
73
76
  const mockExtra = createMockExtra(host);
74
- const result = await appsSdkResourceCallback(new URL("ui://views/apps-sdk/my-view.html"), mockExtra);
77
+ const result = await appsSdkResourceCallback(new URL("ui://views/ext-apps/my-view.html"), mockExtra);
75
78
  expect(mockRegisterTool).toHaveBeenCalled();
76
79
  expect(result).toEqual({
77
80
  contents: [
78
81
  {
79
- uri: "ui://views/apps-sdk/my-view.html",
80
- mimeType: "text/html+skybridge",
82
+ uri: "ui://views/ext-apps/my-view.html",
83
+ mimeType: "text/html;profile=mcp-app",
81
84
  text: expect.stringContaining('<div id="root"></div>'),
82
85
  _meta: {
83
- "openai/widgetCSP": {
84
- resource_domains: [serverUrl],
85
- connect_domains: [serverUrl, hmrUrl],
86
+ ui: {
87
+ csp: {
88
+ resourceDomains: [serverUrl],
89
+ connectDomains: [serverUrl, hmrUrl],
90
+ baseUriDomains: [serverUrl],
91
+ },
92
+ domain: serverUrl,
93
+ description: "Test view",
86
94
  },
87
- "openai/widgetDomain": serverUrl,
88
95
  "openai/widgetDescription": "Test view",
89
96
  },
90
97
  },
@@ -110,20 +117,24 @@ describe("McpServer.registerTool (unified API)", () => {
110
117
  const host = "myapp.com";
111
118
  const serverUrl = `https://${host}`;
112
119
  const mockExtra = createMockExtra(host);
113
- const versionedUri = `ui://views/apps-sdk/my-view.html${expectedVersionParam("assets/my-view-abc123.js", "style.css")}`;
120
+ const versionedUri = `ui://views/ext-apps/my-view.html${expectedVersionParam("assets/my-view-abc123.js", "style.css")}`;
114
121
  const result = await appsSdkResourceCallback(new URL(versionedUri), mockExtra);
115
122
  expect(result).toEqual({
116
123
  contents: [
117
124
  {
118
125
  uri: versionedUri,
119
- mimeType: "text/html+skybridge",
126
+ mimeType: "text/html;profile=mcp-app",
120
127
  text: expect.stringContaining('<div id="root"></div>'),
121
128
  _meta: {
122
- "openai/widgetCSP": {
123
- resource_domains: [serverUrl],
124
- connect_domains: [serverUrl],
129
+ ui: {
130
+ csp: {
131
+ resourceDomains: [serverUrl],
132
+ connectDomains: [serverUrl],
133
+ baseUriDomains: [serverUrl],
134
+ },
135
+ domain: serverUrl,
136
+ description: "Test view",
125
137
  },
126
- "openai/widgetDomain": serverUrl,
127
138
  "openai/widgetDescription": "Test view",
128
139
  },
129
140
  },
@@ -142,7 +153,7 @@ describe("McpServer.registerTool (unified API)", () => {
142
153
  view: { component: "my-view", description: "Test view" },
143
154
  }, vi.fn());
144
155
  const extAppsResourceCallback = mockRegisterResource.mock
145
- .calls[1]?.[3];
156
+ .calls[0]?.[3];
146
157
  expect(extAppsResourceCallback).toBeDefined();
147
158
  const forwardedUrl = "https://everything-3a2c1264.staging.alpic.live/mcp?foo=bar";
148
159
  const expectedDomain = `${crypto
@@ -167,9 +178,10 @@ describe("McpServer.registerTool (unified API)", () => {
167
178
  description: "Test view",
168
179
  domain: expectedDomain,
169
180
  },
181
+ "openai/widgetDescription": "Test view",
170
182
  });
171
183
  });
172
- it("should register resources with correct hostType for both apps-sdk and ext-apps", async () => {
184
+ it("should register a single ext-apps resource", async () => {
173
185
  server.registerTool({
174
186
  name: "my-view",
175
187
  description: "Test tool",
@@ -179,37 +191,14 @@ describe("McpServer.registerTool (unified API)", () => {
179
191
  prefersBorder: true,
180
192
  },
181
193
  }, vi.fn());
182
- expect(mockRegisterResource).toHaveBeenCalledTimes(2);
183
- const appsSdkCallback = mockRegisterResource.mock
194
+ expect(mockRegisterResource).toHaveBeenCalledTimes(1);
195
+ const resourceCallback = mockRegisterResource.mock
184
196
  .calls[0]?.[3];
185
197
  const host = "localhost:3000";
186
198
  const serverUrl = `http://${host}`;
187
199
  const hmrUrl = `ws://${host}`;
188
- const appsSdkResult = await appsSdkCallback(new URL("ui://views/apps-sdk/my-view.html"), createMockExtra(host));
189
- expect(appsSdkResult).toEqual({
190
- contents: [
191
- {
192
- uri: "ui://views/apps-sdk/my-view.html",
193
- mimeType: "text/html+skybridge",
194
- text: expect.stringContaining('<div id="root"></div>'),
195
- _meta: {
196
- "openai/widgetCSP": {
197
- resource_domains: [serverUrl],
198
- connect_domains: [serverUrl, hmrUrl],
199
- },
200
- "openai/widgetDomain": serverUrl,
201
- "openai/widgetDescription": "Test view",
202
- "openai/widgetPrefersBorder": true,
203
- },
204
- },
205
- ],
206
- });
207
- expect(appsSdkResult.contents[0]?.text).toContain('window.skybridge = { hostType: "apps-sdk", serverUrl: "http://localhost:3000" };');
208
- const extAppsResourceCallback = mockRegisterResource.mock
209
- .calls[1]?.[3];
210
- expect(extAppsResourceCallback).toBeDefined();
211
- const extAppsResult = await extAppsResourceCallback(new URL("ui://views/ext-apps/my-view.html"), createMockExtra(host));
212
- expect(extAppsResult).toEqual({
200
+ const result = await resourceCallback(new URL("ui://views/ext-apps/my-view.html"), createMockExtra(host));
201
+ expect(result).toEqual({
213
202
  contents: [
214
203
  {
215
204
  uri: "ui://views/ext-apps/my-view.html",
@@ -226,27 +215,26 @@ describe("McpServer.registerTool (unified API)", () => {
226
215
  description: "Test view",
227
216
  prefersBorder: true,
228
217
  },
218
+ "openai/widgetDescription": "Test view",
229
219
  },
230
220
  },
231
221
  ],
232
222
  });
233
- expect(extAppsResult.contents[0]?.text).toContain('window.skybridge = { hostType: "mcp-app", serverUrl: "http://localhost:3000" };');
223
+ expect(result.contents[0]?.text).toContain('window.skybridge = { hostType: "mcp-app", serverUrl: "http://localhost:3000" };');
234
224
  });
235
- it("should register tool with ui.resourceUri metadata", async () => {
225
+ it("should advertise the single resource via ui.resourceUri only (no openai/outputTemplate)", async () => {
236
226
  server.registerTool({
237
227
  name: "my-view",
238
228
  description: "Test tool",
239
229
  view: { component: "my-view", description: "Test view" },
240
230
  }, vi.fn());
241
- expect(mockRegisterTool).toHaveBeenCalledTimes(1);
242
- const toolCallArgs = mockRegisterTool.mock.calls[0];
243
- const toolConfig = toolCallArgs?.[1];
244
- expect(toolConfig._meta).toHaveProperty("ui");
245
- expect(toolConfig._meta?.ui).toEqual({
246
- resourceUri: "ui://views/ext-apps/my-view.html",
247
- });
231
+ const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
232
+ const uri = "ui://views/ext-apps/my-view.html";
233
+ expect(toolConfig._meta?.ui?.resourceUri).toBe(uri);
234
+ expect(toolConfig._meta?.["ui/resourceUri"]).toBe(uri);
235
+ expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
248
236
  });
249
- it("should register tool with openai/outputTemplate when apps-sdk only", async () => {
237
+ it("treats the deprecated hosts option as a no-op (always the single resource)", async () => {
250
238
  server.registerTool({
251
239
  name: "my-view",
252
240
  description: "Test tool",
@@ -256,11 +244,10 @@ describe("McpServer.registerTool (unified API)", () => {
256
244
  hosts: ["apps-sdk"],
257
245
  },
258
246
  }, vi.fn());
259
- expect(mockRegisterTool).toHaveBeenCalledTimes(1);
260
- const toolCallArgs = mockRegisterTool.mock.calls[0];
261
- const toolConfig = toolCallArgs?.[1];
262
- expect(toolConfig._meta).not.toHaveProperty("ui");
263
- expect(toolConfig._meta?.["openai/outputTemplate"]).toBe("ui://views/apps-sdk/my-view.html");
247
+ expect(mockRegisterResource).toHaveBeenCalledTimes(1);
248
+ const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
249
+ expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/my-view.html");
250
+ expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
264
251
  });
265
252
  it("should not version view URIs in development", () => {
266
253
  server.registerTool({
@@ -269,12 +256,11 @@ describe("McpServer.registerTool (unified API)", () => {
269
256
  view: { component: "my-view", description: "Test view" },
270
257
  }, vi.fn());
271
258
  const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
272
- expect(toolConfig._meta?.["openai/outputTemplate"]).toBe("ui://views/apps-sdk/my-view.html");
259
+ expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
273
260
  expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/my-view.html");
274
- // The URI registered with the resource handler must match the URI in
275
- // outputTemplate exactly so the SDK can resolve `resources/read` requests.
276
- expect(mockRegisterResource.mock.calls[0]?.[1]).toBe("ui://views/apps-sdk/my-view.html");
277
- expect(mockRegisterResource.mock.calls[1]?.[1]).toBe("ui://views/ext-apps/my-view.html");
261
+ // The URI registered with the resource handler must match ui.resourceUri
262
+ // exactly so the SDK can resolve `resources/read` requests.
263
+ expect(mockRegisterResource.mock.calls[0]?.[1]).toBe("ui://views/ext-apps/my-view.html");
278
264
  });
279
265
  it("should append a stable content hash to view URIs in production", () => {
280
266
  setTestEnv({ NODE_ENV: "production" });
@@ -285,10 +271,9 @@ describe("McpServer.registerTool (unified API)", () => {
285
271
  }, vi.fn());
286
272
  const expected = expectedVersionParam("assets/my-view-abc123.js", "style.css");
287
273
  const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
288
- expect(toolConfig._meta?.["openai/outputTemplate"]).toBe(`ui://views/apps-sdk/my-view.html${expected}`);
274
+ expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
289
275
  expect(toolConfig._meta?.ui?.resourceUri).toBe(`ui://views/ext-apps/my-view.html${expected}`);
290
- expect(mockRegisterResource.mock.calls[0]?.[1]).toBe(`ui://views/apps-sdk/my-view.html${expected}`);
291
- expect(mockRegisterResource.mock.calls[1]?.[1]).toBe(`ui://views/ext-apps/my-view.html${expected}`);
276
+ expect(mockRegisterResource.mock.calls[0]?.[1]).toBe(`ui://views/ext-apps/my-view.html${expected}`);
292
277
  });
293
278
  it("should produce different version params for views with different bundles", () => {
294
279
  setTestEnv({ NODE_ENV: "production" });
@@ -302,8 +287,8 @@ describe("McpServer.registerTool (unified API)", () => {
302
287
  description: "Second tool",
303
288
  view: { component: "folder-view" },
304
289
  }, vi.fn());
305
- const myviewTemplate = (mockRegisterTool.mock.calls[0]?.[1])._meta?.["openai/outputTemplate"];
306
- const folderviewTemplate = (mockRegisterTool.mock.calls[1]?.[1])._meta?.["openai/outputTemplate"];
290
+ const myviewTemplate = (mockRegisterTool.mock.calls[0]?.[1])._meta?.ui?.resourceUri;
291
+ const folderviewTemplate = (mockRegisterTool.mock.calls[1]?.[1])._meta?.ui?.resourceUri;
307
292
  expect(myviewTemplate).not.toEqual(folderviewTemplate);
308
293
  expect(myviewTemplate).toMatch(/\?v=[0-9a-f]{8}$/);
309
294
  expect(folderviewTemplate).toMatch(/\?v=[0-9a-f]{8}$/);
@@ -316,26 +301,7 @@ describe("McpServer.registerTool (unified API)", () => {
316
301
  view: { component: "unknown-view" },
317
302
  }, vi.fn());
318
303
  const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
319
- expect(toolConfig._meta?.["openai/outputTemplate"]).toBe("ui://views/apps-sdk/unknown-view.html");
320
- });
321
- it("should register tool with ui.resourceUri only when mcp-app only", async () => {
322
- server.registerTool({
323
- name: "my-view",
324
- description: "Test tool",
325
- view: {
326
- component: "my-view",
327
- description: "Test view",
328
- hosts: ["mcp-app"],
329
- },
330
- }, vi.fn());
331
- expect(mockRegisterTool).toHaveBeenCalledTimes(1);
332
- const toolCallArgs = mockRegisterTool.mock.calls[0];
333
- const toolConfig = toolCallArgs?.[1];
334
- expect(toolConfig._meta).toHaveProperty("ui");
335
- expect(toolConfig._meta?.ui).toEqual({
336
- resourceUri: "ui://views/ext-apps/my-view.html",
337
- });
338
- expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
304
+ expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/unknown-view.html");
339
305
  });
340
306
  it("should inject viewUUID into _meta of tool callback results", async () => {
341
307
  const mockToolCallback = vi.fn().mockResolvedValue({
@@ -473,11 +439,12 @@ describe("McpServer.registerTool (unified API)", () => {
473
439
  const host = "localhost:3000";
474
440
  const serverUrl = `http://${host}`;
475
441
  const hmrUrl = `ws://${host}`;
476
- const result = await appsSdkCallback(new URL("ui://views/apps-sdk/csp-tool.html"), createMockExtra(host));
442
+ const result = await appsSdkCallback(new URL("ui://views/ext-apps/csp-tool.html"), createMockExtra(host));
477
443
  const meta = result.contents[0]?._meta;
478
- expect(meta["openai/widgetCSP"]).toEqual({
479
- resource_domains: [serverUrl, "https://cdn.example.com"],
480
- connect_domains: [serverUrl, hmrUrl, "https://api.example.com"],
444
+ expect(meta.ui?.csp).toEqual({
445
+ resourceDomains: [serverUrl, "https://cdn.example.com"],
446
+ connectDomains: [serverUrl, hmrUrl, "https://api.example.com"],
447
+ baseUriDomains: [serverUrl],
481
448
  });
482
449
  });
483
450
  it("should let view._meta override framework-computed keys", async () => {
@@ -489,18 +456,20 @@ describe("McpServer.registerTool (unified API)", () => {
489
456
  description: "Test view",
490
457
  csp: { connectDomains: ["https://api.x.com"] },
491
458
  _meta: {
492
- "openai/widgetCSP": {
493
- connect_domains: ["https://api.y.com"],
459
+ ui: {
460
+ csp: {
461
+ connectDomains: ["https://api.y.com"],
462
+ },
494
463
  },
495
464
  },
496
465
  },
497
466
  }, vi.fn());
498
467
  const appsSdkCallback = mockRegisterResource.mock
499
468
  .calls[0]?.[3];
500
- const result = await appsSdkCallback(new URL("ui://views/apps-sdk/override-tool.html"), createMockExtra("localhost:3000"));
469
+ const result = await appsSdkCallback(new URL("ui://views/ext-apps/override-tool.html"), createMockExtra("localhost:3000"));
501
470
  const meta = result.contents[0]?._meta;
502
- expect(meta["openai/widgetCSP"]).toEqual({
503
- connect_domains: ["https://api.y.com"],
471
+ expect(meta.ui?.csp).toEqual({
472
+ connectDomains: ["https://api.y.com"],
504
473
  });
505
474
  });
506
475
  it("should pass user _meta keys through to tool config", () => {
@@ -520,4 +489,48 @@ describe("McpServer.registerTool (unified API)", () => {
520
489
  expect(toolConfig._meta?.["acme.com/category"]).toBe("utility");
521
490
  });
522
491
  });
492
+ describe("resources/list view _meta injection", () => {
493
+ afterEach(() => resetTestEnv());
494
+ it("attaches CSP, domain, and connectDomains _meta to view resources at list time", async () => {
495
+ setTestEnv({ NODE_ENV: "production" });
496
+ const server = new McpServerClass({ name: "test", version: "1.0.0" }, { capabilities: {} });
497
+ server.registerTool({
498
+ name: "start",
499
+ description: "Start",
500
+ view: {
501
+ component: "my-view",
502
+ description: "Onboarding deck",
503
+ domain: "skybridge.tech",
504
+ csp: {
505
+ resourceDomains: ["https://fonts.googleapis.com"],
506
+ redirectDomains: ["https://docs.skybridge.tech"],
507
+ },
508
+ },
509
+ }, vi.fn().mockResolvedValue({
510
+ content: [{ type: "text", text: "ok" }],
511
+ structuredContent: {},
512
+ }));
513
+ const client = new Client({ name: "test-client", version: "1.0.0" });
514
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
515
+ await server.connect(serverTransport);
516
+ await client.connect(clientTransport);
517
+ const { resources } = await client.listResources();
518
+ await client.close();
519
+ await server.close();
520
+ const appsSdk = resources.find((r) => r.uri.includes("apps-sdk"));
521
+ const extApps = resources.find((r) => r.uri.includes("ext-apps"));
522
+ expect(appsSdk).toBeUndefined();
523
+ expect(extApps?._meta).toBeDefined();
524
+ const extUi = (extApps?._meta).ui;
525
+ expect(extUi?.csp?.connectDomains?.length).toBeGreaterThan(0);
526
+ expect(extUi?.csp?.resourceDomains).toContain("https://fonts.googleapis.com");
527
+ expect(extUi?.domain).toBe("skybridge.tech");
528
+ const meta = extApps?._meta;
529
+ expect(meta["openai/widgetDescription"]).toBe("Onboarding deck");
530
+ expect(meta["openai/widgetCSP"]?.redirect_domains).toEqual([
531
+ "https://docs.skybridge.tech",
532
+ ]);
533
+ expect(meta.ui?.csp).not.toHaveProperty("redirectDomains");
534
+ });
535
+ });
523
536
  //# sourceMappingURL=view.test.js.map