@workerdeck/ui 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { $ as isMutatingTool, A as PERMISSION_MODES, At as MenuItem, B as Composer, Bt as Input, C as TerminalPermissionPrompt, Ct as DialogClose, D as SubagentStrip, Dt as DialogTrigger, E as parseUserQuestions, Et as DialogRow, F as SkillsDialog, Ft as SelectItem, G as previewPatch, Gt as cn, H as TerminalSurface, Ht as badgeVariants, I as McpDialog, It as SelectItemText, J as Ink, K as Band, L as HostFilesDialog, Lt as SelectTrigger, M as permissionModeChoices, Mt as MenuTrigger, N as permissionModeMeta, Nt as Select, O as PermissionPrompt, Ot as Menu, P as ModelSelect, Pt as SelectContent, Q as useAffordances, Rt as SelectValue, S as TerminalQuestionPrompt, St as DialogBody, T as QuestionPrompt, Tt as DialogHeader, U as TerminalMarkdown, Ut as Button, V as skillPrompt, Vt as Badge, W as TerminalDiff, Wt as buttonVariants, X as CopyAction, Y as Row, Z as WithActions, _ as ConversationContent, _t as copyText, a as Transcript, at as commandTrigger, b as STATUS_META, bt as TooltipProvider, c as PromptTokenText, ct as usePromptAreaState, d as FileCard, dt as segmentsToPlainText, et as toolIcon, f as TerminalItemView, ft as ProgressRing, g as Conversation, gt as CopyButton, h as Loader, ht as Spinner, i as useMinuteClock, it as useTranscriptVariant, j as PermissionModeSelect, jt as MenuSeparator, k as Response, kt as MenuContent, l as Message, lt as PromptArea, m as SessionEmptyState, mt as CodeBlock, n as UsageDialog, nt as TranscriptVariantProvider, o as ToolCallCard, ot as hashtagTrigger, p as TerminalTranscript, pt as Splitter, q as Blank, r as UsageMeters, rt as useTranscriptDensity, s as Reasoning, st as mentionTrigger, t as SessionPanel, tt as TranscriptDensityProvider, u as MessageContent, ut as plainTextToSegments, v as ConversationScrollButton, vt as Tip, w as QUESTION_BEHAVIORS, wt as DialogContent, x as SessionInfoDialog, xt as Dialog, y as StatusBar, yt as TooltipContent, z as ContextDialog, zt as PortalScope } from "./SessionPanel-DDgBkHsi.mjs";
2
- import { S as toolInputPreview, _ as formatRateLimitWindowLong, b as friendlyModel, c as tightestWindow, d as formatAgoPrecise, f as formatBytes, g as formatRateLimitWindow, h as formatDuration, i as meterSeverity, m as formatCountdown, o as modelLabel, p as formatCost, r as meterColorClass, s as statusPresentation, t as contextSeverity, u as windowLabel, v as formatRelativeTime, x as rateLimitWindowSeconds, y as formatTokens } from "./status-C0HSLZas.mjs";
1
+ import { $ as isMutatingTool, A as PERMISSION_MODES, At as MenuItem, B as Composer, Bt as Input, C as TerminalPermissionPrompt, Ct as DialogClose, D as SubagentStrip, Dt as DialogTrigger, E as parseUserQuestions, Et as DialogRow, F as SkillsDialog, Ft as SelectItem, G as previewPatch, Gt as cn, H as TerminalSurface, Ht as badgeVariants, I as McpDialog, It as SelectItemText, J as Ink, K as Band, L as HostFilesDialog, Lt as SelectTrigger, M as permissionModeChoices, Mt as MenuTrigger, N as permissionModeMeta, Nt as Select, O as PermissionPrompt, Ot as Menu, P as ModelSelect, Pt as SelectContent, Q as useAffordances, Rt as SelectValue, S as TerminalQuestionPrompt, St as DialogBody, T as QuestionPrompt, Tt as DialogHeader, U as TerminalMarkdown, Ut as Button, V as skillPrompt, Vt as Badge, W as TerminalDiff, Wt as buttonVariants, X as CopyAction, Y as Row, Z as WithActions, _ as ConversationContent, _t as copyText, a as Transcript, at as commandTrigger, b as STATUS_META, bt as TooltipProvider, c as PromptTokenText, ct as usePromptAreaState, d as FileCard, dt as segmentsToPlainText, et as toolIcon, f as TerminalItemView, ft as ProgressRing, g as Conversation, gt as CopyButton, h as Loader, ht as Spinner, i as useMinuteClock, it as useTranscriptVariant, j as PermissionModeSelect, jt as MenuSeparator, k as Response, kt as MenuContent, l as Message, lt as PromptArea, m as SessionEmptyState, mt as CodeBlock, n as UsageDialog, nt as TranscriptVariantProvider, o as ToolCallCard, ot as hashtagTrigger, p as TerminalTranscript, pt as Splitter, q as Blank, r as UsageMeters, rt as useTranscriptDensity, s as Reasoning, st as mentionTrigger, t as SessionPanel, tt as TranscriptDensityProvider, u as MessageContent, ut as plainTextToSegments, v as ConversationScrollButton, vt as Tip, w as QUESTION_BEHAVIORS, wt as DialogContent, x as SessionInfoDialog, xt as Dialog, y as StatusBar, yt as TooltipContent, z as ContextDialog, zt as PortalScope } from "./SessionPanel-DVhnUwXw.mjs";
2
+ import { C as toolInputPreview, S as rateLimitWindowSeconds, _ as formatRateLimitWindow, b as formatTokens, c as tightestWindow, f as formatAgoPrecise, g as formatDuration, h as formatCountdown, i as meterSeverity, m as formatCost, o as modelLabel, p as formatBytes, r as meterColorClass, s as statusPresentation, t as contextSeverity, u as windowLabel, v as formatRateLimitWindowLong, x as friendlyModel, y as formatRelativeTime } from "./status-BW2xj79g.mjs";
3
3
  import { Fragment, forwardRef, useEffect, useMemo, useRef, useState } from "react";
4
4
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { Anchor, ArrowRight, Atom, Beaker, BellRing, Bike, Binary, Blocks, Bot, Box, Brain, Briefcase, Brush, Bug, Building2, Cable, Camera, Car, Cat, Check, ChevronDown, ChevronRight, CircleAlert, CircleSlash, CircuitBoard, Cloud, Code, Coffee, Cog, Compass, Container, Cpu, CreditCard, Database, Diamond, Dog, Dot, Eraser, Feather, Film, Flame, FlaskConical, Folder, Gamepad2, Gauge, Gem, Ghost, Gift, GitBranch, Globe, GraduationCap, Hammer, Hexagon, House, Image, Key, Landmark, Laptop, Layers, Leaf, Library, Lightbulb, Lock, Mail, Map as Map$1, MessageCircle, Mic, Monitor, Moon, Mountain, Music, Network, Newspaper, Notebook, Orbit, Package, Palette, PauseCircle, PenTool, Pencil, Phone, PiggyBank, Plane, Plug, Puzzle, Radar, Radio, Receipt, Rocket, Ruler, Satellite, Scale, Scissors, Search, SearchX, Server, Shield, Ship, ShoppingCart, Signal, Smartphone, Sparkles, Sprout, Square, Star, Sun, Table, Tag, Target, Telescope, Terminal, TestTube, Trash2, TreePine, Trophy, Truck, Umbrella, Users, Wallet, Wand, Waves, Webhook, Wifi, Wrench, X, Zap } from "lucide-react";
@@ -399,7 +399,8 @@ function ProjectIcon({ icon, src, name, className }) {
399
399
  className: cn("inline-block size-3 shrink-0 object-contain", className)
400
400
  });
401
401
  }
402
- return /* @__PURE__ */ jsx(GLYPHS[icon.name] ?? Folder, { className: cn("inline-block size-3 shrink-0", className) });
402
+ const Glyph = GLYPHS[icon.name] ?? Folder;
403
+ return /* @__PURE__ */ jsx(Glyph, { className: cn("inline-block size-3 shrink-0", className) });
403
404
  }
404
405
  //#endregion
405
406
  //#region src/components/agent/ContextRing.tsx
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["AlertDialogPrimitive","SonnerToaster","Map"],"sources":["../src/components/ui/Card.tsx","../src/components/ui/Textarea.tsx","../src/components/ui/AlertDialog.tsx","../src/components/ui/Sonner.tsx","../src/components/ui/Empty.tsx","../src/components/prompt-area/segment-helpers.ts","../src/components/terminal/StatusLine.tsx","../src/components/agent/SessionList.tsx","../src/components/agent/ProjectIcon.tsx","../src/components/agent/ContextRing.tsx","../src/components/agent/EngineIcon.tsx","../src/components/agent/SessionStatusIcon.tsx","../src/components/agent/SessionSteps.tsx","../src/components/agent/SessionItem.tsx","../src/components/agent/SessionBrowser.tsx"],"sourcesContent":["import { type HTMLAttributes } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nexport function Card({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div data-slot=\"card\" className={cn('rounded-lg border border-border bg-surface', className)} {...props} />\n}\n\nexport function CardHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex items-start justify-between gap-3 px-4 pt-3.5 pb-3', className)} {...props} />\n}\n\nexport function CardTitle({ className, ...props }: HTMLAttributes<HTMLHeadingElement>) {\n return <h3 className={cn('text-heading-3 font-semibold text-text', className)} {...props} />\n}\n\nexport function CardContent({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('px-4 pb-4', className)} {...props} />\n}\n","import { type TextareaHTMLAttributes, forwardRef } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaHTMLAttributes<HTMLTextAreaElement>>(({ className, ...props }, ref) => (\n <textarea\n ref={ref}\n data-slot=\"textarea\"\n className={cn(\n 'w-full resize-none rounded-md border border-border bg-bg px-2.5 py-2 text-body-sm text-text',\n 'placeholder:text-fg-4 transition-colors outline-none',\n 'hover:border-border-strong focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40',\n 'disabled:pointer-events-none disabled:opacity-50',\n className,\n )}\n {...props}\n />\n))\nTextarea.displayName = 'Textarea'\n","import { type FunctionComponent } from 'react'\nimport { AlertDialog as AlertDialogPrimitive } from '@base-ui/react/alert-dialog'\nimport { cn } from '../../lib/utils.ts'\nimport { PortalScope } from './PortalScope.tsx'\n\nexport const AlertDialog = AlertDialogPrimitive.Root\nexport const AlertDialogTrigger = AlertDialogPrimitive.Trigger\nexport const AlertDialogClose = AlertDialogPrimitive.Close\n\nexport const AlertDialogContent: FunctionComponent<AlertDialogPrimitive.Popup.Props> = ({ className, children, ...props }) => (\n <AlertDialogPrimitive.Portal>\n <PortalScope>\n <AlertDialogPrimitive.Backdrop\n className={cn(\n 'fixed inset-0 z-70 bg-black/40 backdrop-blur-[1px]',\n 'transition-opacity duration-(--motion-base)',\n 'data-starting-style:opacity-0 data-ending-style:opacity-0',\n )}\n />\n <AlertDialogPrimitive.Popup\n data-slot=\"alert-dialog-content\"\n className={cn(\n 'fixed top-1/2 left-1/2 z-70 w-[min(28rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2',\n 'rounded-lg border border-border bg-surface p-5 shadow-(--shadow-lg) outline-none',\n 'transition-[opacity,transform] duration-(--motion-base)',\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-ending-style:scale-95 data-ending-style:opacity-0',\n className,\n )}\n {...props}\n >\n {children}\n </AlertDialogPrimitive.Popup>\n </PortalScope>\n </AlertDialogPrimitive.Portal>\n)\n\nexport const AlertDialogTitle: FunctionComponent<AlertDialogPrimitive.Title.Props> = ({ className, ...props }) => (\n <AlertDialogPrimitive.Title className={cn('text-heading-3 font-semibold text-text', className)} {...props} />\n)\n\nexport const AlertDialogDescription: FunctionComponent<AlertDialogPrimitive.Description.Props> = ({ className, ...props }) => (\n <AlertDialogPrimitive.Description className={cn('mt-1.5 text-body-sm text-muted-foreground', className)} {...props} />\n)\n","import { Toaster as SonnerToaster, toast } from 'sonner'\n\nexport { toast }\n\nexport function Toaster() {\n return (\n <SonnerToaster\n position=\"bottom-right\"\n toastOptions={{\n style: {\n background: 'var(--surface)',\n color: 'var(--text)',\n border: '1px solid var(--border)',\n boxShadow: 'var(--shadow-md)',\n fontFamily: 'var(--cw-font-sans)',\n fontSize: 'var(--text-body-sm)',\n },\n }}\n />\n )\n}\n","import type { ReactNode } from 'react'\nimport { Button } from './Button.tsx'\n\nexport function Empty({\n icon,\n title,\n description,\n action,\n onAction,\n}: {\n icon: ReactNode\n title: string\n description?: ReactNode\n action?: string\n onAction?: () => void\n}) {\n return (\n <div className=\"flex flex-col items-center gap-2 px-5 py-8 text-center\">\n <div className=\"text-fg-4 opacity-60 [&_svg]:size-7\">{icon}</div>\n <p className=\"text-body-sm font-medium text-fg-2\">{title}</p>\n {description ? <p className=\"max-w-[26ch] text-balance text-label leading-relaxed text-fg-4\">{description}</p> : null}\n {action && onAction ? (\n <Button variant=\"outline\" size=\"sm\" className=\"mt-1\" onClick={onAction}>\n {action}\n </Button>\n ) : null}\n </div>\n )\n}\n\nexport function EmptyKey({ children }: { children: ReactNode }) {\n return <span className=\"rounded border border-border px-1 font-mono text-fg-3\">{children}</span>\n}\n","/**\n * Convenience helpers for creating and inspecting Segments.\n *\n * These reduce boilerplate when building AI chat UIs that work with the\n * PromptArea document model.\n *\n * @example\n * ```ts\n * import { text, chip, isSegmentsEmpty, segmentsToPlainText } from './segment-helpers.ts'\n *\n * const greeting = [text('Hello '), chip({ trigger: '@', value: 'u1', displayText: 'Alice' })]\n * isSegmentsEmpty(greeting) // false\n * segmentsToPlainText(greeting) // \"Hello @Alice\"\n * ```\n */\n\nimport type { Segment, TextSegment, ChipSegment } from './types.ts'\nimport { segmentsToPlainText, plainTextToSegments } from './prompt-area-engine.ts'\n\n// Re-export serialization utilities so consumers have a single import.\nexport { segmentsToPlainText, plainTextToSegments }\n\n/** Create a text segment. */\nexport function text(value: string): TextSegment {\n return { type: 'text', text: value }\n}\n\n/** Create a chip segment. */\nexport function chip(opts: Omit<ChipSegment, 'type'>): ChipSegment {\n return { type: 'chip', ...opts }\n}\n\n/** Returns `true` when the segment array is empty or contains only whitespace text. */\nexport function isSegmentsEmpty(segments: Segment[]): boolean {\n if (segments.length === 0) {\n return true\n }\n return segments.every((seg) => seg.type === 'text' && seg.text.trim() === '')\n}\n\n/** Returns `true` when the segment array contains at least one chip. */\nexport function hasChips(segments: Segment[]): boolean {\n return segments.some((seg) => seg.type === 'chip')\n}\n\n/** Extracts all chip segments from a segment array. */\nexport function getChips(segments: Segment[]): ChipSegment[] {\n return segments.filter((seg): seg is ChipSegment => seg.type === 'chip')\n}\n\n/** Extracts chips matching a specific trigger character. */\nexport function getChipsByTrigger(segments: Segment[], trigger: string): ChipSegment[] {\n return segments.filter((seg): seg is ChipSegment => seg.type === 'chip' && seg.trigger === trigger)\n}\n","import type { RateLimitInfo } from '@workerdeck/protocol'\nimport type { ConnectionState, TranscriptState } from '@workerdeck/react'\nimport { formatCost, formatTokens } from '../../lib/format.ts'\nimport {\n contextSeverity,\n meterSeverity,\n modelLabel,\n statusPresentation,\n tightestWindow,\n windowLabel,\n type StatusSeverity,\n} from '../../lib/status.ts'\nimport { Ink, Row, type Tone } from './row.tsx'\n\nconst SEVERITY_TONE: Record<StatusSeverity, Tone> = {\n none: 'dim',\n warning: 'yellow',\n error: 'red',\n}\n\nexport interface TerminalStatusLineProps {\n className?: string\n state: TranscriptState\n rateLimits?: Record<string, RateLimitInfo>\n connection?: ConnectionState\n onOpenStatus?: () => void\n onOpenContext?: () => void\n onOpenUsage?: () => void\n}\n\nfunction Reading({ tone, onPress, label, children }: { tone?: Tone; onPress?: () => void; label?: string; children: React.ReactNode }) {\n if (!onPress) {\n return <Ink tone={tone}>{children}</Ink>\n }\n return (\n <button type=\"button\" className=\"term-reading\" onClick={onPress} title={label}>\n <Ink tone={tone}>{children}</Ink>\n </button>\n )\n}\n\nexport function TerminalStatusLine({\n className,\n state,\n rateLimits,\n connection,\n onOpenStatus,\n onOpenContext,\n onOpenUsage,\n}: TerminalStatusLineProps) {\n const presentation = statusPresentation({ status: state.status, connection })\n const usage = state.contextUsage\n const window = tightestWindow(rateLimits ?? state.rateLimits)\n const model = modelLabel({ model: state.model, models: state.models ?? [] })\n\n const parts: React.ReactNode[] = [\n <Reading key=\"status\" tone={SEVERITY_TONE[presentation.severity]} onPress={onOpenStatus} label=\"Session status\">\n {presentation.label}\n </Reading>,\n ]\n\n if (usage) {\n parts.push(\n <Reading key=\"context\" tone={SEVERITY_TONE[contextSeverity(usage)]} onPress={onOpenContext} label=\"Context window\">\n {Math.round(usage.percentage)}% ctx ({formatTokens(usage.totalTokens)})\n </Reading>,\n )\n }\n\n if (window) {\n parts.push(\n <Reading key=\"usage\" tone={SEVERITY_TONE[meterSeverity(window.info.utilization)]} onPress={onOpenUsage} label=\"Plan usage\">\n {Math.round(window.info.utilization ?? 0)}% {windowLabel(window.key)}\n </Reading>,\n )\n }\n\n if (state.totalCostUsd > 0) {\n parts.push(\n <Ink key=\"cost\" tone=\"faint\">\n {formatCost(state.totalCostUsd)}\n </Ink>,\n )\n }\n\n if (model) {\n parts.push(\n <Ink key=\"model\" tone=\"faint\">\n {model}\n </Ink>,\n )\n }\n if (state.permissionMode && state.permissionMode !== 'default') {\n parts.push(\n <Ink key=\"mode\" tone=\"yellow\">\n {state.permissionMode}\n </Ink>,\n )\n }\n\n return (\n <Row data-slot=\"status-line\" tone=\"dim\" className={className}>\n {parts.map((part, index) => (\n <span key={index}>\n {index > 0 ? <Ink tone=\"faint\"> · </Ink> : null}\n {part}\n </span>\n ))}\n </Row>\n )\n}\n","import type { SessionInfo } from '@workerdeck/protocol'\nimport { Trash2 } from 'lucide-react'\nimport { Badge } from '../ui/Badge.tsx'\nimport { Button } from '../ui/Button.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { formatCost, formatRelativeTime } from '../../lib/format.ts'\nimport { STATUS_META } from './status.ts'\n\nexport interface SessionListItemProps {\n session: SessionInfo\n active?: boolean\n onSelect?: (id: string) => void\n onDelete?: (id: string) => void\n className?: string\n}\n\nexport function SessionListItem({ session, active, onSelect, onDelete, className }: SessionListItemProps) {\n const meta = STATUS_META[session.status]\n return (\n <div\n data-slot=\"session-list-item\"\n data-active={active || undefined}\n className={cn(\n 'group flex w-full items-center gap-2 rounded-md border border-transparent px-2.5 py-2 text-left transition-colors',\n active ? 'border-border bg-surface' : 'hover:bg-surface-hover',\n className,\n )}\n >\n <button type=\"button\" onClick={() => onSelect?.(session.id)} className=\"min-w-0 flex-1 text-left outline-none\">\n <div className=\"flex items-center gap-2\">\n <span className=\"truncate text-body-sm font-medium text-fg-1\">{session.title ?? session.id.slice(0, 8)}</span>\n <Badge variant={meta.variant} dot className=\"shrink-0\">\n {meta.label}\n </Badge>\n </div>\n <div className=\"mt-0.5 flex items-center gap-2 font-mono text-label text-fg-4\">\n <span className=\"truncate\">{session.cwd}</span>\n {session.profile ? <span className=\"shrink-0\">@{session.profile}</span> : null}\n <span className=\"shrink-0\">{formatCost(session.totalCostUsd)}</span>\n <span className=\"shrink-0\">{formatRelativeTime(session.lastActivityAt ?? session.createdAt)}</span>\n </div>\n </button>\n {onDelete ? (\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"Close session\"\n className=\"opacity-0 transition-opacity group-hover:opacity-100\"\n onClick={() => onDelete(session.id)}\n >\n <Trash2 className=\"size-3.5 text-fg-3\" />\n </Button>\n ) : null}\n </div>\n )\n}\n\nexport interface SessionListProps {\n sessions: SessionInfo[]\n activeId?: string\n onSelect?: (id: string) => void\n onDelete?: (id: string) => void\n emptyText?: string\n className?: string\n}\n\nexport function SessionList({ sessions, activeId, onSelect, onDelete, emptyText = 'No sessions yet.', className }: SessionListProps) {\n return (\n <div data-slot=\"session-list\" className={cn('flex flex-col gap-1', className)}>\n {sessions.length === 0 ? (\n <div className=\"px-2.5 py-6 text-center text-body-sm text-fg-4\">{emptyText}</div>\n ) : (\n sessions.map((session) => (\n <SessionListItem key={session.id} session={session} active={session.id === activeId} onSelect={onSelect} onDelete={onDelete} />\n ))\n )}\n </div>\n )\n}\n","import type { ProjectIcon as ProjectIconSpec } from '@workerdeck/protocol'\nimport {\n Anchor,\n Atom,\n Beaker,\n Bike,\n Binary,\n Blocks,\n Bot,\n Box,\n Brain,\n Briefcase,\n Brush,\n Bug,\n Building2,\n Cable,\n Camera,\n Car,\n Cat,\n CircuitBoard,\n Cloud,\n Code,\n Coffee,\n Cog,\n Compass,\n Container,\n Cpu,\n CreditCard,\n Database,\n Diamond,\n Dog,\n Feather,\n Film,\n Flame,\n FlaskConical,\n Folder,\n Gamepad2,\n Gauge,\n Gem,\n Ghost,\n Gift,\n GitBranch,\n Globe,\n GraduationCap,\n Hammer,\n Hexagon,\n House,\n Image,\n Key,\n Landmark,\n Laptop,\n Layers,\n Leaf,\n Library,\n Lightbulb,\n Lock,\n Mail,\n Map,\n MessageCircle,\n Mic,\n Monitor,\n Moon,\n Mountain,\n Music,\n Network,\n Newspaper,\n Notebook,\n Orbit,\n Package,\n Palette,\n PenTool,\n Phone,\n PiggyBank,\n Plane,\n Plug,\n Puzzle,\n Radar,\n Radio,\n Receipt,\n Rocket,\n Ruler,\n Satellite,\n Scale,\n Scissors,\n Server,\n Shield,\n Ship,\n ShoppingCart,\n Signal,\n Smartphone,\n Sparkles,\n Sprout,\n Square,\n Star,\n Sun,\n Table,\n Tag,\n Target,\n Telescope,\n Terminal,\n TestTube,\n TreePine,\n Trophy,\n Truck,\n Umbrella,\n Users,\n Wallet,\n Wand,\n Waves,\n Webhook,\n Wifi,\n Wrench,\n Zap,\n} from 'lucide-react'\nimport type { ComponentType } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nconst GLYPHS: Record<string, ComponentType<{ className?: string }>> = {\n anchor: Anchor,\n atom: Atom,\n beaker: Beaker,\n bike: Bike,\n binary: Binary,\n blocks: Blocks,\n bot: Bot,\n box: Box,\n brain: Brain,\n briefcase: Briefcase,\n brush: Brush,\n bug: Bug,\n 'building-2': Building2,\n cable: Cable,\n camera: Camera,\n car: Car,\n cat: Cat,\n 'circuit-board': CircuitBoard,\n cloud: Cloud,\n code: Code,\n coffee: Coffee,\n cog: Cog,\n compass: Compass,\n container: Container,\n cpu: Cpu,\n 'credit-card': CreditCard,\n database: Database,\n diamond: Diamond,\n dog: Dog,\n feather: Feather,\n film: Film,\n flame: Flame,\n 'flask-conical': FlaskConical,\n folder: Folder,\n 'gamepad-2': Gamepad2,\n gauge: Gauge,\n gem: Gem,\n ghost: Ghost,\n gift: Gift,\n 'git-branch': GitBranch,\n globe: Globe,\n 'graduation-cap': GraduationCap,\n hammer: Hammer,\n hexagon: Hexagon,\n house: House,\n image: Image,\n key: Key,\n landmark: Landmark,\n laptop: Laptop,\n layers: Layers,\n leaf: Leaf,\n library: Library,\n lightbulb: Lightbulb,\n lock: Lock,\n mail: Mail,\n map: Map,\n 'message-circle': MessageCircle,\n mic: Mic,\n monitor: Monitor,\n moon: Moon,\n mountain: Mountain,\n music: Music,\n network: Network,\n newspaper: Newspaper,\n notebook: Notebook,\n orbit: Orbit,\n package: Package,\n palette: Palette,\n 'pen-tool': PenTool,\n phone: Phone,\n 'piggy-bank': PiggyBank,\n plane: Plane,\n plug: Plug,\n puzzle: Puzzle,\n radar: Radar,\n radio: Radio,\n receipt: Receipt,\n rocket: Rocket,\n ruler: Ruler,\n satellite: Satellite,\n scale: Scale,\n scissors: Scissors,\n server: Server,\n shield: Shield,\n ship: Ship,\n 'shopping-cart': ShoppingCart,\n signal: Signal,\n smartphone: Smartphone,\n sparkles: Sparkles,\n sprout: Sprout,\n square: Square,\n star: Star,\n sun: Sun,\n table: Table,\n tag: Tag,\n target: Target,\n telescope: Telescope,\n terminal: Terminal,\n 'test-tube': TestTube,\n 'tree-pine': TreePine,\n trophy: Trophy,\n truck: Truck,\n umbrella: Umbrella,\n users: Users,\n wallet: Wallet,\n wand: Wand,\n waves: Waves,\n webhook: Webhook,\n wifi: Wifi,\n wrench: Wrench,\n zap: Zap,\n}\n\nexport function ProjectIcon({\n icon,\n src,\n name,\n className,\n}: {\n icon: ProjectIconSpec | undefined\n src?: string\n name?: string\n className?: string\n}) {\n if (!icon) {\n return null\n }\n if (icon.type === 'image') {\n if (!src) {\n return null\n }\n return <img src={src} alt=\"\" aria-hidden title={name} className={cn('inline-block size-3 shrink-0 object-contain', className)} />\n }\n const Glyph = GLYPHS[icon.name] ?? Folder\n return <Glyph className={cn('inline-block size-3 shrink-0', className)} />\n}\n","import type { ContextReading } from '@workerdeck/protocol'\nimport { ProgressRing } from '../ui/ProgressRing.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { formatTokens } from '../../lib/format.ts'\nimport { meterColorClass } from '../../lib/status.ts'\n\nexport function ContextRing({ usage, size = 11, className }: { usage: ContextReading | undefined; size?: number; className?: string }) {\n if (usage === undefined) {\n return null\n }\n return (\n <span\n title={`Context ${usage.percentage.toFixed(0)}% · ${formatTokens(usage.totalTokens)} / ${formatTokens(usage.maxTokens)}`}\n className={cn('shrink-0 leading-none', meterColorClass(usage.percentage), className)}\n >\n <ProgressRing value={usage.percentage} size={size} strokeWidth={2} />\n </span>\n )\n}\n","import { cn } from '../../lib/utils.ts'\n\n// Paths from `@lobehub/icons-static-svg` (MIT, © LobeHub), inlined. The marks are trademarks of their owners, used only to identify a session's engine.\nconst PATHS: Record<string, { title: string; d: string }> = {\n claude: {\n title: 'Claude',\n d: 'M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z',\n },\n codex: {\n title: 'OpenAI',\n d: 'M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z',\n },\n gemini: {\n title: 'Gemini',\n d: 'M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z',\n },\n deepseek: {\n title: 'DeepSeek',\n d: 'M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z',\n },\n moonshot: {\n title: 'Moonshot',\n d: 'M1.052 16.916l9.539 2.552a21.007 21.007 0 00.06 2.033l5.956 1.593a11.997 11.997 0 01-5.586.865l-.18-.016-.044-.004-.084-.009-.094-.01a11.605 11.605 0 01-.157-.02l-.107-.014-.11-.016a11.962 11.962 0 01-.32-.051l-.042-.008-.075-.013-.107-.02-.07-.015-.093-.019-.075-.016-.095-.02-.097-.023-.094-.022-.068-.017-.088-.022-.09-.024-.095-.025-.082-.023-.109-.03-.062-.02-.084-.025-.093-.028-.105-.034-.058-.019-.08-.026-.09-.031-.066-.024a6.293 6.293 0 01-.044-.015l-.068-.025-.101-.037-.057-.022-.08-.03-.087-.035-.088-.035-.079-.032-.095-.04-.063-.028-.063-.027a5.655 5.655 0 01-.041-.018l-.066-.03-.103-.047-.052-.024-.096-.046-.062-.03-.084-.04-.086-.044-.093-.047-.052-.027-.103-.055-.057-.03-.058-.032a6.49 6.49 0 01-.046-.026l-.094-.053-.06-.034-.051-.03-.072-.041-.082-.05-.093-.056-.052-.032-.084-.053-.061-.039-.079-.05-.07-.047-.053-.035a7.785 7.785 0 01-.054-.036l-.044-.03-.044-.03a6.066 6.066 0 01-.04-.028l-.057-.04-.076-.054-.069-.05-.074-.054-.056-.042-.076-.057-.076-.059-.086-.067-.045-.035-.064-.052-.074-.06-.089-.073-.046-.039-.046-.039a7.516 7.516 0 01-.043-.037l-.045-.04-.061-.053-.07-.062-.068-.06-.062-.058-.067-.062-.053-.05-.088-.084a13.28 13.28 0 01-.099-.097l-.029-.028-.041-.042-.069-.07-.05-.051-.05-.053a6.457 6.457 0 01-.168-.179l-.08-.088-.062-.07-.071-.08-.042-.049-.053-.062-.058-.068-.046-.056a7.175 7.175 0 01-.027-.033l-.045-.055-.066-.082-.041-.052-.05-.064-.02-.025a11.99 11.99 0 01-1.44-2.402zm-1.02-5.794l11.353 3.037a20.468 20.468 0 00-.469 2.011l10.817 2.894a12.076 12.076 0 01-1.845 2.005L.657 15.923l-.016-.046-.035-.104a11.965 11.965 0 01-.05-.153l-.007-.023a11.896 11.896 0 01-.207-.741l-.03-.126-.018-.08-.021-.097-.018-.081-.018-.09-.017-.084-.018-.094c-.026-.141-.05-.283-.071-.426l-.017-.118-.011-.083-.013-.102a12.01 12.01 0 01-.019-.161l-.005-.047a12.12 12.12 0 01-.034-2.145zm1.593-5.15l11.948 3.196c-.368.605-.705 1.231-1.01 1.875l11.295 3.022c-.142.82-.368 1.612-.668 2.365l-11.55-3.09L.124 10.26l.015-.1.008-.049.01-.067.015-.087.018-.098c.026-.148.056-.295.088-.442l.028-.124.02-.085.024-.097c.022-.09.045-.18.07-.268l.028-.102.023-.083.03-.1.025-.082.03-.096.026-.082.031-.095a11.896 11.896 0 011.01-2.232zm4.442-4.4L17.352 4.59a20.77 20.77 0 00-1.688 1.721l7.823 2.093c.267.852.442 1.744.513 2.665L2.106 5.213l.045-.065.027-.04.04-.055.046-.065.055-.076.054-.072.064-.086.05-.065.057-.073.055-.07.06-.074.055-.069.065-.077.054-.066.066-.077.053-.06.072-.082.053-.06.067-.074.054-.058.073-.078.058-.06.063-.067.168-.17.1-.098.059-.056.076-.071a12.084 12.084 0 012.272-1.677zM12.017 0h.097l.082.001.069.001.054.002.068.002.046.001.076.003.047.002.06.003.054.002.087.005.105.007.144.011.088.007.044.004.077.008.082.008.047.005.102.012.05.006.108.014.081.01.042.006.065.01.207.032.07.012.065.011.14.026.092.018.11.022.046.01.075.016.041.01L14.7.3l.042.01.065.015.049.012.071.017.096.024.112.03.113.03.113.032.05.015.07.02.078.024.073.023.05.016.05.016.076.025.099.033.102.036.048.017.064.023.093.034.11.041.116.045.1.04.047.02.06.024.041.018.063.026.04.018.057.025.11.048.1.046.074.035.075.036.06.028.092.046.091.045.102.052.053.028.049.026.046.024.06.033.041.022.052.029.088.05.106.06.087.051.057.034.053.032.096.059.088.055.098.062.036.024.064.041.084.056.04.027.062.042.062.043.023.017c.054.037.108.075.161.114l.083.06.065.048.056.043.086.065.082.064.04.03.05.041.086.069.079.065.085.071c.712.6 1.353 1.283 1.909 2.031L7.222.994l.062-.027.065-.028.081-.034.086-.035c.113-.045.227-.09.341-.131l.096-.035.093-.033.084-.03.096-.031c.087-.03.176-.058.264-.085l.091-.027.086-.025.102-.03.085-.023.1-.026L9.04.37l.09-.023.091-.022.095-.022.09-.02.098-.021.091-.02.095-.018.092-.018.1-.018.091-.016.098-.017.092-.014.097-.015.092-.013.102-.013.091-.012.105-.012.09-.01.105-.01c.093-.01.186-.018.28-.024l.106-.008.09-.005.11-.006.093-.004.1-.004.097-.002.099-.002.197-.002z',\n },\n}\n\nexport function engineMark(engine: string, model?: string): string | undefined {\n if (engine === 'claude') {\n return 'claude'\n }\n if (engine === 'codex') {\n return 'codex'\n }\n const id = model?.toLowerCase() ?? ''\n if (!id) {\n return undefined\n }\n if (id.includes('gemini')) {\n return 'gemini'\n }\n if (id.includes('deepseek')) {\n return 'deepseek'\n }\n if (id.includes('moonshot') || id.includes('kimi')) {\n return 'moonshot'\n }\n if (id.includes('claude')) {\n return 'claude'\n }\n if (id.startsWith('gpt') || id.startsWith('o1') || id.startsWith('o3') || id.includes('openai')) {\n return 'codex'\n }\n return undefined\n}\n\nconst VENDOR_MARK: Record<string, string> = {\n claude: 'text-vendor-claude',\n codex: 'text-vendor-openai',\n}\nconst VENDOR_TEXT: Record<string, string> = {\n claude: 'text-vendor-claude',\n}\n\nexport function vendorMarkClass(engine: string, model?: string): string {\n return VENDOR_MARK[engineMark(engine, model) ?? ''] ?? 'text-fg-3'\n}\n\nexport function vendorTextClass(engine: string, model?: string): string {\n return VENDOR_TEXT[engineMark(engine, model) ?? ''] ?? 'text-fg-3'\n}\n\nexport function EngineIcon({ engine, model, className }: { engine: string; model?: string; className?: string }) {\n const mark = PATHS[engineMark(engine, model) ?? '']\n if (!mark) {\n return (\n <span aria-hidden title={engine} className={cn('shrink-0 text-fg-3', className)}>\n ·\n </span>\n )\n }\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n role=\"img\"\n aria-label={mark.title}\n className={cn('size-3 shrink-0 text-fg-3', className)}\n >\n <title>{mark.title}</title>\n <path d={mark.d} />\n </svg>\n )\n}\n","import { BellRing, CircleAlert, CircleSlash, Moon, PauseCircle } from 'lucide-react'\nimport type { SessionRow } from '@workerdeck/protocol'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport function SessionStatusIcon({ row, className }: { row: SessionRow; className?: string }) {\n const { info } = row\n const size = cn('size-4 shrink-0', className)\n if (row.state === 'attention') {\n return <BellRing className={cn(size, 'animate-pulse text-warning')} />\n }\n if (row.state === 'working') {\n return <Spinner className={cn(size, 'text-info')} />\n }\n switch (info.status) {\n case 'failed': {\n return <CircleAlert className={cn(size, 'text-danger')} />\n }\n case 'closed': {\n return <CircleSlash className={cn(size, 'text-fg-4')} />\n }\n case 'parked': {\n return <PauseCircle className={cn(size, 'text-fg-3')} />\n }\n default: {\n return <Moon className={cn(size, 'text-fg-4')} />\n }\n }\n}\n","import { ArrowRight, Check, ChevronDown, ChevronRight, CircleAlert, Dot, PauseCircle } from 'lucide-react'\nimport { isAgentRecord, subagentLabel } from '@workerdeck/protocol'\nimport type { SessionInfo, SubagentInfo } from '@workerdeck/protocol'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport type Step = {\n key: string\n label: string\n noun: string\n kind: 'agent' | 'task'\n state: 'done' | 'running' | 'pending' | 'failed'\n detail?: string\n title: string\n onSelect: () => void\n}\n\nexport function sessionSteps(info: SessionInfo, onSelect: (toolUseId: string, kind: Step['kind']) => void): Step[] {\n const steps = (info.subagents ?? []).map((sub) => {\n const kind = isAgentRecord(sub) ? ('agent' as const) : ('task' as const)\n return {\n key: sub.toolUseId,\n label: subagentLabel(sub),\n noun: 'agent',\n kind,\n state: stepState(sub.status),\n detail: sub.toolCount > 0 ? String(sub.toolCount) : undefined,\n title: `${subagentLabel(sub)} · ${sub.toolCount} tool${sub.toolCount === 1 ? '' : 's'}`,\n onSelect: () => onSelect(sub.toolUseId, kind),\n }\n })\n return [...steps.filter((s) => s.kind === 'agent'), ...steps.filter((s) => s.kind === 'task')]\n}\n\nfunction stepState(status: SubagentInfo['status']): Step['state'] {\n switch (status) {\n case 'running': {\n return 'running'\n }\n case 'failed': {\n return 'failed'\n }\n default: {\n return 'done'\n }\n }\n}\n\nexport function runningSteps(steps: readonly Step[]): number {\n return steps.filter((s) => s.state === 'running').length\n}\n\nexport function StepToggle({\n expanded,\n running,\n total,\n noun,\n onToggle,\n}: {\n expanded: boolean\n running: number\n total: number\n noun: string\n onToggle: () => void\n}) {\n const label = running > 0 && running < total ? `${running}/${total}` : String(total)\n const words = running > 0 && running < total ? `${running} of ${total} ${noun}s running` : `${total} ${noun}${total === 1 ? '' : 's'}`\n const Chevron = expanded ? ChevronDown : ChevronRight\n return (\n <button\n type=\"button\"\n aria-expanded={expanded}\n aria-label={`${expanded ? 'Hide' : 'Show'} ${words}`}\n title={`${expanded ? 'Hide' : 'Show'} ${words}`}\n onClick={(e) => {\n e.stopPropagation()\n onToggle()\n }}\n className={cn(\n 'flex shrink-0 items-center gap-0.5 rounded-[4px] py-0.5 pr-1 pl-0.5 outline-none',\n 'text-[0.75rem] leading-3 hover:bg-row-hover hover:text-fg-2',\n running > 0 ? 'text-info' : 'text-fg-4',\n )}\n >\n <Chevron className=\"size-3\" />\n <span className=\"tabular-nums\">{label}</span>\n </button>\n )\n}\n\nexport function StepRow({ step, active = false, onSelect }: { step: Step; active?: boolean; onSelect: () => void }) {\n const agent = step.kind === 'agent'\n const selected = active && agent\n const body = step.state === 'failed' ? 'text-danger' : agent ? 'text-success' : 'text-fg-4'\n return (\n <button\n type=\"button\"\n title={step.title}\n aria-current={selected || undefined}\n onClick={(e) => {\n e.stopPropagation()\n onSelect()\n }}\n className={cn(\n 'flex w-full items-center gap-1.5 rounded-[4px] py-1 pr-2.5 pl-3.5',\n 'text-left text-micro outline-none',\n selected ? 'bg-row-selected' : 'hover:bg-row-active',\n body,\n )}\n >\n <StepIcon state={step.state} kind={step.kind} />\n <span className=\"min-w-0 flex-1 truncate\">{step.label}</span>\n {step.detail ? <span className=\"shrink-0 tabular-nums text-fg-4\">{step.detail}</span> : null}\n {agent ? <ArrowRight className=\"size-3.5 shrink-0 text-fg-4\" /> : null}\n </button>\n )\n}\n\nfunction StepIcon({ state, kind }: { state: Step['state']; kind: Step['kind'] }) {\n if (kind === 'task' && state !== 'running' && state !== 'failed') {\n return <Dot className=\"size-[11px] shrink-0\" />\n }\n switch (state) {\n case 'running': {\n return <Spinner className=\"size-[11px] shrink-0\" />\n }\n case 'failed': {\n return <CircleAlert className=\"size-[11px] shrink-0\" />\n }\n case 'pending': {\n return <PauseCircle className=\"size-[11px] shrink-0\" />\n }\n default: {\n return <Check className=\"size-[11px] shrink-0\" />\n }\n }\n}\n","import { Fragment, useEffect, useRef, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { projectLabel, projectSubpath, sessionLabel } from '@workerdeck/protocol'\nimport type { SessionRow } from '@workerdeck/protocol'\nimport { ContextRing } from './ContextRing.tsx'\nimport { EngineIcon, vendorMarkClass, vendorTextClass } from './EngineIcon.tsx'\nimport { ProjectIcon } from './ProjectIcon.tsx'\nimport { SessionStatusIcon } from './SessionStatusIcon.tsx'\nimport { StepRow, StepToggle, runningSteps, sessionSteps } from './SessionSteps.tsx'\nimport type { Step } from './SessionSteps.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { formatCost, formatRelativeTime, friendlyModel } from '../../lib/format.ts'\n\nexport interface SessionItemProps {\n row: SessionRow\n active?: boolean\n activeStepKey?: string\n showGateway?: boolean\n showProject?: boolean\n projectIcons?: Record<string, string>\n expanded?: boolean\n onExpandedChange?: (expanded: boolean) => void\n onSelect?: () => void\n onSelectSubagent?: (toolUseId: string) => void\n onRevealStep?: (toolUseId: string) => void\n onRename?: (title: string) => void\n renameOn?: 'doubleClick' | 'external'\n editing?: boolean\n onEditingChange?: (editing: boolean) => void\n actions?: ReactNode\n className?: string\n}\n\nexport function SessionItem({\n row,\n active = false,\n activeStepKey,\n showGateway,\n showProject = true,\n projectIcons,\n expanded,\n onExpandedChange,\n onSelect,\n onSelectSubagent,\n onRevealStep,\n onRename,\n renameOn = 'doubleClick',\n editing,\n onEditingChange,\n actions,\n className,\n}: SessionItemProps) {\n const { info } = row\n const [ownExpanded, setOwnExpanded] = useState(false)\n const open = expanded ?? ownExpanded\n const setOpen = (next: boolean) => {\n setOwnExpanded(next)\n onExpandedChange?.(next)\n }\n const [ownEditing, setOwnEditing] = useState(false)\n const isEditing = editing ?? ownEditing\n const setEditing = (next: boolean) => {\n setOwnEditing(next)\n onEditingChange?.(next)\n }\n\n const engine = info.engine ?? 'claude'\n const project = showProject ? projectLabel(row) : projectSubpath(row)\n const projectIcon = showProject ? info.project?.icon : undefined\n const iconSrc = projectIcon?.type === 'image' ? projectIcons?.[projectIcon.hash] : undefined\n const cost = formatCost(info.totalCostUsd)\n const extras = [\n showGateway ? row.hostName : undefined,\n info.profile ? `@${info.profile}` : undefined,\n cost === '—' ? undefined : cost,\n ].filter((part): part is string => Boolean(part))\n\n const model = friendlyModel(info.model)\n const parts: ReactNode[] = []\n if (model) {\n parts.push(\n <span key=\"model\" className={vendorTextClass(engine, info.model)}>\n {model}\n </span>,\n )\n }\n if (project !== undefined) {\n parts.push(\n <span key=\"project\">\n <ProjectIcon icon={projectIcon} src={iconSrc} name={project} className=\"mr-1.5 size-4 align-[-0.3em]\" />\n {project}\n </span>,\n )\n }\n for (const extra of extras) {\n parts.push(<span key={extra}>{extra}</span>)\n }\n const steps = sessionSteps(info, (toolUseId, kind) => {\n if (kind === 'agent') {\n return onSelectSubagent ? onSelectSubagent(toolUseId) : onSelect?.()\n }\n return onRevealStep ? onRevealStep(toolUseId) : onSelect?.()\n })\n const holdsOpenAgent = steps.some((s) => s.kind === 'agent' && s.key === activeStepKey)\n\n return (\n <div\n data-slot=\"session-item\"\n data-active={active || undefined}\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n if (e.detail > 1 || isEditing) {\n return\n }\n onSelect?.()\n }}\n onKeyDown={(e) => {\n if (e.target !== e.currentTarget) {\n return\n }\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n onSelect?.()\n }\n }}\n className={cn(\n 'group flex w-full cursor-pointer flex-col p-1 text-left outline-none',\n 'rounded-[4px] transition-colors focus-visible:ring-2 focus-visible:ring-ring',\n holdsOpenAgent ? 'bg-row-selected-weak' : active ? 'bg-row-selected' : 'hover:bg-row-hover',\n className,\n )}\n >\n <div className=\"flex flex-col gap-1 py-0.5 pr-0.5 pl-1.5\">\n <div className=\"flex h-5 items-center gap-1.5 overflow-hidden\">\n <Gutter>\n <SessionStatusIcon row={row} />\n </Gutter>\n {isEditing && onRename ? (\n <NameEditor\n initial={info.title ?? ''}\n onCommit={(title) => {\n setEditing(false)\n if (title !== (info.title ?? '')) {\n onRename(title)\n }\n }}\n onCancel={() => setEditing(false)}\n />\n ) : (\n <span\n onDoubleClick={\n onRename && renameOn === 'doubleClick'\n ? (e) => {\n e.stopPropagation()\n setEditing(true)\n }\n : undefined\n }\n className=\"min-w-0 flex-1 truncate text-body-sm font-medium tracking-[-0.005em] text-fg-1\"\n >\n {sessionLabel(info)}\n </span>\n )}\n {row.unseen > 0 ? (\n <span\n // Prose, not rows: `unseen` counts messages a person has not read (`proseCount`).\n title={`${row.unseen} new message${row.unseen === 1 ? '' : 's'}`}\n className={cn(\n 'flex h-4 min-w-6 shrink-0 items-center justify-center rounded-full px-2',\n 'text-[0.75rem] leading-none tracking-[-0.005em] tabular-nums',\n row.state === 'working' || row.state === 'attention' ? 'bg-accent text-accent-fg' : 'bg-badge text-badge-fg',\n )}\n >\n {row.unseen}\n </span>\n ) : null}\n <ContextRing usage={info.contextUsage} size={16} className=\"p-0.5\" />\n </div>\n\n <div className=\"flex h-5 items-center gap-1.5 overflow-hidden text-body-sm tracking-[-0.005em]\">\n <Gutter>\n <EngineIcon engine={engine} model={info.model} className={cn('size-4', vendorMarkClass(engine, info.model))} />\n </Gutter>\n <span className=\"min-w-0 truncate text-fg-4\">\n {parts.map((part, i) => (\n <Fragment key={i}>\n {i > 0 ? ' · ' : ''}\n {part}\n </Fragment>\n ))}\n </span>\n <span className=\"shrink-0 text-fg-4\">\n {parts.length > 0 ? '· ' : ''}\n {formatRelativeTime(info.lastActivityAt ?? info.createdAt)}\n </span>\n <span className=\"min-w-0 flex-1\" />\n {steps.length > 0 ? (\n <StepToggle\n expanded={open}\n running={runningSteps(steps)}\n total={steps.length}\n noun={steps[0]!.noun}\n onToggle={() => setOpen(!open)}\n />\n ) : null}\n {actions}\n </div>\n </div>\n\n {open && steps.length > 0 ? (\n <div className=\"flex flex-col\">\n {steps.map((step: Step) => (\n <StepRow key={step.key} step={step} active={step.key === activeStepKey} onSelect={step.onSelect} />\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\nfunction Gutter({ children }: { children: ReactNode }) {\n return <span className=\"flex size-4 shrink-0 items-center justify-center\">{children}</span>\n}\n\nfunction NameEditor({ initial, onCommit, onCancel }: { initial: string; onCommit: (title: string) => void; onCancel: () => void }) {\n const [value, setValue] = useState(initial)\n const ref = useRef<HTMLInputElement>(null)\n useEffect(() => {\n ref.current?.focus()\n ref.current?.select()\n }, [])\n useEffect(() => {\n const onWindowFocus = () => {\n ref.current?.focus()\n ref.current?.select()\n }\n window.addEventListener('focus', onWindowFocus)\n return () => window.removeEventListener('focus', onWindowFocus)\n }, [])\n return (\n <input\n ref={ref}\n value={value}\n spellCheck={false}\n placeholder=\"Session name\"\n aria-label=\"Session name\"\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n onChange={(e) => setValue(e.target.value)}\n onBlur={() => {\n // Guarded on `document.hasFocus()`: selecting a session focuses another surface (in the extension, another view), and an unguarded blur closes the editor in the frame it appeared.\n if (document.hasFocus()) {\n onCommit(value.trim())\n }\n }}\n onKeyDown={(e) => {\n e.stopPropagation()\n if (e.key === 'Enter') {\n onCommit(value.trim())\n } else if (e.key === 'Escape') {\n onCancel()\n }\n }}\n className={cn(\n '-my-0.5 min-w-0 flex-1 rounded-sm border border-ring bg-bg px-1 py-px',\n 'text-body-sm leading-5 text-fg-1 outline-none',\n )}\n />\n )\n}\n","import { useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { Eraser, Layers, Pencil, Search, SearchX, Trash2, X } from 'lucide-react'\nimport {\n STATE_LABELS,\n STATE_ORDER,\n adaptersOf,\n clearFilters,\n filterRows,\n groupRows,\n hasFacetFilter,\n projectsOf,\n subsetSummary,\n} from '@workerdeck/protocol'\nimport type { GroupBy, SessionRow, SessionState, SortBy, ViewConfig, WorkspaceScope } from '@workerdeck/protocol'\nimport { Button } from '../ui/Button.tsx'\nimport { Empty } from '../ui/Empty.tsx'\nimport { Input } from '../ui/Input.tsx'\nimport { Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue } from '../ui/Select.tsx'\nimport { ProjectIcon } from './ProjectIcon.tsx'\nimport { SessionItem } from './SessionItem.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport { SessionStatusIcon } from './SessionStatusIcon.tsx'\n\nexport interface SessionBrowserProps {\n rows: SessionRow[]\n config: ViewConfig\n onConfigChange: (config: ViewConfig) => void\n scope?: WorkspaceScope\n activeId?: string\n activeSubagentId?: string\n onSelect?: (row: SessionRow) => void\n onDelete?: (row: SessionRow) => void\n onRename?: (row: SessionRow, title: string) => void\n onClearContext?: (row: SessionRow) => void\n onSelectSubagent?: (row: SessionRow, toolUseId: string) => void\n onRevealStep?: (row: SessionRow, toolUseId: string) => void\n emptyState?: React.ReactNode\n showControls?: boolean\n projectIcons?: Record<string, string>\n className?: string\n}\n\nexport function rowShapeClass(active: boolean): string {\n return cn('px-2 py-1.5 hover:bg-row-hover', active ? 'mr-1 ml-0 rounded-r-md border-l-4 border-l-accent' : 'mx-1 rounded-md')\n}\n\nexport function SessionBrowser({\n rows,\n config,\n onConfigChange,\n scope,\n activeId,\n activeSubagentId,\n onSelect,\n onDelete,\n onRename,\n onClearContext,\n onSelectSubagent,\n onRevealStep,\n emptyState,\n showControls = true,\n projectIcons,\n className,\n}: SessionBrowserProps) {\n const visible = useMemo(() => filterRows(rows, config, scope), [rows, config, scope])\n const groups = useMemo(() => groupRows(visible, config), [visible, config])\n const subset = subsetSummary(config, scope, visible.length, rows.length)\n const adapters = useMemo(() => adaptersOf(rows), [rows])\n const projects = useMemo(() => projectsOf(rows), [rows])\n const gateways = useMemo(() => {\n const seen = new Map<string, string>()\n for (const row of rows) {\n seen.set(row.hostId, row.hostName)\n }\n return [...seen].map(([id, name]) => ({ id, name }))\n }, [rows])\n\n const set = (patch: Partial<ViewConfig>) => onConfigChange({ ...config, ...patch })\n\n return (\n <div data-slot=\"session-browser\" className={cn('flex flex-col gap-3', className)}>\n <div className={cn('flex flex-col gap-1.5 px-2', !showControls && 'hidden')}>\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-fg-4\" />\n <Input\n value={config.search}\n onChange={(e) => set({ search: e.target.value })}\n placeholder=\"Search sessions\"\n aria-label=\"Search sessions\"\n className=\"pl-8\"\n />\n </div>\n <FilterRow label=\"State\">\n <FacetSelect\n label=\"State\"\n value={config.states}\n options={STATE_ORDER.map((s) => ({ value: s, label: STATE_LABELS[s] }))}\n onChange={(states) => set({ states: states as SessionState[] })}\n />\n </FilterRow>\n {adapters.length > 1 ? (\n <FilterRow label=\"Engine\">\n <FacetSelect\n label=\"Engine\"\n value={config.adapters}\n options={adapters.map((a) => ({ value: a, label: a }))}\n onChange={(adapters) => set({ adapters })}\n />\n </FilterRow>\n ) : null}\n {gateways.length > 1 ? (\n <FilterRow label=\"Gateway\">\n <FacetSelect\n label=\"Gateway\"\n value={config.gateways}\n options={gateways.map((g) => ({ value: g.id, label: g.name }))}\n onChange={(gateways) => set({ gateways })}\n />\n </FilterRow>\n ) : null}\n {projects.length > 1 ? (\n <FilterRow label=\"Project\">\n <FacetSelect\n label=\"Project\"\n value={config.projects ?? []}\n options={projects.map((p) => ({ value: p.key, label: p.label }))}\n onChange={(next) => set({ projects: next })}\n />\n </FilterRow>\n ) : null}\n <FilterRow label=\"Group\">\n <OneOfSelect\n label=\"Group\"\n value={config.groupBy}\n options={[\n { value: 'none', label: 'No grouping' },\n { value: 'state', label: 'By state' },\n { value: 'adapter', label: 'By engine' },\n ...(projects.length > 1 ? [{ value: 'project' as const, label: 'By project' }] : []),\n ...(gateways.length > 1 ? [{ value: 'gateway' as const, label: 'By gateway' }] : []),\n ]}\n onChange={(groupBy) => set({ groupBy: groupBy as GroupBy })}\n />\n </FilterRow>\n <FilterRow label=\"Sort\">\n <OneOfSelect\n label=\"Sort\"\n value={config.sortBy}\n options={[\n { value: 'recent', label: 'Recent' },\n { value: 'name', label: 'Name' },\n { value: 'state', label: 'State' },\n ...(projects.length > 1 ? [{ value: 'project' as const, label: 'Project' }] : []),\n ...(gateways.length > 1 ? [{ value: 'gateway' as const, label: 'Gateway' }] : []),\n ]}\n onChange={(sortBy) => set({ sortBy: sortBy as SortBy })}\n />\n </FilterRow>\n </div>\n\n {subset ? (\n <div className=\"flex items-center gap-2 px-3 text-label text-fg-4\">\n <span>\n {subset.shown} of {subset.total}\n {subset.causes.length ? ` · ${subset.causes.join(' · ')}` : null}\n </span>\n <button\n type=\"button\"\n className=\"text-fg-3 underline underline-offset-2 hover:text-fg-1\"\n onClick={() => onConfigChange(clearFilters(config))}\n >\n Show all\n </button>\n </div>\n ) : null}\n\n {rows.length === 0 ? (\n (emptyState ?? <Empty icon={<Layers />} title=\"No sessions yet\" />)\n ) : visible.length === 0 ? (\n hasFacetFilter(config) ? (\n <Empty\n icon={<SearchX />}\n title=\"No matches\"\n description=\"No session matches the current search and filters.\"\n action=\"Clear filters\"\n onAction={() => onConfigChange(clearFilters(config))}\n />\n ) : (\n <Empty icon={<Layers />} title=\"Nothing here\" description=\"No session to show.\" />\n )\n ) : (\n <div className=\"flex flex-col gap-4 px-1\">\n {groups.map((group) => (\n <div key={group.key} className=\"flex flex-col gap-1\">\n {config.groupBy !== 'none' && group.label ? (\n <div className=\"flex items-center gap-2 px-2 text-label font-medium text-fg-4\">\n {config.groupBy === 'project' ? (\n <ProjectIcon icon={group.rows[0]?.info.project?.icon} src={iconSrcOf(group.rows[0], projectIcons)} name={group.label} />\n ) : null}\n <span className=\"uppercase tracking-wide\">{group.label}</span>\n <span className=\"text-fg-4/70\">{group.rows.length}</span>\n </div>\n ) : null}\n {group.rows.map((row) => (\n <SessionRowItem\n key={`${row.hostId}:${row.info.id}`}\n row={row}\n active={row.info.id === activeId}\n activeSubagentId={activeSubagentId}\n showGateway={gateways.length > 1 && config.groupBy !== 'gateway'}\n showProject={config.groupBy !== 'project'}\n projectIcons={projectIcons}\n onSelect={onSelect}\n onDelete={onDelete}\n onRename={onRename}\n onClearContext={onClearContext}\n onSelectSubagent={onSelectSubagent}\n onRevealStep={onRevealStep}\n />\n ))}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nfunction iconSrcOf(row: SessionRow | undefined, icons: Record<string, string> | undefined): string | undefined {\n const icon = row?.info.project?.icon\n return icon?.type === 'image' ? icons?.[icon.hash] : undefined\n}\n\ninterface SessionRowItemProps {\n row: SessionRow\n active?: boolean\n activeSubagentId?: string\n showGateway?: boolean\n showProject?: boolean\n projectIcons?: Record<string, string>\n onSelect?: (row: SessionRow) => void\n onDelete?: (row: SessionRow) => void\n onRename?: (row: SessionRow, title: string) => void\n onClearContext?: (row: SessionRow) => void\n onSelectSubagent?: (row: SessionRow, toolUseId: string) => void\n onRevealStep?: (row: SessionRow, toolUseId: string) => void\n}\n\nfunction SessionRowItem({\n row,\n active,\n activeSubagentId,\n showGateway,\n showProject = true,\n projectIcons,\n onSelect,\n onDelete,\n onRename,\n onClearContext,\n onSelectSubagent,\n onRevealStep,\n}: SessionRowItemProps) {\n const { info } = row\n const [editing, setEditing] = useState(false)\n\n return (\n <SessionItem\n row={row}\n active={active === true}\n activeStepKey={activeSubagentId}\n showGateway={showGateway}\n showProject={showProject}\n projectIcons={projectIcons}\n onSelect={() => onSelect?.(row)}\n onSelectSubagent={onSelectSubagent ? (id) => onSelectSubagent(row, id) : undefined}\n onRevealStep={onRevealStep ? (id) => onRevealStep(row, id) : undefined}\n onRename={onRename ? (title) => onRename(row, title) : undefined}\n renameOn=\"external\"\n editing={editing}\n onEditingChange={setEditing}\n actions={\n <>\n {onRename && !editing ? (\n <RowAction label=\"Rename session\" onClick={() => setEditing(true)}>\n <Pencil className=\"size-3 text-fg-3\" />\n </RowAction>\n ) : null}\n {onClearContext && info.capabilities?.clearContext ? (\n <RowAction\n label=\"Clear context\"\n title=\"Clear the conversation — the session keeps running and the old conversation stays resumable\"\n onClick={() => onClearContext(row)}\n >\n <Eraser className=\"size-3 text-fg-3\" />\n </RowAction>\n ) : null}\n {onDelete ? (\n <RowAction label=\"Close session\" onClick={() => onDelete(row)}>\n <Trash2 className=\"size-3 text-fg-3\" />\n </RowAction>\n ) : null}\n </>\n }\n />\n )\n}\n\nfunction RowAction({ label, title, onClick, children }: { label: string; title?: string; onClick: () => void; children: ReactNode }) {\n return (\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={label}\n title={title ?? label}\n className=\"size-5 shrink-0 opacity-0 transition-opacity group-hover:opacity-100\"\n onClick={(e) => {\n e.stopPropagation()\n onClick()\n }}\n >\n {children}\n </Button>\n )\n}\n\nfunction FilterRow({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2\">\n <span aria-hidden className=\"w-14 shrink-0 truncate text-label text-fg-3\">\n {label}\n </span>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n )\n}\n\nfunction FacetSelect({\n label,\n value,\n options,\n onChange,\n}: {\n label: string\n value: string[]\n options: { value: string; label: string }[]\n onChange: (value: string[]) => void\n}) {\n return (\n <div className=\"flex items-center gap-1\">\n <Select multiple value={value} onValueChange={(v) => onChange(v as string[])}>\n <SelectTrigger aria-label={label} className=\"min-w-0 flex-1\">\n <SelectValue>\n {value.length === 0\n ? 'All'\n : value.length === 1\n ? (options.find((o) => o.value === value[0])?.label ?? 'All')\n : `${value.length} selected`}\n </SelectValue>\n </SelectTrigger>\n <SelectContent>\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n <SelectItemText>{option.label}</SelectItemText>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {value.length > 0 ? (\n <Button variant=\"ghost\" size=\"icon-sm\" aria-label={`Clear ${label}`} onClick={() => onChange([])}>\n <X className=\"size-3 text-fg-4\" />\n </Button>\n ) : null}\n </div>\n )\n}\n\nfunction OneOfSelect({\n label,\n value,\n options,\n onChange,\n}: {\n label: string\n value: string\n options: readonly { value: string; label: string }[]\n onChange: (value: string) => void\n}) {\n return (\n <Select value={value} onValueChange={(v) => onChange(v as string)}>\n <SelectTrigger aria-label={label} className=\"w-full min-w-0\">\n <SelectValue>{options.find((o) => o.value === value)?.label ?? label}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n <SelectItemText>{option.label}</SelectItemText>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n"],"mappings":";;;;;;;;;AAGA,SAAgB,KAAK,EAAE,WAAW,GAAG,SAAyC;AAC5E,QAAO,oBAAC,OAAD;EAAK,aAAU;EAAO,WAAW,GAAG,8CAA8C,UAAU;EAAE,GAAI;EAAS,CAAA;;AAGpH,SAAgB,WAAW,EAAE,WAAW,GAAG,SAAyC;AAClF,QAAO,oBAAC,OAAD;EAAK,WAAW,GAAG,2DAA2D,UAAU;EAAE,GAAI;EAAS,CAAA;;AAGhH,SAAgB,UAAU,EAAE,WAAW,GAAG,SAA6C;AACrF,QAAO,oBAAC,MAAD;EAAI,WAAW,GAAG,0CAA0C,UAAU;EAAE,GAAI;EAAS,CAAA;;AAG9F,SAAgB,YAAY,EAAE,WAAW,GAAG,SAAyC;AACnF,QAAO,oBAAC,OAAD;EAAK,WAAW,GAAG,aAAa,UAAU;EAAE,GAAI;EAAS,CAAA;;;;ACblE,MAAa,WAAW,YAA8E,EAAE,WAAW,GAAG,SAAS,QAC7H,oBAAC,YAAD;CACO;CACL,aAAU;CACV,WAAW,GACT,+FACA,wDACA,wGACA,oDACA,UACD;CACD,GAAI;CACJ,CAAA,CACF;AACF,SAAS,cAAc;;;ACZvB,MAAa,cAAcA,cAAqB;AAChD,MAAa,qBAAqBA,cAAqB;AACvD,MAAa,mBAAmBA,cAAqB;AAErD,MAAa,sBAA2E,EAAE,WAAW,UAAU,GAAG,YAChH,oBAACA,cAAqB,QAAtB,EAAA,UACE,qBAAC,aAAD,EAAA,UAAA,CACE,oBAACA,cAAqB,UAAtB,EACE,WAAW,GACT,sDACA,+CACA,4DACD,EACD,CAAA,EACF,oBAACA,cAAqB,OAAtB;CACE,aAAU;CACV,WAAW,GACT,iGACA,oFACA,2DACA,8DACA,0DACA,UACD;CACD,GAAI;CAEH;CAC0B,CAAA,CACjB,EAAA,CAAA,EACc,CAAA;AAGhC,MAAa,oBAAyE,EAAE,WAAW,GAAG,YACpG,oBAACA,cAAqB,OAAtB;CAA4B,WAAW,GAAG,0CAA0C,UAAU;CAAE,GAAI;CAAS,CAAA;AAG/G,MAAa,0BAAqF,EAAE,WAAW,GAAG,YAChH,oBAACA,cAAqB,aAAtB;CAAkC,WAAW,GAAG,6CAA6C,UAAU;CAAE,GAAI;CAAS,CAAA;;;ACtCxH,SAAgB,UAAU;AACxB,QACE,oBAACC,WAAD;EACE,UAAS;EACT,cAAc,EACZ,OAAO;GACL,YAAY;GACZ,OAAO;GACP,QAAQ;GACR,WAAW;GACX,YAAY;GACZ,UAAU;GACX,EACF;EACD,CAAA;;;;ACfN,SAAgB,MAAM,EACpB,MACA,OACA,aACA,QACA,YAOC;AACD,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,oBAAC,OAAD;IAAK,WAAU;cAAuC;IAAW,CAAA;GACjE,oBAAC,KAAD;IAAG,WAAU;cAAsC;IAAU,CAAA;GAC5D,cAAc,oBAAC,KAAD;IAAG,WAAU;cAAkE;IAAgB,CAAA,GAAG;GAChH,UAAU,WACT,oBAAC,QAAD;IAAQ,SAAQ;IAAU,MAAK;IAAK,WAAU;IAAO,SAAS;cAC3D;IACM,CAAA,GACP;GACA;;;AAIV,SAAgB,SAAS,EAAE,YAAqC;AAC9D,QAAO,oBAAC,QAAD;EAAM,WAAU;EAAyD;EAAgB,CAAA;;;;;ACElG,SAAgB,gBAAgB,UAA8B;AAC5D,KAAI,SAAS,WAAW,EACtB,QAAO;AAET,QAAO,SAAS,OAAO,QAAQ,IAAI,SAAS,UAAU,IAAI,KAAK,MAAM,KAAK,GAAG;;;AAc/E,SAAgB,kBAAkB,UAAqB,SAAgC;AACrF,QAAO,SAAS,QAAQ,QAA4B,IAAI,SAAS,UAAU,IAAI,YAAY,QAAQ;;;;ACtCrG,MAAM,gBAA8C;CAClD,MAAM;CACN,SAAS;CACT,OAAO;CACR;AAYD,SAAS,QAAQ,EAAE,MAAM,SAAS,OAAO,YAA8F;AACrI,KAAI,CAAC,QACH,QAAO,oBAAC,KAAD;EAAW;EAAO;EAAe,CAAA;AAE1C,QACE,oBAAC,UAAD;EAAQ,MAAK;EAAS,WAAU;EAAe,SAAS;EAAS,OAAO;YACtE,oBAAC,KAAD;GAAW;GAAO;GAAe,CAAA;EAC1B,CAAA;;AAIb,SAAgB,mBAAmB,EACjC,WACA,OACA,YACA,YACA,cACA,eACA,eAC0B;CAC1B,MAAM,eAAe,mBAAmB;EAAE,QAAQ,MAAM;EAAQ;EAAY,CAAC;CAC7E,MAAM,QAAQ,MAAM;CACpB,MAAM,SAAS,eAAe,cAAc,MAAM,WAAW;CAC7D,MAAM,QAAQ,WAAW;EAAE,OAAO,MAAM;EAAO,QAAQ,MAAM,UAAU,EAAE;EAAE,CAAC;CAE5E,MAAM,QAA2B,CAC/B,oBAAC,SAAD;EAAsB,MAAM,cAAc,aAAa;EAAW,SAAS;EAAc,OAAM;YAC5F,aAAa;EACN,EAFG,SAEH,CACX;AAED,KAAI,MACF,OAAM,KACJ,qBAAC,SAAD;EAAuB,MAAM,cAAc,gBAAgB,MAAM;EAAG,SAAS;EAAe,OAAM;YAAlG;GACG,KAAK,MAAM,MAAM,WAAW;GAAC;GAAQ,aAAa,MAAM,YAAY;GAAC;GAC9D;IAFG,UAEH,CACX;AAGH,KAAI,OACF,OAAM,KACJ,qBAAC,SAAD;EAAqB,MAAM,cAAc,cAAc,OAAO,KAAK,YAAY;EAAG,SAAS;EAAa,OAAM;YAA9G;GACG,KAAK,MAAM,OAAO,KAAK,eAAe,EAAE;GAAC;GAAG,YAAY,OAAO,IAAI;GAC5D;IAFG,QAEH,CACX;AAGH,KAAI,MAAM,eAAe,EACvB,OAAM,KACJ,oBAAC,KAAD;EAAgB,MAAK;YAClB,WAAW,MAAM,aAAa;EAC3B,EAFG,OAEH,CACP;AAGH,KAAI,MACF,OAAM,KACJ,oBAAC,KAAD;EAAiB,MAAK;YACnB;EACG,EAFG,QAEH,CACP;AAEH,KAAI,MAAM,kBAAkB,MAAM,mBAAmB,UACnD,OAAM,KACJ,oBAAC,KAAD;EAAgB,MAAK;YAClB,MAAM;EACH,EAFG,OAEH,CACP;AAGH,QACE,oBAAC,KAAD;EAAK,aAAU;EAAc,MAAK;EAAiB;YAChD,MAAM,KAAK,MAAM,UAChB,qBAAC,QAAD,EAAA,UAAA,CACG,QAAQ,IAAI,oBAAC,KAAD;GAAK,MAAK;aAAQ;GAAS,CAAA,GAAG,MAC1C,KACI,EAAA,EAHI,MAGJ,CACP;EACE,CAAA;;;;AC5FV,SAAgB,gBAAgB,EAAE,SAAS,QAAQ,UAAU,UAAU,aAAmC;CACxG,MAAM,OAAO,YAAY,QAAQ;AACjC,QACE,qBAAC,OAAD;EACE,aAAU;EACV,eAAa,UAAU,KAAA;EACvB,WAAW,GACT,qHACA,SAAS,6BAA6B,0BACtC,UACD;YAPH,CASE,qBAAC,UAAD;GAAQ,MAAK;GAAS,eAAe,WAAW,QAAQ,GAAG;GAAE,WAAU;aAAvE,CACE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,QAAD;KAAM,WAAU;eAA+C,QAAQ,SAAS,QAAQ,GAAG,MAAM,GAAG,EAAE;KAAQ,CAAA,EAC9G,oBAAC,OAAD;KAAO,SAAS,KAAK;KAAS,KAAA;KAAI,WAAU;eACzC,KAAK;KACA,CAAA,CACJ;OACN,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAAC,QAAD;MAAM,WAAU;gBAAY,QAAQ;MAAW,CAAA;KAC9C,QAAQ,UAAU,qBAAC,QAAD;MAAM,WAAU;gBAAhB,CAA2B,KAAE,QAAQ,QAAe;UAAG;KAC1E,oBAAC,QAAD;MAAM,WAAU;gBAAY,WAAW,QAAQ,aAAa;MAAQ,CAAA;KACpE,oBAAC,QAAD;MAAM,WAAU;gBAAY,mBAAmB,QAAQ,kBAAkB,QAAQ,UAAU;MAAQ,CAAA;KAC/F;MACC;MACR,WACC,oBAAC,QAAD;GACE,SAAQ;GACR,MAAK;GACL,cAAW;GACX,WAAU;GACV,eAAe,SAAS,QAAQ,GAAG;aAEnC,oBAAC,QAAD,EAAQ,WAAU,sBAAuB,CAAA;GAClC,CAAA,GACP,KACA;;;AAaV,SAAgB,YAAY,EAAE,UAAU,UAAU,UAAU,UAAU,YAAY,oBAAoB,aAA+B;AACnI,QACE,oBAAC,OAAD;EAAK,aAAU;EAAe,WAAW,GAAG,uBAAuB,UAAU;YAC1E,SAAS,WAAW,IACnB,oBAAC,OAAD;GAAK,WAAU;aAAkD;GAAgB,CAAA,GAEjF,SAAS,KAAK,YACZ,oBAAC,iBAAD;GAA2C;GAAS,QAAQ,QAAQ,OAAO;GAAoB;GAAoB;GAAY,EAAzG,QAAQ,GAAiG,CAC/H;EAEA,CAAA;;;;ACyCV,MAAM,SAAgE;CACpE,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,KAAK;CACL,KAAK;CACL,OAAO;CACP,WAAW;CACX,OAAO;CACP,KAAK;CACL,cAAc;CACd,OAAO;CACP,QAAQ;CACR,KAAK;CACL,KAAK;CACL,iBAAiB;CACjB,OAAO;CACP,MAAM;CACN,QAAQ;CACR,KAAK;CACL,SAAS;CACT,WAAW;CACX,KAAK;CACL,eAAe;CACf,UAAU;CACV,SAAS;CACT,KAAK;CACL,SAAS;CACT,MAAM;CACN,OAAO;CACP,iBAAiB;CACjB,QAAQ;CACR,aAAa;CACb,OAAO;CACP,KAAK;CACL,OAAO;CACP,MAAM;CACN,cAAc;CACd,OAAO;CACP,kBAAkB;CAClB,QAAQ;CACR,SAAS;CACT,OAAO;CACP,OAAO;CACP,KAAK;CACL,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,SAAS;CACT,WAAW;CACX,MAAM;CACN,MAAM;CACN,KAAKC;CACL,kBAAkB;CAClB,KAAK;CACL,SAAS;CACT,MAAM;CACN,UAAU;CACV,OAAO;CACP,SAAS;CACT,WAAW;CACX,UAAU;CACV,OAAO;CACP,SAAS;CACT,SAAS;CACT,YAAY;CACZ,OAAO;CACP,cAAc;CACd,OAAO;CACP,MAAM;CACN,QAAQ;CACR,OAAO;CACP,OAAO;CACP,SAAS;CACT,QAAQ;CACR,OAAO;CACP,WAAW;CACX,OAAO;CACP,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,iBAAiB;CACjB,QAAQ;CACR,YAAY;CACZ,UAAU;CACV,QAAQ;CACR,QAAQ;CACR,MAAM;CACN,KAAK;CACL,OAAO;CACP,KAAK;CACL,QAAQ;CACR,WAAW;CACX,UAAU;CACV,aAAa;CACb,aAAa;CACb,QAAQ;CACR,OAAO;CACP,UAAU;CACV,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACP,SAAS;CACT,MAAM;CACN,QAAQ;CACR,KAAK;CACN;AAED,SAAgB,YAAY,EAC1B,MACA,KACA,MACA,aAMC;AACD,KAAI,CAAC,KACH,QAAO;AAET,KAAI,KAAK,SAAS,SAAS;AACzB,MAAI,CAAC,IACH,QAAO;AAET,SAAO,oBAAC,OAAD;GAAU;GAAK,KAAI;GAAG,eAAA;GAAY,OAAO;GAAM,WAAW,GAAG,+CAA+C,UAAU;GAAI,CAAA;;AAGnI,QAAO,oBADO,OAAO,KAAK,SAAS,QAC5B,EAAO,WAAW,GAAG,gCAAgC,UAAU,EAAI,CAAA;;;;ACtP5E,SAAgB,YAAY,EAAE,OAAO,OAAO,IAAI,aAAuF;AACrI,KAAI,UAAU,KAAA,EACZ,QAAO;AAET,QACE,oBAAC,QAAD;EACE,OAAO,WAAW,MAAM,WAAW,QAAQ,EAAE,CAAC,MAAM,aAAa,MAAM,YAAY,CAAC,KAAK,aAAa,MAAM,UAAU;EACtH,WAAW,GAAG,yBAAyB,gBAAgB,MAAM,WAAW,EAAE,UAAU;YAEpF,oBAAC,cAAD;GAAc,OAAO,MAAM;GAAkB;GAAM,aAAa;GAAK,CAAA;EAChE,CAAA;;;;ACbX,MAAM,QAAsD;CAC1D,QAAQ;EACN,OAAO;EACP,GAAG;EACJ;CACD,OAAO;EACL,OAAO;EACP,GAAG;EACJ;CACD,QAAQ;EACN,OAAO;EACP,GAAG;EACJ;CACD,UAAU;EACR,OAAO;EACP,GAAG;EACJ;CACD,UAAU;EACR,OAAO;EACP,GAAG;EACJ;CACF;AAED,SAAgB,WAAW,QAAgB,OAAoC;AAC7E,KAAI,WAAW,SACb,QAAO;AAET,KAAI,WAAW,QACb,QAAO;CAET,MAAM,KAAK,OAAO,aAAa,IAAI;AACnC,KAAI,CAAC,GACH;AAEF,KAAI,GAAG,SAAS,SAAS,CACvB,QAAO;AAET,KAAI,GAAG,SAAS,WAAW,CACzB,QAAO;AAET,KAAI,GAAG,SAAS,WAAW,IAAI,GAAG,SAAS,OAAO,CAChD,QAAO;AAET,KAAI,GAAG,SAAS,SAAS,CACvB,QAAO;AAET,KAAI,GAAG,WAAW,MAAM,IAAI,GAAG,WAAW,KAAK,IAAI,GAAG,WAAW,KAAK,IAAI,GAAG,SAAS,SAAS,CAC7F,QAAO;;AAKX,MAAM,cAAsC;CAC1C,QAAQ;CACR,OAAO;CACR;AACD,MAAM,cAAsC,EAC1C,QAAQ,sBACT;AAED,SAAgB,gBAAgB,QAAgB,OAAwB;AACtE,QAAO,YAAY,WAAW,QAAQ,MAAM,IAAI,OAAO;;AAGzD,SAAgB,gBAAgB,QAAgB,OAAwB;AACtE,QAAO,YAAY,WAAW,QAAQ,MAAM,IAAI,OAAO;;AAGzD,SAAgB,WAAW,EAAE,QAAQ,OAAO,aAAqE;CAC/G,MAAM,OAAO,MAAM,WAAW,QAAQ,MAAM,IAAI;AAChD,KAAI,CAAC,KACH,QACE,oBAAC,QAAD;EAAM,eAAA;EAAY,OAAO;EAAQ,WAAW,GAAG,sBAAsB,UAAU;YAAE;EAE1E,CAAA;AAGX,QACE,qBAAC,OAAD;EACE,SAAQ;EACR,MAAK;EACL,UAAS;EACT,MAAK;EACL,cAAY,KAAK;EACjB,WAAW,GAAG,6BAA6B,UAAU;YANvD,CAQE,oBAAC,SAAD,EAAA,UAAQ,KAAK,OAAc,CAAA,EAC3B,oBAAC,QAAD,EAAM,GAAG,KAAK,GAAK,CAAA,CACf;;;;;ACtFV,SAAgB,kBAAkB,EAAE,KAAK,aAAsD;CAC7F,MAAM,EAAE,SAAS;CACjB,MAAM,OAAO,GAAG,mBAAmB,UAAU;AAC7C,KAAI,IAAI,UAAU,YAChB,QAAO,oBAAC,UAAD,EAAU,WAAW,GAAG,MAAM,6BAA6B,EAAI,CAAA;AAExE,KAAI,IAAI,UAAU,UAChB,QAAO,oBAAC,SAAD,EAAS,WAAW,GAAG,MAAM,YAAY,EAAI,CAAA;AAEtD,SAAQ,KAAK,QAAb;EACE,KAAK,SACH,QAAO,oBAAC,aAAD,EAAa,WAAW,GAAG,MAAM,cAAc,EAAI,CAAA;EAE5D,KAAK,SACH,QAAO,oBAAC,aAAD,EAAa,WAAW,GAAG,MAAM,YAAY,EAAI,CAAA;EAE1D,KAAK,SACH,QAAO,oBAAC,aAAD,EAAa,WAAW,GAAG,MAAM,YAAY,EAAI,CAAA;EAE1D,QACE,QAAO,oBAAC,MAAD,EAAM,WAAW,GAAG,MAAM,YAAY,EAAI,CAAA;;;;;ACRvD,SAAgB,aAAa,MAAmB,UAAmE;CACjH,MAAM,SAAS,KAAK,aAAa,EAAE,EAAE,KAAK,QAAQ;EAChD,MAAM,OAAO,cAAc,IAAI,GAAI,UAAqB;AACxD,SAAO;GACL,KAAK,IAAI;GACT,OAAO,cAAc,IAAI;GACzB,MAAM;GACN;GACA,OAAO,UAAU,IAAI,OAAO;GAC5B,QAAQ,IAAI,YAAY,IAAI,OAAO,IAAI,UAAU,GAAG,KAAA;GACpD,OAAO,GAAG,cAAc,IAAI,CAAC,KAAK,IAAI,UAAU,OAAO,IAAI,cAAc,IAAI,KAAK;GAClF,gBAAgB,SAAS,IAAI,WAAW,KAAK;GAC9C;GACD;AACF,QAAO,CAAC,GAAG,MAAM,QAAQ,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,QAAQ,MAAM,EAAE,SAAS,OAAO,CAAC;;AAGhG,SAAS,UAAU,QAA+C;AAChE,SAAQ,QAAR;EACE,KAAK,UACH,QAAO;EAET,KAAK,SACH,QAAO;EAET,QACE,QAAO;;;AAKb,SAAgB,aAAa,OAAgC;AAC3D,QAAO,MAAM,QAAQ,MAAM,EAAE,UAAU,UAAU,CAAC;;AAGpD,SAAgB,WAAW,EACzB,UACA,SACA,OACA,MACA,YAOC;CACD,MAAM,QAAQ,UAAU,KAAK,UAAU,QAAQ,GAAG,QAAQ,GAAG,UAAU,OAAO,MAAM;CACpF,MAAM,QAAQ,UAAU,KAAK,UAAU,QAAQ,GAAG,QAAQ,MAAM,MAAM,GAAG,KAAK,aAAa,GAAG,MAAM,GAAG,OAAO,UAAU,IAAI,KAAK;CACjI,MAAM,UAAU,WAAW,cAAc;AACzC,QACE,qBAAC,UAAD;EACE,MAAK;EACL,iBAAe;EACf,cAAY,GAAG,WAAW,SAAS,OAAO,GAAG;EAC7C,OAAO,GAAG,WAAW,SAAS,OAAO,GAAG;EACxC,UAAU,MAAM;AACd,KAAE,iBAAiB;AACnB,aAAU;;EAEZ,WAAW,GACT,oFACA,+DACA,UAAU,IAAI,cAAc,YAC7B;YAbH,CAeE,oBAAC,SAAD,EAAS,WAAU,UAAW,CAAA,EAC9B,oBAAC,QAAD;GAAM,WAAU;aAAgB;GAAa,CAAA,CACtC;;;AAIb,SAAgB,QAAQ,EAAE,MAAM,SAAS,OAAO,YAAoE;CAClH,MAAM,QAAQ,KAAK,SAAS;CAC5B,MAAM,WAAW,UAAU;CAC3B,MAAM,OAAO,KAAK,UAAU,WAAW,gBAAgB,QAAQ,iBAAiB;AAChF,QACE,qBAAC,UAAD;EACE,MAAK;EACL,OAAO,KAAK;EACZ,gBAAc,YAAY,KAAA;EAC1B,UAAU,MAAM;AACd,KAAE,iBAAiB;AACnB,aAAU;;EAEZ,WAAW,GACT,qEACA,qCACA,WAAW,oBAAoB,uBAC/B,KACD;YAbH;GAeE,oBAAC,UAAD;IAAU,OAAO,KAAK;IAAO,MAAM,KAAK;IAAQ,CAAA;GAChD,oBAAC,QAAD;IAAM,WAAU;cAA2B,KAAK;IAAa,CAAA;GAC5D,KAAK,SAAS,oBAAC,QAAD;IAAM,WAAU;cAAmC,KAAK;IAAc,CAAA,GAAG;GACvF,QAAQ,oBAAC,YAAD,EAAY,WAAU,+BAAgC,CAAA,GAAG;GAC3D;;;AAIb,SAAS,SAAS,EAAE,OAAO,QAAsD;AAC/E,KAAI,SAAS,UAAU,UAAU,aAAa,UAAU,SACtD,QAAO,oBAAC,KAAD,EAAK,WAAU,wBAAyB,CAAA;AAEjD,SAAQ,OAAR;EACE,KAAK,UACH,QAAO,oBAAC,SAAD,EAAS,WAAU,wBAAyB,CAAA;EAErD,KAAK,SACH,QAAO,oBAAC,aAAD,EAAa,WAAU,wBAAyB,CAAA;EAEzD,KAAK,UACH,QAAO,oBAAC,aAAD,EAAa,WAAU,wBAAyB,CAAA;EAEzD,QACE,QAAO,oBAAC,OAAD,EAAO,WAAU,wBAAyB,CAAA;;;;;ACpGvD,SAAgB,YAAY,EAC1B,KACA,SAAS,OACT,eACA,aACA,cAAc,MACd,cACA,UACA,kBACA,UACA,kBACA,cACA,UACA,WAAW,eACX,SACA,iBACA,SACA,aACmB;CACnB,MAAM,EAAE,SAAS;CACjB,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;CACrD,MAAM,OAAO,YAAY;CACzB,MAAM,WAAW,SAAkB;AACjC,iBAAe,KAAK;AACpB,qBAAmB,KAAK;;CAE1B,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CACnD,MAAM,YAAY,WAAW;CAC7B,MAAM,cAAc,SAAkB;AACpC,gBAAc,KAAK;AACnB,oBAAkB,KAAK;;CAGzB,MAAM,SAAS,KAAK,UAAU;CAC9B,MAAM,UAAU,cAAc,aAAa,IAAI,GAAG,eAAe,IAAI;CACrE,MAAM,cAAc,cAAc,KAAK,SAAS,OAAO,KAAA;CACvD,MAAM,UAAU,aAAa,SAAS,UAAU,eAAe,YAAY,QAAQ,KAAA;CACnF,MAAM,OAAO,WAAW,KAAK,aAAa;CAC1C,MAAM,SAAS;EACb,cAAc,IAAI,WAAW,KAAA;EAC7B,KAAK,UAAU,IAAI,KAAK,YAAY,KAAA;EACpC,SAAS,MAAM,KAAA,IAAY;EAC5B,CAAC,QAAQ,SAAyB,QAAQ,KAAK,CAAC;CAEjD,MAAM,QAAQ,cAAc,KAAK,MAAM;CACvC,MAAM,QAAqB,EAAE;AAC7B,KAAI,MACF,OAAM,KACJ,oBAAC,QAAD;EAAkB,WAAW,gBAAgB,QAAQ,KAAK,MAAM;YAC7D;EACI,EAFG,QAEH,CACR;AAEH,KAAI,YAAY,KAAA,EACd,OAAM,KACJ,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,aAAD;EAAa,MAAM;EAAa,KAAK;EAAS,MAAM;EAAS,WAAU;EAAiC,CAAA,EACvG,QACI,EAAA,EAHG,UAGH,CACR;AAEH,MAAK,MAAM,SAAS,OAClB,OAAM,KAAK,oBAAC,QAAD,EAAA,UAAmB,OAAa,EAArB,MAAqB,CAAC;CAE9C,MAAM,QAAQ,aAAa,OAAO,WAAW,SAAS;AACpD,MAAI,SAAS,QACX,QAAO,mBAAmB,iBAAiB,UAAU,GAAG,YAAY;AAEtE,SAAO,eAAe,aAAa,UAAU,GAAG,YAAY;GAC5D;CACF,MAAM,iBAAiB,MAAM,MAAM,MAAM,EAAE,SAAS,WAAW,EAAE,QAAQ,cAAc;AAEvF,QACE,qBAAC,OAAD;EACE,aAAU;EACV,eAAa,UAAU,KAAA;EACvB,MAAK;EACL,UAAU;EACV,UAAU,MAAM;AACd,OAAI,EAAE,SAAS,KAAK,UAClB;AAEF,eAAY;;EAEd,YAAY,MAAM;AAChB,OAAI,EAAE,WAAW,EAAE,cACjB;AAEF,OAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,MAAE,gBAAgB;AAClB,gBAAY;;;EAGhB,WAAW,GACT,wEACA,gFACA,iBAAiB,yBAAyB,SAAS,oBAAoB,sBACvE,UACD;YAzBH,CA2BE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAAC,QAAD,EAAA,UACE,oBAAC,mBAAD,EAAwB,KAAO,CAAA,EACxB,CAAA;KACR,aAAa,WACZ,oBAAC,YAAD;MACE,SAAS,KAAK,SAAS;MACvB,WAAW,UAAU;AACnB,kBAAW,MAAM;AACjB,WAAI,WAAW,KAAK,SAAS,IAC3B,UAAS,MAAM;;MAGnB,gBAAgB,WAAW,MAAM;MACjC,CAAA,GAEF,oBAAC,QAAD;MACE,eACE,YAAY,aAAa,iBACpB,MAAM;AACL,SAAE,iBAAiB;AACnB,kBAAW,KAAK;UAElB,KAAA;MAEN,WAAU;gBAET,aAAa,KAAK;MACd,CAAA;KAER,IAAI,SAAS,IACZ,oBAAC,QAAD;MAEE,OAAO,GAAG,IAAI,OAAO,cAAc,IAAI,WAAW,IAAI,KAAK;MAC3D,WAAW,GACT,2EACA,gEACA,IAAI,UAAU,aAAa,IAAI,UAAU,cAAc,6BAA6B,yBACrF;gBAEA,IAAI;MACA,CAAA,GACL;KACJ,oBAAC,aAAD;MAAa,OAAO,KAAK;MAAc,MAAM;MAAI,WAAU;MAAU,CAAA;KACjE;OAEN,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAAC,QAAD,EAAA,UACE,oBAAC,YAAD;MAAoB;MAAQ,OAAO,KAAK;MAAO,WAAW,GAAG,UAAU,gBAAgB,QAAQ,KAAK,MAAM,CAAC;MAAI,CAAA,EACxG,CAAA;KACT,oBAAC,QAAD;MAAM,WAAU;gBACb,MAAM,KAAK,MAAM,MAChB,qBAAC,UAAD,EAAA,UAAA,CACG,IAAI,IAAI,QAAQ,IAChB,KACQ,EAAA,EAHI,EAGJ,CACX;MACG,CAAA;KACP,qBAAC,QAAD;MAAM,WAAU;gBAAhB,CACG,MAAM,SAAS,IAAI,OAAO,IAC1B,mBAAmB,KAAK,kBAAkB,KAAK,UAAU,CACrD;;KACP,oBAAC,QAAD,EAAM,WAAU,kBAAmB,CAAA;KAClC,MAAM,SAAS,IACd,oBAAC,YAAD;MACE,UAAU;MACV,SAAS,aAAa,MAAM;MAC5B,OAAO,MAAM;MACb,MAAM,MAAM,GAAI;MAChB,gBAAgB,QAAQ,CAAC,KAAK;MAC9B,CAAA,GACA;KACH;KACG;MACF;MAEL,QAAQ,MAAM,SAAS,IACtB,oBAAC,OAAD;GAAK,WAAU;aACZ,MAAM,KAAK,SACV,oBAAC,SAAD;IAA8B;IAAM,QAAQ,KAAK,QAAQ;IAAe,UAAU,KAAK;IAAY,EAArF,KAAK,IAAgF,CACnG;GACE,CAAA,GACJ,KACA;;;AAIV,SAAS,OAAO,EAAE,YAAqC;AACrD,QAAO,oBAAC,QAAD;EAAM,WAAU;EAAoD;EAAgB,CAAA;;AAG7F,SAAS,WAAW,EAAE,SAAS,UAAU,YAA0F;CACjI,MAAM,CAAC,OAAO,YAAY,SAAS,QAAQ;CAC3C,MAAM,MAAM,OAAyB,KAAK;AAC1C,iBAAgB;AACd,MAAI,SAAS,OAAO;AACpB,MAAI,SAAS,QAAQ;IACpB,EAAE,CAAC;AACN,iBAAgB;EACd,MAAM,sBAAsB;AAC1B,OAAI,SAAS,OAAO;AACpB,OAAI,SAAS,QAAQ;;AAEvB,SAAO,iBAAiB,SAAS,cAAc;AAC/C,eAAa,OAAO,oBAAoB,SAAS,cAAc;IAC9D,EAAE,CAAC;AACN,QACE,oBAAC,SAAD;EACO;EACE;EACP,YAAY;EACZ,aAAY;EACZ,cAAW;EACX,UAAU,MAAM,EAAE,iBAAiB;EACnC,gBAAgB,MAAM,EAAE,iBAAiB;EACzC,WAAW,MAAM,SAAS,EAAE,OAAO,MAAM;EACzC,cAAc;AAEZ,OAAI,SAAS,UAAU,CACrB,UAAS,MAAM,MAAM,CAAC;;EAG1B,YAAY,MAAM;AAChB,KAAE,iBAAiB;AACnB,OAAI,EAAE,QAAQ,QACZ,UAAS,MAAM,MAAM,CAAC;YACb,EAAE,QAAQ,SACnB,WAAU;;EAGd,WAAW,GACT,yEACA,gDACD;EACD,CAAA;;;;AChON,SAAgB,cAAc,QAAyB;AACrD,QAAO,GAAG,kCAAkC,SAAS,sDAAsD,kBAAkB;;AAG/H,SAAgB,eAAe,EAC7B,MACA,QACA,gBACA,OACA,UACA,kBACA,UACA,UACA,UACA,gBACA,kBACA,cACA,YACA,eAAe,MACf,cACA,aACsB;CACtB,MAAM,UAAU,cAAc,WAAW,MAAM,QAAQ,MAAM,EAAE;EAAC;EAAM;EAAQ;EAAM,CAAC;CACrF,MAAM,SAAS,cAAc,UAAU,SAAS,OAAO,EAAE,CAAC,SAAS,OAAO,CAAC;CAC3E,MAAM,SAAS,cAAc,QAAQ,OAAO,QAAQ,QAAQ,KAAK,OAAO;CACxE,MAAM,WAAW,cAAc,WAAW,KAAK,EAAE,CAAC,KAAK,CAAC;CACxD,MAAM,WAAW,cAAc,WAAW,KAAK,EAAE,CAAC,KAAK,CAAC;CACxD,MAAM,WAAW,cAAc;EAC7B,MAAM,uBAAO,IAAI,KAAqB;AACtC,OAAK,MAAM,OAAO,KAChB,MAAK,IAAI,IAAI,QAAQ,IAAI,SAAS;AAEpC,SAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,WAAW;GAAE;GAAI;GAAM,EAAE;IACnD,CAAC,KAAK,CAAC;CAEV,MAAM,OAAO,UAA+B,eAAe;EAAE,GAAG;EAAQ,GAAG;EAAO,CAAC;AAEnF,QACE,qBAAC,OAAD;EAAK,aAAU;EAAkB,WAAW,GAAG,uBAAuB,UAAU;YAAhF;GACE,qBAAC,OAAD;IAAK,WAAW,GAAG,8BAA8B,CAAC,gBAAgB,SAAS;cAA3E;KACE,qBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,oBAAC,QAAD,EAAQ,WAAU,qFAAsF,CAAA,EACxG,oBAAC,OAAD;OACE,OAAO,OAAO;OACd,WAAW,MAAM,IAAI,EAAE,QAAQ,EAAE,OAAO,OAAO,CAAC;OAChD,aAAY;OACZ,cAAW;OACX,WAAU;OACV,CAAA,CACE;;KACN,oBAAC,WAAD;MAAW,OAAM;gBACf,oBAAC,aAAD;OACE,OAAM;OACN,OAAO,OAAO;OACd,SAAS,YAAY,KAAK,OAAO;QAAE,OAAO;QAAG,OAAO,aAAa;QAAI,EAAE;OACvE,WAAW,WAAW,IAAI,EAAU,QAA0B,CAAC;OAC/D,CAAA;MACQ,CAAA;KACX,SAAS,SAAS,IACjB,oBAAC,WAAD;MAAW,OAAM;gBACf,oBAAC,aAAD;OACE,OAAM;OACN,OAAO,OAAO;OACd,SAAS,SAAS,KAAK,OAAO;QAAE,OAAO;QAAG,OAAO;QAAG,EAAE;OACtD,WAAW,aAAa,IAAI,EAAE,UAAU,CAAC;OACzC,CAAA;MACQ,CAAA,GACV;KACH,SAAS,SAAS,IACjB,oBAAC,WAAD;MAAW,OAAM;gBACf,oBAAC,aAAD;OACE,OAAM;OACN,OAAO,OAAO;OACd,SAAS,SAAS,KAAK,OAAO;QAAE,OAAO,EAAE;QAAI,OAAO,EAAE;QAAM,EAAE;OAC9D,WAAW,aAAa,IAAI,EAAE,UAAU,CAAC;OACzC,CAAA;MACQ,CAAA,GACV;KACH,SAAS,SAAS,IACjB,oBAAC,WAAD;MAAW,OAAM;gBACf,oBAAC,aAAD;OACE,OAAM;OACN,OAAO,OAAO,YAAY,EAAE;OAC5B,SAAS,SAAS,KAAK,OAAO;QAAE,OAAO,EAAE;QAAK,OAAO,EAAE;QAAO,EAAE;OAChE,WAAW,SAAS,IAAI,EAAE,UAAU,MAAM,CAAC;OAC3C,CAAA;MACQ,CAAA,GACV;KACJ,oBAAC,WAAD;MAAW,OAAM;gBACf,oBAAC,aAAD;OACE,OAAM;OACN,OAAO,OAAO;OACd,SAAS;QACP;SAAE,OAAO;SAAQ,OAAO;SAAe;QACvC;SAAE,OAAO;SAAS,OAAO;SAAY;QACrC;SAAE,OAAO;SAAW,OAAO;SAAa;QACxC,GAAI,SAAS,SAAS,IAAI,CAAC;SAAE,OAAO;SAAoB,OAAO;SAAc,CAAC,GAAG,EAAE;QACnF,GAAI,SAAS,SAAS,IAAI,CAAC;SAAE,OAAO;SAAoB,OAAO;SAAc,CAAC,GAAG,EAAE;QACpF;OACD,WAAW,YAAY,IAAI,EAAW,SAAoB,CAAC;OAC3D,CAAA;MACQ,CAAA;KACZ,oBAAC,WAAD;MAAW,OAAM;gBACf,oBAAC,aAAD;OACE,OAAM;OACN,OAAO,OAAO;OACd,SAAS;QACP;SAAE,OAAO;SAAU,OAAO;SAAU;QACpC;SAAE,OAAO;SAAQ,OAAO;SAAQ;QAChC;SAAE,OAAO;SAAS,OAAO;SAAS;QAClC,GAAI,SAAS,SAAS,IAAI,CAAC;SAAE,OAAO;SAAoB,OAAO;SAAW,CAAC,GAAG,EAAE;QAChF,GAAI,SAAS,SAAS,IAAI,CAAC;SAAE,OAAO;SAAoB,OAAO;SAAW,CAAC,GAAG,EAAE;QACjF;OACD,WAAW,WAAW,IAAI,EAAU,QAAkB,CAAC;OACvD,CAAA;MACQ,CAAA;KACR;;GAEL,SACC,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,qBAAC,QAAD,EAAA,UAAA;KACG,OAAO;KAAM;KAAK,OAAO;KACzB,OAAO,OAAO,SAAS,MAAM,OAAO,OAAO,KAAK,MAAM,KAAK;KACvD,EAAA,CAAA,EACP,oBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,eAAe,eAAe,aAAa,OAAO,CAAC;eACpD;KAEQ,CAAA,CACL;QACJ;GAEH,KAAK,WAAW,IACd,cAAc,oBAAC,OAAD;IAAO,MAAM,oBAAC,QAAD,EAAU,CAAA;IAAE,OAAM;IAAoB,CAAA,GAChE,QAAQ,WAAW,IACrB,eAAe,OAAO,GACpB,oBAAC,OAAD;IACE,MAAM,oBAAC,SAAD,EAAW,CAAA;IACjB,OAAM;IACN,aAAY;IACZ,QAAO;IACP,gBAAgB,eAAe,aAAa,OAAO,CAAC;IACpD,CAAA,GAEF,oBAAC,OAAD;IAAO,MAAM,oBAAC,QAAD,EAAU,CAAA;IAAE,OAAM;IAAe,aAAY;IAAwB,CAAA,GAGpF,oBAAC,OAAD;IAAK,WAAU;cACZ,OAAO,KAAK,UACX,qBAAC,OAAD;KAAqB,WAAU;eAA/B,CACG,OAAO,YAAY,UAAU,MAAM,QAClC,qBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,OAAO,YAAY,YAClB,oBAAC,aAAD;QAAa,MAAM,MAAM,KAAK,IAAI,KAAK,SAAS;QAAM,KAAK,UAAU,MAAM,KAAK,IAAI,aAAa;QAAE,MAAM,MAAM;QAAS,CAAA,GACtH;OACJ,oBAAC,QAAD;QAAM,WAAU;kBAA2B,MAAM;QAAa,CAAA;OAC9D,oBAAC,QAAD;QAAM,WAAU;kBAAgB,MAAM,KAAK;QAAc,CAAA;OACrD;UACJ,MACH,MAAM,KAAK,KAAK,QACf,oBAAC,gBAAD;MAEO;MACL,QAAQ,IAAI,KAAK,OAAO;MACN;MAClB,aAAa,SAAS,SAAS,KAAK,OAAO,YAAY;MACvD,aAAa,OAAO,YAAY;MAClB;MACJ;MACA;MACA;MACM;MACE;MACJ;MACd,EAbK,GAAG,IAAI,OAAO,GAAG,IAAI,KAAK,KAa/B,CACF,CACE;OA3BI,MAAM,IA2BV,CACN;IACE,CAAA;GAEJ;;;AAIV,SAAS,UAAU,KAA6B,OAA+D;CAC7G,MAAM,OAAO,KAAK,KAAK,SAAS;AAChC,QAAO,MAAM,SAAS,UAAU,QAAQ,KAAK,QAAQ,KAAA;;AAkBvD,SAAS,eAAe,EACtB,KACA,QACA,kBACA,aACA,cAAc,MACd,cACA,UACA,UACA,UACA,gBACA,kBACA,gBACsB;CACtB,MAAM,EAAE,SAAS;CACjB,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;AAE7C,QACE,oBAAC,aAAD;EACO;EACL,QAAQ,WAAW;EACnB,eAAe;EACF;EACA;EACC;EACd,gBAAgB,WAAW,IAAI;EAC/B,kBAAkB,oBAAoB,OAAO,iBAAiB,KAAK,GAAG,GAAG,KAAA;EACzE,cAAc,gBAAgB,OAAO,aAAa,KAAK,GAAG,GAAG,KAAA;EAC7D,UAAU,YAAY,UAAU,SAAS,KAAK,MAAM,GAAG,KAAA;EACvD,UAAS;EACA;EACT,iBAAiB;EACjB,SACE,qBAAA,YAAA,EAAA,UAAA;GACG,YAAY,CAAC,UACZ,oBAAC,WAAD;IAAW,OAAM;IAAiB,eAAe,WAAW,KAAK;cAC/D,oBAAC,QAAD,EAAQ,WAAU,oBAAqB,CAAA;IAC7B,CAAA,GACV;GACH,kBAAkB,KAAK,cAAc,eACpC,oBAAC,WAAD;IACE,OAAM;IACN,OAAM;IACN,eAAe,eAAe,IAAI;cAElC,oBAAC,QAAD,EAAQ,WAAU,oBAAqB,CAAA;IAC7B,CAAA,GACV;GACH,WACC,oBAAC,WAAD;IAAW,OAAM;IAAgB,eAAe,SAAS,IAAI;cAC3D,oBAAC,QAAD,EAAQ,WAAU,oBAAqB,CAAA;IAC7B,CAAA,GACV;GACH,EAAA,CAAA;EAEL,CAAA;;AAIN,SAAS,UAAU,EAAE,OAAO,OAAO,SAAS,YAAyF;AACnI,QACE,oBAAC,QAAD;EACE,SAAQ;EACR,MAAK;EACL,cAAY;EACZ,OAAO,SAAS;EAChB,WAAU;EACV,UAAU,MAAM;AACd,KAAE,iBAAiB;AACnB,YAAS;;EAGV;EACM,CAAA;;AAIb,SAAS,UAAU,EAAE,OAAO,YAA0D;AACpF,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,QAAD;GAAM,eAAA;GAAY,WAAU;aACzB;GACI,CAAA,EACP,oBAAC,OAAD;GAAK,WAAU;GAAkB;GAAe,CAAA,CAC5C;;;AAIV,SAAS,YAAY,EACnB,OACA,OACA,SACA,YAMC;AACD,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,qBAAC,QAAD;GAAQ,UAAA;GAAgB;GAAO,gBAAgB,MAAM,SAAS,EAAc;aAA5E,CACE,oBAAC,eAAD;IAAe,cAAY;IAAO,WAAU;cAC1C,oBAAC,aAAD,EAAA,UACG,MAAM,WAAW,IACd,QACA,MAAM,WAAW,IACd,QAAQ,MAAM,MAAM,EAAE,UAAU,MAAM,GAAG,EAAE,SAAS,QACrD,GAAG,MAAM,OAAO,YACV,CAAA;IACA,CAAA,EAChB,oBAAC,eAAD,EAAA,UACG,QAAQ,KAAK,WACZ,oBAAC,YAAD;IAA+B,OAAO,OAAO;cAC3C,oBAAC,gBAAD,EAAA,UAAiB,OAAO,OAAuB,CAAA;IACpC,EAFI,OAAO,MAEX,CACb,EACY,CAAA,CACT;MACR,MAAM,SAAS,IACd,oBAAC,QAAD;GAAQ,SAAQ;GAAQ,MAAK;GAAU,cAAY,SAAS;GAAS,eAAe,SAAS,EAAE,CAAC;aAC9F,oBAAC,GAAD,EAAG,WAAU,oBAAqB,CAAA;GAC3B,CAAA,GACP,KACA;;;AAIV,SAAS,YAAY,EACnB,OACA,OACA,SACA,YAMC;AACD,QACE,qBAAC,QAAD;EAAe;EAAO,gBAAgB,MAAM,SAAS,EAAY;YAAjE,CACE,oBAAC,eAAD;GAAe,cAAY;GAAO,WAAU;aAC1C,oBAAC,aAAD,EAAA,UAAc,QAAQ,MAAM,MAAM,EAAE,UAAU,MAAM,EAAE,SAAS,OAAoB,CAAA;GACrE,CAAA,EAChB,oBAAC,eAAD,EAAA,UACG,QAAQ,KAAK,WACZ,oBAAC,YAAD;GAA+B,OAAO,OAAO;aAC3C,oBAAC,gBAAD,EAAA,UAAiB,OAAO,OAAuB,CAAA;GACpC,EAFI,OAAO,MAEX,CACb,EACY,CAAA,CACT"}
1
+ {"version":3,"file":"index.mjs","names":["AlertDialogPrimitive","SonnerToaster","Map"],"sources":["../src/components/ui/Card.tsx","../src/components/ui/Textarea.tsx","../src/components/ui/AlertDialog.tsx","../src/components/ui/Sonner.tsx","../src/components/ui/Empty.tsx","../src/components/prompt-area/segment-helpers.ts","../src/components/terminal/StatusLine.tsx","../src/components/agent/SessionList.tsx","../src/components/agent/ProjectIcon.tsx","../src/components/agent/ContextRing.tsx","../src/components/agent/EngineIcon.tsx","../src/components/agent/SessionStatusIcon.tsx","../src/components/agent/SessionSteps.tsx","../src/components/agent/SessionItem.tsx","../src/components/agent/SessionBrowser.tsx"],"sourcesContent":["import { type HTMLAttributes } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nexport function Card({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div data-slot=\"card\" className={cn('rounded-lg border border-border bg-surface', className)} {...props} />\n}\n\nexport function CardHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex items-start justify-between gap-3 px-4 pt-3.5 pb-3', className)} {...props} />\n}\n\nexport function CardTitle({ className, ...props }: HTMLAttributes<HTMLHeadingElement>) {\n return <h3 className={cn('text-heading-3 font-semibold text-text', className)} {...props} />\n}\n\nexport function CardContent({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('px-4 pb-4', className)} {...props} />\n}\n","import { type TextareaHTMLAttributes, forwardRef } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaHTMLAttributes<HTMLTextAreaElement>>(({ className, ...props }, ref) => (\n <textarea\n ref={ref}\n data-slot=\"textarea\"\n className={cn(\n 'w-full resize-none rounded-md border border-border bg-bg px-2.5 py-2 text-body-sm text-text',\n 'placeholder:text-fg-4 transition-colors outline-none',\n 'hover:border-border-strong focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40',\n 'disabled:pointer-events-none disabled:opacity-50',\n className,\n )}\n {...props}\n />\n))\nTextarea.displayName = 'Textarea'\n","import { type FunctionComponent } from 'react'\nimport { AlertDialog as AlertDialogPrimitive } from '@base-ui/react/alert-dialog'\nimport { cn } from '../../lib/utils.ts'\nimport { PortalScope } from './PortalScope.tsx'\n\nexport const AlertDialog = AlertDialogPrimitive.Root\nexport const AlertDialogTrigger = AlertDialogPrimitive.Trigger\nexport const AlertDialogClose = AlertDialogPrimitive.Close\n\nexport const AlertDialogContent: FunctionComponent<AlertDialogPrimitive.Popup.Props> = ({ className, children, ...props }) => (\n <AlertDialogPrimitive.Portal>\n <PortalScope>\n <AlertDialogPrimitive.Backdrop\n className={cn(\n 'fixed inset-0 z-70 bg-black/40 backdrop-blur-[1px]',\n 'transition-opacity duration-(--motion-base)',\n 'data-starting-style:opacity-0 data-ending-style:opacity-0',\n )}\n />\n <AlertDialogPrimitive.Popup\n data-slot=\"alert-dialog-content\"\n className={cn(\n 'fixed top-1/2 left-1/2 z-70 w-[min(28rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2',\n 'rounded-lg border border-border bg-surface p-5 shadow-(--shadow-lg) outline-none',\n 'transition-[opacity,transform] duration-(--motion-base)',\n 'data-starting-style:scale-95 data-starting-style:opacity-0',\n 'data-ending-style:scale-95 data-ending-style:opacity-0',\n className,\n )}\n {...props}\n >\n {children}\n </AlertDialogPrimitive.Popup>\n </PortalScope>\n </AlertDialogPrimitive.Portal>\n)\n\nexport const AlertDialogTitle: FunctionComponent<AlertDialogPrimitive.Title.Props> = ({ className, ...props }) => (\n <AlertDialogPrimitive.Title className={cn('text-heading-3 font-semibold text-text', className)} {...props} />\n)\n\nexport const AlertDialogDescription: FunctionComponent<AlertDialogPrimitive.Description.Props> = ({ className, ...props }) => (\n <AlertDialogPrimitive.Description className={cn('mt-1.5 text-body-sm text-muted-foreground', className)} {...props} />\n)\n","import { Toaster as SonnerToaster, toast } from 'sonner'\n\nexport { toast }\n\nexport function Toaster() {\n return (\n <SonnerToaster\n position=\"bottom-right\"\n toastOptions={{\n style: {\n background: 'var(--surface)',\n color: 'var(--text)',\n border: '1px solid var(--border)',\n boxShadow: 'var(--shadow-md)',\n fontFamily: 'var(--cw-font-sans)',\n fontSize: 'var(--text-body-sm)',\n },\n }}\n />\n )\n}\n","import type { ReactNode } from 'react'\nimport { Button } from './Button.tsx'\n\nexport function Empty({\n icon,\n title,\n description,\n action,\n onAction,\n}: {\n icon: ReactNode\n title: string\n description?: ReactNode\n action?: string\n onAction?: () => void\n}) {\n return (\n <div className=\"flex flex-col items-center gap-2 px-5 py-8 text-center\">\n <div className=\"text-fg-4 opacity-60 [&_svg]:size-7\">{icon}</div>\n <p className=\"text-body-sm font-medium text-fg-2\">{title}</p>\n {description ? <p className=\"max-w-[26ch] text-balance text-label leading-relaxed text-fg-4\">{description}</p> : null}\n {action && onAction ? (\n <Button variant=\"outline\" size=\"sm\" className=\"mt-1\" onClick={onAction}>\n {action}\n </Button>\n ) : null}\n </div>\n )\n}\n\nexport function EmptyKey({ children }: { children: ReactNode }) {\n return <span className=\"rounded border border-border px-1 font-mono text-fg-3\">{children}</span>\n}\n","/**\n * Convenience helpers for creating and inspecting Segments.\n *\n * These reduce boilerplate when building AI chat UIs that work with the\n * PromptArea document model.\n *\n * @example\n * ```ts\n * import { text, chip, isSegmentsEmpty, segmentsToPlainText } from './segment-helpers.ts'\n *\n * const greeting = [text('Hello '), chip({ trigger: '@', value: 'u1', displayText: 'Alice' })]\n * isSegmentsEmpty(greeting) // false\n * segmentsToPlainText(greeting) // \"Hello @Alice\"\n * ```\n */\n\nimport type { Segment, TextSegment, ChipSegment } from './types.ts'\nimport { segmentsToPlainText, plainTextToSegments } from './prompt-area-engine.ts'\n\n// Re-export serialization utilities so consumers have a single import.\nexport { segmentsToPlainText, plainTextToSegments }\n\n/** Create a text segment. */\nexport function text(value: string): TextSegment {\n return { type: 'text', text: value }\n}\n\n/** Create a chip segment. */\nexport function chip(opts: Omit<ChipSegment, 'type'>): ChipSegment {\n return { type: 'chip', ...opts }\n}\n\n/** Returns `true` when the segment array is empty or contains only whitespace text. */\nexport function isSegmentsEmpty(segments: Segment[]): boolean {\n if (segments.length === 0) {\n return true\n }\n return segments.every((seg) => seg.type === 'text' && seg.text.trim() === '')\n}\n\n/** Returns `true` when the segment array contains at least one chip. */\nexport function hasChips(segments: Segment[]): boolean {\n return segments.some((seg) => seg.type === 'chip')\n}\n\n/** Extracts all chip segments from a segment array. */\nexport function getChips(segments: Segment[]): ChipSegment[] {\n return segments.filter((seg): seg is ChipSegment => seg.type === 'chip')\n}\n\n/** Extracts chips matching a specific trigger character. */\nexport function getChipsByTrigger(segments: Segment[], trigger: string): ChipSegment[] {\n return segments.filter((seg): seg is ChipSegment => seg.type === 'chip' && seg.trigger === trigger)\n}\n","import type { RateLimitInfo } from '@workerdeck/protocol'\nimport type { ConnectionState, TranscriptState } from '@workerdeck/react'\nimport { formatCost, formatTokens } from '../../lib/format.ts'\nimport {\n contextSeverity,\n meterSeverity,\n modelLabel,\n statusPresentation,\n tightestWindow,\n windowLabel,\n type StatusSeverity,\n} from '../../lib/status.ts'\nimport { Ink, Row, type Tone } from './row.tsx'\n\nconst SEVERITY_TONE: Record<StatusSeverity, Tone> = {\n none: 'dim',\n warning: 'yellow',\n error: 'red',\n}\n\nexport interface TerminalStatusLineProps {\n className?: string\n state: TranscriptState\n rateLimits?: Record<string, RateLimitInfo>\n connection?: ConnectionState\n onOpenStatus?: () => void\n onOpenContext?: () => void\n onOpenUsage?: () => void\n}\n\nfunction Reading({ tone, onPress, label, children }: { tone?: Tone; onPress?: () => void; label?: string; children: React.ReactNode }) {\n if (!onPress) {\n return <Ink tone={tone}>{children}</Ink>\n }\n return (\n <button type=\"button\" className=\"term-reading\" onClick={onPress} title={label}>\n <Ink tone={tone}>{children}</Ink>\n </button>\n )\n}\n\nexport function TerminalStatusLine({\n className,\n state,\n rateLimits,\n connection,\n onOpenStatus,\n onOpenContext,\n onOpenUsage,\n}: TerminalStatusLineProps) {\n const presentation = statusPresentation({ status: state.status, connection })\n const usage = state.contextUsage\n const window = tightestWindow(rateLimits ?? state.rateLimits)\n const model = modelLabel({ model: state.model, models: state.models ?? [] })\n\n const parts: React.ReactNode[] = [\n <Reading key=\"status\" tone={SEVERITY_TONE[presentation.severity]} onPress={onOpenStatus} label=\"Session status\">\n {presentation.label}\n </Reading>,\n ]\n\n if (usage) {\n parts.push(\n <Reading key=\"context\" tone={SEVERITY_TONE[contextSeverity(usage)]} onPress={onOpenContext} label=\"Context window\">\n {Math.round(usage.percentage)}% ctx ({formatTokens(usage.totalTokens)})\n </Reading>,\n )\n }\n\n if (window) {\n parts.push(\n <Reading key=\"usage\" tone={SEVERITY_TONE[meterSeverity(window.info.utilization)]} onPress={onOpenUsage} label=\"Plan usage\">\n {Math.round(window.info.utilization ?? 0)}% {windowLabel(window.key)}\n </Reading>,\n )\n }\n\n if (state.totalCostUsd > 0) {\n parts.push(\n <Ink key=\"cost\" tone=\"faint\">\n {formatCost(state.totalCostUsd)}\n </Ink>,\n )\n }\n\n if (model) {\n parts.push(\n <Ink key=\"model\" tone=\"faint\">\n {model}\n </Ink>,\n )\n }\n if (state.permissionMode && state.permissionMode !== 'default') {\n parts.push(\n <Ink key=\"mode\" tone=\"yellow\">\n {state.permissionMode}\n </Ink>,\n )\n }\n\n return (\n <Row data-slot=\"status-line\" tone=\"dim\" className={className}>\n {parts.map((part, index) => (\n <span key={index}>\n {index > 0 ? <Ink tone=\"faint\"> · </Ink> : null}\n {part}\n </span>\n ))}\n </Row>\n )\n}\n","import type { SessionInfo } from '@workerdeck/protocol'\nimport { Trash2 } from 'lucide-react'\nimport { Badge } from '../ui/Badge.tsx'\nimport { Button } from '../ui/Button.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { formatCost, formatRelativeTime } from '../../lib/format.ts'\nimport { STATUS_META } from './status.ts'\n\nexport interface SessionListItemProps {\n session: SessionInfo\n active?: boolean\n onSelect?: (id: string) => void\n onDelete?: (id: string) => void\n className?: string\n}\n\nexport function SessionListItem({ session, active, onSelect, onDelete, className }: SessionListItemProps) {\n const meta = STATUS_META[session.status]\n return (\n <div\n data-slot=\"session-list-item\"\n data-active={active || undefined}\n className={cn(\n 'group flex w-full items-center gap-2 rounded-md border border-transparent px-2.5 py-2 text-left transition-colors',\n active ? 'border-border bg-surface' : 'hover:bg-surface-hover',\n className,\n )}\n >\n <button type=\"button\" onClick={() => onSelect?.(session.id)} className=\"min-w-0 flex-1 text-left outline-none\">\n <div className=\"flex items-center gap-2\">\n <span className=\"truncate text-body-sm font-medium text-fg-1\">{session.title ?? session.id.slice(0, 8)}</span>\n <Badge variant={meta.variant} dot className=\"shrink-0\">\n {meta.label}\n </Badge>\n </div>\n <div className=\"mt-0.5 flex items-center gap-2 font-mono text-label text-fg-4\">\n <span className=\"truncate\">{session.cwd}</span>\n {session.profile ? <span className=\"shrink-0\">@{session.profile}</span> : null}\n <span className=\"shrink-0\">{formatCost(session.totalCostUsd)}</span>\n <span className=\"shrink-0\">{formatRelativeTime(session.lastActivityAt ?? session.createdAt)}</span>\n </div>\n </button>\n {onDelete ? (\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label=\"Close session\"\n className=\"opacity-0 transition-opacity group-hover:opacity-100\"\n onClick={() => onDelete(session.id)}\n >\n <Trash2 className=\"size-3.5 text-fg-3\" />\n </Button>\n ) : null}\n </div>\n )\n}\n\nexport interface SessionListProps {\n sessions: SessionInfo[]\n activeId?: string\n onSelect?: (id: string) => void\n onDelete?: (id: string) => void\n emptyText?: string\n className?: string\n}\n\nexport function SessionList({ sessions, activeId, onSelect, onDelete, emptyText = 'No sessions yet.', className }: SessionListProps) {\n return (\n <div data-slot=\"session-list\" className={cn('flex flex-col gap-1', className)}>\n {sessions.length === 0 ? (\n <div className=\"px-2.5 py-6 text-center text-body-sm text-fg-4\">{emptyText}</div>\n ) : (\n sessions.map((session) => (\n <SessionListItem key={session.id} session={session} active={session.id === activeId} onSelect={onSelect} onDelete={onDelete} />\n ))\n )}\n </div>\n )\n}\n","import type { ProjectIcon as ProjectIconSpec } from '@workerdeck/protocol'\nimport {\n Anchor,\n Atom,\n Beaker,\n Bike,\n Binary,\n Blocks,\n Bot,\n Box,\n Brain,\n Briefcase,\n Brush,\n Bug,\n Building2,\n Cable,\n Camera,\n Car,\n Cat,\n CircuitBoard,\n Cloud,\n Code,\n Coffee,\n Cog,\n Compass,\n Container,\n Cpu,\n CreditCard,\n Database,\n Diamond,\n Dog,\n Feather,\n Film,\n Flame,\n FlaskConical,\n Folder,\n Gamepad2,\n Gauge,\n Gem,\n Ghost,\n Gift,\n GitBranch,\n Globe,\n GraduationCap,\n Hammer,\n Hexagon,\n House,\n Image,\n Key,\n Landmark,\n Laptop,\n Layers,\n Leaf,\n Library,\n Lightbulb,\n Lock,\n Mail,\n Map,\n MessageCircle,\n Mic,\n Monitor,\n Moon,\n Mountain,\n Music,\n Network,\n Newspaper,\n Notebook,\n Orbit,\n Package,\n Palette,\n PenTool,\n Phone,\n PiggyBank,\n Plane,\n Plug,\n Puzzle,\n Radar,\n Radio,\n Receipt,\n Rocket,\n Ruler,\n Satellite,\n Scale,\n Scissors,\n Server,\n Shield,\n Ship,\n ShoppingCart,\n Signal,\n Smartphone,\n Sparkles,\n Sprout,\n Square,\n Star,\n Sun,\n Table,\n Tag,\n Target,\n Telescope,\n Terminal,\n TestTube,\n TreePine,\n Trophy,\n Truck,\n Umbrella,\n Users,\n Wallet,\n Wand,\n Waves,\n Webhook,\n Wifi,\n Wrench,\n Zap,\n} from 'lucide-react'\nimport type { ComponentType } from 'react'\nimport { cn } from '../../lib/utils.ts'\n\nconst GLYPHS: Record<string, ComponentType<{ className?: string }>> = {\n anchor: Anchor,\n atom: Atom,\n beaker: Beaker,\n bike: Bike,\n binary: Binary,\n blocks: Blocks,\n bot: Bot,\n box: Box,\n brain: Brain,\n briefcase: Briefcase,\n brush: Brush,\n bug: Bug,\n 'building-2': Building2,\n cable: Cable,\n camera: Camera,\n car: Car,\n cat: Cat,\n 'circuit-board': CircuitBoard,\n cloud: Cloud,\n code: Code,\n coffee: Coffee,\n cog: Cog,\n compass: Compass,\n container: Container,\n cpu: Cpu,\n 'credit-card': CreditCard,\n database: Database,\n diamond: Diamond,\n dog: Dog,\n feather: Feather,\n film: Film,\n flame: Flame,\n 'flask-conical': FlaskConical,\n folder: Folder,\n 'gamepad-2': Gamepad2,\n gauge: Gauge,\n gem: Gem,\n ghost: Ghost,\n gift: Gift,\n 'git-branch': GitBranch,\n globe: Globe,\n 'graduation-cap': GraduationCap,\n hammer: Hammer,\n hexagon: Hexagon,\n house: House,\n image: Image,\n key: Key,\n landmark: Landmark,\n laptop: Laptop,\n layers: Layers,\n leaf: Leaf,\n library: Library,\n lightbulb: Lightbulb,\n lock: Lock,\n mail: Mail,\n map: Map,\n 'message-circle': MessageCircle,\n mic: Mic,\n monitor: Monitor,\n moon: Moon,\n mountain: Mountain,\n music: Music,\n network: Network,\n newspaper: Newspaper,\n notebook: Notebook,\n orbit: Orbit,\n package: Package,\n palette: Palette,\n 'pen-tool': PenTool,\n phone: Phone,\n 'piggy-bank': PiggyBank,\n plane: Plane,\n plug: Plug,\n puzzle: Puzzle,\n radar: Radar,\n radio: Radio,\n receipt: Receipt,\n rocket: Rocket,\n ruler: Ruler,\n satellite: Satellite,\n scale: Scale,\n scissors: Scissors,\n server: Server,\n shield: Shield,\n ship: Ship,\n 'shopping-cart': ShoppingCart,\n signal: Signal,\n smartphone: Smartphone,\n sparkles: Sparkles,\n sprout: Sprout,\n square: Square,\n star: Star,\n sun: Sun,\n table: Table,\n tag: Tag,\n target: Target,\n telescope: Telescope,\n terminal: Terminal,\n 'test-tube': TestTube,\n 'tree-pine': TreePine,\n trophy: Trophy,\n truck: Truck,\n umbrella: Umbrella,\n users: Users,\n wallet: Wallet,\n wand: Wand,\n waves: Waves,\n webhook: Webhook,\n wifi: Wifi,\n wrench: Wrench,\n zap: Zap,\n}\n\nexport function ProjectIcon({\n icon,\n src,\n name,\n className,\n}: {\n icon: ProjectIconSpec | undefined\n src?: string\n name?: string\n className?: string\n}) {\n if (!icon) {\n return null\n }\n if (icon.type === 'image') {\n if (!src) {\n return null\n }\n return <img src={src} alt=\"\" aria-hidden title={name} className={cn('inline-block size-3 shrink-0 object-contain', className)} />\n }\n const Glyph = GLYPHS[icon.name] ?? Folder\n return <Glyph className={cn('inline-block size-3 shrink-0', className)} />\n}\n","import type { ContextReading } from '@workerdeck/protocol'\nimport { ProgressRing } from '../ui/ProgressRing.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { formatTokens } from '../../lib/format.ts'\nimport { meterColorClass } from '../../lib/status.ts'\n\nexport function ContextRing({ usage, size = 11, className }: { usage: ContextReading | undefined; size?: number; className?: string }) {\n if (usage === undefined) {\n return null\n }\n return (\n <span\n title={`Context ${usage.percentage.toFixed(0)}% · ${formatTokens(usage.totalTokens)} / ${formatTokens(usage.maxTokens)}`}\n className={cn('shrink-0 leading-none', meterColorClass(usage.percentage), className)}\n >\n <ProgressRing value={usage.percentage} size={size} strokeWidth={2} />\n </span>\n )\n}\n","import { cn } from '../../lib/utils.ts'\n\n// Paths from `@lobehub/icons-static-svg` (MIT, © LobeHub), inlined. The marks are trademarks of their owners, used only to identify a session's engine.\nconst PATHS: Record<string, { title: string; d: string }> = {\n claude: {\n title: 'Claude',\n d: 'M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z',\n },\n codex: {\n title: 'OpenAI',\n d: 'M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z',\n },\n gemini: {\n title: 'Gemini',\n d: 'M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z',\n },\n deepseek: {\n title: 'DeepSeek',\n d: 'M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z',\n },\n moonshot: {\n title: 'Moonshot',\n d: 'M1.052 16.916l9.539 2.552a21.007 21.007 0 00.06 2.033l5.956 1.593a11.997 11.997 0 01-5.586.865l-.18-.016-.044-.004-.084-.009-.094-.01a11.605 11.605 0 01-.157-.02l-.107-.014-.11-.016a11.962 11.962 0 01-.32-.051l-.042-.008-.075-.013-.107-.02-.07-.015-.093-.019-.075-.016-.095-.02-.097-.023-.094-.022-.068-.017-.088-.022-.09-.024-.095-.025-.082-.023-.109-.03-.062-.02-.084-.025-.093-.028-.105-.034-.058-.019-.08-.026-.09-.031-.066-.024a6.293 6.293 0 01-.044-.015l-.068-.025-.101-.037-.057-.022-.08-.03-.087-.035-.088-.035-.079-.032-.095-.04-.063-.028-.063-.027a5.655 5.655 0 01-.041-.018l-.066-.03-.103-.047-.052-.024-.096-.046-.062-.03-.084-.04-.086-.044-.093-.047-.052-.027-.103-.055-.057-.03-.058-.032a6.49 6.49 0 01-.046-.026l-.094-.053-.06-.034-.051-.03-.072-.041-.082-.05-.093-.056-.052-.032-.084-.053-.061-.039-.079-.05-.07-.047-.053-.035a7.785 7.785 0 01-.054-.036l-.044-.03-.044-.03a6.066 6.066 0 01-.04-.028l-.057-.04-.076-.054-.069-.05-.074-.054-.056-.042-.076-.057-.076-.059-.086-.067-.045-.035-.064-.052-.074-.06-.089-.073-.046-.039-.046-.039a7.516 7.516 0 01-.043-.037l-.045-.04-.061-.053-.07-.062-.068-.06-.062-.058-.067-.062-.053-.05-.088-.084a13.28 13.28 0 01-.099-.097l-.029-.028-.041-.042-.069-.07-.05-.051-.05-.053a6.457 6.457 0 01-.168-.179l-.08-.088-.062-.07-.071-.08-.042-.049-.053-.062-.058-.068-.046-.056a7.175 7.175 0 01-.027-.033l-.045-.055-.066-.082-.041-.052-.05-.064-.02-.025a11.99 11.99 0 01-1.44-2.402zm-1.02-5.794l11.353 3.037a20.468 20.468 0 00-.469 2.011l10.817 2.894a12.076 12.076 0 01-1.845 2.005L.657 15.923l-.016-.046-.035-.104a11.965 11.965 0 01-.05-.153l-.007-.023a11.896 11.896 0 01-.207-.741l-.03-.126-.018-.08-.021-.097-.018-.081-.018-.09-.017-.084-.018-.094c-.026-.141-.05-.283-.071-.426l-.017-.118-.011-.083-.013-.102a12.01 12.01 0 01-.019-.161l-.005-.047a12.12 12.12 0 01-.034-2.145zm1.593-5.15l11.948 3.196c-.368.605-.705 1.231-1.01 1.875l11.295 3.022c-.142.82-.368 1.612-.668 2.365l-11.55-3.09L.124 10.26l.015-.1.008-.049.01-.067.015-.087.018-.098c.026-.148.056-.295.088-.442l.028-.124.02-.085.024-.097c.022-.09.045-.18.07-.268l.028-.102.023-.083.03-.1.025-.082.03-.096.026-.082.031-.095a11.896 11.896 0 011.01-2.232zm4.442-4.4L17.352 4.59a20.77 20.77 0 00-1.688 1.721l7.823 2.093c.267.852.442 1.744.513 2.665L2.106 5.213l.045-.065.027-.04.04-.055.046-.065.055-.076.054-.072.064-.086.05-.065.057-.073.055-.07.06-.074.055-.069.065-.077.054-.066.066-.077.053-.06.072-.082.053-.06.067-.074.054-.058.073-.078.058-.06.063-.067.168-.17.1-.098.059-.056.076-.071a12.084 12.084 0 012.272-1.677zM12.017 0h.097l.082.001.069.001.054.002.068.002.046.001.076.003.047.002.06.003.054.002.087.005.105.007.144.011.088.007.044.004.077.008.082.008.047.005.102.012.05.006.108.014.081.01.042.006.065.01.207.032.07.012.065.011.14.026.092.018.11.022.046.01.075.016.041.01L14.7.3l.042.01.065.015.049.012.071.017.096.024.112.03.113.03.113.032.05.015.07.02.078.024.073.023.05.016.05.016.076.025.099.033.102.036.048.017.064.023.093.034.11.041.116.045.1.04.047.02.06.024.041.018.063.026.04.018.057.025.11.048.1.046.074.035.075.036.06.028.092.046.091.045.102.052.053.028.049.026.046.024.06.033.041.022.052.029.088.05.106.06.087.051.057.034.053.032.096.059.088.055.098.062.036.024.064.041.084.056.04.027.062.042.062.043.023.017c.054.037.108.075.161.114l.083.06.065.048.056.043.086.065.082.064.04.03.05.041.086.069.079.065.085.071c.712.6 1.353 1.283 1.909 2.031L7.222.994l.062-.027.065-.028.081-.034.086-.035c.113-.045.227-.09.341-.131l.096-.035.093-.033.084-.03.096-.031c.087-.03.176-.058.264-.085l.091-.027.086-.025.102-.03.085-.023.1-.026L9.04.37l.09-.023.091-.022.095-.022.09-.02.098-.021.091-.02.095-.018.092-.018.1-.018.091-.016.098-.017.092-.014.097-.015.092-.013.102-.013.091-.012.105-.012.09-.01.105-.01c.093-.01.186-.018.28-.024l.106-.008.09-.005.11-.006.093-.004.1-.004.097-.002.099-.002.197-.002z',\n },\n}\n\nexport function engineMark(engine: string, model?: string): string | undefined {\n if (engine === 'claude') {\n return 'claude'\n }\n if (engine === 'codex') {\n return 'codex'\n }\n const id = model?.toLowerCase() ?? ''\n if (!id) {\n return undefined\n }\n if (id.includes('gemini')) {\n return 'gemini'\n }\n if (id.includes('deepseek')) {\n return 'deepseek'\n }\n if (id.includes('moonshot') || id.includes('kimi')) {\n return 'moonshot'\n }\n if (id.includes('claude')) {\n return 'claude'\n }\n if (id.startsWith('gpt') || id.startsWith('o1') || id.startsWith('o3') || id.includes('openai')) {\n return 'codex'\n }\n return undefined\n}\n\nconst VENDOR_MARK: Record<string, string> = {\n claude: 'text-vendor-claude',\n codex: 'text-vendor-openai',\n}\nconst VENDOR_TEXT: Record<string, string> = {\n claude: 'text-vendor-claude',\n}\n\nexport function vendorMarkClass(engine: string, model?: string): string {\n return VENDOR_MARK[engineMark(engine, model) ?? ''] ?? 'text-fg-3'\n}\n\nexport function vendorTextClass(engine: string, model?: string): string {\n return VENDOR_TEXT[engineMark(engine, model) ?? ''] ?? 'text-fg-3'\n}\n\nexport function EngineIcon({ engine, model, className }: { engine: string; model?: string; className?: string }) {\n const mark = PATHS[engineMark(engine, model) ?? '']\n if (!mark) {\n return (\n <span aria-hidden title={engine} className={cn('shrink-0 text-fg-3', className)}>\n ·\n </span>\n )\n }\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n role=\"img\"\n aria-label={mark.title}\n className={cn('size-3 shrink-0 text-fg-3', className)}\n >\n <title>{mark.title}</title>\n <path d={mark.d} />\n </svg>\n )\n}\n","import { BellRing, CircleAlert, CircleSlash, Moon, PauseCircle } from 'lucide-react'\nimport type { SessionRow } from '@workerdeck/protocol'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport function SessionStatusIcon({ row, className }: { row: SessionRow; className?: string }) {\n const { info } = row\n const size = cn('size-4 shrink-0', className)\n if (row.state === 'attention') {\n return <BellRing className={cn(size, 'animate-pulse text-warning')} />\n }\n if (row.state === 'working') {\n return <Spinner className={cn(size, 'text-info')} />\n }\n switch (info.status) {\n case 'failed': {\n return <CircleAlert className={cn(size, 'text-danger')} />\n }\n case 'closed': {\n return <CircleSlash className={cn(size, 'text-fg-4')} />\n }\n case 'parked': {\n return <PauseCircle className={cn(size, 'text-fg-3')} />\n }\n default: {\n return <Moon className={cn(size, 'text-fg-4')} />\n }\n }\n}\n","import { ArrowRight, Check, ChevronDown, ChevronRight, CircleAlert, Dot, PauseCircle } from 'lucide-react'\nimport { isAgentRecord, subagentLabel } from '@workerdeck/protocol'\nimport type { SessionInfo, SubagentInfo } from '@workerdeck/protocol'\nimport { Spinner } from '../ui/Spinner.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport type Step = {\n key: string\n label: string\n noun: string\n kind: 'agent' | 'task'\n state: 'done' | 'running' | 'pending' | 'failed'\n detail?: string\n title: string\n onSelect: () => void\n}\n\nexport function sessionSteps(info: SessionInfo, onSelect: (toolUseId: string, kind: Step['kind']) => void): Step[] {\n const steps = (info.subagents ?? []).map((sub) => {\n const kind = isAgentRecord(sub) ? ('agent' as const) : ('task' as const)\n return {\n key: sub.toolUseId,\n label: subagentLabel(sub),\n noun: 'agent',\n kind,\n state: stepState(sub.status),\n detail: sub.toolCount > 0 ? String(sub.toolCount) : undefined,\n title: `${subagentLabel(sub)} · ${sub.toolCount} tool${sub.toolCount === 1 ? '' : 's'}`,\n onSelect: () => onSelect(sub.toolUseId, kind),\n }\n })\n return [...steps.filter((s) => s.kind === 'agent'), ...steps.filter((s) => s.kind === 'task')]\n}\n\nfunction stepState(status: SubagentInfo['status']): Step['state'] {\n switch (status) {\n case 'running': {\n return 'running'\n }\n case 'failed': {\n return 'failed'\n }\n default: {\n return 'done'\n }\n }\n}\n\nexport function runningSteps(steps: readonly Step[]): number {\n return steps.filter((s) => s.state === 'running').length\n}\n\nexport function StepToggle({\n expanded,\n running,\n total,\n noun,\n onToggle,\n}: {\n expanded: boolean\n running: number\n total: number\n noun: string\n onToggle: () => void\n}) {\n const label = running > 0 && running < total ? `${running}/${total}` : String(total)\n const words = running > 0 && running < total ? `${running} of ${total} ${noun}s running` : `${total} ${noun}${total === 1 ? '' : 's'}`\n const Chevron = expanded ? ChevronDown : ChevronRight\n return (\n <button\n type=\"button\"\n aria-expanded={expanded}\n aria-label={`${expanded ? 'Hide' : 'Show'} ${words}`}\n title={`${expanded ? 'Hide' : 'Show'} ${words}`}\n onClick={(e) => {\n e.stopPropagation()\n onToggle()\n }}\n className={cn(\n 'flex shrink-0 items-center gap-0.5 rounded-[4px] py-0.5 pr-1 pl-0.5 outline-none',\n 'text-[0.75rem] leading-3 hover:bg-row-hover hover:text-fg-2',\n running > 0 ? 'text-info' : 'text-fg-4',\n )}\n >\n <Chevron className=\"size-3\" />\n <span className=\"tabular-nums\">{label}</span>\n </button>\n )\n}\n\nexport function StepRow({ step, active = false, onSelect }: { step: Step; active?: boolean; onSelect: () => void }) {\n const agent = step.kind === 'agent'\n const selected = active && agent\n const body = step.state === 'failed' ? 'text-danger' : agent ? 'text-success' : 'text-fg-4'\n return (\n <button\n type=\"button\"\n title={step.title}\n aria-current={selected || undefined}\n onClick={(e) => {\n e.stopPropagation()\n onSelect()\n }}\n className={cn(\n 'flex w-full items-center gap-1.5 rounded-[4px] py-1 pr-2.5 pl-3.5',\n 'text-left text-micro outline-none',\n selected ? 'bg-row-selected' : 'hover:bg-row-active',\n body,\n )}\n >\n <StepIcon state={step.state} kind={step.kind} />\n <span className=\"min-w-0 flex-1 truncate\">{step.label}</span>\n {step.detail ? <span className=\"shrink-0 tabular-nums text-fg-4\">{step.detail}</span> : null}\n {agent ? <ArrowRight className=\"size-3.5 shrink-0 text-fg-4\" /> : null}\n </button>\n )\n}\n\nfunction StepIcon({ state, kind }: { state: Step['state']; kind: Step['kind'] }) {\n if (kind === 'task' && state !== 'running' && state !== 'failed') {\n return <Dot className=\"size-[11px] shrink-0\" />\n }\n switch (state) {\n case 'running': {\n return <Spinner className=\"size-[11px] shrink-0\" />\n }\n case 'failed': {\n return <CircleAlert className=\"size-[11px] shrink-0\" />\n }\n case 'pending': {\n return <PauseCircle className=\"size-[11px] shrink-0\" />\n }\n default: {\n return <Check className=\"size-[11px] shrink-0\" />\n }\n }\n}\n","import { Fragment, useEffect, useRef, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { projectLabel, projectSubpath, sessionLabel } from '@workerdeck/protocol'\nimport type { SessionRow } from '@workerdeck/protocol'\nimport { ContextRing } from './ContextRing.tsx'\nimport { EngineIcon, vendorMarkClass, vendorTextClass } from './EngineIcon.tsx'\nimport { ProjectIcon } from './ProjectIcon.tsx'\nimport { SessionStatusIcon } from './SessionStatusIcon.tsx'\nimport { StepRow, StepToggle, runningSteps, sessionSteps } from './SessionSteps.tsx'\nimport type { Step } from './SessionSteps.tsx'\nimport { cn } from '../../lib/utils.ts'\nimport { formatCost, formatRelativeTime, friendlyModel } from '../../lib/format.ts'\n\nexport interface SessionItemProps {\n row: SessionRow\n active?: boolean\n activeStepKey?: string\n showGateway?: boolean\n showProject?: boolean\n projectIcons?: Record<string, string>\n expanded?: boolean\n onExpandedChange?: (expanded: boolean) => void\n onSelect?: () => void\n onSelectSubagent?: (toolUseId: string) => void\n onRevealStep?: (toolUseId: string) => void\n onRename?: (title: string) => void\n renameOn?: 'doubleClick' | 'external'\n editing?: boolean\n onEditingChange?: (editing: boolean) => void\n actions?: ReactNode\n className?: string\n}\n\nexport function SessionItem({\n row,\n active = false,\n activeStepKey,\n showGateway,\n showProject = true,\n projectIcons,\n expanded,\n onExpandedChange,\n onSelect,\n onSelectSubagent,\n onRevealStep,\n onRename,\n renameOn = 'doubleClick',\n editing,\n onEditingChange,\n actions,\n className,\n}: SessionItemProps) {\n const { info } = row\n const [ownExpanded, setOwnExpanded] = useState(false)\n const open = expanded ?? ownExpanded\n const setOpen = (next: boolean) => {\n setOwnExpanded(next)\n onExpandedChange?.(next)\n }\n const [ownEditing, setOwnEditing] = useState(false)\n const isEditing = editing ?? ownEditing\n const setEditing = (next: boolean) => {\n setOwnEditing(next)\n onEditingChange?.(next)\n }\n\n const engine = info.engine ?? 'claude'\n const project = showProject ? projectLabel(row) : projectSubpath(row)\n const projectIcon = showProject ? info.project?.icon : undefined\n const iconSrc = projectIcon?.type === 'image' ? projectIcons?.[projectIcon.hash] : undefined\n const cost = formatCost(info.totalCostUsd)\n const extras = [\n showGateway ? row.hostName : undefined,\n info.profile ? `@${info.profile}` : undefined,\n cost === '—' ? undefined : cost,\n ].filter((part): part is string => Boolean(part))\n\n const model = friendlyModel(info.model)\n const parts: ReactNode[] = []\n if (model) {\n parts.push(\n <span key=\"model\" className={vendorTextClass(engine, info.model)}>\n {model}\n </span>,\n )\n }\n if (project !== undefined) {\n parts.push(\n <span key=\"project\">\n <ProjectIcon icon={projectIcon} src={iconSrc} name={project} className=\"mr-1.5 size-4 align-[-0.3em]\" />\n {project}\n </span>,\n )\n }\n for (const extra of extras) {\n parts.push(<span key={extra}>{extra}</span>)\n }\n const steps = sessionSteps(info, (toolUseId, kind) => {\n if (kind === 'agent') {\n return onSelectSubagent ? onSelectSubagent(toolUseId) : onSelect?.()\n }\n return onRevealStep ? onRevealStep(toolUseId) : onSelect?.()\n })\n const holdsOpenAgent = steps.some((s) => s.kind === 'agent' && s.key === activeStepKey)\n\n return (\n <div\n data-slot=\"session-item\"\n data-active={active || undefined}\n role=\"button\"\n tabIndex={0}\n onClick={(e) => {\n if (e.detail > 1 || isEditing) {\n return\n }\n onSelect?.()\n }}\n onKeyDown={(e) => {\n if (e.target !== e.currentTarget) {\n return\n }\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n onSelect?.()\n }\n }}\n className={cn(\n 'group flex w-full cursor-pointer flex-col p-1 text-left outline-none',\n 'rounded-[4px] transition-colors focus-visible:ring-2 focus-visible:ring-ring',\n holdsOpenAgent ? 'bg-row-selected-weak' : active ? 'bg-row-selected' : 'hover:bg-row-hover',\n className,\n )}\n >\n <div className=\"flex flex-col gap-1 py-0.5 pr-0.5 pl-1.5\">\n <div className=\"flex h-5 items-center gap-1.5 overflow-hidden\">\n <Gutter>\n <SessionStatusIcon row={row} />\n </Gutter>\n {isEditing && onRename ? (\n <NameEditor\n initial={info.title ?? ''}\n onCommit={(title) => {\n setEditing(false)\n if (title !== (info.title ?? '')) {\n onRename(title)\n }\n }}\n onCancel={() => setEditing(false)}\n />\n ) : (\n <span\n onDoubleClick={\n onRename && renameOn === 'doubleClick'\n ? (e) => {\n e.stopPropagation()\n setEditing(true)\n }\n : undefined\n }\n className=\"min-w-0 flex-1 truncate text-body-sm font-medium tracking-[-0.005em] text-fg-1\"\n >\n {sessionLabel(info)}\n </span>\n )}\n {row.unseen > 0 ? (\n <span\n // Prose, not rows: `unseen` counts messages a person has not read (`proseCount`).\n title={`${row.unseen} new message${row.unseen === 1 ? '' : 's'}`}\n className={cn(\n 'flex h-4 min-w-6 shrink-0 items-center justify-center rounded-full px-2',\n 'text-[0.75rem] leading-none tracking-[-0.005em] tabular-nums',\n row.state === 'working' || row.state === 'attention' ? 'bg-accent text-accent-fg' : 'bg-badge text-badge-fg',\n )}\n >\n {row.unseen}\n </span>\n ) : null}\n <ContextRing usage={info.contextUsage} size={16} className=\"p-0.5\" />\n </div>\n\n <div className=\"flex h-5 items-center gap-1.5 overflow-hidden text-body-sm tracking-[-0.005em]\">\n <Gutter>\n <EngineIcon engine={engine} model={info.model} className={cn('size-4', vendorMarkClass(engine, info.model))} />\n </Gutter>\n <span className=\"min-w-0 truncate text-fg-4\">\n {parts.map((part, i) => (\n <Fragment key={i}>\n {i > 0 ? ' · ' : ''}\n {part}\n </Fragment>\n ))}\n </span>\n <span className=\"shrink-0 text-fg-4\">\n {parts.length > 0 ? '· ' : ''}\n {formatRelativeTime(info.lastActivityAt ?? info.createdAt)}\n </span>\n <span className=\"min-w-0 flex-1\" />\n {steps.length > 0 ? (\n <StepToggle\n expanded={open}\n running={runningSteps(steps)}\n total={steps.length}\n noun={steps[0]!.noun}\n onToggle={() => setOpen(!open)}\n />\n ) : null}\n {actions}\n </div>\n </div>\n\n {open && steps.length > 0 ? (\n <div className=\"flex flex-col\">\n {steps.map((step: Step) => (\n <StepRow key={step.key} step={step} active={step.key === activeStepKey} onSelect={step.onSelect} />\n ))}\n </div>\n ) : null}\n </div>\n )\n}\n\nfunction Gutter({ children }: { children: ReactNode }) {\n return <span className=\"flex size-4 shrink-0 items-center justify-center\">{children}</span>\n}\n\nfunction NameEditor({ initial, onCommit, onCancel }: { initial: string; onCommit: (title: string) => void; onCancel: () => void }) {\n const [value, setValue] = useState(initial)\n const ref = useRef<HTMLInputElement>(null)\n useEffect(() => {\n ref.current?.focus()\n ref.current?.select()\n }, [])\n useEffect(() => {\n const onWindowFocus = () => {\n ref.current?.focus()\n ref.current?.select()\n }\n window.addEventListener('focus', onWindowFocus)\n return () => window.removeEventListener('focus', onWindowFocus)\n }, [])\n return (\n <input\n ref={ref}\n value={value}\n spellCheck={false}\n placeholder=\"Session name\"\n aria-label=\"Session name\"\n onClick={(e) => e.stopPropagation()}\n onDoubleClick={(e) => e.stopPropagation()}\n onChange={(e) => setValue(e.target.value)}\n onBlur={() => {\n // Guarded on `document.hasFocus()`: selecting a session focuses another surface (in the extension, another view), and an unguarded blur closes the editor in the frame it appeared.\n if (document.hasFocus()) {\n onCommit(value.trim())\n }\n }}\n onKeyDown={(e) => {\n e.stopPropagation()\n if (e.key === 'Enter') {\n onCommit(value.trim())\n } else if (e.key === 'Escape') {\n onCancel()\n }\n }}\n className={cn(\n '-my-0.5 min-w-0 flex-1 rounded-sm border border-ring bg-bg px-1 py-px',\n 'text-body-sm leading-5 text-fg-1 outline-none',\n )}\n />\n )\n}\n","import { useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { Eraser, Layers, Pencil, Search, SearchX, Trash2, X } from 'lucide-react'\nimport {\n STATE_LABELS,\n STATE_ORDER,\n adaptersOf,\n clearFilters,\n filterRows,\n groupRows,\n hasFacetFilter,\n projectsOf,\n subsetSummary,\n} from '@workerdeck/protocol'\nimport type { GroupBy, SessionRow, SessionState, SortBy, ViewConfig, WorkspaceScope } from '@workerdeck/protocol'\nimport { Button } from '../ui/Button.tsx'\nimport { Empty } from '../ui/Empty.tsx'\nimport { Input } from '../ui/Input.tsx'\nimport { Select, SelectContent, SelectItem, SelectItemText, SelectTrigger, SelectValue } from '../ui/Select.tsx'\nimport { ProjectIcon } from './ProjectIcon.tsx'\nimport { SessionItem } from './SessionItem.tsx'\nimport { cn } from '../../lib/utils.ts'\n\nexport { SessionStatusIcon } from './SessionStatusIcon.tsx'\n\nexport interface SessionBrowserProps {\n rows: SessionRow[]\n config: ViewConfig\n onConfigChange: (config: ViewConfig) => void\n scope?: WorkspaceScope\n activeId?: string\n activeSubagentId?: string\n onSelect?: (row: SessionRow) => void\n onDelete?: (row: SessionRow) => void\n onRename?: (row: SessionRow, title: string) => void\n onClearContext?: (row: SessionRow) => void\n onSelectSubagent?: (row: SessionRow, toolUseId: string) => void\n onRevealStep?: (row: SessionRow, toolUseId: string) => void\n emptyState?: React.ReactNode\n showControls?: boolean\n projectIcons?: Record<string, string>\n className?: string\n}\n\nexport function rowShapeClass(active: boolean): string {\n return cn('px-2 py-1.5 hover:bg-row-hover', active ? 'mr-1 ml-0 rounded-r-md border-l-4 border-l-accent' : 'mx-1 rounded-md')\n}\n\nexport function SessionBrowser({\n rows,\n config,\n onConfigChange,\n scope,\n activeId,\n activeSubagentId,\n onSelect,\n onDelete,\n onRename,\n onClearContext,\n onSelectSubagent,\n onRevealStep,\n emptyState,\n showControls = true,\n projectIcons,\n className,\n}: SessionBrowserProps) {\n const visible = useMemo(() => filterRows(rows, config, scope), [rows, config, scope])\n const groups = useMemo(() => groupRows(visible, config), [visible, config])\n const subset = subsetSummary(config, scope, visible.length, rows.length)\n const adapters = useMemo(() => adaptersOf(rows), [rows])\n const projects = useMemo(() => projectsOf(rows), [rows])\n const gateways = useMemo(() => {\n const seen = new Map<string, string>()\n for (const row of rows) {\n seen.set(row.hostId, row.hostName)\n }\n return [...seen].map(([id, name]) => ({ id, name }))\n }, [rows])\n\n const set = (patch: Partial<ViewConfig>) => onConfigChange({ ...config, ...patch })\n\n return (\n <div data-slot=\"session-browser\" className={cn('flex flex-col gap-3', className)}>\n <div className={cn('flex flex-col gap-1.5 px-2', !showControls && 'hidden')}>\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2 text-fg-4\" />\n <Input\n value={config.search}\n onChange={(e) => set({ search: e.target.value })}\n placeholder=\"Search sessions\"\n aria-label=\"Search sessions\"\n className=\"pl-8\"\n />\n </div>\n <FilterRow label=\"State\">\n <FacetSelect\n label=\"State\"\n value={config.states}\n options={STATE_ORDER.map((s) => ({ value: s, label: STATE_LABELS[s] }))}\n onChange={(states) => set({ states: states as SessionState[] })}\n />\n </FilterRow>\n {adapters.length > 1 ? (\n <FilterRow label=\"Engine\">\n <FacetSelect\n label=\"Engine\"\n value={config.adapters}\n options={adapters.map((a) => ({ value: a, label: a }))}\n onChange={(adapters) => set({ adapters })}\n />\n </FilterRow>\n ) : null}\n {gateways.length > 1 ? (\n <FilterRow label=\"Gateway\">\n <FacetSelect\n label=\"Gateway\"\n value={config.gateways}\n options={gateways.map((g) => ({ value: g.id, label: g.name }))}\n onChange={(gateways) => set({ gateways })}\n />\n </FilterRow>\n ) : null}\n {projects.length > 1 ? (\n <FilterRow label=\"Project\">\n <FacetSelect\n label=\"Project\"\n value={config.projects ?? []}\n options={projects.map((p) => ({ value: p.key, label: p.label }))}\n onChange={(next) => set({ projects: next })}\n />\n </FilterRow>\n ) : null}\n <FilterRow label=\"Group\">\n <OneOfSelect\n label=\"Group\"\n value={config.groupBy}\n options={[\n { value: 'none', label: 'No grouping' },\n { value: 'state', label: 'By state' },\n { value: 'adapter', label: 'By engine' },\n ...(projects.length > 1 ? [{ value: 'project' as const, label: 'By project' }] : []),\n ...(gateways.length > 1 ? [{ value: 'gateway' as const, label: 'By gateway' }] : []),\n ]}\n onChange={(groupBy) => set({ groupBy: groupBy as GroupBy })}\n />\n </FilterRow>\n <FilterRow label=\"Sort\">\n <OneOfSelect\n label=\"Sort\"\n value={config.sortBy}\n options={[\n { value: 'recent', label: 'Recent' },\n { value: 'name', label: 'Name' },\n { value: 'state', label: 'State' },\n ...(projects.length > 1 ? [{ value: 'project' as const, label: 'Project' }] : []),\n ...(gateways.length > 1 ? [{ value: 'gateway' as const, label: 'Gateway' }] : []),\n ]}\n onChange={(sortBy) => set({ sortBy: sortBy as SortBy })}\n />\n </FilterRow>\n </div>\n\n {subset ? (\n <div className=\"flex items-center gap-2 px-3 text-label text-fg-4\">\n <span>\n {subset.shown} of {subset.total}\n {subset.causes.length ? ` · ${subset.causes.join(' · ')}` : null}\n </span>\n <button\n type=\"button\"\n className=\"text-fg-3 underline underline-offset-2 hover:text-fg-1\"\n onClick={() => onConfigChange(clearFilters(config))}\n >\n Show all\n </button>\n </div>\n ) : null}\n\n {rows.length === 0 ? (\n (emptyState ?? <Empty icon={<Layers />} title=\"No sessions yet\" />)\n ) : visible.length === 0 ? (\n hasFacetFilter(config) ? (\n <Empty\n icon={<SearchX />}\n title=\"No matches\"\n description=\"No session matches the current search and filters.\"\n action=\"Clear filters\"\n onAction={() => onConfigChange(clearFilters(config))}\n />\n ) : (\n <Empty icon={<Layers />} title=\"Nothing here\" description=\"No session to show.\" />\n )\n ) : (\n <div className=\"flex flex-col gap-4 px-1\">\n {groups.map((group) => (\n <div key={group.key} className=\"flex flex-col gap-1\">\n {config.groupBy !== 'none' && group.label ? (\n <div className=\"flex items-center gap-2 px-2 text-label font-medium text-fg-4\">\n {config.groupBy === 'project' ? (\n <ProjectIcon icon={group.rows[0]?.info.project?.icon} src={iconSrcOf(group.rows[0], projectIcons)} name={group.label} />\n ) : null}\n <span className=\"uppercase tracking-wide\">{group.label}</span>\n <span className=\"text-fg-4/70\">{group.rows.length}</span>\n </div>\n ) : null}\n {group.rows.map((row) => (\n <SessionRowItem\n key={`${row.hostId}:${row.info.id}`}\n row={row}\n active={row.info.id === activeId}\n activeSubagentId={activeSubagentId}\n showGateway={gateways.length > 1 && config.groupBy !== 'gateway'}\n showProject={config.groupBy !== 'project'}\n projectIcons={projectIcons}\n onSelect={onSelect}\n onDelete={onDelete}\n onRename={onRename}\n onClearContext={onClearContext}\n onSelectSubagent={onSelectSubagent}\n onRevealStep={onRevealStep}\n />\n ))}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nfunction iconSrcOf(row: SessionRow | undefined, icons: Record<string, string> | undefined): string | undefined {\n const icon = row?.info.project?.icon\n return icon?.type === 'image' ? icons?.[icon.hash] : undefined\n}\n\ninterface SessionRowItemProps {\n row: SessionRow\n active?: boolean\n activeSubagentId?: string\n showGateway?: boolean\n showProject?: boolean\n projectIcons?: Record<string, string>\n onSelect?: (row: SessionRow) => void\n onDelete?: (row: SessionRow) => void\n onRename?: (row: SessionRow, title: string) => void\n onClearContext?: (row: SessionRow) => void\n onSelectSubagent?: (row: SessionRow, toolUseId: string) => void\n onRevealStep?: (row: SessionRow, toolUseId: string) => void\n}\n\nfunction SessionRowItem({\n row,\n active,\n activeSubagentId,\n showGateway,\n showProject = true,\n projectIcons,\n onSelect,\n onDelete,\n onRename,\n onClearContext,\n onSelectSubagent,\n onRevealStep,\n}: SessionRowItemProps) {\n const { info } = row\n const [editing, setEditing] = useState(false)\n\n return (\n <SessionItem\n row={row}\n active={active === true}\n activeStepKey={activeSubagentId}\n showGateway={showGateway}\n showProject={showProject}\n projectIcons={projectIcons}\n onSelect={() => onSelect?.(row)}\n onSelectSubagent={onSelectSubagent ? (id) => onSelectSubagent(row, id) : undefined}\n onRevealStep={onRevealStep ? (id) => onRevealStep(row, id) : undefined}\n onRename={onRename ? (title) => onRename(row, title) : undefined}\n renameOn=\"external\"\n editing={editing}\n onEditingChange={setEditing}\n actions={\n <>\n {onRename && !editing ? (\n <RowAction label=\"Rename session\" onClick={() => setEditing(true)}>\n <Pencil className=\"size-3 text-fg-3\" />\n </RowAction>\n ) : null}\n {onClearContext && info.capabilities?.clearContext ? (\n <RowAction\n label=\"Clear context\"\n title=\"Clear the conversation — the session keeps running and the old conversation stays resumable\"\n onClick={() => onClearContext(row)}\n >\n <Eraser className=\"size-3 text-fg-3\" />\n </RowAction>\n ) : null}\n {onDelete ? (\n <RowAction label=\"Close session\" onClick={() => onDelete(row)}>\n <Trash2 className=\"size-3 text-fg-3\" />\n </RowAction>\n ) : null}\n </>\n }\n />\n )\n}\n\nfunction RowAction({ label, title, onClick, children }: { label: string; title?: string; onClick: () => void; children: ReactNode }) {\n return (\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n aria-label={label}\n title={title ?? label}\n className=\"size-5 shrink-0 opacity-0 transition-opacity group-hover:opacity-100\"\n onClick={(e) => {\n e.stopPropagation()\n onClick()\n }}\n >\n {children}\n </Button>\n )\n}\n\nfunction FilterRow({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2\">\n <span aria-hidden className=\"w-14 shrink-0 truncate text-label text-fg-3\">\n {label}\n </span>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </div>\n )\n}\n\nfunction FacetSelect({\n label,\n value,\n options,\n onChange,\n}: {\n label: string\n value: string[]\n options: { value: string; label: string }[]\n onChange: (value: string[]) => void\n}) {\n return (\n <div className=\"flex items-center gap-1\">\n <Select multiple value={value} onValueChange={(v) => onChange(v as string[])}>\n <SelectTrigger aria-label={label} className=\"min-w-0 flex-1\">\n <SelectValue>\n {value.length === 0\n ? 'All'\n : value.length === 1\n ? (options.find((o) => o.value === value[0])?.label ?? 'All')\n : `${value.length} selected`}\n </SelectValue>\n </SelectTrigger>\n <SelectContent>\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n <SelectItemText>{option.label}</SelectItemText>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {value.length > 0 ? (\n <Button variant=\"ghost\" size=\"icon-sm\" aria-label={`Clear ${label}`} onClick={() => onChange([])}>\n <X className=\"size-3 text-fg-4\" />\n </Button>\n ) : null}\n </div>\n )\n}\n\nfunction OneOfSelect({\n label,\n value,\n options,\n onChange,\n}: {\n label: string\n value: string\n options: readonly { value: string; label: string }[]\n onChange: (value: string) => void\n}) {\n return (\n <Select value={value} onValueChange={(v) => onChange(v as string)}>\n <SelectTrigger aria-label={label} className=\"w-full min-w-0\">\n <SelectValue>{options.find((o) => o.value === value)?.label ?? label}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {options.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n <SelectItemText>{option.label}</SelectItemText>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n"],"mappings":"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"}
package/build/scoped.css CHANGED
@@ -227,6 +227,17 @@
227
227
  .wd-root .visible {
228
228
  visibility: visible;
229
229
  }
230
+ .wd-root .sr-only {
231
+ position: absolute;
232
+ width: 1px;
233
+ height: 1px;
234
+ padding: 0;
235
+ margin: -1px;
236
+ overflow: hidden;
237
+ clip-path: inset(50%);
238
+ white-space: nowrap;
239
+ border-width: 0;
240
+ }
230
241
  .wd-root .absolute {
231
242
  position: absolute;
232
243
  }
@@ -1025,6 +1036,9 @@
1025
1036
  .wd-root .border-l-accent {
1026
1037
  border-left-color: var(--accent);
1027
1038
  }
1039
+ .wd-root .bg-\[var\(--sdm-bg\,inherit\)\] {
1040
+ background-color: var(--sdm-bg,inherit);
1041
+ }
1028
1042
  .wd-root .bg-\[var\(--sdm-tbg\)\] {
1029
1043
  background-color: var(--sdm-tbg);
1030
1044
  }
@@ -1670,6 +1684,10 @@
1670
1684
  --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
1671
1685
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1672
1686
  }
1687
+ .wd-root .ring {
1688
+ --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1689
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
1690
+ }
1673
1691
  .wd-root .ring-2 {
1674
1692
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
1675
1693
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -2059,6 +2077,9 @@
2059
2077
  backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
2060
2078
  }
2061
2079
  }
2080
+ .wd-root .dark\:bg-\[var\(--shiki-dark-bg\,var\(--sdm-bg\,inherit\)\)\]:where([data-theme='dark'],[data-theme='dark'] *) {
2081
+ background-color: var(--shiki-dark-bg,var(--sdm-bg,inherit));
2082
+ }
2062
2083
  .wd-root .dark\:bg-\[var\(--shiki-dark-bg\,var\(--sdm-tbg\)\)\]:where([data-theme='dark'],[data-theme='dark'] *) {
2063
2084
  background-color: var(--shiki-dark-bg,var(--sdm-tbg));
2064
2085
  }
@@ -1,4 +1,13 @@
1
1
  //#region src/lib/format.ts
2
+ /**
3
+ * The whole payload of a `compaction` row. The wire event carries no summary because codex's
4
+ * `contextCompaction` item carries none, so the sentence *is* the content.
5
+ *
6
+ * It lives here, in a pure module, because the renderer (`terminal/items.tsx`) and the height book
7
+ * (`terminal/height.ts`) must measure and draw the same string — height.ts cannot import the
8
+ * `.tsx` without pulling React into a module the tests require to stay pure.
9
+ */
10
+ const COMPACTION_TEXT = "context compacted · earlier turns summarised to fit the window";
2
11
  function formatCost(usd) {
3
12
  if (usd === void 0 || Number.isNaN(usd)) return "—";
4
13
  if (usd === 0) return "$0.00";
@@ -17,7 +26,7 @@ function formatTokens(tokens) {
17
26
  return String(Math.round(tokens));
18
27
  }
19
28
  function formatBytes(bytes) {
20
- if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
29
+ if (bytes >= 1048576) return `${(bytes / 1048576).toFixed(1)} MB`;
21
30
  if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;
22
31
  return `${bytes} B`;
23
32
  }
@@ -57,8 +66,8 @@ function formatRateLimitWindowLong(key) {
57
66
  return `Weekly · ${capitalize(key.slice(10).replaceAll("_", " "))}`;
58
67
  }
59
68
  function rateLimitWindowSeconds(key) {
60
- if (key === "five_hour") return 5 * 3600;
61
- if (key.startsWith("seven_day")) return 7 * 86400;
69
+ if (key === "five_hour") return 18e3;
70
+ if (key.startsWith("seven_day")) return 604800;
62
71
  }
63
72
  function formatAgoPrecise(epochMs, now = Date.now()) {
64
73
  const seconds = Math.max(0, Math.floor((now - epochMs) / 1e3));
@@ -238,6 +247,6 @@ function meterTintClass(pct) {
238
247
  return pct >= 90 ? "bg-danger" : pct >= 70 ? "bg-warning" : "bg-accent";
239
248
  }
240
249
  //#endregion
241
- export { toolInputPreview as S, formatRateLimitWindowLong as _, meterTintClass as a, friendlyModel as b, tightestWindow as c, formatAgoPrecise as d, formatBytes as f, formatRateLimitWindow as g, formatDuration as h, meterSeverity as i, usageWindow as l, formatCountdown as m, currentModel as n, modelLabel as o, formatCost as p, meterColorClass as r, statusPresentation as s, contextSeverity as t, windowLabel as u, formatRelativeTime as v, rateLimitWindowSeconds as x, formatTokens as y };
250
+ export { toolInputPreview as C, rateLimitWindowSeconds as S, formatRateLimitWindow as _, meterTintClass as a, formatTokens as b, tightestWindow as c, COMPACTION_TEXT as d, formatAgoPrecise as f, formatDuration as g, formatCountdown as h, meterSeverity as i, usageWindow as l, formatCost as m, currentModel as n, modelLabel as o, formatBytes as p, meterColorClass as r, statusPresentation as s, contextSeverity as t, windowLabel as u, formatRateLimitWindowLong as v, friendlyModel as x, formatRelativeTime as y };
242
251
 
243
- //# sourceMappingURL=status-C0HSLZas.mjs.map
252
+ //# sourceMappingURL=status-BW2xj79g.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-BW2xj79g.mjs","names":[],"sources":["../src/lib/format.ts","../src/lib/status.ts"],"sourcesContent":["/**\n * The whole payload of a `compaction` row. The wire event carries no summary because codex's\n * `contextCompaction` item carries none, so the sentence *is* the content.\n *\n * It lives here, in a pure module, because the renderer (`terminal/items.tsx`) and the height book\n * (`terminal/height.ts`) must measure and draw the same string — height.ts cannot import the\n * `.tsx` without pulling React into a module the tests require to stay pure.\n */\nexport const COMPACTION_TEXT = 'context compacted · earlier turns summarised to fit the window'\n\nexport function formatCost(usd: number | undefined): string {\n if (usd === undefined || Number.isNaN(usd)) {\n return '—'\n }\n if (usd === 0) {\n return '$0.00'\n }\n if (usd < 0.01) {\n return '<$0.01'\n }\n return `$${usd.toFixed(2)}`\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) {\n return `${Math.round(ms)}ms`\n }\n const s = ms / 1000\n if (s < 60) {\n return `${s.toFixed(1)}s`\n }\n const m = Math.floor(s / 60)\n return `${m}m ${Math.round(s % 60)}s`\n}\n\nexport function formatTokens(tokens: number): string {\n if (tokens >= 1_000_000) {\n return `${(tokens / 1_000_000).toFixed(1)}M`\n }\n if (tokens >= 1000) {\n return `${(tokens / 1000).toFixed(1)}k`\n }\n return String(Math.round(tokens))\n}\n\nexport function formatBytes(bytes: number): string {\n if (bytes >= 1024 * 1024) {\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n }\n if (bytes >= 1024) {\n return `${(bytes / 1024).toFixed(1)} KB`\n }\n return `${bytes} B`\n}\n\nexport function formatCountdown(untilEpochMs: number, now = Date.now()): string {\n const remaining = untilEpochMs - now\n if (remaining <= 0) {\n return 'now'\n }\n const minutes = Math.ceil(remaining / 60_000)\n if (minutes < 1) {\n return '<1m'\n }\n if (minutes < 60) {\n return `${minutes}m`\n }\n const days = Math.floor(minutes / (60 * 24))\n if (days >= 1) {\n return `${days}d ${Math.floor((minutes % (60 * 24)) / 60)}h`\n }\n return `${Math.floor(minutes / 60)}h ${minutes % 60}m`\n}\n\nexport function formatRelativeTime(epochMs: number | undefined, now = Date.now()): string {\n if (!epochMs) {\n return '—'\n }\n const diff = Math.max(0, now - epochMs)\n const s = Math.floor(diff / 1000)\n if (s < 60) {\n return 'just now'\n }\n const m = Math.floor(s / 60)\n if (m < 60) {\n return `${m}m ago`\n }\n const h = Math.floor(m / 60)\n if (h < 24) {\n return `${h}h ago`\n }\n const d = Math.floor(h / 24)\n return `${d}d ago`\n}\n\nexport function formatRateLimitWindow(key: string): string {\n if (key === 'five_hour') {\n return '5h'\n }\n if (key === 'seven_day') {\n return '7d'\n }\n const spaced = key.replaceAll('_', ' ')\n return key.startsWith('seven_day_') ? `7d ${spaced.slice('seven day '.length)}` : spaced\n}\n\nexport function formatRateLimitWindowLong(key: string): string {\n if (key === 'five_hour') {\n return '5-hour session'\n }\n if (key === 'seven_day') {\n return 'Weekly'\n }\n if (key === 'seven_day_oauth_apps') {\n return 'Weekly · apps'\n }\n const capitalize = (s: string) => s.replace(/\\b\\w/g, (c) => c.toUpperCase())\n if (!key.startsWith('seven_day_')) {\n return capitalize(key.replaceAll('_', ' '))\n }\n return `Weekly · ${capitalize(key.slice('seven_day_'.length).replaceAll('_', ' '))}`\n}\n\nexport function rateLimitWindowSeconds(key: string): number | undefined {\n if (key === 'five_hour') {\n return 5 * 3600\n }\n if (key.startsWith('seven_day')) {\n return 7 * 86_400\n }\n return undefined\n}\n\nexport function formatAgoPrecise(epochMs: number, now = Date.now()): string {\n const seconds = Math.max(0, Math.floor((now - epochMs) / 1000))\n if (seconds < 60) {\n return `${seconds} sec${seconds === 1 ? '' : 's'} ago`\n }\n if (seconds < 3600) {\n const minutes = Math.floor(seconds / 60)\n return `${minutes} min${minutes === 1 ? '' : 's'} ago`\n }\n const hours = Math.floor(seconds / 3600)\n return `${hours} hour${hours === 1 ? '' : 's'} ago`\n}\n\nexport function toolInputPreview(input: unknown, max = 80): string {\n if (input === null || input === undefined) {\n return ''\n }\n if (typeof input === 'object') {\n const o = input as Record<string, unknown>\n const primary = o.command ?? o.file_path ?? o.path ?? o.url ?? o.pattern ?? o.query ?? o.description\n if (typeof primary === 'string') {\n return primary.length > max ? primary.slice(0, max - 1) + '…' : primary\n }\n }\n const text = JSON.stringify(input) ?? ''\n return text.length > max ? text.slice(0, max - 1) + '…' : text\n}\n\nconst MODEL_FAMILIES: Record<string, { name: string; joiner?: string }> = {\n gpt: { name: 'GPT', joiner: '-' },\n deepseek: { name: 'DeepSeek' },\n glm: { name: 'GLM' },\n qwen: { name: 'Qwen' },\n kimi: { name: 'Kimi' },\n llama: { name: 'Llama' },\n mistral: { name: 'Mistral' },\n grok: { name: 'Grok' },\n}\n\nexport function friendlyModel(id: string | undefined): string | undefined {\n if (!id) {\n return undefined\n }\n const withoutVariant = id.split('[')[0] ?? id\n const parts = withoutVariant.toLowerCase().split('-').filter(Boolean)\n if (parts[0] === 'claude') {\n parts.shift()\n }\n const familyToken = parts.shift()\n if (!familyToken) {\n return id\n }\n const family = MODEL_FAMILIES[familyToken]\n const name =\n family?.name ??\n // OpenAI's reasoning series is lower-case by its own convention ('o3-mini'); \"O3\" reads as a different product.\n (/^o\\d+$/.test(familyToken) ? familyToken : `${familyToken.charAt(0).toUpperCase()}${familyToken.slice(1)}`)\n\n const version: string[] = []\n const words: string[] = []\n for (const part of parts) {\n if (/^\\d{8}$/.test(part)) {\n continue\n }\n if (/^\\d+(\\.\\d+)?$/.test(part)) {\n version.push(part)\n } else {\n words.push(`${part.charAt(0).toUpperCase()}${part.slice(1)}`)\n }\n }\n const versioned = version.length > 0 ? `${name}${family?.joiner ?? ' '}${version.join('.')}` : name\n return [versioned, ...words].join(' ')\n}\n","import type { ModelOption, RateLimitInfo, SessionStatus } from '@workerdeck/protocol'\n\nexport type StatusSeverity = 'none' | 'warning' | 'error'\n\nexport type StatusPresentation = {\n icon: string\n label: string\n severity: StatusSeverity\n}\n\nexport type StatusReadings = {\n status: SessionStatus\n connection?: 'live' | 'reconnecting' | 'offline'\n}\n\nconst STATUS_META: Record<SessionStatus, StatusPresentation> = {\n starting: { icon: 'loading~spin', label: 'Starting', severity: 'none' },\n running: { icon: 'loading~spin', label: 'Running', severity: 'none' },\n awaiting_approval: { icon: 'warning', label: 'Needs approval', severity: 'warning' },\n idle: { icon: 'check', label: 'Idle', severity: 'none' },\n parked: { icon: 'debug-pause', label: 'Parked', severity: 'none' },\n failed: { icon: 'error', label: 'Failed', severity: 'error' },\n closed: { icon: 'circle-slash', label: 'Closed', severity: 'none' },\n}\n\nexport function statusPresentation(vitals: StatusReadings | undefined): StatusPresentation {\n if (!vitals) {\n return { icon: 'hubot', label: 'Connecting…', severity: 'none' }\n }\n if (vitals.connection === 'offline') {\n return { icon: 'debug-disconnect', label: 'Offline', severity: 'error' }\n }\n if (vitals.connection === 'reconnecting') {\n return { icon: 'sync~spin', label: 'Reconnecting…', severity: 'warning' }\n }\n return STATUS_META[vitals.status] ?? { icon: 'hubot', label: vitals.status, severity: 'none' }\n}\n\nexport function meterSeverity(pct: number | undefined): StatusSeverity {\n if (pct === undefined) {\n return 'none'\n }\n if (pct >= 95) {\n return 'error'\n }\n if (pct >= 80) {\n return 'warning'\n }\n return 'none'\n}\n\nexport type UsageLane = 'session' | 'weekly' | 'model'\n\nexport function usageWindow(\n rateLimits: Record<string, RateLimitInfo> | undefined,\n lane: UsageLane,\n): { key: string; info: RateLimitInfo } | undefined {\n if (!rateLimits) {\n return undefined\n }\n if (lane === 'session') {\n const info = rateLimits.five_hour\n return info ? { key: 'five_hour', info } : undefined\n }\n if (lane === 'weekly') {\n const info = rateLimits.seven_day\n return info ? { key: 'seven_day', info } : undefined\n }\n const scoped = Object.fromEntries(\n Object.entries(rateLimits).filter(([key]) => key.startsWith('seven_day_') && key !== 'seven_day_oauth_apps'),\n )\n return tightestWindow(scoped)\n}\n\nexport function tightestWindow(rateLimits: Record<string, RateLimitInfo> | undefined): { key: string; info: RateLimitInfo } | undefined {\n const entries = Object.entries(rateLimits ?? {})\n if (entries.length === 0) {\n return undefined\n }\n let best: { key: string; info: RateLimitInfo } | undefined\n for (const [key, info] of entries) {\n const rank = info.status === 'rejected' ? Number.POSITIVE_INFINITY : (info.utilization ?? -1)\n const bestRank =\n best === undefined\n ? Number.NEGATIVE_INFINITY\n : best.info.status === 'rejected'\n ? Number.POSITIVE_INFINITY\n : (best.info.utilization ?? -1)\n if (rank > bestRank) {\n best = { key, info }\n }\n }\n return best\n}\n\nexport function windowLabel(key: string): string {\n if (key === 'five_hour') {\n return 'Session'\n }\n if (key === 'seven_day') {\n return 'Weekly'\n }\n const scoped = key.startsWith('seven_day_') ? key.slice('seven_day_'.length) : key\n const words = scoped.replaceAll('_', ' ')\n return words.charAt(0).toUpperCase() + words.slice(1)\n}\n\nexport type ModelReadings = { model?: string; models: readonly ModelOption[] }\n\nexport function currentModel(vitals: ModelReadings | undefined): ModelOption | undefined {\n const id = vitals?.model\n if (!id) {\n return undefined\n }\n const bare = (value: string) => value.replace(/\\[.*\\]$/, '')\n const wanted = bare(id)\n return vitals.models.find((m) => bare(m.value) === wanted || (m.resolvedModel && bare(m.resolvedModel) === wanted))\n}\n\nexport function modelLabel(vitals: ModelReadings | undefined): string {\n if (!vitals?.model) {\n return 'Default'\n }\n return currentModel(vitals)?.displayName ?? vitals.model\n}\n\nexport function contextSeverity(usage: { percentage: number } | undefined): StatusSeverity {\n return meterSeverity(usage?.percentage)\n}\n\nexport function meterColorClass(pct: number | undefined): string {\n const severity = meterSeverity(pct)\n return severity === 'error' ? 'text-danger' : severity === 'warning' ? 'text-warning' : 'text-fg-3'\n}\n\n/**\n * The fill colour for a meter bar. Deliberately a different ramp from\n * {@link meterColorClass}: a bar reads as alarming later than a number does, so the tint\n * turns at 70/90 where the text severity turns at 80/95.\n */\nexport function meterTintClass(pct: number): string {\n return pct >= 90 ? 'bg-danger' : pct >= 70 ? 'bg-warning' : 'bg-accent'\n}\n"],"mappings":"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"}