@kvasar/google-stitch 0.1.7 → 0.1.8
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/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -32,6 +32,14 @@ export class StitchMCPClient {
|
|
|
32
32
|
this.connected = true;
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
async createProject(title?: string) {
|
|
36
|
+
await this.connect();
|
|
37
|
+
|
|
38
|
+
return this.client.callTool({
|
|
39
|
+
name: "create_project",
|
|
40
|
+
arguments: title ? { title } : {},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
35
43
|
|
|
36
44
|
async generateScreen(prompt: string) {
|
|
37
45
|
await this.connect();
|
|
@@ -1,7 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Tool: create_project
|
|
3
|
+
* Creates a new Stitch project. A project is a container for UI designs and frontend code.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Type } from "@sinclair/typebox";
|
|
7
|
+
import { StitchMCPClient } from "../services/stitch-mcp-client.js";
|
|
8
|
+
|
|
9
|
+
export interface CreateProjectParams {
|
|
10
|
+
title?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function createProjectTool(client: StitchMCPClient) {
|
|
14
|
+
return {
|
|
15
|
+
name: "create_project" as const,
|
|
16
|
+
description: "Creates a new Stitch project. A project is a container for UI designs and frontend code.",
|
|
17
|
+
parameters: Type.Object({
|
|
18
|
+
title: Type.Optional(
|
|
19
|
+
Type.String({ description: "Optional. The title of the project." })
|
|
20
|
+
),
|
|
21
|
+
}),
|
|
22
|
+
async execute(_id: string, params: CreateProjectParams) {
|
|
23
|
+
const result = await client.createProject(params.title);
|
|
24
|
+
return {
|
|
25
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { StitchMCPClient } from "../services/stitch-mcp-client.js";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import os from "node:os";
|
|
2
5
|
|
|
3
6
|
type StitchGenerateResponse = {
|
|
4
7
|
html?: string;
|
|
@@ -10,6 +13,16 @@ type StitchGenerateResponse = {
|
|
|
10
13
|
code?: string;
|
|
11
14
|
jsx?: string;
|
|
12
15
|
};
|
|
16
|
+
imageUrl?: string;
|
|
17
|
+
screenshotUrl?: string;
|
|
18
|
+
previewUrl?: string;
|
|
19
|
+
data?: {
|
|
20
|
+
imageUrl?: string;
|
|
21
|
+
screenshotUrl?: string;
|
|
22
|
+
previewUrl?: string;
|
|
23
|
+
base64Image?: string;
|
|
24
|
+
rawBytes?: string;
|
|
25
|
+
};
|
|
13
26
|
};
|
|
14
27
|
|
|
15
28
|
export function generateScreenFromTextTool(client: StitchMCPClient) {
|
|
@@ -34,6 +47,59 @@ export function generateScreenFromTextTool(client: StitchMCPClient) {
|
|
|
34
47
|
params.prompt
|
|
35
48
|
)) as StitchGenerateResponse;
|
|
36
49
|
|
|
50
|
+
// Check for image URLs or base64 data
|
|
51
|
+
const imageUrl = result.imageUrl || result.screenshotUrl || result.previewUrl ||
|
|
52
|
+
result.data?.imageUrl || result.data?.screenshotUrl || result.data?.previewUrl;
|
|
53
|
+
const base64Image = result.data?.base64Image;
|
|
54
|
+
const rawBytes = result.data?.rawBytes;
|
|
55
|
+
|
|
56
|
+
if (imageUrl) {
|
|
57
|
+
// If we have an image URL, return it as an image block
|
|
58
|
+
return {
|
|
59
|
+
content: [
|
|
60
|
+
{
|
|
61
|
+
type: "image",
|
|
62
|
+
url: imageUrl,
|
|
63
|
+
caption: "Generated by Google Stitch"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
};
|
|
67
|
+
} else if (base64Image || rawBytes) {
|
|
68
|
+
// Decode and save base64 or raw bytes to a temporary file
|
|
69
|
+
const tempDir = os.tmpdir();
|
|
70
|
+
const tempFilePath = path.join(tempDir, `stitch-screen-${Date.now()}.png`);
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
let imageData: Buffer;
|
|
74
|
+
if (base64Image) {
|
|
75
|
+
// Remove data URL prefix if present
|
|
76
|
+
const cleanBase64 = base64Image.replace(/^data:image\/\w+;base64,/, '');
|
|
77
|
+
imageData = Buffer.from(cleanBase64, 'base64');
|
|
78
|
+
} else if (rawBytes) {
|
|
79
|
+
// Assuming rawBytes is base64 encoded
|
|
80
|
+
imageData = Buffer.from(rawBytes, 'base64');
|
|
81
|
+
} else {
|
|
82
|
+
throw new Error("No image data found");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
fs.writeFileSync(tempFilePath, imageData);
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
content: [
|
|
89
|
+
{
|
|
90
|
+
type: "image",
|
|
91
|
+
path: tempFilePath,
|
|
92
|
+
caption: "Generated by Google Stitch"
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
};
|
|
96
|
+
} catch (error) {
|
|
97
|
+
console.error("Failed to save image:", error);
|
|
98
|
+
// Fall back to HTML if image processing fails
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Fallback to HTML if no image data is available
|
|
37
103
|
const html =
|
|
38
104
|
result.html ??
|
|
39
105
|
result.previewHtml ??
|