diff --git a/src/renderer/src/App.tsx b/src/renderer/src/App.tsx
index 3bcbf8887..1071ff9ae 100644
--- a/src/renderer/src/App.tsx
+++ b/src/renderer/src/App.tsx
@@ -1604,6 +1604,21 @@ function App(): React.JSX.Element {
return
}
+ // Toggle the "show sleeping workspaces" sidebar filter without opening the
+ // filters menu (issue #5209). When revealing them, open the left sidebar
+ // so the now-visible sleeping worktrees are actually reachable.
+ if (matchShortcut('sidebar.sleepingWorkspaces.toggle')) {
+ input.preventDefault()
+ notifyTerminalCapture('sidebar.sleepingWorkspaces.toggle')
+ const store = useAppStore.getState()
+ const nextShowSleeping = !store.showSleepingWorkspaces
+ store.setShowSleepingWorkspaces(nextShowSleeping)
+ if (nextShowSleeping) {
+ store.setSidebarOpen(true)
+ }
+ return
+ }
+
// Why: rename the active terminal tab. Cmd+R is free in the app/terminal
// focus zone because the browser pane owns its own Cmd+R reload and that
// focus never reaches this renderer-window handler. Only terminal tabs
diff --git a/src/renderer/src/components/sidebar/SidebarFilter.tsx b/src/renderer/src/components/sidebar/SidebarFilter.tsx
index 7d21c357a..9927e4e9d 100644
--- a/src/renderer/src/components/sidebar/SidebarFilter.tsx
+++ b/src/renderer/src/components/sidebar/SidebarFilter.tsx
@@ -13,10 +13,12 @@ import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuSeparator,
+ DropdownMenuShortcut,
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'
import { Tooltip, TooltipTrigger, TooltipContent } from '@/components/ui/tooltip'
import RepoBadgeLabel from '@/components/repo/RepoBadgeLabel'
+import { useShortcutLabel } from '@/hooks/useShortcutLabel'
import { searchRepos } from '@/lib/repo-search'
import { cn } from '@/lib/utils'
import { DEFAULT_SHOW_SLEEPING_WORKSPACES } from '../../../../shared/constants'
@@ -37,6 +39,9 @@ const SidebarFilter = React.memo(function SidebarFilter({
}: SidebarFilterProps) {
const showSleepingWorkspaces = useAppStore((s) => s.showSleepingWorkspaces)
const setShowSleepingWorkspaces = useAppStore((s) => s.setShowSleepingWorkspaces)
+ // Surface the user-assigned shortcut here so the filter menu doubles as its
+ // discovery point ('Unassigned' until they bind one in Settings → Shortcuts).
+ const sleepingShortcut = useShortcutLabel('sidebar.sleepingWorkspaces.toggle')
const hideDefaultBranchWorkspace = useAppStore((s) => s.hideDefaultBranchWorkspace)
const setHideDefaultBranchWorkspace = useAppStore((s) => s.setHideDefaultBranchWorkspace)
const hideAutomationGeneratedWorkspaces = useAppStore((s) => s.hideAutomationGeneratedWorkspaces)
@@ -183,6 +188,7 @@ const SidebarFilter = React.memo(function SidebarFilter({
label={translate('auto.components.sidebar.SidebarFilter.638a2d221d', 'Hide sleeping')}
checked={!showSleepingWorkspaces}
onChange={(hideSleeping) => setShowSleepingWorkspaces(!hideSleeping)}
+ shortcutLabel={sleepingShortcut === 'Unassigned' ? undefined : sleepingShortcut}
/>
}
@@ -333,12 +339,14 @@ function FilterToggleRow({
icon,
label,
checked,
- onChange
+ onChange,
+ shortcutLabel
}: {
icon: React.ReactNode
label: string
checked: boolean
onChange: (next: boolean) => void
+ shortcutLabel?: string
}) {
return (
)
diff --git a/src/renderer/src/components/task-page-github-work-item-status.ts b/src/renderer/src/components/task-page-github-work-item-status.ts
index a8028e6a4..ab9d03610 100644
--- a/src/renderer/src/components/task-page-github-work-item-status.ts
+++ b/src/renderer/src/components/task-page-github-work-item-status.ts
@@ -65,8 +65,5 @@ export function getTaskPageGitHubPRIconTone(item: GitHubWorkItemStatusItem): str
return 'text-purple-600 dark:text-purple-300'
case 'closed':
return 'text-rose-600 dark:text-rose-300'
- default:
- // Fallback for any unexpected state
- return 'text-muted-foreground'
}
}
diff --git a/src/shared/keybindings.test.ts b/src/shared/keybindings.test.ts
index 83db7e37e..e69917db0 100644
--- a/src/shared/keybindings.test.ts
+++ b/src/shared/keybindings.test.ts
@@ -456,6 +456,42 @@ describe('keybindings', () => {
)
})
+ it('keeps the sleeping-workspaces toggle unassigned until users customize it', () => {
+ const binding = {
+ key: 's',
+ code: 'KeyS',
+ control: true,
+ meta: false,
+ alt: true,
+ shift: false
+ }
+
+ // Ships unbound on every platform (issue #5209): assign-it-yourself.
+ expect(getEffectiveKeybindingsForAction('sidebar.sleepingWorkspaces.toggle', 'darwin')).toEqual(
+ []
+ )
+ expect(getEffectiveKeybindingsForAction('sidebar.sleepingWorkspaces.toggle', 'linux')).toEqual(
+ []
+ )
+ expect(getEffectiveKeybindingsForAction('sidebar.sleepingWorkspaces.toggle', 'win32')).toEqual(
+ []
+ )
+ expect(keybindingMatchesAction('sidebar.sleepingWorkspaces.toggle', binding, 'linux')).toBe(
+ false
+ )
+ expect(
+ keybindingMatchesAction('sidebar.sleepingWorkspaces.toggle', binding, 'linux', {
+ 'sidebar.sleepingWorkspaces.toggle': ['Mod+Alt+S']
+ })
+ ).toBe(true)
+
+ const definition = getKeybindingDefinition('sidebar.sleepingWorkspaces.toggle')
+ expect(definition?.title).toBe('Toggle Sleeping Workspaces')
+ expect(definition?.searchKeywords).toEqual(
+ expect.arrayContaining(['sleeping', 'workspaces', 'filter'])
+ )
+ })
+
it('defines floating workspace panel action metadata', () => {
const actionIds = [
'floatingWorkspace.maximize' as KeybindingActionId,
diff --git a/src/shared/keybindings.ts b/src/shared/keybindings.ts
index 57a8b7752..6d4c3e64f 100644
--- a/src/shared/keybindings.ts
+++ b/src/shared/keybindings.ts
@@ -48,6 +48,7 @@ export type KeybindingActionId =
| 'sidebar.sourceControl.toggle'
| 'sidebar.checks.toggle'
| 'sidebar.ports.toggle'
+ | 'sidebar.sleepingWorkspaces.toggle'
| 'sidebar.focusWorktreeList'
| 'floatingTerminal.toggle'
| 'floatingWorkspace.maximize'
@@ -393,6 +394,26 @@ export const KEYBINDING_DEFINITIONS: readonly KeybindingDefinition[] = [
win32: []
}
},
+ {
+ id: 'sidebar.sleepingWorkspaces.toggle',
+ title: 'Toggle Sleeping Workspaces',
+ group: 'Global',
+ scope: 'global',
+ searchKeywords: [
+ 'shortcut',
+ 'sidebar',
+ 'sleeping',
+ 'asleep',
+ 'workspaces',
+ 'worktree',
+ 'filter',
+ 'show',
+ 'hide'
+ ],
+ // Why: ship unbound — issue #5209 asks to "assign a shortcut", so we avoid
+ // claiming a cross-platform chord and let users bind it in Settings.
+ defaultBindings: platformBindings([])
+ },
{
id: 'sidebar.focusWorktreeList',
title: 'Focus worktree list',