skybridge 0.0.0-dev.afd3b31 → 0.0.0-dev.aff642f

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 (301) hide show
  1. package/README.md +143 -0
  2. package/bin/run.js +5 -0
  3. package/dist/cli/header.d.ts +4 -0
  4. package/dist/cli/header.js +6 -0
  5. package/dist/cli/header.js.map +1 -0
  6. package/dist/cli/run-command.d.ts +2 -0
  7. package/dist/cli/run-command.js +43 -0
  8. package/dist/cli/run-command.js.map +1 -0
  9. package/dist/cli/use-execute-steps.d.ts +10 -0
  10. package/dist/cli/use-execute-steps.js +31 -0
  11. package/dist/cli/use-execute-steps.js.map +1 -0
  12. package/dist/commands/build.d.ts +9 -0
  13. package/dist/commands/build.js +44 -0
  14. package/dist/commands/build.js.map +1 -0
  15. package/dist/commands/dev.d.ts +9 -0
  16. package/dist/commands/dev.js +32 -0
  17. package/dist/commands/dev.js.map +1 -0
  18. package/dist/commands/start.d.ts +7 -0
  19. package/dist/commands/start.js +33 -0
  20. package/dist/commands/start.js.map +1 -0
  21. package/dist/{src/server → server}/index.d.ts +0 -1
  22. package/dist/{src/server → server}/index.js +0 -1
  23. package/dist/server/index.js.map +1 -0
  24. package/dist/server/inferUtilityTypes.js.map +1 -0
  25. package/dist/{src/server → server}/server.d.ts +26 -1
  26. package/dist/server/server.js +139 -0
  27. package/dist/server/server.js.map +1 -0
  28. package/dist/server/templateHelper.js.map +1 -0
  29. package/dist/{src/server → server}/templates/development.hbs +15 -0
  30. package/dist/{src/server → server}/widgetsDevServer.d.ts +2 -2
  31. package/dist/{src/server → server}/widgetsDevServer.js +11 -2
  32. package/dist/server/widgetsDevServer.js.map +1 -0
  33. package/dist/test/utils.js.map +1 -0
  34. package/dist/{src/test → test}/widget.test.js +101 -6
  35. package/dist/test/widget.test.js.map +1 -0
  36. package/dist/web/bridges/apps-sdk/adaptor.d.ts +21 -0
  37. package/dist/{src/web/bridges/adaptors/apps-sdk-adaptor.js → web/bridges/apps-sdk/adaptor.js} +18 -3
  38. package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -0
  39. package/dist/web/bridges/apps-sdk/bridge.d.ts +10 -0
  40. package/dist/{src/web/bridges/apps-sdk-bridge.js → web/bridges/apps-sdk/bridge.js} +2 -2
  41. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  42. package/dist/web/bridges/apps-sdk/index.d.ts +5 -0
  43. package/dist/web/bridges/apps-sdk/index.js +5 -0
  44. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  45. package/dist/{src/web → web/bridges/apps-sdk}/types.d.ts +15 -56
  46. package/dist/{src/web → web/bridges/apps-sdk}/types.js +0 -1
  47. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  48. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +2 -0
  49. package/dist/{src/web/bridges/hooks/use-apps-sdk-bridge.js → web/bridges/apps-sdk/use-apps-sdk-context.js} +3 -3
  50. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  51. package/dist/web/bridges/get-adaptor.d.ts +2 -0
  52. package/dist/web/bridges/get-adaptor.js +8 -0
  53. package/dist/web/bridges/get-adaptor.js.map +1 -0
  54. package/dist/web/bridges/index.d.ts +5 -0
  55. package/dist/web/bridges/index.js +6 -0
  56. package/dist/web/bridges/index.js.map +1 -0
  57. package/dist/web/bridges/mcp-app/adaptor.d.ts +35 -0
  58. package/dist/web/bridges/mcp-app/adaptor.js +182 -0
  59. package/dist/web/bridges/mcp-app/adaptor.js.map +1 -0
  60. package/dist/web/bridges/mcp-app/bridge.d.ts +43 -0
  61. package/dist/{src/web/bridges/mcp-app-bridge.js → web/bridges/mcp-app/bridge.js} +109 -16
  62. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  63. package/dist/web/bridges/mcp-app/index.d.ts +4 -0
  64. package/dist/web/bridges/mcp-app/index.js +4 -0
  65. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  66. package/dist/web/bridges/mcp-app/types.d.ts +8 -0
  67. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  68. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +5 -0
  69. package/dist/{src/web/bridges/hooks/use-mcp-app-bridge.js → web/bridges/mcp-app/use-mcp-app-context.js} +3 -3
  70. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  71. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +66 -0
  72. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  73. package/dist/web/bridges/types.d.ts +96 -0
  74. package/dist/web/bridges/types.js +2 -0
  75. package/dist/{src/web → web}/bridges/types.js.map +1 -1
  76. package/dist/web/bridges/use-host-context.d.ts +2 -0
  77. package/dist/web/bridges/use-host-context.js +8 -0
  78. package/dist/web/bridges/use-host-context.js.map +1 -0
  79. package/dist/web/components/modal-provider.d.ts +4 -0
  80. package/dist/web/components/modal-provider.js +47 -0
  81. package/dist/web/components/modal-provider.js.map +1 -0
  82. package/dist/{src/web → web}/create-store.js +6 -7
  83. package/dist/web/create-store.js.map +1 -0
  84. package/dist/web/create-store.test.js +126 -0
  85. package/dist/web/create-store.test.js.map +1 -0
  86. package/dist/{src/web → web}/data-llm.js +5 -3
  87. package/dist/web/data-llm.js.map +1 -0
  88. package/dist/web/data-llm.test.js +139 -0
  89. package/dist/web/data-llm.test.js.map +1 -0
  90. package/dist/{src/web → web}/generate-helpers.d.ts +3 -2
  91. package/dist/{src/web → web}/generate-helpers.js +1 -1
  92. package/dist/web/generate-helpers.js.map +1 -0
  93. package/dist/web/generate-helpers.test-d.js.map +1 -0
  94. package/dist/web/generate-helpers.test.js.map +1 -0
  95. package/dist/{src/web → web}/helpers/state.js +13 -8
  96. package/dist/web/helpers/state.js.map +1 -0
  97. package/dist/web/helpers/state.test.js.map +1 -0
  98. package/dist/{src/web → web}/hooks/index.d.ts +0 -1
  99. package/dist/{src/web → web}/hooks/index.js +0 -1
  100. package/dist/web/hooks/index.js.map +1 -0
  101. package/dist/{src/web → web}/hooks/test/utils.d.ts +8 -2
  102. package/dist/web/hooks/test/utils.js +60 -0
  103. package/dist/web/hooks/test/utils.js.map +1 -0
  104. package/dist/{src/web → web}/hooks/use-call-tool.d.ts +3 -2
  105. package/dist/{src/web → web}/hooks/use-call-tool.js +2 -2
  106. package/dist/web/hooks/use-call-tool.js.map +1 -0
  107. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  108. package/dist/{src/web → web}/hooks/use-call-tool.test.js +3 -4
  109. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  110. package/dist/web/hooks/use-display-mode.js +9 -0
  111. package/dist/web/hooks/use-display-mode.js.map +1 -0
  112. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  113. package/dist/web/hooks/use-files.d.ts +6 -0
  114. package/dist/web/hooks/use-files.js +9 -0
  115. package/dist/web/hooks/use-files.js.map +1 -0
  116. package/dist/{src/web → web}/hooks/use-files.test.js +5 -4
  117. package/dist/web/hooks/use-files.test.js.map +1 -0
  118. package/dist/{src/web → web}/hooks/use-layout.d.ts +2 -2
  119. package/dist/{src/web → web}/hooks/use-layout.js +4 -4
  120. package/dist/web/hooks/use-layout.js.map +1 -0
  121. package/dist/{src/web → web}/hooks/use-layout.test.js +6 -5
  122. package/dist/web/hooks/use-layout.test.js.map +1 -0
  123. package/dist/{src/web → web}/hooks/use-open-external.js +2 -2
  124. package/dist/web/hooks/use-open-external.js.map +1 -0
  125. package/dist/{src/web → web}/hooks/use-open-external.test.js +1 -1
  126. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  127. package/dist/{src/web → web}/hooks/use-request-modal.d.ts +2 -2
  128. package/dist/web/hooks/use-request-modal.js +16 -0
  129. package/dist/web/hooks/use-request-modal.js.map +1 -0
  130. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  131. package/dist/{src/web → web}/hooks/use-send-follow-up-message.js +2 -2
  132. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  133. package/dist/{src/web → web}/hooks/use-tool-info.js +4 -4
  134. package/dist/web/hooks/use-tool-info.js.map +1 -0
  135. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  136. package/dist/{src/web → web}/hooks/use-tool-info.test.js +4 -4
  137. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  138. package/dist/{src/web → web}/hooks/use-user.d.ts +1 -1
  139. package/dist/{src/web → web}/hooks/use-user.js +3 -3
  140. package/dist/web/hooks/use-user.js.map +1 -0
  141. package/dist/{src/web → web}/hooks/use-user.test.js +4 -3
  142. package/dist/web/hooks/use-user.test.js.map +1 -0
  143. package/dist/{src/web → web}/hooks/use-widget-state.js +10 -10
  144. package/dist/web/hooks/use-widget-state.js.map +1 -0
  145. package/dist/web/hooks/use-widget-state.test.js.map +1 -0
  146. package/dist/web/index.js.map +1 -0
  147. package/dist/{src/web → web}/mount-widget.js +9 -1
  148. package/dist/web/mount-widget.js.map +1 -0
  149. package/dist/web/plugin/data-llm.test.js.map +1 -0
  150. package/dist/web/plugin/plugin.js.map +1 -0
  151. package/dist/web/plugin/transform-data-llm.js.map +1 -0
  152. package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
  153. package/dist/web/proxy.js.map +1 -0
  154. package/dist/web/types.d.ts +16 -0
  155. package/dist/web/types.js +2 -0
  156. package/dist/web/types.js.map +1 -0
  157. package/package.json +34 -18
  158. package/dist/src/server/devtoolsStaticServer.d.ts +0 -19
  159. package/dist/src/server/devtoolsStaticServer.js +0 -48
  160. package/dist/src/server/devtoolsStaticServer.js.map +0 -1
  161. package/dist/src/server/index.js.map +0 -1
  162. package/dist/src/server/inferUtilityTypes.js.map +0 -1
  163. package/dist/src/server/server.js +0 -86
  164. package/dist/src/server/server.js.map +0 -1
  165. package/dist/src/server/templateHelper.js.map +0 -1
  166. package/dist/src/server/widgetsDevServer.js.map +0 -1
  167. package/dist/src/test/utils.js.map +0 -1
  168. package/dist/src/test/widget.test.js.map +0 -1
  169. package/dist/src/web/bridges/adaptors/apps-sdk-adaptor.d.ts +0 -13
  170. package/dist/src/web/bridges/adaptors/apps-sdk-adaptor.js.map +0 -1
  171. package/dist/src/web/bridges/adaptors/mcp-app-adaptor.d.ts +0 -16
  172. package/dist/src/web/bridges/adaptors/mcp-app-adaptor.js +0 -115
  173. package/dist/src/web/bridges/adaptors/mcp-app-adaptor.js.map +0 -1
  174. package/dist/src/web/bridges/apps-sdk-bridge.d.ts +0 -10
  175. package/dist/src/web/bridges/apps-sdk-bridge.js.map +0 -1
  176. package/dist/src/web/bridges/hooks/use-adaptor.d.ts +0 -2
  177. package/dist/src/web/bridges/hooks/use-adaptor.js +0 -8
  178. package/dist/src/web/bridges/hooks/use-adaptor.js.map +0 -1
  179. package/dist/src/web/bridges/hooks/use-apps-sdk-bridge.d.ts +0 -2
  180. package/dist/src/web/bridges/hooks/use-apps-sdk-bridge.js.map +0 -1
  181. package/dist/src/web/bridges/hooks/use-bridge.d.ts +0 -2
  182. package/dist/src/web/bridges/hooks/use-bridge.js +0 -8
  183. package/dist/src/web/bridges/hooks/use-bridge.js.map +0 -1
  184. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.d.ts +0 -5
  185. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.js.map +0 -1
  186. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.test.js +0 -41
  187. package/dist/src/web/bridges/hooks/use-mcp-app-bridge.test.js.map +0 -1
  188. package/dist/src/web/bridges/index.d.ts +0 -4
  189. package/dist/src/web/bridges/index.js +0 -5
  190. package/dist/src/web/bridges/index.js.map +0 -1
  191. package/dist/src/web/bridges/mcp-app-bridge.d.ts +0 -38
  192. package/dist/src/web/bridges/mcp-app-bridge.js.map +0 -1
  193. package/dist/src/web/bridges/types.d.ts +0 -57
  194. package/dist/src/web/create-store.js.map +0 -1
  195. package/dist/src/web/create-store.test.js +0 -70
  196. package/dist/src/web/create-store.test.js.map +0 -1
  197. package/dist/src/web/data-llm.js.map +0 -1
  198. package/dist/src/web/data-llm.test.js +0 -76
  199. package/dist/src/web/data-llm.test.js.map +0 -1
  200. package/dist/src/web/generate-helpers.js.map +0 -1
  201. package/dist/src/web/generate-helpers.test-d.js.map +0 -1
  202. package/dist/src/web/generate-helpers.test.js.map +0 -1
  203. package/dist/src/web/helpers/state.js.map +0 -1
  204. package/dist/src/web/helpers/state.test.js.map +0 -1
  205. package/dist/src/web/hooks/index.js.map +0 -1
  206. package/dist/src/web/hooks/test/utils.js +0 -40
  207. package/dist/src/web/hooks/test/utils.js.map +0 -1
  208. package/dist/src/web/hooks/use-call-tool.js.map +0 -1
  209. package/dist/src/web/hooks/use-call-tool.test-d.js.map +0 -1
  210. package/dist/src/web/hooks/use-call-tool.test.js.map +0 -1
  211. package/dist/src/web/hooks/use-display-mode.js +0 -10
  212. package/dist/src/web/hooks/use-display-mode.js.map +0 -1
  213. package/dist/src/web/hooks/use-display-mode.test.js.map +0 -1
  214. package/dist/src/web/hooks/use-files.d.ts +0 -10
  215. package/dist/src/web/hooks/use-files.js +0 -7
  216. package/dist/src/web/hooks/use-files.js.map +0 -1
  217. package/dist/src/web/hooks/use-files.test.js.map +0 -1
  218. package/dist/src/web/hooks/use-layout.js.map +0 -1
  219. package/dist/src/web/hooks/use-layout.test.js.map +0 -1
  220. package/dist/src/web/hooks/use-open-external.js.map +0 -1
  221. package/dist/src/web/hooks/use-open-external.test.js.map +0 -1
  222. package/dist/src/web/hooks/use-openai-global.d.ts +0 -3
  223. package/dist/src/web/hooks/use-openai-global.js +0 -6
  224. package/dist/src/web/hooks/use-openai-global.js.map +0 -1
  225. package/dist/src/web/hooks/use-request-modal.js +0 -14
  226. package/dist/src/web/hooks/use-request-modal.js.map +0 -1
  227. package/dist/src/web/hooks/use-request-modal.test.js.map +0 -1
  228. package/dist/src/web/hooks/use-send-follow-up-message.js.map +0 -1
  229. package/dist/src/web/hooks/use-tool-info.js.map +0 -1
  230. package/dist/src/web/hooks/use-tool-info.test-d.js.map +0 -1
  231. package/dist/src/web/hooks/use-tool-info.test.js.map +0 -1
  232. package/dist/src/web/hooks/use-user.js.map +0 -1
  233. package/dist/src/web/hooks/use-user.test.js.map +0 -1
  234. package/dist/src/web/hooks/use-widget-state.js.map +0 -1
  235. package/dist/src/web/hooks/use-widget-state.test.js.map +0 -1
  236. package/dist/src/web/index.js.map +0 -1
  237. package/dist/src/web/mount-widget.js.map +0 -1
  238. package/dist/src/web/plugin/data-llm.test.js.map +0 -1
  239. package/dist/src/web/plugin/plugin.js.map +0 -1
  240. package/dist/src/web/plugin/transform-data-llm.js.map +0 -1
  241. package/dist/src/web/plugin/transform-data-llm.test.js.map +0 -1
  242. package/dist/src/web/proxy.js.map +0 -1
  243. package/dist/src/web/types.js.map +0 -1
  244. package/dist/vitest.config.d.ts +0 -2
  245. package/dist/vitest.config.js +0 -8
  246. package/dist/vitest.config.js.map +0 -1
  247. /package/dist/{src/server → server}/inferUtilityTypes.d.ts +0 -0
  248. /package/dist/{src/server → server}/inferUtilityTypes.js +0 -0
  249. /package/dist/{src/server → server}/templateHelper.d.ts +0 -0
  250. /package/dist/{src/server → server}/templateHelper.js +0 -0
  251. /package/dist/{src/server → server}/templates/production.hbs +0 -0
  252. /package/dist/{src/test → test}/utils.d.ts +0 -0
  253. /package/dist/{src/test → test}/utils.js +0 -0
  254. /package/dist/{src/test → test}/widget.test.d.ts +0 -0
  255. /package/dist/{src/web/bridges → web/bridges/mcp-app}/types.js +0 -0
  256. /package/dist/{src/web/bridges/hooks/use-mcp-app-bridge.test.d.ts → web/bridges/mcp-app/use-mcp-app-context.test.d.ts} +0 -0
  257. /package/dist/{src/web → web}/create-store.d.ts +0 -0
  258. /package/dist/{src/web → web}/create-store.test.d.ts +0 -0
  259. /package/dist/{src/web → web}/data-llm.d.ts +0 -0
  260. /package/dist/{src/web → web}/data-llm.test.d.ts +0 -0
  261. /package/dist/{src/web → web}/generate-helpers.test-d.d.ts +0 -0
  262. /package/dist/{src/web → web}/generate-helpers.test-d.js +0 -0
  263. /package/dist/{src/web → web}/generate-helpers.test.d.ts +0 -0
  264. /package/dist/{src/web → web}/generate-helpers.test.js +0 -0
  265. /package/dist/{src/web → web}/helpers/state.d.ts +0 -0
  266. /package/dist/{src/web → web}/helpers/state.test.d.ts +0 -0
  267. /package/dist/{src/web → web}/helpers/state.test.js +0 -0
  268. /package/dist/{src/web → web}/hooks/use-call-tool.test-d.d.ts +0 -0
  269. /package/dist/{src/web → web}/hooks/use-call-tool.test-d.js +0 -0
  270. /package/dist/{src/web → web}/hooks/use-call-tool.test.d.ts +0 -0
  271. /package/dist/{src/web → web}/hooks/use-display-mode.d.ts +0 -0
  272. /package/dist/{src/web → web}/hooks/use-display-mode.test.d.ts +0 -0
  273. /package/dist/{src/web → web}/hooks/use-display-mode.test.js +0 -0
  274. /package/dist/{src/web → web}/hooks/use-files.test.d.ts +0 -0
  275. /package/dist/{src/web → web}/hooks/use-layout.test.d.ts +0 -0
  276. /package/dist/{src/web → web}/hooks/use-open-external.d.ts +0 -0
  277. /package/dist/{src/web → web}/hooks/use-open-external.test.d.ts +0 -0
  278. /package/dist/{src/web → web}/hooks/use-request-modal.test.d.ts +0 -0
  279. /package/dist/{src/web → web}/hooks/use-request-modal.test.js +0 -0
  280. /package/dist/{src/web → web}/hooks/use-send-follow-up-message.d.ts +0 -0
  281. /package/dist/{src/web → web}/hooks/use-tool-info.d.ts +0 -0
  282. /package/dist/{src/web → web}/hooks/use-tool-info.test-d.d.ts +0 -0
  283. /package/dist/{src/web → web}/hooks/use-tool-info.test-d.js +0 -0
  284. /package/dist/{src/web → web}/hooks/use-tool-info.test.d.ts +0 -0
  285. /package/dist/{src/web → web}/hooks/use-user.test.d.ts +0 -0
  286. /package/dist/{src/web → web}/hooks/use-widget-state.d.ts +0 -0
  287. /package/dist/{src/web → web}/hooks/use-widget-state.test.d.ts +0 -0
  288. /package/dist/{src/web → web}/hooks/use-widget-state.test.js +0 -0
  289. /package/dist/{src/web → web}/index.d.ts +0 -0
  290. /package/dist/{src/web → web}/index.js +0 -0
  291. /package/dist/{src/web → web}/mount-widget.d.ts +0 -0
  292. /package/dist/{src/web → web}/plugin/data-llm.test.d.ts +0 -0
  293. /package/dist/{src/web → web}/plugin/data-llm.test.js +0 -0
  294. /package/dist/{src/web → web}/plugin/plugin.d.ts +0 -0
  295. /package/dist/{src/web → web}/plugin/plugin.js +0 -0
  296. /package/dist/{src/web → web}/plugin/transform-data-llm.d.ts +0 -0
  297. /package/dist/{src/web → web}/plugin/transform-data-llm.js +0 -0
  298. /package/dist/{src/web → web}/plugin/transform-data-llm.test.d.ts +0 -0
  299. /package/dist/{src/web → web}/plugin/transform-data-llm.test.js +0 -0
  300. /package/dist/{src/web → web}/proxy.d.ts +0 -0
  301. /package/dist/{src/web → web}/proxy.js +0 -0
package/README.md ADDED
@@ -0,0 +1,143 @@
1
+ <div align="center">
2
+
3
+ <img alt="Skybridge" src="https://raw.githubusercontent.com/alpic-ai/skybridge/main/docs/images/github-banner.png" width="100%">
4
+
5
+ <br />
6
+
7
+ # Skybridge
8
+
9
+ **Build ChatGPT & MCP Apps. The Modern TypeScript Way.**
10
+
11
+ The fullstack TypeScript framework for AI-embedded widgets.<br />
12
+ **Type-safe. React-powered. Platform-agnostic.**
13
+
14
+ <br />
15
+
16
+ [![NPM Version](https://img.shields.io/npm/v/skybridge?color=e90060&style=for-the-badge)](https://www.npmjs.com/package/skybridge)
17
+ [![NPM Downloads](https://img.shields.io/npm/dm/skybridge?color=e90060&style=for-the-badge)](https://www.npmjs.com/package/skybridge)
18
+ [![GitHub License](https://img.shields.io/github/license/alpic-ai/skybridge?color=e90060&style=for-the-badge)](https://github.com/alpic-ai/skybridge/blob/main/LICENSE)
19
+
20
+ <br />
21
+
22
+ [Documentation](https://docs.skybridge.tech) · [Quick Start](https://docs.skybridge.tech/quickstart/create-new-app) · [Showcase](https://docs.skybridge.tech/showcase)
23
+
24
+ </div>
25
+
26
+ <br />
27
+
28
+ ## ✨ Why Skybridge?
29
+
30
+ ChatGPT Apps and MCP Apps let you embed **rich, interactive UIs** directly in AI conversations. But the raw SDKs are low-level—no hooks, no type safety, no dev tools, and no HMR.
31
+
32
+ **Skybridge fixes that.**
33
+
34
+ | | |
35
+ |:--|:--|
36
+ | 👨‍💻 **Full Dev Environment** — HMR, debug traces, and local devtools. No more refresh loops. | ✅ **End-to-End Type Safety** — tRPC-style inference from server to widget. Autocomplete everywhere. |
37
+ | 🔄 **Widget-to-Model Sync** — Keep the model aware of UI state with `data-llm`. Dual surfaces, one source of truth. | ⚒️ **React Query-style Hooks** — `isPending`, `isError`, callbacks. State management you already know. |
38
+ | 🌐 **Platform Agnostic** — Write once, run anywhere. Works with ChatGPT (Apps SDK) and MCP-compatible clients. | 📦 **Showcase Examples** — Production-ready examples to learn from and build upon. |
39
+
40
+ <br />
41
+
42
+ ## 🚀 Get Started
43
+
44
+ **Create a new app:**
45
+
46
+ ```bash
47
+ npm create skybridge@latest
48
+ ```
49
+
50
+ **Or add to an existing project:**
51
+
52
+ ```bash
53
+ npm i skybridge
54
+ yarn add skybridge
55
+ pnpm add skybridge
56
+ bun add skybridge
57
+ deno add skybridge
58
+ ```
59
+
60
+ <div align="center">
61
+
62
+ **👉 [Read the Docs](https://docs.skybridge.tech) 👈**
63
+
64
+ </div>
65
+
66
+ <br />
67
+
68
+ ## 📦 Architecture
69
+
70
+ Skybridge is a fullstack framework with unified server and client modules:
71
+
72
+ - **`skybridge/server`** — Define tools and widgets with full type inference. Extends the MCP SDK.
73
+ - **`skybridge/web`** — React hooks that consume your server types. Works with Apps SDK (ChatGPT) and MCP Apps.
74
+ - **Dev Environment** — Vite plugin with HMR, DevTools emulator, and optimized builds.
75
+
76
+ ### Server
77
+
78
+ ```ts
79
+ import { McpServer } from "skybridge/server";
80
+
81
+ server.registerWidget("flights", {}, {
82
+ inputSchema: { destination: z.string() },
83
+ }, async ({ destination }) => {
84
+ const flights = await searchFlights(destination);
85
+ return { structuredContent: { flights } };
86
+ });
87
+ ```
88
+
89
+ ### Widget
90
+
91
+ ```tsx
92
+ import { useToolInfo } from "skybridge/web";
93
+
94
+ function FlightsWidget() {
95
+ const { output } = useToolInfo();
96
+
97
+ return output.structuredContent.flights.map(flight =>
98
+ <FlightCard key={flight.id} flight={flight} />
99
+ );
100
+ }
101
+ ```
102
+
103
+ <br />
104
+
105
+ ## 🎯 Features at a Glance
106
+
107
+ - **Live Reload** — Vite HMR. See changes instantly without reinstalling.
108
+ - **Typed Hooks** — Full autocomplete for tools, inputs, outputs.
109
+ - **Widget → Tool Calls** — Trigger server actions from UI.
110
+ - **Dual Surface Sync** — Keep model aware of what users see with `data-llm`.
111
+ - **React Query-style API** — `isPending`, `isError`, callbacks.
112
+ - **Platform Agnostic** — Works with ChatGPT (Apps SDK) and MCP Apps clients (Goose, VSCode, etc.).
113
+ - **MCP Compatible** — Extends the official SDK. Works with any MCP client.
114
+
115
+ <br />
116
+
117
+ ## 📖 Showcase
118
+
119
+ Explore production-ready examples:
120
+
121
+ | Example | Description | Demo | Code |
122
+ |---------|-------------|------|------|
123
+ | **Capitals Explorer** | Interactive world map with geolocation and Wikipedia integration | [Try Demo](https://capitals.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/capitals) |
124
+ | **Ecommerce Carousel** | Product carousel with cart, localization, and modals | [Try Demo](https://ecommerce.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/ecom-carousel) |
125
+ | **Everything** | Comprehensive playground showcasing all hooks and features | [Try Demo](https://everything.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/everything) |
126
+
127
+ See all examples in the [Showcase](https://docs.skybridge.tech/showcase) or browse the [examples/](examples/) directory.
128
+
129
+ <br />
130
+
131
+ <div align="center">
132
+
133
+ [![GitHub Discussions](https://img.shields.io/badge/Discussions-Ask%20Questions-blue?style=flat-square&logo=github)](https://github.com/alpic-ai/skybridge/discussions)
134
+ [![GitHub Issues](https://img.shields.io/badge/Issues-Report%20Bugs-red?style=flat-square&logo=github)](https://github.com/alpic-ai/skybridge/issues)
135
+ [![Discord](https://img.shields.io/badge/Discord-Chat-5865F2?style=flat-square&logo=discord&logoColor=white)](https://discord.com/invite/gNAazGueab)
136
+
137
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions
138
+
139
+ <br />
140
+
141
+ **[MIT License](LICENSE)** · Made with ❤️ by **[Alpic](https://alpic.ai)**
142
+
143
+ </div>
package/bin/run.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execute } from "@oclif/core";
4
+
5
+ await execute({ dir: import.meta.url });
@@ -0,0 +1,4 @@
1
+ export declare const Header: ({ version, children, }: {
2
+ version: string;
3
+ children?: React.ReactNode;
4
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ export const Header = ({ version, children, }) => {
4
+ return (_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\u26F0", " ", "Welcome to Skybridge"] }), _jsxs(Text, { color: "cyan", children: [" v", version] }), children] }));
5
+ };
6
+ //# sourceMappingURL=header.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header.js","sourceRoot":"","sources":["../../src/cli/header.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,EACrB,OAAO,EACP,QAAQ,GAIT,EAAE,EAAE;IACH,OAAO,CACL,MAAC,GAAG,IAAC,YAAY,EAAE,CAAC,aAClB,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,EAAC,IAAI,6BACnB,IAAI,4BACD,EACP,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,mBAAI,OAAO,IAAQ,EACpC,QAAQ,IACL,CACP,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type SpawnOptions } from "node:child_process";
2
+ export declare function runCommand(command: string, options?: SpawnOptions): Promise<void>;
@@ -0,0 +1,43 @@
1
+ import { spawn } from "node:child_process";
2
+ export function runCommand(command, options = {
3
+ stdio: ["ignore", "inherit", "inherit"],
4
+ }) {
5
+ return new Promise((resolve, reject) => {
6
+ const stdoutChunks = [];
7
+ const stderrChunks = [];
8
+ const proc = spawn(command, {
9
+ ...options,
10
+ shell: true,
11
+ });
12
+ if (proc.stdout) {
13
+ proc.stdout.on("data", (chunk) => {
14
+ stdoutChunks.push(chunk);
15
+ });
16
+ }
17
+ if (proc.stderr) {
18
+ proc.stderr.on("data", (chunk) => {
19
+ stderrChunks.push(chunk);
20
+ });
21
+ }
22
+ proc.on("close", (code) => {
23
+ if (code === 0) {
24
+ resolve();
25
+ }
26
+ else {
27
+ const stdoutOutput = Buffer.concat(stdoutChunks).toString();
28
+ const stderrOutput = Buffer.concat(stderrChunks).toString();
29
+ const allOutput = [stdoutOutput, stderrOutput]
30
+ .filter((output) => output.trim())
31
+ .join("\n");
32
+ const errorMessage = allOutput
33
+ ? `Command failed with exit code ${code}\n${allOutput}`
34
+ : `Command failed with exit code ${code}`;
35
+ reject(new Error(errorMessage));
36
+ }
37
+ });
38
+ proc.on("error", (error) => {
39
+ reject(error);
40
+ });
41
+ });
42
+ }
43
+ //# sourceMappingURL=run-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-command.js","sourceRoot":"","sources":["../../src/cli/run-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE9D,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,UAAwB;IACtB,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC;CACxC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,MAAM,YAAY,GAAa,EAAE,CAAC;QAElC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE;YAC1B,GAAG,OAAO;YACV,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/B,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/B,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,EAAE,CAAC;YACZ,CAAC;iBAAM,CAAC;gBACN,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC5D,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAC5D,MAAM,SAAS,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC;qBAC3C,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;qBACjC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,MAAM,YAAY,GAAG,SAAS;oBAC5B,CAAC,CAAC,iCAAiC,IAAI,KAAK,SAAS,EAAE;oBACvD,CAAC,CAAC,iCAAiC,IAAI,EAAE,CAAC;gBAC5C,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;YAClC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACzB,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface CommandStep {
2
+ label: string;
3
+ command: string;
4
+ }
5
+ export declare const useExecuteSteps: (steps: CommandStep[]) => {
6
+ currentStep: number;
7
+ status: "error" | "running" | "success";
8
+ error: string | null;
9
+ execute: () => Promise<void>;
10
+ };
@@ -0,0 +1,31 @@
1
+ import { useCallback, useState } from "react";
2
+ import { runCommand } from "./run-command.js";
3
+ export const useExecuteSteps = (steps) => {
4
+ const [currentStep, setCurrentStep] = useState(0);
5
+ const [status, setStatus] = useState("running");
6
+ const [error, setError] = useState(null);
7
+ const execute = useCallback(async () => {
8
+ try {
9
+ for (let i = 0; i < steps.length; i++) {
10
+ const step = steps[i];
11
+ if (step) {
12
+ setCurrentStep(i);
13
+ await runCommand(step.command);
14
+ }
15
+ }
16
+ setStatus("success");
17
+ setImmediate(() => {
18
+ process.exit(0);
19
+ });
20
+ }
21
+ catch (err) {
22
+ setStatus("error");
23
+ setError(err instanceof Error ? err.message : String(err));
24
+ setImmediate(() => {
25
+ process.exit(1);
26
+ });
27
+ }
28
+ }, [steps]);
29
+ return { currentStep, status, error, execute };
30
+ };
31
+ //# sourceMappingURL=use-execute-steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-execute-steps.js","sourceRoot":"","sources":["../../src/cli/use-execute-steps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAO9C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAoB,EAAE,EAAE;IACtD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAS,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAClC,SAAS,CACV,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,IAAI,CAAC;YACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,IAAI,IAAI,EAAE,CAAC;oBACT,cAAc,CAAC,CAAC,CAAC,CAAC;oBAClB,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC;YACD,SAAS,CAAC,SAAS,CAAC,CAAC;YACrB,YAAY,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3D,YAAY,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACjD,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Command } from "@oclif/core";
2
+ import { type CommandStep } from "../cli/use-execute-steps.js";
3
+ export declare const commandSteps: CommandStep[];
4
+ export default class Build extends Command {
5
+ static description: string;
6
+ static examples: string[];
7
+ static flags: {};
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Command } from "@oclif/core";
3
+ import { Box, render, Text } from "ink";
4
+ import { useEffect } from "react";
5
+ import { Header } from "../cli/header.js";
6
+ import { useExecuteSteps } from "../cli/use-execute-steps.js";
7
+ export const commandSteps = [
8
+ {
9
+ label: "Building widgets",
10
+ command: "vite build -c web/vite.config.ts",
11
+ },
12
+ {
13
+ label: "Compiling server",
14
+ command: "shx rm -rf dist && tsc -p tsconfig.server.json",
15
+ },
16
+ {
17
+ label: "Copying static assets",
18
+ command: "shx cp -r web/dist dist/assets",
19
+ },
20
+ ];
21
+ export default class Build extends Command {
22
+ static description = "Build the widgets and MCP server";
23
+ static examples = ["skybridge build"];
24
+ static flags = {};
25
+ async run() {
26
+ const App = () => {
27
+ const { currentStep, status, error, execute } = useExecuteSteps(commandSteps);
28
+ useEffect(() => {
29
+ execute();
30
+ }, [execute]);
31
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Header, { version: this.config.version, children: _jsx(Text, { color: "green", children: " \u2192 building for production\u2026" }) }), commandSteps.map((step, index) => {
32
+ const isCurrent = index === currentStep && status === "running";
33
+ const isCompleted = index < currentStep || status === "success";
34
+ const isError = status === "error" && index === currentStep;
35
+ return (_jsx(Box, { marginBottom: 0, children: _jsxs(Text, { color: isError ? "red" : isCompleted ? "green" : "grey", children: [isError ? "✗" : isCompleted ? "✓" : isCurrent ? "⟳" : "○", " ", step.label] }) }, step.label));
36
+ }), status === "success" && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "green", bold: true, children: "\u2713 Build completed successfully!" }) })), status === "error" && error && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "red", bold: true, children: "\u2717 Build failed" }), _jsx(Box, { marginTop: 1, flexDirection: "column", children: error.split("\n").map((line) => (_jsx(Text, { color: "red", children: line }, line))) })] }))] }));
37
+ };
38
+ render(_jsx(App, {}), {
39
+ exitOnCtrlC: true,
40
+ patchConsole: false,
41
+ });
42
+ }
43
+ }
44
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class Dev extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ "use-forwarded-host": import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Command, Flags } from "@oclif/core";
3
+ import { Box, render, Text } from "ink";
4
+ import { Header } from "../cli/header.js";
5
+ import { runCommand } from "../cli/run-command.js";
6
+ export default class Dev extends Command {
7
+ static description = "Start development server";
8
+ static examples = ["skybridge"];
9
+ static flags = {
10
+ "use-forwarded-host": Flags.boolean({
11
+ description: "Uses the forwarded host header to construct widget URLs instead of localhost, useful when accessing the dev server through a tunnel (e.g., ngrok)",
12
+ }),
13
+ };
14
+ async run() {
15
+ const { flags } = await this.parse(Dev);
16
+ const env = {
17
+ ...process.env,
18
+ ...(flags["use-forwarded-host"]
19
+ ? { SKYBRIDGE_USE_FORWARDED_HOST: "true" }
20
+ : {}),
21
+ };
22
+ runCommand("nodemon --quiet", {
23
+ stdio: ["ignore", "ignore", "inherit"],
24
+ env,
25
+ });
26
+ const App = () => {
27
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, marginLeft: 1, children: [_jsx(Header, { version: this.config.version }), _jsxs(Box, { children: [_jsxs(Text, { color: "green", children: ["\u2192", " "] }), _jsxs(Text, { color: "white", bold: true, children: ["Open DevTools to test your app locally:", " "] }), _jsx(Text, { color: "green", children: "http://localhost:3000/" })] }), _jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsxs(Text, { children: ["MCP server running at:", " "] }), _jsx(Text, { color: "white", bold: true, children: "http://localhost:3000/mcp" })] }), _jsx(Text, { color: "white", underline: true, children: "To test on ChatGPT:" }), _jsxs(Box, { children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsx(Text, { color: "grey", children: "Make your local server accessible with " }), _jsx(Text, { color: "white", bold: true, children: "ngrok http 3000" })] }), _jsx(Box, { marginBottom: 1, children: _jsxs(Text, { children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsx(Text, { color: "grey", children: "Connect to ChatGPT with URL " }), _jsx(Text, { color: "white", bold: true, children: "https://xxxxxx.ngrok-free.app/mcp" })] }) }), _jsx(Box, { children: _jsxs(Text, { children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsx(Text, { children: "Documentation: " }), _jsx(Text, { color: "white", bold: true, children: "https://docs.skybridge.tech/" })] }) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsx(Text, { children: "If you like Skybridge, please " }), _jsxs(Text, { color: "white", bold: true, children: ["give it a star", " "] }), _jsx(Text, { children: "on GitHub: " }), _jsx(Text, { color: "white", underline: true, children: "https://github.com/alpic-ai/skybridge" }), _jsx(Text, { color: "grey", children: " \uD83D\uDE4F" })] }) })] }));
28
+ };
29
+ render(_jsx(App, {}), { exitOnCtrlC: true, patchConsole: false });
30
+ }
31
+ }
32
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class Start extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {};
6
+ run(): Promise<void>;
7
+ }
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { existsSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { Command } from "@oclif/core";
5
+ import { Box, render, Text } from "ink";
6
+ import { Header } from "../cli/header.js";
7
+ import { runCommand } from "../cli/run-command.js";
8
+ export default class Start extends Command {
9
+ static description = "Start production server";
10
+ static examples = ["skybridge start"];
11
+ static flags = {};
12
+ async run() {
13
+ console.clear();
14
+ const distPath = resolve(process.cwd(), "dist/index.js");
15
+ if (!existsSync(distPath)) {
16
+ console.error("❌ Error: dist/index.js not found");
17
+ console.error("");
18
+ console.error("Please build your project first:");
19
+ console.error(" skybridge build");
20
+ console.error("");
21
+ process.exit(1);
22
+ }
23
+ runCommand("node dist/index.js", {
24
+ stdio: ["ignore", "ignore", "inherit"],
25
+ env: { ...process.env, NODE_ENV: "production" },
26
+ });
27
+ const App = () => {
28
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, marginLeft: 1, children: [_jsx(Header, { version: this.config.version }), _jsxs(Box, { children: [_jsx(Text, { children: "Server running at: " }), _jsx(Text, { color: "green", bold: true, children: "http://localhost:3000/mcp" })] })] }));
29
+ };
30
+ render(_jsx(App, {}), { exitOnCtrlC: true, patchConsole: false });
31
+ }
32
+ }
33
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,KAAM,SAAQ,OAAO;IACxC,MAAM,CAAU,WAAW,GAAG,yBAAyB,CAAC;IACxD,MAAM,CAAU,QAAQ,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC/C,MAAM,CAAU,KAAK,GAAG,EAAE,CAAC;IAEpB,KAAK,CAAC,GAAG;QACd,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhB,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;QACzD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAClD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAClD,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,UAAU,CAAC,oBAAoB,EAAE;YAC/B,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC;YACtC,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE;SAChD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,GAAG,EAAE;YACf,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,aACnD,KAAC,MAAM,IAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,GAAI,EACxC,MAAC,GAAG,eACF,KAAC,IAAI,sCAA2B,EAChC,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI,gDAEjB,IACH,IACF,CACP,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,CAAC,KAAC,GAAG,KAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9D,CAAC"}
@@ -1,4 +1,3 @@
1
- export { devtoolsStaticServer } from "./devtoolsStaticServer.js";
2
1
  export type { AnyToolRegistry, InferTools, ToolInput, ToolNames, ToolOutput, ToolResponseMetadata, } from "./inferUtilityTypes.js";
3
2
  export type { McpServerTypes, ToolDef, WidgetHostType } from "./server.js";
4
3
  export { McpServer } from "./server.js";
@@ -1,4 +1,3 @@
1
- export { devtoolsStaticServer } from "./devtoolsStaticServer.js";
2
1
  export { McpServer } from "./server.js";
3
2
  export { widgetsDevServer } from "./widgetsDevServer.js";
4
3
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inferUtilityTypes.js","sourceRoot":"","sources":["../../src/server/inferUtilityTypes.ts"],"names":[],"mappings":""}
@@ -1,3 +1,4 @@
1
+ import type { McpUiResourceMeta } from "@modelcontextprotocol/ext-apps";
1
2
  import { McpServer as McpServerBase, type RegisteredTool } from "@modelcontextprotocol/sdk/server/mcp.js";
2
3
  import type { AnySchema, SchemaOutput, ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js";
3
4
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
@@ -7,8 +8,32 @@ export type ToolDef<TInput = unknown, TOutput = unknown, TResponseMetadata = unk
7
8
  output: TOutput;
8
9
  responseMetadata: TResponseMetadata;
9
10
  };
11
+ /**
12
+ * Extended MCP Apps CSP with upcoming fields from ext-apps PR #158
13
+ * and Skybridge-specific fields for OpenAI compatibility
14
+ * @see https://github.com/modelcontextprotocol/ext-apps/pull/158
15
+ */
16
+ type ExtendedMcpUiResourceCsp = McpUiResourceMeta["csp"] & {
17
+ /**
18
+ * Origins that can receive openExternal redirects without safe-link modal (OpenAI-specific)
19
+ * @see https://developers.openai.com/apps-sdk/reference#component-resource-_meta-fields
20
+ */
21
+ redirectDomains?: string[];
22
+ };
23
+ /** Extended MCP Apps resource metadata with upcoming CSP fields */
24
+ type ExtendedMcpUiResourceMeta = Omit<McpUiResourceMeta, "csp"> & {
25
+ csp?: ExtendedMcpUiResourceCsp;
26
+ };
27
+ /** User-provided resource configuration with optional CSP override */
28
+ export type WidgetResourceMeta = {
29
+ ui?: ExtendedMcpUiResourceMeta;
30
+ } & Resource["_meta"];
10
31
  export type WidgetHostType = "apps-sdk" | "mcp-app";
11
- type McpServerOriginalResourceConfig = Omit<Resource, "uri" | "name" | "mimeType">;
32
+ type McpServerOriginalResourceConfig = Omit<Resource, "uri" | "name" | "mimeType" | "_meta"> & {
33
+ _meta?: WidgetResourceMeta;
34
+ /** Restrict host types to a specific subset */
35
+ hosts?: WidgetHostType[];
36
+ };
12
37
  type McpServerOriginalToolConfig = Omit<Parameters<typeof McpServerBase.prototype.registerTool<ZodRawShapeCompat, ZodRawShapeCompat>>[1], "inputSchema" | "outputSchema">;
13
38
  type Simplify<T> = {
14
39
  [K in keyof T]: T[K];
@@ -0,0 +1,139 @@
1
+ import { readFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { McpServer as McpServerBase, } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { mergeWith, union } from "es-toolkit";
5
+ import { templateHelper } from "./templateHelper.js";
6
+ const mergeWithUnion = (target, source) => {
7
+ return mergeWith(target, source, (targetVal, sourceVal) => {
8
+ if (Array.isArray(targetVal) && Array.isArray(sourceVal)) {
9
+ return union(targetVal, sourceVal);
10
+ }
11
+ });
12
+ };
13
+ export class McpServer extends McpServerBase {
14
+ registerWidget(name, resourceConfig, toolConfig, toolCallback) {
15
+ const userMeta = resourceConfig._meta;
16
+ const toolMeta = {
17
+ ...toolConfig._meta,
18
+ };
19
+ if (!resourceConfig.hosts || resourceConfig.hosts.includes("apps-sdk")) {
20
+ const widgetConfig = {
21
+ hostType: "apps-sdk",
22
+ uri: `ui://widgets/apps-sdk/${name}.html`,
23
+ mimeType: "text/html+skybridge",
24
+ buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
25
+ const userUi = userMeta?.ui;
26
+ const userCsp = userUi?.csp;
27
+ const defaults = {
28
+ "openai/widgetCSP": {
29
+ resource_domains: resourceDomains,
30
+ connect_domains: connectDomains,
31
+ },
32
+ "openai/widgetDomain": domain,
33
+ "openai/widgetDescription": toolConfig.description,
34
+ };
35
+ const fromUi = {
36
+ "openai/widgetCSP": {
37
+ resource_domains: userCsp?.resourceDomains,
38
+ connect_domains: userCsp?.connectDomains,
39
+ frame_domains: userCsp?.frameDomains,
40
+ redirect_domains: userCsp?.redirectDomains,
41
+ },
42
+ "openai/widgetDomain": userUi?.domain,
43
+ "openai/widgetPrefersBorder": userUi?.prefersBorder,
44
+ };
45
+ const directOpenaiKeys = Object.fromEntries(Object.entries(userMeta ?? {}).filter(([key]) => key.startsWith("openai/")));
46
+ return mergeWithUnion(mergeWithUnion(defaults, fromUi), directOpenaiKeys);
47
+ },
48
+ };
49
+ this.registerWidgetResource({
50
+ name,
51
+ widgetConfig,
52
+ resourceConfig,
53
+ });
54
+ toolMeta["openai/outputTemplate"] = widgetConfig.uri;
55
+ }
56
+ if (!resourceConfig.hosts || resourceConfig.hosts.includes("mcp-app")) {
57
+ const widgetConfig = {
58
+ hostType: "mcp-app",
59
+ uri: `ui://widgets/ext-apps/${name}.html`,
60
+ mimeType: "text/html;profile=mcp-app",
61
+ buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
62
+ const defaults = {
63
+ ui: {
64
+ csp: {
65
+ resourceDomains,
66
+ connectDomains,
67
+ },
68
+ domain,
69
+ },
70
+ };
71
+ return mergeWithUnion(defaults, { ui: userMeta?.ui });
72
+ },
73
+ };
74
+ this.registerWidgetResource({
75
+ name,
76
+ widgetConfig,
77
+ resourceConfig,
78
+ });
79
+ toolMeta.ui = { resourceUri: widgetConfig.uri };
80
+ }
81
+ this.registerTool(name, {
82
+ ...toolConfig,
83
+ _meta: toolMeta,
84
+ }, toolCallback);
85
+ return this;
86
+ }
87
+ registerTool(name, config, cb) {
88
+ super.registerTool(name, config, cb);
89
+ return this;
90
+ }
91
+ registerWidgetResource({ name, widgetConfig, resourceConfig, }) {
92
+ const { hostType, uri: widgetUri, mimeType, buildContentMeta, } = widgetConfig;
93
+ this.registerResource(name, widgetUri, { ...resourceConfig, _meta: resourceConfig._meta }, async (uri, extra) => {
94
+ const isProduction = process.env.NODE_ENV === "production";
95
+ const useForwardedHost = process.env.SKYBRIDGE_USE_FORWARDED_HOST === "true";
96
+ const serverUrl = isProduction || useForwardedHost
97
+ ? `https://${extra?.requestInfo?.headers?.["x-forwarded-host"] ?? extra?.requestInfo?.headers?.host}`
98
+ : "http://localhost:3000";
99
+ const html = isProduction
100
+ ? templateHelper.renderProduction({
101
+ hostType,
102
+ serverUrl,
103
+ widgetFile: this.lookupDistFileWithIndexFallback(`src/widgets/${name}`),
104
+ styleFile: this.lookupDistFile("style.css"),
105
+ })
106
+ : templateHelper.renderDevelopment({
107
+ hostType,
108
+ serverUrl,
109
+ widgetName: name,
110
+ });
111
+ const VITE_HMR_WEBSOCKET_DEFAULT_URL = "ws://localhost:24678";
112
+ const contentMeta = buildContentMeta({
113
+ resourceDomains: [serverUrl],
114
+ connectDomains: !isProduction ? [VITE_HMR_WEBSOCKET_DEFAULT_URL] : [],
115
+ domain: serverUrl,
116
+ baseUriDomains: [serverUrl],
117
+ });
118
+ return {
119
+ contents: [
120
+ { uri: uri.href, mimeType, text: html, _meta: contentMeta },
121
+ ],
122
+ };
123
+ });
124
+ }
125
+ lookupDistFile(key) {
126
+ const manifest = this.readManifest();
127
+ return manifest[key]?.file;
128
+ }
129
+ lookupDistFileWithIndexFallback(basePath) {
130
+ const manifest = this.readManifest();
131
+ const flatFileKey = `${basePath}.tsx`;
132
+ const indexFileKey = `${basePath}/index.tsx`;
133
+ return manifest[flatFileKey]?.file ?? manifest[indexFileKey]?.file;
134
+ }
135
+ readManifest() {
136
+ return JSON.parse(readFileSync(path.join(process.cwd(), "dist", "assets", ".vite", "manifest.json"), "utf-8"));
137
+ }
138
+ }
139
+ //# sourceMappingURL=server.js.map