export interface TestImpactOptions { now?: () => number; } /** Names a module exports, from its source text. */ export declare function parseExports(source: string): Set; export interface EditImpact { /** Nearest test files reaching the changed file, relative to cwd, sorted. */ tests: string[]; /** Tests reaching it only through more layers of imports; counted, not listed. */ fartherTests: number; /** One shell command per package that runs exactly those tests. */ commands: string[]; /** Exports the edit removed that some importer still imports by name. */ brokenCallers: Array<{ name: string; importers: string[]; }>; } export declare class TestImpactIndex { private readonly cwd; private readonly entries; private readonly importers; private known; private scannedAt; private scanning; /** Export sets captured just before a tool write, keyed by absolute path. */ private readonly preWriteExports; /** Files whose reaching tests were already shown; later edits stay quiet. */ private readonly shown; private readonly runnerCache; private readonly now; constructor(cwd: string, options?: TestImpactOptions); /** Record a file's exports before a tool overwrites it. */ beforeWrite(absPath: string): Promise; /** * Model-facing note for a just-written file: the tests that reach it (first * edit of each file only) and importers left using a removed export (every * time). Empty when there is nothing to say. */ noteAfterWrite(absPath: string, content: string): Promise; /** Tests and commands covering a set of changed files (cwd-relative or absolute). */ impactFor(files: Iterable, brokenCallers?: EditImpact["brokenCallers"]): Promise; private isSource; private ensureScanned; /** * Source files under cwd, cwd-relative and sorted. `git ls-files` first: it * applies every nested .gitignore and never walks ignored trees (measured on * this repo: 17ms vs 12s for a directory walk that descends into build * output before filtering). The walk is the fallback outside a git checkout. */ private listSourceFiles; private scan; private resolveSpec; private updateEntry; private removeEntry; /** * Tests reaching `file`, nearest import layer first. A layer is added while * the running total stays at or under {@link MAX_COMMAND_TESTS}, and the * first layer that finds any test is always added. Without the cap a shared * hub (a session object most tests construct) makes a leaf helper "reach" * half the suite, and a list that long is a list nobody runs. `farther` * counts the reaching tests left out. */ private reachingTests; private brokenCallers; /** Nearest package.json's test runner (vitest or jest), walking up to cwd. */ private runnerFor; private commandsFor; } /** The note appended to a successful edit/write result. Empty when nothing applies. */ export declare function formatEditImpactNote(relPath: string, impact: EditImpact): string; /** One line for the verification demand: which tests reach the changed files, and how to run them. */ export declare function formatImpactForVerification(impact: EditImpact): string;