Skip to content

Show merged PR status in thread sidebar when no open PR exists - #53

Closed
juliusmarminge wants to merge 7 commits into
mainfrom
codething/4efb5794
Closed

juliusmarminge wants to merge 7 commits into
mainfrom
codething/4efb5794

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Feb 15, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Extend GitStatusResult with a nullable mergedPr field in shared contracts.
  • Update server git status flow to fetch merged PR metadata (gh pr list --state merged) when no open PR is found.
  • Preserve best-effort behavior so PR lookup failures still return status with openPr/mergedPr as null.
  • Surface merged PR state in the web sidebar by querying per-thread git status and showing a new Merged status pill when branch-matched and no open PR exists.
  • Add and update tests across server, websocket, web logic, and contracts for the new mergedPr behavior.

Testing

  • apps/server/src/gitManager.test.ts: verified merged PR fallback lookup, no merged lookup when open PR exists, and failure resilience (openPr/mergedPr null).
  • apps/server/src/wsServer.test.ts: updated status expectations to include mergedPr: null.
  • apps/web/src/components/GitActionsControl.logic.test.ts: updated status fixture to include mergedPr: null.
  • packages/contracts/src/git.test.ts: updated schema parsing test to include mergedPr: null.
  • Project lint: Not run (not provided in input).
  • Full test suite: Not run (not provided in input).

Open with Devin

Summary by CodeRabbit

  • New Features

    • PRs now include an explicit state (open/closed/merged) and updatedAt, improving status accuracy.
    • UI controls and quick actions use PR state and URL to enable/disable and route PR actions.
    • Sidebar and thread listings show a per-branch PR status indicator (e.g., "PR open", "PR merged").
  • Bug Fixes

    • PR lookup now considers all states and surfaces the most recently updated PR for status displays.

Note

Medium Risk
Changes the shared GitStatusResult contract and server status flow to call gh pr list --state all and return the latest PR with a derived state; incorrect parsing/sorting or gh behavior could cause misleading PR status or extra load.

Overview
Git status now returns a unified pr object (or null) with state (open/closed/merged), replacing the previous openPr field in the shared contracts and all callers.

On the server, GitManager.status now queries GitHub via gh pr list --state all and picks the most recently updated PR, normalizing MERGED/mergedAt into state: "merged" while keeping best-effort behavior (failures yield pr: null).

On the web, git actions/CTAs now treat “open PR” specifically as gitStatus.pr?.state === "open", and the thread sidebar periodically queries git status per thread/worktree to display a PR-state icon (open/closed/merged) when the thread’s branch matches the repo status.

Written by Cursor Bugbot for commit 4b3825e. This will update automatically on new commits. Configure here.

Note

Display merged PR status in the thread sidebar by returning pr with state from GitManager.status and removing openPr

Rename openPr to pr with a state field in the Git status contract, add latest-PR lookup across all states in GitManager.status, and render a per-thread PR state icon in the sidebar. Update server and web logic/tests to use gitStatus.pr?.state === "open" for actions and UI.

📍Where to Start

Start with the status flow in makeGitManager.status in apps/server/src/git/Layers/GitManager.ts, then review findLatestPr, parsePullRequestList, and toStatusPr, followed by the sidebar integration in apps/web/src/components/Sidebar.tsx.

Macroscope summarized e8dfc42.

- extend `GitStatusResult` with nullable `mergedPr` metadata
- in server git status, query merged PR only when no open PR is found
- in sidebar, display a `Merged` status pill for threads on branches with merged PRs
- update server/web/contracts tests for the new status shape
@coderabbitai

coderabbitai Bot commented Feb 15, 2026 •

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Replaces openPr with a nullable pr object that includes a normalized PR state ("open" | "closed" | "merged") and updatedAt. Server PR lookup now queries broader PR states and selects the most recently updated PR; UI, tests, and contracts updated to consume the new pr shape.

Changes

Cohort / File(s) Summary
Contracts & types
packages/contracts/src/git.ts, packages/contracts/src/git.test.ts
Replaced openPr with `pr: GitStatusPr
Server public types
apps/server/src/git.ts
Updated GitStatusDetails / service payload to use pr (nullable) instead of openPr; aligned exported types with contract.
Git manager implementation
apps/server/src/gitManager.ts
Renamed PR model to PullRequestInfo with state and updatedAt; added findLatestPr(...); parse/normalize state/updatedAt; status() now returns pr (latest PR) instead of openPr.
Server tests & WS
apps/server/src/gitManager.test.ts, apps/server/src/wsServer.test.ts
Updated mocks/assertions to expect pr and pr.state; added merged/closed scenarios and ensured gh invoked with wider state lookups.
Web UI logic & components
apps/web/src/components/GitActionsControl.logic.ts, apps/web/src/components/GitActionsControl.logic.test.ts, apps/web/src/components/GitActionsControl.tsx, apps/web/src/components/Sidebar.tsx
Replaced checks for openPr with pr?.state === "open"; derive PR URLs from pr.url; wired per-thread PR state in Sidebar and added PR status pill rendering; updated tests and effect dependencies.
Server surface & tests small edits
apps/server/src/gitManager.*, apps/server/src/git.* (others grouped)
JSON field selection for GH CLI extended to include state, mergedAt, updatedAt; error handling for PR JSON parsing tightened; minor signature/name updates (OpenPrInfo → PullRequestInfo).

Sequence Diagram

sequenceDiagram
    participant Web as Sidebar (Web)
    participant API as GitManager (Server)
    participant GH as GitHub CLI

    Web->>API: status(cwd, branch)
    API->>GH: gh pr list --state all --json number,title,url,baseRefName,headRefName,state,updatedAt,mergedAt
    GH-->>API: list (may be empty)

    alt list non-empty
        API->>API: parsePullRequestList -> normalize state/updatedAt
        API->>API: sort by updatedAt -> pick latest PR
        API-->>Web: GitStatusResult { pr: latestPR, ... }
    else empty
        API-->>Web: GitStatusResult { pr: null, ... }
    end

    alt pr.state == "merged"
        Web->>Web: render "PR merged" pill
    else pr.state == "open"
        Web->>Web: render "PR open" pill and link
    else
        Web->>Web: no PR pill
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Show merged PR status in thread sidebar when no open PR exists' accurately and concisely summarizes the primary objective of the changeset: adding the ability to display merged PR status in the sidebar UI as a fallback when no open PR is available.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codething/4efb5794

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

@macroscopeapp

macroscopeapp Bot commented Feb 15, 2026 •

Copy link
Copy Markdown
Contributor

Show per-thread PR state in the Sidebar and return GitManager.status pr with state across server and contracts

Rename openPr to pr in contracts and server status, add PR state parsing and normalization, fetch the latest PR with GitManager.findLatestPr using --state all and limit 20, and render a PR status icon in the Sidebar using per-thread Git status polling.

📍Where to Start

Start with GitManager.status and the new findLatestPr in gitManager.ts, then review the Sidebar PR indicator logic in Sidebar.tsx.


Macroscope summarized 4b3825e.

@greptile-apps

greptile-apps Bot commented Feb 15, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds merged PR detection to the git status flow. When no open PR exists for a branch, the server now falls back to querying gh pr list --state merged and surfaces the result as a new mergedPr field on GitStatusResult. The web sidebar consumes this to show a "Merged" status pill on threads whose branch has a merged PR.

  • Extends GitStatusResult contract with a nullable mergedPr field matching the openPr shape.
  • Adds findMergedPr to GitManager as a fallback when findOpenPr returns nothing.
  • Removes the hasUpstream guard from the PR lookup condition — intentional for merged branches (whose remote ref may be deleted), but also widens findOpenPr to run on unpushed branches unnecessarily.
  • Sidebar now polls git status per-thread via useQueries to derive merged PR state; threads sharing the same cwd will share cache entries, but worktree threads each trigger independent queries.
  • Test coverage is thorough: merged PR lookup, open-PR-skips-merged, and failure resilience are all covered.

Confidence Score: 4/5

  • This PR is safe to merge with minor performance considerations around the widened PR lookup guard and per-thread polling.
  • The feature is well-structured with proper best-effort error handling and good test coverage. The main concerns are performance-related: removing the hasUpstream guard causes unnecessary gh CLI calls for unpushed branches, and per-thread useQueries polling in the sidebar could scale poorly with many worktree threads. These are non-blocking style concerns rather than correctness bugs.
  • Pay close attention to apps/server/src/gitManager.ts (widened guard condition) and apps/web/src/components/Sidebar.tsx (per-thread polling performance).

Important Files Changed

Filename Overview
packages/contracts/src/git.ts Adds nullable mergedPr field to gitStatusResultSchema with the same shape as openPr. Clean, mechanical addition.
packages/contracts/src/git.test.ts Updates schema parsing test to include mergedPr: null. Straightforward test fixture update.
apps/server/src/git.ts Updates GitStatusDetails to omit mergedPr from GitStatusResult and adds mergedPr: null to the GitCoreService.status() return. Correct — the core service never looks up PRs itself.
apps/server/src/gitManager.ts Adds findMergedPr method and merged PR fallback in status(). The hasUpstream guard was removed, which widens the PR lookup to branches without a remote tracking branch — this is intentional for merged branches but also changes the findOpenPr behavior. Performance concern: two sequential gh pr list calls when no open PR exists.
apps/server/src/gitManager.test.ts Adds test for merged PR metadata, verifies no merged lookup when open PR exists, and checks failure resilience. Good coverage of the new behavior.
apps/server/src/wsServer.test.ts Adds mergedPr: null to mock status fixture. Mechanical update.
apps/web/src/components/GitActionsControl.logic.test.ts Adds mergedPr: null to test status fixture. Mechanical update.
apps/web/src/components/Sidebar.tsx Adds per-thread git status polling via useQueries to detect merged PRs and show a "Merged" pill. Fires a git status query for every thread with a branch, which could cause many gh CLI invocations with worktrees. Uses as type assertion instead of proper query typing.

Sequence Diagram

sequenceDiagram
    participant Sidebar as Sidebar (useQueries)
    participant WS as WebSocket Server
    participant GM as GitManager.status()
    participant GH as GitHub CLI (gh)

    Sidebar->>WS: git.status({ cwd })
    WS->>GM: status({ cwd })
    GM->>GM: gitCore.statusDetails(cwd)

    alt branch exists
        GM->>GH: gh pr list --head branch --state open
        alt open PR found
            GH-->>GM: [{ number, title, url, ... }]
            GM-->>WS: { openPr: {...}, mergedPr: null }
        else no open PR
            GH-->>GM: []
            GM->>GH: gh pr list --head branch --state merged
            alt merged PR found
                GH-->>GM: [{ number, title, url, ... }]
                GM-->>WS: { openPr: null, mergedPr: {...} }
            else no merged PR
                GH-->>GM: []
                GM-->>WS: { openPr: null, mergedPr: null }
            end
        end
    else no branch (detached HEAD)
        GM-->>WS: { openPr: null, mergedPr: null }
    end

    WS-->>Sidebar: GitStatusResult
    Sidebar->>Sidebar: Derive mergedPrByThreadId
    Sidebar->>Sidebar: Show "Merged" pill if applicable
Loading

Last reviewed commit: 46347e2

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment thread apps/server/src/gitManager.ts Outdated
let openPr: ReturnType<typeof toStatusOpenPr> | null = null;
if (details.branch && details.hasUpstream) {
let mergedPr: ReturnType<typeof toStatusOpenPr> | null = null;
if (details.branch) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hasUpstream guard removed for findOpenPr too

The old condition was if (details.branch && details.hasUpstream), which avoided calling gh pr list for branches that have never been pushed to a remote. Removing hasUpstream is necessary for the merged PR path (the remote branch may have been deleted after merge), but it also means findOpenPr now runs for local-only branches that can't possibly have an open PR. This adds an unnecessary gh CLI call (with 30s timeout) on every status check for unpushed branches.

Consider restoring the hasUpstream check for findOpenPr and only skipping it for the merged lookup:

Suggested change
if (details.branch) {
if (details.branch) {
try {
if (details.hasUpstream) {
const existing = await this.findOpenPr(input.cwd, details.branch);
if (existing) {
openPr = toStatusOpenPr(existing);
}
}
if (!openPr) {
const merged = await this.findMergedPr(input.cwd, details.branch);
if (merged) {
mergedPr = toStatusOpenPr(merged);
}
}

Comment on lines +156 to +166
const threadGitStatusQueries = useQueries({
queries: threadGitTargets.map((target) => {
const base = gitStatusQueryOptions(api, target.cwd);
return {
...base,
enabled: Boolean(base.enabled && target.branch !== null),
staleTime: 30_000,
refetchInterval: 60_000,
};
}),
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per-thread git status polling may cause performance issues

This fires a separate useQueries entry for every thread. Although queries with the same cwd will share a cache key, threads using worktrees each have a unique path, meaning N worktree threads = N independent status queries. Each query triggers git status --porcelain + up to 2 gh pr list calls (open + merged), polling every 60s. For users with many worktree threads, this could saturate gh API rate limits or slow down the sidebar.

Consider deduplicating by cwd before passing to useQueries, or only querying for visible/expanded threads.

Comment thread apps/web/src/components/Sidebar.tsx Outdated
for (let index = 0; index < threadGitTargets.length; index += 1) {
const target = threadGitTargets[index];
if (!target) continue;
const status = threadGitStatusQueries[index]?.data as GitStatusResult | undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsafe as type assertion on query data

threadGitStatusQueries[index]?.data is typed as the inferred return type from the query function, but using as GitStatusResult | undefined bypasses type safety. If the query's return type ever diverges from GitStatusResult, this cast will silently hide the mismatch. Consider using a type-safe approach, e.g., assigning the result of gitStatusQueryOptions with an explicit generic or using a type guard.

- server: only query open PRs when the current branch has an upstream; still fall back to merged PR lookup
- tests: cover status behavior for branches without upstream tracking
- web: fetch git status once per cwd, validate query data with schema parsing, and map merged PR badges by thread branch match

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/server/src/gitManager.ts (1)

421-447: Consider extracting a shared helper to reduce duplication.

findMergedPr and findOpenPr are nearly identical, differing only in the --state argument. This could be consolidated into a single method with a state parameter.

♻️ Optional refactor to reduce duplication
-  private async findOpenPr(cwd: string, branch: string): Promise<OpenPrInfo | null> {
+  private async findPrByState(
+    cwd: string,
+    branch: string,
+    state: "open" | "merged",
+  ): Promise<OpenPrInfo | null> {
     const stdout = await this.runGhStdout(cwd, [
       "pr",
       "list",
       "--head",
       branch,
       "--state",
-      "open",
+      state,
       "--limit",
       "1",
       "--json",
       "number,title,url,baseRefName,headRefName",
     ]);

     const raw = trimStdout(stdout);
     if (raw.length === 0) return null;

     let parsedJson: unknown;
     try {
       parsedJson = JSON.parse(raw);
     } catch {
       throw new Error("GitHub CLI returned invalid PR list JSON.");
     }

     const parsed = parseOpenPrList(parsedJson);
     return parsed[0] ?? null;
   }

-  private async findMergedPr(cwd: string, branch: string): Promise<OpenPrInfo | null> {
-    // ... duplicate implementation
-  }
+
+  private async findOpenPr(cwd: string, branch: string): Promise<OpenPrInfo | null> {
+    return this.findPrByState(cwd, branch, "open");
+  }
+
+  private async findMergedPr(cwd: string, branch: string): Promise<OpenPrInfo | null> {
+    return this.findPrByState(cwd, branch, "merged");
+  }

- Replace `openPr`/`mergedPr` with `pr` in server and contracts
- Add PR `state` (`open`/`closed`/`merged`) to git status schema
- Resolve latest branch PR via `gh pr list --state all` sorted by `updatedAt`

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/server/src/gitManager.ts (2)

216-240: ⚠️ Potential issue | 🟠 Major

Validate GitStatusResult with the contract schema.
This method returns a shared contract object but skips gitStatusResultSchema.parse, which can allow malformed payloads to escape. Please validate output for consistency with other endpoints.

✅ Proposed fix
-import {
-  gitRunStackedActionInputSchema,
-  gitRunStackedActionResultSchema,
-  gitStatusInputSchema,
-  type GitStatusPrState,
-  type GitRunStackedActionInput,
-  type GitRunStackedActionResult,
-  type GitStatusInput,
-  type GitStatusResult,
-} from "@t3tools/contracts";
+import {
+  gitRunStackedActionInputSchema,
+  gitRunStackedActionResultSchema,
+  gitStatusInputSchema,
+  gitStatusResultSchema,
+  type GitStatusPrState,
+  type GitRunStackedActionInput,
+  type GitRunStackedActionResult,
+  type GitStatusInput,
+  type GitStatusResult,
+} from "@t3tools/contracts";
@@
-    return {
+    return gitStatusResultSchema.parse({
       branch: details.branch,
       hasWorkingTreeChanges: details.hasWorkingTreeChanges,
       workingTree: details.workingTree,
       hasUpstream: details.hasUpstream,
       aheadCount: details.aheadCount,
       behindCount: details.behindCount,
       pr,
-    };
+    });

As per coding guidelines, "apps/**/*.{ts,tsx}: Use Zod schemas from packages/contracts for shared type contracts covering provider events, WebSocket protocol, and model/session types".


437-467: ⚠️ Potential issue | 🟠 Major

Prefer open PRs over merged/closed when both exist.
Sorting all states by updatedAt can select a merged/closed PR even when an open PR exists for the branch, which would show the wrong status pill. Please prioritize open PRs first, then fall back to the most recent non-open PR. Also guard against invalid updatedAt values for deterministic ordering.

🛠️ Proposed fix
-    const parsed = parsePullRequestList(parsedJson).toSorted((a, b) => {
-      const left = a.updatedAt ? Date.parse(a.updatedAt) : 0;
-      const right = b.updatedAt ? Date.parse(b.updatedAt) : 0;
-      return right - left;
-    });
-    return parsed[0] ?? null;
+    const parsed = parsePullRequestList(parsedJson);
+    const toTimestamp = (value: string | null): number => {
+      const parsedValue = value ? Date.parse(value) : 0;
+      return Number.isFinite(parsedValue) ? parsedValue : 0;
+    };
+    const byUpdatedDesc = (a: PullRequestInfo, b: PullRequestInfo) =>
+      toTimestamp(b.updatedAt) - toTimestamp(a.updatedAt);
+
+    const open = parsed.filter((pr) => pr.state === "open").toSorted(byUpdatedDesc);
+    if (open[0]) return open[0];
+
+    const nonOpen = parsed.filter((pr) => pr.state !== "open").toSorted(byUpdatedDesc);
+    return nonOpen[0] ?? null;

Co-authored-by: codex <codex@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/server/src/gitManager.ts (1)

219-238: ⚠️ Potential issue | 🟠 Major

Open PR can be masked by a newer closed/merged PR.

findLatestPr selects by updatedAt across all states. If a closed/merged PR has a newer timestamp than an existing open PR on the same branch, status will surface the non‑open PR and the UI will disable open‑PR actions incorrectly. Prefer open PRs explicitly before falling back to the latest non‑open entry.

🐛 Suggested fix
-    let pr: ReturnType<typeof toStatusPr> | null = null;
-    if (details.branch) {
-      try {
-        const existing = await this.findLatestPr(input.cwd, details.branch);
-        if (existing) {
-          pr = toStatusPr(existing);
-        }
-      } catch {
-        // PR lookup is best-effort for status rendering.
-      }
-    }
+    let pr: ReturnType<typeof toStatusPr> | null = null;
+    if (details.branch) {
+      try {
+        const open = await this.findOpenPr(input.cwd, details.branch);
+        const existing = open ?? (await this.findLatestPr(input.cwd, details.branch));
+        if (existing) {
+          pr = toStatusPr(existing);
+        }
+      } catch {
+        // PR lookup is best-effort for status rendering.
+      }
+    }

Also applies to: 436-466

🧹 Nitpick comments (1)
apps/web/src/components/GitActionsControl.logic.test.ts (1)

28-86: Add coverage for non-open PR states.

Now that pr.state drives open-PR detection, consider adding a case that asserts "merged"/"closed" behaves like “no open PR” (e.g., create‑PR actions stay enabled). This guards against future regressions in state handling.

Co-authored-by: codex <codex@users.noreply.github.com>
Comment thread apps/server/src/gitManager.ts Outdated
Comment thread apps/web/src/components/Sidebar.tsx Outdated
@cursor

cursor Bot commented Feb 20, 2026

Copy link
Copy Markdown
Contributor

Bugbot Autofix prepared fixes for 2 of the 2 bugs found in the latest run.

  • ✅ Fixed: findLatestPr ignores open PRs in favor of recent ones
    • Added a primary sort key that places open PRs before merged/closed PRs, then falls back to updatedAt for tie-breaking within each group.
  • ✅ Fixed: Three unused icon imports added to Sidebar
    • Removed the unused MonitorIcon, MoonIcon, and SunIcon imports from the lucide-react import statement.

Create PR

Or push these changes by commenting:

@cursor push 8578146fb9
Preview (8578146fb9)
diff --git a/apps/server/src/gitManager.ts b/apps/server/src/gitManager.ts
--- a/apps/server/src/gitManager.ts
+++ b/apps/server/src/gitManager.ts
@@ -458,6 +458,9 @@
     }
 
     const parsed = parsePullRequestList(parsedJson).toSorted((a, b) => {
+      const aOpen = a.state === "open" ? 1 : 0;
+      const bOpen = b.state === "open" ? 1 : 0;
+      if (aOpen !== bOpen) return bOpen - aOpen;
       const left = a.updatedAt ? Date.parse(a.updatedAt) : 0;
       const right = b.updatedAt ? Date.parse(b.updatedAt) : 0;
       return right - left;

diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx
--- a/apps/web/src/components/Sidebar.tsx
+++ b/apps/web/src/components/Sidebar.tsx
@@ -1,10 +1,4 @@
-import {
-  GitPullRequestIcon,
-  MonitorIcon,
-  MoonIcon,
-  SunIcon,
-  TerminalIcon,
-} from "lucide-react";
+import { GitPullRequestIcon, TerminalIcon } from "lucide-react";
 import { useCallback, useEffect, useMemo, useState } from "react";
 import type { ResolvedKeybindingsConfig } from "@t3tools/contracts";
 import { useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/react-query";

Co-authored-by: codex <codex@users.noreply.github.com>

@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 and found 1 potential issue.

Bugbot Autofix is ON, but it could not run because the spend limit has been reached. To enable Bugbot Autofix, raise your spend limit in the Cursor dashboard.

const right = b.updatedAt ? Date.parse(b.updatedAt) : 0;
return right - left;
});
return parsed[0] ?? null;

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.

findLatestPr may hide open PR behind stale merged PR

Medium Severity

findLatestPr sorts all PRs (open, closed, merged) solely by updatedAt and returns the first result. If a branch has both an open PR and a merged/closed PR that was updated more recently (e.g., via a comment on the old PR), the merged PR is returned instead of the open one. This causes the UI to show "PR merged" and offer "Create PR" even though an open PR exists, contradicting the stated intent of showing merged state only "when no open PR exists."

Additional Locations (1)

Fix in Cursor Fix in Web

maria-rcks pushed a commit to maria-rcks/t3libre that referenced this pull request Sep 21, 2026
i2cjak referenced this pull request in i2cjak/Backplane Sep 29, 2026
@joeljanson joeljanson mentioned this pull request Oct 7, 2026
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