From 14bf9e4a53865918188c983dad3f3c08cc2be519 Mon Sep 17 00:00:00 2001 From: Julius Olsson Date: Sun, 26 Apr 2026 21:07:23 +0200 Subject: [PATCH 1/2] fix: show active worktree badge --- .../tile-tree/TileLeaf/SessionBadges.tsx | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/renderer/src/workspace/tile-tree/TileLeaf/SessionBadges.tsx b/src/renderer/src/workspace/tile-tree/TileLeaf/SessionBadges.tsx index 9ca4152c5..da12e7cf5 100644 --- a/src/renderer/src/workspace/tile-tree/TileLeaf/SessionBadges.tsx +++ b/src/renderer/src/workspace/tile-tree/TileLeaf/SessionBadges.tsx @@ -13,19 +13,28 @@ export function WorktreeBadge({ context: AgentWorkContext | null | undefined activity: WorktreeActivityState | null | undefined }) { - if (!context?.worktreePath) return null - const label = context.branch ?? shortPath(context.worktreePath) + // The badge is a "where is this agent working now?" signal, so + // prefer the latest active worktree over the longer-lived primary + // score winner. The primary context can lag badly in sessions that + // start on main and later move to a feature worktree: main has more + // cumulative events, while activity.active already reflects the + // most recent command cwd. + const displayContext = activity?.active?.worktreePath + ? activity.active + : context + if (!displayContext?.worktreePath) return null + const label = displayContext.branch ?? shortPath(displayContext.worktreePath) if (!label) return null - const color = worktreeBadgeColor(context) + const color = worktreeBadgeColor(displayContext) const title = [ - 'Primary worktree', - context.branch ? `Branch: ${context.branch}` : null, - `Worktree: ${context.worktreePath}`, - `Source: ${context.source}`, - `Confidence: ${context.confidence}`, - activity?.active?.worktreePath && - activity.active.worktreePath !== context.worktreePath - ? `Active now: ${activity.active.branch ?? shortPath(activity.active.worktreePath)} (${activity.active.worktreePath})` + activity?.active?.worktreePath ? 'Active worktree' : 'Primary worktree', + displayContext.branch ? `Branch: ${displayContext.branch}` : null, + `Worktree: ${displayContext.worktreePath}`, + `Source: ${displayContext.source}`, + `Confidence: ${displayContext.confidence}`, + context?.worktreePath && + context.worktreePath !== displayContext.worktreePath + ? `Primary: ${context.branch ?? shortPath(context.worktreePath)} (${context.worktreePath})` : null, activity ? `Touched: ${Object.values(activity.touched).length}` From b3f4ee14576951594e3848f8c02bab27bf6fc546 Mon Sep 17 00:00:00 2001 From: Julius Olsson Date: Sun, 26 Apr 2026 21:11:39 +0200 Subject: [PATCH 2/2] feat: show unread agent indicators --- .../src/workspace/dispatch/DispatchLayout.tsx | 68 +++++++++++ .../src/workspace/hook/actions/pane.ts | 20 +++- .../workspace/hook/ipc/useIpcSubscriptions.ts | 107 +++++++++++++++--- src/renderer/src/workspace/workspaceState.ts | 13 +++ 4 files changed, 189 insertions(+), 19 deletions(-) diff --git a/src/renderer/src/workspace/dispatch/DispatchLayout.tsx b/src/renderer/src/workspace/dispatch/DispatchLayout.tsx index 10a9e1c56..4c9375dc4 100644 --- a/src/renderer/src/workspace/dispatch/DispatchLayout.tsx +++ b/src/renderer/src/workspace/dispatch/DispatchLayout.tsx @@ -207,6 +207,14 @@ const DispatchAgentListRow = memo(function DispatchAgentListRow({ workContext: current?.workContext, workActivity: current?.workActivity, entries: current?.entries, + unreadSince: current?.unreadSince, + unreadKind: current?.unreadKind, + pendingApproval: current?.pendingApproval, + pendingTrustDialog: current?.pendingTrustDialog, + pendingResumePrompt: current?.pendingResumePrompt, + pendingPermissionPrompt: current?.pendingPermissionPrompt, + pendingCompaction: current?.pendingCompaction, + processError: current?.processError, } })) const onSelect = useCallback(() => { @@ -218,6 +226,12 @@ const DispatchAgentListRow = memo(function DispatchAgentListRow({ const title = runtime.entries ? cachedLatestPromptTitle(runtime.entries, row.kind) ?? row.title : row.title + const attentionLabel = dispatchAttentionLabel(runtime) + const unreadKind = attentionLabel + ? 'attention' + : runtime.unreadKind === 'attention' + ? 'output' + : runtime.unreadKind return (