From c6197694b53697691f344d5d08144b23ab859ee7 Mon Sep 17 00:00:00 2001 From: josedario87 Date: Fri, 20 Feb 2026 13:32:42 -0600 Subject: [PATCH] feat: Ctrl+1..5 terminal shortcuts and improved AgentBadge indicator - Ctrl+1 through Ctrl+5 switch to open terminals by index - Opens floating window automatically if closed - AgentBadge shows active terminal state dot and index (2/3) - Dropdown items display shortcut numbers for discoverability --- .../components/FloatingTranscriptDebug.vue | 26 ++++++++++--- .../transcript-debug/AgentBadge.vue | 39 +++++++++++++++++-- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/FloatingTranscriptDebug.vue b/frontend/src/components/FloatingTranscriptDebug.vue index 90f9751..18d9d96 100644 --- a/frontend/src/components/FloatingTranscriptDebug.vue +++ b/frontend/src/components/FloatingTranscriptDebug.vue @@ -432,11 +432,25 @@ watch(isOpen, async (open) => { }) // ============================================================================ -// ZOOM KEYBOARD HANDLER +// KEYBOARD SHORTCUTS // ============================================================================ -function handleZoomKey(e: KeyboardEvent) { - if (!isOpen.value || !e.ctrlKey) return +function handleKeydown(e: KeyboardEvent) { + if (!e.ctrlKey) return + + // Ctrl+1..5 → switch to terminal by index + const num = parseInt(e.key) + if (num >= 1 && num <= 5) { + const slot = openTerminals.value[num - 1] + if (!slot) return + e.preventDefault() + if (!isOpen.value) isOpen.value = true + switchToTerminal(slot.sessionId) + return + } + + // Zoom shortcuts (only when open) + if (!isOpen.value) return if (e.key === '+' || e.key === '=') { e.preventDefault() zoom.value = Math.min(2, +(zoom.value + 0.1).toFixed(1)) @@ -453,7 +467,7 @@ function handleZoomKey(e: KeyboardEvent) { onMounted(async () => { checkMobile() window.addEventListener('resize', checkMobile) - document.addEventListener('keydown', handleZoomKey) + document.addEventListener('keydown', handleKeydown) oceanLifeTimer = setInterval(tickOceanLife, 20000) tickOceanLife() await voice.init() @@ -463,7 +477,7 @@ onBeforeUnmount(() => { if (oceanLifeTimer) clearInterval(oceanLifeTimer) disconnectRealtime() voice.cleanup() - document.removeEventListener('keydown', handleZoomKey) + document.removeEventListener('keydown', handleKeydown) document.removeEventListener('mousemove', onDrag) document.removeEventListener('mouseup', stopDrag) document.removeEventListener('mousemove', onResize) @@ -1203,6 +1217,8 @@ onBeforeUnmount(() => { color: rgba(255,255,255,0.85); font-family: 'Courier New', monospace; font-size: 12px; + line-height: 1.5; + field-sizing: content; } /* Send button: pixel art daytime ocean, no border */ diff --git a/frontend/src/components/transcript-debug/AgentBadge.vue b/frontend/src/components/transcript-debug/AgentBadge.vue index 1febfe1..ee53568 100644 --- a/frontend/src/components/transcript-debug/AgentBadge.vue +++ b/frontend/src/components/transcript-debug/AgentBadge.vue @@ -1,14 +1,23 @@