feat: search query utilities and multi-signal scoring
- Add src/search/query-utils.ts with extractSearchTerms, scorePathRelevance, kindBonus, detectApiIntent, inferRouteDirectories - Add multi-signal scoring to searchNodes (kind bonus + path relevance) - Improve FTS query sanitization (strip :^ chars, filter boolean operators) - Add comprehensive search tests
This commit is contained in:
+13
-1
@@ -18,6 +18,7 @@ import {
|
||||
SearchResult,
|
||||
} from '../types';
|
||||
import { safeJsonParse } from '../utils';
|
||||
import { kindBonus, scorePathRelevance } from '../search/query-utils';
|
||||
|
||||
/**
|
||||
* Database row types (snake_case from SQLite)
|
||||
@@ -451,6 +452,15 @@ export class QueryBuilder {
|
||||
results = this.searchNodesLike(query, { kinds, languages, limit, offset });
|
||||
}
|
||||
|
||||
// Apply multi-signal scoring
|
||||
if (results.length > 0 && query) {
|
||||
results = results.map(r => ({
|
||||
...r,
|
||||
score: r.score + kindBonus(r.node.kind) + scorePathRelevance(r.node.filePath, query),
|
||||
}));
|
||||
results.sort((a, b) => b.score - a.score);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -463,9 +473,11 @@ export class QueryBuilder {
|
||||
// Add prefix wildcard for better matching (e.g., "auth" matches "AuthService", "authenticate")
|
||||
// Escape special FTS5 characters and add prefix wildcard
|
||||
const ftsQuery = query
|
||||
.replace(/['"*()]/g, '') // Remove special chars
|
||||
.replace(/['"*():^]/g, '') // Remove FTS5 special chars
|
||||
.split(/\s+/)
|
||||
.filter(term => term.length > 0)
|
||||
// Strip FTS5 boolean operators to prevent query manipulation
|
||||
.filter(term => !/^(AND|OR|NOT|NEAR)$/i.test(term))
|
||||
.map(term => `"${term}"*`) // Prefix match each term
|
||||
.join(' OR ');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user