gemini-design-mcp 2.0.0 → 3.0.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/build/index.js +218 -40
- package/build/prompts/system.d.ts +3 -1
- package/build/prompts/system.js +101 -6
- package/build/tools/{generate-frontend.d.ts → create-frontend.d.ts} +13 -15
- package/build/tools/create-frontend.js +71 -0
- package/build/tools/modify-frontend.d.ts +18 -0
- package/build/tools/modify-frontend.js +46 -0
- package/build/tools/snippet-frontend.d.ts +20 -0
- package/build/tools/snippet-frontend.js +46 -0
- package/package.json +1 -1
- package/build/tools/generate-frontend.js +0 -61
package/build/index.js
CHANGED
|
@@ -1,74 +1,252 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
-
import {
|
|
4
|
+
import { createFrontendSchema, createFrontend } from "./tools/create-frontend.js";
|
|
5
|
+
import { modifyFrontendSchema, modifyFrontend } from "./tools/modify-frontend.js";
|
|
6
|
+
import { snippetFrontendSchema, snippetFrontend } from "./tools/snippet-frontend.js";
|
|
5
7
|
// Create MCP server
|
|
6
8
|
const server = new McpServer({
|
|
7
9
|
name: "gemini-design-mcp",
|
|
8
|
-
version: "
|
|
10
|
+
version: "3.0.0",
|
|
9
11
|
});
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// TOOL 1: CREATE_FRONTEND
|
|
14
|
+
// =============================================================================
|
|
15
|
+
server.tool("create_frontend", `Create a NEW, complete frontend file (page, component, layout, section).
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
18
|
+
🎯 WHEN TO USE THIS TOOL
|
|
19
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
20
|
+
|
|
21
|
+
Use this tool when you need to create a NEW file that doesn't exist yet:
|
|
22
|
+
✅ "Create a pricing page with 3 tiers"
|
|
23
|
+
✅ "Create a new UserProfile component"
|
|
24
|
+
✅ "Create the main dashboard layout"
|
|
25
|
+
✅ "Create a settings page"
|
|
26
|
+
|
|
27
|
+
DO NOT use this tool for:
|
|
28
|
+
❌ Modifying existing files → use modify_frontend
|
|
29
|
+
❌ Adding code to existing files → use snippet_frontend
|
|
14
30
|
|
|
15
31
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
-
|
|
32
|
+
⚠️ CRITICAL: MANDATORY FLOW BEFORE CALLING
|
|
17
33
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
18
34
|
|
|
19
|
-
|
|
20
|
-
|
|
35
|
+
STEP 1: CHECK PROJECT STATE
|
|
36
|
+
─────────────────────────────
|
|
37
|
+
Before calling this tool, you MUST check the project state:
|
|
38
|
+
|
|
39
|
+
A) EMPTY REPO (no package.json, no framework):
|
|
40
|
+
→ DO NOT call any tool yet
|
|
21
41
|
→ Ask user: "What tech stack do you want? (Next.js, React + Vite, Vue, etc.)"
|
|
22
|
-
→
|
|
23
|
-
→ Only proceed after
|
|
42
|
+
→ Help them initialize the project first
|
|
43
|
+
→ Only proceed after framework is installed
|
|
44
|
+
|
|
45
|
+
B) PROJECT EXISTS but NO frontend files/design yet:
|
|
46
|
+
→ Proceed to Step 2 (Vibe Selection) - MANDATORY
|
|
47
|
+
|
|
48
|
+
C) PROJECT EXISTS with existing frontend code:
|
|
49
|
+
→ Analyze existing files to understand design system
|
|
50
|
+
→ Pass relevant files as context parameter
|
|
51
|
+
→ Skip vibe selection (use existing design system)
|
|
52
|
+
|
|
53
|
+
STEP 2: VIBE SELECTION (Required for new designs)
|
|
54
|
+
──────────────────────────────────────────────────
|
|
55
|
+
If the project has no existing design system, you MUST run vibe selection:
|
|
56
|
+
|
|
57
|
+
1. Generate 5 vibe options with RICH, EVOCATIVE descriptions (2-3 sentences each).
|
|
58
|
+
Each vibe should paint a vivid picture of the aesthetic. Examples:
|
|
59
|
+
|
|
60
|
+
🏛️ "Pristine Museum"
|
|
61
|
+
An ultra-clean, 'white-cube' aesthetic focused on vast negative space and
|
|
62
|
+
absolute stillness. Content is displayed like art in a modern gallery.
|
|
63
|
+
Minimal chrome, maximum breathing room, typography as sculpture.
|
|
64
|
+
|
|
65
|
+
⚡ "Technical Precision"
|
|
66
|
+
A layout-driven vibe emphasizing the grid and intentional structure.
|
|
67
|
+
Sharp edges, monospace accents, blueprint energy. Feels slightly
|
|
68
|
+
'under construction' in a cool, architectural way.
|
|
69
|
+
|
|
70
|
+
🌊 "Fluid & Organic"
|
|
71
|
+
Soft curves, flowing gradients, and natural movement throughout.
|
|
72
|
+
Like water or silk, everything feels smooth and interconnected.
|
|
73
|
+
Calming yet sophisticated, with gentle animations.
|
|
74
|
+
|
|
75
|
+
🔥 "Bold & Unapologetic"
|
|
76
|
+
High contrast, oversized typography, dramatic color blocks.
|
|
77
|
+
It demands attention and makes a statement. Not for the faint of heart.
|
|
78
|
+
Strong visual hierarchy, impactful first impressions.
|
|
79
|
+
|
|
80
|
+
🌙 "Dark Luxe"
|
|
81
|
+
Deep, rich darks with subtle metallic or jewel-tone accents.
|
|
82
|
+
Premium feel, like a high-end app at night. Sophisticated shadows,
|
|
83
|
+
glowing highlights, and refined micro-interactions.
|
|
84
|
+
|
|
85
|
+
2. Present vibes to user, wait for selection
|
|
86
|
+
|
|
87
|
+
3. Call this tool with designSystem.vibe filled
|
|
88
|
+
|
|
89
|
+
STEP 3: GATHER CONTEXT
|
|
90
|
+
───────────────────────
|
|
91
|
+
If the project has existing code:
|
|
92
|
+
- Read relevant files (components, styles, theme config)
|
|
93
|
+
- Pass them as the context parameter
|
|
94
|
+
- This ensures Gemini matches the existing design system
|
|
95
|
+
|
|
96
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
97
|
+
📤 OUTPUT
|
|
98
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
99
|
+
|
|
100
|
+
Returns a COMPLETE file with:
|
|
101
|
+
- All necessary imports at the top
|
|
102
|
+
- Proper component/page structure
|
|
103
|
+
- Exports (default or named)
|
|
104
|
+
- Ready to save directly to filePath`, createFrontendSchema, createFrontend);
|
|
105
|
+
// =============================================================================
|
|
106
|
+
// TOOL 2: MODIFY_FRONTEND
|
|
107
|
+
// =============================================================================
|
|
108
|
+
server.tool("modify_frontend", `Modify an EXISTING frontend file while maintaining design quality.
|
|
109
|
+
|
|
110
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
111
|
+
🎯 WHEN TO USE THIS TOOL
|
|
112
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
113
|
+
|
|
114
|
+
Use this tool when you need to CHANGE an existing file:
|
|
115
|
+
✅ "Add a delete button to this card component"
|
|
116
|
+
✅ "Change the color scheme from blue to purple"
|
|
117
|
+
✅ "Add loading and error states"
|
|
118
|
+
✅ "Make this sidebar collapsible"
|
|
119
|
+
✅ "Add dark mode support to this component"
|
|
120
|
+
✅ "Refactor this component to use a different state pattern"
|
|
24
121
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
122
|
+
DO NOT use this tool for:
|
|
123
|
+
❌ Creating new files → use create_frontend
|
|
124
|
+
❌ Generating isolated snippets → use snippet_frontend
|
|
28
125
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
126
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
127
|
+
⚠️ REQUIRED BEFORE CALLING
|
|
128
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
129
|
+
|
|
130
|
+
1. READ THE EXISTING FILE FIRST
|
|
131
|
+
You MUST read the file's current content before calling this tool.
|
|
132
|
+
Pass the complete file content as existingCode parameter.
|
|
133
|
+
|
|
134
|
+
2. UNDERSTAND THE MODIFICATION
|
|
135
|
+
Be specific about what to change. Vague requests = vague results.
|
|
136
|
+
Good: "Add a red delete button in the top-right corner of each card"
|
|
137
|
+
Bad: "Make it better"
|
|
138
|
+
|
|
139
|
+
3. GATHER RELATED CONTEXT (if needed)
|
|
140
|
+
If the modification needs to match patterns from other files,
|
|
141
|
+
pass those files as the context parameter.
|
|
35
142
|
|
|
36
143
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
37
|
-
|
|
144
|
+
🔧 HOW IT WORKS
|
|
38
145
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
39
146
|
|
|
40
|
-
|
|
147
|
+
Gemini will:
|
|
148
|
+
- Analyze the existing code structure and patterns
|
|
149
|
+
- Apply the requested modification surgically
|
|
150
|
+
- Preserve the existing design language (colors, spacing, typography)
|
|
151
|
+
- Maintain all unrelated functionality
|
|
152
|
+
- Add new imports only if needed
|
|
153
|
+
- Return the COMPLETE modified file
|
|
41
154
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
• 🌙 "Dark & Techy" - Dark mode, neon accents, developer aesthetic
|
|
46
|
-
• 🌿 "Calm & Minimal" - Zen, whitespace, soft tones
|
|
47
|
-
• 🚀 "Bold & Modern" - Gradients, geometric shapes, striking
|
|
155
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
156
|
+
📤 OUTPUT
|
|
157
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
48
158
|
|
|
49
|
-
|
|
159
|
+
Returns the COMPLETE modified file:
|
|
160
|
+
- Ready to replace the original file entirely
|
|
161
|
+
- All imports preserved + new ones added
|
|
162
|
+
- Same file structure and exports
|
|
163
|
+
- Modification applied with premium quality`, modifyFrontendSchema, modifyFrontend);
|
|
164
|
+
// =============================================================================
|
|
165
|
+
// TOOL 3: SNIPPET_FRONTEND
|
|
166
|
+
// =============================================================================
|
|
167
|
+
server.tool("snippet_frontend", `Generate a code SNIPPET to INSERT into an existing file.
|
|
50
168
|
|
|
51
|
-
|
|
169
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
170
|
+
🎯 WHEN TO USE THIS TOOL
|
|
171
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
172
|
+
|
|
173
|
+
Use this tool when you need to ADD something to an existing file:
|
|
174
|
+
✅ "Add a sidebar to this dashboard" (snippet to insert)
|
|
175
|
+
✅ "Generate a data table component to add here"
|
|
176
|
+
✅ "Create a custom hook for API calls"
|
|
177
|
+
✅ "Add a modal component inside this page"
|
|
178
|
+
✅ "Generate a form section to add after the header"
|
|
52
179
|
|
|
53
|
-
|
|
180
|
+
DO NOT use this tool for:
|
|
181
|
+
❌ Creating complete new files → use create_frontend
|
|
182
|
+
❌ Modifying existing code → use modify_frontend
|
|
54
183
|
|
|
55
184
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
56
|
-
|
|
185
|
+
💡 KEY DIFFERENCE FROM OTHER TOOLS
|
|
57
186
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
58
187
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
188
|
+
| Tool | Input | Output |
|
|
189
|
+
|------------------|--------------------------|----------------------------|
|
|
190
|
+
| create_frontend | What to create | Complete new file |
|
|
191
|
+
| modify_frontend | Existing code + changes | Complete modified file |
|
|
192
|
+
| snippet_frontend | Insertion context | Code snippet to insert |
|
|
193
|
+
|
|
194
|
+
snippet_frontend is for when you want to INSERT new code into an existing file
|
|
195
|
+
without having Gemini rewrite the entire file.
|
|
196
|
+
|
|
197
|
+
Example flow:
|
|
198
|
+
1. User: "Add a sidebar to my dashboard"
|
|
199
|
+
2. You read Dashboard.tsx
|
|
200
|
+
3. You call snippet_frontend with insertion context
|
|
201
|
+
4. Gemini returns just the sidebar code
|
|
202
|
+
5. You insert it at the right location in Dashboard.tsx
|
|
203
|
+
|
|
204
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
205
|
+
⚠️ REQUIRED: INSERTION CONTEXT
|
|
206
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
207
|
+
|
|
208
|
+
The insertionContext parameter is CRITICAL. It tells Gemini:
|
|
209
|
+
- WHERE the snippet will be inserted
|
|
210
|
+
- WHAT code surrounds it
|
|
211
|
+
- WHAT patterns to match
|
|
212
|
+
|
|
213
|
+
Good insertionContext example:
|
|
214
|
+
"Inside the Dashboard component's return statement, after the <Header />
|
|
215
|
+
component. The file uses Tailwind CSS with a dark theme (zinc-900 background,
|
|
216
|
+
zinc-100 text). State is managed with useState hooks. The existing components
|
|
217
|
+
use rounded-xl borders and p-6 padding."
|
|
218
|
+
|
|
219
|
+
Bad insertionContext example:
|
|
220
|
+
"In the dashboard file"
|
|
221
|
+
|
|
222
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
223
|
+
📤 OUTPUT FORMAT
|
|
224
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
225
|
+
|
|
226
|
+
Returns a snippet with this structure (if new imports needed):
|
|
227
|
+
|
|
228
|
+
// NEW IMPORTS NEEDED:
|
|
229
|
+
import { useState } from "react";
|
|
230
|
+
import { Dialog } from "@headlessui/react";
|
|
231
|
+
|
|
232
|
+
// SNIPPET:
|
|
233
|
+
<Sidebar className="...">
|
|
234
|
+
...
|
|
235
|
+
</Sidebar>
|
|
236
|
+
|
|
237
|
+
Or just the snippet if no new imports are needed.
|
|
62
238
|
|
|
63
|
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
//
|
|
239
|
+
You (the agent) are responsible for:
|
|
240
|
+
- Merging new imports with existing imports
|
|
241
|
+
- Inserting the snippet at the correct location
|
|
242
|
+
- Ensuring the file still compiles after insertion`, snippetFrontendSchema, snippetFrontend);
|
|
243
|
+
// =============================================================================
|
|
244
|
+
// START SERVER
|
|
245
|
+
// =============================================================================
|
|
68
246
|
async function main() {
|
|
69
247
|
const transport = new StdioServerTransport();
|
|
70
248
|
await server.connect(transport);
|
|
71
|
-
console.error("gemini-design-mcp
|
|
249
|
+
console.error("gemini-design-mcp v3.0.0 running on stdio");
|
|
72
250
|
}
|
|
73
251
|
main().catch((error) => {
|
|
74
252
|
console.error("Fatal error:", error);
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const CREATE_FRONTEND_PROMPT = "You are an elite UI/UX Designer creating production-ready, visually stunning interfaces.\n\nYOUR TASK: Create a COMPLETE, NEW frontend file.\n\nDESIGN EXCELLENCE REQUIREMENTS:\n\n1. **MAXIMUM DETAIL AND DENSITY**\n - The interface MUST be densely populated and feature-rich\n - NEVER produce simple wireframes, empty containers, or placeholder content\n - Fill the space with intricate details, realistic content, background elements, and meaningful UI components\n - Every section should feel like a fully finished, polished product\n\n2. **PREMIUM VISUAL STYLING**\n - Apply high-end design principles throughout\n - Use sophisticated styling: nuanced shadows, subtle gradients, refined borders, micro-textures\n - Add depth and dimension with layered elements\n - The aesthetic MUST feel modern, premium, and visually captivating\n - Use professional color palettes with proper contrast and hierarchy\n\n3. **COMPREHENSIVE INTERACTIVITY**\n - Design every element to look tangible and interactive\n - Include visual states: hover effects, focus rings, active states, transitions\n - Buttons should look clickable, inputs should look fillable\n - The interface should feel alive, not static\n\n4. **LAYOUT EXCELLENCE**\n - Use proper visual hierarchy with clear focal points\n - Apply consistent spacing rhythm throughout\n - Ensure the layout breathes - balance density with whitespace\n - Full viewport height designs (min-height: 100vh on body)\n - No awkward gaps or orphaned elements\n\n5. **RESPONSIVE BY DEFAULT**\n - Designs MUST work flawlessly on mobile and desktop\n - Touch-friendly sizing for interactive elements on mobile\n - Stackable grids that adapt naturally to screen size\n\n6. **REALISTIC CONTENT**\n - Use believable placeholder content (real-looking names, dates, numbers)\n - Include appropriate icons, avatars, and imagery\n - Data visualizations should have realistic data points\n - Text should be contextually appropriate, not \"Lorem ipsum\"\n\nOUTPUT REQUIREMENTS:\n- Return a COMPLETE file with all necessary imports at the top\n- Include proper exports (default or named as appropriate)\n- The code must be ready to use as-is, no modifications needed\n- Follow the tech stack conventions exactly\n- Return ONLY the code, no explanations or markdown fences";
|
|
2
|
+
export declare const MODIFY_FRONTEND_PROMPT = "You are an elite UI/UX Designer modifying existing frontend code.\n\nYOUR TASK: Modify the provided code according to the user's request while maintaining design excellence.\n\nMODIFICATION PRINCIPLES:\n\n1. **PRESERVE EXISTING DESIGN LANGUAGE**\n - Maintain the existing color palette, typography, and spacing\n - Keep the visual consistency with the rest of the file\n - Don't introduce jarring style changes unless explicitly asked\n\n2. **ENHANCE, DON'T BREAK**\n - Your modifications should improve or extend, not degrade\n - Maintain all existing functionality unless asked to remove it\n - Keep the same code patterns and conventions used in the file\n\n3. **SURGICAL PRECISION**\n - Only change what needs to be changed\n - Don't refactor unrelated parts of the code\n - Preserve imports that are still needed, add new ones as required\n\n4. **QUALITY STANDARD**\n - New elements must match the premium quality of existing code\n - Apply the same level of visual polish to new additions\n - Ensure new interactive elements have proper states (hover, focus, etc.)\n\n5. **STRUCTURAL INTEGRITY**\n - Maintain proper component structure\n - Keep props/state management patterns consistent\n - Ensure the file remains properly typed (if TypeScript)\n\nOUTPUT REQUIREMENTS:\n- Return the COMPLETE modified file (not just the changes)\n- Include ALL original imports plus any new ones needed\n- Maintain the original file structure and export pattern\n- The code must be ready to replace the original file\n- Return ONLY the code, no explanations or markdown fences";
|
|
3
|
+
export declare const SNIPPET_FRONTEND_PROMPT = "You are an elite UI/UX Designer generating a code snippet.\n\nYOUR TASK: Generate a focused code snippet that will be INSERTED into an existing file.\n\nSNIPPET PRINCIPLES:\n\n1. **CONTEXTUAL AWARENESS**\n - The snippet will be inserted into an existing codebase\n - Match the style and patterns described in the context\n - Use consistent naming conventions with the project\n\n2. **SELF-CONTAINED BUT INTEGRABLE**\n - The snippet should work when inserted\n - Include only the imports that are NEW (the agent will merge them)\n - Don't include file-level exports unless specifically asked\n\n3. **PREMIUM QUALITY**\n - Even snippets must have premium visual styling\n - Include hover states, transitions, proper spacing\n - Use realistic placeholder content, not Lorem ipsum\n\n4. **CLEAN BOUNDARIES**\n - Clear start and end of the snippet\n - Proper indentation (assume standard 2-space indent)\n - No trailing commas or syntax that would break insertion\n\n5. **FOCUSED SCOPE**\n - Generate exactly what was asked, nothing more\n - Don't add \"nice to have\" features unless requested\n - Keep the snippet as lean as possible while meeting requirements\n\nOUTPUT REQUIREMENTS:\n- Return ONLY the code snippet\n- If new imports are needed, list them at the very top, clearly separated\n- The snippet should be ready to paste/insert\n- Match the tech stack and patterns from context\n- Return ONLY the code, no explanations or markdown fences\n\nFORMAT (if imports needed):\n// NEW IMPORTS NEEDED:\nimport { X } from \"y\";\n\n// SNIPPET:\n<your code here>";
|
package/build/prompts/system.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// CREATE_FRONTEND PROMPT
|
|
3
|
+
// Used for creating NEW complete files (pages, components, sections)
|
|
4
|
+
// =============================================================================
|
|
5
|
+
export const CREATE_FRONTEND_PROMPT = `You are an elite UI/UX Designer creating production-ready, visually stunning interfaces.
|
|
6
|
+
|
|
7
|
+
YOUR TASK: Create a COMPLETE, NEW frontend file.
|
|
2
8
|
|
|
3
9
|
DESIGN EXCELLENCE REQUIREMENTS:
|
|
4
10
|
|
|
@@ -39,9 +45,98 @@ DESIGN EXCELLENCE REQUIREMENTS:
|
|
|
39
45
|
- Data visualizations should have realistic data points
|
|
40
46
|
- Text should be contextually appropriate, not "Lorem ipsum"
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
- Return COMPLETE
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
48
|
+
OUTPUT REQUIREMENTS:
|
|
49
|
+
- Return a COMPLETE file with all necessary imports at the top
|
|
50
|
+
- Include proper exports (default or named as appropriate)
|
|
51
|
+
- The code must be ready to use as-is, no modifications needed
|
|
52
|
+
- Follow the tech stack conventions exactly
|
|
53
|
+
- Return ONLY the code, no explanations or markdown fences`;
|
|
54
|
+
// =============================================================================
|
|
55
|
+
// MODIFY_FRONTEND PROMPT
|
|
56
|
+
// Used for modifying EXISTING files while preserving design quality
|
|
57
|
+
// =============================================================================
|
|
58
|
+
export const MODIFY_FRONTEND_PROMPT = `You are an elite UI/UX Designer modifying existing frontend code.
|
|
59
|
+
|
|
60
|
+
YOUR TASK: Modify the provided code according to the user's request while maintaining design excellence.
|
|
61
|
+
|
|
62
|
+
MODIFICATION PRINCIPLES:
|
|
63
|
+
|
|
64
|
+
1. **PRESERVE EXISTING DESIGN LANGUAGE**
|
|
65
|
+
- Maintain the existing color palette, typography, and spacing
|
|
66
|
+
- Keep the visual consistency with the rest of the file
|
|
67
|
+
- Don't introduce jarring style changes unless explicitly asked
|
|
68
|
+
|
|
69
|
+
2. **ENHANCE, DON'T BREAK**
|
|
70
|
+
- Your modifications should improve or extend, not degrade
|
|
71
|
+
- Maintain all existing functionality unless asked to remove it
|
|
72
|
+
- Keep the same code patterns and conventions used in the file
|
|
73
|
+
|
|
74
|
+
3. **SURGICAL PRECISION**
|
|
75
|
+
- Only change what needs to be changed
|
|
76
|
+
- Don't refactor unrelated parts of the code
|
|
77
|
+
- Preserve imports that are still needed, add new ones as required
|
|
78
|
+
|
|
79
|
+
4. **QUALITY STANDARD**
|
|
80
|
+
- New elements must match the premium quality of existing code
|
|
81
|
+
- Apply the same level of visual polish to new additions
|
|
82
|
+
- Ensure new interactive elements have proper states (hover, focus, etc.)
|
|
83
|
+
|
|
84
|
+
5. **STRUCTURAL INTEGRITY**
|
|
85
|
+
- Maintain proper component structure
|
|
86
|
+
- Keep props/state management patterns consistent
|
|
87
|
+
- Ensure the file remains properly typed (if TypeScript)
|
|
88
|
+
|
|
89
|
+
OUTPUT REQUIREMENTS:
|
|
90
|
+
- Return the COMPLETE modified file (not just the changes)
|
|
91
|
+
- Include ALL original imports plus any new ones needed
|
|
92
|
+
- Maintain the original file structure and export pattern
|
|
93
|
+
- The code must be ready to replace the original file
|
|
47
94
|
- Return ONLY the code, no explanations or markdown fences`;
|
|
95
|
+
// =============================================================================
|
|
96
|
+
// SNIPPET_FRONTEND PROMPT
|
|
97
|
+
// Used for generating code snippets to INSERT into existing files
|
|
98
|
+
// =============================================================================
|
|
99
|
+
export const SNIPPET_FRONTEND_PROMPT = `You are an elite UI/UX Designer generating a code snippet.
|
|
100
|
+
|
|
101
|
+
YOUR TASK: Generate a focused code snippet that will be INSERTED into an existing file.
|
|
102
|
+
|
|
103
|
+
SNIPPET PRINCIPLES:
|
|
104
|
+
|
|
105
|
+
1. **CONTEXTUAL AWARENESS**
|
|
106
|
+
- The snippet will be inserted into an existing codebase
|
|
107
|
+
- Match the style and patterns described in the context
|
|
108
|
+
- Use consistent naming conventions with the project
|
|
109
|
+
|
|
110
|
+
2. **SELF-CONTAINED BUT INTEGRABLE**
|
|
111
|
+
- The snippet should work when inserted
|
|
112
|
+
- Include only the imports that are NEW (the agent will merge them)
|
|
113
|
+
- Don't include file-level exports unless specifically asked
|
|
114
|
+
|
|
115
|
+
3. **PREMIUM QUALITY**
|
|
116
|
+
- Even snippets must have premium visual styling
|
|
117
|
+
- Include hover states, transitions, proper spacing
|
|
118
|
+
- Use realistic placeholder content, not Lorem ipsum
|
|
119
|
+
|
|
120
|
+
4. **CLEAN BOUNDARIES**
|
|
121
|
+
- Clear start and end of the snippet
|
|
122
|
+
- Proper indentation (assume standard 2-space indent)
|
|
123
|
+
- No trailing commas or syntax that would break insertion
|
|
124
|
+
|
|
125
|
+
5. **FOCUSED SCOPE**
|
|
126
|
+
- Generate exactly what was asked, nothing more
|
|
127
|
+
- Don't add "nice to have" features unless requested
|
|
128
|
+
- Keep the snippet as lean as possible while meeting requirements
|
|
129
|
+
|
|
130
|
+
OUTPUT REQUIREMENTS:
|
|
131
|
+
- Return ONLY the code snippet
|
|
132
|
+
- If new imports are needed, list them at the very top, clearly separated
|
|
133
|
+
- The snippet should be ready to paste/insert
|
|
134
|
+
- Match the tech stack and patterns from context
|
|
135
|
+
- Return ONLY the code, no explanations or markdown fences
|
|
136
|
+
|
|
137
|
+
FORMAT (if imports needed):
|
|
138
|
+
// NEW IMPORTS NEEDED:
|
|
139
|
+
import { X } from "y";
|
|
140
|
+
|
|
141
|
+
// SNIPPET:
|
|
142
|
+
<your code here>`;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const createFrontendSchema: {
|
|
3
3
|
request: z.ZodString;
|
|
4
|
+
filePath: z.ZodString;
|
|
5
|
+
techStack: z.ZodString;
|
|
4
6
|
context: z.ZodNullable<z.ZodString>;
|
|
5
|
-
techStack: z.ZodOptional<z.ZodString>;
|
|
6
7
|
designSystem: z.ZodOptional<z.ZodObject<{
|
|
7
|
-
|
|
8
|
-
vibe: z.ZodOptional<z.ZodObject<{
|
|
8
|
+
vibe: z.ZodObject<{
|
|
9
9
|
name: z.ZodString;
|
|
10
10
|
description: z.ZodString;
|
|
11
11
|
keywords: z.ZodArray<z.ZodString, "many">;
|
|
@@ -17,30 +17,28 @@ export declare const generateFrontendSchema: {
|
|
|
17
17
|
name: string;
|
|
18
18
|
description: string;
|
|
19
19
|
keywords: string[];
|
|
20
|
-
}
|
|
20
|
+
}>;
|
|
21
21
|
}, "strip", z.ZodTypeAny, {
|
|
22
|
-
|
|
23
|
-
vibe?: {
|
|
22
|
+
vibe: {
|
|
24
23
|
name: string;
|
|
25
24
|
description: string;
|
|
26
25
|
keywords: string[];
|
|
27
|
-
}
|
|
26
|
+
};
|
|
28
27
|
}, {
|
|
29
|
-
|
|
30
|
-
vibe?: {
|
|
28
|
+
vibe: {
|
|
31
29
|
name: string;
|
|
32
30
|
description: string;
|
|
33
31
|
keywords: string[];
|
|
34
|
-
}
|
|
32
|
+
};
|
|
35
33
|
}>>;
|
|
36
34
|
};
|
|
37
|
-
export declare function
|
|
35
|
+
export declare function createFrontend(params: {
|
|
38
36
|
request: string;
|
|
37
|
+
filePath: string;
|
|
38
|
+
techStack: string;
|
|
39
39
|
context: string | null;
|
|
40
|
-
techStack?: string;
|
|
41
40
|
designSystem?: {
|
|
42
|
-
|
|
43
|
-
vibe?: {
|
|
41
|
+
vibe: {
|
|
44
42
|
name: string;
|
|
45
43
|
description: string;
|
|
46
44
|
keywords: string[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { generateWithGemini } from "../lib/gemini.js";
|
|
3
|
+
import { CREATE_FRONTEND_PROMPT } from "../prompts/system.js";
|
|
4
|
+
export const createFrontendSchema = {
|
|
5
|
+
request: z.string().describe("What to create: describe the page, component, or section. " +
|
|
6
|
+
"Be specific about functionality and content. " +
|
|
7
|
+
"Example: 'A pricing page with 3 tiers (Basic, Pro, Enterprise) with feature comparison table'"),
|
|
8
|
+
filePath: z.string().describe("The path where this file will be created. " +
|
|
9
|
+
"Example: 'src/components/PricingPage.tsx' or 'app/dashboard/page.tsx'"),
|
|
10
|
+
techStack: z.string().describe("The tech stack to use. Be specific. " +
|
|
11
|
+
"Examples: 'React + TypeScript + Tailwind CSS', 'Next.js 14 App Router + shadcn/ui', 'Vue 3 + Composition API + CSS Modules'"),
|
|
12
|
+
context: z.string().nullable().describe("Existing project code for design consistency. " +
|
|
13
|
+
"Pass relevant files (components, styles, theme config) so Gemini matches your design system. " +
|
|
14
|
+
"Null only if this is the FIRST file in a new project."),
|
|
15
|
+
designSystem: z.object({
|
|
16
|
+
vibe: z.object({
|
|
17
|
+
name: z.string().describe("Vibe name (e.g., 'Pristine Museum', 'Dark Luxe')"),
|
|
18
|
+
description: z.string().describe("Rich, evocative description of the mood (2-3 sentences)"),
|
|
19
|
+
keywords: z.array(z.string()).describe("Style keywords (e.g., ['minimal', 'whitespace', 'gallery'])"),
|
|
20
|
+
}).describe("The selected design vibe"),
|
|
21
|
+
}).optional().describe("Design system with selected vibe. REQUIRED for new projects without existing design. " +
|
|
22
|
+
"The calling agent generates 5 vibe options, user selects, then pass the selection here."),
|
|
23
|
+
};
|
|
24
|
+
export async function createFrontend(params) {
|
|
25
|
+
const { request, filePath, techStack, context, designSystem } = params;
|
|
26
|
+
// Build design system instructions if provided
|
|
27
|
+
let designSystemInstructions = '';
|
|
28
|
+
if (designSystem?.vibe) {
|
|
29
|
+
const { vibe } = designSystem;
|
|
30
|
+
designSystemInstructions = `
|
|
31
|
+
MANDATORY DESIGN SYSTEM (User Selected Vibe):
|
|
32
|
+
|
|
33
|
+
**Design Vibe: "${vibe.name}"**
|
|
34
|
+
${vibe.description}
|
|
35
|
+
|
|
36
|
+
Keywords to embody: ${vibe.keywords.join(', ')}
|
|
37
|
+
|
|
38
|
+
Interpret this vibe creatively:
|
|
39
|
+
- Choose colors, gradients, and visual styling that embody this atmosphere
|
|
40
|
+
- Select a font from Google Fonts that perfectly matches this vibe
|
|
41
|
+
- Apply consistent visual language throughout the entire interface
|
|
42
|
+
- You have freedom in the specific implementation, but the overall feel MUST match this vibe
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
// Build context instructions
|
|
46
|
+
let contextInstructions = '';
|
|
47
|
+
if (context) {
|
|
48
|
+
contextInstructions = `
|
|
49
|
+
EXISTING PROJECT CONTEXT (match this design system):
|
|
50
|
+
${context}
|
|
51
|
+
|
|
52
|
+
IMPORTANT: Analyze the existing code carefully and match:
|
|
53
|
+
- Color palette and theme
|
|
54
|
+
- Typography and font choices
|
|
55
|
+
- Component patterns and naming conventions
|
|
56
|
+
- Spacing and layout rhythms
|
|
57
|
+
- Import patterns and file structure
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
const systemPrompt = `${CREATE_FRONTEND_PROMPT}
|
|
61
|
+
${designSystemInstructions}
|
|
62
|
+
${contextInstructions}
|
|
63
|
+
TECH STACK: ${techStack}
|
|
64
|
+
FILE PATH: ${filePath}
|
|
65
|
+
|
|
66
|
+
Remember: Return a COMPLETE file ready to save at ${filePath}`.trim();
|
|
67
|
+
const result = await generateWithGemini(systemPrompt, request);
|
|
68
|
+
return {
|
|
69
|
+
content: [{ type: "text", text: result }],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const modifyFrontendSchema: {
|
|
3
|
+
request: z.ZodString;
|
|
4
|
+
filePath: z.ZodString;
|
|
5
|
+
existingCode: z.ZodString;
|
|
6
|
+
context: z.ZodOptional<z.ZodString>;
|
|
7
|
+
};
|
|
8
|
+
export declare function modifyFrontend(params: {
|
|
9
|
+
request: string;
|
|
10
|
+
filePath: string;
|
|
11
|
+
existingCode: string;
|
|
12
|
+
context?: string;
|
|
13
|
+
}): Promise<{
|
|
14
|
+
content: {
|
|
15
|
+
type: "text";
|
|
16
|
+
text: string;
|
|
17
|
+
}[];
|
|
18
|
+
}>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { generateWithGemini } from "../lib/gemini.js";
|
|
3
|
+
import { MODIFY_FRONTEND_PROMPT } from "../prompts/system.js";
|
|
4
|
+
export const modifyFrontendSchema = {
|
|
5
|
+
request: z.string().describe("What modification to make. Be specific and clear. " +
|
|
6
|
+
"Examples: " +
|
|
7
|
+
"'Add a delete button with confirmation modal to each card', " +
|
|
8
|
+
"'Change the color scheme from blue to purple', " +
|
|
9
|
+
"'Add loading and error states to this component', " +
|
|
10
|
+
"'Make the sidebar collapsible with animation'"),
|
|
11
|
+
filePath: z.string().describe("The path of the file being modified. " +
|
|
12
|
+
"Example: 'src/components/Sidebar.tsx'"),
|
|
13
|
+
existingCode: z.string().describe("The COMPLETE current content of the file to modify. " +
|
|
14
|
+
"Pass the entire file, not just a snippet. " +
|
|
15
|
+
"Gemini will return the complete modified file."),
|
|
16
|
+
context: z.string().optional().describe("Additional project context if needed for the modification. " +
|
|
17
|
+
"Pass related files if the modification needs to match patterns from elsewhere. " +
|
|
18
|
+
"Optional - only include if relevant to the modification."),
|
|
19
|
+
};
|
|
20
|
+
export async function modifyFrontend(params) {
|
|
21
|
+
const { request, filePath, existingCode, context } = params;
|
|
22
|
+
// Build context instructions
|
|
23
|
+
let contextInstructions = '';
|
|
24
|
+
if (context) {
|
|
25
|
+
contextInstructions = `
|
|
26
|
+
ADDITIONAL PROJECT CONTEXT (for reference):
|
|
27
|
+
${context}
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
30
|
+
const systemPrompt = `${MODIFY_FRONTEND_PROMPT}
|
|
31
|
+
${contextInstructions}
|
|
32
|
+
FILE BEING MODIFIED: ${filePath}
|
|
33
|
+
|
|
34
|
+
EXISTING CODE TO MODIFY:
|
|
35
|
+
\`\`\`
|
|
36
|
+
${existingCode}
|
|
37
|
+
\`\`\`
|
|
38
|
+
|
|
39
|
+
MODIFICATION REQUESTED: ${request}
|
|
40
|
+
|
|
41
|
+
Remember: Return the COMPLETE modified file, ready to replace the original.`.trim();
|
|
42
|
+
const result = await generateWithGemini(systemPrompt, request);
|
|
43
|
+
return {
|
|
44
|
+
content: [{ type: "text", text: result }],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const snippetFrontendSchema: {
|
|
3
|
+
request: z.ZodString;
|
|
4
|
+
targetFile: z.ZodString;
|
|
5
|
+
techStack: z.ZodString;
|
|
6
|
+
insertionContext: z.ZodString;
|
|
7
|
+
context: z.ZodOptional<z.ZodString>;
|
|
8
|
+
};
|
|
9
|
+
export declare function snippetFrontend(params: {
|
|
10
|
+
request: string;
|
|
11
|
+
targetFile: string;
|
|
12
|
+
techStack: string;
|
|
13
|
+
insertionContext: string;
|
|
14
|
+
context?: string;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
content: {
|
|
17
|
+
type: "text";
|
|
18
|
+
text: string;
|
|
19
|
+
}[];
|
|
20
|
+
}>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { generateWithGemini } from "../lib/gemini.js";
|
|
3
|
+
import { SNIPPET_FRONTEND_PROMPT } from "../prompts/system.js";
|
|
4
|
+
export const snippetFrontendSchema = {
|
|
5
|
+
request: z.string().describe("What code snippet to generate. Be specific about what you need. " +
|
|
6
|
+
"Examples: " +
|
|
7
|
+
"'A sidebar component with navigation links and user profile section', " +
|
|
8
|
+
"'A data table with sorting, filtering, and pagination', " +
|
|
9
|
+
"'A form validation function for email and password', " +
|
|
10
|
+
"'A custom hook for handling API requests with loading/error states'"),
|
|
11
|
+
targetFile: z.string().describe("The file where this snippet will be inserted. " +
|
|
12
|
+
"Example: 'src/components/Dashboard.tsx' - helps Gemini match the file's patterns"),
|
|
13
|
+
techStack: z.string().describe("The tech stack being used. " +
|
|
14
|
+
"Examples: 'React + TypeScript + Tailwind CSS', 'Vue 3 + Composition API'"),
|
|
15
|
+
insertionContext: z.string().describe("WHERE in the file this snippet will go and surrounding code context. " +
|
|
16
|
+
"This helps Gemini generate code that integrates smoothly. " +
|
|
17
|
+
"Example: 'Inside the Dashboard component, after the header section. " +
|
|
18
|
+
"The file uses useState for state and has a dark theme with zinc colors.'"),
|
|
19
|
+
context: z.string().optional().describe("Additional project files for design/pattern reference. " +
|
|
20
|
+
"Pass components, styles, or utilities that the snippet should match. " +
|
|
21
|
+
"Optional but recommended for consistency."),
|
|
22
|
+
};
|
|
23
|
+
export async function snippetFrontend(params) {
|
|
24
|
+
const { request, targetFile, techStack, insertionContext, context } = params;
|
|
25
|
+
// Build context instructions
|
|
26
|
+
let contextInstructions = '';
|
|
27
|
+
if (context) {
|
|
28
|
+
contextInstructions = `
|
|
29
|
+
PROJECT CONTEXT (match these patterns):
|
|
30
|
+
${context}
|
|
31
|
+
`;
|
|
32
|
+
}
|
|
33
|
+
const systemPrompt = `${SNIPPET_FRONTEND_PROMPT}
|
|
34
|
+
${contextInstructions}
|
|
35
|
+
TECH STACK: ${techStack}
|
|
36
|
+
TARGET FILE: ${targetFile}
|
|
37
|
+
|
|
38
|
+
INSERTION CONTEXT:
|
|
39
|
+
${insertionContext}
|
|
40
|
+
|
|
41
|
+
Generate a snippet that will integrate smoothly at this location.`.trim();
|
|
42
|
+
const result = await generateWithGemini(systemPrompt, request);
|
|
43
|
+
return {
|
|
44
|
+
content: [{ type: "text", text: result }],
|
|
45
|
+
};
|
|
46
|
+
}
|
package/package.json
CHANGED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { generateWithGemini } from "../lib/gemini.js";
|
|
3
|
-
import { GENERATE_FRONTEND_PROMPT } from "../prompts/system.js";
|
|
4
|
-
export const generateFrontendSchema = {
|
|
5
|
-
request: z.string().describe("Description of what to create (component, page, section, etc.)"),
|
|
6
|
-
context: z.string().nullable().describe("Existing project code for reference (components, styles, config). " +
|
|
7
|
-
"Send relevant files to ensure design consistency. " +
|
|
8
|
-
"Null if new project."),
|
|
9
|
-
techStack: z.string().optional().describe("Tech stack (e.g., 'React + Tailwind', 'Vue + CSS', 'HTML/CSS vanilla', 'Next.js + shadcn'). " +
|
|
10
|
-
"If not specified, Gemini will choose based on context."),
|
|
11
|
-
designSystem: z.object({
|
|
12
|
-
font: z.string().optional().describe("Google Font name to use as primary font"),
|
|
13
|
-
vibe: z.object({
|
|
14
|
-
name: z.string().describe("Vibe name (e.g., 'Corporate & Professional')"),
|
|
15
|
-
description: z.string().describe("Mood description (e.g., 'Clean lines, trustworthy feel')"),
|
|
16
|
-
keywords: z.array(z.string()).describe("Style keywords (e.g., ['minimal', 'corporate'])"),
|
|
17
|
-
}).optional().describe("Selected design vibe"),
|
|
18
|
-
}).optional().describe("Design system selection. The calling agent generates vibe options, " +
|
|
19
|
-
"user selects, then pass the selection here for consistent styling."),
|
|
20
|
-
};
|
|
21
|
-
export async function generateFrontend(params) {
|
|
22
|
-
const { request, context, techStack, designSystem } = params;
|
|
23
|
-
// Build design system instructions if provided
|
|
24
|
-
let designSystemInstructions = '';
|
|
25
|
-
if (designSystem?.font || designSystem?.vibe) {
|
|
26
|
-
const { font, vibe } = designSystem;
|
|
27
|
-
const fontInstructions = font
|
|
28
|
-
? `- **Font**: Use "${font}" from Google Fonts as the primary font family. Import it in the <head> or via CSS.`
|
|
29
|
-
: '';
|
|
30
|
-
const vibeInstructions = vibe
|
|
31
|
-
? `- **Design Vibe** "${vibe.name}":
|
|
32
|
-
Mood: ${vibe.description}
|
|
33
|
-
Keywords: ${vibe.keywords.join(', ')}
|
|
34
|
-
|
|
35
|
-
Interpret this vibe creatively - choose colors, gradients, and visual styling that embody this atmosphere. You have freedom in the specific colors, but the overall feel must match this vibe.`
|
|
36
|
-
: '';
|
|
37
|
-
designSystemInstructions = `
|
|
38
|
-
MANDATORY DESIGN SYSTEM (User Selected):
|
|
39
|
-
${fontInstructions}
|
|
40
|
-
${vibeInstructions}
|
|
41
|
-
|
|
42
|
-
Apply this design system consistently throughout the entire interface.
|
|
43
|
-
`;
|
|
44
|
-
}
|
|
45
|
-
const systemPrompt = `${GENERATE_FRONTEND_PROMPT}
|
|
46
|
-
${designSystemInstructions}
|
|
47
|
-
${techStack ? `TECH STACK: ${techStack}` : ""}`.trim();
|
|
48
|
-
const userPrompt = context
|
|
49
|
-
? `PROJECT CONTEXT (match this style):
|
|
50
|
-
${context}
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
REQUEST:
|
|
55
|
-
${request}`
|
|
56
|
-
: request;
|
|
57
|
-
const result = await generateWithGemini(systemPrompt, userPrompt);
|
|
58
|
-
return {
|
|
59
|
-
content: [{ type: "text", text: result }],
|
|
60
|
-
};
|
|
61
|
-
}
|