skybridge 0.0.0-dev.fe84ef2 → 0.0.0-dev.febf292

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 (350) hide show
  1. package/LICENSE +21 -674
  2. package/README.md +82 -352
  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/use-execute-steps.d.ts +11 -0
  17. package/dist/cli/use-execute-steps.js +36 -0
  18. package/dist/cli/use-execute-steps.js.map +1 -0
  19. package/dist/cli/use-nodemon.d.ts +7 -0
  20. package/dist/cli/use-nodemon.js +76 -0
  21. package/dist/cli/use-nodemon.js.map +1 -0
  22. package/dist/cli/use-typescript-check.d.ts +8 -0
  23. package/dist/cli/use-typescript-check.js +59 -0
  24. package/dist/cli/use-typescript-check.js.map +1 -0
  25. package/dist/commands/build.d.ts +9 -0
  26. package/dist/commands/build.js +46 -0
  27. package/dist/commands/build.js.map +1 -0
  28. package/dist/commands/dev.d.ts +10 -0
  29. package/dist/commands/dev.js +42 -0
  30. package/dist/commands/dev.js.map +1 -0
  31. package/dist/commands/start.d.ts +9 -0
  32. package/dist/commands/start.js +52 -0
  33. package/dist/commands/start.js.map +1 -0
  34. package/dist/commands/telemetry/disable.d.ts +5 -0
  35. package/dist/commands/telemetry/disable.js +14 -0
  36. package/dist/commands/telemetry/disable.js.map +1 -0
  37. package/dist/commands/telemetry/enable.d.ts +5 -0
  38. package/dist/commands/telemetry/enable.js +14 -0
  39. package/dist/commands/telemetry/enable.js.map +1 -0
  40. package/dist/commands/telemetry/status.d.ts +5 -0
  41. package/dist/commands/telemetry/status.js +14 -0
  42. package/dist/commands/telemetry/status.js.map +1 -0
  43. package/dist/server/asset-base-url-transform-plugin.d.ts +11 -0
  44. package/dist/server/asset-base-url-transform-plugin.js +34 -0
  45. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  46. package/dist/server/asset-base-url-transform-plugin.test.js +56 -0
  47. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  48. package/dist/server/const.d.ts +1 -0
  49. package/dist/server/const.js +2 -0
  50. package/dist/server/const.js.map +1 -0
  51. package/dist/server/express.d.ts +9 -0
  52. package/dist/server/express.js +72 -0
  53. package/dist/server/express.js.map +1 -0
  54. package/dist/server/express.test.js +74 -0
  55. package/dist/server/express.test.js.map +1 -0
  56. package/dist/server/index.d.ts +4 -0
  57. package/dist/server/index.js.map +1 -0
  58. package/dist/{src/server → server}/inferUtilityTypes.d.ts +10 -0
  59. package/dist/server/inferUtilityTypes.js.map +1 -0
  60. package/dist/server/server.d.ts +105 -0
  61. package/dist/server/server.js +206 -0
  62. package/dist/server/server.js.map +1 -0
  63. package/dist/{src/server → server}/templateHelper.d.ts +4 -0
  64. package/dist/{src/server → server}/templateHelper.js +5 -4
  65. package/dist/server/templateHelper.js.map +1 -0
  66. package/dist/server/templates/development.hbs +67 -0
  67. package/dist/{src/server → server}/templates/production.hbs +1 -1
  68. package/dist/{src/server → server}/widgetsDevServer.d.ts +2 -2
  69. package/dist/server/widgetsDevServer.js +63 -0
  70. package/dist/server/widgetsDevServer.js.map +1 -0
  71. package/dist/{src/test → test}/utils.d.ts +54 -8
  72. package/dist/{src/test → test}/utils.js +86 -8
  73. package/dist/test/utils.js.map +1 -0
  74. package/dist/test/widget.test.js +261 -0
  75. package/dist/test/widget.test.js.map +1 -0
  76. package/dist/web/bridges/apps-sdk/adaptor.d.ts +22 -0
  77. package/dist/web/bridges/apps-sdk/adaptor.js +75 -0
  78. package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -0
  79. package/dist/web/bridges/apps-sdk/bridge.d.ts +10 -0
  80. package/dist/web/bridges/apps-sdk/bridge.js +46 -0
  81. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  82. package/dist/web/bridges/apps-sdk/index.d.ts +5 -0
  83. package/dist/web/bridges/apps-sdk/index.js +5 -0
  84. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  85. package/dist/{src/web → web/bridges/apps-sdk}/types.d.ts +37 -49
  86. package/dist/{src/web → web/bridges/apps-sdk}/types.js +0 -1
  87. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  88. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +2 -0
  89. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +7 -0
  90. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  91. package/dist/web/bridges/get-adaptor.d.ts +2 -0
  92. package/dist/web/bridges/get-adaptor.js +8 -0
  93. package/dist/web/bridges/get-adaptor.js.map +1 -0
  94. package/dist/web/bridges/index.d.ts +5 -0
  95. package/dist/web/bridges/index.js +6 -0
  96. package/dist/web/bridges/index.js.map +1 -0
  97. package/dist/web/bridges/mcp-app/adaptor.d.ts +36 -0
  98. package/dist/web/bridges/mcp-app/adaptor.js +190 -0
  99. package/dist/web/bridges/mcp-app/adaptor.js.map +1 -0
  100. package/dist/web/bridges/mcp-app/bridge.d.ts +43 -0
  101. package/dist/web/bridges/mcp-app/bridge.js +260 -0
  102. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  103. package/dist/web/bridges/mcp-app/index.d.ts +4 -0
  104. package/dist/web/bridges/mcp-app/index.js +4 -0
  105. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  106. package/dist/web/bridges/mcp-app/types.d.ts +8 -0
  107. package/dist/web/bridges/mcp-app/types.js +2 -0
  108. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  109. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +5 -0
  110. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +7 -0
  111. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  112. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +66 -0
  113. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  114. package/dist/web/bridges/types.d.ts +102 -0
  115. package/dist/web/bridges/types.js +2 -0
  116. package/dist/web/bridges/types.js.map +1 -0
  117. package/dist/web/bridges/use-host-context.d.ts +2 -0
  118. package/dist/web/bridges/use-host-context.js +8 -0
  119. package/dist/web/bridges/use-host-context.js.map +1 -0
  120. package/dist/web/components/modal-provider.d.ts +4 -0
  121. package/dist/web/components/modal-provider.js +47 -0
  122. package/dist/web/components/modal-provider.js.map +1 -0
  123. package/dist/web/create-store.js +24 -0
  124. package/dist/web/create-store.js.map +1 -0
  125. package/dist/web/create-store.test.js +129 -0
  126. package/dist/web/create-store.test.js.map +1 -0
  127. package/dist/{src/web → web}/data-llm.js +11 -7
  128. package/dist/web/data-llm.js.map +1 -0
  129. package/dist/web/data-llm.test.js +141 -0
  130. package/dist/web/data-llm.test.js.map +1 -0
  131. package/dist/{src/web → web}/generate-helpers.d.ts +11 -8
  132. package/dist/{src/web → web}/generate-helpers.js +5 -3
  133. package/dist/web/generate-helpers.js.map +1 -0
  134. package/dist/{src/web → web}/generate-helpers.test-d.js +59 -3
  135. package/dist/web/generate-helpers.test-d.js.map +1 -0
  136. package/dist/{src/web → web}/generate-helpers.test.js +1 -1
  137. package/dist/web/generate-helpers.test.js.map +1 -0
  138. package/dist/{src/web → web}/helpers/state.d.ts +3 -1
  139. package/dist/web/helpers/state.js +45 -0
  140. package/dist/web/helpers/state.js.map +1 -0
  141. package/dist/web/helpers/state.test.js +53 -0
  142. package/dist/web/helpers/state.test.js.map +1 -0
  143. package/dist/web/hooks/index.d.ts +11 -0
  144. package/dist/{src/web → web}/hooks/index.js +3 -4
  145. package/dist/web/hooks/index.js.map +1 -0
  146. package/dist/web/hooks/test/utils.d.ts +16 -0
  147. package/dist/web/hooks/test/utils.js +60 -0
  148. package/dist/web/hooks/test/utils.js.map +1 -0
  149. package/dist/{src/web → web}/hooks/use-call-tool.d.ts +3 -2
  150. package/dist/{src/web → web}/hooks/use-call-tool.js +12 -4
  151. package/dist/web/hooks/use-call-tool.js.map +1 -0
  152. package/dist/{src/web → web}/hooks/use-call-tool.test-d.js +1 -1
  153. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  154. package/dist/{src/web → web}/hooks/use-call-tool.test.js +35 -16
  155. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  156. package/dist/web/hooks/use-display-mode.d.ts +4 -0
  157. package/dist/web/hooks/use-display-mode.js +9 -0
  158. package/dist/web/hooks/use-display-mode.js.map +1 -0
  159. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  160. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  161. package/dist/{src/web → web}/hooks/use-display-mode.test.js +3 -2
  162. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  163. package/dist/web/hooks/use-files.d.ts +6 -0
  164. package/dist/web/hooks/use-files.js +9 -0
  165. package/dist/web/hooks/use-files.js.map +1 -0
  166. package/dist/{src/web → web}/hooks/use-files.test.js +11 -6
  167. package/dist/web/hooks/use-files.test.js.map +1 -0
  168. package/dist/web/hooks/use-layout.d.ts +22 -0
  169. package/dist/web/hooks/use-layout.js +23 -0
  170. package/dist/web/hooks/use-layout.js.map +1 -0
  171. package/dist/web/hooks/use-layout.test.js +96 -0
  172. package/dist/web/hooks/use-layout.test.js.map +1 -0
  173. package/dist/web/hooks/use-open-external.d.ts +3 -0
  174. package/dist/web/hooks/use-open-external.js +8 -0
  175. package/dist/web/hooks/use-open-external.js.map +1 -0
  176. package/dist/web/hooks/use-open-external.test.js +60 -0
  177. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  178. package/dist/web/hooks/use-request-modal.d.ts +9 -0
  179. package/dist/web/hooks/use-request-modal.js +16 -0
  180. package/dist/web/hooks/use-request-modal.js.map +1 -0
  181. package/dist/web/hooks/use-request-modal.test.js +57 -0
  182. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  183. package/dist/web/hooks/use-send-follow-up-message.js +8 -0
  184. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  185. package/dist/web/hooks/use-set-open-in-app-url.d.ts +1 -0
  186. package/dist/web/hooks/use-set-open-in-app-url.js +8 -0
  187. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  188. package/dist/web/hooks/use-set-open-in-app-url.test.js +43 -0
  189. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  190. package/dist/{src/web → web}/hooks/use-tool-info.d.ts +13 -2
  191. package/dist/web/hooks/use-tool-info.js +26 -0
  192. package/dist/web/hooks/use-tool-info.js.map +1 -0
  193. package/dist/web/hooks/use-tool-info.test-d.d.ts +1 -0
  194. package/dist/{src/web → web}/hooks/use-tool-info.test-d.js +40 -5
  195. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  196. package/dist/web/hooks/use-tool-info.test.d.ts +1 -0
  197. package/dist/web/hooks/use-tool-info.test.js +130 -0
  198. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  199. package/dist/web/hooks/use-user.d.ts +18 -0
  200. package/dist/web/hooks/use-user.js +19 -0
  201. package/dist/web/hooks/use-user.js.map +1 -0
  202. package/dist/web/hooks/use-user.test.d.ts +1 -0
  203. package/dist/web/hooks/use-user.test.js +94 -0
  204. package/dist/web/hooks/use-user.test.js.map +1 -0
  205. package/dist/{src/web → web}/hooks/use-widget-state.js +11 -11
  206. package/dist/web/hooks/use-widget-state.js.map +1 -0
  207. package/dist/web/hooks/use-widget-state.test.d.ts +1 -0
  208. package/dist/{src/web → web}/hooks/use-widget-state.test.js +12 -8
  209. package/dist/web/hooks/use-widget-state.test.js.map +1 -0
  210. package/dist/{src/web → web}/index.d.ts +5 -4
  211. package/dist/{src/web → web}/index.js +5 -4
  212. package/dist/web/index.js.map +1 -0
  213. package/dist/{src/web → web}/mount-widget.js +9 -1
  214. package/dist/web/mount-widget.js.map +1 -0
  215. package/dist/web/plugin/data-llm.test.d.ts +1 -0
  216. package/dist/web/plugin/data-llm.test.js.map +1 -0
  217. package/dist/web/plugin/plugin.js +54 -0
  218. package/dist/web/plugin/plugin.js.map +1 -0
  219. package/dist/{src/web → web}/plugin/transform-data-llm.js +6 -3
  220. package/dist/web/plugin/transform-data-llm.js.map +1 -0
  221. package/dist/web/plugin/transform-data-llm.test.d.ts +1 -0
  222. package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
  223. package/dist/web/plugin/validate-widget.d.ts +5 -0
  224. package/dist/web/plugin/validate-widget.js +27 -0
  225. package/dist/web/plugin/validate-widget.js.map +1 -0
  226. package/dist/web/plugin/validate-widget.test.d.ts +1 -0
  227. package/dist/web/plugin/validate-widget.test.js +42 -0
  228. package/dist/web/plugin/validate-widget.test.js.map +1 -0
  229. package/dist/{src/web → web}/proxy.js +6 -2
  230. package/dist/web/proxy.js.map +1 -0
  231. package/dist/web/types.d.ts +16 -0
  232. package/dist/web/types.js +2 -0
  233. package/dist/web/types.js.map +1 -0
  234. package/package.json +67 -36
  235. package/tsconfig.base.json +28 -0
  236. package/dist/src/server/index.d.ts +0 -4
  237. package/dist/src/server/index.js.map +0 -1
  238. package/dist/src/server/inferUtilityTypes.js.map +0 -1
  239. package/dist/src/server/server.d.ts +0 -48
  240. package/dist/src/server/server.js +0 -62
  241. package/dist/src/server/server.js.map +0 -1
  242. package/dist/src/server/templateHelper.js.map +0 -1
  243. package/dist/src/server/templates/development.hbs +0 -12
  244. package/dist/src/server/widgetsDevServer.js +0 -39
  245. package/dist/src/server/widgetsDevServer.js.map +0 -1
  246. package/dist/src/test/utils.js.map +0 -1
  247. package/dist/src/test/widget.test.js +0 -90
  248. package/dist/src/test/widget.test.js.map +0 -1
  249. package/dist/src/web/create-store.js +0 -41
  250. package/dist/src/web/create-store.js.map +0 -1
  251. package/dist/src/web/data-llm.js.map +0 -1
  252. package/dist/src/web/data-llm.test.js +0 -76
  253. package/dist/src/web/data-llm.test.js.map +0 -1
  254. package/dist/src/web/generate-helpers.js.map +0 -1
  255. package/dist/src/web/generate-helpers.test-d.js.map +0 -1
  256. package/dist/src/web/generate-helpers.test.js.map +0 -1
  257. package/dist/src/web/helpers/state.js +0 -37
  258. package/dist/src/web/helpers/state.js.map +0 -1
  259. package/dist/src/web/hooks/index.d.ts +0 -12
  260. package/dist/src/web/hooks/index.js.map +0 -1
  261. package/dist/src/web/hooks/use-call-tool.js.map +0 -1
  262. package/dist/src/web/hooks/use-call-tool.test-d.js.map +0 -1
  263. package/dist/src/web/hooks/use-call-tool.test.js.map +0 -1
  264. package/dist/src/web/hooks/use-display-mode.d.ts +0 -4
  265. package/dist/src/web/hooks/use-display-mode.js +0 -7
  266. package/dist/src/web/hooks/use-display-mode.js.map +0 -1
  267. package/dist/src/web/hooks/use-display-mode.test.js.map +0 -1
  268. package/dist/src/web/hooks/use-files.d.ts +0 -10
  269. package/dist/src/web/hooks/use-files.js +0 -7
  270. package/dist/src/web/hooks/use-files.js.map +0 -1
  271. package/dist/src/web/hooks/use-files.test.js.map +0 -1
  272. package/dist/src/web/hooks/use-locale.d.ts +0 -1
  273. package/dist/src/web/hooks/use-locale.js +0 -5
  274. package/dist/src/web/hooks/use-locale.js.map +0 -1
  275. package/dist/src/web/hooks/use-locale.test.js +0 -21
  276. package/dist/src/web/hooks/use-locale.test.js.map +0 -1
  277. package/dist/src/web/hooks/use-open-external.d.ts +0 -1
  278. package/dist/src/web/hooks/use-open-external.js +0 -6
  279. package/dist/src/web/hooks/use-open-external.js.map +0 -1
  280. package/dist/src/web/hooks/use-open-external.test.js +0 -24
  281. package/dist/src/web/hooks/use-open-external.test.js.map +0 -1
  282. package/dist/src/web/hooks/use-openai-global.d.ts +0 -2
  283. package/dist/src/web/hooks/use-openai-global.js +0 -23
  284. package/dist/src/web/hooks/use-openai-global.js.map +0 -1
  285. package/dist/src/web/hooks/use-request-modal.d.ts +0 -6
  286. package/dist/src/web/hooks/use-request-modal.js +0 -9
  287. package/dist/src/web/hooks/use-request-modal.js.map +0 -1
  288. package/dist/src/web/hooks/use-request-modal.test.js +0 -24
  289. package/dist/src/web/hooks/use-request-modal.test.js.map +0 -1
  290. package/dist/src/web/hooks/use-send-follow-up-message.js +0 -11
  291. package/dist/src/web/hooks/use-send-follow-up-message.js.map +0 -1
  292. package/dist/src/web/hooks/use-theme.d.ts +0 -1
  293. package/dist/src/web/hooks/use-theme.js +0 -5
  294. package/dist/src/web/hooks/use-theme.js.map +0 -1
  295. package/dist/src/web/hooks/use-theme.test.js +0 -26
  296. package/dist/src/web/hooks/use-theme.test.js.map +0 -1
  297. package/dist/src/web/hooks/use-tool-info.js +0 -22
  298. package/dist/src/web/hooks/use-tool-info.js.map +0 -1
  299. package/dist/src/web/hooks/use-tool-info.test-d.js.map +0 -1
  300. package/dist/src/web/hooks/use-tool-info.test.js +0 -59
  301. package/dist/src/web/hooks/use-tool-info.test.js.map +0 -1
  302. package/dist/src/web/hooks/use-user-agent.d.ts +0 -1
  303. package/dist/src/web/hooks/use-user-agent.js +0 -5
  304. package/dist/src/web/hooks/use-user-agent.js.map +0 -1
  305. package/dist/src/web/hooks/use-user-agent.test.js +0 -31
  306. package/dist/src/web/hooks/use-user-agent.test.js.map +0 -1
  307. package/dist/src/web/hooks/use-widget-state.js.map +0 -1
  308. package/dist/src/web/hooks/use-widget-state.test.js.map +0 -1
  309. package/dist/src/web/index.js.map +0 -1
  310. package/dist/src/web/mount-widget.js.map +0 -1
  311. package/dist/src/web/plugin/data-llm.test.js.map +0 -1
  312. package/dist/src/web/plugin/plugin.js +0 -33
  313. package/dist/src/web/plugin/plugin.js.map +0 -1
  314. package/dist/src/web/plugin/transform-data-llm.js.map +0 -1
  315. package/dist/src/web/plugin/transform-data-llm.test.js.map +0 -1
  316. package/dist/src/web/proxy.js.map +0 -1
  317. package/dist/src/web/types.js.map +0 -1
  318. package/dist/vitest.config.d.ts +0 -2
  319. package/dist/vitest.config.js +0 -8
  320. package/dist/vitest.config.js.map +0 -1
  321. /package/dist/{src/test/widget.test.d.ts → server/asset-base-url-transform-plugin.test.d.ts} +0 -0
  322. /package/dist/{src/web/data-llm.test.d.ts → server/express.test.d.ts} +0 -0
  323. /package/dist/{src/server → server}/index.js +0 -0
  324. /package/dist/{src/server → server}/inferUtilityTypes.js +0 -0
  325. /package/dist/{src/web/generate-helpers.test-d.d.ts → test/widget.test.d.ts} +0 -0
  326. /package/dist/{src/web/generate-helpers.test.d.ts → web/bridges/mcp-app/use-mcp-app-context.test.d.ts} +0 -0
  327. /package/dist/{src/web → web}/create-store.d.ts +0 -0
  328. /package/dist/{src/web/hooks/use-call-tool.test-d.d.ts → web/create-store.test.d.ts} +0 -0
  329. /package/dist/{src/web → web}/data-llm.d.ts +0 -0
  330. /package/dist/{src/web/plugin → web}/data-llm.test.d.ts +0 -0
  331. /package/dist/{src/web/hooks/use-call-tool.test.d.ts → web/generate-helpers.test-d.d.ts} +0 -0
  332. /package/dist/{src/web/hooks/use-display-mode.test.d.ts → web/generate-helpers.test.d.ts} +0 -0
  333. /package/dist/{src/web/hooks/use-files.test.d.ts → web/helpers/state.test.d.ts} +0 -0
  334. /package/dist/{src/web/hooks/use-locale.test.d.ts → web/hooks/use-call-tool.test-d.d.ts} +0 -0
  335. /package/dist/{src/web/hooks/use-open-external.test.d.ts → web/hooks/use-call-tool.test.d.ts} +0 -0
  336. /package/dist/{src/web/hooks/use-request-modal.test.d.ts → web/hooks/use-display-mode.test-d.d.ts} +0 -0
  337. /package/dist/{src/web/hooks/use-theme.test.d.ts → web/hooks/use-display-mode.test.d.ts} +0 -0
  338. /package/dist/{src/web/hooks/use-tool-info.test-d.d.ts → web/hooks/use-files.test.d.ts} +0 -0
  339. /package/dist/{src/web/hooks/use-tool-info.test.d.ts → web/hooks/use-layout.test.d.ts} +0 -0
  340. /package/dist/{src/web/hooks/use-user-agent.test.d.ts → web/hooks/use-open-external.test.d.ts} +0 -0
  341. /package/dist/{src/web/hooks/use-widget-state.test.d.ts → web/hooks/use-request-modal.test.d.ts} +0 -0
  342. /package/dist/{src/web → web}/hooks/use-send-follow-up-message.d.ts +0 -0
  343. /package/dist/{src/web/plugin/transform-data-llm.test.d.ts → web/hooks/use-set-open-in-app-url.test.d.ts} +0 -0
  344. /package/dist/{src/web → web}/hooks/use-widget-state.d.ts +0 -0
  345. /package/dist/{src/web → web}/mount-widget.d.ts +0 -0
  346. /package/dist/{src/web → web}/plugin/data-llm.test.js +0 -0
  347. /package/dist/{src/web → web}/plugin/plugin.d.ts +0 -0
  348. /package/dist/{src/web → web}/plugin/transform-data-llm.d.ts +0 -0
  349. /package/dist/{src/web → web}/plugin/transform-data-llm.test.js +0 -0
  350. /package/dist/{src/web → web}/proxy.d.ts +0 -0
package/README.md CHANGED
@@ -1,415 +1,145 @@
1
1
  <div align="center">
2
2
 
3
- # Skybridge
4
-
5
- **Skybridge is the TypeScript framework for building ChatGPT apps**
6
-
7
- [![By Alpic](https://img.shields.io/badge/Made%20by%20Alpic-f6ffed?logo=alpic)](https://alpic.ai)
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)
12
-
13
- </div>
14
-
15
- Skybridge comes with 2 packages:
3
+ <img alt="Skybridge" src="https://raw.githubusercontent.com/alpic-ai/skybridge/main/docs/images/github-banner.png" width="100%">
16
4
 
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.
5
+ <br />
19
6
 
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.
23
-
24
- ## Installation
7
+ # Skybridge
25
8
 
26
- ```bash
27
- pnpm add skybridge
28
- ```
9
+ **Build ChatGPT & MCP Apps. The Modern TypeScript Way.**
29
10
 
30
- ## Concepts
11
+ The fullstack TypeScript framework for AI-embedded widgets.<br />
12
+ **Type-safe. React-powered. Platform-agnostic.**
31
13
 
32
- ### Widgets
14
+ <br />
33
15
 
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.
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)
35
19
 
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.
20
+ <br />
37
21
 
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:
22
+ [Documentation](https://docs.skybridge.tech) · [Quick Start](https://docs.skybridge.tech/quickstart/create-new-app) · [Showcase](https://docs.skybridge.tech/showcase)
39
23
 
40
- _Project structure_
24
+ </div>
41
25
 
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
- ```
26
+ <br />
51
27
 
52
- _server/src/index.ts_
28
+ ## ✨ Why Skybridge?
53
29
 
54
- ```ts
55
- import { McpServer } from "skybridge/server";
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.
56
31
 
57
- const server = new McpServer();
32
+ **Skybridge fixes that.**
58
33
 
59
- server.widget(
60
- "pokemon"
61
- // Remaining arguments...
62
- );
63
- ```
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. |
64
39
 
65
- _web/src/widgets/pokemon.tsx_
40
+ <br />
66
41
 
67
- ```ts
68
- import { mountWidget } from "skybridge/web";
42
+ ## 🚀 Get Started
69
43
 
70
- const Pokemon: React.FunctionComponent = () => {
71
- // Your React component code goes here...
72
- };
44
+ **Create a new app:**
73
45
 
74
- mountWidget(<Pokemon />);
46
+ ```bash
47
+ npm create skybridge@latest
75
48
  ```
76
49
 
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.
86
-
87
- **Vite plugin**
50
+ **Or add to an existing project:**
88
51
 
89
- The `skybridge/web` package comes with a Vite plugin that allows you to build your widgets as regular Vite apps.
90
-
91
- ```ts
92
- import { defineConfig } from "vite";
93
- import { skybridge } from "skybridge/web";
94
-
95
- export default defineConfig({
96
- plugins: [skybridge()],
97
- });
52
+ ```bash
53
+ npm i skybridge
54
+ yarn add skybridge
55
+ pnpm add skybridge
56
+ bun add skybridge
57
+ deno add skybridge
98
58
  ```
99
59
 
100
- **Typed Hooks**
60
+ <div align="center">
101
61
 
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.
62
+ **👉 [Read the Docs](https://docs.skybridge.tech) 👈**
103
63
 
104
- > **Tip:** For the best TypeScript experience, use typed hooks throughout your application. They provide autocomplete, type safety, and better IDE support.
64
+ </div>
105
65
 
106
- > **Important:** For `generateHelpers` to work correctly, your MCP server must be defined using method chaining (e.g., `server.widget(...).widget(...).registerTool(...)`). This ensures TypeScript can properly infer the tool registry type from the chained calls.
66
+ <br />
107
67
 
108
- **Examples:**
68
+ ## 📦 Architecture
109
69
 
110
- **Works** - Using method chaining:
70
+ Skybridge is a fullstack framework with unified server and client modules:
111
71
 
112
- ```ts
113
- import { McpServer } from "skybridge/server";
114
- import { z } from "zod";
115
-
116
- const server = new McpServer({ name: "my-app", version: "1.0" }, {})
117
- .widget("search-voyage", {}, {
118
- inputSchema: { destination: z.string() },
119
- }, async ({ destination }) => {
120
- return { content: [{ type: "text", text: `Found trips to ${destination}` }] };
121
- })
122
- .registerTool("calculate-price", {
123
- inputSchema: { tripId: z.string() },
124
- }, async ({ tripId }) => {
125
- return { content: [{ type: "text", text: `Price for ${tripId}` }] };
126
- });
127
-
128
- export type AppType = typeof server; // ✅ Type inference works correctly
129
- ```
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.
130
75
 
131
- **Doesn't work** - Without method chaining:
76
+ ### Server
132
77
 
133
78
  ```ts
134
79
  import { McpServer } from "skybridge/server";
135
- import { z } from "zod";
136
-
137
- const server = new McpServer({ name: "my-app", version: "1.0" }, {});
138
80
 
139
- server.widget("search-voyage", {}, {
81
+ server.registerWidget("flights", {}, {
140
82
  inputSchema: { destination: z.string() },
141
83
  }, async ({ destination }) => {
142
- return { content: [{ type: "text", text: `Found trips to ${destination}` }] };
143
- });
144
-
145
- server.registerTool("calculate-price", {
146
- inputSchema: { tripId: z.string() },
147
- }, async ({ tripId }) => {
148
- return { content: [{ type: "text", text: `Price for ${tripId}` }] };
84
+ const flights = await searchFlights(destination);
85
+ return { structuredContent: { flights } };
149
86
  });
150
-
151
- export type AppType = typeof server; // ❌ Type inference fails - tool registry is empty
152
- ```
153
-
154
- _Server setup (server/src/index.ts)_
155
-
156
- ```ts
157
- import { McpServer } from "skybridge/server";
158
- import { z } from "zod";
159
-
160
- const server = new McpServer({ name: "my-app", version: "1.0" }, {})
161
- .widget("search-voyage", {}, {
162
- description: "Search for trips",
163
- inputSchema: {
164
- destination: z.string(),
165
- departureDate: z.string().optional(),
166
- },
167
- outputSchema: {
168
- results: z.array(z.object({ id: z.string(), name: z.string() })),
169
- totalCount: z.number(),
170
- },
171
- }, async ({ destination }) => {
172
- // Your tool logic here...
173
- return { content: [{ type: "text", text: `Found trips to ${destination}` }] };
174
- })
175
- .widget("get-details", {}, {
176
- inputSchema: { tripId: z.string() },
177
- }, async ({ tripId }) => {
178
- return { content: [{ type: "text", text: `Details for ${tripId}` }] };
179
- });
180
-
181
- // Export the server type for the client
182
- export type AppType = typeof server;
183
- ```
184
-
185
- _One-time setup (web/src/skybridge.ts)_
186
-
187
- Create typed hooks once and export them for use across your app. This file acts as a bridge between your server types and your widgets:
188
-
189
- ```ts
190
- import type { AppType } from "../server"; // type-only import
191
- import { generateHelpers } from "skybridge/web";
192
-
193
- export const { useCallTool, useToolInfo } = generateHelpers<AppType>();
194
87
  ```
195
88
 
196
- _Usage in widgets (web/src/widgets/search.tsx)_
89
+ ### Widget
197
90
 
198
91
  ```tsx
199
- import { useCallTool, useToolInfo } from "../skybridge"; // import typed hooks
200
-
201
- export function SearchWidget() {
202
- const { callTool, data, isPending } = useCallTool("search-voyage");
203
- // ^ autocomplete for tool names
204
- const toolInfo = useToolInfo<"search-voyage">();
205
- // ^ autocomplete for widget names
206
-
207
- const handleSearch = () => {
208
- callTool({ destination: "Spain" });
209
- // ^ autocomplete for input fields
210
- };
211
-
212
- return (
213
- <div>
214
- <button onClick={handleSearch} disabled={isPending}>
215
- Search
216
- </button>
217
- {toolInfo.isSuccess && (
218
- <div>Found {toolInfo.output.structuredContent.totalCount} results</div>
219
- // ^ typed output
220
- )}
221
- </div>
222
- );
223
- }
224
- ```
225
-
226
- **Hooks**
227
-
228
- The `skybridge/web` package comes with a set of hooks to help you build your widgets :
229
-
230
- - `useOpenAiGlobal`: A generic hook to get any global data from the OpenAI iFrame skybridge runtime (in `window.openai`).
231
- - `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.
232
- - `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.
233
- - `useToolInfo`: A hook to get the tool input, output, and response metadata with type inference. Provides a discriminated union based on status (pending/success).
234
- - `useCallTool`: A @tanstack/react-query inspired hook to send make additional tool calls inside a widget.
235
- - `generateHelpers`: A factory that creates typed versions of `useCallTool` and `useToolInfo` with full type inference from your server type.
236
-
237
- _useOpenAiGlobal_
238
-
239
- ```ts
240
- import { useOpenAiGlobal } from "skybridge/web";
241
-
242
- const theme = useOpenAiGlobal("theme");
243
- ```
244
-
245
- _useToolOutput_
246
-
247
- ```ts
248
- import { useToolOutput } from "skybridge/web";
249
-
250
- const toolOutput = useToolOutput();
251
- ```
252
-
253
- _useToolResponseMetadata_
254
-
255
- ```ts
256
- import { useToolResponseMetadata } from "skybridge/web";
257
-
258
- const toolResponseMetadata = useToolResponseMetadata();
259
- ```
260
-
261
- _useToolInfo_
262
-
263
- ```ts
264
92
  import { useToolInfo } from "skybridge/web";
265
93
 
266
- const toolInfo = useToolInfo<{
267
- input: { query: string };
268
- output: { results: string[] };
269
- responseMetadata: { id: number };
270
- }>();
271
-
272
- // toolInfo.input is typed based on the input type
273
- // toolInfo.output.structuredContent is typed based on the output type (undefined when pending)
274
- // toolInfo.status narrows correctly: "pending" | "success"
94
+ function FlightsWidget() {
95
+ const { output } = useToolInfo();
275
96
 
276
- if (toolInfo.isPending) {
277
- // toolInfo.output is undefined here (pending state)
278
- console.log(toolInfo.input.query);
279
- }
280
-
281
- if (toolInfo.isSuccess) {
282
- // toolInfo.output.structuredContent is typed here
283
- console.log(toolInfo.output.structuredContent.results);
97
+ return output.structuredContent.flights.map(flight =>
98
+ <FlightCard key={flight.id} flight={flight} />
99
+ );
284
100
  }
285
101
  ```
286
102
 
287
- _useToolInfo_ with typed hooks (recommended)
103
+ <br />
288
104
 
289
- ```tsx
290
- import { useToolInfo } from "../skybridge"; // import typed hooks
105
+ ## 🎯 Features at a Glance
291
106
 
292
- export function SearchWidget() {
293
- const toolInfo = useToolInfo<"search-voyage">();
294
- // ^ autocomplete for widget names
295
- // toolInfo.input is typed as { destination: string; departureDate?: string; ... }
296
- // toolInfo.output.structuredContent is typed as { results: Array<...>; totalCount: number; }
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.
297
114
 
298
- if (toolInfo.isSuccess) {
299
- return <div>Found {toolInfo.output.structuredContent.totalCount} results</div>;
300
- }
115
+ <br />
301
116
 
302
- return <div>Searching for {toolInfo.input.destination}...</div>;
303
- }
304
- ```
117
+ ## 📖 Showcase
305
118
 
306
- _useCallTool_ in synchronous mode
119
+ Explore production-ready examples:
307
120
 
308
- ```ts
309
- import { useCallTool } from "skybridge/web";
310
-
311
- export const TestTool: React.FunctionComponent = () => {
312
- const { callTool, isPending } = useCallTool("myToolName");
313
-
314
- return (
315
- <div>
316
- <button
317
- disabled={isPending}
318
- onClick={() => {
319
- callTool({ input: "test input" }, {
320
- onSuccess: (data) => {
321
- alert("Tool returned: " + data);
322
- },
323
- });
324
- >
325
- Call Tool inside a widget
326
- </button>
327
- </div>
328
- );
329
- };
330
- ```
331
-
332
- _useCallTool_ in asynchronous mode
333
-
334
- ```ts
335
- import { useCallTool } from "skybridge/web";
336
-
337
- export const TestTool: React.FunctionComponent = () => {
338
- const { callToolAsync, isPending } = useCallTool("myToolName");
339
-
340
- return (
341
- <div>
342
- <button
343
- disabled={isPending}
344
- onClick={async () => {
345
- const data = await callToolAsync({ input: "test input" });
346
- alert("Tool returned: " + data);
347
- }}
348
- >
349
- Call Tool inside a widget
350
- </button>
351
- </div>
352
- );
353
- };
354
- ```
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
+ | **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
+ | **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) |
355
128
 
356
- **State Management**
129
+ See all examples in the [Showcase](https://docs.skybridge.tech/showcase) or browse the [examples/](examples/) directory.
357
130
 
358
- The `skybridge/web` package provides `createStore` for creating Zustand stores with automatic persistence to `window.openai.widgetState`. This is useful when you need more advanced state management than what `useWidgetState` provides.
131
+ <br />
359
132
 
360
- _createStore_
361
-
362
- ```ts
363
- import { createStore } from "skybridge/web";
364
-
365
- type CounterState = {
366
- count: number;
367
- increment: () => void;
368
- decrement: () => void;
369
- };
370
-
371
- const useCounterStore = createStore<CounterState>(
372
- (set) => ({
373
- count: 0,
374
- increment: () => set((state) => ({ count: state.count + 1 })),
375
- decrement: () => set((state) => ({ count: state.count - 1 })),
376
- }),
377
- { count: 0 } // Optional default state
378
- );
379
-
380
- // Use in your component
381
- function CounterWidget() {
382
- const { count, increment, decrement } = useCounterStore();
383
-
384
- return (
385
- <div>
386
- <p>Count: {count}</p>
387
- <button onClick={increment}>Increment</button>
388
- <button onClick={decrement}>Decrement</button>
389
- </div>
390
- );
391
- }
392
- ```
393
-
394
- The `createStore` function:
395
-
396
- - Automatically persists state to `window.openai.widgetState`
397
- - Syncs with external state changes from the host
398
- - Only serializes state data, not methods
133
+ <div align="center">
399
134
 
400
- ## Migrate your existing MCP server to a ChatGPT app
135
+ [![GitHub Discussions](https://img.shields.io/badge/Discussions-Ask%20Questions-blue?style=flat-square&logo=github)](https://github.com/alpic-ai/skybridge/discussions)
136
+ [![GitHub Issues](https://img.shields.io/badge/Issues-Report%20Bugs-red?style=flat-square&logo=github)](https://github.com/alpic-ai/skybridge/issues)
137
+ [![Discord](https://img.shields.io/badge/Discord-Chat-5865F2?style=flat-square&logo=discord&logoColor=white)](https://discord.com/invite/gNAazGueab)
401
138
 
402
- If you're already using the `@modelcontextprotocol/sdk` to build a MCP server, you can migrate to a ChatGPT app by following these steps:
139
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions
403
140
 
404
- 1. Replace your `McpServer` import from `@modelcontextprotocol/sdk` with the same import from `skybridge/server`
405
- 2. Create a new vite project in a folder named `web` and install the `skybridge` package
406
- 3. Replace the `vite.config.ts` file with the following:
141
+ <br />
407
142
 
408
- ```ts
409
- import { defineConfig } from "vite";
410
- import { skybridge } from "skybridge/web";
143
+ **[MIT License](LICENSE)** · Made with ❤️ by **[Alpic](https://alpic.ai)**
411
144
 
412
- export default defineConfig({
413
- plugins: [skybridge()],
414
- });
415
- ```
145
+ </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"}
@@ -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"}