gemini-design-mcp 3.12.1 → 3.12.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/prompts/system.js
CHANGED
|
@@ -613,6 +613,64 @@ Si un design system est fourni dans le context, tu DOIS :
|
|
|
613
613
|
- Si un élément n'existe pas dans le design system, le créer en utilisant UNIQUEMENT les tokens définis
|
|
614
614
|
`;
|
|
615
615
|
|
|
616
|
+
// =============================================================================
|
|
617
|
+
// GENERATE VIBES PAGE PROMPT
|
|
618
|
+
// Generates a visual page with 5 sections for the user to see and select
|
|
619
|
+
// =============================================================================
|
|
620
|
+
export const GENERATE_VIBES_PAGE_PROMPT = `Tu génères une page React/HTML complète avec 5 sections visuelles pour permettre à l'utilisateur de choisir son design préféré.
|
|
621
|
+
|
|
622
|
+
ÉTAPE 1: Analyse le projet et génère 5 VIBES UNIQUES adaptées
|
|
623
|
+
- Chaque vibe doit avoir un nom créatif et une direction esthétique claire
|
|
624
|
+
- Les 5 vibes doivent être TRÈS différentes les unes des autres
|
|
625
|
+
- Adapte les vibes au type de projet et à l'audience
|
|
626
|
+
- Exemples de directions: Luxe/Minimal, Brutalist/Raw, Playful/Colorful, Corporate/Trust, Dark/Techy, Editorial, Y2K Revival, etc.
|
|
627
|
+
|
|
628
|
+
ÉTAPE 2: Génère une page avec 5 sections identiques (même structure) mais stylées différemment
|
|
629
|
+
|
|
630
|
+
STRUCTURE DE CHAQUE SECTION (identique pour les 5):
|
|
631
|
+
- Un label bien visible "Vibe #X: [Nom créatif de la vibe]" en haut
|
|
632
|
+
- Hero heading: "Transform Your Workflow"
|
|
633
|
+
- Subheading: "The modern platform for teams who want to move faster"
|
|
634
|
+
- CTA button: "Get Started"
|
|
635
|
+
- 3 feature cards en grille avec:
|
|
636
|
+
- Titre: "Lightning Fast" / "Secure by Design" / "Team Collaboration"
|
|
637
|
+
- Description courte pour chaque
|
|
638
|
+
- Séparateur visuel clair entre sections (ligne, espace, ou changement de fond)
|
|
639
|
+
|
|
640
|
+
RÈGLES CRITIQUES:
|
|
641
|
+
1. Marquer CHAQUE section avec des commentaires HTML:
|
|
642
|
+
<!-- VIBE_1_START -->
|
|
643
|
+
... tout le code de la section 1 ...
|
|
644
|
+
<!-- VIBE_1_END -->
|
|
645
|
+
|
|
646
|
+
<!-- VIBE_2_START -->
|
|
647
|
+
... tout le code de la section 2 ...
|
|
648
|
+
<!-- VIBE_2_END -->
|
|
649
|
+
|
|
650
|
+
(et ainsi de suite jusqu'à VIBE_5)
|
|
651
|
+
|
|
652
|
+
2. CHAQUE section doit être COMPLÈTE et auto-suffisante:
|
|
653
|
+
- Tous les styles Tailwind inline
|
|
654
|
+
- Extractible telle quelle sans modification
|
|
655
|
+
- Pas de dépendances sur d'autres sections
|
|
656
|
+
|
|
657
|
+
3. Le MÊME contenu texte pour les 5 sections:
|
|
658
|
+
- "Transform Your Workflow"
|
|
659
|
+
- "The modern platform for teams who want to move faster"
|
|
660
|
+
- Mêmes titres de features
|
|
661
|
+
- SEUL LE STYLE CHANGE
|
|
662
|
+
|
|
663
|
+
4. Styles TRÈS différents entre les sections:
|
|
664
|
+
- Couleurs de fond différentes
|
|
665
|
+
- Typographie différente (tailles, poids)
|
|
666
|
+
- Spacing différent
|
|
667
|
+
- Border-radius différent
|
|
668
|
+
- Effets différents (shadows, gradients, etc.)
|
|
669
|
+
|
|
670
|
+
5. Inclure TOUTES les classes Tailwind inline - AUCUNE variable externe, AUCUN CSS custom
|
|
671
|
+
|
|
672
|
+
OUTPUT: Une page React/HTML complète et fonctionnelle avec les 5 sections bien marquées. Le code doit être prêt à être sauvegardé et ouvert dans un navigateur.`;
|
|
673
|
+
|
|
616
674
|
export const SNIPPET_FRONTEND_PROMPT = `You are an elite UI/UX Designer generating a code snippet to INSERT.
|
|
617
675
|
|
|
618
676
|
YOUR TASK: Generate a focused code snippet that will be INSERTED into an existing file.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { generateWithGemini } from "../lib/gemini.js";
|
|
3
|
-
import { CREATE_FRONTEND_PROMPT, DESIGN_SYSTEM_GENERATION_PROMPT } from "../prompts/system.js";
|
|
4
|
-
import { stripCodeFences, parseGeminiResponseWithDesignSystem } from "../lib/filesystem.js";
|
|
3
|
+
import { CREATE_FRONTEND_PROMPT, DESIGN_SYSTEM_GENERATION_PROMPT, DESIGN_SYSTEM_USAGE_INSTRUCTIONS } from "../prompts/system.js";
|
|
4
|
+
import { stripCodeFences, parseGeminiResponseWithDesignSystem, loadDesignSystemIfExists } from "../lib/filesystem.js";
|
|
5
5
|
import { scaleSchema, scaleDescriptions } from "../lib/scale.js";
|
|
6
6
|
export const createFrontendSchema = {
|
|
7
7
|
request: z.string().describe("What to create: describe the page, component, or section. " +
|
|
@@ -29,9 +29,17 @@ export const createFrontendSchema = {
|
|
|
29
29
|
"Activer UNIQUEMENT pour la PREMIÈRE page du projet. " +
|
|
30
30
|
"Le design system sera retourné séparément pour être sauvegardé dans design-system.md"
|
|
31
31
|
),
|
|
32
|
+
projectRoot: z.string().optional().describe(
|
|
33
|
+
"Root directory du projet. Utilisé pour auto-charger design-system.md s'il existe. " +
|
|
34
|
+
"TOUJOURS passer ce paramètre pour que Gemini utilise le design system existant."
|
|
35
|
+
),
|
|
32
36
|
};
|
|
33
37
|
export async function createFrontend(params) {
|
|
34
|
-
const { request, filePath, techStack, context, designSystem, generateDesignSystem } = params;
|
|
38
|
+
const { request, filePath, techStack, context, designSystem, generateDesignSystem, projectRoot } = params;
|
|
39
|
+
|
|
40
|
+
// Auto-load design system if exists
|
|
41
|
+
const autoDesignSystem = loadDesignSystemIfExists(projectRoot);
|
|
42
|
+
|
|
35
43
|
// Build design system instructions if provided
|
|
36
44
|
let designSystemInstructions = '';
|
|
37
45
|
if (designSystem?.vibe) {
|
|
@@ -51,9 +59,22 @@ Interpret this vibe creatively — choose colors, typography, and styling that e
|
|
|
51
59
|
The scale above is MANDATORY and defines how large or small UI elements should be.
|
|
52
60
|
`;
|
|
53
61
|
}
|
|
54
|
-
// Build context instructions
|
|
62
|
+
// Build context instructions - prioritize auto-loaded design system
|
|
55
63
|
let contextInstructions = '';
|
|
56
|
-
|
|
64
|
+
let designSystemRules = '';
|
|
65
|
+
|
|
66
|
+
if (autoDesignSystem) {
|
|
67
|
+
contextInstructions = `
|
|
68
|
+
## DESIGN SYSTEM COMPLET (COPIER EXACTEMENT - TOUT LE CODE):
|
|
69
|
+
|
|
70
|
+
${autoDesignSystem}
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
RÈGLE CRITIQUE: Copier EXACTEMENT les classes Tailwind, couleurs, spacing, border-radius du code ci-dessus.
|
|
74
|
+
NE JAMAIS inventer de nouvelles valeurs. Le nouveau composant doit ressembler EXACTEMENT au design system.
|
|
75
|
+
`;
|
|
76
|
+
designSystemRules = DESIGN_SYSTEM_USAGE_INSTRUCTIONS;
|
|
77
|
+
} else if (context && context !== "null" && context.trim() !== "") {
|
|
57
78
|
contextInstructions = `
|
|
58
79
|
EXISTING PROJECT CONTEXT (match this design system):
|
|
59
80
|
${context}
|
|
@@ -82,6 +103,7 @@ FILE PATH: ${filePath}
|
|
|
82
103
|
RAPPEL CRITIQUE: Tu DOIS utiliser le format avec les markers <!-- CODE_START/END --> et <!-- DESIGN_SYSTEM_START/END -->. Ne retourne JAMAIS juste le code.`.trim();
|
|
83
104
|
} else {
|
|
84
105
|
systemPrompt = `${CREATE_FRONTEND_PROMPT}
|
|
106
|
+
${designSystemRules}
|
|
85
107
|
${designSystemInstructions}
|
|
86
108
|
${contextInstructions}
|
|
87
109
|
TECH STACK: ${techStack}
|
|
@@ -1,42 +1,23 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { generateWithGemini } from "../lib/gemini.js";
|
|
3
|
+
import { GENERATE_VIBES_PAGE_PROMPT } from "../prompts/system.js";
|
|
4
|
+
import { stripCodeFences } from "../lib/filesystem.js";
|
|
5
|
+
|
|
3
6
|
export const generateVibesSchema = {
|
|
4
|
-
projectDescription: z.string().describe("
|
|
5
|
-
"
|
|
6
|
-
projectType: z.string().optional().describe("Type
|
|
7
|
-
"
|
|
8
|
-
targetAudience: z.string().optional().describe("
|
|
9
|
-
"
|
|
7
|
+
projectDescription: z.string().describe("Description du projet. " +
|
|
8
|
+
"Exemple: 'Un dashboard SaaS pour gérer les tickets de support client'"),
|
|
9
|
+
projectType: z.string().optional().describe("Type de projet. " +
|
|
10
|
+
"Exemples: 'landing page', 'dashboard', 'e-commerce', 'portfolio', 'blog', 'mobile app'"),
|
|
11
|
+
targetAudience: z.string().optional().describe("Audience cible. " +
|
|
12
|
+
"Exemples: 'developers', 'enterprise clients', 'young consumers', 'creative professionals'"),
|
|
13
|
+
techStack: z.string().optional().describe("Tech stack pour la page de vibes. " +
|
|
14
|
+
"Default: 'React + TypeScript + Tailwind CSS'. " +
|
|
15
|
+
"Exemples: 'Next.js + Tailwind', 'Vue 3 + Tailwind', 'HTML + Tailwind'"),
|
|
10
16
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
Each vibe should represent a unique visual direction and feeling.
|
|
14
|
-
Describe the mood, not specific colors - let the designer interpret creatively.
|
|
15
|
-
Think: "Corporate & Trustworthy" vs "Playful & Vibrant" vs "Dark & Techy"
|
|
16
|
-
|
|
17
|
-
IMPORTANT - Each vibe MUST include a SCALE recommendation:
|
|
18
|
-
- "zoomed" = Large elements, big buttons, big text, full-width cards (e.g., kids apps, accessibility-focused)
|
|
19
|
-
- "refined" = Subtle scale, smaller typography, contained elements, elegant proportions (e.g., luxury, Linear.app, Raycast)
|
|
20
|
-
- "balanced" = Standard scale, middle ground
|
|
21
|
-
|
|
22
|
-
The scale is NOT about density (dense vs sparse), it's about the SIZE of elements.
|
|
23
|
-
A luxury watch e-commerce site has refined/small scale. A kids learning platform has zoomed/large scale.
|
|
24
|
-
|
|
25
|
-
OUTPUT FORMAT (JSON):
|
|
26
|
-
Return ONLY a valid JSON array with exactly 5 vibes. No markdown, no explanation.
|
|
27
|
-
|
|
28
|
-
[
|
|
29
|
-
{
|
|
30
|
-
"emoji": "🏛️",
|
|
31
|
-
"name": "Vibe Name",
|
|
32
|
-
"description": "2-3 sentences describing the mood and atmosphere.",
|
|
33
|
-
"scale": "refined" | "balanced" | "zoomed",
|
|
34
|
-
"keywords": ["keyword1", "keyword2", "keyword3"]
|
|
35
|
-
}
|
|
36
|
-
]`;
|
|
17
|
+
|
|
37
18
|
export async function generateVibes(params) {
|
|
38
|
-
const { projectDescription, projectType, targetAudience } = params;
|
|
39
|
-
|
|
19
|
+
const { projectDescription, projectType, targetAudience, techStack } = params;
|
|
20
|
+
|
|
40
21
|
let contextParts = [`Project: ${projectDescription}`];
|
|
41
22
|
if (projectType) {
|
|
42
23
|
contextParts.push(`Type: ${projectType}`);
|
|
@@ -44,57 +25,59 @@ export async function generateVibes(params) {
|
|
|
44
25
|
if (targetAudience) {
|
|
45
26
|
contextParts.push(`Target Audience: ${targetAudience}`);
|
|
46
27
|
}
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
28
|
+
|
|
29
|
+
const userPrompt = `${contextParts.join("\n")}
|
|
30
|
+
Tech Stack: ${techStack || "React + TypeScript + Tailwind CSS"}
|
|
31
|
+
|
|
32
|
+
Génère 5 vibes DIFFÉRENTES et ADAPTÉES à ce projet spécifique.
|
|
33
|
+
Puis génère la page complète avec 5 sections, une pour chaque vibe.
|
|
34
|
+
Chaque section doit montrer visuellement le style de la vibe.`;
|
|
35
|
+
|
|
36
|
+
const result = await generateWithGemini(
|
|
37
|
+
GENERATE_VIBES_PAGE_PROMPT,
|
|
38
|
+
userPrompt,
|
|
39
|
+
undefined,
|
|
40
|
+
"high",
|
|
41
|
+
"generate_vibes"
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const code = stripCodeFences(result);
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
content: [{
|
|
48
|
+
type: "text",
|
|
49
|
+
text: `VIBES_PAGE_CODE:
|
|
50
|
+
|
|
51
|
+
${code}
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
INSTRUCTIONS POUR L'AGENT:
|
|
56
|
+
1. Demande à l'utilisateur: "Tu n'as pas de design system. Je peux créer vibes-selection.tsx pour que tu choisisses visuellement ton style préféré?"
|
|
57
|
+
2. Si oui → Écris ce code dans le fichier (vibes-selection.tsx ou vibes-selection.html selon le projet)
|
|
58
|
+
3. Dis à l'utilisateur d'ouvrir la page et de choisir (ex: "vibe 3" ou "la deuxième")
|
|
59
|
+
4. Quand l'utilisateur a choisi, extrais le code entre <!-- VIBE_X_START --> et <!-- VIBE_X_END -->
|
|
60
|
+
5. Sauvegarde CE CODE ENTIER (pas un résumé) dans design-system.md à la racine du projet
|
|
61
|
+
6. Demande si tu dois supprimer vibes-selection.tsx
|
|
62
|
+
|
|
63
|
+
FORMAT DU design-system.md:
|
|
64
|
+
\`\`\`markdown
|
|
65
|
+
# Design System - [Nom du Projet]
|
|
66
|
+
|
|
67
|
+
## Vibe Sélectionnée: [Nom de la vibe choisie]
|
|
68
|
+
|
|
69
|
+
## Code de Référence (COPIER EXACTEMENT)
|
|
70
|
+
|
|
71
|
+
[Coller ici TOUT le code extrait entre les markers VIBE_X_START et VIBE_X_END]
|
|
72
|
+
|
|
73
|
+
## Instructions d'utilisation
|
|
74
|
+
|
|
75
|
+
Pour tous les composants frontend:
|
|
76
|
+
- Copier EXACTEMENT les classes Tailwind de ce code de référence
|
|
77
|
+
- Utiliser les mêmes couleurs, spacing, border-radius
|
|
78
|
+
- Maintenir la même direction esthétique
|
|
79
|
+
\`\`\`
|
|
80
|
+
`
|
|
81
|
+
}]
|
|
82
|
+
};
|
|
100
83
|
}
|
|
@@ -31,12 +31,18 @@ export async function modifyFrontend(params) {
|
|
|
31
31
|
let contextInstructions = '';
|
|
32
32
|
if (autoDesignSystem) {
|
|
33
33
|
contextInstructions = `
|
|
34
|
-
##
|
|
34
|
+
## DESIGN SYSTEM COMPLET (COPIER EXACTEMENT - NE RIEN MODIFIER):
|
|
35
35
|
|
|
36
36
|
${autoDesignSystem}
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
40
|
+
RÈGLES CRITIQUES:
|
|
41
|
+
- Copier EXACTEMENT les classes Tailwind du design system ci-dessus
|
|
42
|
+
- NE JAMAIS inventer de nouvelles couleurs, paddings, ou border-radius
|
|
43
|
+
- Utiliser les mêmes patterns visuels (shadows, transitions, etc.)
|
|
44
|
+
- Le code modifié doit être INDISTINGUABLE du reste du projet
|
|
45
|
+
|
|
40
46
|
`;
|
|
41
47
|
}
|
|
42
48
|
if (context) {
|
|
@@ -34,12 +34,18 @@ export async function snippetFrontend(params) {
|
|
|
34
34
|
let contextInstructions = '';
|
|
35
35
|
if (autoDesignSystem) {
|
|
36
36
|
contextInstructions = `
|
|
37
|
-
##
|
|
37
|
+
## DESIGN SYSTEM COMPLET (COPIER EXACTEMENT - NE RIEN MODIFIER):
|
|
38
38
|
|
|
39
39
|
${autoDesignSystem}
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
43
|
+
RÈGLES CRITIQUES:
|
|
44
|
+
- Copier EXACTEMENT les classes Tailwind du design system ci-dessus
|
|
45
|
+
- NE JAMAIS inventer de nouvelles couleurs, paddings, ou border-radius
|
|
46
|
+
- Utiliser les mêmes patterns visuels (shadows, transitions, etc.)
|
|
47
|
+
- Le snippet doit être INDISTINGUABLE du reste du projet
|
|
48
|
+
|
|
43
49
|
`;
|
|
44
50
|
}
|
|
45
51
|
if (context) {
|