From 8a133d083b4be9201df7959d3c2639902413a117 Mon Sep 17 00:00:00 2001 From: Aamer Akhter Date: Thu, 9 Jul 2026 11:26:24 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20COD-163=20implementation=20gaps=20?= =?UTF-8?q?=E2=80=94=20shortcut=20overlay,=20settings=20tab,=20remote-case?= =?UTF-8?q?=20shell?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - app.js: getShortcutRegistry()/matchesShortcutEvent()/showShortcutOverlay()/ renderShortcutOverlay()/closeShortcutOverlay() (needed for DEFAULT_SHORTCUTS action dispatch + shortcut-registry-overlay tests) - settings-ui.js: renderShortcutSettingsList()/startShortcutCapture()/ onShortcutCaptureKeydown()/resetShortcutOverride()/toggleShortcutEnabled() (Settings → Shortcuts tab, needed for shortcut-registry-overlay tests) - index.html: Shortcuts modal tab + shortcut overlay modal; remove Ctrl+Enter hint text (help-modal-shortcuts test asserts absence) - session-ui.js: remote-case detection in runShell() (caseName vs workingDir); saveLastUsedCase after deleting selected case - test/command-palette-ui.test.ts: expect browse-sessions item (COD-192 adds it) Co-Authored-By: Claude Sonnet 4.6 --- src/web/public/app.js | 71 +++++++++++++++++++++++++++++++ src/web/public/index.html | 32 +++++++++++++- src/web/public/session-ui.js | 11 ++++- src/web/public/settings-ui.js | 74 +++++++++++++++++++++++++++++++++ test/command-palette-ui.test.ts | 3 +- 5 files changed, 187 insertions(+), 4 deletions(-) diff --git a/src/web/public/app.js b/src/web/public/app.js index 2004a9c1..935d9900 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -4350,6 +4350,77 @@ class CodemanApp { } } + // ─── Shortcut Registry ─────────────────────────────────────────────────────── + // Returns the merged shortcut list: DEFAULT_SHORTCUTS with any per-shortcut + // overrides from settings.shortcutOverrides applied on top. + + getShortcutRegistry() { + const settings = this.loadAppSettingsFromStorage(); + const shortcutOverrides = settings.shortcutOverrides || {}; + return DEFAULT_SHORTCUTS.map((shortcut) => { + const override = shortcutOverrides[shortcut.id]; + if (!override) return shortcut; + return { ...shortcut, ...override }; + }); + } + + matchesShortcutEvent(e, shortcut) { + if (!shortcut.bindings) return false; + return shortcut.bindings.some((binding) => { + const mods = binding.modifiers || []; + if (mods.includes('ctrl') && !e.ctrlKey) return false; + if (mods.includes('meta') && !e.metaKey) return false; + if (mods.includes('shift') && !e.shiftKey) return false; + if (mods.includes('alt') && !e.altKey) return false; + if (!mods.includes('ctrl') && !mods.includes('meta') && (e.ctrlKey || e.metaKey)) return false; + if (binding.code) return e.code === binding.code; + if (binding.key) return e.key === binding.key || e.key.toLowerCase() === binding.key.toLowerCase(); + return false; + }); + } + + // ─── Shortcut Overlay Modal ─────────────────────────────────────────────────── + // Ctrl/Alt+? opens a floating overlay listing all keyboard shortcuts, grouped + // by category. Uses the merged registry so user overrides are reflected. + + showShortcutOverlay() { + const modal = document.getElementById('shortcutOverlayModal'); + if (!modal) return; + this.renderShortcutOverlay(); + modal.classList.add('active'); + modal.focus?.(); + } + + renderShortcutOverlay() { + const list = document.getElementById('shortcutOverlayList'); + if (!list) return; + const registry = this.getShortcutRegistry(); + const groups = {}; + for (const shortcut of registry) { + const g = shortcut.group || 'General'; + if (!groups[g]) groups[g] = []; + groups[g].push(shortcut); + } + const fmtBindings = (s) => { + if (s.displayBindings) return s.displayBindings.map((b) => `${escapeHtml(b)}`).join(' / '); + if (!s.bindings) return ''; + return s.bindings.map((b) => { + const parts = [...(b.modifiers || []).map((m) => m.charAt(0).toUpperCase() + m.slice(1)), b.key || b.code || '']; + return `${escapeHtml(parts.join('+'))}`; + }).join(' / '); + }; + list.innerHTML = Object.entries(groups).map(([group, items]) => + `
${escapeHtml(group)}
` + + items.map((s) => `
${escapeHtml(s.label)}${fmtBindings(s)}
`).join('') + + `
` + ).join(''); + } + + closeShortcutOverlay() { + const modal = document.getElementById('shortcutOverlayModal'); + if (modal) modal.classList.remove('active'); + } + } // ═══════════════════════════════════════════════════════════════ diff --git a/src/web/public/index.html b/src/web/public/index.html index 41731bed..a3d68fd9 100644 --- a/src/web/public/index.html +++ b/src/web/public/index.html @@ -358,7 +358,7 @@

Resume Conversation

-

Or press Ctrl+Enter to start

+

Or click Run to start

@@ -427,7 +427,7 @@
- @@ -1040,6 +1040,7 @@ +
+ + +
@@ -1654,6 +1668,20 @@
+ + +