From 0450985dd8a100d9f5d3dc352dd4d776738dcb97 Mon Sep 17 00:00:00 2001 From: Daniel Kutyla Date: Thu, 19 Mar 2026 12:34:50 +0100 Subject: [PATCH 1/3] feat(keymap): add Ctrl+Alt+D shortcut to navigate to Kanban board Registers a global nav:kanban action (Ctrl+Alt+D / Cmd+Alt+D on Mac) that switches to the Kanban board from any app. Also adds a default shortcuts table to the documentation Keymap section. --- src/apps/documentation/public/page.js | 12 ++++++++++++ src/packages/shared-assets/keymap-registry.js | 5 +++++ src/public/app.js | 10 ++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/apps/documentation/public/page.js b/src/apps/documentation/public/page.js index 4da2f96..1f82052 100644 --- a/src/apps/documentation/public/page.js +++ b/src/apps/documentation/public/page.js @@ -378,6 +378,18 @@ const MODULES_HTML = `
\u2328

Keymap

Configurable keyboard shortcuts for dashboard navigation and actions. Customize bindings for switching between apps, triggering actions, and navigating the UI efficiently.

+

Default Shortcuts

+ + + + + + + + + + +
Ctrl+Alt+DNavigate to Kanban board (from any app)
Ctrl+Alt+1–9Switch to terminal tab 1–9
Ctrl+Alt+JNew terminal pane
Ctrl+Alt+BNew browser pane
Ctrl+Alt+KClose current pane
Ctrl+Alt+ArrowsNavigate between panes in grid
Ctrl+Alt+Shift (hold)Hold-to-speak voice input
`; diff --git a/src/packages/shared-assets/keymap-registry.js b/src/packages/shared-assets/keymap-registry.js index 6078411..65f1025 100644 --- a/src/packages/shared-assets/keymap-registry.js +++ b/src/packages/shared-assets/keymap-registry.js @@ -494,6 +494,11 @@ { ctrlOrMeta: true, altKey: true, shiftKey: true }, 'Hold to speak', 'Voice'); + // Navigation group + KeymapRegistry.register('nav:kanban', + { ctrlOrMeta: true, altKey: true, code: 'KeyD' }, + 'Go to Kanban', 'Navigation'); + // Kanban group KeymapRegistry.register('kanban:focus-search', { key: '/' }, diff --git a/src/public/app.js b/src/public/app.js index a053688..64d1c80 100644 --- a/src/public/app.js +++ b/src/public/app.js @@ -675,6 +675,16 @@ if (typeof VoiceWidget !== 'undefined') { const voiceMountEl = document.getElementById('voice-widget-mount'); if (voiceMountEl) voiceWidget.mount(voiceMountEl); + // Handle global navigation shortcuts (Ctrl+Alt+D → Kanban, etc.) + document.addEventListener('keydown', (e) => { + if (typeof KeymapRegistry === 'undefined') return; + const action = KeymapRegistry.resolve(e); + if (action === 'nav:kanban') { + e.preventDefault(); + selectApp('kanban'); + } + }); + // Handle Ctrl+Alt+Shift hold-to-speak when the shell has focus let voiceKeyActive = false; document.addEventListener('keydown', (e) => { From a582155aa3d327b38edac8722e90c54d84b5e474 Mon Sep 17 00:00:00 2001 From: Daniel Kutyla Date: Thu, 19 Mar 2026 12:44:11 +0100 Subject: [PATCH 2/3] fix(shell): handle nav:kanban shortcut within shell's own keydown handler Store the SPA navigate callback from mount context and handle the nav:kanban action directly in the shell's keydown switch, so Ctrl+Alt+D routes through the dashboard properly when inside the shell. --- src/apps/shell/public/page.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/apps/shell/public/page.js b/src/apps/shell/public/page.js index 6c88bdc..e13c758 100644 --- a/src/apps/shell/public/page.js +++ b/src/apps/shell/public/page.js @@ -16,6 +16,7 @@ let _keydownHandler = null; let _xtermLoaded = false; let _mountedOnce = false; let _restoring = false; // true during snapshot batch restore — suppresses premature fits +let _navigate = null; // SPA navigate callback from dashboard ctx const panes = new Map(); // id -> pane object const pendingData = new Map(); // id -> string[] — buffers terminal data for panes not yet created @@ -1421,8 +1422,9 @@ export async function mount(container, ctx) { // 3. Get refs const refs = getRefs(container); - // 4. Set initial project + // 4. Set initial project + stash navigate callback activeProject = ctx?.project || null; + _navigate = ctx?.navigate || null; // 5. Load xterm.js dynamically await ensureXterm(); @@ -1555,6 +1557,11 @@ export async function mount(container, ctx) { if (activePaneId) panes.get(activePaneId)?.destroy(); break; } + case 'nav:kanban': { + e.preventDefault(); + if (_navigate) _navigate('kanban'); + break; + } default: { const termMatch = action.match(/^shell:terminal-(\d)$/); if (termMatch) { From 334ab80cddd0d60cd77694e5d7d04dea8ea7d808 Mon Sep 17 00:00:00 2001 From: Daniel Kutyla Date: Thu, 19 Mar 2026 12:47:05 +0100 Subject: [PATCH 3/3] fix(shell): Ctrl+Alt+D switches to dashboard grid tab within shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverts the kanban sidebar navigation approach. Instead, Ctrl+Alt+D now works like Ctrl+Alt+1-9 — it's a shell-scoped shortcut that switches to the Dashboard (grid view) tab showing all panes. --- src/apps/documentation/public/page.js | 2 +- src/apps/shell/public/page.js | 8 +++----- src/packages/shared-assets/keymap-registry.js | 9 ++++----- src/public/app.js | 10 ---------- 4 files changed, 8 insertions(+), 21 deletions(-) diff --git a/src/apps/documentation/public/page.js b/src/apps/documentation/public/page.js index 1f82052..85050bd 100644 --- a/src/apps/documentation/public/page.js +++ b/src/apps/documentation/public/page.js @@ -381,7 +381,7 @@ const MODULES_HTML = `

Default Shortcuts

- + diff --git a/src/apps/shell/public/page.js b/src/apps/shell/public/page.js index e13c758..891b015 100644 --- a/src/apps/shell/public/page.js +++ b/src/apps/shell/public/page.js @@ -16,7 +16,6 @@ let _keydownHandler = null; let _xtermLoaded = false; let _mountedOnce = false; let _restoring = false; // true during snapshot batch restore — suppresses premature fits -let _navigate = null; // SPA navigate callback from dashboard ctx const panes = new Map(); // id -> pane object const pendingData = new Map(); // id -> string[] — buffers terminal data for panes not yet created @@ -1422,9 +1421,8 @@ export async function mount(container, ctx) { // 3. Get refs const refs = getRefs(container); - // 4. Set initial project + stash navigate callback + // 4. Set initial project activeProject = ctx?.project || null; - _navigate = ctx?.navigate || null; // 5. Load xterm.js dynamically await ensureXterm(); @@ -1557,9 +1555,9 @@ export async function mount(container, ctx) { if (activePaneId) panes.get(activePaneId)?.destroy(); break; } - case 'nav:kanban': { + case 'shell:dashboard': { e.preventDefault(); - if (_navigate) _navigate('kanban'); + setActiveTab(refs, 'grid'); break; } default: { diff --git a/src/packages/shared-assets/keymap-registry.js b/src/packages/shared-assets/keymap-registry.js index 65f1025..38bfd6f 100644 --- a/src/packages/shared-assets/keymap-registry.js +++ b/src/packages/shared-assets/keymap-registry.js @@ -489,16 +489,15 @@ { ctrlOrMeta: true, altKey: true, code: 'KeyK' }, 'Close pane', 'Shell'); + KeymapRegistry.register('shell:dashboard', + { ctrlOrMeta: true, altKey: true, code: 'KeyD' }, + 'Dashboard (grid view)', 'Shell'); + // Voice group KeymapRegistry.register('voice:hold-to-speak', { ctrlOrMeta: true, altKey: true, shiftKey: true }, 'Hold to speak', 'Voice'); - // Navigation group - KeymapRegistry.register('nav:kanban', - { ctrlOrMeta: true, altKey: true, code: 'KeyD' }, - 'Go to Kanban', 'Navigation'); - // Kanban group KeymapRegistry.register('kanban:focus-search', { key: '/' }, diff --git a/src/public/app.js b/src/public/app.js index 64d1c80..a053688 100644 --- a/src/public/app.js +++ b/src/public/app.js @@ -675,16 +675,6 @@ if (typeof VoiceWidget !== 'undefined') { const voiceMountEl = document.getElementById('voice-widget-mount'); if (voiceMountEl) voiceWidget.mount(voiceMountEl); - // Handle global navigation shortcuts (Ctrl+Alt+D → Kanban, etc.) - document.addEventListener('keydown', (e) => { - if (typeof KeymapRegistry === 'undefined') return; - const action = KeymapRegistry.resolve(e); - if (action === 'nav:kanban') { - e.preventDefault(); - selectApp('kanban'); - } - }); - // Handle Ctrl+Alt+Shift hold-to-speak when the shell has focus let voiceKeyActive = false; document.addEventListener('keydown', (e) => {
Ctrl+Alt+DNavigate to Kanban board (from any app)
Ctrl+Alt+DSwitch to Dashboard (grid view) in Shell
Ctrl+Alt+1–9Switch to terminal tab 1–9
Ctrl+Alt+JNew terminal pane
Ctrl+Alt+BNew browser pane