VT Code computes text changes in the publishable vtcode-diff crate. The crate has no dependency on other VT Code
crates: it owns bounded similar-based diff computation, the semantic document model, intraline byte ranges,
Unicode-width wrapping, unified/side-by-side layout, and bounded excerpts.
Application crates own policy and presentation:
vtcode-uicaches the document when an overlay opens and only relayouts or scrolls it during resize and navigation.- theme and terminal capability selection remain in the VT Code design system; diff styling uses a subtle full-row add/delete tint and a stronger background for changed intraline spans. Context rows remain un-tinted, while hunk and file metadata use bold syntax-highlighted foregrounds with no background. ANSI16 terminals and explicit no-color output fall back to foreground-only styling.
- syntax highlighting is injectable application work, so the reusable crate does not depend on
syntector VT Code themes. - approval state, modal priority,
Enter/Escbehavior, and runtime events are unchanged and remain outside the diff crate.
DiffOptions defaults to practical Myers with separate line and intraline timeouts. Patience and Histogram are public
library choices but are not config values. For large output, preserve readable semantic rows and disable costly
refinement before suppressing content. LayoutOptions::max_rows produces a head/tail excerpt with an explicit omission
row.
The user-facing unified layout is still configured as "inline" for backward compatibility. Width decisions use the
measured content width after message indentation and transcript framing: side-by-side falls back to unified below the
shared 60-column threshold, and either unified presentation hides its visible +/-, line-number, and │ gutter when
keeping it would leave less than 20 columns for source text. The gutter and side-by-side panes return automatically when
a resize restores enough width. Tests should cover asymmetric insert/delete cases, UTF-8 boundaries, display-width
wrapping, deadlines, pairing, exact omission accounting, and both sides of these width boundaries.
TurnDiffTracker(vtcode-core) aggregates per-file changes within a turn.get_unified_diffoutput is deterministic (entries sorted by path) and bounded: entries whose stored content exceeds 200 000 bytes render as a one-line summary instead of a full diff.- The
ThreadEvent::FileChangepayload (FileChangeIteminvtcode-exec-events) carries optionalunified_diff,additions, anddeletionsfields. They are populated from the tracker so consumers can render per-change previews without recomputation; older events without the fields deserialize unchanged, and the fields are omitted from output when unset. vtcode-diffskips intraline refinement when any line contains a NUL byte (binary content), preserving line-level diffs without paying the word-level cost. CRLF terminators, missing-final-newline hints, and git-compatible zero-context hunk headers (@@ -0,0 +1,N @@) are covered by regression tests.- Hunk headers keep their authored range counts. Previews render
@@ -65,19 +65,0 @@verbatim (anddisplay_lines_from_hunkssynthesizes the same git-compatible form viaformat_hunk_header); collapsing to the start-only@@ -65 +65 @@is rejected because it misreports a multi-line or pure-deletion hunk as a one-line change. - Diff syntax highlighting reconstructs each side (pre-image and post-image) in original file order and highlights it once, bounded by the existing byte/line caps, so parser state survives hunk boundaries (multi-line strings and comments split across hunks stay correctly highlighted). Oversized content falls back to per-hunk highlighting.
- Selectable diff themes live in
vtcode-ui's design layer (DiffTheme: github, ayu, gruvbox, nord, solarized, dracula). Every accent in every theme is contrast-checked against its background at WCAG AA 4.5:1 byevery_theme_meets_wcag_aa_contrast. Useformat_colored_diff_with_themefor themed rendering; the default theme keeps the canonicalformat_colored_diffcolors. - The overlay header truncates the file path so the action label and
(+N -N)counts remain visible at any width.
User-facing behavior for long diffs in the TUI:
- Transcript wrap — when tool output renders into the inline TUI sink, edit/patch body rows are word-wrapped instead
of ellipsis-truncated, up to a 2 000-cell safety cap (
DIFF_WRAP_SOURCE_MAX_WIDTHinsrc/agent/runloop/tool_output/streams.rs). Continuation rows hang under the visible gutter or, for compact tinted rows without a gutter, under the single marker cell. CLI / no-sink renders keep the boundedMAX_LINE_LENGTHcap. - Vertical omission — expandable
review full diffcopy andDiffReviewAnchorare recorded only when the renderer still holds the complete unified body and clipped it for display (inline TUI sink, not a pre-truncated registry excerpt). Tool-level truncated previews advertise omission/excerpt copy and never claim full-diff review. CLI/no-sink keeps the actionableexec_command/sed recovery hint. - Safety-cap expand — when an inline-TUI body row exceeds
DIFF_WRAP_SOURCE_MAX_WIDTH, the transcript still ellipsis-truncates that row but also advertises expand (… diff truncated — review full diff for <path>) and records aDiffReviewAnchorwith the retained unified payload. - Review overlay — approval/conflict/readonly-review overlays use the full viewport. Layout keeps
LayoutOptions.wrap = true; long lines wrap inside the overlay. When laid-out wrapped rows exceed content height the controls footer shows+N more. Completed-edit review can open from a retained unified preview viaDiffOverlayRequest { unified: Some(...), mode: ReadonlyReview }/DiffPreviewState::from_unified.
Spec: docs/compose/spec/tui-diff-auto-expand.md.
The presentation architecture was informed by the open-source Codex terminal diff design (Apache-2.0). VT Code's implementation and state model remain independent; no Codex source code was copied.