import { type GitRunner } from '../project.js';
import type { FileGitStatus } from './file-status.js';
import { safeRepoPath } from './file-read.js';
export { safeRepoPath };
/** One file's diff, capped so a hover card can render it. */
export interface FileDiff {
    /** The repo-relative path asked for. */
    path: string;
    status: FileGitStatus;
    /** Unified diff body, hunks only (git's `diff --git` / index preamble is dropped). */
    patch: string;
    added: number;
    removed: number;
    /** The patch hit the preview cap and was cut. */
    truncated: boolean;
    /** Nothing textual to show (git reports a binary change, or the file is not UTF-8 text). */
    binary: boolean;
}
/** One changed file in a session's Changes list (#817): what moved, and by how much. */
export interface FileChange {
    path: string;
    status: FileGitStatus;
    added: number;
    removed: number;
    /** Line counts are unavailable (a binary file, or an untracked one too large to count). */
    binary: boolean;
}
/**
 * The diff for one changed file in the checkout at `cwd`.
 *
 * Tracked files diff against `HEAD`, not the index, so a change the agent staged still shows;
 * that also matches `git status --porcelain`, which is what dotted the file in the first place.
 * An untracked file is rendered as all-added from its contents, since `git diff --no-index`
 * exits non-zero on a difference and would read as a failure here.
 *
 * Returns null when the path is unsafe, unreadable, or has no diff to show.
 */
export declare function readFileDiff(cwd: string, path: string, status: FileGitStatus, git?: GitRunner): Promise<FileDiff | null>;
/** One `git diff --numstat` line, parsed. */
export interface NumstatEntry {
    path: string;
    added: number;
    removed: number;
    binary: boolean;
}
/**
 * Parse `git diff --numstat` output: `added<TAB>removed<TAB>path`, with `-` for both counts
 * on a binary file. The one parser for the grammar — it was written here and in run-handoff,
 * and the copies had already drifted on a path containing a tab (this side rejoined it, the
 * other dropped the line).
 */
export declare function parseNumstat(out: string): NumstatEntry[];
/**
 * Every changed file in the checkout at `cwd`, with its line counts: the session's Changes list
 * (#817). One `git status` plus one `git diff --numstat`, not a diff per file, so a session that
 * touched forty files still costs two git calls.
 *
 * Untracked files have no numstat entry (they are not in the diff at all), so their added count
 * is their line count, read from disk. Sorted by path, so the list does not reshuffle as a live
 * session edits.
 */
export declare function readFileChanges(cwd: string, statuses: Record<string, FileGitStatus>, git?: GitRunner): Promise<FileChange[]>;
//# sourceMappingURL=file-diff.d.ts.map