skybridge 0.0.0-dev.f05bf4f → 0.0.0-dev.f06e6cc

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 (644) hide show
  1. package/README.md +155 -0
  2. package/bin/run.js +5 -0
  3. package/dist/cli/build-helpers.d.ts +11 -0
  4. package/dist/cli/build-helpers.js +107 -0
  5. package/dist/cli/build-helpers.js.map +1 -0
  6. package/dist/cli/build-helpers.test.js +132 -0
  7. package/dist/cli/build-helpers.test.js.map +1 -0
  8. package/dist/cli/build-steps.d.ts +2 -0
  9. package/dist/cli/build-steps.js +73 -0
  10. package/dist/cli/build-steps.js.map +1 -0
  11. package/dist/cli/build-steps.test.js +52 -0
  12. package/dist/cli/build-steps.test.js.map +1 -0
  13. package/dist/cli/detect-port.d.ts +18 -0
  14. package/dist/cli/detect-port.js +49 -0
  15. package/dist/cli/detect-port.js.map +1 -0
  16. package/dist/cli/header.d.ts +4 -0
  17. package/dist/cli/header.js +6 -0
  18. package/dist/cli/header.js.map +1 -0
  19. package/dist/cli/resolve-skybridge-config.d.ts +5 -0
  20. package/dist/cli/resolve-skybridge-config.js +18 -0
  21. package/dist/cli/resolve-skybridge-config.js.map +1 -0
  22. package/dist/cli/run-command.d.ts +2 -0
  23. package/dist/cli/run-command.js +43 -0
  24. package/dist/cli/run-command.js.map +1 -0
  25. package/dist/cli/run-plain.d.ts +18 -0
  26. package/dist/cli/run-plain.js +89 -0
  27. package/dist/cli/run-plain.js.map +1 -0
  28. package/dist/cli/telemetry.d.ts +7 -0
  29. package/dist/cli/telemetry.js +125 -0
  30. package/dist/cli/telemetry.js.map +1 -0
  31. package/dist/cli/tunnel-control-server.d.ts +9 -0
  32. package/dist/cli/tunnel-control-server.js +31 -0
  33. package/dist/cli/tunnel-control-server.js.map +1 -0
  34. package/dist/cli/tunnel-control-server.test.js +39 -0
  35. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  36. package/dist/cli/tunnel-handler.d.ts +3 -0
  37. package/dist/cli/tunnel-handler.js +48 -0
  38. package/dist/cli/tunnel-handler.js.map +1 -0
  39. package/dist/cli/tunnel-handler.test.js +105 -0
  40. package/dist/cli/tunnel-handler.test.js.map +1 -0
  41. package/dist/cli/tunnel.d.ts +57 -0
  42. package/dist/cli/tunnel.js +154 -0
  43. package/dist/cli/tunnel.js.map +1 -0
  44. package/dist/cli/tunnel.test.js +190 -0
  45. package/dist/cli/tunnel.test.js.map +1 -0
  46. package/dist/cli/types.d.ts +5 -0
  47. package/dist/cli/types.js.map +1 -0
  48. package/dist/cli/use-execute-steps.d.ts +11 -0
  49. package/dist/cli/use-execute-steps.js +36 -0
  50. package/dist/cli/use-execute-steps.js.map +1 -0
  51. package/dist/cli/use-messages.d.ts +3 -0
  52. package/dist/cli/use-messages.js +11 -0
  53. package/dist/cli/use-messages.js.map +1 -0
  54. package/dist/cli/use-nodemon.d.ts +16 -0
  55. package/dist/cli/use-nodemon.js +92 -0
  56. package/dist/cli/use-nodemon.js.map +1 -0
  57. package/dist/cli/use-open-browser.d.ts +1 -0
  58. package/dist/cli/use-open-browser.js +44 -0
  59. package/dist/cli/use-open-browser.js.map +1 -0
  60. package/dist/cli/use-tunnel.d.ts +14 -0
  61. package/dist/cli/use-tunnel.js +131 -0
  62. package/dist/cli/use-tunnel.js.map +1 -0
  63. package/dist/cli/use-typescript-check.d.ts +15 -0
  64. package/dist/cli/use-typescript-check.js +97 -0
  65. package/dist/cli/use-typescript-check.js.map +1 -0
  66. package/dist/commands/build.d.ts +6 -0
  67. package/dist/commands/build.js +31 -0
  68. package/dist/commands/build.js.map +1 -0
  69. package/dist/commands/create.d.ts +9 -0
  70. package/dist/commands/create.js +30 -0
  71. package/dist/commands/create.js.map +1 -0
  72. package/dist/commands/dev.d.ts +13 -0
  73. package/dist/commands/dev.js +128 -0
  74. package/dist/commands/dev.js.map +1 -0
  75. package/dist/commands/start.d.ts +9 -0
  76. package/dist/commands/start.js +55 -0
  77. package/dist/commands/start.js.map +1 -0
  78. package/dist/commands/telemetry/disable.d.ts +5 -0
  79. package/dist/commands/telemetry/disable.js +14 -0
  80. package/dist/commands/telemetry/disable.js.map +1 -0
  81. package/dist/commands/telemetry/enable.d.ts +5 -0
  82. package/dist/commands/telemetry/enable.js +14 -0
  83. package/dist/commands/telemetry/enable.js.map +1 -0
  84. package/dist/commands/telemetry/status.d.ts +5 -0
  85. package/dist/commands/telemetry/status.js +14 -0
  86. package/dist/commands/telemetry/status.js.map +1 -0
  87. package/dist/context-warnings.d.ts +5 -0
  88. package/dist/context-warnings.js +31 -0
  89. package/dist/context-warnings.js.map +1 -0
  90. package/dist/context-warnings.test.js +28 -0
  91. package/dist/context-warnings.test.js.map +1 -0
  92. package/dist/server/app.d.ts +194 -0
  93. package/dist/server/app.js +266 -0
  94. package/dist/server/app.js.map +1 -0
  95. package/dist/server/app.test.js +97 -0
  96. package/dist/server/app.test.js.map +1 -0
  97. package/dist/server/asset-base-url-transform-plugin.d.ts +11 -0
  98. package/dist/server/asset-base-url-transform-plugin.js +48 -0
  99. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  100. package/dist/server/asset-base-url-transform-plugin.test.js +134 -0
  101. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  102. package/dist/server/auth/discovery.d.ts +33 -0
  103. package/dist/server/auth/discovery.js +56 -0
  104. package/dist/server/auth/discovery.js.map +1 -0
  105. package/dist/server/auth/discovery.test.js +93 -0
  106. package/dist/server/auth/discovery.test.js.map +1 -0
  107. package/dist/server/auth/index.d.ts +48 -0
  108. package/dist/server/auth/index.js +2 -0
  109. package/dist/server/auth/index.js.map +1 -0
  110. package/dist/server/auth/providers/auth0.d.ts +40 -0
  111. package/dist/server/auth/providers/auth0.js +36 -0
  112. package/dist/server/auth/providers/auth0.js.map +1 -0
  113. package/dist/server/auth/providers/auth0.test.js +50 -0
  114. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  115. package/dist/server/auth/providers/authplane.d.ts +49 -0
  116. package/dist/server/auth/providers/authplane.js +57 -0
  117. package/dist/server/auth/providers/authplane.js.map +1 -0
  118. package/dist/server/auth/providers/authplane.test.js +143 -0
  119. package/dist/server/auth/providers/authplane.test.js.map +1 -0
  120. package/dist/server/auth/providers/clerk.d.ts +51 -0
  121. package/dist/server/auth/providers/clerk.js +19 -0
  122. package/dist/server/auth/providers/clerk.js.map +1 -0
  123. package/dist/server/auth/providers/clerk.test.js +30 -0
  124. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  125. package/dist/server/auth/providers/custom.d.ts +40 -0
  126. package/dist/server/auth/providers/custom.js +59 -0
  127. package/dist/server/auth/providers/custom.js.map +1 -0
  128. package/dist/server/auth/providers/custom.test.js +161 -0
  129. package/dist/server/auth/providers/custom.test.js.map +1 -0
  130. package/dist/server/auth/providers/descope.d.ts +44 -0
  131. package/dist/server/auth/providers/descope.js +44 -0
  132. package/dist/server/auth/providers/descope.js.map +1 -0
  133. package/dist/server/auth/providers/descope.test.js +62 -0
  134. package/dist/server/auth/providers/descope.test.js.map +1 -0
  135. package/dist/server/auth/providers/shared.d.ts +2 -0
  136. package/dist/server/auth/providers/shared.js +6 -0
  137. package/dist/server/auth/providers/shared.js.map +1 -0
  138. package/dist/server/auth/providers/shared.test.js +10 -0
  139. package/dist/server/auth/providers/shared.test.js.map +1 -0
  140. package/dist/server/auth/providers/stytch.d.ts +25 -0
  141. package/dist/server/auth/providers/stytch.js +16 -0
  142. package/dist/server/auth/providers/stytch.js.map +1 -0
  143. package/dist/server/auth/providers/verify-spy.d.ts +12 -0
  144. package/dist/server/auth/providers/verify-spy.js +21 -0
  145. package/dist/server/auth/providers/verify-spy.js.map +1 -0
  146. package/dist/server/auth/providers/workos.d.ts +33 -0
  147. package/dist/server/auth/providers/workos.js +15 -0
  148. package/dist/server/auth/providers/workos.js.map +1 -0
  149. package/dist/server/auth/security-schemes.d.ts +23 -0
  150. package/dist/server/auth/security-schemes.js +64 -0
  151. package/dist/server/auth/security-schemes.js.map +1 -0
  152. package/dist/server/auth/security-schemes.test.js +99 -0
  153. package/dist/server/auth/security-schemes.test.js.map +1 -0
  154. package/dist/server/auth/setup.d.ts +6 -0
  155. package/dist/server/auth/setup.js +91 -0
  156. package/dist/server/auth/setup.js.map +1 -0
  157. package/dist/server/auth/setup.test.js +514 -0
  158. package/dist/server/auth/setup.test.js.map +1 -0
  159. package/dist/server/auth/verify.d.ts +46 -0
  160. package/dist/server/auth/verify.js +62 -0
  161. package/dist/server/auth/verify.js.map +1 -0
  162. package/dist/server/auth/verify.test.js +149 -0
  163. package/dist/server/auth/verify.test.js.map +1 -0
  164. package/dist/server/auth-extra.test-d.js +130 -0
  165. package/dist/server/auth-extra.test-d.js.map +1 -0
  166. package/dist/server/auth.d.ts +57 -0
  167. package/dist/server/auth.js +27 -0
  168. package/dist/server/auth.js.map +1 -0
  169. package/dist/server/build-manifest.test.js +28 -0
  170. package/dist/server/build-manifest.test.js.map +1 -0
  171. package/dist/server/content-helpers.d.ts +67 -0
  172. package/dist/server/content-helpers.js +79 -0
  173. package/dist/server/content-helpers.js.map +1 -0
  174. package/dist/server/content-helpers.test.d.ts +1 -0
  175. package/dist/server/content-helpers.test.js +70 -0
  176. package/dist/server/content-helpers.test.js.map +1 -0
  177. package/dist/server/express.d.ts +31 -0
  178. package/dist/server/express.js +107 -0
  179. package/dist/server/express.js.map +1 -0
  180. package/dist/server/express.test.d.ts +1 -0
  181. package/dist/server/express.test.js +608 -0
  182. package/dist/server/express.test.js.map +1 -0
  183. package/dist/server/file-ref.d.ts +28 -0
  184. package/dist/server/file-ref.js +27 -0
  185. package/dist/server/file-ref.js.map +1 -0
  186. package/dist/server/host.d.ts +2 -0
  187. package/dist/server/host.js +11 -0
  188. package/dist/server/host.js.map +1 -0
  189. package/dist/server/host.test.d.ts +1 -0
  190. package/dist/server/host.test.js +13 -0
  191. package/dist/server/host.test.js.map +1 -0
  192. package/dist/server/index.d.ts +22 -0
  193. package/dist/server/index.js +18 -0
  194. package/dist/server/index.js.map +1 -0
  195. package/dist/{src/server → server}/inferUtilityTypes.d.ts +6 -6
  196. package/dist/server/inferUtilityTypes.js.map +1 -0
  197. package/dist/server/mcp-errors.test.d.ts +1 -0
  198. package/dist/server/mcp-errors.test.js +41 -0
  199. package/dist/server/mcp-errors.test.js.map +1 -0
  200. package/dist/server/metric.d.ts +14 -0
  201. package/dist/server/metric.js +62 -0
  202. package/dist/server/metric.js.map +1 -0
  203. package/dist/server/middleware.d.ts +162 -0
  204. package/dist/server/middleware.js +126 -0
  205. package/dist/server/middleware.js.map +1 -0
  206. package/dist/server/middleware.test-d.d.ts +1 -0
  207. package/dist/server/middleware.test-d.js +75 -0
  208. package/dist/server/middleware.test-d.js.map +1 -0
  209. package/dist/server/middleware.test.d.ts +1 -0
  210. package/dist/server/middleware.test.js +601 -0
  211. package/dist/server/middleware.test.js.map +1 -0
  212. package/dist/server/register-tool.test.d.ts +1 -0
  213. package/dist/server/register-tool.test.js +27 -0
  214. package/dist/server/register-tool.test.js.map +1 -0
  215. package/dist/server/requestOrigin.d.ts +7 -0
  216. package/dist/server/requestOrigin.js +25 -0
  217. package/dist/server/requestOrigin.js.map +1 -0
  218. package/dist/server/server.d.ts +420 -0
  219. package/dist/server/server.js +546 -0
  220. package/dist/server/server.js.map +1 -0
  221. package/dist/server/skills-integration.test.d.ts +1 -0
  222. package/dist/server/skills-integration.test.js +86 -0
  223. package/dist/server/skills-integration.test.js.map +1 -0
  224. package/dist/server/skills.d.ts +27 -0
  225. package/dist/server/skills.js +188 -0
  226. package/dist/server/skills.js.map +1 -0
  227. package/dist/server/skills.test.d.ts +1 -0
  228. package/dist/server/skills.test.js +243 -0
  229. package/dist/server/skills.test.js.map +1 -0
  230. package/dist/{src/server → server}/templateHelper.d.ts +2 -7
  231. package/dist/server/templateHelper.js +11 -0
  232. package/dist/server/templateHelper.js.map +1 -0
  233. package/dist/server/templates.generated.d.ts +4 -0
  234. package/dist/server/templates.generated.js +43 -0
  235. package/dist/server/templates.generated.js.map +1 -0
  236. package/dist/server/tool-extra.test.d.ts +1 -0
  237. package/dist/server/tool-extra.test.js +88 -0
  238. package/dist/server/tool-extra.test.js.map +1 -0
  239. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  240. package/dist/server/tunnel-proxy-router.js +110 -0
  241. package/dist/server/tunnel-proxy-router.js.map +1 -0
  242. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  243. package/dist/server/tunnel-proxy-router.test.js +229 -0
  244. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  245. package/dist/server/view-name.test-d.d.ts +1 -0
  246. package/dist/server/view-name.test-d.js +8 -0
  247. package/dist/server/view-name.test-d.js.map +1 -0
  248. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  249. package/dist/server/view-resource-resolution.test.js +176 -0
  250. package/dist/server/view-resource-resolution.test.js.map +1 -0
  251. package/dist/server/viewsDevServer.d.ts +14 -0
  252. package/dist/server/viewsDevServer.js +48 -0
  253. package/dist/server/viewsDevServer.js.map +1 -0
  254. package/dist/{src/test → test}/utils.d.ts +21 -31
  255. package/dist/test/utils.js +266 -0
  256. package/dist/test/utils.js.map +1 -0
  257. package/dist/test/view.test.d.ts +1 -0
  258. package/dist/test/view.test.js +540 -0
  259. package/dist/test/view.test.js.map +1 -0
  260. package/dist/version.d.ts +1 -0
  261. package/dist/version.js +3 -0
  262. package/dist/version.js.map +1 -0
  263. package/dist/views/index.d.ts +10 -0
  264. package/dist/views/index.js +3 -0
  265. package/dist/views/index.js.map +1 -0
  266. package/dist/views/scan-views.d.ts +16 -0
  267. package/dist/views/scan-views.js +88 -0
  268. package/dist/views/scan-views.js.map +1 -0
  269. package/dist/views/scan-views.test.d.ts +1 -0
  270. package/dist/views/scan-views.test.js +99 -0
  271. package/dist/views/scan-views.test.js.map +1 -0
  272. package/dist/views/validate-view.d.ts +1 -0
  273. package/dist/views/validate-view.js +9 -0
  274. package/dist/views/validate-view.js.map +1 -0
  275. package/dist/views/validate-view.test.d.ts +1 -0
  276. package/dist/views/validate-view.test.js +24 -0
  277. package/dist/views/validate-view.test.js.map +1 -0
  278. package/dist/web/bridges/adaptor.d.ts +51 -0
  279. package/dist/web/bridges/adaptor.js +327 -0
  280. package/dist/web/bridges/adaptor.js.map +1 -0
  281. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  282. package/dist/web/bridges/adaptor.test.js +225 -0
  283. package/dist/web/bridges/adaptor.test.js.map +1 -0
  284. package/dist/web/bridges/apps-sdk/bridge.d.ts +15 -0
  285. package/dist/{src/web/bridges/apps-sdk-bridge.js → web/bridges/apps-sdk/bridge.js} +17 -5
  286. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  287. package/dist/web/bridges/apps-sdk/index.d.ts +4 -0
  288. package/dist/web/bridges/apps-sdk/index.js +4 -0
  289. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  290. package/dist/web/bridges/apps-sdk/types.d.ts +133 -0
  291. package/dist/{src/web → web/bridges/apps-sdk}/types.js +0 -1
  292. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  293. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +13 -0
  294. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +18 -0
  295. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  296. package/dist/web/bridges/get-adaptor.d.ts +9 -0
  297. package/dist/web/bridges/get-adaptor.js +10 -0
  298. package/dist/web/bridges/get-adaptor.js.map +1 -0
  299. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  300. package/dist/web/bridges/get-adaptor.test.js +32 -0
  301. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  302. package/dist/web/bridges/index.d.ts +5 -0
  303. package/dist/web/bridges/index.js +6 -0
  304. package/dist/web/bridges/index.js.map +1 -0
  305. package/dist/web/bridges/mcp-app/bridge.d.ts +39 -0
  306. package/dist/web/bridges/mcp-app/bridge.js +168 -0
  307. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  308. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  309. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  310. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  311. package/dist/web/bridges/mcp-app/index.d.ts +3 -0
  312. package/dist/web/bridges/mcp-app/index.js +3 -0
  313. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  314. package/dist/web/bridges/mcp-app/types.d.ts +10 -0
  315. package/dist/web/bridges/mcp-app/types.js +2 -0
  316. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  317. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +19 -0
  318. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +19 -0
  319. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  320. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.d.ts +1 -0
  321. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +26 -0
  322. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  323. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  324. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  325. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  326. package/dist/web/bridges/types.d.ts +219 -0
  327. package/dist/web/bridges/types.js +15 -0
  328. package/dist/web/bridges/types.js.map +1 -0
  329. package/dist/web/bridges/types.test.d.ts +1 -0
  330. package/dist/web/bridges/types.test.js +19 -0
  331. package/dist/web/bridges/types.test.js.map +1 -0
  332. package/dist/web/bridges/use-host-context.d.ts +7 -0
  333. package/dist/web/bridges/use-host-context.js +13 -0
  334. package/dist/web/bridges/use-host-context.js.map +1 -0
  335. package/dist/web/components/modal-provider.d.ts +4 -0
  336. package/dist/web/components/modal-provider.js +46 -0
  337. package/dist/web/components/modal-provider.js.map +1 -0
  338. package/dist/web/create-store.d.ts +29 -0
  339. package/dist/web/create-store.js +64 -0
  340. package/dist/web/create-store.js.map +1 -0
  341. package/dist/web/create-store.test.d.ts +1 -0
  342. package/dist/web/create-store.test.js +132 -0
  343. package/dist/web/create-store.test.js.map +1 -0
  344. package/dist/web/data-llm.d.ts +47 -0
  345. package/dist/{src/web → web}/data-llm.js +35 -5
  346. package/dist/web/data-llm.js.map +1 -0
  347. package/dist/web/data-llm.test.d.ts +1 -0
  348. package/dist/web/data-llm.test.js +155 -0
  349. package/dist/web/data-llm.test.js.map +1 -0
  350. package/dist/{src/web → web}/generate-helpers.d.ts +41 -32
  351. package/dist/{src/web → web}/generate-helpers.js +36 -28
  352. package/dist/web/generate-helpers.js.map +1 -0
  353. package/dist/web/generate-helpers.test-d.d.ts +1 -0
  354. package/dist/{src/web → web}/generate-helpers.test-d.js +33 -31
  355. package/dist/web/generate-helpers.test-d.js.map +1 -0
  356. package/dist/web/generate-helpers.test.d.ts +1 -0
  357. package/dist/{src/web → web}/generate-helpers.test.js +2 -2
  358. package/dist/web/generate-helpers.test.js.map +1 -0
  359. package/dist/{src/web → web}/helpers/state.d.ts +2 -2
  360. package/dist/web/helpers/state.js +45 -0
  361. package/dist/web/helpers/state.js.map +1 -0
  362. package/dist/web/helpers/state.test.d.ts +1 -0
  363. package/dist/{src/web → web}/helpers/state.test.js +9 -9
  364. package/dist/web/helpers/state.test.js.map +1 -0
  365. package/dist/web/hooks/index.d.ts +16 -0
  366. package/dist/web/hooks/index.js +17 -0
  367. package/dist/web/hooks/index.js.map +1 -0
  368. package/dist/web/hooks/test/utils.d.ts +21 -0
  369. package/dist/web/hooks/test/utils.js +75 -0
  370. package/dist/web/hooks/test/utils.js.map +1 -0
  371. package/dist/{src/web → web}/hooks/use-call-tool.d.ts +47 -1
  372. package/dist/{src/web → web}/hooks/use-call-tool.js +30 -2
  373. package/dist/web/hooks/use-call-tool.js.map +1 -0
  374. package/dist/web/hooks/use-call-tool.test-d.d.ts +1 -0
  375. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  376. package/dist/web/hooks/use-call-tool.test.d.ts +1 -0
  377. package/dist/{src/web → web}/hooks/use-call-tool.test.js +63 -29
  378. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  379. package/dist/web/hooks/use-display-mode.d.ts +24 -0
  380. package/dist/web/hooks/use-display-mode.js +29 -0
  381. package/dist/web/hooks/use-display-mode.js.map +1 -0
  382. package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
  383. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  384. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  385. package/dist/web/hooks/use-display-mode.test.d.ts +1 -0
  386. package/dist/web/hooks/use-display-mode.test.js +77 -0
  387. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  388. package/dist/web/hooks/use-download.d.ts +3 -0
  389. package/dist/web/hooks/use-download.js +7 -0
  390. package/dist/web/hooks/use-download.js.map +1 -0
  391. package/dist/web/hooks/use-download.test.d.ts +1 -0
  392. package/dist/web/hooks/use-download.test.js +103 -0
  393. package/dist/web/hooks/use-download.test.js.map +1 -0
  394. package/dist/web/hooks/use-files.d.ts +39 -0
  395. package/dist/web/hooks/use-files.js +42 -0
  396. package/dist/web/hooks/use-files.js.map +1 -0
  397. package/dist/web/hooks/use-files.test.d.ts +1 -0
  398. package/dist/web/hooks/use-files.test.js +62 -0
  399. package/dist/web/hooks/use-files.test.js.map +1 -0
  400. package/dist/web/hooks/use-host.d.ts +22 -0
  401. package/dist/web/hooks/use-host.js +30 -0
  402. package/dist/web/hooks/use-host.js.map +1 -0
  403. package/dist/web/hooks/use-host.test.d.ts +1 -0
  404. package/dist/web/hooks/use-host.test.js +59 -0
  405. package/dist/web/hooks/use-host.test.js.map +1 -0
  406. package/dist/web/hooks/use-open-external.d.ts +20 -0
  407. package/dist/web/hooks/use-open-external.js +24 -0
  408. package/dist/web/hooks/use-open-external.js.map +1 -0
  409. package/dist/web/hooks/use-open-external.test.d.ts +1 -0
  410. package/dist/web/hooks/use-open-external.test.js +75 -0
  411. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  412. package/dist/web/hooks/use-register-view-tool.d.ts +37 -0
  413. package/dist/web/hooks/use-register-view-tool.js +50 -0
  414. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  415. package/dist/web/hooks/use-request-close.d.ts +16 -0
  416. package/dist/web/hooks/use-request-close.js +21 -0
  417. package/dist/web/hooks/use-request-close.js.map +1 -0
  418. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  419. package/dist/web/hooks/use-request-close.test.js +47 -0
  420. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  421. package/dist/web/hooks/use-request-modal.d.ts +24 -0
  422. package/dist/web/hooks/use-request-modal.js +31 -0
  423. package/dist/web/hooks/use-request-modal.js.map +1 -0
  424. package/dist/web/hooks/use-request-modal.test.d.ts +1 -0
  425. package/dist/{src/web → web}/hooks/use-request-modal.test.js +16 -2
  426. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  427. package/dist/web/hooks/use-request-size.d.ts +20 -0
  428. package/dist/web/hooks/use-request-size.js +24 -0
  429. package/dist/web/hooks/use-request-size.js.map +1 -0
  430. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  431. package/dist/web/hooks/use-request-size.test.js +47 -0
  432. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  433. package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -0
  434. package/dist/web/hooks/use-send-follow-up-message.js +25 -0
  435. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  436. package/dist/web/hooks/use-set-open-in-app-url.d.ts +18 -0
  437. package/dist/web/hooks/use-set-open-in-app-url.js +25 -0
  438. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  439. package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
  440. package/dist/web/hooks/use-set-open-in-app-url.test.js +57 -0
  441. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  442. package/dist/web/hooks/use-tool-info.d.ts +68 -0
  443. package/dist/web/hooks/use-tool-info.js +48 -0
  444. package/dist/web/hooks/use-tool-info.js.map +1 -0
  445. package/dist/web/hooks/use-tool-info.test-d.d.ts +1 -0
  446. package/dist/{src/web → web}/hooks/use-tool-info.test-d.js +11 -34
  447. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  448. package/dist/web/hooks/use-tool-info.test.d.ts +1 -0
  449. package/dist/{src/web → web}/hooks/use-tool-info.test.js +45 -40
  450. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  451. package/dist/{src/web → web}/hooks/use-user.d.ts +5 -2
  452. package/dist/web/hooks/use-user.js +38 -0
  453. package/dist/web/hooks/use-user.js.map +1 -0
  454. package/dist/web/hooks/use-user.test.d.ts +1 -0
  455. package/dist/web/hooks/use-user.test.js +170 -0
  456. package/dist/web/hooks/use-user.test.js.map +1 -0
  457. package/dist/web/hooks/use-view-state.d.ts +25 -0
  458. package/dist/web/hooks/use-view-state.js +42 -0
  459. package/dist/web/hooks/use-view-state.js.map +1 -0
  460. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  461. package/dist/web/hooks/use-view-state.test.js +212 -0
  462. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  463. package/dist/web/hooks/use-viewport.d.ts +20 -0
  464. package/dist/web/hooks/use-viewport.js +21 -0
  465. package/dist/web/hooks/use-viewport.js.map +1 -0
  466. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  467. package/dist/web/hooks/use-viewport.test.js +109 -0
  468. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  469. package/dist/{src/web → web}/index.d.ts +1 -2
  470. package/dist/{src/web → web}/index.js +1 -2
  471. package/dist/web/index.js.map +1 -0
  472. package/dist/web/mount-view.d.ts +21 -0
  473. package/dist/web/mount-view.js +43 -0
  474. package/dist/web/mount-view.js.map +1 -0
  475. package/dist/{src/web → web}/proxy.js +0 -1
  476. package/dist/web/proxy.js.map +1 -0
  477. package/dist/web/types.d.ts +20 -0
  478. package/dist/web/types.js +2 -0
  479. package/dist/web/types.js.map +1 -0
  480. package/package.json +78 -31
  481. package/tsconfig.base.json +33 -0
  482. package/dist/src/server/devtoolsStaticServer.d.ts +0 -19
  483. package/dist/src/server/devtoolsStaticServer.js +0 -48
  484. package/dist/src/server/devtoolsStaticServer.js.map +0 -1
  485. package/dist/src/server/index.d.ts +0 -5
  486. package/dist/src/server/index.js +0 -4
  487. package/dist/src/server/index.js.map +0 -1
  488. package/dist/src/server/inferUtilityTypes.js.map +0 -1
  489. package/dist/src/server/server.d.ts +0 -74
  490. package/dist/src/server/server.js +0 -82
  491. package/dist/src/server/server.js.map +0 -1
  492. package/dist/src/server/templateHelper.js +0 -30
  493. package/dist/src/server/templateHelper.js.map +0 -1
  494. package/dist/src/server/templates/development.hbs +0 -51
  495. package/dist/src/server/templates/production.hbs +0 -7
  496. package/dist/src/server/widgetsDevServer.d.ts +0 -12
  497. package/dist/src/server/widgetsDevServer.js +0 -47
  498. package/dist/src/server/widgetsDevServer.js.map +0 -1
  499. package/dist/src/test/utils.js +0 -242
  500. package/dist/src/test/utils.js.map +0 -1
  501. package/dist/src/test/widget.test.js +0 -143
  502. package/dist/src/test/widget.test.js.map +0 -1
  503. package/dist/src/web/bridges/adaptors/apps-sdk-adaptor.d.ts +0 -13
  504. package/dist/src/web/bridges/adaptors/apps-sdk-adaptor.js +0 -33
  505. package/dist/src/web/bridges/adaptors/apps-sdk-adaptor.js.map +0 -1
  506. package/dist/src/web/bridges/adaptors/mcp-app-adaptor.d.ts +0 -16
  507. package/dist/src/web/bridges/adaptors/mcp-app-adaptor.js +0 -115
  508. package/dist/src/web/bridges/adaptors/mcp-app-adaptor.js.map +0 -1
  509. package/dist/src/web/bridges/apps-sdk-bridge.d.ts +0 -10
  510. package/dist/src/web/bridges/apps-sdk-bridge.js.map +0 -1
  511. package/dist/src/web/bridges/hooks/use-adaptor.d.ts +0 -2
  512. package/dist/src/web/bridges/hooks/use-adaptor.js +0 -8
  513. package/dist/src/web/bridges/hooks/use-adaptor.js.map +0 -1
  514. package/dist/src/web/bridges/hooks/use-apps-sdk-bridge.d.ts +0 -2
  515. package/dist/src/web/bridges/hooks/use-apps-sdk-bridge.js +0 -7
  516. package/dist/src/web/bridges/hooks/use-apps-sdk-bridge.js.map +0 -1
  517. package/dist/src/web/bridges/hooks/use-bridge.d.ts +0 -2
  518. package/dist/src/web/bridges/hooks/use-bridge.js +0 -8
  519. package/dist/src/web/bridges/hooks/use-bridge.js.map +0 -1
  520. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.d.ts +0 -5
  521. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.js +0 -7
  522. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.js.map +0 -1
  523. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.test.js +0 -41
  524. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.test.js.map +0 -1
  525. package/dist/src/web/bridges/index.d.ts +0 -4
  526. package/dist/src/web/bridges/index.js +0 -5
  527. package/dist/src/web/bridges/index.js.map +0 -1
  528. package/dist/src/web/bridges/mcp-app-bridge.d.ts +0 -38
  529. package/dist/src/web/bridges/mcp-app-bridge.js +0 -162
  530. package/dist/src/web/bridges/mcp-app-bridge.js.map +0 -1
  531. package/dist/src/web/bridges/types.d.ts +0 -57
  532. package/dist/src/web/bridges/types.js.map +0 -1
  533. package/dist/src/web/create-store.d.ts +0 -3
  534. package/dist/src/web/create-store.js +0 -25
  535. package/dist/src/web/create-store.js.map +0 -1
  536. package/dist/src/web/create-store.test.js +0 -70
  537. package/dist/src/web/create-store.test.js.map +0 -1
  538. package/dist/src/web/data-llm.d.ts +0 -14
  539. package/dist/src/web/data-llm.js.map +0 -1
  540. package/dist/src/web/data-llm.test.js +0 -76
  541. package/dist/src/web/data-llm.test.js.map +0 -1
  542. package/dist/src/web/generate-helpers.js.map +0 -1
  543. package/dist/src/web/generate-helpers.test-d.js.map +0 -1
  544. package/dist/src/web/generate-helpers.test.js.map +0 -1
  545. package/dist/src/web/helpers/state.js +0 -40
  546. package/dist/src/web/helpers/state.js.map +0 -1
  547. package/dist/src/web/helpers/state.test.js.map +0 -1
  548. package/dist/src/web/hooks/index.d.ts +0 -11
  549. package/dist/src/web/hooks/index.js +0 -12
  550. package/dist/src/web/hooks/index.js.map +0 -1
  551. package/dist/src/web/hooks/test/utils.d.ts +0 -10
  552. package/dist/src/web/hooks/test/utils.js +0 -40
  553. package/dist/src/web/hooks/test/utils.js.map +0 -1
  554. package/dist/src/web/hooks/use-call-tool.js.map +0 -1
  555. package/dist/src/web/hooks/use-call-tool.test-d.js.map +0 -1
  556. package/dist/src/web/hooks/use-call-tool.test.js.map +0 -1
  557. package/dist/src/web/hooks/use-display-mode.d.ts +0 -4
  558. package/dist/src/web/hooks/use-display-mode.js +0 -10
  559. package/dist/src/web/hooks/use-display-mode.js.map +0 -1
  560. package/dist/src/web/hooks/use-display-mode.test.js +0 -41
  561. package/dist/src/web/hooks/use-display-mode.test.js.map +0 -1
  562. package/dist/src/web/hooks/use-files.d.ts +0 -10
  563. package/dist/src/web/hooks/use-files.js +0 -7
  564. package/dist/src/web/hooks/use-files.js.map +0 -1
  565. package/dist/src/web/hooks/use-files.test.js +0 -29
  566. package/dist/src/web/hooks/use-files.test.js.map +0 -1
  567. package/dist/src/web/hooks/use-layout.d.ts +0 -22
  568. package/dist/src/web/hooks/use-layout.js +0 -23
  569. package/dist/src/web/hooks/use-layout.js.map +0 -1
  570. package/dist/src/web/hooks/use-layout.test.js +0 -95
  571. package/dist/src/web/hooks/use-layout.test.js.map +0 -1
  572. package/dist/src/web/hooks/use-open-external.d.ts +0 -1
  573. package/dist/src/web/hooks/use-open-external.js +0 -8
  574. package/dist/src/web/hooks/use-open-external.js.map +0 -1
  575. package/dist/src/web/hooks/use-open-external.test.js +0 -50
  576. package/dist/src/web/hooks/use-open-external.test.js.map +0 -1
  577. package/dist/src/web/hooks/use-openai-global.d.ts +0 -3
  578. package/dist/src/web/hooks/use-openai-global.js +0 -6
  579. package/dist/src/web/hooks/use-openai-global.js.map +0 -1
  580. package/dist/src/web/hooks/use-request-modal.d.ts +0 -9
  581. package/dist/src/web/hooks/use-request-modal.js +0 -14
  582. package/dist/src/web/hooks/use-request-modal.js.map +0 -1
  583. package/dist/src/web/hooks/use-request-modal.test.js.map +0 -1
  584. package/dist/src/web/hooks/use-send-follow-up-message.d.ts +0 -1
  585. package/dist/src/web/hooks/use-send-follow-up-message.js +0 -8
  586. package/dist/src/web/hooks/use-send-follow-up-message.js.map +0 -1
  587. package/dist/src/web/hooks/use-tool-info.d.ts +0 -36
  588. package/dist/src/web/hooks/use-tool-info.js +0 -26
  589. package/dist/src/web/hooks/use-tool-info.js.map +0 -1
  590. package/dist/src/web/hooks/use-tool-info.test-d.js.map +0 -1
  591. package/dist/src/web/hooks/use-tool-info.test.js.map +0 -1
  592. package/dist/src/web/hooks/use-user.js +0 -19
  593. package/dist/src/web/hooks/use-user.js.map +0 -1
  594. package/dist/src/web/hooks/use-user.test.js +0 -93
  595. package/dist/src/web/hooks/use-user.test.js.map +0 -1
  596. package/dist/src/web/hooks/use-widget-state.d.ts +0 -4
  597. package/dist/src/web/hooks/use-widget-state.js +0 -32
  598. package/dist/src/web/hooks/use-widget-state.js.map +0 -1
  599. package/dist/src/web/hooks/use-widget-state.test.js +0 -61
  600. package/dist/src/web/hooks/use-widget-state.test.js.map +0 -1
  601. package/dist/src/web/index.js.map +0 -1
  602. package/dist/src/web/mount-widget.d.ts +0 -1
  603. package/dist/src/web/mount-widget.js +0 -19
  604. package/dist/src/web/mount-widget.js.map +0 -1
  605. package/dist/src/web/plugin/data-llm.test.js +0 -81
  606. package/dist/src/web/plugin/data-llm.test.js.map +0 -1
  607. package/dist/src/web/plugin/plugin.d.ts +0 -2
  608. package/dist/src/web/plugin/plugin.js +0 -39
  609. package/dist/src/web/plugin/plugin.js.map +0 -1
  610. package/dist/src/web/plugin/transform-data-llm.d.ts +0 -12
  611. package/dist/src/web/plugin/transform-data-llm.js +0 -96
  612. package/dist/src/web/plugin/transform-data-llm.js.map +0 -1
  613. package/dist/src/web/plugin/transform-data-llm.test.js +0 -81
  614. package/dist/src/web/plugin/transform-data-llm.test.js.map +0 -1
  615. package/dist/src/web/proxy.js.map +0 -1
  616. package/dist/src/web/types.d.ts +0 -149
  617. package/dist/src/web/types.js.map +0 -1
  618. package/dist/vitest.config.d.ts +0 -2
  619. package/dist/vitest.config.js +0 -8
  620. package/dist/vitest.config.js.map +0 -1
  621. /package/dist/{src/test/widget.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  622. /package/dist/{src/web/bridges/hooks/use-mcp-app-bridge.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  623. /package/dist/{src/web/create-store.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
  624. /package/dist/{src/web/data-llm.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
  625. /package/dist/{src/web/generate-helpers.test-d.d.ts → cli/tunnel.test.d.ts} +0 -0
  626. /package/dist/{src/web/bridges → cli}/types.js +0 -0
  627. /package/dist/{src/web/generate-helpers.test.d.ts → context-warnings.test.d.ts} +0 -0
  628. /package/dist/{src/web/helpers/state.test.d.ts → server/app.test.d.ts} +0 -0
  629. /package/dist/{src/web/hooks/use-call-tool.test-d.d.ts → server/asset-base-url-transform-plugin.test.d.ts} +0 -0
  630. /package/dist/{src/web/hooks/use-display-mode.test.d.ts → server/auth/discovery.test.d.ts} +0 -0
  631. /package/dist/{src/web/hooks/use-files.test.d.ts → server/auth/providers/auth0.test.d.ts} +0 -0
  632. /package/dist/{src/web/hooks/use-layout.test.d.ts → server/auth/providers/authplane.test.d.ts} +0 -0
  633. /package/dist/{src/web/hooks/use-open-external.test.d.ts → server/auth/providers/clerk.test.d.ts} +0 -0
  634. /package/dist/{src/web/hooks/use-request-modal.test.d.ts → server/auth/providers/custom.test.d.ts} +0 -0
  635. /package/dist/{src/web/hooks/use-tool-info.test-d.d.ts → server/auth/providers/descope.test.d.ts} +0 -0
  636. /package/dist/{src/web/hooks/use-tool-info.test.d.ts → server/auth/providers/shared.test.d.ts} +0 -0
  637. /package/dist/{src/web/hooks/use-user.test.d.ts → server/auth/security-schemes.test.d.ts} +0 -0
  638. /package/dist/{src/web/hooks/use-widget-state.test.d.ts → server/auth/setup.test.d.ts} +0 -0
  639. /package/dist/{src/web/plugin/data-llm.test.d.ts → server/auth/verify.test.d.ts} +0 -0
  640. /package/dist/{src/web/hooks/use-call-tool.test.d.ts → server/auth-extra.test-d.d.ts} +0 -0
  641. /package/dist/{src/web/plugin/transform-data-llm.test.d.ts → server/build-manifest.test.d.ts} +0 -0
  642. /package/dist/{src/server → server}/inferUtilityTypes.js +0 -0
  643. /package/dist/{src/web → web}/hooks/use-call-tool.test-d.js +0 -0
  644. /package/dist/{src/web → web}/proxy.d.ts +0 -0
@@ -0,0 +1,25 @@
1
+ import { useCallback } from "react";
2
+ import { getAdaptor } from "../bridges/index.js";
3
+ /**
4
+ * Override the target URL the host opens from its fullscreen "Open in <App>"
5
+ * affordance. If unset, the host opens the view's current iframe path.
6
+ *
7
+ * Currently Apps-SDK-only — calling this from MCP Apps throws.
8
+ *
9
+ * Call this once your view has enough context to construct the canonical URL
10
+ * (e.g. a permalink to the entity the user is currently viewing).
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * const setOpenInAppUrl = useSetOpenInAppUrl();
15
+ * useEffect(() => { setOpenInAppUrl(`https://example.com/orders/${orderId}`); }, [orderId]);
16
+ * ```
17
+ *
18
+ * @see https://docs.skybridge.tech/api-reference/use-set-open-in-app-url
19
+ */
20
+ export function useSetOpenInAppUrl() {
21
+ const adaptor = getAdaptor();
22
+ const setOpenInAppUrl = useCallback((href) => adaptor.setOpenInAppUrl(href), [adaptor]);
23
+ return setOpenInAppUrl;
24
+ }
25
+ //# sourceMappingURL=use-set-open-in-app-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-set-open-in-app-url.js","sourceRoot":"","sources":["../../../src/web/hooks/use-set-open-in-app-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,eAAe,GAAG,WAAW,CACjC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,EAC/C,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,OAAO,eAAe,CAAC;AACzB,CAAC","sourcesContent":["import { useCallback } from \"react\";\nimport { getAdaptor } from \"../bridges/index.js\";\n\n/**\n * Override the target URL the host opens from its fullscreen \"Open in <App>\"\n * affordance. If unset, the host opens the view's current iframe path.\n *\n * Currently Apps-SDK-only — calling this from MCP Apps throws.\n *\n * Call this once your view has enough context to construct the canonical URL\n * (e.g. a permalink to the entity the user is currently viewing).\n *\n * @example\n * ```tsx\n * const setOpenInAppUrl = useSetOpenInAppUrl();\n * useEffect(() => { setOpenInAppUrl(`https://example.com/orders/${orderId}`); }, [orderId]);\n * ```\n *\n * @see https://docs.skybridge.tech/api-reference/use-set-open-in-app-url\n */\nexport function useSetOpenInAppUrl() {\n const adaptor = getAdaptor();\n const setOpenInAppUrl = useCallback(\n (href: string) => adaptor.setOpenInAppUrl(href),\n [adaptor],\n );\n\n return setOpenInAppUrl;\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,57 @@
1
+ import { renderHook } from "@testing-library/react";
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";
6
+ import { NotSupportedError } from "../bridges/types.js";
7
+ import { useSetOpenInAppUrl } from "./use-set-open-in-app-url.js";
8
+ describe("useSetOpenInAppUrl", () => {
9
+ afterEach(() => {
10
+ vi.unstubAllGlobals();
11
+ vi.resetAllMocks();
12
+ HostAdaptor.resetInstance();
13
+ AppsSdkBridge.resetInstance();
14
+ McpAppBridge.resetInstance();
15
+ });
16
+ describe("apps-sdk host", () => {
17
+ let setOpenInAppUrlMock;
18
+ beforeEach(() => {
19
+ setOpenInAppUrlMock = vi.fn().mockResolvedValue(undefined);
20
+ vi.stubGlobal("openai", {
21
+ setOpenInAppUrl: setOpenInAppUrlMock,
22
+ });
23
+ vi.stubGlobal("skybridge", { serverUrl: "https://example.com" });
24
+ vi.stubGlobal("parent", { postMessage: vi.fn() });
25
+ });
26
+ it("should return a function that calls window.openai.setOpenInAppUrl with the href", async () => {
27
+ const { result } = renderHook(() => useSetOpenInAppUrl());
28
+ const href = "https://example.com/path";
29
+ await result.current(href);
30
+ expect(setOpenInAppUrlMock).toHaveBeenCalledTimes(1);
31
+ expect(setOpenInAppUrlMock).toHaveBeenCalledWith({ href });
32
+ });
33
+ it("should reject when href is empty", async () => {
34
+ const { result } = renderHook(() => useSetOpenInAppUrl());
35
+ await expect(result.current("")).rejects.toThrow("The href parameter is required.");
36
+ });
37
+ it("should call setOpenInAppUrl when href origin differs from serverUrl origin", async () => {
38
+ const { result } = renderHook(() => useSetOpenInAppUrl());
39
+ const href = "https://different-domain.com/path";
40
+ await result.current(href);
41
+ expect(setOpenInAppUrlMock).toHaveBeenCalledTimes(1);
42
+ expect(setOpenInAppUrlMock).toHaveBeenCalledWith({ href });
43
+ });
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
+ });
56
+ });
57
+ //# sourceMappingURL=use-set-open-in-app-url.test.js.map
@@ -0,0 +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":"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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"]}
@@ -0,0 +1,68 @@
1
+ import type { UnknownObject } from "../types.js";
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
+ */
9
+ export type ToolPendingState<ToolInput extends UnknownObject> = {
10
+ status: "pending";
11
+ isPending: true;
12
+ isSuccess: false;
13
+ input: ToolInput | undefined;
14
+ output: undefined;
15
+ responseMetadata: undefined;
16
+ };
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
+ export type ToolSuccessState<ToolInput extends UnknownObject, ToolOutput extends UnknownObject, ToolResponseMetadata extends UnknownObject> = {
24
+ status: "success";
25
+ isPending: false;
26
+ isSuccess: true;
27
+ input: ToolInput | undefined;
28
+ output: ToolOutput;
29
+ responseMetadata: ToolResponseMetadata;
30
+ };
31
+ /**
32
+ * Discriminated union describing the tool invocation that triggered the
33
+ * current view render. Use `isPending` / `isSuccess` to narrow.
34
+ */
35
+ export type ToolState<ToolInput extends UnknownObject, ToolOutput extends UnknownObject, ToolResponseMetadata extends UnknownObject> = ToolPendingState<ToolInput> | ToolSuccessState<ToolInput, ToolOutput, ToolResponseMetadata>;
36
+ type ToolSignature = {
37
+ input: UnknownObject;
38
+ output: UnknownObject;
39
+ responseMetadata: UnknownObject;
40
+ };
41
+ /**
42
+ * Access the tool invocation that produced the current view: its `input`,
43
+ * resulting `output`, and `responseMetadata`. The shape evolves as the tool
44
+ * runs (pending → success), exposed through {@link ToolState}.
45
+ *
46
+ * For full input/output typing per tool name, prefer the typed `useToolInfo`
47
+ * returned by {@link generateHelpers} over the generic form.
48
+ *
49
+ * @typeParam TS - Optional partial shape `{ input, output, responseMetadata }`
50
+ * to refine each field's type. When omitted, each typed field resolves to
51
+ * `never` — pass an explicit shape or use the typed helper from
52
+ * {@link generateHelpers} to get usable types.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * const { isSuccess, input, output } = useToolInfo<{
57
+ * input: { query: string };
58
+ * output: { results: Result[] };
59
+ * }>();
60
+ *
61
+ * if (!isSuccess || !output) return <Skeleton />;
62
+ * return <Results items={output.results} />;
63
+ * ```
64
+ *
65
+ * @see https://docs.skybridge.tech/api-reference/use-tool-info
66
+ */
67
+ export declare function useToolInfo<TS extends Partial<ToolSignature> = Record<string, never>>(): ToolState<UnknownObject & TS["input"], UnknownObject & TS["output"], UnknownObject & TS["responseMetadata"]>;
68
+ export {};
@@ -0,0 +1,48 @@
1
+ import { useHostContext } from "../bridges/index.js";
2
+ function deriveStatus(output, responseMetadata) {
3
+ if (output === null && responseMetadata === null) {
4
+ return "pending";
5
+ }
6
+ return "success";
7
+ }
8
+ /**
9
+ * Access the tool invocation that produced the current view: its `input`,
10
+ * resulting `output`, and `responseMetadata`. The shape evolves as the tool
11
+ * runs (pending → success), exposed through {@link ToolState}.
12
+ *
13
+ * For full input/output typing per tool name, prefer the typed `useToolInfo`
14
+ * returned by {@link generateHelpers} over the generic form.
15
+ *
16
+ * @typeParam TS - Optional partial shape `{ input, output, responseMetadata }`
17
+ * to refine each field's type. When omitted, each typed field resolves to
18
+ * `never` — pass an explicit shape or use the typed helper from
19
+ * {@link generateHelpers} to get usable types.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * const { isSuccess, input, output } = useToolInfo<{
24
+ * input: { query: string };
25
+ * output: { results: Result[] };
26
+ * }>();
27
+ *
28
+ * if (!isSuccess || !output) return <Skeleton />;
29
+ * return <Results items={output.results} />;
30
+ * ```
31
+ *
32
+ * @see https://docs.skybridge.tech/api-reference/use-tool-info
33
+ */
34
+ export function useToolInfo() {
35
+ const input = useHostContext("toolInput");
36
+ const output = useHostContext("toolOutput");
37
+ const responseMetadata = useHostContext("toolResponseMetadata");
38
+ const status = deriveStatus(output, responseMetadata);
39
+ return {
40
+ input: input ?? undefined,
41
+ status,
42
+ isPending: status === "pending",
43
+ isSuccess: status === "success",
44
+ output,
45
+ responseMetadata,
46
+ };
47
+ }
48
+ //# sourceMappingURL=use-tool-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tool-info.js","sourceRoot":"","sources":["../../../src/web/hooks/use-tool-info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAwDrD,SAAS,YAAY,CACnB,MAAsC,EACtC,gBAAgD;IAEhD,IAAI,MAAM,KAAK,IAAI,IAAI,gBAAgB,KAAK,IAAI,EAAE,CAAC;QACjD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,WAAW;IAGzB,MAAM,KAAK,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;IAC5C,MAAM,gBAAgB,GAAG,cAAc,CAAC,sBAAsB,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAMtD,OAAO;QACL,KAAK,EAAE,KAAK,IAAI,SAAS;QACzB,MAAM;QACN,SAAS,EAAE,MAAM,KAAK,SAAS;QAC/B,SAAS,EAAE,MAAM,KAAK,SAAS;QAC/B,MAAM;QACN,gBAAgB;KACqB,CAAC;AAC1C,CAAC","sourcesContent":["import { useHostContext } from \"../bridges/index.js\";\nimport type { UnknownObject } from \"../types.js\";\n\n/**\n * {@link useToolInfo} state while the tool is executing — `output` is not yet\n * available.\n *\n * `input` is optional: the host may render the view before delivering the\n * tool arguments.\n */\nexport type ToolPendingState<ToolInput extends UnknownObject> = {\n status: \"pending\";\n isPending: true;\n isSuccess: false;\n input: ToolInput | undefined;\n output: undefined;\n responseMetadata: undefined;\n};\n\n/**\n * {@link useToolInfo} state once the tool returned — `output` is available.\n *\n * `input` is optional: the host may not have surfaced the tool arguments by\n * the time `output` arrives.\n */\nexport type ToolSuccessState<\n ToolInput extends UnknownObject,\n ToolOutput extends UnknownObject,\n ToolResponseMetadata extends UnknownObject,\n> = {\n status: \"success\";\n isPending: false;\n isSuccess: true;\n input: ToolInput | undefined;\n output: ToolOutput;\n responseMetadata: ToolResponseMetadata;\n};\n\n/**\n * Discriminated union describing the tool invocation that triggered the\n * current view render. Use `isPending` / `isSuccess` to narrow.\n */\nexport type ToolState<\n ToolInput extends UnknownObject,\n ToolOutput extends UnknownObject,\n ToolResponseMetadata extends UnknownObject,\n> =\n | ToolPendingState<ToolInput>\n | ToolSuccessState<ToolInput, ToolOutput, ToolResponseMetadata>;\n\ntype ToolSignature = {\n input: UnknownObject;\n output: UnknownObject;\n responseMetadata: UnknownObject;\n};\n\nfunction deriveStatus(\n output: Record<string, unknown> | null,\n responseMetadata: Record<string, unknown> | null,\n): \"pending\" | \"success\" {\n if (output === null && responseMetadata === null) {\n return \"pending\";\n }\n return \"success\";\n}\n\n/**\n * Access the tool invocation that produced the current view: its `input`,\n * resulting `output`, and `responseMetadata`. The shape evolves as the tool\n * runs (pending → success), exposed through {@link ToolState}.\n *\n * For full input/output typing per tool name, prefer the typed `useToolInfo`\n * returned by {@link generateHelpers} over the generic form.\n *\n * @typeParam TS - Optional partial shape `{ input, output, responseMetadata }`\n * to refine each field's type. When omitted, each typed field resolves to\n * `never` — pass an explicit shape or use the typed helper from\n * {@link generateHelpers} to get usable types.\n *\n * @example\n * ```tsx\n * const { isSuccess, input, output } = useToolInfo<{\n * input: { query: string };\n * output: { results: Result[] };\n * }>();\n *\n * if (!isSuccess || !output) return <Skeleton />;\n * return <Results items={output.results} />;\n * ```\n *\n * @see https://docs.skybridge.tech/api-reference/use-tool-info\n */\nexport function useToolInfo<\n TS extends Partial<ToolSignature> = Record<string, never>,\n>() {\n const input = useHostContext(\"toolInput\");\n const output = useHostContext(\"toolOutput\");\n const responseMetadata = useHostContext(\"toolResponseMetadata\");\n\n const status = deriveStatus(output, responseMetadata);\n\n type Input = UnknownObject & TS[\"input\"];\n type Output = UnknownObject & TS[\"output\"];\n type Metadata = UnknownObject & TS[\"responseMetadata\"];\n\n return {\n input: input ?? undefined,\n status,\n isPending: status === \"pending\",\n isSuccess: status === \"success\",\n output,\n responseMetadata,\n } as ToolState<Input, Output, Metadata>;\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -6,24 +6,19 @@ test("useToolInfo - TypeScript typing", () => {
6
6
  expectTypeOf(result.status);
7
7
  expectTypeOf(result.isPending);
8
8
  expectTypeOf(result.isSuccess);
9
- expectTypeOf(result.isIdle);
10
9
  expectTypeOf(result.input);
11
10
  });
12
11
  test("should correctly type input, output, and responseMetadata with explicit ToolSignature", () => {
13
12
  const result = useToolInfo();
14
- // When idle, input should be undefined
15
- if (result.status === "idle") {
16
- expectTypeOf(result.input);
17
- expectTypeOf(result.output);
18
- expectTypeOf(result.responseMetadata);
19
- }
20
- // When pending, output and responseMetadata should be undefined
13
+ // When pending, input may be undefined (host hasn't delivered args yet,
14
+ // or the tool has no input schema)
21
15
  if (result.status === "pending") {
22
16
  expectTypeOf(result.input);
23
17
  expectTypeOf(result.output);
24
18
  expectTypeOf(result.responseMetadata);
25
19
  }
26
- // When success, output and responseMetadata should be defined
20
+ // When success, output and responseMetadata are defined; input may still
21
+ // be undefined if the host hasn't surfaced the tool arguments
27
22
  if (result.status === "success") {
28
23
  expectTypeOf(result.input);
29
24
  expectTypeOf(result.output);
@@ -32,35 +27,17 @@ test("useToolInfo - TypeScript typing", () => {
32
27
  });
33
28
  test("should correctly narrow types based on status discriminated union", () => {
34
29
  const result = useToolInfo();
35
- // Test type narrowing for idle
36
- if (result.isIdle) {
37
- expectTypeOf(result.status);
38
- expectTypeOf(result.isIdle);
39
- expectTypeOf(result.isPending);
40
- expectTypeOf(result.isSuccess);
41
- expectTypeOf(result.input);
42
- expectTypeOf(result.output);
43
- expectTypeOf(result.responseMetadata);
44
- }
45
30
  // Test type narrowing for pending
46
31
  if (result.isPending) {
47
32
  expectTypeOf(result.status);
48
- expectTypeOf(result.isIdle);
49
33
  expectTypeOf(result.isPending);
50
34
  expectTypeOf(result.isSuccess);
35
+ expectTypeOf(result.input);
51
36
  expectTypeOf(result.output);
52
37
  expectTypeOf(result.responseMetadata);
53
38
  }
54
39
  if (result.isSuccess) {
55
40
  expectTypeOf(result.status);
56
- expectTypeOf(result.isIdle);
57
- expectTypeOf(result.isPending);
58
- expectTypeOf(result.isSuccess);
59
- expectTypeOf(result.output);
60
- expectTypeOf(result.responseMetadata);
61
- }
62
- if (result.status === "idle") {
63
- expectTypeOf(result.isIdle);
64
41
  expectTypeOf(result.isPending);
65
42
  expectTypeOf(result.isSuccess);
66
43
  expectTypeOf(result.input);
@@ -69,7 +46,6 @@ test("useToolInfo - TypeScript typing", () => {
69
46
  }
70
47
  if (result.status === "pending") {
71
48
  expectTypeOf(result.input);
72
- expectTypeOf(result.isIdle);
73
49
  expectTypeOf(result.isPending);
74
50
  expectTypeOf(result.isSuccess);
75
51
  expectTypeOf(result.output);
@@ -77,7 +53,6 @@ test("useToolInfo - TypeScript typing", () => {
77
53
  }
78
54
  if (result.status === "success") {
79
55
  expectTypeOf(result.input);
80
- expectTypeOf(result.isIdle);
81
56
  expectTypeOf(result.isPending);
82
57
  expectTypeOf(result.isSuccess);
83
58
  expectTypeOf(result.output);
@@ -86,22 +61,24 @@ test("useToolInfo - TypeScript typing", () => {
86
61
  });
87
62
  test("should handle partial ToolSignature with only input specified", () => {
88
63
  const result = useToolInfo();
89
- // Input can be TestInput or undefined (when idle)
90
- if (result.status === "pending" || result.status === "success") {
64
+ // Input is optional in both states — undefined while args haven't arrived
65
+ // (pending) and for no-input tools (success).
66
+ if (result.status === "pending") {
91
67
  expectTypeOf(result.input);
92
68
  }
93
69
  if (result.status === "success") {
70
+ expectTypeOf(result.input);
94
71
  expectTypeOf(result.output);
95
72
  expectTypeOf(result.responseMetadata);
96
73
  }
97
74
  });
98
75
  test("should handle ToolSignature with only output specified", () => {
99
76
  const result = useToolInfo();
100
- // Input can be Record<string, unknown> or undefined (when idle)
101
- if (result.status === "pending" || result.status === "success") {
77
+ if (result.status === "pending") {
102
78
  expectTypeOf(result.input);
103
79
  }
104
80
  if (result.status === "success") {
81
+ expectTypeOf(result.input);
105
82
  expectTypeOf(result.output);
106
83
  }
107
84
  });
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tool-info.test-d.js","sourceRoot":"","sources":["../../../src/web/hooks/use-tool-info.test-d.ts"],"names":[],"mappings":"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","sourcesContent":["import { expectTypeOf, test } from \"vitest\";\nimport { useToolInfo } from \"./use-tool-info.js\";\n\ntest(\"useToolInfo - TypeScript typing\", () => {\n test(\"should have correct types when no generic parameter is provided\", () => {\n const result = useToolInfo();\n\n expectTypeOf<\"pending\" | \"success\">(result.status);\n expectTypeOf<boolean>(result.isPending);\n expectTypeOf<boolean>(result.isSuccess);\n expectTypeOf<Record<string, unknown> | undefined>(result.input);\n });\n\n test(\"should correctly type input, output, and responseMetadata with explicit ToolSignature\", () => {\n type TestInput = { name: string; args: { name: string } };\n type TestOutput = { name: string; color: string };\n type TestMetadata = { id: number };\n\n const result = useToolInfo<{\n input: TestInput;\n output: TestOutput;\n responseMetadata: TestMetadata;\n }>();\n\n // When pending, input may be undefined (host hasn't delivered args yet,\n // or the tool has no input schema)\n if (result.status === \"pending\") {\n expectTypeOf<TestInput | undefined>(result.input);\n expectTypeOf<undefined>(result.output);\n expectTypeOf<undefined>(result.responseMetadata);\n }\n\n // When success, output and responseMetadata are defined; input may still\n // be undefined if the host hasn't surfaced the tool arguments\n if (result.status === \"success\") {\n expectTypeOf<TestInput | undefined>(result.input);\n expectTypeOf<TestOutput>(result.output);\n expectTypeOf<TestMetadata>(result.responseMetadata);\n }\n });\n\n test(\"should correctly narrow types based on status discriminated union\", () => {\n type TestInput = { query: string };\n type TestOutput = { result: string };\n type TestMetadata = { timestamp: number };\n\n const result = useToolInfo<{\n input: TestInput;\n output: TestOutput;\n responseMetadata: TestMetadata;\n }>();\n\n // Test type narrowing for pending\n if (result.isPending) {\n expectTypeOf<\"pending\">(result.status);\n expectTypeOf<true>(result.isPending);\n expectTypeOf<false>(result.isSuccess);\n expectTypeOf<TestInput | undefined>(result.input);\n expectTypeOf<undefined>(result.output);\n expectTypeOf<undefined>(result.responseMetadata);\n }\n\n if (result.isSuccess) {\n expectTypeOf<\"success\">(result.status);\n expectTypeOf<false>(result.isPending);\n expectTypeOf<true>(result.isSuccess);\n expectTypeOf<TestInput | undefined>(result.input);\n expectTypeOf<TestOutput>(result.output);\n expectTypeOf<TestMetadata>(result.responseMetadata);\n }\n\n if (result.status === \"pending\") {\n expectTypeOf<TestInput | undefined>(result.input);\n expectTypeOf<true>(result.isPending);\n expectTypeOf<false>(result.isSuccess);\n expectTypeOf<undefined>(result.output);\n expectTypeOf<undefined>(result.responseMetadata);\n }\n\n if (result.status === \"success\") {\n expectTypeOf<TestInput | undefined>(result.input);\n expectTypeOf<false>(result.isPending);\n expectTypeOf<true>(result.isSuccess);\n expectTypeOf<TestOutput>(result.output);\n expectTypeOf<TestMetadata>(result.responseMetadata);\n }\n });\n\n test(\"should handle partial ToolSignature with only input specified\", () => {\n type TestInput = { id: number };\n\n const result = useToolInfo<{\n input: TestInput;\n }>();\n\n // Input is optional in both states — undefined while args haven't arrived\n // (pending) and for no-input tools (success).\n if (result.status === \"pending\") {\n expectTypeOf<TestInput | undefined>(result.input);\n }\n\n if (result.status === \"success\") {\n expectTypeOf<TestInput | undefined>(result.input);\n expectTypeOf<Record<string, unknown>>(result.output);\n expectTypeOf<Record<string, unknown>>(result.responseMetadata);\n }\n });\n\n test(\"should handle ToolSignature with only output specified\", () => {\n type TestOutput = { data: string[] };\n\n const result = useToolInfo<{\n output: TestOutput;\n }>();\n\n if (result.status === \"pending\") {\n expectTypeOf<Record<string, unknown> | undefined>(result.input);\n }\n\n if (result.status === \"success\") {\n expectTypeOf<Record<string, unknown> | undefined>(result.input);\n expectTypeOf<TestOutput>(result.output);\n }\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,37 +1,45 @@
1
- import { act, fireEvent, renderHook, waitFor } from "@testing-library/react";
1
+ import { act, renderHook, waitFor } from "@testing-library/react";
2
2
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
- import { McpAppAdaptor } from "../bridges/adaptors/mcp-app-adaptor.js";
4
- import { McpAppBridge } from "../bridges/mcp-app-bridge.js";
5
- import { SET_GLOBALS_EVENT_TYPE, SetGlobalsEvent, } from "../types.js";
6
- import { fireToolInputNotification, fireToolResultNotification, getMcpAppHostPostMessageMock, } from "./test/utils.js";
3
+ import { HostAdaptor } from "../bridges/adaptor.js";
4
+ import { McpAppBridge } from "../bridges/mcp-app/index.js";
5
+ import { fireToolInputNotification, fireToolResultNotification, getMcpAppHostPostMessageMock, MockResizeObserver, } from "./test/utils.js";
7
6
  import { useToolInfo } from "./use-tool-info.js";
8
7
  describe("useToolInfo", () => {
9
8
  describe("apps-sdk host", () => {
10
- let OpenaiMock;
11
9
  beforeEach(() => {
12
- OpenaiMock = {
13
- toolInput: { name: "pokemon", args: { name: "pikachu" } },
10
+ vi.stubGlobal("parent", { postMessage: getMcpAppHostPostMessageMock() });
11
+ vi.stubGlobal("openai", {
12
+ toolInput: null,
14
13
  toolOutput: null,
15
14
  toolResponseMetadata: null,
16
- };
17
- vi.stubGlobal("openai", OpenaiMock);
18
- vi.stubGlobal("skybridge", { hostType: "apps-sdk" });
15
+ });
16
+ vi.stubGlobal("skybridge", {});
17
+ vi.stubGlobal("ResizeObserver", MockResizeObserver);
19
18
  });
20
19
  afterEach(() => {
20
+ HostAdaptor.resetInstance();
21
21
  vi.unstubAllGlobals();
22
22
  vi.resetAllMocks();
23
+ McpAppBridge.resetInstance();
23
24
  });
24
- it("should return toolInput on initial mount window.openai", () => {
25
+ it("should return pending state with tool input from tool-input notification", async () => {
25
26
  const { result } = renderHook(() => useToolInfo());
26
- expect(result.current).toMatchObject({
27
- input: { name: "pokemon", args: { name: "pikachu" } },
28
- status: "pending",
29
- isIdle: false,
30
- isPending: true,
31
- isSuccess: false,
27
+ act(() => {
28
+ fireToolInputNotification({
29
+ name: "pokemon",
30
+ args: { name: "pikachu" },
31
+ });
32
+ });
33
+ await waitFor(() => {
34
+ expect(result.current).toMatchObject({
35
+ input: { name: "pokemon", args: { name: "pikachu" } },
36
+ status: "pending",
37
+ isPending: true,
38
+ isSuccess: false,
39
+ });
32
40
  });
33
41
  });
34
- it("should eventually return tool output and response metadata once tool call completes", async () => {
42
+ it("should return success state once tool-result notification arrives", async () => {
35
43
  const toolOutput = {
36
44
  name: "pikachu",
37
45
  color: "yellow",
@@ -40,21 +48,19 @@ describe("useToolInfo", () => {
40
48
  const toolResponseMetadata = { id: 12 };
41
49
  const { result } = renderHook(() => useToolInfo());
42
50
  act(() => {
43
- OpenaiMock.toolOutput = toolOutput;
44
- OpenaiMock.toolResponseMetadata = toolResponseMetadata;
45
- fireEvent(window, new SetGlobalsEvent(SET_GLOBALS_EVENT_TYPE, {
46
- detail: {
47
- globals: {
48
- toolOutput,
49
- toolResponseMetadata,
50
- },
51
- },
52
- }));
51
+ fireToolInputNotification({
52
+ name: "pokemon",
53
+ args: { name: "pikachu" },
54
+ });
55
+ fireToolResultNotification({
56
+ content: [{ type: "text", text: JSON.stringify(toolOutput) }],
57
+ structuredContent: toolOutput,
58
+ _meta: toolResponseMetadata,
59
+ });
53
60
  });
54
61
  await waitFor(() => {
55
62
  expect(result.current).toMatchObject({
56
63
  status: "success",
57
- isIdle: false,
58
64
  isPending: false,
59
65
  isSuccess: true,
60
66
  output: toolOutput,
@@ -66,23 +72,24 @@ describe("useToolInfo", () => {
66
72
  describe("mcp-app host", () => {
67
73
  beforeEach(() => {
68
74
  vi.stubGlobal("parent", { postMessage: getMcpAppHostPostMessageMock() });
69
- vi.stubGlobal("skybridge", { hostType: "mcp-app" });
75
+ vi.stubGlobal("skybridge", {});
76
+ vi.stubGlobal("openai", undefined);
77
+ vi.stubGlobal("ResizeObserver", MockResizeObserver);
70
78
  });
71
- afterEach(() => {
79
+ afterEach(async () => {
80
+ HostAdaptor.resetInstance();
72
81
  vi.unstubAllGlobals();
73
82
  vi.resetAllMocks();
74
83
  McpAppBridge.resetInstance();
75
- McpAppAdaptor.resetInstance();
76
84
  });
77
- it("should return idle state initially when tool input is not yet set", async () => {
85
+ it("should return pending state with undefined input before tool-input notification arrives", async () => {
78
86
  const { result } = renderHook(() => useToolInfo());
79
87
  await waitFor(() => {
80
88
  expect(result.current).toMatchObject({
81
- status: "idle",
82
- isIdle: true,
83
- isPending: false,
89
+ status: "pending",
90
+ isPending: true,
84
91
  isSuccess: false,
85
- input: null,
92
+ input: undefined,
86
93
  output: null,
87
94
  responseMetadata: null,
88
95
  });
@@ -96,7 +103,6 @@ describe("useToolInfo", () => {
96
103
  await waitFor(() => {
97
104
  expect(result.current).toMatchObject({
98
105
  status: "pending",
99
- isIdle: false,
100
106
  isPending: true,
101
107
  isSuccess: false,
102
108
  input: { name: "pokemon", query: "pikachu" },
@@ -116,7 +122,6 @@ describe("useToolInfo", () => {
116
122
  await waitFor(() => {
117
123
  expect(result.current).toMatchObject({
118
124
  status: "success",
119
- isIdle: false,
120
125
  isPending: false,
121
126
  isSuccess: true,
122
127
  input: { name: "pokemon", query: "pikachu" },
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-tool-info.test.js","sourceRoot":"","sources":["../../../src/web/hooks/use-tool-info.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { act, 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/index.js\";\nimport {\n fireToolInputNotification,\n fireToolResultNotification,\n getMcpAppHostPostMessageMock,\n MockResizeObserver,\n} from \"./test/utils.js\";\nimport { useToolInfo } from \"./use-tool-info.js\";\n\ndescribe(\"useToolInfo\", () => {\n describe(\"apps-sdk host\", () => {\n beforeEach(() => {\n vi.stubGlobal(\"parent\", { postMessage: getMcpAppHostPostMessageMock() });\n vi.stubGlobal(\"openai\", {\n toolInput: null,\n toolOutput: null,\n toolResponseMetadata: null,\n });\n vi.stubGlobal(\"skybridge\", {});\n vi.stubGlobal(\"ResizeObserver\", MockResizeObserver);\n });\n\n afterEach(() => {\n HostAdaptor.resetInstance();\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n McpAppBridge.resetInstance();\n });\n\n it(\"should return pending state with tool input from tool-input notification\", async () => {\n const { result } = renderHook(() => useToolInfo());\n\n act(() => {\n fireToolInputNotification({\n name: \"pokemon\",\n args: { name: \"pikachu\" },\n });\n });\n\n await waitFor(() => {\n expect(result.current).toMatchObject({\n input: { name: \"pokemon\", args: { name: \"pikachu\" } },\n status: \"pending\",\n isPending: true,\n isSuccess: false,\n });\n });\n });\n\n it(\"should return success state once tool-result notification arrives\", async () => {\n const toolOutput = {\n name: \"pikachu\",\n color: \"yellow\",\n description:\n \"When several of these POKéMON gather, their\\felectricity could build and cause lightning storms.\",\n };\n const toolResponseMetadata = { id: 12 };\n const { result } = renderHook(() => useToolInfo());\n\n act(() => {\n fireToolInputNotification({\n name: \"pokemon\",\n args: { name: \"pikachu\" },\n });\n fireToolResultNotification({\n content: [{ type: \"text\", text: JSON.stringify(toolOutput) }],\n structuredContent: toolOutput,\n _meta: toolResponseMetadata,\n });\n });\n\n await waitFor(() => {\n expect(result.current).toMatchObject({\n status: \"success\",\n isPending: false,\n isSuccess: true,\n output: toolOutput,\n responseMetadata: toolResponseMetadata,\n });\n });\n });\n });\n\n describe(\"mcp-app host\", () => {\n beforeEach(() => {\n vi.stubGlobal(\"parent\", { postMessage: getMcpAppHostPostMessageMock() });\n vi.stubGlobal(\"skybridge\", {});\n vi.stubGlobal(\"openai\", undefined);\n vi.stubGlobal(\"ResizeObserver\", MockResizeObserver);\n });\n\n afterEach(async () => {\n HostAdaptor.resetInstance();\n vi.unstubAllGlobals();\n vi.resetAllMocks();\n McpAppBridge.resetInstance();\n });\n\n it(\"should return pending state with undefined input before tool-input notification arrives\", async () => {\n const { result } = renderHook(() => useToolInfo());\n\n await waitFor(() => {\n expect(result.current).toMatchObject({\n status: \"pending\",\n isPending: true,\n isSuccess: false,\n input: undefined,\n output: null,\n responseMetadata: null,\n });\n });\n });\n\n it(\"should return pending state with tool input from tool-input notification\", async () => {\n const { result } = renderHook(() => useToolInfo());\n\n act(() => {\n fireToolInputNotification({ name: \"pokemon\", query: \"pikachu\" });\n });\n\n await waitFor(() => {\n expect(result.current).toMatchObject({\n status: \"pending\",\n isPending: true,\n isSuccess: false,\n input: { name: \"pokemon\", query: \"pikachu\" },\n });\n });\n });\n\n it(\"should return success state with output from tool-result notification\", async () => {\n const { result } = renderHook(() => useToolInfo());\n\n act(() => {\n fireToolInputNotification({ name: \"pokemon\", query: \"pikachu\" });\n fireToolResultNotification({\n content: [{ type: \"text\", text: \"Pikachu data\" }],\n structuredContent: { name: \"pikachu\", color: \"yellow\" },\n _meta: { requestId: \"123\" },\n });\n });\n\n await waitFor(() => {\n expect(result.current).toMatchObject({\n status: \"success\",\n isPending: false,\n isSuccess: true,\n input: { name: \"pokemon\", query: \"pikachu\" },\n output: { name: \"pikachu\", color: \"yellow\" },\n responseMetadata: { requestId: \"123\" },\n });\n });\n });\n });\n});\n"]}
@@ -1,6 +1,7 @@
1
- import type { UserAgent } from "../types.js";
1
+ import { type Theme, type UserAgent } from "../bridges/index.js";
2
2
  export type UserState = {
3
3
  locale: string;
4
+ theme: Theme;
4
5
  userAgent: UserAgent;
5
6
  };
6
7
  /**
@@ -9,10 +10,12 @@ export type UserState = {
9
10
  *
10
11
  * @example
11
12
  * ```tsx
12
- * const { locale, userAgent } = useUser();
13
+ * const { locale, theme, userAgent } = useUser();
13
14
  *
14
15
  * // Access device type
15
16
  * const isMobile = userAgent.device.type === "mobile";
16
17
  * ```
18
+ *
19
+ * @see https://docs.skybridge.tech/api-reference/use-user
17
20
  */
18
21
  export declare function useUser(): UserState;
@@ -0,0 +1,38 @@
1
+ import { useHostContext, } from "../bridges/index.js";
2
+ const DEFAULT_LOCALE = "en-US";
3
+ /**
4
+ * Normalizes a locale string to canonical BCP 47 format using {@link Intl.Locale}.
5
+ *
6
+ * Handles underscored identifiers returned by the ChatGPT mobile app (e.g. "fr_FR" → "fr-FR"),
7
+ * incorrect casing (e.g. "en-us" → "en-US"), and complex subtags (e.g. "zh_Hans_CN" → "zh-Hans-CN").
8
+ * Falls back to "en-US" if the locale is invalid.
9
+ */
10
+ function normalizeLocale(locale) {
11
+ try {
12
+ return new Intl.Locale(locale.replace(/_/g, "-")).toString();
13
+ }
14
+ catch {
15
+ return DEFAULT_LOCALE;
16
+ }
17
+ }
18
+ /**
19
+ * Hook for accessing session-stable user information.
20
+ * These values are set once at initialization and do not change during the session.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * const { locale, theme, userAgent } = useUser();
25
+ *
26
+ * // Access device type
27
+ * const isMobile = userAgent.device.type === "mobile";
28
+ * ```
29
+ *
30
+ * @see https://docs.skybridge.tech/api-reference/use-user
31
+ */
32
+ export function useUser() {
33
+ const rawLocale = useHostContext("locale");
34
+ const theme = useHostContext("theme");
35
+ const userAgent = useHostContext("userAgent");
36
+ return { locale: normalizeLocale(rawLocale), theme, userAgent };
37
+ }
38
+ //# sourceMappingURL=use-user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-user.js","sourceRoot":"","sources":["../../../src/web/hooks/use-user.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,cAAc,GACf,MAAM,qBAAqB,CAAC;AAQ7B,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B;;;;;;GAMG;AACH,SAAS,eAAe,CAAC,MAAc;IACrC,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,OAAO;IACrB,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAE9C,OAAO,EAAE,MAAM,EAAE,eAAe,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAClE,CAAC","sourcesContent":["import {\n type Theme,\n type UserAgent,\n useHostContext,\n} from \"../bridges/index.js\";\n\nexport type UserState = {\n locale: string;\n theme: Theme;\n userAgent: UserAgent;\n};\n\nconst DEFAULT_LOCALE = \"en-US\";\n\n/**\n * Normalizes a locale string to canonical BCP 47 format using {@link Intl.Locale}.\n *\n * Handles underscored identifiers returned by the ChatGPT mobile app (e.g. \"fr_FR\" → \"fr-FR\"),\n * incorrect casing (e.g. \"en-us\" → \"en-US\"), and complex subtags (e.g. \"zh_Hans_CN\" → \"zh-Hans-CN\").\n * Falls back to \"en-US\" if the locale is invalid.\n */\nfunction normalizeLocale(locale: string): string {\n try {\n return new Intl.Locale(locale.replace(/_/g, \"-\")).toString();\n } catch {\n return DEFAULT_LOCALE;\n }\n}\n\n/**\n * Hook for accessing session-stable user information.\n * These values are set once at initialization and do not change during the session.\n *\n * @example\n * ```tsx\n * const { locale, theme, userAgent } = useUser();\n *\n * // Access device type\n * const isMobile = userAgent.device.type === \"mobile\";\n * ```\n *\n * @see https://docs.skybridge.tech/api-reference/use-user\n */\nexport function useUser(): UserState {\n const rawLocale = useHostContext(\"locale\");\n const theme = useHostContext(\"theme\");\n const userAgent = useHostContext(\"userAgent\");\n\n return { locale: normalizeLocale(rawLocale), theme, userAgent };\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};