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
@@ -1,13 +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";
3
- import { McpServer } from "./server.js";
4
+ import { Skybridge } from "./app.js";
4
5
  vi.mock("@skybridge/devtools", () => ({
5
6
  devtoolsStaticServer: () => ((_req, _res, next) => next()),
6
7
  }));
7
8
  vi.mock("./viewsDevServer.js", () => ({
8
9
  viewsDevServer: (_httpServer) => ((_req, _res, next) => next()),
9
10
  }));
10
- const fakeServer = {};
11
11
  async function listen(app) {
12
12
  const server = http.createServer(app);
13
13
  await new Promise((resolve) => server.listen(0, resolve));
@@ -26,6 +26,153 @@ async function postMcp(port) {
26
26
  async function postApi(port) {
27
27
  return fetch(`http://localhost:${port}/api/test`, { method: "POST" });
28
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(health.headers.get("x-powered-by")).toBe("skybridge");
57
+ expect(await health.json()).toEqual({ status: "ok" });
58
+ // /mcp still works (POST returns 200/4xx, not 404)
59
+ const mcp = await postMcp(port);
60
+ expect(mcp.status).not.toBe(404);
61
+ });
62
+ it("app.use and app.express.use produce the same registration order", async () => {
63
+ const { createApp } = await import("./express.js");
64
+ const callsA = [];
65
+ const callsB = [];
66
+ const buildApp = () => new Skybridge({
67
+ name: "t",
68
+ version: "0.0.0",
69
+ handler: (server) => server,
70
+ });
71
+ const sA = buildApp();
72
+ sA.use((_req, _res, next) => {
73
+ callsA.push("first");
74
+ next();
75
+ });
76
+ sA.express.use((_req, _res, next) => {
77
+ callsA.push("second");
78
+ next();
79
+ });
80
+ const sB = buildApp();
81
+ sB.express.use((_req, _res, next) => {
82
+ callsB.push("first");
83
+ next();
84
+ });
85
+ sB.use((_req, _res, next) => {
86
+ callsB.push("second");
87
+ next();
88
+ });
89
+ for (const s of [sA, sB]) {
90
+ s.express.get("/probe", (_req, res) => res.json({ ok: true }));
91
+ const httpServer = http.createServer();
92
+ await createApp({ app: s, httpServer });
93
+ const { port, server: listening } = await listen(s.express);
94
+ openServer = listening;
95
+ await fetch(`http://localhost:${port}/probe`);
96
+ listening.close();
97
+ }
98
+ expect(callsA).toEqual(["first", "second"]);
99
+ expect(callsB).toEqual(["first", "second"]);
100
+ });
101
+ it("useOnError still wraps thrown /mcp errors after the route is mounted", async () => {
102
+ const { createApp } = await import("./express.js");
103
+ const app = new Skybridge({
104
+ name: "t",
105
+ version: "0.0.0",
106
+ handler: (server) => server,
107
+ });
108
+ // Register the error handler BEFORE createApp — useOnError should still
109
+ // apply it after /mcp, so /mcp errors hit it.
110
+ const seen = [];
111
+ app.useOnError((_err, _req, res, _next) => {
112
+ seen.push("useOnError");
113
+ res.status(503).json({ from: "useOnError" });
114
+ });
115
+ // Force the /mcp handler to throw so the error pipeline runs.
116
+ app.use("/mcp", () => {
117
+ throw new Error("boom");
118
+ });
119
+ const httpServer = http.createServer();
120
+ await createApp({
121
+ app,
122
+ httpServer,
123
+ // Mirror what run() does: forward the app's useOnError handlers
124
+ // to createApp so they get applied after /mcp.
125
+ // biome-ignore lint/complexity/useLiteralKeys: test mirrors run() internals to verify useOnError ordering
126
+ errorMiddleware: app["errorMiddleware"],
127
+ });
128
+ const { port, server: listening } = await listen(app.express);
129
+ openServer = listening;
130
+ const res = await postMcp(port);
131
+ expect(seen).toEqual(["useOnError"]);
132
+ expect(res.status).toBe(503);
133
+ expect(await res.json()).toEqual({ from: "useOnError" });
134
+ });
135
+ });
136
+ describe("Skybridge JSON body parser options", () => {
137
+ const largeBody = JSON.stringify({ data: "x".repeat(200 * 1024) });
138
+ async function postEcho(port, body) {
139
+ return fetch(`http://localhost:${port}/echo`, {
140
+ method: "POST",
141
+ headers: { "Content-Type": "application/json" },
142
+ body,
143
+ });
144
+ }
145
+ it("forwards json options to express.json", async () => {
146
+ const app = new Skybridge({
147
+ name: "t",
148
+ version: "0.0.0",
149
+ json: { limit: "10mb" },
150
+ handler: (server) => server,
151
+ });
152
+ app.express.post("/echo", (req, res) => {
153
+ res.json({ received: req.body.data.length });
154
+ });
155
+ const { port, server: listening } = await listen(app.express);
156
+ openServer = listening;
157
+ const res = await postEcho(port, largeBody);
158
+ expect(res.status).toBe(200);
159
+ expect(await res.json()).toEqual({ received: 200 * 1024 });
160
+ });
161
+ it("keeps the default 100kb limit when no options are passed", async () => {
162
+ const app = new Skybridge({
163
+ name: "t",
164
+ version: "0.0.0",
165
+ handler: (server) => server,
166
+ });
167
+ app.express.post("/echo", (_req, res) => {
168
+ res.json({ ok: true });
169
+ });
170
+ const { port, server: listening } = await listen(app.express);
171
+ openServer = listening;
172
+ const res = await postEcho(port, largeBody);
173
+ expect(res.status).toBe(413);
174
+ });
175
+ });
29
176
  describe("createApp", () => {
30
177
  it("runs global custom middleware before the /mcp handler", async () => {
31
178
  const { createApp } = await import("./express.js");
@@ -34,14 +181,16 @@ describe("createApp", () => {
34
181
  calls.push("custom");
35
182
  next();
36
183
  };
37
- const httpServer = http.createServer();
38
- const app = await createApp({
39
- mcpServer: fakeServer,
40
- httpServer,
41
- customMiddleware: [{ handlers: [mw] }],
184
+ const app = new Skybridge({
185
+ name: "t",
186
+ version: "0.0.0",
187
+ handler: (server) => server,
42
188
  });
43
- const { port, server } = await listen(app);
44
- openServer = server;
189
+ app.use(mw);
190
+ const httpServer = http.createServer();
191
+ const expressApp = await createApp({ app, httpServer });
192
+ const { port, server: httpListening } = await listen(expressApp);
193
+ openServer = httpListening;
45
194
  await postMcp(port);
46
195
  expect(calls).toEqual(["custom"]);
47
196
  });
@@ -52,14 +201,16 @@ describe("createApp", () => {
52
201
  calls.push("auth");
53
202
  next();
54
203
  };
55
- const httpServer = http.createServer();
56
- const app = await createApp({
57
- mcpServer: fakeServer,
58
- httpServer,
59
- customMiddleware: [{ path: "/mcp", handlers: [mw] }],
204
+ const app = new Skybridge({
205
+ name: "t",
206
+ version: "0.0.0",
207
+ handler: (server) => server,
60
208
  });
61
- const { port, server } = await listen(app);
62
- openServer = server;
209
+ app.use("/mcp", mw);
210
+ const httpServer = http.createServer();
211
+ const expressApp = await createApp({ app, httpServer });
212
+ const { port, server: httpListening } = await listen(expressApp);
213
+ openServer = httpListening;
63
214
  await postMcp(port);
64
215
  expect(calls).toEqual(["auth"]);
65
216
  });
@@ -70,14 +221,16 @@ describe("createApp", () => {
70
221
  calls.push("reject");
71
222
  res.status(401).json({ error: "Unauthorized" });
72
223
  };
73
- const httpServer = http.createServer();
74
- const app = await createApp({
75
- mcpServer: fakeServer,
76
- httpServer,
77
- customMiddleware: [{ path: "/mcp", handlers: [reject] }],
224
+ const app = new Skybridge({
225
+ name: "t",
226
+ version: "0.0.0",
227
+ handler: (server) => server,
78
228
  });
79
- const { port, server } = await listen(app);
80
- openServer = server;
229
+ app.use("/mcp", reject);
230
+ const httpServer = http.createServer();
231
+ const expressApp = await createApp({ app, httpServer });
232
+ const { port, server: httpListening } = await listen(expressApp);
233
+ openServer = httpListening;
81
234
  const res = await postMcp(port);
82
235
  expect(calls).toEqual(["reject"]);
83
236
  expect(res.status).toBe(401);
@@ -94,14 +247,17 @@ describe("createApp", () => {
94
247
  calls.push("B");
95
248
  next();
96
249
  };
97
- const httpServer = http.createServer();
98
- const app = await createApp({
99
- mcpServer: fakeServer,
100
- httpServer,
101
- customMiddleware: [{ handlers: [mwA] }, { handlers: [mwB] }],
250
+ const app = new Skybridge({
251
+ name: "t",
252
+ version: "0.0.0",
253
+ handler: (server) => server,
102
254
  });
103
- const { port, server } = await listen(app);
104
- openServer = server;
255
+ app.use(mwA);
256
+ app.use(mwB);
257
+ const httpServer = http.createServer();
258
+ const expressApp = await createApp({ app, httpServer });
259
+ const { port, server: httpListening } = await listen(expressApp);
260
+ openServer = httpListening;
105
261
  await postMcp(port);
106
262
  expect(calls).toEqual(["A", "B"]);
107
263
  });
@@ -112,14 +268,16 @@ describe("createApp", () => {
112
268
  calls.push("api");
113
269
  next();
114
270
  };
115
- const httpServer = http.createServer();
116
- const app = await createApp({
117
- mcpServer: fakeServer,
118
- httpServer,
119
- customMiddleware: [{ path: "/api", handlers: [apiMw] }],
271
+ const app = new Skybridge({
272
+ name: "t",
273
+ version: "0.0.0",
274
+ handler: (server) => server,
120
275
  });
121
- const { port, server } = await listen(app);
122
- openServer = server;
276
+ app.use("/api", apiMw);
277
+ const httpServer = http.createServer();
278
+ const expressApp = await createApp({ app, httpServer });
279
+ const { port, server: httpListening } = await listen(expressApp);
280
+ openServer = httpListening;
123
281
  // Hit /mcp — the /api middleware should NOT fire
124
282
  await postMcp(port);
125
283
  expect(calls).toEqual([]);
@@ -131,14 +289,16 @@ describe("createApp", () => {
131
289
  router.get("/health", (_req, res) => {
132
290
  res.json({ status: "ok" });
133
291
  });
134
- const httpServer = http.createServer();
135
- const app = await createApp({
136
- mcpServer: fakeServer,
137
- httpServer,
138
- customMiddleware: [{ handlers: [router] }],
292
+ const app = new Skybridge({
293
+ name: "t",
294
+ version: "0.0.0",
295
+ handler: (server) => server,
139
296
  });
140
- const { port, server } = await listen(app);
141
- openServer = server;
297
+ app.use(router);
298
+ const httpServer = http.createServer();
299
+ const expressApp = await createApp({ app, httpServer });
300
+ const { port, server: httpListening } = await listen(expressApp);
301
+ openServer = httpListening;
142
302
  const res = await fetch(`http://localhost:${port}/health`);
143
303
  expect(res.status).toBe(200);
144
304
  expect(await res.json()).toEqual({ status: "ok" });
@@ -150,16 +310,16 @@ describe("createApp", () => {
150
310
  router.get("/data", (_req, res) => {
151
311
  res.json({ value: 42 });
152
312
  });
153
- const httpServer = http.createServer();
154
- const app = await createApp({
155
- mcpServer: fakeServer,
156
- httpServer,
157
- customMiddleware: [
158
- { path: "/api", handlers: [router] },
159
- ],
313
+ const app = new Skybridge({
314
+ name: "t",
315
+ version: "0.0.0",
316
+ handler: (server) => server,
160
317
  });
161
- const { port, server } = await listen(app);
162
- openServer = server;
318
+ app.use("/api", router);
319
+ const httpServer = http.createServer();
320
+ const expressApp = await createApp({ app, httpServer });
321
+ const { port, server: httpListening } = await listen(expressApp);
322
+ openServer = httpListening;
163
323
  const res = await fetch(`http://localhost:${port}/api/data`);
164
324
  expect(res.status).toBe(200);
165
325
  expect(await res.json()).toEqual({ value: 42 });
@@ -169,14 +329,16 @@ describe("createApp", () => {
169
329
  const throwing = () => {
170
330
  throw new Error("boom");
171
331
  };
172
- const httpServer = http.createServer();
173
- const app = await createApp({
174
- mcpServer: fakeServer,
175
- httpServer,
176
- customMiddleware: [{ path: "/explode", handlers: [throwing] }],
332
+ const app = new Skybridge({
333
+ name: "t",
334
+ version: "0.0.0",
335
+ handler: (server) => server,
177
336
  });
178
- const { port, server } = await listen(app);
179
- openServer = server;
337
+ app.use("/explode", throwing);
338
+ const httpServer = http.createServer();
339
+ const expressApp = await createApp({ app, httpServer });
340
+ const { port, server: httpListening } = await listen(expressApp);
341
+ openServer = httpListening;
180
342
  const res = await fetch(`http://localhost:${port}/explode`);
181
343
  expect(res.status).toBe(500);
182
344
  // Server process did not crash — it still accepts connections
@@ -186,10 +348,20 @@ describe("createApp", () => {
186
348
  it("returns 500 JSON-RPC error when the MCP handler throws and no error middleware is registered", async () => {
187
349
  const { createApp } = await import("./express.js");
188
350
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
351
+ const app = new Skybridge({
352
+ name: "t",
353
+ version: "0.0.0",
354
+ handler: (server) => server,
355
+ });
356
+ // Force the express-level error path: make a /mcp middleware throw so the
357
+ // error pipeline runs and lands in the default /mcp error handler.
358
+ app.use("/mcp", () => {
359
+ throw new Error("boom");
360
+ });
189
361
  const httpServer = http.createServer();
190
- const app = await createApp({ mcpServer: fakeServer, httpServer });
191
- const { port, server } = await listen(app);
192
- openServer = server;
362
+ const expressApp = await createApp({ app, httpServer });
363
+ const { port, server: httpListening } = await listen(expressApp);
364
+ openServer = httpListening;
193
365
  const res = await postMcp(port);
194
366
  expect(res.status).toBe(500);
195
367
  expect(await res.json()).toEqual({
@@ -207,14 +379,22 @@ describe("createApp", () => {
207
379
  calls.push("error-handler");
208
380
  res.status(503).json({ custom: true });
209
381
  };
382
+ const app = new Skybridge({
383
+ name: "t",
384
+ version: "0.0.0",
385
+ handler: (server) => server,
386
+ });
387
+ app.use("/mcp", () => {
388
+ throw new Error("boom");
389
+ });
210
390
  const httpServer = http.createServer();
211
- const app = await createApp({
212
- mcpServer: fakeServer,
391
+ const expressApp = await createApp({
392
+ app,
213
393
  httpServer,
214
394
  errorMiddleware: [{ handlers: [errorHandler] }],
215
395
  });
216
- const { port, server } = await listen(app);
217
- openServer = server;
396
+ const { port, server: httpListening } = await listen(expressApp);
397
+ openServer = httpListening;
218
398
  const res = await postMcp(port);
219
399
  expect(calls).toEqual(["error-handler"]);
220
400
  expect(res.status).toBe(503);
@@ -230,15 +410,23 @@ describe("createApp", () => {
230
410
  const throwingApiRoute = (_req, _res, next) => {
231
411
  next(new Error("api error"));
232
412
  };
413
+ const app = new Skybridge({
414
+ name: "t",
415
+ version: "0.0.0",
416
+ handler: (server) => server,
417
+ });
418
+ app.use("/mcp", () => {
419
+ throw new Error("boom");
420
+ });
421
+ app.use("/api/test", throwingApiRoute);
233
422
  const httpServer = http.createServer();
234
- const app = await createApp({
235
- mcpServer: fakeServer,
423
+ const expressApp = await createApp({
424
+ app,
236
425
  httpServer,
237
- customMiddleware: [{ path: "/api/test", handlers: [throwingApiRoute] }],
238
426
  errorMiddleware: [{ path: "/mcp", handlers: [mcpErrorHandler] }],
239
427
  });
240
- const { port, server } = await listen(app);
241
- openServer = server;
428
+ const { port, server: httpListening } = await listen(expressApp);
429
+ openServer = httpListening;
242
430
  const mcpRes = await postMcp(port);
243
431
  expect(calls).toEqual(["mcp-error-handler"]);
244
432
  expect(mcpRes.status).toBe(503);
@@ -251,20 +439,20 @@ describe("createApp", () => {
251
439
  });
252
440
  it("handles concurrent /mcp requests without 'Already connected to a transport'", async () => {
253
441
  const { createApp } = await import("./express.js");
254
- const mcpServer = new McpServer({
255
- name: "concurrent-test",
256
- version: "0.0.0",
257
- });
258
442
  // Slow tool: keeps the underlying transport bound long enough to overlap
259
443
  // with concurrent requests, exposing the shared-McpServer race.
260
- mcpServer.registerTool({ name: "slow", description: "slow" }, async () => {
261
- await new Promise((r) => setTimeout(r, 50));
262
- return { content: [{ type: "text", text: "done" }] };
444
+ const app = new Skybridge({
445
+ name: "concurrent-test",
446
+ version: "0.0.0",
447
+ handler: (server) => server.registerTool({ name: "slow", description: "slow" }, async () => {
448
+ await new Promise((r) => setTimeout(r, 50));
449
+ return { content: [{ type: "text", text: "done" }] };
450
+ }),
263
451
  });
264
452
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
265
453
  const httpServer = http.createServer();
266
- const app = await createApp({ mcpServer, httpServer });
267
- const { port, server } = await listen(app);
454
+ const expressApp = await createApp({ app, httpServer });
455
+ const { port, server } = await listen(expressApp);
268
456
  openServer = server;
269
457
  const callBody = (id) => JSON.stringify({
270
458
  jsonrpc: "2.0",
@@ -286,4 +474,180 @@ describe("createApp", () => {
286
474
  consoleSpy.mockRestore();
287
475
  });
288
476
  });
477
+ describe("createApp Vercel mode", () => {
478
+ it("app.run() returns the Express app without binding a port when VERCEL=1", async () => {
479
+ const prevVercel = process.env.VERCEL;
480
+ const prevEnv = process.env.NODE_ENV;
481
+ process.env.VERCEL = "1";
482
+ process.env.NODE_ENV = "production";
483
+ try {
484
+ vi.resetModules();
485
+ const { Skybridge: Reloaded } = await import("./app.js");
486
+ const app = new Reloaded({
487
+ name: "t",
488
+ version: "0.0.0",
489
+ handler: (server) => server,
490
+ });
491
+ const result = await app.run();
492
+ expect(typeof result).toBe("function");
493
+ expect(result).toBe(app.express);
494
+ const { port, server: listening } = await listen(app.express);
495
+ openServer = listening;
496
+ const res = await postMcp(port);
497
+ expect(res.status).not.toBe(404);
498
+ }
499
+ finally {
500
+ if (prevVercel === undefined) {
501
+ delete process.env.VERCEL;
502
+ }
503
+ else {
504
+ process.env.VERCEL = prevVercel;
505
+ }
506
+ process.env.NODE_ENV = prevEnv;
507
+ vi.resetModules();
508
+ }
509
+ });
510
+ it("passes onMcpError to the /mcp handler when VERCEL=1", async () => {
511
+ const prevVercel = process.env.VERCEL;
512
+ const prevEnv = process.env.NODE_ENV;
513
+ process.env.VERCEL = "1";
514
+ process.env.NODE_ENV = "production";
515
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
516
+ try {
517
+ vi.resetModules();
518
+ const { Skybridge: Reloaded } = await import("./app.js");
519
+ const onMcpError = vi.fn();
520
+ const app = new Reloaded({
521
+ name: "t",
522
+ version: "0.0.0",
523
+ onMcpError,
524
+ handler: (server) => server,
525
+ });
526
+ await app.run();
527
+ const { port, server: listening } = await listen(app.express);
528
+ openServer = listening;
529
+ const res = await fetch(`http://localhost:${port}/mcp`, {
530
+ method: "POST",
531
+ headers: {
532
+ "content-type": "application/json",
533
+ accept: "application/json, text/event-stream",
534
+ "mcp-protocol-version": "client-supplied-text",
535
+ },
536
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "tools/list" }),
537
+ });
538
+ expect(res.status).toBe(400);
539
+ expect(onMcpError).toHaveBeenCalledTimes(1);
540
+ expect(consoleSpy).not.toHaveBeenCalled();
541
+ }
542
+ finally {
543
+ consoleSpy.mockRestore();
544
+ if (prevVercel === undefined) {
545
+ delete process.env.VERCEL;
546
+ }
547
+ else {
548
+ process.env.VERCEL = prevVercel;
549
+ }
550
+ process.env.NODE_ENV = prevEnv;
551
+ vi.resetModules();
552
+ }
553
+ });
554
+ });
555
+ describe("createApp tunnel routes", () => {
556
+ it("proxies POST /__skybridge/tunnel to the cli control server in dev mode", async () => {
557
+ // Stand up a fake control listener that returns a known JSON body.
558
+ const control = http.createServer((_req, res) => {
559
+ res.writeHead(200, { "Content-Type": "application/json" });
560
+ res.end('{"status":"idle"}');
561
+ });
562
+ await new Promise((resolve) => control.listen(0, "127.0.0.1", resolve));
563
+ const controlAddr = control.address();
564
+ if (typeof controlAddr === "string" || controlAddr === null) {
565
+ control.close();
566
+ throw new Error("control server has no address");
567
+ }
568
+ const controlPort = controlAddr.port;
569
+ const prev = process.env.__TUNNEL_CONTROL_PORT;
570
+ process.env.__TUNNEL_CONTROL_PORT = String(controlPort);
571
+ try {
572
+ const { createApp } = await import("./express.js");
573
+ const app = new Skybridge({
574
+ name: "t",
575
+ version: "0.0.0",
576
+ handler: (server) => server,
577
+ });
578
+ const httpServer = http.createServer();
579
+ const expressApp = await createApp({ app, httpServer });
580
+ const { port, server } = await listen(expressApp);
581
+ openServer = server;
582
+ const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
583
+ method: "POST",
584
+ });
585
+ expect(res.status).toBe(200);
586
+ expect(await res.json()).toEqual({ status: "idle" });
587
+ }
588
+ finally {
589
+ if (prev === undefined) {
590
+ delete process.env.__TUNNEL_CONTROL_PORT;
591
+ }
592
+ else {
593
+ process.env.__TUNNEL_CONTROL_PORT = prev;
594
+ }
595
+ await new Promise((resolve) => control.close(() => resolve()));
596
+ }
597
+ });
598
+ it("does not expose /__skybridge/tunnel in production mode", async () => {
599
+ const prevEnv = process.env.NODE_ENV;
600
+ process.env.NODE_ENV = "production";
601
+ try {
602
+ vi.resetModules();
603
+ const { createApp } = await import("./express.js");
604
+ const { Skybridge: ReloadedSkybridge } = await import("./app.js");
605
+ const app = new ReloadedSkybridge({
606
+ name: "t",
607
+ version: "0.0.0",
608
+ handler: (server) => server,
609
+ });
610
+ const httpServer = http.createServer();
611
+ const expressApp = await createApp({ app, httpServer });
612
+ const { port, server } = await listen(expressApp);
613
+ openServer = server;
614
+ const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
615
+ method: "POST",
616
+ });
617
+ expect(res.status).toBe(404);
618
+ }
619
+ finally {
620
+ process.env.NODE_ENV = prevEnv;
621
+ vi.resetModules();
622
+ }
623
+ });
624
+ });
625
+ describe("createApp mount path", () => {
626
+ it("serves /mcp with the mount path intact on the request URL", async () => {
627
+ const { createApp } = await import("./express.js");
628
+ const app = new Skybridge({
629
+ name: "t",
630
+ version: "0.0.0",
631
+ handler: (server) => server.registerTool({
632
+ name: "echo-url",
633
+ description: "Echoes the request URL.",
634
+ inputSchema: {},
635
+ }, (_args, extra) => ({
636
+ content: [{ type: "text", text: extra.http?.req?.url ?? "" }],
637
+ })),
638
+ });
639
+ const httpServer = http.createServer();
640
+ const expressApp = await createApp({ app, httpServer });
641
+ const { port, server } = await listen(expressApp);
642
+ openServer = server;
643
+ const client = new Client({ name: "test-client", version: "0.0.0" });
644
+ await client.connect(new StreamableHTTPClientTransport(new URL(`http://localhost:${port}/mcp`)));
645
+ const result = (await client.callTool({
646
+ name: "echo-url",
647
+ arguments: {},
648
+ }));
649
+ await client.close();
650
+ expect(new URL(result.content[0]?.text ?? "").pathname).toBe("/mcp");
651
+ });
652
+ });
289
653
  //# sourceMappingURL=express.test.js.map