skybridge 0.0.0-dev.efb7a49 → 0.0.0-dev.efba8c5

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 (500) hide show
  1. package/README.md +126 -128
  2. package/dist/cli/build-helpers.d.ts +11 -0
  3. package/dist/cli/build-helpers.js +107 -0
  4. package/dist/cli/build-helpers.js.map +1 -0
  5. package/dist/cli/build-helpers.test.js +132 -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 +73 -0
  9. package/dist/cli/build-steps.js.map +1 -0
  10. package/dist/cli/build-steps.test.js +52 -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 +1 -1
  17. package/dist/cli/header.js.map +1 -1
  18. package/dist/cli/resolve-skybridge-config.d.ts +5 -0
  19. package/dist/cli/resolve-skybridge-config.js +18 -0
  20. package/dist/cli/resolve-skybridge-config.js.map +1 -0
  21. package/dist/cli/run-command.js.map +1 -1
  22. package/dist/cli/run-plain.d.ts +18 -0
  23. package/dist/cli/run-plain.js +89 -0
  24. package/dist/cli/run-plain.js.map +1 -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.d.ts +3 -0
  45. package/dist/cli/use-messages.js +11 -0
  46. package/dist/cli/use-messages.js.map +1 -0
  47. package/dist/cli/use-nodemon.d.ts +16 -2
  48. package/dist/cli/use-nodemon.js +84 -72
  49. package/dist/cli/use-nodemon.js.map +1 -1
  50. package/dist/cli/use-open-browser.d.ts +1 -0
  51. package/dist/cli/use-open-browser.js +44 -0
  52. package/dist/cli/use-open-browser.js.map +1 -0
  53. package/dist/cli/use-tunnel.d.ts +13 -7
  54. package/dist/cli/use-tunnel.js +103 -73
  55. package/dist/cli/use-tunnel.js.map +1 -1
  56. package/dist/cli/use-typescript-check.d.ts +9 -2
  57. package/dist/cli/use-typescript-check.js +89 -51
  58. package/dist/cli/use-typescript-check.js.map +1 -1
  59. package/dist/commands/build.d.ts +0 -3
  60. package/dist/commands/build.js +3 -18
  61. package/dist/commands/build.js.map +1 -1
  62. package/dist/commands/create.d.ts +9 -0
  63. package/dist/commands/create.js +30 -0
  64. package/dist/commands/create.js.map +1 -0
  65. package/dist/commands/dev.d.ts +3 -0
  66. package/dist/commands/dev.js +90 -6
  67. package/dist/commands/dev.js.map +1 -1
  68. package/dist/commands/start.js +13 -10
  69. package/dist/commands/start.js.map +1 -1
  70. package/dist/commands/telemetry/disable.js.map +1 -1
  71. package/dist/commands/telemetry/enable.js.map +1 -1
  72. package/dist/commands/telemetry/status.js.map +1 -1
  73. package/dist/context-warnings.d.ts +5 -0
  74. package/dist/context-warnings.js +31 -0
  75. package/dist/context-warnings.js.map +1 -0
  76. package/dist/context-warnings.test.js +28 -0
  77. package/dist/context-warnings.test.js.map +1 -0
  78. package/dist/server/app.d.ts +194 -0
  79. package/dist/server/app.js +266 -0
  80. package/dist/server/app.js.map +1 -0
  81. package/dist/server/app.test.d.ts +1 -0
  82. package/dist/server/app.test.js +97 -0
  83. package/dist/server/app.test.js.map +1 -0
  84. package/dist/server/asset-base-url-transform-plugin.d.ts +6 -6
  85. package/dist/server/asset-base-url-transform-plugin.js +25 -11
  86. package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
  87. package/dist/server/asset-base-url-transform-plugin.test.js +92 -14
  88. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
  89. package/dist/server/auth/discovery.d.ts +33 -0
  90. package/dist/server/auth/discovery.js +56 -0
  91. package/dist/server/auth/discovery.js.map +1 -0
  92. package/dist/server/auth/discovery.test.d.ts +1 -0
  93. package/dist/server/auth/discovery.test.js +93 -0
  94. package/dist/server/auth/discovery.test.js.map +1 -0
  95. package/dist/server/auth/index.d.ts +48 -0
  96. package/dist/server/auth/index.js +2 -0
  97. package/dist/server/auth/index.js.map +1 -0
  98. package/dist/server/auth/providers/auth0.d.ts +40 -0
  99. package/dist/server/auth/providers/auth0.js +36 -0
  100. package/dist/server/auth/providers/auth0.js.map +1 -0
  101. package/dist/server/auth/providers/auth0.test.d.ts +1 -0
  102. package/dist/server/auth/providers/auth0.test.js +50 -0
  103. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  104. package/dist/server/auth/providers/authplane.d.ts +49 -0
  105. package/dist/server/auth/providers/authplane.js +57 -0
  106. package/dist/server/auth/providers/authplane.js.map +1 -0
  107. package/dist/server/auth/providers/authplane.test.d.ts +1 -0
  108. package/dist/server/auth/providers/authplane.test.js +143 -0
  109. package/dist/server/auth/providers/authplane.test.js.map +1 -0
  110. package/dist/server/auth/providers/clerk.d.ts +51 -0
  111. package/dist/server/auth/providers/clerk.js +19 -0
  112. package/dist/server/auth/providers/clerk.js.map +1 -0
  113. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  114. package/dist/server/auth/providers/clerk.test.js +30 -0
  115. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  116. package/dist/server/auth/providers/custom.d.ts +40 -0
  117. package/dist/server/auth/providers/custom.js +59 -0
  118. package/dist/server/auth/providers/custom.js.map +1 -0
  119. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  120. package/dist/server/auth/providers/custom.test.js +161 -0
  121. package/dist/server/auth/providers/custom.test.js.map +1 -0
  122. package/dist/server/auth/providers/descope.d.ts +44 -0
  123. package/dist/server/auth/providers/descope.js +44 -0
  124. package/dist/server/auth/providers/descope.js.map +1 -0
  125. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  126. package/dist/server/auth/providers/descope.test.js +62 -0
  127. package/dist/server/auth/providers/descope.test.js.map +1 -0
  128. package/dist/server/auth/providers/shared.d.ts +2 -0
  129. package/dist/server/auth/providers/shared.js +6 -0
  130. package/dist/server/auth/providers/shared.js.map +1 -0
  131. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  132. package/dist/server/auth/providers/shared.test.js +10 -0
  133. package/dist/server/auth/providers/shared.test.js.map +1 -0
  134. package/dist/server/auth/providers/stytch.d.ts +25 -0
  135. package/dist/server/auth/providers/stytch.js +16 -0
  136. package/dist/server/auth/providers/stytch.js.map +1 -0
  137. package/dist/server/auth/providers/verify-spy.d.ts +12 -0
  138. package/dist/server/auth/providers/verify-spy.js +21 -0
  139. package/dist/server/auth/providers/verify-spy.js.map +1 -0
  140. package/dist/server/auth/providers/workos.d.ts +33 -0
  141. package/dist/server/auth/providers/workos.js +15 -0
  142. package/dist/server/auth/providers/workos.js.map +1 -0
  143. package/dist/server/auth/security-schemes.d.ts +23 -0
  144. package/dist/server/auth/security-schemes.js +64 -0
  145. package/dist/server/auth/security-schemes.js.map +1 -0
  146. package/dist/server/auth/security-schemes.test.d.ts +1 -0
  147. package/dist/server/auth/security-schemes.test.js +99 -0
  148. package/dist/server/auth/security-schemes.test.js.map +1 -0
  149. package/dist/server/auth/setup.d.ts +6 -0
  150. package/dist/server/auth/setup.js +91 -0
  151. package/dist/server/auth/setup.js.map +1 -0
  152. package/dist/server/auth/setup.test.d.ts +1 -0
  153. package/dist/server/auth/setup.test.js +514 -0
  154. package/dist/server/auth/setup.test.js.map +1 -0
  155. package/dist/server/auth/verify.d.ts +46 -0
  156. package/dist/server/auth/verify.js +62 -0
  157. package/dist/server/auth/verify.js.map +1 -0
  158. package/dist/server/auth/verify.test.d.ts +1 -0
  159. package/dist/server/auth/verify.test.js +149 -0
  160. package/dist/server/auth/verify.test.js.map +1 -0
  161. package/dist/server/auth-extra.test-d.d.ts +1 -0
  162. package/dist/server/auth-extra.test-d.js +130 -0
  163. package/dist/server/auth-extra.test-d.js.map +1 -0
  164. package/dist/server/auth.d.ts +57 -0
  165. package/dist/server/auth.js +27 -0
  166. package/dist/server/auth.js.map +1 -0
  167. package/dist/server/build-manifest.test.d.ts +1 -0
  168. package/dist/server/build-manifest.test.js +28 -0
  169. package/dist/server/build-manifest.test.js.map +1 -0
  170. package/dist/server/content-helpers.d.ts +67 -0
  171. package/dist/server/content-helpers.js +79 -0
  172. package/dist/server/content-helpers.js.map +1 -0
  173. package/dist/server/content-helpers.test.d.ts +1 -0
  174. package/dist/server/content-helpers.test.js +70 -0
  175. package/dist/server/content-helpers.test.js.map +1 -0
  176. package/dist/server/express.d.ts +23 -7
  177. package/dist/server/express.js +62 -32
  178. package/dist/server/express.js.map +1 -1
  179. package/dist/server/express.test.js +429 -73
  180. package/dist/server/express.test.js.map +1 -1
  181. package/dist/server/file-ref.d.ts +28 -0
  182. package/dist/server/file-ref.js +27 -0
  183. package/dist/server/file-ref.js.map +1 -0
  184. package/dist/server/host.d.ts +2 -0
  185. package/dist/server/host.js +11 -0
  186. package/dist/server/host.js.map +1 -0
  187. package/dist/server/host.test.d.ts +1 -0
  188. package/dist/server/host.test.js +13 -0
  189. package/dist/server/host.test.js.map +1 -0
  190. package/dist/server/index.d.ts +20 -3
  191. package/dist/server/index.js +17 -2
  192. package/dist/server/index.js.map +1 -1
  193. package/dist/server/inferUtilityTypes.d.ts +6 -6
  194. package/dist/server/inferUtilityTypes.js.map +1 -1
  195. package/dist/server/mcp-errors.test.d.ts +1 -0
  196. package/dist/server/mcp-errors.test.js +41 -0
  197. package/dist/server/mcp-errors.test.js.map +1 -0
  198. package/dist/server/metric.d.ts +14 -0
  199. package/dist/server/metric.js +62 -0
  200. package/dist/server/metric.js.map +1 -0
  201. package/dist/server/middleware.d.ts +51 -13
  202. package/dist/server/middleware.js +33 -0
  203. package/dist/server/middleware.js.map +1 -1
  204. package/dist/server/middleware.test-d.js +1 -1
  205. package/dist/server/middleware.test-d.js.map +1 -1
  206. package/dist/server/middleware.test.js +242 -131
  207. package/dist/server/middleware.test.js.map +1 -1
  208. package/dist/server/register-tool.test.d.ts +1 -0
  209. package/dist/server/register-tool.test.js +27 -0
  210. package/dist/server/register-tool.test.js.map +1 -0
  211. package/dist/server/requestOrigin.d.ts +7 -0
  212. package/dist/server/requestOrigin.js +25 -0
  213. package/dist/server/requestOrigin.js.map +1 -0
  214. package/dist/server/server.d.ts +359 -89
  215. package/dist/server/server.js +488 -230
  216. package/dist/server/server.js.map +1 -1
  217. package/dist/server/skills-integration.test.d.ts +1 -0
  218. package/dist/server/skills-integration.test.js +86 -0
  219. package/dist/server/skills-integration.test.js.map +1 -0
  220. package/dist/server/skills.d.ts +27 -0
  221. package/dist/server/skills.js +188 -0
  222. package/dist/server/skills.js.map +1 -0
  223. package/dist/server/skills.test.d.ts +1 -0
  224. package/dist/server/skills.test.js +243 -0
  225. package/dist/server/skills.test.js.map +1 -0
  226. package/dist/server/templateHelper.d.ts +2 -7
  227. package/dist/server/templateHelper.js +3 -22
  228. package/dist/server/templateHelper.js.map +1 -1
  229. package/dist/server/templates.generated.d.ts +4 -0
  230. package/dist/server/templates.generated.js +43 -0
  231. package/dist/server/templates.generated.js.map +1 -0
  232. package/dist/server/tool-extra.test.d.ts +1 -0
  233. package/dist/server/tool-extra.test.js +88 -0
  234. package/dist/server/tool-extra.test.js.map +1 -0
  235. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  236. package/dist/server/tunnel-proxy-router.js +110 -0
  237. package/dist/server/tunnel-proxy-router.js.map +1 -0
  238. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  239. package/dist/server/tunnel-proxy-router.test.js +229 -0
  240. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  241. package/dist/server/view-name.test-d.d.ts +1 -0
  242. package/dist/server/view-name.test-d.js +8 -0
  243. package/dist/server/view-name.test-d.js.map +1 -0
  244. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  245. package/dist/server/view-resource-resolution.test.js +176 -0
  246. package/dist/server/view-resource-resolution.test.js.map +1 -0
  247. package/dist/server/viewsDevServer.d.ts +14 -0
  248. package/dist/server/viewsDevServer.js +48 -0
  249. package/dist/server/viewsDevServer.js.map +1 -0
  250. package/dist/test/utils.d.ts +21 -31
  251. package/dist/test/utils.js +222 -198
  252. package/dist/test/utils.js.map +1 -1
  253. package/dist/test/view.test.d.ts +1 -0
  254. package/dist/test/view.test.js +540 -0
  255. package/dist/test/view.test.js.map +1 -0
  256. package/dist/version.d.ts +1 -0
  257. package/dist/version.js +3 -0
  258. package/dist/version.js.map +1 -0
  259. package/dist/views/index.d.ts +10 -0
  260. package/dist/views/index.js +3 -0
  261. package/dist/views/index.js.map +1 -0
  262. package/dist/views/scan-views.d.ts +16 -0
  263. package/dist/views/scan-views.js +88 -0
  264. package/dist/views/scan-views.js.map +1 -0
  265. package/dist/views/scan-views.test.d.ts +1 -0
  266. package/dist/views/scan-views.test.js +99 -0
  267. package/dist/views/scan-views.test.js.map +1 -0
  268. package/dist/views/validate-view.d.ts +1 -0
  269. package/dist/views/validate-view.js +9 -0
  270. package/dist/views/validate-view.js.map +1 -0
  271. package/dist/views/validate-view.test.d.ts +1 -0
  272. package/dist/views/validate-view.test.js +24 -0
  273. package/dist/views/validate-view.test.js.map +1 -0
  274. package/dist/web/bridges/adaptor.d.ts +51 -0
  275. package/dist/web/bridges/adaptor.js +327 -0
  276. package/dist/web/bridges/adaptor.js.map +1 -0
  277. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  278. package/dist/web/bridges/adaptor.test.js +225 -0
  279. package/dist/web/bridges/adaptor.test.js.map +1 -0
  280. package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -1
  281. package/dist/web/bridges/apps-sdk/bridge.js +15 -3
  282. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  283. package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
  284. package/dist/web/bridges/apps-sdk/index.js +0 -1
  285. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  286. package/dist/web/bridges/apps-sdk/types.d.ts +18 -6
  287. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  288. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
  289. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
  290. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  291. package/dist/web/bridges/get-adaptor.d.ts +7 -0
  292. package/dist/web/bridges/get-adaptor.js +9 -7
  293. package/dist/web/bridges/get-adaptor.js.map +1 -1
  294. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  295. package/dist/web/bridges/get-adaptor.test.js +32 -0
  296. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  297. package/dist/web/bridges/index.js.map +1 -1
  298. package/dist/web/bridges/mcp-app/bridge.d.ts +15 -2
  299. package/dist/web/bridges/mcp-app/bridge.js +73 -7
  300. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  301. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  302. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  303. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  304. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  305. package/dist/web/bridges/mcp-app/index.js +0 -1
  306. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  307. package/dist/web/bridges/mcp-app/types.d.ts +2 -0
  308. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  309. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +12 -0
  310. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +12 -0
  311. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  312. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -1
  313. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  314. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  315. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  316. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  317. package/dist/web/bridges/types.d.ts +127 -11
  318. package/dist/web/bridges/types.js +14 -1
  319. package/dist/web/bridges/types.js.map +1 -1
  320. package/dist/web/bridges/types.test.d.ts +1 -0
  321. package/dist/web/bridges/types.test.js +19 -0
  322. package/dist/web/bridges/types.test.js.map +1 -0
  323. package/dist/web/bridges/use-host-context.d.ts +5 -0
  324. package/dist/web/bridges/use-host-context.js +5 -0
  325. package/dist/web/bridges/use-host-context.js.map +1 -1
  326. package/dist/web/components/modal-provider.d.ts +1 -1
  327. package/dist/web/components/modal-provider.js +4 -3
  328. package/dist/web/components/modal-provider.js.map +1 -1
  329. package/dist/web/create-store.d.ts +26 -0
  330. package/dist/web/create-store.js +43 -3
  331. package/dist/web/create-store.js.map +1 -1
  332. package/dist/web/create-store.test.js +24 -23
  333. package/dist/web/create-store.test.js.map +1 -1
  334. package/dist/web/data-llm.d.ts +35 -2
  335. package/dist/web/data-llm.js +31 -3
  336. package/dist/web/data-llm.js.map +1 -1
  337. package/dist/web/data-llm.test.js +42 -29
  338. package/dist/web/data-llm.test.js.map +1 -1
  339. package/dist/web/generate-helpers.d.ts +39 -31
  340. package/dist/web/generate-helpers.js +36 -28
  341. package/dist/web/generate-helpers.js.map +1 -1
  342. package/dist/web/generate-helpers.test-d.js +33 -31
  343. package/dist/web/generate-helpers.test-d.js.map +1 -1
  344. package/dist/web/generate-helpers.test.js +2 -2
  345. package/dist/web/generate-helpers.test.js.map +1 -1
  346. package/dist/web/helpers/state.d.ts +2 -2
  347. package/dist/web/helpers/state.js +11 -11
  348. package/dist/web/helpers/state.js.map +1 -1
  349. package/dist/web/helpers/state.test.js +9 -9
  350. package/dist/web/helpers/state.test.js.map +1 -1
  351. package/dist/web/hooks/index.d.ts +7 -2
  352. package/dist/web/hooks/index.js +7 -2
  353. package/dist/web/hooks/index.js.map +1 -1
  354. package/dist/web/hooks/test/utils.d.ts +7 -2
  355. package/dist/web/hooks/test/utils.js +14 -3
  356. package/dist/web/hooks/test/utils.js.map +1 -1
  357. package/dist/web/hooks/use-call-tool.d.ts +45 -0
  358. package/dist/web/hooks/use-call-tool.js +28 -0
  359. package/dist/web/hooks/use-call-tool.js.map +1 -1
  360. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
  361. package/dist/web/hooks/use-call-tool.test.js +64 -29
  362. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  363. package/dist/web/hooks/use-display-mode.d.ts +20 -0
  364. package/dist/web/hooks/use-display-mode.js +20 -0
  365. package/dist/web/hooks/use-display-mode.js.map +1 -1
  366. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
  367. package/dist/web/hooks/use-display-mode.test.js +57 -21
  368. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  369. package/dist/web/hooks/use-download.d.ts +3 -0
  370. package/dist/web/hooks/use-download.js +7 -0
  371. package/dist/web/hooks/use-download.js.map +1 -0
  372. package/dist/web/hooks/use-download.test.d.ts +1 -0
  373. package/dist/web/hooks/use-download.test.js +103 -0
  374. package/dist/web/hooks/use-download.test.js.map +1 -0
  375. package/dist/web/hooks/use-files.d.ts +34 -1
  376. package/dist/web/hooks/use-files.js +33 -0
  377. package/dist/web/hooks/use-files.js.map +1 -1
  378. package/dist/web/hooks/use-files.test.js +31 -3
  379. package/dist/web/hooks/use-files.test.js.map +1 -1
  380. package/dist/web/hooks/use-host.d.ts +22 -0
  381. package/dist/web/hooks/use-host.js +30 -0
  382. package/dist/web/hooks/use-host.js.map +1 -0
  383. package/dist/web/hooks/use-host.test.d.ts +1 -0
  384. package/dist/web/hooks/use-host.test.js +59 -0
  385. package/dist/web/hooks/use-host.test.js.map +1 -0
  386. package/dist/web/hooks/use-open-external.d.ts +17 -0
  387. package/dist/web/hooks/use-open-external.js +16 -0
  388. package/dist/web/hooks/use-open-external.js.map +1 -1
  389. package/dist/web/hooks/use-open-external.test.js +15 -5
  390. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  391. package/dist/web/hooks/use-register-view-tool.d.ts +37 -0
  392. package/dist/web/hooks/use-register-view-tool.js +50 -0
  393. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  394. package/dist/web/hooks/use-request-close.d.ts +16 -0
  395. package/dist/web/hooks/use-request-close.js +21 -0
  396. package/dist/web/hooks/use-request-close.js.map +1 -0
  397. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  398. package/dist/web/hooks/use-request-close.test.js +47 -0
  399. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  400. package/dist/web/hooks/use-request-modal.d.ts +16 -1
  401. package/dist/web/hooks/use-request-modal.js +19 -4
  402. package/dist/web/hooks/use-request-modal.js.map +1 -1
  403. package/dist/web/hooks/use-request-modal.test.js +12 -2
  404. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  405. package/dist/web/hooks/use-request-size.d.ts +20 -0
  406. package/dist/web/hooks/use-request-size.js +24 -0
  407. package/dist/web/hooks/use-request-size.js.map +1 -0
  408. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  409. package/dist/web/hooks/use-request-size.test.js +47 -0
  410. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  411. package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -1
  412. package/dist/web/hooks/use-send-follow-up-message.js +19 -2
  413. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  414. package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
  415. package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
  416. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
  417. package/dist/web/hooks/use-set-open-in-app-url.test.js +26 -12
  418. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  419. package/dist/web/hooks/use-tool-info.d.ts +46 -14
  420. package/dist/web/hooks/use-tool-info.js +29 -7
  421. package/dist/web/hooks/use-tool-info.js.map +1 -1
  422. package/dist/web/hooks/use-tool-info.test-d.js +11 -34
  423. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  424. package/dist/web/hooks/use-tool-info.test.js +42 -37
  425. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  426. package/dist/web/hooks/use-user.d.ts +5 -2
  427. package/dist/web/hooks/use-user.js +6 -3
  428. package/dist/web/hooks/use-user.js.map +1 -1
  429. package/dist/web/hooks/use-user.test.js +85 -37
  430. package/dist/web/hooks/use-user.test.js.map +1 -1
  431. package/dist/web/hooks/use-view-state.d.ts +25 -0
  432. package/dist/web/hooks/use-view-state.js +42 -0
  433. package/dist/web/hooks/use-view-state.js.map +1 -0
  434. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  435. package/dist/web/hooks/use-view-state.test.js +212 -0
  436. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  437. package/dist/web/hooks/use-viewport.d.ts +20 -0
  438. package/dist/web/hooks/use-viewport.js +21 -0
  439. package/dist/web/hooks/use-viewport.js.map +1 -0
  440. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  441. package/dist/web/hooks/use-viewport.test.js +109 -0
  442. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  443. package/dist/web/index.d.ts +1 -2
  444. package/dist/web/index.js +1 -2
  445. package/dist/web/index.js.map +1 -1
  446. package/dist/web/mount-view.d.ts +21 -0
  447. package/dist/web/mount-view.js +43 -0
  448. package/dist/web/mount-view.js.map +1 -0
  449. package/dist/web/proxy.js.map +1 -1
  450. package/dist/web/types.d.ts +4 -0
  451. package/dist/web/types.js.map +1 -1
  452. package/package.json +46 -26
  453. package/tsconfig.base.json +2 -0
  454. package/dist/server/templates/development.hbs +0 -12
  455. package/dist/server/templates/production.hbs +0 -6
  456. package/dist/server/widgetsDevServer.d.ts +0 -13
  457. package/dist/server/widgetsDevServer.js +0 -57
  458. package/dist/server/widgetsDevServer.js.map +0 -1
  459. package/dist/test/widget.test.js +0 -263
  460. package/dist/test/widget.test.js.map +0 -1
  461. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -22
  462. package/dist/web/bridges/apps-sdk/adaptor.js +0 -75
  463. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  464. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -38
  465. package/dist/web/bridges/mcp-app/adaptor.js +0 -184
  466. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
  467. package/dist/web/hooks/use-layout.d.ts +0 -22
  468. package/dist/web/hooks/use-layout.js +0 -23
  469. package/dist/web/hooks/use-layout.js.map +0 -1
  470. package/dist/web/hooks/use-layout.test.js +0 -96
  471. package/dist/web/hooks/use-layout.test.js.map +0 -1
  472. package/dist/web/hooks/use-widget-state.d.ts +0 -4
  473. package/dist/web/hooks/use-widget-state.js +0 -32
  474. package/dist/web/hooks/use-widget-state.js.map +0 -1
  475. package/dist/web/hooks/use-widget-state.test.js +0 -64
  476. package/dist/web/hooks/use-widget-state.test.js.map +0 -1
  477. package/dist/web/mount-widget.d.ts +0 -1
  478. package/dist/web/mount-widget.js +0 -27
  479. package/dist/web/mount-widget.js.map +0 -1
  480. package/dist/web/plugin/data-llm.test.js +0 -81
  481. package/dist/web/plugin/data-llm.test.js.map +0 -1
  482. package/dist/web/plugin/plugin.d.ts +0 -2
  483. package/dist/web/plugin/plugin.js +0 -54
  484. package/dist/web/plugin/plugin.js.map +0 -1
  485. package/dist/web/plugin/transform-data-llm.d.ts +0 -12
  486. package/dist/web/plugin/transform-data-llm.js +0 -96
  487. package/dist/web/plugin/transform-data-llm.js.map +0 -1
  488. package/dist/web/plugin/transform-data-llm.test.js +0 -81
  489. package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
  490. package/dist/web/plugin/validate-widget.d.ts +0 -5
  491. package/dist/web/plugin/validate-widget.js +0 -27
  492. package/dist/web/plugin/validate-widget.js.map +0 -1
  493. package/dist/web/plugin/validate-widget.test.js +0 -42
  494. package/dist/web/plugin/validate-widget.test.js.map +0 -1
  495. /package/dist/{test/widget.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  496. /package/dist/{web/hooks/use-layout.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  497. /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
  498. /package/dist/{web/plugin/data-llm.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
  499. /package/dist/{web/plugin/transform-data-llm.test.d.ts → cli/tunnel.test.d.ts} +0 -0
  500. /package/dist/{web/plugin/validate-widget.test.d.ts → context-warnings.test.d.ts} +0 -0
@@ -1,12 +1,13 @@
1
1
  import http from "node:http";
2
+ import { Client, StreamableHTTPClientTransport, } from "@modelcontextprotocol/client";
2
3
  import { afterEach, describe, expect, it, vi } from "vitest";
4
+ import { Skybridge } from "./app.js";
3
5
  vi.mock("@skybridge/devtools", () => ({
4
6
  devtoolsStaticServer: () => ((_req, _res, next) => next()),
5
7
  }));
6
- vi.mock("./widgetsDevServer.js", () => ({
7
- widgetsDevServer: (_httpServer) => ((_req, _res, next) => next()),
8
+ vi.mock("./viewsDevServer.js", () => ({
9
+ viewsDevServer: (_httpServer) => ((_req, _res, next) => next()),
8
10
  }));
9
- const fakeServer = {};
10
11
  async function listen(app) {
11
12
  const server = http.createServer(app);
12
13
  await new Promise((resolve) => server.listen(0, resolve));
@@ -25,6 +26,152 @@ async function postMcp(port) {
25
26
  async function postApi(port) {
26
27
  return fetch(`http://localhost:${port}/api/test`, { method: "POST" });
27
28
  }
29
+ describe("Skybridge.express", () => {
30
+ it("exposes a ready Express app immediately after construction", () => {
31
+ const app = new Skybridge({
32
+ name: "t",
33
+ version: "0.0.0",
34
+ handler: (server) => server,
35
+ });
36
+ expect(app.express).toBeDefined();
37
+ expect(typeof app.express.use).toBe("function");
38
+ expect(typeof app.express.get).toBe("function");
39
+ });
40
+ it("app.express.get registers a route reachable alongside /mcp", async () => {
41
+ const { createApp } = await import("./express.js");
42
+ const app = new Skybridge({
43
+ name: "t",
44
+ version: "0.0.0",
45
+ handler: (server) => server,
46
+ });
47
+ app.express.get("/health", (_req, res) => {
48
+ res.json({ status: "ok" });
49
+ });
50
+ const httpServer = http.createServer();
51
+ await createApp({ app, httpServer });
52
+ const { port, server: listening } = await listen(app.express);
53
+ openServer = listening;
54
+ const health = await fetch(`http://localhost:${port}/health`);
55
+ expect(health.status).toBe(200);
56
+ expect(await health.json()).toEqual({ status: "ok" });
57
+ // /mcp still works (POST returns 200/4xx, not 404)
58
+ const mcp = await postMcp(port);
59
+ expect(mcp.status).not.toBe(404);
60
+ });
61
+ it("app.use and app.express.use produce the same registration order", async () => {
62
+ const { createApp } = await import("./express.js");
63
+ const callsA = [];
64
+ const callsB = [];
65
+ const buildApp = () => new Skybridge({
66
+ name: "t",
67
+ version: "0.0.0",
68
+ handler: (server) => server,
69
+ });
70
+ const sA = buildApp();
71
+ sA.use((_req, _res, next) => {
72
+ callsA.push("first");
73
+ next();
74
+ });
75
+ sA.express.use((_req, _res, next) => {
76
+ callsA.push("second");
77
+ next();
78
+ });
79
+ const sB = buildApp();
80
+ sB.express.use((_req, _res, next) => {
81
+ callsB.push("first");
82
+ next();
83
+ });
84
+ sB.use((_req, _res, next) => {
85
+ callsB.push("second");
86
+ next();
87
+ });
88
+ for (const s of [sA, sB]) {
89
+ s.express.get("/probe", (_req, res) => res.json({ ok: true }));
90
+ const httpServer = http.createServer();
91
+ await createApp({ app: s, httpServer });
92
+ const { port, server: listening } = await listen(s.express);
93
+ openServer = listening;
94
+ await fetch(`http://localhost:${port}/probe`);
95
+ listening.close();
96
+ }
97
+ expect(callsA).toEqual(["first", "second"]);
98
+ expect(callsB).toEqual(["first", "second"]);
99
+ });
100
+ it("useOnError still wraps thrown /mcp errors after the route is mounted", async () => {
101
+ const { createApp } = await import("./express.js");
102
+ const app = new Skybridge({
103
+ name: "t",
104
+ version: "0.0.0",
105
+ handler: (server) => server,
106
+ });
107
+ // Register the error handler BEFORE createApp — useOnError should still
108
+ // apply it after /mcp, so /mcp errors hit it.
109
+ const seen = [];
110
+ app.useOnError((_err, _req, res, _next) => {
111
+ seen.push("useOnError");
112
+ res.status(503).json({ from: "useOnError" });
113
+ });
114
+ // Force the /mcp handler to throw so the error pipeline runs.
115
+ app.use("/mcp", () => {
116
+ throw new Error("boom");
117
+ });
118
+ const httpServer = http.createServer();
119
+ await createApp({
120
+ app,
121
+ httpServer,
122
+ // Mirror what run() does: forward the app's useOnError handlers
123
+ // to createApp so they get applied after /mcp.
124
+ // biome-ignore lint/complexity/useLiteralKeys: test mirrors run() internals to verify useOnError ordering
125
+ errorMiddleware: app["errorMiddleware"],
126
+ });
127
+ const { port, server: listening } = await listen(app.express);
128
+ openServer = listening;
129
+ const res = await postMcp(port);
130
+ expect(seen).toEqual(["useOnError"]);
131
+ expect(res.status).toBe(503);
132
+ expect(await res.json()).toEqual({ from: "useOnError" });
133
+ });
134
+ });
135
+ describe("Skybridge JSON body parser options", () => {
136
+ const largeBody = JSON.stringify({ data: "x".repeat(200 * 1024) });
137
+ async function postEcho(port, body) {
138
+ return fetch(`http://localhost:${port}/echo`, {
139
+ method: "POST",
140
+ headers: { "Content-Type": "application/json" },
141
+ body,
142
+ });
143
+ }
144
+ it("forwards json options to express.json", async () => {
145
+ const app = new Skybridge({
146
+ name: "t",
147
+ version: "0.0.0",
148
+ json: { limit: "10mb" },
149
+ handler: (server) => server,
150
+ });
151
+ app.express.post("/echo", (req, res) => {
152
+ res.json({ received: req.body.data.length });
153
+ });
154
+ const { port, server: listening } = await listen(app.express);
155
+ openServer = listening;
156
+ const res = await postEcho(port, largeBody);
157
+ expect(res.status).toBe(200);
158
+ expect(await res.json()).toEqual({ received: 200 * 1024 });
159
+ });
160
+ it("keeps the default 100kb limit when no options are passed", async () => {
161
+ const app = new Skybridge({
162
+ name: "t",
163
+ version: "0.0.0",
164
+ handler: (server) => server,
165
+ });
166
+ app.express.post("/echo", (_req, res) => {
167
+ res.json({ ok: true });
168
+ });
169
+ const { port, server: listening } = await listen(app.express);
170
+ openServer = listening;
171
+ const res = await postEcho(port, largeBody);
172
+ expect(res.status).toBe(413);
173
+ });
174
+ });
28
175
  describe("createApp", () => {
29
176
  it("runs global custom middleware before the /mcp handler", async () => {
30
177
  const { createApp } = await import("./express.js");
@@ -33,14 +180,16 @@ describe("createApp", () => {
33
180
  calls.push("custom");
34
181
  next();
35
182
  };
36
- const httpServer = http.createServer();
37
- const app = await createApp({
38
- mcpServer: fakeServer,
39
- httpServer,
40
- customMiddleware: [{ handlers: [mw] }],
183
+ const app = new Skybridge({
184
+ name: "t",
185
+ version: "0.0.0",
186
+ handler: (server) => server,
41
187
  });
42
- const { port, server } = await listen(app);
43
- openServer = server;
188
+ app.use(mw);
189
+ const httpServer = http.createServer();
190
+ const expressApp = await createApp({ app, httpServer });
191
+ const { port, server: httpListening } = await listen(expressApp);
192
+ openServer = httpListening;
44
193
  await postMcp(port);
45
194
  expect(calls).toEqual(["custom"]);
46
195
  });
@@ -51,14 +200,16 @@ describe("createApp", () => {
51
200
  calls.push("auth");
52
201
  next();
53
202
  };
54
- const httpServer = http.createServer();
55
- const app = await createApp({
56
- mcpServer: fakeServer,
57
- httpServer,
58
- customMiddleware: [{ path: "/mcp", handlers: [mw] }],
203
+ const app = new Skybridge({
204
+ name: "t",
205
+ version: "0.0.0",
206
+ handler: (server) => server,
59
207
  });
60
- const { port, server } = await listen(app);
61
- openServer = server;
208
+ app.use("/mcp", mw);
209
+ const httpServer = http.createServer();
210
+ const expressApp = await createApp({ app, httpServer });
211
+ const { port, server: httpListening } = await listen(expressApp);
212
+ openServer = httpListening;
62
213
  await postMcp(port);
63
214
  expect(calls).toEqual(["auth"]);
64
215
  });
@@ -69,14 +220,16 @@ describe("createApp", () => {
69
220
  calls.push("reject");
70
221
  res.status(401).json({ error: "Unauthorized" });
71
222
  };
72
- const httpServer = http.createServer();
73
- const app = await createApp({
74
- mcpServer: fakeServer,
75
- httpServer,
76
- customMiddleware: [{ path: "/mcp", handlers: [reject] }],
223
+ const app = new Skybridge({
224
+ name: "t",
225
+ version: "0.0.0",
226
+ handler: (server) => server,
77
227
  });
78
- const { port, server } = await listen(app);
79
- openServer = server;
228
+ app.use("/mcp", reject);
229
+ const httpServer = http.createServer();
230
+ const expressApp = await createApp({ app, httpServer });
231
+ const { port, server: httpListening } = await listen(expressApp);
232
+ openServer = httpListening;
80
233
  const res = await postMcp(port);
81
234
  expect(calls).toEqual(["reject"]);
82
235
  expect(res.status).toBe(401);
@@ -93,14 +246,17 @@ describe("createApp", () => {
93
246
  calls.push("B");
94
247
  next();
95
248
  };
96
- const httpServer = http.createServer();
97
- const app = await createApp({
98
- mcpServer: fakeServer,
99
- httpServer,
100
- customMiddleware: [{ handlers: [mwA] }, { handlers: [mwB] }],
249
+ const app = new Skybridge({
250
+ name: "t",
251
+ version: "0.0.0",
252
+ handler: (server) => server,
101
253
  });
102
- const { port, server } = await listen(app);
103
- openServer = server;
254
+ app.use(mwA);
255
+ app.use(mwB);
256
+ const httpServer = http.createServer();
257
+ const expressApp = await createApp({ app, httpServer });
258
+ const { port, server: httpListening } = await listen(expressApp);
259
+ openServer = httpListening;
104
260
  await postMcp(port);
105
261
  expect(calls).toEqual(["A", "B"]);
106
262
  });
@@ -111,14 +267,16 @@ describe("createApp", () => {
111
267
  calls.push("api");
112
268
  next();
113
269
  };
114
- const httpServer = http.createServer();
115
- const app = await createApp({
116
- mcpServer: fakeServer,
117
- httpServer,
118
- customMiddleware: [{ path: "/api", handlers: [apiMw] }],
270
+ const app = new Skybridge({
271
+ name: "t",
272
+ version: "0.0.0",
273
+ handler: (server) => server,
119
274
  });
120
- const { port, server } = await listen(app);
121
- openServer = server;
275
+ app.use("/api", apiMw);
276
+ const httpServer = http.createServer();
277
+ const expressApp = await createApp({ app, httpServer });
278
+ const { port, server: httpListening } = await listen(expressApp);
279
+ openServer = httpListening;
122
280
  // Hit /mcp — the /api middleware should NOT fire
123
281
  await postMcp(port);
124
282
  expect(calls).toEqual([]);
@@ -130,14 +288,16 @@ describe("createApp", () => {
130
288
  router.get("/health", (_req, res) => {
131
289
  res.json({ status: "ok" });
132
290
  });
133
- const httpServer = http.createServer();
134
- const app = await createApp({
135
- mcpServer: fakeServer,
136
- httpServer,
137
- customMiddleware: [{ handlers: [router] }],
291
+ const app = new Skybridge({
292
+ name: "t",
293
+ version: "0.0.0",
294
+ handler: (server) => server,
138
295
  });
139
- const { port, server } = await listen(app);
140
- openServer = server;
296
+ app.use(router);
297
+ const httpServer = http.createServer();
298
+ const expressApp = await createApp({ app, httpServer });
299
+ const { port, server: httpListening } = await listen(expressApp);
300
+ openServer = httpListening;
141
301
  const res = await fetch(`http://localhost:${port}/health`);
142
302
  expect(res.status).toBe(200);
143
303
  expect(await res.json()).toEqual({ status: "ok" });
@@ -149,16 +309,16 @@ describe("createApp", () => {
149
309
  router.get("/data", (_req, res) => {
150
310
  res.json({ value: 42 });
151
311
  });
152
- const httpServer = http.createServer();
153
- const app = await createApp({
154
- mcpServer: fakeServer,
155
- httpServer,
156
- customMiddleware: [
157
- { path: "/api", handlers: [router] },
158
- ],
312
+ const app = new Skybridge({
313
+ name: "t",
314
+ version: "0.0.0",
315
+ handler: (server) => server,
159
316
  });
160
- const { port, server } = await listen(app);
161
- openServer = server;
317
+ app.use("/api", router);
318
+ const httpServer = http.createServer();
319
+ const expressApp = await createApp({ app, httpServer });
320
+ const { port, server: httpListening } = await listen(expressApp);
321
+ openServer = httpListening;
162
322
  const res = await fetch(`http://localhost:${port}/api/data`);
163
323
  expect(res.status).toBe(200);
164
324
  expect(await res.json()).toEqual({ value: 42 });
@@ -168,14 +328,16 @@ describe("createApp", () => {
168
328
  const throwing = () => {
169
329
  throw new Error("boom");
170
330
  };
171
- const httpServer = http.createServer();
172
- const app = await createApp({
173
- mcpServer: fakeServer,
174
- httpServer,
175
- customMiddleware: [{ path: "/explode", handlers: [throwing] }],
331
+ const app = new Skybridge({
332
+ name: "t",
333
+ version: "0.0.0",
334
+ handler: (server) => server,
176
335
  });
177
- const { port, server } = await listen(app);
178
- openServer = server;
336
+ app.use("/explode", throwing);
337
+ const httpServer = http.createServer();
338
+ const expressApp = await createApp({ app, httpServer });
339
+ const { port, server: httpListening } = await listen(expressApp);
340
+ openServer = httpListening;
179
341
  const res = await fetch(`http://localhost:${port}/explode`);
180
342
  expect(res.status).toBe(500);
181
343
  // Server process did not crash — it still accepts connections
@@ -185,10 +347,20 @@ describe("createApp", () => {
185
347
  it("returns 500 JSON-RPC error when the MCP handler throws and no error middleware is registered", async () => {
186
348
  const { createApp } = await import("./express.js");
187
349
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
350
+ const app = new Skybridge({
351
+ name: "t",
352
+ version: "0.0.0",
353
+ handler: (server) => server,
354
+ });
355
+ // Force the express-level error path: make a /mcp middleware throw so the
356
+ // error pipeline runs and lands in the default /mcp error handler.
357
+ app.use("/mcp", () => {
358
+ throw new Error("boom");
359
+ });
188
360
  const httpServer = http.createServer();
189
- const app = await createApp({ mcpServer: fakeServer, httpServer });
190
- const { port, server } = await listen(app);
191
- openServer = server;
361
+ const expressApp = await createApp({ app, httpServer });
362
+ const { port, server: httpListening } = await listen(expressApp);
363
+ openServer = httpListening;
192
364
  const res = await postMcp(port);
193
365
  expect(res.status).toBe(500);
194
366
  expect(await res.json()).toEqual({
@@ -206,14 +378,22 @@ describe("createApp", () => {
206
378
  calls.push("error-handler");
207
379
  res.status(503).json({ custom: true });
208
380
  };
381
+ const app = new Skybridge({
382
+ name: "t",
383
+ version: "0.0.0",
384
+ handler: (server) => server,
385
+ });
386
+ app.use("/mcp", () => {
387
+ throw new Error("boom");
388
+ });
209
389
  const httpServer = http.createServer();
210
- const app = await createApp({
211
- mcpServer: fakeServer,
390
+ const expressApp = await createApp({
391
+ app,
212
392
  httpServer,
213
393
  errorMiddleware: [{ handlers: [errorHandler] }],
214
394
  });
215
- const { port, server } = await listen(app);
216
- openServer = server;
395
+ const { port, server: httpListening } = await listen(expressApp);
396
+ openServer = httpListening;
217
397
  const res = await postMcp(port);
218
398
  expect(calls).toEqual(["error-handler"]);
219
399
  expect(res.status).toBe(503);
@@ -229,15 +409,23 @@ describe("createApp", () => {
229
409
  const throwingApiRoute = (_req, _res, next) => {
230
410
  next(new Error("api error"));
231
411
  };
412
+ const app = new Skybridge({
413
+ name: "t",
414
+ version: "0.0.0",
415
+ handler: (server) => server,
416
+ });
417
+ app.use("/mcp", () => {
418
+ throw new Error("boom");
419
+ });
420
+ app.use("/api/test", throwingApiRoute);
232
421
  const httpServer = http.createServer();
233
- const app = await createApp({
234
- mcpServer: fakeServer,
422
+ const expressApp = await createApp({
423
+ app,
235
424
  httpServer,
236
- customMiddleware: [{ path: "/api/test", handlers: [throwingApiRoute] }],
237
425
  errorMiddleware: [{ path: "/mcp", handlers: [mcpErrorHandler] }],
238
426
  });
239
- const { port, server } = await listen(app);
240
- openServer = server;
427
+ const { port, server: httpListening } = await listen(expressApp);
428
+ openServer = httpListening;
241
429
  const mcpRes = await postMcp(port);
242
430
  expect(calls).toEqual(["mcp-error-handler"]);
243
431
  expect(mcpRes.status).toBe(503);
@@ -248,5 +436,173 @@ describe("createApp", () => {
248
436
  expect(apiRes.status).toBe(500);
249
437
  consoleSpy.mockRestore();
250
438
  });
439
+ it("handles concurrent /mcp requests without 'Already connected to a transport'", async () => {
440
+ const { createApp } = await import("./express.js");
441
+ // Slow tool: keeps the underlying transport bound long enough to overlap
442
+ // with concurrent requests, exposing the shared-McpServer race.
443
+ const app = new Skybridge({
444
+ name: "concurrent-test",
445
+ version: "0.0.0",
446
+ handler: (server) => server.registerTool({ name: "slow", description: "slow" }, async () => {
447
+ await new Promise((r) => setTimeout(r, 50));
448
+ return { content: [{ type: "text", text: "done" }] };
449
+ }),
450
+ });
451
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
452
+ const httpServer = http.createServer();
453
+ const expressApp = await createApp({ app, httpServer });
454
+ const { port, server } = await listen(expressApp);
455
+ openServer = server;
456
+ const callBody = (id) => JSON.stringify({
457
+ jsonrpc: "2.0",
458
+ method: "tools/call",
459
+ id,
460
+ params: { name: "slow", arguments: {} },
461
+ });
462
+ const N = 10;
463
+ const responses = await Promise.all(Array.from({ length: N }, (_, i) => fetch(`http://localhost:${port}/mcp`, {
464
+ method: "POST",
465
+ headers: {
466
+ "Content-Type": "application/json",
467
+ Accept: "application/json, text/event-stream",
468
+ },
469
+ body: callBody(i + 1),
470
+ })));
471
+ expect(responses.map((r) => r.status)).toEqual(Array(N).fill(200));
472
+ expect(consoleSpy).not.toHaveBeenCalledWith("Error handling MCP request:", expect.any(Error));
473
+ consoleSpy.mockRestore();
474
+ });
475
+ });
476
+ describe("createApp Vercel mode", () => {
477
+ it("app.run() returns the Express app without binding a port when VERCEL=1", async () => {
478
+ const prevVercel = process.env.VERCEL;
479
+ const prevEnv = process.env.NODE_ENV;
480
+ process.env.VERCEL = "1";
481
+ process.env.NODE_ENV = "production";
482
+ try {
483
+ vi.resetModules();
484
+ const { Skybridge: Reloaded } = await import("./app.js");
485
+ const app = new Reloaded({
486
+ name: "t",
487
+ version: "0.0.0",
488
+ handler: (server) => server,
489
+ });
490
+ const result = await app.run();
491
+ expect(typeof result).toBe("function");
492
+ expect(result).toBe(app.express);
493
+ const { port, server: listening } = await listen(app.express);
494
+ openServer = listening;
495
+ const res = await postMcp(port);
496
+ expect(res.status).not.toBe(404);
497
+ }
498
+ finally {
499
+ if (prevVercel === undefined) {
500
+ delete process.env.VERCEL;
501
+ }
502
+ else {
503
+ process.env.VERCEL = prevVercel;
504
+ }
505
+ process.env.NODE_ENV = prevEnv;
506
+ vi.resetModules();
507
+ }
508
+ });
509
+ });
510
+ describe("createApp tunnel routes", () => {
511
+ it("proxies POST /__skybridge/tunnel to the cli control server in dev mode", async () => {
512
+ // Stand up a fake control listener that returns a known JSON body.
513
+ const control = http.createServer((_req, res) => {
514
+ res.writeHead(200, { "Content-Type": "application/json" });
515
+ res.end('{"status":"idle"}');
516
+ });
517
+ await new Promise((resolve) => control.listen(0, "127.0.0.1", resolve));
518
+ const controlAddr = control.address();
519
+ if (typeof controlAddr === "string" || controlAddr === null) {
520
+ control.close();
521
+ throw new Error("control server has no address");
522
+ }
523
+ const controlPort = controlAddr.port;
524
+ const prev = process.env.__TUNNEL_CONTROL_PORT;
525
+ process.env.__TUNNEL_CONTROL_PORT = String(controlPort);
526
+ try {
527
+ const { createApp } = await import("./express.js");
528
+ const app = new Skybridge({
529
+ name: "t",
530
+ version: "0.0.0",
531
+ handler: (server) => server,
532
+ });
533
+ const httpServer = http.createServer();
534
+ const expressApp = await createApp({ app, httpServer });
535
+ const { port, server } = await listen(expressApp);
536
+ openServer = server;
537
+ const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
538
+ method: "POST",
539
+ });
540
+ expect(res.status).toBe(200);
541
+ expect(await res.json()).toEqual({ status: "idle" });
542
+ }
543
+ finally {
544
+ if (prev === undefined) {
545
+ delete process.env.__TUNNEL_CONTROL_PORT;
546
+ }
547
+ else {
548
+ process.env.__TUNNEL_CONTROL_PORT = prev;
549
+ }
550
+ await new Promise((resolve) => control.close(() => resolve()));
551
+ }
552
+ });
553
+ it("does not expose /__skybridge/tunnel in production mode", async () => {
554
+ const prevEnv = process.env.NODE_ENV;
555
+ process.env.NODE_ENV = "production";
556
+ try {
557
+ vi.resetModules();
558
+ const { createApp } = await import("./express.js");
559
+ const { Skybridge: ReloadedSkybridge } = await import("./app.js");
560
+ const app = new ReloadedSkybridge({
561
+ name: "t",
562
+ version: "0.0.0",
563
+ handler: (server) => server,
564
+ });
565
+ const httpServer = http.createServer();
566
+ const expressApp = await createApp({ app, httpServer });
567
+ const { port, server } = await listen(expressApp);
568
+ openServer = server;
569
+ const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
570
+ method: "POST",
571
+ });
572
+ expect(res.status).toBe(404);
573
+ }
574
+ finally {
575
+ process.env.NODE_ENV = prevEnv;
576
+ vi.resetModules();
577
+ }
578
+ });
579
+ });
580
+ describe("createApp mount path", () => {
581
+ it("serves /mcp with the mount path intact on the request URL", async () => {
582
+ const { createApp } = await import("./express.js");
583
+ const app = new Skybridge({
584
+ name: "t",
585
+ version: "0.0.0",
586
+ handler: (server) => server.registerTool({
587
+ name: "echo-url",
588
+ description: "Echoes the request URL.",
589
+ inputSchema: {},
590
+ }, (_args, extra) => ({
591
+ content: [{ type: "text", text: extra.http?.req?.url ?? "" }],
592
+ })),
593
+ });
594
+ const httpServer = http.createServer();
595
+ const expressApp = await createApp({ app, httpServer });
596
+ const { port, server } = await listen(expressApp);
597
+ openServer = server;
598
+ const client = new Client({ name: "test-client", version: "0.0.0" });
599
+ await client.connect(new StreamableHTTPClientTransport(new URL(`http://localhost:${port}/mcp`)));
600
+ const result = (await client.callTool({
601
+ name: "echo-url",
602
+ arguments: {},
603
+ }));
604
+ await client.close();
605
+ expect(new URL(result.content[0]?.text ?? "").pathname).toBe("/mcp");
606
+ });
251
607
  });
252
608
  //# sourceMappingURL=express.test.js.map