Skip to content

feat(mobile): add a native pull-request manager - #6398

Open
SergeSerb2 wants to merge 5 commits into
pingdotgg:mainfrom
SergeSerb2:feat/mobile-native-pull-requests
Open

feat(mobile): add a native pull-request manager#6398
SergeSerb2 wants to merge 5 commits into
pingdotgg:mainfrom
SergeSerb2:feat/mobile-native-pull-requests

Conversation

@SergeSerb2

@SergeSerb2 SergeSerb2 commented Aug 12, 2026

Copy link
Copy Markdown

What Changed

Mobile now has the same in-app pull-request workspace desktop already has: a list, a detail view (Overview / Conversation / Files), comments, reviews, reviewers, merge/close/reopen, and conflict/finding handoffs into a new thread. Home, the sidebar, and a thread's git controls open that manager instead of the system browser.

This reuses the existing server, contracts, and createPullRequestEnvironmentAtoms client-runtime — no new wire protocol. The UI is mobile-native (grouped lists, sheets, confirmations) rather than a squeezed copy of the desktop right panel.

Why

Desktop can manage a PR without leaving the app. Mobile still sent people to GitHub. That is the gap this fills.

I looked for an existing mobile manager on this repo (PullRequestsScreen, native PR routes). Thread-row PR badges exist; the manager does not.

UI Changes

New Pull Requests screen from the home/sidebar git-pull icon. Detail uses a segmented Overview / Conversation / Files layout with a bottom Merge / Resolve conflicts / Submit a review action.

Screenshots were not captured in this pass.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Test plan

  • Same implementation typechecks and unit-tests in the T3 Pretty tree (vp run --filter @t3tools/mobile typecheck; 50 focused tests)
  • vp test run on apps/mobile/src/features/pull-requests/*.test.ts
  • vp run --filter @t3tools/mobile typecheck
  • iOS: open Pull Requests from home and the sidebar, open a PR, comment/review/merge or resolve conflicts in a new thread
  • iOS: tap View PR from a thread's git controls and land in the native detail, not Safari

Model: grok-4.6

Made with Cursor

Note

Add a native pull request manager to the mobile app

  • Adds full pull request browsing, filtering, and detail views via new routes (PullRequests, PullRequestDetail, PullRequestDiff, PullRequestComment, PullRequestReviewers) registered in Stack.tsx.
  • Introduces useOpenNativePullRequest to route supported PR URLs to in-app screens, falling back to an external browser; replaces previous tryOpenExternalUrl calls in thread git controls and the git overview sheet.
  • Adds pull request entry points to the home header, workspace sidebar, and thread sidebar across iOS and Android.
  • Implements a unified diff parser (pullRequestDiffParse.ts) that handles multi-file patches, binary files, withheld hunks, renames, and paginated loading via usePullRequestDiffSlices.
  • Adds usePullRequestHandoff to check out a PR into a worktree and start a task thread directly from the detail view.
  • Adds list-side logic for grouping, ranking, debounced search, involvement filtering, diff stat merging, and partitioned pagination.
  • Risk: pullRequestDiffLoaderLayer is now merged into the runtime snapshot loader composition, which changes how the runtime is composed for all environments.

Macroscope summarized 98ed285.

Phone and iPad can now browse, review, merge, and resolve conflicts in-app instead of bouncing to the browser, matching the desktop PR workspace with mobile navigation and git-control entry points.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 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: d3ca4dac-fb68-400d-9b9b-f9d12714c33d

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 github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Aug 12, 2026
Comment thread apps/mobile/src/features/pull-requests/PullRequestsScreen.tsx
Comment thread apps/mobile/src/features/pull-requests/pullRequestDetail.logic.ts
Comment thread apps/mobile/src/features/pull-requests/PullRequestsRouteScreen.tsx Outdated
Comment thread apps/mobile/src/Stack.tsx
Comment thread apps/mobile/src/features/pull-requests/pullRequestDiffParse.ts Outdated
Comment thread apps/mobile/src/features/pull-requests/pullRequestDetail.logic.ts
Comment thread apps/mobile/src/features/pull-requests/PullRequestCommentSheet.tsx
Comment thread apps/mobile/src/features/pull-requests/usePullRequestList.ts Outdated
Comment thread apps/mobile/src/features/pull-requests/PullRequestDetailScreen.tsx
Comment thread apps/mobile/src/features/pull-requests/usePullRequestHandoff.ts
Comment thread apps/mobile/src/features/pull-requests/pullRequestDetail.logic.ts Outdated
Comment thread apps/mobile/src/features/pull-requests/PullRequestDetailScreen.tsx
Comment thread apps/mobile/src/Stack.tsx
@macroscopeapp

macroscopeapp Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

2 blocking correctness issues found. Diff is too large for automated approval analysis. A human reviewer should evaluate this PR.

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

Follow diff continuation cursors, gate native navigation on environment capability, refresh list and detail after mutations, and keep Hermes-safe sorts.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/mobile/src/features/pull-requests/PullRequestCommentSheet.tsx Outdated
Comment thread apps/mobile/src/features/pull-requests/usePullRequestDiffSlices.ts Outdated
Comment thread apps/mobile/src/features/pull-requests/PullRequestCommentSheet.tsx Outdated
Comment thread apps/mobile/src/features/pull-requests/usePullRequestHandoff.ts Outdated
Comment thread apps/mobile/src/features/pull-requests/usePullRequestDiffSlices.ts Outdated
Comment thread apps/mobile/src/features/pull-requests/usePullRequestHandoff.ts Outdated
Comment thread apps/mobile/src/features/pull-requests/usePullRequestDiffSlices.ts Outdated
…pace

Partial list failures, vanished host filters, and Azure-incapable Files/reviewer/verdict controls were offering actions the host cannot do. Empty Comment/Request-changes reviews could also send, and a paged diff could not refresh or retry.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/mobile/src/features/pull-requests/usePullRequestDiffSlices.ts Outdated
Opening a truncated file still showed the empty patch, Fix findings could run before review comments loaded, and a failed load-more hid its error behind already-visible rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread apps/mobile/src/features/pull-requests/pullRequestDiffParse.ts Outdated
Comment thread apps/mobile/src/features/pull-requests/pullRequestDiffParse.ts Outdated
Comment thread apps/mobile/src/features/pull-requests/pullRequestDiffParse.ts
Comment thread apps/mobile/src/features/pull-requests/PullRequestDiffScreen.tsx
Expanded files mounted every line at once, and header-only adds, deletes, and renames never called diffFileContents because /dev/null and mode lines were dropped. Pull-to-refresh also left GitHub row sizes stale, and host/project filters survived an environment switch.

Co-authored-by: Cursor <cursoragent@cursor.com>
return;
}
if (canContinue) {
setPage({ key: filterKey, size: pageSize, cursors: nextCursors });

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.

🟠 High pull-requests/usePullRequestList.ts:240

When nextCursors exists for only some repositories, loadMore requests the next page with the same pageSize, so repositories without cursors return the same rows and older PRs from them are never loaded. Increase the page size while continuing with nextCursors.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/mobile/src/features/pull-requests/usePullRequestList.ts around line 240:

When `nextCursors` exists for only some repositories, `loadMore` requests the next page with the same `pageSize`, so repositories without cursors return the same rows and older PRs from them are never loaded. Increase the page size while continuing with `nextCursors`.

Comment on lines +71 to +73
const scopeKey = reference
? `${reference.projectId}:${reference.repository}:${reference.number}`
: "";

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.

🟠 High pull-requests/PullRequestDiffScreen.tsx:71

Updating a mounted route between environments with the same project, repository, PR, and path leaves attemptedCursors populated from the previous environment, so matching cursors are skipped and pagination stops before the file is found. Include environmentId in scopeKey so the cursor-attempt state is reset for each environment.

Suggested change
const scopeKey = reference
? `${reference.projectId}:${reference.repository}:${reference.number}`
: "";
const scopeKey = reference
? `${environmentId}:${reference.projectId}:${reference.repository}:${reference.number}`
: "";
🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/mobile/src/features/pull-requests/PullRequestDiffScreen.tsx around lines 71-73:

Updating a mounted route between environments with the same project, repository, PR, and path leaves `attemptedCursors` populated from the previous environment, so matching cursors are skipped and pagination stops before the file is found. Include `environmentId` in `scopeKey` so the cursor-attempt state is reset for each environment.

@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 98ed285. Configure here.

authoredQuery.refresh();
reviewingQuery.refresh();
refreshStats();
}, [authoredQuery, baselineQuery, refreshList, refreshStats, reviewingQuery]);

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.

Stats refresh clears then goes stale

Medium Severity

refreshStats clears statsByRow immediately and only calls firstStatsQuery.refresh(), then the merge effect walks later chunks from still-cached SWR data. Focus/refreshQueries therefore blanks +/- counts, and after load-more past the 500-ref chunk size later pages can keep pre-invalidate stats.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 98ed285. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant