Skip to content

feat(desktop): redesign pull requests screen with split-pane view, code diff tab, and review comments - #6682

Draft
AviPeltz wants to merge 6 commits into
mainfrom
debug-pr-screen-fetch
Draft

AviPeltz wants to merge 6 commits into
mainfrom
debug-pr-screen-fetch

Conversation

@AviPeltz

@AviPeltz AviPeltz commented Aug 19, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • List: split-pane layout (list + detail side by side) with role-based All / Reviewing / Authored tabs. All shows a grouped "my work" dashboard (Needs my review / Previously reviewed / Authored); Reviewing mirrors that as two full sections (GitHub's search API rejects qualifier-level OR, so it can't be one combined query); Authored reuses the existing flat, fully paginated list. Rows show status-dot-on-icon, diff stats, and branch name.
  • Detail: header redesign with Review / Summary / Code / Checks tabs.
    • Review is backed by new getThreads/setThreadResolution procedures and reuses CommentThread (refactored to a pure presentational component so it works outside a workspace context).
    • Code is a new file tree + diff viewer built on @pierre/trees/@pierre/diffs, matching the workspace Changes pane — resizable/collapsible tree, split/unified toggle, backed by a new getDiff procedure.
  • Backend: search-pull-requests now enriches results with additions/deletions/headRefName via the existing GraphQL checks-enrichment call (no extra round trips), and accepts a viewerRelationship qualifier for the grouped list sections.

Bugs fixed along the way

  • Duplicate-path crash in the Code tab: gh pr diff --patch emits one diff --git block per commit, so a file touched across multiple commits produced a duplicate tree path and crashed @pierre/trees. Switched to the plain cumulative diff, plus a defensive dedupe as a backstop.
  • Unscrollable diff: the pull-requests layout's Outlet wrapper wasn't a flex container, so tall diff content overflowed invisibly past an ancestor's overflow:hidden with no scrollbar anywhere to reach it.
  • Borderless "Open" state pill.
  • Original PR-screen "Failed to fetch" investigation (offline-host routing) from earlier in this branch.

Test plan

  • bunx tsc --noEmit clean on apps/desktop and packages/host-service
  • bunx biome check clean on all touched files
  • bun test passes for pull-requests (13/13)
  • Verified live end-to-end over CDP against the running dev app: list tabs/grouped sections, split-pane detail, Review tab (real threads/comments), Code tab (multi-file diffs, scroll, resize, split/unified toggle, the duplicate-path crash repro + fix)
  • Manual review of the design against the Figma references

https://claude.ai/code/session_01DyR8ibewWvkhknCgKtpfXL


Summary by cubic

Redesigns the desktop Pull Requests screen to a split-pane list + detail with role-based tabs and adds Code and Review tabs to the detail view. This replaces the old flat list/minimal detail and prevents noisy errors by skipping known‑offline hosts.

  • UI
    • List: All (grouped “Needs my review”/“Previously reviewed”/“Authored”), Reviewing (two sections; GitHub search rejects qualifier‑level OR), and Authored (flat, paginated). Rows show status dot, diff stats, and branch.
    • Detail: new Review/Summary/Code/Checks tabs. Code uses @pierre/trees and @pierre/diffs with file tree, resize/collapse, and split/unified toggle. Review shows threads and supports resolve; CommentThread is now presentational.
  • Backend
    • Adds pullRequests.getDiff, pullRequests.getThreads, and pullRequests.setThreadResolution.
    • search-pull-requests accepts viewerRelationship and enriches rows with additions/deletions/headRefName via the existing GraphQL pass (no extra calls).
  • Reliability and fixes
    • useHostTargetUrl avoids routing to known‑offline hosts; detail page maps NOT_FOUND TRPCClientError to an “update device” prompt.
    • Switches from gh pr diff --patch to cumulative diff and defensively dedupes paths; fixes unscrollable diff and borderless “Open” pill.
  • Routing and filters
    • New URL params: state=open|all|merged, tab=all|reviewing|authored. Filter store persists mergedOnly and viewTab; merged takes precedence over all when serializing.

Rollout

  • Deploy desktop and host-service together. The UI degrades gracefully on older hosts, but the Review and Code tabs require the new pullRequests.getDiff/getThreads/setThreadResolution procedures.

Written for commit 2d97798. Summary will update on new commits.

Review in cubic

useHostTargetUrl built a relay URL for any host purely from orgId+hostId,
with no online check, so the Pull Requests screen (list and detail) fired
real fetches at hosts that are confirmed offline and surfaced the raw
network/JSON-parse failure as a persistent red error banner. It now
consults useKnownHosts and returns null for a host it knows is offline,
matching the pattern already used for workspace/project/sidebar-PR fans;
downstream `enabled: !!hostUrl` guards then skip the doomed fetch instead
of erroring, and Delete Project correctly reports no reachable host
instead of attempting one.

The PR detail page also now distinguishes a NOT_FOUND TRPCClientError
(host reachable, but its host-service predates the pullRequests.getContent
procedure) from other errors, showing an "update your device" message
instead of the raw fetch/parse text.

Claude-Session: https://claude.ai/code/session_01DyR8ibewWvkhknCgKtpfXL
…de diff tab, and review comments

Rebuilds the pull requests screen end to end:

- List: split-pane layout (list + detail side by side) with role-based
  All/Reviewing/Authored tabs. All shows a grouped "my work" dashboard
  (Needs my review / Previously reviewed / Authored); Reviewing mirrors
  that as two full sections since GitHub's search API rejects
  qualifier-level OR; Authored reuses the existing flat, paginated list.
  Rows show status-dot-on-icon, diff stats, and branch name.

- Detail: header redesign with Review/Summary/Code/Checks tabs. Review
  is backed by new getThreads/setThreadResolution procedures and reuses
  CommentThread (refactored to a pure presentational component so it
  works outside a workspace context). Code is a new file tree + diff
  viewer built on @pierre/trees and @pierre/diffs, matching the
  workspace Changes pane — resizable/collapsible tree, split/unified
  toggle, backed by a new getDiff procedure.

- Backend: search-pull-requests now enriches results with additions/
  deletions/headRefName via the existing GraphQL checks-enrichment call
  (no extra round trips), and accepts a viewerRelationship qualifier for
  the grouped list sections.

Fixes found via live testing along the way: a duplicate-path crash in
the Code tab (gh pr diff --patch emits one diff --git block per commit,
so a file touched across commits produced a duplicate tree path —
switched to the plain cumulative diff, plus a defensive dedupe), an
unscrollable diff (the pull-requests layout's Outlet wrapper wasn't a
flex container, so tall content overflowed invisibly past an ancestor's
overflow:hidden with no scrollbar to reach it), and a borderless "Open"
state pill.
@coderabbitai

coderabbitai Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ea4a6bef-98f8-46fb-ad21-a5249eb59009

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) ✅ View Branch
Vercel API (Vercel) ✅ Open Preview
Vercel Web (Vercel) ✅ Open Preview
Vercel Marketing (Vercel) ✅ Open Preview
Vercel Admin (Vercel) ✅ Open Preview
Vercel Docs (Vercel) ✅ Open Preview

Preview updates automatically with new commits

AviPeltz added a commit that referenced this pull request Aug 20, 2026
…merge, close, and reopen (#6710)

* feat(desktop): pull requests split-view layout foundation

Keep the PR list persistently mounted in a fixed left pane while the
route's child content (empty state or detail) renders in the flexible
right pane via Outlet, so switching PRs no longer unmounts the list and
loses scroll/pagination state. Adds a collapse toggle in the shared
layout (available on every child route, including the empty index) and
a matching rounded-corner/color treatment when the app sidebar is
collapsed. Detail page loses its now-redundant back button and its
full-browser-width centering, since the list is always reachable.

Tab bar, diff/review tabs, and author-filter combobox are deliberately
out of scope for this PR.

* feat(desktop): richer PR list — row visuals, role tabs, grouped dashboard

Ports the list-view portion of the PR-screen redesign (#6682)
onto the split-view foundation: All/Reviewing/Authored tabs, an "All" tab
dashboard grouping PRs by viewer relationship (Needs my review / Previously
reviewed / Authored), a two-line PullRequestRow (status-dot-on-icon, avatar,
diff stats, branch name), and a consolidated Filters popover (State/Repository/
Author/Reviews) replacing the old always-expanded filter row. Backend enriches
search-pull-requests with additions/deletions/headRefName via the existing
GraphQL checks call (no extra round trips) and a viewerRelationship qualifier
for the grouped sections.

Deliberately does not adopt that PR's list-pane collapse/toggle placement
(detail-page-only, via a separate non-persisted store) — this branch already
fixed that dead end by keeping the toggle in the shared layout. Also restores
a window-drag filler in the new top bar that the source PR dropped, and keeps
the Code/Review detail tabs, PRDetailHeader redesign, and getDiff/getThreads
backend out of scope for a later PR.

* fix(desktop): match list view to Figma spec — flat list, no role tabs

Replaces the role-based All/Reviewing/Authored tabs and grouped "my work"
dashboard from the previous commit with what the PRListView Figma frame
(node 3157-1146) actually specifies: All/Open/Merged state tabs over a
single flat, paginated list — matching the design system's source of truth
rather than the exploratory GitHub PR this was ported from.

Row layout now follows the frame precisely: icon, title, and a tight
avatar/repo/#/branch meta line on the left, with relative time and diff
stats stacked in a right-aligned column instead of inline after the title.
Drops the status-dot icon badge, which the frame doesn't show. The Filters
popover keeps Repository/Author/Reviews now that State is a primary tab.

PullRequestGroupSection, PullRequestsGroupedContent,
PullRequestsReviewingContent, and the viewerRelationship util are removed
as unused. The backend's viewerRelationship qualifier is left in place,
unused but harmless, in case a future PR revisits grouped views.

* feat(desktop): resizable pull-requests split view, list/preview-only modes

Wraps the list pane in the app's existing ResizablePanel (already used for
the app sidebar), so dragging the divider resizes it between 300-720px,
double-clicking resets to the 420px default, and the width persists.

Adds a second collapse direction: PullRequestDetailToggle, the mirror image
of the existing PullRequestListToggle, lives in the list's own top bar so
it stays reachable even when the detail pane is fully hidden. The two
collapse flags are mutually exclusive — expanding one always collapses the
other, since hiding both would leave nothing on screen.

Also gives the pull-requests search input a visible bg-muted fill instead
of blending into the pane background, via a new optional className prop on
the shared WorkItemsSearch component (left at its default elsewhere).

* fix(desktop): show filter values in the pull-requests Filters popover

Repository/Author/Reviews each hid their label behind an @4XL:inline
container-query class, tuned for the old wide inline toolbar row. Crammed
into the new ~320px Filters popover, that breakpoint never fires, so every
row rendered as a bare icon + chevron with no indication of the selected
value and a large dead-space gap — the "weird" dropdown.

Fixes the two PR-scoped filters (Author, Reviews) directly. ProjectFilter
is shared with the Tasks top bar, which still relies on the width-gated
label, so it gets an opt-in `alwaysShowLabel` prop instead of a default
change. Restructures each popover row to `flex justify-between` so the
label and the (now-visible) value/chevron actually sit on one line, which
`space-y-1.5` around an inline label span never did correctly.

* feat(desktop): lighter PR icon + live author-contributor dropdown

PRIcon: swaps the open/draft glyph for lucide's git-pull-request-arrow
(matching the Figma spec) and sets strokeWidth 1 on every state's icon
(open, merged, closed, queued) for a consistent, lighter line weight.

AuthorFilter: replaces the free-text-only popover with a searchable
combobox listing the selected repo's actual contributors (avatar + login),
backed by a new host-service procedure, getRepoContributors, that shells
to `gh api repos/{owner}/{repo}/contributors` and caches the result for 5
minutes per repo. Falls back to the original free-text entry — including a
"Filter by @<text>" option for anyone not in the top 100 contributors —
when zero or multiple repos are selected, since there's no single
contributor set to list in that case.

* feat(desktop): merge/close/reopen actions on the PR detail page

Replaces the flat spacer in the header with a state-tinted badge (Open/
Draft/Closed/Merged, matching PRStatusGroup's color language from the v2
workspace sidebar) so the header reads as complete instead of leaving a
dead gap between the PR number and the action buttons.

Adds a single actions dropdown, gated on state: mergeable PRs (open,
non-draft) get Squash/merge-commit/rebase options via the existing
host-service github.mergePR mutation (Octokit-backed, already used by the
v2 sidebar's own merge dropdown) plus Close; non-mergeable open PRs get
just Close; closed PRs get Reopen. Merge and close both confirm via an
AlertDialog with the specific PR title/method in the copy; reopen is
immediate since it's non-destructive. All three invalidate both the detail
and list queries on success so state updates everywhere at once. The
merge trigger gets a subtle emerald tint when active, echoing GitHub's own
green merge button.

New host-service procedure: pullRequests.setState (open/closed via
`gh pr close`/`gh pr reopen`) — no equivalent existed; merge reuses
github.mergePR rather than adding a duplicate gh-CLI-based one.

Verified live via CDP end-to-end for both flows (dropdown → confirm dialog
→ cancel) without executing a real mutation against the shared repo.

* fix(desktop): remove the PR detail header's double toolbar, align pane borders

The list-collapse toggle rendered in its own row above the PR detail
page's own header, stacking two near-empty toolbars. Render it inline
in the detail header instead (still rendered from layout.tsx for the
index route, which has no header of its own), tighten the header's top
padding, and pad the bottom just enough that its border lines up with
the list pane's toolbar. Also swap the close-PR action's icon from a
generic X to git-pull-request-closed, matching the other PR icons.

* fix(desktop,host-service): address code-review findings on the PR split view

Fixes 15 issues surfaced by review of PR #6710:

- Direct #N PR lookups now apply mergedOnly/viewerRelationship, matching
  the search path, so they can't leak a PR into the wrong tab/grouping
- Schema rejects combining viewerRelationship with author/review
- Merge resolves the repo live (new pullRequests.mergePR procedure) instead
  of trusting a project's cached repoOwner/repoName, matching setState;
  setState's mutationFn now throws instead of silently no-opping
- Selecting a PR row now expands a collapsed detail pane instead of
  navigating into a hidden pane
- The list pane stays one stable element type across detail-collapse
  toggles, so it no longer remounts and loses scroll/pagination state
- Merge's confirm dialog no longer uses destructive (red) styling
- Restored per-row CI check status in the PR list
- Repo-slug label renders independent of the author avatar (was hidden
  for authorless/bot PRs)
- Guarded against unparsable updatedAt producing NaN
- Fixed cross-repo PR selection collision when no project is in scope
- Author filter: popover no longer goes blank on a failed contributor
  fetch, live search strips a leading "@", and custom-option matching is
  case-insensitive
- get-repo-contributors handles a repo's empty (204) response instead of
  crashing, and falls back to Octokit like its sibling procedure
- Minor a11y: Filters button announces the active count, state tabs use
  radiogroup/radio semantics

Claude-Session: https://claude.ai/code/session_01299739VL1C3UdwH1mSkVY2
@github-actions

Copy link
Copy Markdown
Contributor

This PR has had no activity for 53 days and will close in 7 days unless there is new activity. If this contribution is still important or relevant, please leave a comment to keep it open. If it closes, you are welcome to reopen it or ask a maintainer to reopen it. Thank you for contributing!

This branch was previously deployed

1 inactive deployment
preview — 2d977983 Deployed Aug 19, 2026 by AviPeltz via Deploy Docs #8138
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant