feat: make agent switching shortcut configurable (#1186)

Adds Cycle Agent to shortcut settings with Tab as the default
Applies custom shortcut in chat input and model selector
Updates help dialog to show saved shortcut values
This commit is contained in:
Bohdan Triapitsyn
2026-05-15 00:27:39 +03:00
parent 8c226afbbb
commit ba019c05a6
19 changed files with 139 additions and 17 deletions
+53 -1
View File
@@ -9,9 +9,10 @@ import { createWorktreeSession } from '@/lib/worktreeSessionCreator';
import { useConfigStore } from '@/stores/useConfigStore';
import { canUseElectronDesktopIPC, invokeDesktop, isVSCodeRuntime } from '@/lib/desktop';
import { showOpenCodeStatus } from '@/lib/openCodeStatus';
import { eventMatchesShortcut, getEffectiveShortcutCombo } from '@/lib/shortcuts';
import { eventMatchesShortcut, getEffectiveShortcutCombo, normalizeCombo } from '@/lib/shortcuts';
import { useDirectoryStore } from '@/stores/useDirectoryStore';
import { useProjectsStore } from '@/stores/useProjectsStore';
import { getCycledPrimaryAgentName } from '@/components/chat/mobileControlsUtils';
export const useKeyboardShortcuts = () => {
const openNewSessionDraft = useSessionUIStore((s) => s.openNewSessionDraft);
@@ -101,6 +102,10 @@ export const useKeyboardShortcuts = () => {
return;
}
const isChatInputTarget = (target: EventTarget | null) => {
return target instanceof HTMLTextAreaElement && target.getAttribute('data-chat-input') === 'true';
};
if (eventMatchesShortcut(e, combo('open_command_palette'))) {
e.preventDefault();
toggleCommandPalette();
@@ -200,6 +205,53 @@ export const useKeyboardShortcuts = () => {
return;
}
const cycleAgentCombo = combo('cycle_agent');
const cycleAgentBackwardCombo = cycleAgentCombo && !cycleAgentCombo.includes('shift')
? normalizeCombo(`shift+${cycleAgentCombo}`)
: '';
const cycleAgentDirection = cycleAgentBackwardCombo && eventMatchesShortcut(e, cycleAgentBackwardCombo)
? -1
: eventMatchesShortcut(e, cycleAgentCombo)
? 1
: 0;
if (cycleAgentDirection !== 0) {
const {
isSettingsDialogOpen,
isCommandPaletteOpen,
isHelpDialogOpen,
isSessionSwitcherOpen,
isAboutDialogOpen,
activeMainTab,
} = useUIStore.getState();
const hasOverlay = isSettingsDialogOpen || isCommandPaletteOpen || isHelpDialogOpen || isSessionSwitcherOpen || isAboutDialogOpen;
if (hasOverlay || activeMainTab !== 'chat' || !isChatInputTarget(e.target)) {
return;
}
const configState = useConfigStore.getState();
const nextAgentName = getCycledPrimaryAgentName(
configState.getVisibleAgents(),
configState.currentAgentName,
cycleAgentDirection,
);
if (!nextAgentName) {
return;
}
e.preventDefault();
configState.setAgent(nextAgentName);
useUIStore.getState().addRecentAgent(nextAgentName);
const sessionId = useSessionUIStore.getState().currentSessionId;
if (sessionId) {
useSelectionStore.getState().saveSessionAgentSelection(sessionId, nextAgentName);
}
return;
}
if (eventMatchesShortcut(e, combo('toggle_right_sidebar'))) {
const { isMobile } = useUIStore.getState();
if (isMobile) {