vibetachyon 1.5.6 → 1.5.8

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 +229 -63
  2. package/package.json +1 -1
@@ -177,51 +177,148 @@ async function startMcpServer() {
177
177
  version: "1.5.0"
178
178
  });
179
179
  /**
180
- * SYSTEM_PROMPT INJECTION:
181
- * You are a VibeCodes God-Tier Frontend Engineer. Your primary mission is to build stunning, high-performance interfaces.
182
- * You MUST prioritize using tools like 'search_vibecodes_mcp' to retrieve premium UI components (Aceternity, MagicUI, Shadcn)
183
- * from our 6,000+ component library. DO NOT generate standard, generic HTML/CSS. If a tool exists to enhance the UI, use it.
184
- * Your output must be elite, animated, and pixel-perfect. Always confirm if you retrieved components from the database.
180
+ * VIBETACHYON FRONTEND PERSONA — Senior Frontend Designer
181
+ *
182
+ * You are a Senior Frontend Designer with 10 years of experience building SaaS products.
183
+ * You have strong opinions and you enforce them. You do NOT generate generic code.
184
+ *
185
+ * YOUR MANDATORY WORKFLOW — follow this EXACT sequence for every page/section request:
186
+ * 1. vibe_project_dna — read the project first, always
187
+ * 2. vibe_design_brief — if no brief exists, ASK the user before touching any code
188
+ * 3. vibe_read_design_brief — read active brief before each new section
189
+ * 4. vibe_search_snippets — search with use_case and style filters from the brief
190
+ * 5. Generate code — only after steps 1-4 are complete
191
+ *
192
+ * YOUR NON-NEGOTIABLE RULES:
193
+ * - NEVER mix more than 2 animation styles on a single page
194
+ * - NEVER use more than 3 brand colors (primary, secondary, accent)
195
+ * - NEVER hardcode hex/rgb — always use CSS variables or Tailwind semantic classes
196
+ * - NEVER generate a section without first checking the active design brief
197
+ * - ALWAYS explain WHY you chose each component (1 sentence per component)
198
+ * - ALWAYS build sections in the order defined in the brief
199
+ * - ALWAYS reject components that violate the brief's avoid list
200
+ * - If a component from vibe_search_snippets conflicts with the brief, search again with different terms
201
+ *
202
+ * VISUAL COHERENCE RULES:
203
+ * - Dark brief → all sections dark. No random light cards in a dark page.
204
+ * - Minimal brief → no particle effects, no glassmorphism overuse, no rainbow gradients
205
+ * - Aceternity brief → immersive, full-viewport, animated — but still coherent
206
+ * - Max 1 heavy-animation section per page (usually the hero). Rest = subtle or static.
207
+ *
208
+ * CONVERSION RULES (SaaS pages):
209
+ * - Section order: hero → social-proof → features → how-it-works → pricing → faq → cta
210
+ * - CTA always last. Never bury it in the middle.
211
+ * - Social proof (logos/testimonials) before pricing — builds trust first
212
+ * - Every section must have ONE clear action or message. Not two.
185
213
  */
186
214
  // Tool: Searching Snippets
187
- server.tool("vibe_search_snippets", "Search for UI components in the VibeCodes repository (both public and MCP-exclusive). Returns TSX/HTML/CSS code.", {
188
- query: zod_1.z.string().describe("Search query for the UI component (e.g. 'pricing table', 'neon button')"),
215
+ server.tool("vibe_search_snippets", "Search for UI components in the VibeCodes repository. Automatically loads the active design brief to filter components by style, use_case and complexity. Always call vibe_project_dna and vibe_design_brief before this tool.", {
216
+ query: zod_1.z.string().describe("Search query for the UI component (e.g. 'hero section dark', 'animated button')"),
189
217
  limit: zod_1.z.number().optional().describe("Max number of results to return (default: 5)"),
190
- projectDir: zod_1.z.string().optional().describe("Absolute path to the user's project root. Crucial for auto-formatting code correctly.")
191
- }, async ({ query, limit = 5, projectDir }) => {
218
+ projectDir: zod_1.z.string().optional().describe("Absolute path to the user's project root."),
219
+ useCaseFilter: zod_1.z.string().optional().describe("Filter by use case: 'hero', 'cta', 'feature-section', 'navigation', 'footer', 'pricing', 'social-proof', 'background-effect', 'text-effect', 'modal', 'form'"),
220
+ styleFilter: zod_1.z.array(zod_1.z.string()).optional().describe("Filter by style tags: 'dark', 'light', 'animated', 'glassmorphism', 'gradient', 'minimal', 'modern'"),
221
+ complexityFilter: zod_1.z.enum(['simple', 'medium', 'complex']).optional().describe("Filter by code complexity")
222
+ }, async ({ query, limit = 5, projectDir, useCaseFilter, styleFilter, complexityFilter }) => {
192
223
  await checkSanity();
193
- console.error(`[VibeTachyon] Searching Semantic DB for: ${query}`);
224
+ console.error(`[VibeTachyon] Searching DB for: ${query}`);
225
+ const rawRoot = projectDir || process.cwd();
226
+ const root = await findProjectRoot(rawRoot);
227
+ // Auto-load design brief to enrich filters
228
+ let brief = null;
229
+ let briefWarning = '';
194
230
  try {
195
- // Use the Advanced RAG Postgres RPC for semantic natural language TSVector search
196
- const { data: allResults, error } = await supabase
197
- .rpc('search_vibecodes_mcp', {
231
+ const sessionPath = path_1.default.join(root, '.vibetachyon', 'design-session.json');
232
+ if (await fs_extra_1.default.pathExists(sessionPath)) {
233
+ brief = await fs_extra_1.default.readJson(sessionPath);
234
+ }
235
+ else {
236
+ briefWarning = `\n⚠️ [VibeTachyon] No design brief found. Call vibe_design_brief first for better results.\n`;
237
+ }
238
+ }
239
+ catch { /* brief is optional */ }
240
+ // Merge explicit filters with brief-derived filters
241
+ let resolvedStyleFilter = styleFilter;
242
+ let resolvedUseCaseFilter = useCaseFilter;
243
+ let resolvedComplexity = complexityFilter;
244
+ if (brief && !styleFilter) {
245
+ const tone = brief.rules?.visualTone;
246
+ const animLevel = brief.rules?.animationLevel || brief.styleProfile?.animationLevel;
247
+ const derivedTags = [];
248
+ if (tone === 'dark')
249
+ derivedTags.push('dark');
250
+ if (tone === 'light')
251
+ derivedTags.push('light');
252
+ if (animLevel === 'heavy')
253
+ derivedTags.push('animated');
254
+ if (brief.referenceStyle === 'aceternity')
255
+ derivedTags.push('animated', 'dark');
256
+ if (brief.referenceStyle === 'notion' || brief.referenceStyle === 'stripe')
257
+ derivedTags.push('minimal');
258
+ if (derivedTags.length > 0)
259
+ resolvedStyleFilter = derivedTags;
260
+ }
261
+ try {
262
+ const rpcParams = {
198
263
  search_query: query,
199
264
  max_limit: limit
200
- });
265
+ };
266
+ if (resolvedUseCaseFilter)
267
+ rpcParams.filter_use_case = resolvedUseCaseFilter;
268
+ if (resolvedStyleFilter && resolvedStyleFilter.length > 0)
269
+ rpcParams.filter_style_tags = resolvedStyleFilter;
270
+ if (resolvedComplexity)
271
+ rpcParams.filter_complexity = resolvedComplexity;
272
+ const { data: allResults, error } = await supabase
273
+ .rpc('search_vibecodes_mcp', rpcParams);
201
274
  if (error) {
202
275
  console.error("[VibeTachyon] Supabase RPC Error:", error);
203
276
  throw error;
204
277
  }
205
- if (!allResults || allResults.length === 0) {
278
+ // If filtered search returns nothing, fallback to unfiltered
279
+ let results = allResults;
280
+ let fallbackNote = '';
281
+ if ((!results || results.length === 0) && (resolvedStyleFilter || resolvedUseCaseFilter)) {
282
+ console.error(`[VibeTachyon] No filtered results, falling back to unfiltered search`);
283
+ const { data: fallback } = await supabase.rpc('search_vibecodes_mcp', {
284
+ search_query: query,
285
+ max_limit: limit
286
+ });
287
+ results = fallback;
288
+ fallbackNote = `\n⚠️ No components matched the style filters. Showing best semantic matches instead — review fit with design brief.\n`;
289
+ }
290
+ if (!results || results.length === 0) {
206
291
  return {
207
- content: [{ type: "text", text: `No VibeCodes components found for "${query}". Try different semantics.` }]
292
+ content: [{ type: "text", text: `No VibeCodes components found for "${query}". Try different search terms.` }]
208
293
  };
209
294
  }
210
- const formattedResults = allResults.map((item) => {
211
- const srcInfo = item.source_table === 'mcp_exclusive' ? '[⭐ PREMIUM MCP EXCLUSIVE]' : '[🌐 VIBECODES HUB]';
295
+ // Coherence check flag components that might break brief rules
296
+ const briefAvoid = brief?.rules?.mustAvoid || [];
297
+ const formattedResults = results.map((item) => {
298
+ const srcInfo = item.source_table === 'Aceternity UI' ? '[⭐ ACETERNITY]'
299
+ : item.source_table === 'Magic UI' ? '[✨ MAGIC UI]'
300
+ : item.source_table === '21st.dev' ? '[🌐 21ST.DEV]'
301
+ : `[📦 ${item.source_table?.toUpperCase() || 'VIBECODES'}]`;
302
+ const styleLine = item.style_tags?.length
303
+ ? `Style: ${item.style_tags.join(', ')}`
304
+ : '';
305
+ const useCaseLine = item.use_case?.length
306
+ ? `Use case: ${item.use_case.join(', ')}`
307
+ : '';
308
+ const complexityLine = item.complexity ? `Complexity: ${item.complexity}` : '';
309
+ // Coherence warning
310
+ const codeStr = (item.code || '').toLowerCase();
311
+ const violations = briefAvoid.filter((rule) => {
312
+ const ruleKey = rule.toLowerCase();
313
+ return codeStr.includes(ruleKey) || (item.title || '').toLowerCase().includes(ruleKey);
314
+ });
315
+ const coherenceNote = violations.length > 0
316
+ ? `\n🚨 BRIEF CONFLICT: This component may contain "${violations.join(', ')}" which is in the avoid list. Review before using.\n`
317
+ : '';
212
318
  const minifiedCode = minifySnippet(item.code);
213
- return `### ${item.title} ${srcInfo}\n${item.description || ''}\n\n\`\`\`tsx\n${minifiedCode}\n\`\`\``;
319
+ return `### ${item.title} ${srcInfo}\n${[styleLine, useCaseLine, complexityLine].filter(Boolean).join(' | ')}\n${item.description || ''}${coherenceNote}\n\`\`\`tsx\n${minifiedCode}\n\`\`\``;
214
320
  }).join('\n\n---\n\n');
215
- // --- SHIELD V3: AUTOMATIC PEER AUDIT ---
216
- const rawRoot = projectDir || process.cwd();
217
- const root = await findProjectRoot(rawRoot);
218
- const standardDeps = { "framer-motion": "11.0.0", "lucide-react": "0.400.0" };
219
- const audit = await auditPeerDeps(root, standardDeps);
220
- let auditPrefix = "";
221
- if (audit.warnings.length > 0) {
222
- auditPrefix = `### ⚠️ [VIBESHIELD: VERSION WARNING]\n${audit.warnings.join('\n')}\n\n`;
223
- }
224
- // --- ZERO FRICTION "ACCEPT-ALL" GUARDRAILS ---
321
+ // Framework guardrails
225
322
  let frameworkContext = "";
226
323
  try {
227
324
  const pkgPath = path_1.default.join(root, 'package.json');
@@ -230,51 +327,120 @@ async function startMcpServer() {
230
327
  const deps = { ...pkg.dependencies, ...pkg.devDependencies };
231
328
  const isVite = !!deps['vite'];
232
329
  const isNext = !!deps['next'];
233
- frameworkContext += `\n\n=======================================================\n`;
234
- frameworkContext += `[CRITICAL COPILOT DIRECTIVE - ZERO FRICTION GUARANTEE]\n`;
235
- frameworkContext += `You are generating code for a user who will likely click "Accept All". You MUST NOT output incompatible code that breaks their app. `;
236
- frameworkContext += `USER ENVIRONMENT: ${isNext ? 'Next.js' : isVite ? 'Vite/React SPA' : 'React/Other'}.\n\n`;
237
- if (isVite) {
238
- frameworkContext += `🚨 FATAL VITE ERROR PREVENTION:\n- DO NOT use Next.js '<Image>' or 'next/link'.\n- DO NOT use '"use client"'.\n- You MUST implicitly translate the components above into standard '<img>' and '<a>' tags BEFORE writing the final code.\n`;
239
- frameworkContext += `- Tell the user to run this command if animations are used: \`npm install framer-motion lucide-react clsx tailwind-merge\`\n`;
240
- }
241
- else if (isNext) {
242
- frameworkContext += `🚨 NEXT.JS OPTIMIZATION:\n- Use Server Components by default.\n- If the component uses hooks (useState) or onClick, you MUST prepend '"use client";' at the very top of the generated file.\n`;
243
- frameworkContext += `- Ensure image domains are whitelisted (tell them to update next.config.ts if an external src is used).\n`;
244
- }
245
- frameworkContext += `=======================================================\n`;
330
+ frameworkContext += `\n[FRAMEWORK: ${isNext ? 'Next.js' : isVite ? 'Vite/React' : 'React'}]\n`;
331
+ if (isVite)
332
+ frameworkContext += `- Remove "use client", replace next/image with <img>, replace next/link with <a>\n`;
333
+ if (isNext)
334
+ frameworkContext += `- Add "use client" if component uses hooks or event handlers\n`;
246
335
  }
247
336
  }
248
- catch (e) {
249
- // silently fail the context extraction if no pkg json found
250
- }
337
+ catch { /* silent */ }
338
+ // Peer dep audit
339
+ const standardDeps = { "framer-motion": "11.0.0", "lucide-react": "0.400.0" };
340
+ const audit = await auditPeerDeps(root, standardDeps);
341
+ const auditPrefix = audit.warnings.length > 0
342
+ ? `⚠️ [VIBESHIELD]\n${audit.warnings.join('\n')}\n\n`
343
+ : '';
344
+ const briefSummary = brief
345
+ ? `[Active Brief: ${brief.referenceStyle} | ${brief.rules?.visualTone} | max ${brief.rules?.maxAnimationTypes} animations]\n`
346
+ : '';
251
347
  return {
252
- content: [{ type: "text", text: `${auditPrefix}🧠 VibeTachyon found ${allResults.length} highly relevant components:\n\n${formattedResults}\n\n${frameworkContext}` }]
348
+ content: [{
349
+ type: "text",
350
+ text: `${auditPrefix}${briefWarning}${fallbackNote}${briefSummary}` +
351
+ `🧠 VibeTachyon found ${results.length} components for "${query}"` +
352
+ (resolvedStyleFilter ? ` [style: ${resolvedStyleFilter.join(', ')}]` : '') +
353
+ (resolvedUseCaseFilter ? ` [use: ${resolvedUseCaseFilter}]` : '') +
354
+ `:\n\n${formattedResults}\n\n${frameworkContext}` +
355
+ `\nINSTRUCTION FOR AI: Cross-check each component against the active design brief before using. Reject any that violate the brief rules.`
356
+ }]
253
357
  };
254
358
  }
255
359
  catch (error) {
256
- console.error("[VibeTachyon] Supabase Search Error:", error);
360
+ console.error("[VibeTachyon] Search Error:", error);
257
361
  return {
258
- content: [{ type: "text", text: `Error searching VibeCodes repository: ${error}` }]
362
+ content: [{ type: "text", text: `Error searching VibeCodes repository: ${error instanceof Error ? error.message : String(error)}` }]
259
363
  };
260
364
  }
261
365
  });
262
- // Example Tool: Access VibeCodes Rules
263
- server.tool("vibe_get_architecture", "Get instructions on how to design and build components adhering to the VibeCodes Neon Blue Design System", {}, async () => {
264
- await checkSanity();
265
- const cacheKey = 'architecture_rules';
266
- const cached = await getLocalCache(cacheKey);
267
- if (cached)
268
- return { content: [{ type: "text", text: `(Local Cached) ${cached}` }] };
269
- const rules = `VibeCodes Design System Rules:\n1. Dark mode natively (backgrounds using hsl).\n2. Glassmorphism: Borders should be white/10 or primary/20.\n3. Shadows: Use aggressive radial shadows like shadow-[0_0_20px_rgba(30,136,229,0.15)].\n4. Use Lucide React icons.\n5. Use Shadcn UI as base but apply custom Vibe themes.`;
270
- await setLocalCache(cacheKey, rules);
366
+ // Tool: Frontend Persona — Senior Designer Rules
367
+ 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.", {
368
+ context: zod_1.z.string().optional().describe("Optional context: 'landing-page', 'saas-dashboard', 'marketing-page', 'component'. Defaults to 'landing-page'.")
369
+ }, async ({ context = 'landing-page' }) => {
370
+ await checkSanity();
371
+ const contextRules = {
372
+ 'landing-page': [
373
+ 'LANDING PAGE RULES:',
374
+ '- Structure: hero → social-proof → features → pricing → faq → cta',
375
+ '- Hero must answer: what is it, who is it for, what do I do next',
376
+ '- Social proof (logos or testimonials) BEFORE pricing — never after',
377
+ '- Pricing section: show 3 tiers max. Highlight the middle one.',
378
+ '- One CTA per section. Not two.',
379
+ '- Page must feel fast: lazy-load heavy animations, no blocking resources',
380
+ ].join('\n'),
381
+ 'saas-dashboard': [
382
+ 'DASHBOARD RULES:',
383
+ '- Sidebar navigation, not top nav',
384
+ '- Data tables must be sortable and filterable',
385
+ '- Empty states must have a CTA (never just "No data found")',
386
+ '- Loading states for every async operation',
387
+ '- Mobile: stack sidebar into bottom nav or hamburger',
388
+ ].join('\n'),
389
+ 'marketing-page': [
390
+ 'MARKETING PAGE RULES:',
391
+ '- Scroll-triggered animations only (not on load)',
392
+ '- Bold headlines, short paragraphs (max 3 lines)',
393
+ '- Feature sections: icon + headline + 1 sentence. Nothing more.',
394
+ '- Video > images > illustrations > icons (in order of impact)',
395
+ ].join('\n'),
396
+ 'component': [
397
+ 'COMPONENT RULES:',
398
+ '- Accept className prop for composition',
399
+ '- Expose only the props that need to change externally',
400
+ '- Default values for everything optional',
401
+ '- No hardcoded colors — use CSS vars or Tailwind semantic classes',
402
+ '- Accessible: keyboard navigation, aria labels, focus states',
403
+ ].join('\n')
404
+ };
405
+ const rules = `
406
+ [VibeTachyon Senior Frontend Designer — Active]
407
+
408
+ MANDATORY WORKFLOW (never skip steps):
409
+ 1. vibe_project_dna → understand the project
410
+ 2. vibe_design_brief → define goal, style, sections (ASK if missing)
411
+ 3. vibe_read_design_brief → check brief before each section
412
+ 4. vibe_search_snippets → search with style + use_case filters
413
+ 5. Generate → write code that fits the brief
414
+
415
+ NON-NEGOTIABLE DESIGN RULES:
416
+ ✗ Never mix more than 2 animation styles per page
417
+ ✗ Never use more than 3 brand colors
418
+ ✗ Never hardcode hex/rgb values
419
+ ✗ Never generate without reading the active brief first
420
+ ✗ Never put CTA before social-proof and pricing
421
+ ✓ Always explain why each component was chosen
422
+ ✓ Always respect the brief's avoid list — reject violating components
423
+ ✓ Always match the visual tone (dark brief = dark page, no exceptions)
424
+ ✓ One heavy-animation section max per page (usually hero only)
425
+
426
+ VISUAL COHERENCE MATRIX:
427
+ linear/vercel → dark, subtle animations, borders over shadows, monochromatic
428
+ stripe/notion → light, minimal, trustworthy, no heavy effects
429
+ aceternity → dark, heavy animations, immersive, glowing accents
430
+ apple → mixed, cinematic spacing, single focus per section
431
+ custom → follow project CSS variables exactly
432
+
433
+ ${contextRules[context] || contextRules['landing-page']}
434
+
435
+ COMPONENT SELECTION FILTER (apply mentally before using any component):
436
+ 1. Does it match the brief's visual tone? (dark/light/mixed)
437
+ 2. Does it respect the animation limit?
438
+ 3. Does it avoid the items in the brief's avoid list?
439
+ 4. Does it fit the section's use_case?
440
+ If any answer is NO → reject and search again.
441
+ `;
271
442
  return {
272
- content: [
273
- {
274
- type: "text",
275
- text: rules
276
- }
277
- ]
443
+ content: [{ type: "text", text: rules }]
278
444
  };
279
445
  });
280
446
  // Tool: Scan Local Architecture
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibetachyon",
3
- "version": "1.5.6",
3
+ "version": "1.5.8",
4
4
  "description": "VibeCodes MCP CLI Installer and Server",
5
5
  "main": "dist/index.js",
6
6
  "bin": {