skybridge 0.0.0-dev.b9f65be → 0.0.0-dev.b9f85b3

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 (369) hide show
  1. package/README.md +3 -0
  2. package/dist/cli/build-helpers.d.ts +7 -1
  3. package/dist/cli/build-helpers.js +58 -6
  4. package/dist/cli/build-helpers.js.map +1 -1
  5. package/dist/cli/build-helpers.test.js +89 -1
  6. package/dist/cli/build-helpers.test.js.map +1 -1
  7. package/dist/cli/build-steps.d.ts +2 -0
  8. package/dist/cli/build-steps.js +73 -0
  9. package/dist/cli/build-steps.js.map +1 -0
  10. package/dist/cli/build-steps.test.js +52 -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/resolve-skybridge-config.d.ts +5 -0
  17. package/dist/cli/{resolve-views-dir.js → resolve-skybridge-config.js} +4 -3
  18. package/dist/cli/resolve-skybridge-config.js.map +1 -0
  19. package/dist/cli/run-plain.d.ts +18 -0
  20. package/dist/cli/run-plain.js +89 -0
  21. package/dist/cli/run-plain.js.map +1 -0
  22. package/dist/cli/use-execute-steps.d.ts +1 -1
  23. package/dist/cli/use-nodemon.d.ts +14 -0
  24. package/dist/cli/use-nodemon.js +81 -62
  25. package/dist/cli/use-nodemon.js.map +1 -1
  26. package/dist/cli/use-typescript-check.d.ts +8 -2
  27. package/dist/cli/use-typescript-check.js +70 -67
  28. package/dist/cli/use-typescript-check.js.map +1 -1
  29. package/dist/commands/build.d.ts +0 -3
  30. package/dist/commands/build.js +5 -56
  31. package/dist/commands/build.js.map +1 -1
  32. package/dist/commands/dev.d.ts +1 -0
  33. package/dist/commands/dev.js +35 -3
  34. package/dist/commands/dev.js.map +1 -1
  35. package/dist/commands/start.js +7 -1
  36. package/dist/commands/start.js.map +1 -1
  37. package/dist/context-warnings.d.ts +5 -0
  38. package/dist/context-warnings.js +31 -0
  39. package/dist/context-warnings.js.map +1 -0
  40. package/dist/context-warnings.test.js +28 -0
  41. package/dist/context-warnings.test.js.map +1 -0
  42. package/dist/server/app.d.ts +175 -0
  43. package/dist/server/app.js +275 -0
  44. package/dist/server/app.js.map +1 -0
  45. package/dist/server/auth/discovery.d.ts +33 -0
  46. package/dist/server/auth/discovery.js +56 -0
  47. package/dist/server/auth/discovery.js.map +1 -0
  48. package/dist/server/auth/discovery.test.js +93 -0
  49. package/dist/server/auth/discovery.test.js.map +1 -0
  50. package/dist/server/auth/index.d.ts +30 -0
  51. package/dist/server/auth/index.js +2 -0
  52. package/dist/server/auth/index.js.map +1 -0
  53. package/dist/server/auth/providers/auth0.d.ts +40 -0
  54. package/dist/server/auth/providers/auth0.js +31 -0
  55. package/dist/server/auth/providers/auth0.js.map +1 -0
  56. package/dist/server/auth/providers/auth0.test.js +50 -0
  57. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  58. package/dist/server/auth/providers/authplane.d.ts +49 -0
  59. package/dist/server/auth/providers/authplane.js +57 -0
  60. package/dist/server/auth/providers/authplane.js.map +1 -0
  61. package/dist/server/auth/providers/authplane.test.d.ts +1 -0
  62. package/dist/server/auth/providers/authplane.test.js +140 -0
  63. package/dist/server/auth/providers/authplane.test.js.map +1 -0
  64. package/dist/server/auth/providers/clerk.d.ts +51 -0
  65. package/dist/server/auth/providers/clerk.js +19 -0
  66. package/dist/server/auth/providers/clerk.js.map +1 -0
  67. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  68. package/dist/server/auth/providers/clerk.test.js +30 -0
  69. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  70. package/dist/server/auth/providers/custom.d.ts +40 -0
  71. package/dist/server/auth/providers/custom.js +56 -0
  72. package/dist/server/auth/providers/custom.js.map +1 -0
  73. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  74. package/dist/server/auth/providers/custom.test.js +158 -0
  75. package/dist/server/auth/providers/custom.test.js.map +1 -0
  76. package/dist/server/auth/providers/descope.d.ts +44 -0
  77. package/dist/server/auth/providers/descope.js +44 -0
  78. package/dist/server/auth/providers/descope.js.map +1 -0
  79. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  80. package/dist/server/auth/providers/descope.test.js +62 -0
  81. package/dist/server/auth/providers/descope.test.js.map +1 -0
  82. package/dist/server/auth/providers/shared.d.ts +2 -0
  83. package/dist/server/auth/providers/shared.js +6 -0
  84. package/dist/server/auth/providers/shared.js.map +1 -0
  85. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  86. package/dist/server/auth/providers/shared.test.js +10 -0
  87. package/dist/server/auth/providers/shared.test.js.map +1 -0
  88. package/dist/server/auth/providers/stytch.d.ts +25 -0
  89. package/dist/server/auth/providers/stytch.js +16 -0
  90. package/dist/server/auth/providers/stytch.js.map +1 -0
  91. package/dist/server/auth/providers/verify-spy.d.ts +12 -0
  92. package/dist/server/auth/providers/verify-spy.js +21 -0
  93. package/dist/server/auth/providers/verify-spy.js.map +1 -0
  94. package/dist/server/auth/providers/workos.d.ts +33 -0
  95. package/dist/server/auth/providers/workos.js +15 -0
  96. package/dist/server/auth/providers/workos.js.map +1 -0
  97. package/dist/server/auth/security-schemes.d.ts +23 -0
  98. package/dist/server/auth/security-schemes.js +64 -0
  99. package/dist/server/auth/security-schemes.js.map +1 -0
  100. package/dist/server/auth/security-schemes.test.d.ts +1 -0
  101. package/dist/server/auth/security-schemes.test.js +99 -0
  102. package/dist/server/auth/security-schemes.test.js.map +1 -0
  103. package/dist/server/auth/setup.d.ts +6 -0
  104. package/dist/server/auth/setup.js +91 -0
  105. package/dist/server/auth/setup.js.map +1 -0
  106. package/dist/server/auth/setup.test.d.ts +1 -0
  107. package/dist/server/auth/setup.test.js +512 -0
  108. package/dist/server/auth/setup.test.js.map +1 -0
  109. package/dist/server/auth/verify.d.ts +46 -0
  110. package/dist/server/auth/verify.js +62 -0
  111. package/dist/server/auth/verify.js.map +1 -0
  112. package/dist/server/auth/verify.test.d.ts +1 -0
  113. package/dist/server/auth/verify.test.js +149 -0
  114. package/dist/server/auth/verify.test.js.map +1 -0
  115. package/dist/server/auth-extra.test-d.js +71 -0
  116. package/dist/server/auth-extra.test-d.js.map +1 -0
  117. package/dist/server/auth.d.ts +42 -5
  118. package/dist/server/auth.js +3 -4
  119. package/dist/server/auth.js.map +1 -1
  120. package/dist/server/build-manifest.test.d.ts +1 -0
  121. package/dist/server/build-manifest.test.js +28 -0
  122. package/dist/server/build-manifest.test.js.map +1 -0
  123. package/dist/server/content-helpers.d.ts +1 -1
  124. package/dist/server/content-helpers.js.map +1 -1
  125. package/dist/server/express.d.ts +23 -3
  126. package/dist/server/express.js +37 -32
  127. package/dist/server/express.js.map +1 -1
  128. package/dist/server/express.test.js +154 -95
  129. package/dist/server/express.test.js.map +1 -1
  130. package/dist/server/factory-loader.test.d.ts +1 -0
  131. package/dist/server/factory-loader.test.js +81 -0
  132. package/dist/server/factory-loader.test.js.map +1 -0
  133. package/dist/server/file-ref.d.ts +1 -1
  134. package/dist/server/file-ref.js +1 -1
  135. package/dist/server/file-ref.js.map +1 -1
  136. package/dist/server/host.d.ts +2 -0
  137. package/dist/server/host.js +11 -0
  138. package/dist/server/host.js.map +1 -0
  139. package/dist/server/host.test.d.ts +1 -0
  140. package/dist/server/host.test.js +13 -0
  141. package/dist/server/host.test.js.map +1 -0
  142. package/dist/server/index.d.ts +16 -3
  143. package/dist/server/index.js +13 -2
  144. package/dist/server/index.js.map +1 -1
  145. package/dist/server/mcp-errors.test.d.ts +1 -0
  146. package/dist/server/mcp-errors.test.js +37 -0
  147. package/dist/server/mcp-errors.test.js.map +1 -0
  148. package/dist/server/middleware.d.ts +35 -10
  149. package/dist/server/middleware.js +33 -0
  150. package/dist/server/middleware.js.map +1 -1
  151. package/dist/server/middleware.test-d.js +1 -1
  152. package/dist/server/middleware.test-d.js.map +1 -1
  153. package/dist/server/middleware.test.js +190 -131
  154. package/dist/server/middleware.test.js.map +1 -1
  155. package/dist/server/register-tool.test.d.ts +1 -0
  156. package/dist/server/register-tool.test.js +23 -0
  157. package/dist/server/register-tool.test.js.map +1 -0
  158. package/dist/server/requestOrigin.d.ts +7 -0
  159. package/dist/server/requestOrigin.js +25 -0
  160. package/dist/server/requestOrigin.js.map +1 -0
  161. package/dist/server/server.d.ts +167 -122
  162. package/dist/server/server.js +346 -330
  163. package/dist/server/server.js.map +1 -1
  164. package/dist/server/skills-integration.test.d.ts +1 -0
  165. package/dist/server/skills-integration.test.js +79 -0
  166. package/dist/server/skills-integration.test.js.map +1 -0
  167. package/dist/server/skills.d.ts +27 -0
  168. package/dist/server/skills.js +188 -0
  169. package/dist/server/skills.js.map +1 -0
  170. package/dist/server/skills.test.d.ts +1 -0
  171. package/dist/server/skills.test.js +243 -0
  172. package/dist/server/skills.test.js.map +1 -0
  173. package/dist/server/templateHelper.d.ts +0 -3
  174. package/dist/server/templateHelper.js.map +1 -1
  175. package/dist/server/templates.generated.js +4 -8
  176. package/dist/server/templates.generated.js.map +1 -1
  177. package/dist/server/tool-extra.test.d.ts +1 -0
  178. package/dist/server/tool-extra.test.js +72 -0
  179. package/dist/server/tool-extra.test.js.map +1 -0
  180. package/dist/server/view-name.test-d.d.ts +1 -0
  181. package/dist/server/view-name.test-d.js +8 -0
  182. package/dist/server/view-name.test-d.js.map +1 -0
  183. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  184. package/dist/server/view-resource-resolution.test.js +172 -0
  185. package/dist/server/view-resource-resolution.test.js.map +1 -0
  186. package/dist/server/viewsDevServer.js +4 -1
  187. package/dist/server/viewsDevServer.js.map +1 -1
  188. package/dist/test/utils.d.ts +9 -11
  189. package/dist/test/utils.js +18 -13
  190. package/dist/test/utils.js.map +1 -1
  191. package/dist/test/view.test.js +88 -120
  192. package/dist/test/view.test.js.map +1 -1
  193. package/dist/views/index.d.ts +10 -0
  194. package/dist/views/index.js +3 -0
  195. package/dist/views/index.js.map +1 -0
  196. package/dist/{web/plugin → views}/scan-views.js +1 -1
  197. package/dist/views/scan-views.js.map +1 -0
  198. package/dist/views/scan-views.test.d.ts +1 -0
  199. package/dist/views/scan-views.test.js.map +1 -0
  200. package/dist/views/validate-view.d.ts +1 -0
  201. package/dist/{web/plugin → views}/validate-view.js +2 -2
  202. package/dist/views/validate-view.js.map +1 -0
  203. package/dist/views/validate-view.test.d.ts +1 -0
  204. package/dist/views/validate-view.test.js.map +1 -0
  205. package/dist/web/bridges/adaptor.d.ts +51 -0
  206. package/dist/web/bridges/adaptor.js +327 -0
  207. package/dist/web/bridges/adaptor.js.map +1 -0
  208. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  209. package/dist/web/bridges/adaptor.test.js +225 -0
  210. package/dist/web/bridges/adaptor.test.js.map +1 -0
  211. package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -2
  212. package/dist/web/bridges/apps-sdk/bridge.js +15 -4
  213. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  214. package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
  215. package/dist/web/bridges/apps-sdk/index.js +0 -1
  216. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  217. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +1 -1
  218. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +1 -1
  219. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  220. package/dist/web/bridges/get-adaptor.d.ts +4 -4
  221. package/dist/web/bridges/get-adaptor.js +6 -11
  222. package/dist/web/bridges/get-adaptor.js.map +1 -1
  223. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  224. package/dist/web/bridges/get-adaptor.test.js +32 -0
  225. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  226. package/dist/web/bridges/mcp-app/bridge.d.ts +15 -3
  227. package/dist/web/bridges/mcp-app/bridge.js +73 -8
  228. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  229. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  230. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  231. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  232. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  233. package/dist/web/bridges/mcp-app/index.js +0 -1
  234. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  235. package/dist/web/bridges/mcp-app/types.d.ts +2 -0
  236. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  237. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +1 -1
  238. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +1 -1
  239. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  240. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -1
  241. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  242. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  243. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  244. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  245. package/dist/web/bridges/types.d.ts +55 -7
  246. package/dist/web/bridges/types.js +14 -1
  247. package/dist/web/bridges/types.js.map +1 -1
  248. package/dist/web/bridges/types.test.d.ts +1 -0
  249. package/dist/web/bridges/types.test.js +19 -0
  250. package/dist/web/bridges/types.test.js.map +1 -0
  251. package/dist/web/components/modal-provider.d.ts +1 -1
  252. package/dist/web/components/modal-provider.js +4 -3
  253. package/dist/web/components/modal-provider.js.map +1 -1
  254. package/dist/web/create-store.test.js +10 -7
  255. package/dist/web/create-store.test.js.map +1 -1
  256. package/dist/web/data-llm.d.ts +1 -1
  257. package/dist/web/data-llm.test.js +20 -7
  258. package/dist/web/data-llm.test.js.map +1 -1
  259. package/dist/web/generate-helpers.d.ts +13 -12
  260. package/dist/web/generate-helpers.js +10 -9
  261. package/dist/web/generate-helpers.js.map +1 -1
  262. package/dist/web/generate-helpers.test-d.js +7 -5
  263. package/dist/web/generate-helpers.test-d.js.map +1 -1
  264. package/dist/web/generate-helpers.test.js +2 -2
  265. package/dist/web/generate-helpers.test.js.map +1 -1
  266. package/dist/web/hooks/index.d.ts +3 -1
  267. package/dist/web/hooks/index.js +3 -1
  268. package/dist/web/hooks/index.js.map +1 -1
  269. package/dist/web/hooks/test/utils.d.ts +2 -1
  270. package/dist/web/hooks/test/utils.js +1 -1
  271. package/dist/web/hooks/test/utils.js.map +1 -1
  272. package/dist/web/hooks/use-call-tool.test.js +39 -25
  273. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  274. package/dist/web/hooks/use-display-mode.d.ts +1 -1
  275. package/dist/web/hooks/use-display-mode.js +1 -1
  276. package/dist/web/hooks/use-display-mode.js.map +1 -1
  277. package/dist/web/hooks/use-display-mode.test.js +57 -21
  278. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  279. package/dist/web/hooks/use-download.d.ts +1 -3
  280. package/dist/web/hooks/use-download.js +1 -2
  281. package/dist/web/hooks/use-download.js.map +1 -1
  282. package/dist/web/hooks/use-download.test.js +18 -10
  283. package/dist/web/hooks/use-download.test.js.map +1 -1
  284. package/dist/web/hooks/use-files.test.js +11 -3
  285. package/dist/web/hooks/use-files.test.js.map +1 -1
  286. package/dist/web/hooks/use-host.d.ts +22 -0
  287. package/dist/web/hooks/use-host.js +30 -0
  288. package/dist/web/hooks/use-host.js.map +1 -0
  289. package/dist/web/hooks/use-host.test.d.ts +1 -0
  290. package/dist/web/hooks/use-host.test.js +59 -0
  291. package/dist/web/hooks/use-host.test.js.map +1 -0
  292. package/dist/web/hooks/use-open-external.test.js +15 -5
  293. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  294. package/dist/web/hooks/use-register-view-tool.d.ts +37 -0
  295. package/dist/web/hooks/use-register-view-tool.js +50 -0
  296. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  297. package/dist/web/hooks/use-request-close.test.js +35 -40
  298. package/dist/web/hooks/use-request-close.test.js.map +1 -1
  299. package/dist/web/hooks/use-request-modal.test.js +11 -1
  300. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  301. package/dist/web/hooks/use-request-size.d.ts +1 -1
  302. package/dist/web/hooks/use-request-size.js +1 -1
  303. package/dist/web/hooks/use-request-size.js.map +1 -1
  304. package/dist/web/hooks/use-request-size.test.js +35 -53
  305. package/dist/web/hooks/use-request-size.test.js.map +1 -1
  306. package/dist/web/hooks/use-set-open-in-app-url.test.js +26 -12
  307. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  308. package/dist/web/hooks/use-tool-info.d.ts +18 -19
  309. package/dist/web/hooks/use-tool-info.js +4 -8
  310. package/dist/web/hooks/use-tool-info.js.map +1 -1
  311. package/dist/web/hooks/use-tool-info.test-d.js +11 -34
  312. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  313. package/dist/web/hooks/use-tool-info.test.js +42 -37
  314. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  315. package/dist/web/hooks/use-user.d.ts +3 -2
  316. package/dist/web/hooks/use-user.js +4 -3
  317. package/dist/web/hooks/use-user.js.map +1 -1
  318. package/dist/web/hooks/use-user.test.js +85 -37
  319. package/dist/web/hooks/use-user.test.js.map +1 -1
  320. package/dist/web/hooks/use-view-state.js +19 -9
  321. package/dist/web/hooks/use-view-state.js.map +1 -1
  322. package/dist/web/hooks/use-view-state.test.js +39 -4
  323. package/dist/web/hooks/use-view-state.test.js.map +1 -1
  324. package/dist/web/hooks/use-viewport.d.ts +20 -0
  325. package/dist/web/hooks/use-viewport.js +21 -0
  326. package/dist/web/hooks/use-viewport.js.map +1 -0
  327. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  328. package/dist/web/hooks/use-viewport.test.js +109 -0
  329. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  330. package/dist/web/mount-view.d.ts +3 -2
  331. package/dist/web/mount-view.js +5 -8
  332. package/dist/web/mount-view.js.map +1 -1
  333. package/package.json +33 -27
  334. package/dist/cli/resolve-views-dir.d.ts +0 -1
  335. package/dist/cli/resolve-views-dir.js.map +0 -1
  336. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -28
  337. package/dist/web/bridges/apps-sdk/adaptor.js +0 -113
  338. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  339. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -52
  340. package/dist/web/bridges/mcp-app/adaptor.js +0 -280
  341. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
  342. package/dist/web/hooks/use-layout.d.ts +0 -24
  343. package/dist/web/hooks/use-layout.js +0 -25
  344. package/dist/web/hooks/use-layout.js.map +0 -1
  345. package/dist/web/hooks/use-layout.test.js +0 -96
  346. package/dist/web/hooks/use-layout.test.js.map +0 -1
  347. package/dist/web/plugin/data-llm.test.js +0 -81
  348. package/dist/web/plugin/data-llm.test.js.map +0 -1
  349. package/dist/web/plugin/plugin.d.ts +0 -33
  350. package/dist/web/plugin/plugin.js +0 -189
  351. package/dist/web/plugin/plugin.js.map +0 -1
  352. package/dist/web/plugin/scan-views.js.map +0 -1
  353. package/dist/web/plugin/scan-views.test.js.map +0 -1
  354. package/dist/web/plugin/transform-data-llm.d.ts +0 -12
  355. package/dist/web/plugin/transform-data-llm.js +0 -96
  356. package/dist/web/plugin/transform-data-llm.js.map +0 -1
  357. package/dist/web/plugin/transform-data-llm.test.js +0 -81
  358. package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
  359. package/dist/web/plugin/validate-view.d.ts +0 -1
  360. package/dist/web/plugin/validate-view.js.map +0 -1
  361. package/dist/web/plugin/validate-view.test.js.map +0 -1
  362. /package/dist/{web/hooks/use-layout.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  363. /package/dist/{web/plugin/data-llm.test.d.ts → context-warnings.test.d.ts} +0 -0
  364. /package/dist/{web/plugin/transform-data-llm.test.d.ts → server/auth/discovery.test.d.ts} +0 -0
  365. /package/dist/{web/plugin/validate-view.test.d.ts → server/auth/providers/auth0.test.d.ts} +0 -0
  366. /package/dist/{web/plugin/scan-views.test.d.ts → server/auth-extra.test-d.d.ts} +0 -0
  367. /package/dist/{web/plugin → views}/scan-views.d.ts +0 -0
  368. /package/dist/{web/plugin → views}/scan-views.test.js +0 -0
  369. /package/dist/{web/plugin → views}/validate-view.test.js +0 -0
@@ -0,0 +1,37 @@
1
+ import type { ViewToolConfig, ViewToolHandler, ViewToolInputShape } from "../bridges/types.js";
2
+ /**
3
+ * Register a tool the view exposes to the host and model — the MCP Apps
4
+ * "app-provided tools" feature. A view tool runs *inside the view*: the host
5
+ * discovers it via `tools/list` and invokes it via `tools/call`, and the
6
+ * handler executes against the view's live state. It is the inverse of
7
+ * {@link useCallTool} (which calls a server tool). Registered on mount, removed
8
+ * on unmount; re-registered when `config.name` changes.
9
+ *
10
+ * MCP Apps only — on the Apps SDK (`window.openai`) runtime it is a no-op.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * import * as z from "zod";
15
+ * import { useRegisterViewTool } from "skybridge/web";
16
+ *
17
+ * useRegisterViewTool(
18
+ * {
19
+ * name: "chess_make_move",
20
+ * description: "Play a move in algebraic notation, e.g. 'e4' or 'Nf3'.",
21
+ * inputSchema: { san: z.string() },
22
+ * annotations: { readOnlyHint: false },
23
+ * },
24
+ * ({ san }) => {
25
+ * const move = game.move(san);
26
+ * return {
27
+ * content: [{ type: "text", text: move ? `Played ${move.san}` : "Illegal move" }],
28
+ * structuredContent: { fen: game.fen() },
29
+ * isError: !move,
30
+ * };
31
+ * },
32
+ * );
33
+ * ```
34
+ *
35
+ * @see https://docs.skybridge.tech/api-reference/use-register-view-tool
36
+ */
37
+ export declare const useRegisterViewTool: <TInput extends ViewToolInputShape = ViewToolInputShape>(config: ViewToolConfig<TInput>, handler: ViewToolHandler<TInput>) => void;
@@ -0,0 +1,50 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { getAdaptor } from "../bridges/index.js";
3
+ /**
4
+ * Register a tool the view exposes to the host and model — the MCP Apps
5
+ * "app-provided tools" feature. A view tool runs *inside the view*: the host
6
+ * discovers it via `tools/list` and invokes it via `tools/call`, and the
7
+ * handler executes against the view's live state. It is the inverse of
8
+ * {@link useCallTool} (which calls a server tool). Registered on mount, removed
9
+ * on unmount; re-registered when `config.name` changes.
10
+ *
11
+ * MCP Apps only — on the Apps SDK (`window.openai`) runtime it is a no-op.
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * import * as z from "zod";
16
+ * import { useRegisterViewTool } from "skybridge/web";
17
+ *
18
+ * useRegisterViewTool(
19
+ * {
20
+ * name: "chess_make_move",
21
+ * description: "Play a move in algebraic notation, e.g. 'e4' or 'Nf3'.",
22
+ * inputSchema: { san: z.string() },
23
+ * annotations: { readOnlyHint: false },
24
+ * },
25
+ * ({ san }) => {
26
+ * const move = game.move(san);
27
+ * return {
28
+ * content: [{ type: "text", text: move ? `Played ${move.san}` : "Illegal move" }],
29
+ * structuredContent: { fen: game.fen() },
30
+ * isError: !move,
31
+ * };
32
+ * },
33
+ * );
34
+ * ```
35
+ *
36
+ * @see https://docs.skybridge.tech/api-reference/use-register-view-tool
37
+ */
38
+ export const useRegisterViewTool = (config, handler) => {
39
+ const { name } = config;
40
+ const configRef = useRef(config);
41
+ configRef.current = config;
42
+ const handlerRef = useRef(handler);
43
+ handlerRef.current = handler;
44
+ useEffect(() => {
45
+ const adaptor = getAdaptor();
46
+ const wrappedHandler = (args) => handlerRef.current(args);
47
+ return adaptor.registerViewTool({ ...configRef.current, name }, wrappedHandler);
48
+ }, [name]);
49
+ };
50
+ //# sourceMappingURL=use-register-view-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-register-view-tool.js","sourceRoot":"","sources":["../../../src/web/hooks/use-register-view-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAQjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAGjC,MAA8B,EAC9B,OAAgC,EAChC,EAAE;IACF,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;IACxB,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC;IAC3B,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,MAAM,cAAc,GAAuB,CAAC,IAAI,EAAE,EAAE,CAClD,UAAU,CAAC,OAAO,CAAC,IAA8C,CAAC,CAAC;QAErE,OAAO,OAAO,CAAC,gBAAgB,CAC7B,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,EAC9B,cAAc,CACf,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AACb,CAAC,CAAC","sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { getAdaptor } from \"../bridges/index.js\";\nimport type {\n AnyViewToolHandler,\n ViewToolConfig,\n ViewToolHandler,\n ViewToolInputShape,\n} from \"../bridges/types.js\";\n\n/**\n * Register a tool the view exposes to the host and model — the MCP Apps\n * \"app-provided tools\" feature. A view tool runs *inside the view*: the host\n * discovers it via `tools/list` and invokes it via `tools/call`, and the\n * handler executes against the view's live state. It is the inverse of\n * {@link useCallTool} (which calls a server tool). Registered on mount, removed\n * on unmount; re-registered when `config.name` changes.\n *\n * MCP Apps only — on the Apps SDK (`window.openai`) runtime it is a no-op.\n *\n * @example\n * ```tsx\n * import * as z from \"zod\";\n * import { useRegisterViewTool } from \"skybridge/web\";\n *\n * useRegisterViewTool(\n * {\n * name: \"chess_make_move\",\n * description: \"Play a move in algebraic notation, e.g. 'e4' or 'Nf3'.\",\n * inputSchema: { san: z.string() },\n * annotations: { readOnlyHint: false },\n * },\n * ({ san }) => {\n * const move = game.move(san);\n * return {\n * content: [{ type: \"text\", text: move ? `Played ${move.san}` : \"Illegal move\" }],\n * structuredContent: { fen: game.fen() },\n * isError: !move,\n * };\n * },\n * );\n * ```\n *\n * @see https://docs.skybridge.tech/api-reference/use-register-view-tool\n */\nexport const useRegisterViewTool = <\n TInput extends ViewToolInputShape = ViewToolInputShape,\n>(\n config: ViewToolConfig<TInput>,\n handler: ViewToolHandler<TInput>,\n) => {\n const { name } = config;\n const configRef = useRef(config);\n configRef.current = config;\n const handlerRef = useRef(handler);\n handlerRef.current = handler;\n\n useEffect(() => {\n const adaptor = getAdaptor();\n const wrappedHandler: AnyViewToolHandler = (args) =>\n handlerRef.current(args as Parameters<ViewToolHandler<TInput>>[0]);\n\n return adaptor.registerViewTool(\n { ...configRef.current, name },\n wrappedHandler,\n );\n }, [name]);\n};\n"]}
@@ -1,52 +1,47 @@
1
- import { renderHook, waitFor } from "@testing-library/react";
1
+ import { act, renderHook } from "@testing-library/react";
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { HostAdaptor } from "../bridges/adaptor.js";
4
+ import { getAdaptor } from "../bridges/get-adaptor.js";
3
5
  import { McpAppBridge } from "../bridges/mcp-app/bridge.js";
4
- import { getMcpAppHostPostMessageMock, MockResizeObserver, } from "./test/utils.js";
5
6
  import { useRequestClose } from "./use-request-close.js";
6
7
  describe("useRequestClose", () => {
7
- describe("apps-sdk host", () => {
8
- let requestCloseMock;
9
- beforeEach(() => {
10
- requestCloseMock = vi.fn().mockResolvedValue(undefined);
11
- vi.stubGlobal("openai", {
12
- requestClose: requestCloseMock,
13
- });
14
- vi.stubGlobal("skybridge", { hostType: "apps-sdk" });
15
- });
16
- afterEach(() => {
17
- vi.unstubAllGlobals();
18
- vi.resetAllMocks();
19
- });
20
- it("should return a function that calls window.openai.requestClose", async () => {
21
- const { result } = renderHook(() => useRequestClose());
8
+ beforeEach(() => {
9
+ HostAdaptor.resetInstance();
10
+ McpAppBridge.resetInstance();
11
+ vi.stubGlobal("skybridge", {});
12
+ vi.stubGlobal("openai", undefined);
13
+ vi.stubGlobal("parent", { postMessage: vi.fn() });
14
+ });
15
+ afterEach(() => {
16
+ vi.unstubAllGlobals();
17
+ vi.resetAllMocks();
18
+ HostAdaptor.resetInstance();
19
+ McpAppBridge.resetInstance();
20
+ });
21
+ it("calls app.requestTeardown via the MCP path", async () => {
22
+ const requestTeardown = vi.fn().mockResolvedValue(undefined);
23
+ // biome-ignore lint/suspicious/noExplicitAny: test seam
24
+ const adaptor = getAdaptor();
25
+ adaptor.mcp.getApp = vi.fn().mockResolvedValue({ requestTeardown });
26
+ const { result } = renderHook(() => useRequestClose());
27
+ await act(async () => {
22
28
  await result.current();
23
- expect(requestCloseMock).toHaveBeenCalledTimes(1);
24
- expect(requestCloseMock).toHaveBeenCalledWith();
25
29
  });
30
+ expect(requestTeardown).toHaveBeenCalledTimes(1);
26
31
  });
27
- describe("mcp-app host", () => {
28
- let postMessageMock;
29
- beforeEach(() => {
30
- vi.stubGlobal("skybridge", { hostType: "mcp-app" });
31
- vi.stubGlobal("ResizeObserver", MockResizeObserver);
32
- postMessageMock = getMcpAppHostPostMessageMock();
33
- vi.stubGlobal("parent", { postMessage: postMessageMock });
34
- });
35
- afterEach(async () => {
36
- vi.unstubAllGlobals();
37
- vi.resetAllMocks();
38
- McpAppBridge.resetInstance();
39
- });
40
- it("should send a ui/notifications/request-teardown notification to the MCP host", async () => {
41
- const { result } = renderHook(() => useRequestClose());
32
+ it("calls app.requestTeardown even when window.openai is present", async () => {
33
+ vi.stubGlobal("openai", { requestClose: vi.fn() });
34
+ HostAdaptor.resetInstance();
35
+ McpAppBridge.resetInstance();
36
+ const requestTeardown = vi.fn().mockResolvedValue(undefined);
37
+ // biome-ignore lint/suspicious/noExplicitAny: test seam
38
+ const adaptor = getAdaptor();
39
+ adaptor.mcp.getApp = vi.fn().mockResolvedValue({ requestTeardown });
40
+ const { result } = renderHook(() => useRequestClose());
41
+ await act(async () => {
42
42
  await result.current();
43
- await waitFor(() => {
44
- expect(postMessageMock).toHaveBeenCalledWith(expect.objectContaining({
45
- jsonrpc: "2.0",
46
- method: "ui/notifications/request-teardown",
47
- }), "*");
48
- });
49
43
  });
44
+ expect(requestTeardown).toHaveBeenCalledTimes(1);
50
45
  });
51
46
  });
52
47
  //# sourceMappingURL=use-request-close.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-request-close.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-request-close.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,IAAI,gBAA0C,CAAC;QAE/C,UAAU,CAAC,GAAG,EAAE;YACd,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YACxD,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;gBACtB,YAAY,EAAE,gBAAgB;aAC/B,CAAC,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,GAAG,EAAE;YACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;YACtB,EAAE,CAAC,aAAa,EAAE,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;YAC9E,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC;YAEvD,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;YAEvB,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YAClD,MAAM,CAAC,gBAAgB,CAAC,CAAC,oBAAoB,EAAE,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,IAAI,eAAgE,CAAC;QAErE,UAAU,CAAC,GAAG,EAAE;YACd,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;YACpD,EAAE,CAAC,UAAU,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;YACpD,eAAe,GAAG,4BAA4B,EAAE,CAAC;YACjD,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,KAAK,IAAI,EAAE;YACnB,EAAE,CAAC,gBAAgB,EAAE,CAAC;YACtB,EAAE,CAAC,aAAa,EAAE,CAAC;YACnB,YAAY,CAAC,aAAa,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;YAC5F,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC;YAEvD,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;YAEvB,MAAM,OAAO,CAAC,GAAG,EAAE;gBACjB,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,MAAM,CAAC,gBAAgB,CAAC;oBACtB,OAAO,EAAE,KAAK;oBACd,MAAM,EAAE,mCAAmC;iBAC5C,CAAC,EACF,GAAG,CACJ,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { renderHook, waitFor } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { McpAppBridge } from \"../bridges/mcp-app/bridge.js\";\nimport {\n getMcpAppHostPostMessageMock,\n MockResizeObserver,\n} from \"./test/utils.js\";\nimport { useRequestClose } from \"./use-request-close.js\";\n\ndescribe(\"useRequestClose\", () => {\n describe(\"apps-sdk host\", () => {\n let requestCloseMock: ReturnType<typeof vi.fn>;\n\n beforeEach(() => {\n requestCloseMock = vi.fn().mockResolvedValue(undefined);\n vi.stubGlobal(\"openai\", {\n requestClose: requestCloseMock,\n });\n vi.stubGlobal(\"skybridge\", { hostType: \"apps-sdk\" });\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n });\n\n it(\"should return a function that calls window.openai.requestClose\", async () => {\n const { result } = renderHook(() => useRequestClose());\n\n await result.current();\n\n expect(requestCloseMock).toHaveBeenCalledTimes(1);\n expect(requestCloseMock).toHaveBeenCalledWith();\n });\n });\n\n describe(\"mcp-app host\", () => {\n let postMessageMock: ReturnType<typeof getMcpAppHostPostMessageMock>;\n\n beforeEach(() => {\n vi.stubGlobal(\"skybridge\", { hostType: \"mcp-app\" });\n vi.stubGlobal(\"ResizeObserver\", MockResizeObserver);\n postMessageMock = getMcpAppHostPostMessageMock();\n vi.stubGlobal(\"parent\", { postMessage: postMessageMock });\n });\n\n afterEach(async () => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n McpAppBridge.resetInstance();\n });\n\n it(\"should send a ui/notifications/request-teardown notification to the MCP host\", async () => {\n const { result } = renderHook(() => useRequestClose());\n\n await result.current();\n\n await waitFor(() => {\n expect(postMessageMock).toHaveBeenCalledWith(\n expect.objectContaining({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/request-teardown\",\n }),\n \"*\",\n );\n });\n });\n });\n});\n"]}
1
+ {"version":3,"file":"use-request-close.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-request-close.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { act, renderHook } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { HostAdaptor } from \"../bridges/adaptor.js\";\nimport { getAdaptor } from \"../bridges/get-adaptor.js\";\nimport { McpAppBridge } from \"../bridges/mcp-app/bridge.js\";\nimport { useRequestClose } from \"./use-request-close.js\";\n\ndescribe(\"useRequestClose\", () => {\n beforeEach(() => {\n HostAdaptor.resetInstance();\n McpAppBridge.resetInstance();\n vi.stubGlobal(\"skybridge\", {});\n vi.stubGlobal(\"openai\", undefined);\n vi.stubGlobal(\"parent\", { postMessage: vi.fn() });\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n HostAdaptor.resetInstance();\n McpAppBridge.resetInstance();\n });\n\n it(\"calls app.requestTeardown via the MCP path\", async () => {\n const requestTeardown = vi.fn().mockResolvedValue(undefined);\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n const adaptor = getAdaptor() as any;\n adaptor.mcp.getApp = vi.fn().mockResolvedValue({ requestTeardown });\n\n const { result } = renderHook(() => useRequestClose());\n await act(async () => {\n await result.current();\n });\n\n expect(requestTeardown).toHaveBeenCalledTimes(1);\n });\n\n it(\"calls app.requestTeardown even when window.openai is present\", async () => {\n vi.stubGlobal(\"openai\", { requestClose: vi.fn() });\n HostAdaptor.resetInstance();\n McpAppBridge.resetInstance();\n\n const requestTeardown = vi.fn().mockResolvedValue(undefined);\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n const adaptor = getAdaptor() as any;\n adaptor.mcp.getApp = vi.fn().mockResolvedValue({ requestTeardown });\n\n const { result } = renderHook(() => useRequestClose());\n await act(async () => {\n await result.current();\n });\n\n expect(requestTeardown).toHaveBeenCalledTimes(1);\n });\n});\n"]}
@@ -1,11 +1,18 @@
1
1
  import { renderHook } from "@testing-library/react";
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { HostAdaptor } from "../bridges/adaptor.js";
4
+ import { AppsSdkBridge } from "../bridges/apps-sdk/bridge.js";
5
+ import { McpAppBridge } from "../bridges/mcp-app/bridge.js";
3
6
  import { useRequestModal } from "./use-request-modal.js";
4
7
  describe("useRequestModal", () => {
5
8
  let requestModalMock;
6
9
  beforeEach(() => {
10
+ HostAdaptor.resetInstance();
11
+ McpAppBridge.resetInstance();
12
+ AppsSdkBridge.resetInstance();
7
13
  requestModalMock = vi.fn();
8
- vi.stubGlobal("skybridge", { hostType: "apps-sdk" });
14
+ vi.stubGlobal("skybridge", {});
15
+ vi.stubGlobal("parent", { postMessage: vi.fn() });
9
16
  vi.stubGlobal("openai", {
10
17
  requestModal: requestModalMock,
11
18
  view: { mode: "inline" },
@@ -14,6 +21,9 @@ describe("useRequestModal", () => {
14
21
  afterEach(() => {
15
22
  vi.unstubAllGlobals();
16
23
  vi.resetAllMocks();
24
+ HostAdaptor.resetInstance();
25
+ McpAppBridge.resetInstance();
26
+ AppsSdkBridge.resetInstance();
17
27
  });
18
28
  it("should return an object with open, isOpen, and params properties where isOpen is false when mode is not modal", () => {
19
29
  const { result } = renderHook(() => useRequestModal());
@@ -1 +1 @@
1
- {"version":3,"file":"use-request-modal.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-request-modal.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { renderHook } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { useRequestModal } from \"./use-request-modal.js\";\n\ndescribe(\"useRequestModal\", () => {\n let requestModalMock: ReturnType<typeof vi.fn>;\n\n beforeEach(() => {\n requestModalMock = vi.fn();\n vi.stubGlobal(\"skybridge\", { hostType: \"apps-sdk\" });\n vi.stubGlobal(\"openai\", {\n requestModal: requestModalMock,\n view: { mode: \"inline\" },\n });\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n });\n\n it(\"should return an object with open, isOpen, and params properties where isOpen is false when mode is not modal\", () => {\n const { result } = renderHook(() => useRequestModal());\n\n expect(typeof result.current).toBe(\"object\");\n expect(result.current).toHaveProperty(\"open\");\n expect(result.current).toHaveProperty(\"isOpen\");\n expect(result.current).toHaveProperty(\"params\");\n\n const { open, isOpen, params } = result.current;\n expect(typeof open).toBe(\"function\");\n expect(isOpen).toBe(false);\n expect(params).toBeUndefined();\n });\n\n it(\"should return isOpen as true when mode is modal\", () => {\n vi.stubGlobal(\"openai\", {\n requestModal: requestModalMock,\n view: { mode: \"modal\" },\n });\n\n const { result } = renderHook(() => useRequestModal());\n const { isOpen } = result.current;\n\n expect(isOpen).toBe(true);\n });\n\n it(\"should return params from view when available\", () => {\n const testParams = { foo: \"bar\", baz: 42 };\n vi.stubGlobal(\"openai\", {\n requestModal: requestModalMock,\n view: { mode: \"modal\", params: testParams },\n });\n\n const { result } = renderHook(() => useRequestModal());\n const { params } = result.current;\n\n expect(params).toEqual(testParams);\n });\n\n it(\"should call window.openai.requestModal with the options when open is called\", () => {\n const { result } = renderHook(() => useRequestModal());\n const { open } = result.current;\n\n const options = {\n title: \"Test Modal\",\n params: { foo: \"bar\" },\n template: \"ui://view/modal-template.html\",\n };\n open(options);\n\n expect(requestModalMock).toHaveBeenCalledTimes(1);\n expect(requestModalMock).toHaveBeenCalledWith(options);\n });\n});\n"]}
1
+ {"version":3,"file":"use-request-modal.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-request-modal.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { renderHook } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { HostAdaptor } from \"../bridges/adaptor.js\";\nimport { AppsSdkBridge } from \"../bridges/apps-sdk/bridge.js\";\nimport { McpAppBridge } from \"../bridges/mcp-app/bridge.js\";\nimport { useRequestModal } from \"./use-request-modal.js\";\n\ndescribe(\"useRequestModal\", () => {\n let requestModalMock: ReturnType<typeof vi.fn>;\n\n beforeEach(() => {\n HostAdaptor.resetInstance();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n requestModalMock = vi.fn();\n vi.stubGlobal(\"skybridge\", {});\n vi.stubGlobal(\"parent\", { postMessage: vi.fn() });\n vi.stubGlobal(\"openai\", {\n requestModal: requestModalMock,\n view: { mode: \"inline\" },\n });\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n HostAdaptor.resetInstance();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n });\n\n it(\"should return an object with open, isOpen, and params properties where isOpen is false when mode is not modal\", () => {\n const { result } = renderHook(() => useRequestModal());\n\n expect(typeof result.current).toBe(\"object\");\n expect(result.current).toHaveProperty(\"open\");\n expect(result.current).toHaveProperty(\"isOpen\");\n expect(result.current).toHaveProperty(\"params\");\n\n const { open, isOpen, params } = result.current;\n expect(typeof open).toBe(\"function\");\n expect(isOpen).toBe(false);\n expect(params).toBeUndefined();\n });\n\n it(\"should return isOpen as true when mode is modal\", () => {\n vi.stubGlobal(\"openai\", {\n requestModal: requestModalMock,\n view: { mode: \"modal\" },\n });\n\n const { result } = renderHook(() => useRequestModal());\n const { isOpen } = result.current;\n\n expect(isOpen).toBe(true);\n });\n\n it(\"should return params from view when available\", () => {\n const testParams = { foo: \"bar\", baz: 42 };\n vi.stubGlobal(\"openai\", {\n requestModal: requestModalMock,\n view: { mode: \"modal\", params: testParams },\n });\n\n const { result } = renderHook(() => useRequestModal());\n const { params } = result.current;\n\n expect(params).toEqual(testParams);\n });\n\n it(\"should call window.openai.requestModal with the options when open is called\", () => {\n const { result } = renderHook(() => useRequestModal());\n const { open } = result.current;\n\n const options = {\n title: \"Test Modal\",\n params: { foo: \"bar\" },\n template: \"ui://view/modal-template.html\",\n };\n open(options);\n\n expect(requestModalMock).toHaveBeenCalledTimes(1);\n expect(requestModalMock).toHaveBeenCalledWith(options);\n });\n});\n"]}
@@ -3,7 +3,7 @@ import type { RequestSizeOptions } from "../bridges/types.js";
3
3
  export type RequestSizeFn = (size: RequestSizeOptions) => Promise<void>;
4
4
  /**
5
5
  * Ask the host to resize the view iframe. The applied size is host-driven —
6
- * the host decides whether and how to honor the request, and {@link useLayout}
6
+ * the host decides whether and how to honor the request, and {@link useViewport}
7
7
  * still reports the final `maxHeight` it allows.
8
8
  *
9
9
  * Pair with a `ResizeObserver` on your root element to react to content size
@@ -2,7 +2,7 @@ import { useCallback } from "react";
2
2
  import { getAdaptor } from "../bridges/index.js";
3
3
  /**
4
4
  * Ask the host to resize the view iframe. The applied size is host-driven —
5
- * the host decides whether and how to honor the request, and {@link useLayout}
5
+ * the host decides whether and how to honor the request, and {@link useViewport}
6
6
  * still reports the final `maxHeight` it allows.
7
7
  *
8
8
  * Pair with a `ResizeObserver` on your root element to react to content size
@@ -1 +1 @@
1
- {"version":3,"file":"use-request-size.js","sourceRoot":"","sources":["../../../src/web/hooks/use-request-size.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAMjD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,IAAwB,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EACvD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import { useCallback } from \"react\";\nimport { getAdaptor } from \"../bridges/index.js\";\nimport type { RequestSizeOptions } from \"../bridges/types.js\";\n\n/** Function that asks the host to resize the view, returned by {@link useRequestSize}. */\nexport type RequestSizeFn = (size: RequestSizeOptions) => Promise<void>;\n\n/**\n * Ask the host to resize the view iframe. The applied size is host-driven —\n * the host decides whether and how to honor the request, and {@link useLayout}\n * still reports the final `maxHeight` it allows.\n *\n * Pair with a `ResizeObserver` on your root element to react to content size\n * changes without hard-coded values.\n *\n * @example\n * ```tsx\n * const requestSize = useRequestSize();\n * useEffect(() => { requestSize({ height: rootRef.current!.scrollHeight }); }, [content]);\n * ```\n *\n * @see https://docs.skybridge.tech/api-reference/use-request-size\n */\nexport function useRequestSize(): RequestSizeFn {\n const adaptor = getAdaptor();\n const requestSize = useCallback(\n (size: RequestSizeOptions) => adaptor.requestSize(size),\n [adaptor],\n );\n\n return requestSize;\n}\n"]}
1
+ {"version":3,"file":"use-request-size.js","sourceRoot":"","sources":["../../../src/web/hooks/use-request-size.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAMjD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,IAAwB,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EACvD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,OAAO,WAAW,CAAC;AACrB,CAAC","sourcesContent":["import { useCallback } from \"react\";\nimport { getAdaptor } from \"../bridges/index.js\";\nimport type { RequestSizeOptions } from \"../bridges/types.js\";\n\n/** Function that asks the host to resize the view, returned by {@link useRequestSize}. */\nexport type RequestSizeFn = (size: RequestSizeOptions) => Promise<void>;\n\n/**\n * Ask the host to resize the view iframe. The applied size is host-driven —\n * the host decides whether and how to honor the request, and {@link useViewport}\n * still reports the final `maxHeight` it allows.\n *\n * Pair with a `ResizeObserver` on your root element to react to content size\n * changes without hard-coded values.\n *\n * @example\n * ```tsx\n * const requestSize = useRequestSize();\n * useEffect(() => { requestSize({ height: rootRef.current!.scrollHeight }); }, [content]);\n * ```\n *\n * @see https://docs.skybridge.tech/api-reference/use-request-size\n */\nexport function useRequestSize(): RequestSizeFn {\n const adaptor = getAdaptor();\n const requestSize = useCallback(\n (size: RequestSizeOptions) => adaptor.requestSize(size),\n [adaptor],\n );\n\n return requestSize;\n}\n"]}
@@ -1,64 +1,46 @@
1
1
  import { renderHook, waitFor } from "@testing-library/react";
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
- import { AppsSdkAdaptor } from "../bridges/apps-sdk/adaptor.js";
3
+ import { HostAdaptor } from "../bridges/adaptor.js";
4
4
  import { McpAppBridge } from "../bridges/mcp-app/bridge.js";
5
5
  import { getMcpAppHostPostMessageMock, MockResizeObserver, } from "./test/utils.js";
6
6
  import { useRequestSize } from "./use-request-size.js";
7
7
  describe("useRequestSize", () => {
8
- describe("apps-sdk host", () => {
9
- let consoleWarnSpy;
10
- beforeEach(() => {
11
- AppsSdkAdaptor.resetInstance();
12
- vi.stubGlobal("openai", {});
13
- vi.stubGlobal("skybridge", { hostType: "apps-sdk" });
14
- consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => { });
15
- });
16
- afterEach(() => {
17
- AppsSdkAdaptor.resetInstance();
18
- vi.unstubAllGlobals();
19
- vi.resetAllMocks();
20
- });
21
- it("warns that requestSize is not supported on Apps SDK", async () => {
22
- const { result } = renderHook(() => useRequestSize());
23
- await result.current({ height: 400 });
24
- expect(consoleWarnSpy).toHaveBeenCalledTimes(1);
25
- expect(consoleWarnSpy.mock.calls[0]?.[0]).toContain("not supported");
26
- });
8
+ let postMessageMock;
9
+ beforeEach(() => {
10
+ HostAdaptor.resetInstance();
11
+ McpAppBridge.resetInstance();
12
+ vi.stubGlobal("skybridge", {});
13
+ vi.stubGlobal("openai", undefined);
14
+ vi.stubGlobal("ResizeObserver", MockResizeObserver);
15
+ postMessageMock = getMcpAppHostPostMessageMock();
16
+ vi.stubGlobal("parent", { postMessage: postMessageMock });
27
17
  });
28
- describe("mcp-app host", () => {
29
- let postMessageMock;
30
- beforeEach(() => {
31
- vi.stubGlobal("skybridge", { hostType: "mcp-app" });
32
- vi.stubGlobal("ResizeObserver", MockResizeObserver);
33
- postMessageMock = getMcpAppHostPostMessageMock();
34
- vi.stubGlobal("parent", { postMessage: postMessageMock });
35
- });
36
- afterEach(async () => {
37
- vi.unstubAllGlobals();
38
- vi.resetAllMocks();
39
- McpAppBridge.resetInstance();
40
- });
41
- it("sends a ui/notifications/size-changed notification with width and height", async () => {
42
- const { result } = renderHook(() => useRequestSize());
43
- await result.current({ width: 800, height: 400 });
44
- await waitFor(() => {
45
- expect(postMessageMock).toHaveBeenCalledWith(expect.objectContaining({
46
- jsonrpc: "2.0",
47
- method: "ui/notifications/size-changed",
48
- params: { width: 800, height: 400 },
49
- }), "*");
50
- });
18
+ afterEach(() => {
19
+ vi.unstubAllGlobals();
20
+ vi.resetAllMocks();
21
+ HostAdaptor.resetInstance();
22
+ McpAppBridge.resetInstance();
23
+ });
24
+ it("sends a ui/notifications/size-changed notification with width and height", async () => {
25
+ const { result } = renderHook(() => useRequestSize());
26
+ await result.current({ width: 800, height: 400 });
27
+ await waitFor(() => {
28
+ expect(postMessageMock).toHaveBeenCalledWith(expect.objectContaining({
29
+ jsonrpc: "2.0",
30
+ method: "ui/notifications/size-changed",
31
+ params: { width: 800, height: 400 },
32
+ }), "*");
51
33
  });
52
- it("forwards height-only payloads as-is", async () => {
53
- const { result } = renderHook(() => useRequestSize());
54
- await result.current({ height: 400 });
55
- await waitFor(() => {
56
- expect(postMessageMock).toHaveBeenCalledWith(expect.objectContaining({
57
- jsonrpc: "2.0",
58
- method: "ui/notifications/size-changed",
59
- params: { height: 400 },
60
- }), "*");
61
- });
34
+ });
35
+ it("forwards height-only payloads as-is", async () => {
36
+ const { result } = renderHook(() => useRequestSize());
37
+ await result.current({ height: 400 });
38
+ await waitFor(() => {
39
+ expect(postMessageMock).toHaveBeenCalledWith(expect.objectContaining({
40
+ jsonrpc: "2.0",
41
+ method: "ui/notifications/size-changed",
42
+ params: { height: 400 },
43
+ }), "*");
62
44
  });
63
45
  });
64
46
  });
@@ -1 +1 @@
1
- {"version":3,"file":"use-request-size.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-request-size.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { renderHook, waitFor } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { AppsSdkAdaptor } from \"../bridges/apps-sdk/adaptor.js\";\nimport { McpAppBridge } from \"../bridges/mcp-app/bridge.js\";\nimport {\n getMcpAppHostPostMessageMock,\n MockResizeObserver,\n} from \"./test/utils.js\";\nimport { useRequestSize } from \"./use-request-size.js\";\n\ndescribe(\"useRequestSize\", () => {\n describe(\"apps-sdk host\", () => {\n let consoleWarnSpy: ReturnType<typeof vi.spyOn>;\n\n beforeEach(() => {\n AppsSdkAdaptor.resetInstance();\n vi.stubGlobal(\"openai\", {});\n vi.stubGlobal(\"skybridge\", { hostType: \"apps-sdk\" });\n consoleWarnSpy = vi.spyOn(console, \"warn\").mockImplementation(() => {});\n });\n\n afterEach(() => {\n AppsSdkAdaptor.resetInstance();\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n });\n\n it(\"warns that requestSize is not supported on Apps SDK\", async () => {\n const { result } = renderHook(() => useRequestSize());\n\n await result.current({ height: 400 });\n\n expect(consoleWarnSpy).toHaveBeenCalledTimes(1);\n expect(consoleWarnSpy.mock.calls[0]?.[0]).toContain(\"not supported\");\n });\n });\n\n describe(\"mcp-app host\", () => {\n let postMessageMock: ReturnType<typeof getMcpAppHostPostMessageMock>;\n\n beforeEach(() => {\n vi.stubGlobal(\"skybridge\", { hostType: \"mcp-app\" });\n vi.stubGlobal(\"ResizeObserver\", MockResizeObserver);\n postMessageMock = getMcpAppHostPostMessageMock();\n vi.stubGlobal(\"parent\", { postMessage: postMessageMock });\n });\n\n afterEach(async () => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n McpAppBridge.resetInstance();\n });\n\n it(\"sends a ui/notifications/size-changed notification with width and height\", async () => {\n const { result } = renderHook(() => useRequestSize());\n\n await result.current({ width: 800, height: 400 });\n\n await waitFor(() => {\n expect(postMessageMock).toHaveBeenCalledWith(\n expect.objectContaining({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/size-changed\",\n params: { width: 800, height: 400 },\n }),\n \"*\",\n );\n });\n });\n\n it(\"forwards height-only payloads as-is\", async () => {\n const { result } = renderHook(() => useRequestSize());\n\n await result.current({ height: 400 });\n\n await waitFor(() => {\n expect(postMessageMock).toHaveBeenCalledWith(\n expect.objectContaining({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/size-changed\",\n params: { height: 400 },\n }),\n \"*\",\n );\n });\n });\n });\n});\n"]}
1
+ {"version":3,"file":"use-request-size.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-request-size.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACL,4BAA4B,EAC5B,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAI,eAAgE,CAAC;IAErE,UAAU,CAAC,GAAG,EAAE;QACd,WAAW,CAAC,aAAa,EAAE,CAAC;QAC5B,YAAY,CAAC,aAAa,EAAE,CAAC;QAC7B,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC/B,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACnC,EAAE,CAAC,UAAU,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;QACpD,eAAe,GAAG,4BAA4B,EAAE,CAAC;QACjD,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;QACtB,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,WAAW,CAAC,aAAa,EAAE,CAAC;QAC5B,YAAY,CAAC,aAAa,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;QAEtD,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAElD,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,MAAM,CAAC,gBAAgB,CAAC;gBACtB,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,+BAA+B;gBACvC,MAAM,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;aACpC,CAAC,EACF,GAAG,CACJ,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;QAEtD,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAEtC,MAAM,OAAO,CAAC,GAAG,EAAE;YACjB,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAC1C,MAAM,CAAC,gBAAgB,CAAC;gBACtB,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,+BAA+B;gBACvC,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE;aACxB,CAAC,EACF,GAAG,CACJ,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { renderHook, waitFor } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { HostAdaptor } from \"../bridges/adaptor.js\";\nimport { McpAppBridge } from \"../bridges/mcp-app/bridge.js\";\nimport {\n getMcpAppHostPostMessageMock,\n MockResizeObserver,\n} from \"./test/utils.js\";\nimport { useRequestSize } from \"./use-request-size.js\";\n\ndescribe(\"useRequestSize\", () => {\n let postMessageMock: ReturnType<typeof getMcpAppHostPostMessageMock>;\n\n beforeEach(() => {\n HostAdaptor.resetInstance();\n McpAppBridge.resetInstance();\n vi.stubGlobal(\"skybridge\", {});\n vi.stubGlobal(\"openai\", undefined);\n vi.stubGlobal(\"ResizeObserver\", MockResizeObserver);\n postMessageMock = getMcpAppHostPostMessageMock();\n vi.stubGlobal(\"parent\", { postMessage: postMessageMock });\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n HostAdaptor.resetInstance();\n McpAppBridge.resetInstance();\n });\n\n it(\"sends a ui/notifications/size-changed notification with width and height\", async () => {\n const { result } = renderHook(() => useRequestSize());\n\n await result.current({ width: 800, height: 400 });\n\n await waitFor(() => {\n expect(postMessageMock).toHaveBeenCalledWith(\n expect.objectContaining({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/size-changed\",\n params: { width: 800, height: 400 },\n }),\n \"*\",\n );\n });\n });\n\n it(\"forwards height-only payloads as-is\", async () => {\n const { result } = renderHook(() => useRequestSize());\n\n await result.current({ height: 400 });\n\n await waitFor(() => {\n expect(postMessageMock).toHaveBeenCalledWith(\n expect.objectContaining({\n jsonrpc: \"2.0\",\n method: \"ui/notifications/size-changed\",\n params: { height: 400 },\n }),\n \"*\",\n );\n });\n });\n});\n"]}
@@ -1,8 +1,18 @@
1
1
  import { renderHook } from "@testing-library/react";
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
- import { AppsSdkAdaptor } from "../bridges/apps-sdk/adaptor.js";
3
+ import { HostAdaptor } from "../bridges/adaptor.js";
4
+ import { AppsSdkBridge } from "../bridges/apps-sdk/bridge.js";
5
+ import { McpAppBridge } from "../bridges/mcp-app/bridge.js";
6
+ import { NotSupportedError } from "../bridges/types.js";
4
7
  import { useSetOpenInAppUrl } from "./use-set-open-in-app-url.js";
5
8
  describe("useSetOpenInAppUrl", () => {
9
+ afterEach(() => {
10
+ vi.unstubAllGlobals();
11
+ vi.resetAllMocks();
12
+ HostAdaptor.resetInstance();
13
+ AppsSdkBridge.resetInstance();
14
+ McpAppBridge.resetInstance();
15
+ });
6
16
  describe("apps-sdk host", () => {
7
17
  let setOpenInAppUrlMock;
8
18
  beforeEach(() => {
@@ -10,15 +20,8 @@ describe("useSetOpenInAppUrl", () => {
10
20
  vi.stubGlobal("openai", {
11
21
  setOpenInAppUrl: setOpenInAppUrlMock,
12
22
  });
13
- vi.stubGlobal("skybridge", {
14
- hostType: "apps-sdk",
15
- serverUrl: "https://example.com",
16
- });
17
- });
18
- afterEach(() => {
19
- vi.unstubAllGlobals();
20
- vi.resetAllMocks();
21
- AppsSdkAdaptor.resetInstance();
23
+ vi.stubGlobal("skybridge", { serverUrl: "https://example.com" });
24
+ vi.stubGlobal("parent", { postMessage: vi.fn() });
22
25
  });
23
26
  it("should return a function that calls window.openai.setOpenInAppUrl with the href", async () => {
24
27
  const { result } = renderHook(() => useSetOpenInAppUrl());
@@ -27,9 +30,9 @@ describe("useSetOpenInAppUrl", () => {
27
30
  expect(setOpenInAppUrlMock).toHaveBeenCalledTimes(1);
28
31
  expect(setOpenInAppUrlMock).toHaveBeenCalledWith({ href });
29
32
  });
30
- it("should throw an error when href is empty", () => {
33
+ it("should reject when href is empty", async () => {
31
34
  const { result } = renderHook(() => useSetOpenInAppUrl());
32
- expect(() => result.current("")).toThrow("The href parameter is required.");
35
+ await expect(result.current("")).rejects.toThrow("The href parameter is required.");
33
36
  });
34
37
  it("should call setOpenInAppUrl when href origin differs from serverUrl origin", async () => {
35
38
  const { result } = renderHook(() => useSetOpenInAppUrl());
@@ -39,5 +42,16 @@ describe("useSetOpenInAppUrl", () => {
39
42
  expect(setOpenInAppUrlMock).toHaveBeenCalledWith({ href });
40
43
  });
41
44
  });
45
+ describe("mcp-app host", () => {
46
+ beforeEach(() => {
47
+ vi.stubGlobal("openai", undefined);
48
+ vi.stubGlobal("skybridge", { serverUrl: "https://example.com" });
49
+ vi.stubGlobal("parent", { postMessage: vi.fn() });
50
+ });
51
+ it("should throw NotSupportedError when called from an MCP App runtime", async () => {
52
+ const { result } = renderHook(() => useSetOpenInAppUrl());
53
+ await expect(result.current("https://example.com/path")).rejects.toBeInstanceOf(NotSupportedError);
54
+ });
55
+ });
42
56
  });
43
57
  //# sourceMappingURL=use-set-open-in-app-url.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-set-open-in-app-url.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-set-open-in-app-url.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,IAAI,mBAA6C,CAAC;QAElD,UAAU,CAAC,GAAG,EAAE;YACd,mBAAmB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAC3D,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE;gBACtB,eAAe,EAAE,mBAAmB;aACrC,CAAC,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE;gBACzB,QAAQ,EAAE,UAAU;gBACpB,SAAS,EAAE,qBAAqB;aACjC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,GAAG,EAAE;YACb,EAAE,CAAC,gBAAgB,EAAE,CAAC;YACtB,EAAE,CAAC,aAAa,EAAE,CAAC;YACnB,cAAc,CAAC,aAAa,EAAE,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;YAC/F,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAE1D,MAAM,IAAI,GAAG,0BAA0B,CAAC;YACxC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAE3B,MAAM,CAAC,mBAAmB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,mBAAmB,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAE1D,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CACtC,iCAAiC,CAClC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;YAC1F,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,kBAAkB,EAAE,CAAC,CAAC;YAE1D,MAAM,IAAI,GAAG,mCAAmC,CAAC;YACjD,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAE3B,MAAM,CAAC,mBAAmB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM,CAAC,mBAAmB,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { renderHook } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { AppsSdkAdaptor } from \"../bridges/apps-sdk/adaptor.js\";\nimport { useSetOpenInAppUrl } from \"./use-set-open-in-app-url.js\";\n\ndescribe(\"useSetOpenInAppUrl\", () => {\n describe(\"apps-sdk host\", () => {\n let setOpenInAppUrlMock: ReturnType<typeof vi.fn>;\n\n beforeEach(() => {\n setOpenInAppUrlMock = vi.fn().mockResolvedValue(undefined);\n vi.stubGlobal(\"openai\", {\n setOpenInAppUrl: setOpenInAppUrlMock,\n });\n vi.stubGlobal(\"skybridge\", {\n hostType: \"apps-sdk\",\n serverUrl: \"https://example.com\",\n });\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n AppsSdkAdaptor.resetInstance();\n });\n\n it(\"should return a function that calls window.openai.setOpenInAppUrl with the href\", async () => {\n const { result } = renderHook(() => useSetOpenInAppUrl());\n\n const href = \"https://example.com/path\";\n await result.current(href);\n\n expect(setOpenInAppUrlMock).toHaveBeenCalledTimes(1);\n expect(setOpenInAppUrlMock).toHaveBeenCalledWith({ href });\n });\n\n it(\"should throw an error when href is empty\", () => {\n const { result } = renderHook(() => useSetOpenInAppUrl());\n\n expect(() => result.current(\"\")).toThrow(\n \"The href parameter is required.\",\n );\n });\n\n it(\"should call setOpenInAppUrl when href origin differs from serverUrl origin\", async () => {\n const { result } = renderHook(() => useSetOpenInAppUrl());\n\n const href = \"https://different-domain.com/path\";\n await result.current(href);\n\n expect(setOpenInAppUrlMock).toHaveBeenCalledTimes(1);\n expect(setOpenInAppUrlMock).toHaveBeenCalledWith({ href });\n });\n });\n});\n"]}
1
+ {"version":3,"file":"use-set-open-in-app-url.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-set-open-in-app-url.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { renderHook } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { HostAdaptor } from \"../bridges/adaptor.js\";\nimport { AppsSdkBridge } from \"../bridges/apps-sdk/bridge.js\";\nimport { McpAppBridge } from \"../bridges/mcp-app/bridge.js\";\nimport { NotSupportedError } from \"../bridges/types.js\";\nimport { useSetOpenInAppUrl } from \"./use-set-open-in-app-url.js\";\n\ndescribe(\"useSetOpenInAppUrl\", () => {\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n HostAdaptor.resetInstance();\n AppsSdkBridge.resetInstance();\n McpAppBridge.resetInstance();\n });\n\n describe(\"apps-sdk host\", () => {\n let setOpenInAppUrlMock: ReturnType<typeof vi.fn>;\n\n beforeEach(() => {\n setOpenInAppUrlMock = vi.fn().mockResolvedValue(undefined);\n vi.stubGlobal(\"openai\", {\n setOpenInAppUrl: setOpenInAppUrlMock,\n });\n vi.stubGlobal(\"skybridge\", { serverUrl: \"https://example.com\" });\n vi.stubGlobal(\"parent\", { postMessage: vi.fn() });\n });\n\n it(\"should return a function that calls window.openai.setOpenInAppUrl with the href\", async () => {\n const { result } = renderHook(() => useSetOpenInAppUrl());\n\n const href = \"https://example.com/path\";\n await result.current(href);\n\n expect(setOpenInAppUrlMock).toHaveBeenCalledTimes(1);\n expect(setOpenInAppUrlMock).toHaveBeenCalledWith({ href });\n });\n\n it(\"should reject when href is empty\", async () => {\n const { result } = renderHook(() => useSetOpenInAppUrl());\n\n await expect(result.current(\"\")).rejects.toThrow(\n \"The href parameter is required.\",\n );\n });\n\n it(\"should call setOpenInAppUrl when href origin differs from serverUrl origin\", async () => {\n const { result } = renderHook(() => useSetOpenInAppUrl());\n\n const href = \"https://different-domain.com/path\";\n await result.current(href);\n\n expect(setOpenInAppUrlMock).toHaveBeenCalledTimes(1);\n expect(setOpenInAppUrlMock).toHaveBeenCalledWith({ href });\n });\n });\n\n describe(\"mcp-app host\", () => {\n beforeEach(() => {\n vi.stubGlobal(\"openai\", undefined);\n vi.stubGlobal(\"skybridge\", { serverUrl: \"https://example.com\" });\n vi.stubGlobal(\"parent\", { postMessage: vi.fn() });\n });\n\n it(\"should throw NotSupportedError when called from an MCP App runtime\", async () => {\n const { result } = renderHook(() => useSetOpenInAppUrl());\n\n await expect(\n result.current(\"https://example.com/path\"),\n ).rejects.toBeInstanceOf(NotSupportedError);\n });\n });\n});\n"]}
@@ -1,39 +1,38 @@
1
1
  import type { UnknownObject } from "../types.js";
2
- /** {@link useToolInfo} state before the tool has been invoked. */
3
- export type ToolIdleState = {
4
- status: "idle";
5
- isIdle: true;
6
- isPending: false;
7
- isSuccess: false;
8
- input: undefined;
9
- output: undefined;
10
- responseMetadata: undefined;
11
- };
12
- /** {@link useToolInfo} state while the tool is executing — `input` is available, output is not yet. */
2
+ /**
3
+ * {@link useToolInfo} state while the tool is executing — `output` is not yet
4
+ * available.
5
+ *
6
+ * `input` is optional: the host may render the view before delivering the
7
+ * tool arguments.
8
+ */
13
9
  export type ToolPendingState<ToolInput extends UnknownObject> = {
14
10
  status: "pending";
15
- isIdle: false;
16
11
  isPending: true;
17
12
  isSuccess: false;
18
- input: ToolInput;
13
+ input: ToolInput | undefined;
19
14
  output: undefined;
20
15
  responseMetadata: undefined;
21
16
  };
22
- /** {@link useToolInfo} state once the tool returned — `input`, `output`, and `responseMetadata` are all available. */
17
+ /**
18
+ * {@link useToolInfo} state once the tool returned — `output` is available.
19
+ *
20
+ * `input` is optional: the host may not have surfaced the tool arguments by
21
+ * the time `output` arrives.
22
+ */
23
23
  export type ToolSuccessState<ToolInput extends UnknownObject, ToolOutput extends UnknownObject, ToolResponseMetadata extends UnknownObject> = {
24
24
  status: "success";
25
- isIdle: false;
26
25
  isPending: false;
27
26
  isSuccess: true;
28
- input: ToolInput;
27
+ input: ToolInput | undefined;
29
28
  output: ToolOutput;
30
29
  responseMetadata: ToolResponseMetadata;
31
30
  };
32
31
  /**
33
32
  * Discriminated union describing the tool invocation that triggered the
34
- * current view render. Use `isIdle` / `isPending` / `isSuccess` to narrow.
33
+ * current view render. Use `isPending` / `isSuccess` to narrow.
35
34
  */
36
- export type ToolState<ToolInput extends UnknownObject, ToolOutput extends UnknownObject, ToolResponseMetadata extends UnknownObject> = ToolIdleState | ToolPendingState<ToolInput> | ToolSuccessState<ToolInput, ToolOutput, ToolResponseMetadata>;
35
+ export type ToolState<ToolInput extends UnknownObject, ToolOutput extends UnknownObject, ToolResponseMetadata extends UnknownObject> = ToolPendingState<ToolInput> | ToolSuccessState<ToolInput, ToolOutput, ToolResponseMetadata>;
37
36
  type ToolSignature = {
38
37
  input: UnknownObject;
39
38
  output: UnknownObject;
@@ -42,7 +41,7 @@ type ToolSignature = {
42
41
  /**
43
42
  * Access the tool invocation that produced the current view: its `input`,
44
43
  * resulting `output`, and `responseMetadata`. The shape evolves as the tool
45
- * runs (idle → pending → success), exposed through {@link ToolState}.
44
+ * runs (pending → success), exposed through {@link ToolState}.
46
45
  *
47
46
  * For full input/output typing per tool name, prefer the typed `useToolInfo`
48
47
  * returned by {@link generateHelpers} over the generic form.