Skip to content

feat(web): cite text from pull request descriptions and comments - #329

Merged
adampeterhiggins merged 1 commit into
mainfrom
ah/cite-pr-text-selection
Oct 15, 2026
Merged

adampeterhiggins merged 1 commit into
mainfrom
ah/cite-pr-text-selection

Conversation

@adampeterhiggins

Copy link
Copy Markdown
Owner

You could cite a selection from an assistant response into the composer, but not from a pull request's description or comments in the sidebar. Quoting a reviewer meant copying and pasting their words, losing who said it and which PR it came from.

Selecting text there now shows the same Cite button. It puts one chip at the composer's caret, for example #327 · Description "The comment form now has a spli…". The chip previews the quote under its author's avatar, with the PR on top and a link back to the remark on GitHub. Nothing is sent. With no thread beside the panel, it opens one holding the chip.

Before

Selecting text in the description does nothing.

Before: selected description text, no action

After

After: Cite button beside the selection

After: the chip in the composer, previewing the quote under its author

How

  • PullRequestQuoteSource marks the rendered description and comment bodies, on both the Summary and Timeline tabs, with their author and link. PullRequestQuoteToolbar watches the panel for a selection inside one, using the selection capture and positioning the assistant Cite toolbar already uses. captureAssistantTextSelection takes the source selector as a parameter for this.
  • buildPullRequestQuoteContext builds one review-comment record. It carries the PR metadata, the quote as a one-remark thread, and instructions marking it as quoted, untrusted text. The contract is unchanged. Its id sits outside the hand-off namespace, so later hand-offs don't sweep it, and each citation is new.
  • isPullRequestSummaryContext now also requires no thread, so a quote that carries the PR renders as the quote, not as the whole-PR chip.
  • The chip's label uses the plain selection, and its preview keeps the formatting (bold, inline code) as Markdown. The Markdown serialization is shared with the assistant toolbar via serializeSelectedMarkdownQuote.
  • Mobile needs no change. The pull-request-quote: section id makes it a review-comment chip there, and its detail sheet already shows the PR and the review-comment card.

Testing

  • vp test run passes on the new buildPullRequestQuoteContext tests and the other PR panel and context-record suites I ran.
  • Web typecheck is clean.
  • Checked in the dev app on PRs beside a thread: cited a description and a comment, and checked the chip label, the preview card and the GitHub link. The selection was made with a script that fires the same events as a mouse drag, as the browser tools can only drag element to element.
  • Nine tests fail on main as well, in files this PR doesn't touch: the guide-stop handoff, ChatMarkdown permissions, AssistantCitationChip, MessagesTimeline and ThreadRelationshipsControl.

Implemented with Claude Opus 5.5 in Claude Code, driven from T3 Code.

🤖 Generated with Claude Code

Selecting text in a pull request's description or comments, on the Summary
or Timeline tab, shows the same Cite button as an assistant response. It
puts one chip at the composer's caret holding the quote under its author,
with the pull request it came from.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adampeterhiggins
adampeterhiggins merged commit 62ea3ff into main Oct 15, 2026
adampeterhiggins added a commit that referenced this pull request Oct 21, 2026
* test(server): restore fork tests dropped by the upstream sync

The upstream test cull in #415 removed fork-only coverage for subfolder
session import, imported-session resume, unguarded Claude overage silence
and MCP tool-name uniqueness across the fork's toolkits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(web): restore the command palette's fork actions lost in the upstream sync

Upstream sync #415 rebuilt the command palette and dropped the fork's
actions and views, leaving their hooks, reducer cases, and shortcuts
orphaned.

Restores, in the new structure:
- New thread from PR, branch, or issue; Import conversation…
- Export transcript, Show agents, Run scheduled task now (single task or
  a submenu, plus the run-scheduled-task open intent)
- Attach thread / Linear / Notion / Granola / Slack / Discord / GitHub
  issue / pull request / repository, and link/unlink for GitHub, Linear,
  Slack, Discord, Notion and Granola
- Open/close split view and focus the other pane; show/hide sidebar tabs
- The Needs attention submenu and its attentionInbox.open shortcut
- Deleting the `>` that came from the file picker returns to file search
- Thread search shows tab-group-name matches again
- Restart agent session goes through useRestartAgentSession

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(web): restore composer fork behaviour lost in the upstream sync

Upstream sync #415 split the composer and silently dropped several fork
behaviours. Port them back into the new structure:

- @ menu Chats tab (Files/Chats/Agents/Models): Files lists paths only,
  Chats lists sibling chat tabs then other threads, opens on Chats when only
  chats match, has its own empty states, and picking a chat tab captures its
  summary as a thread-tab chip at the caret.
- Pasted, stash-restored and draft-restored chips keep checkout, repository,
  thread-tab, issue, Slack/Discord/Notion/Granola, subagent, link and model
  context; stashing clears the thread's snapshot records.
- Chips inserted mid-message land at the insertion caret (pending snapshot).
- Citation comments get Save as draft and the Add to queue label.
- composer.saveDraft keybinding works again.
- A quick-message submit waits for attachment uploads.
- File rows whose bytes are being restored show "Restoring…".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(web): only the focused split pane's composer answers stash and save-draft keys

Restores the fork's split-pane guard dropped in the #415 sync. Both panes
mount a composer with a window-level key handler, so without it one shortcut
stashed or saved a draft in both panes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(web): restore fork timeline and file-link behaviour lost in the upstream sync

The #415 sync split MessagesTimeline and ChatMarkdown into smaller files and
dropped fork behaviour along the way. Port it into the new structure:

- Fork into new tab on user messages (onForkFromMessage through the row context)
- Tool-call and thought hover preview cards on collapsed work rows, with the
  expanded row and card sharing ToolCallDetails/toolCallDetailOutput
- Copyable path breadcrumbs on collapsed and live tool rows
- View diagnostics on failed turns
- Workspace changed divider for moved threads
- @handle and Attach to parent chat on the Subagent of divider
- Linear/Granola monochrome brand marks for tool activity icons
- File links follow the Open in default and extension rules, offer an Open with
  submenu and Open in T3 file viewer, and keep the registry mention hover
- Restored scroll offsets stay inside rows that rewrapped while hidden

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(web): restore PR panel, PR page, sidebar pin and work-log behaviour lost in the upstream sync

The upstream sync (#415) silently dropped several fork behaviours while
upstream split the PR panel and page into smaller components. Port them
back into the new structure:

- PR panel: cite quotes from descriptions and comments (#329) and save a
  fix or selection as a thread draft (#353) again; the Guide and Code tabs
  only offer drafts for server threads.
- PR header number, repository link and "Open on host" menu item follow
  the "Open links in" setting, and the number's context menu opens through it.
- Thread PR panel renders the watch status line again (#98).
- PR page filter counts read every involvement plus the search, ignore the
  unsearched baseline while a search is typed, show loading rows, and the
  applied filters render as removable pills below the controls.
- Pinned sidebar rows keep the pin trailing, outside the hover swap (#150).
- Work log labels read/search tools by what they did instead of "linked
  issues" (#424).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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