Skip to content

feat: agent attention marks and line-exact navigation for live sessions - #728

Merged
elucid merged 10 commits into
mainfrom
elucid/agent-attention
Aug 14, 2026
Merged

feat: agent attention marks and line-exact navigation for live sessions#728
elucid merged 10 commits into
mainfrom
elucid/agent-attention

Conversation

@elucid

@elucid elucid commented Aug 13, 2026

Copy link
Copy Markdown
Member

What

hunk-agent-attention-v2.mp4

Stacked on #727 (which stacks on #726). This PR makes the agent story in both of those descriptions true: the capabilities extensions gained there are now reachable by coding agents driving a live review session through the daemon.

hunk session highlight add <session> --file src/config.ts --new-line 214 \
  --start 13 --end 23 --tone warning --focus
hunk session highlight clear <session>
hunk session navigate <session> --file src/config.ts --new-line 214

Until now an agent explaining a changeset in someone's terminal could scroll hunk-to-hunk and leave comments — and hope the reader's eye found the right spot. Now it can mark the exact characters it is talking about and land the viewport on the exact line, in one call.

The guided-walkthrough primitive

highlight add --focus is the composed gesture: mark the range, reveal its line at the app's standard landing position, narrate, highlight clear, move on. An agent answering "where does this change behavior?" lights up the expression as it explains it. Nothing else in the ecosystem can do this in the reviewer's own terminal.

Design

  • One paint pipeline, one addressing vocabulary. Agent marks validate through the same module, tones, offset semantics ([start, end) UTF-16 code units of the raw line text), and per-file/per-line caps as extension line highlighters (feat(extensions): let extensions mark character ranges inside diff lines (API v5) #726), and merge into the single map DiffPane already paints from — agent marks paint last where ranges overlap. No second paint path; the same contrast guarantee and geometry-neutrality hold.
  • Same reveal, same landing spot. session navigate --old-line/--new-line (previously hunk-granular) now rides the exact revealLine path from feat(extensions): line-exact review navigation with ctx.navigation.revealLine #727max(2, 25% of viewport) context above, guarded hunk fallback for unrenderable lines — and reports revealed: "line" | "hunk" so the agent knows what actually happened.
  • Sibling of the comment family. Selectors, --file addressing, and the exactly-one line-target constraint are the ones session comment add already established; the command surface, validation, --help, and the generated review skill all derive from the one declarative spec in surface.ts.
  • Lifetime tied to the content they address. Marks survive scrolling, navigation, and reloads that leave the marked file's content unchanged — they are re-keyed onto the rebuilt review. A reload that changes that file, or drops it, takes its marks with it: unlike comments, nothing can re-derive offset-addressed marks against changed text, and a stale mark would silently light up the wrong characters. Documented in the skill and architecture doc.
  • Versioned rollout. Daemon protocol version bumped; older daemons auto-refresh through the existing capability check.

Evidence

PTY end-to-end against a real daemon-registered session: highlight add … --focus --json returns revealed: "line", a needle 111 lines into a large hunk lands in the top half of a 24-row terminal, cell-background inspection proves the marked characters carry a background their neighbors don't, and highlight clear reports exact removal counts. A script-based mirror covers CI Linux in test/session/broker-e2e.test.ts.

Notes

Why reconcile.ts and merge.ts survive #733's rework

#733's staleness machinery (per-file publish, paint-time file-identity filtering, generation-scoped retention, the merged-total cap) lives inside useLineHighlights and governs extension-derived marks only: it makes sure stale marks are dropped, and relies on highlighters re-running to restore fresh ones. Agent attention marks have no re-derivation source — nothing re-runs them after a reload — so reconcile.ts is the only mechanism that keeps still-valid marks, enforcing the same staleness discipline from the other direction: carried only when contentIdentity is unchanged, re-keyed onto the replacement's runtime id, dropped for changed or departed files. The two are complementary, not duplicative. #733's identity guard cannot reject carried marks because agent marks never pass through it: they merge in after it via merge.ts, keyed by the current runtime id. AppHost.reload.test.tsx proves both reload shapes at the painted-cell level — same-id reload, and the VCS case where an unrelated file joining the changeset shifts an untouched file's index-embedding runtime id (sabotaging the re-key makes that test fail). The merged paint total stays bounded: ≤ 4000 from the extension merged cap plus ≤ 2000 from the agent per-file cap, with agent marks accumulating only one validated CLI call at a time.

@vercel

vercel Bot commented Aug 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hunk-web Ignored Ignored Preview Aug 14, 2026 4:35pm

Request Review

@elucid
elucid force-pushed the elucid/agent-attention branch from 6146cd0 to 99c411a Compare August 13, 2026 20:35
@elucid
elucid force-pushed the elucid/reveal-line branch from 39cd7d2 to 1e42375 Compare August 13, 2026 20:35
@elucid
elucid marked this pull request as ready for review August 13, 2026 23:44
@greptile-apps

greptile-apps Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds daemon-driven character-range attention marks and upgrades session line navigation to use the UI’s exact-line reveal path.

  • Adds highlight add and highlight clear across CLI parsing, protocol validation, daemon routing, and the app bridge.
  • Validates, paints, clears, and reload-reconciles agent marks through the existing line-highlight pipeline.
  • Adds exact-line navigation results, generated documentation, and unit, broker, reload, and PTY coverage.

Confidence Score: 4/5

The filtered-file navigation failure should be fixed before merging because session commands can report success while moving the reviewer to an unrelated file.

Exact-line navigation and focused highlights resolve absolute targets from all files, but their reveal fallback operates on visible files, allowing an active filter to redirect the resulting selection.

Files Needing Attention: src/ui/hooks/useReviewController.ts; src/session/agent/cliClient.ts

Important Files Changed

Filename Overview
src/ui/hooks/useReviewController.ts Adds mark ownership, reload reconciliation, and exact-line navigation; filtered targets can report success while selection reconciles to another file.
src/session/protocolSchemas.ts Adds strict daemon schemas for highlight actions, with app-side validation enforcing the relational range constraint.
src/session/broker/brokerServer.ts Advertises and routes both new highlight actions through the existing guarded session API.
src/ui/highlights/reconcile.ts Re-keys marks only when semantic file identity and content identity remain unchanged.
src/ui/App.tsx Merges extension and agent marks into the single highlight map consumed by DiffPane.
src/session/agent/cliClient.ts Adds highlight requests and text formatters; the exported formatters lack required TSDoc comments.

Sequence Diagram

sequenceDiagram
  participant Agent as Session CLI
  participant Daemon as Session daemon
  participant Bridge as App bridge
  participant Review as Review controller
  participant Diff as Diff pane
  Agent->>Daemon: highlight-add / navigate
  Daemon->>Bridge: highlight / navigate_to_hunk
  Bridge->>Review: validate mark or reveal line
  Review->>Review: update mark map and selection
  Review-->>Daemon: result with revealed status
  Review->>Diff: merged extension + agent marks
  Diff-->>Agent: terminal paints range / viewport moves
Loading
Prompt To Fix All With AI
### Issue 1
src/ui/hooks/useReviewController.ts:907-921
**Filtered targets report false success**

When exact-line navigation or a focused highlight targets a file hidden by the active filter, `revealLine` returns `none` and this branch selects the hidden file anyway. Selection reconciliation then moves to the first visible file, so the command reports success while the viewport lands on an unrelated file.

### Issue 2
src/session/agent/cliClient.ts:557-577
**Exported formatters lack TSDoc**

The newly exported `formatHighlightOutput` and `formatClearHighlightsOutput` helpers omit the required short TSDoc explanations, leaving the new module surface without its mandated API-level purpose documentation.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "docs(website): regenerate CLI reference ..." | Re-trigger Greptile

Comment thread src/ui/hooks/useReviewController.ts Outdated
Comment thread src/session/agent/cliClient.ts
elucid added a commit that referenced this pull request Aug 14, 2026
Both helpers became module surface when the highlight commands landed, so they
owe a reader the same short explanation every other exported helper here
carries.

Reported by Greptile on #728.
@elucid
elucid force-pushed the elucid/agent-attention branch from 29251ea to d5b8ecc Compare August 14, 2026 02:51
@elucid
elucid force-pushed the elucid/reveal-line branch from e616156 to f756f53 Compare August 14, 2026 03:59
elucid added a commit that referenced this pull request Aug 14, 2026
Both helpers became module surface when the highlight commands landed, so they
owe a reader the same short explanation every other exported helper here
carries.

Reported by Greptile on #728.
@elucid
elucid force-pushed the elucid/reveal-line branch from f756f53 to cf68c9f Compare August 14, 2026 04:50
@elucid
elucid force-pushed the elucid/agent-attention branch from d5b8ecc to b95b653 Compare August 14, 2026 04:50
auto-merge was automatically disabled August 14, 2026 15:37

Pull Request is not mergeable

auto-merge was automatically disabled August 14, 2026 15:39

Pull Request is not mergeable

auto-merge was automatically disabled August 14, 2026 15:49

Pull Request is not mergeable

elucid added a commit that referenced this pull request Aug 14, 2026
Both helpers became module surface when the highlight commands landed, so they
owe a reader the same short explanation every other exported helper here
carries.

Reported by Greptile on #728.
@elucid
elucid force-pushed the elucid/agent-attention branch from b95b653 to 777aace Compare August 14, 2026 16:10
@elucid
elucid force-pushed the elucid/reveal-line branch from cf68c9f to 026dd45 Compare August 14, 2026 16:10
@elucid
elucid changed the base branch from elucid/reveal-line to main August 14, 2026 16:32
elucid added 10 commits August 14, 2026 12:34
Agents could only annotate and navigate live sessions at hunk granularity;
the extension API's character-range marks and line-exact reveals had no
daemon-facing counterpart. Declare highlight-add / highlight-clear actions,
their strict request schemas, and the applied/cleared result shapes, and let
navigate results report whether a line target landed line-exactly. Bump the
daemon compatibility version because the forwarded payload set grew.
hunk session highlight add / clear are siblings of the comment family: the
same selector notation, the same --old-line/--new-line targeting constraint,
and offsets that reuse the extension API's [start, end) vocabulary so one
range means the same thing to agents and extensions. --start introduces a
non-negative integer parse because offsets are 0-based.
…d bridge

The HTTP client, capability-checked command runner, broker dispatcher, and
app bridge each learn the two highlight actions the same way the comment
actions travel, so an older daemon is refreshed automatically when an agent
first asks for a highlight.
Agent marks validate through the same module extension line highlighters
answer to, merge into the one map DiffPane paints from, and clear when a
reload replaces the review document (offset-addressed marks have no owner
to re-derive them, unlike extension highlighters which re-run). A navigate
line target now rides the same revealLine path ctx.navigation.revealLine
uses, so agents and extensions share one landing policy and one hunk
fallback.
…gation

Unit coverage tracks each tier the new actions cross: CLI parse shapes and
error wording, wire schema acceptance and rejection, client envelope
mapping, formatter output, controller validation/caps/reveal/reload
semantics, and the merged paint map's identity guarantees.
The PTY test drives a real daemon-registered session: the highlight CLI
marks a range whose cells visibly change background, the --focus reveal
lands a line 100+ rows below the hunk anchor near the viewport top, and a
line-target navigate reports the same line-exact landing. The script-based
session e2e covers the same flow on CI Linux terminals.
The generated review skill gains the highlight family with the offset
semantics spelled out, the guiding-a-review flow now narrates with marks,
and the architecture doc records why agent marks feed the extension paint
pipeline instead of growing a parallel one.
A reload replaced the review document and dropped every agent attention
mark, so a stray `r`, the File > Reload menu item, an extension workspace
write, or `hunk session reload` silently erased marks the agent had just
painted. The agent only found out at `highlight clear`, which honestly
reported `removedCount: 0` for a mark it had watched succeed.

Marks are content-derived state, so retire them the way the review store
already retires notes: a file that comes back with an unchanged
`contentIdentity` still shows the same characters on the same lines, so
its marks stay valid and are re-keyed onto the replacement runtime id.
Marks on files whose content changed, or that left the review, are still
dropped rather than left lighting up text nobody marked.
The attention-mark and line-navigation changes regenerated the in-repo
skill but not the website's generated mirrors, so check:docs failed on CI.
Output of `bun run generate:docs`, no hand edits.
Both helpers became module surface when the highlight commands landed, so they
owe a reader the same short explanation every other exported helper here
carries.

Reported by Greptile on #728.
@elucid
elucid force-pushed the elucid/agent-attention branch from 777aace to 1fd47e7 Compare August 14, 2026 16:35
@elucid
elucid merged commit bb6405e into main Aug 14, 2026
12 checks passed
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