/** * Pure status helpers for the session UI — NO React, NO realtime, NO xterm imports, * so they're trivially unit-testable and safe to pull anywhere. */ import type { TerminalStatus } from '../terminal/themes' import type { SessionStatusKind, SessionSummary } from './types' /** Visual tokens for a resolved session status. */ export interface SessionStatusVisual { kind: SessionStatusKind label: string /** Tailwind-token classes for the badge pill (light + dark friendly). */ className: string /** Tailwind-token colour class for a status icon/text. */ toneClassName: string } const DEFAULT_LABELS: Record = { active: 'Active', success: 'Success', error: 'Error', warning: 'Needs review', idle: 'Idle', completed: 'Completed', } const KIND_CLASSES: Record = { active: 'bg-primary/15 text-primary border border-primary/30', success: 'bg-emerald-500/15 text-emerald-600 dark:text-emerald-400 border border-emerald-500/30', error: 'bg-red-500/15 text-red-600 dark:text-red-400 border border-red-500/30', warning: 'bg-amber-500/15 text-amber-600 dark:text-amber-400 border border-amber-500/30', idle: 'bg-muted text-muted-foreground border border-border', completed: 'bg-muted text-muted-foreground border border-border', } const KIND_TONE: Record = { active: 'text-primary', success: 'text-emerald-600 dark:text-emerald-400', error: 'text-red-600 dark:text-red-400', warning: 'text-amber-600 dark:text-amber-400', idle: 'text-muted-foreground', completed: 'text-muted-foreground', } /** * Resolve the effective status of a session view-model. Prefers an explicit * `status`; otherwise derives `active`/`idle` from `isActive`. */ export function resolveSessionStatus( session: Pick, ): SessionStatusVisual { const kind: SessionStatusKind = session.status ?? (session.isActive ? 'active' : 'idle') return { kind, label: session.statusLabel ?? DEFAULT_LABELS[kind], className: KIND_CLASSES[kind], toneClassName: KIND_TONE[kind], } } /** * The connection states an `AgentSocket` reports (mirrors `@startsimpli/realtime`'s * `AgentSocketStatus`). Redefined locally so this module stays realtime-free. */ export type AgentConnectionStatus = 'idle' | 'connecting' | 'open' | 'reconnecting' | 'closed' /** Map an agent socket status onto the terminal chrome's `TerminalStatus`. */ export function mapSocketStatus(status: AgentConnectionStatus): TerminalStatus { switch (status) { case 'open': return 'connected' case 'connecting': case 'reconnecting': return 'connecting' case 'idle': case 'closed': default: return 'disconnected' } }