/** * Edit matcher: resolve an Edit tool `old_string` against a file's content * via a tiered cascade. * * Tiers (short-circuit on the first that yields any match): * 1. exact — raw indexOf, caller handles multi-match based on replace_all * 2. line-trimmed — per-line trailing-whitespace tolerance; must be unique * 3. indentation-flexible — strips common leading indent on both sides, * also tolerates trailing whitespace; must be unique * * Also exports `findNearestMatch` for "did you mean...?" error hints when * no tier matches, and `reindentReplacement` for producing a replacement * string that respects the haystack's indentation when tier 3 matched. * * This module is intentionally pure and I/O-free so the cascade can be * exhaustively unit-tested without the filesystem. */ export type MatchResult = { kind: 'exact'; /** Char offset in haystack where the first match begins. */ startIndex: number; /** Length of the matched span (equals needle.length). */ matchedLength: number; /** Total number of exact occurrences in haystack. */ count: number; /** * 1-based line numbers where each match begins. Capped at the first * 3 entries (diagnostic use only; full count is in `count`). */ matchLines: number[]; } | { kind: 'line-trimmed'; startIndex: number; matchedLength: number; } | { kind: 'indentation-flexible'; startIndex: number; matchedLength: number; /** Common leading indent of the needle's non-empty lines. */ needleIndent: string; /** Common leading indent of the matched haystack window. */ haystackIndent: string; } | { kind: 'ambiguous'; tier: 'line-trimmed' | 'indentation-flexible'; count: number; /** 1-based line numbers, first 3. */ matchLines: number[]; } | { kind: 'none'; }; /** * Run the tiered matcher. Both arguments should already be line-ending * normalized (CRLF -> LF) by the caller. */ export declare function findMatch(haystack: string, needle: string): MatchResult; /** * Re-indent a replacement string so it fits the haystack's indentation * when tier 3 (indentation-flexible) matched. * * Strips up to `needleIndent` leading whitespace from each non-empty line * of `newString`, then prepends `haystackIndent`. Empty / whitespace-only * lines pass through untouched. */ export declare function reindentReplacement(newString: string, needleIndent: string, haystackIndent: string): string; export interface NearestMatch { /** 1-based line number of the best candidate. */ bestLine: number; /** Similarity ratio in [0, 1]. */ bestRatio: number; /** * Pre-formatted multi-line snippet with line numbers and an arrow on * the best candidate. Suitable for direct inclusion in an error message. */ snippet: string; } /** * Find the closest line in `haystack` to the first non-empty line of * `needle`, returning a diff-style snippet with ±3 lines of context. * Returns undefined when no reasonable candidate (ratio < 0.5) exists. */ export declare function findNearestMatch(haystack: string, needle: string): NearestMatch | undefined; //# sourceMappingURL=edit-matcher.d.ts.map