diff --git a/src/web/public/app.js b/src/web/public/app.js index a2de1649..5908d285 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -251,6 +251,23 @@ const _SSE_HANDLER_MAP = [ [SSE_EVENTS.ORCHESTRATOR_ERROR, '_onOrchestratorError'], ]; + +// ═══════════════════════════════════════════════════════════════ +// Session Name Prefix Parser +// ═══════════════════════════════════════════════════════════════ +// Parses w- or s- prefix from session names. +// Returns { prefix, suffix } or null if name does not match the pattern. +function parseSessionPrefix(name) { + if (!name) return null; + const m = name.match(/^(w\d+-[a-zA-Z0-9_-]+|s\d+-[a-zA-Z0-9_-]+)/); + if (!m) return null; + const prefix = m[1]; + const rest = name.slice(prefix.length); + if (rest === "") return { prefix, suffix: "" }; + if (rest.startsWith(": ")) return { prefix, suffix: rest.slice(2) }; + return null; +} + // ═══════════════════════════════════════════════════════════════ // CodemanApp Class — constructor and global state // ═══════════════════════════════════════════════════════════════ @@ -615,10 +632,8 @@ class CodemanApp { // shift? (require Shift), action }. const SHORTCUTS = [ { key: '?', altKey: '/', ctrl: true, action: () => this.showHelp() }, - { key: 'Enter', ctrl: true, action: () => this.quickStart() }, { key: 'w', ctrl: true, action: () => this.killActiveSession() }, { key: 'Tab', ctrl: true, action: () => this.nextSession() }, - { key: 'k', ctrl: true, action: () => this.killAllSessions() }, { key: 'l', ctrl: true, action: () => this.clearTerminal() }, { key: 'R', ctrl: true, shift: true, action: () => this.restoreTerminalSize() }, { key: '=', altKey: '+', ctrl: true, action: () => this.increaseFontSize() }, @@ -637,6 +652,16 @@ class CodemanApp { this.closeHelp(); } + // Alt+1-9: switch to Codeman session by index + if (e.altKey && !e.ctrlKey && !e.shiftKey && e.key >= '1' && e.key <= '9') { + const idx = parseInt(e.key) - 1; + if (idx < this.sessionOrder.length) { + e.preventDefault(); + this.selectSession(this.sessionOrder[idx]); + } + return; + } + // Match against shortcut table for (const s of SHORTCUTS) { const keyMatch = e.key === s.key || (s.altKey && e.key === s.altKey); @@ -1712,7 +1737,12 @@ class CodemanApp { // Update name if changed const nameEl = tab.querySelector('.tab-name'); if (nameEl && nameEl.textContent !== name) { - nameEl.textContent = name; + const _p = parseSessionPrefix(name); + if (_p && _p.suffix) { + nameEl.innerHTML = '' + escapeHtml(_p.prefix) + ': ' + escapeHtml(_p.suffix) + ''; + } else { + nameEl.textContent = name; + } } // Update task badge @@ -1820,7 +1850,7 @@ class CodemanApp { ${mode === 'shell' ? '' : mode === 'opencode' ? '' : ''} - ${escapeHtml(name)} + ${(() => { const p = parseSessionPrefix(name); return p && p.suffix ? '' + escapeHtml(p.prefix) + ': ' + escapeHtml(p.suffix) + '' : escapeHtml(name); })()} ${showFolder ? `\u{1F4C1} ${escapeHtml(folderName)}` : ''} diff --git a/src/web/public/index.html b/src/web/public/index.html index b9df9fab..50daf7c7 100644 --- a/src/web/public/index.html +++ b/src/web/public/index.html @@ -477,10 +477,9 @@