@tangle-network/agent-app 0.43.1 → 0.43.3

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.
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-E7QYOOON.js";
8
8
 
9
9
  // src/web-react/index.tsx
10
- import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef4, useState as useState7, memo } from "react";
10
+ import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef4, useState as useState6, memo } from "react";
11
11
 
12
12
  // src/web-react/smooth-text.ts
13
13
  import { useEffect, useRef, useState } from "react";
@@ -490,11 +490,35 @@ async function streamChatTurn(opts) {
490
490
  }
491
491
 
492
492
  // src/web-react/chat-composer.tsx
493
- import { useCallback, useState as useState3 } from "react";
494
493
  import {
495
- AgentComposer
496
- } from "@tangle-network/sandbox-ui/chat";
497
- import { jsx as jsx4 } from "react/jsx-runtime";
494
+ useCallback,
495
+ useEffect as useEffect3,
496
+ useRef as useRef3,
497
+ useState as useState3
498
+ } from "react";
499
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
500
+ function SendGlyph({ className }) {
501
+ return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z" }) });
502
+ }
503
+ function StopGlyph({ className }) {
504
+ return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": true, children: /* @__PURE__ */ jsx4("rect", { x: "6", y: "6", width: "12", height: "12", rx: "2" }) });
505
+ }
506
+ function PaperclipGlyph({ className }) {
507
+ return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
508
+ }
509
+ function FolderGlyph({ className }) {
510
+ return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
511
+ /* @__PURE__ */ jsx4("path", { d: "M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z" }),
512
+ /* @__PURE__ */ jsx4("path", { d: "M12 10v6m-3-3h6" })
513
+ ] });
514
+ }
515
+ function CloseGlyph({ className }) {
516
+ return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "M18 6 6 18M6 6l12 12" }) });
517
+ }
518
+ function UploadGlyph({ className }) {
519
+ return /* @__PURE__ */ jsx4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx4("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12" }) });
520
+ }
521
+ var MAX_HEIGHT = 168;
498
522
  function ChatComposer({
499
523
  onSend,
500
524
  onCancel,
@@ -505,13 +529,14 @@ function ChatComposer({
505
529
  onValueChange,
506
530
  initialValue,
507
531
  controls,
532
+ controlsPlacement = "above",
508
533
  onAttach,
509
534
  onAttachFolder,
510
- pendingFiles,
535
+ pendingFiles = [],
511
536
  onRemoveFile,
512
537
  accept,
513
- dropTitle,
514
- dropDescription,
538
+ dropTitle = "Drop files to add context",
539
+ dropDescription = "They attach to your next message.",
515
540
  focusShortcut = true,
516
541
  sendLabel = "Send",
517
542
  className
@@ -519,6 +544,11 @@ function ChatComposer({
519
544
  const isControlled = value !== void 0;
520
545
  const [internal, setInternal] = useState3(initialValue ?? "");
521
546
  const text = isControlled ? value : internal;
547
+ const textareaRef = useRef3(null);
548
+ const fileInputRef = useRef3(null);
549
+ const folderInputRef = useRef3(null);
550
+ const [dragOver, setDragOver] = useState3(false);
551
+ const dragDepth = useRef3(0);
522
552
  const setText = useCallback(
523
553
  (next) => {
524
554
  if (!isControlled) setInternal(next);
@@ -526,40 +556,218 @@ function ChatComposer({
526
556
  },
527
557
  [isControlled, onValueChange]
528
558
  );
529
- const handleSubmit = useCallback(() => {
559
+ useEffect3(() => {
560
+ const el = textareaRef.current;
561
+ if (!el) return;
562
+ el.style.height = "auto";
563
+ el.style.height = `${Math.min(el.scrollHeight, MAX_HEIGHT)}px`;
564
+ }, [text]);
565
+ useEffect3(() => {
566
+ if (!focusShortcut || disabled) return;
567
+ function onKeyDown(e) {
568
+ if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "l") {
569
+ e.preventDefault();
570
+ textareaRef.current?.focus();
571
+ }
572
+ }
573
+ document.addEventListener("keydown", onKeyDown);
574
+ return () => document.removeEventListener("keydown", onKeyDown);
575
+ }, [focusShortcut, disabled]);
576
+ const canSend = text.trim().length > 0 && !isStreaming && !disabled;
577
+ const send = useCallback(() => {
530
578
  const trimmed = text.trim();
531
579
  if (!trimmed || isStreaming || disabled) return;
532
580
  onSend(trimmed);
533
581
  setText("");
534
582
  }, [text, isStreaming, disabled, onSend, setText]);
535
- return /* @__PURE__ */ jsx4(
536
- AgentComposer,
583
+ const handleKeyDown = (e) => {
584
+ if (e.nativeEvent.isComposing) return;
585
+ if (e.key === "Enter" && !e.shiftKey) {
586
+ e.preventDefault();
587
+ send();
588
+ }
589
+ };
590
+ const handleFileChange = (e) => {
591
+ if (e.target.files?.length) onAttach?.(e.target.files);
592
+ e.target.value = "";
593
+ };
594
+ const handleFolderChange = (e) => {
595
+ if (e.target.files?.length) (onAttachFolder ?? onAttach)?.(e.target.files);
596
+ e.target.value = "";
597
+ };
598
+ const handleDragEnter = useCallback((e) => {
599
+ e.preventDefault();
600
+ e.stopPropagation();
601
+ dragDepth.current++;
602
+ if (e.dataTransfer?.types.includes("Files")) setDragOver(true);
603
+ }, []);
604
+ const handleDragLeave = useCallback((e) => {
605
+ e.preventDefault();
606
+ e.stopPropagation();
607
+ dragDepth.current--;
608
+ if (dragDepth.current <= 0) {
609
+ dragDepth.current = 0;
610
+ setDragOver(false);
611
+ }
612
+ }, []);
613
+ const handleDragOver = useCallback((e) => {
614
+ e.preventDefault();
615
+ e.stopPropagation();
616
+ if (e.dataTransfer) e.dataTransfer.dropEffect = "copy";
617
+ }, []);
618
+ const handleDrop = useCallback(
619
+ (e) => {
620
+ e.preventDefault();
621
+ e.stopPropagation();
622
+ dragDepth.current = 0;
623
+ setDragOver(false);
624
+ const files = e.dataTransfer?.files;
625
+ if (files?.length) onAttach?.(files);
626
+ },
627
+ [onAttach]
628
+ );
629
+ const folderChips = pendingFiles.filter((f) => f.kind === "folder");
630
+ const fileChips = pendingFiles.filter((f) => f.kind !== "folder");
631
+ const showFooter = controls != null && controlsPlacement === "footer";
632
+ const showAbove = controls != null && controlsPlacement === "above";
633
+ return /* @__PURE__ */ jsxs3(
634
+ "div",
537
635
  {
538
- value: text,
539
- onChange: setText,
540
- onSubmit: handleSubmit,
541
- placeholder,
542
- disabled,
543
- busy: isStreaming,
544
- onCancel,
545
- controls,
546
- onAttach,
547
- onAttachFolder,
548
- attachments: pendingFiles,
549
- onRemoveFile,
550
- accept,
551
- dropTitle,
552
- dropDescription,
553
- focusShortcut,
554
- sendLabel,
555
- className
636
+ className: `relative ${className ?? ""}`,
637
+ onDragEnter: onAttach ? handleDragEnter : void 0,
638
+ onDragLeave: onAttach ? handleDragLeave : void 0,
639
+ onDragOver: onAttach ? handleDragOver : void 0,
640
+ onDrop: onAttach ? handleDrop : void 0,
641
+ children: [
642
+ dragOver && /* @__PURE__ */ jsx4("div", { className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-2xl border-2 border-dashed border-primary/50 bg-card/95", children: /* @__PURE__ */ jsxs3("div", { className: "text-center", children: [
643
+ /* @__PURE__ */ jsx4("span", { className: "mx-auto mb-2 flex h-11 w-11 items-center justify-center rounded-xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsx4(UploadGlyph, { className: "h-5 w-5" }) }),
644
+ /* @__PURE__ */ jsx4("p", { className: "text-sm font-semibold text-foreground", children: dropTitle }),
645
+ /* @__PURE__ */ jsx4("p", { className: "mt-0.5 text-xs text-muted-foreground", children: dropDescription })
646
+ ] }) }),
647
+ showAbove && /* @__PURE__ */ jsx4("div", { className: "mb-1.5 flex flex-wrap items-center gap-1.5 px-1", children: controls }),
648
+ pendingFiles.length > 0 && /* @__PURE__ */ jsx4("div", { className: "mb-2 flex flex-wrap gap-1.5", children: [...folderChips, ...fileChips].map((f) => /* @__PURE__ */ jsxs3(
649
+ "span",
650
+ {
651
+ className: `inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-xs ${f.status === "error" ? "border-destructive/40 text-destructive" : "border-border bg-muted/50 text-foreground"}`,
652
+ children: [
653
+ f.kind === "folder" ? /* @__PURE__ */ jsx4(FolderGlyph, { className: "h-3 w-3 shrink-0" }) : /* @__PURE__ */ jsx4(PaperclipGlyph, { className: "h-3 w-3 shrink-0" }),
654
+ /* @__PURE__ */ jsx4("span", { className: "max-w-[150px] truncate", children: f.name }),
655
+ f.fileCount !== void 0 && /* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
656
+ "(",
657
+ f.fileCount,
658
+ ")"
659
+ ] }),
660
+ f.status === "uploading" && /* @__PURE__ */ jsx4("span", { className: "h-3 w-3 animate-spin rounded-full border-2 border-primary border-t-transparent" }),
661
+ onRemoveFile && /* @__PURE__ */ jsx4(
662
+ "button",
663
+ {
664
+ type: "button",
665
+ "aria-label": `Remove ${f.name}`,
666
+ onClick: () => onRemoveFile(f.id),
667
+ className: "rounded p-0.5 text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
668
+ children: /* @__PURE__ */ jsx4(CloseGlyph, { className: "h-3 w-3" })
669
+ }
670
+ )
671
+ ]
672
+ },
673
+ f.id
674
+ )) }),
675
+ /* @__PURE__ */ jsxs3("div", { className: "flex items-end gap-2 rounded-2xl border border-border bg-card px-2.5 py-2 transition focus-within:border-primary/40 focus-within:ring-2 focus-within:ring-primary/15", children: [
676
+ onAttach && /* @__PURE__ */ jsxs3(Fragment2, { children: [
677
+ /* @__PURE__ */ jsx4(
678
+ "button",
679
+ {
680
+ type: "button",
681
+ onClick: () => fileInputRef.current?.click(),
682
+ disabled,
683
+ "aria-label": "Attach files",
684
+ title: "Attach files",
685
+ className: "mb-0.5 shrink-0 rounded-lg p-2 text-muted-foreground transition hover:bg-accent/40 hover:text-foreground disabled:opacity-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
686
+ children: /* @__PURE__ */ jsx4(PaperclipGlyph, { className: "h-4 w-4" })
687
+ }
688
+ ),
689
+ /* @__PURE__ */ jsx4("input", { ref: fileInputRef, type: "file", multiple: true, className: "hidden", accept, onChange: handleFileChange })
690
+ ] }),
691
+ onAttachFolder && /* @__PURE__ */ jsxs3(Fragment2, { children: [
692
+ /* @__PURE__ */ jsx4(
693
+ "button",
694
+ {
695
+ type: "button",
696
+ onClick: () => folderInputRef.current?.click(),
697
+ disabled,
698
+ "aria-label": "Attach folder",
699
+ title: "Attach folder",
700
+ className: "mb-0.5 shrink-0 rounded-lg p-2 text-muted-foreground transition hover:bg-accent/40 hover:text-foreground disabled:opacity-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
701
+ children: /* @__PURE__ */ jsx4(FolderGlyph, { className: "h-4 w-4" })
702
+ }
703
+ ),
704
+ /* @__PURE__ */ jsx4(
705
+ "input",
706
+ {
707
+ ref: folderInputRef,
708
+ type: "file",
709
+ multiple: true,
710
+ className: "hidden",
711
+ onChange: handleFolderChange,
712
+ ...{ webkitdirectory: "" }
713
+ }
714
+ )
715
+ ] }),
716
+ /* @__PURE__ */ jsx4(
717
+ "textarea",
718
+ {
719
+ ref: textareaRef,
720
+ value: text,
721
+ onChange: (e) => setText(e.target.value),
722
+ onKeyDown: handleKeyDown,
723
+ placeholder,
724
+ disabled,
725
+ rows: 1,
726
+ "aria-label": "Message input",
727
+ className: "max-h-[168px] min-h-[40px] flex-1 resize-none bg-transparent px-1.5 py-2 text-[15px] leading-6 text-foreground outline-none placeholder:text-muted-foreground disabled:opacity-50"
728
+ }
729
+ ),
730
+ showFooter && /* @__PURE__ */ jsx4("div", { className: "mb-0.5 flex shrink-0 items-center gap-1.5", children: controls }),
731
+ isStreaming ? /* @__PURE__ */ jsxs3(
732
+ "button",
733
+ {
734
+ type: "button",
735
+ onClick: onCancel,
736
+ "aria-label": "Stop response",
737
+ className: "mb-0.5 inline-flex shrink-0 items-center gap-1.5 rounded-full bg-destructive/15 px-3.5 py-2 text-sm font-medium text-destructive transition hover:bg-destructive/25 focus:outline-none focus-visible:ring-2 focus-visible:ring-destructive/50",
738
+ children: [
739
+ /* @__PURE__ */ jsx4(StopGlyph, { className: "h-3.5 w-3.5" }),
740
+ /* @__PURE__ */ jsx4("span", { children: "Stop" })
741
+ ]
742
+ }
743
+ ) : /* @__PURE__ */ jsxs3(
744
+ "button",
745
+ {
746
+ type: "button",
747
+ onClick: send,
748
+ disabled: !canSend,
749
+ "aria-label": sendLabel,
750
+ className: "mb-0.5 inline-flex shrink-0 items-center gap-1.5 rounded-full bg-primary px-3.5 py-2 text-sm font-medium text-primary-foreground shadow-sm transition hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-40 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-card",
751
+ children: [
752
+ /* @__PURE__ */ jsx4(SendGlyph, { className: "h-3.5 w-3.5" }),
753
+ /* @__PURE__ */ jsx4("span", { children: sendLabel })
754
+ ]
755
+ }
756
+ )
757
+ ] }),
758
+ focusShortcut && /* @__PURE__ */ jsx4("div", { className: "mt-1.5 flex justify-end px-1", children: /* @__PURE__ */ jsxs3("span", { className: "text-xs text-muted-foreground", children: [
759
+ /* @__PURE__ */ jsx4("kbd", { className: "rounded border border-border bg-background px-1 py-0.5 text-[10px]", children: "Cmd" }),
760
+ /* @__PURE__ */ jsx4("kbd", { className: "ml-0.5 rounded border border-border bg-background px-1 py-0.5 text-[10px]", children: "L" }),
761
+ /* @__PURE__ */ jsx4("span", { className: "ml-1", children: "to focus" })
762
+ ] }) })
763
+ ]
556
764
  }
557
765
  );
558
766
  }
559
767
 
560
768
  // src/web-react/mission-activity.tsx
561
- import { useCallback as useCallback2, useEffect as useEffect3, useState as useState4 } from "react";
562
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
769
+ import { useCallback as useCallback2, useEffect as useEffect4, useState as useState4 } from "react";
770
+ import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
563
771
  var LIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "running"]);
564
772
  var OK_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "succeeded"]);
565
773
  var ERROR_STATUSES = /* @__PURE__ */ new Set(["failed", "error", "cancelled", "aborted"]);
@@ -612,7 +820,7 @@ function RefreshGlyph({ className }) {
612
820
  return /* @__PURE__ */ jsx5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx5("path", { d: "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" }) });
613
821
  }
614
822
  function CopyGlyph({ className }) {
615
- return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
823
+ return /* @__PURE__ */ jsxs4("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
616
824
  /* @__PURE__ */ jsx5("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
617
825
  /* @__PURE__ */ jsx5("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
618
826
  ] });
@@ -629,7 +837,7 @@ function TraceIdCopy({ traceId }) {
629
837
  }
630
838
  );
631
839
  }, [traceId]);
632
- return /* @__PURE__ */ jsxs3(
840
+ return /* @__PURE__ */ jsxs4(
633
841
  "button",
634
842
  {
635
843
  type: "button",
@@ -646,7 +854,7 @@ function TraceIdCopy({ traceId }) {
646
854
  );
647
855
  }
648
856
  function StatusDot({ tone }) {
649
- return /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center", children: [
857
+ return /* @__PURE__ */ jsxs4("span", { className: "inline-flex items-center", children: [
650
858
  /* @__PURE__ */ jsx5(
651
859
  "span",
652
860
  {
@@ -666,8 +874,8 @@ function FlowWaterfall({ trace }) {
666
874
  const rows = waterfallLayout(trace);
667
875
  if (rows.length === 0) return null;
668
876
  const cost = formatActivityCost(trace.costUsd);
669
- return /* @__PURE__ */ jsxs3("div", { className: "space-y-1", children: [
670
- rows.map((row, i) => /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
877
+ return /* @__PURE__ */ jsxs4("div", { className: "space-y-1", children: [
878
+ rows.map((row, i) => /* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
671
879
  /* @__PURE__ */ jsx5("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
672
880
  /* @__PURE__ */ jsx5("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx5(
673
881
  "div",
@@ -678,7 +886,7 @@ function FlowWaterfall({ trace }) {
678
886
  ) }),
679
887
  /* @__PURE__ */ jsx5("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
680
888
  ] }, i)),
681
- /* @__PURE__ */ jsxs3("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
889
+ /* @__PURE__ */ jsxs4("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
682
890
  (trace.totalMs / 1e3).toFixed(1),
683
891
  "s",
684
892
  cost ? ` \xB7 ${cost}` : ""
@@ -688,29 +896,29 @@ function FlowWaterfall({ trace }) {
688
896
  function MissionActivityLane({ activity, startedAt, nowMs }) {
689
897
  const [expanded, setExpanded] = useState4(false);
690
898
  if (activity.length === 0) return null;
691
- return /* @__PURE__ */ jsxs3("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
899
+ return /* @__PURE__ */ jsxs4("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
692
900
  activity.map((run) => {
693
901
  const tone = activityTone(run.status);
694
902
  const cost = formatActivityCost(run.costUsd);
695
903
  const duration = formatActivityDuration(run.durationMs);
696
- return /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
904
+ return /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
697
905
  /* @__PURE__ */ jsx5(StatusDot, { tone }),
698
- /* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
906
+ /* @__PURE__ */ jsxs4("span", { className: "min-w-0 flex-1 truncate", children: [
699
907
  /* @__PURE__ */ jsx5("span", { className: "font-medium", children: run.tool }),
700
- /* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
908
+ /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground", children: [
701
909
  " \u2014 ",
702
910
  run.detail
703
911
  ] })
704
912
  ] }),
705
913
  tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx5("span", { className: "shrink-0 rounded-full bg-warning/10 px-1.5 py-0.5 font-mono text-[10px] text-warning", children: [run.iteration !== void 0 ? `iter ${run.iteration}` : null, run.phase ?? null].filter(Boolean).join(" \xB7 ") }),
706
- /* @__PURE__ */ jsxs3("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
914
+ /* @__PURE__ */ jsxs4("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
707
915
  tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx5("span", { children: run.status }),
708
916
  cost && /* @__PURE__ */ jsx5("span", { children: cost }),
709
917
  duration && /* @__PURE__ */ jsx5("span", { children: duration })
710
918
  ] })
711
919
  ] }, run.taskId);
712
920
  }),
713
- /* @__PURE__ */ jsxs3(
921
+ /* @__PURE__ */ jsxs4(
714
922
  "button",
715
923
  {
716
924
  type: "button",
@@ -741,12 +949,12 @@ function ActivityRow({
741
949
  const tone = activityTone(record.status);
742
950
  const cost = formatActivityCost(record.costUsd);
743
951
  const duration = formatActivityDuration(record.durationMs);
744
- return /* @__PURE__ */ jsxs3("div", { className: "rounded-lg border border-border/60 bg-card", children: [
745
- /* @__PURE__ */ jsxs3("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm", children: [
952
+ return /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border border-border/60 bg-card", children: [
953
+ /* @__PURE__ */ jsxs4("button", { type: "button", onClick: () => setOpen((v) => !v), className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-sm", children: [
746
954
  /* @__PURE__ */ jsx5(StatusDot, { tone }),
747
- /* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
955
+ /* @__PURE__ */ jsxs4("span", { className: "min-w-0 flex-1 truncate", children: [
748
956
  /* @__PURE__ */ jsx5("span", { className: "font-medium", children: record.tool }),
749
- /* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
957
+ /* @__PURE__ */ jsxs4("span", { className: "text-muted-foreground", children: [
750
958
  " \u2014 ",
751
959
  record.detail
752
960
  ] })
@@ -762,18 +970,18 @@ function ActivityRow({
762
970
  cost && /* @__PURE__ */ jsx5("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
763
971
  /* @__PURE__ */ jsx5(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
764
972
  ] }),
765
- open && /* @__PURE__ */ jsxs3("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
973
+ open && /* @__PURE__ */ jsxs4("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
766
974
  record.durationMs !== void 0 && /* @__PURE__ */ jsx5("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx5(FlowWaterfall, { trace: stepActivityFlowTrace([record]) }) }),
767
- /* @__PURE__ */ jsxs3("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
975
+ /* @__PURE__ */ jsxs4("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
768
976
  /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "task" }),
769
977
  /* @__PURE__ */ jsx5("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
770
978
  /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "started" }),
771
979
  /* @__PURE__ */ jsx5("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
772
- duration && /* @__PURE__ */ jsxs3(Fragment2, { children: [
980
+ duration && /* @__PURE__ */ jsxs4(Fragment3, { children: [
773
981
  /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "duration" }),
774
982
  /* @__PURE__ */ jsx5("dd", { className: "text-muted-foreground", children: duration })
775
983
  ] }),
776
- record.traceId && /* @__PURE__ */ jsxs3(Fragment2, { children: [
984
+ record.traceId && /* @__PURE__ */ jsxs4(Fragment3, { children: [
777
985
  /* @__PURE__ */ jsx5("dt", { className: "text-muted-foreground/60", children: "trace" }),
778
986
  /* @__PURE__ */ jsx5("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx5(TraceIdCopy, { traceId: record.traceId }) })
779
987
  ] })
@@ -803,11 +1011,11 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
803
1011
  },
804
1012
  [fetchActivity]
805
1013
  );
806
- useEffect3(() => {
1014
+ useEffect4(() => {
807
1015
  void load();
808
1016
  }, [load]);
809
- return /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
810
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
1017
+ return /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
1018
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
811
1019
  /* @__PURE__ */ jsx5("h2", { className: "flex-1 text-sm font-semibold", children: title }),
812
1020
  /* @__PURE__ */ jsx5(
813
1021
  "button",
@@ -837,256 +1045,10 @@ function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent ac
837
1045
  ] });
838
1046
  }
839
1047
 
840
- // src/web-react/sandbox-terminal.ts
841
- import { useCallback as useCallback3, useEffect as useEffect4, useRef as useRef3, useState as useState5 } from "react";
842
- var DEFAULT_PROVISION_POLL_INTERVAL_MS = 2e3;
843
- var DEFAULT_PROVISION_POLL_TIMEOUT_MS = 9e4;
844
- var DEFAULT_TOKEN_REFRESH_SKEW_MS = 12e4;
845
- var EMPTY_CONNECTION = {
846
- runtimeUrl: null,
847
- sidecarUrl: null,
848
- token: null,
849
- expiresAt: null,
850
- status: "idle",
851
- error: null,
852
- loading: false
853
- };
854
- function useSandboxTerminalConnection(opts) {
855
- const [conn, setConn] = useState5(EMPTY_CONNECTION);
856
- const mountedRef = useRef3(false);
857
- const generationRef = useRef3(0);
858
- const fetcher = opts.fetcher ?? fetch;
859
- const pollIntervalMs = opts.provisionPollIntervalMs ?? DEFAULT_PROVISION_POLL_INTERVAL_MS;
860
- const pollTimeoutMs = opts.provisionPollTimeoutMs ?? DEFAULT_PROVISION_POLL_TIMEOUT_MS;
861
- const refreshSkewMs = opts.tokenRefreshSkewMs ?? DEFAULT_TOKEN_REFRESH_SKEW_MS;
862
- const connectionUrl = useCallback3(() => {
863
- if (typeof opts.connectionUrl === "function") return opts.connectionUrl(opts.workspaceId);
864
- return opts.connectionUrl ?? `/api/workspaces/${encodeURIComponent(opts.workspaceId)}/sandbox/connection`;
865
- }, [opts.connectionUrl, opts.workspaceId]);
866
- const connect = useCallback3(async () => {
867
- const generation = generationRef.current + 1;
868
- generationRef.current = generation;
869
- const isCurrent = () => mountedRef.current && generationRef.current === generation;
870
- const setCurrentConn = (value) => {
871
- if (!isCurrent()) return;
872
- setConn(value);
873
- };
874
- setCurrentConn((current) => ({ ...current, loading: true, error: null }));
875
- const deadline = Date.now() + pollTimeoutMs;
876
- while (isCurrent()) {
877
- try {
878
- const res = await fetcher(connectionUrl());
879
- const data = await res.json();
880
- if (!isCurrent()) return;
881
- const runtimeUrl = data.runtimeUrl ?? data.sidecarUrl;
882
- if (res.ok && runtimeUrl && data.token && data.expiresAt) {
883
- setCurrentConn({
884
- runtimeUrl,
885
- sidecarUrl: data.sidecarUrl ?? runtimeUrl,
886
- token: data.token,
887
- expiresAt: data.expiresAt,
888
- status: data.status ?? "running",
889
- error: null,
890
- loading: false,
891
- ...data.sandboxId ? { sandboxId: data.sandboxId } : {}
892
- });
893
- return;
894
- }
895
- if (res.ok) {
896
- setCurrentConn({
897
- runtimeUrl: null,
898
- sidecarUrl: null,
899
- token: null,
900
- expiresAt: null,
901
- loading: false,
902
- error: "Sandbox connection response is missing required fields",
903
- status: data.status ?? "error",
904
- ...data.sandboxId ? { sandboxId: data.sandboxId } : {}
905
- });
906
- return;
907
- }
908
- if (res.status === 503 && Date.now() < deadline) {
909
- setCurrentConn((current) => ({
910
- ...current,
911
- loading: true,
912
- status: data.status ?? "provisioning",
913
- error: null
914
- }));
915
- await sleep(pollIntervalMs);
916
- continue;
917
- }
918
- setCurrentConn((current) => ({
919
- ...current,
920
- runtimeUrl: null,
921
- sidecarUrl: null,
922
- token: null,
923
- expiresAt: null,
924
- loading: false,
925
- error: data.error ?? "Sandbox not available",
926
- status: data.status ?? "error"
927
- }));
928
- return;
929
- } catch (err) {
930
- if (!isCurrent()) return;
931
- if (Date.now() < deadline) {
932
- await sleep(pollIntervalMs);
933
- continue;
934
- }
935
- setCurrentConn((current) => ({
936
- ...current,
937
- runtimeUrl: null,
938
- sidecarUrl: null,
939
- token: null,
940
- expiresAt: null,
941
- loading: false,
942
- error: err instanceof Error ? err.message : "Connection failed"
943
- }));
944
- return;
945
- }
946
- }
947
- }, [connectionUrl, fetcher, pollIntervalMs, pollTimeoutMs]);
948
- useEffect4(() => {
949
- mountedRef.current = true;
950
- return () => {
951
- mountedRef.current = false;
952
- generationRef.current += 1;
953
- };
954
- }, []);
955
- useEffect4(() => {
956
- void connect();
957
- }, [connect]);
958
- useEffect4(() => {
959
- if (!conn.runtimeUrl || !conn.token || !conn.expiresAt) return;
960
- const refreshAt = Date.parse(conn.expiresAt) - Date.now() - refreshSkewMs;
961
- if (!Number.isFinite(refreshAt)) {
962
- setConn((current) => ({
963
- ...current,
964
- runtimeUrl: null,
965
- sidecarUrl: null,
966
- token: null,
967
- expiresAt: null,
968
- status: "error",
969
- error: "Sandbox token expiry is invalid"
970
- }));
971
- return;
972
- }
973
- const timer = window.setTimeout(() => {
974
- void connect();
975
- }, Math.max(1e3, refreshAt));
976
- return () => window.clearTimeout(timer);
977
- }, [conn.runtimeUrl, conn.token, conn.expiresAt, connect, refreshSkewMs]);
978
- return { ...conn, connect };
979
- }
980
- function sleep(ms) {
981
- return new Promise((resolve) => window.setTimeout(resolve, ms));
982
- }
983
- var DEFAULT_TERMINAL_CID_KEY = "agent-app:terminal-connection-id";
984
- function newConnectionId() {
985
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
986
- return `cid-${Date.now().toString(36)}-${Math.floor(Math.random() * 1e9).toString(36)}`;
987
- }
988
- function tabTerminalConnectionId(storageKey = DEFAULT_TERMINAL_CID_KEY) {
989
- try {
990
- const store = globalThis.sessionStorage;
991
- const existing = store?.getItem(storageKey);
992
- if (existing) return existing;
993
- const id = newConnectionId();
994
- store?.setItem(storageKey, id);
995
- return id;
996
- } catch {
997
- return newConnectionId();
998
- }
999
- }
1000
-
1001
- // src/web-react/workspace-terminal-panel.tsx
1002
- import { lazy as lazy2, Suspense as Suspense2 } from "react";
1003
- import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
1004
- var TerminalView = lazy2(
1005
- () => import("@tangle-network/sandbox-ui/terminal").then((m) => ({ default: m.TerminalView }))
1006
- );
1007
- var TONE_DOT = {
1008
- idle: "bg-muted-foreground/50",
1009
- connecting: "animate-pulse bg-warning",
1010
- connected: "bg-success",
1011
- error: "bg-destructive"
1012
- };
1013
- function defaultStatusDisplay(conn) {
1014
- if (conn.error) return { tone: "error", label: "Disconnected" };
1015
- if (conn.runtimeUrl && conn.token) return { tone: "connected", label: "Connected" };
1016
- if (conn.loading) return { tone: "connecting", label: conn.status === "provisioning" ? "Provisioning\u2026" : "Connecting\u2026" };
1017
- return { tone: "idle", label: "Idle" };
1018
- }
1019
- function WorkspaceTerminalPanel({
1020
- connection,
1021
- connectionId,
1022
- title = "Terminal",
1023
- subtitle,
1024
- isActive,
1025
- onRetry,
1026
- statusDisplay,
1027
- headerExtra,
1028
- className
1029
- }) {
1030
- const status = (statusDisplay ?? defaultStatusDisplay)(connection);
1031
- const apiUrl = connection.runtimeUrl ?? connection.sidecarUrl;
1032
- const ready = Boolean(apiUrl && connection.token);
1033
- return /* @__PURE__ */ jsxs4("div", { className: `flex h-full min-h-0 flex-col overflow-hidden rounded-xl border border-border bg-card ${className ?? ""}`, children: [
1034
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-3 border-b border-border px-4 py-2.5", children: [
1035
- /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
1036
- /* @__PURE__ */ jsx6("p", { className: "truncate text-sm font-medium text-foreground", children: title }),
1037
- subtitle && /* @__PURE__ */ jsx6("p", { className: "truncate text-xs text-muted-foreground", children: subtitle })
1038
- ] }),
1039
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
1040
- /* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
1041
- /* @__PURE__ */ jsx6("span", { className: `h-1.5 w-1.5 rounded-full ${TONE_DOT[status.tone]}`, "aria-hidden": true }),
1042
- status.label
1043
- ] }),
1044
- headerExtra
1045
- ] })
1046
- ] }),
1047
- /* @__PURE__ */ jsx6("div", { className: "relative min-h-0 flex-1", children: ready ? /* @__PURE__ */ jsx6(Suspense2, { fallback: /* @__PURE__ */ jsx6(TerminalMessage, { children: "Loading terminal\u2026" }), children: /* @__PURE__ */ jsx6(
1048
- TerminalView,
1049
- {
1050
- apiUrl,
1051
- token: connection.token,
1052
- connectionId,
1053
- title,
1054
- subtitle,
1055
- isActive
1056
- }
1057
- ) }) : /* @__PURE__ */ jsx6(TerminalMessage, { children: connection.error ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
1058
- /* @__PURE__ */ jsx6("p", { className: "text-sm text-destructive", children: connection.error }),
1059
- onRetry && /* @__PURE__ */ jsx6(
1060
- "button",
1061
- {
1062
- type: "button",
1063
- onClick: onRetry,
1064
- className: "mt-3 inline-flex items-center justify-center rounded-lg border border-border px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-muted",
1065
- children: "Reconnect"
1066
- }
1067
- )
1068
- ] }) : connection.loading ? /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground", children: connection.status === "provisioning" ? "Provisioning sandbox\u2026" : "Connecting\u2026" }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
1069
- /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground", children: "Terminal not connected." }),
1070
- onRetry && /* @__PURE__ */ jsx6(
1071
- "button",
1072
- {
1073
- type: "button",
1074
- onClick: onRetry,
1075
- className: "mt-3 inline-flex items-center justify-center rounded-lg border border-border px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-muted",
1076
- children: "Connect"
1077
- }
1078
- )
1079
- ] }) }) })
1080
- ] });
1081
- }
1082
- function TerminalMessage({ children }) {
1083
- return /* @__PURE__ */ jsx6("div", { className: "absolute inset-0 flex flex-col items-center justify-center p-6 text-center", children });
1084
- }
1085
-
1086
1048
  // src/web-react/seat-paywall.tsx
1087
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
1049
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1088
1050
  function CheckGlyph() {
1089
- return /* @__PURE__ */ jsx7(
1051
+ return /* @__PURE__ */ jsx6(
1090
1052
  "svg",
1091
1053
  {
1092
1054
  className: "h-4 w-4 shrink-0 text-primary",
@@ -1097,14 +1059,14 @@ function CheckGlyph() {
1097
1059
  strokeLinecap: "round",
1098
1060
  strokeLinejoin: "round",
1099
1061
  "aria-hidden": true,
1100
- children: /* @__PURE__ */ jsx7("path", { d: "M20 6 9 17l-5-5" })
1062
+ children: /* @__PURE__ */ jsx6("path", { d: "M20 6 9 17l-5-5" })
1101
1063
  }
1102
1064
  );
1103
1065
  }
1104
1066
  function Benefit({ children }) {
1105
1067
  return /* @__PURE__ */ jsxs5("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
1106
- /* @__PURE__ */ jsx7("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx7(CheckGlyph, {}) }),
1107
- /* @__PURE__ */ jsx7("span", { children })
1068
+ /* @__PURE__ */ jsx6("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx6(CheckGlyph, {}) }),
1069
+ /* @__PURE__ */ jsx6("span", { children })
1108
1070
  ] });
1109
1071
  }
1110
1072
  function SeatPaywall({
@@ -1118,30 +1080,30 @@ function SeatPaywall({
1118
1080
  footnote
1119
1081
  }) {
1120
1082
  const { pending, run } = usePending();
1121
- return /* @__PURE__ */ jsx7("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs5("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
1122
- /* @__PURE__ */ jsx7("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
1083
+ return /* @__PURE__ */ jsx6("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs5("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
1084
+ /* @__PURE__ */ jsx6("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
1123
1085
  /* @__PURE__ */ jsxs5("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
1124
1086
  "Unlock ",
1125
1087
  product
1126
1088
  ] }),
1127
- tagline && /* @__PURE__ */ jsx7("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
1089
+ tagline && /* @__PURE__ */ jsx6("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
1128
1090
  /* @__PURE__ */ jsxs5("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
1129
1091
  /* @__PURE__ */ jsxs5("span", { className: "text-3xl font-semibold text-foreground", children: [
1130
1092
  "$",
1131
1093
  priceUsd
1132
1094
  ] }),
1133
- /* @__PURE__ */ jsx7("span", { className: "text-sm text-muted-foreground", children: "/mo" })
1095
+ /* @__PURE__ */ jsx6("span", { className: "text-sm text-muted-foreground", children: "/mo" })
1134
1096
  ] }),
1135
1097
  /* @__PURE__ */ jsxs5("p", { className: "mt-1 text-sm text-muted-foreground", children: [
1136
1098
  "Includes $",
1137
1099
  includedUsageUsd,
1138
1100
  "/mo of AI usage"
1139
1101
  ] }),
1140
- /* @__PURE__ */ jsx7("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
1102
+ /* @__PURE__ */ jsx6("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
1141
1103
  `Full access to ${product}`,
1142
1104
  `$${includedUsageUsd}/mo of AI usage included, every month`
1143
- ]).map((benefit, i) => /* @__PURE__ */ jsx7(Benefit, { children: benefit }, i)) }),
1144
- /* @__PURE__ */ jsx7(
1105
+ ]).map((benefit, i) => /* @__PURE__ */ jsx6(Benefit, { children: benefit }, i)) }),
1106
+ /* @__PURE__ */ jsx6(
1145
1107
  "button",
1146
1108
  {
1147
1109
  type: "button",
@@ -1151,13 +1113,13 @@ function SeatPaywall({
1151
1113
  children: pending ? "Opening checkout\u2026" : ctaLabel ?? `Unlock ${product}`
1152
1114
  }
1153
1115
  ),
1154
- footnote && /* @__PURE__ */ jsx7("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
1116
+ footnote && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
1155
1117
  ] }) });
1156
1118
  }
1157
1119
 
1158
1120
  // src/web-react/agent-session-controls.tsx
1159
- import { useMemo as useMemo2, useState as useState6 } from "react";
1160
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1121
+ import { useMemo as useMemo2, useState as useState5 } from "react";
1122
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1161
1123
  var HARNESS_LABELS = {
1162
1124
  opencode: "OpenCode (any model)",
1163
1125
  "claude-code": "Claude Code (Anthropic)",
@@ -1177,12 +1139,12 @@ function harnessLabel(h) {
1177
1139
  return HARNESS_LABELS[h] ?? h;
1178
1140
  }
1179
1141
  function ChevronDown2({ className }) {
1180
- return /* @__PURE__ */ jsx8("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx8("path", { d: "m6 9 6 6 6-6" }) });
1142
+ return /* @__PURE__ */ jsx7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx7("path", { d: "m6 9 6 6 6-6" }) });
1181
1143
  }
1182
1144
  function GearGlyph({ className }) {
1183
1145
  return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1184
- /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "3" }),
1185
- /* @__PURE__ */ jsx8("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
1146
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "3" }),
1147
+ /* @__PURE__ */ jsx7("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
1186
1148
  ] });
1187
1149
  }
1188
1150
  var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background";
@@ -1191,7 +1153,7 @@ function HarnessPicker({
1191
1153
  onChange,
1192
1154
  available
1193
1155
  }) {
1194
- const [open, setOpen] = useState6(false);
1156
+ const [open, setOpen] = useState5(false);
1195
1157
  const { containerRef, triggerProps } = usePopover(open, setOpen);
1196
1158
  const options = available ?? Object.keys(HARNESS_LABELS);
1197
1159
  return /* @__PURE__ */ jsxs6("div", { ref: containerRef, className: "relative inline-flex", children: [
@@ -1204,12 +1166,12 @@ function HarnessPicker({
1204
1166
  title: "Agent backend",
1205
1167
  className: `inline-flex w-full items-center justify-between gap-1.5 rounded-lg border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent/30 ${FOCUS_RING}`,
1206
1168
  children: [
1207
- /* @__PURE__ */ jsx8("span", { className: "truncate", children: harnessLabel(value) }),
1208
- /* @__PURE__ */ jsx8(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
1169
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: harnessLabel(value) }),
1170
+ /* @__PURE__ */ jsx7(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
1209
1171
  ]
1210
1172
  }
1211
1173
  ),
1212
- open && /* @__PURE__ */ jsx8("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 max-h-64 w-full min-w-[220px] overflow-y-auto rounded-xl border border-border bg-card p-1 shadow-lg", children: options.map((h) => /* @__PURE__ */ jsx8(
1174
+ open && /* @__PURE__ */ jsx7("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 max-h-64 w-full min-w-[220px] overflow-y-auto rounded-xl border border-border bg-card p-1 shadow-lg", children: options.map((h) => /* @__PURE__ */ jsx7(
1213
1175
  "button",
1214
1176
  {
1215
1177
  type: "button",
@@ -1256,11 +1218,11 @@ function AgentSessionControls(props) {
1256
1218
  className
1257
1219
  } = props;
1258
1220
  const { onModel, onHarness } = useCoherentHandlers(props);
1259
- const [open, setOpen] = useState6(false);
1221
+ const [open, setOpen] = useState5(false);
1260
1222
  const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
1261
1223
  const selectedModel = models.find((m) => m.id === model);
1262
1224
  const showEffort = selectedModel?.supportsReasoning ?? true;
1263
- const modelPicker = /* @__PURE__ */ jsx8(
1225
+ const modelPicker = /* @__PURE__ */ jsx7(
1264
1226
  ModelPicker,
1265
1227
  {
1266
1228
  value: model,
@@ -1273,15 +1235,15 @@ function AgentSessionControls(props) {
1273
1235
  if (layout === "inline") {
1274
1236
  return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1275
1237
  modelPicker,
1276
- showHarness && /* @__PURE__ */ jsx8(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1277
- showEffort && /* @__PURE__ */ jsx8(EffortPicker, { value: effort, onChange: onEffortChange })
1238
+ showHarness && /* @__PURE__ */ jsx7(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1239
+ showEffort && /* @__PURE__ */ jsx7(EffortPicker, { value: effort, onChange: onEffortChange })
1278
1240
  ] });
1279
1241
  }
1280
1242
  const hasAdvanced = showHarness || showEffort;
1281
1243
  return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1282
1244
  modelPicker,
1283
1245
  hasAdvanced && /* @__PURE__ */ jsxs6("div", { ref: popoverRef, className: "relative inline-flex", children: [
1284
- /* @__PURE__ */ jsx8(
1246
+ /* @__PURE__ */ jsx7(
1285
1247
  "button",
1286
1248
  {
1287
1249
  type: "button",
@@ -1290,19 +1252,19 @@ function AgentSessionControls(props) {
1290
1252
  title: "Model settings \u2014 pick the agent backend and how hard it thinks",
1291
1253
  className: `flex h-8 w-8 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-muted hover:text-foreground data-[state=open]:bg-muted ${FOCUS_RING}`,
1292
1254
  "data-state": open ? "open" : "closed",
1293
- children: /* @__PURE__ */ jsx8(GearGlyph, { className: "h-4 w-4" })
1255
+ children: /* @__PURE__ */ jsx7(GearGlyph, { className: "h-4 w-4" })
1294
1256
  }
1295
1257
  ),
1296
1258
  open && /* @__PURE__ */ jsxs6("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-72 space-y-3 rounded-xl border border-border bg-card p-3 shadow-lg", children: [
1297
1259
  showHarness && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
1298
- /* @__PURE__ */ jsx8("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
1299
- /* @__PURE__ */ jsx8(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1300
- /* @__PURE__ */ jsx8("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
1260
+ /* @__PURE__ */ jsx7("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
1261
+ /* @__PURE__ */ jsx7(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1262
+ /* @__PURE__ */ jsx7("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
1301
1263
  ] }),
1302
1264
  showEffort && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
1303
- /* @__PURE__ */ jsx8("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
1304
- /* @__PURE__ */ jsx8(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
1305
- /* @__PURE__ */ jsx8("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
1265
+ /* @__PURE__ */ jsx7("p", { className: "text-xs font-medium text-foreground", children: "Thinking" }),
1266
+ /* @__PURE__ */ jsx7(EffortPicker, { value: effort, onChange: onEffortChange, label: "" }),
1267
+ /* @__PURE__ */ jsx7("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
1306
1268
  ] })
1307
1269
  ] })
1308
1270
  ] })
@@ -1310,7 +1272,7 @@ function AgentSessionControls(props) {
1310
1272
  }
1311
1273
 
1312
1274
  // src/web-react/index.tsx
1313
- import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1275
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1314
1276
  function formatModelCost(msg, models) {
1315
1277
  if (msg.promptTokens == null && msg.completionTokens == null) return null;
1316
1278
  const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
@@ -1326,39 +1288,39 @@ function formatTokensPerSecond(msg) {
1326
1288
  function RunDrillIn({ run, onClose }) {
1327
1289
  return /* @__PURE__ */ jsxs7("div", { className: "fixed inset-y-0 right-0 z-50 flex w-[480px] max-w-full flex-col border-l border-border bg-card shadow-xl", children: [
1328
1290
  /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
1329
- /* @__PURE__ */ jsx9(
1291
+ /* @__PURE__ */ jsx8(
1330
1292
  "span",
1331
1293
  {
1332
1294
  className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
1333
1295
  }
1334
1296
  ),
1335
1297
  /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
1336
- /* @__PURE__ */ jsx9("p", { className: "truncate text-sm font-semibold", children: run.title }),
1337
- /* @__PURE__ */ jsx9("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
1298
+ /* @__PURE__ */ jsx8("p", { className: "truncate text-sm font-semibold", children: run.title }),
1299
+ /* @__PURE__ */ jsx8("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
1338
1300
  ] }),
1339
- /* @__PURE__ */ jsx9(
1301
+ /* @__PURE__ */ jsx8(
1340
1302
  "button",
1341
1303
  {
1342
1304
  type: "button",
1343
1305
  onClick: onClose,
1344
1306
  "aria-label": "Close",
1345
1307
  className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground",
1346
- children: /* @__PURE__ */ jsx9("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx9("path", { d: "M18 6 6 18M6 6l12 12" }) })
1308
+ children: /* @__PURE__ */ jsx8("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx8("path", { d: "M18 6 6 18M6 6l12 12" }) })
1347
1309
  }
1348
1310
  )
1349
1311
  ] }),
1350
1312
  /* @__PURE__ */ jsxs7("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
1351
- run.steps.length === 0 && /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
1313
+ run.steps.length === 0 && /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
1352
1314
  run.steps.map((step, i) => /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border/60 bg-background", children: [
1353
1315
  /* @__PURE__ */ jsxs7("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
1354
- /* @__PURE__ */ jsx9("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
1355
- /* @__PURE__ */ jsx9("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
1356
- /* @__PURE__ */ jsx9("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
1316
+ /* @__PURE__ */ jsx8("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
1317
+ /* @__PURE__ */ jsx8("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
1318
+ /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
1357
1319
  ] }),
1358
- step.detail && /* @__PURE__ */ jsx9("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap px-3 py-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: step.detail })
1320
+ step.detail && /* @__PURE__ */ jsx8("pre", { className: "max-h-48 overflow-auto whitespace-pre-wrap px-3 py-2 font-mono text-[11px] leading-relaxed text-muted-foreground", children: step.detail })
1359
1321
  ] }, i))
1360
1322
  ] }),
1361
- /* @__PURE__ */ jsx9("p", { className: "border-t border-border px-4 py-2 text-[11px] text-muted-foreground", children: "Readonly drill-in. Follow up in the main chat." })
1323
+ /* @__PURE__ */ jsx8("p", { className: "border-t border-border px-4 py-2 text-[11px] text-muted-foreground", children: "Readonly drill-in. Follow up in the main chat." })
1362
1324
  ] });
1363
1325
  }
1364
1326
  function pendingApprovalOf(call) {
@@ -1373,19 +1335,19 @@ function ChatEmptyState({
1373
1335
  doors
1374
1336
  }) {
1375
1337
  return /* @__PURE__ */ jsxs7("div", { className: "mx-auto flex w-full max-w-2xl flex-col items-center px-6 py-12 text-center sm:py-20", children: [
1376
- /* @__PURE__ */ jsx9("span", { className: "mb-5 inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-primary/10 ring-1 ring-primary/15", children: /* @__PURE__ */ jsx9(BrandMark, { size: 32, className: "shrink-0" }) }),
1377
- /* @__PURE__ */ jsx9("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
1378
- /* @__PURE__ */ jsx9("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
1379
- subline && /* @__PURE__ */ jsx9("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
1380
- doors && doors.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs7(
1338
+ /* @__PURE__ */ jsx8("span", { className: "mb-5 inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-primary/10 ring-1 ring-primary/15", children: /* @__PURE__ */ jsx8(BrandMark, { size: 32, className: "shrink-0" }) }),
1339
+ /* @__PURE__ */ jsx8("p", { className: "text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground", children: productName }),
1340
+ /* @__PURE__ */ jsx8("h2", { className: "mt-1.5 text-balance text-2xl font-semibold leading-tight text-foreground sm:text-[28px]", children: headline }),
1341
+ subline && /* @__PURE__ */ jsx8("p", { className: "mt-3 max-w-md text-[15px] leading-relaxed text-muted-foreground", children: subline }),
1342
+ doors && doors.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-7 grid w-full gap-2.5 sm:grid-cols-3", children: doors.slice(0, 3).map((door, i) => /* @__PURE__ */ jsxs7(
1381
1343
  "button",
1382
1344
  {
1383
1345
  type: "button",
1384
1346
  onClick: door.onSelect,
1385
1347
  className: "group flex min-h-[44px] flex-col items-start rounded-xl border border-border bg-card px-4 py-3 text-left transition hover:border-primary/40 hover:bg-accent/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1386
1348
  children: [
1387
- /* @__PURE__ */ jsx9("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
1388
- door.description && /* @__PURE__ */ jsx9("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
1349
+ /* @__PURE__ */ jsx8("span", { className: "text-sm font-semibold text-foreground", children: door.label }),
1350
+ door.description && /* @__PURE__ */ jsx8("span", { className: "mt-0.5 text-[12px] leading-snug text-muted-foreground", children: door.description })
1389
1351
  ]
1390
1352
  },
1391
1353
  i
@@ -1395,25 +1357,25 @@ function ChatEmptyState({
1395
1357
  function ToolGlyph({ name, className }) {
1396
1358
  if (name.startsWith("sandbox_")) {
1397
1359
  return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1398
- /* @__PURE__ */ jsx9("polyline", { points: "4 17 10 11 4 5" }),
1399
- /* @__PURE__ */ jsx9("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
1360
+ /* @__PURE__ */ jsx8("polyline", { points: "4 17 10 11 4 5" }),
1361
+ /* @__PURE__ */ jsx8("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
1400
1362
  ] });
1401
1363
  }
1402
1364
  if (name === "submit_proposal") {
1403
1365
  return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1404
- /* @__PURE__ */ jsx9("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1405
- /* @__PURE__ */ jsx9("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
1366
+ /* @__PURE__ */ jsx8("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1367
+ /* @__PURE__ */ jsx8("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
1406
1368
  ] });
1407
1369
  }
1408
1370
  if (name === "schedule_followup") {
1409
1371
  return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
1410
- /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "9" }),
1411
- /* @__PURE__ */ jsx9("path", { d: "M12 7v5l3 3" })
1372
+ /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "9" }),
1373
+ /* @__PURE__ */ jsx8("path", { d: "M12 7v5l3 3" })
1412
1374
  ] });
1413
1375
  }
1414
1376
  return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1415
- /* @__PURE__ */ jsx9("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
1416
- /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "4" })
1377
+ /* @__PURE__ */ jsx8("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
1378
+ /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "4" })
1417
1379
  ] });
1418
1380
  }
1419
1381
  function toolOutcomeOf(call) {
@@ -1480,9 +1442,9 @@ function truncate(v, max = 240) {
1480
1442
  function KvRows({ data }) {
1481
1443
  const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
1482
1444
  if (!entries.length) return null;
1483
- return /* @__PURE__ */ jsx9("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs7("div", { className: "contents", children: [
1484
- /* @__PURE__ */ jsx9("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
1485
- /* @__PURE__ */ jsx9("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
1445
+ return /* @__PURE__ */ jsx8("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs7("div", { className: "contents", children: [
1446
+ /* @__PURE__ */ jsx8("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
1447
+ /* @__PURE__ */ jsx8("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
1486
1448
  ] }, k)) });
1487
1449
  }
1488
1450
  function ShellDetail({ call }) {
@@ -1490,26 +1452,26 @@ function ShellDetail({ call }) {
1490
1452
  const r = outcome?.result ?? {};
1491
1453
  return /* @__PURE__ */ jsxs7("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
1492
1454
  /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
1493
- /* @__PURE__ */ jsx9("span", { className: "select-none text-zinc-500", children: "$" }),
1494
- /* @__PURE__ */ jsx9("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
1455
+ /* @__PURE__ */ jsx8("span", { className: "select-none text-zinc-500", children: "$" }),
1456
+ /* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
1495
1457
  r.exitCode != null && /* @__PURE__ */ jsxs7("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
1496
1458
  "exit ",
1497
1459
  r.exitCode
1498
1460
  ] })
1499
1461
  ] }),
1500
- /* @__PURE__ */ jsx9("pre", { className: "max-h-56 overflow-auto whitespace-pre-wrap px-3 pb-2.5 pt-1.5 text-zinc-300", children: outcome?.ok === false ? outcome.message ?? "failed" : [r.stdout, r.stderr].filter(Boolean).join("\n") || "(no output)" })
1462
+ /* @__PURE__ */ jsx8("pre", { className: "max-h-56 overflow-auto whitespace-pre-wrap px-3 pb-2.5 pt-1.5 text-zinc-300", children: outcome?.ok === false ? outcome.message ?? "failed" : [r.stdout, r.stderr].filter(Boolean).join("\n") || "(no output)" })
1501
1463
  ] });
1502
1464
  }
1503
1465
  function DefaultToolDetail({ call }) {
1504
1466
  const outcome = toolOutcomeOf(call);
1505
1467
  return /* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
1506
1468
  call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs7("div", { children: [
1507
- /* @__PURE__ */ jsx9("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
1508
- /* @__PURE__ */ jsx9(KvRows, { data: call.args })
1469
+ /* @__PURE__ */ jsx8("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
1470
+ /* @__PURE__ */ jsx8(KvRows, { data: call.args })
1509
1471
  ] }),
1510
1472
  outcome && /* @__PURE__ */ jsxs7("div", { children: [
1511
- /* @__PURE__ */ jsx9("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
1512
- outcome.ok === false ? /* @__PURE__ */ jsx9("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx9(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx9("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
1473
+ /* @__PURE__ */ jsx8("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
1474
+ outcome.ok === false ? /* @__PURE__ */ jsx8("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx8(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx8("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
1513
1475
  ] })
1514
1476
  ] });
1515
1477
  }
@@ -1520,23 +1482,23 @@ function ProposalCard({
1520
1482
  approval,
1521
1483
  renderers
1522
1484
  }) {
1523
- const [expanded, setExpanded] = useState7(false);
1485
+ const [expanded, setExpanded] = useState6(false);
1524
1486
  const { summary, meta } = proposalPreview(call);
1525
1487
  const custom = renderers?.[call.name]?.(call, message);
1526
1488
  const { pending: deciding, run: decide } = usePending();
1527
1489
  return /* @__PURE__ */ jsxs7("div", { className: "w-full max-w-full rounded-xl border border-warning/50 bg-warning/[0.06] text-sm shadow-sm ring-1 ring-warning/10", children: [
1528
1490
  /* @__PURE__ */ jsxs7("div", { className: "flex items-start gap-2.5 px-4 pt-3.5", children: [
1529
- /* @__PURE__ */ jsx9("span", { className: "mt-0.5 inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-warning/15 text-warning", children: /* @__PURE__ */ jsx9(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
1491
+ /* @__PURE__ */ jsx8("span", { className: "mt-0.5 inline-flex h-6 w-6 shrink-0 items-center justify-center rounded-full bg-warning/15 text-warning", children: /* @__PURE__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5" }) }),
1530
1492
  /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
1531
- /* @__PURE__ */ jsx9("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
1532
- /* @__PURE__ */ jsx9("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
1533
- summary && /* @__PURE__ */ jsx9("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
1534
- meta.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx9("span", { className: "rounded-full bg-muted/60 px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
1493
+ /* @__PURE__ */ jsx8("p", { className: "text-[10px] font-semibold uppercase tracking-wider text-warning-foreground", children: "Needs your approval" }),
1494
+ /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-[15px] font-semibold leading-snug text-foreground", children: friendlyToolTitle(call) }),
1495
+ summary && /* @__PURE__ */ jsx8("p", { className: "mt-1 text-[13px] leading-relaxed text-muted-foreground", children: summary }),
1496
+ meta.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-1.5 flex flex-wrap items-center gap-1.5", children: meta.map((m, i) => /* @__PURE__ */ jsx8("span", { className: "rounded-full bg-muted/60 px-2 py-0.5 text-[11px] font-medium text-muted-foreground", children: m }, i)) })
1535
1497
  ] })
1536
1498
  ] }),
1537
1499
  /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap items-center gap-2 px-4 pb-3.5 pt-3", children: [
1538
1500
  approval ? /* @__PURE__ */ jsxs7(Fragment4, { children: [
1539
- /* @__PURE__ */ jsx9(
1501
+ /* @__PURE__ */ jsx8(
1540
1502
  "button",
1541
1503
  {
1542
1504
  type: "button",
@@ -1546,7 +1508,7 @@ function ProposalCard({
1546
1508
  children: "Approve & run"
1547
1509
  }
1548
1510
  ),
1549
- /* @__PURE__ */ jsx9(
1511
+ /* @__PURE__ */ jsx8(
1550
1512
  "button",
1551
1513
  {
1552
1514
  type: "button",
@@ -1556,7 +1518,7 @@ function ProposalCard({
1556
1518
  children: "Reject"
1557
1519
  }
1558
1520
  )
1559
- ] }) : /* @__PURE__ */ jsx9("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
1521
+ ] }) : /* @__PURE__ */ jsx8("span", { className: "text-[12px] font-medium text-muted-foreground", children: "Awaiting approval\u2026" }),
1560
1522
  /* @__PURE__ */ jsxs7(
1561
1523
  "button",
1562
1524
  {
@@ -1566,12 +1528,12 @@ function ProposalCard({
1566
1528
  className: "ml-auto inline-flex items-center gap-1 rounded text-[12px] font-medium text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1567
1529
  children: [
1568
1530
  expanded ? "Hide details" : "View details",
1569
- /* @__PURE__ */ jsx9(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
1531
+ /* @__PURE__ */ jsx8(ChevronDown, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` })
1570
1532
  ]
1571
1533
  }
1572
1534
  )
1573
1535
  ] }),
1574
- expanded && /* @__PURE__ */ jsx9("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx9(DefaultToolDetail, { call }) })
1536
+ expanded && /* @__PURE__ */ jsx8("div", { className: "border-t border-warning/20 px-4 py-3 text-xs", children: custom ?? /* @__PURE__ */ jsx8(DefaultToolDetail, { call }) })
1575
1537
  ] });
1576
1538
  }
1577
1539
  function FollowupCard({ call }) {
@@ -1579,10 +1541,10 @@ function FollowupCard({ call }) {
1579
1541
  const when = typeof a.when === "string" ? a.when : typeof a.at === "string" ? a.at : typeof a.schedule === "string" ? a.schedule : null;
1580
1542
  return /* @__PURE__ */ jsxs7("div", { className: "w-fit min-w-[260px] max-w-full rounded-lg border border-border/60 border-l-2 border-l-primary/60 bg-muted/20 px-3 py-2 text-sm", children: [
1581
1543
  /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
1582
- /* @__PURE__ */ jsx9(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
1583
- /* @__PURE__ */ jsx9("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
1544
+ /* @__PURE__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-primary/80" }),
1545
+ /* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 truncate font-medium text-foreground", children: friendlyToolTitle(call) })
1584
1546
  ] }),
1585
- when && /* @__PURE__ */ jsx9("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
1547
+ when && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 pl-[22px] text-[12px] text-muted-foreground", children: when })
1586
1548
  ] });
1587
1549
  }
1588
1550
  function ToolCallCard({
@@ -1592,13 +1554,13 @@ function ToolCallCard({
1592
1554
  onOpenRun,
1593
1555
  renderers
1594
1556
  }) {
1595
- const [expanded, setExpanded] = useState7(false);
1557
+ const [expanded, setExpanded] = useState6(false);
1596
1558
  const pending = call.status === "done" ? pendingApprovalOf(call) : null;
1597
1559
  const kind = blockKindOf(call);
1598
1560
  const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
1599
1561
  const custom = renderers?.[call.name]?.(call, message);
1600
1562
  if (pending) {
1601
- return /* @__PURE__ */ jsx9(
1563
+ return /* @__PURE__ */ jsx8(
1602
1564
  ProposalCard,
1603
1565
  {
1604
1566
  call,
@@ -1610,7 +1572,7 @@ function ToolCallCard({
1610
1572
  );
1611
1573
  }
1612
1574
  if (kind === "followup" && !failed) {
1613
- return /* @__PURE__ */ jsx9(FollowupCard, { call });
1575
+ return /* @__PURE__ */ jsx8(FollowupCard, { call });
1614
1576
  }
1615
1577
  const isCommand = kind === "command";
1616
1578
  return /* @__PURE__ */ jsxs7(
@@ -1627,14 +1589,14 @@ function ToolCallCard({
1627
1589
  "aria-expanded": expanded,
1628
1590
  className: "flex min-w-0 flex-1 items-center gap-2 rounded text-left focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1629
1591
  children: [
1630
- /* @__PURE__ */ jsx9(
1592
+ /* @__PURE__ */ jsx8(
1631
1593
  "span",
1632
1594
  {
1633
1595
  className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" : failed ? "bg-destructive" : "bg-success"}`
1634
1596
  }
1635
1597
  ),
1636
- /* @__PURE__ */ jsx9(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
1637
- /* @__PURE__ */ jsx9(
1598
+ /* @__PURE__ */ jsx8(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
1599
+ /* @__PURE__ */ jsx8(
1638
1600
  "span",
1639
1601
  {
1640
1602
  className: `min-w-0 flex-1 truncate ${isCommand ? "font-mono text-[12px] tracking-tight text-foreground/90" : "font-medium"}`,
@@ -1644,8 +1606,8 @@ function ToolCallCard({
1644
1606
  ]
1645
1607
  }
1646
1608
  ),
1647
- /* @__PURE__ */ jsx9("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
1648
- /* @__PURE__ */ jsx9(
1609
+ /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : failed ? "failed" : "done" }),
1610
+ /* @__PURE__ */ jsx8(
1649
1611
  "button",
1650
1612
  {
1651
1613
  type: "button",
@@ -1653,13 +1615,13 @@ function ToolCallCard({
1653
1615
  "aria-label": expanded ? "Collapse details" : "Expand details",
1654
1616
  "aria-expanded": expanded,
1655
1617
  className: "shrink-0 rounded p-0.5 focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1656
- children: /* @__PURE__ */ jsx9(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
1618
+ children: /* @__PURE__ */ jsx8(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
1657
1619
  }
1658
1620
  )
1659
1621
  ] }),
1660
1622
  expanded && /* @__PURE__ */ jsxs7("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
1661
- custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx9(ShellDetail, { call }) : /* @__PURE__ */ jsx9(DefaultToolDetail, { call })),
1662
- onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx9(
1623
+ custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx8(ShellDetail, { call }) : /* @__PURE__ */ jsx8(DefaultToolDetail, { call })),
1624
+ onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx8(
1663
1625
  "button",
1664
1626
  {
1665
1627
  type: "button",
@@ -1674,7 +1636,7 @@ function ToolCallCard({
1674
1636
  );
1675
1637
  }
1676
1638
  function StreamingCaret() {
1677
- return /* @__PURE__ */ jsx9(
1639
+ return /* @__PURE__ */ jsx8(
1678
1640
  "span",
1679
1641
  {
1680
1642
  className: "ml-0.5 inline-block h-[1.1em] w-[3px] translate-y-[2px] animate-pulse rounded-sm bg-foreground/70",
@@ -1693,7 +1655,7 @@ function SegmentText({
1693
1655
  if (!content.trim() && !showCaret) return null;
1694
1656
  return /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
1695
1657
  body,
1696
- showCaret && /* @__PURE__ */ jsx9(StreamingCaret, {})
1658
+ showCaret && /* @__PURE__ */ jsx8(StreamingCaret, {})
1697
1659
  ] });
1698
1660
  }
1699
1661
  function SegmentedBody({
@@ -1712,7 +1674,7 @@ function SegmentedBody({
1712
1674
  const leftoverToolCalls = (msg.toolCalls ?? []).filter(
1713
1675
  (tc) => !segmentToolIds.has(tc.id)
1714
1676
  );
1715
- const renderToolCard = (call) => /* @__PURE__ */ jsx9(
1677
+ const renderToolCard = (call) => /* @__PURE__ */ jsx8(
1716
1678
  ToolCallCard,
1717
1679
  {
1718
1680
  call,
@@ -1725,7 +1687,7 @@ function SegmentedBody({
1725
1687
  );
1726
1688
  return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-2", children: [
1727
1689
  segments.map(
1728
- (seg, i) => seg.kind === "text" ? /* @__PURE__ */ jsx9(
1690
+ (seg, i) => seg.kind === "text" ? /* @__PURE__ */ jsx8(
1729
1691
  SegmentText,
1730
1692
  {
1731
1693
  content: seg.content,
@@ -1737,7 +1699,7 @@ function SegmentedBody({
1737
1699
  ) : renderToolCard(seg.call)
1738
1700
  ),
1739
1701
  leftoverToolCalls.map(renderToolCard),
1740
- streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx9(StreamingCaret, {})
1702
+ streaming && segments[lastIndex]?.kind === "tool" && /* @__PURE__ */ jsx8(StreamingCaret, {})
1741
1703
  ] });
1742
1704
  }
1743
1705
  function AssistantMessageImpl({
@@ -1774,19 +1736,19 @@ function AssistantMessageImpl({
1774
1736
  );
1775
1737
  return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1776
1738
  /* @__PURE__ */ jsxs7("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
1777
- /* @__PURE__ */ jsx9("span", { className: "font-semibold uppercase", children: agentLabel }),
1778
- msg.modelUsed && /* @__PURE__ */ jsx9("span", { className: "font-mono normal-case", children: msg.modelUsed }),
1779
- formatTokensPerSecond(msg) && /* @__PURE__ */ jsx9("span", { children: formatTokensPerSecond(msg) }),
1780
- formatModelCost(msg, models) && /* @__PURE__ */ jsx9("span", { children: formatModelCost(msg, models) })
1739
+ /* @__PURE__ */ jsx8("span", { className: "font-semibold uppercase", children: agentLabel }),
1740
+ msg.modelUsed && /* @__PURE__ */ jsx8("span", { className: "font-mono normal-case", children: msg.modelUsed }),
1741
+ formatTokensPerSecond(msg) && /* @__PURE__ */ jsx8("span", { children: formatTokensPerSecond(msg) }),
1742
+ formatModelCost(msg, models) && /* @__PURE__ */ jsx8("span", { children: formatModelCost(msg, models) })
1781
1743
  ] }),
1782
1744
  reasoning && /* @__PURE__ */ jsxs7("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !hasAnswerText, children: [
1783
- /* @__PURE__ */ jsx9("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsxs7("span", { className: "animate-pulse", children: [
1745
+ /* @__PURE__ */ jsx8("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !hasAnswerText ? /* @__PURE__ */ jsxs7("span", { className: "animate-pulse", children: [
1784
1746
  "Thinking",
1785
1747
  thinkingSeconds >= 3 ? ` \xB7 ${thinkingSeconds}s` : "\u2026"
1786
1748
  ] }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
1787
- /* @__PURE__ */ jsx9("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
1749
+ /* @__PURE__ */ jsx8("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
1788
1750
  ] }),
1789
- segments && segments.length > 0 ? /* @__PURE__ */ jsx9(
1751
+ segments && segments.length > 0 ? /* @__PURE__ */ jsx8(
1790
1752
  SegmentedBody,
1791
1753
  {
1792
1754
  segments,
@@ -1800,9 +1762,9 @@ function AssistantMessageImpl({
1800
1762
  ) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
1801
1763
  /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
1802
1764
  body,
1803
- streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx9(StreamingCaret, {})
1765
+ streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx8(StreamingCaret, {})
1804
1766
  ] }),
1805
- msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx9(
1767
+ msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx8(
1806
1768
  ToolCallCard,
1807
1769
  {
1808
1770
  call: tc,
@@ -1819,7 +1781,7 @@ function AssistantMessageImpl({
1819
1781
  }
1820
1782
  var AssistantMessage = memo(AssistantMessageImpl);
1821
1783
  function useThinkingSeconds(active) {
1822
- const [seconds, setSeconds] = useState7(0);
1784
+ const [seconds, setSeconds] = useState6(0);
1823
1785
  useEffect5(() => {
1824
1786
  if (!active) return;
1825
1787
  setSeconds(0);
@@ -1831,22 +1793,22 @@ function useThinkingSeconds(active) {
1831
1793
  function ThinkingRow({ agentLabel }) {
1832
1794
  const seconds = useThinkingSeconds(true);
1833
1795
  return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1834
- /* @__PURE__ */ jsx9("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
1796
+ /* @__PURE__ */ jsx8("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
1835
1797
  /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
1836
- /* @__PURE__ */ jsx9("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx9("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
1798
+ /* @__PURE__ */ jsx8("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx8("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
1837
1799
  "Thinking",
1838
1800
  seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
1839
1801
  ] })
1840
1802
  ] });
1841
1803
  }
1842
1804
  function StreamErrorRow({ message, onRetry }) {
1843
- return /* @__PURE__ */ jsx9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { role: "alert", className: "flex items-start gap-2.5 rounded-lg border border-destructive/40 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
1805
+ return /* @__PURE__ */ jsx8("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { role: "alert", className: "flex items-start gap-2.5 rounded-lg border border-destructive/40 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
1844
1806
  /* @__PURE__ */ jsxs7("svg", { className: "mt-0.5 h-4 w-4 shrink-0", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1845
- /* @__PURE__ */ jsx9("circle", { cx: "12", cy: "12", r: "9" }),
1846
- /* @__PURE__ */ jsx9("path", { d: "M12 8v4m0 4h.01" })
1807
+ /* @__PURE__ */ jsx8("circle", { cx: "12", cy: "12", r: "9" }),
1808
+ /* @__PURE__ */ jsx8("path", { d: "M12 8v4m0 4h.01" })
1847
1809
  ] }),
1848
- /* @__PURE__ */ jsx9("span", { className: "min-w-0 flex-1 break-words", children: message }),
1849
- onRetry && /* @__PURE__ */ jsx9(
1810
+ /* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1 break-words", children: message }),
1811
+ onRetry && /* @__PURE__ */ jsx8(
1850
1812
  "button",
1851
1813
  {
1852
1814
  type: "button",
@@ -1875,12 +1837,12 @@ function ChatMessages({
1875
1837
  header
1876
1838
  }) {
1877
1839
  const renderBody = useMemo3(
1878
- () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx9("p", { className: "whitespace-pre-wrap", children: content })),
1840
+ () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx8("p", { className: "whitespace-pre-wrap", children: content })),
1879
1841
  [renderMarkdown]
1880
1842
  );
1881
1843
  const lastIsUser = messages[messages.length - 1]?.role === "user";
1882
1844
  if (messages.length === 0 && !loading && !error) {
1883
- const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx9(ChatEmptyState, { ...emptyState });
1845
+ const empty = renderEmpty ? renderEmpty() : /* @__PURE__ */ jsx8(ChatEmptyState, { ...emptyState });
1884
1846
  return /* @__PURE__ */ jsxs7(Fragment4, { children: [
1885
1847
  header,
1886
1848
  empty
@@ -1889,10 +1851,10 @@ function ChatMessages({
1889
1851
  return /* @__PURE__ */ jsxs7(Fragment4, { children: [
1890
1852
  header,
1891
1853
  messages.map(
1892
- (msg) => msg.role === "user" ? /* @__PURE__ */ jsx9("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { className: "ml-auto w-fit max-w-[85%]", children: [
1893
- /* @__PURE__ */ jsx9("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
1894
- /* @__PURE__ */ jsx9("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx9("p", { className: "whitespace-pre-wrap", children: msg.content }) })
1895
- ] }) }, msg.id) : /* @__PURE__ */ jsx9(
1854
+ (msg) => msg.role === "user" ? /* @__PURE__ */ jsx8("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs7("div", { className: "ml-auto w-fit max-w-[85%]", children: [
1855
+ /* @__PURE__ */ jsx8("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
1856
+ /* @__PURE__ */ jsx8("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx8("p", { className: "whitespace-pre-wrap", children: msg.content }) })
1857
+ ] }) }, msg.id) : /* @__PURE__ */ jsx8(
1896
1858
  AssistantMessage,
1897
1859
  {
1898
1860
  msg,
@@ -1908,8 +1870,8 @@ function ChatMessages({
1908
1870
  msg.id
1909
1871
  )
1910
1872
  ),
1911
- loading && lastIsUser && /* @__PURE__ */ jsx9(ThinkingRow, { agentLabel }),
1912
- error && !loading && /* @__PURE__ */ jsx9(StreamErrorRow, { message: error, onRetry })
1873
+ loading && lastIsUser && /* @__PURE__ */ jsx8(ThinkingRow, { agentLabel }),
1874
+ error && !loading && /* @__PURE__ */ jsx8(StreamErrorRow, { message: error, onRetry })
1913
1875
  ] });
1914
1876
  }
1915
1877
 
@@ -1934,9 +1896,6 @@ export {
1934
1896
  FlowWaterfall,
1935
1897
  MissionActivityLane,
1936
1898
  AgentActivityPanel,
1937
- useSandboxTerminalConnection,
1938
- tabTerminalConnectionId,
1939
- WorkspaceTerminalPanel,
1940
1899
  SeatPaywall,
1941
1900
  AgentSessionControls,
1942
1901
  formatModelCost,
@@ -1947,4 +1906,4 @@ export {
1947
1906
  useThinkingSeconds,
1948
1907
  ChatMessages
1949
1908
  };
1950
- //# sourceMappingURL=chunk-7DPQ5VWR.js.map
1909
+ //# sourceMappingURL=chunk-VKHB7VP4.js.map