Merge branch 'main' into refactor/frontend

This commit is contained in:
Cody Seibert
2025-12-19 14:42:31 -05:00
24 changed files with 1205 additions and 879 deletions

View File

@@ -8,6 +8,7 @@ import { WorktreeActionsDropdown } from "./worktree-actions-dropdown";
interface WorktreeTabProps {
worktree: WorktreeInfo;
cardCount?: number; // Number of unarchived cards for this branch
isSelected: boolean;
isRunning: boolean;
isActivating: boolean;
@@ -43,6 +44,7 @@ interface WorktreeTabProps {
export function WorktreeTab({
worktree,
cardCount,
isSelected,
isRunning,
isActivating,
@@ -96,9 +98,9 @@ export function WorktreeTab({
<RefreshCw className="w-3 h-3 animate-spin" />
)}
{worktree.branch}
{worktree.hasChanges && (
{cardCount !== undefined && cardCount > 0 && (
<span className="inline-flex items-center justify-center h-4 min-w-[1rem] px-1 text-[10px] font-medium rounded bg-background/80 text-foreground border border-border">
{worktree.changedFilesCount}
{cardCount}
</span>
)}
</Button>
@@ -139,9 +141,9 @@ export function WorktreeTab({
<RefreshCw className="w-3 h-3 animate-spin" />
)}
{worktree.branch}
{worktree.hasChanges && (
{cardCount !== undefined && cardCount > 0 && (
<span className="inline-flex items-center justify-center h-4 min-w-[1rem] px-1 text-[10px] font-medium rounded bg-background/80 text-foreground border border-border">
{worktree.changedFilesCount}
{cardCount}
</span>
)}
</Button>

View File

@@ -35,5 +35,6 @@ export interface WorktreePanelProps {
onRemovedWorktrees?: (removedWorktrees: Array<{ path: string; branch: string }>) => void;
runningFeatureIds?: string[];
features?: FeatureInfo[];
branchCardCounts?: Record<string, number>; // Map of branch name to unarchived card count
refreshTrigger?: number;
}

View File

@@ -23,6 +23,7 @@ export function WorktreePanel({
onRemovedWorktrees,
runningFeatureIds = [],
features = [],
branchCardCounts,
refreshTrigger = 0,
}: WorktreePanelProps) {
const {
@@ -109,43 +110,47 @@ export function WorktreePanel({
<span className="text-sm text-muted-foreground mr-2">Branch:</span>
<div className="flex items-center gap-1 flex-wrap">
{worktrees.map((worktree) => (
<WorktreeTab
key={worktree.path}
worktree={worktree}
isSelected={isWorktreeSelected(worktree)}
isRunning={hasRunningFeatures(worktree)}
isActivating={isActivating}
isDevServerRunning={isDevServerRunning(worktree)}
devServerInfo={getDevServerInfo(worktree)}
defaultEditorName={defaultEditorName}
branches={branches}
filteredBranches={filteredBranches}
branchFilter={branchFilter}
isLoadingBranches={isLoadingBranches}
isSwitching={isSwitching}
isPulling={isPulling}
isPushing={isPushing}
isStartingDevServer={isStartingDevServer}
aheadCount={aheadCount}
behindCount={behindCount}
onSelectWorktree={handleSelectWorktree}
onBranchDropdownOpenChange={handleBranchDropdownOpenChange(worktree)}
onActionsDropdownOpenChange={handleActionsDropdownOpenChange(worktree)}
onBranchFilterChange={setBranchFilter}
onSwitchBranch={handleSwitchBranch}
onCreateBranch={onCreateBranch}
onPull={handlePull}
onPush={handlePush}
onOpenInEditor={handleOpenInEditor}
onCommit={onCommit}
onCreatePR={onCreatePR}
onDeleteWorktree={onDeleteWorktree}
onStartDevServer={handleStartDevServer}
onStopDevServer={handleStopDevServer}
onOpenDevServerUrl={handleOpenDevServerUrl}
/>
))}
{worktrees.map((worktree) => {
const cardCount = branchCardCounts?.[worktree.branch];
return (
<WorktreeTab
key={worktree.path}
worktree={worktree}
cardCount={cardCount}
isSelected={isWorktreeSelected(worktree)}
isRunning={hasRunningFeatures(worktree)}
isActivating={isActivating}
isDevServerRunning={isDevServerRunning(worktree)}
devServerInfo={getDevServerInfo(worktree)}
defaultEditorName={defaultEditorName}
branches={branches}
filteredBranches={filteredBranches}
branchFilter={branchFilter}
isLoadingBranches={isLoadingBranches}
isSwitching={isSwitching}
isPulling={isPulling}
isPushing={isPushing}
isStartingDevServer={isStartingDevServer}
aheadCount={aheadCount}
behindCount={behindCount}
onSelectWorktree={handleSelectWorktree}
onBranchDropdownOpenChange={handleBranchDropdownOpenChange(worktree)}
onActionsDropdownOpenChange={handleActionsDropdownOpenChange(worktree)}
onBranchFilterChange={setBranchFilter}
onSwitchBranch={handleSwitchBranch}
onCreateBranch={onCreateBranch}
onPull={handlePull}
onPush={handlePush}
onOpenInEditor={handleOpenInEditor}
onCommit={onCommit}
onCreatePR={onCreatePR}
onDeleteWorktree={onDeleteWorktree}
onStartDevServer={handleStartDevServer}
onStopDevServer={handleStopDevServer}
onOpenDevServerUrl={handleOpenDevServerUrl}
/>
);
})}
<Button
variant="ghost"