Skip to content

feat(panel): deep links to review threads in the Pull request tab - #3884

Merged
luke-agent[bot] merged 2 commits into
mainfrom
feat/pr-thread-deep-links
Oct 19, 2026
Merged

luke-agent[bot] merged 2 commits into
mainfrom
feat/pr-thread-deep-links

Conversation

@dastratakos

@dastratakos dastratakos commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Deep links for review comments in an agent's Pull request tab: press a thread in the Conversation to open it in Files changed, and back again. Each thread also gets a Luke link of its own.

What it does

A link place for one thread. It's LINK_PLACE.PULL_REQUEST_THREAD { planId, agentId, threadId, view }, written under the agent's Changes link:

https://tryluke.dev/<ws>/plan/<planId>/agent/<agentId>/changes/conversation/thread/<threadId>
https://tryluke.dev/<ws>/plan/<planId>/agent/<agentId>/changes/files/thread/<threadId>

threadId is GitHub's GraphQL node id for the thread (ReviewThread.id), the same id reply and resolve already use. Opening the link:

  1. openLink (use-tasks-tab) opens the agent's Pull request tab, reusing a shared tab the way CHANGES does, on the view the link names.
  2. It leaves a counted threadReveal ask on a context (thread-reveal.tsx), the same pattern as MessageReveal.
  3. The tab takes the ask, finds the thread in its conversation read, and brings it into view. If the read no longer holds that thread, a toast says so.

Both in-tab jumps call openPlace with this place, so they take the same route as a link from anywhere. Copy link in a thread's ⋯ copies the link for the view the thread is drawn in, through useCopyLinkItem.

Conversation → Files changed. Pressing a thread's file/lines header, or ⋯ › View in Files changed:

  • opens the file if it is collapsed or folded as viewed (new ChangesList.expand), and clears a filter that hides it
  • shows a minimized line's chip and opens the thread, even a resolved or outdated one
  • scrolls Pierre's list to the thread's line (new DiffListHandle.revealLine, using CodeView.scrollTo({ type: "line" }))
  • for a line no hunk shows, or an outdated thread, scrolls to the file header, where the above-the-diff list stands
  • lights the thread's lines in the lit range from feat(panel): select code to comment, keep several line comments open, and light a thread's lines on hover #3818 until its ring ends
  • rings the card (data-search-landed) and focuses its summary with preventScroll

A thread whose file is no longer in the diff gets a toast saying so, and is shown in the Conversation instead.

Files changed → Conversation. ⋯ › View in Conversation scrolls the Conversation's own scroller to the card (centreWithin, never scrollIntoView), then opens, rings and focuses it. A thread brought into view stays visible even if Hide resolved or Hide bots would hide it.

How the scroll stays right while things expand

The jump is a pending state that resolves over renders, not in one call:

  1. useListLanding opens the file, shows the chip, and records the place.
  2. PierreDiffList's reveal effect runs after its update effect, so Pierre already has the file open and its notes laid out. Only then does it call revealLine or reveal.
  3. Pierre keeps the target pending and re-resolves it every frame, and on every measurement, until it settles. Files above the thread that mount and measure taller on the way still land it in the right place.

The card's focus and ring wait, through focusSeek, until the card stands inside the list's box.

Screenshots

Light Dark
Conversation (press src/expiry.ts lines 34–35)
→ Files changed: file opened, scrolled to line 35, lines lit, thread ringed and focused
⋯ › View in Conversation: the card centred, ringed and focused
A thread's file and lines under the pointer: underlined, with the tooltip "View in Files changed"

Tests

  • luke-link.test: both views round-trip, plus refusals for a bad view, a misspelled step, a missing or trailing id, a taskless agent, and an id with characters outside the pattern.
  • use-tasks-tab.test: the route opens the Pull request tab, sets the view, and leaves counted asks; letting go of an older ask leaves the newer one standing.
  • agent-pull-request-tab.test:
    • a collapsed file plus a minimized thread, reached through the window's route: the file opens, the list scrolls to line 13, the lines light, the thread is ringed and focused, and the lines go out as the ring ends
    • a line outside the hunks, and an outdated thread: the list scrolls to the file header, and the folded thread opens above the diff
    • a file no longer in the diff: the thread stays in the Conversation and is shown there
    • Files changed → Conversation through Hide resolved
    • Copy link

Checks

  • pnpm check:affected ran out of memory on this sandbox (exit 137 on the service and web typecheck, and features workers timing out). I ran the fallback set instead, and it passed:
    • tsc for features, panel, desktop, ui and web
    • features vitest and the touched panel suites
    • ./scripts/oxlint.sh, biome
    • pnpm knip
    • ./scripts/repository-checks.sh
  • Desktop/panel and @luke/features/luke-link only, with no service change, so no Preview run is needed.

The stacked follow-up will open GitHub anchors (#discussion_r…, #issuecomment-…, #pullrequestreview-…) inside the tab.

Made with Luke

View guided diff Turn on auto-fix

A review thread gets a Luke link of its own, LINK_PLACE.PULL_REQUEST_THREAD
(`…/agent/<id>/changes/<conversation|files>/thread/<threadId>`), routed by
openLink to the agent's Pull request tab on the view it names, which brings
the thread into view by GitHub's node id.

- Conversation → Files changed: a thread's file and lines, or its ⋯'s View
  in Files changed, opens the file (collapsed or folded as viewed), clears a
  filter hiding it, shows a minimized line's chip, opens the thread, scrolls
  Pierre's list to its line (or the file's above-the-diff list for a line
  no hunk shows or an outdated thread), lights its lines until its ring ends,
  and moves the focus to it. A thread whose file left the diff says so and
  is shown in the Conversation instead.
- Files changed → Conversation: View in Conversation scrolls to, opens, rings
  and focuses the card there, standing through Hide resolved and Hide bots.
- Copy link in a thread's ⋯ copies its link in the view it is drawn in.

Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
@vercel

vercel Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
luke-web Ready Ready Preview Oct 19, 2026 6:40pm UTC

Request Review

luke-agent Bot added a commit that referenced this pull request Oct 19, 2026
Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
luke-agent Bot added a commit that referenced this pull request Oct 19, 2026
Co-authored-by: luke-agent[bot] <339870089+luke-agent[bot]@users.noreply.github.com>
@luke-agent
luke-agent Bot marked this pull request as ready for review October 19, 2026 18:37
@luke-agent
luke-agent Bot enabled auto-merge October 19, 2026 18:37
@luke-agent
luke-agent Bot added this pull request to the merge queue Oct 19, 2026

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

Comment thread packages/panel/src/tasks/agent-changes-tab.tsx
Comment thread packages/panel/src/tasks/thread-reveal.tsx
Merged via the queue into main with commit 4ac6afa Oct 19, 2026
11 checks passed
@luke-agent
luke-agent Bot deleted the feat/pr-thread-deep-links branch October 19, 2026 19:04

This branch was successfully deployed

1 active deployment
Preview — 8ddd1e50 Deployed Oct 19, 2026 by vercel[bot]
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