skybridge 0.0.0-dev.fe06299 → 0.0.0-dev.fe35f75

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 (250) hide show
  1. package/README.md +8 -8
  2. package/dist/cli/detect-port.js.map +1 -1
  3. package/dist/cli/header.js +1 -1
  4. package/dist/cli/header.js.map +1 -1
  5. package/dist/cli/run-command.js.map +1 -1
  6. package/dist/cli/telemetry.js.map +1 -1
  7. package/dist/cli/tunnel-control-server.d.ts +9 -0
  8. package/dist/cli/tunnel-control-server.js +31 -0
  9. package/dist/cli/tunnel-control-server.js.map +1 -0
  10. package/dist/cli/tunnel-control-server.test.js +39 -0
  11. package/dist/cli/tunnel-control-server.test.js.map +1 -0
  12. package/dist/cli/tunnel-handler.d.ts +3 -0
  13. package/dist/cli/tunnel-handler.js +48 -0
  14. package/dist/cli/tunnel-handler.js.map +1 -0
  15. package/dist/cli/tunnel-handler.test.js +105 -0
  16. package/dist/cli/tunnel-handler.test.js.map +1 -0
  17. package/dist/cli/tunnel.d.ts +57 -0
  18. package/dist/cli/tunnel.js +154 -0
  19. package/dist/cli/tunnel.js.map +1 -0
  20. package/dist/cli/tunnel.test.js +190 -0
  21. package/dist/cli/tunnel.test.js.map +1 -0
  22. package/dist/cli/types.js.map +1 -1
  23. package/dist/cli/use-execute-steps.js.map +1 -1
  24. package/dist/cli/use-messages.d.ts +3 -0
  25. package/dist/cli/use-messages.js +11 -0
  26. package/dist/cli/use-messages.js.map +1 -0
  27. package/dist/cli/use-nodemon.d.ts +2 -2
  28. package/dist/cli/use-nodemon.js +18 -25
  29. package/dist/cli/use-nodemon.js.map +1 -1
  30. package/dist/cli/use-open-browser.d.ts +1 -0
  31. package/dist/cli/use-open-browser.js +44 -0
  32. package/dist/cli/use-open-browser.js.map +1 -0
  33. package/dist/cli/use-tunnel.d.ts +13 -7
  34. package/dist/cli/use-tunnel.js +103 -73
  35. package/dist/cli/use-tunnel.js.map +1 -1
  36. package/dist/cli/use-typescript-check.d.ts +1 -0
  37. package/dist/cli/use-typescript-check.js +41 -6
  38. package/dist/cli/use-typescript-check.js.map +1 -1
  39. package/dist/commands/build.js +63 -7
  40. package/dist/commands/build.js.map +1 -1
  41. package/dist/commands/dev.d.ts +2 -0
  42. package/dist/commands/dev.js +42 -6
  43. package/dist/commands/dev.js.map +1 -1
  44. package/dist/commands/start.js +7 -10
  45. package/dist/commands/start.js.map +1 -1
  46. package/dist/commands/telemetry/disable.js.map +1 -1
  47. package/dist/commands/telemetry/enable.js.map +1 -1
  48. package/dist/commands/telemetry/status.js.map +1 -1
  49. package/dist/server/asset-base-url-transform-plugin.d.ts +5 -6
  50. package/dist/server/asset-base-url-transform-plugin.js +9 -10
  51. package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
  52. package/dist/server/asset-base-url-transform-plugin.test.js +41 -13
  53. package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
  54. package/dist/server/content-helpers.d.ts +27 -0
  55. package/dist/server/content-helpers.js +46 -0
  56. package/dist/server/content-helpers.js.map +1 -0
  57. package/dist/server/content-helpers.test.d.ts +1 -0
  58. package/dist/server/content-helpers.test.js +70 -0
  59. package/dist/server/content-helpers.test.js.map +1 -0
  60. package/dist/server/express.d.ts +2 -6
  61. package/dist/server/express.js +34 -10
  62. package/dist/server/express.js.map +1 -1
  63. package/dist/server/express.test.js +249 -71
  64. package/dist/server/express.test.js.map +1 -1
  65. package/dist/server/index.d.ts +4 -3
  66. package/dist/server/index.js +3 -2
  67. package/dist/server/index.js.map +1 -1
  68. package/dist/server/inferUtilityTypes.d.ts +6 -6
  69. package/dist/server/inferUtilityTypes.js.map +1 -1
  70. package/dist/server/metric.d.ts +14 -0
  71. package/dist/server/metric.js +62 -0
  72. package/dist/server/metric.js.map +1 -0
  73. package/dist/server/middleware.js.map +1 -1
  74. package/dist/server/middleware.test-d.js.map +1 -1
  75. package/dist/server/middleware.test.js +12 -9
  76. package/dist/server/middleware.test.js.map +1 -1
  77. package/dist/server/server.d.ts +122 -76
  78. package/dist/server/server.js +262 -82
  79. package/dist/server/server.js.map +1 -1
  80. package/dist/server/templateHelper.d.ts +5 -7
  81. package/dist/server/templateHelper.js +3 -22
  82. package/dist/server/templateHelper.js.map +1 -1
  83. package/dist/server/templates.generated.d.ts +4 -0
  84. package/dist/server/templates.generated.js +47 -0
  85. package/dist/server/templates.generated.js.map +1 -0
  86. package/dist/server/tunnel-proxy-router.d.ts +7 -0
  87. package/dist/server/tunnel-proxy-router.js +110 -0
  88. package/dist/server/tunnel-proxy-router.js.map +1 -0
  89. package/dist/server/tunnel-proxy-router.test.d.ts +1 -0
  90. package/dist/server/tunnel-proxy-router.test.js +229 -0
  91. package/dist/server/tunnel-proxy-router.test.js.map +1 -0
  92. package/dist/server/viewsDevServer.d.ts +14 -0
  93. package/dist/server/viewsDevServer.js +45 -0
  94. package/dist/server/viewsDevServer.js.map +1 -0
  95. package/dist/test/utils.d.ts +13 -21
  96. package/dist/test/utils.js +42 -37
  97. package/dist/test/utils.js.map +1 -1
  98. package/dist/test/view.test.d.ts +1 -0
  99. package/dist/test/view.test.js +523 -0
  100. package/dist/test/view.test.js.map +1 -0
  101. package/dist/version.d.ts +1 -0
  102. package/dist/version.js +3 -0
  103. package/dist/version.js.map +1 -0
  104. package/dist/web/bridges/apps-sdk/adaptor.d.ts +8 -4
  105. package/dist/web/bridges/apps-sdk/adaptor.js +43 -16
  106. package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -1
  107. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  108. package/dist/web/bridges/apps-sdk/index.js.map +1 -1
  109. package/dist/web/bridges/apps-sdk/types.d.ts +18 -6
  110. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  111. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  112. package/dist/web/bridges/get-adaptor.js.map +1 -1
  113. package/dist/web/bridges/index.js.map +1 -1
  114. package/dist/web/bridges/mcp-app/adaptor.d.ts +18 -6
  115. package/dist/web/bridges/mcp-app/adaptor.js +115 -28
  116. package/dist/web/bridges/mcp-app/adaptor.js.map +1 -1
  117. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  118. package/dist/web/bridges/mcp-app/index.js.map +1 -1
  119. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  120. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  121. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  122. package/dist/web/bridges/types.d.ts +24 -10
  123. package/dist/web/bridges/types.js.map +1 -1
  124. package/dist/web/bridges/use-host-context.js.map +1 -1
  125. package/dist/web/components/modal-provider.js +2 -2
  126. package/dist/web/components/modal-provider.js.map +1 -1
  127. package/dist/web/create-store.js +17 -3
  128. package/dist/web/create-store.js.map +1 -1
  129. package/dist/web/create-store.test.js +14 -16
  130. package/dist/web/create-store.test.js.map +1 -1
  131. package/dist/web/data-llm.d.ts +1 -1
  132. package/dist/web/data-llm.js +3 -3
  133. package/dist/web/data-llm.js.map +1 -1
  134. package/dist/web/data-llm.test.js +22 -22
  135. package/dist/web/data-llm.test.js.map +1 -1
  136. package/dist/web/generate-helpers.d.ts +20 -18
  137. package/dist/web/generate-helpers.js +20 -18
  138. package/dist/web/generate-helpers.js.map +1 -1
  139. package/dist/web/generate-helpers.test-d.js +26 -26
  140. package/dist/web/generate-helpers.test-d.js.map +1 -1
  141. package/dist/web/generate-helpers.test.js.map +1 -1
  142. package/dist/web/helpers/state.d.ts +2 -2
  143. package/dist/web/helpers/state.js +11 -11
  144. package/dist/web/helpers/state.js.map +1 -1
  145. package/dist/web/helpers/state.test.js +9 -9
  146. package/dist/web/helpers/state.test.js.map +1 -1
  147. package/dist/web/hooks/index.d.ts +3 -1
  148. package/dist/web/hooks/index.js +3 -1
  149. package/dist/web/hooks/index.js.map +1 -1
  150. package/dist/web/hooks/test/utils.js.map +1 -1
  151. package/dist/web/hooks/use-call-tool.js.map +1 -1
  152. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -1
  153. package/dist/web/hooks/use-call-tool.test.js +0 -4
  154. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  155. package/dist/web/hooks/use-display-mode.js.map +1 -1
  156. package/dist/web/hooks/use-display-mode.test-d.js.map +1 -1
  157. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  158. package/dist/web/hooks/use-files.d.ts +2 -1
  159. package/dist/web/hooks/use-files.js +1 -0
  160. package/dist/web/hooks/use-files.js.map +1 -1
  161. package/dist/web/hooks/use-files.test.js +22 -2
  162. package/dist/web/hooks/use-files.test.js.map +1 -1
  163. package/dist/web/hooks/use-layout.js.map +1 -1
  164. package/dist/web/hooks/use-layout.test.js.map +1 -1
  165. package/dist/web/hooks/use-open-external.js.map +1 -1
  166. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  167. package/dist/web/hooks/use-request-close.d.ts +2 -0
  168. package/dist/web/hooks/use-request-close.js +8 -0
  169. package/dist/web/hooks/use-request-close.js.map +1 -0
  170. package/dist/web/hooks/use-request-close.test.d.ts +1 -0
  171. package/dist/web/hooks/use-request-close.test.js +52 -0
  172. package/dist/web/hooks/use-request-close.test.js.map +1 -0
  173. package/dist/web/hooks/use-request-modal.d.ts +1 -1
  174. package/dist/web/hooks/use-request-modal.js +4 -4
  175. package/dist/web/hooks/use-request-modal.js.map +1 -1
  176. package/dist/web/hooks/use-request-modal.test.js +1 -1
  177. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  178. package/dist/web/hooks/use-request-size.d.ts +3 -0
  179. package/dist/web/hooks/use-request-size.js +8 -0
  180. package/dist/web/hooks/use-request-size.js.map +1 -0
  181. package/dist/web/hooks/use-request-size.test.d.ts +1 -0
  182. package/dist/web/hooks/use-request-size.test.js +65 -0
  183. package/dist/web/hooks/use-request-size.test.js.map +1 -0
  184. package/dist/web/hooks/use-send-follow-up-message.d.ts +2 -1
  185. package/dist/web/hooks/use-send-follow-up-message.js +2 -2
  186. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  187. package/dist/web/hooks/use-set-open-in-app-url.js.map +1 -1
  188. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  189. package/dist/web/hooks/use-tool-info.js.map +1 -1
  190. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  191. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  192. package/dist/web/hooks/use-user.js.map +1 -1
  193. package/dist/web/hooks/use-user.test.js.map +1 -1
  194. package/dist/web/hooks/use-view-state.d.ts +4 -0
  195. package/dist/web/hooks/use-view-state.js +32 -0
  196. package/dist/web/hooks/use-view-state.js.map +1 -0
  197. package/dist/web/hooks/use-view-state.test.d.ts +1 -0
  198. package/dist/web/hooks/use-view-state.test.js +177 -0
  199. package/dist/web/hooks/use-view-state.test.js.map +1 -0
  200. package/dist/web/index.d.ts +1 -2
  201. package/dist/web/index.js +1 -2
  202. package/dist/web/index.js.map +1 -1
  203. package/dist/web/mount-view.d.ts +1 -0
  204. package/dist/web/{mount-widget.js → mount-view.js} +2 -2
  205. package/dist/web/mount-view.js.map +1 -0
  206. package/dist/web/plugin/data-llm.test.js.map +1 -1
  207. package/dist/web/plugin/plugin.d.ts +4 -1
  208. package/dist/web/plugin/plugin.js +127 -25
  209. package/dist/web/plugin/plugin.js.map +1 -1
  210. package/dist/web/plugin/scan-views.d.ts +16 -0
  211. package/dist/web/plugin/scan-views.js +88 -0
  212. package/dist/web/plugin/scan-views.js.map +1 -0
  213. package/dist/web/plugin/scan-views.test.d.ts +1 -0
  214. package/dist/web/plugin/scan-views.test.js +99 -0
  215. package/dist/web/plugin/scan-views.test.js.map +1 -0
  216. package/dist/web/plugin/transform-data-llm.js +1 -1
  217. package/dist/web/plugin/transform-data-llm.js.map +1 -1
  218. package/dist/web/plugin/transform-data-llm.test.js.map +1 -1
  219. package/dist/web/plugin/validate-view.d.ts +1 -0
  220. package/dist/web/plugin/validate-view.js +9 -0
  221. package/dist/web/plugin/validate-view.js.map +1 -0
  222. package/dist/web/plugin/validate-view.test.d.ts +1 -0
  223. package/dist/web/plugin/validate-view.test.js +24 -0
  224. package/dist/web/plugin/validate-view.test.js.map +1 -0
  225. package/dist/web/proxy.js.map +1 -1
  226. package/dist/web/types.js.map +1 -1
  227. package/package.json +24 -14
  228. package/tsconfig.base.json +2 -0
  229. package/dist/server/templates/development.hbs +0 -12
  230. package/dist/server/templates/production.hbs +0 -6
  231. package/dist/server/widgetsDevServer.d.ts +0 -13
  232. package/dist/server/widgetsDevServer.js +0 -57
  233. package/dist/server/widgetsDevServer.js.map +0 -1
  234. package/dist/test/widget.test.js +0 -263
  235. package/dist/test/widget.test.js.map +0 -1
  236. package/dist/web/hooks/use-widget-state.d.ts +0 -4
  237. package/dist/web/hooks/use-widget-state.js +0 -32
  238. package/dist/web/hooks/use-widget-state.js.map +0 -1
  239. package/dist/web/hooks/use-widget-state.test.js +0 -64
  240. package/dist/web/hooks/use-widget-state.test.js.map +0 -1
  241. package/dist/web/mount-widget.d.ts +0 -1
  242. package/dist/web/mount-widget.js.map +0 -1
  243. package/dist/web/plugin/validate-widget.d.ts +0 -5
  244. package/dist/web/plugin/validate-widget.js +0 -27
  245. package/dist/web/plugin/validate-widget.js.map +0 -1
  246. package/dist/web/plugin/validate-widget.test.js +0 -42
  247. package/dist/web/plugin/validate-widget.test.js.map +0 -1
  248. /package/dist/{test/widget.test.d.ts → cli/tunnel-control-server.test.d.ts} +0 -0
  249. /package/dist/{web/hooks/use-widget-state.test.d.ts → cli/tunnel-handler.test.d.ts} +0 -0
  250. /package/dist/{web/plugin/validate-widget.test.d.ts → cli/tunnel.test.d.ts} +0 -0
@@ -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,94 @@ 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
+ });
28
116
  describe("createApp", () => {
29
117
  it("runs global custom middleware before the /mcp handler", async () => {
30
118
  const { createApp } = await import("./express.js");
@@ -33,14 +121,12 @@ describe("createApp", () => {
33
121
  calls.push("custom");
34
122
  next();
35
123
  };
124
+ const server = new McpServer({ name: "t", version: "0.0.0" });
125
+ server.use(mw);
36
126
  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;
127
+ const app = await createApp({ mcpServer: server, httpServer });
128
+ const { port, server: httpListening } = await listen(app);
129
+ openServer = httpListening;
44
130
  await postMcp(port);
45
131
  expect(calls).toEqual(["custom"]);
46
132
  });
@@ -51,14 +137,12 @@ describe("createApp", () => {
51
137
  calls.push("auth");
52
138
  next();
53
139
  };
140
+ const server = new McpServer({ name: "t", version: "0.0.0" });
141
+ server.use("/mcp", mw);
54
142
  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;
143
+ const app = await createApp({ mcpServer: server, httpServer });
144
+ const { port, server: httpListening } = await listen(app);
145
+ openServer = httpListening;
62
146
  await postMcp(port);
63
147
  expect(calls).toEqual(["auth"]);
64
148
  });
@@ -69,14 +153,12 @@ describe("createApp", () => {
69
153
  calls.push("reject");
70
154
  res.status(401).json({ error: "Unauthorized" });
71
155
  };
156
+ const server = new McpServer({ name: "t", version: "0.0.0" });
157
+ server.use("/mcp", reject);
72
158
  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;
159
+ const app = await createApp({ mcpServer: server, httpServer });
160
+ const { port, server: httpListening } = await listen(app);
161
+ openServer = httpListening;
80
162
  const res = await postMcp(port);
81
163
  expect(calls).toEqual(["reject"]);
82
164
  expect(res.status).toBe(401);
@@ -93,14 +175,13 @@ describe("createApp", () => {
93
175
  calls.push("B");
94
176
  next();
95
177
  };
178
+ const server = new McpServer({ name: "t", version: "0.0.0" });
179
+ server.use(mwA);
180
+ server.use(mwB);
96
181
  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;
182
+ const app = await createApp({ mcpServer: server, httpServer });
183
+ const { port, server: httpListening } = await listen(app);
184
+ openServer = httpListening;
104
185
  await postMcp(port);
105
186
  expect(calls).toEqual(["A", "B"]);
106
187
  });
@@ -111,14 +192,12 @@ describe("createApp", () => {
111
192
  calls.push("api");
112
193
  next();
113
194
  };
195
+ const server = new McpServer({ name: "t", version: "0.0.0" });
196
+ server.use("/api", apiMw);
114
197
  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;
198
+ const app = await createApp({ mcpServer: server, httpServer });
199
+ const { port, server: httpListening } = await listen(app);
200
+ openServer = httpListening;
122
201
  // Hit /mcp — the /api middleware should NOT fire
123
202
  await postMcp(port);
124
203
  expect(calls).toEqual([]);
@@ -130,14 +209,12 @@ describe("createApp", () => {
130
209
  router.get("/health", (_req, res) => {
131
210
  res.json({ status: "ok" });
132
211
  });
212
+ const server = new McpServer({ name: "t", version: "0.0.0" });
213
+ server.use(router);
133
214
  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;
215
+ const app = await createApp({ mcpServer: server, httpServer });
216
+ const { port, server: httpListening } = await listen(app);
217
+ openServer = httpListening;
141
218
  const res = await fetch(`http://localhost:${port}/health`);
142
219
  expect(res.status).toBe(200);
143
220
  expect(await res.json()).toEqual({ status: "ok" });
@@ -149,16 +226,12 @@ describe("createApp", () => {
149
226
  router.get("/data", (_req, res) => {
150
227
  res.json({ value: 42 });
151
228
  });
229
+ const server = new McpServer({ name: "t", version: "0.0.0" });
230
+ server.use("/api", router);
152
231
  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;
232
+ const app = await createApp({ mcpServer: server, httpServer });
233
+ const { port, server: httpListening } = await listen(app);
234
+ openServer = httpListening;
162
235
  const res = await fetch(`http://localhost:${port}/api/data`);
163
236
  expect(res.status).toBe(200);
164
237
  expect(await res.json()).toEqual({ value: 42 });
@@ -168,14 +241,12 @@ describe("createApp", () => {
168
241
  const throwing = () => {
169
242
  throw new Error("boom");
170
243
  };
244
+ const server = new McpServer({ name: "t", version: "0.0.0" });
245
+ server.use("/explode", throwing);
171
246
  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;
247
+ const app = await createApp({ mcpServer: server, httpServer });
248
+ const { port, server: httpListening } = await listen(app);
249
+ openServer = httpListening;
179
250
  const res = await fetch(`http://localhost:${port}/explode`);
180
251
  expect(res.status).toBe(500);
181
252
  // Server process did not crash — it still accepts connections
@@ -185,10 +256,15 @@ describe("createApp", () => {
185
256
  it("returns 500 JSON-RPC error when the MCP handler throws and no error middleware is registered", async () => {
186
257
  const { createApp } = await import("./express.js");
187
258
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
259
+ const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
260
+ // Force the express-level error path: make connectStatelessTransport
261
+ // reject so the request handler hits its try/catch and calls next(error),
262
+ // which lands in the default /mcp error handler.
263
+ vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
188
264
  const httpServer = http.createServer();
189
- const app = await createApp({ mcpServer: fakeServer, httpServer });
190
- const { port, server } = await listen(app);
191
- openServer = server;
265
+ const app = await createApp({ mcpServer, httpServer });
266
+ const { port, server: httpListening } = await listen(app);
267
+ openServer = httpListening;
192
268
  const res = await postMcp(port);
193
269
  expect(res.status).toBe(500);
194
270
  expect(await res.json()).toEqual({
@@ -206,14 +282,16 @@ describe("createApp", () => {
206
282
  calls.push("error-handler");
207
283
  res.status(503).json({ custom: true });
208
284
  };
285
+ const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
286
+ vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
209
287
  const httpServer = http.createServer();
210
288
  const app = await createApp({
211
- mcpServer: fakeServer,
289
+ mcpServer,
212
290
  httpServer,
213
291
  errorMiddleware: [{ handlers: [errorHandler] }],
214
292
  });
215
- const { port, server } = await listen(app);
216
- openServer = server;
293
+ const { port, server: httpListening } = await listen(app);
294
+ openServer = httpListening;
217
295
  const res = await postMcp(port);
218
296
  expect(calls).toEqual(["error-handler"]);
219
297
  expect(res.status).toBe(503);
@@ -229,15 +307,17 @@ describe("createApp", () => {
229
307
  const throwingApiRoute = (_req, _res, next) => {
230
308
  next(new Error("api error"));
231
309
  };
310
+ const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
311
+ vi.spyOn(mcpServer, "connectStatelessTransport").mockRejectedValue(new Error("boom"));
312
+ mcpServer.use("/api/test", throwingApiRoute);
232
313
  const httpServer = http.createServer();
233
314
  const app = await createApp({
234
- mcpServer: fakeServer,
315
+ mcpServer,
235
316
  httpServer,
236
- customMiddleware: [{ path: "/api/test", handlers: [throwingApiRoute] }],
237
317
  errorMiddleware: [{ path: "/mcp", handlers: [mcpErrorHandler] }],
238
318
  });
239
- const { port, server } = await listen(app);
240
- openServer = server;
319
+ const { port, server: httpListening } = await listen(app);
320
+ openServer = httpListening;
241
321
  const mcpRes = await postMcp(port);
242
322
  expect(calls).toEqual(["mcp-error-handler"]);
243
323
  expect(mcpRes.status).toBe(503);
@@ -248,5 +328,103 @@ describe("createApp", () => {
248
328
  expect(apiRes.status).toBe(500);
249
329
  consoleSpy.mockRestore();
250
330
  });
331
+ it("handles concurrent /mcp requests without 'Already connected to a transport'", async () => {
332
+ const { createApp } = await import("./express.js");
333
+ const mcpServer = new McpServer({
334
+ name: "concurrent-test",
335
+ version: "0.0.0",
336
+ });
337
+ // Slow tool: keeps the underlying transport bound long enough to overlap
338
+ // with concurrent requests, exposing the shared-McpServer race.
339
+ mcpServer.registerTool({ name: "slow", description: "slow" }, async () => {
340
+ await new Promise((r) => setTimeout(r, 50));
341
+ return { content: [{ type: "text", text: "done" }] };
342
+ });
343
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
344
+ const httpServer = http.createServer();
345
+ const app = await createApp({ mcpServer, httpServer });
346
+ const { port, server } = await listen(app);
347
+ openServer = server;
348
+ const callBody = (id) => JSON.stringify({
349
+ jsonrpc: "2.0",
350
+ method: "tools/call",
351
+ id,
352
+ params: { name: "slow", arguments: {} },
353
+ });
354
+ const N = 10;
355
+ const responses = await Promise.all(Array.from({ length: N }, (_, i) => fetch(`http://localhost:${port}/mcp`, {
356
+ method: "POST",
357
+ headers: {
358
+ "Content-Type": "application/json",
359
+ Accept: "application/json, text/event-stream",
360
+ },
361
+ body: callBody(i + 1),
362
+ })));
363
+ expect(responses.map((r) => r.status)).toEqual(Array(N).fill(200));
364
+ expect(consoleSpy).not.toHaveBeenCalledWith("Error handling MCP request:", expect.any(Error));
365
+ consoleSpy.mockRestore();
366
+ });
367
+ });
368
+ describe("createApp tunnel routes", () => {
369
+ it("proxies POST /__skybridge/tunnel to the cli control server in dev mode", async () => {
370
+ // Stand up a fake control listener that returns a known JSON body.
371
+ const control = http.createServer((_req, res) => {
372
+ res.writeHead(200, { "Content-Type": "application/json" });
373
+ res.end('{"status":"idle"}');
374
+ });
375
+ await new Promise((resolve) => control.listen(0, "127.0.0.1", resolve));
376
+ const controlAddr = control.address();
377
+ if (typeof controlAddr === "string" || controlAddr === null) {
378
+ control.close();
379
+ throw new Error("control server has no address");
380
+ }
381
+ const controlPort = controlAddr.port;
382
+ const prev = process.env.__TUNNEL_CONTROL_PORT;
383
+ process.env.__TUNNEL_CONTROL_PORT = String(controlPort);
384
+ try {
385
+ const { createApp } = await import("./express.js");
386
+ const mcpServer = new McpServer({ name: "t", version: "0.0.0" });
387
+ const httpServer = http.createServer();
388
+ const app = await createApp({ mcpServer, httpServer });
389
+ const { port, server } = await listen(app);
390
+ openServer = server;
391
+ const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
392
+ method: "POST",
393
+ });
394
+ expect(res.status).toBe(200);
395
+ expect(await res.json()).toEqual({ status: "idle" });
396
+ }
397
+ finally {
398
+ if (prev === undefined) {
399
+ delete process.env.__TUNNEL_CONTROL_PORT;
400
+ }
401
+ else {
402
+ process.env.__TUNNEL_CONTROL_PORT = prev;
403
+ }
404
+ await new Promise((resolve) => control.close(() => resolve()));
405
+ }
406
+ });
407
+ it("does not expose /__skybridge/tunnel in production mode", async () => {
408
+ const prevEnv = process.env.NODE_ENV;
409
+ process.env.NODE_ENV = "production";
410
+ try {
411
+ vi.resetModules();
412
+ const { createApp } = await import("./express.js");
413
+ const { McpServer: ReloadedMcpServer } = await import("./server.js");
414
+ const mcpServer = new ReloadedMcpServer({ name: "t", version: "0.0.0" });
415
+ const httpServer = http.createServer();
416
+ const app = await createApp({ mcpServer, httpServer });
417
+ const { port, server } = await listen(app);
418
+ openServer = server;
419
+ const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {
420
+ method: "POST",
421
+ });
422
+ expect(res.status).toBe(404);
423
+ }
424
+ finally {
425
+ process.env.NODE_ENV = prevEnv;
426
+ vi.resetModules();
427
+ }
428
+ });
251
429
  });
252
430
  //# sourceMappingURL=express.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"express.test.js","sourceRoot":"","sources":["../../src/server/express.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"express.test.js","sourceRoot":"","sources":["../../src/server/express.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,CAAC;IACpC,oBAAoB,EAAE,GAAG,EAAE,CACzB,CAAC,CAAC,IAAa,EAAE,IAAa,EAAE,IAAgB,EAAE,EAAE,CAClD,IAAI,EAAE,CAAmB;CAC9B,CAAC,CAAC,CAAC;AAEJ,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE,CAAC,CAAC;IACpC,cAAc,EAAE,CAAC,WAAoB,EAAE,EAAE,CACvC,CAAC,CAAC,IAAa,EAAE,IAAa,EAAE,IAAgB,EAAE,EAAE,CAClD,IAAI,EAAE,CAAmB;CAC9B,CAAC,CAAC,CAAC;AAEJ,KAAK,UAAU,MAAM,CAAC,GAA4C;IAChE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAChE,MAAM,IAAI,GAAI,MAAM,CAAC,OAAO,EAAuB,CAAC,IAAI,CAAC;IACzD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC;AAED,IAAI,UAAmC,CAAC;AACxC,SAAS,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;AAErC,KAAK,UAAU,OAAO,CAAC,IAAY;IACjC,OAAO,KAAK,CAAC,oBAAoB,IAAI,MAAM,EAAE;QAC3C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;KACtE,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,IAAY;IACjC,OAAO,KAAK,CAAC,oBAAoB,IAAI,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,MAAM,CAAC,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC1C,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QACnD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjE,UAAU,GAAG,SAAS,CAAC;QAEvB,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,SAAS,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAEtD,mDAAmD;QACnD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAEzE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;QACzB,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC1B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAClC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,WAAW,EAAE,CAAC;QACzB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAClC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC1B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;QAEH,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC;YACzB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YACvC,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;YAC9C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAC5D,UAAU,GAAG,SAAS,CAAC;YACvB,MAAM,KAAK,CAAC,oBAAoB,IAAI,QAAQ,CAAC,CAAC;YAC9C,SAAS,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;QAED,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;QACpF,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,wEAAwE;QACxE,8CAA8C;QAC9C,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;YAC3C,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACxB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,8DAA8D;QAC9D,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC,iBAAiB,CAC7D,IAAI,KAAK,CAAC,MAAM,CAAC,CAClB,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,SAAS,CAAC;YACd,SAAS,EAAE,MAAM;YACjB,UAAU;YACV,sEAAsE;YACtE,+CAA+C;YAC/C,0GAA0G;YAC1G,eAAe,EAAE,MAAM,CAAC,uBAAuB,CAAC;SACjD,CAAC,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjE,UAAU,GAAG,SAAS,CAAC;QAEvB,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,EAAE,GAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC9C,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEf,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAE/D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,EAAE,GAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC9C,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACnB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAEvB,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAE/D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,MAAM,GAAmB,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3C,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAClD,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAE3B,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAE/D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,GAAG,GAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC/C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QACF,MAAM,GAAG,GAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC/C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEhB,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAE/D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,KAAK,GAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YACjD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClB,IAAI,EAAE,CAAC;QACT,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAE/D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,iDAAiD;QACjD,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAClC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,MAAwB,CAAC,CAAC;QAErC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAE/D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,SAAS,CAAC,CAAC;QAC3D,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAChC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAwB,CAAC,CAAC;QAE7C,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAE/D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,WAAW,CAAC,CAAC;QAC7D,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAEnD,MAAM,QAAQ,GAAmB,GAAG,EAAE;YACpC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAEjC,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAE/D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,UAAU,CAAC,CAAC;QAC5D,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE7B,8DAA8D;QAC9D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,UAAU,CAAC,CAAC;QACjE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;QAC5G,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAE3E,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACjE,qEAAqE;QACrE,0EAA0E;QAC1E,iDAAiD;QACjD,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,2BAA2B,CAAC,CAAC,iBAAiB,CAChE,IAAI,KAAK,CAAC,MAAM,CAAC,CAClB,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;QACvD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC;YAC/B,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE;YACzD,EAAE,EAAE,IAAI;SACT,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CACrC,6BAA6B,EAC7B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAClB,CAAC;QACF,UAAU,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,YAAY,GAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;YACnE,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC5B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACjE,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,2BAA2B,CAAC,CAAC,iBAAiB,CAChE,IAAI,KAAK,CAAC,MAAM,CAAC,CAClB,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC;YAC1B,SAAS;YACT,UAAU;YACV,eAAe,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC;SAChD,CAAC,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,eAAe,GAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;YACtE,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAChC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC;QAEF,MAAM,gBAAgB,GAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;YAC5D,IAAI,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;QAC/B,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACjE,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,2BAA2B,CAAC,CAAC,iBAAiB,CAChE,IAAI,KAAK,CAAC,MAAM,CAAC,CAClB,CAAC;QACF,SAAS,CAAC,GAAG,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;QAE7C,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC;YAC1B,SAAS;YACT,UAAU;YACV,eAAe,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC;SACjE,CAAC,CAAC;QACH,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1D,UAAU,GAAG,aAAa,CAAC;QAE3B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAEnE,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,UAAU,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;QAC3F,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAEnD,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC;YAC9B,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QACH,yEAAyE;QACzE,gEAAgE;QAChE,SAAS,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAC5C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAE3E,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;QACvD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3C,UAAU,GAAG,MAAM,CAAC;QAEpB,MAAM,QAAQ,GAAG,CAAC,EAAU,EAAE,EAAE,CAC9B,IAAI,CAAC,SAAS,CAAC;YACb,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,YAAY;YACpB,EAAE;YACF,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE;SACxC,CAAC,CAAC;QAEL,MAAM,CAAC,GAAG,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACjC,KAAK,CAAC,oBAAoB,IAAI,MAAM,EAAE;YACpC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,MAAM,EAAE,qCAAqC;aAC9C;YACD,IAAI,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;SACtB,CAAC,CACH,CACF,CAAC;QAEF,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACnE,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,oBAAoB,CACzC,6BAA6B,EAC7B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAClB,CAAC;QACF,UAAU,CAAC,WAAW,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,mEAAmE;QACnE,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC9C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAClC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,CACxC,CAAC;QACF,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QACtC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YAC5D,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC;QAErC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YACnD,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACjE,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;YACvD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3C,UAAU,GAAG,MAAM,CAAC;YAEpB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,qBAAqB,EAAE;gBACrE,MAAM,EAAE,MAAM;aACf,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;gBAAS,CAAC;YACT,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;YAC3C,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,IAAI,CAAC;YAC3C,CAAC;YACD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,YAAY,CAAC;QACpC,IAAI,CAAC;YACH,EAAE,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YACnD,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACrE,MAAM,SAAS,GAAG,IAAI,iBAAiB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YACzE,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;YACvD,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC;YAC3C,UAAU,GAAG,MAAM,CAAC;YAEpB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,qBAAqB,EAAE;gBACrE,MAAM,EAAE,MAAM;aACf,CAAC,CAAC;YACH,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC;YAC/B,EAAE,CAAC,YAAY,EAAE,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import http from \"node:http\";\nimport type { ErrorRequestHandler, RequestHandler } from \"express\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { McpServer } from \"./server.js\";\n\nvi.mock(\"@skybridge/devtools\", () => ({\n devtoolsStaticServer: () =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\n\nvi.mock(\"./viewsDevServer.js\", () => ({\n viewsDevServer: (_httpServer: unknown) =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\n\nasync function listen(app: Parameters<typeof http.createServer>[1]) {\n const server = http.createServer(app);\n await new Promise<void>((resolve) => server.listen(0, resolve));\n const port = (server.address() as { port: number }).port;\n return { port, server };\n}\n\nlet openServer: http.Server | undefined;\nafterEach(() => openServer?.close());\n\nasync function postMcp(port: number) {\n return fetch(`http://localhost:${port}/mcp`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ jsonrpc: \"2.0\", method: \"initialize\", id: 1 }),\n });\n}\n\nasync function postApi(port: number) {\n return fetch(`http://localhost:${port}/api/test`, { method: \"POST\" });\n}\n\ndescribe(\"McpServer.express\", () => {\n it(\"exposes a ready Express app immediately after construction\", () => {\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n expect(server.express).toBeDefined();\n expect(typeof server.express.use).toBe(\"function\");\n expect(typeof server.express.get).toBe(\"function\");\n });\n\n it(\"server.express.get registers a route reachable alongside /mcp\", async () => {\n const { createApp } = await import(\"./express.js\");\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.express.get(\"/health\", (_req, res) => {\n res.json({ status: \"ok\" });\n });\n\n const httpServer = http.createServer();\n await createApp({ mcpServer: server, httpServer });\n const { port, server: listening } = await listen(server.express);\n openServer = listening;\n\n const health = await fetch(`http://localhost:${port}/health`);\n expect(health.status).toBe(200);\n expect(await health.json()).toEqual({ status: \"ok\" });\n\n // /mcp still works (POST returns 200/4xx, not 404)\n const mcp = await postMcp(port);\n expect(mcp.status).not.toBe(404);\n });\n\n it(\"server.use and server.express.use produce the same registration order\", async () => {\n const { createApp } = await import(\"./express.js\");\n const callsA: string[] = [];\n const callsB: string[] = [];\n\n const buildServer = () => new McpServer({ name: \"t\", version: \"0.0.0\" });\n\n const sA = buildServer();\n sA.use((_req, _res, next) => {\n callsA.push(\"first\");\n next();\n });\n sA.express.use((_req, _res, next) => {\n callsA.push(\"second\");\n next();\n });\n\n const sB = buildServer();\n sB.express.use((_req, _res, next) => {\n callsB.push(\"first\");\n next();\n });\n sB.use((_req, _res, next) => {\n callsB.push(\"second\");\n next();\n });\n\n for (const s of [sA, sB]) {\n s.express.get(\"/probe\", (_req, res) => res.json({ ok: true }));\n const httpServer = http.createServer();\n await createApp({ mcpServer: s, httpServer });\n const { port, server: listening } = await listen(s.express);\n openServer = listening;\n await fetch(`http://localhost:${port}/probe`);\n listening.close();\n }\n\n expect(callsA).toEqual([\"first\", \"second\"]);\n expect(callsB).toEqual([\"first\", \"second\"]);\n });\n\n it(\"useOnError still wraps thrown /mcp errors after the route is mounted\", async () => {\n const { createApp } = await import(\"./express.js\");\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n // Register the error handler BEFORE createApp — useOnError should still\n // apply it after /mcp, so /mcp errors hit it.\n const seen: string[] = [];\n server.useOnError((_err, _req, res, _next) => {\n seen.push(\"useOnError\");\n res.status(503).json({ from: \"useOnError\" });\n });\n\n // Force the /mcp handler to throw so the error pipeline runs.\n vi.spyOn(server, \"connectStatelessTransport\").mockRejectedValue(\n new Error(\"boom\"),\n );\n\n const httpServer = http.createServer();\n await createApp({\n mcpServer: server,\n httpServer,\n // Mirror what run() does: forward the McpServer's useOnError handlers\n // to createApp so they get applied after /mcp.\n // biome-ignore lint/complexity/useLiteralKeys: test mirrors run() internals to verify useOnError ordering\n errorMiddleware: server[\"customErrorMiddleware\"],\n });\n const { port, server: listening } = await listen(server.express);\n openServer = listening;\n\n const res = await postMcp(port);\n expect(seen).toEqual([\"useOnError\"]);\n expect(res.status).toBe(503);\n expect(await res.json()).toEqual({ from: \"useOnError\" });\n });\n});\n\ndescribe(\"createApp\", () => {\n it(\"runs global custom middleware before the /mcp handler\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const mw: RequestHandler = (_req, _res, next) => {\n calls.push(\"custom\");\n next();\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(mw);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n await postMcp(port);\n expect(calls).toEqual([\"custom\"]);\n });\n\n it(\"runs path-scoped middleware on /mcp\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const mw: RequestHandler = (_req, _res, next) => {\n calls.push(\"auth\");\n next();\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/mcp\", mw);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n await postMcp(port);\n expect(calls).toEqual([\"auth\"]);\n });\n\n it(\"allows middleware to short-circuit with 401\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const reject: RequestHandler = (_req, res) => {\n calls.push(\"reject\");\n res.status(401).json({ error: \"Unauthorized\" });\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/mcp\", reject);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await postMcp(port);\n expect(calls).toEqual([\"reject\"]);\n expect(res.status).toBe(401);\n expect(await res.json()).toEqual({ error: \"Unauthorized\" });\n });\n\n it(\"runs multiple global middleware in registration order\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const mwA: RequestHandler = (_req, _res, next) => {\n calls.push(\"A\");\n next();\n };\n const mwB: RequestHandler = (_req, _res, next) => {\n calls.push(\"B\");\n next();\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(mwA);\n server.use(mwB);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n await postMcp(port);\n expect(calls).toEqual([\"A\", \"B\"]);\n });\n\n it(\"path-scoped middleware does not run on non-matching paths\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const apiMw: RequestHandler = (_req, _res, next) => {\n calls.push(\"api\");\n next();\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/api\", apiMw);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n // Hit /mcp — the /api middleware should NOT fire\n await postMcp(port);\n expect(calls).toEqual([]);\n });\n\n it(\"supports Express Router via custom middleware\", async () => {\n const { createApp } = await import(\"./express.js\");\n const { Router } = await import(\"express\");\n\n const router = Router();\n router.get(\"/health\", (_req, res) => {\n res.json({ status: \"ok\" });\n });\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(router as RequestHandler);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await fetch(`http://localhost:${port}/health`);\n expect(res.status).toBe(200);\n expect(await res.json()).toEqual({ status: \"ok\" });\n });\n\n it(\"supports path-prefixed Router\", async () => {\n const { createApp } = await import(\"./express.js\");\n const { Router } = await import(\"express\");\n\n const router = Router();\n router.get(\"/data\", (_req, res) => {\n res.json({ value: 42 });\n });\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/api\", router as RequestHandler);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await fetch(`http://localhost:${port}/api/data`);\n expect(res.status).toBe(200);\n expect(await res.json()).toEqual({ value: 42 });\n });\n\n it(\"server survives middleware errors without crashing\", async () => {\n const { createApp } = await import(\"./express.js\");\n\n const throwing: RequestHandler = () => {\n throw new Error(\"boom\");\n };\n\n const server = new McpServer({ name: \"t\", version: \"0.0.0\" });\n server.use(\"/explode\", throwing);\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer: server, httpServer });\n\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await fetch(`http://localhost:${port}/explode`);\n expect(res.status).toBe(500);\n\n // Server process did not crash — it still accepts connections\n const followUp = await fetch(`http://localhost:${port}/explode`);\n expect(followUp.status).toBe(500);\n });\n\n it(\"returns 500 JSON-RPC error when the MCP handler throws and no error middleware is registered\", async () => {\n const { createApp } = await import(\"./express.js\");\n const consoleSpy = vi.spyOn(console, \"error\").mockImplementation(() => {});\n\n const mcpServer = new McpServer({ name: \"t\", version: \"0.0.0\" });\n // Force the express-level error path: make connectStatelessTransport\n // reject so the request handler hits its try/catch and calls next(error),\n // which lands in the default /mcp error handler.\n vi.spyOn(mcpServer, \"connectStatelessTransport\").mockRejectedValue(\n new Error(\"boom\"),\n );\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer, httpServer });\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await postMcp(port);\n expect(res.status).toBe(500);\n expect(await res.json()).toEqual({\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Internal server error\" },\n id: null,\n });\n expect(consoleSpy).toHaveBeenCalledWith(\n \"Error handling MCP request:\",\n expect.any(Error),\n );\n consoleSpy.mockRestore();\n });\n\n it(\"invokes a custom error handler when the MCP handler throws\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const errorHandler: ErrorRequestHandler = (_err, _req, res, _next) => {\n calls.push(\"error-handler\");\n res.status(503).json({ custom: true });\n };\n\n const mcpServer = new McpServer({ name: \"t\", version: \"0.0.0\" });\n vi.spyOn(mcpServer, \"connectStatelessTransport\").mockRejectedValue(\n new Error(\"boom\"),\n );\n\n const httpServer = http.createServer();\n const app = await createApp({\n mcpServer,\n httpServer,\n errorMiddleware: [{ handlers: [errorHandler] }],\n });\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const res = await postMcp(port);\n expect(calls).toEqual([\"error-handler\"]);\n expect(res.status).toBe(503);\n expect(await res.json()).toEqual({ custom: true });\n });\n\n it(\"invokes a path-scoped error handler only for matching routes\", async () => {\n const { createApp } = await import(\"./express.js\");\n const calls: string[] = [];\n\n const mcpErrorHandler: ErrorRequestHandler = (_err, _req, res, _next) => {\n calls.push(\"mcp-error-handler\");\n res.status(503).json({ from: \"mcp-error-handler\" });\n };\n\n const throwingApiRoute: RequestHandler = (_req, _res, next) => {\n next(new Error(\"api error\"));\n };\n\n const mcpServer = new McpServer({ name: \"t\", version: \"0.0.0\" });\n vi.spyOn(mcpServer, \"connectStatelessTransport\").mockRejectedValue(\n new Error(\"boom\"),\n );\n mcpServer.use(\"/api/test\", throwingApiRoute);\n\n const httpServer = http.createServer();\n const app = await createApp({\n mcpServer,\n httpServer,\n errorMiddleware: [{ path: \"/mcp\", handlers: [mcpErrorHandler] }],\n });\n const { port, server: httpListening } = await listen(app);\n openServer = httpListening;\n\n const mcpRes = await postMcp(port);\n expect(calls).toEqual([\"mcp-error-handler\"]);\n expect(mcpRes.status).toBe(503);\n expect(await mcpRes.json()).toEqual({ from: \"mcp-error-handler\" });\n\n const consoleSpy = vi.spyOn(console, \"error\").mockImplementation(() => {});\n const apiRes = await postApi(port);\n expect(calls).toEqual([\"mcp-error-handler\"]);\n expect(apiRes.status).toBe(500);\n consoleSpy.mockRestore();\n });\n\n it(\"handles concurrent /mcp requests without 'Already connected to a transport'\", async () => {\n const { createApp } = await import(\"./express.js\");\n\n const mcpServer = new McpServer({\n name: \"concurrent-test\",\n version: \"0.0.0\",\n });\n // Slow tool: keeps the underlying transport bound long enough to overlap\n // with concurrent requests, exposing the shared-McpServer race.\n mcpServer.registerTool({ name: \"slow\", description: \"slow\" }, async () => {\n await new Promise((r) => setTimeout(r, 50));\n return { content: [{ type: \"text\" as const, text: \"done\" }] };\n });\n\n const consoleSpy = vi.spyOn(console, \"error\").mockImplementation(() => {});\n\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer, httpServer });\n const { port, server } = await listen(app);\n openServer = server;\n\n const callBody = (id: number) =>\n JSON.stringify({\n jsonrpc: \"2.0\",\n method: \"tools/call\",\n id,\n params: { name: \"slow\", arguments: {} },\n });\n\n const N = 10;\n const responses = await Promise.all(\n Array.from({ length: N }, (_, i) =>\n fetch(`http://localhost:${port}/mcp`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json, text/event-stream\",\n },\n body: callBody(i + 1),\n }),\n ),\n );\n\n expect(responses.map((r) => r.status)).toEqual(Array(N).fill(200));\n expect(consoleSpy).not.toHaveBeenCalledWith(\n \"Error handling MCP request:\",\n expect.any(Error),\n );\n consoleSpy.mockRestore();\n });\n});\n\ndescribe(\"createApp tunnel routes\", () => {\n it(\"proxies POST /__skybridge/tunnel to the cli control server in dev mode\", async () => {\n // Stand up a fake control listener that returns a known JSON body.\n const control = http.createServer((_req, res) => {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end('{\"status\":\"idle\"}');\n });\n await new Promise<void>((resolve) =>\n control.listen(0, \"127.0.0.1\", resolve),\n );\n const controlAddr = control.address();\n if (typeof controlAddr === \"string\" || controlAddr === null) {\n control.close();\n throw new Error(\"control server has no address\");\n }\n const controlPort = controlAddr.port;\n\n const prev = process.env.__TUNNEL_CONTROL_PORT;\n process.env.__TUNNEL_CONTROL_PORT = String(controlPort);\n try {\n const { createApp } = await import(\"./express.js\");\n const mcpServer = new McpServer({ name: \"t\", version: \"0.0.0\" });\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer, httpServer });\n const { port, server } = await listen(app);\n openServer = server;\n\n const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {\n method: \"POST\",\n });\n expect(res.status).toBe(200);\n expect(await res.json()).toEqual({ status: \"idle\" });\n } finally {\n if (prev === undefined) {\n delete process.env.__TUNNEL_CONTROL_PORT;\n } else {\n process.env.__TUNNEL_CONTROL_PORT = prev;\n }\n await new Promise<void>((resolve) => control.close(() => resolve()));\n }\n });\n\n it(\"does not expose /__skybridge/tunnel in production mode\", async () => {\n const prevEnv = process.env.NODE_ENV;\n process.env.NODE_ENV = \"production\";\n try {\n vi.resetModules();\n const { createApp } = await import(\"./express.js\");\n const { McpServer: ReloadedMcpServer } = await import(\"./server.js\");\n const mcpServer = new ReloadedMcpServer({ name: \"t\", version: \"0.0.0\" });\n const httpServer = http.createServer();\n const app = await createApp({ mcpServer, httpServer });\n const { port, server } = await listen(app);\n openServer = server;\n\n const res = await fetch(`http://localhost:${port}/__skybridge/tunnel`, {\n method: \"POST\",\n });\n expect(res.status).toBe(404);\n } finally {\n process.env.NODE_ENV = prevEnv;\n vi.resetModules();\n }\n });\n});\n"]}
@@ -1,5 +1,6 @@
1
+ export { audio, embeddedResource, image, resourceLink, text, } from "./content-helpers.js";
1
2
  export type { AnyToolRegistry, InferTools, ToolInput, ToolNames, ToolOutput, ToolResponseMetadata, } from "./inferUtilityTypes.js";
2
3
  export type { McpExtra, McpMethodString, McpMiddlewareFilter, McpMiddlewareFn, McpResultFor, McpTypedMiddlewareFn, McpWildcard, } from "./middleware.js";
3
- export type { McpServerTypes, ToolDef, WidgetHostType } from "./server.js";
4
- export { McpServer } from "./server.js";
5
- export { widgetsDevServer } from "./widgetsDevServer.js";
4
+ export type { HandlerContent, KnownToolMeta, McpServerTypes, ToolDef, ToolMeta, ViewConfig, ViewCsp, ViewHostType, ViewName, ViewNameRegistry, } from "./server.js";
5
+ export { McpServer, normalizeContent, } from "./server.js";
6
+ export { viewsDevServer } from "./viewsDevServer.js";
@@ -1,3 +1,4 @@
1
- export { McpServer } from "./server.js";
2
- export { widgetsDevServer } from "./widgetsDevServer.js";
1
+ export { audio, embeddedResource, image, resourceLink, text, } from "./content-helpers.js";
2
+ export { McpServer, normalizeContent, } from "./server.js";
3
+ export { viewsDevServer } from "./viewsDevServer.js";
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,gBAAgB,EAChB,KAAK,EACL,YAAY,EACZ,IAAI,GACL,MAAM,sBAAsB,CAAC;AA8B9B,OAAO,EACL,SAAS,EACT,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC","sourcesContent":["export {\n audio,\n embeddedResource,\n image,\n resourceLink,\n text,\n} from \"./content-helpers.js\";\nexport type {\n AnyToolRegistry,\n InferTools,\n ToolInput,\n ToolNames,\n ToolOutput,\n ToolResponseMetadata,\n} from \"./inferUtilityTypes.js\";\nexport type {\n McpExtra,\n McpMethodString,\n McpMiddlewareFilter,\n McpMiddlewareFn,\n McpResultFor,\n McpTypedMiddlewareFn,\n McpWildcard,\n} from \"./middleware.js\";\nexport type {\n HandlerContent,\n KnownToolMeta,\n McpServerTypes,\n ToolDef,\n ToolMeta,\n ViewConfig,\n ViewCsp,\n ViewHostType,\n ViewName,\n ViewNameRegistry,\n} from \"./server.js\";\nexport {\n McpServer,\n normalizeContent,\n} from \"./server.js\";\nexport { viewsDevServer } from \"./viewsDevServer.js\";\n"]}
@@ -1,12 +1,12 @@
1
1
  import type { McpServerTypes, ToolDef } from "./server.js";
2
2
  /**
3
- * Any tool registry shape (includes both widgets and regular tools).
3
+ * Any tool registry shape (includes both views and regular tools).
4
4
  * Used as a constraint for type parameters that accept tool registries.
5
5
  */
6
6
  export type AnyToolRegistry = Record<string, ToolDef>;
7
7
  /**
8
8
  * Extract the tool registry type from an McpServer instance.
9
- * This includes both widgets (registered via widget()) and regular tools (registered via registerTool()).
9
+ * This includes both views (registered via view()) and regular tools (registered via registerTool()).
10
10
  *
11
11
  * Uses the `$types` property pattern for cross-package type inference.
12
12
  * This works across package boundaries because TypeScript uses structural typing
@@ -24,7 +24,7 @@ export type InferTools<ServerType> = ServerType extends {
24
24
  type ExtractTool<ServerType, K extends ToolNames<ServerType>> = InferTools<ServerType>[K];
25
25
  /**
26
26
  * Get a union of all tool names from an McpServer instance.
27
- * This includes both widgets and regular tools.
27
+ * This includes both views and regular tools.
28
28
  *
29
29
  * @example
30
30
  * ```ts
@@ -34,7 +34,7 @@ type ExtractTool<ServerType, K extends ToolNames<ServerType>> = InferTools<Serve
34
34
  */
35
35
  export type ToolNames<ServerType> = keyof InferTools<ServerType> & string;
36
36
  /**
37
- * Get the input type for a specific tool (widget or regular tool).
37
+ * Get the input type for a specific tool (view or regular tool).
38
38
  *
39
39
  * @example
40
40
  * ```ts
@@ -43,7 +43,7 @@ export type ToolNames<ServerType> = keyof InferTools<ServerType> & string;
43
43
  */
44
44
  export type ToolInput<ServerType, ToolName extends ToolNames<ServerType>> = ExtractTool<ServerType, ToolName>["input"];
45
45
  /**
46
- * Get the output type for a specific tool (widget or regular tool).
46
+ * Get the output type for a specific tool (view or regular tool).
47
47
  *
48
48
  * @example
49
49
  * ```ts
@@ -52,7 +52,7 @@ export type ToolInput<ServerType, ToolName extends ToolNames<ServerType>> = Extr
52
52
  */
53
53
  export type ToolOutput<ServerType, ToolName extends ToolNames<ServerType>> = ExtractTool<ServerType, ToolName>["output"];
54
54
  /**
55
- * Get the responseMetadata type for a specific tool (widget or regular tool).
55
+ * Get the responseMetadata type for a specific tool (view or regular tool).
56
56
  * This is inferred from the `_meta` property of the tool callback's return value.
57
57
  *
58
58
  * @example
@@ -1 +1 @@
1
- {"version":3,"file":"inferUtilityTypes.js","sourceRoot":"","sources":["../../src/server/inferUtilityTypes.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"inferUtilityTypes.js","sourceRoot":"","sources":["../../src/server/inferUtilityTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { McpServerTypes, ToolDef } from \"./server.js\";\n\n/**\n * Any tool registry shape (includes both views and regular tools).\n * Used as a constraint for type parameters that accept tool registries.\n */\nexport type AnyToolRegistry = Record<string, ToolDef>;\n\n/**\n * Extract the tool registry type from an McpServer instance.\n * This includes both views (registered via view()) and regular tools (registered via registerTool()).\n *\n * Uses the `$types` property pattern for cross-package type inference.\n * This works across package boundaries because TypeScript uses structural typing\n * on the shape of `$types`, rather than nominal typing on the McpServer class itself.\n *\n * @example\n * ```ts\n * type MyTools = InferTools<MyServer>;\n * // { \"search\": ToolDef<...>, \"calculate\": ToolDef<...> }\n * ```\n */\nexport type InferTools<ServerType> = ServerType extends {\n $types: McpServerTypes<infer W>;\n}\n ? W\n : never;\ntype ExtractTool<\n ServerType,\n K extends ToolNames<ServerType>,\n> = InferTools<ServerType>[K];\n\n/**\n * Get a union of all tool names from an McpServer instance.\n * This includes both views and regular tools.\n *\n * @example\n * ```ts\n * type Names = ToolNames<MyServer>;\n * // \"search\" | \"calculate\" | \"details\"\n * ```\n */\nexport type ToolNames<ServerType> = keyof InferTools<ServerType> & string;\n\n/**\n * Get the input type for a specific tool (view or regular tool).\n *\n * @example\n * ```ts\n * type SearchInput = ToolInput<MyServer, \"search\">;\n * ```\n */\nexport type ToolInput<\n ServerType,\n ToolName extends ToolNames<ServerType>,\n> = ExtractTool<ServerType, ToolName>[\"input\"];\n\n/**\n * Get the output type for a specific tool (view or regular tool).\n *\n * @example\n * ```ts\n * type SearchOutput = ToolOutput<MyServer, \"search\">;\n * ```\n */\nexport type ToolOutput<\n ServerType,\n ToolName extends ToolNames<ServerType>,\n> = ExtractTool<ServerType, ToolName>[\"output\"];\n\n/**\n * Get the responseMetadata type for a specific tool (view or regular tool).\n * This is inferred from the `_meta` property of the tool callback's return value.\n *\n * @example\n * ```ts\n * type SearchMeta = ToolResponseMetadata<MyServer, \"search\">;\n * ```\n */\nexport type ToolResponseMetadata<\n ServerType,\n ToolName extends ToolNames<ServerType>,\n> = ExtractTool<ServerType, ToolName>[\"responseMetadata\"];\n"]}