diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx index f0188af478c0..34bbf16724bd 100644 --- a/apps/web/src/components/ChatView.tsx +++ b/apps/web/src/components/ChatView.tsx @@ -4406,14 +4406,28 @@ function ChatViewContent(props: ChatViewProps) { linkedPullRequest: linkedThreadPullRequest, linkedPullRequestStatus, }); - // The right panel offers the thread's own change request, so it can only offer it once the - // branch has one; until then the picker says so rather than opening an empty panel. + // The right panel offers the thread's own change request, else the checkout's open one: the + // same one the git menu's "View PR" opens in this panel. A shared checkout keeps the recorded + // thread branch strict (#4460), so an agent that branches and opens a PR mid-thread leaves the + // thread without one while the checkout has it. A linked PR is the thread's own even while + // its detail is still loading, so the checkout never stands in for it. Without either the + // picker says so rather than opening an empty panel. + const checkoutPr = + linkedThreadPullRequest === null && gitStatusQuery.data?.pr?.state === "open" + ? gitStatusQuery.data.pr + : null; const addPullRequestSurface = useCallback(() => { - if (activeThreadPr === null) return; - openThreadPullRequest(activeThreadPr.number); - }, [activeThreadPr, openThreadPullRequest]); + if (activeThreadPr !== null) { + openThreadPullRequest(activeThreadPr.number); + } else if (checkoutPr !== null) { + openProjectPullRequest(checkoutPr.number); + } + }, [activeThreadPr, checkoutPr, openProjectPullRequest, openThreadPullRequest]); const pullRequestSurfaceAvailable = - supportsPullRequests && activeThreadPr !== null && threadRepository !== null; + supportsPullRequests && + (activeThreadPr !== null + ? threadRepository !== null + : checkoutPr !== null && activeProjectRepository !== null); // Primitive slice of the displayed PR for the settle-rule memos below: // resolveDisplayedThreadPr returns a fresh object every render, so memoize // on the fields the rules read instead of the object identity. diff --git a/apps/web/src/components/RightPanelTabs.tsx b/apps/web/src/components/RightPanelTabs.tsx index 9d057a3d2980..644b0b696b05 100644 --- a/apps/web/src/components/RightPanelTabs.tsx +++ b/apps/web/src/components/RightPanelTabs.tsx @@ -99,7 +99,7 @@ const SURFACE_DISABLED_REASONS = { terminal: "Terminal surfaces are only available from a project thread.", files: "Files are only available when a project is open.", diff: "Diff is only available for server threads in Git repositories.", - pullRequest: "This thread's branch has no pull request yet.", + pullRequest: "This branch has no pull request yet.", agents: "Agents are only available from a thread.", } as const;