skybridge 0.0.0-dev.e9705ff → 0.0.0-dev.e9a7859

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 (556) hide show
  1. package/LICENSE +21 -674
  2. package/README.md +123 -386
  3. package/bin/run.js +5 -0
  4. package/dist/cli/build-helpers.d.ts +7 -0
  5. package/dist/cli/build-helpers.js +82 -0
  6. package/dist/cli/build-helpers.js.map +1 -0
  7. package/dist/cli/build-helpers.test.js +64 -0
  8. package/dist/cli/build-helpers.test.js.map +1 -0
  9. package/dist/cli/detect-port.d.ts +18 -0
  10. package/dist/cli/detect-port.js +50 -0
  11. package/dist/cli/detect-port.js.map +1 -0
  12. package/dist/cli/header.d.ts +4 -0
  13. package/dist/cli/header.js +6 -0
  14. package/dist/cli/header.js.map +1 -0
  15. package/dist/cli/resolve-views-dir.d.ts +1 -0
  16. package/dist/cli/resolve-views-dir.js +17 -0
  17. package/dist/cli/resolve-views-dir.js.map +1 -0
  18. package/dist/cli/run-command.d.ts +2 -0
  19. package/dist/cli/run-command.js +43 -0
  20. package/dist/cli/run-command.js.map +1 -0
  21. package/dist/cli/telemetry.d.ts +7 -0
  22. package/dist/cli/telemetry.js +123 -0
  23. package/dist/cli/telemetry.js.map +1 -0
  24. package/dist/cli/tunnel-control-server.d.ts +9 -0
  25. package/dist/cli/tunnel-control-server.js +31 -0
  26. package/dist/cli/tunnel-control-server.js.map +1 -0
  27. package/dist/cli/tunnel-control-server.test.js +39 -0
  28. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  29. package/dist/cli/tunnel-handler.d.ts +3 -0
  30. package/dist/cli/tunnel-handler.js +48 -0
  31. package/dist/cli/tunnel-handler.js.map +1 -0
  32. package/dist/cli/tunnel-handler.test.js +105 -0
  33. package/dist/cli/tunnel-handler.test.js.map +1 -0
  34. package/dist/cli/tunnel.d.ts +57 -0
  35. package/dist/cli/tunnel.js +154 -0
  36. package/dist/cli/tunnel.js.map +1 -0
  37. package/dist/cli/tunnel.test.js +190 -0
  38. package/dist/cli/tunnel.test.js.map +1 -0
  39. package/dist/cli/types.d.ts +5 -0
  40. package/dist/cli/types.js +2 -0
  41. package/dist/cli/types.js.map +1 -0
  42. package/dist/cli/use-execute-steps.d.ts +11 -0
  43. package/dist/cli/use-execute-steps.js +36 -0
  44. package/dist/cli/use-execute-steps.js.map +1 -0
  45. package/dist/cli/use-messages.d.ts +3 -0
  46. package/dist/cli/use-messages.js +11 -0
  47. package/dist/cli/use-messages.js.map +1 -0
  48. package/dist/cli/use-nodemon.d.ts +2 -0
  49. package/dist/cli/use-nodemon.js +73 -0
  50. package/dist/cli/use-nodemon.js.map +1 -0
  51. package/dist/cli/use-open-browser.d.ts +1 -0
  52. package/dist/cli/use-open-browser.js +44 -0
  53. package/dist/cli/use-open-browser.js.map +1 -0
  54. package/dist/cli/use-tunnel.d.ts +14 -0
  55. package/dist/cli/use-tunnel.js +131 -0
  56. package/dist/cli/use-tunnel.js.map +1 -0
  57. package/dist/cli/use-typescript-check.d.ts +9 -0
  58. package/dist/cli/use-typescript-check.js +94 -0
  59. package/dist/cli/use-typescript-check.js.map +1 -0
  60. package/dist/commands/build.d.ts +8 -0
  61. package/dist/commands/build.js +90 -0
  62. package/dist/commands/build.js.map +1 -0
  63. package/dist/commands/create.d.ts +9 -0
  64. package/dist/commands/create.js +30 -0
  65. package/dist/commands/create.js.map +1 -0
  66. package/dist/commands/dev.d.ts +12 -0
  67. package/dist/commands/dev.js +96 -0
  68. package/dist/commands/dev.js.map +1 -0
  69. package/dist/commands/start.d.ts +9 -0
  70. package/dist/commands/start.js +55 -0
  71. package/dist/commands/start.js.map +1 -0
  72. package/dist/commands/telemetry/disable.d.ts +5 -0
  73. package/dist/commands/telemetry/disable.js +14 -0
  74. package/dist/commands/telemetry/disable.js.map +1 -0
  75. package/dist/commands/telemetry/enable.d.ts +5 -0
  76. package/dist/commands/telemetry/enable.js +14 -0
  77. package/dist/commands/telemetry/enable.js.map +1 -0
  78. package/dist/commands/telemetry/status.d.ts +5 -0
  79. package/dist/commands/telemetry/status.js +14 -0
  80. package/dist/commands/telemetry/status.js.map +1 -0
  81. package/dist/server/asset-base-url-transform-plugin.d.ts +11 -0
  82. package/dist/server/asset-base-url-transform-plugin.js +48 -0
  83. package/dist/server/asset-base-url-transform-plugin.js.map +1 -0
  84. package/dist/server/asset-base-url-transform-plugin.test.js +134 -0
  85. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -0
  86. package/dist/server/auth/discovery.d.ts +32 -0
  87. package/dist/server/auth/discovery.js +56 -0
  88. package/dist/server/auth/discovery.js.map +1 -0
  89. package/dist/server/auth/discovery.test.js +93 -0
  90. package/dist/server/auth/discovery.test.js.map +1 -0
  91. package/dist/server/auth/index.d.ts +18 -0
  92. package/dist/server/auth/index.js +2 -0
  93. package/dist/server/auth/index.js.map +1 -0
  94. package/dist/server/auth/providers/auth0.d.ts +18 -0
  95. package/dist/server/auth/providers/auth0.js +31 -0
  96. package/dist/server/auth/providers/auth0.js.map +1 -0
  97. package/dist/server/auth/providers/auth0.test.js +48 -0
  98. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  99. package/dist/server/auth/providers/clerk.d.ts +14 -0
  100. package/dist/server/auth/providers/clerk.js +16 -0
  101. package/dist/server/auth/providers/clerk.js.map +1 -0
  102. package/dist/server/auth/providers/clerk.test.js +28 -0
  103. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  104. package/dist/server/auth/providers/custom.d.ts +24 -0
  105. package/dist/server/auth/providers/custom.js +37 -0
  106. package/dist/server/auth/providers/custom.js.map +1 -0
  107. package/dist/server/auth/providers/custom.test.js +107 -0
  108. package/dist/server/auth/providers/custom.test.js.map +1 -0
  109. package/dist/server/auth/providers/descope.d.ts +15 -0
  110. package/dist/server/auth/providers/descope.js +34 -0
  111. package/dist/server/auth/providers/descope.js.map +1 -0
  112. package/dist/server/auth/providers/descope.test.js +38 -0
  113. package/dist/server/auth/providers/descope.test.js.map +1 -0
  114. package/dist/server/auth/providers/shared.d.ts +2 -0
  115. package/dist/server/auth/providers/shared.js +6 -0
  116. package/dist/server/auth/providers/shared.js.map +1 -0
  117. package/dist/server/auth/providers/shared.test.js +10 -0
  118. package/dist/server/auth/providers/shared.test.js.map +1 -0
  119. package/dist/server/auth/providers/stytch.d.ts +12 -0
  120. package/dist/server/auth/providers/stytch.js +13 -0
  121. package/dist/server/auth/providers/stytch.js.map +1 -0
  122. package/dist/server/auth/providers/workos.d.ts +11 -0
  123. package/dist/server/auth/providers/workos.js +12 -0
  124. package/dist/server/auth/providers/workos.js.map +1 -0
  125. package/dist/server/auth/setup.d.ts +4 -0
  126. package/dist/server/auth/setup.js +51 -0
  127. package/dist/server/auth/setup.js.map +1 -0
  128. package/dist/server/auth/setup.test.js +185 -0
  129. package/dist/server/auth/setup.test.js.map +1 -0
  130. package/dist/server/auth/verify.d.ts +12 -0
  131. package/dist/server/auth/verify.js +38 -0
  132. package/dist/server/auth/verify.js.map +1 -0
  133. package/dist/server/auth/verify.test.js +100 -0
  134. package/dist/server/auth/verify.test.js.map +1 -0
  135. package/dist/server/auth.d.ts +20 -0
  136. package/dist/server/auth.js +28 -0
  137. package/dist/server/auth.js.map +1 -0
  138. package/dist/server/build-manifest.test.js +27 -0
  139. package/dist/server/build-manifest.test.js.map +1 -0
  140. package/dist/server/content-helpers.d.ts +67 -0
  141. package/dist/server/content-helpers.js +79 -0
  142. package/dist/server/content-helpers.js.map +1 -0
  143. package/dist/server/content-helpers.test.js +70 -0
  144. package/dist/server/content-helpers.test.js.map +1 -0
  145. package/dist/server/express.d.ts +11 -0
  146. package/dist/server/express.js +101 -0
  147. package/dist/server/express.js.map +1 -0
  148. package/dist/server/express.test.js +491 -0
  149. package/dist/server/express.test.js.map +1 -0
  150. package/dist/server/file-ref.d.ts +28 -0
  151. package/dist/server/file-ref.js +27 -0
  152. package/dist/server/file-ref.js.map +1 -0
  153. package/dist/server/index.d.ts +15 -0
  154. package/dist/server/index.js +12 -0
  155. package/dist/server/index.js.map +1 -0
  156. package/dist/{src/server → server}/inferUtilityTypes.d.ts +15 -5
  157. package/dist/server/inferUtilityTypes.js.map +1 -0
  158. package/dist/server/metric.d.ts +14 -0
  159. package/dist/server/metric.js +62 -0
  160. package/dist/server/metric.js.map +1 -0
  161. package/dist/server/middleware.d.ts +137 -0
  162. package/dist/server/middleware.js +93 -0
  163. package/dist/server/middleware.js.map +1 -0
  164. package/dist/server/middleware.test-d.js +75 -0
  165. package/dist/server/middleware.test-d.js.map +1 -0
  166. package/dist/server/middleware.test.js +493 -0
  167. package/dist/server/middleware.test.js.map +1 -0
  168. package/dist/server/requestOrigin.d.ts +7 -0
  169. package/dist/server/requestOrigin.js +25 -0
  170. package/dist/server/requestOrigin.js.map +1 -0
  171. package/dist/server/server.d.ts +419 -0
  172. package/dist/server/server.js +632 -0
  173. package/dist/server/server.js.map +1 -0
  174. package/dist/{src/server → server}/templateHelper.d.ts +5 -4
  175. package/dist/server/templateHelper.js +11 -0
  176. package/dist/server/templateHelper.js.map +1 -0
  177. package/dist/server/templates.generated.d.ts +4 -0
  178. package/dist/server/templates.generated.js +47 -0
  179. package/dist/server/templates.generated.js.map +1 -0
  180. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  181. package/dist/server/tunnel-proxy-router.js +110 -0
  182. package/dist/server/tunnel-proxy-router.js.map +1 -0
  183. package/dist/server/tunnel-proxy-router.test.js +229 -0
  184. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  185. package/dist/server/view-name.test-d.js +8 -0
  186. package/dist/server/view-name.test-d.js.map +1 -0
  187. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  188. package/dist/server/view-resource-resolution.test.js +171 -0
  189. package/dist/server/view-resource-resolution.test.js.map +1 -0
  190. package/dist/server/viewsDevServer.d.ts +14 -0
  191. package/dist/server/viewsDevServer.js +45 -0
  192. package/dist/server/viewsDevServer.js.map +1 -0
  193. package/dist/test/utils.d.ts +127 -0
  194. package/dist/test/utils.js +247 -0
  195. package/dist/test/utils.js.map +1 -0
  196. package/dist/test/view.test.d.ts +1 -0
  197. package/dist/test/view.test.js +536 -0
  198. package/dist/test/view.test.js.map +1 -0
  199. package/dist/version.d.ts +1 -0
  200. package/dist/version.js +3 -0
  201. package/dist/version.js.map +1 -0
  202. package/dist/web/bridges/adaptor.d.ts +51 -0
  203. package/dist/web/bridges/adaptor.js +313 -0
  204. package/dist/web/bridges/adaptor.js.map +1 -0
  205. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  206. package/dist/web/bridges/adaptor.test.js +197 -0
  207. package/dist/web/bridges/adaptor.test.js.map +1 -0
  208. package/dist/web/bridges/apps-sdk/bridge.d.ts +15 -0
  209. package/dist/web/bridges/apps-sdk/bridge.js +58 -0
  210. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -0
  211. package/dist/web/bridges/apps-sdk/index.d.ts +4 -0
  212. package/dist/web/bridges/apps-sdk/index.js +4 -0
  213. package/dist/web/bridges/apps-sdk/index.js.map +1 -0
  214. package/dist/web/bridges/apps-sdk/types.d.ts +133 -0
  215. package/dist/{src/web → web/bridges/apps-sdk}/types.js +0 -1
  216. package/dist/web/bridges/apps-sdk/types.js.map +1 -0
  217. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +13 -0
  218. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +18 -0
  219. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -0
  220. package/dist/web/bridges/get-adaptor.d.ts +9 -0
  221. package/dist/web/bridges/get-adaptor.js +10 -0
  222. package/dist/web/bridges/get-adaptor.js.map +1 -0
  223. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  224. package/dist/web/bridges/get-adaptor.test.js +32 -0
  225. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  226. package/dist/web/bridges/index.d.ts +5 -0
  227. package/dist/web/bridges/index.js +6 -0
  228. package/dist/web/bridges/index.js.map +1 -0
  229. package/dist/web/bridges/mcp-app/bridge.d.ts +39 -0
  230. package/dist/web/bridges/mcp-app/bridge.js +166 -0
  231. package/dist/web/bridges/mcp-app/bridge.js.map +1 -0
  232. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  233. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  234. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  235. package/dist/web/bridges/mcp-app/index.d.ts +3 -0
  236. package/dist/web/bridges/mcp-app/index.js +3 -0
  237. package/dist/web/bridges/mcp-app/index.js.map +1 -0
  238. package/dist/web/bridges/mcp-app/types.d.ts +8 -0
  239. package/dist/web/bridges/mcp-app/types.js +2 -0
  240. package/dist/web/bridges/mcp-app/types.js.map +1 -0
  241. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +19 -0
  242. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +19 -0
  243. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -0
  244. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.d.ts +1 -0
  245. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +26 -0
  246. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -0
  247. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  248. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  249. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  250. package/dist/web/bridges/types.d.ts +214 -0
  251. package/dist/web/bridges/types.js +15 -0
  252. package/dist/web/bridges/types.js.map +1 -0
  253. package/dist/web/bridges/types.test.d.ts +1 -0
  254. package/dist/web/bridges/types.test.js +19 -0
  255. package/dist/web/bridges/types.test.js.map +1 -0
  256. package/dist/web/bridges/use-host-context.d.ts +7 -0
  257. package/dist/web/bridges/use-host-context.js +13 -0
  258. package/dist/web/bridges/use-host-context.js.map +1 -0
  259. package/dist/web/components/modal-provider.d.ts +4 -0
  260. package/dist/web/components/modal-provider.js +46 -0
  261. package/dist/web/components/modal-provider.js.map +1 -0
  262. package/dist/web/create-store.d.ts +29 -0
  263. package/dist/web/create-store.js +64 -0
  264. package/dist/web/create-store.js.map +1 -0
  265. package/dist/web/create-store.test.d.ts +1 -0
  266. package/dist/web/create-store.test.js +132 -0
  267. package/dist/web/create-store.test.js.map +1 -0
  268. package/dist/web/data-llm.d.ts +47 -0
  269. package/dist/{src/web → web}/data-llm.js +41 -9
  270. package/dist/web/data-llm.js.map +1 -0
  271. package/dist/web/data-llm.test.d.ts +1 -0
  272. package/dist/web/data-llm.test.js +146 -0
  273. package/dist/web/data-llm.test.js.map +1 -0
  274. package/dist/{src/web → web}/generate-helpers.d.ts +32 -25
  275. package/dist/{src/web → web}/generate-helpers.js +26 -20
  276. package/dist/web/generate-helpers.js.map +1 -0
  277. package/dist/web/generate-helpers.test-d.d.ts +1 -0
  278. package/dist/{src/web → web}/generate-helpers.test-d.js +81 -23
  279. package/dist/web/generate-helpers.test-d.js.map +1 -0
  280. package/dist/web/generate-helpers.test.d.ts +1 -0
  281. package/dist/{src/web → web}/generate-helpers.test.js +1 -1
  282. package/dist/web/generate-helpers.test.js.map +1 -0
  283. package/dist/{src/web → web}/helpers/state.d.ts +2 -2
  284. package/dist/web/helpers/state.js +45 -0
  285. package/dist/web/helpers/state.js.map +1 -0
  286. package/dist/web/helpers/state.test.d.ts +1 -0
  287. package/dist/web/helpers/state.test.js +53 -0
  288. package/dist/web/helpers/state.test.js.map +1 -0
  289. package/dist/web/hooks/index.d.ts +15 -0
  290. package/dist/web/hooks/index.js +16 -0
  291. package/dist/web/hooks/index.js.map +1 -0
  292. package/dist/web/hooks/test/utils.d.ts +20 -0
  293. package/dist/web/hooks/test/utils.js +75 -0
  294. package/dist/web/hooks/test/utils.js.map +1 -0
  295. package/dist/{src/web → web}/hooks/use-call-tool.d.ts +48 -2
  296. package/dist/web/hooks/use-call-tool.js +96 -0
  297. package/dist/web/hooks/use-call-tool.js.map +1 -0
  298. package/dist/web/hooks/use-call-tool.test-d.d.ts +1 -0
  299. package/dist/{src/web → web}/hooks/use-call-tool.test-d.js +1 -1
  300. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  301. package/dist/web/hooks/use-call-tool.test.d.ts +1 -0
  302. package/dist/{src/web → web}/hooks/use-call-tool.test.js +93 -39
  303. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  304. package/dist/web/hooks/use-display-mode.d.ts +24 -0
  305. package/dist/web/hooks/use-display-mode.js +29 -0
  306. package/dist/web/hooks/use-display-mode.js.map +1 -0
  307. package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
  308. package/dist/web/hooks/use-display-mode.test-d.js +8 -0
  309. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
  310. package/dist/web/hooks/use-display-mode.test.d.ts +1 -0
  311. package/dist/web/hooks/use-display-mode.test.js +77 -0
  312. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  313. package/dist/web/hooks/use-download.d.ts +5 -0
  314. package/dist/web/hooks/use-download.js +8 -0
  315. package/dist/web/hooks/use-download.js.map +1 -0
  316. package/dist/web/hooks/use-download.test.d.ts +1 -0
  317. package/dist/web/hooks/use-download.test.js +103 -0
  318. package/dist/web/hooks/use-download.test.js.map +1 -0
  319. package/dist/web/hooks/use-files.d.ts +39 -0
  320. package/dist/web/hooks/use-files.js +42 -0
  321. package/dist/web/hooks/use-files.js.map +1 -0
  322. package/dist/web/hooks/use-files.test.d.ts +1 -0
  323. package/dist/web/hooks/use-files.test.js +62 -0
  324. package/dist/web/hooks/use-files.test.js.map +1 -0
  325. package/dist/web/hooks/use-layout.d.ts +24 -0
  326. package/dist/web/hooks/use-layout.js +25 -0
  327. package/dist/web/hooks/use-layout.js.map +1 -0
  328. package/dist/web/hooks/use-layout.test.d.ts +1 -0
  329. package/dist/web/hooks/use-layout.test.js +129 -0
  330. package/dist/web/hooks/use-layout.test.js.map +1 -0
  331. package/dist/web/hooks/use-open-external.d.ts +20 -0
  332. package/dist/web/hooks/use-open-external.js +24 -0
  333. package/dist/web/hooks/use-open-external.js.map +1 -0
  334. package/dist/web/hooks/use-open-external.test.d.ts +1 -0
  335. package/dist/web/hooks/use-open-external.test.js +75 -0
  336. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  337. package/dist/web/hooks/use-register-view-tool.d.ts +38 -0
  338. package/dist/web/hooks/use-register-view-tool.js +50 -0
  339. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  340. package/dist/web/hooks/use-request-close.d.ts +16 -0
  341. package/dist/web/hooks/use-request-close.js +21 -0
  342. package/dist/web/hooks/use-request-close.js.map +1 -0
  343. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  344. package/dist/web/hooks/use-request-close.test.js +47 -0
  345. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  346. package/dist/web/hooks/use-request-modal.d.ts +24 -0
  347. package/dist/web/hooks/use-request-modal.js +31 -0
  348. package/dist/web/hooks/use-request-modal.js.map +1 -0
  349. package/dist/web/hooks/use-request-modal.test.d.ts +1 -0
  350. package/dist/web/hooks/use-request-modal.test.js +71 -0
  351. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  352. package/dist/web/hooks/use-request-size.d.ts +20 -0
  353. package/dist/web/hooks/use-request-size.js +24 -0
  354. package/dist/web/hooks/use-request-size.js.map +1 -0
  355. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  356. package/dist/web/hooks/use-request-size.test.js +47 -0
  357. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  358. package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -0
  359. package/dist/web/hooks/use-send-follow-up-message.js +25 -0
  360. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  361. package/dist/web/hooks/use-set-open-in-app-url.d.ts +18 -0
  362. package/dist/web/hooks/use-set-open-in-app-url.js +25 -0
  363. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -0
  364. package/dist/web/hooks/use-set-open-in-app-url.test.d.ts +1 -0
  365. package/dist/web/hooks/use-set-open-in-app-url.test.js +63 -0
  366. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -0
  367. package/dist/web/hooks/use-tool-info.d.ts +87 -0
  368. package/dist/web/hooks/use-tool-info.js +49 -0
  369. package/dist/web/hooks/use-tool-info.js.map +1 -0
  370. package/dist/web/hooks/use-tool-info.test-d.d.ts +1 -0
  371. package/dist/{src/web → web}/hooks/use-tool-info.test-d.js +24 -7
  372. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  373. package/dist/web/hooks/use-tool-info.test.d.ts +1 -0
  374. package/dist/web/hooks/use-tool-info.test.js +140 -0
  375. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  376. package/dist/web/hooks/use-user.d.ts +20 -0
  377. package/dist/web/hooks/use-user.js +37 -0
  378. package/dist/web/hooks/use-user.js.map +1 -0
  379. package/dist/web/hooks/use-user.test.d.ts +1 -0
  380. package/dist/web/hooks/use-user.test.js +168 -0
  381. package/dist/web/hooks/use-user.test.js.map +1 -0
  382. package/dist/web/hooks/use-view-state.d.ts +25 -0
  383. package/dist/web/hooks/use-view-state.js +32 -0
  384. package/dist/web/hooks/use-view-state.js.map +1 -0
  385. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  386. package/dist/web/hooks/use-view-state.test.js +181 -0
  387. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  388. package/dist/{src/web → web}/index.d.ts +5 -5
  389. package/dist/{src/web → web}/index.js +5 -5
  390. package/dist/web/index.js.map +1 -0
  391. package/dist/web/mount-view.d.ts +20 -0
  392. package/dist/web/mount-view.js +46 -0
  393. package/dist/web/mount-view.js.map +1 -0
  394. package/dist/web/plugin/data-llm.test.d.ts +1 -0
  395. package/dist/web/plugin/data-llm.test.js.map +1 -0
  396. package/dist/web/plugin/plugin.d.ts +33 -0
  397. package/dist/web/plugin/plugin.js +189 -0
  398. package/dist/web/plugin/plugin.js.map +1 -0
  399. package/dist/web/plugin/scan-views.d.ts +16 -0
  400. package/dist/web/plugin/scan-views.js +88 -0
  401. package/dist/web/plugin/scan-views.js.map +1 -0
  402. package/dist/web/plugin/scan-views.test.d.ts +1 -0
  403. package/dist/web/plugin/scan-views.test.js +99 -0
  404. package/dist/web/plugin/scan-views.test.js.map +1 -0
  405. package/dist/{src/web → web}/plugin/transform-data-llm.js +7 -4
  406. package/dist/web/plugin/transform-data-llm.js.map +1 -0
  407. package/dist/web/plugin/transform-data-llm.test.d.ts +1 -0
  408. package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
  409. package/dist/web/plugin/validate-view.d.ts +1 -0
  410. package/dist/web/plugin/validate-view.js +9 -0
  411. package/dist/web/plugin/validate-view.js.map +1 -0
  412. package/dist/web/plugin/validate-view.test.d.ts +1 -0
  413. package/dist/web/plugin/validate-view.test.js +24 -0
  414. package/dist/web/plugin/validate-view.test.js.map +1 -0
  415. package/dist/{src/web → web}/proxy.js +6 -2
  416. package/dist/web/proxy.js.map +1 -0
  417. package/dist/web/types.d.ts +20 -0
  418. package/dist/web/types.js +2 -0
  419. package/dist/web/types.js.map +1 -0
  420. package/package.json +86 -38
  421. package/tsconfig.base.json +33 -0
  422. package/dist/src/server/index.d.ts +0 -4
  423. package/dist/src/server/index.js +0 -3
  424. package/dist/src/server/index.js.map +0 -1
  425. package/dist/src/server/inferUtilityTypes.js.map +0 -1
  426. package/dist/src/server/server.d.ts +0 -48
  427. package/dist/src/server/server.js +0 -62
  428. package/dist/src/server/server.js.map +0 -1
  429. package/dist/src/server/templateHelper.js +0 -29
  430. package/dist/src/server/templateHelper.js.map +0 -1
  431. package/dist/src/server/templates/development.hbs +0 -12
  432. package/dist/src/server/templates/production.hbs +0 -6
  433. package/dist/src/server/widgetsDevServer.d.ts +0 -12
  434. package/dist/src/server/widgetsDevServer.js +0 -39
  435. package/dist/src/server/widgetsDevServer.js.map +0 -1
  436. package/dist/src/test/utils.d.ts +0 -89
  437. package/dist/src/test/utils.js +0 -164
  438. package/dist/src/test/utils.js.map +0 -1
  439. package/dist/src/test/widget.test.js +0 -90
  440. package/dist/src/test/widget.test.js.map +0 -1
  441. package/dist/src/web/create-store.d.ts +0 -3
  442. package/dist/src/web/create-store.js +0 -25
  443. package/dist/src/web/create-store.js.map +0 -1
  444. package/dist/src/web/create-store.test.js +0 -70
  445. package/dist/src/web/create-store.test.js.map +0 -1
  446. package/dist/src/web/data-llm.d.ts +0 -14
  447. package/dist/src/web/data-llm.js.map +0 -1
  448. package/dist/src/web/data-llm.test.js +0 -76
  449. package/dist/src/web/data-llm.test.js.map +0 -1
  450. package/dist/src/web/generate-helpers.js.map +0 -1
  451. package/dist/src/web/generate-helpers.test-d.js.map +0 -1
  452. package/dist/src/web/generate-helpers.test.js.map +0 -1
  453. package/dist/src/web/helpers/state.js +0 -40
  454. package/dist/src/web/helpers/state.js.map +0 -1
  455. package/dist/src/web/helpers/state.test.js +0 -46
  456. package/dist/src/web/helpers/state.test.js.map +0 -1
  457. package/dist/src/web/hooks/index.d.ts +0 -12
  458. package/dist/src/web/hooks/index.js +0 -13
  459. package/dist/src/web/hooks/index.js.map +0 -1
  460. package/dist/src/web/hooks/use-call-tool.js +0 -60
  461. package/dist/src/web/hooks/use-call-tool.js.map +0 -1
  462. package/dist/src/web/hooks/use-call-tool.test-d.js.map +0 -1
  463. package/dist/src/web/hooks/use-call-tool.test.js.map +0 -1
  464. package/dist/src/web/hooks/use-display-mode.d.ts +0 -4
  465. package/dist/src/web/hooks/use-display-mode.js +0 -7
  466. package/dist/src/web/hooks/use-display-mode.js.map +0 -1
  467. package/dist/src/web/hooks/use-display-mode.test.js +0 -40
  468. package/dist/src/web/hooks/use-display-mode.test.js.map +0 -1
  469. package/dist/src/web/hooks/use-files.d.ts +0 -10
  470. package/dist/src/web/hooks/use-files.js +0 -7
  471. package/dist/src/web/hooks/use-files.js.map +0 -1
  472. package/dist/src/web/hooks/use-files.test.js +0 -29
  473. package/dist/src/web/hooks/use-files.test.js.map +0 -1
  474. package/dist/src/web/hooks/use-locale.d.ts +0 -1
  475. package/dist/src/web/hooks/use-locale.js +0 -5
  476. package/dist/src/web/hooks/use-locale.js.map +0 -1
  477. package/dist/src/web/hooks/use-locale.test.js +0 -21
  478. package/dist/src/web/hooks/use-locale.test.js.map +0 -1
  479. package/dist/src/web/hooks/use-open-external.d.ts +0 -1
  480. package/dist/src/web/hooks/use-open-external.js +0 -6
  481. package/dist/src/web/hooks/use-open-external.js.map +0 -1
  482. package/dist/src/web/hooks/use-open-external.test.js +0 -24
  483. package/dist/src/web/hooks/use-open-external.test.js.map +0 -1
  484. package/dist/src/web/hooks/use-openai-global.d.ts +0 -2
  485. package/dist/src/web/hooks/use-openai-global.js +0 -23
  486. package/dist/src/web/hooks/use-openai-global.js.map +0 -1
  487. package/dist/src/web/hooks/use-request-modal.d.ts +0 -6
  488. package/dist/src/web/hooks/use-request-modal.js +0 -9
  489. package/dist/src/web/hooks/use-request-modal.js.map +0 -1
  490. package/dist/src/web/hooks/use-request-modal.test.js +0 -24
  491. package/dist/src/web/hooks/use-request-modal.test.js.map +0 -1
  492. package/dist/src/web/hooks/use-send-follow-up-message.d.ts +0 -1
  493. package/dist/src/web/hooks/use-send-follow-up-message.js +0 -11
  494. package/dist/src/web/hooks/use-send-follow-up-message.js.map +0 -1
  495. package/dist/src/web/hooks/use-theme.d.ts +0 -1
  496. package/dist/src/web/hooks/use-theme.js +0 -5
  497. package/dist/src/web/hooks/use-theme.js.map +0 -1
  498. package/dist/src/web/hooks/use-theme.test.js +0 -26
  499. package/dist/src/web/hooks/use-theme.test.js.map +0 -1
  500. package/dist/src/web/hooks/use-tool-info.d.ts +0 -25
  501. package/dist/src/web/hooks/use-tool-info.js +0 -22
  502. package/dist/src/web/hooks/use-tool-info.js.map +0 -1
  503. package/dist/src/web/hooks/use-tool-info.test-d.js.map +0 -1
  504. package/dist/src/web/hooks/use-tool-info.test.js +0 -59
  505. package/dist/src/web/hooks/use-tool-info.test.js.map +0 -1
  506. package/dist/src/web/hooks/use-user-agent.d.ts +0 -1
  507. package/dist/src/web/hooks/use-user-agent.js +0 -5
  508. package/dist/src/web/hooks/use-user-agent.js.map +0 -1
  509. package/dist/src/web/hooks/use-user-agent.test.js +0 -31
  510. package/dist/src/web/hooks/use-user-agent.test.js.map +0 -1
  511. package/dist/src/web/hooks/use-widget-state.d.ts +0 -4
  512. package/dist/src/web/hooks/use-widget-state.js +0 -32
  513. package/dist/src/web/hooks/use-widget-state.js.map +0 -1
  514. package/dist/src/web/hooks/use-widget-state.test.js +0 -60
  515. package/dist/src/web/hooks/use-widget-state.test.js.map +0 -1
  516. package/dist/src/web/index.js.map +0 -1
  517. package/dist/src/web/mount-widget.d.ts +0 -1
  518. package/dist/src/web/mount-widget.js +0 -19
  519. package/dist/src/web/mount-widget.js.map +0 -1
  520. package/dist/src/web/plugin/data-llm.test.js.map +0 -1
  521. package/dist/src/web/plugin/plugin.d.ts +0 -2
  522. package/dist/src/web/plugin/plugin.js +0 -33
  523. package/dist/src/web/plugin/plugin.js.map +0 -1
  524. package/dist/src/web/plugin/transform-data-llm.js.map +0 -1
  525. package/dist/src/web/plugin/transform-data-llm.test.js.map +0 -1
  526. package/dist/src/web/proxy.js.map +0 -1
  527. package/dist/src/web/types.d.ts +0 -133
  528. package/dist/src/web/types.js.map +0 -1
  529. package/dist/vitest.config.d.ts +0 -2
  530. package/dist/vitest.config.js +0 -8
  531. package/dist/vitest.config.js.map +0 -1
  532. /package/dist/{src/test/widget.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  533. /package/dist/{src/web/create-store.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
  534. /package/dist/{src/web/data-llm.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
  535. /package/dist/{src/web/generate-helpers.test-d.d.ts → cli/tunnel.test.d.ts} +0 -0
  536. /package/dist/{src/web/generate-helpers.test.d.ts → server/asset-base-url-transform-plugin.test.d.ts} +0 -0
  537. /package/dist/{src/web/helpers/state.test.d.ts → server/auth/discovery.test.d.ts} +0 -0
  538. /package/dist/{src/web/hooks/use-call-tool.test-d.d.ts → server/auth/providers/auth0.test.d.ts} +0 -0
  539. /package/dist/{src/web/hooks/use-call-tool.test.d.ts → server/auth/providers/clerk.test.d.ts} +0 -0
  540. /package/dist/{src/web/hooks/use-display-mode.test.d.ts → server/auth/providers/custom.test.d.ts} +0 -0
  541. /package/dist/{src/web/hooks/use-files.test.d.ts → server/auth/providers/descope.test.d.ts} +0 -0
  542. /package/dist/{src/web/hooks/use-locale.test.d.ts → server/auth/providers/shared.test.d.ts} +0 -0
  543. /package/dist/{src/web/hooks/use-open-external.test.d.ts → server/auth/setup.test.d.ts} +0 -0
  544. /package/dist/{src/web/hooks/use-request-modal.test.d.ts → server/auth/verify.test.d.ts} +0 -0
  545. /package/dist/{src/web/hooks/use-theme.test.d.ts → server/build-manifest.test.d.ts} +0 -0
  546. /package/dist/{src/web/hooks/use-tool-info.test-d.d.ts → server/content-helpers.test.d.ts} +0 -0
  547. /package/dist/{src/web/hooks/use-tool-info.test.d.ts → server/express.test.d.ts} +0 -0
  548. /package/dist/{src/server → server}/inferUtilityTypes.js +0 -0
  549. /package/dist/{src/web/hooks/use-user-agent.test.d.ts → server/middleware.test-d.d.ts} +0 -0
  550. /package/dist/{src/web/hooks/use-widget-state.test.d.ts → server/middleware.test.d.ts} +0 -0
  551. /package/dist/{src/web/plugin/data-llm.test.d.ts → server/tunnel-proxy-router.test.d.ts} +0 -0
  552. /package/dist/{src/web/plugin/transform-data-llm.test.d.ts → server/view-name.test-d.d.ts} +0 -0
  553. /package/dist/{src/web → web}/plugin/data-llm.test.js +0 -0
  554. /package/dist/{src/web → web}/plugin/transform-data-llm.d.ts +0 -0
  555. /package/dist/{src/web → web}/plugin/transform-data-llm.test.js +0 -0
  556. /package/dist/{src/web → web}/proxy.d.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-helpers.js","sourceRoot":"","sources":["../../src/cli/build-helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n cpSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport path from \"node:path\";\n\n// Primes the manifest in skybridge's module scope, then dynamically imports\n// `./server.js` so user code runs *after* the side channel is set. The\n// dynamic import is load-bearing: a static `export { default } from ...` is\n// hoisted with the rest of the static graph and would evaluate `server.js`\n// before `__setBuildManifest` runs.\nexport const ENTRY_WRAPPER_CONTENT = `import { __setBuildManifest } from \"skybridge/server\";\nimport manifest from \"./vite-manifest.js\";\n\n__setBuildManifest(manifest);\n\nconst userMod = await import(\"./server.js\");\nexport default userMod.default;\n`;\n\nexport function emitEntryWrapper(distDir: string): void {\n writeFileSync(path.join(distDir, \"__entry.js\"), ENTRY_WRAPPER_CONTENT);\n}\n\nexport function emitManifestModule(\n manifestPath: string,\n outPath: string,\n): void {\n const manifest = readFileSync(manifestPath, \"utf-8\");\n writeFileSync(outPath, `export default ${manifest};\\n`);\n}\n\nexport const VERCEL_FUNCTION_NAME = \"mcp\";\n\nexport const VERCEL_CONFIG: unknown = {\n version: 3,\n routes: [\n {\n src: \"/assets/(.*)\",\n headers: { \"Access-Control-Allow-Origin\": \"*\" },\n continue: true,\n },\n { handle: \"filesystem\" },\n { src: \"/(.*)\", dest: `/${VERCEL_FUNCTION_NAME}` },\n ],\n};\n\nexport const VERCEL_VC_CONFIG: unknown = {\n runtime: \"nodejs22.x\",\n handler: \"index.js\",\n launcherType: \"Nodejs\",\n shouldAddHelpers: true,\n};\n\n// Emit a Build Output API tree under `.vercel/output/`. Bundling the server\n// with esbuild produces a self-contained function bundle, so we don't ship\n// `node_modules` and don't touch tracked paths like `api/` or `public/`.\n//\n// Entry is `dist/__entry.js` — the wrapper that primes the Vite manifest via\n// `__setBuildManifest` before importing user code. Bundling `dist/server.js`\n// directly would skip that priming and 500 on view resource reads when the\n// function falls back to `readFileSync('dist/assets/.vite/manifest.json')`\n// (Vercel functions don't ship `dist/`).\nexport async function emitVercelBuildOutput(root: string): Promise<void> {\n const outputDir = path.join(root, \".vercel\", \"output\");\n const funcDir = path.join(\n outputDir,\n \"functions\",\n `${VERCEL_FUNCTION_NAME}.func`,\n );\n const staticAssetsDir = path.join(outputDir, \"static\", \"assets\");\n\n rmSync(outputDir, { recursive: true, force: true });\n mkdirSync(funcDir, { recursive: true });\n\n const { build } = await import(\"esbuild\");\n await build({\n entryPoints: [path.join(root, \"dist\", \"__entry.js\")],\n bundle: true,\n platform: \"node\",\n target: \"node22\",\n format: \"esm\",\n outfile: path.join(funcDir, \"index.js\"),\n // Lets esbuild DCE dev-only branches that pull in vite/devtools.\n define: { \"process.env.NODE_ENV\": '\"production\"' },\n // Dev-only deps reachable from re-exports; safe to leave unresolved since\n // the code paths that touch them are eliminated by the NODE_ENV define.\n external: [\"vite\", \"@skybridge/devtools\"],\n banner: {\n // ESM bundles miss CJS interop globals that some deps reach for.\n js: \"import{createRequire}from'node:module';const require=createRequire(import.meta.url);\",\n },\n });\n\n writeFileSync(\n path.join(funcDir, \".vc-config.json\"),\n `${JSON.stringify(VERCEL_VC_CONFIG, null, 2)}\\n`,\n );\n writeFileSync(\n path.join(funcDir, \"package.json\"),\n `${JSON.stringify({ type: \"module\" }, null, 2)}\\n`,\n );\n\n cpSync(path.join(root, \"dist\", \"assets\"), staticAssetsDir, {\n recursive: true,\n });\n\n writeFileSync(\n path.join(outputDir, \"config.json\"),\n `${JSON.stringify(VERCEL_CONFIG, null, 2)}\\n`,\n );\n}\n"]}
@@ -0,0 +1,64 @@
1
+ // @vitest-environment node
2
+ // esbuild's invariant check on TextEncoder/Uint8Array trips jsdom's polyfill.
3
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync, } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import path from "node:path";
6
+ import { describe, expect, it } from "vitest";
7
+ import { ENTRY_WRAPPER_CONTENT, emitEntryWrapper, emitManifestModule, emitVercelBuildOutput, VERCEL_CONFIG, VERCEL_VC_CONFIG, } from "./build-helpers.js";
8
+ function mkTmp(prefix = "skybridge-build-helpers-") {
9
+ return mkdtempSync(path.join(tmpdir(), prefix));
10
+ }
11
+ describe("emitEntryWrapper", () => {
12
+ it("writes dist/__entry.js that primes the manifest before importing user code", () => {
13
+ const dir = mkTmp();
14
+ emitEntryWrapper(dir);
15
+ const out = readFileSync(path.join(dir, "__entry.js"), "utf-8");
16
+ expect(out).toBe(ENTRY_WRAPPER_CONTENT);
17
+ expect(out).toContain('import { __setBuildManifest } from "skybridge/server"');
18
+ expect(out).toContain('import manifest from "./vite-manifest.js"');
19
+ expect(out).toContain("__setBuildManifest(manifest)");
20
+ // Dynamic import is load-bearing: `server.js` must evaluate after the
21
+ // setter runs, so a static re-export wouldn't work.
22
+ expect(out).toContain('await import("./server.js")');
23
+ expect(out).toContain("export default userMod.default");
24
+ });
25
+ });
26
+ describe("emitManifestModule", () => {
27
+ it("inlines the JSON manifest as an ESM default export", () => {
28
+ const dir = mkTmp();
29
+ const inPath = path.join(dir, "manifest.json");
30
+ const outPath = path.join(dir, "vite-manifest.js");
31
+ const manifest = { "src/views/foo.tsx": { file: "assets/foo-abc.js" } };
32
+ writeFileSync(inPath, JSON.stringify(manifest));
33
+ emitManifestModule(inPath, outPath);
34
+ const out = readFileSync(outPath, "utf-8");
35
+ expect(out.startsWith("export default ")).toBe(true);
36
+ const literal = out
37
+ .slice("export default ".length)
38
+ .trim()
39
+ .replace(/;$/, "");
40
+ expect(JSON.parse(literal)).toEqual(manifest);
41
+ });
42
+ });
43
+ describe("emitVercelBuildOutput", () => {
44
+ it("emits a Build Output API tree with bundled function and static assets", async () => {
45
+ const root = mkTmp();
46
+ mkdirSync(path.join(root, "dist", "assets"), { recursive: true });
47
+ writeFileSync(path.join(root, "dist", "server.js"), "export default function handler(_req, res) { res.end('ok'); }\n");
48
+ // Minimal `dist/__entry.js` (the real wrapper imports `skybridge/server`,
49
+ // which isn't resolvable in this test's tmp dir — the function-bundling
50
+ // contract we care about here is just "bundle whatever `__entry.js`
51
+ // imports into a single function file").
52
+ writeFileSync(path.join(root, "dist", "__entry.js"), "const userMod = await import('./server.js');\nexport default userMod.default;\n");
53
+ writeFileSync(path.join(root, "dist", "assets", "view-abc.js"), "/* bundled view */\n");
54
+ await emitVercelBuildOutput(root);
55
+ const outputDir = path.join(root, ".vercel", "output");
56
+ const funcDir = path.join(outputDir, "functions", "mcp.func");
57
+ expect(existsSync(path.join(funcDir, "index.js"))).toBe(true);
58
+ expect(JSON.parse(readFileSync(path.join(funcDir, ".vc-config.json"), "utf-8"))).toEqual(VERCEL_VC_CONFIG);
59
+ expect(JSON.parse(readFileSync(path.join(funcDir, "package.json"), "utf-8"))).toEqual({ type: "module" });
60
+ expect(JSON.parse(readFileSync(path.join(outputDir, "config.json"), "utf-8"))).toEqual(VERCEL_CONFIG);
61
+ expect(readFileSync(path.join(outputDir, "static", "assets", "view-abc.js"), "utf-8")).toContain("bundled view");
62
+ });
63
+ });
64
+ //# sourceMappingURL=build-helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-helpers.test.js","sourceRoot":"","sources":["../../src/cli/build-helpers.test.ts"],"names":[],"mappings":"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","sourcesContent":["// @vitest-environment node\n// esbuild's invariant check on TextEncoder/Uint8Array trips jsdom's polyfill.\nimport {\n existsSync,\n mkdirSync,\n mkdtempSync,\n readFileSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { describe, expect, it } from \"vitest\";\nimport {\n ENTRY_WRAPPER_CONTENT,\n emitEntryWrapper,\n emitManifestModule,\n emitVercelBuildOutput,\n VERCEL_CONFIG,\n VERCEL_VC_CONFIG,\n} from \"./build-helpers.js\";\n\nfunction mkTmp(prefix = \"skybridge-build-helpers-\") {\n return mkdtempSync(path.join(tmpdir(), prefix));\n}\n\ndescribe(\"emitEntryWrapper\", () => {\n it(\"writes dist/__entry.js that primes the manifest before importing user code\", () => {\n const dir = mkTmp();\n emitEntryWrapper(dir);\n const out = readFileSync(path.join(dir, \"__entry.js\"), \"utf-8\");\n expect(out).toBe(ENTRY_WRAPPER_CONTENT);\n expect(out).toContain(\n 'import { __setBuildManifest } from \"skybridge/server\"',\n );\n expect(out).toContain('import manifest from \"./vite-manifest.js\"');\n expect(out).toContain(\"__setBuildManifest(manifest)\");\n // Dynamic import is load-bearing: `server.js` must evaluate after the\n // setter runs, so a static re-export wouldn't work.\n expect(out).toContain('await import(\"./server.js\")');\n expect(out).toContain(\"export default userMod.default\");\n });\n});\n\ndescribe(\"emitManifestModule\", () => {\n it(\"inlines the JSON manifest as an ESM default export\", () => {\n const dir = mkTmp();\n const inPath = path.join(dir, \"manifest.json\");\n const outPath = path.join(dir, \"vite-manifest.js\");\n const manifest = { \"src/views/foo.tsx\": { file: \"assets/foo-abc.js\" } };\n writeFileSync(inPath, JSON.stringify(manifest));\n emitManifestModule(inPath, outPath);\n const out = readFileSync(outPath, \"utf-8\");\n expect(out.startsWith(\"export default \")).toBe(true);\n const literal = out\n .slice(\"export default \".length)\n .trim()\n .replace(/;$/, \"\");\n expect(JSON.parse(literal)).toEqual(manifest);\n });\n});\n\ndescribe(\"emitVercelBuildOutput\", () => {\n it(\"emits a Build Output API tree with bundled function and static assets\", async () => {\n const root = mkTmp();\n mkdirSync(path.join(root, \"dist\", \"assets\"), { recursive: true });\n writeFileSync(\n path.join(root, \"dist\", \"server.js\"),\n \"export default function handler(_req, res) { res.end('ok'); }\\n\",\n );\n // Minimal `dist/__entry.js` (the real wrapper imports `skybridge/server`,\n // which isn't resolvable in this test's tmp dir — the function-bundling\n // contract we care about here is just \"bundle whatever `__entry.js`\n // imports into a single function file\").\n writeFileSync(\n path.join(root, \"dist\", \"__entry.js\"),\n \"const userMod = await import('./server.js');\\nexport default userMod.default;\\n\",\n );\n writeFileSync(\n path.join(root, \"dist\", \"assets\", \"view-abc.js\"),\n \"/* bundled view */\\n\",\n );\n\n await emitVercelBuildOutput(root);\n\n const outputDir = path.join(root, \".vercel\", \"output\");\n const funcDir = path.join(outputDir, \"functions\", \"mcp.func\");\n\n expect(existsSync(path.join(funcDir, \"index.js\"))).toBe(true);\n expect(\n JSON.parse(readFileSync(path.join(funcDir, \".vc-config.json\"), \"utf-8\")),\n ).toEqual(VERCEL_VC_CONFIG);\n expect(\n JSON.parse(readFileSync(path.join(funcDir, \"package.json\"), \"utf-8\")),\n ).toEqual({ type: \"module\" });\n expect(\n JSON.parse(readFileSync(path.join(outputDir, \"config.json\"), \"utf-8\")),\n ).toEqual(VERCEL_CONFIG);\n expect(\n readFileSync(\n path.join(outputDir, \"static\", \"assets\", \"view-abc.js\"),\n \"utf-8\",\n ),\n ).toContain(\"bundled view\");\n });\n});\n"]}
@@ -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 first available port at or after `startPort`, incrementing
12
+ * by one until a free port is found or `MAX_PORT_INCREMENT` is reached.
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,50 @@
1
+ import net from "node:net";
2
+ const DEFAULT_PORT = 3000;
3
+ const MAX_PORT_INCREMENT = 100;
4
+ export async function resolvePort(flagPort) {
5
+ if (flagPort && flagPort > 1) {
6
+ return { port: flagPort, fallback: false };
7
+ }
8
+ const rawEnv = process.env.PORT;
9
+ if (rawEnv) {
10
+ const parsed = Number(rawEnv);
11
+ if (Number.isInteger(parsed) && parsed > 0) {
12
+ return { port: parsed, fallback: false };
13
+ }
14
+ return {
15
+ port: await detectAvailablePort(DEFAULT_PORT),
16
+ fallback: false,
17
+ envWarning: `Invalid PORT="${rawEnv}", ignoring and using default`,
18
+ };
19
+ }
20
+ const port = await detectAvailablePort(DEFAULT_PORT);
21
+ return { port, fallback: port !== DEFAULT_PORT };
22
+ }
23
+ /**
24
+ * Returns the first available port at or after `startPort`, incrementing
25
+ * by one until a free port is found or `MAX_PORT_INCREMENT` is reached.
26
+ *
27
+ * @param host - Bind address for the check. Pass `"localhost"` for
28
+ * services that bind to 127.0.0.1 (e.g. Vite HMR). Omit for
29
+ * services that bind to all interfaces (e.g. the HTTP server).
30
+ */
31
+ export async function detectAvailablePort(startPort, host) {
32
+ for (let port = startPort; port < startPort + MAX_PORT_INCREMENT; port++) {
33
+ if (await isPortAvailable(port, host)) {
34
+ return port;
35
+ }
36
+ console.log(`Port ${port} is in use, trying another one...`);
37
+ }
38
+ throw new Error(`No available port found between ${startPort} and ${startPort + MAX_PORT_INCREMENT - 1}`);
39
+ }
40
+ function isPortAvailable(port, host) {
41
+ return new Promise((resolve) => {
42
+ const server = net.createServer();
43
+ server.once("error", () => resolve(false));
44
+ server.once("listening", () => {
45
+ server.close(() => resolve(true));
46
+ });
47
+ server.listen(port, host);
48
+ });
49
+ }
50
+ //# 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;AAC1B,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAE/B,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,KAAK,IAAI,IAAI,GAAG,SAAS,EAAE,IAAI,GAAG,SAAS,GAAG,kBAAkB,EAAE,IAAI,EAAE,EAAE,CAAC;QACzE,IAAI,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,mCAAmC,CAAC,CAAC;IAC/D,CAAC;IACD,MAAM,IAAI,KAAK,CACb,mCAAmC,SAAS,QAAQ,SAAS,GAAG,kBAAkB,GAAG,CAAC,EAAE,CACzF,CAAC;AACJ,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;\nconst MAX_PORT_INCREMENT = 100;\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 first available port at or after `startPort`, incrementing\n * by one until a free port is found or `MAX_PORT_INCREMENT` is reached.\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 for (let port = startPort; port < startPort + MAX_PORT_INCREMENT; port++) {\n if (await isPortAvailable(port, host)) {\n return port;\n }\n console.log(`Port ${port} is in use, trying another one...`);\n }\n throw new Error(\n `No available port found between ${startPort} and ${startPort + MAX_PORT_INCREMENT - 1}`,\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 @@
1
+ export declare function resolveViewsDir(root: string): Promise<string | undefined>;
@@ -0,0 +1,17 @@
1
+ export async function resolveViewsDir(root) {
2
+ const { loadConfigFromFile } = await import("vite");
3
+ const loaded = await loadConfigFromFile({ command: "build", mode: "production" }, undefined, root);
4
+ const isPluginCandidate = (value) => typeof value === "object" && value !== null;
5
+ const plugins = [];
6
+ const walk = (value) => {
7
+ if (Array.isArray(value)) {
8
+ value.forEach(walk);
9
+ }
10
+ else if (isPluginCandidate(value)) {
11
+ plugins.push(value);
12
+ }
13
+ };
14
+ walk(loaded?.config.plugins ?? []);
15
+ return plugins.find((p) => p.name === "skybridge")?.api?.viewsDir;
16
+ }
17
+ //# sourceMappingURL=resolve-views-dir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-views-dir.js","sourceRoot":"","sources":["../../src/cli/resolve-views-dir.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY;IAEZ,MAAM,EAAE,kBAAkB,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CACrC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,EACxC,SAAS,EACT,IAAI,CACL,CAAC;IAEF,MAAM,iBAAiB,GAAG,CACxB,KAAc,EAC2C,EAAE,CAC3D,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;IAE9C,MAAM,OAAO,GAA0D,EAAE,CAAC;IAC1E,MAAM,IAAI,GAAG,CAAC,KAAc,EAAE,EAAE;QAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;aAAM,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,CAAC;IACF,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC;AACpE,CAAC","sourcesContent":["export async function resolveViewsDir(\n root: string,\n): Promise<string | undefined> {\n const { loadConfigFromFile } = await import(\"vite\");\n const loaded = await loadConfigFromFile(\n { command: \"build\", mode: \"production\" },\n undefined,\n root,\n );\n\n const isPluginCandidate = (\n value: unknown,\n ): value is { name?: string; api?: { viewsDir?: string } } =>\n typeof value === \"object\" && value !== null;\n\n const plugins: Array<{ name?: string; api?: { viewsDir?: string } }> = [];\n const walk = (value: unknown) => {\n if (Array.isArray(value)) {\n value.forEach(walk);\n } else if (isPluginCandidate(value)) {\n plugins.push(value);\n }\n };\n walk(loaded?.config.plugins ?? []);\n return plugins.find((p) => p.name === \"skybridge\")?.api?.viewsDir;\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;
@@ -0,0 +1,123 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import ci from "ci-info";
5
+ import { PostHog } from "posthog-node";
6
+ const POSTHOG_API_KEY = "phc_rQdkCYr0DO4NcZBQXZnUwsHAbau9zuNwKIpil9FQP6v";
7
+ const POSTHOG_HOST = "https://us.i.posthog.com";
8
+ const ENV_TELEMETRY_DISABLED = "SKYBRIDGE_TELEMETRY_DISABLED";
9
+ const ENV_TELEMETRY_DEBUG = "SKYBRIDGE_TELEMETRY_DEBUG";
10
+ const ENV_DO_NOT_TRACK = "DO_NOT_TRACK";
11
+ const GLOBAL_CONFIG_DIR = join(homedir(), ".skybridge");
12
+ const GLOBAL_CONFIG_FILE = join(GLOBAL_CONFIG_DIR, "config.json");
13
+ let posthogClient = null;
14
+ function getPostHogClient() {
15
+ if (!posthogClient) {
16
+ posthogClient = new PostHog(POSTHOG_API_KEY, {
17
+ host: POSTHOG_HOST,
18
+ flushAt: 1,
19
+ flushInterval: 0,
20
+ });
21
+ }
22
+ return posthogClient;
23
+ }
24
+ function readJsonFile(filePath) {
25
+ try {
26
+ if (existsSync(filePath)) {
27
+ const content = readFileSync(filePath, "utf-8");
28
+ return JSON.parse(content);
29
+ }
30
+ }
31
+ catch {
32
+ // Ignore errors reading config
33
+ }
34
+ return null;
35
+ }
36
+ function writeJsonFile(filePath, data) {
37
+ try {
38
+ const dir = join(filePath, "..");
39
+ if (!existsSync(dir)) {
40
+ mkdirSync(dir, { recursive: true });
41
+ }
42
+ writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
43
+ }
44
+ catch {
45
+ // Ignore errors writing config
46
+ }
47
+ }
48
+ function getGlobalConfig() {
49
+ const existing = readJsonFile(GLOBAL_CONFIG_FILE);
50
+ if (existing?.machineId && existing?.telemetry !== undefined) {
51
+ return existing;
52
+ }
53
+ const config = {
54
+ machineId: existing?.machineId || crypto.randomUUID(),
55
+ telemetry: {
56
+ enabled: existing?.telemetry?.enabled ?? true,
57
+ },
58
+ };
59
+ writeJsonFile(GLOBAL_CONFIG_FILE, config);
60
+ return config;
61
+ }
62
+ export function isEnabled() {
63
+ if (process.env[ENV_TELEMETRY_DISABLED] === "1" ||
64
+ process.env[ENV_TELEMETRY_DISABLED]?.toLowerCase() === "true") {
65
+ return false;
66
+ }
67
+ if (process.env[ENV_DO_NOT_TRACK] === "1" ||
68
+ process.env[ENV_DO_NOT_TRACK]?.toLowerCase() === "true") {
69
+ return false;
70
+ }
71
+ if (ci.isCI) {
72
+ return true;
73
+ }
74
+ const config = getGlobalConfig();
75
+ return config.telemetry.enabled;
76
+ }
77
+ export function isDebugMode() {
78
+ return (process.env[ENV_TELEMETRY_DEBUG] === "1" ||
79
+ process.env[ENV_TELEMETRY_DEBUG]?.toLowerCase() === "true");
80
+ }
81
+ export function setEnabled(enabled) {
82
+ const config = getGlobalConfig();
83
+ config.telemetry.enabled = enabled;
84
+ writeJsonFile(GLOBAL_CONFIG_FILE, config);
85
+ }
86
+ export function getMachineId() {
87
+ if (ci.isCI) {
88
+ return ci.name ?? "unknown-ci";
89
+ }
90
+ return getGlobalConfig().machineId;
91
+ }
92
+ const hook = async ({ id: command, config: { version }, error, }) => {
93
+ if (!isEnabled()) {
94
+ return;
95
+ }
96
+ const event = {
97
+ version,
98
+ machineId: getMachineId(),
99
+ sessionId: crypto.randomUUID(),
100
+ isCI: ci.isCI,
101
+ nodeVersion: process.version,
102
+ platform: process.platform,
103
+ outcome: error ? "failure" : "success",
104
+ error: error?.message,
105
+ };
106
+ if (isDebugMode()) {
107
+ console.error("[Telemetry Debug] Would send event:", JSON.stringify(event, null, 2));
108
+ return;
109
+ }
110
+ try {
111
+ const client = getPostHogClient();
112
+ client.capture({
113
+ distinctId: event.machineId,
114
+ event: command,
115
+ properties: event,
116
+ });
117
+ }
118
+ catch {
119
+ // Silently ignore telemetry errors - never block CLI operation
120
+ }
121
+ };
122
+ export default hook;
123
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/cli/telemetry.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { Hook } from \"@oclif/core\";\nimport ci from \"ci-info\";\nimport { PostHog } from \"posthog-node\";\n\nconst POSTHOG_API_KEY = \"phc_rQdkCYr0DO4NcZBQXZnUwsHAbau9zuNwKIpil9FQP6v\";\nconst POSTHOG_HOST = \"https://us.i.posthog.com\";\n\nconst ENV_TELEMETRY_DISABLED = \"SKYBRIDGE_TELEMETRY_DISABLED\";\nconst ENV_TELEMETRY_DEBUG = \"SKYBRIDGE_TELEMETRY_DEBUG\";\nconst ENV_DO_NOT_TRACK = \"DO_NOT_TRACK\";\n\nconst GLOBAL_CONFIG_DIR = join(homedir(), \".skybridge\");\nconst GLOBAL_CONFIG_FILE = join(GLOBAL_CONFIG_DIR, \"config.json\");\n\ninterface GlobalConfig {\n machineId: string;\n telemetry: {\n enabled: boolean;\n };\n}\n\ninterface TelemetryEvent {\n version: string;\n machineId: string;\n sessionId: string;\n isCI: boolean;\n nodeVersion: string;\n platform: NodeJS.Platform;\n outcome: \"success\" | \"failure\";\n error?: string;\n}\n\nlet posthogClient: PostHog | null = null;\n\nfunction getPostHogClient(): PostHog {\n if (!posthogClient) {\n posthogClient = new PostHog(POSTHOG_API_KEY, {\n host: POSTHOG_HOST,\n flushAt: 1,\n flushInterval: 0,\n });\n }\n\n return posthogClient;\n}\n\nfunction readJsonFile<T>(filePath: string): T | null {\n try {\n if (existsSync(filePath)) {\n const content = readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as T;\n }\n } catch {\n // Ignore errors reading config\n }\n return null;\n}\n\nfunction writeJsonFile(filePath: string, data: unknown): void {\n try {\n const dir = join(filePath, \"..\");\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(filePath, JSON.stringify(data, null, 2), \"utf-8\");\n } catch {\n // Ignore errors writing config\n }\n}\n\nfunction getGlobalConfig(): GlobalConfig {\n const existing = readJsonFile<GlobalConfig>(GLOBAL_CONFIG_FILE);\n if (existing?.machineId && existing?.telemetry !== undefined) {\n return existing;\n }\n\n const config: GlobalConfig = {\n machineId: existing?.machineId || crypto.randomUUID(),\n telemetry: {\n enabled: existing?.telemetry?.enabled ?? true,\n },\n };\n\n writeJsonFile(GLOBAL_CONFIG_FILE, config);\n return config;\n}\n\nexport function isEnabled(): boolean {\n if (\n process.env[ENV_TELEMETRY_DISABLED] === \"1\" ||\n process.env[ENV_TELEMETRY_DISABLED]?.toLowerCase() === \"true\"\n ) {\n return false;\n }\n\n if (\n process.env[ENV_DO_NOT_TRACK] === \"1\" ||\n process.env[ENV_DO_NOT_TRACK]?.toLowerCase() === \"true\"\n ) {\n return false;\n }\n\n if (ci.isCI) {\n return true;\n }\n\n const config = getGlobalConfig();\n return config.telemetry.enabled;\n}\n\nexport function isDebugMode(): boolean {\n return (\n process.env[ENV_TELEMETRY_DEBUG] === \"1\" ||\n process.env[ENV_TELEMETRY_DEBUG]?.toLowerCase() === \"true\"\n );\n}\n\nexport function setEnabled(enabled: boolean): void {\n const config = getGlobalConfig();\n config.telemetry.enabled = enabled;\n writeJsonFile(GLOBAL_CONFIG_FILE, config);\n}\n\nexport function getMachineId(): string {\n if (ci.isCI) {\n return ci.name ?? \"unknown-ci\";\n }\n\n return getGlobalConfig().machineId;\n}\n\nconst hook: Hook<\"finally\"> = async ({\n id: command,\n config: { version },\n error,\n}) => {\n if (!isEnabled()) {\n return;\n }\n\n const event: TelemetryEvent = {\n version,\n machineId: getMachineId(),\n sessionId: crypto.randomUUID(),\n isCI: ci.isCI,\n nodeVersion: process.version,\n platform: process.platform,\n outcome: error ? \"failure\" : \"success\",\n error: error?.message,\n };\n\n if (isDebugMode()) {\n console.error(\n \"[Telemetry Debug] Would send event:\",\n JSON.stringify(event, null, 2),\n );\n return;\n }\n\n try {\n const client = getPostHogClient();\n client.capture({\n distinctId: event.machineId,\n event: command,\n properties: event,\n });\n } catch {\n // Silently ignore telemetry errors - never block CLI operation\n }\n};\n\nexport default hook;\n"]}
@@ -0,0 +1,9 @@
1
+ import { type SpawnFn, TunnelManager } from "./tunnel.js";
2
+ export type TunnelControlServer = {
3
+ port: number;
4
+ manager: TunnelManager;
5
+ close: () => Promise<void>;
6
+ };
7
+ export declare function startTunnelControlServer(getPort: () => number, options?: {
8
+ spawn?: SpawnFn;
9
+ }): Promise<TunnelControlServer>;
@@ -0,0 +1,31 @@
1
+ import http from "node:http";
2
+ import { TunnelManager } from "./tunnel.js";
3
+ import { createTunnelHandler } from "./tunnel-handler.js";
4
+ export async function startTunnelControlServer(getPort, options) {
5
+ const manager = new TunnelManager({ getPort, spawn: options?.spawn });
6
+ const server = http.createServer(createTunnelHandler(manager));
7
+ await new Promise((resolve, reject) => {
8
+ server.once("error", reject);
9
+ server.listen(0, "127.0.0.1", () => {
10
+ server.off("error", reject);
11
+ resolve();
12
+ });
13
+ });
14
+ const address = server.address();
15
+ if (typeof address === "string" || address === null) {
16
+ server.close();
17
+ throw new Error("tunnel control server has no address");
18
+ }
19
+ return {
20
+ port: address.port,
21
+ manager,
22
+ close: () => new Promise((resolve, reject) => {
23
+ manager.stop();
24
+ // Force any in-flight SSE connections to drop so server.close()
25
+ // doesn't hang indefinitely on subscribers that never end on their own.
26
+ server.closeAllConnections();
27
+ server.close((err) => (err ? reject(err) : resolve()));
28
+ }),
29
+ };
30
+ }
31
+ //# sourceMappingURL=tunnel-control-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-control-server.js","sourceRoot":"","sources":["../../src/cli/tunnel-control-server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAgB,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAQ1D,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,OAAqB,EACrB,OAA6B;IAE7B,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5B,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IACjC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACpD,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,OAAO;QACP,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACpC,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,gEAAgE;YAChE,wEAAwE;YACxE,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC;KACL,CAAC;AACJ,CAAC","sourcesContent":["import http from \"node:http\";\nimport { type SpawnFn, TunnelManager } from \"./tunnel.js\";\nimport { createTunnelHandler } from \"./tunnel-handler.js\";\n\nexport type TunnelControlServer = {\n port: number;\n manager: TunnelManager;\n close: () => Promise<void>;\n};\n\nexport async function startTunnelControlServer(\n getPort: () => number,\n options?: { spawn?: SpawnFn },\n): Promise<TunnelControlServer> {\n const manager = new TunnelManager({ getPort, spawn: options?.spawn });\n const server = http.createServer(createTunnelHandler(manager));\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => {\n server.off(\"error\", reject);\n resolve();\n });\n });\n const address = server.address();\n if (typeof address === \"string\" || address === null) {\n server.close();\n throw new Error(\"tunnel control server has no address\");\n }\n return {\n port: address.port,\n manager,\n close: () =>\n new Promise<void>((resolve, reject) => {\n manager.stop();\n // Force any in-flight SSE connections to drop so server.close()\n // doesn't hang indefinitely on subscribers that never end on their own.\n server.closeAllConnections();\n server.close((err) => (err ? reject(err) : resolve()));\n }),\n };\n}\n"]}
@@ -0,0 +1,39 @@
1
+ import { afterEach, describe, expect, it } from "vitest";
2
+ import { startTunnelControlServer } from "./tunnel-control-server.js";
3
+ let openControl;
4
+ afterEach(async () => {
5
+ await openControl?.close();
6
+ openControl = undefined;
7
+ });
8
+ describe("startTunnelControlServer", () => {
9
+ it("listens on a random loopback port and serves /__skybridge/tunnel/events", async () => {
10
+ const control = await startTunnelControlServer(() => 3000);
11
+ openControl = control;
12
+ expect(control.port).toBeGreaterThan(0);
13
+ const res = await fetch(`http://127.0.0.1:${control.port}/__skybridge/tunnel/events`);
14
+ expect(res.headers.get("content-type")).toMatch(/text\/event-stream/);
15
+ const reader = res.body.getReader();
16
+ const { value } = await reader.read();
17
+ const chunk = new TextDecoder().decode(value);
18
+ expect(chunk).toContain("event: state");
19
+ expect(chunk).toContain('"status":"idle"');
20
+ await reader.cancel();
21
+ });
22
+ it("two concurrent control servers get different ports", async () => {
23
+ const a = await startTunnelControlServer(() => 3000);
24
+ const b = await startTunnelControlServer(() => 4000);
25
+ try {
26
+ expect(a.port).not.toBe(b.port);
27
+ }
28
+ finally {
29
+ await a.close();
30
+ await b.close();
31
+ }
32
+ });
33
+ it("close() shuts the listener", async () => {
34
+ const control = await startTunnelControlServer(() => 3000);
35
+ await control.close();
36
+ await expect(fetch(`http://127.0.0.1:${control.port}/__skybridge/tunnel/events`)).rejects.toThrow();
37
+ });
38
+ });
39
+ //# sourceMappingURL=tunnel-control-server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-control-server.test.js","sourceRoot":"","sources":["../../src/cli/tunnel-control-server.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,IAAI,WAAuD,CAAC;AAC5D,SAAS,CAAC,KAAK,IAAI,EAAE;IACnB,MAAM,WAAW,EAAE,KAAK,EAAE,CAAC;IAC3B,WAAW,GAAG,SAAS,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3D,WAAW,GAAG,OAAO,CAAC;QAEtB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAExC,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,oBAAoB,OAAO,CAAC,IAAI,4BAA4B,CAC7D,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAEtE,MAAM,MAAM,GAAI,GAAG,CAAC,IAAmC,CAAC,SAAS,EAAE,CAAC;QACpE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC3C,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,CAAC,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,CAAC,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,MAAM,MAAM,CACV,KAAK,CAAC,oBAAoB,OAAO,CAAC,IAAI,4BAA4B,CAAC,CACpE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { afterEach, describe, expect, it } from \"vitest\";\nimport { startTunnelControlServer } from \"./tunnel-control-server.js\";\n\nlet openControl: { close: () => Promise<void> } | undefined;\nafterEach(async () => {\n await openControl?.close();\n openControl = undefined;\n});\n\ndescribe(\"startTunnelControlServer\", () => {\n it(\"listens on a random loopback port and serves /__skybridge/tunnel/events\", async () => {\n const control = await startTunnelControlServer(() => 3000);\n openControl = control;\n\n expect(control.port).toBeGreaterThan(0);\n\n const res = await fetch(\n `http://127.0.0.1:${control.port}/__skybridge/tunnel/events`,\n );\n expect(res.headers.get(\"content-type\")).toMatch(/text\\/event-stream/);\n\n const reader = (res.body as ReadableStream<Uint8Array>).getReader();\n const { value } = await reader.read();\n const chunk = new TextDecoder().decode(value);\n expect(chunk).toContain(\"event: state\");\n expect(chunk).toContain('\"status\":\"idle\"');\n await reader.cancel();\n });\n\n it(\"two concurrent control servers get different ports\", async () => {\n const a = await startTunnelControlServer(() => 3000);\n const b = await startTunnelControlServer(() => 4000);\n try {\n expect(a.port).not.toBe(b.port);\n } finally {\n await a.close();\n await b.close();\n }\n });\n\n it(\"close() shuts the listener\", async () => {\n const control = await startTunnelControlServer(() => 3000);\n await control.close();\n await expect(\n fetch(`http://127.0.0.1:${control.port}/__skybridge/tunnel/events`),\n ).rejects.toThrow();\n });\n});\n"]}
@@ -0,0 +1,3 @@
1
+ import type { IncomingMessage, ServerResponse } from "node:http";
2
+ import type { TunnelManager } from "./tunnel.js";
3
+ export declare function createTunnelHandler(manager: TunnelManager): (req: IncomingMessage, res: ServerResponse) => void;
@@ -0,0 +1,48 @@
1
+ export function createTunnelHandler(manager) {
2
+ return (req, res) => {
3
+ if (req.url === "/__skybridge/tunnel" && req.method === "POST") {
4
+ manager.start();
5
+ sendJson(res, 200, manager.getState());
6
+ return;
7
+ }
8
+ if (req.url === "/__skybridge/tunnel" && req.method === "DELETE") {
9
+ manager.stop();
10
+ sendJson(res, 200, manager.getState());
11
+ return;
12
+ }
13
+ if (req.url === "/__skybridge/tunnel/events" && req.method === "GET") {
14
+ writeSseHead(res);
15
+ writeSse(res, "state", manager.getState());
16
+ const onState = (s) => {
17
+ writeSse(res, "state", s);
18
+ };
19
+ const onActivity = (a) => {
20
+ writeSse(res, "activity", a);
21
+ };
22
+ manager.on("state", onState);
23
+ manager.on("activity", onActivity);
24
+ req.on("close", () => {
25
+ manager.off("state", onState);
26
+ manager.off("activity", onActivity);
27
+ });
28
+ return;
29
+ }
30
+ res.writeHead(404).end();
31
+ };
32
+ }
33
+ function sendJson(res, status, data) {
34
+ res.writeHead(status, { "Content-Type": "application/json" });
35
+ res.end(JSON.stringify(data));
36
+ }
37
+ function writeSseHead(res) {
38
+ res.writeHead(200, {
39
+ "Content-Type": "text/event-stream",
40
+ "Cache-Control": "no-cache, no-transform",
41
+ Connection: "keep-alive",
42
+ });
43
+ res.flushHeaders?.();
44
+ }
45
+ function writeSse(res, event, data) {
46
+ res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
47
+ }
48
+ //# sourceMappingURL=tunnel-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel-handler.js","sourceRoot":"","sources":["../../src/cli/tunnel-handler.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,mBAAmB,CAAC,OAAsB;IACxD,OAAO,CAAC,GAAoB,EAAE,GAAmB,EAAQ,EAAE;QACzD,IAAI,GAAG,CAAC,GAAG,KAAK,qBAAqB,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC/D,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YACvC,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,GAAG,KAAK,qBAAqB,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACjE,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YACvC,OAAO;QACT,CAAC;QACD,IAAI,GAAG,CAAC,GAAG,KAAK,4BAA4B,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;YACrE,YAAY,CAAC,GAAG,CAAC,CAAC;YAClB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC3C,MAAM,OAAO,GAAG,CAAC,CAAc,EAAE,EAAE;gBACjC,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;YAC5B,CAAC,CAAC;YACF,MAAM,UAAU,GAAG,CAAC,CAAiB,EAAE,EAAE;gBACvC,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;YAC/B,CAAC,CAAC;YACF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7B,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACnC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACnB,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAC3B,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,GAAmB,EAAE,MAAc,EAAE,IAAa;IAClE,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC9D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,YAAY,CAAC,GAAmB;IACvC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;QACjB,cAAc,EAAE,mBAAmB;QACnC,eAAe,EAAE,wBAAwB;QACzC,UAAU,EAAE,YAAY;KACzB,CAAC,CAAC;IACH,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC;AACvB,CAAC;AAED,SAAS,QAAQ,CAAC,GAAmB,EAAE,KAAa,EAAE,IAAa;IACjE,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,WAAW,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAClE,CAAC","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport type { TunnelActivity, TunnelManager, TunnelState } from \"./tunnel.js\";\n\nexport function createTunnelHandler(manager: TunnelManager) {\n return (req: IncomingMessage, res: ServerResponse): void => {\n if (req.url === \"/__skybridge/tunnel\" && req.method === \"POST\") {\n manager.start();\n sendJson(res, 200, manager.getState());\n return;\n }\n if (req.url === \"/__skybridge/tunnel\" && req.method === \"DELETE\") {\n manager.stop();\n sendJson(res, 200, manager.getState());\n return;\n }\n if (req.url === \"/__skybridge/tunnel/events\" && req.method === \"GET\") {\n writeSseHead(res);\n writeSse(res, \"state\", manager.getState());\n const onState = (s: TunnelState) => {\n writeSse(res, \"state\", s);\n };\n const onActivity = (a: TunnelActivity) => {\n writeSse(res, \"activity\", a);\n };\n manager.on(\"state\", onState);\n manager.on(\"activity\", onActivity);\n req.on(\"close\", () => {\n manager.off(\"state\", onState);\n manager.off(\"activity\", onActivity);\n });\n return;\n }\n res.writeHead(404).end();\n };\n}\n\nfunction sendJson(res: ServerResponse, status: number, data: unknown): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(data));\n}\n\nfunction writeSseHead(res: ServerResponse): void {\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\",\n });\n res.flushHeaders?.();\n}\n\nfunction writeSse(res: ServerResponse, event: string, data: unknown): void {\n res.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n}\n"]}