feat: upgrade to hunkdiff 0.21.0 - #8
Merged
Merged
Conversation
Context lines of a marked hunk borrowed the same amber as the lines that move, which overstated how much of the file a mark would actually take. That was not a choice so much as a constraint: the only other tones available either shifted brightness alone and vanished against an added line's green, or already meant something else in the diff. Hunk 0.21 (extension API 16) adds `dim`, which recedes a line toward its background while preserving token hues. Changed lines keep the amber and context takes `dim`, so `context_marks = "edge"` and `"full"` now trace a hunk's reach without competing with what will move. The default stays "none". Tones are decided per line in buildMarkHighlights, where a line is already classified, rather than stamped across the set at the call site. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Every command here treats the diff on screen as work that has not landed yet: staging reads the working copy, and discarding writes to it. Hunk makes no such promise — `hunk show` reviews a commit, and 0.21 added `hunk diff <from> <to>` for comparing two revisions. The text checks did not catch this, because they cannot. "This patch matches the file on disk" is equally true of uncommitted work and of committed history the working copy agrees with. So on a clean checkout, reviewing `HEAD~1 HEAD` and pressing D passed every check and reverted those lines in the working copy — an edit nobody asked for, which rides into the next commit if it goes unnoticed. Ask the VCS instead: one `jj diff --name-only`, or `git diff --name-only HEAD` plus `ls-files --others` so a review holding only an untracked file still counts. If no reviewed file is uncommitted, refuse before any dialog. The check is per review rather than per file — a stale file inside a working-copy review is what the staleness and agreement checks are for. The README already listed this refusal and already said working-copy reviews only; the code kept that promise only when the text happened to disagree. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The declaration and the hunkdiff caret range can drift apart silently: the host refuses only an extension claiming a generation higher than its own, so a Renovate bump that leaves `apiVersion` behind loads and runs exactly as before — until someone reaches for an API the declaration does not claim. Nothing failed; the number was just wrong. Verified it fails for the right reason by setting apiVersion back to 8: `Expected: 16, Received: 8`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
package.json declares extension API generation 16, and the host refuses any extension declaring higher than its own, so the oldest Hunk that will load this one is 0.21 — 0.20 ships generation 8. The Requirements line still named 0.20 and v8: correct until the 0.21.0 bump, and stranded by it.
CI cannot vouch for a hunkdiff bump. The package is imported almost entirely as a type-only import, so only tsc covers it, and only for the four interfaces this repository names. What drifts silently is the prose around it: the stated minimum Hunk version, the command table, the demo GIFs. This skill is the reading and reconciling that has to happen by hand — where the release notes live, which claims to re-check, and when to hand off to demo-gifs.
The 7-day minimumReleaseAge plus schedule:weekly put the hunkdiff PR 7 to 14 days behind the release, and every one of those days is spent not reading release notes we could have read on day one. Nothing merges itself here — automerge stays off and the bump is finished by hand — so the PR serves mainly as the notification that a release happened. The comment above the rule was stale in two ways, and now says so: the manifest test imports HUNK_EXTENSION_API_VERSION as a value, so one hunkdiff module really is evaluated under bun test, and extension API generations drag our stated minimum Hunk version along with them.
Fires when Renovate opens the PR rather than on a schedule, so it runs the day the release lands, and commits on top of Renovate's own bump — one PR then carries the new version and everything the new version implies. opened and reopened only, never synchronize: the job pushes to the branch that triggered it. jj is not installed here, so the jj-backed suites self-skip, and the prompt tells the agent to defer to the CI job on the same commit rather than report a green run as full coverage.
Marks were visible only as amber inside the diff. Mark hunks in three
files that are screens apart and there was no way to read the set back:
the confirmation counts it ("3 hunks in 2 files") but cannot name it, so
C was pressed on trust. On a small review the diff shows you everything;
this is for the large agent-authored changeset the tool exists for.
Opened with L — M and m are Hunk's menu bar and hunk headers, and
registering a pane does not show it, so without a key it would be
unreachable. Sized as a fraction of the terminal with an 18-column floor,
below which a path stops being readable.
State stays in the MarkStore. Panes unmount when they are closed, so a
component owning the marks would drop them on every close; the store now
publishes changes and hands back a snapshot whose identity moves only
when a mark does — a fresh map per read is an infinite render, a stale one
never repaints.
The listing and path fitting are plain functions in src/ui/markedSet.ts
with their own tests. What is left in the component is only what needs a
renderer.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A long marked list is read against a diff scrolled somewhere inside it, and the two had nothing in common to look at: the list said what was marked, the review said where you were, and neither said which row you were standing on. The current file's row now takes the accent colour on the selected-hunk background. No `hunk_viewed` subscription, though that is what the issue proposed. Hunk passes `selectedFileId` and `selectedHunkIndex` into every pane render, so the component already holds the cursor and a handler would have re-fetched what was in hand. The event earns its place for consumers outside a pane — a command, a log — and there are none here. Nothing is picked out when the cursor sits in a file with no marks, which is the usual state while still reading. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps hunkdiff to 0.21.0 (extension API generation 16) and takes what the new
generation makes possible or newly requires.
dimfor marked context. Context lines shared the amber of the lines that move, overstating a mark's reach.context_marks = "edge"/"full"now use 0.21'sdimtone; the default stays"none".hunk diff <a> <b>, whereDpreviously passed every text check and edited the working copy anyway. Now asks the VCS before any dialog.L— the marked-set pane. Lists each marked file and its hunk count beside the diff, with the cursor's file picked out. For large reviews, where the scattered marksCwill take cannot be read off the diff.