skybridge 0.0.0-dev.fc22b35 → 0.0.0-dev.fc23608
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.
- package/README.md +17 -8
- package/dist/cli/detect-port.d.ts +18 -0
- package/dist/cli/detect-port.js +61 -0
- package/dist/cli/detect-port.js.map +1 -0
- package/dist/cli/types.d.ts +6 -0
- package/dist/cli/types.js +2 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/use-nodemon.d.ts +1 -5
- package/dist/cli/use-nodemon.js +39 -9
- package/dist/cli/use-nodemon.js.map +1 -1
- package/dist/cli/use-tunnel.d.ts +8 -0
- package/dist/cli/use-tunnel.js +102 -0
- package/dist/cli/use-tunnel.js.map +1 -0
- package/dist/commands/build.js +1 -1
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/dev.d.ts +2 -1
- package/dist/commands/dev.js +22 -7
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/start.d.ts +3 -1
- package/dist/commands/start.js +32 -8
- package/dist/commands/start.js.map +1 -1
- package/dist/server/asset-base-url-transform-plugin.d.ts +5 -6
- package/dist/server/asset-base-url-transform-plugin.js +8 -9
- package/dist/server/asset-base-url-transform-plugin.js.map +1 -1
- package/dist/server/asset-base-url-transform-plugin.test.js +12 -13
- package/dist/server/asset-base-url-transform-plugin.test.js.map +1 -1
- package/dist/server/express.d.ts +15 -0
- package/dist/server/express.js +77 -0
- package/dist/server/express.js.map +1 -0
- package/dist/server/express.test.d.ts +1 -0
- package/dist/server/express.test.js +252 -0
- package/dist/server/express.test.js.map +1 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/metric.d.ts +14 -0
- package/dist/server/metric.js +62 -0
- package/dist/server/metric.js.map +1 -0
- package/dist/server/middleware.d.ts +124 -0
- package/dist/server/middleware.js +93 -0
- package/dist/server/middleware.js.map +1 -0
- package/dist/server/middleware.test-d.d.ts +1 -0
- package/dist/server/middleware.test-d.js +75 -0
- package/dist/server/middleware.test-d.js.map +1 -0
- package/dist/server/middleware.test.d.ts +1 -0
- package/dist/server/middleware.test.js +490 -0
- package/dist/server/middleware.test.js.map +1 -0
- package/dist/server/server.d.ts +52 -1
- package/dist/server/server.js +173 -24
- package/dist/server/server.js.map +1 -1
- package/dist/server/templateHelper.d.ts +0 -1
- package/dist/server/templateHelper.js.map +1 -1
- package/dist/server/templates/development.hbs +0 -55
- package/dist/server/widgetsDevServer.d.ts +2 -1
- package/dist/server/widgetsDevServer.js +3 -8
- package/dist/server/widgetsDevServer.js.map +1 -1
- package/dist/test/widget.test.js +67 -19
- package/dist/test/widget.test.js.map +1 -1
- package/dist/version.d.ts +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/dist/web/bridges/apps-sdk/adaptor.d.ts +4 -4
- package/dist/web/bridges/apps-sdk/adaptor.js +26 -15
- package/dist/web/bridges/apps-sdk/adaptor.js.map +1 -1
- package/dist/web/bridges/apps-sdk/bridge.d.ts +1 -1
- package/dist/web/bridges/apps-sdk/index.d.ts +1 -1
- package/dist/web/bridges/apps-sdk/index.js.map +1 -1
- package/dist/web/bridges/apps-sdk/types.d.ts +14 -8
- package/dist/web/bridges/apps-sdk/types.js.map +1 -1
- package/dist/web/bridges/mcp-app/adaptor.d.ts +10 -4
- package/dist/web/bridges/mcp-app/adaptor.js +115 -38
- package/dist/web/bridges/mcp-app/adaptor.js.map +1 -1
- package/dist/web/bridges/mcp-app/bridge.d.ts +13 -30
- package/dist/web/bridges/mcp-app/bridge.js +43 -196
- package/dist/web/bridges/mcp-app/bridge.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.d.ts +5 -3
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js +2 -2
- package/dist/web/bridges/mcp-app/use-mcp-app-context.js.map +1 -1
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js +1 -41
- package/dist/web/bridges/mcp-app/use-mcp-app-context.test.js.map +1 -1
- package/dist/web/bridges/types.d.ts +8 -3
- package/dist/web/components/modal-provider.js +2 -4
- package/dist/web/components/modal-provider.js.map +1 -1
- package/dist/web/create-store.js +15 -1
- package/dist/web/create-store.js.map +1 -1
- package/dist/web/create-store.test.js +9 -4
- package/dist/web/create-store.test.js.map +1 -1
- package/dist/web/data-llm.test.js +11 -8
- package/dist/web/data-llm.test.js.map +1 -1
- package/dist/web/hooks/index.d.ts +1 -1
- package/dist/web/hooks/index.js.map +1 -1
- package/dist/web/hooks/test/utils.js +4 -0
- package/dist/web/hooks/test/utils.js.map +1 -1
- package/dist/web/hooks/use-display-mode.d.ts +3 -3
- package/dist/web/hooks/use-display-mode.js.map +1 -1
- package/dist/web/hooks/use-display-mode.test-d.d.ts +1 -0
- package/dist/web/hooks/use-display-mode.test-d.js +8 -0
- package/dist/web/hooks/use-display-mode.test-d.js.map +1 -0
- package/dist/web/hooks/use-files.test.js +5 -1
- package/dist/web/hooks/use-files.test.js.map +1 -1
- package/dist/web/hooks/use-layout.test.js +3 -3
- package/dist/web/hooks/use-layout.test.js.map +1 -1
- package/dist/web/hooks/use-open-external.d.ts +3 -1
- package/dist/web/hooks/use-open-external.js +1 -1
- package/dist/web/hooks/use-open-external.js.map +1 -1
- package/dist/web/hooks/use-open-external.test.js +26 -11
- package/dist/web/hooks/use-open-external.test.js.map +1 -1
- package/dist/web/hooks/use-request-modal.test.js +5 -1
- package/dist/web/hooks/use-request-modal.test.js.map +1 -1
- package/dist/web/hooks/use-set-open-in-app-url.test.js +5 -11
- package/dist/web/hooks/use-set-open-in-app-url.test.js.map +1 -1
- package/dist/web/hooks/use-tool-info.test.js +1 -1
- package/dist/web/hooks/use-tool-info.test.js.map +1 -1
- package/dist/web/hooks/use-user.js +18 -2
- package/dist/web/hooks/use-user.js.map +1 -1
- package/dist/web/hooks/use-user.test.js +29 -1
- package/dist/web/hooks/use-user.test.js.map +1 -1
- package/dist/web/hooks/use-widget-state.test.js +123 -7
- package/dist/web/hooks/use-widget-state.test.js.map +1 -1
- package/dist/web/plugin/plugin.js +17 -9
- package/dist/web/plugin/plugin.js.map +1 -1
- package/dist/web/plugin/transform-data-llm.js +1 -1
- package/dist/web/plugin/transform-data-llm.js.map +1 -1
- package/dist/web/plugin/validate-widget.d.ts +5 -0
- package/dist/web/plugin/validate-widget.js +27 -0
- package/dist/web/plugin/validate-widget.js.map +1 -0
- package/dist/web/plugin/validate-widget.test.d.ts +1 -0
- package/dist/web/plugin/validate-widget.test.js +42 -0
- package/dist/web/plugin/validate-widget.test.js.map +1 -0
- package/package.json +29 -24
- package/tsconfig.base.json +31 -0
package/dist/server/server.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
|
+
import http from "node:http";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { McpServer as McpServerBase, } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
6
|
import { mergeWith, union } from "es-toolkit";
|
|
7
|
+
import { createApp } from "./express.js";
|
|
8
|
+
import { createMiddlewareEntry } from "./metric.js";
|
|
9
|
+
import { buildMiddlewareChain, getHandlerMaps } from "./middleware.js";
|
|
6
10
|
import { templateHelper } from "./templateHelper.js";
|
|
7
11
|
const mergeWithUnion = (target, source) => {
|
|
8
12
|
return mergeWith(target, source, (targetVal, sourceVal) => {
|
|
@@ -12,6 +16,111 @@ const mergeWithUnion = (target, source) => {
|
|
|
12
16
|
});
|
|
13
17
|
};
|
|
14
18
|
export class McpServer extends McpServerBase {
|
|
19
|
+
express;
|
|
20
|
+
customMiddleware = [];
|
|
21
|
+
customErrorMiddleware = [];
|
|
22
|
+
mcpMiddlewareEntries = [];
|
|
23
|
+
mcpMiddlewareApplied = false;
|
|
24
|
+
use(pathOrHandler, ...handlers) {
|
|
25
|
+
if (typeof pathOrHandler === "string") {
|
|
26
|
+
this.customMiddleware.push({
|
|
27
|
+
path: pathOrHandler,
|
|
28
|
+
handlers,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
this.customMiddleware.push({
|
|
33
|
+
handlers: [pathOrHandler, ...handlers],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
useOnError(pathOrHandler, ...handlers) {
|
|
39
|
+
if (typeof pathOrHandler === "string") {
|
|
40
|
+
this.customErrorMiddleware.push({ path: pathOrHandler, handlers });
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
this.customErrorMiddleware.push({
|
|
44
|
+
handlers: [pathOrHandler, ...handlers],
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
mcpMiddleware(filterOrHandler,
|
|
50
|
+
// biome-ignore lint/suspicious/noExplicitAny: overloads narrow the handler type at call sites; implementation must accept all variants
|
|
51
|
+
maybeHandler) {
|
|
52
|
+
if (this.mcpMiddlewareApplied) {
|
|
53
|
+
throw new Error("Cannot register MCP middleware after run() or connect() has been called");
|
|
54
|
+
}
|
|
55
|
+
const handler = maybeHandler;
|
|
56
|
+
if (typeof filterOrHandler === "function") {
|
|
57
|
+
this.mcpMiddlewareEntries.push({
|
|
58
|
+
filter: null,
|
|
59
|
+
handler: filterOrHandler,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
else if (handler) {
|
|
63
|
+
this.mcpMiddlewareEntries.push({
|
|
64
|
+
filter: filterOrHandler,
|
|
65
|
+
handler,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
throw new Error("mcpMiddleware requires a handler function when a filter is provided");
|
|
70
|
+
}
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
applyMcpMiddleware() {
|
|
74
|
+
if (this.mcpMiddlewareApplied) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
this.mcpMiddlewareApplied = true;
|
|
78
|
+
const monitoringEntry = createMiddlewareEntry();
|
|
79
|
+
const entries = monitoringEntry
|
|
80
|
+
? [monitoringEntry, ...this.mcpMiddlewareEntries]
|
|
81
|
+
: this.mcpMiddlewareEntries;
|
|
82
|
+
if (entries.length === 0) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const { requestHandlers, notificationHandlers } = getHandlerMaps(this.server);
|
|
86
|
+
// Wrap existing handlers and proxy future .set() for lazy SDK registration
|
|
87
|
+
const instrumentMap = (map, isNotification) => {
|
|
88
|
+
for (const [method, handler] of map) {
|
|
89
|
+
map.set(method, buildMiddlewareChain(method, isNotification, handler, entries));
|
|
90
|
+
}
|
|
91
|
+
const originalSet = map.set.bind(map);
|
|
92
|
+
map.set = (method, handler) => originalSet(method, buildMiddlewareChain(method, isNotification, handler, entries));
|
|
93
|
+
};
|
|
94
|
+
instrumentMap(requestHandlers, false);
|
|
95
|
+
instrumentMap(notificationHandlers, true);
|
|
96
|
+
}
|
|
97
|
+
async connect(transport) {
|
|
98
|
+
this.applyMcpMiddleware();
|
|
99
|
+
return super.connect(transport);
|
|
100
|
+
}
|
|
101
|
+
async run() {
|
|
102
|
+
this.applyMcpMiddleware();
|
|
103
|
+
const httpServer = http.createServer();
|
|
104
|
+
if (!this.express) {
|
|
105
|
+
this.express = await createApp({
|
|
106
|
+
mcpServer: this,
|
|
107
|
+
httpServer,
|
|
108
|
+
customMiddleware: this.customMiddleware,
|
|
109
|
+
errorMiddleware: this.customErrorMiddleware,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
httpServer.on("request", this.express);
|
|
113
|
+
return new Promise((resolve, reject) => {
|
|
114
|
+
httpServer.on("error", (error) => {
|
|
115
|
+
console.error("Failed to start server:", error);
|
|
116
|
+
reject(error);
|
|
117
|
+
});
|
|
118
|
+
const port = parseInt(process.env.__PORT ?? "3000", 10);
|
|
119
|
+
httpServer.listen(port, () => {
|
|
120
|
+
resolve();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
}
|
|
15
124
|
registerWidget(name, resourceConfig, toolConfig, toolCallback) {
|
|
16
125
|
const userMeta = resourceConfig._meta;
|
|
17
126
|
const toolMeta = {
|
|
@@ -22,7 +131,7 @@ export class McpServer extends McpServerBase {
|
|
|
22
131
|
hostType: "apps-sdk",
|
|
23
132
|
uri: `ui://widgets/apps-sdk/${name}.html`,
|
|
24
133
|
mimeType: "text/html+skybridge",
|
|
25
|
-
buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
|
|
134
|
+
buildContentMeta: ({ resourceDomains, connectDomains, domain }, overrides) => {
|
|
26
135
|
const userUi = userMeta?.ui;
|
|
27
136
|
const userCsp = userUi?.csp;
|
|
28
137
|
const defaults = {
|
|
@@ -31,7 +140,7 @@ export class McpServer extends McpServerBase {
|
|
|
31
140
|
connect_domains: connectDomains,
|
|
32
141
|
},
|
|
33
142
|
"openai/widgetDomain": domain,
|
|
34
|
-
"openai/widgetDescription":
|
|
143
|
+
"openai/widgetDescription": resourceConfig.description,
|
|
35
144
|
};
|
|
36
145
|
const fromUi = {
|
|
37
146
|
"openai/widgetCSP": {
|
|
@@ -44,7 +153,7 @@ export class McpServer extends McpServerBase {
|
|
|
44
153
|
"openai/widgetPrefersBorder": userUi?.prefersBorder,
|
|
45
154
|
};
|
|
46
155
|
const directOpenaiKeys = Object.fromEntries(Object.entries(userMeta ?? {}).filter(([key]) => key.startsWith("openai/")));
|
|
47
|
-
return mergeWithUnion(mergeWithUnion(defaults, fromUi), directOpenaiKeys);
|
|
156
|
+
return mergeWithUnion(mergeWithUnion(mergeWithUnion(defaults, fromUi), directOpenaiKeys), { "openai/widgetDomain": overrides.domain });
|
|
48
157
|
},
|
|
49
158
|
};
|
|
50
159
|
this.registerWidgetResource({
|
|
@@ -59,7 +168,7 @@ export class McpServer extends McpServerBase {
|
|
|
59
168
|
hostType: "mcp-app",
|
|
60
169
|
uri: `ui://widgets/ext-apps/${name}.html`,
|
|
61
170
|
mimeType: "text/html;profile=mcp-app",
|
|
62
|
-
buildContentMeta: ({ resourceDomains, connectDomains, domain }) => {
|
|
171
|
+
buildContentMeta: ({ resourceDomains, connectDomains, domain }, overrides) => {
|
|
63
172
|
const defaults = {
|
|
64
173
|
ui: {
|
|
65
174
|
csp: {
|
|
@@ -69,7 +178,9 @@ export class McpServer extends McpServerBase {
|
|
|
69
178
|
domain,
|
|
70
179
|
},
|
|
71
180
|
};
|
|
72
|
-
return mergeWithUnion(defaults, {
|
|
181
|
+
return mergeWithUnion(defaults, {
|
|
182
|
+
ui: { ...userMeta?.ui, ...overrides },
|
|
183
|
+
});
|
|
73
184
|
},
|
|
74
185
|
};
|
|
75
186
|
this.registerWidgetResource({
|
|
@@ -81,10 +192,20 @@ export class McpServer extends McpServerBase {
|
|
|
81
192
|
toolMeta["ui/resourceUri"] = widgetConfig.uri;
|
|
82
193
|
toolMeta.ui = { resourceUri: widgetConfig.uri };
|
|
83
194
|
}
|
|
195
|
+
const wrappedToolCallback = async (args, extra) => {
|
|
196
|
+
const result = await toolCallback(args, extra);
|
|
197
|
+
return {
|
|
198
|
+
...result,
|
|
199
|
+
_meta: {
|
|
200
|
+
...result._meta,
|
|
201
|
+
viewUUID: crypto.randomUUID(),
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
};
|
|
84
205
|
this.registerTool(name, {
|
|
85
206
|
...toolConfig,
|
|
86
207
|
_meta: toolMeta,
|
|
87
|
-
},
|
|
208
|
+
}, wrappedToolCallback);
|
|
88
209
|
return this;
|
|
89
210
|
}
|
|
90
211
|
registerTool(name, config, cb) {
|
|
@@ -95,14 +216,33 @@ export class McpServer extends McpServerBase {
|
|
|
95
216
|
const { hostType, uri: widgetUri, mimeType, buildContentMeta, } = widgetConfig;
|
|
96
217
|
this.registerResource(name, widgetUri, { ...resourceConfig, _meta: resourceConfig._meta }, async (uri, extra) => {
|
|
97
218
|
const isProduction = process.env.NODE_ENV === "production";
|
|
98
|
-
const useForwardedHost = process.env.SKYBRIDGE_USE_FORWARDED_HOST === "true";
|
|
99
219
|
const isClaude = extra?.requestInfo?.headers?.["user-agent"] === "Claude-User";
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
220
|
+
const headers = extra?.requestInfo?.headers || {};
|
|
221
|
+
const header = (key) => {
|
|
222
|
+
const val = headers[key];
|
|
223
|
+
return Array.isArray(val) ? val[0] : val;
|
|
224
|
+
};
|
|
225
|
+
let serverUrl;
|
|
226
|
+
const forwardedHost = header("x-forwarded-host");
|
|
227
|
+
const origin = header("origin");
|
|
228
|
+
const host = header("host");
|
|
229
|
+
if (forwardedHost) {
|
|
230
|
+
const proto = header("x-forwarded-proto") || "https";
|
|
231
|
+
serverUrl = `${proto}://${forwardedHost}`;
|
|
232
|
+
}
|
|
233
|
+
else if (origin) {
|
|
234
|
+
serverUrl = origin;
|
|
235
|
+
}
|
|
236
|
+
else if (host) {
|
|
237
|
+
const proto = ["127.0.0.1:", "localhost:"].some((p) => host.startsWith(p))
|
|
238
|
+
? "http"
|
|
239
|
+
: "https";
|
|
240
|
+
serverUrl = `${proto}://${host}`;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
const devPort = process.env.__PORT || "3000";
|
|
244
|
+
serverUrl = `http://localhost:${devPort}`;
|
|
245
|
+
}
|
|
106
246
|
const html = isProduction
|
|
107
247
|
? templateHelper.renderProduction({
|
|
108
248
|
hostType,
|
|
@@ -113,22 +253,31 @@ export class McpServer extends McpServerBase {
|
|
|
113
253
|
: templateHelper.renderDevelopment({
|
|
114
254
|
hostType,
|
|
115
255
|
serverUrl,
|
|
116
|
-
useLocalNetworkAccess: !useExternalHost,
|
|
117
256
|
widgetName: name,
|
|
118
257
|
});
|
|
119
|
-
const
|
|
258
|
+
const connectDomains = [serverUrl];
|
|
259
|
+
if (!isProduction) {
|
|
260
|
+
const wsUrl = new URL(serverUrl);
|
|
261
|
+
wsUrl.protocol = wsUrl.protocol === "https:" ? "wss:" : "ws:";
|
|
262
|
+
connectDomains.push(wsUrl.origin);
|
|
263
|
+
}
|
|
264
|
+
let contentMetaOverrides = {};
|
|
265
|
+
if (isClaude) {
|
|
266
|
+
const pathname = extra?.requestInfo?.url?.pathname ?? "";
|
|
267
|
+
const url = `${serverUrl}${pathname}`;
|
|
268
|
+
const hash = crypto
|
|
269
|
+
.createHash("sha256")
|
|
270
|
+
.update(url)
|
|
271
|
+
.digest("hex")
|
|
272
|
+
.slice(0, 32);
|
|
273
|
+
contentMetaOverrides = { domain: `${hash}.claudemcpcontent.com` };
|
|
274
|
+
}
|
|
120
275
|
const contentMeta = buildContentMeta({
|
|
121
276
|
resourceDomains: [serverUrl],
|
|
122
|
-
connectDomains
|
|
123
|
-
domain:
|
|
124
|
-
? `${crypto
|
|
125
|
-
.createHash("sha256")
|
|
126
|
-
.update(`https://${hostFromHeaders}/mcp`)
|
|
127
|
-
.digest("hex")
|
|
128
|
-
.slice(0, 32)}.claudemcpcontent.com`
|
|
129
|
-
: serverUrl,
|
|
277
|
+
connectDomains,
|
|
278
|
+
domain: serverUrl,
|
|
130
279
|
baseUriDomains: [serverUrl],
|
|
131
|
-
});
|
|
280
|
+
}, contentMetaOverrides);
|
|
132
281
|
return {
|
|
133
282
|
contents: [
|
|
134
283
|
{ uri: uri.href, mimeType, text: html, _meta: contentMeta },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,EACL,SAAS,IAAI,aAAa,GAG3B,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +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,
|
|
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"}
|
|
@@ -6,61 +6,6 @@
|
|
|
6
6
|
window.__vite_plugin_react_preamble_installed__ = true;
|
|
7
7
|
</script>
|
|
8
8
|
<script type="module" src="{{serverUrl}}/@vite/client"></script>
|
|
9
|
-
{{#if useLocalNetworkAccess}}
|
|
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
|
-
{{/if}}
|
|
64
9
|
<div id="root"></div>
|
|
65
10
|
<script type="module" id="dev-widget-entry">
|
|
66
11
|
import('{{serverUrl}}/src/widgets/{{widgetName}}');
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type http from "node:http";
|
|
1
2
|
import { type Router } from "express";
|
|
2
3
|
/**
|
|
3
4
|
* Install Vite dev server
|
|
@@ -9,4 +10,4 @@ import { type Router } from "express";
|
|
|
9
10
|
* app.use(await widgetsRouter());
|
|
10
11
|
* }
|
|
11
12
|
*/
|
|
12
|
-
export declare const widgetsDevServer: () => Promise<Router>;
|
|
13
|
+
export declare const widgetsDevServer: (httpServer: http.Server) => Promise<Router>;
|
|
@@ -13,7 +13,7 @@ import { assetBaseUrlTransformPlugin } from "./asset-base-url-transform-plugin.j
|
|
|
13
13
|
* app.use(await widgetsRouter());
|
|
14
14
|
* }
|
|
15
15
|
*/
|
|
16
|
-
export const widgetsDevServer = async () => {
|
|
16
|
+
export const widgetsDevServer = async (httpServer) => {
|
|
17
17
|
const router = express.Router();
|
|
18
18
|
const { createServer, searchForWorkspaceRoot, loadConfigFromFile } = await import("vite");
|
|
19
19
|
// Since 0.16.0, the template is a single package that does not rely on workspace.
|
|
@@ -36,19 +36,14 @@ export const widgetsDevServer = async () => {
|
|
|
36
36
|
allowedHosts: true,
|
|
37
37
|
middlewareMode: true,
|
|
38
38
|
hmr: {
|
|
39
|
-
|
|
40
|
-
host: "localhost",
|
|
41
|
-
port: 24678,
|
|
39
|
+
server: httpServer,
|
|
42
40
|
},
|
|
43
41
|
},
|
|
44
42
|
root: webAppRoot,
|
|
45
43
|
optimizeDeps: {
|
|
46
44
|
include: ["react", "react-dom/client"],
|
|
47
45
|
},
|
|
48
|
-
plugins: [
|
|
49
|
-
...userPlugins,
|
|
50
|
-
assetBaseUrlTransformPlugin({ devServerOrigin: "http://localhost:3000" }),
|
|
51
|
-
],
|
|
46
|
+
plugins: [...userPlugins, assetBaseUrlTransformPlugin()],
|
|
52
47
|
});
|
|
53
48
|
router.use(cors());
|
|
54
49
|
router.use("/", vite.middlewares);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widgetsDevServer.js","sourceRoot":"","sources":["../../src/server/widgetsDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"widgetsDevServer.js","sourceRoot":"","sources":["../../src/server/widgetsDevServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,OAAO,EAAE,EAAe,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AAEnF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,UAAuB,EACN,EAAE;IACnB,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,EACJ,KAAK,EACL,OAAO,EACP,OAAO,EAAE,WAAW,GAAG,EAAE,EACzB,GAAG,SAAS,EACb,GAAG,YAAY,EAAE,MAAM,IAAI,EAAE,CAAC;IAE/B,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;YACpB,GAAG,EAAE;gBACH,MAAM,EAAE,UAAU;aACnB;SACF;QACD,IAAI,EAAE,UAAU;QAChB,YAAY,EAAE;YACZ,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,CAAC;SACvC;QACD,OAAO,EAAE,CAAC,GAAG,WAAW,EAAE,2BAA2B,EAAE,CAAC;KACzD,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"}
|
package/dist/test/widget.test.js
CHANGED
|
@@ -43,8 +43,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
43
43
|
const appsSdkResourceCallback = mockRegisterResource.mock
|
|
44
44
|
.calls[0]?.[3];
|
|
45
45
|
expect(appsSdkResourceCallback).toBeDefined();
|
|
46
|
-
const
|
|
47
|
-
const
|
|
46
|
+
const host = "localhost:3000";
|
|
47
|
+
const serverUrl = `http://${host}`;
|
|
48
|
+
const hmrUrl = `ws://${host}`;
|
|
49
|
+
const mockExtra = createMockExtra(host);
|
|
48
50
|
const result = await appsSdkResourceCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), mockExtra);
|
|
49
51
|
expect(mockRegisterTool).toHaveBeenCalled();
|
|
50
52
|
expect(result).toEqual({
|
|
@@ -56,10 +58,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
56
58
|
_meta: {
|
|
57
59
|
"openai/widgetCSP": {
|
|
58
60
|
resource_domains: [serverUrl],
|
|
59
|
-
connect_domains: [
|
|
61
|
+
connect_domains: [serverUrl, hmrUrl],
|
|
60
62
|
},
|
|
61
63
|
"openai/widgetDomain": serverUrl,
|
|
62
|
-
"openai/widgetDescription": "Test
|
|
64
|
+
"openai/widgetDescription": "Test widget",
|
|
63
65
|
},
|
|
64
66
|
},
|
|
65
67
|
],
|
|
@@ -93,10 +95,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
93
95
|
_meta: {
|
|
94
96
|
"openai/widgetCSP": {
|
|
95
97
|
resource_domains: [serverUrl],
|
|
96
|
-
connect_domains: [],
|
|
98
|
+
connect_domains: [serverUrl],
|
|
97
99
|
},
|
|
98
100
|
"openai/widgetDomain": serverUrl,
|
|
99
|
-
"openai/widgetDescription": "Test
|
|
101
|
+
"openai/widgetDescription": "Test widget",
|
|
100
102
|
},
|
|
101
103
|
},
|
|
102
104
|
],
|
|
@@ -134,7 +136,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
134
136
|
expect(mockRegisterResource).toHaveBeenCalledTimes(2);
|
|
135
137
|
const appsSdkCallback = mockRegisterResource.mock
|
|
136
138
|
.calls[0]?.[3];
|
|
137
|
-
const appsSdkResult = await appsSdkCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), createMockExtra("
|
|
139
|
+
const appsSdkResult = await appsSdkCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), createMockExtra("localhost:3000"));
|
|
140
|
+
const host = "localhost:3000";
|
|
141
|
+
const serverUrl = `http://${host}`;
|
|
142
|
+
const hmrUrl = `ws://${host}`;
|
|
138
143
|
expect(appsSdkResult).toEqual({
|
|
139
144
|
contents: [
|
|
140
145
|
{
|
|
@@ -143,11 +148,11 @@ describe("McpServer.registerWidget", () => {
|
|
|
143
148
|
text: expect.stringContaining('<div id="root"></div>'),
|
|
144
149
|
_meta: {
|
|
145
150
|
"openai/widgetCSP": {
|
|
146
|
-
resource_domains: [
|
|
147
|
-
connect_domains: [
|
|
151
|
+
resource_domains: [serverUrl],
|
|
152
|
+
connect_domains: [serverUrl, hmrUrl],
|
|
148
153
|
},
|
|
149
|
-
"openai/widgetDomain":
|
|
150
|
-
"openai/widgetDescription": "Test
|
|
154
|
+
"openai/widgetDomain": serverUrl,
|
|
155
|
+
"openai/widgetDescription": "Test widget",
|
|
151
156
|
"openai/widgetPrefersBorder": true,
|
|
152
157
|
},
|
|
153
158
|
},
|
|
@@ -157,7 +162,7 @@ describe("McpServer.registerWidget", () => {
|
|
|
157
162
|
const extAppsResourceCallback = mockRegisterResource.mock
|
|
158
163
|
.calls[1]?.[3];
|
|
159
164
|
expect(extAppsResourceCallback).toBeDefined();
|
|
160
|
-
const extAppsResult = await extAppsResourceCallback(new URL("ui://widgets/ext-apps/my-widget.html"), createMockExtra(
|
|
165
|
+
const extAppsResult = await extAppsResourceCallback(new URL("ui://widgets/ext-apps/my-widget.html"), createMockExtra(host));
|
|
161
166
|
expect(extAppsResult).toEqual({
|
|
162
167
|
contents: [
|
|
163
168
|
{
|
|
@@ -167,10 +172,10 @@ describe("McpServer.registerWidget", () => {
|
|
|
167
172
|
_meta: {
|
|
168
173
|
ui: {
|
|
169
174
|
csp: {
|
|
170
|
-
resourceDomains: [
|
|
171
|
-
connectDomains: [
|
|
175
|
+
resourceDomains: [serverUrl],
|
|
176
|
+
connectDomains: [serverUrl, hmrUrl],
|
|
172
177
|
},
|
|
173
|
-
domain:
|
|
178
|
+
domain: serverUrl,
|
|
174
179
|
},
|
|
175
180
|
},
|
|
176
181
|
},
|
|
@@ -214,12 +219,15 @@ describe("McpServer.registerWidget", () => {
|
|
|
214
219
|
server.registerWidget("override-test", mockRegisterResourceConfig, mockToolConfig, mockToolCallback);
|
|
215
220
|
const appsSdkCallback = mockRegisterResource.mock
|
|
216
221
|
.calls[0]?.[3];
|
|
217
|
-
const
|
|
222
|
+
const host = `localhost:3000`;
|
|
223
|
+
const serverUrl = `http://${host}`;
|
|
224
|
+
const hmrUrl = `ws://${host}`;
|
|
225
|
+
const result = await appsSdkCallback(new URL("ui://widgets/apps-sdk/override-test.html"), createMockExtra(host));
|
|
218
226
|
const meta = result.contents[0]?._meta;
|
|
219
227
|
// CSP arrays are merged with union - all unique domains from defaults and user config are preserved
|
|
220
228
|
expect(meta["openai/widgetCSP"]).toEqual({
|
|
221
|
-
resource_domains: [
|
|
222
|
-
connect_domains: [
|
|
229
|
+
resource_domains: [serverUrl, "https://from-ui-csp.com"],
|
|
230
|
+
connect_domains: [serverUrl, hmrUrl, "https://from-ui-csp.com"],
|
|
223
231
|
frame_domains: undefined,
|
|
224
232
|
redirect_domains: undefined,
|
|
225
233
|
});
|
|
@@ -228,7 +236,7 @@ describe("McpServer.registerWidget", () => {
|
|
|
228
236
|
// PrefersBorder should be overridden by direct openai/* key (highest priority)
|
|
229
237
|
expect(meta["openai/widgetPrefersBorder"]).toBe(true);
|
|
230
238
|
// Description should be from defaults (toolConfig.description)
|
|
231
|
-
expect(meta["openai/widgetDescription"]).toBe("Test
|
|
239
|
+
expect(meta["openai/widgetDescription"]).toBe("Test widget");
|
|
232
240
|
});
|
|
233
241
|
it("should register tool with ui.resourceUri metadata only", async () => {
|
|
234
242
|
const mockToolCallback = vi.fn();
|
|
@@ -242,6 +250,46 @@ describe("McpServer.registerWidget", () => {
|
|
|
242
250
|
});
|
|
243
251
|
expect(toolConfig._meta?.["openai/outputTemplate"]).to.be.undefined;
|
|
244
252
|
});
|
|
253
|
+
it("should inject viewUUID into _meta of tool callback results", async () => {
|
|
254
|
+
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
255
|
+
content: [{ type: "text", text: "result" }],
|
|
256
|
+
structuredContent: { data: "test" },
|
|
257
|
+
});
|
|
258
|
+
server.registerWidget("my-widget", { description: "Test widget" }, { description: "Test tool" }, mockToolCallback);
|
|
259
|
+
// The registerTool should have been called with a wrapped callback
|
|
260
|
+
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
261
|
+
expect(wrappedCallback).toBeDefined();
|
|
262
|
+
const result = await wrappedCallback({}, {});
|
|
263
|
+
expect(result._meta).toBeDefined();
|
|
264
|
+
expect(result._meta?.viewUUID).toBeDefined();
|
|
265
|
+
expect(typeof result._meta?.viewUUID).toBe("string");
|
|
266
|
+
// UUID v4 format
|
|
267
|
+
expect(result._meta?.viewUUID).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/);
|
|
268
|
+
});
|
|
269
|
+
it("should preserve existing _meta when injecting viewUUID", async () => {
|
|
270
|
+
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
271
|
+
content: [{ type: "text", text: "result" }],
|
|
272
|
+
structuredContent: { data: "test" },
|
|
273
|
+
_meta: { requestId: "req-123", cached: true },
|
|
274
|
+
});
|
|
275
|
+
server.registerWidget("my-widget", { description: "Test widget" }, { description: "Test tool" }, mockToolCallback);
|
|
276
|
+
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
277
|
+
const result = await wrappedCallback({}, {});
|
|
278
|
+
expect(result._meta?.requestId).toBe("req-123");
|
|
279
|
+
expect(result._meta?.cached).toBe(true);
|
|
280
|
+
expect(result._meta?.viewUUID).toBeDefined();
|
|
281
|
+
});
|
|
282
|
+
it("should generate unique viewUUIDs across calls", async () => {
|
|
283
|
+
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
284
|
+
content: [{ type: "text", text: "result" }],
|
|
285
|
+
structuredContent: {},
|
|
286
|
+
});
|
|
287
|
+
server.registerWidget("my-widget", { description: "Test widget" }, { description: "Test tool" }, mockToolCallback);
|
|
288
|
+
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
289
|
+
const result1 = await wrappedCallback({}, {});
|
|
290
|
+
const result2 = await wrappedCallback({}, {});
|
|
291
|
+
expect(result1._meta?.viewUUID).not.toBe(result2._meta?.viewUUID);
|
|
292
|
+
});
|
|
245
293
|
it("should register tool with uopenai/outputTemplate metadata only", async () => {
|
|
246
294
|
const mockToolCallback = vi.fn();
|
|
247
295
|
server.registerWidget("my-widget", { description: "Test widget", hosts: ["apps-sdk"] }, { description: "Test tool" }, mockToolCallback);
|