Pure data structure for reviewing agent file edits.
Wraps the hunks produced by Git.Diff.diff_lines/2 with navigation
state and per-hunk resolution tracking. The file viewer renders in
"diff mode" when a DiffReview is present, and the user can accept
or reject individual hunks without leaving the agentic view.
Summary
Functions
Accepts all unresolved hunks.
Marks the current hunk as accepted and advances to the next unresolved.
Returns the current hunk, or nil if no hunks exist.
Returns the start line of the current hunk in the after-content, suitable for scrolling the viewer to show it.
Creates a DiffReview from authoritative precomputed cumulative hunks.
Returns the materialized post-resolution lines, reverting only rejected hunks.
Creates a new DiffReview from a file path and before/after content strings.
Moves to the next unresolved hunk. Wraps around to the first.
Reconstructs the original pre-agent lines by reverting every review hunk.
Moves to the previous unresolved hunk. Wraps around to the last.
Rejects all unresolved hunks.
Marks the current hunk as rejected and advances to the next unresolved.
Returns the resolution for a given hunk index, or nil if unresolved.
Returns true when every hunk has been accepted or rejected.
Returns {added_count, removed_count} summarizing the diff.
Builds the list of lines to display in unified diff format.
Updates the diff review with new after-content and authoritative cumulative hunks while preserving resolutions for hunks that have not changed.
Updates the diff review from already split after-lines and authoritative cumulative hunks.
Types
@type diff_line() :: {String.t(), :context | :added | :removed | :hunk_header, non_neg_integer() | nil}
@type resolution() :: :accepted | :rejected
Resolution status for a single hunk.
@type t() :: %MingaEditor.Agent.DiffReview{ after_lines: [String.t()], current_hunk_index: non_neg_integer(), hunks: [Minga.Core.Diff.hunk()], path: String.t(), resolutions: %{required(non_neg_integer()) => resolution()} }
Diff review state.
Functions
Accepts all unresolved hunks.
Marks the current hunk as accepted and advances to the next unresolved.
@spec current_hunk(t()) :: Minga.Core.Diff.hunk() | nil
Returns the current hunk, or nil if no hunks exist.
@spec current_hunk_line(t()) :: non_neg_integer()
Returns the start line of the current hunk in the after-content, suitable for scrolling the viewer to show it.
@spec from_hunks(String.t(), String.t(), [Minga.Core.Diff.hunk()]) :: t() | nil
Creates a DiffReview from authoritative precomputed cumulative hunks.
Returns the materialized post-resolution lines, reverting only rejected hunks.
Creates a new DiffReview from a file path and before/after content strings.
Splits content into lines, computes hunks via Git.Diff.diff_lines/2,
and initializes with no resolutions and the cursor on the first hunk.
Returns nil if there are no hunks (no changes detected).
Moves to the next unresolved hunk. Wraps around to the first.
Reconstructs the original pre-agent lines by reverting every review hunk.
Moves to the previous unresolved hunk. Wraps around to the last.
Rejects all unresolved hunks.
Marks the current hunk as rejected and advances to the next unresolved.
@spec resolution_at(t(), non_neg_integer()) :: resolution() | nil
Returns the resolution for a given hunk index, or nil if unresolved.
Returns true when every hunk has been accepted or rejected.
@spec summary(t()) :: {non_neg_integer(), non_neg_integer()}
Returns {added_count, removed_count} summarizing the diff.
Counts lines added and removed across all hunks.
@spec to_display_lines(t(), non_neg_integer()) :: [diff_line()]
Builds the list of lines to display in unified diff format.
Returns a list of {text, type, hunk_index_or_nil} tuples where
type is :context, :added, :removed, or :hunk_header.
hunk_index_or_nil links display lines back to their hunk for
resolution marker rendering.
@spec update_after(t(), String.t(), [Minga.Core.Diff.hunk()]) :: t() | nil
Updates the diff review with new after-content and authoritative cumulative hunks while preserving resolutions for hunks that have not changed.
@spec update_after_lines(t(), [String.t()], [Minga.Core.Diff.hunk()]) :: t() | nil
Updates the diff review from already split after-lines and authoritative cumulative hunks.