@mrxkun/mcfast-mcp 1.4.3 → 1.4.4
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.
- package/package.json +1 -1
- package/src/index.js +101 -38
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -560,52 +560,115 @@ async function handleSearchCode({ query, files, regex = false, caseSensitive = f
|
|
|
560
560
|
const start = Date.now();
|
|
561
561
|
try {
|
|
562
562
|
const results = [];
|
|
563
|
-
const flags = caseSensitive ? 'm' : 'im';
|
|
564
|
-
const pattern = regex ? new RegExp(query, flags) : null;
|
|
565
|
-
const queryLower = query.toLowerCase();
|
|
566
563
|
let totalInputChars = 0;
|
|
567
564
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
if (
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
565
|
+
// If regex mode, use original regex logic
|
|
566
|
+
if (regex) {
|
|
567
|
+
const flags = caseSensitive ? 'm' : 'im';
|
|
568
|
+
const pattern = new RegExp(query, flags);
|
|
569
|
+
|
|
570
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
571
|
+
if (typeof content !== 'string') continue;
|
|
572
|
+
totalInputChars += content.length;
|
|
573
|
+
|
|
574
|
+
const lines = content.split('\n');
|
|
575
|
+
lines.forEach((line, index) => {
|
|
576
|
+
if (pattern.test(line)) {
|
|
577
|
+
pattern.lastIndex = 0;
|
|
578
|
+
const startLine = Math.max(0, index - contextLines);
|
|
579
|
+
const endLine = Math.min(lines.length - 1, index + contextLines);
|
|
580
|
+
|
|
581
|
+
const contextSnippet = lines
|
|
582
|
+
.slice(startLine, endLine + 1)
|
|
583
|
+
.map((l, i) => ({
|
|
584
|
+
lineNumber: startLine + i + 1,
|
|
585
|
+
content: l,
|
|
586
|
+
isMatch: startLine + i === index
|
|
587
|
+
}));
|
|
588
|
+
|
|
589
|
+
results.push({
|
|
590
|
+
file: filePath,
|
|
591
|
+
lineNumber: index + 1,
|
|
592
|
+
matchedLine: line.trim(),
|
|
593
|
+
context: contextSnippet,
|
|
594
|
+
matchType: 'regex'
|
|
595
|
+
});
|
|
583
596
|
}
|
|
584
|
-
}
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
} else {
|
|
600
|
+
// Semantic search with stop words filtering
|
|
601
|
+
const queryLower = query.toLowerCase();
|
|
602
|
+
|
|
603
|
+
// Common English stop words to filter out
|
|
604
|
+
const stopWords = new Set([
|
|
605
|
+
'a', 'an', 'and', 'are', 'as', 'at', 'be', 'by', 'for', 'from', 'has', 'he',
|
|
606
|
+
'in', 'is', 'it', 'its', 'of', 'on', 'that', 'the', 'to', 'was', 'will', 'with',
|
|
607
|
+
'how', 'what', 'when', 'where', 'who', 'why', 'does', 'do', 'this', 'these', 'those'
|
|
608
|
+
]);
|
|
609
|
+
|
|
610
|
+
// Extract significant words (3+ chars, not stop words)
|
|
611
|
+
const words = queryLower
|
|
612
|
+
.split(/\W+/)
|
|
613
|
+
.filter(w => w.length >= 3 && !stopWords.has(w));
|
|
614
|
+
|
|
615
|
+
// If no significant words, fall back to whole query
|
|
616
|
+
const searchTerms = words.length > 0 ? words : [queryLower];
|
|
617
|
+
|
|
618
|
+
for (const [filePath, content] of Object.entries(files)) {
|
|
619
|
+
if (typeof content !== 'string') continue;
|
|
620
|
+
totalInputChars += content.length;
|
|
621
|
+
|
|
622
|
+
const lines = content.split('\n');
|
|
623
|
+
lines.forEach((line, index) => {
|
|
624
|
+
const lineLower = caseSensitive ? line : line.toLowerCase();
|
|
625
|
+
const searchQuery = caseSensitive ? query : queryLower;
|
|
626
|
+
|
|
627
|
+
// Check 1: Exact phrase match (highest priority)
|
|
628
|
+
const exactMatch = lineLower.includes(searchQuery);
|
|
629
|
+
|
|
630
|
+
// Check 2: All significant words present (semantic match)
|
|
631
|
+
const allWordsMatch = searchTerms.every(term => lineLower.includes(term));
|
|
632
|
+
|
|
633
|
+
// Check 3: At least half of significant words present (fuzzy match)
|
|
634
|
+
const matchCount = searchTerms.filter(term => lineLower.includes(term)).length;
|
|
635
|
+
const fuzzyMatch = matchCount >= Math.ceil(searchTerms.length / 2);
|
|
636
|
+
|
|
637
|
+
if (exactMatch || allWordsMatch || (searchTerms.length > 1 && fuzzyMatch)) {
|
|
638
|
+
const startLine = Math.max(0, index - contextLines);
|
|
639
|
+
const endLine = Math.min(lines.length - 1, index + contextLines);
|
|
640
|
+
|
|
641
|
+
const contextSnippet = lines
|
|
642
|
+
.slice(startLine, endLine + 1)
|
|
643
|
+
.map((l, i) => ({
|
|
644
|
+
lineNumber: startLine + i + 1,
|
|
645
|
+
content: l,
|
|
646
|
+
isMatch: startLine + i === index
|
|
647
|
+
}));
|
|
648
|
+
|
|
649
|
+
results.push({
|
|
650
|
+
file: filePath,
|
|
651
|
+
lineNumber: index + 1,
|
|
652
|
+
matchedLine: line.trim(),
|
|
653
|
+
context: contextSnippet,
|
|
654
|
+
matchType: exactMatch ? 'exact' : allWordsMatch ? 'semantic' : 'fuzzy',
|
|
655
|
+
matchScore: exactMatch ? 100 : allWordsMatch ? 80 : matchCount * 10
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
}
|
|
585
660
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
const contextSnippet = lines
|
|
591
|
-
.slice(startLine, endLine + 1)
|
|
592
|
-
.map((l, i) => ({
|
|
593
|
-
lineNumber: startLine + i + 1,
|
|
594
|
-
content: l,
|
|
595
|
-
isMatch: startLine + i === index
|
|
596
|
-
}));
|
|
597
|
-
|
|
598
|
-
results.push({
|
|
599
|
-
file: filePath,
|
|
600
|
-
lineNumber: index + 1,
|
|
601
|
-
matchedLine: line.trim(),
|
|
602
|
-
context: contextSnippet
|
|
603
|
-
});
|
|
661
|
+
// Sort results: by score (highest first), then by file
|
|
662
|
+
results.sort((a, b) => {
|
|
663
|
+
if (a.matchScore !== b.matchScore) {
|
|
664
|
+
return b.matchScore - a.matchScore;
|
|
604
665
|
}
|
|
666
|
+
return a.file.localeCompare(b.file);
|
|
605
667
|
});
|
|
606
668
|
}
|
|
607
669
|
|
|
608
|
-
|
|
670
|
+
const searchType = regex ? 'regex' : 'semantic';
|
|
671
|
+
let output = `🔍 Found ${results.length} matches for "${query}" (${searchType} search)\n\n`;
|
|
609
672
|
if (results.length === 0) {
|
|
610
673
|
output += "No matches found in provided context.";
|
|
611
674
|
} else {
|