@wrongstack/webui 0.2.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index-CJmc6zwr.js +94 -0
- package/dist/assets/{index-CRAjL4S_.css → index-TCwASaz8.css} +1 -1
- package/dist/assets/vendor-Dff2jyfM.js +521 -0
- package/dist/index.css +14 -0
- package/dist/index.css.map +1 -1
- package/dist/index.html +3 -2
- package/dist/index.js +1054 -899
- package/dist/index.js.map +1 -1
- package/dist/server/entry.js +137 -51
- package/dist/server/entry.js.map +1 -1
- package/dist/server/index.js +137 -51
- package/dist/server/index.js.map +1 -1
- package/package.json +21 -14
- package/dist/assets/index-C1jTV4WR.js +0 -609
package/dist/index.js
CHANGED
|
@@ -1,57 +1,3 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __esm = (fn, res) => function __init() {
|
|
4
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
5
|
-
};
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
// src/lib/chime.ts
|
|
12
|
-
var chime_exports = {};
|
|
13
|
-
__export(chime_exports, {
|
|
14
|
-
playCompletionChime: () => playCompletionChime
|
|
15
|
-
});
|
|
16
|
-
function audio() {
|
|
17
|
-
if (typeof window === "undefined") return null;
|
|
18
|
-
if (ctx) return ctx;
|
|
19
|
-
const Cls = window.AudioContext || window.webkitAudioContext;
|
|
20
|
-
if (!Cls) return null;
|
|
21
|
-
try {
|
|
22
|
-
ctx = new Cls();
|
|
23
|
-
} catch {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
26
|
-
return ctx;
|
|
27
|
-
}
|
|
28
|
-
function tone(freq, startAt, durSec) {
|
|
29
|
-
const ac = audio();
|
|
30
|
-
if (!ac) return;
|
|
31
|
-
const t = ac.currentTime + startAt;
|
|
32
|
-
const osc = ac.createOscillator();
|
|
33
|
-
const gain = ac.createGain();
|
|
34
|
-
osc.type = "sine";
|
|
35
|
-
osc.frequency.value = freq;
|
|
36
|
-
gain.gain.setValueAtTime(0, t);
|
|
37
|
-
gain.gain.linearRampToValueAtTime(0.18, t + 0.01);
|
|
38
|
-
gain.gain.exponentialRampToValueAtTime(1e-4, t + durSec);
|
|
39
|
-
osc.connect(gain).connect(ac.destination);
|
|
40
|
-
osc.start(t);
|
|
41
|
-
osc.stop(t + durSec + 0.02);
|
|
42
|
-
}
|
|
43
|
-
function playCompletionChime() {
|
|
44
|
-
tone(659.25, 0, 0.18);
|
|
45
|
-
tone(880, 0.12, 0.24);
|
|
46
|
-
}
|
|
47
|
-
var ctx;
|
|
48
|
-
var init_chime = __esm({
|
|
49
|
-
"src/lib/chime.ts"() {
|
|
50
|
-
"use strict";
|
|
51
|
-
ctx = null;
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
1
|
// src/main.tsx
|
|
56
2
|
import React7 from "react";
|
|
57
3
|
import ReactDOM from "react-dom/client";
|
|
@@ -129,8 +75,39 @@ function Toaster() {
|
|
|
129
75
|
return /* @__PURE__ */ jsx("div", { className: "fixed bottom-4 right-4 z-[60] flex flex-col gap-2 pointer-events-auto", children: toasts.map((t) => /* @__PURE__ */ jsx(ToastItem, { entry: t }, t.id)) });
|
|
130
76
|
}
|
|
131
77
|
|
|
132
|
-
// src/
|
|
133
|
-
|
|
78
|
+
// src/lib/chime.ts
|
|
79
|
+
var ctx = null;
|
|
80
|
+
function audio() {
|
|
81
|
+
if (typeof window === "undefined") return null;
|
|
82
|
+
if (ctx) return ctx;
|
|
83
|
+
const Cls = window.AudioContext || window.webkitAudioContext;
|
|
84
|
+
if (!Cls) return null;
|
|
85
|
+
try {
|
|
86
|
+
ctx = new Cls();
|
|
87
|
+
} catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
return ctx;
|
|
91
|
+
}
|
|
92
|
+
function tone(freq, startAt, durSec) {
|
|
93
|
+
const ac = audio();
|
|
94
|
+
if (!ac) return;
|
|
95
|
+
const t = ac.currentTime + startAt;
|
|
96
|
+
const osc = ac.createOscillator();
|
|
97
|
+
const gain = ac.createGain();
|
|
98
|
+
osc.type = "sine";
|
|
99
|
+
osc.frequency.value = freq;
|
|
100
|
+
gain.gain.setValueAtTime(0, t);
|
|
101
|
+
gain.gain.linearRampToValueAtTime(0.18, t + 0.01);
|
|
102
|
+
gain.gain.exponentialRampToValueAtTime(1e-4, t + durSec);
|
|
103
|
+
osc.connect(gain).connect(ac.destination);
|
|
104
|
+
osc.start(t);
|
|
105
|
+
osc.stop(t + durSec + 0.02);
|
|
106
|
+
}
|
|
107
|
+
function playCompletionChime() {
|
|
108
|
+
tone(659.25, 0, 0.18);
|
|
109
|
+
tone(880, 0.12, 0.24);
|
|
110
|
+
}
|
|
134
111
|
|
|
135
112
|
// src/lib/favicon.ts
|
|
136
113
|
var BASE_BG = "#4f46e5";
|
|
@@ -492,9 +469,18 @@ var WrongStackWebSocketClient = class {
|
|
|
492
469
|
compactContext(aggressive = false) {
|
|
493
470
|
this.send({ type: "context.compact", payload: { aggressive } });
|
|
494
471
|
}
|
|
472
|
+
repairContext() {
|
|
473
|
+
this.send({ type: "context.repair" });
|
|
474
|
+
}
|
|
495
475
|
debugContext() {
|
|
496
476
|
this.send({ type: "context.debug" });
|
|
497
477
|
}
|
|
478
|
+
listContextModes() {
|
|
479
|
+
this.send({ type: "context.modes.list" });
|
|
480
|
+
}
|
|
481
|
+
switchContextMode(id) {
|
|
482
|
+
this.send({ type: "context.mode.switch", payload: { id } });
|
|
483
|
+
}
|
|
498
484
|
// ---- Inspect commands (mirror TUI/CLI's /tools /memory /skill /diag /stats) ----
|
|
499
485
|
listTools() {
|
|
500
486
|
this.send({ type: "tools.list" });
|
|
@@ -786,6 +772,8 @@ var useSessionStore = create2()(
|
|
|
786
772
|
projectName: "",
|
|
787
773
|
mode: "default",
|
|
788
774
|
modes: [],
|
|
775
|
+
contextMode: "balanced",
|
|
776
|
+
contextModes: [],
|
|
789
777
|
iteration: null,
|
|
790
778
|
todos: [],
|
|
791
779
|
setSession: (session) => set({ session }),
|
|
@@ -825,12 +813,14 @@ var useSessionStore = create2()(
|
|
|
825
813
|
maxContext: env.maxContext ?? state.maxContext,
|
|
826
814
|
projectName: env.projectName ?? state.projectName,
|
|
827
815
|
mode: env.mode ?? state.mode,
|
|
816
|
+
contextMode: env.contextMode ?? state.contextMode,
|
|
828
817
|
inputCost: env.inputCost ?? state.inputCost,
|
|
829
818
|
outputCost: env.outputCost ?? state.outputCost,
|
|
830
819
|
cacheReadCost: env.cacheReadCost ?? state.cacheReadCost
|
|
831
820
|
})),
|
|
832
821
|
setIteration: (iteration) => set({ iteration }),
|
|
833
822
|
setModes: (modes) => set({ modes }),
|
|
823
|
+
setContextModes: (contextModes) => set({ contextModes }),
|
|
834
824
|
setTodos: (todos) => set({ todos })
|
|
835
825
|
}),
|
|
836
826
|
{
|
|
@@ -948,6 +938,7 @@ function installHandlers(ws) {
|
|
|
948
938
|
maxContext: payload.maxContext,
|
|
949
939
|
projectName: payload.projectName,
|
|
950
940
|
mode: payload.mode,
|
|
941
|
+
contextMode: payload.contextMode,
|
|
951
942
|
inputCost: payload.inputCost,
|
|
952
943
|
outputCost: payload.outputCost,
|
|
953
944
|
cacheReadCost: payload.cacheReadCost
|
|
@@ -1037,13 +1028,25 @@ function installHandlers(ws) {
|
|
|
1037
1028
|
});
|
|
1038
1029
|
on("context.compacted", (msg) => {
|
|
1039
1030
|
const payload = msg.payload;
|
|
1040
|
-
|
|
1031
|
+
let summary = payload.reductions.length ? payload.reductions.map((r) => `${r.phase}: ${r.saved}`).join(", ") : "no-op";
|
|
1032
|
+
if (payload.repaired) {
|
|
1033
|
+
summary += `; repaired ${payload.repaired.removedToolUses.length} tool_use, ${payload.repaired.removedToolResults.length} tool_result, ${payload.repaired.removedMessages} empty messages`;
|
|
1034
|
+
}
|
|
1041
1035
|
useChatStore.getState().addMessage({
|
|
1042
1036
|
role: "assistant",
|
|
1043
1037
|
content: `\u{1F5DC}\uFE0F Context compacted: ${payload.before} \u2192 ${payload.after} tokens (saved ~${payload.saved}). ${summary}`
|
|
1044
1038
|
});
|
|
1045
1039
|
useSessionStore.setState({ lastInputTokens: payload.after });
|
|
1046
1040
|
});
|
|
1041
|
+
on("context.repaired", (msg) => {
|
|
1042
|
+
const payload = msg.payload;
|
|
1043
|
+
const removed = payload.removedToolUses.length + payload.removedToolResults.length + payload.removedMessages;
|
|
1044
|
+
const msgCount = payload.beforeMessages !== void 0 && payload.afterMessages !== void 0 ? ` Messages: ${payload.beforeMessages} -> ${payload.afterMessages}.` : "";
|
|
1045
|
+
useChatStore.getState().addMessage({
|
|
1046
|
+
role: "assistant",
|
|
1047
|
+
content: `Context repaired: removed ${removed} orphan protocol item(s).${msgCount} tool_use ${payload.removedToolUses.length}, tool_result ${payload.removedToolResults.length}.`
|
|
1048
|
+
});
|
|
1049
|
+
});
|
|
1047
1050
|
on("session.end", () => {
|
|
1048
1051
|
useConfigStore.getState().setWsConnected(false);
|
|
1049
1052
|
});
|
|
@@ -1323,6 +1326,24 @@ ${body}` : "\u{1F9E0} **Memory** \n\n_empty \u2014 nothing remembered yet_"
|
|
|
1323
1326
|
useSessionStore.getState().setModes(p.modes.map((m) => ({ id: m.id, name: m.name, description: m.description })));
|
|
1324
1327
|
useSessionStore.getState().setEnv({ mode: p.activeId });
|
|
1325
1328
|
});
|
|
1329
|
+
on("context.modes.list", (msg) => {
|
|
1330
|
+
const p = msg.payload;
|
|
1331
|
+
useSessionStore.getState().setContextModes(
|
|
1332
|
+
p.modes.map((m) => ({
|
|
1333
|
+
id: m.id,
|
|
1334
|
+
name: m.name,
|
|
1335
|
+
description: m.description,
|
|
1336
|
+
thresholds: m.thresholds,
|
|
1337
|
+
preserveK: m.preserveK,
|
|
1338
|
+
eliseThreshold: m.eliseThreshold
|
|
1339
|
+
}))
|
|
1340
|
+
);
|
|
1341
|
+
useSessionStore.getState().setEnv({ contextMode: p.activeId });
|
|
1342
|
+
});
|
|
1343
|
+
on("context.mode.changed", (msg) => {
|
|
1344
|
+
const p = msg.payload;
|
|
1345
|
+
useSessionStore.getState().setEnv({ contextMode: p.id });
|
|
1346
|
+
});
|
|
1326
1347
|
on("sessions.list", (msg) => {
|
|
1327
1348
|
const payload = msg.payload;
|
|
1328
1349
|
useHistoryStore.getState().setEntries(payload.sessions ?? [], payload.error ?? null);
|
|
@@ -1442,6 +1463,9 @@ function useWebSocket() {
|
|
|
1442
1463
|
const getStats = useCallback(() => client2.getStats(), [client2]);
|
|
1443
1464
|
const listModes = useCallback(() => client2.listModes(), [client2]);
|
|
1444
1465
|
const switchMode = useCallback((id) => client2.switchMode(id), [client2]);
|
|
1466
|
+
const listContextModes = useCallback(() => client2.listContextModes(), [client2]);
|
|
1467
|
+
const switchContextMode = useCallback((id) => client2.switchContextMode(id), [client2]);
|
|
1468
|
+
const repairContext = useCallback(() => client2.repairContext(), [client2]);
|
|
1445
1469
|
return {
|
|
1446
1470
|
client: client2,
|
|
1447
1471
|
sendMessage,
|
|
@@ -1467,12 +1491,15 @@ function useWebSocket() {
|
|
|
1467
1491
|
getDiag,
|
|
1468
1492
|
getStats,
|
|
1469
1493
|
listModes,
|
|
1470
|
-
switchMode
|
|
1494
|
+
switchMode,
|
|
1495
|
+
listContextModes,
|
|
1496
|
+
switchContextMode,
|
|
1497
|
+
repairContext
|
|
1471
1498
|
};
|
|
1472
1499
|
}
|
|
1473
1500
|
|
|
1474
1501
|
// src/App.tsx
|
|
1475
|
-
import { useEffect as
|
|
1502
|
+
import { useEffect as useEffect20 } from "react";
|
|
1476
1503
|
|
|
1477
1504
|
// src/components/ChatView.tsx
|
|
1478
1505
|
import {
|
|
@@ -1491,7 +1518,7 @@ import {
|
|
|
1491
1518
|
Sun as Sun2,
|
|
1492
1519
|
Zap as Zap2
|
|
1493
1520
|
} from "lucide-react";
|
|
1494
|
-
import { useCallback as useCallback3, useEffect as
|
|
1521
|
+
import { useCallback as useCallback3, useEffect as useEffect12, useRef as useRef9, useState as useState13 } from "react";
|
|
1495
1522
|
|
|
1496
1523
|
// src/components/ChatInput.tsx
|
|
1497
1524
|
import { Pencil, Send, Square } from "lucide-react";
|
|
@@ -1642,6 +1669,15 @@ function CommandPalette() {
|
|
|
1642
1669
|
keywords: ["compact", "shrink", "context"],
|
|
1643
1670
|
run: () => ws.client?.compactContext?.()
|
|
1644
1671
|
},
|
|
1672
|
+
{
|
|
1673
|
+
id: "repair-context",
|
|
1674
|
+
category: "Session",
|
|
1675
|
+
label: "Repair context",
|
|
1676
|
+
hint: "Remove orphan tool protocol blocks",
|
|
1677
|
+
icon: Wrench,
|
|
1678
|
+
keywords: ["repair", "context", "tool_use", "tool_result"],
|
|
1679
|
+
run: () => ws.client?.repairContext?.()
|
|
1680
|
+
},
|
|
1645
1681
|
{
|
|
1646
1682
|
id: "export",
|
|
1647
1683
|
category: "Session",
|
|
@@ -1729,8 +1765,7 @@ function CommandPalette() {
|
|
|
1729
1765
|
const next = !useConfigStore.getState().soundOnComplete;
|
|
1730
1766
|
useConfigStore.getState().setSoundOnComplete(next);
|
|
1731
1767
|
if (next) {
|
|
1732
|
-
|
|
1733
|
-
});
|
|
1768
|
+
playCompletionChime();
|
|
1734
1769
|
}
|
|
1735
1770
|
}
|
|
1736
1771
|
}
|
|
@@ -2123,6 +2158,11 @@ var SLASH_COMMANDS = [
|
|
|
2123
2158
|
category: "Session",
|
|
2124
2159
|
description: "Shrink context \u2014 elide ancient tool output"
|
|
2125
2160
|
},
|
|
2161
|
+
{
|
|
2162
|
+
name: "/repair",
|
|
2163
|
+
category: "Session",
|
|
2164
|
+
description: "Repair orphan tool_use/tool_result blocks in context"
|
|
2165
|
+
},
|
|
2126
2166
|
{
|
|
2127
2167
|
name: "/debug",
|
|
2128
2168
|
category: "Inspect",
|
|
@@ -2237,6 +2277,9 @@ function ChatInput() {
|
|
|
2237
2277
|
case "/compact!":
|
|
2238
2278
|
client2?.compactContext?.(cmd === "/compact!");
|
|
2239
2279
|
return true;
|
|
2280
|
+
case "/repair":
|
|
2281
|
+
client2?.repairContext?.();
|
|
2282
|
+
return true;
|
|
2240
2283
|
case "/debug":
|
|
2241
2284
|
case "/context":
|
|
2242
2285
|
client2?.debugContext?.();
|
|
@@ -2857,18 +2900,130 @@ function ConnectionChip({ wsStatus, wsConnected }) {
|
|
|
2857
2900
|
);
|
|
2858
2901
|
}
|
|
2859
2902
|
|
|
2860
|
-
// src/components/
|
|
2903
|
+
// src/components/ContextModePicker.tsx
|
|
2904
|
+
import { Check, ChevronDown, Gauge } from "lucide-react";
|
|
2861
2905
|
import { useEffect as useEffect7, useRef as useRef5, useState as useState5 } from "react";
|
|
2862
|
-
import {
|
|
2906
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2907
|
+
var FALLBACK_MODES = [
|
|
2908
|
+
{
|
|
2909
|
+
id: "balanced",
|
|
2910
|
+
name: "Balanced",
|
|
2911
|
+
description: "Default rolling compaction",
|
|
2912
|
+
thresholds: { warn: 0.6, soft: 0.75, hard: 0.9 },
|
|
2913
|
+
preserveK: 10,
|
|
2914
|
+
eliseThreshold: 2e3
|
|
2915
|
+
}
|
|
2916
|
+
];
|
|
2917
|
+
function ContextModePicker() {
|
|
2918
|
+
const contextMode = useSessionStore((s) => s.contextMode);
|
|
2919
|
+
const contextModes = useSessionStore((s) => s.contextModes);
|
|
2920
|
+
const { listContextModes, switchContextMode } = useWebSocket();
|
|
2921
|
+
const [open, setOpen] = useState5(false);
|
|
2922
|
+
const rootRef = useRef5(null);
|
|
2923
|
+
useEffect7(() => {
|
|
2924
|
+
if (open) listContextModes();
|
|
2925
|
+
}, [open, listContextModes]);
|
|
2926
|
+
useEffect7(() => {
|
|
2927
|
+
if (!open) return;
|
|
2928
|
+
const onClick = (e) => {
|
|
2929
|
+
if (!rootRef.current?.contains(e.target)) setOpen(false);
|
|
2930
|
+
};
|
|
2931
|
+
const onKey = (e) => {
|
|
2932
|
+
if (e.key === "Escape") setOpen(false);
|
|
2933
|
+
};
|
|
2934
|
+
document.addEventListener("mousedown", onClick);
|
|
2935
|
+
document.addEventListener("keydown", onKey);
|
|
2936
|
+
return () => {
|
|
2937
|
+
document.removeEventListener("mousedown", onClick);
|
|
2938
|
+
document.removeEventListener("keydown", onKey);
|
|
2939
|
+
};
|
|
2940
|
+
}, [open]);
|
|
2941
|
+
const items = contextModes.length > 0 ? contextModes : FALLBACK_MODES;
|
|
2942
|
+
const active = items.find((m) => m.id === contextMode) ?? items[0];
|
|
2943
|
+
return /* @__PURE__ */ jsxs6("div", { ref: rootRef, className: "relative shrink-0", children: [
|
|
2944
|
+
/* @__PURE__ */ jsxs6(
|
|
2945
|
+
"button",
|
|
2946
|
+
{
|
|
2947
|
+
type: "button",
|
|
2948
|
+
onClick: () => setOpen((v) => !v),
|
|
2949
|
+
className: cn(
|
|
2950
|
+
"flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium",
|
|
2951
|
+
"bg-emerald-500/10 text-emerald-700 dark:text-emerald-300 hover:bg-emerald-500/15 transition-colors border border-transparent hover:border-emerald-500/30"
|
|
2952
|
+
),
|
|
2953
|
+
title: "Context-window mode",
|
|
2954
|
+
children: [
|
|
2955
|
+
/* @__PURE__ */ jsx7(Gauge, { className: "h-3 w-3" }),
|
|
2956
|
+
"ctx: ",
|
|
2957
|
+
/* @__PURE__ */ jsx7("span", { className: "font-mono", children: contextMode || active.id }),
|
|
2958
|
+
/* @__PURE__ */ jsx7(ChevronDown, { className: "h-3 w-3 opacity-60" })
|
|
2959
|
+
]
|
|
2960
|
+
}
|
|
2961
|
+
),
|
|
2962
|
+
open && /* @__PURE__ */ jsxs6("div", { className: "absolute top-full left-0 mt-1 w-80 rounded-md border bg-popover shadow-lg z-30 py-1", children: [
|
|
2963
|
+
/* @__PURE__ */ jsx7("div", { className: "px-3 py-1.5 text-[10px] uppercase tracking-wider text-muted-foreground border-b", children: "Context Window" }),
|
|
2964
|
+
items.map((m) => /* @__PURE__ */ jsxs6(
|
|
2965
|
+
"button",
|
|
2966
|
+
{
|
|
2967
|
+
type: "button",
|
|
2968
|
+
onClick: () => {
|
|
2969
|
+
switchContextMode(m.id);
|
|
2970
|
+
setOpen(false);
|
|
2971
|
+
},
|
|
2972
|
+
className: cn(
|
|
2973
|
+
"w-full text-left px-3 py-2 hover:bg-accent/40 flex items-start gap-2",
|
|
2974
|
+
m.id === contextMode && "bg-accent/30"
|
|
2975
|
+
),
|
|
2976
|
+
children: [
|
|
2977
|
+
/* @__PURE__ */ jsx7(
|
|
2978
|
+
Check,
|
|
2979
|
+
{
|
|
2980
|
+
className: cn(
|
|
2981
|
+
"h-3.5 w-3.5 mt-0.5 shrink-0",
|
|
2982
|
+
m.id === contextMode ? "opacity-100 text-primary" : "opacity-0"
|
|
2983
|
+
)
|
|
2984
|
+
}
|
|
2985
|
+
),
|
|
2986
|
+
/* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
|
|
2987
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2", children: [
|
|
2988
|
+
/* @__PURE__ */ jsx7("span", { className: "text-xs font-mono", children: m.id }),
|
|
2989
|
+
m.thresholds && /* @__PURE__ */ jsxs6("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
|
|
2990
|
+
Math.round(m.thresholds.warn * 100),
|
|
2991
|
+
"/",
|
|
2992
|
+
Math.round(m.thresholds.soft * 100),
|
|
2993
|
+
"/",
|
|
2994
|
+
Math.round(m.thresholds.hard * 100),
|
|
2995
|
+
"%"
|
|
2996
|
+
] })
|
|
2997
|
+
] }),
|
|
2998
|
+
/* @__PURE__ */ jsx7("div", { className: "text-[11px] text-muted-foreground leading-snug", children: m.description }),
|
|
2999
|
+
(m.preserveK || m.eliseThreshold) && /* @__PURE__ */ jsxs6("div", { className: "mt-1 text-[10px] text-muted-foreground/80", children: [
|
|
3000
|
+
"keep ",
|
|
3001
|
+
m.preserveK ?? "-",
|
|
3002
|
+
" recent \xB7 elide ",
|
|
3003
|
+
m.eliseThreshold ?? "-",
|
|
3004
|
+
"+ tokens"
|
|
3005
|
+
] })
|
|
3006
|
+
] })
|
|
3007
|
+
]
|
|
3008
|
+
},
|
|
3009
|
+
m.id
|
|
3010
|
+
))
|
|
3011
|
+
] })
|
|
3012
|
+
] });
|
|
3013
|
+
}
|
|
3014
|
+
|
|
3015
|
+
// src/components/CostChip.tsx
|
|
3016
|
+
import { useEffect as useEffect8, useRef as useRef6, useState as useState6 } from "react";
|
|
3017
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2863
3018
|
function CostChip() {
|
|
2864
3019
|
const cost = useSessionStore((s) => s.cost);
|
|
2865
3020
|
const inputCost = useSessionStore((s) => s.inputCost);
|
|
2866
3021
|
const outputCost = useSessionStore((s) => s.outputCost);
|
|
2867
3022
|
const cacheReadCost = useSessionStore((s) => s.cacheReadCost);
|
|
2868
3023
|
const messages = useChatStore((s) => s.messages);
|
|
2869
|
-
const [open, setOpen] =
|
|
2870
|
-
const rootRef =
|
|
2871
|
-
|
|
3024
|
+
const [open, setOpen] = useState6(false);
|
|
3025
|
+
const rootRef = useRef6(null);
|
|
3026
|
+
useEffect8(() => {
|
|
2872
3027
|
if (!open) return;
|
|
2873
3028
|
const onClick = (e) => {
|
|
2874
3029
|
if (!rootRef.current?.contains(e.target)) setOpen(false);
|
|
@@ -2902,8 +3057,8 @@ function CostChip() {
|
|
|
2902
3057
|
})();
|
|
2903
3058
|
const fmt$ = (v) => v >= 0.01 ? `$${v.toFixed(4)}` : v > 0 ? `$${v.toFixed(6).replace(/0+$/, "").replace(/\.$/, "")}` : "$0";
|
|
2904
3059
|
const haveRates = inputCost > 0 || outputCost > 0;
|
|
2905
|
-
return /* @__PURE__ */
|
|
2906
|
-
/* @__PURE__ */
|
|
3060
|
+
return /* @__PURE__ */ jsxs7("div", { ref: rootRef, className: "relative inline-block", children: [
|
|
3061
|
+
/* @__PURE__ */ jsxs7(
|
|
2907
3062
|
"button",
|
|
2908
3063
|
{
|
|
2909
3064
|
type: "button",
|
|
@@ -2918,42 +3073,42 @@ function CostChip() {
|
|
|
2918
3073
|
]
|
|
2919
3074
|
}
|
|
2920
3075
|
),
|
|
2921
|
-
open && /* @__PURE__ */
|
|
2922
|
-
/* @__PURE__ */
|
|
2923
|
-
/* @__PURE__ */
|
|
2924
|
-
/* @__PURE__ */
|
|
3076
|
+
open && /* @__PURE__ */ jsxs7("div", { className: "absolute right-0 top-full mt-1 z-30 w-80 rounded-md border bg-popover shadow-lg p-3 text-foreground", children: [
|
|
3077
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between mb-2", children: [
|
|
3078
|
+
/* @__PURE__ */ jsx8("span", { className: "text-xs uppercase tracking-wider text-muted-foreground font-medium", children: "Cost breakdown" }),
|
|
3079
|
+
/* @__PURE__ */ jsx8("span", { className: "font-mono tabular-nums text-sm font-semibold text-green-600 dark:text-green-400", children: fmt$(cost) })
|
|
2925
3080
|
] }),
|
|
2926
|
-
haveRates ? /* @__PURE__ */
|
|
2927
|
-
/* @__PURE__ */
|
|
2928
|
-
/* @__PURE__ */
|
|
2929
|
-
/* @__PURE__ */
|
|
3081
|
+
haveRates ? /* @__PURE__ */ jsxs7("div", { className: "text-[11px] text-muted-foreground font-mono mb-3 border-b pb-2", children: [
|
|
3082
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex justify-between", children: [
|
|
3083
|
+
/* @__PURE__ */ jsx8("span", { children: "input /1M" }),
|
|
3084
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2930
3085
|
"$",
|
|
2931
3086
|
inputCost.toFixed(2)
|
|
2932
3087
|
] })
|
|
2933
3088
|
] }),
|
|
2934
|
-
/* @__PURE__ */
|
|
2935
|
-
/* @__PURE__ */
|
|
2936
|
-
/* @__PURE__ */
|
|
3089
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex justify-between", children: [
|
|
3090
|
+
/* @__PURE__ */ jsx8("span", { children: "output /1M" }),
|
|
3091
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2937
3092
|
"$",
|
|
2938
3093
|
outputCost.toFixed(2)
|
|
2939
3094
|
] })
|
|
2940
3095
|
] }),
|
|
2941
|
-
cacheReadCost > 0 && /* @__PURE__ */
|
|
2942
|
-
/* @__PURE__ */
|
|
2943
|
-
/* @__PURE__ */
|
|
3096
|
+
cacheReadCost > 0 && /* @__PURE__ */ jsxs7("div", { className: "flex justify-between", children: [
|
|
3097
|
+
/* @__PURE__ */ jsx8("span", { children: "cache /1M" }),
|
|
3098
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
2944
3099
|
"$",
|
|
2945
3100
|
cacheReadCost.toFixed(2)
|
|
2946
3101
|
] })
|
|
2947
3102
|
] })
|
|
2948
|
-
] }) : /* @__PURE__ */
|
|
2949
|
-
turns.length === 0 ? /* @__PURE__ */
|
|
2950
|
-
/* @__PURE__ */
|
|
3103
|
+
] }) : /* @__PURE__ */ jsx8("div", { className: "text-[11px] text-muted-foreground italic mb-3 border-b pb-2", children: "No pricing for the current model \u2014 cost figures are zero." }),
|
|
3104
|
+
turns.length === 0 ? /* @__PURE__ */ jsx8("div", { className: "text-xs text-muted-foreground italic", children: "No completed turns yet. Run a prompt to see per-turn cost here." }) : /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
3105
|
+
/* @__PURE__ */ jsxs7("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground/80 mb-1", children: [
|
|
2951
3106
|
"Top ",
|
|
2952
3107
|
turns.length,
|
|
2953
3108
|
" expensive turn",
|
|
2954
3109
|
turns.length === 1 ? "" : "s"
|
|
2955
3110
|
] }),
|
|
2956
|
-
/* @__PURE__ */
|
|
3111
|
+
/* @__PURE__ */ jsx8("ul", { className: "space-y-1", children: turns.map((t) => /* @__PURE__ */ jsx8("li", { children: /* @__PURE__ */ jsxs7(
|
|
2957
3112
|
"button",
|
|
2958
3113
|
{
|
|
2959
3114
|
type: "button",
|
|
@@ -2964,11 +3119,11 @@ function CostChip() {
|
|
|
2964
3119
|
},
|
|
2965
3120
|
className: "w-full text-left rounded px-2 py-1.5 hover:bg-accent/40 transition-colors",
|
|
2966
3121
|
children: [
|
|
2967
|
-
/* @__PURE__ */
|
|
2968
|
-
/* @__PURE__ */
|
|
2969
|
-
/* @__PURE__ */
|
|
3122
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
3123
|
+
/* @__PURE__ */ jsx8("span", { className: "text-xs truncate", children: t.preview }),
|
|
3124
|
+
/* @__PURE__ */ jsx8("span", { className: "text-xs font-mono tabular-nums text-green-600 dark:text-green-400 shrink-0", children: fmt$(t.cost) })
|
|
2970
3125
|
] }),
|
|
2971
|
-
/* @__PURE__ */
|
|
3126
|
+
/* @__PURE__ */ jsxs7("div", { className: "text-[10px] text-muted-foreground font-mono mt-0.5", children: [
|
|
2972
3127
|
t.tools,
|
|
2973
3128
|
" tool",
|
|
2974
3129
|
t.tools === 1 ? "" : "s",
|
|
@@ -3100,9 +3255,9 @@ function safeJson(v) {
|
|
|
3100
3255
|
// src/components/MessageBubble.tsx
|
|
3101
3256
|
import {
|
|
3102
3257
|
Bot,
|
|
3103
|
-
Check,
|
|
3258
|
+
Check as Check2,
|
|
3104
3259
|
CheckCircle2 as CheckCircle22,
|
|
3105
|
-
ChevronDown as
|
|
3260
|
+
ChevronDown as ChevronDown3,
|
|
3106
3261
|
ChevronRight as ChevronRight2,
|
|
3107
3262
|
Clock,
|
|
3108
3263
|
Copy,
|
|
@@ -3116,36 +3271,36 @@ import {
|
|
|
3116
3271
|
User,
|
|
3117
3272
|
XCircle as XCircle2
|
|
3118
3273
|
} from "lucide-react";
|
|
3119
|
-
import { memo as memo3, useState as
|
|
3274
|
+
import { memo as memo3, useState as useState8 } from "react";
|
|
3120
3275
|
import ReactMarkdown from "react-markdown";
|
|
3121
3276
|
import remarkGfm from "remark-gfm";
|
|
3122
3277
|
|
|
3123
3278
|
// src/components/DiffView.tsx
|
|
3124
3279
|
import { memo, useMemo as useMemo2 } from "react";
|
|
3125
|
-
import { jsx as
|
|
3280
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3126
3281
|
var DiffView = memo(function DiffView2({ oldText, newText, caption }) {
|
|
3127
3282
|
const rows = useMemo2(() => computeDiff(oldText, newText), [oldText, newText]);
|
|
3128
3283
|
if (rows === null) {
|
|
3129
|
-
return /* @__PURE__ */
|
|
3284
|
+
return /* @__PURE__ */ jsx9("div", { className: "text-xs text-muted-foreground italic px-3 py-2", children: "Diff omitted (file too large to render inline)." });
|
|
3130
3285
|
}
|
|
3131
3286
|
const adds = rows.filter((r) => r.kind === "add").length;
|
|
3132
3287
|
const dels = rows.filter((r) => r.kind === "del").length;
|
|
3133
|
-
return /* @__PURE__ */
|
|
3134
|
-
/* @__PURE__ */
|
|
3135
|
-
/* @__PURE__ */
|
|
3136
|
-
/* @__PURE__ */
|
|
3137
|
-
/* @__PURE__ */
|
|
3288
|
+
return /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border bg-background/40 overflow-hidden text-xs", children: [
|
|
3289
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between px-3 py-1.5 border-b bg-muted/40", children: [
|
|
3290
|
+
/* @__PURE__ */ jsx9("span", { className: "font-mono text-muted-foreground truncate", children: caption ?? "diff" }),
|
|
3291
|
+
/* @__PURE__ */ jsxs8("span", { className: "font-mono shrink-0", children: [
|
|
3292
|
+
/* @__PURE__ */ jsxs8("span", { className: "text-emerald-600 dark:text-emerald-400", children: [
|
|
3138
3293
|
"+",
|
|
3139
3294
|
adds
|
|
3140
3295
|
] }),
|
|
3141
|
-
/* @__PURE__ */
|
|
3142
|
-
/* @__PURE__ */
|
|
3296
|
+
/* @__PURE__ */ jsx9("span", { className: "text-muted-foreground mx-1", children: "\xB7" }),
|
|
3297
|
+
/* @__PURE__ */ jsxs8("span", { className: "text-rose-600 dark:text-rose-400", children: [
|
|
3143
3298
|
"-",
|
|
3144
3299
|
dels
|
|
3145
3300
|
] })
|
|
3146
3301
|
] })
|
|
3147
3302
|
] }),
|
|
3148
|
-
/* @__PURE__ */
|
|
3303
|
+
/* @__PURE__ */ jsx9("div", { className: "font-mono leading-relaxed max-h-96 overflow-auto", children: rows.map((r, i) => /* @__PURE__ */ jsxs8(
|
|
3149
3304
|
"div",
|
|
3150
3305
|
{
|
|
3151
3306
|
className: cn(
|
|
@@ -3154,7 +3309,7 @@ var DiffView = memo(function DiffView2({ oldText, newText, caption }) {
|
|
|
3154
3309
|
r.kind === "del" && "bg-rose-500/10"
|
|
3155
3310
|
),
|
|
3156
3311
|
children: [
|
|
3157
|
-
/* @__PURE__ */
|
|
3312
|
+
/* @__PURE__ */ jsx9(
|
|
3158
3313
|
"span",
|
|
3159
3314
|
{
|
|
3160
3315
|
className: cn(
|
|
@@ -3166,7 +3321,7 @@ var DiffView = memo(function DiffView2({ oldText, newText, caption }) {
|
|
|
3166
3321
|
children: r.kind === "add" ? "+" : r.kind === "del" ? "-" : " "
|
|
3167
3322
|
}
|
|
3168
3323
|
),
|
|
3169
|
-
/* @__PURE__ */
|
|
3324
|
+
/* @__PURE__ */ jsx9(
|
|
3170
3325
|
"pre",
|
|
3171
3326
|
{
|
|
3172
3327
|
className: cn(
|
|
@@ -3241,9 +3396,9 @@ function diffFromToolInput(toolName, input) {
|
|
|
3241
3396
|
}
|
|
3242
3397
|
|
|
3243
3398
|
// src/components/ToolResult.tsx
|
|
3244
|
-
import { ChevronDown, ChevronRight, ChevronsDown, ChevronsUp } from "lucide-react";
|
|
3245
|
-
import { memo as memo2, useMemo as useMemo3, useState as
|
|
3246
|
-
import { Fragment as Fragment3, jsx as
|
|
3399
|
+
import { ChevronDown as ChevronDown2, ChevronRight, ChevronsDown, ChevronsUp } from "lucide-react";
|
|
3400
|
+
import { memo as memo2, useMemo as useMemo3, useState as useState7 } from "react";
|
|
3401
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3247
3402
|
var LONG_OUTPUT_THRESHOLD = 25;
|
|
3248
3403
|
var LONG_PEEK_LINES = 12;
|
|
3249
3404
|
function CollapsibleText({
|
|
@@ -3255,17 +3410,17 @@ function CollapsibleText({
|
|
|
3255
3410
|
}) {
|
|
3256
3411
|
const lines = useMemo3(() => text.split("\n"), [text]);
|
|
3257
3412
|
const isLong = lines.length > LONG_OUTPUT_THRESHOLD;
|
|
3258
|
-
const [expanded, setExpanded] =
|
|
3413
|
+
const [expanded, setExpanded] = useState7(!isLong);
|
|
3259
3414
|
const shown = expanded ? text : lines.slice(0, LONG_PEEK_LINES).join("\n");
|
|
3260
3415
|
const renderGutter = !!showLineNumbers && isLong && expanded;
|
|
3261
|
-
return /* @__PURE__ */
|
|
3416
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("rounded-md border bg-background/40 overflow-hidden", className), children: [
|
|
3262
3417
|
renderGutter ? (
|
|
3263
3418
|
// Force `whitespace-pre` inside the gutter view so the line numbers
|
|
3264
3419
|
// stay 1:1 with content rows. Long horizontal lines scroll within
|
|
3265
3420
|
// the shared overflow container rather than wrapping (which would
|
|
3266
3421
|
// break alignment between the gutter and the body).
|
|
3267
|
-
/* @__PURE__ */
|
|
3268
|
-
/* @__PURE__ */
|
|
3422
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex max-h-96 overflow-auto", children: [
|
|
3423
|
+
/* @__PURE__ */ jsx10(
|
|
3269
3424
|
"pre",
|
|
3270
3425
|
{
|
|
3271
3426
|
"aria-hidden": true,
|
|
@@ -3273,7 +3428,7 @@ function CollapsibleText({
|
|
|
3273
3428
|
children: lines.map((_, i) => `${i + 1}`).join("\n")
|
|
3274
3429
|
}
|
|
3275
3430
|
),
|
|
3276
|
-
/* @__PURE__ */
|
|
3431
|
+
/* @__PURE__ */ jsx10(
|
|
3277
3432
|
"pre",
|
|
3278
3433
|
{
|
|
3279
3434
|
className: cn(
|
|
@@ -3284,7 +3439,7 @@ function CollapsibleText({
|
|
|
3284
3439
|
}
|
|
3285
3440
|
)
|
|
3286
3441
|
] })
|
|
3287
|
-
) : /* @__PURE__ */
|
|
3442
|
+
) : /* @__PURE__ */ jsx10(
|
|
3288
3443
|
"pre",
|
|
3289
3444
|
{
|
|
3290
3445
|
className: cn(
|
|
@@ -3295,19 +3450,19 @@ function CollapsibleText({
|
|
|
3295
3450
|
children: shown
|
|
3296
3451
|
}
|
|
3297
3452
|
),
|
|
3298
|
-
isLong && /* @__PURE__ */
|
|
3453
|
+
isLong && /* @__PURE__ */ jsx10(
|
|
3299
3454
|
"button",
|
|
3300
3455
|
{
|
|
3301
3456
|
type: "button",
|
|
3302
3457
|
onClick: () => setExpanded((v) => !v),
|
|
3303
3458
|
className: "w-full flex items-center justify-center gap-1 px-2 py-1 border-t bg-muted/30 text-[11px] text-muted-foreground hover:text-foreground transition-colors",
|
|
3304
|
-
children: expanded ? /* @__PURE__ */
|
|
3305
|
-
/* @__PURE__ */
|
|
3459
|
+
children: expanded ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
3460
|
+
/* @__PURE__ */ jsx10(ChevronsUp, { className: "h-3 w-3" }),
|
|
3306
3461
|
"Collapse to first ",
|
|
3307
3462
|
LONG_PEEK_LINES,
|
|
3308
3463
|
" lines"
|
|
3309
|
-
] }) : /* @__PURE__ */
|
|
3310
|
-
/* @__PURE__ */
|
|
3464
|
+
] }) : /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
3465
|
+
/* @__PURE__ */ jsx10(ChevronsDown, { className: "h-3 w-3" }),
|
|
3311
3466
|
"Show all ",
|
|
3312
3467
|
lines.length,
|
|
3313
3468
|
" lines (",
|
|
@@ -3326,10 +3481,10 @@ var ToolResult = memo2(function ToolResult2({
|
|
|
3326
3481
|
}) {
|
|
3327
3482
|
const shape = useMemo3(() => detectShape(toolName, result), [toolName, result]);
|
|
3328
3483
|
if (shape.kind === "json") {
|
|
3329
|
-
return /* @__PURE__ */
|
|
3484
|
+
return /* @__PURE__ */ jsx10(JsonResult, { value: shape.value, isError, className });
|
|
3330
3485
|
}
|
|
3331
3486
|
if (shape.kind === "numbered") {
|
|
3332
|
-
return /* @__PURE__ */
|
|
3487
|
+
return /* @__PURE__ */ jsx10(
|
|
3333
3488
|
CollapsibleText,
|
|
3334
3489
|
{
|
|
3335
3490
|
text: result,
|
|
@@ -3340,8 +3495,8 @@ var ToolResult = memo2(function ToolResult2({
|
|
|
3340
3495
|
);
|
|
3341
3496
|
}
|
|
3342
3497
|
if (shape.kind === "bash") {
|
|
3343
|
-
return /* @__PURE__ */
|
|
3344
|
-
shape.stdout && /* @__PURE__ */
|
|
3498
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("rounded-md border bg-background/40 overflow-hidden", className), children: [
|
|
3499
|
+
shape.stdout && /* @__PURE__ */ jsx10(
|
|
3345
3500
|
CollapsibleText,
|
|
3346
3501
|
{
|
|
3347
3502
|
text: shape.stdout,
|
|
@@ -3351,7 +3506,7 @@ var ToolResult = memo2(function ToolResult2({
|
|
|
3351
3506
|
showLineNumbers: true
|
|
3352
3507
|
}
|
|
3353
3508
|
),
|
|
3354
|
-
(shape.exitCode !== void 0 || shape.duration) && /* @__PURE__ */
|
|
3509
|
+
(shape.exitCode !== void 0 || shape.duration) && /* @__PURE__ */ jsxs9(
|
|
3355
3510
|
"div",
|
|
3356
3511
|
{
|
|
3357
3512
|
className: cn(
|
|
@@ -3359,17 +3514,17 @@ var ToolResult = memo2(function ToolResult2({
|
|
|
3359
3514
|
shape.exitCode && shape.exitCode !== 0 ? "text-destructive" : "text-muted-foreground"
|
|
3360
3515
|
),
|
|
3361
3516
|
children: [
|
|
3362
|
-
shape.exitCode !== void 0 && /* @__PURE__ */
|
|
3517
|
+
shape.exitCode !== void 0 && /* @__PURE__ */ jsxs9("span", { children: [
|
|
3363
3518
|
"exit code: ",
|
|
3364
|
-
/* @__PURE__ */
|
|
3519
|
+
/* @__PURE__ */ jsx10("span", { className: "font-mono", children: shape.exitCode })
|
|
3365
3520
|
] }),
|
|
3366
|
-
shape.duration && /* @__PURE__ */
|
|
3521
|
+
shape.duration && /* @__PURE__ */ jsx10("span", { children: shape.duration })
|
|
3367
3522
|
]
|
|
3368
3523
|
}
|
|
3369
3524
|
)
|
|
3370
3525
|
] });
|
|
3371
3526
|
}
|
|
3372
|
-
return /* @__PURE__ */
|
|
3527
|
+
return /* @__PURE__ */ jsx10(
|
|
3373
3528
|
CollapsibleText,
|
|
3374
3529
|
{
|
|
3375
3530
|
text: result,
|
|
@@ -3422,8 +3577,8 @@ function JsonResult({
|
|
|
3422
3577
|
}
|
|
3423
3578
|
}, [value]);
|
|
3424
3579
|
const lineCount = pretty.split("\n").length;
|
|
3425
|
-
const [expanded, setExpanded] =
|
|
3426
|
-
return /* @__PURE__ */
|
|
3580
|
+
const [expanded, setExpanded] = useState7(lineCount < 30);
|
|
3581
|
+
return /* @__PURE__ */ jsxs9(
|
|
3427
3582
|
"div",
|
|
3428
3583
|
{
|
|
3429
3584
|
className: cn(
|
|
@@ -3432,26 +3587,26 @@ function JsonResult({
|
|
|
3432
3587
|
className
|
|
3433
3588
|
),
|
|
3434
3589
|
children: [
|
|
3435
|
-
/* @__PURE__ */
|
|
3590
|
+
/* @__PURE__ */ jsxs9(
|
|
3436
3591
|
"button",
|
|
3437
3592
|
{
|
|
3438
3593
|
type: "button",
|
|
3439
3594
|
onClick: () => setExpanded((v) => !v),
|
|
3440
3595
|
className: "w-full flex items-center justify-between px-2 py-1 border-b bg-muted/30 text-[11px] text-muted-foreground hover:text-foreground",
|
|
3441
3596
|
children: [
|
|
3442
|
-
/* @__PURE__ */
|
|
3443
|
-
expanded ? /* @__PURE__ */
|
|
3444
|
-
/* @__PURE__ */
|
|
3597
|
+
/* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-1", children: [
|
|
3598
|
+
expanded ? /* @__PURE__ */ jsx10(ChevronDown2, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx10(ChevronRight, { className: "h-3 w-3" }),
|
|
3599
|
+
/* @__PURE__ */ jsxs9("span", { className: "font-mono", children: [
|
|
3445
3600
|
"JSON \xB7 ",
|
|
3446
3601
|
lineCount,
|
|
3447
3602
|
" lines"
|
|
3448
3603
|
] })
|
|
3449
3604
|
] }),
|
|
3450
|
-
/* @__PURE__ */
|
|
3605
|
+
/* @__PURE__ */ jsx10("span", { children: expanded ? "collapse" : "expand" })
|
|
3451
3606
|
]
|
|
3452
3607
|
}
|
|
3453
3608
|
),
|
|
3454
|
-
expanded && /* @__PURE__ */
|
|
3609
|
+
expanded && /* @__PURE__ */ jsx10(
|
|
3455
3610
|
"pre",
|
|
3456
3611
|
{
|
|
3457
3612
|
className: cn(
|
|
@@ -3467,7 +3622,7 @@ function JsonResult({
|
|
|
3467
3622
|
}
|
|
3468
3623
|
|
|
3469
3624
|
// src/components/MessageBubble.tsx
|
|
3470
|
-
import { Fragment as Fragment4, jsx as
|
|
3625
|
+
import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3471
3626
|
async function copyToClipboard(text) {
|
|
3472
3627
|
try {
|
|
3473
3628
|
if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) {
|
|
@@ -3500,7 +3655,7 @@ var markdownComponents = {
|
|
|
3500
3655
|
const match = /language-(\w+)/.exec(className ?? "");
|
|
3501
3656
|
const codeText = String(children ?? "").replace(/\n$/, "");
|
|
3502
3657
|
if (inline || !match) {
|
|
3503
|
-
return /* @__PURE__ */
|
|
3658
|
+
return /* @__PURE__ */ jsx11(
|
|
3504
3659
|
"code",
|
|
3505
3660
|
{
|
|
3506
3661
|
className: cn("rounded bg-muted/60 px-1.5 py-0.5 text-[0.85em] font-mono", className),
|
|
@@ -3509,12 +3664,12 @@ var markdownComponents = {
|
|
|
3509
3664
|
}
|
|
3510
3665
|
);
|
|
3511
3666
|
}
|
|
3512
|
-
return /* @__PURE__ */
|
|
3513
|
-
/* @__PURE__ */
|
|
3514
|
-
/* @__PURE__ */
|
|
3515
|
-
/* @__PURE__ */
|
|
3667
|
+
return /* @__PURE__ */ jsxs10("div", { className: "not-prose relative my-3 rounded-lg border bg-muted/30 overflow-hidden", children: [
|
|
3668
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between px-3 py-1.5 border-b bg-muted/40 text-xs", children: [
|
|
3669
|
+
/* @__PURE__ */ jsx11("span", { className: "font-mono text-muted-foreground", children: match[1] }),
|
|
3670
|
+
/* @__PURE__ */ jsx11(CopyButton, { text: codeText, label: "" })
|
|
3516
3671
|
] }),
|
|
3517
|
-
/* @__PURE__ */
|
|
3672
|
+
/* @__PURE__ */ jsx11("pre", { className: "overflow-x-auto p-3 text-xs leading-relaxed font-mono max-h-[40rem]", children: /* @__PURE__ */ jsx11("code", { children: codeText }) })
|
|
3518
3673
|
] });
|
|
3519
3674
|
}
|
|
3520
3675
|
};
|
|
@@ -3523,8 +3678,8 @@ function CopyButton({
|
|
|
3523
3678
|
className,
|
|
3524
3679
|
label = "Copy"
|
|
3525
3680
|
}) {
|
|
3526
|
-
const [copied, setCopied] =
|
|
3527
|
-
return /* @__PURE__ */
|
|
3681
|
+
const [copied, setCopied] = useState8(false);
|
|
3682
|
+
return /* @__PURE__ */ jsx11(
|
|
3528
3683
|
"button",
|
|
3529
3684
|
{
|
|
3530
3685
|
type: "button",
|
|
@@ -3541,12 +3696,12 @@ function CopyButton({
|
|
|
3541
3696
|
className
|
|
3542
3697
|
),
|
|
3543
3698
|
title: label,
|
|
3544
|
-
children: copied ? /* @__PURE__ */
|
|
3545
|
-
/* @__PURE__ */
|
|
3546
|
-
/* @__PURE__ */
|
|
3547
|
-
] }) : /* @__PURE__ */
|
|
3548
|
-
/* @__PURE__ */
|
|
3549
|
-
/* @__PURE__ */
|
|
3699
|
+
children: copied ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
3700
|
+
/* @__PURE__ */ jsx11(Check2, { className: "h-3 w-3 text-green-500" }),
|
|
3701
|
+
/* @__PURE__ */ jsx11("span", { children: "Copied" })
|
|
3702
|
+
] }) : /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
3703
|
+
/* @__PURE__ */ jsx11(Copy, { className: "h-3 w-3" }),
|
|
3704
|
+
/* @__PURE__ */ jsx11("span", { children: label })
|
|
3550
3705
|
] })
|
|
3551
3706
|
}
|
|
3552
3707
|
);
|
|
@@ -3581,17 +3736,17 @@ function detectStackBoundary(text) {
|
|
|
3581
3736
|
}
|
|
3582
3737
|
function ErrorBodyWithStack({ text }) {
|
|
3583
3738
|
const idx = detectStackBoundary(text);
|
|
3584
|
-
const [open, setOpen] =
|
|
3739
|
+
const [open, setOpen] = useState8(false);
|
|
3585
3740
|
if (idx === -1) {
|
|
3586
|
-
return /* @__PURE__ */
|
|
3741
|
+
return /* @__PURE__ */ jsx11("pre", { className: "whitespace-pre-wrap break-words font-mono text-xs leading-relaxed", children: text });
|
|
3587
3742
|
}
|
|
3588
3743
|
const lines = text.split("\n");
|
|
3589
3744
|
const head = lines.slice(0, idx).join("\n").trim();
|
|
3590
3745
|
const stack = lines.slice(idx).join("\n");
|
|
3591
3746
|
const frameCount = stack.split("\n").filter((l) => l.trim().length > 0).length;
|
|
3592
|
-
return /* @__PURE__ */
|
|
3593
|
-
head && /* @__PURE__ */
|
|
3594
|
-
/* @__PURE__ */
|
|
3747
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
|
|
3748
|
+
head && /* @__PURE__ */ jsx11("pre", { className: "whitespace-pre-wrap break-words font-mono text-xs leading-relaxed", children: head }),
|
|
3749
|
+
/* @__PURE__ */ jsxs10(
|
|
3595
3750
|
"button",
|
|
3596
3751
|
{
|
|
3597
3752
|
type: "button",
|
|
@@ -3609,24 +3764,24 @@ function ErrorBodyWithStack({ text }) {
|
|
|
3609
3764
|
]
|
|
3610
3765
|
}
|
|
3611
3766
|
),
|
|
3612
|
-
open && /* @__PURE__ */
|
|
3767
|
+
open && /* @__PURE__ */ jsx11("pre", { className: "whitespace-pre-wrap break-words font-mono text-[11px] leading-snug bg-destructive/5 border border-destructive/20 rounded p-2 max-h-80 overflow-auto", children: stack })
|
|
3613
3768
|
] });
|
|
3614
3769
|
}
|
|
3615
3770
|
function ToolInputView({ input }) {
|
|
3616
|
-
const [openKeys, setOpenKeys] =
|
|
3771
|
+
const [openKeys, setOpenKeys] = useState8({});
|
|
3617
3772
|
if (input === null || input === void 0 || typeof input !== "object" || Array.isArray(input)) {
|
|
3618
|
-
return /* @__PURE__ */
|
|
3773
|
+
return /* @__PURE__ */ jsx11("pre", { className: "whitespace-pre-wrap break-all text-xs font-mono", children: JSON.stringify(input, null, 2) });
|
|
3619
3774
|
}
|
|
3620
3775
|
const entries = Object.entries(input);
|
|
3621
3776
|
if (entries.length === 0) {
|
|
3622
|
-
return /* @__PURE__ */
|
|
3777
|
+
return /* @__PURE__ */ jsx11("span", { className: "text-xs text-muted-foreground italic", children: "(no params)" });
|
|
3623
3778
|
}
|
|
3624
|
-
return /* @__PURE__ */
|
|
3779
|
+
return /* @__PURE__ */ jsx11("div", { className: "text-xs font-mono", children: entries.map(([k, v]) => {
|
|
3625
3780
|
const isPrimitive = v === null || v === void 0 || typeof v === "string" || typeof v === "number" || typeof v === "boolean";
|
|
3626
3781
|
if (isPrimitive) {
|
|
3627
3782
|
const display = v === null ? "null" : v === void 0 ? "undefined" : typeof v === "string" ? v : String(v);
|
|
3628
3783
|
const isLong = typeof v === "string" && (display.length > 80 || display.includes("\n"));
|
|
3629
|
-
return /* @__PURE__ */
|
|
3784
|
+
return /* @__PURE__ */ jsxs10(
|
|
3630
3785
|
"div",
|
|
3631
3786
|
{
|
|
3632
3787
|
className: cn(
|
|
@@ -3634,11 +3789,11 @@ function ToolInputView({ input }) {
|
|
|
3634
3789
|
isLong ? "flex flex-col gap-0.5" : "flex items-baseline gap-2"
|
|
3635
3790
|
),
|
|
3636
3791
|
children: [
|
|
3637
|
-
/* @__PURE__ */
|
|
3792
|
+
/* @__PURE__ */ jsxs10("span", { className: "text-muted-foreground shrink-0", children: [
|
|
3638
3793
|
k,
|
|
3639
3794
|
":"
|
|
3640
3795
|
] }),
|
|
3641
|
-
/* @__PURE__ */
|
|
3796
|
+
/* @__PURE__ */ jsx11(
|
|
3642
3797
|
"span",
|
|
3643
3798
|
{
|
|
3644
3799
|
className: cn(
|
|
@@ -3657,24 +3812,24 @@ function ToolInputView({ input }) {
|
|
|
3657
3812
|
}
|
|
3658
3813
|
const open = !!openKeys[k];
|
|
3659
3814
|
const summary = Array.isArray(v) ? `[${v.length} item${v.length === 1 ? "" : "s"}]` : `{${Object.keys(v).length} key${Object.keys(v).length === 1 ? "" : "s"}}`;
|
|
3660
|
-
return /* @__PURE__ */
|
|
3661
|
-
/* @__PURE__ */
|
|
3815
|
+
return /* @__PURE__ */ jsxs10("div", { className: "py-0.5", children: [
|
|
3816
|
+
/* @__PURE__ */ jsxs10(
|
|
3662
3817
|
"button",
|
|
3663
3818
|
{
|
|
3664
3819
|
type: "button",
|
|
3665
3820
|
onClick: () => setOpenKeys((p) => ({ ...p, [k]: !p[k] })),
|
|
3666
3821
|
className: "flex items-baseline gap-2 hover:bg-muted/30 rounded px-1 -mx-1",
|
|
3667
3822
|
children: [
|
|
3668
|
-
/* @__PURE__ */
|
|
3669
|
-
/* @__PURE__ */
|
|
3823
|
+
/* @__PURE__ */ jsx11("span", { className: "text-muted-foreground/60 text-[10px]", children: open ? "\u25BE" : "\u25B8" }),
|
|
3824
|
+
/* @__PURE__ */ jsxs10("span", { className: "text-muted-foreground", children: [
|
|
3670
3825
|
k,
|
|
3671
3826
|
":"
|
|
3672
3827
|
] }),
|
|
3673
|
-
/* @__PURE__ */
|
|
3828
|
+
/* @__PURE__ */ jsx11("span", { className: "text-violet-600 dark:text-violet-400", children: summary })
|
|
3674
3829
|
]
|
|
3675
3830
|
}
|
|
3676
3831
|
),
|
|
3677
|
-
open && /* @__PURE__ */
|
|
3832
|
+
open && /* @__PURE__ */ jsx11("pre", { className: "ml-3 mt-1 whitespace-pre-wrap break-all text-[11px] bg-muted/40 rounded px-2 py-1.5", children: JSON.stringify(v, null, 2) })
|
|
3678
3833
|
] }, k);
|
|
3679
3834
|
}) });
|
|
3680
3835
|
}
|
|
@@ -3690,10 +3845,10 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3690
3845
|
isFirst = false,
|
|
3691
3846
|
isContinuation = false
|
|
3692
3847
|
}) {
|
|
3693
|
-
const [expandedTools, setExpandedTools] =
|
|
3694
|
-
const [editing, setEditing] =
|
|
3695
|
-
const [editValue, setEditValue] =
|
|
3696
|
-
const [showRaw, setShowRaw] =
|
|
3848
|
+
const [expandedTools, setExpandedTools] = useState8({});
|
|
3849
|
+
const [editing, setEditing] = useState8(false);
|
|
3850
|
+
const [editValue, setEditValue] = useState8("");
|
|
3851
|
+
const [showRaw, setShowRaw] = useState8(false);
|
|
3697
3852
|
const isUser = message.role === "user";
|
|
3698
3853
|
const isTool = message.role === "tool";
|
|
3699
3854
|
void message.role;
|
|
@@ -3762,7 +3917,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3762
3917
|
setEditing(false);
|
|
3763
3918
|
setEditValue("");
|
|
3764
3919
|
};
|
|
3765
|
-
return /* @__PURE__ */
|
|
3920
|
+
return /* @__PURE__ */ jsxs10(
|
|
3766
3921
|
"div",
|
|
3767
3922
|
{
|
|
3768
3923
|
"data-message-id": message.id,
|
|
@@ -3774,7 +3929,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3774
3929
|
isPinned && "ring-1 ring-amber-500/30 bg-amber-500/[0.02] px-1 -mx-1"
|
|
3775
3930
|
),
|
|
3776
3931
|
children: [
|
|
3777
|
-
isContinuation ? /* @__PURE__ */
|
|
3932
|
+
isContinuation ? /* @__PURE__ */ jsx11("div", { className: "flex-shrink-0 w-8 h-8", "aria-hidden": true }) : /* @__PURE__ */ jsx11(
|
|
3778
3933
|
"div",
|
|
3779
3934
|
{
|
|
3780
3935
|
className: cn(
|
|
@@ -3782,11 +3937,11 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3782
3937
|
"ring-2 ring-offset-2 ring-offset-background",
|
|
3783
3938
|
isUser ? "bg-primary text-primary-foreground ring-primary/20" : isTool ? "bg-secondary text-secondary-foreground ring-secondary/20" : "bg-accent text-accent-foreground ring-accent/20"
|
|
3784
3939
|
),
|
|
3785
|
-
children: isUser ? /* @__PURE__ */
|
|
3940
|
+
children: isUser ? /* @__PURE__ */ jsx11(User, { className: "h-4 w-4" }) : isTool ? /* @__PURE__ */ jsx11(Terminal, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx11(Bot, { className: "h-4 w-4" })
|
|
3786
3941
|
}
|
|
3787
3942
|
),
|
|
3788
|
-
/* @__PURE__ */
|
|
3789
|
-
isFirst && !isContinuation && /* @__PURE__ */
|
|
3943
|
+
/* @__PURE__ */ jsxs10("div", { className: cn("flex flex-col gap-1.5 max-w-[85%]", isUser && "items-end"), children: [
|
|
3944
|
+
isFirst && !isContinuation && /* @__PURE__ */ jsx11(
|
|
3790
3945
|
"span",
|
|
3791
3946
|
{
|
|
3792
3947
|
className: cn(
|
|
@@ -3796,7 +3951,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3796
3951
|
children: isUser ? "You" : isTool ? "Tool" : "Assistant"
|
|
3797
3952
|
}
|
|
3798
3953
|
),
|
|
3799
|
-
isTool && message.toolName && /* @__PURE__ */
|
|
3954
|
+
isTool && message.toolName && /* @__PURE__ */ jsxs10(
|
|
3800
3955
|
"button",
|
|
3801
3956
|
{
|
|
3802
3957
|
type: "button",
|
|
@@ -3807,18 +3962,18 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3807
3962
|
message.isError ? "text-destructive" : "text-foreground"
|
|
3808
3963
|
),
|
|
3809
3964
|
children: [
|
|
3810
|
-
/* @__PURE__ */
|
|
3811
|
-
/* @__PURE__ */
|
|
3812
|
-
/* @__PURE__ */
|
|
3965
|
+
/* @__PURE__ */ jsx11("span", { className: "text-muted-foreground/50", children: expandedTools[message.id] ? /* @__PURE__ */ jsx11(ChevronDown3, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx11(ChevronRight2, { className: "h-3 w-3" }) }),
|
|
3966
|
+
/* @__PURE__ */ jsx11(Terminal, { className: "h-3 w-3" }),
|
|
3967
|
+
/* @__PURE__ */ jsx11("span", { className: "font-mono", children: message.toolName }),
|
|
3813
3968
|
message.toolResult === void 0 ? (
|
|
3814
3969
|
// Pulsing dot while still running (matches the inline indicator below).
|
|
3815
|
-
/* @__PURE__ */
|
|
3816
|
-
) : message.isError ? /* @__PURE__ */
|
|
3817
|
-
typeof message.toolDurationMs === "number" && /* @__PURE__ */
|
|
3970
|
+
/* @__PURE__ */ jsx11("span", { className: "h-1.5 w-1.5 rounded-full bg-amber-500 animate-pulse", "aria-hidden": true })
|
|
3971
|
+
) : message.isError ? /* @__PURE__ */ jsx11(XCircle2, { className: "h-3 w-3 text-destructive" }) : /* @__PURE__ */ jsx11(CheckCircle22, { className: "h-3 w-3 text-green-500" }),
|
|
3972
|
+
typeof message.toolDurationMs === "number" && /* @__PURE__ */ jsx11("span", { className: "text-xs text-muted-foreground tabular-nums font-normal", children: formatToolDuration(message.toolDurationMs) })
|
|
3818
3973
|
]
|
|
3819
3974
|
}
|
|
3820
3975
|
),
|
|
3821
|
-
/* @__PURE__ */
|
|
3976
|
+
/* @__PURE__ */ jsx11(
|
|
3822
3977
|
"div",
|
|
3823
3978
|
{
|
|
3824
3979
|
className: cn(
|
|
@@ -3831,9 +3986,9 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3831
3986
|
const expanded = !!expandedTools[message.id];
|
|
3832
3987
|
const inputSummary = message.toolInput !== void 0 ? summarizeToolInput(message.toolName, message.toolInput) : "";
|
|
3833
3988
|
const lines = message.toolResult ? message.toolResult.split("\n").length : 0;
|
|
3834
|
-
return /* @__PURE__ */
|
|
3835
|
-
inputSummary && !expanded && /* @__PURE__ */
|
|
3836
|
-
message.toolResult === void 0 && message.progressLines && message.progressLines.length > 0 && /* @__PURE__ */
|
|
3989
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-1", children: [
|
|
3990
|
+
inputSummary && !expanded && /* @__PURE__ */ jsx11("div", { className: "text-xs text-muted-foreground font-mono truncate", children: inputSummary }),
|
|
3991
|
+
message.toolResult === void 0 && message.progressLines && message.progressLines.length > 0 && /* @__PURE__ */ jsx11("div", { className: "mt-1 rounded-md border border-amber-500/20 bg-amber-500/5 p-1.5 text-[11px] font-mono leading-snug max-h-32 overflow-auto", children: message.progressLines.slice(-6).map((line, i) => /* @__PURE__ */ jsx11(
|
|
3837
3992
|
"div",
|
|
3838
3993
|
{
|
|
3839
3994
|
className: "truncate text-muted-foreground",
|
|
@@ -3844,7 +3999,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3844
3999
|
expanded && message.toolInput !== void 0 && (() => {
|
|
3845
4000
|
const diffArgs = diffFromToolInput(message.toolName, message.toolInput);
|
|
3846
4001
|
if (diffArgs) {
|
|
3847
|
-
return /* @__PURE__ */
|
|
4002
|
+
return /* @__PURE__ */ jsx11(
|
|
3848
4003
|
DiffView,
|
|
3849
4004
|
{
|
|
3850
4005
|
oldText: diffArgs.oldText,
|
|
@@ -3853,16 +4008,16 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3853
4008
|
}
|
|
3854
4009
|
);
|
|
3855
4010
|
}
|
|
3856
|
-
return /* @__PURE__ */
|
|
3857
|
-
/* @__PURE__ */
|
|
3858
|
-
/* @__PURE__ */
|
|
3859
|
-
/* @__PURE__ */
|
|
4011
|
+
return /* @__PURE__ */ jsxs10("div", { className: "p-3 bg-muted/50 rounded-lg overflow-x-auto", children: [
|
|
4012
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-1 text-muted-foreground mb-2 text-xs", children: [
|
|
4013
|
+
/* @__PURE__ */ jsx11(Clock, { className: "h-3 w-3" }),
|
|
4014
|
+
/* @__PURE__ */ jsx11("span", { children: "Input" })
|
|
3860
4015
|
] }),
|
|
3861
|
-
/* @__PURE__ */
|
|
4016
|
+
/* @__PURE__ */ jsx11(ToolInputView, { input: message.toolInput })
|
|
3862
4017
|
] });
|
|
3863
4018
|
})(),
|
|
3864
|
-
expanded && message.toolResult !== void 0 && message.toolResult.length > 0 && /* @__PURE__ */
|
|
3865
|
-
/* @__PURE__ */
|
|
4019
|
+
expanded && message.toolResult !== void 0 && message.toolResult.length > 0 && /* @__PURE__ */ jsxs10("div", { className: "relative group/tool", children: [
|
|
4020
|
+
/* @__PURE__ */ jsx11(
|
|
3866
4021
|
ToolResult,
|
|
3867
4022
|
{
|
|
3868
4023
|
toolName: message.toolName,
|
|
@@ -3870,8 +4025,8 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3870
4025
|
isError: message.isError
|
|
3871
4026
|
}
|
|
3872
4027
|
),
|
|
3873
|
-
/* @__PURE__ */
|
|
3874
|
-
/* @__PURE__ */
|
|
4028
|
+
/* @__PURE__ */ jsxs10("div", { className: "absolute top-1.5 right-1.5 flex items-center gap-1 opacity-0 group-hover/tool:opacity-100 transition-opacity", children: [
|
|
4029
|
+
/* @__PURE__ */ jsx11(
|
|
3875
4030
|
CopyButton,
|
|
3876
4031
|
{
|
|
3877
4032
|
text: message.toolResult,
|
|
@@ -3879,7 +4034,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3879
4034
|
className: "bg-background/80 border rounded px-1.5 py-0.5"
|
|
3880
4035
|
}
|
|
3881
4036
|
),
|
|
3882
|
-
message.toolResult.split("\n").length > 5 && /* @__PURE__ */
|
|
4037
|
+
message.toolResult.split("\n").length > 5 && /* @__PURE__ */ jsx11(
|
|
3883
4038
|
"button",
|
|
3884
4039
|
{
|
|
3885
4040
|
type: "button",
|
|
@@ -3894,14 +4049,14 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3894
4049
|
},
|
|
3895
4050
|
className: "inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground bg-background/80 border rounded px-1.5 py-0.5",
|
|
3896
4051
|
title: "Download as file",
|
|
3897
|
-
children: /* @__PURE__ */
|
|
4052
|
+
children: /* @__PURE__ */ jsx11(Download2, { className: "h-3 w-3" })
|
|
3898
4053
|
}
|
|
3899
4054
|
)
|
|
3900
4055
|
] })
|
|
3901
4056
|
] }),
|
|
3902
|
-
expanded && message.toolResult !== void 0 && message.toolResult.length === 0 && /* @__PURE__ */
|
|
3903
|
-
!expanded && message.isError && message.toolResult && /* @__PURE__ */
|
|
3904
|
-
(message.toolResult !== void 0 && message.toolResult.length > 0 || message.toolInput !== void 0 && Object.keys(message.toolInput ?? {}).length > 0) && /* @__PURE__ */
|
|
4057
|
+
expanded && message.toolResult !== void 0 && message.toolResult.length === 0 && /* @__PURE__ */ jsx11("span", { className: "text-xs text-muted-foreground italic", children: "(empty)" }),
|
|
4058
|
+
!expanded && message.isError && message.toolResult && /* @__PURE__ */ jsx11("div", { className: "text-xs font-mono text-destructive truncate", children: message.toolResult.split("\n")[0] }),
|
|
4059
|
+
(message.toolResult !== void 0 && message.toolResult.length > 0 || message.toolInput !== void 0 && Object.keys(message.toolInput ?? {}).length > 0) && /* @__PURE__ */ jsx11(
|
|
3905
4060
|
"button",
|
|
3906
4061
|
{
|
|
3907
4062
|
type: "button",
|
|
@@ -3911,8 +4066,8 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3911
4066
|
}
|
|
3912
4067
|
)
|
|
3913
4068
|
] });
|
|
3914
|
-
})() : editing && isUser ? /* @__PURE__ */
|
|
3915
|
-
/* @__PURE__ */
|
|
4069
|
+
})() : editing && isUser ? /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-2 min-w-[280px]", children: [
|
|
4070
|
+
/* @__PURE__ */ jsx11(
|
|
3916
4071
|
"textarea",
|
|
3917
4072
|
{
|
|
3918
4073
|
value: editValue,
|
|
@@ -3930,10 +4085,10 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3930
4085
|
className: "w-full resize-none rounded-md border bg-background text-foreground px-2 py-1.5 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-ring"
|
|
3931
4086
|
}
|
|
3932
4087
|
),
|
|
3933
|
-
/* @__PURE__ */
|
|
3934
|
-
/* @__PURE__ */
|
|
3935
|
-
/* @__PURE__ */
|
|
3936
|
-
/* @__PURE__ */
|
|
4088
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between gap-2", children: [
|
|
4089
|
+
/* @__PURE__ */ jsx11("span", { className: "text-[10px] text-primary-foreground/60", children: "\u2318/Ctrl+Enter to save \xB7 Esc to cancel" }),
|
|
4090
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex gap-1", children: [
|
|
4091
|
+
/* @__PURE__ */ jsx11(
|
|
3937
4092
|
"button",
|
|
3938
4093
|
{
|
|
3939
4094
|
type: "button",
|
|
@@ -3942,7 +4097,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3942
4097
|
children: "Cancel"
|
|
3943
4098
|
}
|
|
3944
4099
|
),
|
|
3945
|
-
/* @__PURE__ */
|
|
4100
|
+
/* @__PURE__ */ jsx11(
|
|
3946
4101
|
"button",
|
|
3947
4102
|
{
|
|
3948
4103
|
type: "button",
|
|
@@ -3954,19 +4109,19 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3954
4109
|
)
|
|
3955
4110
|
] })
|
|
3956
4111
|
] })
|
|
3957
|
-
] }) : /* @__PURE__ */
|
|
4112
|
+
] }) : /* @__PURE__ */ jsx11("div", { className: "text-sm leading-relaxed markdown-content", children: message.content ? showRaw && message.role === "assistant" ? /* @__PURE__ */ jsx11("pre", { className: "whitespace-pre-wrap break-words font-mono text-xs leading-relaxed text-foreground/90 max-h-[40rem] overflow-auto", children: message.content }) : message.role === "assistant" && message.isError ? /* @__PURE__ */ jsx11(ErrorBodyWithStack, { text: message.content }) : /* @__PURE__ */ jsx11(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: message.content }) : message.streaming ? /* @__PURE__ */ jsx11("span", { className: "inline-block animate-pulse text-muted-foreground", children: "Typing..." }) : /* @__PURE__ */ jsx11("span", { className: "text-muted-foreground italic", children: "No content" }) })
|
|
3958
4113
|
}
|
|
3959
4114
|
),
|
|
3960
|
-
/* @__PURE__ */
|
|
4115
|
+
/* @__PURE__ */ jsxs10(
|
|
3961
4116
|
"div",
|
|
3962
4117
|
{
|
|
3963
4118
|
className: cn("flex items-center gap-2 px-1", isUser ? "flex-row-reverse" : "flex-row"),
|
|
3964
4119
|
children: [
|
|
3965
|
-
/* @__PURE__ */
|
|
4120
|
+
/* @__PURE__ */ jsx11("span", { className: "text-xs text-muted-foreground/50", children: new Date(message.timestamp).toLocaleTimeString([], {
|
|
3966
4121
|
hour: "2-digit",
|
|
3967
4122
|
minute: "2-digit"
|
|
3968
4123
|
}) }),
|
|
3969
|
-
message.runSummary && /* @__PURE__ */
|
|
4124
|
+
message.runSummary && /* @__PURE__ */ jsxs10(
|
|
3970
4125
|
"span",
|
|
3971
4126
|
{
|
|
3972
4127
|
className: "text-[10px] text-muted-foreground/60 font-mono tabular-nums",
|
|
@@ -3991,7 +4146,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3991
4146
|
const dollars = (u.input * inputCost + u.output * outputCost + (u.cacheRead ?? 0) * cacheReadCost) / 1e6;
|
|
3992
4147
|
const haveCost = inputCost > 0 || outputCost > 0;
|
|
3993
4148
|
const dollarStr = dollars >= 0.01 ? `$${dollars.toFixed(4)}` : dollars > 0 ? `$${dollars.toFixed(6).replace(/0+$/, "").replace(/\.$/, "")}` : "";
|
|
3994
|
-
return /* @__PURE__ */
|
|
4149
|
+
return /* @__PURE__ */ jsxs10(
|
|
3995
4150
|
"span",
|
|
3996
4151
|
{
|
|
3997
4152
|
className: "text-[10px] text-muted-foreground/60 font-mono tabular-nums",
|
|
@@ -4011,7 +4166,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
4011
4166
|
}
|
|
4012
4167
|
);
|
|
4013
4168
|
})(),
|
|
4014
|
-
!isTool && message.content && !message.streaming && /* @__PURE__ */
|
|
4169
|
+
!isTool && message.content && !message.streaming && /* @__PURE__ */ jsx11(
|
|
4015
4170
|
CopyButton,
|
|
4016
4171
|
{
|
|
4017
4172
|
text: message.content,
|
|
@@ -4019,7 +4174,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
4019
4174
|
className: "opacity-0 group-hover:opacity-100 transition-opacity"
|
|
4020
4175
|
}
|
|
4021
4176
|
),
|
|
4022
|
-
message.role === "assistant" && message.content && !message.streaming && /* @__PURE__ */
|
|
4177
|
+
message.role === "assistant" && message.content && !message.streaming && /* @__PURE__ */ jsxs10(
|
|
4023
4178
|
"button",
|
|
4024
4179
|
{
|
|
4025
4180
|
type: "button",
|
|
@@ -4030,12 +4185,12 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
4030
4185
|
showRaw ? "text-primary hover:text-primary/80 opacity-100" : "opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-foreground"
|
|
4031
4186
|
),
|
|
4032
4187
|
children: [
|
|
4033
|
-
/* @__PURE__ */
|
|
4034
|
-
/* @__PURE__ */
|
|
4188
|
+
/* @__PURE__ */ jsx11(FileCode2, { className: "h-3 w-3" }),
|
|
4189
|
+
/* @__PURE__ */ jsx11("span", { children: showRaw ? "Rendered" : "Raw" })
|
|
4035
4190
|
]
|
|
4036
4191
|
}
|
|
4037
4192
|
),
|
|
4038
|
-
isUser && !editing && !isLoading && message.content && /* @__PURE__ */
|
|
4193
|
+
isUser && !editing && !isLoading && message.content && /* @__PURE__ */ jsxs10(
|
|
4039
4194
|
"button",
|
|
4040
4195
|
{
|
|
4041
4196
|
type: "button",
|
|
@@ -4043,12 +4198,12 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
4043
4198
|
title: "Edit & resend this prompt",
|
|
4044
4199
|
className: "opacity-0 group-hover:opacity-100 transition-opacity text-xs text-muted-foreground hover:text-foreground inline-flex items-center gap-1",
|
|
4045
4200
|
children: [
|
|
4046
|
-
/* @__PURE__ */
|
|
4047
|
-
/* @__PURE__ */
|
|
4201
|
+
/* @__PURE__ */ jsx11(Pencil2, { className: "h-3 w-3" }),
|
|
4202
|
+
/* @__PURE__ */ jsx11("span", { children: "Edit" })
|
|
4048
4203
|
]
|
|
4049
4204
|
}
|
|
4050
4205
|
),
|
|
4051
|
-
message.role === "assistant" && message.content && !message.streaming && /* @__PURE__ */
|
|
4206
|
+
message.role === "assistant" && message.content && !message.streaming && /* @__PURE__ */ jsxs10(
|
|
4052
4207
|
"button",
|
|
4053
4208
|
{
|
|
4054
4209
|
type: "button",
|
|
@@ -4059,12 +4214,12 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
4059
4214
|
isPinned ? "text-amber-500 hover:text-amber-600 opacity-100" : "opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-foreground"
|
|
4060
4215
|
),
|
|
4061
4216
|
children: [
|
|
4062
|
-
isPinned ? /* @__PURE__ */
|
|
4063
|
-
/* @__PURE__ */
|
|
4217
|
+
isPinned ? /* @__PURE__ */ jsx11(PinOff, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx11(Pin, { className: "h-3 w-3" }),
|
|
4218
|
+
/* @__PURE__ */ jsx11("span", { children: isPinned ? "Pinned" : "Pin" })
|
|
4064
4219
|
]
|
|
4065
4220
|
}
|
|
4066
4221
|
),
|
|
4067
|
-
isLatestAssistant && message.content && !message.streaming && /* @__PURE__ */
|
|
4222
|
+
isLatestAssistant && message.content && !message.streaming && /* @__PURE__ */ jsxs10(
|
|
4068
4223
|
"button",
|
|
4069
4224
|
{
|
|
4070
4225
|
type: "button",
|
|
@@ -4072,8 +4227,8 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
4072
4227
|
title: "Regenerate this response",
|
|
4073
4228
|
className: "opacity-0 group-hover:opacity-100 transition-opacity text-xs text-muted-foreground hover:text-foreground inline-flex items-center gap-1",
|
|
4074
4229
|
children: [
|
|
4075
|
-
/* @__PURE__ */
|
|
4076
|
-
/* @__PURE__ */
|
|
4230
|
+
/* @__PURE__ */ jsx11(RotateCcw3, { className: "h-3 w-3" }),
|
|
4231
|
+
/* @__PURE__ */ jsx11("span", { children: "Retry" })
|
|
4077
4232
|
]
|
|
4078
4233
|
}
|
|
4079
4234
|
)
|
|
@@ -4087,19 +4242,19 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
4087
4242
|
});
|
|
4088
4243
|
|
|
4089
4244
|
// src/components/ModePicker.tsx
|
|
4090
|
-
import { Check as
|
|
4091
|
-
import { useEffect as
|
|
4092
|
-
import { jsx as
|
|
4245
|
+
import { Check as Check3, ChevronDown as ChevronDown4 } from "lucide-react";
|
|
4246
|
+
import { useEffect as useEffect9, useRef as useRef7, useState as useState9 } from "react";
|
|
4247
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4093
4248
|
function ModePicker() {
|
|
4094
4249
|
const mode = useSessionStore((s) => s.mode);
|
|
4095
4250
|
const modes = useSessionStore((s) => s.modes);
|
|
4096
4251
|
const { listModes, switchMode } = useWebSocket();
|
|
4097
|
-
const [open, setOpen] =
|
|
4098
|
-
const rootRef =
|
|
4099
|
-
|
|
4252
|
+
const [open, setOpen] = useState9(false);
|
|
4253
|
+
const rootRef = useRef7(null);
|
|
4254
|
+
useEffect9(() => {
|
|
4100
4255
|
if (open) listModes();
|
|
4101
4256
|
}, [open, listModes]);
|
|
4102
|
-
|
|
4257
|
+
useEffect9(() => {
|
|
4103
4258
|
if (!open) return;
|
|
4104
4259
|
const onClick = (e) => {
|
|
4105
4260
|
if (!rootRef.current?.contains(e.target)) setOpen(false);
|
|
@@ -4115,8 +4270,8 @@ function ModePicker() {
|
|
|
4115
4270
|
};
|
|
4116
4271
|
}, [open]);
|
|
4117
4272
|
const items = modes.length > 0 ? modes : [{ id: "default", name: "Default", description: "Standard agent behaviour" }];
|
|
4118
|
-
return /* @__PURE__ */
|
|
4119
|
-
/* @__PURE__ */
|
|
4273
|
+
return /* @__PURE__ */ jsxs11("div", { ref: rootRef, className: "relative shrink-0", children: [
|
|
4274
|
+
/* @__PURE__ */ jsxs11(
|
|
4120
4275
|
"button",
|
|
4121
4276
|
{
|
|
4122
4277
|
type: "button",
|
|
@@ -4128,14 +4283,14 @@ function ModePicker() {
|
|
|
4128
4283
|
title: "Active mode",
|
|
4129
4284
|
children: [
|
|
4130
4285
|
"mode: ",
|
|
4131
|
-
/* @__PURE__ */
|
|
4132
|
-
/* @__PURE__ */
|
|
4286
|
+
/* @__PURE__ */ jsx12("span", { className: "font-mono", children: mode || "default" }),
|
|
4287
|
+
/* @__PURE__ */ jsx12(ChevronDown4, { className: "h-3 w-3 opacity-60" })
|
|
4133
4288
|
]
|
|
4134
4289
|
}
|
|
4135
4290
|
),
|
|
4136
|
-
open && /* @__PURE__ */
|
|
4137
|
-
/* @__PURE__ */
|
|
4138
|
-
items.map((m) => /* @__PURE__ */
|
|
4291
|
+
open && /* @__PURE__ */ jsxs11("div", { className: "absolute top-full left-0 mt-1 w-64 rounded-md border bg-popover shadow-lg z-30 py-1", children: [
|
|
4292
|
+
/* @__PURE__ */ jsx12("div", { className: "px-3 py-1.5 text-[10px] uppercase tracking-wider text-muted-foreground border-b", children: "Mode" }),
|
|
4293
|
+
items.map((m) => /* @__PURE__ */ jsxs11(
|
|
4139
4294
|
"button",
|
|
4140
4295
|
{
|
|
4141
4296
|
type: "button",
|
|
@@ -4148,8 +4303,8 @@ function ModePicker() {
|
|
|
4148
4303
|
m.id === mode && "bg-accent/30"
|
|
4149
4304
|
),
|
|
4150
4305
|
children: [
|
|
4151
|
-
/* @__PURE__ */
|
|
4152
|
-
|
|
4306
|
+
/* @__PURE__ */ jsx12(
|
|
4307
|
+
Check3,
|
|
4153
4308
|
{
|
|
4154
4309
|
className: cn(
|
|
4155
4310
|
"h-3.5 w-3.5 mt-0.5 shrink-0",
|
|
@@ -4157,9 +4312,9 @@ function ModePicker() {
|
|
|
4157
4312
|
)
|
|
4158
4313
|
}
|
|
4159
4314
|
),
|
|
4160
|
-
/* @__PURE__ */
|
|
4161
|
-
/* @__PURE__ */
|
|
4162
|
-
m.description && /* @__PURE__ */
|
|
4315
|
+
/* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
|
|
4316
|
+
/* @__PURE__ */ jsx12("div", { className: "text-xs font-mono", children: m.id }),
|
|
4317
|
+
m.description && /* @__PURE__ */ jsx12("div", { className: "text-[11px] text-muted-foreground leading-snug", children: m.description })
|
|
4163
4318
|
] })
|
|
4164
4319
|
]
|
|
4165
4320
|
},
|
|
@@ -4171,17 +4326,17 @@ function ModePicker() {
|
|
|
4171
4326
|
|
|
4172
4327
|
// src/components/SearchOverlay.tsx
|
|
4173
4328
|
import { ArrowDown, ArrowUp, Search as Search2, X as X2 } from "lucide-react";
|
|
4174
|
-
import { useEffect as
|
|
4175
|
-
import { jsx as
|
|
4329
|
+
import { useEffect as useEffect10, useMemo as useMemo4, useRef as useRef8, useState as useState10 } from "react";
|
|
4330
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4176
4331
|
function SearchOverlay() {
|
|
4177
4332
|
const open = useUIStore((s) => s.searchOpen);
|
|
4178
4333
|
const setOpen = useUIStore((s) => s.setSearchOpen);
|
|
4179
4334
|
const query = useUIStore((s) => s.searchQuery);
|
|
4180
4335
|
const setQuery = useUIStore((s) => s.setSearchQuery);
|
|
4181
4336
|
const messages = useChatStore((s) => s.messages);
|
|
4182
|
-
const inputRef =
|
|
4183
|
-
const [activeHit, setActiveHit] =
|
|
4184
|
-
|
|
4337
|
+
const inputRef = useRef8(null);
|
|
4338
|
+
const [activeHit, setActiveHit] = useState10(0);
|
|
4339
|
+
useEffect10(() => {
|
|
4185
4340
|
if (open) requestAnimationFrame(() => inputRef.current?.focus());
|
|
4186
4341
|
}, [open]);
|
|
4187
4342
|
const hits = useMemo4(() => {
|
|
@@ -4194,10 +4349,10 @@ function SearchOverlay() {
|
|
|
4194
4349
|
return m.content.toLowerCase().includes(q);
|
|
4195
4350
|
}).map((m) => m.id);
|
|
4196
4351
|
}, [messages, query]);
|
|
4197
|
-
|
|
4352
|
+
useEffect10(() => {
|
|
4198
4353
|
if (activeHit >= hits.length) setActiveHit(0);
|
|
4199
4354
|
}, [hits, activeHit]);
|
|
4200
|
-
|
|
4355
|
+
useEffect10(() => {
|
|
4201
4356
|
const win = window;
|
|
4202
4357
|
const highlights = win.CSS?.highlights;
|
|
4203
4358
|
const HighlightCtor = win.Highlight;
|
|
@@ -4251,7 +4406,7 @@ function SearchOverlay() {
|
|
|
4251
4406
|
}
|
|
4252
4407
|
return clear;
|
|
4253
4408
|
}, [query, hits, activeHit, open]);
|
|
4254
|
-
|
|
4409
|
+
useEffect10(() => {
|
|
4255
4410
|
const id = hits[activeHit];
|
|
4256
4411
|
if (!id) return;
|
|
4257
4412
|
const el = document.querySelector(`[data-message-id="${id}"]`);
|
|
@@ -4264,9 +4419,9 @@ function SearchOverlay() {
|
|
|
4264
4419
|
if (hits.length === 0) return;
|
|
4265
4420
|
setActiveHit((i) => (i + dir + hits.length) % hits.length);
|
|
4266
4421
|
};
|
|
4267
|
-
return /* @__PURE__ */
|
|
4268
|
-
/* @__PURE__ */
|
|
4269
|
-
/* @__PURE__ */
|
|
4422
|
+
return /* @__PURE__ */ jsx13("div", { className: "absolute top-2 right-4 z-30 w-[28rem] max-w-[calc(100%-2rem)] rounded-lg border bg-popover shadow-xl", children: /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 px-3 py-2", children: [
|
|
4423
|
+
/* @__PURE__ */ jsx13(Search2, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
|
|
4424
|
+
/* @__PURE__ */ jsx13(
|
|
4270
4425
|
"input",
|
|
4271
4426
|
{
|
|
4272
4427
|
ref: inputRef,
|
|
@@ -4291,8 +4446,8 @@ function SearchOverlay() {
|
|
|
4291
4446
|
className: "flex-1 bg-transparent outline-none text-sm placeholder:text-muted-foreground"
|
|
4292
4447
|
}
|
|
4293
4448
|
),
|
|
4294
|
-
/* @__PURE__ */
|
|
4295
|
-
/* @__PURE__ */
|
|
4449
|
+
/* @__PURE__ */ jsx13("span", { className: "text-xs text-muted-foreground tabular-nums shrink-0", children: hits.length === 0 ? query ? "0" : "" : `${activeHit + 1} / ${hits.length}` }),
|
|
4450
|
+
/* @__PURE__ */ jsx13(
|
|
4296
4451
|
"button",
|
|
4297
4452
|
{
|
|
4298
4453
|
type: "button",
|
|
@@ -4302,10 +4457,10 @@ function SearchOverlay() {
|
|
|
4302
4457
|
"p-1 rounded hover:bg-muted disabled:opacity-30 disabled:cursor-not-allowed"
|
|
4303
4458
|
),
|
|
4304
4459
|
title: "Previous hit",
|
|
4305
|
-
children: /* @__PURE__ */
|
|
4460
|
+
children: /* @__PURE__ */ jsx13(ArrowUp, { className: "h-3.5 w-3.5" })
|
|
4306
4461
|
}
|
|
4307
4462
|
),
|
|
4308
|
-
/* @__PURE__ */
|
|
4463
|
+
/* @__PURE__ */ jsx13(
|
|
4309
4464
|
"button",
|
|
4310
4465
|
{
|
|
4311
4466
|
type: "button",
|
|
@@ -4315,26 +4470,26 @@ function SearchOverlay() {
|
|
|
4315
4470
|
"p-1 rounded hover:bg-muted disabled:opacity-30 disabled:cursor-not-allowed"
|
|
4316
4471
|
),
|
|
4317
4472
|
title: "Next hit",
|
|
4318
|
-
children: /* @__PURE__ */
|
|
4473
|
+
children: /* @__PURE__ */ jsx13(ArrowDown, { className: "h-3.5 w-3.5" })
|
|
4319
4474
|
}
|
|
4320
4475
|
),
|
|
4321
|
-
/* @__PURE__ */
|
|
4476
|
+
/* @__PURE__ */ jsx13(
|
|
4322
4477
|
"button",
|
|
4323
4478
|
{
|
|
4324
4479
|
type: "button",
|
|
4325
4480
|
onClick: () => setOpen(false),
|
|
4326
4481
|
className: "p-1 rounded hover:bg-muted text-muted-foreground",
|
|
4327
4482
|
title: "Close (Esc)",
|
|
4328
|
-
children: /* @__PURE__ */
|
|
4483
|
+
children: /* @__PURE__ */ jsx13(X2, { className: "h-3.5 w-3.5" })
|
|
4329
4484
|
}
|
|
4330
4485
|
)
|
|
4331
4486
|
] }) });
|
|
4332
4487
|
}
|
|
4333
4488
|
|
|
4334
4489
|
// src/components/ToolGroup.tsx
|
|
4335
|
-
import { CheckCircle2 as CheckCircle23, ChevronDown as
|
|
4336
|
-
import { memo as memo4, useState as
|
|
4337
|
-
import { jsx as
|
|
4490
|
+
import { CheckCircle2 as CheckCircle23, ChevronDown as ChevronDown5, ChevronRight as ChevronRight3, Loader2 as Loader22, Terminal as Terminal2, XCircle as XCircle3 } from "lucide-react";
|
|
4491
|
+
import { memo as memo4, useState as useState11 } from "react";
|
|
4492
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4338
4493
|
function formatDuration(ms) {
|
|
4339
4494
|
if (ms < 1e3) return `${ms}ms`;
|
|
4340
4495
|
if (ms < 6e4) return `${(ms / 1e3).toFixed(ms < 1e4 ? 2 : 1)}s`;
|
|
@@ -4347,9 +4502,9 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4347
4502
|
defaultOpen = false,
|
|
4348
4503
|
isContinuation = false
|
|
4349
4504
|
}) {
|
|
4350
|
-
const [open, setOpen] =
|
|
4505
|
+
const [open, setOpen] = useState11(defaultOpen);
|
|
4351
4506
|
if (tools.length === 1) {
|
|
4352
|
-
return /* @__PURE__ */
|
|
4507
|
+
return /* @__PURE__ */ jsx14(MessageBubble, { message: tools[0], isFirst: true, isContinuation });
|
|
4353
4508
|
}
|
|
4354
4509
|
const running = tools.filter((t) => t.toolResult === void 0).length;
|
|
4355
4510
|
const errored = tools.filter((t) => t.isError).length;
|
|
@@ -4357,10 +4512,10 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4357
4512
|
const names = Array.from(new Set(tools.map((t) => t.toolName).filter(Boolean)));
|
|
4358
4513
|
const preview = names.slice(0, 3).join(", ");
|
|
4359
4514
|
const more = names.length > 3 ? ` +${names.length - 3}` : "";
|
|
4360
|
-
return /* @__PURE__ */
|
|
4361
|
-
isContinuation ? /* @__PURE__ */
|
|
4362
|
-
/* @__PURE__ */
|
|
4363
|
-
/* @__PURE__ */
|
|
4515
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex gap-3 animate-message", children: [
|
|
4516
|
+
isContinuation ? /* @__PURE__ */ jsx14("div", { className: "flex-shrink-0 w-8 h-8", "aria-hidden": true }) : /* @__PURE__ */ jsx14("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__ */ jsx14(Terminal2, { className: "h-4 w-4" }) }),
|
|
4517
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1.5 max-w-[85%] flex-1 min-w-0", children: [
|
|
4518
|
+
/* @__PURE__ */ jsxs13(
|
|
4364
4519
|
"button",
|
|
4365
4520
|
{
|
|
4366
4521
|
type: "button",
|
|
@@ -4371,16 +4526,16 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4371
4526
|
"border border-border/40 bg-muted/30"
|
|
4372
4527
|
),
|
|
4373
4528
|
children: [
|
|
4374
|
-
open ? /* @__PURE__ */
|
|
4375
|
-
/* @__PURE__ */
|
|
4376
|
-
/* @__PURE__ */
|
|
4529
|
+
open ? /* @__PURE__ */ jsx14(ChevronDown5, { className: "h-3.5 w-3.5 text-muted-foreground" }) : /* @__PURE__ */ jsx14(ChevronRight3, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
4530
|
+
/* @__PURE__ */ jsx14(Terminal2, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
4531
|
+
/* @__PURE__ */ jsxs13("span", { className: "font-mono text-xs", children: [
|
|
4377
4532
|
tools.length,
|
|
4378
4533
|
" tool call",
|
|
4379
4534
|
tools.length === 1 ? "" : "s"
|
|
4380
4535
|
] }),
|
|
4381
|
-
running > 0 ? /* @__PURE__ */
|
|
4382
|
-
totalMs > 0 && /* @__PURE__ */
|
|
4383
|
-
preview && /* @__PURE__ */
|
|
4536
|
+
running > 0 ? /* @__PURE__ */ jsx14(Loader22, { className: "h-3 w-3 animate-spin text-amber-500" }) : errored > 0 ? /* @__PURE__ */ jsx14(XCircle3, { className: "h-3 w-3 text-destructive" }) : /* @__PURE__ */ jsx14(CheckCircle23, { className: "h-3 w-3 text-green-500" }),
|
|
4537
|
+
totalMs > 0 && /* @__PURE__ */ jsx14("span", { className: "text-xs text-muted-foreground tabular-nums font-normal", children: formatDuration(totalMs) }),
|
|
4538
|
+
preview && /* @__PURE__ */ jsxs13("span", { className: "text-xs text-muted-foreground/80 font-mono truncate", children: [
|
|
4384
4539
|
"\xB7 ",
|
|
4385
4540
|
preview,
|
|
4386
4541
|
more
|
|
@@ -4388,7 +4543,7 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4388
4543
|
]
|
|
4389
4544
|
}
|
|
4390
4545
|
),
|
|
4391
|
-
open && /* @__PURE__ */
|
|
4546
|
+
open && /* @__PURE__ */ jsx14("div", { className: "space-y-2 pl-3 border-l-2 border-border/40 ml-2", children: tools.map((tool) => /* @__PURE__ */ jsx14(MessageBubble, { message: tool, isFirst: false }, tool.id)) })
|
|
4392
4547
|
] })
|
|
4393
4548
|
] });
|
|
4394
4549
|
});
|
|
@@ -4406,8 +4561,8 @@ import {
|
|
|
4406
4561
|
Wrench as Wrench2,
|
|
4407
4562
|
Zap
|
|
4408
4563
|
} from "lucide-react";
|
|
4409
|
-
import { useEffect as
|
|
4410
|
-
import { Fragment as Fragment5, jsx as
|
|
4564
|
+
import { useEffect as useEffect11, useState as useState12 } from "react";
|
|
4565
|
+
import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4411
4566
|
var CARDS = [
|
|
4412
4567
|
{
|
|
4413
4568
|
icon: Search3,
|
|
@@ -4481,8 +4636,8 @@ function WelcomeScreen() {
|
|
|
4481
4636
|
const wsConnected = useConfigStore((s) => s.wsConnected);
|
|
4482
4637
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
4483
4638
|
const setCurrentView = useUIStore((s) => s.setCurrentView);
|
|
4484
|
-
const [savedCount, setSavedCount] =
|
|
4485
|
-
|
|
4639
|
+
const [savedCount, setSavedCount] = useState12(void 0);
|
|
4640
|
+
useEffect11(() => {
|
|
4486
4641
|
if (!wsConnected) return;
|
|
4487
4642
|
const client2 = getWSClient(wsUrl);
|
|
4488
4643
|
const off = client2.on("providers.saved", (msg) => {
|
|
@@ -4498,40 +4653,40 @@ function WelcomeScreen() {
|
|
|
4498
4653
|
const recentPrompts = promptHistory.slice(0, 6);
|
|
4499
4654
|
const { listSessions, resumeSession } = useWebSocket();
|
|
4500
4655
|
const historyEntries = useHistoryStore((s) => s.entries);
|
|
4501
|
-
|
|
4656
|
+
useEffect11(() => {
|
|
4502
4657
|
if (wsConnected && historyEntries.length === 0) listSessions(10);
|
|
4503
4658
|
}, [wsConnected]);
|
|
4504
4659
|
const sessionNicknames = useUIStore((s) => s.sessionNicknames);
|
|
4505
4660
|
const recentSessions = historyEntries.filter((e) => !e.isCurrent).slice(0, 4);
|
|
4506
|
-
return /* @__PURE__ */
|
|
4507
|
-
/* @__PURE__ */
|
|
4508
|
-
/* @__PURE__ */
|
|
4509
|
-
/* @__PURE__ */
|
|
4510
|
-
/* @__PURE__ */
|
|
4661
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-8 py-8 px-2 max-w-5xl mx-auto w-full", children: [
|
|
4662
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex flex-col items-center text-center gap-3", children: [
|
|
4663
|
+
/* @__PURE__ */ jsxs14("div", { className: "relative", children: [
|
|
4664
|
+
/* @__PURE__ */ jsx15("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__ */ jsx15(Zap, { className: "h-7 w-7 text-primary-foreground" }) }),
|
|
4665
|
+
/* @__PURE__ */ jsx15("div", { className: "absolute -inset-3 bg-gradient-to-r from-transparent via-primary/10 to-transparent animate-pulse rounded-full -z-10" })
|
|
4511
4666
|
] }),
|
|
4512
|
-
/* @__PURE__ */
|
|
4513
|
-
/* @__PURE__ */
|
|
4667
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
4668
|
+
/* @__PURE__ */ jsxs14("h2", { className: "text-2xl font-semibold tracking-tight", children: [
|
|
4514
4669
|
"Where do you want to start",
|
|
4515
|
-
projectName ? /* @__PURE__ */
|
|
4670
|
+
projectName ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
4516
4671
|
" in ",
|
|
4517
|
-
/* @__PURE__ */
|
|
4672
|
+
/* @__PURE__ */ jsx15("span", { className: "text-primary", children: projectName })
|
|
4518
4673
|
] }) : "",
|
|
4519
4674
|
"?"
|
|
4520
4675
|
] }),
|
|
4521
|
-
/* @__PURE__ */
|
|
4676
|
+
/* @__PURE__ */ jsxs14("p", { className: "text-sm text-muted-foreground mt-2 max-w-2xl mx-auto leading-relaxed", children: [
|
|
4522
4677
|
"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 ",
|
|
4523
|
-
/* @__PURE__ */
|
|
4678
|
+
/* @__PURE__ */ jsx15("span", { className: "font-mono text-foreground/80", children: "/" }),
|
|
4524
4679
|
" ",
|
|
4525
4680
|
"for the full command palette."
|
|
4526
4681
|
] }),
|
|
4527
|
-
provider && model && /* @__PURE__ */
|
|
4682
|
+
provider && model && /* @__PURE__ */ jsxs14("p", { className: "text-xs text-muted-foreground/70 mt-2 font-mono", children: [
|
|
4528
4683
|
provider,
|
|
4529
4684
|
" / ",
|
|
4530
4685
|
model
|
|
4531
4686
|
] })
|
|
4532
4687
|
] })
|
|
4533
4688
|
] }),
|
|
4534
|
-
wsConnected && savedCount === 0 && /* @__PURE__ */
|
|
4689
|
+
wsConnected && savedCount === 0 && /* @__PURE__ */ jsxs14(
|
|
4535
4690
|
"button",
|
|
4536
4691
|
{
|
|
4537
4692
|
type: "button",
|
|
@@ -4542,42 +4697,42 @@ function WelcomeScreen() {
|
|
|
4542
4697
|
"p-4 flex items-center gap-4 text-left"
|
|
4543
4698
|
),
|
|
4544
4699
|
children: [
|
|
4545
|
-
/* @__PURE__ */
|
|
4546
|
-
/* @__PURE__ */
|
|
4547
|
-
/* @__PURE__ */
|
|
4548
|
-
/* @__PURE__ */
|
|
4700
|
+
/* @__PURE__ */ jsx15("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__ */ jsx15(KeyRound, { className: "h-6 w-6" }) }),
|
|
4701
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0", children: [
|
|
4702
|
+
/* @__PURE__ */ jsx15("h3", { className: "text-base font-semibold mb-1", children: "No API key configured yet" }),
|
|
4703
|
+
/* @__PURE__ */ jsx15("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." })
|
|
4549
4704
|
] }),
|
|
4550
|
-
/* @__PURE__ */
|
|
4705
|
+
/* @__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: [
|
|
4551
4706
|
"Open Settings ",
|
|
4552
|
-
/* @__PURE__ */
|
|
4707
|
+
/* @__PURE__ */ jsx15(ArrowRight, { className: "h-3.5 w-3.5" })
|
|
4553
4708
|
] })
|
|
4554
4709
|
]
|
|
4555
4710
|
}
|
|
4556
4711
|
),
|
|
4557
|
-
/* @__PURE__ */
|
|
4712
|
+
/* @__PURE__ */ jsx15("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-4", children: CARDS.map((card) => {
|
|
4558
4713
|
const Icon2 = card.icon;
|
|
4559
|
-
return /* @__PURE__ */
|
|
4714
|
+
return /* @__PURE__ */ jsxs14(
|
|
4560
4715
|
"div",
|
|
4561
4716
|
{
|
|
4562
4717
|
className: "rounded-xl border bg-card/40 backdrop-blur-sm p-4 flex flex-col gap-3",
|
|
4563
4718
|
children: [
|
|
4564
|
-
/* @__PURE__ */
|
|
4565
|
-
/* @__PURE__ */
|
|
4719
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
|
|
4720
|
+
/* @__PURE__ */ jsx15(
|
|
4566
4721
|
"span",
|
|
4567
4722
|
{
|
|
4568
4723
|
className: cn(
|
|
4569
4724
|
"flex items-center justify-center w-8 h-8 rounded-lg border",
|
|
4570
4725
|
card.tone
|
|
4571
4726
|
),
|
|
4572
|
-
children: /* @__PURE__ */
|
|
4727
|
+
children: /* @__PURE__ */ jsx15(Icon2, { className: "h-4 w-4" })
|
|
4573
4728
|
}
|
|
4574
4729
|
),
|
|
4575
|
-
/* @__PURE__ */
|
|
4576
|
-
/* @__PURE__ */
|
|
4577
|
-
/* @__PURE__ */
|
|
4730
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
4731
|
+
/* @__PURE__ */ jsx15("h3", { className: "text-sm font-semibold", children: card.title }),
|
|
4732
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs text-muted-foreground", children: card.hint })
|
|
4578
4733
|
] })
|
|
4579
4734
|
] }),
|
|
4580
|
-
/* @__PURE__ */
|
|
4735
|
+
/* @__PURE__ */ jsx15("div", { className: "flex flex-col gap-1.5", children: card.prompts.map((p, i) => /* @__PURE__ */ jsx15(
|
|
4581
4736
|
"button",
|
|
4582
4737
|
{
|
|
4583
4738
|
type: "button",
|
|
@@ -4593,12 +4748,12 @@ function WelcomeScreen() {
|
|
|
4593
4748
|
card.title
|
|
4594
4749
|
);
|
|
4595
4750
|
}) }),
|
|
4596
|
-
recentSessions.length > 0 && /* @__PURE__ */
|
|
4597
|
-
/* @__PURE__ */
|
|
4598
|
-
/* @__PURE__ */
|
|
4599
|
-
/* @__PURE__ */
|
|
4751
|
+
recentSessions.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "rounded-xl border bg-muted/20 p-4", children: [
|
|
4752
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
4753
|
+
/* @__PURE__ */ jsx15(ArchiveRestore2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
4754
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs uppercase tracking-wider text-muted-foreground font-medium", children: "Pick back up" })
|
|
4600
4755
|
] }),
|
|
4601
|
-
/* @__PURE__ */
|
|
4756
|
+
/* @__PURE__ */ jsx15("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-2", children: recentSessions.map((entry) => /* @__PURE__ */ jsxs14(
|
|
4602
4757
|
"button",
|
|
4603
4758
|
{
|
|
4604
4759
|
type: "button",
|
|
@@ -4606,12 +4761,12 @@ function WelcomeScreen() {
|
|
|
4606
4761
|
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",
|
|
4607
4762
|
title: entry.title,
|
|
4608
4763
|
children: [
|
|
4609
|
-
/* @__PURE__ */
|
|
4610
|
-
/* @__PURE__ */
|
|
4764
|
+
/* @__PURE__ */ jsx15("div", { className: "text-sm font-medium truncate text-foreground group-hover/sess:text-primary", children: sessionNicknames[entry.id] || entry.title || "(empty)" }),
|
|
4765
|
+
/* @__PURE__ */ jsxs14("div", { className: "text-[10px] text-muted-foreground font-mono truncate mt-0.5", children: [
|
|
4611
4766
|
entry.provider,
|
|
4612
4767
|
"/",
|
|
4613
4768
|
entry.model,
|
|
4614
|
-
entry.tokenTotal > 0 && /* @__PURE__ */
|
|
4769
|
+
entry.tokenTotal > 0 && /* @__PURE__ */ jsxs14("span", { className: "ml-2", children: [
|
|
4615
4770
|
"\xB7 ",
|
|
4616
4771
|
entry.tokenTotal.toLocaleString(),
|
|
4617
4772
|
" tok"
|
|
@@ -4622,12 +4777,12 @@ function WelcomeScreen() {
|
|
|
4622
4777
|
entry.id
|
|
4623
4778
|
)) })
|
|
4624
4779
|
] }),
|
|
4625
|
-
recentPrompts.length > 0 && /* @__PURE__ */
|
|
4626
|
-
/* @__PURE__ */
|
|
4627
|
-
/* @__PURE__ */
|
|
4628
|
-
/* @__PURE__ */
|
|
4780
|
+
recentPrompts.length > 0 && /* @__PURE__ */ jsxs14("div", { className: "rounded-xl border bg-muted/20 p-4", children: [
|
|
4781
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
4782
|
+
/* @__PURE__ */ jsx15(Clock2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
4783
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs uppercase tracking-wider text-muted-foreground font-medium", children: "Recent prompts" })
|
|
4629
4784
|
] }),
|
|
4630
|
-
/* @__PURE__ */
|
|
4785
|
+
/* @__PURE__ */ jsx15("div", { className: "flex flex-col gap-1.5", children: recentPrompts.filter((p) => !p.startsWith("/")).slice(0, 5).map((p, i) => /* @__PURE__ */ jsx15(
|
|
4631
4786
|
"button",
|
|
4632
4787
|
{
|
|
4633
4788
|
type: "button",
|
|
@@ -4639,20 +4794,20 @@ function WelcomeScreen() {
|
|
|
4639
4794
|
i
|
|
4640
4795
|
)) })
|
|
4641
4796
|
] }),
|
|
4642
|
-
/* @__PURE__ */
|
|
4643
|
-
/* @__PURE__ */
|
|
4644
|
-
/* @__PURE__ */
|
|
4645
|
-
/* @__PURE__ */
|
|
4797
|
+
/* @__PURE__ */ jsxs14("div", { className: "rounded-xl border bg-muted/20 p-4", children: [
|
|
4798
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
4799
|
+
/* @__PURE__ */ jsx15(Keyboard, { className: "h-4 w-4 text-muted-foreground" }),
|
|
4800
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs uppercase tracking-wider text-muted-foreground font-medium", children: "Quick commands" })
|
|
4646
4801
|
] }),
|
|
4647
|
-
/* @__PURE__ */
|
|
4802
|
+
/* @__PURE__ */ jsx15("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-2", children: SLASH_REFS.map((c) => /* @__PURE__ */ jsxs14(
|
|
4648
4803
|
"button",
|
|
4649
4804
|
{
|
|
4650
4805
|
type: "button",
|
|
4651
4806
|
onClick: () => fillTextarea(c.name),
|
|
4652
4807
|
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",
|
|
4653
4808
|
children: [
|
|
4654
|
-
/* @__PURE__ */
|
|
4655
|
-
/* @__PURE__ */
|
|
4809
|
+
/* @__PURE__ */ jsx15("span", { className: "font-mono text-xs text-foreground", children: c.name }),
|
|
4810
|
+
/* @__PURE__ */ jsx15("span", { className: "text-[11px] text-muted-foreground truncate", children: c.hint })
|
|
4656
4811
|
]
|
|
4657
4812
|
},
|
|
4658
4813
|
c.name
|
|
@@ -4664,22 +4819,22 @@ function WelcomeScreen() {
|
|
|
4664
4819
|
// src/components/ui/scroll-area.tsx
|
|
4665
4820
|
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
4666
4821
|
import * as React2 from "react";
|
|
4667
|
-
import { jsx as
|
|
4668
|
-
var ScrollArea = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
4822
|
+
import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4823
|
+
var ScrollArea = React2.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs15(
|
|
4669
4824
|
ScrollAreaPrimitive.Root,
|
|
4670
4825
|
{
|
|
4671
4826
|
ref,
|
|
4672
4827
|
className: cn("relative overflow-hidden", className),
|
|
4673
4828
|
...props,
|
|
4674
4829
|
children: [
|
|
4675
|
-
/* @__PURE__ */
|
|
4676
|
-
/* @__PURE__ */
|
|
4677
|
-
/* @__PURE__ */
|
|
4830
|
+
/* @__PURE__ */ jsx16(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
|
|
4831
|
+
/* @__PURE__ */ jsx16(ScrollBar, {}),
|
|
4832
|
+
/* @__PURE__ */ jsx16(ScrollAreaPrimitive.Corner, {})
|
|
4678
4833
|
]
|
|
4679
4834
|
}
|
|
4680
4835
|
));
|
|
4681
4836
|
ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
|
|
4682
|
-
var ScrollBar = React2.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */
|
|
4837
|
+
var ScrollBar = React2.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
4683
4838
|
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
4684
4839
|
{
|
|
4685
4840
|
ref,
|
|
@@ -4691,13 +4846,13 @@ var ScrollBar = React2.forwardRef(({ className, orientation = "vertical", ...pro
|
|
|
4691
4846
|
className
|
|
4692
4847
|
),
|
|
4693
4848
|
...props,
|
|
4694
|
-
children: /* @__PURE__ */
|
|
4849
|
+
children: /* @__PURE__ */ jsx16(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-border" })
|
|
4695
4850
|
}
|
|
4696
4851
|
));
|
|
4697
4852
|
ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
|
|
4698
4853
|
|
|
4699
4854
|
// src/components/ChatView.tsx
|
|
4700
|
-
import { Fragment as Fragment6, jsx as
|
|
4855
|
+
import { Fragment as Fragment6, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4701
4856
|
function fmtTok(n) {
|
|
4702
4857
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
4703
4858
|
if (n >= 1e3) return `${(n / 1e3).toFixed(n >= 1e4 ? 0 : 1)}k`;
|
|
@@ -4708,11 +4863,11 @@ function ThinkingBubble() {
|
|
|
4708
4863
|
if (!buf) return null;
|
|
4709
4864
|
const tailLines = buf.split("\n").slice(-6);
|
|
4710
4865
|
const tail = tailLines.join("\n").trim();
|
|
4711
|
-
return /* @__PURE__ */
|
|
4712
|
-
/* @__PURE__ */
|
|
4713
|
-
/* @__PURE__ */
|
|
4714
|
-
/* @__PURE__ */
|
|
4715
|
-
/* @__PURE__ */
|
|
4866
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex gap-3 animate-message", children: [
|
|
4867
|
+
/* @__PURE__ */ jsx17("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__ */ jsx17(Brain2, { className: "h-4 w-4 animate-pulse" }) }),
|
|
4868
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1 max-w-[85%] min-w-0", children: [
|
|
4869
|
+
/* @__PURE__ */ jsx17("span", { className: "text-xs font-medium text-violet-600 dark:text-violet-400 px-1", children: "Thinking\u2026" }),
|
|
4870
|
+
/* @__PURE__ */ jsx17("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__ */ jsx17("pre", { className: "whitespace-pre-wrap break-words font-sans text-xs leading-relaxed italic max-h-32 overflow-hidden", children: tail || "\u2026" }) })
|
|
4716
4871
|
] })
|
|
4717
4872
|
] });
|
|
4718
4873
|
}
|
|
@@ -4728,17 +4883,17 @@ function ChatView() {
|
|
|
4728
4883
|
const { totalTokens, cost, startTime, lastInputTokens, maxContext, projectName, iteration } = useSessionStore();
|
|
4729
4884
|
const { wsConnected, wsStatus, provider, model } = useConfigStore();
|
|
4730
4885
|
const { setCurrentView } = useUIStore();
|
|
4731
|
-
const scrollRef =
|
|
4886
|
+
const scrollRef = useRef9(null);
|
|
4732
4887
|
const ctxPct = maxContext > 0 && lastInputTokens > 0 ? Math.min(100, Math.round(lastInputTokens / maxContext * 100)) : 0;
|
|
4733
4888
|
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";
|
|
4734
|
-
const [pinnedToBottom, setPinnedToBottom] =
|
|
4735
|
-
const [unreadCount, setUnreadCount] =
|
|
4736
|
-
const [scrolledDeep, setScrolledDeep] =
|
|
4737
|
-
const lastSeenCount =
|
|
4889
|
+
const [pinnedToBottom, setPinnedToBottom] = useState13(true);
|
|
4890
|
+
const [unreadCount, setUnreadCount] = useState13(0);
|
|
4891
|
+
const [scrolledDeep, setScrolledDeep] = useState13(false);
|
|
4892
|
+
const lastSeenCount = useRef9(messages.length);
|
|
4738
4893
|
const getViewport = useCallback3(() => {
|
|
4739
4894
|
return scrollRef.current?.querySelector("[data-radix-scroll-area-viewport]") ?? null;
|
|
4740
4895
|
}, []);
|
|
4741
|
-
|
|
4896
|
+
useEffect12(() => {
|
|
4742
4897
|
const viewport = getViewport();
|
|
4743
4898
|
if (!viewport) return;
|
|
4744
4899
|
const onScroll = () => {
|
|
@@ -4755,7 +4910,7 @@ function ChatView() {
|
|
|
4755
4910
|
viewport.addEventListener("scroll", onScroll, { passive: true });
|
|
4756
4911
|
return () => viewport.removeEventListener("scroll", onScroll);
|
|
4757
4912
|
}, [getViewport, messages.length]);
|
|
4758
|
-
|
|
4913
|
+
useEffect12(() => {
|
|
4759
4914
|
const viewport = getViewport();
|
|
4760
4915
|
if (!viewport) return;
|
|
4761
4916
|
if (pinnedToBottom) {
|
|
@@ -4779,14 +4934,14 @@ function ChatView() {
|
|
|
4779
4934
|
if (!viewport) return;
|
|
4780
4935
|
viewport.scrollTo({ top: 0, behavior: "smooth" });
|
|
4781
4936
|
}, [getViewport]);
|
|
4782
|
-
const [runStartedAt, setRunStartedAt] =
|
|
4783
|
-
const [nowTick, setNowTick] =
|
|
4784
|
-
const streamAnchor =
|
|
4785
|
-
|
|
4937
|
+
const [runStartedAt, setRunStartedAt] = useState13(null);
|
|
4938
|
+
const [nowTick, setNowTick] = useState13(() => Date.now());
|
|
4939
|
+
const streamAnchor = useRef9(null);
|
|
4940
|
+
useEffect12(() => {
|
|
4786
4941
|
if (isLoading && runStartedAt === null) setRunStartedAt(Date.now());
|
|
4787
4942
|
if (!isLoading && runStartedAt !== null) setRunStartedAt(null);
|
|
4788
4943
|
}, [isLoading, runStartedAt]);
|
|
4789
|
-
|
|
4944
|
+
useEffect12(() => {
|
|
4790
4945
|
if (!isLoading) return;
|
|
4791
4946
|
const t = setInterval(() => setNowTick(Date.now()), 500);
|
|
4792
4947
|
return () => clearInterval(t);
|
|
@@ -4807,11 +4962,11 @@ function ChatView() {
|
|
|
4807
4962
|
})();
|
|
4808
4963
|
const stateTone = agentState === "idle" ? "bg-muted text-muted-foreground" : agentState === "streaming" ? "bg-blue-500/10 text-blue-600 dark:text-blue-400" : "bg-amber-500/10 text-amber-600 dark:text-amber-400";
|
|
4809
4964
|
const hasStatusContent = maxContext > 0 && lastInputTokens > 0 || totalTokens.input > 0 || !!startTime;
|
|
4810
|
-
return /* @__PURE__ */
|
|
4811
|
-
/* @__PURE__ */
|
|
4812
|
-
/* @__PURE__ */
|
|
4813
|
-
/* @__PURE__ */
|
|
4814
|
-
!sidebarOpen && /* @__PURE__ */
|
|
4965
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col h-full", children: [
|
|
4966
|
+
/* @__PURE__ */ jsxs16("header", { className: "flex flex-col border-b bg-card shrink-0", children: [
|
|
4967
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between gap-2 px-3 py-2", children: [
|
|
4968
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-1.5 min-w-0 flex-1", children: [
|
|
4969
|
+
!sidebarOpen && /* @__PURE__ */ jsx17(
|
|
4815
4970
|
Button,
|
|
4816
4971
|
{
|
|
4817
4972
|
variant: "ghost",
|
|
@@ -4819,12 +4974,12 @@ function ChatView() {
|
|
|
4819
4974
|
className: "h-7 w-7 shrink-0",
|
|
4820
4975
|
onClick: toggleSidebar,
|
|
4821
4976
|
title: "Open sidebar (Ctrl+\\\\)",
|
|
4822
|
-
children: /* @__PURE__ */
|
|
4977
|
+
children: /* @__PURE__ */ jsx17(PanelLeftOpen, { className: "h-4 w-4" })
|
|
4823
4978
|
}
|
|
4824
4979
|
),
|
|
4825
|
-
!sidebarOpen && /* @__PURE__ */
|
|
4826
|
-
/* @__PURE__ */
|
|
4827
|
-
/* @__PURE__ */
|
|
4980
|
+
!sidebarOpen && /* @__PURE__ */ jsx17("div", { className: "flex items-center gap-1.5 shrink-0 mr-1", children: /* @__PURE__ */ jsx17("div", { className: "w-5 h-5 rounded bg-primary flex items-center justify-center", children: /* @__PURE__ */ jsx17(Zap2, { className: "h-3 w-3 text-primary-foreground" }) }) }),
|
|
4981
|
+
/* @__PURE__ */ jsx17(ConnectionChip, { wsStatus, wsConnected }),
|
|
4982
|
+
/* @__PURE__ */ jsxs16(
|
|
4828
4983
|
"span",
|
|
4829
4984
|
{
|
|
4830
4985
|
className: cn(
|
|
@@ -4833,23 +4988,23 @@ function ChatView() {
|
|
|
4833
4988
|
),
|
|
4834
4989
|
title: `Agent state: ${agentState}`,
|
|
4835
4990
|
children: [
|
|
4836
|
-
agentState !== "idle" && /* @__PURE__ */
|
|
4837
|
-
/* @__PURE__ */
|
|
4991
|
+
agentState !== "idle" && /* @__PURE__ */ jsx17("span", { className: "h-1.5 w-1.5 rounded-full bg-current animate-pulse" }),
|
|
4992
|
+
/* @__PURE__ */ jsx17("span", { children: agentState })
|
|
4838
4993
|
]
|
|
4839
4994
|
}
|
|
4840
4995
|
),
|
|
4841
|
-
projectName && /* @__PURE__ */
|
|
4996
|
+
projectName && /* @__PURE__ */ jsxs16(
|
|
4842
4997
|
"span",
|
|
4843
4998
|
{
|
|
4844
4999
|
className: "flex items-center gap-1 text-[11px] text-muted-foreground shrink-0 min-w-0",
|
|
4845
5000
|
title: `Project: ${projectName}`,
|
|
4846
5001
|
children: [
|
|
4847
|
-
/* @__PURE__ */
|
|
4848
|
-
/* @__PURE__ */
|
|
5002
|
+
/* @__PURE__ */ jsx17(FolderOpen, { className: "h-3 w-3 shrink-0" }),
|
|
5003
|
+
/* @__PURE__ */ jsx17("span", { className: "truncate max-w-[12rem]", children: projectName })
|
|
4849
5004
|
]
|
|
4850
5005
|
}
|
|
4851
5006
|
),
|
|
4852
|
-
/* @__PURE__ */
|
|
5007
|
+
/* @__PURE__ */ jsxs16(
|
|
4853
5008
|
"button",
|
|
4854
5009
|
{
|
|
4855
5010
|
type: "button",
|
|
@@ -4857,23 +5012,24 @@ function ChatView() {
|
|
|
4857
5012
|
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",
|
|
4858
5013
|
title: "Change provider / model (Ctrl+M)",
|
|
4859
5014
|
children: [
|
|
4860
|
-
/* @__PURE__ */
|
|
4861
|
-
/* @__PURE__ */
|
|
4862
|
-
/* @__PURE__ */
|
|
4863
|
-
/* @__PURE__ */
|
|
4864
|
-
/* @__PURE__ */
|
|
5015
|
+
/* @__PURE__ */ jsx17(Cpu2, { className: "h-3 w-3 text-muted-foreground group-hover:text-foreground shrink-0" }),
|
|
5016
|
+
/* @__PURE__ */ jsxs16("span", { className: "font-mono truncate max-w-[16rem]", children: [
|
|
5017
|
+
/* @__PURE__ */ jsx17("span", { className: "text-muted-foreground", children: provider || "no-provider" }),
|
|
5018
|
+
/* @__PURE__ */ jsx17("span", { className: "text-muted-foreground/40 mx-0.5", children: "/" }),
|
|
5019
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium", children: model || "no-model" })
|
|
4865
5020
|
] })
|
|
4866
5021
|
]
|
|
4867
5022
|
}
|
|
4868
5023
|
),
|
|
4869
|
-
/* @__PURE__ */
|
|
4870
|
-
|
|
5024
|
+
/* @__PURE__ */ jsx17(ModePicker, {}),
|
|
5025
|
+
/* @__PURE__ */ jsx17(ContextModePicker, {}),
|
|
5026
|
+
iteration && /* @__PURE__ */ jsxs16(
|
|
4871
5027
|
"span",
|
|
4872
5028
|
{
|
|
4873
5029
|
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",
|
|
4874
5030
|
title: "Agent iteration",
|
|
4875
5031
|
children: [
|
|
4876
|
-
/* @__PURE__ */
|
|
5032
|
+
/* @__PURE__ */ jsx17(Activity, { className: "h-3 w-3 animate-pulse" }),
|
|
4877
5033
|
"iter ",
|
|
4878
5034
|
iteration.index,
|
|
4879
5035
|
iteration.max > 0 ? `/${iteration.max}` : ""
|
|
@@ -4881,8 +5037,8 @@ function ChatView() {
|
|
|
4881
5037
|
}
|
|
4882
5038
|
)
|
|
4883
5039
|
] }),
|
|
4884
|
-
/* @__PURE__ */
|
|
4885
|
-
/* @__PURE__ */
|
|
5040
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-0.5 shrink-0", children: [
|
|
5041
|
+
/* @__PURE__ */ jsx17(
|
|
4886
5042
|
Button,
|
|
4887
5043
|
{
|
|
4888
5044
|
variant: "ghost",
|
|
@@ -4890,10 +5046,10 @@ function ChatView() {
|
|
|
4890
5046
|
className: "h-7 w-7",
|
|
4891
5047
|
onClick: () => setPaletteOpen(true),
|
|
4892
5048
|
title: "Command palette (Ctrl+K)",
|
|
4893
|
-
children: /* @__PURE__ */
|
|
5049
|
+
children: /* @__PURE__ */ jsx17(Command, { className: "h-4 w-4" })
|
|
4894
5050
|
}
|
|
4895
5051
|
),
|
|
4896
|
-
/* @__PURE__ */
|
|
5052
|
+
/* @__PURE__ */ jsx17(
|
|
4897
5053
|
Button,
|
|
4898
5054
|
{
|
|
4899
5055
|
variant: "ghost",
|
|
@@ -4904,10 +5060,10 @@ function ChatView() {
|
|
|
4904
5060
|
setTheme(next);
|
|
4905
5061
|
},
|
|
4906
5062
|
title: `Theme: ${theme} (click to cycle)`,
|
|
4907
|
-
children: theme === "light" ? /* @__PURE__ */
|
|
5063
|
+
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" })
|
|
4908
5064
|
}
|
|
4909
5065
|
),
|
|
4910
|
-
/* @__PURE__ */
|
|
5066
|
+
/* @__PURE__ */ jsx17(
|
|
4911
5067
|
Button,
|
|
4912
5068
|
{
|
|
4913
5069
|
variant: "ghost",
|
|
@@ -4918,7 +5074,7 @@ function ChatView() {
|
|
|
4918
5074
|
children: "?"
|
|
4919
5075
|
}
|
|
4920
5076
|
),
|
|
4921
|
-
/* @__PURE__ */
|
|
5077
|
+
/* @__PURE__ */ jsx17(
|
|
4922
5078
|
Button,
|
|
4923
5079
|
{
|
|
4924
5080
|
variant: "ghost",
|
|
@@ -4926,14 +5082,14 @@ function ChatView() {
|
|
|
4926
5082
|
className: "h-7 w-7",
|
|
4927
5083
|
onClick: () => setCurrentView("settings"),
|
|
4928
5084
|
title: "Settings",
|
|
4929
|
-
children: /* @__PURE__ */
|
|
5085
|
+
children: /* @__PURE__ */ jsx17(Settings, { className: "h-4 w-4" })
|
|
4930
5086
|
}
|
|
4931
5087
|
)
|
|
4932
5088
|
] })
|
|
4933
5089
|
] }),
|
|
4934
|
-
hasStatusContent && /* @__PURE__ */
|
|
4935
|
-
/* @__PURE__ */
|
|
4936
|
-
maxContext > 0 && lastInputTokens > 0 && /* @__PURE__ */
|
|
5090
|
+
hasStatusContent && /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between gap-3 px-3 py-1 border-t bg-muted/20 text-[11px] text-muted-foreground", children: [
|
|
5091
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3 min-w-0 flex-1 tabular-nums", children: [
|
|
5092
|
+
maxContext > 0 && lastInputTokens > 0 && /* @__PURE__ */ jsxs16(
|
|
4937
5093
|
"span",
|
|
4938
5094
|
{
|
|
4939
5095
|
className: cn(
|
|
@@ -4951,26 +5107,26 @@ function ChatView() {
|
|
|
4951
5107
|
]
|
|
4952
5108
|
}
|
|
4953
5109
|
),
|
|
4954
|
-
totalTokens.input > 0 && /* @__PURE__ */
|
|
4955
|
-
/* @__PURE__ */
|
|
4956
|
-
/* @__PURE__ */
|
|
4957
|
-
/* @__PURE__ */
|
|
5110
|
+
totalTokens.input > 0 && /* @__PURE__ */ jsxs16(Fragment6, { children: [
|
|
5111
|
+
/* @__PURE__ */ jsxs16("span", { className: "flex items-center gap-1", children: [
|
|
5112
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium text-foreground", children: fmtTok(totalTokens.input) }),
|
|
5113
|
+
/* @__PURE__ */ jsx17("span", { children: "in" })
|
|
4958
5114
|
] }),
|
|
4959
|
-
/* @__PURE__ */
|
|
4960
|
-
/* @__PURE__ */
|
|
4961
|
-
/* @__PURE__ */
|
|
5115
|
+
/* @__PURE__ */ jsxs16("span", { className: "flex items-center gap-1", children: [
|
|
5116
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium text-foreground", children: fmtTok(totalTokens.output) }),
|
|
5117
|
+
/* @__PURE__ */ jsx17("span", { children: "out" })
|
|
4962
5118
|
] }),
|
|
4963
5119
|
totalTokens.cacheRead && totalTokens.cacheRead > 0 && (() => {
|
|
4964
5120
|
const denom = (totalTokens.cacheRead ?? 0) + totalTokens.input;
|
|
4965
5121
|
const pct = denom > 0 ? Math.round((totalTokens.cacheRead ?? 0) / denom * 100) : 0;
|
|
4966
|
-
return /* @__PURE__ */
|
|
5122
|
+
return /* @__PURE__ */ jsxs16(
|
|
4967
5123
|
"span",
|
|
4968
5124
|
{
|
|
4969
5125
|
className: "flex items-center gap-1",
|
|
4970
5126
|
title: `Cache hit ratio: ${pct}%`,
|
|
4971
5127
|
children: [
|
|
4972
|
-
/* @__PURE__ */
|
|
4973
|
-
/* @__PURE__ */
|
|
5128
|
+
/* @__PURE__ */ jsx17("span", { className: "font-medium text-foreground", children: fmtTok(totalTokens.cacheRead) }),
|
|
5129
|
+
/* @__PURE__ */ jsxs16("span", { children: [
|
|
4974
5130
|
"cache (",
|
|
4975
5131
|
pct,
|
|
4976
5132
|
"%)"
|
|
@@ -4979,15 +5135,15 @@ function ChatView() {
|
|
|
4979
5135
|
}
|
|
4980
5136
|
);
|
|
4981
5137
|
})(),
|
|
4982
|
-
/* @__PURE__ */
|
|
5138
|
+
/* @__PURE__ */ jsx17(CostChip, {})
|
|
4983
5139
|
] })
|
|
4984
5140
|
] }),
|
|
4985
|
-
startTime && /* @__PURE__ */
|
|
5141
|
+
startTime && /* @__PURE__ */ jsx17("span", { className: "text-muted-foreground/70 tabular-nums shrink-0", children: formatDuration2(startTime) })
|
|
4986
5142
|
] })
|
|
4987
5143
|
] }),
|
|
4988
|
-
/* @__PURE__ */
|
|
4989
|
-
/* @__PURE__ */
|
|
4990
|
-
!pinnedToBottom && /* @__PURE__ */
|
|
5144
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex-1 relative overflow-hidden", children: [
|
|
5145
|
+
/* @__PURE__ */ jsx17(SearchOverlay, {}),
|
|
5146
|
+
!pinnedToBottom && /* @__PURE__ */ jsxs16(
|
|
4991
5147
|
"button",
|
|
4992
5148
|
{
|
|
4993
5149
|
type: "button",
|
|
@@ -4999,12 +5155,12 @@ function ChatView() {
|
|
|
4999
5155
|
"hover:bg-primary/90 transition-colors animate-message"
|
|
5000
5156
|
),
|
|
5001
5157
|
children: [
|
|
5002
|
-
/* @__PURE__ */
|
|
5158
|
+
/* @__PURE__ */ jsx17(ArrowDown2, { className: "h-3.5 w-3.5" }),
|
|
5003
5159
|
unreadCount > 0 ? `${unreadCount} new message${unreadCount === 1 ? "" : "s"}` : "Jump to latest"
|
|
5004
5160
|
]
|
|
5005
5161
|
}
|
|
5006
5162
|
),
|
|
5007
|
-
scrolledDeep && /* @__PURE__ */
|
|
5163
|
+
scrolledDeep && /* @__PURE__ */ jsxs16(
|
|
5008
5164
|
"button",
|
|
5009
5165
|
{
|
|
5010
5166
|
type: "button",
|
|
@@ -5017,12 +5173,12 @@ function ChatView() {
|
|
|
5017
5173
|
"hover:text-foreground hover:bg-background transition-colors animate-message"
|
|
5018
5174
|
),
|
|
5019
5175
|
children: [
|
|
5020
|
-
/* @__PURE__ */
|
|
5021
|
-
/* @__PURE__ */
|
|
5176
|
+
/* @__PURE__ */ jsx17(ArrowUp2, { className: "h-3 w-3" }),
|
|
5177
|
+
/* @__PURE__ */ jsx17("span", { children: "Top" })
|
|
5022
5178
|
]
|
|
5023
5179
|
}
|
|
5024
5180
|
),
|
|
5025
|
-
/* @__PURE__ */
|
|
5181
|
+
/* @__PURE__ */ jsx17(ScrollArea, { className: "h-full", ref: scrollRef, children: /* @__PURE__ */ jsxs16(
|
|
5026
5182
|
"div",
|
|
5027
5183
|
{
|
|
5028
5184
|
className: cn(
|
|
@@ -5030,7 +5186,7 @@ function ChatView() {
|
|
|
5030
5186
|
compactMode ? "max-w-5xl p-3 space-y-3" : "max-w-5xl p-4 space-y-6"
|
|
5031
5187
|
),
|
|
5032
5188
|
children: [
|
|
5033
|
-
messages.length === 0 && !isLoading && /* @__PURE__ */
|
|
5189
|
+
messages.length === 0 && !isLoading && /* @__PURE__ */ jsx17(WelcomeScreen, {}),
|
|
5034
5190
|
(() => {
|
|
5035
5191
|
const groups = [];
|
|
5036
5192
|
for (let i = 0; i < messages.length; i++) {
|
|
@@ -5095,14 +5251,14 @@ function ChatView() {
|
|
|
5095
5251
|
const day = dayKey(ts);
|
|
5096
5252
|
if (day !== prevDay) {
|
|
5097
5253
|
out.push(
|
|
5098
|
-
/* @__PURE__ */
|
|
5254
|
+
/* @__PURE__ */ jsxs16(
|
|
5099
5255
|
"div",
|
|
5100
5256
|
{
|
|
5101
5257
|
className: "flex items-center gap-3 py-1 text-[11px] text-muted-foreground/70 uppercase tracking-wider font-medium",
|
|
5102
5258
|
children: [
|
|
5103
|
-
/* @__PURE__ */
|
|
5104
|
-
/* @__PURE__ */
|
|
5105
|
-
/* @__PURE__ */
|
|
5259
|
+
/* @__PURE__ */ jsx17("div", { className: "flex-1 h-px bg-border/50" }),
|
|
5260
|
+
/* @__PURE__ */ jsx17("span", { children: dayLabel(ts) }),
|
|
5261
|
+
/* @__PURE__ */ jsx17("div", { className: "flex-1 h-px bg-border/50" })
|
|
5106
5262
|
]
|
|
5107
5263
|
},
|
|
5108
5264
|
`day-${day}-${idx}`
|
|
@@ -5111,15 +5267,15 @@ function ChatView() {
|
|
|
5111
5267
|
prevDay = day;
|
|
5112
5268
|
}
|
|
5113
5269
|
if (t.kind === "user") {
|
|
5114
|
-
out.push(/* @__PURE__ */
|
|
5270
|
+
out.push(/* @__PURE__ */ jsx17(MessageBubble, { message: t.message, isFirst: true }, t.key));
|
|
5115
5271
|
continue;
|
|
5116
5272
|
}
|
|
5117
5273
|
const isLastTurn = idx === turns.length - 1;
|
|
5118
5274
|
out.push(
|
|
5119
|
-
/* @__PURE__ */
|
|
5275
|
+
/* @__PURE__ */ jsx17("div", { className: cn(compactMode ? "space-y-1" : "space-y-1.5"), children: t.items.map((g, gi) => {
|
|
5120
5276
|
const continuation = gi > 0;
|
|
5121
5277
|
if (g.kind === "msg") {
|
|
5122
|
-
return /* @__PURE__ */
|
|
5278
|
+
return /* @__PURE__ */ jsx17(
|
|
5123
5279
|
MessageBubble,
|
|
5124
5280
|
{
|
|
5125
5281
|
message: g.message,
|
|
@@ -5130,7 +5286,7 @@ function ChatView() {
|
|
|
5130
5286
|
);
|
|
5131
5287
|
}
|
|
5132
5288
|
const isLatestRunning = isLastTurn && gi === t.items.length - 1 && isLoading && g.tools.some((tt) => tt.toolResult === void 0);
|
|
5133
|
-
return /* @__PURE__ */
|
|
5289
|
+
return /* @__PURE__ */ jsx17(
|
|
5134
5290
|
ToolGroup,
|
|
5135
5291
|
{
|
|
5136
5292
|
tools: g.tools,
|
|
@@ -5144,7 +5300,7 @@ function ChatView() {
|
|
|
5144
5300
|
}
|
|
5145
5301
|
return out;
|
|
5146
5302
|
})(),
|
|
5147
|
-
/* @__PURE__ */
|
|
5303
|
+
/* @__PURE__ */ jsx17(ThinkingBubble, {}),
|
|
5148
5304
|
isLoading && (() => {
|
|
5149
5305
|
const last = messages[messages.length - 1];
|
|
5150
5306
|
const runningTools = messages.filter(
|
|
@@ -5186,22 +5342,22 @@ function ChatView() {
|
|
|
5186
5342
|
} else if (streamAnchor.current) {
|
|
5187
5343
|
streamAnchor.current = null;
|
|
5188
5344
|
}
|
|
5189
|
-
return /* @__PURE__ */
|
|
5190
|
-
/* @__PURE__ */
|
|
5191
|
-
/* @__PURE__ */
|
|
5192
|
-
/* @__PURE__ */
|
|
5193
|
-
/* @__PURE__ */
|
|
5194
|
-
/* @__PURE__ */
|
|
5195
|
-
/* @__PURE__ */
|
|
5345
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex gap-3 animate-message", children: [
|
|
5346
|
+
/* @__PURE__ */ jsx17("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__ */ jsx17(Bot2, { className: "h-4 w-4" }) }),
|
|
5347
|
+
/* @__PURE__ */ jsx17("div", { className: "flex flex-col gap-1.5", children: /* @__PURE__ */ jsx17("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: [
|
|
5348
|
+
/* @__PURE__ */ jsxs16("span", { className: "flex gap-1", children: [
|
|
5349
|
+
/* @__PURE__ */ jsx17("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce [animation-delay:-0.3s]" }),
|
|
5350
|
+
/* @__PURE__ */ jsx17("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce [animation-delay:-0.15s]" }),
|
|
5351
|
+
/* @__PURE__ */ jsx17("span", { className: "h-1.5 w-1.5 rounded-full bg-primary/70 animate-bounce" })
|
|
5196
5352
|
] }),
|
|
5197
|
-
/* @__PURE__ */
|
|
5198
|
-
/* @__PURE__ */
|
|
5199
|
-
iteration && /* @__PURE__ */
|
|
5353
|
+
/* @__PURE__ */ jsx17("span", { className: "text-foreground/90", children: label }),
|
|
5354
|
+
/* @__PURE__ */ jsx17("span", { className: "text-xs text-muted-foreground tabular-nums", children: elapsed }),
|
|
5355
|
+
iteration && /* @__PURE__ */ jsxs16("span", { className: "text-xs text-muted-foreground tabular-nums", children: [
|
|
5200
5356
|
"\xB7 iter ",
|
|
5201
5357
|
iteration.index,
|
|
5202
5358
|
iteration.max > 0 ? `/${iteration.max}` : ""
|
|
5203
5359
|
] }),
|
|
5204
|
-
speedLabel && /* @__PURE__ */
|
|
5360
|
+
speedLabel && /* @__PURE__ */ jsxs16("span", { className: "text-xs text-muted-foreground/80 tabular-nums", children: [
|
|
5205
5361
|
"\xB7 ",
|
|
5206
5362
|
speedLabel
|
|
5207
5363
|
] })
|
|
@@ -5212,25 +5368,25 @@ function ChatView() {
|
|
|
5212
5368
|
}
|
|
5213
5369
|
) })
|
|
5214
5370
|
] }),
|
|
5215
|
-
/* @__PURE__ */
|
|
5216
|
-
/* @__PURE__ */
|
|
5217
|
-
/* @__PURE__ */
|
|
5371
|
+
/* @__PURE__ */ jsx17("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: [
|
|
5372
|
+
/* @__PURE__ */ jsx17(ChatInput, {}),
|
|
5373
|
+
/* @__PURE__ */ jsx17("p", { className: "text-xs text-center text-muted-foreground/50 mt-2", children: "Press Enter to send, Shift+Enter for new line" })
|
|
5218
5374
|
] }) })
|
|
5219
5375
|
] });
|
|
5220
5376
|
}
|
|
5221
5377
|
|
|
5222
5378
|
// src/components/ConfirmDialog.tsx
|
|
5223
5379
|
import { AlertTriangle as AlertTriangle2, FileEdit, Globe, ShieldAlert, Terminal as Terminal3, Wrench as Wrench3 } from "lucide-react";
|
|
5224
|
-
import { useEffect as
|
|
5380
|
+
import { useEffect as useEffect13 } from "react";
|
|
5225
5381
|
|
|
5226
5382
|
// src/components/ui/dialog.tsx
|
|
5227
5383
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
5228
5384
|
import { X as X3 } from "lucide-react";
|
|
5229
5385
|
import * as React3 from "react";
|
|
5230
|
-
import { jsx as
|
|
5386
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5231
5387
|
var Dialog = DialogPrimitive.Root;
|
|
5232
5388
|
var DialogPortal = DialogPrimitive.Portal;
|
|
5233
|
-
var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5389
|
+
var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(
|
|
5234
5390
|
DialogPrimitive.Overlay,
|
|
5235
5391
|
{
|
|
5236
5392
|
ref,
|
|
@@ -5242,9 +5398,9 @@ var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
5242
5398
|
}
|
|
5243
5399
|
));
|
|
5244
5400
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
5245
|
-
var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
5246
|
-
/* @__PURE__ */
|
|
5247
|
-
/* @__PURE__ */
|
|
5401
|
+
var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs17(DialogPortal, { children: [
|
|
5402
|
+
/* @__PURE__ */ jsx18(DialogOverlay, {}),
|
|
5403
|
+
/* @__PURE__ */ jsxs17(
|
|
5248
5404
|
DialogPrimitive.Content,
|
|
5249
5405
|
{
|
|
5250
5406
|
ref,
|
|
@@ -5255,18 +5411,18 @@ var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) =
|
|
|
5255
5411
|
...props,
|
|
5256
5412
|
children: [
|
|
5257
5413
|
children,
|
|
5258
|
-
/* @__PURE__ */
|
|
5259
|
-
/* @__PURE__ */
|
|
5260
|
-
/* @__PURE__ */
|
|
5414
|
+
/* @__PURE__ */ jsxs17(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: [
|
|
5415
|
+
/* @__PURE__ */ jsx18(X3, { className: "h-4 w-4" }),
|
|
5416
|
+
/* @__PURE__ */ jsx18("span", { className: "sr-only", children: "Close" })
|
|
5261
5417
|
] })
|
|
5262
5418
|
]
|
|
5263
5419
|
}
|
|
5264
5420
|
)
|
|
5265
5421
|
] }));
|
|
5266
5422
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
5267
|
-
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */
|
|
5423
|
+
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx18("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
|
|
5268
5424
|
DialogHeader.displayName = "DialogHeader";
|
|
5269
|
-
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */
|
|
5425
|
+
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx18(
|
|
5270
5426
|
"div",
|
|
5271
5427
|
{
|
|
5272
5428
|
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
@@ -5274,7 +5430,7 @@ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx17(
|
|
|
5274
5430
|
}
|
|
5275
5431
|
);
|
|
5276
5432
|
DialogFooter.displayName = "DialogFooter";
|
|
5277
|
-
var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5433
|
+
var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(
|
|
5278
5434
|
DialogPrimitive.Title,
|
|
5279
5435
|
{
|
|
5280
5436
|
ref,
|
|
@@ -5283,7 +5439,7 @@ var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5283
5439
|
}
|
|
5284
5440
|
));
|
|
5285
5441
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
5286
|
-
var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5442
|
+
var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(
|
|
5287
5443
|
DialogPrimitive.Description,
|
|
5288
5444
|
{
|
|
5289
5445
|
ref,
|
|
@@ -5294,7 +5450,7 @@ var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
5294
5450
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
5295
5451
|
|
|
5296
5452
|
// src/components/ConfirmDialog.tsx
|
|
5297
|
-
import { jsx as
|
|
5453
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5298
5454
|
function pickToolIcon(toolName) {
|
|
5299
5455
|
if (/edit|write|create|patch/i.test(toolName)) return FileEdit;
|
|
5300
5456
|
if (/bash|shell|exec|run|command/i.test(toolName)) return Terminal3;
|
|
@@ -5307,7 +5463,7 @@ function SmartInputPreview({
|
|
|
5307
5463
|
}) {
|
|
5308
5464
|
const diffArgs = diffFromToolInput(toolName, input);
|
|
5309
5465
|
if (diffArgs) {
|
|
5310
|
-
return /* @__PURE__ */
|
|
5466
|
+
return /* @__PURE__ */ jsx19("div", { className: "rounded-lg overflow-hidden border", children: /* @__PURE__ */ jsx19(
|
|
5311
5467
|
DiffView,
|
|
5312
5468
|
{
|
|
5313
5469
|
oldText: diffArgs.oldText,
|
|
@@ -5320,12 +5476,12 @@ function SmartInputPreview({
|
|
|
5320
5476
|
const obj = input;
|
|
5321
5477
|
const cmd = obj.command ?? obj.cmd ?? obj.script;
|
|
5322
5478
|
if (typeof cmd === "string" && cmd.trim().length > 0) {
|
|
5323
|
-
return /* @__PURE__ */
|
|
5324
|
-
/* @__PURE__ */
|
|
5325
|
-
/* @__PURE__ */
|
|
5326
|
-
/* @__PURE__ */
|
|
5479
|
+
return /* @__PURE__ */ jsxs18("div", { className: "rounded-lg border bg-background/40 overflow-hidden", children: [
|
|
5480
|
+
/* @__PURE__ */ jsxs18("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: [
|
|
5481
|
+
/* @__PURE__ */ jsx19(Terminal3, { className: "h-3 w-3" }),
|
|
5482
|
+
/* @__PURE__ */ jsx19("span", { children: "Command" })
|
|
5327
5483
|
] }),
|
|
5328
|
-
/* @__PURE__ */
|
|
5484
|
+
/* @__PURE__ */ jsxs18("pre", { className: "px-3 py-2 text-xs font-mono whitespace-pre-wrap break-all max-h-40 overflow-auto", children: [
|
|
5329
5485
|
"$",
|
|
5330
5486
|
cmd
|
|
5331
5487
|
] })
|
|
@@ -5334,16 +5490,16 @@ function SmartInputPreview({
|
|
|
5334
5490
|
const url = obj.url;
|
|
5335
5491
|
if (typeof url === "string") {
|
|
5336
5492
|
const method = obj.method ?? "GET";
|
|
5337
|
-
return /* @__PURE__ */
|
|
5338
|
-
/* @__PURE__ */
|
|
5493
|
+
return /* @__PURE__ */ jsxs18("div", { className: "rounded-lg border bg-background/40 px-3 py-2 text-xs font-mono", children: [
|
|
5494
|
+
/* @__PURE__ */ jsx19("span", { className: "text-muted-foreground", children: method.toUpperCase() }),
|
|
5339
5495
|
" ",
|
|
5340
|
-
/* @__PURE__ */
|
|
5496
|
+
/* @__PURE__ */ jsx19("span", { className: "break-all", children: url })
|
|
5341
5497
|
] });
|
|
5342
5498
|
}
|
|
5343
5499
|
}
|
|
5344
|
-
return /* @__PURE__ */
|
|
5345
|
-
/* @__PURE__ */
|
|
5346
|
-
/* @__PURE__ */
|
|
5500
|
+
return /* @__PURE__ */ jsxs18("div", { className: "p-3 rounded-lg bg-muted/50 border text-xs font-mono", children: [
|
|
5501
|
+
/* @__PURE__ */ jsx19("div", { className: "text-muted-foreground mb-2", children: "Input:" }),
|
|
5502
|
+
/* @__PURE__ */ jsx19("pre", { className: "whitespace-pre-wrap break-all max-h-60 overflow-auto", children: JSON.stringify(input, null, 2) })
|
|
5347
5503
|
] });
|
|
5348
5504
|
}
|
|
5349
5505
|
function ConfirmDialog() {
|
|
@@ -5355,7 +5511,7 @@ function ConfirmDialog() {
|
|
|
5355
5511
|
}
|
|
5356
5512
|
hideConfirm();
|
|
5357
5513
|
};
|
|
5358
|
-
|
|
5514
|
+
useEffect13(() => {
|
|
5359
5515
|
if (!showConfirmDialog) return;
|
|
5360
5516
|
const onKey = (e) => {
|
|
5361
5517
|
const target = e.target;
|
|
@@ -5376,50 +5532,50 @@ function ConfirmDialog() {
|
|
|
5376
5532
|
return () => window.removeEventListener("keydown", onKey);
|
|
5377
5533
|
}, [showConfirmDialog, confirmInfo?.id]);
|
|
5378
5534
|
if (!confirmInfo) {
|
|
5379
|
-
return /* @__PURE__ */
|
|
5535
|
+
return /* @__PURE__ */ jsx19(Dialog, { open: showConfirmDialog, onOpenChange: () => hideConfirm(), children: /* @__PURE__ */ jsx19(DialogContent, {}) });
|
|
5380
5536
|
}
|
|
5381
5537
|
const Icon2 = pickToolIcon(confirmInfo.toolName);
|
|
5382
5538
|
const isEdit = /edit|write/i.test(confirmInfo.toolName);
|
|
5383
|
-
return /* @__PURE__ */
|
|
5384
|
-
/* @__PURE__ */
|
|
5385
|
-
/* @__PURE__ */
|
|
5386
|
-
/* @__PURE__ */
|
|
5539
|
+
return /* @__PURE__ */ jsx19(Dialog, { open: showConfirmDialog, onOpenChange: () => hideConfirm(), children: /* @__PURE__ */ jsxs18(DialogContent, { className: "sm:max-w-2xl", children: [
|
|
5540
|
+
/* @__PURE__ */ jsxs18(DialogHeader, { children: [
|
|
5541
|
+
/* @__PURE__ */ jsxs18(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
5542
|
+
/* @__PURE__ */ jsx19(ShieldAlert, { className: "h-5 w-5 text-yellow-500" }),
|
|
5387
5543
|
"Confirm: ",
|
|
5388
5544
|
confirmInfo.toolName
|
|
5389
5545
|
] }),
|
|
5390
|
-
/* @__PURE__ */
|
|
5546
|
+
/* @__PURE__ */ jsxs18(DialogDescription, { children: [
|
|
5391
5547
|
"The agent wants to ",
|
|
5392
5548
|
isEdit ? "modify a file" : "run this tool",
|
|
5393
5549
|
". Review the request below and decide whether to proceed."
|
|
5394
5550
|
] })
|
|
5395
5551
|
] }),
|
|
5396
|
-
/* @__PURE__ */
|
|
5397
|
-
/* @__PURE__ */
|
|
5398
|
-
/* @__PURE__ */
|
|
5399
|
-
/* @__PURE__ */
|
|
5400
|
-
/* @__PURE__ */
|
|
5401
|
-
/* @__PURE__ */
|
|
5552
|
+
/* @__PURE__ */ jsxs18("div", { className: "py-2 space-y-3", children: [
|
|
5553
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-3 p-3 rounded-lg bg-muted", children: [
|
|
5554
|
+
/* @__PURE__ */ jsx19(Icon2, { className: "h-5 w-5 text-muted-foreground" }),
|
|
5555
|
+
/* @__PURE__ */ jsxs18("div", { className: "min-w-0", children: [
|
|
5556
|
+
/* @__PURE__ */ jsx19("div", { className: "font-medium font-mono truncate", children: confirmInfo.toolName }),
|
|
5557
|
+
/* @__PURE__ */ jsxs18("div", { className: "text-xs text-muted-foreground", children: [
|
|
5402
5558
|
isEdit ? "File modification" : "Tool execution",
|
|
5403
5559
|
" \u2014 preview below"
|
|
5404
5560
|
] })
|
|
5405
5561
|
] })
|
|
5406
5562
|
] }),
|
|
5407
|
-
confirmInfo.input !== void 0 && /* @__PURE__ */
|
|
5408
|
-
confirmInfo.suggestedPattern && /* @__PURE__ */
|
|
5409
|
-
/* @__PURE__ */
|
|
5410
|
-
/* @__PURE__ */
|
|
5411
|
-
/* @__PURE__ */
|
|
5412
|
-
/* @__PURE__ */
|
|
5413
|
-
/* @__PURE__ */
|
|
5563
|
+
confirmInfo.input !== void 0 && /* @__PURE__ */ jsx19(SmartInputPreview, { toolName: confirmInfo.toolName, input: confirmInfo.input }),
|
|
5564
|
+
confirmInfo.suggestedPattern && /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 p-3 rounded-lg bg-yellow-500/10 border border-yellow-500/20", children: [
|
|
5565
|
+
/* @__PURE__ */ jsx19(AlertTriangle2, { className: "h-4 w-4 text-yellow-600 mt-0.5 shrink-0" }),
|
|
5566
|
+
/* @__PURE__ */ jsxs18("div", { className: "text-sm min-w-0", children: [
|
|
5567
|
+
/* @__PURE__ */ jsx19("div", { className: "font-medium text-yellow-800 dark:text-yellow-200", children: "Trust pattern suggestion" }),
|
|
5568
|
+
/* @__PURE__ */ jsx19("div", { className: "font-mono text-xs mt-1 break-all", children: confirmInfo.suggestedPattern }),
|
|
5569
|
+
/* @__PURE__ */ jsxs18("div", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
5414
5570
|
"Picking ",
|
|
5415
|
-
/* @__PURE__ */
|
|
5571
|
+
/* @__PURE__ */ jsx19("span", { className: "font-medium", children: "Always" }),
|
|
5416
5572
|
" will whitelist matching calls for this project."
|
|
5417
5573
|
] })
|
|
5418
5574
|
] })
|
|
5419
5575
|
] })
|
|
5420
5576
|
] }),
|
|
5421
|
-
/* @__PURE__ */
|
|
5422
|
-
/* @__PURE__ */
|
|
5577
|
+
/* @__PURE__ */ jsxs18(DialogFooter, { className: "gap-2 sm:gap-2 flex-wrap", children: [
|
|
5578
|
+
/* @__PURE__ */ jsx19(
|
|
5423
5579
|
Button,
|
|
5424
5580
|
{
|
|
5425
5581
|
variant: "outline",
|
|
@@ -5429,7 +5585,7 @@ function ConfirmDialog() {
|
|
|
5429
5585
|
children: "Deny always"
|
|
5430
5586
|
}
|
|
5431
5587
|
),
|
|
5432
|
-
/* @__PURE__ */
|
|
5588
|
+
/* @__PURE__ */ jsxs18(
|
|
5433
5589
|
Button,
|
|
5434
5590
|
{
|
|
5435
5591
|
variant: "outline",
|
|
@@ -5438,11 +5594,11 @@ function ConfirmDialog() {
|
|
|
5438
5594
|
title: "Reject this single call (Esc / n)",
|
|
5439
5595
|
children: [
|
|
5440
5596
|
"No ",
|
|
5441
|
-
/* @__PURE__ */
|
|
5597
|
+
/* @__PURE__ */ jsx19("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background", children: "n" })
|
|
5442
5598
|
]
|
|
5443
5599
|
}
|
|
5444
5600
|
),
|
|
5445
|
-
/* @__PURE__ */
|
|
5601
|
+
/* @__PURE__ */ jsxs18(
|
|
5446
5602
|
Button,
|
|
5447
5603
|
{
|
|
5448
5604
|
variant: "outline",
|
|
@@ -5451,11 +5607,11 @@ function ConfirmDialog() {
|
|
|
5451
5607
|
title: "Approve and remember the pattern for the project (a)",
|
|
5452
5608
|
children: [
|
|
5453
5609
|
"Always ",
|
|
5454
|
-
/* @__PURE__ */
|
|
5610
|
+
/* @__PURE__ */ jsx19("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background", children: "a" })
|
|
5455
5611
|
]
|
|
5456
5612
|
}
|
|
5457
5613
|
),
|
|
5458
|
-
/* @__PURE__ */
|
|
5614
|
+
/* @__PURE__ */ jsxs18(
|
|
5459
5615
|
Button,
|
|
5460
5616
|
{
|
|
5461
5617
|
size: "sm",
|
|
@@ -5463,7 +5619,7 @@ function ConfirmDialog() {
|
|
|
5463
5619
|
title: "Approve this single call (y)",
|
|
5464
5620
|
children: [
|
|
5465
5621
|
"Yes ",
|
|
5466
|
-
/* @__PURE__ */
|
|
5622
|
+
/* @__PURE__ */ jsx19("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background/80", children: "y" })
|
|
5467
5623
|
]
|
|
5468
5624
|
}
|
|
5469
5625
|
)
|
|
@@ -5473,19 +5629,19 @@ function ConfirmDialog() {
|
|
|
5473
5629
|
|
|
5474
5630
|
// src/components/ConnectionBanner.tsx
|
|
5475
5631
|
import { Loader2 as Loader23, RotateCcw as RotateCcw4, WifiOff as WifiOff3, X as X4 } from "lucide-react";
|
|
5476
|
-
import { useEffect as
|
|
5477
|
-
import { jsx as
|
|
5632
|
+
import { useEffect as useEffect14, useState as useState14 } from "react";
|
|
5633
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5478
5634
|
function ConnectionBanner() {
|
|
5479
5635
|
const wsStatus = useConfigStore((s) => s.wsStatus);
|
|
5480
5636
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
5481
|
-
const [dismissed, setDismissed] =
|
|
5482
|
-
const [now, setNow] =
|
|
5483
|
-
|
|
5637
|
+
const [dismissed, setDismissed] = useState14(false);
|
|
5638
|
+
const [now, setNow] = useState14(Date.now());
|
|
5639
|
+
useEffect14(() => {
|
|
5484
5640
|
if (wsStatus.state !== "reconnecting") return;
|
|
5485
5641
|
const id = setInterval(() => setNow(Date.now()), 500);
|
|
5486
5642
|
return () => clearInterval(id);
|
|
5487
5643
|
}, [wsStatus.state]);
|
|
5488
|
-
|
|
5644
|
+
useEffect14(() => {
|
|
5489
5645
|
if (wsStatus.state === "open") setDismissed(false);
|
|
5490
5646
|
}, [wsStatus.state]);
|
|
5491
5647
|
if (wsStatus.state === "open" || wsStatus.state === "connecting") return null;
|
|
@@ -5494,7 +5650,7 @@ function ConnectionBanner() {
|
|
|
5494
5650
|
const isReconnecting = wsStatus.state === "reconnecting";
|
|
5495
5651
|
const errorText = wsStatus.state === "closed" ? wsStatus.error : wsStatus.state === "reconnecting" ? wsStatus.lastError : void 0;
|
|
5496
5652
|
const remaining = isReconnecting ? Math.max(0, Math.ceil((wsStatus.nextRetryAt - now) / 1e3)) : 0;
|
|
5497
|
-
return /* @__PURE__ */
|
|
5653
|
+
return /* @__PURE__ */ jsxs19(
|
|
5498
5654
|
"div",
|
|
5499
5655
|
{
|
|
5500
5656
|
className: cn(
|
|
@@ -5502,12 +5658,12 @@ function ConnectionBanner() {
|
|
|
5502
5658
|
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"
|
|
5503
5659
|
),
|
|
5504
5660
|
children: [
|
|
5505
|
-
isReconnecting ? /* @__PURE__ */
|
|
5506
|
-
/* @__PURE__ */
|
|
5507
|
-
/* @__PURE__ */
|
|
5508
|
-
errorText && /* @__PURE__ */
|
|
5661
|
+
isReconnecting ? /* @__PURE__ */ jsx20(Loader23, { className: "h-4 w-4 animate-spin shrink-0" }) : /* @__PURE__ */ jsx20(WifiOff3, { className: "h-4 w-4 shrink-0" }),
|
|
5662
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 min-w-0", children: [
|
|
5663
|
+
/* @__PURE__ */ jsx20("div", { className: "font-medium", children: isReconnecting ? `Reconnecting to backend (attempt ${wsStatus.attempt}) \u2014 retrying in ${remaining}s` : "Disconnected from backend" }),
|
|
5664
|
+
errorText && /* @__PURE__ */ jsx20("div", { className: "text-xs opacity-80 truncate", children: errorText })
|
|
5509
5665
|
] }),
|
|
5510
|
-
/* @__PURE__ */
|
|
5666
|
+
/* @__PURE__ */ jsxs19(
|
|
5511
5667
|
"button",
|
|
5512
5668
|
{
|
|
5513
5669
|
type: "button",
|
|
@@ -5519,19 +5675,19 @@ function ConnectionBanner() {
|
|
|
5519
5675
|
),
|
|
5520
5676
|
title: "Retry connection now",
|
|
5521
5677
|
children: [
|
|
5522
|
-
/* @__PURE__ */
|
|
5678
|
+
/* @__PURE__ */ jsx20(RotateCcw4, { className: "h-3 w-3" }),
|
|
5523
5679
|
"Retry now"
|
|
5524
5680
|
]
|
|
5525
5681
|
}
|
|
5526
5682
|
),
|
|
5527
|
-
/* @__PURE__ */
|
|
5683
|
+
/* @__PURE__ */ jsx20(
|
|
5528
5684
|
"button",
|
|
5529
5685
|
{
|
|
5530
5686
|
type: "button",
|
|
5531
5687
|
onClick: () => setDismissed(true),
|
|
5532
5688
|
className: "text-current/60 hover:text-current shrink-0",
|
|
5533
5689
|
title: "Dismiss (chip in topbar still shows status)",
|
|
5534
|
-
children: /* @__PURE__ */
|
|
5690
|
+
children: /* @__PURE__ */ jsx20(X4, { className: "h-4 w-4" })
|
|
5535
5691
|
}
|
|
5536
5692
|
)
|
|
5537
5693
|
]
|
|
@@ -5542,7 +5698,7 @@ function ConnectionBanner() {
|
|
|
5542
5698
|
// src/components/ErrorBoundary.tsx
|
|
5543
5699
|
import { AlertTriangle as AlertTriangle3, RefreshCw } from "lucide-react";
|
|
5544
5700
|
import { Component } from "react";
|
|
5545
|
-
import { jsx as
|
|
5701
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
5546
5702
|
var ErrorBoundary = class extends Component {
|
|
5547
5703
|
state = { error: null };
|
|
5548
5704
|
static getDerivedStateFromError(error) {
|
|
@@ -5557,17 +5713,17 @@ var ErrorBoundary = class extends Component {
|
|
|
5557
5713
|
};
|
|
5558
5714
|
render() {
|
|
5559
5715
|
if (this.state.error) {
|
|
5560
|
-
return /* @__PURE__ */
|
|
5561
|
-
/* @__PURE__ */
|
|
5562
|
-
/* @__PURE__ */
|
|
5563
|
-
/* @__PURE__ */
|
|
5564
|
-
/* @__PURE__ */
|
|
5565
|
-
/* @__PURE__ */
|
|
5566
|
-
/* @__PURE__ */
|
|
5567
|
-
/* @__PURE__ */
|
|
5716
|
+
return /* @__PURE__ */ jsx21("div", { className: "flex items-center justify-center h-screen bg-background", children: /* @__PURE__ */ jsxs20("div", { className: "flex flex-col items-center gap-4 p-8 max-w-md text-center", children: [
|
|
5717
|
+
/* @__PURE__ */ jsx21(AlertTriangle3, { className: "h-12 w-12 text-destructive" }),
|
|
5718
|
+
/* @__PURE__ */ jsx21("h1", { className: "text-lg font-semibold", children: "Something went wrong" }),
|
|
5719
|
+
/* @__PURE__ */ jsx21("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." }),
|
|
5720
|
+
/* @__PURE__ */ jsx21("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 }),
|
|
5721
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex gap-2", children: [
|
|
5722
|
+
/* @__PURE__ */ jsxs20(Button, { size: "sm", variant: "outline", onClick: () => window.location.reload(), children: [
|
|
5723
|
+
/* @__PURE__ */ jsx21(RefreshCw, { className: "h-4 w-4 mr-1" }),
|
|
5568
5724
|
"Reload page"
|
|
5569
5725
|
] }),
|
|
5570
|
-
/* @__PURE__ */
|
|
5726
|
+
/* @__PURE__ */ jsx21(Button, { size: "sm", onClick: this.handleReset, children: "Try again" })
|
|
5571
5727
|
] })
|
|
5572
5728
|
] }) });
|
|
5573
5729
|
}
|
|
@@ -5577,22 +5733,22 @@ var ErrorBoundary = class extends Component {
|
|
|
5577
5733
|
|
|
5578
5734
|
// src/components/QuickModelSwitcher.tsx
|
|
5579
5735
|
import { ArrowRight as ArrowRight2, Cpu as Cpu3, Search as Search4 } from "lucide-react";
|
|
5580
|
-
import { useEffect as
|
|
5581
|
-
import { jsx as
|
|
5736
|
+
import { useEffect as useEffect15, useMemo as useMemo5, useRef as useRef10, useState as useState15 } from "react";
|
|
5737
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5582
5738
|
function QuickModelSwitcher() {
|
|
5583
5739
|
const open = useUIStore((s) => s.modelSwitcherOpen);
|
|
5584
5740
|
const setOpen = useUIStore((s) => s.setModelSwitcherOpen);
|
|
5585
|
-
const [query, setQuery] =
|
|
5586
|
-
const [selected, setSelected] =
|
|
5587
|
-
const [saved, setSaved] =
|
|
5588
|
-
const [modelsByProvider, setModelsByProvider] =
|
|
5589
|
-
const inputRef =
|
|
5741
|
+
const [query, setQuery] = useState15("");
|
|
5742
|
+
const [selected, setSelected] = useState15(0);
|
|
5743
|
+
const [saved, setSaved] = useState15([]);
|
|
5744
|
+
const [modelsByProvider, setModelsByProvider] = useState15({});
|
|
5745
|
+
const inputRef = useRef10(null);
|
|
5590
5746
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
5591
5747
|
const currentProvider = useConfigStore((s) => s.provider);
|
|
5592
5748
|
const currentModel = useConfigStore((s) => s.model);
|
|
5593
5749
|
const paletteOpen = useUIStore((s) => s.paletteOpen);
|
|
5594
5750
|
const ws = useWebSocket();
|
|
5595
|
-
|
|
5751
|
+
useEffect15(() => {
|
|
5596
5752
|
const onKey = (e) => {
|
|
5597
5753
|
const mod = e.ctrlKey || e.metaKey;
|
|
5598
5754
|
if (mod && e.key.toLowerCase() === "m" && !e.shiftKey && !e.altKey) {
|
|
@@ -5609,7 +5765,7 @@ function QuickModelSwitcher() {
|
|
|
5609
5765
|
window.addEventListener("keydown", onKey);
|
|
5610
5766
|
return () => window.removeEventListener("keydown", onKey);
|
|
5611
5767
|
}, [open, paletteOpen]);
|
|
5612
|
-
|
|
5768
|
+
useEffect15(() => {
|
|
5613
5769
|
const client2 = getWSClient(wsUrl);
|
|
5614
5770
|
const offSaved = client2.on("providers.saved", (msg) => {
|
|
5615
5771
|
const p = msg.payload;
|
|
@@ -5624,14 +5780,14 @@ function QuickModelSwitcher() {
|
|
|
5624
5780
|
offModels();
|
|
5625
5781
|
};
|
|
5626
5782
|
}, [wsUrl]);
|
|
5627
|
-
|
|
5783
|
+
useEffect15(() => {
|
|
5628
5784
|
if (!open) return;
|
|
5629
5785
|
setQuery("");
|
|
5630
5786
|
setSelected(0);
|
|
5631
5787
|
ws.listSavedProviders();
|
|
5632
5788
|
requestAnimationFrame(() => inputRef.current?.focus());
|
|
5633
5789
|
}, [open, ws]);
|
|
5634
|
-
|
|
5790
|
+
useEffect15(() => {
|
|
5635
5791
|
if (!open) return;
|
|
5636
5792
|
for (const sp of saved) {
|
|
5637
5793
|
if (!modelsByProvider[sp.id]) {
|
|
@@ -5662,7 +5818,7 @@ function QuickModelSwitcher() {
|
|
|
5662
5818
|
return a.provider.localeCompare(b.provider) || a.model.localeCompare(b.model);
|
|
5663
5819
|
});
|
|
5664
5820
|
}, [saved, modelsByProvider, query, currentProvider, currentModel]);
|
|
5665
|
-
|
|
5821
|
+
useEffect15(() => {
|
|
5666
5822
|
if (selected >= candidates.length) setSelected(0);
|
|
5667
5823
|
}, [candidates.length, selected]);
|
|
5668
5824
|
const commit = (idx) => {
|
|
@@ -5672,7 +5828,7 @@ function QuickModelSwitcher() {
|
|
|
5672
5828
|
setOpen(false);
|
|
5673
5829
|
};
|
|
5674
5830
|
if (!open) return null;
|
|
5675
|
-
return /* @__PURE__ */
|
|
5831
|
+
return /* @__PURE__ */ jsx22(
|
|
5676
5832
|
"div",
|
|
5677
5833
|
{
|
|
5678
5834
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-background/60 backdrop-blur-sm pt-[15vh]",
|
|
@@ -5682,10 +5838,10 @@ function QuickModelSwitcher() {
|
|
|
5682
5838
|
onKeyDown: (e) => {
|
|
5683
5839
|
if (e.key === "Escape") setOpen(false);
|
|
5684
5840
|
},
|
|
5685
|
-
children: /* @__PURE__ */
|
|
5686
|
-
/* @__PURE__ */
|
|
5687
|
-
/* @__PURE__ */
|
|
5688
|
-
/* @__PURE__ */
|
|
5841
|
+
children: /* @__PURE__ */ jsxs21("div", { className: "w-full max-w-xl rounded-xl border bg-popover shadow-2xl overflow-hidden", children: [
|
|
5842
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-2 border-b px-3 py-2", children: [
|
|
5843
|
+
/* @__PURE__ */ jsx22(Search4, { className: "h-4 w-4 text-muted-foreground" }),
|
|
5844
|
+
/* @__PURE__ */ jsx22(
|
|
5689
5845
|
"input",
|
|
5690
5846
|
{
|
|
5691
5847
|
ref: inputRef,
|
|
@@ -5713,9 +5869,9 @@ function QuickModelSwitcher() {
|
|
|
5713
5869
|
className: "flex-1 bg-transparent outline-none text-sm placeholder:text-muted-foreground"
|
|
5714
5870
|
}
|
|
5715
5871
|
),
|
|
5716
|
-
/* @__PURE__ */
|
|
5872
|
+
/* @__PURE__ */ jsx22("span", { className: "text-[10px] text-muted-foreground font-mono", children: "\u2191\u2193 \xB7 Enter \xB7 Esc" })
|
|
5717
5873
|
] }),
|
|
5718
|
-
/* @__PURE__ */
|
|
5874
|
+
/* @__PURE__ */ jsx22("div", { className: "max-h-[50vh] overflow-y-auto py-1", children: candidates.length === 0 ? /* @__PURE__ */ jsx22("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__ */ jsxs21(
|
|
5719
5875
|
"button",
|
|
5720
5876
|
{
|
|
5721
5877
|
type: "button",
|
|
@@ -5727,7 +5883,7 @@ function QuickModelSwitcher() {
|
|
|
5727
5883
|
c.isCurrent && "font-medium"
|
|
5728
5884
|
),
|
|
5729
5885
|
children: [
|
|
5730
|
-
/* @__PURE__ */
|
|
5886
|
+
/* @__PURE__ */ jsx22(
|
|
5731
5887
|
Cpu3,
|
|
5732
5888
|
{
|
|
5733
5889
|
className: cn(
|
|
@@ -5736,19 +5892,19 @@ function QuickModelSwitcher() {
|
|
|
5736
5892
|
)
|
|
5737
5893
|
}
|
|
5738
5894
|
),
|
|
5739
|
-
/* @__PURE__ */
|
|
5740
|
-
/* @__PURE__ */
|
|
5741
|
-
/* @__PURE__ */
|
|
5742
|
-
/* @__PURE__ */
|
|
5743
|
-
/* @__PURE__ */
|
|
5895
|
+
/* @__PURE__ */ jsxs21("div", { className: "min-w-0 flex-1", children: [
|
|
5896
|
+
/* @__PURE__ */ jsxs21("div", { className: "truncate", children: [
|
|
5897
|
+
/* @__PURE__ */ jsx22("span", { className: "text-muted-foreground", children: c.provider }),
|
|
5898
|
+
/* @__PURE__ */ jsx22("span", { className: "mx-1 text-muted-foreground/40", children: "\xB7" }),
|
|
5899
|
+
/* @__PURE__ */ jsx22("span", { children: c.modelName })
|
|
5744
5900
|
] }),
|
|
5745
|
-
c.contextWindow && /* @__PURE__ */
|
|
5901
|
+
c.contextWindow && /* @__PURE__ */ jsxs21("div", { className: "text-[10px] text-muted-foreground font-mono", children: [
|
|
5746
5902
|
c.model,
|
|
5747
5903
|
" \xB7 ctx ",
|
|
5748
5904
|
c.contextWindow.toLocaleString()
|
|
5749
5905
|
] })
|
|
5750
5906
|
] }),
|
|
5751
|
-
c.isCurrent ? /* @__PURE__ */
|
|
5907
|
+
c.isCurrent ? /* @__PURE__ */ jsx22("span", { className: "text-[10px] uppercase tracking-wide text-primary font-semibold", children: "active" }) : /* @__PURE__ */ jsx22(ArrowRight2, { className: "h-3.5 w-3.5 text-muted-foreground opacity-0 group-hover:opacity-100" })
|
|
5752
5908
|
]
|
|
5753
5909
|
},
|
|
5754
5910
|
`${c.provider}:${c.model}`
|
|
@@ -5778,11 +5934,11 @@ import {
|
|
|
5778
5934
|
Trash2 as Trash22,
|
|
5779
5935
|
X as X5
|
|
5780
5936
|
} from "lucide-react";
|
|
5781
|
-
import { useState as
|
|
5937
|
+
import { useState as useState17, useEffect as useEffect17, useCallback as useCallback4 } from "react";
|
|
5782
5938
|
|
|
5783
5939
|
// src/components/ThemeProvider.tsx
|
|
5784
|
-
import { createContext, useContext, useEffect as
|
|
5785
|
-
import { jsx as
|
|
5940
|
+
import { createContext, useContext, useEffect as useEffect16, useState as useState16 } from "react";
|
|
5941
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
5786
5942
|
var ThemeProviderContext = createContext(void 0);
|
|
5787
5943
|
function ThemeProvider({
|
|
5788
5944
|
children,
|
|
@@ -5790,13 +5946,13 @@ function ThemeProvider({
|
|
|
5790
5946
|
storageKey = "wrongstack-theme"
|
|
5791
5947
|
}) {
|
|
5792
5948
|
const { theme: storeTheme, setTheme: setStoreTheme } = useConfigStore();
|
|
5793
|
-
const [theme, setTheme] =
|
|
5949
|
+
const [theme, setTheme] = useState16(() => {
|
|
5794
5950
|
if (typeof window !== "undefined") {
|
|
5795
5951
|
return localStorage.getItem(storageKey) || defaultTheme;
|
|
5796
5952
|
}
|
|
5797
5953
|
return defaultTheme;
|
|
5798
5954
|
});
|
|
5799
|
-
|
|
5955
|
+
useEffect16(() => {
|
|
5800
5956
|
const root = window.document.documentElement;
|
|
5801
5957
|
root.classList.remove("light", "dark");
|
|
5802
5958
|
if (theme === "system") {
|
|
@@ -5814,7 +5970,7 @@ function ThemeProvider({
|
|
|
5814
5970
|
setStoreTheme(newTheme);
|
|
5815
5971
|
}
|
|
5816
5972
|
};
|
|
5817
|
-
return /* @__PURE__ */
|
|
5973
|
+
return /* @__PURE__ */ jsx23(ThemeProviderContext.Provider, { value, children });
|
|
5818
5974
|
}
|
|
5819
5975
|
function useTheme() {
|
|
5820
5976
|
const context = useContext(ThemeProviderContext);
|
|
@@ -5826,10 +5982,10 @@ function useTheme() {
|
|
|
5826
5982
|
|
|
5827
5983
|
// src/components/ui/input.tsx
|
|
5828
5984
|
import * as React4 from "react";
|
|
5829
|
-
import { jsx as
|
|
5985
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
5830
5986
|
var Input = React4.forwardRef(
|
|
5831
5987
|
({ className, type, ...props }, ref) => {
|
|
5832
|
-
return /* @__PURE__ */
|
|
5988
|
+
return /* @__PURE__ */ jsx24(
|
|
5833
5989
|
"input",
|
|
5834
5990
|
{
|
|
5835
5991
|
type,
|
|
@@ -5848,9 +6004,9 @@ Input.displayName = "Input";
|
|
|
5848
6004
|
// src/components/ui/tabs.tsx
|
|
5849
6005
|
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
5850
6006
|
import * as React5 from "react";
|
|
5851
|
-
import { jsx as
|
|
6007
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
5852
6008
|
var Tabs = TabsPrimitive.Root;
|
|
5853
|
-
var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6009
|
+
var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
5854
6010
|
TabsPrimitive.List,
|
|
5855
6011
|
{
|
|
5856
6012
|
ref,
|
|
@@ -5862,7 +6018,7 @@ var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
5862
6018
|
}
|
|
5863
6019
|
));
|
|
5864
6020
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
5865
|
-
var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6021
|
+
var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
5866
6022
|
TabsPrimitive.Trigger,
|
|
5867
6023
|
{
|
|
5868
6024
|
ref,
|
|
@@ -5874,7 +6030,7 @@ var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5874
6030
|
}
|
|
5875
6031
|
));
|
|
5876
6032
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
5877
|
-
var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6033
|
+
var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
5878
6034
|
TabsPrimitive.Content,
|
|
5879
6035
|
{
|
|
5880
6036
|
ref,
|
|
@@ -5888,7 +6044,7 @@ var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5888
6044
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
5889
6045
|
|
|
5890
6046
|
// src/components/SettingsPanel.tsx
|
|
5891
|
-
import { Fragment as Fragment7, jsx as
|
|
6047
|
+
import { Fragment as Fragment7, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5892
6048
|
function SettingsPanel() {
|
|
5893
6049
|
const { setCurrentView } = useUIStore();
|
|
5894
6050
|
const { provider, model, setProvider, setModel, wsConnected } = useConfigStore();
|
|
@@ -5897,25 +6053,25 @@ function SettingsPanel() {
|
|
|
5897
6053
|
const wsClient = ws.client;
|
|
5898
6054
|
const listProviders = ws.listProviders;
|
|
5899
6055
|
const listSavedProviders = ws.listSavedProviders;
|
|
5900
|
-
const [catalogProviders, setCatalogProviders] =
|
|
5901
|
-
const [catalogModels, setCatalogModels] =
|
|
5902
|
-
const [savedProviders, setSavedProviders] =
|
|
5903
|
-
const [isLoadingCatalog, setIsLoadingCatalog] =
|
|
5904
|
-
const [isLoadingModels, setIsLoadingModels] =
|
|
5905
|
-
const [isLoadingSaved, setIsLoadingSaved] =
|
|
5906
|
-
const [operationStatus, setOperationStatus] =
|
|
5907
|
-
const [providerTab, setProviderTab] =
|
|
5908
|
-
const [showAddKeyForm, setShowAddKeyForm] =
|
|
5909
|
-
const [newKeyLabel, setNewKeyLabel] =
|
|
5910
|
-
const [newKeyValue, setNewKeyValue] =
|
|
5911
|
-
const [showNewKeyValue, setShowNewKeyValue] =
|
|
5912
|
-
const [showAddProviderForm, setShowAddProviderForm] =
|
|
5913
|
-
const [newProviderId, setNewProviderId] =
|
|
5914
|
-
const [newProviderFamily, setNewProviderFamily] =
|
|
5915
|
-
const [newProviderBaseUrl, setNewProviderBaseUrl] =
|
|
5916
|
-
const [newProviderApiKey, setNewProviderApiKey] =
|
|
6056
|
+
const [catalogProviders, setCatalogProviders] = useState17([]);
|
|
6057
|
+
const [catalogModels, setCatalogModels] = useState17({});
|
|
6058
|
+
const [savedProviders, setSavedProviders] = useState17([]);
|
|
6059
|
+
const [isLoadingCatalog, setIsLoadingCatalog] = useState17(false);
|
|
6060
|
+
const [isLoadingModels, setIsLoadingModels] = useState17(false);
|
|
6061
|
+
const [isLoadingSaved, setIsLoadingSaved] = useState17(false);
|
|
6062
|
+
const [operationStatus, setOperationStatus] = useState17(null);
|
|
6063
|
+
const [providerTab, setProviderTab] = useState17("catalog");
|
|
6064
|
+
const [showAddKeyForm, setShowAddKeyForm] = useState17(null);
|
|
6065
|
+
const [newKeyLabel, setNewKeyLabel] = useState17("");
|
|
6066
|
+
const [newKeyValue, setNewKeyValue] = useState17("");
|
|
6067
|
+
const [showNewKeyValue, setShowNewKeyValue] = useState17(false);
|
|
6068
|
+
const [showAddProviderForm, setShowAddProviderForm] = useState17(false);
|
|
6069
|
+
const [newProviderId, setNewProviderId] = useState17("");
|
|
6070
|
+
const [newProviderFamily, setNewProviderFamily] = useState17("openai-compatible");
|
|
6071
|
+
const [newProviderBaseUrl, setNewProviderBaseUrl] = useState17("");
|
|
6072
|
+
const [newProviderApiKey, setNewProviderApiKey] = useState17("");
|
|
5917
6073
|
const currentCatalogProvider = catalogProviders.find((p) => p.id === provider);
|
|
5918
|
-
|
|
6074
|
+
useEffect17(() => {
|
|
5919
6075
|
const handleProviderCatalog = (msg) => {
|
|
5920
6076
|
if (msg.type === "provider.catalog") {
|
|
5921
6077
|
const payload = msg.payload;
|
|
@@ -6023,7 +6179,7 @@ function SettingsPanel() {
|
|
|
6023
6179
|
},
|
|
6024
6180
|
[ws]
|
|
6025
6181
|
);
|
|
6026
|
-
const [catalogQuery, setCatalogQuery] =
|
|
6182
|
+
const [catalogQuery, setCatalogQuery] = useState17("");
|
|
6027
6183
|
const families = ["anthropic", "openai", "google", "openai-compatible"];
|
|
6028
6184
|
const filteredCatalog = catalogQuery.trim() ? catalogProviders.filter((p) => {
|
|
6029
6185
|
const q = catalogQuery.trim().toLowerCase();
|
|
@@ -6037,52 +6193,52 @@ function SettingsPanel() {
|
|
|
6037
6193
|
},
|
|
6038
6194
|
{}
|
|
6039
6195
|
);
|
|
6040
|
-
return /* @__PURE__ */
|
|
6041
|
-
/* @__PURE__ */
|
|
6042
|
-
/* @__PURE__ */
|
|
6043
|
-
/* @__PURE__ */
|
|
6196
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col h-full", children: [
|
|
6197
|
+
/* @__PURE__ */ jsxs22("header", { className: "flex items-center justify-between px-4 py-3 border-b bg-card shrink-0", children: [
|
|
6198
|
+
/* @__PURE__ */ jsx26("h1", { className: "text-lg font-semibold", children: "Settings" }),
|
|
6199
|
+
/* @__PURE__ */ jsx26(Button, { variant: "ghost", size: "icon", onClick: () => setCurrentView("chat"), children: /* @__PURE__ */ jsx26(X5, { className: "h-4 w-4" }) })
|
|
6044
6200
|
] }),
|
|
6045
|
-
/* @__PURE__ */
|
|
6046
|
-
/* @__PURE__ */
|
|
6047
|
-
/* @__PURE__ */
|
|
6048
|
-
/* @__PURE__ */
|
|
6201
|
+
/* @__PURE__ */ jsx26(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsx26("div", { className: "p-6 max-w-2xl mx-auto", children: /* @__PURE__ */ jsxs22(Tabs, { defaultValue: "provider", children: [
|
|
6202
|
+
/* @__PURE__ */ jsxs22(TabsList, { className: "w-full justify-start mb-6 grid grid-cols-4", children: [
|
|
6203
|
+
/* @__PURE__ */ jsxs22(TabsTrigger, { value: "provider", className: "gap-2", children: [
|
|
6204
|
+
/* @__PURE__ */ jsx26(Network, { className: "h-4 w-4" }),
|
|
6049
6205
|
"Provider"
|
|
6050
6206
|
] }),
|
|
6051
|
-
/* @__PURE__ */
|
|
6052
|
-
/* @__PURE__ */
|
|
6207
|
+
/* @__PURE__ */ jsxs22(TabsTrigger, { value: "model", className: "gap-2", children: [
|
|
6208
|
+
/* @__PURE__ */ jsx26(Cpu4, { className: "h-4 w-4" }),
|
|
6053
6209
|
"Model"
|
|
6054
6210
|
] }),
|
|
6055
|
-
/* @__PURE__ */
|
|
6056
|
-
/* @__PURE__ */
|
|
6211
|
+
/* @__PURE__ */ jsxs22(TabsTrigger, { value: "connection", className: "gap-2", children: [
|
|
6212
|
+
/* @__PURE__ */ jsx26(Globe2, { className: "h-4 w-4" }),
|
|
6057
6213
|
"Connection"
|
|
6058
6214
|
] }),
|
|
6059
|
-
/* @__PURE__ */
|
|
6060
|
-
/* @__PURE__ */
|
|
6215
|
+
/* @__PURE__ */ jsxs22(TabsTrigger, { value: "appearance", className: "gap-2", children: [
|
|
6216
|
+
/* @__PURE__ */ jsx26(Palette, { className: "h-4 w-4" }),
|
|
6061
6217
|
"Appearance"
|
|
6062
6218
|
] })
|
|
6063
6219
|
] }),
|
|
6064
|
-
/* @__PURE__ */
|
|
6065
|
-
/* @__PURE__ */
|
|
6066
|
-
/* @__PURE__ */
|
|
6220
|
+
/* @__PURE__ */ jsxs22(TabsContent, { value: "provider", className: "space-y-4", children: [
|
|
6221
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex gap-2 mb-4", children: [
|
|
6222
|
+
/* @__PURE__ */ jsxs22(
|
|
6067
6223
|
Button,
|
|
6068
6224
|
{
|
|
6069
6225
|
variant: providerTab === "catalog" ? "default" : "outline",
|
|
6070
6226
|
size: "sm",
|
|
6071
6227
|
onClick: () => setProviderTab("catalog"),
|
|
6072
6228
|
children: [
|
|
6073
|
-
/* @__PURE__ */
|
|
6229
|
+
/* @__PURE__ */ jsx26(Globe2, { className: "h-4 w-4 mr-1" }),
|
|
6074
6230
|
"Catalog"
|
|
6075
6231
|
]
|
|
6076
6232
|
}
|
|
6077
6233
|
),
|
|
6078
|
-
/* @__PURE__ */
|
|
6234
|
+
/* @__PURE__ */ jsxs22(
|
|
6079
6235
|
Button,
|
|
6080
6236
|
{
|
|
6081
6237
|
variant: providerTab === "saved" ? "default" : "outline",
|
|
6082
6238
|
size: "sm",
|
|
6083
6239
|
onClick: () => setProviderTab("saved"),
|
|
6084
6240
|
children: [
|
|
6085
|
-
/* @__PURE__ */
|
|
6241
|
+
/* @__PURE__ */ jsx26(Key, { className: "h-4 w-4 mr-1" }),
|
|
6086
6242
|
"Saved (",
|
|
6087
6243
|
savedProviders.length,
|
|
6088
6244
|
")"
|
|
@@ -6090,7 +6246,7 @@ function SettingsPanel() {
|
|
|
6090
6246
|
}
|
|
6091
6247
|
)
|
|
6092
6248
|
] }),
|
|
6093
|
-
operationStatus && /* @__PURE__ */
|
|
6249
|
+
operationStatus && /* @__PURE__ */ jsxs22(
|
|
6094
6250
|
"div",
|
|
6095
6251
|
{
|
|
6096
6252
|
className: cn(
|
|
@@ -6098,13 +6254,13 @@ function SettingsPanel() {
|
|
|
6098
6254
|
operationStatus.success ? "bg-green-500/10 text-green-600" : "bg-red-500/10 text-red-600"
|
|
6099
6255
|
),
|
|
6100
6256
|
children: [
|
|
6101
|
-
operationStatus.success ? /* @__PURE__ */
|
|
6257
|
+
operationStatus.success ? /* @__PURE__ */ jsx26(CheckCircle24, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx26(AlertCircle, { className: "h-4 w-4" }),
|
|
6102
6258
|
operationStatus.message
|
|
6103
6259
|
]
|
|
6104
6260
|
}
|
|
6105
6261
|
),
|
|
6106
|
-
providerTab === "catalog" && /* @__PURE__ */
|
|
6107
|
-
/* @__PURE__ */
|
|
6262
|
+
providerTab === "catalog" && /* @__PURE__ */ jsxs22("div", { className: "space-y-4", children: [
|
|
6263
|
+
/* @__PURE__ */ jsx26(
|
|
6108
6264
|
Input,
|
|
6109
6265
|
{
|
|
6110
6266
|
placeholder: `Search ${catalogProviders.length} providers (name / id / family)\u2026`,
|
|
@@ -6113,19 +6269,19 @@ function SettingsPanel() {
|
|
|
6113
6269
|
className: "text-sm"
|
|
6114
6270
|
}
|
|
6115
6271
|
),
|
|
6116
|
-
isLoadingCatalog && catalogProviders.length === 0 ? /* @__PURE__ */
|
|
6117
|
-
/* @__PURE__ */
|
|
6118
|
-
/* @__PURE__ */
|
|
6119
|
-
] }) : filteredCatalog.length === 0 && catalogQuery ? /* @__PURE__ */
|
|
6272
|
+
isLoadingCatalog && catalogProviders.length === 0 ? /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-center py-8", children: [
|
|
6273
|
+
/* @__PURE__ */ jsx26(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }),
|
|
6274
|
+
/* @__PURE__ */ jsx26("span", { className: "ml-2 text-muted-foreground", children: "Loading catalog..." })
|
|
6275
|
+
] }) : filteredCatalog.length === 0 && catalogQuery ? /* @__PURE__ */ jsxs22("div", { className: "text-center py-8 text-muted-foreground text-sm", children: [
|
|
6120
6276
|
'No providers match "',
|
|
6121
|
-
/* @__PURE__ */
|
|
6277
|
+
/* @__PURE__ */ jsx26("span", { className: "font-mono", children: catalogQuery }),
|
|
6122
6278
|
'".'
|
|
6123
|
-
] }) : /* @__PURE__ */
|
|
6279
|
+
] }) : /* @__PURE__ */ jsx26(Fragment7, { children: families.map((family) => {
|
|
6124
6280
|
const providers = catalogByFamily[family];
|
|
6125
6281
|
if (!providers?.length) return null;
|
|
6126
|
-
return /* @__PURE__ */
|
|
6127
|
-
/* @__PURE__ */
|
|
6128
|
-
/* @__PURE__ */
|
|
6282
|
+
return /* @__PURE__ */ jsxs22("div", { className: "space-y-2", children: [
|
|
6283
|
+
/* @__PURE__ */ jsx26("h3", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-wider", children: family }),
|
|
6284
|
+
/* @__PURE__ */ jsx26("div", { className: "grid grid-cols-1 gap-2", children: providers.map((p) => /* @__PURE__ */ jsxs22(
|
|
6129
6285
|
"button",
|
|
6130
6286
|
{
|
|
6131
6287
|
type: "button",
|
|
@@ -6135,28 +6291,28 @@ function SettingsPanel() {
|
|
|
6135
6291
|
provider === p.id ? "border-primary bg-primary/5 ring-2 ring-primary/20" : "border-border hover:bg-muted"
|
|
6136
6292
|
),
|
|
6137
6293
|
children: [
|
|
6138
|
-
/* @__PURE__ */
|
|
6139
|
-
/* @__PURE__ */
|
|
6140
|
-
/* @__PURE__ */
|
|
6141
|
-
/* @__PURE__ */
|
|
6294
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex w-full justify-between items-start", children: [
|
|
6295
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
6296
|
+
/* @__PURE__ */ jsx26("span", { className: "font-medium", children: p.name }),
|
|
6297
|
+
/* @__PURE__ */ jsxs22("span", { className: "ml-2 text-xs text-muted-foreground", children: [
|
|
6142
6298
|
"(",
|
|
6143
6299
|
p.id,
|
|
6144
6300
|
")"
|
|
6145
6301
|
] })
|
|
6146
6302
|
] }),
|
|
6147
|
-
/* @__PURE__ */
|
|
6148
|
-
p.hasApiKey && /* @__PURE__ */
|
|
6149
|
-
/* @__PURE__ */
|
|
6303
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2", children: [
|
|
6304
|
+
p.hasApiKey && /* @__PURE__ */ jsxs22("span", { className: "text-xs bg-green-500/10 text-green-600 px-2 py-0.5 rounded", children: [
|
|
6305
|
+
/* @__PURE__ */ jsx26(Key, { className: "h-3 w-3 inline mr-1" }),
|
|
6150
6306
|
"Configured"
|
|
6151
6307
|
] }),
|
|
6152
|
-
p.envVars[0] && /* @__PURE__ */
|
|
6308
|
+
p.envVars[0] && /* @__PURE__ */ jsxs22("span", { className: "text-xs text-muted-foreground", children: [
|
|
6153
6309
|
"ENV: ",
|
|
6154
6310
|
p.envVars[0]
|
|
6155
6311
|
] }),
|
|
6156
|
-
provider === p.id && /* @__PURE__ */
|
|
6312
|
+
provider === p.id && /* @__PURE__ */ jsx26(CheckCircle24, { className: "h-4 w-4 text-primary" })
|
|
6157
6313
|
] })
|
|
6158
6314
|
] }),
|
|
6159
|
-
/* @__PURE__ */
|
|
6315
|
+
/* @__PURE__ */ jsxs22("div", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
6160
6316
|
p.modelCount,
|
|
6161
6317
|
" models",
|
|
6162
6318
|
p.apiBase && ` \xB7 ${p.apiBase}`
|
|
@@ -6168,25 +6324,25 @@ function SettingsPanel() {
|
|
|
6168
6324
|
] }, family);
|
|
6169
6325
|
}) })
|
|
6170
6326
|
] }),
|
|
6171
|
-
providerTab === "saved" && /* @__PURE__ */
|
|
6172
|
-
/* @__PURE__ */
|
|
6173
|
-
/* @__PURE__ */
|
|
6174
|
-
/* @__PURE__ */
|
|
6327
|
+
providerTab === "saved" && /* @__PURE__ */ jsxs22("div", { className: "space-y-4", children: [
|
|
6328
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex justify-between items-center", children: [
|
|
6329
|
+
/* @__PURE__ */ jsx26("p", { className: "text-sm text-muted-foreground", children: "Manage your API keys and provider configurations" }),
|
|
6330
|
+
/* @__PURE__ */ jsxs22(
|
|
6175
6331
|
Button,
|
|
6176
6332
|
{
|
|
6177
6333
|
size: "sm",
|
|
6178
6334
|
variant: "outline",
|
|
6179
6335
|
onClick: () => setShowAddProviderForm(!showAddProviderForm),
|
|
6180
6336
|
children: [
|
|
6181
|
-
/* @__PURE__ */
|
|
6337
|
+
/* @__PURE__ */ jsx26(Plus, { className: "h-4 w-4 mr-1" }),
|
|
6182
6338
|
"Add Provider"
|
|
6183
6339
|
]
|
|
6184
6340
|
}
|
|
6185
6341
|
)
|
|
6186
6342
|
] }),
|
|
6187
|
-
showAddProviderForm && /* @__PURE__ */
|
|
6188
|
-
/* @__PURE__ */
|
|
6189
|
-
/* @__PURE__ */
|
|
6343
|
+
showAddProviderForm && /* @__PURE__ */ jsxs22("div", { className: "p-4 border rounded-lg space-y-3 bg-muted/50", children: [
|
|
6344
|
+
/* @__PURE__ */ jsx26("h4", { className: "font-medium", children: "Add Custom Provider" }),
|
|
6345
|
+
/* @__PURE__ */ jsx26(
|
|
6190
6346
|
Input,
|
|
6191
6347
|
{
|
|
6192
6348
|
placeholder: "Provider ID (e.g. my-llm-server)",
|
|
@@ -6194,21 +6350,21 @@ function SettingsPanel() {
|
|
|
6194
6350
|
onChange: (e) => setNewProviderId(e.target.value)
|
|
6195
6351
|
}
|
|
6196
6352
|
),
|
|
6197
|
-
/* @__PURE__ */
|
|
6353
|
+
/* @__PURE__ */ jsxs22(
|
|
6198
6354
|
"select",
|
|
6199
6355
|
{
|
|
6200
6356
|
className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
6201
6357
|
value: newProviderFamily,
|
|
6202
6358
|
onChange: (e) => setNewProviderFamily(e.target.value),
|
|
6203
6359
|
children: [
|
|
6204
|
-
/* @__PURE__ */
|
|
6205
|
-
/* @__PURE__ */
|
|
6206
|
-
/* @__PURE__ */
|
|
6207
|
-
/* @__PURE__ */
|
|
6360
|
+
/* @__PURE__ */ jsx26("option", { value: "anthropic", children: "Anthropic" }),
|
|
6361
|
+
/* @__PURE__ */ jsx26("option", { value: "openai", children: "OpenAI" }),
|
|
6362
|
+
/* @__PURE__ */ jsx26("option", { value: "openai-compatible", children: "OpenAI Compatible" }),
|
|
6363
|
+
/* @__PURE__ */ jsx26("option", { value: "google", children: "Google" })
|
|
6208
6364
|
]
|
|
6209
6365
|
}
|
|
6210
6366
|
),
|
|
6211
|
-
/* @__PURE__ */
|
|
6367
|
+
/* @__PURE__ */ jsx26(
|
|
6212
6368
|
Input,
|
|
6213
6369
|
{
|
|
6214
6370
|
placeholder: "Base URL (optional, e.g. http://localhost:11434/v1)",
|
|
@@ -6216,7 +6372,7 @@ function SettingsPanel() {
|
|
|
6216
6372
|
onChange: (e) => setNewProviderBaseUrl(e.target.value)
|
|
6217
6373
|
}
|
|
6218
6374
|
),
|
|
6219
|
-
/* @__PURE__ */
|
|
6375
|
+
/* @__PURE__ */ jsx26(
|
|
6220
6376
|
Input,
|
|
6221
6377
|
{
|
|
6222
6378
|
type: "password",
|
|
@@ -6225,8 +6381,8 @@ function SettingsPanel() {
|
|
|
6225
6381
|
onChange: (e) => setNewProviderApiKey(e.target.value)
|
|
6226
6382
|
}
|
|
6227
6383
|
),
|
|
6228
|
-
/* @__PURE__ */
|
|
6229
|
-
/* @__PURE__ */
|
|
6384
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex gap-2", children: [
|
|
6385
|
+
/* @__PURE__ */ jsx26(
|
|
6230
6386
|
Button,
|
|
6231
6387
|
{
|
|
6232
6388
|
size: "sm",
|
|
@@ -6235,7 +6391,7 @@ function SettingsPanel() {
|
|
|
6235
6391
|
children: "Add"
|
|
6236
6392
|
}
|
|
6237
6393
|
),
|
|
6238
|
-
/* @__PURE__ */
|
|
6394
|
+
/* @__PURE__ */ jsx26(
|
|
6239
6395
|
Button,
|
|
6240
6396
|
{
|
|
6241
6397
|
size: "sm",
|
|
@@ -6246,59 +6402,59 @@ function SettingsPanel() {
|
|
|
6246
6402
|
)
|
|
6247
6403
|
] })
|
|
6248
6404
|
] }),
|
|
6249
|
-
isLoadingSaved ? /* @__PURE__ */
|
|
6250
|
-
/* @__PURE__ */
|
|
6251
|
-
/* @__PURE__ */
|
|
6252
|
-
/* @__PURE__ */
|
|
6253
|
-
] }) : savedProviders.map((sp) => /* @__PURE__ */
|
|
6254
|
-
/* @__PURE__ */
|
|
6255
|
-
/* @__PURE__ */
|
|
6256
|
-
/* @__PURE__ */
|
|
6257
|
-
sp.family && /* @__PURE__ */
|
|
6405
|
+
isLoadingSaved ? /* @__PURE__ */ jsx26("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx26(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : savedProviders.length === 0 ? /* @__PURE__ */ jsxs22("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
6406
|
+
/* @__PURE__ */ jsx26(Key, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
|
|
6407
|
+
/* @__PURE__ */ jsx26("p", { children: "No saved providers yet" }),
|
|
6408
|
+
/* @__PURE__ */ jsx26("p", { className: "text-sm", children: "Add a provider to get started" })
|
|
6409
|
+
] }) : savedProviders.map((sp) => /* @__PURE__ */ jsxs22("div", { className: "border rounded-lg p-4 space-y-3", children: [
|
|
6410
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex justify-between items-start", children: [
|
|
6411
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
6412
|
+
/* @__PURE__ */ jsx26("h4", { className: "font-medium", children: sp.id }),
|
|
6413
|
+
sp.family && /* @__PURE__ */ jsx26("span", { className: "text-xs text-muted-foreground", children: sp.family })
|
|
6258
6414
|
] }),
|
|
6259
|
-
/* @__PURE__ */
|
|
6415
|
+
/* @__PURE__ */ jsx26("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx26(
|
|
6260
6416
|
Button,
|
|
6261
6417
|
{
|
|
6262
6418
|
size: "icon",
|
|
6263
6419
|
variant: "ghost",
|
|
6264
6420
|
onClick: () => handleRemoveProvider(sp.id),
|
|
6265
|
-
children: /* @__PURE__ */
|
|
6421
|
+
children: /* @__PURE__ */ jsx26(Trash22, { className: "h-4 w-4 text-destructive" })
|
|
6266
6422
|
}
|
|
6267
6423
|
) })
|
|
6268
6424
|
] }),
|
|
6269
|
-
sp.baseUrl && /* @__PURE__ */
|
|
6270
|
-
/* @__PURE__ */
|
|
6425
|
+
sp.baseUrl && /* @__PURE__ */ jsxs22("div", { className: "text-xs text-muted-foreground", children: [
|
|
6426
|
+
/* @__PURE__ */ jsx26(Globe2, { className: "h-3 w-3 inline mr-1" }),
|
|
6271
6427
|
sp.baseUrl
|
|
6272
6428
|
] }),
|
|
6273
|
-
/* @__PURE__ */
|
|
6274
|
-
/* @__PURE__ */
|
|
6275
|
-
/* @__PURE__ */
|
|
6276
|
-
/* @__PURE__ */
|
|
6429
|
+
/* @__PURE__ */ jsxs22("div", { className: "space-y-2", children: [
|
|
6430
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex justify-between items-center", children: [
|
|
6431
|
+
/* @__PURE__ */ jsx26("span", { className: "text-sm font-medium", children: "API Keys" }),
|
|
6432
|
+
/* @__PURE__ */ jsxs22(
|
|
6277
6433
|
Button,
|
|
6278
6434
|
{
|
|
6279
6435
|
size: "sm",
|
|
6280
6436
|
variant: "ghost",
|
|
6281
6437
|
onClick: () => setShowAddKeyForm(showAddKeyForm === sp.id ? null : sp.id),
|
|
6282
6438
|
children: [
|
|
6283
|
-
/* @__PURE__ */
|
|
6439
|
+
/* @__PURE__ */ jsx26(Plus, { className: "h-3 w-3 mr-1" }),
|
|
6284
6440
|
"Add Key"
|
|
6285
6441
|
]
|
|
6286
6442
|
}
|
|
6287
6443
|
)
|
|
6288
6444
|
] }),
|
|
6289
|
-
sp.apiKeys.length === 0 && !showAddKeyForm && /* @__PURE__ */
|
|
6290
|
-
sp.apiKeys.map((key) => /* @__PURE__ */
|
|
6445
|
+
sp.apiKeys.length === 0 && !showAddKeyForm && /* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground", children: "No keys configured" }),
|
|
6446
|
+
sp.apiKeys.map((key) => /* @__PURE__ */ jsxs22(
|
|
6291
6447
|
"div",
|
|
6292
6448
|
{
|
|
6293
6449
|
className: "flex items-center justify-between p-2 bg-muted/50 rounded",
|
|
6294
6450
|
children: [
|
|
6295
|
-
/* @__PURE__ */
|
|
6296
|
-
/* @__PURE__ */
|
|
6297
|
-
key.isActive && /* @__PURE__ */
|
|
6298
|
-
/* @__PURE__ */
|
|
6451
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
6452
|
+
/* @__PURE__ */ jsx26("span", { className: "text-sm font-medium", children: key.label }),
|
|
6453
|
+
key.isActive && /* @__PURE__ */ jsx26("span", { className: "ml-2 text-xs bg-green-500/10 text-green-600 px-1.5 py-0.5 rounded", children: "Active" }),
|
|
6454
|
+
/* @__PURE__ */ jsx26("div", { className: "text-xs text-muted-foreground font-mono", children: key.maskedKey })
|
|
6299
6455
|
] }),
|
|
6300
|
-
/* @__PURE__ */
|
|
6301
|
-
!key.isActive && /* @__PURE__ */
|
|
6456
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex gap-1", children: [
|
|
6457
|
+
!key.isActive && /* @__PURE__ */ jsx26(
|
|
6302
6458
|
Button,
|
|
6303
6459
|
{
|
|
6304
6460
|
size: "sm",
|
|
@@ -6307,13 +6463,13 @@ function SettingsPanel() {
|
|
|
6307
6463
|
children: "Set Active"
|
|
6308
6464
|
}
|
|
6309
6465
|
),
|
|
6310
|
-
/* @__PURE__ */
|
|
6466
|
+
/* @__PURE__ */ jsx26(
|
|
6311
6467
|
Button,
|
|
6312
6468
|
{
|
|
6313
6469
|
size: "icon",
|
|
6314
6470
|
variant: "ghost",
|
|
6315
6471
|
onClick: () => handleDeleteKey(sp.id, key.label),
|
|
6316
|
-
children: /* @__PURE__ */
|
|
6472
|
+
children: /* @__PURE__ */ jsx26(Trash22, { className: "h-3 w-3 text-destructive" })
|
|
6317
6473
|
}
|
|
6318
6474
|
)
|
|
6319
6475
|
] })
|
|
@@ -6321,8 +6477,8 @@ function SettingsPanel() {
|
|
|
6321
6477
|
},
|
|
6322
6478
|
key.label
|
|
6323
6479
|
)),
|
|
6324
|
-
showAddKeyForm === sp.id && /* @__PURE__ */
|
|
6325
|
-
/* @__PURE__ */
|
|
6480
|
+
showAddKeyForm === sp.id && /* @__PURE__ */ jsxs22("div", { className: "p-3 border rounded space-y-2 bg-background", children: [
|
|
6481
|
+
/* @__PURE__ */ jsx26(
|
|
6326
6482
|
Input,
|
|
6327
6483
|
{
|
|
6328
6484
|
placeholder: "Key label (e.g. default, production)",
|
|
@@ -6330,8 +6486,8 @@ function SettingsPanel() {
|
|
|
6330
6486
|
onChange: (e) => setNewKeyLabel(e.target.value)
|
|
6331
6487
|
}
|
|
6332
6488
|
),
|
|
6333
|
-
/* @__PURE__ */
|
|
6334
|
-
/* @__PURE__ */
|
|
6489
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex gap-2", children: [
|
|
6490
|
+
/* @__PURE__ */ jsx26(
|
|
6335
6491
|
Input,
|
|
6336
6492
|
{
|
|
6337
6493
|
type: showNewKeyValue ? "text" : "password",
|
|
@@ -6340,18 +6496,18 @@ function SettingsPanel() {
|
|
|
6340
6496
|
onChange: (e) => setNewKeyValue(e.target.value)
|
|
6341
6497
|
}
|
|
6342
6498
|
),
|
|
6343
|
-
/* @__PURE__ */
|
|
6499
|
+
/* @__PURE__ */ jsx26(
|
|
6344
6500
|
Button,
|
|
6345
6501
|
{
|
|
6346
6502
|
size: "icon",
|
|
6347
6503
|
variant: "ghost",
|
|
6348
6504
|
onClick: () => setShowNewKeyValue(!showNewKeyValue),
|
|
6349
|
-
children: showNewKeyValue ? /* @__PURE__ */
|
|
6505
|
+
children: showNewKeyValue ? /* @__PURE__ */ jsx26(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx26(Eye, { className: "h-4 w-4" })
|
|
6350
6506
|
}
|
|
6351
6507
|
)
|
|
6352
6508
|
] }),
|
|
6353
|
-
/* @__PURE__ */
|
|
6354
|
-
/* @__PURE__ */
|
|
6509
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex gap-2", children: [
|
|
6510
|
+
/* @__PURE__ */ jsx26(
|
|
6355
6511
|
Button,
|
|
6356
6512
|
{
|
|
6357
6513
|
size: "sm",
|
|
@@ -6360,7 +6516,7 @@ function SettingsPanel() {
|
|
|
6360
6516
|
children: "Save Key"
|
|
6361
6517
|
}
|
|
6362
6518
|
),
|
|
6363
|
-
/* @__PURE__ */
|
|
6519
|
+
/* @__PURE__ */ jsx26(
|
|
6364
6520
|
Button,
|
|
6365
6521
|
{
|
|
6366
6522
|
size: "sm",
|
|
@@ -6379,13 +6535,13 @@ function SettingsPanel() {
|
|
|
6379
6535
|
] }, sp.id))
|
|
6380
6536
|
] })
|
|
6381
6537
|
] }),
|
|
6382
|
-
/* @__PURE__ */
|
|
6383
|
-
/* @__PURE__ */
|
|
6384
|
-
/* @__PURE__ */
|
|
6385
|
-
/* @__PURE__ */
|
|
6386
|
-
/* @__PURE__ */
|
|
6538
|
+
/* @__PURE__ */ jsx26(TabsContent, { value: "model", className: "space-y-4", children: provider ? /* @__PURE__ */ jsxs22(Fragment7, { children: [
|
|
6539
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between", children: [
|
|
6540
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
6541
|
+
/* @__PURE__ */ jsx26("p", { className: "text-sm font-medium", children: currentCatalogProvider?.name || provider }),
|
|
6542
|
+
/* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground", children: provider })
|
|
6387
6543
|
] }),
|
|
6388
|
-
/* @__PURE__ */
|
|
6544
|
+
/* @__PURE__ */ jsx26(
|
|
6389
6545
|
Button,
|
|
6390
6546
|
{
|
|
6391
6547
|
variant: "ghost",
|
|
@@ -6394,15 +6550,15 @@ function SettingsPanel() {
|
|
|
6394
6550
|
setIsLoadingModels(true);
|
|
6395
6551
|
ws.listProviderModels?.(provider);
|
|
6396
6552
|
},
|
|
6397
|
-
children: /* @__PURE__ */
|
|
6553
|
+
children: /* @__PURE__ */ jsx26(RefreshCw2, { className: cn("h-4 w-4", isLoadingModels && "animate-spin") })
|
|
6398
6554
|
}
|
|
6399
6555
|
)
|
|
6400
6556
|
] }),
|
|
6401
|
-
isLoadingModels && !catalogModels[provider] ? /* @__PURE__ */
|
|
6402
|
-
/* @__PURE__ */
|
|
6403
|
-
/* @__PURE__ */
|
|
6404
|
-
] }) : /* @__PURE__ */
|
|
6405
|
-
(catalogModels[provider] || []).map((m) => /* @__PURE__ */
|
|
6557
|
+
isLoadingModels && !catalogModels[provider] ? /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-center py-8", children: [
|
|
6558
|
+
/* @__PURE__ */ jsx26(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }),
|
|
6559
|
+
/* @__PURE__ */ jsx26("span", { className: "ml-2 text-muted-foreground", children: "Loading models..." })
|
|
6560
|
+
] }) : /* @__PURE__ */ jsxs22("div", { className: "space-y-1", children: [
|
|
6561
|
+
(catalogModels[provider] || []).map((m) => /* @__PURE__ */ jsxs22(
|
|
6406
6562
|
"button",
|
|
6407
6563
|
{
|
|
6408
6564
|
type: "button",
|
|
@@ -6412,47 +6568,47 @@ function SettingsPanel() {
|
|
|
6412
6568
|
model === m.id ? "border-primary bg-primary/5 ring-2 ring-primary/20" : "border-border hover:bg-muted"
|
|
6413
6569
|
),
|
|
6414
6570
|
children: [
|
|
6415
|
-
/* @__PURE__ */
|
|
6416
|
-
/* @__PURE__ */
|
|
6417
|
-
/* @__PURE__ */
|
|
6571
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
6572
|
+
/* @__PURE__ */ jsx26("span", { className: "font-medium", children: m.name || m.id }),
|
|
6573
|
+
/* @__PURE__ */ jsx26("div", { className: "flex gap-2 mt-1", children: m.capabilities.map((cap) => /* @__PURE__ */ jsx26("span", { className: "text-xs bg-muted px-1.5 py-0.5 rounded", children: cap }, cap)) })
|
|
6418
6574
|
] }),
|
|
6419
|
-
/* @__PURE__ */
|
|
6420
|
-
m.contextWindow && /* @__PURE__ */
|
|
6575
|
+
/* @__PURE__ */ jsxs22("div", { className: "text-right text-xs text-muted-foreground", children: [
|
|
6576
|
+
m.contextWindow && /* @__PURE__ */ jsxs22("div", { children: [
|
|
6421
6577
|
m.contextWindow / 1e3,
|
|
6422
6578
|
"k context"
|
|
6423
6579
|
] }),
|
|
6424
|
-
m.inputCost && m.outputCost && /* @__PURE__ */
|
|
6580
|
+
m.inputCost && m.outputCost && /* @__PURE__ */ jsxs22("div", { children: [
|
|
6425
6581
|
"$",
|
|
6426
6582
|
m.inputCost,
|
|
6427
6583
|
"/$",
|
|
6428
6584
|
m.outputCost
|
|
6429
6585
|
] }),
|
|
6430
|
-
model === m.id && /* @__PURE__ */
|
|
6586
|
+
model === m.id && /* @__PURE__ */ jsx26(CheckCircle24, { className: "h-4 w-4 text-primary mt-1" })
|
|
6431
6587
|
] })
|
|
6432
6588
|
]
|
|
6433
6589
|
},
|
|
6434
6590
|
m.id
|
|
6435
6591
|
)),
|
|
6436
|
-
catalogModels[provider]?.length === 0 && /* @__PURE__ */
|
|
6592
|
+
catalogModels[provider]?.length === 0 && /* @__PURE__ */ jsx26("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." })
|
|
6437
6593
|
] })
|
|
6438
|
-
] }) : /* @__PURE__ */
|
|
6439
|
-
/* @__PURE__ */
|
|
6440
|
-
/* @__PURE__ */
|
|
6594
|
+
] }) : /* @__PURE__ */ jsxs22("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
6595
|
+
/* @__PURE__ */ jsx26(Cpu4, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
|
|
6596
|
+
/* @__PURE__ */ jsx26("p", { children: "Select a provider first" })
|
|
6441
6597
|
] }) }),
|
|
6442
|
-
/* @__PURE__ */
|
|
6443
|
-
/* @__PURE__ */
|
|
6444
|
-
/* @__PURE__ */
|
|
6598
|
+
/* @__PURE__ */ jsxs22(TabsContent, { value: "connection", className: "space-y-4", children: [
|
|
6599
|
+
/* @__PURE__ */ jsxs22("div", { className: "space-y-3", children: [
|
|
6600
|
+
/* @__PURE__ */ jsxs22(
|
|
6445
6601
|
"label",
|
|
6446
6602
|
{
|
|
6447
6603
|
htmlFor: "websocket-url",
|
|
6448
6604
|
className: "text-sm font-medium flex items-center gap-2",
|
|
6449
6605
|
children: [
|
|
6450
|
-
/* @__PURE__ */
|
|
6606
|
+
/* @__PURE__ */ jsx26(Globe2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
6451
6607
|
"WebSocket Server URL"
|
|
6452
6608
|
]
|
|
6453
6609
|
}
|
|
6454
6610
|
),
|
|
6455
|
-
/* @__PURE__ */
|
|
6611
|
+
/* @__PURE__ */ jsx26(
|
|
6456
6612
|
Input,
|
|
6457
6613
|
{
|
|
6458
6614
|
id: "websocket-url",
|
|
@@ -6462,70 +6618,70 @@ function SettingsPanel() {
|
|
|
6462
6618
|
className: "font-mono text-sm"
|
|
6463
6619
|
}
|
|
6464
6620
|
),
|
|
6465
|
-
/* @__PURE__ */
|
|
6621
|
+
/* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground", children: "URL of the WrongStack WebSocket server. The server runs alongside the CLI." })
|
|
6466
6622
|
] }),
|
|
6467
|
-
/* @__PURE__ */
|
|
6468
|
-
/* @__PURE__ */
|
|
6469
|
-
/* @__PURE__ */
|
|
6623
|
+
/* @__PURE__ */ jsxs22("div", { className: "p-4 rounded-lg border bg-muted/50", children: [
|
|
6624
|
+
/* @__PURE__ */ jsx26("h4", { className: "text-sm font-medium mb-2", children: "Starting the WebSocket Server" }),
|
|
6625
|
+
/* @__PURE__ */ jsxs22("p", { className: "text-xs text-muted-foreground mb-3", children: [
|
|
6470
6626
|
"Standalone: run ",
|
|
6471
|
-
/* @__PURE__ */
|
|
6627
|
+
/* @__PURE__ */ jsx26("code", { className: "bg-muted px-1 py-0.5 rounded", children: "./dev.ps1" }),
|
|
6472
6628
|
" ",
|
|
6473
6629
|
"from the repo root, or set WS_HOST/WS_PORT before launching",
|
|
6474
6630
|
" ",
|
|
6475
|
-
/* @__PURE__ */
|
|
6631
|
+
/* @__PURE__ */ jsx26("code", { className: "bg-muted px-1 py-0.5 rounded", children: "node packages/webui/dist/server/entry.js" }),
|
|
6476
6632
|
". Or alongside the CLI:",
|
|
6477
6633
|
" ",
|
|
6478
|
-
/* @__PURE__ */
|
|
6634
|
+
/* @__PURE__ */ jsx26("code", { className: "bg-muted px-1 py-0.5 rounded", children: "wstack --webui" }),
|
|
6479
6635
|
"."
|
|
6480
6636
|
] })
|
|
6481
6637
|
] })
|
|
6482
6638
|
] }),
|
|
6483
|
-
/* @__PURE__ */
|
|
6484
|
-
/* @__PURE__ */
|
|
6485
|
-
/* @__PURE__ */
|
|
6486
|
-
/* @__PURE__ */
|
|
6487
|
-
/* @__PURE__ */
|
|
6639
|
+
/* @__PURE__ */ jsxs22(TabsContent, { value: "appearance", className: "space-y-4", children: [
|
|
6640
|
+
/* @__PURE__ */ jsxs22("div", { children: [
|
|
6641
|
+
/* @__PURE__ */ jsx26("h3", { className: "text-sm font-semibold mb-3", children: "Theme" }),
|
|
6642
|
+
/* @__PURE__ */ jsxs22("div", { className: "grid grid-cols-3 gap-2 max-w-md", children: [
|
|
6643
|
+
/* @__PURE__ */ jsxs22(
|
|
6488
6644
|
Button,
|
|
6489
6645
|
{
|
|
6490
6646
|
variant: theme === "light" ? "default" : "outline",
|
|
6491
6647
|
size: "sm",
|
|
6492
6648
|
onClick: () => setTheme("light"),
|
|
6493
6649
|
children: [
|
|
6494
|
-
/* @__PURE__ */
|
|
6650
|
+
/* @__PURE__ */ jsx26(Sun3, { className: "h-4 w-4 mr-1" }),
|
|
6495
6651
|
"Light"
|
|
6496
6652
|
]
|
|
6497
6653
|
}
|
|
6498
6654
|
),
|
|
6499
|
-
/* @__PURE__ */
|
|
6655
|
+
/* @__PURE__ */ jsxs22(
|
|
6500
6656
|
Button,
|
|
6501
6657
|
{
|
|
6502
6658
|
variant: theme === "dark" ? "default" : "outline",
|
|
6503
6659
|
size: "sm",
|
|
6504
6660
|
onClick: () => setTheme("dark"),
|
|
6505
6661
|
children: [
|
|
6506
|
-
/* @__PURE__ */
|
|
6662
|
+
/* @__PURE__ */ jsx26(Moon3, { className: "h-4 w-4 mr-1" }),
|
|
6507
6663
|
"Dark"
|
|
6508
6664
|
]
|
|
6509
6665
|
}
|
|
6510
6666
|
),
|
|
6511
|
-
/* @__PURE__ */
|
|
6667
|
+
/* @__PURE__ */ jsxs22(
|
|
6512
6668
|
Button,
|
|
6513
6669
|
{
|
|
6514
6670
|
variant: theme === "system" ? "default" : "outline",
|
|
6515
6671
|
size: "sm",
|
|
6516
6672
|
onClick: () => setTheme("system"),
|
|
6517
6673
|
children: [
|
|
6518
|
-
/* @__PURE__ */
|
|
6674
|
+
/* @__PURE__ */ jsx26(Monitor3, { className: "h-4 w-4 mr-1" }),
|
|
6519
6675
|
"System"
|
|
6520
6676
|
]
|
|
6521
6677
|
}
|
|
6522
6678
|
)
|
|
6523
6679
|
] }),
|
|
6524
|
-
/* @__PURE__ */
|
|
6680
|
+
/* @__PURE__ */ jsx26("p", { className: "text-xs text-muted-foreground mt-2", children: "System follows your OS-level light/dark preference." })
|
|
6525
6681
|
] }),
|
|
6526
|
-
/* @__PURE__ */
|
|
6527
|
-
/* @__PURE__ */
|
|
6528
|
-
/* @__PURE__ */
|
|
6682
|
+
/* @__PURE__ */ jsxs22("div", { className: "pt-2 border-t", children: [
|
|
6683
|
+
/* @__PURE__ */ jsx26("h3", { className: "text-sm font-semibold mb-3 mt-3", children: "Preferences" }),
|
|
6684
|
+
/* @__PURE__ */ jsx26(
|
|
6529
6685
|
PreferenceToggle,
|
|
6530
6686
|
{
|
|
6531
6687
|
label: "Compact density",
|
|
@@ -6534,7 +6690,7 @@ function SettingsPanel() {
|
|
|
6534
6690
|
onChange: () => useUIStore.getState().toggleCompactMode()
|
|
6535
6691
|
}
|
|
6536
6692
|
),
|
|
6537
|
-
/* @__PURE__ */
|
|
6693
|
+
/* @__PURE__ */ jsx26(
|
|
6538
6694
|
PreferenceToggle,
|
|
6539
6695
|
{
|
|
6540
6696
|
label: "Sound on completion",
|
|
@@ -6564,17 +6720,16 @@ function PreferenceToggle({
|
|
|
6564
6720
|
const next = !useConfigStore.getState().soundOnComplete;
|
|
6565
6721
|
useConfigStore.getState().setSoundOnComplete(next);
|
|
6566
6722
|
if (next) {
|
|
6567
|
-
|
|
6568
|
-
});
|
|
6723
|
+
playCompletionChime();
|
|
6569
6724
|
}
|
|
6570
6725
|
}
|
|
6571
6726
|
};
|
|
6572
|
-
return /* @__PURE__ */
|
|
6573
|
-
/* @__PURE__ */
|
|
6574
|
-
/* @__PURE__ */
|
|
6575
|
-
hint && /* @__PURE__ */
|
|
6727
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex items-start justify-between gap-3 py-2", children: [
|
|
6728
|
+
/* @__PURE__ */ jsxs22("div", { className: "min-w-0 flex-1", children: [
|
|
6729
|
+
/* @__PURE__ */ jsx26("div", { className: "text-sm font-medium", children: label }),
|
|
6730
|
+
hint && /* @__PURE__ */ jsx26("div", { className: "text-xs text-muted-foreground mt-0.5", children: hint })
|
|
6576
6731
|
] }),
|
|
6577
|
-
/* @__PURE__ */
|
|
6732
|
+
/* @__PURE__ */ jsx26(
|
|
6578
6733
|
"button",
|
|
6579
6734
|
{
|
|
6580
6735
|
type: "button",
|
|
@@ -6585,7 +6740,7 @@ function PreferenceToggle({
|
|
|
6585
6740
|
"shrink-0 relative inline-flex h-5 w-9 rounded-full border transition-colors",
|
|
6586
6741
|
on ? "bg-primary border-primary" : "bg-muted border-input hover:bg-muted/80"
|
|
6587
6742
|
),
|
|
6588
|
-
children: /* @__PURE__ */
|
|
6743
|
+
children: /* @__PURE__ */ jsx26(
|
|
6589
6744
|
"span",
|
|
6590
6745
|
{
|
|
6591
6746
|
className: cn(
|
|
@@ -6601,8 +6756,8 @@ function PreferenceToggle({
|
|
|
6601
6756
|
|
|
6602
6757
|
// src/components/ShortcutsOverlay.tsx
|
|
6603
6758
|
import { Keyboard as Keyboard2, X as X6 } from "lucide-react";
|
|
6604
|
-
import { useEffect as
|
|
6605
|
-
import { jsx as
|
|
6759
|
+
import { useEffect as useEffect18 } from "react";
|
|
6760
|
+
import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
6606
6761
|
var SHORTCUTS = [
|
|
6607
6762
|
{
|
|
6608
6763
|
section: "Global",
|
|
@@ -6652,7 +6807,7 @@ var SHORTCUTS = [
|
|
|
6652
6807
|
function ShortcutsOverlay() {
|
|
6653
6808
|
const open = useUIStore((s) => s.shortcutsOpen);
|
|
6654
6809
|
const setOpen = useUIStore((s) => s.setShortcutsOpen);
|
|
6655
|
-
|
|
6810
|
+
useEffect18(() => {
|
|
6656
6811
|
const onKey = (e) => {
|
|
6657
6812
|
const target = e.target;
|
|
6658
6813
|
const tag = target?.tagName?.toLowerCase();
|
|
@@ -6671,7 +6826,7 @@ function ShortcutsOverlay() {
|
|
|
6671
6826
|
return () => window.removeEventListener("keydown", onKey);
|
|
6672
6827
|
}, [setOpen]);
|
|
6673
6828
|
if (!open) return null;
|
|
6674
|
-
return /* @__PURE__ */
|
|
6829
|
+
return /* @__PURE__ */ jsx27(
|
|
6675
6830
|
"div",
|
|
6676
6831
|
{
|
|
6677
6832
|
className: "fixed inset-0 z-50 bg-background/60 backdrop-blur-sm flex items-center justify-center px-4",
|
|
@@ -6679,49 +6834,49 @@ function ShortcutsOverlay() {
|
|
|
6679
6834
|
onKeyDown: (e) => {
|
|
6680
6835
|
if (e.key === "Escape") setOpen(false);
|
|
6681
6836
|
},
|
|
6682
|
-
children: /* @__PURE__ */
|
|
6837
|
+
children: /* @__PURE__ */ jsxs23(
|
|
6683
6838
|
"div",
|
|
6684
6839
|
{
|
|
6685
6840
|
onClick: (e) => e.stopPropagation(),
|
|
6686
6841
|
onKeyDown: (e) => e.stopPropagation(),
|
|
6687
6842
|
className: "w-full max-w-2xl rounded-xl border bg-popover shadow-2xl overflow-hidden flex flex-col max-h-[80vh]",
|
|
6688
6843
|
children: [
|
|
6689
|
-
/* @__PURE__ */
|
|
6690
|
-
/* @__PURE__ */
|
|
6691
|
-
/* @__PURE__ */
|
|
6692
|
-
/* @__PURE__ */
|
|
6844
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between px-5 py-4 border-b", children: [
|
|
6845
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2", children: [
|
|
6846
|
+
/* @__PURE__ */ jsx27(Keyboard2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
6847
|
+
/* @__PURE__ */ jsx27("h2", { className: "text-sm font-semibold", children: "Keyboard shortcuts" })
|
|
6693
6848
|
] }),
|
|
6694
|
-
/* @__PURE__ */
|
|
6849
|
+
/* @__PURE__ */ jsx27(
|
|
6695
6850
|
"button",
|
|
6696
6851
|
{
|
|
6697
6852
|
type: "button",
|
|
6698
6853
|
onClick: () => setOpen(false),
|
|
6699
6854
|
className: "text-muted-foreground hover:text-foreground p-1 rounded hover:bg-muted",
|
|
6700
|
-
children: /* @__PURE__ */
|
|
6855
|
+
children: /* @__PURE__ */ jsx27(X6, { className: "h-4 w-4" })
|
|
6701
6856
|
}
|
|
6702
6857
|
)
|
|
6703
6858
|
] }),
|
|
6704
|
-
/* @__PURE__ */
|
|
6705
|
-
/* @__PURE__ */
|
|
6706
|
-
/* @__PURE__ */
|
|
6859
|
+
/* @__PURE__ */ jsx27("div", { className: "overflow-y-auto px-5 py-4 space-y-6", children: SHORTCUTS.map((group) => /* @__PURE__ */ jsxs23("div", { children: [
|
|
6860
|
+
/* @__PURE__ */ jsx27("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground mb-2", children: group.section }),
|
|
6861
|
+
/* @__PURE__ */ jsx27("div", { className: "grid grid-cols-1 gap-1.5", children: group.items.map((s) => /* @__PURE__ */ jsxs23(
|
|
6707
6862
|
"div",
|
|
6708
6863
|
{
|
|
6709
6864
|
className: "flex items-center justify-between gap-3 text-sm px-2 py-1.5 rounded hover:bg-muted/40",
|
|
6710
6865
|
children: [
|
|
6711
|
-
/* @__PURE__ */
|
|
6712
|
-
/* @__PURE__ */
|
|
6713
|
-
ki > 0 && /* @__PURE__ */
|
|
6714
|
-
/* @__PURE__ */
|
|
6866
|
+
/* @__PURE__ */ jsx27("span", { className: "text-foreground/80", children: s.description }),
|
|
6867
|
+
/* @__PURE__ */ jsx27("span", { className: "flex items-center gap-1 shrink-0", children: s.keys.map((k, ki) => /* @__PURE__ */ jsxs23("span", { className: "flex items-center gap-1", children: [
|
|
6868
|
+
ki > 0 && /* @__PURE__ */ jsx27("span", { className: "text-muted-foreground/40 text-xs", children: "+" }),
|
|
6869
|
+
/* @__PURE__ */ jsx27("kbd", { className: "font-mono text-[10px] border rounded px-1.5 py-0.5 bg-background", children: k })
|
|
6715
6870
|
] }, k)) })
|
|
6716
6871
|
]
|
|
6717
6872
|
},
|
|
6718
6873
|
s.description
|
|
6719
6874
|
)) })
|
|
6720
6875
|
] }, group.section)) }),
|
|
6721
|
-
/* @__PURE__ */
|
|
6876
|
+
/* @__PURE__ */ jsxs23("div", { className: "border-t px-5 py-3 text-xs text-muted-foreground", children: [
|
|
6722
6877
|
"Press",
|
|
6723
6878
|
" ",
|
|
6724
|
-
/* @__PURE__ */
|
|
6879
|
+
/* @__PURE__ */ jsx27("kbd", { className: "font-mono text-[10px] border rounded px-1 py-0.5 bg-background", children: "?" }),
|
|
6725
6880
|
" ",
|
|
6726
6881
|
"any time to reopen this list."
|
|
6727
6882
|
] })
|
|
@@ -6755,8 +6910,8 @@ import {
|
|
|
6755
6910
|
X as X7,
|
|
6756
6911
|
Zap as Zap3
|
|
6757
6912
|
} from "lucide-react";
|
|
6758
|
-
import { useEffect as
|
|
6759
|
-
import { Fragment as Fragment8, jsx as
|
|
6913
|
+
import { useEffect as useEffect19, useState as useState18 } from "react";
|
|
6914
|
+
import { Fragment as Fragment8, jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
6760
6915
|
function Sidebar() {
|
|
6761
6916
|
const { toggleSidebar, currentView, setCurrentView } = useUIStore();
|
|
6762
6917
|
const sidebarWidth = useUIStore((s) => s.sidebarWidth);
|
|
@@ -6765,13 +6920,13 @@ function Sidebar() {
|
|
|
6765
6920
|
const { messages, clearMessages } = useChatStore();
|
|
6766
6921
|
const pinnedIds = useUIStore((s) => s.pinnedIds);
|
|
6767
6922
|
const unpinAll = useUIStore((s) => s.unpinAll);
|
|
6768
|
-
const [historyQuery, setHistoryQuery] =
|
|
6923
|
+
const [historyQuery, setHistoryQuery] = useState18("");
|
|
6769
6924
|
const favoriteSessionIds = useUIStore((s) => s.favoriteSessionIds);
|
|
6770
6925
|
const toggleFavoriteSession = useUIStore((s) => s.toggleFavoriteSession);
|
|
6771
6926
|
const sessionNicknames = useUIStore((s) => s.sessionNicknames);
|
|
6772
6927
|
const setSessionNickname = useUIStore((s) => s.setSessionNickname);
|
|
6773
|
-
const [renamingId, setRenamingId] =
|
|
6774
|
-
const [renameDraft, setRenameDraft] =
|
|
6928
|
+
const [renamingId, setRenamingId] = useState18(null);
|
|
6929
|
+
const [renameDraft, setRenameDraft] = useState18("");
|
|
6775
6930
|
const pinnedRows = pinnedIds.map((id) => messages.find((m) => m.id === id)).filter((m) => !!m && m.content.length > 0);
|
|
6776
6931
|
const { wsConnected, wsUrl, provider, model } = useConfigStore();
|
|
6777
6932
|
const {
|
|
@@ -6780,11 +6935,11 @@ function Sidebar() {
|
|
|
6780
6935
|
error: historyError
|
|
6781
6936
|
} = useHistoryStore();
|
|
6782
6937
|
const { listSessions, deleteSession, resumeSession, client: client2 } = useWebSocket();
|
|
6783
|
-
|
|
6938
|
+
useEffect19(() => {
|
|
6784
6939
|
if (wsConnected) client2?.getTodos?.();
|
|
6785
6940
|
}, [wsConnected, client2]);
|
|
6786
6941
|
const activeSessionId = session?.id;
|
|
6787
|
-
|
|
6942
|
+
useEffect19(() => {
|
|
6788
6943
|
void activeSessionId;
|
|
6789
6944
|
if (currentView === "history" && wsConnected) {
|
|
6790
6945
|
listSessions(50);
|
|
@@ -6868,13 +7023,13 @@ function Sidebar() {
|
|
|
6868
7023
|
document.body.style.cursor = "col-resize";
|
|
6869
7024
|
document.body.style.userSelect = "none";
|
|
6870
7025
|
};
|
|
6871
|
-
return /* @__PURE__ */
|
|
7026
|
+
return /* @__PURE__ */ jsxs24(
|
|
6872
7027
|
"aside",
|
|
6873
7028
|
{
|
|
6874
7029
|
style: { width: `${sidebarWidth}px` },
|
|
6875
7030
|
className: "relative border-r bg-card flex flex-col shrink-0",
|
|
6876
7031
|
children: [
|
|
6877
|
-
/* @__PURE__ */
|
|
7032
|
+
/* @__PURE__ */ jsxs24(
|
|
6878
7033
|
"div",
|
|
6879
7034
|
{
|
|
6880
7035
|
onMouseDown: startDrag,
|
|
@@ -6882,56 +7037,56 @@ function Sidebar() {
|
|
|
6882
7037
|
className: "group/handle absolute top-0 right-0 h-full w-2 cursor-col-resize z-10 flex items-center justify-end",
|
|
6883
7038
|
title: "Drag to resize \xB7 double-click to reset",
|
|
6884
7039
|
children: [
|
|
6885
|
-
/* @__PURE__ */
|
|
6886
|
-
/* @__PURE__ */
|
|
6887
|
-
/* @__PURE__ */
|
|
6888
|
-
/* @__PURE__ */
|
|
6889
|
-
/* @__PURE__ */
|
|
7040
|
+
/* @__PURE__ */ jsx28("div", { className: "h-full w-px bg-border group-hover/handle:bg-primary/60 group-hover/handle:w-0.5 transition-all" }),
|
|
7041
|
+
/* @__PURE__ */ jsxs24("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: [
|
|
7042
|
+
/* @__PURE__ */ jsx28("span", { className: "h-1 w-1 rounded-full bg-primary/70" }),
|
|
7043
|
+
/* @__PURE__ */ jsx28("span", { className: "h-1 w-1 rounded-full bg-primary/70" }),
|
|
7044
|
+
/* @__PURE__ */ jsx28("span", { className: "h-1 w-1 rounded-full bg-primary/70" })
|
|
6890
7045
|
] })
|
|
6891
7046
|
]
|
|
6892
7047
|
}
|
|
6893
7048
|
),
|
|
6894
|
-
/* @__PURE__ */
|
|
6895
|
-
/* @__PURE__ */
|
|
6896
|
-
/* @__PURE__ */
|
|
6897
|
-
/* @__PURE__ */
|
|
7049
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-between px-4 py-3 border-b", children: [
|
|
7050
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2", children: [
|
|
7051
|
+
/* @__PURE__ */ jsx28("div", { className: "w-6 h-6 rounded bg-primary flex items-center justify-center", children: /* @__PURE__ */ jsx28(Zap3, { className: "h-4 w-4 text-primary-foreground" }) }),
|
|
7052
|
+
/* @__PURE__ */ jsx28("span", { className: "text-sm font-semibold tracking-tight", children: "WrongStack" })
|
|
6898
7053
|
] }),
|
|
6899
|
-
/* @__PURE__ */
|
|
7054
|
+
/* @__PURE__ */ jsx28(Button, { variant: "ghost", size: "icon", onClick: toggleSidebar, children: /* @__PURE__ */ jsx28(PanelLeftClose, { className: "h-4 w-4" }) })
|
|
6900
7055
|
] }),
|
|
6901
|
-
/* @__PURE__ */
|
|
7056
|
+
/* @__PURE__ */ jsxs24(
|
|
6902
7057
|
Tabs,
|
|
6903
7058
|
{
|
|
6904
7059
|
value: currentView === "settings" ? "chat" : currentView,
|
|
6905
7060
|
onValueChange: (v) => setCurrentView(v),
|
|
6906
7061
|
className: "flex-1 flex flex-col",
|
|
6907
7062
|
children: [
|
|
6908
|
-
/* @__PURE__ */
|
|
6909
|
-
/* @__PURE__ */
|
|
7063
|
+
/* @__PURE__ */ jsxs24(TabsList, { className: "w-full rounded-none bg-transparent p-2 h-auto grid grid-cols-2", children: [
|
|
7064
|
+
/* @__PURE__ */ jsxs24(
|
|
6910
7065
|
TabsTrigger,
|
|
6911
7066
|
{
|
|
6912
7067
|
value: "chat",
|
|
6913
7068
|
className: "flex-col gap-1.5 py-2 data-[state=active]:bg-primary/10",
|
|
6914
7069
|
children: [
|
|
6915
|
-
/* @__PURE__ */
|
|
6916
|
-
/* @__PURE__ */
|
|
7070
|
+
/* @__PURE__ */ jsx28(MessageSquare, { className: "h-4 w-4" }),
|
|
7071
|
+
/* @__PURE__ */ jsx28("span", { className: "text-xs", children: "Chat" })
|
|
6917
7072
|
]
|
|
6918
7073
|
}
|
|
6919
7074
|
),
|
|
6920
|
-
/* @__PURE__ */
|
|
7075
|
+
/* @__PURE__ */ jsxs24(
|
|
6921
7076
|
TabsTrigger,
|
|
6922
7077
|
{
|
|
6923
7078
|
value: "history",
|
|
6924
7079
|
className: "flex-col gap-1.5 py-2 data-[state=active]:bg-primary/10",
|
|
6925
7080
|
children: [
|
|
6926
|
-
/* @__PURE__ */
|
|
6927
|
-
/* @__PURE__ */
|
|
7081
|
+
/* @__PURE__ */ jsx28(History, { className: "h-4 w-4" }),
|
|
7082
|
+
/* @__PURE__ */ jsx28("span", { className: "text-xs", children: "History" })
|
|
6928
7083
|
]
|
|
6929
7084
|
}
|
|
6930
7085
|
)
|
|
6931
7086
|
] }),
|
|
6932
|
-
/* @__PURE__ */
|
|
6933
|
-
/* @__PURE__ */
|
|
6934
|
-
/* @__PURE__ */
|
|
7087
|
+
/* @__PURE__ */ jsxs24(TabsContent, { value: "chat", className: "flex-1 flex flex-col m-0 overflow-hidden", children: [
|
|
7088
|
+
/* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b", children: [
|
|
7089
|
+
/* @__PURE__ */ jsxs24(
|
|
6935
7090
|
"div",
|
|
6936
7091
|
{
|
|
6937
7092
|
className: cn(
|
|
@@ -6939,95 +7094,95 @@ function Sidebar() {
|
|
|
6939
7094
|
wsConnected ? "bg-green-500/10 text-green-600 dark:text-green-400" : "bg-yellow-500/10 text-yellow-600 dark:text-yellow-400"
|
|
6940
7095
|
),
|
|
6941
7096
|
children: [
|
|
6942
|
-
wsConnected ? /* @__PURE__ */
|
|
6943
|
-
/* @__PURE__ */
|
|
7097
|
+
wsConnected ? /* @__PURE__ */ jsx28(Wifi3, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx28(WifiOff4, { className: "h-4 w-4" }),
|
|
7098
|
+
/* @__PURE__ */ jsx28("span", { className: "font-medium", children: wsConnected ? "Connected" : "Disconnected" })
|
|
6944
7099
|
]
|
|
6945
7100
|
}
|
|
6946
7101
|
),
|
|
6947
|
-
/* @__PURE__ */
|
|
7102
|
+
/* @__PURE__ */ jsx28("div", { className: "text-xs text-muted-foreground mt-2 px-1 font-mono", children: wsUrl })
|
|
6948
7103
|
] }),
|
|
6949
|
-
/* @__PURE__ */
|
|
7104
|
+
/* @__PURE__ */ jsxs24(
|
|
6950
7105
|
"button",
|
|
6951
7106
|
{
|
|
6952
7107
|
type: "button",
|
|
6953
7108
|
onClick: () => setCurrentView("settings"),
|
|
6954
7109
|
className: "px-4 py-3 border-b text-left hover:bg-muted/40 transition-colors",
|
|
6955
7110
|
children: [
|
|
6956
|
-
/* @__PURE__ */
|
|
6957
|
-
/* @__PURE__ */
|
|
6958
|
-
/* @__PURE__ */
|
|
6959
|
-
/* @__PURE__ */
|
|
6960
|
-
/* @__PURE__ */
|
|
7111
|
+
/* @__PURE__ */ jsx28("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground mb-1", children: "Active model" }),
|
|
7112
|
+
/* @__PURE__ */ jsxs24("div", { className: "font-mono text-xs truncate", children: [
|
|
7113
|
+
/* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: provider || "\u2014" }),
|
|
7114
|
+
/* @__PURE__ */ jsx28("span", { className: "text-muted-foreground/40 mx-1", children: "/" }),
|
|
7115
|
+
/* @__PURE__ */ jsx28("span", { className: "font-medium", children: model || "\u2014" })
|
|
6961
7116
|
] })
|
|
6962
7117
|
]
|
|
6963
7118
|
}
|
|
6964
7119
|
),
|
|
6965
|
-
/* @__PURE__ */
|
|
6966
|
-
/* @__PURE__ */
|
|
6967
|
-
/* @__PURE__ */
|
|
7120
|
+
/* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b space-y-3", children: [
|
|
7121
|
+
/* @__PURE__ */ jsxs24("h3", { className: "text-sm font-medium flex items-center gap-2", children: [
|
|
7122
|
+
/* @__PURE__ */ jsx28(Database2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
6968
7123
|
"Session"
|
|
6969
7124
|
] }),
|
|
6970
|
-
/* @__PURE__ */
|
|
6971
|
-
/* @__PURE__ */
|
|
6972
|
-
/* @__PURE__ */
|
|
6973
|
-
/* @__PURE__ */
|
|
7125
|
+
/* @__PURE__ */ jsxs24("div", { className: "grid grid-cols-2 gap-2 text-xs", children: [
|
|
7126
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7127
|
+
/* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Messages" }),
|
|
7128
|
+
/* @__PURE__ */ jsx28("span", { className: "text-lg font-semibold", children: messages.length })
|
|
6974
7129
|
] }),
|
|
6975
|
-
/* @__PURE__ */
|
|
6976
|
-
/* @__PURE__ */
|
|
6977
|
-
/* @__PURE__ */
|
|
7130
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7131
|
+
/* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Duration" }),
|
|
7132
|
+
/* @__PURE__ */ jsx28("span", { className: "text-lg font-semibold", children: formatDuration2(session?.startedAt ?? null) })
|
|
6978
7133
|
] }),
|
|
6979
|
-
/* @__PURE__ */
|
|
6980
|
-
/* @__PURE__ */
|
|
6981
|
-
/* @__PURE__ */
|
|
7134
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7135
|
+
/* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Input" }),
|
|
7136
|
+
/* @__PURE__ */ jsx28("span", { className: "text-lg font-semibold", children: totalTokens.input.toLocaleString() })
|
|
6982
7137
|
] }),
|
|
6983
|
-
/* @__PURE__ */
|
|
6984
|
-
/* @__PURE__ */
|
|
6985
|
-
/* @__PURE__ */
|
|
7138
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7139
|
+
/* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Output" }),
|
|
7140
|
+
/* @__PURE__ */ jsx28("span", { className: "text-lg font-semibold", children: totalTokens.output.toLocaleString() })
|
|
6986
7141
|
] })
|
|
6987
7142
|
] }),
|
|
6988
|
-
cost > 0 && /* @__PURE__ */
|
|
6989
|
-
/* @__PURE__ */
|
|
6990
|
-
/* @__PURE__ */
|
|
7143
|
+
cost > 0 && /* @__PURE__ */ jsxs24("div", { className: "flex justify-between items-center p-2 rounded-lg bg-green-500/10", children: [
|
|
7144
|
+
/* @__PURE__ */ jsx28("span", { className: "text-sm text-muted-foreground", children: "Cost" }),
|
|
7145
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-lg font-semibold text-green-600 dark:text-green-400", children: [
|
|
6991
7146
|
"$",
|
|
6992
7147
|
cost.toFixed(4)
|
|
6993
7148
|
] })
|
|
6994
7149
|
] })
|
|
6995
7150
|
] }),
|
|
6996
|
-
todos.length > 0 && /* @__PURE__ */
|
|
6997
|
-
/* @__PURE__ */
|
|
6998
|
-
/* @__PURE__ */
|
|
6999
|
-
/* @__PURE__ */
|
|
7151
|
+
todos.length > 0 && /* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b space-y-2", children: [
|
|
7152
|
+
/* @__PURE__ */ jsxs24("h3", { className: "text-sm font-medium flex items-center justify-between", children: [
|
|
7153
|
+
/* @__PURE__ */ jsxs24("span", { className: "flex items-center gap-2", children: [
|
|
7154
|
+
/* @__PURE__ */ jsx28(ListTodo, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7000
7155
|
"Todos"
|
|
7001
7156
|
] }),
|
|
7002
|
-
/* @__PURE__ */
|
|
7157
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
|
|
7003
7158
|
todos.filter((t) => t.status === "completed").length,
|
|
7004
7159
|
"/",
|
|
7005
7160
|
todos.length
|
|
7006
7161
|
] })
|
|
7007
7162
|
] }),
|
|
7008
|
-
/* @__PURE__ */
|
|
7163
|
+
/* @__PURE__ */ jsx28("ul", { className: "space-y-1 max-h-48 overflow-y-auto pr-1", children: todos.map((t) => {
|
|
7009
7164
|
const Icon2 = t.status === "completed" ? CheckCircle25 : t.status === "in_progress" ? CircleDot : Circle;
|
|
7010
7165
|
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";
|
|
7011
|
-
return /* @__PURE__ */
|
|
7166
|
+
return /* @__PURE__ */ jsxs24(
|
|
7012
7167
|
"li",
|
|
7013
7168
|
{
|
|
7014
7169
|
className: cn("flex items-start gap-2 text-xs leading-snug", tone2),
|
|
7015
7170
|
children: [
|
|
7016
|
-
/* @__PURE__ */
|
|
7017
|
-
/* @__PURE__ */
|
|
7171
|
+
/* @__PURE__ */ jsx28(Icon2, { className: "h-3.5 w-3.5 mt-0.5 shrink-0" }),
|
|
7172
|
+
/* @__PURE__ */ jsx28("span", { className: "break-words", children: t.status === "in_progress" && t.activeForm ? t.activeForm : t.content })
|
|
7018
7173
|
]
|
|
7019
7174
|
},
|
|
7020
7175
|
t.id
|
|
7021
7176
|
);
|
|
7022
7177
|
}) })
|
|
7023
7178
|
] }),
|
|
7024
|
-
pinnedRows.length > 0 && /* @__PURE__ */
|
|
7025
|
-
/* @__PURE__ */
|
|
7026
|
-
/* @__PURE__ */
|
|
7027
|
-
/* @__PURE__ */
|
|
7179
|
+
pinnedRows.length > 0 && /* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b space-y-2", children: [
|
|
7180
|
+
/* @__PURE__ */ jsxs24("h3", { className: "text-sm font-medium flex items-center justify-between", children: [
|
|
7181
|
+
/* @__PURE__ */ jsxs24("span", { className: "flex items-center gap-2", children: [
|
|
7182
|
+
/* @__PURE__ */ jsx28(Pin2, { className: "h-4 w-4 text-amber-500" }),
|
|
7028
7183
|
"Pinned"
|
|
7029
7184
|
] }),
|
|
7030
|
-
/* @__PURE__ */
|
|
7185
|
+
/* @__PURE__ */ jsx28(
|
|
7031
7186
|
"button",
|
|
7032
7187
|
{
|
|
7033
7188
|
type: "button",
|
|
@@ -7037,9 +7192,9 @@ function Sidebar() {
|
|
|
7037
7192
|
}
|
|
7038
7193
|
)
|
|
7039
7194
|
] }),
|
|
7040
|
-
/* @__PURE__ */
|
|
7195
|
+
/* @__PURE__ */ jsx28("ul", { className: "space-y-1 max-h-48 overflow-y-auto pr-1", children: pinnedRows.map((m) => {
|
|
7041
7196
|
const preview = m.content.replace(/\s+/g, " ").slice(0, 80);
|
|
7042
|
-
return /* @__PURE__ */
|
|
7197
|
+
return /* @__PURE__ */ jsx28("li", { children: /* @__PURE__ */ jsxs24(
|
|
7043
7198
|
"button",
|
|
7044
7199
|
{
|
|
7045
7200
|
type: "button",
|
|
@@ -7062,8 +7217,8 @@ function Sidebar() {
|
|
|
7062
7217
|
) }, m.id);
|
|
7063
7218
|
}) })
|
|
7064
7219
|
] }),
|
|
7065
|
-
/* @__PURE__ */
|
|
7066
|
-
/* @__PURE__ */
|
|
7220
|
+
/* @__PURE__ */ jsxs24("div", { className: "px-4 py-3 border-b space-y-2", children: [
|
|
7221
|
+
/* @__PURE__ */ jsxs24(
|
|
7067
7222
|
Button,
|
|
7068
7223
|
{
|
|
7069
7224
|
variant: "outline",
|
|
@@ -7074,12 +7229,12 @@ function Sidebar() {
|
|
|
7074
7229
|
client2?.clearContext?.();
|
|
7075
7230
|
},
|
|
7076
7231
|
children: [
|
|
7077
|
-
/* @__PURE__ */
|
|
7232
|
+
/* @__PURE__ */ jsx28(Trash23, { className: "h-4 w-4 mr-2" }),
|
|
7078
7233
|
"Clear context"
|
|
7079
7234
|
]
|
|
7080
7235
|
}
|
|
7081
7236
|
),
|
|
7082
|
-
/* @__PURE__ */
|
|
7237
|
+
/* @__PURE__ */ jsxs24(
|
|
7083
7238
|
Button,
|
|
7084
7239
|
{
|
|
7085
7240
|
variant: "outline",
|
|
@@ -7088,12 +7243,12 @@ function Sidebar() {
|
|
|
7088
7243
|
onClick: () => client2?.newSession?.(),
|
|
7089
7244
|
disabled: !wsConnected,
|
|
7090
7245
|
children: [
|
|
7091
|
-
/* @__PURE__ */
|
|
7246
|
+
/* @__PURE__ */ jsx28(RotateCcw5, { className: "h-4 w-4 mr-2" }),
|
|
7092
7247
|
"New session"
|
|
7093
7248
|
]
|
|
7094
7249
|
}
|
|
7095
7250
|
),
|
|
7096
|
-
/* @__PURE__ */
|
|
7251
|
+
/* @__PURE__ */ jsxs24(
|
|
7097
7252
|
Button,
|
|
7098
7253
|
{
|
|
7099
7254
|
variant: "outline",
|
|
@@ -7102,14 +7257,14 @@ function Sidebar() {
|
|
|
7102
7257
|
onClick: () => client2?.compactContext?.(),
|
|
7103
7258
|
disabled: !wsConnected,
|
|
7104
7259
|
children: [
|
|
7105
|
-
/* @__PURE__ */
|
|
7260
|
+
/* @__PURE__ */ jsx28(Database2, { className: "h-4 w-4 mr-2" }),
|
|
7106
7261
|
"Compact context"
|
|
7107
7262
|
]
|
|
7108
7263
|
}
|
|
7109
7264
|
)
|
|
7110
7265
|
] }),
|
|
7111
|
-
/* @__PURE__ */
|
|
7112
|
-
/* @__PURE__ */
|
|
7266
|
+
/* @__PURE__ */ jsx28("div", { className: "flex-1" }),
|
|
7267
|
+
/* @__PURE__ */ jsx28("div", { className: "px-3 py-3 border-t", children: /* @__PURE__ */ jsxs24(
|
|
7113
7268
|
Button,
|
|
7114
7269
|
{
|
|
7115
7270
|
variant: "ghost",
|
|
@@ -7117,16 +7272,16 @@ function Sidebar() {
|
|
|
7117
7272
|
className: "w-full justify-start",
|
|
7118
7273
|
onClick: () => setCurrentView("settings"),
|
|
7119
7274
|
children: [
|
|
7120
|
-
/* @__PURE__ */
|
|
7275
|
+
/* @__PURE__ */ jsx28(SettingsIcon2, { className: "h-4 w-4 mr-2" }),
|
|
7121
7276
|
"Settings"
|
|
7122
7277
|
]
|
|
7123
7278
|
}
|
|
7124
7279
|
) })
|
|
7125
7280
|
] }),
|
|
7126
|
-
/* @__PURE__ */
|
|
7127
|
-
/* @__PURE__ */
|
|
7128
|
-
/* @__PURE__ */
|
|
7129
|
-
/* @__PURE__ */
|
|
7281
|
+
/* @__PURE__ */ jsxs24(TabsContent, { value: "history", className: "flex-1 m-0 flex flex-col overflow-hidden", children: [
|
|
7282
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-between px-4 py-2 border-b", children: [
|
|
7283
|
+
/* @__PURE__ */ jsx28("span", { className: "text-xs uppercase tracking-wider text-muted-foreground", children: "Recent sessions" }),
|
|
7284
|
+
/* @__PURE__ */ jsx28(
|
|
7130
7285
|
Button,
|
|
7131
7286
|
{
|
|
7132
7287
|
variant: "ghost",
|
|
@@ -7135,13 +7290,13 @@ function Sidebar() {
|
|
|
7135
7290
|
onClick: () => listSessions(50),
|
|
7136
7291
|
disabled: !wsConnected,
|
|
7137
7292
|
title: "Refresh",
|
|
7138
|
-
children: historyLoading ? /* @__PURE__ */
|
|
7293
|
+
children: historyLoading ? /* @__PURE__ */ jsx28(Loader25, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx28(RefreshCw3, { className: "h-3.5 w-3.5" })
|
|
7139
7294
|
}
|
|
7140
7295
|
)
|
|
7141
7296
|
] }),
|
|
7142
|
-
historyEntries.length > 3 && /* @__PURE__ */
|
|
7143
|
-
/* @__PURE__ */
|
|
7144
|
-
/* @__PURE__ */
|
|
7297
|
+
historyEntries.length > 3 && /* @__PURE__ */ jsx28("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ jsxs24("div", { className: "relative", children: [
|
|
7298
|
+
/* @__PURE__ */ jsx28(Search5, { className: "absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/60" }),
|
|
7299
|
+
/* @__PURE__ */ jsx28(
|
|
7145
7300
|
"input",
|
|
7146
7301
|
{
|
|
7147
7302
|
type: "text",
|
|
@@ -7151,28 +7306,28 @@ function Sidebar() {
|
|
|
7151
7306
|
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"
|
|
7152
7307
|
}
|
|
7153
7308
|
),
|
|
7154
|
-
historyQuery && /* @__PURE__ */
|
|
7309
|
+
historyQuery && /* @__PURE__ */ jsx28(
|
|
7155
7310
|
"button",
|
|
7156
7311
|
{
|
|
7157
7312
|
type: "button",
|
|
7158
7313
|
onClick: () => setHistoryQuery(""),
|
|
7159
7314
|
className: "absolute right-1 top-1/2 -translate-y-1/2 text-muted-foreground/60 hover:text-foreground p-0.5",
|
|
7160
7315
|
title: "Clear filter",
|
|
7161
|
-
children: /* @__PURE__ */
|
|
7316
|
+
children: /* @__PURE__ */ jsx28(X7, { className: "h-3 w-3" })
|
|
7162
7317
|
}
|
|
7163
7318
|
)
|
|
7164
7319
|
] }) }),
|
|
7165
|
-
historyError && /* @__PURE__ */
|
|
7166
|
-
/* @__PURE__ */
|
|
7167
|
-
/* @__PURE__ */
|
|
7168
|
-
/* @__PURE__ */
|
|
7169
|
-
/* @__PURE__ */
|
|
7170
|
-
] }) : groupedHistory.length === 0 ? /* @__PURE__ */
|
|
7171
|
-
/* @__PURE__ */
|
|
7172
|
-
/* @__PURE__ */
|
|
7173
|
-
/* @__PURE__ */
|
|
7174
|
-
] }) : /* @__PURE__ */
|
|
7175
|
-
/* @__PURE__ */
|
|
7320
|
+
historyError && /* @__PURE__ */ jsx28("div", { className: "px-4 py-2 text-xs text-destructive bg-destructive/5 border-b", children: historyError }),
|
|
7321
|
+
/* @__PURE__ */ jsx28(ScrollArea, { className: "flex-1", children: historyEntries.length === 0 && !historyLoading ? /* @__PURE__ */ jsxs24("div", { className: "text-center text-muted-foreground py-8 px-4", children: [
|
|
7322
|
+
/* @__PURE__ */ jsx28(History, { className: "h-8 w-8 mx-auto mb-3 opacity-20" }),
|
|
7323
|
+
/* @__PURE__ */ jsx28("p", { className: "text-sm font-medium", children: "No history yet" }),
|
|
7324
|
+
/* @__PURE__ */ jsx28("p", { className: "text-xs mt-1", children: "Your conversations will appear here" })
|
|
7325
|
+
] }) : groupedHistory.length === 0 ? /* @__PURE__ */ jsxs24("div", { className: "text-center text-muted-foreground py-8 px-4", children: [
|
|
7326
|
+
/* @__PURE__ */ jsx28(Search5, { className: "h-8 w-8 mx-auto mb-3 opacity-20" }),
|
|
7327
|
+
/* @__PURE__ */ jsx28("p", { className: "text-sm font-medium", children: "No matches" }),
|
|
7328
|
+
/* @__PURE__ */ jsx28("p", { className: "text-xs mt-1", children: "Try a different filter" })
|
|
7329
|
+
] }) : /* @__PURE__ */ jsx28("div", { className: "p-2 space-y-3", children: groupedHistory.map((group) => /* @__PURE__ */ jsxs24("div", { className: "space-y-1", children: [
|
|
7330
|
+
/* @__PURE__ */ jsxs24(
|
|
7176
7331
|
"div",
|
|
7177
7332
|
{
|
|
7178
7333
|
className: cn(
|
|
@@ -7180,10 +7335,10 @@ function Sidebar() {
|
|
|
7180
7335
|
group.star ? "text-amber-500" : "text-muted-foreground/80"
|
|
7181
7336
|
),
|
|
7182
7337
|
children: [
|
|
7183
|
-
group.star && /* @__PURE__ */
|
|
7338
|
+
group.star && /* @__PURE__ */ jsx28(Star, { className: "h-3 w-3 fill-current" }),
|
|
7184
7339
|
group.label,
|
|
7185
7340
|
" ",
|
|
7186
|
-
/* @__PURE__ */
|
|
7341
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-muted-foreground/50 font-normal normal-case ml-1", children: [
|
|
7187
7342
|
"(",
|
|
7188
7343
|
group.rows.length,
|
|
7189
7344
|
")"
|
|
@@ -7191,7 +7346,7 @@ function Sidebar() {
|
|
|
7191
7346
|
]
|
|
7192
7347
|
}
|
|
7193
7348
|
),
|
|
7194
|
-
group.rows.map((entry) => /* @__PURE__ */
|
|
7349
|
+
group.rows.map((entry) => /* @__PURE__ */ jsxs24(
|
|
7195
7350
|
"div",
|
|
7196
7351
|
{
|
|
7197
7352
|
className: cn(
|
|
@@ -7199,7 +7354,7 @@ function Sidebar() {
|
|
|
7199
7354
|
entry.isCurrent ? "bg-primary/5 border-primary/40" : "bg-card border-border/60 hover:bg-muted/40 hover:border-primary/40"
|
|
7200
7355
|
),
|
|
7201
7356
|
children: [
|
|
7202
|
-
/* @__PURE__ */
|
|
7357
|
+
/* @__PURE__ */ jsx28(
|
|
7203
7358
|
"button",
|
|
7204
7359
|
{
|
|
7205
7360
|
type: "button",
|
|
@@ -7211,8 +7366,8 @@ function Sidebar() {
|
|
|
7211
7366
|
setRenameDraft(sessionNicknames[entry.id] ?? entry.title ?? "");
|
|
7212
7367
|
},
|
|
7213
7368
|
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",
|
|
7214
|
-
children: /* @__PURE__ */
|
|
7215
|
-
renamingId === entry.id ? /* @__PURE__ */
|
|
7369
|
+
children: /* @__PURE__ */ jsxs24("div", { className: "min-w-0 flex-1", children: [
|
|
7370
|
+
renamingId === entry.id ? /* @__PURE__ */ jsx28(
|
|
7216
7371
|
"input",
|
|
7217
7372
|
{
|
|
7218
7373
|
value: renameDraft,
|
|
@@ -7235,7 +7390,7 @@ function Sidebar() {
|
|
|
7235
7390
|
placeholder: entry.title || "Nickname",
|
|
7236
7391
|
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"
|
|
7237
7392
|
}
|
|
7238
|
-
) : /* @__PURE__ */
|
|
7393
|
+
) : /* @__PURE__ */ jsx28(
|
|
7239
7394
|
"div",
|
|
7240
7395
|
{
|
|
7241
7396
|
className: "font-medium truncate text-foreground",
|
|
@@ -7245,30 +7400,30 @@ Double-click to rename`,
|
|
|
7245
7400
|
children: sessionNicknames[entry.id] || entry.title || "(empty)"
|
|
7246
7401
|
}
|
|
7247
7402
|
),
|
|
7248
|
-
/* @__PURE__ */
|
|
7403
|
+
/* @__PURE__ */ jsxs24("div", { className: "text-[10px] text-muted-foreground font-mono truncate mt-0.5", children: [
|
|
7249
7404
|
entry.provider,
|
|
7250
7405
|
"/",
|
|
7251
7406
|
entry.model
|
|
7252
7407
|
] }),
|
|
7253
|
-
/* @__PURE__ */
|
|
7254
|
-
/* @__PURE__ */
|
|
7255
|
-
entry.tokenTotal > 0 && /* @__PURE__ */
|
|
7256
|
-
/* @__PURE__ */
|
|
7257
|
-
/* @__PURE__ */
|
|
7408
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2 text-[10px] text-muted-foreground/80 mt-0.5", children: [
|
|
7409
|
+
/* @__PURE__ */ jsx28("span", { children: formatRelative(entry.startedAt) }),
|
|
7410
|
+
entry.tokenTotal > 0 && /* @__PURE__ */ jsxs24(Fragment8, { children: [
|
|
7411
|
+
/* @__PURE__ */ jsx28("span", { children: "\xB7" }),
|
|
7412
|
+
/* @__PURE__ */ jsxs24("span", { className: "tabular-nums", children: [
|
|
7258
7413
|
entry.tokenTotal.toLocaleString(),
|
|
7259
7414
|
" tok"
|
|
7260
7415
|
] })
|
|
7261
7416
|
] }),
|
|
7262
|
-
entry.isCurrent && /* @__PURE__ */
|
|
7263
|
-
/* @__PURE__ */
|
|
7264
|
-
/* @__PURE__ */
|
|
7417
|
+
entry.isCurrent && /* @__PURE__ */ jsxs24(Fragment8, { children: [
|
|
7418
|
+
/* @__PURE__ */ jsx28("span", { children: "\xB7" }),
|
|
7419
|
+
/* @__PURE__ */ jsx28("span", { className: "text-primary font-medium", children: "active" })
|
|
7265
7420
|
] })
|
|
7266
7421
|
] })
|
|
7267
7422
|
] })
|
|
7268
7423
|
}
|
|
7269
7424
|
),
|
|
7270
|
-
/* @__PURE__ */
|
|
7271
|
-
/* @__PURE__ */
|
|
7425
|
+
/* @__PURE__ */ jsxs24("div", { className: "absolute right-2 top-2 flex items-center gap-1", children: [
|
|
7426
|
+
/* @__PURE__ */ jsx28(
|
|
7272
7427
|
"button",
|
|
7273
7428
|
{
|
|
7274
7429
|
type: "button",
|
|
@@ -7278,7 +7433,7 @@ Double-click to rename`,
|
|
|
7278
7433
|
favoriteSessionIds.includes(entry.id) ? "opacity-100 text-amber-500" : "opacity-0 group-hover:opacity-100 text-muted-foreground"
|
|
7279
7434
|
),
|
|
7280
7435
|
title: favoriteSessionIds.includes(entry.id) ? "Unfavorite" : "Mark as favorite",
|
|
7281
|
-
children: /* @__PURE__ */
|
|
7436
|
+
children: /* @__PURE__ */ jsx28(
|
|
7282
7437
|
Star,
|
|
7283
7438
|
{
|
|
7284
7439
|
className: cn(
|
|
@@ -7289,7 +7444,7 @@ Double-click to rename`,
|
|
|
7289
7444
|
)
|
|
7290
7445
|
}
|
|
7291
7446
|
),
|
|
7292
|
-
!entry.isCurrent && /* @__PURE__ */
|
|
7447
|
+
!entry.isCurrent && /* @__PURE__ */ jsx28(
|
|
7293
7448
|
"button",
|
|
7294
7449
|
{
|
|
7295
7450
|
type: "button",
|
|
@@ -7300,7 +7455,7 @@ Double-click to rename`,
|
|
|
7300
7455
|
},
|
|
7301
7456
|
className: "opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-destructive",
|
|
7302
7457
|
title: "Delete session",
|
|
7303
|
-
children: /* @__PURE__ */
|
|
7458
|
+
children: /* @__PURE__ */ jsx28(Trash23, { className: "h-3.5 w-3.5" })
|
|
7304
7459
|
}
|
|
7305
7460
|
)
|
|
7306
7461
|
] })
|
|
@@ -7319,7 +7474,7 @@ Double-click to rename`,
|
|
|
7319
7474
|
}
|
|
7320
7475
|
|
|
7321
7476
|
// src/App.tsx
|
|
7322
|
-
import { jsx as
|
|
7477
|
+
import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
7323
7478
|
function AppInner() {
|
|
7324
7479
|
const { theme } = useTheme();
|
|
7325
7480
|
const { currentView, sidebarOpen, toggleSidebar, setSearchOpen, setSidebarOpen } = useUIStore();
|
|
@@ -7329,7 +7484,7 @@ function AppInner() {
|
|
|
7329
7484
|
const sessionTitle = useSessionStore((s) => s.session?.title);
|
|
7330
7485
|
const sessionId = useSessionStore((s) => s.session?.id);
|
|
7331
7486
|
const nickname = useUIStore((s) => sessionId ? s.sessionNicknames[sessionId] : void 0);
|
|
7332
|
-
|
|
7487
|
+
useEffect20(() => {
|
|
7333
7488
|
if (typeof window === "undefined") return;
|
|
7334
7489
|
const mq = window.matchMedia("(max-width: 768px)");
|
|
7335
7490
|
const apply = () => {
|
|
@@ -7342,7 +7497,7 @@ function AppInner() {
|
|
|
7342
7497
|
return () => mq.removeEventListener("change", apply);
|
|
7343
7498
|
}, [setSidebarOpen]);
|
|
7344
7499
|
useWebSocketBootstrap();
|
|
7345
|
-
|
|
7500
|
+
useEffect20(() => {
|
|
7346
7501
|
const parts = [];
|
|
7347
7502
|
if (isLoading) {
|
|
7348
7503
|
const it = iteration ? ` iter ${iteration.index}${iteration.max ? `/${iteration.max}` : ""}` : "";
|
|
@@ -7359,7 +7514,7 @@ function AppInner() {
|
|
|
7359
7514
|
document.title = "WrongStack";
|
|
7360
7515
|
};
|
|
7361
7516
|
}, [isLoading, iteration, projectName, sessionTitle, nickname]);
|
|
7362
|
-
|
|
7517
|
+
useEffect20(() => {
|
|
7363
7518
|
const onKey = (e) => {
|
|
7364
7519
|
const t = e.target;
|
|
7365
7520
|
const tag = t?.tagName?.toLowerCase();
|
|
@@ -7455,27 +7610,27 @@ function AppInner() {
|
|
|
7455
7610
|
window.addEventListener("keydown", onKey);
|
|
7456
7611
|
return () => window.removeEventListener("keydown", onKey);
|
|
7457
7612
|
}, [toggleSidebar, setSearchOpen]);
|
|
7458
|
-
return /* @__PURE__ */
|
|
7459
|
-
sidebarOpen && /* @__PURE__ */
|
|
7460
|
-
/* @__PURE__ */
|
|
7461
|
-
/* @__PURE__ */
|
|
7462
|
-
currentView === "chat" && /* @__PURE__ */
|
|
7463
|
-
currentView === "settings" && /* @__PURE__ */
|
|
7613
|
+
return /* @__PURE__ */ jsxs25("div", { className: cn("flex h-screen", theme), children: [
|
|
7614
|
+
sidebarOpen && /* @__PURE__ */ jsx29(Sidebar, {}),
|
|
7615
|
+
/* @__PURE__ */ jsxs25("main", { className: "flex-1 flex flex-col overflow-hidden", children: [
|
|
7616
|
+
/* @__PURE__ */ jsx29(ConnectionBanner, {}),
|
|
7617
|
+
currentView === "chat" && /* @__PURE__ */ jsx29(ChatView, {}),
|
|
7618
|
+
currentView === "settings" && /* @__PURE__ */ jsx29(SettingsPanel, {})
|
|
7464
7619
|
] }),
|
|
7465
|
-
/* @__PURE__ */
|
|
7466
|
-
/* @__PURE__ */
|
|
7467
|
-
/* @__PURE__ */
|
|
7468
|
-
/* @__PURE__ */
|
|
7469
|
-
/* @__PURE__ */
|
|
7620
|
+
/* @__PURE__ */ jsx29(ConfirmDialog, {}),
|
|
7621
|
+
/* @__PURE__ */ jsx29(CommandPalette, {}),
|
|
7622
|
+
/* @__PURE__ */ jsx29(ShortcutsOverlay, {}),
|
|
7623
|
+
/* @__PURE__ */ jsx29(QuickModelSwitcher, {}),
|
|
7624
|
+
/* @__PURE__ */ jsx29(Toaster, {})
|
|
7470
7625
|
] });
|
|
7471
7626
|
}
|
|
7472
7627
|
function App() {
|
|
7473
|
-
return /* @__PURE__ */
|
|
7628
|
+
return /* @__PURE__ */ jsx29(ErrorBoundary, { children: /* @__PURE__ */ jsx29(ThemeProvider, { defaultTheme: "system", children: /* @__PURE__ */ jsx29(AppInner, {}) }) });
|
|
7474
7629
|
}
|
|
7475
7630
|
|
|
7476
7631
|
// src/main.tsx
|
|
7477
|
-
import { jsx as
|
|
7632
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
7478
7633
|
ReactDOM.createRoot(document.getElementById("root")).render(
|
|
7479
|
-
/* @__PURE__ */
|
|
7634
|
+
/* @__PURE__ */ jsx30(React7.StrictMode, { children: /* @__PURE__ */ jsx30(App, {}) })
|
|
7480
7635
|
);
|
|
7481
7636
|
//# sourceMappingURL=index.js.map
|