Add state badges to session card headers

This commit is contained in:
Jared Miller 2026-01-28 13:52:01 -05:00
parent a93475f3ab
commit 298faecf72
Signed by: shmup
GPG key ID: 22B5C6D66A38B06C

View file

@ -100,6 +100,60 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
align-items: center;
gap: 8px;
}
.state-badge {
padding: 2px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
flex-shrink: 0;
}
.state-ready {
background: #6b7280;
color: white;
}
.state-thinking {
background: #3b82f6;
color: white;
}
.state-thinking::after {
content: '...';
animation: dots 1.5s infinite;
}
@keyframes dots {
0%, 20% { content: '.'; }
40% { content: '..'; }
60%, 100% { content: '...'; }
}
.state-permission {
background: #f59e0b;
color: white;
}
.state-question {
background: #f59e0b;
color: white;
}
.state-complete {
background: #10b981;
color: white;
}
.state-interrupted {
background: #ef4444;
color: white;
}
.session-cwd {
@ -566,6 +620,7 @@
output: '',
outputRenderedLength: 0,
expanded: false,
state: 'ready',
});
renderSessions();
});
@ -602,6 +657,15 @@
renderPrompts();
});
es.addEventListener('state', (e) => {
const data = JSON.parse(e.data);
const session = state.sessions.get(data.session_id);
if (session) {
session.state = data.state;
updateSessionCard(data.session_id);
}
});
state.eventSource = es;
}
@ -615,6 +679,19 @@
}
};
function renderStateBadge(sessionState) {
const labels = {
ready: 'Ready',
thinking: 'Thinking',
permission: 'Permission Required',
question: 'Question',
complete: 'Complete',
interrupted: 'Interrupted'
};
const label = labels[sessionState] || sessionState;
return `<span class="state-badge state-${sessionState}">${label}</span>`;
}
function renderSessions() {
if (state.sessions.size === 0) {
$sessions.innerHTML = '<div class="empty-state">No active sessions</div>';
@ -625,7 +702,10 @@
<div class="session ${s.expanded ? 'expanded' : ''}" data-session="${s.id}">
<div class="session-header" onclick="toggleSession('${s.id}')">
<div class="session-info">
<div class="session-command">${escapeHtml(s.command || 'claude')}</div>
<div class="session-command">
<span>${escapeHtml(s.command || 'claude')}</span>
${renderStateBadge(s.state || 'ready')}
</div>
<div class="session-cwd">${escapeHtml(s.cwd || '~')}</div>
</div>
<div class="session-toggle"></div>
@ -655,6 +735,22 @@
}
}
function updateSessionCard(sessionId) {
const session = state.sessions.get(sessionId);
if (!session) return;
const $sessionCard = document.querySelector(`[data-session="${sessionId}"]`);
if ($sessionCard) {
const $commandDiv = $sessionCard.querySelector('.session-command');
if ($commandDiv) {
$commandDiv.innerHTML = `
<span>${escapeHtml(session.command || 'claude')}</span>
${renderStateBadge(session.state || 'ready')}
`;
}
}
}
function renderPrompts() {
if (state.prompts.size === 0) {
$prompts.innerHTML = '<div class="empty-state">No pending prompts</div>';