vibetachyon 2.0.0 → 2.1.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 +69 -4
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -178,6 +178,12 @@ const STYLE_PALETTES = {
|
|
|
178
178
|
};
|
|
179
179
|
// --- Changelog (per version) ---
|
|
180
180
|
const CHANGELOG = {
|
|
181
|
+
'2.1.0': [
|
|
182
|
+
'Fix: vibe_compose_landing_page detecta framework (Next.js/Vite) automaticamente',
|
|
183
|
+
'Fix: output sempre .tsx React, nunca index.html',
|
|
184
|
+
'Instruções explícitas de conversão HTML→JSX (class→className, useEffect)',
|
|
185
|
+
'Detecta src/app vs app para outputTarget correto',
|
|
186
|
+
],
|
|
181
187
|
'2.0.0': [
|
|
182
188
|
'8 presets visuais reais: linear, vercel, stripe, bold-dark, agency...',
|
|
183
189
|
'Paletas CSS aplicadas automaticamente — sem mais neon hardcoded',
|
|
@@ -1709,7 +1715,7 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
1709
1715
|
}
|
|
1710
1716
|
});
|
|
1711
1717
|
// Tool: Compose Landing Page
|
|
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.", {
|
|
1718
|
+
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. OUTPUT: Always generates Next.js TSX React components (never index.html). For Next.js projects, saves to src/app/page.tsx or app/page.tsx. Convert all HTML templates to JSX (class→className, style={{}} etc).", {
|
|
1713
1719
|
themeOrIndustry: zod_1.z.string().describe("The theme, industry, or style of the page (e.g., 'SaaS Finance', 'Dental Clinic', 'Developer Tool')"),
|
|
1714
1720
|
projectDir: zod_1.z.string().optional().describe("Absolute path to the project root. Used to read the design brief.")
|
|
1715
1721
|
}, async ({ themeOrIndustry, projectDir }) => {
|
|
@@ -1722,6 +1728,36 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
1722
1728
|
let briefAvoid = [];
|
|
1723
1729
|
const cwd = projectDir || process.cwd();
|
|
1724
1730
|
const root = await findProjectRoot(cwd);
|
|
1731
|
+
// Detect framework for output instructions
|
|
1732
|
+
let framework = 'unknown';
|
|
1733
|
+
let outputTarget = '';
|
|
1734
|
+
const pkgPath = path_1.default.join(root, 'package.json');
|
|
1735
|
+
if (await fs_extra_1.default.pathExists(pkgPath)) {
|
|
1736
|
+
try {
|
|
1737
|
+
const pkg = await fs_extra_1.default.readJson(pkgPath);
|
|
1738
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
1739
|
+
if (deps['next']) {
|
|
1740
|
+
framework = 'nextjs';
|
|
1741
|
+
const hasAppSrc = await fs_extra_1.default.pathExists(path_1.default.join(root, 'src', 'app'));
|
|
1742
|
+
const hasApp = await fs_extra_1.default.pathExists(path_1.default.join(root, 'app'));
|
|
1743
|
+
if (hasAppSrc)
|
|
1744
|
+
outputTarget = 'src/app/page.tsx';
|
|
1745
|
+
else if (hasApp)
|
|
1746
|
+
outputTarget = 'app/page.tsx';
|
|
1747
|
+
else
|
|
1748
|
+
outputTarget = 'src/app/page.tsx';
|
|
1749
|
+
}
|
|
1750
|
+
else if (deps['vite'] || deps['react']) {
|
|
1751
|
+
framework = 'vite';
|
|
1752
|
+
outputTarget = 'src/App.tsx';
|
|
1753
|
+
}
|
|
1754
|
+
else if (deps['nuxt']) {
|
|
1755
|
+
framework = 'nuxt';
|
|
1756
|
+
outputTarget = 'pages/index.vue';
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
catch { /* ignore */ }
|
|
1760
|
+
}
|
|
1725
1761
|
const briefPath = path_1.default.join(root, '.vibetachyon', 'design-session.json');
|
|
1726
1762
|
if (await fs_extra_1.default.pathExists(briefPath)) {
|
|
1727
1763
|
try {
|
|
@@ -1753,12 +1789,35 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
1753
1789
|
];
|
|
1754
1790
|
let combinedPage = `[🎬 ANIMMASTER PAGE COMPOSER: ${themeOrIndustry}]\n`;
|
|
1755
1791
|
combinedPage += `Style: ${briefStyle} | Tone: ${briefTone}\n\n`;
|
|
1756
|
-
|
|
1792
|
+
// Framework-aware output instructions
|
|
1793
|
+
combinedPage += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
|
|
1794
|
+
combinedPage += `📁 OUTPUT TARGET: ${outputTarget || 'src/app/page.tsx'}\n`;
|
|
1795
|
+
combinedPage += `🚨 NEVER create index.html — this is a ${framework === 'nextjs' ? 'Next.js' : framework === 'vite' ? 'React/Vite' : 'React'} project\n`;
|
|
1796
|
+
combinedPage += `🚨 ALL output MUST be .tsx React components, NOT plain HTML files\n`;
|
|
1797
|
+
if (framework === 'nextjs') {
|
|
1798
|
+
combinedPage += `\n📋 NEXTJS TSX RULES:\n`;
|
|
1799
|
+
combinedPage += ` • Convert all HTML → JSX: class→className, for→htmlFor, style={{}}\n`;
|
|
1800
|
+
combinedPage += ` • Add "use client" directive at top if using animations/events\n`;
|
|
1801
|
+
combinedPage += ` • Inline scripts → useEffect(() => { /* JS here */ }, [])\n`;
|
|
1802
|
+
combinedPage += ` • External CDN scripts → use next/script: <Script src="..." strategy="afterInteractive" />\n`;
|
|
1803
|
+
combinedPage += ` • Self-closing tags: <img />, <br />, <input />\n`;
|
|
1804
|
+
combinedPage += ` • Create each section as a separate component in src/components/\n`;
|
|
1805
|
+
combinedPage += ` • Page file: export default function Page() { return (<main>...</main>) }\n`;
|
|
1806
|
+
}
|
|
1807
|
+
else if (framework === 'vite') {
|
|
1808
|
+
combinedPage += `\n📋 VITE/REACT TSX RULES:\n`;
|
|
1809
|
+
combinedPage += ` • Convert HTML → JSX: class→className, for→htmlFor\n`;
|
|
1810
|
+
combinedPage += ` • Inline scripts → useEffect with cleanup\n`;
|
|
1811
|
+
combinedPage += ` • Add React imports at top\n`;
|
|
1812
|
+
}
|
|
1813
|
+
combinedPage += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n`;
|
|
1814
|
+
combinedPage += `⚠️ MANDATORY COLOR RULES — INJECT THIS PALETTE IN globals.css:\n\`\`\`css\n${paletteCSS}\n\`\`\`\n\n`;
|
|
1757
1815
|
combinedPage += `CRITICAL: Use ONLY var(--background), var(--primary), var(--foreground), var(--border), var(--card) etc.\n`;
|
|
1758
1816
|
combinedPage += `NEVER hardcode hex colors. NEVER use purple/neon unless --primary IS purple in the palette above.\n`;
|
|
1759
1817
|
if (briefAvoid.length > 0)
|
|
1760
1818
|
combinedPage += `AVOID: ${briefAvoid.join(', ')}\n`;
|
|
1761
|
-
combinedPage += `\nINSTRUCTION FOR AI: Assemble a complete page using Animmaster components in init_order sequence.\n
|
|
1819
|
+
combinedPage += `\nINSTRUCTION FOR AI: Assemble a complete page using Animmaster components in init_order sequence.\n`;
|
|
1820
|
+
combinedPage += `Convert ALL HTML templates below to JSX. Initialize JS in useEffect hooks.\n\n`;
|
|
1762
1821
|
const allComponents = [];
|
|
1763
1822
|
for (const { section, query, useCase } of sectionMap) {
|
|
1764
1823
|
const { data } = await supabase
|
|
@@ -1793,7 +1852,13 @@ COMPONENT SELECTION FILTER (apply mentally before using any component):
|
|
|
1793
1852
|
}
|
|
1794
1853
|
const totalBudget = allComponents.reduce((sum, c) => sum + (c.animation_budget || 0), 0);
|
|
1795
1854
|
combinedPage += `\n---\nTotal animation budget: ${totalBudget}/30 | Components: ${allComponents.length}\n`;
|
|
1796
|
-
combinedPage += `\
|
|
1855
|
+
combinedPage += `\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
|
|
1856
|
+
combinedPage += `FINAL INSTRUCTION:\n`;
|
|
1857
|
+
combinedPage += `1. Initialize components in init_order sequence (preloader → cursor → header → effects)\n`;
|
|
1858
|
+
combinedPage += `2. Save the page to: ${outputTarget || 'src/app/page.tsx'}\n`;
|
|
1859
|
+
combinedPage += `3. ${framework === 'nextjs' ? 'Add "use client" at top, convert all HTML to JSX (class→className)' : 'Convert HTML to JSX React components'}\n`;
|
|
1860
|
+
combinedPage += `4. NEVER create index.html — always .tsx files only\n`;
|
|
1861
|
+
combinedPage += `━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`;
|
|
1797
1862
|
return { content: [{ type: "text", text: combinedPage }] };
|
|
1798
1863
|
}
|
|
1799
1864
|
catch (err) {
|