import type { ParseCodeFilesResult } from './build.js';
import { type DiscoverCodeOptions } from './discover.js';
import type { CodeSkippedFile, ParsedFile } from './types.js';
import type { SourceInlineManifestEntry } from './source-inline.js';
/**
 * One indexed file as recorded in the cache manifest. The manifest covers
 * every file the index saw — parsed and guardrail-skipped alike — so a
 * freshness check never mistakes a skipped file for a new one.
 */
export interface ManifestEntry extends SourceInlineManifestEntry {
    mtimeMs: number;
}
export interface ChangedFileStat {
    path: string;
    relativePath: string;
    size: number;
    mtimeMs: number;
}
export interface ManifestDiff {
    added: ChangedFileStat[];
    modified: ChangedFileStat[];
    deleted: Array<{
        path: string;
        relativePath: string;
    }>;
    hasChanges: boolean;
}
/**
 * Diff the manifest against a full discovery pass: files on disk that are
 * missing from the manifest are added, size/mtime mismatches are modified,
 * and manifest entries absent from discovery are deleted.
 */
export declare function computeManifestDiff(manifest: readonly ManifestEntry[], repoRoot: string, discoverOptions?: DiscoverCodeOptions, signal?: AbortSignal): Promise<ManifestDiff>;
/**
 * Watcher fast path: classify an explicit changed-file list without a
 * discovery pass. Entries outside the repo, without a language spec,
 * rejected by the same ignore matcher discovery uses, or that discovery
 * would never yield (dot-segments, excluded directories, symlinks — see
 * wouldDiscoverPath) are dropped — required so the result is equivalent to
 * what a full rebuild would have seen. On case-insensitive filesystems a
 * stat can succeed for a stale casing after a case-only rename; such entries
 * are redirected to the on-disk casing (stale casing deleted if indexed,
 * real casing classified normally).
 */
export declare function classifyChangedFiles(changedFiles: readonly string[], manifest: readonly ManifestEntry[], repoRoot: string, discoverOptions?: DiscoverCodeOptions, signal?: AbortSignal): Promise<ManifestDiff>;
/**
 * `ParsedFile.imports[].resolvedPath` is parse-time state: adding or deleting
 * files can change how an *unchanged* importer resolves. Returns the absolute
 * paths of cached files whose imports would resolve differently today, so the
 * caller can re-parse them (imports are never patched in place).
 *
 * Only imports that could plausibly be affected are re-checked: those whose
 * specifier stem matches an added file's basename or parent directory (covers
 * both `./x` → `x.ts` and `./x` → `x/index.ts`, plus extension-priority
 * shadowing of an existing resolution), bare-directory specifiers (`.`/`..`)
 * when an `index.*`/`__init__.py` was added, still-unresolved non-relative
 * specifiers when anything was added (tsconfig `paths` exact aliases like
 * `@api` never stem-match the mapped file's basename), and those whose
 * resolved target was deleted. A flagged import is re-resolved via the same
 * resolveImportPath the parsers use; any difference from the cached
 * annotation flags the file.
 */
export declare function findResolutionImpactedFiles(cachedFiles: readonly ParsedFile[], diff: ManifestDiff, repoRoot: string): string[];
/**
 * Merge cached parse results with fresh ones: drop `removals` (deleted files
 * plus everything re-parsed), insert the fresh entries, and sort both outputs
 * by absolute path with the default string comparator — reproducing the
 * `discovered.sort()` order a full build would produce, which is what makes
 * incremental output deep-equal a fresh full build.
 */
export declare function spliceIndexInputs(cachedFiles: readonly ParsedFile[], cachedSkipped: readonly CodeSkippedFile[], removals: ReadonlySet<string>, fresh: ParseCodeFilesResult): {
    parsedFiles: ParsedFile[];
    skippedFiles: CodeSkippedFile[];
};
