@wrongstack/webui 0.256.1 → 0.257.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -888,6 +888,8 @@ var useUIStore = create4()(
888
888
  dockSection: null,
889
889
  fleetMonitorOpen: false,
890
890
  agentsMonitorOpen: false,
891
+ inspectorOpen: false,
892
+ inspectorTab: "fleet",
891
893
  selectActivity: (activity) => set({ activeActivity: activity }),
892
894
  toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),
893
895
  setSidebarOpen: (open) => set({ sidebarOpen: open }),
@@ -935,20 +937,30 @@ var useUIStore = create4()(
935
937
  setDockSection: (section) => set({ dockSection: section }),
936
938
  toggleDockSection: (section) => set((s) => ({ dockSection: s.dockSection === section ? null : section })),
937
939
  setFleetMonitorOpen: (open) => set({ fleetMonitorOpen: open }),
938
- setAgentsMonitorOpen: (open) => set({ agentsMonitorOpen: open })
940
+ setAgentsMonitorOpen: (open) => set({ agentsMonitorOpen: open }),
941
+ setInspectorOpen: (open) => set({ inspectorOpen: open }),
942
+ setInspectorTab: (tab) => set({ inspectorTab: tab }),
943
+ toggleInspector: () => set((s) => ({ inspectorOpen: !s.inspectorOpen }))
939
944
  }),
940
945
  {
941
946
  name: "wrongstack-ui",
942
- version: 1,
947
+ version: 2,
943
948
  // v0 → v1: 'context'/'sessions' activities were removed and the
944
949
  // sidebar width bounds changed — coerce persisted values so a stale
945
950
  // localStorage entry can't select a panel that no longer exists.
946
- migrate: (persisted) => {
951
+ // v1 → v2: the modal FleetDrawer/AgentsDrawer were replaced by a
952
+ // single docked InspectorPanel; drop the stale drawer booleans so
953
+ // they can't force the (removed) fields back into state.
954
+ migrate: (persisted, version) => {
947
955
  const p = persisted ?? {};
948
956
  p.activeActivity = coerceActivity(p.activeActivity);
949
957
  if (typeof p.sidebarWidth === "number") {
950
958
  p.sidebarWidth = Math.max(SIDEBAR_MIN_WIDTH, Math.min(SIDEBAR_MAX_WIDTH, p.sidebarWidth));
951
959
  }
960
+ if (version < 2) {
961
+ delete p.fleetDrawerOpen;
962
+ delete p.agentsDrawerOpen;
963
+ }
952
964
  return p;
953
965
  },
954
966
  partialize: (s) => ({
@@ -961,7 +973,9 @@ var useUIStore = create4()(
961
973
  favoriteSessionIds: s.favoriteSessionIds,
962
974
  sessionNicknames: s.sessionNicknames,
963
975
  fileExplorerWidth: s.fileExplorerWidth,
964
- refineEnabled: s.refineEnabled
976
+ refineEnabled: s.refineEnabled,
977
+ inspectorOpen: s.inspectorOpen,
978
+ inspectorTab: s.inspectorTab
965
979
  })
966
980
  }
967
981
  )
@@ -2916,7 +2930,7 @@ function useWebSocket() {
2916
2930
  }
2917
2931
 
2918
2932
  // src/App.tsx
2919
- import { useEffect as useEffect44 } from "react";
2933
+ import { useEffect as useEffect45 } from "react";
2920
2934
 
2921
2935
  // src/components/ActivityBar.tsx
2922
2936
  import {
@@ -3105,8 +3119,16 @@ function ActivityBar() {
3105
3119
  {
3106
3120
  icon: /* @__PURE__ */ jsx3(LayoutGrid, { size: 16 }),
3107
3121
  label: "Fleet Monitor (Ctrl+Shift+M)",
3108
- active: useUIStore.getState().fleetMonitorOpen,
3109
- onClick: () => useUIStore.getState().setFleetMonitorOpen(!useUIStore.getState().fleetMonitorOpen)
3122
+ active: useUIStore.getState().inspectorOpen && useUIStore.getState().inspectorTab === "fleet",
3123
+ onClick: () => {
3124
+ const ui = useUIStore.getState();
3125
+ if (ui.inspectorOpen && ui.inspectorTab === "fleet") {
3126
+ ui.setInspectorOpen(false);
3127
+ } else {
3128
+ ui.setInspectorTab("fleet");
3129
+ ui.setInspectorOpen(true);
3130
+ }
3131
+ }
3110
3132
  }
3111
3133
  ),
3112
3134
  /* @__PURE__ */ jsx3(
@@ -3114,8 +3136,16 @@ function ActivityBar() {
3114
3136
  {
3115
3137
  icon: /* @__PURE__ */ jsx3(ActivityIconSvg, { size: 16 }),
3116
3138
  label: "Agents Monitor (Ctrl+Shift+A)",
3117
- active: useUIStore.getState().agentsMonitorOpen,
3118
- onClick: () => useUIStore.getState().setAgentsMonitorOpen(!useUIStore.getState().agentsMonitorOpen)
3139
+ active: useUIStore.getState().inspectorOpen && useUIStore.getState().inspectorTab === "agents",
3140
+ onClick: () => {
3141
+ const ui = useUIStore.getState();
3142
+ if (ui.inspectorOpen && ui.inspectorTab === "agents") {
3143
+ ui.setInspectorOpen(false);
3144
+ } else {
3145
+ ui.setInspectorTab("agents");
3146
+ ui.setInspectorOpen(true);
3147
+ }
3148
+ }
3119
3149
  }
3120
3150
  )
3121
3151
  ] }),
@@ -5029,7 +5059,7 @@ import {
5029
5059
  Terminal as Terminal4,
5030
5060
  Zap as Zap5
5031
5061
  } from "lucide-react";
5032
- import { memo as memo5, useCallback as useCallback10, useEffect as useEffect18, useMemo as useMemo8, useRef as useRef14, useState as useState24 } from "react";
5062
+ import { memo as memo5, useCallback as useCallback10, useEffect as useEffect19, useMemo as useMemo7, useRef as useRef14, useState as useState25 } from "react";
5033
5063
  import { VList } from "virtua";
5034
5064
 
5035
5065
  // src/components/AutonomyPicker.tsx
@@ -7744,7 +7774,7 @@ import {
7744
7774
  User,
7745
7775
  XCircle as XCircle5
7746
7776
  } from "lucide-react";
7747
- import { memo as memo3, useState as useState18 } from "react";
7777
+ import { memo as memo3, useState as useState19 } from "react";
7748
7778
  import ReactMarkdown from "react-markdown";
7749
7779
  import remarkGfm from "remark-gfm";
7750
7780
 
@@ -8096,20 +8126,28 @@ function JsonResult({
8096
8126
  }
8097
8127
 
8098
8128
  // src/components/NextStepsBar.tsx
8099
- import { ArrowRight as ArrowRight2, Lightbulb, MousePointerClick } from "lucide-react";
8100
- import { useMemo as useMemo5 } from "react";
8129
+ import { ArrowRight as ArrowRight2, Lightbulb, MousePointerClick, Timer as Timer2 } from "lucide-react";
8130
+ import { useEffect as useEffect14, useState as useState14 } from "react";
8101
8131
  import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
8102
- var NEXT_STEPS_RE = /💡\s*Next steps?\s*\n+((?:\d+\.\s+.+\n?)+)/i;
8132
+ var NEXT_STEPS_RE = /💡\s*Next steps?\s*\n+((?:\d+\.\s+.+(?:\s+auto="true")?\n?)+)/i;
8133
+ var ITEM_RE = /^(\d+)\.\s+(.+?)(?:\s+auto="true")?$/;
8103
8134
  function parseNextSteps(content) {
8104
8135
  const match = NEXT_STEPS_RE.exec(content);
8105
- if (!match?.[1]) return [];
8106
- const block = match[1];
8136
+ if (match?.[1]) {
8137
+ const block = match[1];
8138
+ return parseStepLines(block);
8139
+ }
8140
+ return parseStepLines(content);
8141
+ }
8142
+ function parseStepLines(block) {
8107
8143
  const lines = block.split("\n").filter(Boolean);
8108
8144
  const steps = [];
8109
8145
  for (const line of lines) {
8110
- const m = /^(\d+)\.\s+(.+)$/.exec(line.trim());
8146
+ const m = ITEM_RE.exec(line.trim());
8111
8147
  if (m) {
8112
- steps.push({ index: Number.parseInt(m[1], 10), text: m[2].trim() });
8148
+ const text = m[2].trim();
8149
+ const hasAuto = line.trim().endsWith('auto="true"');
8150
+ steps.push({ index: Number.parseInt(m[1], 10), text, auto: hasAuto });
8113
8151
  }
8114
8152
  }
8115
8153
  return steps.slice(0, 6);
@@ -8125,42 +8163,100 @@ function fillInput(text) {
8125
8163
  ta.dispatchEvent(new Event("input", { bubbles: true }));
8126
8164
  ta.focus();
8127
8165
  }
8166
+ function AutoCountdown({
8167
+ delayMs,
8168
+ onComplete
8169
+ }) {
8170
+ const [remaining, setRemaining] = useState14(Math.ceil(delayMs / 1e3));
8171
+ useEffect14(() => {
8172
+ if (remaining <= 0) {
8173
+ onComplete();
8174
+ return;
8175
+ }
8176
+ const timer = setTimeout(() => setRemaining((r) => r - 1), 1e3);
8177
+ return () => clearTimeout(timer);
8178
+ }, [remaining, onComplete]);
8179
+ return /* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1 text-xs text-primary font-medium", children: [
8180
+ /* @__PURE__ */ jsx23(Timer2, { className: "h-3 w-3" }),
8181
+ remaining,
8182
+ "s"
8183
+ ] });
8184
+ }
8128
8185
  function NextStepsBar({
8129
- steps
8186
+ steps,
8187
+ yoloMode = false,
8188
+ autoMode = false,
8189
+ autoDelayMs = 3e4,
8190
+ onAutoSubmit
8130
8191
  }) {
8131
8192
  if (steps.length === 0) return null;
8193
+ const showAutoCountdown = yoloMode && autoMode;
8194
+ const autoStep = showAutoCountdown ? steps.find((s) => s.auto) : void 0;
8132
8195
  return /* @__PURE__ */ jsxs21("div", { className: "mt-4 rounded-xl border border-primary/20 bg-primary/[0.03] overflow-hidden animate-message", children: [
8133
8196
  /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-2 px-3.5 py-2 border-b border-primary/10 bg-primary/[0.04]", children: [
8134
8197
  /* @__PURE__ */ jsx23("span", { className: "flex items-center justify-center w-5 h-5 rounded-md bg-primary/15 text-primary", children: /* @__PURE__ */ jsx23(Lightbulb, { className: "h-3 w-3" }) }),
8135
8198
  /* @__PURE__ */ jsx23("span", { className: "text-xs font-semibold text-foreground/90", children: "Next steps" }),
8136
- /* @__PURE__ */ jsx23("span", { className: "text-[10px] text-muted-foreground ml-auto", children: "click to fill input" })
8199
+ showAutoCountdown && autoStep ? /* @__PURE__ */ jsxs21("span", { className: "ml-auto flex items-center gap-1 text-xs text-primary", children: [
8200
+ /* @__PURE__ */ jsx23(Timer2, { className: "h-3 w-3" }),
8201
+ "auto-submitting in ",
8202
+ /* @__PURE__ */ jsx23(AutoCountdown, { delayMs: autoDelayMs, onComplete: () => onAutoSubmit?.(autoStep.text) })
8203
+ ] }) : /* @__PURE__ */ jsx23("span", { className: "text-[10px] text-muted-foreground ml-auto", children: "click to fill input" })
8137
8204
  ] }),
8138
- /* @__PURE__ */ jsx23("div", { className: "flex flex-col p-2 gap-1", children: steps.map((s) => /* @__PURE__ */ jsxs21(
8139
- "button",
8140
- {
8141
- type: "button",
8142
- onClick: () => fillInput(s.text),
8143
- className: "group flex items-center gap-2.5 w-full text-left px-3 py-2 rounded-lg transition-all\n hover:bg-primary/[0.08] hover:shadow-sm\n border border-transparent hover:border-primary/20",
8144
- title: `Click to fill: ${s.text}`,
8145
- children: [
8146
- /* @__PURE__ */ jsx23("span", { className: "flex items-center justify-center w-5 h-5 rounded-md bg-muted/80 group-hover:bg-primary/20\n text-[11px] font-mono font-semibold tabular-nums shrink-0\n text-muted-foreground group-hover:text-primary transition-colors", children: s.index }),
8147
- /* @__PURE__ */ jsx23(ArrowRight2, { className: "h-3.5 w-3.5 text-muted-foreground/60 group-hover:text-primary group-hover:translate-x-0.5 transition-all shrink-0" }),
8148
- /* @__PURE__ */ jsx23("span", { className: "text-sm leading-snug text-foreground/80 group-hover:text-foreground transition-colors flex-1 min-w-0", children: s.text }),
8149
- /* @__PURE__ */ jsx23(MousePointerClick, { className: "h-3.5 w-3.5 opacity-0 group-hover:opacity-100 text-primary/60 transition-all shrink-0" })
8150
- ]
8151
- },
8152
- s.index
8153
- )) })
8205
+ /* @__PURE__ */ jsx23("div", { className: "flex flex-col p-2 gap-1", children: steps.map((s) => {
8206
+ const isAutoSelected = showAutoCountdown && s.auto;
8207
+ return /* @__PURE__ */ jsxs21(
8208
+ "button",
8209
+ {
8210
+ type: "button",
8211
+ onClick: () => fillInput(s.text),
8212
+ className: `group flex items-center gap-2.5 w-full text-left px-3 py-2 rounded-lg transition-all border ${isAutoSelected ? "bg-primary/10 border-primary/30 ring-1 ring-primary/20" : "border-transparent hover:bg-primary/[0.08] hover:shadow-sm hover:border-primary/20"}`,
8213
+ title: `Click to fill: ${s.text}`,
8214
+ children: [
8215
+ /* @__PURE__ */ jsx23(
8216
+ "span",
8217
+ {
8218
+ className: `flex items-center justify-center w-5 h-5 rounded-md text-[11px] font-mono font-semibold tabular-nums shrink-0 transition-colors ${isAutoSelected ? "bg-primary/30 text-primary" : "bg-muted/80 group-hover:bg-primary/20 text-muted-foreground group-hover:text-primary"}`,
8219
+ children: s.index
8220
+ }
8221
+ ),
8222
+ /* @__PURE__ */ jsx23(
8223
+ ArrowRight2,
8224
+ {
8225
+ className: `h-3.5 w-3.5 shrink-0 transition-all ${isAutoSelected ? "text-primary" : "text-muted-foreground/60 group-hover:text-primary group-hover:translate-x-0.5"}`
8226
+ }
8227
+ ),
8228
+ /* @__PURE__ */ jsx23(
8229
+ "span",
8230
+ {
8231
+ className: `text-sm leading-snug flex-1 min-w-0 transition-colors ${isAutoSelected ? "text-foreground font-medium" : "text-foreground/80 group-hover:text-foreground"}`,
8232
+ children: s.text
8233
+ }
8234
+ ),
8235
+ s.auto && /* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1 text-[10px] text-primary/70", children: [
8236
+ /* @__PURE__ */ jsx23(Timer2, { className: "h-3 w-3" }),
8237
+ "auto"
8238
+ ] }),
8239
+ /* @__PURE__ */ jsx23(
8240
+ MousePointerClick,
8241
+ {
8242
+ className: `h-3.5 w-3.5 shrink-0 transition-all ${isAutoSelected ? "opacity-100 text-primary/60" : "opacity-0 group-hover:opacity-100 text-primary/60"}`
8243
+ }
8244
+ )
8245
+ ]
8246
+ },
8247
+ s.index
8248
+ );
8249
+ }) })
8154
8250
  ] });
8155
8251
  }
8156
8252
 
8157
8253
  // src/components/MessageBubble/CopyButton.tsx
8158
8254
  import { Copy as Copy3, Check as Check4 } from "lucide-react";
8159
- import { useState as useState15 } from "react";
8255
+ import { useState as useState16 } from "react";
8160
8256
 
8161
8257
  // src/components/MessageBubble/utils.tsx
8162
8258
  import { Check as Check3, Copy as Copy2, FileCode2 } from "lucide-react";
8163
- import { useCallback as useCallback8, useMemo as useMemo6, useState as useState14 } from "react";
8259
+ import { useCallback as useCallback8, useMemo as useMemo5, useState as useState15 } from "react";
8164
8260
  import rehypeHighlight from "rehype-highlight";
8165
8261
  import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
8166
8262
  async function copyToClipboard(text) {
@@ -8212,7 +8308,7 @@ function formatToolDuration(ms) {
8212
8308
  }
8213
8309
  var rehypePlugins = [rehypeHighlight];
8214
8310
  function CodeCopyButton({ text }) {
8215
- const [copied, setCopied] = useState14(false);
8311
+ const [copied, setCopied] = useState15(false);
8216
8312
  const handleCopy = useCallback8(async () => {
8217
8313
  const ok = await copyToClipboard(text);
8218
8314
  if (ok) {
@@ -8239,6 +8335,25 @@ function CodeCopyButton({ text }) {
8239
8335
  );
8240
8336
  }
8241
8337
  var markdownComponents = {
8338
+ next_steps({ children }) {
8339
+ const rawText = typeof children === "string" ? children.trim() : "";
8340
+ if (!rawText) return null;
8341
+ const steps = parseNextSteps(rawText);
8342
+ if (steps.length === 0) return null;
8343
+ return /* @__PURE__ */ jsx24(
8344
+ NextStepsBar,
8345
+ {
8346
+ steps,
8347
+ onAutoSubmit: (text) => {
8348
+ fillInput(text);
8349
+ const form = document.querySelector('form[class*="flex items-end gap-2"]');
8350
+ if (form) {
8351
+ form.dispatchEvent(new Event("submit", { bubbles: true, cancelable: true }));
8352
+ }
8353
+ }
8354
+ }
8355
+ );
8356
+ },
8242
8357
  code({
8243
8358
  inline,
8244
8359
  className,
@@ -8250,7 +8365,7 @@ var markdownComponents = {
8250
8365
  if (inline || !match) {
8251
8366
  return /* @__PURE__ */ jsx24("code", { className: cn("rounded border border-border/60 px-1.5 py-0.5 text-[0.85em] font-mono", className), ...props, children });
8252
8367
  }
8253
- const lines = useMemo6(() => codeText.split("\n"), [codeText]);
8368
+ const lines = useMemo5(() => codeText.split("\n"), [codeText]);
8254
8369
  const hasLineNumbers = lines.length > 1;
8255
8370
  return /* @__PURE__ */ jsxs22("div", { className: "not-prose relative my-3 rounded-lg border border-border overflow-hidden group/codeblock", children: [
8256
8371
  /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-3 py-1 border-b border-border text-xs", children: [
@@ -8288,7 +8403,7 @@ function CopyButton({
8288
8403
  className,
8289
8404
  label = "Copy"
8290
8405
  }) {
8291
- const [copied, setCopied] = useState15(false);
8406
+ const [copied, setCopied] = useState16(false);
8292
8407
  return /* @__PURE__ */ jsx25(
8293
8408
  "button",
8294
8409
  {
@@ -8319,7 +8434,7 @@ function CopyButton({
8319
8434
 
8320
8435
  // src/components/MessageBubble/ErrorBody.tsx
8321
8436
  import { expectDefined as expectDefined10 } from "@wrongstack/core";
8322
- import { useState as useState16 } from "react";
8437
+ import { useState as useState17 } from "react";
8323
8438
  import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
8324
8439
  function detectStackBoundary(text) {
8325
8440
  const lines = text.split("\n");
@@ -8333,7 +8448,7 @@ function detectStackBoundary(text) {
8333
8448
  }
8334
8449
  function ErrorBodyWithStack({ text }) {
8335
8450
  const idx = detectStackBoundary(text);
8336
- const [open, setOpen] = useState16(false);
8451
+ const [open, setOpen] = useState17(false);
8337
8452
  if (idx === -1) {
8338
8453
  return /* @__PURE__ */ jsx26("pre", { className: "whitespace-pre-wrap break-words font-mono text-xs leading-relaxed", children: text });
8339
8454
  }
@@ -8366,10 +8481,10 @@ function ErrorBodyWithStack({ text }) {
8366
8481
  }
8367
8482
 
8368
8483
  // src/components/MessageBubble/ToolInputView.tsx
8369
- import { useState as useState17 } from "react";
8484
+ import { useState as useState18 } from "react";
8370
8485
  import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
8371
8486
  function ToolInputView({ input }) {
8372
- const [openKeys, setOpenKeys] = useState17({});
8487
+ const [openKeys, setOpenKeys] = useState18({});
8373
8488
  if (input === null || input === void 0 || typeof input !== "object" || Array.isArray(input)) {
8374
8489
  return /* @__PURE__ */ jsx27("pre", { className: "whitespace-pre-wrap break-all text-xs font-mono", children: JSON.stringify(input, null, 2) });
8375
8490
  }
@@ -8432,10 +8547,10 @@ var MessageBubble = memo3(function MessageBubble2({
8432
8547
  isFirst = false,
8433
8548
  isContinuation = false
8434
8549
  }) {
8435
- const [expandedTools, setExpandedTools] = useState18({});
8436
- const [editing, setEditing] = useState18(false);
8437
- const [editValue, setEditValue] = useState18("");
8438
- const [showRaw, setShowRaw] = useState18(false);
8550
+ const [expandedTools, setExpandedTools] = useState19({});
8551
+ const [editing, setEditing] = useState19(false);
8552
+ const [editValue, setEditValue] = useState19("");
8553
+ const [showRaw, setShowRaw] = useState19(false);
8439
8554
  const isUser = message.role === "user";
8440
8555
  const isTool = message.role === "tool";
8441
8556
  void message.role;
@@ -8451,6 +8566,15 @@ var MessageBubble = memo3(function MessageBubble2({
8451
8566
  const inputCost = useSessionStore((s) => s.inputCost);
8452
8567
  const outputCost = useSessionStore((s) => s.outputCost);
8453
8568
  const cacheReadCost = useSessionStore((s) => s.cacheReadCost);
8569
+ const localPrefs = useLocalPrefs();
8570
+ const { autonomy, yolo } = localPrefs;
8571
+ const handleAutoSubmit = (text) => {
8572
+ addMessage({ role: "user", content: text });
8573
+ setLoading(true);
8574
+ const client2 = getWSClient(wsUrl);
8575
+ client2.sendMessage(text);
8576
+ fillInput("");
8577
+ };
8454
8578
  const isLatestAssistant = (() => {
8455
8579
  if (message.role !== "assistant" || isLoading) return false;
8456
8580
  const all = useChatStore.getState().messages;
@@ -8623,7 +8747,16 @@ var MessageBubble = memo3(function MessageBubble2({
8623
8747
  isLatestAssistant && message.content && (() => {
8624
8748
  const steps = parseNextSteps(message.content);
8625
8749
  if (steps.length === 0) return null;
8626
- return /* @__PURE__ */ jsx28(NextStepsBar, { steps });
8750
+ return /* @__PURE__ */ jsx28(
8751
+ NextStepsBar,
8752
+ {
8753
+ steps,
8754
+ yoloMode: yolo,
8755
+ autoMode: autonomy === "auto",
8756
+ autoDelayMs: localPrefs.autonomyDelayMs,
8757
+ onAutoSubmit: handleAutoSubmit
8758
+ }
8759
+ );
8627
8760
  })(),
8628
8761
  /* @__PURE__ */ jsxs26("div", { className: cn("flex items-center gap-2 px-1", isUser ? "flex-row-reverse" : "flex-row"), children: [
8629
8762
  /* @__PURE__ */ jsx28("span", { className: "text-xs text-muted-foreground/50", children: new Date(message.timestamp).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) }),
@@ -8700,18 +8833,18 @@ var MessageBubble = memo3(function MessageBubble2({
8700
8833
 
8701
8834
  // src/components/ModePicker.tsx
8702
8835
  import { Check as Check5, ChevronDown as ChevronDown6 } from "lucide-react";
8703
- import { useEffect as useEffect14, useRef as useRef11, useState as useState19 } from "react";
8836
+ import { useEffect as useEffect15, useRef as useRef11, useState as useState20 } from "react";
8704
8837
  import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
8705
8838
  function ModePicker() {
8706
8839
  const mode = useSessionStore((s) => s.mode);
8707
8840
  const modes = useSessionStore((s) => s.modes);
8708
8841
  const { listModes, switchMode } = useWebSocket();
8709
- const [open, setOpen] = useState19(false);
8842
+ const [open, setOpen] = useState20(false);
8710
8843
  const rootRef = useRef11(null);
8711
- useEffect14(() => {
8844
+ useEffect15(() => {
8712
8845
  if (open) listModes();
8713
8846
  }, [open, listModes]);
8714
- useEffect14(() => {
8847
+ useEffect15(() => {
8715
8848
  if (!open) return;
8716
8849
  const onClick = (e) => {
8717
8850
  if (!rootRef.current?.contains(e.target)) setOpen(false);
@@ -8783,18 +8916,18 @@ function ModePicker() {
8783
8916
 
8784
8917
  // src/components/ProcessMonitor.tsx
8785
8918
  import { Shield, Square as Square3, Terminal as Terminal2, X as X6 } from "lucide-react";
8786
- import { useCallback as useCallback9, useEffect as useEffect15, useRef as useRef12, useState as useState20 } from "react";
8919
+ import { useCallback as useCallback9, useEffect as useEffect16, useRef as useRef12, useState as useState21 } from "react";
8787
8920
  import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
8788
8921
  function ProcessMonitor({
8789
8922
  open,
8790
8923
  onClose,
8791
8924
  className
8792
8925
  }) {
8793
- const [processes, setProcesses] = useState20([]);
8926
+ const [processes, setProcesses] = useState21([]);
8794
8927
  const ws = useWebSocket();
8795
8928
  const offRef = useRef12(null);
8796
8929
  const pollRef = useRef12(null);
8797
- useEffect15(() => {
8930
+ useEffect16(() => {
8798
8931
  if (!open || !ws.client?.isConnected) return;
8799
8932
  ws.client.send?.({ type: "process.list" });
8800
8933
  offRef.current = ws.client.on?.("process.list", (msg) => {
@@ -8941,8 +9074,12 @@ function ProcessMonitor({
8941
9074
 
8942
9075
  // src/components/SearchOverlay.tsx
8943
9076
  import { ArrowDown as ArrowDown2, ArrowUp as ArrowUp2, Search as Search2, X as X7 } from "lucide-react";
8944
- import { useEffect as useEffect16, useMemo as useMemo7, useRef as useRef13, useState as useState21 } from "react";
9077
+ import { useEffect as useEffect17, useMemo as useMemo6, useRef as useRef13, useState as useState22 } from "react";
8945
9078
  import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
9079
+ var HIGHLIGHT_STYLES = `
9080
+ ::highlight(chat-search) { background-color: hsl(var(--primary) / 0.3); color: inherit; }
9081
+ ::highlight(chat-search-active) { background-color: hsl(var(--primary) / 0.85); color: hsl(var(--primary-foreground)); }
9082
+ `;
8946
9083
  function SearchOverlay() {
8947
9084
  const open = useUIStore((s) => s.searchOpen);
8948
9085
  const setOpen = useUIStore((s) => s.setSearchOpen);
@@ -8951,12 +9088,20 @@ function SearchOverlay() {
8951
9088
  const messages = useChatStore((s) => s.messages);
8952
9089
  const requestScrollToMessage = useUIStore((s) => s.requestScrollToMessage);
8953
9090
  const inputRef = useRef13(null);
8954
- const [activeHit, setActiveHit] = useState21(0);
8955
- const [repaintNonce, setRepaintNonce] = useState21(0);
8956
- useEffect16(() => {
9091
+ const [activeHit, setActiveHit] = useState22(0);
9092
+ const [repaintNonce, setRepaintNonce] = useState22(0);
9093
+ useEffect17(() => {
8957
9094
  if (open) requestAnimationFrame(() => inputRef.current?.focus());
8958
9095
  }, [open]);
8959
- const hits = useMemo7(() => {
9096
+ useEffect17(() => {
9097
+ const style = document.createElement("style");
9098
+ style.textContent = HIGHLIGHT_STYLES;
9099
+ document.head.appendChild(style);
9100
+ return () => {
9101
+ document.head.removeChild(style);
9102
+ };
9103
+ }, []);
9104
+ const hits = useMemo6(() => {
8960
9105
  const q = query.trim().toLowerCase();
8961
9106
  if (!q) return [];
8962
9107
  return messages.filter((m) => {
@@ -8966,10 +9111,10 @@ function SearchOverlay() {
8966
9111
  return m.content.toLowerCase().includes(q);
8967
9112
  }).map((m) => m.id);
8968
9113
  }, [messages, query]);
8969
- useEffect16(() => {
9114
+ useEffect17(() => {
8970
9115
  if (activeHit >= hits.length) setActiveHit(0);
8971
9116
  }, [hits, activeHit]);
8972
- useEffect16(() => {
9117
+ useEffect17(() => {
8973
9118
  const win = window;
8974
9119
  const highlights = win.CSS?.highlights;
8975
9120
  const HighlightCtor = win.Highlight;
@@ -9023,7 +9168,7 @@ function SearchOverlay() {
9023
9168
  }
9024
9169
  return clear;
9025
9170
  }, [query, hits, activeHit, open, repaintNonce]);
9026
- useEffect16(() => {
9171
+ useEffect17(() => {
9027
9172
  const id = hits[activeHit];
9028
9173
  if (!id) return;
9029
9174
  requestScrollToMessage(id);
@@ -9109,7 +9254,7 @@ function SearchOverlay() {
9109
9254
  // src/components/ToolGroup.tsx
9110
9255
  import { expectDefined as expectDefined12 } from "@wrongstack/core";
9111
9256
  import { CheckCircle2 as CheckCircle26, ChevronDown as ChevronDown7, ChevronRight as ChevronRight5, Loader2 as Loader22, Terminal as Terminal3, XCircle as XCircle6 } from "lucide-react";
9112
- import { memo as memo4, useState as useState22 } from "react";
9257
+ import { memo as memo4, useState as useState23 } from "react";
9113
9258
  import { jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
9114
9259
  function formatDuration2(ms) {
9115
9260
  if (ms < 1e3) return `${ms}ms`;
@@ -9123,7 +9268,7 @@ var ToolGroup = memo4(function ToolGroup2({
9123
9268
  defaultOpen = false,
9124
9269
  isContinuation = false
9125
9270
  }) {
9126
- const [open, setOpen] = useState22(defaultOpen);
9271
+ const [open, setOpen] = useState23(defaultOpen);
9127
9272
  if (tools.length === 1) {
9128
9273
  return /* @__PURE__ */ jsx32(MessageBubble, { message: expectDefined12(tools[0]), isFirst: true, isContinuation });
9129
9274
  }
@@ -9182,7 +9327,7 @@ import {
9182
9327
  Sparkles as Sparkles4,
9183
9328
  Zap as Zap4
9184
9329
  } from "lucide-react";
9185
- import { useEffect as useEffect17, useState as useState23 } from "react";
9330
+ import { useEffect as useEffect18, useState as useState24 } from "react";
9186
9331
  import { Fragment as Fragment8, jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
9187
9332
  var CARDS = [
9188
9333
  {
@@ -9257,8 +9402,8 @@ function WelcomeScreen() {
9257
9402
  const wsConnected = useConfigStore((s) => s.wsConnected);
9258
9403
  const wsUrl = useConfigStore((s) => s.wsUrl);
9259
9404
  const setCurrentView = useUIStore((s) => s.setCurrentView);
9260
- const [savedCount, setSavedCount] = useState23(void 0);
9261
- useEffect17(() => {
9405
+ const [savedCount, setSavedCount] = useState24(void 0);
9406
+ useEffect18(() => {
9262
9407
  if (!wsConnected) return;
9263
9408
  const client2 = getWSClient(wsUrl);
9264
9409
  const off = client2.on("providers.saved", (msg) => {
@@ -9274,7 +9419,7 @@ function WelcomeScreen() {
9274
9419
  const recentPrompts = promptHistory.slice(0, 6);
9275
9420
  const { listSessions, resumeSession } = useWebSocket();
9276
9421
  const historyEntries = useHistoryStore((s) => s.entries);
9277
- useEffect17(() => {
9422
+ useEffect18(() => {
9278
9423
  if (wsConnected && historyEntries.length === 0) listSessions(10);
9279
9424
  }, [wsConnected]);
9280
9425
  const sessionNicknames = useUIStore((s) => s.sessionNicknames);
@@ -9518,12 +9663,12 @@ function ChatView() {
9518
9663
  const nickname = useUIStore((s) => sessionId ? s.sessionNicknames[sessionId] : void 0);
9519
9664
  const setSessionNickname = useUIStore((s) => s.setSessionNickname);
9520
9665
  const sessionTitle = session?.title;
9521
- const [renamingTitle, setRenamingTitle] = useState24(false);
9522
- const [titleDraft, setTitleDraft] = useState24("");
9666
+ const [renamingTitle, setRenamingTitle] = useState25(false);
9667
+ const [titleDraft, setTitleDraft] = useState25("");
9523
9668
  const historyEntries = useHistoryStore((s) => s.entries);
9524
- const [switcherOpen, setSwitcherOpen] = useState24(false);
9669
+ const [switcherOpen, setSwitcherOpen] = useState25(false);
9525
9670
  const switcherRef = useRef14(null);
9526
- useEffect18(() => {
9671
+ useEffect19(() => {
9527
9672
  if (!switcherOpen) return;
9528
9673
  const onClick = (e) => {
9529
9674
  if (!switcherRef.current?.contains(e.target)) setSwitcherOpen(false);
@@ -9540,10 +9685,10 @@ function ChatView() {
9540
9685
  }, [switcherOpen]);
9541
9686
  const { provider, model } = useConfigStore();
9542
9687
  const vlistRef = useRef14(null);
9543
- const rows = useMemo8(() => buildChatRows(messages), [messages]);
9688
+ const rows = useMemo7(() => buildChatRows(messages), [messages]);
9544
9689
  const childCountRef = useRef14(0);
9545
9690
  childCountRef.current = rows.length + 1;
9546
- const rowIndexById = useMemo8(() => {
9691
+ const rowIndexById = useMemo7(() => {
9547
9692
  const map = /* @__PURE__ */ new Map();
9548
9693
  rows.forEach((row, i) => {
9549
9694
  if (row.kind === "user") map.set(row.message.id, i);
@@ -9563,19 +9708,19 @@ function ChatView() {
9563
9708
  const ws = getWSClient();
9564
9709
  ws?.send?.({ type: "autonomy.switch", payload: { mode } });
9565
9710
  }, []);
9566
- const [processOpen, setProcessOpen] = useState24(false);
9567
- const [checkpointOpen, setCheckpointOpen] = useState24(false);
9568
- const [breakdownOpen, setBreakdownOpen] = useState24(false);
9569
- useEffect18(() => {
9711
+ const [processOpen, setProcessOpen] = useState25(false);
9712
+ const [checkpointOpen, setCheckpointOpen] = useState25(false);
9713
+ const [breakdownOpen, setBreakdownOpen] = useState25(false);
9714
+ useEffect19(() => {
9570
9715
  const handler = () => setBreakdownOpen(true);
9571
9716
  document.addEventListener("open:context-breakdown", handler);
9572
9717
  return () => document.removeEventListener("open:context-breakdown", handler);
9573
9718
  }, []);
9574
9719
  const ctxPct = maxContext > 0 && lastInputTokens > 0 ? Math.round(lastInputTokens / maxContext * 100) : 0;
9575
9720
  const ctxTone = ctxPct >= 85 ? "bg-red-500/15 text-red-600 dark:text-red-400" : ctxPct >= 70 ? "bg-amber-500/15 text-amber-600 dark:text-amber-400" : "bg-muted text-muted-foreground";
9576
- const [pinnedToBottom, setPinnedToBottom] = useState24(true);
9577
- const [unreadCount, setUnreadCount] = useState24(0);
9578
- const [scrolledDeep, setScrolledDeep] = useState24(false);
9721
+ const [pinnedToBottom, setPinnedToBottom] = useState25(true);
9722
+ const [unreadCount, setUnreadCount] = useState25(0);
9723
+ const [scrolledDeep, setScrolledDeep] = useState25(false);
9579
9724
  const lastSeenCount = useRef14(messages.length);
9580
9725
  const handleScroll = useCallback10(() => {
9581
9726
  const h = vlistRef.current;
@@ -9589,7 +9734,15 @@ function ChatView() {
9589
9734
  }
9590
9735
  setScrolledDeep(h.scrollOffset > h.viewportSize && h.scrollSize > h.viewportSize * 2.5);
9591
9736
  }, []);
9592
- useEffect18(() => {
9737
+ const handleHistorySelect = useCallback10(
9738
+ (sessionId2) => {
9739
+ const ws = getWSClient();
9740
+ ws?.resumeSession?.(sessionId2);
9741
+ setSwitcherOpen(false);
9742
+ },
9743
+ []
9744
+ );
9745
+ useEffect19(() => {
9593
9746
  const h = vlistRef.current;
9594
9747
  if (!h) return;
9595
9748
  if (pinnedToBottom) {
@@ -9600,7 +9753,7 @@ function ChatView() {
9600
9753
  if (delta > 0) setUnreadCount(delta);
9601
9754
  }
9602
9755
  }, [messages, pinnedToBottom]);
9603
- useEffect18(() => {
9756
+ useEffect19(() => {
9604
9757
  setPinnedToBottom(true);
9605
9758
  setUnreadCount(0);
9606
9759
  lastSeenCount.current = useChatStore.getState().messages.length;
@@ -9608,7 +9761,7 @@ function ChatView() {
9608
9761
  vlistRef.current?.scrollToIndex(childCountRef.current - 1, { align: "end" });
9609
9762
  });
9610
9763
  }, [sessionId]);
9611
- useEffect18(() => {
9764
+ useEffect19(() => {
9612
9765
  if (!scrollTarget) return;
9613
9766
  const idx = rowIndexById.get(scrollTarget.id);
9614
9767
  if (idx === void 0) return;
@@ -9623,14 +9776,49 @@ function ChatView() {
9623
9776
  const scrollToTop = useCallback10(() => {
9624
9777
  vlistRef.current?.scrollToIndex(0, { align: "start", smooth: true });
9625
9778
  }, []);
9626
- const [runStartedAt, setRunStartedAt] = useState24(null);
9627
- const [nowTick, setNowTick] = useState24(() => Date.now());
9779
+ const [runStartedAt, setRunStartedAt] = useState25(null);
9780
+ const [nowTick, setNowTick] = useState25(() => Date.now());
9628
9781
  const streamAnchor = useRef14(null);
9629
- useEffect18(() => {
9782
+ const runningStatus = useMemo7(() => {
9783
+ const last = messages[messages.length - 1];
9784
+ const runningTools = messages.filter((m) => m.role === "tool" && m.toolResult === void 0);
9785
+ let label = "Thinking\u2026";
9786
+ if (runningTools.length > 0) {
9787
+ const names = Array.from(new Set(runningTools.map((t) => t.toolName).filter(Boolean)));
9788
+ const preview = names.slice(0, 2).join(", ");
9789
+ const more = names.length > 2 ? ` +${names.length - 2}` : "";
9790
+ label = runningTools.length === 1 ? `Running ${preview || "tool"}\u2026` : `Running ${runningTools.length} tools (${preview}${more})\u2026`;
9791
+ } else if (last?.role === "assistant" && last.content) {
9792
+ label = "Writing reply\u2026";
9793
+ } else if (last?.role === "tool" && last.toolResult !== void 0) {
9794
+ label = "Thinking about the next step\u2026";
9795
+ }
9796
+ const elapsedSec = runStartedAt ? Math.max(0, Math.floor((nowTick - runStartedAt) / 1e3)) : 0;
9797
+ const elapsed = elapsedSec < 60 ? `${elapsedSec}s` : `${Math.floor(elapsedSec / 60)}m ${elapsedSec % 60}s`;
9798
+ let speedLabel = "";
9799
+ const streamingBubble = last?.role === "assistant" && last.streaming && last.content ? last : null;
9800
+ if (streamingBubble) {
9801
+ const anchor = streamAnchor.current;
9802
+ if (!anchor || anchor.id !== streamingBubble.id) {
9803
+ streamAnchor.current = { id: streamingBubble.id, at: Date.now(), len: streamingBubble.content.length };
9804
+ } else {
9805
+ const dt = Math.max(1, nowTick - anchor.at);
9806
+ const dl = Math.max(0, streamingBubble.content.length - anchor.len);
9807
+ if (dt > 500 && dl > 0) {
9808
+ const cps = dl * 1e3 / dt;
9809
+ speedLabel = cps >= 1e3 ? `${(cps / 1e3).toFixed(1)}k ch/s` : `${Math.round(cps)} ch/s`;
9810
+ }
9811
+ }
9812
+ } else if (streamAnchor.current) {
9813
+ streamAnchor.current = null;
9814
+ }
9815
+ return { label, elapsed, speedLabel };
9816
+ }, [messages, nowTick, runStartedAt]);
9817
+ useEffect19(() => {
9630
9818
  if (isLoading && runStartedAt === null) setRunStartedAt(Date.now());
9631
9819
  if (!isLoading && runStartedAt !== null) setRunStartedAt(null);
9632
9820
  }, [isLoading, runStartedAt]);
9633
- useEffect18(() => {
9821
+ useEffect19(() => {
9634
9822
  if (!isLoading) return;
9635
9823
  const t = setInterval(() => setNowTick(Date.now()), 500);
9636
9824
  return () => clearInterval(t);
@@ -9740,11 +9928,7 @@ function ChatView() {
9740
9928
  "button",
9741
9929
  {
9742
9930
  type: "button",
9743
- onClick: () => {
9744
- const ws = getWSClient();
9745
- ws?.resumeSession?.(e.id);
9746
- setSwitcherOpen(false);
9747
- },
9931
+ onClick: () => handleHistorySelect(e.id),
9748
9932
  className: cn(
9749
9933
  "w-full text-left px-2 py-1.5 rounded text-xs hover:bg-accent transition-colors",
9750
9934
  e.isCurrent && "bg-primary/10"
@@ -9933,69 +10117,27 @@ function ChatView() {
9933
10117
  className: cn("mx-auto max-w-5xl w-full px-4", compactMode ? "pb-3" : "pb-8"),
9934
10118
  children: [
9935
10119
  /* @__PURE__ */ jsx35(ThinkingBubble, {}),
9936
- isLoading && (() => {
9937
- const last = messages[messages.length - 1];
9938
- const runningTools = messages.filter(
9939
- (m) => m.role === "tool" && m.toolResult === void 0
9940
- );
9941
- let label = "Thinking\u2026";
9942
- if (runningTools.length > 0) {
9943
- const names = Array.from(
9944
- new Set(runningTools.map((t) => t.toolName).filter(Boolean))
9945
- );
9946
- const preview = names.slice(0, 2).join(", ");
9947
- const more = names.length > 2 ? ` +${names.length - 2}` : "";
9948
- label = runningTools.length === 1 ? `Running ${preview || "tool"}\u2026` : `Running ${runningTools.length} tools (${preview}${more})\u2026`;
9949
- } else if (last?.role === "assistant" && last.content) {
9950
- label = "Writing reply\u2026";
9951
- } else if (last?.role === "tool" && last.toolResult !== void 0) {
9952
- label = "Thinking about the next step\u2026";
9953
- }
9954
- const elapsedSec = runStartedAt ? Math.max(0, Math.floor((nowTick - runStartedAt) / 1e3)) : 0;
9955
- const elapsed = elapsedSec < 60 ? `${elapsedSec}s` : `${Math.floor(elapsedSec / 60)}m ${elapsedSec % 60}s`;
9956
- let speedLabel = "";
9957
- const streamingBubble = last?.role === "assistant" && last.streaming && last.content ? last : null;
9958
- if (streamingBubble) {
9959
- const anchor = streamAnchor.current;
9960
- if (!anchor || anchor.id !== streamingBubble.id) {
9961
- streamAnchor.current = {
9962
- id: streamingBubble.id,
9963
- at: Date.now(),
9964
- len: streamingBubble.content.length
9965
- };
9966
- } else {
9967
- const dt = Math.max(1, nowTick - anchor.at);
9968
- const dl = Math.max(0, streamingBubble.content.length - anchor.len);
9969
- if (dt > 500 && dl > 0) {
9970
- const cps = dl * 1e3 / dt;
9971
- speedLabel = cps >= 1e3 ? `${(cps / 1e3).toFixed(1)}k ch/s` : `${Math.round(cps)} ch/s`;
9972
- }
9973
- }
9974
- } else if (streamAnchor.current) {
9975
- streamAnchor.current = null;
9976
- }
9977
- return /* @__PURE__ */ jsxs33("div", { className: "flex gap-3 animate-message", children: [
9978
- /* @__PURE__ */ jsx35("div", { className: "flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center bg-accent text-accent-foreground ring-2 ring-offset-2 ring-offset-background ring-accent/20", children: /* @__PURE__ */ jsx35(Bot4, { className: "h-4 w-4" }) }),
9979
- /* @__PURE__ */ jsx35("div", { className: "flex flex-col gap-1.5", children: /* @__PURE__ */ jsx35("div", { className: "rounded-2xl px-4 py-3 bg-card border text-foreground", children: /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-3 text-sm", children: [
9980
- /* @__PURE__ */ jsxs33("span", { className: "flex gap-1", children: [
9981
- /* @__PURE__ */ jsx35("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce [animation-delay:-0.3s]" }),
9982
- /* @__PURE__ */ jsx35("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce [animation-delay:-0.15s]" }),
9983
- /* @__PURE__ */ jsx35("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce" })
9984
- ] }),
9985
- /* @__PURE__ */ jsx35("span", { className: "text-foreground/90", children: label }),
9986
- /* @__PURE__ */ jsx35("span", { className: "text-xs text-muted-foreground tabular-nums", children: elapsed }),
9987
- iteration && /* @__PURE__ */ jsxs33("span", { className: "text-xs text-muted-foreground tabular-nums", children: [
9988
- "\xB7 iter ",
9989
- iteration.index,
9990
- iteration.max > 0 ? `/${iteration.max}` : ""
9991
- ] }),
9992
- speedLabel && /* @__PURE__ */ jsxs33("span", { className: "text-xs text-muted-foreground/80 tabular-nums", children: [
9993
- "\xB7 ",
9994
- speedLabel
9995
- ] })
9996
- ] }) }) })
9997
- ] });
9998
- })()
10120
+ isLoading && /* @__PURE__ */ jsxs33("div", { className: "flex gap-3 animate-message", children: [
10121
+ /* @__PURE__ */ jsx35("div", { className: "flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center bg-accent text-accent-foreground ring-2 ring-offset-2 ring-offset-background ring-accent/20", children: /* @__PURE__ */ jsx35(Bot4, { className: "h-4 w-4" }) }),
10122
+ /* @__PURE__ */ jsx35("div", { className: "flex flex-col gap-1.5", children: /* @__PURE__ */ jsx35("div", { className: "rounded-2xl px-4 py-3 bg-card border text-foreground", children: /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-3 text-sm", children: [
10123
+ /* @__PURE__ */ jsxs33("span", { className: "flex gap-1", children: [
10124
+ /* @__PURE__ */ jsx35("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce [animation-delay:-0.3s]" }),
10125
+ /* @__PURE__ */ jsx35("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce [animation-delay:-0.15s]" }),
10126
+ /* @__PURE__ */ jsx35("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce" })
10127
+ ] }),
10128
+ /* @__PURE__ */ jsx35("span", { className: "text-foreground/90", children: runningStatus.label }),
10129
+ /* @__PURE__ */ jsx35("span", { className: "text-xs text-muted-foreground tabular-nums", children: runningStatus.elapsed }),
10130
+ iteration && /* @__PURE__ */ jsxs33("span", { className: "text-xs text-muted-foreground tabular-nums", children: [
10131
+ "\xB7 iter ",
10132
+ iteration.index,
10133
+ iteration.max > 0 ? `/${iteration.max}` : ""
10134
+ ] }),
10135
+ runningStatus.speedLabel && /* @__PURE__ */ jsxs33("span", { className: "text-xs text-muted-foreground/80 tabular-nums", children: [
10136
+ "\xB7 ",
10137
+ runningStatus.speedLabel
10138
+ ] })
10139
+ ] }) }) })
10140
+ ] })
9999
10141
  ]
10000
10142
  },
10001
10143
  "__live"
@@ -10062,7 +10204,7 @@ function ChatView() {
10062
10204
 
10063
10205
  // src/components/CodeEditor.tsx
10064
10206
  import { X as X8, Circle as Circle3 } from "lucide-react";
10065
- import { useCallback as useCallback11, useEffect as useEffect19, useMemo as useMemo9, useRef as useRef15 } from "react";
10207
+ import { useCallback as useCallback11, useEffect as useEffect20, useMemo as useMemo8, useRef as useRef15 } from "react";
10066
10208
  import Editor, { loader } from "@monaco-editor/react";
10067
10209
  import * as monaco2 from "monaco-editor";
10068
10210
 
@@ -10509,13 +10651,13 @@ function CodeEditor() {
10509
10651
  const updateContent = useFileStore((s) => s.updateContent);
10510
10652
  const { theme: appTheme } = useTheme();
10511
10653
  const editorRef = useRef15(null);
10512
- const activeFile = useMemo9(
10654
+ const activeFile = useMemo8(
10513
10655
  () => openFiles.find((f) => f.path === activeFilePath) ?? null,
10514
10656
  [openFiles, activeFilePath]
10515
10657
  );
10516
10658
  const language = activeFilePath ? getLanguage(activeFilePath) : "plaintext";
10517
10659
  const monacoTheme = getMonacoTheme();
10518
- useEffect19(() => {
10660
+ useEffect20(() => {
10519
10661
  const resolved = getMonacoTheme();
10520
10662
  monaco2.editor.setTheme(resolved);
10521
10663
  }, [appTheme]);
@@ -10531,7 +10673,7 @@ function CodeEditor() {
10531
10673
  },
10532
10674
  [activeFilePath, updateContent]
10533
10675
  );
10534
- useEffect19(() => {
10676
+ useEffect20(() => {
10535
10677
  const onKeyDown = (e) => {
10536
10678
  const mod = e.ctrlKey || e.metaKey;
10537
10679
  const tag = e.target?.tagName?.toLowerCase();
@@ -10597,7 +10739,7 @@ function CodeEditor() {
10597
10739
 
10598
10740
  // src/components/ConfirmDialog.tsx
10599
10741
  import { AlertTriangle as AlertTriangle3, FileEdit, Globe as Globe2, ShieldAlert, Terminal as Terminal5, Wrench as Wrench5 } from "lucide-react";
10600
- import { useEffect as useEffect20, useRef as useRef16 } from "react";
10742
+ import { useEffect as useEffect21, useRef as useRef16 } from "react";
10601
10743
 
10602
10744
  // src/components/ui/dialog.tsx
10603
10745
  import * as DialogPrimitive from "@radix-ui/react-dialog";
@@ -10733,7 +10875,7 @@ function ConfirmDialog() {
10733
10875
  }
10734
10876
  hideConfirm();
10735
10877
  };
10736
- useEffect20(() => {
10878
+ useEffect21(() => {
10737
10879
  if (!showConfirmDialog) return;
10738
10880
  const onKey = (e) => {
10739
10881
  const target = e.target;
@@ -10857,7 +10999,7 @@ function ConfirmDialog() {
10857
10999
  }
10858
11000
 
10859
11001
  // src/components/ConfirmModal.tsx
10860
- import { useEffect as useEffect21 } from "react";
11002
+ import { useEffect as useEffect22 } from "react";
10861
11003
  import { create as create15 } from "zustand";
10862
11004
  import { jsx as jsx39, jsxs as jsxs37 } from "react/jsx-runtime";
10863
11005
  var useConfirmModalStore = create15()((set, get) => ({
@@ -10879,7 +11021,7 @@ function confirmModal(options) {
10879
11021
  function ConfirmModalHost() {
10880
11022
  const request = useConfirmModalStore((s) => s.request);
10881
11023
  const settle = useConfirmModalStore((s) => s.settle);
10882
- useEffect21(() => {
11024
+ useEffect22(() => {
10883
11025
  if (!request) return;
10884
11026
  const onKey = (e) => {
10885
11027
  if (e.key === "Enter") {
@@ -10922,19 +11064,19 @@ function ConfirmModalHost() {
10922
11064
 
10923
11065
  // src/components/ConnectionBanner.tsx
10924
11066
  import { Loader2 as Loader23, RotateCcw as RotateCcw4, WifiOff, X as X10 } from "lucide-react";
10925
- import { useEffect as useEffect22, useState as useState25 } from "react";
11067
+ import { useEffect as useEffect23, useState as useState26 } from "react";
10926
11068
  import { jsx as jsx40, jsxs as jsxs38 } from "react/jsx-runtime";
10927
11069
  function ConnectionBanner() {
10928
11070
  const wsStatus = useConfigStore((s) => s.wsStatus);
10929
11071
  const wsUrl = useConfigStore((s) => s.wsUrl);
10930
- const [dismissed, setDismissed] = useState25(false);
10931
- const [now, setNow] = useState25(Date.now());
10932
- useEffect22(() => {
11072
+ const [dismissed, setDismissed] = useState26(false);
11073
+ const [now, setNow] = useState26(Date.now());
11074
+ useEffect23(() => {
10933
11075
  if (wsStatus.state !== "reconnecting") return;
10934
11076
  const id = setInterval(() => setNow(Date.now()), 500);
10935
11077
  return () => clearInterval(id);
10936
11078
  }, [wsStatus.state]);
10937
- useEffect22(() => {
11079
+ useEffect23(() => {
10938
11080
  if (wsStatus.state === "open") setDismissed(false);
10939
11081
  }, [wsStatus.state]);
10940
11082
  if (wsStatus.state === "open" || wsStatus.state === "connecting") return null;
@@ -11026,7 +11168,7 @@ var ErrorBoundary = class extends Component {
11026
11168
 
11027
11169
  // src/components/QuickModelSwitcher.tsx
11028
11170
  import { ArrowRight as ArrowRight4, Cpu as Cpu6, Search as Search4 } from "lucide-react";
11029
- import { useEffect as useEffect23, useMemo as useMemo10, useRef as useRef17, useState as useState26 } from "react";
11171
+ import { useEffect as useEffect24, useMemo as useMemo9, useRef as useRef17, useState as useState27 } from "react";
11030
11172
 
11031
11173
  // src/components/QuickModelSwitcher.filter.ts
11032
11174
  function buildModelCandidates(saved, modelsByProvider, query, currentProvider, currentModel) {
@@ -11058,17 +11200,17 @@ import { jsx as jsx42, jsxs as jsxs40 } from "react/jsx-runtime";
11058
11200
  function QuickModelSwitcher() {
11059
11201
  const open = useUIStore((s) => s.modelSwitcherOpen);
11060
11202
  const setOpen = useUIStore((s) => s.setModelSwitcherOpen);
11061
- const [query, setQuery] = useState26("");
11062
- const [selected, setSelected] = useState26(0);
11063
- const [saved, setSaved] = useState26([]);
11064
- const [modelsByProvider, setModelsByProvider] = useState26({});
11203
+ const [query, setQuery] = useState27("");
11204
+ const [selected, setSelected] = useState27(0);
11205
+ const [saved, setSaved] = useState27([]);
11206
+ const [modelsByProvider, setModelsByProvider] = useState27({});
11065
11207
  const inputRef = useRef17(null);
11066
11208
  const wsUrl = useConfigStore((s) => s.wsUrl);
11067
11209
  const currentProvider = useConfigStore((s) => s.provider);
11068
11210
  const currentModel = useConfigStore((s) => s.model);
11069
11211
  const paletteOpen = useUIStore((s) => s.paletteOpen);
11070
11212
  const { listSavedProviders, listProviderModels, switchModel } = useWebSocket();
11071
- useEffect23(() => {
11213
+ useEffect24(() => {
11072
11214
  const onKey = (e) => {
11073
11215
  const mod = e.ctrlKey || e.metaKey;
11074
11216
  if (mod && e.key.toLowerCase() === "m" && !e.shiftKey && !e.altKey) {
@@ -11085,7 +11227,7 @@ function QuickModelSwitcher() {
11085
11227
  window.addEventListener("keydown", onKey);
11086
11228
  return () => window.removeEventListener("keydown", onKey);
11087
11229
  }, [open, paletteOpen]);
11088
- useEffect23(() => {
11230
+ useEffect24(() => {
11089
11231
  const client2 = getWSClient(wsUrl);
11090
11232
  const offSaved = client2.on("providers.saved", (msg) => {
11091
11233
  const p = msg.payload;
@@ -11100,14 +11242,14 @@ function QuickModelSwitcher() {
11100
11242
  offModels();
11101
11243
  };
11102
11244
  }, [wsUrl]);
11103
- useEffect23(() => {
11245
+ useEffect24(() => {
11104
11246
  if (!open) return;
11105
11247
  setQuery("");
11106
11248
  setSelected(0);
11107
11249
  listSavedProviders();
11108
11250
  requestAnimationFrame(() => inputRef.current?.focus());
11109
11251
  }, [open, listSavedProviders]);
11110
- useEffect23(() => {
11252
+ useEffect24(() => {
11111
11253
  if (!open) return;
11112
11254
  for (const sp of saved) {
11113
11255
  if (!modelsByProvider[sp.id]) {
@@ -11115,7 +11257,7 @@ function QuickModelSwitcher() {
11115
11257
  }
11116
11258
  }
11117
11259
  }, [open, saved, modelsByProvider, listProviderModels]);
11118
- const candidates = useMemo10(
11260
+ const candidates = useMemo9(
11119
11261
  () => buildModelCandidates(
11120
11262
  saved,
11121
11263
  modelsByProvider,
@@ -11125,7 +11267,7 @@ function QuickModelSwitcher() {
11125
11267
  ),
11126
11268
  [saved, modelsByProvider, query, currentProvider, currentModel]
11127
11269
  );
11128
- useEffect23(() => {
11270
+ useEffect24(() => {
11129
11271
  if (selected >= candidates.length) setSelected(0);
11130
11272
  }, [candidates.length, selected]);
11131
11273
  const commit = (idx) => {
@@ -11238,7 +11380,7 @@ import {
11238
11380
  X as X11,
11239
11381
  Zap as Zap6
11240
11382
  } from "lucide-react";
11241
- import { useState as useState28, useEffect as useEffect24, useCallback as useCallback13 } from "react";
11383
+ import { useState as useState29, useEffect as useEffect25, useCallback as useCallback13 } from "react";
11242
11384
 
11243
11385
  // src/components/ui/input.tsx
11244
11386
  import * as React3 from "react";
@@ -11467,7 +11609,7 @@ import {
11467
11609
  Plus,
11468
11610
  Trash2 as Trash22
11469
11611
  } from "lucide-react";
11470
- import { useState as useState27, useCallback as useCallback12 } from "react";
11612
+ import { useState as useState28, useCallback as useCallback12 } from "react";
11471
11613
  import { Fragment as Fragment10, jsx as jsx48, jsxs as jsxs44 } from "react/jsx-runtime";
11472
11614
  var PROVIDER_FAMILIES = ["anthropic", "openai", "google", "openai-compatible"];
11473
11615
  function ProviderSection({
@@ -11487,15 +11629,15 @@ function ProviderSection({
11487
11629
  catalogQuery,
11488
11630
  setCatalogQuery
11489
11631
  }) {
11490
- const [showAddKeyForm, setShowAddKeyForm] = useState27(null);
11491
- const [newKeyLabel, setNewKeyLabel] = useState27("");
11492
- const [newKeyValue, setNewKeyValue] = useState27("");
11493
- const [showNewKeyValue, setShowNewKeyValue] = useState27(false);
11494
- const [showAddProviderForm, setShowAddProviderForm] = useState27(false);
11495
- const [newProviderId, setNewProviderId] = useState27("");
11496
- const [newProviderFamily, setNewProviderFamily] = useState27("openai-compatible");
11497
- const [newProviderBaseUrl, setNewProviderBaseUrl] = useState27("");
11498
- const [newProviderApiKey, setNewProviderApiKey] = useState27("");
11632
+ const [showAddKeyForm, setShowAddKeyForm] = useState28(null);
11633
+ const [newKeyLabel, setNewKeyLabel] = useState28("");
11634
+ const [newKeyValue, setNewKeyValue] = useState28("");
11635
+ const [showNewKeyValue, setShowNewKeyValue] = useState28(false);
11636
+ const [showAddProviderForm, setShowAddProviderForm] = useState28(false);
11637
+ const [newProviderId, setNewProviderId] = useState28("");
11638
+ const [newProviderFamily, setNewProviderFamily] = useState28("openai-compatible");
11639
+ const [newProviderBaseUrl, setNewProviderBaseUrl] = useState28("");
11640
+ const [newProviderApiKey, setNewProviderApiKey] = useState28("");
11499
11641
  const handleAddKey = useCallback12(
11500
11642
  (providerId) => {
11501
11643
  if (!newKeyLabel.trim() || !newKeyValue.trim()) return;
@@ -11879,16 +12021,16 @@ function SettingsPanel() {
11879
12021
  },
11880
12022
  [localPrefs, updatePrefs]
11881
12023
  );
11882
- const [catalogProviders, setCatalogProviders] = useState28([]);
11883
- const [catalogModels, setCatalogModels] = useState28({});
11884
- const [savedProviders, setSavedProviders] = useState28([]);
11885
- const [isLoadingCatalog, setIsLoadingCatalog] = useState28(false);
11886
- const [isLoadingModels, setIsLoadingModels] = useState28(false);
11887
- const [isLoadingSaved, setIsLoadingSaved] = useState28(false);
11888
- const [providerTab, setProviderTab] = useState28("catalog");
11889
- const [catalogQuery, setCatalogQuery] = useState28("");
12024
+ const [catalogProviders, setCatalogProviders] = useState29([]);
12025
+ const [catalogModels, setCatalogModels] = useState29({});
12026
+ const [savedProviders, setSavedProviders] = useState29([]);
12027
+ const [isLoadingCatalog, setIsLoadingCatalog] = useState29(false);
12028
+ const [isLoadingModels, setIsLoadingModels] = useState29(false);
12029
+ const [isLoadingSaved, setIsLoadingSaved] = useState29(false);
12030
+ const [providerTab, setProviderTab] = useState29("catalog");
12031
+ const [catalogQuery, setCatalogQuery] = useState29("");
11890
12032
  const currentCatalogProvider = catalogProviders.find((p) => p.id === provider);
11891
- useEffect24(() => {
12033
+ useEffect25(() => {
11892
12034
  const handleProviderCatalog = (msg) => {
11893
12035
  if (msg.type === "provider.catalog") {
11894
12036
  const payload = msg.payload;
@@ -12447,7 +12589,7 @@ import {
12447
12589
  Network as Network2,
12448
12590
  Zap as Zap7
12449
12591
  } from "lucide-react";
12450
- import { useCallback as useCallback14, useEffect as useEffect25, useState as useState29 } from "react";
12592
+ import { useCallback as useCallback14, useEffect as useEffect26, useState as useState30 } from "react";
12451
12593
  import { jsx as jsx51, jsxs as jsxs47 } from "react/jsx-runtime";
12452
12594
  function ProviderCard({
12453
12595
  provider,
@@ -12532,9 +12674,9 @@ function ApiKeyInput({
12532
12674
  providerId,
12533
12675
  onSave
12534
12676
  }) {
12535
- const [key, setKey] = useState29("");
12536
- const [label, setLabel] = useState29("default");
12537
- const [isLoading, setIsLoading] = useState29(false);
12677
+ const [key, setKey] = useState30("");
12678
+ const [label, setLabel] = useState30("default");
12679
+ const [isLoading, setIsLoading] = useState30(false);
12538
12680
  const handleSave = async () => {
12539
12681
  if (!key.trim()) return;
12540
12682
  setIsLoading(true);
@@ -12588,15 +12730,15 @@ function SetupScreen() {
12588
12730
  const { setCurrentView } = useUIStore();
12589
12731
  const { provider, model, setProvider, setModel, wsConnected, wsUrl } = useConfigStore();
12590
12732
  const ws = useWebSocket();
12591
- const [step, setStep] = useState29("provider");
12592
- const [catalogProviders, setCatalogProviders] = useState29([]);
12593
- const [catalogModels, setCatalogModels] = useState29({});
12594
- const [savedProviders, setSavedProviders] = useState29([]);
12595
- const [isLoadingCatalog, setIsLoadingCatalog] = useState29(false);
12596
- const [isLoadingModels, setIsLoadingModels] = useState29(false);
12597
- const [selectedProvider, setSelectedProvider] = useState29(null);
12598
- const [selectedModel, setSelectedModel] = useState29(null);
12599
- useEffect25(() => {
12733
+ const [step, setStep] = useState30("provider");
12734
+ const [catalogProviders, setCatalogProviders] = useState30([]);
12735
+ const [catalogModels, setCatalogModels] = useState30({});
12736
+ const [savedProviders, setSavedProviders] = useState30([]);
12737
+ const [isLoadingCatalog, setIsLoadingCatalog] = useState30(false);
12738
+ const [isLoadingModels, setIsLoadingModels] = useState30(false);
12739
+ const [selectedProvider, setSelectedProvider] = useState30(null);
12740
+ const [selectedModel, setSelectedModel] = useState30(null);
12741
+ useEffect26(() => {
12600
12742
  if (!wsConnected) return;
12601
12743
  const wsClient = getWSClient(wsUrl);
12602
12744
  const off1 = wsClient.on("provider.catalog", (msg) => {
@@ -12638,7 +12780,7 @@ function SetupScreen() {
12638
12780
  off3?.();
12639
12781
  };
12640
12782
  }, [wsConnected, wsUrl, provider, model]);
12641
- useEffect25(() => {
12783
+ useEffect26(() => {
12642
12784
  if (!selectedProvider || !wsConnected) return;
12643
12785
  const wsClient = getWSClient(wsUrl);
12644
12786
  if (!catalogModels[selectedProvider]) {
@@ -12844,7 +12986,7 @@ function SetupScreen() {
12844
12986
 
12845
12987
  // src/components/SessionsDashboard.tsx
12846
12988
  import { Clock as Clock9, Cpu as Cpu10, FolderGit2, Wifi, WifiOff as WifiOff2, Loader2 as Loader27 } from "lucide-react";
12847
- import { useCallback as useCallback15, useEffect as useEffect26, useState as useState30 } from "react";
12989
+ import { useCallback as useCallback15, useEffect as useEffect27, useState as useState31 } from "react";
12848
12990
  import { jsx as jsx52, jsxs as jsxs48 } from "react/jsx-runtime";
12849
12991
  function agentIcon(status) {
12850
12992
  switch (status) {
@@ -12907,9 +13049,9 @@ function fmtTimeAgo(iso) {
12907
13049
  return `${Math.floor(min / 60)}h ago`;
12908
13050
  }
12909
13051
  function SessionsDashboard() {
12910
- const [sessions, setSessions] = useState30([]);
12911
- const [loading, setLoading] = useState30(true);
12912
- const [error, setError] = useState30(null);
13052
+ const [sessions, setSessions] = useState31([]);
13053
+ const [loading, setLoading] = useState31(true);
13054
+ const [error, setError] = useState31(null);
12913
13055
  const fetchSessions = useCallback15(async () => {
12914
13056
  try {
12915
13057
  const res = await fetch("/api/sessions");
@@ -12930,7 +13072,7 @@ function SessionsDashboard() {
12930
13072
  setLoading(false);
12931
13073
  }
12932
13074
  }, []);
12933
- useEffect26(() => {
13075
+ useEffect27(() => {
12934
13076
  void fetchSessions();
12935
13077
  const t = setInterval(fetchSessions, 5e3);
12936
13078
  return () => clearInterval(t);
@@ -13023,7 +13165,7 @@ function SessionsDashboard() {
13023
13165
 
13024
13166
  // src/components/ShortcutsOverlay.tsx
13025
13167
  import { Keyboard as Keyboard3, X as X12 } from "lucide-react";
13026
- import { useEffect as useEffect27 } from "react";
13168
+ import { useEffect as useEffect28 } from "react";
13027
13169
  import { jsx as jsx53, jsxs as jsxs49 } from "react/jsx-runtime";
13028
13170
  var SHORTCUTS = [
13029
13171
  {
@@ -13085,7 +13227,7 @@ var SHORTCUTS = [
13085
13227
  function ShortcutsOverlay() {
13086
13228
  const open = useUIStore((s) => s.shortcutsOpen);
13087
13229
  const setOpen = useUIStore((s) => s.setShortcutsOpen);
13088
- useEffect27(() => {
13230
+ useEffect28(() => {
13089
13231
  const onKey = (e) => {
13090
13232
  const target = e.target;
13091
13233
  const tag = target?.tagName?.toLowerCase();
@@ -13179,7 +13321,7 @@ import {
13179
13321
  ReactFlowProvider
13180
13322
  } from "@xyflow/react";
13181
13323
  import "@xyflow/react/dist/style.css";
13182
- import { useCallback as useCallback16, useEffect as useEffect28, useState as useState31 } from "react";
13324
+ import { useCallback as useCallback16, useEffect as useEffect29, useState as useState32 } from "react";
13183
13325
  import {
13184
13326
  Bot as Bot8,
13185
13327
  Cpu as Cpu11,
@@ -13525,8 +13667,8 @@ function AgentFlowCanvas({ containerRef }) {
13525
13667
  const counters = useVizStore((s) => s.counters);
13526
13668
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
13527
13669
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);
13528
- const [selectedNode, setSelectedNode] = useState31(null);
13529
- useEffect28(() => {
13670
+ const [selectedNode, setSelectedNode] = useState32(null);
13671
+ useEffect29(() => {
13530
13672
  const rfNodes = [];
13531
13673
  const rfEdges = [];
13532
13674
  rfNodes.push({
@@ -13700,7 +13842,7 @@ function AgentFlowCanvas({ containerRef }) {
13700
13842
  setEdges(rfEdges);
13701
13843
  setTimeout(() => fitView({ padding: 0.2, duration: 300 }), 50);
13702
13844
  }, [session, projectName, iteration, fleetAgents, cost, lastInputTokens, maxContext, setNodes, setEdges, fitView]);
13703
- useEffect28(() => {
13845
+ useEffect29(() => {
13704
13846
  if (vizEvents.length === 0) return;
13705
13847
  const latestEvent = vizEvents[0];
13706
13848
  if (!latestEvent) return;
@@ -13906,7 +14048,7 @@ function AgentFlowCanvasWithProvider(props) {
13906
14048
 
13907
14049
  // src/components/SidePanel/index.tsx
13908
14050
  import { PanelLeftClose } from "lucide-react";
13909
- import { useEffect as useEffect35 } from "react";
14051
+ import { useEffect as useEffect36 } from "react";
13910
14052
 
13911
14053
  // src/components/FileExplorer.tsx
13912
14054
  import {
@@ -13927,7 +14069,7 @@ import {
13927
14069
  Loader2 as Loader28,
13928
14070
  Minimize2
13929
14071
  } from "lucide-react";
13930
- import { useCallback as useCallback17, useEffect as useEffect29, useMemo as useMemo12, useRef as useRef19, useState as useState32 } from "react";
14072
+ import { useCallback as useCallback17, useEffect as useEffect30, useMemo as useMemo11, useRef as useRef19, useState as useState33 } from "react";
13931
14073
  import { jsx as jsx56, jsxs as jsxs51 } from "react/jsx-runtime";
13932
14074
  var EXT_ICONS = {
13933
14075
  // ── Code ──
@@ -14048,10 +14190,10 @@ function TreeNodeItem({
14048
14190
  onSelect,
14049
14191
  onOpen
14050
14192
  }) {
14051
- const [expanded, setExpanded] = useState32(depth < 1);
14193
+ const [expanded, setExpanded] = useState33(depth < 1);
14052
14194
  const activeFilePath = useFileStore((s) => s.activeFilePath);
14053
14195
  const isActive = node.type === "file" && node.path === activeFilePath;
14054
- useEffect29(() => {
14196
+ useEffect30(() => {
14055
14197
  if (forceExpand !== null) setExpanded(forceExpand);
14056
14198
  }, [forceExpand]);
14057
14199
  if (node.type === "directory") {
@@ -14153,7 +14295,7 @@ function FileExplorer() {
14153
14295
  const segments = cwd.replace(/\\/g, "/").split("/").filter(Boolean);
14154
14296
  return (segments[segments.length - 1] ?? "") === projectName;
14155
14297
  })();
14156
- const breadcrumbs = useMemo12(() => {
14298
+ const breadcrumbs = useMemo11(() => {
14157
14299
  if (!cwd || !projectName) return [];
14158
14300
  const norm = cwd.replace(/\\/g, "/");
14159
14301
  const segments = norm.split("/").filter(Boolean);
@@ -14180,7 +14322,7 @@ function FileExplorer() {
14180
14322
  }));
14181
14323
  }, [cwd, projectName]);
14182
14324
  const bcRef = useRef19(null);
14183
- useEffect29(() => {
14325
+ useEffect30(() => {
14184
14326
  const el = bcRef.current;
14185
14327
  if (el && breadcrumbs.length > 1) {
14186
14328
  el.scrollLeft = el.scrollWidth;
@@ -14189,8 +14331,8 @@ function FileExplorer() {
14189
14331
  const handleBreadcrumbClick = useCallback17((crumbPath) => {
14190
14332
  getWSClient().send({ type: "working_dir.set", payload: { path: crumbPath } });
14191
14333
  }, []);
14192
- const [contextMenu, setContextMenu] = useState32(null);
14193
- useEffect29(() => {
14334
+ const [contextMenu, setContextMenu] = useState33(null);
14335
+ useEffect30(() => {
14194
14336
  if (!contextMenu) return;
14195
14337
  const close = () => setContextMenu(null);
14196
14338
  const onKey = (e) => {
@@ -14231,9 +14373,9 @@ function FileExplorer() {
14231
14373
  const parent = norm.split("/").slice(0, -1).join("/") || norm;
14232
14374
  getWSClient().send({ type: "working_dir.set", payload: { path: parent } });
14233
14375
  }, [cwd]);
14234
- const [showSpinner, setShowSpinner] = useState32(false);
14376
+ const [showSpinner, setShowSpinner] = useState33(false);
14235
14377
  const spinnerTimer = useRef19(null);
14236
- useEffect29(() => {
14378
+ useEffect30(() => {
14237
14379
  if (treeLoading) {
14238
14380
  spinnerTimer.current = setTimeout(() => setShowSpinner(true), 150);
14239
14381
  } else {
@@ -14244,9 +14386,9 @@ function FileExplorer() {
14244
14386
  if (spinnerTimer.current) clearTimeout(spinnerTimer.current);
14245
14387
  };
14246
14388
  }, [treeLoading]);
14247
- const [selectedPath, setSelectedPath] = useState32(null);
14248
- const [globalExpand, setGlobalExpand] = useState32(null);
14249
- const dirCount = useMemo12(() => {
14389
+ const [selectedPath, setSelectedPath] = useState33(null);
14390
+ const [globalExpand, setGlobalExpand] = useState33(null);
14391
+ const dirCount = useMemo11(() => {
14250
14392
  let count = 0;
14251
14393
  const walk = (nodes) => {
14252
14394
  for (const n of nodes) {
@@ -14257,7 +14399,7 @@ function FileExplorer() {
14257
14399
  walk(tree);
14258
14400
  return count;
14259
14401
  }, [tree]);
14260
- const cwdStats = useMemo12(() => {
14402
+ const cwdStats = useMemo11(() => {
14261
14403
  let files = 0;
14262
14404
  let dirs = 0;
14263
14405
  for (const n of tree) {
@@ -14298,7 +14440,7 @@ function FileExplorer() {
14298
14440
  );
14299
14441
  setSelectedPath(null);
14300
14442
  }, []);
14301
- useEffect29(() => {
14443
+ useEffect30(() => {
14302
14444
  if (activeFilePath) setSelectedPath(null);
14303
14445
  }, [activeFilePath]);
14304
14446
  if (showSpinner) {
@@ -14512,7 +14654,7 @@ import {
14512
14654
  UserCheck,
14513
14655
  Trash2 as Trash23
14514
14656
  } from "lucide-react";
14515
- import { useEffect as useEffect30, useState as useState33 } from "react";
14657
+ import { useEffect as useEffect31, useState as useState34 } from "react";
14516
14658
  import { jsx as jsx57, jsxs as jsxs52 } from "react/jsx-runtime";
14517
14659
  var TYPE_ICONS = {
14518
14660
  note: FileText5,
@@ -14536,12 +14678,15 @@ function fmtTime(iso) {
14536
14678
  function MailboxPanel({ className }) {
14537
14679
  const messages = useMailboxStore((s) => s.messages);
14538
14680
  const agents = useMailboxStore((s) => s.agents);
14539
- const [collapsed, setCollapsed] = useState33(false);
14540
- const [deleting, setDeleting] = useState33(false);
14681
+ const [collapsed, setCollapsed] = useState34(false);
14682
+ const [deleting, setDeleting] = useState34(false);
14541
14683
  const { client: client2 } = useWebSocket();
14542
- const [ready, setReady] = useState33(client2.status.state === "open");
14543
- useEffect30(() => client2.onStatus((s) => setReady(s.state === "open")), [client2]);
14544
- useEffect30(() => {
14684
+ const [ready, setReady] = useState34(client2.status.state === "open");
14685
+ useEffect31(() => {
14686
+ const off = client2.onStatus((s) => setReady(s.state === "open"));
14687
+ return () => off();
14688
+ }, [client2]);
14689
+ useEffect31(() => {
14545
14690
  if (!ready) return;
14546
14691
  client2.send({ type: "mailbox.messages", payload: { limit: 30 } });
14547
14692
  client2.send({ type: "mailbox.agents", payload: {} });
@@ -14560,7 +14705,7 @@ function MailboxPanel({ className }) {
14560
14705
  setDeleting(true);
14561
14706
  client2.send({ type: "mailbox.clear" });
14562
14707
  }
14563
- useEffect30(() => {
14708
+ useEffect31(() => {
14564
14709
  if (deleting && messages.length === 0) setDeleting(false);
14565
14710
  }, [deleting, messages.length]);
14566
14711
  return /* @__PURE__ */ jsxs52("div", { className: cn("rounded-lg border border-border bg-card/60 backdrop-blur-sm", className), children: [
@@ -14669,22 +14814,22 @@ function MailboxPanel({ className }) {
14669
14814
 
14670
14815
  // src/components/ProjectsPanel.tsx
14671
14816
  import { ExternalLink, Folder as Folder3, FolderPlus, History as History3, Loader2 as Loader29 } from "lucide-react";
14672
- import { useCallback as useCallback18, useEffect as useEffect31, useRef as useRef20, useState as useState34 } from "react";
14817
+ import { useCallback as useCallback18, useEffect as useEffect32, useRef as useRef20, useState as useState35 } from "react";
14673
14818
  import { jsx as jsx58, jsxs as jsxs53 } from "react/jsx-runtime";
14674
14819
  function ProjectsPanel({ fullView }) {
14675
- const [projects, setProjects] = useState34([]);
14676
- const [loading, setLoading] = useState34(true);
14677
- const [adding, setAdding] = useState34(false);
14678
- const [folderPath, setFolderPath] = useState34("");
14679
- const [projectName, setProjectName] = useState34("");
14680
- const [dialogOpen, setDialogOpen] = useState34(false);
14820
+ const [projects, setProjects] = useState35([]);
14821
+ const [loading, setLoading] = useState35(true);
14822
+ const [adding, setAdding] = useState35(false);
14823
+ const [folderPath, setFolderPath] = useState35("");
14824
+ const [projectName, setProjectName] = useState35("");
14825
+ const [dialogOpen, setDialogOpen] = useState35(false);
14681
14826
  const projectNameRef = useRef20(null);
14682
- const [confirmSwitch, setConfirmSwitch] = useState34({ open: false, project: null, agentCount: 0 });
14827
+ const [confirmSwitch, setConfirmSwitch] = useState35({ open: false, project: null, agentCount: 0 });
14683
14828
  const fetchProjects = useCallback18(() => {
14684
14829
  const ws = getWSClient();
14685
14830
  ws.send({ type: "projects.list" });
14686
14831
  }, []);
14687
- useEffect31(() => {
14832
+ useEffect32(() => {
14688
14833
  setLoading(true);
14689
14834
  const ws = getWSClient();
14690
14835
  const offList = ws.on("projects.list", (msg) => {
@@ -14958,11 +15103,11 @@ function ProjectsPanel({ fullView }) {
14958
15103
 
14959
15104
  // src/components/SidePanel/AgentsPanel.tsx
14960
15105
  import { Bot as Bot10, LayoutGrid as LayoutGrid2, Wrench as Wrench8 } from "lucide-react";
14961
- import { useMemo as useMemo14, useState as useState36 } from "react";
15106
+ import { useMemo as useMemo13, useState as useState37 } from "react";
14962
15107
 
14963
15108
  // src/components/FleetPanel.tsx
14964
15109
  import { Bot as Bot9, Check as Check7, ChevronDown as ChevronDown9, ChevronRight as ChevronRight8, Clock as Clock11, Copy as Copy4, Cpu as Cpu12, Crown, Wrench as Wrench7, X as X14, Zap as Zap9 } from "lucide-react";
14965
- import { useCallback as useCallback19, useMemo as useMemo13, useState as useState35 } from "react";
15110
+ import { useCallback as useCallback19, useMemo as useMemo12, useState as useState36 } from "react";
14966
15111
 
14967
15112
  // src/components/ui/sparkline.tsx
14968
15113
  import { jsx as jsx59 } from "react/jsx-runtime";
@@ -15038,7 +15183,7 @@ function AgentDetail({
15038
15183
  const active = agent.status === "running";
15039
15184
  const tool = agent.currentTool ?? agent.lastTool;
15040
15185
  const elapsed = Date.now() - agent.startedAt;
15041
- const [copied, setCopied] = useState35(false);
15186
+ const [copied, setCopied] = useState36(false);
15042
15187
  const leaderId = useFleetStore((s) => s.leaderId);
15043
15188
  const isLeader = agent.id === leaderId;
15044
15189
  const handleCopy = useCallback19(async (text) => {
@@ -15339,9 +15484,9 @@ function FleetPanel({
15339
15484
  className
15340
15485
  }) {
15341
15486
  const agents = useFleetStore((s) => s.agents);
15342
- const [collapsed, setCollapsed] = useState35(true);
15343
- const [selectedId, setSelectedId] = useState35(null);
15344
- const list = useMemo13(() => {
15487
+ const [collapsed, setCollapsed] = useState36(true);
15488
+ const [selectedId, setSelectedId] = useState36(null);
15489
+ const list = useMemo12(() => {
15345
15490
  const arr = Array.from(agents.values());
15346
15491
  arr.sort((x, y) => {
15347
15492
  const xa = x.status === "running" ? 0 : 1;
@@ -15454,8 +15599,8 @@ function AgentRow2({ agent, onClick }) {
15454
15599
  function AgentsPanel() {
15455
15600
  const fleetAgents = useFleetStore((s) => s.agents);
15456
15601
  const setCurrentView = useUIStore((s) => s.setCurrentView);
15457
- const [selectedAgentId, setSelectedAgentId] = useState36(null);
15458
- const fleetList = useMemo14(() => {
15602
+ const [selectedAgentId, setSelectedAgentId] = useState37(null);
15603
+ const fleetList = useMemo13(() => {
15459
15604
  const arr = Array.from(fleetAgents.values());
15460
15605
  arr.sort((x, y) => {
15461
15606
  const xa = x.status === "running" ? 0 : 1;
@@ -15502,7 +15647,7 @@ function AgentsPanel() {
15502
15647
 
15503
15648
  // src/components/SidePanel/HistoryPanel.tsx
15504
15649
  import { LayoutGrid as LayoutGrid3 } from "lucide-react";
15505
- import { useEffect as useEffect33, useState as useState38 } from "react";
15650
+ import { useEffect as useEffect34, useState as useState39 } from "react";
15506
15651
 
15507
15652
  // src/components/SidePanel/SessionList.tsx
15508
15653
  import {
@@ -15514,7 +15659,7 @@ import {
15514
15659
  Trash2 as Trash24,
15515
15660
  X as X15
15516
15661
  } from "lucide-react";
15517
- import { useCallback as useCallback20, useEffect as useEffect32, useMemo as useMemo15, useState as useState37 } from "react";
15662
+ import { useCallback as useCallback20, useEffect as useEffect33, useMemo as useMemo14, useState as useState38 } from "react";
15518
15663
  import { Fragment as Fragment15, jsx as jsx62, jsxs as jsxs56 } from "react/jsx-runtime";
15519
15664
  var formatRelative = (iso) => {
15520
15665
  const ts = Date.parse(iso);
@@ -15545,10 +15690,10 @@ function SessionList({
15545
15690
  const toggleFavoriteSession = useUIStore((s) => s.toggleFavoriteSession);
15546
15691
  const sessionNicknames = useUIStore((s) => s.sessionNicknames);
15547
15692
  const setSessionNickname = useUIStore((s) => s.setSessionNickname);
15548
- const [renamingId, setRenamingId] = useState37(null);
15549
- const [renameDraft, setRenameDraft] = useState37("");
15550
- const [resumingId, setResumingId] = useState37(null);
15551
- useEffect32(() => {
15693
+ const [renamingId, setRenamingId] = useState38(null);
15694
+ const [renameDraft, setRenameDraft] = useState38("");
15695
+ const [resumingId, setResumingId] = useState38(null);
15696
+ useEffect33(() => {
15552
15697
  if (resumingId && historyEntries.some((e) => e.id === resumingId && e.isCurrent)) {
15553
15698
  setResumingId(null);
15554
15699
  }
@@ -15561,7 +15706,7 @@ function SessionList({
15561
15706
  },
15562
15707
  [resumeSession]
15563
15708
  );
15564
- const emptySessionIds = useMemo15(
15709
+ const emptySessionIds = useMemo14(
15565
15710
  () => getEmptySessionIds(historyEntries),
15566
15711
  [historyEntries]
15567
15712
  );
@@ -15775,8 +15920,8 @@ function HistoryPanel() {
15775
15920
  const { listSessions, resumeSession, deleteSession } = useWebSocket();
15776
15921
  const setCurrentView = useUIStore((s) => s.setCurrentView);
15777
15922
  const activeSessionId = useSessionStore((s) => s.session?.id);
15778
- const [query, setQuery] = useState38("");
15779
- useEffect33(() => {
15923
+ const [query, setQuery] = useState39("");
15924
+ useEffect34(() => {
15780
15925
  void activeSessionId;
15781
15926
  if (wsConnected) listSessions(50);
15782
15927
  }, [wsConnected, activeSessionId, listSessions]);
@@ -15827,7 +15972,7 @@ import {
15827
15972
  Wifi as Wifi2,
15828
15973
  WifiOff as WifiOff3
15829
15974
  } from "lucide-react";
15830
- import { useCallback as useCallback21, useEffect as useEffect34, useMemo as useMemo16, useState as useState39 } from "react";
15975
+ import { useCallback as useCallback21, useEffect as useEffect35, useMemo as useMemo15, useState as useState40 } from "react";
15831
15976
  import { jsx as jsx64, jsxs as jsxs58 } from "react/jsx-runtime";
15832
15977
  function fmtCost4(v) {
15833
15978
  if (v <= 0) return "$0.000";
@@ -15954,15 +16099,15 @@ function SessionPanel() {
15954
16099
  },
15955
16100
  [localPrefs, updatePrefs]
15956
16101
  );
15957
- const [breakdownOpen, setBreakdownOpen] = useState39(false);
16102
+ const [breakdownOpen, setBreakdownOpen] = useState40(false);
15958
16103
  const startedAt = session?.startedAt ?? null;
15959
- const [now, setNow] = useState39(() => Date.now());
15960
- useEffect34(() => {
16104
+ const [now, setNow] = useState40(() => Date.now());
16105
+ useEffect35(() => {
15961
16106
  if (!startedAt) return;
15962
16107
  const t = setInterval(() => setNow(Date.now()), 1e3);
15963
16108
  return () => clearInterval(t);
15964
16109
  }, [startedAt]);
15965
- const runningAgents = useMemo16(
16110
+ const runningAgents = useMemo15(
15966
16111
  () => Array.from(fleetAgents.values()).filter((a) => a.status === "running").length,
15967
16112
  [fleetAgents]
15968
16113
  );
@@ -16331,7 +16476,7 @@ function SidePanel() {
16331
16476
  const setSidebarWidth = useUIStore((s) => s.setSidebarWidth);
16332
16477
  const wsConnected = useConfigStore((s) => s.wsConnected);
16333
16478
  const { client: client2 } = useWebSocket();
16334
- useEffect35(() => {
16479
+ useEffect36(() => {
16335
16480
  if (activeActivity !== "files" || !wsConnected) return;
16336
16481
  useFileStore.getState().setTreeLoading(true);
16337
16482
  const cwd = useSessionStore.getState().cwd;
@@ -16398,22 +16543,22 @@ function SidePanel() {
16398
16543
 
16399
16544
  // src/components/WorkspaceDock.tsx
16400
16545
  import { Bot as Bot11, GitBranch as GitBranch3, ListTodo as ListTodo2, Maximize2 as Maximize22, Rocket as Rocket4, Target as Target3, Users as Users3 } from "lucide-react";
16401
- import { useCallback as useCallback26, useEffect as useEffect41, useMemo as useMemo17, useRef as useRef24, useState as useState46 } from "react";
16546
+ import { useCallback as useCallback26, useEffect as useEffect42, useMemo as useMemo16, useRef as useRef24, useState as useState47 } from "react";
16402
16547
 
16403
16548
  // src/components/CollabPanel.tsx
16404
16549
  import { Eye as Eye2, LogIn, LogOut, MessageSquareWarning, Pause as Pause5, Play as Play6, Users as Users2 } from "lucide-react";
16405
- import { useEffect as useEffect36, useState as useState40 } from "react";
16550
+ import { useEffect as useEffect37, useState as useState41 } from "react";
16406
16551
  import { jsx as jsx66, jsxs as jsxs60 } from "react/jsx-runtime";
16407
16552
  function CollabPanel({ sessionId, className }) {
16408
- const [participants, setParticipants] = useState40([]);
16409
- const [joined, setJoined] = useState40(false);
16410
- const [joinedRole, setJoinedRole] = useState40(null);
16411
- const [error, setError] = useState40(null);
16412
- const [openAnnotationCount, setOpenAnnotationCount] = useState40(0);
16413
- const [paused, setPaused] = useState40(false);
16553
+ const [participants, setParticipants] = useState41([]);
16554
+ const [joined, setJoined] = useState41(false);
16555
+ const [joinedRole, setJoinedRole] = useState41(null);
16556
+ const [error, setError] = useState41(null);
16557
+ const [openAnnotationCount, setOpenAnnotationCount] = useState41(0);
16558
+ const [paused, setPaused] = useState41(false);
16414
16559
  const wsUrl = useConfigStore((s) => s.wsUrl);
16415
16560
  const client2 = getWSClient(wsUrl);
16416
- useEffect36(() => {
16561
+ useEffect37(() => {
16417
16562
  const offs = [];
16418
16563
  offs.push(
16419
16564
  client2.on("collab.state", (msg) => {
@@ -16701,7 +16846,7 @@ import {
16701
16846
  TrendingUp,
16702
16847
  Minus
16703
16848
  } from "lucide-react";
16704
- import { useEffect as useEffect37, useState as useState41 } from "react";
16849
+ import { useEffect as useEffect38, useState as useState42 } from "react";
16705
16850
  import { jsx as jsx67, jsxs as jsxs61 } from "react/jsx-runtime";
16706
16851
  var TREND_ICON = {
16707
16852
  up: /* @__PURE__ */ jsx67(TrendingUp, { className: "h-3.5 w-3.5 text-emerald-500" }),
@@ -16736,8 +16881,8 @@ var STATE_CONFIG = {
16736
16881
  }
16737
16882
  };
16738
16883
  function GoalPanel({ goal, className }) {
16739
- const [collapsed, setCollapsed] = useState41(false);
16740
- useEffect37(() => {
16884
+ const [collapsed, setCollapsed] = useState42(false);
16885
+ useEffect38(() => {
16741
16886
  const ws = getWSClient();
16742
16887
  ws?.send?.({ type: "goal.get" });
16743
16888
  const timer = setInterval(() => {
@@ -16745,7 +16890,7 @@ function GoalPanel({ goal, className }) {
16745
16890
  }, 1e4);
16746
16891
  return () => clearInterval(timer);
16747
16892
  }, []);
16748
- useEffect37(() => {
16893
+ useEffect38(() => {
16749
16894
  if (!goal || goal.goalState === "completed" || goal.goalState === "failed" || goal.goalState === "abandoned") {
16750
16895
  setCollapsed(true);
16751
16896
  }
@@ -16865,11 +17010,11 @@ function GoalPanel({ goal, className }) {
16865
17010
  }
16866
17011
 
16867
17012
  // src/components/WorkDashboard.tsx
16868
- import { useState as useState45 } from "react";
17013
+ import { useState as useState46 } from "react";
16869
17014
 
16870
17015
  // src/components/TodosPanel.tsx
16871
17016
  import { CheckCircle2 as CheckCircle214, Circle as Circle7, Clock as Clock13, Trash2 as Trash25 } from "lucide-react";
16872
- import { useCallback as useCallback23, useEffect as useEffect38, useRef as useRef21, useState as useState42 } from "react";
17017
+ import { useCallback as useCallback23, useEffect as useEffect39, useRef as useRef21, useState as useState43 } from "react";
16873
17018
  import { jsx as jsx68, jsxs as jsxs62 } from "react/jsx-runtime";
16874
17019
  var STATUS_ORDER = {
16875
17020
  in_progress: 0,
@@ -16877,11 +17022,11 @@ var STATUS_ORDER = {
16877
17022
  completed: 2
16878
17023
  };
16879
17024
  function TodosPanel() {
16880
- const [todos, setTodos] = useState42([]);
16881
- const [collapsedSections, setCollapsedSections] = useState42(/* @__PURE__ */ new Set());
17025
+ const [todos, setTodos] = useState43([]);
17026
+ const [collapsedSections, setCollapsedSections] = useState43(/* @__PURE__ */ new Set());
16882
17027
  const ws = getWSClient();
16883
17028
  const offRef = useRef21(null);
16884
- useEffect38(() => {
17029
+ useEffect39(() => {
16885
17030
  ws.send({ type: "todos.get" });
16886
17031
  offRef.current = ws.on("todos.updated", (msg) => {
16887
17032
  const payload = msg?.payload;
@@ -17014,7 +17159,7 @@ function TodosPanel() {
17014
17159
 
17015
17160
  // src/components/TasksPanel.tsx
17016
17161
  import { CheckCircle2 as CheckCircle215, Circle as Circle8, Clock as Clock14, Pause as Pause6, XCircle as XCircle8, RotateCcw as RotateCcw5 } from "lucide-react";
17017
- import { useCallback as useCallback24, useEffect as useEffect39, useRef as useRef22, useState as useState43 } from "react";
17162
+ import { useCallback as useCallback24, useEffect as useEffect40, useRef as useRef22, useState as useState44 } from "react";
17018
17163
  import { jsx as jsx69, jsxs as jsxs63 } from "react/jsx-runtime";
17019
17164
  var STATUS_CONFIG2 = {
17020
17165
  pending: { icon: /* @__PURE__ */ jsx69(Circle8, { className: "w-3.5 h-3.5" }), label: "Pending", color: "text-muted-foreground/50" },
@@ -17039,11 +17184,11 @@ var TYPE_ICON = {
17039
17184
  chore: "\u{1F527}"
17040
17185
  };
17041
17186
  function TasksPanel() {
17042
- const [tasks, setTasks] = useState43([]);
17043
- const [collapsed, setCollapsed] = useState43(/* @__PURE__ */ new Set());
17187
+ const [tasks, setTasks] = useState44([]);
17188
+ const [collapsed, setCollapsed] = useState44(/* @__PURE__ */ new Set());
17044
17189
  const ws = getWSClient();
17045
17190
  const offRef = useRef22(null);
17046
- useEffect39(() => {
17191
+ useEffect40(() => {
17047
17192
  ws.getTasks();
17048
17193
  offRef.current = ws.on("tasks.updated", (msg) => {
17049
17194
  const payload = msg?.payload;
@@ -17183,7 +17328,7 @@ function TasksPanel() {
17183
17328
 
17184
17329
  // src/components/PlanPanel.tsx
17185
17330
  import { CheckCircle2 as CheckCircle216, Circle as Circle9, Clock as Clock15 } from "lucide-react";
17186
- import { useCallback as useCallback25, useEffect as useEffect40, useRef as useRef23, useState as useState44 } from "react";
17331
+ import { useCallback as useCallback25, useEffect as useEffect41, useRef as useRef23, useState as useState45 } from "react";
17187
17332
  import { jsx as jsx70, jsxs as jsxs64 } from "react/jsx-runtime";
17188
17333
  var STATUS_CONFIG3 = {
17189
17334
  open: { icon: /* @__PURE__ */ jsx70(Circle9, { className: "w-3.5 h-3.5" }), label: "Open", color: "text-muted-foreground/50" },
@@ -17191,11 +17336,11 @@ var STATUS_CONFIG3 = {
17191
17336
  done: { icon: /* @__PURE__ */ jsx70(CheckCircle216, { className: "w-3.5 h-3.5" }), label: "Done", color: "text-emerald-500" }
17192
17337
  };
17193
17338
  function PlanPanel() {
17194
- const [items, setItems] = useState44([]);
17195
- const [collapsed, setCollapsed] = useState44(/* @__PURE__ */ new Set());
17339
+ const [items, setItems] = useState45([]);
17340
+ const [collapsed, setCollapsed] = useState45(/* @__PURE__ */ new Set());
17196
17341
  const ws = getWSClient();
17197
17342
  const offRef = useRef23(null);
17198
- useEffect40(() => {
17343
+ useEffect41(() => {
17199
17344
  ws.getPlan();
17200
17345
  offRef.current = ws.on("plan.updated", (msg) => {
17201
17346
  const payload = msg?.payload;
@@ -17329,7 +17474,7 @@ var TABS = [
17329
17474
  { id: "plan", label: "Plan", icon: "\u{1F5FA}\uFE0F" }
17330
17475
  ];
17331
17476
  function WorkDashboard() {
17332
- const [activeTab, setActiveTab] = useState45("todos");
17477
+ const [activeTab, setActiveTab] = useState46("todos");
17333
17478
  return /* @__PURE__ */ jsxs65("div", { className: "rounded-lg border border-border bg-card/50 backdrop-blur-sm overflow-hidden", children: [
17334
17479
  /* @__PURE__ */ jsx71("div", { className: "flex border-b border-border/50 bg-muted/30", children: TABS.map((tab) => /* @__PURE__ */ jsxs65(
17335
17480
  "button",
@@ -17429,9 +17574,9 @@ function WorkspaceDock({ sessionId }) {
17429
17574
  () => toggleAutoPhaseAutonomous(!autoPhase.autonomous),
17430
17575
  [toggleAutoPhaseAutonomous, autoPhase.autonomous]
17431
17576
  );
17432
- const [worktreeView, setWorktreeView] = useState46("graph");
17577
+ const [worktreeView, setWorktreeView] = useState47("graph");
17433
17578
  const fleetTotal = fleetAgents.size;
17434
- const fleetRunning = useMemo17(
17579
+ const fleetRunning = useMemo16(
17435
17580
  () => Array.from(fleetAgents.values()).filter((a) => a.status === "running").length,
17436
17581
  [fleetAgents]
17437
17582
  );
@@ -17439,7 +17584,7 @@ function WorkspaceDock({ sessionId }) {
17439
17584
  const todosActive = todos.some((t) => t.status === "in_progress");
17440
17585
  const phasesActive = autoPhase.phases.length > 0;
17441
17586
  const prevPhaseCount = useRef24(autoPhase.phases.length);
17442
- useEffect41(() => {
17587
+ useEffect42(() => {
17443
17588
  const ui = useUIStore.getState();
17444
17589
  if (prevPhaseCount.current === 0 && autoPhase.phases.length > 0 && ui.dockSection === null) {
17445
17590
  ui.setDockSection("autophase");
@@ -17580,285 +17725,33 @@ function WorkspaceDock({ sessionId }) {
17580
17725
  ] });
17581
17726
  }
17582
17727
 
17583
- // src/components/AgentsMonitor.tsx
17584
- import { Bot as Bot12, ChevronLeft, ChevronRight as ChevronRight10, Cpu as Cpu14, Crown as Crown2, Loader2 as Loader211, Wrench as Wrench9, X as X16, Zap as Zap10 } from "lucide-react";
17585
- import { useCallback as useCallback27, useEffect as useEffect42, useMemo as useMemo18, useState as useState47 } from "react";
17728
+ // src/components/FleetMonitor.tsx
17729
+ import {
17730
+ Activity as Activity5,
17731
+ ArrowRight as ArrowRight6,
17732
+ Bot as Bot12,
17733
+ ChevronRight as ChevronRight11,
17734
+ Clock as Clock16,
17735
+ Cpu as Cpu14,
17736
+ Crown as Crown2,
17737
+ Database as Database4,
17738
+ DollarSign as DollarSign2,
17739
+ FolderOpen as FolderOpen5,
17740
+ Loader2 as Loader211,
17741
+ Timer as Timer3,
17742
+ Users as Users4,
17743
+ Wrench as Wrench9,
17744
+ XCircle as XCircle9,
17745
+ Zap as Zap10
17746
+ } from "lucide-react";
17747
+ import { useCallback as useCallback27, useEffect as useEffect43, useMemo as useMemo17, useState as useState48 } from "react";
17748
+
17749
+ // src/components/ui/dropdown-menu.tsx
17750
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
17751
+ import { Check as Check8, ChevronRight as ChevronRight10, Circle as Circle10 } from "lucide-react";
17752
+ import * as React6 from "react";
17586
17753
  import { jsx as jsx73, jsxs as jsxs67 } from "react/jsx-runtime";
17587
- function fmtCost5(v) {
17588
- if (v <= 0) return "$0";
17589
- if (v >= 0.01) return `$${v.toFixed(3)}`;
17590
- return `$${v.toFixed(5)}`.replace(/0+$/, "").replace(/\.$/, "");
17591
- }
17592
- function fmtDuration3(ms) {
17593
- const sec = Math.floor(ms / 1e3);
17594
- if (sec < 60) return `${sec}s`;
17595
- const min = Math.floor(sec / 60);
17596
- return `${min}m ${sec % 60}s`;
17597
- }
17598
- var STATUS_META5 = {
17599
- running: { led: "bg-[hsl(var(--success))]", label: "running", pulse: true, badge: "bg-[hsl(var(--success))]/15 text-[hsl(var(--success))]" },
17600
- completed: { led: "bg-[hsl(var(--success))]", label: "done", pulse: false, badge: "bg-muted text-muted-foreground" },
17601
- failed: { led: "bg-destructive", label: "failed", pulse: false, badge: "bg-destructive/15 text-destructive" },
17602
- timeout: { led: "bg-[hsl(var(--warning))]", label: "timeout", pulse: false, badge: "bg-amber-500/15 text-amber-500" },
17603
- stopped: { led: "bg-muted-foreground", label: "stopped", pulse: false, badge: "bg-muted text-muted-foreground" }
17604
- };
17605
- function AgentCard2({ agent, isLeader }) {
17606
- const meta2 = STATUS_META5[agent.status];
17607
- const active = agent.status === "running";
17608
- const elapsed = Date.now() - agent.startedAt;
17609
- const toolLogSlice = agent.toolLog.slice(0, 8);
17610
- const last8Tools = [...toolLogSlice].reverse();
17611
- return /* @__PURE__ */ jsxs67("div", { className: cn(
17612
- "rounded-xl border p-4 space-y-3",
17613
- active ? "border-primary/20 bg-primary/[0.02]" : "border-border bg-card",
17614
- isLeader && "ring-2 ring-amber-500/30"
17615
- ), children: [
17616
- /* @__PURE__ */ jsxs67("div", { className: "flex items-start justify-between", children: [
17617
- /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-2", children: [
17618
- /* @__PURE__ */ jsx73("span", { className: cn("led", meta2.led, meta2.pulse && "led-pulse", "mt-0.5") }),
17619
- /* @__PURE__ */ jsxs67("div", { children: [
17620
- /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-1.5", children: [
17621
- /* @__PURE__ */ jsx73("span", { className: "text-sm font-semibold", children: agent.name }),
17622
- isLeader && /* @__PURE__ */ jsx73(Crown2, { className: "h-3.5 w-3.5 text-amber-500", "aria-label": "leader" }),
17623
- agent.extensions > 0 && /* @__PURE__ */ jsxs67("span", { className: "inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded-full bg-amber-500/15 text-[10px] text-amber-600 dark:text-amber-400 font-medium", children: [
17624
- /* @__PURE__ */ jsx73(Zap10, { className: "h-2.5 w-2.5" }),
17625
- "\xD7",
17626
- agent.extensions
17627
- ] })
17628
- ] }),
17629
- /* @__PURE__ */ jsx73("span", { className: cn("inline-block mt-0.5 px-1.5 py-0.5 rounded text-[10px] font-medium", meta2.badge), children: meta2.label })
17630
- ] })
17631
- ] }),
17632
- /* @__PURE__ */ jsx73("div", { className: "flex items-center gap-1 text-[10px] text-muted-foreground", children: isLeader && /* @__PURE__ */ jsx73("span", { className: "text-[9px] bg-amber-500/15 text-amber-600 dark:text-amber-400 px-1.5 py-0.5 rounded", children: "LEADER" }) })
17633
- ] }),
17634
- agent.description && /* @__PURE__ */ jsx73("p", { className: "text-xs text-muted-foreground leading-relaxed line-clamp-2", children: agent.description }),
17635
- agent.budgetWarning && /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-2 px-3 py-2 rounded-lg bg-amber-500/10 border border-amber-500/20 text-xs", children: [
17636
- /* @__PURE__ */ jsx73(Zap10, { className: "h-3.5 w-3.5 text-amber-500 shrink-0" }),
17637
- /* @__PURE__ */ jsxs67("span", { className: "text-amber-600 dark:text-amber-400", children: [
17638
- "\u26A1 hitting ",
17639
- /* @__PURE__ */ jsx73("strong", { children: agent.budgetWarning.kind }),
17640
- " limit (",
17641
- agent.budgetWarning.used,
17642
- "/",
17643
- agent.budgetWarning.limit,
17644
- ") \u2014 extending"
17645
- ] })
17646
- ] }),
17647
- agent.failureReason && /* @__PURE__ */ jsx73("div", { className: "flex items-center gap-2 px-3 py-2 rounded-lg bg-destructive/10 border border-destructive/20 text-xs", children: /* @__PURE__ */ jsxs67("span", { className: "text-destructive font-medium", children: [
17648
- "\u2717 ",
17649
- agent.failureReason
17650
- ] }) }),
17651
- /* @__PURE__ */ jsxs67("div", { className: "grid grid-cols-4 gap-2", children: [
17652
- /* @__PURE__ */ jsxs67("div", { className: "rounded-lg border bg-muted/30 px-2 py-1.5 text-center", children: [
17653
- /* @__PURE__ */ jsx73("div", { className: "text-[10px] text-muted-foreground", children: "Iters" }),
17654
- /* @__PURE__ */ jsx73("div", { className: "text-xs font-mono font-semibold tabular-nums", children: agent.iteration })
17655
- ] }),
17656
- /* @__PURE__ */ jsxs67("div", { className: "rounded-lg border bg-muted/30 px-2 py-1.5 text-center", children: [
17657
- /* @__PURE__ */ jsx73("div", { className: "text-[10px] text-muted-foreground", children: "Tools" }),
17658
- /* @__PURE__ */ jsx73("div", { className: "text-xs font-mono font-semibold tabular-nums", children: agent.toolCalls })
17659
- ] }),
17660
- /* @__PURE__ */ jsxs67("div", { className: "rounded-lg border bg-muted/30 px-2 py-1.5 text-center", children: [
17661
- /* @__PURE__ */ jsx73("div", { className: "text-[10px] text-muted-foreground", children: "Cost" }),
17662
- /* @__PURE__ */ jsx73("div", { className: "text-xs font-mono font-semibold tabular-nums", children: fmtCost5(agent.costUsd) })
17663
- ] }),
17664
- /* @__PURE__ */ jsxs67("div", { className: "rounded-lg border bg-muted/30 px-2 py-1.5 text-center", children: [
17665
- /* @__PURE__ */ jsx73("div", { className: "text-[10px] text-muted-foreground", children: "Elapsed" }),
17666
- /* @__PURE__ */ jsx73("div", { className: "text-xs font-mono font-semibold tabular-nums", children: fmtDuration3(elapsed) })
17667
- ] })
17668
- ] }),
17669
- /* @__PURE__ */ jsxs67("div", { className: "space-y-1.5", children: [
17670
- /* @__PURE__ */ jsxs67("div", { className: "flex items-center justify-between", children: [
17671
- /* @__PURE__ */ jsx73("span", { className: "text-[10px] text-muted-foreground", children: "Activity (12 bins)" }),
17672
- /* @__PURE__ */ jsx73(SparklineChart, { bins: agent.sparklineBins, className: "font-mono text-[9px]" })
17673
- ] }),
17674
- /* @__PURE__ */ jsx73(ContextBar, { pct: agent.ctxPct, tokens: agent.ctxTokens, maxTokens: agent.maxContext })
17675
- ] }),
17676
- (agent.provider || agent.model) && /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
17677
- /* @__PURE__ */ jsx73(Cpu14, { className: "h-3 w-3" }),
17678
- /* @__PURE__ */ jsxs67("span", { className: "font-mono", children: [
17679
- agent.provider ?? "?",
17680
- "/",
17681
- agent.model ?? "?"
17682
- ] })
17683
- ] }),
17684
- (agent.currentTool || agent.lastTool) && /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
17685
- /* @__PURE__ */ jsx73(Wrench9, { className: cn("h-3 w-3", active && "animate-pulse text-primary") }),
17686
- /* @__PURE__ */ jsx73("span", { className: "font-mono", children: agent.currentTool ?? agent.lastTool }),
17687
- active && /* @__PURE__ */ jsx73(Loader211, { className: "h-3 w-3 animate-spin" })
17688
- ] }),
17689
- agent.partialText && active && /* @__PURE__ */ jsxs67("div", { className: "rounded-lg border bg-muted/30 p-2", children: [
17690
- /* @__PURE__ */ jsx73("div", { className: "text-[9px] text-muted-foreground uppercase tracking-wider mb-1", children: "Streaming output" }),
17691
- /* @__PURE__ */ jsx73("pre", { className: "text-[10px] font-mono text-foreground/80 whitespace-pre-wrap line-clamp-3 leading-relaxed", children: agent.partialText })
17692
- ] }),
17693
- last8Tools.length > 0 && /* @__PURE__ */ jsxs67("div", { className: "space-y-1", children: [
17694
- /* @__PURE__ */ jsx73("div", { className: "text-[9px] text-muted-foreground uppercase tracking-wider", children: "Recent tools" }),
17695
- /* @__PURE__ */ jsx73("div", { className: "space-y-0.5", children: last8Tools.map((tool, i) => /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-2 text-[10px] font-mono", children: [
17696
- /* @__PURE__ */ jsx73("span", { className: cn("shrink-0", tool.ok ? "text-[hsl(var(--success))]" : "text-destructive"), children: tool.ok ? "\u2713" : "\u2717" }),
17697
- /* @__PURE__ */ jsx73("span", { className: "text-muted-foreground truncate", children: tool.name }),
17698
- /* @__PURE__ */ jsx73("span", { className: "ml-auto tabular-nums text-muted-foreground shrink-0", children: tool.durationMs >= 1e3 ? `${(tool.durationMs / 1e3).toFixed(1)}s` : `${tool.durationMs}ms` })
17699
- ] }, i)) })
17700
- ] }),
17701
- agent.finalText && !active && /* @__PURE__ */ jsxs67("div", { className: "rounded-lg border bg-muted/30 p-2", children: [
17702
- /* @__PURE__ */ jsx73("div", { className: "text-[9px] text-muted-foreground uppercase tracking-wider mb-1", children: "Final output" }),
17703
- /* @__PURE__ */ jsx73("pre", { className: "text-[10px] font-mono text-foreground/80 whitespace-pre-wrap line-clamp-4 leading-relaxed", children: agent.finalText })
17704
- ] })
17705
- ] });
17706
- }
17707
- function AgentsMonitor({ onClose }) {
17708
- const fleetAgents = useFleetStore((s) => s.agents);
17709
- const leaderId = useFleetStore((s) => s.leaderId);
17710
- const [selectedIdx, setSelectedIdx] = useState47(0);
17711
- const fleetList = useMemo18(() => {
17712
- const arr = Array.from(fleetAgents.values());
17713
- arr.sort((x, y) => {
17714
- if (x.id === leaderId) return -1;
17715
- if (y.id === leaderId) return 1;
17716
- const xa = x.status === "running" ? 0 : 1;
17717
- const ya = y.status === "running" ? 0 : 1;
17718
- if (xa !== ya) return xa - ya;
17719
- return x.startedAt - y.startedAt;
17720
- });
17721
- return arr;
17722
- }, [fleetAgents, leaderId]);
17723
- const handleKeyDown = useCallback27(
17724
- (e) => {
17725
- if (e.key === "Escape") {
17726
- onClose();
17727
- return;
17728
- }
17729
- if (e.key === "ArrowDown") {
17730
- e.preventDefault();
17731
- setSelectedIdx((i) => Math.min(i + 1, fleetList.length - 1));
17732
- return;
17733
- }
17734
- if (e.key === "ArrowUp") {
17735
- e.preventDefault();
17736
- setSelectedIdx((i) => Math.max(i - 1, 0));
17737
- return;
17738
- }
17739
- },
17740
- [fleetList.length, onClose]
17741
- );
17742
- useEffect42(() => {
17743
- const handleGlobal = (e) => {
17744
- if (e.key === "Escape") onClose();
17745
- };
17746
- window.addEventListener("keydown", handleGlobal);
17747
- return () => window.removeEventListener("keydown", handleGlobal);
17748
- }, [onClose]);
17749
- const selectedAgent = fleetList[selectedIdx] ?? null;
17750
- return /* @__PURE__ */ jsxs67(
17751
- "div",
17752
- {
17753
- className: "fixed inset-0 z-50 flex flex-col bg-background/95 backdrop-blur-md",
17754
- onKeyDown: handleKeyDown,
17755
- tabIndex: -1,
17756
- children: [
17757
- /* @__PURE__ */ jsxs67("div", { className: "flex items-center justify-between px-4 py-3 border-b bg-card/80 backdrop-blur shrink-0", children: [
17758
- /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-3", children: [
17759
- /* @__PURE__ */ jsx73(Bot12, { className: "h-5 w-5 text-primary" }),
17760
- /* @__PURE__ */ jsx73("h2", { className: "text-sm font-semibold", children: "Agents Monitor" }),
17761
- /* @__PURE__ */ jsxs67("span", { className: "text-xs text-muted-foreground", children: [
17762
- fleetList.length,
17763
- " total"
17764
- ] })
17765
- ] }),
17766
- /* @__PURE__ */ jsxs67("div", { className: "flex items-center gap-2", children: [
17767
- /* @__PURE__ */ jsx73(
17768
- "button",
17769
- {
17770
- type: "button",
17771
- onClick: () => setSelectedIdx((i) => Math.max(i - 1, 0)),
17772
- className: "p-1.5 rounded-md hover:bg-muted transition-colors disabled:opacity-30",
17773
- disabled: selectedIdx === 0,
17774
- "aria-label": "Previous agent",
17775
- children: /* @__PURE__ */ jsx73(ChevronLeft, { className: "h-4 w-4" })
17776
- }
17777
- ),
17778
- /* @__PURE__ */ jsx73("span", { className: "text-xs tabular-nums text-muted-foreground font-mono", children: fleetList.length > 0 ? `${selectedIdx + 1}/${fleetList.length}` : "0/0" }),
17779
- /* @__PURE__ */ jsx73(
17780
- "button",
17781
- {
17782
- type: "button",
17783
- onClick: () => setSelectedIdx((i) => Math.min(i + 1, fleetList.length - 1)),
17784
- className: "p-1.5 rounded-md hover:bg-muted transition-colors disabled:opacity-30",
17785
- disabled: selectedIdx >= fleetList.length - 1,
17786
- "aria-label": "Next agent",
17787
- children: /* @__PURE__ */ jsx73(ChevronRight10, { className: "h-4 w-4" })
17788
- }
17789
- ),
17790
- /* @__PURE__ */ jsx73(
17791
- "button",
17792
- {
17793
- type: "button",
17794
- onClick: onClose,
17795
- className: "p-1.5 rounded-md hover:bg-muted transition-colors ml-2",
17796
- "aria-label": "Close agents monitor",
17797
- children: /* @__PURE__ */ jsx73(X16, { className: "h-4 w-4" })
17798
- }
17799
- )
17800
- ] })
17801
- ] }),
17802
- /* @__PURE__ */ jsx73("div", { className: "flex-1 overflow-y-auto p-4", children: fleetList.length === 0 ? /* @__PURE__ */ jsxs67("div", { className: "flex flex-col items-center justify-center h-full text-muted-foreground", children: [
17803
- /* @__PURE__ */ jsx73(Bot12, { className: "h-12 w-12 mb-3 opacity-20" }),
17804
- /* @__PURE__ */ jsx73("p", { className: "text-sm font-medium", children: "No agents active" })
17805
- ] }) : selectedAgent ? /* @__PURE__ */ jsx73("div", { className: "max-w-2xl mx-auto", children: /* @__PURE__ */ jsx73(AgentCard2, { agent: selectedAgent, isLeader: selectedAgent.id === leaderId }) }) : null }),
17806
- fleetList.length > 0 && /* @__PURE__ */ jsxs67("div", { className: "border-t bg-card/80 backdrop-blur shrink-0", children: [
17807
- /* @__PURE__ */ jsx73("div", { className: "px-4 py-2 flex items-center gap-2 overflow-x-auto", children: fleetList.map((agent, i) => /* @__PURE__ */ jsxs67(
17808
- "button",
17809
- {
17810
- type: "button",
17811
- onClick: () => setSelectedIdx(i),
17812
- className: cn(
17813
- "shrink-0 flex items-center gap-1.5 px-2 py-1 rounded-md text-[10px] transition-colors",
17814
- i === selectedIdx ? "bg-primary/15 text-primary ring-1 ring-primary/40" : "hover:bg-accent text-muted-foreground"
17815
- ),
17816
- children: [
17817
- /* @__PURE__ */ jsx73("span", { className: cn("led", STATUS_META5[agent.status].led, STATUS_META5[agent.status].pulse && "led-pulse", "shrink-0") }),
17818
- /* @__PURE__ */ jsx73("span", { children: agent.name }),
17819
- agent.id === leaderId && /* @__PURE__ */ jsx73(Crown2, { className: "h-2.5 w-2.5 text-amber-500 shrink-0" })
17820
- ]
17821
- },
17822
- agent.id
17823
- )) }),
17824
- /* @__PURE__ */ jsxs67("div", { className: "px-4 py-1.5 border-t text-[10px] text-muted-foreground flex items-center gap-4", children: [
17825
- /* @__PURE__ */ jsx73("span", { children: "\u2190\u2192 page" }),
17826
- /* @__PURE__ */ jsx73("span", { children: "\u2191\u2193 navigate list" }),
17827
- /* @__PURE__ */ jsx73("span", { children: "Esc close" })
17828
- ] })
17829
- ] })
17830
- ]
17831
- }
17832
- );
17833
- }
17834
-
17835
- // src/components/FleetMonitor.tsx
17836
- import {
17837
- Activity as Activity5,
17838
- ArrowRight as ArrowRight6,
17839
- Bot as Bot13,
17840
- ChevronRight as ChevronRight12,
17841
- Clock as Clock17,
17842
- Cpu as Cpu15,
17843
- Crown as Crown3,
17844
- Database as Database4,
17845
- DollarSign as DollarSign3,
17846
- FolderOpen as FolderOpen5,
17847
- Loader2 as Loader212,
17848
- Timer as Timer2,
17849
- Users as Users4,
17850
- Wrench as Wrench10,
17851
- XCircle as XCircle9,
17852
- Zap as Zap11
17853
- } from "lucide-react";
17854
- import { useCallback as useCallback28, useEffect as useEffect43, useMemo as useMemo19, useState as useState48 } from "react";
17855
-
17856
- // src/components/ui/dropdown-menu.tsx
17857
- import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
17858
- import { Check as Check8, ChevronRight as ChevronRight11, Circle as Circle10 } from "lucide-react";
17859
- import * as React6 from "react";
17860
- import { jsx as jsx74, jsxs as jsxs68 } from "react/jsx-runtime";
17861
- var DropdownMenuSubTrigger = React6.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs68(
17754
+ var DropdownMenuSubTrigger = React6.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs67(
17862
17755
  DropdownMenuPrimitive.SubTrigger,
17863
17756
  {
17864
17757
  ref,
@@ -17870,12 +17763,12 @@ var DropdownMenuSubTrigger = React6.forwardRef(({ className, inset, children, ..
17870
17763
  ...props,
17871
17764
  children: [
17872
17765
  children,
17873
- /* @__PURE__ */ jsx74(ChevronRight11, { className: "ml-auto h-4 w-4" })
17766
+ /* @__PURE__ */ jsx73(ChevronRight10, { className: "ml-auto h-4 w-4" })
17874
17767
  ]
17875
17768
  }
17876
17769
  ));
17877
17770
  DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
17878
- var DropdownMenuSubContent = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx74(
17771
+ var DropdownMenuSubContent = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx73(
17879
17772
  DropdownMenuPrimitive.SubContent,
17880
17773
  {
17881
17774
  ref,
@@ -17887,7 +17780,7 @@ var DropdownMenuSubContent = React6.forwardRef(({ className, ...props }, ref) =>
17887
17780
  }
17888
17781
  ));
17889
17782
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
17890
- var DropdownMenuContent = React6.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx74(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx74(
17783
+ var DropdownMenuContent = React6.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx73(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx73(
17891
17784
  DropdownMenuPrimitive.Content,
17892
17785
  {
17893
17786
  ref,
@@ -17900,7 +17793,7 @@ var DropdownMenuContent = React6.forwardRef(({ className, sideOffset = 4, ...pro
17900
17793
  }
17901
17794
  ) }));
17902
17795
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
17903
- var DropdownMenuItem = React6.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx74(
17796
+ var DropdownMenuItem = React6.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx73(
17904
17797
  DropdownMenuPrimitive.Item,
17905
17798
  {
17906
17799
  ref,
@@ -17913,7 +17806,7 @@ var DropdownMenuItem = React6.forwardRef(({ className, inset, ...props }, ref) =
17913
17806
  }
17914
17807
  ));
17915
17808
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
17916
- var DropdownMenuCheckboxItem = React6.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs68(
17809
+ var DropdownMenuCheckboxItem = React6.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs67(
17917
17810
  DropdownMenuPrimitive.CheckboxItem,
17918
17811
  {
17919
17812
  ref,
@@ -17924,13 +17817,13 @@ var DropdownMenuCheckboxItem = React6.forwardRef(({ className, children, checked
17924
17817
  checked,
17925
17818
  ...props,
17926
17819
  children: [
17927
- /* @__PURE__ */ jsx74("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx74(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx74(Check8, { className: "h-4 w-4" }) }) }),
17820
+ /* @__PURE__ */ jsx73("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx73(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx73(Check8, { className: "h-4 w-4" }) }) }),
17928
17821
  children
17929
17822
  ]
17930
17823
  }
17931
17824
  ));
17932
17825
  DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
17933
- var DropdownMenuRadioItem = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs68(
17826
+ var DropdownMenuRadioItem = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs67(
17934
17827
  DropdownMenuPrimitive.RadioItem,
17935
17828
  {
17936
17829
  ref,
@@ -17940,13 +17833,13 @@ var DropdownMenuRadioItem = React6.forwardRef(({ className, children, ...props }
17940
17833
  ),
17941
17834
  ...props,
17942
17835
  children: [
17943
- /* @__PURE__ */ jsx74("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx74(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx74(Circle10, { className: "h-2 w-2 fill-current" }) }) }),
17836
+ /* @__PURE__ */ jsx73("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx73(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx73(Circle10, { className: "h-2 w-2 fill-current" }) }) }),
17944
17837
  children
17945
17838
  ]
17946
17839
  }
17947
17840
  ));
17948
17841
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
17949
- var DropdownMenuLabel = React6.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx74(
17842
+ var DropdownMenuLabel = React6.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx73(
17950
17843
  DropdownMenuPrimitive.Label,
17951
17844
  {
17952
17845
  ref,
@@ -17955,7 +17848,7 @@ var DropdownMenuLabel = React6.forwardRef(({ className, inset, ...props }, ref)
17955
17848
  }
17956
17849
  ));
17957
17850
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
17958
- var DropdownMenuSeparator = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx74(
17851
+ var DropdownMenuSeparator = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx73(
17959
17852
  DropdownMenuPrimitive.Separator,
17960
17853
  {
17961
17854
  ref,
@@ -17965,12 +17858,12 @@ var DropdownMenuSeparator = React6.forwardRef(({ className, ...props }, ref) =>
17965
17858
  ));
17966
17859
  DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
17967
17860
  var DropdownMenuShortcut = ({ className, ...props }) => {
17968
- return /* @__PURE__ */ jsx74("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
17861
+ return /* @__PURE__ */ jsx73("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
17969
17862
  };
17970
17863
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
17971
17864
 
17972
17865
  // src/components/ui/concurrency-gauge.tsx
17973
- import { jsx as jsx75, jsxs as jsxs69 } from "react/jsx-runtime";
17866
+ import { jsx as jsx74, jsxs as jsxs68 } from "react/jsx-runtime";
17974
17867
  function ConcurrencyGauge({
17975
17868
  current,
17976
17869
  max,
@@ -17981,14 +17874,14 @@ function ConcurrencyGauge({
17981
17874
  const empty = Math.max(0, max - filled);
17982
17875
  const pct = max > 0 ? filled / max * 100 : 0;
17983
17876
  const barColor = pct >= 90 ? "text-destructive" : pct >= 70 ? "text-[hsl(var(--warning))]" : "text-[hsl(var(--success))]";
17984
- return /* @__PURE__ */ jsxs69("span", { className, title: `Fleet concurrency: ${current}/${max}`, children: [
17985
- /* @__PURE__ */ jsxs69("span", { "aria-hidden": "true", className: "font-mono text-[10px] tracking-tight", children: [
17877
+ return /* @__PURE__ */ jsxs68("span", { className, title: `Fleet concurrency: ${current}/${max}`, children: [
17878
+ /* @__PURE__ */ jsxs68("span", { "aria-hidden": "true", className: "font-mono text-[10px] tracking-tight", children: [
17986
17879
  "[",
17987
- /* @__PURE__ */ jsx75("span", { className: barColor, children: "\u2588".repeat(filled) }),
17988
- /* @__PURE__ */ jsx75("span", { className: "text-[hsl(var(--muted))]", children: "\u2591".repeat(empty) }),
17880
+ /* @__PURE__ */ jsx74("span", { className: barColor, children: "\u2588".repeat(filled) }),
17881
+ /* @__PURE__ */ jsx74("span", { className: "text-[hsl(var(--muted))]", children: "\u2591".repeat(empty) }),
17989
17882
  "]"
17990
17883
  ] }),
17991
- showLabel && /* @__PURE__ */ jsxs69("span", { className: "ml-1.5 tabular-nums text-[10px] text-muted-foreground font-mono", children: [
17884
+ showLabel && /* @__PURE__ */ jsxs68("span", { className: "ml-1.5 tabular-nums text-[10px] text-muted-foreground font-mono", children: [
17992
17885
  current,
17993
17886
  "/",
17994
17887
  max
@@ -17997,7 +17890,7 @@ function ConcurrencyGauge({
17997
17890
  }
17998
17891
 
17999
17892
  // src/components/ui/event-timeline.tsx
18000
- import { jsx as jsx76, jsxs as jsxs70 } from "react/jsx-runtime";
17893
+ import { jsx as jsx75, jsxs as jsxs69 } from "react/jsx-runtime";
18001
17894
  function relTime(ts) {
18002
17895
  const delta = Date.now() - ts;
18003
17896
  if (delta < 5e3) return "just now";
@@ -18018,18 +17911,18 @@ var KIND_ICONS = {
18018
17911
  function EventTimeline({ events, max = 20, className }) {
18019
17912
  const visible = events.slice(0, max);
18020
17913
  if (visible.length === 0) {
18021
- return /* @__PURE__ */ jsx76("div", { className: `py-4 text-center text-xs text-muted-foreground ${className ?? ""}`, children: "No events yet." });
17914
+ return /* @__PURE__ */ jsx75("div", { className: `py-4 text-center text-xs text-muted-foreground ${className ?? ""}`, children: "No events yet." });
18022
17915
  }
18023
- return /* @__PURE__ */ jsx76("div", { className: `space-y-0.5 overflow-y-auto max-h-48 ${className ?? ""}`, children: visible.map((ev) => /* @__PURE__ */ jsxs70(
17916
+ return /* @__PURE__ */ jsx75("div", { className: `space-y-0.5 overflow-y-auto max-h-48 ${className ?? ""}`, children: visible.map((ev) => /* @__PURE__ */ jsxs69(
18024
17917
  "div",
18025
17918
  {
18026
17919
  className: "flex items-start gap-2 text-[10px] leading-tight py-0.5 px-1 rounded hover:bg-accent/50 transition-colors",
18027
17920
  children: [
18028
- /* @__PURE__ */ jsx76("span", { className: "shrink-0 w-5 text-center", "aria-hidden": "true", children: KIND_ICONS[ev.kind] ?? "\xB7" }),
18029
- /* @__PURE__ */ jsx76("span", { className: "shrink-0 w-12 text-right text-muted-foreground font-mono tabular-nums", children: relTime(ev.timestamp) }),
18030
- /* @__PURE__ */ jsx76("span", { className: "truncate text-foreground/90", children: ev.message }),
18031
- ev.value !== void 0 && ev.kind === "tool_executed" && /* @__PURE__ */ jsx76("span", { className: "ml-auto shrink-0 tabular-nums text-muted-foreground font-mono", children: ev.value >= 1e3 ? `${(ev.value / 1e3).toFixed(1)}s` : `${ev.value}ms` }),
18032
- ev.value !== void 0 && ev.kind === "ctx_pct" && /* @__PURE__ */ jsxs70("span", { className: "ml-auto shrink-0 tabular-nums text-muted-foreground font-mono", children: [
17921
+ /* @__PURE__ */ jsx75("span", { className: "shrink-0 w-5 text-center", "aria-hidden": "true", children: KIND_ICONS[ev.kind] ?? "\xB7" }),
17922
+ /* @__PURE__ */ jsx75("span", { className: "shrink-0 w-12 text-right text-muted-foreground font-mono tabular-nums", children: relTime(ev.timestamp) }),
17923
+ /* @__PURE__ */ jsx75("span", { className: "truncate text-foreground/90", children: ev.message }),
17924
+ ev.value !== void 0 && ev.kind === "tool_executed" && /* @__PURE__ */ jsx75("span", { className: "ml-auto shrink-0 tabular-nums text-muted-foreground font-mono", children: ev.value >= 1e3 ? `${(ev.value / 1e3).toFixed(1)}s` : `${ev.value}ms` }),
17925
+ ev.value !== void 0 && ev.kind === "ctx_pct" && /* @__PURE__ */ jsxs69("span", { className: "ml-auto shrink-0 tabular-nums text-muted-foreground font-mono", children: [
18033
17926
  ev.value,
18034
17927
  "%"
18035
17928
  ] })
@@ -18040,8 +17933,8 @@ function EventTimeline({ events, max = 20, className }) {
18040
17933
  }
18041
17934
 
18042
17935
  // src/components/FleetMonitor.tsx
18043
- import { Fragment as Fragment16, jsx as jsx77, jsxs as jsxs71 } from "react/jsx-runtime";
18044
- function fmtCost6(v) {
17936
+ import { Fragment as Fragment16, jsx as jsx76, jsxs as jsxs70 } from "react/jsx-runtime";
17937
+ function fmtCost5(v) {
18045
17938
  if (v <= 0) return "$0";
18046
17939
  if (v >= 0.01) return `$${v.toFixed(3)}`;
18047
17940
  return `$${v.toFixed(5)}`.replace(/0+$/, "").replace(/\.$/, "");
@@ -18059,7 +17952,7 @@ function fmtElapsed3(ms) {
18059
17952
  if (m > 0) return `${m}m ${s % 60}s`;
18060
17953
  return `${s}s`;
18061
17954
  }
18062
- var STATUS_META6 = {
17955
+ var STATUS_META5 = {
18063
17956
  running: { led: "bg-emerald-500", label: "running", pulse: true, color: "text-emerald-500" },
18064
17957
  completed: { led: "bg-emerald-500", label: "done", pulse: false, color: "text-emerald-500" },
18065
17958
  failed: { led: "bg-destructive", label: "failed", pulse: false, color: "text-destructive" },
@@ -18072,9 +17965,9 @@ function FleetAgentDetailPanel({
18072
17965
  }) {
18073
17966
  const [copied, setCopied] = useState48(false);
18074
17967
  const [showFullToolLog, setShowFullToolLog] = useState48(false);
18075
- const meta2 = STATUS_META6[agent.status];
17968
+ const meta2 = STATUS_META5[agent.status];
18076
17969
  const active = agent.status === "running";
18077
- const handleCopy = useCallback28(async (text) => {
17970
+ const handleCopy = useCallback27(async (text) => {
18078
17971
  try {
18079
17972
  await navigator.clipboard.writeText(text);
18080
17973
  setCopied(true);
@@ -18084,110 +17977,110 @@ function FleetAgentDetailPanel({
18084
17977
  }, []);
18085
17978
  const totalToolDuration = agent.toolLog.reduce((sum, t) => sum + t.durationMs, 0);
18086
17979
  const avgToolDuration = agent.toolLog.length > 0 ? Math.round(totalToolDuration / agent.toolLog.length) : 0;
18087
- const uniqueTools = useMemo19(() => {
17980
+ const uniqueTools = useMemo17(() => {
18088
17981
  const tools = /* @__PURE__ */ new Set();
18089
17982
  agent.toolLog.forEach((t) => tools.add(t.name));
18090
17983
  return tools.size;
18091
17984
  }, [agent.toolLog]);
18092
17985
  const outputText = agent.partialText || agent.finalText || void 0;
18093
17986
  const isStream = !agent.finalText && !!agent.partialText;
18094
- return /* @__PURE__ */ jsxs71("div", { className: "h-full flex flex-col", children: [
18095
- /* @__PURE__ */ jsxs71("div", { className: "shrink-0 border-b bg-card p-4 space-y-3", children: [
18096
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center justify-between", children: [
18097
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-3", children: [
18098
- /* @__PURE__ */ jsx77("div", { className: "flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10", children: /* @__PURE__ */ jsx77(Bot13, { className: "h-5 w-5 text-primary" }) }),
18099
- /* @__PURE__ */ jsxs71("div", { children: [
18100
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2", children: [
18101
- /* @__PURE__ */ jsx77("span", { className: "text-base font-semibold", children: agent.name }),
18102
- /* @__PURE__ */ jsx77("span", { className: cn(
17987
+ return /* @__PURE__ */ jsxs70("div", { className: "h-full flex flex-col", children: [
17988
+ /* @__PURE__ */ jsxs70("div", { className: "shrink-0 border-b bg-card p-4 space-y-3", children: [
17989
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center justify-between", children: [
17990
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-3", children: [
17991
+ /* @__PURE__ */ jsx76("div", { className: "flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10", children: /* @__PURE__ */ jsx76(Bot12, { className: "h-5 w-5 text-primary" }) }),
17992
+ /* @__PURE__ */ jsxs70("div", { children: [
17993
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-2", children: [
17994
+ /* @__PURE__ */ jsx76("span", { className: "text-base font-semibold", children: agent.name }),
17995
+ /* @__PURE__ */ jsx76("span", { className: cn(
18103
17996
  "px-2 py-0.5 rounded text-[10px] font-medium uppercase tracking-wider",
18104
17997
  agent.status === "running" ? "bg-emerald-500/15 text-emerald-600 dark:text-emerald-400" : agent.status === "failed" || agent.status === "timeout" ? "bg-destructive/15 text-destructive" : "bg-muted text-muted-foreground"
18105
17998
  ), children: meta2.label })
18106
17999
  ] }),
18107
- /* @__PURE__ */ jsxs71("span", { className: "text-[10px] text-muted-foreground font-mono", children: [
18000
+ /* @__PURE__ */ jsxs70("span", { className: "text-[10px] text-muted-foreground font-mono", children: [
18108
18001
  "session: ",
18109
18002
  agent.sessionId?.slice(0, 12),
18110
18003
  "\u2026"
18111
18004
  ] })
18112
18005
  ] })
18113
18006
  ] }),
18114
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [
18115
- active && /* @__PURE__ */ jsxs71("span", { className: "flex items-center gap-1.5", children: [
18116
- /* @__PURE__ */ jsx77(Timer2, { className: "h-3.5 w-3.5" }),
18117
- /* @__PURE__ */ jsx77("span", { className: "tabular-nums font-mono", children: fmtElapsed3(Math.max(0, now - agent.startedAt)) })
18007
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-2 text-[11px] text-muted-foreground", children: [
18008
+ active && /* @__PURE__ */ jsxs70("span", { className: "flex items-center gap-1.5", children: [
18009
+ /* @__PURE__ */ jsx76(Timer3, { className: "h-3.5 w-3.5" }),
18010
+ /* @__PURE__ */ jsx76("span", { className: "tabular-nums font-mono", children: fmtElapsed3(Math.max(0, now - agent.startedAt)) })
18118
18011
  ] }),
18119
- /* @__PURE__ */ jsx77("span", { className: cn("led", meta2.led, active && "led-pulse") })
18012
+ /* @__PURE__ */ jsx76("span", { className: cn("led", meta2.led, active && "led-pulse") })
18120
18013
  ] })
18121
18014
  ] }),
18122
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-3 px-3 py-2 rounded-lg bg-muted/30", children: [
18123
- /* @__PURE__ */ jsx77("span", { className: "text-[10px] text-muted-foreground uppercase tracking-wider", children: "Activity" }),
18124
- /* @__PURE__ */ jsx77(SparklineChart, { bins: agent.sparklineBins, className: "font-mono text-[9px]" }),
18125
- agent.budgetWarning && /* @__PURE__ */ jsxs71("span", { className: "ml-auto flex items-center gap-1 text-[10px] text-amber-500", children: [
18126
- /* @__PURE__ */ jsx77(Zap11, { className: "h-3 w-3" }),
18015
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-3 px-3 py-2 rounded-lg bg-muted/30", children: [
18016
+ /* @__PURE__ */ jsx76("span", { className: "text-[10px] text-muted-foreground uppercase tracking-wider", children: "Activity" }),
18017
+ /* @__PURE__ */ jsx76(SparklineChart, { bins: agent.sparklineBins, className: "font-mono text-[9px]" }),
18018
+ agent.budgetWarning && /* @__PURE__ */ jsxs70("span", { className: "ml-auto flex items-center gap-1 text-[10px] text-amber-500", children: [
18019
+ /* @__PURE__ */ jsx76(Zap10, { className: "h-3 w-3" }),
18127
18020
  "budget warning"
18128
18021
  ] })
18129
18022
  ] }),
18130
- agent.description && /* @__PURE__ */ jsxs71("div", { className: "px-3 py-2 rounded-lg bg-muted/20 border border-border/50", children: [
18131
- /* @__PURE__ */ jsx77("span", { className: "text-[9px] text-muted-foreground uppercase tracking-wider", children: "Current Task" }),
18132
- /* @__PURE__ */ jsx77("p", { className: "text-xs mt-1 text-foreground/80", children: agent.description })
18023
+ agent.description && /* @__PURE__ */ jsxs70("div", { className: "px-3 py-2 rounded-lg bg-muted/20 border border-border/50", children: [
18024
+ /* @__PURE__ */ jsx76("span", { className: "text-[9px] text-muted-foreground uppercase tracking-wider", children: "Current Task" }),
18025
+ /* @__PURE__ */ jsx76("p", { className: "text-xs mt-1 text-foreground/80", children: agent.description })
18133
18026
  ] })
18134
18027
  ] }),
18135
- /* @__PURE__ */ jsxs71("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [
18136
- /* @__PURE__ */ jsxs71("div", { className: "grid grid-cols-2 gap-3", children: [
18137
- /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-card p-3", children: [
18138
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 text-[9px] text-muted-foreground uppercase tracking-wider mb-2", children: [
18139
- /* @__PURE__ */ jsx77(Cpu15, { className: "h-3 w-3" }),
18028
+ /* @__PURE__ */ jsxs70("div", { className: "flex-1 overflow-y-auto p-4 space-y-4", children: [
18029
+ /* @__PURE__ */ jsxs70("div", { className: "grid grid-cols-2 gap-3", children: [
18030
+ /* @__PURE__ */ jsxs70("div", { className: "rounded-lg border bg-card p-3", children: [
18031
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-2 text-[9px] text-muted-foreground uppercase tracking-wider mb-2", children: [
18032
+ /* @__PURE__ */ jsx76(Cpu14, { className: "h-3 w-3" }),
18140
18033
  " Provider / Model"
18141
18034
  ] }),
18142
- /* @__PURE__ */ jsxs71("div", { className: "text-sm font-mono font-medium", children: [
18035
+ /* @__PURE__ */ jsxs70("div", { className: "text-sm font-mono font-medium", children: [
18143
18036
  agent.provider ?? "?",
18144
18037
  "/",
18145
18038
  agent.model ?? "?"
18146
18039
  ] })
18147
18040
  ] }),
18148
- /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-card p-3", children: [
18149
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 text-[9px] text-muted-foreground uppercase tracking-wider mb-2", children: [
18150
- /* @__PURE__ */ jsx77(Activity5, { className: "h-3 w-3" }),
18041
+ /* @__PURE__ */ jsxs70("div", { className: "rounded-lg border bg-card p-3", children: [
18042
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-2 text-[9px] text-muted-foreground uppercase tracking-wider mb-2", children: [
18043
+ /* @__PURE__ */ jsx76(Activity5, { className: "h-3 w-3" }),
18151
18044
  " Performance"
18152
18045
  ] }),
18153
- /* @__PURE__ */ jsxs71("div", { className: "space-y-1", children: [
18154
- /* @__PURE__ */ jsxs71("div", { className: "flex justify-between text-[11px]", children: [
18155
- /* @__PURE__ */ jsx77("span", { className: "text-muted-foreground", children: "Iterations" }),
18156
- /* @__PURE__ */ jsx77("span", { className: "font-mono font-medium", children: agent.iteration })
18046
+ /* @__PURE__ */ jsxs70("div", { className: "space-y-1", children: [
18047
+ /* @__PURE__ */ jsxs70("div", { className: "flex justify-between text-[11px]", children: [
18048
+ /* @__PURE__ */ jsx76("span", { className: "text-muted-foreground", children: "Iterations" }),
18049
+ /* @__PURE__ */ jsx76("span", { className: "font-mono font-medium", children: agent.iteration })
18157
18050
  ] }),
18158
- /* @__PURE__ */ jsxs71("div", { className: "flex justify-between text-[11px]", children: [
18159
- /* @__PURE__ */ jsx77("span", { className: "text-muted-foreground", children: "Tool Calls" }),
18160
- /* @__PURE__ */ jsx77("span", { className: "font-mono font-medium", children: agent.toolCalls })
18051
+ /* @__PURE__ */ jsxs70("div", { className: "flex justify-between text-[11px]", children: [
18052
+ /* @__PURE__ */ jsx76("span", { className: "text-muted-foreground", children: "Tool Calls" }),
18053
+ /* @__PURE__ */ jsx76("span", { className: "font-mono font-medium", children: agent.toolCalls })
18161
18054
  ] }),
18162
- /* @__PURE__ */ jsxs71("div", { className: "flex justify-between text-[11px]", children: [
18163
- /* @__PURE__ */ jsx77("span", { className: "text-muted-foreground", children: "Unique Tools" }),
18164
- /* @__PURE__ */ jsx77("span", { className: "font-mono font-medium", children: uniqueTools })
18055
+ /* @__PURE__ */ jsxs70("div", { className: "flex justify-between text-[11px]", children: [
18056
+ /* @__PURE__ */ jsx76("span", { className: "text-muted-foreground", children: "Unique Tools" }),
18057
+ /* @__PURE__ */ jsx76("span", { className: "font-mono font-medium", children: uniqueTools })
18165
18058
  ] })
18166
18059
  ] })
18167
18060
  ] }),
18168
- /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-card p-3", children: [
18169
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 text-[9px] text-muted-foreground uppercase tracking-wider mb-2", children: [
18170
- /* @__PURE__ */ jsx77(DollarSign3, { className: "h-3 w-3" }),
18061
+ /* @__PURE__ */ jsxs70("div", { className: "rounded-lg border bg-card p-3", children: [
18062
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-2 text-[9px] text-muted-foreground uppercase tracking-wider mb-2", children: [
18063
+ /* @__PURE__ */ jsx76(DollarSign2, { className: "h-3 w-3" }),
18171
18064
  " Cost"
18172
18065
  ] }),
18173
- /* @__PURE__ */ jsx77("div", { className: "text-lg font-mono font-bold text-emerald-500", children: fmtCost6(agent.costUsd) }),
18174
- /* @__PURE__ */ jsxs71("div", { className: "text-[10px] text-muted-foreground mt-1", children: [
18066
+ /* @__PURE__ */ jsx76("div", { className: "text-lg font-mono font-bold text-emerald-500", children: fmtCost5(agent.costUsd) }),
18067
+ /* @__PURE__ */ jsxs70("div", { className: "text-[10px] text-muted-foreground mt-1", children: [
18175
18068
  "avg ",
18176
18069
  avgToolDuration,
18177
18070
  "ms per tool"
18178
18071
  ] })
18179
18072
  ] }),
18180
- /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-card p-3", children: [
18181
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 text-[9px] text-muted-foreground uppercase tracking-wider mb-2", children: [
18182
- /* @__PURE__ */ jsx77(Database4, { className: "h-3 w-3" }),
18073
+ /* @__PURE__ */ jsxs70("div", { className: "rounded-lg border bg-card p-3", children: [
18074
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-2 text-[9px] text-muted-foreground uppercase tracking-wider mb-2", children: [
18075
+ /* @__PURE__ */ jsx76(Database4, { className: "h-3 w-3" }),
18183
18076
  " Context"
18184
18077
  ] }),
18185
- /* @__PURE__ */ jsxs71("div", { className: "space-y-2", children: [
18186
- /* @__PURE__ */ jsxs71("div", { className: "flex justify-between text-[11px]", children: [
18187
- /* @__PURE__ */ jsx77("span", { className: "text-muted-foreground", children: "Tokens" }),
18188
- /* @__PURE__ */ jsx77("span", { className: "font-mono font-medium", children: fmtTok3(agent.ctxTokens) })
18078
+ /* @__PURE__ */ jsxs70("div", { className: "space-y-2", children: [
18079
+ /* @__PURE__ */ jsxs70("div", { className: "flex justify-between text-[11px]", children: [
18080
+ /* @__PURE__ */ jsx76("span", { className: "text-muted-foreground", children: "Tokens" }),
18081
+ /* @__PURE__ */ jsx76("span", { className: "font-mono font-medium", children: fmtTok3(agent.ctxTokens) })
18189
18082
  ] }),
18190
- /* @__PURE__ */ jsx77("div", { className: "h-2 w-full rounded-full bg-muted overflow-hidden", children: /* @__PURE__ */ jsx77(
18083
+ /* @__PURE__ */ jsx76("div", { className: "h-2 w-full rounded-full bg-muted overflow-hidden", children: /* @__PURE__ */ jsx76(
18191
18084
  "div",
18192
18085
  {
18193
18086
  className: cn(
@@ -18197,34 +18090,34 @@ function FleetAgentDetailPanel({
18197
18090
  style: { width: `${Math.min(200, agent.ctxPct)}%` }
18198
18091
  }
18199
18092
  ) }),
18200
- /* @__PURE__ */ jsxs71("span", { className: "text-[10px] text-muted-foreground tabular-nums font-mono", children: [
18093
+ /* @__PURE__ */ jsxs70("span", { className: "text-[10px] text-muted-foreground tabular-nums font-mono", children: [
18201
18094
  agent.ctxPct,
18202
18095
  "% used"
18203
18096
  ] })
18204
18097
  ] })
18205
18098
  ] })
18206
18099
  ] }),
18207
- agent.currentTool && /* @__PURE__ */ jsxs71("div", { className: cn(
18100
+ agent.currentTool && /* @__PURE__ */ jsxs70("div", { className: cn(
18208
18101
  "rounded-lg border px-4 py-3 flex items-center gap-3",
18209
18102
  active ? "border-primary/30 bg-primary/[0.04]" : "border-border bg-muted/30"
18210
18103
  ), children: [
18211
- /* @__PURE__ */ jsx77(Wrench10, { className: cn("h-4 w-4", active ? "text-primary animate-pulse" : "text-muted-foreground") }),
18212
- /* @__PURE__ */ jsx77("span", { className: "text-sm font-mono font-medium", children: agent.currentTool }),
18213
- active ? /* @__PURE__ */ jsxs71("span", { className: "ml-auto flex items-center gap-1.5 text-[10px] text-primary", children: [
18214
- /* @__PURE__ */ jsx77(Loader212, { className: "h-3 w-3 animate-spin" }),
18104
+ /* @__PURE__ */ jsx76(Wrench9, { className: cn("h-4 w-4", active ? "text-primary animate-pulse" : "text-muted-foreground") }),
18105
+ /* @__PURE__ */ jsx76("span", { className: "text-sm font-mono font-medium", children: agent.currentTool }),
18106
+ active ? /* @__PURE__ */ jsxs70("span", { className: "ml-auto flex items-center gap-1.5 text-[10px] text-primary", children: [
18107
+ /* @__PURE__ */ jsx76(Loader211, { className: "h-3 w-3 animate-spin" }),
18215
18108
  " running\u2026"
18216
- ] }) : /* @__PURE__ */ jsx77("span", { className: "ml-auto text-[10px] text-muted-foreground", children: "completed" })
18109
+ ] }) : /* @__PURE__ */ jsx76("span", { className: "ml-auto text-[10px] text-muted-foreground", children: "completed" })
18217
18110
  ] }),
18218
- outputText ? /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-card", children: [
18219
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center justify-between px-4 py-2 border-b bg-muted/30", children: [
18220
- /* @__PURE__ */ jsx77("span", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: isStream ? /* @__PURE__ */ jsxs71(Fragment16, { children: [
18221
- /* @__PURE__ */ jsx77("span", { className: "w-2 h-2 rounded-full bg-blue-500 animate-pulse" }),
18111
+ outputText ? /* @__PURE__ */ jsxs70("div", { className: "rounded-lg border bg-card", children: [
18112
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center justify-between px-4 py-2 border-b bg-muted/30", children: [
18113
+ /* @__PURE__ */ jsx76("span", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: isStream ? /* @__PURE__ */ jsxs70(Fragment16, { children: [
18114
+ /* @__PURE__ */ jsx76("span", { className: "w-2 h-2 rounded-full bg-blue-500 animate-pulse" }),
18222
18115
  "Live Output"
18223
- ] }) : /* @__PURE__ */ jsxs71(Fragment16, { children: [
18224
- /* @__PURE__ */ jsx77(FolderOpen5, { className: "h-3 w-3" }),
18116
+ ] }) : /* @__PURE__ */ jsxs70(Fragment16, { children: [
18117
+ /* @__PURE__ */ jsx76(FolderOpen5, { className: "h-3 w-3" }),
18225
18118
  "Final Output"
18226
18119
  ] }) }),
18227
- /* @__PURE__ */ jsx77(
18120
+ /* @__PURE__ */ jsx76(
18228
18121
  "button",
18229
18122
  {
18230
18123
  type: "button",
@@ -18234,16 +18127,16 @@ function FleetAgentDetailPanel({
18234
18127
  }
18235
18128
  )
18236
18129
  ] }),
18237
- /* @__PURE__ */ jsx77("pre", { className: "p-4 text-xs whitespace-pre-wrap font-mono text-foreground/80 leading-relaxed max-h-64 overflow-y-auto", children: outputText })
18238
- ] }) : active ? /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border border-dashed border-border p-6 text-center", children: [
18239
- /* @__PURE__ */ jsx77(Loader212, { className: "h-6 w-6 mx-auto mb-2 text-muted-foreground/50 animate-spin" }),
18240
- /* @__PURE__ */ jsx77("span", { className: "text-xs text-muted-foreground", children: "Waiting for output\u2026" })
18130
+ /* @__PURE__ */ jsx76("pre", { className: "p-4 text-xs whitespace-pre-wrap font-mono text-foreground/80 leading-relaxed max-h-64 overflow-y-auto", children: outputText })
18131
+ ] }) : active ? /* @__PURE__ */ jsxs70("div", { className: "rounded-lg border border-dashed border-border p-6 text-center", children: [
18132
+ /* @__PURE__ */ jsx76(Loader211, { className: "h-6 w-6 mx-auto mb-2 text-muted-foreground/50 animate-spin" }),
18133
+ /* @__PURE__ */ jsx76("span", { className: "text-xs text-muted-foreground", children: "Waiting for output\u2026" })
18241
18134
  ] }) : null,
18242
- agent.budgetWarning && /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-3 px-4 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20", children: [
18243
- /* @__PURE__ */ jsx77(Zap11, { className: "h-5 w-5 text-amber-500 shrink-0" }),
18244
- /* @__PURE__ */ jsxs71("div", { children: [
18245
- /* @__PURE__ */ jsx77("span", { className: "text-sm font-medium text-amber-600 dark:text-amber-400", children: "\u26A1 Budget Warning" }),
18246
- /* @__PURE__ */ jsxs71("p", { className: "text-[11px] text-amber-600/80 dark:text-amber-400/80 mt-0.5", children: [
18135
+ agent.budgetWarning && /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-3 px-4 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20", children: [
18136
+ /* @__PURE__ */ jsx76(Zap10, { className: "h-5 w-5 text-amber-500 shrink-0" }),
18137
+ /* @__PURE__ */ jsxs70("div", { children: [
18138
+ /* @__PURE__ */ jsx76("span", { className: "text-sm font-medium text-amber-600 dark:text-amber-400", children: "\u26A1 Budget Warning" }),
18139
+ /* @__PURE__ */ jsxs70("p", { className: "text-[11px] text-amber-600/80 dark:text-amber-400/80 mt-0.5", children: [
18247
18140
  "Hitting ",
18248
18141
  agent.budgetWarning.kind,
18249
18142
  " limit (",
@@ -18254,15 +18147,15 @@ function FleetAgentDetailPanel({
18254
18147
  ] })
18255
18148
  ] })
18256
18149
  ] }),
18257
- agent.extensions > 0 && /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-3 px-4 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20", children: [
18258
- /* @__PURE__ */ jsx77(Zap11, { className: "h-5 w-5 text-amber-500 shrink-0" }),
18259
- /* @__PURE__ */ jsxs71("div", { children: [
18260
- /* @__PURE__ */ jsxs71("span", { className: "text-sm font-medium", children: [
18150
+ agent.extensions > 0 && /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-3 px-4 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20", children: [
18151
+ /* @__PURE__ */ jsx76(Zap10, { className: "h-5 w-5 text-amber-500 shrink-0" }),
18152
+ /* @__PURE__ */ jsxs70("div", { children: [
18153
+ /* @__PURE__ */ jsxs70("span", { className: "text-sm font-medium", children: [
18261
18154
  agent.extensions,
18262
18155
  " Budget Extension",
18263
18156
  agent.extensions === 1 ? "" : "s"
18264
18157
  ] }),
18265
- /* @__PURE__ */ jsxs71("p", { className: "text-[11px] text-muted-foreground mt-0.5", children: [
18158
+ /* @__PURE__ */ jsxs70("p", { className: "text-[11px] text-muted-foreground mt-0.5", children: [
18266
18159
  "Agent extended its budget ",
18267
18160
  agent.extensions,
18268
18161
  " time",
@@ -18271,39 +18164,39 @@ function FleetAgentDetailPanel({
18271
18164
  ] })
18272
18165
  ] })
18273
18166
  ] }),
18274
- agent.error && /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4", children: [
18275
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 mb-2", children: [
18276
- /* @__PURE__ */ jsx77(XCircle9, { className: "h-4 w-4 text-destructive" }),
18277
- /* @__PURE__ */ jsx77("span", { className: "text-[10px] font-semibold text-destructive uppercase tracking-wider", children: "Error" })
18167
+ agent.error && /* @__PURE__ */ jsxs70("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4", children: [
18168
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-2 mb-2", children: [
18169
+ /* @__PURE__ */ jsx76(XCircle9, { className: "h-4 w-4 text-destructive" }),
18170
+ /* @__PURE__ */ jsx76("span", { className: "text-[10px] font-semibold text-destructive uppercase tracking-wider", children: "Error" })
18278
18171
  ] }),
18279
- /* @__PURE__ */ jsx77("p", { className: "text-sm text-destructive/90", children: agent.error.message })
18172
+ /* @__PURE__ */ jsx76("p", { className: "text-sm text-destructive/90", children: agent.error.message })
18280
18173
  ] }),
18281
- agent.failureReason && /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4", children: [
18282
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 mb-2", children: [
18283
- /* @__PURE__ */ jsx77(XCircle9, { className: "h-4 w-4 text-destructive" }),
18284
- /* @__PURE__ */ jsx77("span", { className: "text-[10px] font-semibold text-destructive uppercase tracking-wider", children: "Failure Reason" })
18174
+ agent.failureReason && /* @__PURE__ */ jsxs70("div", { className: "rounded-lg border border-destructive/30 bg-destructive/5 p-4", children: [
18175
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-2 mb-2", children: [
18176
+ /* @__PURE__ */ jsx76(XCircle9, { className: "h-4 w-4 text-destructive" }),
18177
+ /* @__PURE__ */ jsx76("span", { className: "text-[10px] font-semibold text-destructive uppercase tracking-wider", children: "Failure Reason" })
18285
18178
  ] }),
18286
- /* @__PURE__ */ jsx77("p", { className: "text-sm text-destructive/90", children: agent.failureReason })
18179
+ /* @__PURE__ */ jsx76("p", { className: "text-sm text-destructive/90", children: agent.failureReason })
18287
18180
  ] }),
18288
- agent.toolLog.length > 0 && /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-card", children: [
18289
- /* @__PURE__ */ jsxs71(
18181
+ agent.toolLog.length > 0 && /* @__PURE__ */ jsxs70("div", { className: "rounded-lg border bg-card", children: [
18182
+ /* @__PURE__ */ jsxs70(
18290
18183
  "button",
18291
18184
  {
18292
18185
  type: "button",
18293
18186
  onClick: () => setShowFullToolLog(!showFullToolLog),
18294
18187
  className: "w-full flex items-center justify-between px-4 py-2 border-b bg-muted/30 hover:bg-muted/50 transition-colors",
18295
18188
  children: [
18296
- /* @__PURE__ */ jsxs71("span", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
18297
- /* @__PURE__ */ jsx77(Wrench10, { className: "h-3 w-3" }),
18189
+ /* @__PURE__ */ jsxs70("span", { className: "text-[10px] font-semibold text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
18190
+ /* @__PURE__ */ jsx76(Wrench9, { className: "h-3 w-3" }),
18298
18191
  "Tool Log (",
18299
18192
  agent.toolLog.length,
18300
18193
  " calls)"
18301
18194
  ] }),
18302
- /* @__PURE__ */ jsx77(ChevronRight12, { className: cn("h-4 w-4 text-muted-foreground transition-transform", showFullToolLog && "rotate-90") })
18195
+ /* @__PURE__ */ jsx76(ChevronRight11, { className: cn("h-4 w-4 text-muted-foreground transition-transform", showFullToolLog && "rotate-90") })
18303
18196
  ]
18304
18197
  }
18305
18198
  ),
18306
- /* @__PURE__ */ jsx77("div", { className: cn("overflow-hidden transition-all", showFullToolLog ? "max-h-[500px]" : "max-h-48"), children: /* @__PURE__ */ jsx77("div", { className: "p-2 space-y-0.5", children: agent.toolLog.map((tl, i) => /* @__PURE__ */ jsxs71(
18199
+ /* @__PURE__ */ jsx76("div", { className: cn("overflow-hidden transition-all", showFullToolLog ? "max-h-[500px]" : "max-h-48"), children: /* @__PURE__ */ jsx76("div", { className: "p-2 space-y-0.5", children: agent.toolLog.map((tl, i) => /* @__PURE__ */ jsxs70(
18307
18200
  "div",
18308
18201
  {
18309
18202
  className: cn(
@@ -18311,11 +18204,11 @@ function FleetAgentDetailPanel({
18311
18204
  tl.ok ? "bg-muted/30 hover:bg-muted/50" : "bg-destructive/5 border border-destructive/20"
18312
18205
  ),
18313
18206
  children: [
18314
- /* @__PURE__ */ jsx77("span", { className: cn("led shrink-0", tl.ok ? "bg-emerald-500" : "bg-destructive") }),
18315
- /* @__PURE__ */ jsx77("span", { className: cn("font-mono font-medium w-20 shrink-0", tl.ok ? "text-foreground" : "text-destructive"), children: tl.name }),
18316
- /* @__PURE__ */ jsx77("span", { className: "text-muted-foreground tabular-nums text-[10px]", children: tl.durationMs >= 1e3 ? `${(tl.durationMs / 1e3).toFixed(2)}s` : `${tl.durationMs}ms` }),
18317
- !tl.ok && /* @__PURE__ */ jsx77("span", { className: "ml-auto text-[10px] text-destructive font-medium", children: "Failed" }),
18318
- /* @__PURE__ */ jsx77("span", { className: "ml-auto text-[9px] text-muted-foreground tabular-nums", children: new Date(tl.at).toLocaleTimeString() })
18207
+ /* @__PURE__ */ jsx76("span", { className: cn("led shrink-0", tl.ok ? "bg-emerald-500" : "bg-destructive") }),
18208
+ /* @__PURE__ */ jsx76("span", { className: cn("font-mono font-medium w-20 shrink-0", tl.ok ? "text-foreground" : "text-destructive"), children: tl.name }),
18209
+ /* @__PURE__ */ jsx76("span", { className: "text-muted-foreground tabular-nums text-[10px]", children: tl.durationMs >= 1e3 ? `${(tl.durationMs / 1e3).toFixed(2)}s` : `${tl.durationMs}ms` }),
18210
+ !tl.ok && /* @__PURE__ */ jsx76("span", { className: "ml-auto text-[10px] text-destructive font-medium", children: "Failed" }),
18211
+ /* @__PURE__ */ jsx76("span", { className: "ml-auto text-[9px] text-muted-foreground tabular-nums", children: new Date(tl.at).toLocaleTimeString() })
18319
18212
  ]
18320
18213
  },
18321
18214
  `${tl.name}-${tl.at}-${i}`
@@ -18330,9 +18223,9 @@ function FleetAgentRow({
18330
18223
  isLeader,
18331
18224
  onClick
18332
18225
  }) {
18333
- const meta2 = STATUS_META6[agent.status];
18226
+ const meta2 = STATUS_META5[agent.status];
18334
18227
  const active = agent.status === "running";
18335
- return /* @__PURE__ */ jsxs71(
18228
+ return /* @__PURE__ */ jsxs70(
18336
18229
  "button",
18337
18230
  {
18338
18231
  type: "button",
@@ -18343,27 +18236,27 @@ function FleetAgentRow({
18343
18236
  active && !isSelected && "bg-muted/30"
18344
18237
  ),
18345
18238
  children: [
18346
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-1 min-w-0", children: [
18347
- /* @__PURE__ */ jsx77("span", { className: cn("led shrink-0", meta2.led, meta2.pulse && "led-pulse") }),
18348
- /* @__PURE__ */ jsx77("span", { className: "truncate font-medium", children: agent.name }),
18349
- isLeader && /* @__PURE__ */ jsx77(Crown3, { className: "h-3 w-3 shrink-0 text-amber-500", "aria-label": "leader" })
18239
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-1 min-w-0", children: [
18240
+ /* @__PURE__ */ jsx76("span", { className: cn("led shrink-0", meta2.led, meta2.pulse && "led-pulse") }),
18241
+ /* @__PURE__ */ jsx76("span", { className: "truncate font-medium", children: agent.name }),
18242
+ isLeader && /* @__PURE__ */ jsx76(Crown2, { className: "h-3 w-3 shrink-0 text-amber-500", "aria-label": "leader" })
18350
18243
  ] }),
18351
- /* @__PURE__ */ jsx77("span", { className: cn("text-[10px] tabular-nums", active ? "text-emerald-500" : "text-muted-foreground"), children: meta2.label }),
18352
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-1 min-w-0", children: [
18353
- /* @__PURE__ */ jsx77(SparklineChart, { bins: agent.sparklineBins, className: "font-mono text-[9px]" }),
18354
- agent.budgetWarning && /* @__PURE__ */ jsx77("span", { title: `\u26A1 hitting ${agent.budgetWarning.kind} limit (${agent.budgetWarning.used}/${agent.budgetWarning.limit})`, children: /* @__PURE__ */ jsx77(Zap11, { className: "h-3 w-3 shrink-0 text-amber-500", "aria-label": "budget warning" }) })
18244
+ /* @__PURE__ */ jsx76("span", { className: cn("text-[10px] tabular-nums", active ? "text-emerald-500" : "text-muted-foreground"), children: meta2.label }),
18245
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-1 min-w-0", children: [
18246
+ /* @__PURE__ */ jsx76(SparklineChart, { bins: agent.sparklineBins, className: "font-mono text-[9px]" }),
18247
+ agent.budgetWarning && /* @__PURE__ */ jsx76("span", { title: `\u26A1 hitting ${agent.budgetWarning.kind} limit (${agent.budgetWarning.used}/${agent.budgetWarning.limit})`, children: /* @__PURE__ */ jsx76(Zap10, { className: "h-3 w-3 shrink-0 text-amber-500", "aria-label": "budget warning" }) })
18355
18248
  ] }),
18356
- /* @__PURE__ */ jsxs71("span", { className: "tabular-nums text-muted-foreground text-[10px]", children: [
18249
+ /* @__PURE__ */ jsxs70("span", { className: "tabular-nums text-muted-foreground text-[10px]", children: [
18357
18250
  agent.iteration,
18358
18251
  "it"
18359
18252
  ] }),
18360
- /* @__PURE__ */ jsxs71("span", { className: "tabular-nums text-muted-foreground text-[10px]", children: [
18253
+ /* @__PURE__ */ jsxs70("span", { className: "tabular-nums text-muted-foreground text-[10px]", children: [
18361
18254
  agent.toolCalls,
18362
18255
  "tc"
18363
18256
  ] }),
18364
- /* @__PURE__ */ jsx77("span", { className: "tabular-nums font-mono text-[10px]", children: fmtCost6(agent.costUsd) }),
18365
- /* @__PURE__ */ jsxs71("div", { className: "flex flex-col gap-0.5 min-w-0", children: [
18366
- /* @__PURE__ */ jsx77("div", { className: "h-1.5 w-full rounded-full bg-muted overflow-hidden", children: /* @__PURE__ */ jsx77(
18257
+ /* @__PURE__ */ jsx76("span", { className: "tabular-nums font-mono text-[10px]", children: fmtCost5(agent.costUsd) }),
18258
+ /* @__PURE__ */ jsxs70("div", { className: "flex flex-col gap-0.5 min-w-0", children: [
18259
+ /* @__PURE__ */ jsx76("div", { className: "h-1.5 w-full rounded-full bg-muted overflow-hidden", children: /* @__PURE__ */ jsx76(
18367
18260
  "div",
18368
18261
  {
18369
18262
  className: cn(
@@ -18373,10 +18266,10 @@ function FleetAgentRow({
18373
18266
  style: { width: `${Math.min(200, agent.ctxPct)}%` }
18374
18267
  }
18375
18268
  ) }),
18376
- /* @__PURE__ */ jsx77("span", { className: "text-[9px] tabular-nums text-muted-foreground font-mono leading-none", children: agent.maxContext > 0 ? `${agent.ctxPct}%` : "\u2014" })
18269
+ /* @__PURE__ */ jsx76("span", { className: "text-[9px] tabular-nums text-muted-foreground font-mono leading-none", children: agent.maxContext > 0 ? `${agent.ctxPct}%` : "\u2014" })
18377
18270
  ] }),
18378
- /* @__PURE__ */ jsx77("span", { className: "tabular-nums text-[10px] text-muted-foreground", children: agent.extensions > 0 ? `\u26A1\xD7${agent.extensions}` : "\u2014" }),
18379
- /* @__PURE__ */ jsx77("span", { className: "text-[9px] text-destructive truncate", title: agent.failureReason, children: agent.failureReason ?? "" })
18271
+ /* @__PURE__ */ jsx76("span", { className: "tabular-nums text-[10px] text-muted-foreground", children: agent.extensions > 0 ? `\u26A1\xD7${agent.extensions}` : "\u2014" }),
18272
+ /* @__PURE__ */ jsx76("span", { className: "text-[9px] text-destructive truncate", title: agent.failureReason, children: agent.failureReason ?? "" })
18380
18273
  ]
18381
18274
  }
18382
18275
  );
@@ -18399,7 +18292,7 @@ function FleetMonitor({
18399
18292
  const t = setInterval(() => setNowTick(Date.now()), 1e3);
18400
18293
  return () => clearInterval(t);
18401
18294
  }, []);
18402
- const fleetList = useMemo19(() => {
18295
+ const fleetList = useMemo17(() => {
18403
18296
  const arr = Array.from(fleetAgents.values());
18404
18297
  arr.sort((x, y) => {
18405
18298
  if (x.id === leaderId) return -1;
@@ -18411,13 +18304,17 @@ function FleetMonitor({
18411
18304
  });
18412
18305
  return arr;
18413
18306
  }, [fleetAgents, leaderId]);
18414
- const totalCost = useMemo19(
18307
+ const totalCost = useMemo17(
18415
18308
  () => Array.from(fleetAgents.values()).reduce((sum, a) => sum + a.costUsd, 0),
18416
18309
  [fleetAgents]
18417
18310
  );
18418
18311
  const runningCount = fleetList.filter((a) => a.status === "running").length;
18419
18312
  const selectedAgent = selectedIdx !== null ? fleetList[selectedIdx] : null;
18420
- const handleKeyDown = useCallback28(
18313
+ const handleAgentClick = useCallback27(
18314
+ (i) => setSelectedIdx((prev) => prev === i ? null : i),
18315
+ []
18316
+ );
18317
+ const handleKeyDown = useCallback27(
18421
18318
  (e) => {
18422
18319
  if (e.key === "Escape") {
18423
18320
  if (selectedIdx !== null) {
@@ -18451,30 +18348,30 @@ function FleetMonitor({
18451
18348
  return () => window.removeEventListener("keydown", handleGlobal);
18452
18349
  }, [onClose]);
18453
18350
  const containerClass = isOverlay ? "fixed inset-0 z-50 flex flex-col bg-background/95 backdrop-blur-md" : "flex flex-col h-full";
18454
- return /* @__PURE__ */ jsxs71(
18351
+ return /* @__PURE__ */ jsxs70(
18455
18352
  "div",
18456
18353
  {
18457
18354
  className: containerClass,
18458
18355
  onKeyDown: handleKeyDown,
18459
18356
  tabIndex: -1,
18460
18357
  children: [
18461
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center justify-between px-4 py-3 border-b bg-card/80 backdrop-blur shrink-0", children: [
18462
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-3", children: [
18463
- /* @__PURE__ */ jsx77(Bot13, { className: "h-5 w-5 text-primary" }),
18464
- /* @__PURE__ */ jsxs71("h2", { className: "text-sm font-semibold flex items-center gap-2", children: [
18358
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center justify-between px-4 py-3 border-b bg-card/80 backdrop-blur shrink-0", children: [
18359
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-3", children: [
18360
+ /* @__PURE__ */ jsx76(Bot12, { className: "h-5 w-5 text-primary" }),
18361
+ /* @__PURE__ */ jsxs70("h2", { className: "text-sm font-semibold flex items-center gap-2", children: [
18465
18362
  "FLEET MONITOR",
18466
- runningCount > 0 && /* @__PURE__ */ jsxs71("span", { className: "flex items-center gap-1 text-[11px] text-emerald-500 font-normal", children: [
18467
- /* @__PURE__ */ jsx77("span", { className: "led led-pulse bg-emerald-500" }),
18363
+ runningCount > 0 && /* @__PURE__ */ jsxs70("span", { className: "flex items-center gap-1 text-[11px] text-emerald-500 font-normal", children: [
18364
+ /* @__PURE__ */ jsx76("span", { className: "led led-pulse bg-emerald-500" }),
18468
18365
  runningCount,
18469
18366
  " running"
18470
18367
  ] })
18471
18368
  ] }),
18472
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
18473
- /* @__PURE__ */ jsxs71("span", { children: [
18369
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
18370
+ /* @__PURE__ */ jsxs70("span", { children: [
18474
18371
  fleetList.length,
18475
18372
  " total agents"
18476
18373
  ] }),
18477
- /* @__PURE__ */ jsx77(
18374
+ /* @__PURE__ */ jsx76(
18478
18375
  ConcurrencyGauge,
18479
18376
  {
18480
18377
  current: fleetConcurrency,
@@ -18484,77 +18381,77 @@ function FleetMonitor({
18484
18381
  )
18485
18382
  ] })
18486
18383
  ] }),
18487
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-3", children: [
18488
- /* @__PURE__ */ jsxs71("span", { className: "text-xs text-muted-foreground tabular-nums font-mono", children: [
18384
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-3", children: [
18385
+ /* @__PURE__ */ jsxs70("span", { className: "text-xs text-muted-foreground tabular-nums font-mono", children: [
18489
18386
  "\u2193",
18490
18387
  fmtTok3(fleetTokensIn),
18491
18388
  " \u2191",
18492
18389
  fmtTok3(fleetTokensOut),
18493
18390
  " \xB7 ",
18494
- fmtCost6(totalCost)
18391
+ fmtCost5(totalCost)
18495
18392
  ] }),
18496
- /* @__PURE__ */ jsx77("span", { className: "text-xs text-muted-foreground tabular-nums font-mono", children: leaderId ? `\u{1F451} ${fleetAgents.get(leaderId)?.name ?? leaderId}` : "no leader" }),
18497
- isOverlay && onClose && /* @__PURE__ */ jsx77(
18393
+ /* @__PURE__ */ jsx76("span", { className: "text-xs text-muted-foreground tabular-nums font-mono", children: leaderId ? `\u{1F451} ${fleetAgents.get(leaderId)?.name ?? leaderId}` : "no leader" }),
18394
+ isOverlay && onClose && /* @__PURE__ */ jsx76(
18498
18395
  "button",
18499
18396
  {
18500
18397
  type: "button",
18501
18398
  onClick: onClose,
18502
18399
  className: "p-1.5 rounded-md hover:bg-muted transition-colors",
18503
18400
  "aria-label": "Close fleet monitor",
18504
- children: /* @__PURE__ */ jsx77(XCircle9, { className: "h-4 w-4" })
18401
+ children: /* @__PURE__ */ jsx76(XCircle9, { className: "h-4 w-4" })
18505
18402
  }
18506
18403
  )
18507
18404
  ] })
18508
18405
  ] }),
18509
- /* @__PURE__ */ jsxs71("div", { className: "flex-1 flex overflow-hidden", children: [
18510
- /* @__PURE__ */ jsxs71("div", { className: cn(
18406
+ /* @__PURE__ */ jsxs70("div", { className: "flex-1 flex overflow-hidden", children: [
18407
+ /* @__PURE__ */ jsxs70("div", { className: cn(
18511
18408
  "flex flex-col border-r transition-all duration-200",
18512
18409
  selectedAgent ? "w-[500px] shrink-0" : "w-full"
18513
18410
  ), children: [
18514
- /* @__PURE__ */ jsx77("div", { className: "border-b bg-card/80 px-3 py-2", children: /* @__PURE__ */ jsxs71("div", { className: "grid grid-cols-[140px_60px_1fr_60px_60px_60px_60px_50px_50px] gap-x-2 text-[9px] uppercase tracking-wider text-muted-foreground font-medium", children: [
18515
- /* @__PURE__ */ jsx77("span", { children: "Name" }),
18516
- /* @__PURE__ */ jsx77("span", { children: "Status" }),
18517
- /* @__PURE__ */ jsx77("span", { children: "Activity" }),
18518
- /* @__PURE__ */ jsx77("span", { children: "Iters" }),
18519
- /* @__PURE__ */ jsx77("span", { children: "Tools" }),
18520
- /* @__PURE__ */ jsx77("span", { children: "Cost" }),
18521
- /* @__PURE__ */ jsx77("span", { children: "CTX" }),
18522
- /* @__PURE__ */ jsx77("span", { children: "Ext" }),
18523
- /* @__PURE__ */ jsx77("span", { children: "Reason" })
18411
+ /* @__PURE__ */ jsx76("div", { className: "border-b bg-card/80 px-3 py-2", children: /* @__PURE__ */ jsxs70("div", { className: "grid grid-cols-[140px_60px_1fr_60px_60px_60px_60px_50px_50px] gap-x-2 text-[9px] uppercase tracking-wider text-muted-foreground font-medium", children: [
18412
+ /* @__PURE__ */ jsx76("span", { children: "Name" }),
18413
+ /* @__PURE__ */ jsx76("span", { children: "Status" }),
18414
+ /* @__PURE__ */ jsx76("span", { children: "Activity" }),
18415
+ /* @__PURE__ */ jsx76("span", { children: "Iters" }),
18416
+ /* @__PURE__ */ jsx76("span", { children: "Tools" }),
18417
+ /* @__PURE__ */ jsx76("span", { children: "Cost" }),
18418
+ /* @__PURE__ */ jsx76("span", { children: "CTX" }),
18419
+ /* @__PURE__ */ jsx76("span", { children: "Ext" }),
18420
+ /* @__PURE__ */ jsx76("span", { children: "Reason" })
18524
18421
  ] }) }),
18525
- /* @__PURE__ */ jsx77("div", { className: "flex-1 overflow-y-auto", children: fleetList.length === 0 ? /* @__PURE__ */ jsxs71("div", { className: "flex flex-col items-center justify-center h-full text-muted-foreground", children: [
18526
- /* @__PURE__ */ jsx77(Users4, { className: "h-12 w-12 mb-3 opacity-20" }),
18527
- /* @__PURE__ */ jsx77("p", { className: "text-sm font-medium", children: "No agents active" }),
18528
- /* @__PURE__ */ jsx77("p", { className: "text-xs mt-1", children: "Agents appear here when the fleet is active." })
18529
- ] }) : /* @__PURE__ */ jsx77("div", { className: "p-2 space-y-0.5", children: fleetList.map((agent, i) => /* @__PURE__ */ jsx77(
18422
+ /* @__PURE__ */ jsx76("div", { className: "flex-1 overflow-y-auto", children: fleetList.length === 0 ? /* @__PURE__ */ jsxs70("div", { className: "flex flex-col items-center justify-center h-full text-muted-foreground", children: [
18423
+ /* @__PURE__ */ jsx76(Users4, { className: "h-12 w-12 mb-3 opacity-20" }),
18424
+ /* @__PURE__ */ jsx76("p", { className: "text-sm font-medium", children: "No agents active" }),
18425
+ /* @__PURE__ */ jsx76("p", { className: "text-xs mt-1", children: "Agents appear here when the fleet is active." })
18426
+ ] }) : /* @__PURE__ */ jsx76("div", { className: "p-2 space-y-0.5", children: fleetList.map((agent, i) => /* @__PURE__ */ jsx76(
18530
18427
  FleetAgentRow,
18531
18428
  {
18532
18429
  agent,
18533
18430
  isSelected: i === selectedIdx,
18534
18431
  isLeader: agent.id === leaderId,
18535
- onClick: () => setSelectedIdx(i === selectedIdx ? null : i)
18432
+ onClick: () => handleAgentClick(i)
18536
18433
  },
18537
18434
  agent.id
18538
18435
  )) }) }),
18539
- /* @__PURE__ */ jsxs71("div", { className: "border-t bg-card/80 shrink-0", children: [
18540
- /* @__PURE__ */ jsx77("div", { className: "px-4 py-2 border-b", children: /* @__PURE__ */ jsxs71("span", { className: "text-[10px] uppercase tracking-wider text-muted-foreground font-medium flex items-center gap-2", children: [
18541
- /* @__PURE__ */ jsx77(Clock17, { className: "h-3 w-3" }),
18436
+ /* @__PURE__ */ jsxs70("div", { className: "border-t bg-card/80 shrink-0", children: [
18437
+ /* @__PURE__ */ jsx76("div", { className: "px-4 py-2 border-b", children: /* @__PURE__ */ jsxs70("span", { className: "text-[10px] uppercase tracking-wider text-muted-foreground font-medium flex items-center gap-2", children: [
18438
+ /* @__PURE__ */ jsx76(Clock16, { className: "h-3 w-3" }),
18542
18439
  "Event Timeline"
18543
18440
  ] }) }),
18544
- /* @__PURE__ */ jsx77("div", { className: "px-4 py-2 max-h-32 overflow-y-auto", children: /* @__PURE__ */ jsx77(EventTimeline, { events: eventTimeline, max: 10 }) }),
18545
- /* @__PURE__ */ jsxs71("div", { className: "px-4 py-1.5 border-t text-[10px] text-muted-foreground flex items-center gap-4", children: [
18546
- /* @__PURE__ */ jsx77("span", { children: "\u2191\u2193 navigate" }),
18547
- /* @__PURE__ */ jsx77("span", { children: "\u21B5 select detail" }),
18548
- /* @__PURE__ */ jsx77("span", { children: "Esc deselect / close" })
18441
+ /* @__PURE__ */ jsx76("div", { className: "px-4 py-2 max-h-32 overflow-y-auto", children: /* @__PURE__ */ jsx76(EventTimeline, { events: eventTimeline, max: 10 }) }),
18442
+ /* @__PURE__ */ jsxs70("div", { className: "px-4 py-1.5 border-t text-[10px] text-muted-foreground flex items-center gap-4", children: [
18443
+ /* @__PURE__ */ jsx76("span", { children: "\u2191\u2193 navigate" }),
18444
+ /* @__PURE__ */ jsx76("span", { children: "\u21B5 select detail" }),
18445
+ /* @__PURE__ */ jsx76("span", { children: "Esc deselect / close" })
18549
18446
  ] })
18550
18447
  ] })
18551
18448
  ] }),
18552
- selectedAgent && /* @__PURE__ */ jsx77("div", { className: "flex-1 overflow-hidden bg-card/50", children: /* @__PURE__ */ jsxs71("div", { className: "h-full flex flex-col", children: [
18553
- /* @__PURE__ */ jsxs71("div", { className: "shrink-0 px-4 py-2 border-b bg-card/80 flex items-center gap-2", children: [
18554
- /* @__PURE__ */ jsx77(ArrowRight6, { className: "h-4 w-4 text-primary" }),
18555
- /* @__PURE__ */ jsx77("span", { className: "text-xs font-semibold text-primary", children: selectedAgent.name }),
18556
- /* @__PURE__ */ jsx77("span", { className: "text-[10px] text-muted-foreground", children: "detailed view" }),
18557
- /* @__PURE__ */ jsx77(
18449
+ selectedAgent && /* @__PURE__ */ jsx76("div", { className: "flex-1 overflow-hidden bg-card/50", children: /* @__PURE__ */ jsxs70("div", { className: "h-full flex flex-col", children: [
18450
+ /* @__PURE__ */ jsxs70("div", { className: "shrink-0 px-4 py-2 border-b bg-card/80 flex items-center gap-2", children: [
18451
+ /* @__PURE__ */ jsx76(ArrowRight6, { className: "h-4 w-4 text-primary" }),
18452
+ /* @__PURE__ */ jsx76("span", { className: "text-xs font-semibold text-primary", children: selectedAgent.name }),
18453
+ /* @__PURE__ */ jsx76("span", { className: "text-[10px] text-muted-foreground", children: "detailed view" }),
18454
+ /* @__PURE__ */ jsx76(
18558
18455
  "button",
18559
18456
  {
18560
18457
  type: "button",
@@ -18564,25 +18461,25 @@ function FleetMonitor({
18564
18461
  }
18565
18462
  )
18566
18463
  ] }),
18567
- /* @__PURE__ */ jsx77("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx77(FleetAgentDetailPanel, { agent: selectedAgent, now: nowTick }) })
18464
+ /* @__PURE__ */ jsx76("div", { className: "flex-1 overflow-hidden", children: /* @__PURE__ */ jsx76(FleetAgentDetailPanel, { agent: selectedAgent, now: nowTick }) })
18568
18465
  ] }) }),
18569
- !selectedAgent && fleetList.length > 0 && /* @__PURE__ */ jsx77("div", { className: "flex-1 flex items-center justify-center bg-muted/20", children: /* @__PURE__ */ jsxs71("div", { className: "text-center space-y-3 max-w-sm", children: [
18570
- /* @__PURE__ */ jsx77(Users4, { className: "h-12 w-12 text-muted-foreground/30 mx-auto" }),
18571
- /* @__PURE__ */ jsx77("p", { className: "text-sm text-muted-foreground", children: "Select an agent to view detailed information" }),
18572
- /* @__PURE__ */ jsx77("p", { className: "text-xs text-muted-foreground/60", children: "Click on any agent in the list to see detailed metrics, tool logs, streaming output, and more \u2014 similar to the chat history detailed view." }),
18573
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center justify-center gap-4 pt-2", children: [
18574
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
18575
- /* @__PURE__ */ jsx77("kbd", { className: "px-1.5 py-0.5 rounded bg-muted border text-[9px]", children: "\u2191" }),
18576
- /* @__PURE__ */ jsx77("kbd", { className: "px-1.5 py-0.5 rounded bg-muted border text-[9px]", children: "\u2193" }),
18577
- /* @__PURE__ */ jsx77("span", { children: "navigate" })
18466
+ !selectedAgent && fleetList.length > 0 && /* @__PURE__ */ jsx76("div", { className: "flex-1 flex items-center justify-center bg-muted/20", children: /* @__PURE__ */ jsxs70("div", { className: "text-center space-y-3 max-w-sm", children: [
18467
+ /* @__PURE__ */ jsx76(Users4, { className: "h-12 w-12 text-muted-foreground/30 mx-auto" }),
18468
+ /* @__PURE__ */ jsx76("p", { className: "text-sm text-muted-foreground", children: "Select an agent to view detailed information" }),
18469
+ /* @__PURE__ */ jsx76("p", { className: "text-xs text-muted-foreground/60", children: "Click on any agent in the list to see detailed metrics, tool logs, streaming output, and more \u2014 similar to the chat history detailed view." }),
18470
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center justify-center gap-4 pt-2", children: [
18471
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
18472
+ /* @__PURE__ */ jsx76("kbd", { className: "px-1.5 py-0.5 rounded bg-muted border text-[9px]", children: "\u2191" }),
18473
+ /* @__PURE__ */ jsx76("kbd", { className: "px-1.5 py-0.5 rounded bg-muted border text-[9px]", children: "\u2193" }),
18474
+ /* @__PURE__ */ jsx76("span", { children: "navigate" })
18578
18475
  ] }),
18579
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
18580
- /* @__PURE__ */ jsx77("kbd", { className: "px-1.5 py-0.5 rounded bg-muted border text-[9px]", children: "Enter" }),
18581
- /* @__PURE__ */ jsx77("span", { children: "select" })
18476
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
18477
+ /* @__PURE__ */ jsx76("kbd", { className: "px-1.5 py-0.5 rounded bg-muted border text-[9px]", children: "Enter" }),
18478
+ /* @__PURE__ */ jsx76("span", { children: "select" })
18582
18479
  ] }),
18583
- /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
18584
- /* @__PURE__ */ jsx77("kbd", { className: "px-1.5 py-0.5 rounded bg-muted border text-[9px]", children: "Esc" }),
18585
- /* @__PURE__ */ jsx77("span", { children: "deselect" })
18480
+ /* @__PURE__ */ jsxs70("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
18481
+ /* @__PURE__ */ jsx76("kbd", { className: "px-1.5 py-0.5 rounded bg-muted border text-[9px]", children: "Esc" }),
18482
+ /* @__PURE__ */ jsx76("span", { children: "deselect" })
18586
18483
  ] })
18587
18484
  ] })
18588
18485
  ] }) })
@@ -18592,18 +18489,468 @@ function FleetMonitor({
18592
18489
  );
18593
18490
  }
18594
18491
 
18595
- // src/App.tsx
18492
+ // src/components/InspectorPanel.tsx
18493
+ import { Bot as Bot14, ChevronDown as ChevronDown11, ChevronUp, Users as Users5 } from "lucide-react";
18494
+ import { useMemo as useMemo19, useState as useState50 } from "react";
18495
+
18496
+ // src/components/AgentsMonitor.tsx
18497
+ import { Bot as Bot13, ChevronLeft, ChevronRight as ChevronRight12, Cpu as Cpu15, Crown as Crown3, Loader2 as Loader212, Wrench as Wrench10, X as X16, Zap as Zap11 } from "lucide-react";
18498
+ import { useCallback as useCallback28, useEffect as useEffect44, useMemo as useMemo18, useState as useState49 } from "react";
18499
+ import { jsx as jsx77, jsxs as jsxs71 } from "react/jsx-runtime";
18500
+ function fmtCost6(v) {
18501
+ if (v <= 0) return "$0";
18502
+ if (v >= 0.01) return `$${v.toFixed(3)}`;
18503
+ return `$${v.toFixed(5)}`.replace(/0+$/, "").replace(/\.$/, "");
18504
+ }
18505
+ function fmtDuration3(ms) {
18506
+ const sec = Math.floor(ms / 1e3);
18507
+ if (sec < 60) return `${sec}s`;
18508
+ const min = Math.floor(sec / 60);
18509
+ return `${min}m ${sec % 60}s`;
18510
+ }
18511
+ var STATUS_META6 = {
18512
+ running: { led: "bg-[hsl(var(--success))]", label: "running", pulse: true, badge: "bg-[hsl(var(--success))]/15 text-[hsl(var(--success))]" },
18513
+ completed: { led: "bg-[hsl(var(--success))]", label: "done", pulse: false, badge: "bg-muted text-muted-foreground" },
18514
+ failed: { led: "bg-destructive", label: "failed", pulse: false, badge: "bg-destructive/15 text-destructive" },
18515
+ timeout: { led: "bg-[hsl(var(--warning))]", label: "timeout", pulse: false, badge: "bg-amber-500/15 text-amber-500" },
18516
+ stopped: { led: "bg-muted-foreground", label: "stopped", pulse: false, badge: "bg-muted text-muted-foreground" }
18517
+ };
18518
+ function AgentCard2({ agent, isLeader }) {
18519
+ const meta2 = STATUS_META6[agent.status];
18520
+ const active = agent.status === "running";
18521
+ const elapsed = Date.now() - agent.startedAt;
18522
+ const toolLogSlice = agent.toolLog.slice(0, 8);
18523
+ const last8Tools = [...toolLogSlice].reverse();
18524
+ return /* @__PURE__ */ jsxs71("div", { className: cn(
18525
+ "rounded-xl border p-4 space-y-3",
18526
+ active ? "border-primary/20 bg-primary/[0.02]" : "border-border bg-card",
18527
+ isLeader && "ring-2 ring-amber-500/30"
18528
+ ), children: [
18529
+ /* @__PURE__ */ jsxs71("div", { className: "flex items-start justify-between", children: [
18530
+ /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2", children: [
18531
+ /* @__PURE__ */ jsx77("span", { className: cn("led", meta2.led, meta2.pulse && "led-pulse", "mt-0.5") }),
18532
+ /* @__PURE__ */ jsxs71("div", { children: [
18533
+ /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-1.5", children: [
18534
+ /* @__PURE__ */ jsx77("span", { className: "text-sm font-semibold", children: agent.name }),
18535
+ isLeader && /* @__PURE__ */ jsx77(Crown3, { className: "h-3.5 w-3.5 text-amber-500", "aria-label": "leader" }),
18536
+ agent.extensions > 0 && /* @__PURE__ */ jsxs71("span", { className: "inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded-full bg-amber-500/15 text-[10px] text-amber-600 dark:text-amber-400 font-medium", children: [
18537
+ /* @__PURE__ */ jsx77(Zap11, { className: "h-2.5 w-2.5" }),
18538
+ "\xD7",
18539
+ agent.extensions
18540
+ ] })
18541
+ ] }),
18542
+ /* @__PURE__ */ jsx77("span", { className: cn("inline-block mt-0.5 px-1.5 py-0.5 rounded text-[10px] font-medium", meta2.badge), children: meta2.label })
18543
+ ] })
18544
+ ] }),
18545
+ /* @__PURE__ */ jsx77("div", { className: "flex items-center gap-1 text-[10px] text-muted-foreground", children: isLeader && /* @__PURE__ */ jsx77("span", { className: "text-[9px] bg-amber-500/15 text-amber-600 dark:text-amber-400 px-1.5 py-0.5 rounded", children: "LEADER" }) })
18546
+ ] }),
18547
+ agent.description && /* @__PURE__ */ jsx77("p", { className: "text-xs text-muted-foreground leading-relaxed line-clamp-2", children: agent.description }),
18548
+ agent.budgetWarning && /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 px-3 py-2 rounded-lg bg-amber-500/10 border border-amber-500/20 text-xs", children: [
18549
+ /* @__PURE__ */ jsx77(Zap11, { className: "h-3.5 w-3.5 text-amber-500 shrink-0" }),
18550
+ /* @__PURE__ */ jsxs71("span", { className: "text-amber-600 dark:text-amber-400", children: [
18551
+ "\u26A1 hitting ",
18552
+ /* @__PURE__ */ jsx77("strong", { children: agent.budgetWarning.kind }),
18553
+ " limit (",
18554
+ agent.budgetWarning.used,
18555
+ "/",
18556
+ agent.budgetWarning.limit,
18557
+ ") \u2014 extending"
18558
+ ] })
18559
+ ] }),
18560
+ agent.failureReason && /* @__PURE__ */ jsx77("div", { className: "flex items-center gap-2 px-3 py-2 rounded-lg bg-destructive/10 border border-destructive/20 text-xs", children: /* @__PURE__ */ jsxs71("span", { className: "text-destructive font-medium", children: [
18561
+ "\u2717 ",
18562
+ agent.failureReason
18563
+ ] }) }),
18564
+ /* @__PURE__ */ jsxs71("div", { className: "grid grid-cols-4 gap-2", children: [
18565
+ /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-muted/30 px-2 py-1.5 text-center", children: [
18566
+ /* @__PURE__ */ jsx77("div", { className: "text-[10px] text-muted-foreground", children: "Iters" }),
18567
+ /* @__PURE__ */ jsx77("div", { className: "text-xs font-mono font-semibold tabular-nums", children: agent.iteration })
18568
+ ] }),
18569
+ /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-muted/30 px-2 py-1.5 text-center", children: [
18570
+ /* @__PURE__ */ jsx77("div", { className: "text-[10px] text-muted-foreground", children: "Tools" }),
18571
+ /* @__PURE__ */ jsx77("div", { className: "text-xs font-mono font-semibold tabular-nums", children: agent.toolCalls })
18572
+ ] }),
18573
+ /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-muted/30 px-2 py-1.5 text-center", children: [
18574
+ /* @__PURE__ */ jsx77("div", { className: "text-[10px] text-muted-foreground", children: "Cost" }),
18575
+ /* @__PURE__ */ jsx77("div", { className: "text-xs font-mono font-semibold tabular-nums", children: fmtCost6(agent.costUsd) })
18576
+ ] }),
18577
+ /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-muted/30 px-2 py-1.5 text-center", children: [
18578
+ /* @__PURE__ */ jsx77("div", { className: "text-[10px] text-muted-foreground", children: "Elapsed" }),
18579
+ /* @__PURE__ */ jsx77("div", { className: "text-xs font-mono font-semibold tabular-nums", children: fmtDuration3(elapsed) })
18580
+ ] })
18581
+ ] }),
18582
+ /* @__PURE__ */ jsxs71("div", { className: "space-y-1.5", children: [
18583
+ /* @__PURE__ */ jsxs71("div", { className: "flex items-center justify-between", children: [
18584
+ /* @__PURE__ */ jsx77("span", { className: "text-[10px] text-muted-foreground", children: "Activity (12 bins)" }),
18585
+ /* @__PURE__ */ jsx77(SparklineChart, { bins: agent.sparklineBins, className: "font-mono text-[9px]" })
18586
+ ] }),
18587
+ /* @__PURE__ */ jsx77(ContextBar, { pct: agent.ctxPct, tokens: agent.ctxTokens, maxTokens: agent.maxContext })
18588
+ ] }),
18589
+ (agent.provider || agent.model) && /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
18590
+ /* @__PURE__ */ jsx77(Cpu15, { className: "h-3 w-3" }),
18591
+ /* @__PURE__ */ jsxs71("span", { className: "font-mono", children: [
18592
+ agent.provider ?? "?",
18593
+ "/",
18594
+ agent.model ?? "?"
18595
+ ] })
18596
+ ] }),
18597
+ (agent.currentTool || agent.lastTool) && /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-1.5 text-[10px] text-muted-foreground", children: [
18598
+ /* @__PURE__ */ jsx77(Wrench10, { className: cn("h-3 w-3", active && "animate-pulse text-primary") }),
18599
+ /* @__PURE__ */ jsx77("span", { className: "font-mono", children: agent.currentTool ?? agent.lastTool }),
18600
+ active && /* @__PURE__ */ jsx77(Loader212, { className: "h-3 w-3 animate-spin" })
18601
+ ] }),
18602
+ agent.partialText && active && /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-muted/30 p-2", children: [
18603
+ /* @__PURE__ */ jsx77("div", { className: "text-[9px] text-muted-foreground uppercase tracking-wider mb-1", children: "Streaming output" }),
18604
+ /* @__PURE__ */ jsx77("pre", { className: "text-[10px] font-mono text-foreground/80 whitespace-pre-wrap line-clamp-3 leading-relaxed", children: agent.partialText })
18605
+ ] }),
18606
+ last8Tools.length > 0 && /* @__PURE__ */ jsxs71("div", { className: "space-y-1", children: [
18607
+ /* @__PURE__ */ jsx77("div", { className: "text-[9px] text-muted-foreground uppercase tracking-wider", children: "Recent tools" }),
18608
+ /* @__PURE__ */ jsx77("div", { className: "space-y-0.5", children: last8Tools.map((tool, i) => /* @__PURE__ */ jsxs71("div", { className: "flex items-center gap-2 text-[10px] font-mono", children: [
18609
+ /* @__PURE__ */ jsx77("span", { className: cn("shrink-0", tool.ok ? "text-[hsl(var(--success))]" : "text-destructive"), children: tool.ok ? "\u2713" : "\u2717" }),
18610
+ /* @__PURE__ */ jsx77("span", { className: "text-muted-foreground truncate", children: tool.name }),
18611
+ /* @__PURE__ */ jsx77("span", { className: "ml-auto tabular-nums text-muted-foreground shrink-0", children: tool.durationMs >= 1e3 ? `${(tool.durationMs / 1e3).toFixed(1)}s` : `${tool.durationMs}ms` })
18612
+ ] }, i)) })
18613
+ ] }),
18614
+ agent.finalText && !active && /* @__PURE__ */ jsxs71("div", { className: "rounded-lg border bg-muted/30 p-2", children: [
18615
+ /* @__PURE__ */ jsx77("div", { className: "text-[9px] text-muted-foreground uppercase tracking-wider mb-1", children: "Final output" }),
18616
+ /* @__PURE__ */ jsx77("pre", { className: "text-[10px] font-mono text-foreground/80 whitespace-pre-wrap line-clamp-4 leading-relaxed", children: agent.finalText })
18617
+ ] })
18618
+ ] });
18619
+ }
18620
+
18621
+ // src/components/InspectorPanel.tsx
18596
18622
  import { Fragment as Fragment17, jsx as jsx78, jsxs as jsxs72 } from "react/jsx-runtime";
18623
+ var PANEL_HEIGHT = 320;
18624
+ function fmtCost7(v) {
18625
+ if (v <= 0) return "$0";
18626
+ if (v >= 0.01) return `$${v.toFixed(3)}`;
18627
+ return `$${v.toFixed(5)}`.replace(/0+$/, "").replace(/\.$/, "");
18628
+ }
18629
+ function fmtTok4(n) {
18630
+ if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
18631
+ if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
18632
+ return String(n);
18633
+ }
18634
+ function sortFleet(agents, leaderId) {
18635
+ const arr = Array.from(agents.values());
18636
+ arr.sort((x, y) => {
18637
+ if (x.id === leaderId) return -1;
18638
+ if (y.id === leaderId) return 1;
18639
+ const xa = x.status === "running" ? 0 : 1;
18640
+ const ya = y.status === "running" ? 0 : 1;
18641
+ if (xa !== ya) return xa - ya;
18642
+ return x.startedAt - y.startedAt;
18643
+ });
18644
+ return arr;
18645
+ }
18646
+ function InspectorPanel() {
18647
+ const inspectorOpen = useUIStore((s) => s.inspectorOpen);
18648
+ const inspectorTab = useUIStore((s) => s.inspectorTab);
18649
+ const toggleInspector = useUIStore((s) => s.toggleInspector);
18650
+ const setInspectorOpen = useUIStore((s) => s.setInspectorOpen);
18651
+ const setInspectorTab = useUIStore((s) => s.setInspectorTab);
18652
+ const fleetAgents = useFleetStore((s) => s.agents);
18653
+ const leaderId = useFleetStore((s) => s.leaderId);
18654
+ const fleetTokensIn = useFleetStore((s) => s.fleetTokensIn);
18655
+ const fleetTokensOut = useFleetStore((s) => s.fleetTokensOut);
18656
+ const fleetConcurrency = useFleetStore((s) => s.fleetConcurrency);
18657
+ const fleetConcurrencyMax = useFleetStore((s) => s.fleetConcurrencyMax);
18658
+ const eventTimeline = useFleetStore((s) => s.eventTimeline);
18659
+ const fleetList = useMemo19(
18660
+ () => sortFleet(fleetAgents, leaderId),
18661
+ [fleetAgents, leaderId]
18662
+ );
18663
+ const runningCount = fleetList.filter((a) => a.status === "running").length;
18664
+ const totalCost = fleetList.reduce((sum, a) => sum + a.costUsd, 0);
18665
+ const fleetTotal = fleetList.length;
18666
+ const [selectedAgentId, setSelectedAgentId] = useState50(null);
18667
+ const selectedAgent = useMemo19(() => {
18668
+ if (!selectedAgentId) return fleetList[0] ?? null;
18669
+ return fleetAgents.get(selectedAgentId) ?? fleetList[0] ?? null;
18670
+ }, [selectedAgentId, fleetList, fleetAgents]);
18671
+ const openFleetTab = () => setInspectorTab("fleet");
18672
+ const openAgentsTab = () => setInspectorTab("agents");
18673
+ const handleSelectAgent = (agent) => {
18674
+ setSelectedAgentId(agent.id);
18675
+ openAgentsTab();
18676
+ };
18677
+ return /* @__PURE__ */ jsxs72("div", { className: "shrink-0 border-t bg-card flex flex-col", children: [
18678
+ /* @__PURE__ */ jsxs72(
18679
+ "button",
18680
+ {
18681
+ type: "button",
18682
+ onClick: toggleInspector,
18683
+ className: cn(
18684
+ "group w-full flex items-center justify-between gap-2 px-3 h-7 text-[11px]",
18685
+ "text-muted-foreground hover:text-foreground hover:bg-accent/40 transition-colors"
18686
+ ),
18687
+ title: inspectorOpen ? "Hide inspector panel" : "Show inspector panel (Fleet / Agents)",
18688
+ children: [
18689
+ /* @__PURE__ */ jsxs72("span", { className: "flex items-center gap-2 min-w-0", children: [
18690
+ inspectorOpen ? /* @__PURE__ */ jsx78(ChevronDown11, { className: "h-3.5 w-3.5 shrink-0" }) : /* @__PURE__ */ jsx78(ChevronUp, { className: "h-3.5 w-3.5 shrink-0" }),
18691
+ /* @__PURE__ */ jsx78("span", { className: "font-medium uppercase tracking-wider", children: "Inspector" }),
18692
+ fleetTotal > 0 && /* @__PURE__ */ jsxs72(Fragment17, { children: [
18693
+ /* @__PURE__ */ jsx78("span", { className: "opacity-40", children: "\xB7" }),
18694
+ /* @__PURE__ */ jsxs72("span", { className: "flex items-center gap-1", children: [
18695
+ /* @__PURE__ */ jsx78(
18696
+ "span",
18697
+ {
18698
+ className: cn(
18699
+ "h-1.5 w-1.5 rounded-full",
18700
+ runningCount > 0 ? "bg-emerald-500 animate-pulse" : "bg-muted-foreground/50"
18701
+ )
18702
+ }
18703
+ ),
18704
+ /* @__PURE__ */ jsxs72("span", { className: "tabular-nums", children: [
18705
+ runningCount,
18706
+ "/",
18707
+ fleetTotal
18708
+ ] })
18709
+ ] }),
18710
+ /* @__PURE__ */ jsx78("span", { className: "opacity-40 hidden sm:inline", children: "\xB7" }),
18711
+ /* @__PURE__ */ jsxs72("span", { className: "tabular-nums font-mono hidden sm:inline", children: [
18712
+ "\u2193",
18713
+ fmtTok4(fleetTokensIn),
18714
+ " \u2191",
18715
+ fmtTok4(fleetTokensOut),
18716
+ " \xB7 ",
18717
+ fmtCost7(totalCost)
18718
+ ] })
18719
+ ] })
18720
+ ] }),
18721
+ /* @__PURE__ */ jsxs72("span", { className: "flex items-center gap-1 shrink-0 opacity-70 group-hover:opacity-100", children: [
18722
+ /* @__PURE__ */ jsx78(Bot14, { className: "h-3 w-3" }),
18723
+ /* @__PURE__ */ jsx78(Users5, { className: "h-3 w-3" })
18724
+ ] })
18725
+ ]
18726
+ }
18727
+ ),
18728
+ /* @__PURE__ */ jsx78(
18729
+ "div",
18730
+ {
18731
+ className: "overflow-hidden transition-[height] duration-300 ease-[cubic-bezier(0.16,1,0.3,1)]",
18732
+ style: { height: inspectorOpen ? PANEL_HEIGHT : 0 },
18733
+ children: /* @__PURE__ */ jsxs72("div", { className: "flex flex-col", style: { height: PANEL_HEIGHT }, children: [
18734
+ /* @__PURE__ */ jsxs72("div", { className: "flex items-center gap-1 px-2 h-8 border-b bg-muted/30 shrink-0", children: [
18735
+ /* @__PURE__ */ jsx78(
18736
+ TabButton,
18737
+ {
18738
+ active: inspectorTab === "fleet",
18739
+ onClick: openFleetTab,
18740
+ icon: /* @__PURE__ */ jsx78(Bot14, { className: "h-3.5 w-3.5" }),
18741
+ label: "Fleet",
18742
+ count: fleetTotal,
18743
+ running: runningCount
18744
+ }
18745
+ ),
18746
+ /* @__PURE__ */ jsx78(
18747
+ TabButton,
18748
+ {
18749
+ active: inspectorTab === "agents",
18750
+ onClick: openAgentsTab,
18751
+ icon: /* @__PURE__ */ jsx78(Users5, { className: "h-3.5 w-3.5" }),
18752
+ label: "Agents",
18753
+ count: fleetTotal
18754
+ }
18755
+ ),
18756
+ /* @__PURE__ */ jsx78("div", { className: "flex-1" }),
18757
+ /* @__PURE__ */ jsx78(
18758
+ "button",
18759
+ {
18760
+ type: "button",
18761
+ onClick: () => setInspectorOpen(false),
18762
+ className: "p-1 rounded hover:bg-muted transition-colors text-muted-foreground hover:text-foreground",
18763
+ "aria-label": "Collapse inspector panel",
18764
+ title: "Collapse (Esc)",
18765
+ children: /* @__PURE__ */ jsx78(ChevronDown11, { className: "h-4 w-4" })
18766
+ }
18767
+ )
18768
+ ] }),
18769
+ /* @__PURE__ */ jsx78("div", { className: "flex-1 min-h-0 overflow-y-auto", children: inspectorTab === "fleet" ? /* @__PURE__ */ jsx78(
18770
+ FleetTabContent,
18771
+ {
18772
+ fleetList,
18773
+ leaderId,
18774
+ selectedAgentId,
18775
+ runningCount,
18776
+ fleetConcurrency,
18777
+ fleetConcurrencyMax,
18778
+ fleetTokensIn,
18779
+ fleetTokensOut,
18780
+ totalCost,
18781
+ eventTimeline,
18782
+ onSelectAgent: handleSelectAgent
18783
+ }
18784
+ ) : /* @__PURE__ */ jsx78(
18785
+ AgentsTabContent,
18786
+ {
18787
+ fleetList,
18788
+ selectedAgent,
18789
+ leaderId,
18790
+ selectedAgentId: selectedAgent?.id ?? null,
18791
+ onSelectAgent: setSelectedAgentId
18792
+ }
18793
+ ) })
18794
+ ] })
18795
+ }
18796
+ )
18797
+ ] });
18798
+ }
18799
+ function TabButton({
18800
+ active,
18801
+ onClick,
18802
+ icon,
18803
+ label,
18804
+ count,
18805
+ running
18806
+ }) {
18807
+ return /* @__PURE__ */ jsxs72(
18808
+ "button",
18809
+ {
18810
+ type: "button",
18811
+ onClick,
18812
+ className: cn(
18813
+ "flex items-center gap-1.5 px-2.5 h-6 rounded-md text-[11px] font-medium transition-colors",
18814
+ active ? "bg-background text-foreground shadow-sm ring-1 ring-border" : "text-muted-foreground hover:text-foreground hover:bg-background/60"
18815
+ ),
18816
+ children: [
18817
+ icon,
18818
+ label,
18819
+ count > 0 && /* @__PURE__ */ jsx78(
18820
+ "span",
18821
+ {
18822
+ className: cn(
18823
+ "tabular-nums text-[10px] px-1 rounded-full",
18824
+ running && running > 0 ? "bg-emerald-500/15 text-emerald-600 dark:text-emerald-400" : "bg-muted text-muted-foreground"
18825
+ ),
18826
+ children: running !== void 0 ? `${running}/${count}` : count
18827
+ }
18828
+ )
18829
+ ]
18830
+ }
18831
+ );
18832
+ }
18833
+ function FleetTabContent({
18834
+ fleetList,
18835
+ leaderId,
18836
+ selectedAgentId,
18837
+ runningCount,
18838
+ fleetConcurrency,
18839
+ fleetConcurrencyMax,
18840
+ fleetTokensIn,
18841
+ fleetTokensOut,
18842
+ totalCost,
18843
+ eventTimeline,
18844
+ onSelectAgent
18845
+ }) {
18846
+ return /* @__PURE__ */ jsxs72("div", { className: "flex flex-col h-full", children: [
18847
+ /* @__PURE__ */ jsxs72("div", { className: "flex items-center gap-3 px-3 py-1.5 border-b text-[11px] text-muted-foreground shrink-0", children: [
18848
+ /* @__PURE__ */ jsxs72("span", { className: "flex items-center gap-1", children: [
18849
+ runningCount > 0 && /* @__PURE__ */ jsx78("span", { className: "h-1.5 w-1.5 rounded-full bg-emerald-500 animate-pulse" }),
18850
+ /* @__PURE__ */ jsxs72("span", { className: "tabular-nums", children: [
18851
+ runningCount,
18852
+ " running \xB7 ",
18853
+ fleetList.length,
18854
+ " total"
18855
+ ] })
18856
+ ] }),
18857
+ /* @__PURE__ */ jsx78(ConcurrencyGauge, { current: fleetConcurrency, max: fleetConcurrencyMax, showLabel: true }),
18858
+ /* @__PURE__ */ jsx78("div", { className: "flex-1" }),
18859
+ /* @__PURE__ */ jsxs72("span", { className: "tabular-nums font-mono", children: [
18860
+ "\u2193",
18861
+ fmtTok4(fleetTokensIn),
18862
+ " \u2191",
18863
+ fmtTok4(fleetTokensOut),
18864
+ " \xB7 ",
18865
+ fmtCost7(totalCost)
18866
+ ] })
18867
+ ] }),
18868
+ fleetList.length === 0 ? /* @__PURE__ */ jsxs72("div", { className: "flex flex-col items-center justify-center py-8 text-muted-foreground", children: [
18869
+ /* @__PURE__ */ jsx78(Users5, { className: "h-8 w-8 mb-2 opacity-20" }),
18870
+ /* @__PURE__ */ jsx78("p", { className: "text-xs font-medium", children: "No agents active" }),
18871
+ /* @__PURE__ */ jsx78("p", { className: "text-[11px] mt-0.5", children: "Agents appear here when the fleet is active." })
18872
+ ] }) : /* @__PURE__ */ jsx78("div", { className: "flex-1 min-h-0 overflow-y-auto p-1.5", children: fleetList.map((agent) => /* @__PURE__ */ jsx78(
18873
+ FleetAgentRow,
18874
+ {
18875
+ agent,
18876
+ isSelected: selectedAgentId === agent.id,
18877
+ isLeader: agent.id === leaderId,
18878
+ onClick: () => onSelectAgent(agent)
18879
+ },
18880
+ agent.id
18881
+ )) }),
18882
+ eventTimeline.length > 0 && /* @__PURE__ */ jsx78("div", { className: "border-t px-3 py-1.5 shrink-0", children: /* @__PURE__ */ jsx78(EventTimeline, { events: eventTimeline, max: 4 }) })
18883
+ ] });
18884
+ }
18885
+ function AgentsTabContent({
18886
+ fleetList,
18887
+ selectedAgent,
18888
+ leaderId,
18889
+ selectedAgentId,
18890
+ onSelectAgent
18891
+ }) {
18892
+ if (fleetList.length === 0) {
18893
+ return /* @__PURE__ */ jsxs72("div", { className: "flex flex-col items-center justify-center py-8 text-muted-foreground", children: [
18894
+ /* @__PURE__ */ jsx78(Bot14, { className: "h-8 w-8 mb-2 opacity-20" }),
18895
+ /* @__PURE__ */ jsx78("p", { className: "text-xs font-medium", children: "No agents active" })
18896
+ ] });
18897
+ }
18898
+ if (!selectedAgent) return null;
18899
+ const selectedIdx = Math.max(
18900
+ 0,
18901
+ fleetList.findIndex((a) => a.id === selectedAgentId)
18902
+ );
18903
+ return /* @__PURE__ */ jsxs72("div", { className: "flex flex-col h-full", children: [
18904
+ /* @__PURE__ */ jsx78("div", { className: "flex-1 min-h-0 overflow-y-auto p-3", children: /* @__PURE__ */ jsx78("div", { className: "max-w-2xl mx-auto", children: /* @__PURE__ */ jsx78(AgentCard2, { agent: selectedAgent, isLeader: selectedAgent.id === leaderId }) }) }),
18905
+ /* @__PURE__ */ jsx78("div", { className: "border-t px-2 py-1.5 shrink-0", children: /* @__PURE__ */ jsx78("div", { className: "flex items-center gap-1 overflow-x-auto pb-0.5", children: fleetList.map((agent, i) => /* @__PURE__ */ jsxs72(
18906
+ "button",
18907
+ {
18908
+ type: "button",
18909
+ onClick: () => onSelectAgent(agent.id),
18910
+ className: cn(
18911
+ "shrink-0 flex items-center gap-1.5 px-2 py-1 rounded-md text-[10px] transition-colors",
18912
+ agent.id === selectedAgent?.id ? "bg-primary/15 text-primary ring-1 ring-primary/40" : "hover:bg-accent text-muted-foreground"
18913
+ ),
18914
+ title: `${agent.name}${i === selectedIdx ? " (selected)" : ""}`,
18915
+ children: [
18916
+ /* @__PURE__ */ jsx78(
18917
+ "span",
18918
+ {
18919
+ className: cn(
18920
+ "h-1.5 w-1.5 rounded-full shrink-0",
18921
+ agent.status === "running" ? "bg-emerald-500 animate-pulse" : agent.status === "failed" ? "bg-destructive" : "bg-muted-foreground/50"
18922
+ )
18923
+ }
18924
+ ),
18925
+ /* @__PURE__ */ jsx78("span", { className: "truncate max-w-[8rem]", children: agent.name })
18926
+ ]
18927
+ },
18928
+ agent.id
18929
+ )) }) })
18930
+ ] });
18931
+ }
18932
+
18933
+ // src/App.tsx
18934
+ import { Fragment as Fragment18, jsx as jsx79, jsxs as jsxs73 } from "react/jsx-runtime";
18597
18935
  function AppInner() {
18598
18936
  const { theme } = useTheme();
18599
- const { currentView, sidebarOpen, toggleSidebar, setSearchOpen, setSidebarOpen, setCurrentView, fleetMonitorOpen, agentsMonitorOpen, setFleetMonitorOpen, setAgentsMonitorOpen } = useUIStore();
18937
+ const {
18938
+ currentView,
18939
+ sidebarOpen,
18940
+ toggleSidebar,
18941
+ setSearchOpen,
18942
+ setSidebarOpen,
18943
+ setCurrentView,
18944
+ setInspectorTab,
18945
+ toggleInspector
18946
+ } = useUIStore();
18600
18947
  const isLoading = useChatStore((s) => s.isLoading);
18601
18948
  const iteration = useSessionStore((s) => s.iteration);
18602
18949
  const projectName = useSessionStore((s) => s.projectName);
18603
18950
  const sessionTitle = useSessionStore((s) => s.session?.title);
18604
18951
  const sessionId = useSessionStore((s) => s.session?.id);
18605
18952
  const nickname = useUIStore((s) => sessionId ? s.sessionNicknames[sessionId] : void 0);
18606
- useEffect44(() => {
18953
+ useEffect45(() => {
18607
18954
  const onOpenFile = (e) => {
18608
18955
  const { filePath } = e.detail;
18609
18956
  const ws = getWSClient(useConfigStore.getState().wsUrl);
@@ -18614,7 +18961,7 @@ function AppInner() {
18614
18961
  window.addEventListener("wrongstack:open-file", onOpenFile);
18615
18962
  return () => window.removeEventListener("wrongstack:open-file", onOpenFile);
18616
18963
  }, []);
18617
- useEffect44(() => {
18964
+ useEffect45(() => {
18618
18965
  const onSaveFile = (e) => {
18619
18966
  const { filePath } = e.detail;
18620
18967
  const file = useFileStore.getState().openFiles.find((f) => f.path === filePath);
@@ -18630,7 +18977,7 @@ function AppInner() {
18630
18977
  window.addEventListener("wrongstack:save-file", onSaveFile);
18631
18978
  return () => window.removeEventListener("wrongstack:save-file", onSaveFile);
18632
18979
  }, []);
18633
- useEffect44(() => {
18980
+ useEffect45(() => {
18634
18981
  if (typeof window === "undefined") return;
18635
18982
  const mq = window.matchMedia("(max-width: 768px)");
18636
18983
  const apply = () => {
@@ -18643,7 +18990,7 @@ function AppInner() {
18643
18990
  return () => mq.removeEventListener("change", apply);
18644
18991
  }, [setSidebarOpen]);
18645
18992
  useWebSocketBootstrap();
18646
- useEffect44(() => {
18993
+ useEffect45(() => {
18647
18994
  const parts = [];
18648
18995
  if (isLoading) {
18649
18996
  const it = iteration ? ` iter ${iteration.index}${iteration.max ? `/${iteration.max}` : ""}` : "";
@@ -18660,7 +19007,7 @@ function AppInner() {
18660
19007
  document.title = projectName || "AI Agent";
18661
19008
  };
18662
19009
  }, [isLoading, iteration, projectName, sessionTitle, nickname]);
18663
- useEffect44(() => {
19010
+ useEffect45(() => {
18664
19011
  const onKey = (e) => {
18665
19012
  const t = e.target;
18666
19013
  const tag = t?.tagName?.toLowerCase();
@@ -18710,11 +19057,26 @@ function AppInner() {
18710
19057
  }
18711
19058
  if (mod && e.shiftKey && e.key.toLowerCase() === "m") {
18712
19059
  e.preventDefault();
18713
- useUIStore.getState().setFleetMonitorOpen(!useUIStore.getState().fleetMonitorOpen);
19060
+ const s = useUIStore.getState();
19061
+ if (s.inspectorOpen && s.inspectorTab === "fleet") {
19062
+ toggleInspector();
19063
+ } else {
19064
+ setInspectorTab("fleet");
19065
+ if (!s.inspectorOpen) toggleInspector();
19066
+ }
18714
19067
  }
18715
19068
  if (mod && e.shiftKey && e.key.toLowerCase() === "a") {
18716
19069
  e.preventDefault();
18717
- useUIStore.getState().setAgentsMonitorOpen(!useUIStore.getState().agentsMonitorOpen);
19070
+ const s = useUIStore.getState();
19071
+ if (s.inspectorOpen && s.inspectorTab === "agents") {
19072
+ toggleInspector();
19073
+ } else {
19074
+ setInspectorTab("agents");
19075
+ if (!s.inspectorOpen) toggleInspector();
19076
+ }
19077
+ }
19078
+ if (e.key === "Escape" && !mod && useUIStore.getState().inspectorOpen) {
19079
+ useUIStore.getState().setInspectorOpen(false);
18718
19080
  }
18719
19081
  if (!inField && !mod && !e.altKey) {
18720
19082
  const bubbles = Array.from(document.querySelectorAll("[data-message-id]"));
@@ -18773,52 +19135,41 @@ function AppInner() {
18773
19135
  window.addEventListener("keydown", onKey);
18774
19136
  return () => window.removeEventListener("keydown", onKey);
18775
19137
  }, [toggleSidebar, setSearchOpen]);
18776
- return /* @__PURE__ */ jsxs72("div", { className: cn("flex h-screen", theme), children: [
18777
- currentView !== "setup" && /* @__PURE__ */ jsx78(ActivityBar, {}),
18778
- sidebarOpen && currentView !== "setup" && /* @__PURE__ */ jsx78(SidePanel, {}),
18779
- /* @__PURE__ */ jsxs72("main", { className: "flex-1 flex flex-col overflow-hidden", children: [
18780
- currentView !== "setup" && /* @__PURE__ */ jsx78(ConnectionBanner, {}),
18781
- currentView === "chat" && /* @__PURE__ */ jsxs72(Fragment17, { children: [
18782
- sessionId && /* @__PURE__ */ jsx78("div", { className: "px-4 pt-2", children: /* @__PURE__ */ jsx78(WorkspaceDock, { sessionId }) }),
18783
- /* @__PURE__ */ jsx78(ChatView, {})
19138
+ return /* @__PURE__ */ jsxs73("div", { className: cn("flex h-screen", theme), children: [
19139
+ currentView !== "setup" && /* @__PURE__ */ jsx79(ActivityBar, {}),
19140
+ sidebarOpen && currentView !== "setup" && /* @__PURE__ */ jsx79(SidePanel, {}),
19141
+ /* @__PURE__ */ jsxs73("main", { className: "flex-1 flex flex-col overflow-hidden", children: [
19142
+ currentView !== "setup" && /* @__PURE__ */ jsx79(ConnectionBanner, {}),
19143
+ currentView === "chat" && /* @__PURE__ */ jsxs73(Fragment18, { children: [
19144
+ sessionId && /* @__PURE__ */ jsx79("div", { className: "px-4 pt-2", children: /* @__PURE__ */ jsx79(WorkspaceDock, { sessionId }) }),
19145
+ /* @__PURE__ */ jsx79(ChatView, {}),
19146
+ /* @__PURE__ */ jsx79(InspectorPanel, {})
18784
19147
  ] }),
18785
- currentView === "settings" && /* @__PURE__ */ jsx78(SettingsPanel, {}),
18786
- currentView === "setup" && /* @__PURE__ */ jsx78(SetupScreen, {}),
18787
- currentView === "autophase" && /* @__PURE__ */ jsx78(AutoPhaseView, { onClose: () => setCurrentView("chat") }),
18788
- currentView === "agents" && /* @__PURE__ */ jsx78("div", { className: "flex-1 flex flex-col overflow-hidden", children: /* @__PURE__ */ jsx78(AgentsPage, {}) }),
18789
- currentView === "agentflow" && /* @__PURE__ */ jsx78("div", { className: "flex-1 flex flex-col overflow-hidden", children: /* @__PURE__ */ jsx78(AgentFlowCanvasWithProvider, {}) }),
18790
- currentView === "fleet" && /* @__PURE__ */ jsx78("div", { className: "flex-1 flex flex-col overflow-hidden", children: /* @__PURE__ */ jsx78(FleetMonitor, { isOverlay: false }) }),
18791
- currentView === "sessions" && /* @__PURE__ */ jsx78("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx78(SessionsDashboard, {}) }),
18792
- currentView === "files" && /* @__PURE__ */ jsx78(CodeEditor, {})
19148
+ currentView === "settings" && /* @__PURE__ */ jsx79(SettingsPanel, {}),
19149
+ currentView === "setup" && /* @__PURE__ */ jsx79(SetupScreen, {}),
19150
+ currentView === "autophase" && /* @__PURE__ */ jsx79(AutoPhaseView, { onClose: () => setCurrentView("chat") }),
19151
+ currentView === "agents" && /* @__PURE__ */ jsx79("div", { className: "flex-1 flex flex-col overflow-hidden", children: /* @__PURE__ */ jsx79(AgentsPage, {}) }),
19152
+ currentView === "agentflow" && /* @__PURE__ */ jsx79("div", { className: "flex-1 flex flex-col overflow-hidden", children: /* @__PURE__ */ jsx79(AgentFlowCanvasWithProvider, {}) }),
19153
+ currentView === "fleet" && /* @__PURE__ */ jsx79("div", { className: "flex-1 flex flex-col overflow-hidden", children: /* @__PURE__ */ jsx79(FleetMonitor, { isOverlay: false }) }),
19154
+ currentView === "sessions" && /* @__PURE__ */ jsx79("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx79(SessionsDashboard, {}) }),
19155
+ currentView === "files" && /* @__PURE__ */ jsx79(CodeEditor, {})
18793
19156
  ] }),
18794
- fleetMonitorOpen && currentView !== "fleet" && /* @__PURE__ */ jsx78(
18795
- FleetMonitor,
18796
- {
18797
- isOverlay: true,
18798
- onClose: () => setFleetMonitorOpen(false),
18799
- onSelectAgent: (agent) => {
18800
- setFleetMonitorOpen(false);
18801
- setAgentsMonitorOpen(true);
18802
- }
18803
- }
18804
- ),
18805
- agentsMonitorOpen && /* @__PURE__ */ jsx78(AgentsMonitor, { onClose: () => setAgentsMonitorOpen(false) }),
18806
- /* @__PURE__ */ jsx78(ConfirmDialog, {}),
18807
- /* @__PURE__ */ jsx78(ConfirmModalHost, {}),
18808
- /* @__PURE__ */ jsx78(CommandPalette, {}),
18809
- /* @__PURE__ */ jsx78(ShortcutsOverlay, {}),
18810
- /* @__PURE__ */ jsx78(QuickModelSwitcher, {}),
18811
- /* @__PURE__ */ jsx78(Toaster, {})
19157
+ /* @__PURE__ */ jsx79(ConfirmDialog, {}),
19158
+ /* @__PURE__ */ jsx79(ConfirmModalHost, {}),
19159
+ /* @__PURE__ */ jsx79(CommandPalette, {}),
19160
+ /* @__PURE__ */ jsx79(ShortcutsOverlay, {}),
19161
+ /* @__PURE__ */ jsx79(QuickModelSwitcher, {}),
19162
+ /* @__PURE__ */ jsx79(Toaster, {})
18812
19163
  ] });
18813
19164
  }
18814
19165
  function App() {
18815
- return /* @__PURE__ */ jsx78(ErrorBoundary, { children: /* @__PURE__ */ jsx78(ThemeProvider, { defaultTheme: "system", children: /* @__PURE__ */ jsx78(AppInner, {}) }) });
19166
+ return /* @__PURE__ */ jsx79(ErrorBoundary, { children: /* @__PURE__ */ jsx79(ThemeProvider, { defaultTheme: "system", children: /* @__PURE__ */ jsx79(AppInner, {}) }) });
18816
19167
  }
18817
19168
 
18818
19169
  // src/main.tsx
18819
19170
  import "./index.css";
18820
- import { jsx as jsx79 } from "react/jsx-runtime";
19171
+ import { jsx as jsx80 } from "react/jsx-runtime";
18821
19172
  ReactDOM.createRoot(expectDefined14(document.getElementById("root"))).render(
18822
- /* @__PURE__ */ jsx79(React7.StrictMode, { children: /* @__PURE__ */ jsx79(App, {}) })
19173
+ /* @__PURE__ */ jsx80(React7.StrictMode, { children: /* @__PURE__ */ jsx80(App, {}) })
18823
19174
  );
18824
19175
  //# sourceMappingURL=index.js.map