sonance-brand-mcp 1.3.59 → 1.3.60

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.
@@ -511,48 +511,81 @@ function searchFilesSmart(
511
511
  return sortedResults.map(r => ({ path: r.path, content: r.content, score: r.score }));
512
512
  }
513
513
 
514
- const VISION_SYSTEM_PROMPT = `You are a code editor. Make ONLY the change the user requested.
514
+ const VISION_SYSTEM_PROMPT = `You are a code editor like Cursor. Before making changes, REASON about what needs to be done.
515
+
516
+ ═══════════════════════════════════════════════════════════════════════════════
517
+ STEP 1: ANALYZE (Think like Cursor)
518
+ ═══════════════════════════════════════════════════════════════════════════════
519
+
520
+ Before writing any patches, analyze the screenshot and answer:
521
+
522
+ 1. CURRENT STATE: What do I see in the screenshot?
523
+ - Is the element visible/readable right now?
524
+ - What colors/styles are currently applied?
525
+
526
+ 2. PROBLEM IDENTIFICATION: What's actually wrong?
527
+ - Contrast issue? (text blending with background)
528
+ - Hidden element? (not showing at all)
529
+ - Hover state issue? (only visible on interaction)
530
+ - Layout issue? (wrong size/position)
531
+ - Or is it already correct?
532
+
533
+ 3. FIX STRATEGY: What should I change?
534
+ - DEFAULT state only (element needs to look different normally)
535
+ - HOVER state only (element needs different hover effect)
536
+ - BOTH states (element needs overall visibility improvement)
537
+ - ASK for clarification (request is too vague)
538
+
539
+ ═══════════════════════════════════════════════════════════════════════════════
540
+ STEP 2: GENERATE PATCHES (Only after reasoning)
541
+ ═══════════════════════════════════════════════════════════════════════════════
542
+
543
+ CRITICAL - FILE SELECTION:
544
+ - You MUST modify the file marked "TARGET COMPONENT" - this is the file you have FULL visibility into
545
+ - Do NOT try to modify other files listed in context - you only see their imports/exports, not full content
546
+ - If the TARGET COMPONENT is not the right file, return clarification_needed
547
+
548
+ COPY EXACTLY from the TARGET COMPONENT section:
549
+ - Your "search" string must match the file CHARACTER-FOR-CHARACTER
550
+ - Include exact indentation and at least 3 lines of context
551
+ - If the element looks FINE in the screenshot, say so
515
552
 
516
553
  RULES:
517
- 1. Make the SMALLEST possible change to accomplish the request
518
- 2. Do NOT refactor, rebrand, or "improve" anything else
519
- 3. Do NOT change import statements unless explicitly required
520
- 4. Do NOT change component libraries (e.g., heroui to shadcn)
521
- 5. If fixing a color/visibility issue, change ONLY that element's classes
522
- 6. Your patch should typically be 1-5 lines, not 50+
523
- 7. NEVER invent or guess code - your "search" string MUST match the file EXACTLY
524
- 8. NEVER change data mappings (icon names, keys, enum values) unless user explicitly provides the new values
525
- 9. If you don't know what values exist in a database or data source, DO NOT guess - ask for clarification
526
-
527
- CRITICAL - ELEMENT VERIFICATION:
528
- - When a focused element is mentioned, SEARCH the provided file content for that EXACT element
529
- - Look for the actual JSX/HTML code: <button, <Button, <div, className, onClick, etc.
530
- - If you cannot find the element in the TARGET COMPONENT section, it may be in a child component
531
- - NEVER guess what element code looks like - find it in the file or report "element not found"
532
- - If the element is not in the provided file, return: {"modifications": [], "explanation": "The focused element appears to be in a child component, not in [filename]"}
533
-
534
- CRITICAL - DATA INTEGRITY:
535
- - If code references database values (like icon_name, type, status), DO NOT change the mapping keys
536
- - You cannot see database content - only change STRUCTURE, not DATA MAPPINGS
537
- - Example: If you see iconMap["EyeOff"] = SomeIcon, do NOT change "EyeOff" to something else
538
- - If user wants different icons, they must tell you the EXACT icon names they want
539
-
540
- PATCH FORMAT:
541
- Return ONLY raw JSON (no markdown, no preamble):
554
+ 1. Make the SMALLEST possible change
555
+ 2. Do NOT refactor or "improve" other code
556
+ 3. NEVER invent code - COPY exact code from file
557
+ 4. NEVER change data mappings unless user provides new values
558
+ 5. If visibility issue: prefer explicit colors (text-white, text-black) over semantic tokens
559
+
560
+ ═══════════════════════════════════════════════════════════════════════════════
561
+ RESPONSE FORMAT
562
+ ═══════════════════════════════════════════════════════════════════════════════
563
+
564
+ Return ONLY raw JSON:
542
565
  {
543
- "reasoning": "brief explanation",
566
+ "analysis": {
567
+ "currentState": "what I see in the screenshot",
568
+ "problem": "the actual issue (or 'none - element appears correct')",
569
+ "fixStrategy": "default|hover|both|clarification_needed"
570
+ },
571
+ "reasoning": "my diagnosis and approach",
544
572
  "modifications": [{
545
573
  "filePath": "path/to/file.tsx",
546
574
  "patches": [{
547
- "search": "exact original code (copy from provided file)",
548
- "replace": "minimal change",
549
- "explanation": "what this does"
575
+ "search": "EXACT copy from file",
576
+ "replace": "changed code",
577
+ "explanation": "what this changes and why"
550
578
  }]
551
579
  }],
552
- "explanation": "summary"
580
+ "explanation": "summary of what was changed"
553
581
  }
554
582
 
555
- If you cannot find the exact code to modify, OR if you would need to guess data values, return empty modifications array with explanation.`;
583
+ If the element looks correct, return:
584
+ {
585
+ "analysis": { "currentState": "...", "problem": "none", "fixStrategy": "clarification_needed" },
586
+ "modifications": [],
587
+ "explanation": "The element appears visible/correct in the screenshot. Please specify what needs to change."
588
+ }`;
556
589
 
557
590
  export async function POST(request: Request) {
558
591
  // Only allow in development
@@ -875,30 +908,59 @@ ${truncatedContent}${wasTruncated ? "\n// ... (truncated)" : ""}
875
908
 
876
909
  // ========== THEME DISCOVERY (REFERENCE ONLY) ==========
877
910
  // Dynamically discover theme tokens from the target codebase
878
- // This is marked as REFERENCE ONLY so the LLM doesn't use it to justify extra changes
879
911
  const discoveredTheme = await discoverTheme(projectRoot);
880
912
  const themeContext = formatThemeForPrompt(discoveredTheme);
881
913
 
914
+ // Check if this is a visibility-related request
915
+ const isVisibilityRequest = /visible|can't see|cant see|not visible|hidden|color|contrast/i.test(userPrompt);
916
+
882
917
  if (discoveredTheme.discoveredFiles.length > 0) {
883
- textContent += `
918
+ // Only include detailed color guidance for visibility requests
919
+ if (isVisibilityRequest) {
920
+ // Extract available text color classes from discovered theme
921
+ const textColorClasses = Object.keys(discoveredTheme.cssVariables)
922
+ .filter(key => key.includes('foreground') || key.includes('text'))
923
+ .map(key => `text-${key.replace('--', '').replace(/-/g, '-')}`)
924
+ .slice(0, 10);
925
+
926
+ textContent += `
884
927
  ═══════════════════════════════════════════════════════════════════════════════
885
- REFERENCE ONLY (do not use this to justify additional changes)
928
+ COLOR FIX GUIDANCE (for visibility issues only)
886
929
  ═══════════════════════════════════════════════════════════════════════════════
887
930
 
888
- If you need to pick a color for a VISIBILITY fix, these are safe choices:
889
- - bg-accent text-white (cyan button with white text)
890
- - bg-primary text-white (charcoal button with white text)
891
- - bg-success text-white (green button with white text)
892
- - bg-destructive text-white (red button with white text)
931
+ AVAILABLE TEXT COLORS (use these for contrast fixes):
932
+ - text-white (always visible on dark backgrounds)
933
+ - text-black (always visible on light backgrounds)
934
+ - text-foreground (theme default)
935
+ - text-primary-foreground (for bg-primary)
936
+ - text-accent-foreground (for bg-accent - CHECK IF THIS HAS GOOD CONTRAST)
937
+ - text-destructive-foreground (for bg-destructive)
938
+
939
+ SAFE BUTTON PATTERNS:
940
+ - bg-accent text-white (cyan button, guaranteed visible)
941
+ - bg-primary text-white (charcoal button, guaranteed visible)
942
+ - bg-destructive text-white (red button, guaranteed visible)
943
+ - bg-muted text-foreground (gray button, guaranteed visible)
893
944
 
894
- But ONLY use these if the user is asking for a color/visibility change.
895
- Do NOT rebrand or change other elements to match.
945
+ IMPORTANT: If current code has text-accent-foreground or similar semantic colors
946
+ that result in poor contrast, REPLACE with text-white or text-black.
896
947
 
897
948
  `;
949
+ } else {
950
+ // For non-visibility requests, minimal reference
951
+ textContent += `
952
+ ═══════════════════════════════════════════════════════════════════════════════
953
+ REFERENCE ONLY (do not use this to justify additional changes)
954
+ ═══════════════════════════════════════════════════════════════════════════════
955
+ Theme discovered from: ${discoveredTheme.discoveredFiles.join(', ')}
956
+ `;
957
+ }
958
+
898
959
  debugLog("Theme discovery complete", {
899
960
  filesFound: discoveredTheme.discoveredFiles,
900
961
  cssVariableCount: Object.keys(discoveredTheme.cssVariables).length,
901
962
  tailwindColorCount: Object.keys(discoveredTheme.tailwindColors).length,
963
+ isVisibilityRequest,
902
964
  });
903
965
  }
904
966
 
@@ -1043,6 +1105,11 @@ This is better than generating patches with made-up code.`,
1043
1105
 
1044
1106
  // Parse AI response - now expecting patches instead of full file content
1045
1107
  let aiResponse: {
1108
+ analysis?: {
1109
+ currentState?: string;
1110
+ problem?: string;
1111
+ fixStrategy?: string;
1112
+ };
1046
1113
  reasoning?: string;
1047
1114
  modifications: Array<{
1048
1115
  filePath: string;
@@ -1090,9 +1157,31 @@ This is better than generating patches with made-up code.`,
1090
1157
  );
1091
1158
  }
1092
1159
 
1160
+ // Log the LLM's analysis/reasoning (like Cursor showing its thought process)
1161
+ if (aiResponse.analysis) {
1162
+ debugLog("LLM Analysis (Step 1)", {
1163
+ currentState: aiResponse.analysis.currentState,
1164
+ problem: aiResponse.analysis.problem,
1165
+ fixStrategy: aiResponse.analysis.fixStrategy,
1166
+ });
1167
+ }
1168
+
1093
1169
  finalExplanation = aiResponse.explanation;
1094
1170
  finalReasoning = aiResponse.reasoning;
1095
1171
 
1172
+ // If LLM says clarification is needed, return that to the user
1173
+ if (aiResponse.analysis?.fixStrategy === "clarification_needed" &&
1174
+ (!aiResponse.modifications || aiResponse.modifications.length === 0)) {
1175
+ return NextResponse.json({
1176
+ success: true,
1177
+ sessionId: newSessionId,
1178
+ needsClarification: true,
1179
+ analysis: aiResponse.analysis,
1180
+ explanation: aiResponse.explanation || "The element appears correct. Please specify what needs to change.",
1181
+ modifications: [],
1182
+ });
1183
+ }
1184
+
1096
1185
  if (!aiResponse.modifications || aiResponse.modifications.length === 0) {
1097
1186
  return NextResponse.json({
1098
1187
  success: true,
@@ -1131,6 +1220,19 @@ This is better than generating patches with made-up code.`,
1131
1220
  continue;
1132
1221
  }
1133
1222
 
1223
+ // CRITICAL: Warn if LLM is trying to modify a file OTHER than the TARGET COMPONENT
1224
+ // This usually means the LLM is trying to modify a file it doesn't have full visibility into
1225
+ const targetComponentPath = recommendedFileContent?.path;
1226
+ if (targetComponentPath && mod.filePath !== targetComponentPath) {
1227
+ debugLog("WARNING: LLM trying to modify non-target file", {
1228
+ targetComponent: targetComponentPath,
1229
+ attemptedFile: mod.filePath,
1230
+ warning: "LLM may be hallucinating code since it only has full content of the TARGET COMPONENT"
1231
+ });
1232
+ console.warn(`[Apply-First] ⚠️ LLM is modifying ${mod.filePath} but TARGET COMPONENT is ${targetComponentPath}`);
1233
+ console.warn(`[Apply-First] ⚠️ This may cause hallucination since LLM only has full visibility into the TARGET COMPONENT`);
1234
+ }
1235
+
1134
1236
  const fullPath = path.join(projectRoot, mod.filePath);
1135
1237
  let originalContent = "";
1136
1238
  if (fs.existsSync(fullPath)) {
@@ -1206,6 +1308,34 @@ This is better than generating patches with made-up code.`,
1206
1308
  modifiedContent = patchResult.modifiedContent;
1207
1309
  console.log(`[Apply-First] All ${mod.patches.length} patches applied successfully to ${mod.filePath}`);
1208
1310
  }
1311
+
1312
+ // SYNTAX VALIDATION: Check for common JSX/HTML tag mismatches
1313
+ // This catches cases where the LLM changes opening tags but not closing tags
1314
+ if (mod.filePath.endsWith('.tsx') || mod.filePath.endsWith('.jsx')) {
1315
+ const openDivs = (modifiedContent.match(/<div[\s>]/g) || []).length;
1316
+ const closeDivs = (modifiedContent.match(/<\/div>/g) || []).length;
1317
+ const openSpans = (modifiedContent.match(/<span[\s>]/g) || []).length;
1318
+ const closeSpans = (modifiedContent.match(/<\/span>/g) || []).length;
1319
+
1320
+ if (openDivs !== closeDivs || openSpans !== closeSpans) {
1321
+ debugLog("SYNTAX WARNING: Tag mismatch detected", {
1322
+ filePath: mod.filePath,
1323
+ divs: { open: openDivs, close: closeDivs },
1324
+ spans: { open: openSpans, close: closeSpans },
1325
+ });
1326
+ console.warn(`[Apply-First] ⚠️ SYNTAX WARNING: Tag mismatch in ${mod.filePath}`);
1327
+ console.warn(`[Apply-First] divs: ${openDivs} open, ${closeDivs} close`);
1328
+ console.warn(`[Apply-First] spans: ${openSpans} open, ${closeSpans} close`);
1329
+
1330
+ // If there's a significant mismatch, reject the change
1331
+ const divDiff = Math.abs(openDivs - closeDivs);
1332
+ const spanDiff = Math.abs(openSpans - closeSpans);
1333
+ if (divDiff > 0 || spanDiff > 0) {
1334
+ patchErrors.push(`${mod.filePath}: LLM introduced syntax error - tag mismatch detected (${divDiff} div, ${spanDiff} span). Change rejected.`);
1335
+ continue;
1336
+ }
1337
+ }
1338
+ }
1209
1339
  } else if (mod.modifiedContent) {
1210
1340
  // Legacy: AI returned full file content
1211
1341
  console.warn(`[Apply-First] Legacy modifiedContent received for ${mod.filePath} - patch-based format preferred`);
@@ -507,50 +507,83 @@ function searchFilesSmart(
507
507
  return sortedResults.map(r => ({ path: r.path, content: r.content, score: r.score }));
508
508
  }
509
509
 
510
- const VISION_SYSTEM_PROMPT = `You are a code editor. Make ONLY the change the user requested.
510
+ const VISION_SYSTEM_PROMPT = `You are a code editor like Cursor. Before making changes, REASON about what needs to be done.
511
+
512
+ ═══════════════════════════════════════════════════════════════════════════════
513
+ STEP 1: ANALYZE (Think like Cursor)
514
+ ═══════════════════════════════════════════════════════════════════════════════
515
+
516
+ Before writing any patches, analyze the screenshot and answer:
517
+
518
+ 1. CURRENT STATE: What do I see in the screenshot?
519
+ - Is the element visible/readable right now?
520
+ - What colors/styles are currently applied?
521
+
522
+ 2. PROBLEM IDENTIFICATION: What's actually wrong?
523
+ - Contrast issue? (text blending with background)
524
+ - Hidden element? (not showing at all)
525
+ - Hover state issue? (only visible on interaction)
526
+ - Layout issue? (wrong size/position)
527
+ - Or is it already correct?
528
+
529
+ 3. FIX STRATEGY: What should I change?
530
+ - DEFAULT state only (element needs to look different normally)
531
+ - HOVER state only (element needs different hover effect)
532
+ - BOTH states (element needs overall visibility improvement)
533
+ - ASK for clarification (request is too vague)
534
+
535
+ ═══════════════════════════════════════════════════════════════════════════════
536
+ STEP 2: GENERATE PATCHES (Only after reasoning)
537
+ ═══════════════════════════════════════════════════════════════════════════════
538
+
539
+ CRITICAL - FILE SELECTION:
540
+ - You MUST modify the file marked "TARGET COMPONENT" - this is the file you have FULL visibility into
541
+ - Do NOT try to modify other files listed in context - you only see their imports/exports, not full content
542
+ - If the TARGET COMPONENT is not the right file, return clarification_needed
543
+
544
+ COPY EXACTLY from the TARGET COMPONENT section:
545
+ - Your "search" string must match the file CHARACTER-FOR-CHARACTER
546
+ - Include exact indentation and at least 3 lines of context
547
+ - If the element looks FINE in the screenshot, say so
511
548
 
512
549
  RULES:
513
- 1. Make the SMALLEST possible change to accomplish the request
514
- 2. Do NOT refactor, rebrand, or "improve" anything else
515
- 3. Do NOT change import statements unless explicitly required
516
- 4. Do NOT change component libraries (e.g., heroui to shadcn)
517
- 5. If fixing a color/visibility issue, change ONLY that element's classes
518
- 6. Your patch should typically be 1-5 lines, not 50+
519
- 7. NEVER invent or guess code - your "search" string MUST match the file EXACTLY
520
- 8. NEVER change data mappings (icon names, keys, enum values) unless user explicitly provides the new values
521
- 9. If you don't know what values exist in a database or data source, DO NOT guess - ask for clarification
522
-
523
- CRITICAL - ELEMENT VERIFICATION:
524
- - When a focused element is mentioned, SEARCH the provided file content for that EXACT element
525
- - Look for the actual JSX/HTML code: <button, <Button, <div, className, onClick, etc.
526
- - If you cannot find the element in the TARGET COMPONENT section, it may be in a child component
527
- - NEVER guess what element code looks like - find it in the file or report "element not found"
528
- - If the element is not in the provided file, return: {"modifications": [], "explanation": "The focused element appears to be in a child component, not in [filename]"}
529
-
530
- CRITICAL - DATA INTEGRITY:
531
- - If code references database values (like icon_name, type, status), DO NOT change the mapping keys
532
- - You cannot see database content - only change STRUCTURE, not DATA MAPPINGS
533
- - Example: If you see iconMap["EyeOff"] = SomeIcon, do NOT change "EyeOff" to something else
534
- - If user wants different icons, they must tell you the EXACT icon names they want
535
-
536
- PATCH FORMAT:
537
- Return ONLY raw JSON (no markdown, no preamble):
550
+ 1. Make the SMALLEST possible change
551
+ 2. Do NOT refactor or "improve" other code
552
+ 3. NEVER invent code - COPY exact code from file
553
+ 4. NEVER change data mappings unless user provides new values
554
+ 5. If visibility issue: prefer explicit colors (text-white, text-black) over semantic tokens
555
+
556
+ ═══════════════════════════════════════════════════════════════════════════════
557
+ RESPONSE FORMAT
558
+ ═══════════════════════════════════════════════════════════════════════════════
559
+
560
+ Return ONLY raw JSON:
538
561
  {
539
- "reasoning": "brief explanation",
562
+ "analysis": {
563
+ "currentState": "what I see in the screenshot",
564
+ "problem": "the actual issue (or 'none - element appears correct')",
565
+ "fixStrategy": "default|hover|both|clarification_needed"
566
+ },
567
+ "reasoning": "my diagnosis and approach",
540
568
  "modifications": [{
541
569
  "filePath": "path/to/file.tsx",
542
570
  "patches": [{
543
- "search": "exact original code (copy from provided file)",
544
- "replace": "minimal change",
545
- "explanation": "what this does"
571
+ "search": "EXACT copy from file",
572
+ "replace": "changed code",
573
+ "explanation": "what this changes and why"
546
574
  }],
547
575
  "previewCSS": "optional CSS for live preview"
548
576
  }],
549
577
  "aggregatedPreviewCSS": "combined CSS for all changes",
550
- "explanation": "summary"
578
+ "explanation": "summary of what was changed"
551
579
  }
552
580
 
553
- If you cannot find the exact code to modify, OR if you would need to guess data values, return empty modifications array with explanation.`;
581
+ If the element looks correct, return:
582
+ {
583
+ "analysis": { "currentState": "...", "problem": "none", "fixStrategy": "clarification_needed" },
584
+ "modifications": [],
585
+ "explanation": "The element appears visible/correct in the screenshot. Please specify what needs to change."
586
+ }`;
554
587
 
555
588
  export async function POST(request: Request) {
556
589
  // Only allow in development
@@ -846,30 +879,59 @@ ${truncatedContent}${wasTruncated ? "\n// ... (truncated)" : ""}
846
879
 
847
880
  // ========== THEME DISCOVERY (REFERENCE ONLY) ==========
848
881
  // Dynamically discover theme tokens from the target codebase
849
- // This is marked as REFERENCE ONLY so the LLM doesn't use it to justify extra changes
850
882
  const discoveredTheme = await discoverTheme(projectRoot);
851
883
  const themeContext = formatThemeForPrompt(discoveredTheme);
852
884
 
885
+ // Check if this is a visibility-related request
886
+ const isVisibilityRequest = /visible|can't see|cant see|not visible|hidden|color|contrast/i.test(userPrompt);
887
+
853
888
  if (discoveredTheme.discoveredFiles.length > 0) {
854
- textContent += `
889
+ // Only include detailed color guidance for visibility requests
890
+ if (isVisibilityRequest) {
891
+ // Extract available text color classes from discovered theme
892
+ const textColorClasses = Object.keys(discoveredTheme.cssVariables)
893
+ .filter(key => key.includes('foreground') || key.includes('text'))
894
+ .map(key => `text-${key.replace('--', '').replace(/-/g, '-')}`)
895
+ .slice(0, 10);
896
+
897
+ textContent += `
855
898
  ═══════════════════════════════════════════════════════════════════════════════
856
- REFERENCE ONLY (do not use this to justify additional changes)
899
+ COLOR FIX GUIDANCE (for visibility issues only)
857
900
  ═══════════════════════════════════════════════════════════════════════════════
858
901
 
859
- If you need to pick a color for a VISIBILITY fix, these are safe choices:
860
- - bg-accent text-white (cyan button with white text)
861
- - bg-primary text-white (charcoal button with white text)
862
- - bg-success text-white (green button with white text)
863
- - bg-destructive text-white (red button with white text)
902
+ AVAILABLE TEXT COLORS (use these for contrast fixes):
903
+ - text-white (always visible on dark backgrounds)
904
+ - text-black (always visible on light backgrounds)
905
+ - text-foreground (theme default)
906
+ - text-primary-foreground (for bg-primary)
907
+ - text-accent-foreground (for bg-accent - CHECK IF THIS HAS GOOD CONTRAST)
908
+ - text-destructive-foreground (for bg-destructive)
864
909
 
865
- But ONLY use these if the user is asking for a color/visibility change.
866
- Do NOT rebrand or change other elements to match.
910
+ SAFE BUTTON PATTERNS:
911
+ - bg-accent text-white (cyan button, guaranteed visible)
912
+ - bg-primary text-white (charcoal button, guaranteed visible)
913
+ - bg-destructive text-white (red button, guaranteed visible)
914
+ - bg-muted text-foreground (gray button, guaranteed visible)
867
915
 
916
+ IMPORTANT: If current code has text-accent-foreground or similar semantic colors
917
+ that result in poor contrast, REPLACE with text-white or text-black.
918
+
919
+ `;
920
+ } else {
921
+ // For non-visibility requests, minimal reference
922
+ textContent += `
923
+ ═══════════════════════════════════════════════════════════════════════════════
924
+ REFERENCE ONLY (do not use this to justify additional changes)
925
+ ═══════════════════════════════════════════════════════════════════════════════
926
+ Theme discovered from: ${discoveredTheme.discoveredFiles.join(', ')}
868
927
  `;
928
+ }
929
+
869
930
  debugLog("Theme discovery complete", {
870
931
  filesFound: discoveredTheme.discoveredFiles,
871
932
  cssVariableCount: Object.keys(discoveredTheme.cssVariables).length,
872
933
  tailwindColorCount: Object.keys(discoveredTheme.tailwindColors).length,
934
+ isVisibilityRequest,
873
935
  });
874
936
  }
875
937
 
@@ -1010,6 +1072,11 @@ This is better than generating patches with made-up code.`,
1010
1072
 
1011
1073
  // Parse AI response - now expecting patches instead of full file content
1012
1074
  let aiResponse: {
1075
+ analysis?: {
1076
+ currentState?: string;
1077
+ problem?: string;
1078
+ fixStrategy?: string;
1079
+ };
1013
1080
  reasoning?: string;
1014
1081
  modifications: Array<{
1015
1082
  filePath: string;
@@ -1061,10 +1128,31 @@ This is better than generating patches with made-up code.`,
1061
1128
  );
1062
1129
  }
1063
1130
 
1131
+ // Log the LLM's analysis/reasoning (like Cursor showing its thought process)
1132
+ if (aiResponse.analysis) {
1133
+ debugLog("LLM Analysis (Step 1)", {
1134
+ currentState: aiResponse.analysis.currentState,
1135
+ problem: aiResponse.analysis.problem,
1136
+ fixStrategy: aiResponse.analysis.fixStrategy,
1137
+ });
1138
+ }
1139
+
1064
1140
  finalExplanation = aiResponse.explanation;
1065
1141
  finalReasoning = aiResponse.reasoning;
1066
1142
  finalAggregatedCSS = aiResponse.aggregatedPreviewCSS;
1067
1143
 
1144
+ // If LLM says clarification is needed, return that to the user
1145
+ if (aiResponse.analysis?.fixStrategy === "clarification_needed" &&
1146
+ (!aiResponse.modifications || aiResponse.modifications.length === 0)) {
1147
+ return NextResponse.json({
1148
+ success: true,
1149
+ needsClarification: true,
1150
+ analysis: aiResponse.analysis,
1151
+ explanation: aiResponse.explanation || "The element appears correct. Please specify what needs to change.",
1152
+ modifications: [],
1153
+ });
1154
+ }
1155
+
1068
1156
  debugLog("VALIDATION: Known file paths from page context", {
1069
1157
  pageFile: pageContext.pageFile,
1070
1158
  knownPaths: Array.from(knownPaths),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonance-brand-mcp",
3
- "version": "1.3.59",
3
+ "version": "1.3.60",
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",