skybridge 0.0.0-dev.e3e0986 → 0.0.0-dev.e434f62

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 (444) hide show
  1. package/LICENSE +21 -674
  2. package/README.md +95 -262
  3. package/bin/run.js +5 -0
  4. package/dist/cli/detect-port.d.ts +18 -0
  5. package/dist/cli/detect-port.js +61 -0
  6. package/dist/cli/detect-port.js.map +1 -0
  7. package/dist/cli/header.d.ts +4 -0
  8. package/dist/cli/header.js +6 -0
  9. package/dist/cli/header.js.map +1 -0
  10. package/dist/cli/run-command.d.ts +2 -0
  11. package/dist/cli/run-command.js +43 -0
  12. package/dist/cli/run-command.js.map +1 -0
  13. package/dist/cli/telemetry.d.ts +7 -0
  14. package/dist/cli/telemetry.js +123 -0
  15. package/dist/cli/telemetry.js.map +1 -0
  16. package/dist/cli/tunnel-control-server.d.ts +9 -0
  17. package/dist/cli/tunnel-control-server.js +31 -0
  18. package/dist/cli/tunnel-control-server.js.map +1 -0
  19. package/dist/cli/tunnel-control-server.test.js +39 -0
  20. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  21. package/dist/cli/tunnel-handler.d.ts +3 -0
  22. package/dist/cli/tunnel-handler.js +48 -0
  23. package/dist/cli/tunnel-handler.js.map +1 -0
  24. package/dist/cli/tunnel-handler.test.js +105 -0
  25. package/dist/cli/tunnel-handler.test.js.map +1 -0
  26. package/dist/cli/tunnel.d.ts +57 -0
  27. package/dist/cli/tunnel.js +154 -0
  28. package/dist/cli/tunnel.js.map +1 -0
  29. package/dist/cli/tunnel.test.js +190 -0
  30. package/dist/cli/tunnel.test.js.map +1 -0
  31. package/dist/cli/types.d.ts +5 -0
  32. package/dist/cli/types.js +2 -0
  33. package/dist/cli/types.js.map +1 -0
  34. package/dist/cli/use-execute-steps.d.ts +11 -0
  35. package/dist/cli/use-execute-steps.js +36 -0
  36. package/dist/cli/use-execute-steps.js.map +1 -0
  37. package/dist/cli/use-messages.d.ts +3 -0
  38. package/dist/cli/use-messages.js +11 -0
  39. package/dist/cli/use-messages.js.map +1 -0
  40. package/dist/cli/use-nodemon.d.ts +2 -0
  41. package/dist/cli/use-nodemon.js +73 -0
  42. package/dist/cli/use-nodemon.js.map +1 -0
  43. package/dist/cli/use-open-browser.d.ts +1 -0
  44. package/dist/cli/use-open-browser.js +44 -0
  45. package/dist/cli/use-open-browser.js.map +1 -0
  46. package/dist/cli/use-tunnel.d.ts +14 -0
  47. package/dist/cli/use-tunnel.js +131 -0
  48. package/dist/cli/use-tunnel.js.map +1 -0
  49. package/dist/cli/use-typescript-check.d.ts +9 -0
  50. package/dist/cli/use-typescript-check.js +94 -0
  51. package/dist/cli/use-typescript-check.js.map +1 -0
  52. package/dist/commands/build.d.ts +9 -0
  53. package/dist/commands/build.js +102 -0
  54. package/dist/commands/build.js.map +1 -0
  55. package/dist/commands/dev.d.ts +12 -0
  56. package/dist/commands/dev.js +80 -0
  57. package/dist/commands/dev.js.map +1 -0
  58. package/dist/commands/start.d.ts +9 -0
  59. package/dist/commands/start.js +49 -0
  60. package/dist/commands/start.js.map +1 -0
  61. package/dist/commands/telemetry/disable.d.ts +5 -0
  62. package/dist/commands/telemetry/disable.js +14 -0
  63. package/dist/commands/telemetry/disable.js.map +1 -0
  64. package/dist/commands/telemetry/enable.d.ts +5 -0
  65. package/dist/commands/telemetry/enable.js +14 -0
  66. package/dist/commands/telemetry/enable.js.map +1 -0
  67. package/dist/commands/telemetry/status.d.ts +5 -0
  68. package/dist/commands/telemetry/status.js +14 -0
  69. package/dist/commands/telemetry/status.js.map +1 -0
  70. package/dist/server/asset-base-url-transform-plugin.d.ts +10 -0
  71. package/dist/server/asset-base-url-transform-plugin.js +33 -0
  72. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  73. package/dist/server/asset-base-url-transform-plugin.test.js +84 -0
  74. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  75. package/dist/server/content-helpers.d.ts +27 -0
  76. package/dist/server/content-helpers.js +46 -0
  77. package/dist/server/content-helpers.js.map +1 -0
  78. package/dist/server/content-helpers.test.js +70 -0
  79. package/dist/server/content-helpers.test.js.map +1 -0
  80. package/dist/server/express.d.ts +11 -0
  81. package/dist/server/express.js +101 -0
  82. package/dist/server/express.js.map +1 -0
  83. package/dist/server/express.test.js +430 -0
  84. package/dist/server/express.test.js.map +1 -0
  85. package/dist/server/index.d.ts +6 -0
  86. package/dist/server/index.js +4 -0
  87. package/dist/server/index.js.map +1 -0
  88. package/dist/server/inferUtilityTypes.d.ts +64 -0
  89. package/dist/server/inferUtilityTypes.js.map +1 -0
  90. package/dist/server/metric.d.ts +14 -0
  91. package/dist/server/metric.js +62 -0
  92. package/dist/server/metric.js.map +1 -0
  93. package/dist/server/middleware.d.ts +124 -0
  94. package/dist/server/middleware.js +93 -0
  95. package/dist/server/middleware.js.map +1 -0
  96. package/dist/server/middleware.test-d.js +75 -0
  97. package/dist/server/middleware.test-d.js.map +1 -0
  98. package/dist/server/middleware.test.js +493 -0
  99. package/dist/server/middleware.test.js.map +1 -0
  100. package/dist/server/server.d.ts +203 -0
  101. package/dist/server/server.js +523 -0
  102. package/dist/server/server.js.map +1 -0
  103. package/dist/{src/server → server}/templateHelper.d.ts +5 -4
  104. package/dist/server/templateHelper.js +11 -0
  105. package/dist/server/templateHelper.js.map +1 -0
  106. package/dist/server/templates.generated.d.ts +4 -0
  107. package/dist/server/templates.generated.js +47 -0
  108. package/dist/server/templates.generated.js.map +1 -0
  109. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  110. package/dist/server/tunnel-proxy-router.js +110 -0
  111. package/dist/server/tunnel-proxy-router.js.map +1 -0
  112. package/dist/server/tunnel-proxy-router.test.js +229 -0
  113. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  114. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  115. package/dist/server/view-resource-resolution.test.js +90 -0
  116. package/dist/server/view-resource-resolution.test.js.map +1 -0
  117. package/dist/server/viewsDevServer.d.ts +14 -0
  118. package/dist/server/viewsDevServer.js +45 -0
  119. package/dist/server/viewsDevServer.js.map +1 -0
  120. package/dist/test/utils.d.ts +127 -0
  121. package/dist/test/utils.js +247 -0
  122. package/dist/test/utils.js.map +1 -0
  123. package/dist/test/view.test.js +523 -0
  124. package/dist/test/view.test.js.map +1 -0
  125. package/dist/version.d.ts +1 -0
  126. package/dist/version.js +3 -0
  127. package/dist/version.js.map +1 -0
  128. package/dist/web/bridges/apps-sdk/adaptor.d.ts +26 -0
  129. package/dist/web/bridges/apps-sdk/adaptor.js +102 -0
  130. package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -0
  131. package/dist/web/bridges/apps-sdk/bridge.d.ts +10 -0
  132. package/dist/web/bridges/apps-sdk/bridge.js +46 -0
  133. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  134. package/dist/web/bridges/apps-sdk/index.d.ts +5 -0
  135. package/dist/web/bridges/apps-sdk/index.js +5 -0
  136. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  137. package/dist/web/bridges/apps-sdk/types.d.ts +133 -0
  138. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  139. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +2 -0
  140. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +7 -0
  141. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  142. package/dist/web/bridges/get-adaptor.d.ts +2 -0
  143. package/dist/web/bridges/get-adaptor.js +8 -0
  144. package/dist/web/bridges/get-adaptor.js.map +1 -0
  145. package/dist/web/bridges/index.d.ts +5 -0
  146. package/dist/web/bridges/index.js +6 -0
  147. package/dist/web/bridges/index.js.map +1 -0
  148. package/dist/web/bridges/mcp-app/adaptor.d.ts +50 -0
  149. package/dist/web/bridges/mcp-app/adaptor.js +271 -0
  150. package/dist/web/bridges/mcp-app/adaptor.js.map +1 -0
  151. package/dist/web/bridges/mcp-app/bridge.d.ts +26 -0
  152. package/dist/web/bridges/mcp-app/bridge.js +102 -0
  153. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  154. package/dist/web/bridges/mcp-app/index.d.ts +4 -0
  155. package/dist/web/bridges/mcp-app/index.js +4 -0
  156. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  157. package/dist/web/bridges/mcp-app/types.d.ts +8 -0
  158. package/dist/web/bridges/mcp-app/types.js +2 -0
  159. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  160. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +7 -0
  161. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +7 -0
  162. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  163. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +26 -0
  164. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  165. package/dist/web/bridges/types.d.ts +117 -0
  166. package/dist/web/bridges/types.js +2 -0
  167. package/dist/web/bridges/types.js.map +1 -0
  168. package/dist/web/bridges/use-host-context.d.ts +2 -0
  169. package/dist/web/bridges/use-host-context.js +8 -0
  170. package/dist/web/bridges/use-host-context.js.map +1 -0
  171. package/dist/web/components/modal-provider.d.ts +4 -0
  172. package/dist/web/components/modal-provider.js +45 -0
  173. package/dist/web/components/modal-provider.js.map +1 -0
  174. package/dist/web/create-store.d.ts +3 -0
  175. package/dist/web/create-store.js +38 -0
  176. package/dist/web/create-store.js.map +1 -0
  177. package/dist/web/create-store.test.js +129 -0
  178. package/dist/web/create-store.test.js.map +1 -0
  179. package/dist/web/data-llm.d.ts +14 -0
  180. package/dist/web/data-llm.js +72 -0
  181. package/dist/web/data-llm.js.map +1 -0
  182. package/dist/web/data-llm.test.js +142 -0
  183. package/dist/web/data-llm.test.js.map +1 -0
  184. package/dist/web/generate-helpers.d.ts +118 -0
  185. package/dist/web/generate-helpers.js +113 -0
  186. package/dist/web/generate-helpers.js.map +1 -0
  187. package/dist/web/generate-helpers.test-d.js +209 -0
  188. package/dist/web/generate-helpers.test-d.js.map +1 -0
  189. package/dist/web/generate-helpers.test.d.ts +1 -0
  190. package/dist/web/generate-helpers.test.js +17 -0
  191. package/dist/web/generate-helpers.test.js.map +1 -0
  192. package/dist/web/helpers/state.d.ts +7 -0
  193. package/dist/web/helpers/state.js +45 -0
  194. package/dist/web/helpers/state.js.map +1 -0
  195. package/dist/web/helpers/state.test.d.ts +1 -0
  196. package/dist/web/helpers/state.test.js +53 -0
  197. package/dist/web/helpers/state.test.js.map +1 -0
  198. package/dist/web/hooks/index.d.ts +13 -0
  199. package/dist/web/hooks/index.js +14 -0
  200. package/dist/web/hooks/index.js.map +1 -0
  201. package/dist/web/hooks/test/utils.d.ts +16 -0
  202. package/dist/web/hooks/test/utils.js +64 -0
  203. package/dist/web/hooks/test/utils.js.map +1 -0
  204. package/dist/web/hooks/use-call-tool.d.ts +101 -0
  205. package/dist/{src/web → web}/hooks/use-call-tool.js +19 -19
  206. package/dist/web/hooks/use-call-tool.js.map +1 -0
  207. package/dist/web/hooks/use-call-tool.test-d.d.ts +1 -0
  208. package/dist/web/hooks/use-call-tool.test-d.js +104 -0
  209. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  210. package/dist/web/hooks/use-call-tool.test.d.ts +1 -0
  211. package/dist/{src/web → web}/hooks/use-call-tool.test.js +40 -17
  212. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  213. package/dist/web/hooks/use-display-mode.d.ts +4 -0
  214. package/dist/web/hooks/use-display-mode.js +9 -0
  215. package/dist/web/hooks/use-display-mode.js.map +1 -0
  216. package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
  217. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  218. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  219. package/dist/web/hooks/use-display-mode.test.d.ts +1 -0
  220. package/dist/{src/web → web}/hooks/use-display-mode.test.js +3 -2
  221. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  222. package/dist/web/hooks/use-files.d.ts +7 -0
  223. package/dist/web/hooks/use-files.js +10 -0
  224. package/dist/web/hooks/use-files.js.map +1 -0
  225. package/dist/web/hooks/use-files.test.d.ts +1 -0
  226. package/dist/web/hooks/use-files.test.js +54 -0
  227. package/dist/web/hooks/use-files.test.js.map +1 -0
  228. package/dist/web/hooks/use-layout.d.ts +22 -0
  229. package/dist/web/hooks/use-layout.js +23 -0
  230. package/dist/web/hooks/use-layout.js.map +1 -0
  231. package/dist/web/hooks/use-layout.test.d.ts +1 -0
  232. package/dist/web/hooks/use-layout.test.js +96 -0
  233. package/dist/web/hooks/use-layout.test.js.map +1 -0
  234. package/dist/web/hooks/use-open-external.d.ts +3 -0
  235. package/dist/web/hooks/use-open-external.js +8 -0
  236. package/dist/web/hooks/use-open-external.js.map +1 -0
  237. package/dist/web/hooks/use-open-external.test.d.ts +1 -0
  238. package/dist/web/hooks/use-open-external.test.js +65 -0
  239. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  240. package/dist/web/hooks/use-request-close.d.ts +2 -0
  241. package/dist/web/hooks/use-request-close.js +8 -0
  242. package/dist/web/hooks/use-request-close.js.map +1 -0
  243. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  244. package/dist/web/hooks/use-request-close.test.js +52 -0
  245. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  246. package/dist/web/hooks/use-request-modal.d.ts +9 -0
  247. package/dist/web/hooks/use-request-modal.js +16 -0
  248. package/dist/web/hooks/use-request-modal.js.map +1 -0
  249. package/dist/web/hooks/use-request-modal.test.d.ts +1 -0
  250. package/dist/web/hooks/use-request-modal.test.js +61 -0
  251. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  252. package/dist/web/hooks/use-request-size.d.ts +3 -0
  253. package/dist/web/hooks/use-request-size.js +8 -0
  254. package/dist/web/hooks/use-request-size.js.map +1 -0
  255. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  256. package/dist/web/hooks/use-request-size.test.js +65 -0
  257. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  258. package/dist/web/hooks/use-send-follow-up-message.d.ts +2 -0
  259. package/dist/web/hooks/use-send-follow-up-message.js +8 -0
  260. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  261. package/dist/web/hooks/use-set-open-in-app-url.d.ts +1 -0
  262. package/dist/web/hooks/use-set-open-in-app-url.js +8 -0
  263. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  264. package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
  265. package/dist/web/hooks/use-set-open-in-app-url.test.js +43 -0
  266. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  267. package/dist/{src/web → web}/hooks/use-tool-info.d.ts +13 -2
  268. package/dist/web/hooks/use-tool-info.js +26 -0
  269. package/dist/web/hooks/use-tool-info.js.map +1 -0
  270. package/dist/web/hooks/use-tool-info.test-d.d.ts +1 -0
  271. package/dist/{src/web → web}/hooks/use-tool-info.test-d.js +40 -5
  272. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  273. package/dist/web/hooks/use-tool-info.test.d.ts +1 -0
  274. package/dist/web/hooks/use-tool-info.test.js +130 -0
  275. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  276. package/dist/web/hooks/use-user.d.ts +18 -0
  277. package/dist/web/hooks/use-user.js +35 -0
  278. package/dist/web/hooks/use-user.js.map +1 -0
  279. package/dist/web/hooks/use-user.test.d.ts +1 -0
  280. package/dist/web/hooks/use-user.test.js +122 -0
  281. package/dist/web/hooks/use-user.test.js.map +1 -0
  282. package/dist/web/hooks/use-view-state.d.ts +4 -0
  283. package/dist/web/hooks/use-view-state.js +32 -0
  284. package/dist/web/hooks/use-view-state.js.map +1 -0
  285. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  286. package/dist/web/hooks/use-view-state.test.js +177 -0
  287. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  288. package/dist/web/index.d.ts +7 -0
  289. package/dist/web/index.js +8 -0
  290. package/dist/web/index.js.map +1 -0
  291. package/dist/web/mount-view.d.ts +1 -0
  292. package/dist/{src/web/mount-widget.js → web/mount-view.js} +11 -3
  293. package/dist/web/mount-view.js.map +1 -0
  294. package/dist/web/plugin/data-llm.test.d.ts +1 -0
  295. package/dist/web/plugin/data-llm.test.js +81 -0
  296. package/dist/web/plugin/data-llm.test.js.map +1 -0
  297. package/dist/web/plugin/plugin.d.ts +5 -0
  298. package/dist/web/plugin/plugin.js +156 -0
  299. package/dist/web/plugin/plugin.js.map +1 -0
  300. package/dist/web/plugin/scan-views.d.ts +16 -0
  301. package/dist/web/plugin/scan-views.js +88 -0
  302. package/dist/web/plugin/scan-views.js.map +1 -0
  303. package/dist/web/plugin/scan-views.test.d.ts +1 -0
  304. package/dist/web/plugin/scan-views.test.js +99 -0
  305. package/dist/web/plugin/scan-views.test.js.map +1 -0
  306. package/dist/web/plugin/transform-data-llm.d.ts +12 -0
  307. package/dist/web/plugin/transform-data-llm.js +96 -0
  308. package/dist/web/plugin/transform-data-llm.js.map +1 -0
  309. package/dist/web/plugin/transform-data-llm.test.d.ts +1 -0
  310. package/dist/web/plugin/transform-data-llm.test.js +81 -0
  311. package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
  312. package/dist/web/plugin/validate-view.d.ts +1 -0
  313. package/dist/web/plugin/validate-view.js +9 -0
  314. package/dist/web/plugin/validate-view.js.map +1 -0
  315. package/dist/web/plugin/validate-view.test.d.ts +1 -0
  316. package/dist/web/plugin/validate-view.test.js +24 -0
  317. package/dist/web/plugin/validate-view.test.js.map +1 -0
  318. package/dist/{src/web → web}/proxy.js +6 -2
  319. package/dist/web/proxy.js.map +1 -0
  320. package/dist/web/types.d.ts +16 -0
  321. package/dist/web/types.js +2 -0
  322. package/dist/web/types.js.map +1 -0
  323. package/package.json +81 -36
  324. package/tsconfig.base.json +33 -0
  325. package/dist/src/server/index.d.ts +0 -4
  326. package/dist/src/server/index.js +0 -3
  327. package/dist/src/server/index.js.map +0 -1
  328. package/dist/src/server/inferUtilityTypes.d.ts +0 -33
  329. package/dist/src/server/inferUtilityTypes.js.map +0 -1
  330. package/dist/src/server/server.d.ts +0 -19
  331. package/dist/src/server/server.js +0 -58
  332. package/dist/src/server/server.js.map +0 -1
  333. package/dist/src/server/templateHelper.js +0 -29
  334. package/dist/src/server/templateHelper.js.map +0 -1
  335. package/dist/src/server/templates/development.hbs +0 -12
  336. package/dist/src/server/templates/production.hbs +0 -6
  337. package/dist/src/server/widgetsDevServer.d.ts +0 -12
  338. package/dist/src/server/widgetsDevServer.js +0 -39
  339. package/dist/src/server/widgetsDevServer.js.map +0 -1
  340. package/dist/src/test/utils.d.ts +0 -28
  341. package/dist/src/test/utils.js +0 -43
  342. package/dist/src/test/utils.js.map +0 -1
  343. package/dist/src/test/widget.test.js +0 -90
  344. package/dist/src/test/widget.test.js.map +0 -1
  345. package/dist/src/web/hooks/index.d.ts +0 -14
  346. package/dist/src/web/hooks/index.js +0 -15
  347. package/dist/src/web/hooks/index.js.map +0 -1
  348. package/dist/src/web/hooks/use-call-tool.d.ts +0 -62
  349. package/dist/src/web/hooks/use-call-tool.js.map +0 -1
  350. package/dist/src/web/hooks/use-call-tool.test.js.map +0 -1
  351. package/dist/src/web/hooks/use-display-mode.d.ts +0 -4
  352. package/dist/src/web/hooks/use-display-mode.js +0 -7
  353. package/dist/src/web/hooks/use-display-mode.js.map +0 -1
  354. package/dist/src/web/hooks/use-display-mode.test.js.map +0 -1
  355. package/dist/src/web/hooks/use-files.d.ts +0 -10
  356. package/dist/src/web/hooks/use-files.js +0 -7
  357. package/dist/src/web/hooks/use-files.js.map +0 -1
  358. package/dist/src/web/hooks/use-files.test.js +0 -29
  359. package/dist/src/web/hooks/use-files.test.js.map +0 -1
  360. package/dist/src/web/hooks/use-locale.d.ts +0 -1
  361. package/dist/src/web/hooks/use-locale.js +0 -5
  362. package/dist/src/web/hooks/use-locale.js.map +0 -1
  363. package/dist/src/web/hooks/use-locale.test.js +0 -21
  364. package/dist/src/web/hooks/use-locale.test.js.map +0 -1
  365. package/dist/src/web/hooks/use-open-external.d.ts +0 -1
  366. package/dist/src/web/hooks/use-open-external.js +0 -6
  367. package/dist/src/web/hooks/use-open-external.js.map +0 -1
  368. package/dist/src/web/hooks/use-open-external.test.js +0 -24
  369. package/dist/src/web/hooks/use-open-external.test.js.map +0 -1
  370. package/dist/src/web/hooks/use-openai-global.d.ts +0 -2
  371. package/dist/src/web/hooks/use-openai-global.js +0 -23
  372. package/dist/src/web/hooks/use-openai-global.js.map +0 -1
  373. package/dist/src/web/hooks/use-request-modal.d.ts +0 -6
  374. package/dist/src/web/hooks/use-request-modal.js +0 -9
  375. package/dist/src/web/hooks/use-request-modal.js.map +0 -1
  376. package/dist/src/web/hooks/use-request-modal.test.js +0 -24
  377. package/dist/src/web/hooks/use-request-modal.test.js.map +0 -1
  378. package/dist/src/web/hooks/use-send-follow-up-message.d.ts +0 -1
  379. package/dist/src/web/hooks/use-send-follow-up-message.js +0 -11
  380. package/dist/src/web/hooks/use-send-follow-up-message.js.map +0 -1
  381. package/dist/src/web/hooks/use-theme.d.ts +0 -1
  382. package/dist/src/web/hooks/use-theme.js +0 -5
  383. package/dist/src/web/hooks/use-theme.js.map +0 -1
  384. package/dist/src/web/hooks/use-theme.test.js +0 -26
  385. package/dist/src/web/hooks/use-theme.test.js.map +0 -1
  386. package/dist/src/web/hooks/use-tool-info.js +0 -22
  387. package/dist/src/web/hooks/use-tool-info.js.map +0 -1
  388. package/dist/src/web/hooks/use-tool-info.test-d.js.map +0 -1
  389. package/dist/src/web/hooks/use-tool-info.test.js +0 -59
  390. package/dist/src/web/hooks/use-tool-info.test.js.map +0 -1
  391. package/dist/src/web/hooks/use-tool-output.d.ts +0 -4
  392. package/dist/src/web/hooks/use-tool-output.js +0 -9
  393. package/dist/src/web/hooks/use-tool-output.js.map +0 -1
  394. package/dist/src/web/hooks/use-tool-response-metadata.d.ts +0 -4
  395. package/dist/src/web/hooks/use-tool-response-metadata.js +0 -8
  396. package/dist/src/web/hooks/use-tool-response-metadata.js.map +0 -1
  397. package/dist/src/web/hooks/use-user-agent.d.ts +0 -1
  398. package/dist/src/web/hooks/use-user-agent.js +0 -5
  399. package/dist/src/web/hooks/use-user-agent.js.map +0 -1
  400. package/dist/src/web/hooks/use-user-agent.test.js +0 -31
  401. package/dist/src/web/hooks/use-user-agent.test.js.map +0 -1
  402. package/dist/src/web/hooks/use-widget-state.d.ts +0 -4
  403. package/dist/src/web/hooks/use-widget-state.js +0 -30
  404. package/dist/src/web/hooks/use-widget-state.js.map +0 -1
  405. package/dist/src/web/hooks/use-widget-state.test.js +0 -60
  406. package/dist/src/web/hooks/use-widget-state.test.js.map +0 -1
  407. package/dist/src/web/index.d.ts +0 -5
  408. package/dist/src/web/index.js +0 -6
  409. package/dist/src/web/index.js.map +0 -1
  410. package/dist/src/web/mount-widget.d.ts +0 -1
  411. package/dist/src/web/mount-widget.js.map +0 -1
  412. package/dist/src/web/plugin.d.ts +0 -2
  413. package/dist/src/web/plugin.js +0 -28
  414. package/dist/src/web/plugin.js.map +0 -1
  415. package/dist/src/web/proxy.js.map +0 -1
  416. package/dist/src/web/typed-hooks.d.ts +0 -61
  417. package/dist/src/web/typed-hooks.js +0 -61
  418. package/dist/src/web/typed-hooks.js.map +0 -1
  419. package/dist/src/web/typed-hooks.test-d.js +0 -72
  420. package/dist/src/web/typed-hooks.test-d.js.map +0 -1
  421. package/dist/src/web/typed-hooks.test.js +0 -10
  422. package/dist/src/web/typed-hooks.test.js.map +0 -1
  423. package/dist/src/web/types.d.ts +0 -119
  424. package/dist/src/web/types.js.map +0 -1
  425. package/dist/vitest.config.d.ts +0 -2
  426. package/dist/vitest.config.js +0 -8
  427. package/dist/vitest.config.js.map +0 -1
  428. /package/dist/{src/test/widget.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
  429. /package/dist/{src/web/hooks/use-call-tool.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
  430. /package/dist/{src/web/hooks/use-display-mode.test.d.ts → cli/tunnel.test.d.ts} +0 -0
  431. /package/dist/{src/web/hooks/use-files.test.d.ts → server/asset-base-url-transform-plugin.test.d.ts} +0 -0
  432. /package/dist/{src/web/hooks/use-locale.test.d.ts → server/content-helpers.test.d.ts} +0 -0
  433. /package/dist/{src/web/hooks/use-open-external.test.d.ts → server/express.test.d.ts} +0 -0
  434. /package/dist/{src/server → server}/inferUtilityTypes.js +0 -0
  435. /package/dist/{src/web/hooks/use-request-modal.test.d.ts → server/middleware.test-d.d.ts} +0 -0
  436. /package/dist/{src/web/hooks/use-theme.test.d.ts → server/middleware.test.d.ts} +0 -0
  437. /package/dist/{src/web/hooks/use-tool-info.test-d.d.ts → server/tunnel-proxy-router.test.d.ts} +0 -0
  438. /package/dist/{src/web/hooks/use-tool-info.test.d.ts → test/view.test.d.ts} +0 -0
  439. /package/dist/{src/web → web/bridges/apps-sdk}/types.js +0 -0
  440. /package/dist/{src/web/hooks/use-user-agent.test.d.ts → web/bridges/mcp-app/use-mcp-app-context.test.d.ts} +0 -0
  441. /package/dist/{src/web/hooks/use-widget-state.test.d.ts → web/create-store.test.d.ts} +0 -0
  442. /package/dist/{src/web/typed-hooks.test-d.d.ts → web/data-llm.test.d.ts} +0 -0
  443. /package/dist/{src/web/typed-hooks.test.d.ts → web/generate-helpers.test-d.d.ts} +0 -0
  444. /package/dist/{src/web → web}/proxy.d.ts +0 -0
package/README.md CHANGED
@@ -1,320 +1,153 @@
1
1
  <div align="center">
2
2
 
3
- # Skybridge
3
+ <img alt="Skybridge" src="https://raw.githubusercontent.com/alpic-ai/skybridge/main/docs/images/github-banner.png" width="100%">
4
4
 
5
- **Skybridge is the TypeScript framework for building ChatGPT apps**
5
+ <br />
6
6
 
7
- [![By Alpic](https://img.shields.io/badge/Made%20by%20Alpic-f6ffed?logo=alpic)](https://alpic.ai)
7
+ **Build ChatGPT & MCP Apps. The Modern TypeScript Way.**
8
8
 
9
- ![NPM Downloads](https://img.shields.io/npm/dm/skybridge?color=e90060)
10
- ![NPM Version](https://img.shields.io/npm/v/skybridge?color=e90060)
11
- ![GitHub License](https://img.shields.io/github/license/alpic-ai/skybridge?color=e90060)
9
+ The fullstack TypeScript framework for AI-embedded views.<br />
10
+ **Type-safe. React-powered. Platform-agnostic.**
12
11
 
13
- </div>
14
-
15
- Skybridge comes with 2 packages:
16
-
17
- - `skybridge/server`: A drop-in replacement of the `@modelcontextprotocol/sdk` official `McpServer` class with extra features for widget development.
18
- - `skybridge/web`: A react library with hooks and components to build widgets on the underlying _OpenAI iFrame skybridge_ runtime.
19
-
20
- ## Quick start
21
-
22
- To get started in less than a minute, you can [create a new repository](https://github.com/new?template_name=apps-sdk-template&template_owner=alpic-ai) using our [ChatGPT SDK template](https://github.com/alpic-ai/apps-sdk-template). This template includes a basic setup for both the server and the widgets.
12
+ <br />
23
13
 
24
- ## Installation
14
+ [![NPM Version](https://img.shields.io/npm/v/skybridge?color=e90060&style=for-the-badge)](https://www.npmjs.com/package/skybridge)
15
+ [![NPM Downloads](https://img.shields.io/npm/dm/skybridge?color=e90060&style=for-the-badge)](https://www.npmjs.com/package/skybridge)
16
+ [![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)
25
17
 
26
- ```bash
27
- pnpm add skybridge
28
- ```
18
+ <br />
29
19
 
30
- ## Concepts
20
+ [Documentation](https://docs.skybridge.tech) · [Quick Start](https://docs.skybridge.tech/quickstart/create-new-app) · [Showcase](https://docs.skybridge.tech/showcase)
31
21
 
32
- ### Widgets
22
+ </div>
33
23
 
34
- > A widget is a UI component that turns structured tool results into a human-friendly UI. Those are built using React components. They are rendered inside an iframe inline with the conversation on ChatGPT.
24
+ <br />
35
25
 
36
- Each widget in your app must have a unique name. The name is used to bridge the tool invocation result with the widget React component.
26
+ ## Why Skybridge?
37
27
 
38
- For example, in order to register a new widget named `pokemon` on your ChatGPT app. You should have the following file structure and file contents:
28
+ 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.
39
29
 
40
- _Project structure_
30
+ **Skybridge fixes that.**
41
31
 
42
- ```
43
- server/
44
- └── src/
45
- └── index.ts // Register the widget with McpServer.widget()
46
- web/
47
- └── src/
48
- └── widgets/
49
- └── pokemon.tsx // Use the same widget name as the file name
50
- ```
32
+ | | |
33
+ |:--|:--|
34
+ | 🌐 **Write once, run everywhere** — Skybridge works seamlessly with ChatGPT (Apps SDK) and MCP-compatible clients. | ✅ **End-to-End Type Safety** — tRPC-style inference from server to view. Autocomplete everywhere. |
35
+ | 🔄 **View-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. |
36
+ | 👨‍💻 **Full dev environment** — HMR, debug traces, and local devtools. | 📦 **Showcase Examples** — Production-ready examples to learn from and build upon. |
51
37
 
52
- _server/src/index.ts_
38
+ <br />
53
39
 
54
- ```ts
55
- import { McpServer } from "skybridge/server";
40
+ ## 🚀 Get Started
56
41
 
57
- const server = new McpServer();
42
+ **Create a new app:**
58
43
 
59
- server.widget(
60
- "pokemon"
61
- // Remaining arguments...
62
- );
44
+ ```bash
45
+ npm create skybridge@latest
63
46
  ```
64
47
 
65
- _web/src/widgets/pokemon.tsx_
66
-
67
- ```ts
68
- import { mountWidget } from "skybridge/web";
69
-
70
- const Pokemon: React.FunctionComponent = () => {
71
- // Your React component code goes here...
72
- };
48
+ **Or add to an existing project:**
73
49
 
74
- mountWidget(<Pokemon />);
50
+ ```bash
51
+ npm i skybridge
52
+ yarn add skybridge
53
+ pnpm add skybridge
54
+ bun add skybridge
55
+ deno add skybridge
75
56
  ```
76
57
 
77
- ## Packages
78
-
79
- ### skybridge/server
80
-
81
- The `skybridge/server` package is a drop-in replacement of the `@modelcontextprotocol/sdk` official `McpServer` class with extra features for widget development. If you're already using the `@modelcontextprotocol/sdk`, you can simply replace your `McpServer` import with `skybridge/server` and you're good to go.
82
-
83
- ### skybridge/web
84
-
85
- The `skybridge/web` package is a react library with hooks and components to build widgets on the underlying _OpenAI iFrame skybridge_ runtime.
58
+ <div align="center">
86
59
 
87
- **Vite plugin**
60
+ **👉 [Read the Docs](https://docs.skybridge.tech) 👈**
88
61
 
89
- The `skybridge/web` package comes with a Vite plugin that allows you to build your widgets as regular Vite apps.
62
+ </div>
90
63
 
91
- ```ts
92
- import { defineConfig } from "vite";
93
- import { skybridge } from "skybridge/web";
64
+ <br />
94
65
 
95
- export default defineConfig({
96
- plugins: [skybridge()],
97
- });
98
- ```
66
+ ## 📦 Architecture
99
67
 
100
- **Typed Hooks**
68
+ Skybridge is a fullstack framework with unified server and client modules:
101
69
 
102
- Skybridge provides fully typed hooks that give you autocomplete for tool names and type inference for inputs/outputs - similar to tRPC. This is opt-in and requires exporting your server type.
70
+ - **`skybridge/server`** Define tools and views with full type inference. Extends the MCP SDK.
71
+ - **`skybridge/web`** — React hooks that consume your server types. Works with Apps SDK (ChatGPT) and MCP Apps.
72
+ - **Dev Environment** — Vite plugin with HMR, DevTools emulator, and optimized builds.
103
73
 
104
- _Server setup (server/src/index.ts)_
74
+ ### Server
105
75
 
106
76
  ```ts
107
77
  import { McpServer } from "skybridge/server";
108
- import { z } from "zod";
109
-
110
- const server = new McpServer({ name: "my-app", version: "1.0" }, {})
111
- .widget("search-voyage", {}, {
112
- description: "Search for trips",
113
- inputSchema: {
114
- destination: z.string(),
115
- departureDate: z.string().optional(),
116
- },
117
- outputSchema: {
118
- results: z.array(z.object({ id: z.string(), name: z.string() })),
119
- },
120
- }, async ({ destination }) => {
121
- // Your tool logic here...
122
- return { content: [{ type: "text", text: `Found trips to ${destination}` }] };
123
- })
124
- .widget("get-details", {}, {
125
- inputSchema: { tripId: z.string() },
126
- }, async ({ tripId }) => {
127
- return { content: [{ type: "text", text: `Details for ${tripId}` }] };
128
- });
129
-
130
- // Export the server type for the client
131
- export type AppType = typeof server;
132
- ```
133
-
134
- _One-time setup (web/src/skybridge.ts)_
135
78
 
136
- Create typed hooks once and export them for use across your app:
137
-
138
- ```ts
139
- import type { AppType } from "../server"; // type-only import
140
- import { createTypedHooks } from "skybridge/web";
141
-
142
- export const { useCallTool, useToolInfo } = createTypedHooks<AppType>();
79
+ server.registerView("flights", {}, {
80
+ inputSchema: { destination: z.string() },
81
+ }, async ({ destination }) => {
82
+ const flights = await searchFlights(destination);
83
+ return { structuredContent: { flights } };
84
+ });
143
85
  ```
144
86
 
145
- _Usage in widgets (web/src/widgets/search.tsx)_
87
+ ### View
146
88
 
147
89
  ```tsx
148
- import { useCallTool, useToolInfo } from "../skybridge"; // import typed hooks
149
-
150
- export function SearchWidget() {
151
- const { callTool, data, isPending } = useCallTool("search-voyage");
152
- // ^ autocomplete for tool names
153
- const toolInfo = useToolInfo<"search-voyage">();
154
- // ^ autocomplete for widget names
155
-
156
- const handleSearch = () => {
157
- callTool({ destination: "Spain" });
158
- // ^ autocomplete for input fields
159
- };
160
-
161
- return (
162
- <div>
163
- <button onClick={handleSearch} disabled={isPending}>
164
- Search
165
- </button>
166
- {toolInfo.isSuccess && (
167
- <div>Found {toolInfo.output.totalCount} results</div>
168
- // ^ typed output
169
- )}
170
- </div>
171
- );
172
- }
173
- ```
174
-
175
- **Hooks**
176
-
177
- The `skybridge/web` package comes with a set of hooks to help you build your widgets :
178
-
179
- - `useOpenAiGlobal`: A generic hook to get any global data from the OpenAI iFrame skybridge runtime (in `window.openai`).
180
- - `useToolOutput`: A hook to get the initial tool `structuredContent` returned when rendering the widget for the first time. The data inside this hook is not updated when the tool is called again.
181
- - `useToolResponseMetadata`: A hook to get the initial tool `meta` returned when rendering the widget for the first time. The data inside this hook is not updated when the tool is called again.
182
- - `useToolInfo`: A hook to get the tool input, output, and response metadata with type inference. Provides a discriminated union based on status (pending/success).
183
- - `useCallTool`: A @tanstack/react-query inspired hook to send make additional tool calls inside a widget.
184
- - `createTypedHooks`: A factory that creates typed versions of `useCallTool` and `useToolInfo` with full type inference from your server type.
185
-
186
- _useOpenAiGlobal_
187
-
188
- ```ts
189
- import { useOpenAiGlobal } from "skybridge/web";
190
-
191
- const theme = useOpenAiGlobal("theme");
192
- ```
193
-
194
- _useToolOutput_
195
-
196
- ```ts
197
- import { useToolOutput } from "skybridge/web";
198
-
199
- const toolOutput = useToolOutput();
200
- ```
201
-
202
- _useToolResponseMetadata_
203
-
204
- ```ts
205
- import { useToolResponseMetadata } from "skybridge/web";
206
-
207
- const toolResponseMetadata = useToolResponseMetadata();
208
- ```
209
-
210
- _useToolInfo_
211
-
212
- ```ts
213
90
  import { useToolInfo } from "skybridge/web";
214
91
 
215
- const toolInfo = useToolInfo<{
216
- input: { query: string };
217
- output: { results: string[] };
218
- responseMetadata: { id: number };
219
- }>();
92
+ function FlightsView() {
93
+ const { output } = useToolInfo();
220
94
 
221
- // toolInfo.input is typed based on the input type
222
- // toolInfo.output is typed based on the output type (undefined when pending)
223
- // toolInfo.status narrows correctly: "pending" | "success"
224
-
225
- if (toolInfo.isPending) {
226
- // toolInfo.output is undefined here
227
- console.log(toolInfo.input.query);
228
- }
229
-
230
- if (toolInfo.isSuccess) {
231
- // toolInfo.output is typed here
232
- console.log(toolInfo.output.results);
95
+ return output.structuredContent.flights.map(flight =>
96
+ <FlightCard key={flight.id} flight={flight} />
97
+ );
233
98
  }
234
99
  ```
235
100
 
236
- _useToolInfo_ with typed hooks (recommended)
101
+ <br />
237
102
 
238
- ```tsx
239
- import { useToolInfo } from "../skybridge"; // import typed hooks
103
+ ## 🎯 Features at a Glance
240
104
 
241
- export function SearchWidget() {
242
- const toolInfo = useToolInfo<"search-voyage">();
243
- // ^ autocomplete for widget names
244
- // toolInfo.input is typed as { destination: string; departureDate?: string; ... }
245
- // toolInfo.output is typed as { results: Array<...>; totalCount: number; } | undefined
105
+ - **Live Reload** — Vite HMR. See changes instantly without reinstalling.
106
+ - **Typed Hooks** — Full autocomplete for tools, inputs, outputs.
107
+ - **View Tool Calls** — Trigger server actions from UI.
108
+ - **Dual Surface Sync** Keep model aware of what users see with `data-llm`.
109
+ - **React Query-style API** `isPending`, `isError`, callbacks.
110
+ - **Platform Agnostic** — Works with ChatGPT (Apps SDK) and MCP Apps clients (Goose, VSCode, etc.).
111
+ - **MCP Compatible** — Extends the official SDK. Works with any MCP client.
246
112
 
247
- if (toolInfo.isSuccess) {
248
- return <div>Found {toolInfo.output.totalCount} results</div>;
249
- }
113
+ <br />
250
114
 
251
- return <div>Searching for {toolInfo.input.destination}...</div>;
252
- }
253
- ```
115
+ ## 📖 Showcase
254
116
 
255
- _useCallTool_ in synchronous mode
117
+ Explore production-ready examples:
256
118
 
257
- ```ts
258
- import { useCallTool } from "skybridge/web";
259
-
260
- export const TestTool: React.FunctionComponent = () => {
261
- const { callTool, isPending } = useCallTool("myToolName");
262
-
263
- return (
264
- <div>
265
- <button
266
- disabled={isPending}
267
- onClick={() => {
268
- callTool({ input: "test input" }, {
269
- onSuccess: (data) => {
270
- alert("Tool returned: " + data);
271
- },
272
- });
273
- >
274
- Call Tool inside a widget
275
- </button>
276
- </div>
277
- );
278
- };
279
- ```
119
+ | Example | Description | Demo | Code |
120
+ |------------------------|----------------------------------------------------------------------------------|-----------------------------------------------------|-------------------------------------------------------------------------------------|
121
+ | **Awaze — Cottage Search** | Holiday cottage search and booking experience — browse properties, filter by location, and explore availability | [Try Demo](https://mcp.cottages.com/try) | — |
122
+ | **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) |
123
+ | **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) |
124
+ | **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) |
125
+ | **Investigation Game** | Interactive murder mystery game with multi-screen gameplay and dynamic story progression | [Try Demo](https://investigation-game.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/investigation-game) |
126
+ | **Productivity** | Data visualization dashboard demonstrating Skybridge capabilities for MCP Apps | [Try Demo](https://productivity.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/productivity) |
127
+ | **Time's Up** | Word-guessing party game where the user gives hints and the AI tries to guess the secret word | [Try Demo](https://times-up.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/times-up) |
128
+ | **Lumo — Interactive AI Tutor** | Adaptive educational tutor with Mermaid.js diagrams, mind maps, quizzes, and fill-in-the-blank exercises | [Try Demo](https://lumo-mcp-app-39519fdd.alpic.live/try) | [View Code](https://github.com/connorads/lumo-mcp-app) |
129
+ | **Auth — Auth0** | Full OAuth authentication with Auth0 and personalized coffee shop search | — | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/auth-auth0) |
130
+ | **Auth — Clerk** | Full OAuth authentication with Clerk and personalized coffee shop search | — | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/auth-clerk) |
131
+ | **Auth — Stytch** | Full OAuth authentication with Stytch and personalized coffee shop search | — | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/auth-stytch) |
132
+ | **Auth WorkOS AuthKit** | Full OAuth authentication with WorkOS AuthKit and personalized coffee shop search | — | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/auth-workos) |
133
+ | **Flight Booking** | Flight booking carousel with dynamic search and booking flow | [Try Demo](https://flight-booking.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/flight-booking) |
134
+ | **Generative UI** | Dynamic UI generation using json-render and Skybridge | [Try Demo](https://generative-ui.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/generative-ui) |
135
+ | **Manifest Starter** | Starter app with Manifest UI agentic components out-of-the-box | [Try Demo](https://manifest-ui.skybridge.tech/try) | [View Code](https://github.com/alpic-ai/skybridge/tree/main/examples/manifest-ui) |
280
136
 
281
- _useCallTool_ in asynchronous mode
137
+ See all examples in the [Showcase](https://docs.skybridge.tech/showcase) or browse the [examples/](examples/) directory.
282
138
 
283
- ```ts
284
- import { useCallTool } from "skybridge/web";
285
-
286
- export const TestTool: React.FunctionComponent = () => {
287
- const { callToolAsync, isPending } = useCallTool("myToolName");
288
-
289
- return (
290
- <div>
291
- <button
292
- disabled={isPending}
293
- onClick={async () => {
294
- const data = await callToolAsync({ input: "test input" });
295
- alert("Tool returned: " + data);
296
- }}
297
- >
298
- Call Tool inside a widget
299
- </button>
300
- </div>
301
- );
302
- };
303
- ```
139
+ <br />
304
140
 
305
- ## Migrate your existing MCP server to a ChatGPT app
141
+ <div align="center">
306
142
 
307
- If you're already using the `@modelcontextprotocol/sdk` to build a MCP server, you can migrate to a ChatGPT app by following these steps:
143
+ [![GitHub Discussions](https://img.shields.io/badge/Discussions-Ask%20Questions-blue?style=flat-square&logo=github)](https://github.com/alpic-ai/skybridge/discussions)
144
+ [![GitHub Issues](https://img.shields.io/badge/Issues-Report%20Bugs-red?style=flat-square&logo=github)](https://github.com/alpic-ai/skybridge/issues)
145
+ [![Discord](https://img.shields.io/badge/Discord-Chat-5865F2?style=flat-square&logo=discord&logoColor=white)](https://discord.com/invite/gNAazGueab)
308
146
 
309
- 1. Replace your `McpServer` import from `@modelcontextprotocol/sdk` with the same import from `skybridge/server`
310
- 2. Create a new vite project in a folder named `web` and install the `skybridge` package
311
- 3. Replace the `vite.config.ts` file with the following:
147
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions
312
148
 
313
- ```ts
314
- import { defineConfig } from "vite";
315
- import { skybridge } from "skybridge/web";
149
+ <br />
316
150
 
317
- export default defineConfig({
318
- plugins: [skybridge()],
319
- });
320
- ```
151
+ **[MIT License](LICENSE)** · Made with ❤️ by **[Alpic](https://alpic.ai)**
152
+
153
+ </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,18 @@
1
+ export declare function resolvePort(flagPort?: number): Promise<{
2
+ port: number;
3
+ fallback: boolean;
4
+ envWarning?: undefined;
5
+ } | {
6
+ port: number;
7
+ fallback: boolean;
8
+ envWarning: string;
9
+ }>;
10
+ /**
11
+ * Returns the given port if available, otherwise lets the OS
12
+ * pick a free port via `listen(0)`.
13
+ *
14
+ * @param host - Bind address for the check. Pass `"localhost"` for
15
+ * services that bind to 127.0.0.1 (e.g. Vite HMR). Omit for
16
+ * services that bind to all interfaces (e.g. the HTTP server).
17
+ */
18
+ export declare function detectAvailablePort(startPort: number, host?: string): Promise<number>;
@@ -0,0 +1,61 @@
1
+ import net from "node:net";
2
+ const DEFAULT_PORT = 3000;
3
+ export async function resolvePort(flagPort) {
4
+ if (flagPort && flagPort > 1) {
5
+ return { port: flagPort, fallback: false };
6
+ }
7
+ const rawEnv = process.env.PORT;
8
+ if (rawEnv) {
9
+ const parsed = Number(rawEnv);
10
+ if (Number.isInteger(parsed) && parsed > 0) {
11
+ return { port: parsed, fallback: false };
12
+ }
13
+ return {
14
+ port: await detectAvailablePort(DEFAULT_PORT),
15
+ fallback: false,
16
+ envWarning: `Invalid PORT="${rawEnv}", ignoring and using default`,
17
+ };
18
+ }
19
+ const port = await detectAvailablePort(DEFAULT_PORT);
20
+ return { port, fallback: port !== DEFAULT_PORT };
21
+ }
22
+ /**
23
+ * Returns the given port if available, otherwise lets the OS
24
+ * pick a free port via `listen(0)`.
25
+ *
26
+ * @param host - Bind address for the check. Pass `"localhost"` for
27
+ * services that bind to 127.0.0.1 (e.g. Vite HMR). Omit for
28
+ * services that bind to all interfaces (e.g. the HTTP server).
29
+ */
30
+ export async function detectAvailablePort(startPort, host) {
31
+ const available = await isPortAvailable(startPort, host);
32
+ if (available) {
33
+ return startPort;
34
+ }
35
+ return new Promise((resolve, reject) => {
36
+ const server = net.createServer();
37
+ server.once("error", reject);
38
+ server.once("listening", () => {
39
+ const addr = server.address();
40
+ if (addr && typeof addr === "object") {
41
+ const { port } = addr;
42
+ server.close(() => resolve(port));
43
+ }
44
+ else {
45
+ server.close(() => reject(new Error("Failed to detect available port")));
46
+ }
47
+ });
48
+ server.listen(0, host);
49
+ });
50
+ }
51
+ function isPortAvailable(port, host) {
52
+ return new Promise((resolve) => {
53
+ const server = net.createServer();
54
+ server.once("error", () => resolve(false));
55
+ server.once("listening", () => {
56
+ server.close(() => resolve(true));
57
+ });
58
+ server.listen(port, host);
59
+ });
60
+ }
61
+ //# sourceMappingURL=detect-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-port.js","sourceRoot":"","sources":["../../src/cli/detect-port.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAE3B,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAiB;IACjD,IAAI,QAAQ,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IAChC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC3C,CAAC;QACD,OAAO;YACL,IAAI,EAAE,MAAM,mBAAmB,CAAC,YAAY,CAAC;YAC7C,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,iBAAiB,MAAM,+BAA+B;SACnE,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,YAAY,CAAC,CAAC;IACrD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,KAAK,YAAY,EAAE,CAAC;AACnD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,IAAa;IAEb,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IACzD,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QAElC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;gBACtB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAChB,MAAM,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CACrD,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,IAAY,EAAE,IAAa;IAClD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,EAAE,CAAC;QAElC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import net from \"node:net\";\n\nconst DEFAULT_PORT = 3000;\n\nexport async function resolvePort(flagPort?: number) {\n if (flagPort && flagPort > 1) {\n return { port: flagPort, fallback: false };\n }\n\n const rawEnv = process.env.PORT;\n if (rawEnv) {\n const parsed = Number(rawEnv);\n if (Number.isInteger(parsed) && parsed > 0) {\n return { port: parsed, fallback: false };\n }\n return {\n port: await detectAvailablePort(DEFAULT_PORT),\n fallback: false,\n envWarning: `Invalid PORT=\"${rawEnv}\", ignoring and using default`,\n };\n }\n\n const port = await detectAvailablePort(DEFAULT_PORT);\n return { port, fallback: port !== DEFAULT_PORT };\n}\n\n/**\n * Returns the given port if available, otherwise lets the OS\n * pick a free port via `listen(0)`.\n *\n * @param host - Bind address for the check. Pass `\"localhost\"` for\n * services that bind to 127.0.0.1 (e.g. Vite HMR). Omit for\n * services that bind to all interfaces (e.g. the HTTP server).\n */\nexport async function detectAvailablePort(\n startPort: number,\n host?: string,\n): Promise<number> {\n const available = await isPortAvailable(startPort, host);\n if (available) {\n return startPort;\n }\n\n return new Promise((resolve, reject) => {\n const server = net.createServer();\n\n server.once(\"error\", reject);\n server.once(\"listening\", () => {\n const addr = server.address();\n if (addr && typeof addr === \"object\") {\n const { port } = addr;\n server.close(() => resolve(port));\n } else {\n server.close(() =>\n reject(new Error(\"Failed to detect available port\")),\n );\n }\n });\n\n server.listen(0, host);\n });\n}\n\nfunction isPortAvailable(port: number, host?: string): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer();\n\n server.once(\"error\", () => resolve(false));\n server.once(\"listening\", () => {\n server.close(() => resolve(true));\n });\n\n server.listen(port, host);\n });\n}\n"]}
@@ -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", " ", "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,iBACD,EACP,MAAC,IAAI,IAAC,KAAK,EAAC,MAAM,mBAAI,OAAO,IAAQ,EACpC,QAAQ,IACL,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { Box, Text } from \"ink\";\n\nexport const Header = ({\n version,\n children,\n}: {\n version: string;\n children?: React.ReactNode;\n}) => {\n return (\n <Box marginBottom={1}>\n <Text color=\"cyan\" bold>\n ⛰{\" \"}Skybridge\n </Text>\n <Text color=\"cyan\"> v{version}</Text>\n {children}\n </Box>\n );\n};\n"]}
@@ -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","sourcesContent":["import { type SpawnOptions, spawn } from \"node:child_process\";\n\nexport function runCommand(\n command: string,\n options: SpawnOptions = {\n stdio: [\"ignore\", \"inherit\", \"inherit\"],\n },\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n const proc = spawn(command, {\n ...options,\n shell: true,\n });\n\n if (proc.stdout) {\n proc.stdout.on(\"data\", (chunk) => {\n stdoutChunks.push(chunk);\n });\n }\n\n if (proc.stderr) {\n proc.stderr.on(\"data\", (chunk) => {\n stderrChunks.push(chunk);\n });\n }\n\n proc.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n const stdoutOutput = Buffer.concat(stdoutChunks).toString();\n const stderrOutput = Buffer.concat(stderrChunks).toString();\n const allOutput = [stdoutOutput, stderrOutput]\n .filter((output) => output.trim())\n .join(\"\\n\");\n const errorMessage = allOutput\n ? `Command failed with exit code ${code}\\n${allOutput}`\n : `Command failed with exit code ${code}`;\n reject(new Error(errorMessage));\n }\n });\n\n proc.on(\"error\", (error) => {\n reject(error);\n });\n });\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { Hook } from "@oclif/core";
2
+ export declare function isEnabled(): boolean;
3
+ export declare function isDebugMode(): boolean;
4
+ export declare function setEnabled(enabled: boolean): void;
5
+ export declare function getMachineId(): string;
6
+ declare const hook: Hook<"finally">;
7
+ export default hook;