+ Shortcuts won't trigger when typing in input fields. Use
+ single keys (A-Z, 0-9) or special keys like ` (backtick).
+ Changes take effect immediately.
+
+
+
+
+
+
{/* Feature Defaults Section */}
= {
- board: "K", // K for Kanban
- agent: "A", // A for Agent
- spec: "D", // D for Document (Spec)
- context: "C", // C for Context
- tools: "T", // T for Tools
- settings: "S", // S for Settings
- profiles: "M", // M for Models/profiles
-};
-
-/**
- * Shortcut definitions for UI controls
- */
-export const UI_SHORTCUTS: Record = {
- toggleSidebar: "`", // Backtick to toggle sidebar
-};
-
-/**
- * Shortcut definitions for add buttons
- */
-export const ACTION_SHORTCUTS: Record = {
- addFeature: "N", // N for New feature
- addContextFile: "F", // F for File (add context file)
- startNext: "G", // G for Grab (start next features from backlog)
- newSession: "N", // N for New session (in agent view)
- openProject: "O", // O for Open project (navigate to welcome view)
- projectPicker: "P", // P for Project picker
- cyclePrevProject: "Q", // Q for previous project (cycle back through MRU)
- cycleNextProject: "E", // E for next project (cycle forward through MRU)
- addProfile: "N", // N for New profile (when in profiles view)
-};
+export function useKeyboardShortcutsConfig() {
+ const keyboardShortcuts = useAppStore((state) => state.keyboardShortcuts);
+ return keyboardShortcuts;
+}
diff --git a/app/src/store/app-store.ts b/app/src/store/app-store.ts
index 738de87f..7c9ced56 100644
--- a/app/src/store/app-store.ts
+++ b/app/src/store/app-store.ts
@@ -37,6 +37,60 @@ export interface ApiKeys {
openai: string;
}
+// Keyboard Shortcuts
+export interface KeyboardShortcuts {
+ // Navigation shortcuts
+ board: string;
+ agent: string;
+ spec: string;
+ context: string;
+ tools: string;
+ settings: string;
+ profiles: string;
+
+ // UI shortcuts
+ toggleSidebar: string;
+
+ // Action shortcuts
+ addFeature: string;
+ addContextFile: string;
+ startNext: string;
+ newSession: string;
+ openProject: string;
+ projectPicker: string;
+ cyclePrevProject: string;
+ cycleNextProject: string;
+ addProfile: string;
+}
+
+// Default keyboard shortcuts
+export const DEFAULT_KEYBOARD_SHORTCUTS: KeyboardShortcuts = {
+ // Navigation
+ board: "K",
+ agent: "A",
+ spec: "D",
+ context: "C",
+ tools: "T",
+ settings: "S",
+ profiles: "M",
+
+ // UI
+ toggleSidebar: "`",
+
+ // Actions
+ // Note: Some shortcuts share the same key (e.g., "N" for addFeature, newSession, addProfile)
+ // This is intentional as they are context-specific and only active in their respective views
+ addFeature: "N", // Only active in board view
+ addContextFile: "F", // Only active in context view
+ startNext: "G", // Only active in board view
+ newSession: "N", // Only active in agent view
+ openProject: "O", // Global shortcut
+ projectPicker: "P", // Global shortcut
+ cyclePrevProject: "Q", // Global shortcut
+ cycleNextProject: "E", // Global shortcut
+ addProfile: "N", // Only active in profiles view
+};
+
export interface ImageAttachment {
id: string;
data: string; // base64 encoded image data
@@ -203,6 +257,9 @@ export interface AppState {
// Profile Display Settings
showProfilesOnly: boolean; // When true, hide model tweaking options and show only profile selection
+ // Keyboard Shortcuts
+ keyboardShortcuts: KeyboardShortcuts; // User-defined keyboard shortcuts
+
// Project Analysis
projectAnalysis: ProjectAnalysis | null;
isAnalyzing: boolean;
@@ -303,6 +360,11 @@ export interface AppActions {
// Profile Display Settings actions
setShowProfilesOnly: (enabled: boolean) => void;
+ // Keyboard Shortcuts actions
+ setKeyboardShortcut: (key: keyof KeyboardShortcuts, value: string) => void;
+ setKeyboardShortcuts: (shortcuts: Partial) => void;
+ resetKeyboardShortcuts: () => void;
+
// AI Profile actions
addAIProfile: (profile: Omit) => void;
updateAIProfile: (id: string, updates: Partial) => void;
@@ -404,6 +466,7 @@ const initialState: AppState = {
defaultSkipTests: false, // Default to TDD mode (tests enabled)
useWorktrees: false, // Default to disabled (worktree feature is experimental)
showProfilesOnly: false, // Default to showing all options (not profiles only)
+ keyboardShortcuts: DEFAULT_KEYBOARD_SHORTCUTS, // Default keyboard shortcuts
aiProfiles: DEFAULT_AI_PROFILES,
projectAnalysis: null,
isAnalyzing: false,
@@ -907,6 +970,29 @@ export const useAppStore = create()(
// Profile Display Settings actions
setShowProfilesOnly: (enabled) => set({ showProfilesOnly: enabled }),
+ // Keyboard Shortcuts actions
+ setKeyboardShortcut: (key, value) => {
+ set({
+ keyboardShortcuts: {
+ ...get().keyboardShortcuts,
+ [key]: value,
+ },
+ });
+ },
+
+ setKeyboardShortcuts: (shortcuts) => {
+ set({
+ keyboardShortcuts: {
+ ...get().keyboardShortcuts,
+ ...shortcuts,
+ },
+ });
+ },
+
+ resetKeyboardShortcuts: () => {
+ set({ keyboardShortcuts: DEFAULT_KEYBOARD_SHORTCUTS });
+ },
+
// AI Profile actions
addAIProfile: (profile) => {
const id = `profile-${Date.now()}-${Math.random()
@@ -985,6 +1071,7 @@ export const useAppStore = create()(
defaultSkipTests: state.defaultSkipTests,
useWorktrees: state.useWorktrees,
showProfilesOnly: state.showProfilesOnly,
+ keyboardShortcuts: state.keyboardShortcuts,
aiProfiles: state.aiProfiles,
lastSelectedSessionByProject: state.lastSelectedSessionByProject,
}),