skybridge 0.0.0-dev.dc4ed16 → 0.0.0-dev.dc576c4

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 (476) hide show
  1. package/LICENSE +21 -674
  2. package/README.md +123 -386
  3. package/bin/run.js +5 -0
  4. package/dist/cli/detect-port.d.ts +18 -0
  5. package/dist/cli/detect-port.js +61 -0
  6. package/dist/cli/detect-port.js.map +1 -0
  7. package/dist/cli/header.d.ts +4 -0
  8. package/dist/cli/header.js +6 -0
  9. package/dist/cli/header.js.map +1 -0
  10. package/dist/cli/resolve-views-dir.d.ts +1 -0
  11. package/dist/cli/resolve-views-dir.js +17 -0
  12. package/dist/cli/resolve-views-dir.js.map +1 -0
  13. package/dist/cli/run-command.d.ts +2 -0
  14. package/dist/cli/run-command.js +43 -0
  15. package/dist/cli/run-command.js.map +1 -0
  16. package/dist/cli/telemetry.d.ts +7 -0
  17. package/dist/cli/telemetry.js +123 -0
  18. package/dist/cli/telemetry.js.map +1 -0
  19. package/dist/cli/tunnel-control-server.d.ts +9 -0
  20. package/dist/cli/tunnel-control-server.js +31 -0
  21. package/dist/cli/tunnel-control-server.js.map +1 -0
  22. package/dist/cli/tunnel-control-server.test.js +39 -0
  23. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  24. package/dist/cli/tunnel-handler.d.ts +3 -0
  25. package/dist/cli/tunnel-handler.js +48 -0
  26. package/dist/cli/tunnel-handler.js.map +1 -0
  27. package/dist/cli/tunnel-handler.test.js +105 -0
  28. package/dist/cli/tunnel-handler.test.js.map +1 -0
  29. package/dist/cli/tunnel.d.ts +57 -0
  30. package/dist/cli/tunnel.js +154 -0
  31. package/dist/cli/tunnel.js.map +1 -0
  32. package/dist/cli/tunnel.test.js +190 -0
  33. package/dist/cli/tunnel.test.js.map +1 -0
  34. package/dist/cli/types.d.ts +5 -0
  35. package/dist/cli/types.js +2 -0
  36. package/dist/cli/types.js.map +1 -0
  37. package/dist/cli/use-execute-steps.d.ts +11 -0
  38. package/dist/cli/use-execute-steps.js +36 -0
  39. package/dist/cli/use-execute-steps.js.map +1 -0
  40. package/dist/cli/use-messages.d.ts +3 -0
  41. package/dist/cli/use-messages.js +11 -0
  42. package/dist/cli/use-messages.js.map +1 -0
  43. package/dist/cli/use-nodemon.d.ts +2 -0
  44. package/dist/cli/use-nodemon.js +73 -0
  45. package/dist/cli/use-nodemon.js.map +1 -0
  46. package/dist/cli/use-open-browser.d.ts +1 -0
  47. package/dist/cli/use-open-browser.js +44 -0
  48. package/dist/cli/use-open-browser.js.map +1 -0
  49. package/dist/cli/use-tunnel.d.ts +14 -0
  50. package/dist/cli/use-tunnel.js +131 -0
  51. package/dist/cli/use-tunnel.js.map +1 -0
  52. package/dist/cli/use-typescript-check.d.ts +9 -0
  53. package/dist/cli/use-typescript-check.js +94 -0
  54. package/dist/cli/use-typescript-check.js.map +1 -0
  55. package/dist/commands/build.d.ts +9 -0
  56. package/dist/commands/build.js +87 -0
  57. package/dist/commands/build.js.map +1 -0
  58. package/dist/commands/create.d.ts +9 -0
  59. package/dist/commands/create.js +30 -0
  60. package/dist/commands/create.js.map +1 -0
  61. package/dist/commands/dev.d.ts +12 -0
  62. package/dist/commands/dev.js +96 -0
  63. package/dist/commands/dev.js.map +1 -0
  64. package/dist/commands/start.d.ts +9 -0
  65. package/dist/commands/start.js +49 -0
  66. package/dist/commands/start.js.map +1 -0
  67. package/dist/commands/telemetry/disable.d.ts +5 -0
  68. package/dist/commands/telemetry/disable.js +14 -0
  69. package/dist/commands/telemetry/disable.js.map +1 -0
  70. package/dist/commands/telemetry/enable.d.ts +5 -0
  71. package/dist/commands/telemetry/enable.js +14 -0
  72. package/dist/commands/telemetry/enable.js.map +1 -0
  73. package/dist/commands/telemetry/status.d.ts +5 -0
  74. package/dist/commands/telemetry/status.js +14 -0
  75. package/dist/commands/telemetry/status.js.map +1 -0
  76. package/dist/server/asset-base-url-transform-plugin.d.ts +11 -0
  77. package/dist/server/asset-base-url-transform-plugin.js +48 -0
  78. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  79. package/dist/server/asset-base-url-transform-plugin.test.js +134 -0
  80. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  81. package/dist/server/auth.d.ts +20 -0
  82. package/dist/server/auth.js +28 -0
  83. package/dist/server/auth.js.map +1 -0
  84. package/dist/server/content-helpers.d.ts +67 -0
  85. package/dist/server/content-helpers.js +79 -0
  86. package/dist/server/content-helpers.js.map +1 -0
  87. package/dist/server/content-helpers.test.js +70 -0
  88. package/dist/server/content-helpers.test.js.map +1 -0
  89. package/dist/server/express.d.ts +11 -0
  90. package/dist/server/express.js +101 -0
  91. package/dist/server/express.js.map +1 -0
  92. package/dist/server/express.test.js +430 -0
  93. package/dist/server/express.test.js.map +1 -0
  94. package/dist/server/file-ref.d.ts +28 -0
  95. package/dist/server/file-ref.js +27 -0
  96. package/dist/server/file-ref.js.map +1 -0
  97. package/dist/server/index.d.ts +8 -0
  98. package/dist/server/index.js +6 -0
  99. package/dist/server/index.js.map +1 -0
  100. package/dist/{src/server → server}/inferUtilityTypes.d.ts +15 -5
  101. package/dist/server/inferUtilityTypes.js.map +1 -0
  102. package/dist/server/metric.d.ts +14 -0
  103. package/dist/server/metric.js +62 -0
  104. package/dist/server/metric.js.map +1 -0
  105. package/dist/server/middleware.d.ts +137 -0
  106. package/dist/server/middleware.js +93 -0
  107. package/dist/server/middleware.js.map +1 -0
  108. package/dist/server/middleware.test-d.js +75 -0
  109. package/dist/server/middleware.test-d.js.map +1 -0
  110. package/dist/server/middleware.test.js +493 -0
  111. package/dist/server/middleware.test.js.map +1 -0
  112. package/dist/server/server.d.ts +398 -0
  113. package/dist/server/server.js +561 -0
  114. package/dist/server/server.js.map +1 -0
  115. package/dist/{src/server → server}/templateHelper.d.ts +5 -4
  116. package/dist/server/templateHelper.js +11 -0
  117. package/dist/server/templateHelper.js.map +1 -0
  118. package/dist/server/templates.generated.d.ts +4 -0
  119. package/dist/server/templates.generated.js +47 -0
  120. package/dist/server/templates.generated.js.map +1 -0
  121. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  122. package/dist/server/tunnel-proxy-router.js +110 -0
  123. package/dist/server/tunnel-proxy-router.js.map +1 -0
  124. package/dist/server/tunnel-proxy-router.test.js +229 -0
  125. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  126. package/dist/server/viewsDevServer.d.ts +14 -0
  127. package/dist/server/viewsDevServer.js +45 -0
  128. package/dist/server/viewsDevServer.js.map +1 -0
  129. package/dist/test/utils.d.ts +127 -0
  130. package/dist/test/utils.js +247 -0
  131. package/dist/test/utils.js.map +1 -0
  132. package/dist/test/view.test.js +568 -0
  133. package/dist/test/view.test.js.map +1 -0
  134. package/dist/version.d.ts +1 -0
  135. package/dist/version.js +3 -0
  136. package/dist/version.js.map +1 -0
  137. package/dist/web/bridges/adaptor.d.ts +48 -0
  138. package/dist/web/bridges/adaptor.js +308 -0
  139. package/dist/web/bridges/adaptor.js.map +1 -0
  140. package/dist/web/bridges/adaptor.test.js +205 -0
  141. package/dist/web/bridges/adaptor.test.js.map +1 -0
  142. package/dist/web/bridges/apps-sdk/bridge.d.ts +11 -0
  143. package/dist/web/bridges/apps-sdk/bridge.js +46 -0
  144. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  145. package/dist/web/bridges/apps-sdk/index.d.ts +4 -0
  146. package/dist/web/bridges/apps-sdk/index.js +4 -0
  147. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  148. package/dist/web/bridges/apps-sdk/types.d.ts +133 -0
  149. package/dist/{src/web → web/bridges/apps-sdk}/types.js +0 -1
  150. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  151. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +13 -0
  152. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +18 -0
  153. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  154. package/dist/web/bridges/get-adaptor.d.ts +11 -0
  155. package/dist/web/bridges/get-adaptor.js +30 -0
  156. package/dist/web/bridges/get-adaptor.js.map +1 -0
  157. package/dist/web/bridges/get-adaptor.test.js +48 -0
  158. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  159. package/dist/web/bridges/host-context-stores.d.ts +27 -0
  160. package/dist/web/bridges/host-context-stores.js +73 -0
  161. package/dist/web/bridges/host-context-stores.js.map +1 -0
  162. package/dist/web/bridges/index.d.ts +5 -0
  163. package/dist/web/bridges/index.js +6 -0
  164. package/dist/web/bridges/index.js.map +1 -0
  165. package/dist/web/bridges/mcp-app/bridge.d.ts +27 -0
  166. package/dist/web/bridges/mcp-app/bridge.js +100 -0
  167. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  168. package/dist/web/bridges/mcp-app/bridge.test.js +21 -0
  169. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  170. package/dist/web/bridges/mcp-app/index.d.ts +3 -0
  171. package/dist/web/bridges/mcp-app/index.js +3 -0
  172. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  173. package/dist/web/bridges/mcp-app/types.d.ts +8 -0
  174. package/dist/web/bridges/mcp-app/types.js +2 -0
  175. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  176. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +19 -0
  177. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +19 -0
  178. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  179. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +26 -0
  180. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  181. package/dist/web/bridges/types.d.ts +186 -0
  182. package/dist/web/bridges/types.js +15 -0
  183. package/dist/web/bridges/types.js.map +1 -0
  184. package/dist/web/bridges/types.test.js +19 -0
  185. package/dist/web/bridges/types.test.js.map +1 -0
  186. package/dist/web/bridges/use-host-context.d.ts +7 -0
  187. package/dist/web/bridges/use-host-context.js +13 -0
  188. package/dist/web/bridges/use-host-context.js.map +1 -0
  189. package/dist/web/components/modal-provider.d.ts +4 -0
  190. package/dist/web/components/modal-provider.js +46 -0
  191. package/dist/web/components/modal-provider.js.map +1 -0
  192. package/dist/web/create-store.d.ts +29 -0
  193. package/dist/web/create-store.js +64 -0
  194. package/dist/web/create-store.js.map +1 -0
  195. package/dist/web/create-store.test.js +131 -0
  196. package/dist/web/create-store.test.js.map +1 -0
  197. package/dist/web/data-llm.d.ts +47 -0
  198. package/dist/{src/web → web}/data-llm.js +41 -9
  199. package/dist/web/data-llm.js.map +1 -0
  200. package/dist/web/data-llm.test.js +145 -0
  201. package/dist/web/data-llm.test.js.map +1 -0
  202. package/dist/{src/web → web}/generate-helpers.d.ts +32 -25
  203. package/dist/{src/web → web}/generate-helpers.js +26 -20
  204. package/dist/web/generate-helpers.js.map +1 -0
  205. package/dist/{src/web → web}/generate-helpers.test-d.js +79 -23
  206. package/dist/web/generate-helpers.test-d.js.map +1 -0
  207. package/dist/{src/web → web}/generate-helpers.test.js +1 -1
  208. package/dist/web/generate-helpers.test.js.map +1 -0
  209. package/dist/{src/web → web}/helpers/state.d.ts +2 -2
  210. package/dist/web/helpers/state.js +45 -0
  211. package/dist/web/helpers/state.js.map +1 -0
  212. package/dist/web/helpers/state.test.d.ts +1 -0
  213. package/dist/web/helpers/state.test.js +53 -0
  214. package/dist/web/helpers/state.test.js.map +1 -0
  215. package/dist/web/hooks/index.d.ts +14 -0
  216. package/dist/web/hooks/index.js +15 -0
  217. package/dist/web/hooks/index.js.map +1 -0
  218. package/dist/web/hooks/test/utils.d.ts +20 -0
  219. package/dist/web/hooks/test/utils.js +75 -0
  220. package/dist/web/hooks/test/utils.js.map +1 -0
  221. package/dist/{src/web → web}/hooks/use-call-tool.d.ts +48 -2
  222. package/dist/web/hooks/use-call-tool.js +96 -0
  223. package/dist/web/hooks/use-call-tool.js.map +1 -0
  224. package/dist/web/hooks/use-call-tool.test-d.d.ts +1 -0
  225. package/dist/{src/web → web}/hooks/use-call-tool.test-d.js +1 -1
  226. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  227. package/dist/web/hooks/use-call-tool.test.d.ts +1 -0
  228. package/dist/{src/web → web}/hooks/use-call-tool.test.js +92 -39
  229. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  230. package/dist/web/hooks/use-display-mode.d.ts +24 -0
  231. package/dist/web/hooks/use-display-mode.js +29 -0
  232. package/dist/web/hooks/use-display-mode.js.map +1 -0
  233. package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
  234. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  235. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  236. package/dist/web/hooks/use-display-mode.test.d.ts +1 -0
  237. package/dist/web/hooks/use-display-mode.test.js +76 -0
  238. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  239. package/dist/web/hooks/use-download.d.ts +5 -0
  240. package/dist/web/hooks/use-download.js +8 -0
  241. package/dist/web/hooks/use-download.js.map +1 -0
  242. package/dist/web/hooks/use-download.test.d.ts +1 -0
  243. package/dist/web/hooks/use-download.test.js +103 -0
  244. package/dist/web/hooks/use-download.test.js.map +1 -0
  245. package/dist/web/hooks/use-files.d.ts +39 -0
  246. package/dist/web/hooks/use-files.js +42 -0
  247. package/dist/web/hooks/use-files.js.map +1 -0
  248. package/dist/web/hooks/use-files.test.d.ts +1 -0
  249. package/dist/web/hooks/use-files.test.js +62 -0
  250. package/dist/web/hooks/use-files.test.js.map +1 -0
  251. package/dist/web/hooks/use-layout.d.ts +24 -0
  252. package/dist/web/hooks/use-layout.js +25 -0
  253. package/dist/web/hooks/use-layout.js.map +1 -0
  254. package/dist/web/hooks/use-layout.test.d.ts +1 -0
  255. package/dist/web/hooks/use-layout.test.js +129 -0
  256. package/dist/web/hooks/use-layout.test.js.map +1 -0
  257. package/dist/web/hooks/use-open-external.d.ts +20 -0
  258. package/dist/web/hooks/use-open-external.js +24 -0
  259. package/dist/web/hooks/use-open-external.js.map +1 -0
  260. package/dist/web/hooks/use-open-external.test.d.ts +1 -0
  261. package/dist/web/hooks/use-open-external.test.js +79 -0
  262. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  263. package/dist/web/hooks/use-request-close.d.ts +16 -0
  264. package/dist/web/hooks/use-request-close.js +21 -0
  265. package/dist/web/hooks/use-request-close.js.map +1 -0
  266. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  267. package/dist/web/hooks/use-request-close.test.js +46 -0
  268. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  269. package/dist/web/hooks/use-request-modal.d.ts +24 -0
  270. package/dist/web/hooks/use-request-modal.js +31 -0
  271. package/dist/web/hooks/use-request-modal.js.map +1 -0
  272. package/dist/web/hooks/use-request-modal.test.d.ts +1 -0
  273. package/dist/web/hooks/use-request-modal.test.js +71 -0
  274. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  275. package/dist/web/hooks/use-request-size.d.ts +20 -0
  276. package/dist/web/hooks/use-request-size.js +24 -0
  277. package/dist/web/hooks/use-request-size.js.map +1 -0
  278. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  279. package/dist/web/hooks/use-request-size.test.js +47 -0
  280. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  281. package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -0
  282. package/dist/web/hooks/use-send-follow-up-message.js +25 -0
  283. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  284. package/dist/web/hooks/use-set-open-in-app-url.d.ts +18 -0
  285. package/dist/web/hooks/use-set-open-in-app-url.js +25 -0
  286. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  287. package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
  288. package/dist/web/hooks/use-set-open-in-app-url.test.js +63 -0
  289. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  290. package/dist/web/hooks/use-tool-info.d.ts +69 -0
  291. package/dist/web/hooks/use-tool-info.js +52 -0
  292. package/dist/web/hooks/use-tool-info.js.map +1 -0
  293. package/dist/web/hooks/use-tool-info.test-d.d.ts +1 -0
  294. package/dist/{src/web → web}/hooks/use-tool-info.test-d.js +40 -5
  295. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  296. package/dist/web/hooks/use-tool-info.test.d.ts +1 -0
  297. package/dist/web/hooks/use-tool-info.test.js +140 -0
  298. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  299. package/dist/web/hooks/use-user.d.ts +20 -0
  300. package/dist/web/hooks/use-user.js +37 -0
  301. package/dist/web/hooks/use-user.js.map +1 -0
  302. package/dist/web/hooks/use-user.test.d.ts +1 -0
  303. package/dist/web/hooks/use-user.test.js +168 -0
  304. package/dist/web/hooks/use-user.test.js.map +1 -0
  305. package/dist/web/hooks/use-view-state.d.ts +25 -0
  306. package/dist/web/hooks/use-view-state.js +32 -0
  307. package/dist/web/hooks/use-view-state.js.map +1 -0
  308. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  309. package/dist/web/hooks/use-view-state.test.js +181 -0
  310. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  311. package/dist/{src/web → web}/index.d.ts +5 -5
  312. package/dist/{src/web → web}/index.js +5 -5
  313. package/dist/web/index.js.map +1 -0
  314. package/dist/web/mount-view.d.ts +20 -0
  315. package/dist/web/mount-view.js +46 -0
  316. package/dist/web/mount-view.js.map +1 -0
  317. package/dist/web/plugin/data-llm.test.d.ts +1 -0
  318. package/dist/web/plugin/data-llm.test.js.map +1 -0
  319. package/dist/web/plugin/plugin.d.ts +33 -0
  320. package/dist/web/plugin/plugin.js +189 -0
  321. package/dist/web/plugin/plugin.js.map +1 -0
  322. package/dist/web/plugin/scan-views.d.ts +16 -0
  323. package/dist/web/plugin/scan-views.js +88 -0
  324. package/dist/web/plugin/scan-views.js.map +1 -0
  325. package/dist/web/plugin/scan-views.test.d.ts +1 -0
  326. package/dist/web/plugin/scan-views.test.js +99 -0
  327. package/dist/web/plugin/scan-views.test.js.map +1 -0
  328. package/dist/{src/web → web}/plugin/transform-data-llm.js +7 -4
  329. package/dist/web/plugin/transform-data-llm.js.map +1 -0
  330. package/dist/web/plugin/transform-data-llm.test.d.ts +1 -0
  331. package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
  332. package/dist/web/plugin/validate-view.d.ts +1 -0
  333. package/dist/web/plugin/validate-view.js +9 -0
  334. package/dist/web/plugin/validate-view.js.map +1 -0
  335. package/dist/web/plugin/validate-view.test.d.ts +1 -0
  336. package/dist/web/plugin/validate-view.test.js +24 -0
  337. package/dist/web/plugin/validate-view.test.js.map +1 -0
  338. package/dist/{src/web → web}/proxy.js +6 -2
  339. package/dist/web/proxy.js.map +1 -0
  340. package/dist/web/types.d.ts +20 -0
  341. package/dist/web/types.js +2 -0
  342. package/dist/web/types.js.map +1 -0
  343. package/package.json +83 -38
  344. package/tsconfig.base.json +33 -0
  345. package/dist/src/server/index.d.ts +0 -4
  346. package/dist/src/server/index.js +0 -3
  347. package/dist/src/server/index.js.map +0 -1
  348. package/dist/src/server/inferUtilityTypes.js.map +0 -1
  349. package/dist/src/server/server.d.ts +0 -48
  350. package/dist/src/server/server.js +0 -62
  351. package/dist/src/server/server.js.map +0 -1
  352. package/dist/src/server/templateHelper.js +0 -29
  353. package/dist/src/server/templateHelper.js.map +0 -1
  354. package/dist/src/server/templates/development.hbs +0 -12
  355. package/dist/src/server/templates/production.hbs +0 -6
  356. package/dist/src/server/widgetsDevServer.d.ts +0 -12
  357. package/dist/src/server/widgetsDevServer.js +0 -39
  358. package/dist/src/server/widgetsDevServer.js.map +0 -1
  359. package/dist/src/test/utils.d.ts +0 -89
  360. package/dist/src/test/utils.js +0 -164
  361. package/dist/src/test/utils.js.map +0 -1
  362. package/dist/src/test/widget.test.js +0 -90
  363. package/dist/src/test/widget.test.js.map +0 -1
  364. package/dist/src/web/create-store.d.ts +0 -3
  365. package/dist/src/web/create-store.js +0 -25
  366. package/dist/src/web/create-store.js.map +0 -1
  367. package/dist/src/web/data-llm.d.ts +0 -14
  368. package/dist/src/web/data-llm.js.map +0 -1
  369. package/dist/src/web/data-llm.test.js +0 -76
  370. package/dist/src/web/data-llm.test.js.map +0 -1
  371. package/dist/src/web/generate-helpers.js.map +0 -1
  372. package/dist/src/web/generate-helpers.test-d.js.map +0 -1
  373. package/dist/src/web/generate-helpers.test.js.map +0 -1
  374. package/dist/src/web/helpers/state.js +0 -40
  375. package/dist/src/web/helpers/state.js.map +0 -1
  376. package/dist/src/web/helpers/state.test.js +0 -46
  377. package/dist/src/web/helpers/state.test.js.map +0 -1
  378. package/dist/src/web/hooks/index.d.ts +0 -12
  379. package/dist/src/web/hooks/index.js +0 -13
  380. package/dist/src/web/hooks/index.js.map +0 -1
  381. package/dist/src/web/hooks/use-call-tool.js +0 -60
  382. package/dist/src/web/hooks/use-call-tool.js.map +0 -1
  383. package/dist/src/web/hooks/use-call-tool.test-d.js.map +0 -1
  384. package/dist/src/web/hooks/use-call-tool.test.js.map +0 -1
  385. package/dist/src/web/hooks/use-display-mode.d.ts +0 -4
  386. package/dist/src/web/hooks/use-display-mode.js +0 -7
  387. package/dist/src/web/hooks/use-display-mode.js.map +0 -1
  388. package/dist/src/web/hooks/use-display-mode.test.js +0 -40
  389. package/dist/src/web/hooks/use-display-mode.test.js.map +0 -1
  390. package/dist/src/web/hooks/use-files.d.ts +0 -10
  391. package/dist/src/web/hooks/use-files.js +0 -7
  392. package/dist/src/web/hooks/use-files.js.map +0 -1
  393. package/dist/src/web/hooks/use-files.test.js +0 -29
  394. package/dist/src/web/hooks/use-files.test.js.map +0 -1
  395. package/dist/src/web/hooks/use-locale.d.ts +0 -1
  396. package/dist/src/web/hooks/use-locale.js +0 -5
  397. package/dist/src/web/hooks/use-locale.js.map +0 -1
  398. package/dist/src/web/hooks/use-locale.test.js +0 -21
  399. package/dist/src/web/hooks/use-locale.test.js.map +0 -1
  400. package/dist/src/web/hooks/use-open-external.d.ts +0 -1
  401. package/dist/src/web/hooks/use-open-external.js +0 -6
  402. package/dist/src/web/hooks/use-open-external.js.map +0 -1
  403. package/dist/src/web/hooks/use-open-external.test.js +0 -24
  404. package/dist/src/web/hooks/use-open-external.test.js.map +0 -1
  405. package/dist/src/web/hooks/use-openai-global.d.ts +0 -2
  406. package/dist/src/web/hooks/use-openai-global.js +0 -23
  407. package/dist/src/web/hooks/use-openai-global.js.map +0 -1
  408. package/dist/src/web/hooks/use-request-modal.d.ts +0 -6
  409. package/dist/src/web/hooks/use-request-modal.js +0 -9
  410. package/dist/src/web/hooks/use-request-modal.js.map +0 -1
  411. package/dist/src/web/hooks/use-request-modal.test.js +0 -24
  412. package/dist/src/web/hooks/use-request-modal.test.js.map +0 -1
  413. package/dist/src/web/hooks/use-send-follow-up-message.d.ts +0 -1
  414. package/dist/src/web/hooks/use-send-follow-up-message.js +0 -11
  415. package/dist/src/web/hooks/use-send-follow-up-message.js.map +0 -1
  416. package/dist/src/web/hooks/use-theme.d.ts +0 -1
  417. package/dist/src/web/hooks/use-theme.js +0 -5
  418. package/dist/src/web/hooks/use-theme.js.map +0 -1
  419. package/dist/src/web/hooks/use-theme.test.js +0 -26
  420. package/dist/src/web/hooks/use-theme.test.js.map +0 -1
  421. package/dist/src/web/hooks/use-tool-info.d.ts +0 -25
  422. package/dist/src/web/hooks/use-tool-info.js +0 -22
  423. package/dist/src/web/hooks/use-tool-info.js.map +0 -1
  424. package/dist/src/web/hooks/use-tool-info.test-d.js.map +0 -1
  425. package/dist/src/web/hooks/use-tool-info.test.js +0 -59
  426. package/dist/src/web/hooks/use-tool-info.test.js.map +0 -1
  427. package/dist/src/web/hooks/use-user-agent.d.ts +0 -1
  428. package/dist/src/web/hooks/use-user-agent.js +0 -5
  429. package/dist/src/web/hooks/use-user-agent.js.map +0 -1
  430. package/dist/src/web/hooks/use-user-agent.test.js +0 -31
  431. package/dist/src/web/hooks/use-user-agent.test.js.map +0 -1
  432. package/dist/src/web/hooks/use-widget-state.d.ts +0 -4
  433. package/dist/src/web/hooks/use-widget-state.js +0 -32
  434. package/dist/src/web/hooks/use-widget-state.js.map +0 -1
  435. package/dist/src/web/hooks/use-widget-state.test.js +0 -60
  436. package/dist/src/web/hooks/use-widget-state.test.js.map +0 -1
  437. package/dist/src/web/index.js.map +0 -1
  438. package/dist/src/web/mount-widget.d.ts +0 -1
  439. package/dist/src/web/mount-widget.js +0 -19
  440. package/dist/src/web/mount-widget.js.map +0 -1
  441. package/dist/src/web/plugin/data-llm.test.js.map +0 -1
  442. package/dist/src/web/plugin/plugin.d.ts +0 -2
  443. package/dist/src/web/plugin/plugin.js +0 -33
  444. package/dist/src/web/plugin/plugin.js.map +0 -1
  445. package/dist/src/web/plugin/transform-data-llm.js.map +0 -1
  446. package/dist/src/web/plugin/transform-data-llm.test.js.map +0 -1
  447. package/dist/src/web/proxy.js.map +0 -1
  448. package/dist/src/web/types.d.ts +0 -133
  449. package/dist/src/web/types.js.map +0 -1
  450. package/dist/vitest.config.d.ts +0 -2
  451. package/dist/vitest.config.js +0 -8
  452. package/dist/vitest.config.js.map +0 -1
  453. /package/dist/{src/test/widget.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
  454. /package/dist/{src/web/data-llm.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
  455. /package/dist/{src/web/generate-helpers.test-d.d.ts → cli/tunnel.test.d.ts} +0 -0
  456. /package/dist/{src/web/generate-helpers.test.d.ts → server/asset-base-url-transform-plugin.test.d.ts} +0 -0
  457. /package/dist/{src/web/helpers/state.test.d.ts → server/content-helpers.test.d.ts} +0 -0
  458. /package/dist/{src/web/hooks/use-call-tool.test-d.d.ts → server/express.test.d.ts} +0 -0
  459. /package/dist/{src/server → server}/inferUtilityTypes.js +0 -0
  460. /package/dist/{src/web/hooks/use-call-tool.test.d.ts → server/middleware.test-d.d.ts} +0 -0
  461. /package/dist/{src/web/hooks/use-display-mode.test.d.ts → server/middleware.test.d.ts} +0 -0
  462. /package/dist/{src/web/hooks/use-files.test.d.ts → server/tunnel-proxy-router.test.d.ts} +0 -0
  463. /package/dist/{src/web/hooks/use-locale.test.d.ts → test/view.test.d.ts} +0 -0
  464. /package/dist/{src/web/hooks/use-open-external.test.d.ts → web/bridges/adaptor.test.d.ts} +0 -0
  465. /package/dist/{src/web/hooks/use-request-modal.test.d.ts → web/bridges/get-adaptor.test.d.ts} +0 -0
  466. /package/dist/{src/web/hooks/use-theme.test.d.ts → web/bridges/mcp-app/bridge.test.d.ts} +0 -0
  467. /package/dist/{src/web/hooks/use-tool-info.test-d.d.ts → web/bridges/mcp-app/use-mcp-app-context.test.d.ts} +0 -0
  468. /package/dist/{src/web/hooks/use-tool-info.test.d.ts → web/bridges/types.test.d.ts} +0 -0
  469. /package/dist/{src/web/hooks/use-user-agent.test.d.ts → web/create-store.test.d.ts} +0 -0
  470. /package/dist/{src/web/plugin → web}/data-llm.test.d.ts +0 -0
  471. /package/dist/{src/web/hooks/use-widget-state.test.d.ts → web/generate-helpers.test-d.d.ts} +0 -0
  472. /package/dist/{src/web/plugin/transform-data-llm.test.d.ts → web/generate-helpers.test.d.ts} +0 -0
  473. /package/dist/{src/web → web}/plugin/data-llm.test.js +0 -0
  474. /package/dist/{src/web → web}/plugin/transform-data-llm.d.ts +0 -0
  475. /package/dist/{src/web → web}/plugin/transform-data-llm.test.js +0 -0
  476. /package/dist/{src/web → web}/proxy.d.ts +0 -0
@@ -0,0 +1,96 @@
1
+ import { useRef, useState } from "react";
2
+ import { getAdaptor, } from "../bridges/index.js";
3
+ /**
4
+ * Call a server tool from a view and track its execution state.
5
+ *
6
+ * Returns the current {@link CallToolState} plus two callers: `callTool`
7
+ * (fire-and-forget, with optional {@link SideEffects}) and `callToolAsync`
8
+ * (promise-returning). If the same instance is invoked again while a call is
9
+ * in flight, the older response is dropped from the rendered state (but any
10
+ * `onSuccess` / `onError` / `onSettled` callbacks attached to it still fire).
11
+ *
12
+ * Pair with {@link useToolInfo} to read the result of the tool invocation
13
+ * that produced the current view. For end-to-end type safety across tool
14
+ * inputs and outputs, prefer the typed helpers produced by {@link generateHelpers}
15
+ * over calling this hook directly.
16
+ *
17
+ * @typeParam ToolArgs - Shape of the tool's input args (`null` for no-arg tools).
18
+ * @typeParam ToolResponse - Shape of the tool's `structuredContent` / `meta`.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * const { callTool, isPending, data } = useCallTool<{ query: string }>("search");
23
+ *
24
+ * <button onClick={() => callTool({ query: "skybridge" }, {
25
+ * onSuccess: (res) => console.log(res.structuredContent),
26
+ * })} />
27
+ * ```
28
+ *
29
+ * @see https://docs.skybridge.tech/api-reference/use-call-tool
30
+ */
31
+ export const useCallTool = (name) => {
32
+ const [{ status, data, error }, setCallToolState] = useState({ status: "idle", data: undefined, error: undefined });
33
+ const callIdRef = useRef(0);
34
+ const adaptor = getAdaptor();
35
+ const execute = async (toolArgs) => {
36
+ const callId = ++callIdRef.current;
37
+ setCallToolState({ status: "pending", data: undefined, error: undefined });
38
+ try {
39
+ const data = await adaptor.callTool(name, toolArgs);
40
+ if (callId === callIdRef.current) {
41
+ setCallToolState({ status: "success", data, error: undefined });
42
+ }
43
+ return data;
44
+ }
45
+ catch (error) {
46
+ if (callId === callIdRef.current) {
47
+ setCallToolState({ status: "error", data: undefined, error });
48
+ }
49
+ throw error;
50
+ }
51
+ };
52
+ const callToolAsync = ((toolArgs) => {
53
+ if (toolArgs === undefined) {
54
+ return execute(null);
55
+ }
56
+ return execute(toolArgs);
57
+ });
58
+ const callTool = ((firstArg, sideEffects) => {
59
+ let toolArgs;
60
+ if (firstArg &&
61
+ typeof firstArg === "object" &&
62
+ ("onSuccess" in firstArg ||
63
+ "onError" in firstArg ||
64
+ "onSettled" in firstArg)) {
65
+ toolArgs = null; // no toolArgs provided
66
+ sideEffects = firstArg;
67
+ }
68
+ else {
69
+ toolArgs = (firstArg === undefined ? null : firstArg);
70
+ }
71
+ execute(toolArgs)
72
+ .then((data) => {
73
+ sideEffects?.onSuccess?.(data, toolArgs);
74
+ sideEffects?.onSettled?.(data, undefined, toolArgs);
75
+ })
76
+ .catch((error) => {
77
+ sideEffects?.onError?.(error, toolArgs);
78
+ sideEffects?.onSettled?.(undefined, error, toolArgs);
79
+ });
80
+ });
81
+ const callToolState = {
82
+ status,
83
+ data,
84
+ error,
85
+ isIdle: status === "idle",
86
+ isPending: status === "pending",
87
+ isSuccess: status === "success",
88
+ isError: status === "error",
89
+ };
90
+ return {
91
+ ...callToolState,
92
+ callTool,
93
+ callToolAsync,
94
+ };
95
+ };
96
+ //# sourceMappingURL=use-call-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-call-tool.js","sourceRoot":"","sources":["../../../src/web/hooks/use-call-tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { useRef, useState } from \"react\";\n\nimport {\n type CallToolArgs,\n type CallToolResponse,\n getAdaptor,\n} from \"../bridges/index.js\";\nimport type { HasRequiredKeys } from \"../types.js\";\n\ntype CallToolIdleState = {\n status: \"idle\";\n isIdle: true;\n isPending: false;\n isSuccess: false;\n isError: false;\n data: undefined;\n error: undefined;\n};\n\ntype CallToolPendingState = {\n status: \"pending\";\n isIdle: false;\n isPending: true;\n isSuccess: false;\n isError: false;\n data: undefined;\n error: undefined;\n};\n\ntype CallToolSuccessState<TData extends CallToolResponse = CallToolResponse> = {\n status: \"success\";\n isIdle: false;\n isPending: false;\n isSuccess: true;\n isError: false;\n data: TData;\n error: undefined;\n};\n\ntype CallToolErrorState = {\n status: \"error\";\n isIdle: false;\n isPending: false;\n isSuccess: false;\n isError: true;\n data: undefined;\n error: unknown;\n};\n\n/**\n * State of a {@link useCallTool} invocation, discriminated by `status`.\n * Use `isIdle` / `isPending` / `isSuccess` / `isError` for ergonomic conditional rendering.\n */\nexport type CallToolState<TData extends CallToolResponse = CallToolResponse> =\n | CallToolIdleState\n | CallToolPendingState\n | CallToolSuccessState<TData>\n | CallToolErrorState;\n\n/**\n * Optional callbacks fired around a {@link useCallTool} call.\n * `onSettled` runs after success or error.\n */\nexport type SideEffects<ToolArgs, ToolResponse> = {\n onSuccess?: (data: ToolResponse, toolArgs: ToolArgs) => void;\n onError?: (error: unknown, toolArgs: ToolArgs) => void;\n onSettled?: (\n data: ToolResponse | undefined,\n error: unknown | undefined,\n toolArgs: ToolArgs,\n ) => void;\n};\n\ntype IsArgsOptional<T> = [T] extends [null]\n ? true\n : HasRequiredKeys<T> extends false\n ? true\n : false;\n\n/**\n * Fire-and-forget call function returned by {@link useCallTool}. Tracks state\n * on the hook and supports optional {@link SideEffects} callbacks. Args are\n * optional when the tool accepts none.\n */\nexport type CallToolFn<TArgs, TResponse> =\n IsArgsOptional<TArgs> extends true\n ? {\n (): void;\n (sideEffects: SideEffects<TArgs, TResponse>): void;\n (args: TArgs): void;\n (args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;\n }\n : {\n (args: TArgs): void;\n (args: TArgs, sideEffects: SideEffects<TArgs, TResponse>): void;\n };\n\n/**\n * Promise-returning call function returned by {@link useCallTool}. Rejects\n * if the tool errors; use `try/catch` for error handling.\n */\nexport type CallToolAsyncFn<TArgs, TResponse> =\n IsArgsOptional<TArgs> extends true\n ? {\n (): Promise<TResponse>;\n (args: TArgs): Promise<TResponse>;\n }\n : (args: TArgs) => Promise<TResponse>;\n\ntype ToolResponseSignature = Pick<\n CallToolResponse,\n \"structuredContent\" | \"meta\"\n>;\n\n/**\n * Call a server tool from a view and track its execution state.\n *\n * Returns the current {@link CallToolState} plus two callers: `callTool`\n * (fire-and-forget, with optional {@link SideEffects}) and `callToolAsync`\n * (promise-returning). If the same instance is invoked again while a call is\n * in flight, the older response is dropped from the rendered state (but any\n * `onSuccess` / `onError` / `onSettled` callbacks attached to it still fire).\n *\n * Pair with {@link useToolInfo} to read the result of the tool invocation\n * that produced the current view. For end-to-end type safety across tool\n * inputs and outputs, prefer the typed helpers produced by {@link generateHelpers}\n * over calling this hook directly.\n *\n * @typeParam ToolArgs - Shape of the tool's input args (`null` for no-arg tools).\n * @typeParam ToolResponse - Shape of the tool's `structuredContent` / `meta`.\n *\n * @example\n * ```tsx\n * const { callTool, isPending, data } = useCallTool<{ query: string }>(\"search\");\n *\n * <button onClick={() => callTool({ query: \"skybridge\" }, {\n * onSuccess: (res) => console.log(res.structuredContent),\n * })} />\n * ```\n *\n * @see https://docs.skybridge.tech/api-reference/use-call-tool\n */\nexport const useCallTool = <\n ToolArgs extends CallToolArgs = null,\n ToolResponse extends Partial<ToolResponseSignature> = Record<string, never>,\n>(\n name: string,\n) => {\n type CombinedCallToolResponse = CallToolResponse & ToolResponse;\n\n const [{ status, data, error }, setCallToolState] = useState<\n Omit<\n CallToolState<CombinedCallToolResponse>,\n \"isIdle\" | \"isPending\" | \"isSuccess\" | \"isError\"\n >\n >({ status: \"idle\", data: undefined, error: undefined });\n\n const callIdRef = useRef(0);\n const adaptor = getAdaptor();\n\n const execute = async (\n toolArgs: ToolArgs,\n ): Promise<CombinedCallToolResponse> => {\n const callId = ++callIdRef.current;\n setCallToolState({ status: \"pending\", data: undefined, error: undefined });\n\n try {\n const data = await adaptor.callTool<ToolArgs, CombinedCallToolResponse>(\n name,\n toolArgs,\n );\n if (callId === callIdRef.current) {\n setCallToolState({ status: \"success\", data, error: undefined });\n }\n\n return data;\n } catch (error) {\n if (callId === callIdRef.current) {\n setCallToolState({ status: \"error\", data: undefined, error });\n }\n throw error;\n }\n };\n\n const callToolAsync = ((toolArgs?: ToolArgs) => {\n if (toolArgs === undefined) {\n return execute(null as ToolArgs);\n }\n return execute(toolArgs);\n }) as CallToolAsyncFn<ToolArgs, CombinedCallToolResponse>;\n\n const callTool = ((\n firstArg?: ToolArgs | SideEffects<ToolArgs, CombinedCallToolResponse>,\n sideEffects?: SideEffects<ToolArgs, CombinedCallToolResponse>,\n ) => {\n let toolArgs: ToolArgs;\n if (\n firstArg &&\n typeof firstArg === \"object\" &&\n (\"onSuccess\" in firstArg ||\n \"onError\" in firstArg ||\n \"onSettled\" in firstArg)\n ) {\n toolArgs = null as ToolArgs; // no toolArgs provided\n sideEffects = firstArg;\n } else {\n toolArgs = (firstArg === undefined ? null : firstArg) as ToolArgs;\n }\n\n execute(toolArgs)\n .then((data) => {\n sideEffects?.onSuccess?.(data, toolArgs);\n sideEffects?.onSettled?.(data, undefined, toolArgs);\n })\n .catch((error) => {\n sideEffects?.onError?.(error, toolArgs);\n sideEffects?.onSettled?.(undefined, error, toolArgs);\n });\n }) as CallToolFn<ToolArgs, CombinedCallToolResponse>;\n\n const callToolState = {\n status,\n data,\n error,\n isIdle: status === \"idle\",\n isPending: status === \"pending\",\n isSuccess: status === \"success\",\n isError: status === \"error\",\n } as CallToolState<CombinedCallToolResponse>;\n\n return {\n ...callToolState,\n callTool,\n callToolAsync,\n };\n};\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { expectTypeOf, test } from "vitest";
2
- import { useCallTool } from "./use-call-tool.js";
2
+ import { useCallTool, } from "./use-call-tool.js";
3
3
  test("callTool can be called without args when ToolArgs is null", () => {
4
4
  const { callTool, callToolAsync } = useCallTool("test-tool");
5
5
  callTool();
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-call-tool.test-d.js","sourceRoot":"","sources":["../../../src/web/hooks/use-call-tool.test-d.ts"],"names":[],"mappings":"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","sourcesContent":["import { expectTypeOf, test } from \"vitest\";\nimport type { CallToolResponse } from \"../bridges/types.js\";\nimport {\n type CallToolState,\n type SideEffects,\n useCallTool,\n} from \"./use-call-tool.js\";\n\ntest(\"callTool can be called without args when ToolArgs is null\", () => {\n const { callTool, callToolAsync } = useCallTool<null>(\"test-tool\");\n callTool();\n callTool({ onSuccess: () => {} });\n callToolAsync();\n});\n\ntest(\"callTool requires args when ToolArgs has required properties\", () => {\n type Args = { query: string };\n const { callTool, callToolAsync } = useCallTool<Args>(\"test-tool\");\n\n // @ts-expect-error - query is required\n callTool();\n\n callTool({ query: \"test\" });\n callTool({ query: \"test\" }, { onSuccess: () => {} });\n\n // @ts-expect-error - query is required\n callToolAsync();\n callToolAsync({ query: \"test\" });\n});\n\ntest(\"callTool supports sideEffects with correct types\", () => {\n type Args = { id: number };\n type Response = { structuredContent: { result: string } };\n\n const { callTool } = useCallTool<Args, Response>(\"test-tool\");\n\n callTool(\n { id: 1 },\n {\n onSuccess: (data, args) => {\n expectTypeOf(data.structuredContent.result).toBeString();\n expectTypeOf(args.id).toBeNumber();\n },\n onError: (error, args) => {\n expectTypeOf(error).toBeUnknown();\n expectTypeOf(args.id).toBeNumber();\n },\n onSettled: (data, error, args) => {\n if (data) {\n expectTypeOf(data.structuredContent.result).toBeString();\n }\n expectTypeOf(error).toEqualTypeOf<unknown | undefined>();\n expectTypeOf(args.id).toBeNumber();\n },\n },\n );\n});\n\ntest(\"callTool allows sideEffects as first arg when ToolArgs is null\", () => {\n type Response = { structuredContent: { value: number } };\n const { callTool } = useCallTool<null, Response>(\"test-tool\");\n\n callTool({\n onSuccess: (data) => {\n expectTypeOf(data.structuredContent.value).toBeNumber();\n },\n });\n});\n\ntest(\"callToolAsync returns correctly typed promise\", () => {\n type Args = { name: string };\n type Response = {\n structuredContent: { greeting: string };\n meta: { id: number };\n };\n\n const { callToolAsync } = useCallTool<Args, Response>(\"test-tool\");\n\n const promise = callToolAsync({ name: \"test\" });\n\n expectTypeOf(promise).resolves.toHaveProperty(\"structuredContent\");\n expectTypeOf(promise).resolves.toHaveProperty(\"meta\");\n});\n\ntest(\"state narrowing works correctly with status\", () => {\n type Response = { structuredContent: { data: string } };\n const result = useCallTool<null, Response>(\"test-tool\");\n\n if (result.status === \"idle\") {\n expectTypeOf(result.isIdle).toEqualTypeOf<true>();\n expectTypeOf(result.data).toEqualTypeOf<undefined>();\n }\n\n if (result.status === \"pending\") {\n expectTypeOf(result.isPending).toEqualTypeOf<true>();\n expectTypeOf(result.data).toEqualTypeOf<undefined>();\n }\n\n if (result.status === \"success\") {\n expectTypeOf(result.isSuccess).toEqualTypeOf<true>();\n expectTypeOf(result.data).not.toEqualTypeOf<undefined>();\n expectTypeOf(result.data.structuredContent.data).toBeString();\n }\n\n if (result.status === \"error\") {\n expectTypeOf(result.isError).toEqualTypeOf<true>();\n expectTypeOf(result.error).toBeUnknown();\n }\n});\n\ntest(\"state narrowing works correctly with boolean flags\", () => {\n type Response = { structuredContent: { items: string[] } };\n const result = useCallTool<null, Response>(\"test-tool\");\n\n if (result.isIdle) {\n expectTypeOf(result.status).toEqualTypeOf<\"idle\">();\n }\n\n if (result.isPending) {\n expectTypeOf(result.status).toEqualTypeOf<\"pending\">();\n }\n\n if (result.isSuccess) {\n expectTypeOf(result.status).toEqualTypeOf<\"success\">();\n expectTypeOf(result.data.structuredContent.items).toBeArray();\n }\n\n if (result.isError) {\n expectTypeOf(result.status).toEqualTypeOf<\"error\">();\n }\n});\n\ntest(\"CallToolState type is correctly exported and usable\", () => {\n type Response = { structuredContent: { foo: string } };\n type MyState = CallToolState<CallToolResponse & Response>;\n\n const state: MyState = {} as MyState;\n\n if (state.status === \"success\") {\n expectTypeOf(state.data.structuredContent.foo).toBeString();\n }\n});\n\ntest(\"SideEffects type is correctly exported and usable\", () => {\n type Args = { x: number };\n type Response = CallToolResponse & { structuredContent: { y: string } };\n\n const sideEffects: SideEffects<Args, Response> = {\n onSuccess: (data, args) => {\n expectTypeOf(data.structuredContent.y).toBeString();\n expectTypeOf(args.x).toBeNumber();\n },\n };\n\n expectTypeOf(sideEffects).toHaveProperty(\"onSuccess\");\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,17 +1,26 @@
1
1
  import { act, renderHook, waitFor } from "@testing-library/react";
2
- import { afterEach, beforeEach, describe, expect, it, vi, expectTypeOf, } from "vitest";
2
+ import { afterEach, beforeEach, describe, expect, expectTypeOf, it, vi, } from "vitest";
3
+ import { AppsSdkBridge } from "../bridges/apps-sdk/bridge.js";
4
+ import { _resetAdaptor, getAdaptor } from "../bridges/get-adaptor.js";
5
+ import { McpAppBridge } from "../bridges/mcp-app/bridge.js";
3
6
  import { useCallTool } from "./use-call-tool.js";
4
7
  describe("useCallTool - onSuccess callback", () => {
5
- let OpenaiMock;
8
+ let callToolMock;
6
9
  beforeEach(() => {
7
- OpenaiMock = {
8
- callTool: vi.fn(),
9
- };
10
- vi.stubGlobal("openai", OpenaiMock);
10
+ _resetAdaptor();
11
+ McpAppBridge.resetInstance();
12
+ AppsSdkBridge.resetInstance();
13
+ vi.stubGlobal("parent", { postMessage: vi.fn() });
14
+ vi.stubGlobal("skybridge", { hostType: "apps-sdk" });
15
+ vi.stubGlobal("openai", { callTool: vi.fn() });
16
+ callToolMock = vi.spyOn(getAdaptor(), "callTool");
11
17
  });
12
18
  afterEach(() => {
13
19
  vi.unstubAllGlobals();
14
20
  vi.resetAllMocks();
21
+ _resetAdaptor();
22
+ McpAppBridge.resetInstance();
23
+ AppsSdkBridge.resetInstance();
15
24
  });
16
25
  const toolName = "test-tool";
17
26
  const args = { input: "test input" };
@@ -19,21 +28,38 @@ describe("useCallTool - onSuccess callback", () => {
19
28
  content: [{ type: "text", text: "test result" }],
20
29
  structuredContent: { result: "test" },
21
30
  isError: false,
22
- result: "test result",
23
31
  meta: {},
24
32
  };
25
33
  const error = new Error("test error");
26
- it("should call window.openai.callTool with correct arguments", async () => {
34
+ it("should normalize _meta to meta when SDK returns _meta instead of meta", async () => {
35
+ const rawSdkResponse = {
36
+ content: [{ type: "text", text: "result" }],
37
+ structuredContent: { value: 1 },
38
+ isError: false,
39
+ meta: { secret: "only visible to widget" },
40
+ };
41
+ callToolMock.mockResolvedValueOnce(rawSdkResponse);
42
+ const { result } = renderHook(() => useCallTool(toolName));
43
+ await act(async () => {
44
+ result.current.callTool(args);
45
+ });
46
+ await waitFor(() => {
47
+ expect(result.current.data).toMatchObject({
48
+ meta: { secret: "only visible to widget" },
49
+ });
50
+ });
51
+ });
52
+ it("should call adaptor.callTool with correct arguments", async () => {
27
53
  const { result } = renderHook(() => useCallTool(toolName));
28
54
  await act(async () => {
29
55
  result.current.callTool(args);
30
56
  });
31
- expect(OpenaiMock.callTool).toHaveBeenCalledWith(toolName, args);
57
+ expect(callToolMock).toHaveBeenCalledWith(toolName, args);
32
58
  });
33
59
  it("should call onSuccess callback with correct data and toolArgs on successful execution", async () => {
34
60
  const onSuccess = vi.fn();
35
61
  const onError = vi.fn();
36
- OpenaiMock.callTool.mockResolvedValueOnce(data);
62
+ callToolMock.mockResolvedValueOnce(data);
37
63
  const { result } = renderHook(() => useCallTool(toolName));
38
64
  act(() => {
39
65
  result.current.callTool(args, {
@@ -49,7 +75,7 @@ describe("useCallTool - onSuccess callback", () => {
49
75
  it("should call onError callback with error and toolArgs on failed execution", async () => {
50
76
  const onSuccess = vi.fn();
51
77
  const onError = vi.fn();
52
- OpenaiMock.callTool.mockRejectedValueOnce(error);
78
+ callToolMock.mockRejectedValueOnce(error);
53
79
  const { result } = renderHook(() => useCallTool(toolName));
54
80
  act(() => {
55
81
  result.current.callTool(args, {
@@ -66,7 +92,7 @@ describe("useCallTool - onSuccess callback", () => {
66
92
  const onSuccess = vi.fn();
67
93
  const onError = vi.fn();
68
94
  const onSettled = vi.fn();
69
- OpenaiMock.callTool.mockResolvedValueOnce(data);
95
+ callToolMock.mockResolvedValueOnce(data);
70
96
  const { result } = renderHook(() => useCallTool(toolName));
71
97
  act(() => {
72
98
  result.current.callTool(args, {
@@ -85,7 +111,7 @@ describe("useCallTool - onSuccess callback", () => {
85
111
  const onSuccess = vi.fn();
86
112
  const onError = vi.fn();
87
113
  const onSettled = vi.fn();
88
- OpenaiMock.callTool.mockRejectedValueOnce(error);
114
+ callToolMock.mockRejectedValueOnce(error);
89
115
  const { result } = renderHook(() => useCallTool(toolName));
90
116
  act(() => {
91
117
  result.current.callTool(args, {
@@ -100,18 +126,53 @@ describe("useCallTool - onSuccess callback", () => {
100
126
  expect(onSuccess).not.toHaveBeenCalled();
101
127
  });
102
128
  });
129
+ it("should always return last call started state", async () => {
130
+ const { result } = renderHook(() => useCallTool(toolName));
131
+ const firstCallData = {
132
+ ...data,
133
+ structuredContent: { result: "first call result" },
134
+ };
135
+ const secondCallData = {
136
+ ...data,
137
+ structuredContent: { result: "second call result" },
138
+ };
139
+ const { promise: firstCallToolPromise, resolve: resolveFirstCallTool } = Promise.withResolvers();
140
+ const { promise: secondCallToolPromise, resolve: resolveSecondCallTool } = Promise.withResolvers();
141
+ callToolMock
142
+ .mockImplementationOnce(() => firstCallToolPromise)
143
+ .mockImplementationOnce(() => secondCallToolPromise);
144
+ await act(() => {
145
+ result.current.callTool(args);
146
+ result.current.callTool(args);
147
+ resolveFirstCallTool(firstCallData);
148
+ return firstCallToolPromise;
149
+ });
150
+ expect(result.current.status).toEqual("pending");
151
+ expect(result.current.data).toEqual(undefined);
152
+ resolveSecondCallTool(secondCallData);
153
+ await waitFor(() => {
154
+ expect(result.current.status).toEqual("success");
155
+ expect(result.current.data).toEqual(secondCallData);
156
+ });
157
+ });
103
158
  });
104
159
  describe("useCallTool - TypeScript typing", () => {
105
- let OpenaiMock;
160
+ let callToolMock;
106
161
  beforeEach(() => {
107
- OpenaiMock = {
108
- callTool: vi.fn(),
109
- };
110
- vi.stubGlobal("openai", OpenaiMock);
162
+ _resetAdaptor();
163
+ McpAppBridge.resetInstance();
164
+ AppsSdkBridge.resetInstance();
165
+ vi.stubGlobal("parent", { postMessage: vi.fn() });
166
+ vi.stubGlobal("skybridge", { hostType: "apps-sdk" });
167
+ vi.stubGlobal("openai", { callTool: vi.fn() });
168
+ callToolMock = vi.spyOn(getAdaptor(), "callTool");
111
169
  });
112
170
  afterEach(() => {
113
171
  vi.unstubAllGlobals();
114
172
  vi.resetAllMocks();
173
+ _resetAdaptor();
174
+ McpAppBridge.resetInstance();
175
+ AppsSdkBridge.resetInstance();
115
176
  });
116
177
  it("should have correct return types when ToolArgs is null and ToolResponse is specified", async () => {
117
178
  const { result } = renderHook(() => useCallTool("test-tool"));
@@ -119,14 +180,13 @@ describe("useCallTool - TypeScript typing", () => {
119
180
  content: [{ type: "text", text: "test" }],
120
181
  structuredContent: { result: "test" },
121
182
  isError: false,
122
- result: "test",
123
183
  meta: { id: 123 },
124
184
  };
125
- OpenaiMock.callTool.mockResolvedValueOnce(data);
185
+ callToolMock.mockResolvedValueOnce(data);
126
186
  await act(async () => {
127
187
  result.current.callTool();
128
188
  });
129
- expect(OpenaiMock.callTool).toHaveBeenCalledWith("test-tool", null);
189
+ expect(callToolMock).toHaveBeenCalledWith("test-tool", null);
130
190
  expectTypeOf(result.current.data);
131
191
  });
132
192
  it("should correctly type callToolAsync return value", async () => {
@@ -136,18 +196,14 @@ describe("useCallTool - TypeScript typing", () => {
136
196
  content: [{ type: "text", text: "answer" }],
137
197
  structuredContent: { answer: "test answer" },
138
198
  isError: false,
139
- result: "answer",
140
199
  meta: {},
141
200
  };
142
- OpenaiMock.callTool.mockResolvedValueOnce(mockResponse);
143
- let promise;
144
- let resolvedValue;
145
- await act(async () => {
146
- promise = result.current.callToolAsync(testArgs);
147
- expectTypeOf(promise);
148
- resolvedValue = await promise;
201
+ callToolMock.mockResolvedValueOnce(mockResponse);
202
+ const returnedValue = await act(async () => {
203
+ return result.current.callToolAsync(testArgs);
149
204
  });
150
- expect(resolvedValue).toEqual(mockResponse);
205
+ expectTypeOf(returnedValue);
206
+ expect(returnedValue).toEqual(mockResponse);
151
207
  });
152
208
  it("should correctly type callToolAsync when ToolArgs is null", async () => {
153
209
  const { result } = renderHook(() => useCallTool("test-tool"));
@@ -155,17 +211,14 @@ describe("useCallTool - TypeScript typing", () => {
155
211
  content: [{ type: "text", text: "data" }],
156
212
  structuredContent: { data: "test data" },
157
213
  isError: false,
158
- result: "data",
214
+ meta: {},
159
215
  };
160
- OpenaiMock.callTool.mockResolvedValueOnce(mockResponse);
161
- let promise;
162
- let resolvedValue;
163
- await act(async () => {
164
- promise = result.current.callToolAsync();
165
- expectTypeOf(promise);
166
- resolvedValue = await promise;
216
+ callToolMock.mockResolvedValueOnce(mockResponse);
217
+ const returnedValue = await act(async () => {
218
+ return result.current.callToolAsync();
167
219
  });
168
- expect(resolvedValue).toEqual(mockResponse);
220
+ expectTypeOf(returnedValue);
221
+ expect(returnedValue).toEqual(mockResponse);
169
222
  });
170
223
  });
171
224
  //# sourceMappingURL=use-call-tool.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-call-tool.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-call-tool.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { act, renderHook, waitFor } from \"@testing-library/react\";\nimport {\n afterEach,\n beforeEach,\n describe,\n expect,\n expectTypeOf,\n it,\n type Mock,\n vi,\n} from \"vitest\";\n\nimport { AppsSdkBridge } from \"../bridges/apps-sdk/bridge.js\";\nimport { _resetAdaptor, getAdaptor } from \"../bridges/get-adaptor.js\";\nimport { McpAppBridge } from \"../bridges/mcp-app/bridge.js\";\nimport type { CallToolResponse } from \"../bridges/types.js\";\nimport { useCallTool } from \"./use-call-tool.js\";\n\ndescribe(\"useCallTool - onSuccess callback\", () => {\n let callToolMock: Mock;\n\n beforeEach(() => {\n _resetAdaptor();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"parent\", { postMessage: vi.fn() });\n vi.stubGlobal(\"skybridge\", { hostType: \"apps-sdk\" });\n vi.stubGlobal(\"openai\", { callTool: vi.fn() });\n callToolMock = vi.spyOn(getAdaptor(), \"callTool\") as unknown as Mock;\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n _resetAdaptor();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n });\n\n const toolName = \"test-tool\";\n const args = { input: \"test input\" };\n const data: CallToolResponse = {\n content: [{ type: \"text\" as const, text: \"test result\" }],\n structuredContent: { result: \"test\" },\n isError: false,\n meta: {},\n };\n const error = new Error(\"test error\");\n\n it(\"should normalize _meta to meta when SDK returns _meta instead of meta\", async () => {\n const rawSdkResponse = {\n content: [{ type: \"text\" as const, text: \"result\" }],\n structuredContent: { value: 1 },\n isError: false,\n meta: { secret: \"only visible to widget\" },\n };\n callToolMock.mockResolvedValueOnce(rawSdkResponse);\n const { result } = renderHook(() =>\n useCallTool<typeof args, typeof data>(toolName),\n );\n\n await act(async () => {\n result.current.callTool(args);\n });\n\n await waitFor(() => {\n expect(result.current.data).toMatchObject({\n meta: { secret: \"only visible to widget\" },\n });\n });\n });\n\n it(\"should call adaptor.callTool with correct arguments\", async () => {\n const { result } = renderHook(() =>\n useCallTool<typeof args, typeof data>(toolName),\n );\n await act(async () => {\n result.current.callTool(args);\n });\n expect(callToolMock).toHaveBeenCalledWith(toolName, args);\n });\n\n it(\"should call onSuccess callback with correct data and toolArgs on successful execution\", async () => {\n const onSuccess = vi.fn();\n const onError = vi.fn();\n callToolMock.mockResolvedValueOnce(data);\n const { result } = renderHook(() =>\n useCallTool<typeof args, typeof data>(toolName),\n );\n\n act(() => {\n result.current.callTool(args, {\n onSuccess,\n onError,\n });\n });\n\n await waitFor(() => {\n expect(onSuccess).toHaveBeenCalledWith(data, args);\n expect(onError).not.toHaveBeenCalled();\n });\n });\n\n it(\"should call onError callback with error and toolArgs on failed execution\", async () => {\n const onSuccess = vi.fn();\n const onError = vi.fn();\n callToolMock.mockRejectedValueOnce(error);\n const { result } = renderHook(() =>\n useCallTool<typeof args, typeof data>(toolName),\n );\n\n act(() => {\n result.current.callTool(args, {\n onSuccess,\n onError,\n });\n });\n\n await waitFor(() => {\n expect(onSuccess).not.toHaveBeenCalled();\n expect(onError).toHaveBeenCalledWith(error, args);\n });\n });\n\n it(\"should call onSettled callback with data and undefined error on successful execution\", async () => {\n const onSuccess = vi.fn();\n const onError = vi.fn();\n const onSettled = vi.fn();\n callToolMock.mockResolvedValueOnce(data);\n const { result } = renderHook(() =>\n useCallTool<typeof args, typeof data>(toolName),\n );\n\n act(() => {\n result.current.callTool(args, {\n onSuccess,\n onError,\n onSettled,\n });\n });\n\n await waitFor(() => {\n expect(onSuccess).toHaveBeenCalledWith(data, args);\n expect(onSettled).toHaveBeenCalledWith(data, undefined, args);\n expect(onError).not.toHaveBeenCalled();\n });\n });\n\n it(\"should call onSettled callback with undefined data and error on failed execution\", async () => {\n const onSuccess = vi.fn();\n const onError = vi.fn();\n const onSettled = vi.fn();\n callToolMock.mockRejectedValueOnce(error);\n const { result } = renderHook(() =>\n useCallTool<typeof args, typeof data>(toolName),\n );\n\n act(() => {\n result.current.callTool(args, {\n onSuccess,\n onError,\n onSettled,\n });\n });\n\n await waitFor(() => {\n expect(onError).toHaveBeenCalledWith(error, args);\n expect(onSettled).toHaveBeenCalledWith(undefined, error, args);\n expect(onSuccess).not.toHaveBeenCalled();\n });\n });\n\n it(\"should always return last call started state\", async () => {\n const { result } = renderHook(() =>\n useCallTool<typeof args, typeof data>(toolName),\n );\n\n const firstCallData = {\n ...data,\n structuredContent: { result: \"first call result\" },\n };\n const secondCallData = {\n ...data,\n structuredContent: { result: \"second call result\" },\n };\n const { promise: firstCallToolPromise, resolve: resolveFirstCallTool } =\n Promise.withResolvers();\n const { promise: secondCallToolPromise, resolve: resolveSecondCallTool } =\n Promise.withResolvers();\n callToolMock\n .mockImplementationOnce(() => firstCallToolPromise)\n .mockImplementationOnce(() => secondCallToolPromise);\n\n await act(() => {\n result.current.callTool(args);\n result.current.callTool(args);\n resolveFirstCallTool(firstCallData);\n return firstCallToolPromise;\n });\n\n expect(result.current.status).toEqual(\"pending\");\n expect(result.current.data).toEqual(undefined);\n resolveSecondCallTool(secondCallData);\n\n await waitFor(() => {\n expect(result.current.status).toEqual(\"success\");\n expect(result.current.data).toEqual(secondCallData);\n });\n });\n});\n\ndescribe(\"useCallTool - TypeScript typing\", () => {\n let callToolMock: Mock;\n\n beforeEach(() => {\n _resetAdaptor();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"parent\", { postMessage: vi.fn() });\n vi.stubGlobal(\"skybridge\", { hostType: \"apps-sdk\" });\n vi.stubGlobal(\"openai\", { callTool: vi.fn() });\n callToolMock = vi.spyOn(getAdaptor(), \"callTool\") as unknown as Mock;\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n _resetAdaptor();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n });\n\n it(\"should have correct return types when ToolArgs is null and ToolResponse is specified\", async () => {\n type TestResponse = CallToolResponse & {\n structuredContent: { result: string };\n meta: { id: number };\n };\n\n const { result } = renderHook(() =>\n useCallTool<null, TestResponse>(\"test-tool\"),\n );\n const data: TestResponse = {\n content: [{ type: \"text\" as const, text: \"test\" }],\n structuredContent: { result: \"test\" },\n isError: false,\n meta: { id: 123 },\n };\n\n callToolMock.mockResolvedValueOnce(data);\n\n await act(async () => {\n result.current.callTool();\n });\n\n expect(callToolMock).toHaveBeenCalledWith(\"test-tool\", null);\n expectTypeOf<typeof data | undefined>(result.current.data);\n });\n\n it(\"should correctly type callToolAsync return value\", async () => {\n type TestArgs = { query: string };\n type TestResponse = CallToolResponse & {\n structuredContent: { answer: string };\n };\n\n const { result } = renderHook(() =>\n useCallTool<TestArgs, TestResponse>(\"test-tool\"),\n );\n\n const testArgs: TestArgs = { query: \"test\" };\n const mockResponse: TestResponse = {\n content: [{ type: \"text\" as const, text: \"answer\" }],\n structuredContent: { answer: \"test answer\" },\n isError: false,\n meta: {},\n };\n\n callToolMock.mockResolvedValueOnce(mockResponse);\n\n const returnedValue = await act(async () => {\n return result.current.callToolAsync(testArgs);\n });\n expectTypeOf<typeof mockResponse>(returnedValue);\n expect(returnedValue).toEqual(mockResponse);\n });\n\n it(\"should correctly type callToolAsync when ToolArgs is null\", async () => {\n type TestResponse = CallToolResponse & {\n structuredContent: { data: string };\n };\n\n const { result } = renderHook(() =>\n useCallTool<null, TestResponse>(\"test-tool\"),\n );\n\n const mockResponse: TestResponse = {\n content: [{ type: \"text\" as const, text: \"data\" }],\n structuredContent: { data: \"test data\" },\n isError: false,\n meta: {},\n };\n\n callToolMock.mockResolvedValueOnce(mockResponse);\n\n const returnedValue = await act(async () => {\n return result.current.callToolAsync();\n });\n expectTypeOf<typeof mockResponse>(returnedValue);\n expect(returnedValue).toEqual(mockResponse);\n });\n});\n"]}
@@ -0,0 +1,24 @@
1
+ import type { RequestDisplayMode } from "../bridges/types.js";
2
+ /**
3
+ * Read and change the view's display mode (`"inline"`, `"pip"`, `"fullscreen"`).
4
+ *
5
+ * Returns a tuple `[displayMode, setDisplayMode]`. `setDisplayMode` asks the
6
+ * host to switch modes — the host returns the mode it actually applied, which
7
+ * may differ from the request. The reported value also updates when the host
8
+ * changes the mode on its own (e.g. user expands the widget).
9
+ *
10
+ * `"modal"` is reachable via {@link useRequestModal}, not this hook. To react
11
+ * to layout changes that come with display-mode switches (e.g. `maxHeight`),
12
+ * pair with {@link useLayout}.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * const [mode, setMode] = useDisplayMode();
17
+ * <button onClick={() => setMode("fullscreen")}>Expand</button>
18
+ * ```
19
+ *
20
+ * @see https://docs.skybridge.tech/api-reference/use-display-mode
21
+ */
22
+ export declare function useDisplayMode(): readonly [import("../index.js").DisplayMode, (mode: RequestDisplayMode) => Promise<{
23
+ mode: RequestDisplayMode;
24
+ }>];
@@ -0,0 +1,29 @@
1
+ import { useCallback } from "react";
2
+ import { getAdaptor, useHostContext } from "../bridges/index.js";
3
+ /**
4
+ * Read and change the view's display mode (`"inline"`, `"pip"`, `"fullscreen"`).
5
+ *
6
+ * Returns a tuple `[displayMode, setDisplayMode]`. `setDisplayMode` asks the
7
+ * host to switch modes — the host returns the mode it actually applied, which
8
+ * may differ from the request. The reported value also updates when the host
9
+ * changes the mode on its own (e.g. user expands the widget).
10
+ *
11
+ * `"modal"` is reachable via {@link useRequestModal}, not this hook. To react
12
+ * to layout changes that come with display-mode switches (e.g. `maxHeight`),
13
+ * pair with {@link useLayout}.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * const [mode, setMode] = useDisplayMode();
18
+ * <button onClick={() => setMode("fullscreen")}>Expand</button>
19
+ * ```
20
+ *
21
+ * @see https://docs.skybridge.tech/api-reference/use-display-mode
22
+ */
23
+ export function useDisplayMode() {
24
+ const displayMode = useHostContext("displayMode");
25
+ const adaptor = getAdaptor();
26
+ const setDisplayMode = useCallback((mode) => adaptor.requestDisplayMode(mode), [adaptor]);
27
+ return [displayMode, setDisplayMode];
28
+ }
29
+ //# sourceMappingURL=use-display-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-display-mode.js","sourceRoot":"","sources":["../../../src/web/hooks/use-display-mode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGjE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,WAAW,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,cAAc,GAAG,WAAW,CAChC,CAAC,IAAwB,EAAE,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAC9D,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,OAAO,CAAC,WAAW,EAAE,cAAc,CAAU,CAAC;AAChD,CAAC","sourcesContent":["import { useCallback } from \"react\";\nimport { getAdaptor, useHostContext } from \"../bridges/index.js\";\nimport type { RequestDisplayMode } from \"../bridges/types.js\";\n\n/**\n * Read and change the view's display mode (`\"inline\"`, `\"pip\"`, `\"fullscreen\"`).\n *\n * Returns a tuple `[displayMode, setDisplayMode]`. `setDisplayMode` asks the\n * host to switch modes — the host returns the mode it actually applied, which\n * may differ from the request. The reported value also updates when the host\n * changes the mode on its own (e.g. user expands the widget).\n *\n * `\"modal\"` is reachable via {@link useRequestModal}, not this hook. To react\n * to layout changes that come with display-mode switches (e.g. `maxHeight`),\n * pair with {@link useLayout}.\n *\n * @example\n * ```tsx\n * const [mode, setMode] = useDisplayMode();\n * <button onClick={() => setMode(\"fullscreen\")}>Expand</button>\n * ```\n *\n * @see https://docs.skybridge.tech/api-reference/use-display-mode\n */\nexport function useDisplayMode() {\n const displayMode = useHostContext(\"displayMode\");\n const adaptor = getAdaptor();\n const setDisplayMode = useCallback(\n (mode: RequestDisplayMode) => adaptor.requestDisplayMode(mode),\n [adaptor],\n );\n\n return [displayMode, setDisplayMode] as const;\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { expectTypeOf, test } from "vitest";
2
+ test("setDisplayMode only accepts requestable display modes", () => {
3
+ expectTypeOf().toEqualTypeOf();
4
+ // @ts-expect-error "modal" is a host state, not a valid request mode
5
+ const _invalidMode = "modal";
6
+ void _invalidMode;
7
+ });
8
+ //# sourceMappingURL=use-display-mode.test-d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-display-mode.test-d.js","sourceRoot":"","sources":["../../../src/web/hooks/use-display-mode.test-d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAI5C,IAAI,CAAC,uDAAuD,EAAE,GAAG,EAAE;IAGjE,YAAY,EAET,CAAC,aAAa,EAAsB,CAAC;IAExC,qEAAqE;IACrE,MAAM,YAAY,GAAkC,OAAO,CAAC;IAC5D,KAAK,YAAY,CAAC;AACpB,CAAC,CAAC,CAAC","sourcesContent":["import { expectTypeOf, test } from \"vitest\";\nimport type { RequestDisplayMode } from \"../bridges/types.js\";\nimport type { useDisplayMode } from \"./use-display-mode.js\";\n\ntest(\"setDisplayMode only accepts requestable display modes\", () => {\n type SetDisplayMode = ReturnType<typeof useDisplayMode>[1];\n\n expectTypeOf<\n Parameters<SetDisplayMode>[0]\n >().toEqualTypeOf<RequestDisplayMode>();\n\n // @ts-expect-error \"modal\" is a host state, not a valid request mode\n const _invalidMode: Parameters<SetDisplayMode>[0] = \"modal\";\n void _invalidMode;\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,76 @@
1
+ import { act, fireEvent, renderHook, waitFor } from "@testing-library/react";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ import { AppsSdkBridge } from "../bridges/apps-sdk/bridge.js";
4
+ import { _resetAdaptor, getAdaptor } from "../bridges/get-adaptor.js";
5
+ import { McpAppBridge } from "../bridges/mcp-app/bridge.js";
6
+ import { getMcpAppHostPostMessageMock, MockResizeObserver, } from "./test/utils.js";
7
+ import { useDisplayMode } from "./use-display-mode.js";
8
+ describe("useDisplayMode", () => {
9
+ beforeEach(() => {
10
+ _resetAdaptor();
11
+ McpAppBridge.resetInstance();
12
+ AppsSdkBridge.resetInstance();
13
+ vi.stubGlobal("skybridge", { hostType: "apps-sdk" });
14
+ vi.stubGlobal("openai", { view: { mode: "inline" } });
15
+ vi.stubGlobal("ResizeObserver", MockResizeObserver);
16
+ });
17
+ afterEach(() => {
18
+ vi.unstubAllGlobals();
19
+ vi.resetAllMocks();
20
+ _resetAdaptor();
21
+ McpAppBridge.resetInstance();
22
+ AppsSdkBridge.resetInstance();
23
+ });
24
+ it("should return the current display mode from MCP host context", async () => {
25
+ vi.stubGlobal("parent", {
26
+ postMessage: getMcpAppHostPostMessageMock({ displayMode: "inline" }),
27
+ });
28
+ const { result } = renderHook(() => useDisplayMode());
29
+ await waitFor(() => {
30
+ expect(result.current[0]).toBe("inline");
31
+ });
32
+ });
33
+ it("should update display mode on host-context-changed notification", async () => {
34
+ vi.stubGlobal("parent", {
35
+ postMessage: getMcpAppHostPostMessageMock({ displayMode: "inline" }),
36
+ });
37
+ const { result } = renderHook(() => useDisplayMode());
38
+ await waitFor(() => {
39
+ expect(result.current[0]).toBe("inline");
40
+ });
41
+ act(() => {
42
+ fireEvent(window, new MessageEvent("message", {
43
+ source: window.parent,
44
+ data: {
45
+ jsonrpc: "2.0",
46
+ method: "ui/notifications/host-context-changed",
47
+ params: { displayMode: "fullscreen" },
48
+ },
49
+ }));
50
+ });
51
+ await waitFor(() => {
52
+ expect(result.current[0]).toBe("fullscreen");
53
+ });
54
+ });
55
+ it("should call requestDisplayMode on the adaptor when setDisplayMode is called", async () => {
56
+ vi.stubGlobal("parent", {
57
+ postMessage: getMcpAppHostPostMessageMock({ displayMode: "inline" }),
58
+ });
59
+ const { result } = renderHook(() => useDisplayMode());
60
+ await waitFor(() => expect(result.current[0]).toBe("inline"));
61
+ // Patch mcp.getApp to avoid real protocol request
62
+ const adaptor = getAdaptor();
63
+ const fakeApp = {
64
+ requestDisplayMode: vi.fn().mockResolvedValue({ mode: "fullscreen" }),
65
+ };
66
+ // biome-ignore lint/suspicious/noExplicitAny: test seam
67
+ adaptor.mcp.getApp = vi.fn().mockResolvedValue(fakeApp);
68
+ await act(async () => {
69
+ await result.current[1]("fullscreen");
70
+ });
71
+ expect(fakeApp.requestDisplayMode).toHaveBeenCalledWith({
72
+ mode: "fullscreen",
73
+ });
74
+ });
75
+ });
76
+ //# sourceMappingURL=use-display-mode.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-display-mode.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-display-mode.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { act, fireEvent, renderHook, waitFor } from \"@testing-library/react\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { AppsSdkBridge } from \"../bridges/apps-sdk/bridge.js\";\nimport { _resetAdaptor, getAdaptor } from \"../bridges/get-adaptor.js\";\nimport { McpAppBridge } from \"../bridges/mcp-app/bridge.js\";\nimport {\n getMcpAppHostPostMessageMock,\n MockResizeObserver,\n} from \"./test/utils.js\";\nimport { useDisplayMode } from \"./use-display-mode.js\";\n\ndescribe(\"useDisplayMode\", () => {\n beforeEach(() => {\n _resetAdaptor();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n vi.stubGlobal(\"skybridge\", { hostType: \"apps-sdk\" });\n vi.stubGlobal(\"openai\", { view: { mode: \"inline\" } });\n vi.stubGlobal(\"ResizeObserver\", MockResizeObserver);\n });\n\n afterEach(() => {\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n _resetAdaptor();\n McpAppBridge.resetInstance();\n AppsSdkBridge.resetInstance();\n });\n\n it(\"should return the current display mode from MCP host context\", async () => {\n vi.stubGlobal(\"parent\", {\n postMessage: getMcpAppHostPostMessageMock({ displayMode: \"inline\" }),\n });\n\n const { result } = renderHook(() => useDisplayMode());\n\n await waitFor(() => {\n expect(result.current[0]).toBe(\"inline\");\n });\n });\n\n it(\"should update display mode on host-context-changed notification\", async () => {\n vi.stubGlobal(\"parent\", {\n postMessage: getMcpAppHostPostMessageMock({ displayMode: \"inline\" }),\n });\n\n const { result } = renderHook(() => useDisplayMode());\n\n await waitFor(() => {\n expect(result.current[0]).toBe(\"inline\");\n });\n\n act(() => {\n fireEvent(\n window,\n new MessageEvent(\"message\", {\n source: window.parent,\n data: {\n jsonrpc: \"2.0\",\n method: \"ui/notifications/host-context-changed\",\n params: { displayMode: \"fullscreen\" },\n },\n }),\n );\n });\n\n await waitFor(() => {\n expect(result.current[0]).toBe(\"fullscreen\");\n });\n });\n\n it(\"should call requestDisplayMode on the adaptor when setDisplayMode is called\", async () => {\n vi.stubGlobal(\"parent\", {\n postMessage: getMcpAppHostPostMessageMock({ displayMode: \"inline\" }),\n });\n\n const { result } = renderHook(() => useDisplayMode());\n\n await waitFor(() => expect(result.current[0]).toBe(\"inline\"));\n\n // Patch mcp.getApp to avoid real protocol request\n const adaptor = getAdaptor();\n const fakeApp = {\n requestDisplayMode: vi.fn().mockResolvedValue({ mode: \"fullscreen\" }),\n };\n // biome-ignore lint/suspicious/noExplicitAny: test seam\n (adaptor as any).mcp.getApp = vi.fn().mockResolvedValue(fakeApp);\n\n await act(async () => {\n await result.current[1](\"fullscreen\");\n });\n\n expect(fakeApp.requestDisplayMode).toHaveBeenCalledWith({\n mode: \"fullscreen\",\n });\n });\n});\n"]}
@@ -0,0 +1,5 @@
1
+ import type { DownloadParams, DownloadResult } from "../bridges/types.js";
2
+ export type DownloadFn = (params: DownloadParams) => Promise<DownloadResult>;
3
+ export declare function useDownload(): {
4
+ download: DownloadFn;
5
+ };
@@ -0,0 +1,8 @@
1
+ import { useCallback } from "react";
2
+ import { getAdaptor } from "../bridges/index.js";
3
+ export function useDownload() {
4
+ const adaptor = getAdaptor();
5
+ const download = useCallback((params) => adaptor.download(params), [adaptor]);
6
+ return { download };
7
+ }
8
+ //# sourceMappingURL=use-download.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-download.js","sourceRoot":"","sources":["../../../src/web/hooks/use-download.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAKjD,MAAM,UAAU,WAAW;IACzB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,WAAW,CAC1B,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EACpC,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,OAAO,EAAE,QAAQ,EAAE,CAAC;AACtB,CAAC","sourcesContent":["import { useCallback } from \"react\";\nimport { getAdaptor } from \"../bridges/index.js\";\nimport type { DownloadParams, DownloadResult } from \"../bridges/types.js\";\n\nexport type DownloadFn = (params: DownloadParams) => Promise<DownloadResult>;\n\nexport function useDownload(): { download: DownloadFn } {\n const adaptor = getAdaptor();\n const download = useCallback<DownloadFn>(\n (params) => adaptor.download(params),\n [adaptor],\n );\n\n return { download };\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};