Each inline review comment under `pr view <n> --reviews` now renders its `id` (the handle a reply targets), `resolved` (`yes`/`no`, from whether Gitea populated the comment's `resolver`), and `diff_hunk`. The hunk is structurally trimmed to its `@@` header line plus its last two lines by default (hunks of three lines or fewer are left whole) and emitted verbatim under `--full`, so the trim never touches the char-based body truncation path. The raw `position`/`original_position` diff offsets stay unsurfaced. The fields ride the existing reviews-plus-per-review-comments fetch — no extra API calls.
3.7 KiB
spec
| spec |
|---|
| pr-review-comments |
What to build
Extend pr view <n> --reviews so each inline review comment carries the anchoring information an agent needs to answer and reply to it without a second API call.
Each inline-comment row gains three fields: id (the comment's own id, the handle replies target), diff_hunk, and resolved (yes/no, derived client-side from whether the comment's resolver user is populated).
diff_hunk renders with a bespoke structural trim, distinct from the char-based body truncation: by default the hunk's @@ header line plus its last two lines, collapsed when the hunk is three lines or fewer.
This keeps both the file-line anchor (the header) and the code at the comment (the tail).
Under --full the entire diff_hunk is emitted verbatim — the hunk is never run through the body char-truncation path.
The raw position / original_position diff offsets are deliberately not surfaced.
These fields ride the existing --reviews fetch (reviews list plus one inline-comments fetch per review); no extra API calls are introduced.
Acceptance criteria
- Each inline-comment row under
--reviewsrendersid,diff_hunk, andresolved resolvedisyeswhen the comment'sresolveris populated andnootherwise- Default
diff_hunkshows the@@header line plus the hunk's last two lines; a hunk of three lines or fewer renders in full --fullemits the entirediff_hunkverbatim, with no char-truncation applied to it- Raw
position/original_positionare not rendered - No additional API calls beyond the existing reviews-plus-per-review-comments fetch
- Fixture-server tests drive
pr view N --reviewsand--fullagainst reviews and inline comments carryingid,diff_hunk, and a set/unsetresolver, asserting the renderedid, trimmed-vs-fulldiff_hunk, andresolved: yes/no
Implementation Notes
- The structural trim lives in
src/diff.tsas a puretrimDiffHunk(hunk)besidetruncateDiff: for a hunk longer than three lines it returns the first (@@header) line plus the last two lines joined by newline; three lines or fewer is returned unchanged.buildReviewRowsinsrc/commands/pr.tscalls it for the default path and passesdiff_hunkverbatim under--full, so the hunk never touches the char-based body-truncation path. - The inline-comment row's field order is
id, author, path, resolved, diff_hunk, body, which is the TOON table header the tests assert against. resolvediscomment.resolver ? "yes" : "no"— a truthiness check on the SDK's optionalresolveruser, matching the spec's "set / not set" derivation.- No fresh RED for the
resolved: yes,--full-verbatim, and ≤3-line-full cases: the cohesivetrimDiffHunkhelper (and theresolvertruthiness branch) implemented in the first GREEN already covered them, so their tests were green on arrival. Each was proven non-vacuous with a sentinel-probe swap (per the TDD skill) and kept as a regression guard rather than dropped. - No new API calls: the three fields ride the existing reviews-plus-per-review-comments fan-out that
--reviewsalready performs.
Review follow-ups (/review-uncommitted), both addressed in this branch:
- Standards flagged
id: comment.id ?? 0as fabricating an identifier — the very handle a reply copies intoreply_to. Replaced with areviewCommentIdhelper that throwsUNKNOWNon a missing id, mirroring the repo's existingpullNumber/headSha"never invent an identifier" convention. - Spec flagged the exactly-four-line trim boundary (the shortest hunk the
<= 3guard actually trims) as untested. Added a regression test for it; a<= 4off-by-one would now fail.