import {
  stepActivityFlowTrace
} from "../chunk-2QI7XV2T.js";
import {
  snapHarnessToModel,
  snapModelToHarness
} from "../chunk-5VXPDXZJ.js";

// src/web-react/index.tsx
import { useEffect as useEffect5, useMemo as useMemo3, useRef as useRef4, useState as useState6, memo } from "react";

// src/web-react/smooth-text.ts
import { useEffect, useRef, useState } from "react";
function nextRevealCount(shown, targetLength, dtMs, opts = {}) {
  if (shown >= targetLength) return targetLength;
  const base = opts.baseCharsPerSecond ?? 90;
  const catchUp = opts.catchUpPerChar ?? 5;
  const max = opts.maxCharsPerSecond ?? 2400;
  const backlog = targetLength - shown;
  const rate = Math.min(max, base + backlog * catchUp);
  return Math.min(targetLength, shown + rate * dtMs / 1e3);
}
function useSmoothText(target, enabled, opts) {
  const [, force] = useState(0);
  const shownRef = useRef(0);
  const lastTargetRef = useRef("");
  if (!target.startsWith(lastTargetRef.current.slice(0, Math.floor(shownRef.current)))) {
    shownRef.current = 0;
  }
  lastTargetRef.current = target;
  if (!enabled) shownRef.current = target.length;
  useEffect(() => {
    if (!enabled) return;
    let raf = 0;
    let last = null;
    const tick = (t) => {
      const dt = last == null ? 16 : Math.min(t - last, 100);
      last = t;
      const targetLen = lastTargetRef.current.length;
      if (shownRef.current < targetLen) {
        shownRef.current = nextRevealCount(shownRef.current, targetLen, dt, opts);
        force((n) => n + 1);
        raf = requestAnimationFrame(tick);
      }
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [enabled, target]);
  return target.slice(0, Math.floor(shownRef.current));
}

// src/web-react/controls.tsx
import { useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";

// src/web-react/provider-logo.tsx
import { jsx, jsxs } from "react/jsx-runtime";
var LOGOS = {
  anthropic: { viewBox: "0 0 24 24", fill: "#D97757", paths: ["M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z"] },
  google: { viewBox: "0 0 24 24", fill: "#8E75B2", paths: ["M11.04 19.32Q12 21.51 12 24q0-2.49.93-4.68.96-2.19 2.58-3.81t3.81-2.55Q21.51 12 24 12q-2.49 0-4.68-.93a12.3 12.3 0 0 1-3.81-2.58 12.3 12.3 0 0 1-2.58-3.81Q12 2.49 12 0q0 2.49-.96 4.68-.93 2.19-2.55 3.81a12.3 12.3 0 0 1-3.81 2.58Q2.49 12 0 12q2.49 0 4.68.96 2.19.93 3.81 2.55t2.55 3.81"] },
  deepseek: { viewBox: "0 0 24 24", fill: "#4D6BFE", paths: ["M23.748 4.651c-.254-.124-.364.113-.512.233-.051.04-.094.09-.137.137-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.155-.708-.311-.955-.65-.172-.24-.219-.509-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.094.172.187.129.323-.082.28-.18.553-.266.833-.055.179-.137.218-.328.14a5.5 5.5 0 0 1-1.737-1.179c-.857-.828-1.631-1.743-2.597-2.46a12 12 0 0 0-.689-.47c-.985-.957.13-1.743.387-1.836.27-.098.094-.433-.778-.428-.872.003-1.67.295-2.687.685a3 3 0 0 1-.465.136 9.6 9.6 0 0 0-2.883-.101c-1.885.21-3.39 1.1-4.497 2.622C.082 8.776-.231 10.854.152 13.02c.403 2.284 1.568 4.175 3.36 5.653 1.857 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.132-.284 4.994-1.86.47.234.962.328 1.78.398.629.058 1.235-.031 1.705-.129.735-.155.684-.836.418-.961-2.155-1.004-1.682-.595-2.112-.926 1.095-1.295 2.768-3.598 3.284-6.733.05-.346.115-.834.108-1.114-.004-.171.035-.238.23-.257a4.2 4.2 0 0 0 1.545-.475c1.397-.763 1.96-2.016 2.093-3.517.02-.23-.004-.467-.247-.588M11.58 18.168c-2.088-1.642-3.101-2.183-3.52-2.16-.39.024-.32.472-.234.763.09.288.207.487.371.74.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.168-1.361-.801-2.5-1.86-3.301-3.306-.775-1.393-1.225-2.888-1.299-4.482-.02-.385.094-.522.477-.592a4.7 4.7 0 0 1 1.53-.038c2.131.311 3.946 1.264 5.467 2.774.868.86 1.525 1.887 2.202 2.89.72 1.066 1.494 2.082 2.48 2.915.348.291.626.513.892.677-.802.09-2.14.109-3.055-.615zm1.001-6.44a.306.306 0 0 1 .415-.287.3.3 0 0 1 .113.074.3.3 0 0 1 .086.214c0 .17-.136.307-.308.307a.303.303 0 0 1-.306-.307m3.11 1.596c-.2.081-.4.151-.591.16a1.25 1.25 0 0 1-.798-.254c-.274-.23-.47-.358-.551-.758a1.7 1.7 0 0 1 .015-.588c.07-.327-.007-.537-.238-.727-.188-.156-.426-.199-.689-.199a.6.6 0 0 1-.254-.078.253.253 0 0 1-.114-.358 1 1 0 0 1 .192-.21c.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.392.451.462.576.685.915.176.264.336.536.446.848.066.194-.02.353-.25.45"] },
  mistral: { viewBox: "0 0 24 24", fill: "#FA520F", paths: ["M17.143 3.429v3.428h-3.429v3.429h-3.428V6.857H6.857V3.43H3.43v13.714H0v3.428h10.286v-3.428H6.857v-3.429h3.429v3.429h3.429v-3.429h3.428v3.429h-3.428v3.428H24v-3.428h-3.43V3.429z"] },
  xai: { viewBox: "0 0 24 24", fill: "#000000", paths: ["M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.182z"] },
  nvidia: { viewBox: "0 0 24 24", fill: "#76B900", paths: ["M8.948 8.798v-1.43a6.7 6.7 0 0 1 .424-.018c3.922-.124 6.493 3.374 6.493 3.374s-2.774 3.851-5.75 3.851c-.398 0-.787-.062-1.158-.185v-4.346c1.528.185 1.837.857 2.747 2.385l2.04-1.714s-1.492-1.952-4-1.952a6.016 6.016 0 0 0-.796.035m0-4.735v2.138l.424-.027c5.45-.185 9.01 4.47 9.01 4.47s-4.08 4.964-8.33 4.964c-.37 0-.733-.035-1.095-.097v1.325c.3.035.61.062.91.062 3.957 0 6.82-2.023 9.593-4.408.459.371 2.34 1.263 2.73 1.652-2.633 2.208-8.772 3.984-12.253 3.984-.335 0-.653-.018-.971-.053v1.864H24V4.063zm0 10.326v1.131c-3.657-.654-4.673-4.46-4.673-4.46s1.758-1.944 4.673-2.262v1.237H8.94c-1.528-.186-2.73 1.245-2.73 1.245s.68 2.412 2.739 3.11M2.456 10.9s2.164-3.197 6.5-3.533V6.201C4.153 6.59 0 10.653 0 10.653s2.35 6.802 8.948 7.42v-1.237c-4.84-.6-6.492-5.936-6.492-5.936z"] },
  meta: { viewBox: "0 0 24 24", fill: "#0467DF", paths: ["M6.915 4.03c-1.968 0-3.683 1.28-4.871 3.113C.704 9.208 0 11.883 0 14.449c0 .706.07 1.369.21 1.973a6.624 6.624 0 0 0 .265.86 5.297 5.297 0 0 0 .371.761c.696 1.159 1.818 1.927 3.593 1.927 1.497 0 2.633-.671 3.965-2.444.76-1.012 1.144-1.626 2.663-4.32l.756-1.339.186-.325c.061.1.121.196.183.3l2.152 3.595c.724 1.21 1.665 2.556 2.47 3.314 1.046.987 1.992 1.22 3.06 1.22 1.075 0 1.876-.355 2.455-.843a3.743 3.743 0 0 0 .81-.973c.542-.939.861-2.127.861-3.745 0-2.72-.681-5.357-2.084-7.45-1.282-1.912-2.957-2.93-4.716-2.93-1.047 0-2.088.467-3.053 1.308-.652.57-1.257 1.29-1.82 2.05-.69-.875-1.335-1.547-1.958-2.056-1.182-.966-2.315-1.303-3.454-1.303zm10.16 2.053c1.147 0 2.188.758 2.992 1.999 1.132 1.748 1.647 4.195 1.647 6.4 0 1.548-.368 2.9-1.839 2.9-.58 0-1.027-.23-1.664-1.004-.496-.601-1.343-1.878-2.832-4.358l-.617-1.028a44.908 44.908 0 0 0-1.255-1.98c.07-.109.141-.224.211-.327 1.12-1.667 2.118-2.602 3.358-2.602zm-10.201.553c1.265 0 2.058.791 2.675 1.446.307.327.737.871 1.234 1.579l-1.02 1.566c-.757 1.163-1.882 3.017-2.837 4.338-1.191 1.649-1.81 1.817-2.486 1.817-.524 0-1.038-.237-1.383-.794-.263-.426-.464-1.13-.464-2.046 0-2.221.63-4.535 1.66-6.088.454-.687.964-1.226 1.533-1.533a2.264 2.264 0 0 1 1.088-.285z"] },
  moonshotai: { viewBox: "0 0 24 24", fill: "#16191E", paths: ["m1.053 16.91 9.538 2.55a21 20.981 0 0 0 .06 2.031l5.956 1.592a12 11.99 0 0 1-15.554-6.172m-1.02-5.79 11.352 3.035a21 20.981 0 0 0-.469 2.01l10.817 2.89a12 11.99 0 0 1-1.845 2.004L.658 15.918a12 11.99 0 0 1-.625-4.796m1.593-5.146L13.573 9.17a21 20.981 0 0 0-1.01 1.874l11.297 3.02a21 20.981 0 0 1-.67 2.362l-11.55-3.087L.125 10.26a12 11.99 0 0 1 1.499-4.285ZM6.067 1.58l11.285 3.016a21 20.981 0 0 0-1.688 1.719l7.824 2.091a21 20.981 0 0 1 .513 2.664L2.107 5.218a12 11.99 0 0 1 3.96-3.638M21.68 4.866 7.222 1.003A12 11.99 0 0 1 21.68 4.866"] },
  openai: { viewBox: "0 0 256 260", fill: "#10A37F", paths: ["M239.184 106.203a64.72 64.72 0 0 0-5.576-53.103C219.452 28.459 191 15.784 163.213 21.74A65.586 65.586 0 0 0 52.096 45.22a64.72 64.72 0 0 0-43.23 31.36c-14.31 24.602-11.061 55.634 8.033 76.74a64.67 64.67 0 0 0 5.525 53.102c14.174 24.65 42.644 37.324 70.446 31.36a64.72 64.72 0 0 0 48.754 21.744c28.481.025 53.714-18.361 62.414-45.481a64.77 64.77 0 0 0 43.229-31.36c14.137-24.558 10.875-55.423-8.083-76.483m-97.56 136.338a48.4 48.4 0 0 1-31.105-11.255l1.535-.87l51.67-29.825a8.6 8.6 0 0 0 4.247-7.367v-72.85l21.845 12.636c.218.111.37.32.409.563v60.367c-.056 26.818-21.783 48.545-48.601 48.601M37.158 197.93a48.35 48.35 0 0 1-5.781-32.589l1.534.921l51.722 29.826a8.34 8.34 0 0 0 8.441 0l63.181-36.425v25.221a.87.87 0 0 1-.358.665l-52.335 30.184c-23.257 13.398-52.97 5.431-66.404-17.803M23.549 85.38a48.5 48.5 0 0 1 25.58-21.333v61.39a8.29 8.29 0 0 0 4.195 7.316l62.874 36.272l-21.845 12.636a.82.82 0 0 1-.767 0L41.353 151.53c-23.211-13.454-31.171-43.144-17.804-66.405zm179.466 41.695l-63.08-36.63L161.73 77.86a.82.82 0 0 1 .768 0l52.233 30.184a48.6 48.6 0 0 1-7.316 87.635v-61.391a8.54 8.54 0 0 0-4.4-7.213m21.742-32.69l-1.535-.922l-51.619-30.081a8.39 8.39 0 0 0-8.492 0L99.98 99.808V74.587a.72.72 0 0 1 .307-.665l52.233-30.133a48.652 48.652 0 0 1 72.236 50.391zM88.061 139.097l-21.845-12.585a.87.87 0 0 1-.41-.614V65.685a48.652 48.652 0 0 1 79.757-37.346l-1.535.87l-51.67 29.825a8.6 8.6 0 0 0-4.246 7.367zm11.868-25.58L128.067 97.3l28.188 16.218v32.434l-28.086 16.218l-28.188-16.218z"] }
};
var ALIASES = {
  moonshot: "moonshotai",
  deepseek_ai: "deepseek",
  "x-ai": "xai",
  "meta-llama": "meta"
};
var MONOGRAM = {
  cohere: { bg: "#fae8ff", fg: "#c026d3" },
  groq: { bg: "#fce7f3", fg: "#db2777" },
  cerebras: { bg: "#ccfbf1", fg: "#0d9488" },
  zai: { bg: "#ede9fe", fg: "#7c3aed" },
  "z-ai": { bg: "#ede9fe", fg: "#7c3aed" },
  tuner: { bg: "#dbeafe", fg: "#2563eb" }
};
function ProviderLogo({ provider, size = 16 }) {
  const key = ALIASES[provider ?? ""] ?? provider ?? "";
  const logo = LOGOS[key];
  if (logo) {
    return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: logo.viewBox, role: "img", "aria-label": key, children: logo.paths.map((d, i) => /* @__PURE__ */ jsx("path", { d, fill: logo.fill }, i)) });
  }
  const mono = MONOGRAM[key] ?? { bg: "#f3f4f6", fg: "#6b7280" };
  return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 16 16", role: "img", "aria-label": key || "model", children: [
    /* @__PURE__ */ jsx("rect", { width: "16", height: "16", rx: "4", fill: mono.bg }),
    /* @__PURE__ */ jsx("text", { x: "8", y: "11.6", textAnchor: "middle", fill: mono.fg, fontSize: "9", fontWeight: "700", fontFamily: "system-ui, sans-serif", children: (key || "?").charAt(0).toUpperCase() })
  ] });
}

// src/web-react/controls.tsx
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
function ChevronDown({ className }) {
  return /* @__PURE__ */ jsx2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6" }) });
}
function SearchGlyph({ className }) {
  return /* @__PURE__ */ jsxs2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
    /* @__PURE__ */ jsx2("circle", { cx: "11", cy: "11", r: "8" }),
    /* @__PURE__ */ jsx2("path", { d: "m21 21-4.3-4.3" })
  ] });
}
function SparkleGlyph({ className }) {
  return /* @__PURE__ */ jsx2("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx2("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3M5.6 5.6l2.1 2.1m8.6 8.6 2.1 2.1m0-12.8-2.1 2.1M7.7 16.3l-2.1 2.1" }) });
}
function usePopover(open, setOpen) {
  const containerRef = useRef2(null);
  const triggerRef = useRef2(null);
  useEffect2(() => {
    if (!open) return;
    function onMouseDown(e) {
      if (containerRef.current && !containerRef.current.contains(e.target)) setOpen(false);
    }
    function onKeyDown(e) {
      if (e.key === "Escape") {
        setOpen(false);
        triggerRef.current?.focus();
      }
    }
    document.addEventListener("mousedown", onMouseDown);
    document.addEventListener("keydown", onKeyDown);
    return () => {
      document.removeEventListener("mousedown", onMouseDown);
      document.removeEventListener("keydown", onKeyDown);
    };
  }, [open, setOpen]);
  return {
    containerRef,
    triggerRef,
    triggerProps: {
      ref: triggerRef,
      "aria-haspopup": true,
      "aria-expanded": open
    }
  };
}
var POPOVER_OPTION_FOCUS = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-card";
function usePending() {
  const [pending, setPending] = useState2(false);
  const inFlight = useRef2(false);
  const mounted = useRef2(true);
  useEffect2(() => {
    mounted.current = true;
    return () => {
      mounted.current = false;
    };
  }, []);
  const run = (action) => {
    if (inFlight.current) return;
    let result;
    try {
      result = action();
    } catch {
      return;
    }
    if (!(result instanceof Promise)) return;
    inFlight.current = true;
    setPending(true);
    void result.finally(() => {
      inFlight.current = false;
      if (mounted.current) setPending(false);
    });
  };
  return { pending, run };
}
function formatPrice(p) {
  if (!p) return void 0;
  const n = Number(p);
  if (isNaN(n) || n === 0) return void 0;
  const perM = n * 1e6;
  return perM >= 1 ? `$${perM.toFixed(0)}/M` : `$${perM.toFixed(2)}/M`;
}
function formatContext(len) {
  if (!len) return void 0;
  if (len >= 1e6) return `${(len / 1e6).toFixed(1)}M ctx`;
  if (len >= 1e3) return `${Math.round(len / 1e3)}K ctx`;
  return `${len} ctx`;
}
function SectionHeader({ children }) {
  return /* @__PURE__ */ jsx2("div", { className: "px-3 pb-1 pt-3 text-xs font-semibold uppercase tracking-wide text-muted-foreground", children });
}
function ModelRow({
  model,
  selected,
  onSelect,
  renderProviderBadge
}) {
  const price = formatPrice(model.pricing?.prompt);
  const ctx = formatContext(model.contextLength);
  return /* @__PURE__ */ jsxs2(
    "button",
    {
      type: "button",
      onClick: onSelect,
      className: `flex w-full items-center gap-2.5 rounded-md px-3 py-2.5 text-left text-sm transition ${POPOVER_OPTION_FOCUS} ${selected ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
      children: [
        renderProviderBadge ? renderProviderBadge(model.provider) : /* @__PURE__ */ jsx2(ProviderLogo, { provider: model.provider, size: 16 }),
        /* @__PURE__ */ jsx2("span", { className: "truncate", children: model.name }),
        !model.supportsTools && /* @__PURE__ */ jsx2("span", { className: "shrink-0 rounded bg-muted/60 px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground", children: "no tools" }),
        /* @__PURE__ */ jsxs2("span", { className: "ml-auto flex shrink-0 items-center gap-2 text-xs text-muted-foreground", children: [
          ctx && /* @__PURE__ */ jsx2("span", { children: ctx }),
          price && /* @__PURE__ */ jsx2("span", { children: price })
        ] })
      ]
    }
  );
}
function ModelPicker({ value, onChange, models, loading, renderProviderBadge, recommendedLabel = "Recommended" }) {
  const [open, setOpen] = useState2(false);
  const [query, setQuery] = useState2("");
  const { containerRef, triggerProps } = usePopover(open, setOpen);
  const inputRef = useRef2(null);
  useEffect2(() => {
    if (open) inputRef.current?.focus();
  }, [open]);
  const selected = models.find((m) => m.id === value);
  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return null;
    return models.filter(
      (m) => m.id.toLowerCase().includes(q) || m.name.toLowerCase().includes(q) || (m.description?.toLowerCase() ?? "").includes(q) || m.provider.toLowerCase().includes(q)
    );
  }, [models, query]);
  const sections = useMemo(() => {
    const recommended = models.filter((m) => m.featured);
    const byProvider = [];
    for (const m of models) {
      if (m.featured) continue;
      const last = byProvider[byProvider.length - 1];
      if (last && last.provider === m.provider) last.items.push(m);
      else byProvider.push({ provider: m.provider, items: [m] });
    }
    return { recommended, byProvider };
  }, [models]);
  const select = (id) => {
    onChange(id);
    setOpen(false);
    setQuery("");
  };
  return /* @__PURE__ */ jsxs2("div", { ref: containerRef, className: "relative inline-flex", children: [
    /* @__PURE__ */ jsxs2(
      "button",
      {
        type: "button",
        ...triggerProps,
        onClick: () => setOpen(!open),
        className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
        children: [
          selected ? renderProviderBadge ? renderProviderBadge(selected.provider) : /* @__PURE__ */ jsx2(ProviderLogo, { provider: selected.provider, size: 16 }) : /* @__PURE__ */ jsx2(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
          /* @__PURE__ */ jsx2("span", { className: "max-w-[160px] truncate", children: selected?.name ?? value }),
          /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
        ]
      }
    ),
    open && /* @__PURE__ */ jsxs2("div", { className: "absolute bottom-full left-0 z-50 mb-2 w-[420px] overflow-hidden rounded-xl border border-border bg-card shadow-lg", children: [
      /* @__PURE__ */ jsx2("div", { className: "border-b border-border px-3 py-2", children: /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2 rounded-lg border border-border bg-background px-3 py-2", children: [
        /* @__PURE__ */ jsx2(SearchGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
        /* @__PURE__ */ jsx2(
          "input",
          {
            ref: inputRef,
            type: "text",
            value: query,
            onChange: (e) => setQuery(e.target.value),
            placeholder: "Search models...",
            className: "flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground"
          }
        )
      ] }) }),
      /* @__PURE__ */ jsxs2("div", { className: "max-h-[400px] overflow-y-auto p-1 pb-2", children: [
        loading && /* @__PURE__ */ jsx2("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "Loading models..." }),
        !loading && filtered && /* @__PURE__ */ jsxs2(Fragment, { children: [
          filtered.length === 0 && /* @__PURE__ */ jsx2("div", { className: "px-3 py-4 text-center text-sm text-muted-foreground", children: "No models match your search" }),
          filtered.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
        ] }),
        !loading && !filtered && /* @__PURE__ */ jsxs2(Fragment, { children: [
          sections.recommended.length > 0 && /* @__PURE__ */ jsxs2(Fragment, { children: [
            /* @__PURE__ */ jsx2(SectionHeader, { children: recommendedLabel }),
            sections.recommended.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
          ] }),
          sections.byProvider.map((g) => /* @__PURE__ */ jsxs2("div", { children: [
            /* @__PURE__ */ jsx2(SectionHeader, { children: g.provider }),
            g.items.map((m) => /* @__PURE__ */ jsx2(ModelRow, { model: m, selected: m.id === value, onSelect: () => select(m.id), renderProviderBadge }, m.id))
          ] }, g.provider))
        ] })
      ] })
    ] })
  ] });
}
var EFFORT_LEVELS = [
  { id: "off", label: "Off" },
  { id: "low", label: "Low" },
  { id: "medium", label: "Medium" },
  { id: "high", label: "High" }
];
function EffortPicker({ value, onChange }) {
  const [open, setOpen] = useState2(false);
  const { containerRef, triggerProps } = usePopover(open, setOpen);
  const selected = EFFORT_LEVELS.find((l) => l.id === value) ?? EFFORT_LEVELS[2];
  return /* @__PURE__ */ jsxs2("div", { ref: containerRef, className: "relative inline-flex", children: [
    /* @__PURE__ */ jsxs2(
      "button",
      {
        type: "button",
        ...triggerProps,
        onClick: () => setOpen(!open),
        title: "Reasoning effort",
        className: "inline-flex items-center gap-1.5 rounded-full border border-border bg-card px-3 py-1.5 text-sm font-medium text-foreground transition hover:bg-accent/30 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background",
        children: [
          /* @__PURE__ */ jsx2(SparkleGlyph, { className: "h-3.5 w-3.5 text-muted-foreground" }),
          /* @__PURE__ */ jsx2("span", { children: selected.label }),
          /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
        ]
      }
    ),
    open && /* @__PURE__ */ jsx2("div", { role: "menu", className: "absolute bottom-full left-0 z-50 mb-2 w-36 overflow-hidden rounded-xl border border-border bg-card p-1 shadow-lg", children: EFFORT_LEVELS.map((l) => /* @__PURE__ */ jsx2(
      "button",
      {
        type: "button",
        role: "menuitemradio",
        "aria-checked": l.id === value,
        onClick: () => {
          onChange(l.id);
          setOpen(false);
        },
        className: `flex w-full items-center rounded-md px-3 py-2 text-left text-sm transition ${POPOVER_OPTION_FOCUS} ${l.id === value ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
        children: l.label
      },
      l.id
    )) })
  ] });
}

// src/web-react/chat-stream.ts
function dispatchChatStreamLine(line, cb) {
  let receivedContent = false;
  let turnId;
  if (!line.trim()) return { receivedContent };
  let parsed;
  try {
    parsed = JSON.parse(line);
  } catch {
    return { receivedContent };
  }
  if (parsed.kind === "tool_result") {
    cb.onToolResult?.({
      toolCallId: parsed.toolCallId,
      toolName: parsed.toolName,
      label: parsed.label,
      outcome: parsed.outcome ?? parsed.result
    });
    return { receivedContent: true };
  }
  const evt = parsed.kind === "event" ? parsed.event : parsed;
  if (!evt || typeof evt !== "object") return { receivedContent };
  switch (evt.type) {
    case "turn":
      if (typeof evt.turnId === "string") turnId = evt.turnId;
      break;
    case "text":
      if (typeof evt.text === "string") {
        cb.onText?.(evt.text);
        receivedContent = true;
      }
      break;
    case "reasoning":
      if (typeof evt.text === "string") {
        cb.onReasoning?.(evt.text);
        receivedContent = true;
      }
      break;
    case "tool_call": {
      const call = evt.call ?? evt;
      cb.onToolCall?.({
        toolCallId: call.toolCallId ?? call.id,
        toolName: String(call.toolName ?? call.name ?? "unknown"),
        args: call.args ?? {}
      });
      receivedContent = true;
      break;
    }
    case "tool_result":
      cb.onToolResult?.({
        toolCallId: evt.toolCallId,
        toolName: evt.toolName,
        label: evt.label,
        outcome: evt.outcome ?? evt.result
      });
      receivedContent = true;
      break;
    case "usage": {
      const u = evt.usage;
      if (u) cb.onUsage?.({ promptTokens: u.promptTokens ?? 0, completionTokens: u.completionTokens ?? 0 });
      break;
    }
    case "metadata":
      cb.onMetadata?.(evt.data ?? {});
      break;
    case "error":
      cb.onErrorEvent?.(String(evt.details ?? evt.error ?? "Unknown stream error"));
      break;
    default:
      break;
  }
  return { turnId, receivedContent };
}
async function consumeChatStream(body, cb) {
  const reader = body.getReader();
  const decoder = new TextDecoder();
  let buffer = "";
  let turnId = null;
  let receivedContent = false;
  const handle = (line) => {
    const r = dispatchChatStreamLine(line, cb);
    if (r.turnId) {
      turnId = r.turnId;
      cb.onTurnId?.(r.turnId);
    }
    if (r.receivedContent) receivedContent = true;
  };
  for (; ; ) {
    const { done, value } = await reader.read();
    if (done) {
      if (buffer.trim()) handle(buffer);
      break;
    }
    buffer += decoder.decode(value, { stream: true });
    const lines = buffer.split("\n");
    buffer = lines.pop() ?? "";
    for (const line of lines) handle(line);
  }
  return { turnId, receivedContent };
}
async function streamChatTurn(opts) {
  const res = await opts.start();
  if (!res.ok || !res.body) {
    const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
    throw new Error(err.error ?? `HTTP ${res.status}`);
  }
  let turnId = null;
  const cb = {
    ...opts.callbacks,
    onTurnId: (id) => {
      turnId = id;
      opts.callbacks.onTurnId?.(id);
    }
  };
  try {
    return await consumeChatStream(res.body, cb);
  } catch (transportErr) {
    if (!turnId || !opts.resume) throw transportErr;
    opts.onResetForResume?.();
    const resumed = await opts.resume(turnId, 0);
    if (!resumed.ok || !resumed.body) throw transportErr;
    return await consumeChatStream(resumed.body, cb);
  }
}

// src/web-react/mission-activity.tsx
import { useCallback, useEffect as useEffect3, useState as useState3 } from "react";
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
var LIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "running"]);
var OK_STATUSES = /* @__PURE__ */ new Set(["completed", "done", "succeeded"]);
var ERROR_STATUSES = /* @__PURE__ */ new Set(["failed", "error", "cancelled", "aborted"]);
function activityTone(status) {
  const s = status.toLowerCase();
  if (LIVE_STATUSES.has(s)) return "live";
  if (OK_STATUSES.has(s)) return "ok";
  if (ERROR_STATUSES.has(s)) return "error";
  return "neutral";
}
function formatActivityCost(costUsd) {
  if (costUsd === void 0 || !isFinite(costUsd) || costUsd <= 0) return null;
  return costUsd < 0.01 ? `$${costUsd.toFixed(4)}` : `$${costUsd.toFixed(2)}`;
}
function formatActivityDuration(durationMs) {
  if (durationMs === void 0 || !isFinite(durationMs) || durationMs < 0) return null;
  const totalSeconds = Math.round(durationMs / 1e3);
  if (totalSeconds < 60) return `${totalSeconds}s`;
  const minutes = Math.floor(totalSeconds / 60);
  const seconds = totalSeconds % 60;
  if (minutes < 60) return `${minutes}m ${String(seconds).padStart(2, "0")}s`;
  return `${Math.floor(minutes / 60)}h ${String(minutes % 60).padStart(2, "0")}m`;
}
function mergeActivityPages(existing, incoming) {
  const byTask = /* @__PURE__ */ new Map();
  for (const row of existing) byTask.set(row.taskId, row);
  for (const row of incoming) byTask.set(row.taskId, row);
  return [...byTask.values()].sort((a, b) => Date.parse(b.startedAt) - Date.parse(a.startedAt));
}
function waterfallLayout(trace) {
  const total = trace.totalMs > 0 ? trace.totalMs : 1;
  return [...trace.spans].sort((a, b) => a.startMs - b.startMs).map((span) => {
    const meta = span.meta ?? {};
    const failed = meta.ok === false || typeof meta.status === "string" && activityTone(meta.status) === "error";
    return {
      name: span.name,
      kind: span.kind,
      offsetPct: Math.max(0, Math.min(100, span.startMs / total * 100)),
      widthPct: Math.max(0.5, Math.min(100, (span.endMs - span.startMs) / total * 100)),
      durationLabel: `${((span.endMs - span.startMs) / 1e3).toFixed(1)}s${span.approx ? "~" : ""}`,
      approx: span.approx === true,
      ok: !failed
    };
  });
}
function ChevronGlyph({ className }) {
  return /* @__PURE__ */ jsx3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx3("path", { d: "m6 9 6 6 6-6" }) });
}
function RefreshGlyph({ className }) {
  return /* @__PURE__ */ jsx3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx3("path", { d: "M21 12a9 9 0 1 1-2.64-6.36M21 3v6h-6" }) });
}
function CopyGlyph({ className }) {
  return /* @__PURE__ */ jsxs3("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
    /* @__PURE__ */ jsx3("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
    /* @__PURE__ */ jsx3("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
  ] });
}
function TraceIdCopy({ traceId }) {
  const [copied, setCopied] = useState3(false);
  const copy = useCallback(() => {
    void navigator.clipboard?.writeText(traceId).then(
      () => {
        setCopied(true);
        setTimeout(() => setCopied(false), 1200);
      },
      () => {
      }
    );
  }, [traceId]);
  return /* @__PURE__ */ jsxs3(
    "button",
    {
      type: "button",
      onClick: copy,
      title: "Copy trace id",
      "aria-label": "Copy trace id",
      className: "inline-flex min-w-0 items-center gap-1.5 rounded text-left font-mono text-muted-foreground transition hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-card",
      children: [
        /* @__PURE__ */ jsx3("span", { className: "truncate", children: traceId }),
        /* @__PURE__ */ jsx3(CopyGlyph, { className: "h-3 w-3 shrink-0" }),
        copied && /* @__PURE__ */ jsx3("span", { className: "shrink-0 not-italic text-success", children: "copied" })
      ]
    }
  );
}
function StatusDot({ tone }) {
  return /* @__PURE__ */ jsxs3("span", { className: "inline-flex items-center", children: [
    /* @__PURE__ */ jsx3(
      "span",
      {
        "aria-hidden": true,
        className: `h-2 w-2 shrink-0 rounded-full ${tone === "live" ? "animate-pulse bg-warning" : tone === "ok" ? "bg-success" : tone === "error" ? "bg-destructive" : "bg-muted-foreground/40"}`
      }
    ),
    /* @__PURE__ */ jsx3("span", { className: "sr-only", children: tone })
  ] });
}
var BAR_CLASS = {
  pipeline: "bg-muted-foreground/30",
  model: "bg-primary/60",
  tool: "bg-primary"
};
function FlowWaterfall({ trace }) {
  const rows = waterfallLayout(trace);
  if (rows.length === 0) return null;
  const cost = formatActivityCost(trace.costUsd);
  return /* @__PURE__ */ jsxs3("div", { className: "space-y-1", children: [
    rows.map((row, i) => /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-[minmax(0,2fr)_minmax(0,3fr)_auto] items-center gap-2", children: [
      /* @__PURE__ */ jsx3("span", { className: "truncate font-mono text-[11px] text-muted-foreground", title: row.name, children: row.name }),
      /* @__PURE__ */ jsx3("div", { className: "relative h-2 rounded-sm bg-muted/40", children: /* @__PURE__ */ jsx3(
        "div",
        {
          className: `absolute inset-y-0 rounded-sm ${row.ok ? BAR_CLASS[row.kind] : "bg-destructive/80"} ${row.approx ? "opacity-70" : ""}`,
          style: { left: `${row.offsetPct}%`, width: `${row.widthPct}%` }
        }
      ) }),
      /* @__PURE__ */ jsx3("span", { className: "shrink-0 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: row.durationLabel })
    ] }, i)),
    /* @__PURE__ */ jsxs3("p", { className: "pt-0.5 text-right font-mono text-[10px] tabular-nums text-muted-foreground/60", children: [
      (trace.totalMs / 1e3).toFixed(1),
      "s",
      cost ? ` \xB7 ${cost}` : ""
    ] })
  ] });
}
function MissionActivityLane({ activity, startedAt, nowMs }) {
  const [expanded, setExpanded] = useState3(false);
  if (activity.length === 0) return null;
  return /* @__PURE__ */ jsxs3("div", { className: "mt-1 border-l border-border/50 pl-3", children: [
    activity.map((run) => {
      const tone = activityTone(run.status);
      const cost = formatActivityCost(run.costUsd);
      const duration = formatActivityDuration(run.durationMs);
      return /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
        /* @__PURE__ */ jsx3(StatusDot, { tone }),
        /* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
          /* @__PURE__ */ jsx3("span", { className: "font-medium", children: run.tool }),
          /* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
            " \u2014 ",
            run.detail
          ] })
        ] }),
        tone === "live" && (run.iteration !== void 0 || run.phase !== void 0) && /* @__PURE__ */ jsx3("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 ") }),
        /* @__PURE__ */ jsxs3("span", { className: "flex shrink-0 items-center gap-1.5 font-mono text-[10px] tabular-nums text-muted-foreground/70", children: [
          tone !== "live" && tone !== "ok" && /* @__PURE__ */ jsx3("span", { children: run.status }),
          cost && /* @__PURE__ */ jsx3("span", { children: cost }),
          duration && /* @__PURE__ */ jsx3("span", { children: duration })
        ] })
      ] }, run.taskId);
    }),
    /* @__PURE__ */ jsxs3(
      "button",
      {
        type: "button",
        onClick: () => setExpanded((v) => !v),
        className: "flex items-center gap-1 py-0.5 text-[10px] font-medium text-muted-foreground/70 transition hover:text-foreground",
        children: [
          /* @__PURE__ */ jsx3(ChevronGlyph, { className: `h-3 w-3 transition-transform ${expanded ? "rotate-180" : ""}` }),
          "timeline"
        ]
      }
    ),
    expanded && /* @__PURE__ */ jsx3("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx3(
      FlowWaterfall,
      {
        trace: stepActivityFlowTrace(activity, {
          ...startedAt !== void 0 ? { startedAt } : {},
          ...nowMs !== void 0 ? { nowMs } : {}
        })
      }
    ) })
  ] });
}
function ActivityRow({
  record,
  renderMissionRef
}) {
  const [open, setOpen] = useState3(false);
  const tone = activityTone(record.status);
  const cost = formatActivityCost(record.costUsd);
  const duration = formatActivityDuration(record.durationMs);
  return /* @__PURE__ */ jsxs3("div", { className: "rounded-lg border border-border/60 bg-card", children: [
    /* @__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: [
      /* @__PURE__ */ jsx3(StatusDot, { tone }),
      /* @__PURE__ */ jsxs3("span", { className: "min-w-0 flex-1 truncate", children: [
        /* @__PURE__ */ jsx3("span", { className: "font-medium", children: record.tool }),
        /* @__PURE__ */ jsxs3("span", { className: "text-muted-foreground", children: [
          " \u2014 ",
          record.detail
        ] })
      ] }),
      tone === "live" && (record.iteration !== void 0 || record.phase !== void 0) && /* @__PURE__ */ jsx3("span", { className: "shrink-0 rounded-full bg-warning/10 px-2 py-0.5 font-mono text-[10px] text-warning", children: [record.iteration !== void 0 ? `iter ${record.iteration}` : null, record.phase ?? null].filter(Boolean).join(" \xB7 ") }),
      /* @__PURE__ */ jsx3(
        "span",
        {
          className: `shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium ${tone === "ok" ? "bg-success/10 text-success" : tone === "error" ? "bg-destructive/10 text-destructive" : tone === "live" ? "bg-warning/10 text-warning" : "bg-muted/60 text-muted-foreground"}`,
          children: record.status
        }
      ),
      cost && /* @__PURE__ */ jsx3("span", { className: "shrink-0 font-mono text-[11px] tabular-nums text-muted-foreground", children: cost }),
      /* @__PURE__ */ jsx3(ChevronGlyph, { className: `h-3 w-3 shrink-0 text-muted-foreground transition-transform ${open ? "rotate-180" : ""}` })
    ] }),
    open && /* @__PURE__ */ jsxs3("div", { className: "space-y-2.5 border-t border-border/40 px-3 py-2.5", children: [
      record.durationMs !== void 0 && /* @__PURE__ */ jsx3("div", { className: "rounded-md border border-border/50 bg-muted/10 p-2", children: /* @__PURE__ */ jsx3(FlowWaterfall, { trace: stepActivityFlowTrace([record]) }) }),
      /* @__PURE__ */ jsxs3("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 font-mono text-[11px]", children: [
        /* @__PURE__ */ jsx3("dt", { className: "text-muted-foreground/60", children: "task" }),
        /* @__PURE__ */ jsx3("dd", { className: "truncate text-muted-foreground", children: record.taskId }),
        /* @__PURE__ */ jsx3("dt", { className: "text-muted-foreground/60", children: "started" }),
        /* @__PURE__ */ jsx3("dd", { className: "text-muted-foreground", children: new Date(record.startedAt).toLocaleString() }),
        duration && /* @__PURE__ */ jsxs3(Fragment2, { children: [
          /* @__PURE__ */ jsx3("dt", { className: "text-muted-foreground/60", children: "duration" }),
          /* @__PURE__ */ jsx3("dd", { className: "text-muted-foreground", children: duration })
        ] }),
        record.traceId && /* @__PURE__ */ jsxs3(Fragment2, { children: [
          /* @__PURE__ */ jsx3("dt", { className: "text-muted-foreground/60", children: "trace" }),
          /* @__PURE__ */ jsx3("dd", { className: "min-w-0", children: /* @__PURE__ */ jsx3(TraceIdCopy, { traceId: record.traceId }) })
        ] })
      ] }),
      record.missionRef && renderMissionRef?.(record.missionRef, record)
    ] })
  ] });
}
function AgentActivityPanel({ fetchActivity, renderMissionRef, title = "Agent activity", emptyLabel = "No agent runs yet." }) {
  const [rows, setRows] = useState3([]);
  const [cursor, setCursor] = useState3(void 0);
  const [loading, setLoading] = useState3(false);
  const [error, setError] = useState3(null);
  const load = useCallback(
    async (from) => {
      setLoading(true);
      setError(null);
      try {
        const page = await fetchActivity(from);
        setRows((prev) => mergeActivityPages(from === void 0 ? [] : prev, page.items));
        setCursor(page.nextCursor);
      } catch (e) {
        setError(e instanceof Error ? e.message : String(e));
      } finally {
        setLoading(false);
      }
    },
    [fetchActivity]
  );
  useEffect3(() => {
    void load();
  }, [load]);
  return /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
    /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2", children: [
      /* @__PURE__ */ jsx3("h2", { className: "flex-1 text-sm font-semibold", children: title }),
      /* @__PURE__ */ jsx3(
        "button",
        {
          type: "button",
          onClick: () => void load(),
          disabled: loading,
          "aria-label": "Refresh",
          className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground disabled:opacity-50",
          children: /* @__PURE__ */ jsx3(RefreshGlyph, { className: `h-3.5 w-3.5 ${loading ? "animate-spin" : ""}` })
        }
      )
    ] }),
    error && /* @__PURE__ */ jsx3("p", { role: "alert", className: "rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-xs text-destructive", children: error }),
    !error && rows.length === 0 && !loading && /* @__PURE__ */ jsx3("p", { className: "px-1 text-sm text-muted-foreground", children: emptyLabel }),
    /* @__PURE__ */ jsx3("div", { className: "space-y-1.5", children: rows.map((record) => /* @__PURE__ */ jsx3(ActivityRow, { record, renderMissionRef }, record.taskId)) }),
    cursor && /* @__PURE__ */ jsx3(
      "button",
      {
        type: "button",
        onClick: () => void load(cursor),
        disabled: loading,
        className: "w-full rounded-md border border-border bg-card px-3 py-1.5 text-xs font-medium text-muted-foreground transition hover:bg-accent/30 disabled:opacity-50",
        children: "Older runs"
      }
    )
  ] });
}

// src/web-react/sandbox-terminal.ts
import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef3, useState as useState4 } from "react";
var DEFAULT_PROVISION_POLL_INTERVAL_MS = 2e3;
var DEFAULT_PROVISION_POLL_TIMEOUT_MS = 9e4;
var DEFAULT_TOKEN_REFRESH_SKEW_MS = 12e4;
var EMPTY_CONNECTION = {
  runtimeUrl: null,
  sidecarUrl: null,
  token: null,
  expiresAt: null,
  status: "idle",
  error: null,
  loading: false
};
function useSandboxTerminalConnection(opts) {
  const [conn, setConn] = useState4(EMPTY_CONNECTION);
  const mountedRef = useRef3(false);
  const generationRef = useRef3(0);
  const fetcher = opts.fetcher ?? fetch;
  const pollIntervalMs = opts.provisionPollIntervalMs ?? DEFAULT_PROVISION_POLL_INTERVAL_MS;
  const pollTimeoutMs = opts.provisionPollTimeoutMs ?? DEFAULT_PROVISION_POLL_TIMEOUT_MS;
  const refreshSkewMs = opts.tokenRefreshSkewMs ?? DEFAULT_TOKEN_REFRESH_SKEW_MS;
  const connectionUrl = useCallback2(() => {
    if (typeof opts.connectionUrl === "function") return opts.connectionUrl(opts.workspaceId);
    return opts.connectionUrl ?? `/api/workspaces/${encodeURIComponent(opts.workspaceId)}/sandbox/connection`;
  }, [opts.connectionUrl, opts.workspaceId]);
  const connect = useCallback2(async () => {
    const generation = generationRef.current + 1;
    generationRef.current = generation;
    const isCurrent = () => mountedRef.current && generationRef.current === generation;
    const setCurrentConn = (value) => {
      if (!isCurrent()) return;
      setConn(value);
    };
    setCurrentConn((current) => ({ ...current, loading: true, error: null }));
    const deadline = Date.now() + pollTimeoutMs;
    while (isCurrent()) {
      try {
        const res = await fetcher(connectionUrl());
        const data = await res.json();
        if (!isCurrent()) return;
        const runtimeUrl = data.runtimeUrl ?? data.sidecarUrl;
        if (res.ok && runtimeUrl && data.token && data.expiresAt) {
          setCurrentConn({
            runtimeUrl,
            sidecarUrl: data.sidecarUrl ?? runtimeUrl,
            token: data.token,
            expiresAt: data.expiresAt,
            status: data.status ?? "running",
            error: null,
            loading: false,
            ...data.sandboxId ? { sandboxId: data.sandboxId } : {}
          });
          return;
        }
        if (res.ok) {
          setCurrentConn({
            runtimeUrl: null,
            sidecarUrl: null,
            token: null,
            expiresAt: null,
            loading: false,
            error: "Sandbox connection response is missing required fields",
            status: data.status ?? "error",
            ...data.sandboxId ? { sandboxId: data.sandboxId } : {}
          });
          return;
        }
        if (res.status === 503 && Date.now() < deadline) {
          setCurrentConn((current) => ({
            ...current,
            loading: true,
            status: data.status ?? "provisioning",
            error: null
          }));
          await sleep(pollIntervalMs);
          continue;
        }
        setCurrentConn((current) => ({
          ...current,
          runtimeUrl: null,
          sidecarUrl: null,
          token: null,
          expiresAt: null,
          loading: false,
          error: data.error ?? "Sandbox not available",
          status: data.status ?? "error"
        }));
        return;
      } catch (err) {
        if (!isCurrent()) return;
        if (Date.now() < deadline) {
          await sleep(pollIntervalMs);
          continue;
        }
        setCurrentConn((current) => ({
          ...current,
          runtimeUrl: null,
          sidecarUrl: null,
          token: null,
          expiresAt: null,
          loading: false,
          error: err instanceof Error ? err.message : "Connection failed"
        }));
        return;
      }
    }
  }, [connectionUrl, fetcher, pollIntervalMs, pollTimeoutMs]);
  useEffect4(() => {
    mountedRef.current = true;
    return () => {
      mountedRef.current = false;
      generationRef.current += 1;
    };
  }, []);
  useEffect4(() => {
    void connect();
  }, [connect]);
  useEffect4(() => {
    if (!conn.runtimeUrl || !conn.token || !conn.expiresAt) return;
    const refreshAt = Date.parse(conn.expiresAt) - Date.now() - refreshSkewMs;
    if (!Number.isFinite(refreshAt)) {
      setConn((current) => ({
        ...current,
        runtimeUrl: null,
        sidecarUrl: null,
        token: null,
        expiresAt: null,
        status: "error",
        error: "Sandbox token expiry is invalid"
      }));
      return;
    }
    const timer = window.setTimeout(() => {
      void connect();
    }, Math.max(1e3, refreshAt));
    return () => window.clearTimeout(timer);
  }, [conn.runtimeUrl, conn.token, conn.expiresAt, connect, refreshSkewMs]);
  return { ...conn, connect };
}
function sleep(ms) {
  return new Promise((resolve) => window.setTimeout(resolve, ms));
}

// src/web-react/seat-paywall.tsx
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
function CheckGlyph() {
  return /* @__PURE__ */ jsx4(
    "svg",
    {
      className: "h-4 w-4 shrink-0 text-primary",
      viewBox: "0 0 24 24",
      fill: "none",
      stroke: "currentColor",
      strokeWidth: "2.5",
      strokeLinecap: "round",
      strokeLinejoin: "round",
      "aria-hidden": true,
      children: /* @__PURE__ */ jsx4("path", { d: "M20 6 9 17l-5-5" })
    }
  );
}
function Benefit({ children }) {
  return /* @__PURE__ */ jsxs4("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
    /* @__PURE__ */ jsx4("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx4(CheckGlyph, {}) }),
    /* @__PURE__ */ jsx4("span", { children })
  ] });
}
function SeatPaywall({
  product,
  onCheckout,
  priceUsd = 100,
  includedUsageUsd = 50,
  tagline,
  ctaLabel,
  benefits,
  footnote
}) {
  const { pending, run } = usePending();
  return /* @__PURE__ */ jsx4("div", { className: "flex min-h-[60vh] w-full items-center justify-center p-6", children: /* @__PURE__ */ jsxs4("div", { className: "w-full max-w-md rounded-2xl border border-border bg-card p-8 shadow-sm", children: [
    /* @__PURE__ */ jsx4("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
    /* @__PURE__ */ jsxs4("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
      "Unlock ",
      product
    ] }),
    tagline && /* @__PURE__ */ jsx4("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
    /* @__PURE__ */ jsxs4("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
      /* @__PURE__ */ jsxs4("span", { className: "text-3xl font-semibold text-foreground", children: [
        "$",
        priceUsd
      ] }),
      /* @__PURE__ */ jsx4("span", { className: "text-sm text-muted-foreground", children: "/mo" })
    ] }),
    /* @__PURE__ */ jsxs4("p", { className: "mt-1 text-sm text-muted-foreground", children: [
      "Includes $",
      includedUsageUsd,
      "/mo of AI usage"
    ] }),
    /* @__PURE__ */ jsx4("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
      `Full access to ${product}`,
      `$${includedUsageUsd}/mo of AI usage included, every month`
    ]).map((benefit, i) => /* @__PURE__ */ jsx4(Benefit, { children: benefit }, i)) }),
    /* @__PURE__ */ jsx4(
      "button",
      {
        type: "button",
        disabled: pending,
        onClick: () => run(onCheckout),
        className: "mt-7 inline-flex w-full items-center justify-center rounded-xl bg-primary px-4 py-2.5 text-sm font-medium text-primary-foreground transition hover:bg-primary/90 disabled:cursor-not-allowed disabled:opacity-70",
        children: pending ? "Opening checkout\u2026" : ctaLabel ?? `Unlock ${product}`
      }
    ),
    footnote && /* @__PURE__ */ jsx4("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
  ] }) });
}

// src/web-react/agent-session-controls.tsx
import { useMemo as useMemo2, useState as useState5 } from "react";
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
var HARNESS_LABELS = {
  opencode: "OpenCode (any model)",
  "claude-code": "Claude Code (Anthropic)",
  codex: "Codex (OpenAI)",
  "kimi-code": "Kimi (Moonshot)",
  amp: "Amp",
  "factory-droids": "Factory Droids",
  cursor: "Cursor",
  hermes: "Hermes",
  forge: "Forge",
  pi: "Pi",
  openclaw: "OpenClaw",
  acp: "ACP",
  "cli-base": "CLI"
};
function harnessLabel(h) {
  return HARNESS_LABELS[h] ?? h;
}
function ChevronDown2({ className }) {
  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: "m6 9 6 6 6-6" }) });
}
function GearGlyph({ className }) {
  return /* @__PURE__ */ jsxs5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
    /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "3" }),
    /* @__PURE__ */ jsx5("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" })
  ] });
}
var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background";
function HarnessPicker({
  value,
  onChange,
  available
}) {
  const [open, setOpen] = useState5(false);
  const { containerRef, triggerProps } = usePopover(open, setOpen);
  const options = available ?? Object.keys(HARNESS_LABELS);
  return /* @__PURE__ */ jsxs5("div", { ref: containerRef, className: "relative inline-flex", children: [
    /* @__PURE__ */ jsxs5(
      "button",
      {
        type: "button",
        ...triggerProps,
        onClick: () => setOpen(!open),
        title: "Agent backend",
        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}`,
        children: [
          /* @__PURE__ */ jsx5("span", { className: "truncate", children: harnessLabel(value) }),
          /* @__PURE__ */ jsx5(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
        ]
      }
    ),
    open && /* @__PURE__ */ jsx5("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__ */ jsx5(
      "button",
      {
        type: "button",
        role: "menuitemradio",
        "aria-checked": h === value,
        onClick: () => {
          onChange(h);
          setOpen(false);
        },
        className: `flex w-full items-center rounded-md px-3 py-2 text-left text-sm transition ${FOCUS_RING} ${h === value ? "bg-primary/10 font-medium" : "hover:bg-accent/30"}`,
        children: harnessLabel(h)
      },
      h
    )) })
  ] });
}
function useCoherentHandlers(props) {
  const { model, models, harness, onModelChange, onHarnessChange } = props;
  const canonicalIds = useMemo2(() => models.map((m) => m.id), [models]);
  const onModel = (next) => {
    onModelChange(next);
    const nextHarness = snapHarnessToModel(harness, next);
    if (nextHarness !== harness) onHarnessChange(nextHarness);
  };
  const onHarness = (next) => {
    onHarnessChange(next);
    const snapped = snapModelToHarness(next, model, canonicalIds);
    if (snapped !== model) onModelChange(snapped);
  };
  return { onModel, onHarness };
}
function AgentSessionControls(props) {
  const {
    models,
    modelsLoading,
    model,
    harness,
    availableHarnesses,
    effort,
    onEffortChange,
    layout = "inline",
    showHarness = true,
    renderProviderBadge,
    className
  } = props;
  const { onModel, onHarness } = useCoherentHandlers(props);
  const [open, setOpen] = useState5(false);
  const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
  const selectedModel = models.find((m) => m.id === model);
  const showEffort = selectedModel?.supportsReasoning ?? true;
  const modelPicker = /* @__PURE__ */ jsx5(
    ModelPicker,
    {
      value: model,
      onChange: onModel,
      models,
      loading: modelsLoading,
      renderProviderBadge
    }
  );
  if (layout === "inline") {
    return /* @__PURE__ */ jsxs5("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
      modelPicker,
      showHarness && /* @__PURE__ */ jsx5(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
      showEffort && /* @__PURE__ */ jsx5(EffortPicker, { value: effort, onChange: onEffortChange })
    ] });
  }
  const hasAdvanced = showHarness || showEffort;
  return /* @__PURE__ */ jsxs5("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
    modelPicker,
    hasAdvanced && /* @__PURE__ */ jsxs5("div", { ref: popoverRef, className: "relative inline-flex", children: [
      /* @__PURE__ */ jsx5(
        "button",
        {
          type: "button",
          ...triggerProps,
          onClick: () => setOpen(!open),
          title: "Model settings \u2014 pick the agent backend and how hard it thinks",
          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}`,
          "data-state": open ? "open" : "closed",
          children: /* @__PURE__ */ jsx5(GearGlyph, { className: "h-4 w-4" })
        }
      ),
      open && /* @__PURE__ */ jsxs5("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: [
        showHarness && /* @__PURE__ */ jsxs5("div", { className: "space-y-1.5", children: [
          /* @__PURE__ */ jsx5("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
          /* @__PURE__ */ jsx5(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
          /* @__PURE__ */ jsx5("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
        ] }),
        showEffort && /* @__PURE__ */ jsxs5("div", { className: "space-y-1.5", children: [
          /* @__PURE__ */ jsx5("p", { className: "text-xs font-medium text-foreground", children: "Reasoning effort" }),
          /* @__PURE__ */ jsx5(EffortPicker, { value: effort, onChange: onEffortChange }),
          /* @__PURE__ */ jsx5("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
        ] })
      ] })
    ] })
  ] });
}

// src/web-react/index.tsx
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
function formatModelCost(msg, models) {
  if (msg.promptTokens == null && msg.completionTokens == null) return null;
  const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
  if (!pricing) return null;
  const cost = (msg.promptTokens ?? 0) * Number(pricing.prompt ?? 0) + (msg.completionTokens ?? 0) * Number(pricing.completion ?? 0);
  if (!isFinite(cost) || cost <= 0) return null;
  return cost < 0.01 ? `$${cost.toFixed(4)}` : `$${cost.toFixed(2)}`;
}
function formatTokensPerSecond(msg) {
  if (msg.completionTokens == null || !msg.durationMs) return null;
  return `${Math.round(msg.completionTokens / (msg.durationMs / 1e3))} tok/s`;
}
function RunDrillIn({ run, onClose }) {
  return /* @__PURE__ */ jsxs6("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: [
    /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
      /* @__PURE__ */ jsx6(
        "span",
        {
          className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
        }
      ),
      /* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
        /* @__PURE__ */ jsx6("p", { className: "truncate text-sm font-semibold", children: run.title }),
        /* @__PURE__ */ jsx6("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
      ] }),
      /* @__PURE__ */ jsx6(
        "button",
        {
          type: "button",
          onClick: onClose,
          "aria-label": "Close",
          className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground",
          children: /* @__PURE__ */ jsx6("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx6("path", { d: "M18 6 6 18M6 6l12 12" }) })
        }
      )
    ] }),
    /* @__PURE__ */ jsxs6("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
      run.steps.length === 0 && /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
      run.steps.map((step, i) => /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border/60 bg-background", children: [
        /* @__PURE__ */ jsxs6("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
          /* @__PURE__ */ jsx6("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
          /* @__PURE__ */ jsx6("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
          /* @__PURE__ */ jsx6("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
        ] }),
        step.detail && /* @__PURE__ */ jsx6("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 })
      ] }, i))
    ] }),
    /* @__PURE__ */ jsx6("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." })
  ] });
}
function pendingApprovalOf(call) {
  const outcome = call.result;
  if (!outcome?.ok || outcome.result?.status !== "queued_for_approval" || !outcome.result.proposalId) return null;
  return { proposalId: outcome.result.proposalId };
}
function ToolGlyph({ name, className }) {
  if (name.startsWith("sandbox_")) {
    return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
      /* @__PURE__ */ jsx6("polyline", { points: "4 17 10 11 4 5" }),
      /* @__PURE__ */ jsx6("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
    ] });
  }
  if (name === "submit_proposal") {
    return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
      /* @__PURE__ */ jsx6("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
      /* @__PURE__ */ jsx6("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
    ] });
  }
  if (name === "schedule_followup") {
    return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
      /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "9" }),
      /* @__PURE__ */ jsx6("path", { d: "M12 7v5l3 3" })
    ] });
  }
  return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
    /* @__PURE__ */ jsx6("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
    /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "4" })
  ] });
}
function toolOutcomeOf(call) {
  return call.result;
}
function friendlyToolTitle(call) {
  const a = call.args ?? {};
  switch (call.name) {
    case "submit_proposal":
      return `Proposal \xB7 ${String(a.type ?? "")}${a.title ? `: ${String(a.title)}` : ""}`;
    case "sandbox_create":
      return `Create sandbox (${String(a.environment ?? "universal")})`;
    case "sandbox_run_command":
      return `$ ${String(a.command ?? "")}`;
    case "sandbox_destroy":
      return `Destroy sandbox ${String(a.sandbox_id ?? "")}`;
    case "schedule_followup":
      return `Follow-up \xB7 ${String(a.title ?? "")}`;
    case "render_ui":
      return `Render view \xB7 ${String(a.title ?? "")}`;
    case "add_citation":
      return `Citation \xB7 ${String(a.path ?? "")}`;
    default:
      return call.name;
  }
}
function truncate(v, max = 240) {
  const s = typeof v === "string" ? v : JSON.stringify(v);
  return s.length > max ? `${s.slice(0, max)}\u2026` : s;
}
function KvRows({ data }) {
  const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
  if (!entries.length) return null;
  return /* @__PURE__ */ jsx6("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs6("div", { className: "contents", children: [
    /* @__PURE__ */ jsx6("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
    /* @__PURE__ */ jsx6("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
  ] }, k)) });
}
function ShellDetail({ call }) {
  const outcome = toolOutcomeOf(call);
  const r = outcome?.result ?? {};
  return /* @__PURE__ */ jsxs6("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
    /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
      /* @__PURE__ */ jsx6("span", { className: "select-none text-zinc-500", children: "$" }),
      /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
      r.exitCode != null && /* @__PURE__ */ jsxs6("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
        "exit ",
        r.exitCode
      ] })
    ] }),
    /* @__PURE__ */ jsx6("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)" })
  ] });
}
function DefaultToolDetail({ call }) {
  const outcome = toolOutcomeOf(call);
  return /* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
    call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs6("div", { children: [
      /* @__PURE__ */ jsx6("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
      /* @__PURE__ */ jsx6(KvRows, { data: call.args })
    ] }),
    outcome && /* @__PURE__ */ jsxs6("div", { children: [
      /* @__PURE__ */ jsx6("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
      outcome.ok === false ? /* @__PURE__ */ jsx6("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx6(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx6("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
    ] })
  ] });
}
function ToolCallCard({
  call,
  message,
  approval,
  onOpenRun,
  renderers
}) {
  const [expanded, setExpanded] = useState6(false);
  const pending = call.status === "done" ? pendingApprovalOf(call) : null;
  const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
  const custom = renderers?.[call.name]?.(call, message);
  const { pending: deciding, run: decide } = usePending();
  return /* @__PURE__ */ jsxs6(
    "div",
    {
      className: `w-fit min-w-[280px] max-w-full rounded-lg border text-xs transition ${pending ? "border-warning/40 bg-warning/5" : failed ? "border-destructive/40 bg-destructive/5" : "border-border/60 bg-muted/20"}`,
      children: [
        /* @__PURE__ */ jsxs6("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
          /* @__PURE__ */ jsxs6(
            "button",
            {
              type: "button",
              onClick: () => setExpanded((v) => !v),
              "aria-expanded": expanded,
              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",
              children: [
                /* @__PURE__ */ jsx6(
                  "span",
                  {
                    className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" : pending ? "bg-warning" : failed ? "bg-destructive" : "bg-success"}`
                  }
                ),
                /* @__PURE__ */ jsx6(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
                /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate font-medium", children: friendlyToolTitle(call) })
              ]
            }
          ),
          pending && approval && /* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1", children: [
            /* @__PURE__ */ jsx6(
              "button",
              {
                type: "button",
                disabled: deciding,
                onClick: () => decide(() => approval.onApprove(pending.proposalId, call.id)),
                className: "rounded bg-success px-2 py-0.5 text-[11px] font-semibold text-success-foreground transition hover:bg-success/90 disabled:cursor-not-allowed disabled:opacity-60",
                children: "Approve"
              }
            ),
            /* @__PURE__ */ jsx6(
              "button",
              {
                type: "button",
                disabled: deciding,
                onClick: () => decide(() => approval.onReject(pending.proposalId, call.id)),
                className: "rounded border border-border bg-card px-2 py-0.5 text-[11px] font-medium text-foreground transition hover:bg-accent/30 disabled:cursor-not-allowed disabled:opacity-60",
                children: "Reject"
              }
            )
          ] }),
          /* @__PURE__ */ jsx6("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : pending ? "awaiting approval" : failed ? "failed" : "done" }),
          /* @__PURE__ */ jsx6(
            "button",
            {
              type: "button",
              onClick: () => setExpanded((v) => !v),
              "aria-label": expanded ? "Collapse details" : "Expand details",
              "aria-expanded": expanded,
              className: "shrink-0 rounded p-0.5 focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
              children: /* @__PURE__ */ jsx6(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
            }
          )
        ] }),
        expanded && /* @__PURE__ */ jsxs6("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
          custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx6(ShellDetail, { call }) : /* @__PURE__ */ jsx6(DefaultToolDetail, { call })),
          onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx6(
            "button",
            {
              type: "button",
              onClick: () => onOpenRun(call, message),
              className: "mt-2 rounded border border-border bg-card px-2 py-1 text-[11px] font-medium transition hover:bg-accent/30",
              children: "Open full transcript \u2192"
            }
          )
        ] })
      ]
    }
  );
}
function AssistantMessageImpl({
  msg,
  streaming,
  models,
  agentLabel,
  renderBody,
  approval,
  onToolCallClick,
  toolRenderers,
  renderExtras
}) {
  const content = useSmoothText(msg.content, streaming);
  const reasoning = useSmoothText(msg.reasoning ?? "", streaming);
  const body = useMemo3(() => renderBody(content), [renderBody, content]);
  const reasoningScrollRef = useRef4(null);
  const thinkStartRef = useRef4(null);
  const thinkMsRef = useRef4(null);
  if (streaming && reasoning && !content && thinkStartRef.current === null) {
    thinkStartRef.current = performance.now();
  }
  if (content && thinkStartRef.current !== null && thinkMsRef.current === null) {
    thinkMsRef.current = performance.now() - thinkStartRef.current;
  }
  useEffect5(() => {
    const el = reasoningScrollRef.current;
    if (el && streaming && !content) el.scrollTop = el.scrollHeight;
  }, [reasoning, streaming, content]);
  return /* @__PURE__ */ jsxs6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
    /* @__PURE__ */ jsxs6("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
      /* @__PURE__ */ jsx6("span", { className: "font-semibold uppercase", children: agentLabel }),
      msg.modelUsed && /* @__PURE__ */ jsx6("span", { className: "font-mono normal-case", children: msg.modelUsed }),
      formatTokensPerSecond(msg) && /* @__PURE__ */ jsx6("span", { children: formatTokensPerSecond(msg) }),
      formatModelCost(msg, models) && /* @__PURE__ */ jsx6("span", { children: formatModelCost(msg, models) })
    ] }),
    reasoning && /* @__PURE__ */ jsxs6("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !content, children: [
      /* @__PURE__ */ jsx6("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !content ? /* @__PURE__ */ jsx6("span", { className: "animate-pulse", children: "Thinking\u2026" }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
      /* @__PURE__ */ jsx6("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
    ] }),
    /* @__PURE__ */ jsxs6("div", { className: "text-base leading-[1.75]", children: [
      body,
      streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx6("span", { className: "ml-0.5 inline-block h-[1.1em] w-[3px] translate-y-[2px] animate-pulse rounded-sm bg-foreground/70", "aria-hidden": true })
    ] }),
    msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx6("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx6(
      ToolCallCard,
      {
        call: tc,
        message: msg,
        approval,
        onOpenRun: onToolCallClick,
        renderers: toolRenderers
      },
      tc.id
    )) }),
    renderExtras?.(msg)
  ] });
}
var AssistantMessage = memo(AssistantMessageImpl);
function ThinkingRow({ agentLabel }) {
  const [seconds, setSeconds] = useState6(0);
  useEffect5(() => {
    const id = setInterval(() => setSeconds((s) => s + 1), 1e3);
    return () => clearInterval(id);
  }, []);
  return /* @__PURE__ */ jsxs6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
    /* @__PURE__ */ jsx6("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
    /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
      /* @__PURE__ */ jsx6("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx6("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
      "Thinking",
      seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
    ] })
  ] });
}
function StreamErrorRow({ message, onRetry }) {
  return /* @__PURE__ */ jsx6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs6("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: [
    /* @__PURE__ */ jsxs6("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: [
      /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "9" }),
      /* @__PURE__ */ jsx6("path", { d: "M12 8v4m0 4h.01" })
    ] }),
    /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 break-words", children: message }),
    onRetry && /* @__PURE__ */ jsx6(
      "button",
      {
        type: "button",
        onClick: onRetry,
        className: `shrink-0 rounded border border-destructive/40 bg-card px-2 py-0.5 text-[11px] font-medium text-destructive transition hover:bg-destructive/10 ${POPOVER_OPTION_FOCUS}`,
        children: "Retry"
      }
    )
  ] }) });
}
function ChatMessages({
  messages,
  models = [],
  renderMarkdown,
  renderExtras,
  userLabel = "User",
  agentLabel = "Agent",
  loading,
  approval,
  onToolCallClick,
  toolRenderers,
  error,
  onRetry,
  renderEmpty
}) {
  const renderBody = useMemo3(
    () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap", children: content })),
    [renderMarkdown]
  );
  const lastIsUser = messages[messages.length - 1]?.role === "user";
  if (messages.length === 0 && !loading && !error && renderEmpty) return /* @__PURE__ */ jsx6(Fragment3, { children: renderEmpty() });
  return /* @__PURE__ */ jsxs6(Fragment3, { children: [
    messages.map(
      (msg) => msg.role === "user" ? /* @__PURE__ */ jsx6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: /* @__PURE__ */ jsxs6("div", { className: "ml-auto w-fit max-w-[85%]", children: [
        /* @__PURE__ */ jsx6("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
        /* @__PURE__ */ jsx6("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap", children: msg.content }) })
      ] }) }, msg.id) : /* @__PURE__ */ jsx6(
        AssistantMessage,
        {
          msg,
          streaming: !!loading && msg.id === messages[messages.length - 1]?.id,
          models,
          agentLabel,
          renderBody,
          approval,
          onToolCallClick,
          toolRenderers,
          renderExtras
        },
        msg.id
      )
    ),
    loading && lastIsUser && /* @__PURE__ */ jsx6(ThinkingRow, { agentLabel }),
    error && !loading && /* @__PURE__ */ jsx6(StreamErrorRow, { message: error, onRetry })
  ] });
}
export {
  AgentActivityPanel,
  AgentSessionControls,
  ChatMessages,
  EffortPicker,
  FlowWaterfall,
  MissionActivityLane,
  ModelPicker,
  ProviderLogo,
  RunDrillIn,
  SeatPaywall,
  activityTone,
  consumeChatStream,
  dispatchChatStreamLine,
  formatActivityCost,
  formatActivityDuration,
  formatModelCost,
  formatTokensPerSecond,
  mergeActivityPages,
  nextRevealCount,
  pendingApprovalOf,
  streamChatTurn,
  usePending,
  usePopover,
  useSandboxTerminalConnection,
  useSmoothText,
  waterfallLayout
};
//# sourceMappingURL=index.js.map