diff --git a/public/index.html b/public/index.html index 9017b09..cf0c798 100644 --- a/public/index.html +++ b/public/index.html @@ -447,6 +447,59 @@ border-top: 1px solid #3a3a3a; } + .stats-widget { + padding: 8px 12px; + background: #1e1e1e; + border-bottom: 1px solid #333; + font-size: 12px; + color: #888; + } + + .stats-line { + display: flex; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 4px; + } + + .stats-line:last-child { + margin-bottom: 0; + } + + .stats-item { + display: flex; + align-items: center; + gap: 4px; + } + + .stats-value { + color: #fff; + font-weight: 500; + } + + .mode-badge { + padding: 2px 6px; + border-radius: 3px; + font-size: 10px; + font-weight: 600; + text-transform: uppercase; + } + + .mode-plan { + background: #7c3aed; + color: white; + } + + .mode-auto { + background: #059669; + color: white; + } + + .model-name { + color: #666; + font-size: 11px; + } + .empty-state { padding: 32px 16px; text-align: center; @@ -471,6 +524,19 @@ border-color: #ff9800; } + .stats-widget { + background: #f5f5f5; + border-bottom-color: #e0e0e0; + } + + .stats-value { + color: #1a1a1a; + } + + .model-name { + color: #999; + } + .session-output { background: #f5f5f5; border-top-color: #e0e0e0; @@ -621,6 +687,15 @@ outputRenderedLength: 0, expanded: false, state: 'ready', + prompts: 0, + completions: 0, + tools: 0, + compressions: 0, + thinking_seconds: 0, + work_seconds: 0, + mode: 'normal', + model: null, + idle_since: null, }); renderSessions(); }); @@ -666,6 +741,23 @@ } }); + es.addEventListener('stats', (e) => { + const data = JSON.parse(e.data); + const session = state.sessions.get(data.session_id); + if (session) { + if (data.prompts !== undefined) session.prompts = data.prompts; + if (data.completions !== undefined) session.completions = data.completions; + if (data.tools !== undefined) session.tools = data.tools; + if (data.compressions !== undefined) session.compressions = data.compressions; + if (data.thinking_seconds !== undefined) session.thinking_seconds = data.thinking_seconds; + if (data.work_seconds !== undefined) session.work_seconds = data.work_seconds; + if (data.mode !== undefined) session.mode = data.mode; + if (data.model !== undefined) session.model = data.model; + if (data.idle_since !== undefined) session.idle_since = data.idle_since; + updateStatsWidget(data.session_id); + } + }); + state.eventSource = es; } @@ -692,6 +784,60 @@ return `${label}`; } + function formatDuration(seconds) { + if (seconds < 60) return `${seconds}s`; + if (seconds < 3600) return `${Math.floor(seconds / 60)}m`; + return `${Math.floor(seconds / 3600)}h`; + } + + function renderStatsWidget(session) { + const lines = []; + + // Counts line + const counts = []; + if (session.prompts > 0) counts.push(`${session.prompts} prompts`); + if (session.completions > 0) counts.push(`${session.completions} completions`); + if (session.tools > 0) counts.push(`${session.tools} tools`); + if (session.compressions > 0) counts.push(`${session.compressions} compressions`); + + if (counts.length > 0) { + lines.push(`