From 8bbd0b635b88fd70b40c90aeb1fa181577fc52e9 Mon Sep 17 00:00:00 2001 From: Vincent Caetano Date: Mon, 9 Nov 2026 23:19:14 -0300 Subject: [PATCH 1/2] feat(web): add a compact thread cards option for the sidebar Sidebar cards spend a third line on the branch, environment and provider, which the hover card already shows. The new "Compact thread cards" setting (off by default) drops that line: the environment and provider icons move, smaller and without the instance badge, next to the project name, and the PR badge and terminal status move next to the title. Co-Authored-By: Claude Opus 5.5 --- .../settings/DesktopClientSettings.test.ts | 1 + .../components/settings/SettingsPanels.tsx | 30 +++++++++++ .../src/components/settings/settingsSearch.ts | 6 +++ .../components/sidebar/SidebarThreadRow.tsx | 50 +++++++++++++++---- packages/contracts/src/settings.ts | 2 + 5 files changed, 78 insertions(+), 11 deletions(-) diff --git a/apps/desktop/src/settings/DesktopClientSettings.test.ts b/apps/desktop/src/settings/DesktopClientSettings.test.ts index 1ab9b3159e1f9..fbb39e1c8608d 100644 --- a/apps/desktop/src/settings/DesktopClientSettings.test.ts +++ b/apps/desktop/src/settings/DesktopClientSettings.test.ts @@ -66,6 +66,7 @@ const clientSettings: ClientSettings = { threadDetailsUsageEnabled: false, threadDetailsItems: {}, sidebarWorkingShelfEnabled: false, + sidebarCompactThreadCards: false, loadBalancingEnabled: false, loadBalancingWeights: { "environment-1": 75, "environment-2": 0 }, pullRequestMergeMethodOverrides: {}, diff --git a/apps/web/src/components/settings/SettingsPanels.tsx b/apps/web/src/components/settings/SettingsPanels.tsx index a37bf1581990e..b0e643fad88c5 100644 --- a/apps/web/src/components/settings/SettingsPanels.tsx +++ b/apps/web/src/components/settings/SettingsPanels.tsx @@ -491,6 +491,9 @@ export function useSettingsRestore(onRestored?: () => void) { ...(settings.sidebarWorkingShelfEnabled !== DEFAULT_UNIFIED_SETTINGS.sidebarWorkingShelfEnabled ? ["Working section"] : []), + ...(settings.sidebarCompactThreadCards !== DEFAULT_UNIFIED_SETTINGS.sidebarCompactThreadCards + ? ["Compact thread cards"] + : []), ...(settings.sidebarAutoSettleAfterDays !== DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleAfterDays ? ["Auto-settle inactive threads"] : []), @@ -660,6 +663,7 @@ export function useSettingsRestore(onRestored?: () => void) { sidebarProjectGroupingMode: DEFAULT_UNIFIED_SETTINGS.sidebarProjectGroupingMode, sidebarProjectSortOrder: DEFAULT_UNIFIED_SETTINGS.sidebarProjectSortOrder, sidebarWorkingShelfEnabled: DEFAULT_UNIFIED_SETTINGS.sidebarWorkingShelfEnabled, + sidebarCompactThreadCards: DEFAULT_UNIFIED_SETTINGS.sidebarCompactThreadCards, sidebarAutoSettleAfterDays: DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleAfterDays, sidebarAutoSettleKeepPullRequests: DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleKeepPullRequests, sidebarAutoSettleOnMerge: DEFAULT_UNIFIED_SETTINGS.sidebarAutoSettleOnMerge, @@ -880,6 +884,32 @@ export function GeneralSettingsPanel() { /> } /> + + updateSettings({ + sidebarCompactThreadCards: DEFAULT_UNIFIED_SETTINGS.sidebarCompactThreadCards, + }) + } + /> + ) : null + } + control={ + + updateSettings({ sidebarCompactThreadCards: Boolean(checked) }) + } + aria-label="Compact thread cards" + /> + } + /> diff --git a/apps/web/src/components/settings/settingsSearch.ts b/apps/web/src/components/settings/settingsSearch.ts index f7492035874da..12ed12c25cf37 100644 --- a/apps/web/src/components/settings/settingsSearch.ts +++ b/apps/web/src/components/settings/settingsSearch.ts @@ -461,6 +461,12 @@ export const SETTINGS_SEARCH_ITEMS = [ to: "/settings/general", searchTerms: ["hide fold running monitoring threads inbox sidebar shelf"], }, + { + id: "compact-thread-cards", + title: "Compact thread cards", + to: "/settings/general", + searchTerms: ["sidebar dense smaller hide branch worktree provider environment row"], + }, { id: "boring-sidebar", title: "Boring sidebar (group by project)", diff --git a/apps/web/src/components/sidebar/SidebarThreadRow.tsx b/apps/web/src/components/sidebar/SidebarThreadRow.tsx index 3a50e76d06bda..2326a582d287b 100644 --- a/apps/web/src/components/sidebar/SidebarThreadRow.tsx +++ b/apps/web/src/components/sidebar/SidebarThreadRow.tsx @@ -119,6 +119,7 @@ import { Menu, MenuItem, MenuItemDetail, MenuPopup, MenuSeparator, MenuTrigger } import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; import { MiddleTruncate } from "../ui/middle-truncate"; import { useThreadHasUnsentDraft } from "../../composerDraftStore"; +import { useClientSettings } from "../../hooks/useSettings"; // The fields thread rows show. Provider status pushes refresh `checkedAt`, // status and auth on every provider; leaving those out keeps each @@ -183,15 +184,15 @@ function terminalProcessLabel(count: number): string { function SidebarProviderStack(props: { thread: SidebarThreadSummary; providerEntryByInstanceId: ReadonlyMap; + compact?: boolean; }) { const stack = resolveThreadProviderStack(props.thread); const currentInstanceId = stack[stack.length - 1]!; const currentEntry = props.providerEntryByInstanceId.get(currentInstanceId) ?? null; if (currentEntry === null) return null; - const showInstanceBadge = shouldShowInstanceBadge( - currentEntry, - props.providerEntryByInstanceId.values(), - ); + const showInstanceBadge = + !props.compact && + shouldShowInstanceBadge(currentEntry, props.providerEntryByInstanceId.values()); const current = ( ); if (stack.length === 1) { @@ -812,6 +813,8 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP const isRemote = thread.environmentId !== props.currentEnvironmentId; const showsScratchMachine = !thread.branch && props.scratchMachineLabel !== null; + const compactCard = + useClientSettings((settings) => settings.sidebarCompactThreadCards) && variant === "card"; const detailsTooltip = ( ); - const titleLineIcons = metaLineEmpty ? ( + const compactHeaderIcons = compactCard ? ( + + {isRemote || showsScratchMachine ? ( + + ) : null} + + + ) : null; + const titleLineIcons = compactCard ? ( + <> + {terminalStatusIcon} + {prBadge} + + ) : metaLineEmpty ? ( {remoteMachineIcon} @@ -1435,7 +1458,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP
@@ -1448,13 +1471,18 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP {pinIndicator} {props.projectDisplayName ? ( {props.projectDisplayName} - ) : ( + ) : compactCard ? null : ( )} + {compactHeaderIcons} + {compactCard ? : null} {sortable?.isDragging ? ( dragDestination ) : ( @@ -1592,7 +1620,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: SidebarThreadRowP ) : null} {titleLineIcons}
- {metaLine} + {compactCard ? null : metaLine}
{detailsTooltip} diff --git a/packages/contracts/src/settings.ts b/packages/contracts/src/settings.ts index cd112d84bf9f4..9e525290b2ef2 100644 --- a/packages/contracts/src/settings.ts +++ b/packages/contracts/src/settings.ts @@ -525,6 +525,7 @@ export const ClientSettingsSchema = Schema.Struct({ Schema.withDecodingDefault(Effect.succeed({})), ), sidebarWorkingShelfEnabled: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(true))), + sidebarCompactThreadCards: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), sidebarProjectGroupingMode: SidebarProjectGroupingMode.pipe( Schema.withDecodingDefault(Effect.succeed(DEFAULT_SIDEBAR_PROJECT_GROUPING_MODE)), ), @@ -2032,6 +2033,7 @@ export const ClientSettingsPatch = Schema.Struct({ threadDetailsUsageEnabled: Schema.optionalKey(Schema.Boolean), threadDetailsItems: Schema.optionalKey(Schema.Record(Schema.String, Schema.Boolean)), sidebarWorkingShelfEnabled: Schema.optionalKey(Schema.Boolean), + sidebarCompactThreadCards: Schema.optionalKey(Schema.Boolean), sidebarProjectGroupingMode: Schema.optionalKey(SidebarProjectGroupingMode), sidebarProjectGroupingOverrides: Schema.optionalKey( Schema.Record(TrimmedNonEmptyString, SidebarProjectGroupingMode), From 1de6c5a35e51fcc80872b8b232b69b16ceb72055 Mon Sep 17 00:00:00 2001 From: maria-rcks Date: Sun, 15 Nov 2026 03:13:42 +0000 Subject: [PATCH 2/2] fix(web): translate compact card settings --- apps/web/src/components/settings/SettingsPanels.tsx | 11 ++++++++--- apps/web/src/components/settings/settingsSearch.ts | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/apps/web/src/components/settings/SettingsPanels.tsx b/apps/web/src/components/settings/SettingsPanels.tsx index 4971d0d9fb797..70a3b17733ee7 100644 --- a/apps/web/src/components/settings/SettingsPanels.tsx +++ b/apps/web/src/components/settings/SettingsPanels.tsx @@ -935,8 +935,13 @@ export function GeneralSettingsPanel() { } /> + Drop the branch line from sidebar cards. Environment and provider icons move next to + the project name, and PRs next to the title. Hover a card for the details. + + } resetAction={ settings.sidebarCompactThreadCards !== DEFAULT_UNIFIED_SETTINGS.sidebarCompactThreadCards ? ( @@ -956,7 +961,7 @@ export function GeneralSettingsPanel() { onCheckedChange={(checked) => updateSettings({ sidebarCompactThreadCards: Boolean(checked) }) } - aria-label="Compact thread cards" + aria-label={gt("Compact thread cards")} /> } /> diff --git a/apps/web/src/components/settings/settingsSearch.ts b/apps/web/src/components/settings/settingsSearch.ts index d3cbf66f644b6..bd10b9d15e243 100644 --- a/apps/web/src/components/settings/settingsSearch.ts +++ b/apps/web/src/components/settings/settingsSearch.ts @@ -467,7 +467,7 @@ export const SETTINGS_SEARCH_ITEMS = [ }, { id: "compact-thread-cards", - title: "Compact thread cards", + title: msg("Compact thread cards"), to: "/settings/general", searchTerms: ["sidebar dense smaller hide branch worktree provider environment row"], },