/** * Exact-match-first ranking for object searches. * * Defect #15 (2026-07-21 sweep): `search(type="edt", query="Num")` at limit=40 * never surfaced the EDT `Num` — the result window was filled with `NumberOf*` / * `Numeric*` prefix hits. Neither backing search ranks by match quality: * • the C# bridge scans provider primary keys in provider order and stops at * `Results.Count >= maxResults` (MetadataReadService.SearchObjects), and * • the SQLite path orders by FTS5 `rank`, which is a token-frequency score, * not a name-equality score. * So a short exact name that happens to sort/enumerate late is invisible. * * PERFORMANCE NOTE: ranking here is pure in-memory work over an already-bounded * result window — it never widens a SQL query. The companion "the exact match * was outside the window" probe must stay index-safe; see * `lookupSymbolsNocase` in utils/symbolLookup.ts (exact-case probe on * idx_name_type, bounded FTS phrase fallback — never `LIKE` and never * `COLLATE NOCASE` as the primary predicate). */ /** Lower is better. 0 = exact, 1 = exact ignoring case, 2 = prefix, 3 = everything else. */ export declare function exactMatchRank(query: string, name: string): 0 | 1 | 2 | 3; /** True when `name` equals `query` ignoring case. */ export declare function isExactNameMatch(query: string, name: string): boolean; /** * Stable sort putting exact name matches first, then case-insensitive exact, * then prefix matches, leaving the backing search's own order intact within * each band (so bridge/FTS relevance is preserved where it says nothing about * name equality). */ export declare function rankExactFirst(query: string, items: T[], nameOf: (item: T) => string): T[]; /** * Ranking that keeps exact-name matches first but additionally prioritizes * custom/ISV-model symbols directly after them, ahead of the far larger * Microsoft standard corpus. * * Motivation: a broad keyword fills the C# bridge's fixed result window * (`maxResults`) in provider-enumeration order, which is dominated by Microsoft * standard objects, so custom matches that enumerate later get truncated and * the search appears to "return only Microsoft objects". Surfacing custom hits * into their own band guarantees they are visible regardless of window size. * * Tiers (lower first): * 0 = exact name match (any model — an exact Microsoft hit still wins) * 1 = custom-model hit * 2 = everything else * Within a tier the name-quality rank and original order are preserved (stable), * so bridge/FTS relevance is untouched where it says nothing about equality. */ export declare function rankCustomFirst(query: string, items: T[], nameOf: (item: T) => string, isCustom: (item: T) => boolean): T[]; //# sourceMappingURL=exactMatchRanking.d.ts.map