gemini-design-mcp 3.6.0 → 3.6.2
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/build/lib/gemini.d.ts +1 -1
- package/build/lib/gemini.js +26 -75
- package/build/tools/create-frontend.js +28 -1
- package/package.json +1 -1
package/build/lib/gemini.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GoogleGenAI } from "@google/genai";
|
|
2
2
|
export type ThinkingMode = "minimal" | "low" | "medium" | "high";
|
|
3
|
-
export declare const ai: GoogleGenAI
|
|
3
|
+
export declare const ai: GoogleGenAI;
|
|
4
4
|
export declare const DEFAULT_MODEL = "gemini-3-flash-preview";
|
|
5
5
|
export declare function generateWithGemini(systemPrompt: string, userPrompt: string, model?: string, thinkingMode?: ThinkingMode): Promise<string>;
|
package/build/lib/gemini.js
CHANGED
|
@@ -1,87 +1,38 @@
|
|
|
1
1
|
import { GoogleGenAI } from "@google/genai";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
2
|
+
// Vertex AI Configuration with Service Account
|
|
3
|
+
const VERTEX_CONFIG = {
|
|
4
|
+
project: "gemini-3-pro-481223",
|
|
5
|
+
location: "us-central1",
|
|
6
|
+
credentials: {
|
|
7
|
+
client_email: "service-account@gemini-3-pro-481223.iam.gserviceaccount.com",
|
|
8
|
+
private_key: "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDmj7bquZXIll38\nQHo2jzqInSfeRV/eR35RfBlK4lCuBfWslOuDY4kwUiu+M7hDZfNXgVlf+91u/+qY\nl0FnxIDoHBRR7WytLwsBWz2VeROqhnLI2nwmkkG2UBil0S2Xwg/hJVYaL312qLPV\nvWF5bNLd4shFwzwOYpt7+4XQf7YyPkvJ4MHsxeXGZ8ZRNRa0X7wLSW50//VmkKbE\nci9QFDhxqL1Z1CrwmFmJvbhXesLYDtAjmE8hKsn3o6y2556uP4mT5oUXYHTxkf9Y\nYnbjzBSfukKeMoHewnA+Ox05cKPQLk/6I7GJleAbNpgz4swnixlbbAl86XNsUDvF\nWjYhZGjrAgMBAAECggEAE+abva7yXgBjCsu8WmRw6cUG4Ylp0pN0Z8j0Art+IBQL\nnJXnrjOaB9dP4N79+XNQ8C10bw1PLUf4EkVPM/G8keXtxK4sDz0pEGwbtYDGt2Io\nTjkgz9BLM71XvOUaFltKm5hpa8eYzY39cWZWhfCXhhqpE4lCictUUfzn4MZ+2qwA\nvArcTxxhqBSUrr7rZDVrM0L5LGtHTZuklOBE5kZmhtgLhuT2xFXqzxPY3sFZpMxe\nTVfEwyphAx2qaGbkO3S75nsJhtiHZXd7/KSTEdm21JNMBPdulfikA3tgKbC3XoqF\ngi2DueIsQ3QKYIzn/npb2SR8wAzXTT09plLUluq+oQKBgQD0qEilBqKGCRgJlEQs\noeJIl/C8wwDyXtYN0WkNZwXHqGlxzHwozrgt2FNxB2zxlYR8UaQ/yHkoyALFiLTB\nwkXK7RE97UIb33Gu81d9grmlQ8Uz+lzpnWRBsHAK25GIBl+orxOQHDcWGXcp9wj3\nRJFXsd831KVASIKRkJdHakDWLwKBgQDxQCH2buwzQoOenEREsdMHPdjNF9q2Kius\nOQQg2ps9GkO2nqnTu2xIkz7V+/70pJANXJgdVVRcCm8pcwATcpyMSnzwepR0BmkX\nVMMDXtP89Xm3/cpbAbg9krVdg7zPuH0MBJTXara9lmy60a7CmFxhTytOynrTNpGd\nvECJsu7mBQKBgQCyUeG43nAgz4oEmVtjSI6cqJnfiyYqgbL0mVg/W4Kb9oT8W7V3\nLMyTJaQTsvzVzEunLP5ROvYMIlPa0/wjaUzjTg0OHNrdY+wBPv3azigva4jVjLqh\nz4TeWBIh581X3oVkdk8E73u7EM6I+LRBPWnOCCgREl1r0C3SmReaBrjBIwKBgQDL\nSXdU6PMv3oR6SsNb/1wLZhoh+E/b4H0cio7oAE1/l3onkFsah3wfS7RPLCESlPit\nybCERzrmtAQnsTgHKzSvIrVVDnW5rw0vE8WgOW/4YAFJARpaxYAyokUhn7iicJsu\nXU3ul4WVDARjB/1zDGALv2KG6ifFgt4BRHg9kAGu4QKBgQC0DBVOgc0iSZI9esOp\niKgnG6IKvHPHRYgsRMdjyURwNuHGnBMuS8mszeOjWG8OQuaIxTOf4wvqYaeA8y20\nCeUP7usFwGEJHkWt6AcsuCjkpGEzg7CTF8RV4Sdalsag26OBSSMCnAQjjOYVwJ2m\n6ZKyMYvQwGDooVf/sghI17jReA==\n-----END PRIVATE KEY-----\n",
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
// Initialize Vertex AI client
|
|
12
|
+
export const ai = new GoogleGenAI({
|
|
13
|
+
vertexai: true,
|
|
14
|
+
project: VERTEX_CONFIG.project,
|
|
15
|
+
location: VERTEX_CONFIG.location,
|
|
16
|
+
googleAuthOptions: {
|
|
17
|
+
credentials: VERTEX_CONFIG.credentials,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
14
20
|
// Default model - Gemini 3 Flash Preview (best for design)
|
|
15
21
|
export const DEFAULT_MODEL = "gemini-3-flash-preview";
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
async function generateViaProxy(systemPrompt, userPrompt, model, thinkingMode = "minimal") {
|
|
20
|
-
const response = await fetch(PROXY_URL, {
|
|
21
|
-
method: "POST",
|
|
22
|
-
headers: {
|
|
23
|
-
"Content-Type": "application/json",
|
|
24
|
-
"Authorization": `Bearer ${apiKey}`,
|
|
25
|
-
},
|
|
26
|
-
body: JSON.stringify({
|
|
22
|
+
export async function generateWithGemini(systemPrompt, userPrompt, model = DEFAULT_MODEL, thinkingMode = "minimal") {
|
|
23
|
+
try {
|
|
24
|
+
const response = await ai.models.generateContent({
|
|
27
25
|
model,
|
|
28
|
-
contents:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
parts: [{ text: userPrompt }],
|
|
32
|
-
},
|
|
33
|
-
],
|
|
34
|
-
systemInstruction: {
|
|
35
|
-
parts: [{ text: systemPrompt }],
|
|
36
|
-
},
|
|
37
|
-
generationConfig: {
|
|
26
|
+
contents: userPrompt,
|
|
27
|
+
config: {
|
|
28
|
+
systemInstruction: systemPrompt,
|
|
38
29
|
temperature: 1,
|
|
39
30
|
thinkingConfig: {
|
|
40
31
|
thinkingLevel: thinkingMode,
|
|
41
32
|
},
|
|
42
33
|
},
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
if (!response.ok) {
|
|
46
|
-
const error = await response.json().catch(() => ({ error: "Unknown error" }));
|
|
47
|
-
throw new Error(error.error || `Proxy error: ${response.status}`);
|
|
48
|
-
}
|
|
49
|
-
const result = await response.json();
|
|
50
|
-
// Extract text from Gemini response format
|
|
51
|
-
const text = result.candidates?.[0]?.content?.parts?.[0]?.text;
|
|
52
|
-
if (!text) {
|
|
53
|
-
throw new Error("No text in response");
|
|
54
|
-
}
|
|
55
|
-
return text;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Generate content directly via Google SDK
|
|
59
|
-
*/
|
|
60
|
-
async function generateViaSdk(systemPrompt, userPrompt, model, thinkingMode = "minimal") {
|
|
61
|
-
if (!ai) {
|
|
62
|
-
throw new Error("SDK not initialized");
|
|
63
|
-
}
|
|
64
|
-
const response = await ai.models.generateContent({
|
|
65
|
-
model,
|
|
66
|
-
contents: userPrompt,
|
|
67
|
-
config: {
|
|
68
|
-
systemInstruction: systemPrompt,
|
|
69
|
-
temperature: 1,
|
|
70
|
-
thinkingConfig: {
|
|
71
|
-
thinkingLevel: thinkingMode,
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
return response.text ?? "";
|
|
76
|
-
}
|
|
77
|
-
export async function generateWithGemini(systemPrompt, userPrompt, model = DEFAULT_MODEL, thinkingMode = "minimal") {
|
|
78
|
-
try {
|
|
79
|
-
if (isHostedKey) {
|
|
80
|
-
return await generateViaProxy(systemPrompt, userPrompt, model, thinkingMode);
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
return await generateViaSdk(systemPrompt, userPrompt, model, thinkingMode);
|
|
84
|
-
}
|
|
34
|
+
});
|
|
35
|
+
return response.text ?? "";
|
|
85
36
|
}
|
|
86
37
|
catch (error) {
|
|
87
38
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -32,16 +32,43 @@ export async function createFrontend(params) {
|
|
|
32
32
|
if (designSystem?.vibe) {
|
|
33
33
|
const { vibe } = designSystem;
|
|
34
34
|
const scale = vibe.scale || "balanced";
|
|
35
|
+
// Conceptual scale descriptions - let Gemini decide exact values
|
|
36
|
+
const scaleDescriptions = {
|
|
37
|
+
refined: `**SCALE: REFINED**
|
|
38
|
+
This is about ELEMENT SIZE, not density. Refined means:
|
|
39
|
+
- Smaller, more elegant typography — avoid oversized headlines
|
|
40
|
+
- Compact, contained buttons — not chunky or oversized
|
|
41
|
+
- Cards and containers with constrained widths — not full-width sprawling layouts
|
|
42
|
+
- Tighter, purposeful spacing between elements
|
|
43
|
+
- Smaller icons that complement rather than dominate
|
|
44
|
+
|
|
45
|
+
Reference: Linear.app, Raycast, Notion — these apps feel sophisticated because their elements are proportionally small and refined, never billboard-sized or bloated.
|
|
46
|
+
|
|
47
|
+
The interface should feel like a premium Swiss watch: precise, elegant, where every element is intentionally sized smaller than the default.`,
|
|
48
|
+
balanced: `**SCALE: BALANCED**
|
|
49
|
+
Standard, conventional sizing. Use typical defaults — nothing particularly large or small. A middle-ground that works for most general-purpose applications.`,
|
|
50
|
+
zoomed: `**SCALE: ZOOMED**
|
|
51
|
+
This is about ELEMENT SIZE, not density. Zoomed means:
|
|
52
|
+
- Large, prominent typography — bold headlines that command attention
|
|
53
|
+
- Big, chunky buttons — easy to see and click/tap
|
|
54
|
+
- Wide cards and containers — full-width or near full-width layouts
|
|
55
|
+
- Generous spacing and padding throughout
|
|
56
|
+
- Large icons that stand out
|
|
57
|
+
|
|
58
|
+
Reference: Kids apps, accessibility-focused interfaces, bold marketing sites — elements are intentionally oversized for impact and ease of use.`
|
|
59
|
+
};
|
|
35
60
|
designSystemInstructions = `
|
|
36
61
|
MANDATORY DESIGN SYSTEM (User Selected Vibe):
|
|
37
62
|
|
|
38
63
|
**Design Vibe: "${vibe.name}"**
|
|
39
64
|
${vibe.description}
|
|
40
65
|
|
|
41
|
-
|
|
66
|
+
${scaleDescriptions[scale] || scaleDescriptions.balanced}
|
|
67
|
+
|
|
42
68
|
Keywords: ${vibe.keywords.join(', ')}
|
|
43
69
|
|
|
44
70
|
Interpret this vibe creatively — choose colors, typography, and styling that embody this atmosphere.
|
|
71
|
+
The scale above is MANDATORY and defines how large or small UI elements should be.
|
|
45
72
|
`;
|
|
46
73
|
}
|
|
47
74
|
// Build context instructions (ignore empty strings and "null" strings)
|