skybridge 0.0.0-dev.e97960f → 0.0.0-dev.e99ee17

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 (439) hide show
  1. package/README.md +126 -124
  2. package/dist/cli/build-helpers.d.ts +11 -0
  3. package/dist/cli/build-helpers.js +107 -0
  4. package/dist/cli/build-helpers.js.map +1 -0
  5. package/dist/cli/build-helpers.test.js +132 -0
  6. package/dist/cli/build-helpers.test.js.map +1 -0
  7. package/dist/cli/build-steps.d.ts +2 -0
  8. package/dist/cli/build-steps.js +73 -0
  9. package/dist/cli/build-steps.js.map +1 -0
  10. package/dist/cli/build-steps.test.js +52 -0
  11. package/dist/cli/build-steps.test.js.map +1 -0
  12. package/dist/cli/detect-port.d.ts +2 -2
  13. package/dist/cli/detect-port.js +8 -20
  14. package/dist/cli/detect-port.js.map +1 -1
  15. package/dist/cli/header.d.ts +1 -1
  16. package/dist/cli/resolve-skybridge-config.d.ts +5 -0
  17. package/dist/cli/resolve-skybridge-config.js +18 -0
  18. package/dist/cli/resolve-skybridge-config.js.map +1 -0
  19. package/dist/cli/run-plain.d.ts +18 -0
  20. package/dist/cli/run-plain.js +90 -0
  21. package/dist/cli/run-plain.js.map +1 -0
  22. package/dist/cli/telemetry.js +2 -0
  23. package/dist/cli/telemetry.js.map +1 -1
  24. package/dist/cli/use-execute-steps.d.ts +1 -1
  25. package/dist/cli/use-nodemon.d.ts +25 -1
  26. package/dist/cli/use-nodemon.js +96 -63
  27. package/dist/cli/use-nodemon.js.map +1 -1
  28. package/dist/cli/use-typescript-check.d.ts +8 -2
  29. package/dist/cli/use-typescript-check.js +71 -68
  30. package/dist/cli/use-typescript-check.js.map +1 -1
  31. package/dist/commands/build.d.ts +0 -3
  32. package/dist/commands/build.js +2 -73
  33. package/dist/commands/build.js.map +1 -1
  34. package/dist/commands/create.d.ts +9 -0
  35. package/dist/commands/create.js +30 -0
  36. package/dist/commands/create.js.map +1 -0
  37. package/dist/commands/dev.d.ts +1 -0
  38. package/dist/commands/dev.js +51 -3
  39. package/dist/commands/dev.js.map +1 -1
  40. package/dist/commands/start.js +7 -1
  41. package/dist/commands/start.js.map +1 -1
  42. package/dist/context-warnings.d.ts +5 -0
  43. package/dist/context-warnings.js +31 -0
  44. package/dist/context-warnings.js.map +1 -0
  45. package/dist/context-warnings.test.js +28 -0
  46. package/dist/context-warnings.test.js.map +1 -0
  47. package/dist/server/app.d.ts +194 -0
  48. package/dist/server/app.js +266 -0
  49. package/dist/server/app.js.map +1 -0
  50. package/dist/server/app.test.js +97 -0
  51. package/dist/server/app.test.js.map +1 -0
  52. package/dist/server/asset-base-url-transform-plugin.d.ts +1 -0
  53. package/dist/server/asset-base-url-transform-plugin.js +16 -1
  54. package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
  55. package/dist/server/asset-base-url-transform-plugin.test.js +51 -1
  56. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
  57. package/dist/server/auth/discovery.d.ts +33 -0
  58. package/dist/server/auth/discovery.js +56 -0
  59. package/dist/server/auth/discovery.js.map +1 -0
  60. package/dist/server/auth/discovery.test.d.ts +1 -0
  61. package/dist/server/auth/discovery.test.js +93 -0
  62. package/dist/server/auth/discovery.test.js.map +1 -0
  63. package/dist/server/auth/index.d.ts +48 -0
  64. package/dist/server/auth/index.js +2 -0
  65. package/dist/server/auth/index.js.map +1 -0
  66. package/dist/server/auth/providers/auth0.d.ts +40 -0
  67. package/dist/server/auth/providers/auth0.js +36 -0
  68. package/dist/server/auth/providers/auth0.js.map +1 -0
  69. package/dist/server/auth/providers/auth0.test.d.ts +1 -0
  70. package/dist/server/auth/providers/auth0.test.js +50 -0
  71. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  72. package/dist/server/auth/providers/authplane.d.ts +49 -0
  73. package/dist/server/auth/providers/authplane.js +57 -0
  74. package/dist/server/auth/providers/authplane.js.map +1 -0
  75. package/dist/server/auth/providers/authplane.test.d.ts +1 -0
  76. package/dist/server/auth/providers/authplane.test.js +143 -0
  77. package/dist/server/auth/providers/authplane.test.js.map +1 -0
  78. package/dist/server/auth/providers/clerk.d.ts +51 -0
  79. package/dist/server/auth/providers/clerk.js +19 -0
  80. package/dist/server/auth/providers/clerk.js.map +1 -0
  81. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  82. package/dist/server/auth/providers/clerk.test.js +30 -0
  83. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  84. package/dist/server/auth/providers/custom.d.ts +42 -0
  85. package/dist/server/auth/providers/custom.js +59 -0
  86. package/dist/server/auth/providers/custom.js.map +1 -0
  87. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  88. package/dist/server/auth/providers/custom.test.js +161 -0
  89. package/dist/server/auth/providers/custom.test.js.map +1 -0
  90. package/dist/server/auth/providers/descope.d.ts +44 -0
  91. package/dist/server/auth/providers/descope.js +44 -0
  92. package/dist/server/auth/providers/descope.js.map +1 -0
  93. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  94. package/dist/server/auth/providers/descope.test.js +62 -0
  95. package/dist/server/auth/providers/descope.test.js.map +1 -0
  96. package/dist/server/auth/providers/shared.d.ts +2 -0
  97. package/dist/server/auth/providers/shared.js +6 -0
  98. package/dist/server/auth/providers/shared.js.map +1 -0
  99. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  100. package/dist/server/auth/providers/shared.test.js +10 -0
  101. package/dist/server/auth/providers/shared.test.js.map +1 -0
  102. package/dist/server/auth/providers/stytch.d.ts +25 -0
  103. package/dist/server/auth/providers/stytch.js +16 -0
  104. package/dist/server/auth/providers/stytch.js.map +1 -0
  105. package/dist/server/auth/providers/verify-spy.d.ts +12 -0
  106. package/dist/server/auth/providers/verify-spy.js +21 -0
  107. package/dist/server/auth/providers/verify-spy.js.map +1 -0
  108. package/dist/server/auth/providers/workos.d.ts +34 -0
  109. package/dist/server/auth/providers/workos.js +16 -0
  110. package/dist/server/auth/providers/workos.js.map +1 -0
  111. package/dist/server/auth/security-schemes.d.ts +23 -0
  112. package/dist/server/auth/security-schemes.js +64 -0
  113. package/dist/server/auth/security-schemes.js.map +1 -0
  114. package/dist/server/auth/security-schemes.test.d.ts +1 -0
  115. package/dist/server/auth/security-schemes.test.js +99 -0
  116. package/dist/server/auth/security-schemes.test.js.map +1 -0
  117. package/dist/server/auth/setup.d.ts +6 -0
  118. package/dist/server/auth/setup.js +91 -0
  119. package/dist/server/auth/setup.js.map +1 -0
  120. package/dist/server/auth/setup.test.d.ts +1 -0
  121. package/dist/server/auth/setup.test.js +514 -0
  122. package/dist/server/auth/setup.test.js.map +1 -0
  123. package/dist/server/auth/verify.d.ts +48 -0
  124. package/dist/server/auth/verify.js +62 -0
  125. package/dist/server/auth/verify.js.map +1 -0
  126. package/dist/server/auth/verify.test.d.ts +1 -0
  127. package/dist/server/auth/verify.test.js +165 -0
  128. package/dist/server/auth/verify.test.js.map +1 -0
  129. package/dist/server/auth-extra.test-d.js +130 -0
  130. package/dist/server/auth-extra.test-d.js.map +1 -0
  131. package/dist/server/auth.d.ts +57 -0
  132. package/dist/server/auth.js +27 -0
  133. package/dist/server/auth.js.map +1 -0
  134. package/dist/server/build-manifest.test.d.ts +1 -0
  135. package/dist/server/build-manifest.test.js +28 -0
  136. package/dist/server/build-manifest.test.js.map +1 -0
  137. package/dist/server/content-helpers.d.ts +41 -1
  138. package/dist/server/content-helpers.js +33 -0
  139. package/dist/server/content-helpers.js.map +1 -1
  140. package/dist/server/events.d.ts +113 -0
  141. package/dist/server/events.js +318 -0
  142. package/dist/server/events.js.map +1 -0
  143. package/dist/server/events.test.d.ts +1 -0
  144. package/dist/server/events.test.js +172 -0
  145. package/dist/server/events.test.js.map +1 -0
  146. package/dist/server/express.d.ts +23 -3
  147. package/dist/server/express.js +43 -32
  148. package/dist/server/express.js.map +1 -1
  149. package/dist/server/express.test.js +269 -90
  150. package/dist/server/express.test.js.map +1 -1
  151. package/dist/server/file-ref.d.ts +21 -1
  152. package/dist/server/file-ref.js +20 -1
  153. package/dist/server/file-ref.js.map +1 -1
  154. package/dist/server/form-input.d.ts +120 -0
  155. package/dist/server/form-input.js +89 -0
  156. package/dist/server/form-input.js.map +1 -0
  157. package/dist/server/host.d.ts +2 -0
  158. package/dist/server/host.js +11 -0
  159. package/dist/server/host.js.map +1 -0
  160. package/dist/server/host.test.d.ts +1 -0
  161. package/dist/server/host.test.js +13 -0
  162. package/dist/server/host.test.js.map +1 -0
  163. package/dist/server/index.d.ts +19 -2
  164. package/dist/server/index.js +16 -1
  165. package/dist/server/index.js.map +1 -1
  166. package/dist/server/mcp-errors.test.d.ts +1 -0
  167. package/dist/server/mcp-errors.test.js +41 -0
  168. package/dist/server/mcp-errors.test.js.map +1 -0
  169. package/dist/server/middleware.d.ts +51 -13
  170. package/dist/server/middleware.js +33 -0
  171. package/dist/server/middleware.js.map +1 -1
  172. package/dist/server/middleware.test-d.js +1 -1
  173. package/dist/server/middleware.test-d.js.map +1 -1
  174. package/dist/server/middleware.test.js +242 -134
  175. package/dist/server/middleware.test.js.map +1 -1
  176. package/dist/server/register-tool.test.d.ts +1 -0
  177. package/dist/server/register-tool.test.js +230 -0
  178. package/dist/server/register-tool.test.js.map +1 -0
  179. package/dist/server/requestOrigin.d.ts +7 -0
  180. package/dist/server/requestOrigin.js +25 -0
  181. package/dist/server/requestOrigin.js.map +1 -0
  182. package/dist/server/server.d.ts +532 -67
  183. package/dist/server/server.js +646 -315
  184. package/dist/server/server.js.map +1 -1
  185. package/dist/server/skills-integration.test.d.ts +1 -0
  186. package/dist/server/skills-integration.test.js +86 -0
  187. package/dist/server/skills-integration.test.js.map +1 -0
  188. package/dist/server/skills.d.ts +27 -0
  189. package/dist/server/skills.js +188 -0
  190. package/dist/server/skills.js.map +1 -0
  191. package/dist/server/skills.test.d.ts +1 -0
  192. package/dist/server/skills.test.js +243 -0
  193. package/dist/server/skills.test.js.map +1 -0
  194. package/dist/server/templateHelper.d.ts +0 -3
  195. package/dist/server/templateHelper.js.map +1 -1
  196. package/dist/server/templates.generated.js +4 -8
  197. package/dist/server/templates.generated.js.map +1 -1
  198. package/dist/server/tool-extra.test.d.ts +1 -0
  199. package/dist/server/tool-extra.test.js +167 -0
  200. package/dist/server/tool-extra.test.js.map +1 -0
  201. package/dist/server/view-name.test-d.d.ts +1 -0
  202. package/dist/server/view-name.test-d.js +8 -0
  203. package/dist/server/view-name.test-d.js.map +1 -0
  204. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  205. package/dist/server/view-resource-resolution.test.js +176 -0
  206. package/dist/server/view-resource-resolution.test.js.map +1 -0
  207. package/dist/server/viewsDevServer.js +4 -1
  208. package/dist/server/viewsDevServer.js.map +1 -1
  209. package/dist/test/utils.d.ts +9 -11
  210. package/dist/test/utils.js +220 -201
  211. package/dist/test/utils.js.map +1 -1
  212. package/dist/test/view.test.js +123 -106
  213. package/dist/test/view.test.js.map +1 -1
  214. package/dist/views/index.d.ts +10 -0
  215. package/dist/views/index.js +3 -0
  216. package/dist/views/index.js.map +1 -0
  217. package/dist/{web/plugin → views}/scan-views.js +1 -1
  218. package/dist/views/scan-views.js.map +1 -0
  219. package/dist/views/scan-views.test.d.ts +1 -0
  220. package/dist/views/scan-views.test.js.map +1 -0
  221. package/dist/views/validate-view.d.ts +1 -0
  222. package/dist/{web/plugin → views}/validate-view.js +2 -2
  223. package/dist/views/validate-view.js.map +1 -0
  224. package/dist/views/validate-view.test.d.ts +1 -0
  225. package/dist/views/validate-view.test.js.map +1 -0
  226. package/dist/web/bridges/adaptor.d.ts +62 -0
  227. package/dist/web/bridges/adaptor.js +471 -0
  228. package/dist/web/bridges/adaptor.js.map +1 -0
  229. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  230. package/dist/web/bridges/adaptor.test.js +264 -0
  231. package/dist/web/bridges/adaptor.test.js.map +1 -0
  232. package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -1
  233. package/dist/web/bridges/apps-sdk/bridge.js +15 -3
  234. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  235. package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
  236. package/dist/web/bridges/apps-sdk/index.js +0 -1
  237. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  238. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
  239. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
  240. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  241. package/dist/web/bridges/get-adaptor.d.ts +7 -0
  242. package/dist/web/bridges/get-adaptor.js +9 -7
  243. package/dist/web/bridges/get-adaptor.js.map +1 -1
  244. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  245. package/dist/web/bridges/get-adaptor.test.js +32 -0
  246. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  247. package/dist/web/bridges/mcp-app/bridge.d.ts +15 -2
  248. package/dist/web/bridges/mcp-app/bridge.js +80 -7
  249. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  250. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  251. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  252. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  253. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  254. package/dist/web/bridges/mcp-app/index.js +0 -1
  255. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  256. package/dist/web/bridges/mcp-app/types.d.ts +19 -2
  257. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  258. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +13 -1
  259. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +12 -0
  260. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  261. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -1
  262. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  263. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  264. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  265. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  266. package/dist/web/bridges/types.d.ts +160 -5
  267. package/dist/web/bridges/types.js +14 -1
  268. package/dist/web/bridges/types.js.map +1 -1
  269. package/dist/web/bridges/types.test.d.ts +1 -0
  270. package/dist/web/bridges/types.test.js +19 -0
  271. package/dist/web/bridges/types.test.js.map +1 -0
  272. package/dist/web/bridges/use-host-context.d.ts +5 -0
  273. package/dist/web/bridges/use-host-context.js +5 -0
  274. package/dist/web/bridges/use-host-context.js.map +1 -1
  275. package/dist/web/components/modal-provider.d.ts +1 -1
  276. package/dist/web/components/modal-provider.js +4 -3
  277. package/dist/web/components/modal-provider.js.map +1 -1
  278. package/dist/web/create-store.d.ts +26 -0
  279. package/dist/web/create-store.js +26 -0
  280. package/dist/web/create-store.js.map +1 -1
  281. package/dist/web/create-store.test.js +10 -7
  282. package/dist/web/create-store.test.js.map +1 -1
  283. package/dist/web/data-llm.d.ts +34 -1
  284. package/dist/web/data-llm.js +31 -2
  285. package/dist/web/data-llm.js.map +1 -1
  286. package/dist/web/data-llm.test.js +26 -7
  287. package/dist/web/data-llm.test.js.map +1 -1
  288. package/dist/web/generate-helpers.d.ts +25 -19
  289. package/dist/web/generate-helpers.js +23 -17
  290. package/dist/web/generate-helpers.js.map +1 -1
  291. package/dist/web/generate-helpers.test-d.js +7 -5
  292. package/dist/web/generate-helpers.test-d.js.map +1 -1
  293. package/dist/web/generate-helpers.test.js +2 -2
  294. package/dist/web/generate-helpers.test.js.map +1 -1
  295. package/dist/web/hooks/index.d.ts +8 -1
  296. package/dist/web/hooks/index.js +8 -1
  297. package/dist/web/hooks/index.js.map +1 -1
  298. package/dist/web/hooks/openai-extensions.test.d.ts +1 -0
  299. package/dist/web/hooks/openai-extensions.test.js +107 -0
  300. package/dist/web/hooks/openai-extensions.test.js.map +1 -0
  301. package/dist/web/hooks/test/utils.d.ts +7 -2
  302. package/dist/web/hooks/test/utils.js +14 -3
  303. package/dist/web/hooks/test/utils.js.map +1 -1
  304. package/dist/web/hooks/use-call-tool.d.ts +47 -2
  305. package/dist/web/hooks/use-call-tool.js +43 -10
  306. package/dist/web/hooks/use-call-tool.js.map +1 -1
  307. package/dist/web/hooks/use-call-tool.test.js +75 -25
  308. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  309. package/dist/web/hooks/use-deep-link.d.ts +22 -0
  310. package/dist/web/hooks/use-deep-link.js +34 -0
  311. package/dist/web/hooks/use-deep-link.js.map +1 -0
  312. package/dist/web/hooks/use-display-mode.d.ts +20 -0
  313. package/dist/web/hooks/use-display-mode.js +20 -0
  314. package/dist/web/hooks/use-display-mode.js.map +1 -1
  315. package/dist/web/hooks/use-display-mode.test.js +57 -21
  316. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  317. package/dist/web/hooks/use-download.d.ts +3 -0
  318. package/dist/web/hooks/use-download.js +7 -0
  319. package/dist/web/hooks/use-download.js.map +1 -0
  320. package/dist/web/hooks/use-download.test.d.ts +1 -0
  321. package/dist/web/hooks/use-download.test.js +103 -0
  322. package/dist/web/hooks/use-download.test.js.map +1 -0
  323. package/dist/web/hooks/use-file-resource.d.ts +37 -0
  324. package/dist/web/hooks/use-file-resource.js +98 -0
  325. package/dist/web/hooks/use-file-resource.js.map +1 -0
  326. package/dist/web/hooks/use-file-resource.test.d.ts +1 -0
  327. package/dist/web/hooks/use-file-resource.test.js +65 -0
  328. package/dist/web/hooks/use-file-resource.test.js.map +1 -0
  329. package/dist/web/hooks/use-files.d.ts +32 -0
  330. package/dist/web/hooks/use-files.js +32 -0
  331. package/dist/web/hooks/use-files.js.map +1 -1
  332. package/dist/web/hooks/use-files.test.js +11 -3
  333. package/dist/web/hooks/use-files.test.js.map +1 -1
  334. package/dist/web/hooks/use-host.d.ts +44 -0
  335. package/dist/web/hooks/use-host.js +45 -0
  336. package/dist/web/hooks/use-host.js.map +1 -0
  337. package/dist/web/hooks/use-host.test.d.ts +1 -0
  338. package/dist/web/hooks/use-host.test.js +59 -0
  339. package/dist/web/hooks/use-host.test.js.map +1 -0
  340. package/dist/web/hooks/use-model-context.d.ts +44 -0
  341. package/dist/web/hooks/use-model-context.js +63 -0
  342. package/dist/web/hooks/use-model-context.js.map +1 -0
  343. package/dist/web/hooks/use-open-external.d.ts +17 -0
  344. package/dist/web/hooks/use-open-external.js +16 -0
  345. package/dist/web/hooks/use-open-external.js.map +1 -1
  346. package/dist/web/hooks/use-open-external.test.js +15 -5
  347. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  348. package/dist/web/hooks/use-open-file.d.ts +20 -0
  349. package/dist/web/hooks/use-open-file.js +25 -0
  350. package/dist/web/hooks/use-open-file.js.map +1 -0
  351. package/dist/web/hooks/use-register-view-tool.d.ts +37 -0
  352. package/dist/web/hooks/use-register-view-tool.js +50 -0
  353. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  354. package/dist/web/hooks/use-request-close.d.ts +14 -0
  355. package/dist/web/hooks/use-request-close.js +13 -0
  356. package/dist/web/hooks/use-request-close.js.map +1 -1
  357. package/dist/web/hooks/use-request-close.test.js +35 -40
  358. package/dist/web/hooks/use-request-close.test.js.map +1 -1
  359. package/dist/web/hooks/use-request-modal.d.ts +16 -1
  360. package/dist/web/hooks/use-request-modal.js +16 -1
  361. package/dist/web/hooks/use-request-modal.js.map +1 -1
  362. package/dist/web/hooks/use-request-modal.test.js +11 -1
  363. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  364. package/dist/web/hooks/use-request-size.d.ts +17 -0
  365. package/dist/web/hooks/use-request-size.js +16 -0
  366. package/dist/web/hooks/use-request-size.js.map +1 -1
  367. package/dist/web/hooks/use-request-size.test.js +35 -53
  368. package/dist/web/hooks/use-request-size.test.js.map +1 -1
  369. package/dist/web/hooks/use-send-follow-up-message.d.ts +25 -2
  370. package/dist/web/hooks/use-send-follow-up-message.js +23 -0
  371. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  372. package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
  373. package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
  374. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
  375. package/dist/web/hooks/use-set-open-in-app-url.test.js +26 -12
  376. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  377. package/dist/web/hooks/use-tool-info.d.ts +46 -14
  378. package/dist/web/hooks/use-tool-info.js +29 -7
  379. package/dist/web/hooks/use-tool-info.js.map +1 -1
  380. package/dist/web/hooks/use-tool-info.test-d.js +11 -34
  381. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  382. package/dist/web/hooks/use-tool-info.test.js +42 -37
  383. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  384. package/dist/web/hooks/use-user.d.ts +5 -2
  385. package/dist/web/hooks/use-user.js +6 -3
  386. package/dist/web/hooks/use-user.js.map +1 -1
  387. package/dist/web/hooks/use-user.test.js +85 -37
  388. package/dist/web/hooks/use-user.test.js.map +1 -1
  389. package/dist/web/hooks/use-view-state.d.ts +21 -0
  390. package/dist/web/hooks/use-view-state.js +19 -9
  391. package/dist/web/hooks/use-view-state.js.map +1 -1
  392. package/dist/web/hooks/use-view-state.test.js +39 -4
  393. package/dist/web/hooks/use-view-state.test.js.map +1 -1
  394. package/dist/web/hooks/use-viewport.d.ts +20 -0
  395. package/dist/web/hooks/use-viewport.js +21 -0
  396. package/dist/web/hooks/use-viewport.js.map +1 -0
  397. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  398. package/dist/web/hooks/use-viewport.test.js +109 -0
  399. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  400. package/dist/web/mount-view.d.ts +20 -0
  401. package/dist/web/mount-view.js +22 -6
  402. package/dist/web/mount-view.js.map +1 -1
  403. package/dist/web/types.d.ts +4 -0
  404. package/dist/web/types.js.map +1 -1
  405. package/package.json +35 -23
  406. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -26
  407. package/dist/web/bridges/apps-sdk/adaptor.js +0 -102
  408. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  409. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -50
  410. package/dist/web/bridges/mcp-app/adaptor.js +0 -271
  411. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
  412. package/dist/web/hooks/use-layout.d.ts +0 -22
  413. package/dist/web/hooks/use-layout.js +0 -23
  414. package/dist/web/hooks/use-layout.js.map +0 -1
  415. package/dist/web/hooks/use-layout.test.js +0 -96
  416. package/dist/web/hooks/use-layout.test.js.map +0 -1
  417. package/dist/web/plugin/data-llm.test.js +0 -81
  418. package/dist/web/plugin/data-llm.test.js.map +0 -1
  419. package/dist/web/plugin/plugin.d.ts +0 -5
  420. package/dist/web/plugin/plugin.js +0 -163
  421. package/dist/web/plugin/plugin.js.map +0 -1
  422. package/dist/web/plugin/scan-views.js.map +0 -1
  423. package/dist/web/plugin/scan-views.test.js.map +0 -1
  424. package/dist/web/plugin/transform-data-llm.d.ts +0 -12
  425. package/dist/web/plugin/transform-data-llm.js +0 -96
  426. package/dist/web/plugin/transform-data-llm.js.map +0 -1
  427. package/dist/web/plugin/transform-data-llm.test.js +0 -81
  428. package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
  429. package/dist/web/plugin/validate-view.d.ts +0 -1
  430. package/dist/web/plugin/validate-view.js.map +0 -1
  431. package/dist/web/plugin/validate-view.test.js.map +0 -1
  432. /package/dist/{web/hooks/use-layout.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  433. /package/dist/{web/plugin/data-llm.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  434. /package/dist/{web/plugin/scan-views.test.d.ts → context-warnings.test.d.ts} +0 -0
  435. /package/dist/{web/plugin/transform-data-llm.test.d.ts → server/app.test.d.ts} +0 -0
  436. /package/dist/{web/plugin/validate-view.test.d.ts → server/auth-extra.test-d.d.ts} +0 -0
  437. /package/dist/{web/plugin → views}/scan-views.d.ts +0 -0
  438. /package/dist/{web/plugin → views}/scan-views.test.js +0 -0
  439. /package/dist/{web/plugin → views}/validate-view.test.js +0 -0
@@ -20,7 +20,7 @@ export function scanViewsSync(viewsDir) {
20
20
  const invalid = [];
21
21
  for (const candidate of candidates) {
22
22
  const code = readFileSync(candidate.filePath, "utf-8");
23
- if (hasDefaultExport(code, candidate.filePath)) {
23
+ if (hasDefaultExport(code)) {
24
24
  valid.push(candidate);
25
25
  }
26
26
  else {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-views.js","sourceRoot":"","sources":["../../src/views/scan-views.ts"],"names":[],"mappings":"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","sourcesContent":["import { globSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, isAbsolute, join, parse, resolve } from \"node:path\";\nimport { hasDefaultExport } from \"./validate-view.js\";\n\nexport interface DiscoveredView {\n name: string;\n filePath: string;\n}\n\nexport interface InvalidView {\n filePath: string;\n}\n\nexport function scanViewsSync(viewsDir: string): {\n valid: DiscoveredView[];\n invalid: InvalidView[];\n} {\n const flatPattern = resolve(viewsDir, \"*.{tsx,jsx}\");\n const dirPattern = resolve(viewsDir, \"*/index.{tsx,jsx}\");\n\n const flatFiles = globSync(flatPattern).map((file) => ({\n name: parse(file).name,\n filePath: file,\n }));\n\n const dirFiles = globSync(dirPattern).map((file) => ({\n name: basename(dirname(file)),\n filePath: file,\n }));\n\n // A barrel file like `views/foo/index.tsx` (no default export) must not\n // falsely collide with a sibling `views/foo.tsx`. Drop top-level `index`\n // before splitting valid vs invalid.\n const candidates = [...flatFiles, ...dirFiles].filter(\n (v) => v.name !== \"index\",\n );\n\n const valid: DiscoveredView[] = [];\n const invalid: InvalidView[] = [];\n for (const candidate of candidates) {\n const code = readFileSync(candidate.filePath, \"utf-8\");\n if (hasDefaultExport(code)) {\n valid.push(candidate);\n } else {\n invalid.push({\n filePath: candidate.filePath,\n });\n }\n }\n\n return { valid, invalid };\n}\n\nexport function assertUniqueViewNames(views: DiscoveredView[]): void {\n const nameMap = new Map<string, string[]>();\n for (const view of views) {\n const paths = nameMap.get(view.name) ?? [];\n paths.push(view.filePath);\n nameMap.set(view.name, paths);\n }\n\n for (const [name, paths] of nameMap) {\n if (paths.length > 1) {\n throw new Error(\n `skybridge: duplicate view name \"${name}\" resolved from:\\n - ${paths.join(\"\\n - \")}\\nRename one of the files to avoid the conflict.`,\n );\n }\n }\n}\n\nexport function discoverViewsSync(viewsDir: string): DiscoveredView[] {\n const { valid } = scanViewsSync(viewsDir);\n assertUniqueViewNames(valid);\n return valid;\n}\n\nexport function generateViewsDts(views: DiscoveredView[]): string {\n const entries = views.map((v) => ` \"${v.name}\": true;`).join(\"\\n\");\n return [\n \"export {};\",\n \"\",\n 'declare module \"skybridge/server\" {',\n \" interface ViewNameRegistry {\",\n entries,\n \" }\",\n \"}\",\n \"\",\n ].join(\"\\n\");\n}\n\nexport function writeViewsDts(\n projectRoot: string,\n views: DiscoveredView[],\n): void {\n const dir = join(projectRoot, \".skybridge\");\n mkdirSync(dir, { recursive: true });\n\n const filePath = join(dir, \"views.d.ts\");\n const content = generateViewsDts(views);\n\n try {\n const existing = readFileSync(filePath, \"utf-8\");\n if (existing === content) {\n return;\n }\n } catch {\n // File doesn't exist yet\n }\n\n writeFileSync(filePath, content, \"utf-8\");\n}\n\nexport function scanAndWriteViewsDts(\n projectRoot?: string,\n viewsDir?: string,\n): void {\n const root = projectRoot ?? process.cwd();\n const rawDir = viewsDir ?? \"src/views\";\n const resolvedDir = isAbsolute(rawDir) ? rawDir : resolve(root, rawDir);\n\n const views = discoverViewsSync(resolvedDir);\n writeViewsDts(root, views);\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-views.test.js","sourceRoot":"","sources":["../../src/views/scan-views.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n mkdirSync,\n mkdtempSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { afterEach, beforeEach, describe, expect, it } from \"vitest\";\nimport {\n discoverViewsSync,\n scanAndWriteViewsDts,\n scanViewsSync,\n writeViewsDts,\n} from \"./scan-views.js\";\n\nconst DEFAULT_EXPORT = \"export default function V() { return null; }\";\n\ndescribe(\"discoverViewsSync\", () => {\n let root: string;\n let viewsDir: string;\n\n beforeEach(() => {\n root = mkdtempSync(join(tmpdir(), \"skybridge-scan-\"));\n viewsDir = join(root, \"views\");\n mkdirSync(viewsDir, { recursive: true });\n });\n\n afterEach(() => {\n rmSync(root, { recursive: true, force: true });\n });\n\n it(\"picks up flat and dir-index views\", () => {\n writeFileSync(join(viewsDir, \"a.tsx\"), DEFAULT_EXPORT);\n mkdirSync(join(viewsDir, \"my-view\"));\n writeFileSync(join(viewsDir, \"my-view/index.tsx\"), DEFAULT_EXPORT);\n\n expect(\n discoverViewsSync(viewsDir)\n .map((v) => v.name)\n .sort(),\n ).toEqual([\"a\", \"my-view\"]);\n });\n\n it(\"throws on duplicate view names (flat + dir-index collision)\", () => {\n writeFileSync(join(viewsDir, \"dup.tsx\"), DEFAULT_EXPORT);\n mkdirSync(join(viewsDir, \"dup\"));\n writeFileSync(join(viewsDir, \"dup/index.tsx\"), DEFAULT_EXPORT);\n\n expect(() => discoverViewsSync(viewsDir)).toThrow(\n /duplicate view name \"dup\"/,\n );\n });\n});\n\ndescribe(\"scanViewsSync\", () => {\n let root: string;\n let viewsDir: string;\n\n beforeEach(() => {\n root = mkdtempSync(join(tmpdir(), \"skybridge-scan-views-\"));\n viewsDir = join(root, \"views\");\n mkdirSync(viewsDir, { recursive: true });\n });\n\n afterEach(() => {\n rmSync(root, { recursive: true, force: true });\n });\n\n it(\"returns valid and invalid views from a flat layout\", () => {\n writeFileSync(join(viewsDir, \"ok.tsx\"), DEFAULT_EXPORT);\n writeFileSync(\n join(viewsDir, \"broken.tsx\"),\n \"export const Foo = () => null;\",\n );\n\n const { valid, invalid } = scanViewsSync(viewsDir);\n\n expect(valid.map((v) => v.name).sort()).toEqual([\"ok\"]);\n expect(invalid).toEqual([{ filePath: join(viewsDir, \"broken.tsx\") }]);\n });\n\n it(\"flags an index file in a view dir that lacks a default export\", () => {\n mkdirSync(join(viewsDir, \"broken\"));\n writeFileSync(\n join(viewsDir, \"broken/index.tsx\"),\n \"export const Foo = () => null;\",\n );\n\n const { valid, invalid } = scanViewsSync(viewsDir);\n\n expect(valid).toEqual([]);\n expect(invalid).toEqual([{ filePath: join(viewsDir, \"broken/index.tsx\") }]);\n });\n\n it(\"ignores top-level index.tsx (treated as a barrel, not a view)\", () => {\n writeFileSync(\n join(viewsDir, \"index.tsx\"),\n \"export const Foo = () => null;\",\n );\n\n const { valid, invalid } = scanViewsSync(viewsDir);\n\n expect(valid).toEqual([]);\n expect(invalid).toEqual([]);\n });\n});\n\ndescribe(\"writeViewsDts\", () => {\n let root: string;\n\n beforeEach(() => {\n root = mkdtempSync(join(tmpdir(), \"skybridge-dts-\"));\n });\n\n afterEach(() => {\n rmSync(root, { recursive: true, force: true });\n });\n\n it(\"is a no-op when content is unchanged\", () => {\n const views = [{ name: \"a\", filePath: \"/a.tsx\" }];\n writeViewsDts(root, views);\n\n const dtsPath = join(root, \".skybridge\", \"views.d.ts\");\n const firstMtime = statSync(dtsPath).mtimeMs;\n\n writeViewsDts(root, views);\n expect(statSync(dtsPath).mtimeMs).toBe(firstMtime);\n });\n});\n\ndescribe(\"scanAndWriteViewsDts\", () => {\n let root: string;\n\n beforeEach(() => {\n root = mkdtempSync(join(tmpdir(), \"skybridge-scan-dts-\"));\n mkdirSync(join(root, \"src/views\"), { recursive: true });\n writeFileSync(join(root, \"src/views/hello.tsx\"), DEFAULT_EXPORT);\n });\n\n afterEach(() => {\n rmSync(root, { recursive: true, force: true });\n });\n\n it(\"writes a views.d.ts that augments skybridge/server with discovered view names\", () => {\n scanAndWriteViewsDts(root);\n\n const content = readFileSync(join(root, \".skybridge/views.d.ts\"), \"utf-8\");\n expect(content).toContain('declare module \"skybridge/server\"');\n expect(content).toContain('\"hello\": true;');\n });\n});\n"]}
@@ -0,0 +1 @@
1
+ export declare function hasDefaultExport(code: string): boolean;
@@ -1,7 +1,7 @@
1
1
  function stripComments(code) {
2
- return code.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
2
+ return code.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
3
3
  }
4
- export function hasDefaultExport(code, _filePath) {
4
+ export function hasDefaultExport(code) {
5
5
  const stripped = stripComments(code);
6
6
  return (/export\s+default\s/.test(stripped) ||
7
7
  /export\s*\{[^}]*\bas\s+default\b[^}]*}/.test(stripped));
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-view.js","sourceRoot":"","sources":["../../src/views/validate-view.ts"],"names":[],"mappings":"AAAA,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,CACL,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC;QACnC,wCAAwC,CAAC,IAAI,CAAC,QAAQ,CAAC,CACxD,CAAC;AACJ,CAAC","sourcesContent":["function stripComments(code: string): string {\n return code.replace(/\\/\\/[^\\n]*/g, \"\").replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n}\n\nexport function hasDefaultExport(code: string): boolean {\n const stripped = stripComments(code);\n return (\n /export\\s+default\\s/.test(stripped) ||\n /export\\s*\\{[^}]*\\bas\\s+default\\b[^}]*}/.test(stripped)\n );\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-view.test.js","sourceRoot":"","sources":["../../src/views/validate-view.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,gBAAgB,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,gBAAgB,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,IAAI,GAAG;;;KAGZ,CAAC;QACF,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { hasDefaultExport } from \"./validate-view.js\";\n\ndescribe(\"hasDefaultExport\", () => {\n it(\"detects export default declaration\", () => {\n expect(hasDefaultExport(\"export default MyView;\")).toBe(true);\n });\n\n it(\"detects export default function\", () => {\n expect(hasDefaultExport(\"export default function MyView() {}\")).toBe(true);\n });\n\n it(\"detects re-export as default\", () => {\n expect(hasDefaultExport(\"export { Foo as default };\")).toBe(true);\n });\n\n it(\"returns false when no default export\", () => {\n expect(hasDefaultExport(\"export const Foo = 1;\")).toBe(false);\n });\n\n it(\"ignores commented-out default exports\", () => {\n const code = `\n // export default MyView;\n /* export default MyView; */\n `;\n expect(hasDefaultExport(code)).toBe(false);\n });\n});\n"]}
@@ -0,0 +1,62 @@
1
+ import type { Adaptor, AnyViewToolHandler, CallToolOptions, CallToolResponse, DownloadParams, DownloadResult, FileMetadata, FileResource, FileResourceContent, FileResourceWriteResult, FollowUpMessage, HostContext, HostContextStore, ModelContextParams, OpenExternalOptions, RequestDisplayMode, RequestModalOptions, RequestSizeOptions, ResourceRepresentation, SendFollowUpMessageOptions, SetViewStateAction, UploadFileOptions, ViewToolConfig } from "./types.js";
2
+ /**
3
+ * @internal
4
+ * Single composite implementation of {@link Adaptor}. Composes the MCP App
5
+ * bridge (always present) with an optional `window.openai` overlay. Per-method
6
+ * routing rules are encoded inline.
7
+ */
8
+ export declare class HostAdaptor implements Adaptor {
9
+ private static instance;
10
+ static getInstance(): HostAdaptor;
11
+ static resetInstance(): void;
12
+ private readonly mcp;
13
+ private readonly openai;
14
+ private readonly stores;
15
+ private _viewState;
16
+ private readonly viewStateListeners;
17
+ private _viewUUID;
18
+ private _modelContext;
19
+ private readonly resourceListeners;
20
+ private resourceApp?;
21
+ private _polyfillDisplay;
22
+ private readonly polyfillDisplayListeners;
23
+ private readonly polyfillDisplayStore;
24
+ private readonly polyfillViewStateStore;
25
+ private unsubscribeViewUUID;
26
+ private unsubscribeModelContext;
27
+ constructor();
28
+ /** @internal Release any subscriptions held on the underlying bridges. */
29
+ cleanup(): void;
30
+ getHostContextStore: <K extends keyof HostContext>(key: K) => HostContextStore<K>;
31
+ callTool: <ToolArgs extends Record<string, unknown> | null = null, ToolResponse extends CallToolResponse = CallToolResponse>(name: string, args: ToolArgs, options?: CallToolOptions) => Promise<ToolResponse>;
32
+ registerViewTool: (config: ViewToolConfig, handler: AnyViewToolHandler) => (() => void);
33
+ requestDisplayMode: (mode: RequestDisplayMode) => Promise<{
34
+ [x: string]: unknown;
35
+ mode: "inline" | "fullscreen" | "pip";
36
+ }>;
37
+ requestClose: () => Promise<void>;
38
+ requestSize: (size: RequestSizeOptions) => Promise<void>;
39
+ sendFollowUpMessage: (prompt: FollowUpMessage, options?: SendFollowUpMessageOptions) => Promise<void>;
40
+ openExternal: (href: string, options?: OpenExternalOptions) => void;
41
+ download: (params: DownloadParams) => Promise<DownloadResult>;
42
+ setViewState: (stateOrUpdater: SetViewStateAction) => Promise<void>;
43
+ updateModelContext: (params: ModelContextParams) => Promise<string | undefined>;
44
+ private sendModelContext;
45
+ openFile: (path: string) => Promise<void>;
46
+ readResource: (uri: string, representation?: ResourceRepresentation) => Promise<FileResource>;
47
+ watchResource: (uri: string, onUpdate: () => void) => (() => void);
48
+ writeResource: (uri: string, content: FileResourceContent, ifMatch?: string) => Promise<FileResourceWriteResult>;
49
+ private getResourceApp;
50
+ uploadFile: (file: File, options?: UploadFileOptions) => Promise<FileMetadata>;
51
+ getFileDownloadUrl: (file: FileMetadata) => Promise<{
52
+ downloadUrl: string;
53
+ }>;
54
+ selectFiles: () => Promise<FileMetadata[]>;
55
+ openModal: (options: RequestModalOptions) => void;
56
+ setOpenInAppUrl: (href: string) => Promise<void>;
57
+ closeModal: () => void;
58
+ private trackFileIds;
59
+ private subscribeToViewUUID;
60
+ private restoreFromLocalStorage;
61
+ protected persistToLocalStorage(state: Record<string, unknown> | null): void;
62
+ }
@@ -0,0 +1,471 @@
1
+ import { ResultSchema } from "@modelcontextprotocol/core";
2
+ import * as z from "zod/v4";
3
+ import { warnOnLargeViewState } from "../../context-warnings.js";
4
+ import { AppsSdkBridge } from "./apps-sdk/bridge.js";
5
+ import { McpAppBridge } from "./mcp-app/bridge.js";
6
+ import { NotSupportedError } from "./types.js";
7
+ const ResourceMetaSchema = z.object({
8
+ writable: z.boolean().optional(),
9
+ etag: z.string().optional(),
10
+ });
11
+ const WriteResultSchema = z.discriminatedUnion("outcome", [
12
+ z.object({ outcome: z.enum(["saved", "conflict"]), etag: z.string() }),
13
+ z.object({ outcome: z.literal("too-large"), maxBytes: z.number() }),
14
+ ]);
15
+ const STORAGE_PREFIX = "sb:";
16
+ const MAX_STORAGE_ENTRIES = 200;
17
+ function isImage(mimeType) {
18
+ return mimeType?.startsWith("image/") ?? false;
19
+ }
20
+ function findStorageKey(viewUUID) {
21
+ const suffix = `:${viewUUID}`;
22
+ for (let i = 0; i < localStorage.length; i++) {
23
+ const key = localStorage.key(i);
24
+ if (key?.startsWith(STORAGE_PREFIX) && key.endsWith(suffix)) {
25
+ return key;
26
+ }
27
+ }
28
+ return undefined;
29
+ }
30
+ /**
31
+ * @internal
32
+ * Single composite implementation of {@link Adaptor}. Composes the MCP App
33
+ * bridge (always present) with an optional `window.openai` overlay. Per-method
34
+ * routing rules are encoded inline.
35
+ */
36
+ export class HostAdaptor {
37
+ static instance = null;
38
+ static getInstance() {
39
+ if (!HostAdaptor.instance) {
40
+ HostAdaptor.instance = new HostAdaptor();
41
+ }
42
+ return HostAdaptor.instance;
43
+ }
44
+ static resetInstance() {
45
+ HostAdaptor.instance?.cleanup();
46
+ HostAdaptor.instance = null;
47
+ }
48
+ mcp;
49
+ openai = null;
50
+ stores;
51
+ _viewState = null;
52
+ viewStateListeners = new Set();
53
+ _viewUUID = null;
54
+ _modelContext = null;
55
+ resourceListeners = new Map();
56
+ resourceApp;
57
+ _polyfillDisplay = { mode: "inline" };
58
+ polyfillDisplayListeners = new Set();
59
+ polyfillDisplayStore;
60
+ polyfillViewStateStore;
61
+ unsubscribeViewUUID = null;
62
+ unsubscribeModelContext = null;
63
+ constructor() {
64
+ this.mcp = McpAppBridge.getInstance();
65
+ let overlayStores = null;
66
+ if (typeof window !== "undefined" && window.openai !== undefined) {
67
+ this.openai = window.openai;
68
+ overlayStores = AppsSdkBridge.getInstance().createOverlayStores();
69
+ }
70
+ // Built once so that getHostContextStore returns stable references — required
71
+ // by useSyncExternalStore to avoid resubscribing on every render.
72
+ this.polyfillDisplayStore = {
73
+ subscribe: (onChange) => {
74
+ this.polyfillDisplayListeners.add(onChange);
75
+ return () => {
76
+ this.polyfillDisplayListeners.delete(onChange);
77
+ };
78
+ },
79
+ getSnapshot: () => this._polyfillDisplay,
80
+ };
81
+ this.polyfillViewStateStore = {
82
+ subscribe: (onChange) => {
83
+ this.viewStateListeners.add(onChange);
84
+ return () => {
85
+ this.viewStateListeners.delete(onChange);
86
+ };
87
+ },
88
+ getSnapshot: () => this._viewState,
89
+ };
90
+ this.stores = {
91
+ ...this.mcp.createContextStores(),
92
+ display: overlayStores?.display ?? this.polyfillDisplayStore,
93
+ viewState: overlayStores?.viewState ?? this.polyfillViewStateStore,
94
+ };
95
+ this.subscribeToViewUUID();
96
+ this.unsubscribeModelContext = this.mcp.subscribe("openai/modelContext")(() => {
97
+ if (this.mcp.getSnapshot("openai/modelContext") === null) {
98
+ this._modelContext = null;
99
+ }
100
+ });
101
+ }
102
+ /** @internal Release any subscriptions held on the underlying bridges. */
103
+ cleanup() {
104
+ this.unsubscribeViewUUID?.();
105
+ this.unsubscribeViewUUID = null;
106
+ this.unsubscribeModelContext?.();
107
+ this.unsubscribeModelContext = null;
108
+ }
109
+ // ---- Adaptor interface ----
110
+ getHostContextStore = (key) => this.stores[key];
111
+ callTool = async (name, args, options) => {
112
+ const timeout = options?.timeout;
113
+ if (timeout !== undefined && (!Number.isFinite(timeout) || timeout <= 0)) {
114
+ throw new RangeError("Tool call timeout must be a positive, finite number of milliseconds.");
115
+ }
116
+ const app = await this.mcp.getApp();
117
+ const params = { name, arguments: args ?? undefined };
118
+ const response = await app.callServerTool(params, { timeout });
119
+ return {
120
+ content: response.content,
121
+ structuredContent: response.structuredContent ?? {},
122
+ isError: response.isError ?? false,
123
+ meta: response._meta ?? {},
124
+ };
125
+ };
126
+ registerViewTool = (config, handler) => {
127
+ return this.mcp.registerViewTool(config, handler);
128
+ };
129
+ requestDisplayMode = async (mode) => {
130
+ const app = await this.mcp.getApp();
131
+ return app.requestDisplayMode({ mode });
132
+ };
133
+ requestClose = async () => {
134
+ if (this.openai) {
135
+ await this.openai.requestClose();
136
+ }
137
+ const app = await this.mcp.getApp();
138
+ await app.requestTeardown();
139
+ };
140
+ requestSize = async (size) => {
141
+ const app = await this.mcp.getApp();
142
+ await app.sendSizeChanged(size);
143
+ };
144
+ sendFollowUpMessage = async (prompt, options) => {
145
+ const target = options?.target;
146
+ if (this.openai && typeof prompt === "string" && target !== "new") {
147
+ await this.openai.sendFollowUpMessage({
148
+ prompt,
149
+ scrollToBottom: options?.scrollToBottom,
150
+ });
151
+ return;
152
+ }
153
+ const app = await this.mcp.getApp();
154
+ if (target === "new" &&
155
+ !app.getHostCapabilities()?.experimental?.["openai/message"]) {
156
+ throw new NotSupportedError("sendFollowUpMessage", "the host does not advertise openai/message, so it can't open a new conversation");
157
+ }
158
+ const result = await app.sendMessage({
159
+ role: "user",
160
+ content: typeof prompt === "string" ? [{ type: "text", text: prompt }] : prompt,
161
+ ...(target === "new" && { _meta: { "openai/message": { target } } }),
162
+ });
163
+ if (result?.isError) {
164
+ throw new Error("The host rejected the follow-up message.");
165
+ }
166
+ };
167
+ openExternal = (href, options) => {
168
+ if (this.openai) {
169
+ this.openai.openExternal({ href, ...options });
170
+ return;
171
+ }
172
+ this.mcp
173
+ .getApp()
174
+ .then((app) => app.openLink({ url: href }))
175
+ .catch((err) => {
176
+ console.error("Failed to open external link:", err);
177
+ });
178
+ };
179
+ download = async (params) => {
180
+ const app = await this.mcp.getApp();
181
+ if (!app.getHostCapabilities()?.downloadFile) {
182
+ console.error("[skybridge] download: host does not support ui/download-file");
183
+ return { isError: true };
184
+ }
185
+ return app.downloadFile(params);
186
+ };
187
+ setViewState = async (stateOrUpdater) => {
188
+ if (this.openai) {
189
+ const modelContent = typeof stateOrUpdater === "function"
190
+ ? stateOrUpdater(this.openai.widgetState?.modelContent ?? null)
191
+ : stateOrUpdater;
192
+ warnOnLargeViewState(modelContent, "setWidgetState");
193
+ await this.openai.setWidgetState({
194
+ privateContent: {},
195
+ ...this.openai.widgetState,
196
+ modelContent,
197
+ });
198
+ return;
199
+ }
200
+ const newState = typeof stateOrUpdater === "function"
201
+ ? stateOrUpdater(this._viewState)
202
+ : stateOrUpdater;
203
+ warnOnLargeViewState(newState, "setViewState");
204
+ // update local state immediately so successive calls see fresh state
205
+ this._viewState = newState;
206
+ this.viewStateListeners.forEach((l) => {
207
+ l();
208
+ });
209
+ this.persistToLocalStorage(newState);
210
+ try {
211
+ await this.sendModelContext();
212
+ }
213
+ catch (error) {
214
+ console.error("Failed to update view state in MCP App.", error);
215
+ }
216
+ };
217
+ updateModelContext = async (params) => {
218
+ const app = await this.mcp.getApp();
219
+ const capabilities = app.getHostCapabilities();
220
+ if (!capabilities?.updateModelContext &&
221
+ !capabilities?.experimental?.["openai/modelContext"]) {
222
+ throw new NotSupportedError("updateModelContext", "the host does not advertise updateModelContext");
223
+ }
224
+ const previous = this._modelContext;
225
+ this._modelContext = params;
226
+ const result = await this.sendModelContext().catch((error) => {
227
+ if (this._modelContext === params) {
228
+ this._modelContext = previous;
229
+ }
230
+ throw error;
231
+ });
232
+ const parsed = z
233
+ .object({ updateId: z.string() })
234
+ .safeParse(result._meta?.["openai/modelContext"]);
235
+ return parsed.success ? parsed.data.updateId : undefined;
236
+ };
237
+ async sendModelContext() {
238
+ const viewState = this.openai ? null : this._viewState;
239
+ const extra = this._modelContext;
240
+ const collisions = Object.keys(extra?.structuredContent ?? {}).filter((key) => viewState !== null && key in viewState);
241
+ if (collisions.length > 0) {
242
+ console.warn(`skybridge: view state overrides model context keys ${collisions.join(", ")}.`);
243
+ }
244
+ const structuredContent = { ...extra?.structuredContent, ...viewState };
245
+ const app = await this.mcp.getApp();
246
+ return app.updateModelContext({
247
+ ...(Object.keys(structuredContent).length > 0 && { structuredContent }),
248
+ content: [
249
+ ...(viewState === null
250
+ ? []
251
+ : [
252
+ {
253
+ type: "text",
254
+ text: JSON.stringify(viewState),
255
+ annotations: { audience: ["assistant"] },
256
+ },
257
+ ]),
258
+ ...(extra?.content ?? []),
259
+ ],
260
+ });
261
+ }
262
+ openFile = async (path) => {
263
+ const app = await this.mcp.getApp();
264
+ if (!app.getHostCapabilities()?.experimental?.["openai/files"]) {
265
+ throw new NotSupportedError("openFile", "the host does not advertise openai/files");
266
+ }
267
+ await app.request({ method: "openai/files/open", params: { path } }, ResultSchema);
268
+ };
269
+ readResource = async (uri, representation) => {
270
+ const app = await this.mcp.getApp();
271
+ const { contents } = await app.readServerResource({
272
+ uri,
273
+ ...(representation && {
274
+ _meta: { "openai/resource": { representation } },
275
+ }),
276
+ });
277
+ const item = contents.find((content) => content.uri === uri) ?? contents[0];
278
+ if (!item) {
279
+ throw new Error(`The host returned no contents for ${uri}.`);
280
+ }
281
+ const { data: meta } = ResourceMetaSchema.safeParse(item._meta?.["openai/resource"]);
282
+ return {
283
+ ...("text" in item ? { text: item.text } : { blob: item.blob }),
284
+ mimeType: item.mimeType,
285
+ writable: meta?.writable ?? false,
286
+ etag: meta?.etag,
287
+ };
288
+ };
289
+ watchResource = (uri, onUpdate) => {
290
+ const listeners = this.resourceListeners.get(uri) ?? new Set();
291
+ if (listeners.size === 0) {
292
+ this.resourceListeners.set(uri, listeners);
293
+ this.getResourceApp()
294
+ .then((app) => app?.request({ method: "resources/subscribe", params: { uri } }, ResultSchema))
295
+ .catch((error) => {
296
+ console.warn(`Failed to subscribe to ${uri}.`, error);
297
+ });
298
+ }
299
+ listeners.add(onUpdate);
300
+ return () => {
301
+ if (listeners.delete(onUpdate) && listeners.size === 0) {
302
+ this.resourceListeners.delete(uri);
303
+ this.getResourceApp()
304
+ .then((app) => app?.request({ method: "resources/unsubscribe", params: { uri } }, ResultSchema))
305
+ .catch(() => { });
306
+ }
307
+ };
308
+ };
309
+ writeResource = async (uri, content, ifMatch) => {
310
+ const app = await this.getResourceApp();
311
+ if (!app) {
312
+ throw new NotSupportedError("writeResource", "the host does not advertise openai/resource");
313
+ }
314
+ return app.request({
315
+ method: "openai/resources/write",
316
+ params: { uri, ...content, ...(ifMatch && { ifMatch }) },
317
+ }, WriteResultSchema);
318
+ };
319
+ getResourceApp() {
320
+ this.resourceApp ??= this.mcp.getApp().then((app) => {
321
+ if (!app.getHostCapabilities()?.experimental?.["openai/resource"]) {
322
+ return undefined;
323
+ }
324
+ app.setNotificationHandler("notifications/resources/updated", ({ params }) => {
325
+ this.resourceListeners.get(params.uri)?.forEach((l) => {
326
+ l();
327
+ });
328
+ });
329
+ return app;
330
+ });
331
+ return this.resourceApp;
332
+ }
333
+ uploadFile = async (file, options) => {
334
+ if (!this.openai) {
335
+ throw new NotSupportedError("uploadFile");
336
+ }
337
+ const metadata = await this.openai.uploadFile(file, options);
338
+ if (isImage(metadata.mimeType ?? file.type)) {
339
+ await this.trackFileIds(metadata.fileId);
340
+ }
341
+ return metadata;
342
+ };
343
+ getFileDownloadUrl = (file) => {
344
+ if (!this.openai) {
345
+ return Promise.reject(new NotSupportedError("getFileDownloadUrl"));
346
+ }
347
+ return this.openai.getFileDownloadUrl(file);
348
+ };
349
+ selectFiles = async () => {
350
+ if (!this.openai) {
351
+ throw new NotSupportedError("selectFiles");
352
+ }
353
+ if (!this.openai.selectFiles) {
354
+ throw new Error("selectFiles is not supported by the current host version.");
355
+ }
356
+ const files = await this.openai.selectFiles();
357
+ const imageIds = [];
358
+ for (const file of files) {
359
+ if (isImage(file.mimeType)) {
360
+ imageIds.push(file.fileId);
361
+ }
362
+ }
363
+ if (imageIds.length > 0) {
364
+ await this.trackFileIds(...imageIds);
365
+ }
366
+ return files;
367
+ };
368
+ openModal = (options) => {
369
+ if (this.openai) {
370
+ this.openai.requestModal(options);
371
+ return;
372
+ }
373
+ this._polyfillDisplay = { mode: "modal", params: options.params };
374
+ this.polyfillDisplayListeners.forEach((l) => {
375
+ l();
376
+ });
377
+ };
378
+ setOpenInAppUrl = (href) => {
379
+ if (!this.openai) {
380
+ return Promise.reject(new NotSupportedError("setOpenInAppUrl"));
381
+ }
382
+ const trimmed = href.trim();
383
+ if (!trimmed) {
384
+ return Promise.reject(new Error("The href parameter is required."));
385
+ }
386
+ return this.openai.setOpenInAppUrl({ href: trimmed });
387
+ };
388
+ closeModal = () => {
389
+ if (this.openai) {
390
+ return; // host owns modal lifecycle
391
+ }
392
+ this._polyfillDisplay = { mode: "inline" };
393
+ this.polyfillDisplayListeners.forEach((l) => {
394
+ l();
395
+ });
396
+ };
397
+ async trackFileIds(...fileIds) {
398
+ if (!this.openai) {
399
+ return;
400
+ }
401
+ const current = this.openai.widgetState;
402
+ const state = current
403
+ ? { ...current }
404
+ : { modelContent: {}, privateContent: {} };
405
+ if (!state.imageIds) {
406
+ state.imageIds = [];
407
+ }
408
+ state.imageIds.push(...fileIds);
409
+ await this.openai.setWidgetState(state);
410
+ }
411
+ // ---- viewState persistence helpers ----
412
+ subscribeToViewUUID() {
413
+ this.unsubscribeViewUUID = this.mcp.subscribe("toolResult")(() => {
414
+ const toolResult = this.mcp.getSnapshot("toolResult");
415
+ const viewUUID = toolResult?._meta?.viewUUID;
416
+ if (viewUUID && viewUUID !== this._viewUUID) {
417
+ this._viewUUID = viewUUID;
418
+ this.restoreFromLocalStorage(viewUUID);
419
+ }
420
+ });
421
+ }
422
+ restoreFromLocalStorage(viewUUID) {
423
+ try {
424
+ const existingKey = findStorageKey(viewUUID);
425
+ if (existingKey) {
426
+ const stored = localStorage.getItem(existingKey);
427
+ if (stored !== null) {
428
+ this._viewState = JSON.parse(stored);
429
+ this.viewStateListeners.forEach((l) => {
430
+ l();
431
+ });
432
+ }
433
+ }
434
+ }
435
+ catch (err) {
436
+ console.error(err);
437
+ }
438
+ }
439
+ persistToLocalStorage(state) {
440
+ if (!this._viewUUID || state === null) {
441
+ return;
442
+ }
443
+ try {
444
+ const oldKey = findStorageKey(this._viewUUID);
445
+ if (oldKey) {
446
+ localStorage.removeItem(oldKey);
447
+ }
448
+ const newKey = `${STORAGE_PREFIX}${Date.now()}:${this._viewUUID}`;
449
+ localStorage.setItem(newKey, JSON.stringify(state));
450
+ const keys = [];
451
+ for (let i = 0; i < localStorage.length; i++) {
452
+ const key = localStorage.key(i);
453
+ if (key?.startsWith(STORAGE_PREFIX)) {
454
+ keys.push(key);
455
+ }
456
+ }
457
+ if (keys.length <= MAX_STORAGE_ENTRIES) {
458
+ return;
459
+ }
460
+ keys.sort();
461
+ const toRemove = keys.slice(0, keys.length - MAX_STORAGE_ENTRIES);
462
+ for (const key of toRemove) {
463
+ localStorage.removeItem(key);
464
+ }
465
+ }
466
+ catch (err) {
467
+ console.error(err);
468
+ }
469
+ }
470
+ }
471
+ //# sourceMappingURL=adaptor.js.map