diff --git a/server/src/web/routes/sessions.ts b/server/src/web/routes/sessions.ts index b03bda01..0502194b 100644 --- a/server/src/web/routes/sessions.ts +++ b/server/src/web/routes/sessions.ts @@ -8,15 +8,18 @@ type SessionSummaryMetadata = { name?: string path: string summary?: { text: string } + flavor?: string | null } type SessionSummary = { id: string active: boolean + activeAt: number updatedAt: number metadata: SessionSummaryMetadata | null todoProgress: { completed: number; total: number } | null pendingRequestsCount: number + modelMode?: 'default' | 'sonnet' | 'opus' | null } function toSessionSummary(session: Session): SessionSummary { @@ -25,7 +28,8 @@ function toSessionSummary(session: Session): SessionSummary { const metadata: SessionSummaryMetadata | null = session.metadata ? { name: session.metadata.name, path: session.metadata.path, - summary: session.metadata.summary ? { text: session.metadata.summary.text } : undefined + summary: session.metadata.summary ? { text: session.metadata.summary.text } : undefined, + flavor: session.metadata.flavor ?? null } : null const todoProgress = session.todos?.length ? { @@ -36,10 +40,12 @@ function toSessionSummary(session: Session): SessionSummary { return { id: session.id, active: session.active, + activeAt: session.activeAt, updatedAt: session.updatedAt, metadata, todoProgress, - pendingRequestsCount + pendingRequestsCount, + modelMode: session.modelMode ?? null } } diff --git a/web/src/components/SessionList.tsx b/web/src/components/SessionList.tsx index 1ee38413..561b7476 100644 --- a/web/src/components/SessionList.tsx +++ b/web/src/components/SessionList.tsx @@ -1,5 +1,3 @@ -import { Badge } from '@/components/ui/badge' -import { Card, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import type { SessionSummary } from '@/types/api' function PlusIcon(props: { className?: string }) { @@ -63,6 +61,37 @@ function getTodoProgress(session: SessionSummary): { completed: number; total: n return session.todoProgress } +function getAgentLabel(session: SessionSummary): string { + const flavor = session.metadata?.flavor?.trim() + if (flavor) return flavor + return 'unknown' +} + +function getModelLabel(session: SessionSummary): string { + return session.modelMode ?? 'default' +} + +function formatRelativeTime(value: number): string | null { + const ms = value < 1_000_000_000_000 ? value * 1000 : value + if (!Number.isFinite(ms)) return null + const delta = Date.now() - ms + if (delta < 60_000) return 'just now' + const minutes = Math.floor(delta / 60_000) + if (minutes < 60) return `${minutes}m ago` + const hours = Math.floor(minutes / 60) + if (hours < 24) return `${hours}h ago` + const days = Math.floor(hours / 24) + if (days < 7) return `${days}d ago` + return new Date(ms).toLocaleDateString() +} + +function getLastSeenLabel(session: SessionSummary): string | null { + if (session.active) return null + const lastSeen = formatRelativeTime(session.activeAt ?? session.updatedAt) + if (!lastSeen) return null + return `last seen ${lastSeen}` +} + export function SessionList(props: { sessions: SessionSummary[] onSelect: (sessionId: string) => void @@ -71,54 +100,70 @@ export function SessionList(props: { isLoading: boolean }) { return ( -