diff --git a/frontend/src/app/Main.tsx b/frontend/src/app/Main.tsx
index 295be880..9537087c 100644
--- a/frontend/src/app/Main.tsx
+++ b/frontend/src/app/Main.tsx
@@ -78,11 +78,9 @@ if (typeof window !== 'undefined') {
}
import { report, getSessionTraceState, getRecentActions } from '@/shared/serviceClient';
import { useRouteTracker } from '@/shared/hooks/useRouteTracker';
-import { useKeyboardShortcuts } from '@/shared/hooks/useKeyboardShortcuts';
import { useDeepLink } from '@/shared/hooks/useDeepLink';
import { useWindowFocus } from '@/shared/hooks/useWindowFocus';
import { useInteractionHeartbeat } from '@/shared/hooks/useInteractionHeartbeat';
-import KeyboardShortcutsHelp from './components/overlays/KeyboardShortcutsHelp';
import { ThemeProvider, useThemeMode, useClaudeTokens } from '@/shared/styles/ThemeContext';
import { ClaudeTokens } from '@/shared/styles/claudeTokens';
@@ -207,11 +205,6 @@ function buildMuiTheme(c: ClaudeTokens, mode: 'light' | 'dark') {
});
}
-const ShortcutsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
- useKeyboardShortcuts();
- return <>{children}>;
-};
-
const DeepLinkListener: React.FC<{ children: React.ReactNode }> = ({ children }) => {
useDeepLink();
useWindowFocus();
@@ -469,8 +462,7 @@ const ThemedApp: React.FC = () => {
-
-
+
@@ -502,7 +494,6 @@ const ThemedApp: React.FC = () => {
-
);
diff --git a/frontend/src/app/components/overlays/KeyboardShortcutsHelp.tsx b/frontend/src/app/components/overlays/KeyboardShortcutsHelp.tsx
deleted file mode 100644
index cd92daa5..00000000
--- a/frontend/src/app/components/overlays/KeyboardShortcutsHelp.tsx
+++ /dev/null
@@ -1,95 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import Dialog from '@mui/material/Dialog';
-import DialogTitle from '@mui/material/DialogTitle';
-import DialogContent from '@mui/material/DialogContent';
-import Box from '@mui/material/Box';
-import Typography from '@mui/material/Typography';
-import { useClaudeTokens } from '@/shared/styles/ThemeContext';
-
-const shortcuts = [
- { key: 'd', description: 'Go to Dashboard' },
- { key: '1-9', description: 'Open agent by position' },
- { key: '⌘M', description: 'Add App' },
- { key: '⌘N', description: 'New Browser' },
- { key: '⌘O', description: 'History' },
- { key: 'Shift+A', description: 'Approve all pending' },
- { key: 'Shift+D', description: 'Deny all pending' },
- { key: '?', description: 'Show this help' },
-];
-
-const KeyboardShortcutsHelp: React.FC = () => {
- const c = useClaudeTokens();
- const [open, setOpen] = useState(false);
-
- useEffect(() => {
- const handler = (e: KeyboardEvent) => {
- const target = e.target as HTMLElement;
- if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) return;
- if (e.key === '?') {
- setOpen((prev) => !prev);
- }
- };
- window.addEventListener('keydown', handler);
- return () => window.removeEventListener('keydown', handler);
- }, []);
-
- return (
-
- );
-};
-
-export default KeyboardShortcutsHelp;
diff --git a/frontend/src/app/pages/Commands/Commands.tsx b/frontend/src/app/pages/Commands/Commands.tsx
index d7df9b97..ea9451ac 100644
--- a/frontend/src/app/pages/Commands/Commands.tsx
+++ b/frontend/src/app/pages/Commands/Commands.tsx
@@ -5,7 +5,6 @@ import Chip from '@mui/material/Chip';
import PsychologyIcon from '@mui/icons-material/Psychology';
import SmartToyOutlinedIcon from '@mui/icons-material/SmartToyOutlined';
import AlternateEmailIcon from '@mui/icons-material/AlternateEmail';
-import KeyboardIcon from '@mui/icons-material/Keyboard';
import TerminalIcon from '@mui/icons-material/Terminal';
import InsertDriveFileOutlinedIcon from '@mui/icons-material/InsertDriveFileOutlined';
import LanguageIcon from '@mui/icons-material/Language';
@@ -36,46 +35,6 @@ interface AtCommand {
isChild?: boolean;
}
-interface Shortcut {
- key: string;
- description: string;
- category: 'navigation' | 'action';
-}
-
-const SHORTCUTS: Shortcut[] = [
- { key: 'd', description: 'Go to Dashboard', category: 'navigation' },
- { key: '1-9', description: 'Open agent by position', category: 'navigation' },
- { key: 'Shift+A', description: 'Approve all pending', category: 'action' },
- { key: 'Shift+D', description: 'Deny all pending', category: 'action' },
- { key: '?', description: 'Show shortcuts dialog', category: 'navigation' },
-];
-
-const KeyBadge: React.FC<{ keys: string; c: any }> = ({ keys, c }) => (
-
-
- {keys}
-
-
-);
-
const SectionHeader: React.FC<{
icon: React.ReactNode;
title: string;
@@ -248,9 +207,6 @@ export const CommandsContent: React.FC = () => {
return items;
}, [builtinTools, customTools, outputItems]);
- const navShortcuts = SHORTCUTS.filter((s) => s.category === 'navigation');
- const actionShortcuts = SHORTCUTS.filter((s) => s.category === 'action');
-
return (
@@ -436,95 +392,6 @@ export const CommandsContent: React.FC = () => {
)}
-
-
-
- }
- title="Keyboard Shortcuts"
- subtitle="Press ? anywhere to see the quick-reference dialog"
- count={SHORTCUTS.length}
- c={c}
- />
-
-
-
-
- Navigation
-
-
- {navShortcuts.map((s) => (
-
-
- {s.description}
-
-
-
- ))}
-
-
-
-
-
- Actions
-
-
- {actionShortcuts.map((s) => (
-
-
- {s.description}
-
-
-
- ))}
-
-
-
-
);
};
diff --git a/frontend/src/shared/hooks/useKeyboardShortcuts.ts b/frontend/src/shared/hooks/useKeyboardShortcuts.ts
deleted file mode 100644
index 941b092e..00000000
--- a/frontend/src/shared/hooks/useKeyboardShortcuts.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { useEffect, useCallback } from 'react';
-import { useNavigate } from 'react-router-dom';
-import { useAppDispatch, useAppSelector } from '@/shared/hooks';
-import { handleApproval, setActiveSession } from '@/shared/state/agentsSlice';
-
-export function useKeyboardShortcuts() {
- const navigate = useNavigate();
- const dispatch = useAppDispatch();
- const sessions = useAppSelector((state) => state.agents.sessions);
-
- const handler = useCallback(
- (e: KeyboardEvent) => {
- const target = e.target as HTMLElement | null;
- const active = document.activeElement as HTMLElement | null;
- // Double-guard: e.target AND document.activeElement. A bare-letter
- // shortcut would otherwise fire if focus is on a wrapper Box and the
- // child input never received it, kicking the user out mid-type.
- const isInputLike = (el: HTMLElement | null) =>
- !!el && (
- el.tagName === 'INPUT' ||
- el.tagName === 'TEXTAREA' ||
- el.isContentEditable ||
- !!el.closest('input, textarea, [contenteditable="true"]')
- );
- if (isInputLike(target) || isInputLike(active)) return;
-
- // Mod-gated shortcuts only. Bare letters were footguns: typing the
- // letter "d" anywhere outside a tagged input field used to navigate
- // home, which surprised users typing workflow titles/descriptions.
- if (e.key.toLowerCase() === 'd' && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
- e.preventDefault();
- navigate('/');
- return;
- }
-
- if (e.key === 'A' && e.shiftKey && (e.metaKey || e.ctrlKey)) {
- e.preventDefault();
- for (const session of Object.values(sessions)) {
- for (const req of session.pending_approvals) {
- dispatch(handleApproval({ requestId: req.id, behavior: 'allow' }));
- }
- }
- return;
- }
-
- if (e.key === 'D' && e.shiftKey && (e.metaKey || e.ctrlKey)) {
- e.preventDefault();
- for (const session of Object.values(sessions)) {
- for (const req of session.pending_approvals) {
- dispatch(handleApproval({ requestId: req.id, behavior: 'deny' }));
- }
- }
- return;
- }
-
- if (e.key >= '1' && e.key <= '9' && (e.metaKey || e.ctrlKey) && !e.shiftKey) {
- e.preventDefault();
- const idx = parseInt(e.key) - 1;
- const sessionList = Object.values(sessions).sort(
- (a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
- );
- if (sessionList[idx]) {
- navigate('/');
- dispatch(setActiveSession(sessionList[idx].id));
- }
- return;
- }
- },
- [navigate, dispatch, sessions]
- );
-
- useEffect(() => {
- window.addEventListener('keydown', handler);
- return () => window.removeEventListener('keydown', handler);
- }, [handler]);
-}