skybridge 0.0.0-dev.f03017e → 0.0.0-dev.f0394fc

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 (513) hide show
  1. package/README.md +126 -124
  2. package/dist/cli/build-helpers.d.ts +11 -0
  3. package/dist/cli/build-helpers.js +113 -0
  4. package/dist/cli/build-helpers.js.map +1 -0
  5. package/dist/cli/build-helpers.test.js +143 -0
  6. package/dist/cli/build-helpers.test.js.map +1 -0
  7. package/dist/cli/build-steps.d.ts +2 -0
  8. package/dist/cli/build-steps.js +84 -0
  9. package/dist/cli/build-steps.js.map +1 -0
  10. package/dist/cli/build-steps.test.js +72 -0
  11. package/dist/cli/build-steps.test.js.map +1 -0
  12. package/dist/cli/detect-port.d.ts +2 -2
  13. package/dist/cli/detect-port.js +8 -20
  14. package/dist/cli/detect-port.js.map +1 -1
  15. package/dist/cli/header.d.ts +1 -1
  16. package/dist/cli/header.js.map +1 -1
  17. package/dist/cli/resolve-skybridge-config.d.ts +6 -0
  18. package/dist/cli/resolve-skybridge-config.js +28 -0
  19. package/dist/cli/resolve-skybridge-config.js.map +1 -0
  20. package/dist/cli/run-command.js.map +1 -1
  21. package/dist/cli/run-plain.d.ts +18 -0
  22. package/dist/cli/run-plain.js +90 -0
  23. package/dist/cli/run-plain.js.map +1 -0
  24. package/dist/cli/telemetry.js +2 -0
  25. package/dist/cli/telemetry.js.map +1 -1
  26. package/dist/cli/tunnel-control-server.d.ts +9 -0
  27. package/dist/cli/tunnel-control-server.js +31 -0
  28. package/dist/cli/tunnel-control-server.js.map +1 -0
  29. package/dist/cli/tunnel-control-server.test.js +39 -0
  30. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  31. package/dist/cli/tunnel-handler.d.ts +3 -0
  32. package/dist/cli/tunnel-handler.js +48 -0
  33. package/dist/cli/tunnel-handler.js.map +1 -0
  34. package/dist/cli/tunnel-handler.test.js +105 -0
  35. package/dist/cli/tunnel-handler.test.js.map +1 -0
  36. package/dist/cli/tunnel.d.ts +57 -0
  37. package/dist/cli/tunnel.js +154 -0
  38. package/dist/cli/tunnel.js.map +1 -0
  39. package/dist/cli/tunnel.test.js +190 -0
  40. package/dist/cli/tunnel.test.js.map +1 -0
  41. package/dist/cli/types.js.map +1 -1
  42. package/dist/cli/use-execute-steps.d.ts +1 -1
  43. package/dist/cli/use-execute-steps.js.map +1 -1
  44. package/dist/cli/use-messages.js.map +1 -1
  45. package/dist/cli/use-nodemon.d.ts +25 -1
  46. package/dist/cli/use-nodemon.js +97 -55
  47. package/dist/cli/use-nodemon.js.map +1 -1
  48. package/dist/cli/use-open-browser.d.ts +1 -0
  49. package/dist/cli/use-open-browser.js +44 -0
  50. package/dist/cli/use-open-browser.js.map +1 -0
  51. package/dist/cli/use-tunnel.d.ts +1 -1
  52. package/dist/cli/use-tunnel.js +102 -68
  53. package/dist/cli/use-tunnel.js.map +1 -1
  54. package/dist/cli/use-typescript-check.d.ts +9 -2
  55. package/dist/cli/use-typescript-check.js +91 -51
  56. package/dist/cli/use-typescript-check.js.map +1 -1
  57. package/dist/commands/build.d.ts +0 -3
  58. package/dist/commands/build.js +2 -38
  59. package/dist/commands/build.js.map +1 -1
  60. package/dist/commands/create.d.ts +9 -0
  61. package/dist/commands/create.js +30 -0
  62. package/dist/commands/create.js.map +1 -0
  63. package/dist/commands/dev.d.ts +2 -0
  64. package/dist/commands/dev.js +84 -5
  65. package/dist/commands/dev.js.map +1 -1
  66. package/dist/commands/start.js +7 -1
  67. package/dist/commands/start.js.map +1 -1
  68. package/dist/commands/telemetry/disable.js.map +1 -1
  69. package/dist/commands/telemetry/enable.js.map +1 -1
  70. package/dist/commands/telemetry/status.js.map +1 -1
  71. package/dist/context-warnings.d.ts +5 -0
  72. package/dist/context-warnings.js +31 -0
  73. package/dist/context-warnings.js.map +1 -0
  74. package/dist/context-warnings.test.js +28 -0
  75. package/dist/context-warnings.test.js.map +1 -0
  76. package/dist/server/app.d.ts +211 -0
  77. package/dist/server/app.js +277 -0
  78. package/dist/server/app.js.map +1 -0
  79. package/dist/server/app.test.d.ts +1 -0
  80. package/dist/server/app.test.js +178 -0
  81. package/dist/server/app.test.js.map +1 -0
  82. package/dist/server/asset-base-url-transform-plugin.d.ts +1 -0
  83. package/dist/server/asset-base-url-transform-plugin.js +17 -2
  84. package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
  85. package/dist/server/asset-base-url-transform-plugin.test.js +80 -1
  86. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
  87. package/dist/server/auth/discovery.d.ts +33 -0
  88. package/dist/server/auth/discovery.js +56 -0
  89. package/dist/server/auth/discovery.js.map +1 -0
  90. package/dist/server/auth/discovery.test.d.ts +1 -0
  91. package/dist/server/auth/discovery.test.js +93 -0
  92. package/dist/server/auth/discovery.test.js.map +1 -0
  93. package/dist/server/auth/index.d.ts +48 -0
  94. package/dist/server/auth/index.js +2 -0
  95. package/dist/server/auth/index.js.map +1 -0
  96. package/dist/server/auth/providers/auth0.d.ts +40 -0
  97. package/dist/server/auth/providers/auth0.js +36 -0
  98. package/dist/server/auth/providers/auth0.js.map +1 -0
  99. package/dist/server/auth/providers/auth0.test.d.ts +1 -0
  100. package/dist/server/auth/providers/auth0.test.js +50 -0
  101. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  102. package/dist/server/auth/providers/authplane.d.ts +49 -0
  103. package/dist/server/auth/providers/authplane.js +57 -0
  104. package/dist/server/auth/providers/authplane.js.map +1 -0
  105. package/dist/server/auth/providers/authplane.test.d.ts +1 -0
  106. package/dist/server/auth/providers/authplane.test.js +143 -0
  107. package/dist/server/auth/providers/authplane.test.js.map +1 -0
  108. package/dist/server/auth/providers/clerk.d.ts +51 -0
  109. package/dist/server/auth/providers/clerk.js +19 -0
  110. package/dist/server/auth/providers/clerk.js.map +1 -0
  111. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  112. package/dist/server/auth/providers/clerk.test.js +30 -0
  113. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  114. package/dist/server/auth/providers/custom.d.ts +42 -0
  115. package/dist/server/auth/providers/custom.js +59 -0
  116. package/dist/server/auth/providers/custom.js.map +1 -0
  117. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  118. package/dist/server/auth/providers/custom.test.js +161 -0
  119. package/dist/server/auth/providers/custom.test.js.map +1 -0
  120. package/dist/server/auth/providers/descope.d.ts +44 -0
  121. package/dist/server/auth/providers/descope.js +44 -0
  122. package/dist/server/auth/providers/descope.js.map +1 -0
  123. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  124. package/dist/server/auth/providers/descope.test.js +62 -0
  125. package/dist/server/auth/providers/descope.test.js.map +1 -0
  126. package/dist/server/auth/providers/shared.d.ts +2 -0
  127. package/dist/server/auth/providers/shared.js +6 -0
  128. package/dist/server/auth/providers/shared.js.map +1 -0
  129. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  130. package/dist/server/auth/providers/shared.test.js +10 -0
  131. package/dist/server/auth/providers/shared.test.js.map +1 -0
  132. package/dist/server/auth/providers/stytch.d.ts +25 -0
  133. package/dist/server/auth/providers/stytch.js +16 -0
  134. package/dist/server/auth/providers/stytch.js.map +1 -0
  135. package/dist/server/auth/providers/verify-spy.d.ts +12 -0
  136. package/dist/server/auth/providers/verify-spy.js +21 -0
  137. package/dist/server/auth/providers/verify-spy.js.map +1 -0
  138. package/dist/server/auth/providers/workos.d.ts +34 -0
  139. package/dist/server/auth/providers/workos.js +16 -0
  140. package/dist/server/auth/providers/workos.js.map +1 -0
  141. package/dist/server/auth/security-schemes.d.ts +23 -0
  142. package/dist/server/auth/security-schemes.js +64 -0
  143. package/dist/server/auth/security-schemes.js.map +1 -0
  144. package/dist/server/auth/security-schemes.test.d.ts +1 -0
  145. package/dist/server/auth/security-schemes.test.js +99 -0
  146. package/dist/server/auth/security-schemes.test.js.map +1 -0
  147. package/dist/server/auth/setup.d.ts +6 -0
  148. package/dist/server/auth/setup.js +91 -0
  149. package/dist/server/auth/setup.js.map +1 -0
  150. package/dist/server/auth/setup.test.d.ts +1 -0
  151. package/dist/server/auth/setup.test.js +514 -0
  152. package/dist/server/auth/setup.test.js.map +1 -0
  153. package/dist/server/auth/verify.d.ts +48 -0
  154. package/dist/server/auth/verify.js +62 -0
  155. package/dist/server/auth/verify.js.map +1 -0
  156. package/dist/server/auth/verify.test.d.ts +1 -0
  157. package/dist/server/auth/verify.test.js +165 -0
  158. package/dist/server/auth/verify.test.js.map +1 -0
  159. package/dist/server/auth-extra.test-d.d.ts +1 -0
  160. package/dist/server/auth-extra.test-d.js +130 -0
  161. package/dist/server/auth-extra.test-d.js.map +1 -0
  162. package/dist/server/auth.d.ts +57 -0
  163. package/dist/server/auth.js +27 -0
  164. package/dist/server/auth.js.map +1 -0
  165. package/dist/server/build-manifest.test.d.ts +1 -0
  166. package/dist/server/build-manifest.test.js +28 -0
  167. package/dist/server/build-manifest.test.js.map +1 -0
  168. package/dist/server/content-helpers.d.ts +41 -1
  169. package/dist/server/content-helpers.js +33 -0
  170. package/dist/server/content-helpers.js.map +1 -1
  171. package/dist/server/content-helpers.test.js.map +1 -1
  172. package/dist/server/events.d.ts +113 -0
  173. package/dist/server/events.js +318 -0
  174. package/dist/server/events.js.map +1 -0
  175. package/dist/server/events.test.d.ts +1 -0
  176. package/dist/server/events.test.js +172 -0
  177. package/dist/server/events.test.js.map +1 -0
  178. package/dist/server/express.d.ts +24 -7
  179. package/dist/server/express.js +66 -30
  180. package/dist/server/express.js.map +1 -1
  181. package/dist/server/express.test.js +445 -81
  182. package/dist/server/express.test.js.map +1 -1
  183. package/dist/server/file-ref.d.ts +28 -0
  184. package/dist/server/file-ref.js +27 -0
  185. package/dist/server/file-ref.js.map +1 -0
  186. package/dist/server/form-input.d.ts +120 -0
  187. package/dist/server/form-input.js +89 -0
  188. package/dist/server/form-input.js.map +1 -0
  189. package/dist/server/host.d.ts +2 -0
  190. package/dist/server/host.js +11 -0
  191. package/dist/server/host.js.map +1 -0
  192. package/dist/server/host.test.d.ts +1 -0
  193. package/dist/server/host.test.js +13 -0
  194. package/dist/server/host.test.js.map +1 -0
  195. package/dist/server/index.d.ts +20 -2
  196. package/dist/server/index.js +17 -1
  197. package/dist/server/index.js.map +1 -1
  198. package/dist/server/inferUtilityTypes.d.ts +6 -6
  199. package/dist/server/inferUtilityTypes.js.map +1 -1
  200. package/dist/server/mcp-errors.test.d.ts +1 -0
  201. package/dist/server/mcp-errors.test.js +229 -0
  202. package/dist/server/mcp-errors.test.js.map +1 -0
  203. package/dist/server/metric.d.ts +5 -3
  204. package/dist/server/metric.js +5 -5
  205. package/dist/server/metric.js.map +1 -1
  206. package/dist/server/middleware.d.ts +51 -13
  207. package/dist/server/middleware.js +33 -0
  208. package/dist/server/middleware.js.map +1 -1
  209. package/dist/server/middleware.test-d.js +1 -1
  210. package/dist/server/middleware.test-d.js.map +1 -1
  211. package/dist/server/middleware.test.js +242 -134
  212. package/dist/server/middleware.test.js.map +1 -1
  213. package/dist/server/register-tool.test.d.ts +1 -0
  214. package/dist/server/register-tool.test.js +230 -0
  215. package/dist/server/register-tool.test.js.map +1 -0
  216. package/dist/server/requestOrigin.d.ts +7 -0
  217. package/dist/server/requestOrigin.js +25 -0
  218. package/dist/server/requestOrigin.js.map +1 -0
  219. package/dist/server/server.d.ts +548 -56
  220. package/dist/server/server.js +685 -286
  221. package/dist/server/server.js.map +1 -1
  222. package/dist/server/skills-integration.test.d.ts +1 -0
  223. package/dist/server/skills-integration.test.js +86 -0
  224. package/dist/server/skills-integration.test.js.map +1 -0
  225. package/dist/server/skills.d.ts +27 -0
  226. package/dist/server/skills.js +188 -0
  227. package/dist/server/skills.js.map +1 -0
  228. package/dist/server/skills.test.d.ts +1 -0
  229. package/dist/server/skills.test.js +243 -0
  230. package/dist/server/skills.test.js.map +1 -0
  231. package/dist/server/templateHelper.d.ts +0 -5
  232. package/dist/server/templateHelper.js +3 -22
  233. package/dist/server/templateHelper.js.map +1 -1
  234. package/dist/server/templates.generated.d.ts +4 -0
  235. package/dist/server/templates.generated.js +43 -0
  236. package/dist/server/templates.generated.js.map +1 -0
  237. package/dist/server/tool-extra.test.d.ts +1 -0
  238. package/dist/server/tool-extra.test.js +167 -0
  239. package/dist/server/tool-extra.test.js.map +1 -0
  240. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  241. package/dist/server/tunnel-proxy-router.js +110 -0
  242. package/dist/server/tunnel-proxy-router.js.map +1 -0
  243. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  244. package/dist/server/tunnel-proxy-router.test.js +229 -0
  245. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  246. package/dist/server/view-name.test-d.d.ts +1 -0
  247. package/dist/server/view-name.test-d.js +8 -0
  248. package/dist/server/view-name.test-d.js.map +1 -0
  249. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  250. package/dist/server/view-resource-resolution.test.js +176 -0
  251. package/dist/server/view-resource-resolution.test.js.map +1 -0
  252. package/dist/server/viewsDevServer.js +4 -1
  253. package/dist/server/viewsDevServer.js.map +1 -1
  254. package/dist/test/utils.d.ts +9 -11
  255. package/dist/test/utils.js +220 -201
  256. package/dist/test/utils.js.map +1 -1
  257. package/dist/test/view.test.js +199 -113
  258. package/dist/test/view.test.js.map +1 -1
  259. package/dist/version.js +1 -3
  260. package/dist/version.js.map +1 -1
  261. package/dist/views/index.d.ts +10 -0
  262. package/dist/views/index.js +3 -0
  263. package/dist/views/index.js.map +1 -0
  264. package/dist/{web/plugin → views}/scan-views.d.ts +8 -0
  265. package/dist/{web/plugin → views}/scan-views.js +26 -8
  266. package/dist/views/scan-views.js.map +1 -0
  267. package/dist/views/scan-views.test.d.ts +1 -0
  268. package/dist/{web/plugin → views}/scan-views.test.js +33 -1
  269. package/dist/views/scan-views.test.js.map +1 -0
  270. package/dist/views/validate-view.d.ts +1 -0
  271. package/dist/{web/plugin → views}/validate-view.js +2 -2
  272. package/dist/views/validate-view.js.map +1 -0
  273. package/dist/views/validate-view.test.d.ts +1 -0
  274. package/dist/views/validate-view.test.js.map +1 -0
  275. package/dist/web/bridges/adaptor.d.ts +62 -0
  276. package/dist/web/bridges/adaptor.js +477 -0
  277. package/dist/web/bridges/adaptor.js.map +1 -0
  278. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  279. package/dist/web/bridges/adaptor.test.js +281 -0
  280. package/dist/web/bridges/adaptor.test.js.map +1 -0
  281. package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -1
  282. package/dist/web/bridges/apps-sdk/bridge.js +15 -3
  283. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  284. package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
  285. package/dist/web/bridges/apps-sdk/index.js +0 -1
  286. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  287. package/dist/web/bridges/apps-sdk/types.d.ts +10 -4
  288. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  289. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
  290. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
  291. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  292. package/dist/web/bridges/get-adaptor.d.ts +7 -0
  293. package/dist/web/bridges/get-adaptor.js +9 -7
  294. package/dist/web/bridges/get-adaptor.js.map +1 -1
  295. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  296. package/dist/web/bridges/get-adaptor.test.js +32 -0
  297. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  298. package/dist/web/bridges/index.js.map +1 -1
  299. package/dist/web/bridges/mcp-app/bridge.d.ts +15 -2
  300. package/dist/web/bridges/mcp-app/bridge.js +80 -7
  301. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  302. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  303. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  304. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  305. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  306. package/dist/web/bridges/mcp-app/index.js +0 -1
  307. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  308. package/dist/web/bridges/mcp-app/types.d.ts +19 -2
  309. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  310. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +13 -1
  311. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +12 -0
  312. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  313. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -1
  314. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  315. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  316. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  317. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  318. package/dist/web/bridges/types.d.ts +174 -11
  319. package/dist/web/bridges/types.js +14 -1
  320. package/dist/web/bridges/types.js.map +1 -1
  321. package/dist/web/bridges/types.test.d.ts +1 -0
  322. package/dist/web/bridges/types.test.js +19 -0
  323. package/dist/web/bridges/types.test.js.map +1 -0
  324. package/dist/web/bridges/use-host-context.d.ts +5 -0
  325. package/dist/web/bridges/use-host-context.js +5 -0
  326. package/dist/web/bridges/use-host-context.js.map +1 -1
  327. package/dist/web/components/modal-provider.d.ts +1 -1
  328. package/dist/web/components/modal-provider.js +4 -3
  329. package/dist/web/components/modal-provider.js.map +1 -1
  330. package/dist/web/create-store.d.ts +26 -0
  331. package/dist/web/create-store.js +35 -9
  332. package/dist/web/create-store.js.map +1 -1
  333. package/dist/web/create-store.test.js +24 -23
  334. package/dist/web/create-store.test.js.map +1 -1
  335. package/dist/web/data-llm.d.ts +35 -2
  336. package/dist/web/data-llm.js +34 -5
  337. package/dist/web/data-llm.js.map +1 -1
  338. package/dist/web/data-llm.test.js +48 -29
  339. package/dist/web/data-llm.test.js.map +1 -1
  340. package/dist/web/generate-helpers.d.ts +25 -19
  341. package/dist/web/generate-helpers.js +23 -17
  342. package/dist/web/generate-helpers.js.map +1 -1
  343. package/dist/web/generate-helpers.test-d.js +14 -12
  344. package/dist/web/generate-helpers.test-d.js.map +1 -1
  345. package/dist/web/generate-helpers.test.js +2 -2
  346. package/dist/web/generate-helpers.test.js.map +1 -1
  347. package/dist/web/helpers/state.d.ts +2 -2
  348. package/dist/web/helpers/state.js +11 -11
  349. package/dist/web/helpers/state.js.map +1 -1
  350. package/dist/web/helpers/state.test.js +9 -9
  351. package/dist/web/helpers/state.test.js.map +1 -1
  352. package/dist/web/hooks/index.d.ts +11 -2
  353. package/dist/web/hooks/index.js +11 -2
  354. package/dist/web/hooks/index.js.map +1 -1
  355. package/dist/web/hooks/openai-extensions.test.d.ts +1 -0
  356. package/dist/web/hooks/openai-extensions.test.js +107 -0
  357. package/dist/web/hooks/openai-extensions.test.js.map +1 -0
  358. package/dist/web/hooks/test/utils.d.ts +7 -2
  359. package/dist/web/hooks/test/utils.js +14 -3
  360. package/dist/web/hooks/test/utils.js.map +1 -1
  361. package/dist/web/hooks/use-call-tool.d.ts +47 -2
  362. package/dist/web/hooks/use-call-tool.js +43 -10
  363. package/dist/web/hooks/use-call-tool.js.map +1 -1
  364. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
  365. package/dist/web/hooks/use-call-tool.test.js +75 -29
  366. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  367. package/dist/web/hooks/use-deep-link.d.ts +22 -0
  368. package/dist/web/hooks/use-deep-link.js +34 -0
  369. package/dist/web/hooks/use-deep-link.js.map +1 -0
  370. package/dist/web/hooks/use-display-mode.d.ts +20 -0
  371. package/dist/web/hooks/use-display-mode.js +20 -0
  372. package/dist/web/hooks/use-display-mode.js.map +1 -1
  373. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
  374. package/dist/web/hooks/use-display-mode.test.js +57 -21
  375. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  376. package/dist/web/hooks/use-download.d.ts +3 -0
  377. package/dist/web/hooks/use-download.js +7 -0
  378. package/dist/web/hooks/use-download.js.map +1 -0
  379. package/dist/web/hooks/use-download.test.d.ts +1 -0
  380. package/dist/web/hooks/use-download.test.js +103 -0
  381. package/dist/web/hooks/use-download.test.js.map +1 -0
  382. package/dist/web/hooks/use-file-resource.d.ts +37 -0
  383. package/dist/web/hooks/use-file-resource.js +98 -0
  384. package/dist/web/hooks/use-file-resource.js.map +1 -0
  385. package/dist/web/hooks/use-file-resource.test.d.ts +1 -0
  386. package/dist/web/hooks/use-file-resource.test.js +65 -0
  387. package/dist/web/hooks/use-file-resource.test.js.map +1 -0
  388. package/dist/web/hooks/use-files.d.ts +32 -0
  389. package/dist/web/hooks/use-files.js +32 -0
  390. package/dist/web/hooks/use-files.js.map +1 -1
  391. package/dist/web/hooks/use-files.test.js +11 -3
  392. package/dist/web/hooks/use-files.test.js.map +1 -1
  393. package/dist/web/hooks/use-host.d.ts +44 -0
  394. package/dist/web/hooks/use-host.js +45 -0
  395. package/dist/web/hooks/use-host.js.map +1 -0
  396. package/dist/web/hooks/use-host.test.d.ts +1 -0
  397. package/dist/web/hooks/use-host.test.js +59 -0
  398. package/dist/web/hooks/use-host.test.js.map +1 -0
  399. package/dist/web/hooks/use-model-context.d.ts +44 -0
  400. package/dist/web/hooks/use-model-context.js +63 -0
  401. package/dist/web/hooks/use-model-context.js.map +1 -0
  402. package/dist/web/hooks/use-open-external.d.ts +17 -0
  403. package/dist/web/hooks/use-open-external.js +16 -0
  404. package/dist/web/hooks/use-open-external.js.map +1 -1
  405. package/dist/web/hooks/use-open-external.test.js +15 -5
  406. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  407. package/dist/web/hooks/use-open-file.d.ts +20 -0
  408. package/dist/web/hooks/use-open-file.js +25 -0
  409. package/dist/web/hooks/use-open-file.js.map +1 -0
  410. package/dist/web/hooks/use-register-view-tool.d.ts +37 -0
  411. package/dist/web/hooks/use-register-view-tool.js +50 -0
  412. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  413. package/dist/web/hooks/use-request-close.d.ts +16 -0
  414. package/dist/web/hooks/use-request-close.js +21 -0
  415. package/dist/web/hooks/use-request-close.js.map +1 -0
  416. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  417. package/dist/web/hooks/use-request-close.test.js +47 -0
  418. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  419. package/dist/web/hooks/use-request-modal.d.ts +16 -1
  420. package/dist/web/hooks/use-request-modal.js +19 -4
  421. package/dist/web/hooks/use-request-modal.js.map +1 -1
  422. package/dist/web/hooks/use-request-modal.test.js +12 -2
  423. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  424. package/dist/web/hooks/use-request-size.d.ts +20 -0
  425. package/dist/web/hooks/use-request-size.js +24 -0
  426. package/dist/web/hooks/use-request-size.js.map +1 -0
  427. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  428. package/dist/web/hooks/use-request-size.test.js +47 -0
  429. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  430. package/dist/web/hooks/use-send-follow-up-message.d.ts +25 -1
  431. package/dist/web/hooks/use-send-follow-up-message.js +25 -2
  432. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  433. package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
  434. package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
  435. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
  436. package/dist/web/hooks/use-set-open-in-app-url.test.js +26 -12
  437. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  438. package/dist/web/hooks/use-tool-info.d.ts +46 -14
  439. package/dist/web/hooks/use-tool-info.js +29 -7
  440. package/dist/web/hooks/use-tool-info.js.map +1 -1
  441. package/dist/web/hooks/use-tool-info.test-d.js +11 -34
  442. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  443. package/dist/web/hooks/use-tool-info.test.js +42 -37
  444. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  445. package/dist/web/hooks/use-user.d.ts +5 -2
  446. package/dist/web/hooks/use-user.js +6 -3
  447. package/dist/web/hooks/use-user.js.map +1 -1
  448. package/dist/web/hooks/use-user.test.js +85 -37
  449. package/dist/web/hooks/use-user.test.js.map +1 -1
  450. package/dist/web/hooks/use-view-state.d.ts +25 -0
  451. package/dist/web/hooks/use-view-state.js +42 -0
  452. package/dist/web/hooks/use-view-state.js.map +1 -0
  453. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  454. package/dist/web/hooks/{use-widget-state.test.js → use-view-state.test.js} +56 -21
  455. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  456. package/dist/web/hooks/use-viewport.d.ts +20 -0
  457. package/dist/web/hooks/use-viewport.js +21 -0
  458. package/dist/web/hooks/use-viewport.js.map +1 -0
  459. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  460. package/dist/web/hooks/use-viewport.test.js +109 -0
  461. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  462. package/dist/web/index.d.ts +1 -3
  463. package/dist/web/index.js +1 -2
  464. package/dist/web/index.js.map +1 -1
  465. package/dist/web/mount-view.d.ts +21 -0
  466. package/dist/web/mount-view.js +43 -0
  467. package/dist/web/mount-view.js.map +1 -0
  468. package/dist/web/proxy.js.map +1 -1
  469. package/dist/web/types.d.ts +4 -0
  470. package/dist/web/types.js.map +1 -1
  471. package/package.json +46 -28
  472. package/dist/server/templates/development.hbs +0 -12
  473. package/dist/server/templates/production.hbs +0 -6
  474. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -24
  475. package/dist/web/bridges/apps-sdk/adaptor.js +0 -87
  476. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  477. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -48
  478. package/dist/web/bridges/mcp-app/adaptor.js +0 -268
  479. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
  480. package/dist/web/hooks/use-layout.d.ts +0 -22
  481. package/dist/web/hooks/use-layout.js +0 -23
  482. package/dist/web/hooks/use-layout.js.map +0 -1
  483. package/dist/web/hooks/use-layout.test.js +0 -96
  484. package/dist/web/hooks/use-layout.test.js.map +0 -1
  485. package/dist/web/hooks/use-widget-state.d.ts +0 -4
  486. package/dist/web/hooks/use-widget-state.js +0 -32
  487. package/dist/web/hooks/use-widget-state.js.map +0 -1
  488. package/dist/web/hooks/use-widget-state.test.js.map +0 -1
  489. package/dist/web/mount-widget.d.ts +0 -1
  490. package/dist/web/mount-widget.js +0 -27
  491. package/dist/web/mount-widget.js.map +0 -1
  492. package/dist/web/plugin/data-llm.test.js +0 -81
  493. package/dist/web/plugin/data-llm.test.js.map +0 -1
  494. package/dist/web/plugin/plugin.d.ts +0 -5
  495. package/dist/web/plugin/plugin.js +0 -141
  496. package/dist/web/plugin/plugin.js.map +0 -1
  497. package/dist/web/plugin/scan-views.js.map +0 -1
  498. package/dist/web/plugin/scan-views.test.js.map +0 -1
  499. package/dist/web/plugin/transform-data-llm.d.ts +0 -12
  500. package/dist/web/plugin/transform-data-llm.js +0 -96
  501. package/dist/web/plugin/transform-data-llm.js.map +0 -1
  502. package/dist/web/plugin/transform-data-llm.test.js +0 -81
  503. package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
  504. package/dist/web/plugin/validate-view.d.ts +0 -1
  505. package/dist/web/plugin/validate-view.js.map +0 -1
  506. package/dist/web/plugin/validate-view.test.js.map +0 -1
  507. /package/dist/{web/hooks/use-layout.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  508. /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  509. /package/dist/{web/plugin/data-llm.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
  510. /package/dist/{web/plugin/scan-views.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
  511. /package/dist/{web/plugin/transform-data-llm.test.d.ts → cli/tunnel.test.d.ts} +0 -0
  512. /package/dist/{web/plugin/validate-view.test.d.ts → context-warnings.test.d.ts} +0 -0
  513. /package/dist/{web/plugin → views}/validate-view.test.js +0 -0
@@ -1,19 +1,34 @@
1
1
  import crypto from "node:crypto";
2
+ import { Client, InMemoryTransport } from "@modelcontextprotocol/client";
2
3
  import { afterEach, beforeEach, describe, expect, it, vi, } from "vitest";
4
+ import { TOOL_OUTPUT_WARNING_TOKENS } from "../context-warnings.js";
5
+ import { Skybridge } from "../server/app.js";
3
6
  import { createMockExtra, createMockMcpServer, resetTestEnv, setTestEnv, } from "./utils.js";
4
7
  const mockManifest = {
5
- "skybridge:view:my-widget": {
6
- file: "assets/my-widget-abc123.js",
7
- name: "my-widget",
8
+ "skybridge:view:my-view": {
9
+ file: "assets/my-view-abc123.js",
10
+ name: "my-view",
8
11
  isEntry: true,
9
12
  },
10
- "skybridge:view:folder-widget": {
11
- file: "assets/folder-widget-def456.js",
12
- name: "folder-widget",
13
+ "skybridge:view:folder-view": {
14
+ file: "assets/folder-view-def456.js",
15
+ name: "folder-view",
13
16
  isEntry: true,
14
17
  },
15
18
  "style.css": { file: "style.css" },
16
19
  };
20
+ // Mirrors `McpServer.computeViewVersionParam`. Tests recompute the expected
21
+ // hash from the mocked manifest so they don't hardcode digest output.
22
+ function expectedVersionParam(viewFile, styleFile) {
23
+ const hash = crypto
24
+ .createHash("sha256")
25
+ .update(viewFile)
26
+ .update("\0")
27
+ .update(styleFile)
28
+ .digest("hex")
29
+ .slice(0, 8);
30
+ return `?v=${hash}`;
31
+ }
17
32
  const actual = vi.hoisted(() => require("node:fs"));
18
33
  vi.mock("node:fs", () => {
19
34
  const readFileSyncImpl = (path, ...args) => {
@@ -45,10 +60,10 @@ describe("McpServer.registerTool (unified API)", () => {
45
60
  it("should generate correct HTML for development mode", async () => {
46
61
  setTestEnv({ NODE_ENV: "development" });
47
62
  server.registerTool({
48
- name: "my-widget",
63
+ name: "my-view",
49
64
  description: "Test tool",
50
65
  view: {
51
- component: "my-widget",
66
+ component: "my-view",
52
67
  description: "Test view",
53
68
  },
54
69
  }, vi.fn());
@@ -59,20 +74,24 @@ describe("McpServer.registerTool (unified API)", () => {
59
74
  const serverUrl = `http://${host}`;
60
75
  const hmrUrl = `ws://${host}`;
61
76
  const mockExtra = createMockExtra(host);
62
- const result = await appsSdkResourceCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), mockExtra);
77
+ const result = await appsSdkResourceCallback(new URL("ui://views/ext-apps/my-view.html"), mockExtra);
63
78
  expect(mockRegisterTool).toHaveBeenCalled();
64
79
  expect(result).toEqual({
65
80
  contents: [
66
81
  {
67
- uri: "ui://widgets/apps-sdk/my-widget.html",
68
- mimeType: "text/html+skybridge",
82
+ uri: "ui://views/ext-apps/my-view.html",
83
+ mimeType: "text/html;profile=mcp-app",
69
84
  text: expect.stringContaining('<div id="root"></div>'),
70
85
  _meta: {
71
- "openai/widgetCSP": {
72
- resource_domains: [serverUrl],
73
- 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",
74
94
  },
75
- "openai/widgetDomain": serverUrl,
76
95
  "openai/widgetDescription": "Test view",
77
96
  },
78
97
  },
@@ -80,15 +99,15 @@ describe("McpServer.registerTool (unified API)", () => {
80
99
  });
81
100
  expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/@react-refresh`);
82
101
  expect(result.contents[0]?.text).toContain(`${serverUrl}/@vite/client`);
83
- expect(result.contents[0]?.text).toContain(`${serverUrl}/_skybridge/view/my-widget`);
102
+ expect(result.contents[0]?.text).toContain(`${serverUrl}/_skybridge/view/my-view`);
84
103
  });
85
104
  it("should generate correct HTML for production mode", async () => {
86
105
  setTestEnv({ NODE_ENV: "production" });
87
106
  server.registerTool({
88
- name: "my-widget",
107
+ name: "my-view",
89
108
  description: "Test tool",
90
109
  view: {
91
- component: "my-widget",
110
+ component: "my-view",
92
111
  description: "Test view",
93
112
  },
94
113
  }, vi.fn());
@@ -98,19 +117,24 @@ describe("McpServer.registerTool (unified API)", () => {
98
117
  const host = "myapp.com";
99
118
  const serverUrl = `https://${host}`;
100
119
  const mockExtra = createMockExtra(host);
101
- const result = await appsSdkResourceCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), mockExtra);
120
+ const versionedUri = `ui://views/ext-apps/my-view.html${expectedVersionParam("assets/my-view-abc123.js", "style.css")}`;
121
+ const result = await appsSdkResourceCallback(new URL(versionedUri), mockExtra);
102
122
  expect(result).toEqual({
103
123
  contents: [
104
124
  {
105
- uri: "ui://widgets/apps-sdk/my-widget.html",
106
- mimeType: "text/html+skybridge",
125
+ uri: versionedUri,
126
+ mimeType: "text/html;profile=mcp-app",
107
127
  text: expect.stringContaining('<div id="root"></div>'),
108
128
  _meta: {
109
- "openai/widgetCSP": {
110
- resource_domains: [serverUrl],
111
- connect_domains: [serverUrl],
129
+ ui: {
130
+ csp: {
131
+ resourceDomains: [serverUrl],
132
+ connectDomains: [serverUrl],
133
+ baseUriDomains: [serverUrl],
134
+ },
135
+ domain: serverUrl,
136
+ description: "Test view",
112
137
  },
113
- "openai/widgetDomain": serverUrl,
114
138
  "openai/widgetDescription": "Test view",
115
139
  },
116
140
  },
@@ -118,18 +142,18 @@ describe("McpServer.registerTool (unified API)", () => {
118
142
  });
119
143
  expect(result.contents[0]?.text).not.toContain(`${serverUrl}/assets/@react-refresh`);
120
144
  expect(result.contents[0]?.text).not.toContain(`${serverUrl}@vite/client`);
121
- expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/assets/my-widget-abc123.js`);
145
+ expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/assets/my-view-abc123.js`);
122
146
  expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/style.css`);
123
147
  });
124
148
  it("should prefer x-alpic-forwarded-url when hashing Claude view domains", async () => {
125
149
  setTestEnv({ NODE_ENV: "production" });
126
150
  server.registerTool({
127
- name: "my-widget",
151
+ name: "my-view",
128
152
  description: "Test tool",
129
- view: { component: "my-widget", description: "Test view" },
153
+ view: { component: "my-view", description: "Test view" },
130
154
  }, vi.fn());
131
155
  const extAppsResourceCallback = mockRegisterResource.mock
132
- .calls[1]?.[3];
156
+ .calls[0]?.[3];
133
157
  expect(extAppsResourceCallback).toBeDefined();
134
158
  const forwardedUrl = "https://everything-3a2c1264.staging.alpic.live/mcp?foo=bar";
135
159
  const expectedDomain = `${crypto
@@ -137,7 +161,7 @@ describe("McpServer.registerTool (unified API)", () => {
137
161
  .update(forwardedUrl)
138
162
  .digest("hex")
139
163
  .slice(0, 32)}.claudemcpcontent.com`;
140
- const result = await extAppsResourceCallback(new URL("ui://widgets/ext-apps/my-widget.html"), createMockExtra("localhost:3000", {
164
+ const result = await extAppsResourceCallback(new URL(`ui://views/ext-apps/my-view.html${expectedVersionParam("assets/my-view-abc123.js", "style.css")}`), createMockExtra("localhost:3000", {
141
165
  headers: {
142
166
  "user-agent": "Claude-User",
143
167
  "x-alpic-forwarded-url": forwardedUrl,
@@ -154,52 +178,30 @@ describe("McpServer.registerTool (unified API)", () => {
154
178
  description: "Test view",
155
179
  domain: expectedDomain,
156
180
  },
181
+ "openai/widgetDescription": "Test view",
157
182
  });
158
183
  });
159
- 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 () => {
160
185
  server.registerTool({
161
- name: "my-widget",
186
+ name: "my-view",
162
187
  description: "Test tool",
163
188
  view: {
164
- component: "my-widget",
189
+ component: "my-view",
165
190
  description: "Test view",
166
191
  prefersBorder: true,
167
192
  },
168
193
  }, vi.fn());
169
- expect(mockRegisterResource).toHaveBeenCalledTimes(2);
170
- const appsSdkCallback = mockRegisterResource.mock
194
+ expect(mockRegisterResource).toHaveBeenCalledTimes(1);
195
+ const resourceCallback = mockRegisterResource.mock
171
196
  .calls[0]?.[3];
172
197
  const host = "localhost:3000";
173
198
  const serverUrl = `http://${host}`;
174
199
  const hmrUrl = `ws://${host}`;
175
- const appsSdkResult = await appsSdkCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), createMockExtra(host));
176
- expect(appsSdkResult).toEqual({
177
- contents: [
178
- {
179
- uri: "ui://widgets/apps-sdk/my-widget.html",
180
- mimeType: "text/html+skybridge",
181
- text: expect.stringContaining('<div id="root"></div>'),
182
- _meta: {
183
- "openai/widgetCSP": {
184
- resource_domains: [serverUrl],
185
- connect_domains: [serverUrl, hmrUrl],
186
- },
187
- "openai/widgetDomain": serverUrl,
188
- "openai/widgetDescription": "Test view",
189
- "openai/widgetPrefersBorder": true,
190
- },
191
- },
192
- ],
193
- });
194
- expect(appsSdkResult.contents[0]?.text).toContain('window.skybridge = { hostType: "apps-sdk", serverUrl: "http://localhost:3000" };');
195
- const extAppsResourceCallback = mockRegisterResource.mock
196
- .calls[1]?.[3];
197
- expect(extAppsResourceCallback).toBeDefined();
198
- const extAppsResult = await extAppsResourceCallback(new URL("ui://widgets/ext-apps/my-widget.html"), createMockExtra(host));
199
- expect(extAppsResult).toEqual({
200
+ const result = await resourceCallback(new URL("ui://views/ext-apps/my-view.html"), createMockExtra(host));
201
+ expect(result).toEqual({
200
202
  contents: [
201
203
  {
202
- uri: "ui://widgets/ext-apps/my-widget.html",
204
+ uri: "ui://views/ext-apps/my-view.html",
203
205
  mimeType: "text/html;profile=mcp-app",
204
206
  text: expect.stringContaining('<div id="root"></div>'),
205
207
  _meta: {
@@ -213,60 +215,78 @@ describe("McpServer.registerTool (unified API)", () => {
213
215
  description: "Test view",
214
216
  prefersBorder: true,
215
217
  },
218
+ "openai/widgetDescription": "Test view",
216
219
  },
217
220
  },
218
221
  ],
219
222
  });
220
- expect(extAppsResult.contents[0]?.text).toContain('window.skybridge = { hostType: "mcp-app", serverUrl: "http://localhost:3000" };');
223
+ expect(result.contents[0]?.text).toContain('window.skybridge = { serverUrl: "http://localhost:3000" };');
221
224
  });
222
- it("should register tool with ui.resourceUri metadata", async () => {
225
+ it("should advertise the single resource via ui.resourceUri only (no openai/outputTemplate)", async () => {
223
226
  server.registerTool({
224
- name: "my-widget",
227
+ name: "my-view",
225
228
  description: "Test tool",
226
- view: { component: "my-widget", description: "Test view" },
229
+ view: { component: "my-view", description: "Test view" },
227
230
  }, vi.fn());
228
- expect(mockRegisterTool).toHaveBeenCalledTimes(1);
229
- const toolCallArgs = mockRegisterTool.mock.calls[0];
230
- const toolConfig = toolCallArgs?.[1];
231
- expect(toolConfig._meta).toHaveProperty("ui");
232
- expect(toolConfig._meta?.ui).toEqual({
233
- resourceUri: "ui://widgets/ext-apps/my-widget.html",
234
- });
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();
235
236
  });
236
- it("should register tool with openai/outputTemplate when apps-sdk only", async () => {
237
+ it("should not version view URIs in development", () => {
237
238
  server.registerTool({
238
- name: "my-widget",
239
+ name: "my-view",
239
240
  description: "Test tool",
240
- view: {
241
- component: "my-widget",
242
- description: "Test view",
243
- hosts: ["apps-sdk"],
244
- },
241
+ view: { component: "my-view", description: "Test view" },
245
242
  }, vi.fn());
246
- expect(mockRegisterTool).toHaveBeenCalledTimes(1);
247
- const toolCallArgs = mockRegisterTool.mock.calls[0];
248
- const toolConfig = toolCallArgs?.[1];
249
- expect(toolConfig._meta).not.toHaveProperty("ui");
250
- expect(toolConfig._meta?.["openai/outputTemplate"]).toBe("ui://widgets/apps-sdk/my-widget.html");
243
+ const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
244
+ expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
245
+ expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/my-view.html");
246
+ // The URI registered with the resource handler must match ui.resourceUri
247
+ // exactly so the SDK can resolve `resources/read` requests.
248
+ expect(mockRegisterResource.mock.calls[0]?.[1]).toBe("ui://views/ext-apps/my-view.html");
251
249
  });
252
- it("should register tool with ui.resourceUri only when mcp-app only", async () => {
250
+ it("should append a stable content hash to view URIs in production", () => {
251
+ setTestEnv({ NODE_ENV: "production" });
253
252
  server.registerTool({
254
- name: "my-widget",
253
+ name: "my-view",
255
254
  description: "Test tool",
256
- view: {
257
- component: "my-widget",
258
- description: "Test view",
259
- hosts: ["mcp-app"],
260
- },
255
+ view: { component: "my-view", description: "Test view" },
261
256
  }, vi.fn());
262
- expect(mockRegisterTool).toHaveBeenCalledTimes(1);
263
- const toolCallArgs = mockRegisterTool.mock.calls[0];
264
- const toolConfig = toolCallArgs?.[1];
265
- expect(toolConfig._meta).toHaveProperty("ui");
266
- expect(toolConfig._meta?.ui).toEqual({
267
- resourceUri: "ui://widgets/ext-apps/my-widget.html",
268
- });
257
+ const expected = expectedVersionParam("assets/my-view-abc123.js", "style.css");
258
+ const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
269
259
  expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
260
+ expect(toolConfig._meta?.ui?.resourceUri).toBe(`ui://views/ext-apps/my-view.html${expected}`);
261
+ expect(mockRegisterResource.mock.calls[0]?.[1]).toBe(`ui://views/ext-apps/my-view.html${expected}`);
262
+ });
263
+ it("should produce different version params for views with different bundles", () => {
264
+ setTestEnv({ NODE_ENV: "production" });
265
+ server.registerTool({
266
+ name: "my-view",
267
+ description: "First tool",
268
+ view: { component: "my-view" },
269
+ }, vi.fn());
270
+ server.registerTool({
271
+ name: "folder-view",
272
+ description: "Second tool",
273
+ view: { component: "folder-view" },
274
+ }, vi.fn());
275
+ const myviewTemplate = mockRegisterTool.mock.calls[0][1]._meta?.ui?.resourceUri;
276
+ const folderviewTemplate = mockRegisterTool.mock.calls[1][1]._meta?.ui?.resourceUri;
277
+ expect(myviewTemplate).not.toEqual(folderviewTemplate);
278
+ expect(myviewTemplate).toMatch(/\?v=[0-9a-f]{8}$/);
279
+ expect(folderviewTemplate).toMatch(/\?v=[0-9a-f]{8}$/);
280
+ });
281
+ it("should fall back to bare URI in production when manifest is missing", () => {
282
+ setTestEnv({ NODE_ENV: "production" });
283
+ server.registerTool({
284
+ name: "unknown-view",
285
+ description: "Test tool",
286
+ view: { component: "unknown-view" },
287
+ }, vi.fn());
288
+ const toolConfig = mockRegisterTool.mock.calls[0]?.[1];
289
+ expect(toolConfig._meta?.ui?.resourceUri).toBe("ui://views/ext-apps/unknown-view.html");
270
290
  });
271
291
  it("should inject viewUUID into _meta of tool callback results", async () => {
272
292
  const mockToolCallback = vi.fn().mockResolvedValue({
@@ -274,9 +294,9 @@ describe("McpServer.registerTool (unified API)", () => {
274
294
  structuredContent: { data: "test" },
275
295
  });
276
296
  server.registerTool({
277
- name: "my-widget",
297
+ name: "my-view",
278
298
  description: "Test tool",
279
- view: { component: "my-widget", description: "Test view" },
299
+ view: { component: "my-view", description: "Test view" },
280
300
  }, mockToolCallback);
281
301
  const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
282
302
  expect(wrappedCallback).toBeDefined();
@@ -286,6 +306,21 @@ describe("McpServer.registerTool (unified API)", () => {
286
306
  expect(typeof result._meta?.viewUUID).toBe("string");
287
307
  expect(result._meta?.viewUUID).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
288
308
  });
309
+ it("warns when a tool callback returns large model-visible output", async () => {
310
+ const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
311
+ server.registerTool({ name: "large-output", description: "Test tool" }, vi.fn().mockResolvedValue({
312
+ content: [
313
+ {
314
+ type: "text",
315
+ text: "x".repeat(TOOL_OUTPUT_WARNING_TOKENS * 4),
316
+ },
317
+ ],
318
+ }));
319
+ const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
320
+ await wrappedCallback({}, {});
321
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Tool "large-output" returned'));
322
+ warnSpy.mockRestore();
323
+ });
289
324
  it("should preserve existing _meta when injecting viewUUID", async () => {
290
325
  const mockToolCallback = vi.fn().mockResolvedValue({
291
326
  content: [{ type: "text", text: "result" }],
@@ -293,9 +328,9 @@ describe("McpServer.registerTool (unified API)", () => {
293
328
  _meta: { requestId: "req-123", cached: true },
294
329
  });
295
330
  server.registerTool({
296
- name: "my-widget",
331
+ name: "my-view",
297
332
  description: "Test tool",
298
- view: { component: "my-widget", description: "Test view" },
333
+ view: { component: "my-view", description: "Test view" },
299
334
  }, mockToolCallback);
300
335
  const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
301
336
  const result = await wrappedCallback({}, {});
@@ -309,9 +344,9 @@ describe("McpServer.registerTool (unified API)", () => {
309
344
  structuredContent: {},
310
345
  });
311
346
  server.registerTool({
312
- name: "my-widget",
347
+ name: "my-view",
313
348
  description: "Test tool",
314
- view: { component: "my-widget", description: "Test view" },
349
+ view: { component: "my-view", description: "Test view" },
315
350
  }, mockToolCallback);
316
351
  const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
317
352
  const result1 = await wrappedCallback({}, {});
@@ -404,11 +439,12 @@ describe("McpServer.registerTool (unified API)", () => {
404
439
  const host = "localhost:3000";
405
440
  const serverUrl = `http://${host}`;
406
441
  const hmrUrl = `ws://${host}`;
407
- const result = await appsSdkCallback(new URL("ui://widgets/apps-sdk/csp-tool.html"), createMockExtra(host));
442
+ const result = await appsSdkCallback(new URL("ui://views/ext-apps/csp-tool.html"), createMockExtra(host));
408
443
  const meta = result.contents[0]?._meta;
409
- expect(meta["openai/widgetCSP"]).toEqual({
410
- resource_domains: [serverUrl, "https://cdn.example.com"],
411
- 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],
412
448
  });
413
449
  });
414
450
  it("should let view._meta override framework-computed keys", async () => {
@@ -420,18 +456,20 @@ describe("McpServer.registerTool (unified API)", () => {
420
456
  description: "Test view",
421
457
  csp: { connectDomains: ["https://api.x.com"] },
422
458
  _meta: {
423
- "openai/widgetCSP": {
424
- connect_domains: ["https://api.y.com"],
459
+ ui: {
460
+ csp: {
461
+ connectDomains: ["https://api.y.com"],
462
+ },
425
463
  },
426
464
  },
427
465
  },
428
466
  }, vi.fn());
429
467
  const appsSdkCallback = mockRegisterResource.mock
430
468
  .calls[0]?.[3];
431
- const result = await appsSdkCallback(new URL("ui://widgets/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"));
432
470
  const meta = result.contents[0]?._meta;
433
- expect(meta["openai/widgetCSP"]).toEqual({
434
- connect_domains: ["https://api.y.com"],
471
+ expect(meta.ui?.csp).toEqual({
472
+ connectDomains: ["https://api.y.com"],
435
473
  });
436
474
  });
437
475
  it("should pass user _meta keys through to tool config", () => {
@@ -451,4 +489,52 @@ describe("McpServer.registerTool (unified API)", () => {
451
489
  expect(toolConfig._meta?.["acme.com/category"]).toBe("utility");
452
490
  });
453
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 app = new Skybridge({
497
+ name: "test",
498
+ version: "1.0.0",
499
+ handler: (server) => server.registerTool({
500
+ name: "start",
501
+ description: "Start",
502
+ view: {
503
+ component: "my-view",
504
+ description: "Onboarding deck",
505
+ domain: "skybridge.tech",
506
+ csp: {
507
+ resourceDomains: ["https://fonts.googleapis.com"],
508
+ redirectDomains: ["https://docs.skybridge.tech"],
509
+ },
510
+ },
511
+ }, vi.fn().mockResolvedValue({
512
+ content: [{ type: "text", text: "ok" }],
513
+ structuredContent: {},
514
+ })),
515
+ });
516
+ const instance = await app.createServerInstance();
517
+ const client = new Client({ name: "test-client", version: "1.0.0" });
518
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
519
+ await instance.connect(serverTransport);
520
+ await client.connect(clientTransport);
521
+ const { resources } = await client.listResources();
522
+ await client.close();
523
+ await instance.close();
524
+ const appsSdk = resources.find((r) => r.uri.includes("apps-sdk"));
525
+ const extApps = resources.find((r) => r.uri.includes("ext-apps"));
526
+ expect(appsSdk).toBeUndefined();
527
+ expect(extApps?._meta).toBeDefined();
528
+ const extUi = extApps._meta?.ui;
529
+ expect(extUi?.csp?.connectDomains?.length).toBeGreaterThan(0);
530
+ expect(extUi?.csp?.resourceDomains).toContain("https://fonts.googleapis.com");
531
+ expect(extUi?.domain).toBe("skybridge.tech");
532
+ const meta = extApps?._meta;
533
+ expect(meta["openai/widgetDescription"]).toBe("Onboarding deck");
534
+ expect(meta["openai/widgetCSP"]?.redirect_domains).toEqual([
535
+ "https://docs.skybridge.tech",
536
+ ]);
537
+ expect(meta.ui?.csp).not.toHaveProperty("redirectDomains");
538
+ });
539
+ });
454
540
  //# sourceMappingURL=view.test.js.map