skybridge 0.0.0-dev.d2cb8f6 → 0.0.0-dev.d33e6f5

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 (327) hide show
  1. package/README.md +15 -14
  2. package/dist/cli/build-helpers.d.ts +2 -2
  3. package/dist/cli/build-helpers.js +13 -5
  4. package/dist/cli/build-helpers.js.map +1 -1
  5. package/dist/cli/build-helpers.test.js +30 -4
  6. package/dist/cli/build-helpers.test.js.map +1 -1
  7. package/dist/cli/build-steps.js +17 -6
  8. package/dist/cli/build-steps.js.map +1 -1
  9. package/dist/cli/build-steps.test.js +23 -3
  10. package/dist/cli/build-steps.test.js.map +1 -1
  11. package/dist/cli/detect-port.js +0 -1
  12. package/dist/cli/detect-port.js.map +1 -1
  13. package/dist/cli/resolve-skybridge-config.d.ts +1 -0
  14. package/dist/cli/resolve-skybridge-config.js +11 -1
  15. package/dist/cli/resolve-skybridge-config.js.map +1 -1
  16. package/dist/cli/run-plain.js +2 -1
  17. package/dist/cli/run-plain.js.map +1 -1
  18. package/dist/cli/telemetry.js +2 -0
  19. package/dist/cli/telemetry.js.map +1 -1
  20. package/dist/cli/use-execute-steps.d.ts +1 -1
  21. package/dist/cli/use-nodemon.d.ts +11 -1
  22. package/dist/cli/use-nodemon.js +30 -8
  23. package/dist/cli/use-nodemon.js.map +1 -1
  24. package/dist/cli/use-typescript-check.js +3 -1
  25. package/dist/cli/use-typescript-check.js.map +1 -1
  26. package/dist/commands/dev.js +4 -4
  27. package/dist/commands/dev.js.map +1 -1
  28. package/dist/commands/start.js +2 -2
  29. package/dist/commands/start.js.map +1 -1
  30. package/dist/context-warnings.d.ts +5 -0
  31. package/dist/context-warnings.js +31 -0
  32. package/dist/context-warnings.js.map +1 -0
  33. package/dist/context-warnings.test.js +28 -0
  34. package/dist/context-warnings.test.js.map +1 -0
  35. package/dist/server/app.d.ts +211 -0
  36. package/dist/server/app.js +277 -0
  37. package/dist/server/app.js.map +1 -0
  38. package/dist/server/app.test.js +178 -0
  39. package/dist/server/app.test.js.map +1 -0
  40. package/dist/server/auth/discovery.d.ts +2 -1
  41. package/dist/server/auth/discovery.js +2 -2
  42. package/dist/server/auth/discovery.js.map +1 -1
  43. package/dist/server/auth/index.d.ts +35 -5
  44. package/dist/server/auth/index.js.map +1 -1
  45. package/dist/server/auth/providers/auth0.d.ts +25 -3
  46. package/dist/server/auth/providers/auth0.js +13 -8
  47. package/dist/server/auth/providers/auth0.js.map +1 -1
  48. package/dist/server/auth/providers/auth0.test.js +5 -3
  49. package/dist/server/auth/providers/auth0.test.js.map +1 -1
  50. package/dist/server/auth/providers/authplane.d.ts +4 -2
  51. package/dist/server/auth/providers/authplane.js.map +1 -1
  52. package/dist/server/auth/providers/authplane.test.js +23 -18
  53. package/dist/server/auth/providers/authplane.test.js.map +1 -1
  54. package/dist/server/auth/providers/clerk.d.ts +40 -3
  55. package/dist/server/auth/providers/clerk.js +4 -1
  56. package/dist/server/auth/providers/clerk.js.map +1 -1
  57. package/dist/server/auth/providers/clerk.test.js +5 -3
  58. package/dist/server/auth/providers/clerk.test.js.map +1 -1
  59. package/dist/server/auth/providers/custom.d.ts +16 -6
  60. package/dist/server/auth/providers/custom.js +14 -4
  61. package/dist/server/auth/providers/custom.js.map +1 -1
  62. package/dist/server/auth/providers/custom.test.js +24 -19
  63. package/dist/server/auth/providers/custom.test.js.map +1 -1
  64. package/dist/server/auth/providers/descope.d.ts +32 -3
  65. package/dist/server/auth/providers/descope.js.map +1 -1
  66. package/dist/server/auth/providers/descope.test.js +8 -6
  67. package/dist/server/auth/providers/descope.test.js.map +1 -1
  68. package/dist/server/auth/providers/stytch.d.ts +16 -3
  69. package/dist/server/auth/providers/stytch.js +4 -1
  70. package/dist/server/auth/providers/stytch.js.map +1 -1
  71. package/dist/server/auth/providers/verify-spy.d.ts +12 -0
  72. package/dist/server/auth/providers/verify-spy.js +21 -0
  73. package/dist/server/auth/providers/verify-spy.js.map +1 -0
  74. package/dist/server/auth/providers/workos.d.ts +28 -5
  75. package/dist/server/auth/providers/workos.js +6 -2
  76. package/dist/server/auth/providers/workos.js.map +1 -1
  77. package/dist/server/auth/setup.d.ts +1 -1
  78. package/dist/server/auth/setup.js +4 -5
  79. package/dist/server/auth/setup.js.map +1 -1
  80. package/dist/server/auth/setup.test.js +97 -57
  81. package/dist/server/auth/setup.test.js.map +1 -1
  82. package/dist/server/auth/verify.d.ts +42 -6
  83. package/dist/server/auth/verify.js +27 -3
  84. package/dist/server/auth/verify.js.map +1 -1
  85. package/dist/server/auth/verify.test.js +65 -0
  86. package/dist/server/auth/verify.test.js.map +1 -1
  87. package/dist/server/auth-extra.test-d.js +130 -0
  88. package/dist/server/auth-extra.test-d.js.map +1 -0
  89. package/dist/server/auth.d.ts +43 -6
  90. package/dist/server/auth.js +4 -5
  91. package/dist/server/auth.js.map +1 -1
  92. package/dist/server/build-manifest.test.js +7 -6
  93. package/dist/server/build-manifest.test.js.map +1 -1
  94. package/dist/server/content-helpers.d.ts +1 -1
  95. package/dist/server/content-helpers.js.map +1 -1
  96. package/dist/server/events.d.ts +113 -0
  97. package/dist/server/events.js +318 -0
  98. package/dist/server/events.js.map +1 -0
  99. package/dist/server/events.test.js +172 -0
  100. package/dist/server/events.test.js.map +1 -0
  101. package/dist/server/express.d.ts +24 -3
  102. package/dist/server/express.js +44 -32
  103. package/dist/server/express.js.map +1 -1
  104. package/dist/server/express.test.js +265 -103
  105. package/dist/server/express.test.js.map +1 -1
  106. package/dist/server/file-ref.d.ts +1 -1
  107. package/dist/server/file-ref.js +1 -1
  108. package/dist/server/file-ref.js.map +1 -1
  109. package/dist/server/form-input.d.ts +120 -0
  110. package/dist/server/form-input.js +89 -0
  111. package/dist/server/form-input.js.map +1 -0
  112. package/dist/server/index.d.ts +15 -8
  113. package/dist/server/index.js +8 -2
  114. package/dist/server/index.js.map +1 -1
  115. package/dist/server/mcp-errors.test.js +229 -0
  116. package/dist/server/mcp-errors.test.js.map +1 -0
  117. package/dist/server/metric.d.ts +5 -3
  118. package/dist/server/metric.js +5 -5
  119. package/dist/server/metric.js.map +1 -1
  120. package/dist/server/middleware.d.ts +35 -10
  121. package/dist/server/middleware.js +33 -0
  122. package/dist/server/middleware.js.map +1 -1
  123. package/dist/server/middleware.test-d.js +1 -1
  124. package/dist/server/middleware.test-d.js.map +1 -1
  125. package/dist/server/middleware.test.js +242 -134
  126. package/dist/server/middleware.test.js.map +1 -1
  127. package/dist/server/register-tool.test.js +230 -0
  128. package/dist/server/register-tool.test.js.map +1 -0
  129. package/dist/server/server.d.ts +338 -128
  130. package/dist/server/server.js +389 -305
  131. package/dist/server/server.js.map +1 -1
  132. package/dist/server/skills-integration.test.js +44 -21
  133. package/dist/server/skills-integration.test.js.map +1 -1
  134. package/dist/server/skills.d.ts +14 -10
  135. package/dist/server/skills.js +49 -39
  136. package/dist/server/skills.js.map +1 -1
  137. package/dist/server/skills.test.js +77 -44
  138. package/dist/server/skills.test.js.map +1 -1
  139. package/dist/server/templateHelper.d.ts +1 -3
  140. package/dist/server/templateHelper.js.map +1 -1
  141. package/dist/server/templates.generated.js +28 -18
  142. package/dist/server/templates.generated.js.map +1 -1
  143. package/dist/server/tool-extra.test.d.ts +1 -0
  144. package/dist/server/tool-extra.test.js +167 -0
  145. package/dist/server/tool-extra.test.js.map +1 -0
  146. package/dist/server/view-resource-resolution.test.js +53 -13
  147. package/dist/server/view-resource-resolution.test.js.map +1 -1
  148. package/dist/test/utils.d.ts +9 -11
  149. package/dist/test/utils.js +220 -201
  150. package/dist/test/utils.js.map +1 -1
  151. package/dist/test/view.test.js +41 -37
  152. package/dist/test/view.test.js.map +1 -1
  153. package/dist/views/index.d.ts +10 -0
  154. package/dist/views/index.js +3 -0
  155. package/dist/views/index.js.map +1 -0
  156. package/dist/{web/plugin → views}/scan-views.js +1 -1
  157. package/dist/views/scan-views.js.map +1 -0
  158. package/dist/views/scan-views.test.d.ts +1 -0
  159. package/dist/views/scan-views.test.js.map +1 -0
  160. package/dist/views/validate-view.d.ts +1 -0
  161. package/dist/{web/plugin → views}/validate-view.js +2 -2
  162. package/dist/views/validate-view.js.map +1 -0
  163. package/dist/views/validate-view.test.d.ts +1 -0
  164. package/dist/views/validate-view.test.js.map +1 -0
  165. package/dist/web/bridges/adaptor.d.ts +14 -3
  166. package/dist/web/bridges/adaptor.js +168 -29
  167. package/dist/web/bridges/adaptor.js.map +1 -1
  168. package/dist/web/bridges/adaptor.test.js +77 -9
  169. package/dist/web/bridges/adaptor.test.js.map +1 -1
  170. package/dist/web/bridges/apps-sdk/bridge.js +1 -1
  171. package/dist/web/bridges/apps-sdk/bridge.js.map +1 -1
  172. package/dist/web/bridges/apps-sdk/types.d.ts +3 -4
  173. package/dist/web/bridges/apps-sdk/types.js.map +1 -1
  174. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.d.ts +4 -4
  175. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js +4 -4
  176. package/dist/web/bridges/apps-sdk/use-apps-sdk-context.js.map +1 -1
  177. package/dist/web/bridges/get-adaptor.test.js +2 -2
  178. package/dist/web/bridges/get-adaptor.test.js.map +1 -1
  179. package/dist/web/bridges/mcp-app/bridge.d.ts +1 -1
  180. package/dist/web/bridges/mcp-app/bridge.js +10 -3
  181. package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
  182. package/dist/web/bridges/mcp-app/bridge.test.js +2 -2
  183. package/dist/web/bridges/mcp-app/bridge.test.js.map +1 -1
  184. package/dist/web/bridges/mcp-app/types.d.ts +18 -3
  185. package/dist/web/bridges/mcp-app/types.js.map +1 -1
  186. package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +2 -2
  187. package/dist/web/bridges/mcp-app/use-mcp-app-context.js +1 -1
  188. package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
  189. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -1
  190. package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
  191. package/dist/web/bridges/mcp-app/view-tools.test.js +1 -1
  192. package/dist/web/bridges/mcp-app/view-tools.test.js.map +1 -1
  193. package/dist/web/bridges/types.d.ts +74 -16
  194. package/dist/web/bridges/types.js +1 -1
  195. package/dist/web/bridges/types.js.map +1 -1
  196. package/dist/web/create-store.test.js +2 -2
  197. package/dist/web/create-store.test.js.map +1 -1
  198. package/dist/web/data-llm.js +3 -2
  199. package/dist/web/data-llm.js.map +1 -1
  200. package/dist/web/data-llm.test.js +11 -4
  201. package/dist/web/data-llm.test.js.map +1 -1
  202. package/dist/web/generate-helpers.d.ts +23 -19
  203. package/dist/web/generate-helpers.js +21 -17
  204. package/dist/web/generate-helpers.js.map +1 -1
  205. package/dist/web/generate-helpers.test-d.js +3 -3
  206. package/dist/web/generate-helpers.test-d.js.map +1 -1
  207. package/dist/web/generate-helpers.test.js +2 -2
  208. package/dist/web/generate-helpers.test.js.map +1 -1
  209. package/dist/web/hooks/index.d.ts +6 -2
  210. package/dist/web/hooks/index.js +6 -2
  211. package/dist/web/hooks/index.js.map +1 -1
  212. package/dist/web/hooks/openai-extensions.test.d.ts +1 -0
  213. package/dist/web/hooks/openai-extensions.test.js +107 -0
  214. package/dist/web/hooks/openai-extensions.test.js.map +1 -0
  215. package/dist/web/hooks/use-call-tool.d.ts +2 -2
  216. package/dist/web/hooks/use-call-tool.js +15 -10
  217. package/dist/web/hooks/use-call-tool.js.map +1 -1
  218. package/dist/web/hooks/use-call-tool.test.js +15 -4
  219. package/dist/web/hooks/use-call-tool.test.js.map +1 -1
  220. package/dist/web/hooks/use-deep-link.d.ts +22 -0
  221. package/dist/web/hooks/use-deep-link.js +34 -0
  222. package/dist/web/hooks/use-deep-link.js.map +1 -0
  223. package/dist/web/hooks/use-display-mode.d.ts +1 -1
  224. package/dist/web/hooks/use-display-mode.js +1 -1
  225. package/dist/web/hooks/use-display-mode.js.map +1 -1
  226. package/dist/web/hooks/use-display-mode.test.js +1 -1
  227. package/dist/web/hooks/use-display-mode.test.js.map +1 -1
  228. package/dist/web/hooks/use-download.d.ts +1 -3
  229. package/dist/web/hooks/use-download.js +1 -2
  230. package/dist/web/hooks/use-download.js.map +1 -1
  231. package/dist/web/hooks/use-download.test.js +7 -7
  232. package/dist/web/hooks/use-download.test.js.map +1 -1
  233. package/dist/web/hooks/use-file-resource.d.ts +37 -0
  234. package/dist/web/hooks/use-file-resource.js +98 -0
  235. package/dist/web/hooks/use-file-resource.js.map +1 -0
  236. package/dist/web/hooks/use-file-resource.test.d.ts +1 -0
  237. package/dist/web/hooks/use-file-resource.test.js +65 -0
  238. package/dist/web/hooks/use-file-resource.test.js.map +1 -0
  239. package/dist/web/hooks/use-files.test.js +1 -1
  240. package/dist/web/hooks/use-files.test.js.map +1 -1
  241. package/dist/web/hooks/use-host.d.ts +44 -0
  242. package/dist/web/hooks/use-host.js +45 -0
  243. package/dist/web/hooks/use-host.js.map +1 -0
  244. package/dist/web/hooks/use-host.test.d.ts +1 -0
  245. package/dist/web/hooks/{use-host-info.test.js → use-host.test.js} +7 -7
  246. package/dist/web/hooks/use-host.test.js.map +1 -0
  247. package/dist/web/hooks/use-model-context.d.ts +44 -0
  248. package/dist/web/hooks/use-model-context.js +63 -0
  249. package/dist/web/hooks/use-model-context.js.map +1 -0
  250. package/dist/web/hooks/use-open-external.test.js +2 -2
  251. package/dist/web/hooks/use-open-external.test.js.map +1 -1
  252. package/dist/web/hooks/use-open-file.d.ts +20 -0
  253. package/dist/web/hooks/use-open-file.js +25 -0
  254. package/dist/web/hooks/use-open-file.js.map +1 -0
  255. package/dist/web/hooks/use-register-view-tool.d.ts +3 -4
  256. package/dist/web/hooks/use-register-view-tool.js +1 -1
  257. package/dist/web/hooks/use-register-view-tool.js.map +1 -1
  258. package/dist/web/hooks/use-request-close.test.js +1 -1
  259. package/dist/web/hooks/use-request-close.test.js.map +1 -1
  260. package/dist/web/hooks/use-request-modal.test.js +1 -1
  261. package/dist/web/hooks/use-request-modal.test.js.map +1 -1
  262. package/dist/web/hooks/use-request-size.d.ts +1 -1
  263. package/dist/web/hooks/use-request-size.js +1 -1
  264. package/dist/web/hooks/use-request-size.js.map +1 -1
  265. package/dist/web/hooks/use-request-size.test.js +1 -1
  266. package/dist/web/hooks/use-request-size.test.js.map +1 -1
  267. package/dist/web/hooks/use-send-follow-up-message.d.ts +8 -2
  268. package/dist/web/hooks/use-send-follow-up-message.js +6 -0
  269. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -1
  270. package/dist/web/hooks/use-set-open-in-app-url.test.js +2 -8
  271. package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
  272. package/dist/web/hooks/use-tool-info.d.ts +1 -20
  273. package/dist/web/hooks/use-tool-info.js +0 -1
  274. package/dist/web/hooks/use-tool-info.js.map +1 -1
  275. package/dist/web/hooks/use-tool-info.test-d.js +0 -5
  276. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -1
  277. package/dist/web/hooks/use-tool-info.test.js +2 -7
  278. package/dist/web/hooks/use-tool-info.test.js.map +1 -1
  279. package/dist/web/hooks/use-user.d.ts +3 -2
  280. package/dist/web/hooks/use-user.js +4 -3
  281. package/dist/web/hooks/use-user.js.map +1 -1
  282. package/dist/web/hooks/use-user.test.js +5 -3
  283. package/dist/web/hooks/use-user.test.js.map +1 -1
  284. package/dist/web/hooks/use-view-state.test.js +2 -2
  285. package/dist/web/hooks/use-view-state.test.js.map +1 -1
  286. package/dist/web/hooks/use-viewport.d.ts +20 -0
  287. package/dist/web/hooks/use-viewport.js +21 -0
  288. package/dist/web/hooks/use-viewport.js.map +1 -0
  289. package/dist/web/hooks/use-viewport.test.d.ts +1 -0
  290. package/dist/web/hooks/{use-layout.test.js → use-viewport.test.js} +12 -32
  291. package/dist/web/hooks/use-viewport.test.js.map +1 -0
  292. package/dist/web/mount-view.d.ts +3 -2
  293. package/dist/web/mount-view.js +6 -11
  294. package/dist/web/mount-view.js.map +1 -1
  295. package/package.json +17 -13
  296. package/dist/web/hooks/use-host-info.d.ts +0 -22
  297. package/dist/web/hooks/use-host-info.js +0 -30
  298. package/dist/web/hooks/use-host-info.js.map +0 -1
  299. package/dist/web/hooks/use-host-info.test.js.map +0 -1
  300. package/dist/web/hooks/use-layout.d.ts +0 -24
  301. package/dist/web/hooks/use-layout.js +0 -25
  302. package/dist/web/hooks/use-layout.js.map +0 -1
  303. package/dist/web/hooks/use-layout.test.js.map +0 -1
  304. package/dist/web/plugin/data-llm.test.js +0 -81
  305. package/dist/web/plugin/data-llm.test.js.map +0 -1
  306. package/dist/web/plugin/plugin.d.ts +0 -39
  307. package/dist/web/plugin/plugin.js +0 -189
  308. package/dist/web/plugin/plugin.js.map +0 -1
  309. package/dist/web/plugin/scan-views.js.map +0 -1
  310. package/dist/web/plugin/scan-views.test.js.map +0 -1
  311. package/dist/web/plugin/transform-data-llm.d.ts +0 -12
  312. package/dist/web/plugin/transform-data-llm.js +0 -96
  313. package/dist/web/plugin/transform-data-llm.js.map +0 -1
  314. package/dist/web/plugin/transform-data-llm.test.js +0 -81
  315. package/dist/web/plugin/transform-data-llm.test.js.map +0 -1
  316. package/dist/web/plugin/validate-view.d.ts +0 -1
  317. package/dist/web/plugin/validate-view.js.map +0 -1
  318. package/dist/web/plugin/validate-view.test.js.map +0 -1
  319. /package/dist/{web/hooks/use-host-info.test.d.ts → context-warnings.test.d.ts} +0 -0
  320. /package/dist/{web/hooks/use-layout.test.d.ts → server/app.test.d.ts} +0 -0
  321. /package/dist/{web/plugin/data-llm.test.d.ts → server/auth-extra.test-d.d.ts} +0 -0
  322. /package/dist/{web/plugin/scan-views.test.d.ts → server/events.test.d.ts} +0 -0
  323. /package/dist/{web/plugin/transform-data-llm.test.d.ts → server/mcp-errors.test.d.ts} +0 -0
  324. /package/dist/{web/plugin/validate-view.test.d.ts → server/register-tool.test.d.ts} +0 -0
  325. /package/dist/{web/plugin → views}/scan-views.d.ts +0 -0
  326. /package/dist/{web/plugin → views}/scan-views.test.js +0 -0
  327. /package/dist/{web/plugin → views}/validate-view.test.js +0 -0
@@ -8,10 +8,8 @@ export const developmentTemplate = Handlebars.template({ "compiler": [8, ">= 4.3
8
8
  }
9
9
  return undefined;
10
10
  };
11
- return "<script type=\"module\">window.skybridge = { hostType: \""
12
- + alias4(((helper = (helper = lookupProperty(helpers, "hostType") || (depth0 != null ? lookupProperty(depth0, "hostType") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "hostType", "hash": {}, "data": data, "loc": { "start": { "line": 1, "column": 54 }, "end": { "line": 1, "column": 66 } } }) : helper)))
13
- + "\", serverUrl: \""
14
- + alias4(((helper = (helper = lookupProperty(helpers, "serverUrl") || (depth0 != null ? lookupProperty(depth0, "serverUrl") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "serverUrl", "hash": {}, "data": data, "loc": { "start": { "line": 1, "column": 81 }, "end": { "line": 1, "column": 94 } } }) : helper)))
11
+ return "<script type=\"module\">window.skybridge = { serverUrl: \""
12
+ + alias4(((helper = (helper = lookupProperty(helpers, "serverUrl") || (depth0 != null ? lookupProperty(depth0, "serverUrl") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "serverUrl", "hash": {}, "data": data, "loc": { "start": { "line": 1, "column": 55 }, "end": { "line": 1, "column": 68 } } }) : helper)))
15
13
  + "\" };</script>\n<script type=\"module\">\n import { injectIntoGlobalHook } from \""
16
14
  + alias4(((helper = (helper = lookupProperty(helpers, "serverUrl") || (depth0 != null ? lookupProperty(depth0, "serverUrl") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "serverUrl", "hash": {}, "data": data, "loc": { "start": { "line": 3, "column": 40 }, "end": { "line": 3, "column": 53 } } }) : helper)))
17
15
  + "/assets/@react-refresh\";\n injectIntoGlobalHook(window); window.$RefreshReg$ = () => {};\n window.$RefreshSig$ = () => (type) => type;\n window.__vite_plugin_react_preamble_installed__ = true;\n</script>\n<script type=\"module\" src=\""
@@ -23,25 +21,37 @@ export const developmentTemplate = Handlebars.template({ "compiler": [8, ">= 4.3
23
21
  + "');\n</script>";
24
22
  }, "useData": true });
25
23
  /** @type {HandlebarsTemplateDelegate} */
26
- export const productionTemplate = Handlebars.template({ "compiler": [8, ">= 4.3.0"], "main": function (container, depth0, helpers, partials, data) {
27
- var helper, alias1 = depth0 != null ? depth0 : (container.nullContext || {}), alias2 = container.hooks.helperMissing, alias3 = "function", alias4 = container.escapeExpression, lookupProperty = container.lookupProperty || function (parent, propertyName) {
24
+ export const productionTemplate = Handlebars.template({ "0": function (container, depth0, helpers, partials, data, blockParams, depths) {
25
+ var alias1 = container.lambda, alias2 = container.escapeExpression, lookupProperty = container.lookupProperty || function (parent, propertyName) {
26
+ if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
27
+ return parent[propertyName];
28
+ }
29
+ return undefined;
30
+ };
31
+ return "<link rel=\"modulepreload\" crossorigin href=\""
32
+ + alias2(alias1((depths[1] != null ? lookupProperty(depths[1], "serverUrl") : depths[1]), depth0))
33
+ + "/assets/"
34
+ + alias2(alias1(depth0, depth0))
35
+ + "\" />\n";
36
+ }, "compiler": [8, ">= 4.3.0"], "main": function (container, depth0, helpers, partials, data, blockParams, depths) {
37
+ var stack1, helper, alias1 = depth0 != null ? depth0 : (container.nullContext || {}), alias2 = container.hooks.helperMissing, alias3 = "function", alias4 = container.escapeExpression, lookupProperty = container.lookupProperty || function (parent, propertyName) {
28
38
  if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
29
39
  return parent[propertyName];
30
40
  }
31
41
  return undefined;
32
42
  };
33
- return "<script type=\"module\">window.skybridge = { hostType: \""
34
- + alias4(((helper = (helper = lookupProperty(helpers, "hostType") || (depth0 != null ? lookupProperty(depth0, "hostType") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "hostType", "hash": {}, "data": data, "loc": { "start": { "line": 1, "column": 54 }, "end": { "line": 1, "column": 66 } } }) : helper)))
35
- + "\", serverUrl: \""
36
- + alias4(((helper = (helper = lookupProperty(helpers, "serverUrl") || (depth0 != null ? lookupProperty(depth0, "serverUrl") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "serverUrl", "hash": {}, "data": data, "loc": { "start": { "line": 1, "column": 81 }, "end": { "line": 1, "column": 94 } } }) : helper)))
37
- + "\" };</script>\n<div id=\"root\"></div>\n<script type=\"module\">\n import('"
38
- + alias4(((helper = (helper = lookupProperty(helpers, "serverUrl") || (depth0 != null ? lookupProperty(depth0, "serverUrl") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "serverUrl", "hash": {}, "data": data, "loc": { "start": { "line": 4, "column": 10 }, "end": { "line": 4, "column": 23 } } }) : helper)))
43
+ return "<link rel=\"stylesheet\" crossorigin href=\""
44
+ + alias4(((helper = (helper = lookupProperty(helpers, "serverUrl") || (depth0 != null ? lookupProperty(depth0, "serverUrl") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "serverUrl", "hash": {}, "data": data, "loc": { "start": { "line": 1, "column": 41 }, "end": { "line": 1, "column": 54 } } }) : helper)))
39
45
  + "/assets/"
40
- + alias4(((helper = (helper = lookupProperty(helpers, "viewFile") || (depth0 != null ? lookupProperty(depth0, "viewFile") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "viewFile", "hash": {}, "data": data, "loc": { "start": { "line": 4, "column": 31 }, "end": { "line": 4, "column": 43 } } }) : helper)))
41
- + "');\n</script>\n<link rel=\"stylesheet\" crossorigin href=\""
42
- + alias4(((helper = (helper = lookupProperty(helpers, "serverUrl") || (depth0 != null ? lookupProperty(depth0, "serverUrl") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "serverUrl", "hash": {}, "data": data, "loc": { "start": { "line": 6, "column": 41 }, "end": { "line": 6, "column": 54 } } }) : helper)))
46
+ + alias4(((helper = (helper = lookupProperty(helpers, "styleFile") || (depth0 != null ? lookupProperty(depth0, "styleFile") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "styleFile", "hash": {}, "data": data, "loc": { "start": { "line": 1, "column": 62 }, "end": { "line": 1, "column": 75 } } }) : helper)))
47
+ + "\" />\n"
48
+ + ((stack1 = lookupProperty(helpers, "each").call(alias1, (depth0 != null ? lookupProperty(depth0, "preloadFiles") : depth0), { "name": "each", "hash": {}, "fn": container.program(0, data, 0, blockParams, depths), "inverse": container.noop, "data": data, "loc": { "start": { "line": 2, "column": 0 }, "end": { "line": 4, "column": 9 } } })) != null ? stack1 : "")
49
+ + "<div id=\"root\"></div>\n<script type=\"module\">window.skybridge = { serverUrl: \""
50
+ + alias4(((helper = (helper = lookupProperty(helpers, "serverUrl") || (depth0 != null ? lookupProperty(depth0, "serverUrl") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "serverUrl", "hash": {}, "data": data, "loc": { "start": { "line": 6, "column": 55 }, "end": { "line": 6, "column": 68 } } }) : helper)))
51
+ + "\" };</script>\n<script type=\"module\">\n import('"
52
+ + alias4(((helper = (helper = lookupProperty(helpers, "serverUrl") || (depth0 != null ? lookupProperty(depth0, "serverUrl") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "serverUrl", "hash": {}, "data": data, "loc": { "start": { "line": 8, "column": 10 }, "end": { "line": 8, "column": 23 } } }) : helper)))
43
53
  + "/assets/"
44
- + alias4(((helper = (helper = lookupProperty(helpers, "styleFile") || (depth0 != null ? lookupProperty(depth0, "styleFile") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "styleFile", "hash": {}, "data": data, "loc": { "start": { "line": 6, "column": 62 }, "end": { "line": 6, "column": 75 } } }) : helper)))
45
- + "\" />";
46
- }, "useData": true });
54
+ + alias4(((helper = (helper = lookupProperty(helpers, "viewFile") || (depth0 != null ? lookupProperty(depth0, "viewFile") : depth0)) != null ? helper : alias2), (typeof helper === alias3 ? helper.call(alias1, { "name": "viewFile", "hash": {}, "data": data, "loc": { "start": { "line": 8, "column": 31 }, "end": { "line": 8, "column": 43 } } }) : helper)))
55
+ + "');\n</script>\n";
56
+ }, "useData": true, "useDepths": true });
47
57
  //# sourceMappingURL=templates.generated.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"templates.generated.js","sourceRoot":"","sources":["../../src/server/templates.generated.js"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,OAAO,UAAU,MAAM,uBAAuB,CAAC;AAE/C,yCAAyC;AACzC,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC,QAAQ,CAAC,EAAC,UAAU,EAAC,CAAC,CAAC,EAAC,UAAU,CAAC,EAAC,MAAM,EAAC,UAAS,SAAS,EAAC,MAAM,EAAC,OAAO,EAAC,QAAQ,EAAC,IAAI;QACpI,IAAI,MAAM,EAAE,MAAM,GAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,MAAM,GAAC,SAAS,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,GAAC,UAAU,EAAE,MAAM,GAAC,SAAS,CAAC,gBAAgB,EAAE,cAAc,GAAG,SAAS,CAAC,cAAc,IAAI,UAAS,MAAM,EAAE,YAAY;YAC9O,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC;gBAC/D,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO,SAAS,CAAA;QACpB,CAAC,CAAC;QAEJ,OAAO,2DAA2D;cAC9D,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,UAAU,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,UAAU,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACrU,mBAAmB;cACnB,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACxU,qFAAqF;cACrF,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACxU,iPAAiP;cACjP,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACxU,gHAAgH;cAChH,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cAC1U,mBAAmB;cACnB,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,UAAU,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,UAAU,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,EAAE,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACvU,gBAAgB,CAAC;IACvB,CAAC,EAAC,SAAS,EAAC,IAAI,EAAC,CAAC,CAAC;AACnB,yCAAyC;AACzC,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC,QAAQ,CAAC,EAAC,UAAU,EAAC,CAAC,CAAC,EAAC,UAAU,CAAC,EAAC,MAAM,EAAC,UAAS,SAAS,EAAC,MAAM,EAAC,OAAO,EAAC,QAAQ,EAAC,IAAI;QACnI,IAAI,MAAM,EAAE,MAAM,GAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,MAAM,GAAC,SAAS,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,GAAC,UAAU,EAAE,MAAM,GAAC,SAAS,CAAC,gBAAgB,EAAE,cAAc,GAAG,SAAS,CAAC,cAAc,IAAI,UAAS,MAAM,EAAE,YAAY;YAC9O,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC;gBAC/D,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO,SAAS,CAAA;QACpB,CAAC,CAAC;QAEJ,OAAO,2DAA2D;cAC9D,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,UAAU,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,UAAU,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACrU,mBAAmB;cACnB,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACxU,+EAA+E;cAC/E,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACxU,UAAU;cACV,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,UAAU,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,UAAU,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACrU,8DAA8D;cAC9D,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACxU,UAAU;cACV,MAAM,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,OAAO,EAAC,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,EAAC,CAAC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAC,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,EAAE,EAAC,MAAM,EAAC,IAAI,EAAC,KAAK,EAAC,EAAC,OAAO,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,KAAK,EAAC,EAAC,MAAM,EAAC,CAAC,EAAC,QAAQ,EAAC,EAAE,EAAC,EAAC,EAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;cACxU,OAAO,CAAC;IACd,CAAC,EAAC,SAAS,EAAC,IAAI,EAAC,CAAC,CAAC","sourcesContent":["// AUTO-GENERATED by scripts/precompile-templates.mjs. Do not edit.\nimport Handlebars from \"handlebars/runtime.js\";\n\n/** @type {HandlebarsTemplateDelegate} */\nexport const developmentTemplate = Handlebars.template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=\"function\", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"<script type=\\\"module\\\">window.skybridge = { hostType: \\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"hostType\") || (depth0 != null ? lookupProperty(depth0,\"hostType\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"hostType\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":1,\"column\":54},\"end\":{\"line\":1,\"column\":66}}}) : helper)))\n + \"\\\", serverUrl: \\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":1,\"column\":81},\"end\":{\"line\":1,\"column\":94}}}) : helper)))\n + \"\\\" };</script>\\n<script type=\\\"module\\\">\\n import { injectIntoGlobalHook } from \\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":3,\"column\":40},\"end\":{\"line\":3,\"column\":53}}}) : helper)))\n + \"/assets/@react-refresh\\\";\\n injectIntoGlobalHook(window); window.$RefreshReg$ = () => {};\\n window.$RefreshSig$ = () => (type) => type;\\n window.__vite_plugin_react_preamble_installed__ = true;\\n</script>\\n<script type=\\\"module\\\" src=\\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":8,\"column\":27},\"end\":{\"line\":8,\"column\":40}}}) : helper)))\n + \"/@vite/client\\\"></script>\\n<div id=\\\"root\\\"></div>\\n<script type=\\\"module\\\" id=\\\"dev-view-entry\\\">\\n import('\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":11,\"column\":10},\"end\":{\"line\":11,\"column\":23}}}) : helper)))\n + \"/_skybridge/view/\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"viewName\") || (depth0 != null ? lookupProperty(depth0,\"viewName\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"viewName\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":11,\"column\":40},\"end\":{\"line\":11,\"column\":52}}}) : helper)))\n + \"');\\n</script>\";\n},\"useData\":true});\n/** @type {HandlebarsTemplateDelegate} */\nexport const productionTemplate = Handlebars.template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=\"function\", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"<script type=\\\"module\\\">window.skybridge = { hostType: \\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"hostType\") || (depth0 != null ? lookupProperty(depth0,\"hostType\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"hostType\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":1,\"column\":54},\"end\":{\"line\":1,\"column\":66}}}) : helper)))\n + \"\\\", serverUrl: \\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":1,\"column\":81},\"end\":{\"line\":1,\"column\":94}}}) : helper)))\n + \"\\\" };</script>\\n<div id=\\\"root\\\"></div>\\n<script type=\\\"module\\\">\\n import('\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":4,\"column\":10},\"end\":{\"line\":4,\"column\":23}}}) : helper)))\n + \"/assets/\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"viewFile\") || (depth0 != null ? lookupProperty(depth0,\"viewFile\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"viewFile\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":4,\"column\":31},\"end\":{\"line\":4,\"column\":43}}}) : helper)))\n + \"');\\n</script>\\n<link rel=\\\"stylesheet\\\" crossorigin href=\\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":6,\"column\":41},\"end\":{\"line\":6,\"column\":54}}}) : helper)))\n + \"/assets/\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"styleFile\") || (depth0 != null ? lookupProperty(depth0,\"styleFile\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"styleFile\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":6,\"column\":62},\"end\":{\"line\":6,\"column\":75}}}) : helper)))\n + \"\\\" />\";\n},\"useData\":true});\n"]}
1
+ {"version":3,"file":"templates.generated.js","sourceRoot":"","sources":["../../src/server/templates.generated.js"],"names":[],"mappings":"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","sourcesContent":["// AUTO-GENERATED by scripts/precompile-templates.mjs. Do not edit.\nimport Handlebars from \"handlebars/runtime.js\";\n\n/** @type {HandlebarsTemplateDelegate} */\nexport const developmentTemplate = Handlebars.template({\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data) {\n var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=\"function\", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"<script type=\\\"module\\\">window.skybridge = { serverUrl: \\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":1,\"column\":55},\"end\":{\"line\":1,\"column\":68}}}) : helper)))\n + \"\\\" };</script>\\n<script type=\\\"module\\\">\\n import { injectIntoGlobalHook } from \\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":3,\"column\":40},\"end\":{\"line\":3,\"column\":53}}}) : helper)))\n + \"/assets/@react-refresh\\\";\\n injectIntoGlobalHook(window); window.$RefreshReg$ = () => {};\\n window.$RefreshSig$ = () => (type) => type;\\n window.__vite_plugin_react_preamble_installed__ = true;\\n</script>\\n<script type=\\\"module\\\" src=\\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":8,\"column\":27},\"end\":{\"line\":8,\"column\":40}}}) : helper)))\n + \"/@vite/client\\\"></script>\\n<div id=\\\"root\\\"></div>\\n<script type=\\\"module\\\" id=\\\"dev-view-entry\\\">\\n import('\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":11,\"column\":10},\"end\":{\"line\":11,\"column\":23}}}) : helper)))\n + \"/_skybridge/view/\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"viewName\") || (depth0 != null ? lookupProperty(depth0,\"viewName\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"viewName\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":11,\"column\":40},\"end\":{\"line\":11,\"column\":52}}}) : helper)))\n + \"');\\n</script>\";\n},\"useData\":true});\n/** @type {HandlebarsTemplateDelegate} */\nexport const productionTemplate = Handlebars.template({\"0\":function(container,depth0,helpers,partials,data,blockParams,depths) {\n var alias1=container.lambda, alias2=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"<link rel=\\\"modulepreload\\\" crossorigin href=\\\"\"\n + alias2(alias1((depths[1] != null ? lookupProperty(depths[1],\"serverUrl\") : depths[1]), depth0))\n + \"/assets/\"\n + alias2(alias1(depth0, depth0))\n + \"\\\" />\\n\";\n},\"compiler\":[8,\">= 4.3.0\"],\"main\":function(container,depth0,helpers,partials,data,blockParams,depths) {\n var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=container.hooks.helperMissing, alias3=\"function\", alias4=container.escapeExpression, lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n };\n\n return \"<link rel=\\\"stylesheet\\\" crossorigin href=\\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":1,\"column\":41},\"end\":{\"line\":1,\"column\":54}}}) : helper)))\n + \"/assets/\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"styleFile\") || (depth0 != null ? lookupProperty(depth0,\"styleFile\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"styleFile\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":1,\"column\":62},\"end\":{\"line\":1,\"column\":75}}}) : helper)))\n + \"\\\" />\\n\"\n + ((stack1 = lookupProperty(helpers,\"each\").call(alias1,(depth0 != null ? lookupProperty(depth0,\"preloadFiles\") : depth0),{\"name\":\"each\",\"hash\":{},\"fn\":container.program(0, data, 0, blockParams, depths),\"inverse\":container.noop,\"data\":data,\"loc\":{\"start\":{\"line\":2,\"column\":0},\"end\":{\"line\":4,\"column\":9}}})) != null ? stack1 : \"\")\n + \"<div id=\\\"root\\\"></div>\\n<script type=\\\"module\\\">window.skybridge = { serverUrl: \\\"\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":6,\"column\":55},\"end\":{\"line\":6,\"column\":68}}}) : helper)))\n + \"\\\" };</script>\\n<script type=\\\"module\\\">\\n import('\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"serverUrl\") || (depth0 != null ? lookupProperty(depth0,\"serverUrl\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"serverUrl\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":8,\"column\":10},\"end\":{\"line\":8,\"column\":23}}}) : helper)))\n + \"/assets/\"\n + alias4(((helper = (helper = lookupProperty(helpers,\"viewFile\") || (depth0 != null ? lookupProperty(depth0,\"viewFile\") : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{\"name\":\"viewFile\",\"hash\":{},\"data\":data,\"loc\":{\"start\":{\"line\":8,\"column\":31},\"end\":{\"line\":8,\"column\":43}}}) : helper)))\n + \"');\\n</script>\\n\";\n},\"useData\":true,\"useDepths\":true});\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,167 @@
1
+ // @vitest-environment node
2
+ import http from "node:http";
3
+ import { Client, StreamableHTTPClientTransport, } from "@modelcontextprotocol/client";
4
+ import { afterEach, describe, expect, it, vi } from "vitest";
5
+ import { z } from "zod";
6
+ import { Skybridge } from "./app.js";
7
+ import { requestFormInput } from "./form-input.js";
8
+ vi.mock("@skybridge/devtools", () => ({
9
+ devtoolsStaticServer: () => ((_r, _s, n) => n()),
10
+ }));
11
+ vi.mock("./viewsDevServer.js", () => ({
12
+ viewsDevServer: () => ((_r, _s, n) => n()),
13
+ }));
14
+ let openServer;
15
+ afterEach(() => openServer?.close());
16
+ describe("tool handler extra", () => {
17
+ it("exposes the client hints the host sent on the request", async () => {
18
+ const { createApp } = await import("./express.js");
19
+ let seenLocale;
20
+ const app = new Skybridge({
21
+ name: "t",
22
+ version: "0.0.0",
23
+ handler: (server) => server.registerTool({
24
+ name: "hints",
25
+ description: "Reads client hints.",
26
+ inputSchema: {},
27
+ }, (_args, extra) => {
28
+ seenLocale = extra.mcpReq._meta?.["openai/locale"];
29
+ return { content: [{ type: "text", text: "ok" }] };
30
+ }),
31
+ });
32
+ const httpServer = http.createServer();
33
+ const expressApp = await createApp({ app, httpServer });
34
+ const listening = http.createServer(expressApp);
35
+ await new Promise((r) => listening.listen(0, r));
36
+ openServer = listening;
37
+ const port = listening.address().port;
38
+ const client = new Client({ name: "c", version: "0.0.0" });
39
+ await client.connect(new StreamableHTTPClientTransport(new URL(`http://localhost:${port}/mcp`)));
40
+ await client.callTool({
41
+ name: "hints",
42
+ arguments: {},
43
+ _meta: { "openai/locale": "fr-FR" },
44
+ });
45
+ await client.close();
46
+ expect(seenLocale).toBe("fr-FR");
47
+ });
48
+ });
49
+ describe("stateless server instances", () => {
50
+ it("carries the registered capabilities onto each per-request instance", async () => {
51
+ const app = new Skybridge({
52
+ name: "t",
53
+ version: "0.0.0",
54
+ handler: (server) => server.registerTool({ name: "a-tool", description: "d", inputSchema: {} }, () => ({ content: [{ type: "text", text: "ok" }] })),
55
+ });
56
+ const fresh = await app.createServerInstance();
57
+ expect(fresh.getCapabilities().tools).toBeDefined();
58
+ });
59
+ it("serves a 2026-era caller with that era's result shape", async () => {
60
+ const { createApp } = await import("./express.js");
61
+ const app = new Skybridge({
62
+ name: "t",
63
+ version: "0.0.0",
64
+ handler: (server) => server.registerTool({
65
+ name: "scalar",
66
+ description: "Returns a scalar structuredContent.",
67
+ inputSchema: {},
68
+ outputSchema: z.number(),
69
+ }, () => ({
70
+ structuredContent: 42,
71
+ content: [{ type: "text", text: "42" }],
72
+ })),
73
+ });
74
+ const httpServer = http.createServer();
75
+ const expressApp = await createApp({ app, httpServer });
76
+ const listening = http.createServer(expressApp);
77
+ await new Promise((r) => listening.listen(0, r));
78
+ openServer = listening;
79
+ const port = listening.address().port;
80
+ const client = new Client({ name: "c", version: "0.0.0" }, { versionNegotiation: { mode: "auto" } });
81
+ await client.connect(new StreamableHTTPClientTransport(new URL(`http://localhost:${port}/mcp`)));
82
+ const result = await client.callTool({ name: "scalar", arguments: {} });
83
+ const negotiated = client.getNegotiatedProtocolVersion();
84
+ await client.close();
85
+ expect(negotiated).toBe("2026-07-28");
86
+ expect(result.structuredContent).toBe(42);
87
+ });
88
+ it("asks for an OpenAI form over multi-round-trip requests", async () => {
89
+ const { createApp } = await import("./express.js");
90
+ const requestedSchema = {
91
+ type: "object",
92
+ properties: {
93
+ part: {
94
+ type: "string",
95
+ oneOf: [{ const: "bolt", title: "M6 bolt", description: "Fastener" }],
96
+ },
97
+ drawing: {
98
+ type: "string",
99
+ format: "uri",
100
+ "x-openai-input": {
101
+ type: "resource",
102
+ options: [{ uri: "cad://drawings/bolt", name: "bolt" }],
103
+ },
104
+ },
105
+ },
106
+ required: ["part"],
107
+ };
108
+ const app = new Skybridge({
109
+ name: "t",
110
+ version: "0.0.0",
111
+ handler: (server) => server.registerTool({ name: "pick-part" }, (_args, extra) => {
112
+ const result = requestFormInput(extra, {
113
+ key: "part",
114
+ message: "Choose a part",
115
+ requestedSchema,
116
+ });
117
+ if ("resultType" in result) {
118
+ return result;
119
+ }
120
+ return {
121
+ content: `${result.action}:${result.action === "accept" && result.content.part}`,
122
+ };
123
+ }),
124
+ });
125
+ const httpServer = http.createServer();
126
+ const expressApp = await createApp({ app, httpServer });
127
+ const listening = http.createServer(expressApp);
128
+ await new Promise((r) => listening.listen(0, r));
129
+ openServer = listening;
130
+ const port = listening.address().port;
131
+ const client = new Client({ name: "c", version: "0.0.0" }, {
132
+ capabilities: {
133
+ elicitation: { form: {} },
134
+ extensions: { "openai/elicitation": { form: {} } },
135
+ },
136
+ versionNegotiation: { mode: "auto" },
137
+ });
138
+ const asked = [];
139
+ let answer = { part: "bolt", drawing: "cad://drawings/bolt" };
140
+ client.setRequestHandler("elicitation/create", (request) => {
141
+ asked.push(request.params);
142
+ return { action: "accept", content: answer };
143
+ });
144
+ await client.connect(new StreamableHTTPClientTransport(new URL(`http://localhost:${port}/mcp`)));
145
+ const result = await client.callTool({ name: "pick-part" });
146
+ expect(result.content).toEqual([{ type: "text", text: "accept:bolt" }]);
147
+ expect(asked).toEqual([
148
+ {
149
+ mode: "form",
150
+ message: "Choose a part",
151
+ requestedSchema: { type: "object", properties: {} },
152
+ _meta: { "openai/elicitation": { requestedSchema } },
153
+ },
154
+ ]);
155
+ for (answer of [
156
+ { part: "washer", drawing: "cad://drawings/bolt" },
157
+ { part: "bolt", drawing: "cad://drawings/other" },
158
+ ]) {
159
+ await expect(client.callTool({ name: "pick-part" })).resolves.toMatchObject({
160
+ isError: true,
161
+ content: [{ text: expect.stringContaining("does not match") }],
162
+ });
163
+ }
164
+ await client.close();
165
+ });
166
+ });
167
+ //# sourceMappingURL=tool-extra.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-extra.test.js","sourceRoot":"","sources":["../../src/server/tool-extra.test.ts"],"names":[],"mappings":"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","sourcesContent":["// @vitest-environment node\nimport http from \"node:http\";\nimport {\n Client,\n StreamableHTTPClientTransport,\n} from \"@modelcontextprotocol/client\";\nimport type { RequestHandler } from \"express\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { z } from \"zod\";\nimport { Skybridge } from \"./app.js\";\nimport { requestFormInput } from \"./form-input.js\";\n\nvi.mock(\"@skybridge/devtools\", () => ({\n devtoolsStaticServer: () =>\n ((_r: unknown, _s: unknown, n: () => void) => n()) as RequestHandler,\n}));\nvi.mock(\"./viewsDevServer.js\", () => ({\n viewsDevServer: () =>\n ((_r: unknown, _s: unknown, n: () => void) => n()) as RequestHandler,\n}));\n\nlet openServer: http.Server | undefined;\nafterEach(() => openServer?.close());\n\ndescribe(\"tool handler extra\", () => {\n it(\"exposes the client hints the host sent on the request\", async () => {\n const { createApp } = await import(\"./express.js\");\n let seenLocale: unknown;\n const app = new Skybridge({\n name: \"t\",\n version: \"0.0.0\",\n handler: (server) =>\n server.registerTool(\n {\n name: \"hints\",\n description: \"Reads client hints.\",\n inputSchema: {},\n },\n (_args, extra) => {\n seenLocale = extra.mcpReq._meta?.[\"openai/locale\"];\n return { content: [{ type: \"text\", text: \"ok\" }] };\n },\n ),\n });\n\n const httpServer = http.createServer();\n const expressApp = await createApp({ app, httpServer });\n const listening = http.createServer(expressApp);\n await new Promise<void>((r) => listening.listen(0, r));\n openServer = listening;\n const port = (listening.address() as { port: number }).port;\n\n const client = new Client({ name: \"c\", version: \"0.0.0\" });\n await client.connect(\n new StreamableHTTPClientTransport(\n new URL(`http://localhost:${port}/mcp`),\n ),\n );\n await client.callTool({\n name: \"hints\",\n arguments: {},\n _meta: { \"openai/locale\": \"fr-FR\" },\n });\n await client.close();\n\n expect(seenLocale).toBe(\"fr-FR\");\n });\n});\n\ndescribe(\"stateless server instances\", () => {\n it(\"carries the registered capabilities onto each per-request instance\", async () => {\n const app = new Skybridge({\n name: \"t\",\n version: \"0.0.0\",\n handler: (server) =>\n server.registerTool(\n { name: \"a-tool\", description: \"d\", inputSchema: {} },\n () => ({ content: [{ type: \"text\", text: \"ok\" }] }),\n ),\n });\n\n const fresh = await app.createServerInstance();\n\n expect(fresh.getCapabilities().tools).toBeDefined();\n });\n\n it(\"serves a 2026-era caller with that era's result shape\", async () => {\n const { createApp } = await import(\"./express.js\");\n const app = new Skybridge({\n name: \"t\",\n version: \"0.0.0\",\n handler: (server) =>\n server.registerTool(\n {\n name: \"scalar\",\n description: \"Returns a scalar structuredContent.\",\n inputSchema: {},\n outputSchema: z.number(),\n },\n () => ({\n structuredContent: 42,\n content: [{ type: \"text\", text: \"42\" }],\n }),\n ),\n });\n\n const httpServer = http.createServer();\n const expressApp = await createApp({ app, httpServer });\n const listening = http.createServer(expressApp);\n await new Promise<void>((r) => listening.listen(0, r));\n openServer = listening;\n const port = (listening.address() as { port: number }).port;\n\n const client = new Client(\n { name: \"c\", version: \"0.0.0\" },\n { versionNegotiation: { mode: \"auto\" } },\n );\n await client.connect(\n new StreamableHTTPClientTransport(\n new URL(`http://localhost:${port}/mcp`),\n ),\n );\n const result = await client.callTool({ name: \"scalar\", arguments: {} });\n const negotiated = client.getNegotiatedProtocolVersion();\n await client.close();\n\n expect(negotiated).toBe(\"2026-07-28\");\n expect(result.structuredContent).toBe(42);\n });\n\n it(\"asks for an OpenAI form over multi-round-trip requests\", async () => {\n const { createApp } = await import(\"./express.js\");\n const requestedSchema = {\n type: \"object\" as const,\n properties: {\n part: {\n type: \"string\" as const,\n oneOf: [{ const: \"bolt\", title: \"M6 bolt\", description: \"Fastener\" }],\n },\n drawing: {\n type: \"string\" as const,\n format: \"uri\" as const,\n \"x-openai-input\": {\n type: \"resource\" as const,\n options: [{ uri: \"cad://drawings/bolt\", name: \"bolt\" }],\n },\n },\n },\n required: [\"part\"],\n };\n const app = new Skybridge({\n name: \"t\",\n version: \"0.0.0\",\n handler: (server) =>\n server.registerTool({ name: \"pick-part\" }, (_args, extra) => {\n const result = requestFormInput(extra, {\n key: \"part\",\n message: \"Choose a part\",\n requestedSchema,\n });\n if (\"resultType\" in result) {\n return result;\n }\n return {\n content: `${result.action}:${result.action === \"accept\" && result.content.part}`,\n };\n }),\n });\n const httpServer = http.createServer();\n const expressApp = await createApp({ app, httpServer });\n const listening = http.createServer(expressApp);\n await new Promise<void>((r) => listening.listen(0, r));\n openServer = listening;\n const port = (listening.address() as { port: number }).port;\n\n const client = new Client(\n { name: \"c\", version: \"0.0.0\" },\n {\n capabilities: {\n elicitation: { form: {} },\n extensions: { \"openai/elicitation\": { form: {} } },\n },\n versionNegotiation: { mode: \"auto\" },\n },\n );\n const asked: unknown[] = [];\n let answer = { part: \"bolt\", drawing: \"cad://drawings/bolt\" };\n client.setRequestHandler(\"elicitation/create\", (request) => {\n asked.push(request.params);\n return { action: \"accept\", content: answer };\n });\n await client.connect(\n new StreamableHTTPClientTransport(\n new URL(`http://localhost:${port}/mcp`),\n ),\n );\n\n const result = await client.callTool({ name: \"pick-part\" });\n expect(result.content).toEqual([{ type: \"text\", text: \"accept:bolt\" }]);\n expect(asked).toEqual([\n {\n mode: \"form\",\n message: \"Choose a part\",\n requestedSchema: { type: \"object\", properties: {} },\n _meta: { \"openai/elicitation\": { requestedSchema } },\n },\n ]);\n\n for (answer of [\n { part: \"washer\", drawing: \"cad://drawings/bolt\" },\n { part: \"bolt\", drawing: \"cad://drawings/other\" },\n ]) {\n await expect(\n client.callTool({ name: \"pick-part\" }),\n ).resolves.toMatchObject({\n isError: true,\n content: [{ text: expect.stringContaining(\"does not match\") }],\n });\n }\n await client.close();\n });\n});\n"]}
@@ -1,9 +1,7 @@
1
1
  import http from "node:http";
2
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
4
- import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
2
+ import { Client, InMemoryTransport, StreamableHTTPClientTransport, } from "@modelcontextprotocol/client";
5
3
  import { afterEach, describe, expect, it, vi } from "vitest";
6
- import { __setBuildManifest, McpServer } from "./index.js";
4
+ import { __setBuildManifest, Skybridge } from "./index.js";
7
5
  vi.mock("@skybridge/devtools", () => ({
8
6
  devtoolsStaticServer: () => ((_req, _res, next) => next()),
9
7
  }));
@@ -15,18 +13,27 @@ vi.mock("./viewsDevServer.js", () => ({
15
13
  // (it busts host/CDN caches when the bundle changes); it is not part of the
16
14
  // resource's identity, so a stale, absent, or arbitrary param must still serve
17
15
  // the underlying asset.
16
+ function buildApp(register) {
17
+ return new Skybridge({
18
+ name: "test",
19
+ version: "1.0.0",
20
+ handler: (server) => {
21
+ register(server);
22
+ return server;
23
+ },
24
+ });
25
+ }
18
26
  async function connect(register) {
19
- const server = new McpServer({ name: "test", version: "1.0.0" });
20
- register(server);
27
+ const instance = await buildApp(register).createServerInstance();
21
28
  const client = new Client({ name: "test-client", version: "1.0.0" });
22
29
  const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
23
- await server.connect(serverTransport);
30
+ await instance.connect(serverTransport);
24
31
  await client.connect(clientTransport);
25
32
  return {
26
33
  client,
27
34
  teardown: async () => {
28
35
  await client.close();
29
- await server.close();
36
+ await instance.close();
30
37
  },
31
38
  };
32
39
  }
@@ -35,11 +42,10 @@ afterEach(() => openHttpServer?.close());
35
42
  // Connect over real HTTP so forwarded proxy headers reach the resource handler.
36
43
  async function connectHttp(register, headers) {
37
44
  const { createApp } = await import("./express.js");
38
- const server = new McpServer({ name: "test", version: "1.0.0" });
39
- register(server);
45
+ const app = buildApp(register);
40
46
  const httpServer = http.createServer();
41
- await createApp({ mcpServer: server, httpServer });
42
- const listening = http.createServer(server.express);
47
+ await createApp({ app, httpServer });
48
+ const listening = http.createServer(app.express);
43
49
  await new Promise((resolve) => listening.listen(0, resolve));
44
50
  openHttpServer = listening;
45
51
  const port = listening.address().port;
@@ -50,7 +56,6 @@ async function connectHttp(register, headers) {
50
56
  client,
51
57
  teardown: async () => {
52
58
  await client.close();
53
- await server.close();
54
59
  },
55
60
  };
56
61
  }
@@ -152,6 +157,41 @@ describe("view resource resolution (cache key)", () => {
152
157
  await teardown();
153
158
  }
154
159
  });
160
+ it("preloads the view entry and its static imports (prod)", async () => {
161
+ process.env.NODE_ENV = "production";
162
+ __setBuildManifest({
163
+ "src/views/widget.tsx": {
164
+ isEntry: true,
165
+ name: "widget",
166
+ file: "assets/widget-ABC123.js",
167
+ imports: ["_shared.js", "_ui.js"],
168
+ dynamicImports: ["src/lazy.tsx"],
169
+ },
170
+ "_shared.js": { file: "assets/shared-DEF456.js" },
171
+ "_ui.js": { file: "assets/ui-GHI789.js", imports: ["_shared.js"] },
172
+ "src/lazy.tsx": { file: "assets/lazy-JKL012.js", isDynamicEntry: true },
173
+ "style.css": { file: "assets/style-XYZ.css" },
174
+ });
175
+ const { client, teardown } = await connect(registerWidget);
176
+ try {
177
+ const { contents } = await client.readResource({
178
+ uri: "ui://views/ext-apps/widget.html",
179
+ });
180
+ const { text } = textContent(contents);
181
+ const preloaded = [
182
+ ...text.matchAll(/<link rel="modulepreload" crossorigin href="[^"]*\/assets\/(assets\/[^"]+)" \/>/g),
183
+ ].map((match) => match[1]);
184
+ expect(preloaded).toEqual([
185
+ "assets/widget-ABC123.js",
186
+ "assets/shared-DEF456.js",
187
+ "assets/ui-GHI789.js",
188
+ ]);
189
+ expect(text.indexOf("modulepreload")).toBeLessThan(text.indexOf("import("));
190
+ }
191
+ finally {
192
+ await teardown();
193
+ }
194
+ });
155
195
  // Back-compat: older Skybridge advertised the view at `ui://views/apps-sdk/...`
156
196
  // via openai/outputTemplate. We no longer advertise it, but apps published then
157
197
  // have it cached, so the read must still resolve to the ext-apps content.
@@ -1 +1 @@
1
- {"version":3,"file":"view-resource-resolution.test.js","sourceRoot":"","sources":["../../src/server/view-resource-resolution.test.ts"],"names":[],"mappings":"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","sourcesContent":["import http from \"node:http\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport type { RequestHandler } from \"express\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { __setBuildManifest, McpServer } from \"./index.js\";\n\nvi.mock(\"@skybridge/devtools\", () => ({\n devtoolsStaticServer: () =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\nvi.mock(\"./viewsDevServer.js\", () => ({\n viewsDevServer: (_httpServer: unknown) =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\n\n// Mirror what the Skybridge Vite plugin generates in `.skybridge/views.d.ts`:\n// narrow `ViewName` so `component: \"widget\"` typechecks against the registry.\ndeclare module \"./server.js\" {\n interface ViewNameRegistry {\n widget: true;\n }\n}\n\n// SKY-435: a view resource must resolve no matter the `?v=` query param value.\n// The version param is a content-derived cache key for external consumers\n// (it busts host/CDN caches when the bundle changes); it is not part of the\n// resource's identity, so a stale, absent, or arbitrary param must still serve\n// the underlying asset.\n\nasync function connect(register: (server: McpServer) => void) {\n const server = new McpServer({ name: \"test\", version: \"1.0.0\" });\n register(server);\n const client = new Client({ name: \"test-client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await server.connect(serverTransport);\n await client.connect(clientTransport);\n return {\n client,\n teardown: async () => {\n await client.close();\n await server.close();\n },\n };\n}\n\nlet openHttpServer: http.Server | undefined;\nafterEach(() => openHttpServer?.close());\n\n// Connect over real HTTP so forwarded proxy headers reach the resource handler.\nasync function connectHttp(\n register: (server: McpServer) => void,\n headers: Record<string, string>,\n) {\n const { createApp } = await import(\"./express.js\");\n const server = new McpServer({ name: \"test\", version: \"1.0.0\" });\n register(server);\n const httpServer = http.createServer();\n await createApp({ mcpServer: server, httpServer });\n const listening = http.createServer(server.express);\n await new Promise<void>((resolve) => listening.listen(0, resolve));\n openHttpServer = listening;\n const port = (listening.address() as { port: number }).port;\n\n const client = new Client({ name: \"test-client\", version: \"1.0.0\" });\n const transport = new StreamableHTTPClientTransport(\n new URL(`http://localhost:${port}/mcp`),\n { requestInit: { headers } },\n );\n await client.connect(transport);\n return {\n client,\n teardown: async () => {\n await client.close();\n await server.close();\n },\n };\n}\n\nfunction registerWidget(server: McpServer) {\n server.registerTool(\n { name: \"show\", description: \"show\", view: { component: \"widget\" } },\n () => ({ content: [{ type: \"text\" as const, text: \"ok\" }] }),\n );\n}\n\n/** Narrow a read-resource content entry to its text variant. */\nfunction textContent(contents: Array<{ uri: string }>): {\n uri: string;\n text: string;\n} {\n return contents[0] as { uri: string; text: string };\n}\n\ndescribe(\"view resource resolution (cache key)\", () => {\n afterEach(() => {\n delete process.env.NODE_ENV;\n });\n\n it(\"resolves regardless of the ?v= param and echoes the requested URI\", async () => {\n const { client, teardown } = await connect(registerWidget);\n\n const { resources } = await client.listResources();\n const listed = resources.find((r) =>\n r.uri.startsWith(\"ui://views/ext-apps/widget.html\"),\n );\n // Dev build advertises no cache key.\n expect(listed?.uri).toBe(\"ui://views/ext-apps/widget.html\");\n\n // A stale/arbitrary/absent param all resolve the same underlying asset,\n // and the response echoes the URI the consumer asked for (never rewritten).\n for (const uri of [\n \"ui://views/ext-apps/widget.html?v=stale123\",\n \"ui://views/ext-apps/widget.html?v=whatever-else\",\n \"ui://views/ext-apps/widget.html\",\n ]) {\n const { contents } = await client.readResource({ uri });\n expect(contents).toHaveLength(1);\n const content = textContent(contents);\n expect(typeof content.text).toBe(\"string\");\n expect(content.text.length).toBeGreaterThan(0);\n expect(content.uri).toBe(uri);\n }\n\n await teardown();\n });\n\n it(\"resolves a stale cache key when the canonical URI carries ?v= (prod)\", async () => {\n process.env.NODE_ENV = \"production\";\n __setBuildManifest({\n \"src/views/widget.tsx\": {\n isEntry: true,\n name: \"widget\",\n file: \"assets/widget-ABC123.js\",\n },\n \"style.css\": { file: \"assets/style-XYZ.css\" },\n } as unknown as Record<string, { file: string }>);\n\n const { client, teardown } = await connect(registerWidget);\n\n const { resources } = await client.listResources();\n const listed = resources.find((r) =>\n r.uri.startsWith(\"ui://views/ext-apps/widget.html\"),\n );\n // Production advertises a content-derived cache key.\n expect(listed?.uri).toMatch(\n /^ui:\\/\\/views\\/ext-apps\\/widget\\.html\\?v=[0-9a-f]{8}$/,\n );\n\n // A consumer holding a stale key still resolves the current asset.\n const staleUri = \"ui://views/ext-apps/widget.html?v=00000000\";\n const { contents } = await client.readResource({ uri: staleUri });\n expect(contents).toHaveLength(1);\n const content = textContent(contents);\n expect(typeof content.text).toBe(\"string\");\n expect(content.uri).toBe(staleUri);\n\n await teardown();\n });\n\n it(\"still throws for an unknown view path\", async () => {\n const { client, teardown } = await connect(registerWidget);\n\n await expect(\n client.readResource({ uri: \"ui://views/ext-apps/nope.html?v=1\" }),\n ).rejects.toThrow();\n\n await teardown();\n });\n\n // A proxy routing the request under a path prefix sends x-forwarded-prefix;\n // the view's asset URLs must carry that prefix (and the forwarded origin) so\n // they resolve back through the same routing. Per-request, so one process can\n // serve many hosts/prefixes at once.\n it(\"prefixes emitted asset URLs with x-forwarded-prefix (prod)\", async () => {\n process.env.NODE_ENV = \"production\";\n __setBuildManifest({\n \"src/views/widget.tsx\": {\n isEntry: true,\n name: \"widget\",\n file: \"assets/widget-ABC123.js\",\n },\n \"style.css\": { file: \"assets/style-XYZ.css\" },\n } as unknown as Record<string, { file: string }>);\n\n const { client, teardown } = await connectHttp(registerWidget, {\n \"x-forwarded-host\": \"foo.com\",\n \"x-forwarded-proto\": \"https\",\n \"x-forwarded-prefix\": \"/v1/canary\",\n });\n try {\n const { contents } = await client.readResource({\n uri: \"ui://views/ext-apps/widget.html\",\n });\n const { text } = textContent(contents);\n // Forwarded origin + prefix. (`assets/assets` is the existing layout: the\n // manifest `file` already carries `assets/` and the template prepends\n // `/assets/`; build.tsx's `_redirects` collapses it on the asset host.)\n expect(text).toContain(\n \"https://foo.com/v1/canary/assets/assets/widget-ABC123.js\",\n );\n expect(text).toContain(\n \"https://foo.com/v1/canary/assets/assets/style-XYZ.css\",\n );\n // No unprefixed asset URL leaks through.\n expect(text).not.toContain(\"foo.com/assets/\");\n } finally {\n await teardown();\n }\n });\n\n // Back-compat: older Skybridge advertised the view at `ui://views/apps-sdk/...`\n // via openai/outputTemplate. We no longer advertise it, but apps published then\n // have it cached, so the read must still resolve to the ext-apps content.\n it(\"resolves the legacy apps-sdk URL to the ext-apps content\", async () => {\n const { client, teardown } = await connect(registerWidget);\n\n const legacyUri = \"ui://views/apps-sdk/widget.html\";\n const { contents } = await client.readResource({ uri: legacyUri });\n\n expect(contents).toHaveLength(1);\n const content = contents[0] as {\n uri: string;\n text: string;\n mimeType: string;\n };\n expect(content.mimeType).toBe(\"text/html;profile=mcp-app\");\n expect(content.text.length).toBeGreaterThan(0);\n // The response echoes the requested (legacy) URI, never the canonical one.\n expect(content.uri).toBe(legacyUri);\n\n await teardown();\n });\n});\n"]}
1
+ {"version":3,"file":"view-resource-resolution.test.js","sourceRoot":"","sources":["../../src/server/view-resource-resolution.test.ts"],"names":[],"mappings":"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","sourcesContent":["import http from \"node:http\";\nimport {\n Client,\n InMemoryTransport,\n StreamableHTTPClientTransport,\n} from \"@modelcontextprotocol/client\";\nimport type { RequestHandler } from \"express\";\nimport { afterEach, describe, expect, it, vi } from \"vitest\";\nimport { __setBuildManifest, type McpServer, Skybridge } from \"./index.js\";\n\nvi.mock(\"@skybridge/devtools\", () => ({\n devtoolsStaticServer: () =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\nvi.mock(\"./viewsDevServer.js\", () => ({\n viewsDevServer: (_httpServer: unknown) =>\n ((_req: unknown, _res: unknown, next: () => void) =>\n next()) as RequestHandler,\n}));\n\n// Mirror what the Skybridge Vite plugin generates in `.skybridge/views.d.ts`:\n// narrow `ViewName` so `component: \"widget\"` typechecks against the registry.\ndeclare module \"./server.js\" {\n interface ViewNameRegistry {\n widget: true;\n }\n}\n\n// SKY-435: a view resource must resolve no matter the `?v=` query param value.\n// The version param is a content-derived cache key for external consumers\n// (it busts host/CDN caches when the bundle changes); it is not part of the\n// resource's identity, so a stale, absent, or arbitrary param must still serve\n// the underlying asset.\n\nfunction buildApp(register: (server: McpServer) => void) {\n return new Skybridge({\n name: \"test\",\n version: \"1.0.0\",\n handler: (server) => {\n register(server);\n return server;\n },\n });\n}\n\nasync function connect(register: (server: McpServer) => void) {\n const instance = await buildApp(register).createServerInstance();\n const client = new Client({ name: \"test-client\", version: \"1.0.0\" });\n const [clientTransport, serverTransport] =\n InMemoryTransport.createLinkedPair();\n await instance.connect(serverTransport);\n await client.connect(clientTransport);\n return {\n client,\n teardown: async () => {\n await client.close();\n await instance.close();\n },\n };\n}\n\nlet openHttpServer: http.Server | undefined;\nafterEach(() => openHttpServer?.close());\n\n// Connect over real HTTP so forwarded proxy headers reach the resource handler.\nasync function connectHttp(\n register: (server: McpServer) => void,\n headers: Record<string, string>,\n) {\n const { createApp } = await import(\"./express.js\");\n const app = buildApp(register);\n const httpServer = http.createServer();\n await createApp({ app, httpServer });\n const listening = http.createServer(app.express);\n await new Promise<void>((resolve) => listening.listen(0, resolve));\n openHttpServer = listening;\n const port = (listening.address() as { port: number }).port;\n\n const client = new Client({ name: \"test-client\", version: \"1.0.0\" });\n const transport = new StreamableHTTPClientTransport(\n new URL(`http://localhost:${port}/mcp`),\n { requestInit: { headers } },\n );\n await client.connect(transport);\n return {\n client,\n teardown: async () => {\n await client.close();\n },\n };\n}\n\nfunction registerWidget(server: McpServer) {\n server.registerTool(\n { name: \"show\", description: \"show\", view: { component: \"widget\" } },\n () => ({ content: [{ type: \"text\" as const, text: \"ok\" }] }),\n );\n}\n\n/** Narrow a read-resource content entry to its text variant. */\nfunction textContent(contents: Array<{ uri: string }>): {\n uri: string;\n text: string;\n} {\n return contents[0] as { uri: string; text: string };\n}\n\ndescribe(\"view resource resolution (cache key)\", () => {\n afterEach(() => {\n delete process.env.NODE_ENV;\n });\n\n it(\"resolves regardless of the ?v= param and echoes the requested URI\", async () => {\n const { client, teardown } = await connect(registerWidget);\n\n const { resources } = await client.listResources();\n const listed = resources.find((r) =>\n r.uri.startsWith(\"ui://views/ext-apps/widget.html\"),\n );\n // Dev build advertises no cache key.\n expect(listed?.uri).toBe(\"ui://views/ext-apps/widget.html\");\n\n // A stale/arbitrary/absent param all resolve the same underlying asset,\n // and the response echoes the URI the consumer asked for (never rewritten).\n for (const uri of [\n \"ui://views/ext-apps/widget.html?v=stale123\",\n \"ui://views/ext-apps/widget.html?v=whatever-else\",\n \"ui://views/ext-apps/widget.html\",\n ]) {\n const { contents } = await client.readResource({ uri });\n expect(contents).toHaveLength(1);\n const content = textContent(contents);\n expect(typeof content.text).toBe(\"string\");\n expect(content.text.length).toBeGreaterThan(0);\n expect(content.uri).toBe(uri);\n }\n\n await teardown();\n });\n\n it(\"resolves a stale cache key when the canonical URI carries ?v= (prod)\", async () => {\n process.env.NODE_ENV = \"production\";\n __setBuildManifest({\n \"src/views/widget.tsx\": {\n isEntry: true,\n name: \"widget\",\n file: \"assets/widget-ABC123.js\",\n },\n \"style.css\": { file: \"assets/style-XYZ.css\" },\n } as unknown as Record<string, { file: string }>);\n\n const { client, teardown } = await connect(registerWidget);\n\n const { resources } = await client.listResources();\n const listed = resources.find((r) =>\n r.uri.startsWith(\"ui://views/ext-apps/widget.html\"),\n );\n // Production advertises a content-derived cache key.\n expect(listed?.uri).toMatch(\n /^ui:\\/\\/views\\/ext-apps\\/widget\\.html\\?v=[0-9a-f]{8}$/,\n );\n\n // A consumer holding a stale key still resolves the current asset.\n const staleUri = \"ui://views/ext-apps/widget.html?v=00000000\";\n const { contents } = await client.readResource({ uri: staleUri });\n expect(contents).toHaveLength(1);\n const content = textContent(contents);\n expect(typeof content.text).toBe(\"string\");\n expect(content.uri).toBe(staleUri);\n\n await teardown();\n });\n\n it(\"still throws for an unknown view path\", async () => {\n const { client, teardown } = await connect(registerWidget);\n\n await expect(\n client.readResource({ uri: \"ui://views/ext-apps/nope.html?v=1\" }),\n ).rejects.toThrow();\n\n await teardown();\n });\n\n // A proxy routing the request under a path prefix sends x-forwarded-prefix;\n // the view's asset URLs must carry that prefix (and the forwarded origin) so\n // they resolve back through the same routing. Per-request, so one process can\n // serve many hosts/prefixes at once.\n it(\"prefixes emitted asset URLs with x-forwarded-prefix (prod)\", async () => {\n process.env.NODE_ENV = \"production\";\n __setBuildManifest({\n \"src/views/widget.tsx\": {\n isEntry: true,\n name: \"widget\",\n file: \"assets/widget-ABC123.js\",\n },\n \"style.css\": { file: \"assets/style-XYZ.css\" },\n } as unknown as Record<string, { file: string }>);\n\n const { client, teardown } = await connectHttp(registerWidget, {\n \"x-forwarded-host\": \"foo.com\",\n \"x-forwarded-proto\": \"https\",\n \"x-forwarded-prefix\": \"/v1/canary\",\n });\n try {\n const { contents } = await client.readResource({\n uri: \"ui://views/ext-apps/widget.html\",\n });\n const { text } = textContent(contents);\n // Forwarded origin + prefix. (`assets/assets` is the existing layout: the\n // manifest `file` already carries `assets/` and the template prepends\n // `/assets/`; build.tsx's `_redirects` collapses it on the asset host.)\n expect(text).toContain(\n \"https://foo.com/v1/canary/assets/assets/widget-ABC123.js\",\n );\n expect(text).toContain(\n \"https://foo.com/v1/canary/assets/assets/style-XYZ.css\",\n );\n // No unprefixed asset URL leaks through.\n expect(text).not.toContain(\"foo.com/assets/\");\n } finally {\n await teardown();\n }\n });\n\n it(\"preloads the view entry and its static imports (prod)\", async () => {\n process.env.NODE_ENV = \"production\";\n __setBuildManifest({\n \"src/views/widget.tsx\": {\n isEntry: true,\n name: \"widget\",\n file: \"assets/widget-ABC123.js\",\n imports: [\"_shared.js\", \"_ui.js\"],\n dynamicImports: [\"src/lazy.tsx\"],\n },\n \"_shared.js\": { file: \"assets/shared-DEF456.js\" },\n \"_ui.js\": { file: \"assets/ui-GHI789.js\", imports: [\"_shared.js\"] },\n \"src/lazy.tsx\": { file: \"assets/lazy-JKL012.js\", isDynamicEntry: true },\n \"style.css\": { file: \"assets/style-XYZ.css\" },\n } as unknown as Record<string, { file: string }>);\n\n const { client, teardown } = await connect(registerWidget);\n try {\n const { contents } = await client.readResource({\n uri: \"ui://views/ext-apps/widget.html\",\n });\n const { text } = textContent(contents);\n const preloaded = [\n ...text.matchAll(\n /<link rel=\"modulepreload\" crossorigin href=\"[^\"]*\\/assets\\/(assets\\/[^\"]+)\" \\/>/g,\n ),\n ].map((match) => match[1]);\n expect(preloaded).toEqual([\n \"assets/widget-ABC123.js\",\n \"assets/shared-DEF456.js\",\n \"assets/ui-GHI789.js\",\n ]);\n expect(text.indexOf(\"modulepreload\")).toBeLessThan(\n text.indexOf(\"import(\"),\n );\n } finally {\n await teardown();\n }\n });\n\n // Back-compat: older Skybridge advertised the view at `ui://views/apps-sdk/...`\n // via openai/outputTemplate. We no longer advertise it, but apps published then\n // have it cached, so the read must still resolve to the ext-apps content.\n it(\"resolves the legacy apps-sdk URL to the ext-apps content\", async () => {\n const { client, teardown } = await connect(registerWidget);\n\n const legacyUri = \"ui://views/apps-sdk/widget.html\";\n const { contents } = await client.readResource({ uri: legacyUri });\n\n expect(contents).toHaveLength(1);\n const content = contents[0] as {\n uri: string;\n text: string;\n mimeType: string;\n };\n expect(content.mimeType).toBe(\"text/html;profile=mcp-app\");\n expect(content.text.length).toBeGreaterThan(0);\n // The response echoes the requested (legacy) URI, never the canonical one.\n expect(content.uri).toBe(legacyUri);\n\n await teardown();\n });\n});\n"]}
@@ -1,11 +1,12 @@
1
1
  import { type MockInstance } from "vitest";
2
+ import { Skybridge } from "../server/app.js";
2
3
  import { McpServer } from "../server/server.js";
3
4
  export declare function createMockMcpServer(): {
4
5
  server: McpServer;
5
6
  mockRegisterResource: MockInstance<McpServer["registerResource"]>;
6
7
  mockRegisterTool: MockInstance;
7
8
  };
8
- export declare function createTestServer(): McpServer<Record<never, import("../server/server.js").ToolDef<unknown, unknown, unknown>> & {
9
+ export declare function createTestApp(): Skybridge<Record<never, import("../server/server.js").ToolDef> & {
9
10
  "search-trip": import("../server/server.js").ToolDef<{
10
11
  destination: string;
11
12
  departureDate?: string | undefined;
@@ -91,8 +92,8 @@ export declare function createTestServer(): McpServer<Record<never, import("../s
91
92
  processedAt: number;
92
93
  region: string;
93
94
  }>;
94
- }>;
95
- export declare function createMinimalTestServer(): McpServer<Record<never, import("../server/server.js").ToolDef<unknown, unknown, unknown>> & {
95
+ }, undefined, import("../server/auth.js").ExtraClaims>;
96
+ export declare function createMinimalTestApp(): Skybridge<Record<never, import("../server/server.js").ToolDef> & {
96
97
  "search-trip": import("../server/server.js").ToolDef<{
97
98
  destination: string;
98
99
  }, {
@@ -100,8 +101,8 @@ export declare function createMinimalTestServer(): McpServer<Record<never, impor
100
101
  id: string;
101
102
  }[];
102
103
  }, unknown>;
103
- }>;
104
- export declare function createInterfaceTestServer(): McpServer<Record<never, import("../server/server.js").ToolDef<unknown, unknown, unknown>> & {
104
+ }, undefined, import("../server/auth.js").ExtraClaims>;
105
+ export declare function createInterfaceTestApp(): Skybridge<Record<never, import("../server/server.js").ToolDef> & {
105
106
  "interface-view": import("../server/server.js").ToolDef<{
106
107
  id: string;
107
108
  }, {
@@ -111,16 +112,13 @@ export declare function createInterfaceTestServer(): McpServer<Record<never, imp
111
112
  processedBy: string;
112
113
  version: number;
113
114
  }>;
114
- }>;
115
+ }, undefined, import("../server/auth.js").ExtraClaims>;
115
116
  export declare function createMockExtra(host: string, options?: {
116
117
  headers?: Record<string, string | string[]>;
117
118
  url?: URL | string;
118
119
  }): {
119
- requestInfo: {
120
- url?: string | URL | undefined;
121
- headers: {
122
- host: string;
123
- };
120
+ http: {
121
+ req: Request;
124
122
  };
125
123
  };
126
124
  export declare function setTestEnv(env: Record<string, string>): void;