sonance-brand-mcp 1.3.84 → 1.3.86

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.
@@ -944,41 +944,41 @@ export async function POST(request: Request) {
944
944
  });
945
945
  }
946
946
 
947
- // CURSOR-STYLE: If focused element search has high confidence, use it directly
948
- // Skip the LLM guessing phase - we found the file that contains the code
949
- const HIGH_CONFIDENCE_THRESHOLD = 50; // Score of 50+ means we found exact matches
950
-
951
- if (focusedElementHints.length > 0 && focusedElementHints[0].score >= HIGH_CONFIDENCE_THRESHOLD) {
952
- // HIGH CONFIDENCE: Use focused element match directly
947
+ // IMPROVED: Relative scoring - compare focused element vs smart search
948
+ // This prevents false positives from generic element IDs in wrong files
949
+ const smartSearchTopScore = searchResults[0]?.score || 0;
950
+ const smartSearchTopPath = searchResults[0]?.path || null;
951
+ const focusedTopScore = focusedElementHints[0]?.score || 0;
952
+ const focusedTopPath = focusedElementHints[0]?.path || null;
953
+
954
+ // Check if Phase 2a match (component-name) is confirmed by focused element search
955
+ const phase2aConfirmed = phase2aMatches.length > 0 &&
956
+ focusedElementHints.some(h => phase2aMatches.includes(h.path) && h.score > 0);
957
+
958
+ if (phase2aConfirmed) {
959
+ // PRIORITY 1: Phase 2a match confirmed by element search - highest confidence
960
+ const confirmedPath = phase2aMatches.find(p =>
961
+ focusedElementHints.some(h => h.path === p && h.score > 0)
962
+ );
953
963
  recommendedFile = {
954
- path: focusedElementHints[0].path,
955
- reason: `Content search found element (score: ${focusedElementHints[0].score}, matches: ${focusedElementHints[0].matches.join(', ')})`
964
+ path: confirmedPath!,
965
+ reason: `Phase 2a component-name match confirmed by element search`
956
966
  };
957
- debugLog("HIGH CONFIDENCE: Using focused element match directly", recommendedFile);
958
- } else if (searchResults.length > 0) {
959
- // LOW CONFIDENCE: Fall back to LLM selection
960
- const candidateFiles = searchResults.slice(0, 10).map(r => r.path);
961
- const selectedFile = await selectBestFileFromList(
962
- screenshot,
963
- userPrompt,
964
- candidateFiles,
965
- apiKey,
966
- focusedElementHints
967
- );
968
-
969
- if (selectedFile) {
970
- recommendedFile = {
971
- path: selectedFile,
972
- reason: `LLM selected from ${candidateFiles.length} candidate files`
973
- };
974
- } else {
975
- // Fallback to highest score if LLM selection fails
976
- recommendedFile = {
977
- path: searchResults[0].path,
978
- reason: `Highest content match score (${searchResults[0].score} points)`
979
- };
980
- }
981
- debugLog("Recommended file for editing", recommendedFile);
967
+ debugLog("PRIORITY 1: Phase 2a confirmed by element search", recommendedFile);
968
+ } else if (focusedTopScore > smartSearchTopScore * 0.5 && focusedTopScore >= 400) {
969
+ // PRIORITY 2: Focused element has strong absolute score AND relative to smart search
970
+ recommendedFile = {
971
+ path: focusedTopPath!,
972
+ reason: `Focused element match (score: ${focusedTopScore}, exceeds threshold)`
973
+ };
974
+ debugLog("PRIORITY 2: Strong focused element match", recommendedFile);
975
+ } else if (smartSearchTopPath) {
976
+ // PRIORITY 3: Smart search top result - trusted baseline
977
+ recommendedFile = {
978
+ path: smartSearchTopPath,
979
+ reason: `Smart search top result (score: ${smartSearchTopScore})`
980
+ };
981
+ debugLog("PRIORITY 3: Using smart search top result", recommendedFile);
982
982
  }
983
983
 
984
984
  debugLog("Phase 1+2 complete", {
@@ -913,41 +913,41 @@ export async function POST(request: Request) {
913
913
  });
914
914
  }
915
915
 
916
- // CURSOR-STYLE: If focused element search has high confidence, use it directly
917
- // Skip the LLM guessing phase - we found the file that contains the code
918
- const HIGH_CONFIDENCE_THRESHOLD = 50; // Score of 50+ means we found exact matches
919
-
920
- if (focusedElementHints.length > 0 && focusedElementHints[0].score >= HIGH_CONFIDENCE_THRESHOLD) {
921
- // HIGH CONFIDENCE: Use focused element match directly
916
+ // IMPROVED: Relative scoring - compare focused element vs smart search
917
+ // This prevents false positives from generic element IDs in wrong files
918
+ const smartSearchTopScore = searchResults[0]?.score || 0;
919
+ const smartSearchTopPath = searchResults[0]?.path || null;
920
+ const focusedTopScore = focusedElementHints[0]?.score || 0;
921
+ const focusedTopPath = focusedElementHints[0]?.path || null;
922
+
923
+ // Check if Phase 2a match (component-name) is confirmed by focused element search
924
+ const phase2aConfirmed = phase2aMatches.length > 0 &&
925
+ focusedElementHints.some(h => phase2aMatches.includes(h.path) && h.score > 0);
926
+
927
+ if (phase2aConfirmed) {
928
+ // PRIORITY 1: Phase 2a match confirmed by element search - highest confidence
929
+ const confirmedPath = phase2aMatches.find(p =>
930
+ focusedElementHints.some(h => h.path === p && h.score > 0)
931
+ );
922
932
  recommendedFile = {
923
- path: focusedElementHints[0].path,
924
- reason: `Content search found element (score: ${focusedElementHints[0].score}, matches: ${focusedElementHints[0].matches.join(', ')})`
933
+ path: confirmedPath!,
934
+ reason: `Phase 2a component-name match confirmed by element search`
925
935
  };
926
- debugLog("HIGH CONFIDENCE: Using focused element match directly", recommendedFile);
927
- } else if (searchResults.length > 0) {
928
- // LOW CONFIDENCE: Fall back to LLM selection
929
- const candidateFiles = searchResults.slice(0, 10).map(r => r.path);
930
- const selectedFile = await selectBestFileFromList(
931
- screenshot,
932
- userPrompt,
933
- candidateFiles,
934
- apiKey,
935
- focusedElementHints
936
- );
937
-
938
- if (selectedFile) {
939
- recommendedFile = {
940
- path: selectedFile,
941
- reason: `LLM selected from ${candidateFiles.length} candidate files`
942
- };
943
- } else {
944
- // Fallback to highest score if LLM selection fails
945
- recommendedFile = {
946
- path: searchResults[0].path,
947
- reason: `Highest content match score (${searchResults[0].score} points)`
948
- };
949
- }
950
- debugLog("Recommended file for editing", recommendedFile);
936
+ debugLog("PRIORITY 1: Phase 2a confirmed by element search", recommendedFile);
937
+ } else if (focusedTopScore > smartSearchTopScore * 0.5 && focusedTopScore >= 400) {
938
+ // PRIORITY 2: Focused element has strong absolute score AND relative to smart search
939
+ recommendedFile = {
940
+ path: focusedTopPath!,
941
+ reason: `Focused element match (score: ${focusedTopScore}, exceeds threshold)`
942
+ };
943
+ debugLog("PRIORITY 2: Strong focused element match", recommendedFile);
944
+ } else if (smartSearchTopPath) {
945
+ // PRIORITY 3: Smart search top result - trusted baseline
946
+ recommendedFile = {
947
+ path: smartSearchTopPath,
948
+ reason: `Smart search top result (score: ${smartSearchTopScore})`
949
+ };
950
+ debugLog("PRIORITY 3: Using smart search top result", recommendedFile);
951
951
  }
952
952
 
953
953
  debugLog("Phase 1+2 complete", {
@@ -2582,7 +2582,15 @@ export function SonanceDevTools() {
2582
2582
  </div>
2583
2583
 
2584
2584
  {/* Content */}
2585
- <div className="flex-1 overflow-y-auto p-4 text-[#333F48]">
2585
+ <div
2586
+ className="flex-1 overflow-y-auto p-4 text-[#333F48]"
2587
+ style={{
2588
+ overscrollBehavior: "contain", // Prevent scroll chaining to parent (modal)
2589
+ WebkitOverflowScrolling: "touch", // Smooth scrolling on iOS
2590
+ }}
2591
+ onWheel={(e) => e.stopPropagation()} // Prevent modal from intercepting wheel events
2592
+ onTouchMove={(e) => e.stopPropagation()} // Prevent modal from intercepting touch scroll
2593
+ >
2586
2594
  {/* Analysis Tab */}
2587
2595
  {activeTab === "analysis" && (
2588
2596
  <AnalysisPanel
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonance-brand-mcp",
3
- "version": "1.3.84",
3
+ "version": "1.3.86",
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",