From 55456e0c2d5e51c33edb9ba3f665c5beafde882e Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Sat, 20 Jun 2026 03:00:52 -0700 Subject: [PATCH] Show branch-discovered PRs on worktrees with no linked PRs (#5894) Allow branch-discovered GitHub and GitLab PRs to display on the worktree card even when the worktree has no explicitly linked PR metadata. This is enabled by passing the review hint key option down and allowing the PR display logic to show neutral branch-level lookups when no linked review key is present. --- .../sidebar/WorktreeCard.pr-display.test.tsx | 24 +++++++++++++++++++ .../src/components/sidebar/WorktreeCard.tsx | 5 +++- .../sidebar/worktree-card-pr-display.test.ts | 18 +++++++++++++- .../sidebar/worktree-card-pr-display.ts | 14 +++++++++-- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/components/sidebar/WorktreeCard.pr-display.test.tsx b/src/renderer/src/components/sidebar/WorktreeCard.pr-display.test.tsx index ee145d69d..169858153 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.pr-display.test.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.pr-display.test.tsx @@ -247,6 +247,30 @@ describe('WorktreeCard linked PR display', () => { expect(markup).not.toContain('Stale branch PR') }) + it('shows branch-discovered GH PR status when the worktree has no linked PR', async () => { + settings = { experimentalNewWorktreeCardStyle: true } + hostedReviewCache = { + 'local::repo-1::feature/local-branch': { + data: makeHostedReview({ number: 456, title: 'Branch PR', state: 'open' }), + fetchedAt: Date.now(), + linkedReviewHintKey: '' + } + } + const { default: WorktreeCard } = await import('./WorktreeCard') + + const markup = renderWorktreeCardMarkup( + + ) + + expect(markup).toContain('PR checks: Passing') + expect(markup).toContain('text-emerald-500/80') + expect(markup).not.toContain('Branch') + }) + it('shows branch-discovered hosted review providers without linked worktree metadata', async () => { settings = { experimentalNewWorktreeCardStyle: true } hostedReviewCache = { diff --git a/src/renderer/src/components/sidebar/WorktreeCard.tsx b/src/renderer/src/components/sidebar/WorktreeCard.tsx index beaadc987..f20cdd23d 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.tsx @@ -409,7 +409,10 @@ const WorktreeCard = React.memo(function WorktreeCard({ linkedGitLabMR, linkedBitbucketPR, linkedAzureDevOpsPR, - linkedGiteaPR + linkedGiteaPR, + { + reviewHintKey: hostedReviewEntry?.linkedReviewHintKey + } ) const issue: IssueInfo | null | undefined = worktree.linkedIssue ? issueEntry !== undefined diff --git a/src/renderer/src/components/sidebar/worktree-card-pr-display.test.ts b/src/renderer/src/components/sidebar/worktree-card-pr-display.test.ts index 7baaeb091..4b2896852 100644 --- a/src/renderer/src/components/sidebar/worktree-card-pr-display.test.ts +++ b/src/renderer/src/components/sidebar/worktree-card-pr-display.test.ts @@ -60,7 +60,23 @@ describe('getWorktreeCardPrDisplay', () => { expect(getWorktreeCardPrDisplay(undefined, null)).toBeNull() }) - it('ignores cached branch PR details when the worktree is unlinked', () => { + it('ignores linked-lookup PR details when the worktree is unlinked', () => { + expect( + getWorktreeCardPrDisplay(pr, null, null, null, null, null, { + reviewHintKey: 'github:123' + }) + ).toBeNull() + }) + + it('shows branch-discovered GitHub PR details when the worktree is unlinked', () => { + expect( + getWorktreeCardPrDisplay(pr, null, null, null, null, null, { + reviewHintKey: '' + }) + ).toBe(pr) + }) + + it('treats missing cache hints as unsafe for unlinked GitHub PR details', () => { expect(getWorktreeCardPrDisplay(pr, null)).toBeNull() }) diff --git a/src/renderer/src/components/sidebar/worktree-card-pr-display.ts b/src/renderer/src/components/sidebar/worktree-card-pr-display.ts index 32dca723b..406f02290 100644 --- a/src/renderer/src/components/sidebar/worktree-card-pr-display.ts +++ b/src/renderer/src/components/sidebar/worktree-card-pr-display.ts @@ -21,6 +21,10 @@ export type WorktreeCardPrDisplay = status?: HostedReviewInfo['status'] } +type WorktreeCardPrDisplayOptions = { + reviewHintKey?: string +} + function getLinkedReviewNumber( provider: LinkedReviewMetadataProvider, links: LinkedReviewNumbers @@ -60,7 +64,8 @@ export function getWorktreeCardPrDisplay( linkedGitLabMR: number | null = null, linkedBitbucketPR: number | null = null, linkedAzureDevOpsPR: number | null = null, - linkedGiteaPR: number | null = null + linkedGiteaPR: number | null = null, + options: WorktreeCardPrDisplayOptions = {} ): WorktreeCardPrDisplay | null { const links = { linkedPR, @@ -75,7 +80,12 @@ export function getWorktreeCardPrDisplay( } const linkedReviewNumber = getLinkedReviewNumber(review.provider, links) if (linkedReviewNumber === null) { - return review.provider === 'github' || review.provider === 'gitlab' ? null : review + if (review.provider !== 'github' && review.provider !== 'gitlab') { + return review + } + // Why: GitHub/GitLab linked lookups can outlive the worktree metadata + // that requested them. A neutral branch lookup is safe to show unlinked. + return options.reviewHintKey === '' ? review : null } if (review.number === linkedReviewNumber) { return review