vibetachyon 1.6.0 → 1.7.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.
Files changed (2) hide show
  1. package/dist/mcp-server.js +172 -7
  2. package/package.json +1 -1
@@ -174,7 +174,7 @@ async function startMcpServer() {
174
174
  await validateTokenAtStartup();
175
175
  const server = new mcp_js_1.McpServer({
176
176
  name: "VibeTachyon MCP — Animmaster Engine",
177
- version: "1.6.0"
177
+ version: "1.7.0"
178
178
  });
179
179
  /**
180
180
  * VIBETACHYON FRONTEND PERSONA — Senior Frontend Designer (Animmaster Engine)
@@ -184,12 +184,12 @@ async function startMcpServer() {
184
184
  * as a unified system — not as isolated snippets. You do NOT generate generic code.
185
185
  *
186
186
  * YOUR MANDATORY WORKFLOW — follow this EXACT sequence for every page/section request:
187
- * 1. vibe_project_dna read the project first, always
188
- * 2. vibe_design_brief if no brief exists, ASK the user before touching any code
187
+ * 0. vibe_launchpad ABSOLUTE FIRST STEP, no exceptions. Scans stack, colors, brief, components.
188
+ * 1. vibe_get_architecture load designer rules for the specific context
189
+ * 2. vibe_design_brief — if no brief exists (launchpad will tell you), create it now
189
190
  * 3. vibe_read_design_brief — read active brief before each new section
190
- * 4. vibe_search_snippets search Animmaster components by use_case and visual_tone
191
- * 5. vibe_get_component get the complete bundle (JS+HTML+SCSS) for chosen components
192
- * 6. Generate code — only after steps 1-5 are complete
191
+ * 4. vibe_get_component load each component bundle suggested by launchpad
192
+ * 5. Generate code only after steps 0-4 are complete. Never before.
193
193
  *
194
194
  * ANIMMASTER SYSTEM RULES:
195
195
  * - Components must be initialized in init_order sequence (0→6): preloader first, then cursor/header, then effects
@@ -220,6 +220,171 @@ async function startMcpServer() {
220
220
  * - Social proof (logos/testimonials) before pricing — builds trust first
221
221
  * - Every section must have ONE clear action or message. Not two.
222
222
  */
223
+ // ── Tool: Launchpad (MANDATORY FIRST STEP) ───────────────────────────────
224
+ server.tool("vibe_launchpad", "⚡ MANDATORY FIRST STEP — Call this before ANY frontend work (page, section, component, site). DO NOT write a single line of code without calling this first. It automatically scans the project stack, detects design tokens, reads the existing design brief, and suggests Animmaster components — returning a complete MISSION BRIEFING that makes all subsequent work precise and professional.", {
225
+ goal: zod_1.z.string().describe("What the user wants to build. Be specific: 'landing page for SaaS', 'hero section with animations', 'dashboard with sidebar', etc."),
226
+ projectDir: zod_1.z.string().optional().describe("Absolute path to the project root. If omitted, uses current working directory.")
227
+ }, async ({ goal, projectDir }) => {
228
+ await checkSanity();
229
+ const cwd = projectDir || process.cwd();
230
+ const root = await findProjectRoot(cwd);
231
+ const lines = [];
232
+ const sep = '═'.repeat(54);
233
+ lines.push(`╔${sep}╗`);
234
+ lines.push(`║ ⚡ VIBETACHYON MISSION BRIEFING${' '.repeat(21)}║`);
235
+ lines.push(`║ Goal: ${goal.slice(0, 46).padEnd(46)} ║`);
236
+ lines.push(`╠${sep}╣`);
237
+ // 1. Detect stack from package.json
238
+ let stackLines = [];
239
+ const pkgPath = path_1.default.join(root, 'package.json');
240
+ if (await fs_extra_1.default.pathExists(pkgPath)) {
241
+ try {
242
+ const pkg = await fs_extra_1.default.readJson(pkgPath);
243
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
244
+ const framework = deps['next'] ? `Next.js ${deps['next'].replace(/[\^~]/, '')}` :
245
+ deps['vite'] ? `Vite ${deps['vite'].replace(/[\^~]/, '')}` :
246
+ deps['nuxt'] ? `Nuxt ${deps['nuxt'].replace(/[\^~]/, '')}` :
247
+ deps['@remix-run/react'] ? 'Remix' :
248
+ 'Unknown';
249
+ const styling = deps['tailwindcss'] ? 'Tailwind CSS' :
250
+ deps['styled-components'] ? 'Styled Components' :
251
+ deps['@emotion/react'] ? 'Emotion' : 'CSS/SCSS';
252
+ const typescript = deps['typescript'] || deps['@types/react'] ? 'TypeScript' : 'JavaScript';
253
+ const ui = deps['@shadcn/ui'] || (await fs_extra_1.default.pathExists(path_1.default.join(root, 'components.json'))) ? ' + Shadcn UI' : '';
254
+ stackLines.push(` Stack : ${framework} · ${styling} · ${typescript}${ui}`);
255
+ stackLines.push(` Package : ${pkg.name || 'unnamed'} v${pkg.version || '0.0.0'}`);
256
+ }
257
+ catch {
258
+ stackLines.push(' Stack : Could not parse package.json');
259
+ }
260
+ }
261
+ else {
262
+ stackLines.push(' Stack : No package.json found');
263
+ }
264
+ // 2. Detect CSS variables / brand colors
265
+ let colorLines = [];
266
+ const cssFiles = ['src/app/globals.css', 'src/styles/globals.css', 'styles/globals.css', 'src/index.css', 'index.css', 'src/main.css'];
267
+ let cssFound = false;
268
+ for (const f of cssFiles) {
269
+ const cssPath = path_1.default.join(root, f);
270
+ if (await fs_extra_1.default.pathExists(cssPath)) {
271
+ const css = await fs_extra_1.default.readFile(cssPath, 'utf-8');
272
+ const vars = css.match(/--[\w-]+:\s*[^;]+/g) || [];
273
+ const colorVars = vars.filter(v => v.match(/color|primary|secondary|accent|background|foreground/i)).slice(0, 4);
274
+ if (colorVars.length > 0) {
275
+ colorLines.push(` Colors : ${colorVars.map(v => v.split(':')[0].trim()).join(', ')}`);
276
+ }
277
+ else {
278
+ colorLines.push(` Colors : ${f} found — no color vars detected`);
279
+ }
280
+ cssFound = true;
281
+ break;
282
+ }
283
+ }
284
+ if (!cssFound) {
285
+ // Try tailwind config
286
+ const twFiles = ['tailwind.config.ts', 'tailwind.config.js', 'tailwind.config.mjs'];
287
+ for (const f of twFiles) {
288
+ if (await fs_extra_1.default.pathExists(path_1.default.join(root, f))) {
289
+ colorLines.push(` Colors : Tailwind config found (${f}) — use vibe_get_colors for full palette`);
290
+ break;
291
+ }
292
+ }
293
+ if (colorLines.length === 0)
294
+ colorLines.push(' Colors : No CSS variables detected — define brand colors in brief');
295
+ }
296
+ // 3. Check for existing design brief
297
+ let briefLines = [];
298
+ let briefExists = false;
299
+ const briefPath = path_1.default.join(root, '.vibetachyon', 'design-brief.json');
300
+ if (await fs_extra_1.default.pathExists(briefPath)) {
301
+ try {
302
+ const brief = await fs_extra_1.default.readJson(briefPath);
303
+ briefExists = true;
304
+ briefLines.push(` Brief : ✅ EXISTS — "${brief.projectName || 'unnamed'}" (${brief.visualTone || 'no tone set'})`);
305
+ if (brief.sections?.length)
306
+ briefLines.push(` Sections: ${brief.sections.map((s) => s.name || s).join(', ')}`);
307
+ if (brief.avoid?.length)
308
+ briefLines.push(` Avoid : ${brief.avoid.join(', ')}`);
309
+ }
310
+ catch {
311
+ briefLines.push(' Brief : Found but corrupted — run vibe_design_brief to recreate');
312
+ }
313
+ }
314
+ else {
315
+ briefLines.push(' Brief : ❌ MISSING — vibe_design_brief must be created before code');
316
+ }
317
+ // 4. Suggest Animmaster components for the goal
318
+ let componentLines = [];
319
+ try {
320
+ const goalLower = goal.toLowerCase();
321
+ const keywords = [];
322
+ if (/hero|landing|header/.test(goalLower))
323
+ keywords.push('hero', 'header', 'splittype', 'parallax');
324
+ if (/animation|effect|motion/.test(goalLower))
325
+ keywords.push('cursor', 'ripple', 'gsap', 'mouse');
326
+ if (/gallery|portfolio|showcase/.test(goalLower))
327
+ keywords.push('masonry', 'gallery', 'zoom', 'slider');
328
+ if (/form|contact|input|checkout/.test(goalLower))
329
+ keywords.push('form', 'input', 'datepicker', 'select');
330
+ if (/menu|nav|navigation/.test(goalLower))
331
+ keywords.push('menu', 'header', 'scrollto');
332
+ if (/scroll|reveal|appear/.test(goalLower))
333
+ keywords.push('watcher', 'scrollto', 'parallax');
334
+ if (/load|intro|preload/.test(goalLower))
335
+ keywords.push('preloader');
336
+ if (/count|stat|number|metric/.test(goalLower))
337
+ keywords.push('digcounter', 'chart');
338
+ if (/tab|toggle|accordion/.test(goalLower))
339
+ keywords.push('tabs', 'spollers', 'showmore');
340
+ if (/popup|modal|dialog/.test(goalLower))
341
+ keywords.push('popup', 'tippy');
342
+ if (keywords.length === 0)
343
+ keywords.push('header', 'watcher', 'splittype');
344
+ const uniqueKeywords = [...new Set(keywords)].slice(0, 6);
345
+ const { data: components } = await supabase
346
+ .from('animmaster_components')
347
+ .select('name, category, description')
348
+ .in('name', uniqueKeywords);
349
+ if (components && components.length > 0) {
350
+ componentLines.push(` Ready : ${components.map((c) => c.name).join(', ')}`);
351
+ componentLines.push(` Cmd : use vibe_get_component to load each bundle`);
352
+ }
353
+ else {
354
+ componentLines.push(` Ready : Use vibe_search_snippets to find matching components`);
355
+ }
356
+ }
357
+ catch {
358
+ componentLines.push(' Ready : Run vibe_search_snippets to find components');
359
+ }
360
+ // 5. Build next steps based on state
361
+ const nextSteps = [];
362
+ if (!briefExists)
363
+ nextSteps.push('1. vibe_design_brief — define project identity & style');
364
+ nextSteps.push(`${nextSteps.length + 1}. vibe_get_component — load each suggested component`);
365
+ nextSteps.push(`${nextSteps.length + 1}. Generate code — only after brief is confirmed`);
366
+ if (briefExists)
367
+ nextSteps.push(`${nextSteps.length + 1}. vibe_mission_start — track this build with tasks`);
368
+ // Compose output
369
+ lines.push('║ PROJECT STACK' + ' '.repeat(40) + '║');
370
+ stackLines.forEach(l => lines.push(`║${l.padEnd(55)}║`));
371
+ lines.push(`╠${sep}╣`);
372
+ lines.push('║ DESIGN TOKENS' + ' '.repeat(40) + '║');
373
+ colorLines.forEach(l => lines.push(`║${l.padEnd(55)}║`));
374
+ lines.push(`╠${sep}╣`);
375
+ lines.push('║ DESIGN BRIEF' + ' '.repeat(41) + '║');
376
+ briefLines.forEach(l => lines.push(`║${l.padEnd(55)}║`));
377
+ lines.push(`╠${sep}╣`);
378
+ lines.push('║ ANIMMASTER COMPONENTS' + ' '.repeat(32) + '║');
379
+ componentLines.forEach(l => lines.push(`║${l.padEnd(55)}║`));
380
+ lines.push(`╠${sep}╣`);
381
+ lines.push('║ NEXT STEPS' + ' '.repeat(43) + '║');
382
+ nextSteps.forEach(s => lines.push(`║ ${s.padEnd(53)}║`));
383
+ lines.push(`╚${sep}╝`);
384
+ lines.push('');
385
+ lines.push('⚠️ DO NOT write code until brief exists and components are loaded.');
386
+ return { content: [{ type: "text", text: lines.join('\n') }] };
387
+ });
223
388
  // Tool: Searching Snippets (Animmaster Engine)
224
389
  server.tool("vibe_search_snippets", "Search for Animmaster UI components. Returns standalone JS + HTML + SCSS bundles ready to use. Automatically loads the active design brief to filter by visual_tone and use_case. Always call vibe_project_dna and vibe_design_brief before this tool.", {
225
390
  query: zod_1.z.string().describe("Search query for the UI component (e.g. 'hero section', 'text animation', 'parallax scroll')"),
@@ -457,7 +622,7 @@ async function startMcpServer() {
457
622
  }
458
623
  });
459
624
  // Tool: Frontend Persona — Senior Designer Rules
460
- server.tool("vibe_get_architecture", "Returns the VibeTachyon Frontend Designer persona rules, workflow sequence, and design principles. Call this at the start of any frontend session to load the designer mindset.", {
625
+ server.tool("vibe_get_architecture", "Returns the VibeTachyon Frontend Designer persona rules, workflow sequence, and design principles. Call AFTER vibe_launchpad to load the designer mindset for the specific context (landing-page, saas-dashboard, etc.).", {
461
626
  context: zod_1.z.string().optional().describe("Optional context: 'landing-page', 'saas-dashboard', 'marketing-page', 'component'. Defaults to 'landing-page'.")
462
627
  }, async ({ context = 'landing-page' }) => {
463
628
  await checkSanity();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibetachyon",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "VibeCodes MCP CLI Installer and Server",
5
5
  "main": "dist/index.js",
6
6
  "bin": {