skybridge 0.0.0-dev.c003b05 → 0.0.0-dev.c006b0b

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