sonance-brand-mcp 1.3.67 → 1.3.69

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.
@@ -480,18 +480,32 @@ export function analyzeContrastRelationships(
480
480
  // Track which backgrounds we've analyzed to add white/black alternatives
481
481
  const analyzedBackgrounds: { name: string; rgb: RGB }[] = [];
482
482
 
483
+ // DEBUG: Log start of analysis
484
+ const varCount = Object.keys(cssVariables).length;
485
+ console.log("[Contrast] Starting analysis with", varCount, "variables");
486
+
487
+ let skippedForeground = 0;
488
+ let skippedNonColor = 0;
489
+ let failedParse = 0;
490
+ let noForegroundVar = 0;
491
+ let pairsAnalyzed = 0;
492
+
483
493
  // Find all bg/foreground pairs automatically
484
494
  for (const [varName, value] of Object.entries(cssVariables)) {
485
495
  // Skip if this is a foreground variable
486
- if (varName.includes("foreground")) continue;
496
+ if (varName.includes("foreground")) {
497
+ skippedForeground++;
498
+ continue;
499
+ }
487
500
 
488
501
  // Skip non-color variables
489
502
  if (
490
503
  varName.includes("radius") ||
491
504
  varName.includes("shadow") ||
492
505
  varName.includes("ring") ||
493
- varName.includes("border") && !varName.match(/border$/)
506
+ (varName.includes("border") && !varName.match(/border$/))
494
507
  ) {
508
+ skippedNonColor++;
495
509
  continue;
496
510
  }
497
511
 
@@ -500,19 +514,30 @@ export function analyzeContrastRelationships(
500
514
 
501
515
  // Parse background color
502
516
  const bgRgb = parseColorToRgb(value);
503
- if (!bgRgb) continue;
517
+ if (!bgRgb) {
518
+ // DEBUG: Log failed parses for important color variables
519
+ if (baseName.includes("primary") || baseName.includes("accent") || baseName.includes("success")) {
520
+ console.log("[Contrast] Failed to parse:", varName, "=", value);
521
+ }
522
+ failedParse++;
523
+ continue;
524
+ }
504
525
 
505
526
  // Track this background for alternative suggestions
506
527
  analyzedBackgrounds.push({ name: baseName, rgb: bgRgb });
507
528
 
508
529
  // Check if there's a corresponding foreground variable
509
530
  if (cssVariables[foregroundVar]) {
531
+ pairsAnalyzed++;
510
532
  const fgRgb = parseColorToRgb(cssVariables[foregroundVar]);
511
533
 
512
534
  if (fgRgb) {
513
535
  const ratio = getContrastRatio(bgRgb, fgRgb);
514
536
  const passes = ratio >= 4.5; // WCAG AA for normal text
515
537
 
538
+ // DEBUG: Log analyzed pairs
539
+ console.log("[Contrast] Pair:", baseName, "bg:", value, "fg:", cssVariables[foregroundVar], "ratio:", ratio.toFixed(1), passes ? "PASS" : "FAIL");
540
+
516
541
  if (!passes) {
517
542
  // Find the best alternative
518
543
  const alternative = getBestAlternative(bgRgb);
@@ -531,9 +556,26 @@ export function analyzeContrastRelationships(
531
556
  });
532
557
  }
533
558
  }
559
+ } else {
560
+ // DEBUG: Log important variables without foreground
561
+ if (baseName.includes("primary") || baseName.includes("accent") || baseName.includes("success")) {
562
+ console.log("[Contrast] No foreground var for:", baseName, "looked for:", foregroundVar);
563
+ }
564
+ noForegroundVar++;
534
565
  }
535
566
  }
536
567
 
568
+ // DEBUG: Summary
569
+ console.log("[Contrast] Summary:", {
570
+ total: varCount,
571
+ skippedForeground,
572
+ skippedNonColor,
573
+ failedParse,
574
+ noForegroundVar,
575
+ pairsAnalyzed,
576
+ analyzedBackgrounds: analyzedBackgrounds.length,
577
+ });
578
+
537
579
  // Add white/black alternatives for all analyzed backgrounds
538
580
  const whiteRgb: RGB = { r: 255, g: 255, b: 255 };
539
581
  const blackRgb: RGB = { r: 0, g: 0, b: 0 };
@@ -627,6 +669,53 @@ export async function discoverTheme(projectRoot: string): Promise<DiscoveredThem
627
669
  return result;
628
670
  }
629
671
 
672
+ /**
673
+ * Get a human-readable description of a color based on its luminance and name
674
+ * This helps the LLM understand what colors look like visually
675
+ */
676
+ function getColorDescription(value: string, name: string): string {
677
+ const rgb = parseColorToRgb(value);
678
+ if (!rgb) return "";
679
+
680
+ const luminance = getLuminance(rgb);
681
+ const baseName = name.replace(/^--/, "");
682
+
683
+ // Very light colors (like white)
684
+ if (luminance > 0.9) {
685
+ if (baseName.includes("foreground")) {
686
+ return " (WHITE text)";
687
+ }
688
+ return " ⚠️ WHITE - do NOT use for buttons";
689
+ }
690
+
691
+ // Very dark colors
692
+ if (luminance < 0.1) {
693
+ if (baseName.includes("background")) {
694
+ return " (DARK background)";
695
+ }
696
+ return " (BLACK/DARK)";
697
+ }
698
+
699
+ // Semantic color guidance
700
+ if (baseName.includes("accent")) {
701
+ return " ✓ ACCENT - good for buttons/CTAs";
702
+ }
703
+ if (baseName.includes("success")) {
704
+ return " ✓ GREEN - good for positive actions";
705
+ }
706
+ if (baseName.includes("destructive")) {
707
+ return " ✓ RED - good for danger/delete";
708
+ }
709
+ if (baseName.includes("warning")) {
710
+ return " (ORANGE/YELLOW - caution)";
711
+ }
712
+ if (baseName.includes("primary") && luminance > 0.7) {
713
+ return " ⚠️ LIGHT - avoid for buttons on light backgrounds";
714
+ }
715
+
716
+ return "";
717
+ }
718
+
630
719
  /**
631
720
  * Format discovered theme as context for the LLM prompt
632
721
  * Includes contrast warnings to prevent bad color combinations
@@ -637,9 +726,15 @@ export function formatThemeForPrompt(theme: DiscoveredTheme): string {
637
726
  lines.push("**TARGET CODEBASE THEME (discovered):**");
638
727
  lines.push("");
639
728
 
729
+ // Quick reference for button colors
730
+ lines.push("BUTTON COLOR QUICK REFERENCE:");
731
+ lines.push(" ✓ Use for buttons: bg-accent, bg-success, bg-destructive");
732
+ lines.push(" ✗ Avoid for buttons: bg-primary (may be WHITE), bg-secondary (may be transparent)");
733
+ lines.push("");
734
+
640
735
  // CSS Variables
641
736
  if (Object.keys(theme.cssVariables).length > 0) {
642
- lines.push("CSS Variables:");
737
+ lines.push("COLOR TOKENS (with usage guidance):");
643
738
 
644
739
  // Group by category
645
740
  const categories: Record<string, string[]> = {
@@ -648,7 +743,10 @@ export function formatThemeForPrompt(theme: DiscoveredTheme): string {
648
743
  };
649
744
 
650
745
  for (const [name, value] of Object.entries(theme.cssVariables)) {
651
- const entry = ` ${name}: ${value}`;
746
+ // Add color description for important tokens
747
+ const description = getColorDescription(value, name);
748
+ const entry = ` ${name}: ${value}${description}`;
749
+
652
750
  if (
653
751
  name.includes("background") ||
654
752
  name.includes("foreground") ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonance-brand-mcp",
3
- "version": "1.3.67",
3
+ "version": "1.3.69",
4
4
  "description": "MCP Server for Sonance Brand Guidelines and Component Library - gives Claude instant access to brand colors, typography, and UI components.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",