Skip to content

Conversation

@rabanspiegel
Copy link
Contributor

@rabanspiegel rabanspiegel commented Dec 19, 2025

Problem

PR status displayed inconsistently between sidebar and main view. One component could show stale data (e.g., "View PR") while another showed current state (e.g., "PR Merged").

Root cause: Each component independently fetched PR status via IPC with local state, creating cache inconsistency when PRs were merged/closed externally.

Solution

Implement shared cache pattern following existing containerRuns.ts architecture:

New: lib/prStatusStore.ts

  • Centralized cache with automatic deduplication of concurrent requests
  • Subscription pattern for reactive updates across all components
  • Single source of truth for PR status data

Updated: hooks/usePrStatus.ts

  • Simplified hook using store subscriptions instead of direct IPC
  • Removed unused error state
  • Removed loading state (subscription emits cached values immediately)
  • Maintains same interface for backward compatibility

Updated: lib/prStatus.ts

  • Added PrStatus type (extends PrInfo with display stats)
  • Clean separation: PrInfo for logic/filtering, PrStatus for display

Updated: Direct IPC calls replaced with store

  • components/ProjectMainView.tsx - Delete dialog PR checks
  • components/kanban/KanbanBoard.tsx - Auto-complete detection
  • hooks/useDeleteRisks.ts - Risk assessment

Benefits

  • Consistency: All components display identical PR status from shared cache
  • Performance: Single IPC call per taskPath, deduplicated across consumers
  • Maintainability: Follows established patterns (containerRuns.ts, activityStore.ts)
  • Simplicity: 14 fewer lines, removed unused states and imports

Testing

  • Verify consistent PR status between sidebar and main view
  • Test open, draft, merged, and closed PR states
  • Confirm PR stats (additions/deletions) display in tooltips
  • Check manual refresh functionality
  • Verify no performance regressions

Note

Centralizes PR status via a shared store with deduplicated IPC and subscriptions, updating hooks and components to use it for consistent, up-to-date UI.

  • Core:
    • Shared Store: Add lib/prStatusStore.ts with cached PR status, concurrent request deduplication, and subscribeToPrStatus/refreshPrStatus APIs.
  • Types:
    • Define PrStatus in lib/prStatus.ts (extends PrInfo with diff stats) and reuse isActivePr.
  • Hooks:
    • Rewrite hooks/usePrStatus.ts to subscribe to the store; remove loading/error and return { pr, refresh }.
  • Components:
    • components/ProjectMainView.tsx: Replace direct IPC PR checks with refreshPrStatus; use isActivePr in delete flow.
    • components/kanban/KanbanBoard.tsx: Use refreshPrStatus to auto-mark tasks “Ready for review”.
    • hooks/useDeleteRisks.ts: Switch to refreshPrStatus and isActivePr for risk assessment.
    • components/PrPreviewTooltip.tsx: Import PrStatus from lib/prStatus.
    • components/FileChangesPanel.tsx: Remove PR loading skeleton/prop; rely on shared usePrStatus.

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

Implement prStatusStore with subscription pattern similar to containerRuns
to ensure consistent PR status across sidebar and main view components.
Updates all remaining direct getPrStatus() calls to use refreshPrStatus()
from the shared prStatusStore for complete consistency across the app.
- Remove unused getPrStatus() sync getter from prStatusStore
- Fix bug where additions/deletions/changedFiles were lost due to
  casting to PrInfo instead of preserving full PR metadata
- Restore PrStatus type in usePrStatus hook to maintain compatibility
  with PrPreviewTooltip component which needs stats fields
Remove redundant PrData type from prStatusStore and use PrStatus
directly from usePrStatus hook, eliminating duplicate type definition
while maintaining clear separation between PrInfo (logic) and PrStatus (display).
- Move PrStatus type to lib/prStatus.ts alongside PrInfo
- Remove unused error state from usePrStatus hook
- Remove loading state (subscription pattern emits immediately with cache)
- Update prStatusStore to import PrStatus from correct location
- Remove skeleton loader from FileChangesPanel (not needed with instant cache)
- Update PrPreviewTooltip import to use new type location
@vercel
Copy link

vercel bot commented Dec 19, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
docs Ready Ready Preview, Comment Dec 19, 2025 1:51am

additions?: number;
deletions?: number;
changedFiles?: number;
};
Copy link

Choose a reason for hiding this comment

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

Bug: Type change makes number/url optional, breaking UI display

The PrStatus type definition changed from having required fields (number: number, url: string, state: string) to inheriting from PrInfo where these are optional (number?: number, url?: string, state?: string | null). Multiple UI components use pr.number in template strings without null checks (e.g., (#${pr.number})), which would display (#undefined) if the field is missing. The old type guaranteed these fields existed; the new type does not, creating a type safety regression that could produce incorrect UI text.

Additional Locations (1)

Fix in Cursor Fix in Web

When taskPath changes from Task A to Task B, clear pr state immediately
to prevent briefly showing Task A's PR button while Task B's data loads.
@arnestrickmann arnestrickmann merged commit 4f0c34b into main Dec 19, 2025
4 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.

3 participants