feat: keyboard shortcuts for navigation, views, and task actions#293
feat: keyboard shortcuts for navigation, views, and task actions#293pikann wants to merge 1 commit into
Conversation
…tions Lets users navigate between sidebar pages, switch views on an interaction page, and act on the task under the pointer (open, epic, move column, delete) via Mod+key shortcuts, plus a right-click context menu on every task card/row with matching shortcut hints. Discoverable through a Mod+/ help dialog and localized across all 9 supported locales. Builds on the keyboard-shortcut direction discussed in #230. Co-Authored-By: RSnew <64447978+RSnew@users.noreply.github.com> Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Important
Several user-facing shortcuts in the new keymap collide with browser/OS defaults or are not actually wired, and goto.settings is layout-broken on common US keyboards. Type check, lint, and tests all pass, so these are UX-correctness issues rather than crashes.
Reviewed changes — added a global keyboard shortcut system, task right-click context menu, platform-aware keycap components, and help dialog across the authenticated web app.
- Add
lib/shortcuts/*keymap, provider, hover/page zustand stores, andkeymap.test.ts. - Add
TaskContextMenuaroundTaskCard/TaskRowwith move-to, status, assignee, type, priority, epic, copy, and delete actions. - Add
components/ui/context-menu.tsxandcomponents/ui/kbd.tsx. - Add
ShortcutHelpDialogreachable fromMod+/and the user menu. - Wire page shortcuts and a delete confirmation dialog in
InteractionLayout.
ℹ️ Task shortcuts are mouse-only by design
Task-scope shortcuts are registered from onMouseEnter/onMouseLeave, and the docs correctly call this an accessibility gap. Open a follow-up issue for keyboard focus support so the same shortcuts are available to keyboard-only users.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
| // Roughly half the keyboard is off-limits because the browser or the OS | ||
| // swallows the keydown before page JS ever sees it, or because overriding it | ||
| // would break a near-universal user expectation: | ||
| // - Hard-blocked, no override possible on any browser: Mod+T/N/W (tab/window |
There was a problem hiding this comment.
Several chosen shortcuts overlap with browser defaults that the file’s hard-blocked list misses. Even with preventDefault(), tab/window/history/bookmark bindings are often non-cancelable, so users may get browser behavior instead of the app action.
Technical details
# Affected sites
- `apps/web/src/lib/shortcuts/keymap.ts:10-16` — comment lists hard-blocked combos but omits several used below.
- `apps/web/src/lib/shortcuts/keymap.ts:53-79` — PLAIN_ACTIONS / SHIFT_ACTIONS contain the colliding bindings.
## Collisions to verify
Based on Chrome keyboard-shortcut docs:
- `Mod+Shift+W` (automation) = close current window on macOS/Windows/Linux.
- `Mod+Shift+H` (home) = open home page on macOS/Windows.
- `Mod+Shift+A` (active sprint) = tab search in Chrome.
- `Mod+Shift+,` (settings) = Chrome Settings on macOS (`⌘,`, and with Shift it still conflicts).
- `Mod+G` (agents) = find next match.
- `Mod+J` (team) = open downloads (Windows/Linux).
- `Mod+D` (docs) = bookmark current page.
- `Mod+O` (open task) = open file dialog.
- `Mod+[` / `Mod+]` (prev/next view) = history back/forward on macOS.
## Required outcome
Audit every binding against browser/OS defaults and replace contested combos. Prefer keys that are truly free, even if less mnemonic.| a: "goto.activeSprint", | ||
| x: "goto.conversations", | ||
| w: "goto.automation", | ||
| ",": "goto.settings", |
There was a problem hiding this comment.
On US English keyboards, Shift+Comma produces <, not ,, so goto.settings will not match here. Consider matching on e.code === "Comma" or accepting both , and < so the shortcut works across layouts.
| chords: [{ mod: true, key: "B" }], | ||
| }, | ||
| { | ||
| id: "general.close", |
There was a problem hiding this comment.
Esc is shown in the help dialog as general.close, but ShortcutProvider never matches or dispatches it. Either implement a global close stack or remove general.close from SHORTCUT_DISPLAY and the docs to avoid a false promise.
| * Action callbacks the currently-hovered/focused task card or row exposes to | ||
| * the global shortcut provider. Views register a task's actions on | ||
| * mouseenter/focus and clear them on mouseleave/blur — see | ||
| * `use-task-shortcut-target.ts`. Only one task can be "active" at a time, so |
There was a problem hiding this comment.
The docstring references use-task-shortcut-target.ts, which doesn't exist. Update it to point to TaskCard and TaskRow.

What
A discoverable keyboard shortcut system for the web app:
Mod+Shift+H,Mod+I,Mod+G, etc.)Mod+[/Mod+], focus search withMod+F, toggle view settings withMod+Shift+F, create a task withMod+EnterMod+O(open),Mod+E(epic),Mod+←/Mod+→(move to the previous/next column of whatever the view is grouped by — status, sprint, assignee, or type), orMod+⌫(delete)Mod+/help dialog listing every binding, generated from a single keymap registry so it can never drift from the real bindingsFull design rationale (including which
Mod+keycombos are hard-blocked by the browser/OS and had to be worked around) is indocs/product/keyboard-shortcuts.md.Localized in all 9 supported locales (en, es, fr, ja, ko, pt-BR, ru, vi, zh-CN).
Why
Closes #230. The issue's discussion converged on exactly this shape — hovering a task and pressing a key, plus a right-click menu that shows the matching shortcut next to each action — so this PR builds that as general infrastructure (any task field, any view's columns) rather than a single sprint/backlog toggle.
This replaces #231 with a broader solution: instead of one double-click gesture for Backlog ↔ Sprint, moving a task to any column (including Sprint or Backlog when a view groups by sprint) is available via
Mod+←/Mod+→while hovering, or via the right-click "Move to" menu — plus the rest of the shortcut system above. Big thanks to @RSnew for the original report and for pushing the discussion toward the hover-shortcut + context-menu design in the comments — credited as co-author on the commit.Test plan
tsc -b --noEmit— cleanbiome check .— cleanvitest run— 306 tests pass, including newlib/shortcuts/keymap.test.tscoverage of the key matcher