skybridge 0.0.0-dev.ee5d59f → 0.0.0-dev.ee6593a

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 (422) hide show
  1. package/README.md +124 -124
  2. package/dist/cli/build-helpers.d.ts +11 -0
  3. package/dist/cli/build-helpers.js +102 -0
  4. package/dist/cli/build-helpers.js.map +1 -0
  5. package/dist/cli/build-helpers.test.js +119 -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 +9 -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-views-dir.d.ts +1 -0
  18. package/dist/cli/resolve-views-dir.js +17 -0
  19. package/dist/cli/resolve-views-dir.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 +89 -0
  23. package/dist/cli/run-plain.js.map +1 -0
  24. package/dist/cli/telemetry.js.map +1 -1
  25. package/dist/cli/tunnel-control-server.d.ts +9 -0
  26. package/dist/cli/tunnel-control-server.js +31 -0
  27. package/dist/cli/tunnel-control-server.js.map +1 -0
  28. package/dist/cli/tunnel-control-server.test.js +39 -0
  29. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  30. package/dist/cli/tunnel-handler.d.ts +3 -0
  31. package/dist/cli/tunnel-handler.js +48 -0
  32. package/dist/cli/tunnel-handler.js.map +1 -0
  33. package/dist/cli/tunnel-handler.test.d.ts +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.d.ts +1 -0
  40. package/dist/cli/tunnel.test.js +190 -0
  41. package/dist/cli/tunnel.test.js.map +1 -0
  42. package/dist/cli/types.js.map +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 +14 -0
  46. package/dist/cli/use-nodemon.js +72 -52
  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 +89 -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 +3 -18
  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 +81 -2
  65. package/dist/commands/dev.js.map +1 -1
  66. package/dist/commands/start.js +8 -7
  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/server/asset-base-url-transform-plugin.d.ts +1 -0
  72. package/dist/server/asset-base-url-transform-plugin.js +17 -2
  73. package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
  74. package/dist/server/asset-base-url-transform-plugin.test.js +80 -1
  75. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
  76. package/dist/server/auth/discovery.d.ts +32 -0
  77. package/dist/server/auth/discovery.js +56 -0
  78. package/dist/server/auth/discovery.js.map +1 -0
  79. package/dist/server/auth/discovery.test.d.ts +1 -0
  80. package/dist/server/auth/discovery.test.js +93 -0
  81. package/dist/server/auth/discovery.test.js.map +1 -0
  82. package/dist/server/auth/index.d.ts +18 -0
  83. package/dist/server/auth/index.js +2 -0
  84. package/dist/server/auth/index.js.map +1 -0
  85. package/dist/server/auth/providers/auth0.d.ts +18 -0
  86. package/dist/server/auth/providers/auth0.js +31 -0
  87. package/dist/server/auth/providers/auth0.js.map +1 -0
  88. package/dist/server/auth/providers/auth0.test.d.ts +1 -0
  89. package/dist/server/auth/providers/auth0.test.js +48 -0
  90. package/dist/server/auth/providers/auth0.test.js.map +1 -0
  91. package/dist/server/auth/providers/clerk.d.ts +14 -0
  92. package/dist/server/auth/providers/clerk.js +16 -0
  93. package/dist/server/auth/providers/clerk.js.map +1 -0
  94. package/dist/server/auth/providers/clerk.test.d.ts +1 -0
  95. package/dist/server/auth/providers/clerk.test.js +28 -0
  96. package/dist/server/auth/providers/clerk.test.js.map +1 -0
  97. package/dist/server/auth/providers/custom.d.ts +30 -0
  98. package/dist/server/auth/providers/custom.js +40 -0
  99. package/dist/server/auth/providers/custom.js.map +1 -0
  100. package/dist/server/auth/providers/custom.test.d.ts +1 -0
  101. package/dist/server/auth/providers/custom.test.js +128 -0
  102. package/dist/server/auth/providers/custom.test.js.map +1 -0
  103. package/dist/server/auth/providers/descope.d.ts +15 -0
  104. package/dist/server/auth/providers/descope.js +35 -0
  105. package/dist/server/auth/providers/descope.js.map +1 -0
  106. package/dist/server/auth/providers/descope.test.d.ts +1 -0
  107. package/dist/server/auth/providers/descope.test.js +39 -0
  108. package/dist/server/auth/providers/descope.test.js.map +1 -0
  109. package/dist/server/auth/providers/shared.d.ts +2 -0
  110. package/dist/server/auth/providers/shared.js +6 -0
  111. package/dist/server/auth/providers/shared.js.map +1 -0
  112. package/dist/server/auth/providers/shared.test.d.ts +1 -0
  113. package/dist/server/auth/providers/shared.test.js +10 -0
  114. package/dist/server/auth/providers/shared.test.js.map +1 -0
  115. package/dist/server/auth/providers/stytch.d.ts +12 -0
  116. package/dist/server/auth/providers/stytch.js +13 -0
  117. package/dist/server/auth/providers/stytch.js.map +1 -0
  118. package/dist/server/auth/providers/workos.d.ts +11 -0
  119. package/dist/server/auth/providers/workos.js +12 -0
  120. package/dist/server/auth/providers/workos.js.map +1 -0
  121. package/dist/server/auth/setup.d.ts +4 -0
  122. package/dist/server/auth/setup.js +51 -0
  123. package/dist/server/auth/setup.js.map +1 -0
  124. package/dist/server/auth/setup.test.d.ts +1 -0
  125. package/dist/server/auth/setup.test.js +185 -0
  126. package/dist/server/auth/setup.test.js.map +1 -0
  127. package/dist/server/auth/verify.d.ts +12 -0
  128. package/dist/server/auth/verify.js +38 -0
  129. package/dist/server/auth/verify.js.map +1 -0
  130. package/dist/server/auth/verify.test.d.ts +1 -0
  131. package/dist/server/auth/verify.test.js +100 -0
  132. package/dist/server/auth/verify.test.js.map +1 -0
  133. package/dist/server/auth.d.ts +20 -0
  134. package/dist/server/auth.js +28 -0
  135. package/dist/server/auth.js.map +1 -0
  136. package/dist/server/build-manifest.test.d.ts +1 -0
  137. package/dist/server/build-manifest.test.js +27 -0
  138. package/dist/server/build-manifest.test.js.map +1 -0
  139. package/dist/server/content-helpers.d.ts +67 -0
  140. package/dist/server/content-helpers.js +79 -0
  141. package/dist/server/content-helpers.js.map +1 -0
  142. package/dist/server/content-helpers.test.d.ts +1 -0
  143. package/dist/server/content-helpers.test.js +70 -0
  144. package/dist/server/content-helpers.test.js.map +1 -0
  145. package/dist/server/express.d.ts +1 -5
  146. package/dist/server/express.js +34 -10
  147. package/dist/server/express.js.map +1 -1
  148. package/dist/server/express.test.js +310 -71
  149. package/dist/server/express.test.js.map +1 -1
  150. package/dist/server/file-ref.d.ts +28 -0
  151. package/dist/server/file-ref.js +27 -0
  152. package/dist/server/file-ref.js.map +1 -0
  153. package/dist/server/index.d.ts +14 -3
  154. package/dist/server/index.js +12 -2
  155. package/dist/server/index.js.map +1 -1
  156. package/dist/server/inferUtilityTypes.d.ts +6 -6
  157. package/dist/server/inferUtilityTypes.js.map +1 -1
  158. package/dist/server/metric.js.map +1 -1
  159. package/dist/server/middleware.d.ts +16 -3
  160. package/dist/server/middleware.js.map +1 -1
  161. package/dist/server/middleware.test-d.js.map +1 -1
  162. package/dist/server/middleware.test.js +12 -9
  163. package/dist/server/middleware.test.js.map +1 -1
  164. package/dist/server/requestOrigin.d.ts +7 -0
  165. package/dist/server/requestOrigin.js +25 -0
  166. package/dist/server/requestOrigin.js.map +1 -0
  167. package/dist/server/server.d.ts +349 -72
  168. package/dist/server/server.js +538 -174
  169. package/dist/server/server.js.map +1 -1
  170. package/dist/server/skills-integration.test.d.ts +1 -0
  171. package/dist/server/skills-integration.test.js +63 -0
  172. package/dist/server/skills-integration.test.js.map +1 -0
  173. package/dist/server/skills.d.ts +23 -0
  174. package/dist/server/skills.js +178 -0
  175. package/dist/server/skills.js.map +1 -0
  176. package/dist/server/skills.test.d.ts +1 -0
  177. package/dist/server/skills.test.js +210 -0
  178. package/dist/server/skills.test.js.map +1 -0
  179. package/dist/server/templateHelper.d.ts +5 -7
  180. package/dist/server/templateHelper.js +3 -22
  181. package/dist/server/templateHelper.js.map +1 -1
  182. package/dist/server/templates.generated.d.ts +4 -0
  183. package/dist/server/templates.generated.js +47 -0
  184. package/dist/server/templates.generated.js.map +1 -0
  185. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  186. package/dist/server/tunnel-proxy-router.js +110 -0
  187. package/dist/server/tunnel-proxy-router.js.map +1 -0
  188. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  189. package/dist/server/tunnel-proxy-router.test.js +229 -0
  190. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  191. package/dist/server/view-name.test-d.d.ts +1 -0
  192. package/dist/server/view-name.test-d.js +8 -0
  193. package/dist/server/view-name.test-d.js.map +1 -0
  194. package/dist/server/view-resource-resolution.test.d.ts +6 -0
  195. package/dist/server/view-resource-resolution.test.js +171 -0
  196. package/dist/server/view-resource-resolution.test.js.map +1 -0
  197. package/dist/server/viewsDevServer.d.ts +14 -0
  198. package/dist/server/viewsDevServer.js +45 -0
  199. package/dist/server/viewsDevServer.js.map +1 -0
  200. package/dist/test/utils.d.ts +8 -20
  201. package/dist/test/utils.js +39 -35
  202. package/dist/test/utils.js.map +1 -1
  203. package/dist/test/view.test.d.ts +1 -0
  204. package/dist/test/view.test.js +536 -0
  205. package/dist/test/view.test.js.map +1 -0
  206. package/dist/version.js +1 -3
  207. package/dist/version.js.map +1 -1
  208. package/dist/web/bridges/adaptor.d.ts +51 -0
  209. package/dist/web/bridges/adaptor.js +330 -0
  210. package/dist/web/bridges/adaptor.js.map +1 -0
  211. package/dist/web/bridges/adaptor.test.d.ts +1 -0
  212. package/dist/web/bridges/adaptor.test.js +208 -0
  213. package/dist/web/bridges/adaptor.test.js.map +1 -0
  214. package/dist/web/bridges/apps-sdk/bridge.d.ts +6 -1
  215. package/dist/web/bridges/apps-sdk/bridge.js +15 -3
  216. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  217. package/dist/web/bridges/apps-sdk/index.d.ts +0 -1
  218. package/dist/web/bridges/apps-sdk/index.js +0 -1
  219. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  220. package/dist/web/bridges/apps-sdk/types.d.ts +8 -1
  221. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  222. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +11 -0
  223. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +11 -0
  224. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  225. package/dist/web/bridges/get-adaptor.d.ts +7 -0
  226. package/dist/web/bridges/get-adaptor.js +9 -7
  227. package/dist/web/bridges/get-adaptor.js.map +1 -1
  228. package/dist/web/bridges/get-adaptor.test.d.ts +1 -0
  229. package/dist/web/bridges/get-adaptor.test.js +32 -0
  230. package/dist/web/bridges/get-adaptor.test.js.map +1 -0
  231. package/dist/web/bridges/index.js.map +1 -1
  232. package/dist/web/bridges/mcp-app/bridge.d.ts +15 -2
  233. package/dist/web/bridges/mcp-app/bridge.js +68 -4
  234. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  235. package/dist/web/bridges/mcp-app/bridge.test.d.ts +1 -0
  236. package/dist/web/bridges/mcp-app/bridge.test.js +17 -0
  237. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -0
  238. package/dist/web/bridges/mcp-app/index.d.ts +0 -1
  239. package/dist/web/bridges/mcp-app/index.js +0 -1
  240. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  241. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  242. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +12 -0
  243. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +12 -0
  244. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  245. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  246. package/dist/web/bridges/mcp-app/view-tools.test.d.ts +1 -0
  247. package/dist/web/bridges/mcp-app/view-tools.test.js +143 -0
  248. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -0
  249. package/dist/web/bridges/types.d.ts +115 -10
  250. package/dist/web/bridges/types.js +14 -1
  251. package/dist/web/bridges/types.js.map +1 -1
  252. package/dist/web/bridges/types.test.d.ts +1 -0
  253. package/dist/web/bridges/types.test.js +19 -0
  254. package/dist/web/bridges/types.test.js.map +1 -0
  255. package/dist/web/bridges/use-host-context.d.ts +5 -0
  256. package/dist/web/bridges/use-host-context.js +5 -0
  257. package/dist/web/bridges/use-host-context.js.map +1 -1
  258. package/dist/web/components/modal-provider.d.ts +1 -1
  259. package/dist/web/components/modal-provider.js +4 -3
  260. package/dist/web/components/modal-provider.js.map +1 -1
  261. package/dist/web/create-store.d.ts +26 -0
  262. package/dist/web/create-store.js +35 -9
  263. package/dist/web/create-store.js.map +1 -1
  264. package/dist/web/create-store.test.js +22 -21
  265. package/dist/web/create-store.test.js.map +1 -1
  266. package/dist/web/data-llm.d.ts +35 -2
  267. package/dist/web/data-llm.js +31 -3
  268. package/dist/web/data-llm.js.map +1 -1
  269. package/dist/web/data-llm.test.js +39 -27
  270. package/dist/web/data-llm.test.js.map +1 -1
  271. package/dist/web/generate-helpers.d.ts +22 -18
  272. package/dist/web/generate-helpers.js +22 -18
  273. package/dist/web/generate-helpers.js.map +1 -1
  274. package/dist/web/generate-helpers.test-d.js +30 -28
  275. package/dist/web/generate-helpers.test-d.js.map +1 -1
  276. package/dist/web/generate-helpers.test.js.map +1 -1
  277. package/dist/web/helpers/state.d.ts +2 -2
  278. package/dist/web/helpers/state.js +11 -11
  279. package/dist/web/helpers/state.js.map +1 -1
  280. package/dist/web/helpers/state.test.js +9 -9
  281. package/dist/web/helpers/state.test.js.map +1 -1
  282. package/dist/web/hooks/index.d.ts +5 -1
  283. package/dist/web/hooks/index.js +5 -1
  284. package/dist/web/hooks/index.js.map +1 -1
  285. package/dist/web/hooks/test/utils.d.ts +6 -2
  286. package/dist/web/hooks/test/utils.js +13 -2
  287. package/dist/web/hooks/test/utils.js.map +1 -1
  288. package/dist/web/hooks/use-call-tool.d.ts +45 -0
  289. package/dist/web/hooks/use-call-tool.js +28 -0
  290. package/dist/web/hooks/use-call-tool.js.map +1 -1
  291. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
  292. package/dist/web/hooks/use-call-tool.test.js +62 -27
  293. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  294. package/dist/web/hooks/use-display-mode.d.ts +20 -0
  295. package/dist/web/hooks/use-display-mode.js +20 -0
  296. package/dist/web/hooks/use-display-mode.js.map +1 -1
  297. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
  298. package/dist/web/hooks/use-display-mode.test.js +56 -20
  299. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  300. package/dist/web/hooks/use-download.d.ts +5 -0
  301. package/dist/web/hooks/use-download.js +8 -0
  302. package/dist/web/hooks/use-download.js.map +1 -0
  303. package/dist/web/hooks/use-download.test.d.ts +1 -0
  304. package/dist/web/hooks/use-download.test.js +103 -0
  305. package/dist/web/hooks/use-download.test.js.map +1 -0
  306. package/dist/web/hooks/use-files.d.ts +32 -0
  307. package/dist/web/hooks/use-files.js +32 -0
  308. package/dist/web/hooks/use-files.js.map +1 -1
  309. package/dist/web/hooks/use-files.test.js +10 -2
  310. package/dist/web/hooks/use-files.test.js.map +1 -1
  311. package/dist/web/hooks/use-layout.d.ts +2 -0
  312. package/dist/web/hooks/use-layout.js +2 -0
  313. package/dist/web/hooks/use-layout.js.map +1 -1
  314. package/dist/web/hooks/use-layout.test.js +59 -26
  315. package/dist/web/hooks/use-layout.test.js.map +1 -1
  316. package/dist/web/hooks/use-open-external.d.ts +17 -0
  317. package/dist/web/hooks/use-open-external.js +16 -0
  318. package/dist/web/hooks/use-open-external.js.map +1 -1
  319. package/dist/web/hooks/use-open-external.test.js +13 -3
  320. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  321. package/dist/web/hooks/use-register-view-tool.d.ts +38 -0
  322. package/dist/web/hooks/use-register-view-tool.js +50 -0
  323. package/dist/web/hooks/use-register-view-tool.js.map +1 -0
  324. package/dist/web/hooks/use-request-close.d.ts +16 -0
  325. package/dist/web/hooks/use-request-close.js +21 -0
  326. package/dist/web/hooks/use-request-close.js.map +1 -0
  327. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  328. package/dist/web/hooks/use-request-close.test.js +47 -0
  329. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  330. package/dist/web/hooks/use-request-modal.d.ts +16 -1
  331. package/dist/web/hooks/use-request-modal.js +19 -4
  332. package/dist/web/hooks/use-request-modal.js.map +1 -1
  333. package/dist/web/hooks/use-request-modal.test.js +11 -1
  334. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  335. package/dist/web/hooks/use-request-size.d.ts +20 -0
  336. package/dist/web/hooks/use-request-size.js +24 -0
  337. package/dist/web/hooks/use-request-size.js.map +1 -0
  338. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  339. package/dist/web/hooks/use-request-size.test.js +47 -0
  340. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  341. package/dist/web/hooks/use-send-follow-up-message.d.ts +19 -1
  342. package/dist/web/hooks/use-send-follow-up-message.js +19 -2
  343. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  344. package/dist/web/hooks/use-set-open-in-app-url.d.ts +17 -0
  345. package/dist/web/hooks/use-set-open-in-app-url.js +17 -0
  346. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
  347. package/dist/web/hooks/use-set-open-in-app-url.test.js +28 -8
  348. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  349. package/dist/web/hooks/use-tool-info.d.ts +53 -2
  350. package/dist/web/hooks/use-tool-info.js +30 -7
  351. package/dist/web/hooks/use-tool-info.js.map +1 -1
  352. package/dist/web/hooks/use-tool-info.test-d.js +11 -29
  353. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  354. package/dist/web/hooks/use-tool-info.test.js +42 -32
  355. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  356. package/dist/web/hooks/use-user.d.ts +2 -0
  357. package/dist/web/hooks/use-user.js +2 -0
  358. package/dist/web/hooks/use-user.js.map +1 -1
  359. package/dist/web/hooks/use-user.test.js +81 -35
  360. package/dist/web/hooks/use-user.test.js.map +1 -1
  361. package/dist/web/hooks/use-view-state.d.ts +25 -0
  362. package/dist/web/hooks/use-view-state.js +32 -0
  363. package/dist/web/hooks/use-view-state.js.map +1 -0
  364. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  365. package/dist/web/hooks/{use-widget-state.test.js → use-view-state.test.js} +23 -19
  366. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  367. package/dist/web/index.d.ts +1 -2
  368. package/dist/web/index.js +1 -2
  369. package/dist/web/index.js.map +1 -1
  370. package/dist/web/mount-view.d.ts +20 -0
  371. package/dist/web/{mount-widget.js → mount-view.js} +21 -2
  372. package/dist/web/mount-view.js.map +1 -0
  373. package/dist/web/plugin/data-llm.test.js.map +1 -1
  374. package/dist/web/plugin/plugin.d.ts +32 -1
  375. package/dist/web/plugin/plugin.js +159 -25
  376. package/dist/web/plugin/plugin.js.map +1 -1
  377. package/dist/web/plugin/scan-views.d.ts +16 -0
  378. package/dist/web/plugin/scan-views.js +88 -0
  379. package/dist/web/plugin/scan-views.js.map +1 -0
  380. package/dist/web/plugin/scan-views.test.d.ts +1 -0
  381. package/dist/web/plugin/scan-views.test.js +99 -0
  382. package/dist/web/plugin/scan-views.test.js.map +1 -0
  383. package/dist/web/plugin/transform-data-llm.js.map +1 -1
  384. package/dist/web/plugin/transform-data-llm.test.js.map +1 -1
  385. package/dist/web/plugin/validate-view.d.ts +1 -0
  386. package/dist/web/plugin/validate-view.js +9 -0
  387. package/dist/web/plugin/validate-view.js.map +1 -0
  388. package/dist/web/plugin/validate-view.test.d.ts +1 -0
  389. package/dist/web/plugin/validate-view.test.js +24 -0
  390. package/dist/web/plugin/validate-view.test.js.map +1 -0
  391. package/dist/web/proxy.js.map +1 -1
  392. package/dist/web/types.d.ts +4 -0
  393. package/dist/web/types.js.map +1 -1
  394. package/package.json +39 -22
  395. package/tsconfig.base.json +2 -0
  396. package/dist/server/templates/development.hbs +0 -12
  397. package/dist/server/templates/production.hbs +0 -6
  398. package/dist/server/widgetsDevServer.d.ts +0 -13
  399. package/dist/server/widgetsDevServer.js +0 -52
  400. package/dist/server/widgetsDevServer.js.map +0 -1
  401. package/dist/test/widget.test.js +0 -334
  402. package/dist/test/widget.test.js.map +0 -1
  403. package/dist/web/bridges/apps-sdk/adaptor.d.ts +0 -24
  404. package/dist/web/bridges/apps-sdk/adaptor.js +0 -87
  405. package/dist/web/bridges/apps-sdk/adaptor.js.map +0 -1
  406. package/dist/web/bridges/mcp-app/adaptor.d.ts +0 -48
  407. package/dist/web/bridges/mcp-app/adaptor.js +0 -268
  408. package/dist/web/bridges/mcp-app/adaptor.js.map +0 -1
  409. package/dist/web/hooks/use-widget-state.d.ts +0 -4
  410. package/dist/web/hooks/use-widget-state.js +0 -32
  411. package/dist/web/hooks/use-widget-state.js.map +0 -1
  412. package/dist/web/hooks/use-widget-state.test.js.map +0 -1
  413. package/dist/web/mount-widget.d.ts +0 -1
  414. package/dist/web/mount-widget.js.map +0 -1
  415. package/dist/web/plugin/validate-widget.d.ts +0 -5
  416. package/dist/web/plugin/validate-widget.js +0 -27
  417. package/dist/web/plugin/validate-widget.js.map +0 -1
  418. package/dist/web/plugin/validate-widget.test.js +0 -42
  419. package/dist/web/plugin/validate-widget.test.js.map +0 -1
  420. /package/dist/{test/widget.test.d.ts → cli/build-helpers.test.d.ts} +0 -0
  421. /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/build-steps.test.d.ts} +0 -0
  422. /package/dist/{web/plugin/validate-widget.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
@@ -2,6 +2,16 @@ import path from "node:path";
2
2
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
3
  import cors from "cors";
4
4
  import express from "express";
5
+ function parseControlPort(raw) {
6
+ if (raw === undefined) {
7
+ return null;
8
+ }
9
+ const n = Number.parseInt(raw, 10);
10
+ if (!Number.isFinite(n) || n <= 0 || n >= 65536) {
11
+ return null;
12
+ }
13
+ return n;
14
+ }
5
15
  function applyMiddlewares(app, middlewares) {
6
16
  for (const middleware of middlewares) {
7
17
  if (middleware.path) {
@@ -22,18 +32,25 @@ function defaultErrorHandler(err, _req, res, _next) {
22
32
  });
23
33
  }
24
34
  }
25
- export async function createApp({ mcpServer, httpServer, customMiddleware = [], errorMiddleware = [], }) {
26
- const app = express();
27
- app.use(express.json());
28
- const env = process.env.NODE_ENV || "development";
29
- applyMiddlewares(app, customMiddleware);
30
- if (env !== "production") {
35
+ export async function createApp({ mcpServer, httpServer, errorMiddleware = [], }) {
36
+ const app = mcpServer.express;
37
+ // Read `process.env.NODE_ENV` inline: wrangler/esbuild only substitute the literal expression,
38
+ // so a local const would defeat dead-code elimination of the dev-only imports below.
39
+ if (process.env.NODE_ENV !== "production") {
31
40
  const { devtoolsStaticServer } = await import("@skybridge/devtools");
32
41
  app.use(await devtoolsStaticServer());
33
- const { widgetsDevServer } = await import("./widgetsDevServer.js");
34
- app.use(await widgetsDevServer(httpServer));
42
+ const { viewsDevServer } = await import("./viewsDevServer.js");
43
+ app.use(await viewsDevServer(httpServer));
44
+ const controlPort = parseControlPort(process.env.__TUNNEL_CONTROL_PORT);
45
+ if (controlPort !== null) {
46
+ const { createTunnelProxyRouter } = await import("./tunnel-proxy-router.js");
47
+ app.use(createTunnelProxyRouter(controlPort));
48
+ }
49
+ else if (process.env.__TUNNEL_CONTROL_PORT !== undefined) {
50
+ console.warn(`Ignoring invalid __TUNNEL_CONTROL_PORT=${process.env.__TUNNEL_CONTROL_PORT}`);
51
+ }
35
52
  }
36
- if (env === "production") {
53
+ else {
37
54
  const assetsPath = path.join(process.cwd(), "dist", "assets");
38
55
  app.use("/assets", cors());
39
56
  app.use("/assets", express.static(assetsPath));
@@ -59,11 +76,18 @@ const mcpMiddleware = (server) => {
59
76
  try {
60
77
  const transport = new StreamableHTTPServerTransport({
61
78
  sessionIdGenerator: undefined,
79
+ // Respond with a single JSON body instead of SSE. Skybridge's stateless
80
+ // transport never streams server-initiated messages, so SSE adds no
81
+ // capability — and on workerd specifically, `cloudflare:node`'s http
82
+ // bridge silently drops chunked writes that happen after the request
83
+ // handler awaits, which manifests as a 200 with empty body for any
84
+ // async tools/call.
85
+ enableJsonResponse: true,
62
86
  });
63
87
  res.on("close", () => {
64
88
  transport.close();
65
89
  });
66
- await server.connect(transport);
90
+ await server.connectStatelessTransport(transport);
67
91
  // Express strips the mount path from req.url (e.g. "/mcp" becomes "/").
68
92
  // Restore it so the SDK builds the correct requestInfo.url.
69
93
  req.url = req.originalUrl;
@@ -1 +1 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/server/express.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../../src/server/express.ts"],"names":[],"mappings":"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","sourcesContent":["import type http from \"node:http\";\nimport path from \"node:path\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport cors from \"cors\";\nimport express from \"express\";\nimport type { McpServer } from \"./server.js\";\n\nfunction parseControlPort(raw: string | undefined): number | null {\n if (raw === undefined) {\n return null;\n }\n const n = Number.parseInt(raw, 10);\n if (!Number.isFinite(n) || n <= 0 || n >= 65536) {\n return null;\n }\n return n;\n}\n\nfunction applyMiddlewares(\n app: express.Express,\n middlewares: Array<{\n path?: string;\n handlers: express.ErrorRequestHandler[];\n }>,\n): void {\n for (const middleware of middlewares) {\n if (middleware.path) {\n app.use(middleware.path, ...middleware.handlers);\n } else {\n app.use(...middleware.handlers);\n }\n }\n}\n\nfunction defaultErrorHandler(\n err: unknown,\n _req: express.Request,\n res: express.Response,\n _next: express.NextFunction,\n) {\n console.error(\"Error handling MCP request:\", err);\n if (!res.headersSent) {\n res.status(500).json({\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Internal server error\" },\n id: null,\n });\n }\n}\n\nexport async function createApp({\n mcpServer,\n httpServer,\n errorMiddleware = [],\n}: {\n mcpServer: McpServer;\n httpServer: http.Server;\n errorMiddleware?: {\n path?: string;\n handlers: express.ErrorRequestHandler[];\n }[];\n}): Promise<express.Express> {\n const app = mcpServer.express;\n\n // Read `process.env.NODE_ENV` inline: wrangler/esbuild only substitute the literal expression,\n // so a local const would defeat dead-code elimination of the dev-only imports below.\n if (process.env.NODE_ENV !== \"production\") {\n const { devtoolsStaticServer } = await import(\"@skybridge/devtools\");\n app.use(await devtoolsStaticServer());\n const { viewsDevServer } = await import(\"./viewsDevServer.js\");\n app.use(await viewsDevServer(httpServer));\n\n const controlPort = parseControlPort(process.env.__TUNNEL_CONTROL_PORT);\n if (controlPort !== null) {\n const { createTunnelProxyRouter } = await import(\n \"./tunnel-proxy-router.js\"\n );\n app.use(createTunnelProxyRouter(controlPort));\n } else if (process.env.__TUNNEL_CONTROL_PORT !== undefined) {\n console.warn(\n `Ignoring invalid __TUNNEL_CONTROL_PORT=${process.env.__TUNNEL_CONTROL_PORT}`,\n );\n }\n } else {\n const assetsPath = path.join(process.cwd(), \"dist\", \"assets\");\n\n app.use(\"/assets\", cors());\n app.use(\"/assets\", express.static(assetsPath));\n }\n\n app.use(\"/mcp\", mcpMiddleware(mcpServer));\n\n applyMiddlewares(app, errorMiddleware);\n\n app.use(\"/mcp\", defaultErrorHandler);\n\n return app;\n}\n\nconst mcpMiddleware = (server: McpServer): express.RequestHandler => {\n return async (\n req: express.Request,\n res: express.Response,\n next: express.NextFunction,\n ) => {\n if (req.method !== \"POST\") {\n res.writeHead(405).end(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Method not allowed.\",\n },\n id: null,\n }),\n );\n return;\n }\n\n try {\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n // Respond with a single JSON body instead of SSE. Skybridge's stateless\n // transport never streams server-initiated messages, so SSE adds no\n // capability — and on workerd specifically, `cloudflare:node`'s http\n // bridge silently drops chunked writes that happen after the request\n // handler awaits, which manifests as a 200 with empty body for any\n // async tools/call.\n enableJsonResponse: true,\n });\n\n res.on(\"close\", () => {\n transport.close();\n });\n\n await server.connectStatelessTransport(transport);\n // Express strips the mount path from req.url (e.g. \"/mcp\" becomes \"/\").\n // Restore it so the SDK builds the correct requestInfo.url.\n req.url = req.originalUrl;\n await transport.handleRequest(req, res, req.body);\n } catch (error) {\n next(error);\n }\n };\n};\n"]}
@@ -1,12 +1,12 @@
1
1
  import http from "node:http";
2
2
  import { afterEach, describe, expect, it, vi } from "vitest";
3
+ import { McpServer } from "./server.js";
3
4
  vi.mock("@skybridge/devtools", () => ({
4
5
  devtoolsStaticServer: () => ((_req, _res, next) => next()),
5
6
  }));
6
- vi.mock("./widgetsDevServer.js", () => ({
7
- widgetsDevServer: (_httpServer) => ((_req, _res, next) => next()),
7
+ vi.mock("./viewsDevServer.js", () => ({
8
+ viewsDevServer: (_httpServer) => ((_req, _res, next) => next()),
8
9
  }));
9
- const fakeServer = {};
10
10
  async function listen(app) {
11
11
  const server = http.createServer(app);
12
12
  await new Promise((resolve) => server.listen(0, resolve));
@@ -25,6 +25,125 @@ async function postMcp(port) {
25
25
  async function postApi(port) {
26
26
  return fetch(`http://localhost:${port}/api/test`, { method: "POST" });
27
27
  }
28
+ describe("McpServer.express", () => {
29
+ it("exposes a ready Express app immediately after construction", () => {
30
+ const server = new McpServer({ name: "t", version: "0.0.0" });
31
+ expect(server.express).toBeDefined();
32
+ expect(typeof server.express.use).toBe("function");
33
+ expect(typeof server.express.get).toBe("function");
34
+ });
35
+ it("server.express.get registers a route reachable alongside /mcp", async () => {
36
+ const { createApp } = await import("./express.js");
37
+ const server = new McpServer({ name: "t", version: "0.0.0" });
38
+ server.express.get("/health", (_req, res) => {
39
+ res.json({ status: "ok" });
40
+ });
41
+ const httpServer = http.createServer();
42
+ await createApp({ mcpServer: server, httpServer });
43
+ const { port, server: listening } = await listen(server.express);
44
+ openServer = listening;
45
+ const health = await fetch(`http://localhost:${port}/health`);
46
+ expect(health.status).toBe(200);
47
+ expect(await health.json()).toEqual({ status: "ok" });
48
+ // /mcp still works (POST returns 200/4xx, not 404)
49
+ const mcp = await postMcp(port);
50
+ expect(mcp.status).not.toBe(404);
51
+ });
52
+ it("server.use and server.express.use produce the same registration order", async () => {
53
+ const { createApp } = await import("./express.js");
54
+ const callsA = [];
55
+ const callsB = [];
56
+ const buildServer = () => new McpServer({ name: "t", version: "0.0.0" });
57
+ const sA = buildServer();
58
+ sA.use((_req, _res, next) => {
59
+ callsA.push("first");
60
+ next();
61
+ });
62
+ sA.express.use((_req, _res, next) => {
63
+ callsA.push("second");
64
+ next();
65
+ });
66
+ const sB = buildServer();
67
+ sB.express.use((_req, _res, next) => {
68
+ callsB.push("first");
69
+ next();
70
+ });
71
+ sB.use((_req, _res, next) => {
72
+ callsB.push("second");
73
+ next();
74
+ });
75
+ for (const s of [sA, sB]) {
76
+ s.express.get("/probe", (_req, res) => res.json({ ok: true }));
77
+ const httpServer = http.createServer();
78
+ await createApp({ mcpServer: s, httpServer });
79
+ const { port, server: listening } = await listen(s.express);
80
+ openServer = listening;
81
+ await fetch(`http://localhost:${port}/probe`);
82
+ listening.close();
83
+ }
84
+ expect(callsA).toEqual(["first", "second"]);
85
+ expect(callsB).toEqual(["first", "second"]);
86
+ });
87
+ it("useOnError still wraps thrown /mcp errors after the route is mounted", async () => {
88
+ const { createApp } = await import("./express.js");
89
+ const server = new McpServer({ name: "t", version: "0.0.0" });
90
+ // Register the error handler BEFORE createApp — useOnError should still
91
+ // apply it after /mcp, so /mcp errors hit it.
92
+ const seen = [];
93
+ server.useOnError((_err, _req, res, _next) => {
94
+ seen.push("useOnError");
95
+ res.status(503).json({ from: "useOnError" });
96
+ });
97
+ // Force the /mcp handler to throw so the error pipeline runs.
98
+ vi.spyOn(server, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
99
+ const httpServer = http.createServer();
100
+ await createApp({
101
+ mcpServer: server,
102
+ httpServer,
103
+ // Mirror what run() does: forward the McpServer's useOnError handlers
104
+ // to createApp so they get applied after /mcp.
105
+ // biome-ignore lint/complexity/useLiteralKeys: test mirrors run() internals to verify useOnError ordering
106
+ errorMiddleware: server["customErrorMiddleware"],
107
+ });
108
+ const { port, server: listening } = await listen(server.express);
109
+ openServer = listening;
110
+ const res = await postMcp(port);
111
+ expect(seen).toEqual(["useOnError"]);
112
+ expect(res.status).toBe(503);
113
+ expect(await res.json()).toEqual({ from: "useOnError" });
114
+ });
115
+ });
116
+ describe("McpServer JSON body parser options", () => {
117
+ const largeBody = JSON.stringify({ data: "x".repeat(200 * 1024) });
118
+ async function postEcho(port, body) {
119
+ return fetch(`http://localhost:${port}/echo`, {
120
+ method: "POST",
121
+ headers: { "Content-Type": "application/json" },
122
+ body,
123
+ });
124
+ }
125
+ it("forwards json options to express.json", async () => {
126
+ const server = new McpServer({ name: "t", version: "0.0.0" }, {}, { json: { limit: "10mb" } });
127
+ server.express.post("/echo", (req, res) => {
128
+ res.json({ received: req.body.data.length });
129
+ });
130
+ const { port, server: listening } = await listen(server.express);
131
+ openServer = listening;
132
+ const res = await postEcho(port, largeBody);
133
+ expect(res.status).toBe(200);
134
+ expect(await res.json()).toEqual({ received: 200 * 1024 });
135
+ });
136
+ it("keeps the default 100kb limit when no options are passed", async () => {
137
+ const server = new McpServer({ name: "t", version: "0.0.0" });
138
+ server.express.post("/echo", (_req, res) => {
139
+ res.json({ ok: true });
140
+ });
141
+ const { port, server: listening } = await listen(server.express);
142
+ openServer = listening;
143
+ const res = await postEcho(port, largeBody);
144
+ expect(res.status).toBe(413);
145
+ });
146
+ });
28
147
  describe("createApp", () => {
29
148
  it("runs global custom middleware before the /mcp handler", async () => {
30
149
  const { createApp } = await import("./express.js");
@@ -33,14 +152,12 @@ describe("createApp", () => {
33
152
  calls.push("custom");
34
153
  next();
35
154
  };
155
+ const server = new McpServer({ name: "t", version: "0.0.0" });
156
+ server.use(mw);
36
157
  const httpServer = http.createServer();
37
- const app = await createApp({
38
- mcpServer: fakeServer,
39
- httpServer,
40
- customMiddleware: [{ handlers: [mw] }],
41
- });
42
- const { port, server } = await listen(app);
43
- openServer = server;
158
+ const app = await createApp({ mcpServer: server, httpServer });
159
+ const { port, server: httpListening } = await listen(app);
160
+ openServer = httpListening;
44
161
  await postMcp(port);
45
162
  expect(calls).toEqual(["custom"]);
46
163
  });
@@ -51,14 +168,12 @@ describe("createApp", () => {
51
168
  calls.push("auth");
52
169
  next();
53
170
  };
171
+ const server = new McpServer({ name: "t", version: "0.0.0" });
172
+ server.use("/mcp", mw);
54
173
  const httpServer = http.createServer();
55
- const app = await createApp({
56
- mcpServer: fakeServer,
57
- httpServer,
58
- customMiddleware: [{ path: "/mcp", handlers: [mw] }],
59
- });
60
- const { port, server } = await listen(app);
61
- openServer = server;
174
+ const app = await createApp({ mcpServer: server, httpServer });
175
+ const { port, server: httpListening } = await listen(app);
176
+ openServer = httpListening;
62
177
  await postMcp(port);
63
178
  expect(calls).toEqual(["auth"]);
64
179
  });
@@ -69,14 +184,12 @@ describe("createApp", () => {
69
184
  calls.push("reject");
70
185
  res.status(401).json({ error: "Unauthorized" });
71
186
  };
187
+ const server = new McpServer({ name: "t", version: "0.0.0" });
188
+ server.use("/mcp", reject);
72
189
  const httpServer = http.createServer();
73
- const app = await createApp({
74
- mcpServer: fakeServer,
75
- httpServer,
76
- customMiddleware: [{ path: "/mcp", handlers: [reject] }],
77
- });
78
- const { port, server } = await listen(app);
79
- openServer = server;
190
+ const app = await createApp({ mcpServer: server, httpServer });
191
+ const { port, server: httpListening } = await listen(app);
192
+ openServer = httpListening;
80
193
  const res = await postMcp(port);
81
194
  expect(calls).toEqual(["reject"]);
82
195
  expect(res.status).toBe(401);
@@ -93,14 +206,13 @@ describe("createApp", () => {
93
206
  calls.push("B");
94
207
  next();
95
208
  };
209
+ const server = new McpServer({ name: "t", version: "0.0.0" });
210
+ server.use(mwA);
211
+ server.use(mwB);
96
212
  const httpServer = http.createServer();
97
- const app = await createApp({
98
- mcpServer: fakeServer,
99
- httpServer,
100
- customMiddleware: [{ handlers: [mwA] }, { handlers: [mwB] }],
101
- });
102
- const { port, server } = await listen(app);
103
- openServer = server;
213
+ const app = await createApp({ mcpServer: server, httpServer });
214
+ const { port, server: httpListening } = await listen(app);
215
+ openServer = httpListening;
104
216
  await postMcp(port);
105
217
  expect(calls).toEqual(["A", "B"]);
106
218
  });
@@ -111,14 +223,12 @@ describe("createApp", () => {
111
223
  calls.push("api");
112
224
  next();
113
225
  };
226
+ const server = new McpServer({ name: "t", version: "0.0.0" });
227
+ server.use("/api", apiMw);
114
228
  const httpServer = http.createServer();
115
- const app = await createApp({
116
- mcpServer: fakeServer,
117
- httpServer,
118
- customMiddleware: [{ path: "/api", handlers: [apiMw] }],
119
- });
120
- const { port, server } = await listen(app);
121
- openServer = server;
229
+ const app = await createApp({ mcpServer: server, httpServer });
230
+ const { port, server: httpListening } = await listen(app);
231
+ openServer = httpListening;
122
232
  // Hit /mcp — the /api middleware should NOT fire
123
233
  await postMcp(port);
124
234
  expect(calls).toEqual([]);
@@ -130,14 +240,12 @@ describe("createApp", () => {
130
240
  router.get("/health", (_req, res) => {
131
241
  res.json({ status: "ok" });
132
242
  });
243
+ const server = new McpServer({ name: "t", version: "0.0.0" });
244
+ server.use(router);
133
245
  const httpServer = http.createServer();
134
- const app = await createApp({
135
- mcpServer: fakeServer,
136
- httpServer,
137
- customMiddleware: [{ handlers: [router] }],
138
- });
139
- const { port, server } = await listen(app);
140
- openServer = server;
246
+ const app = await createApp({ mcpServer: server, httpServer });
247
+ const { port, server: httpListening } = await listen(app);
248
+ openServer = httpListening;
141
249
  const res = await fetch(`http://localhost:${port}/health`);
142
250
  expect(res.status).toBe(200);
143
251
  expect(await res.json()).toEqual({ status: "ok" });
@@ -149,16 +257,12 @@ describe("createApp", () => {
149
257
  router.get("/data", (_req, res) => {
150
258
  res.json({ value: 42 });
151
259
  });
260
+ const server = new McpServer({ name: "t", version: "0.0.0" });
261
+ server.use("/api", router);
152
262
  const httpServer = http.createServer();
153
- const app = await createApp({
154
- mcpServer: fakeServer,
155
- httpServer,
156
- customMiddleware: [
157
- { path: "/api", handlers: [router] },
158
- ],
159
- });
160
- const { port, server } = await listen(app);
161
- openServer = server;
263
+ const app = await createApp({ mcpServer: server, httpServer });
264
+ const { port, server: httpListening } = await listen(app);
265
+ openServer = httpListening;
162
266
  const res = await fetch(`http://localhost:${port}/api/data`);
163
267
  expect(res.status).toBe(200);
164
268
  expect(await res.json()).toEqual({ value: 42 });
@@ -168,14 +272,12 @@ describe("createApp", () => {
168
272
  const throwing = () => {
169
273
  throw new Error("boom");
170
274
  };
275
+ const server = new McpServer({ name: "t", version: "0.0.0" });
276
+ server.use("/explode", throwing);
171
277
  const httpServer = http.createServer();
172
- const app = await createApp({
173
- mcpServer: fakeServer,
174
- httpServer,
175
- customMiddleware: [{ path: "/explode", handlers: [throwing] }],
176
- });
177
- const { port, server } = await listen(app);
178
- openServer = server;
278
+ const app = await createApp({ mcpServer: server, httpServer });
279
+ const { port, server: httpListening } = await listen(app);
280
+ openServer = httpListening;
179
281
  const res = await fetch(`http://localhost:${port}/explode`);
180
282
  expect(res.status).toBe(500);
181
283
  // Server process did not crash — it still accepts connections
@@ -185,10 +287,15 @@ describe("createApp", () => {
185
287
  it("returns 500 JSON-RPC error when the MCP handler throws and no error middleware is registered", async () => {
186
288
  const { createApp } = await import("./express.js");
187
289
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
290
+ const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
291
+ // Force the express-level error path: make connectStatelessTransport
292
+ // reject so the request handler hits its try/catch and calls next(error),
293
+ // which lands in the default /mcp error handler.
294
+ vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
188
295
  const httpServer = http.createServer();
189
- const app = await createApp({ mcpServer: fakeServer, httpServer });
190
- const { port, server } = await listen(app);
191
- openServer = server;
296
+ const app = await createApp({ mcpServer, httpServer });
297
+ const { port, server: httpListening } = await listen(app);
298
+ openServer = httpListening;
192
299
  const res = await postMcp(port);
193
300
  expect(res.status).toBe(500);
194
301
  expect(await res.json()).toEqual({
@@ -206,14 +313,16 @@ describe("createApp", () => {
206
313
  calls.push("error-handler");
207
314
  res.status(503).json({ custom: true });
208
315
  };
316
+ const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
317
+ vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
209
318
  const httpServer = http.createServer();
210
319
  const app = await createApp({
211
- mcpServer: fakeServer,
320
+ mcpServer,
212
321
  httpServer,
213
322
  errorMiddleware: [{ handlers: [errorHandler] }],
214
323
  });
215
- const { port, server } = await listen(app);
216
- openServer = server;
324
+ const { port, server: httpListening } = await listen(app);
325
+ openServer = httpListening;
217
326
  const res = await postMcp(port);
218
327
  expect(calls).toEqual(["error-handler"]);
219
328
  expect(res.status).toBe(503);
@@ -229,15 +338,17 @@ describe("createApp", () => {
229
338
  const throwingApiRoute = (_req, _res, next) => {
230
339
  next(new Error("api error"));
231
340
  };
341
+ const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
342
+ vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
343
+ mcpServer.use("/api/test", throwingApiRoute);
232
344
  const httpServer = http.createServer();
233
345
  const app = await createApp({
234
- mcpServer: fakeServer,
346
+ mcpServer,
235
347
  httpServer,
236
- customMiddleware: [{ path: "/api/test", handlers: [throwingApiRoute] }],
237
348
  errorMiddleware: [{ path: "/mcp", handlers: [mcpErrorHandler] }],
238
349
  });
239
- const { port, server } = await listen(app);
240
- openServer = server;
350
+ const { port, server: httpListening } = await listen(app);
351
+ openServer = httpListening;
241
352
  const mcpRes = await postMcp(port);
242
353
  expect(calls).toEqual(["mcp-error-handler"]);
243
354
  expect(mcpRes.status).toBe(503);
@@ -248,5 +359,133 @@ describe("createApp", () => {
248
359
  expect(apiRes.status).toBe(500);
249
360
  consoleSpy.mockRestore();
250
361
  });
362
+ it("handles concurrent /mcp requests without 'Already connected to a transport'", async () => {
363
+ const { createApp } = await import("./express.js");
364
+ const mcpServer = new McpServer({
365
+ name: "concurrent-test",
366
+ version: "0.0.0",
367
+ });
368
+ // Slow tool: keeps the underlying transport bound long enough to overlap
369
+ // with concurrent requests, exposing the shared-McpServer race.
370
+ mcpServer.registerTool({ name: "slow", description: "slow" }, async () => {
371
+ await new Promise((r) => setTimeout(r, 50));
372
+ return { content: [{ type: "text", text: "done" }] };
373
+ });
374
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
375
+ const httpServer = http.createServer();
376
+ const app = await createApp({ mcpServer, httpServer });
377
+ const { port, server } = await listen(app);
378
+ openServer = server;
379
+ const callBody = (id) => JSON.stringify({
380
+ jsonrpc: "2.0",
381
+ method: "tools/call",
382
+ id,
383
+ params: { name: "slow", arguments: {} },
384
+ });
385
+ const N = 10;
386
+ const responses = await Promise.all(Array.from({ length: N }, (_, i) => fetch(`http://localhost:${port}/mcp`, {
387
+ method: "POST",
388
+ headers: {
389
+ "Content-Type": "application/json",
390
+ Accept: "application/json, text/event-stream",
391
+ },
392
+ body: callBody(i + 1),
393
+ })));
394
+ expect(responses.map((r) => r.status)).toEqual(Array(N).fill(200));
395
+ expect(consoleSpy).not.toHaveBeenCalledWith("Error handling MCP request:", expect.any(Error));
396
+ consoleSpy.mockRestore();
397
+ });
398
+ });
399
+ describe("createApp Vercel mode", () => {
400
+ it("server.run() returns the Express app without binding a port when VERCEL=1", async () => {
401
+ const prevVercel = process.env.VERCEL;
402
+ const prevEnv = process.env.NODE_ENV;
403
+ process.env.VERCEL = "1";
404
+ process.env.NODE_ENV = "production";
405
+ try {
406
+ vi.resetModules();
407
+ const { McpServer: Reloaded } = await import("./server.js");
408
+ const server = new Reloaded({ name: "t", version: "0.0.0" });
409
+ const result = await server.run();
410
+ expect(typeof result).toBe("function");
411
+ expect(result).toBe(server.express);
412
+ const { port, server: listening } = await listen(server.express);
413
+ openServer = listening;
414
+ const res = await postMcp(port);
415
+ expect(res.status).not.toBe(404);
416
+ }
417
+ finally {
418
+ if (prevVercel === undefined) {
419
+ delete process.env.VERCEL;
420
+ }
421
+ else {
422
+ process.env.VERCEL = prevVercel;
423
+ }
424
+ process.env.NODE_ENV = prevEnv;
425
+ vi.resetModules();
426
+ }
427
+ });
428
+ });
429
+ describe("createApp tunnel routes", () => {
430
+ it("proxies POST /__skybridge/tunnel to the cli control server in dev mode", async () => {
431
+ // Stand up a fake control listener that returns a known JSON body.
432
+ const control = http.createServer((_req, res) => {
433
+ res.writeHead(200, { "Content-Type": "application/json" });
434
+ res.end('{"status":"idle"}');
435
+ });
436
+ await new Promise((resolve) => control.listen(0, "127.0.0.1", resolve));
437
+ const controlAddr = control.address();
438
+ if (typeof controlAddr === "string" || controlAddr === null) {
439
+ control.close();
440
+ throw new Error("control server has no address");
441
+ }
442
+ const controlPort = controlAddr.port;
443
+ const prev = process.env.__TUNNEL_CONTROL_PORT;
444
+ process.env.__TUNNEL_CONTROL_PORT = String(controlPort);
445
+ try {
446
+ const { createApp } = await import("./express.js");
447
+ const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
448
+ const httpServer = http.createServer();
449
+ const app = await createApp({ mcpServer, httpServer });
450
+ const { port, server } = await listen(app);
451
+ openServer = server;
452
+ const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
453
+ method: "POST",
454
+ });
455
+ expect(res.status).toBe(200);
456
+ expect(await res.json()).toEqual({ status: "idle" });
457
+ }
458
+ finally {
459
+ if (prev === undefined) {
460
+ delete process.env.__TUNNEL_CONTROL_PORT;
461
+ }
462
+ else {
463
+ process.env.__TUNNEL_CONTROL_PORT = prev;
464
+ }
465
+ await new Promise((resolve) => control.close(() => resolve()));
466
+ }
467
+ });
468
+ it("does not expose /__skybridge/tunnel in production mode", async () => {
469
+ const prevEnv = process.env.NODE_ENV;
470
+ process.env.NODE_ENV = "production";
471
+ try {
472
+ vi.resetModules();
473
+ const { createApp } = await import("./express.js");
474
+ const { McpServer: ReloadedMcpServer } = await import("./server.js");
475
+ const mcpServer = new ReloadedMcpServer({ name: "t", version: "0.0.0" });
476
+ const httpServer = http.createServer();
477
+ const app = await createApp({ mcpServer, httpServer });
478
+ const { port, server } = await listen(app);
479
+ openServer = server;
480
+ const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
481
+ method: "POST",
482
+ });
483
+ expect(res.status).toBe(404);
484
+ }
485
+ finally {
486
+ process.env.NODE_ENV = prevEnv;
487
+ vi.resetModules();
488
+ }
489
+ });
251
490
  });
252
491
  //# sourceMappingURL=express.test.js.map