@wrongstack/webui 0.54.1 → 0.66.13
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/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-500-normal-Ael50iVv.woff +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-500-normal-Bq9vWWag.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-600-normal-CTOM6hUh.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-600-normal-fLZuRloM.woff +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-ext-500-normal-BIfNGwUT.woff +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-ext-500-normal-BqneJy0T.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-ext-600-normal-9HEixskS.woff +0 -0
- package/dist/assets/ibm-plex-mono-cyrillic-ext-600-normal-V-xxqcpd.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
- package/dist/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
- package/dist/assets/ibm-plex-mono-latin-ext-500-normal-CAhNIIs5.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-ext-500-normal-CZ70TYgx.woff +0 -0
- package/dist/assets/ibm-plex-mono-latin-ext-600-normal-D38SheWl.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-latin-ext-600-normal-DmB0ttJJ.woff +0 -0
- package/dist/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
- package/dist/assets/ibm-plex-mono-vietnamese-500-normal-C8zxqsMH.woff +0 -0
- package/dist/assets/ibm-plex-mono-vietnamese-500-normal-DZ4AoWbu.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-vietnamese-600-normal-D2EvbN8M.woff2 +0 -0
- package/dist/assets/ibm-plex-mono-vietnamese-600-normal-iLQfcSjf.woff +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-ext-wght-normal-d45eAU9y.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-cyrillic-wght-normal-BAAhND-U.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-greek-wght-normal-CmyJS8uq.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-ext-wght-normal-CIII54If.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-latin-wght-normal-IvpUvPa2.woff2 +0 -0
- package/dist/assets/ibm-plex-sans-vietnamese-wght-normal-Dg1JeJN0.woff2 +0 -0
- package/dist/assets/index-CnURnGh-.css +1 -0
- package/dist/assets/index-aAReViZF.js +94 -0
- package/dist/assets/vendor-DW1jimNH.css +1 -0
- package/dist/index.css +333 -200
- package/dist/index.css.map +1 -1
- package/dist/index.html +4 -3
- package/dist/index.js +984 -641
- package/dist/index.js.map +1 -1
- package/dist/server/entry.js +444 -126
- package/dist/server/entry.js.map +1 -1
- package/dist/server/index.d.ts +298 -2
- package/dist/server/index.js +445 -96
- package/dist/server/index.js.map +1 -1
- package/package.json +9 -6
- package/dist/assets/index-5ECutVTP.css +0 -1
- package/dist/assets/index-BRHGqfHg.js +0 -94
- /package/dist/assets/{vendor-oYD55Pw4.js → vendor-wUxgMlp-.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// src/main.tsx
|
|
2
2
|
import React6 from "react";
|
|
3
3
|
import ReactDOM from "react-dom/client";
|
|
4
|
+
import "@fontsource-variable/ibm-plex-sans";
|
|
5
|
+
import "@fontsource/ibm-plex-mono/400.css";
|
|
6
|
+
import "@fontsource/ibm-plex-mono/500.css";
|
|
7
|
+
import "@fontsource/ibm-plex-mono/600.css";
|
|
4
8
|
|
|
5
9
|
// src/lib/utils.ts
|
|
6
10
|
import { clsx } from "clsx";
|
|
@@ -592,8 +596,15 @@ var WrongStackWebSocketClient = class {
|
|
|
592
596
|
}
|
|
593
597
|
};
|
|
594
598
|
var client = null;
|
|
599
|
+
var DEFAULT_WS_PORT = 3457;
|
|
600
|
+
function resolveWsPort() {
|
|
601
|
+
if (typeof document === "undefined") return DEFAULT_WS_PORT;
|
|
602
|
+
const raw = document.querySelector('meta[name="wrongstack-ws-port"]')?.getAttribute("content");
|
|
603
|
+
const parsed = raw ? Number.parseInt(raw, 10) : Number.NaN;
|
|
604
|
+
return Number.isFinite(parsed) && parsed > 0 && parsed < 65536 ? parsed : DEFAULT_WS_PORT;
|
|
605
|
+
}
|
|
595
606
|
function defaultWsUrl() {
|
|
596
|
-
const port =
|
|
607
|
+
const port = resolveWsPort();
|
|
597
608
|
if (typeof window === "undefined" || !window.location?.hostname) {
|
|
598
609
|
return `ws://127.0.0.1:${port}`;
|
|
599
610
|
}
|
|
@@ -966,6 +977,73 @@ var useWorktreeStore = create2()((set) => ({
|
|
|
966
977
|
setSnapshot: (worktrees, baseBranch) => set({ worktrees, baseBranch }),
|
|
967
978
|
pushEvent: (e) => set((s) => ({ activity: [...s.activity, e].slice(-40) }))
|
|
968
979
|
}));
|
|
980
|
+
function blankAgent(id, name) {
|
|
981
|
+
return {
|
|
982
|
+
id,
|
|
983
|
+
name: name?.trim() || id,
|
|
984
|
+
status: "running",
|
|
985
|
+
iteration: 0,
|
|
986
|
+
toolCalls: 0,
|
|
987
|
+
costUsd: 0,
|
|
988
|
+
ctxPct: 0,
|
|
989
|
+
ctxTokens: 0,
|
|
990
|
+
maxContext: 0,
|
|
991
|
+
extensions: 0,
|
|
992
|
+
startedAt: Date.now()
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
var useFleetStore = create2()((set) => ({
|
|
996
|
+
agents: /* @__PURE__ */ new Map(),
|
|
997
|
+
clear: () => set({ agents: /* @__PURE__ */ new Map() }),
|
|
998
|
+
applyEvent: (e) => set((state) => {
|
|
999
|
+
const agents = new Map(state.agents);
|
|
1000
|
+
const prev = agents.get(e.subagentId) ?? blankAgent(e.subagentId, e.name);
|
|
1001
|
+
const next = { ...prev };
|
|
1002
|
+
switch (e.kind) {
|
|
1003
|
+
case "spawned":
|
|
1004
|
+
next.name = e.name?.trim() || next.name;
|
|
1005
|
+
next.provider = e.provider ?? next.provider;
|
|
1006
|
+
next.model = e.model ?? next.model;
|
|
1007
|
+
next.description = e.description ?? next.description;
|
|
1008
|
+
next.taskId = e.taskId ?? next.taskId;
|
|
1009
|
+
next.status = "running";
|
|
1010
|
+
break;
|
|
1011
|
+
case "task_started":
|
|
1012
|
+
next.description = e.description ?? next.description;
|
|
1013
|
+
next.taskId = e.taskId ?? next.taskId;
|
|
1014
|
+
next.status = "running";
|
|
1015
|
+
break;
|
|
1016
|
+
case "tool_executed":
|
|
1017
|
+
next.lastTool = e.toolName ?? next.lastTool;
|
|
1018
|
+
next.toolCalls = next.toolCalls + 1;
|
|
1019
|
+
break;
|
|
1020
|
+
case "iteration_summary":
|
|
1021
|
+
next.iteration = e.iteration ?? next.iteration;
|
|
1022
|
+
if (typeof e.toolCalls === "number") next.toolCalls = e.toolCalls;
|
|
1023
|
+
if (typeof e.costUsd === "number") next.costUsd = e.costUsd;
|
|
1024
|
+
next.currentTool = e.currentTool ?? next.currentTool;
|
|
1025
|
+
break;
|
|
1026
|
+
case "budget_extended":
|
|
1027
|
+
next.extensions = e.totalExtensions ?? next.extensions + 1;
|
|
1028
|
+
break;
|
|
1029
|
+
case "ctx_pct":
|
|
1030
|
+
next.ctxPct = Math.round(Math.min(1, Math.max(0, e.load ?? 0)) * 100);
|
|
1031
|
+
next.ctxTokens = e.tokens ?? next.ctxTokens;
|
|
1032
|
+
next.maxContext = e.maxContext ?? next.maxContext;
|
|
1033
|
+
break;
|
|
1034
|
+
case "task_completed":
|
|
1035
|
+
next.status = e.status === "success" ? "completed" : e.status ?? "completed";
|
|
1036
|
+
if (typeof e.iterations === "number") next.iteration = e.iterations;
|
|
1037
|
+
if (typeof e.toolCalls === "number") next.toolCalls = e.toolCalls;
|
|
1038
|
+
next.error = e.error;
|
|
1039
|
+
next.currentTool = void 0;
|
|
1040
|
+
next.completedAt = Date.now();
|
|
1041
|
+
break;
|
|
1042
|
+
}
|
|
1043
|
+
agents.set(e.subagentId, next);
|
|
1044
|
+
return { agents };
|
|
1045
|
+
})
|
|
1046
|
+
}));
|
|
969
1047
|
|
|
970
1048
|
// src/hooks/useWebSocket.ts
|
|
971
1049
|
import { useCallback, useEffect as useEffect2, useRef } from "react";
|
|
@@ -997,7 +1075,10 @@ function installHandlers(ws) {
|
|
|
997
1075
|
provider: payload.provider,
|
|
998
1076
|
model: payload.model
|
|
999
1077
|
});
|
|
1000
|
-
if (isNew || payload.reset)
|
|
1078
|
+
if (isNew || payload.reset) {
|
|
1079
|
+
useChatStore.getState().clearMessages();
|
|
1080
|
+
useFleetStore.getState().clear();
|
|
1081
|
+
}
|
|
1001
1082
|
const replay = payload.replayMessages;
|
|
1002
1083
|
if (replay && replay.length > 0) {
|
|
1003
1084
|
const chat = useChatStore.getState();
|
|
@@ -1441,6 +1522,9 @@ ${body}` : "\u{1F9E0} **Memory** \n\n_empty \u2014 nothing remembered yet_"
|
|
|
1441
1522
|
const p = msg.payload;
|
|
1442
1523
|
useWorktreeStore.getState().pushEvent(p);
|
|
1443
1524
|
});
|
|
1525
|
+
on("subagent.event", (msg) => {
|
|
1526
|
+
useFleetStore.getState().applyEvent(msg.payload);
|
|
1527
|
+
});
|
|
1444
1528
|
return () => {
|
|
1445
1529
|
for (const off of offs) off();
|
|
1446
1530
|
};
|
|
@@ -1627,14 +1711,11 @@ import {
|
|
|
1627
1711
|
Command,
|
|
1628
1712
|
Cpu as Cpu2,
|
|
1629
1713
|
FolderOpen,
|
|
1630
|
-
Monitor as Monitor2,
|
|
1631
|
-
Moon as Moon2,
|
|
1632
1714
|
PanelLeftOpen,
|
|
1633
1715
|
Settings,
|
|
1634
|
-
Sun as Sun2,
|
|
1635
1716
|
Zap as Zap2
|
|
1636
1717
|
} from "lucide-react";
|
|
1637
|
-
import { useCallback as useCallback3, useEffect as
|
|
1718
|
+
import { useCallback as useCallback3, useEffect as useEffect13, useRef as useRef9, useState as useState14 } from "react";
|
|
1638
1719
|
|
|
1639
1720
|
// src/components/ChatInput.tsx
|
|
1640
1721
|
import { Pencil, Send, Square } from "lucide-react";
|
|
@@ -4618,10 +4699,99 @@ function SearchOverlay() {
|
|
|
4618
4699
|
] }) });
|
|
4619
4700
|
}
|
|
4620
4701
|
|
|
4702
|
+
// src/components/ThemeToggle.tsx
|
|
4703
|
+
import { Monitor as Monitor2, Moon as Moon2, Sun as Sun2 } from "lucide-react";
|
|
4704
|
+
|
|
4705
|
+
// src/components/ThemeProvider.tsx
|
|
4706
|
+
import { createContext, useContext, useEffect as useEffect11, useState as useState11 } from "react";
|
|
4707
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
4708
|
+
var ThemeProviderContext = createContext(void 0);
|
|
4709
|
+
function ThemeProvider({
|
|
4710
|
+
children,
|
|
4711
|
+
defaultTheme = "system",
|
|
4712
|
+
storageKey = "wrongstack-theme"
|
|
4713
|
+
}) {
|
|
4714
|
+
const { setTheme: setStoreTheme } = useConfigStore();
|
|
4715
|
+
const [theme, setTheme] = useState11(() => {
|
|
4716
|
+
if (typeof window !== "undefined") {
|
|
4717
|
+
return localStorage.getItem(storageKey) || defaultTheme;
|
|
4718
|
+
}
|
|
4719
|
+
return defaultTheme;
|
|
4720
|
+
});
|
|
4721
|
+
useEffect11(() => {
|
|
4722
|
+
const root = window.document.documentElement;
|
|
4723
|
+
root.classList.remove("light", "dark");
|
|
4724
|
+
if (theme === "system") {
|
|
4725
|
+
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
4726
|
+
root.classList.add(systemTheme);
|
|
4727
|
+
} else {
|
|
4728
|
+
root.classList.add(theme);
|
|
4729
|
+
}
|
|
4730
|
+
}, [theme]);
|
|
4731
|
+
const value = {
|
|
4732
|
+
theme,
|
|
4733
|
+
setTheme: (newTheme) => {
|
|
4734
|
+
localStorage.setItem(storageKey, newTheme);
|
|
4735
|
+
setTheme(newTheme);
|
|
4736
|
+
setStoreTheme(newTheme);
|
|
4737
|
+
}
|
|
4738
|
+
};
|
|
4739
|
+
return /* @__PURE__ */ jsx14(ThemeProviderContext.Provider, { value, children });
|
|
4740
|
+
}
|
|
4741
|
+
function useTheme() {
|
|
4742
|
+
const context = useContext(ThemeProviderContext);
|
|
4743
|
+
if (context === void 0) {
|
|
4744
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
4745
|
+
}
|
|
4746
|
+
return context;
|
|
4747
|
+
}
|
|
4748
|
+
|
|
4749
|
+
// src/components/ThemeToggle.tsx
|
|
4750
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
4751
|
+
var OPTIONS = [
|
|
4752
|
+
{ value: "light", icon: Sun2, label: "Light" },
|
|
4753
|
+
{ value: "dark", icon: Moon2, label: "Dark" },
|
|
4754
|
+
{ value: "system", icon: Monitor2, label: "System" }
|
|
4755
|
+
];
|
|
4756
|
+
function ThemeToggle({ className }) {
|
|
4757
|
+
const { theme, setTheme } = useTheme();
|
|
4758
|
+
return /* @__PURE__ */ jsx15(
|
|
4759
|
+
"div",
|
|
4760
|
+
{
|
|
4761
|
+
className: cn(
|
|
4762
|
+
"inline-flex items-center gap-0.5 rounded-lg border border-border bg-card/70 p-0.5 shadow-sm",
|
|
4763
|
+
className
|
|
4764
|
+
),
|
|
4765
|
+
role: "radiogroup",
|
|
4766
|
+
"aria-label": "Theme",
|
|
4767
|
+
children: OPTIONS.map(({ value, icon: Icon2, label }) => {
|
|
4768
|
+
const active = theme === value;
|
|
4769
|
+
return /* @__PURE__ */ jsx15(
|
|
4770
|
+
"button",
|
|
4771
|
+
{
|
|
4772
|
+
type: "button",
|
|
4773
|
+
role: "radio",
|
|
4774
|
+
"aria-checked": active,
|
|
4775
|
+
title: `${label} theme`,
|
|
4776
|
+
"aria-label": `${label} theme`,
|
|
4777
|
+
onClick: () => setTheme(value),
|
|
4778
|
+
className: cn(
|
|
4779
|
+
"grid h-7 w-7 place-items-center rounded-md transition-all duration-150",
|
|
4780
|
+
active ? "bg-primary/15 text-primary shadow-[inset_0_0_0_1px_hsl(var(--primary)/0.35)]" : "text-muted-foreground hover:bg-accent hover:text-foreground"
|
|
4781
|
+
),
|
|
4782
|
+
children: /* @__PURE__ */ jsx15(Icon2, { className: "h-3.5 w-3.5", strokeWidth: 2.2 })
|
|
4783
|
+
},
|
|
4784
|
+
value
|
|
4785
|
+
);
|
|
4786
|
+
})
|
|
4787
|
+
}
|
|
4788
|
+
);
|
|
4789
|
+
}
|
|
4790
|
+
|
|
4621
4791
|
// src/components/ToolGroup.tsx
|
|
4622
4792
|
import { CheckCircle2 as CheckCircle23, ChevronDown as ChevronDown5, ChevronRight as ChevronRight3, Loader2 as Loader22, Terminal as Terminal2, XCircle as XCircle3 } from "lucide-react";
|
|
4623
|
-
import { memo as memo4, useState as
|
|
4624
|
-
import { jsx as
|
|
4793
|
+
import { memo as memo4, useState as useState12 } from "react";
|
|
4794
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4625
4795
|
function formatDuration(ms) {
|
|
4626
4796
|
if (ms < 1e3) return `${ms}ms`;
|
|
4627
4797
|
if (ms < 6e4) return `${(ms / 1e3).toFixed(ms < 1e4 ? 2 : 1)}s`;
|
|
@@ -4634,9 +4804,9 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4634
4804
|
defaultOpen = false,
|
|
4635
4805
|
isContinuation = false
|
|
4636
4806
|
}) {
|
|
4637
|
-
const [open, setOpen] =
|
|
4807
|
+
const [open, setOpen] = useState12(defaultOpen);
|
|
4638
4808
|
if (tools.length === 1) {
|
|
4639
|
-
return /* @__PURE__ */
|
|
4809
|
+
return /* @__PURE__ */ jsx16(MessageBubble, { message: tools[0], isFirst: true, isContinuation });
|
|
4640
4810
|
}
|
|
4641
4811
|
const running = tools.filter((t) => t.toolResult === void 0).length;
|
|
4642
4812
|
const errored = tools.filter((t) => t.isError).length;
|
|
@@ -4645,7 +4815,7 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4645
4815
|
const preview = names.slice(0, 3).join(", ");
|
|
4646
4816
|
const more = names.length > 3 ? ` +${names.length - 3}` : "";
|
|
4647
4817
|
return /* @__PURE__ */ jsxs13("div", { className: "flex gap-3 animate-message", children: [
|
|
4648
|
-
isContinuation ? /* @__PURE__ */
|
|
4818
|
+
isContinuation ? /* @__PURE__ */ jsx16("div", { className: "flex-shrink-0 w-8 h-8", "aria-hidden": true }) : /* @__PURE__ */ jsx16("div", { className: "flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center bg-secondary text-secondary-foreground ring-2 ring-offset-2 ring-offset-background ring-secondary/20", children: /* @__PURE__ */ jsx16(Terminal2, { className: "h-4 w-4" }) }),
|
|
4649
4819
|
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1.5 max-w-[85%] flex-1 min-w-0", children: [
|
|
4650
4820
|
/* @__PURE__ */ jsxs13(
|
|
4651
4821
|
"button",
|
|
@@ -4658,15 +4828,15 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4658
4828
|
"border border-border/40 bg-muted/30"
|
|
4659
4829
|
),
|
|
4660
4830
|
children: [
|
|
4661
|
-
open ? /* @__PURE__ */
|
|
4662
|
-
/* @__PURE__ */
|
|
4831
|
+
open ? /* @__PURE__ */ jsx16(ChevronDown5, { className: "h-3.5 w-3.5 text-muted-foreground" }) : /* @__PURE__ */ jsx16(ChevronRight3, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
4832
|
+
/* @__PURE__ */ jsx16(Terminal2, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
4663
4833
|
/* @__PURE__ */ jsxs13("span", { className: "font-mono text-xs", children: [
|
|
4664
4834
|
tools.length,
|
|
4665
4835
|
" tool call",
|
|
4666
4836
|
tools.length === 1 ? "" : "s"
|
|
4667
4837
|
] }),
|
|
4668
|
-
running > 0 ? /* @__PURE__ */
|
|
4669
|
-
totalMs > 0 && /* @__PURE__ */
|
|
4838
|
+
running > 0 ? /* @__PURE__ */ jsx16(Loader22, { className: "h-3 w-3 animate-spin text-amber-500" }) : errored > 0 ? /* @__PURE__ */ jsx16(XCircle3, { className: "h-3 w-3 text-destructive" }) : /* @__PURE__ */ jsx16(CheckCircle23, { className: "h-3 w-3 text-green-500" }),
|
|
4839
|
+
totalMs > 0 && /* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground tabular-nums font-normal", children: formatDuration(totalMs) }),
|
|
4670
4840
|
preview && /* @__PURE__ */ jsxs13("span", { className: "text-xs text-muted-foreground/80 font-mono truncate", children: [
|
|
4671
4841
|
"\xB7 ",
|
|
4672
4842
|
preview,
|
|
@@ -4675,7 +4845,7 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4675
4845
|
]
|
|
4676
4846
|
}
|
|
4677
4847
|
),
|
|
4678
|
-
open && /* @__PURE__ */
|
|
4848
|
+
open && /* @__PURE__ */ jsx16("div", { className: "space-y-2 pl-3 border-l-2 border-border/40 ml-2", children: tools.map((tool) => /* @__PURE__ */ jsx16(MessageBubble, { message: tool, isFirst: false }, tool.id)) })
|
|
4679
4849
|
] })
|
|
4680
4850
|
] });
|
|
4681
4851
|
});
|
|
@@ -4693,8 +4863,8 @@ import {
|
|
|
4693
4863
|
Wrench as Wrench2,
|
|
4694
4864
|
Zap
|
|
4695
4865
|
} from "lucide-react";
|
|
4696
|
-
import { useEffect as
|
|
4697
|
-
import { Fragment as Fragment5, jsx as
|
|
4866
|
+
import { useEffect as useEffect12, useState as useState13 } from "react";
|
|
4867
|
+
import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4698
4868
|
var CARDS = [
|
|
4699
4869
|
{
|
|
4700
4870
|
icon: Search3,
|
|
@@ -4768,8 +4938,8 @@ function WelcomeScreen() {
|
|
|
4768
4938
|
const wsConnected = useConfigStore((s) => s.wsConnected);
|
|
4769
4939
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
4770
4940
|
const setCurrentView = useUIStore((s) => s.setCurrentView);
|
|
4771
|
-
const [savedCount, setSavedCount] =
|
|
4772
|
-
|
|
4941
|
+
const [savedCount, setSavedCount] = useState13(void 0);
|
|
4942
|
+
useEffect12(() => {
|
|
4773
4943
|
if (!wsConnected) return;
|
|
4774
4944
|
const client2 = getWSClient(wsUrl);
|
|
4775
4945
|
const off = client2.on("providers.saved", (msg) => {
|
|
@@ -4785,7 +4955,7 @@ function WelcomeScreen() {
|
|
|
4785
4955
|
const recentPrompts = promptHistory.slice(0, 6);
|
|
4786
4956
|
const { listSessions, resumeSession } = useWebSocket();
|
|
4787
4957
|
const historyEntries = useHistoryStore((s) => s.entries);
|
|
4788
|
-
|
|
4958
|
+
useEffect12(() => {
|
|
4789
4959
|
if (wsConnected && historyEntries.length === 0) listSessions(10);
|
|
4790
4960
|
}, [wsConnected]);
|
|
4791
4961
|
const sessionNicknames = useUIStore((s) => s.sessionNicknames);
|
|
@@ -4793,21 +4963,21 @@ function WelcomeScreen() {
|
|
|
4793
4963
|
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-8 py-8 px-2 max-w-5xl mx-auto w-full", children: [
|
|
4794
4964
|
/* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center text-center gap-3", children: [
|
|
4795
4965
|
/* @__PURE__ */ jsxs14("div", { className: "relative", children: [
|
|
4796
|
-
/* @__PURE__ */
|
|
4797
|
-
/* @__PURE__ */
|
|
4966
|
+
/* @__PURE__ */ jsx17("div", { className: "w-14 h-14 rounded-2xl bg-gradient-to-br from-primary via-primary to-primary/60 flex items-center justify-center shadow-lg shadow-primary/20", children: /* @__PURE__ */ jsx17(Zap, { className: "h-7 w-7 text-primary-foreground" }) }),
|
|
4967
|
+
/* @__PURE__ */ jsx17("div", { className: "absolute -inset-3 bg-gradient-to-r from-transparent via-primary/10 to-transparent animate-pulse rounded-full -z-10" })
|
|
4798
4968
|
] }),
|
|
4799
4969
|
/* @__PURE__ */ jsxs14("div", { children: [
|
|
4800
4970
|
/* @__PURE__ */ jsxs14("h2", { className: "text-2xl font-semibold tracking-tight", children: [
|
|
4801
4971
|
"Where do you want to start",
|
|
4802
4972
|
projectName ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
4803
4973
|
" in ",
|
|
4804
|
-
/* @__PURE__ */
|
|
4974
|
+
/* @__PURE__ */ jsx17("span", { className: "text-primary", children: projectName })
|
|
4805
4975
|
] }) : "",
|
|
4806
4976
|
"?"
|
|
4807
4977
|
] }),
|
|
4808
4978
|
/* @__PURE__ */ jsxs14("p", { className: "text-sm text-muted-foreground mt-2 max-w-2xl mx-auto leading-relaxed", children: [
|
|
4809
4979
|
"WrongStack is connected to your project and ready to read, edit, run commands, search the codebase, track todos, and remember context across sessions. Pick a starting prompt below, write your own, or type ",
|
|
4810
|
-
/* @__PURE__ */
|
|
4980
|
+
/* @__PURE__ */ jsx17("span", { className: "font-mono text-foreground/80", children: "/" }),
|
|
4811
4981
|
" ",
|
|
4812
4982
|
"for the full command palette."
|
|
4813
4983
|
] }),
|
|
@@ -4829,19 +4999,19 @@ function WelcomeScreen() {
|
|
|
4829
4999
|
"p-4 flex items-center gap-4 text-left"
|
|
4830
5000
|
),
|
|
4831
5001
|
children: [
|
|
4832
|
-
/* @__PURE__ */
|
|
5002
|
+
/* @__PURE__ */ jsx17("span", { className: "flex items-center justify-center w-12 h-12 rounded-lg bg-amber-500/15 text-amber-600 dark:text-amber-400 shrink-0", children: /* @__PURE__ */ jsx17(KeyRound, { className: "h-6 w-6" }) }),
|
|
4833
5003
|
/* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
|
|
4834
|
-
/* @__PURE__ */
|
|
4835
|
-
/* @__PURE__ */
|
|
5004
|
+
/* @__PURE__ */ jsx17("h3", { className: "text-base font-semibold mb-1", children: "No API key configured yet" }),
|
|
5005
|
+
/* @__PURE__ */ jsx17("p", { className: "text-sm text-muted-foreground leading-relaxed", children: "Register a provider in Settings before sending a message \u2014 otherwise the agent has nothing to talk to. Anthropic, OpenAI, Google, and any OpenAI-compatible endpoint all work." })
|
|
4836
5006
|
] }),
|
|
4837
5007
|
/* @__PURE__ */ jsxs14("span", { className: "flex items-center gap-1 text-xs text-amber-600 dark:text-amber-400 font-medium shrink-0 group-hover:translate-x-0.5 transition-transform", children: [
|
|
4838
5008
|
"Open Settings ",
|
|
4839
|
-
/* @__PURE__ */
|
|
5009
|
+
/* @__PURE__ */ jsx17(ArrowRight, { className: "h-3.5 w-3.5" })
|
|
4840
5010
|
] })
|
|
4841
5011
|
]
|
|
4842
5012
|
}
|
|
4843
5013
|
),
|
|
4844
|
-
/* @__PURE__ */
|
|
5014
|
+
/* @__PURE__ */ jsx17("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-4", children: CARDS.map((card) => {
|
|
4845
5015
|
const Icon2 = card.icon;
|
|
4846
5016
|
return /* @__PURE__ */ jsxs14(
|
|
4847
5017
|
"div",
|
|
@@ -4849,22 +5019,22 @@ function WelcomeScreen() {
|
|
|
4849
5019
|
className: "rounded-xl border bg-card/40 backdrop-blur-sm p-4 flex flex-col gap-3",
|
|
4850
5020
|
children: [
|
|
4851
5021
|
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4852
|
-
/* @__PURE__ */
|
|
5022
|
+
/* @__PURE__ */ jsx17(
|
|
4853
5023
|
"span",
|
|
4854
5024
|
{
|
|
4855
5025
|
className: cn(
|
|
4856
5026
|
"flex items-center justify-center w-8 h-8 rounded-lg border",
|
|
4857
5027
|
card.tone
|
|
4858
5028
|
),
|
|
4859
|
-
children: /* @__PURE__ */
|
|
5029
|
+
children: /* @__PURE__ */ jsx17(Icon2, { className: "h-4 w-4" })
|
|
4860
5030
|
}
|
|
4861
5031
|
),
|
|
4862
5032
|
/* @__PURE__ */ jsxs14("div", { children: [
|
|
4863
|
-
/* @__PURE__ */
|
|
4864
|
-
/* @__PURE__ */
|
|
5033
|
+
/* @__PURE__ */ jsx17("h3", { className: "text-sm font-semibold", children: card.title }),
|
|
5034
|
+
/* @__PURE__ */ jsx17("p", { className: "text-xs text-muted-foreground", children: card.hint })
|
|
4865
5035
|
] })
|
|
4866
5036
|
] }),
|
|
4867
|
-
/* @__PURE__ */
|
|
5037
|
+
/* @__PURE__ */ jsx17("div", { className: "flex flex-col gap-1.5", children: card.prompts.map((p, i) => /* @__PURE__ */ jsx17(
|
|
4868
5038
|
"button",
|
|
4869
5039
|
{
|
|
4870
5040
|
type: "button",
|
|
@@ -4882,10 +5052,10 @@ function WelcomeScreen() {
|
|
|
4882
5052
|
}) }),
|
|
4883
5053
|
recentSessions.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "rounded-xl border bg-muted/20 p-4", children: [
|
|
4884
5054
|
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
4885
|
-
/* @__PURE__ */
|
|
4886
|
-
/* @__PURE__ */
|
|
5055
|
+
/* @__PURE__ */ jsx17(ArchiveRestore2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
5056
|
+
/* @__PURE__ */ jsx17("span", { className: "text-xs uppercase tracking-wider text-muted-foreground font-medium", children: "Pick back up" })
|
|
4887
5057
|
] }),
|
|
4888
|
-
/* @__PURE__ */
|
|
5058
|
+
/* @__PURE__ */ jsx17("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-2", children: recentSessions.map((entry) => /* @__PURE__ */ jsxs14(
|
|
4889
5059
|
"button",
|
|
4890
5060
|
{
|
|
4891
5061
|
type: "button",
|
|
@@ -4893,7 +5063,7 @@ function WelcomeScreen() {
|
|
|
4893
5063
|
className: "text-left rounded-lg border border-border/40 bg-background/60 hover:border-primary/40 hover:bg-accent/30 px-3 py-2 transition-colors group/sess",
|
|
4894
5064
|
title: entry.title,
|
|
4895
5065
|
children: [
|
|
4896
|
-
/* @__PURE__ */
|
|
5066
|
+
/* @__PURE__ */ jsx17("div", { className: "text-sm font-medium truncate text-foreground group-hover/sess:text-primary", children: sessionNicknames[entry.id] || entry.title || "(empty)" }),
|
|
4897
5067
|
/* @__PURE__ */ jsxs14("div", { className: "text-[10px] text-muted-foreground font-mono truncate mt-0.5", children: [
|
|
4898
5068
|
entry.provider,
|
|
4899
5069
|
"/",
|
|
@@ -4911,10 +5081,10 @@ function WelcomeScreen() {
|
|
|
4911
5081
|
] }),
|
|
4912
5082
|
recentPrompts.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "rounded-xl border bg-muted/20 p-4", children: [
|
|
4913
5083
|
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
4914
|
-
/* @__PURE__ */
|
|
4915
|
-
/* @__PURE__ */
|
|
5084
|
+
/* @__PURE__ */ jsx17(Clock2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
5085
|
+
/* @__PURE__ */ jsx17("span", { className: "text-xs uppercase tracking-wider text-muted-foreground font-medium", children: "Recent prompts" })
|
|
4916
5086
|
] }),
|
|
4917
|
-
/* @__PURE__ */
|
|
5087
|
+
/* @__PURE__ */ jsx17("div", { className: "flex flex-col gap-1.5", children: recentPrompts.filter((p) => !p.startsWith("/")).slice(0, 5).map((p, i) => /* @__PURE__ */ jsx17(
|
|
4918
5088
|
"button",
|
|
4919
5089
|
{
|
|
4920
5090
|
type: "button",
|
|
@@ -4928,18 +5098,18 @@ function WelcomeScreen() {
|
|
|
4928
5098
|
] }),
|
|
4929
5099
|
/* @__PURE__ */ jsxs14("div", { className: "rounded-xl border bg-muted/20 p-4", children: [
|
|
4930
5100
|
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
4931
|
-
/* @__PURE__ */
|
|
4932
|
-
/* @__PURE__ */
|
|
5101
|
+
/* @__PURE__ */ jsx17(Keyboard, { className: "h-4 w-4 text-muted-foreground" }),
|
|
5102
|
+
/* @__PURE__ */ jsx17("span", { className: "text-xs uppercase tracking-wider text-muted-foreground font-medium", children: "Quick commands" })
|
|
4933
5103
|
] }),
|
|
4934
|
-
/* @__PURE__ */
|
|
5104
|
+
/* @__PURE__ */ jsx17("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-2", children: SLASH_REFS.map((c) => /* @__PURE__ */ jsxs14(
|
|
4935
5105
|
"button",
|
|
4936
5106
|
{
|
|
4937
5107
|
type: "button",
|
|
4938
5108
|
onClick: () => fillTextarea(c.name),
|
|
4939
5109
|
className: "text-left flex flex-col gap-0.5 rounded-md border border-border/40 bg-background/60 px-3 py-2 hover:border-primary/40 hover:bg-accent/40 transition-colors",
|
|
4940
5110
|
children: [
|
|
4941
|
-
/* @__PURE__ */
|
|
4942
|
-
/* @__PURE__ */
|
|
5111
|
+
/* @__PURE__ */ jsx17("span", { className: "font-mono text-xs text-foreground", children: c.name }),
|
|
5112
|
+
/* @__PURE__ */ jsx17("span", { className: "text-[11px] text-muted-foreground truncate", children: c.hint })
|
|
4943
5113
|
]
|
|
4944
5114
|
},
|
|
4945
5115
|
c.name
|
|
@@ -4951,7 +5121,7 @@ function WelcomeScreen() {
|
|
|
4951
5121
|
// src/components/ui/scroll-area.tsx
|
|
4952
5122
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
4953
5123
|
import * as React2 from "react";
|
|
4954
|
-
import { jsx as
|
|
5124
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4955
5125
|
var ScrollArea = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs15(
|
|
4956
5126
|
ScrollAreaPrimitive.Root,
|
|
4957
5127
|
{
|
|
@@ -4959,14 +5129,14 @@ var ScrollArea = React2.forwardRef(({ className, children, ...props }, ref) => /
|
|
|
4959
5129
|
className: cn("relative overflow-hidden", className),
|
|
4960
5130
|
...props,
|
|
4961
5131
|
children: [
|
|
4962
|
-
/* @__PURE__ */
|
|
4963
|
-
/* @__PURE__ */
|
|
4964
|
-
/* @__PURE__ */
|
|
5132
|
+
/* @__PURE__ */ jsx18(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
|
|
5133
|
+
/* @__PURE__ */ jsx18(ScrollBar, {}),
|
|
5134
|
+
/* @__PURE__ */ jsx18(ScrollAreaPrimitive.Corner, {})
|
|
4965
5135
|
]
|
|
4966
5136
|
}
|
|
4967
5137
|
));
|
|
4968
5138
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
4969
|
-
var ScrollBar = React2.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */
|
|
5139
|
+
var ScrollBar = React2.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx18(
|
|
4970
5140
|
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
4971
5141
|
{
|
|
4972
5142
|
ref,
|
|
@@ -4978,13 +5148,13 @@ var ScrollBar = React2.forwardRef(({ className, orientation = "vertical", ...pro
|
|
|
4978
5148
|
className
|
|
4979
5149
|
),
|
|
4980
5150
|
...props,
|
|
4981
|
-
children: /* @__PURE__ */
|
|
5151
|
+
children: /* @__PURE__ */ jsx18(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-border" })
|
|
4982
5152
|
}
|
|
4983
5153
|
));
|
|
4984
5154
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
4985
5155
|
|
|
4986
5156
|
// src/components/ChatView.tsx
|
|
4987
|
-
import { Fragment as Fragment6, jsx as
|
|
5157
|
+
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4988
5158
|
function fmtTok(n) {
|
|
4989
5159
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
4990
5160
|
if (n >= 1e3) return `${(n / 1e3).toFixed(n >= 1e4 ? 0 : 1)}k`;
|
|
@@ -4996,10 +5166,10 @@ function ThinkingBubble() {
|
|
|
4996
5166
|
const tailLines = buf.split("\n").slice(-6);
|
|
4997
5167
|
const tail = tailLines.join("\n").trim();
|
|
4998
5168
|
return /* @__PURE__ */ jsxs16("div", { className: "flex gap-3 animate-message", children: [
|
|
4999
|
-
/* @__PURE__ */
|
|
5169
|
+
/* @__PURE__ */ jsx19("div", { className: "flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center bg-violet-500/10 text-violet-600 dark:text-violet-400 ring-2 ring-offset-2 ring-offset-background ring-violet-500/20", children: /* @__PURE__ */ jsx19(Brain2, { className: "h-4 w-4 animate-pulse" }) }),
|
|
5000
5170
|
/* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1 max-w-[85%] min-w-0", children: [
|
|
5001
|
-
/* @__PURE__ */
|
|
5002
|
-
/* @__PURE__ */
|
|
5171
|
+
/* @__PURE__ */ jsx19("span", { className: "text-xs font-medium text-violet-600 dark:text-violet-400 px-1", children: "Thinking\u2026" }),
|
|
5172
|
+
/* @__PURE__ */ jsx19("div", { className: "rounded-2xl rounded-bl-md px-3 py-2 bg-violet-500/[0.04] border border-violet-500/20 text-foreground/80", children: /* @__PURE__ */ jsx19("pre", { className: "whitespace-pre-wrap break-words font-sans text-xs leading-relaxed italic max-h-32 overflow-hidden", children: tail || "\u2026" }) })
|
|
5003
5173
|
] })
|
|
5004
5174
|
] });
|
|
5005
5175
|
}
|
|
@@ -5010,22 +5180,20 @@ function ChatView() {
|
|
|
5010
5180
|
const sidebarOpen = useUIStore((s) => s.sidebarOpen);
|
|
5011
5181
|
const toggleSidebar = useUIStore((s) => s.toggleSidebar);
|
|
5012
5182
|
const compactMode = useUIStore((s) => s.compactMode);
|
|
5013
|
-
const setTheme = useConfigStore((s) => s.setTheme);
|
|
5014
|
-
const theme = useConfigStore((s) => s.theme);
|
|
5015
5183
|
const { totalTokens, startTime, lastInputTokens, maxContext, projectName, iteration } = useSessionStore();
|
|
5016
5184
|
const { wsConnected, wsStatus, provider, model } = useConfigStore();
|
|
5017
5185
|
const { setCurrentView } = useUIStore();
|
|
5018
5186
|
const scrollRef = useRef9(null);
|
|
5019
5187
|
const ctxPct = maxContext > 0 && lastInputTokens > 0 ? Math.min(100, Math.round(lastInputTokens / maxContext * 100)) : 0;
|
|
5020
5188
|
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";
|
|
5021
|
-
const [pinnedToBottom, setPinnedToBottom] =
|
|
5022
|
-
const [unreadCount, setUnreadCount] =
|
|
5023
|
-
const [scrolledDeep, setScrolledDeep] =
|
|
5189
|
+
const [pinnedToBottom, setPinnedToBottom] = useState14(true);
|
|
5190
|
+
const [unreadCount, setUnreadCount] = useState14(0);
|
|
5191
|
+
const [scrolledDeep, setScrolledDeep] = useState14(false);
|
|
5024
5192
|
const lastSeenCount = useRef9(messages.length);
|
|
5025
5193
|
const getViewport = useCallback3(() => {
|
|
5026
5194
|
return scrollRef.current?.querySelector("[data-radix-scroll-area-viewport]") ?? null;
|
|
5027
5195
|
}, []);
|
|
5028
|
-
|
|
5196
|
+
useEffect13(() => {
|
|
5029
5197
|
const viewport = getViewport();
|
|
5030
5198
|
if (!viewport) return;
|
|
5031
5199
|
const onScroll = () => {
|
|
@@ -5042,7 +5210,7 @@ function ChatView() {
|
|
|
5042
5210
|
viewport.addEventListener("scroll", onScroll, { passive: true });
|
|
5043
5211
|
return () => viewport.removeEventListener("scroll", onScroll);
|
|
5044
5212
|
}, [getViewport, messages.length]);
|
|
5045
|
-
|
|
5213
|
+
useEffect13(() => {
|
|
5046
5214
|
const viewport = getViewport();
|
|
5047
5215
|
if (!viewport) return;
|
|
5048
5216
|
if (pinnedToBottom) {
|
|
@@ -5066,14 +5234,14 @@ function ChatView() {
|
|
|
5066
5234
|
if (!viewport) return;
|
|
5067
5235
|
viewport.scrollTo({ top: 0, behavior: "smooth" });
|
|
5068
5236
|
}, [getViewport]);
|
|
5069
|
-
const [runStartedAt, setRunStartedAt] =
|
|
5070
|
-
const [nowTick, setNowTick] =
|
|
5237
|
+
const [runStartedAt, setRunStartedAt] = useState14(null);
|
|
5238
|
+
const [nowTick, setNowTick] = useState14(() => Date.now());
|
|
5071
5239
|
const streamAnchor = useRef9(null);
|
|
5072
|
-
|
|
5240
|
+
useEffect13(() => {
|
|
5073
5241
|
if (isLoading && runStartedAt === null) setRunStartedAt(Date.now());
|
|
5074
5242
|
if (!isLoading && runStartedAt !== null) setRunStartedAt(null);
|
|
5075
5243
|
}, [isLoading, runStartedAt]);
|
|
5076
|
-
|
|
5244
|
+
useEffect13(() => {
|
|
5077
5245
|
if (!isLoading) return;
|
|
5078
5246
|
const t = setInterval(() => setNowTick(Date.now()), 500);
|
|
5079
5247
|
return () => clearInterval(t);
|
|
@@ -5098,7 +5266,7 @@ function ChatView() {
|
|
|
5098
5266
|
/* @__PURE__ */ jsxs16("header", { className: "flex flex-col border-b bg-card shrink-0", children: [
|
|
5099
5267
|
/* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between gap-2 px-3 py-2", children: [
|
|
5100
5268
|
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1.5 min-w-0 flex-1", children: [
|
|
5101
|
-
!sidebarOpen && /* @__PURE__ */
|
|
5269
|
+
!sidebarOpen && /* @__PURE__ */ jsx19(
|
|
5102
5270
|
Button,
|
|
5103
5271
|
{
|
|
5104
5272
|
variant: "ghost",
|
|
@@ -5106,11 +5274,11 @@ function ChatView() {
|
|
|
5106
5274
|
className: "h-7 w-7 shrink-0",
|
|
5107
5275
|
onClick: toggleSidebar,
|
|
5108
5276
|
title: "Open sidebar (Ctrl+\\\\)",
|
|
5109
|
-
children: /* @__PURE__ */
|
|
5277
|
+
children: /* @__PURE__ */ jsx19(PanelLeftOpen, { className: "h-4 w-4" })
|
|
5110
5278
|
}
|
|
5111
5279
|
),
|
|
5112
|
-
!sidebarOpen && /* @__PURE__ */
|
|
5113
|
-
/* @__PURE__ */
|
|
5280
|
+
!sidebarOpen && /* @__PURE__ */ jsx19("div", { className: "flex items-center gap-1.5 shrink-0 mr-1", children: /* @__PURE__ */ jsx19("div", { className: "w-5 h-5 rounded bg-primary flex items-center justify-center", children: /* @__PURE__ */ jsx19(Zap2, { className: "h-3 w-3 text-primary-foreground" }) }) }),
|
|
5281
|
+
/* @__PURE__ */ jsx19(ConnectionChip, { wsStatus, wsConnected }),
|
|
5114
5282
|
/* @__PURE__ */ jsxs16(
|
|
5115
5283
|
"span",
|
|
5116
5284
|
{
|
|
@@ -5120,8 +5288,8 @@ function ChatView() {
|
|
|
5120
5288
|
),
|
|
5121
5289
|
title: `Agent state: ${agentState}`,
|
|
5122
5290
|
children: [
|
|
5123
|
-
agentState !== "idle" && /* @__PURE__ */
|
|
5124
|
-
/* @__PURE__ */
|
|
5291
|
+
agentState !== "idle" && /* @__PURE__ */ jsx19("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-pulse" }),
|
|
5292
|
+
/* @__PURE__ */ jsx19("span", { children: agentState })
|
|
5125
5293
|
]
|
|
5126
5294
|
}
|
|
5127
5295
|
),
|
|
@@ -5131,8 +5299,8 @@ function ChatView() {
|
|
|
5131
5299
|
className: "flex items-center gap-1 text-[11px] text-muted-foreground shrink-0 min-w-0",
|
|
5132
5300
|
title: `Project: ${projectName}`,
|
|
5133
5301
|
children: [
|
|
5134
|
-
/* @__PURE__ */
|
|
5135
|
-
/* @__PURE__ */
|
|
5302
|
+
/* @__PURE__ */ jsx19(FolderOpen, { className: "h-3 w-3 shrink-0" }),
|
|
5303
|
+
/* @__PURE__ */ jsx19("span", { className: "truncate max-w-[12rem]", children: projectName })
|
|
5136
5304
|
]
|
|
5137
5305
|
}
|
|
5138
5306
|
),
|
|
@@ -5144,24 +5312,24 @@ function ChatView() {
|
|
|
5144
5312
|
className: "group flex items-center gap-1 px-2 py-0.5 rounded-md border bg-background/50 hover:bg-accent hover:border-primary/40 transition-colors text-[11px] min-w-0 shrink-0",
|
|
5145
5313
|
title: "Change provider / model (Ctrl+M)",
|
|
5146
5314
|
children: [
|
|
5147
|
-
/* @__PURE__ */
|
|
5315
|
+
/* @__PURE__ */ jsx19(Cpu2, { className: "h-3 w-3 text-muted-foreground group-hover:text-foreground shrink-0" }),
|
|
5148
5316
|
/* @__PURE__ */ jsxs16("span", { className: "font-mono truncate max-w-[16rem]", children: [
|
|
5149
|
-
/* @__PURE__ */
|
|
5150
|
-
/* @__PURE__ */
|
|
5151
|
-
/* @__PURE__ */
|
|
5317
|
+
/* @__PURE__ */ jsx19("span", { className: "text-muted-foreground", children: provider || "no-provider" }),
|
|
5318
|
+
/* @__PURE__ */ jsx19("span", { className: "text-muted-foreground/40 mx-0.5", children: "/" }),
|
|
5319
|
+
/* @__PURE__ */ jsx19("span", { className: "font-medium", children: model || "no-model" })
|
|
5152
5320
|
] })
|
|
5153
5321
|
]
|
|
5154
5322
|
}
|
|
5155
5323
|
),
|
|
5156
|
-
/* @__PURE__ */
|
|
5157
|
-
/* @__PURE__ */
|
|
5324
|
+
/* @__PURE__ */ jsx19(ModePicker, {}),
|
|
5325
|
+
/* @__PURE__ */ jsx19(ContextModePicker, {}),
|
|
5158
5326
|
iteration && /* @__PURE__ */ jsxs16(
|
|
5159
5327
|
"span",
|
|
5160
5328
|
{
|
|
5161
5329
|
className: "flex items-center gap-1 px-1.5 py-0.5 rounded-full text-[11px] font-medium bg-primary/10 text-primary shrink-0",
|
|
5162
5330
|
title: "Agent iteration",
|
|
5163
5331
|
children: [
|
|
5164
|
-
/* @__PURE__ */
|
|
5332
|
+
/* @__PURE__ */ jsx19(Activity, { className: "h-3 w-3 animate-pulse" }),
|
|
5165
5333
|
"iter ",
|
|
5166
5334
|
iteration.index,
|
|
5167
5335
|
iteration.max > 0 ? `/${iteration.max}` : ""
|
|
@@ -5170,7 +5338,7 @@ function ChatView() {
|
|
|
5170
5338
|
)
|
|
5171
5339
|
] }),
|
|
5172
5340
|
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-0.5 shrink-0", children: [
|
|
5173
|
-
/* @__PURE__ */
|
|
5341
|
+
/* @__PURE__ */ jsx19(
|
|
5174
5342
|
Button,
|
|
5175
5343
|
{
|
|
5176
5344
|
variant: "ghost",
|
|
@@ -5178,24 +5346,11 @@ function ChatView() {
|
|
|
5178
5346
|
className: "h-7 w-7",
|
|
5179
5347
|
onClick: () => setPaletteOpen(true),
|
|
5180
5348
|
title: "Command palette (Ctrl+K)",
|
|
5181
|
-
children: /* @__PURE__ */
|
|
5349
|
+
children: /* @__PURE__ */ jsx19(Command, { className: "h-4 w-4" })
|
|
5182
5350
|
}
|
|
5183
5351
|
),
|
|
5184
|
-
/* @__PURE__ */
|
|
5185
|
-
|
|
5186
|
-
{
|
|
5187
|
-
variant: "ghost",
|
|
5188
|
-
size: "icon",
|
|
5189
|
-
className: "h-7 w-7",
|
|
5190
|
-
onClick: () => {
|
|
5191
|
-
const next = theme === "light" ? "dark" : theme === "dark" ? "system" : "light";
|
|
5192
|
-
setTheme(next);
|
|
5193
|
-
},
|
|
5194
|
-
title: `Theme: ${theme} (click to cycle)`,
|
|
5195
|
-
children: theme === "light" ? /* @__PURE__ */ jsx17(Sun2, { className: "h-4 w-4" }) : theme === "dark" ? /* @__PURE__ */ jsx17(Moon2, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx17(Monitor2, { className: "h-4 w-4" })
|
|
5196
|
-
}
|
|
5197
|
-
),
|
|
5198
|
-
/* @__PURE__ */ jsx17(
|
|
5352
|
+
/* @__PURE__ */ jsx19(ThemeToggle, { className: "mx-0.5" }),
|
|
5353
|
+
/* @__PURE__ */ jsx19(
|
|
5199
5354
|
Button,
|
|
5200
5355
|
{
|
|
5201
5356
|
variant: "ghost",
|
|
@@ -5206,7 +5361,7 @@ function ChatView() {
|
|
|
5206
5361
|
children: "?"
|
|
5207
5362
|
}
|
|
5208
5363
|
),
|
|
5209
|
-
/* @__PURE__ */
|
|
5364
|
+
/* @__PURE__ */ jsx19(
|
|
5210
5365
|
Button,
|
|
5211
5366
|
{
|
|
5212
5367
|
variant: "ghost",
|
|
@@ -5214,7 +5369,7 @@ function ChatView() {
|
|
|
5214
5369
|
className: "h-7 w-7",
|
|
5215
5370
|
onClick: () => setCurrentView("settings"),
|
|
5216
5371
|
title: "Settings",
|
|
5217
|
-
children: /* @__PURE__ */
|
|
5372
|
+
children: /* @__PURE__ */ jsx19(Settings, { className: "h-4 w-4" })
|
|
5218
5373
|
}
|
|
5219
5374
|
)
|
|
5220
5375
|
] })
|
|
@@ -5241,12 +5396,12 @@ function ChatView() {
|
|
|
5241
5396
|
),
|
|
5242
5397
|
totalTokens.input > 0 && /* @__PURE__ */ jsxs16(Fragment6, { children: [
|
|
5243
5398
|
/* @__PURE__ */ jsxs16("span", { className: "flex items-center gap-1", children: [
|
|
5244
|
-
/* @__PURE__ */
|
|
5245
|
-
/* @__PURE__ */
|
|
5399
|
+
/* @__PURE__ */ jsx19("span", { className: "font-medium text-foreground", children: fmtTok(totalTokens.input) }),
|
|
5400
|
+
/* @__PURE__ */ jsx19("span", { children: "in" })
|
|
5246
5401
|
] }),
|
|
5247
5402
|
/* @__PURE__ */ jsxs16("span", { className: "flex items-center gap-1", children: [
|
|
5248
|
-
/* @__PURE__ */
|
|
5249
|
-
/* @__PURE__ */
|
|
5403
|
+
/* @__PURE__ */ jsx19("span", { className: "font-medium text-foreground", children: fmtTok(totalTokens.output) }),
|
|
5404
|
+
/* @__PURE__ */ jsx19("span", { children: "out" })
|
|
5250
5405
|
] }),
|
|
5251
5406
|
totalTokens.cacheRead && totalTokens.cacheRead > 0 && (() => {
|
|
5252
5407
|
const denom = (totalTokens.cacheRead ?? 0) + totalTokens.input;
|
|
@@ -5257,7 +5412,7 @@ function ChatView() {
|
|
|
5257
5412
|
className: "flex items-center gap-1",
|
|
5258
5413
|
title: `Cache hit ratio: ${pct}%`,
|
|
5259
5414
|
children: [
|
|
5260
|
-
/* @__PURE__ */
|
|
5415
|
+
/* @__PURE__ */ jsx19("span", { className: "font-medium text-foreground", children: fmtTok(totalTokens.cacheRead) }),
|
|
5261
5416
|
/* @__PURE__ */ jsxs16("span", { children: [
|
|
5262
5417
|
"cache (",
|
|
5263
5418
|
pct,
|
|
@@ -5267,14 +5422,14 @@ function ChatView() {
|
|
|
5267
5422
|
}
|
|
5268
5423
|
);
|
|
5269
5424
|
})(),
|
|
5270
|
-
/* @__PURE__ */
|
|
5425
|
+
/* @__PURE__ */ jsx19(CostChip, {})
|
|
5271
5426
|
] })
|
|
5272
5427
|
] }),
|
|
5273
|
-
startTime && /* @__PURE__ */
|
|
5428
|
+
startTime && /* @__PURE__ */ jsx19("span", { className: "text-muted-foreground/70 tabular-nums shrink-0", children: formatDuration2(startTime) })
|
|
5274
5429
|
] })
|
|
5275
5430
|
] }),
|
|
5276
5431
|
/* @__PURE__ */ jsxs16("div", { className: "flex-1 relative overflow-hidden", children: [
|
|
5277
|
-
/* @__PURE__ */
|
|
5432
|
+
/* @__PURE__ */ jsx19(SearchOverlay, {}),
|
|
5278
5433
|
!pinnedToBottom && /* @__PURE__ */ jsxs16(
|
|
5279
5434
|
"button",
|
|
5280
5435
|
{
|
|
@@ -5287,7 +5442,7 @@ function ChatView() {
|
|
|
5287
5442
|
"hover:bg-primary/90 transition-colors animate-message"
|
|
5288
5443
|
),
|
|
5289
5444
|
children: [
|
|
5290
|
-
/* @__PURE__ */
|
|
5445
|
+
/* @__PURE__ */ jsx19(ArrowDown2, { className: "h-3.5 w-3.5" }),
|
|
5291
5446
|
unreadCount > 0 ? `${unreadCount} new message${unreadCount === 1 ? "" : "s"}` : "Jump to latest"
|
|
5292
5447
|
]
|
|
5293
5448
|
}
|
|
@@ -5305,12 +5460,12 @@ function ChatView() {
|
|
|
5305
5460
|
"hover:text-foreground hover:bg-background transition-colors animate-message"
|
|
5306
5461
|
),
|
|
5307
5462
|
children: [
|
|
5308
|
-
/* @__PURE__ */
|
|
5309
|
-
/* @__PURE__ */
|
|
5463
|
+
/* @__PURE__ */ jsx19(ArrowUp2, { className: "h-3 w-3" }),
|
|
5464
|
+
/* @__PURE__ */ jsx19("span", { children: "Top" })
|
|
5310
5465
|
]
|
|
5311
5466
|
}
|
|
5312
5467
|
),
|
|
5313
|
-
/* @__PURE__ */
|
|
5468
|
+
/* @__PURE__ */ jsx19(ScrollArea, { className: "h-full", ref: scrollRef, children: /* @__PURE__ */ jsxs16(
|
|
5314
5469
|
"div",
|
|
5315
5470
|
{
|
|
5316
5471
|
className: cn(
|
|
@@ -5318,7 +5473,7 @@ function ChatView() {
|
|
|
5318
5473
|
compactMode ? "max-w-5xl p-3 space-y-3" : "max-w-5xl p-4 space-y-6"
|
|
5319
5474
|
),
|
|
5320
5475
|
children: [
|
|
5321
|
-
messages.length === 0 && !isLoading && /* @__PURE__ */
|
|
5476
|
+
messages.length === 0 && !isLoading && /* @__PURE__ */ jsx19(WelcomeScreen, {}),
|
|
5322
5477
|
(() => {
|
|
5323
5478
|
const groups = [];
|
|
5324
5479
|
for (let i = 0; i < messages.length; i++) {
|
|
@@ -5388,9 +5543,9 @@ function ChatView() {
|
|
|
5388
5543
|
{
|
|
5389
5544
|
className: "flex items-center gap-3 py-1 text-[11px] text-muted-foreground/70 uppercase tracking-wider font-medium",
|
|
5390
5545
|
children: [
|
|
5391
|
-
/* @__PURE__ */
|
|
5392
|
-
/* @__PURE__ */
|
|
5393
|
-
/* @__PURE__ */
|
|
5546
|
+
/* @__PURE__ */ jsx19("div", { className: "flex-1 h-px bg-border/50" }),
|
|
5547
|
+
/* @__PURE__ */ jsx19("span", { children: dayLabel(ts) }),
|
|
5548
|
+
/* @__PURE__ */ jsx19("div", { className: "flex-1 h-px bg-border/50" })
|
|
5394
5549
|
]
|
|
5395
5550
|
},
|
|
5396
5551
|
`day-${day}-${idx}`
|
|
@@ -5399,15 +5554,15 @@ function ChatView() {
|
|
|
5399
5554
|
prevDay = day;
|
|
5400
5555
|
}
|
|
5401
5556
|
if (t.kind === "user") {
|
|
5402
|
-
out.push(/* @__PURE__ */
|
|
5557
|
+
out.push(/* @__PURE__ */ jsx19(MessageBubble, { message: t.message, isFirst: true }, t.key));
|
|
5403
5558
|
continue;
|
|
5404
5559
|
}
|
|
5405
5560
|
const isLastTurn = idx === turns.length - 1;
|
|
5406
5561
|
out.push(
|
|
5407
|
-
/* @__PURE__ */
|
|
5562
|
+
/* @__PURE__ */ jsx19("div", { className: cn(compactMode ? "space-y-1" : "space-y-1.5"), children: t.items.map((g, gi) => {
|
|
5408
5563
|
const continuation = gi > 0;
|
|
5409
5564
|
if (g.kind === "msg") {
|
|
5410
|
-
return /* @__PURE__ */
|
|
5565
|
+
return /* @__PURE__ */ jsx19(
|
|
5411
5566
|
MessageBubble,
|
|
5412
5567
|
{
|
|
5413
5568
|
message: g.message,
|
|
@@ -5418,7 +5573,7 @@ function ChatView() {
|
|
|
5418
5573
|
);
|
|
5419
5574
|
}
|
|
5420
5575
|
const isLatestRunning = isLastTurn && gi === t.items.length - 1 && isLoading && g.tools.some((tt) => tt.toolResult === void 0);
|
|
5421
|
-
return /* @__PURE__ */
|
|
5576
|
+
return /* @__PURE__ */ jsx19(
|
|
5422
5577
|
ToolGroup,
|
|
5423
5578
|
{
|
|
5424
5579
|
tools: g.tools,
|
|
@@ -5432,7 +5587,7 @@ function ChatView() {
|
|
|
5432
5587
|
}
|
|
5433
5588
|
return out;
|
|
5434
5589
|
})(),
|
|
5435
|
-
/* @__PURE__ */
|
|
5590
|
+
/* @__PURE__ */ jsx19(ThinkingBubble, {}),
|
|
5436
5591
|
isLoading && (() => {
|
|
5437
5592
|
const last = messages[messages.length - 1];
|
|
5438
5593
|
const runningTools = messages.filter(
|
|
@@ -5475,15 +5630,15 @@ function ChatView() {
|
|
|
5475
5630
|
streamAnchor.current = null;
|
|
5476
5631
|
}
|
|
5477
5632
|
return /* @__PURE__ */ jsxs16("div", { className: "flex gap-3 animate-message", children: [
|
|
5478
|
-
/* @__PURE__ */
|
|
5479
|
-
/* @__PURE__ */
|
|
5633
|
+
/* @__PURE__ */ jsx19("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__ */ jsx19(Bot2, { className: "h-4 w-4" }) }),
|
|
5634
|
+
/* @__PURE__ */ jsx19("div", { className: "flex flex-col gap-1.5", children: /* @__PURE__ */ jsx19("div", { className: "rounded-2xl px-4 py-3 bg-card border text-foreground", children: /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3 text-sm", children: [
|
|
5480
5635
|
/* @__PURE__ */ jsxs16("span", { className: "flex gap-1", children: [
|
|
5481
|
-
/* @__PURE__ */
|
|
5482
|
-
/* @__PURE__ */
|
|
5483
|
-
/* @__PURE__ */
|
|
5636
|
+
/* @__PURE__ */ jsx19("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce [animation-delay:-0.3s]" }),
|
|
5637
|
+
/* @__PURE__ */ jsx19("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce [animation-delay:-0.15s]" }),
|
|
5638
|
+
/* @__PURE__ */ jsx19("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce" })
|
|
5484
5639
|
] }),
|
|
5485
|
-
/* @__PURE__ */
|
|
5486
|
-
/* @__PURE__ */
|
|
5640
|
+
/* @__PURE__ */ jsx19("span", { className: "text-foreground/90", children: label }),
|
|
5641
|
+
/* @__PURE__ */ jsx19("span", { className: "text-xs text-muted-foreground tabular-nums", children: elapsed }),
|
|
5487
5642
|
iteration && /* @__PURE__ */ jsxs16("span", { className: "text-xs text-muted-foreground tabular-nums", children: [
|
|
5488
5643
|
"\xB7 iter ",
|
|
5489
5644
|
iteration.index,
|
|
@@ -5500,27 +5655,27 @@ function ChatView() {
|
|
|
5500
5655
|
}
|
|
5501
5656
|
) })
|
|
5502
5657
|
] }),
|
|
5503
|
-
/* @__PURE__ */
|
|
5504
|
-
/* @__PURE__ */
|
|
5505
|
-
/* @__PURE__ */
|
|
5658
|
+
/* @__PURE__ */ jsx19("div", { className: "border-t bg-card/50 backdrop-blur supports-[backdrop-filter]:bg-card/50 p-4 shrink-0", children: /* @__PURE__ */ jsxs16("div", { className: "max-w-5xl mx-auto", children: [
|
|
5659
|
+
/* @__PURE__ */ jsx19(ChatInput, {}),
|
|
5660
|
+
/* @__PURE__ */ jsx19("p", { className: "text-xs text-center text-muted-foreground/50 mt-2", children: "Press Enter to send, Shift+Enter for new line" })
|
|
5506
5661
|
] }) })
|
|
5507
5662
|
] });
|
|
5508
5663
|
}
|
|
5509
5664
|
|
|
5510
5665
|
// src/components/CollabPanel.tsx
|
|
5511
5666
|
import { Eye, LogIn, LogOut, MessageSquareWarning, Pause, Play, Users } from "lucide-react";
|
|
5512
|
-
import { useEffect as
|
|
5513
|
-
import { jsx as
|
|
5667
|
+
import { useEffect as useEffect14, useState as useState15 } from "react";
|
|
5668
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5514
5669
|
function CollabPanel({ sessionId, className }) {
|
|
5515
|
-
const [participants, setParticipants] =
|
|
5516
|
-
const [joined, setJoined] =
|
|
5517
|
-
const [joinedRole, setJoinedRole] =
|
|
5518
|
-
const [error, setError] =
|
|
5519
|
-
const [openAnnotationCount, setOpenAnnotationCount] =
|
|
5520
|
-
const [paused, setPaused] =
|
|
5670
|
+
const [participants, setParticipants] = useState15([]);
|
|
5671
|
+
const [joined, setJoined] = useState15(false);
|
|
5672
|
+
const [joinedRole, setJoinedRole] = useState15(null);
|
|
5673
|
+
const [error, setError] = useState15(null);
|
|
5674
|
+
const [openAnnotationCount, setOpenAnnotationCount] = useState15(0);
|
|
5675
|
+
const [paused, setPaused] = useState15(false);
|
|
5521
5676
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
5522
5677
|
const client2 = getWSClient(wsUrl);
|
|
5523
|
-
|
|
5678
|
+
useEffect14(() => {
|
|
5524
5679
|
const offs = [];
|
|
5525
5680
|
offs.push(
|
|
5526
5681
|
client2.on("collab.state", (msg) => {
|
|
@@ -5611,8 +5766,8 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5611
5766
|
className
|
|
5612
5767
|
),
|
|
5613
5768
|
children: [
|
|
5614
|
-
/* @__PURE__ */
|
|
5615
|
-
/* @__PURE__ */
|
|
5769
|
+
/* @__PURE__ */ jsx20(Users, { className: "w-4 h-4 text-muted-foreground" }),
|
|
5770
|
+
/* @__PURE__ */ jsx20("span", { className: "text-xs text-muted-foreground", children: "No live observers" }),
|
|
5616
5771
|
/* @__PURE__ */ jsxs17("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
5617
5772
|
/* @__PURE__ */ jsxs17(
|
|
5618
5773
|
"button",
|
|
@@ -5622,7 +5777,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5622
5777
|
className: "inline-flex items-center gap-1 text-xs px-2 py-1 rounded bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
|
|
5623
5778
|
title: "Join as a read-only observer (Phase 1)",
|
|
5624
5779
|
children: [
|
|
5625
|
-
/* @__PURE__ */
|
|
5780
|
+
/* @__PURE__ */ jsx20(LogIn, { className: "w-3 h-3" }),
|
|
5626
5781
|
"observer"
|
|
5627
5782
|
]
|
|
5628
5783
|
}
|
|
@@ -5635,7 +5790,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5635
5790
|
className: "inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-300 hover:bg-amber-500/20 transition-colors",
|
|
5636
5791
|
title: "Join as an annotator \u2014 leave inline notes on tool calls (Phase 2)",
|
|
5637
5792
|
children: [
|
|
5638
|
-
/* @__PURE__ */
|
|
5793
|
+
/* @__PURE__ */ jsx20(MessageSquareWarning, { className: "w-3 h-3" }),
|
|
5639
5794
|
"annotator"
|
|
5640
5795
|
]
|
|
5641
5796
|
}
|
|
@@ -5648,7 +5803,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5648
5803
|
className: "inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-rose-500/40 bg-rose-500/10 text-rose-700 dark:text-rose-300 hover:bg-rose-500/20 transition-colors",
|
|
5649
5804
|
title: "Join as a controller \u2014 can pause the agent loop (Phase 3)",
|
|
5650
5805
|
children: [
|
|
5651
|
-
/* @__PURE__ */
|
|
5806
|
+
/* @__PURE__ */ jsx20(Pause, { className: "w-3 h-3" }),
|
|
5652
5807
|
"controller"
|
|
5653
5808
|
]
|
|
5654
5809
|
}
|
|
@@ -5672,7 +5827,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5672
5827
|
"Collab: ",
|
|
5673
5828
|
error
|
|
5674
5829
|
] }),
|
|
5675
|
-
/* @__PURE__ */
|
|
5830
|
+
/* @__PURE__ */ jsx20(
|
|
5676
5831
|
"button",
|
|
5677
5832
|
{
|
|
5678
5833
|
type: "button",
|
|
@@ -5697,10 +5852,10 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5697
5852
|
),
|
|
5698
5853
|
children: [
|
|
5699
5854
|
/* @__PURE__ */ jsxs17("span", { className: "relative flex h-2 w-2", "aria-label": "Live", children: [
|
|
5700
|
-
/* @__PURE__ */
|
|
5701
|
-
/* @__PURE__ */
|
|
5855
|
+
/* @__PURE__ */ jsx20("span", { className: "absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75 animate-ping" }),
|
|
5856
|
+
/* @__PURE__ */ jsx20("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-emerald-500" })
|
|
5702
5857
|
] }),
|
|
5703
|
-
/* @__PURE__ */
|
|
5858
|
+
/* @__PURE__ */ jsx20(Users, { className: "w-4 h-4 text-emerald-700 dark:text-emerald-400" }),
|
|
5704
5859
|
/* @__PURE__ */ jsxs17("span", { className: "text-xs font-medium text-emerald-700 dark:text-emerald-300", children: [
|
|
5705
5860
|
participants.length,
|
|
5706
5861
|
" ",
|
|
@@ -5712,7 +5867,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5712
5867
|
title: `${openAnnotationCount} open annotation(s) \u2014 annotators reviewing this session`,
|
|
5713
5868
|
className: "ml-2 inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-amber-500/15 text-amber-700 dark:text-amber-300 border border-amber-500/30",
|
|
5714
5869
|
children: [
|
|
5715
|
-
/* @__PURE__ */
|
|
5870
|
+
/* @__PURE__ */ jsx20(MessageSquareWarning, { className: "w-3 h-3" }),
|
|
5716
5871
|
openAnnotationCount,
|
|
5717
5872
|
" note",
|
|
5718
5873
|
openAnnotationCount === 1 ? "" : "s"
|
|
@@ -5725,7 +5880,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5725
5880
|
title: "Agent loop is paused \u2014 a controller is reviewing",
|
|
5726
5881
|
className: "ml-2 inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-rose-500/15 text-rose-700 dark:text-rose-300 border border-rose-500/40",
|
|
5727
5882
|
children: [
|
|
5728
|
-
/* @__PURE__ */
|
|
5883
|
+
/* @__PURE__ */ jsx20(Pause, { className: "w-3 h-3" }),
|
|
5729
5884
|
"paused"
|
|
5730
5885
|
]
|
|
5731
5886
|
}
|
|
@@ -5737,7 +5892,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5737
5892
|
title: `Joined ${new Date(p.joinedAt).toLocaleTimeString()}`,
|
|
5738
5893
|
className: "inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
|
|
5739
5894
|
children: [
|
|
5740
|
-
/* @__PURE__ */
|
|
5895
|
+
/* @__PURE__ */ jsx20(Eye, { className: "w-3 h-3" }),
|
|
5741
5896
|
p.role
|
|
5742
5897
|
]
|
|
5743
5898
|
},
|
|
@@ -5756,7 +5911,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5756
5911
|
className: "ml-auto inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-rose-500/40 bg-rose-500/10 text-rose-700 dark:text-rose-300 hover:bg-rose-500/20 transition-colors",
|
|
5757
5912
|
title: "Resume the agent loop",
|
|
5758
5913
|
children: [
|
|
5759
|
-
/* @__PURE__ */
|
|
5914
|
+
/* @__PURE__ */ jsx20(Play, { className: "w-3 h-3" }),
|
|
5760
5915
|
"Resume"
|
|
5761
5916
|
]
|
|
5762
5917
|
}
|
|
@@ -5768,7 +5923,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5768
5923
|
className: "ml-auto inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-300 hover:bg-amber-500/20 transition-colors",
|
|
5769
5924
|
title: "Pause the agent before the next tool call",
|
|
5770
5925
|
children: [
|
|
5771
|
-
/* @__PURE__ */
|
|
5926
|
+
/* @__PURE__ */ jsx20(Pause, { className: "w-3 h-3" }),
|
|
5772
5927
|
"Pause agent"
|
|
5773
5928
|
]
|
|
5774
5929
|
}
|
|
@@ -5781,7 +5936,7 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5781
5936
|
className: "ml-auto inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-border hover:bg-muted transition-colors",
|
|
5782
5937
|
title: "Leave the observer session",
|
|
5783
5938
|
children: [
|
|
5784
|
-
/* @__PURE__ */
|
|
5939
|
+
/* @__PURE__ */ jsx20(LogOut, { className: "w-3 h-3" }),
|
|
5785
5940
|
"Leave"
|
|
5786
5941
|
]
|
|
5787
5942
|
}
|
|
@@ -5793,16 +5948,16 @@ function CollabPanel({ sessionId, className }) {
|
|
|
5793
5948
|
|
|
5794
5949
|
// src/components/ConfirmDialog.tsx
|
|
5795
5950
|
import { AlertTriangle as AlertTriangle2, FileEdit, Globe, ShieldAlert, Terminal as Terminal3, Wrench as Wrench3 } from "lucide-react";
|
|
5796
|
-
import { useEffect as
|
|
5951
|
+
import { useEffect as useEffect15, useRef as useRef10 } from "react";
|
|
5797
5952
|
|
|
5798
5953
|
// src/components/ui/dialog.tsx
|
|
5799
5954
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
5800
5955
|
import { X as X3 } from "lucide-react";
|
|
5801
5956
|
import * as React3 from "react";
|
|
5802
|
-
import { jsx as
|
|
5957
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5803
5958
|
var Dialog = DialogPrimitive.Root;
|
|
5804
5959
|
var DialogPortal = DialogPrimitive.Portal;
|
|
5805
|
-
var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5960
|
+
var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
|
|
5806
5961
|
DialogPrimitive.Overlay,
|
|
5807
5962
|
{
|
|
5808
5963
|
ref,
|
|
@@ -5815,7 +5970,7 @@ var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
5815
5970
|
));
|
|
5816
5971
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
5817
5972
|
var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs18(DialogPortal, { children: [
|
|
5818
|
-
/* @__PURE__ */
|
|
5973
|
+
/* @__PURE__ */ jsx21(DialogOverlay, {}),
|
|
5819
5974
|
/* @__PURE__ */ jsxs18(
|
|
5820
5975
|
DialogPrimitive.Content,
|
|
5821
5976
|
{
|
|
@@ -5828,17 +5983,17 @@ var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) =
|
|
|
5828
5983
|
children: [
|
|
5829
5984
|
children,
|
|
5830
5985
|
/* @__PURE__ */ jsxs18(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
|
|
5831
|
-
/* @__PURE__ */
|
|
5832
|
-
/* @__PURE__ */
|
|
5986
|
+
/* @__PURE__ */ jsx21(X3, { className: "h-4 w-4" }),
|
|
5987
|
+
/* @__PURE__ */ jsx21("span", { className: "sr-only", children: "Close" })
|
|
5833
5988
|
] })
|
|
5834
5989
|
]
|
|
5835
5990
|
}
|
|
5836
5991
|
)
|
|
5837
5992
|
] }));
|
|
5838
5993
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
5839
|
-
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */
|
|
5994
|
+
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx21("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
|
|
5840
5995
|
DialogHeader.displayName = "DialogHeader";
|
|
5841
|
-
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */
|
|
5996
|
+
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx21(
|
|
5842
5997
|
"div",
|
|
5843
5998
|
{
|
|
5844
5999
|
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
@@ -5846,7 +6001,7 @@ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx19(
|
|
|
5846
6001
|
}
|
|
5847
6002
|
);
|
|
5848
6003
|
DialogFooter.displayName = "DialogFooter";
|
|
5849
|
-
var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6004
|
+
var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
|
|
5850
6005
|
DialogPrimitive.Title,
|
|
5851
6006
|
{
|
|
5852
6007
|
ref,
|
|
@@ -5855,7 +6010,7 @@ var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5855
6010
|
}
|
|
5856
6011
|
));
|
|
5857
6012
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
5858
|
-
var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6013
|
+
var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx21(
|
|
5859
6014
|
DialogPrimitive.Description,
|
|
5860
6015
|
{
|
|
5861
6016
|
ref,
|
|
@@ -5866,7 +6021,7 @@ var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
5866
6021
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
5867
6022
|
|
|
5868
6023
|
// src/components/ConfirmDialog.tsx
|
|
5869
|
-
import { jsx as
|
|
6024
|
+
import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5870
6025
|
function pickToolIcon(toolName) {
|
|
5871
6026
|
if (/edit|write|create|patch/i.test(toolName)) return FileEdit;
|
|
5872
6027
|
if (/bash|shell|exec|run|command/i.test(toolName)) return Terminal3;
|
|
@@ -5879,7 +6034,7 @@ function SmartInputPreview({
|
|
|
5879
6034
|
}) {
|
|
5880
6035
|
const diffArgs = diffFromToolInput(toolName, input);
|
|
5881
6036
|
if (diffArgs) {
|
|
5882
|
-
return /* @__PURE__ */
|
|
6037
|
+
return /* @__PURE__ */ jsx22("div", { className: "rounded-lg overflow-hidden border", children: /* @__PURE__ */ jsx22(
|
|
5883
6038
|
DiffView,
|
|
5884
6039
|
{
|
|
5885
6040
|
oldText: diffArgs.oldText,
|
|
@@ -5894,8 +6049,8 @@ function SmartInputPreview({
|
|
|
5894
6049
|
if (typeof cmd === "string" && cmd.trim().length > 0) {
|
|
5895
6050
|
return /* @__PURE__ */ jsxs19("div", { className: "rounded-lg border bg-background/40 overflow-hidden", children: [
|
|
5896
6051
|
/* @__PURE__ */ jsxs19("div", { className: "px-3 py-1.5 text-[10px] uppercase tracking-wider text-muted-foreground border-b bg-muted/40 flex items-center gap-1.5", children: [
|
|
5897
|
-
/* @__PURE__ */
|
|
5898
|
-
/* @__PURE__ */
|
|
6052
|
+
/* @__PURE__ */ jsx22(Terminal3, { className: "h-3 w-3" }),
|
|
6053
|
+
/* @__PURE__ */ jsx22("span", { children: "Command" })
|
|
5899
6054
|
] }),
|
|
5900
6055
|
/* @__PURE__ */ jsxs19("pre", { className: "px-3 py-2 text-xs font-mono whitespace-pre-wrap break-all max-h-40 overflow-auto", children: [
|
|
5901
6056
|
"$",
|
|
@@ -5907,15 +6062,15 @@ function SmartInputPreview({
|
|
|
5907
6062
|
if (typeof url === "string") {
|
|
5908
6063
|
const method = obj.method ?? "GET";
|
|
5909
6064
|
return /* @__PURE__ */ jsxs19("div", { className: "rounded-lg border bg-background/40 px-3 py-2 text-xs font-mono", children: [
|
|
5910
|
-
/* @__PURE__ */
|
|
6065
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: method.toUpperCase() }),
|
|
5911
6066
|
" ",
|
|
5912
|
-
/* @__PURE__ */
|
|
6067
|
+
/* @__PURE__ */ jsx22("span", { className: "break-all", children: url })
|
|
5913
6068
|
] });
|
|
5914
6069
|
}
|
|
5915
6070
|
}
|
|
5916
6071
|
return /* @__PURE__ */ jsxs19("div", { className: "p-3 rounded-lg bg-muted/50 border text-xs font-mono", children: [
|
|
5917
|
-
/* @__PURE__ */
|
|
5918
|
-
/* @__PURE__ */
|
|
6072
|
+
/* @__PURE__ */ jsx22("div", { className: "text-muted-foreground mb-2", children: "Input:" }),
|
|
6073
|
+
/* @__PURE__ */ jsx22("pre", { className: "whitespace-pre-wrap break-all max-h-60 overflow-auto", children: JSON.stringify(input, null, 2) })
|
|
5919
6074
|
] });
|
|
5920
6075
|
}
|
|
5921
6076
|
function ConfirmDialog() {
|
|
@@ -5928,7 +6083,7 @@ function ConfirmDialog() {
|
|
|
5928
6083
|
}
|
|
5929
6084
|
hideConfirm();
|
|
5930
6085
|
};
|
|
5931
|
-
|
|
6086
|
+
useEffect15(() => {
|
|
5932
6087
|
if (!showConfirmDialog) return;
|
|
5933
6088
|
const onKey = (e) => {
|
|
5934
6089
|
const target = e.target;
|
|
@@ -5953,14 +6108,14 @@ function ConfirmDialog() {
|
|
|
5953
6108
|
return () => window.removeEventListener("keydown", onKey);
|
|
5954
6109
|
}, [showConfirmDialog, confirmInfo?.id]);
|
|
5955
6110
|
if (!confirmInfo) {
|
|
5956
|
-
return /* @__PURE__ */
|
|
6111
|
+
return /* @__PURE__ */ jsx22(Dialog, { open: showConfirmDialog, onOpenChange: () => hideConfirm(), children: /* @__PURE__ */ jsx22(DialogContent, {}) });
|
|
5957
6112
|
}
|
|
5958
6113
|
const Icon2 = pickToolIcon(confirmInfo.toolName);
|
|
5959
6114
|
const isEdit = /edit|write/i.test(confirmInfo.toolName);
|
|
5960
|
-
return /* @__PURE__ */
|
|
6115
|
+
return /* @__PURE__ */ jsx22(Dialog, { open: showConfirmDialog, onOpenChange: () => hideConfirm(), children: /* @__PURE__ */ jsxs19(DialogContent, { className: "sm:max-w-2xl border-yellow-500/50", ref: dialogRef, tabIndex: -1, children: [
|
|
5961
6116
|
/* @__PURE__ */ jsxs19(DialogHeader, { children: [
|
|
5962
6117
|
/* @__PURE__ */ jsxs19(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
5963
|
-
/* @__PURE__ */
|
|
6118
|
+
/* @__PURE__ */ jsx22(ShieldAlert, { className: "h-5 w-5 text-yellow-500 animate-pulse" }),
|
|
5964
6119
|
"Approval required: ",
|
|
5965
6120
|
confirmInfo.toolName
|
|
5966
6121
|
] }),
|
|
@@ -5972,24 +6127,24 @@ function ConfirmDialog() {
|
|
|
5972
6127
|
] }),
|
|
5973
6128
|
/* @__PURE__ */ jsxs19("div", { className: "py-2 space-y-3", children: [
|
|
5974
6129
|
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-3 p-3 rounded-lg bg-muted", children: [
|
|
5975
|
-
/* @__PURE__ */
|
|
6130
|
+
/* @__PURE__ */ jsx22(Icon2, { className: "h-5 w-5 text-muted-foreground" }),
|
|
5976
6131
|
/* @__PURE__ */ jsxs19("div", { className: "min-w-0", children: [
|
|
5977
|
-
/* @__PURE__ */
|
|
6132
|
+
/* @__PURE__ */ jsx22("div", { className: "font-medium font-mono truncate", children: confirmInfo.toolName }),
|
|
5978
6133
|
/* @__PURE__ */ jsxs19("div", { className: "text-xs text-muted-foreground", children: [
|
|
5979
6134
|
isEdit ? "File modification" : "Tool execution",
|
|
5980
6135
|
" \u2014 preview below"
|
|
5981
6136
|
] })
|
|
5982
6137
|
] })
|
|
5983
6138
|
] }),
|
|
5984
|
-
confirmInfo.input !== void 0 && /* @__PURE__ */
|
|
6139
|
+
confirmInfo.input !== void 0 && /* @__PURE__ */ jsx22(SmartInputPreview, { toolName: confirmInfo.toolName, input: confirmInfo.input }),
|
|
5985
6140
|
confirmInfo.suggestedPattern && /* @__PURE__ */ jsxs19("div", { className: "flex items-start gap-2 p-3 rounded-lg bg-yellow-500/10 border border-yellow-500/20", children: [
|
|
5986
|
-
/* @__PURE__ */
|
|
6141
|
+
/* @__PURE__ */ jsx22(AlertTriangle2, { className: "h-4 w-4 text-yellow-600 mt-0.5 shrink-0" }),
|
|
5987
6142
|
/* @__PURE__ */ jsxs19("div", { className: "text-sm min-w-0", children: [
|
|
5988
|
-
/* @__PURE__ */
|
|
5989
|
-
/* @__PURE__ */
|
|
6143
|
+
/* @__PURE__ */ jsx22("div", { className: "font-medium text-yellow-800 dark:text-yellow-200", children: "Trust pattern suggestion" }),
|
|
6144
|
+
/* @__PURE__ */ jsx22("div", { className: "font-mono text-xs mt-1 break-all", children: confirmInfo.suggestedPattern }),
|
|
5990
6145
|
/* @__PURE__ */ jsxs19("div", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
5991
6146
|
"Picking ",
|
|
5992
|
-
/* @__PURE__ */
|
|
6147
|
+
/* @__PURE__ */ jsx22("span", { className: "font-medium", children: "Always" }),
|
|
5993
6148
|
" will whitelist matching calls for this project."
|
|
5994
6149
|
] })
|
|
5995
6150
|
] })
|
|
@@ -6005,7 +6160,7 @@ function ConfirmDialog() {
|
|
|
6005
6160
|
title: "Reject this and all future calls matching the pattern (d)",
|
|
6006
6161
|
children: [
|
|
6007
6162
|
"Deny always ",
|
|
6008
|
-
/* @__PURE__ */
|
|
6163
|
+
/* @__PURE__ */ jsx22("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background", children: "d" })
|
|
6009
6164
|
]
|
|
6010
6165
|
}
|
|
6011
6166
|
),
|
|
@@ -6018,7 +6173,7 @@ function ConfirmDialog() {
|
|
|
6018
6173
|
title: "Reject this single call (Esc / n)",
|
|
6019
6174
|
children: [
|
|
6020
6175
|
"No ",
|
|
6021
|
-
/* @__PURE__ */
|
|
6176
|
+
/* @__PURE__ */ jsx22("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background", children: "n" })
|
|
6022
6177
|
]
|
|
6023
6178
|
}
|
|
6024
6179
|
),
|
|
@@ -6031,7 +6186,7 @@ function ConfirmDialog() {
|
|
|
6031
6186
|
title: "Approve and remember the pattern for the project (a)",
|
|
6032
6187
|
children: [
|
|
6033
6188
|
"Always ",
|
|
6034
|
-
/* @__PURE__ */
|
|
6189
|
+
/* @__PURE__ */ jsx22("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background", children: "a" })
|
|
6035
6190
|
]
|
|
6036
6191
|
}
|
|
6037
6192
|
),
|
|
@@ -6043,7 +6198,7 @@ function ConfirmDialog() {
|
|
|
6043
6198
|
title: "Approve this single call (y)",
|
|
6044
6199
|
children: [
|
|
6045
6200
|
"Yes ",
|
|
6046
|
-
/* @__PURE__ */
|
|
6201
|
+
/* @__PURE__ */ jsx22("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background/80", children: "y" })
|
|
6047
6202
|
]
|
|
6048
6203
|
}
|
|
6049
6204
|
)
|
|
@@ -6053,19 +6208,19 @@ function ConfirmDialog() {
|
|
|
6053
6208
|
|
|
6054
6209
|
// src/components/ConnectionBanner.tsx
|
|
6055
6210
|
import { Loader2 as Loader23, RotateCcw as RotateCcw4, WifiOff as WifiOff2, X as X4 } from "lucide-react";
|
|
6056
|
-
import { useEffect as
|
|
6057
|
-
import { jsx as
|
|
6211
|
+
import { useEffect as useEffect16, useState as useState16 } from "react";
|
|
6212
|
+
import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
6058
6213
|
function ConnectionBanner() {
|
|
6059
6214
|
const wsStatus = useConfigStore((s) => s.wsStatus);
|
|
6060
6215
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
6061
|
-
const [dismissed, setDismissed] =
|
|
6062
|
-
const [now, setNow] =
|
|
6063
|
-
|
|
6216
|
+
const [dismissed, setDismissed] = useState16(false);
|
|
6217
|
+
const [now, setNow] = useState16(Date.now());
|
|
6218
|
+
useEffect16(() => {
|
|
6064
6219
|
if (wsStatus.state !== "reconnecting") return;
|
|
6065
6220
|
const id = setInterval(() => setNow(Date.now()), 500);
|
|
6066
6221
|
return () => clearInterval(id);
|
|
6067
6222
|
}, [wsStatus.state]);
|
|
6068
|
-
|
|
6223
|
+
useEffect16(() => {
|
|
6069
6224
|
if (wsStatus.state === "open") setDismissed(false);
|
|
6070
6225
|
}, [wsStatus.state]);
|
|
6071
6226
|
if (wsStatus.state === "open" || wsStatus.state === "connecting") return null;
|
|
@@ -6082,10 +6237,10 @@ function ConnectionBanner() {
|
|
|
6082
6237
|
isReconnecting ? "bg-orange-500/10 text-orange-700 dark:text-orange-300 border-orange-500/30" : "bg-red-500/10 text-red-700 dark:text-red-300 border-red-500/30"
|
|
6083
6238
|
),
|
|
6084
6239
|
children: [
|
|
6085
|
-
isReconnecting ? /* @__PURE__ */
|
|
6240
|
+
isReconnecting ? /* @__PURE__ */ jsx23(Loader23, { className: "h-4 w-4 animate-spin shrink-0" }) : /* @__PURE__ */ jsx23(WifiOff2, { className: "h-4 w-4 shrink-0" }),
|
|
6086
6241
|
/* @__PURE__ */ jsxs20("div", { className: "flex-1 min-w-0", children: [
|
|
6087
|
-
/* @__PURE__ */
|
|
6088
|
-
errorText && /* @__PURE__ */
|
|
6242
|
+
/* @__PURE__ */ jsx23("div", { className: "font-medium", children: isReconnecting ? `Reconnecting to backend (attempt ${wsStatus.attempt}) \u2014 retrying in ${remaining}s` : "Disconnected from backend" }),
|
|
6243
|
+
errorText && /* @__PURE__ */ jsx23("div", { className: "text-xs opacity-80 truncate", children: errorText })
|
|
6089
6244
|
] }),
|
|
6090
6245
|
/* @__PURE__ */ jsxs20(
|
|
6091
6246
|
"button",
|
|
@@ -6099,19 +6254,19 @@ function ConnectionBanner() {
|
|
|
6099
6254
|
),
|
|
6100
6255
|
title: "Retry connection now",
|
|
6101
6256
|
children: [
|
|
6102
|
-
/* @__PURE__ */
|
|
6257
|
+
/* @__PURE__ */ jsx23(RotateCcw4, { className: "h-3 w-3" }),
|
|
6103
6258
|
"Retry now"
|
|
6104
6259
|
]
|
|
6105
6260
|
}
|
|
6106
6261
|
),
|
|
6107
|
-
/* @__PURE__ */
|
|
6262
|
+
/* @__PURE__ */ jsx23(
|
|
6108
6263
|
"button",
|
|
6109
6264
|
{
|
|
6110
6265
|
type: "button",
|
|
6111
6266
|
onClick: () => setDismissed(true),
|
|
6112
6267
|
className: "text-current/60 hover:text-current shrink-0",
|
|
6113
6268
|
title: "Dismiss (chip in topbar still shows status)",
|
|
6114
|
-
children: /* @__PURE__ */
|
|
6269
|
+
children: /* @__PURE__ */ jsx23(X4, { className: "h-4 w-4" })
|
|
6115
6270
|
}
|
|
6116
6271
|
)
|
|
6117
6272
|
]
|
|
@@ -6122,7 +6277,7 @@ function ConnectionBanner() {
|
|
|
6122
6277
|
// src/components/ErrorBoundary.tsx
|
|
6123
6278
|
import { AlertTriangle as AlertTriangle3, RefreshCw } from "lucide-react";
|
|
6124
6279
|
import { Component } from "react";
|
|
6125
|
-
import { jsx as
|
|
6280
|
+
import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
6126
6281
|
var ErrorBoundary = class extends Component {
|
|
6127
6282
|
state = { error: null };
|
|
6128
6283
|
static getDerivedStateFromError(error) {
|
|
@@ -6137,17 +6292,17 @@ var ErrorBoundary = class extends Component {
|
|
|
6137
6292
|
};
|
|
6138
6293
|
render() {
|
|
6139
6294
|
if (this.state.error) {
|
|
6140
|
-
return /* @__PURE__ */
|
|
6141
|
-
/* @__PURE__ */
|
|
6142
|
-
/* @__PURE__ */
|
|
6143
|
-
/* @__PURE__ */
|
|
6144
|
-
/* @__PURE__ */
|
|
6295
|
+
return /* @__PURE__ */ jsx24("div", { className: "flex items-center justify-center h-screen bg-background", children: /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-4 p-8 max-w-md text-center", children: [
|
|
6296
|
+
/* @__PURE__ */ jsx24(AlertTriangle3, { className: "h-12 w-12 text-destructive" }),
|
|
6297
|
+
/* @__PURE__ */ jsx24("h1", { className: "text-lg font-semibold", children: "Something went wrong" }),
|
|
6298
|
+
/* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: "A rendering error occurred. Your session is still active on the server \u2014 reloading will pick up where you left off." }),
|
|
6299
|
+
/* @__PURE__ */ jsx24("pre", { className: "text-xs font-mono text-muted-foreground bg-muted/50 rounded p-3 max-h-32 overflow-auto w-full text-left", children: this.state.error.message }),
|
|
6145
6300
|
/* @__PURE__ */ jsxs21("div", { className: "flex gap-2", children: [
|
|
6146
6301
|
/* @__PURE__ */ jsxs21(Button, { size: "sm", variant: "outline", onClick: () => window.location.reload(), children: [
|
|
6147
|
-
/* @__PURE__ */
|
|
6302
|
+
/* @__PURE__ */ jsx24(RefreshCw, { className: "h-4 w-4 mr-1" }),
|
|
6148
6303
|
"Reload page"
|
|
6149
6304
|
] }),
|
|
6150
|
-
/* @__PURE__ */
|
|
6305
|
+
/* @__PURE__ */ jsx24(Button, { size: "sm", onClick: this.handleReset, children: "Try again" })
|
|
6151
6306
|
] })
|
|
6152
6307
|
] }) });
|
|
6153
6308
|
}
|
|
@@ -6155,24 +6310,200 @@ var ErrorBoundary = class extends Component {
|
|
|
6155
6310
|
}
|
|
6156
6311
|
};
|
|
6157
6312
|
|
|
6313
|
+
// src/components/FleetPanel.tsx
|
|
6314
|
+
import { Bot as Bot3, ChevronDown as ChevronDown6, ChevronRight as ChevronRight4, Cpu as Cpu3, Wrench as Wrench4, Zap as Zap3 } from "lucide-react";
|
|
6315
|
+
import { useMemo as useMemo5, useState as useState17 } from "react";
|
|
6316
|
+
import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
6317
|
+
var STATUS_META = {
|
|
6318
|
+
running: {
|
|
6319
|
+
tone: "text-[hsl(var(--success))]",
|
|
6320
|
+
led: "text-[hsl(var(--success))]",
|
|
6321
|
+
label: "running",
|
|
6322
|
+
pulse: true
|
|
6323
|
+
},
|
|
6324
|
+
completed: {
|
|
6325
|
+
tone: "text-muted-foreground",
|
|
6326
|
+
led: "text-[hsl(var(--success))]",
|
|
6327
|
+
label: "done",
|
|
6328
|
+
pulse: false
|
|
6329
|
+
},
|
|
6330
|
+
failed: {
|
|
6331
|
+
tone: "text-destructive",
|
|
6332
|
+
led: "text-destructive",
|
|
6333
|
+
label: "failed",
|
|
6334
|
+
pulse: false
|
|
6335
|
+
},
|
|
6336
|
+
timeout: {
|
|
6337
|
+
tone: "text-[hsl(var(--warning))]",
|
|
6338
|
+
led: "text-[hsl(var(--warning))]",
|
|
6339
|
+
label: "timeout",
|
|
6340
|
+
pulse: false
|
|
6341
|
+
},
|
|
6342
|
+
stopped: {
|
|
6343
|
+
tone: "text-muted-foreground",
|
|
6344
|
+
led: "text-muted-foreground",
|
|
6345
|
+
label: "stopped",
|
|
6346
|
+
pulse: false
|
|
6347
|
+
}
|
|
6348
|
+
};
|
|
6349
|
+
function fmtCost(v) {
|
|
6350
|
+
if (v <= 0) return "$0";
|
|
6351
|
+
if (v >= 0.01) return `$${v.toFixed(3)}`;
|
|
6352
|
+
return `$${v.toFixed(5).replace(/0+$/, "").replace(/\.$/, "")}`;
|
|
6353
|
+
}
|
|
6354
|
+
function AgentCard({ a }) {
|
|
6355
|
+
const meta = STATUS_META[a.status];
|
|
6356
|
+
const active = a.status === "running";
|
|
6357
|
+
const tool = a.currentTool ?? a.lastTool;
|
|
6358
|
+
return /* @__PURE__ */ jsxs22(
|
|
6359
|
+
"div",
|
|
6360
|
+
{
|
|
6361
|
+
className: cn(
|
|
6362
|
+
"flex min-w-[15rem] max-w-[18rem] flex-col gap-1.5 rounded-lg border p-2.5 transition-colors",
|
|
6363
|
+
active ? "border-primary/30 bg-primary/[0.04]" : "border-border bg-card opacity-90"
|
|
6364
|
+
),
|
|
6365
|
+
children: [
|
|
6366
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
6367
|
+
/* @__PURE__ */ jsx25("span", { className: cn("led shrink-0", meta.led, meta.pulse && "led-pulse") }),
|
|
6368
|
+
/* @__PURE__ */ jsx25("span", { className: "truncate text-xs font-semibold text-foreground", title: a.name, children: a.name }),
|
|
6369
|
+
/* @__PURE__ */ jsx25("span", { className: cn("ml-auto shrink-0 text-[10px] uppercase tracking-wider", meta.tone), children: meta.label })
|
|
6370
|
+
] }),
|
|
6371
|
+
a.model && /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1 text-[10px] text-muted-foreground min-w-0", children: [
|
|
6372
|
+
/* @__PURE__ */ jsx25(Cpu3, { className: "h-3 w-3 shrink-0" }),
|
|
6373
|
+
/* @__PURE__ */ jsx25("span", { className: "truncate font-mono", title: `${a.provider ?? ""}/${a.model}`, children: a.model })
|
|
6374
|
+
] }),
|
|
6375
|
+
/* @__PURE__ */ jsxs22("div", { className: "tabular flex items-center gap-2 text-[11px] text-muted-foreground", children: [
|
|
6376
|
+
/* @__PURE__ */ jsxs22("span", { title: "iteration", children: [
|
|
6377
|
+
"L",
|
|
6378
|
+
a.iteration
|
|
6379
|
+
] }),
|
|
6380
|
+
/* @__PURE__ */ jsx25("span", { className: "text-border", children: "\xB7" }),
|
|
6381
|
+
/* @__PURE__ */ jsxs22("span", { title: "tool calls", children: [
|
|
6382
|
+
a.toolCalls,
|
|
6383
|
+
" tools"
|
|
6384
|
+
] }),
|
|
6385
|
+
/* @__PURE__ */ jsx25("span", { className: "text-border", children: "\xB7" }),
|
|
6386
|
+
/* @__PURE__ */ jsx25("span", { className: "text-foreground/80", title: "cost so far", children: fmtCost(a.costUsd) }),
|
|
6387
|
+
a.extensions > 0 && /* @__PURE__ */ jsxs22(
|
|
6388
|
+
"span",
|
|
6389
|
+
{
|
|
6390
|
+
className: "ml-auto inline-flex items-center gap-0.5 rounded bg-primary/15 px-1 text-[10px] text-primary",
|
|
6391
|
+
title: `Self-extended budget ${a.extensions}\xD7`,
|
|
6392
|
+
children: [
|
|
6393
|
+
/* @__PURE__ */ jsx25(Zap3, { className: "h-2.5 w-2.5" }),
|
|
6394
|
+
a.extensions
|
|
6395
|
+
]
|
|
6396
|
+
}
|
|
6397
|
+
)
|
|
6398
|
+
] }),
|
|
6399
|
+
tool && /* @__PURE__ */ jsxs22(
|
|
6400
|
+
"div",
|
|
6401
|
+
{
|
|
6402
|
+
className: cn(
|
|
6403
|
+
"flex items-center gap-1 text-[10px] truncate",
|
|
6404
|
+
active ? "text-primary" : "text-muted-foreground"
|
|
6405
|
+
),
|
|
6406
|
+
title: a.currentTool ? `running ${tool}` : `last ran ${tool}`,
|
|
6407
|
+
children: [
|
|
6408
|
+
/* @__PURE__ */ jsx25(Wrench4, { className: cn("h-3 w-3 shrink-0", active && "animate-pulse") }),
|
|
6409
|
+
/* @__PURE__ */ jsx25("span", { className: "truncate font-mono", children: tool })
|
|
6410
|
+
]
|
|
6411
|
+
}
|
|
6412
|
+
),
|
|
6413
|
+
a.maxContext > 0 && /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-1.5", title: `Context ${a.ctxPct}%`, children: [
|
|
6414
|
+
/* @__PURE__ */ jsx25("div", { className: "h-1 flex-1 overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx25(
|
|
6415
|
+
"div",
|
|
6416
|
+
{
|
|
6417
|
+
className: cn(
|
|
6418
|
+
"h-full rounded-full transition-all duration-500",
|
|
6419
|
+
a.ctxPct >= 85 ? "bg-destructive" : a.ctxPct >= 70 ? "bg-[hsl(var(--warning))]" : "bg-primary"
|
|
6420
|
+
),
|
|
6421
|
+
style: { width: `${Math.max(2, a.ctxPct)}%` }
|
|
6422
|
+
}
|
|
6423
|
+
) }),
|
|
6424
|
+
/* @__PURE__ */ jsxs22("span", { className: "tabular text-[9px] text-muted-foreground", children: [
|
|
6425
|
+
a.ctxPct,
|
|
6426
|
+
"%"
|
|
6427
|
+
] })
|
|
6428
|
+
] }),
|
|
6429
|
+
a.error && /* @__PURE__ */ jsxs22(
|
|
6430
|
+
"div",
|
|
6431
|
+
{
|
|
6432
|
+
className: "truncate rounded bg-destructive/10 px-1.5 py-0.5 text-[10px] text-destructive",
|
|
6433
|
+
title: a.error.message,
|
|
6434
|
+
children: [
|
|
6435
|
+
a.error.kind,
|
|
6436
|
+
": ",
|
|
6437
|
+
a.error.message
|
|
6438
|
+
]
|
|
6439
|
+
}
|
|
6440
|
+
)
|
|
6441
|
+
]
|
|
6442
|
+
}
|
|
6443
|
+
);
|
|
6444
|
+
}
|
|
6445
|
+
function FleetPanel({ className }) {
|
|
6446
|
+
const agents = useFleetStore((s) => s.agents);
|
|
6447
|
+
const [collapsed, setCollapsed] = useState17(false);
|
|
6448
|
+
const list = useMemo5(() => {
|
|
6449
|
+
const arr = Array.from(agents.values());
|
|
6450
|
+
arr.sort((x, y) => {
|
|
6451
|
+
const xa = x.status === "running" ? 0 : 1;
|
|
6452
|
+
const ya = y.status === "running" ? 0 : 1;
|
|
6453
|
+
if (xa !== ya) return xa - ya;
|
|
6454
|
+
return x.startedAt - y.startedAt;
|
|
6455
|
+
});
|
|
6456
|
+
return arr;
|
|
6457
|
+
}, [agents]);
|
|
6458
|
+
if (list.length === 0) return null;
|
|
6459
|
+
const activeCount = list.filter((a) => a.status === "running").length;
|
|
6460
|
+
return /* @__PURE__ */ jsxs22("div", { className: cn("rounded-lg border border-border bg-card/50 backdrop-blur-sm", className), children: [
|
|
6461
|
+
/* @__PURE__ */ jsxs22(
|
|
6462
|
+
"button",
|
|
6463
|
+
{
|
|
6464
|
+
type: "button",
|
|
6465
|
+
onClick: () => setCollapsed((v) => !v),
|
|
6466
|
+
className: "flex w-full items-center gap-2 px-3 py-2 text-left",
|
|
6467
|
+
children: [
|
|
6468
|
+
/* @__PURE__ */ jsx25(Bot3, { className: "h-4 w-4 text-primary" }),
|
|
6469
|
+
/* @__PURE__ */ jsx25("span", { className: "text-xs font-semibold text-foreground", children: "Fleet" }),
|
|
6470
|
+
/* @__PURE__ */ jsxs22("span", { className: "tabular text-[10px] text-muted-foreground", children: [
|
|
6471
|
+
list.length,
|
|
6472
|
+
" agent",
|
|
6473
|
+
list.length === 1 ? "" : "s",
|
|
6474
|
+
activeCount > 0 && /* @__PURE__ */ jsxs22("span", { className: "text-[hsl(var(--success))]", children: [
|
|
6475
|
+
" \xB7 ",
|
|
6476
|
+
activeCount,
|
|
6477
|
+
" active"
|
|
6478
|
+
] })
|
|
6479
|
+
] }),
|
|
6480
|
+
activeCount > 0 && /* @__PURE__ */ jsx25("span", { className: "led led-pulse text-[hsl(var(--success))]", "aria-hidden": true }),
|
|
6481
|
+
collapsed ? /* @__PURE__ */ jsx25(ChevronRight4, { className: "ml-auto h-4 w-4 text-muted-foreground" }) : /* @__PURE__ */ jsx25(ChevronDown6, { className: "ml-auto h-4 w-4 text-muted-foreground" })
|
|
6482
|
+
]
|
|
6483
|
+
}
|
|
6484
|
+
),
|
|
6485
|
+
!collapsed && /* @__PURE__ */ jsx25("div", { className: "flex gap-2 overflow-x-auto px-3 pb-3 pt-0.5", children: list.map((a) => /* @__PURE__ */ jsx25(AgentCard, { a }, a.id)) })
|
|
6486
|
+
] });
|
|
6487
|
+
}
|
|
6488
|
+
|
|
6158
6489
|
// src/components/QuickModelSwitcher.tsx
|
|
6159
|
-
import { ArrowRight as ArrowRight2, Cpu as
|
|
6160
|
-
import { useEffect as
|
|
6161
|
-
import { jsx as
|
|
6490
|
+
import { ArrowRight as ArrowRight2, Cpu as Cpu4, Search as Search4 } from "lucide-react";
|
|
6491
|
+
import { useEffect as useEffect17, useMemo as useMemo6, useRef as useRef11, useState as useState18 } from "react";
|
|
6492
|
+
import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
6162
6493
|
function QuickModelSwitcher() {
|
|
6163
6494
|
const open = useUIStore((s) => s.modelSwitcherOpen);
|
|
6164
6495
|
const setOpen = useUIStore((s) => s.setModelSwitcherOpen);
|
|
6165
|
-
const [query, setQuery] =
|
|
6166
|
-
const [selected, setSelected] =
|
|
6167
|
-
const [saved, setSaved] =
|
|
6168
|
-
const [modelsByProvider, setModelsByProvider] =
|
|
6496
|
+
const [query, setQuery] = useState18("");
|
|
6497
|
+
const [selected, setSelected] = useState18(0);
|
|
6498
|
+
const [saved, setSaved] = useState18([]);
|
|
6499
|
+
const [modelsByProvider, setModelsByProvider] = useState18({});
|
|
6169
6500
|
const inputRef = useRef11(null);
|
|
6170
6501
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
6171
6502
|
const currentProvider = useConfigStore((s) => s.provider);
|
|
6172
6503
|
const currentModel = useConfigStore((s) => s.model);
|
|
6173
6504
|
const paletteOpen = useUIStore((s) => s.paletteOpen);
|
|
6174
6505
|
const ws = useWebSocket();
|
|
6175
|
-
|
|
6506
|
+
useEffect17(() => {
|
|
6176
6507
|
const onKey = (e) => {
|
|
6177
6508
|
const mod = e.ctrlKey || e.metaKey;
|
|
6178
6509
|
if (mod && e.key.toLowerCase() === "m" && !e.shiftKey && !e.altKey) {
|
|
@@ -6189,7 +6520,7 @@ function QuickModelSwitcher() {
|
|
|
6189
6520
|
window.addEventListener("keydown", onKey);
|
|
6190
6521
|
return () => window.removeEventListener("keydown", onKey);
|
|
6191
6522
|
}, [open, paletteOpen]);
|
|
6192
|
-
|
|
6523
|
+
useEffect17(() => {
|
|
6193
6524
|
const client2 = getWSClient(wsUrl);
|
|
6194
6525
|
const offSaved = client2.on("providers.saved", (msg) => {
|
|
6195
6526
|
const p = msg.payload;
|
|
@@ -6204,14 +6535,14 @@ function QuickModelSwitcher() {
|
|
|
6204
6535
|
offModels();
|
|
6205
6536
|
};
|
|
6206
6537
|
}, [wsUrl]);
|
|
6207
|
-
|
|
6538
|
+
useEffect17(() => {
|
|
6208
6539
|
if (!open) return;
|
|
6209
6540
|
setQuery("");
|
|
6210
6541
|
setSelected(0);
|
|
6211
6542
|
ws.listSavedProviders();
|
|
6212
6543
|
requestAnimationFrame(() => inputRef.current?.focus());
|
|
6213
6544
|
}, [open, ws]);
|
|
6214
|
-
|
|
6545
|
+
useEffect17(() => {
|
|
6215
6546
|
if (!open) return;
|
|
6216
6547
|
for (const sp of saved) {
|
|
6217
6548
|
if (!modelsByProvider[sp.id]) {
|
|
@@ -6219,7 +6550,7 @@ function QuickModelSwitcher() {
|
|
|
6219
6550
|
}
|
|
6220
6551
|
}
|
|
6221
6552
|
}, [open, saved, modelsByProvider, ws]);
|
|
6222
|
-
const candidates =
|
|
6553
|
+
const candidates = useMemo6(() => {
|
|
6223
6554
|
const list = [];
|
|
6224
6555
|
for (const sp of saved) {
|
|
6225
6556
|
const models = modelsByProvider[sp.id] ?? [];
|
|
@@ -6242,7 +6573,7 @@ function QuickModelSwitcher() {
|
|
|
6242
6573
|
return a.provider.localeCompare(b.provider) || a.model.localeCompare(b.model);
|
|
6243
6574
|
});
|
|
6244
6575
|
}, [saved, modelsByProvider, query, currentProvider, currentModel]);
|
|
6245
|
-
|
|
6576
|
+
useEffect17(() => {
|
|
6246
6577
|
if (selected >= candidates.length) setSelected(0);
|
|
6247
6578
|
}, [candidates.length, selected]);
|
|
6248
6579
|
const commit = (idx) => {
|
|
@@ -6252,7 +6583,7 @@ function QuickModelSwitcher() {
|
|
|
6252
6583
|
setOpen(false);
|
|
6253
6584
|
};
|
|
6254
6585
|
if (!open) return null;
|
|
6255
|
-
return /* @__PURE__ */
|
|
6586
|
+
return /* @__PURE__ */ jsx26(
|
|
6256
6587
|
"div",
|
|
6257
6588
|
{
|
|
6258
6589
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-background/60 backdrop-blur-sm pt-[15vh]",
|
|
@@ -6262,10 +6593,10 @@ function QuickModelSwitcher() {
|
|
|
6262
6593
|
onKeyDown: (e) => {
|
|
6263
6594
|
if (e.key === "Escape") setOpen(false);
|
|
6264
6595
|
},
|
|
6265
|
-
children: /* @__PURE__ */
|
|
6266
|
-
/* @__PURE__ */
|
|
6267
|
-
/* @__PURE__ */
|
|
6268
|
-
/* @__PURE__ */
|
|
6596
|
+
children: /* @__PURE__ */ jsxs23("div", { className: "w-full max-w-xl rounded-xl border bg-popover shadow-2xl overflow-hidden", children: [
|
|
6597
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 border-b px-3 py-2", children: [
|
|
6598
|
+
/* @__PURE__ */ jsx26(Search4, { className: "h-4 w-4 text-muted-foreground" }),
|
|
6599
|
+
/* @__PURE__ */ jsx26(
|
|
6269
6600
|
"input",
|
|
6270
6601
|
{
|
|
6271
6602
|
ref: inputRef,
|
|
@@ -6293,9 +6624,9 @@ function QuickModelSwitcher() {
|
|
|
6293
6624
|
className: "flex-1 bg-transparent outline-none text-sm placeholder:text-muted-foreground"
|
|
6294
6625
|
}
|
|
6295
6626
|
),
|
|
6296
|
-
/* @__PURE__ */
|
|
6627
|
+
/* @__PURE__ */ jsx26("span", { className: "text-[10px] text-muted-foreground font-mono", children: "\u2191\u2193 \xB7 Enter \xB7 Esc" })
|
|
6297
6628
|
] }),
|
|
6298
|
-
/* @__PURE__ */
|
|
6629
|
+
/* @__PURE__ */ jsx26("div", { className: "max-h-[50vh] overflow-y-auto py-1", children: candidates.length === 0 ? /* @__PURE__ */ jsx26("div", { className: "px-4 py-8 text-center text-sm text-muted-foreground", children: saved.length === 0 ? "No saved providers \u2014 register a key in Settings first." : "Loading models\u2026" }) : candidates.map((c, idx) => /* @__PURE__ */ jsxs23(
|
|
6299
6630
|
"button",
|
|
6300
6631
|
{
|
|
6301
6632
|
type: "button",
|
|
@@ -6307,8 +6638,8 @@ function QuickModelSwitcher() {
|
|
|
6307
6638
|
c.isCurrent && "font-medium"
|
|
6308
6639
|
),
|
|
6309
6640
|
children: [
|
|
6310
|
-
/* @__PURE__ */
|
|
6311
|
-
|
|
6641
|
+
/* @__PURE__ */ jsx26(
|
|
6642
|
+
Cpu4,
|
|
6312
6643
|
{
|
|
6313
6644
|
className: cn(
|
|
6314
6645
|
"h-4 w-4 shrink-0",
|
|
@@ -6316,19 +6647,19 @@ function QuickModelSwitcher() {
|
|
|
6316
6647
|
)
|
|
6317
6648
|
}
|
|
6318
6649
|
),
|
|
6319
|
-
/* @__PURE__ */
|
|
6320
|
-
/* @__PURE__ */
|
|
6321
|
-
/* @__PURE__ */
|
|
6322
|
-
/* @__PURE__ */
|
|
6323
|
-
/* @__PURE__ */
|
|
6650
|
+
/* @__PURE__ */ jsxs23("div", { className: "min-w-0 flex-1", children: [
|
|
6651
|
+
/* @__PURE__ */ jsxs23("div", { className: "truncate", children: [
|
|
6652
|
+
/* @__PURE__ */ jsx26("span", { className: "text-muted-foreground", children: c.provider }),
|
|
6653
|
+
/* @__PURE__ */ jsx26("span", { className: "mx-1 text-muted-foreground/40", children: "\xB7" }),
|
|
6654
|
+
/* @__PURE__ */ jsx26("span", { children: c.modelName })
|
|
6324
6655
|
] }),
|
|
6325
|
-
c.contextWindow && /* @__PURE__ */
|
|
6656
|
+
c.contextWindow && /* @__PURE__ */ jsxs23("div", { className: "text-[10px] text-muted-foreground font-mono", children: [
|
|
6326
6657
|
c.model,
|
|
6327
6658
|
" \xB7 ctx ",
|
|
6328
6659
|
c.contextWindow.toLocaleString()
|
|
6329
6660
|
] })
|
|
6330
6661
|
] }),
|
|
6331
|
-
c.isCurrent ? /* @__PURE__ */
|
|
6662
|
+
c.isCurrent ? /* @__PURE__ */ jsx26("span", { className: "text-[10px] uppercase tracking-wide text-primary font-semibold", children: "active" }) : /* @__PURE__ */ jsx26(ArrowRight2, { className: "h-3.5 w-3.5 text-muted-foreground opacity-0 group-hover:opacity-100" })
|
|
6332
6663
|
]
|
|
6333
6664
|
},
|
|
6334
6665
|
`${c.provider}:${c.model}`
|
|
@@ -6342,7 +6673,7 @@ function QuickModelSwitcher() {
|
|
|
6342
6673
|
import {
|
|
6343
6674
|
AlertCircle,
|
|
6344
6675
|
CheckCircle2 as CheckCircle24,
|
|
6345
|
-
Cpu as
|
|
6676
|
+
Cpu as Cpu5,
|
|
6346
6677
|
Eye as Eye2,
|
|
6347
6678
|
EyeOff,
|
|
6348
6679
|
Globe as Globe2,
|
|
@@ -6358,58 +6689,14 @@ import {
|
|
|
6358
6689
|
Trash2 as Trash22,
|
|
6359
6690
|
X as X5
|
|
6360
6691
|
} from "lucide-react";
|
|
6361
|
-
import { useState as
|
|
6362
|
-
|
|
6363
|
-
// src/components/ThemeProvider.tsx
|
|
6364
|
-
import { createContext, useContext, useEffect as useEffect17, useState as useState17 } from "react";
|
|
6365
|
-
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
6366
|
-
var ThemeProviderContext = createContext(void 0);
|
|
6367
|
-
function ThemeProvider({
|
|
6368
|
-
children,
|
|
6369
|
-
defaultTheme = "system",
|
|
6370
|
-
storageKey = "wrongstack-theme"
|
|
6371
|
-
}) {
|
|
6372
|
-
const { setTheme: setStoreTheme } = useConfigStore();
|
|
6373
|
-
const [theme, setTheme] = useState17(() => {
|
|
6374
|
-
if (typeof window !== "undefined") {
|
|
6375
|
-
return localStorage.getItem(storageKey) || defaultTheme;
|
|
6376
|
-
}
|
|
6377
|
-
return defaultTheme;
|
|
6378
|
-
});
|
|
6379
|
-
useEffect17(() => {
|
|
6380
|
-
const root = window.document.documentElement;
|
|
6381
|
-
root.classList.remove("light", "dark");
|
|
6382
|
-
if (theme === "system") {
|
|
6383
|
-
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
6384
|
-
root.classList.add(systemTheme);
|
|
6385
|
-
} else {
|
|
6386
|
-
root.classList.add(theme);
|
|
6387
|
-
}
|
|
6388
|
-
}, [theme]);
|
|
6389
|
-
const value = {
|
|
6390
|
-
theme,
|
|
6391
|
-
setTheme: (newTheme) => {
|
|
6392
|
-
localStorage.setItem(storageKey, newTheme);
|
|
6393
|
-
setTheme(newTheme);
|
|
6394
|
-
setStoreTheme(newTheme);
|
|
6395
|
-
}
|
|
6396
|
-
};
|
|
6397
|
-
return /* @__PURE__ */ jsx24(ThemeProviderContext.Provider, { value, children });
|
|
6398
|
-
}
|
|
6399
|
-
function useTheme() {
|
|
6400
|
-
const context = useContext(ThemeProviderContext);
|
|
6401
|
-
if (context === void 0) {
|
|
6402
|
-
throw new Error("useTheme must be used within a ThemeProvider");
|
|
6403
|
-
}
|
|
6404
|
-
return context;
|
|
6405
|
-
}
|
|
6692
|
+
import { useState as useState19, useEffect as useEffect18, useCallback as useCallback4 } from "react";
|
|
6406
6693
|
|
|
6407
6694
|
// src/components/ui/input.tsx
|
|
6408
6695
|
import * as React4 from "react";
|
|
6409
|
-
import { jsx as
|
|
6696
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
6410
6697
|
var Input = React4.forwardRef(
|
|
6411
6698
|
({ className, type, ...props }, ref) => {
|
|
6412
|
-
return /* @__PURE__ */
|
|
6699
|
+
return /* @__PURE__ */ jsx27(
|
|
6413
6700
|
"input",
|
|
6414
6701
|
{
|
|
6415
6702
|
type,
|
|
@@ -6428,9 +6715,9 @@ Input.displayName = "Input";
|
|
|
6428
6715
|
// src/components/ui/tabs.tsx
|
|
6429
6716
|
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
6430
6717
|
import * as React5 from "react";
|
|
6431
|
-
import { jsx as
|
|
6718
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
6432
6719
|
var Tabs = TabsPrimitive.Root;
|
|
6433
|
-
var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6720
|
+
var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
|
|
6434
6721
|
TabsPrimitive.List,
|
|
6435
6722
|
{
|
|
6436
6723
|
ref,
|
|
@@ -6442,7 +6729,7 @@ var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
6442
6729
|
}
|
|
6443
6730
|
));
|
|
6444
6731
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
6445
|
-
var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6732
|
+
var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
|
|
6446
6733
|
TabsPrimitive.Trigger,
|
|
6447
6734
|
{
|
|
6448
6735
|
ref,
|
|
@@ -6454,7 +6741,7 @@ var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
6454
6741
|
}
|
|
6455
6742
|
));
|
|
6456
6743
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
6457
|
-
var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6744
|
+
var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx28(
|
|
6458
6745
|
TabsPrimitive.Content,
|
|
6459
6746
|
{
|
|
6460
6747
|
ref,
|
|
@@ -6468,30 +6755,30 @@ var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
6468
6755
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
6469
6756
|
|
|
6470
6757
|
// src/components/SettingsPanel.tsx
|
|
6471
|
-
import { Fragment as Fragment7, jsx as
|
|
6758
|
+
import { Fragment as Fragment7, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
6472
6759
|
function SettingsPanel() {
|
|
6473
6760
|
const { setCurrentView } = useUIStore();
|
|
6474
6761
|
const { provider, model, setProvider, setModel, wsConnected } = useConfigStore();
|
|
6475
6762
|
const { theme, setTheme } = useTheme();
|
|
6476
6763
|
const ws = useWebSocket();
|
|
6477
6764
|
const wsClient = ws.client;
|
|
6478
|
-
const [catalogProviders, setCatalogProviders] =
|
|
6479
|
-
const [catalogModels, setCatalogModels] =
|
|
6480
|
-
const [savedProviders, setSavedProviders] =
|
|
6481
|
-
const [isLoadingCatalog, setIsLoadingCatalog] =
|
|
6482
|
-
const [isLoadingModels, setIsLoadingModels] =
|
|
6483
|
-
const [isLoadingSaved, setIsLoadingSaved] =
|
|
6484
|
-
const [operationStatus, setOperationStatus] =
|
|
6485
|
-
const [providerTab, setProviderTab] =
|
|
6486
|
-
const [showAddKeyForm, setShowAddKeyForm] =
|
|
6487
|
-
const [newKeyLabel, setNewKeyLabel] =
|
|
6488
|
-
const [newKeyValue, setNewKeyValue] =
|
|
6489
|
-
const [showNewKeyValue, setShowNewKeyValue] =
|
|
6490
|
-
const [showAddProviderForm, setShowAddProviderForm] =
|
|
6491
|
-
const [newProviderId, setNewProviderId] =
|
|
6492
|
-
const [newProviderFamily, setNewProviderFamily] =
|
|
6493
|
-
const [newProviderBaseUrl, setNewProviderBaseUrl] =
|
|
6494
|
-
const [newProviderApiKey, setNewProviderApiKey] =
|
|
6765
|
+
const [catalogProviders, setCatalogProviders] = useState19([]);
|
|
6766
|
+
const [catalogModels, setCatalogModels] = useState19({});
|
|
6767
|
+
const [savedProviders, setSavedProviders] = useState19([]);
|
|
6768
|
+
const [isLoadingCatalog, setIsLoadingCatalog] = useState19(false);
|
|
6769
|
+
const [isLoadingModels, setIsLoadingModels] = useState19(false);
|
|
6770
|
+
const [isLoadingSaved, setIsLoadingSaved] = useState19(false);
|
|
6771
|
+
const [operationStatus, setOperationStatus] = useState19(null);
|
|
6772
|
+
const [providerTab, setProviderTab] = useState19("catalog");
|
|
6773
|
+
const [showAddKeyForm, setShowAddKeyForm] = useState19(null);
|
|
6774
|
+
const [newKeyLabel, setNewKeyLabel] = useState19("");
|
|
6775
|
+
const [newKeyValue, setNewKeyValue] = useState19("");
|
|
6776
|
+
const [showNewKeyValue, setShowNewKeyValue] = useState19(false);
|
|
6777
|
+
const [showAddProviderForm, setShowAddProviderForm] = useState19(false);
|
|
6778
|
+
const [newProviderId, setNewProviderId] = useState19("");
|
|
6779
|
+
const [newProviderFamily, setNewProviderFamily] = useState19("openai-compatible");
|
|
6780
|
+
const [newProviderBaseUrl, setNewProviderBaseUrl] = useState19("");
|
|
6781
|
+
const [newProviderApiKey, setNewProviderApiKey] = useState19("");
|
|
6495
6782
|
const currentCatalogProvider = catalogProviders.find((p) => p.id === provider);
|
|
6496
6783
|
useEffect18(() => {
|
|
6497
6784
|
const handleProviderCatalog = (msg) => {
|
|
@@ -6602,7 +6889,7 @@ function SettingsPanel() {
|
|
|
6602
6889
|
},
|
|
6603
6890
|
[ws]
|
|
6604
6891
|
);
|
|
6605
|
-
const [catalogQuery, setCatalogQuery] =
|
|
6892
|
+
const [catalogQuery, setCatalogQuery] = useState19("");
|
|
6606
6893
|
const families = ["anthropic", "openai", "google", "openai-compatible"];
|
|
6607
6894
|
const filteredCatalog = catalogQuery.trim() ? catalogProviders.filter((p) => {
|
|
6608
6895
|
const q = catalogQuery.trim().toLowerCase();
|
|
@@ -6616,52 +6903,52 @@ function SettingsPanel() {
|
|
|
6616
6903
|
},
|
|
6617
6904
|
{}
|
|
6618
6905
|
);
|
|
6619
|
-
return /* @__PURE__ */
|
|
6620
|
-
/* @__PURE__ */
|
|
6621
|
-
/* @__PURE__ */
|
|
6622
|
-
/* @__PURE__ */
|
|
6906
|
+
return /* @__PURE__ */ jsxs24("div", { className: "flex flex-col h-full", children: [
|
|
6907
|
+
/* @__PURE__ */ jsxs24("header", { className: "flex items-center justify-between px-4 py-3 border-b bg-card shrink-0", children: [
|
|
6908
|
+
/* @__PURE__ */ jsx29("h1", { className: "text-lg font-semibold", children: "Settings" }),
|
|
6909
|
+
/* @__PURE__ */ jsx29(Button, { variant: "ghost", size: "icon", onClick: () => setCurrentView("chat"), children: /* @__PURE__ */ jsx29(X5, { className: "h-4 w-4" }) })
|
|
6623
6910
|
] }),
|
|
6624
|
-
/* @__PURE__ */
|
|
6625
|
-
/* @__PURE__ */
|
|
6626
|
-
/* @__PURE__ */
|
|
6627
|
-
/* @__PURE__ */
|
|
6911
|
+
/* @__PURE__ */ jsx29(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsx29("div", { className: "p-6 max-w-2xl mx-auto", children: /* @__PURE__ */ jsxs24(Tabs, { defaultValue: "provider", children: [
|
|
6912
|
+
/* @__PURE__ */ jsxs24(TabsList, { className: "w-full justify-start mb-6 grid grid-cols-4", children: [
|
|
6913
|
+
/* @__PURE__ */ jsxs24(TabsTrigger, { value: "provider", className: "gap-2", children: [
|
|
6914
|
+
/* @__PURE__ */ jsx29(Network, { className: "h-4 w-4" }),
|
|
6628
6915
|
"Provider"
|
|
6629
6916
|
] }),
|
|
6630
|
-
/* @__PURE__ */
|
|
6631
|
-
/* @__PURE__ */
|
|
6917
|
+
/* @__PURE__ */ jsxs24(TabsTrigger, { value: "model", className: "gap-2", children: [
|
|
6918
|
+
/* @__PURE__ */ jsx29(Cpu5, { className: "h-4 w-4" }),
|
|
6632
6919
|
"Model"
|
|
6633
6920
|
] }),
|
|
6634
|
-
/* @__PURE__ */
|
|
6635
|
-
/* @__PURE__ */
|
|
6921
|
+
/* @__PURE__ */ jsxs24(TabsTrigger, { value: "connection", className: "gap-2", children: [
|
|
6922
|
+
/* @__PURE__ */ jsx29(Globe2, { className: "h-4 w-4" }),
|
|
6636
6923
|
"Connection"
|
|
6637
6924
|
] }),
|
|
6638
|
-
/* @__PURE__ */
|
|
6639
|
-
/* @__PURE__ */
|
|
6925
|
+
/* @__PURE__ */ jsxs24(TabsTrigger, { value: "appearance", className: "gap-2", children: [
|
|
6926
|
+
/* @__PURE__ */ jsx29(Palette, { className: "h-4 w-4" }),
|
|
6640
6927
|
"Appearance"
|
|
6641
6928
|
] })
|
|
6642
6929
|
] }),
|
|
6643
|
-
/* @__PURE__ */
|
|
6644
|
-
/* @__PURE__ */
|
|
6645
|
-
/* @__PURE__ */
|
|
6930
|
+
/* @__PURE__ */ jsxs24(TabsContent, { value: "provider", className: "space-y-4", children: [
|
|
6931
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-2 mb-4", children: [
|
|
6932
|
+
/* @__PURE__ */ jsxs24(
|
|
6646
6933
|
Button,
|
|
6647
6934
|
{
|
|
6648
6935
|
variant: providerTab === "catalog" ? "default" : "outline",
|
|
6649
6936
|
size: "sm",
|
|
6650
6937
|
onClick: () => setProviderTab("catalog"),
|
|
6651
6938
|
children: [
|
|
6652
|
-
/* @__PURE__ */
|
|
6939
|
+
/* @__PURE__ */ jsx29(Globe2, { className: "h-4 w-4 mr-1" }),
|
|
6653
6940
|
"Catalog"
|
|
6654
6941
|
]
|
|
6655
6942
|
}
|
|
6656
6943
|
),
|
|
6657
|
-
/* @__PURE__ */
|
|
6944
|
+
/* @__PURE__ */ jsxs24(
|
|
6658
6945
|
Button,
|
|
6659
6946
|
{
|
|
6660
6947
|
variant: providerTab === "saved" ? "default" : "outline",
|
|
6661
6948
|
size: "sm",
|
|
6662
6949
|
onClick: () => setProviderTab("saved"),
|
|
6663
6950
|
children: [
|
|
6664
|
-
/* @__PURE__ */
|
|
6951
|
+
/* @__PURE__ */ jsx29(Key, { className: "h-4 w-4 mr-1" }),
|
|
6665
6952
|
"Saved (",
|
|
6666
6953
|
savedProviders.length,
|
|
6667
6954
|
")"
|
|
@@ -6669,7 +6956,7 @@ function SettingsPanel() {
|
|
|
6669
6956
|
}
|
|
6670
6957
|
)
|
|
6671
6958
|
] }),
|
|
6672
|
-
operationStatus && /* @__PURE__ */
|
|
6959
|
+
operationStatus && /* @__PURE__ */ jsxs24(
|
|
6673
6960
|
"div",
|
|
6674
6961
|
{
|
|
6675
6962
|
className: cn(
|
|
@@ -6677,13 +6964,13 @@ function SettingsPanel() {
|
|
|
6677
6964
|
operationStatus.success ? "bg-green-500/10 text-green-600" : "bg-red-500/10 text-red-600"
|
|
6678
6965
|
),
|
|
6679
6966
|
children: [
|
|
6680
|
-
operationStatus.success ? /* @__PURE__ */
|
|
6967
|
+
operationStatus.success ? /* @__PURE__ */ jsx29(CheckCircle24, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx29(AlertCircle, { className: "h-4 w-4" }),
|
|
6681
6968
|
operationStatus.message
|
|
6682
6969
|
]
|
|
6683
6970
|
}
|
|
6684
6971
|
),
|
|
6685
|
-
providerTab === "catalog" && /* @__PURE__ */
|
|
6686
|
-
/* @__PURE__ */
|
|
6972
|
+
providerTab === "catalog" && /* @__PURE__ */ jsxs24("div", { className: "space-y-4", children: [
|
|
6973
|
+
/* @__PURE__ */ jsx29(
|
|
6687
6974
|
Input,
|
|
6688
6975
|
{
|
|
6689
6976
|
placeholder: `Search ${catalogProviders.length} providers (name / id / family)\u2026`,
|
|
@@ -6692,19 +6979,19 @@ function SettingsPanel() {
|
|
|
6692
6979
|
className: "text-sm"
|
|
6693
6980
|
}
|
|
6694
6981
|
),
|
|
6695
|
-
isLoadingCatalog && catalogProviders.length === 0 ? /* @__PURE__ */
|
|
6696
|
-
/* @__PURE__ */
|
|
6697
|
-
/* @__PURE__ */
|
|
6698
|
-
] }) : filteredCatalog.length === 0 && catalogQuery ? /* @__PURE__ */
|
|
6982
|
+
isLoadingCatalog && catalogProviders.length === 0 ? /* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-center py-8", children: [
|
|
6983
|
+
/* @__PURE__ */ jsx29(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }),
|
|
6984
|
+
/* @__PURE__ */ jsx29("span", { className: "ml-2 text-muted-foreground", children: "Loading catalog..." })
|
|
6985
|
+
] }) : filteredCatalog.length === 0 && catalogQuery ? /* @__PURE__ */ jsxs24("div", { className: "text-center py-8 text-muted-foreground text-sm", children: [
|
|
6699
6986
|
'No providers match "',
|
|
6700
|
-
/* @__PURE__ */
|
|
6987
|
+
/* @__PURE__ */ jsx29("span", { className: "font-mono", children: catalogQuery }),
|
|
6701
6988
|
'".'
|
|
6702
|
-
] }) : /* @__PURE__ */
|
|
6989
|
+
] }) : /* @__PURE__ */ jsx29(Fragment7, { children: families.map((family) => {
|
|
6703
6990
|
const providers = catalogByFamily[family];
|
|
6704
6991
|
if (!providers?.length) return null;
|
|
6705
|
-
return /* @__PURE__ */
|
|
6706
|
-
/* @__PURE__ */
|
|
6707
|
-
/* @__PURE__ */
|
|
6992
|
+
return /* @__PURE__ */ jsxs24("div", { className: "space-y-2", children: [
|
|
6993
|
+
/* @__PURE__ */ jsx29("h3", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-wider", children: family }),
|
|
6994
|
+
/* @__PURE__ */ jsx29("div", { className: "grid grid-cols-1 gap-2", children: providers.map((p) => /* @__PURE__ */ jsxs24(
|
|
6708
6995
|
"button",
|
|
6709
6996
|
{
|
|
6710
6997
|
type: "button",
|
|
@@ -6714,28 +7001,28 @@ function SettingsPanel() {
|
|
|
6714
7001
|
provider === p.id ? "border-primary bg-primary/5 ring-2 ring-primary/20" : "border-border hover:bg-muted"
|
|
6715
7002
|
),
|
|
6716
7003
|
children: [
|
|
6717
|
-
/* @__PURE__ */
|
|
6718
|
-
/* @__PURE__ */
|
|
6719
|
-
/* @__PURE__ */
|
|
6720
|
-
/* @__PURE__ */
|
|
7004
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex w-full justify-between items-start", children: [
|
|
7005
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
7006
|
+
/* @__PURE__ */ jsx29("span", { className: "font-medium", children: p.name }),
|
|
7007
|
+
/* @__PURE__ */ jsxs24("span", { className: "ml-2 text-xs text-muted-foreground", children: [
|
|
6721
7008
|
"(",
|
|
6722
7009
|
p.id,
|
|
6723
7010
|
")"
|
|
6724
7011
|
] })
|
|
6725
7012
|
] }),
|
|
6726
|
-
/* @__PURE__ */
|
|
6727
|
-
p.hasApiKey && /* @__PURE__ */
|
|
6728
|
-
/* @__PURE__ */
|
|
7013
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2", children: [
|
|
7014
|
+
p.hasApiKey && /* @__PURE__ */ jsxs24("span", { className: "text-xs bg-green-500/10 text-green-600 px-2 py-0.5 rounded", children: [
|
|
7015
|
+
/* @__PURE__ */ jsx29(Key, { className: "h-3 w-3 inline mr-1" }),
|
|
6729
7016
|
"Configured"
|
|
6730
7017
|
] }),
|
|
6731
|
-
p.envVars[0] && /* @__PURE__ */
|
|
7018
|
+
p.envVars[0] && /* @__PURE__ */ jsxs24("span", { className: "text-xs text-muted-foreground", children: [
|
|
6732
7019
|
"ENV: ",
|
|
6733
7020
|
p.envVars[0]
|
|
6734
7021
|
] }),
|
|
6735
|
-
provider === p.id && /* @__PURE__ */
|
|
7022
|
+
provider === p.id && /* @__PURE__ */ jsx29(CheckCircle24, { className: "h-4 w-4 text-primary" })
|
|
6736
7023
|
] })
|
|
6737
7024
|
] }),
|
|
6738
|
-
/* @__PURE__ */
|
|
7025
|
+
/* @__PURE__ */ jsxs24("div", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
6739
7026
|
p.modelCount,
|
|
6740
7027
|
" models",
|
|
6741
7028
|
p.apiBase && ` \xB7 ${p.apiBase}`
|
|
@@ -6747,25 +7034,25 @@ function SettingsPanel() {
|
|
|
6747
7034
|
] }, family);
|
|
6748
7035
|
}) })
|
|
6749
7036
|
] }),
|
|
6750
|
-
providerTab === "saved" && /* @__PURE__ */
|
|
6751
|
-
/* @__PURE__ */
|
|
6752
|
-
/* @__PURE__ */
|
|
6753
|
-
/* @__PURE__ */
|
|
7037
|
+
providerTab === "saved" && /* @__PURE__ */ jsxs24("div", { className: "space-y-4", children: [
|
|
7038
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex justify-between items-center", children: [
|
|
7039
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: "Manage your API keys and provider configurations" }),
|
|
7040
|
+
/* @__PURE__ */ jsxs24(
|
|
6754
7041
|
Button,
|
|
6755
7042
|
{
|
|
6756
7043
|
size: "sm",
|
|
6757
7044
|
variant: "outline",
|
|
6758
7045
|
onClick: () => setShowAddProviderForm(!showAddProviderForm),
|
|
6759
7046
|
children: [
|
|
6760
|
-
/* @__PURE__ */
|
|
7047
|
+
/* @__PURE__ */ jsx29(Plus, { className: "h-4 w-4 mr-1" }),
|
|
6761
7048
|
"Add Provider"
|
|
6762
7049
|
]
|
|
6763
7050
|
}
|
|
6764
7051
|
)
|
|
6765
7052
|
] }),
|
|
6766
|
-
showAddProviderForm && /* @__PURE__ */
|
|
6767
|
-
/* @__PURE__ */
|
|
6768
|
-
/* @__PURE__ */
|
|
7053
|
+
showAddProviderForm && /* @__PURE__ */ jsxs24("div", { className: "p-4 border rounded-lg space-y-3 bg-muted/50", children: [
|
|
7054
|
+
/* @__PURE__ */ jsx29("h4", { className: "font-medium", children: "Add Custom Provider" }),
|
|
7055
|
+
/* @__PURE__ */ jsx29(
|
|
6769
7056
|
Input,
|
|
6770
7057
|
{
|
|
6771
7058
|
placeholder: "Provider ID (e.g. my-llm-server)",
|
|
@@ -6773,21 +7060,21 @@ function SettingsPanel() {
|
|
|
6773
7060
|
onChange: (e) => setNewProviderId(e.target.value)
|
|
6774
7061
|
}
|
|
6775
7062
|
),
|
|
6776
|
-
/* @__PURE__ */
|
|
7063
|
+
/* @__PURE__ */ jsxs24(
|
|
6777
7064
|
"select",
|
|
6778
7065
|
{
|
|
6779
7066
|
className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
6780
7067
|
value: newProviderFamily,
|
|
6781
7068
|
onChange: (e) => setNewProviderFamily(e.target.value),
|
|
6782
7069
|
children: [
|
|
6783
|
-
/* @__PURE__ */
|
|
6784
|
-
/* @__PURE__ */
|
|
6785
|
-
/* @__PURE__ */
|
|
6786
|
-
/* @__PURE__ */
|
|
7070
|
+
/* @__PURE__ */ jsx29("option", { value: "anthropic", children: "Anthropic" }),
|
|
7071
|
+
/* @__PURE__ */ jsx29("option", { value: "openai", children: "OpenAI" }),
|
|
7072
|
+
/* @__PURE__ */ jsx29("option", { value: "openai-compatible", children: "OpenAI Compatible" }),
|
|
7073
|
+
/* @__PURE__ */ jsx29("option", { value: "google", children: "Google" })
|
|
6787
7074
|
]
|
|
6788
7075
|
}
|
|
6789
7076
|
),
|
|
6790
|
-
/* @__PURE__ */
|
|
7077
|
+
/* @__PURE__ */ jsx29(
|
|
6791
7078
|
Input,
|
|
6792
7079
|
{
|
|
6793
7080
|
placeholder: "Base URL (optional, e.g. http://localhost:11434/v1)",
|
|
@@ -6795,7 +7082,7 @@ function SettingsPanel() {
|
|
|
6795
7082
|
onChange: (e) => setNewProviderBaseUrl(e.target.value)
|
|
6796
7083
|
}
|
|
6797
7084
|
),
|
|
6798
|
-
/* @__PURE__ */
|
|
7085
|
+
/* @__PURE__ */ jsx29(
|
|
6799
7086
|
Input,
|
|
6800
7087
|
{
|
|
6801
7088
|
type: "password",
|
|
@@ -6804,8 +7091,8 @@ function SettingsPanel() {
|
|
|
6804
7091
|
onChange: (e) => setNewProviderApiKey(e.target.value)
|
|
6805
7092
|
}
|
|
6806
7093
|
),
|
|
6807
|
-
/* @__PURE__ */
|
|
6808
|
-
/* @__PURE__ */
|
|
7094
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-2", children: [
|
|
7095
|
+
/* @__PURE__ */ jsx29(
|
|
6809
7096
|
Button,
|
|
6810
7097
|
{
|
|
6811
7098
|
size: "sm",
|
|
@@ -6814,7 +7101,7 @@ function SettingsPanel() {
|
|
|
6814
7101
|
children: "Add"
|
|
6815
7102
|
}
|
|
6816
7103
|
),
|
|
6817
|
-
/* @__PURE__ */
|
|
7104
|
+
/* @__PURE__ */ jsx29(
|
|
6818
7105
|
Button,
|
|
6819
7106
|
{
|
|
6820
7107
|
size: "sm",
|
|
@@ -6825,59 +7112,59 @@ function SettingsPanel() {
|
|
|
6825
7112
|
)
|
|
6826
7113
|
] })
|
|
6827
7114
|
] }),
|
|
6828
|
-
isLoadingSaved ? /* @__PURE__ */
|
|
6829
|
-
/* @__PURE__ */
|
|
6830
|
-
/* @__PURE__ */
|
|
6831
|
-
/* @__PURE__ */
|
|
6832
|
-
] }) : savedProviders.map((sp) => /* @__PURE__ */
|
|
6833
|
-
/* @__PURE__ */
|
|
6834
|
-
/* @__PURE__ */
|
|
6835
|
-
/* @__PURE__ */
|
|
6836
|
-
sp.family && /* @__PURE__ */
|
|
7115
|
+
isLoadingSaved ? /* @__PURE__ */ jsx29("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx29(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : savedProviders.length === 0 ? /* @__PURE__ */ jsxs24("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
7116
|
+
/* @__PURE__ */ jsx29(Key, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
|
|
7117
|
+
/* @__PURE__ */ jsx29("p", { children: "No saved providers yet" }),
|
|
7118
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm", children: "Add a provider to get started" })
|
|
7119
|
+
] }) : savedProviders.map((sp) => /* @__PURE__ */ jsxs24("div", { className: "border rounded-lg p-4 space-y-3", children: [
|
|
7120
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex justify-between items-start", children: [
|
|
7121
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
7122
|
+
/* @__PURE__ */ jsx29("h4", { className: "font-medium", children: sp.id }),
|
|
7123
|
+
sp.family && /* @__PURE__ */ jsx29("span", { className: "text-xs text-muted-foreground", children: sp.family })
|
|
6837
7124
|
] }),
|
|
6838
|
-
/* @__PURE__ */
|
|
7125
|
+
/* @__PURE__ */ jsx29("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx29(
|
|
6839
7126
|
Button,
|
|
6840
7127
|
{
|
|
6841
7128
|
size: "icon",
|
|
6842
7129
|
variant: "ghost",
|
|
6843
7130
|
onClick: () => handleRemoveProvider(sp.id),
|
|
6844
|
-
children: /* @__PURE__ */
|
|
7131
|
+
children: /* @__PURE__ */ jsx29(Trash22, { className: "h-4 w-4 text-destructive" })
|
|
6845
7132
|
}
|
|
6846
7133
|
) })
|
|
6847
7134
|
] }),
|
|
6848
|
-
sp.baseUrl && /* @__PURE__ */
|
|
6849
|
-
/* @__PURE__ */
|
|
7135
|
+
sp.baseUrl && /* @__PURE__ */ jsxs24("div", { className: "text-xs text-muted-foreground", children: [
|
|
7136
|
+
/* @__PURE__ */ jsx29(Globe2, { className: "h-3 w-3 inline mr-1" }),
|
|
6850
7137
|
sp.baseUrl
|
|
6851
7138
|
] }),
|
|
6852
|
-
/* @__PURE__ */
|
|
6853
|
-
/* @__PURE__ */
|
|
6854
|
-
/* @__PURE__ */
|
|
6855
|
-
/* @__PURE__ */
|
|
7139
|
+
/* @__PURE__ */ jsxs24("div", { className: "space-y-2", children: [
|
|
7140
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex justify-between items-center", children: [
|
|
7141
|
+
/* @__PURE__ */ jsx29("span", { className: "text-sm font-medium", children: "API Keys" }),
|
|
7142
|
+
/* @__PURE__ */ jsxs24(
|
|
6856
7143
|
Button,
|
|
6857
7144
|
{
|
|
6858
7145
|
size: "sm",
|
|
6859
7146
|
variant: "ghost",
|
|
6860
7147
|
onClick: () => setShowAddKeyForm(showAddKeyForm === sp.id ? null : sp.id),
|
|
6861
7148
|
children: [
|
|
6862
|
-
/* @__PURE__ */
|
|
7149
|
+
/* @__PURE__ */ jsx29(Plus, { className: "h-3 w-3 mr-1" }),
|
|
6863
7150
|
"Add Key"
|
|
6864
7151
|
]
|
|
6865
7152
|
}
|
|
6866
7153
|
)
|
|
6867
7154
|
] }),
|
|
6868
|
-
sp.apiKeys.length === 0 && !showAddKeyForm && /* @__PURE__ */
|
|
6869
|
-
sp.apiKeys.map((key) => /* @__PURE__ */
|
|
7155
|
+
sp.apiKeys.length === 0 && !showAddKeyForm && /* @__PURE__ */ jsx29("p", { className: "text-xs text-muted-foreground", children: "No keys configured" }),
|
|
7156
|
+
sp.apiKeys.map((key) => /* @__PURE__ */ jsxs24(
|
|
6870
7157
|
"div",
|
|
6871
7158
|
{
|
|
6872
7159
|
className: "flex items-center justify-between p-2 bg-muted/50 rounded",
|
|
6873
7160
|
children: [
|
|
6874
|
-
/* @__PURE__ */
|
|
6875
|
-
/* @__PURE__ */
|
|
6876
|
-
key.isActive && /* @__PURE__ */
|
|
6877
|
-
/* @__PURE__ */
|
|
7161
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
7162
|
+
/* @__PURE__ */ jsx29("span", { className: "text-sm font-medium", children: key.label }),
|
|
7163
|
+
key.isActive && /* @__PURE__ */ jsx29("span", { className: "ml-2 text-xs bg-green-500/10 text-green-600 px-1.5 py-0.5 rounded", children: "Active" }),
|
|
7164
|
+
/* @__PURE__ */ jsx29("div", { className: "text-xs text-muted-foreground font-mono", children: key.maskedKey })
|
|
6878
7165
|
] }),
|
|
6879
|
-
/* @__PURE__ */
|
|
6880
|
-
!key.isActive && /* @__PURE__ */
|
|
7166
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-1", children: [
|
|
7167
|
+
!key.isActive && /* @__PURE__ */ jsx29(
|
|
6881
7168
|
Button,
|
|
6882
7169
|
{
|
|
6883
7170
|
size: "sm",
|
|
@@ -6886,13 +7173,13 @@ function SettingsPanel() {
|
|
|
6886
7173
|
children: "Set Active"
|
|
6887
7174
|
}
|
|
6888
7175
|
),
|
|
6889
|
-
/* @__PURE__ */
|
|
7176
|
+
/* @__PURE__ */ jsx29(
|
|
6890
7177
|
Button,
|
|
6891
7178
|
{
|
|
6892
7179
|
size: "icon",
|
|
6893
7180
|
variant: "ghost",
|
|
6894
7181
|
onClick: () => handleDeleteKey(sp.id, key.label),
|
|
6895
|
-
children: /* @__PURE__ */
|
|
7182
|
+
children: /* @__PURE__ */ jsx29(Trash22, { className: "h-3 w-3 text-destructive" })
|
|
6896
7183
|
}
|
|
6897
7184
|
)
|
|
6898
7185
|
] })
|
|
@@ -6900,8 +7187,8 @@ function SettingsPanel() {
|
|
|
6900
7187
|
},
|
|
6901
7188
|
key.label
|
|
6902
7189
|
)),
|
|
6903
|
-
showAddKeyForm === sp.id && /* @__PURE__ */
|
|
6904
|
-
/* @__PURE__ */
|
|
7190
|
+
showAddKeyForm === sp.id && /* @__PURE__ */ jsxs24("div", { className: "p-3 border rounded space-y-2 bg-background", children: [
|
|
7191
|
+
/* @__PURE__ */ jsx29(
|
|
6905
7192
|
Input,
|
|
6906
7193
|
{
|
|
6907
7194
|
placeholder: "Key label (e.g. default, production)",
|
|
@@ -6909,8 +7196,8 @@ function SettingsPanel() {
|
|
|
6909
7196
|
onChange: (e) => setNewKeyLabel(e.target.value)
|
|
6910
7197
|
}
|
|
6911
7198
|
),
|
|
6912
|
-
/* @__PURE__ */
|
|
6913
|
-
/* @__PURE__ */
|
|
7199
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-2", children: [
|
|
7200
|
+
/* @__PURE__ */ jsx29(
|
|
6914
7201
|
Input,
|
|
6915
7202
|
{
|
|
6916
7203
|
type: showNewKeyValue ? "text" : "password",
|
|
@@ -6919,18 +7206,18 @@ function SettingsPanel() {
|
|
|
6919
7206
|
onChange: (e) => setNewKeyValue(e.target.value)
|
|
6920
7207
|
}
|
|
6921
7208
|
),
|
|
6922
|
-
/* @__PURE__ */
|
|
7209
|
+
/* @__PURE__ */ jsx29(
|
|
6923
7210
|
Button,
|
|
6924
7211
|
{
|
|
6925
7212
|
size: "icon",
|
|
6926
7213
|
variant: "ghost",
|
|
6927
7214
|
onClick: () => setShowNewKeyValue(!showNewKeyValue),
|
|
6928
|
-
children: showNewKeyValue ? /* @__PURE__ */
|
|
7215
|
+
children: showNewKeyValue ? /* @__PURE__ */ jsx29(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx29(Eye2, { className: "h-4 w-4" })
|
|
6929
7216
|
}
|
|
6930
7217
|
)
|
|
6931
7218
|
] }),
|
|
6932
|
-
/* @__PURE__ */
|
|
6933
|
-
/* @__PURE__ */
|
|
7219
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex gap-2", children: [
|
|
7220
|
+
/* @__PURE__ */ jsx29(
|
|
6934
7221
|
Button,
|
|
6935
7222
|
{
|
|
6936
7223
|
size: "sm",
|
|
@@ -6939,7 +7226,7 @@ function SettingsPanel() {
|
|
|
6939
7226
|
children: "Save Key"
|
|
6940
7227
|
}
|
|
6941
7228
|
),
|
|
6942
|
-
/* @__PURE__ */
|
|
7229
|
+
/* @__PURE__ */ jsx29(
|
|
6943
7230
|
Button,
|
|
6944
7231
|
{
|
|
6945
7232
|
size: "sm",
|
|
@@ -6958,13 +7245,13 @@ function SettingsPanel() {
|
|
|
6958
7245
|
] }, sp.id))
|
|
6959
7246
|
] })
|
|
6960
7247
|
] }),
|
|
6961
|
-
/* @__PURE__ */
|
|
6962
|
-
/* @__PURE__ */
|
|
6963
|
-
/* @__PURE__ */
|
|
6964
|
-
/* @__PURE__ */
|
|
6965
|
-
/* @__PURE__ */
|
|
7248
|
+
/* @__PURE__ */ jsx29(TabsContent, { value: "model", className: "space-y-4", children: provider ? /* @__PURE__ */ jsxs24(Fragment7, { children: [
|
|
7249
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-between", children: [
|
|
7250
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
7251
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm font-medium", children: currentCatalogProvider?.name || provider }),
|
|
7252
|
+
/* @__PURE__ */ jsx29("p", { className: "text-xs text-muted-foreground", children: provider })
|
|
6966
7253
|
] }),
|
|
6967
|
-
/* @__PURE__ */
|
|
7254
|
+
/* @__PURE__ */ jsx29(
|
|
6968
7255
|
Button,
|
|
6969
7256
|
{
|
|
6970
7257
|
variant: "ghost",
|
|
@@ -6973,15 +7260,15 @@ function SettingsPanel() {
|
|
|
6973
7260
|
setIsLoadingModels(true);
|
|
6974
7261
|
ws.listProviderModels?.(provider);
|
|
6975
7262
|
},
|
|
6976
|
-
children: /* @__PURE__ */
|
|
7263
|
+
children: /* @__PURE__ */ jsx29(RefreshCw2, { className: cn("h-4 w-4", isLoadingModels && "animate-spin") })
|
|
6977
7264
|
}
|
|
6978
7265
|
)
|
|
6979
7266
|
] }),
|
|
6980
|
-
isLoadingModels && !catalogModels[provider] ? /* @__PURE__ */
|
|
6981
|
-
/* @__PURE__ */
|
|
6982
|
-
/* @__PURE__ */
|
|
6983
|
-
] }) : /* @__PURE__ */
|
|
6984
|
-
(catalogModels[provider] || []).map((m) => /* @__PURE__ */
|
|
7267
|
+
isLoadingModels && !catalogModels[provider] ? /* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-center py-8", children: [
|
|
7268
|
+
/* @__PURE__ */ jsx29(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }),
|
|
7269
|
+
/* @__PURE__ */ jsx29("span", { className: "ml-2 text-muted-foreground", children: "Loading models..." })
|
|
7270
|
+
] }) : /* @__PURE__ */ jsxs24("div", { className: "space-y-1", children: [
|
|
7271
|
+
(catalogModels[provider] || []).map((m) => /* @__PURE__ */ jsxs24(
|
|
6985
7272
|
"button",
|
|
6986
7273
|
{
|
|
6987
7274
|
type: "button",
|
|
@@ -6991,47 +7278,47 @@ function SettingsPanel() {
|
|
|
6991
7278
|
model === m.id ? "border-primary bg-primary/5 ring-2 ring-primary/20" : "border-border hover:bg-muted"
|
|
6992
7279
|
),
|
|
6993
7280
|
children: [
|
|
6994
|
-
/* @__PURE__ */
|
|
6995
|
-
/* @__PURE__ */
|
|
6996
|
-
/* @__PURE__ */
|
|
7281
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
7282
|
+
/* @__PURE__ */ jsx29("span", { className: "font-medium", children: m.name || m.id }),
|
|
7283
|
+
/* @__PURE__ */ jsx29("div", { className: "flex gap-2 mt-1", children: m.capabilities.map((cap) => /* @__PURE__ */ jsx29("span", { className: "text-xs bg-muted px-1.5 py-0.5 rounded", children: cap }, cap)) })
|
|
6997
7284
|
] }),
|
|
6998
|
-
/* @__PURE__ */
|
|
6999
|
-
m.contextWindow && /* @__PURE__ */
|
|
7285
|
+
/* @__PURE__ */ jsxs24("div", { className: "text-right text-xs text-muted-foreground", children: [
|
|
7286
|
+
m.contextWindow && /* @__PURE__ */ jsxs24("div", { children: [
|
|
7000
7287
|
m.contextWindow / 1e3,
|
|
7001
7288
|
"k context"
|
|
7002
7289
|
] }),
|
|
7003
|
-
m.inputCost && m.outputCost && /* @__PURE__ */
|
|
7290
|
+
m.inputCost && m.outputCost && /* @__PURE__ */ jsxs24("div", { children: [
|
|
7004
7291
|
"$",
|
|
7005
7292
|
m.inputCost,
|
|
7006
7293
|
"/$",
|
|
7007
7294
|
m.outputCost
|
|
7008
7295
|
] }),
|
|
7009
|
-
model === m.id && /* @__PURE__ */
|
|
7296
|
+
model === m.id && /* @__PURE__ */ jsx29(CheckCircle24, { className: "h-4 w-4 text-primary mt-1" })
|
|
7010
7297
|
] })
|
|
7011
7298
|
]
|
|
7012
7299
|
},
|
|
7013
7300
|
m.id
|
|
7014
7301
|
)),
|
|
7015
|
-
catalogModels[provider]?.length === 0 && /* @__PURE__ */
|
|
7302
|
+
catalogModels[provider]?.length === 0 && /* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground text-center py-4", children: "No models found for this provider. The catalog might be empty or still loading." })
|
|
7016
7303
|
] })
|
|
7017
|
-
] }) : /* @__PURE__ */
|
|
7018
|
-
/* @__PURE__ */
|
|
7019
|
-
/* @__PURE__ */
|
|
7304
|
+
] }) : /* @__PURE__ */ jsxs24("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
7305
|
+
/* @__PURE__ */ jsx29(Cpu5, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
|
|
7306
|
+
/* @__PURE__ */ jsx29("p", { children: "Select a provider first" })
|
|
7020
7307
|
] }) }),
|
|
7021
|
-
/* @__PURE__ */
|
|
7022
|
-
/* @__PURE__ */
|
|
7023
|
-
/* @__PURE__ */
|
|
7308
|
+
/* @__PURE__ */ jsxs24(TabsContent, { value: "connection", className: "space-y-4", children: [
|
|
7309
|
+
/* @__PURE__ */ jsxs24("div", { className: "space-y-3", children: [
|
|
7310
|
+
/* @__PURE__ */ jsxs24(
|
|
7024
7311
|
"label",
|
|
7025
7312
|
{
|
|
7026
7313
|
htmlFor: "websocket-url",
|
|
7027
7314
|
className: "text-sm font-medium flex items-center gap-2",
|
|
7028
7315
|
children: [
|
|
7029
|
-
/* @__PURE__ */
|
|
7316
|
+
/* @__PURE__ */ jsx29(Globe2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7030
7317
|
"WebSocket Server URL"
|
|
7031
7318
|
]
|
|
7032
7319
|
}
|
|
7033
7320
|
),
|
|
7034
|
-
/* @__PURE__ */
|
|
7321
|
+
/* @__PURE__ */ jsx29(
|
|
7035
7322
|
Input,
|
|
7036
7323
|
{
|
|
7037
7324
|
id: "websocket-url",
|
|
@@ -7041,70 +7328,70 @@ function SettingsPanel() {
|
|
|
7041
7328
|
className: "font-mono text-sm"
|
|
7042
7329
|
}
|
|
7043
7330
|
),
|
|
7044
|
-
/* @__PURE__ */
|
|
7331
|
+
/* @__PURE__ */ jsx29("p", { className: "text-xs text-muted-foreground", children: "URL of the WrongStack WebSocket server. The server runs alongside the CLI." })
|
|
7045
7332
|
] }),
|
|
7046
|
-
/* @__PURE__ */
|
|
7047
|
-
/* @__PURE__ */
|
|
7048
|
-
/* @__PURE__ */
|
|
7333
|
+
/* @__PURE__ */ jsxs24("div", { className: "p-4 rounded-lg border bg-muted/50", children: [
|
|
7334
|
+
/* @__PURE__ */ jsx29("h4", { className: "text-sm font-medium mb-2", children: "Starting the WebSocket Server" }),
|
|
7335
|
+
/* @__PURE__ */ jsxs24("p", { className: "text-xs text-muted-foreground mb-3", children: [
|
|
7049
7336
|
"Standalone: run ",
|
|
7050
|
-
/* @__PURE__ */
|
|
7337
|
+
/* @__PURE__ */ jsx29("code", { className: "bg-muted px-1 py-0.5 rounded", children: "./dev.ps1" }),
|
|
7051
7338
|
" ",
|
|
7052
7339
|
"from the repo root, or set WS_HOST/WS_PORT before launching",
|
|
7053
7340
|
" ",
|
|
7054
|
-
/* @__PURE__ */
|
|
7341
|
+
/* @__PURE__ */ jsx29("code", { className: "bg-muted px-1 py-0.5 rounded", children: "node packages/webui/dist/server/entry.js" }),
|
|
7055
7342
|
". Or alongside the CLI:",
|
|
7056
7343
|
" ",
|
|
7057
|
-
/* @__PURE__ */
|
|
7344
|
+
/* @__PURE__ */ jsx29("code", { className: "bg-muted px-1 py-0.5 rounded", children: "wstack --webui" }),
|
|
7058
7345
|
"."
|
|
7059
7346
|
] })
|
|
7060
7347
|
] })
|
|
7061
7348
|
] }),
|
|
7062
|
-
/* @__PURE__ */
|
|
7063
|
-
/* @__PURE__ */
|
|
7064
|
-
/* @__PURE__ */
|
|
7065
|
-
/* @__PURE__ */
|
|
7066
|
-
/* @__PURE__ */
|
|
7349
|
+
/* @__PURE__ */ jsxs24(TabsContent, { value: "appearance", className: "space-y-4", children: [
|
|
7350
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
7351
|
+
/* @__PURE__ */ jsx29("h3", { className: "text-sm font-semibold mb-3", children: "Theme" }),
|
|
7352
|
+
/* @__PURE__ */ jsxs24("div", { className: "grid grid-cols-3 gap-2 max-w-md", children: [
|
|
7353
|
+
/* @__PURE__ */ jsxs24(
|
|
7067
7354
|
Button,
|
|
7068
7355
|
{
|
|
7069
7356
|
variant: theme === "light" ? "default" : "outline",
|
|
7070
7357
|
size: "sm",
|
|
7071
7358
|
onClick: () => setTheme("light"),
|
|
7072
7359
|
children: [
|
|
7073
|
-
/* @__PURE__ */
|
|
7360
|
+
/* @__PURE__ */ jsx29(Sun3, { className: "h-4 w-4 mr-1" }),
|
|
7074
7361
|
"Light"
|
|
7075
7362
|
]
|
|
7076
7363
|
}
|
|
7077
7364
|
),
|
|
7078
|
-
/* @__PURE__ */
|
|
7365
|
+
/* @__PURE__ */ jsxs24(
|
|
7079
7366
|
Button,
|
|
7080
7367
|
{
|
|
7081
7368
|
variant: theme === "dark" ? "default" : "outline",
|
|
7082
7369
|
size: "sm",
|
|
7083
7370
|
onClick: () => setTheme("dark"),
|
|
7084
7371
|
children: [
|
|
7085
|
-
/* @__PURE__ */
|
|
7372
|
+
/* @__PURE__ */ jsx29(Moon3, { className: "h-4 w-4 mr-1" }),
|
|
7086
7373
|
"Dark"
|
|
7087
7374
|
]
|
|
7088
7375
|
}
|
|
7089
7376
|
),
|
|
7090
|
-
/* @__PURE__ */
|
|
7377
|
+
/* @__PURE__ */ jsxs24(
|
|
7091
7378
|
Button,
|
|
7092
7379
|
{
|
|
7093
7380
|
variant: theme === "system" ? "default" : "outline",
|
|
7094
7381
|
size: "sm",
|
|
7095
7382
|
onClick: () => setTheme("system"),
|
|
7096
7383
|
children: [
|
|
7097
|
-
/* @__PURE__ */
|
|
7384
|
+
/* @__PURE__ */ jsx29(Monitor3, { className: "h-4 w-4 mr-1" }),
|
|
7098
7385
|
"System"
|
|
7099
7386
|
]
|
|
7100
7387
|
}
|
|
7101
7388
|
)
|
|
7102
7389
|
] }),
|
|
7103
|
-
/* @__PURE__ */
|
|
7390
|
+
/* @__PURE__ */ jsx29("p", { className: "text-xs text-muted-foreground mt-2", children: "System follows your OS-level light/dark preference." })
|
|
7104
7391
|
] }),
|
|
7105
|
-
/* @__PURE__ */
|
|
7106
|
-
/* @__PURE__ */
|
|
7107
|
-
/* @__PURE__ */
|
|
7392
|
+
/* @__PURE__ */ jsxs24("div", { className: "pt-2 border-t", children: [
|
|
7393
|
+
/* @__PURE__ */ jsx29("h3", { className: "text-sm font-semibold mb-3 mt-3", children: "Preferences" }),
|
|
7394
|
+
/* @__PURE__ */ jsx29(
|
|
7108
7395
|
PreferenceToggle,
|
|
7109
7396
|
{
|
|
7110
7397
|
label: "Compact density",
|
|
@@ -7113,7 +7400,7 @@ function SettingsPanel() {
|
|
|
7113
7400
|
onChange: () => useUIStore.getState().toggleCompactMode()
|
|
7114
7401
|
}
|
|
7115
7402
|
),
|
|
7116
|
-
/* @__PURE__ */
|
|
7403
|
+
/* @__PURE__ */ jsx29(
|
|
7117
7404
|
PreferenceToggle,
|
|
7118
7405
|
{
|
|
7119
7406
|
label: "Sound on completion",
|
|
@@ -7147,12 +7434,12 @@ function PreferenceToggle({
|
|
|
7147
7434
|
}
|
|
7148
7435
|
}
|
|
7149
7436
|
};
|
|
7150
|
-
return /* @__PURE__ */
|
|
7151
|
-
/* @__PURE__ */
|
|
7152
|
-
/* @__PURE__ */
|
|
7153
|
-
hint && /* @__PURE__ */
|
|
7437
|
+
return /* @__PURE__ */ jsxs24("div", { className: "flex items-start justify-between gap-3 py-2", children: [
|
|
7438
|
+
/* @__PURE__ */ jsxs24("div", { className: "min-w-0 flex-1", children: [
|
|
7439
|
+
/* @__PURE__ */ jsx29("div", { className: "text-sm font-medium", children: label }),
|
|
7440
|
+
hint && /* @__PURE__ */ jsx29("div", { className: "text-xs text-muted-foreground mt-0.5", children: hint })
|
|
7154
7441
|
] }),
|
|
7155
|
-
/* @__PURE__ */
|
|
7442
|
+
/* @__PURE__ */ jsx29(
|
|
7156
7443
|
"button",
|
|
7157
7444
|
{
|
|
7158
7445
|
type: "button",
|
|
@@ -7163,7 +7450,7 @@ function PreferenceToggle({
|
|
|
7163
7450
|
"shrink-0 relative inline-flex h-5 w-9 rounded-full border transition-colors",
|
|
7164
7451
|
on ? "bg-primary border-primary" : "bg-muted border-input hover:bg-muted/80"
|
|
7165
7452
|
),
|
|
7166
|
-
children: /* @__PURE__ */
|
|
7453
|
+
children: /* @__PURE__ */ jsx29(
|
|
7167
7454
|
"span",
|
|
7168
7455
|
{
|
|
7169
7456
|
className: cn(
|
|
@@ -7180,7 +7467,7 @@ function PreferenceToggle({
|
|
|
7180
7467
|
// src/components/ShortcutsOverlay.tsx
|
|
7181
7468
|
import { Keyboard as Keyboard2, X as X6 } from "lucide-react";
|
|
7182
7469
|
import { useEffect as useEffect19 } from "react";
|
|
7183
|
-
import { jsx as
|
|
7470
|
+
import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
7184
7471
|
var SHORTCUTS = [
|
|
7185
7472
|
{
|
|
7186
7473
|
section: "Global",
|
|
@@ -7249,7 +7536,7 @@ function ShortcutsOverlay() {
|
|
|
7249
7536
|
return () => window.removeEventListener("keydown", onKey);
|
|
7250
7537
|
}, [setOpen]);
|
|
7251
7538
|
if (!open) return null;
|
|
7252
|
-
return /* @__PURE__ */
|
|
7539
|
+
return /* @__PURE__ */ jsx30(
|
|
7253
7540
|
"div",
|
|
7254
7541
|
{
|
|
7255
7542
|
className: "fixed inset-0 z-50 bg-background/60 backdrop-blur-sm flex items-center justify-center px-4",
|
|
@@ -7257,49 +7544,49 @@ function ShortcutsOverlay() {
|
|
|
7257
7544
|
onKeyDown: (e) => {
|
|
7258
7545
|
if (e.key === "Escape") setOpen(false);
|
|
7259
7546
|
},
|
|
7260
|
-
children: /* @__PURE__ */
|
|
7547
|
+
children: /* @__PURE__ */ jsxs25(
|
|
7261
7548
|
"div",
|
|
7262
7549
|
{
|
|
7263
7550
|
onClick: (e) => e.stopPropagation(),
|
|
7264
7551
|
onKeyDown: (e) => e.stopPropagation(),
|
|
7265
7552
|
className: "w-full max-w-2xl rounded-xl border bg-popover shadow-2xl overflow-hidden flex flex-col max-h-[80vh]",
|
|
7266
7553
|
children: [
|
|
7267
|
-
/* @__PURE__ */
|
|
7268
|
-
/* @__PURE__ */
|
|
7269
|
-
/* @__PURE__ */
|
|
7270
|
-
/* @__PURE__ */
|
|
7554
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between px-5 py-4 border-b", children: [
|
|
7555
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2", children: [
|
|
7556
|
+
/* @__PURE__ */ jsx30(Keyboard2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7557
|
+
/* @__PURE__ */ jsx30("h2", { className: "text-sm font-semibold", children: "Keyboard shortcuts" })
|
|
7271
7558
|
] }),
|
|
7272
|
-
/* @__PURE__ */
|
|
7559
|
+
/* @__PURE__ */ jsx30(
|
|
7273
7560
|
"button",
|
|
7274
7561
|
{
|
|
7275
7562
|
type: "button",
|
|
7276
7563
|
onClick: () => setOpen(false),
|
|
7277
7564
|
className: "text-muted-foreground hover:text-foreground p-1 rounded hover:bg-muted",
|
|
7278
|
-
children: /* @__PURE__ */
|
|
7565
|
+
children: /* @__PURE__ */ jsx30(X6, { className: "h-4 w-4" })
|
|
7279
7566
|
}
|
|
7280
7567
|
)
|
|
7281
7568
|
] }),
|
|
7282
|
-
/* @__PURE__ */
|
|
7283
|
-
/* @__PURE__ */
|
|
7284
|
-
/* @__PURE__ */
|
|
7569
|
+
/* @__PURE__ */ jsx30("div", { className: "overflow-y-auto px-5 py-4 space-y-6", children: SHORTCUTS.map((group) => /* @__PURE__ */ jsxs25("div", { children: [
|
|
7570
|
+
/* @__PURE__ */ jsx30("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground mb-2", children: group.section }),
|
|
7571
|
+
/* @__PURE__ */ jsx30("div", { className: "grid grid-cols-1 gap-1.5", children: group.items.map((s) => /* @__PURE__ */ jsxs25(
|
|
7285
7572
|
"div",
|
|
7286
7573
|
{
|
|
7287
7574
|
className: "flex items-center justify-between gap-3 text-sm px-2 py-1.5 rounded hover:bg-muted/40",
|
|
7288
7575
|
children: [
|
|
7289
|
-
/* @__PURE__ */
|
|
7290
|
-
/* @__PURE__ */
|
|
7291
|
-
ki > 0 && /* @__PURE__ */
|
|
7292
|
-
/* @__PURE__ */
|
|
7576
|
+
/* @__PURE__ */ jsx30("span", { className: "text-foreground/80", children: s.description }),
|
|
7577
|
+
/* @__PURE__ */ jsx30("span", { className: "flex items-center gap-1 shrink-0", children: s.keys.map((k, ki) => /* @__PURE__ */ jsxs25("span", { className: "flex items-center gap-1", children: [
|
|
7578
|
+
ki > 0 && /* @__PURE__ */ jsx30("span", { className: "text-muted-foreground/40 text-xs", children: "+" }),
|
|
7579
|
+
/* @__PURE__ */ jsx30("kbd", { className: "font-mono text-[10px] border rounded px-1.5 py-0.5 bg-background", children: k })
|
|
7293
7580
|
] }, k)) })
|
|
7294
7581
|
]
|
|
7295
7582
|
},
|
|
7296
7583
|
s.description
|
|
7297
7584
|
)) })
|
|
7298
7585
|
] }, group.section)) }),
|
|
7299
|
-
/* @__PURE__ */
|
|
7586
|
+
/* @__PURE__ */ jsxs25("div", { className: "border-t px-5 py-3 text-xs text-muted-foreground", children: [
|
|
7300
7587
|
"Press",
|
|
7301
7588
|
" ",
|
|
7302
|
-
/* @__PURE__ */
|
|
7589
|
+
/* @__PURE__ */ jsx30("kbd", { className: "font-mono text-[10px] border rounded px-1 py-0.5 bg-background", children: "?" }),
|
|
7303
7590
|
" ",
|
|
7304
7591
|
"any time to reopen this list."
|
|
7305
7592
|
] })
|
|
@@ -7331,10 +7618,10 @@ import {
|
|
|
7331
7618
|
Wifi as Wifi2,
|
|
7332
7619
|
WifiOff as WifiOff3,
|
|
7333
7620
|
X as X7,
|
|
7334
|
-
Zap as
|
|
7621
|
+
Zap as Zap4
|
|
7335
7622
|
} from "lucide-react";
|
|
7336
|
-
import { useEffect as useEffect20, useState as
|
|
7337
|
-
import { Fragment as Fragment8, jsx as
|
|
7623
|
+
import { useEffect as useEffect20, useState as useState20 } from "react";
|
|
7624
|
+
import { Fragment as Fragment8, jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
7338
7625
|
function Sidebar() {
|
|
7339
7626
|
const { toggleSidebar, currentView, setCurrentView } = useUIStore();
|
|
7340
7627
|
const sidebarWidth = useUIStore((s) => s.sidebarWidth);
|
|
@@ -7343,13 +7630,13 @@ function Sidebar() {
|
|
|
7343
7630
|
const { messages, clearMessages } = useChatStore();
|
|
7344
7631
|
const pinnedIds = useUIStore((s) => s.pinnedIds);
|
|
7345
7632
|
const unpinAll = useUIStore((s) => s.unpinAll);
|
|
7346
|
-
const [historyQuery, setHistoryQuery] =
|
|
7633
|
+
const [historyQuery, setHistoryQuery] = useState20("");
|
|
7347
7634
|
const favoriteSessionIds = useUIStore((s) => s.favoriteSessionIds);
|
|
7348
7635
|
const toggleFavoriteSession = useUIStore((s) => s.toggleFavoriteSession);
|
|
7349
7636
|
const sessionNicknames = useUIStore((s) => s.sessionNicknames);
|
|
7350
7637
|
const setSessionNickname = useUIStore((s) => s.setSessionNickname);
|
|
7351
|
-
const [renamingId, setRenamingId] =
|
|
7352
|
-
const [renameDraft, setRenameDraft] =
|
|
7638
|
+
const [renamingId, setRenamingId] = useState20(null);
|
|
7639
|
+
const [renameDraft, setRenameDraft] = useState20("");
|
|
7353
7640
|
const pinnedRows = pinnedIds.map((id) => messages.find((m) => m.id === id)).filter((m) => !!m && m.content.length > 0);
|
|
7354
7641
|
const { wsConnected, wsUrl, provider, model } = useConfigStore();
|
|
7355
7642
|
const {
|
|
@@ -7446,13 +7733,13 @@ function Sidebar() {
|
|
|
7446
7733
|
document.body.style.cursor = "col-resize";
|
|
7447
7734
|
document.body.style.userSelect = "none";
|
|
7448
7735
|
};
|
|
7449
|
-
return /* @__PURE__ */
|
|
7736
|
+
return /* @__PURE__ */ jsxs26(
|
|
7450
7737
|
"aside",
|
|
7451
7738
|
{
|
|
7452
7739
|
style: { width: `${sidebarWidth}px` },
|
|
7453
7740
|
className: "relative border-r bg-card flex flex-col shrink-0",
|
|
7454
7741
|
children: [
|
|
7455
|
-
/* @__PURE__ */
|
|
7742
|
+
/* @__PURE__ */ jsxs26(
|
|
7456
7743
|
"div",
|
|
7457
7744
|
{
|
|
7458
7745
|
onMouseDown: startDrag,
|
|
@@ -7460,56 +7747,70 @@ function Sidebar() {
|
|
|
7460
7747
|
className: "group/handle absolute top-0 right-0 h-full w-2 cursor-col-resize z-10 flex items-center justify-end",
|
|
7461
7748
|
title: "Drag to resize \xB7 double-click to reset",
|
|
7462
7749
|
children: [
|
|
7463
|
-
/* @__PURE__ */
|
|
7464
|
-
/* @__PURE__ */
|
|
7465
|
-
/* @__PURE__ */
|
|
7466
|
-
/* @__PURE__ */
|
|
7467
|
-
/* @__PURE__ */
|
|
7750
|
+
/* @__PURE__ */ jsx31("div", { className: "h-full w-px bg-border group-hover/handle:bg-primary/60 group-hover/handle:w-0.5 transition-all" }),
|
|
7751
|
+
/* @__PURE__ */ jsxs26("div", { className: "absolute right-0 top-1/2 -translate-y-1/2 flex flex-col gap-0.5 opacity-0 group-hover/handle:opacity-100 transition-opacity pr-0.5", children: [
|
|
7752
|
+
/* @__PURE__ */ jsx31("span", { className: "h-1 w-1 rounded-full bg-primary/70" }),
|
|
7753
|
+
/* @__PURE__ */ jsx31("span", { className: "h-1 w-1 rounded-full bg-primary/70" }),
|
|
7754
|
+
/* @__PURE__ */ jsx31("span", { className: "h-1 w-1 rounded-full bg-primary/70" })
|
|
7468
7755
|
] })
|
|
7469
7756
|
]
|
|
7470
7757
|
}
|
|
7471
7758
|
),
|
|
7472
|
-
/* @__PURE__ */
|
|
7473
|
-
/* @__PURE__ */
|
|
7474
|
-
/* @__PURE__ */
|
|
7475
|
-
/* @__PURE__ */
|
|
7759
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between px-4 py-3 border-b", children: [
|
|
7760
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2.5", children: [
|
|
7761
|
+
/* @__PURE__ */ jsx31("div", { className: "relative w-7 h-7 rounded-md bg-primary flex items-center justify-center shadow-[0_0_0_1px_hsl(var(--primary)/0.4),0_2px_8px_-2px_hsl(var(--primary)/0.5)]", children: /* @__PURE__ */ jsx31(Zap4, { className: "h-4 w-4 text-primary-foreground", strokeWidth: 2.4 }) }),
|
|
7762
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex flex-col leading-none", children: [
|
|
7763
|
+
/* @__PURE__ */ jsx31("span", { className: "text-sm font-semibold tracking-tight", children: "WrongStack" }),
|
|
7764
|
+
/* @__PURE__ */ jsxs26("span", { className: "flex items-center gap-1 text-[10px] text-muted-foreground mt-0.5", children: [
|
|
7765
|
+
/* @__PURE__ */ jsx31(
|
|
7766
|
+
"span",
|
|
7767
|
+
{
|
|
7768
|
+
className: cn(
|
|
7769
|
+
"led",
|
|
7770
|
+
wsConnected ? "text-[hsl(var(--success))] led-pulse" : "text-[hsl(var(--warning))]"
|
|
7771
|
+
)
|
|
7772
|
+
}
|
|
7773
|
+
),
|
|
7774
|
+
/* @__PURE__ */ jsx31("span", { className: "tabular font-medium uppercase tracking-wider", children: wsConnected ? "online" : "offline" })
|
|
7775
|
+
] })
|
|
7776
|
+
] })
|
|
7476
7777
|
] }),
|
|
7477
|
-
/* @__PURE__ */
|
|
7778
|
+
/* @__PURE__ */ jsx31(Button, { variant: "ghost", size: "icon", onClick: toggleSidebar, title: "Collapse sidebar (Ctrl+\\\\)", children: /* @__PURE__ */ jsx31(PanelLeftClose, { className: "h-4 w-4" }) })
|
|
7478
7779
|
] }),
|
|
7479
|
-
/* @__PURE__ */
|
|
7780
|
+
/* @__PURE__ */ jsxs26(
|
|
7480
7781
|
Tabs,
|
|
7481
7782
|
{
|
|
7482
7783
|
value: currentView === "settings" ? "chat" : currentView,
|
|
7483
7784
|
onValueChange: (v) => setCurrentView(v),
|
|
7484
7785
|
className: "flex-1 flex flex-col",
|
|
7485
7786
|
children: [
|
|
7486
|
-
/* @__PURE__ */
|
|
7487
|
-
/* @__PURE__ */
|
|
7787
|
+
/* @__PURE__ */ jsxs26(TabsList, { className: "w-full rounded-none bg-transparent p-2 h-auto grid grid-cols-2", children: [
|
|
7788
|
+
/* @__PURE__ */ jsxs26(
|
|
7488
7789
|
TabsTrigger,
|
|
7489
7790
|
{
|
|
7490
7791
|
value: "chat",
|
|
7491
7792
|
className: "flex-col gap-1.5 py-2 data-[state=active]:bg-primary/10",
|
|
7492
7793
|
children: [
|
|
7493
|
-
/* @__PURE__ */
|
|
7494
|
-
/* @__PURE__ */
|
|
7794
|
+
/* @__PURE__ */ jsx31(MessageSquare, { className: "h-4 w-4" }),
|
|
7795
|
+
/* @__PURE__ */ jsx31("span", { className: "text-xs", children: "Chat" })
|
|
7495
7796
|
]
|
|
7496
7797
|
}
|
|
7497
7798
|
),
|
|
7498
|
-
/* @__PURE__ */
|
|
7799
|
+
/* @__PURE__ */ jsxs26(
|
|
7499
7800
|
TabsTrigger,
|
|
7500
7801
|
{
|
|
7501
7802
|
value: "history",
|
|
7502
7803
|
className: "flex-col gap-1.5 py-2 data-[state=active]:bg-primary/10",
|
|
7503
7804
|
children: [
|
|
7504
|
-
/* @__PURE__ */
|
|
7505
|
-
/* @__PURE__ */
|
|
7805
|
+
/* @__PURE__ */ jsx31(History, { className: "h-4 w-4" }),
|
|
7806
|
+
/* @__PURE__ */ jsx31("span", { className: "text-xs", children: "History" })
|
|
7506
7807
|
]
|
|
7507
7808
|
}
|
|
7508
7809
|
)
|
|
7509
7810
|
] }),
|
|
7510
|
-
/* @__PURE__ */
|
|
7511
|
-
/* @__PURE__ */
|
|
7512
|
-
/* @__PURE__ */
|
|
7811
|
+
/* @__PURE__ */ jsxs26(TabsContent, { value: "chat", className: "flex-1 flex flex-col m-0 overflow-hidden", children: [
|
|
7812
|
+
/* @__PURE__ */ jsxs26("div", { className: "px-4 py-3 border-b", children: [
|
|
7813
|
+
/* @__PURE__ */ jsxs26(
|
|
7513
7814
|
"div",
|
|
7514
7815
|
{
|
|
7515
7816
|
className: cn(
|
|
@@ -7517,95 +7818,134 @@ function Sidebar() {
|
|
|
7517
7818
|
wsConnected ? "bg-green-500/10 text-green-600 dark:text-green-400" : "bg-yellow-500/10 text-yellow-600 dark:text-yellow-400"
|
|
7518
7819
|
),
|
|
7519
7820
|
children: [
|
|
7520
|
-
wsConnected ? /* @__PURE__ */
|
|
7521
|
-
/* @__PURE__ */
|
|
7821
|
+
wsConnected ? /* @__PURE__ */ jsx31(Wifi2, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx31(WifiOff3, { className: "h-4 w-4" }),
|
|
7822
|
+
/* @__PURE__ */ jsx31("span", { className: "font-medium", children: wsConnected ? "Connected" : "Disconnected" })
|
|
7522
7823
|
]
|
|
7523
7824
|
}
|
|
7524
7825
|
),
|
|
7525
|
-
/* @__PURE__ */
|
|
7826
|
+
/* @__PURE__ */ jsx31("div", { className: "text-xs text-muted-foreground mt-2 px-1 font-mono", children: wsUrl })
|
|
7526
7827
|
] }),
|
|
7527
|
-
/* @__PURE__ */
|
|
7828
|
+
/* @__PURE__ */ jsxs26(
|
|
7528
7829
|
"button",
|
|
7529
7830
|
{
|
|
7530
7831
|
type: "button",
|
|
7531
7832
|
onClick: () => setCurrentView("settings"),
|
|
7532
7833
|
className: "px-4 py-3 border-b text-left hover:bg-muted/40 transition-colors",
|
|
7533
7834
|
children: [
|
|
7534
|
-
/* @__PURE__ */
|
|
7535
|
-
/* @__PURE__ */
|
|
7536
|
-
/* @__PURE__ */
|
|
7537
|
-
/* @__PURE__ */
|
|
7538
|
-
/* @__PURE__ */
|
|
7835
|
+
/* @__PURE__ */ jsx31("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground mb-1", children: "Active model" }),
|
|
7836
|
+
/* @__PURE__ */ jsxs26("div", { className: "font-mono text-xs truncate", children: [
|
|
7837
|
+
/* @__PURE__ */ jsx31("span", { className: "text-muted-foreground", children: provider || "\u2014" }),
|
|
7838
|
+
/* @__PURE__ */ jsx31("span", { className: "text-muted-foreground/40 mx-1", children: "/" }),
|
|
7839
|
+
/* @__PURE__ */ jsx31("span", { className: "font-medium", children: model || "\u2014" })
|
|
7539
7840
|
] })
|
|
7540
7841
|
]
|
|
7541
7842
|
}
|
|
7542
7843
|
),
|
|
7543
|
-
/* @__PURE__ */
|
|
7544
|
-
/* @__PURE__ */
|
|
7545
|
-
/* @__PURE__ */
|
|
7844
|
+
/* @__PURE__ */ jsxs26("div", { className: "px-4 py-3 border-b space-y-3", children: [
|
|
7845
|
+
/* @__PURE__ */ jsxs26("h3", { className: "text-sm font-medium flex items-center gap-2", children: [
|
|
7846
|
+
/* @__PURE__ */ jsx31(Database2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7546
7847
|
"Session"
|
|
7547
7848
|
] }),
|
|
7548
|
-
/* @__PURE__ */
|
|
7549
|
-
/* @__PURE__ */
|
|
7550
|
-
/* @__PURE__ */
|
|
7551
|
-
/* @__PURE__ */
|
|
7849
|
+
/* @__PURE__ */ jsxs26("div", { className: "grid grid-cols-2 gap-2 text-xs", children: [
|
|
7850
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7851
|
+
/* @__PURE__ */ jsx31("span", { className: "text-muted-foreground", children: "Messages" }),
|
|
7852
|
+
/* @__PURE__ */ jsx31("span", { className: "text-lg font-semibold", children: messages.length })
|
|
7552
7853
|
] }),
|
|
7553
|
-
/* @__PURE__ */
|
|
7554
|
-
/* @__PURE__ */
|
|
7555
|
-
/* @__PURE__ */
|
|
7854
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7855
|
+
/* @__PURE__ */ jsx31("span", { className: "text-muted-foreground", children: "Duration" }),
|
|
7856
|
+
/* @__PURE__ */ jsx31("span", { className: "text-lg font-semibold", children: formatDuration2(session?.startedAt ?? null) })
|
|
7556
7857
|
] }),
|
|
7557
|
-
/* @__PURE__ */
|
|
7558
|
-
/* @__PURE__ */
|
|
7559
|
-
/* @__PURE__ */
|
|
7858
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7859
|
+
/* @__PURE__ */ jsx31("span", { className: "text-muted-foreground", children: "Input" }),
|
|
7860
|
+
/* @__PURE__ */ jsx31("span", { className: "text-lg font-semibold", children: totalTokens.input.toLocaleString() })
|
|
7560
7861
|
] }),
|
|
7561
|
-
/* @__PURE__ */
|
|
7562
|
-
/* @__PURE__ */
|
|
7563
|
-
/* @__PURE__ */
|
|
7862
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7863
|
+
/* @__PURE__ */ jsx31("span", { className: "text-muted-foreground", children: "Output" }),
|
|
7864
|
+
/* @__PURE__ */ jsx31("span", { className: "text-lg font-semibold", children: totalTokens.output.toLocaleString() })
|
|
7564
7865
|
] })
|
|
7565
7866
|
] }),
|
|
7566
|
-
cost > 0 && /* @__PURE__ */
|
|
7567
|
-
/* @__PURE__ */
|
|
7568
|
-
/* @__PURE__ */
|
|
7867
|
+
cost > 0 && /* @__PURE__ */ jsxs26("div", { className: "flex justify-between items-center p-2 rounded-lg bg-green-500/10", children: [
|
|
7868
|
+
/* @__PURE__ */ jsx31("span", { className: "text-sm text-muted-foreground", children: "Cost" }),
|
|
7869
|
+
/* @__PURE__ */ jsxs26("span", { className: "text-lg font-semibold text-green-600 dark:text-green-400", children: [
|
|
7569
7870
|
"$",
|
|
7570
7871
|
cost.toFixed(4)
|
|
7571
7872
|
] })
|
|
7572
7873
|
] })
|
|
7573
7874
|
] }),
|
|
7574
|
-
todos.length > 0 &&
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7875
|
+
todos.length > 0 && (() => {
|
|
7876
|
+
const done = todos.filter((t) => t.status === "completed").length;
|
|
7877
|
+
const running = todos.filter((t) => t.status === "in_progress").length;
|
|
7878
|
+
const pct = todos.length > 0 ? Math.round(done / todos.length * 100) : 0;
|
|
7879
|
+
const allDone = done === todos.length;
|
|
7880
|
+
return /* @__PURE__ */ jsxs26("div", { className: "px-4 py-3 border-b space-y-2.5", children: [
|
|
7881
|
+
/* @__PURE__ */ jsxs26("h3", { className: "text-sm font-medium flex items-center justify-between", children: [
|
|
7882
|
+
/* @__PURE__ */ jsxs26("span", { className: "flex items-center gap-2", children: [
|
|
7883
|
+
/* @__PURE__ */ jsx31(ListTodo, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7884
|
+
"Plan"
|
|
7885
|
+
] }),
|
|
7886
|
+
/* @__PURE__ */ jsxs26("span", { className: "tabular text-[10px] text-muted-foreground", children: [
|
|
7887
|
+
done,
|
|
7888
|
+
"/",
|
|
7889
|
+
todos.length
|
|
7890
|
+
] })
|
|
7579
7891
|
] }),
|
|
7580
|
-
/* @__PURE__ */
|
|
7581
|
-
|
|
7582
|
-
"/",
|
|
7583
|
-
todos.length
|
|
7584
|
-
] })
|
|
7585
|
-
] }),
|
|
7586
|
-
/* @__PURE__ */ jsx29("ul", { className: "space-y-1 max-h-48 overflow-y-auto pr-1", children: todos.map((t) => {
|
|
7587
|
-
const Icon2 = t.status === "completed" ? CheckCircle25 : t.status === "in_progress" ? CircleDot : Circle;
|
|
7588
|
-
const tone2 = t.status === "completed" ? "text-green-600 dark:text-green-400 line-through opacity-70" : t.status === "in_progress" ? "text-amber-600 dark:text-amber-400" : "text-muted-foreground";
|
|
7589
|
-
return /* @__PURE__ */ jsxs25(
|
|
7590
|
-
"li",
|
|
7892
|
+
/* @__PURE__ */ jsx31(
|
|
7893
|
+
"div",
|
|
7591
7894
|
{
|
|
7592
|
-
className: cn(
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
|
|
7601
|
-
|
|
7602
|
-
|
|
7603
|
-
|
|
7604
|
-
|
|
7605
|
-
|
|
7895
|
+
className: cn(
|
|
7896
|
+
"relative h-1.5 w-full overflow-hidden rounded-full bg-muted",
|
|
7897
|
+
running > 0 && "bar-sweep"
|
|
7898
|
+
),
|
|
7899
|
+
title: `${pct}% complete`,
|
|
7900
|
+
children: /* @__PURE__ */ jsx31(
|
|
7901
|
+
"div",
|
|
7902
|
+
{
|
|
7903
|
+
className: cn(
|
|
7904
|
+
"h-full rounded-full transition-all duration-500",
|
|
7905
|
+
allDone ? "bg-[hsl(var(--success))]" : "bg-primary"
|
|
7906
|
+
),
|
|
7907
|
+
style: { width: `${Math.max(pct, running > 0 ? 4 : 0)}%` }
|
|
7908
|
+
}
|
|
7909
|
+
)
|
|
7910
|
+
}
|
|
7911
|
+
),
|
|
7912
|
+
/* @__PURE__ */ jsx31("ul", { className: "space-y-0.5 max-h-56 overflow-y-auto pr-1 -mx-1", children: todos.map((t) => {
|
|
7913
|
+
const Icon2 = t.status === "completed" ? CheckCircle25 : t.status === "in_progress" ? CircleDot : Circle;
|
|
7914
|
+
const active = t.status === "in_progress";
|
|
7915
|
+
const tone2 = t.status === "completed" ? "text-[hsl(var(--success))] line-through opacity-60" : active ? "text-foreground" : "text-muted-foreground";
|
|
7916
|
+
return /* @__PURE__ */ jsxs26(
|
|
7917
|
+
"li",
|
|
7918
|
+
{
|
|
7919
|
+
className: cn(
|
|
7920
|
+
"flex items-start gap-2 text-xs leading-snug rounded-md px-1.5 py-1 transition-colors",
|
|
7921
|
+
active && "bg-primary/10 ring-1 ring-inset ring-primary/20",
|
|
7922
|
+
tone2
|
|
7923
|
+
),
|
|
7924
|
+
children: [
|
|
7925
|
+
/* @__PURE__ */ jsx31(
|
|
7926
|
+
Icon2,
|
|
7927
|
+
{
|
|
7928
|
+
className: cn(
|
|
7929
|
+
"h-3.5 w-3.5 mt-0.5 shrink-0",
|
|
7930
|
+
active && "text-primary animate-pulse"
|
|
7931
|
+
)
|
|
7932
|
+
}
|
|
7933
|
+
),
|
|
7934
|
+
/* @__PURE__ */ jsx31("span", { className: "break-words", children: active && t.activeForm ? t.activeForm : t.content })
|
|
7935
|
+
]
|
|
7936
|
+
},
|
|
7937
|
+
t.id
|
|
7938
|
+
);
|
|
7939
|
+
}) })
|
|
7940
|
+
] });
|
|
7941
|
+
})(),
|
|
7942
|
+
pinnedRows.length > 0 && /* @__PURE__ */ jsxs26("div", { className: "px-4 py-3 border-b space-y-2", children: [
|
|
7943
|
+
/* @__PURE__ */ jsxs26("h3", { className: "text-sm font-medium flex items-center justify-between", children: [
|
|
7944
|
+
/* @__PURE__ */ jsxs26("span", { className: "flex items-center gap-2", children: [
|
|
7945
|
+
/* @__PURE__ */ jsx31(Pin2, { className: "h-4 w-4 text-amber-500" }),
|
|
7606
7946
|
"Pinned"
|
|
7607
7947
|
] }),
|
|
7608
|
-
/* @__PURE__ */
|
|
7948
|
+
/* @__PURE__ */ jsx31(
|
|
7609
7949
|
"button",
|
|
7610
7950
|
{
|
|
7611
7951
|
type: "button",
|
|
@@ -7615,9 +7955,9 @@ function Sidebar() {
|
|
|
7615
7955
|
}
|
|
7616
7956
|
)
|
|
7617
7957
|
] }),
|
|
7618
|
-
/* @__PURE__ */
|
|
7958
|
+
/* @__PURE__ */ jsx31("ul", { className: "space-y-1 max-h-48 overflow-y-auto pr-1", children: pinnedRows.map((m) => {
|
|
7619
7959
|
const preview = m.content.replace(/\s+/g, " ").slice(0, 80);
|
|
7620
|
-
return /* @__PURE__ */
|
|
7960
|
+
return /* @__PURE__ */ jsx31("li", { children: /* @__PURE__ */ jsxs26(
|
|
7621
7961
|
"button",
|
|
7622
7962
|
{
|
|
7623
7963
|
type: "button",
|
|
@@ -7640,8 +7980,8 @@ function Sidebar() {
|
|
|
7640
7980
|
) }, m.id);
|
|
7641
7981
|
}) })
|
|
7642
7982
|
] }),
|
|
7643
|
-
/* @__PURE__ */
|
|
7644
|
-
/* @__PURE__ */
|
|
7983
|
+
/* @__PURE__ */ jsxs26("div", { className: "px-4 py-3 border-b space-y-2", children: [
|
|
7984
|
+
/* @__PURE__ */ jsxs26(
|
|
7645
7985
|
Button,
|
|
7646
7986
|
{
|
|
7647
7987
|
variant: "outline",
|
|
@@ -7652,12 +7992,12 @@ function Sidebar() {
|
|
|
7652
7992
|
client2?.clearContext?.();
|
|
7653
7993
|
},
|
|
7654
7994
|
children: [
|
|
7655
|
-
/* @__PURE__ */
|
|
7995
|
+
/* @__PURE__ */ jsx31(Trash23, { className: "h-4 w-4 mr-2" }),
|
|
7656
7996
|
"Clear context"
|
|
7657
7997
|
]
|
|
7658
7998
|
}
|
|
7659
7999
|
),
|
|
7660
|
-
/* @__PURE__ */
|
|
8000
|
+
/* @__PURE__ */ jsxs26(
|
|
7661
8001
|
Button,
|
|
7662
8002
|
{
|
|
7663
8003
|
variant: "outline",
|
|
@@ -7666,12 +8006,12 @@ function Sidebar() {
|
|
|
7666
8006
|
onClick: () => client2?.newSession?.(),
|
|
7667
8007
|
disabled: !wsConnected,
|
|
7668
8008
|
children: [
|
|
7669
|
-
/* @__PURE__ */
|
|
8009
|
+
/* @__PURE__ */ jsx31(RotateCcw5, { className: "h-4 w-4 mr-2" }),
|
|
7670
8010
|
"New session"
|
|
7671
8011
|
]
|
|
7672
8012
|
}
|
|
7673
8013
|
),
|
|
7674
|
-
/* @__PURE__ */
|
|
8014
|
+
/* @__PURE__ */ jsxs26(
|
|
7675
8015
|
Button,
|
|
7676
8016
|
{
|
|
7677
8017
|
variant: "outline",
|
|
@@ -7680,14 +8020,14 @@ function Sidebar() {
|
|
|
7680
8020
|
onClick: () => client2?.compactContext?.(),
|
|
7681
8021
|
disabled: !wsConnected,
|
|
7682
8022
|
children: [
|
|
7683
|
-
/* @__PURE__ */
|
|
8023
|
+
/* @__PURE__ */ jsx31(Database2, { className: "h-4 w-4 mr-2" }),
|
|
7684
8024
|
"Compact context"
|
|
7685
8025
|
]
|
|
7686
8026
|
}
|
|
7687
8027
|
)
|
|
7688
8028
|
] }),
|
|
7689
|
-
/* @__PURE__ */
|
|
7690
|
-
/* @__PURE__ */
|
|
8029
|
+
/* @__PURE__ */ jsx31("div", { className: "flex-1" }),
|
|
8030
|
+
/* @__PURE__ */ jsx31("div", { className: "px-3 py-3 border-t", children: /* @__PURE__ */ jsxs26(
|
|
7691
8031
|
Button,
|
|
7692
8032
|
{
|
|
7693
8033
|
variant: "ghost",
|
|
@@ -7695,16 +8035,16 @@ function Sidebar() {
|
|
|
7695
8035
|
className: "w-full justify-start",
|
|
7696
8036
|
onClick: () => setCurrentView("settings"),
|
|
7697
8037
|
children: [
|
|
7698
|
-
/* @__PURE__ */
|
|
8038
|
+
/* @__PURE__ */ jsx31(SettingsIcon2, { className: "h-4 w-4 mr-2" }),
|
|
7699
8039
|
"Settings"
|
|
7700
8040
|
]
|
|
7701
8041
|
}
|
|
7702
8042
|
) })
|
|
7703
8043
|
] }),
|
|
7704
|
-
/* @__PURE__ */
|
|
7705
|
-
/* @__PURE__ */
|
|
7706
|
-
/* @__PURE__ */
|
|
7707
|
-
/* @__PURE__ */
|
|
8044
|
+
/* @__PURE__ */ jsxs26(TabsContent, { value: "history", className: "flex-1 m-0 flex flex-col overflow-hidden", children: [
|
|
8045
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between px-4 py-2 border-b", children: [
|
|
8046
|
+
/* @__PURE__ */ jsx31("span", { className: "text-xs uppercase tracking-wider text-muted-foreground", children: "Recent sessions" }),
|
|
8047
|
+
/* @__PURE__ */ jsx31(
|
|
7708
8048
|
Button,
|
|
7709
8049
|
{
|
|
7710
8050
|
variant: "ghost",
|
|
@@ -7713,13 +8053,13 @@ function Sidebar() {
|
|
|
7713
8053
|
onClick: () => listSessions(50),
|
|
7714
8054
|
disabled: !wsConnected,
|
|
7715
8055
|
title: "Refresh",
|
|
7716
|
-
children: historyLoading ? /* @__PURE__ */
|
|
8056
|
+
children: historyLoading ? /* @__PURE__ */ jsx31(Loader25, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx31(RefreshCw3, { className: "h-3.5 w-3.5" })
|
|
7717
8057
|
}
|
|
7718
8058
|
)
|
|
7719
8059
|
] }),
|
|
7720
|
-
historyEntries.length > 3 && /* @__PURE__ */
|
|
7721
|
-
/* @__PURE__ */
|
|
7722
|
-
/* @__PURE__ */
|
|
8060
|
+
historyEntries.length > 3 && /* @__PURE__ */ jsx31("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ jsxs26("div", { className: "relative", children: [
|
|
8061
|
+
/* @__PURE__ */ jsx31(Search5, { className: "absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/60" }),
|
|
8062
|
+
/* @__PURE__ */ jsx31(
|
|
7723
8063
|
"input",
|
|
7724
8064
|
{
|
|
7725
8065
|
type: "text",
|
|
@@ -7729,28 +8069,28 @@ function Sidebar() {
|
|
|
7729
8069
|
className: "w-full pl-7 pr-7 py-1 text-xs rounded-md bg-muted/40 border border-transparent focus:bg-background focus:border-input focus:outline-none focus:ring-1 focus:ring-ring placeholder:text-muted-foreground/50"
|
|
7730
8070
|
}
|
|
7731
8071
|
),
|
|
7732
|
-
historyQuery && /* @__PURE__ */
|
|
8072
|
+
historyQuery && /* @__PURE__ */ jsx31(
|
|
7733
8073
|
"button",
|
|
7734
8074
|
{
|
|
7735
8075
|
type: "button",
|
|
7736
8076
|
onClick: () => setHistoryQuery(""),
|
|
7737
8077
|
className: "absolute right-1 top-1/2 -translate-y-1/2 text-muted-foreground/60 hover:text-foreground p-0.5",
|
|
7738
8078
|
title: "Clear filter",
|
|
7739
|
-
children: /* @__PURE__ */
|
|
8079
|
+
children: /* @__PURE__ */ jsx31(X7, { className: "h-3 w-3" })
|
|
7740
8080
|
}
|
|
7741
8081
|
)
|
|
7742
8082
|
] }) }),
|
|
7743
|
-
historyError && /* @__PURE__ */
|
|
7744
|
-
/* @__PURE__ */
|
|
7745
|
-
/* @__PURE__ */
|
|
7746
|
-
/* @__PURE__ */
|
|
7747
|
-
/* @__PURE__ */
|
|
7748
|
-
] }) : groupedHistory.length === 0 ? /* @__PURE__ */
|
|
7749
|
-
/* @__PURE__ */
|
|
7750
|
-
/* @__PURE__ */
|
|
7751
|
-
/* @__PURE__ */
|
|
7752
|
-
] }) : /* @__PURE__ */
|
|
7753
|
-
/* @__PURE__ */
|
|
8083
|
+
historyError && /* @__PURE__ */ jsx31("div", { className: "px-4 py-2 text-xs text-destructive bg-destructive/5 border-b", children: historyError }),
|
|
8084
|
+
/* @__PURE__ */ jsx31(ScrollArea, { className: "flex-1", children: historyEntries.length === 0 && !historyLoading ? /* @__PURE__ */ jsxs26("div", { className: "text-center text-muted-foreground py-8 px-4", children: [
|
|
8085
|
+
/* @__PURE__ */ jsx31(History, { className: "h-8 w-8 mx-auto mb-3 opacity-20" }),
|
|
8086
|
+
/* @__PURE__ */ jsx31("p", { className: "text-sm font-medium", children: "No history yet" }),
|
|
8087
|
+
/* @__PURE__ */ jsx31("p", { className: "text-xs mt-1", children: "Your conversations will appear here" })
|
|
8088
|
+
] }) : groupedHistory.length === 0 ? /* @__PURE__ */ jsxs26("div", { className: "text-center text-muted-foreground py-8 px-4", children: [
|
|
8089
|
+
/* @__PURE__ */ jsx31(Search5, { className: "h-8 w-8 mx-auto mb-3 opacity-20" }),
|
|
8090
|
+
/* @__PURE__ */ jsx31("p", { className: "text-sm font-medium", children: "No matches" }),
|
|
8091
|
+
/* @__PURE__ */ jsx31("p", { className: "text-xs mt-1", children: "Try a different filter" })
|
|
8092
|
+
] }) : /* @__PURE__ */ jsx31("div", { className: "p-2 space-y-3", children: groupedHistory.map((group) => /* @__PURE__ */ jsxs26("div", { className: "space-y-1", children: [
|
|
8093
|
+
/* @__PURE__ */ jsxs26(
|
|
7754
8094
|
"div",
|
|
7755
8095
|
{
|
|
7756
8096
|
className: cn(
|
|
@@ -7758,10 +8098,10 @@ function Sidebar() {
|
|
|
7758
8098
|
group.star ? "text-amber-500" : "text-muted-foreground/80"
|
|
7759
8099
|
),
|
|
7760
8100
|
children: [
|
|
7761
|
-
group.star && /* @__PURE__ */
|
|
8101
|
+
group.star && /* @__PURE__ */ jsx31(Star, { className: "h-3 w-3 fill-current" }),
|
|
7762
8102
|
group.label,
|
|
7763
8103
|
" ",
|
|
7764
|
-
/* @__PURE__ */
|
|
8104
|
+
/* @__PURE__ */ jsxs26("span", { className: "text-muted-foreground/50 font-normal normal-case ml-1", children: [
|
|
7765
8105
|
"(",
|
|
7766
8106
|
group.rows.length,
|
|
7767
8107
|
")"
|
|
@@ -7769,7 +8109,7 @@ function Sidebar() {
|
|
|
7769
8109
|
]
|
|
7770
8110
|
}
|
|
7771
8111
|
),
|
|
7772
|
-
group.rows.map((entry) => /* @__PURE__ */
|
|
8112
|
+
group.rows.map((entry) => /* @__PURE__ */ jsxs26(
|
|
7773
8113
|
"div",
|
|
7774
8114
|
{
|
|
7775
8115
|
className: cn(
|
|
@@ -7777,7 +8117,7 @@ function Sidebar() {
|
|
|
7777
8117
|
entry.isCurrent ? "bg-primary/5 border-primary/40" : "bg-card border-border/60 hover:bg-muted/40 hover:border-primary/40"
|
|
7778
8118
|
),
|
|
7779
8119
|
children: [
|
|
7780
|
-
/* @__PURE__ */
|
|
8120
|
+
/* @__PURE__ */ jsx31(
|
|
7781
8121
|
"button",
|
|
7782
8122
|
{
|
|
7783
8123
|
type: "button",
|
|
@@ -7789,8 +8129,8 @@ function Sidebar() {
|
|
|
7789
8129
|
setRenameDraft(sessionNicknames[entry.id] ?? entry.title ?? "");
|
|
7790
8130
|
},
|
|
7791
8131
|
className: "block w-full rounded-md px-3 py-2 pr-16 text-left disabled:cursor-default focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
7792
|
-
children: /* @__PURE__ */
|
|
7793
|
-
renamingId === entry.id ? /* @__PURE__ */
|
|
8132
|
+
children: /* @__PURE__ */ jsxs26("div", { className: "min-w-0 flex-1", children: [
|
|
8133
|
+
renamingId === entry.id ? /* @__PURE__ */ jsx31(
|
|
7794
8134
|
"input",
|
|
7795
8135
|
{
|
|
7796
8136
|
value: renameDraft,
|
|
@@ -7813,7 +8153,7 @@ function Sidebar() {
|
|
|
7813
8153
|
placeholder: entry.title || "Nickname",
|
|
7814
8154
|
className: "w-full text-sm bg-background border border-input rounded px-1.5 py-0.5 focus:outline-none focus:ring-1 focus:ring-ring"
|
|
7815
8155
|
}
|
|
7816
|
-
) : /* @__PURE__ */
|
|
8156
|
+
) : /* @__PURE__ */ jsx31(
|
|
7817
8157
|
"div",
|
|
7818
8158
|
{
|
|
7819
8159
|
className: "font-medium truncate text-foreground",
|
|
@@ -7823,30 +8163,30 @@ Double-click to rename`,
|
|
|
7823
8163
|
children: sessionNicknames[entry.id] || entry.title || "(empty)"
|
|
7824
8164
|
}
|
|
7825
8165
|
),
|
|
7826
|
-
/* @__PURE__ */
|
|
8166
|
+
/* @__PURE__ */ jsxs26("div", { className: "text-[10px] text-muted-foreground font-mono truncate mt-0.5", children: [
|
|
7827
8167
|
entry.provider,
|
|
7828
8168
|
"/",
|
|
7829
8169
|
entry.model
|
|
7830
8170
|
] }),
|
|
7831
|
-
/* @__PURE__ */
|
|
7832
|
-
/* @__PURE__ */
|
|
7833
|
-
entry.tokenTotal > 0 && /* @__PURE__ */
|
|
7834
|
-
/* @__PURE__ */
|
|
7835
|
-
/* @__PURE__ */
|
|
8171
|
+
/* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2 text-[10px] text-muted-foreground/80 mt-0.5", children: [
|
|
8172
|
+
/* @__PURE__ */ jsx31("span", { children: formatRelative(entry.startedAt) }),
|
|
8173
|
+
entry.tokenTotal > 0 && /* @__PURE__ */ jsxs26(Fragment8, { children: [
|
|
8174
|
+
/* @__PURE__ */ jsx31("span", { children: "\xB7" }),
|
|
8175
|
+
/* @__PURE__ */ jsxs26("span", { className: "tabular-nums", children: [
|
|
7836
8176
|
entry.tokenTotal.toLocaleString(),
|
|
7837
8177
|
" tok"
|
|
7838
8178
|
] })
|
|
7839
8179
|
] }),
|
|
7840
|
-
entry.isCurrent && /* @__PURE__ */
|
|
7841
|
-
/* @__PURE__ */
|
|
7842
|
-
/* @__PURE__ */
|
|
8180
|
+
entry.isCurrent && /* @__PURE__ */ jsxs26(Fragment8, { children: [
|
|
8181
|
+
/* @__PURE__ */ jsx31("span", { children: "\xB7" }),
|
|
8182
|
+
/* @__PURE__ */ jsx31("span", { className: "text-primary font-medium", children: "active" })
|
|
7843
8183
|
] })
|
|
7844
8184
|
] })
|
|
7845
8185
|
] })
|
|
7846
8186
|
}
|
|
7847
8187
|
),
|
|
7848
|
-
/* @__PURE__ */
|
|
7849
|
-
/* @__PURE__ */
|
|
8188
|
+
/* @__PURE__ */ jsxs26("div", { className: "absolute right-2 top-2 flex items-center gap-1", children: [
|
|
8189
|
+
/* @__PURE__ */ jsx31(
|
|
7850
8190
|
"button",
|
|
7851
8191
|
{
|
|
7852
8192
|
type: "button",
|
|
@@ -7856,7 +8196,7 @@ Double-click to rename`,
|
|
|
7856
8196
|
favoriteSessionIds.includes(entry.id) ? "opacity-100 text-amber-500" : "opacity-0 group-hover:opacity-100 text-muted-foreground"
|
|
7857
8197
|
),
|
|
7858
8198
|
title: favoriteSessionIds.includes(entry.id) ? "Unfavorite" : "Mark as favorite",
|
|
7859
|
-
children: /* @__PURE__ */
|
|
8199
|
+
children: /* @__PURE__ */ jsx31(
|
|
7860
8200
|
Star,
|
|
7861
8201
|
{
|
|
7862
8202
|
className: cn(
|
|
@@ -7867,7 +8207,7 @@ Double-click to rename`,
|
|
|
7867
8207
|
)
|
|
7868
8208
|
}
|
|
7869
8209
|
),
|
|
7870
|
-
!entry.isCurrent && /* @__PURE__ */
|
|
8210
|
+
!entry.isCurrent && /* @__PURE__ */ jsx31(
|
|
7871
8211
|
"button",
|
|
7872
8212
|
{
|
|
7873
8213
|
type: "button",
|
|
@@ -7878,7 +8218,7 @@ Double-click to rename`,
|
|
|
7878
8218
|
},
|
|
7879
8219
|
className: "opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-destructive",
|
|
7880
8220
|
title: "Delete session",
|
|
7881
|
-
children: /* @__PURE__ */
|
|
8221
|
+
children: /* @__PURE__ */ jsx31(Trash23, { className: "h-3.5 w-3.5" })
|
|
7882
8222
|
}
|
|
7883
8223
|
)
|
|
7884
8224
|
] })
|
|
@@ -7897,7 +8237,7 @@ Double-click to rename`,
|
|
|
7897
8237
|
}
|
|
7898
8238
|
|
|
7899
8239
|
// src/App.tsx
|
|
7900
|
-
import { Fragment as Fragment9, jsx as
|
|
8240
|
+
import { Fragment as Fragment9, jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
7901
8241
|
function AppInner() {
|
|
7902
8242
|
const { theme } = useTheme();
|
|
7903
8243
|
const { currentView, sidebarOpen, toggleSidebar, setSearchOpen, setSidebarOpen } = useUIStore();
|
|
@@ -8033,30 +8373,33 @@ function AppInner() {
|
|
|
8033
8373
|
window.addEventListener("keydown", onKey);
|
|
8034
8374
|
return () => window.removeEventListener("keydown", onKey);
|
|
8035
8375
|
}, [toggleSidebar, setSearchOpen]);
|
|
8036
|
-
return /* @__PURE__ */
|
|
8037
|
-
sidebarOpen && /* @__PURE__ */
|
|
8038
|
-
/* @__PURE__ */
|
|
8039
|
-
/* @__PURE__ */
|
|
8040
|
-
currentView === "chat" && /* @__PURE__ */
|
|
8041
|
-
sessionId && /* @__PURE__ */
|
|
8042
|
-
|
|
8376
|
+
return /* @__PURE__ */ jsxs27("div", { className: cn("flex h-screen", theme), children: [
|
|
8377
|
+
sidebarOpen && /* @__PURE__ */ jsx32(Sidebar, {}),
|
|
8378
|
+
/* @__PURE__ */ jsxs27("main", { className: "flex-1 flex flex-col overflow-hidden", children: [
|
|
8379
|
+
/* @__PURE__ */ jsx32(ConnectionBanner, {}),
|
|
8380
|
+
currentView === "chat" && /* @__PURE__ */ jsxs27(Fragment9, { children: [
|
|
8381
|
+
sessionId && /* @__PURE__ */ jsxs27("div", { className: "px-4 pt-2 space-y-2", children: [
|
|
8382
|
+
/* @__PURE__ */ jsx32(CollabPanel, { sessionId }),
|
|
8383
|
+
/* @__PURE__ */ jsx32(FleetPanel, {})
|
|
8384
|
+
] }),
|
|
8385
|
+
/* @__PURE__ */ jsx32(ChatView, {})
|
|
8043
8386
|
] }),
|
|
8044
|
-
currentView === "settings" && /* @__PURE__ */
|
|
8387
|
+
currentView === "settings" && /* @__PURE__ */ jsx32(SettingsPanel, {})
|
|
8045
8388
|
] }),
|
|
8046
|
-
/* @__PURE__ */
|
|
8047
|
-
/* @__PURE__ */
|
|
8048
|
-
/* @__PURE__ */
|
|
8049
|
-
/* @__PURE__ */
|
|
8050
|
-
/* @__PURE__ */
|
|
8389
|
+
/* @__PURE__ */ jsx32(ConfirmDialog, {}),
|
|
8390
|
+
/* @__PURE__ */ jsx32(CommandPalette, {}),
|
|
8391
|
+
/* @__PURE__ */ jsx32(ShortcutsOverlay, {}),
|
|
8392
|
+
/* @__PURE__ */ jsx32(QuickModelSwitcher, {}),
|
|
8393
|
+
/* @__PURE__ */ jsx32(Toaster, {})
|
|
8051
8394
|
] });
|
|
8052
8395
|
}
|
|
8053
8396
|
function App() {
|
|
8054
|
-
return /* @__PURE__ */
|
|
8397
|
+
return /* @__PURE__ */ jsx32(ErrorBoundary, { children: /* @__PURE__ */ jsx32(ThemeProvider, { defaultTheme: "system", children: /* @__PURE__ */ jsx32(AppInner, {}) }) });
|
|
8055
8398
|
}
|
|
8056
8399
|
|
|
8057
8400
|
// src/main.tsx
|
|
8058
|
-
import { jsx as
|
|
8401
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
8059
8402
|
ReactDOM.createRoot(document.getElementById("root")).render(
|
|
8060
|
-
/* @__PURE__ */
|
|
8403
|
+
/* @__PURE__ */ jsx33(React6.StrictMode, { children: /* @__PURE__ */ jsx33(App, {}) })
|
|
8061
8404
|
);
|
|
8062
8405
|
//# sourceMappingURL=index.js.map
|