Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 5x 5x 5x 95x 10x 85x 10x 75x 5x 70x 40x 30x 30x 20x 10x 10x 5x 36x 36x 36x 36x 78x 36x 123x 36x 41x 41x 41x 276x 163x 276x 78x 41x | /**
* Lightweight diff parsing utilities for the FileEditCard.
*
* Handles two formats:
* 1. Unified diff strings (from Copilot's `detailedContent` field)
* 2. Old/new string pairs (from Claude Code's `Edit` tool args)
*/
/** A single line in a parsed diff. */
export interface DiffLine {
/** Line classification. */
type: "add" | "remove" | "context" | "header";
/** Line content (without the leading +/- prefix). */
content: string;
}
/** Addition/removal counts for a diff. */
export interface DiffStats {
added: number;
removed: number;
}
/**
* Parses a unified diff string into typed lines.
*
* Recognizes `@@` hunk headers, `+`/`-` prefixed lines, and context lines.
* Skips `---`/`+++` file header lines and `diff --git` preamble.
*/
export function parseUnifiedDiff(diff: string): DiffLine[] {
const lines = diff.split("\n");
const result: DiffLine[] = [];
for (const line of lines) {
if (line.startsWith("diff --git") || line.startsWith("index ")) {
continue;
}
// Skip file header lines (--- a/file, +++ b/file) but not hunk content
// lines that happen to start with "---" or "+++" (which appear as
// "----..." or "++++..." in the diff and are handled by +/- rules below).
if (
(line.startsWith("--- ") || line.startsWith("+++ ")) &&
!line.startsWith("---- ") &&
!line.startsWith("++++ ")
) {
continue;
}
if (line.startsWith("@@")) {
result.push({ type: "header", content: line });
} else if (line.startsWith("+")) {
result.push({ type: "add", content: line.slice(1) });
I} else if (line.startsWith("-")) {
result.push({ type: "remove", content: line.slice(1) });
} else if (line.startsWith(" ")) {
result.push({ type: "context", content: line.slice(1) });
} else if (line === "") {
// Empty lines in unified diffs are context lines
result.push({ type: "context", content: "" });
}
}
return result;
}
/**
* Constructs a minimal diff from old and new strings.
*
* This is a simple line-by-line comparison — not a true LCS diff algorithm.
* Shows all old lines as removals followed by all new lines as additions.
* Good enough for the small, targeted edits agents typically make.
*/
export function diffFromOldNew(oldStr: string, newStr: string): DiffLine[] {
const oldLines = oldStr.split("\n");
const newLines = newStr.split("\n");
const result: DiffLine[] = [];
for (const line of oldLines) {
result.push({ type: "remove", content: line });
}
for (const line of newLines) {
result.push({ type: "add", content: line });
}
return result;
}
/** Counts additions and removals in a parsed diff. */
export function diffStats(lines: DiffLine[]): DiffStats {
let added = 0;
let removed = 0;
for (const line of lines) {
if (line.type === "add") {
added++;
}
if (line.type === "remove") {
removed++;
}
}
return { added, removed };
}
|