skybridge 0.0.0-dev.bffc31c → 0.0.0-dev.c003b05
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/dist/cli/use-nodemon.js +2 -2
- package/dist/cli/use-nodemon.js.map +1 -1
- package/dist/commands/build.js +27 -6
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/start.js +2 -7
- package/dist/commands/start.js.map +1 -1
- package/dist/server/content-helpers.d.ts +27 -0
- package/dist/server/content-helpers.js +46 -0
- package/dist/server/content-helpers.js.map +1 -0
- package/dist/server/content-helpers.test.js +70 -0
- package/dist/server/content-helpers.test.js.map +1 -0
- package/dist/server/express.js +2 -2
- package/dist/server/express.js.map +1 -1
- package/dist/server/express.test.js +2 -2
- package/dist/server/express.test.js.map +1 -1
- package/dist/server/index.d.ts +4 -3
- package/dist/server/index.js +3 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware.test.js +12 -9
- package/dist/server/middleware.test.js.map +1 -1
- package/dist/server/server.d.ts +79 -72
- package/dist/server/server.js +141 -85
- package/dist/server/server.js.map +1 -1
- package/dist/server/templateHelper.d.ts +5 -5
- package/dist/server/templates/development.hbs +2 -2
- package/dist/server/templates/production.hbs +1 -1
- package/dist/server/viewsDevServer.d.ts +14 -0
- package/dist/server/viewsDevServer.js +45 -0
- package/dist/server/viewsDevServer.js.map +1 -0
- package/dist/test/utils.d.ts +8 -20
- package/dist/test/utils.js +39 -35
- package/dist/test/utils.js.map +1 -1
- package/dist/test/{widget.test.js → view.test.js} +229 -109
- package/dist/test/view.test.js.map +1 -0
- package/dist/web/bridges/types.d.ts +2 -2
- package/dist/web/generate-helpers.d.ts +20 -18
- package/dist/web/generate-helpers.js +20 -18
- package/dist/web/generate-helpers.js.map +1 -1
- package/dist/web/generate-helpers.test-d.js +20 -20
- package/dist/web/generate-helpers.test-d.js.map +1 -1
- package/dist/web/index.d.ts +1 -0
- package/dist/web/index.js.map +1 -1
- package/dist/web/plugin/plugin.d.ts +4 -1
- package/dist/web/plugin/plugin.js +112 -25
- package/dist/web/plugin/plugin.js.map +1 -1
- package/dist/web/plugin/scan-views.d.ts +8 -0
- package/dist/web/plugin/scan-views.js +70 -0
- package/dist/web/plugin/scan-views.js.map +1 -0
- package/dist/web/plugin/scan-views.test.d.ts +1 -0
- package/dist/web/plugin/scan-views.test.js +67 -0
- package/dist/web/plugin/scan-views.test.js.map +1 -0
- package/dist/web/plugin/validate-view.d.ts +1 -0
- package/dist/web/plugin/validate-view.js +9 -0
- package/dist/web/plugin/validate-view.js.map +1 -0
- package/dist/web/plugin/validate-view.test.d.ts +1 -0
- package/dist/web/plugin/validate-view.test.js +24 -0
- package/dist/web/plugin/validate-view.test.js.map +1 -0
- package/package.json +4 -1
- package/tsconfig.base.json +2 -0
- package/dist/server/widgetsDevServer.d.ts +0 -13
- package/dist/server/widgetsDevServer.js +0 -52
- package/dist/server/widgetsDevServer.js.map +0 -1
- package/dist/test/widget.test.js.map +0 -1
- package/dist/web/plugin/validate-widget.d.ts +0 -5
- package/dist/web/plugin/validate-widget.js +0 -27
- package/dist/web/plugin/validate-widget.js.map +0 -1
- package/dist/web/plugin/validate-widget.test.js +0 -42
- package/dist/web/plugin/validate-widget.test.js.map +0 -1
- /package/dist/{test/widget.test.d.ts → server/content-helpers.test.d.ts} +0 -0
- /package/dist/{web/plugin/validate-widget.test.d.ts → test/view.test.d.ts} +0 -0
|
@@ -2,8 +2,16 @@ import crypto from "node:crypto";
|
|
|
2
2
|
import { afterEach, beforeEach, describe, expect, it, vi, } from "vitest";
|
|
3
3
|
import { createMockExtra, createMockMcpServer, resetTestEnv, setTestEnv, } from "./utils.js";
|
|
4
4
|
const mockManifest = {
|
|
5
|
-
"
|
|
6
|
-
|
|
5
|
+
"skybridge:view:my-widget": {
|
|
6
|
+
file: "assets/my-widget-abc123.js",
|
|
7
|
+
name: "my-widget",
|
|
8
|
+
isEntry: true,
|
|
9
|
+
},
|
|
10
|
+
"skybridge:view:folder-widget": {
|
|
11
|
+
file: "assets/folder-widget-def456.js",
|
|
12
|
+
name: "folder-widget",
|
|
13
|
+
isEntry: true,
|
|
14
|
+
},
|
|
7
15
|
"style.css": { file: "style.css" },
|
|
8
16
|
};
|
|
9
17
|
const actual = vi.hoisted(() => require("node:fs"));
|
|
@@ -22,7 +30,7 @@ vi.mock("node:fs", () => {
|
|
|
22
30
|
},
|
|
23
31
|
};
|
|
24
32
|
});
|
|
25
|
-
describe("McpServer.
|
|
33
|
+
describe("McpServer.registerTool (unified API)", () => {
|
|
26
34
|
let server;
|
|
27
35
|
let mockRegisterResource;
|
|
28
36
|
let mockRegisterTool;
|
|
@@ -36,11 +44,14 @@ describe("McpServer.registerWidget", () => {
|
|
|
36
44
|
});
|
|
37
45
|
it("should generate correct HTML for development mode", async () => {
|
|
38
46
|
setTestEnv({ NODE_ENV: "development" });
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
server.registerTool({
|
|
48
|
+
name: "my-widget",
|
|
49
|
+
description: "Test tool",
|
|
50
|
+
view: {
|
|
51
|
+
component: "my-widget",
|
|
52
|
+
description: "Test view",
|
|
53
|
+
},
|
|
54
|
+
}, vi.fn());
|
|
44
55
|
const appsSdkResourceCallback = mockRegisterResource.mock
|
|
45
56
|
.calls[0]?.[3];
|
|
46
57
|
expect(appsSdkResourceCallback).toBeDefined();
|
|
@@ -62,24 +73,25 @@ describe("McpServer.registerWidget", () => {
|
|
|
62
73
|
connect_domains: [serverUrl, hmrUrl],
|
|
63
74
|
},
|
|
64
75
|
"openai/widgetDomain": serverUrl,
|
|
65
|
-
"openai/widgetDescription": "Test
|
|
76
|
+
"openai/widgetDescription": "Test view",
|
|
66
77
|
},
|
|
67
78
|
},
|
|
68
79
|
],
|
|
69
80
|
});
|
|
70
|
-
// Check development-specific content
|
|
71
81
|
expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/@react-refresh`);
|
|
72
82
|
expect(result.contents[0]?.text).toContain(`${serverUrl}/@vite/client`);
|
|
73
|
-
expect(result.contents[0]?.text).toContain(`${serverUrl}/
|
|
74
|
-
expect(result.contents[0]?.text).not.toContain(`${serverUrl}/src/widgets/my-widget.tsx`);
|
|
83
|
+
expect(result.contents[0]?.text).toContain(`${serverUrl}/_skybridge/view/my-widget`);
|
|
75
84
|
});
|
|
76
85
|
it("should generate correct HTML for production mode", async () => {
|
|
77
86
|
setTestEnv({ NODE_ENV: "production" });
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
server.registerTool({
|
|
88
|
+
name: "my-widget",
|
|
89
|
+
description: "Test tool",
|
|
90
|
+
view: {
|
|
91
|
+
component: "my-widget",
|
|
92
|
+
description: "Test view",
|
|
93
|
+
},
|
|
94
|
+
}, vi.fn());
|
|
83
95
|
const appsSdkResourceCallback = mockRegisterResource.mock
|
|
84
96
|
.calls[0]?.[3];
|
|
85
97
|
expect(appsSdkResourceCallback).toBeDefined();
|
|
@@ -99,21 +111,23 @@ describe("McpServer.registerWidget", () => {
|
|
|
99
111
|
connect_domains: [serverUrl],
|
|
100
112
|
},
|
|
101
113
|
"openai/widgetDomain": serverUrl,
|
|
102
|
-
"openai/widgetDescription": "Test
|
|
114
|
+
"openai/widgetDescription": "Test view",
|
|
103
115
|
},
|
|
104
116
|
},
|
|
105
117
|
],
|
|
106
118
|
});
|
|
107
|
-
// Check production-specific content
|
|
108
119
|
expect(result.contents[0]?.text).not.toContain(`${serverUrl}/assets/@react-refresh`);
|
|
109
120
|
expect(result.contents[0]?.text).not.toContain(`${serverUrl}@vite/client`);
|
|
110
|
-
expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/my-widget.js`);
|
|
121
|
+
expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/assets/my-widget-abc123.js`);
|
|
111
122
|
expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/style.css`);
|
|
112
123
|
});
|
|
113
|
-
it("should prefer x-alpic-forwarded-url when hashing Claude
|
|
124
|
+
it("should prefer x-alpic-forwarded-url when hashing Claude view domains", async () => {
|
|
114
125
|
setTestEnv({ NODE_ENV: "production" });
|
|
115
|
-
|
|
116
|
-
|
|
126
|
+
server.registerTool({
|
|
127
|
+
name: "my-widget",
|
|
128
|
+
description: "Test tool",
|
|
129
|
+
view: { component: "my-widget", description: "Test view" },
|
|
130
|
+
}, vi.fn());
|
|
117
131
|
const extAppsResourceCallback = mockRegisterResource.mock
|
|
118
132
|
.calls[1]?.[3];
|
|
119
133
|
expect(extAppsResourceCallback).toBeDefined();
|
|
@@ -135,42 +149,30 @@ describe("McpServer.registerWidget", () => {
|
|
|
135
149
|
csp: {
|
|
136
150
|
resourceDomains: ["http://localhost:3000"],
|
|
137
151
|
connectDomains: ["http://localhost:3000"],
|
|
152
|
+
baseUriDomains: ["http://localhost:3000"],
|
|
138
153
|
},
|
|
154
|
+
description: "Test view",
|
|
139
155
|
domain: expectedDomain,
|
|
140
156
|
},
|
|
141
157
|
});
|
|
142
158
|
});
|
|
143
|
-
it("should
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const serverUrl = `https://${host}`;
|
|
154
|
-
const mockExtra = createMockExtra(host);
|
|
155
|
-
const result = await appsSdkResourceCallback(new URL("ui://widgets/apps-sdk/folder-widget.html"), mockExtra);
|
|
156
|
-
// Should resolve to folder-widget.js from the manifest entry "src/widgets/folder-widget/index.tsx"
|
|
157
|
-
expect(result.contents[0]?.text).toContain(`${serverUrl}/assets/folder-widget.js`);
|
|
158
|
-
});
|
|
159
|
-
it("should register resources with correct hostType for both apps-sdk and ext-apps formats", async () => {
|
|
160
|
-
const mockToolCallback = vi.fn();
|
|
161
|
-
const mockRegisterResourceConfig = {
|
|
162
|
-
description: "Test widget",
|
|
163
|
-
_meta: { "openai/widgetPrefersBorder": true },
|
|
164
|
-
};
|
|
165
|
-
const mockToolConfig = { description: "Test tool" };
|
|
166
|
-
server.registerWidget("my-widget", mockRegisterResourceConfig, mockToolConfig, mockToolCallback);
|
|
159
|
+
it("should register resources with correct hostType for both apps-sdk and ext-apps", async () => {
|
|
160
|
+
server.registerTool({
|
|
161
|
+
name: "my-widget",
|
|
162
|
+
description: "Test tool",
|
|
163
|
+
view: {
|
|
164
|
+
component: "my-widget",
|
|
165
|
+
description: "Test view",
|
|
166
|
+
prefersBorder: true,
|
|
167
|
+
},
|
|
168
|
+
}, vi.fn());
|
|
167
169
|
expect(mockRegisterResource).toHaveBeenCalledTimes(2);
|
|
168
170
|
const appsSdkCallback = mockRegisterResource.mock
|
|
169
171
|
.calls[0]?.[3];
|
|
170
|
-
const appsSdkResult = await appsSdkCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), createMockExtra("localhost:3000"));
|
|
171
172
|
const host = "localhost:3000";
|
|
172
173
|
const serverUrl = `http://${host}`;
|
|
173
174
|
const hmrUrl = `ws://${host}`;
|
|
175
|
+
const appsSdkResult = await appsSdkCallback(new URL("ui://widgets/apps-sdk/my-widget.html"), createMockExtra(host));
|
|
174
176
|
expect(appsSdkResult).toEqual({
|
|
175
177
|
contents: [
|
|
176
178
|
{
|
|
@@ -183,7 +185,7 @@ describe("McpServer.registerWidget", () => {
|
|
|
183
185
|
connect_domains: [serverUrl, hmrUrl],
|
|
184
186
|
},
|
|
185
187
|
"openai/widgetDomain": serverUrl,
|
|
186
|
-
"openai/widgetDescription": "Test
|
|
188
|
+
"openai/widgetDescription": "Test view",
|
|
187
189
|
"openai/widgetPrefersBorder": true,
|
|
188
190
|
},
|
|
189
191
|
},
|
|
@@ -205,8 +207,11 @@ describe("McpServer.registerWidget", () => {
|
|
|
205
207
|
csp: {
|
|
206
208
|
resourceDomains: [serverUrl],
|
|
207
209
|
connectDomains: [serverUrl, hmrUrl],
|
|
210
|
+
baseUriDomains: [serverUrl],
|
|
208
211
|
},
|
|
209
212
|
domain: serverUrl,
|
|
213
|
+
description: "Test view",
|
|
214
|
+
prefersBorder: true,
|
|
210
215
|
},
|
|
211
216
|
},
|
|
212
217
|
},
|
|
@@ -214,11 +219,12 @@ describe("McpServer.registerWidget", () => {
|
|
|
214
219
|
});
|
|
215
220
|
expect(extAppsResult.contents[0]?.text).toContain('window.skybridge = { hostType: "mcp-app", serverUrl: "http://localhost:3000" };');
|
|
216
221
|
});
|
|
217
|
-
it("should register tool with ui.resourceUri metadata
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
+
it("should register tool with ui.resourceUri metadata", async () => {
|
|
223
|
+
server.registerTool({
|
|
224
|
+
name: "my-widget",
|
|
225
|
+
description: "Test tool",
|
|
226
|
+
view: { component: "my-widget", description: "Test view" },
|
|
227
|
+
}, vi.fn());
|
|
222
228
|
expect(mockRegisterTool).toHaveBeenCalledTimes(1);
|
|
223
229
|
const toolCallArgs = mockRegisterTool.mock.calls[0];
|
|
224
230
|
const toolConfig = toolCallArgs?.[1];
|
|
@@ -227,51 +233,32 @@ describe("McpServer.registerWidget", () => {
|
|
|
227
233
|
resourceUri: "ui://widgets/ext-apps/my-widget.html",
|
|
228
234
|
});
|
|
229
235
|
});
|
|
230
|
-
it("should
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
description: "Test
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
resourceDomains: ["https://from-ui-csp.com"],
|
|
239
|
-
connectDomains: ["https://from-ui-csp.com"],
|
|
240
|
-
},
|
|
241
|
-
domain: "https://from-ui-domain.com",
|
|
242
|
-
prefersBorder: false,
|
|
243
|
-
},
|
|
244
|
-
// Direct openai/* keys (highest priority) - should override ui.*
|
|
245
|
-
"openai/widgetDomain": "https://direct-override.com",
|
|
246
|
-
"openai/widgetPrefersBorder": true,
|
|
236
|
+
it("should register tool with openai/outputTemplate when apps-sdk only", async () => {
|
|
237
|
+
server.registerTool({
|
|
238
|
+
name: "my-widget",
|
|
239
|
+
description: "Test tool",
|
|
240
|
+
view: {
|
|
241
|
+
component: "my-widget",
|
|
242
|
+
description: "Test view",
|
|
243
|
+
hosts: ["apps-sdk"],
|
|
247
244
|
},
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const serverUrl = `http://${host}`;
|
|
255
|
-
const hmrUrl = `ws://${host}`;
|
|
256
|
-
const result = await appsSdkCallback(new URL("ui://widgets/apps-sdk/override-test.html"), createMockExtra(host));
|
|
257
|
-
const meta = result.contents[0]?._meta;
|
|
258
|
-
// CSP arrays are merged with union - all unique domains from defaults and user config are preserved
|
|
259
|
-
expect(meta["openai/widgetCSP"]).toEqual({
|
|
260
|
-
resource_domains: [serverUrl, "https://from-ui-csp.com"],
|
|
261
|
-
connect_domains: [serverUrl, hmrUrl, "https://from-ui-csp.com"],
|
|
262
|
-
frame_domains: undefined,
|
|
263
|
-
redirect_domains: undefined,
|
|
264
|
-
});
|
|
265
|
-
// Domain should be overridden by direct openai/* key (highest priority)
|
|
266
|
-
expect(meta["openai/widgetDomain"]).toBe("https://direct-override.com");
|
|
267
|
-
// PrefersBorder should be overridden by direct openai/* key (highest priority)
|
|
268
|
-
expect(meta["openai/widgetPrefersBorder"]).toBe(true);
|
|
269
|
-
// Description should be from defaults (toolConfig.description)
|
|
270
|
-
expect(meta["openai/widgetDescription"]).toBe("Test widget");
|
|
245
|
+
}, vi.fn());
|
|
246
|
+
expect(mockRegisterTool).toHaveBeenCalledTimes(1);
|
|
247
|
+
const toolCallArgs = mockRegisterTool.mock.calls[0];
|
|
248
|
+
const toolConfig = toolCallArgs?.[1];
|
|
249
|
+
expect(toolConfig._meta).not.toHaveProperty("ui");
|
|
250
|
+
expect(toolConfig._meta?.["openai/outputTemplate"]).toBe("ui://widgets/apps-sdk/my-widget.html");
|
|
271
251
|
});
|
|
272
|
-
it("should register tool with ui.resourceUri
|
|
273
|
-
|
|
274
|
-
|
|
252
|
+
it("should register tool with ui.resourceUri only when mcp-app only", async () => {
|
|
253
|
+
server.registerTool({
|
|
254
|
+
name: "my-widget",
|
|
255
|
+
description: "Test tool",
|
|
256
|
+
view: {
|
|
257
|
+
component: "my-widget",
|
|
258
|
+
description: "Test view",
|
|
259
|
+
hosts: ["mcp-app"],
|
|
260
|
+
},
|
|
261
|
+
}, vi.fn());
|
|
275
262
|
expect(mockRegisterTool).toHaveBeenCalledTimes(1);
|
|
276
263
|
const toolCallArgs = mockRegisterTool.mock.calls[0];
|
|
277
264
|
const toolConfig = toolCallArgs?.[1];
|
|
@@ -279,22 +266,24 @@ describe("McpServer.registerWidget", () => {
|
|
|
279
266
|
expect(toolConfig._meta?.ui).toEqual({
|
|
280
267
|
resourceUri: "ui://widgets/ext-apps/my-widget.html",
|
|
281
268
|
});
|
|
282
|
-
expect(toolConfig._meta?.["openai/outputTemplate"]).
|
|
269
|
+
expect(toolConfig._meta?.["openai/outputTemplate"]).toBeUndefined();
|
|
283
270
|
});
|
|
284
271
|
it("should inject viewUUID into _meta of tool callback results", async () => {
|
|
285
272
|
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
286
273
|
content: [{ type: "text", text: "result" }],
|
|
287
274
|
structuredContent: { data: "test" },
|
|
288
275
|
});
|
|
289
|
-
server.
|
|
290
|
-
|
|
276
|
+
server.registerTool({
|
|
277
|
+
name: "my-widget",
|
|
278
|
+
description: "Test tool",
|
|
279
|
+
view: { component: "my-widget", description: "Test view" },
|
|
280
|
+
}, mockToolCallback);
|
|
291
281
|
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
292
282
|
expect(wrappedCallback).toBeDefined();
|
|
293
283
|
const result = await wrappedCallback({}, {});
|
|
294
284
|
expect(result._meta).toBeDefined();
|
|
295
285
|
expect(result._meta?.viewUUID).toBeDefined();
|
|
296
286
|
expect(typeof result._meta?.viewUUID).toBe("string");
|
|
297
|
-
// UUID v4 format
|
|
298
287
|
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}$/);
|
|
299
288
|
});
|
|
300
289
|
it("should preserve existing _meta when injecting viewUUID", async () => {
|
|
@@ -303,7 +292,11 @@ describe("McpServer.registerWidget", () => {
|
|
|
303
292
|
structuredContent: { data: "test" },
|
|
304
293
|
_meta: { requestId: "req-123", cached: true },
|
|
305
294
|
});
|
|
306
|
-
server.
|
|
295
|
+
server.registerTool({
|
|
296
|
+
name: "my-widget",
|
|
297
|
+
description: "Test tool",
|
|
298
|
+
view: { component: "my-widget", description: "Test view" },
|
|
299
|
+
}, mockToolCallback);
|
|
307
300
|
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
308
301
|
const result = await wrappedCallback({}, {});
|
|
309
302
|
expect(result._meta?.requestId).toBe("req-123");
|
|
@@ -315,20 +308,147 @@ describe("McpServer.registerWidget", () => {
|
|
|
315
308
|
content: [{ type: "text", text: "result" }],
|
|
316
309
|
structuredContent: {},
|
|
317
310
|
});
|
|
318
|
-
server.
|
|
311
|
+
server.registerTool({
|
|
312
|
+
name: "my-widget",
|
|
313
|
+
description: "Test tool",
|
|
314
|
+
view: { component: "my-widget", description: "Test view" },
|
|
315
|
+
}, mockToolCallback);
|
|
319
316
|
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
320
317
|
const result1 = await wrappedCallback({}, {});
|
|
321
318
|
const result2 = await wrappedCallback({}, {});
|
|
322
319
|
expect(result1._meta?.viewUUID).not.toBe(result2._meta?.viewUUID);
|
|
323
320
|
});
|
|
324
|
-
it("should
|
|
325
|
-
|
|
326
|
-
|
|
321
|
+
it("should enforce one-tool-per-view constraint", () => {
|
|
322
|
+
server.registerTool({
|
|
323
|
+
name: "shake",
|
|
324
|
+
description: "First tool",
|
|
325
|
+
view: { component: "magic-8-ball" },
|
|
326
|
+
}, vi.fn());
|
|
327
|
+
expect(() => {
|
|
328
|
+
server.registerTool({
|
|
329
|
+
name: "shake-v2",
|
|
330
|
+
description: "Second tool",
|
|
331
|
+
view: { component: "magic-8-ball" },
|
|
332
|
+
}, vi.fn());
|
|
333
|
+
}).toThrow('skybridge: view "magic-8-ball" is already used by tool "shake"');
|
|
334
|
+
});
|
|
335
|
+
it("should normalize string content to ContentBlock array", async () => {
|
|
336
|
+
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
337
|
+
content: "Hello world",
|
|
338
|
+
structuredContent: {},
|
|
339
|
+
});
|
|
340
|
+
server.registerTool({
|
|
341
|
+
name: "string-content",
|
|
342
|
+
description: "Test tool",
|
|
343
|
+
view: { component: "string-content" },
|
|
344
|
+
}, mockToolCallback);
|
|
345
|
+
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
346
|
+
const result = await wrappedCallback({}, {});
|
|
347
|
+
expect(result.content).toEqual([{ type: "text", text: "Hello world" }]);
|
|
348
|
+
});
|
|
349
|
+
it("should normalize single ContentBlock to array", async () => {
|
|
350
|
+
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
351
|
+
content: { type: "text", text: "Single block" },
|
|
352
|
+
structuredContent: {},
|
|
353
|
+
});
|
|
354
|
+
server.registerTool({
|
|
355
|
+
name: "single-block",
|
|
356
|
+
description: "Test tool",
|
|
357
|
+
view: { component: "single-block" },
|
|
358
|
+
}, mockToolCallback);
|
|
359
|
+
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
360
|
+
const result = await wrappedCallback({}, {});
|
|
361
|
+
expect(result.content).toEqual([{ type: "text", text: "Single block" }]);
|
|
362
|
+
});
|
|
363
|
+
it("should pass through ContentBlock array unchanged", async () => {
|
|
364
|
+
const blocks = [
|
|
365
|
+
{ type: "text", text: "A" },
|
|
366
|
+
{ type: "text", text: "B" },
|
|
367
|
+
];
|
|
368
|
+
const mockToolCallback = vi.fn().mockResolvedValue({
|
|
369
|
+
content: blocks,
|
|
370
|
+
structuredContent: {},
|
|
371
|
+
});
|
|
372
|
+
server.registerTool({
|
|
373
|
+
name: "array-content",
|
|
374
|
+
description: "Test tool",
|
|
375
|
+
view: { component: "array-content" },
|
|
376
|
+
}, mockToolCallback);
|
|
377
|
+
const wrappedCallback = mockRegisterTool.mock.calls[0]?.[2];
|
|
378
|
+
const result = await wrappedCallback({}, {});
|
|
379
|
+
expect(result.content).toEqual(blocks);
|
|
380
|
+
});
|
|
381
|
+
it("should register tool without view (no resource registration)", () => {
|
|
382
|
+
server.registerTool({
|
|
383
|
+
name: "plain-tool",
|
|
384
|
+
description: "No view",
|
|
385
|
+
}, vi.fn());
|
|
386
|
+
expect(mockRegisterResource).not.toHaveBeenCalled();
|
|
327
387
|
expect(mockRegisterTool).toHaveBeenCalledTimes(1);
|
|
388
|
+
});
|
|
389
|
+
it("should apply view.csp fields to resource _meta", async () => {
|
|
390
|
+
server.registerTool({
|
|
391
|
+
name: "csp-tool",
|
|
392
|
+
description: "Test tool",
|
|
393
|
+
view: {
|
|
394
|
+
component: "csp-tool",
|
|
395
|
+
description: "Test view",
|
|
396
|
+
csp: {
|
|
397
|
+
connectDomains: ["https://api.example.com"],
|
|
398
|
+
resourceDomains: ["https://cdn.example.com"],
|
|
399
|
+
},
|
|
400
|
+
},
|
|
401
|
+
}, vi.fn());
|
|
402
|
+
const appsSdkCallback = mockRegisterResource.mock
|
|
403
|
+
.calls[0]?.[3];
|
|
404
|
+
const host = "localhost:3000";
|
|
405
|
+
const serverUrl = `http://${host}`;
|
|
406
|
+
const hmrUrl = `ws://${host}`;
|
|
407
|
+
const result = await appsSdkCallback(new URL("ui://widgets/apps-sdk/csp-tool.html"), createMockExtra(host));
|
|
408
|
+
const meta = result.contents[0]?._meta;
|
|
409
|
+
expect(meta["openai/widgetCSP"]).toEqual({
|
|
410
|
+
resource_domains: [serverUrl, "https://cdn.example.com"],
|
|
411
|
+
connect_domains: [serverUrl, hmrUrl, "https://api.example.com"],
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
it("should let view._meta override framework-computed keys", async () => {
|
|
415
|
+
server.registerTool({
|
|
416
|
+
name: "override-tool",
|
|
417
|
+
description: "Test tool",
|
|
418
|
+
view: {
|
|
419
|
+
component: "override-tool",
|
|
420
|
+
description: "Test view",
|
|
421
|
+
csp: { connectDomains: ["https://api.x.com"] },
|
|
422
|
+
_meta: {
|
|
423
|
+
"openai/widgetCSP": {
|
|
424
|
+
connect_domains: ["https://api.y.com"],
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
}, vi.fn());
|
|
429
|
+
const appsSdkCallback = mockRegisterResource.mock
|
|
430
|
+
.calls[0]?.[3];
|
|
431
|
+
const result = await appsSdkCallback(new URL("ui://widgets/apps-sdk/override-tool.html"), createMockExtra("localhost:3000"));
|
|
432
|
+
const meta = result.contents[0]?._meta;
|
|
433
|
+
expect(meta["openai/widgetCSP"]).toEqual({
|
|
434
|
+
connect_domains: ["https://api.y.com"],
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
it("should pass user _meta keys through to tool config", () => {
|
|
438
|
+
server.registerTool({
|
|
439
|
+
name: "meta-tool",
|
|
440
|
+
description: "Test tool",
|
|
441
|
+
_meta: {
|
|
442
|
+
"openai/widgetAccessible": true,
|
|
443
|
+
"openai/toolInvocation/invoking": "Loading...",
|
|
444
|
+
"acme.com/category": "utility",
|
|
445
|
+
},
|
|
446
|
+
}, vi.fn());
|
|
328
447
|
const toolCallArgs = mockRegisterTool.mock.calls[0];
|
|
329
448
|
const toolConfig = toolCallArgs?.[1];
|
|
330
|
-
expect(toolConfig._meta).
|
|
331
|
-
expect(toolConfig._meta?.["openai/
|
|
449
|
+
expect(toolConfig._meta?.["openai/widgetAccessible"]).toBe(true);
|
|
450
|
+
expect(toolConfig._meta?.["openai/toolInvocation/invoking"]).toBe("Loading...");
|
|
451
|
+
expect(toolConfig._meta?.["acme.com/category"]).toBe("utility");
|
|
332
452
|
});
|
|
333
453
|
});
|
|
334
|
-
//# sourceMappingURL=
|
|
454
|
+
//# sourceMappingURL=view.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view.test.js","sourceRoot":"","sources":["../../src/test/view.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAMjC,OAAO,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,MAAM,EACN,EAAE,EAEF,EAAE,GACH,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,MAAM,YAAY,GAAG;IACnB,0BAA0B,EAAE;QAC1B,IAAI,EAAE,4BAA4B;QAClC,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,IAAI;KACd;IACD,8BAA8B,EAAE;QAC9B,IAAI,EAAE,gCAAgC;QACtC,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,IAAI;KACd;IACD,WAAW,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;CACnC,CAAC;AAEF,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;AAEpD,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;IACtB,MAAM,gBAAgB,GAAG,CACvB,IAA+C,EAC/C,GAAG,IAAe,EACsB,EAAE;QAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YAC/D,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAEjC,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC,CAAC;IACF,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAA+B,CAAC;IAE3E,OAAO;QACL,YAAY;QACZ,OAAO,EAAE;YACP,YAAY;SACb;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,IAAI,MAAiB,CAAC;IACtB,IAAI,oBAAiE,CAAC;IACtE,IAAI,gBAA8B,CAAC;IAEnC,UAAU,CAAC,GAAG,EAAE;QACd,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,gBAAgB,EAAE;YACjD,mBAAmB,EAAE,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,YAAY,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,UAAU,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC;QAExC,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE;gBACJ,SAAS,EAAE,WAAW;gBACtB,WAAW,EAAE,WAAW;aACzB;SACF,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAI;aACtD,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAKb,CAAC;QACH,MAAM,CAAC,uBAAuB,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,MAAM,IAAI,GAAG,gBAAgB,CAAC;QAC9B,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,QAAQ,IAAI,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAGrC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,IAAI,GAAG,CAAC,sCAAsC,CAAC,EAC/C,SAAS,CACV,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,sCAAsC;oBAC3C,QAAQ,EAAE,qBAAqB;oBAC/B,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC;oBACtD,KAAK,EAAE;wBACL,kBAAkB,EAAE;4BAClB,gBAAgB,EAAE,CAAC,SAAS,CAAC;4BAC7B,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;yBACrC;wBACD,qBAAqB,EAAE,SAAS;wBAChC,0BAA0B,EAAE,WAAW;qBACxC;iBACF;aACF;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CACxC,GAAG,SAAS,wBAAwB,CACrC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,SAAS,eAAe,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CACxC,GAAG,SAAS,4BAA4B,CACzC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;QAEvC,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE;gBACJ,SAAS,EAAE,WAAW;gBACtB,WAAW,EAAE,WAAW;aACzB;SACF,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAI;aACtD,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAKb,CAAC;QACH,MAAM,CAAC,uBAAuB,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,MAAM,IAAI,GAAG,WAAW,CAAC;QACzB,MAAM,SAAS,GAAG,WAAW,IAAI,EAAE,CAAC;QACpC,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAGrC,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,IAAI,GAAG,CAAC,sCAAsC,CAAC,EAC/C,SAAS,CACV,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,sCAAsC;oBAC3C,QAAQ,EAAE,qBAAqB;oBAC/B,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC;oBACtD,KAAK,EAAE;wBACL,kBAAkB,EAAE;4BAClB,gBAAgB,EAAE,CAAC,SAAS,CAAC;4BAC7B,eAAe,EAAE,CAAC,SAAS,CAAC;yBAC7B;wBACD,qBAAqB,EAAE,SAAS;wBAChC,0BAA0B,EAAE,WAAW;qBACxC;iBACF;aACF;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAC5C,GAAG,SAAS,wBAAwB,CACrC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,SAAS,cAAc,CAAC,CAAC;QAC3E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CACxC,GAAG,SAAS,oCAAoC,CACjD,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,GAAG,SAAS,mBAAmB,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;QACpF,UAAU,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;QAEvC,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;SAC3D,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAI;aACtD,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAUb,CAAC;QACH,MAAM,CAAC,uBAAuB,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,MAAM,YAAY,GAChB,4DAA4D,CAAC;QAC/D,MAAM,cAAc,GAAG,GAAG,MAAM;aAC7B,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,YAAY,CAAC;aACpB,MAAM,CAAC,KAAK,CAAC;aACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC;QAEvC,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAC1C,IAAI,GAAG,CAAC,sCAAsC,CAAC,EAC/C,eAAe,CAAC,gBAAgB,EAAE;YAChC,OAAO,EAAE;gBACP,YAAY,EAAE,aAAa;gBAC3B,uBAAuB,EAAE,YAAY;aACtC;YACD,GAAG,EAAE,2BAA2B;SACjC,CAAsE,CACxE,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC;YACxC,EAAE,EAAE;gBACF,GAAG,EAAE;oBACH,eAAe,EAAE,CAAC,uBAAuB,CAAC;oBAC1C,cAAc,EAAE,CAAC,uBAAuB,CAAC;oBACzC,cAAc,EAAE,CAAC,uBAAuB,CAAC;iBAC1C;gBACD,WAAW,EAAE,WAAW;gBACxB,MAAM,EAAE,cAAc;aACvB;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE;gBACJ,SAAS,EAAE,WAAW;gBACtB,WAAW,EAAE,WAAW;gBACxB,aAAa,EAAE,IAAI;aACpB;SACF,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,CAAC,oBAAoB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAEtD,MAAM,eAAe,GAAG,oBAAoB,CAAC,IAAI;aAC9C,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAKb,CAAC;QACH,MAAM,IAAI,GAAG,gBAAgB,CAAC;QAC9B,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,QAAQ,IAAI,EAAE,CAAC;QAE9B,MAAM,aAAa,GAAG,MAAM,eAAe,CACzC,IAAI,GAAG,CAAC,sCAAsC,CAAC,EAC/C,eAAe,CAAC,IAAI,CAGnB,CACF,CAAC;QAEF,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC;YAC5B,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,sCAAsC;oBAC3C,QAAQ,EAAE,qBAAqB;oBAC/B,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC;oBACtD,KAAK,EAAE;wBACL,kBAAkB,EAAE;4BAClB,gBAAgB,EAAE,CAAC,SAAS,CAAC;4BAC7B,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;yBACrC;wBACD,qBAAqB,EAAE,SAAS;wBAChC,0BAA0B,EAAE,WAAW;wBACvC,4BAA4B,EAAE,IAAI;qBACnC;iBACF;aACF;SACF,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAC/C,kFAAkF,CACnF,CAAC;QAEF,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAI;aACtD,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAUb,CAAC;QACH,MAAM,CAAC,uBAAuB,CAAC,CAAC,WAAW,EAAE,CAAC;QAE9C,MAAM,aAAa,GAAG,MAAM,uBAAuB,CACjD,IAAI,GAAG,CAAC,sCAAsC,CAAC,EAC/C,eAAe,CAAC,IAAI,CAGnB,CACF,CAAC;QAEF,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC;YAC5B,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,sCAAsC;oBAC3C,QAAQ,EAAE,2BAA2B;oBACrC,IAAI,EAAE,MAAM,CAAC,gBAAgB,CAAC,uBAAuB,CAAC;oBACtD,KAAK,EAAE;wBACL,EAAE,EAAE;4BACF,GAAG,EAAE;gCACH,eAAe,EAAE,CAAC,SAAS,CAAC;gCAC5B,cAAc,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC;gCACnC,cAAc,EAAE,CAAC,SAAS,CAAC;6BAC5B;4BACD,MAAM,EAAE,SAAS;4BACjB,WAAW,EAAE,WAAW;4BACxB,aAAa,EAAE,IAAI;yBACpB;qBACF;iBACF;aACF;SACF,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAC/C,iFAAiF,CAClF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;SAC3D,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAElD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC,CAAC,CAAwC,CAAC;QAE5E,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC;YACnC,WAAW,EAAE,sCAAsC;SACpD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE;gBACJ,SAAS,EAAE,WAAW;gBACtB,WAAW,EAAE,WAAW;gBACxB,KAAK,EAAE,CAAC,UAAU,CAAC;aACpB;SACF,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAElD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC,CAAC,CAAwC,CAAC;QAE5E,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CACtD,sCAAsC,CACvC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE;gBACJ,SAAS,EAAE,WAAW;gBACtB,WAAW,EAAE,WAAW;gBACxB,KAAK,EAAE,CAAC,SAAS,CAAC;aACnB;SACF,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAElD,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC,CAAC,CAAwC,CAAC;QAE5E,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC;YACnC,WAAW,EAAE,sCAAsC;SACpD,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YACjD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC3C,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;SACpC,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;SAC3D,EACD,gBAAgB,CACjB,CAAC;QAEF,MAAM,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAET,CAAC;QAClD,MAAM,CAAC,eAAe,CAAC,CAAC,WAAW,EAAE,CAAC;QAEtC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAE7C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7C,MAAM,CAAC,OAAO,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,OAAO,CACpC,gEAAgE,CACjE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YACjD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC3C,iBAAiB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACnC,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE;SAC9C,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;SAC3D,EACD,gBAAgB,CACjB,CAAC;QAEF,MAAM,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAET,CAAC;QAClD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAE7C,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YACjD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;YAC3C,iBAAiB,EAAE,EAAE;SACtB,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;SAC3D,EACD,gBAAgB,CACjB,CAAC;QAEF,MAAM,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAET,CAAC;QAClD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAE9C,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,YAAY;YACzB,IAAI,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE;SACpC,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,CAAC,YAAY,CACjB;gBACE,IAAI,EAAE,UAAU;gBAChB,WAAW,EAAE,aAAa;gBAC1B,IAAI,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE;aACpC,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QACJ,CAAC,CAAC,CAAC,OAAO,CACR,gEAAgE,CACjE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YACjD,OAAO,EAAE,aAAa;YACtB,iBAAiB,EAAE,EAAE;SACtB,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE;SACtC,EACD,gBAAgB,CACjB,CAAC;QAEF,MAAM,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAEtB,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAE7C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YACjD,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE;YAC/C,iBAAiB,EAAE,EAAE;SACtB,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE;SACpC,EACD,gBAAgB,CACjB,CAAC;QAEF,MAAM,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAEtB,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAE7C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,MAAM,GAAG;YACb,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE;YAC3B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE;SAC5B,CAAC;QACF,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;YACjD,OAAO,EAAE,MAAM;YACf,iBAAiB,EAAE,EAAE;SACtB,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,eAAe;YACrB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE,EAAE,SAAS,EAAE,eAAe,EAAE;SACrC,EACD,gBAAgB,CACjB,CAAC;QAEF,MAAM,eAAe,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAEtB,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAE7C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,SAAS;SACvB,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACpD,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE;gBACJ,SAAS,EAAE,UAAU;gBACrB,WAAW,EAAE,WAAW;gBACxB,GAAG,EAAE;oBACH,cAAc,EAAE,CAAC,yBAAyB,CAAC;oBAC3C,eAAe,EAAE,CAAC,yBAAyB,CAAC;iBAC7C;aACF;SACF,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,eAAe,GAAG,oBAAoB,CAAC,IAAI;aAC9C,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CASb,CAAC;QAEH,MAAM,IAAI,GAAG,gBAAgB,CAAC;QAC9B,MAAM,SAAS,GAAG,UAAU,IAAI,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,QAAQ,IAAI,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC,IAAI,GAAG,CAAC,qCAAqC,CAAC,EAC9C,eAAe,CAAC,IAAI,CAGnB,CACF,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAgC,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC;YACvC,gBAAgB,EAAE,CAAC,SAAS,EAAE,yBAAyB,CAAC;YACxD,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,yBAAyB,CAAC;SAChE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,eAAe;YACrB,WAAW,EAAE,WAAW;YACxB,IAAI,EAAE;gBACJ,SAAS,EAAE,eAAe;gBAC1B,WAAW,EAAE,WAAW;gBACxB,GAAG,EAAE,EAAE,cAAc,EAAE,CAAC,mBAAmB,CAAC,EAAE;gBAC9C,KAAK,EAAE;oBACL,kBAAkB,EAAE;wBAClB,eAAe,EAAE,CAAC,mBAAmB,CAAC;qBACvC;iBACF;aACF;SACF,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,eAAe,GAAG,oBAAoB,CAAC,IAAI;aAC9C,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CASb,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC,IAAI,GAAG,CAAC,0CAA0C,CAAC,EACnD,eAAe,CAAC,gBAAgB,CAG/B,CACF,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAgC,CAAC;QAClE,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC;YACvC,eAAe,EAAE,CAAC,mBAAmB,CAAC;SACvC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,YAAY,CACjB;YACE,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,WAAW;YACxB,KAAK,EAAE;gBACL,yBAAyB,EAAE,IAAI;gBAC/B,gCAAgC,EAAE,YAAY;gBAC9C,mBAAmB,EAAE,SAAS;aAC/B;SACF,EACD,EAAE,CAAC,EAAE,EAAE,CACR,CAAC;QAEF,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC,CAAC,CAAwC,CAAC;QAE5E,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,gCAAgC,CAAC,CAAC,CAAC,IAAI,CAC/D,YAAY,CACb,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
2
|
import type { useSyncExternalStore } from "react";
|
|
3
|
-
import type {
|
|
3
|
+
import type { ViewHostType } from "../../server/index.js";
|
|
4
4
|
export type SkybridgeProperties = {
|
|
5
|
-
hostType:
|
|
5
|
+
hostType: ViewHostType;
|
|
6
6
|
serverUrl: string;
|
|
7
7
|
};
|
|
8
8
|
declare global {
|
|
@@ -15,7 +15,7 @@ type TypedToolInfoReturn<TInput, TOutput, TResponseMetadata> = ToolState<Objecti
|
|
|
15
15
|
* Creates typed versions of skybridge hooks with full type inference
|
|
16
16
|
* for tool names, inputs, and outputs.
|
|
17
17
|
*
|
|
18
|
-
* This is the recommended way to use skybridge hooks in your
|
|
18
|
+
* This is the recommended way to use skybridge hooks in your views.
|
|
19
19
|
* Set this up once in a dedicated file and export the typed hooks for use across your app.
|
|
20
20
|
*
|
|
21
21
|
* @typeParam ServerType - The type of your McpServer instance (use `typeof server`).
|
|
@@ -24,11 +24,13 @@ type TypedToolInfoReturn<TInput, TOutput, TResponseMetadata> = ToolState<Objecti
|
|
|
24
24
|
*
|
|
25
25
|
* @example
|
|
26
26
|
* ```typescript
|
|
27
|
-
* //
|
|
27
|
+
* // src/server.ts
|
|
28
28
|
* const server = new McpServer({ name: "my-app", version: "1.0" }, {})
|
|
29
|
-
* .
|
|
29
|
+
* .registerTool({
|
|
30
|
+
* name: "search-trip",
|
|
30
31
|
* inputSchema: { destination: z.string() },
|
|
31
32
|
* outputSchema: { results: z.array(z.string()) },
|
|
33
|
+
* view: { component: "search-trip", description: "Search trips" },
|
|
32
34
|
* }, async ({ destination }) => {
|
|
33
35
|
* return { content: [{ type: "text", text: `Found trips to ${destination}` }] };
|
|
34
36
|
* });
|
|
@@ -38,8 +40,8 @@ type TypedToolInfoReturn<TInput, TOutput, TResponseMetadata> = ToolState<Objecti
|
|
|
38
40
|
*
|
|
39
41
|
* @example
|
|
40
42
|
* ```typescript
|
|
41
|
-
* //
|
|
42
|
-
* import type { AppType } from "
|
|
43
|
+
* // src/helpers.ts (one-time setup)
|
|
44
|
+
* import type { AppType } from "./server";
|
|
43
45
|
* import { generateHelpers } from "skybridge/web";
|
|
44
46
|
*
|
|
45
47
|
* export const { useCallTool, useToolInfo } = generateHelpers<AppType>();
|
|
@@ -47,19 +49,19 @@ type TypedToolInfoReturn<TInput, TOutput, TResponseMetadata> = ToolState<Objecti
|
|
|
47
49
|
*
|
|
48
50
|
* @example
|
|
49
51
|
* ```typescript
|
|
50
|
-
* //
|
|
51
|
-
* import { useCallTool, useToolInfo } from "../
|
|
52
|
+
* // src/views/search.tsx (usage)
|
|
53
|
+
* import { useCallTool, useToolInfo } from "../helpers";
|
|
52
54
|
*
|
|
53
|
-
* export function
|
|
54
|
-
* const { callTool, data } = useCallTool("search-
|
|
55
|
+
* export function SearchView() {
|
|
56
|
+
* const { callTool, data } = useCallTool("search-trip");
|
|
55
57
|
* // ^ autocomplete for tool names
|
|
56
58
|
* callTool({ destination: "Spain" });
|
|
57
59
|
* // ^ autocomplete for input fields
|
|
58
60
|
*
|
|
59
|
-
* const toolInfo = useToolInfo<"search-
|
|
60
|
-
* // ^ autocomplete for
|
|
61
|
-
* // toolInfo.input is typed based on
|
|
62
|
-
* // toolInfo.output.structuredContent is typed based on
|
|
61
|
+
* const toolInfo = useToolInfo<"search-trip">();
|
|
62
|
+
* // ^ autocomplete for view names
|
|
63
|
+
* // toolInfo.input is typed based on view input schema
|
|
64
|
+
* // toolInfo.output.structuredContent is typed based on view output schema
|
|
63
65
|
* }
|
|
64
66
|
* ```
|
|
65
67
|
*/
|
|
@@ -68,12 +70,12 @@ export declare function generateHelpers<ServerType = never>(): {
|
|
|
68
70
|
* Typed version of `useCallTool` that provides autocomplete for tool names
|
|
69
71
|
* and type inference for inputs and outputs.
|
|
70
72
|
*
|
|
71
|
-
* @param name - The name of the
|
|
73
|
+
* @param name - The name of the tool to call. Autocompletes based on your server's tool registry.
|
|
72
74
|
* @returns A hook with typed `callTool` function and `data` property.
|
|
73
75
|
*
|
|
74
76
|
* @example
|
|
75
77
|
* ```typescript
|
|
76
|
-
* const { callTool, data, isPending } = useCallTool("search-
|
|
78
|
+
* const { callTool, data, isPending } = useCallTool("search-trip");
|
|
77
79
|
* // TypeScript knows callTool expects { destination: string }
|
|
78
80
|
* callTool({ destination: "Spain" });
|
|
79
81
|
*
|
|
@@ -85,15 +87,15 @@ export declare function generateHelpers<ServerType = never>(): {
|
|
|
85
87
|
*/
|
|
86
88
|
useCallTool: <ToolName extends keyof InferTools<ServerType> & string>(name: ToolName) => TypedCallToolReturn<ToolInput<ServerType, ToolName>, ToolOutput<ServerType, ToolName>>;
|
|
87
89
|
/**
|
|
88
|
-
* Typed version of `useToolInfo` that provides autocomplete for
|
|
90
|
+
* Typed version of `useToolInfo` that provides autocomplete for tool names
|
|
89
91
|
* and type inference for inputs, outputs, and responseMetadata.
|
|
90
92
|
*
|
|
91
|
-
* @typeParam K - The name of the
|
|
93
|
+
* @typeParam K - The name of the tool. Autocompletes based on your server's tool registry.
|
|
92
94
|
* @returns A discriminated union with `status: "pending" | "success"` that narrows correctly.
|
|
93
95
|
*
|
|
94
96
|
* @example
|
|
95
97
|
* ```typescript
|
|
96
|
-
* const toolInfo = useToolInfo<"search-
|
|
98
|
+
* const toolInfo = useToolInfo<"search-trip">();
|
|
97
99
|
* // toolInfo.input is typed as { destination: string; ... }
|
|
98
100
|
* // toolInfo.output is typed as { results: Array<...>; ... }
|
|
99
101
|
* // toolInfo.responseMetadata is typed based on _meta in callback return
|