@drawcall/design 0.5.11 → 0.6.0
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 +3 -7
- package/dist/auth.d.ts +3 -0
- package/dist/auth.js +29 -0
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/cli.js +2 -2
- package/dist/command.d.ts +0 -1
- package/dist/command.js +1 -35
- package/dist/mcp/file.d.ts +3 -2
- package/dist/mcp/file.js +9 -6
- package/dist/mcp/frame.d.ts +3 -2
- package/dist/mcp/frame.js +24 -11
- package/dist/mcp/index.d.ts +1 -2
- package/dist/mcp/index.js +0 -1
- package/dist/mcp/project.d.ts +3 -2
- package/dist/mcp/project.js +4 -8
- package/dist/mcp/register.d.ts +3 -2
- package/dist/mcp/register.js +4 -7
- package/dist/mcp/types.d.ts +2 -24
- package/dist/options.d.ts +2 -0
- package/dist/options.js +4 -0
- package/dist/project-state.d.ts +6 -6
- package/dist/standalone.d.ts +3 -0
- package/dist/standalone.js +7 -0
- package/dist/v1/contract.d.ts +13 -13
- package/dist/v1/schemas.d.ts +8 -8
- package/package.json +2 -2
- package/dist/mcp/client.d.ts +0 -3
- package/dist/mcp/client.js +0 -38
package/README.md
CHANGED
|
@@ -40,23 +40,19 @@ The Commander implementation is available for aggregate CLIs:
|
|
|
40
40
|
```ts
|
|
41
41
|
import { createDesignCommand } from "@drawcall/design";
|
|
42
42
|
|
|
43
|
-
program.addCommand(createDesignCommand(
|
|
43
|
+
program.addCommand(createDesignCommand());
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
The MCP tools can be mounted into a server owned by another package:
|
|
47
47
|
|
|
48
48
|
```ts
|
|
49
|
-
import {
|
|
50
|
-
createDesignMcpOperations,
|
|
51
|
-
registerDesignTools,
|
|
52
|
-
v1,
|
|
53
|
-
} from "@drawcall/design";
|
|
49
|
+
import { registerDesignTools, v1 } from "@drawcall/design";
|
|
54
50
|
import { McpServer } from "@modelcontextprotocol/server";
|
|
55
51
|
|
|
56
52
|
const client = v1.createClient({ authToken: process.env.DRAWCALL_AUTH_TOKEN });
|
|
57
53
|
const server = new McpServer({ name: "mcp.drawcall.ai", version: "1.0.0" });
|
|
58
54
|
|
|
59
|
-
registerDesignTools(server,
|
|
55
|
+
registerDesignTools(server, client);
|
|
60
56
|
```
|
|
61
57
|
|
|
62
58
|
The host owns the server identity, authentication, and transport. The MCP SDK
|
package/dist/auth.d.ts
ADDED
package/dist/auth.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getConfigPath as getAuthConfigPath, runDeviceLogin, saveAuthToken, signOut, } from "@drawcall/auth";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { clearConfig, saveConfig } from "./config.js";
|
|
4
|
+
import { apiOption } from "./options.js";
|
|
5
|
+
import { createClient, DEFAULT_BASE_URL } from "./v1/client.js";
|
|
6
|
+
export function createLoginCommand() {
|
|
7
|
+
return new Command("login")
|
|
8
|
+
.description("Sign in with your Drawcall account")
|
|
9
|
+
.action(async (_options, command) => {
|
|
10
|
+
const baseUrlOverride = apiOption(command);
|
|
11
|
+
const baseUrl = baseUrlOverride ?? DEFAULT_BASE_URL;
|
|
12
|
+
const token = await runDeviceLogin();
|
|
13
|
+
const client = createClient({ baseUrl, authToken: token });
|
|
14
|
+
const user = await client.user.me();
|
|
15
|
+
if (baseUrlOverride)
|
|
16
|
+
await saveConfig({ baseUrl });
|
|
17
|
+
else
|
|
18
|
+
await clearConfig();
|
|
19
|
+
await saveAuthToken(token);
|
|
20
|
+
console.log(`Signed in as ${user.email}. Credentials saved to ${getAuthConfigPath()}.`);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export function createLogoutCommand() {
|
|
24
|
+
return new Command("logout").description("Sign out").action(async () => {
|
|
25
|
+
const authExisted = await signOut();
|
|
26
|
+
const configExisted = await clearConfig();
|
|
27
|
+
console.log(authExisted || configExisted ? "Signed out." : "Already signed out.");
|
|
28
|
+
});
|
|
29
|
+
}
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * as v1 from "./v1/index.js";
|
|
2
|
-
export {
|
|
2
|
+
export { registerDesignTools, type DesignMcpOptions, type DesignMcpServer, type DesignMcpToolResult, } from "./mcp/index.js";
|
|
3
3
|
export { cliDesignSkill, mcpDesignSkill } from "./skill.generated.js";
|
|
4
4
|
export { frameCreationCapabilities, type FrameCreationCapability, type FrameCreationCapabilityId, type FrameCreationInput, } from "./v1/capabilities.js";
|
|
5
5
|
export { cameraPoseSchema, IMAGE_GENERATION_MODEL, IMAGE_GENERATION_PROVIDER, } from "./v1/schemas.js";
|
package/dist/browser.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * as v1 from "./v1/index.js";
|
|
2
|
-
export {
|
|
2
|
+
export { registerDesignTools, } from "./mcp/index.js";
|
|
3
3
|
export { cliDesignSkill, mcpDesignSkill } from "./skill.generated.js";
|
|
4
4
|
export { frameCreationCapabilities, } from "./v1/capabilities.js";
|
|
5
5
|
export { cameraPoseSchema, IMAGE_GENERATION_MODEL, IMAGE_GENERATION_PROVIDER, } from "./v1/schemas.js";
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
const program =
|
|
2
|
+
import { createDesignCli } from "./standalone.js";
|
|
3
|
+
const program = createDesignCli();
|
|
4
4
|
if (process.argv.length <= 2) {
|
|
5
5
|
program.outputHelp();
|
|
6
6
|
}
|
package/dist/command.d.ts
CHANGED
package/dist/command.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { getConfigPath as getAuthConfigPath, runDeviceLogin, saveAuthToken, signOut, } from "@drawcall/auth";
|
|
3
2
|
import { Command, Option } from "commander";
|
|
4
|
-
import { clearConfig, saveConfig } from "./config.js";
|
|
5
3
|
import { getCliClient } from "./cli-client.js";
|
|
6
4
|
import { readImageInput } from "./image.js";
|
|
5
|
+
import { apiOption } from "./options.js";
|
|
7
6
|
import { cliDesignSkill } from "./skill.generated.js";
|
|
8
7
|
import { parseFrameSize } from "./target.js";
|
|
9
|
-
import { createClient, DEFAULT_BASE_URL } from "./v1/client.js";
|
|
10
8
|
import { designIdSchema, marketAssetSchema } from "./v1/schemas.js";
|
|
11
9
|
export function createDesignCommand(options = {}) {
|
|
12
10
|
const program = new Command()
|
|
@@ -21,8 +19,6 @@ export function createDesignCommand(options = {}) {
|
|
|
21
19
|
.action(() => {
|
|
22
20
|
process.stdout.write(cliDesignSkill);
|
|
23
21
|
});
|
|
24
|
-
if (options.includeAuthCommands ?? true)
|
|
25
|
-
addAuthCommands(program);
|
|
26
22
|
const project = program.command("project").description("Manage projects");
|
|
27
23
|
project
|
|
28
24
|
.command("list")
|
|
@@ -204,32 +200,6 @@ export function createDesignCommand(options = {}) {
|
|
|
204
200
|
});
|
|
205
201
|
return program;
|
|
206
202
|
}
|
|
207
|
-
function addAuthCommands(program) {
|
|
208
|
-
program
|
|
209
|
-
.command("login")
|
|
210
|
-
.description("Sign in with your Drawcall account")
|
|
211
|
-
.action(async (_options, command) => {
|
|
212
|
-
const baseUrlOverride = apiOption(command);
|
|
213
|
-
const baseUrl = baseUrlOverride ?? DEFAULT_BASE_URL;
|
|
214
|
-
const token = await runDeviceLogin();
|
|
215
|
-
const client = createClient({ baseUrl, authToken: token });
|
|
216
|
-
const user = await client.user.me();
|
|
217
|
-
if (baseUrlOverride)
|
|
218
|
-
await saveConfig({ baseUrl });
|
|
219
|
-
else
|
|
220
|
-
await clearConfig();
|
|
221
|
-
await saveAuthToken(token);
|
|
222
|
-
console.log(`Signed in as ${user.email}. Credentials saved to ${getAuthConfigPath()}.`);
|
|
223
|
-
});
|
|
224
|
-
program
|
|
225
|
-
.command("logout")
|
|
226
|
-
.description("Sign out")
|
|
227
|
-
.action(async () => {
|
|
228
|
-
const authExisted = await signOut();
|
|
229
|
-
const configExisted = await clearConfig();
|
|
230
|
-
console.log(authExisted || configExisted ? "Signed out." : "Already signed out.");
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
203
|
async function createFrameInput(project, name, options) {
|
|
234
204
|
if (options.type === "glts") {
|
|
235
205
|
if (options.image !== undefined || options.asset !== undefined) {
|
|
@@ -276,10 +246,6 @@ async function createFrameInput(project, name, options) {
|
|
|
276
246
|
async function clientFor(command) {
|
|
277
247
|
return getCliClient(apiOption(command));
|
|
278
248
|
}
|
|
279
|
-
function apiOption(command) {
|
|
280
|
-
const value = command.optsWithGlobals().api;
|
|
281
|
-
return typeof value === "string" ? value : undefined;
|
|
282
|
-
}
|
|
283
249
|
function projectId(command) {
|
|
284
250
|
const value = command.optsWithGlobals().project;
|
|
285
251
|
if (typeof value !== "string") {
|
package/dist/mcp/file.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { DesignV1Client } from "../v1/client.js";
|
|
2
|
+
import type { DesignMcpServer } from "./types.js";
|
|
3
|
+
export declare function registerFileTools(server: DesignMcpServer, client: DesignV1Client): void;
|
package/dist/mcp/file.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fileTextSchema } from "../v1/schemas.js";
|
|
2
2
|
import { fileResult, result } from "./result.js";
|
|
3
3
|
import { directoryPathSchema, fileInput, projectInput } from "./schema.js";
|
|
4
|
-
export function registerFileTools(server,
|
|
4
|
+
export function registerFileTools(server, client) {
|
|
5
5
|
server.registerTool("list_files", {
|
|
6
6
|
description: "Return canonical project-absolute paths. Omit path to list the entire project; otherwise use /<frame-id> without a trailing slash. Pass returned file paths unchanged to file tools.",
|
|
7
7
|
inputSchema: projectInput.extend({
|
|
@@ -13,7 +13,10 @@ export function registerFileTools(server, design, run) {
|
|
|
13
13
|
openWorldHint: false,
|
|
14
14
|
idempotentHint: true,
|
|
15
15
|
},
|
|
16
|
-
}, async ({ project, path }) => result(await
|
|
16
|
+
}, async ({ project, path }) => result(await client.filesystem.list({
|
|
17
|
+
project,
|
|
18
|
+
...(path === undefined ? {} : { path }),
|
|
19
|
+
})));
|
|
17
20
|
server.registerTool("read_file", {
|
|
18
21
|
description: "Read one canonical project-absolute path returned by list_files. The path includes the frame ID; this tool does not accept a frame argument. Binary files return their hosted URL and media type.",
|
|
19
22
|
inputSchema: fileInput,
|
|
@@ -24,7 +27,7 @@ export function registerFileTools(server, design, run) {
|
|
|
24
27
|
idempotentHint: true,
|
|
25
28
|
},
|
|
26
29
|
}, async ({ project, path }) => {
|
|
27
|
-
const file = await
|
|
30
|
+
const file = await client.filesystem.read({ project, path });
|
|
28
31
|
return file.type === "text" ? fileResult(file) : result(file);
|
|
29
32
|
});
|
|
30
33
|
server.registerTool("write_file", {
|
|
@@ -35,7 +38,7 @@ export function registerFileTools(server, design, run) {
|
|
|
35
38
|
destructiveHint: true,
|
|
36
39
|
openWorldHint: true,
|
|
37
40
|
},
|
|
38
|
-
}, async ({ project, path, text }) => result(await
|
|
41
|
+
}, async ({ project, path, text }) => result(await client.filesystem.write({ project, path, text })));
|
|
39
42
|
server.registerTool("edit_file", {
|
|
40
43
|
description: "Replace oldText when it occurs exactly once at a canonical project-absolute .glts path. The path includes the frame ID; this tool does not accept a frame argument.",
|
|
41
44
|
inputSchema: fileInput.extend({
|
|
@@ -47,7 +50,7 @@ export function registerFileTools(server, design, run) {
|
|
|
47
50
|
destructiveHint: true,
|
|
48
51
|
openWorldHint: true,
|
|
49
52
|
},
|
|
50
|
-
}, async ({ project, path, oldText, newText }) => result(await
|
|
53
|
+
}, async ({ project, path, oldText, newText }) => result(await client.filesystem.edit({ project, path, oldText, newText })));
|
|
51
54
|
server.registerTool("delete_file", {
|
|
52
55
|
description: "Permanently delete one .glts file at a canonical project-absolute path. The path includes the frame ID; this tool does not accept a frame argument.",
|
|
53
56
|
inputSchema: fileInput,
|
|
@@ -56,5 +59,5 @@ export function registerFileTools(server, design, run) {
|
|
|
56
59
|
destructiveHint: true,
|
|
57
60
|
openWorldHint: true,
|
|
58
61
|
},
|
|
59
|
-
}, async ({ project, path }) => result(await
|
|
62
|
+
}, async ({ project, path }) => result(await client.filesystem.delete({ project, path })));
|
|
60
63
|
}
|
package/dist/mcp/frame.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { DesignV1Client } from "../v1/client.js";
|
|
2
|
+
import type { DesignMcpServer } from "./types.js";
|
|
3
|
+
export declare function registerFrameTools(server: DesignMcpServer, client: DesignV1Client, fetcher: typeof globalThis.fetch): void;
|
package/dist/mcp/frame.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { frameNameSchema, generateImageFrameSchema } from "../v1/schemas.js";
|
|
1
|
+
import { frameNameSchema, generateImageFrameSchema, } from "../v1/schemas.js";
|
|
2
2
|
import { base64, result } from "./result.js";
|
|
3
3
|
import { createFrameSchema, frameCreationInput, frameInput, projectInput, } from "./schema.js";
|
|
4
|
-
export function registerFrameTools(server,
|
|
4
|
+
export function registerFrameTools(server, client, fetcher) {
|
|
5
5
|
server.registerTool("list_frames", {
|
|
6
6
|
description: "List frames. Use their immutable ids for frame commands and filesystem paths.",
|
|
7
7
|
inputSchema: projectInput,
|
|
@@ -11,9 +11,7 @@ export function registerFrameTools(server, design, run) {
|
|
|
11
11
|
openWorldHint: false,
|
|
12
12
|
idempotentHint: true,
|
|
13
13
|
},
|
|
14
|
-
}, async ({ project }) => result({
|
|
15
|
-
frames: await run("list_frames", () => design.listFrames(project)),
|
|
16
|
-
}));
|
|
14
|
+
}, async ({ project }) => result({ frames: await client.frame.list({ project }) }));
|
|
17
15
|
server.registerTool("create_frame", {
|
|
18
16
|
description: "Create a frame in a Drawcall Design project. Use type=glts for reusable 3D objects and scenes, then write its source with write_file. Use type=image only for an existing public image URL and type=market only for an exact public Market asset.",
|
|
19
17
|
inputSchema: createFrameSchema,
|
|
@@ -24,7 +22,7 @@ export function registerFrameTools(server, design, run) {
|
|
|
24
22
|
idempotentHint: false,
|
|
25
23
|
},
|
|
26
24
|
}, async (input) => result({
|
|
27
|
-
frame: await
|
|
25
|
+
frame: await client.frame.create(frameCreationInput(input)),
|
|
28
26
|
}));
|
|
29
27
|
server.registerTool("generate_image", {
|
|
30
28
|
description: "Generate a 2D image or reference frame from text and up to four same-project image frame references. Use only when the user asks for a 2D image, picture, concept, or reference; do not use for 3D objects, scenes, or reusable GLTS assets. For edit, target is reference 0. New frames are the default; result=replace explicitly replaces the target image while preserving its frame ID, name, and layout.",
|
|
@@ -36,7 +34,7 @@ export function registerFrameTools(server, design, run) {
|
|
|
36
34
|
idempotentHint: false,
|
|
37
35
|
},
|
|
38
36
|
}, async (input) => result({
|
|
39
|
-
frame: await
|
|
37
|
+
frame: await client.frame.generateImage(input),
|
|
40
38
|
}));
|
|
41
39
|
server.registerTool("rename_frame", {
|
|
42
40
|
description: "Rename a frame. Its immutable frame id does not change.",
|
|
@@ -47,7 +45,7 @@ export function registerFrameTools(server, design, run) {
|
|
|
47
45
|
openWorldHint: false,
|
|
48
46
|
},
|
|
49
47
|
}, async ({ project, frame, name }) => result({
|
|
50
|
-
frame: await
|
|
48
|
+
frame: await client.frame.rename({ project, frame, name }),
|
|
51
49
|
}));
|
|
52
50
|
server.registerTool("delete_frame", {
|
|
53
51
|
description: "Permanently delete a frame.",
|
|
@@ -58,7 +56,7 @@ export function registerFrameTools(server, design, run) {
|
|
|
58
56
|
openWorldHint: true,
|
|
59
57
|
idempotentHint: false,
|
|
60
58
|
},
|
|
61
|
-
}, async ({ project, frame }) => result(await
|
|
59
|
+
}, async ({ project, frame }) => result(await client.frame.delete({ project, frame })));
|
|
62
60
|
server.registerTool("get_frame_screenshot", {
|
|
63
61
|
description: "Render a DPR-1 PNG screenshot of a frame.",
|
|
64
62
|
inputSchema: frameInput,
|
|
@@ -69,7 +67,8 @@ export function registerFrameTools(server, design, run) {
|
|
|
69
67
|
idempotentHint: true,
|
|
70
68
|
},
|
|
71
69
|
}, async ({ project, frame }) => {
|
|
72
|
-
const screenshot = await
|
|
70
|
+
const screenshot = await client.frame.screenshot({ project, frame });
|
|
71
|
+
const png = await screenshotBytes(screenshot, fetcher);
|
|
73
72
|
const structuredContent = {
|
|
74
73
|
url: screenshot.url,
|
|
75
74
|
width: screenshot.width,
|
|
@@ -80,7 +79,7 @@ export function registerFrameTools(server, design, run) {
|
|
|
80
79
|
content: [
|
|
81
80
|
{
|
|
82
81
|
type: "image",
|
|
83
|
-
data: base64(
|
|
82
|
+
data: base64(png),
|
|
84
83
|
mimeType: screenshot.mediaType,
|
|
85
84
|
},
|
|
86
85
|
],
|
|
@@ -88,3 +87,17 @@ export function registerFrameTools(server, design, run) {
|
|
|
88
87
|
};
|
|
89
88
|
});
|
|
90
89
|
}
|
|
90
|
+
async function screenshotBytes(screenshot, fetcher) {
|
|
91
|
+
const response = await fetcher(screenshot.url);
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
throw new Error(`Could not read screenshot ${screenshot.url}: ${response.status} ${response.statusText}`);
|
|
94
|
+
}
|
|
95
|
+
const mediaType = response.headers
|
|
96
|
+
.get("content-type")
|
|
97
|
+
?.split(";", 1)[0]
|
|
98
|
+
?.trim();
|
|
99
|
+
if (mediaType !== screenshot.mediaType) {
|
|
100
|
+
throw new Error(`Screenshot ${screenshot.url} returned ${mediaType ?? "no media type"}; expected ${screenshot.mediaType}`);
|
|
101
|
+
}
|
|
102
|
+
return new Uint8Array(await response.arrayBuffer());
|
|
103
|
+
}
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
export { createDesignMcpOperations } from "./client.js";
|
|
2
1
|
export { registerDesignTools } from "./register.js";
|
|
3
|
-
export type {
|
|
2
|
+
export type { DesignMcpOptions, DesignMcpServer, DesignMcpToolResult, } from "./types.js";
|
package/dist/mcp/index.js
CHANGED
package/dist/mcp/project.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { DesignV1Client } from "../v1/client.js";
|
|
2
|
+
import type { DesignMcpServer } from "./types.js";
|
|
3
|
+
export declare function registerProjectTools(server: DesignMcpServer, client: DesignV1Client): void;
|
package/dist/mcp/project.js
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { projectNameSchema } from "../v1/schemas.js";
|
|
3
3
|
import { result } from "./result.js";
|
|
4
4
|
import { projectInput } from "./schema.js";
|
|
5
|
-
export function registerProjectTools(server,
|
|
5
|
+
export function registerProjectTools(server, client) {
|
|
6
6
|
server.registerTool("list_projects", {
|
|
7
7
|
description: "List projects available to the current Drawcall account.",
|
|
8
8
|
annotations: {
|
|
@@ -11,9 +11,7 @@ export function registerProjectTools(server, design, run) {
|
|
|
11
11
|
openWorldHint: false,
|
|
12
12
|
idempotentHint: true,
|
|
13
13
|
},
|
|
14
|
-
}, async () => result({
|
|
15
|
-
projects: await run("list_projects", () => design.listProjects()),
|
|
16
|
-
}));
|
|
14
|
+
}, async () => result({ projects: await client.project.list() }));
|
|
17
15
|
server.registerTool("create_project", {
|
|
18
16
|
description: "Create a project. Use its returned immutable id in every later call.",
|
|
19
17
|
inputSchema: z.object({ name: projectNameSchema }).strict(),
|
|
@@ -23,9 +21,7 @@ export function registerProjectTools(server, design, run) {
|
|
|
23
21
|
openWorldHint: false,
|
|
24
22
|
idempotentHint: false,
|
|
25
23
|
},
|
|
26
|
-
}, async ({ name }) => result({
|
|
27
|
-
project: await run("create_project", () => design.createProject(name)),
|
|
28
|
-
}));
|
|
24
|
+
}, async ({ name }) => result({ project: await client.project.create({ name }) }));
|
|
29
25
|
server.registerTool("delete_project", {
|
|
30
26
|
description: "Permanently delete a project and its frames.",
|
|
31
27
|
inputSchema: projectInput,
|
|
@@ -35,5 +31,5 @@ export function registerProjectTools(server, design, run) {
|
|
|
35
31
|
openWorldHint: true,
|
|
36
32
|
idempotentHint: false,
|
|
37
33
|
},
|
|
38
|
-
}, async ({ project }) => result(await
|
|
34
|
+
}, async ({ project }) => result(await client.project.delete({ project })));
|
|
39
35
|
}
|
package/dist/mcp/register.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { DesignV1Client } from "../v1/client.js";
|
|
2
|
+
import type { DesignMcpOptions, DesignMcpServer } from "./types.js";
|
|
3
|
+
export declare function registerDesignTools(server: DesignMcpServer, client: DesignV1Client, options?: DesignMcpOptions): void;
|
package/dist/mcp/register.js
CHANGED
|
@@ -2,12 +2,9 @@ import { registerFileTools } from "./file.js";
|
|
|
2
2
|
import { registerFrameTools } from "./frame.js";
|
|
3
3
|
import { registerProjectTools } from "./project.js";
|
|
4
4
|
import { registerSkillTool } from "./skill.js";
|
|
5
|
-
export function registerDesignTools(server,
|
|
5
|
+
export function registerDesignTools(server, client, options = {}) {
|
|
6
6
|
registerSkillTool(server);
|
|
7
|
-
registerProjectTools(server,
|
|
8
|
-
registerFrameTools(server,
|
|
9
|
-
registerFileTools(server,
|
|
10
|
-
}
|
|
11
|
-
function runOperation(_name, operation) {
|
|
12
|
-
return operation();
|
|
7
|
+
registerProjectTools(server, client);
|
|
8
|
+
registerFrameTools(server, client, options.fetch ?? globalThis.fetch);
|
|
9
|
+
registerFileTools(server, client);
|
|
13
10
|
}
|
package/dist/mcp/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { CreateFrame, DesignFile, FileList, FileMutation, Frame, GenerateImageFrame, Project, Screenshot } from "../v1/schemas.js";
|
|
2
1
|
import type { z } from "zod";
|
|
3
2
|
export interface DesignMcpToolResult {
|
|
4
3
|
[key: string]: unknown;
|
|
@@ -27,28 +26,7 @@ type DesignMcpToolHandler<Input extends z.ZodType | undefined> = Input extends z
|
|
|
27
26
|
export interface DesignMcpServer {
|
|
28
27
|
registerTool<Input extends z.ZodType | undefined = undefined>(name: string, config: DesignMcpToolConfig<Input>, handler: DesignMcpToolHandler<Input>): unknown;
|
|
29
28
|
}
|
|
30
|
-
export interface
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
export type DesignMcpOperationRunner = <Result>(name: string, operation: () => Promise<Result>) => Promise<Result>;
|
|
34
|
-
export interface DesignMcpOperations {
|
|
35
|
-
listProjects(): Promise<Project[]>;
|
|
36
|
-
createProject(name: string): Promise<Project>;
|
|
37
|
-
deleteProject(project: string): Promise<{
|
|
38
|
-
id: string;
|
|
39
|
-
}>;
|
|
40
|
-
listFrames(project: string): Promise<Frame[]>;
|
|
41
|
-
createFrame(input: CreateFrame): Promise<Frame>;
|
|
42
|
-
generateImage(input: GenerateImageFrame): Promise<Frame>;
|
|
43
|
-
renameFrame(project: string, frame: string, name: string): Promise<Frame>;
|
|
44
|
-
deleteFrame(project: string, frame: string): Promise<{
|
|
45
|
-
id: string;
|
|
46
|
-
}>;
|
|
47
|
-
listFiles(project: string, path?: string): Promise<FileList>;
|
|
48
|
-
readFile(project: string, path: string): Promise<DesignFile>;
|
|
49
|
-
writeFile(project: string, path: string, text: string): Promise<FileMutation>;
|
|
50
|
-
editFile(project: string, path: string, oldText: string, newText: string): Promise<FileMutation>;
|
|
51
|
-
deleteFile(project: string, path: string): Promise<FileMutation>;
|
|
52
|
-
screenshot(project: string, frame: string): Promise<DesignMcpScreenshot>;
|
|
29
|
+
export interface DesignMcpOptions {
|
|
30
|
+
fetch?: typeof globalThis.fetch;
|
|
53
31
|
}
|
|
54
32
|
export {};
|
package/dist/options.js
ADDED
package/dist/project-state.d.ts
CHANGED
|
@@ -65,8 +65,8 @@ export declare const projectImageFrameRecordSchema: z.ZodObject<{
|
|
|
65
65
|
frameUpdatedAt: z.ZodString;
|
|
66
66
|
}, z.core.$strip>>;
|
|
67
67
|
result: z.ZodEnum<{
|
|
68
|
-
new: "new";
|
|
69
68
|
replace: "replace";
|
|
69
|
+
new: "new";
|
|
70
70
|
}>;
|
|
71
71
|
provider: z.ZodLiteral<"fal-ai">;
|
|
72
72
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -82,8 +82,8 @@ export declare const projectImageFrameRecordSchema: z.ZodObject<{
|
|
|
82
82
|
frameUpdatedAt: z.ZodString;
|
|
83
83
|
}, z.core.$strip>>;
|
|
84
84
|
result: z.ZodEnum<{
|
|
85
|
-
new: "new";
|
|
86
85
|
replace: "replace";
|
|
86
|
+
new: "new";
|
|
87
87
|
}>;
|
|
88
88
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
89
89
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -177,8 +177,8 @@ export declare const projectFrameRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObj
|
|
|
177
177
|
frameUpdatedAt: z.ZodString;
|
|
178
178
|
}, z.core.$strip>>;
|
|
179
179
|
result: z.ZodEnum<{
|
|
180
|
-
new: "new";
|
|
181
180
|
replace: "replace";
|
|
181
|
+
new: "new";
|
|
182
182
|
}>;
|
|
183
183
|
provider: z.ZodLiteral<"fal-ai">;
|
|
184
184
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -194,8 +194,8 @@ export declare const projectFrameRecordSchema: z.ZodDiscriminatedUnion<[z.ZodObj
|
|
|
194
194
|
frameUpdatedAt: z.ZodString;
|
|
195
195
|
}, z.core.$strip>>;
|
|
196
196
|
result: z.ZodEnum<{
|
|
197
|
-
new: "new";
|
|
198
197
|
replace: "replace";
|
|
198
|
+
new: "new";
|
|
199
199
|
}>;
|
|
200
200
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
201
201
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -287,8 +287,8 @@ export declare const projectStateSchema: z.ZodObject<{
|
|
|
287
287
|
frameUpdatedAt: z.ZodString;
|
|
288
288
|
}, z.core.$strip>>;
|
|
289
289
|
result: z.ZodEnum<{
|
|
290
|
-
new: "new";
|
|
291
290
|
replace: "replace";
|
|
291
|
+
new: "new";
|
|
292
292
|
}>;
|
|
293
293
|
provider: z.ZodLiteral<"fal-ai">;
|
|
294
294
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -304,8 +304,8 @@ export declare const projectStateSchema: z.ZodObject<{
|
|
|
304
304
|
frameUpdatedAt: z.ZodString;
|
|
305
305
|
}, z.core.$strip>>;
|
|
306
306
|
result: z.ZodEnum<{
|
|
307
|
-
new: "new";
|
|
308
307
|
replace: "replace";
|
|
308
|
+
new: "new";
|
|
309
309
|
}>;
|
|
310
310
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
311
311
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createLoginCommand, createLogoutCommand } from "./auth.js";
|
|
2
|
+
import { createDesignCommand } from "./command.js";
|
|
3
|
+
export function createDesignCli(options = {}) {
|
|
4
|
+
return createDesignCommand(options)
|
|
5
|
+
.addCommand(createLoginCommand())
|
|
6
|
+
.addCommand(createLogoutCommand());
|
|
7
|
+
}
|
package/dist/v1/contract.d.ts
CHANGED
|
@@ -154,8 +154,8 @@ export declare const contract: {
|
|
|
154
154
|
frameUpdatedAt: z.ZodString;
|
|
155
155
|
}, z.core.$strip>>;
|
|
156
156
|
result: z.ZodEnum<{
|
|
157
|
-
new: "new";
|
|
158
157
|
replace: "replace";
|
|
158
|
+
new: "new";
|
|
159
159
|
}>;
|
|
160
160
|
provider: z.ZodLiteral<"fal-ai">;
|
|
161
161
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -171,8 +171,8 @@ export declare const contract: {
|
|
|
171
171
|
frameUpdatedAt: z.ZodString;
|
|
172
172
|
}, z.core.$strip>>;
|
|
173
173
|
result: z.ZodEnum<{
|
|
174
|
-
new: "new";
|
|
175
174
|
replace: "replace";
|
|
175
|
+
new: "new";
|
|
176
176
|
}>;
|
|
177
177
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
178
178
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -264,8 +264,8 @@ export declare const contract: {
|
|
|
264
264
|
frameUpdatedAt: z.ZodString;
|
|
265
265
|
}, z.core.$strip>>;
|
|
266
266
|
result: z.ZodEnum<{
|
|
267
|
-
new: "new";
|
|
268
267
|
replace: "replace";
|
|
268
|
+
new: "new";
|
|
269
269
|
}>;
|
|
270
270
|
provider: z.ZodLiteral<"fal-ai">;
|
|
271
271
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -281,8 +281,8 @@ export declare const contract: {
|
|
|
281
281
|
frameUpdatedAt: z.ZodString;
|
|
282
282
|
}, z.core.$strip>>;
|
|
283
283
|
result: z.ZodEnum<{
|
|
284
|
-
new: "new";
|
|
285
284
|
replace: "replace";
|
|
285
|
+
new: "new";
|
|
286
286
|
}>;
|
|
287
287
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
288
288
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -311,8 +311,8 @@ export declare const contract: {
|
|
|
311
311
|
target: z.ZodOptional<z.ZodString>;
|
|
312
312
|
references: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
313
313
|
result: z.ZodEnum<{
|
|
314
|
-
new: "new";
|
|
315
314
|
replace: "replace";
|
|
315
|
+
new: "new";
|
|
316
316
|
}>;
|
|
317
317
|
name: z.ZodOptional<z.ZodString>;
|
|
318
318
|
x: z.ZodOptional<z.ZodNumber>;
|
|
@@ -368,8 +368,8 @@ export declare const contract: {
|
|
|
368
368
|
frameUpdatedAt: z.ZodString;
|
|
369
369
|
}, z.core.$strip>>;
|
|
370
370
|
result: z.ZodEnum<{
|
|
371
|
-
new: "new";
|
|
372
371
|
replace: "replace";
|
|
372
|
+
new: "new";
|
|
373
373
|
}>;
|
|
374
374
|
provider: z.ZodLiteral<"fal-ai">;
|
|
375
375
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -385,8 +385,8 @@ export declare const contract: {
|
|
|
385
385
|
frameUpdatedAt: z.ZodString;
|
|
386
386
|
}, z.core.$strip>>;
|
|
387
387
|
result: z.ZodEnum<{
|
|
388
|
-
new: "new";
|
|
389
388
|
replace: "replace";
|
|
389
|
+
new: "new";
|
|
390
390
|
}>;
|
|
391
391
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
392
392
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -460,8 +460,8 @@ export declare const contract: {
|
|
|
460
460
|
frameUpdatedAt: z.ZodString;
|
|
461
461
|
}, z.core.$strip>>;
|
|
462
462
|
result: z.ZodEnum<{
|
|
463
|
-
new: "new";
|
|
464
463
|
replace: "replace";
|
|
464
|
+
new: "new";
|
|
465
465
|
}>;
|
|
466
466
|
provider: z.ZodLiteral<"fal-ai">;
|
|
467
467
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -477,8 +477,8 @@ export declare const contract: {
|
|
|
477
477
|
frameUpdatedAt: z.ZodString;
|
|
478
478
|
}, z.core.$strip>>;
|
|
479
479
|
result: z.ZodEnum<{
|
|
480
|
-
new: "new";
|
|
481
480
|
replace: "replace";
|
|
481
|
+
new: "new";
|
|
482
482
|
}>;
|
|
483
483
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
484
484
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -566,8 +566,8 @@ export declare const contract: {
|
|
|
566
566
|
frameUpdatedAt: z.ZodString;
|
|
567
567
|
}, z.core.$strip>>;
|
|
568
568
|
result: z.ZodEnum<{
|
|
569
|
-
new: "new";
|
|
570
569
|
replace: "replace";
|
|
570
|
+
new: "new";
|
|
571
571
|
}>;
|
|
572
572
|
provider: z.ZodLiteral<"fal-ai">;
|
|
573
573
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -583,8 +583,8 @@ export declare const contract: {
|
|
|
583
583
|
frameUpdatedAt: z.ZodString;
|
|
584
584
|
}, z.core.$strip>>;
|
|
585
585
|
result: z.ZodEnum<{
|
|
586
|
-
new: "new";
|
|
587
586
|
replace: "replace";
|
|
587
|
+
new: "new";
|
|
588
588
|
}>;
|
|
589
589
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
590
590
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -661,8 +661,8 @@ export declare const contract: {
|
|
|
661
661
|
frameUpdatedAt: z.ZodString;
|
|
662
662
|
}, z.core.$strip>>;
|
|
663
663
|
result: z.ZodEnum<{
|
|
664
|
-
new: "new";
|
|
665
664
|
replace: "replace";
|
|
665
|
+
new: "new";
|
|
666
666
|
}>;
|
|
667
667
|
provider: z.ZodLiteral<"fal-ai">;
|
|
668
668
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -678,8 +678,8 @@ export declare const contract: {
|
|
|
678
678
|
frameUpdatedAt: z.ZodString;
|
|
679
679
|
}, z.core.$strip>>;
|
|
680
680
|
result: z.ZodEnum<{
|
|
681
|
-
new: "new";
|
|
682
681
|
replace: "replace";
|
|
682
|
+
new: "new";
|
|
683
683
|
}>;
|
|
684
684
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
685
685
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
package/dist/v1/schemas.d.ts
CHANGED
|
@@ -97,8 +97,8 @@ export declare const imageGenerationOperationSchema: z.ZodEnum<{
|
|
|
97
97
|
edit: "edit";
|
|
98
98
|
}>;
|
|
99
99
|
export declare const imageGenerationResultSchema: z.ZodEnum<{
|
|
100
|
-
new: "new";
|
|
101
100
|
replace: "replace";
|
|
101
|
+
new: "new";
|
|
102
102
|
}>;
|
|
103
103
|
export declare const imageGenerationReferenceSchema: z.ZodObject<{
|
|
104
104
|
frameId: z.ZodString;
|
|
@@ -120,8 +120,8 @@ export declare const imageGenerationProvenanceSchema: z.ZodDiscriminatedUnion<[z
|
|
|
120
120
|
frameUpdatedAt: z.ZodString;
|
|
121
121
|
}, z.core.$strip>>;
|
|
122
122
|
result: z.ZodEnum<{
|
|
123
|
-
new: "new";
|
|
124
123
|
replace: "replace";
|
|
124
|
+
new: "new";
|
|
125
125
|
}>;
|
|
126
126
|
provider: z.ZodLiteral<"fal-ai">;
|
|
127
127
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -137,8 +137,8 @@ export declare const imageGenerationProvenanceSchema: z.ZodDiscriminatedUnion<[z
|
|
|
137
137
|
frameUpdatedAt: z.ZodString;
|
|
138
138
|
}, z.core.$strip>>;
|
|
139
139
|
result: z.ZodEnum<{
|
|
140
|
-
new: "new";
|
|
141
140
|
replace: "replace";
|
|
141
|
+
new: "new";
|
|
142
142
|
}>;
|
|
143
143
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
144
144
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -168,8 +168,8 @@ export declare const imageFrameSchema: z.ZodObject<{
|
|
|
168
168
|
frameUpdatedAt: z.ZodString;
|
|
169
169
|
}, z.core.$strip>>;
|
|
170
170
|
result: z.ZodEnum<{
|
|
171
|
-
new: "new";
|
|
172
171
|
replace: "replace";
|
|
172
|
+
new: "new";
|
|
173
173
|
}>;
|
|
174
174
|
provider: z.ZodLiteral<"fal-ai">;
|
|
175
175
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -185,8 +185,8 @@ export declare const imageFrameSchema: z.ZodObject<{
|
|
|
185
185
|
frameUpdatedAt: z.ZodString;
|
|
186
186
|
}, z.core.$strip>>;
|
|
187
187
|
result: z.ZodEnum<{
|
|
188
|
-
new: "new";
|
|
189
188
|
replace: "replace";
|
|
189
|
+
new: "new";
|
|
190
190
|
}>;
|
|
191
191
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
192
192
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -257,8 +257,8 @@ export declare const frameSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
257
257
|
frameUpdatedAt: z.ZodString;
|
|
258
258
|
}, z.core.$strip>>;
|
|
259
259
|
result: z.ZodEnum<{
|
|
260
|
-
new: "new";
|
|
261
260
|
replace: "replace";
|
|
261
|
+
new: "new";
|
|
262
262
|
}>;
|
|
263
263
|
provider: z.ZodLiteral<"fal-ai">;
|
|
264
264
|
model: z.ZodLiteral<"openai/gpt-image-2">;
|
|
@@ -274,8 +274,8 @@ export declare const frameSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
274
274
|
frameUpdatedAt: z.ZodString;
|
|
275
275
|
}, z.core.$strip>>;
|
|
276
276
|
result: z.ZodEnum<{
|
|
277
|
-
new: "new";
|
|
278
277
|
replace: "replace";
|
|
278
|
+
new: "new";
|
|
279
279
|
}>;
|
|
280
280
|
provider: z.ZodLiteral<"cloudflare-workers-ai">;
|
|
281
281
|
model: z.ZodLiteral<"@cf/black-forest-labs/flux-2-klein-4b">;
|
|
@@ -352,8 +352,8 @@ export declare const generateImageFrameSchema: z.ZodObject<{
|
|
|
352
352
|
target: z.ZodOptional<z.ZodString>;
|
|
353
353
|
references: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
354
354
|
result: z.ZodEnum<{
|
|
355
|
-
new: "new";
|
|
356
355
|
replace: "replace";
|
|
356
|
+
new: "new";
|
|
357
357
|
}>;
|
|
358
358
|
name: z.ZodOptional<z.ZodString>;
|
|
359
359
|
x: z.ZodOptional<z.ZodNumber>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drawcall/design",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Typed API and remote CLI for Drawcall Design",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"skills"
|
|
17
17
|
],
|
|
18
18
|
"bin": {
|
|
19
|
-
"design": "
|
|
19
|
+
"design": "dist/cli.js"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"generate": "node scripts/generate-skill.mjs",
|
package/dist/mcp/client.d.ts
DELETED
package/dist/mcp/client.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
export function createDesignMcpOperations(client, fetcher = globalThis.fetch) {
|
|
2
|
-
return {
|
|
3
|
-
listProjects: () => client.project.list(),
|
|
4
|
-
createProject: (name) => client.project.create({ name }),
|
|
5
|
-
deleteProject: (project) => client.project.delete({ project }),
|
|
6
|
-
listFrames: (project) => client.frame.list({ project }),
|
|
7
|
-
createFrame: (input) => client.frame.create(input),
|
|
8
|
-
generateImage: (input) => client.frame.generateImage(input),
|
|
9
|
-
renameFrame: (project, frame, name) => client.frame.rename({ project, frame, name }),
|
|
10
|
-
deleteFrame: (project, frame) => client.frame.delete({ project, frame }),
|
|
11
|
-
listFiles: (project, path) => client.filesystem.list({
|
|
12
|
-
project,
|
|
13
|
-
...(path === undefined ? {} : { path }),
|
|
14
|
-
}),
|
|
15
|
-
readFile: (project, path) => client.filesystem.read({ project, path }),
|
|
16
|
-
writeFile: (project, path, text) => client.filesystem.write({ project, path, text }),
|
|
17
|
-
editFile: (project, path, oldText, newText) => client.filesystem.edit({ project, path, oldText, newText }),
|
|
18
|
-
deleteFile: (project, path) => client.filesystem.delete({ project, path }),
|
|
19
|
-
screenshot: async (project, frame) => {
|
|
20
|
-
const screenshot = await client.frame.screenshot({ project, frame });
|
|
21
|
-
const response = await fetcher(screenshot.url);
|
|
22
|
-
if (!response.ok) {
|
|
23
|
-
throw new Error(`Could not read screenshot ${screenshot.url}: ${response.status} ${response.statusText}`);
|
|
24
|
-
}
|
|
25
|
-
const mediaType = response.headers
|
|
26
|
-
.get("content-type")
|
|
27
|
-
?.split(";", 1)[0]
|
|
28
|
-
?.trim();
|
|
29
|
-
if (mediaType !== screenshot.mediaType) {
|
|
30
|
-
throw new Error(`Screenshot ${screenshot.url} returned ${mediaType ?? "no media type"}; expected ${screenshot.mediaType}`);
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
...screenshot,
|
|
34
|
-
png: new Uint8Array(await response.arrayBuffer()),
|
|
35
|
-
};
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
}
|