skybridge 0.0.0-dev.ad2a0aa → 0.0.0-dev.ad93096

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 (278) hide show
  1. package/bin/run.js +5 -0
  2. package/dist/cli/use-version.d.ts +1 -0
  3. package/dist/cli/use-version.js +34 -0
  4. package/dist/cli/use-version.js.map +1 -0
  5. package/dist/commands/dev.d.ts +7 -0
  6. package/dist/commands/dev.js +35 -0
  7. package/dist/commands/dev.js.map +1 -0
  8. package/dist/{src/server → server}/index.d.ts +0 -1
  9. package/dist/{src/server → server}/index.js +0 -1
  10. package/dist/server/index.js.map +1 -0
  11. package/dist/server/inferUtilityTypes.js.map +1 -0
  12. package/dist/{src/server → server}/server.d.ts +29 -2
  13. package/dist/{src/server → server}/server.js +54 -16
  14. package/dist/server/server.js.map +1 -0
  15. package/dist/server/templateHelper.js.map +1 -0
  16. package/dist/server/templates/development.hbs +66 -0
  17. package/dist/{src/server → server}/templates/production.hbs +1 -1
  18. package/dist/{src/server → server}/widgetsDevServer.d.ts +2 -2
  19. package/dist/{src/server → server}/widgetsDevServer.js +11 -3
  20. package/dist/server/widgetsDevServer.js.map +1 -0
  21. package/dist/test/utils.js.map +1 -0
  22. package/dist/{src/test → test}/widget.test.js +104 -13
  23. package/dist/test/widget.test.js.map +1 -0
  24. package/dist/web/bridges/adaptors/apps-sdk-adaptor.d.ts +13 -0
  25. package/dist/web/bridges/adaptors/apps-sdk-adaptor.js +33 -0
  26. package/dist/web/bridges/adaptors/apps-sdk-adaptor.js.map +1 -0
  27. package/dist/web/bridges/adaptors/mcp-app-adaptor.d.ts +16 -0
  28. package/dist/web/bridges/adaptors/mcp-app-adaptor.js +115 -0
  29. package/dist/web/bridges/adaptors/mcp-app-adaptor.js.map +1 -0
  30. package/dist/web/bridges/apps-sdk-bridge.d.ts +10 -0
  31. package/dist/web/bridges/apps-sdk-bridge.js +46 -0
  32. package/dist/web/bridges/apps-sdk-bridge.js.map +1 -0
  33. package/dist/web/bridges/hooks/use-adaptor.d.ts +2 -0
  34. package/dist/web/bridges/hooks/use-adaptor.js +8 -0
  35. package/dist/web/bridges/hooks/use-adaptor.js.map +1 -0
  36. package/dist/web/bridges/hooks/use-apps-sdk-bridge.d.ts +2 -0
  37. package/dist/web/bridges/hooks/use-apps-sdk-bridge.js +7 -0
  38. package/dist/web/bridges/hooks/use-apps-sdk-bridge.js.map +1 -0
  39. package/dist/web/bridges/hooks/use-bridge.d.ts +2 -0
  40. package/dist/web/bridges/hooks/use-bridge.js +8 -0
  41. package/dist/web/bridges/hooks/use-bridge.js.map +1 -0
  42. package/dist/web/bridges/hooks/use-mcp-app-bridge.d.ts +5 -0
  43. package/dist/web/bridges/hooks/use-mcp-app-bridge.js +7 -0
  44. package/dist/web/bridges/hooks/use-mcp-app-bridge.js.map +1 -0
  45. package/dist/web/bridges/hooks/use-mcp-app-bridge.test.js +41 -0
  46. package/dist/web/bridges/hooks/use-mcp-app-bridge.test.js.map +1 -0
  47. package/dist/web/bridges/index.d.ts +4 -0
  48. package/dist/web/bridges/index.js +5 -0
  49. package/dist/web/bridges/index.js.map +1 -0
  50. package/dist/web/bridges/mcp-app-bridge.d.ts +38 -0
  51. package/dist/web/bridges/mcp-app-bridge.js +162 -0
  52. package/dist/web/bridges/mcp-app-bridge.js.map +1 -0
  53. package/dist/web/bridges/types.d.ts +57 -0
  54. package/dist/web/bridges/types.js +2 -0
  55. package/dist/web/bridges/types.js.map +1 -0
  56. package/dist/web/create-store.js.map +1 -0
  57. package/dist/web/create-store.test.js.map +1 -0
  58. package/dist/{src/web → web}/data-llm.js +4 -2
  59. package/dist/web/data-llm.js.map +1 -0
  60. package/dist/web/data-llm.test.js.map +1 -0
  61. package/dist/web/generate-helpers.js.map +1 -0
  62. package/dist/{src/web → web}/generate-helpers.test-d.js +4 -1
  63. package/dist/web/generate-helpers.test-d.js.map +1 -0
  64. package/dist/web/generate-helpers.test.js.map +1 -0
  65. package/dist/web/helpers/state.js.map +1 -0
  66. package/dist/web/helpers/state.test.js.map +1 -0
  67. package/dist/{src/web → web}/hooks/index.d.ts +2 -3
  68. package/dist/{src/web → web}/hooks/index.js +2 -3
  69. package/dist/web/hooks/index.js.map +1 -0
  70. package/dist/web/hooks/test/utils.d.ts +10 -0
  71. package/dist/web/hooks/test/utils.js +40 -0
  72. package/dist/web/hooks/test/utils.js.map +1 -0
  73. package/dist/{src/web → web}/hooks/use-call-tool.d.ts +1 -1
  74. package/dist/{src/web → web}/hooks/use-call-tool.js +12 -4
  75. package/dist/web/hooks/use-call-tool.js.map +1 -0
  76. package/dist/{src/web → web}/hooks/use-call-tool.test-d.js +1 -1
  77. package/dist/web/hooks/use-call-tool.test-d.js.map +1 -0
  78. package/dist/{src/web → web}/hooks/use-call-tool.test.js +28 -3
  79. package/dist/web/hooks/use-call-tool.test.js.map +1 -0
  80. package/dist/web/hooks/use-display-mode.d.ts +4 -0
  81. package/dist/web/hooks/use-display-mode.js +10 -0
  82. package/dist/web/hooks/use-display-mode.js.map +1 -0
  83. package/dist/{src/web → web}/hooks/use-display-mode.test.js +1 -1
  84. package/dist/web/hooks/use-display-mode.test.js.map +1 -0
  85. package/dist/web/hooks/use-files.js.map +1 -0
  86. package/dist/web/hooks/use-files.test.js.map +1 -0
  87. package/dist/web/hooks/use-layout.d.ts +22 -0
  88. package/dist/web/hooks/use-layout.js +23 -0
  89. package/dist/web/hooks/use-layout.js.map +1 -0
  90. package/dist/web/hooks/use-layout.test.js +95 -0
  91. package/dist/web/hooks/use-layout.test.js.map +1 -0
  92. package/dist/web/hooks/use-open-external.js +8 -0
  93. package/dist/web/hooks/use-open-external.js.map +1 -0
  94. package/dist/web/hooks/use-open-external.test.js +50 -0
  95. package/dist/web/hooks/use-open-external.test.js.map +1 -0
  96. package/dist/{src/web → web}/hooks/use-openai-global.d.ts +1 -1
  97. package/dist/{src/web → web}/hooks/use-openai-global.js +1 -1
  98. package/dist/web/hooks/use-openai-global.js.map +1 -0
  99. package/dist/web/hooks/use-request-modal.d.ts +9 -0
  100. package/dist/web/hooks/use-request-modal.js +14 -0
  101. package/dist/web/hooks/use-request-modal.js.map +1 -0
  102. package/dist/web/hooks/use-request-modal.test.js +57 -0
  103. package/dist/web/hooks/use-request-modal.test.js.map +1 -0
  104. package/dist/web/hooks/use-send-follow-up-message.js +8 -0
  105. package/dist/web/hooks/use-send-follow-up-message.js.map +1 -0
  106. package/dist/{src/web → web}/hooks/use-tool-info.d.ts +12 -1
  107. package/dist/web/hooks/use-tool-info.js +26 -0
  108. package/dist/web/hooks/use-tool-info.js.map +1 -0
  109. package/dist/{src/web → web}/hooks/use-tool-info.test-d.js +40 -4
  110. package/dist/web/hooks/use-tool-info.test-d.js.map +1 -0
  111. package/dist/web/hooks/use-tool-info.test.js +130 -0
  112. package/dist/web/hooks/use-tool-info.test.js.map +1 -0
  113. package/dist/web/hooks/use-user.d.ts +18 -0
  114. package/dist/web/hooks/use-user.js +19 -0
  115. package/dist/web/hooks/use-user.js.map +1 -0
  116. package/dist/web/hooks/use-user.test.js +93 -0
  117. package/dist/web/hooks/use-user.test.js.map +1 -0
  118. package/dist/{src/web → web}/hooks/use-widget-state.js +1 -1
  119. package/dist/web/hooks/use-widget-state.js.map +1 -0
  120. package/dist/{src/web → web}/hooks/use-widget-state.test.js +1 -1
  121. package/dist/web/hooks/use-widget-state.test.js.map +1 -0
  122. package/dist/web/index.js.map +1 -0
  123. package/dist/web/mount-widget.js.map +1 -0
  124. package/dist/web/plugin/data-llm.test.js.map +1 -0
  125. package/dist/web/plugin/plugin.js.map +1 -0
  126. package/dist/{src/web → web}/plugin/transform-data-llm.js +6 -3
  127. package/dist/web/plugin/transform-data-llm.js.map +1 -0
  128. package/dist/web/plugin/transform-data-llm.test.js.map +1 -0
  129. package/dist/web/proxy.js.map +1 -0
  130. package/dist/{src/web → web}/types.d.ts +20 -9
  131. package/dist/web/types.js.map +1 -0
  132. package/package.json +47 -33
  133. package/README.md +0 -125
  134. package/dist/src/server/devtoolsStaticServer.d.ts +0 -15
  135. package/dist/src/server/devtoolsStaticServer.js +0 -38
  136. package/dist/src/server/devtoolsStaticServer.js.map +0 -1
  137. package/dist/src/server/index.js.map +0 -1
  138. package/dist/src/server/inferUtilityTypes.js.map +0 -1
  139. package/dist/src/server/server.js.map +0 -1
  140. package/dist/src/server/templateHelper.js.map +0 -1
  141. package/dist/src/server/templates/development.hbs +0 -13
  142. package/dist/src/server/widgetsDevServer.js.map +0 -1
  143. package/dist/src/test/utils.js.map +0 -1
  144. package/dist/src/test/widget.test.js.map +0 -1
  145. package/dist/src/web/bridges/constants.d.ts +0 -2
  146. package/dist/src/web/bridges/constants.js +0 -3
  147. package/dist/src/web/bridges/constants.js.map +0 -1
  148. package/dist/src/web/bridges/index.d.ts +0 -2
  149. package/dist/src/web/bridges/index.js +0 -3
  150. package/dist/src/web/bridges/index.js.map +0 -1
  151. package/dist/src/web/bridges/use-apps-sdk-bridge.d.ts +0 -7
  152. package/dist/src/web/bridges/use-apps-sdk-bridge.js +0 -39
  153. package/dist/src/web/bridges/use-apps-sdk-bridge.js.map +0 -1
  154. package/dist/src/web/bridges/use-mcp-app-bridge.d.ts +0 -25
  155. package/dist/src/web/bridges/use-mcp-app-bridge.js +0 -128
  156. package/dist/src/web/bridges/use-mcp-app-bridge.js.map +0 -1
  157. package/dist/src/web/bridges/use-mcp-app-bridge.test.js +0 -65
  158. package/dist/src/web/bridges/use-mcp-app-bridge.test.js.map +0 -1
  159. package/dist/src/web/create-store.js.map +0 -1
  160. package/dist/src/web/create-store.test.js.map +0 -1
  161. package/dist/src/web/data-llm.js.map +0 -1
  162. package/dist/src/web/data-llm.test.js.map +0 -1
  163. package/dist/src/web/generate-helpers.js.map +0 -1
  164. package/dist/src/web/generate-helpers.test-d.js.map +0 -1
  165. package/dist/src/web/generate-helpers.test.js.map +0 -1
  166. package/dist/src/web/helpers/state.js.map +0 -1
  167. package/dist/src/web/helpers/state.test.js.map +0 -1
  168. package/dist/src/web/hooks/index.js.map +0 -1
  169. package/dist/src/web/hooks/use-call-tool.js.map +0 -1
  170. package/dist/src/web/hooks/use-call-tool.test-d.js.map +0 -1
  171. package/dist/src/web/hooks/use-call-tool.test.js.map +0 -1
  172. package/dist/src/web/hooks/use-display-mode.d.ts +0 -4
  173. package/dist/src/web/hooks/use-display-mode.js +0 -10
  174. package/dist/src/web/hooks/use-display-mode.js.map +0 -1
  175. package/dist/src/web/hooks/use-display-mode.test.js.map +0 -1
  176. package/dist/src/web/hooks/use-files.js.map +0 -1
  177. package/dist/src/web/hooks/use-files.test.js.map +0 -1
  178. package/dist/src/web/hooks/use-locale.d.ts +0 -1
  179. package/dist/src/web/hooks/use-locale.js +0 -10
  180. package/dist/src/web/hooks/use-locale.js.map +0 -1
  181. package/dist/src/web/hooks/use-locale.test.js +0 -22
  182. package/dist/src/web/hooks/use-locale.test.js.map +0 -1
  183. package/dist/src/web/hooks/use-open-external.js +0 -6
  184. package/dist/src/web/hooks/use-open-external.js.map +0 -1
  185. package/dist/src/web/hooks/use-open-external.test.js +0 -24
  186. package/dist/src/web/hooks/use-open-external.test.js.map +0 -1
  187. package/dist/src/web/hooks/use-openai-global.js.map +0 -1
  188. package/dist/src/web/hooks/use-request-modal.d.ts +0 -6
  189. package/dist/src/web/hooks/use-request-modal.js +0 -9
  190. package/dist/src/web/hooks/use-request-modal.js.map +0 -1
  191. package/dist/src/web/hooks/use-request-modal.test.js +0 -24
  192. package/dist/src/web/hooks/use-request-modal.test.js.map +0 -1
  193. package/dist/src/web/hooks/use-send-follow-up-message.js +0 -11
  194. package/dist/src/web/hooks/use-send-follow-up-message.js.map +0 -1
  195. package/dist/src/web/hooks/use-theme.d.ts +0 -1
  196. package/dist/src/web/hooks/use-theme.js +0 -10
  197. package/dist/src/web/hooks/use-theme.js.map +0 -1
  198. package/dist/src/web/hooks/use-theme.test.js +0 -27
  199. package/dist/src/web/hooks/use-theme.test.js.map +0 -1
  200. package/dist/src/web/hooks/use-tool-info.js +0 -20
  201. package/dist/src/web/hooks/use-tool-info.js.map +0 -1
  202. package/dist/src/web/hooks/use-tool-info.test-d.js.map +0 -1
  203. package/dist/src/web/hooks/use-tool-info.test.js +0 -60
  204. package/dist/src/web/hooks/use-tool-info.test.js.map +0 -1
  205. package/dist/src/web/hooks/use-user-agent.d.ts +0 -1
  206. package/dist/src/web/hooks/use-user-agent.js +0 -5
  207. package/dist/src/web/hooks/use-user-agent.js.map +0 -1
  208. package/dist/src/web/hooks/use-user-agent.test.d.ts +0 -1
  209. package/dist/src/web/hooks/use-user-agent.test.js +0 -32
  210. package/dist/src/web/hooks/use-user-agent.test.js.map +0 -1
  211. package/dist/src/web/hooks/use-widget-state.js.map +0 -1
  212. package/dist/src/web/hooks/use-widget-state.test.js.map +0 -1
  213. package/dist/src/web/index.js.map +0 -1
  214. package/dist/src/web/mount-widget.js.map +0 -1
  215. package/dist/src/web/plugin/data-llm.test.js.map +0 -1
  216. package/dist/src/web/plugin/plugin.js.map +0 -1
  217. package/dist/src/web/plugin/transform-data-llm.js.map +0 -1
  218. package/dist/src/web/plugin/transform-data-llm.test.js.map +0 -1
  219. package/dist/src/web/proxy.js.map +0 -1
  220. package/dist/src/web/types.js.map +0 -1
  221. package/dist/vitest.config.d.ts +0 -2
  222. package/dist/vitest.config.js +0 -8
  223. package/dist/vitest.config.js.map +0 -1
  224. /package/dist/{src/server → server}/inferUtilityTypes.d.ts +0 -0
  225. /package/dist/{src/server → server}/inferUtilityTypes.js +0 -0
  226. /package/dist/{src/server → server}/templateHelper.d.ts +0 -0
  227. /package/dist/{src/server → server}/templateHelper.js +0 -0
  228. /package/dist/{src/test → test}/utils.d.ts +0 -0
  229. /package/dist/{src/test → test}/utils.js +0 -0
  230. /package/dist/{src/test → test}/widget.test.d.ts +0 -0
  231. /package/dist/{src/web/bridges → web/bridges/hooks}/use-mcp-app-bridge.test.d.ts +0 -0
  232. /package/dist/{src/web → web}/create-store.d.ts +0 -0
  233. /package/dist/{src/web → web}/create-store.js +0 -0
  234. /package/dist/{src/web → web}/create-store.test.d.ts +0 -0
  235. /package/dist/{src/web → web}/create-store.test.js +0 -0
  236. /package/dist/{src/web → web}/data-llm.d.ts +0 -0
  237. /package/dist/{src/web → web}/data-llm.test.d.ts +0 -0
  238. /package/dist/{src/web → web}/data-llm.test.js +0 -0
  239. /package/dist/{src/web → web}/generate-helpers.d.ts +0 -0
  240. /package/dist/{src/web → web}/generate-helpers.js +0 -0
  241. /package/dist/{src/web → web}/generate-helpers.test-d.d.ts +0 -0
  242. /package/dist/{src/web → web}/generate-helpers.test.d.ts +0 -0
  243. /package/dist/{src/web → web}/generate-helpers.test.js +0 -0
  244. /package/dist/{src/web → web}/helpers/state.d.ts +0 -0
  245. /package/dist/{src/web → web}/helpers/state.js +0 -0
  246. /package/dist/{src/web → web}/helpers/state.test.d.ts +0 -0
  247. /package/dist/{src/web → web}/helpers/state.test.js +0 -0
  248. /package/dist/{src/web → web}/hooks/use-call-tool.test-d.d.ts +0 -0
  249. /package/dist/{src/web → web}/hooks/use-call-tool.test.d.ts +0 -0
  250. /package/dist/{src/web → web}/hooks/use-display-mode.test.d.ts +0 -0
  251. /package/dist/{src/web → web}/hooks/use-files.d.ts +0 -0
  252. /package/dist/{src/web → web}/hooks/use-files.js +0 -0
  253. /package/dist/{src/web → web}/hooks/use-files.test.d.ts +0 -0
  254. /package/dist/{src/web → web}/hooks/use-files.test.js +0 -0
  255. /package/dist/{src/web/hooks/use-locale.test.d.ts → web/hooks/use-layout.test.d.ts} +0 -0
  256. /package/dist/{src/web → web}/hooks/use-open-external.d.ts +0 -0
  257. /package/dist/{src/web → web}/hooks/use-open-external.test.d.ts +0 -0
  258. /package/dist/{src/web → web}/hooks/use-request-modal.test.d.ts +0 -0
  259. /package/dist/{src/web → web}/hooks/use-send-follow-up-message.d.ts +0 -0
  260. /package/dist/{src/web → web}/hooks/use-tool-info.test-d.d.ts +0 -0
  261. /package/dist/{src/web → web}/hooks/use-tool-info.test.d.ts +0 -0
  262. /package/dist/{src/web/hooks/use-theme.test.d.ts → web/hooks/use-user.test.d.ts} +0 -0
  263. /package/dist/{src/web → web}/hooks/use-widget-state.d.ts +0 -0
  264. /package/dist/{src/web → web}/hooks/use-widget-state.test.d.ts +0 -0
  265. /package/dist/{src/web → web}/index.d.ts +0 -0
  266. /package/dist/{src/web → web}/index.js +0 -0
  267. /package/dist/{src/web → web}/mount-widget.d.ts +0 -0
  268. /package/dist/{src/web → web}/mount-widget.js +0 -0
  269. /package/dist/{src/web → web}/plugin/data-llm.test.d.ts +0 -0
  270. /package/dist/{src/web → web}/plugin/data-llm.test.js +0 -0
  271. /package/dist/{src/web → web}/plugin/plugin.d.ts +0 -0
  272. /package/dist/{src/web → web}/plugin/plugin.js +0 -0
  273. /package/dist/{src/web → web}/plugin/transform-data-llm.d.ts +0 -0
  274. /package/dist/{src/web → web}/plugin/transform-data-llm.test.d.ts +0 -0
  275. /package/dist/{src/web → web}/plugin/transform-data-llm.test.js +0 -0
  276. /package/dist/{src/web → web}/proxy.d.ts +0 -0
  277. /package/dist/{src/web → web}/proxy.js +0 -0
  278. /package/dist/{src/web → web}/types.js +0 -0
package/bin/run.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { execute } from "@oclif/core";
4
+
5
+ await execute({ dir: import.meta.url });
@@ -0,0 +1 @@
1
+ export declare const useVersion: () => string | undefined;
@@ -0,0 +1,34 @@
1
+ import { existsSync, readFileSync } from "fs";
2
+ import path from "path";
3
+ import { useEffect, useState } from "react";
4
+ import { fileURLToPath } from "url";
5
+ function findPackageJson(startDir) {
6
+ let currentDir = startDir;
7
+ const root = path.parse(currentDir).root;
8
+ while (currentDir !== root) {
9
+ const packageJsonPath = path.join(currentDir, "package.json");
10
+ if (existsSync(packageJsonPath)) {
11
+ return packageJsonPath;
12
+ }
13
+ currentDir = path.dirname(currentDir);
14
+ }
15
+ return null;
16
+ }
17
+ function getSkybridgeVersion() {
18
+ const currentFileDir = path.dirname(fileURLToPath(import.meta.url));
19
+ const packageJsonPath = findPackageJson(currentFileDir);
20
+ if (!packageJsonPath) {
21
+ return "";
22
+ }
23
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
24
+ return packageJson.version || "";
25
+ }
26
+ export const useVersion = () => {
27
+ const [version, setVersion] = useState();
28
+ useEffect(() => {
29
+ const v = getSkybridgeVersion();
30
+ setVersion(v);
31
+ }, []);
32
+ return version;
33
+ };
34
+ //# sourceMappingURL=use-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-version.js","sourceRoot":"","sources":["../../src/cli/use-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,SAAS,eAAe,CAAC,QAAgB;IACvC,IAAI,UAAU,GAAG,QAAQ,CAAC;IAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;IAEzC,OAAO,UAAU,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAC9D,IAAI,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YAChC,OAAO,eAAe,CAAC;QACzB,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,mBAAmB;IAC1B,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACpE,MAAM,eAAe,GAAG,eAAe,CAAC,cAAc,CAAC,CAAC;IAExD,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;IACvE,OAAO,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,EAAE;IAC7B,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,EAAU,CAAC;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,GAAG,mBAAmB,EAAE,CAAC;QAChC,UAAU,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class Dev extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {};
6
+ run(): Promise<void>;
7
+ }
@@ -0,0 +1,35 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { spawn } from "node:child_process";
3
+ import { Command, Flags } from "@oclif/core";
4
+ import { Box, render, Text } from "ink";
5
+ import { useEffect } from "react";
6
+ import { useVersion } from "../cli/use-version.js";
7
+ export default class Dev extends Command {
8
+ static description = "Start development server";
9
+ static examples = ["<%= config.bin %> <%= command.id %>"];
10
+ static flags = {};
11
+ async run() {
12
+ const { flags } = await this.parse(Dev);
13
+ // Clear console for fullscreen experience
14
+ console.clear();
15
+ const App = () => {
16
+ const version = useVersion();
17
+ useEffect(() => {
18
+ const nodemon = spawn("nodemon", ["--quiet"], {
19
+ stdio: ["ignore", "ignore", "inherit"],
20
+ });
21
+ return () => {
22
+ if (nodemon && !nodemon.killed) {
23
+ nodemon.kill();
24
+ }
25
+ };
26
+ }, []);
27
+ if (!version) {
28
+ return null;
29
+ }
30
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, marginLeft: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "cyan", bold: true, children: ["\u26F0", " ", "Welcome to Skybridge"] }), _jsxs(Text, { color: "cyan", children: [" v", version] })] }), _jsxs(Box, { children: [_jsxs(Text, { color: "green", children: ["\u2192", " "] }), _jsx(Text, { color: "white", bold: true, children: "Open DevTools to test your app locally" }), _jsxs(Text, { children: [":", " "] }), _jsx(Text, { color: "green", children: "http://localhost:3000/" })] }), _jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsxs(Text, { children: ["MCP server running at:", " "] }), _jsx(Text, { color: "white", bold: true, children: "http://localhost:3000/mcp" })] }), _jsx(Text, { color: "white", underline: true, children: "To test on ChatGPT:" }), _jsxs(Box, { children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsxs(Text, { color: "grey", children: ["Make your local server accessible with", " ", _jsx(Text, { color: "white", bold: true, children: "ngrok http 3000" })] })] }), _jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsxs(Text, { color: "grey", children: ["Connect to ChatGPT with URL", " ", _jsx(Text, { color: "white", bold: true, children: "https://xxxxxx.ngrok-free.app/mcp" })] })] }), _jsxs(Box, { children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsx(Text, { children: "Documentation: " }), _jsx(Text, { color: "white", bold: true, children: "https://skybridge.tech/" })] }), _jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: "#20a832", children: ["\u2192", " "] }), _jsxs(Text, { children: [_jsxs(Text, { color: "white", bold: true, children: ["If you like Skybridge,", " "] }), "please give it a star on GitHub:", " ", _jsx(Text, { color: "white", underline: true, children: "https://github.com/alpic-ai/skybridge" }), " ", "\uD83D\uDE4F"] })] })] }));
31
+ };
32
+ render(_jsx(App, {}), { exitOnCtrlC: true, patchConsole: false });
33
+ }
34
+ }
35
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- export { devtoolsStaticServer } from "./devtoolsStaticServer.js";
2
1
  export type { AnyToolRegistry, InferTools, ToolInput, ToolNames, ToolOutput, ToolResponseMetadata, } from "./inferUtilityTypes.js";
3
2
  export type { McpServerTypes, ToolDef, WidgetHostType } from "./server.js";
4
3
  export { McpServer } from "./server.js";
@@ -1,4 +1,3 @@
1
- export { devtoolsStaticServer } from "./devtoolsStaticServer.js";
2
1
  export { McpServer } from "./server.js";
3
2
  export { widgetsDevServer } from "./widgetsDevServer.js";
4
3
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inferUtilityTypes.js","sourceRoot":"","sources":["../../src/server/inferUtilityTypes.ts"],"names":[],"mappings":""}
@@ -1,3 +1,4 @@
1
+ import type { McpUiResourceMeta } from "@modelcontextprotocol/ext-apps";
1
2
  import { McpServer as McpServerBase, type RegisteredTool } from "@modelcontextprotocol/sdk/server/mcp.js";
2
3
  import type { AnySchema, SchemaOutput, ZodRawShapeCompat } from "@modelcontextprotocol/sdk/server/zod-compat.js";
3
4
  import type { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
@@ -7,8 +8,34 @@ export type ToolDef<TInput = unknown, TOutput = unknown, TResponseMetadata = unk
7
8
  output: TOutput;
8
9
  responseMetadata: TResponseMetadata;
9
10
  };
10
- export type WidgetHostType = "chatgpt-app" | "mcp-app";
11
- type McpServerOriginalResourceConfig = Omit<Resource, "uri" | "name" | "mimeType">;
11
+ /**
12
+ * Extended MCP Apps CSP with upcoming fields from ext-apps PR #158
13
+ * and Skybridge-specific fields for OpenAI compatibility
14
+ * @see https://github.com/modelcontextprotocol/ext-apps/pull/158
15
+ */
16
+ type ExtendedMcpUiResourceCsp = McpUiResourceMeta["csp"] & {
17
+ /** Origins allowed for nested iframe embeds */
18
+ frameDomains?: string[];
19
+ /** Origins permitted for the <base> tag URI directive */
20
+ baseUriDomains?: string[];
21
+ /**
22
+ * Origins that can receive openExternal redirects without safe-link modal (OpenAI-specific)
23
+ * @see https://developers.openai.com/apps-sdk/reference#component-resource-_meta-fields
24
+ */
25
+ redirectDomains?: string[];
26
+ };
27
+ /** Extended MCP Apps resource metadata with upcoming CSP fields */
28
+ type ExtendedMcpUiResourceMeta = Omit<McpUiResourceMeta, "csp"> & {
29
+ csp?: ExtendedMcpUiResourceCsp;
30
+ };
31
+ /** User-provided resource configuration with optional CSP override */
32
+ export type WidgetResourceMeta = {
33
+ ui?: ExtendedMcpUiResourceMeta;
34
+ } & Resource["_meta"];
35
+ export type WidgetHostType = "apps-sdk" | "mcp-app";
36
+ type McpServerOriginalResourceConfig = Omit<Resource, "uri" | "name" | "mimeType" | "_meta"> & {
37
+ _meta?: WidgetResourceMeta;
38
+ };
12
39
  type McpServerOriginalToolConfig = Omit<Parameters<typeof McpServerBase.prototype.registerTool<ZodRawShapeCompat, ZodRawShapeCompat>>[1], "inputSchema" | "outputSchema">;
13
40
  type Simplify<T> = {
14
41
  [K in keyof T]: T[K];
@@ -1,39 +1,70 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import path from "node:path";
3
3
  import { McpServer as McpServerBase, } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { toMerged } from "es-toolkit";
4
5
  import { templateHelper } from "./templateHelper.js";
5
6
  export class McpServer extends McpServerBase {
6
7
  registerWidget(name, resourceConfig, toolConfig, toolCallback) {
7
- const resourceMetadata = {
8
- ...(resourceConfig._meta ?? {}),
9
- };
10
- if (toolConfig.description !== undefined) {
11
- resourceMetadata["openai/widgetDescription"] = toolConfig.description;
12
- }
8
+ const userMeta = resourceConfig._meta;
13
9
  const appsSdkResourceConfig = {
14
- hostType: "chatgpt-app",
10
+ hostType: "apps-sdk",
15
11
  uri: `ui://widgets/apps-sdk/${name}.html`,
16
12
  mimeType: "text/html+skybridge",
13
+ buildContentMeta: ({ serverUrl, wsServerUrl }) => {
14
+ const userUi = userMeta?.ui;
15
+ const defaults = {
16
+ "openai/widgetCSP": {
17
+ resource_domains: [serverUrl],
18
+ connect_domains: [serverUrl, wsServerUrl],
19
+ },
20
+ "openai/widgetDomain": serverUrl,
21
+ "openai/widgetDescription": toolConfig.description,
22
+ };
23
+ const userCsp = userUi?.csp;
24
+ const fromUi = {
25
+ "openai/widgetCSP": {
26
+ resource_domains: userCsp?.resourceDomains,
27
+ connect_domains: userCsp?.connectDomains,
28
+ frame_domains: userCsp?.frameDomains,
29
+ redirect_domains: userCsp?.redirectDomains,
30
+ },
31
+ "openai/widgetDomain": userUi?.domain,
32
+ "openai/widgetPrefersBorder": userUi?.prefersBorder,
33
+ };
34
+ const directOpenaiKeys = Object.fromEntries(Object.entries(userMeta ?? {}).filter(([key]) => key.startsWith("openai/")));
35
+ return toMerged(toMerged(defaults, fromUi), directOpenaiKeys);
36
+ },
17
37
  };
18
38
  const extAppsResourceConfig = {
19
39
  hostType: "mcp-app",
20
40
  uri: `ui://widgets/ext-apps/${name}.html`,
21
41
  mimeType: "text/html;profile=mcp-app",
42
+ buildContentMeta: ({ serverUrl, wsServerUrl }) => {
43
+ const defaults = {
44
+ ui: {
45
+ csp: {
46
+ resourceDomains: [serverUrl],
47
+ connectDomains: [serverUrl, wsServerUrl],
48
+ },
49
+ domain: serverUrl,
50
+ },
51
+ };
52
+ return toMerged(defaults, { ui: userMeta?.ui });
53
+ },
22
54
  };
23
- [appsSdkResourceConfig, extAppsResourceConfig].forEach(({ hostType, uri, mimeType }) => {
55
+ [appsSdkResourceConfig, extAppsResourceConfig].forEach((widgetConfig) => {
24
56
  this.registerWidgetResource({
25
57
  name,
26
- hostType,
27
- widgetUri: uri,
28
- mimeType,
58
+ widgetConfig,
29
59
  resourceConfig,
30
- resourceMetadata,
31
60
  });
32
61
  });
33
62
  const toolMeta = {
34
63
  ...toolConfig._meta,
35
64
  "openai/outputTemplate": appsSdkResourceConfig.uri,
36
- // "ui/resourceUri": extAppsResourceConfig.uri,
65
+ ui: {
66
+ resourceUri: extAppsResourceConfig.uri,
67
+ },
37
68
  };
38
69
  this.registerTool(name, {
39
70
  ...toolConfig,
@@ -45,11 +76,13 @@ export class McpServer extends McpServerBase {
45
76
  super.registerTool(name, config, cb);
46
77
  return this;
47
78
  }
48
- registerWidgetResource({ name, hostType, widgetUri, mimeType, resourceConfig, resourceMetadata, }) {
49
- this.registerResource(name, widgetUri, { ...resourceConfig, _meta: resourceMetadata }, async (uri, extra) => {
79
+ registerWidgetResource({ name, widgetConfig, resourceConfig, }) {
80
+ const { hostType, uri: widgetUri, mimeType, buildContentMeta, } = widgetConfig;
81
+ this.registerResource(name, widgetUri, { ...resourceConfig, _meta: resourceConfig._meta }, async (uri, extra) => {
50
82
  const serverUrl = process.env.NODE_ENV === "production"
51
83
  ? `https://${extra?.requestInfo?.headers?.["x-forwarded-host"] ?? extra?.requestInfo?.headers?.host}`
52
84
  : `http://localhost:3000`;
85
+ const wsServerUrl = serverUrl.replace(/^http/, "ws");
53
86
  const html = process.env.NODE_ENV === "production"
54
87
  ? templateHelper.renderProduction({
55
88
  hostType,
@@ -62,7 +95,12 @@ export class McpServer extends McpServerBase {
62
95
  serverUrl,
63
96
  widgetName: name,
64
97
  });
65
- return { contents: [{ uri: uri.href, mimeType, text: html }] };
98
+ const contentMeta = buildContentMeta({ serverUrl, wsServerUrl });
99
+ return {
100
+ contents: [
101
+ { uri: uri.href, mimeType, text: html, _meta: contentMeta },
102
+ ],
103
+ };
66
104
  });
67
105
  }
68
106
  lookupDistFile(key) {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateHelper.js","sourceRoot":"","sources":["../../src/server/templateHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,UAAU,MAAM,YAAY,CAAC;AAGpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,cAAc;IACV,aAAa,GAAG,IAAI,GAAG,EAAsC,CAAC;IAE9D,YAAY,CAAC,YAAoB;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACpD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,YAAY,MAAM,CAAC,CAAC;QACzE,MAAM,cAAc,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAEpD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,gBAAgB,CAAC,IAKhB;QACC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QACjD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,iBAAiB,CAAC,IAIjB;QACC,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QAClD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC"}
@@ -0,0 +1,66 @@
1
+ <base href="{{serverUrl}}" />
2
+ <script type="module">window.skybridge = { hostType: "{{hostType}}" };</script>
3
+ <script type="module">
4
+ import { injectIntoGlobalHook } from "{{serverUrl}}/assets/@react-refresh";
5
+ injectIntoGlobalHook(window); window.$RefreshReg$ = () => {};
6
+ window.$RefreshSig$ = () => (type) => type;
7
+ window.__vite_plugin_react_preamble_installed__ = true;
8
+ </script>
9
+ <script type="module" src="{{serverUrl}}/@vite/client"></script>
10
+ <script type="module">
11
+ // Checks for browser support and shows error if local network access is denied
12
+ (async () => {
13
+ if (!navigator.permissions?.query) {
14
+ return;
15
+ }
16
+
17
+ // Skip for non-http(s) protocols (file://, custom protocols in Electron, etc.)
18
+ const protocol = window.location.protocol;
19
+ const isNonHttpProtocol = protocol !== 'http:' && protocol !== 'https:'
20
+ if (isNonHttpProtocol) {
21
+ return;
22
+ }
23
+
24
+ const host = window.location.hostname;
25
+ const isLoopback = host === 'localhost'
26
+ || /^127\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.test(host)
27
+ || host === '::1';
28
+ if (isLoopback) {
29
+ return;
30
+ }
31
+
32
+ try {
33
+ const status = await navigator.permissions.query({ name: "local-network-access" });
34
+ if (status.state === "denied") {
35
+ const errorDiv = document.createElement("div");
36
+ errorDiv.style.cssText = "background: #fef2f2; border: 2px solid #ef4444; border-radius: 8px; padding: 16px; text-align: center; z-index: 10000; font-family: system-ui, sans-serif;";
37
+
38
+ const errorTitle = document.createElement("div");
39
+ errorTitle.style.cssText = "color: #ef4444; font-size: 18px; font-weight: 600; margin-bottom: 8px;";
40
+ errorTitle.textContent = "Error: Local network access permission is denied.";
41
+
42
+ const errorMessage = document.createElement("div");
43
+ errorMessage.style.cssText = "color: #ef4444; font-size: 14px;";
44
+ errorMessage.textContent = "Local network access is required for your widget to connect to the local dev server. Please enable it in your browser settings. ";
45
+
46
+ const link = document.createElement("a");
47
+ link.href = "https://developer.chrome.com/blog/local-network-access";
48
+ link.target = "_blank";
49
+ link.rel = "noopener noreferrer";
50
+ link.style.cssText = "color: #ef4444; text-decoration: underline;";
51
+ link.textContent = "Learn more";
52
+ errorMessage.appendChild(link);
53
+
54
+ errorDiv.appendChild(errorTitle);
55
+ errorDiv.appendChild(errorMessage);
56
+ document.body.appendChild(errorDiv);
57
+ }
58
+ } catch (e) {
59
+ // Permission API doesn't support local-network-access, ignore silently
60
+ }
61
+ })();
62
+ </script>
63
+ <div id="root"></div>
64
+ <script type="module" id="dev-widget-entry">
65
+ import('{{serverUrl}}/src/widgets/{{widgetName}}');
66
+ </script>
@@ -1,5 +1,5 @@
1
1
  <base href="{{serverUrl}}" />
2
- <script> window.skybridge = { hostType: "{{hostType}}" }; </script>
2
+ <script type="module">window.skybridge = { hostType: "{{hostType}}" };</script>
3
3
  <div id="root"></div>
4
4
  <script type="module">
5
5
  import('{{serverUrl}}/assets/{{widgetFile}}');
@@ -1,4 +1,4 @@
1
- import { type RequestHandler } from "express";
1
+ import { type Router } from "express";
2
2
  /**
3
3
  * Install Vite dev server
4
4
  * This router MUST be installed at the application root, like so:
@@ -9,4 +9,4 @@ import { type RequestHandler } from "express";
9
9
  * app.use(await widgetsRouter());
10
10
  * }
11
11
  */
12
- export declare const widgetsDevServer: () => Promise<RequestHandler>;
12
+ export declare const widgetsDevServer: () => Promise<Router>;
@@ -1,3 +1,4 @@
1
+ import { existsSync } from "node:fs";
1
2
  import path from "node:path";
2
3
  import cors from "cors";
3
4
  import express, {} from "express";
@@ -14,10 +15,17 @@ import express, {} from "express";
14
15
  export const widgetsDevServer = async () => {
15
16
  const router = express.Router();
16
17
  const { createServer, searchForWorkspaceRoot, loadConfigFromFile } = await import("vite");
17
- const workspaceRoot = searchForWorkspaceRoot(process.cwd());
18
- const webAppRoot = path.join(workspaceRoot, "web");
18
+ // Since 0.16.0, the template is a single package that does not rely on workspace.
19
+ // It means that, when starting the server, the working dir is the template root
20
+ // hence we don't need to walk up the tree to find the workspace, which does not exist anymore.
21
+ let webAppRoot = path.join(process.cwd(), "web");
22
+ // fallback to the old behavior for backward compatibility
23
+ const hasWebAppRoot = existsSync(webAppRoot);
24
+ if (!hasWebAppRoot) {
25
+ const workspaceRoot = searchForWorkspaceRoot(process.cwd());
26
+ webAppRoot = path.join(workspaceRoot, "web");
27
+ }
19
28
  const configResult = await loadConfigFromFile({ command: "serve", mode: "development" }, path.join(webAppRoot, "vite.config.ts"), webAppRoot);
20
- // biome-ignore lint/correctness/noUnusedVariables: Remove build-specific options that don't apply to dev server
21
29
  const { build, preview, ...devConfig } = configResult?.config || {};
22
30
  const vite = await createServer({
23
31
  ...devConfig,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgetsDevServer.js","sourceRoot":"","sources":["../../src/server/widgetsDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,EAAE,EAAe,MAAM,SAAS,CAAC;AAC/C;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAqB,EAAE;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAEhC,MAAM,EAAE,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,GAChE,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAEvB,kFAAkF;IAClF,gFAAgF;IAChF,+FAA+F;IAC/F,IAAI,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;IAEjD,0DAA0D;IAC1D,MAAM,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,MAAM,aAAa,GAAG,sBAAsB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5D,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAC3C,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EACzC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,EACvC,UAAU,CACX,CAAC;IAEF,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,SAAS,EAAE,GAAG,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;IAEpE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC;QAC9B,GAAG,SAAS;QACZ,UAAU,EAAE,KAAK,EAAE,kFAAkF;QACrG,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE;YACN,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;SACrB;QACD,IAAI,EAAE,UAAU;QAChB,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,CAAC;SACvC;KACF,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAElC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"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"}
@@ -5,15 +5,12 @@ const mockManifest = {
5
5
  "src/widgets/folder-widget/index.tsx": { file: "folder-widget.js" },
6
6
  "style.css": { file: "style.css" },
7
7
  };
8
- vi.mock("node:fs", async () => {
9
- const actual = await vi.importActual("node:fs");
8
+ const actual = vi.hoisted(() => require("node:fs"));
9
+ vi.mock("node:fs", () => {
10
10
  const readFileSyncImpl = (path, ...args) => {
11
11
  if (typeof path === "string" && path.includes("manifest.json")) {
12
12
  return JSON.stringify(mockManifest);
13
13
  }
14
- // Type assertion needed because readFileSync has overloads with different parameter types
15
- // Using @ts-expect-error because the overloads are complex and we're forwarding args
16
- // @ts-expect-error - readFileSync overloads require complex type handling
17
14
  return actual.readFileSync(path, ...args);
18
15
  };
19
16
  const readFileSync = vi.fn(readFileSyncImpl);
@@ -56,11 +53,19 @@ describe("McpServer.registerWidget", () => {
56
53
  uri: "ui://widgets/apps-sdk/my-widget.html",
57
54
  mimeType: "text/html+skybridge",
58
55
  text: expect.stringContaining('<div id="root"></div>'),
56
+ _meta: {
57
+ "openai/widgetCSP": {
58
+ resource_domains: [serverUrl],
59
+ connect_domains: [serverUrl, "ws://localhost:3000"],
60
+ },
61
+ "openai/widgetDomain": serverUrl,
62
+ "openai/widgetDescription": "Test tool",
63
+ },
59
64
  },
60
65
  ],
61
66
  });
62
67
  // Check development-specific content
63
- expect(result.contents[0]?.text).toContain(`${serverUrl}/@react-refresh`);
68
+ expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/@react-refresh`);
64
69
  expect(result.contents[0]?.text).toContain(`${serverUrl}/@vite/client`);
65
70
  expect(result.contents[0]?.text).toContain(`${serverUrl}/src/widgets/my-widget`);
66
71
  expect(result.contents[0]?.text).not.toContain(`${serverUrl}/src/widgets/my-widget.tsx`);
@@ -75,8 +80,9 @@ describe("McpServer.registerWidget", () => {
75
80
  const appsSdkResourceCallback = mockRegisterResource.mock
76
81
  .calls[0]?.[3];
77
82
  expect(appsSdkResourceCallback).toBeDefined();
78
- const serverUrl = "https://myapp.com";
79
- const mockExtra = createMockExtra(serverUrl);
83
+ const host = "myapp.com";
84
+ const serverUrl = `https://${host}`;
85
+ const mockExtra = createMockExtra(host);
80
86
  const result = await appsSdkResourceCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), mockExtra);
81
87
  expect(result).toEqual({
82
88
  contents: [
@@ -84,11 +90,19 @@ describe("McpServer.registerWidget", () => {
84
90
  uri: "ui://widgets/apps-sdk/my-widget.html",
85
91
  mimeType: "text/html+skybridge",
86
92
  text: expect.stringContaining('<div id="root"></div>'),
93
+ _meta: {
94
+ "openai/widgetCSP": {
95
+ resource_domains: [serverUrl],
96
+ connect_domains: [serverUrl, `wss://${host}`],
97
+ },
98
+ "openai/widgetDomain": serverUrl,
99
+ "openai/widgetDescription": "Test tool",
100
+ },
87
101
  },
88
102
  ],
89
103
  });
90
104
  // Check production-specific content
91
- expect(result.contents[0]?.text).not.toContain(`${serverUrl}@react-refresh`);
105
+ expect(result.contents[0]?.text).not.toContain(`${serverUrl}/assets/@react-refresh`);
92
106
  expect(result.contents[0]?.text).not.toContain(`${serverUrl}@vite/client`);
93
107
  expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/my-widget.js`);
94
108
  expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/style.css`);
@@ -102,15 +116,19 @@ describe("McpServer.registerWidget", () => {
102
116
  const appsSdkResourceCallback = mockRegisterResource.mock
103
117
  .calls[0]?.[3];
104
118
  expect(appsSdkResourceCallback).toBeDefined();
105
- const serverUrl = "https://myapp.com";
106
- const mockExtra = createMockExtra(serverUrl);
119
+ const host = "myapp.com";
120
+ const serverUrl = `https://${host}`;
121
+ const mockExtra = createMockExtra(host);
107
122
  const result = await appsSdkResourceCallback(new URL("ui://widgets/apps-sdk/folder-widget.html"), mockExtra);
108
123
  // Should resolve to folder-widget.js from the manifest entry "src/widgets/folder-widget/index.tsx"
109
124
  expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/folder-widget.js`);
110
125
  });
111
126
  it("should register resources with correct hostType for both apps-sdk and ext-apps formats", async () => {
112
127
  const mockToolCallback = vi.fn();
113
- const mockRegisterResourceConfig = { description: "Test widget" };
128
+ const mockRegisterResourceConfig = {
129
+ description: "Test widget",
130
+ _meta: { "openai/widgetPrefersBorder": true },
131
+ };
114
132
  const mockToolConfig = { description: "Test tool" };
115
133
  server.registerWidget("my-widget", mockRegisterResourceConfig, mockToolConfig, mockToolCallback);
116
134
  expect(mockRegisterResource).toHaveBeenCalledTimes(2);
@@ -123,10 +141,19 @@ describe("McpServer.registerWidget", () => {
123
141
  uri: "ui://widgets/apps-sdk/my-widget.html",
124
142
  mimeType: "text/html+skybridge",
125
143
  text: expect.stringContaining('<div id="root"></div>'),
144
+ _meta: {
145
+ "openai/widgetCSP": {
146
+ resource_domains: ["http://localhost:3000"],
147
+ connect_domains: ["http://localhost:3000", "ws://localhost:3000"],
148
+ },
149
+ "openai/widgetDomain": "http://localhost:3000",
150
+ "openai/widgetDescription": "Test tool",
151
+ "openai/widgetPrefersBorder": true,
152
+ },
126
153
  },
127
154
  ],
128
155
  });
129
- expect(appsSdkResult.contents[0]?.text).toContain('window.skybridge = { hostType: "chatgpt-app" }');
156
+ expect(appsSdkResult.contents[0]?.text).toContain('window.skybridge = { hostType: "apps-sdk" }');
130
157
  const extAppsResourceCallback = mockRegisterResource.mock
131
158
  .calls[1]?.[3];
132
159
  expect(extAppsResourceCallback).toBeDefined();
@@ -137,10 +164,74 @@ describe("McpServer.registerWidget", () => {
137
164
  uri: "ui://widgets/ext-apps/my-widget.html",
138
165
  mimeType: "text/html;profile=mcp-app",
139
166
  text: expect.stringContaining('<div id="root"></div>'),
167
+ _meta: {
168
+ ui: {
169
+ csp: {
170
+ resourceDomains: ["http://localhost:3000"],
171
+ connectDomains: [
172
+ "http://localhost:3000",
173
+ "ws://localhost:3000",
174
+ ],
175
+ },
176
+ domain: "http://localhost:3000",
177
+ },
178
+ },
140
179
  },
141
180
  ],
142
181
  });
143
182
  expect(extAppsResult.contents[0]?.text).toContain('window.skybridge = { hostType: "mcp-app" }');
144
183
  });
184
+ it("should register tool with ui.resourceUri metadata (not deprecated ui/resourceUri)", async () => {
185
+ const mockToolCallback = vi.fn();
186
+ const mockRegisterResourceConfig = { description: "Test widget" };
187
+ const mockToolConfig = { description: "Test tool" };
188
+ server.registerWidget("my-widget", mockRegisterResourceConfig, mockToolConfig, mockToolCallback);
189
+ expect(mockRegisterTool).toHaveBeenCalledTimes(1);
190
+ const toolCallArgs = mockRegisterTool.mock.calls[0];
191
+ const toolConfig = toolCallArgs?.[1];
192
+ expect(toolConfig._meta).toHaveProperty("ui");
193
+ expect(toolConfig._meta?.ui).toEqual({
194
+ resourceUri: "ui://widgets/ext-apps/my-widget.html",
195
+ });
196
+ });
197
+ it("should apply meta overrides in correct priority: defaults < ui.* < direct openai/* keys", async () => {
198
+ const mockToolCallback = vi.fn();
199
+ const mockRegisterResourceConfig = {
200
+ description: "Test widget",
201
+ _meta: {
202
+ // ui.csp overrides (middle priority)
203
+ ui: {
204
+ csp: {
205
+ resourceDomains: ["https://from-ui-csp.com"],
206
+ connectDomains: ["https://from-ui-csp.com"],
207
+ },
208
+ domain: "https://from-ui-domain.com",
209
+ prefersBorder: false,
210
+ },
211
+ // Direct openai/* keys (highest priority) - should override ui.*
212
+ "openai/widgetDomain": "https://direct-override.com",
213
+ "openai/widgetPrefersBorder": true,
214
+ },
215
+ };
216
+ const mockToolConfig = { description: "Test tool" };
217
+ server.registerWidget("override-test", mockRegisterResourceConfig, mockToolConfig, mockToolCallback);
218
+ const appsSdkCallback = mockRegisterResource.mock
219
+ .calls[0]?.[3];
220
+ const result = await appsSdkCallback(new URL("ui://widgets/apps-sdk/override-test.html"), createMockExtra("__not_used__"));
221
+ const meta = result.contents[0]?._meta;
222
+ // CSP arrays are merged by index - user value replaces at index 0, defaults remain at other indices
223
+ expect(meta["openai/widgetCSP"]).toEqual({
224
+ resource_domains: ["https://from-ui-csp.com"],
225
+ connect_domains: ["https://from-ui-csp.com", "ws://localhost:3000"],
226
+ frame_domains: undefined,
227
+ redirect_domains: undefined,
228
+ });
229
+ // Domain should be overridden by direct openai/* key (highest priority)
230
+ expect(meta["openai/widgetDomain"]).toBe("https://direct-override.com");
231
+ // PrefersBorder should be overridden by direct openai/* key (highest priority)
232
+ expect(meta["openai/widgetPrefersBorder"]).toBe(true);
233
+ // Description should be from defaults (toolConfig.description)
234
+ expect(meta["openai/widgetDescription"]).toBe("Test tool");
235
+ });
145
236
  });
146
237
  //# sourceMappingURL=widget.test.js.map