@tangle-network/agent-app 0.39.2 → 0.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/.claude/skills/eval-campaign/SKILL.md +5 -5
  2. package/.claude/skills/surface-evolution/SKILL.md +2 -2
  3. package/dist/auth-DuptSkWh.d.ts +39 -0
  4. package/dist/{chunk-TQ5M7BFV.js → chunk-2A7STBX7.js} +2 -2
  5. package/dist/{chunk-FDJ6JQCI.js → chunk-3II3AWHY.js} +6 -4
  6. package/dist/{chunk-FDJ6JQCI.js.map → chunk-3II3AWHY.js.map} +1 -1
  7. package/dist/{chunk-RH74YJIK.js → chunk-7EVZUIHW.js} +7 -2
  8. package/dist/chunk-7EVZUIHW.js.map +1 -0
  9. package/dist/{chunk-DBIG2PHS.js → chunk-IZAH45W2.js} +3 -3
  10. package/dist/{chunk-PPSZNVKT.js → chunk-MFRCM32T.js} +29 -3
  11. package/dist/chunk-MFRCM32T.js.map +1 -0
  12. package/dist/{chunk-BUUJ7TEQ.js → chunk-NEOV2NQ3.js} +2 -2
  13. package/dist/{chunk-CPI3RILI.js → chunk-ULZEF45E.js} +49 -7
  14. package/dist/chunk-ULZEF45E.js.map +1 -0
  15. package/dist/{chunk-2FDTJIU4.js → chunk-WFMUDX5J.js} +2 -2
  16. package/dist/design-canvas/index.d.ts +3 -3
  17. package/dist/design-canvas/index.js +2 -2
  18. package/dist/eval/index.d.ts +1 -1
  19. package/dist/eval-campaign/index.d.ts +3 -3
  20. package/dist/eval-campaign/index.js +4 -4
  21. package/dist/eval-campaign/index.js.map +1 -1
  22. package/dist/index.d.ts +4 -4
  23. package/dist/index.js +18 -8
  24. package/dist/{mcp-4I_RHhNa.d.ts → mcp-BHfIoGLW.d.ts} +10 -6
  25. package/dist/preset-cloudflare/index.d.ts +1 -1
  26. package/dist/runtime/index.d.ts +3 -3
  27. package/dist/runtime/index.js +2 -2
  28. package/dist/sandbox/index.d.ts +2 -2
  29. package/dist/sandbox/index.js +4 -4
  30. package/dist/sequences/index.d.ts +3 -3
  31. package/dist/sequences/index.js +2 -2
  32. package/dist/stream/index.d.ts +37 -3
  33. package/dist/stream/index.js +5 -1
  34. package/dist/tools/index.d.ts +13 -8
  35. package/dist/tools/index.js +9 -3
  36. package/dist/{types-wHs0rmtu.d.ts → types-BEOvc_ue.d.ts} +68 -1
  37. package/dist/web-react/index.d.ts +58 -1
  38. package/dist/web-react/index.js +241 -137
  39. package/dist/web-react/index.js.map +1 -1
  40. package/package.json +12 -12
  41. package/dist/auth-DcK5ERaL.d.ts +0 -65
  42. package/dist/chunk-CPI3RILI.js.map +0 -1
  43. package/dist/chunk-PPSZNVKT.js.map +0 -1
  44. package/dist/chunk-RH74YJIK.js.map +0 -1
  45. /package/dist/{chunk-TQ5M7BFV.js.map → chunk-2A7STBX7.js.map} +0 -0
  46. /package/dist/{chunk-DBIG2PHS.js.map → chunk-IZAH45W2.js.map} +0 -0
  47. /package/dist/{chunk-BUUJ7TEQ.js.map → chunk-NEOV2NQ3.js.map} +0 -0
  48. /package/dist/{chunk-2FDTJIU4.js.map → chunk-WFMUDX5J.js.map} +0 -0
@@ -882,11 +882,113 @@ function useSandboxTerminalConnection(opts) {
882
882
  function sleep(ms) {
883
883
  return new Promise((resolve) => window.setTimeout(resolve, ms));
884
884
  }
885
+ var DEFAULT_TERMINAL_CID_KEY = "agent-app:terminal-connection-id";
886
+ function newConnectionId() {
887
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
888
+ return `cid-${Date.now().toString(36)}-${Math.floor(Math.random() * 1e9).toString(36)}`;
889
+ }
890
+ function tabTerminalConnectionId(storageKey = DEFAULT_TERMINAL_CID_KEY) {
891
+ try {
892
+ const store = globalThis.sessionStorage;
893
+ const existing = store?.getItem(storageKey);
894
+ if (existing) return existing;
895
+ const id = newConnectionId();
896
+ store?.setItem(storageKey, id);
897
+ return id;
898
+ } catch {
899
+ return newConnectionId();
900
+ }
901
+ }
902
+
903
+ // src/web-react/workspace-terminal-panel.tsx
904
+ import { lazy, Suspense } from "react";
905
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
906
+ var TerminalView = lazy(
907
+ () => import("@tangle-network/sandbox-ui/terminal").then((m) => ({ default: m.TerminalView }))
908
+ );
909
+ var TONE_DOT = {
910
+ idle: "bg-muted-foreground/50",
911
+ connecting: "animate-pulse bg-warning",
912
+ connected: "bg-success",
913
+ error: "bg-destructive"
914
+ };
915
+ function defaultStatusDisplay(conn) {
916
+ if (conn.error) return { tone: "error", label: "Disconnected" };
917
+ if (conn.runtimeUrl && conn.token) return { tone: "connected", label: "Connected" };
918
+ if (conn.loading) return { tone: "connecting", label: conn.status === "provisioning" ? "Provisioning\u2026" : "Connecting\u2026" };
919
+ return { tone: "idle", label: "Idle" };
920
+ }
921
+ function WorkspaceTerminalPanel({
922
+ connection,
923
+ connectionId,
924
+ title = "Terminal",
925
+ subtitle,
926
+ isActive,
927
+ onRetry,
928
+ statusDisplay,
929
+ headerExtra,
930
+ className
931
+ }) {
932
+ const status = (statusDisplay ?? defaultStatusDisplay)(connection);
933
+ const apiUrl = connection.runtimeUrl ?? connection.sidecarUrl;
934
+ const ready = Boolean(apiUrl && connection.token);
935
+ return /* @__PURE__ */ jsxs4("div", { className: `flex h-full min-h-0 flex-col overflow-hidden rounded-xl border border-border bg-card ${className ?? ""}`, children: [
936
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between gap-3 border-b border-border px-4 py-2.5", children: [
937
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0", children: [
938
+ /* @__PURE__ */ jsx4("p", { className: "truncate text-sm font-medium text-foreground", children: title }),
939
+ subtitle && /* @__PURE__ */ jsx4("p", { className: "truncate text-xs text-muted-foreground", children: subtitle })
940
+ ] }),
941
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
942
+ /* @__PURE__ */ jsxs4("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
943
+ /* @__PURE__ */ jsx4("span", { className: `h-1.5 w-1.5 rounded-full ${TONE_DOT[status.tone]}`, "aria-hidden": true }),
944
+ status.label
945
+ ] }),
946
+ headerExtra
947
+ ] })
948
+ ] }),
949
+ /* @__PURE__ */ jsx4("div", { className: "relative min-h-0 flex-1", children: ready ? /* @__PURE__ */ jsx4(Suspense, { fallback: /* @__PURE__ */ jsx4(TerminalMessage, { children: "Loading terminal\u2026" }), children: /* @__PURE__ */ jsx4(
950
+ TerminalView,
951
+ {
952
+ apiUrl,
953
+ token: connection.token,
954
+ connectionId,
955
+ title,
956
+ subtitle,
957
+ isActive
958
+ }
959
+ ) }) : /* @__PURE__ */ jsx4(TerminalMessage, { children: connection.error ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
960
+ /* @__PURE__ */ jsx4("p", { className: "text-sm text-destructive", children: connection.error }),
961
+ onRetry && /* @__PURE__ */ jsx4(
962
+ "button",
963
+ {
964
+ type: "button",
965
+ onClick: onRetry,
966
+ 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",
967
+ children: "Reconnect"
968
+ }
969
+ )
970
+ ] }) : connection.loading ? /* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground", children: connection.status === "provisioning" ? "Provisioning sandbox\u2026" : "Connecting\u2026" }) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
971
+ /* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground", children: "Terminal not connected." }),
972
+ onRetry && /* @__PURE__ */ jsx4(
973
+ "button",
974
+ {
975
+ type: "button",
976
+ onClick: onRetry,
977
+ 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",
978
+ children: "Connect"
979
+ }
980
+ )
981
+ ] }) }) })
982
+ ] });
983
+ }
984
+ function TerminalMessage({ children }) {
985
+ return /* @__PURE__ */ jsx4("div", { className: "absolute inset-0 flex flex-col items-center justify-center p-6 text-center", children });
986
+ }
885
987
 
886
988
  // src/web-react/seat-paywall.tsx
887
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
989
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
888
990
  function CheckGlyph() {
889
- return /* @__PURE__ */ jsx4(
991
+ return /* @__PURE__ */ jsx5(
890
992
  "svg",
891
993
  {
892
994
  className: "h-4 w-4 shrink-0 text-primary",
@@ -897,14 +999,14 @@ function CheckGlyph() {
897
999
  strokeLinecap: "round",
898
1000
  strokeLinejoin: "round",
899
1001
  "aria-hidden": true,
900
- children: /* @__PURE__ */ jsx4("path", { d: "M20 6 9 17l-5-5" })
1002
+ children: /* @__PURE__ */ jsx5("path", { d: "M20 6 9 17l-5-5" })
901
1003
  }
902
1004
  );
903
1005
  }
904
1006
  function Benefit({ children }) {
905
- return /* @__PURE__ */ jsxs4("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
906
- /* @__PURE__ */ jsx4("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx4(CheckGlyph, {}) }),
907
- /* @__PURE__ */ jsx4("span", { children })
1007
+ return /* @__PURE__ */ jsxs5("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
1008
+ /* @__PURE__ */ jsx5("span", { className: "mt-0.5", children: /* @__PURE__ */ jsx5(CheckGlyph, {}) }),
1009
+ /* @__PURE__ */ jsx5("span", { children })
908
1010
  ] });
909
1011
  }
910
1012
  function SeatPaywall({
@@ -918,30 +1020,30 @@ function SeatPaywall({
918
1020
  footnote
919
1021
  }) {
920
1022
  const { pending, run } = usePending();
921
- 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: [
922
- /* @__PURE__ */ jsx4("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
923
- /* @__PURE__ */ jsxs4("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
1023
+ return /* @__PURE__ */ jsx5("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: [
1024
+ /* @__PURE__ */ jsx5("p", { className: "text-xs font-medium uppercase tracking-wide text-muted-foreground", children: product }),
1025
+ /* @__PURE__ */ jsxs5("h1", { className: "mt-2 text-2xl font-semibold tracking-tight text-foreground", children: [
924
1026
  "Unlock ",
925
1027
  product
926
1028
  ] }),
927
- tagline && /* @__PURE__ */ jsx4("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
928
- /* @__PURE__ */ jsxs4("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
929
- /* @__PURE__ */ jsxs4("span", { className: "text-3xl font-semibold text-foreground", children: [
1029
+ tagline && /* @__PURE__ */ jsx5("p", { className: "mt-2 text-sm text-muted-foreground", children: tagline }),
1030
+ /* @__PURE__ */ jsxs5("div", { className: "mt-6 flex items-baseline gap-1.5", children: [
1031
+ /* @__PURE__ */ jsxs5("span", { className: "text-3xl font-semibold text-foreground", children: [
930
1032
  "$",
931
1033
  priceUsd
932
1034
  ] }),
933
- /* @__PURE__ */ jsx4("span", { className: "text-sm text-muted-foreground", children: "/mo" })
1035
+ /* @__PURE__ */ jsx5("span", { className: "text-sm text-muted-foreground", children: "/mo" })
934
1036
  ] }),
935
- /* @__PURE__ */ jsxs4("p", { className: "mt-1 text-sm text-muted-foreground", children: [
1037
+ /* @__PURE__ */ jsxs5("p", { className: "mt-1 text-sm text-muted-foreground", children: [
936
1038
  "Includes $",
937
1039
  includedUsageUsd,
938
1040
  "/mo of AI usage"
939
1041
  ] }),
940
- /* @__PURE__ */ jsx4("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
1042
+ /* @__PURE__ */ jsx5("ul", { className: "mt-6 space-y-2.5", children: (benefits ?? [
941
1043
  `Full access to ${product}`,
942
1044
  `$${includedUsageUsd}/mo of AI usage included, every month`
943
- ]).map((benefit, i) => /* @__PURE__ */ jsx4(Benefit, { children: benefit }, i)) }),
944
- /* @__PURE__ */ jsx4(
1045
+ ]).map((benefit, i) => /* @__PURE__ */ jsx5(Benefit, { children: benefit }, i)) }),
1046
+ /* @__PURE__ */ jsx5(
945
1047
  "button",
946
1048
  {
947
1049
  type: "button",
@@ -951,13 +1053,13 @@ function SeatPaywall({
951
1053
  children: pending ? "Opening checkout\u2026" : ctaLabel ?? `Unlock ${product}`
952
1054
  }
953
1055
  ),
954
- footnote && /* @__PURE__ */ jsx4("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
1056
+ footnote && /* @__PURE__ */ jsx5("p", { className: "mt-3 text-center text-xs text-muted-foreground/70", children: footnote })
955
1057
  ] }) });
956
1058
  }
957
1059
 
958
1060
  // src/web-react/agent-session-controls.tsx
959
1061
  import { useMemo as useMemo2, useState as useState5 } from "react";
960
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1062
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
961
1063
  var HARNESS_LABELS = {
962
1064
  opencode: "OpenCode (any model)",
963
1065
  "claude-code": "Claude Code (Anthropic)",
@@ -977,12 +1079,12 @@ function harnessLabel(h) {
977
1079
  return HARNESS_LABELS[h] ?? h;
978
1080
  }
979
1081
  function ChevronDown2({ className }) {
980
- 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" }) });
1082
+ return /* @__PURE__ */ jsx6("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: "m6 9 6 6 6-6" }) });
981
1083
  }
982
1084
  function GearGlyph({ className }) {
983
- return /* @__PURE__ */ jsxs5("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
984
- /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "3" }),
985
- /* @__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" })
1085
+ return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1086
+ /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "3" }),
1087
+ /* @__PURE__ */ jsx6("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" })
986
1088
  ] });
987
1089
  }
988
1090
  var FOCUS_RING = "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-background";
@@ -994,8 +1096,8 @@ function HarnessPicker({
994
1096
  const [open, setOpen] = useState5(false);
995
1097
  const { containerRef, triggerProps } = usePopover(open, setOpen);
996
1098
  const options = available ?? Object.keys(HARNESS_LABELS);
997
- return /* @__PURE__ */ jsxs5("div", { ref: containerRef, className: "relative inline-flex", children: [
998
- /* @__PURE__ */ jsxs5(
1099
+ return /* @__PURE__ */ jsxs6("div", { ref: containerRef, className: "relative inline-flex", children: [
1100
+ /* @__PURE__ */ jsxs6(
999
1101
  "button",
1000
1102
  {
1001
1103
  type: "button",
@@ -1004,12 +1106,12 @@ function HarnessPicker({
1004
1106
  title: "Agent backend",
1005
1107
  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}`,
1006
1108
  children: [
1007
- /* @__PURE__ */ jsx5("span", { className: "truncate", children: harnessLabel(value) }),
1008
- /* @__PURE__ */ jsx5(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
1109
+ /* @__PURE__ */ jsx6("span", { className: "truncate", children: harnessLabel(value) }),
1110
+ /* @__PURE__ */ jsx6(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
1009
1111
  ]
1010
1112
  }
1011
1113
  ),
1012
- 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(
1114
+ open && /* @__PURE__ */ jsx6("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__ */ jsx6(
1013
1115
  "button",
1014
1116
  {
1015
1117
  type: "button",
@@ -1060,7 +1162,7 @@ function AgentSessionControls(props) {
1060
1162
  const { containerRef: popoverRef, triggerProps } = usePopover(open, setOpen);
1061
1163
  const selectedModel = models.find((m) => m.id === model);
1062
1164
  const showEffort = selectedModel?.supportsReasoning ?? true;
1063
- const modelPicker = /* @__PURE__ */ jsx5(
1165
+ const modelPicker = /* @__PURE__ */ jsx6(
1064
1166
  ModelPicker,
1065
1167
  {
1066
1168
  value: model,
@@ -1071,17 +1173,17 @@ function AgentSessionControls(props) {
1071
1173
  }
1072
1174
  );
1073
1175
  if (layout === "inline") {
1074
- return /* @__PURE__ */ jsxs5("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1176
+ return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1075
1177
  modelPicker,
1076
- showHarness && /* @__PURE__ */ jsx5(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1077
- showEffort && /* @__PURE__ */ jsx5(EffortPicker, { value: effort, onChange: onEffortChange })
1178
+ showHarness && /* @__PURE__ */ jsx6(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1179
+ showEffort && /* @__PURE__ */ jsx6(EffortPicker, { value: effort, onChange: onEffortChange })
1078
1180
  ] });
1079
1181
  }
1080
1182
  const hasAdvanced = showHarness || showEffort;
1081
- return /* @__PURE__ */ jsxs5("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1183
+ return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-1.5 ${className ?? ""}`, children: [
1082
1184
  modelPicker,
1083
- hasAdvanced && /* @__PURE__ */ jsxs5("div", { ref: popoverRef, className: "relative inline-flex", children: [
1084
- /* @__PURE__ */ jsx5(
1185
+ hasAdvanced && /* @__PURE__ */ jsxs6("div", { ref: popoverRef, className: "relative inline-flex", children: [
1186
+ /* @__PURE__ */ jsx6(
1085
1187
  "button",
1086
1188
  {
1087
1189
  type: "button",
@@ -1090,19 +1192,19 @@ function AgentSessionControls(props) {
1090
1192
  title: "Model settings \u2014 pick the agent backend and how hard it thinks",
1091
1193
  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}`,
1092
1194
  "data-state": open ? "open" : "closed",
1093
- children: /* @__PURE__ */ jsx5(GearGlyph, { className: "h-4 w-4" })
1195
+ children: /* @__PURE__ */ jsx6(GearGlyph, { className: "h-4 w-4" })
1094
1196
  }
1095
1197
  ),
1096
- 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: [
1097
- showHarness && /* @__PURE__ */ jsxs5("div", { className: "space-y-1.5", children: [
1098
- /* @__PURE__ */ jsx5("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
1099
- /* @__PURE__ */ jsx5(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1100
- /* @__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." })
1198
+ 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: [
1199
+ showHarness && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
1200
+ /* @__PURE__ */ jsx6("p", { className: "text-xs font-medium text-foreground", children: "Agent backend" }),
1201
+ /* @__PURE__ */ jsx6(HarnessPicker, { value: harness, onChange: onHarness, available: availableHarnesses }),
1202
+ /* @__PURE__ */ jsx6("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "The engine that runs the agent. Switching it keeps your model choice compatible." })
1101
1203
  ] }),
1102
- showEffort && /* @__PURE__ */ jsxs5("div", { className: "space-y-1.5", children: [
1103
- /* @__PURE__ */ jsx5("p", { className: "text-xs font-medium text-foreground", children: "Reasoning effort" }),
1104
- /* @__PURE__ */ jsx5(EffortPicker, { value: effort, onChange: onEffortChange }),
1105
- /* @__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." })
1204
+ showEffort && /* @__PURE__ */ jsxs6("div", { className: "space-y-1.5", children: [
1205
+ /* @__PURE__ */ jsx6("p", { className: "text-xs font-medium text-foreground", children: "Reasoning effort" }),
1206
+ /* @__PURE__ */ jsx6(EffortPicker, { value: effort, onChange: onEffortChange }),
1207
+ /* @__PURE__ */ jsx6("p", { className: "text-[11px] leading-snug text-muted-foreground", children: "How hard the agent thinks before answering. Higher is slower but more thorough." })
1106
1208
  ] })
1107
1209
  ] })
1108
1210
  ] })
@@ -1110,7 +1212,7 @@ function AgentSessionControls(props) {
1110
1212
  }
1111
1213
 
1112
1214
  // src/web-react/index.tsx
1113
- import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1215
+ import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1114
1216
  function formatModelCost(msg, models) {
1115
1217
  if (msg.promptTokens == null && msg.completionTokens == null) return null;
1116
1218
  const pricing = models.find((m) => m.id === msg.modelUsed)?.pricing;
@@ -1124,41 +1226,41 @@ function formatTokensPerSecond(msg) {
1124
1226
  return `${Math.round(msg.completionTokens / (msg.durationMs / 1e3))} tok/s`;
1125
1227
  }
1126
1228
  function RunDrillIn({ run, onClose }) {
1127
- 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: [
1128
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
1129
- /* @__PURE__ */ jsx6(
1229
+ 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: [
1230
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 border-b border-border px-4 py-3", children: [
1231
+ /* @__PURE__ */ jsx7(
1130
1232
  "span",
1131
1233
  {
1132
1234
  className: `h-2 w-2 shrink-0 rounded-full ${run.status === "running" ? "bg-warning" : run.status === "error" ? "bg-destructive" : "bg-success"}`
1133
1235
  }
1134
1236
  ),
1135
- /* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
1136
- /* @__PURE__ */ jsx6("p", { className: "truncate text-sm font-semibold", children: run.title }),
1137
- /* @__PURE__ */ jsx6("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
1237
+ /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
1238
+ /* @__PURE__ */ jsx7("p", { className: "truncate text-sm font-semibold", children: run.title }),
1239
+ /* @__PURE__ */ jsx7("p", { className: "truncate font-mono text-[11px] text-muted-foreground", children: run.toolName })
1138
1240
  ] }),
1139
- /* @__PURE__ */ jsx6(
1241
+ /* @__PURE__ */ jsx7(
1140
1242
  "button",
1141
1243
  {
1142
1244
  type: "button",
1143
1245
  onClick: onClose,
1144
1246
  "aria-label": "Close",
1145
1247
  className: "rounded-md p-1.5 text-muted-foreground transition hover:bg-accent/30 hover:text-foreground",
1146
- 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" }) })
1248
+ children: /* @__PURE__ */ jsx7("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx7("path", { d: "M18 6 6 18M6 6l12 12" }) })
1147
1249
  }
1148
1250
  )
1149
1251
  ] }),
1150
- /* @__PURE__ */ jsxs6("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
1151
- run.steps.length === 0 && /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
1152
- run.steps.map((step, i) => /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border/60 bg-background", children: [
1153
- /* @__PURE__ */ jsxs6("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
1154
- /* @__PURE__ */ jsx6("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
1155
- /* @__PURE__ */ jsx6("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
1156
- /* @__PURE__ */ jsx6("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
1252
+ /* @__PURE__ */ jsxs7("div", { className: "flex-1 space-y-3 overflow-y-auto p-4", children: [
1253
+ run.steps.length === 0 && /* @__PURE__ */ jsx7("p", { className: "text-sm text-muted-foreground", children: "No steps recorded yet." }),
1254
+ run.steps.map((step, i) => /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border/60 bg-background", children: [
1255
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-baseline gap-2 border-b border-border/40 px-3 py-1.5", children: [
1256
+ /* @__PURE__ */ jsx7("span", { className: `font-mono text-[11px] ${step.status === "error" ? "text-destructive" : "text-muted-foreground"}`, children: step.status === "error" ? "\u2717" : "$" }),
1257
+ /* @__PURE__ */ jsx7("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: step.label }),
1258
+ /* @__PURE__ */ jsx7("span", { className: "shrink-0 text-[10px] text-muted-foreground", children: new Date(step.at).toLocaleTimeString() })
1157
1259
  ] }),
1158
- 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 })
1260
+ step.detail && /* @__PURE__ */ jsx7("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 })
1159
1261
  ] }, i))
1160
1262
  ] }),
1161
- /* @__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." })
1263
+ /* @__PURE__ */ jsx7("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." })
1162
1264
  ] });
1163
1265
  }
1164
1266
  function pendingApprovalOf(call) {
@@ -1168,26 +1270,26 @@ function pendingApprovalOf(call) {
1168
1270
  }
1169
1271
  function ToolGlyph({ name, className }) {
1170
1272
  if (name.startsWith("sandbox_")) {
1171
- return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1172
- /* @__PURE__ */ jsx6("polyline", { points: "4 17 10 11 4 5" }),
1173
- /* @__PURE__ */ jsx6("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
1273
+ return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1274
+ /* @__PURE__ */ jsx7("polyline", { points: "4 17 10 11 4 5" }),
1275
+ /* @__PURE__ */ jsx7("line", { x1: "12", y1: "19", x2: "20", y2: "19" })
1174
1276
  ] });
1175
1277
  }
1176
1278
  if (name === "submit_proposal") {
1177
- return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1178
- /* @__PURE__ */ jsx6("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1179
- /* @__PURE__ */ jsx6("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
1279
+ return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1280
+ /* @__PURE__ */ jsx7("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
1281
+ /* @__PURE__ */ jsx7("path", { d: "M14 2v6h6M9 15l2 2 4-4" })
1180
1282
  ] });
1181
1283
  }
1182
1284
  if (name === "schedule_followup") {
1183
- return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
1184
- /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "9" }),
1185
- /* @__PURE__ */ jsx6("path", { d: "M12 7v5l3 3" })
1285
+ return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", "aria-hidden": true, children: [
1286
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "9" }),
1287
+ /* @__PURE__ */ jsx7("path", { d: "M12 7v5l3 3" })
1186
1288
  ] });
1187
1289
  }
1188
- return /* @__PURE__ */ jsxs6("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1189
- /* @__PURE__ */ jsx6("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
1190
- /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "4" })
1290
+ return /* @__PURE__ */ jsxs7("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
1291
+ /* @__PURE__ */ jsx7("path", { d: "M12 3v3m0 12v3M3 12h3m12 0h3" }),
1292
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "4" })
1191
1293
  ] });
1192
1294
  }
1193
1295
  function toolOutcomeOf(call) {
@@ -1221,36 +1323,36 @@ function truncate(v, max = 240) {
1221
1323
  function KvRows({ data }) {
1222
1324
  const entries = Object.entries(data).filter(([, v]) => v !== void 0 && v !== null && v !== "");
1223
1325
  if (!entries.length) return null;
1224
- 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: [
1225
- /* @__PURE__ */ jsx6("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
1226
- /* @__PURE__ */ jsx6("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
1326
+ return /* @__PURE__ */ jsx7("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1", children: entries.map(([k, v]) => /* @__PURE__ */ jsxs7("div", { className: "contents", children: [
1327
+ /* @__PURE__ */ jsx7("dt", { className: "font-mono text-[11px] text-muted-foreground", children: k }),
1328
+ /* @__PURE__ */ jsx7("dd", { className: "min-w-0 whitespace-pre-wrap break-words font-mono text-[11px] text-muted-foreground", children: truncate(v) })
1227
1329
  ] }, k)) });
1228
1330
  }
1229
1331
  function ShellDetail({ call }) {
1230
1332
  const outcome = toolOutcomeOf(call);
1231
1333
  const r = outcome?.result ?? {};
1232
- return /* @__PURE__ */ jsxs6("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
1233
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
1234
- /* @__PURE__ */ jsx6("span", { className: "select-none text-zinc-500", children: "$" }),
1235
- /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
1236
- r.exitCode != null && /* @__PURE__ */ jsxs6("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
1334
+ return /* @__PURE__ */ jsxs7("div", { className: "overflow-hidden rounded-md bg-zinc-900 font-mono text-[11px] leading-relaxed", children: [
1335
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 px-3 pt-2 text-zinc-400", children: [
1336
+ /* @__PURE__ */ jsx7("span", { className: "select-none text-zinc-500", children: "$" }),
1337
+ /* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate text-zinc-200", children: String(call.args?.command ?? "") }),
1338
+ r.exitCode != null && /* @__PURE__ */ jsxs7("span", { className: r.exitCode === 0 ? "text-success" : "text-destructive", children: [
1237
1339
  "exit ",
1238
1340
  r.exitCode
1239
1341
  ] })
1240
1342
  ] }),
1241
- /* @__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)" })
1343
+ /* @__PURE__ */ jsx7("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)" })
1242
1344
  ] });
1243
1345
  }
1244
1346
  function DefaultToolDetail({ call }) {
1245
1347
  const outcome = toolOutcomeOf(call);
1246
- return /* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
1247
- call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs6("div", { children: [
1248
- /* @__PURE__ */ jsx6("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
1249
- /* @__PURE__ */ jsx6(KvRows, { data: call.args })
1348
+ return /* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
1349
+ call.args && Object.keys(call.args).length > 0 && /* @__PURE__ */ jsxs7("div", { children: [
1350
+ /* @__PURE__ */ jsx7("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: "Called with" }),
1351
+ /* @__PURE__ */ jsx7(KvRows, { data: call.args })
1250
1352
  ] }),
1251
- outcome && /* @__PURE__ */ jsxs6("div", { children: [
1252
- /* @__PURE__ */ jsx6("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
1253
- 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) })
1353
+ outcome && /* @__PURE__ */ jsxs7("div", { children: [
1354
+ /* @__PURE__ */ jsx7("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: outcome.ok === false ? "Failed" : "Result" }),
1355
+ outcome.ok === false ? /* @__PURE__ */ jsx7("p", { className: "text-xs text-destructive", children: outcome.message ?? "Tool failed" }) : outcome.result && typeof outcome.result === "object" ? /* @__PURE__ */ jsx7(KvRows, { data: outcome.result }) : /* @__PURE__ */ jsx7("p", { className: "font-mono text-[11px] text-muted-foreground", children: truncate(outcome.result) })
1254
1356
  ] })
1255
1357
  ] });
1256
1358
  }
@@ -1266,13 +1368,13 @@ function ToolCallCard({
1266
1368
  const failed = call.status === "error" || toolOutcomeOf(call)?.ok === false;
1267
1369
  const custom = renderers?.[call.name]?.(call, message);
1268
1370
  const { pending: deciding, run: decide } = usePending();
1269
- return /* @__PURE__ */ jsxs6(
1371
+ return /* @__PURE__ */ jsxs7(
1270
1372
  "div",
1271
1373
  {
1272
1374
  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"}`,
1273
1375
  children: [
1274
- /* @__PURE__ */ jsxs6("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
1275
- /* @__PURE__ */ jsxs6(
1376
+ /* @__PURE__ */ jsxs7("div", { className: "flex w-full items-center gap-2 px-3 py-2", children: [
1377
+ /* @__PURE__ */ jsxs7(
1276
1378
  "button",
1277
1379
  {
1278
1380
  type: "button",
@@ -1280,19 +1382,19 @@ function ToolCallCard({
1280
1382
  "aria-expanded": expanded,
1281
1383
  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",
1282
1384
  children: [
1283
- /* @__PURE__ */ jsx6(
1385
+ /* @__PURE__ */ jsx7(
1284
1386
  "span",
1285
1387
  {
1286
1388
  className: `h-2 w-2 shrink-0 rounded-full ${call.status === "running" ? "animate-pulse bg-warning" : pending ? "bg-warning" : failed ? "bg-destructive" : "bg-success"}`
1287
1389
  }
1288
1390
  ),
1289
- /* @__PURE__ */ jsx6(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
1290
- /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 truncate font-medium", children: friendlyToolTitle(call) })
1391
+ /* @__PURE__ */ jsx7(ToolGlyph, { name: call.name, className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
1392
+ /* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 truncate font-medium", children: friendlyToolTitle(call) })
1291
1393
  ]
1292
1394
  }
1293
1395
  ),
1294
- pending && approval && /* @__PURE__ */ jsxs6("span", { className: "flex shrink-0 items-center gap-1", children: [
1295
- /* @__PURE__ */ jsx6(
1396
+ pending && approval && /* @__PURE__ */ jsxs7("span", { className: "flex shrink-0 items-center gap-1", children: [
1397
+ /* @__PURE__ */ jsx7(
1296
1398
  "button",
1297
1399
  {
1298
1400
  type: "button",
@@ -1302,7 +1404,7 @@ function ToolCallCard({
1302
1404
  children: "Approve"
1303
1405
  }
1304
1406
  ),
1305
- /* @__PURE__ */ jsx6(
1407
+ /* @__PURE__ */ jsx7(
1306
1408
  "button",
1307
1409
  {
1308
1410
  type: "button",
@@ -1313,8 +1415,8 @@ function ToolCallCard({
1313
1415
  }
1314
1416
  )
1315
1417
  ] }),
1316
- /* @__PURE__ */ jsx6("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : pending ? "awaiting approval" : failed ? "failed" : "done" }),
1317
- /* @__PURE__ */ jsx6(
1418
+ /* @__PURE__ */ jsx7("span", { className: "shrink-0 text-[11px] text-muted-foreground", children: call.status === "running" ? "running\u2026" : pending ? "awaiting approval" : failed ? "failed" : "done" }),
1419
+ /* @__PURE__ */ jsx7(
1318
1420
  "button",
1319
1421
  {
1320
1422
  type: "button",
@@ -1322,13 +1424,13 @@ function ToolCallCard({
1322
1424
  "aria-label": expanded ? "Collapse details" : "Expand details",
1323
1425
  "aria-expanded": expanded,
1324
1426
  className: "shrink-0 rounded p-0.5 focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1325
- children: /* @__PURE__ */ jsx6(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
1427
+ children: /* @__PURE__ */ jsx7(ChevronDown, { className: `h-3 w-3 text-muted-foreground transition-transform ${expanded ? "rotate-180" : ""}` })
1326
1428
  }
1327
1429
  )
1328
1430
  ] }),
1329
- expanded && /* @__PURE__ */ jsxs6("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
1330
- custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx6(ShellDetail, { call }) : /* @__PURE__ */ jsx6(DefaultToolDetail, { call })),
1331
- onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx6(
1431
+ expanded && /* @__PURE__ */ jsxs7("div", { className: "border-t border-border/40 px-3 py-2.5", children: [
1432
+ custom ?? (call.name === "sandbox_run_command" ? /* @__PURE__ */ jsx7(ShellDetail, { call }) : /* @__PURE__ */ jsx7(DefaultToolDetail, { call })),
1433
+ onOpenRun && call.name.startsWith("sandbox_") && /* @__PURE__ */ jsx7(
1332
1434
  "button",
1333
1435
  {
1334
1436
  type: "button",
@@ -1369,22 +1471,22 @@ function AssistantMessageImpl({
1369
1471
  const el = reasoningScrollRef.current;
1370
1472
  if (el && streaming && !content) el.scrollTop = el.scrollHeight;
1371
1473
  }, [reasoning, streaming, content]);
1372
- return /* @__PURE__ */ jsxs6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1373
- /* @__PURE__ */ jsxs6("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
1374
- /* @__PURE__ */ jsx6("span", { className: "font-semibold uppercase", children: agentLabel }),
1375
- msg.modelUsed && /* @__PURE__ */ jsx6("span", { className: "font-mono normal-case", children: msg.modelUsed }),
1376
- formatTokensPerSecond(msg) && /* @__PURE__ */ jsx6("span", { children: formatTokensPerSecond(msg) }),
1377
- formatModelCost(msg, models) && /* @__PURE__ */ jsx6("span", { children: formatModelCost(msg, models) })
1474
+ return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1475
+ /* @__PURE__ */ jsxs7("div", { className: "mb-1 flex items-baseline gap-2 text-[11px] tracking-wide text-muted-foreground", children: [
1476
+ /* @__PURE__ */ jsx7("span", { className: "font-semibold uppercase", children: agentLabel }),
1477
+ msg.modelUsed && /* @__PURE__ */ jsx7("span", { className: "font-mono normal-case", children: msg.modelUsed }),
1478
+ formatTokensPerSecond(msg) && /* @__PURE__ */ jsx7("span", { children: formatTokensPerSecond(msg) }),
1479
+ formatModelCost(msg, models) && /* @__PURE__ */ jsx7("span", { children: formatModelCost(msg, models) })
1378
1480
  ] }),
1379
- 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: [
1380
- /* @__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" }),
1381
- /* @__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 })
1481
+ reasoning && /* @__PURE__ */ jsxs7("details", { className: "mb-2 rounded-lg border-l-2 border-border/70 bg-muted/20 px-3 py-2", open: !content, children: [
1482
+ /* @__PURE__ */ jsx7("summary", { className: "cursor-pointer select-none text-xs font-medium text-muted-foreground", children: !content ? /* @__PURE__ */ jsx7("span", { className: "animate-pulse", children: "Thinking\u2026" }) : thinkMsRef.current != null ? `Thought for ${Math.max(1, Math.round(thinkMsRef.current / 1e3))}s` : "Thought process" }),
1483
+ /* @__PURE__ */ jsx7("div", { ref: reasoningScrollRef, className: "mt-2 max-h-48 overflow-y-auto whitespace-pre-wrap text-[13px] leading-relaxed text-muted-foreground", children: reasoning })
1382
1484
  ] }),
1383
- /* @__PURE__ */ jsxs6("div", { className: "text-base leading-[1.75]", children: [
1485
+ /* @__PURE__ */ jsxs7("div", { className: "text-base leading-[1.75]", children: [
1384
1486
  body,
1385
- 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 })
1487
+ streaming && content && !msg.toolCalls?.length && /* @__PURE__ */ jsx7("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 })
1386
1488
  ] }),
1387
- 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(
1489
+ msg.toolCalls && msg.toolCalls.length > 0 && /* @__PURE__ */ jsx7("div", { className: "mt-2 flex flex-col gap-1.5", children: msg.toolCalls.map((tc) => /* @__PURE__ */ jsx7(
1388
1490
  ToolCallCard,
1389
1491
  {
1390
1492
  call: tc,
@@ -1405,23 +1507,23 @@ function ThinkingRow({ agentLabel }) {
1405
1507
  const id = setInterval(() => setSeconds((s) => s + 1), 1e3);
1406
1508
  return () => clearInterval(id);
1407
1509
  }, []);
1408
- return /* @__PURE__ */ jsxs6("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1409
- /* @__PURE__ */ jsx6("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
1410
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
1411
- /* @__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" }) }),
1510
+ return /* @__PURE__ */ jsxs7("div", { className: "mx-auto w-full max-w-3xl px-6 py-3", children: [
1511
+ /* @__PURE__ */ jsx7("p", { className: "mb-1 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: agentLabel }),
1512
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2 text-base text-muted-foreground", children: [
1513
+ /* @__PURE__ */ jsx7("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "aria-hidden": true, children: /* @__PURE__ */ jsx7("path", { d: "M21 12a9 9 0 1 1-6.219-8.56", strokeLinecap: "round" }) }),
1412
1514
  "Thinking",
1413
1515
  seconds >= 3 ? ` \xB7 ${seconds}s` : "..."
1414
1516
  ] })
1415
1517
  ] });
1416
1518
  }
1417
1519
  function StreamErrorRow({ message, onRetry }) {
1418
- 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: [
1419
- /* @__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: [
1420
- /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "9" }),
1421
- /* @__PURE__ */ jsx6("path", { d: "M12 8v4m0 4h.01" })
1520
+ return /* @__PURE__ */ jsx7("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: [
1521
+ /* @__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: [
1522
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "9" }),
1523
+ /* @__PURE__ */ jsx7("path", { d: "M12 8v4m0 4h.01" })
1422
1524
  ] }),
1423
- /* @__PURE__ */ jsx6("span", { className: "min-w-0 flex-1 break-words", children: message }),
1424
- onRetry && /* @__PURE__ */ jsx6(
1525
+ /* @__PURE__ */ jsx7("span", { className: "min-w-0 flex-1 break-words", children: message }),
1526
+ onRetry && /* @__PURE__ */ jsx7(
1425
1527
  "button",
1426
1528
  {
1427
1529
  type: "button",
@@ -1448,17 +1550,17 @@ function ChatMessages({
1448
1550
  renderEmpty
1449
1551
  }) {
1450
1552
  const renderBody = useMemo3(
1451
- () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx6("p", { className: "whitespace-pre-wrap", children: content })),
1553
+ () => renderMarkdown ?? ((content) => /* @__PURE__ */ jsx7("p", { className: "whitespace-pre-wrap", children: content })),
1452
1554
  [renderMarkdown]
1453
1555
  );
1454
1556
  const lastIsUser = messages[messages.length - 1]?.role === "user";
1455
- if (messages.length === 0 && !loading && !error && renderEmpty) return /* @__PURE__ */ jsx6(Fragment3, { children: renderEmpty() });
1456
- return /* @__PURE__ */ jsxs6(Fragment3, { children: [
1557
+ if (messages.length === 0 && !loading && !error && renderEmpty) return /* @__PURE__ */ jsx7(Fragment4, { children: renderEmpty() });
1558
+ return /* @__PURE__ */ jsxs7(Fragment4, { children: [
1457
1559
  messages.map(
1458
- (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: [
1459
- /* @__PURE__ */ jsx6("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
1460
- /* @__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 }) })
1461
- ] }) }, msg.id) : /* @__PURE__ */ jsx6(
1560
+ (msg) => msg.role === "user" ? /* @__PURE__ */ jsx7("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: [
1561
+ /* @__PURE__ */ jsx7("p", { className: "mb-1 text-right text-[11px] font-semibold uppercase tracking-wide text-muted-foreground", children: userLabel }),
1562
+ /* @__PURE__ */ jsx7("div", { className: "rounded-2xl rounded-tr-md bg-primary/10 px-4 py-2.5 text-base leading-relaxed", children: /* @__PURE__ */ jsx7("p", { className: "whitespace-pre-wrap", children: msg.content }) })
1563
+ ] }) }, msg.id) : /* @__PURE__ */ jsx7(
1462
1564
  AssistantMessage,
1463
1565
  {
1464
1566
  msg,
@@ -1474,8 +1576,8 @@ function ChatMessages({
1474
1576
  msg.id
1475
1577
  )
1476
1578
  ),
1477
- loading && lastIsUser && /* @__PURE__ */ jsx6(ThinkingRow, { agentLabel }),
1478
- error && !loading && /* @__PURE__ */ jsx6(StreamErrorRow, { message: error, onRetry })
1579
+ loading && lastIsUser && /* @__PURE__ */ jsx7(ThinkingRow, { agentLabel }),
1580
+ error && !loading && /* @__PURE__ */ jsx7(StreamErrorRow, { message: error, onRetry })
1479
1581
  ] });
1480
1582
  }
1481
1583
  export {
@@ -1489,6 +1591,7 @@ export {
1489
1591
  ProviderLogo,
1490
1592
  RunDrillIn,
1491
1593
  SeatPaywall,
1594
+ WorkspaceTerminalPanel,
1492
1595
  activityTone,
1493
1596
  consumeChatStream,
1494
1597
  dispatchChatStreamLine,
@@ -1500,6 +1603,7 @@ export {
1500
1603
  nextRevealCount,
1501
1604
  pendingApprovalOf,
1502
1605
  streamChatTurn,
1606
+ tabTerminalConnectionId,
1503
1607
  usePending,
1504
1608
  usePopover,
1505
1609
  useSandboxTerminalConnection,