skybridge 0.0.0-dev.f03017e → 0.0.0-dev.f0394fc

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 (513) hide show
  1. package/README.md +126 -124
  2. package/dist/cli/build-helpers.d.ts +11 -0
  3. package/dist/cli/build-helpers.js +113 -0
  4. package/dist/cli/build-helpers.js.map +1 -0
  5. package/dist/cli/build-helpers.test.js +143 -0
  6. package/dist/cli/build-helpers.test.js.map +1 -0
  7. package/dist/cli/build-steps.d.ts +2 -0
  8. package/dist/cli/build-steps.js +84 -0
  9. package/dist/cli/build-steps.js.map +1 -0
  10. package/dist/cli/build-steps.test.js +72 -0
  11. package/dist/cli/build-steps.test.js.map +1 -0
  12. package/dist/cli/detect-port.d.ts +2 -2
  13. package/dist/cli/detect-port.js +8 -20
  14. package/dist/cli/detect-port.js.map +1 -1
  15. package/dist/cli/header.d.ts +1 -1
  16. package/dist/cli/header.js.map +1 -1
  17. package/dist/cli/resolve-skybridge-config.d.ts +6 -0
  18. package/dist/cli/resolve-skybridge-config.js +28 -0
  19. package/dist/cli/resolve-skybridge-config.js.map +1 -0
  20. package/dist/cli/run-command.js.map +1 -1
  21. package/dist/cli/run-plain.d.ts +18 -0
  22. package/dist/cli/run-plain.js +90 -0
  23. package/dist/cli/run-plain.js.map +1 -0
  24. package/dist/cli/telemetry.js +2 -0
  25. package/dist/cli/telemetry.js.map +1 -1
  26. package/dist/cli/tunnel-control-server.d.ts +9 -0
  27. package/dist/cli/tunnel-control-server.js +31 -0
  28. package/dist/cli/tunnel-control-server.js.map +1 -0
  29. package/dist/cli/tunnel-control-server.test.js +39 -0
  30. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  31. package/dist/cli/tunnel-handler.d.ts +3 -0
  32. package/dist/cli/tunnel-handler.js +48 -0
  33. package/dist/cli/tunnel-handler.js.map +1 -0
  34. package/dist/cli/tunnel-handler.test.js +105 -0
  35. package/dist/cli/tunnel-handler.test.js.map +1 -0
  36. package/dist/cli/tunnel.d.ts +57 -0
  37. package/dist/cli/tunnel.js +154 -0
  38. package/dist/cli/tunnel.js.map +1 -0
  39. package/dist/cli/tunnel.test.js +190 -0
  40. package/dist/cli/tunnel.test.js.map +1 -0
  41. package/dist/cli/types.js.map +1 -1
  42. package/dist/cli/use-execute-steps.d.ts +1 -1
  43. package/dist/cli/use-execute-steps.js.map +1 -1
  44. package/dist/cli/use-messages.js.map +1 -1
  45. package/dist/cli/use-nodemon.d.ts +25 -1
  46. package/dist/cli/use-nodemon.js +97 -55
  47. package/dist/cli/use-nodemon.js.map +1 -1
  48. package/dist/cli/use-open-browser.d.ts +1 -0
  49. package/dist/cli/use-open-browser.js +44 -0
  50. package/dist/cli/use-open-browser.js.map +1 -0
  51. package/dist/cli/use-tunnel.d.ts +1 -1
  52. package/dist/cli/use-tunnel.js +102 -68
  53. package/dist/cli/use-tunnel.js.map +1 -1
  54. package/dist/cli/use-typescript-check.d.ts +9 -2
  55. package/dist/cli/use-typescript-check.js +91 -51
  56. package/dist/cli/use-typescript-check.js.map +1 -1
  57. package/dist/commands/build.d.ts +0 -3
  58. package/dist/commands/build.js +2 -38
  59. package/dist/commands/build.js.map +1 -1
  60. package/dist/commands/create.d.ts +9 -0
  61. package/dist/commands/create.js +30 -0
  62. package/dist/commands/create.js.map +1 -0
  63. package/dist/commands/dev.d.ts +2 -0
  64. package/dist/commands/dev.js +84 -5
  65. package/dist/commands/dev.js.map +1 -1
  66. package/dist/commands/start.js +7 -1
  67. package/dist/commands/start.js.map +1 -1
  68. package/dist/commands/telemetry/disable.js.map +1 -1
  69. package/dist/commands/telemetry/enable.js.map +1 -1
  70. package/dist/commands/telemetry/status.js.map +1 -1
  71. package/dist/context-warnings.d.ts +5 -0
  72. package/dist/context-warnings.js +31 -0
  73. package/dist/context-warnings.js.map +1 -0
  74. package/dist/context-warnings.test.js +28 -0
  75. package/dist/context-warnings.test.js.map +1 -0
  76. package/dist/server/app.d.ts +211 -0
  77. package/dist/server/app.js +277 -0
  78. package/dist/server/app.js.map +1 -0
  79. package/dist/server/app.test.d.ts +1 -0
  80. package/dist/server/app.test.js +178 -0
  81. package/dist/server/app.test.js.map +1 -0
  82. package/dist/server/asset-base-url-transform-plugin.d.ts +1 -0
  83. package/dist/server/asset-base-url-transform-plugin.js +17 -2
  84. package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
  85. package/dist/server/asset-base-url-transform-plugin.test.js +80 -1
  86. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
  87. package/dist/server/auth/discovery.d.ts +33 -0
  88. package/dist/server/auth/discovery.js +56 -0
  89. package/dist/server/auth/discovery.js.map +1 -0
  90. package/dist/server/auth/discovery.test.d.ts +1 -0
  91. package/dist/server/auth/discovery.test.js +93 -0
  92. package/dist/server/auth/discovery.test.js.map +1 -0
  93. package/dist/server/auth/index.d.ts +48 -0
  94. package/dist/server/auth/index.js +2 -0
  95. package/dist/server/auth/index.js.map +1 -0
  96. package/dist/server/auth/providers/auth0.d.ts +40 -0
  97. package/dist/server/auth/providers/auth0.js +36 -0
  98. package/dist/server/auth/providers/auth0.js.map +1 -0
  99. package/dist/server/auth/providers/auth0.test.d.ts +1 -0
  100. package/dist/server/auth/providers/auth0.test.js +50 -0
  101. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  102. package/dist/server/auth/providers/authplane.d.ts +49 -0
  103. package/dist/server/auth/providers/authplane.js +57 -0
  104. package/dist/server/auth/providers/authplane.js.map +1 -0
  105. package/dist/server/auth/providers/authplane.test.d.ts +1 -0
  106. package/dist/server/auth/providers/authplane.test.js +143 -0
  107. package/dist/server/auth/providers/authplane.test.js.map +1 -0
  108. package/dist/server/auth/providers/clerk.d.ts +51 -0
  109. package/dist/server/auth/providers/clerk.js +19 -0
  110. package/dist/server/auth/providers/clerk.js.map +1 -0
  111. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  112. package/dist/server/auth/providers/clerk.test.js +30 -0
  113. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  114. package/dist/server/auth/providers/custom.d.ts +42 -0
  115. package/dist/server/auth/providers/custom.js +59 -0
  116. package/dist/server/auth/providers/custom.js.map +1 -0
  117. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  118. package/dist/server/auth/providers/custom.test.js +161 -0
  119. package/dist/server/auth/providers/custom.test.js.map +1 -0
  120. package/dist/server/auth/providers/descope.d.ts +44 -0
  121. package/dist/server/auth/providers/descope.js +44 -0
  122. package/dist/server/auth/providers/descope.js.map +1 -0
  123. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  124. package/dist/server/auth/providers/descope.test.js +62 -0
  125. package/dist/server/auth/providers/descope.test.js.map +1 -0
  126. package/dist/server/auth/providers/shared.d.ts +2 -0
  127. package/dist/server/auth/providers/shared.js +6 -0
  128. package/dist/server/auth/providers/shared.js.map +1 -0
  129. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  130. package/dist/server/auth/providers/shared.test.js +10 -0
  131. package/dist/server/auth/providers/shared.test.js.map +1 -0
  132. package/dist/server/auth/providers/stytch.d.ts +25 -0
  133. package/dist/server/auth/providers/stytch.js +16 -0
  134. package/dist/server/auth/providers/stytch.js.map +1 -0
  135. package/dist/server/auth/providers/verify-spy.d.ts +12 -0
  136. package/dist/server/auth/providers/verify-spy.js +21 -0
  137. package/dist/server/auth/providers/verify-spy.js.map +1 -0
  138. package/dist/server/auth/providers/workos.d.ts +34 -0
  139. package/dist/server/auth/providers/workos.js +16 -0
  140. package/dist/server/auth/providers/workos.js.map +1 -0
  141. package/dist/server/auth/security-schemes.d.ts +23 -0
  142. package/dist/server/auth/security-schemes.js +64 -0
  143. package/dist/server/auth/security-schemes.js.map +1 -0
  144. package/dist/server/auth/security-schemes.test.d.ts +1 -0
  145. package/dist/server/auth/security-schemes.test.js +99 -0
  146. package/dist/server/auth/security-schemes.test.js.map +1 -0
  147. package/dist/server/auth/setup.d.ts +6 -0
  148. package/dist/server/auth/setup.js +91 -0
  149. package/dist/server/auth/setup.js.map +1 -0
  150. package/dist/server/auth/setup.test.d.ts +1 -0
  151. package/dist/server/auth/setup.test.js +514 -0
  152. package/dist/server/auth/setup.test.js.map +1 -0
  153. package/dist/server/auth/verify.d.ts +48 -0
  154. package/dist/server/auth/verify.js +62 -0
  155. package/dist/server/auth/verify.js.map +1 -0
  156. package/dist/server/auth/verify.test.d.ts +1 -0
  157. package/dist/server/auth/verify.test.js +165 -0
  158. package/dist/server/auth/verify.test.js.map +1 -0
  159. package/dist/server/auth-extra.test-d.d.ts +1 -0
  160. package/dist/server/auth-extra.test-d.js +130 -0
  161. package/dist/server/auth-extra.test-d.js.map +1 -0
  162. package/dist/server/auth.d.ts +57 -0
  163. package/dist/server/auth.js +27 -0
  164. package/dist/server/auth.js.map +1 -0
  165. package/dist/server/build-manifest.test.d.ts +1 -0
  166. package/dist/server/build-manifest.test.js +28 -0
  167. package/dist/server/build-manifest.test.js.map +1 -0
  168. package/dist/server/content-helpers.d.ts +41 -1
  169. package/dist/server/content-helpers.js +33 -0
  170. package/dist/server/content-helpers.js.map +1 -1
  171. package/dist/server/content-helpers.test.js.map +1 -1
  172. package/dist/server/events.d.ts +113 -0
  173. package/dist/server/events.js +318 -0
  174. package/dist/server/events.js.map +1 -0
  175. package/dist/server/events.test.d.ts +1 -0
  176. package/dist/server/events.test.js +172 -0
  177. package/dist/server/events.test.js.map +1 -0
  178. package/dist/server/express.d.ts +24 -7
  179. package/dist/server/express.js +66 -30
  180. package/dist/server/express.js.map +1 -1
  181. package/dist/server/express.test.js +445 -81
  182. package/dist/server/express.test.js.map +1 -1
  183. package/dist/server/file-ref.d.ts +28 -0
  184. package/dist/server/file-ref.js +27 -0
  185. package/dist/server/file-ref.js.map +1 -0
  186. package/dist/server/form-input.d.ts +120 -0
  187. package/dist/server/form-input.js +89 -0
  188. package/dist/server/form-input.js.map +1 -0
  189. package/dist/server/host.d.ts +2 -0
  190. package/dist/server/host.js +11 -0
  191. package/dist/server/host.js.map +1 -0
  192. package/dist/server/host.test.d.ts +1 -0
  193. package/dist/server/host.test.js +13 -0
  194. package/dist/server/host.test.js.map +1 -0
  195. package/dist/server/index.d.ts +20 -2
  196. package/dist/server/index.js +17 -1
  197. package/dist/server/index.js.map +1 -1
  198. package/dist/server/inferUtilityTypes.d.ts +6 -6
  199. package/dist/server/inferUtilityTypes.js.map +1 -1
  200. package/dist/server/mcp-errors.test.d.ts +1 -0
  201. package/dist/server/mcp-errors.test.js +229 -0
  202. package/dist/server/mcp-errors.test.js.map +1 -0
  203. package/dist/server/metric.d.ts +5 -3
  204. package/dist/server/metric.js +5 -5
  205. package/dist/server/metric.js.map +1 -1
  206. package/dist/server/middleware.d.ts +51 -13
  207. package/dist/server/middleware.js +33 -0
  208. package/dist/server/middleware.js.map +1 -1
  209. package/dist/server/middleware.test-d.js +1 -1
  210. package/dist/server/middleware.test-d.js.map +1 -1
  211. package/dist/server/middleware.test.js +242 -134
  212. package/dist/server/middleware.test.js.map +1 -1
  213. package/dist/server/register-tool.test.d.ts +1 -0
  214. package/dist/server/register-tool.test.js +230 -0
  215. package/dist/server/register-tool.test.js.map +1 -0
  216. package/dist/server/requestOrigin.d.ts +7 -0
  217. package/dist/server/requestOrigin.js +25 -0
  218. package/dist/server/requestOrigin.js.map +1 -0
  219. package/dist/server/server.d.ts +548 -56
  220. package/dist/server/server.js +685 -286
  221. package/dist/server/server.js.map +1 -1
  222. package/dist/server/skills-integration.test.d.ts +1 -0
  223. package/dist/server/skills-integration.test.js +86 -0
  224. package/dist/server/skills-integration.test.js.map +1 -0
  225. package/dist/server/skills.d.ts +27 -0
  226. package/dist/server/skills.js +188 -0
  227. package/dist/server/skills.js.map +1 -0
  228. package/dist/server/skills.test.d.ts +1 -0
  229. package/dist/server/skills.test.js +243 -0
  230. package/dist/server/skills.test.js.map +1 -0
  231. package/dist/server/templateHelper.d.ts +0 -5
  232. package/dist/server/templateHelper.js +3 -22
  233. package/dist/server/templateHelper.js.map +1 -1
  234. package/dist/server/templates.generated.d.ts +4 -0
  235. package/dist/server/templates.generated.js +43 -0
  236. package/dist/server/templates.generated.js.map +1 -0
  237. package/dist/server/tool-extra.test.d.ts +1 -0
  238. package/dist/server/tool-extra.test.js +167 -0
  239. package/dist/server/tool-extra.test.js.map +1 -0
  240. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  241. package/dist/server/tunnel-proxy-router.js +110 -0
  242. package/dist/server/tunnel-proxy-router.js.map +1 -0
  243. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  244. package/dist/server/tunnel-proxy-router.test.js +229 -0
  245. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  246. package/dist/server/view-name.test-d.d.ts +1 -0
  247. package/dist/server/view-name.test-d.js +8 -0
  248. package/dist/server/view-name.test-d.js.map +1 -0
  249. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  250. package/dist/server/view-resource-resolution.test.js +176 -0
  251. package/dist/server/view-resource-resolution.test.js.map +1 -0
  252. package/dist/server/viewsDevServer.js +4 -1
  253. package/dist/server/viewsDevServer.js.map +1 -1
  254. package/dist/test/utils.d.ts +9 -11
  255. package/dist/test/utils.js +220 -201
  256. package/dist/test/utils.js.map +1 -1
  257. package/dist/test/view.test.js +199 -113
  258. package/dist/test/view.test.js.map +1 -1
  259. package/dist/version.js +1 -3
  260. package/dist/version.js.map +1 -1
  261. package/dist/views/index.d.ts +10 -0
  262. package/dist/views/index.js +3 -0
  263. package/dist/views/index.js.map +1 -0
  264. package/dist/{web/plugin → views}/scan-views.d.ts +8 -0
  265. package/dist/{web/plugin → views}/scan-views.js +26 -8
  266. package/dist/views/scan-views.js.map +1 -0
  267. package/dist/views/scan-views.test.d.ts +1 -0
  268. package/dist/{web/plugin → views}/scan-views.test.js +33 -1
  269. package/dist/views/scan-views.test.js.map +1 -0
  270. package/dist/views/validate-view.d.ts +1 -0
  271. package/dist/{web/plugin → views}/validate-view.js +2 -2
  272. package/dist/views/validate-view.js.map +1 -0
  273. package/dist/views/validate-view.test.d.ts +1 -0
  274. package/dist/views/validate-view.test.js.map +1 -0
  275. package/dist/web/bridges/adaptor.d.ts +62 -0
  276. package/dist/web/bridges/adaptor.js +477 -0
  277. package/dist/web/bridges/adaptor.js.map +1 -0
  278. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  279. package/dist/web/bridges/adaptor.test.js +281 -0
  280. package/dist/web/bridges/adaptor.test.js.map +1 -0
  281. package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -1
  282. package/dist/web/bridges/apps-sdk/bridge.js +15 -3
  283. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  284. package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
  285. package/dist/web/bridges/apps-sdk/index.js +0 -1
  286. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  287. package/dist/web/bridges/apps-sdk/types.d.ts +10 -4
  288. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  289. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
  290. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
  291. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  292. package/dist/web/bridges/get-adaptor.d.ts +7 -0
  293. package/dist/web/bridges/get-adaptor.js +9 -7
  294. package/dist/web/bridges/get-adaptor.js.map +1 -1
  295. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  296. package/dist/web/bridges/get-adaptor.test.js +32 -0
  297. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  298. package/dist/web/bridges/index.js.map +1 -1
  299. package/dist/web/bridges/mcp-app/bridge.d.ts +15 -2
  300. package/dist/web/bridges/mcp-app/bridge.js +80 -7
  301. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  302. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  303. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  304. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  305. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  306. package/dist/web/bridges/mcp-app/index.js +0 -1
  307. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  308. package/dist/web/bridges/mcp-app/types.d.ts +19 -2
  309. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  310. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +13 -1
  311. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +12 -0
  312. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  313. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -1
  314. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  315. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  316. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  317. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  318. package/dist/web/bridges/types.d.ts +174 -11
  319. package/dist/web/bridges/types.js +14 -1
  320. package/dist/web/bridges/types.js.map +1 -1
  321. package/dist/web/bridges/types.test.d.ts +1 -0
  322. package/dist/web/bridges/types.test.js +19 -0
  323. package/dist/web/bridges/types.test.js.map +1 -0
  324. package/dist/web/bridges/use-host-context.d.ts +5 -0
  325. package/dist/web/bridges/use-host-context.js +5 -0
  326. package/dist/web/bridges/use-host-context.js.map +1 -1
  327. package/dist/web/components/modal-provider.d.ts +1 -1
  328. package/dist/web/components/modal-provider.js +4 -3
  329. package/dist/web/components/modal-provider.js.map +1 -1
  330. package/dist/web/create-store.d.ts +26 -0
  331. package/dist/web/create-store.js +35 -9
  332. package/dist/web/create-store.js.map +1 -1
  333. package/dist/web/create-store.test.js +24 -23
  334. package/dist/web/create-store.test.js.map +1 -1
  335. package/dist/web/data-llm.d.ts +35 -2
  336. package/dist/web/data-llm.js +34 -5
  337. package/dist/web/data-llm.js.map +1 -1
  338. package/dist/web/data-llm.test.js +48 -29
  339. package/dist/web/data-llm.test.js.map +1 -1
  340. package/dist/web/generate-helpers.d.ts +25 -19
  341. package/dist/web/generate-helpers.js +23 -17
  342. package/dist/web/generate-helpers.js.map +1 -1
  343. package/dist/web/generate-helpers.test-d.js +14 -12
  344. package/dist/web/generate-helpers.test-d.js.map +1 -1
  345. package/dist/web/generate-helpers.test.js +2 -2
  346. package/dist/web/generate-helpers.test.js.map +1 -1
  347. package/dist/web/helpers/state.d.ts +2 -2
  348. package/dist/web/helpers/state.js +11 -11
  349. package/dist/web/helpers/state.js.map +1 -1
  350. package/dist/web/helpers/state.test.js +9 -9
  351. package/dist/web/helpers/state.test.js.map +1 -1
  352. package/dist/web/hooks/index.d.ts +11 -2
  353. package/dist/web/hooks/index.js +11 -2
  354. package/dist/web/hooks/index.js.map +1 -1
  355. package/dist/web/hooks/openai-extensions.test.d.ts +1 -0
  356. package/dist/web/hooks/openai-extensions.test.js +107 -0
  357. package/dist/web/hooks/openai-extensions.test.js.map +1 -0
  358. package/dist/web/hooks/test/utils.d.ts +7 -2
  359. package/dist/web/hooks/test/utils.js +14 -3
  360. package/dist/web/hooks/test/utils.js.map +1 -1
  361. package/dist/web/hooks/use-call-tool.d.ts +47 -2
  362. package/dist/web/hooks/use-call-tool.js +43 -10
  363. package/dist/web/hooks/use-call-tool.js.map +1 -1
  364. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
  365. package/dist/web/hooks/use-call-tool.test.js +75 -29
  366. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  367. package/dist/web/hooks/use-deep-link.d.ts +22 -0
  368. package/dist/web/hooks/use-deep-link.js +34 -0
  369. package/dist/web/hooks/use-deep-link.js.map +1 -0
  370. package/dist/web/hooks/use-display-mode.d.ts +20 -0
  371. package/dist/web/hooks/use-display-mode.js +20 -0
  372. package/dist/web/hooks/use-display-mode.js.map +1 -1
  373. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
  374. package/dist/web/hooks/use-display-mode.test.js +57 -21
  375. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  376. package/dist/web/hooks/use-download.d.ts +3 -0
  377. package/dist/web/hooks/use-download.js +7 -0
  378. package/dist/web/hooks/use-download.js.map +1 -0
  379. package/dist/web/hooks/use-download.test.d.ts +1 -0
  380. package/dist/web/hooks/use-download.test.js +103 -0
  381. package/dist/web/hooks/use-download.test.js.map +1 -0
  382. package/dist/web/hooks/use-file-resource.d.ts +37 -0
  383. package/dist/web/hooks/use-file-resource.js +98 -0
  384. package/dist/web/hooks/use-file-resource.js.map +1 -0
  385. package/dist/web/hooks/use-file-resource.test.d.ts +1 -0
  386. package/dist/web/hooks/use-file-resource.test.js +65 -0
  387. package/dist/web/hooks/use-file-resource.test.js.map +1 -0
  388. package/dist/web/hooks/use-files.d.ts +32 -0
  389. package/dist/web/hooks/use-files.js +32 -0
  390. package/dist/web/hooks/use-files.js.map +1 -1
  391. package/dist/web/hooks/use-files.test.js +11 -3
  392. package/dist/web/hooks/use-files.test.js.map +1 -1
  393. package/dist/web/hooks/use-host.d.ts +44 -0
  394. package/dist/web/hooks/use-host.js +45 -0
  395. package/dist/web/hooks/use-host.js.map +1 -0
  396. package/dist/web/hooks/use-host.test.d.ts +1 -0
  397. package/dist/web/hooks/use-host.test.js +59 -0
  398. package/dist/web/hooks/use-host.test.js.map +1 -0
  399. package/dist/web/hooks/use-model-context.d.ts +44 -0
  400. package/dist/web/hooks/use-model-context.js +63 -0
  401. package/dist/web/hooks/use-model-context.js.map +1 -0
  402. package/dist/web/hooks/use-open-external.d.ts +17 -0
  403. package/dist/web/hooks/use-open-external.js +16 -0
  404. package/dist/web/hooks/use-open-external.js.map +1 -1
  405. package/dist/web/hooks/use-open-external.test.js +15 -5
  406. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  407. package/dist/web/hooks/use-open-file.d.ts +20 -0
  408. package/dist/web/hooks/use-open-file.js +25 -0
  409. package/dist/web/hooks/use-open-file.js.map +1 -0
  410. package/dist/web/hooks/use-register-view-tool.d.ts +37 -0
  411. package/dist/web/hooks/use-register-view-tool.js +50 -0
  412. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  413. package/dist/web/hooks/use-request-close.d.ts +16 -0
  414. package/dist/web/hooks/use-request-close.js +21 -0
  415. package/dist/web/hooks/use-request-close.js.map +1 -0
  416. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  417. package/dist/web/hooks/use-request-close.test.js +47 -0
  418. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  419. package/dist/web/hooks/use-request-modal.d.ts +16 -1
  420. package/dist/web/hooks/use-request-modal.js +19 -4
  421. package/dist/web/hooks/use-request-modal.js.map +1 -1
  422. package/dist/web/hooks/use-request-modal.test.js +12 -2
  423. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  424. package/dist/web/hooks/use-request-size.d.ts +20 -0
  425. package/dist/web/hooks/use-request-size.js +24 -0
  426. package/dist/web/hooks/use-request-size.js.map +1 -0
  427. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  428. package/dist/web/hooks/use-request-size.test.js +47 -0
  429. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  430. package/dist/web/hooks/use-send-follow-up-message.d.ts +25 -1
  431. package/dist/web/hooks/use-send-follow-up-message.js +25 -2
  432. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  433. package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
  434. package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
  435. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
  436. package/dist/web/hooks/use-set-open-in-app-url.test.js +26 -12
  437. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  438. package/dist/web/hooks/use-tool-info.d.ts +46 -14
  439. package/dist/web/hooks/use-tool-info.js +29 -7
  440. package/dist/web/hooks/use-tool-info.js.map +1 -1
  441. package/dist/web/hooks/use-tool-info.test-d.js +11 -34
  442. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  443. package/dist/web/hooks/use-tool-info.test.js +42 -37
  444. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  445. package/dist/web/hooks/use-user.d.ts +5 -2
  446. package/dist/web/hooks/use-user.js +6 -3
  447. package/dist/web/hooks/use-user.js.map +1 -1
  448. package/dist/web/hooks/use-user.test.js +85 -37
  449. package/dist/web/hooks/use-user.test.js.map +1 -1
  450. package/dist/web/hooks/use-view-state.d.ts +25 -0
  451. package/dist/web/hooks/use-view-state.js +42 -0
  452. package/dist/web/hooks/use-view-state.js.map +1 -0
  453. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  454. package/dist/web/hooks/{use-widget-state.test.js → use-view-state.test.js} +56 -21
  455. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  456. package/dist/web/hooks/use-viewport.d.ts +20 -0
  457. package/dist/web/hooks/use-viewport.js +21 -0
  458. package/dist/web/hooks/use-viewport.js.map +1 -0
  459. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  460. package/dist/web/hooks/use-viewport.test.js +109 -0
  461. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  462. package/dist/web/index.d.ts +1 -3
  463. package/dist/web/index.js +1 -2
  464. package/dist/web/index.js.map +1 -1
  465. package/dist/web/mount-view.d.ts +21 -0
  466. package/dist/web/mount-view.js +43 -0
  467. package/dist/web/mount-view.js.map +1 -0
  468. package/dist/web/proxy.js.map +1 -1
  469. package/dist/web/types.d.ts +4 -0
  470. package/dist/web/types.js.map +1 -1
  471. package/package.json +46 -28
  472. package/dist/server/templates/development.hbs +0 -12
  473. package/dist/server/templates/production.hbs +0 -6
  474. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -24
  475. package/dist/web/bridges/apps-sdk/adaptor.js +0 -87
  476. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  477. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -48
  478. package/dist/web/bridges/mcp-app/adaptor.js +0 -268
  479. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
  480. package/dist/web/hooks/use-layout.d.ts +0 -22
  481. package/dist/web/hooks/use-layout.js +0 -23
  482. package/dist/web/hooks/use-layout.js.map +0 -1
  483. package/dist/web/hooks/use-layout.test.js +0 -96
  484. package/dist/web/hooks/use-layout.test.js.map +0 -1
  485. package/dist/web/hooks/use-widget-state.d.ts +0 -4
  486. package/dist/web/hooks/use-widget-state.js +0 -32
  487. package/dist/web/hooks/use-widget-state.js.map +0 -1
  488. package/dist/web/hooks/use-widget-state.test.js.map +0 -1
  489. package/dist/web/mount-widget.d.ts +0 -1
  490. package/dist/web/mount-widget.js +0 -27
  491. package/dist/web/mount-widget.js.map +0 -1
  492. package/dist/web/plugin/data-llm.test.js +0 -81
  493. package/dist/web/plugin/data-llm.test.js.map +0 -1
  494. package/dist/web/plugin/plugin.d.ts +0 -5
  495. package/dist/web/plugin/plugin.js +0 -141
  496. package/dist/web/plugin/plugin.js.map +0 -1
  497. package/dist/web/plugin/scan-views.js.map +0 -1
  498. package/dist/web/plugin/scan-views.test.js.map +0 -1
  499. package/dist/web/plugin/transform-data-llm.d.ts +0 -12
  500. package/dist/web/plugin/transform-data-llm.js +0 -96
  501. package/dist/web/plugin/transform-data-llm.js.map +0 -1
  502. package/dist/web/plugin/transform-data-llm.test.js +0 -81
  503. package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
  504. package/dist/web/plugin/validate-view.d.ts +0 -1
  505. package/dist/web/plugin/validate-view.js.map +0 -1
  506. package/dist/web/plugin/validate-view.test.js.map +0 -1
  507. /package/dist/{web/hooks/use-layout.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  508. /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  509. /package/dist/{web/plugin/data-llm.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
  510. /package/dist/{web/plugin/scan-views.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
  511. /package/dist/{web/plugin/transform-data-llm.test.d.ts → cli/tunnel.test.d.ts} +0 -0
  512. /package/dist/{web/plugin/validate-view.test.d.ts → context-warnings.test.d.ts} +0 -0
  513. /package/dist/{web/plugin → views}/validate-view.test.js +0 -0
@@ -0,0 +1,190 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { Readable } from "node:stream";
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
+ import { parseStdoutLine, TunnelManager } from "./tunnel.js";
5
+ describe("parseStdoutLine", () => {
6
+ it("returns a connected event when the forwarding line is seen", () => {
7
+ const result = parseStdoutLine("Forwarding: https://abc.tunnel.example -> http://localhost:3000");
8
+ expect(result).toEqual({
9
+ kind: "connected",
10
+ url: "https://abc.tunnel.example",
11
+ });
12
+ });
13
+ it("strips a trailing slash from the forwarded URL", () => {
14
+ const result = parseStdoutLine("Forwarding: https://abc.tunnel.example/ -> http://localhost:3000");
15
+ expect(result).toEqual({
16
+ kind: "connected",
17
+ url: "https://abc.tunnel.example",
18
+ });
19
+ });
20
+ it("returns a starting event for any other non-empty line", () => {
21
+ expect(parseStdoutLine("Opening tunnel...")).toEqual({
22
+ kind: "starting",
23
+ message: "Opening tunnel...",
24
+ });
25
+ });
26
+ it("returns null for empty lines", () => {
27
+ expect(parseStdoutLine("")).toBeNull();
28
+ expect(parseStdoutLine(" ")).toBeNull();
29
+ });
30
+ });
31
+ function makeFakeChild() {
32
+ const child = new EventEmitter();
33
+ child.stdout = new Readable({ read() { } });
34
+ child.stderr = new Readable({ read() { } });
35
+ child.kill = vi.fn(() => true);
36
+ return child;
37
+ }
38
+ describe("TunnelManager", () => {
39
+ beforeEach(() => {
40
+ vi.useFakeTimers();
41
+ });
42
+ afterEach(() => {
43
+ vi.useRealTimers();
44
+ });
45
+ it("starts idle", () => {
46
+ const manager = new TunnelManager({
47
+ getPort: () => 3000,
48
+ spawn: () => makeFakeChild(),
49
+ });
50
+ expect(manager.getState()).toEqual({ status: "idle" });
51
+ });
52
+ it("transitions idle -> starting -> connected as stdout reports progress", () => {
53
+ const child = makeFakeChild();
54
+ const manager = new TunnelManager({
55
+ getPort: () => 3000,
56
+ spawn: () => child,
57
+ });
58
+ const states = [];
59
+ manager.on("state", (s) => states.push(s.status));
60
+ manager.start();
61
+ child.stdout.emit("data", Buffer.from("Opening tunnel...\n"));
62
+ child.stdout.emit("data", Buffer.from("Forwarding: https://abc.tunnel.example -> http://localhost:3000\n"));
63
+ expect(states).toEqual(["starting", "starting", "connected"]);
64
+ expect(manager.getState()).toEqual({
65
+ status: "connected",
66
+ url: "https://abc.tunnel.example",
67
+ });
68
+ });
69
+ it("emits activity events for stdout lines after connect", () => {
70
+ const child = makeFakeChild();
71
+ const manager = new TunnelManager({
72
+ getPort: () => 3000,
73
+ spawn: () => child,
74
+ });
75
+ const activity = [];
76
+ manager.on("activity", (a) => activity.push({ text: a.text, level: a.level }));
77
+ manager.start();
78
+ child.stdout.emit("data", Buffer.from("Forwarding: https://abc.tunnel.example -> http://localhost:3000\n"));
79
+ child.stdout.emit("data", Buffer.from("GET /widgets/foo\n"));
80
+ child.stderr.emit("data", Buffer.from("connection wobble\n"));
81
+ expect(activity).toEqual([
82
+ { text: "GET /widgets/foo", level: "log" },
83
+ { text: "connection wobble", level: "error" },
84
+ ]);
85
+ });
86
+ it("calling start twice does not spawn twice", () => {
87
+ const spawn = vi.fn(() => makeFakeChild());
88
+ const manager = new TunnelManager({ getPort: () => 3000, spawn });
89
+ manager.start();
90
+ manager.start();
91
+ expect(spawn).toHaveBeenCalledTimes(1);
92
+ });
93
+ it("transitions to error when the connection times out", () => {
94
+ const child = makeFakeChild();
95
+ const manager = new TunnelManager({
96
+ getPort: () => 3000,
97
+ spawn: () => child,
98
+ });
99
+ manager.start();
100
+ vi.advanceTimersByTime(60_000);
101
+ expect(manager.getState().status).toBe("error");
102
+ expect(child.kill).toHaveBeenCalled();
103
+ });
104
+ it("preserves the timeout error message when the killed child later emits close", () => {
105
+ const child = makeFakeChild();
106
+ const manager = new TunnelManager({
107
+ getPort: () => 3000,
108
+ spawn: () => child,
109
+ });
110
+ manager.start();
111
+ vi.advanceTimersByTime(60_000);
112
+ // The killed child emits a non-zero close after the timeout fired.
113
+ child.emit("close", 1);
114
+ expect(manager.getState()).toEqual({
115
+ status: "error",
116
+ message: "Tunnel connection timed out after one minute",
117
+ });
118
+ });
119
+ it("stop() kills the subprocess and goes idle", () => {
120
+ const child = makeFakeChild();
121
+ const manager = new TunnelManager({
122
+ getPort: () => 3000,
123
+ spawn: () => child,
124
+ });
125
+ manager.start();
126
+ manager.stop();
127
+ expect(child.kill).toHaveBeenCalled();
128
+ expect(manager.getState()).toEqual({ status: "idle" });
129
+ });
130
+ it("subscribers get the current state on subscribe", () => {
131
+ const child = makeFakeChild();
132
+ const manager = new TunnelManager({
133
+ getPort: () => 3000,
134
+ spawn: () => child,
135
+ });
136
+ manager.start();
137
+ child.stdout.emit("data", Buffer.from("Forwarding: https://abc.tunnel.example -> http://localhost:3000\n"));
138
+ let received;
139
+ const unsubscribe = manager.subscribe((s) => {
140
+ received = s;
141
+ });
142
+ expect(received).toEqual({
143
+ status: "connected",
144
+ url: "https://abc.tunnel.example",
145
+ });
146
+ unsubscribe();
147
+ });
148
+ it("ignores deferred close from a child that was replaced via stop()+start()", () => {
149
+ const childA = makeFakeChild();
150
+ const childB = makeFakeChild();
151
+ let spawnCount = 0;
152
+ const manager = new TunnelManager({
153
+ getPort: () => 3000,
154
+ spawn: () => (spawnCount++ === 0 ? childA : childB),
155
+ });
156
+ manager.start();
157
+ manager.stop();
158
+ manager.start();
159
+ childB.stdout.emit("data", Buffer.from("Forwarding: https://abc.tunnel.example -> http://localhost:3000\n"));
160
+ expect(manager.getState()).toEqual({
161
+ status: "connected",
162
+ url: "https://abc.tunnel.example",
163
+ });
164
+ // Stale close from childA arrives only now — must not clobber state.
165
+ childA.emit("close", null);
166
+ expect(manager.getState()).toEqual({
167
+ status: "connected",
168
+ url: "https://abc.tunnel.example",
169
+ });
170
+ });
171
+ it("ignores deferred error from a child that was replaced via stop()+start()", () => {
172
+ const childA = makeFakeChild();
173
+ const childB = makeFakeChild();
174
+ let spawnCount = 0;
175
+ const manager = new TunnelManager({
176
+ getPort: () => 3000,
177
+ spawn: () => (spawnCount++ === 0 ? childA : childB),
178
+ });
179
+ manager.start();
180
+ manager.stop();
181
+ manager.start();
182
+ childB.stdout.emit("data", Buffer.from("Forwarding: https://abc.tunnel.example -> http://localhost:3000\n"));
183
+ childA.emit("error", new Error("late spawn failure"));
184
+ expect(manager.getState()).toEqual({
185
+ status: "connected",
186
+ url: "https://abc.tunnel.example",
187
+ });
188
+ });
189
+ });
190
+ //# sourceMappingURL=tunnel.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.test.js","sourceRoot":"","sources":["../../src/cli/tunnel.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventEmitter } from \"node:events\";\nimport { Readable } from \"node:stream\";\nimport { afterEach, beforeEach, describe, expect, it, vi } from \"vitest\";\nimport { parseStdoutLine, TunnelManager, type TunnelState } from \"./tunnel.js\";\n\ndescribe(\"parseStdoutLine\", () => {\n it(\"returns a connected event when the forwarding line is seen\", () => {\n const result = parseStdoutLine(\n \"Forwarding: https://abc.tunnel.example -> http://localhost:3000\",\n );\n expect(result).toEqual({\n kind: \"connected\",\n url: \"https://abc.tunnel.example\",\n });\n });\n\n it(\"strips a trailing slash from the forwarded URL\", () => {\n const result = parseStdoutLine(\n \"Forwarding: https://abc.tunnel.example/ -> http://localhost:3000\",\n );\n expect(result).toEqual({\n kind: \"connected\",\n url: \"https://abc.tunnel.example\",\n });\n });\n\n it(\"returns a starting event for any other non-empty line\", () => {\n expect(parseStdoutLine(\"Opening tunnel...\")).toEqual({\n kind: \"starting\",\n message: \"Opening tunnel...\",\n });\n });\n\n it(\"returns null for empty lines\", () => {\n expect(parseStdoutLine(\"\")).toBeNull();\n expect(parseStdoutLine(\" \")).toBeNull();\n });\n});\n\ntype FakeChild = EventEmitter & {\n stdout: Readable;\n stderr: Readable;\n kill: ReturnType<typeof vi.fn<() => boolean>>;\n};\n\nfunction makeFakeChild(): FakeChild {\n const child = new EventEmitter() as FakeChild;\n child.stdout = new Readable({ read() {} });\n child.stderr = new Readable({ read() {} });\n child.kill = vi.fn<() => boolean>(() => true);\n return child;\n}\n\ndescribe(\"TunnelManager\", () => {\n beforeEach(() => {\n vi.useFakeTimers();\n });\n afterEach(() => {\n vi.useRealTimers();\n });\n\n it(\"starts idle\", () => {\n const manager = new TunnelManager({\n getPort: () => 3000,\n spawn: () => makeFakeChild(),\n });\n expect(manager.getState()).toEqual({ status: \"idle\" });\n });\n\n it(\"transitions idle -> starting -> connected as stdout reports progress\", () => {\n const child = makeFakeChild();\n const manager = new TunnelManager({\n getPort: () => 3000,\n spawn: () => child,\n });\n const states: string[] = [];\n manager.on(\"state\", (s: TunnelState) => states.push(s.status));\n\n manager.start();\n child.stdout.emit(\"data\", Buffer.from(\"Opening tunnel...\\n\"));\n child.stdout.emit(\n \"data\",\n Buffer.from(\n \"Forwarding: https://abc.tunnel.example -> http://localhost:3000\\n\",\n ),\n );\n\n expect(states).toEqual([\"starting\", \"starting\", \"connected\"]);\n expect(manager.getState()).toEqual({\n status: \"connected\",\n url: \"https://abc.tunnel.example\",\n });\n });\n\n it(\"emits activity events for stdout lines after connect\", () => {\n const child = makeFakeChild();\n const manager = new TunnelManager({\n getPort: () => 3000,\n spawn: () => child,\n });\n const activity: Array<{ text: string; level: string }> = [];\n manager.on(\"activity\", (a: { text: string; level: string }) =>\n activity.push({ text: a.text, level: a.level }),\n );\n\n manager.start();\n child.stdout.emit(\n \"data\",\n Buffer.from(\n \"Forwarding: https://abc.tunnel.example -> http://localhost:3000\\n\",\n ),\n );\n child.stdout.emit(\"data\", Buffer.from(\"GET /widgets/foo\\n\"));\n child.stderr.emit(\"data\", Buffer.from(\"connection wobble\\n\"));\n\n expect(activity).toEqual([\n { text: \"GET /widgets/foo\", level: \"log\" },\n { text: \"connection wobble\", level: \"error\" },\n ]);\n });\n\n it(\"calling start twice does not spawn twice\", () => {\n const spawn = vi.fn(() => makeFakeChild());\n const manager = new TunnelManager({ getPort: () => 3000, spawn });\n manager.start();\n manager.start();\n expect(spawn).toHaveBeenCalledTimes(1);\n });\n\n it(\"transitions to error when the connection times out\", () => {\n const child = makeFakeChild();\n const manager = new TunnelManager({\n getPort: () => 3000,\n spawn: () => child,\n });\n manager.start();\n\n vi.advanceTimersByTime(60_000);\n\n expect(manager.getState().status).toBe(\"error\");\n expect(child.kill).toHaveBeenCalled();\n });\n\n it(\"preserves the timeout error message when the killed child later emits close\", () => {\n const child = makeFakeChild();\n const manager = new TunnelManager({\n getPort: () => 3000,\n spawn: () => child,\n });\n manager.start();\n\n vi.advanceTimersByTime(60_000);\n // The killed child emits a non-zero close after the timeout fired.\n child.emit(\"close\", 1);\n\n expect(manager.getState()).toEqual({\n status: \"error\",\n message: \"Tunnel connection timed out after one minute\",\n });\n });\n\n it(\"stop() kills the subprocess and goes idle\", () => {\n const child = makeFakeChild();\n const manager = new TunnelManager({\n getPort: () => 3000,\n spawn: () => child,\n });\n manager.start();\n manager.stop();\n expect(child.kill).toHaveBeenCalled();\n expect(manager.getState()).toEqual({ status: \"idle\" });\n });\n\n it(\"subscribers get the current state on subscribe\", () => {\n const child = makeFakeChild();\n const manager = new TunnelManager({\n getPort: () => 3000,\n spawn: () => child,\n });\n manager.start();\n child.stdout.emit(\n \"data\",\n Buffer.from(\n \"Forwarding: https://abc.tunnel.example -> http://localhost:3000\\n\",\n ),\n );\n\n let received: TunnelState | undefined;\n const unsubscribe = manager.subscribe((s) => {\n received = s;\n });\n expect(received).toEqual({\n status: \"connected\",\n url: \"https://abc.tunnel.example\",\n });\n unsubscribe();\n });\n\n it(\"ignores deferred close from a child that was replaced via stop()+start()\", () => {\n const childA = makeFakeChild();\n const childB = makeFakeChild();\n let spawnCount = 0;\n const manager = new TunnelManager({\n getPort: () => 3000,\n spawn: () => (spawnCount++ === 0 ? childA : childB),\n });\n\n manager.start();\n manager.stop();\n manager.start();\n childB.stdout.emit(\n \"data\",\n Buffer.from(\n \"Forwarding: https://abc.tunnel.example -> http://localhost:3000\\n\",\n ),\n );\n expect(manager.getState()).toEqual({\n status: \"connected\",\n url: \"https://abc.tunnel.example\",\n });\n\n // Stale close from childA arrives only now — must not clobber state.\n childA.emit(\"close\", null);\n expect(manager.getState()).toEqual({\n status: \"connected\",\n url: \"https://abc.tunnel.example\",\n });\n });\n\n it(\"ignores deferred error from a child that was replaced via stop()+start()\", () => {\n const childA = makeFakeChild();\n const childB = makeFakeChild();\n let spawnCount = 0;\n const manager = new TunnelManager({\n getPort: () => 3000,\n spawn: () => (spawnCount++ === 0 ? childA : childB),\n });\n\n manager.start();\n manager.stop();\n manager.start();\n childB.stdout.emit(\n \"data\",\n Buffer.from(\n \"Forwarding: https://abc.tunnel.example -> http://localhost:3000\\n\",\n ),\n );\n\n childA.emit(\"error\", new Error(\"late spawn failure\"));\n expect(manager.getState()).toEqual({\n status: \"connected\",\n url: \"https://abc.tunnel.example\",\n });\n });\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"","sourcesContent":["export type Message = {\n id: string;\n text: string;\n type: \"log\" | \"restart\" | \"error\";\n};\n"]}
@@ -5,7 +5,7 @@ export interface CommandStep {
5
5
  }
6
6
  export declare const useExecuteSteps: (steps: CommandStep[]) => {
7
7
  currentStep: number;
8
- status: "error" | "success" | "running";
8
+ status: "error" | "running" | "success";
9
9
  error: string | null;
10
10
  execute: () => Promise<void>;
11
11
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-execute-steps.js","sourceRoot":"","sources":["../../src/cli/use-execute-steps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQ9C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAoB,EAAE,EAAE;IACtD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAS,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAClC,SAAS,CACV,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,IAAI,CAAC;YACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,IAAI,IAAI,EAAE,CAAC;oBACT,cAAc,CAAC,CAAC,CAAC,CAAC;oBAClB,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;wBACb,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;oBACnB,CAAC;oBACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;wBACjB,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACjC,CAAC;gBACH,CAAC;YACH,CAAC;YACD,SAAS,CAAC,SAAS,CAAC,CAAC;YACrB,YAAY,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3D,YAAY,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACjD,CAAC,CAAC"}
1
+ {"version":3,"file":"use-execute-steps.js","sourceRoot":"","sources":["../../src/cli/use-execute-steps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQ9C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAoB,EAAE,EAAE;IACtD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAS,CAAC,CAAC,CAAC;IAC1D,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAClC,SAAS,CACV,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,IAAI,CAAC;YACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,IAAI,IAAI,EAAE,CAAC;oBACT,cAAc,CAAC,CAAC,CAAC,CAAC;oBAClB,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;wBACb,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;oBACnB,CAAC;oBACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;wBACjB,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACjC,CAAC;gBACH,CAAC;YACH,CAAC;YACD,SAAS,CAAC,SAAS,CAAC,CAAC;YACrB,YAAY,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3D,YAAY,CAAC,GAAG,EAAE;gBAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEZ,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACjD,CAAC,CAAC","sourcesContent":["import { useCallback, useState } from \"react\";\nimport { runCommand } from \"./run-command.js\";\n\nexport interface CommandStep {\n label: string;\n command?: string;\n run?: () => void | Promise<void>;\n}\n\nexport const useExecuteSteps = (steps: CommandStep[]) => {\n const [currentStep, setCurrentStep] = useState<number>(0);\n const [status, setStatus] = useState<\"running\" | \"success\" | \"error\">(\n \"running\",\n );\n const [error, setError] = useState<string | null>(null);\n\n const execute = useCallback(async () => {\n try {\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n if (step) {\n setCurrentStep(i);\n if (step.run) {\n await step.run();\n }\n if (step.command) {\n await runCommand(step.command);\n }\n }\n }\n setStatus(\"success\");\n setImmediate(() => {\n process.exit(0);\n });\n } catch (err) {\n setStatus(\"error\");\n setError(err instanceof Error ? err.message : String(err));\n setImmediate(() => {\n process.exit(1);\n });\n }\n }, [steps]);\n\n return { currentStep, status, error, execute };\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"use-messages.js","sourceRoot":"","sources":["../../src/cli/use-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG9C,MAAM,YAAY,GAAG,EAAE,CAAC;AAIxB,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAiB,EAAE,CAAC,CAAC;IAE7D,MAAM,IAAI,GAAG,WAAW,CAAc,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;QACnD,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,CACnB,CAAC,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CACjE,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"use-messages.js","sourceRoot":"","sources":["../../src/cli/use-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG9C,MAAM,YAAY,GAAG,EAAE,CAAC;AAIxB,MAAM,UAAU,WAAW;IACzB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAiB,EAAE,CAAC,CAAC;IAE7D,MAAM,IAAI,GAAG,WAAW,CAAc,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;QACnD,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE,CACnB,CAAC,GAAG,IAAI,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CACjE,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { useCallback, useState } from \"react\";\nimport type { Message } from \"./types.js\";\n\nconst MAX_MESSAGES = 10;\n\nexport type PushMessage = (text: string, type: Message[\"type\"]) => void;\n\nexport function useMessages(): [Array<Message>, PushMessage] {\n const [messages, setMessages] = useState<Array<Message>>([]);\n\n const push = useCallback<PushMessage>((text, type) => {\n setMessages((prev) =>\n [...prev, { id: randomUUID(), text, type }].slice(-MAX_MESSAGES),\n );\n }, []);\n\n return [messages, push];\n}\n"]}
@@ -1,2 +1,26 @@
1
1
  import type { PushMessage } from "./use-messages.js";
2
- export declare function useNodemon(env: NodeJS.ProcessEnv, pushMessage: PushMessage): void;
2
+ export declare const CRASH_MESSAGE = "\uD83D\uDCA5 Server crashed. Fix the error, then save a watched file to restart it.";
3
+ export interface NodemonHandlers {
4
+ /** A raw chunk of server stdout, forwarded untouched. */
5
+ onStdout: (chunk: Buffer) => void;
6
+ /** A (filtered) chunk of server stderr. */
7
+ onStderr: (message: string) => void;
8
+ /** The server restarted because the listed files changed. */
9
+ onRestart: (files: string[]) => void;
10
+ /**
11
+ * The server exited with a non-zero code. nodemon does not restart it on its
12
+ * own: it waits for the next file change.
13
+ */
14
+ onCrash: () => void;
15
+ }
16
+ /**
17
+ * Boot nodemon and wire its stdout/stderr to the provided handlers. Returns a
18
+ * cleanup function that detaches the listeners and quits nodemon. Shared by the
19
+ * Ink-based dev UI (via {@link useNodemon}) and the `--plain` runner.
20
+ */
21
+ export declare function startNodemon(env: NodeJS.ProcessEnv, handlers: NodemonHandlers): () => void;
22
+ /**
23
+ * Boot nodemon for the Ink dev UI. Returns whether the server is currently
24
+ * down after a crash, so the UI can stop advertising a URL nothing listens on.
25
+ */
26
+ export declare function useNodemon(env: NodeJS.ProcessEnv, pushMessage: PushMessage): boolean;
@@ -1,64 +1,106 @@
1
1
  import { existsSync } from "node:fs";
2
+ import { createRequire } from "node:module";
2
3
  import { resolve } from "node:path";
3
- import nodemonOriginal from "nodemon";
4
- import { useEffect } from "react";
5
- const nodemon = nodemonOriginal;
4
+ import { useEffect, useState } from "react";
5
+ function loadNodemon() {
6
+ try {
7
+ return createRequire(import.meta.url)("nodemon");
8
+ }
9
+ catch {
10
+ throw new Error('skybridge dev needs the "nodemon" peer dependency. Install it with `npm install -D nodemon`.');
11
+ }
12
+ }
13
+ export const CRASH_MESSAGE = "💥 Server crashed. Fix the error, then save a watched file to restart it.";
14
+ const SOURCEMAP_WARNING = /^Sourcemap for ".*" points to missing source files$/;
15
+ /**
16
+ * Boot nodemon and wire its stdout/stderr to the provided handlers. Returns a
17
+ * cleanup function that detaches the listeners and quits nodemon. Shared by the
18
+ * Ink-based dev UI (via {@link useNodemon}) and the `--plain` runner.
19
+ */
20
+ export function startNodemon(env, handlers) {
21
+ const nodemon = loadNodemon();
22
+ const configFile = resolve(process.cwd(), "nodemon.json");
23
+ const config = existsSync(configFile)
24
+ ? {
25
+ configFile,
26
+ }
27
+ : {
28
+ watch: ["src"],
29
+ ext: "ts,json,md",
30
+ exec: "tsx src/index.ts",
31
+ };
32
+ nodemon({ ...config, env, stdout: false });
33
+ const handleStdoutData = (chunk) => {
34
+ handlers.onStdout(chunk);
35
+ };
36
+ const handleStderrData = (chunk) => {
37
+ const message = chunk.toString().trim();
38
+ if (!message) {
39
+ return;
40
+ }
41
+ // Node's source-map warnings for third-party deps (superjson, @mcp/sdk, …) — not actionable.
42
+ const filtered = message
43
+ .split("\n")
44
+ .filter((line) => !SOURCEMAP_WARNING.test(line))
45
+ .join("\n");
46
+ if (filtered) {
47
+ handlers.onStderr(filtered);
48
+ }
49
+ };
50
+ const setupStdoutListener = () => {
51
+ if (nodemon.stdout) {
52
+ nodemon.stdout.off("data", handleStdoutData);
53
+ nodemon.stdout.on("data", handleStdoutData);
54
+ }
55
+ };
56
+ const setupStderrListener = () => {
57
+ if (nodemon.stderr) {
58
+ nodemon.stderr.off("data", handleStderrData);
59
+ nodemon.stderr.on("data", handleStderrData);
60
+ }
61
+ };
62
+ const reattachListeners = () => {
63
+ setupStdoutListener();
64
+ setupStderrListener();
65
+ };
66
+ nodemon.on("readable", reattachListeners);
67
+ nodemon.on("crash", () => {
68
+ handlers.onCrash();
69
+ });
70
+ nodemon.on("restart", (files) => {
71
+ handlers.onRestart(files);
72
+ reattachListeners();
73
+ });
74
+ return () => {
75
+ if (nodemon.stdout) {
76
+ nodemon.stdout.off("data", handleStdoutData);
77
+ }
78
+ if (nodemon.stderr) {
79
+ nodemon.stderr.off("data", handleStderrData);
80
+ }
81
+ nodemon.emit("quit");
82
+ };
83
+ }
84
+ /**
85
+ * Boot nodemon for the Ink dev UI. Returns whether the server is currently
86
+ * down after a crash, so the UI can stop advertising a URL nothing listens on.
87
+ */
6
88
  export function useNodemon(env, pushMessage) {
7
- useEffect(() => {
8
- const configFile = resolve(process.cwd(), "nodemon.json");
9
- const config = existsSync(configFile)
10
- ? {
11
- configFile,
12
- }
13
- : {
14
- watch: ["src"],
15
- ext: "ts,json",
16
- exec: "tsx src/server.ts",
17
- };
18
- nodemon({ ...config, env, stdout: false });
19
- const handleStdoutData = (chunk) => {
89
+ const [crashed, setCrashed] = useState(false);
90
+ useEffect(() => startNodemon(env, {
91
+ onStdout: (chunk) => {
20
92
  const message = chunk.toString().trim();
21
93
  if (message) {
22
94
  pushMessage(message, "log");
23
95
  }
24
- };
25
- const handleStderrData = (chunk) => {
26
- const message = chunk.toString().trim();
27
- if (message) {
28
- pushMessage(message, "error");
29
- }
30
- };
31
- const setupStdoutListener = () => {
32
- if (nodemon.stdout) {
33
- nodemon.stdout.off("data", handleStdoutData);
34
- nodemon.stdout.on("data", handleStdoutData);
35
- }
36
- };
37
- const setupStderrListener = () => {
38
- if (nodemon.stderr) {
39
- nodemon.stderr.off("data", handleStderrData);
40
- nodemon.stderr.on("data", handleStderrData);
41
- }
42
- };
43
- nodemon.on("readable", () => {
44
- setupStdoutListener();
45
- setupStderrListener();
46
- });
47
- nodemon.on("restart", (files) => {
48
- const restartMessage = `Server restarted due to file changes: ${files.join(", ")}`;
49
- pushMessage(restartMessage, "restart");
50
- setupStdoutListener();
51
- setupStderrListener();
52
- });
53
- return () => {
54
- if (nodemon.stdout) {
55
- nodemon.stdout.off("data", handleStdoutData);
56
- }
57
- if (nodemon.stderr) {
58
- nodemon.stderr.off("data", handleStderrData);
59
- }
60
- nodemon.emit("quit");
61
- };
62
- }, [env, pushMessage]);
96
+ },
97
+ onStderr: (message) => pushMessage(message, "error"),
98
+ onRestart: (files) => {
99
+ setCrashed(false);
100
+ pushMessage(`Server restarted due to file changes: ${files.join(", ")}`, "restart");
101
+ },
102
+ onCrash: () => setCrashed(true),
103
+ }), [env, pushMessage]);
104
+ return crashed;
63
105
  }
64
106
  //# sourceMappingURL=use-nodemon.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-nodemon.js","sourceRoot":"","sources":["../../src/cli/use-nodemon.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-nodemon.js","sourceRoot":"","sources":["../../src/cli/use-nodemon.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { resolve } from \"node:path\";\nimport { useEffect, useState } from \"react\";\nimport type { ExtendedNodemon } from \"./nodemon.d.ts\";\nimport type { PushMessage } from \"./use-messages.js\";\n\nfunction loadNodemon(): ExtendedNodemon {\n try {\n return createRequire(import.meta.url)(\"nodemon\") as ExtendedNodemon;\n } catch {\n throw new Error(\n 'skybridge dev needs the \"nodemon\" peer dependency. Install it with `npm install -D nodemon`.',\n );\n }\n}\n\nexport const CRASH_MESSAGE =\n \"💥 Server crashed. Fix the error, then save a watched file to restart it.\";\n\nconst SOURCEMAP_WARNING = /^Sourcemap for \".*\" points to missing source files$/;\n\nexport interface NodemonHandlers {\n /** A raw chunk of server stdout, forwarded untouched. */\n onStdout: (chunk: Buffer) => void;\n /** A (filtered) chunk of server stderr. */\n onStderr: (message: string) => void;\n /** The server restarted because the listed files changed. */\n onRestart: (files: string[]) => void;\n /**\n * The server exited with a non-zero code. nodemon does not restart it on its\n * own: it waits for the next file change.\n */\n onCrash: () => void;\n}\n\n/**\n * Boot nodemon and wire its stdout/stderr to the provided handlers. Returns a\n * cleanup function that detaches the listeners and quits nodemon. Shared by the\n * Ink-based dev UI (via {@link useNodemon}) and the `--plain` runner.\n */\nexport function startNodemon(\n env: NodeJS.ProcessEnv,\n handlers: NodemonHandlers,\n): () => void {\n const nodemon = loadNodemon();\n const configFile = resolve(process.cwd(), \"nodemon.json\");\n\n const config = existsSync(configFile)\n ? {\n configFile,\n }\n : {\n watch: [\"src\"],\n ext: \"ts,json,md\",\n exec: \"tsx src/index.ts\",\n };\n\n nodemon({ ...config, env, stdout: false });\n\n const handleStdoutData = (chunk: Buffer) => {\n handlers.onStdout(chunk);\n };\n\n const handleStderrData = (chunk: Buffer) => {\n const message = chunk.toString().trim();\n if (!message) {\n return;\n }\n // Node's source-map warnings for third-party deps (superjson, @mcp/sdk, …) — not actionable.\n const filtered = message\n .split(\"\\n\")\n .filter((line) => !SOURCEMAP_WARNING.test(line))\n .join(\"\\n\");\n if (filtered) {\n handlers.onStderr(filtered);\n }\n };\n\n const setupStdoutListener = () => {\n if (nodemon.stdout) {\n nodemon.stdout.off(\"data\", handleStdoutData);\n nodemon.stdout.on(\"data\", handleStdoutData);\n }\n };\n\n const setupStderrListener = () => {\n if (nodemon.stderr) {\n nodemon.stderr.off(\"data\", handleStderrData);\n nodemon.stderr.on(\"data\", handleStderrData);\n }\n };\n\n const reattachListeners = () => {\n setupStdoutListener();\n setupStderrListener();\n };\n\n nodemon.on(\"readable\", reattachListeners);\n\n nodemon.on(\"crash\", () => {\n handlers.onCrash();\n });\n\n nodemon.on(\"restart\", (files: string[]) => {\n handlers.onRestart(files);\n reattachListeners();\n });\n\n return () => {\n if (nodemon.stdout) {\n nodemon.stdout.off(\"data\", handleStdoutData);\n }\n if (nodemon.stderr) {\n nodemon.stderr.off(\"data\", handleStderrData);\n }\n nodemon.emit(\"quit\");\n };\n}\n\n/**\n * Boot nodemon for the Ink dev UI. Returns whether the server is currently\n * down after a crash, so the UI can stop advertising a URL nothing listens on.\n */\nexport function useNodemon(\n env: NodeJS.ProcessEnv,\n pushMessage: PushMessage,\n): boolean {\n const [crashed, setCrashed] = useState(false);\n\n useEffect(\n () =>\n startNodemon(env, {\n onStdout: (chunk) => {\n const message = chunk.toString().trim();\n if (message) {\n pushMessage(message, \"log\");\n }\n },\n onStderr: (message) => pushMessage(message, \"error\"),\n onRestart: (files) => {\n setCrashed(false);\n pushMessage(\n `Server restarted due to file changes: ${files.join(\", \")}`,\n \"restart\",\n );\n },\n onCrash: () => setCrashed(true),\n }),\n [env, pushMessage],\n );\n\n return crashed;\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function useOpenBrowser(port: number, enabled: boolean): void;
@@ -0,0 +1,44 @@
1
+ import net from "node:net";
2
+ import open from "open";
3
+ import { useEffect, useRef } from "react";
4
+ const POLL_INTERVAL_MS = 200;
5
+ const POLL_TIMEOUT_MS = 5_000;
6
+ const isPortListening = (port) => new Promise((resolve) => {
7
+ const socket = net.createConnection({ port, host: "127.0.0.1" });
8
+ socket.once("connect", () => {
9
+ socket.end();
10
+ resolve(true);
11
+ });
12
+ socket.once("error", () => {
13
+ socket.destroy();
14
+ resolve(false);
15
+ });
16
+ });
17
+ export function useOpenBrowser(port, enabled) {
18
+ const opened = useRef(false);
19
+ useEffect(() => {
20
+ if (!enabled || opened.current) {
21
+ return;
22
+ }
23
+ let cancelled = false;
24
+ const deadline = Date.now() + POLL_TIMEOUT_MS;
25
+ const tick = async () => {
26
+ while (!cancelled && Date.now() < deadline) {
27
+ if (await isPortListening(port)) {
28
+ if (cancelled || opened.current) {
29
+ return;
30
+ }
31
+ opened.current = true;
32
+ await open(`http://localhost:${port}/`).catch(() => { });
33
+ return;
34
+ }
35
+ await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
36
+ }
37
+ };
38
+ void tick();
39
+ return () => {
40
+ cancelled = true;
41
+ };
42
+ }, [port, enabled]);
43
+ }
44
+ //# sourceMappingURL=use-open-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-open-browser.js","sourceRoot":"","sources":["../../src/cli/use-open-browser.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAC7B,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B,MAAM,eAAe,GAAG,CAAC,IAAY,EAAoB,EAAE,CACzD,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACtB,MAAM,MAAM,GAAG,GAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;QAC1B,MAAM,CAAC,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;QACxB,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,OAAgB;IAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE7B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC;QAE9C,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE;YACtB,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;gBAC3C,IAAI,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;oBAChC,IAAI,SAAS,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBAChC,OAAO;oBACT,CAAC;oBACD,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;oBACtB,MAAM,IAAI,CAAC,oBAAoB,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;oBACxD,OAAO;gBACT,CAAC;gBACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC,CAAC;QAEF,KAAK,IAAI,EAAE,CAAC;QAEZ,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AACtB,CAAC","sourcesContent":["import net from \"node:net\";\nimport open from \"open\";\nimport { useEffect, useRef } from \"react\";\n\nconst POLL_INTERVAL_MS = 200;\nconst POLL_TIMEOUT_MS = 5_000;\n\nconst isPortListening = (port: number): Promise<boolean> =>\n new Promise((resolve) => {\n const socket = net.createConnection({ port, host: \"127.0.0.1\" });\n socket.once(\"connect\", () => {\n socket.end();\n resolve(true);\n });\n socket.once(\"error\", () => {\n socket.destroy();\n resolve(false);\n });\n });\n\nexport function useOpenBrowser(port: number, enabled: boolean): void {\n const opened = useRef(false);\n\n useEffect(() => {\n if (!enabled || opened.current) {\n return;\n }\n\n let cancelled = false;\n const deadline = Date.now() + POLL_TIMEOUT_MS;\n\n const tick = async () => {\n while (!cancelled && Date.now() < deadline) {\n if (await isPortListening(port)) {\n if (cancelled || opened.current) {\n return;\n }\n opened.current = true;\n await open(`http://localhost:${port}/`).catch(() => {});\n return;\n }\n await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));\n }\n };\n\n void tick();\n\n return () => {\n cancelled = true;\n };\n }, [port, enabled]);\n}\n"]}
@@ -11,4 +11,4 @@ export type TunnelState = {
11
11
  status: "error";
12
12
  message: string;
13
13
  };
14
- export declare function useTunnel(port: number | null, pushMessage: PushMessage, verbose: boolean): TunnelState;
14
+ export declare function useTunnel(port: number | null, pushMessage: PushMessage, verbose: boolean, autoStart: boolean): TunnelState;