Skip to content

feat: expand pull request review context and panel tabs - #5546

Merged
maria-rcks merged 10 commits into
pingdotgg:stack/pr-4849-basefrom
maria-rcks:feat/pull-requests-page
Aug 6, 2026
Merged

feat: expand pull request review context and panel tabs#5546
maria-rcks merged 10 commits into
pingdotgg:stack/pr-4849-basefrom
maria-rcks:feat/pull-requests-page

Conversation

@maria-rcks

@maria-rcks maria-rcks commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Dependency

This is an upstream stacked follow-up to #4849. It is based directly on #4849's current head (08225ba0) and is not intended to replace that PR.

The temporary upstream base branch stack/pr-4849-base points exactly at that commit so this PR's commit list and Files changed view contain only this follow-up:

  • 92f8ba5e1 refactor(web): share diff rendering foundations
  • 8b10e5bf0 feat(pull-requests): expand omitted diff context
  • 9393ecc32 feat(web): keep pull requests open as panel tabs

This PR should merge only after #4849. Once #4849 lands, retarget this PR to main and delete the temporary base branch.

Why

The in-app review flow in #4849 had three connected gaps:

  1. Host patches contain only changed hunks. Expanding omitted lines therefore could not work reliably, especially when the local checkout did not have the pull request's exact remote revisions.
  2. Diff styling, virtualized geometry, and inline comment composition had drifted across the thread diff, file preview, and pull request review surfaces.
  3. A thread treated its pull request panel as a singleton, so opening another review replaced the first instead of preserving both as tabs. The compact panel chrome also did not reflect refreshed pull request state.

What changed

Shared diff foundations

  • Added StyledDiffCodeView, the single web adapter around Pierre's CodeView. It keeps app styling and virtualized row measurements together so visual changes cannot silently desynchronize scrolling geometry.
  • Replaced the file-only LocalCommentAnnotation and pull-request-only composer with DiffCommentAnnotation, shared by file previews, thread diffs, and pull request diffs.
  • Extracted normalized full-file loaders with comparison-scoped cache keys for local Git comparisons and host-backed pull request comparisons.
  • Added a lint restriction that directs new CodeView usage through the shared adapter.

Expand omitted pull request context

  • Added the typed pullRequests.diffFileContents RPC through contracts, authorization, WebSocket dispatch, client-runtime state, the pull request service, and provider adapters.
  • GitHub resolves either the pull request base/head pair or a selected commit's parent/head pair, then reads both revisions through the raw contents API.
  • GitLab performs the equivalent lookup with merge-request diff refs or commit parent refs and the repository files API.
  • New, deleted, changed, and renamed files are handled explicitly. Invalid commit SHAs, binary files, unsupported hosts, and files above the 1 MB expansion limit produce bounded errors.
  • The pull request Code tab supplies Pierre with full-file contents, so readers can reveal omitted context without checking out or fetching the review branch locally. Commit-scoped diffs retain a separate comparison identity.

Keep reviews in compact panel tabs

  • Pull request surfaces are keyed by project, repository, and number instead of one singleton ID. Existing persisted singleton state migrates to the new shape.
  • Multiple reviews can coexist as peer tabs beside a thread, and refreshed open/draft/closed/merged state colors the corresponding tab icon.
  • Empty-panel actions correctly disable Terminal when there is no project thread, and the pull request page can collapse and restore its detail panel with the standard layout control.
  • The detail header now centers repository, pull request number, title, author, branches, changed-file count, and additions/deletions. The head branch can be copied directly, conflicts have a dedicated actionable row, and secondary agent handoffs live in the overflow menu.
  • Reviewer display is condensed into accessible avatar stacks, while duplicate title, branch, and state metadata is removed from the Summary tab.
  • User documentation calls out opening linked reviews in compact right-panel tabs without leaving the conversation.

Impact and scope

  • GitHub and GitLab reviews can reveal unchanged context directly in the in-app diff.
  • File previews, thread diffs, and pull request diffs share the same comment interaction and rendering geometry.
  • Readers can retain several pull request reviews beside a thread rather than losing the previous one when another opens.
  • Providers without a diff-file API keep their existing behavior; the capability remains optional at the adapter boundary.
  • The UI changes apply to web and the desktop surface that wraps it. No separate mobile UI behavior is introduced.

Validation

vp test run \
  apps/web/src/components/diffs/DiffCommentAnnotation.test.tsx \
  apps/web/src/components/diffs/StyledDiffCodeView.test.tsx \
  apps/web/src/lib/diffFileContents.test.ts \
  apps/web/src/rightPanelStore.test.ts \
  apps/web/src/components/diffs/AnnotatableCodeView.test.tsx \
  apps/web/src/components/pullRequest/pullRequestDiff.logic.test.ts

6 test files passed, 47 tests passed.

Built with GPT-5.6 Sol via the Codex harness in T3 Code.


Note

Medium Risk
Touches multi-provider PR listing cursors, new host API paths for file contents, and persisted right-panel state migration; mistakes could skip or duplicate list rows or mis-handle auth/binary files.

Overview
Extends in-app pull request review so readers can expand omitted diff context without a local checkout, keep several PRs open as right-panel tabs, and see consistent diff rendering and inline comments across thread diffs, file previews, and PR reviews.

Diff file expansion: New pullRequests.diffFileContents RPC (auth, WS, service, client atoms) fetches full old/new file text at the revisions used for the patch on GitHub and GitLab (1 MB cap, binary/oversized errors, root commits for new files). Providers wire through getDiffFileContents; the PR Code tab uses shared loaders like the thread DiffPanel.

Shared web diff layer: StyledDiffCodeView centralizes Pierre CodeView styling and virtualized geometry; DiffCommentAnnotation replaces the file-only composer. DiffPanel drops inline CSS in favor of the shared adapter and createGitDiffFileContentsLoader.

Panel tabs: PR surfaces are keyed by project/repository/number; tab icons reflect open/draft/closed/merged state from the detail panel. Terminal is disabled in the empty state when there is no project thread.

Provider pagination and robustness: Azure DevOps and GitLab list APIs return cursorAdvance (including malformed raw rows) and keep fetching until pages fill; GitLab continuation uses offset instead of updated_before. GitHub’s search-free fallback applies local state/involvement filters, grows scan up to 1k rows, and tracks team review requests. Bitbucket paginates diffstat, commits, and checks; 401-only maps to unauthenticated. Process output gains stdoutInvalidUtf8 / stderrInvalidUtf8 via decodeUtf8 for safer blob reads.

Permissions fix: When review-thread GraphQL fails, GitHub no longer assumes the viewer authored the PR (didAuthor: false).

Reviewed by Cursor Bugbot for commit d513604. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add tabbed right panel for pull request reviews with full diff file contents expansion

  • The pull requests route replaces its single resizable detail pane with a right panel that supports multiple simultaneous PR tabs; each tab is keyed by PR identity and shows status-aware icons (open/draft/closed/merged).
  • A new pullRequests.diffFileContents RPC fetches full old/new file contents for diff entries, backed by provider-specific implementations for GitHub, GitLab, and Bitbucket; binary and oversized files (>1 MB) are rejected with structured errors.
  • listMergeRequests and listPullRequests pagination switches to stable offset-based cursoring using a cursorAdvance field that counts raw rows consumed including malformed ones.
  • Bitbucket commits, checks, and diffstat aggregation now follow next pagination links to retrieve complete multi-page results.
  • DiffCommentAnnotation replaces LocalCommentAnnotation/ReviewCommentComposer across diff surfaces, gaining configurable labels, an optional secondary action (AI Ask), and a pending guard; a shared StyledDiffCodeView wrapper centralizes diff viewer styling.
  • PullRequestReviewBar now snapshots comments at submit time and only removes those exact IDs afterward, preventing accidental loss of new drafts added during submission.
  • Risk: RIGHT_PANEL_STORAGE_VERSION bumps to 9, triggering migration of persisted right-panel state; legacy singleton pull-request surfaces are rebuilt with reference-keyed IDs.

Macroscope summarized d513604.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. 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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 60eda22e-09ac-4373-9412-25c2767e44af

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.

@macroscopeapp macroscopeapp 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.

Effect service conventions

Reviewed the Effect service code in this PR's changed scope, focused on the follow-up commits (92f8ba5e1..9393ecc32) that add the pullRequests.diffFileContents path through the provider CLIs, provider port, service, RPC and client runtime.

Service shape is fine: Context.Service tags with inline interfaces, namespace imports from effect/* subpaths, make + layer in canonical order, Foo["Service"] member types, dependencies acquired with yield* Foo.Foo, no ManagedRuntime/runPromise outside application boundaries, and the optional getDiffFileContents port member is guarded by the provider capability rather than faked.

Four findings, all the same convention: the new non-decode failures in getPullRequestDiffFileContents / getMergeRequestDiffFileContents are funnelled into the decode-oriented *ReadError with a manufactured new Error(...) as cause, which both invents a cause where no failure occurred and leaves the real context (file path, why the read is refused) only inside a string. Both files already model this class of outcome as its own tagged error (GitHubDiffCursorError, GitHubDiffCommitError, GitLabDiffCommitError, GitLabViewerUnavailableError), so the fix follows the sibling pattern.

Posted via Macroscope — Effect Service Conventions

Comment thread apps/server/src/pullRequest/GitLabPullRequestCli.ts
Comment thread apps/server/src/pullRequest/GitHubPullRequestCli.ts Outdated
Comment thread apps/server/src/pullRequest/GitLabPullRequestCli.ts Outdated
Comment thread apps/server/src/pullRequest/GitHubPullRequestCli.ts Outdated
@maria-rcks

Copy link
Copy Markdown
Collaborator Author

Closing because targeting main included the unmerged ancestry from #4849 instead of showing only this follow-up's three commits.

@maria-rcks maria-rcks closed this Aug 6, 2026
@maria-rcks maria-rcks reopened this Aug 6, 2026
Comment thread apps/web/src/components/pullRequest/PullRequestTimelineTab.tsx
Comment thread apps/server/src/pullRequest/GitLabPullRequestCli.ts
Comment thread apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx Outdated
Comment thread apps/server/src/pullRequest/bitbucketPullRequestJson.ts
Comment thread apps/server/src/pullRequest/GitHubPullRequestProvider.ts Outdated
Comment thread apps/web/src/components/pullRequest/PullRequestReviewBar.tsx Outdated
Comment thread apps/server/src/pullRequest/bitbucketPullRequestJson.ts
Comment thread apps/server/src/pullRequest/GitHubPullRequestCli.ts
Comment thread apps/server/src/pullRequest/GitHubPullRequestCli.ts
Comment thread apps/web/src/components/pullRequest/PullRequestReviewBar.tsx Outdated
@maria-rcks
maria-rcks changed the base branch from main to stack/pr-4849-base August 6, 2026 20:12
Comment thread apps/web/src/routes/_chat.pull-requests.tsx Outdated
@maria-rcks
maria-rcks marked this pull request as ready for review August 6, 2026 20:18
Comment thread apps/server/src/pullRequest/GitLabPullRequestCli.ts
Comment thread apps/web/src/components/ChatView.tsx
@macroscopeapp

macroscopeapp Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR adds a substantial new feature enabling diff file expansion in pull request reviews and multi-tab PR support. It introduces a new RPC endpoint, implements new provider methods across GitHub/GitLab/Azure DevOps/Bitbucket, refactors pagination logic, and changes the UI panel architecture. The scope and new capabilities warrant human review.

You can customize Macroscope's approvability policy. Learn more.

Comment thread apps/web/src/routes/_chat.pull-requests.tsx Outdated
Comment thread apps/server/src/pullRequest/GitLabPullRequestCli.ts Outdated
Comment thread apps/server/src/pullRequest/GitHubPullRequestCli.ts
Comment thread apps/server/src/pullRequest/GitHubPullRequestCli.ts
Comment thread apps/server/src/pullRequest/GitLabPullRequestCli.ts Outdated
Comment thread apps/server/src/pullRequest/GitHubPullRequestCli.ts
Comment thread apps/server/src/pullRequest/GitLabPullRequestCli.ts Outdated

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit aaf8a2b. Configure here.

Comment thread apps/server/src/pullRequest/GitHubPullRequestCli.ts
Comment thread apps/web/src/routes/_chat.pull-requests.tsx
@maria-rcks
maria-rcks merged commit 71fe93a into pingdotgg:stack/pr-4849-base Aug 6, 2026
6 of 7 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