vibetachyon 1.9.0 → 2.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/dist/mcp-server.js +192 -14
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -47,8 +47,142 @@ async function checkSanity() {
|
|
|
47
47
|
throw new Error(`[VIBETACHYON SANITY TRAP] Execution blocked. Agent exceeded ${CALL_LIMIT_PER_SESSION} tool calls in a single session. This prevents infinite loops or excessive API usage. Please restart the CLI if this was intentional.`);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
+
// --- Style Palettes — real CSS values per preset ─────────────────────────
|
|
51
|
+
const STYLE_PALETTES = {
|
|
52
|
+
linear: {
|
|
53
|
+
'--background': '#0a0a0f',
|
|
54
|
+
'--foreground': '#f4f4f5',
|
|
55
|
+
'--primary': '#6366f1',
|
|
56
|
+
'--primary-fg': '#ffffff',
|
|
57
|
+
'--muted': '#1c1c28',
|
|
58
|
+
'--muted-fg': '#8585a8',
|
|
59
|
+
'--border': 'rgba(255,255,255,0.08)',
|
|
60
|
+
'--card': '#111120',
|
|
61
|
+
'--radius': '8px',
|
|
62
|
+
'--font': "'Inter', system-ui, sans-serif",
|
|
63
|
+
'--gradient': 'linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)',
|
|
64
|
+
'--shadow': '0 1px 3px rgba(0,0,0,0.4)',
|
|
65
|
+
},
|
|
66
|
+
vercel: {
|
|
67
|
+
'--background': '#000000',
|
|
68
|
+
'--foreground': '#ffffff',
|
|
69
|
+
'--primary': '#ffffff',
|
|
70
|
+
'--primary-fg': '#000000',
|
|
71
|
+
'--muted': '#111111',
|
|
72
|
+
'--muted-fg': '#888888',
|
|
73
|
+
'--border': '#333333',
|
|
74
|
+
'--card': '#0a0a0a',
|
|
75
|
+
'--radius': '4px',
|
|
76
|
+
'--font': "'Geist', 'Inter', system-ui, sans-serif",
|
|
77
|
+
'--gradient': 'none',
|
|
78
|
+
'--shadow': '0 0 0 1px #333',
|
|
79
|
+
},
|
|
80
|
+
stripe: {
|
|
81
|
+
'--background': '#ffffff',
|
|
82
|
+
'--foreground': '#0a2540',
|
|
83
|
+
'--primary': '#635bff',
|
|
84
|
+
'--primary-fg': '#ffffff',
|
|
85
|
+
'--muted': '#f6f9fc',
|
|
86
|
+
'--muted-fg': '#425466',
|
|
87
|
+
'--border': '#e3e8ee',
|
|
88
|
+
'--card': '#ffffff',
|
|
89
|
+
'--radius': '6px',
|
|
90
|
+
'--font': "'Sohne', 'Inter', system-ui, sans-serif",
|
|
91
|
+
'--gradient': 'linear-gradient(135deg, #635bff 0%, #0a2540 100%)',
|
|
92
|
+
'--shadow': '0 2px 8px rgba(0,0,0,0.08)',
|
|
93
|
+
},
|
|
94
|
+
notion: {
|
|
95
|
+
'--background': '#ffffff',
|
|
96
|
+
'--foreground': '#37352f',
|
|
97
|
+
'--primary': '#2eaadc',
|
|
98
|
+
'--primary-fg': '#ffffff',
|
|
99
|
+
'--muted': '#f7f6f3',
|
|
100
|
+
'--muted-fg': '#9b9a97',
|
|
101
|
+
'--border': '#e9e9e7',
|
|
102
|
+
'--card': '#ffffff',
|
|
103
|
+
'--radius': '3px',
|
|
104
|
+
'--font': "'ui-sans-serif', 'Inter', system-ui, sans-serif",
|
|
105
|
+
'--gradient': 'none',
|
|
106
|
+
'--shadow': '0 1px 3px rgba(0,0,0,0.07)',
|
|
107
|
+
},
|
|
108
|
+
apple: {
|
|
109
|
+
'--background': '#f5f5f7',
|
|
110
|
+
'--foreground': '#1d1d1f',
|
|
111
|
+
'--primary': '#0066cc',
|
|
112
|
+
'--primary-fg': '#ffffff',
|
|
113
|
+
'--muted': '#e8e8ed',
|
|
114
|
+
'--muted-fg': '#6e6e73',
|
|
115
|
+
'--border': 'rgba(0,0,0,0.1)',
|
|
116
|
+
'--card': '#ffffff',
|
|
117
|
+
'--radius': '12px',
|
|
118
|
+
'--font': "'-apple-system', 'SF Pro Display', 'Inter', sans-serif",
|
|
119
|
+
'--gradient': 'linear-gradient(180deg, #f5f5f7 0%, #e8e8ed 100%)',
|
|
120
|
+
'--shadow': '0 4px 20px rgba(0,0,0,0.08)',
|
|
121
|
+
},
|
|
122
|
+
'bold-dark': {
|
|
123
|
+
'--background': '#060b18',
|
|
124
|
+
'--foreground': '#e2e8f0',
|
|
125
|
+
'--primary': '#06b6d4',
|
|
126
|
+
'--primary-fg': '#000000',
|
|
127
|
+
'--muted': '#0f1d2e',
|
|
128
|
+
'--muted-fg': '#94a3b8',
|
|
129
|
+
'--border': 'rgba(6,182,212,0.15)',
|
|
130
|
+
'--card': '#0d1a2e',
|
|
131
|
+
'--radius': '10px',
|
|
132
|
+
'--font': "'Inter', system-ui, sans-serif",
|
|
133
|
+
'--gradient': 'linear-gradient(135deg, #06b6d4 0%, #3b82f6 100%)',
|
|
134
|
+
'--shadow': '0 4px 24px rgba(6,182,212,0.15)',
|
|
135
|
+
},
|
|
136
|
+
agency: {
|
|
137
|
+
'--background': '#0f0f0f',
|
|
138
|
+
'--foreground': '#ffffff',
|
|
139
|
+
'--primary': '#ff6b35',
|
|
140
|
+
'--primary-fg': '#ffffff',
|
|
141
|
+
'--muted': '#1a1a1a',
|
|
142
|
+
'--muted-fg': '#999999',
|
|
143
|
+
'--border': 'rgba(255,107,53,0.2)',
|
|
144
|
+
'--card': '#1a1a1a',
|
|
145
|
+
'--radius': '2px',
|
|
146
|
+
'--font': "'Space Grotesk', 'Inter', system-ui, sans-serif",
|
|
147
|
+
'--gradient': 'linear-gradient(135deg, #ff6b35 0%, #f7c59f 100%)',
|
|
148
|
+
'--shadow': '0 4px 20px rgba(255,107,53,0.2)',
|
|
149
|
+
},
|
|
150
|
+
aceternity: {
|
|
151
|
+
'--background': '#000000',
|
|
152
|
+
'--foreground': '#ffffff',
|
|
153
|
+
'--primary': '#a855f7',
|
|
154
|
+
'--primary-fg': '#ffffff',
|
|
155
|
+
'--muted': '#0a0a0a',
|
|
156
|
+
'--muted-fg': '#71717a',
|
|
157
|
+
'--border': 'rgba(168,85,247,0.2)',
|
|
158
|
+
'--card': '#0a0a0a',
|
|
159
|
+
'--radius': '16px',
|
|
160
|
+
'--font': "'Inter', system-ui, sans-serif",
|
|
161
|
+
'--gradient': 'linear-gradient(135deg, #a855f7 0%, #6366f1 50%, #ec4899 100%)',
|
|
162
|
+
'--shadow': '0 0 40px rgba(168,85,247,0.25)',
|
|
163
|
+
},
|
|
164
|
+
custom: {
|
|
165
|
+
'--background': 'var(--background, #ffffff)',
|
|
166
|
+
'--foreground': 'var(--foreground, #000000)',
|
|
167
|
+
'--primary': 'var(--primary, #3b82f6)',
|
|
168
|
+
'--primary-fg': 'var(--primary-fg, #ffffff)',
|
|
169
|
+
'--muted': 'var(--muted, #f4f4f5)',
|
|
170
|
+
'--muted-fg': 'var(--muted-fg, #71717a)',
|
|
171
|
+
'--border': 'var(--border, #e4e4e7)',
|
|
172
|
+
'--card': 'var(--card, #ffffff)',
|
|
173
|
+
'--radius': 'var(--radius, 8px)',
|
|
174
|
+
'--font': "var(--font-sans, 'Inter', sans-serif)",
|
|
175
|
+
'--gradient': 'none',
|
|
176
|
+
'--shadow': '0 1px 3px rgba(0,0,0,0.1)',
|
|
177
|
+
},
|
|
178
|
+
};
|
|
50
179
|
// --- Changelog (per version) ---
|
|
51
180
|
const CHANGELOG = {
|
|
181
|
+
'2.0.0': [
|
|
182
|
+
'8 presets visuais reais: linear, vercel, stripe, bold-dark, agency...',
|
|
183
|
+
'Paletas CSS aplicadas automaticamente — sem mais neon hardcoded',
|
|
184
|
+
'vibe_compose_landing_page lê o brief e injeta cores corretas',
|
|
185
|
+
],
|
|
52
186
|
'1.9.0': [
|
|
53
187
|
'vibe_clone_design — clone design system de qualquer URL',
|
|
54
188
|
'Detecta cores, tipografia, radius e sombras automaticamente',
|
|
@@ -203,7 +337,7 @@ async function validateTokenAtStartup() {
|
|
|
203
337
|
}
|
|
204
338
|
// --- Update Check ---
|
|
205
339
|
try {
|
|
206
|
-
const CURRENT_VERSION = '
|
|
340
|
+
const CURRENT_VERSION = '2.0.0'; // keep in sync with package.json
|
|
207
341
|
const npmRes = await fetch('https://registry.npmjs.org/vibetachyon/latest', {
|
|
208
342
|
signal: AbortSignal.timeout(4000)
|
|
209
343
|
});
|
|
@@ -232,7 +366,7 @@ async function startMcpServer() {
|
|
|
232
366
|
await validateTokenAtStartup();
|
|
233
367
|
const server = new mcp_js_1.McpServer({
|
|
234
368
|
name: "VibeTachyon MCP — Animmaster Engine",
|
|
235
|
-
version: "
|
|
369
|
+
version: "2.0.0"
|
|
236
370
|
});
|
|
237
371
|
/**
|
|
238
372
|
* VIBETACHYON FRONTEND PERSONA — Senior Frontend Designer (Animmaster Engine)
|
|
@@ -981,7 +1115,7 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
981
1115
|
niche: zod_1.z.string().describe("What is the product niche? e.g. 'B2B SaaS fintech', 'developer tool', 'e-commerce fashion'"),
|
|
982
1116
|
targetAudience: zod_1.z.string().describe("Who is the target user? e.g. 'CTO of early-stage startup', 'solo developer', 'non-technical founder'"),
|
|
983
1117
|
styleWords: zod_1.z.array(zod_1.z.string()).describe("3 adjectives that describe the desired visual style. e.g. ['clean', 'modern', 'trustworthy'] or ['bold', 'dark', 'animated']"),
|
|
984
|
-
referenceStyle: zod_1.z.enum(['linear', 'vercel', 'stripe', 'aceternity', 'apple', 'notion', 'custom']).describe("
|
|
1118
|
+
referenceStyle: zod_1.z.enum(['linear', 'vercel', 'stripe', 'aceternity', 'apple', 'notion', 'bold-dark', 'agency', 'custom']).describe("Visual preset: 'linear'=dark minimal indigo, 'vercel'=black/white terminal, 'stripe'=light professional, 'notion'=clean editorial, 'apple'=light cinematic, 'bold-dark'=dark navy cyan, 'agency'=dark orange dramatic, 'aceternity'=dark glowing purple, 'custom'=use project CSS vars"),
|
|
985
1119
|
sectionsNeeded: zod_1.z.array(zod_1.z.string()).describe("Which page sections are needed in order. e.g. ['hero', 'features', 'social-proof', 'pricing', 'faq', 'cta']")
|
|
986
1120
|
}, async ({ projectDir, pageGoal, niche, targetAudience, styleWords, referenceStyle, sectionsNeeded }) => {
|
|
987
1121
|
await checkSanity();
|
|
@@ -1064,6 +1198,10 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
1064
1198
|
if (sectionsNeeded.includes('pricing') && !sectionsNeeded.includes('social-proof') && !sectionsNeeded.includes('testimonials')) {
|
|
1065
1199
|
sectionWarnings.push('⚠️ Pricing without social proof reduces trust — consider adding testimonials before pricing.');
|
|
1066
1200
|
}
|
|
1201
|
+
const palette = STYLE_PALETTES[referenceStyle] || STYLE_PALETTES.custom;
|
|
1202
|
+
const paletteCSS = Object.entries(palette)
|
|
1203
|
+
.map(([k, v]) => ` ${k}: ${v};`)
|
|
1204
|
+
.join('\n');
|
|
1067
1205
|
const brief = {
|
|
1068
1206
|
createdAt: new Date().toISOString(),
|
|
1069
1207
|
pageGoal,
|
|
@@ -1072,6 +1210,8 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
1072
1210
|
styleWords,
|
|
1073
1211
|
referenceStyle,
|
|
1074
1212
|
sectionsNeeded,
|
|
1213
|
+
palette,
|
|
1214
|
+
paletteCSS: `:root {\n${paletteCSS}\n}`,
|
|
1075
1215
|
styleProfile: profile,
|
|
1076
1216
|
rules: {
|
|
1077
1217
|
maxAnimationTypes: profile.animationLevel === 'heavy' ? 3 : profile.animationLevel === 'subtle' ? 2 : 0,
|
|
@@ -1117,14 +1257,17 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
1117
1257
|
`DESIGN RULES:\n${rulesText}\n\n` +
|
|
1118
1258
|
`SECTION SEQUENCE:\n${sectionsText}` +
|
|
1119
1259
|
`${warningsText}\n\n` +
|
|
1260
|
+
`COLOR PALETTE (USE THESE EXACT VALUES — NO EXCEPTIONS):\n` +
|
|
1261
|
+
`\`\`\`css\n${brief.paletteCSS}\n\`\`\`\n\n` +
|
|
1120
1262
|
`INSTRUCTION FOR AI — CRITICAL RULES FOR THIS SESSION:\n` +
|
|
1121
|
-
`1.
|
|
1122
|
-
`2.
|
|
1123
|
-
`3.
|
|
1124
|
-
`4.
|
|
1125
|
-
`5.
|
|
1126
|
-
`6.
|
|
1127
|
-
`7.
|
|
1263
|
+
`1. ALWAYS inject the CSS palette above as the FIRST thing inside <style> when generating HTML\n` +
|
|
1264
|
+
`2. NEVER hardcode colors like #7c3aed, #a855f7, #ec4899 — use ONLY the CSS vars above\n` +
|
|
1265
|
+
`3. Every component you choose MUST match the "${referenceStyle}" reference style\n` +
|
|
1266
|
+
`4. Visual tone is "${profile.tone}" — ${profile.tone === 'dark' ? 'dark backgrounds, light text' : profile.tone === 'light' ? 'light backgrounds, dark text' : 'adapt to project'}\n` +
|
|
1267
|
+
`5. MAXIMUM ${brief.rules.maxAnimationTypes} different animation styles on the entire page\n` +
|
|
1268
|
+
`6. NEVER use these: ${profile.avoid.join(', ')}\n` +
|
|
1269
|
+
`7. Build sections in this EXACT order: ${sectionsNeeded.join(' → ')}\n` +
|
|
1270
|
+
`8. If a component does NOT match this brief, REJECT it and search again`
|
|
1128
1271
|
}]
|
|
1129
1272
|
};
|
|
1130
1273
|
});
|
|
@@ -1566,11 +1709,39 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
1566
1709
|
}
|
|
1567
1710
|
});
|
|
1568
1711
|
// Tool: Compose Landing Page
|
|
1569
|
-
server.tool("vibe_compose_landing_page", "Macro-composer that autonomously queries the VibeCodes RAG database for a full Landing Page structure (Navbar, Hero, Features, Pricing, Footer).", {
|
|
1570
|
-
themeOrIndustry: zod_1.z.string().describe("The theme, industry, or style of the page (e.g., 'SaaS Finance
|
|
1571
|
-
|
|
1712
|
+
server.tool("vibe_compose_landing_page", "Macro-composer that autonomously queries the VibeCodes RAG database for a full Landing Page structure (Navbar, Hero, Features, Pricing, Footer). ALWAYS call vibe_design_brief first — this tool reads the saved brief to apply the correct color palette.", {
|
|
1713
|
+
themeOrIndustry: zod_1.z.string().describe("The theme, industry, or style of the page (e.g., 'SaaS Finance', 'Dental Clinic', 'Developer Tool')"),
|
|
1714
|
+
projectDir: zod_1.z.string().optional().describe("Absolute path to the project root. Used to read the design brief.")
|
|
1715
|
+
}, async ({ themeOrIndustry, projectDir }) => {
|
|
1572
1716
|
await checkSanity();
|
|
1573
1717
|
try {
|
|
1718
|
+
// Read design brief for palette injection
|
|
1719
|
+
let paletteCSS = '';
|
|
1720
|
+
let briefStyle = 'linear';
|
|
1721
|
+
let briefTone = 'dark';
|
|
1722
|
+
let briefAvoid = [];
|
|
1723
|
+
const cwd = projectDir || process.cwd();
|
|
1724
|
+
const root = await findProjectRoot(cwd);
|
|
1725
|
+
const briefPath = path_1.default.join(root, '.vibetachyon', 'design-session.json');
|
|
1726
|
+
if (await fs_extra_1.default.pathExists(briefPath)) {
|
|
1727
|
+
try {
|
|
1728
|
+
const brief = await fs_extra_1.default.readJson(briefPath);
|
|
1729
|
+
if (brief.paletteCSS)
|
|
1730
|
+
paletteCSS = brief.paletteCSS;
|
|
1731
|
+
if (brief.referenceStyle)
|
|
1732
|
+
briefStyle = brief.referenceStyle;
|
|
1733
|
+
if (brief.styleProfile?.tone)
|
|
1734
|
+
briefTone = brief.styleProfile.tone;
|
|
1735
|
+
if (brief.rules?.mustAvoid)
|
|
1736
|
+
briefAvoid = brief.rules.mustAvoid;
|
|
1737
|
+
}
|
|
1738
|
+
catch { /* use defaults */ }
|
|
1739
|
+
}
|
|
1740
|
+
// Fallback: use linear palette if no brief
|
|
1741
|
+
if (!paletteCSS) {
|
|
1742
|
+
const fallbackPalette = STYLE_PALETTES[briefStyle] || STYLE_PALETTES.linear;
|
|
1743
|
+
paletteCSS = `:root {\n${Object.entries(fallbackPalette).map(([k, v]) => ` ${k}: ${v};`).join('\n')}\n}`;
|
|
1744
|
+
}
|
|
1574
1745
|
// Map sections to Animmaster use cases and search terms
|
|
1575
1746
|
const sectionMap = [
|
|
1576
1747
|
{ section: 'preloader', query: 'preloader', useCase: 'preloader' },
|
|
@@ -1580,7 +1751,14 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
1580
1751
|
{ section: 'features', query: 'features section', useCase: 'feature-section' },
|
|
1581
1752
|
{ section: 'footer', query: 'footer', useCase: 'footer' }
|
|
1582
1753
|
];
|
|
1583
|
-
let combinedPage = `[🎬 ANIMMASTER PAGE COMPOSER: ${themeOrIndustry}]\n
|
|
1754
|
+
let combinedPage = `[🎬 ANIMMASTER PAGE COMPOSER: ${themeOrIndustry}]\n`;
|
|
1755
|
+
combinedPage += `Style: ${briefStyle} | Tone: ${briefTone}\n\n`;
|
|
1756
|
+
combinedPage += `⚠️ MANDATORY COLOR RULES — INJECT THIS PALETTE FIRST IN <style>:\n\`\`\`css\n${paletteCSS}\n\`\`\`\n\n`;
|
|
1757
|
+
combinedPage += `CRITICAL: Use ONLY var(--background), var(--primary), var(--foreground), var(--border), var(--card) etc.\n`;
|
|
1758
|
+
combinedPage += `NEVER hardcode hex colors. NEVER use purple/neon unless --primary IS purple in the palette above.\n`;
|
|
1759
|
+
if (briefAvoid.length > 0)
|
|
1760
|
+
combinedPage += `AVOID: ${briefAvoid.join(', ')}\n`;
|
|
1761
|
+
combinedPage += `\nINSTRUCTION FOR AI: Assemble a complete page using Animmaster components in init_order sequence.\n\n`;
|
|
1584
1762
|
const allComponents = [];
|
|
1585
1763
|
for (const { section, query, useCase } of sectionMap) {
|
|
1586
1764
|
const { data } = await supabase
|