Skip to content

feat(comments): reference a comment into the agent, and turn its answer into a reply draft - #228

Merged
huhamhire merged 3 commits into
devfrom
feat/ask-agent-about-comment
Sep 9, 2026
Merged

huhamhire merged 3 commits into
devfrom
feat/ask-agent-about-comment

Conversation

@huhamhire

Copy link
Copy Markdown
Owner

A reviewer''s comment is usually a claim — is this actually a problem, does this path really run, was it handled elsewhere — and settling it means reading the code the comment points at. That is what the agent is for, but the only way to hand it one was to paste the text into the chat box, dropping the anchor and the authorship on the way. And once you had the answer, replying meant retyping it.

What it does

  1. Reference — a button on any comment attaches it as implicit context for the next question, so "is this right?" is a complete question. The agent receives the comment body, its author, and the file/line it points at.
  2. Reply — the answer carries a use as reply action that turns it into a draft reply to that comment.

No IPC changes

Both halves land on existing contracts, which is most of why this stayed small:

  • agent:ask already carries referencedContext for the diff selection. The comment formats into the same channel, and the two compose — asking whether a comment is right about a selected region needs both.
  • drafts:create already models a reply through replyTo, and the comment''s anchor carries over, so an inline reply keeps its position in the diff.

Cross-pane state goes in a store for the same reason the diff selection does: the comment surfaces and ChatPane are siblings with no common owner below App.

Three decisions worth reviewing

The association is deliberately short-lived. "Use as reply" needs the answer to know which comment it answers, so a referenced comment hands off on send instead of being discarded — detached from the input bar, still tied to that round. The hand-off runs on every send, including unreferenced ones: that is what ends a previous association, so an unrelated later answer never offers itself as a reply to an old comment. Memory only, one round. An association that outlived its round would attach an answer to the wrong comment, which is worse than not offering the action.

It produces a draft, not a posted reply. The words are the agent''s; publishing under the user''s name is the user''s call. It lands in the same pool as every other pending reply — editable, rejectable, published with the review batch.

The prompt says what to do with the comment, not just what it says. Without that instruction a model tends to paraphrase the comment back instead of checking it.

Scope

Both comment surfaces get the reference button, identically — toggle to release, chip with a clear button, released on send, cleared on PR switch. DraftZone does not: a draft is a comment nobody else has written yet, so there is no claim to investigate. That boundary is deliberate rather than an oversight of the comment-surface parity rule.

The glyph is the existing ShareIcon rather than something agent-flavoured, because that is already what "reference" looks like in this app (the finding reference button) — one gesture should not have two icons. Thanks for catching that; my first pass used a robot icon, which drew the target where the established convention draws the action.

Verification

lint / typecheck / test / build pass.

Two visual defects were found by running it, not by the gate — both mine, both fixed here, and worth stating because they show what the gate does not cover:

  • I created an empty styles/features/chat.scss while probing a file, which shadowed the features/chat/ style directory that @use ''./styles/features/chat'' resolves to. Every ChatPane style vanished — and the build passed, because an empty stylesheet is not an error. Removed, artifact rebuilt.
  • The reference button sized itself to its glyph while the text buttons beside it size to a font-size line box, so it stood taller than its row. Both surfaces now take the same padding and font-size, and the svg is display:block so it does not add descender space.

Beyond those, the interaction has not been exercised end to end against a live agent run — worth one pass to confirm the answer''s use as reply produces a draft anchored to the right comment.

🤖 Generated with Claude Code

huhamhire and others added 3 commits September 8, 2026 21:43
A reviewer''s comment is usually a claim -- is this actually a problem, does this
path really run, was it handled elsewhere -- and settling it means reading the
code the comment points at. That is what the agent is for, but the only way to
hand it one was to paste the text into the chat box, dropping the anchor and the
authorship on the way.

The reference button attaches the comment as implicit context for the next
question, so "is this right?" is a complete question. No IPC change was needed:
agent:ask already carries referencedContext for the diff selection, and the two
compose, since asking whether a comment is right about a selected region needs
both.

Cross-pane state goes in a store for the same reason the diff selection does:
the comment surfaces and ChatPane are siblings with no common owner below App.

Both comment surfaces get it, identically -- toggle to release, a chip with a
clear button, released on send, cleared on PR switch. DraftZone does not: a
draft is a comment not yet written by anyone else, so there is no claim to
investigate.

The glyph is the existing ShareIcon rather than something agent-flavoured,
because that is already what "reference" looks like in this app (the finding
reference button); one gesture should not have two icons.

The prompt says what to do with the comment, not just what it says. Without
that instruction a model tends to paraphrase the comment back instead of
checking it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Investigating a comment usually ends in replying to it, and retyping the
conclusion by hand was the remaining manual step.

This needs the answer to know which comment it answers, so a referenced comment
now hands off on send rather than being discarded: it detaches from the input
bar but stays associated with the round it was asked in. The hand-off runs on
every send, including unreferenced ones -- that is what ends a previous
association, so an unrelated later answer never offers itself as a reply to an
old comment. Memory only, one round: an association that outlived its round
would attach an answer to the wrong comment, and that is worse than not offering
the action at all.

It produces a draft, not a posted reply. The words are the agent''s and
publishing under the user''s name is the user''s call, so it lands in the same
draft pool as every other pending reply -- editable, rejectable, published with
the review batch. No IPC change: drafts:create already models a reply through
replyTo, and the comment''s anchor carries over so an inline reply keeps its
position in the diff.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ions

The icon button sized itself to its glyph (line-height:1, its own padding) while
the text buttons beside it size to a font-size line box, so it stood taller than
the row it sits in.

Both surfaces now take the same padding and font-size as the text buttons, so
the line box -- and therefore the height -- is theirs; the inline zone simply
stops overriding the shared rule it already belongs to. The svg is display:block
so it does not sit on the text baseline and add descender space underneath.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@huhamhire huhamhire added the enhancement New feature or request label Sep 9, 2026
@huhamhire
huhamhire merged commit 1151211 into dev Sep 9, 2026
3 checks passed
@huhamhire huhamhire mentioned this pull request Sep 9, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant