diff --git a/src/web/public/app.js b/src/web/public/app.js
index 0444ae07..908fd8e8 100644
--- a/src/web/public/app.js
+++ b/src/web/public/app.js
@@ -158,6 +158,13 @@ class ClaudemanApp {
// Escape to close modals
if (e.key === 'Escape') {
this.closeCaseSelector();
+ this.closeHelp();
+ }
+
+ // Ctrl/Cmd + ? to show help
+ if ((e.ctrlKey || e.metaKey) && (e.key === '?' || e.key === '/')) {
+ e.preventDefault();
+ this.showHelp();
}
// Ctrl/Cmd + Enter to quick start (when not in terminal)
@@ -726,6 +733,15 @@ class ClaudemanApp {
document.getElementById('caseSelectorModal').classList.remove('active');
}
+ // Help modal
+ showHelp() {
+ document.getElementById('helpModal').classList.add('active');
+ }
+
+ closeHelp() {
+ document.getElementById('helpModal').classList.remove('active');
+ }
+
// Actions
async startRun() {
const prompt = document.getElementById('promptInput').value.trim();
@@ -971,6 +987,29 @@ class ClaudemanApp {
this.terminal.writeln('\x1b[90mTerminal cleared\x1b[0m');
}
+ // Copy terminal contents to clipboard
+ async copyTerminal() {
+ try {
+ // Get all text from terminal
+ const buffer = this.terminal.buffer.active;
+ let text = '';
+ for (let i = 0; i < buffer.length; i++) {
+ const line = buffer.getLine(i);
+ if (line) {
+ text += line.translateToString(true) + '\n';
+ }
+ }
+
+ // Strip trailing empty lines
+ text = text.replace(/\n+$/, '\n');
+
+ await navigator.clipboard.writeText(text);
+ this.showToast('Terminal output copied to clipboard', 'success');
+ } catch (err) {
+ this.showToast('Failed to copy: ' + err.message, 'error');
+ }
+ }
+
// Font size controls
increaseFontSize() {
const current = this.terminal.options.fontSize || 14;
diff --git a/src/web/public/index.html b/src/web/public/index.html
index 1bc903c8..464b5c3d 100644
--- a/src/web/public/index.html
+++ b/src/web/public/index.html
@@ -240,6 +240,7 @@
14px
+
@@ -277,6 +278,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
General
+
+ Ctrl+Enter
+ Quick Start
+
+
+ Ctrl+K
+ Kill all sessions
+
+
+ Ctrl+?
+ Show this help
+
+
+ Escape
+ Close modals
+
+
+
+
Terminal
+
+ Ctrl+L
+ Clear terminal
+
+
+ Ctrl++
+ Increase font size
+
+
+ Ctrl+-
+ Decrease font size
+
+
+
+
Navigation
+
+ Ctrl+1
+ Run tab
+
+
+ Ctrl+2
+ Cases tab
+
+
+ Ctrl+3
+ Settings tab
+
+
+
+
+
+
diff --git a/src/web/public/styles.css b/src/web/public/styles.css
index 1162cc5f..eeb3b480 100644
--- a/src/web/public/styles.css
+++ b/src/web/public/styles.css
@@ -1694,3 +1694,75 @@ input[type="checkbox"] {
align-items: center;
gap: 0.5rem;
}
+
+/* Keyboard Shortcuts Modal */
+.shortcuts-list {
+ display: flex;
+ flex-direction: column;
+ gap: 1.5rem;
+}
+
+.shortcut-group h4 {
+ font-size: 0.75rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: var(--text-muted);
+ margin-bottom: 0.75rem;
+ padding-bottom: 0.5rem;
+ border-bottom: 1px solid var(--border);
+}
+
+.shortcut-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.5rem 0;
+ font-size: 0.875rem;
+}
+
+.shortcut-row span {
+ color: var(--text-dim);
+}
+
+kbd {
+ display: inline-block;
+ padding: 0.25rem 0.5rem;
+ background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ font-family: 'SF Mono', Monaco, monospace;
+ font-size: 0.75rem;
+ color: var(--text);
+ box-shadow: 0 2px 0 var(--border);
+ min-width: 24px;
+ text-align: center;
+}
+
+/* Help button */
+.help-btn {
+ position: fixed;
+ bottom: 1rem;
+ right: 1rem;
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%);
+ border: 1px solid var(--border);
+ color: var(--text-dim);
+ font-size: 1.25rem;
+ cursor: pointer;
+ z-index: 100;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s ease;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
+}
+
+.help-btn:hover {
+ background: linear-gradient(135deg, #3a3a3a 0%, #2a2a2a 100%);
+ color: var(--text);
+ transform: translateY(-2px);
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
+}