feat(TRUEREF-0006): implement SQLite FTS5 full-text search engine

- BM25 ranking via SQLite FTS5 bm25() function
- Query preprocessor with wildcard expansion and special char escaping
- Library search with composite scoring (name match, trust score, snippet count)
- Trust score computation from stars, coverage, and source type
- Response formatters for library and snippet results

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Giancarmine Salucci
2026-03-23 09:06:18 +01:00
parent f6be3cfd47
commit 33bdf30709
5 changed files with 1227 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
/**
* Trust score computation for repositories.
*
* Produces a composite score in [0, 10] that reflects the credibility and
* completeness of a repository's documentation.
*/
import type { Repository } from '$lib/types';
/**
* Compute a trust score (010) for a repository.
*
* Score components:
* - Stars : up to 4 points on a log10 scale (10 k stars = 4 pts)
* - Doc coverage : up to 3 points (500 snippets = 3 pts)
* - Source type : 1 point for GitHub repos
* - Indexed state: 1 point when state is "indexed"
* - Description : 1 point when a description is present
*/
export function computeTrustScore(repo: Repository): number {
let score = 0;
// Stars (up to 4 points): log scale, 10k stars ≈ 4 pts.
if (repo.stars) {
score += Math.min(4, Math.log10(repo.stars + 1));
}
// Documentation coverage (up to 3 points).
score += Math.min(3, (repo.totalSnippets ?? 0) / 500);
// Source type (1 point for GitHub).
if (repo.source === 'github') score += 1;
// Successful indexing (1 point).
if (repo.state === 'indexed') score += 1;
// Has description (1 point).
if (repo.description) score += 1;
return Math.min(10, parseFloat(score.toFixed(1)));
}