diff --git a/packages/app/src/app/_layout.tsx b/packages/app/src/app/_layout.tsx index cabdd37c0..a6fdb40c8 100644 --- a/packages/app/src/app/_layout.tsx +++ b/packages/app/src/app/_layout.tsx @@ -264,6 +264,7 @@ function AppContainer({ const daemons = useHosts(); const toggleAgentList = usePanelStore((state) => state.toggleAgentList); const toggleFileExplorer = usePanelStore((state) => state.toggleFileExplorer); + const toggleBothSidebars = usePanelStore((state) => state.toggleBothSidebars); const isMobile = UnistylesRuntime.breakpoint === "xs" || UnistylesRuntime.breakpoint === "sm"; const chromeEnabled = chromeEnabledOverride ?? daemons.length > 0; @@ -274,6 +275,7 @@ function AppContainer({ toggleAgentList, selectedAgentId, toggleFileExplorer, + toggleBothSidebars, }); const containerStyle = useMemo( diff --git a/packages/app/src/hooks/use-keyboard-shortcuts.ts b/packages/app/src/hooks/use-keyboard-shortcuts.ts index 7434e2b9a..42ca92c57 100644 --- a/packages/app/src/hooks/use-keyboard-shortcuts.ts +++ b/packages/app/src/hooks/use-keyboard-shortcuts.ts @@ -33,12 +33,14 @@ export function useKeyboardShortcuts({ toggleAgentList, selectedAgentId, toggleFileExplorer, + toggleBothSidebars, }: { enabled: boolean; isMobile: boolean; toggleAgentList: () => void; selectedAgentId?: string; toggleFileExplorer?: () => void; + toggleBothSidebars?: () => void; }) { const pathname = usePathname(); const hosts = useHosts(); @@ -228,6 +230,11 @@ export function useKeyboardShortcuts({ case "sidebar.toggle.left": toggleAgentList(); return true; + case "sidebar.toggle.both": + if (toggleBothSidebars) { + toggleBothSidebars(); + } + return true; case "sidebar.toggle.right": if (!toggleFileExplorer) { return false; diff --git a/packages/app/src/keyboard/actions.ts b/packages/app/src/keyboard/actions.ts index 4cd0ad84c..d4746bc46 100644 --- a/packages/app/src/keyboard/actions.ts +++ b/packages/app/src/keyboard/actions.ts @@ -35,6 +35,7 @@ export type KeyboardActionId = | "workspace.navigate.relative" | "sidebar.toggle.left" | "sidebar.toggle.right" + | "sidebar.toggle.both" | "command-center.toggle" | "shortcuts.dialog.toggle" | "workspace.terminal.new" diff --git a/packages/app/src/keyboard/keyboard-shortcuts.ts b/packages/app/src/keyboard/keyboard-shortcuts.ts index 1eddcff71..413ec2588 100644 --- a/packages/app/src/keyboard/keyboard-shortcuts.ts +++ b/packages/app/src/keyboard/keyboard-shortcuts.ts @@ -649,22 +649,16 @@ const SHORTCUT_BINDINGS: readonly ShortcutBinding[] = [ keys: ["mod", "B"], }, }, - { - id: "sidebar-toggle-left-cmd-period-mac", - action: "sidebar.toggle.left", - combo: "Cmd+.", - when: { mac: true, commandCenter: false }, - }, { id: "sidebar-toggle-left-ctrl-period-non-mac", action: "sidebar.toggle.left", - combo: "Ctrl+.", + combo: "Ctrl+B", when: { mac: false, commandCenter: false, terminal: false }, help: { id: "toggle-left-sidebar", section: "panels", label: "Toggle left sidebar", - keys: ["mod", "."], + keys: ["mod", "B"], }, }, { @@ -698,6 +692,32 @@ const SHORTCUT_BINDINGS: readonly ShortcutBinding[] = [ when: { hasSelectedAgent: true, commandCenter: false }, }, + // --- Toggle both sidebars --- + { + id: "sidebar-toggle-both-cmd-period-mac", + action: "sidebar.toggle.both", + combo: "Cmd+.", + when: { mac: true, commandCenter: false }, + help: { + id: "toggle-both-sidebars", + section: "panels", + label: "Toggle both sidebars", + keys: ["mod", "."], + }, + }, + { + id: "sidebar-toggle-both-ctrl-period-non-mac", + action: "sidebar.toggle.both", + combo: "Ctrl+.", + when: { mac: false, commandCenter: false, terminal: false }, + help: { + id: "toggle-both-sidebars", + section: "panels", + label: "Toggle both sidebars", + keys: ["mod", "."], + }, + }, + // --- Message input --- { id: "message-input-voice-toggle-cmd-shift-d-mac", diff --git a/packages/app/src/stores/panel-store.ts b/packages/app/src/stores/panel-store.ts index 71782becc..369bd7522 100644 --- a/packages/app/src/stores/panel-store.ts +++ b/packages/app/src/stores/panel-store.ts @@ -78,6 +78,7 @@ interface PanelState { closeToAgent: () => void; toggleAgentList: () => void; toggleFileExplorer: () => void; + toggleBothSidebars: () => void; // File explorer settings actions setExplorerTab: (tab: ExplorerTab) => void; @@ -216,6 +217,24 @@ export const usePanelStore = create()( return nextState; }), + toggleBothSidebars: () => + set((state) => { + // If either sidebar is open, close both. Otherwise, open both. + const anyOpen = state.desktop.agentListOpen || state.desktop.fileExplorerOpen; + if (anyOpen) { + return { + mobileView: "agent" as MobilePanelView, + desktop: { agentListOpen: false, fileExplorerOpen: false }, + }; + } + const resolvedTab = resolveExplorerTabFromActiveCheckout(state); + return { + mobileView: "agent" as MobilePanelView, + desktop: { agentListOpen: true, fileExplorerOpen: true }, + ...(resolvedTab ? { explorerTab: resolvedTab } : {}), + }; + }), + setExplorerTab: (tab) => set({ explorerTab: tab }), setExplorerTabForCheckout: ({ serverId, cwd, isGit, tab }) => set((state) => {