Files
Codeman/src/web/public/index.html
T
arkonandClaude Opus 4.5 363b6d1147 refactor: UI cleanup - move respawn controls, remove mode label, fix dir width
- Move respawn controls from toolbar to session options modal
- Remove unnecessary Mode label from session options (visible in tab)
- Increase directory input width from 200px to 350px
- Add RTL direction to directory display to show end of long paths
- Add respawn status indicator with stop/configure buttons in modal

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 02:06:37 +01:00

282 lines
12 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Claude Code session manager with web interface">
<meta name="theme-color" content="#0a0a0a">
<title>Claudeman</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%2360a5fa'/%3E%3Cstop offset='100%25' stop-color='%233b82f6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='32' height='32' rx='6' fill='%230a0a0a'/%3E%3Cpath d='M18 4L8 18h6l-2 10 10-14h-6z' fill='url(%23g)'/%3E%3C/svg%3E">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.css">
<script src="https://cdn.jsdelivr.net/npm/xterm@5.3.0/lib/xterm.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.min.js"></script>
</head>
<body>
<div class="app">
<!-- Compact Header with Session Tabs -->
<header class="header">
<div class="header-brand">
<span class="logo">Claudeman</span>
</div>
<!-- Session Tabs -->
<div class="session-tabs" id="sessionTabs">
<div class="session-tab new-tab" onclick="app.createNewSession()" title="New Session (Ctrl+N)">
<span>+</span>
</div>
</div>
<div class="header-right">
<div class="connection-status" id="connectionStatus">
<span class="status-dot"></span>
<span class="status-text">Connecting</span>
</div>
<div class="header-tokens" id="headerTokens" title="Total tokens across all sessions">0 tokens</div>
</div>
</header>
<!-- Timer Banner (shown when timed run is active) -->
<div class="timer-banner" id="timerBanner" style="display: none;">
<div class="timer-content">
<span class="timer-value" id="timerValue">00:00:00</span>
<div class="timer-progress"><div class="timer-progress-fill" id="timerProgress"></div></div>
<span class="timer-meta" id="timerMeta">0 tasks | $0.00</span>
</div>
<button class="btn-icon-only" onclick="app.stopCurrentRun()" title="Stop">&#x25A0;</button>
</div>
<!-- Respawn Banner -->
<div class="respawn-banner" id="respawnBanner" style="display: none;">
<span class="respawn-indicator">&#x21BB;</span>
<span class="respawn-state" id="respawnState">Watching</span>
<span class="respawn-cycles">Cycle <span id="respawnCycleCount">0</span></span>
<span class="respawn-timer" id="respawnTimer" style="display: none;"></span>
<span class="respawn-tokens" id="respawnTokens" style="display: none;"></span>
<span class="respawn-step" id="respawnStep"></span>
<button class="btn-icon-only" onclick="app.stopRespawn()" title="Stop Respawn">&#x25A0;</button>
</div>
<!-- Main Terminal Area -->
<main class="main">
<div class="terminal-container" id="terminalContainer"></div>
</main>
<!-- Bottom Toolbar -->
<footer class="toolbar">
<div class="toolbar-left">
<!-- Run Claude -->
<div class="toolbar-group">
<button class="btn-toolbar btn-primary" onclick="app.runClaude()" title="Run Claude (Ctrl+Enter)">
Run Claude
</button>
<button class="btn-toolbar" onclick="app.runShell()" title="Run Shell">
Shell
</button>
<select id="quickStartCase" class="toolbar-select" title="Select case">
<option value="testcase">testcase</option>
</select>
</div>
<!-- Directory -->
<div class="toolbar-group">
<button class="btn-toolbar" onclick="app.toggleDirInput()" title="Set working directory">
<span id="dirDisplay">No directory</span>
</button>
<input type="text" id="dirInput" class="toolbar-input hidden" placeholder="Working directory..." onblur="app.hideDirInput()">
</div>
</div>
<div class="toolbar-right">
<!-- Font Controls -->
<button class="btn-toolbar btn-sm" onclick="app.decreaseFontSize()" title="Decrease font (Ctrl+-)">A-</button>
<span class="font-size-display" id="fontSizeDisplay">14</span>
<button class="btn-toolbar btn-sm" onclick="app.increaseFontSize()" title="Increase font (Ctrl++)">A+</button>
<div class="toolbar-divider"></div>
<button class="btn-toolbar" onclick="app.copyTerminal()" title="Copy terminal">Copy</button>
<button class="btn-toolbar" onclick="app.clearTerminal()" title="Clear terminal (Ctrl+L)">Clear</button>
<div class="toolbar-divider"></div>
<button class="btn-toolbar btn-danger" onclick="app.killActiveSession()" title="Kill current session">Kill</button>
</div>
</footer>
<!-- Respawn Settings Panel (slide-up) -->
<div class="respawn-panel" id="respawnPanel">
<div class="respawn-panel-header">
<span>Respawn Settings</span>
<button class="btn-close" onclick="app.toggleRespawnPanel()">&times;</button>
</div>
<div class="respawn-panel-body">
<div class="form-row">
<label>Update Prompt</label>
<input type="text" id="respawnPrompt" value="update all the docs and CLAUDE.md" placeholder="Prompt to send when idle">
</div>
<div class="form-row-inline">
<div class="form-col">
<label>Idle Timeout</label>
<div class="input-suffix">
<input type="number" id="respawnIdleTimeout" value="5" min="1" max="60">
<span>sec</span>
</div>
</div>
<div class="form-col">
<label>Step Delay</label>
<div class="input-suffix">
<input type="number" id="respawnStepDelay" value="1" min="0" max="10">
<span>sec</span>
</div>
</div>
</div>
<div class="form-row">
<label>Run Duration (optional)</label>
<div class="input-suffix">
<input type="number" id="respawnDuration" value="" min="1" placeholder="No limit">
<span>min</span>
</div>
<span class="form-hint">Leave empty for unlimited. Respawn stops after duration.</span>
</div>
<div class="form-row">
<label>After Update Prompt:</label>
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" id="respawnSendClear" checked>
<span>Send /clear</span>
<span class="checkbox-hint">Clear conversation context</span>
</label>
<label class="checkbox-label">
<input type="checkbox" id="respawnSendInit" checked>
<span>Send /init</span>
<span class="checkbox-hint">Reinitialize session</span>
</label>
</div>
</div>
<div class="form-row">
<label>Auto-Clear Context</label>
<div class="checkbox-group">
<label class="checkbox-label">
<input type="checkbox" id="autoClearEnabled">
<span>Enable Auto-Clear</span>
<span class="checkbox-hint">Clear at token threshold</span>
</label>
</div>
<div class="input-suffix" style="margin-top: 0.5rem;">
<input type="number" id="autoClearThreshold" value="100000" min="10000" max="500000" step="10000">
<span>tokens</span>
</div>
</div>
<div class="form-actions">
<button class="btn-toolbar" onclick="app.toggleRespawnPanel()">Cancel</button>
<button class="btn-toolbar btn-success" onclick="app.enableRespawnOnCurrent()" id="enableOnCurrentBtn" style="display: none;">Enable on Current</button>
<button class="btn-toolbar btn-primary" onclick="app.startInteractiveWithRespawn()">Start New + Respawn</button>
</div>
</div>
</div>
<!-- New Session Panel (slide-up) -->
<div class="new-session-panel" id="newSessionPanel">
<div class="respawn-panel-header">
<span>New Session</span>
<button class="btn-close" onclick="app.hideNewSessionPanel()">&times;</button>
</div>
<div class="respawn-panel-body">
<div class="form-row">
<label>Case / Project</label>
<select id="newSessionCase" class="form-select">
<option value="testcase">testcase (default)</option>
</select>
</div>
<div class="form-row">
<label>Or specify directory</label>
<input type="text" id="newSessionDir" placeholder="~/projects/my-project">
</div>
<div class="form-actions">
<button class="btn-toolbar" onclick="app.hideNewSessionPanel()">Cancel</button>
<button class="btn-toolbar btn-success" onclick="app.createSessionFromPanel()">Create Session</button>
</div>
</div>
</div>
<!-- Help Modal -->
<div class="modal" id="helpModal">
<div class="modal-backdrop" onclick="app.closeHelp()"></div>
<div class="modal-content">
<div class="modal-header">
<h3>Keyboard Shortcuts</h3>
<button class="modal-close" onclick="app.closeHelp()">&times;</button>
</div>
<div class="modal-body">
<div class="shortcuts-grid">
<div><kbd>Ctrl</kbd>+<kbd>Enter</kbd></div><div>Run Claude</div>
<div><kbd>Ctrl</kbd>+<kbd>N</kbd></div><div>New Session</div>
<div><kbd>Ctrl</kbd>+<kbd>W</kbd></div><div>Close Session</div>
<div><kbd>Ctrl</kbd>+<kbd>Tab</kbd></div><div>Next Session</div>
<div><kbd>Ctrl</kbd>+<kbd>K</kbd></div><div>Kill All Sessions</div>
<div><kbd>Ctrl</kbd>+<kbd>L</kbd></div><div>Clear Terminal</div>
<div><kbd>Ctrl</kbd>+<kbd>+</kbd></div><div>Increase Font</div>
<div><kbd>Ctrl</kbd>+<kbd>-</kbd></div><div>Decrease Font</div>
<div><kbd>Ctrl</kbd>+<kbd>?</kbd></div><div>Show Help</div>
<div><kbd>Escape</kbd></div><div>Close Panels</div>
</div>
</div>
</div>
</div>
<!-- Task Tree Panel (slide-up) -->
<div class="task-panel" id="taskPanel">
<div class="task-panel-header">
<span>Background Tasks</span>
<div class="task-panel-stats" id="taskPanelStats">0 running</div>
<button class="btn-close" onclick="app.toggleTaskPanel()">&times;</button>
</div>
<div class="task-panel-body" id="taskPanelBody">
<div class="task-empty">No background tasks</div>
</div>
</div>
<!-- Session Options Modal -->
<div class="modal" id="sessionOptionsModal">
<div class="modal-backdrop" onclick="app.closeSessionOptions()"></div>
<div class="modal-content modal-sm">
<div class="modal-header">
<h3>Session Options</h3>
<button class="modal-close" onclick="app.closeSessionOptions()">&times;</button>
</div>
<div class="modal-body">
<div class="form-row">
<label>Session Name</label>
<input type="text" id="sessionNameInput" placeholder="Enter session name...">
</div>
<div class="form-row">
<label>Directory</label>
<div class="session-dir-display" id="sessionDirDisplay">/path/to/dir</div>
</div>
<div class="form-row session-respawn-section" id="sessionRespawnSection">
<label>Respawn Controller</label>
<div class="session-respawn-status" id="sessionRespawnStatus">
<span class="respawn-status-text">Not active</span>
</div>
<div class="session-respawn-actions">
<button class="btn-toolbar btn-sm" onclick="app.toggleRespawnPanel(); app.closeSessionOptions();" id="sessionConfigRespawnBtn">Configure Respawn</button>
<button class="btn-toolbar btn-sm btn-danger" onclick="app.stopRespawnFromOptions()" id="sessionStopRespawnBtn" style="display: none;">Stop Respawn</button>
</div>
</div>
</div>
<div class="form-actions">
<button class="btn-toolbar" onclick="app.closeSessionOptions()">Cancel</button>
<button class="btn-toolbar btn-primary" onclick="app.saveSessionOptions()">Save</button>
</div>
</div>
</div>
<!-- Help Button -->
<button class="help-btn" onclick="app.showHelp()" title="Keyboard shortcuts (Ctrl+?)">?</button>
</div>
<script src="app.js"></script>
</body>
</html>