// Planu — Prior Decision Searcher (SPEC-615)
// Scores decisions by keyword overlap against a spec description/title.
// Algorithm: BM25-ish token overlap — score = overlap / (overlap + 10)
const TOP_N = 5;
/**
 * Tokenise a string into lower-case alphanumeric tokens (≥3 chars).
 */
function tokenize(text) {
    return new Set(text
        .toLowerCase()
        .split(/\W+/)
        .filter((t) => t.length >= 3));
}
/**
 * BM25-ish relevance: overlap / (overlap + 10).
 * Returns 0 when there is no overlap at all.
 */
function score(queryTokens, docTokens) {
    let overlap = 0;
    for (const t of queryTokens) {
        if (docTokens.has(t)) {
            overlap++;
        }
    }
    if (overlap === 0) {
        return 0;
    }
    return overlap / (overlap + 10);
}
/**
 * Search a decision array for decisions relevant to the given query text.
 *
 * @param query     - spec title + description combined
 * @param decisions - full decision list from decisionStore
 * @param topN      - max results to return (default 5)
 * @returns         - scored links, sorted descending, score > 0 only
 */
export function searchPriorDecisions(query, decisions, topN = TOP_N) {
    const queryTokens = tokenize(query);
    if (queryTokens.size === 0) {
        return [];
    }
    const results = [];
    for (const d of decisions) {
        // Skip superseded decisions — they are no longer authoritative
        if (d.status === 'superseded') {
            continue;
        }
        const docText = `${d.what} ${d.why} ${d.alternatives.join(' ')}`;
        const docTokens = tokenize(docText);
        const s = score(queryTokens, docTokens);
        if (s > 0) {
            results.push({
                decisionId: d.id,
                title: d.what,
                relevanceScore: Math.round(s * 100) / 100,
                rationale: d.why.slice(0, 200),
            });
        }
    }
    return results.sort((a, b) => b.relevanceScore - a.relevanceScore).slice(0, topN);
}
//# sourceMappingURL=searcher.js.map