@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/assets/index-C19_lY6u.css +2 -0
- package/dist/assets/index-DiFYgNpK.js +163 -0
- package/dist/assets/{vendor-XlX63RRU.js → vendor-BXyxPv8C.js} +1 -1
- package/dist/index.html +3 -3
- package/dist/index.js +1207 -856
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/assets/index-DH7u59XN.js +0 -164
- package/dist/assets/index-nmjg9dOb.css +0 -2
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:
|
|
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
|
-
|
|
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
|
|
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().
|
|
3109
|
-
onClick: () =>
|
|
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().
|
|
3118
|
-
onClick: () =>
|
|
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
|
|
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
|
|
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 {
|
|
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
|
|
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 (
|
|
8106
|
-
|
|
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 =
|
|
8146
|
+
const m = ITEM_RE.exec(line.trim());
|
|
8111
8147
|
if (m) {
|
|
8112
|
-
|
|
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__ */
|
|
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) =>
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
|
|
8151
|
-
|
|
8152
|
-
|
|
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
|
|
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
|
|
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] =
|
|
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 =
|
|
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] =
|
|
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
|
|
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] =
|
|
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
|
|
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] =
|
|
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] =
|
|
8436
|
-
const [editing, setEditing] =
|
|
8437
|
-
const [editValue, setEditValue] =
|
|
8438
|
-
const [showRaw, setShowRaw] =
|
|
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(
|
|
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
|
|
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] =
|
|
8842
|
+
const [open, setOpen] = useState20(false);
|
|
8710
8843
|
const rootRef = useRef11(null);
|
|
8711
|
-
|
|
8844
|
+
useEffect15(() => {
|
|
8712
8845
|
if (open) listModes();
|
|
8713
8846
|
}, [open, listModes]);
|
|
8714
|
-
|
|
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
|
|
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] =
|
|
8926
|
+
const [processes, setProcesses] = useState21([]);
|
|
8794
8927
|
const ws = useWebSocket();
|
|
8795
8928
|
const offRef = useRef12(null);
|
|
8796
8929
|
const pollRef = useRef12(null);
|
|
8797
|
-
|
|
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
|
|
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] =
|
|
8955
|
-
const [repaintNonce, setRepaintNonce] =
|
|
8956
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9114
|
+
useEffect17(() => {
|
|
8970
9115
|
if (activeHit >= hits.length) setActiveHit(0);
|
|
8971
9116
|
}, [hits, activeHit]);
|
|
8972
|
-
|
|
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
|
-
|
|
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
|
|
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] =
|
|
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
|
|
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] =
|
|
9261
|
-
|
|
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
|
-
|
|
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] =
|
|
9522
|
-
const [titleDraft, setTitleDraft] =
|
|
9666
|
+
const [renamingTitle, setRenamingTitle] = useState25(false);
|
|
9667
|
+
const [titleDraft, setTitleDraft] = useState25("");
|
|
9523
9668
|
const historyEntries = useHistoryStore((s) => s.entries);
|
|
9524
|
-
const [switcherOpen, setSwitcherOpen] =
|
|
9669
|
+
const [switcherOpen, setSwitcherOpen] = useState25(false);
|
|
9525
9670
|
const switcherRef = useRef14(null);
|
|
9526
|
-
|
|
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 =
|
|
9688
|
+
const rows = useMemo7(() => buildChatRows(messages), [messages]);
|
|
9544
9689
|
const childCountRef = useRef14(0);
|
|
9545
9690
|
childCountRef.current = rows.length + 1;
|
|
9546
|
-
const rowIndexById =
|
|
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] =
|
|
9567
|
-
const [checkpointOpen, setCheckpointOpen] =
|
|
9568
|
-
const [breakdownOpen, setBreakdownOpen] =
|
|
9569
|
-
|
|
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] =
|
|
9577
|
-
const [unreadCount, setUnreadCount] =
|
|
9578
|
-
const [scrolledDeep, setScrolledDeep] =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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] =
|
|
9627
|
-
const [nowTick, setNowTick] =
|
|
9779
|
+
const [runStartedAt, setRunStartedAt] = useState25(null);
|
|
9780
|
+
const [nowTick, setNowTick] = useState25(() => Date.now());
|
|
9628
9781
|
const streamAnchor = useRef14(null);
|
|
9629
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9938
|
-
|
|
9939
|
-
|
|
9940
|
-
|
|
9941
|
-
|
|
9942
|
-
|
|
9943
|
-
|
|
9944
|
-
|
|
9945
|
-
)
|
|
9946
|
-
|
|
9947
|
-
|
|
9948
|
-
|
|
9949
|
-
|
|
9950
|
-
|
|
9951
|
-
|
|
9952
|
-
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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] =
|
|
10931
|
-
const [now, setNow] =
|
|
10932
|
-
|
|
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
|
-
|
|
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
|
|
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] =
|
|
11062
|
-
const [selected, setSelected] =
|
|
11063
|
-
const [saved, setSaved] =
|
|
11064
|
-
const [modelsByProvider, setModelsByProvider] =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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] =
|
|
11491
|
-
const [newKeyLabel, setNewKeyLabel] =
|
|
11492
|
-
const [newKeyValue, setNewKeyValue] =
|
|
11493
|
-
const [showNewKeyValue, setShowNewKeyValue] =
|
|
11494
|
-
const [showAddProviderForm, setShowAddProviderForm] =
|
|
11495
|
-
const [newProviderId, setNewProviderId] =
|
|
11496
|
-
const [newProviderFamily, setNewProviderFamily] =
|
|
11497
|
-
const [newProviderBaseUrl, setNewProviderBaseUrl] =
|
|
11498
|
-
const [newProviderApiKey, setNewProviderApiKey] =
|
|
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] =
|
|
11883
|
-
const [catalogModels, setCatalogModels] =
|
|
11884
|
-
const [savedProviders, setSavedProviders] =
|
|
11885
|
-
const [isLoadingCatalog, setIsLoadingCatalog] =
|
|
11886
|
-
const [isLoadingModels, setIsLoadingModels] =
|
|
11887
|
-
const [isLoadingSaved, setIsLoadingSaved] =
|
|
11888
|
-
const [providerTab, setProviderTab] =
|
|
11889
|
-
const [catalogQuery, setCatalogQuery] =
|
|
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
|
-
|
|
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
|
|
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] =
|
|
12536
|
-
const [label, setLabel] =
|
|
12537
|
-
const [isLoading, setIsLoading] =
|
|
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] =
|
|
12592
|
-
const [catalogProviders, setCatalogProviders] =
|
|
12593
|
-
const [catalogModels, setCatalogModels] =
|
|
12594
|
-
const [savedProviders, setSavedProviders] =
|
|
12595
|
-
const [isLoadingCatalog, setIsLoadingCatalog] =
|
|
12596
|
-
const [isLoadingModels, setIsLoadingModels] =
|
|
12597
|
-
const [selectedProvider, setSelectedProvider] =
|
|
12598
|
-
const [selectedModel, setSelectedModel] =
|
|
12599
|
-
|
|
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
|
-
|
|
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
|
|
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] =
|
|
12911
|
-
const [loading, setLoading] =
|
|
12912
|
-
const [error, setError] =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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] =
|
|
13529
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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] =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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] =
|
|
14193
|
-
|
|
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] =
|
|
14376
|
+
const [showSpinner, setShowSpinner] = useState33(false);
|
|
14235
14377
|
const spinnerTimer = useRef19(null);
|
|
14236
|
-
|
|
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] =
|
|
14248
|
-
const [globalExpand, setGlobalExpand] =
|
|
14249
|
-
const dirCount =
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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] =
|
|
14540
|
-
const [deleting, setDeleting] =
|
|
14681
|
+
const [collapsed, setCollapsed] = useState34(false);
|
|
14682
|
+
const [deleting, setDeleting] = useState34(false);
|
|
14541
14683
|
const { client: client2 } = useWebSocket();
|
|
14542
|
-
const [ready, setReady] =
|
|
14543
|
-
|
|
14544
|
-
|
|
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
|
-
|
|
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
|
|
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] =
|
|
14676
|
-
const [loading, setLoading] =
|
|
14677
|
-
const [adding, setAdding] =
|
|
14678
|
-
const [folderPath, setFolderPath] =
|
|
14679
|
-
const [projectName, setProjectName] =
|
|
14680
|
-
const [dialogOpen, setDialogOpen] =
|
|
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] =
|
|
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
|
-
|
|
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
|
|
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
|
|
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] =
|
|
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] =
|
|
15343
|
-
const [selectedId, setSelectedId] =
|
|
15344
|
-
const list =
|
|
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] =
|
|
15458
|
-
const fleetList =
|
|
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
|
|
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
|
|
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] =
|
|
15549
|
-
const [renameDraft, setRenameDraft] =
|
|
15550
|
-
const [resumingId, setResumingId] =
|
|
15551
|
-
|
|
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 =
|
|
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] =
|
|
15779
|
-
|
|
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
|
|
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] =
|
|
16102
|
+
const [breakdownOpen, setBreakdownOpen] = useState40(false);
|
|
15958
16103
|
const startedAt = session?.startedAt ?? null;
|
|
15959
|
-
const [now, setNow] =
|
|
15960
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
|
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] =
|
|
16409
|
-
const [joined, setJoined] =
|
|
16410
|
-
const [joinedRole, setJoinedRole] =
|
|
16411
|
-
const [error, setError] =
|
|
16412
|
-
const [openAnnotationCount, setOpenAnnotationCount] =
|
|
16413
|
-
const [paused, setPaused] =
|
|
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
|
-
|
|
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
|
|
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] =
|
|
16740
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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] =
|
|
16881
|
-
const [collapsedSections, setCollapsedSections] =
|
|
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
|
-
|
|
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
|
|
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] =
|
|
17043
|
-
const [collapsed, setCollapsed] =
|
|
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
|
-
|
|
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
|
|
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] =
|
|
17195
|
-
const [collapsed, setCollapsed] =
|
|
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
|
-
|
|
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] =
|
|
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] =
|
|
17577
|
+
const [worktreeView, setWorktreeView] = useState47("graph");
|
|
17433
17578
|
const fleetTotal = fleetAgents.size;
|
|
17434
|
-
const fleetRunning =
|
|
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
|
-
|
|
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/
|
|
17584
|
-
import {
|
|
17585
|
-
|
|
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
|
-
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
17985
|
-
/* @__PURE__ */
|
|
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__ */
|
|
17988
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
18029
|
-
/* @__PURE__ */
|
|
18030
|
-
/* @__PURE__ */
|
|
18031
|
-
ev.value !== void 0 && ev.kind === "tool_executed" && /* @__PURE__ */
|
|
18032
|
-
ev.value !== void 0 && ev.kind === "ctx_pct" && /* @__PURE__ */
|
|
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
|
|
18044
|
-
function
|
|
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
|
|
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 =
|
|
17968
|
+
const meta2 = STATUS_META5[agent.status];
|
|
18076
17969
|
const active = agent.status === "running";
|
|
18077
|
-
const handleCopy =
|
|
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 =
|
|
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__ */
|
|
18095
|
-
/* @__PURE__ */
|
|
18096
|
-
/* @__PURE__ */
|
|
18097
|
-
/* @__PURE__ */
|
|
18098
|
-
/* @__PURE__ */
|
|
18099
|
-
/* @__PURE__ */
|
|
18100
|
-
/* @__PURE__ */
|
|
18101
|
-
/* @__PURE__ */
|
|
18102
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
18115
|
-
active && /* @__PURE__ */
|
|
18116
|
-
/* @__PURE__ */
|
|
18117
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18012
|
+
/* @__PURE__ */ jsx76("span", { className: cn("led", meta2.led, active && "led-pulse") })
|
|
18120
18013
|
] })
|
|
18121
18014
|
] }),
|
|
18122
|
-
/* @__PURE__ */
|
|
18123
|
-
/* @__PURE__ */
|
|
18124
|
-
/* @__PURE__ */
|
|
18125
|
-
agent.budgetWarning && /* @__PURE__ */
|
|
18126
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18131
|
-
/* @__PURE__ */
|
|
18132
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18136
|
-
/* @__PURE__ */
|
|
18137
|
-
/* @__PURE__ */
|
|
18138
|
-
/* @__PURE__ */
|
|
18139
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
18149
|
-
/* @__PURE__ */
|
|
18150
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18154
|
-
/* @__PURE__ */
|
|
18155
|
-
/* @__PURE__ */
|
|
18156
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18159
|
-
/* @__PURE__ */
|
|
18160
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18163
|
-
/* @__PURE__ */
|
|
18164
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18169
|
-
/* @__PURE__ */
|
|
18170
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18174
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18181
|
-
/* @__PURE__ */
|
|
18182
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18186
|
-
/* @__PURE__ */
|
|
18187
|
-
/* @__PURE__ */
|
|
18188
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
18212
|
-
/* @__PURE__ */
|
|
18213
|
-
active ? /* @__PURE__ */
|
|
18214
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18109
|
+
] }) : /* @__PURE__ */ jsx76("span", { className: "ml-auto text-[10px] text-muted-foreground", children: "completed" })
|
|
18217
18110
|
] }),
|
|
18218
|
-
outputText ? /* @__PURE__ */
|
|
18219
|
-
/* @__PURE__ */
|
|
18220
|
-
/* @__PURE__ */
|
|
18221
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18224
|
-
/* @__PURE__ */
|
|
18116
|
+
] }) : /* @__PURE__ */ jsxs70(Fragment16, { children: [
|
|
18117
|
+
/* @__PURE__ */ jsx76(FolderOpen5, { className: "h-3 w-3" }),
|
|
18225
18118
|
"Final Output"
|
|
18226
18119
|
] }) }),
|
|
18227
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18238
|
-
] }) : active ? /* @__PURE__ */
|
|
18239
|
-
/* @__PURE__ */
|
|
18240
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18243
|
-
/* @__PURE__ */
|
|
18244
|
-
/* @__PURE__ */
|
|
18245
|
-
/* @__PURE__ */
|
|
18246
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18258
|
-
/* @__PURE__ */
|
|
18259
|
-
/* @__PURE__ */
|
|
18260
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
18275
|
-
/* @__PURE__ */
|
|
18276
|
-
/* @__PURE__ */
|
|
18277
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18172
|
+
/* @__PURE__ */ jsx76("p", { className: "text-sm text-destructive/90", children: agent.error.message })
|
|
18280
18173
|
] }),
|
|
18281
|
-
agent.failureReason && /* @__PURE__ */
|
|
18282
|
-
/* @__PURE__ */
|
|
18283
|
-
/* @__PURE__ */
|
|
18284
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18179
|
+
/* @__PURE__ */ jsx76("p", { className: "text-sm text-destructive/90", children: agent.failureReason })
|
|
18287
18180
|
] }),
|
|
18288
|
-
agent.toolLog.length > 0 && /* @__PURE__ */
|
|
18289
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18297
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
18315
|
-
/* @__PURE__ */
|
|
18316
|
-
/* @__PURE__ */
|
|
18317
|
-
!tl.ok && /* @__PURE__ */
|
|
18318
|
-
/* @__PURE__ */
|
|
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 =
|
|
18226
|
+
const meta2 = STATUS_META5[agent.status];
|
|
18334
18227
|
const active = agent.status === "running";
|
|
18335
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
18347
|
-
/* @__PURE__ */
|
|
18348
|
-
/* @__PURE__ */
|
|
18349
|
-
isLeader && /* @__PURE__ */
|
|
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__ */
|
|
18352
|
-
/* @__PURE__ */
|
|
18353
|
-
/* @__PURE__ */
|
|
18354
|
-
agent.budgetWarning && /* @__PURE__ */
|
|
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__ */
|
|
18249
|
+
/* @__PURE__ */ jsxs70("span", { className: "tabular-nums text-muted-foreground text-[10px]", children: [
|
|
18357
18250
|
agent.iteration,
|
|
18358
18251
|
"it"
|
|
18359
18252
|
] }),
|
|
18360
|
-
/* @__PURE__ */
|
|
18253
|
+
/* @__PURE__ */ jsxs70("span", { className: "tabular-nums text-muted-foreground text-[10px]", children: [
|
|
18361
18254
|
agent.toolCalls,
|
|
18362
18255
|
"tc"
|
|
18363
18256
|
] }),
|
|
18364
|
-
/* @__PURE__ */
|
|
18365
|
-
/* @__PURE__ */
|
|
18366
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
18379
|
-
/* @__PURE__ */
|
|
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 =
|
|
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 =
|
|
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
|
|
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__ */
|
|
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__ */
|
|
18462
|
-
/* @__PURE__ */
|
|
18463
|
-
/* @__PURE__ */
|
|
18464
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18467
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18473
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
18488
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
18391
|
+
fmtCost5(totalCost)
|
|
18495
18392
|
] }),
|
|
18496
|
-
/* @__PURE__ */
|
|
18497
|
-
isOverlay && onClose && /* @__PURE__ */
|
|
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__ */
|
|
18401
|
+
children: /* @__PURE__ */ jsx76(XCircle9, { className: "h-4 w-4" })
|
|
18505
18402
|
}
|
|
18506
18403
|
)
|
|
18507
18404
|
] })
|
|
18508
18405
|
] }),
|
|
18509
|
-
/* @__PURE__ */
|
|
18510
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18515
|
-
/* @__PURE__ */
|
|
18516
|
-
/* @__PURE__ */
|
|
18517
|
-
/* @__PURE__ */
|
|
18518
|
-
/* @__PURE__ */
|
|
18519
|
-
/* @__PURE__ */
|
|
18520
|
-
/* @__PURE__ */
|
|
18521
|
-
/* @__PURE__ */
|
|
18522
|
-
/* @__PURE__ */
|
|
18523
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18526
|
-
/* @__PURE__ */
|
|
18527
|
-
/* @__PURE__ */
|
|
18528
|
-
/* @__PURE__ */
|
|
18529
|
-
] }) : /* @__PURE__ */
|
|
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: () =>
|
|
18432
|
+
onClick: () => handleAgentClick(i)
|
|
18536
18433
|
},
|
|
18537
18434
|
agent.id
|
|
18538
18435
|
)) }) }),
|
|
18539
|
-
/* @__PURE__ */
|
|
18540
|
-
/* @__PURE__ */
|
|
18541
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18545
|
-
/* @__PURE__ */
|
|
18546
|
-
/* @__PURE__ */
|
|
18547
|
-
/* @__PURE__ */
|
|
18548
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18553
|
-
/* @__PURE__ */
|
|
18554
|
-
/* @__PURE__ */
|
|
18555
|
-
/* @__PURE__ */
|
|
18556
|
-
/* @__PURE__ */
|
|
18557
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
18570
|
-
/* @__PURE__ */
|
|
18571
|
-
/* @__PURE__ */
|
|
18572
|
-
/* @__PURE__ */
|
|
18573
|
-
/* @__PURE__ */
|
|
18574
|
-
/* @__PURE__ */
|
|
18575
|
-
/* @__PURE__ */
|
|
18576
|
-
/* @__PURE__ */
|
|
18577
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18580
|
-
/* @__PURE__ */
|
|
18581
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18584
|
-
/* @__PURE__ */
|
|
18585
|
-
/* @__PURE__ */
|
|
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/
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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()
|
|
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()
|
|
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__ */
|
|
18777
|
-
currentView !== "setup" && /* @__PURE__ */
|
|
18778
|
-
sidebarOpen && currentView !== "setup" && /* @__PURE__ */
|
|
18779
|
-
/* @__PURE__ */
|
|
18780
|
-
currentView !== "setup" && /* @__PURE__ */
|
|
18781
|
-
currentView === "chat" && /* @__PURE__ */
|
|
18782
|
-
sessionId && /* @__PURE__ */
|
|
18783
|
-
/* @__PURE__ */
|
|
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__ */
|
|
18786
|
-
currentView === "setup" && /* @__PURE__ */
|
|
18787
|
-
currentView === "autophase" && /* @__PURE__ */
|
|
18788
|
-
currentView === "agents" && /* @__PURE__ */
|
|
18789
|
-
currentView === "agentflow" && /* @__PURE__ */
|
|
18790
|
-
currentView === "fleet" && /* @__PURE__ */
|
|
18791
|
-
currentView === "sessions" && /* @__PURE__ */
|
|
18792
|
-
currentView === "files" && /* @__PURE__ */
|
|
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
|
-
|
|
18795
|
-
|
|
18796
|
-
|
|
18797
|
-
|
|
18798
|
-
|
|
18799
|
-
|
|
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__ */
|
|
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
|
|
19171
|
+
import { jsx as jsx80 } from "react/jsx-runtime";
|
|
18821
19172
|
ReactDOM.createRoot(expectDefined14(document.getElementById("root"))).render(
|
|
18822
|
-
/* @__PURE__ */
|
|
19173
|
+
/* @__PURE__ */ jsx80(React7.StrictMode, { children: /* @__PURE__ */ jsx80(App, {}) })
|
|
18823
19174
|
);
|
|
18824
19175
|
//# sourceMappingURL=index.js.map
|