Skip to content

Let Claude say why each hunk is there - #1

Draft
tanmaykm wants to merge 1 commit into
vdayanand:mainfrom
tanmaykm:explain-hunks
Draft

tanmaykm wants to merge 1 commit into
vdayanand:mainfrom
tanmaykm:explain-hunks

Conversation

@tanmaykm

Copy link
Copy Markdown

The diff says what changed but never why. The viewer already has a panel and a voice line for a note on each hunk, but until now only an outside host filled them in. This adds --explain, which asks Claude for them.

ANTHROPIC_API_KEY=... gitdiff3d --explain main...my-branch

What it does

  • One request for the whole change. It sends the hunks in story order, plus the commit messages of the range. For a single revision it uses the commits since that revision, and it respects -- path. Each hunk comes back with a group label of two to five words and one or two plain sentences on what it does, why, and how it relates to the other hunks. The viewer shows these in the existing panel and v reads them aloud, so the viewer needed no changes.
  • Notes stay on their lines. Each note is keyed to the changed lines it describes, not to a hunk number. When c widens the context and merges hunks, the merged hunk reads the notes in order. When a narrower context splits a hunk, both halves keep its note.
  • Off unless asked for, because it sends source code and commit messages to the Anthropic API.
  • A failure doesn't stop the viewer. No credentials, an API error, a refusal, running out of output room, or malformed JSON each leave the scene served, with the reason shown in the header ("no narration: …") and on stderr. Progress goes to stderr, so --json output stays clean.
  • Model: claude-opus-5 with adaptive thinking, JSON-schema structured output, and the server-side fallback (fallbacks: "default"). If the model declines partway through, the answer is taken from the text after the fallback block.

Dependency

@anthropic-ai/sdk becomes the project's first dependency. It is loaded with require only when --explain is given, so the rest of gitdiff3d still runs from a checkout that never ran npm install. Includes package-lock.json.

Testing

  • make check passes. The 7 new checks run offline against a fake client and cover these cases:
    • notes following their lines when the context width merges hunks
    • hunk indexes that match no hunk being dropped
    • a refusal
    • a partial answer before a fallback
    • the wording when there are no commit messages
  • --explain without credentials still prints valid JSON, and the error is in meta.narrationError.
  • Not yet run against the real API. A first run with a key is the remaining check, and this branch is a good test case: gitdiff3d main...explain-hunks --explain.

Not in this PR

  • A --pr <n> flag that fetches a GitHub PR, diffs it the way GitHub does, and adds its title and description to the prompt.
  • Serving the scene immediately and letting notes arrive later. Right now the call blocks before serving.
  • Caching notes, so that running it again on the same range doesn't cost another request.

The diff knows what changed, never why, and the viewer has had a place for a
note per hunk that nothing here ever filled. --explain sends the whole change
to Claude in one request, hunks in story order with the commit messages of the
range, and each hunk comes back with a group label and a sentence or two on
what it does and how it leans on the others.

The notes are pinned to the changed lines, not to hunk numbers, so they follow
along when a wider context merges hunks or a narrower one splits them. It is
off unless asked for, since it sends source code away, and a failed call still
serves the scene with the reason in the header.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant