feat(panel): a comment under a changed line continues the line's band in Files changed

Merged
DA
12d ago
+209-0

Summary

This is PR 3 of 3 for the approved "Code annotations: one card" design (v3). It follows #4203 and is independent of #4214. In Files changed, an annotation row under a changed line keeps that line's band, so a comment in the middle of an added block reads as standing in it rather than cutting it in two.

  • Done the simple way, not with stage-cli's per-slot generated :has(slot[name=…]) rules. Pierre 1.5.2 does not expose the line type on [data-line-annotation] (its value is hunk,lineIndex), and its numbers-column buffer drops the line type too.
    • Marking: the bundle marks each row, and its paired [data-gutter-buffer="annotation"], with one attribute, data-band="addition|deletion" (diff-view/annotation-bands.ts). It does this in the list's existing onPostRender dress, every time Pierre draws a file.
    • Where the band comes from: the line's own data-line-type, read from the row right before the annotation, since Pierre always pushes a line and then its annotation row. That keeps the panel contract unchanged.
    • Pairing: each buffer is paired with the row in the same position, within each [data-content] and its sibling [data-gutter].
  • Static rules in LOOK_CSS:
    • Grounds: the row's code ground and the buffer's numbers ground are the line's own, mixed exactly as Pierre mixes them (88/80% for the content, 91/85% for the numbers, against the same overrides). I measured both in the browser, and they equal the added line's and its number cell's computed colours.
    • Change bar: drawn where Indicators is set to bars, solid for additions and a 2px stripe for deletions. Classic indicators draw nothing in the row.
  • Backgrounds off: nothing is marked (the marking reads pre[data-background]), so the row keeps the plain ground and a mark from before is taken off.
  • Selection keeps priority: lit lines stay blue above, and the band continues behind the card.
  • No pre { isolation: auto } fix: I saw no highlight painting over a card.

Evidence

Screenshots come from a harness that runs the real AgentPullRequestTab, with the real diff bundle (Pierre plus the highlight worker) and the built styles.css. The fixture is an added block with a comment on line 13, inside it.

  • tsc --noEmit (panel): clean.
  • ./scripts/oxlint.sh: 0 warnings, 0 errors.
  • biome check: clean on the changed files.
  • pnpm knip: clean.
  • ./scripts/repository-checks.sh: passed. Every Pierre variable the rules read has a Luke-token fallback.
  • vitest src/diff-view: 30/30.
  • cd apps/desktop && node scripts/build.mjs: bundle budget passes.

New test, annotation-bands.test.ts (2 tests), on Pierre's unified markup:

  • notes under a removed line and an added line get deletion and addition on both the row and its buffer, and a note under a context line gets nothing
  • with Backgrounds off, nothing is marked, and an earlier mark is taken off

Screenshots

Neutral (before)Band continued (after)
900px, dark
900px, light
360px, dark
360px, light
Hover: lit lines stay blue, band behind the card (dark)(light)

Invariants

  • Every behavior change has, in this PR, the test that fails without it; no change-detector test added.
  • No new as assertion, raw async primitive, or Effect run outside the edges.
  • Test count: +2.
  • The diff bundle's header doc names the band (diff-view/index.ts).
  • PRIVACY.md unchanged.

Made with Luke