@invergent/agent-chat-react 2.19.0 → 2.19.2

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/dist/index.js CHANGED
@@ -1,14 +1,15 @@
1
1
  import { cn, __publicField } from './chunk-47MF6JUW.js';
2
2
  import { createContext, memo, useRef, useEffect, useCallback, useMemo, useState, useLayoutEffect, lazy, useContext, Fragment as Fragment$1, Suspense, useSyncExternalStore, useId, Children } from 'react';
3
3
  import { Button } from '@invergent/ui-sdk/button';
4
+ import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '@invergent/ui-sdk/dropdown-menu';
5
+ import { TabStrip, TabStripTab } from '@invergent/ui-sdk/tab-strip';
6
+ import { Toggle, FilterPill } from '@invergent/ui-sdk/toggle';
4
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
8
  import { ConfirmDialog } from '@invergent/ui-sdk/confirm-dialog';
6
9
  import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@invergent/ui-sdk/dialog';
7
- import { ChevronDownIcon, AlertTriangle, ChevronDown, ChevronRight as ChevronRight$1, RefreshCw, CreditCard, File as File$1, FileImage, FileAudio, FileVideo, FileText, FileCode, FileArchive, FileSpreadsheet, PlugZapIcon, ChevronRightIcon, ArrowLeftIcon, Loader2Icon, InboxIcon, Loader2, AlertCircle, Pause, Play, Ban, TargetIcon, CalendarClockIcon, UsersIcon, Pen, Eraser, Type, MousePointer2, Hand, Maximize2, Undo2, Redo2, CheckIcon, CopyIcon, DownloadIcon, Maximize2Icon, LaptopIcon, MessageSquareIcon, UploadIcon, RefreshCwIcon, AlertCircleIcon, ExternalLinkIcon, ClipboardCheckIcon, ShieldAlertIcon, TimerIcon, CircleDotIcon, ChevronLeftIcon, Trash2Icon, SquareIcon, ArrowDownIcon, FileIcon, TrashIcon, FileTextIcon, Minimize2Icon, XIcon, Clock, ArrowRight, ListTreeIcon, PenLineIcon, PaperclipIcon, CloudIcon, HardDriveIcon, IdCardIcon, PlusIcon, TerminalIcon, SparklesIcon, ClockIcon, ShrinkIcon, FolderOpenIcon, FolderIcon, ImageIcon, CircleDot, XCircle, CheckCircle2, GlobeIcon, SearchIcon, ZapIcon, PanelTopIcon, ArrowUpIcon, ThumbsUpIcon, ThumbsDownIcon, FileCodeIcon, CodeIcon, FileArchiveIcon, FileVideoIcon, FileAudioIcon, FileImageIcon, FileChartLineIcon, FileSpreadsheetIcon, BookOpenIcon, GitBranchIcon, ActivityIcon, EyeIcon, LibraryIcon, ListTodoIcon, XCircleIcon, CheckCircle2Icon, Code, CircleCheckIcon, CircleXIcon, SkullIcon, CheckCircleIcon, CircleIcon } from 'lucide-react';
10
+ import { ChevronDownIcon, AlertTriangle, ChevronDown, ChevronRight as ChevronRight$1, RefreshCw, CreditCard, File as File$1, FileImage, FileAudio, FileVideo, FileText, FileCode, FileArchive, FileSpreadsheet, PlugZapIcon, ChevronRightIcon, ArrowLeftIcon, Loader2Icon, InboxIcon, Loader2, AlertCircle, Pause, Play, Ban, TargetIcon, CalendarClockIcon, Pen, Eraser, Type, MousePointer2, Hand, Maximize2, Undo2, Redo2, CheckIcon, CopyIcon, DownloadIcon, Maximize2Icon, LaptopIcon, MessageSquareIcon, UploadIcon, RefreshCwIcon, AlertCircleIcon, ExternalLinkIcon, ClipboardCheckIcon, ShieldAlertIcon, TimerIcon, CircleDotIcon, ChevronLeftIcon, Trash2Icon, SquareIcon, ArrowDownIcon, FileIcon, TrashIcon, FileTextIcon, Minimize2Icon, XIcon, Clock, ArrowRight, MinusIcon, PlusIcon, ListTreeIcon, PenLineIcon, PaperclipIcon, CloudIcon, HardDriveIcon, IdCardIcon, TerminalIcon, SparklesIcon, ClockIcon, ShrinkIcon, FolderOpenIcon, FolderIcon, ImageIcon, CircleDot, XCircle, CheckCircle2, GlobeIcon, SearchIcon, ZapIcon, PanelTopIcon, ArrowUpIcon, ThumbsUpIcon, ThumbsDownIcon, FileCodeIcon, CodeIcon, FileArchiveIcon, FileVideoIcon, FileAudioIcon, FileImageIcon, FileChartLineIcon, FileSpreadsheetIcon, BookOpenIcon, GitBranchIcon, ActivityIcon, EyeIcon, LibraryIcon, ListTodoIcon, XCircleIcon, CheckCircle2Icon, Code, CircleCheckIcon, CircleXIcon, SkullIcon, CheckCircleIcon, CircleIcon } from 'lucide-react';
8
11
  import { StickToBottom, useStickToBottomContext } from 'use-stick-to-bottom';
9
- import { cva } from 'class-variance-authority';
10
- import { Progress as Progress$1, Dialog as Dialog$1, Slot } from 'radix-ui';
11
- import '@invergent/ui-sdk/separator';
12
+ import { ButtonGroup } from '@invergent/ui-sdk/button-group';
12
13
  import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from '@invergent/ui-sdk/tooltip';
13
14
  import { cjk } from '@streamdown/cjk';
14
15
  import { code } from '@streamdown/code';
@@ -18,29 +19,46 @@ import { defaultRehypePlugins, Streamdown } from 'streamdown';
18
19
  import { useControllableState } from '@radix-ui/react-use-controllable-state';
19
20
  import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '@invergent/ui-sdk/collapsible';
20
21
  import { ThinkingOrb } from 'thinking-orbs';
22
+ import { Timeline, TimelineItem, TimelineHeader, TimelineSeparator, TimelineIndicator, TimelineContent } from '@invergent/ui-sdk/timeline';
23
+ import { CollapsibleHeader } from '@invergent/ui-sdk/collapsible-header';
21
24
  import { ScrollArea } from '@invergent/ui-sdk/scroll-area';
22
25
  import '@invergent/ui-sdk/select';
23
26
  import { createHighlighter } from 'shiki';
24
27
  import { Tabs, TabsList, TabsTrigger, TabsContent } from '@invergent/ui-sdk/tabs';
25
- import { Badge } from '@invergent/ui-sdk/badge';
28
+ import { TagPill, TonePill, TONE, Chip } from '@invergent/ui-sdk/chip';
29
+ import { TextLink } from '@invergent/ui-sdk/text-link';
26
30
  import { diffLines, diffWordsWithSpace } from 'diff';
27
31
  import AnsiImport from 'ansi-to-react';
28
32
  import { Textarea } from '@invergent/ui-sdk/textarea';
33
+ import { ChoiceCard, choiceCardVariants } from '@invergent/ui-sdk/choice-card';
29
34
  import { Input } from '@invergent/ui-sdk/input';
30
- import { Command as Command$1 } from 'cmdk';
35
+ import { Command, CommandList, CommandGroup, CommandItem, CommandEmpty } from '@invergent/ui-sdk/command';
36
+ import '@invergent/ui-sdk/hover-card';
31
37
  import { InputGroupButton, InputGroup, InputGroupTextarea, InputGroupAddon } from '@invergent/ui-sdk/input-group';
32
- import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from '@invergent/ui-sdk/dropdown-menu';
33
38
  import { Spinner } from '@invergent/ui-sdk/spinner';
34
39
  import { nanoid } from 'nanoid';
35
40
  import { BrandBeam } from '@invergent/ui-sdk/brand-beam';
36
41
  export { BrandBeam } from '@invergent/ui-sdk/brand-beam';
42
+ import { ProgressBar } from '@invergent/ui-sdk/progress-bar';
37
43
  import 'tokenlens';
38
- import { Popover, PopoverAnchor, PopoverTrigger, PopoverContent } from '@invergent/ui-sdk/popover';
44
+ import { Item, ItemMedia, ItemContent, ItemTitle, ItemDescription, ItemActions } from '@invergent/ui-sdk/item';
45
+ import { Popover, PopoverAnchor, PopoverContent } from '@invergent/ui-sdk/popover';
46
+ import { ResponsivePanel } from '@invergent/ui-sdk/responsive-panel';
47
+ import { Command as Command$1 } from 'cmdk';
39
48
  import { Skeleton } from '@invergent/ui-sdk/skeleton';
49
+ import { ListRow, listRowVariants } from '@invergent/ui-sdk/list-row';
50
+ import { Alert, AlertTitle, AlertDescription, AlertAction } from '@invergent/ui-sdk/alert';
40
51
  import { Checkbox } from '@invergent/ui-sdk/checkbox';
41
52
  import { Label } from '@invergent/ui-sdk/label';
53
+ import { SegmentedControl } from '@invergent/ui-sdk/segmented-control';
54
+ import { RabbitMark, RABBIT_MARK_BOX, RABBIT_MARK_PATH } from '@invergent/ui-sdk/rabbit-mark';
55
+ import { ViewSwitch, ToggleGroup, ToggleGroupItem } from '@invergent/ui-sdk/toggle-group';
42
56
  import { useTheme } from 'next-themes';
57
+ import { EmptyState } from '@invergent/ui-sdk/empty-state';
58
+ import { SectionLabel } from '@invergent/ui-sdk/section-label';
59
+ import { CONTROL_FIELD, CONTROL_OPTION } from '@invergent/ui-sdk/control-styles';
43
60
  import { formatDistanceToNow } from 'date-fns';
61
+ import { Badge } from '@invergent/ui-sdk/badge';
44
62
  import { Card, CardContent, CardHeader, CardTitle, CardAction } from '@invergent/ui-sdk/card';
45
63
 
46
64
  var AgentChatAdapterContext = createContext(null);
@@ -174,7 +192,6 @@ function BrowserShell({
174
192
  const [frame, setFrame] = useState(null);
175
193
  const [tabs, setTabs] = useState([]);
176
194
  const [nav, setNav] = useState({ url: "", title: "" });
177
- const [menuOpen, setMenuOpen] = useState(false);
178
195
  const [address, setAddress] = useState("");
179
196
  const editingRef = useRef(false);
180
197
  useEffect(() => {
@@ -329,15 +346,13 @@ function BrowserShell({
329
346
  }
330
347
  ),
331
348
  (onToggleControl || hasControl) && /* @__PURE__ */ jsx(
332
- Button,
349
+ Toggle,
333
350
  {
334
- type: "button",
335
- variant: hasControl ? "default" : "ghost",
336
351
  size: "icon-xs",
337
352
  "data-testid": "browser-shell-control",
338
353
  "aria-label": hasControl ? "Return control" : "Take control",
339
- "aria-pressed": hasControl,
340
- onClick: onToggleControl,
354
+ pressed: hasControl,
355
+ onPressedChange: () => onToggleControl?.(),
341
356
  children: /* @__PURE__ */ jsx(Pointer, {})
342
357
  }
343
358
  ),
@@ -386,93 +401,30 @@ function BrowserShell({
386
401
  ]
387
402
  }
388
403
  ),
389
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
390
- /* @__PURE__ */ jsx(
391
- Button,
392
- {
393
- type: "button",
394
- variant: "ghost",
395
- size: "icon-xs",
396
- "aria-label": "More",
397
- onClick: () => setMenuOpen((open) => !open),
398
- children: /* @__PURE__ */ jsx(Ellipsis, {})
399
- }
400
- ),
401
- menuOpen && /* @__PURE__ */ jsxs(
402
- "div",
403
- {
404
- "data-testid": "browser-shell-menu",
405
- className: "absolute right-0 top-8 z-10 min-w-36 rounded-md border border-line bg-card py-1 text-xs shadow-md",
406
- children: [
407
- onMaximize && /* @__PURE__ */ jsx(
408
- "button",
409
- {
410
- type: "button",
411
- className: "block w-full px-3 py-1.5 text-left hover:bg-secondary",
412
- onClick: () => {
413
- setMenuOpen(false);
414
- onMaximize();
415
- },
416
- children: "Maximize"
417
- }
418
- ),
419
- onClose && /* @__PURE__ */ jsx(
420
- "button",
421
- {
422
- type: "button",
423
- className: "block w-full px-3 py-1.5 text-left hover:bg-secondary",
424
- onClick: () => {
425
- setMenuOpen(false);
426
- onClose();
427
- },
428
- children: "Close browser"
429
- }
430
- )
431
- ]
432
- }
433
- )
404
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
405
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", "aria-label": "More", children: /* @__PURE__ */ jsx(Ellipsis, {}) }) }),
406
+ /* @__PURE__ */ jsxs(DropdownMenuContent, { "data-testid": "browser-shell-menu", align: "end", children: [
407
+ onMaximize && /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: onMaximize, children: "Maximize" }),
408
+ onClose && /* @__PURE__ */ jsx(DropdownMenuItem, { onSelect: onClose, children: "Close browser" })
409
+ ] })
434
410
  ] })
435
411
  ] }),
436
412
  showTabs && /* @__PURE__ */ jsx(
437
- "div",
413
+ TabStrip,
438
414
  {
439
415
  "data-testid": "browser-shell-tabs",
440
- className: "flex min-h-[34px] items-center gap-0.5 border-b border-line bg-card px-1.5",
441
- children: tabs.map((tab) => (
442
- // A div, not a button: the close control nests inside, and a
443
- // button inside a button is invalid markup.
444
- /* @__PURE__ */ jsxs(
445
- "div",
446
- {
447
- role: "tab",
448
- tabIndex: 0,
449
- "aria-selected": tab.active,
450
- "data-testid": "browser-shell-tab",
451
- onClick: () => send({ t: "switch_tab", id: tab.id }),
452
- onKeyDown: (event) => {
453
- if (event.key === "Enter") send({ t: "switch_tab", id: tab.id });
454
- },
455
- className: `flex h-6 max-w-33 cursor-pointer items-center gap-1 truncate rounded px-2 text-[11px] ${tab.active ? "bg-secondary text-foreground" : "text-muted-foreground hover:text-foreground"}`,
456
- children: [
457
- /* @__PURE__ */ jsx("span", { className: "truncate", children: tab.title || tab.url }),
458
- hasControl && /* @__PURE__ */ jsx(
459
- "button",
460
- {
461
- type: "button",
462
- "data-testid": "browser-shell-tab-close",
463
- "aria-label": `Close ${tab.title || tab.url}`,
464
- onClick: (event) => {
465
- event.stopPropagation();
466
- command({ t: "close_tab", id: tab.id });
467
- },
468
- className: "flex size-3.5 shrink-0 items-center justify-center rounded-sm text-muted-foreground hover:bg-secondary hover:text-foreground",
469
- children: /* @__PURE__ */ jsx(XSmall, {})
470
- }
471
- )
472
- ]
473
- },
474
- tab.id
475
- )
416
+ className: "min-h-[34px] border-b border-line bg-card px-1.5",
417
+ children: tabs.map((tab) => /* @__PURE__ */ jsx(
418
+ TabStripTab,
419
+ {
420
+ active: tab.active,
421
+ "data-testid": "browser-shell-tab",
422
+ onSelect: () => send({ t: "switch_tab", id: tab.id }),
423
+ onClose: hasControl ? () => command({ t: "close_tab", id: tab.id }) : void 0,
424
+ closeLabel: `Close ${tab.title || tab.url}`,
425
+ children: tab.title || tab.url
426
+ },
427
+ tab.id
476
428
  ))
477
429
  }
478
430
  ),
@@ -552,10 +504,6 @@ var Pointer = () => /* @__PURE__ */ jsxs("svg", { ...svg, children: [
552
504
  /* @__PURE__ */ jsx("path", { d: "M12.586 12.586 19 19" }),
553
505
  /* @__PURE__ */ jsx("path", { d: "M3.688 3.037a.497.497 0 0 0-.651.651l6.5 15.999a.501.501 0 0 0 .947-.062l1.569-6.083a2 2 0 0 1 1.448-1.479l6.124-1.579a.5.5 0 0 0 .063-.947z" })
554
506
  ] });
555
- var XSmall = () => /* @__PURE__ */ jsxs("svg", { ...svg, width: 10, height: 10, className: "size-2.5", children: [
556
- /* @__PURE__ */ jsx("path", { d: "M18 6 6 18" }),
557
- /* @__PURE__ */ jsx("path", { d: "m6 6 12 12" })
558
- ] });
559
507
  var Ellipsis = () => /* @__PURE__ */ jsxs("svg", { ...svg, children: [
560
508
  /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1" }),
561
509
  /* @__PURE__ */ jsx("circle", { cx: "19", cy: "12", r: "1" }),
@@ -867,36 +815,6 @@ var ConversationScrollButton = ({
867
815
  }
868
816
  );
869
817
  };
870
- var buttonGroupVariants = cva(
871
- "group/button-group flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 has-[>[data-slot=button-group]]:gap-2 *:data-[slot=input]:px-4 has-[>[data-variant=outline]]:*:data-[slot=input-group]:border-border has-[>[data-variant=outline]]:*:data-[slot=input-group]:px-2.5 has-[>[data-variant=outline]]:*:data-[slot=select-trigger]:border-border has-[>[data-variant=outline]]:*:[[role=combobox]]:px-2.5 has-[>[data-variant=outline]]:[&>[data-slot=input-group]:has(:focus-visible)]:border-ring has-[>[data-variant=outline]]:[&>[data-slot=select-trigger]:focus-visible]:border-ring has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-none [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[>[data-variant=outline]]:[&>input]:border-border has-[>[data-variant=outline]]:[&>input:focus-visible]:border-ring",
872
- {
873
- variants: {
874
- orientation: {
875
- horizontal: "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-none!",
876
- vertical: "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-none!"
877
- }
878
- },
879
- defaultVariants: {
880
- orientation: "horizontal"
881
- }
882
- }
883
- );
884
- function ButtonGroup({
885
- className,
886
- orientation,
887
- ...props
888
- }) {
889
- return /* @__PURE__ */ jsx(
890
- "div",
891
- {
892
- role: "group",
893
- "data-slot": "button-group",
894
- "data-orientation": orientation,
895
- className: cn(buttonGroupVariants({ orientation }), className),
896
- ...props
897
- }
898
- );
899
- }
900
818
  var streamdownRehypePlugins = Object.entries(defaultRehypePlugins).map(([name, plugin]) => {
901
819
  if (name !== "harden" || !Array.isArray(plugin)) return plugin;
902
820
  const [harden, options] = plugin;
@@ -1203,128 +1121,6 @@ var ReasoningContent = memo(
1203
1121
  Reasoning.displayName = "Reasoning";
1204
1122
  ReasoningTrigger.displayName = "ReasoningTrigger";
1205
1123
  ReasoningContent.displayName = "ReasoningContent";
1206
- var TimelineContext = createContext(
1207
- void 0
1208
- );
1209
- var useTimeline = () => {
1210
- const context = useContext(TimelineContext);
1211
- if (!context) {
1212
- throw new Error("useTimeline must be used within a Timeline");
1213
- }
1214
- return context;
1215
- };
1216
- function Timeline({
1217
- defaultValue = 1,
1218
- value,
1219
- onValueChange,
1220
- orientation = "vertical",
1221
- className,
1222
- children,
1223
- ...props
1224
- }) {
1225
- const [activeStep, setInternalStep] = useState(defaultValue);
1226
- const setActiveStep = useCallback(
1227
- (step) => {
1228
- if (value === void 0) {
1229
- setInternalStep(step);
1230
- }
1231
- onValueChange?.(step);
1232
- },
1233
- [value, onValueChange]
1234
- );
1235
- const currentStep = value ?? activeStep;
1236
- return /* @__PURE__ */ jsx(
1237
- TimelineContext.Provider,
1238
- {
1239
- value: { activeStep: currentStep, setActiveStep },
1240
- children: /* @__PURE__ */ jsx(
1241
- "div",
1242
- {
1243
- className: cn(
1244
- "group/timeline flex flex-col",
1245
- className
1246
- ),
1247
- "data-orientation": orientation,
1248
- "data-slot": "timeline",
1249
- ...props,
1250
- children
1251
- }
1252
- )
1253
- }
1254
- );
1255
- }
1256
- function TimelineContent({
1257
- className,
1258
- ...props
1259
- }) {
1260
- return /* @__PURE__ */ jsx(
1261
- "div",
1262
- {
1263
- className: cn("text-foreground text-sm min-w-0 overflow-hidden", className),
1264
- "data-slot": "timeline-content",
1265
- ...props
1266
- }
1267
- );
1268
- }
1269
- function TimelineHeader({
1270
- className,
1271
- ...props
1272
- }) {
1273
- return /* @__PURE__ */ jsx("div", { className: cn(className), "data-slot": "timeline-header", ...props });
1274
- }
1275
- function TimelineIndicator({
1276
- asChild = false,
1277
- className,
1278
- children,
1279
- ...props
1280
- }) {
1281
- const Comp = asChild ? Slot.Root : "div";
1282
- return /* @__PURE__ */ jsx(
1283
- Comp,
1284
- {
1285
- "aria-hidden": "true",
1286
- className: cn(
1287
- "border-primary/20 group-data-completed/timeline-item:border-primary absolute size-4 rounded-full border-2 top-1.25 -left-6 -translate-x-1/2",
1288
- className
1289
- ),
1290
- "data-slot": "timeline-indicator",
1291
- ...props,
1292
- children
1293
- }
1294
- );
1295
- }
1296
- function TimelineItem({ step, className, ...props }) {
1297
- const { activeStep } = useTimeline();
1298
- return /* @__PURE__ */ jsx(
1299
- "div",
1300
- {
1301
- className: cn(
1302
- "group/timeline-item has-[+[data-completed]]:**:data-[slot=timeline-separator]:bg-primary relative flex flex-col gap-0.5 ms-8 not-last:pb-6",
1303
- className
1304
- ),
1305
- "data-completed": step <= activeStep || void 0,
1306
- "data-slot": "timeline-item",
1307
- ...props
1308
- }
1309
- );
1310
- }
1311
- function TimelineSeparator({
1312
- className,
1313
- ...props
1314
- }) {
1315
- return /* @__PURE__ */ jsx(
1316
- "div",
1317
- {
1318
- "aria-hidden": "true",
1319
- className: cn(
1320
- "bg-primary/10 absolute self-start group-last/timeline-item:hidden -left-6 h-[calc(100%-1rem-0.25rem)] w-0.5 -translate-x-1/2 translate-y-4.5",
1321
- className
1322
- ),
1323
- "data-slot": "timeline-separator",
1324
- ...props
1325
- }
1326
- );
1327
- }
1328
1124
 
1329
1125
  // src/runtime/orb-state.ts
1330
1126
  var ORB_STATE_LABELS = {
@@ -1645,10 +1441,11 @@ function toolErrorSummary(result, max = 180) {
1645
1441
  function CopyButton({ text }) {
1646
1442
  const [copied, setCopied] = useState(false);
1647
1443
  return /* @__PURE__ */ jsx(
1648
- "button",
1444
+ Button,
1649
1445
  {
1650
- type: "button",
1651
- className: "shrink-0 p-0.5 rounded opacity-0 group-hover/in:opacity-100 transition-opacity text-muted-foreground hover:text-foreground",
1446
+ variant: "ghost",
1447
+ size: "icon-xs",
1448
+ className: "opacity-0 text-muted-foreground hover:text-foreground group-hover/in:opacity-100 focus-visible:opacity-100",
1652
1449
  onClick: (e) => {
1653
1450
  e.stopPropagation();
1654
1451
  void navigator.clipboard.writeText(text).then(() => {
@@ -1710,18 +1507,7 @@ function TerminalCollapsible({ command, output, isRunning, hasError }) {
1710
1507
  onOpenChange: setIsOpen,
1711
1508
  className: "not-prose w-full",
1712
1509
  children: [
1713
- /* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "group/trigger flex w-fit items-center gap-2 text-sm transition-colors", children: [
1714
- /* @__PURE__ */ jsx("span", { className: "text-left", children: isRunning ? /* @__PURE__ */ jsx(Shimmer, { as: "span", duration: 1, children: "Running command..." }) : hasError ? /* @__PURE__ */ jsx("span", { className: "font-semibold text-destructive", children: "Command failed" }) : /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: "Command" }) }),
1715
- /* @__PURE__ */ jsx(
1716
- ChevronDownIcon,
1717
- {
1718
- className: cn(
1719
- "size-4 shrink-0 transition-transform",
1720
- isOpen ? "rotate-180" : "rotate-0"
1721
- )
1722
- }
1723
- )
1724
- ] }),
1510
+ /* @__PURE__ */ jsx(CollapsibleHeader, { className: "-ml-2 w-fit max-w-full", children: isRunning ? /* @__PURE__ */ jsx(Shimmer, { as: "span", duration: 1, children: "Running command..." }) : hasError ? /* @__PURE__ */ jsx("span", { className: "font-medium text-destructive", children: "Command failed" }) : /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: "Command" }) }),
1725
1511
  /* @__PURE__ */ jsx(
1726
1512
  CollapsibleContent,
1727
1513
  {
@@ -1845,28 +1631,13 @@ var QueueList = ({
1845
1631
  children,
1846
1632
  className,
1847
1633
  ...props
1848
- }) => /* @__PURE__ */ jsx(ScrollArea, { className: cn("mt-2 -mb-1", className), ...props, children: /* @__PURE__ */ jsx("div", { className: "max-h-40 pr-4", children: /* @__PURE__ */ jsx("ul", { children }) }) });
1634
+ }) => /* @__PURE__ */ jsx(ScrollArea, { className, ...props, children: /* @__PURE__ */ jsx("div", { className: "max-h-40 pr-4", children: /* @__PURE__ */ jsx("ul", { children }) }) });
1849
1635
  var QueueSection = ({
1850
1636
  className,
1851
1637
  defaultOpen = true,
1852
1638
  ...props
1853
1639
  }) => /* @__PURE__ */ jsx(Collapsible, { className: cn(className), defaultOpen, ...props });
1854
- var QueueSectionTrigger = ({
1855
- children,
1856
- className,
1857
- ...props
1858
- }) => /* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1859
- "button",
1860
- {
1861
- className: cn(
1862
- "group flex w-full items-center justify-between rounded-md bg-muted/40 px-3 py-2 text-left font-medium text-muted-foreground text-sm transition-colors hover:bg-muted",
1863
- className
1864
- ),
1865
- type: "button",
1866
- ...props,
1867
- children
1868
- }
1869
- ) });
1640
+ var QueueSectionTrigger = (props) => /* @__PURE__ */ jsx(CollapsibleHeader, { variant: "section", ...props });
1870
1641
  var QueueSectionLabel = ({
1871
1642
  count,
1872
1643
  label,
@@ -1874,7 +1645,6 @@ var QueueSectionLabel = ({
1874
1645
  className,
1875
1646
  ...props
1876
1647
  }) => /* @__PURE__ */ jsxs("span", { className: cn("flex items-center gap-2", className), ...props, children: [
1877
- /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 transition-transform group-data-[state=closed]:-rotate-90" }),
1878
1648
  icon,
1879
1649
  /* @__PURE__ */ jsxs("span", { children: [
1880
1650
  count,
@@ -1885,12 +1655,18 @@ var QueueSectionLabel = ({
1885
1655
  var QueueSectionContent = ({
1886
1656
  className,
1887
1657
  ...props
1888
- }) => /* @__PURE__ */ jsx(CollapsibleContent, { className: cn(className), ...props });
1658
+ }) => /* @__PURE__ */ jsx(
1659
+ CollapsibleContent,
1660
+ {
1661
+ className: cn("border-t border-foreground/[0.08] p-1.5", className),
1662
+ ...props
1663
+ }
1664
+ );
1889
1665
  var Queue = ({ className, ...props }) => /* @__PURE__ */ jsx(
1890
1666
  "div",
1891
1667
  {
1892
1668
  className: cn(
1893
- "flex flex-col gap-2 rounded-xl border border-border bg-background px-3 pt-2 pb-2 shadow-xs",
1669
+ "flex flex-col overflow-hidden rounded-[10px] border border-foreground/[0.08] bg-background",
1894
1670
  className
1895
1671
  ),
1896
1672
  ...props
@@ -2228,7 +2004,7 @@ var CodeBlockCopyButton = ({
2228
2004
  );
2229
2005
  };
2230
2006
  var statusLabels = {
2231
- "approval-requested": "Awaiting Approval",
2007
+ "approval-requested": "Awaiting approval",
2232
2008
  "approval-responded": "Responded",
2233
2009
  "input-available": "Running",
2234
2010
  "input-streaming": "Pending",
@@ -2236,16 +2012,25 @@ var statusLabels = {
2236
2012
  "output-denied": "Denied",
2237
2013
  "output-error": "Error"
2238
2014
  };
2015
+ var statusTones = {
2016
+ "approval-requested": "warn",
2017
+ "approval-responded": "info",
2018
+ "input-available": "muted",
2019
+ "input-streaming": "muted",
2020
+ "output-available": "ok",
2021
+ "output-denied": "warn",
2022
+ "output-error": "bad"
2023
+ };
2239
2024
  var statusIcons = {
2240
- "approval-requested": /* @__PURE__ */ jsx(ClockIcon, { className: "size-4 text-yellow-600" }),
2241
- "approval-responded": /* @__PURE__ */ jsx(CheckCircleIcon, { className: "size-4 text-blue-600" }),
2242
- "input-available": /* @__PURE__ */ jsx(ClockIcon, { className: "size-4 animate-pulse" }),
2243
- "input-streaming": /* @__PURE__ */ jsx(CircleIcon, { className: "size-4" }),
2244
- "output-available": /* @__PURE__ */ jsx(CheckCircleIcon, { className: "size-4 text-green-600" }),
2245
- "output-denied": /* @__PURE__ */ jsx(XCircleIcon, { className: "size-4 text-orange-600" }),
2246
- "output-error": /* @__PURE__ */ jsx(XCircleIcon, { className: "size-4 text-red-600" })
2025
+ "approval-requested": /* @__PURE__ */ jsx(ClockIcon, { className: "size-3" }),
2026
+ "approval-responded": /* @__PURE__ */ jsx(CheckCircleIcon, { className: "size-3" }),
2027
+ "input-available": /* @__PURE__ */ jsx(ClockIcon, { className: "size-3 animate-pulse" }),
2028
+ "input-streaming": /* @__PURE__ */ jsx(CircleIcon, { className: "size-3" }),
2029
+ "output-available": /* @__PURE__ */ jsx(CheckCircleIcon, { className: "size-3" }),
2030
+ "output-denied": /* @__PURE__ */ jsx(XCircleIcon, { className: "size-3" }),
2031
+ "output-error": /* @__PURE__ */ jsx(XCircleIcon, { className: "size-3" })
2247
2032
  };
2248
- var getStatusBadge = (status) => /* @__PURE__ */ jsxs(Badge, { className: "gap-1.5 rounded-full text-xs", variant: "secondary", children: [
2033
+ var getStatusBadge = (status) => /* @__PURE__ */ jsxs(TonePill, { tone: statusTones[status], children: [
2249
2034
  statusIcons[status],
2250
2035
  statusLabels[status]
2251
2036
  ] });
@@ -2253,7 +2038,7 @@ var Sandbox = ({ className, ...props }) => /* @__PURE__ */ jsx(
2253
2038
  Collapsible,
2254
2039
  {
2255
2040
  className: cn(
2256
- "not-prose group mb-4 w-full overflow-hidden rounded-md border border-foreground/20",
2041
+ "not-prose mb-4 w-full overflow-hidden rounded-[10px] border border-foreground/[0.08]",
2257
2042
  className
2258
2043
  ),
2259
2044
  defaultOpen: true,
@@ -2265,22 +2050,17 @@ var SandboxHeader = ({
2265
2050
  title,
2266
2051
  state,
2267
2052
  ...props
2268
- }) => /* @__PURE__ */ jsxs(
2269
- CollapsibleTrigger,
2053
+ }) => /* @__PURE__ */ jsx(
2054
+ CollapsibleHeader,
2270
2055
  {
2271
- className: cn(
2272
- "flex w-full items-center justify-between gap-4 p-3",
2273
- className
2274
- ),
2056
+ variant: "section",
2057
+ icon: Code,
2058
+ className,
2275
2059
  ...props,
2276
- children: [
2277
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
2278
- /* @__PURE__ */ jsx(Code, { className: "size-4 text-muted-foreground" }),
2279
- /* @__PURE__ */ jsx("span", { className: "font-medium text-sm", children: title }),
2280
- getStatusBadge(state)
2281
- ] }),
2282
- /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" })
2283
- ]
2060
+ children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
2061
+ title,
2062
+ getStatusBadge(state)
2063
+ ] })
2284
2064
  }
2285
2065
  );
2286
2066
  var SandboxContent = ({
@@ -2304,7 +2084,7 @@ var SandboxTabsBar = ({
2304
2084
  "div",
2305
2085
  {
2306
2086
  className: cn(
2307
- "flex w-full items-center border-border border-t border-b",
2087
+ "flex w-full items-center border-foreground/[0.08] border-t border-b px-2 py-1.5",
2308
2088
  className
2309
2089
  ),
2310
2090
  ...props
@@ -2313,26 +2093,11 @@ var SandboxTabsBar = ({
2313
2093
  var SandboxTabsList = ({
2314
2094
  className,
2315
2095
  ...props
2316
- }) => /* @__PURE__ */ jsx(
2317
- TabsList,
2318
- {
2319
- className: cn("h-auto rounded-none border-0 bg-transparent p-0", className),
2320
- ...props
2321
- }
2322
- );
2096
+ }) => /* @__PURE__ */ jsx(TabsList, { variant: "line", className, ...props });
2323
2097
  var SandboxTabsTrigger = ({
2324
2098
  className,
2325
2099
  ...props
2326
- }) => /* @__PURE__ */ jsx(
2327
- TabsTrigger,
2328
- {
2329
- className: cn(
2330
- "rounded-none border-0 border-transparent border-b-2 px-4 py-2 font-medium text-muted-foreground text-sm transition-colors data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:text-foreground data-[state=active]:shadow-none",
2331
- className
2332
- ),
2333
- ...props
2334
- }
2335
- );
2100
+ }) => /* @__PURE__ */ jsx(TabsTrigger, { className, ...props });
2336
2101
  var SandboxTabContent = ({
2337
2102
  className,
2338
2103
  ...props
@@ -2783,11 +2548,12 @@ function CollapsedBlock({
2783
2548
  return /* @__PURE__ */ jsxs("div", { className: "flex text-sm leading-5 bg-muted/30 border-y border-border/30", children: [
2784
2549
  /* @__PURE__ */ jsx("span", { className: "w-10 shrink-0" }),
2785
2550
  /* @__PURE__ */ jsxs(
2786
- "button",
2551
+ Button,
2787
2552
  {
2788
- type: "button",
2553
+ variant: "ghost",
2554
+ size: "xs",
2789
2555
  onClick: onExpand,
2790
- className: "flex-1 text-left px-3 py-0.5 text-muted-foreground hover:text-foreground hover:bg-muted/50 transition-colors cursor-pointer",
2556
+ className: "flex-1 justify-start rounded-none font-normal text-muted-foreground hover:text-foreground",
2791
2557
  children: [
2792
2558
  "\u2195 ",
2793
2559
  count,
@@ -2929,15 +2695,7 @@ function FileNameWithTooltip({
2929
2695
  const display = displayPath(filePath);
2930
2696
  const name = fileName(filePath);
2931
2697
  return /* @__PURE__ */ jsxs(Tooltip, { children: [
2932
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: onFileSelect ? /* @__PURE__ */ jsx(
2933
- "button",
2934
- {
2935
- type: "button",
2936
- onClick: () => onFileSelect(filePath),
2937
- className: "text-primary hover:underline truncate text-left cursor-pointer underline",
2938
- children: name
2939
- }
2940
- ) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground truncate", children: name }) }),
2698
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: onFileSelect ? /* @__PURE__ */ jsx(TextLink, { size: "inline", asChild: true, children: /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onFileSelect(filePath), className: "truncate text-left", children: name }) }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground truncate", children: name }) }),
2941
2699
  /* @__PURE__ */ jsx(TooltipContent, { side: "top", children: display })
2942
2700
  ] });
2943
2701
  }
@@ -3355,17 +3113,14 @@ function truncateCommand(cmd, max = 80) {
3355
3113
  }
3356
3114
  function StatusBadge({ status, exitCode }) {
3357
3115
  if (status === "running") {
3358
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs font-medium text-emerald-600 dark:text-emerald-400", children: [
3116
+ return /* @__PURE__ */ jsxs(TonePill, { tone: "ok", children: [
3359
3117
  /* @__PURE__ */ jsx(CircleDotIcon, { className: "size-3 animate-pulse" }),
3360
3118
  "running"
3361
3119
  ] });
3362
3120
  }
3363
3121
  if (status === "exited") {
3364
3122
  const ok = exitCode === 0;
3365
- return /* @__PURE__ */ jsxs("span", { className: cn(
3366
- "inline-flex items-center gap-1 text-xs font-medium",
3367
- ok ? "text-muted-foreground" : "text-red-500 dark:text-red-400"
3368
- ), children: [
3123
+ return /* @__PURE__ */ jsxs(TonePill, { tone: ok ? "muted" : "bad", children: [
3369
3124
  ok ? /* @__PURE__ */ jsx(CircleCheckIcon, { className: "size-3" }) : /* @__PURE__ */ jsx(CircleXIcon, { className: "size-3" }),
3370
3125
  "exited(",
3371
3126
  exitCode ?? "?",
@@ -3373,24 +3128,24 @@ function StatusBadge({ status, exitCode }) {
3373
3128
  ] });
3374
3129
  }
3375
3130
  if (status === "killed") {
3376
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs font-medium text-orange-500 dark:text-orange-400", children: [
3131
+ return /* @__PURE__ */ jsxs(TonePill, { tone: "bad", children: [
3377
3132
  /* @__PURE__ */ jsx(SkullIcon, { className: "size-3" }),
3378
3133
  "killed"
3379
3134
  ] });
3380
3135
  }
3381
3136
  if (status === "timeout") {
3382
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs font-medium text-amber-500 dark:text-amber-400", children: [
3137
+ return /* @__PURE__ */ jsxs(TonePill, { tone: "warn", children: [
3383
3138
  /* @__PURE__ */ jsx(ClockIcon, { className: "size-3" }),
3384
3139
  "timeout"
3385
3140
  ] });
3386
3141
  }
3387
3142
  if (status === "interrupted") {
3388
- return /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-xs font-medium text-amber-500 dark:text-amber-400", children: [
3143
+ return /* @__PURE__ */ jsxs(TonePill, { tone: "warn", children: [
3389
3144
  /* @__PURE__ */ jsx(CircleXIcon, { className: "size-3" }),
3390
3145
  "interrupted"
3391
3146
  ] });
3392
3147
  }
3393
- return /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1 text-xs font-medium text-muted-foreground", children: status });
3148
+ return /* @__PURE__ */ jsx(TonePill, { children: status });
3394
3149
  }
3395
3150
  function ProcessListView({ processes }) {
3396
3151
  if (processes.length === 0) {
@@ -3662,36 +3417,16 @@ function ExpertToolBlock({ tc }) {
3662
3417
  const question = args.question ?? args.prompt ?? "";
3663
3418
  const result = parseExpertResult(tc.result);
3664
3419
  const failed = Boolean(result?.error);
3665
- return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
3666
- /* @__PURE__ */ jsxs(
3667
- "button",
3668
- {
3669
- type: "button",
3670
- onClick: () => setExpanded(!expanded),
3671
- className: cn(
3672
- "flex w-fit max-w-full items-center gap-1.5 rounded-md px-0 py-0.5",
3673
- "text-sm text-muted-foreground hover:text-foreground transition-colors"
3674
- ),
3675
- children: [
3676
- /* @__PURE__ */ jsx(
3677
- ChevronRightIcon,
3678
- {
3679
- className: cn(
3680
- "size-3 shrink-0 transition-transform duration-150",
3681
- expanded && "rotate-90"
3682
- )
3683
- }
3684
- ),
3685
- /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: "Consulted expert" }),
3686
- expertName && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
3687
- "\xB7 ",
3688
- expertName
3689
- ] }),
3690
- failed && /* @__PURE__ */ jsx("span", { className: "text-red-500", children: "\xB7 failed" })
3691
- ]
3692
- }
3693
- ),
3694
- expanded && /* @__PURE__ */ jsxs("div", { className: "ml-6 mt-0.5 space-y-1.5 text-sm", children: [
3420
+ return /* @__PURE__ */ jsxs(Collapsible, { open: expanded, onOpenChange: setExpanded, className: "space-y-1", children: [
3421
+ /* @__PURE__ */ jsx(CollapsibleHeader, { className: "-ml-2 w-fit max-w-full", children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1.5", children: [
3422
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 font-medium text-foreground", children: "Consulted expert" }),
3423
+ expertName && /* @__PURE__ */ jsxs("span", { className: "truncate text-muted-foreground", children: [
3424
+ "\xB7 ",
3425
+ expertName
3426
+ ] }),
3427
+ failed && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-red-500", children: "\xB7 failed" })
3428
+ ] }) }),
3429
+ /* @__PURE__ */ jsxs(CollapsibleContent, { className: "ml-6 mt-0.5 space-y-1.5 text-sm", children: [
3695
3430
  question && /* @__PURE__ */ jsx(ExpertDetail, { label: "Question", content: question }),
3696
3431
  result?.summary && /* @__PURE__ */ jsx(
3697
3432
  ExpertDetail,
@@ -4049,25 +3784,20 @@ function QuickReply({
4049
3784
  disabled,
4050
3785
  onSelect
4051
3786
  }) {
4052
- return /* @__PURE__ */ jsxs(
4053
- "button",
4054
- {
4055
- type: "button",
4056
- disabled,
4057
- onClick: onSelect,
4058
- className: cn(
4059
- "border border-border bg-background text-left text-foreground transition-colors",
4060
- "hover:border-foreground/30 hover:bg-muted",
4061
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
4062
- "disabled:cursor-not-allowed disabled:opacity-50",
4063
- stacked ? "rounded-md px-3 py-2" : "rounded-full px-3.5 py-1.5 text-sm"
4064
- ),
4065
- children: [
4066
- /* @__PURE__ */ jsx("span", { className: cn("block", stacked && "text-sm"), children: choice.label }),
4067
- stacked && choice.description && /* @__PURE__ */ jsx("span", { className: "mt-0.5 block text-xs text-muted-foreground", children: choice.description })
4068
- ]
4069
- }
4070
- );
3787
+ if (stacked) {
3788
+ return /* @__PURE__ */ jsx(
3789
+ ChoiceCard,
3790
+ {
3791
+ size: "sm",
3792
+ selected: false,
3793
+ title: choice.label,
3794
+ description: choice.description,
3795
+ disabled,
3796
+ onClick: onSelect
3797
+ }
3798
+ );
3799
+ }
3800
+ return /* @__PURE__ */ jsx(Button, { variant: "outline", size: "sm", disabled, onClick: onSelect, children: choice.label });
4071
3801
  }
4072
3802
  function BatchAsk({
4073
3803
  tc,
@@ -4183,70 +3913,64 @@ function BatchAsk({
4183
3913
  role: "group",
4184
3914
  "aria-label": "Questions for the user",
4185
3915
  children: [
4186
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b border-border px-3 pt-2", children: [
4187
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3 overflow-x-auto text-sm", children: questions.map((_, i) => {
4188
- const isActive = i === active;
4189
- const answered = answers[i] !== null;
4190
- return /* @__PURE__ */ jsxs(
4191
- "button",
4192
- {
4193
- type: "button",
4194
- onClick: () => setActive(i),
4195
- className: cn(
4196
- "relative pb-2 transition-colors whitespace-nowrap",
4197
- isActive ? "text-foreground" : "text-muted-foreground hover:text-foreground"
4198
- ),
4199
- children: [
4200
- /* @__PURE__ */ jsxs("span", { children: [
4201
- "Question ",
4202
- i + 1
4203
- ] }),
4204
- answered && /* @__PURE__ */ jsx("span", { className: "ml-1 text-[10px] text-emerald-500", children: "\u25CF" }),
4205
- isActive && /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 bottom-0 h-px bg-foreground" })
4206
- ]
4207
- },
4208
- i
4209
- );
4210
- }) }),
4211
- /* @__PURE__ */ jsx(
4212
- Button,
4213
- {
4214
- type: "button",
4215
- variant: "ghost",
4216
- size: "icon-xs",
4217
- onClick: handleCancel,
4218
- className: "ml-2",
4219
- "aria-label": "Cancel clarification and stop chat",
4220
- title: "Esc \u2014 cancel and stop the chat",
4221
- children: /* @__PURE__ */ jsx(XIcon, { className: "size-4" })
4222
- }
4223
- )
4224
- ] }),
4225
- /* @__PURE__ */ jsx("div", { className: "px-3 pt-3", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: current.prompt }) }),
4226
- /* @__PURE__ */ jsxs("div", { className: "mt-3 px-1 pb-2", children: [
4227
- (current.choices ?? []).map((choice, i) => /* @__PURE__ */ jsx(
4228
- ChoiceRow,
4229
- {
4230
- choice,
4231
- selected: currentSel.index === i,
4232
- onSelect: () => selectChoice(i)
4233
- },
4234
- i
4235
- )),
4236
- (current.allow_other ?? true) && /* @__PURE__ */ jsx(
4237
- OtherRow,
4238
- {
4239
- selected: currentSel.index >= OTHER_INDEX_OFFSET,
4240
- value: currentSel.other,
4241
- onSelect: () => updateSelection({ index: OTHER_INDEX_OFFSET }),
4242
- onChange: (v) => updateSelection({ index: OTHER_INDEX_OFFSET, other: v }),
4243
- onCommit: () => {
4244
- if (allAnswered) void handleSubmit();
4245
- else advance();
4246
- }
4247
- }
4248
- )
4249
- ] }),
3916
+ /* @__PURE__ */ jsxs(
3917
+ Tabs,
3918
+ {
3919
+ value: String(active),
3920
+ onValueChange: (value) => setActive(Number(value)),
3921
+ className: "gap-0",
3922
+ children: [
3923
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-border px-3 py-2", children: [
3924
+ /* @__PURE__ */ jsx(TabsList, { variant: "line", className: "no-scrollbar max-w-full overflow-x-auto", children: questions.map((_, i) => /* @__PURE__ */ jsxs(TabsTrigger, { value: String(i), children: [
3925
+ "Question ",
3926
+ i + 1,
3927
+ answers[i] !== null && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-emerald-500", children: "\u25CF" })
3928
+ ] }, i)) }),
3929
+ /* @__PURE__ */ jsx(
3930
+ Button,
3931
+ {
3932
+ type: "button",
3933
+ variant: "ghost",
3934
+ size: "icon-xs",
3935
+ onClick: handleCancel,
3936
+ "aria-label": "Cancel clarification and stop chat",
3937
+ title: "Esc \u2014 cancel and stop the chat",
3938
+ children: /* @__PURE__ */ jsx(XIcon, { className: "size-4" })
3939
+ }
3940
+ )
3941
+ ] }),
3942
+ /* @__PURE__ */ jsxs(TabsContent, { value: String(active), children: [
3943
+ /* @__PURE__ */ jsx("div", { className: "px-3 pt-3", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: current.prompt }) }),
3944
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 flex flex-col gap-1.5 px-3 pb-3", children: [
3945
+ (current.choices ?? []).map((choice, i) => /* @__PURE__ */ jsx(
3946
+ ChoiceCard,
3947
+ {
3948
+ size: "sm",
3949
+ selected: currentSel.index === i,
3950
+ title: choice.label,
3951
+ description: choice.description,
3952
+ onClick: () => selectChoice(i)
3953
+ },
3954
+ i
3955
+ )),
3956
+ (current.allow_other ?? true) && /* @__PURE__ */ jsx(
3957
+ OtherRow,
3958
+ {
3959
+ selected: currentSel.index >= OTHER_INDEX_OFFSET,
3960
+ value: currentSel.other,
3961
+ onSelect: () => updateSelection({ index: OTHER_INDEX_OFFSET }),
3962
+ onChange: (v) => updateSelection({ index: OTHER_INDEX_OFFSET, other: v }),
3963
+ onCommit: () => {
3964
+ if (allAnswered) void handleSubmit();
3965
+ else advance();
3966
+ }
3967
+ }
3968
+ )
3969
+ ] })
3970
+ ] })
3971
+ ]
3972
+ }
3973
+ ),
4250
3974
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 border-t border-border px-3 py-2", children: [
4251
3975
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 text-xs text-muted-foreground", children: [
4252
3976
  /* @__PURE__ */ jsxs("span", { className: "mr-2 tabular-nums", children: [
@@ -4273,30 +3997,6 @@ function BatchAsk({
4273
3997
  }
4274
3998
  );
4275
3999
  }
4276
- function ChoiceRow({
4277
- choice,
4278
- selected,
4279
- onSelect
4280
- }) {
4281
- return /* @__PURE__ */ jsxs(
4282
- "button",
4283
- {
4284
- type: "button",
4285
- onClick: onSelect,
4286
- className: cn(
4287
- "flex w-full items-start gap-3 rounded px-2 py-1.5 text-left transition-colors",
4288
- selected ? "bg-muted" : "hover:bg-muted/40"
4289
- ),
4290
- children: [
4291
- /* @__PURE__ */ jsx(Radio, { selected }),
4292
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
4293
- /* @__PURE__ */ jsx("div", { className: "text-sm text-foreground", children: choice.label }),
4294
- choice.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-muted-foreground", children: choice.description })
4295
- ] })
4296
- ]
4297
- }
4298
- );
4299
- }
4300
4000
  function OtherRow({
4301
4001
  selected,
4302
4002
  value,
@@ -4308,55 +4008,33 @@ function OtherRow({
4308
4008
  "div",
4309
4009
  {
4310
4010
  className: cn(
4311
- "flex items-start gap-3 rounded px-2 py-1.5 transition-colors",
4312
- selected ? "bg-muted" : "hover:bg-muted/40"
4011
+ choiceCardVariants({ size: "sm", selected }),
4012
+ "cursor-pointer flex-col gap-1.5 sm:gap-1.5"
4313
4013
  ),
4014
+ onClick: onSelect,
4314
4015
  children: [
4016
+ /* @__PURE__ */ jsx("span", { className: "text-[14px] font-medium text-foreground sm:text-[13px]", children: "Other" }),
4315
4017
  /* @__PURE__ */ jsx(
4316
- "button",
4018
+ Input,
4317
4019
  {
4318
- type: "button",
4319
- onClick: onSelect,
4320
- className: "flex shrink-0 items-center pt-0.5",
4321
- "aria-label": "Choose Other",
4322
- children: /* @__PURE__ */ jsx(Radio, { selected })
4020
+ "aria-label": "Other answer",
4021
+ placeholder: "Type your answer\u2026",
4022
+ value,
4023
+ onFocus: onSelect,
4024
+ onChange: (e) => onChange(e.target.value),
4025
+ onKeyDown: (e) => {
4026
+ if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && value.trim()) {
4027
+ e.preventDefault();
4028
+ onCommit();
4029
+ }
4030
+ },
4031
+ className: "h-8 text-[13px]"
4323
4032
  }
4324
- ),
4325
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
4326
- /* @__PURE__ */ jsx("div", { className: "text-sm text-foreground", children: "Other" }),
4327
- /* @__PURE__ */ jsx(
4328
- Input,
4329
- {
4330
- placeholder: "Type your answer\u2026",
4331
- value,
4332
- onFocus: onSelect,
4333
- onChange: (e) => onChange(e.target.value),
4334
- onKeyDown: (e) => {
4335
- if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing && value.trim()) {
4336
- e.preventDefault();
4337
- onCommit();
4338
- }
4339
- },
4340
- className: "mt-0.5 h-7 px-0 text-xs"
4341
- }
4342
- )
4343
- ] })
4033
+ )
4344
4034
  ]
4345
4035
  }
4346
4036
  );
4347
4037
  }
4348
- function Radio({ selected }) {
4349
- return /* @__PURE__ */ jsx(
4350
- "span",
4351
- {
4352
- "aria-hidden": true,
4353
- className: cn(
4354
- "mt-[3px] size-3.5 shrink-0 rounded-full border",
4355
- selected ? "border-foreground bg-foreground" : "border-muted-foreground/60 bg-transparent"
4356
- )
4357
- }
4358
- );
4359
- }
4360
4038
  function BatchAskLocked({
4361
4039
  tc,
4362
4040
  questions,
@@ -4469,28 +4147,17 @@ function MemoryToolBlock({ tc }) {
4469
4147
  const targetLabel = TARGET_LABEL[target] ?? target;
4470
4148
  const failed = result?.success === false || !!result?.error;
4471
4149
  return /* @__PURE__ */ jsxs(Collapsible, { open: isOpen, onOpenChange: setIsOpen, className: "not-prose w-full", children: [
4472
- /* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "group/trigger flex w-fit items-center gap-2 text-sm transition-colors", children: [
4473
- /* @__PURE__ */ jsxs("span", { className: "text-left", children: [
4474
- /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: verb }),
4150
+ /* @__PURE__ */ jsx(CollapsibleHeader, { className: "-ml-2 w-fit max-w-full", children: /* @__PURE__ */ jsxs("span", { children: [
4151
+ /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: verb }),
4152
+ " ",
4153
+ /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
4154
+ prep,
4475
4155
  " ",
4476
- /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
4477
- prep,
4478
- " ",
4479
- targetLabel
4480
- ] }),
4481
- result?.usage && !failed && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/60 ml-1.5 text-xs", children: result.usage }),
4482
- failed && /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1.5", children: "\xB7 failed" })
4156
+ targetLabel
4483
4157
  ] }),
4484
- /* @__PURE__ */ jsx(
4485
- ChevronDownIcon,
4486
- {
4487
- className: cn(
4488
- "size-4 shrink-0 transition-transform",
4489
- isOpen ? "rotate-180" : "rotate-0"
4490
- )
4491
- }
4492
- )
4493
- ] }),
4158
+ result?.usage && !failed && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/60 ml-1.5 text-xs", children: result.usage }),
4159
+ failed && /* @__PURE__ */ jsx("span", { className: "text-red-500 ml-1.5", children: "\xB7 failed" })
4160
+ ] }) }),
4494
4161
  /* @__PURE__ */ jsx(
4495
4162
  CollapsibleContent,
4496
4163
  {
@@ -4629,35 +4296,14 @@ function StatusIcon({ tc }) {
4629
4296
  return /* @__PURE__ */ jsx(CheckCircle2Icon, { className: "size-3.5 text-emerald-500" });
4630
4297
  }
4631
4298
  function DefaultToolBlock({ tc }) {
4632
- const [expanded, setExpanded] = useState(false);
4633
4299
  const summary = toolSummary(tc);
4634
- return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border/60 bg-muted/20 overflow-hidden", children: [
4635
- /* @__PURE__ */ jsxs(
4636
- "button",
4637
- {
4638
- type: "button",
4639
- onClick: () => setExpanded(!expanded),
4640
- className: cn(
4641
- "flex w-full items-center gap-2 px-3 py-2",
4642
- "text-sm hover:bg-muted/40 transition-colors cursor-pointer"
4643
- ),
4644
- children: [
4645
- /* @__PURE__ */ jsx(StatusIcon, { tc }),
4646
- /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: toolLabel(tc.toolName) }),
4647
- summary && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/70 truncate text-xs flex-1 text-left", children: summary }),
4648
- /* @__PURE__ */ jsx(
4649
- ChevronRightIcon,
4650
- {
4651
- className: cn(
4652
- "size-3.5 shrink-0 text-muted-foreground/50 transition-transform duration-150 ml-auto",
4653
- expanded && "rotate-90"
4654
- )
4655
- }
4656
- )
4657
- ]
4658
- }
4659
- ),
4660
- expanded && /* @__PURE__ */ jsxs("div", { className: "border-t border-border/40 px-3 py-2 space-y-2", children: [
4300
+ return /* @__PURE__ */ jsxs(Collapsible, { className: "overflow-hidden rounded-[10px] border border-foreground/[0.08]", children: [
4301
+ /* @__PURE__ */ jsx(CollapsibleHeader, { variant: "section", size: "sm", children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
4302
+ /* @__PURE__ */ jsx(StatusIcon, { tc }),
4303
+ /* @__PURE__ */ jsx("span", { className: "shrink-0", children: toolLabel(tc.toolName) }),
4304
+ summary && /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-xs font-normal text-muted-foreground/70", children: summary })
4305
+ ] }) }),
4306
+ /* @__PURE__ */ jsxs(CollapsibleContent, { className: "space-y-2 border-t border-foreground/[0.08] px-3 py-2", children: [
4661
4307
  /* @__PURE__ */ jsx("pre", { className: "overflow-x-auto rounded-md bg-muted/50 px-3 py-2 text-xs text-muted-foreground font-mono whitespace-pre-wrap break-all", children: formatArgs(tc.args) }),
4662
4308
  tc.result && /* @__PURE__ */ jsxs("pre", { className: "overflow-x-auto rounded-md bg-muted/50 px-3 py-2 text-xs font-mono whitespace-pre-wrap break-all max-h-48 overflow-y-auto", children: [
4663
4309
  /* @__PURE__ */ jsx("span", { className: "text-emerald-600 dark:text-emerald-400 font-semibold", children: "Result" }),
@@ -4728,18 +4374,7 @@ function CodeRunToolBlock({
4728
4374
  onOpenChange: setIsOpen,
4729
4375
  className: "not-prose w-full",
4730
4376
  children: [
4731
- /* @__PURE__ */ jsxs(CollapsibleTrigger, { className: "group/trigger flex w-fit items-center gap-2 text-sm transition-colors", children: [
4732
- /* @__PURE__ */ jsx("span", { className: "text-left", children: isRunning ? /* @__PURE__ */ jsx(Shimmer, { as: "span", duration: 1, children: `Running ${label}...` }) : hasError ? /* @__PURE__ */ jsx("span", { className: "font-semibold text-destructive", children: `${label} failed` }) : /* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: `Ran ${label}` }) }),
4733
- /* @__PURE__ */ jsx(
4734
- ChevronDownIcon,
4735
- {
4736
- className: cn(
4737
- "size-4 shrink-0 transition-transform",
4738
- isOpen ? "rotate-180" : "rotate-0"
4739
- )
4740
- }
4741
- )
4742
- ] }),
4377
+ /* @__PURE__ */ jsx(CollapsibleHeader, { className: "-ml-2 w-fit max-w-full", children: isRunning ? /* @__PURE__ */ jsx(Shimmer, { as: "span", duration: 1, children: `Running ${label}...` }) : hasError ? /* @__PURE__ */ jsx("span", { className: "font-medium text-destructive", children: `${label} failed` }) : /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: `Ran ${label}` }) }),
4743
4378
  /* @__PURE__ */ jsx(
4744
4379
  CollapsibleContent,
4745
4380
  {
@@ -5417,88 +5052,6 @@ function renderInlineMarkdown(text) {
5417
5052
  }
5418
5053
  });
5419
5054
  }
5420
- function Command({
5421
- className,
5422
- ...props
5423
- }) {
5424
- return /* @__PURE__ */ jsx(
5425
- Command$1,
5426
- {
5427
- "data-slot": "command",
5428
- className: cn(
5429
- "flex size-full flex-col overflow-hidden bg-popover text-popover-foreground",
5430
- className
5431
- ),
5432
- ...props
5433
- }
5434
- );
5435
- }
5436
- function CommandList({
5437
- className,
5438
- ...props
5439
- }) {
5440
- return /* @__PURE__ */ jsx(
5441
- Command$1.List,
5442
- {
5443
- "data-slot": "command-list",
5444
- className: cn(
5445
- "no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none",
5446
- className
5447
- ),
5448
- ...props
5449
- }
5450
- );
5451
- }
5452
- function CommandEmpty({
5453
- className,
5454
- ...props
5455
- }) {
5456
- return /* @__PURE__ */ jsx(
5457
- Command$1.Empty,
5458
- {
5459
- "data-slot": "command-empty",
5460
- className: cn("py-6 text-center text-sm", className),
5461
- ...props
5462
- }
5463
- );
5464
- }
5465
- function CommandGroup({
5466
- className,
5467
- ...props
5468
- }) {
5469
- return /* @__PURE__ */ jsx(
5470
- Command$1.Group,
5471
- {
5472
- "data-slot": "command-group",
5473
- className: cn(
5474
- "overflow-hidden p-1.5 text-foreground **:[[cmdk-group-heading]]:mb-1 **:[[cmdk-group-heading]]:rounded-sm **:[[cmdk-group-heading]]:bg-orange-100 **:[[cmdk-group-heading]]:px-3 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-sm **:[[cmdk-group-heading]]:font-semibold **:[[cmdk-group-heading]]:tracking-wider **:[[cmdk-group-heading]]:text-foreground dark:**:[[cmdk-group-heading]]:bg-orange-400/40 dark:**:[[cmdk-group-heading]]:text-foreground/90",
5475
- className
5476
- ),
5477
- ...props
5478
- }
5479
- );
5480
- }
5481
- function CommandItem({
5482
- className,
5483
- children,
5484
- ...props
5485
- }) {
5486
- return /* @__PURE__ */ jsxs(
5487
- Command$1.Item,
5488
- {
5489
- "data-slot": "command-item",
5490
- className: cn(
5491
- "group/command-item relative flex cursor-default items-center gap-2 rounded-none px-3 py-2 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-muted data-[selected=true]:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 data-[selected=true]:*:[svg]:text-foreground",
5492
- className
5493
- ),
5494
- ...props,
5495
- children: [
5496
- children,
5497
- /* @__PURE__ */ jsx(CheckIcon, { className: "ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100" })
5498
- ]
5499
- }
5500
- );
5501
- }
5502
5055
  var convertBlobUrlToDataUrl = async (url) => {
5503
5056
  try {
5504
5057
  const response = await fetch(url);
@@ -6203,31 +5756,6 @@ function splitComposerFiles(files) {
6203
5756
  }
6204
5757
  return { images, pending };
6205
5758
  }
6206
- function Progress({
6207
- className,
6208
- value,
6209
- ...props
6210
- }) {
6211
- return /* @__PURE__ */ jsx(
6212
- Progress$1.Root,
6213
- {
6214
- "data-slot": "progress",
6215
- className: cn(
6216
- "relative flex h-0.5 w-full items-center overflow-x-hidden rounded-none bg-muted",
6217
- className
6218
- ),
6219
- ...props,
6220
- children: /* @__PURE__ */ jsx(
6221
- Progress$1.Indicator,
6222
- {
6223
- "data-slot": "progress-indicator",
6224
- className: "size-full flex-1 bg-primary transition-all",
6225
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
6226
- }
6227
- )
6228
- }
6229
- );
6230
- }
6231
5759
  var PERCENT_MAX = 100;
6232
5760
  var NEARLY_FULL = 0.9;
6233
5761
  var ICON_RADIUS = 10;
@@ -6342,20 +5870,9 @@ var ContextContentHeader = ({
6342
5870
  ] })
6343
5871
  ] }),
6344
5872
  /* @__PURE__ */ jsx(
6345
- Progress,
5873
+ ProgressBar,
6346
5874
  {
6347
- className: cn(
6348
- // The primitive only clips its x-axis, which leaves the fill's
6349
- // square end poking out of the pill at both ends.
6350
- "h-1 overflow-hidden rounded-full bg-muted",
6351
- // Amber, not `bg-primary`: primary is the host app's colour, and
6352
- // the two hosts disagree — the agent web app is amber, Studio is
6353
- // near-black — so the same bar came out black beside a Send
6354
- // button the composer hardcodes amber. This is the composer's
6355
- // own accent, so it reads the same wherever it is embedded.
6356
- "[&>[data-slot=progress-indicator]]:bg-amber-500",
6357
- nearlyFull && "[&>[data-slot=progress-indicator]]:bg-destructive"
6358
- ),
5875
+ color: nearlyFull ? "var(--destructive)" : "var(--color-amber-500)",
6359
5876
  value: usedPercent * PERCENT_MAX
6360
5877
  }
6361
5878
  )
@@ -6366,230 +5883,38 @@ var ContextContentBody = ({
6366
5883
  className,
6367
5884
  ...props
6368
5885
  }) => /* @__PURE__ */ jsx("div", { className: cn("w-full space-y-1.5 px-3 py-2.5", className), ...props, children });
6369
- var itemVariants = cva(
6370
- "group/item flex w-full flex-wrap items-center rounded-none border text-sm transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors [a]:hover:bg-muted",
6371
- {
6372
- variants: {
6373
- variant: {
6374
- default: "border-transparent",
6375
- outline: "border-border",
6376
- muted: "border-transparent bg-muted/50"
6377
- },
6378
- size: {
6379
- default: "gap-3.5 px-4 py-3.5",
6380
- sm: "gap-3.5 px-3.5 py-3",
6381
- xs: "gap-2.5 px-3 py-2.5 in-data-[slot=dropdown-menu-content]:p-0"
6382
- }
6383
- },
6384
- defaultVariants: {
6385
- variant: "default",
6386
- size: "default"
6387
- }
6388
- }
6389
- );
6390
- function Item({
6391
- className,
6392
- variant = "default",
6393
- size: size2 = "default",
6394
- asChild = false,
6395
- ...props
6396
- }) {
6397
- const Comp = asChild ? Slot.Root : "div";
6398
- return /* @__PURE__ */ jsx(
6399
- Comp,
6400
- {
6401
- "data-slot": "item",
6402
- "data-variant": variant,
6403
- "data-size": size2,
6404
- className: cn(itemVariants({ variant, size: size2, className })),
6405
- ...props
6406
- }
6407
- );
6408
- }
6409
- var itemMediaVariants = cva(
6410
- "flex shrink-0 items-center justify-center gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start [&_svg]:pointer-events-none",
6411
- {
6412
- variants: {
6413
- variant: {
6414
- default: "bg-transparent",
6415
- icon: "[&_svg:not([class*='size-'])]:size-4",
6416
- image: "size-10 overflow-hidden rounded-none group-data-[size=sm]/item:size-8 group-data-[size=xs]/item:size-6 group-data-[size=xs]/item:rounded-none [&_img]:size-full [&_img]:object-cover"
6417
- }
6418
- },
6419
- defaultVariants: {
6420
- variant: "default"
6421
- }
6422
- }
6423
- );
6424
- function ItemMedia({
6425
- className,
6426
- variant = "default",
6427
- ...props
5886
+ var SEARCH_PLACEHOLDER = {
5887
+ commands: "Search commands\u2026",
5888
+ skills: "Search skills\u2026",
5889
+ scheduled: "Search scheduled tasks\u2026",
5890
+ all: "Type a command or search\u2026"
5891
+ };
5892
+ var NAV_HINT = "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc dismiss";
5893
+ var SEARCH_HINT = {
5894
+ commands: NAV_HINT,
5895
+ skills: "Esc dismiss",
5896
+ scheduled: NAV_HINT,
5897
+ all: NAV_HINT
5898
+ };
5899
+ var NAME_COLUMNS = "grid-cols-[120px_minmax(0,1fr)] sm:grid-cols-[200px_minmax(0,1fr)]";
5900
+ var ROW_CLASS = `grid ${NAME_COLUMNS} min-h-11 items-center gap-4 rounded-[10px] px-3 py-1.5 data-[selected=true]:bg-accent [&_svg]:hidden`;
5901
+ function ComposerCommandMenu({
5902
+ menuMode,
5903
+ searchQuery,
5904
+ onSearchChange,
5905
+ skillsLoading,
5906
+ builtinCommands,
5907
+ adapterCommands,
5908
+ scheduledExamples,
5909
+ onCommandSelect,
5910
+ onEscapeDismiss
6428
5911
  }) {
5912
+ const controlledSearch = menuMode === "commands" || menuMode === "all";
5913
+ const showCommands = menuMode === "commands" || menuMode === "all";
5914
+ const showSkills = menuMode === "skills" || menuMode === "all";
5915
+ const skillsUnattached = menuMode === "skills" && !skillsLoading && adapterCommands.length === 0;
6429
5916
  return /* @__PURE__ */ jsx(
6430
- "div",
6431
- {
6432
- "data-slot": "item-media",
6433
- "data-variant": variant,
6434
- className: cn(itemMediaVariants({ variant, className })),
6435
- ...props
6436
- }
6437
- );
6438
- }
6439
- function ItemContent({ className, ...props }) {
6440
- return /* @__PURE__ */ jsx(
6441
- "div",
6442
- {
6443
- "data-slot": "item-content",
6444
- className: cn(
6445
- "flex flex-1 flex-col gap-1 group-data-[size=xs]/item:gap-0.5 [&+[data-slot=item-content]]:flex-none",
6446
- className
6447
- ),
6448
- ...props
6449
- }
6450
- );
6451
- }
6452
- function ItemTitle({ className, ...props }) {
6453
- return /* @__PURE__ */ jsx(
6454
- "div",
6455
- {
6456
- "data-slot": "item-title",
6457
- className: cn(
6458
- "line-clamp-1 flex w-fit items-center gap-2 text-xs leading-snug font-semibold uppercase underline-offset-4",
6459
- className
6460
- ),
6461
- ...props
6462
- }
6463
- );
6464
- }
6465
- function ItemDescription({ className, ...props }) {
6466
- return /* @__PURE__ */ jsx(
6467
- "p",
6468
- {
6469
- "data-slot": "item-description",
6470
- className: cn(
6471
- "line-clamp-2 text-left text-sm leading-relaxed font-normal text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
6472
- className
6473
- ),
6474
- ...props
6475
- }
6476
- );
6477
- }
6478
- function ItemActions({ className, ...props }) {
6479
- return /* @__PURE__ */ jsx(
6480
- "div",
6481
- {
6482
- "data-slot": "item-actions",
6483
- className: cn("flex items-center gap-2", className),
6484
- ...props
6485
- }
6486
- );
6487
- }
6488
- var MOBILE_QUERY = "(max-width: 767px)";
6489
- function subscribe(onChange) {
6490
- const mql = window.matchMedia(MOBILE_QUERY);
6491
- mql.addEventListener("change", onChange);
6492
- return () => mql.removeEventListener("change", onChange);
6493
- }
6494
- function useIsMobile() {
6495
- return useSyncExternalStore(
6496
- subscribe,
6497
- () => window.matchMedia(MOBILE_QUERY).matches,
6498
- // No viewport when server-rendered; assume desktop, as the SDK does.
6499
- () => false
6500
- );
6501
- }
6502
- function ResponsivePanel({
6503
- open,
6504
- onOpenChange,
6505
- trigger,
6506
- title,
6507
- children,
6508
- align = "start",
6509
- popoverClassName
6510
- }) {
6511
- const isMobile = useIsMobile();
6512
- if (!isMobile) {
6513
- return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange, children: [
6514
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: trigger }),
6515
- /* @__PURE__ */ jsx(
6516
- PopoverContent,
6517
- {
6518
- side: "top",
6519
- align,
6520
- className: cn("w-64 overflow-hidden rounded-xl p-1", popoverClassName),
6521
- children
6522
- }
6523
- )
6524
- ] });
6525
- }
6526
- return /* @__PURE__ */ jsxs(Dialog$1.Root, { open, onOpenChange, children: [
6527
- /* @__PURE__ */ jsx(Dialog$1.Trigger, { asChild: true, children: trigger }),
6528
- /* @__PURE__ */ jsxs(Dialog$1.Portal, { children: [
6529
- /* @__PURE__ */ jsx(
6530
- Dialog$1.Overlay,
6531
- {
6532
- "data-slot": "responsive-panel-overlay",
6533
- className: "fixed inset-0 z-50 bg-black/40 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0"
6534
- }
6535
- ),
6536
- /* @__PURE__ */ jsxs(
6537
- Dialog$1.Content,
6538
- {
6539
- "data-slot": "responsive-panel-sheet",
6540
- "aria-describedby": void 0,
6541
- className: cn(
6542
- "fixed inset-x-0 bottom-0 z-50 flex max-h-[80svh] flex-col overflow-hidden rounded-t-2xl border-t border-border bg-popover pb-[env(safe-area-inset-bottom)] text-popover-foreground shadow-lg",
6543
- "data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom"
6544
- ),
6545
- children: [
6546
- /* @__PURE__ */ jsx(Dialog$1.Title, { className: "sr-only", children: title }),
6547
- /* @__PURE__ */ jsx(
6548
- "div",
6549
- {
6550
- "aria-hidden": "true",
6551
- className: "mx-auto mt-2.5 mb-1 h-1 w-9 shrink-0 rounded-full bg-muted-foreground/30"
6552
- }
6553
- ),
6554
- /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto overscroll-contain p-1", children })
6555
- ]
6556
- }
6557
- )
6558
- ] })
6559
- ] });
6560
- }
6561
- var SEARCH_PLACEHOLDER = {
6562
- commands: "Search commands\u2026",
6563
- skills: "Search skills\u2026",
6564
- scheduled: "Search scheduled tasks\u2026",
6565
- all: "Type a command or search\u2026"
6566
- };
6567
- var NAV_HINT = "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc dismiss";
6568
- var SEARCH_HINT = {
6569
- commands: NAV_HINT,
6570
- skills: "Esc dismiss",
6571
- scheduled: NAV_HINT,
6572
- all: NAV_HINT
6573
- };
6574
- var NAME_COLUMNS = "grid-cols-[120px_minmax(0,1fr)] sm:grid-cols-[200px_minmax(0,1fr)]";
6575
- var ROW_CLASS = `grid ${NAME_COLUMNS} min-h-11 items-center gap-4 rounded-[10px] px-3 py-1.5 data-[selected=true]:bg-accent [&_svg]:hidden`;
6576
- function ComposerCommandMenu({
6577
- menuMode,
6578
- searchQuery,
6579
- onSearchChange,
6580
- skillsLoading,
6581
- builtinCommands,
6582
- adapterCommands,
6583
- scheduledExamples,
6584
- onCommandSelect,
6585
- onEscapeDismiss
6586
- }) {
6587
- const controlledSearch = menuMode === "commands" || menuMode === "all";
6588
- const showCommands = menuMode === "commands" || menuMode === "all";
6589
- const showSkills = menuMode === "skills" || menuMode === "all";
6590
- const skillsUnattached = menuMode === "skills" && !skillsLoading && adapterCommands.length === 0;
6591
- return /* @__PURE__ */ jsx(
6592
- PopoverContent,
5917
+ PopoverContent,
6593
5918
  {
6594
5919
  side: "top",
6595
5920
  align: "start",
@@ -7689,50 +7014,36 @@ function ResearchSourcesPanel({
7689
7014
  }, []);
7690
7015
  if (sources.length === 0) return null;
7691
7016
  return /* @__PURE__ */ jsxs(
7692
- "div",
7017
+ Collapsible,
7693
7018
  {
7694
7019
  ref: rootRef,
7695
- className: "rounded-md border border-line bg-card",
7020
+ open: expanded,
7021
+ onOpenChange: setExpanded,
7022
+ className: "rounded-[10px] border border-foreground/[0.08] bg-card",
7696
7023
  children: [
7697
- /* @__PURE__ */ jsxs(
7698
- "button",
7699
- {
7700
- type: "button",
7701
- onClick: () => setExpanded((prev) => !prev),
7702
- "aria-expanded": expanded,
7703
- className: "flex w-full items-center gap-1.5 px-2 py-1.5 text-left hover:bg-muted/40",
7704
- children: [
7705
- /* @__PURE__ */ jsx(
7706
- ChevronRightIcon,
7707
- {
7708
- className: cn(
7709
- "size-3 shrink-0 text-muted-foreground transition-transform duration-150",
7710
- expanded && "rotate-90"
7711
- )
7712
- }
7713
- ),
7714
- /* @__PURE__ */ jsxs("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-muted-foreground", children: [
7715
- "Sources \xB7 ",
7716
- sources.length
7717
- ] })
7718
- ]
7719
- }
7720
- ),
7721
- expanded && /* @__PURE__ */ jsx("ul", { className: "max-h-35 overflow-y-auto border-t border-line py-1", children: sources.map((s) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
7722
- "a",
7024
+ /* @__PURE__ */ jsxs(CollapsibleHeader, { variant: "section", size: "sm", children: [
7025
+ "Sources \xB7 ",
7026
+ sources.length
7027
+ ] }),
7028
+ /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("ul", { className: "max-h-35 overflow-y-auto border-t border-foreground/[0.08] p-1", children: sources.map((s) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
7029
+ ListRow,
7723
7030
  {
7724
- id: `source-${s.sourceId}`,
7725
- href: s.url,
7726
- target: "_blank",
7727
- rel: "noreferrer",
7728
- className: "group flex items-baseline gap-2 px-2 py-1 hover:bg-muted/60",
7729
- children: [
7730
- /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] font-semibold text-primary tabular-nums", children: s.sourceId }),
7731
- /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-foreground group-hover:underline", children: s.title || s.url }),
7732
- /* @__PURE__ */ jsx("span", { className: "ml-auto shrink-0 truncate text-[10px] text-muted-foreground max-w-[40%]", children: hostname2(s.url) })
7733
- ]
7031
+ asChild: true,
7032
+ size: "sm",
7033
+ label: s.title || s.url,
7034
+ meta: /* @__PURE__ */ jsx("span", { className: "block max-w-40 truncate", children: hostname2(s.url) }),
7035
+ children: /* @__PURE__ */ jsx(
7036
+ "a",
7037
+ {
7038
+ id: `source-${s.sourceId}`,
7039
+ href: s.url,
7040
+ target: "_blank",
7041
+ rel: "noreferrer",
7042
+ children: /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[12px] font-medium text-amber-500 tabular-nums", children: s.sourceId })
7043
+ }
7044
+ )
7734
7045
  }
7735
- ) }, s.sourceId)) })
7046
+ ) }, s.sourceId)) }) })
7736
7047
  ]
7737
7048
  }
7738
7049
  );
@@ -8246,24 +7557,26 @@ function ArtifactHtml({
8246
7557
  ),
8247
7558
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
8248
7559
  spec.caption ? /* @__PURE__ */ jsx("span", { children: spec.caption }) : /* @__PURE__ */ jsx("span", {}),
8249
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 ", children: [
7560
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
8250
7561
  /* @__PURE__ */ jsx(
8251
- "button",
7562
+ Button,
8252
7563
  {
8253
- type: "button",
7564
+ variant: "ghost",
7565
+ size: "icon-xs",
8254
7566
  onClick: () => setZoom((z) => clamp4(z - ZOOM_STEP)),
8255
7567
  disabled: zoom <= MIN_ZOOM,
8256
- className: "hover:text-foreground disabled:opacity-40 cursor-pointer",
7568
+ className: "text-muted-foreground hover:text-foreground",
8257
7569
  "aria-label": "zoom out",
8258
- children: "\u2212"
7570
+ children: /* @__PURE__ */ jsx(MinusIcon, {})
8259
7571
  }
8260
7572
  ),
8261
7573
  /* @__PURE__ */ jsxs(
8262
- "button",
7574
+ Button,
8263
7575
  {
8264
- type: "button",
7576
+ variant: "ghost",
7577
+ size: "xs",
8265
7578
  onClick: () => setZoom(1),
8266
- className: "tabular-nums hover:text-foreground",
7579
+ className: "font-normal tabular-nums text-muted-foreground hover:text-foreground",
8267
7580
  "aria-label": "reset zoom",
8268
7581
  children: [
8269
7582
  Math.round(zoom * 100),
@@ -8272,25 +7585,27 @@ function ArtifactHtml({
8272
7585
  }
8273
7586
  ),
8274
7587
  /* @__PURE__ */ jsx(
8275
- "button",
7588
+ Button,
8276
7589
  {
8277
- type: "button",
7590
+ variant: "ghost",
7591
+ size: "icon-xs",
8278
7592
  onClick: () => setZoom((z) => clamp4(z + ZOOM_STEP)),
8279
7593
  disabled: zoom >= MAX_ZOOM,
8280
- className: "hover:text-foreground disabled:opacity-40",
7594
+ className: "text-muted-foreground hover:text-foreground",
8281
7595
  "aria-label": "zoom in",
8282
- children: "+"
7596
+ children: /* @__PURE__ */ jsx(PlusIcon, {})
8283
7597
  }
8284
7598
  ),
8285
7599
  !fill && /* @__PURE__ */ jsxs(Fragment, { children: [
8286
- /* @__PURE__ */ jsx("span", { className: "text-border", children: "|" }),
7600
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "h-4 w-px bg-border" }),
8287
7601
  /* @__PURE__ */ jsx(
8288
- "button",
7602
+ Button,
8289
7603
  {
8290
- type: "button",
7604
+ variant: "ghost",
7605
+ size: "xs",
8291
7606
  onClick: () => setExpanded((v) => !v),
8292
- className: "hover:text-foreground",
8293
- children: expanded ? "collapse" : "expand"
7607
+ className: "font-normal text-muted-foreground hover:text-foreground",
7608
+ children: expanded ? "Collapse" : "Expand"
8294
7609
  }
8295
7610
  )
8296
7611
  ] })
@@ -8678,61 +7993,50 @@ var ErrorMessage = memo(function ErrorMessage2({
8678
7993
  setRetryPending(false);
8679
7994
  }
8680
7995
  };
8681
- return /* @__PURE__ */ jsxs(
8682
- "div",
8683
- {
8684
- role: "alert",
8685
- className: cn(
8686
- "flex w-full gap-3 rounded-none border-l-4 border-destructive bg-destructive/5 p-4",
8687
- className
8688
- ),
8689
- children: [
8690
- /* @__PURE__ */ jsx(AlertTriangle, { className: "mt-0.5 size-4 shrink-0 text-destructive" }),
8691
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-2", children: [
8692
- /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-destructive", children: errorInfo.title }),
8693
- errorInfo.detail && /* @__PURE__ */ jsxs(
8694
- "button",
8695
- {
8696
- type: "button",
8697
- onClick: () => setDetailOpen((open) => !open),
8698
- className: "flex items-center gap-1 self-start text-xs text-muted-foreground hover:text-foreground",
8699
- "aria-expanded": detailOpen,
8700
- children: [
8701
- detailOpen ? /* @__PURE__ */ jsx(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsx(ChevronRight$1, { className: "size-3" }),
8702
- detailOpen ? "Hide details" : "Show details"
8703
- ]
8704
- }
8705
- ),
8706
- detailOpen && errorInfo.detail && /* @__PURE__ */ jsx("pre", { className: "overflow-x-auto rounded-none border border-destructive/20 bg-background p-2 font-mono text-xs whitespace-pre-wrap wrap-break-word text-muted-foreground", children: errorInfo.detail }),
8707
- (showRetry || onDismiss) && /* @__PURE__ */ jsxs("div", { className: "flex gap-2 pt-1", children: [
8708
- showRetry && /* @__PURE__ */ jsxs(
8709
- Button,
8710
- {
8711
- size: "xs",
8712
- variant: "secondary",
8713
- onClick: handleRetry,
8714
- disabled: retryPending,
8715
- children: [
8716
- /* @__PURE__ */ jsx(
8717
- RefreshCw,
8718
- {
8719
- className: cn("size-3", retryPending && "animate-spin")
8720
- }
8721
- ),
8722
- retryPending ? "Retrying\u2026" : "Retry"
8723
- ]
8724
- }
8725
- ),
8726
- onDismiss && /* @__PURE__ */ jsx(Button, { size: "xs", variant: "ghost", onClick: onDismiss, children: "Dismiss" })
8727
- ] }),
8728
- retryError && /* @__PURE__ */ jsxs("div", { className: "pt-1 text-xs text-destructive", role: "status", children: [
8729
- "Retry failed: ",
8730
- retryError
8731
- ] })
8732
- ] })
8733
- ]
8734
- }
8735
- );
7996
+ return /* @__PURE__ */ jsxs(Alert, { variant: "destructive", className: cn("gap-y-2", className), children: [
7997
+ /* @__PURE__ */ jsx(AlertTriangle, {}),
7998
+ /* @__PURE__ */ jsx(AlertTitle, { children: errorInfo.title }),
7999
+ /* @__PURE__ */ jsxs(AlertDescription, { className: "flex min-w-0 flex-col items-start gap-2", children: [
8000
+ errorInfo.detail && /* @__PURE__ */ jsx(TextLink, { variant: "muted", size: "sm", asChild: true, children: /* @__PURE__ */ jsxs(
8001
+ "button",
8002
+ {
8003
+ type: "button",
8004
+ onClick: () => setDetailOpen((open) => !open),
8005
+ "aria-expanded": detailOpen,
8006
+ children: [
8007
+ detailOpen ? /* @__PURE__ */ jsx(ChevronDown, {}) : /* @__PURE__ */ jsx(ChevronRight$1, {}),
8008
+ detailOpen ? "Hide details" : "Show details"
8009
+ ]
8010
+ }
8011
+ ) }),
8012
+ detailOpen && errorInfo.detail && /* @__PURE__ */ jsx("pre", { className: "w-full overflow-x-auto rounded-[6px] border border-destructive/20 bg-background p-2 font-mono text-xs whitespace-pre-wrap wrap-break-word text-muted-foreground", children: errorInfo.detail }),
8013
+ (showRetry || onDismiss) && /* @__PURE__ */ jsxs("div", { className: "flex gap-2 pt-1", children: [
8014
+ showRetry && /* @__PURE__ */ jsxs(
8015
+ Button,
8016
+ {
8017
+ size: "xs",
8018
+ variant: "secondary",
8019
+ onClick: handleRetry,
8020
+ disabled: retryPending,
8021
+ children: [
8022
+ /* @__PURE__ */ jsx(
8023
+ RefreshCw,
8024
+ {
8025
+ className: cn("size-3", retryPending && "animate-spin")
8026
+ }
8027
+ ),
8028
+ retryPending ? "Retrying\u2026" : "Retry"
8029
+ ]
8030
+ }
8031
+ ),
8032
+ onDismiss && /* @__PURE__ */ jsx(Button, { size: "xs", variant: "ghost", onClick: onDismiss, children: "Dismiss" })
8033
+ ] }),
8034
+ retryError && /* @__PURE__ */ jsxs("div", { className: "pt-1 text-xs text-destructive", role: "status", children: [
8035
+ "Retry failed: ",
8036
+ retryError
8037
+ ] })
8038
+ ] })
8039
+ ] });
8736
8040
  });
8737
8041
  function parseRequestedTokens(detail) {
8738
8042
  const m = detail.match(/["']?requested["']?\s*[:=]\s*(\d+)/);
@@ -8745,34 +8049,24 @@ var InsufficientCreditsCard = memo(function InsufficientCreditsCard2({
8745
8049
  }) {
8746
8050
  const { onOpenBilling } = useAgentChatAdapterContext();
8747
8051
  const requested = parseRequestedTokens(detail);
8748
- return /* @__PURE__ */ jsxs(
8749
- "div",
8750
- {
8751
- role: "alert",
8752
- className: cn(
8753
- "flex w-full gap-3 rounded-md border border-amber-500/30 bg-amber-500/5 p-4",
8754
- className
8755
- ),
8756
- children: [
8757
- /* @__PURE__ */ jsx(CreditCard, { className: "mt-0.5 size-5 shrink-0 text-amber-600 dark:text-amber-400" }),
8758
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-2", children: [
8759
- /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-foreground", children: "You're out of credits" }),
8760
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
8761
- "This run was blocked by the token-credit limit",
8762
- requested ? ` (it needed ~${requested.toLocaleString()} tokens)` : "",
8763
- ". Buy additional credits or upgrade your plan to keep your agents running."
8764
- ] }),
8765
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2 pt-1", children: [
8766
- onOpenBilling && /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: onOpenBilling, children: [
8767
- /* @__PURE__ */ jsx(CreditCard, { className: "size-4" }),
8768
- "Go to Billing"
8769
- ] }),
8770
- onDismiss && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: onDismiss, children: "Dismiss" })
8771
- ] })
8772
- ] })
8773
- ]
8774
- }
8775
- );
8052
+ return /* @__PURE__ */ jsxs(Alert, { variant: "warning", className: cn("gap-y-2", className), children: [
8053
+ /* @__PURE__ */ jsx(CreditCard, {}),
8054
+ /* @__PURE__ */ jsx(AlertTitle, { children: "You're out of credits" }),
8055
+ /* @__PURE__ */ jsxs(AlertDescription, { className: "flex flex-col items-start gap-2", children: [
8056
+ /* @__PURE__ */ jsxs("p", { children: [
8057
+ "This run was blocked by the token-credit limit",
8058
+ requested ? ` (it needed ~${requested.toLocaleString()} tokens)` : "",
8059
+ ". Buy additional credits or upgrade your plan to keep your agents running."
8060
+ ] }),
8061
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2 pt-1", children: [
8062
+ onOpenBilling && /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: onOpenBilling, children: [
8063
+ /* @__PURE__ */ jsx(CreditCard, { className: "size-4" }),
8064
+ "Go to Billing"
8065
+ ] }),
8066
+ onDismiss && /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: onDismiss, children: "Dismiss" })
8067
+ ] })
8068
+ ] })
8069
+ ] });
8776
8070
  });
8777
8071
  var DOCUMENT = { icon: FileTextIcon, kind: "Document" };
8778
8072
  var SPREADSHEET = { icon: FileSpreadsheetIcon, kind: "Spreadsheet" };
@@ -9081,15 +8375,7 @@ function WorkerCard({ worker }) {
9081
8375
  return (
9082
8376
  // A long name is cut, its mark never.
9083
8377
  /* @__PURE__ */ jsxs("li", { className: "flex min-w-0 max-w-full", title: file.label, children: [
9084
- file.kind === "file" && onFileSelect ? /* @__PURE__ */ jsx(
9085
- "button",
9086
- {
9087
- type: "button",
9088
- className: "min-w-0 truncate underline",
9089
- onClick: () => onFileSelect(file.ref),
9090
- children: /* @__PURE__ */ jsx("bdi", { children: file.label })
9091
- }
9092
- ) : /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: /* @__PURE__ */ jsx("bdi", { children: file.label }) }),
8378
+ file.kind === "file" && onFileSelect ? /* @__PURE__ */ jsx(TextLink, { variant: "muted", size: "inline", asChild: true, children: /* @__PURE__ */ jsx("button", { type: "button", className: "min-w-0 truncate", onClick: () => onFileSelect(file.ref), children: /* @__PURE__ */ jsx("bdi", { children: file.label }) }) }) : /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: /* @__PURE__ */ jsx("bdi", { children: file.label }) }),
9093
8379
  mark && /* @__PURE__ */ jsx("span", { "data-mark": landing, className: "shrink-0 whitespace-pre text-muted-foreground", children: ` \xB7 ${mark}` })
9094
8380
  ] }, `${file.kind}:${file.ref}`)
9095
8381
  );
@@ -9937,7 +9223,7 @@ function useElapsedSeconds(since) {
9937
9223
  function formatElapsed(seconds) {
9938
9224
  return seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m ${seconds % 60}s`;
9939
9225
  }
9940
- function CommandGroup2({ commands, live }) {
9226
+ function CommandGroup3({ commands, live }) {
9941
9227
  const [chosen, setChosen] = useState(null);
9942
9228
  const open = chosen ?? live !== void 0;
9943
9229
  const elapsed = useElapsedSeconds(live ? (commands[0]?.message ?? live).createdAt : void 0);
@@ -10025,7 +9311,7 @@ function IterationGroup({
10025
9311
  return /* @__PURE__ */ jsx("p", { className: "py-0.5 text-sm text-muted-foreground", children: reasoningTokenLabel(message, false) });
10026
9312
  }
10027
9313
  const commands = iterationCommands(message);
10028
- return commands.length === 1 ? /* @__PURE__ */ jsx(CommandRow, { label: commands[0].label, calls: commands[0].calls }) : /* @__PURE__ */ jsx(CommandGroup2, { commands });
9314
+ return commands.length === 1 ? /* @__PURE__ */ jsx(CommandRow, { label: commands[0].label, calls: commands[0].calls }) : /* @__PURE__ */ jsx(CommandGroup3, { commands });
10029
9315
  }
10030
9316
  function deriveFileArtifactsFromMessages(messages) {
10031
9317
  const terminalCommands = [];
@@ -10100,10 +9386,10 @@ function SimpleAssistantGroup({
10100
9386
  const endRun = (live) => {
10101
9387
  const key = (run[0]?.message ?? live)?.id;
10102
9388
  if (live && (run.length > 0 || liveCommands(live).length > 0)) {
10103
- rows.push(/* @__PURE__ */ jsx(CommandGroup2, { commands: run, live }, key));
9389
+ rows.push(/* @__PURE__ */ jsx(CommandGroup3, { commands: run, live }, key));
10104
9390
  } else {
10105
9391
  if (run.length > 1) {
10106
- rows.push(/* @__PURE__ */ jsx(CommandGroup2, { commands: run }, key));
9392
+ rows.push(/* @__PURE__ */ jsx(CommandGroup3, { commands: run }, key));
10107
9393
  } else if (run.length === 1) {
10108
9394
  rows.push(
10109
9395
  /* @__PURE__ */ jsx(CommandRow, { label: run[0].label, calls: run[0].calls }, run[0].key)
@@ -10250,34 +9536,30 @@ function AssistantGroup({
10250
9536
  }
10251
9537
  function RetryBanner({ indicator }) {
10252
9538
  const [open, setOpen] = useState(false);
10253
- return /* @__PURE__ */ jsxs(
10254
- "div",
10255
- {
10256
- role: "status",
10257
- className: "flex flex-col gap-1 border-l-2 border-amber-500 bg-amber-500/5 px-3 py-2 text-xs",
10258
- children: [
10259
- /* @__PURE__ */ jsxs(
10260
- "button",
10261
- {
10262
- type: "button",
10263
- onClick: () => setOpen((prev) => !prev),
10264
- className: "flex items-center gap-2 text-left text-amber-600 hover:text-amber-700",
10265
- "aria-expanded": open,
10266
- children: [
10267
- /* @__PURE__ */ jsx(AlertTriangle, { className: "size-3 shrink-0" }),
10268
- /* @__PURE__ */ jsx("span", { className: "flex-1 truncate font-medium", children: indicator.title }),
10269
- /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-foreground/60", children: [
10270
- "attempt ",
10271
- indicator.attempt
10272
- ] }),
10273
- indicator.detail && (open ? /* @__PURE__ */ jsx(ChevronDown, { className: "size-3" }) : /* @__PURE__ */ jsx(ChevronRight$1, { className: "size-3" }))
10274
- ]
10275
- }
10276
- ),
10277
- open && indicator.detail && /* @__PURE__ */ jsx("pre", { className: "mt-1 overflow-x-auto rounded-none bg-background p-2 font-mono text-[11px] whitespace-pre-wrap wrap-break-word text-foreground/60", children: indicator.detail })
10278
- ]
10279
- }
10280
- );
9539
+ return /* @__PURE__ */ jsxs(Alert, { variant: "warning", role: "status", children: [
9540
+ /* @__PURE__ */ jsx(AlertTriangle, {}),
9541
+ /* @__PURE__ */ jsxs(AlertTitle, { className: "flex min-w-0 items-center gap-2 font-medium", children: [
9542
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: indicator.title }),
9543
+ /* @__PURE__ */ jsxs("span", { className: "shrink-0 text-[11.5px] font-normal opacity-70", children: [
9544
+ "attempt ",
9545
+ indicator.attempt
9546
+ ] })
9547
+ ] }),
9548
+ indicator.detail && /* @__PURE__ */ jsx(AlertAction, { children: /* @__PURE__ */ jsxs(
9549
+ Button,
9550
+ {
9551
+ variant: "ghost",
9552
+ size: "xs",
9553
+ onClick: () => setOpen((prev) => !prev),
9554
+ "aria-expanded": open,
9555
+ children: [
9556
+ open ? "Hide details" : "Details",
9557
+ open ? /* @__PURE__ */ jsx(ChevronDown, {}) : /* @__PURE__ */ jsx(ChevronRight$1, {})
9558
+ ]
9559
+ }
9560
+ ) }),
9561
+ open && indicator.detail && /* @__PURE__ */ jsx(AlertDescription, { children: /* @__PURE__ */ jsx("pre", { className: "mt-1 overflow-x-auto rounded-[6px] bg-background p-2 font-mono text-[11px] whitespace-pre-wrap wrap-break-word text-foreground/60", children: indicator.detail }) })
9562
+ ] });
10281
9563
  }
10282
9564
  function WorkingOnItIndicator({ activity }) {
10283
9565
  return /* @__PURE__ */ jsx(Message, { from: "assistant", children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(OrbShimmerLabel, { state: activity.state, label: activity.label }) }) });
@@ -13553,26 +12835,6 @@ function mapSelected(doc, edit) {
13553
12835
  objects: doc.objects.map((o) => o.selected ? edit(o) : o)
13554
12836
  };
13555
12837
  }
13556
- var RABBIT_MARK_PATH = "M49.71,46.83c0,.23.02.45.07.67,2.1.49,4.16,1.07,6.18,1.74.58-.64.94-1.48.94-2.42,0-1.98-1.61-3.59-3.59-3.59s-3.59,1.61-3.59,3.59M33.95,78.3c3.1-5.1,6.72-8.89,11.64-12.21.61-.42,1.24-.8,1.88-1.17.44-.25.61-.66.58-1.05,0-.53-.49-.91-.93-1.12-1.34-.62-2.72-1.5-4.06-2.54-1.57-1.22-3.01-2.59-4.36-4.06-.95-1.04-2.02-2.38-3-3.81-.81-1.18-.63-2.77.43-3.73,1.1-1,2.26-1.92,3.48-2.76.36-.25.72-.49,1.1-.73,2.43-1.55,5.05-2.79,7.79-3.7,3.23-1.07,6.62-1.66,10.03-1.74.59-.35,1.19-.69,1.8-1.01,1.66-.88,3.38-1.62,5.17-2.21,1.58-.54,3.2-.95,4.85-1.24,3.28-.59,6.64-.7,9.95-.32,1.23.14,2.45.34,3.68.62,2.87.64,5.59,1.62,8.09,2.9.54.27.71.95.36,1.45-1.58,2.22-3.46,4.25-5.5,6.05-3.01,2.65-6.51,4.75-10.26,6.17-2.32.88-4.75,1.53-7.22,1.91-.62.1-.78.9-.24,1.22,0,0,.01,0,.02.01,6.97,4.05,13.1,9.22,18.36,15.32.72.83,1.42,1.68,2.1,2.53,3.36,4.22,6.23,8.82,8.56,13.68,1.8,3.73,3.27,7.63,4.39,11.62.73,2.6,1.34,5.24,1.76,7.91.11.76-.87,1.16-1.3.53-1.15-1.69-2.31-3.35-3.61-4.93-1.2-1.46-2.46-2.86-3.75-4.24-5.44-5.8-11.84-10.7-18.84-14.48-7.32-3.94-15.09-6.38-23.44-6.53-2.23-.04-4.46.08-6.68.3-4.05.43-8.02,1.28-11.93,2.4-.03,0-.05.01-.08.02,0,0-.01,0-.02,0-.07.02-.14.03-.21.03-.53,0-.91-.6-.61-1.09M50.95,12.97c-1.31,1.16-2.2,2.71-2.9,4.29-1.66,3.74-2.85,7.74-3.52,11.77-.32,1.92-.56,3.87-1.28,5.69-.17.44-.37.87-.6,1.28-1.18,2.1-3.37,3.19-5.6,3.86-4.96,1.47-10.14,1.97-15.25,2.65-2.37.31-8.03,1.12-7.34,4.69.46,2.36,2.26,4.16,4.08,5.6,2.66,2.11,5.44,4.09,8.33,5.88,1.87,1.15,3.85,2.11,5.6,3.44,1.74,1.33,3.15,3.05,3.58,5.25.22,1.16-.18,2.35-1,3.2-1.57,1.63-3,3.41-4.25,5.29-1.32,2.1-2.38,4.35-3.25,6.65-.59,1.44.97,2.98,2.41,2.37.53-.21,1.07-.41,1.61-.61,2.26-.82,4.68.73,4.93,3.12.17,1.61.38,3.17.63,4.57.46,2.57,3.14,3.63,5.32,1.41,2.84-2.88,4.66-6.31,7.84-8.86,2.53-2.03,6.26-4.17,9.71-3.59,3.17.56,6.27,1.52,9.23,2.85,5.32,2.32,10.36,5.29,14.95,8.86,9.17,7.1,16.56,16.51,21.27,27.1.93,2.07,4.03,1.44,4.1-.83.55-17.71-5.72-35.46-17.11-49.01-2.87-3.42-6.07-6.65-9.59-9.44-.88-.8-1.54-1.7-1.38-2.93.38-2.97,2-4.32,4.04-5.85,2.51-1.89,5.02-3.85,7.16-6.21.03-.03.06-.06.09-.1,1.24-1.37,2.38-2.83,3.4-4.37,1.2-1.81.6-4.26-1.3-5.31,0,0-.96-.52-1.45-.76-2.72-1.34-5.61-2.36-8.6-3.03-2.76-.62-5.58-.93-8.38-.93-2.38,0-4.76.22-7.09.67-1.96.37-3.97-.31-5.25-1.84-.28-.34-.54-.69-.79-1.04-.58-.84-1.09-1.71-1.63-2.58-1.29-2.06-1.87-3.63-2.89-5.84-1.06-2.29-1.85-4.73-3.26-6.86-.73-1.11-1.53-1.54-2.32-1.54s-1.54.41-2.24,1.02";
13557
- var RABBIT_MARK_BOX = {
13558
- x: 14.4021,
13559
- y: 11.93,
13560
- h: 109.058
13561
- };
13562
- function RabbitMark({ className }) {
13563
- return /* @__PURE__ */ jsx(
13564
- "svg",
13565
- {
13566
- className,
13567
- viewBox: "14.4021 11.93 95.1813 109.058",
13568
- fill: "currentColor",
13569
- "aria-hidden": "true",
13570
- children: /* @__PURE__ */ jsx("path", { d: RABBIT_MARK_PATH })
13571
- }
13572
- );
13573
- }
13574
-
13575
- // src/components/whiteboard/render.ts
13576
12838
  var TEXT_GLYPH_ADVANCE = 0.6;
13577
12839
  var AGENT_COLOR = "#2563eb";
13578
12840
  var TEXT_COLOR = "#111827";
@@ -15087,66 +14349,66 @@ function ToolRail({
15087
14349
  return /* @__PURE__ */ jsxs(
15088
14350
  "div",
15089
14351
  {
15090
- className: "flex flex-col gap-1 rounded-lg border bg-background p-1",
14352
+ className: "flex flex-col items-center gap-1 rounded-lg border bg-background p-1",
15091
14353
  role: "toolbar",
15092
14354
  "aria-label": "Whiteboard tools",
15093
14355
  "aria-orientation": "vertical",
15094
14356
  children: [
15095
- TOOLS.map(({ id, label, Icon }) => /* @__PURE__ */ jsx(
15096
- Button,
14357
+ /* @__PURE__ */ jsx(
14358
+ ToggleGroup,
15097
14359
  {
15098
- type: "button",
15099
- size: "icon",
15100
- variant: tool === id ? "default" : "ghost",
15101
- "aria-label": label,
15102
- "aria-pressed": tool === id,
14360
+ type: "single",
14361
+ orientation: "vertical",
14362
+ "aria-label": "Tool",
14363
+ value: tool,
14364
+ onValueChange: (next) => {
14365
+ if (next) onToolChange(next);
14366
+ },
15103
14367
  disabled,
15104
- onClick: () => onToolChange(id),
15105
- children: /* @__PURE__ */ jsx(Icon, { className: "size-4" })
15106
- },
15107
- id
15108
- )),
15109
- /* @__PURE__ */ jsx("div", { className: "my-1 h-px bg-border" }),
15110
- INK_COLORS.map((c) => /* @__PURE__ */ jsx(
15111
- "button",
14368
+ children: TOOLS.map(({ id, label, Icon }) => /* @__PURE__ */ jsx(ToggleGroupItem, { value: id, "aria-label": label, size: "icon", children: /* @__PURE__ */ jsx(Icon, { className: "size-4" }) }, id))
14369
+ }
14370
+ ),
14371
+ /* @__PURE__ */ jsx("div", { className: "my-1 h-px w-full bg-border" }),
14372
+ /* @__PURE__ */ jsx(
14373
+ ToggleGroup,
15112
14374
  {
15113
- type: "button",
15114
- "aria-label": `Colour ${c}`,
15115
- "aria-pressed": color === c,
14375
+ type: "single",
14376
+ variant: "outline",
14377
+ size: "sm",
14378
+ orientation: "vertical",
14379
+ "aria-label": "Colour",
14380
+ value: color,
14381
+ onValueChange: (next) => {
14382
+ if (next) onColorChange(next);
14383
+ },
15116
14384
  disabled,
15117
- onClick: () => onColorChange(c),
15118
- className: cn(
15119
- "mx-auto size-5 rounded-full border-2",
15120
- color === c ? "border-foreground" : "border-transparent"
15121
- ),
15122
- style: { backgroundColor: c }
15123
- },
15124
- c
15125
- )),
15126
- /* @__PURE__ */ jsx("div", { className: "my-1 h-px bg-border" }),
15127
- INK_WIDTHS.map((w) => /* @__PURE__ */ jsx(
15128
- "button",
14385
+ children: INK_COLORS.map((c) => /* @__PURE__ */ jsx(ToggleGroupItem, { value: c, "aria-label": `Colour ${c}`, size: "icon-xs", children: /* @__PURE__ */ jsx("span", { className: "size-5 rounded-full", style: { backgroundColor: c } }) }, c))
14386
+ }
14387
+ ),
14388
+ /* @__PURE__ */ jsx("div", { className: "my-1 h-px w-full bg-border" }),
14389
+ /* @__PURE__ */ jsx(
14390
+ ToggleGroup,
15129
14391
  {
15130
- type: "button",
15131
- "aria-label": `Width ${w}`,
15132
- "aria-pressed": width === w,
14392
+ type: "single",
14393
+ variant: "outline",
14394
+ size: "sm",
14395
+ orientation: "vertical",
14396
+ "aria-label": "Width",
14397
+ value: String(width),
14398
+ onValueChange: (next) => {
14399
+ if (next) onWidthChange(Number(next));
14400
+ },
15133
14401
  disabled,
15134
- onClick: () => onWidthChange(w),
15135
- className: cn(
15136
- "mx-auto flex size-6 items-center justify-center rounded",
15137
- width === w ? "bg-accent" : ""
15138
- ),
15139
- children: /* @__PURE__ */ jsx(
14402
+ children: INK_WIDTHS.map((w) => /* @__PURE__ */ jsx(ToggleGroupItem, { value: String(w), "aria-label": `Width ${w}`, size: "icon-xs", children: /* @__PURE__ */ jsx(
15140
14403
  "span",
15141
14404
  {
15142
14405
  className: "rounded-full bg-foreground",
15143
14406
  style: { width: w + 2, height: w + 2 }
15144
14407
  }
15145
- )
15146
- },
15147
- w
15148
- )),
15149
- /* @__PURE__ */ jsx("div", { className: "my-1 h-px bg-border" }),
14408
+ ) }, w))
14409
+ }
14410
+ ),
14411
+ /* @__PURE__ */ jsx("div", { className: "my-1 h-px w-full bg-border" }),
15150
14412
  /* @__PURE__ */ jsx(
15151
14413
  Button,
15152
14414
  {
@@ -15200,6 +14462,13 @@ var VIEW_MODE_LABELS = {
15200
14462
  expert: "Advanced",
15201
14463
  whiteboard: "Whiteboard"
15202
14464
  };
14465
+ var VIEW_MODE_SEGMENTS2 = ["simple", "expert", "whiteboard"].map(
14466
+ (mode) => ({
14467
+ value: mode,
14468
+ label: VIEW_MODE_LABELS[mode],
14469
+ ariaLabel: `${VIEW_MODE_LABELS[mode]} view`
14470
+ })
14471
+ );
15203
14472
  function AgentWhiteboard(props) {
15204
14473
  const runtime = useAgentChatRuntime({
15205
14474
  adapter: props.adapter,
@@ -16070,21 +15339,15 @@ function WhiteboardSurface({
16070
15339
  children: "New board"
16071
15340
  }
16072
15341
  ) : null,
16073
- viewMode && onViewModeChange && hasAnswer ? /* @__PURE__ */ jsx("div", { className: "flex items-center rounded-full border p-0.5", children: ["simple", "expert", "whiteboard"].map((mode) => /* @__PURE__ */ jsx(
16074
- "button",
15342
+ viewMode && onViewModeChange && hasAnswer ? /* @__PURE__ */ jsx(
15343
+ SegmentedControl,
16075
15344
  {
16076
- type: "button",
16077
- "aria-label": `${VIEW_MODE_LABELS[mode]} view`,
16078
- "aria-pressed": viewMode === mode,
16079
- className: cn(
16080
- "rounded-full px-3 py-1 text-xs",
16081
- viewMode === mode ? "bg-background font-medium shadow-sm" : "text-muted-foreground"
16082
- ),
16083
- onClick: () => onViewModeChange(mode),
16084
- children: VIEW_MODE_LABELS[mode]
16085
- },
16086
- mode
16087
- )) }) : null
15345
+ "aria-label": "View",
15346
+ segments: VIEW_MODE_SEGMENTS2,
15347
+ value: viewMode,
15348
+ onChange: onViewModeChange
15349
+ }
15350
+ ) : null
16088
15351
  ] })
16089
15352
  ] });
16090
15353
  }
@@ -16249,6 +15512,7 @@ function OfficeEditorPane({ adapter, sessionId, path, view, officeEvent, onClose
16249
15512
  const placeholderId = `office-editor-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
16250
15513
  const [error, setError] = useState(null);
16251
15514
  const [loading, setLoading] = useState(true);
15515
+ const [mentionTrouble, setMentionTrouble] = useState(null);
16252
15516
  const [openedAfter] = useState(() => officeEvent?.eventId ?? 0);
16253
15517
  const notice = officeEvent && officeEvent.eventId > openedAfter ? officeEvent : null;
16254
15518
  const [reopenedFor, setReopenedFor] = useState(0);
@@ -16265,6 +15529,7 @@ function OfficeEditorPane({ adapter, sessionId, path, view, officeEvent, onClose
16265
15529
  let editor = null;
16266
15530
  setError(null);
16267
15531
  setLoading(true);
15532
+ setMentionTrouble(null);
16268
15533
  void (async () => {
16269
15534
  try {
16270
15535
  if (!adapter.getWorkspaceEditorConfig) throw new Error("Preview not available. Download the file to open it.");
@@ -16272,7 +15537,31 @@ function OfficeEditorPane({ adapter, sessionId, path, view, officeEvent, onClose
16272
15537
  await loadDocsApi(opened.document_server_url);
16273
15538
  if (cancelled) return;
16274
15539
  if (!window.DocsAPI) throw new Error("The document editor could not be loaded.");
16275
- editor = new window.DocsAPI.DocEditor(placeholderId, opened.config);
15540
+ const users = opened.mentionable_users ?? [];
15541
+ const notify = adapter.notifyWorkspaceEditorMention?.bind(adapter);
15542
+ const events = users.length && notify ? {
15543
+ onRequestUsers: (event) => {
15544
+ const c = event.data?.c;
15545
+ editor?.setUsers({ c, users: c === "mention" || c === "info" ? users : [] });
15546
+ },
15547
+ onRequestSendNotify: (event) => {
15548
+ const mention = event.data ?? {};
15549
+ const emails = mention.emails ?? [];
15550
+ const named2 = new Set(emails.map((email) => email.toLowerCase()));
15551
+ if (!users.some((user) => named2.has(user.email.toLowerCase()))) return;
15552
+ setMentionTrouble(null);
15553
+ void notify({
15554
+ sessionId,
15555
+ path,
15556
+ emails,
15557
+ message: mention.message ?? "",
15558
+ commentId: String(mention.actionLink?.action?.data ?? mention.actionId ?? "")
15559
+ }).catch((sendError) => {
15560
+ if (!cancelled) setMentionTrouble(`The agent was not told about your comment: ${sendError.message}`);
15561
+ });
15562
+ }
15563
+ } : null;
15564
+ editor = new window.DocsAPI.DocEditor(placeholderId, events ? { ...opened.config, events } : opened.config);
16276
15565
  } catch (openError) {
16277
15566
  if (!cancelled) setError(openError.message);
16278
15567
  } finally {
@@ -16324,6 +15613,7 @@ function OfficeEditorPane({ adapter, sessionId, path, view, officeEvent, onClose
16324
15613
  /* @__PURE__ */ jsx("span", { children: error })
16325
15614
  ] }),
16326
15615
  notice && saveNotice(notice) && /* @__PURE__ */ jsx("div", { role: "status", className: "border-b border-line px-3 py-2 text-xs text-muted-foreground", children: saveNotice(notice) }),
15616
+ mentionTrouble && /* @__PURE__ */ jsx("div", { role: "status", className: "border-b border-line px-3 py-2 text-xs text-muted-foreground", children: mentionTrouble }),
16327
15617
  loading && !error && /* @__PURE__ */ jsxs("div", { className: "p-3 text-sm text-muted-foreground", children: [
16328
15618
  "Opening ",
16329
15619
  fileName2,
@@ -16470,46 +15760,37 @@ function FileTreeFolder({
16470
15760
  onSelect?.(path);
16471
15761
  }, [onSelect, path]);
16472
15762
  return /* @__PURE__ */ jsx(Collapsible, { onOpenChange: handleOpenChange, open: isExpanded, children: /* @__PURE__ */ jsxs("div", { className: cn("", className), role: "treeitem", tabIndex: 0, ...props, children: [
16473
- /* @__PURE__ */ jsxs(
16474
- "div",
16475
- {
16476
- className: cn(
16477
- "flex h-9 w-full items-center gap-2 rounded-lg px-2 text-left transition-colors hover:bg-accent",
16478
- isSelected && "bg-accent"
16479
- ),
16480
- children: [
16481
- /* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
16482
- "button",
15763
+ /* @__PURE__ */ jsxs("div", { className: listRowVariants({ size: "sm", active: isSelected }), children: [
15764
+ /* @__PURE__ */ jsx(CollapsibleTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
15765
+ "button",
15766
+ {
15767
+ className: "flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0",
15768
+ type: "button",
15769
+ "aria-label": isExpanded ? `Collapse ${name}` : `Expand ${name}`,
15770
+ children: /* @__PURE__ */ jsx(
15771
+ ChevronRightIcon,
16483
15772
  {
16484
- className: "flex shrink-0 cursor-pointer items-center border-none bg-transparent p-0",
16485
- type: "button",
16486
- "aria-label": isExpanded ? `Collapse ${name}` : `Expand ${name}`,
16487
- children: /* @__PURE__ */ jsx(
16488
- ChevronRightIcon,
16489
- {
16490
- className: cn(
16491
- "size-4 shrink-0 text-muted-foreground transition-transform",
16492
- isExpanded && "rotate-90"
16493
- )
16494
- }
15773
+ className: cn(
15774
+ "size-4 shrink-0 text-muted-foreground transition-transform",
15775
+ isExpanded && "rotate-90"
16495
15776
  )
16496
15777
  }
16497
- ) }),
16498
- /* @__PURE__ */ jsxs(
16499
- "button",
16500
- {
16501
- className: "flex min-w-0 flex-1 cursor-pointer items-center gap-2 border-none bg-transparent p-0 text-left",
16502
- onClick: handleSelect,
16503
- type: "button",
16504
- children: [
16505
- /* @__PURE__ */ jsx(FileTreeIcon, { children: isExpanded ? /* @__PURE__ */ jsx(FolderOpenIcon, { className: "size-4.5 text-muted-foreground", strokeWidth: 1.8 }) : /* @__PURE__ */ jsx(FolderIcon, { className: "size-4.5 text-muted-foreground", strokeWidth: 1.8 }) }),
16506
- /* @__PURE__ */ jsx(FileTreeName, { children: name })
16507
- ]
16508
- }
16509
15778
  )
16510
- ]
16511
- }
16512
- ),
15779
+ }
15780
+ ) }),
15781
+ /* @__PURE__ */ jsxs(
15782
+ "button",
15783
+ {
15784
+ className: "flex min-w-0 flex-1 cursor-pointer items-center gap-2 border-none bg-transparent p-0 text-left",
15785
+ onClick: handleSelect,
15786
+ type: "button",
15787
+ children: [
15788
+ /* @__PURE__ */ jsx(FileTreeIcon, { children: isExpanded ? /* @__PURE__ */ jsx(FolderOpenIcon, { className: "size-4.5 text-muted-foreground", strokeWidth: 1.8 }) : /* @__PURE__ */ jsx(FolderIcon, { className: "size-4.5 text-muted-foreground", strokeWidth: 1.8 }) }),
15789
+ /* @__PURE__ */ jsx(FileTreeName, { children: name })
15790
+ ]
15791
+ }
15792
+ )
15793
+ ] }),
16513
15794
  /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("div", { className: "pl-5", children }) })
16514
15795
  ] }) });
16515
15796
  }
@@ -16538,8 +15819,8 @@ function FileTreeFile({
16538
15819
  "div",
16539
15820
  {
16540
15821
  className: cn(
16541
- "group flex h-9 cursor-pointer items-center gap-2 rounded-lg px-2 transition-colors hover:bg-accent",
16542
- isSelected && "bg-accent",
15822
+ listRowVariants({ size: "sm", active: isSelected }),
15823
+ "group cursor-pointer",
16543
15824
  className
16544
15825
  ),
16545
15826
  onClick: handleClick,
@@ -16576,14 +15857,14 @@ function forgetChatFiles() {
16576
15857
  chats.clear();
16577
15858
  changed();
16578
15859
  }
16579
- function subscribe2(listener) {
15860
+ function subscribe(listener) {
16580
15861
  listeners.add(listener);
16581
15862
  return () => {
16582
15863
  listeners.delete(listener);
16583
15864
  };
16584
15865
  }
16585
15866
  function useChatFiles(chat) {
16586
- return useSyncExternalStore(subscribe2, () => chat === null ? NONE : chats.get(chat) ?? NONE);
15867
+ return useSyncExternalStore(subscribe, () => chat === null ? NONE : chats.get(chat) ?? NONE);
16587
15868
  }
16588
15869
  var SKELETON_WIDTHS2 = [75, 60, 90, 65, 80, 70, 85, 55];
16589
15870
  var NO_ENTRIES = [];
@@ -16662,22 +15943,32 @@ function RenderEntries({
16662
15943
  entry.size != null && /* @__PURE__ */ jsx("span", { className: "ml-1 shrink-0 text-xs text-muted-foreground/60", children: formatFileSize(entry.size) }),
16663
15944
  /* @__PURE__ */ jsxs("div", { className: "ml-1 flex shrink-0 items-center gap-0 opacity-100 transition-opacity md:opacity-0 md:group-hover:opacity-100", children: [
16664
15945
  /* @__PURE__ */ jsx(
16665
- "a",
15946
+ Button,
16666
15947
  {
16667
- href: downloadUrlFor(entry.path),
16668
- download: fileName2,
16669
- className: "rounded p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground",
16670
- onClick: (event) => event.stopPropagation(),
16671
- title: "Download",
16672
- "aria-label": `Download ${fileName2}`,
16673
- children: /* @__PURE__ */ jsx(DownloadIcon, { className: "size-5" })
15948
+ asChild: true,
15949
+ variant: "ghost",
15950
+ size: "icon-xs",
15951
+ className: "text-muted-foreground hover:text-foreground",
15952
+ children: /* @__PURE__ */ jsx(
15953
+ "a",
15954
+ {
15955
+ href: downloadUrlFor(entry.path),
15956
+ download: fileName2,
15957
+ onClick: (event) => event.stopPropagation(),
15958
+ title: "Download",
15959
+ "aria-label": `Download ${fileName2}`,
15960
+ children: /* @__PURE__ */ jsx(DownloadIcon, { className: "size-5" })
15961
+ }
15962
+ )
16674
15963
  }
16675
15964
  ),
16676
15965
  /* @__PURE__ */ jsx(
16677
- "button",
15966
+ Button,
16678
15967
  {
16679
15968
  type: "button",
16680
- className: "rounded p-0.5 text-muted-foreground hover:bg-destructive/10 hover:text-destructive",
15969
+ variant: "ghost",
15970
+ size: "icon-xs",
15971
+ className: "text-muted-foreground hover:bg-destructive/10 hover:text-destructive",
16681
15972
  onClick: (event) => {
16682
15973
  event.stopPropagation();
16683
15974
  onDelete(entry.path);
@@ -16891,7 +16182,7 @@ function WorkspacePanel({
16891
16182
  type: "button",
16892
16183
  variant: "ghost",
16893
16184
  size: "icon-sm",
16894
- className: "rounded-xl text-foreground/80 md:size-11",
16185
+ className: "text-foreground/80 md:size-11",
16895
16186
  onClick: () => fileInputRef.current?.click(),
16896
16187
  disabled: disabled || !sessionId || uploading,
16897
16188
  "aria-label": "Upload files",
@@ -16907,7 +16198,7 @@ function WorkspacePanel({
16907
16198
  type: "button",
16908
16199
  variant: "ghost",
16909
16200
  size: "icon-sm",
16910
- className: "rounded-xl text-foreground/80 md:size-11",
16201
+ className: "text-foreground/80 md:size-11",
16911
16202
  onClick: () => void fetchTree(),
16912
16203
  disabled: !sessionId || loading,
16913
16204
  "aria-label": "Refresh workspace",
@@ -16955,24 +16246,28 @@ function WorkspacePanel({
16955
16246
  /* @__PURE__ */ jsx(AlertCircleIcon, { className: "mt-0.5 size-4 shrink-0" }),
16956
16247
  /* @__PURE__ */ jsx("span", { children: error })
16957
16248
  ] }),
16958
- !loading && !error && entries.length === 0 && /* @__PURE__ */ jsxs("div", { className: "px-4 py-8 text-center text-sm text-faint", children: [
16959
- /* @__PURE__ */ jsx("p", { children: "No workspace files" }),
16960
- /* @__PURE__ */ jsxs(
16961
- Button,
16962
- {
16963
- type: "button",
16964
- variant: "outline",
16965
- size: "sm",
16966
- className: "mt-3 gap-1.5",
16967
- onClick: () => fileInputRef.current?.click(),
16968
- disabled: disabled || !sessionId,
16969
- children: [
16970
- /* @__PURE__ */ jsx(UploadIcon, { className: "size-3.5" }),
16971
- "Upload files"
16972
- ]
16973
- }
16974
- )
16975
- ] }),
16249
+ !loading && !error && entries.length === 0 && /* @__PURE__ */ jsx(
16250
+ EmptyState,
16251
+ {
16252
+ className: "px-4 py-8",
16253
+ logoClassName: "size-9",
16254
+ title: "No workspace files",
16255
+ action: /* @__PURE__ */ jsxs(
16256
+ Button,
16257
+ {
16258
+ type: "button",
16259
+ variant: "outline",
16260
+ size: "sm",
16261
+ onClick: () => fileInputRef.current?.click(),
16262
+ disabled: disabled || !sessionId,
16263
+ children: [
16264
+ /* @__PURE__ */ jsx(UploadIcon, { className: "size-3.5" }),
16265
+ "Upload files"
16266
+ ]
16267
+ }
16268
+ )
16269
+ }
16270
+ ),
16976
16271
  entries.length > 0 && /* @__PURE__ */ jsx(
16977
16272
  FileTree,
16978
16273
  {
@@ -16995,7 +16290,7 @@ function WorkspacePanel({
16995
16290
  )
16996
16291
  ] }) }),
16997
16292
  /* @__PURE__ */ jsx(
16998
- ConfirmDialog2,
16293
+ ConfirmDialog,
16999
16294
  {
17000
16295
  open: deleteTarget !== null,
17001
16296
  title: "Delete file?",
@@ -17015,46 +16310,6 @@ function WorkspacePanel({
17015
16310
  )
17016
16311
  );
17017
16312
  }
17018
- function ConfirmDialog2({
17019
- open,
17020
- title,
17021
- description,
17022
- confirmLabel,
17023
- loading,
17024
- onConfirm,
17025
- onCancel
17026
- }) {
17027
- return /* @__PURE__ */ jsx(
17028
- Dialog,
17029
- {
17030
- open,
17031
- onOpenChange: (nextOpen) => {
17032
- if (!nextOpen && !loading) onCancel();
17033
- },
17034
- children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-md", children: [
17035
- /* @__PURE__ */ jsxs(DialogHeader, { children: [
17036
- /* @__PURE__ */ jsx(DialogTitle, { children: title }),
17037
- /* @__PURE__ */ jsx(DialogDescription, { children: description })
17038
- ] }),
17039
- /* @__PURE__ */ jsxs(DialogFooter, { children: [
17040
- /* @__PURE__ */ jsx(Button, { variant: "outline", disabled: loading, onClick: onCancel, children: "Cancel" }),
17041
- /* @__PURE__ */ jsxs(
17042
- Button,
17043
- {
17044
- variant: "destructive",
17045
- disabled: loading,
17046
- onClick: onConfirm,
17047
- children: [
17048
- loading && /* @__PURE__ */ jsx(Loader2Icon, { className: "mr-1.5 size-3.5 animate-spin" }),
17049
- confirmLabel
17050
- ]
17051
- }
17052
- )
17053
- ] })
17054
- ] })
17055
- }
17056
- );
17057
- }
17058
16313
 
17059
16314
  // src/lib/sessions.ts
17060
16315
  function sessionComputer(config) {
@@ -17095,12 +16350,7 @@ function readOnlyReasonForSession(session) {
17095
16350
  }
17096
16351
  return { readOnly: false };
17097
16352
  }
17098
- var RIGHT_STACK_STYLE = {
17099
- // Both the column's width and the chat panel's right offset read this, so
17100
- // one value keeps them complementary. 50%: the browser shell renders a real
17101
- // page, and page layouts are unusable in a 440px strip.
17102
- ["--right-stack-w"]: "50%"
17103
- };
16353
+ var RIGHT_STACK_STYLE = { ["--right-stack-w"]: "75%" };
17104
16354
  var MOBILE_PANE_LABELS = {
17105
16355
  chat: "Chat",
17106
16356
  browser: "Browser",
@@ -17313,21 +16563,19 @@ function AgentChat({
17313
16563
  "div",
17314
16564
  {
17315
16565
  "data-testid": "mobile-pane-toggle",
17316
- className: "md:hidden flex shrink-0 border-b border-line bg-card",
17317
- children: mobilePanes.map((pane) => /* @__PURE__ */ jsx(
17318
- "button",
16566
+ className: "md:hidden flex shrink-0 justify-center border-b border-line bg-card px-3 py-2",
16567
+ children: /* @__PURE__ */ jsx(
16568
+ SegmentedControl,
17319
16569
  {
17320
- type: "button",
17321
- onClick: () => setMobileView(pane),
17322
- "aria-pressed": activeMobilePane === pane,
17323
- className: cn(
17324
- "flex-1 min-h-11 px-4 py-3 text-sm font-medium border-b-2 -mb-px transition-colors",
17325
- activeMobilePane === pane ? "border-primary text-foreground" : "border-transparent text-subtle hover:text-foreground"
17326
- ),
17327
- children: MOBILE_PANE_LABELS[pane]
17328
- },
17329
- pane
17330
- ))
16570
+ "aria-label": "Show",
16571
+ segments: mobilePanes.map((pane) => ({
16572
+ value: pane,
16573
+ label: MOBILE_PANE_LABELS[pane]
16574
+ })),
16575
+ value: activeMobilePane,
16576
+ onChange: setMobileView
16577
+ }
16578
+ )
17331
16579
  }
17332
16580
  ),
17333
16581
  /* @__PURE__ */ jsx(
@@ -17764,35 +17012,26 @@ function IntegrationsPage({ agentId, adapter, onBack }) {
17764
17012
  }
17765
17013
  };
17766
17014
  return /* @__PURE__ */ jsxs("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-6 p-6", children: [
17767
- /* @__PURE__ */ jsxs(
17768
- "button",
17769
- {
17770
- type: "button",
17771
- onClick: onBack,
17772
- className: "-mx-2 inline-flex min-h-11 w-fit items-center gap-1.5 rounded-lg px-2 text-sm text-muted-foreground pointer-fine:mx-0 pointer-fine:min-h-0 pointer-fine:px-0 pointer-fine:hover:text-foreground",
17773
- children: [
17774
- /* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-4 w-4" }),
17775
- "Back"
17776
- ]
17777
- }
17778
- ),
17015
+ /* @__PURE__ */ jsx(TextLink, { asChild: true, variant: "muted", children: /* @__PURE__ */ jsxs("button", { type: "button", onClick: onBack, children: [
17016
+ /* @__PURE__ */ jsx(ArrowLeftIcon, { className: "size-4" }),
17017
+ "Back"
17018
+ ] }) }),
17779
17019
  /* @__PURE__ */ jsxs("div", { children: [
17780
17020
  /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold text-foreground", children: "Integrations" }),
17781
17021
  /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Connect third-party services to enhance your agent's capabilities" })
17782
17022
  ] }),
17783
17023
  /* @__PURE__ */ jsx(
17784
- "input",
17024
+ Input,
17785
17025
  {
17786
17026
  type: "search",
17787
17027
  value: query,
17788
17028
  onChange: (e) => setQuery(e.target.value),
17789
- placeholder: "Search integrations...",
17790
- className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm"
17029
+ placeholder: "Search integrations..."
17791
17030
  }
17792
17031
  ),
17793
17032
  error && /* @__PURE__ */ jsx("div", { role: "alert", className: "text-xs text-red-500", children: error }),
17794
17033
  grouped.map(([category, items]) => /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-2", children: [
17795
- /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold uppercase tracking-wide text-muted-foreground/70", children: category }),
17034
+ /* @__PURE__ */ jsx(SectionLabel, { label: category, role: "heading", "aria-level": 2, className: "pl-0" }),
17796
17035
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: items.map((r) => /* @__PURE__ */ jsx(
17797
17036
  ToolkitRow,
17798
17037
  {
@@ -17815,53 +17054,73 @@ function ToolkitRow({
17815
17054
  const [open, setOpen] = useState(false);
17816
17055
  const [broken, setBroken] = useState(false);
17817
17056
  const name = row.name ?? titleCase(row.toolkit);
17818
- return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border border-border p-3", children: [
17819
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
17820
- /* @__PURE__ */ jsxs(
17821
- "button",
17822
- {
17823
- type: "button",
17824
- "aria-label": open ? "Collapse" : "Expand",
17825
- "aria-expanded": open,
17826
- onClick: () => setOpen((v) => !v),
17827
- className: "flex min-w-0 flex-1 items-center gap-2 text-left",
17828
- children: [
17829
- open ? /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground/60" }) : /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground/60" }),
17830
- broken || !row.logo ? /* @__PURE__ */ jsx("span", { className: "inline-flex h-5 w-5 items-center justify-center rounded bg-muted text-sm font-semibold uppercase", children: name.charAt(0) }) : /* @__PURE__ */ jsx(
17831
- "img",
17057
+ return (
17058
+ // A boxed disclosure: the header names the toolkit and opens its
17059
+ // description; Connect sits beside it, outside the trigger, since a
17060
+ // button cannot hold another.
17061
+ /* @__PURE__ */ jsxs(
17062
+ Collapsible,
17063
+ {
17064
+ open,
17065
+ onOpenChange: setOpen,
17066
+ className: "rounded-[10px] border border-foreground/[0.08]",
17067
+ children: [
17068
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 pr-3", children: [
17069
+ /* @__PURE__ */ jsx(
17070
+ CollapsibleHeader,
17832
17071
  {
17833
- src: row.logo,
17834
- alt: name,
17835
- className: "h-5 w-5 rounded object-contain",
17836
- onError: () => setBroken(true)
17072
+ variant: "section",
17073
+ "aria-label": open ? "Collapse" : "Expand",
17074
+ className: "min-w-0 flex-1",
17075
+ children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
17076
+ broken || !row.logo ? /* @__PURE__ */ jsx("span", { className: "inline-flex size-5 shrink-0 items-center justify-center rounded bg-muted text-sm font-semibold uppercase", children: name.charAt(0) }) : /* @__PURE__ */ jsx(
17077
+ "img",
17078
+ {
17079
+ src: row.logo,
17080
+ alt: name,
17081
+ className: "size-5 shrink-0 rounded object-contain",
17082
+ onError: () => setBroken(true)
17083
+ }
17084
+ ),
17085
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: name })
17086
+ ] })
17837
17087
  }
17838
17088
  ),
17839
- /* @__PURE__ */ jsx("span", { className: "truncate font-medium text-foreground", children: name })
17840
- ]
17841
- }
17842
- ),
17843
- /* @__PURE__ */ jsx(
17844
- Button,
17845
- {
17846
- type: "button",
17847
- variant: "outline",
17848
- size: "xs",
17849
- disabled: busy,
17850
- onClick: row.connected ? onDisconnect : onConnect,
17851
- className: "ml-auto min-w-[6rem]",
17852
- children: busy ? /* @__PURE__ */ jsxs(Fragment, { children: [
17853
- /* @__PURE__ */ jsx(Loader2Icon, { className: "h-3.5 w-3.5 animate-spin" }),
17854
- row.connected ? "Disconnecting" : "Connecting"
17855
- ] }) : row.connected ? "Disconnect" : "Connect"
17856
- }
17857
- )
17858
- ] }),
17859
- open && /* @__PURE__ */ jsxs("div", { className: "mt-2 pl-7 text-sm text-muted-foreground", children: [
17860
- row.description && /* @__PURE__ */ jsx("p", { children: row.description }),
17861
- /* @__PURE__ */ jsx("span", { className: "mt-1 inline-block rounded bg-primary/10 px-1.5 py-0.5 text-sm font-semibold text-primary", children: row.auth_mode === "api_key" ? "API Key" : "OAuth" })
17862
- ] })
17863
- ] });
17089
+ /* @__PURE__ */ jsx(
17090
+ Button,
17091
+ {
17092
+ type: "button",
17093
+ variant: "outline",
17094
+ size: "xs",
17095
+ disabled: busy,
17096
+ onClick: row.connected ? onDisconnect : onConnect,
17097
+ className: "min-w-[6rem]",
17098
+ children: busy ? /* @__PURE__ */ jsxs(Fragment, { children: [
17099
+ /* @__PURE__ */ jsx(Loader2Icon, { className: "size-3.5 animate-spin" }),
17100
+ row.connected ? "Disconnecting" : "Connecting"
17101
+ ] }) : row.connected ? "Disconnect" : "Connect"
17102
+ }
17103
+ )
17104
+ ] }),
17105
+ /* @__PURE__ */ jsxs(CollapsibleContent, { className: "border-t border-foreground/[0.08] px-3 py-2.5 text-[13px] text-muted-foreground", children: [
17106
+ row.description && /* @__PURE__ */ jsx("p", { children: row.description }),
17107
+ /* @__PURE__ */ jsx(
17108
+ TagPill,
17109
+ {
17110
+ label: row.auth_mode === "api_key" ? "API key" : "OAuth",
17111
+ className: "mt-1.5"
17112
+ }
17113
+ )
17114
+ ] })
17115
+ ]
17116
+ }
17117
+ )
17118
+ );
17864
17119
  }
17120
+ var MODES = [
17121
+ { value: "oauth", label: "Subscription" },
17122
+ { value: "api_key", label: "API key" }
17123
+ ];
17865
17124
  var PROVIDERS = [
17866
17125
  {
17867
17126
  key: "claude",
@@ -17910,18 +17169,10 @@ function CodingAgentsPanel({ agentId, adapter, onBack }) {
17910
17169
  }, [connections]);
17911
17170
  if (!supported) return null;
17912
17171
  return /* @__PURE__ */ jsxs("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-6 p-6", children: [
17913
- onBack && /* @__PURE__ */ jsxs(
17914
- "button",
17915
- {
17916
- type: "button",
17917
- onClick: onBack,
17918
- className: "-mx-2 inline-flex min-h-11 w-fit items-center gap-1.5 rounded-lg px-2 text-sm text-muted-foreground pointer-fine:mx-0 pointer-fine:min-h-0 pointer-fine:px-0 pointer-fine:hover:text-foreground",
17919
- children: [
17920
- /* @__PURE__ */ jsx(ArrowLeftIcon, { className: "h-4 w-4" }),
17921
- "Back"
17922
- ]
17923
- }
17924
- ),
17172
+ onBack && /* @__PURE__ */ jsx(TextLink, { asChild: true, variant: "muted", children: /* @__PURE__ */ jsxs("button", { type: "button", onClick: onBack, children: [
17173
+ /* @__PURE__ */ jsx(ArrowLeftIcon, { className: "size-4" }),
17174
+ "Back"
17175
+ ] }) }),
17925
17176
  /* @__PURE__ */ jsxs("div", { children: [
17926
17177
  /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold text-foreground", children: "Coding agents" }),
17927
17178
  /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Connect your Claude or ChatGPT plan so the agent can run `/code` on your behalf without separate API billing." })
@@ -18000,40 +17251,21 @@ function ProviderCard({
18000
17251
  return /* @__PURE__ */ jsxs("section", { className: "flex flex-col gap-3 rounded-lg border border-border p-4", children: [
18001
17252
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
18002
17253
  /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-foreground", children: meta.name }),
18003
- /* @__PURE__ */ jsx(
18004
- "span",
18005
- {
18006
- className: `inline-flex items-center rounded px-1.5 py-0.5 text-xs font-semibold ${connected ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground"}`,
18007
- children: connected ? `Connected${connection?.auth_mode === "api_key" ? " (API key)" : ""}` : "Not connected"
18008
- }
18009
- )
18010
- ] }),
18011
- /* @__PURE__ */ jsxs("div", { className: "flex gap-1 text-xs", children: [
18012
- /* @__PURE__ */ jsx(
18013
- "button",
18014
- {
18015
- type: "button",
18016
- onClick: () => {
18017
- setMode("oauth");
18018
- setError(null);
18019
- },
18020
- className: `rounded-md border px-2 py-1 ${mode === "oauth" ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground hover:bg-accent"}`,
18021
- children: "Subscription"
18022
- }
18023
- ),
18024
- /* @__PURE__ */ jsx(
18025
- "button",
18026
- {
18027
- type: "button",
18028
- onClick: () => {
18029
- setMode("api_key");
18030
- setError(null);
18031
- },
18032
- className: `rounded-md border px-2 py-1 ${mode === "api_key" ? "border-primary bg-primary/10 text-primary" : "border-border text-muted-foreground hover:bg-accent"}`,
18033
- children: "API key"
18034
- }
18035
- )
17254
+ /* @__PURE__ */ jsx(TonePill, { tone: connected ? "ok" : "muted", children: connected ? `Connected${connection?.auth_mode === "api_key" ? " (API key)" : ""}` : "Not connected" })
18036
17255
  ] }),
17256
+ /* @__PURE__ */ jsx(
17257
+ SegmentedControl,
17258
+ {
17259
+ "aria-label": "Credential type",
17260
+ segments: MODES,
17261
+ value: mode,
17262
+ onChange: (next) => {
17263
+ setMode(next);
17264
+ setError(null);
17265
+ },
17266
+ className: "self-start"
17267
+ }
17268
+ ),
18037
17269
  /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: instructions }),
18038
17270
  /* @__PURE__ */ jsx(
18039
17271
  "textarea",
@@ -18045,7 +17277,7 @@ function ProviderCard({
18045
17277
  autoComplete: "off",
18046
17278
  rows: mode === "oauth" && meta.provider === "openai" ? 4 : 2,
18047
17279
  "aria-label": `${meta.name} credential`,
18048
- className: "w-full resize-y rounded-md border border-border bg-background px-3 py-2 font-mono text-xs [-webkit-text-security:disc]"
17280
+ className: cn(CONTROL_FIELD, "resize-y font-mono [-webkit-text-security:disc]")
18049
17281
  }
18050
17282
  ),
18051
17283
  error && /* @__PURE__ */ jsx("div", { role: "alert", className: "text-xs text-red-500", children: error }),
@@ -18170,21 +17402,27 @@ function kindIcon(kind) {
18170
17402
  }
18171
17403
  var VIEWS = {
18172
17404
  active: {
17405
+ label: "Active",
18173
17406
  statuses: ["pending"],
18174
17407
  kinds: ["input_required", "action_required", "governance_gate"],
18175
17408
  empty: "Nothing needs you right now"
18176
17409
  },
18177
17410
  updates: {
17411
+ label: "Updates",
18178
17412
  statuses: ["pending"],
18179
17413
  kinds: ["task_complete", "progress_checkin"],
18180
17414
  empty: "No news from your agent"
18181
17415
  },
18182
17416
  history: {
17417
+ label: "History",
18183
17418
  statuses: ["acknowledged", "responded", "expired"],
18184
17419
  empty: "No history yet"
18185
17420
  }
18186
17421
  };
18187
- var VIEW_NAMES = Object.keys(VIEWS);
17422
+ var VIEW_OPTIONS = Object.keys(VIEWS).map((id) => ({
17423
+ id,
17424
+ label: VIEWS[id].label
17425
+ }));
18188
17426
  function belongsToView(item, view) {
18189
17427
  const kinds = VIEWS[view].kinds;
18190
17428
  return VIEWS[view].statuses.includes(item.status) && (kinds === void 0 || kinds.includes(item.kind));
@@ -18208,7 +17446,6 @@ function InboxBody({ body, muted }) {
18208
17446
  }
18209
17447
  );
18210
17448
  }
18211
- var FIELD_CLASS = "h-9 w-full border border-line bg-background px-2 text-sm text-foreground outline-none focus:border-primary disabled:opacity-50";
18212
17449
  function errorMessage(error, fallback) {
18213
17450
  return error instanceof Error && error.message ? error.message : fallback;
18214
17451
  }
@@ -18268,7 +17505,7 @@ function QuestionInput({
18268
17505
  "select",
18269
17506
  {
18270
17507
  "aria-label": prompt,
18271
- className: FIELD_CLASS,
17508
+ className: CONTROL_FIELD,
18272
17509
  disabled,
18273
17510
  value: useOther ? OTHER_OPTION : pickedIndex >= 0 ? String(pickedIndex) : "",
18274
17511
  onChange: (event) => {
@@ -18281,9 +17518,17 @@ function QuestionInput({
18281
17518
  if (choice) onPickChoice(choice.label);
18282
17519
  },
18283
17520
  children: [
18284
- /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select" }),
18285
- choices.map((choice, index) => /* @__PURE__ */ jsx("option", { value: String(index), children: choice.label }, choice.label)),
18286
- allowOther && /* @__PURE__ */ jsx("option", { value: OTHER_OPTION, children: "Other" })
17521
+ /* @__PURE__ */ jsx("option", { value: "", disabled: true, className: CONTROL_OPTION, children: "Select" }),
17522
+ choices.map((choice, index) => /* @__PURE__ */ jsx(
17523
+ "option",
17524
+ {
17525
+ value: String(index),
17526
+ className: CONTROL_OPTION,
17527
+ children: choice.label
17528
+ },
17529
+ choice.label
17530
+ )),
17531
+ allowOther && /* @__PURE__ */ jsx("option", { value: OTHER_OPTION, className: CONTROL_OPTION, children: "Other" })
18287
17532
  ]
18288
17533
  }
18289
17534
  ),
@@ -18291,7 +17536,7 @@ function QuestionInput({
18291
17536
  "input",
18292
17537
  {
18293
17538
  "aria-label": `${prompt} (other)`,
18294
- className: FIELD_CLASS,
17539
+ className: CONTROL_FIELD,
18295
17540
  placeholder: "Type your answer\u2026",
18296
17541
  disabled,
18297
17542
  value: typed,
@@ -18304,7 +17549,7 @@ function QuestionInput({
18304
17549
  "input",
18305
17550
  {
18306
17551
  "aria-label": prompt,
18307
- className: FIELD_CLASS,
17552
+ className: CONTROL_FIELD,
18308
17553
  disabled,
18309
17554
  value: typed,
18310
17555
  onChange: (event) => onType(event.target.value)
@@ -18669,18 +17914,10 @@ function InboxDetail({
18669
17914
  }) {
18670
17915
  const Icon = kindIcon(item.kind);
18671
17916
  return /* @__PURE__ */ jsxs("section", { className: "min-w-0 flex-1 overflow-y-auto p-4 md:p-6", children: [
18672
- onBack && /* @__PURE__ */ jsxs(
18673
- "button",
18674
- {
18675
- type: "button",
18676
- onClick: onBack,
18677
- className: "-ml-2 mb-2 inline-flex min-h-11 items-center gap-1.5 px-2 text-sm font-medium text-muted-foreground md:hidden",
18678
- children: [
18679
- /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "size-4" }),
18680
- "Inbox"
18681
- ]
18682
- }
18683
- ),
17917
+ onBack && /* @__PURE__ */ jsx(TextLink, { variant: "muted", asChild: true, className: "mb-2 md:hidden", children: /* @__PURE__ */ jsxs("button", { type: "button", onClick: onBack, children: [
17918
+ /* @__PURE__ */ jsx(ChevronLeftIcon, {}),
17919
+ "Inbox"
17920
+ ] }) }),
18684
17921
  /* @__PURE__ */ jsxs("div", { className: "mb-5 flex min-w-0 items-start gap-3", children: [
18685
17922
  /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex size-8 shrink-0 items-center justify-center border border-line text-muted-foreground", children: /* @__PURE__ */ jsx(Icon, { className: "size-4" }) }),
18686
17923
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
@@ -18870,60 +18107,49 @@ function InboxPanel({
18870
18107
  /* @__PURE__ */ jsx(InboxIcon, { className: "size-4 text-muted-foreground" }),
18871
18108
  /* @__PURE__ */ jsx("h1", { className: "font-semibold", children: title })
18872
18109
  ] }),
18873
- /* @__PURE__ */ jsx("div", { className: "flex gap-1 border-b border-line px-2 py-2", children: VIEW_NAMES.map((value) => /* @__PURE__ */ jsx(
18874
- "button",
18110
+ /* @__PURE__ */ jsx("div", { className: "border-b border-line px-2 py-2", children: /* @__PURE__ */ jsx(
18111
+ ViewSwitch,
18875
18112
  {
18876
- type: "button",
18877
- onClick: () => selectView(value),
18878
- className: cn(
18879
- "px-2 py-1 text-xs capitalize transition-colors",
18880
- view === value ? "bg-line font-medium text-foreground" : "text-muted-foreground hover:text-foreground"
18881
- ),
18882
- children: value
18883
- },
18884
- value
18885
- )) }),
18113
+ label: "Inbox view",
18114
+ views: VIEW_OPTIONS,
18115
+ value: view,
18116
+ onChange: selectView
18117
+ }
18118
+ ) }),
18886
18119
  /* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto", children: [
18887
18120
  error && items.length === 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-2 px-4 py-3", children: [
18888
18121
  /* @__PURE__ */ jsx("p", { className: "text-sm text-destructive", children: error }),
18889
18122
  /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: () => void load(null), children: "Try again" })
18890
18123
  ] }),
18891
- items.length === 0 && !error && !loading && /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-sm text-muted-foreground", children: VIEWS[view].empty }),
18892
- items.map((item) => {
18893
- const Icon = kindIcon(item.kind);
18894
- const selected = item.id === selectedItemId;
18895
- return /* @__PURE__ */ jsxs(
18896
- "button",
18897
- {
18898
- type: "button",
18899
- "aria-label": `Open inbox item ${item.title}`,
18900
- className: cn(
18901
- "flex w-full min-w-0 gap-3 border-l-2 px-3 py-3 text-left transition-colors hover:bg-input",
18902
- selected ? "border-l-primary bg-line text-foreground" : "border-l-transparent text-subtle",
18903
- !item.readAt && "font-medium text-foreground"
18904
- ),
18905
- onClick: () => void selectItem(item.id),
18906
- children: [
18907
- /* @__PURE__ */ jsx(Icon, { className: "mt-0.5 size-4 shrink-0 text-muted-foreground" }),
18908
- /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
18909
- /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center justify-between gap-2", children: [
18910
- /* @__PURE__ */ jsx("span", { className: "truncate text-xs uppercase tracking-wide text-muted-foreground", children: kindLabel(item.kind) }),
18911
- /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatRelative(item.createdAt) })
18912
- ] }),
18913
- /* @__PURE__ */ jsx("span", { className: "mt-1 block truncate text-sm", children: item.title }),
18914
- /* @__PURE__ */ jsx("span", { className: "mt-1 block text-xs text-muted-foreground", children: statusLabel(item.status) })
18915
- ] })
18916
- ]
18917
- },
18918
- item.id
18919
- );
18920
- }),
18921
- nextCursor && /* @__PURE__ */ jsx(
18922
- Button,
18124
+ items.length === 0 && !error && !loading && /* @__PURE__ */ jsx(EmptyState, { className: "px-4 py-10", title: VIEWS[view].empty }),
18125
+ items.map((item) => /* @__PURE__ */ jsx(
18126
+ ListRow,
18923
18127
  {
18924
- type: "button",
18925
- variant: "ghost",
18926
- className: "w-full",
18128
+ size: "lg",
18129
+ icon: kindIcon(item.kind),
18130
+ label: item.title,
18131
+ description: `${kindLabel(item.kind)} \xB7 ${statusLabel(item.status)}`,
18132
+ meta: formatRelative(item.createdAt),
18133
+ isActive: item.id === selectedItemId,
18134
+ badge: !item.readAt && /* @__PURE__ */ jsx(
18135
+ "span",
18136
+ {
18137
+ "aria-label": "Unread",
18138
+ title: "Unread",
18139
+ className: "size-[7px] shrink-0 rounded-full bg-amber-500"
18140
+ }
18141
+ ),
18142
+ "aria-label": `Open inbox item ${item.title}`,
18143
+ onClick: () => void selectItem(item.id)
18144
+ },
18145
+ item.id
18146
+ )),
18147
+ nextCursor && /* @__PURE__ */ jsx(
18148
+ Button,
18149
+ {
18150
+ type: "button",
18151
+ variant: "ghost",
18152
+ className: "w-full",
18927
18153
  onClick: () => void load(nextCursor),
18928
18154
  disabled: loading,
18929
18155
  children: loading ? "Loading" : "Load more"
@@ -18995,12 +18221,12 @@ function useInboxUnreadCount(adapter) {
18995
18221
  }, [listInbox, openInboxStream, refetch]);
18996
18222
  return { unreadCount, hasLoaded, error };
18997
18223
  }
18998
- var CATEGORY_BADGE_CLASS = {
18999
- spawn: "border-primary/30 bg-primary/10 text-primary",
19000
- output: "border-foreground/20 bg-foreground/5 text-foreground/80",
19001
- done: "border-emerald-500/30 bg-emerald-500/10 text-emerald-600",
19002
- verdict: "border-amber-500/30 bg-amber-500/10 text-amber-600",
19003
- system: "border-border bg-muted text-muted-foreground"
18224
+ var CATEGORY_TONE = {
18225
+ spawn: "warn",
18226
+ output: "muted",
18227
+ done: "ok",
18228
+ verdict: "warn",
18229
+ system: "muted"
19004
18230
  };
19005
18231
  function MissionActivityTab({ feed }) {
19006
18232
  const [filter, setFilter] = useState("all");
@@ -19010,15 +18236,15 @@ function MissionActivityTab({ feed }) {
19010
18236
  return newestFirst.filter((e) => missionEventCategory(e.type) === filter);
19011
18237
  }, [feed.events, filter]);
19012
18238
  if (feed.events.length === 0) {
19013
- return /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No mission activity yet." });
18239
+ return /* @__PURE__ */ jsx(EmptyState, { className: "py-8", title: "No mission activity yet" });
19014
18240
  }
19015
18241
  return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
19016
18242
  /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-1.5", children: ["all", ...MISSION_EVENT_CATEGORIES].map((cat) => /* @__PURE__ */ jsx(
19017
- "button",
18243
+ FilterPill,
19018
18244
  {
19019
- type: "button",
18245
+ on: filter === cat,
19020
18246
  onClick: () => setFilter(cat),
19021
- className: `rounded-full border px-2.5 py-0.5 font-mono text-[10px] uppercase tracking-wide transition-colors ${filter === cat ? "border-foreground bg-foreground text-background" : "border-border/60 bg-background text-muted-foreground hover:bg-muted/40"}`,
18247
+ className: "capitalize",
19022
18248
  children: cat
19023
18249
  },
19024
18250
  cat
@@ -19036,28 +18262,18 @@ function ActivityRow({
19036
18262
  /* @__PURE__ */ jsx("span", { className: "w-20 shrink-0 font-mono text-[10px] text-muted-foreground/60", children: formatMissionTimestamp(event.createdAt) }),
19037
18263
  /* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
19038
18264
  /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center", children: [
19039
- /* @__PURE__ */ jsx(
19040
- "span",
19041
- {
19042
- className: `shrink-0 rounded border px-1.5 font-mono uppercase ${CATEGORY_BADGE_CLASS[category]}`,
19043
- children: category
19044
- }
19045
- ),
18265
+ /* @__PURE__ */ jsx(TonePill, { tone: CATEGORY_TONE[category], className: "capitalize", children: category }),
19046
18266
  /* @__PURE__ */ jsx("p", { className: "shrink-0 text-xs text-foreground font-mono", children: missionEventActorLabel(event, feed.sessions) }),
19047
- taskId ? /* @__PURE__ */ jsx("p", { className: "shrink-0 rounded bg-muted px-1.5 py-0.5 font-mono text-[9px] text-muted-foreground/70", children: taskId.slice(0, 8) }) : null
18267
+ taskId ? /* @__PURE__ */ jsx(TagPill, { label: taskId.slice(0, 8), className: "font-mono" }) : null
19048
18268
  ] }),
19049
18269
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("p", { className: "min-w-0 flex-1 truncate text-foreground/80", children: renderInlineMarkdown(missionEventSummary(event)) }) })
19050
18270
  ] })
19051
18271
  ] });
19052
18272
  }
19053
- function verdictToneClass(result) {
19054
- if (result === "satisfied") {
19055
- return "border-emerald-500/30 bg-emerald-500/5 text-emerald-700 dark:text-emerald-400";
19056
- }
19057
- if (result === "failed" || result === "blocked") {
19058
- return "border-destructive/30 bg-destructive/5 text-destructive";
19059
- }
19060
- return "border-amber-500/30 bg-amber-500/5 text-amber-700 dark:text-amber-400";
18273
+ function missionVerdictTone(result) {
18274
+ if (result === "satisfied") return "ok";
18275
+ if (result === "failed" || result === "blocked") return "bad";
18276
+ return "warn";
19061
18277
  }
19062
18278
  function MissionMetadataTab({ mission }) {
19063
18279
  const rows = [
@@ -19108,7 +18324,7 @@ function MissionMetadataTab({ mission }) {
19108
18324
  mission.lastEvaluationResult ? /* @__PURE__ */ jsxs(
19109
18325
  "section",
19110
18326
  {
19111
- className: `space-y-2 rounded-md border p-4 ${verdictToneClass(mission.lastEvaluationResult)}`,
18327
+ className: `space-y-2 rounded-[10px] p-4 ${TONE[missionVerdictTone(mission.lastEvaluationResult)]}`,
19112
18328
  children: [
19113
18329
  /* @__PURE__ */ jsxs("div", { className: "font-mono text-[10px] uppercase tracking-widest", children: [
19114
18330
  "Last verdict \u2014 ",
@@ -19121,7 +18337,7 @@ function MissionMetadataTab({ mission }) {
19121
18337
  }
19122
18338
  ) : null,
19123
18339
  /* @__PURE__ */ jsxs("section", { children: [
19124
- /* @__PURE__ */ jsx("div", { className: "mb-2 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Identifiers" }),
18340
+ /* @__PURE__ */ jsx(SectionLabel, { label: "Identifiers", className: "mb-2 pl-0" }),
19125
18341
  /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1 text-xs", children: rows.map((r) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
19126
18342
  /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground/70", children: r.label }),
19127
18343
  /* @__PURE__ */ jsx("dd", { className: "break-all text-foreground/90", children: r.value })
@@ -19141,22 +18357,12 @@ function compareNodes(a, b) {
19141
18357
  }
19142
18358
  return pa.length - pb.length;
19143
18359
  }
19144
- function statusToneClass(status) {
19145
- switch (status) {
19146
- case "merged":
19147
- return "border-emerald-500/30 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400";
19148
- case "done":
19149
- return "border-sky-500/30 bg-sky-500/10 text-sky-700 dark:text-sky-400";
19150
- case "running":
19151
- return "border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-400";
19152
- case "failed":
19153
- return "border-destructive/30 bg-destructive/10 text-destructive";
19154
- case "pruned":
19155
- return "border-border bg-muted/40 text-muted-foreground/70 line-through";
19156
- default:
19157
- return "border-border bg-muted/30 text-muted-foreground/80";
19158
- }
19159
- }
18360
+ var IDEA_STATUS_TONE = {
18361
+ merged: "ok",
18362
+ done: "info",
18363
+ running: "warn",
18364
+ failed: "bad"
18365
+ };
19160
18366
  function fmtScore(n) {
19161
18367
  if (n === null || n === void 0) return "\u2014";
19162
18368
  return n.toFixed(3).replace(/\.?0+$/, "") || "0";
@@ -19252,9 +18458,10 @@ function IdeaRow({
19252
18458
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
19253
18459
  /* @__PURE__ */ jsx("code", { className: "shrink-0 text-[11px] text-muted-foreground/60", children: node.nodeKey }),
19254
18460
  /* @__PURE__ */ jsx(
19255
- "span",
18461
+ TonePill,
19256
18462
  {
19257
- className: `shrink-0 rounded border px-1.5 py-0.5 font-mono text-[9px] uppercase tracking-wider ${statusToneClass(node.status)}`,
18463
+ tone: IDEA_STATUS_TONE[node.status] ?? "muted",
18464
+ className: node.status === "pruned" ? "capitalize line-through" : "capitalize",
19258
18465
  children: node.status
19259
18466
  }
19260
18467
  ),
@@ -19287,13 +18494,14 @@ function MissionResearchTab({ research }) {
19287
18494
  return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
19288
18495
  /* @__PURE__ */ jsx(RunHeader, { run }),
19289
18496
  /* @__PURE__ */ jsxs("section", { children: [
19290
- /* @__PURE__ */ jsxs("div", { className: "mb-2 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
19291
- "Idea Tree \xB7 ",
19292
- sorted.length,
19293
- " node",
19294
- sorted.length === 1 ? "" : "s"
19295
- ] }),
19296
- sorted.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground/60", children: "No hypotheses yet." }) : /* @__PURE__ */ jsx("ul", { className: "rounded-md border", children: sorted.map((n) => /* @__PURE__ */ jsx(
18497
+ /* @__PURE__ */ jsx(
18498
+ SectionLabel,
18499
+ {
18500
+ label: `Idea tree \xB7 ${sorted.length} node${sorted.length === 1 ? "" : "s"}`,
18501
+ className: "mb-2 pl-0"
18502
+ }
18503
+ ),
18504
+ sorted.length === 0 ? /* @__PURE__ */ jsx(EmptyState, { className: "py-8", title: "No hypotheses yet" }) : /* @__PURE__ */ jsx("ul", { className: "rounded-md border", children: sorted.map((n) => /* @__PURE__ */ jsx(
19297
18505
  IdeaRow,
19298
18506
  {
19299
18507
  node: n,
@@ -19305,27 +18513,30 @@ function MissionResearchTab({ research }) {
19305
18513
  ] })
19306
18514
  ] });
19307
18515
  }
19308
- var TASK_STATUS_BADGE_CLASS = {
19309
- running: "border-primary/30 bg-primary/10 text-primary",
19310
- blocked: "border-amber-500/30 bg-amber-500/10 text-amber-600",
19311
- done: "border-emerald-500/30 bg-emerald-500/10 text-emerald-600",
19312
- failed: "border-destructive/30 bg-destructive/10 text-destructive",
19313
- cancelled: "border-border bg-muted text-muted-foreground"
18516
+ var TASK_STATUS_TONE = {
18517
+ running: "warn",
18518
+ blocked: "warn",
18519
+ done: "ok",
18520
+ failed: "bad",
18521
+ active: "warn",
18522
+ completed: "ok"
19314
18523
  };
19315
- function statusBadgeClass(status) {
19316
- return TASK_STATUS_BADGE_CLASS[status] ?? "border-foreground/20 bg-foreground/5 text-foreground/70";
18524
+ function missionTaskStatusTone(status) {
18525
+ return TASK_STATUS_TONE[status] ?? "muted";
19317
18526
  }
19318
18527
  function TaskChip({
19319
18528
  task,
19320
18529
  onSelect
19321
18530
  }) {
19322
18531
  return /* @__PURE__ */ jsxs(
19323
- "button",
18532
+ Button,
19324
18533
  {
19325
18534
  type: "button",
18535
+ variant: "outline",
18536
+ size: "xs",
19326
18537
  "data-task-chip": true,
19327
18538
  onClick: () => onSelect(task.id),
19328
- className: "inline-flex max-w-full items-center gap-1.5 rounded-full border border-border/60 bg-background px-2.5 py-1 text-xs hover:bg-muted/40",
18539
+ className: "max-w-full",
19329
18540
  children: [
19330
18541
  /* @__PURE__ */ jsx(
19331
18542
  "span",
@@ -19333,8 +18544,8 @@ function TaskChip({
19333
18544
  className: `size-1.5 shrink-0 rounded-full ${missionTaskStatusDotClass(task.status)}`
19334
18545
  }
19335
18546
  ),
19336
- /* @__PURE__ */ jsx("span", { className: "truncate text-foreground/85", children: missionTaskTitle(task.goal, 40) }),
19337
- /* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[9px] text-muted-foreground/60", children: task.id.slice(0, 8) })
18547
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: missionTaskTitle(task.goal, 40) }),
18548
+ /* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[10px] text-muted-foreground", children: task.id.slice(0, 8) })
19338
18549
  ]
19339
18550
  }
19340
18551
  );
@@ -19347,27 +18558,22 @@ function TaskRailRow({
19347
18558
  const preview = stripMissionControlMarkup(
19348
18559
  task.status === "done" && task.result ? task.result : task.goal
19349
18560
  );
19350
- return /* @__PURE__ */ jsxs(
19351
- "button",
18561
+ return /* @__PURE__ */ jsx(
18562
+ ListRow,
19352
18563
  {
19353
- type: "button",
18564
+ asChild: true,
18565
+ size: "sm",
18566
+ isActive: selected,
18567
+ label: task.goal,
18568
+ description: [task.agentDefName, preview].filter(Boolean).join(" \xB7 "),
19354
18569
  onClick: () => onSelect(task.id),
19355
- className: `w-full rounded-md border px-3 py-2 text-left text-sm transition-colors ${selected ? "border-primary/40 bg-primary/5" : "border-transparent hover:bg-muted/40"}`,
19356
- children: [
19357
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
19358
- /* @__PURE__ */ jsx(
19359
- "span",
19360
- {
19361
- className: `size-2 shrink-0 rounded-full ${missionTaskStatusDotClass(task.status)}`
19362
- }
19363
- ),
19364
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground/90", children: task.goal })
19365
- ] }),
19366
- /* @__PURE__ */ jsxs("div", { className: "mt-1 flex flex-col gap-2 pl-4", children: [
19367
- task.agentDefName ? /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs font-mono text-muted-foreground", children: task.agentDefName }) : null,
19368
- /* @__PURE__ */ jsx("span", { className: "line-clamp-2 min-w-0 flex-1 text-xs text-muted-foreground/70", children: preview })
19369
- ] })
19370
- ]
18570
+ className: "cursor-pointer",
18571
+ children: /* @__PURE__ */ jsx("button", { type: "button", children: /* @__PURE__ */ jsx(
18572
+ "span",
18573
+ {
18574
+ className: `size-2 shrink-0 rounded-full ${missionTaskStatusDotClass(task.status)}`
18575
+ }
18576
+ ) })
19371
18577
  }
19372
18578
  );
19373
18579
  }
@@ -19396,17 +18602,12 @@ function MissionTasksTab({
19396
18602
  return outputs.length > 0 ? outputs[outputs.length - 1] : null;
19397
18603
  }, [selected, taskEvents]);
19398
18604
  if (tasks.length === 0) {
19399
- return /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No tasks spawned yet." });
18605
+ return /* @__PURE__ */ jsx(EmptyState, { className: "py-8", title: "No tasks spawned yet" });
19400
18606
  }
19401
18607
  return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 gap-4", children: [
19402
18608
  /* @__PURE__ */ jsx("div", { className: "w-72 shrink-0 space-y-4 overflow-y-auto pr-1", children: groups.map((group) => /* @__PURE__ */ jsxs("div", { children: [
19403
- /* @__PURE__ */ jsxs("div", { className: "mb-1 px-1 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: [
19404
- group.label,
19405
- " (",
19406
- group.tasks.length,
19407
- ")"
19408
- ] }),
19409
- /* @__PURE__ */ jsx("div", { className: "space-y-1", children: group.tasks.map((t) => /* @__PURE__ */ jsx(
18609
+ /* @__PURE__ */ jsx(SectionLabel, { label: `${group.label} (${group.tasks.length})` }),
18610
+ /* @__PURE__ */ jsx("div", { className: "space-y-0.5", children: group.tasks.map((t) => /* @__PURE__ */ jsx(
19410
18611
  TaskRailRow,
19411
18612
  {
19412
18613
  task: t,
@@ -19459,14 +18660,7 @@ function TaskDetail({
19459
18660
  /* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[10px] text-muted-foreground/60", children: task.id.slice(0, 8) })
19460
18661
  ] }),
19461
18662
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs", children: [
19462
- /* @__PURE__ */ jsx(
19463
- Badge,
19464
- {
19465
- variant: "destructive",
19466
- className: `font-mono text-sm uppercase tracking-wide ${statusBadgeClass(task.status)}`,
19467
- children: task.status
19468
- }
19469
- ),
18663
+ /* @__PURE__ */ jsx(TonePill, { tone: missionTaskStatusTone(task.status), className: "capitalize", children: task.status }),
19470
18664
  task.agentDefName ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: task.agentDefName }) : null,
19471
18665
  task.attemptCount > 1 ? /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
19472
18666
  "attempts ",
@@ -19482,30 +18676,26 @@ function TaskDetail({
19482
18676
  ] }),
19483
18677
  /* @__PURE__ */ jsx(OutcomeCard, { outcome }),
19484
18678
  parents.length > 0 || children.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
19485
- /* @__PURE__ */ jsx("div", { className: "font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Dependencies" }),
18679
+ /* @__PURE__ */ jsx(SectionLabel, { label: "Dependencies", className: "pl-0" }),
19486
18680
  parents.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
19487
- /* @__PURE__ */ jsx("span", { className: "mr-1 text-[10px] uppercase text-muted-foreground/50", children: "Depends on" }),
18681
+ /* @__PURE__ */ jsx("span", { className: "mr-1 text-[12px] text-subtle", children: "Depends on" }),
19488
18682
  parents.map((p) => /* @__PURE__ */ jsx(TaskChip, { task: p, onSelect }, p.id))
19489
18683
  ] }) : null,
19490
18684
  children.length > 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
19491
- /* @__PURE__ */ jsx("span", { className: "mr-1 text-[10px] uppercase text-muted-foreground/50", children: "Blocks" }),
18685
+ /* @__PURE__ */ jsx("span", { className: "mr-1 text-[12px] text-subtle", children: "Blocks" }),
19492
18686
  children.map((c) => /* @__PURE__ */ jsx(TaskChip, { task: c, onSelect }, c.id))
19493
18687
  ] }) : null
19494
18688
  ] }) : null,
19495
18689
  /* @__PURE__ */ jsxs("div", { children: [
19496
- /* @__PURE__ */ jsx("div", { className: "mb-1 font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Brief" }),
18690
+ /* @__PURE__ */ jsx(SectionLabel, { label: "Brief", className: "mb-1 pl-0" }),
19497
18691
  /* @__PURE__ */ jsx(MessageResponse, { className: "text-sm leading-relaxed text-foreground/90", children: task.goal })
19498
18692
  ] }),
19499
- task.resultMetadata ? /* @__PURE__ */ jsxs("details", { children: [
19500
- /* @__PURE__ */ jsx("summary", { className: "cursor-pointer font-mono text-[10px] uppercase tracking-widest text-muted-foreground/70", children: "Result metadata" }),
19501
- /* @__PURE__ */ jsx("pre", { className: "mt-1 max-h-64 overflow-auto whitespace-pre-wrap rounded bg-muted/30 px-2 py-1.5 text-[11px] text-foreground/90", children: JSON.stringify(task.resultMetadata, null, 2) })
18693
+ task.resultMetadata ? /* @__PURE__ */ jsxs(Collapsible, { className: "rounded-[10px] border border-foreground/[0.08]", children: [
18694
+ /* @__PURE__ */ jsx(CollapsibleHeader, { variant: "section", size: "sm", children: "Result metadata" }),
18695
+ /* @__PURE__ */ jsx(CollapsibleContent, { children: /* @__PURE__ */ jsx("pre", { className: "max-h-64 overflow-auto whitespace-pre-wrap border-t border-foreground/[0.08] px-3 py-2 text-[11px] text-foreground/90", children: JSON.stringify(task.resultMetadata, null, 2) }) })
19502
18696
  ] }) : null,
19503
18697
  eventsSupported && taskEvents.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
19504
- /* @__PURE__ */ jsxs("div", { className: "mb-2 font-mono font-semibold uppercase text-muted-foreground", children: [
19505
- "History (",
19506
- taskEvents.length,
19507
- ")"
19508
- ] }),
18698
+ /* @__PURE__ */ jsx(SectionLabel, { label: `History (${taskEvents.length})`, className: "mb-2 pl-0" }),
19509
18699
  /* @__PURE__ */ jsx("ol", { className: "space-y-3", children: taskEvents.map((e) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-3 text-xs", children: [
19510
18700
  /* @__PURE__ */ jsx("span", { className: "w-16 shrink-0 font-mono text-[10px] text-muted-foreground/60", children: formatMissionTimestamp(e.createdAt) }),
19511
18701
  /* @__PURE__ */ jsxs("div", { className: "", children: [
@@ -19628,11 +18818,6 @@ function OutcomeCard({ outcome }) {
19628
18818
  }
19629
18819
  );
19630
18820
  }
19631
- var MISSION_WORKER_KIND_BADGE_CLASS = {
19632
- task: "border-primary/40 bg-primary/10 text-primary uppercase tracking-wide text-[10px]",
19633
- worker: "border-foreground/30 bg-foreground/5 text-foreground/80 uppercase tracking-wide text-[10px]",
19634
- delegation: "border-foreground/20 bg-foreground/[0.03] text-foreground/60 uppercase tracking-wide text-[10px]"
19635
- };
19636
18821
  var MISSION_WORKER_KIND_TOOLTIP = {
19637
18822
  task: "Durable Task row created by spawn_task. Retried by the dispatcher; survives across coordinator wakes.",
19638
18823
  worker: "Async one-shot session spawned by spawn_worker. Durable session, no retry/DAG.",
@@ -19644,7 +18829,13 @@ function MissionWorkersTab({
19644
18829
  onOpenTranscript
19645
18830
  }) {
19646
18831
  if (workers.length === 0) {
19647
- return /* @__PURE__ */ jsx("div", { className: "py-8 text-center text-sm text-muted-foreground/60", children: "No workers attached to this mission right now." });
18832
+ return /* @__PURE__ */ jsx(
18833
+ EmptyState,
18834
+ {
18835
+ className: "py-8",
18836
+ title: "No workers attached to this mission right now"
18837
+ }
18838
+ );
19648
18839
  }
19649
18840
  return /* @__PURE__ */ jsx("div", { className: "grid gap-3 sm:grid-cols-2", children: workers.map((w) => /* @__PURE__ */ jsx(
19650
18841
  WorkerCard2,
@@ -19674,18 +18865,11 @@ function WorkerCard2({
19674
18865
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
19675
18866
  /* @__PURE__ */ jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: worker.agentDefName ?? "worker" }),
19676
18867
  /* @__PURE__ */ jsxs(Tooltip, { children: [
19677
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
19678
- Badge,
19679
- {
19680
- variant: "outline",
19681
- className: `mt-1 ${MISSION_WORKER_KIND_BADGE_CLASS[worker.kind]}`,
19682
- children: worker.kind
19683
- }
19684
- ) }),
18868
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Chip, { size: "sm", className: "mt-1 capitalize", children: worker.kind }) }),
19685
18869
  /* @__PURE__ */ jsx(TooltipContent, { className: "max-w-xs", children: MISSION_WORKER_KIND_TOOLTIP[worker.kind] })
19686
18870
  ] })
19687
18871
  ] }),
19688
- /* @__PURE__ */ jsx("span", { className: "shrink-0 font-mono text-[10px] uppercase tracking-wider text-muted-foreground/70", children: statusLabel2 })
18872
+ /* @__PURE__ */ jsx(TonePill, { tone: missionTaskStatusTone(statusLabel2), className: "capitalize", children: statusLabel2 })
19689
18873
  ] }),
19690
18874
  counts ? /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-6", children: [
19691
18875
  /* @__PURE__ */ jsxs("div", { children: [
@@ -19710,13 +18894,13 @@ function WorkerCard2({
19710
18894
  ] }),
19711
18895
  /* @__PURE__ */ jsx("div", { className: "truncate text-xs text-foreground/80", children: deriveMissionWorkerActivityLabel(worker) }),
19712
18896
  /* @__PURE__ */ jsx(
19713
- "a",
18897
+ TextLink,
19714
18898
  {
18899
+ size: "sm",
19715
18900
  href: worker.transcriptUrl,
19716
18901
  target: "_blank",
19717
18902
  rel: "noreferrer",
19718
18903
  onClick: onTranscriptClick,
19719
- className: "inline-block text-xs text-primary hover:underline",
19720
18904
  children: "View session"
19721
18905
  }
19722
18906
  )
@@ -19787,8 +18971,15 @@ function useMissionEvents(input) {
19787
18971
  var DEFAULT_POLL_INTERVAL_MS = 5e3;
19788
18972
  function CountBadge({ n }) {
19789
18973
  if (n === 0) return null;
19790
- return /* @__PURE__ */ jsx("span", { className: "ml-1 rounded bg-muted px-1 py-px text-[9px] text-muted-foreground/70", children: n });
19791
- }
18974
+ return /* @__PURE__ */ jsx(Badge, { variant: "secondary", children: n });
18975
+ }
18976
+ var MISSION_STATUS_TONE = {
18977
+ active: "warn",
18978
+ paused: "warn",
18979
+ satisfied: "ok",
18980
+ failed: "bad",
18981
+ cancelled: "bad"
18982
+ };
19792
18983
  var INITIAL_STATE = {
19793
18984
  mission: null,
19794
18985
  tasks: [],
@@ -19948,7 +19139,6 @@ function MissionDashboard({
19948
19139
  setBusy(false);
19949
19140
  }
19950
19141
  };
19951
- const statusTone = mission.status === "satisfied" ? "border-emerald-500/40 bg-emerald-500/10 text-emerald-700 dark:text-emerald-400" : mission.status === "failed" || mission.status === "cancelled" ? "border-destructive/40 bg-destructive/10 text-destructive" : mission.status === "paused" ? "border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-400" : "border-primary/40 bg-primary/10 text-primary";
19952
19142
  const isActive = ACTIVE_MISSION_STATUSES.has(mission.status);
19953
19143
  const iterationPct = mission.maxIterations > 0 ? Math.min(100, mission.iteration / mission.maxIterations * 100) : 0;
19954
19144
  return /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 300, children: /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-1 flex-col overflow-hidden bg-muted/30", children: [
@@ -19956,9 +19146,10 @@ function MissionDashboard({
19956
19146
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-start justify-between gap-3", children: [
19957
19147
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
19958
19148
  /* @__PURE__ */ jsx(
19959
- "span",
19149
+ TonePill,
19960
19150
  {
19961
- className: `rounded-md border px-2 py-0.5 font-mono text-[10px] font-semibold uppercase tracking-wider ${statusTone}`,
19151
+ tone: MISSION_STATUS_TONE[mission.status] ?? "muted",
19152
+ className: "capitalize",
19962
19153
  children: mission.status
19963
19154
  }
19964
19155
  ),
@@ -19970,9 +19161,9 @@ function MissionDashboard({
19970
19161
  ] }),
19971
19162
  /* @__PURE__ */ jsx("span", { className: "ml-1 text-[10px] uppercase tracking-wider text-muted-foreground/60", children: "iterations" })
19972
19163
  ] }),
19973
- mission.lastEvaluationResult ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-[11px] text-muted-foreground/70", children: [
19974
- /* @__PURE__ */ jsx("span", { className: "opacity-70", children: "last verdict" }),
19975
- /* @__PURE__ */ jsx("span", { className: "rounded border border-primary/30 bg-primary/10 px-1.5 py-0.5 font-mono text-[10px] uppercase tracking-wider text-primary", children: mission.lastEvaluationResult })
19164
+ mission.lastEvaluationResult ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-[12px] text-muted-foreground", children: [
19165
+ /* @__PURE__ */ jsx("span", { children: "Last verdict" }),
19166
+ /* @__PURE__ */ jsx(TonePill, { tone: missionVerdictTone(mission.lastEvaluationResult), children: mission.lastEvaluationResult })
19976
19167
  ] }) : null
19977
19168
  ] }),
19978
19169
  /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-wrap items-center gap-2", children: [
@@ -20034,10 +19225,10 @@ function MissionDashboard({
20034
19225
  ] })
20035
19226
  ] }),
20036
19227
  /* @__PURE__ */ jsx(
20037
- Progress,
19228
+ ProgressBar,
20038
19229
  {
20039
19230
  value: iterationPct,
20040
- className: `h-1 ${isActive ? "" : "opacity-40"}`
19231
+ className: isActive ? void 0 : "opacity-40"
20041
19232
  }
20042
19233
  ),
20043
19234
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
@@ -20115,11 +19306,10 @@ function MissionDashboard({
20115
19306
  ] }),
20116
19307
  /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
20117
19308
  /* @__PURE__ */ jsx(
20118
- "input",
19309
+ Checkbox,
20119
19310
  {
20120
- type: "checkbox",
20121
19311
  checked: cancelCascade,
20122
- onChange: (e) => setCancelCascade(e.target.checked)
19312
+ onCheckedChange: (checked) => setCancelCascade(checked === true)
20123
19313
  }
20124
19314
  ),
20125
19315
  /* @__PURE__ */ jsxs("span", { children: [
@@ -20174,6 +19364,12 @@ function sortMissions(items) {
20174
19364
  return (a.updatedAt ?? "") > (b.updatedAt ?? "") ? -1 : 1;
20175
19365
  });
20176
19366
  }
19367
+ function missionTone(status) {
19368
+ if (status === "active") return "ok";
19369
+ if (status === "paused" || status === "blocked") return "warn";
19370
+ if (status === "failed" || status === "max_iterations_reached") return "bad";
19371
+ return "muted";
19372
+ }
20177
19373
  function MissionRow({
20178
19374
  mission,
20179
19375
  onOpen,
@@ -20204,81 +19400,79 @@ function MissionRow({
20204
19400
  e.preventDefault();
20205
19401
  openMission();
20206
19402
  };
20207
- return /* @__PURE__ */ jsxs(
20208
- "div",
19403
+ return /* @__PURE__ */ jsx(
19404
+ ListRow,
20209
19405
  {
20210
- className: cn(
20211
- "group flex min-w-0 items-start gap-2 border-l-2 border-l-transparent px-3 py-2 text-sm transition-colors cursor-pointer hover:border-l-primary hover:bg-input",
20212
- "min-h-11 md:min-h-0"
20213
- ),
20214
- onClick: openMission,
20215
- onKeyDown: handleRowKeyDown,
20216
- role: "button",
20217
- tabIndex: 0,
20218
- "aria-label": `Open mission ${description}`,
20219
- title: "Open mission dashboard",
20220
- children: [
20221
- /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex size-5 shrink-0 items-center justify-center text-faint", children: /* @__PURE__ */ jsx(TargetIcon, { className: "size-3.5" }) }),
20222
- /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx("div", { className: "flex min-w-0 items-start gap-2", children: /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
20223
- /* @__PURE__ */ jsx("div", { className: "truncate text-foreground", children: description }),
20224
- /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex min-w-0 items-center gap-2", children: /* @__PURE__ */ jsx(
20225
- Badge,
20226
- {
20227
- variant: isActive ? "default" : "secondary",
20228
- className: "shrink-0",
20229
- children: mission.status
20230
- }
20231
- ) }),
20232
- meta.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-0.5 space-y-0.5 text-xs text-faint", children: meta.map((line) => /* @__PURE__ */ jsx("div", { className: "truncate", children: line }, line)) })
20233
- ] }) }) }),
20234
- /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
20235
- isActive && canMutate.pause && /* @__PURE__ */ jsx(
20236
- "button",
20237
- {
20238
- type: "button",
20239
- className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-line hover:text-foreground disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
20240
- onClick: (e) => {
20241
- stopActionClick(e);
20242
- onPause(mission.id);
20243
- },
20244
- "aria-label": "Pause mission",
20245
- title: "Pause mission",
20246
- disabled: busy,
20247
- children: /* @__PURE__ */ jsx(Pause, { className: "size-3.5" })
20248
- }
20249
- ),
20250
- isPaused && canMutate.resume && /* @__PURE__ */ jsx(
20251
- "button",
20252
- {
20253
- type: "button",
20254
- className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-line hover:text-foreground disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
20255
- onClick: (e) => {
20256
- stopActionClick(e);
20257
- onResume(mission.id);
20258
- },
20259
- "aria-label": "Resume mission",
20260
- title: "Resume mission",
20261
- disabled: busy,
20262
- children: /* @__PURE__ */ jsx(Play, { className: "size-3.5" })
20263
- }
20264
- ),
20265
- (isActive || isPaused) && canMutate.cancel && /* @__PURE__ */ jsx(
20266
- "button",
20267
- {
20268
- type: "button",
20269
- className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
20270
- onClick: (e) => {
20271
- stopActionClick(e);
20272
- onCancel(mission.id);
20273
- },
20274
- "aria-label": "Cancel mission",
20275
- title: "Cancel mission",
20276
- disabled: busy,
20277
- children: /* @__PURE__ */ jsx(Ban, { className: "size-3.5" })
20278
- }
20279
- )
20280
- ] })
20281
- ]
19406
+ asChild: true,
19407
+ size: "sm",
19408
+ icon: TargetIcon,
19409
+ label: description,
19410
+ description: /* @__PURE__ */ jsxs(Fragment, { children: [
19411
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5 flex", children: /* @__PURE__ */ jsx(TonePill, { tone: missionTone(mission.status), children: mission.status }) }),
19412
+ meta.map((line) => /* @__PURE__ */ jsx("span", { className: "mt-0.5 block truncate", children: line }, line))
19413
+ ] }),
19414
+ className: "cursor-pointer items-start",
19415
+ trailing: /* @__PURE__ */ jsxs(Fragment, { children: [
19416
+ isActive && canMutate.pause && /* @__PURE__ */ jsx(
19417
+ Button,
19418
+ {
19419
+ variant: "ghost",
19420
+ size: "icon-xs",
19421
+ className: "text-muted-foreground hover:text-foreground md:opacity-70 md:group-hover/list-row:opacity-100",
19422
+ onClick: (e) => {
19423
+ stopActionClick(e);
19424
+ onPause(mission.id);
19425
+ },
19426
+ "aria-label": "Pause mission",
19427
+ title: "Pause mission",
19428
+ disabled: busy,
19429
+ children: /* @__PURE__ */ jsx(Pause, { className: "size-3.5" })
19430
+ }
19431
+ ),
19432
+ isPaused && canMutate.resume && /* @__PURE__ */ jsx(
19433
+ Button,
19434
+ {
19435
+ variant: "ghost",
19436
+ size: "icon-xs",
19437
+ className: "text-muted-foreground hover:text-foreground md:opacity-70 md:group-hover/list-row:opacity-100",
19438
+ onClick: (e) => {
19439
+ stopActionClick(e);
19440
+ onResume(mission.id);
19441
+ },
19442
+ "aria-label": "Resume mission",
19443
+ title: "Resume mission",
19444
+ disabled: busy,
19445
+ children: /* @__PURE__ */ jsx(Play, { className: "size-3.5" })
19446
+ }
19447
+ ),
19448
+ (isActive || isPaused) && canMutate.cancel && /* @__PURE__ */ jsx(
19449
+ Button,
19450
+ {
19451
+ variant: "ghost",
19452
+ size: "icon-xs",
19453
+ className: "text-muted-foreground hover:bg-destructive/10 hover:text-destructive md:opacity-70 md:group-hover/list-row:opacity-100",
19454
+ onClick: (e) => {
19455
+ stopActionClick(e);
19456
+ onCancel(mission.id);
19457
+ },
19458
+ "aria-label": "Cancel mission",
19459
+ title: "Cancel mission",
19460
+ disabled: busy,
19461
+ children: /* @__PURE__ */ jsx(Ban, { className: "size-3.5" })
19462
+ }
19463
+ )
19464
+ ] }),
19465
+ children: /* @__PURE__ */ jsx(
19466
+ "div",
19467
+ {
19468
+ onClick: openMission,
19469
+ onKeyDown: handleRowKeyDown,
19470
+ role: "button",
19471
+ tabIndex: 0,
19472
+ "aria-label": `Open mission ${description}`,
19473
+ title: "Open mission dashboard"
19474
+ }
19475
+ )
20282
19476
  }
20283
19477
  );
20284
19478
  }
@@ -20298,7 +19492,6 @@ function MissionsPanel({
20298
19492
  const [error, setError] = useState(null);
20299
19493
  const [hasEverLoaded, setHasEverLoaded] = useState(false);
20300
19494
  const [busyMissionId, setBusyMissionId] = useState(null);
20301
- const [collapsed, setCollapsed] = useState(false);
20302
19495
  const mounted = useRef(true);
20303
19496
  const requestId = useRef(0);
20304
19497
  const lastFingerprint = useRef("");
@@ -20416,44 +19609,31 @@ function MissionsPanel({
20416
19609
  );
20417
19610
  if (!hasEverLoaded) return null;
20418
19611
  if (!adapter.listMissions) return null;
20419
- const showBody = hideHeader || !collapsed;
20420
19612
  const canMutate = {
20421
19613
  pause: Boolean(adapter.pauseMission),
20422
19614
  resume: Boolean(adapter.resumeMission),
20423
19615
  cancel: Boolean(adapter.cancelMission)
20424
19616
  };
20425
- return /* @__PURE__ */ jsxs("section", { className: "min-w-0 border-t border-line", children: [
20426
- !hideHeader && /* @__PURE__ */ jsxs(
20427
- "button",
20428
- {
20429
- type: "button",
20430
- className: "flex w-full items-center gap-1.5 px-3 py-2 text-left text-xs font-semibold uppercase tracking-wide text-foreground transition-colors hover:bg-input",
20431
- onClick: () => setCollapsed((c) => !c),
20432
- "aria-expanded": !collapsed,
20433
- children: [
20434
- /* @__PURE__ */ jsx(TargetIcon, { className: "size-3.5" }),
20435
- /* @__PURE__ */ jsx("span", { className: "truncate", children: title }),
20436
- activeCount > 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", className: "ml-auto", children: activeCount }),
20437
- collapsed ? /* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-3.5 shrink-0 text-faint" }) : /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-3.5 shrink-0 text-faint" })
20438
- ]
20439
- }
20440
- ),
20441
- showBody && error && /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-destructive", children: error }),
20442
- showBody && !error && items.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-faint", children: "No missions" }),
20443
- showBody && !error && items.length > 0 && /* @__PURE__ */ jsx("div", { className: cn("pb-2", hideHeader && "pt-1"), children: items.map((mission) => /* @__PURE__ */ jsx(
20444
- MissionRow,
20445
- {
20446
- mission,
20447
- busy: busyMissionId === mission.id,
20448
- canMutate,
20449
- onOpen: handleOpen,
20450
- onPause: handlePause,
20451
- onResume: handleResume,
20452
- onCancel: handleCancel
20453
- },
20454
- mission.id
20455
- )) })
20456
- ] });
19617
+ const body = error ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs text-destructive", children: error }) : items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs text-faint", children: "No missions" }) : /* @__PURE__ */ jsx("div", { children: items.map((mission) => /* @__PURE__ */ jsx(
19618
+ MissionRow,
19619
+ {
19620
+ mission,
19621
+ busy: busyMissionId === mission.id,
19622
+ canMutate,
19623
+ onOpen: handleOpen,
19624
+ onPause: handlePause,
19625
+ onResume: handleResume,
19626
+ onCancel: handleCancel
19627
+ },
19628
+ mission.id
19629
+ )) });
19630
+ return /* @__PURE__ */ jsx("section", { className: "min-w-0 border-t border-line p-1", children: hideHeader ? body : /* @__PURE__ */ jsxs(Collapsible, { defaultOpen: true, children: [
19631
+ /* @__PURE__ */ jsxs(CollapsibleHeader, { icon: TargetIcon, children: [
19632
+ title,
19633
+ activeCount > 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", className: "ml-1.5", children: activeCount })
19634
+ ] }),
19635
+ /* @__PURE__ */ jsx(CollapsibleContent, { children: body })
19636
+ ] }) });
20457
19637
  }
20458
19638
  var CITATION_RE = /\[(S\d+(?:\s*,\s*S\d+)*)\]/g;
20459
19639
  function splitCitations(text) {
@@ -20486,17 +19666,15 @@ function CitationText({
20486
19666
  return /* @__PURE__ */ jsx("span", { children: seg.value }, i);
20487
19667
  }
20488
19668
  const src = byId.get(seg.value);
20489
- return /* @__PURE__ */ jsx(
19669
+ return /* @__PURE__ */ jsx(Badge, { asChild: true, className: "mx-0.5 cursor-pointer hover:bg-foreground/[0.12]", children: /* @__PURE__ */ jsx(
20490
19670
  "button",
20491
19671
  {
20492
19672
  type: "button",
20493
19673
  title: src ? `${src.title} \u2014 ${src.url}` : seg.value,
20494
19674
  onClick: () => onCitationClick?.(seg.value),
20495
- className: "mx-0.5 inline-flex items-center rounded-sm bg-muted px-1 text-[10px] font-semibold text-primary hover:bg-primary/10",
20496
19675
  children: seg.value
20497
- },
20498
- i
20499
- );
19676
+ }
19677
+ ) }, i);
20500
19678
  }) });
20501
19679
  }
20502
19680
  var DEFAULT_LIMIT2 = 50;
@@ -20536,6 +19714,11 @@ function scheduleDisplay(item) {
20536
19714
  if (item.kind === "dynamic_loop") return null;
20537
19715
  return item.scheduleDisplay;
20538
19716
  }
19717
+ function statusTone(status) {
19718
+ if (status === "paused") return "warn";
19719
+ if (status === "failed") return "bad";
19720
+ return "muted";
19721
+ }
20539
19722
  function sortScheduledWork(items) {
20540
19723
  return [...items].sort((a, b) => {
20541
19724
  if (a.status === "active" && b.status !== "active") return -1;
@@ -20582,73 +19765,74 @@ function ScheduledWorkRow({
20582
19765
  const stopActionClick = (e) => {
20583
19766
  e.stopPropagation();
20584
19767
  };
20585
- return /* @__PURE__ */ jsxs(
20586
- "div",
19768
+ return /* @__PURE__ */ jsx(
19769
+ ListRow,
20587
19770
  {
20588
- className: cn(
20589
- "group flex min-w-0 items-start gap-2 border-l-2 border-l-transparent px-3 py-2 text-sm transition-colors hover:border-l-primary hover:bg-input",
20590
- "min-h-11 md:min-h-0",
20591
- lastSessionId && "cursor-pointer"
20592
- ),
20593
- onClick: openLastRun,
20594
- onKeyDown: handleRowKeyDown,
20595
- role: lastSessionId ? "button" : void 0,
20596
- tabIndex: lastSessionId ? 0 : void 0,
20597
- "aria-label": lastSessionId ? `Open last run for ${title}` : void 0,
20598
- title: lastSessionId ? "Open last run" : void 0,
20599
- children: [
20600
- /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex size-5 shrink-0 items-center justify-center text-faint", children: /* @__PURE__ */ jsx(CalendarClockIcon, { className: "size-3.5" }) }),
20601
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
20602
- /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [
20603
- /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
20604
- /* @__PURE__ */ jsx("div", { className: "truncate text-foreground", children: title }),
20605
- /* @__PURE__ */ jsx("div", { className: "mt-0.5 flex min-w-0 items-center gap-2", children: /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0", children: formatKind(item.kind) }) }),
20606
- meta.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-0.5 space-y-0.5 text-xs text-faint", children: meta.map((line) => /* @__PURE__ */ jsx("div", { className: "truncate", children: line }, line)) })
20607
- ] }),
20608
- statusText && /* @__PURE__ */ jsx(Badge, { variant: "destructive", className: "shrink-0", children: statusText })
20609
- ] }),
20610
- item.lastError && /* @__PURE__ */ jsx("div", { className: "mt-1 line-clamp-2 text-xs text-destructive", children: item.lastError })
19771
+ asChild: true,
19772
+ size: "sm",
19773
+ icon: CalendarClockIcon,
19774
+ label: title,
19775
+ description: /* @__PURE__ */ jsxs(Fragment, { children: [
19776
+ /* @__PURE__ */ jsxs("span", { className: "mt-0.5 flex gap-1", children: [
19777
+ /* @__PURE__ */ jsx(TonePill, { children: formatKind(item.kind) }),
19778
+ statusText && /* @__PURE__ */ jsx(TonePill, { tone: statusTone(statusText), children: statusText })
20611
19779
  ] }),
20612
- /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [
20613
- showRunNow && /* @__PURE__ */ jsx(
20614
- "button",
20615
- {
20616
- type: "button",
20617
- className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-line hover:text-foreground disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
20618
- onClick: (e) => {
20619
- stopActionClick(e);
20620
- onRunNow(item.id);
20621
- },
20622
- "aria-label": "Run schedule now",
20623
- title: "Run schedule now",
20624
- disabled,
20625
- children: /* @__PURE__ */ jsx(CalendarClockIcon, { className: "size-3.5" })
20626
- }
20627
- ),
20628
- canCancel && isActive && /* @__PURE__ */ jsx(
20629
- "button",
20630
- {
20631
- type: "button",
20632
- className: "rounded p-2 md:p-1 text-faint opacity-100 md:opacity-70 transition-all hover:bg-destructive/10 hover:text-destructive disabled:pointer-events-none disabled:opacity-40 md:group-hover:opacity-100",
20633
- onClick: (e) => {
20634
- stopActionClick(e);
20635
- onCancel(item.id);
20636
- },
20637
- "aria-label": "Cancel schedule",
20638
- title: "Cancel schedule",
20639
- disabled,
20640
- children: /* @__PURE__ */ jsx(Trash2Icon, { className: "size-3.5" })
20641
- }
20642
- )
20643
- ] })
20644
- ]
19780
+ meta.map((line) => /* @__PURE__ */ jsx("span", { className: "mt-0.5 block truncate", children: line }, line)),
19781
+ item.lastError && /* @__PURE__ */ jsx("span", { className: "mt-1 line-clamp-2 whitespace-normal text-destructive", children: item.lastError })
19782
+ ] }),
19783
+ className: cn("items-start", lastSessionId && "cursor-pointer"),
19784
+ trailing: /* @__PURE__ */ jsxs(Fragment, { children: [
19785
+ showRunNow && /* @__PURE__ */ jsx(
19786
+ Button,
19787
+ {
19788
+ variant: "ghost",
19789
+ size: "icon-xs",
19790
+ className: "text-muted-foreground hover:text-foreground md:opacity-70 md:group-hover/list-row:opacity-100",
19791
+ onClick: (e) => {
19792
+ stopActionClick(e);
19793
+ onRunNow(item.id);
19794
+ },
19795
+ "aria-label": "Run schedule now",
19796
+ title: "Run schedule now",
19797
+ disabled,
19798
+ children: /* @__PURE__ */ jsx(CalendarClockIcon, { className: "size-3.5" })
19799
+ }
19800
+ ),
19801
+ canCancel && isActive && /* @__PURE__ */ jsx(
19802
+ Button,
19803
+ {
19804
+ variant: "ghost",
19805
+ size: "icon-xs",
19806
+ className: "text-muted-foreground hover:bg-destructive/10 hover:text-destructive md:opacity-70 md:group-hover/list-row:opacity-100",
19807
+ onClick: (e) => {
19808
+ stopActionClick(e);
19809
+ onCancel(item.id);
19810
+ },
19811
+ "aria-label": "Cancel schedule",
19812
+ title: "Cancel schedule",
19813
+ disabled,
19814
+ children: /* @__PURE__ */ jsx(Trash2Icon, { className: "size-3.5" })
19815
+ }
19816
+ )
19817
+ ] }),
19818
+ children: /* @__PURE__ */ jsx(
19819
+ "div",
19820
+ {
19821
+ onClick: openLastRun,
19822
+ onKeyDown: handleRowKeyDown,
19823
+ role: lastSessionId ? "button" : void 0,
19824
+ tabIndex: lastSessionId ? 0 : void 0,
19825
+ "aria-label": lastSessionId ? `Open last run for ${title}` : void 0,
19826
+ title: lastSessionId ? "Open last run" : void 0
19827
+ }
19828
+ )
20645
19829
  }
20646
19830
  );
20647
19831
  }
20648
19832
  function ScheduledWorkPanel({
20649
19833
  adapter,
20650
19834
  agentId,
20651
- title = "Scheduled Work",
19835
+ title = "Scheduled work",
20652
19836
  limit = DEFAULT_LIMIT2,
20653
19837
  status = "active",
20654
19838
  hideHeader = false,
@@ -20661,7 +19845,6 @@ function ScheduledWorkPanel({
20661
19845
  const [error, setError] = useState(null);
20662
19846
  const [hasEverLoaded, setHasEverLoaded] = useState(false);
20663
19847
  const [actionScheduleId, setActionScheduleId] = useState(null);
20664
- const [collapsed, setCollapsed] = useState(false);
20665
19848
  const mounted = useRef(true);
20666
19849
  const requestId = useRef(0);
20667
19850
  const lastFingerprint = useRef("");
@@ -20767,39 +19950,26 @@ function ScheduledWorkPanel({
20767
19950
  );
20768
19951
  if (!hasEverLoaded) return null;
20769
19952
  if (!adapter.listScheduledWork) return null;
20770
- const showBody = hideHeader || !collapsed;
20771
- return /* @__PURE__ */ jsxs("section", { className: "min-w-0 border-t border-line", children: [
20772
- !hideHeader && /* @__PURE__ */ jsxs(
20773
- "button",
20774
- {
20775
- type: "button",
20776
- className: "flex w-full items-center gap-1.5 px-3 py-2 text-left text-xs font-semibold uppercase tracking-wide text-foreground transition-colors hover:bg-input",
20777
- onClick: () => setCollapsed((current) => !current),
20778
- "aria-expanded": !collapsed,
20779
- children: [
20780
- /* @__PURE__ */ jsx(CalendarClockIcon, { className: "size-3.5" }),
20781
- /* @__PURE__ */ jsx("span", { className: "truncate", children: title }),
20782
- activeCount > 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", className: "ml-auto", children: activeCount }),
20783
- collapsed ? /* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-3.5 shrink-0 text-faint" }) : /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-3.5 shrink-0 text-faint" })
20784
- ]
20785
- }
20786
- ),
20787
- showBody && error && /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-destructive", children: error }),
20788
- showBody && !error && items.length === 0 && /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-faint", children: "No scheduled work" }),
20789
- showBody && !error && items.length > 0 && /* @__PURE__ */ jsx("div", { className: cn("pb-2", hideHeader && "pt-1"), children: items.map((item) => /* @__PURE__ */ jsx(
20790
- ScheduledWorkRow,
20791
- {
20792
- item,
20793
- canRunNow: Boolean(adapter.runScheduledWorkNow),
20794
- canCancel: Boolean(adapter.cancelScheduledWork),
20795
- actionScheduleId,
20796
- onOpenLastRun: handleOpenLastRun,
20797
- onRunNow: handleRunNow,
20798
- onCancel: handleCancel
20799
- },
20800
- item.id
20801
- )) })
20802
- ] });
19953
+ const body = error ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs text-destructive", children: error }) : items.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-xs text-faint", children: "No scheduled work" }) : /* @__PURE__ */ jsx("div", { children: items.map((item) => /* @__PURE__ */ jsx(
19954
+ ScheduledWorkRow,
19955
+ {
19956
+ item,
19957
+ canRunNow: Boolean(adapter.runScheduledWorkNow),
19958
+ canCancel: Boolean(adapter.cancelScheduledWork),
19959
+ actionScheduleId,
19960
+ onOpenLastRun: handleOpenLastRun,
19961
+ onRunNow: handleRunNow,
19962
+ onCancel: handleCancel
19963
+ },
19964
+ item.id
19965
+ )) });
19966
+ return /* @__PURE__ */ jsx("section", { className: "min-w-0 border-t border-line p-1", children: hideHeader ? body : /* @__PURE__ */ jsxs(Collapsible, { defaultOpen: true, children: [
19967
+ /* @__PURE__ */ jsxs(CollapsibleHeader, { icon: CalendarClockIcon, children: [
19968
+ title,
19969
+ activeCount > 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", className: "ml-1.5", children: activeCount })
19970
+ ] }),
19971
+ /* @__PURE__ */ jsx(CollapsibleContent, { children: body })
19972
+ ] }) });
20803
19973
  }
20804
19974
  var POLL_INTERVAL_ACTIVE_MS = 4e3;
20805
19975
  var POLL_INTERVAL_IDLE_MS = 3e4;
@@ -20903,15 +20073,6 @@ function fallbackSessionTitle(entry) {
20903
20073
  if (entry.runKind === "scheduled") return "Scheduled run";
20904
20074
  return "New session";
20905
20075
  }
20906
- function rowStateClass(isActive, isInActiveGroup) {
20907
- if (isActive) {
20908
- return "bg-faint/30 dark:bg-[#1e2840] text-foreground border-l-primary";
20909
- }
20910
- if (isInActiveGroup) {
20911
- return "bg-line/70 dark:bg-line/60 text-foreground/80 hover:bg-input hover:text-foreground border-l-transparent";
20912
- }
20913
- return "bg-transparent text-foreground/80 hover:bg-input hover:text-foreground border-l-transparent";
20914
- }
20915
20076
  function TreeNodeRow({
20916
20077
  entry,
20917
20078
  depth,
@@ -20938,77 +20099,85 @@ function TreeNodeRow({
20938
20099
  if (hasChildren) setExpanded(isInActiveGroup);
20939
20100
  }, [isInActiveGroup, hasChildren]);
20940
20101
  return /* @__PURE__ */ jsxs(Fragment, { children: [
20941
- /* @__PURE__ */ jsxs(
20942
- "div",
20102
+ /* @__PURE__ */ jsx(
20103
+ ListRow,
20943
20104
  {
20944
- role: "button",
20945
- tabIndex: 0,
20946
- onClick: () => onSelect(entry.id),
20947
- onKeyDown: (e) => {
20948
- if (e.key === "Enter" || e.key === " ") onSelect(entry.id);
20949
- },
20105
+ asChild: true,
20106
+ size: "sm",
20107
+ label: title,
20108
+ description: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1", children: [
20109
+ entry.computer && // A chat on a folder of the user's computer, in every list of chats, the browser's too.
20110
+ /* @__PURE__ */ jsxs("span", { "data-testid": "session-computer", title: `On ${entry.computer}`, className: "inline-flex min-w-0 max-w-[50%] items-center gap-1", children: [
20111
+ /* @__PURE__ */ jsx(LaptopIcon, { className: "w-3 h-3 shrink-0", "aria-hidden": "true" }),
20112
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: entry.computer })
20113
+ ] }),
20114
+ entry.computer && subtitle && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }),
20115
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: subtitle })
20116
+ ] }),
20117
+ isActive,
20950
20118
  className: cn(
20951
- "group flex items-center gap-2 w-full py-2 pr-2 text-left cursor-pointer transition-colors border-l-2",
20952
- "min-h-11 md:min-h-0",
20953
- rowStateClass(isActive, isInActiveGroup)
20119
+ "cursor-pointer",
20120
+ !isActive && isInActiveGroup && "bg-foreground/[0.03]"
20954
20121
  ),
20955
20122
  style: { paddingLeft: `${depth * 12 + 12}px` },
20956
- children: [
20957
- hasChildren ? /* @__PURE__ */ jsx(
20958
- "button",
20959
- {
20960
- type: "button",
20961
- className: "p-2 md:p-0.5 rounded hover:bg-line shrink-0",
20962
- onClick: (e) => {
20963
- e.stopPropagation();
20964
- setExpanded(!expanded);
20965
- },
20966
- "aria-label": expanded ? "Collapse" : "Expand",
20967
- "aria-expanded": expanded,
20968
- children: expanded ? /* @__PURE__ */ jsx(ChevronDownIcon, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-3.5 h-3.5" })
20969
- }
20970
- ) : /* @__PURE__ */ jsx("span", { className: "w-4 h-4 shrink-0" }),
20971
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
20972
- /* @__PURE__ */ jsx("div", { className: "text-sm truncate", children: title }),
20973
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 text-xs text-faint min-w-0", children: [
20974
- entry.computer && // A chat on a folder of the user's computer, in every list of chats, the browser's too.
20975
- /* @__PURE__ */ jsxs("span", { "data-testid": "session-computer", title: `On ${entry.computer}`, className: "inline-flex min-w-0 max-w-[50%] items-center gap-1", children: [
20976
- /* @__PURE__ */ jsx(LaptopIcon, { className: "w-3 h-3 shrink-0", "aria-hidden": "true" }),
20977
- /* @__PURE__ */ jsx("span", { className: "truncate", children: entry.computer })
20978
- ] }),
20979
- entry.computer && subtitle && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xB7" }),
20980
- /* @__PURE__ */ jsx("span", { className: "truncate", children: subtitle })
20981
- ] })
20982
- ] }),
20123
+ trailing: /* @__PURE__ */ jsxs(Fragment, { children: [
20983
20124
  isRunning && canStop && isChildSession && /* @__PURE__ */ jsx(
20984
- "button",
20125
+ Button,
20985
20126
  {
20986
- type: "button",
20987
- className: "p-2 md:p-1 rounded opacity-100 md:opacity-0 md:group-hover:opacity-100 hover:bg-destructive/10 hover:text-destructive transition-all",
20127
+ variant: "ghost",
20128
+ size: "icon-xs",
20129
+ className: "text-muted-foreground hover:bg-destructive/10 hover:text-destructive md:opacity-0 md:group-hover/list-row:opacity-100 md:focus-visible:opacity-100",
20988
20130
  onClick: (e) => {
20989
20131
  e.stopPropagation();
20990
20132
  onStop(entry.id);
20991
20133
  },
20992
20134
  "aria-label": "Stop child session",
20993
20135
  title: "Stop child session",
20994
- children: /* @__PURE__ */ jsx(SquareIcon, { className: "w-3 h-3", fill: "currentColor" })
20136
+ children: /* @__PURE__ */ jsx(SquareIcon, { fill: "currentColor" })
20995
20137
  }
20996
20138
  ),
20997
20139
  canDelete && /* @__PURE__ */ jsx(
20998
- "button",
20140
+ Button,
20999
20141
  {
21000
- type: "button",
21001
- className: "p-2 md:p-1 rounded opacity-60 md:opacity-50 md:group-hover:opacity-100 md:focus-visible:opacity-100 hover:bg-destructive/10 hover:text-destructive transition-all",
20142
+ variant: "ghost",
20143
+ size: "icon-xs",
20144
+ className: "text-muted-foreground opacity-60 hover:bg-destructive/10 hover:text-destructive md:opacity-50 md:group-hover/list-row:opacity-100 md:focus-visible:opacity-100",
21002
20145
  onClick: (e) => {
21003
20146
  e.stopPropagation();
21004
20147
  onDelete(entry.id);
21005
20148
  },
21006
20149
  "aria-label": "Delete session",
21007
20150
  title: "Delete session",
21008
- children: /* @__PURE__ */ jsx(Trash2Icon, { className: "w-3 h-3" })
20151
+ children: /* @__PURE__ */ jsx(Trash2Icon, {})
21009
20152
  }
21010
20153
  )
21011
- ]
20154
+ ] }),
20155
+ children: /* @__PURE__ */ jsx(
20156
+ "div",
20157
+ {
20158
+ role: "button",
20159
+ tabIndex: 0,
20160
+ onClick: () => onSelect(entry.id),
20161
+ onKeyDown: (e) => {
20162
+ if (e.key === "Enter" || e.key === " ") onSelect(entry.id);
20163
+ },
20164
+ children: hasChildren ? /* @__PURE__ */ jsx(
20165
+ Button,
20166
+ {
20167
+ variant: "ghost",
20168
+ size: "icon-xs",
20169
+ className: "size-5",
20170
+ onClick: (e) => {
20171
+ e.stopPropagation();
20172
+ setExpanded(!expanded);
20173
+ },
20174
+ "aria-label": expanded ? "Collapse" : "Expand",
20175
+ "aria-expanded": expanded,
20176
+ children: expanded ? /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-3.5" }) : /* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-3.5" })
20177
+ }
20178
+ ) : /* @__PURE__ */ jsx("span", { className: "size-5 shrink-0" })
20179
+ }
20180
+ )
21012
20181
  }
21013
20182
  ),
21014
20183
  hasChildren && expanded && entry.children.map((child) => /* @__PURE__ */ jsx(
@@ -21206,11 +20375,15 @@ function SessionTreePanel({
21206
20375
  const topLevel = hideRoot ? roots.flatMap((r) => r.children) : roots;
21207
20376
  if (topLevel.length === 0) return null;
21208
20377
  return /* @__PURE__ */ jsxs(Fragment, { children: [
21209
- !hideHeader && /* @__PURE__ */ jsxs("div", { className: "border-t border-line flex items-center gap-1.5 px-3 py-2 text-xs font-semibold uppercase tracking-wide", children: [
21210
- /* @__PURE__ */ jsx(UsersIcon, { className: "w-3.5 h-3.5" }),
21211
- /* @__PURE__ */ jsx("span", { children: title }),
21212
- runningCount > 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", className: "h-4 px-1.5 text-[10px] ml-auto", children: runningCount })
21213
- ] }),
20378
+ !hideHeader && /* @__PURE__ */ jsx(
20379
+ SectionLabel,
20380
+ {
20381
+ label: /* @__PURE__ */ jsxs(Fragment, { children: [
20382
+ title,
20383
+ runningCount > 0 && /* @__PURE__ */ jsx(Badge, { variant: "default", className: "ml-1.5", children: runningCount })
20384
+ ] })
20385
+ }
20386
+ ),
21214
20387
  error && /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-xs text-destructive", children: error }),
21215
20388
  !error && /* @__PURE__ */ jsx("div", { className: "px-1 pb-2", children: topLevel.map((entry) => /* @__PURE__ */ jsx(
21216
20389
  TreeNodeRow,