/** * The ONE quote-aware unified-diff header parser. Three divergent parsers * used to read patches: a regex in the orchestrator's diffStats that * missed git-quoted headers (non-ASCII/spaces → protected-path and * NEEDS_HUMAN gates silently skipped those files), a line-scan in the * delivery gate that read `--- `-prefixed CONTENT lines as paths (SQL * comments → false apply refusals), and a header tokenizer in * context/evidence that never decoded octal escapes. All three rebase here. * * Structural rules, not regex governance: file metadata (`---`/`+++`, * `rename from/to`, `new/deleted file mode`, binary markers) is honored only * in HEADER position — between a `diff --git` line and that file's first * `@@` hunk — so patch CONTENT can never masquerade as structure. * * PLAIN unified diffs (GNU `diff -ruN`, the workspace's non-git in-place * fallback) have no `diff --git` anchors, so a document that opens with a * plain file header is parsed in PLAIN mode: a file entry opens only on the * full structural triple — a `--- ` line immediately followed by a `+++ ` * line and an `@@` hunk header — which keeps deleted `-- sql` content lines * from masquerading as file boundaries. Without this mode every non-git * in-place diff summarized to zero files, silently blinding diffstat and * protected-path/risk gating for that whole run class. Inside a git-anchored * document the git rules above apply unchanged (never mixed per document). * Plain-mode entries default to modified (GNU diff marks absent files with * epoch timestamps, not `/dev/null`, so added/deleted classification is * honored only for explicit `/dev/null` headers) — conservative for gating: * every touched path is visible to policy. */ export interface DiffFileEntry { /** Pre-image path (null when the file is newly added). */ oldPath: string | null; /** Post-image path (null when the file is deleted). */ newPath: string | null; added: boolean; deleted: boolean; renamed: boolean; /** Binary change (GIT binary patch payload or a bare "Binary files" stub). */ binary: boolean; /** True when the binary change carries NO applyable payload (stub). */ binaryStub: boolean; } export interface UnifiedDiffSummary { files: DiffFileEntry[]; additions: number; deletions: number; hunks: number; } /** * Decode one git C-quoted path token: strips surrounding quotes and decodes * `\ooo` octal byte escapes plus the standard single-char escapes, yielding * the real on-disk path (utf8). */ export declare function cUnquoteGitPath(raw: string): string; export declare function parseUnifiedDiff(diff: string): UnifiedDiffSummary; export interface DiffPathSummary { paths: string[]; addedPaths: string[]; modifiedPaths: string[]; existingPaths: string[]; /** * EVERY path the diff touches: the new side of every file PLUS the old side * of every rename/modify. This is the ONE set a path policy gate (deny, * protected, built-in human) must match — any gate matching a narrower * projection is bypassable by a diff shape it does not see (the G1 class: * rename-out slipped past new-side-only, new-file-under-glob slipped past * existing-only). */ touchedPaths: string[]; additions: number; deletions: number; } /** * Path-oriented projection of a unified diff for policy/risk gating and * diffstat honesty: which files the patch touches, which are NEW vs * pre-existing, and the +/- counts. Quote-aware via parseUnifiedDiff — a * git-quoted header (non-ASCII, spaces) must never silently DROP a file * from protected-path/NEEDS_HUMAN classification. */ export declare function summarizeDiffPaths(diff: string): DiffPathSummary; //# sourceMappingURL=diff.d.ts.map