Agent pane: Show more lines in the changes view (cx-ncc.85, 3/3)

Merged
TE
25d ago
+395-19

Part of cx-ncc.85 (Claude parity): Show more lines in the changes view. This is step 3 of 3, the page side. Steps 1 and 2 are #19732 (session host context_lines, landed) and #19730 (App pass-through).

In a git scope (Uncommitted, Unstaged, Staged, Committed, Branch), each changed file is read a second time as it scrolls into view. The second read is git.diff with paths: [file] and context_lines: 1_000_000, so it holds every unchanged line. From that read the page rebuilds both versions of the file and hands Pierre the scope's own patch with them (processFile(patch, {oldFile, newFile})). The diff is then no longer partial, and Pierre's hunk separators get their expand buttons: up, down, or both between hunks.

  • What stays the same. The shown hunks are still the scope's, so staging, hunk keys, review threads and find don't change.
  • When the read is not used:
    • its changes differ from the shown diff (the file changed since the scope loaded);
    • the patch was cut short;
    • the answer has more than one hunk, as from an App without #19730, which ignores the new params. The diff then stays exactly as it is today.
  • Skipped files: renames (a one-path read would lose the old name), created, deleted and binary files, truncated patches, and Last turn.
  • Request count: one read per file per scope load, cached, and only for files that come within 400px of the viewport.
  • Mock: the mock daemon answers paths and context_lines from its fixture contents.

Verification

Behavior test: webviews/test/changes-more-lines.test.tsx renders DiffPanel in JSDOM with Pierre and checks:

  • Unstaged reads a.txt whole;
  • the diff gets expand buttons;
  • a hidden line between two hunks shows after the separator is clicked;
  • a stale whole read is not used;
  • without a whole-file source the diff is unchanged.

Results:

  • Red at f671e3898441 (test only): 2 pass, 1 fail. The view never read the file ([] instead of [["unstaged","a.txt"]]).
  • Green at 6f6fd794f22a: 3 pass, 0 fail. changes-stage and changes-pull-request still pass, 12 in all.
  • bun run check, bunx tsc --noEmit -p ., gallery-coverage and ui-rules all pass.
  • Review fix (review subagent):
    • Red at 67ead56cbf1d, 3 pass and 1 fail. A host that ignores or caps context_lines returns a read starting at line 20, and that read was used, so the rebuilt file was too short.
    • Green at 6b1285979276, 4 pass and 0 fail. A read must start at line 1 on both sides.
  • Known gaps (Low in review, not fixed here):
    • After a stage or reload, visible files re-read and flip from partial to whole.
    • Files over the host's 256 KB patch cap come back truncated and never expand, but the host still runs the read.
    • A capped read that starts at line 1 but stops before the file's end shows that point as the file's end.
  • Gallery: agent-pane.diff-panel more-lines. Its play expands the separator between the two hunks and waits for the hidden lines.
  • No new user-facing strings.

Changelog

Added: the changes view's git scopes can show the unchanged lines between and around a file's hunks.

๐Ÿค– Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Makes the changes view's git scopes show the unchanged lines between and around hunks, matching the Claude behavior. Each changed file is re-read with git.diff using paths and context_lines: 1_000_000 as it scrolls into view; the full read lets Pierre's hunk separators expand. The shown hunks, staging, hunk keys, review threads, and find stay unchanged โ€” only the surrounding context is added.

Notes

  • The whole-file read is skipped for renames, created, deleted, and binary files, truncated patches, and the Last turn scope; one read per file per scope load, cached.
  • A read that doesn't start at the file's first line is discarded, as it comes from a host that ignored or capped context_lines and rebuilding from it would shorten the file.
  • Requires the session host to accept paths and context_lines (landed in #19732) and the App to pass them through (landed in #19730).

Showcase

separators expand

lines between hunks shown

Open the live gallery