@wrongstack/webui 0.9.19 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/index-CT8FjKJZ.css +1 -0
- package/dist/assets/index-Cv19VZgJ.js +94 -0
- package/dist/assets/{vendor-Dff2jyfM.js → vendor-oYD55Pw4.js} +126 -96
- package/dist/index.css +47 -0
- package/dist/index.css.map +1 -1
- package/dist/index.html +3 -3
- package/dist/index.js +752 -467
- package/dist/index.js.map +1 -1
- package/dist/server/entry.js +692 -2
- package/dist/server/entry.js.map +1 -1
- package/dist/server/index.js +692 -2
- package/dist/server/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/assets/index-B5qzSV8A.js +0 -94
- package/dist/assets/index-BTevO8Vz.css +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/main.tsx
|
|
2
|
-
import
|
|
2
|
+
import React6 from "react";
|
|
3
3
|
import ReactDOM from "react-dom/client";
|
|
4
4
|
|
|
5
5
|
// src/lib/utils.ts
|
|
@@ -1615,7 +1615,7 @@ function useWebSocket() {
|
|
|
1615
1615
|
}
|
|
1616
1616
|
|
|
1617
1617
|
// src/App.tsx
|
|
1618
|
-
import { useEffect as
|
|
1618
|
+
import { useEffect as useEffect21 } from "react";
|
|
1619
1619
|
|
|
1620
1620
|
// src/components/ChatView.tsx
|
|
1621
1621
|
import {
|
|
@@ -5012,7 +5012,7 @@ function ChatView() {
|
|
|
5012
5012
|
const compactMode = useUIStore((s) => s.compactMode);
|
|
5013
5013
|
const setTheme = useConfigStore((s) => s.setTheme);
|
|
5014
5014
|
const theme = useConfigStore((s) => s.theme);
|
|
5015
|
-
const { totalTokens,
|
|
5015
|
+
const { totalTokens, startTime, lastInputTokens, maxContext, projectName, iteration } = useSessionStore();
|
|
5016
5016
|
const { wsConnected, wsStatus, provider, model } = useConfigStore();
|
|
5017
5017
|
const { setCurrentView } = useUIStore();
|
|
5018
5018
|
const scrollRef = useRef9(null);
|
|
@@ -5507,18 +5507,302 @@ function ChatView() {
|
|
|
5507
5507
|
] });
|
|
5508
5508
|
}
|
|
5509
5509
|
|
|
5510
|
+
// src/components/CollabPanel.tsx
|
|
5511
|
+
import { Eye, LogIn, LogOut, MessageSquareWarning, Pause, Play, Users } from "lucide-react";
|
|
5512
|
+
import { useEffect as useEffect13, useState as useState14 } from "react";
|
|
5513
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5514
|
+
function CollabPanel({ sessionId, className }) {
|
|
5515
|
+
const [participants, setParticipants] = useState14([]);
|
|
5516
|
+
const [joined, setJoined] = useState14(false);
|
|
5517
|
+
const [joinedRole, setJoinedRole] = useState14(null);
|
|
5518
|
+
const [error, setError] = useState14(null);
|
|
5519
|
+
const [openAnnotationCount, setOpenAnnotationCount] = useState14(0);
|
|
5520
|
+
const [paused, setPaused] = useState14(false);
|
|
5521
|
+
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
5522
|
+
const client2 = getWSClient(wsUrl);
|
|
5523
|
+
useEffect13(() => {
|
|
5524
|
+
const offs = [];
|
|
5525
|
+
offs.push(
|
|
5526
|
+
client2.on("collab.state", (msg) => {
|
|
5527
|
+
if (msg?.payload?.sessionId === sessionId) {
|
|
5528
|
+
setParticipants(msg.payload.participants ?? []);
|
|
5529
|
+
}
|
|
5530
|
+
})
|
|
5531
|
+
);
|
|
5532
|
+
offs.push(
|
|
5533
|
+
client2.on("collab.participant.joined", (msg) => {
|
|
5534
|
+
if (msg?.payload?.sessionId !== sessionId) return;
|
|
5535
|
+
const p = msg.payload;
|
|
5536
|
+
setParticipants((prev) => {
|
|
5537
|
+
if (prev.some((x) => x.participantId === p.participantId)) return prev;
|
|
5538
|
+
return [...prev, { participantId: p.participantId, role: p.role, joinedAt: p.joinedAt }];
|
|
5539
|
+
});
|
|
5540
|
+
})
|
|
5541
|
+
);
|
|
5542
|
+
offs.push(
|
|
5543
|
+
client2.on("collab.participant.left", (msg) => {
|
|
5544
|
+
if (msg?.payload?.sessionId !== sessionId) return;
|
|
5545
|
+
const id = msg.payload.participantId;
|
|
5546
|
+
setParticipants((prev) => prev.filter((p) => p.participantId !== id));
|
|
5547
|
+
})
|
|
5548
|
+
);
|
|
5549
|
+
offs.push(
|
|
5550
|
+
client2.on("error", (msg) => {
|
|
5551
|
+
if (msg?.payload?.phase === "collab") {
|
|
5552
|
+
setError(msg.payload.message);
|
|
5553
|
+
setJoined(false);
|
|
5554
|
+
}
|
|
5555
|
+
})
|
|
5556
|
+
);
|
|
5557
|
+
offs.push(client2.on("collab.event", () => {
|
|
5558
|
+
}));
|
|
5559
|
+
offs.push(
|
|
5560
|
+
client2.on("collab.annotation.added", (msg) => {
|
|
5561
|
+
if (msg?.payload?.sessionId !== sessionId) return;
|
|
5562
|
+
if (msg?.payload?.annotation?.resolved) return;
|
|
5563
|
+
setOpenAnnotationCount((c) => c + 1);
|
|
5564
|
+
})
|
|
5565
|
+
);
|
|
5566
|
+
offs.push(
|
|
5567
|
+
client2.on("collab.annotation.resolved", (msg) => {
|
|
5568
|
+
if (msg?.payload?.sessionId !== sessionId) return;
|
|
5569
|
+
setOpenAnnotationCount((c) => Math.max(0, c - 1));
|
|
5570
|
+
})
|
|
5571
|
+
);
|
|
5572
|
+
offs.push(
|
|
5573
|
+
client2.on("collab.pause.granted", (msg) => {
|
|
5574
|
+
if (msg?.payload?.sessionId !== sessionId) return;
|
|
5575
|
+
setPaused(true);
|
|
5576
|
+
})
|
|
5577
|
+
);
|
|
5578
|
+
offs.push(
|
|
5579
|
+
client2.on("collab.pause.released", (msg) => {
|
|
5580
|
+
if (msg?.payload?.sessionId !== sessionId) return;
|
|
5581
|
+
setPaused(false);
|
|
5582
|
+
})
|
|
5583
|
+
);
|
|
5584
|
+
return () => {
|
|
5585
|
+
for (const off of offs) off();
|
|
5586
|
+
};
|
|
5587
|
+
}, [client2, sessionId]);
|
|
5588
|
+
const handleJoin = (role = "observer") => {
|
|
5589
|
+
setError(null);
|
|
5590
|
+
client2.send({ type: "collab.join", payload: { sessionId, role } });
|
|
5591
|
+
setJoined(true);
|
|
5592
|
+
setJoinedRole(role);
|
|
5593
|
+
};
|
|
5594
|
+
const handleRequestPause = () => {
|
|
5595
|
+
client2.send({ type: "collab.request_pause", payload: { sessionId } });
|
|
5596
|
+
};
|
|
5597
|
+
const handleResume = () => {
|
|
5598
|
+
client2.send({ type: "collab.resume", payload: { sessionId } });
|
|
5599
|
+
};
|
|
5600
|
+
const handleLeave = () => {
|
|
5601
|
+
client2.send({ type: "collab.leave", payload: { sessionId } });
|
|
5602
|
+
setJoined(false);
|
|
5603
|
+
setParticipants([]);
|
|
5604
|
+
};
|
|
5605
|
+
if (participants.length === 0 && !error) {
|
|
5606
|
+
return /* @__PURE__ */ jsxs17(
|
|
5607
|
+
"div",
|
|
5608
|
+
{
|
|
5609
|
+
className: cn(
|
|
5610
|
+
"flex items-center gap-2 px-3 py-2 rounded-md border border-dashed border-border bg-card/40",
|
|
5611
|
+
className
|
|
5612
|
+
),
|
|
5613
|
+
children: [
|
|
5614
|
+
/* @__PURE__ */ jsx18(Users, { className: "w-4 h-4 text-muted-foreground" }),
|
|
5615
|
+
/* @__PURE__ */ jsx18("span", { className: "text-xs text-muted-foreground", children: "No live observers" }),
|
|
5616
|
+
/* @__PURE__ */ jsxs17("div", { className: "ml-auto flex items-center gap-1", children: [
|
|
5617
|
+
/* @__PURE__ */ jsxs17(
|
|
5618
|
+
"button",
|
|
5619
|
+
{
|
|
5620
|
+
type: "button",
|
|
5621
|
+
onClick: () => handleJoin("observer"),
|
|
5622
|
+
className: "inline-flex items-center gap-1 text-xs px-2 py-1 rounded bg-primary text-primary-foreground hover:bg-primary/90 transition-colors",
|
|
5623
|
+
title: "Join as a read-only observer (Phase 1)",
|
|
5624
|
+
children: [
|
|
5625
|
+
/* @__PURE__ */ jsx18(LogIn, { className: "w-3 h-3" }),
|
|
5626
|
+
"observer"
|
|
5627
|
+
]
|
|
5628
|
+
}
|
|
5629
|
+
),
|
|
5630
|
+
/* @__PURE__ */ jsxs17(
|
|
5631
|
+
"button",
|
|
5632
|
+
{
|
|
5633
|
+
type: "button",
|
|
5634
|
+
onClick: () => handleJoin("annotator"),
|
|
5635
|
+
className: "inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-300 hover:bg-amber-500/20 transition-colors",
|
|
5636
|
+
title: "Join as an annotator \u2014 leave inline notes on tool calls (Phase 2)",
|
|
5637
|
+
children: [
|
|
5638
|
+
/* @__PURE__ */ jsx18(MessageSquareWarning, { className: "w-3 h-3" }),
|
|
5639
|
+
"annotator"
|
|
5640
|
+
]
|
|
5641
|
+
}
|
|
5642
|
+
),
|
|
5643
|
+
/* @__PURE__ */ jsxs17(
|
|
5644
|
+
"button",
|
|
5645
|
+
{
|
|
5646
|
+
type: "button",
|
|
5647
|
+
onClick: () => handleJoin("controller"),
|
|
5648
|
+
className: "inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-rose-500/40 bg-rose-500/10 text-rose-700 dark:text-rose-300 hover:bg-rose-500/20 transition-colors",
|
|
5649
|
+
title: "Join as a controller \u2014 can pause the agent loop (Phase 3)",
|
|
5650
|
+
children: [
|
|
5651
|
+
/* @__PURE__ */ jsx18(Pause, { className: "w-3 h-3" }),
|
|
5652
|
+
"controller"
|
|
5653
|
+
]
|
|
5654
|
+
}
|
|
5655
|
+
)
|
|
5656
|
+
] })
|
|
5657
|
+
]
|
|
5658
|
+
}
|
|
5659
|
+
);
|
|
5660
|
+
}
|
|
5661
|
+
if (error) {
|
|
5662
|
+
return /* @__PURE__ */ jsxs17(
|
|
5663
|
+
"div",
|
|
5664
|
+
{
|
|
5665
|
+
className: cn(
|
|
5666
|
+
"flex items-center gap-2 px-3 py-2 rounded-md border border-destructive/50 bg-destructive/10",
|
|
5667
|
+
className
|
|
5668
|
+
),
|
|
5669
|
+
role: "alert",
|
|
5670
|
+
children: [
|
|
5671
|
+
/* @__PURE__ */ jsxs17("span", { className: "text-xs text-destructive", children: [
|
|
5672
|
+
"Collab: ",
|
|
5673
|
+
error
|
|
5674
|
+
] }),
|
|
5675
|
+
/* @__PURE__ */ jsx18(
|
|
5676
|
+
"button",
|
|
5677
|
+
{
|
|
5678
|
+
type: "button",
|
|
5679
|
+
onClick: () => {
|
|
5680
|
+
setError(null);
|
|
5681
|
+
setJoined(false);
|
|
5682
|
+
},
|
|
5683
|
+
className: "ml-auto text-xs underline text-destructive",
|
|
5684
|
+
children: "dismiss"
|
|
5685
|
+
}
|
|
5686
|
+
)
|
|
5687
|
+
]
|
|
5688
|
+
}
|
|
5689
|
+
);
|
|
5690
|
+
}
|
|
5691
|
+
return /* @__PURE__ */ jsxs17(
|
|
5692
|
+
"div",
|
|
5693
|
+
{
|
|
5694
|
+
className: cn(
|
|
5695
|
+
"flex items-center gap-2 px-3 py-2 rounded-md border border-emerald-500/40 bg-emerald-500/5",
|
|
5696
|
+
className
|
|
5697
|
+
),
|
|
5698
|
+
children: [
|
|
5699
|
+
/* @__PURE__ */ jsxs17("span", { className: "relative flex h-2 w-2", "aria-label": "Live", children: [
|
|
5700
|
+
/* @__PURE__ */ jsx18("span", { className: "absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75 animate-ping" }),
|
|
5701
|
+
/* @__PURE__ */ jsx18("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-emerald-500" })
|
|
5702
|
+
] }),
|
|
5703
|
+
/* @__PURE__ */ jsx18(Users, { className: "w-4 h-4 text-emerald-700 dark:text-emerald-400" }),
|
|
5704
|
+
/* @__PURE__ */ jsxs17("span", { className: "text-xs font-medium text-emerald-700 dark:text-emerald-300", children: [
|
|
5705
|
+
participants.length,
|
|
5706
|
+
" ",
|
|
5707
|
+
participants.length === 1 ? "observer" : "observers"
|
|
5708
|
+
] }),
|
|
5709
|
+
openAnnotationCount > 0 && /* @__PURE__ */ jsxs17(
|
|
5710
|
+
"span",
|
|
5711
|
+
{
|
|
5712
|
+
title: `${openAnnotationCount} open annotation(s) \u2014 annotators reviewing this session`,
|
|
5713
|
+
className: "ml-2 inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-amber-500/15 text-amber-700 dark:text-amber-300 border border-amber-500/30",
|
|
5714
|
+
children: [
|
|
5715
|
+
/* @__PURE__ */ jsx18(MessageSquareWarning, { className: "w-3 h-3" }),
|
|
5716
|
+
openAnnotationCount,
|
|
5717
|
+
" note",
|
|
5718
|
+
openAnnotationCount === 1 ? "" : "s"
|
|
5719
|
+
]
|
|
5720
|
+
}
|
|
5721
|
+
),
|
|
5722
|
+
paused && /* @__PURE__ */ jsxs17(
|
|
5723
|
+
"span",
|
|
5724
|
+
{
|
|
5725
|
+
title: "Agent loop is paused \u2014 a controller is reviewing",
|
|
5726
|
+
className: "ml-2 inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-rose-500/15 text-rose-700 dark:text-rose-300 border border-rose-500/40",
|
|
5727
|
+
children: [
|
|
5728
|
+
/* @__PURE__ */ jsx18(Pause, { className: "w-3 h-3" }),
|
|
5729
|
+
"paused"
|
|
5730
|
+
]
|
|
5731
|
+
}
|
|
5732
|
+
),
|
|
5733
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-1 ml-2", children: [
|
|
5734
|
+
participants.slice(0, 3).map((p) => /* @__PURE__ */ jsxs17(
|
|
5735
|
+
"span",
|
|
5736
|
+
{
|
|
5737
|
+
title: `Joined ${new Date(p.joinedAt).toLocaleTimeString()}`,
|
|
5738
|
+
className: "inline-flex items-center gap-1 text-[10px] px-1.5 py-0.5 rounded bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
|
|
5739
|
+
children: [
|
|
5740
|
+
/* @__PURE__ */ jsx18(Eye, { className: "w-3 h-3" }),
|
|
5741
|
+
p.role
|
|
5742
|
+
]
|
|
5743
|
+
},
|
|
5744
|
+
p.participantId
|
|
5745
|
+
)),
|
|
5746
|
+
participants.length > 3 && /* @__PURE__ */ jsxs17("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
5747
|
+
"+",
|
|
5748
|
+
participants.length - 3
|
|
5749
|
+
] })
|
|
5750
|
+
] }),
|
|
5751
|
+
joined && joinedRole === "controller" && (paused ? /* @__PURE__ */ jsxs17(
|
|
5752
|
+
"button",
|
|
5753
|
+
{
|
|
5754
|
+
type: "button",
|
|
5755
|
+
onClick: handleResume,
|
|
5756
|
+
className: "ml-auto inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-rose-500/40 bg-rose-500/10 text-rose-700 dark:text-rose-300 hover:bg-rose-500/20 transition-colors",
|
|
5757
|
+
title: "Resume the agent loop",
|
|
5758
|
+
children: [
|
|
5759
|
+
/* @__PURE__ */ jsx18(Play, { className: "w-3 h-3" }),
|
|
5760
|
+
"Resume"
|
|
5761
|
+
]
|
|
5762
|
+
}
|
|
5763
|
+
) : /* @__PURE__ */ jsxs17(
|
|
5764
|
+
"button",
|
|
5765
|
+
{
|
|
5766
|
+
type: "button",
|
|
5767
|
+
onClick: handleRequestPause,
|
|
5768
|
+
className: "ml-auto inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-300 hover:bg-amber-500/20 transition-colors",
|
|
5769
|
+
title: "Pause the agent before the next tool call",
|
|
5770
|
+
children: [
|
|
5771
|
+
/* @__PURE__ */ jsx18(Pause, { className: "w-3 h-3" }),
|
|
5772
|
+
"Pause agent"
|
|
5773
|
+
]
|
|
5774
|
+
}
|
|
5775
|
+
)),
|
|
5776
|
+
joined && joinedRole !== "controller" && /* @__PURE__ */ jsxs17(
|
|
5777
|
+
"button",
|
|
5778
|
+
{
|
|
5779
|
+
type: "button",
|
|
5780
|
+
onClick: handleLeave,
|
|
5781
|
+
className: "ml-auto inline-flex items-center gap-1 text-xs px-2 py-1 rounded border border-border hover:bg-muted transition-colors",
|
|
5782
|
+
title: "Leave the observer session",
|
|
5783
|
+
children: [
|
|
5784
|
+
/* @__PURE__ */ jsx18(LogOut, { className: "w-3 h-3" }),
|
|
5785
|
+
"Leave"
|
|
5786
|
+
]
|
|
5787
|
+
}
|
|
5788
|
+
)
|
|
5789
|
+
]
|
|
5790
|
+
}
|
|
5791
|
+
);
|
|
5792
|
+
}
|
|
5793
|
+
|
|
5510
5794
|
// src/components/ConfirmDialog.tsx
|
|
5511
5795
|
import { AlertTriangle as AlertTriangle2, FileEdit, Globe, ShieldAlert, Terminal as Terminal3, Wrench as Wrench3 } from "lucide-react";
|
|
5512
|
-
import { useEffect as
|
|
5796
|
+
import { useEffect as useEffect14, useRef as useRef10 } from "react";
|
|
5513
5797
|
|
|
5514
5798
|
// src/components/ui/dialog.tsx
|
|
5515
5799
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
5516
5800
|
import { X as X3 } from "lucide-react";
|
|
5517
5801
|
import * as React3 from "react";
|
|
5518
|
-
import { jsx as
|
|
5802
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5519
5803
|
var Dialog = DialogPrimitive.Root;
|
|
5520
5804
|
var DialogPortal = DialogPrimitive.Portal;
|
|
5521
|
-
var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5805
|
+
var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
|
|
5522
5806
|
DialogPrimitive.Overlay,
|
|
5523
5807
|
{
|
|
5524
5808
|
ref,
|
|
@@ -5530,9 +5814,9 @@ var DialogOverlay = React3.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
5530
5814
|
}
|
|
5531
5815
|
));
|
|
5532
5816
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
5533
|
-
var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */
|
|
5534
|
-
/* @__PURE__ */
|
|
5535
|
-
/* @__PURE__ */
|
|
5817
|
+
var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs18(DialogPortal, { children: [
|
|
5818
|
+
/* @__PURE__ */ jsx19(DialogOverlay, {}),
|
|
5819
|
+
/* @__PURE__ */ jsxs18(
|
|
5536
5820
|
DialogPrimitive.Content,
|
|
5537
5821
|
{
|
|
5538
5822
|
ref,
|
|
@@ -5543,18 +5827,18 @@ var DialogContent = React3.forwardRef(({ className, children, ...props }, ref) =
|
|
|
5543
5827
|
...props,
|
|
5544
5828
|
children: [
|
|
5545
5829
|
children,
|
|
5546
|
-
/* @__PURE__ */
|
|
5547
|
-
/* @__PURE__ */
|
|
5548
|
-
/* @__PURE__ */
|
|
5830
|
+
/* @__PURE__ */ jsxs18(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground", children: [
|
|
5831
|
+
/* @__PURE__ */ jsx19(X3, { className: "h-4 w-4" }),
|
|
5832
|
+
/* @__PURE__ */ jsx19("span", { className: "sr-only", children: "Close" })
|
|
5549
5833
|
] })
|
|
5550
5834
|
]
|
|
5551
5835
|
}
|
|
5552
5836
|
)
|
|
5553
5837
|
] }));
|
|
5554
5838
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
5555
|
-
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */
|
|
5839
|
+
var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx19("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
|
|
5556
5840
|
DialogHeader.displayName = "DialogHeader";
|
|
5557
|
-
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */
|
|
5841
|
+
var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx19(
|
|
5558
5842
|
"div",
|
|
5559
5843
|
{
|
|
5560
5844
|
className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
|
|
@@ -5562,7 +5846,7 @@ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx18(
|
|
|
5562
5846
|
}
|
|
5563
5847
|
);
|
|
5564
5848
|
DialogFooter.displayName = "DialogFooter";
|
|
5565
|
-
var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5849
|
+
var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
|
|
5566
5850
|
DialogPrimitive.Title,
|
|
5567
5851
|
{
|
|
5568
5852
|
ref,
|
|
@@ -5571,7 +5855,7 @@ var DialogTitle = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
5571
5855
|
}
|
|
5572
5856
|
));
|
|
5573
5857
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
5574
|
-
var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
5858
|
+
var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx19(
|
|
5575
5859
|
DialogPrimitive.Description,
|
|
5576
5860
|
{
|
|
5577
5861
|
ref,
|
|
@@ -5582,7 +5866,7 @@ var DialogDescription = React3.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
5582
5866
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
5583
5867
|
|
|
5584
5868
|
// src/components/ConfirmDialog.tsx
|
|
5585
|
-
import { jsx as
|
|
5869
|
+
import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
5586
5870
|
function pickToolIcon(toolName) {
|
|
5587
5871
|
if (/edit|write|create|patch/i.test(toolName)) return FileEdit;
|
|
5588
5872
|
if (/bash|shell|exec|run|command/i.test(toolName)) return Terminal3;
|
|
@@ -5595,7 +5879,7 @@ function SmartInputPreview({
|
|
|
5595
5879
|
}) {
|
|
5596
5880
|
const diffArgs = diffFromToolInput(toolName, input);
|
|
5597
5881
|
if (diffArgs) {
|
|
5598
|
-
return /* @__PURE__ */
|
|
5882
|
+
return /* @__PURE__ */ jsx20("div", { className: "rounded-lg overflow-hidden border", children: /* @__PURE__ */ jsx20(
|
|
5599
5883
|
DiffView,
|
|
5600
5884
|
{
|
|
5601
5885
|
oldText: diffArgs.oldText,
|
|
@@ -5608,12 +5892,12 @@ function SmartInputPreview({
|
|
|
5608
5892
|
const obj = input;
|
|
5609
5893
|
const cmd = obj.command ?? obj.cmd ?? obj.script;
|
|
5610
5894
|
if (typeof cmd === "string" && cmd.trim().length > 0) {
|
|
5611
|
-
return /* @__PURE__ */
|
|
5612
|
-
/* @__PURE__ */
|
|
5613
|
-
/* @__PURE__ */
|
|
5614
|
-
/* @__PURE__ */
|
|
5895
|
+
return /* @__PURE__ */ jsxs19("div", { className: "rounded-lg border bg-background/40 overflow-hidden", children: [
|
|
5896
|
+
/* @__PURE__ */ jsxs19("div", { className: "px-3 py-1.5 text-[10px] uppercase tracking-wider text-muted-foreground border-b bg-muted/40 flex items-center gap-1.5", children: [
|
|
5897
|
+
/* @__PURE__ */ jsx20(Terminal3, { className: "h-3 w-3" }),
|
|
5898
|
+
/* @__PURE__ */ jsx20("span", { children: "Command" })
|
|
5615
5899
|
] }),
|
|
5616
|
-
/* @__PURE__ */
|
|
5900
|
+
/* @__PURE__ */ jsxs19("pre", { className: "px-3 py-2 text-xs font-mono whitespace-pre-wrap break-all max-h-40 overflow-auto", children: [
|
|
5617
5901
|
"$",
|
|
5618
5902
|
cmd
|
|
5619
5903
|
] })
|
|
@@ -5622,16 +5906,16 @@ function SmartInputPreview({
|
|
|
5622
5906
|
const url = obj.url;
|
|
5623
5907
|
if (typeof url === "string") {
|
|
5624
5908
|
const method = obj.method ?? "GET";
|
|
5625
|
-
return /* @__PURE__ */
|
|
5626
|
-
/* @__PURE__ */
|
|
5909
|
+
return /* @__PURE__ */ jsxs19("div", { className: "rounded-lg border bg-background/40 px-3 py-2 text-xs font-mono", children: [
|
|
5910
|
+
/* @__PURE__ */ jsx20("span", { className: "text-muted-foreground", children: method.toUpperCase() }),
|
|
5627
5911
|
" ",
|
|
5628
|
-
/* @__PURE__ */
|
|
5912
|
+
/* @__PURE__ */ jsx20("span", { className: "break-all", children: url })
|
|
5629
5913
|
] });
|
|
5630
5914
|
}
|
|
5631
5915
|
}
|
|
5632
|
-
return /* @__PURE__ */
|
|
5633
|
-
/* @__PURE__ */
|
|
5634
|
-
/* @__PURE__ */
|
|
5916
|
+
return /* @__PURE__ */ jsxs19("div", { className: "p-3 rounded-lg bg-muted/50 border text-xs font-mono", children: [
|
|
5917
|
+
/* @__PURE__ */ jsx20("div", { className: "text-muted-foreground mb-2", children: "Input:" }),
|
|
5918
|
+
/* @__PURE__ */ jsx20("pre", { className: "whitespace-pre-wrap break-all max-h-60 overflow-auto", children: JSON.stringify(input, null, 2) })
|
|
5635
5919
|
] });
|
|
5636
5920
|
}
|
|
5637
5921
|
function ConfirmDialog() {
|
|
@@ -5644,7 +5928,7 @@ function ConfirmDialog() {
|
|
|
5644
5928
|
}
|
|
5645
5929
|
hideConfirm();
|
|
5646
5930
|
};
|
|
5647
|
-
|
|
5931
|
+
useEffect14(() => {
|
|
5648
5932
|
if (!showConfirmDialog) return;
|
|
5649
5933
|
const onKey = (e) => {
|
|
5650
5934
|
const target = e.target;
|
|
@@ -5669,50 +5953,50 @@ function ConfirmDialog() {
|
|
|
5669
5953
|
return () => window.removeEventListener("keydown", onKey);
|
|
5670
5954
|
}, [showConfirmDialog, confirmInfo?.id]);
|
|
5671
5955
|
if (!confirmInfo) {
|
|
5672
|
-
return /* @__PURE__ */
|
|
5956
|
+
return /* @__PURE__ */ jsx20(Dialog, { open: showConfirmDialog, onOpenChange: () => hideConfirm(), children: /* @__PURE__ */ jsx20(DialogContent, {}) });
|
|
5673
5957
|
}
|
|
5674
5958
|
const Icon2 = pickToolIcon(confirmInfo.toolName);
|
|
5675
5959
|
const isEdit = /edit|write/i.test(confirmInfo.toolName);
|
|
5676
|
-
return /* @__PURE__ */
|
|
5677
|
-
/* @__PURE__ */
|
|
5678
|
-
/* @__PURE__ */
|
|
5679
|
-
/* @__PURE__ */
|
|
5960
|
+
return /* @__PURE__ */ jsx20(Dialog, { open: showConfirmDialog, onOpenChange: () => hideConfirm(), children: /* @__PURE__ */ jsxs19(DialogContent, { className: "sm:max-w-2xl border-yellow-500/50", ref: dialogRef, tabIndex: -1, children: [
|
|
5961
|
+
/* @__PURE__ */ jsxs19(DialogHeader, { children: [
|
|
5962
|
+
/* @__PURE__ */ jsxs19(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
5963
|
+
/* @__PURE__ */ jsx20(ShieldAlert, { className: "h-5 w-5 text-yellow-500 animate-pulse" }),
|
|
5680
5964
|
"Approval required: ",
|
|
5681
5965
|
confirmInfo.toolName
|
|
5682
5966
|
] }),
|
|
5683
|
-
/* @__PURE__ */
|
|
5967
|
+
/* @__PURE__ */ jsxs19(DialogDescription, { children: [
|
|
5684
5968
|
"The agent wants to ",
|
|
5685
5969
|
isEdit ? "modify a file" : "run this tool",
|
|
5686
5970
|
". Review the request below and decide whether to proceed."
|
|
5687
5971
|
] })
|
|
5688
5972
|
] }),
|
|
5689
|
-
/* @__PURE__ */
|
|
5690
|
-
/* @__PURE__ */
|
|
5691
|
-
/* @__PURE__ */
|
|
5692
|
-
/* @__PURE__ */
|
|
5693
|
-
/* @__PURE__ */
|
|
5694
|
-
/* @__PURE__ */
|
|
5973
|
+
/* @__PURE__ */ jsxs19("div", { className: "py-2 space-y-3", children: [
|
|
5974
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-3 p-3 rounded-lg bg-muted", children: [
|
|
5975
|
+
/* @__PURE__ */ jsx20(Icon2, { className: "h-5 w-5 text-muted-foreground" }),
|
|
5976
|
+
/* @__PURE__ */ jsxs19("div", { className: "min-w-0", children: [
|
|
5977
|
+
/* @__PURE__ */ jsx20("div", { className: "font-medium font-mono truncate", children: confirmInfo.toolName }),
|
|
5978
|
+
/* @__PURE__ */ jsxs19("div", { className: "text-xs text-muted-foreground", children: [
|
|
5695
5979
|
isEdit ? "File modification" : "Tool execution",
|
|
5696
5980
|
" \u2014 preview below"
|
|
5697
5981
|
] })
|
|
5698
5982
|
] })
|
|
5699
5983
|
] }),
|
|
5700
|
-
confirmInfo.input !== void 0 && /* @__PURE__ */
|
|
5701
|
-
confirmInfo.suggestedPattern && /* @__PURE__ */
|
|
5702
|
-
/* @__PURE__ */
|
|
5703
|
-
/* @__PURE__ */
|
|
5704
|
-
/* @__PURE__ */
|
|
5705
|
-
/* @__PURE__ */
|
|
5706
|
-
/* @__PURE__ */
|
|
5984
|
+
confirmInfo.input !== void 0 && /* @__PURE__ */ jsx20(SmartInputPreview, { toolName: confirmInfo.toolName, input: confirmInfo.input }),
|
|
5985
|
+
confirmInfo.suggestedPattern && /* @__PURE__ */ jsxs19("div", { className: "flex items-start gap-2 p-3 rounded-lg bg-yellow-500/10 border border-yellow-500/20", children: [
|
|
5986
|
+
/* @__PURE__ */ jsx20(AlertTriangle2, { className: "h-4 w-4 text-yellow-600 mt-0.5 shrink-0" }),
|
|
5987
|
+
/* @__PURE__ */ jsxs19("div", { className: "text-sm min-w-0", children: [
|
|
5988
|
+
/* @__PURE__ */ jsx20("div", { className: "font-medium text-yellow-800 dark:text-yellow-200", children: "Trust pattern suggestion" }),
|
|
5989
|
+
/* @__PURE__ */ jsx20("div", { className: "font-mono text-xs mt-1 break-all", children: confirmInfo.suggestedPattern }),
|
|
5990
|
+
/* @__PURE__ */ jsxs19("div", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
5707
5991
|
"Picking ",
|
|
5708
|
-
/* @__PURE__ */
|
|
5992
|
+
/* @__PURE__ */ jsx20("span", { className: "font-medium", children: "Always" }),
|
|
5709
5993
|
" will whitelist matching calls for this project."
|
|
5710
5994
|
] })
|
|
5711
5995
|
] })
|
|
5712
5996
|
] })
|
|
5713
5997
|
] }),
|
|
5714
|
-
/* @__PURE__ */
|
|
5715
|
-
/* @__PURE__ */
|
|
5998
|
+
/* @__PURE__ */ jsxs19(DialogFooter, { className: "gap-2 sm:gap-2 flex-wrap", children: [
|
|
5999
|
+
/* @__PURE__ */ jsxs19(
|
|
5716
6000
|
Button,
|
|
5717
6001
|
{
|
|
5718
6002
|
variant: "outline",
|
|
@@ -5721,11 +6005,11 @@ function ConfirmDialog() {
|
|
|
5721
6005
|
title: "Reject this and all future calls matching the pattern (d)",
|
|
5722
6006
|
children: [
|
|
5723
6007
|
"Deny always ",
|
|
5724
|
-
/* @__PURE__ */
|
|
6008
|
+
/* @__PURE__ */ jsx20("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background", children: "d" })
|
|
5725
6009
|
]
|
|
5726
6010
|
}
|
|
5727
6011
|
),
|
|
5728
|
-
/* @__PURE__ */
|
|
6012
|
+
/* @__PURE__ */ jsxs19(
|
|
5729
6013
|
Button,
|
|
5730
6014
|
{
|
|
5731
6015
|
variant: "outline",
|
|
@@ -5734,11 +6018,11 @@ function ConfirmDialog() {
|
|
|
5734
6018
|
title: "Reject this single call (Esc / n)",
|
|
5735
6019
|
children: [
|
|
5736
6020
|
"No ",
|
|
5737
|
-
/* @__PURE__ */
|
|
6021
|
+
/* @__PURE__ */ jsx20("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background", children: "n" })
|
|
5738
6022
|
]
|
|
5739
6023
|
}
|
|
5740
6024
|
),
|
|
5741
|
-
/* @__PURE__ */
|
|
6025
|
+
/* @__PURE__ */ jsxs19(
|
|
5742
6026
|
Button,
|
|
5743
6027
|
{
|
|
5744
6028
|
variant: "outline",
|
|
@@ -5747,11 +6031,11 @@ function ConfirmDialog() {
|
|
|
5747
6031
|
title: "Approve and remember the pattern for the project (a)",
|
|
5748
6032
|
children: [
|
|
5749
6033
|
"Always ",
|
|
5750
|
-
/* @__PURE__ */
|
|
6034
|
+
/* @__PURE__ */ jsx20("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background", children: "a" })
|
|
5751
6035
|
]
|
|
5752
6036
|
}
|
|
5753
6037
|
),
|
|
5754
|
-
/* @__PURE__ */
|
|
6038
|
+
/* @__PURE__ */ jsxs19(
|
|
5755
6039
|
Button,
|
|
5756
6040
|
{
|
|
5757
6041
|
size: "sm",
|
|
@@ -5759,7 +6043,7 @@ function ConfirmDialog() {
|
|
|
5759
6043
|
title: "Approve this single call (y)",
|
|
5760
6044
|
children: [
|
|
5761
6045
|
"Yes ",
|
|
5762
|
-
/* @__PURE__ */
|
|
6046
|
+
/* @__PURE__ */ jsx20("kbd", { className: "ml-1 text-[10px] border rounded px-1 bg-background/80", children: "y" })
|
|
5763
6047
|
]
|
|
5764
6048
|
}
|
|
5765
6049
|
)
|
|
@@ -5768,20 +6052,20 @@ function ConfirmDialog() {
|
|
|
5768
6052
|
}
|
|
5769
6053
|
|
|
5770
6054
|
// src/components/ConnectionBanner.tsx
|
|
5771
|
-
import { Loader2 as Loader23, RotateCcw as RotateCcw4, WifiOff as
|
|
5772
|
-
import { useEffect as
|
|
5773
|
-
import { jsx as
|
|
6055
|
+
import { Loader2 as Loader23, RotateCcw as RotateCcw4, WifiOff as WifiOff2, X as X4 } from "lucide-react";
|
|
6056
|
+
import { useEffect as useEffect15, useState as useState15 } from "react";
|
|
6057
|
+
import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
5774
6058
|
function ConnectionBanner() {
|
|
5775
6059
|
const wsStatus = useConfigStore((s) => s.wsStatus);
|
|
5776
6060
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
5777
|
-
const [dismissed, setDismissed] =
|
|
5778
|
-
const [now, setNow] =
|
|
5779
|
-
|
|
6061
|
+
const [dismissed, setDismissed] = useState15(false);
|
|
6062
|
+
const [now, setNow] = useState15(Date.now());
|
|
6063
|
+
useEffect15(() => {
|
|
5780
6064
|
if (wsStatus.state !== "reconnecting") return;
|
|
5781
6065
|
const id = setInterval(() => setNow(Date.now()), 500);
|
|
5782
6066
|
return () => clearInterval(id);
|
|
5783
6067
|
}, [wsStatus.state]);
|
|
5784
|
-
|
|
6068
|
+
useEffect15(() => {
|
|
5785
6069
|
if (wsStatus.state === "open") setDismissed(false);
|
|
5786
6070
|
}, [wsStatus.state]);
|
|
5787
6071
|
if (wsStatus.state === "open" || wsStatus.state === "connecting") return null;
|
|
@@ -5790,7 +6074,7 @@ function ConnectionBanner() {
|
|
|
5790
6074
|
const isReconnecting = wsStatus.state === "reconnecting";
|
|
5791
6075
|
const errorText = wsStatus.state === "closed" ? wsStatus.error : wsStatus.state === "reconnecting" ? wsStatus.lastError : void 0;
|
|
5792
6076
|
const remaining = isReconnecting ? Math.max(0, Math.ceil((wsStatus.nextRetryAt - now) / 1e3)) : 0;
|
|
5793
|
-
return /* @__PURE__ */
|
|
6077
|
+
return /* @__PURE__ */ jsxs20(
|
|
5794
6078
|
"div",
|
|
5795
6079
|
{
|
|
5796
6080
|
className: cn(
|
|
@@ -5798,12 +6082,12 @@ function ConnectionBanner() {
|
|
|
5798
6082
|
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"
|
|
5799
6083
|
),
|
|
5800
6084
|
children: [
|
|
5801
|
-
isReconnecting ? /* @__PURE__ */
|
|
5802
|
-
/* @__PURE__ */
|
|
5803
|
-
/* @__PURE__ */
|
|
5804
|
-
errorText && /* @__PURE__ */
|
|
6085
|
+
isReconnecting ? /* @__PURE__ */ jsx21(Loader23, { className: "h-4 w-4 animate-spin shrink-0" }) : /* @__PURE__ */ jsx21(WifiOff2, { className: "h-4 w-4 shrink-0" }),
|
|
6086
|
+
/* @__PURE__ */ jsxs20("div", { className: "flex-1 min-w-0", children: [
|
|
6087
|
+
/* @__PURE__ */ jsx21("div", { className: "font-medium", children: isReconnecting ? `Reconnecting to backend (attempt ${wsStatus.attempt}) \u2014 retrying in ${remaining}s` : "Disconnected from backend" }),
|
|
6088
|
+
errorText && /* @__PURE__ */ jsx21("div", { className: "text-xs opacity-80 truncate", children: errorText })
|
|
5805
6089
|
] }),
|
|
5806
|
-
/* @__PURE__ */
|
|
6090
|
+
/* @__PURE__ */ jsxs20(
|
|
5807
6091
|
"button",
|
|
5808
6092
|
{
|
|
5809
6093
|
type: "button",
|
|
@@ -5815,19 +6099,19 @@ function ConnectionBanner() {
|
|
|
5815
6099
|
),
|
|
5816
6100
|
title: "Retry connection now",
|
|
5817
6101
|
children: [
|
|
5818
|
-
/* @__PURE__ */
|
|
6102
|
+
/* @__PURE__ */ jsx21(RotateCcw4, { className: "h-3 w-3" }),
|
|
5819
6103
|
"Retry now"
|
|
5820
6104
|
]
|
|
5821
6105
|
}
|
|
5822
6106
|
),
|
|
5823
|
-
/* @__PURE__ */
|
|
6107
|
+
/* @__PURE__ */ jsx21(
|
|
5824
6108
|
"button",
|
|
5825
6109
|
{
|
|
5826
6110
|
type: "button",
|
|
5827
6111
|
onClick: () => setDismissed(true),
|
|
5828
6112
|
className: "text-current/60 hover:text-current shrink-0",
|
|
5829
6113
|
title: "Dismiss (chip in topbar still shows status)",
|
|
5830
|
-
children: /* @__PURE__ */
|
|
6114
|
+
children: /* @__PURE__ */ jsx21(X4, { className: "h-4 w-4" })
|
|
5831
6115
|
}
|
|
5832
6116
|
)
|
|
5833
6117
|
]
|
|
@@ -5838,7 +6122,7 @@ function ConnectionBanner() {
|
|
|
5838
6122
|
// src/components/ErrorBoundary.tsx
|
|
5839
6123
|
import { AlertTriangle as AlertTriangle3, RefreshCw } from "lucide-react";
|
|
5840
6124
|
import { Component } from "react";
|
|
5841
|
-
import { jsx as
|
|
6125
|
+
import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
5842
6126
|
var ErrorBoundary = class extends Component {
|
|
5843
6127
|
state = { error: null };
|
|
5844
6128
|
static getDerivedStateFromError(error) {
|
|
@@ -5853,17 +6137,17 @@ var ErrorBoundary = class extends Component {
|
|
|
5853
6137
|
};
|
|
5854
6138
|
render() {
|
|
5855
6139
|
if (this.state.error) {
|
|
5856
|
-
return /* @__PURE__ */
|
|
5857
|
-
/* @__PURE__ */
|
|
5858
|
-
/* @__PURE__ */
|
|
5859
|
-
/* @__PURE__ */
|
|
5860
|
-
/* @__PURE__ */
|
|
5861
|
-
/* @__PURE__ */
|
|
5862
|
-
/* @__PURE__ */
|
|
5863
|
-
/* @__PURE__ */
|
|
6140
|
+
return /* @__PURE__ */ jsx22("div", { className: "flex items-center justify-center h-screen bg-background", children: /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-center gap-4 p-8 max-w-md text-center", children: [
|
|
6141
|
+
/* @__PURE__ */ jsx22(AlertTriangle3, { className: "h-12 w-12 text-destructive" }),
|
|
6142
|
+
/* @__PURE__ */ jsx22("h1", { className: "text-lg font-semibold", children: "Something went wrong" }),
|
|
6143
|
+
/* @__PURE__ */ jsx22("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." }),
|
|
6144
|
+
/* @__PURE__ */ jsx22("pre", { className: "text-xs font-mono text-muted-foreground bg-muted/50 rounded p-3 max-h-32 overflow-auto w-full text-left", children: this.state.error.message }),
|
|
6145
|
+
/* @__PURE__ */ jsxs21("div", { className: "flex gap-2", children: [
|
|
6146
|
+
/* @__PURE__ */ jsxs21(Button, { size: "sm", variant: "outline", onClick: () => window.location.reload(), children: [
|
|
6147
|
+
/* @__PURE__ */ jsx22(RefreshCw, { className: "h-4 w-4 mr-1" }),
|
|
5864
6148
|
"Reload page"
|
|
5865
6149
|
] }),
|
|
5866
|
-
/* @__PURE__ */
|
|
6150
|
+
/* @__PURE__ */ jsx22(Button, { size: "sm", onClick: this.handleReset, children: "Try again" })
|
|
5867
6151
|
] })
|
|
5868
6152
|
] }) });
|
|
5869
6153
|
}
|
|
@@ -5873,22 +6157,22 @@ var ErrorBoundary = class extends Component {
|
|
|
5873
6157
|
|
|
5874
6158
|
// src/components/QuickModelSwitcher.tsx
|
|
5875
6159
|
import { ArrowRight as ArrowRight2, Cpu as Cpu3, Search as Search4 } from "lucide-react";
|
|
5876
|
-
import { useEffect as
|
|
5877
|
-
import { jsx as
|
|
6160
|
+
import { useEffect as useEffect16, useMemo as useMemo5, useRef as useRef11, useState as useState16 } from "react";
|
|
6161
|
+
import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
5878
6162
|
function QuickModelSwitcher() {
|
|
5879
6163
|
const open = useUIStore((s) => s.modelSwitcherOpen);
|
|
5880
6164
|
const setOpen = useUIStore((s) => s.setModelSwitcherOpen);
|
|
5881
|
-
const [query, setQuery] =
|
|
5882
|
-
const [selected, setSelected] =
|
|
5883
|
-
const [saved, setSaved] =
|
|
5884
|
-
const [modelsByProvider, setModelsByProvider] =
|
|
6165
|
+
const [query, setQuery] = useState16("");
|
|
6166
|
+
const [selected, setSelected] = useState16(0);
|
|
6167
|
+
const [saved, setSaved] = useState16([]);
|
|
6168
|
+
const [modelsByProvider, setModelsByProvider] = useState16({});
|
|
5885
6169
|
const inputRef = useRef11(null);
|
|
5886
6170
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
5887
6171
|
const currentProvider = useConfigStore((s) => s.provider);
|
|
5888
6172
|
const currentModel = useConfigStore((s) => s.model);
|
|
5889
6173
|
const paletteOpen = useUIStore((s) => s.paletteOpen);
|
|
5890
6174
|
const ws = useWebSocket();
|
|
5891
|
-
|
|
6175
|
+
useEffect16(() => {
|
|
5892
6176
|
const onKey = (e) => {
|
|
5893
6177
|
const mod = e.ctrlKey || e.metaKey;
|
|
5894
6178
|
if (mod && e.key.toLowerCase() === "m" && !e.shiftKey && !e.altKey) {
|
|
@@ -5905,7 +6189,7 @@ function QuickModelSwitcher() {
|
|
|
5905
6189
|
window.addEventListener("keydown", onKey);
|
|
5906
6190
|
return () => window.removeEventListener("keydown", onKey);
|
|
5907
6191
|
}, [open, paletteOpen]);
|
|
5908
|
-
|
|
6192
|
+
useEffect16(() => {
|
|
5909
6193
|
const client2 = getWSClient(wsUrl);
|
|
5910
6194
|
const offSaved = client2.on("providers.saved", (msg) => {
|
|
5911
6195
|
const p = msg.payload;
|
|
@@ -5920,14 +6204,14 @@ function QuickModelSwitcher() {
|
|
|
5920
6204
|
offModels();
|
|
5921
6205
|
};
|
|
5922
6206
|
}, [wsUrl]);
|
|
5923
|
-
|
|
6207
|
+
useEffect16(() => {
|
|
5924
6208
|
if (!open) return;
|
|
5925
6209
|
setQuery("");
|
|
5926
6210
|
setSelected(0);
|
|
5927
6211
|
ws.listSavedProviders();
|
|
5928
6212
|
requestAnimationFrame(() => inputRef.current?.focus());
|
|
5929
6213
|
}, [open, ws]);
|
|
5930
|
-
|
|
6214
|
+
useEffect16(() => {
|
|
5931
6215
|
if (!open) return;
|
|
5932
6216
|
for (const sp of saved) {
|
|
5933
6217
|
if (!modelsByProvider[sp.id]) {
|
|
@@ -5958,7 +6242,7 @@ function QuickModelSwitcher() {
|
|
|
5958
6242
|
return a.provider.localeCompare(b.provider) || a.model.localeCompare(b.model);
|
|
5959
6243
|
});
|
|
5960
6244
|
}, [saved, modelsByProvider, query, currentProvider, currentModel]);
|
|
5961
|
-
|
|
6245
|
+
useEffect16(() => {
|
|
5962
6246
|
if (selected >= candidates.length) setSelected(0);
|
|
5963
6247
|
}, [candidates.length, selected]);
|
|
5964
6248
|
const commit = (idx) => {
|
|
@@ -5968,7 +6252,7 @@ function QuickModelSwitcher() {
|
|
|
5968
6252
|
setOpen(false);
|
|
5969
6253
|
};
|
|
5970
6254
|
if (!open) return null;
|
|
5971
|
-
return /* @__PURE__ */
|
|
6255
|
+
return /* @__PURE__ */ jsx23(
|
|
5972
6256
|
"div",
|
|
5973
6257
|
{
|
|
5974
6258
|
className: "fixed inset-0 z-50 flex items-start justify-center bg-background/60 backdrop-blur-sm pt-[15vh]",
|
|
@@ -5978,10 +6262,10 @@ function QuickModelSwitcher() {
|
|
|
5978
6262
|
onKeyDown: (e) => {
|
|
5979
6263
|
if (e.key === "Escape") setOpen(false);
|
|
5980
6264
|
},
|
|
5981
|
-
children: /* @__PURE__ */
|
|
5982
|
-
/* @__PURE__ */
|
|
5983
|
-
/* @__PURE__ */
|
|
5984
|
-
/* @__PURE__ */
|
|
6265
|
+
children: /* @__PURE__ */ jsxs22("div", { className: "w-full max-w-xl rounded-xl border bg-popover shadow-2xl overflow-hidden", children: [
|
|
6266
|
+
/* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 border-b px-3 py-2", children: [
|
|
6267
|
+
/* @__PURE__ */ jsx23(Search4, { className: "h-4 w-4 text-muted-foreground" }),
|
|
6268
|
+
/* @__PURE__ */ jsx23(
|
|
5985
6269
|
"input",
|
|
5986
6270
|
{
|
|
5987
6271
|
ref: inputRef,
|
|
@@ -6009,9 +6293,9 @@ function QuickModelSwitcher() {
|
|
|
6009
6293
|
className: "flex-1 bg-transparent outline-none text-sm placeholder:text-muted-foreground"
|
|
6010
6294
|
}
|
|
6011
6295
|
),
|
|
6012
|
-
/* @__PURE__ */
|
|
6296
|
+
/* @__PURE__ */ jsx23("span", { className: "text-[10px] text-muted-foreground font-mono", children: "\u2191\u2193 \xB7 Enter \xB7 Esc" })
|
|
6013
6297
|
] }),
|
|
6014
|
-
/* @__PURE__ */
|
|
6298
|
+
/* @__PURE__ */ jsx23("div", { className: "max-h-[50vh] overflow-y-auto py-1", children: candidates.length === 0 ? /* @__PURE__ */ jsx23("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__ */ jsxs22(
|
|
6015
6299
|
"button",
|
|
6016
6300
|
{
|
|
6017
6301
|
type: "button",
|
|
@@ -6023,7 +6307,7 @@ function QuickModelSwitcher() {
|
|
|
6023
6307
|
c.isCurrent && "font-medium"
|
|
6024
6308
|
),
|
|
6025
6309
|
children: [
|
|
6026
|
-
/* @__PURE__ */
|
|
6310
|
+
/* @__PURE__ */ jsx23(
|
|
6027
6311
|
Cpu3,
|
|
6028
6312
|
{
|
|
6029
6313
|
className: cn(
|
|
@@ -6032,19 +6316,19 @@ function QuickModelSwitcher() {
|
|
|
6032
6316
|
)
|
|
6033
6317
|
}
|
|
6034
6318
|
),
|
|
6035
|
-
/* @__PURE__ */
|
|
6036
|
-
/* @__PURE__ */
|
|
6037
|
-
/* @__PURE__ */
|
|
6038
|
-
/* @__PURE__ */
|
|
6039
|
-
/* @__PURE__ */
|
|
6319
|
+
/* @__PURE__ */ jsxs22("div", { className: "min-w-0 flex-1", children: [
|
|
6320
|
+
/* @__PURE__ */ jsxs22("div", { className: "truncate", children: [
|
|
6321
|
+
/* @__PURE__ */ jsx23("span", { className: "text-muted-foreground", children: c.provider }),
|
|
6322
|
+
/* @__PURE__ */ jsx23("span", { className: "mx-1 text-muted-foreground/40", children: "\xB7" }),
|
|
6323
|
+
/* @__PURE__ */ jsx23("span", { children: c.modelName })
|
|
6040
6324
|
] }),
|
|
6041
|
-
c.contextWindow && /* @__PURE__ */
|
|
6325
|
+
c.contextWindow && /* @__PURE__ */ jsxs22("div", { className: "text-[10px] text-muted-foreground font-mono", children: [
|
|
6042
6326
|
c.model,
|
|
6043
6327
|
" \xB7 ctx ",
|
|
6044
6328
|
c.contextWindow.toLocaleString()
|
|
6045
6329
|
] })
|
|
6046
6330
|
] }),
|
|
6047
|
-
c.isCurrent ? /* @__PURE__ */
|
|
6331
|
+
c.isCurrent ? /* @__PURE__ */ jsx23("span", { className: "text-[10px] uppercase tracking-wide text-primary font-semibold", children: "active" }) : /* @__PURE__ */ jsx23(ArrowRight2, { className: "h-3.5 w-3.5 text-muted-foreground opacity-0 group-hover:opacity-100" })
|
|
6048
6332
|
]
|
|
6049
6333
|
},
|
|
6050
6334
|
`${c.provider}:${c.model}`
|
|
@@ -6059,7 +6343,7 @@ import {
|
|
|
6059
6343
|
AlertCircle,
|
|
6060
6344
|
CheckCircle2 as CheckCircle24,
|
|
6061
6345
|
Cpu as Cpu4,
|
|
6062
|
-
Eye,
|
|
6346
|
+
Eye as Eye2,
|
|
6063
6347
|
EyeOff,
|
|
6064
6348
|
Globe as Globe2,
|
|
6065
6349
|
Key,
|
|
@@ -6074,25 +6358,25 @@ import {
|
|
|
6074
6358
|
Trash2 as Trash22,
|
|
6075
6359
|
X as X5
|
|
6076
6360
|
} from "lucide-react";
|
|
6077
|
-
import { useState as
|
|
6361
|
+
import { useState as useState18, useEffect as useEffect18, useCallback as useCallback4 } from "react";
|
|
6078
6362
|
|
|
6079
6363
|
// src/components/ThemeProvider.tsx
|
|
6080
|
-
import { createContext, useContext, useEffect as
|
|
6081
|
-
import { jsx as
|
|
6364
|
+
import { createContext, useContext, useEffect as useEffect17, useState as useState17 } from "react";
|
|
6365
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
6082
6366
|
var ThemeProviderContext = createContext(void 0);
|
|
6083
6367
|
function ThemeProvider({
|
|
6084
6368
|
children,
|
|
6085
6369
|
defaultTheme = "system",
|
|
6086
6370
|
storageKey = "wrongstack-theme"
|
|
6087
6371
|
}) {
|
|
6088
|
-
const {
|
|
6089
|
-
const [theme, setTheme] =
|
|
6372
|
+
const { setTheme: setStoreTheme } = useConfigStore();
|
|
6373
|
+
const [theme, setTheme] = useState17(() => {
|
|
6090
6374
|
if (typeof window !== "undefined") {
|
|
6091
6375
|
return localStorage.getItem(storageKey) || defaultTheme;
|
|
6092
6376
|
}
|
|
6093
6377
|
return defaultTheme;
|
|
6094
6378
|
});
|
|
6095
|
-
|
|
6379
|
+
useEffect17(() => {
|
|
6096
6380
|
const root = window.document.documentElement;
|
|
6097
6381
|
root.classList.remove("light", "dark");
|
|
6098
6382
|
if (theme === "system") {
|
|
@@ -6110,7 +6394,7 @@ function ThemeProvider({
|
|
|
6110
6394
|
setStoreTheme(newTheme);
|
|
6111
6395
|
}
|
|
6112
6396
|
};
|
|
6113
|
-
return /* @__PURE__ */
|
|
6397
|
+
return /* @__PURE__ */ jsx24(ThemeProviderContext.Provider, { value, children });
|
|
6114
6398
|
}
|
|
6115
6399
|
function useTheme() {
|
|
6116
6400
|
const context = useContext(ThemeProviderContext);
|
|
@@ -6122,10 +6406,10 @@ function useTheme() {
|
|
|
6122
6406
|
|
|
6123
6407
|
// src/components/ui/input.tsx
|
|
6124
6408
|
import * as React4 from "react";
|
|
6125
|
-
import { jsx as
|
|
6409
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
6126
6410
|
var Input = React4.forwardRef(
|
|
6127
6411
|
({ className, type, ...props }, ref) => {
|
|
6128
|
-
return /* @__PURE__ */
|
|
6412
|
+
return /* @__PURE__ */ jsx25(
|
|
6129
6413
|
"input",
|
|
6130
6414
|
{
|
|
6131
6415
|
type,
|
|
@@ -6144,9 +6428,9 @@ Input.displayName = "Input";
|
|
|
6144
6428
|
// src/components/ui/tabs.tsx
|
|
6145
6429
|
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
6146
6430
|
import * as React5 from "react";
|
|
6147
|
-
import { jsx as
|
|
6431
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
6148
6432
|
var Tabs = TabsPrimitive.Root;
|
|
6149
|
-
var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6433
|
+
var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
|
|
6150
6434
|
TabsPrimitive.List,
|
|
6151
6435
|
{
|
|
6152
6436
|
ref,
|
|
@@ -6158,7 +6442,7 @@ var TabsList = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
6158
6442
|
}
|
|
6159
6443
|
));
|
|
6160
6444
|
TabsList.displayName = TabsPrimitive.List.displayName;
|
|
6161
|
-
var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6445
|
+
var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
|
|
6162
6446
|
TabsPrimitive.Trigger,
|
|
6163
6447
|
{
|
|
6164
6448
|
ref,
|
|
@@ -6170,7 +6454,7 @@ var TabsTrigger = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
6170
6454
|
}
|
|
6171
6455
|
));
|
|
6172
6456
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
|
|
6173
|
-
var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
6457
|
+
var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx26(
|
|
6174
6458
|
TabsPrimitive.Content,
|
|
6175
6459
|
{
|
|
6176
6460
|
ref,
|
|
@@ -6184,34 +6468,32 @@ var TabsContent = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
6184
6468
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
|
6185
6469
|
|
|
6186
6470
|
// src/components/SettingsPanel.tsx
|
|
6187
|
-
import { Fragment as Fragment7, jsx as
|
|
6471
|
+
import { Fragment as Fragment7, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
6188
6472
|
function SettingsPanel() {
|
|
6189
6473
|
const { setCurrentView } = useUIStore();
|
|
6190
6474
|
const { provider, model, setProvider, setModel, wsConnected } = useConfigStore();
|
|
6191
6475
|
const { theme, setTheme } = useTheme();
|
|
6192
6476
|
const ws = useWebSocket();
|
|
6193
6477
|
const wsClient = ws.client;
|
|
6194
|
-
const
|
|
6195
|
-
const
|
|
6196
|
-
const [
|
|
6197
|
-
const [
|
|
6198
|
-
const [
|
|
6199
|
-
const [
|
|
6200
|
-
const [
|
|
6201
|
-
const [
|
|
6202
|
-
const [
|
|
6203
|
-
const [
|
|
6204
|
-
const [
|
|
6205
|
-
const [
|
|
6206
|
-
const [
|
|
6207
|
-
const [
|
|
6208
|
-
const [
|
|
6209
|
-
const [
|
|
6210
|
-
const [
|
|
6211
|
-
const [newProviderBaseUrl, setNewProviderBaseUrl] = useState17("");
|
|
6212
|
-
const [newProviderApiKey, setNewProviderApiKey] = useState17("");
|
|
6478
|
+
const [catalogProviders, setCatalogProviders] = useState18([]);
|
|
6479
|
+
const [catalogModels, setCatalogModels] = useState18({});
|
|
6480
|
+
const [savedProviders, setSavedProviders] = useState18([]);
|
|
6481
|
+
const [isLoadingCatalog, setIsLoadingCatalog] = useState18(false);
|
|
6482
|
+
const [isLoadingModels, setIsLoadingModels] = useState18(false);
|
|
6483
|
+
const [isLoadingSaved, setIsLoadingSaved] = useState18(false);
|
|
6484
|
+
const [operationStatus, setOperationStatus] = useState18(null);
|
|
6485
|
+
const [providerTab, setProviderTab] = useState18("catalog");
|
|
6486
|
+
const [showAddKeyForm, setShowAddKeyForm] = useState18(null);
|
|
6487
|
+
const [newKeyLabel, setNewKeyLabel] = useState18("");
|
|
6488
|
+
const [newKeyValue, setNewKeyValue] = useState18("");
|
|
6489
|
+
const [showNewKeyValue, setShowNewKeyValue] = useState18(false);
|
|
6490
|
+
const [showAddProviderForm, setShowAddProviderForm] = useState18(false);
|
|
6491
|
+
const [newProviderId, setNewProviderId] = useState18("");
|
|
6492
|
+
const [newProviderFamily, setNewProviderFamily] = useState18("openai-compatible");
|
|
6493
|
+
const [newProviderBaseUrl, setNewProviderBaseUrl] = useState18("");
|
|
6494
|
+
const [newProviderApiKey, setNewProviderApiKey] = useState18("");
|
|
6213
6495
|
const currentCatalogProvider = catalogProviders.find((p) => p.id === provider);
|
|
6214
|
-
|
|
6496
|
+
useEffect18(() => {
|
|
6215
6497
|
const handleProviderCatalog = (msg) => {
|
|
6216
6498
|
if (msg.type === "provider.catalog") {
|
|
6217
6499
|
const payload = msg.payload;
|
|
@@ -6320,7 +6602,7 @@ function SettingsPanel() {
|
|
|
6320
6602
|
},
|
|
6321
6603
|
[ws]
|
|
6322
6604
|
);
|
|
6323
|
-
const [catalogQuery, setCatalogQuery] =
|
|
6605
|
+
const [catalogQuery, setCatalogQuery] = useState18("");
|
|
6324
6606
|
const families = ["anthropic", "openai", "google", "openai-compatible"];
|
|
6325
6607
|
const filteredCatalog = catalogQuery.trim() ? catalogProviders.filter((p) => {
|
|
6326
6608
|
const q = catalogQuery.trim().toLowerCase();
|
|
@@ -6334,52 +6616,52 @@ function SettingsPanel() {
|
|
|
6334
6616
|
},
|
|
6335
6617
|
{}
|
|
6336
6618
|
);
|
|
6337
|
-
return /* @__PURE__ */
|
|
6338
|
-
/* @__PURE__ */
|
|
6339
|
-
/* @__PURE__ */
|
|
6340
|
-
/* @__PURE__ */
|
|
6619
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex flex-col h-full", children: [
|
|
6620
|
+
/* @__PURE__ */ jsxs23("header", { className: "flex items-center justify-between px-4 py-3 border-b bg-card shrink-0", children: [
|
|
6621
|
+
/* @__PURE__ */ jsx27("h1", { className: "text-lg font-semibold", children: "Settings" }),
|
|
6622
|
+
/* @__PURE__ */ jsx27(Button, { variant: "ghost", size: "icon", onClick: () => setCurrentView("chat"), children: /* @__PURE__ */ jsx27(X5, { className: "h-4 w-4" }) })
|
|
6341
6623
|
] }),
|
|
6342
|
-
/* @__PURE__ */
|
|
6343
|
-
/* @__PURE__ */
|
|
6344
|
-
/* @__PURE__ */
|
|
6345
|
-
/* @__PURE__ */
|
|
6624
|
+
/* @__PURE__ */ jsx27(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsx27("div", { className: "p-6 max-w-2xl mx-auto", children: /* @__PURE__ */ jsxs23(Tabs, { defaultValue: "provider", children: [
|
|
6625
|
+
/* @__PURE__ */ jsxs23(TabsList, { className: "w-full justify-start mb-6 grid grid-cols-4", children: [
|
|
6626
|
+
/* @__PURE__ */ jsxs23(TabsTrigger, { value: "provider", className: "gap-2", children: [
|
|
6627
|
+
/* @__PURE__ */ jsx27(Network, { className: "h-4 w-4" }),
|
|
6346
6628
|
"Provider"
|
|
6347
6629
|
] }),
|
|
6348
|
-
/* @__PURE__ */
|
|
6349
|
-
/* @__PURE__ */
|
|
6630
|
+
/* @__PURE__ */ jsxs23(TabsTrigger, { value: "model", className: "gap-2", children: [
|
|
6631
|
+
/* @__PURE__ */ jsx27(Cpu4, { className: "h-4 w-4" }),
|
|
6350
6632
|
"Model"
|
|
6351
6633
|
] }),
|
|
6352
|
-
/* @__PURE__ */
|
|
6353
|
-
/* @__PURE__ */
|
|
6634
|
+
/* @__PURE__ */ jsxs23(TabsTrigger, { value: "connection", className: "gap-2", children: [
|
|
6635
|
+
/* @__PURE__ */ jsx27(Globe2, { className: "h-4 w-4" }),
|
|
6354
6636
|
"Connection"
|
|
6355
6637
|
] }),
|
|
6356
|
-
/* @__PURE__ */
|
|
6357
|
-
/* @__PURE__ */
|
|
6638
|
+
/* @__PURE__ */ jsxs23(TabsTrigger, { value: "appearance", className: "gap-2", children: [
|
|
6639
|
+
/* @__PURE__ */ jsx27(Palette, { className: "h-4 w-4" }),
|
|
6358
6640
|
"Appearance"
|
|
6359
6641
|
] })
|
|
6360
6642
|
] }),
|
|
6361
|
-
/* @__PURE__ */
|
|
6362
|
-
/* @__PURE__ */
|
|
6363
|
-
/* @__PURE__ */
|
|
6643
|
+
/* @__PURE__ */ jsxs23(TabsContent, { value: "provider", className: "space-y-4", children: [
|
|
6644
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex gap-2 mb-4", children: [
|
|
6645
|
+
/* @__PURE__ */ jsxs23(
|
|
6364
6646
|
Button,
|
|
6365
6647
|
{
|
|
6366
6648
|
variant: providerTab === "catalog" ? "default" : "outline",
|
|
6367
6649
|
size: "sm",
|
|
6368
6650
|
onClick: () => setProviderTab("catalog"),
|
|
6369
6651
|
children: [
|
|
6370
|
-
/* @__PURE__ */
|
|
6652
|
+
/* @__PURE__ */ jsx27(Globe2, { className: "h-4 w-4 mr-1" }),
|
|
6371
6653
|
"Catalog"
|
|
6372
6654
|
]
|
|
6373
6655
|
}
|
|
6374
6656
|
),
|
|
6375
|
-
/* @__PURE__ */
|
|
6657
|
+
/* @__PURE__ */ jsxs23(
|
|
6376
6658
|
Button,
|
|
6377
6659
|
{
|
|
6378
6660
|
variant: providerTab === "saved" ? "default" : "outline",
|
|
6379
6661
|
size: "sm",
|
|
6380
6662
|
onClick: () => setProviderTab("saved"),
|
|
6381
6663
|
children: [
|
|
6382
|
-
/* @__PURE__ */
|
|
6664
|
+
/* @__PURE__ */ jsx27(Key, { className: "h-4 w-4 mr-1" }),
|
|
6383
6665
|
"Saved (",
|
|
6384
6666
|
savedProviders.length,
|
|
6385
6667
|
")"
|
|
@@ -6387,7 +6669,7 @@ function SettingsPanel() {
|
|
|
6387
6669
|
}
|
|
6388
6670
|
)
|
|
6389
6671
|
] }),
|
|
6390
|
-
operationStatus && /* @__PURE__ */
|
|
6672
|
+
operationStatus && /* @__PURE__ */ jsxs23(
|
|
6391
6673
|
"div",
|
|
6392
6674
|
{
|
|
6393
6675
|
className: cn(
|
|
@@ -6395,13 +6677,13 @@ function SettingsPanel() {
|
|
|
6395
6677
|
operationStatus.success ? "bg-green-500/10 text-green-600" : "bg-red-500/10 text-red-600"
|
|
6396
6678
|
),
|
|
6397
6679
|
children: [
|
|
6398
|
-
operationStatus.success ? /* @__PURE__ */
|
|
6680
|
+
operationStatus.success ? /* @__PURE__ */ jsx27(CheckCircle24, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx27(AlertCircle, { className: "h-4 w-4" }),
|
|
6399
6681
|
operationStatus.message
|
|
6400
6682
|
]
|
|
6401
6683
|
}
|
|
6402
6684
|
),
|
|
6403
|
-
providerTab === "catalog" && /* @__PURE__ */
|
|
6404
|
-
/* @__PURE__ */
|
|
6685
|
+
providerTab === "catalog" && /* @__PURE__ */ jsxs23("div", { className: "space-y-4", children: [
|
|
6686
|
+
/* @__PURE__ */ jsx27(
|
|
6405
6687
|
Input,
|
|
6406
6688
|
{
|
|
6407
6689
|
placeholder: `Search ${catalogProviders.length} providers (name / id / family)\u2026`,
|
|
@@ -6410,19 +6692,19 @@ function SettingsPanel() {
|
|
|
6410
6692
|
className: "text-sm"
|
|
6411
6693
|
}
|
|
6412
6694
|
),
|
|
6413
|
-
isLoadingCatalog && catalogProviders.length === 0 ? /* @__PURE__ */
|
|
6414
|
-
/* @__PURE__ */
|
|
6415
|
-
/* @__PURE__ */
|
|
6416
|
-
] }) : filteredCatalog.length === 0 && catalogQuery ? /* @__PURE__ */
|
|
6695
|
+
isLoadingCatalog && catalogProviders.length === 0 ? /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-center py-8", children: [
|
|
6696
|
+
/* @__PURE__ */ jsx27(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }),
|
|
6697
|
+
/* @__PURE__ */ jsx27("span", { className: "ml-2 text-muted-foreground", children: "Loading catalog..." })
|
|
6698
|
+
] }) : filteredCatalog.length === 0 && catalogQuery ? /* @__PURE__ */ jsxs23("div", { className: "text-center py-8 text-muted-foreground text-sm", children: [
|
|
6417
6699
|
'No providers match "',
|
|
6418
|
-
/* @__PURE__ */
|
|
6700
|
+
/* @__PURE__ */ jsx27("span", { className: "font-mono", children: catalogQuery }),
|
|
6419
6701
|
'".'
|
|
6420
|
-
] }) : /* @__PURE__ */
|
|
6702
|
+
] }) : /* @__PURE__ */ jsx27(Fragment7, { children: families.map((family) => {
|
|
6421
6703
|
const providers = catalogByFamily[family];
|
|
6422
6704
|
if (!providers?.length) return null;
|
|
6423
|
-
return /* @__PURE__ */
|
|
6424
|
-
/* @__PURE__ */
|
|
6425
|
-
/* @__PURE__ */
|
|
6705
|
+
return /* @__PURE__ */ jsxs23("div", { className: "space-y-2", children: [
|
|
6706
|
+
/* @__PURE__ */ jsx27("h3", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-wider", children: family }),
|
|
6707
|
+
/* @__PURE__ */ jsx27("div", { className: "grid grid-cols-1 gap-2", children: providers.map((p) => /* @__PURE__ */ jsxs23(
|
|
6426
6708
|
"button",
|
|
6427
6709
|
{
|
|
6428
6710
|
type: "button",
|
|
@@ -6432,28 +6714,28 @@ function SettingsPanel() {
|
|
|
6432
6714
|
provider === p.id ? "border-primary bg-primary/5 ring-2 ring-primary/20" : "border-border hover:bg-muted"
|
|
6433
6715
|
),
|
|
6434
6716
|
children: [
|
|
6435
|
-
/* @__PURE__ */
|
|
6436
|
-
/* @__PURE__ */
|
|
6437
|
-
/* @__PURE__ */
|
|
6438
|
-
/* @__PURE__ */
|
|
6717
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex w-full justify-between items-start", children: [
|
|
6718
|
+
/* @__PURE__ */ jsxs23("div", { children: [
|
|
6719
|
+
/* @__PURE__ */ jsx27("span", { className: "font-medium", children: p.name }),
|
|
6720
|
+
/* @__PURE__ */ jsxs23("span", { className: "ml-2 text-xs text-muted-foreground", children: [
|
|
6439
6721
|
"(",
|
|
6440
6722
|
p.id,
|
|
6441
6723
|
")"
|
|
6442
6724
|
] })
|
|
6443
6725
|
] }),
|
|
6444
|
-
/* @__PURE__ */
|
|
6445
|
-
p.hasApiKey && /* @__PURE__ */
|
|
6446
|
-
/* @__PURE__ */
|
|
6726
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2", children: [
|
|
6727
|
+
p.hasApiKey && /* @__PURE__ */ jsxs23("span", { className: "text-xs bg-green-500/10 text-green-600 px-2 py-0.5 rounded", children: [
|
|
6728
|
+
/* @__PURE__ */ jsx27(Key, { className: "h-3 w-3 inline mr-1" }),
|
|
6447
6729
|
"Configured"
|
|
6448
6730
|
] }),
|
|
6449
|
-
p.envVars[0] && /* @__PURE__ */
|
|
6731
|
+
p.envVars[0] && /* @__PURE__ */ jsxs23("span", { className: "text-xs text-muted-foreground", children: [
|
|
6450
6732
|
"ENV: ",
|
|
6451
6733
|
p.envVars[0]
|
|
6452
6734
|
] }),
|
|
6453
|
-
provider === p.id && /* @__PURE__ */
|
|
6735
|
+
provider === p.id && /* @__PURE__ */ jsx27(CheckCircle24, { className: "h-4 w-4 text-primary" })
|
|
6454
6736
|
] })
|
|
6455
6737
|
] }),
|
|
6456
|
-
/* @__PURE__ */
|
|
6738
|
+
/* @__PURE__ */ jsxs23("div", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
6457
6739
|
p.modelCount,
|
|
6458
6740
|
" models",
|
|
6459
6741
|
p.apiBase && ` \xB7 ${p.apiBase}`
|
|
@@ -6465,25 +6747,25 @@ function SettingsPanel() {
|
|
|
6465
6747
|
] }, family);
|
|
6466
6748
|
}) })
|
|
6467
6749
|
] }),
|
|
6468
|
-
providerTab === "saved" && /* @__PURE__ */
|
|
6469
|
-
/* @__PURE__ */
|
|
6470
|
-
/* @__PURE__ */
|
|
6471
|
-
/* @__PURE__ */
|
|
6750
|
+
providerTab === "saved" && /* @__PURE__ */ jsxs23("div", { className: "space-y-4", children: [
|
|
6751
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex justify-between items-center", children: [
|
|
6752
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm text-muted-foreground", children: "Manage your API keys and provider configurations" }),
|
|
6753
|
+
/* @__PURE__ */ jsxs23(
|
|
6472
6754
|
Button,
|
|
6473
6755
|
{
|
|
6474
6756
|
size: "sm",
|
|
6475
6757
|
variant: "outline",
|
|
6476
6758
|
onClick: () => setShowAddProviderForm(!showAddProviderForm),
|
|
6477
6759
|
children: [
|
|
6478
|
-
/* @__PURE__ */
|
|
6760
|
+
/* @__PURE__ */ jsx27(Plus, { className: "h-4 w-4 mr-1" }),
|
|
6479
6761
|
"Add Provider"
|
|
6480
6762
|
]
|
|
6481
6763
|
}
|
|
6482
6764
|
)
|
|
6483
6765
|
] }),
|
|
6484
|
-
showAddProviderForm && /* @__PURE__ */
|
|
6485
|
-
/* @__PURE__ */
|
|
6486
|
-
/* @__PURE__ */
|
|
6766
|
+
showAddProviderForm && /* @__PURE__ */ jsxs23("div", { className: "p-4 border rounded-lg space-y-3 bg-muted/50", children: [
|
|
6767
|
+
/* @__PURE__ */ jsx27("h4", { className: "font-medium", children: "Add Custom Provider" }),
|
|
6768
|
+
/* @__PURE__ */ jsx27(
|
|
6487
6769
|
Input,
|
|
6488
6770
|
{
|
|
6489
6771
|
placeholder: "Provider ID (e.g. my-llm-server)",
|
|
@@ -6491,21 +6773,21 @@ function SettingsPanel() {
|
|
|
6491
6773
|
onChange: (e) => setNewProviderId(e.target.value)
|
|
6492
6774
|
}
|
|
6493
6775
|
),
|
|
6494
|
-
/* @__PURE__ */
|
|
6776
|
+
/* @__PURE__ */ jsxs23(
|
|
6495
6777
|
"select",
|
|
6496
6778
|
{
|
|
6497
6779
|
className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
|
|
6498
6780
|
value: newProviderFamily,
|
|
6499
6781
|
onChange: (e) => setNewProviderFamily(e.target.value),
|
|
6500
6782
|
children: [
|
|
6501
|
-
/* @__PURE__ */
|
|
6502
|
-
/* @__PURE__ */
|
|
6503
|
-
/* @__PURE__ */
|
|
6504
|
-
/* @__PURE__ */
|
|
6783
|
+
/* @__PURE__ */ jsx27("option", { value: "anthropic", children: "Anthropic" }),
|
|
6784
|
+
/* @__PURE__ */ jsx27("option", { value: "openai", children: "OpenAI" }),
|
|
6785
|
+
/* @__PURE__ */ jsx27("option", { value: "openai-compatible", children: "OpenAI Compatible" }),
|
|
6786
|
+
/* @__PURE__ */ jsx27("option", { value: "google", children: "Google" })
|
|
6505
6787
|
]
|
|
6506
6788
|
}
|
|
6507
6789
|
),
|
|
6508
|
-
/* @__PURE__ */
|
|
6790
|
+
/* @__PURE__ */ jsx27(
|
|
6509
6791
|
Input,
|
|
6510
6792
|
{
|
|
6511
6793
|
placeholder: "Base URL (optional, e.g. http://localhost:11434/v1)",
|
|
@@ -6513,7 +6795,7 @@ function SettingsPanel() {
|
|
|
6513
6795
|
onChange: (e) => setNewProviderBaseUrl(e.target.value)
|
|
6514
6796
|
}
|
|
6515
6797
|
),
|
|
6516
|
-
/* @__PURE__ */
|
|
6798
|
+
/* @__PURE__ */ jsx27(
|
|
6517
6799
|
Input,
|
|
6518
6800
|
{
|
|
6519
6801
|
type: "password",
|
|
@@ -6522,8 +6804,8 @@ function SettingsPanel() {
|
|
|
6522
6804
|
onChange: (e) => setNewProviderApiKey(e.target.value)
|
|
6523
6805
|
}
|
|
6524
6806
|
),
|
|
6525
|
-
/* @__PURE__ */
|
|
6526
|
-
/* @__PURE__ */
|
|
6807
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex gap-2", children: [
|
|
6808
|
+
/* @__PURE__ */ jsx27(
|
|
6527
6809
|
Button,
|
|
6528
6810
|
{
|
|
6529
6811
|
size: "sm",
|
|
@@ -6532,7 +6814,7 @@ function SettingsPanel() {
|
|
|
6532
6814
|
children: "Add"
|
|
6533
6815
|
}
|
|
6534
6816
|
),
|
|
6535
|
-
/* @__PURE__ */
|
|
6817
|
+
/* @__PURE__ */ jsx27(
|
|
6536
6818
|
Button,
|
|
6537
6819
|
{
|
|
6538
6820
|
size: "sm",
|
|
@@ -6543,59 +6825,59 @@ function SettingsPanel() {
|
|
|
6543
6825
|
)
|
|
6544
6826
|
] })
|
|
6545
6827
|
] }),
|
|
6546
|
-
isLoadingSaved ? /* @__PURE__ */
|
|
6547
|
-
/* @__PURE__ */
|
|
6548
|
-
/* @__PURE__ */
|
|
6549
|
-
/* @__PURE__ */
|
|
6550
|
-
] }) : savedProviders.map((sp) => /* @__PURE__ */
|
|
6551
|
-
/* @__PURE__ */
|
|
6552
|
-
/* @__PURE__ */
|
|
6553
|
-
/* @__PURE__ */
|
|
6554
|
-
sp.family && /* @__PURE__ */
|
|
6828
|
+
isLoadingSaved ? /* @__PURE__ */ jsx27("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx27(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }) }) : savedProviders.length === 0 ? /* @__PURE__ */ jsxs23("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
6829
|
+
/* @__PURE__ */ jsx27(Key, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
|
|
6830
|
+
/* @__PURE__ */ jsx27("p", { children: "No saved providers yet" }),
|
|
6831
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm", children: "Add a provider to get started" })
|
|
6832
|
+
] }) : savedProviders.map((sp) => /* @__PURE__ */ jsxs23("div", { className: "border rounded-lg p-4 space-y-3", children: [
|
|
6833
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex justify-between items-start", children: [
|
|
6834
|
+
/* @__PURE__ */ jsxs23("div", { children: [
|
|
6835
|
+
/* @__PURE__ */ jsx27("h4", { className: "font-medium", children: sp.id }),
|
|
6836
|
+
sp.family && /* @__PURE__ */ jsx27("span", { className: "text-xs text-muted-foreground", children: sp.family })
|
|
6555
6837
|
] }),
|
|
6556
|
-
/* @__PURE__ */
|
|
6838
|
+
/* @__PURE__ */ jsx27("div", { className: "flex gap-2", children: /* @__PURE__ */ jsx27(
|
|
6557
6839
|
Button,
|
|
6558
6840
|
{
|
|
6559
6841
|
size: "icon",
|
|
6560
6842
|
variant: "ghost",
|
|
6561
6843
|
onClick: () => handleRemoveProvider(sp.id),
|
|
6562
|
-
children: /* @__PURE__ */
|
|
6844
|
+
children: /* @__PURE__ */ jsx27(Trash22, { className: "h-4 w-4 text-destructive" })
|
|
6563
6845
|
}
|
|
6564
6846
|
) })
|
|
6565
6847
|
] }),
|
|
6566
|
-
sp.baseUrl && /* @__PURE__ */
|
|
6567
|
-
/* @__PURE__ */
|
|
6848
|
+
sp.baseUrl && /* @__PURE__ */ jsxs23("div", { className: "text-xs text-muted-foreground", children: [
|
|
6849
|
+
/* @__PURE__ */ jsx27(Globe2, { className: "h-3 w-3 inline mr-1" }),
|
|
6568
6850
|
sp.baseUrl
|
|
6569
6851
|
] }),
|
|
6570
|
-
/* @__PURE__ */
|
|
6571
|
-
/* @__PURE__ */
|
|
6572
|
-
/* @__PURE__ */
|
|
6573
|
-
/* @__PURE__ */
|
|
6852
|
+
/* @__PURE__ */ jsxs23("div", { className: "space-y-2", children: [
|
|
6853
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex justify-between items-center", children: [
|
|
6854
|
+
/* @__PURE__ */ jsx27("span", { className: "text-sm font-medium", children: "API Keys" }),
|
|
6855
|
+
/* @__PURE__ */ jsxs23(
|
|
6574
6856
|
Button,
|
|
6575
6857
|
{
|
|
6576
6858
|
size: "sm",
|
|
6577
6859
|
variant: "ghost",
|
|
6578
6860
|
onClick: () => setShowAddKeyForm(showAddKeyForm === sp.id ? null : sp.id),
|
|
6579
6861
|
children: [
|
|
6580
|
-
/* @__PURE__ */
|
|
6862
|
+
/* @__PURE__ */ jsx27(Plus, { className: "h-3 w-3 mr-1" }),
|
|
6581
6863
|
"Add Key"
|
|
6582
6864
|
]
|
|
6583
6865
|
}
|
|
6584
6866
|
)
|
|
6585
6867
|
] }),
|
|
6586
|
-
sp.apiKeys.length === 0 && !showAddKeyForm && /* @__PURE__ */
|
|
6587
|
-
sp.apiKeys.map((key) => /* @__PURE__ */
|
|
6868
|
+
sp.apiKeys.length === 0 && !showAddKeyForm && /* @__PURE__ */ jsx27("p", { className: "text-xs text-muted-foreground", children: "No keys configured" }),
|
|
6869
|
+
sp.apiKeys.map((key) => /* @__PURE__ */ jsxs23(
|
|
6588
6870
|
"div",
|
|
6589
6871
|
{
|
|
6590
6872
|
className: "flex items-center justify-between p-2 bg-muted/50 rounded",
|
|
6591
6873
|
children: [
|
|
6592
|
-
/* @__PURE__ */
|
|
6593
|
-
/* @__PURE__ */
|
|
6594
|
-
key.isActive && /* @__PURE__ */
|
|
6595
|
-
/* @__PURE__ */
|
|
6874
|
+
/* @__PURE__ */ jsxs23("div", { children: [
|
|
6875
|
+
/* @__PURE__ */ jsx27("span", { className: "text-sm font-medium", children: key.label }),
|
|
6876
|
+
key.isActive && /* @__PURE__ */ jsx27("span", { className: "ml-2 text-xs bg-green-500/10 text-green-600 px-1.5 py-0.5 rounded", children: "Active" }),
|
|
6877
|
+
/* @__PURE__ */ jsx27("div", { className: "text-xs text-muted-foreground font-mono", children: key.maskedKey })
|
|
6596
6878
|
] }),
|
|
6597
|
-
/* @__PURE__ */
|
|
6598
|
-
!key.isActive && /* @__PURE__ */
|
|
6879
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex gap-1", children: [
|
|
6880
|
+
!key.isActive && /* @__PURE__ */ jsx27(
|
|
6599
6881
|
Button,
|
|
6600
6882
|
{
|
|
6601
6883
|
size: "sm",
|
|
@@ -6604,13 +6886,13 @@ function SettingsPanel() {
|
|
|
6604
6886
|
children: "Set Active"
|
|
6605
6887
|
}
|
|
6606
6888
|
),
|
|
6607
|
-
/* @__PURE__ */
|
|
6889
|
+
/* @__PURE__ */ jsx27(
|
|
6608
6890
|
Button,
|
|
6609
6891
|
{
|
|
6610
6892
|
size: "icon",
|
|
6611
6893
|
variant: "ghost",
|
|
6612
6894
|
onClick: () => handleDeleteKey(sp.id, key.label),
|
|
6613
|
-
children: /* @__PURE__ */
|
|
6895
|
+
children: /* @__PURE__ */ jsx27(Trash22, { className: "h-3 w-3 text-destructive" })
|
|
6614
6896
|
}
|
|
6615
6897
|
)
|
|
6616
6898
|
] })
|
|
@@ -6618,8 +6900,8 @@ function SettingsPanel() {
|
|
|
6618
6900
|
},
|
|
6619
6901
|
key.label
|
|
6620
6902
|
)),
|
|
6621
|
-
showAddKeyForm === sp.id && /* @__PURE__ */
|
|
6622
|
-
/* @__PURE__ */
|
|
6903
|
+
showAddKeyForm === sp.id && /* @__PURE__ */ jsxs23("div", { className: "p-3 border rounded space-y-2 bg-background", children: [
|
|
6904
|
+
/* @__PURE__ */ jsx27(
|
|
6623
6905
|
Input,
|
|
6624
6906
|
{
|
|
6625
6907
|
placeholder: "Key label (e.g. default, production)",
|
|
@@ -6627,8 +6909,8 @@ function SettingsPanel() {
|
|
|
6627
6909
|
onChange: (e) => setNewKeyLabel(e.target.value)
|
|
6628
6910
|
}
|
|
6629
6911
|
),
|
|
6630
|
-
/* @__PURE__ */
|
|
6631
|
-
/* @__PURE__ */
|
|
6912
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex gap-2", children: [
|
|
6913
|
+
/* @__PURE__ */ jsx27(
|
|
6632
6914
|
Input,
|
|
6633
6915
|
{
|
|
6634
6916
|
type: showNewKeyValue ? "text" : "password",
|
|
@@ -6637,18 +6919,18 @@ function SettingsPanel() {
|
|
|
6637
6919
|
onChange: (e) => setNewKeyValue(e.target.value)
|
|
6638
6920
|
}
|
|
6639
6921
|
),
|
|
6640
|
-
/* @__PURE__ */
|
|
6922
|
+
/* @__PURE__ */ jsx27(
|
|
6641
6923
|
Button,
|
|
6642
6924
|
{
|
|
6643
6925
|
size: "icon",
|
|
6644
6926
|
variant: "ghost",
|
|
6645
6927
|
onClick: () => setShowNewKeyValue(!showNewKeyValue),
|
|
6646
|
-
children: showNewKeyValue ? /* @__PURE__ */
|
|
6928
|
+
children: showNewKeyValue ? /* @__PURE__ */ jsx27(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx27(Eye2, { className: "h-4 w-4" })
|
|
6647
6929
|
}
|
|
6648
6930
|
)
|
|
6649
6931
|
] }),
|
|
6650
|
-
/* @__PURE__ */
|
|
6651
|
-
/* @__PURE__ */
|
|
6932
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex gap-2", children: [
|
|
6933
|
+
/* @__PURE__ */ jsx27(
|
|
6652
6934
|
Button,
|
|
6653
6935
|
{
|
|
6654
6936
|
size: "sm",
|
|
@@ -6657,7 +6939,7 @@ function SettingsPanel() {
|
|
|
6657
6939
|
children: "Save Key"
|
|
6658
6940
|
}
|
|
6659
6941
|
),
|
|
6660
|
-
/* @__PURE__ */
|
|
6942
|
+
/* @__PURE__ */ jsx27(
|
|
6661
6943
|
Button,
|
|
6662
6944
|
{
|
|
6663
6945
|
size: "sm",
|
|
@@ -6676,13 +6958,13 @@ function SettingsPanel() {
|
|
|
6676
6958
|
] }, sp.id))
|
|
6677
6959
|
] })
|
|
6678
6960
|
] }),
|
|
6679
|
-
/* @__PURE__ */
|
|
6680
|
-
/* @__PURE__ */
|
|
6681
|
-
/* @__PURE__ */
|
|
6682
|
-
/* @__PURE__ */
|
|
6683
|
-
/* @__PURE__ */
|
|
6961
|
+
/* @__PURE__ */ jsx27(TabsContent, { value: "model", className: "space-y-4", children: provider ? /* @__PURE__ */ jsxs23(Fragment7, { children: [
|
|
6962
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between", children: [
|
|
6963
|
+
/* @__PURE__ */ jsxs23("div", { children: [
|
|
6964
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm font-medium", children: currentCatalogProvider?.name || provider }),
|
|
6965
|
+
/* @__PURE__ */ jsx27("p", { className: "text-xs text-muted-foreground", children: provider })
|
|
6684
6966
|
] }),
|
|
6685
|
-
/* @__PURE__ */
|
|
6967
|
+
/* @__PURE__ */ jsx27(
|
|
6686
6968
|
Button,
|
|
6687
6969
|
{
|
|
6688
6970
|
variant: "ghost",
|
|
@@ -6691,15 +6973,15 @@ function SettingsPanel() {
|
|
|
6691
6973
|
setIsLoadingModels(true);
|
|
6692
6974
|
ws.listProviderModels?.(provider);
|
|
6693
6975
|
},
|
|
6694
|
-
children: /* @__PURE__ */
|
|
6976
|
+
children: /* @__PURE__ */ jsx27(RefreshCw2, { className: cn("h-4 w-4", isLoadingModels && "animate-spin") })
|
|
6695
6977
|
}
|
|
6696
6978
|
)
|
|
6697
6979
|
] }),
|
|
6698
|
-
isLoadingModels && !catalogModels[provider] ? /* @__PURE__ */
|
|
6699
|
-
/* @__PURE__ */
|
|
6700
|
-
/* @__PURE__ */
|
|
6701
|
-
] }) : /* @__PURE__ */
|
|
6702
|
-
(catalogModels[provider] || []).map((m) => /* @__PURE__ */
|
|
6980
|
+
isLoadingModels && !catalogModels[provider] ? /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-center py-8", children: [
|
|
6981
|
+
/* @__PURE__ */ jsx27(Loader24, { className: "h-6 w-6 animate-spin text-muted-foreground" }),
|
|
6982
|
+
/* @__PURE__ */ jsx27("span", { className: "ml-2 text-muted-foreground", children: "Loading models..." })
|
|
6983
|
+
] }) : /* @__PURE__ */ jsxs23("div", { className: "space-y-1", children: [
|
|
6984
|
+
(catalogModels[provider] || []).map((m) => /* @__PURE__ */ jsxs23(
|
|
6703
6985
|
"button",
|
|
6704
6986
|
{
|
|
6705
6987
|
type: "button",
|
|
@@ -6709,47 +6991,47 @@ function SettingsPanel() {
|
|
|
6709
6991
|
model === m.id ? "border-primary bg-primary/5 ring-2 ring-primary/20" : "border-border hover:bg-muted"
|
|
6710
6992
|
),
|
|
6711
6993
|
children: [
|
|
6712
|
-
/* @__PURE__ */
|
|
6713
|
-
/* @__PURE__ */
|
|
6714
|
-
/* @__PURE__ */
|
|
6994
|
+
/* @__PURE__ */ jsxs23("div", { children: [
|
|
6995
|
+
/* @__PURE__ */ jsx27("span", { className: "font-medium", children: m.name || m.id }),
|
|
6996
|
+
/* @__PURE__ */ jsx27("div", { className: "flex gap-2 mt-1", children: m.capabilities.map((cap) => /* @__PURE__ */ jsx27("span", { className: "text-xs bg-muted px-1.5 py-0.5 rounded", children: cap }, cap)) })
|
|
6715
6997
|
] }),
|
|
6716
|
-
/* @__PURE__ */
|
|
6717
|
-
m.contextWindow && /* @__PURE__ */
|
|
6998
|
+
/* @__PURE__ */ jsxs23("div", { className: "text-right text-xs text-muted-foreground", children: [
|
|
6999
|
+
m.contextWindow && /* @__PURE__ */ jsxs23("div", { children: [
|
|
6718
7000
|
m.contextWindow / 1e3,
|
|
6719
7001
|
"k context"
|
|
6720
7002
|
] }),
|
|
6721
|
-
m.inputCost && m.outputCost && /* @__PURE__ */
|
|
7003
|
+
m.inputCost && m.outputCost && /* @__PURE__ */ jsxs23("div", { children: [
|
|
6722
7004
|
"$",
|
|
6723
7005
|
m.inputCost,
|
|
6724
7006
|
"/$",
|
|
6725
7007
|
m.outputCost
|
|
6726
7008
|
] }),
|
|
6727
|
-
model === m.id && /* @__PURE__ */
|
|
7009
|
+
model === m.id && /* @__PURE__ */ jsx27(CheckCircle24, { className: "h-4 w-4 text-primary mt-1" })
|
|
6728
7010
|
] })
|
|
6729
7011
|
]
|
|
6730
7012
|
},
|
|
6731
7013
|
m.id
|
|
6732
7014
|
)),
|
|
6733
|
-
catalogModels[provider]?.length === 0 && /* @__PURE__ */
|
|
7015
|
+
catalogModels[provider]?.length === 0 && /* @__PURE__ */ jsx27("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." })
|
|
6734
7016
|
] })
|
|
6735
|
-
] }) : /* @__PURE__ */
|
|
6736
|
-
/* @__PURE__ */
|
|
6737
|
-
/* @__PURE__ */
|
|
7017
|
+
] }) : /* @__PURE__ */ jsxs23("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
7018
|
+
/* @__PURE__ */ jsx27(Cpu4, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
|
|
7019
|
+
/* @__PURE__ */ jsx27("p", { children: "Select a provider first" })
|
|
6738
7020
|
] }) }),
|
|
6739
|
-
/* @__PURE__ */
|
|
6740
|
-
/* @__PURE__ */
|
|
6741
|
-
/* @__PURE__ */
|
|
7021
|
+
/* @__PURE__ */ jsxs23(TabsContent, { value: "connection", className: "space-y-4", children: [
|
|
7022
|
+
/* @__PURE__ */ jsxs23("div", { className: "space-y-3", children: [
|
|
7023
|
+
/* @__PURE__ */ jsxs23(
|
|
6742
7024
|
"label",
|
|
6743
7025
|
{
|
|
6744
7026
|
htmlFor: "websocket-url",
|
|
6745
7027
|
className: "text-sm font-medium flex items-center gap-2",
|
|
6746
7028
|
children: [
|
|
6747
|
-
/* @__PURE__ */
|
|
7029
|
+
/* @__PURE__ */ jsx27(Globe2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
6748
7030
|
"WebSocket Server URL"
|
|
6749
7031
|
]
|
|
6750
7032
|
}
|
|
6751
7033
|
),
|
|
6752
|
-
/* @__PURE__ */
|
|
7034
|
+
/* @__PURE__ */ jsx27(
|
|
6753
7035
|
Input,
|
|
6754
7036
|
{
|
|
6755
7037
|
id: "websocket-url",
|
|
@@ -6759,70 +7041,70 @@ function SettingsPanel() {
|
|
|
6759
7041
|
className: "font-mono text-sm"
|
|
6760
7042
|
}
|
|
6761
7043
|
),
|
|
6762
|
-
/* @__PURE__ */
|
|
7044
|
+
/* @__PURE__ */ jsx27("p", { className: "text-xs text-muted-foreground", children: "URL of the WrongStack WebSocket server. The server runs alongside the CLI." })
|
|
6763
7045
|
] }),
|
|
6764
|
-
/* @__PURE__ */
|
|
6765
|
-
/* @__PURE__ */
|
|
6766
|
-
/* @__PURE__ */
|
|
7046
|
+
/* @__PURE__ */ jsxs23("div", { className: "p-4 rounded-lg border bg-muted/50", children: [
|
|
7047
|
+
/* @__PURE__ */ jsx27("h4", { className: "text-sm font-medium mb-2", children: "Starting the WebSocket Server" }),
|
|
7048
|
+
/* @__PURE__ */ jsxs23("p", { className: "text-xs text-muted-foreground mb-3", children: [
|
|
6767
7049
|
"Standalone: run ",
|
|
6768
|
-
/* @__PURE__ */
|
|
7050
|
+
/* @__PURE__ */ jsx27("code", { className: "bg-muted px-1 py-0.5 rounded", children: "./dev.ps1" }),
|
|
6769
7051
|
" ",
|
|
6770
7052
|
"from the repo root, or set WS_HOST/WS_PORT before launching",
|
|
6771
7053
|
" ",
|
|
6772
|
-
/* @__PURE__ */
|
|
7054
|
+
/* @__PURE__ */ jsx27("code", { className: "bg-muted px-1 py-0.5 rounded", children: "node packages/webui/dist/server/entry.js" }),
|
|
6773
7055
|
". Or alongside the CLI:",
|
|
6774
7056
|
" ",
|
|
6775
|
-
/* @__PURE__ */
|
|
7057
|
+
/* @__PURE__ */ jsx27("code", { className: "bg-muted px-1 py-0.5 rounded", children: "wstack --webui" }),
|
|
6776
7058
|
"."
|
|
6777
7059
|
] })
|
|
6778
7060
|
] })
|
|
6779
7061
|
] }),
|
|
6780
|
-
/* @__PURE__ */
|
|
6781
|
-
/* @__PURE__ */
|
|
6782
|
-
/* @__PURE__ */
|
|
6783
|
-
/* @__PURE__ */
|
|
6784
|
-
/* @__PURE__ */
|
|
7062
|
+
/* @__PURE__ */ jsxs23(TabsContent, { value: "appearance", className: "space-y-4", children: [
|
|
7063
|
+
/* @__PURE__ */ jsxs23("div", { children: [
|
|
7064
|
+
/* @__PURE__ */ jsx27("h3", { className: "text-sm font-semibold mb-3", children: "Theme" }),
|
|
7065
|
+
/* @__PURE__ */ jsxs23("div", { className: "grid grid-cols-3 gap-2 max-w-md", children: [
|
|
7066
|
+
/* @__PURE__ */ jsxs23(
|
|
6785
7067
|
Button,
|
|
6786
7068
|
{
|
|
6787
7069
|
variant: theme === "light" ? "default" : "outline",
|
|
6788
7070
|
size: "sm",
|
|
6789
7071
|
onClick: () => setTheme("light"),
|
|
6790
7072
|
children: [
|
|
6791
|
-
/* @__PURE__ */
|
|
7073
|
+
/* @__PURE__ */ jsx27(Sun3, { className: "h-4 w-4 mr-1" }),
|
|
6792
7074
|
"Light"
|
|
6793
7075
|
]
|
|
6794
7076
|
}
|
|
6795
7077
|
),
|
|
6796
|
-
/* @__PURE__ */
|
|
7078
|
+
/* @__PURE__ */ jsxs23(
|
|
6797
7079
|
Button,
|
|
6798
7080
|
{
|
|
6799
7081
|
variant: theme === "dark" ? "default" : "outline",
|
|
6800
7082
|
size: "sm",
|
|
6801
7083
|
onClick: () => setTheme("dark"),
|
|
6802
7084
|
children: [
|
|
6803
|
-
/* @__PURE__ */
|
|
7085
|
+
/* @__PURE__ */ jsx27(Moon3, { className: "h-4 w-4 mr-1" }),
|
|
6804
7086
|
"Dark"
|
|
6805
7087
|
]
|
|
6806
7088
|
}
|
|
6807
7089
|
),
|
|
6808
|
-
/* @__PURE__ */
|
|
7090
|
+
/* @__PURE__ */ jsxs23(
|
|
6809
7091
|
Button,
|
|
6810
7092
|
{
|
|
6811
7093
|
variant: theme === "system" ? "default" : "outline",
|
|
6812
7094
|
size: "sm",
|
|
6813
7095
|
onClick: () => setTheme("system"),
|
|
6814
7096
|
children: [
|
|
6815
|
-
/* @__PURE__ */
|
|
7097
|
+
/* @__PURE__ */ jsx27(Monitor3, { className: "h-4 w-4 mr-1" }),
|
|
6816
7098
|
"System"
|
|
6817
7099
|
]
|
|
6818
7100
|
}
|
|
6819
7101
|
)
|
|
6820
7102
|
] }),
|
|
6821
|
-
/* @__PURE__ */
|
|
7103
|
+
/* @__PURE__ */ jsx27("p", { className: "text-xs text-muted-foreground mt-2", children: "System follows your OS-level light/dark preference." })
|
|
6822
7104
|
] }),
|
|
6823
|
-
/* @__PURE__ */
|
|
6824
|
-
/* @__PURE__ */
|
|
6825
|
-
/* @__PURE__ */
|
|
7105
|
+
/* @__PURE__ */ jsxs23("div", { className: "pt-2 border-t", children: [
|
|
7106
|
+
/* @__PURE__ */ jsx27("h3", { className: "text-sm font-semibold mb-3 mt-3", children: "Preferences" }),
|
|
7107
|
+
/* @__PURE__ */ jsx27(
|
|
6826
7108
|
PreferenceToggle,
|
|
6827
7109
|
{
|
|
6828
7110
|
label: "Compact density",
|
|
@@ -6831,7 +7113,7 @@ function SettingsPanel() {
|
|
|
6831
7113
|
onChange: () => useUIStore.getState().toggleCompactMode()
|
|
6832
7114
|
}
|
|
6833
7115
|
),
|
|
6834
|
-
/* @__PURE__ */
|
|
7116
|
+
/* @__PURE__ */ jsx27(
|
|
6835
7117
|
PreferenceToggle,
|
|
6836
7118
|
{
|
|
6837
7119
|
label: "Sound on completion",
|
|
@@ -6865,12 +7147,12 @@ function PreferenceToggle({
|
|
|
6865
7147
|
}
|
|
6866
7148
|
}
|
|
6867
7149
|
};
|
|
6868
|
-
return /* @__PURE__ */
|
|
6869
|
-
/* @__PURE__ */
|
|
6870
|
-
/* @__PURE__ */
|
|
6871
|
-
hint && /* @__PURE__ */
|
|
7150
|
+
return /* @__PURE__ */ jsxs23("div", { className: "flex items-start justify-between gap-3 py-2", children: [
|
|
7151
|
+
/* @__PURE__ */ jsxs23("div", { className: "min-w-0 flex-1", children: [
|
|
7152
|
+
/* @__PURE__ */ jsx27("div", { className: "text-sm font-medium", children: label }),
|
|
7153
|
+
hint && /* @__PURE__ */ jsx27("div", { className: "text-xs text-muted-foreground mt-0.5", children: hint })
|
|
6872
7154
|
] }),
|
|
6873
|
-
/* @__PURE__ */
|
|
7155
|
+
/* @__PURE__ */ jsx27(
|
|
6874
7156
|
"button",
|
|
6875
7157
|
{
|
|
6876
7158
|
type: "button",
|
|
@@ -6881,7 +7163,7 @@ function PreferenceToggle({
|
|
|
6881
7163
|
"shrink-0 relative inline-flex h-5 w-9 rounded-full border transition-colors",
|
|
6882
7164
|
on ? "bg-primary border-primary" : "bg-muted border-input hover:bg-muted/80"
|
|
6883
7165
|
),
|
|
6884
|
-
children: /* @__PURE__ */
|
|
7166
|
+
children: /* @__PURE__ */ jsx27(
|
|
6885
7167
|
"span",
|
|
6886
7168
|
{
|
|
6887
7169
|
className: cn(
|
|
@@ -6897,8 +7179,8 @@ function PreferenceToggle({
|
|
|
6897
7179
|
|
|
6898
7180
|
// src/components/ShortcutsOverlay.tsx
|
|
6899
7181
|
import { Keyboard as Keyboard2, X as X6 } from "lucide-react";
|
|
6900
|
-
import { useEffect as
|
|
6901
|
-
import { jsx as
|
|
7182
|
+
import { useEffect as useEffect19 } from "react";
|
|
7183
|
+
import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
6902
7184
|
var SHORTCUTS = [
|
|
6903
7185
|
{
|
|
6904
7186
|
section: "Global",
|
|
@@ -6948,7 +7230,7 @@ var SHORTCUTS = [
|
|
|
6948
7230
|
function ShortcutsOverlay() {
|
|
6949
7231
|
const open = useUIStore((s) => s.shortcutsOpen);
|
|
6950
7232
|
const setOpen = useUIStore((s) => s.setShortcutsOpen);
|
|
6951
|
-
|
|
7233
|
+
useEffect19(() => {
|
|
6952
7234
|
const onKey = (e) => {
|
|
6953
7235
|
const target = e.target;
|
|
6954
7236
|
const tag = target?.tagName?.toLowerCase();
|
|
@@ -6967,7 +7249,7 @@ function ShortcutsOverlay() {
|
|
|
6967
7249
|
return () => window.removeEventListener("keydown", onKey);
|
|
6968
7250
|
}, [setOpen]);
|
|
6969
7251
|
if (!open) return null;
|
|
6970
|
-
return /* @__PURE__ */
|
|
7252
|
+
return /* @__PURE__ */ jsx28(
|
|
6971
7253
|
"div",
|
|
6972
7254
|
{
|
|
6973
7255
|
className: "fixed inset-0 z-50 bg-background/60 backdrop-blur-sm flex items-center justify-center px-4",
|
|
@@ -6975,49 +7257,49 @@ function ShortcutsOverlay() {
|
|
|
6975
7257
|
onKeyDown: (e) => {
|
|
6976
7258
|
if (e.key === "Escape") setOpen(false);
|
|
6977
7259
|
},
|
|
6978
|
-
children: /* @__PURE__ */
|
|
7260
|
+
children: /* @__PURE__ */ jsxs24(
|
|
6979
7261
|
"div",
|
|
6980
7262
|
{
|
|
6981
7263
|
onClick: (e) => e.stopPropagation(),
|
|
6982
7264
|
onKeyDown: (e) => e.stopPropagation(),
|
|
6983
7265
|
className: "w-full max-w-2xl rounded-xl border bg-popover shadow-2xl overflow-hidden flex flex-col max-h-[80vh]",
|
|
6984
7266
|
children: [
|
|
6985
|
-
/* @__PURE__ */
|
|
6986
|
-
/* @__PURE__ */
|
|
6987
|
-
/* @__PURE__ */
|
|
6988
|
-
/* @__PURE__ */
|
|
7267
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-between px-5 py-4 border-b", children: [
|
|
7268
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-2", children: [
|
|
7269
|
+
/* @__PURE__ */ jsx28(Keyboard2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7270
|
+
/* @__PURE__ */ jsx28("h2", { className: "text-sm font-semibold", children: "Keyboard shortcuts" })
|
|
6989
7271
|
] }),
|
|
6990
|
-
/* @__PURE__ */
|
|
7272
|
+
/* @__PURE__ */ jsx28(
|
|
6991
7273
|
"button",
|
|
6992
7274
|
{
|
|
6993
7275
|
type: "button",
|
|
6994
7276
|
onClick: () => setOpen(false),
|
|
6995
7277
|
className: "text-muted-foreground hover:text-foreground p-1 rounded hover:bg-muted",
|
|
6996
|
-
children: /* @__PURE__ */
|
|
7278
|
+
children: /* @__PURE__ */ jsx28(X6, { className: "h-4 w-4" })
|
|
6997
7279
|
}
|
|
6998
7280
|
)
|
|
6999
7281
|
] }),
|
|
7000
|
-
/* @__PURE__ */
|
|
7001
|
-
/* @__PURE__ */
|
|
7002
|
-
/* @__PURE__ */
|
|
7282
|
+
/* @__PURE__ */ jsx28("div", { className: "overflow-y-auto px-5 py-4 space-y-6", children: SHORTCUTS.map((group) => /* @__PURE__ */ jsxs24("div", { children: [
|
|
7283
|
+
/* @__PURE__ */ jsx28("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground mb-2", children: group.section }),
|
|
7284
|
+
/* @__PURE__ */ jsx28("div", { className: "grid grid-cols-1 gap-1.5", children: group.items.map((s) => /* @__PURE__ */ jsxs24(
|
|
7003
7285
|
"div",
|
|
7004
7286
|
{
|
|
7005
7287
|
className: "flex items-center justify-between gap-3 text-sm px-2 py-1.5 rounded hover:bg-muted/40",
|
|
7006
7288
|
children: [
|
|
7007
|
-
/* @__PURE__ */
|
|
7008
|
-
/* @__PURE__ */
|
|
7009
|
-
ki > 0 && /* @__PURE__ */
|
|
7010
|
-
/* @__PURE__ */
|
|
7289
|
+
/* @__PURE__ */ jsx28("span", { className: "text-foreground/80", children: s.description }),
|
|
7290
|
+
/* @__PURE__ */ jsx28("span", { className: "flex items-center gap-1 shrink-0", children: s.keys.map((k, ki) => /* @__PURE__ */ jsxs24("span", { className: "flex items-center gap-1", children: [
|
|
7291
|
+
ki > 0 && /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground/40 text-xs", children: "+" }),
|
|
7292
|
+
/* @__PURE__ */ jsx28("kbd", { className: "font-mono text-[10px] border rounded px-1.5 py-0.5 bg-background", children: k })
|
|
7011
7293
|
] }, k)) })
|
|
7012
7294
|
]
|
|
7013
7295
|
},
|
|
7014
7296
|
s.description
|
|
7015
7297
|
)) })
|
|
7016
7298
|
] }, group.section)) }),
|
|
7017
|
-
/* @__PURE__ */
|
|
7299
|
+
/* @__PURE__ */ jsxs24("div", { className: "border-t px-5 py-3 text-xs text-muted-foreground", children: [
|
|
7018
7300
|
"Press",
|
|
7019
7301
|
" ",
|
|
7020
|
-
/* @__PURE__ */
|
|
7302
|
+
/* @__PURE__ */ jsx28("kbd", { className: "font-mono text-[10px] border rounded px-1 py-0.5 bg-background", children: "?" }),
|
|
7021
7303
|
" ",
|
|
7022
7304
|
"any time to reopen this list."
|
|
7023
7305
|
] })
|
|
@@ -7046,13 +7328,13 @@ import {
|
|
|
7046
7328
|
Settings as SettingsIcon2,
|
|
7047
7329
|
Star,
|
|
7048
7330
|
Trash2 as Trash23,
|
|
7049
|
-
Wifi as
|
|
7050
|
-
WifiOff as
|
|
7331
|
+
Wifi as Wifi2,
|
|
7332
|
+
WifiOff as WifiOff3,
|
|
7051
7333
|
X as X7,
|
|
7052
7334
|
Zap as Zap3
|
|
7053
7335
|
} from "lucide-react";
|
|
7054
|
-
import { useEffect as
|
|
7055
|
-
import { Fragment as Fragment8, jsx as
|
|
7336
|
+
import { useEffect as useEffect20, useState as useState19 } from "react";
|
|
7337
|
+
import { Fragment as Fragment8, jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
7056
7338
|
function Sidebar() {
|
|
7057
7339
|
const { toggleSidebar, currentView, setCurrentView } = useUIStore();
|
|
7058
7340
|
const sidebarWidth = useUIStore((s) => s.sidebarWidth);
|
|
@@ -7061,13 +7343,13 @@ function Sidebar() {
|
|
|
7061
7343
|
const { messages, clearMessages } = useChatStore();
|
|
7062
7344
|
const pinnedIds = useUIStore((s) => s.pinnedIds);
|
|
7063
7345
|
const unpinAll = useUIStore((s) => s.unpinAll);
|
|
7064
|
-
const [historyQuery, setHistoryQuery] =
|
|
7346
|
+
const [historyQuery, setHistoryQuery] = useState19("");
|
|
7065
7347
|
const favoriteSessionIds = useUIStore((s) => s.favoriteSessionIds);
|
|
7066
7348
|
const toggleFavoriteSession = useUIStore((s) => s.toggleFavoriteSession);
|
|
7067
7349
|
const sessionNicknames = useUIStore((s) => s.sessionNicknames);
|
|
7068
7350
|
const setSessionNickname = useUIStore((s) => s.setSessionNickname);
|
|
7069
|
-
const [renamingId, setRenamingId] =
|
|
7070
|
-
const [renameDraft, setRenameDraft] =
|
|
7351
|
+
const [renamingId, setRenamingId] = useState19(null);
|
|
7352
|
+
const [renameDraft, setRenameDraft] = useState19("");
|
|
7071
7353
|
const pinnedRows = pinnedIds.map((id) => messages.find((m) => m.id === id)).filter((m) => !!m && m.content.length > 0);
|
|
7072
7354
|
const { wsConnected, wsUrl, provider, model } = useConfigStore();
|
|
7073
7355
|
const {
|
|
@@ -7076,11 +7358,11 @@ function Sidebar() {
|
|
|
7076
7358
|
error: historyError
|
|
7077
7359
|
} = useHistoryStore();
|
|
7078
7360
|
const { listSessions, deleteSession, resumeSession, client: client2 } = useWebSocket();
|
|
7079
|
-
|
|
7361
|
+
useEffect20(() => {
|
|
7080
7362
|
if (wsConnected) client2?.getTodos?.();
|
|
7081
7363
|
}, [wsConnected, client2]);
|
|
7082
7364
|
const activeSessionId = session?.id;
|
|
7083
|
-
|
|
7365
|
+
useEffect20(() => {
|
|
7084
7366
|
void activeSessionId;
|
|
7085
7367
|
if (currentView === "history" && wsConnected) {
|
|
7086
7368
|
listSessions(50);
|
|
@@ -7164,13 +7446,13 @@ function Sidebar() {
|
|
|
7164
7446
|
document.body.style.cursor = "col-resize";
|
|
7165
7447
|
document.body.style.userSelect = "none";
|
|
7166
7448
|
};
|
|
7167
|
-
return /* @__PURE__ */
|
|
7449
|
+
return /* @__PURE__ */ jsxs25(
|
|
7168
7450
|
"aside",
|
|
7169
7451
|
{
|
|
7170
7452
|
style: { width: `${sidebarWidth}px` },
|
|
7171
7453
|
className: "relative border-r bg-card flex flex-col shrink-0",
|
|
7172
7454
|
children: [
|
|
7173
|
-
/* @__PURE__ */
|
|
7455
|
+
/* @__PURE__ */ jsxs25(
|
|
7174
7456
|
"div",
|
|
7175
7457
|
{
|
|
7176
7458
|
onMouseDown: startDrag,
|
|
@@ -7178,56 +7460,56 @@ function Sidebar() {
|
|
|
7178
7460
|
className: "group/handle absolute top-0 right-0 h-full w-2 cursor-col-resize z-10 flex items-center justify-end",
|
|
7179
7461
|
title: "Drag to resize \xB7 double-click to reset",
|
|
7180
7462
|
children: [
|
|
7181
|
-
/* @__PURE__ */
|
|
7182
|
-
/* @__PURE__ */
|
|
7183
|
-
/* @__PURE__ */
|
|
7184
|
-
/* @__PURE__ */
|
|
7185
|
-
/* @__PURE__ */
|
|
7463
|
+
/* @__PURE__ */ jsx29("div", { className: "h-full w-px bg-border group-hover/handle:bg-primary/60 group-hover/handle:w-0.5 transition-all" }),
|
|
7464
|
+
/* @__PURE__ */ jsxs25("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: [
|
|
7465
|
+
/* @__PURE__ */ jsx29("span", { className: "h-1 w-1 rounded-full bg-primary/70" }),
|
|
7466
|
+
/* @__PURE__ */ jsx29("span", { className: "h-1 w-1 rounded-full bg-primary/70" }),
|
|
7467
|
+
/* @__PURE__ */ jsx29("span", { className: "h-1 w-1 rounded-full bg-primary/70" })
|
|
7186
7468
|
] })
|
|
7187
7469
|
]
|
|
7188
7470
|
}
|
|
7189
7471
|
),
|
|
7190
|
-
/* @__PURE__ */
|
|
7191
|
-
/* @__PURE__ */
|
|
7192
|
-
/* @__PURE__ */
|
|
7193
|
-
/* @__PURE__ */
|
|
7472
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between px-4 py-3 border-b", children: [
|
|
7473
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2", children: [
|
|
7474
|
+
/* @__PURE__ */ jsx29("div", { className: "w-6 h-6 rounded bg-primary flex items-center justify-center", children: /* @__PURE__ */ jsx29(Zap3, { className: "h-4 w-4 text-primary-foreground" }) }),
|
|
7475
|
+
/* @__PURE__ */ jsx29("span", { className: "text-sm font-semibold tracking-tight", children: "WrongStack" })
|
|
7194
7476
|
] }),
|
|
7195
|
-
/* @__PURE__ */
|
|
7477
|
+
/* @__PURE__ */ jsx29(Button, { variant: "ghost", size: "icon", onClick: toggleSidebar, children: /* @__PURE__ */ jsx29(PanelLeftClose, { className: "h-4 w-4" }) })
|
|
7196
7478
|
] }),
|
|
7197
|
-
/* @__PURE__ */
|
|
7479
|
+
/* @__PURE__ */ jsxs25(
|
|
7198
7480
|
Tabs,
|
|
7199
7481
|
{
|
|
7200
7482
|
value: currentView === "settings" ? "chat" : currentView,
|
|
7201
7483
|
onValueChange: (v) => setCurrentView(v),
|
|
7202
7484
|
className: "flex-1 flex flex-col",
|
|
7203
7485
|
children: [
|
|
7204
|
-
/* @__PURE__ */
|
|
7205
|
-
/* @__PURE__ */
|
|
7486
|
+
/* @__PURE__ */ jsxs25(TabsList, { className: "w-full rounded-none bg-transparent p-2 h-auto grid grid-cols-2", children: [
|
|
7487
|
+
/* @__PURE__ */ jsxs25(
|
|
7206
7488
|
TabsTrigger,
|
|
7207
7489
|
{
|
|
7208
7490
|
value: "chat",
|
|
7209
7491
|
className: "flex-col gap-1.5 py-2 data-[state=active]:bg-primary/10",
|
|
7210
7492
|
children: [
|
|
7211
|
-
/* @__PURE__ */
|
|
7212
|
-
/* @__PURE__ */
|
|
7493
|
+
/* @__PURE__ */ jsx29(MessageSquare, { className: "h-4 w-4" }),
|
|
7494
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xs", children: "Chat" })
|
|
7213
7495
|
]
|
|
7214
7496
|
}
|
|
7215
7497
|
),
|
|
7216
|
-
/* @__PURE__ */
|
|
7498
|
+
/* @__PURE__ */ jsxs25(
|
|
7217
7499
|
TabsTrigger,
|
|
7218
7500
|
{
|
|
7219
7501
|
value: "history",
|
|
7220
7502
|
className: "flex-col gap-1.5 py-2 data-[state=active]:bg-primary/10",
|
|
7221
7503
|
children: [
|
|
7222
|
-
/* @__PURE__ */
|
|
7223
|
-
/* @__PURE__ */
|
|
7504
|
+
/* @__PURE__ */ jsx29(History, { className: "h-4 w-4" }),
|
|
7505
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xs", children: "History" })
|
|
7224
7506
|
]
|
|
7225
7507
|
}
|
|
7226
7508
|
)
|
|
7227
7509
|
] }),
|
|
7228
|
-
/* @__PURE__ */
|
|
7229
|
-
/* @__PURE__ */
|
|
7230
|
-
/* @__PURE__ */
|
|
7510
|
+
/* @__PURE__ */ jsxs25(TabsContent, { value: "chat", className: "flex-1 flex flex-col m-0 overflow-hidden", children: [
|
|
7511
|
+
/* @__PURE__ */ jsxs25("div", { className: "px-4 py-3 border-b", children: [
|
|
7512
|
+
/* @__PURE__ */ jsxs25(
|
|
7231
7513
|
"div",
|
|
7232
7514
|
{
|
|
7233
7515
|
className: cn(
|
|
@@ -7235,95 +7517,95 @@ function Sidebar() {
|
|
|
7235
7517
|
wsConnected ? "bg-green-500/10 text-green-600 dark:text-green-400" : "bg-yellow-500/10 text-yellow-600 dark:text-yellow-400"
|
|
7236
7518
|
),
|
|
7237
7519
|
children: [
|
|
7238
|
-
wsConnected ? /* @__PURE__ */
|
|
7239
|
-
/* @__PURE__ */
|
|
7520
|
+
wsConnected ? /* @__PURE__ */ jsx29(Wifi2, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx29(WifiOff3, { className: "h-4 w-4" }),
|
|
7521
|
+
/* @__PURE__ */ jsx29("span", { className: "font-medium", children: wsConnected ? "Connected" : "Disconnected" })
|
|
7240
7522
|
]
|
|
7241
7523
|
}
|
|
7242
7524
|
),
|
|
7243
|
-
/* @__PURE__ */
|
|
7525
|
+
/* @__PURE__ */ jsx29("div", { className: "text-xs text-muted-foreground mt-2 px-1 font-mono", children: wsUrl })
|
|
7244
7526
|
] }),
|
|
7245
|
-
/* @__PURE__ */
|
|
7527
|
+
/* @__PURE__ */ jsxs25(
|
|
7246
7528
|
"button",
|
|
7247
7529
|
{
|
|
7248
7530
|
type: "button",
|
|
7249
7531
|
onClick: () => setCurrentView("settings"),
|
|
7250
7532
|
className: "px-4 py-3 border-b text-left hover:bg-muted/40 transition-colors",
|
|
7251
7533
|
children: [
|
|
7252
|
-
/* @__PURE__ */
|
|
7253
|
-
/* @__PURE__ */
|
|
7254
|
-
/* @__PURE__ */
|
|
7255
|
-
/* @__PURE__ */
|
|
7256
|
-
/* @__PURE__ */
|
|
7534
|
+
/* @__PURE__ */ jsx29("div", { className: "text-[10px] uppercase tracking-wider text-muted-foreground mb-1", children: "Active model" }),
|
|
7535
|
+
/* @__PURE__ */ jsxs25("div", { className: "font-mono text-xs truncate", children: [
|
|
7536
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: provider || "\u2014" }),
|
|
7537
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground/40 mx-1", children: "/" }),
|
|
7538
|
+
/* @__PURE__ */ jsx29("span", { className: "font-medium", children: model || "\u2014" })
|
|
7257
7539
|
] })
|
|
7258
7540
|
]
|
|
7259
7541
|
}
|
|
7260
7542
|
),
|
|
7261
|
-
/* @__PURE__ */
|
|
7262
|
-
/* @__PURE__ */
|
|
7263
|
-
/* @__PURE__ */
|
|
7543
|
+
/* @__PURE__ */ jsxs25("div", { className: "px-4 py-3 border-b space-y-3", children: [
|
|
7544
|
+
/* @__PURE__ */ jsxs25("h3", { className: "text-sm font-medium flex items-center gap-2", children: [
|
|
7545
|
+
/* @__PURE__ */ jsx29(Database2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7264
7546
|
"Session"
|
|
7265
7547
|
] }),
|
|
7266
|
-
/* @__PURE__ */
|
|
7267
|
-
/* @__PURE__ */
|
|
7268
|
-
/* @__PURE__ */
|
|
7269
|
-
/* @__PURE__ */
|
|
7548
|
+
/* @__PURE__ */ jsxs25("div", { className: "grid grid-cols-2 gap-2 text-xs", children: [
|
|
7549
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7550
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "Messages" }),
|
|
7551
|
+
/* @__PURE__ */ jsx29("span", { className: "text-lg font-semibold", children: messages.length })
|
|
7270
7552
|
] }),
|
|
7271
|
-
/* @__PURE__ */
|
|
7272
|
-
/* @__PURE__ */
|
|
7273
|
-
/* @__PURE__ */
|
|
7553
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7554
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "Duration" }),
|
|
7555
|
+
/* @__PURE__ */ jsx29("span", { className: "text-lg font-semibold", children: formatDuration2(session?.startedAt ?? null) })
|
|
7274
7556
|
] }),
|
|
7275
|
-
/* @__PURE__ */
|
|
7276
|
-
/* @__PURE__ */
|
|
7277
|
-
/* @__PURE__ */
|
|
7557
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7558
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "Input" }),
|
|
7559
|
+
/* @__PURE__ */ jsx29("span", { className: "text-lg font-semibold", children: totalTokens.input.toLocaleString() })
|
|
7278
7560
|
] }),
|
|
7279
|
-
/* @__PURE__ */
|
|
7280
|
-
/* @__PURE__ */
|
|
7281
|
-
/* @__PURE__ */
|
|
7561
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex flex-col p-2 rounded-lg bg-muted/50", children: [
|
|
7562
|
+
/* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "Output" }),
|
|
7563
|
+
/* @__PURE__ */ jsx29("span", { className: "text-lg font-semibold", children: totalTokens.output.toLocaleString() })
|
|
7282
7564
|
] })
|
|
7283
7565
|
] }),
|
|
7284
|
-
cost > 0 && /* @__PURE__ */
|
|
7285
|
-
/* @__PURE__ */
|
|
7286
|
-
/* @__PURE__ */
|
|
7566
|
+
cost > 0 && /* @__PURE__ */ jsxs25("div", { className: "flex justify-between items-center p-2 rounded-lg bg-green-500/10", children: [
|
|
7567
|
+
/* @__PURE__ */ jsx29("span", { className: "text-sm text-muted-foreground", children: "Cost" }),
|
|
7568
|
+
/* @__PURE__ */ jsxs25("span", { className: "text-lg font-semibold text-green-600 dark:text-green-400", children: [
|
|
7287
7569
|
"$",
|
|
7288
7570
|
cost.toFixed(4)
|
|
7289
7571
|
] })
|
|
7290
7572
|
] })
|
|
7291
7573
|
] }),
|
|
7292
|
-
todos.length > 0 && /* @__PURE__ */
|
|
7293
|
-
/* @__PURE__ */
|
|
7294
|
-
/* @__PURE__ */
|
|
7295
|
-
/* @__PURE__ */
|
|
7574
|
+
todos.length > 0 && /* @__PURE__ */ jsxs25("div", { className: "px-4 py-3 border-b space-y-2", children: [
|
|
7575
|
+
/* @__PURE__ */ jsxs25("h3", { className: "text-sm font-medium flex items-center justify-between", children: [
|
|
7576
|
+
/* @__PURE__ */ jsxs25("span", { className: "flex items-center gap-2", children: [
|
|
7577
|
+
/* @__PURE__ */ jsx29(ListTodo, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7296
7578
|
"Todos"
|
|
7297
7579
|
] }),
|
|
7298
|
-
/* @__PURE__ */
|
|
7580
|
+
/* @__PURE__ */ jsxs25("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
|
|
7299
7581
|
todos.filter((t) => t.status === "completed").length,
|
|
7300
7582
|
"/",
|
|
7301
7583
|
todos.length
|
|
7302
7584
|
] })
|
|
7303
7585
|
] }),
|
|
7304
|
-
/* @__PURE__ */
|
|
7586
|
+
/* @__PURE__ */ jsx29("ul", { className: "space-y-1 max-h-48 overflow-y-auto pr-1", children: todos.map((t) => {
|
|
7305
7587
|
const Icon2 = t.status === "completed" ? CheckCircle25 : t.status === "in_progress" ? CircleDot : Circle;
|
|
7306
7588
|
const tone2 = t.status === "completed" ? "text-green-600 dark:text-green-400 line-through opacity-70" : t.status === "in_progress" ? "text-amber-600 dark:text-amber-400" : "text-muted-foreground";
|
|
7307
|
-
return /* @__PURE__ */
|
|
7589
|
+
return /* @__PURE__ */ jsxs25(
|
|
7308
7590
|
"li",
|
|
7309
7591
|
{
|
|
7310
7592
|
className: cn("flex items-start gap-2 text-xs leading-snug", tone2),
|
|
7311
7593
|
children: [
|
|
7312
|
-
/* @__PURE__ */
|
|
7313
|
-
/* @__PURE__ */
|
|
7594
|
+
/* @__PURE__ */ jsx29(Icon2, { className: "h-3.5 w-3.5 mt-0.5 shrink-0" }),
|
|
7595
|
+
/* @__PURE__ */ jsx29("span", { className: "break-words", children: t.status === "in_progress" && t.activeForm ? t.activeForm : t.content })
|
|
7314
7596
|
]
|
|
7315
7597
|
},
|
|
7316
7598
|
t.id
|
|
7317
7599
|
);
|
|
7318
7600
|
}) })
|
|
7319
7601
|
] }),
|
|
7320
|
-
pinnedRows.length > 0 && /* @__PURE__ */
|
|
7321
|
-
/* @__PURE__ */
|
|
7322
|
-
/* @__PURE__ */
|
|
7323
|
-
/* @__PURE__ */
|
|
7602
|
+
pinnedRows.length > 0 && /* @__PURE__ */ jsxs25("div", { className: "px-4 py-3 border-b space-y-2", children: [
|
|
7603
|
+
/* @__PURE__ */ jsxs25("h3", { className: "text-sm font-medium flex items-center justify-between", children: [
|
|
7604
|
+
/* @__PURE__ */ jsxs25("span", { className: "flex items-center gap-2", children: [
|
|
7605
|
+
/* @__PURE__ */ jsx29(Pin2, { className: "h-4 w-4 text-amber-500" }),
|
|
7324
7606
|
"Pinned"
|
|
7325
7607
|
] }),
|
|
7326
|
-
/* @__PURE__ */
|
|
7608
|
+
/* @__PURE__ */ jsx29(
|
|
7327
7609
|
"button",
|
|
7328
7610
|
{
|
|
7329
7611
|
type: "button",
|
|
@@ -7333,9 +7615,9 @@ function Sidebar() {
|
|
|
7333
7615
|
}
|
|
7334
7616
|
)
|
|
7335
7617
|
] }),
|
|
7336
|
-
/* @__PURE__ */
|
|
7618
|
+
/* @__PURE__ */ jsx29("ul", { className: "space-y-1 max-h-48 overflow-y-auto pr-1", children: pinnedRows.map((m) => {
|
|
7337
7619
|
const preview = m.content.replace(/\s+/g, " ").slice(0, 80);
|
|
7338
|
-
return /* @__PURE__ */
|
|
7620
|
+
return /* @__PURE__ */ jsx29("li", { children: /* @__PURE__ */ jsxs25(
|
|
7339
7621
|
"button",
|
|
7340
7622
|
{
|
|
7341
7623
|
type: "button",
|
|
@@ -7358,8 +7640,8 @@ function Sidebar() {
|
|
|
7358
7640
|
) }, m.id);
|
|
7359
7641
|
}) })
|
|
7360
7642
|
] }),
|
|
7361
|
-
/* @__PURE__ */
|
|
7362
|
-
/* @__PURE__ */
|
|
7643
|
+
/* @__PURE__ */ jsxs25("div", { className: "px-4 py-3 border-b space-y-2", children: [
|
|
7644
|
+
/* @__PURE__ */ jsxs25(
|
|
7363
7645
|
Button,
|
|
7364
7646
|
{
|
|
7365
7647
|
variant: "outline",
|
|
@@ -7370,12 +7652,12 @@ function Sidebar() {
|
|
|
7370
7652
|
client2?.clearContext?.();
|
|
7371
7653
|
},
|
|
7372
7654
|
children: [
|
|
7373
|
-
/* @__PURE__ */
|
|
7655
|
+
/* @__PURE__ */ jsx29(Trash23, { className: "h-4 w-4 mr-2" }),
|
|
7374
7656
|
"Clear context"
|
|
7375
7657
|
]
|
|
7376
7658
|
}
|
|
7377
7659
|
),
|
|
7378
|
-
/* @__PURE__ */
|
|
7660
|
+
/* @__PURE__ */ jsxs25(
|
|
7379
7661
|
Button,
|
|
7380
7662
|
{
|
|
7381
7663
|
variant: "outline",
|
|
@@ -7384,12 +7666,12 @@ function Sidebar() {
|
|
|
7384
7666
|
onClick: () => client2?.newSession?.(),
|
|
7385
7667
|
disabled: !wsConnected,
|
|
7386
7668
|
children: [
|
|
7387
|
-
/* @__PURE__ */
|
|
7669
|
+
/* @__PURE__ */ jsx29(RotateCcw5, { className: "h-4 w-4 mr-2" }),
|
|
7388
7670
|
"New session"
|
|
7389
7671
|
]
|
|
7390
7672
|
}
|
|
7391
7673
|
),
|
|
7392
|
-
/* @__PURE__ */
|
|
7674
|
+
/* @__PURE__ */ jsxs25(
|
|
7393
7675
|
Button,
|
|
7394
7676
|
{
|
|
7395
7677
|
variant: "outline",
|
|
@@ -7398,14 +7680,14 @@ function Sidebar() {
|
|
|
7398
7680
|
onClick: () => client2?.compactContext?.(),
|
|
7399
7681
|
disabled: !wsConnected,
|
|
7400
7682
|
children: [
|
|
7401
|
-
/* @__PURE__ */
|
|
7683
|
+
/* @__PURE__ */ jsx29(Database2, { className: "h-4 w-4 mr-2" }),
|
|
7402
7684
|
"Compact context"
|
|
7403
7685
|
]
|
|
7404
7686
|
}
|
|
7405
7687
|
)
|
|
7406
7688
|
] }),
|
|
7407
|
-
/* @__PURE__ */
|
|
7408
|
-
/* @__PURE__ */
|
|
7689
|
+
/* @__PURE__ */ jsx29("div", { className: "flex-1" }),
|
|
7690
|
+
/* @__PURE__ */ jsx29("div", { className: "px-3 py-3 border-t", children: /* @__PURE__ */ jsxs25(
|
|
7409
7691
|
Button,
|
|
7410
7692
|
{
|
|
7411
7693
|
variant: "ghost",
|
|
@@ -7413,16 +7695,16 @@ function Sidebar() {
|
|
|
7413
7695
|
className: "w-full justify-start",
|
|
7414
7696
|
onClick: () => setCurrentView("settings"),
|
|
7415
7697
|
children: [
|
|
7416
|
-
/* @__PURE__ */
|
|
7698
|
+
/* @__PURE__ */ jsx29(SettingsIcon2, { className: "h-4 w-4 mr-2" }),
|
|
7417
7699
|
"Settings"
|
|
7418
7700
|
]
|
|
7419
7701
|
}
|
|
7420
7702
|
) })
|
|
7421
7703
|
] }),
|
|
7422
|
-
/* @__PURE__ */
|
|
7423
|
-
/* @__PURE__ */
|
|
7424
|
-
/* @__PURE__ */
|
|
7425
|
-
/* @__PURE__ */
|
|
7704
|
+
/* @__PURE__ */ jsxs25(TabsContent, { value: "history", className: "flex-1 m-0 flex flex-col overflow-hidden", children: [
|
|
7705
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between px-4 py-2 border-b", children: [
|
|
7706
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xs uppercase tracking-wider text-muted-foreground", children: "Recent sessions" }),
|
|
7707
|
+
/* @__PURE__ */ jsx29(
|
|
7426
7708
|
Button,
|
|
7427
7709
|
{
|
|
7428
7710
|
variant: "ghost",
|
|
@@ -7431,13 +7713,13 @@ function Sidebar() {
|
|
|
7431
7713
|
onClick: () => listSessions(50),
|
|
7432
7714
|
disabled: !wsConnected,
|
|
7433
7715
|
title: "Refresh",
|
|
7434
|
-
children: historyLoading ? /* @__PURE__ */
|
|
7716
|
+
children: historyLoading ? /* @__PURE__ */ jsx29(Loader25, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx29(RefreshCw3, { className: "h-3.5 w-3.5" })
|
|
7435
7717
|
}
|
|
7436
7718
|
)
|
|
7437
7719
|
] }),
|
|
7438
|
-
historyEntries.length > 3 && /* @__PURE__ */
|
|
7439
|
-
/* @__PURE__ */
|
|
7440
|
-
/* @__PURE__ */
|
|
7720
|
+
historyEntries.length > 3 && /* @__PURE__ */ jsx29("div", { className: "px-3 py-2 border-b", children: /* @__PURE__ */ jsxs25("div", { className: "relative", children: [
|
|
7721
|
+
/* @__PURE__ */ jsx29(Search5, { className: "absolute left-2 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/60" }),
|
|
7722
|
+
/* @__PURE__ */ jsx29(
|
|
7441
7723
|
"input",
|
|
7442
7724
|
{
|
|
7443
7725
|
type: "text",
|
|
@@ -7447,28 +7729,28 @@ function Sidebar() {
|
|
|
7447
7729
|
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"
|
|
7448
7730
|
}
|
|
7449
7731
|
),
|
|
7450
|
-
historyQuery && /* @__PURE__ */
|
|
7732
|
+
historyQuery && /* @__PURE__ */ jsx29(
|
|
7451
7733
|
"button",
|
|
7452
7734
|
{
|
|
7453
7735
|
type: "button",
|
|
7454
7736
|
onClick: () => setHistoryQuery(""),
|
|
7455
7737
|
className: "absolute right-1 top-1/2 -translate-y-1/2 text-muted-foreground/60 hover:text-foreground p-0.5",
|
|
7456
7738
|
title: "Clear filter",
|
|
7457
|
-
children: /* @__PURE__ */
|
|
7739
|
+
children: /* @__PURE__ */ jsx29(X7, { className: "h-3 w-3" })
|
|
7458
7740
|
}
|
|
7459
7741
|
)
|
|
7460
7742
|
] }) }),
|
|
7461
|
-
historyError && /* @__PURE__ */
|
|
7462
|
-
/* @__PURE__ */
|
|
7463
|
-
/* @__PURE__ */
|
|
7464
|
-
/* @__PURE__ */
|
|
7465
|
-
/* @__PURE__ */
|
|
7466
|
-
] }) : groupedHistory.length === 0 ? /* @__PURE__ */
|
|
7467
|
-
/* @__PURE__ */
|
|
7468
|
-
/* @__PURE__ */
|
|
7469
|
-
/* @__PURE__ */
|
|
7470
|
-
] }) : /* @__PURE__ */
|
|
7471
|
-
/* @__PURE__ */
|
|
7743
|
+
historyError && /* @__PURE__ */ jsx29("div", { className: "px-4 py-2 text-xs text-destructive bg-destructive/5 border-b", children: historyError }),
|
|
7744
|
+
/* @__PURE__ */ jsx29(ScrollArea, { className: "flex-1", children: historyEntries.length === 0 && !historyLoading ? /* @__PURE__ */ jsxs25("div", { className: "text-center text-muted-foreground py-8 px-4", children: [
|
|
7745
|
+
/* @__PURE__ */ jsx29(History, { className: "h-8 w-8 mx-auto mb-3 opacity-20" }),
|
|
7746
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm font-medium", children: "No history yet" }),
|
|
7747
|
+
/* @__PURE__ */ jsx29("p", { className: "text-xs mt-1", children: "Your conversations will appear here" })
|
|
7748
|
+
] }) : groupedHistory.length === 0 ? /* @__PURE__ */ jsxs25("div", { className: "text-center text-muted-foreground py-8 px-4", children: [
|
|
7749
|
+
/* @__PURE__ */ jsx29(Search5, { className: "h-8 w-8 mx-auto mb-3 opacity-20" }),
|
|
7750
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm font-medium", children: "No matches" }),
|
|
7751
|
+
/* @__PURE__ */ jsx29("p", { className: "text-xs mt-1", children: "Try a different filter" })
|
|
7752
|
+
] }) : /* @__PURE__ */ jsx29("div", { className: "p-2 space-y-3", children: groupedHistory.map((group) => /* @__PURE__ */ jsxs25("div", { className: "space-y-1", children: [
|
|
7753
|
+
/* @__PURE__ */ jsxs25(
|
|
7472
7754
|
"div",
|
|
7473
7755
|
{
|
|
7474
7756
|
className: cn(
|
|
@@ -7476,10 +7758,10 @@ function Sidebar() {
|
|
|
7476
7758
|
group.star ? "text-amber-500" : "text-muted-foreground/80"
|
|
7477
7759
|
),
|
|
7478
7760
|
children: [
|
|
7479
|
-
group.star && /* @__PURE__ */
|
|
7761
|
+
group.star && /* @__PURE__ */ jsx29(Star, { className: "h-3 w-3 fill-current" }),
|
|
7480
7762
|
group.label,
|
|
7481
7763
|
" ",
|
|
7482
|
-
/* @__PURE__ */
|
|
7764
|
+
/* @__PURE__ */ jsxs25("span", { className: "text-muted-foreground/50 font-normal normal-case ml-1", children: [
|
|
7483
7765
|
"(",
|
|
7484
7766
|
group.rows.length,
|
|
7485
7767
|
")"
|
|
@@ -7487,7 +7769,7 @@ function Sidebar() {
|
|
|
7487
7769
|
]
|
|
7488
7770
|
}
|
|
7489
7771
|
),
|
|
7490
|
-
group.rows.map((entry) => /* @__PURE__ */
|
|
7772
|
+
group.rows.map((entry) => /* @__PURE__ */ jsxs25(
|
|
7491
7773
|
"div",
|
|
7492
7774
|
{
|
|
7493
7775
|
className: cn(
|
|
@@ -7495,7 +7777,7 @@ function Sidebar() {
|
|
|
7495
7777
|
entry.isCurrent ? "bg-primary/5 border-primary/40" : "bg-card border-border/60 hover:bg-muted/40 hover:border-primary/40"
|
|
7496
7778
|
),
|
|
7497
7779
|
children: [
|
|
7498
|
-
/* @__PURE__ */
|
|
7780
|
+
/* @__PURE__ */ jsx29(
|
|
7499
7781
|
"button",
|
|
7500
7782
|
{
|
|
7501
7783
|
type: "button",
|
|
@@ -7507,8 +7789,8 @@ function Sidebar() {
|
|
|
7507
7789
|
setRenameDraft(sessionNicknames[entry.id] ?? entry.title ?? "");
|
|
7508
7790
|
},
|
|
7509
7791
|
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",
|
|
7510
|
-
children: /* @__PURE__ */
|
|
7511
|
-
renamingId === entry.id ? /* @__PURE__ */
|
|
7792
|
+
children: /* @__PURE__ */ jsxs25("div", { className: "min-w-0 flex-1", children: [
|
|
7793
|
+
renamingId === entry.id ? /* @__PURE__ */ jsx29(
|
|
7512
7794
|
"input",
|
|
7513
7795
|
{
|
|
7514
7796
|
value: renameDraft,
|
|
@@ -7531,7 +7813,7 @@ function Sidebar() {
|
|
|
7531
7813
|
placeholder: entry.title || "Nickname",
|
|
7532
7814
|
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"
|
|
7533
7815
|
}
|
|
7534
|
-
) : /* @__PURE__ */
|
|
7816
|
+
) : /* @__PURE__ */ jsx29(
|
|
7535
7817
|
"div",
|
|
7536
7818
|
{
|
|
7537
7819
|
className: "font-medium truncate text-foreground",
|
|
@@ -7541,30 +7823,30 @@ Double-click to rename`,
|
|
|
7541
7823
|
children: sessionNicknames[entry.id] || entry.title || "(empty)"
|
|
7542
7824
|
}
|
|
7543
7825
|
),
|
|
7544
|
-
/* @__PURE__ */
|
|
7826
|
+
/* @__PURE__ */ jsxs25("div", { className: "text-[10px] text-muted-foreground font-mono truncate mt-0.5", children: [
|
|
7545
7827
|
entry.provider,
|
|
7546
7828
|
"/",
|
|
7547
7829
|
entry.model
|
|
7548
7830
|
] }),
|
|
7549
|
-
/* @__PURE__ */
|
|
7550
|
-
/* @__PURE__ */
|
|
7551
|
-
entry.tokenTotal > 0 && /* @__PURE__ */
|
|
7552
|
-
/* @__PURE__ */
|
|
7553
|
-
/* @__PURE__ */
|
|
7831
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2 text-[10px] text-muted-foreground/80 mt-0.5", children: [
|
|
7832
|
+
/* @__PURE__ */ jsx29("span", { children: formatRelative(entry.startedAt) }),
|
|
7833
|
+
entry.tokenTotal > 0 && /* @__PURE__ */ jsxs25(Fragment8, { children: [
|
|
7834
|
+
/* @__PURE__ */ jsx29("span", { children: "\xB7" }),
|
|
7835
|
+
/* @__PURE__ */ jsxs25("span", { className: "tabular-nums", children: [
|
|
7554
7836
|
entry.tokenTotal.toLocaleString(),
|
|
7555
7837
|
" tok"
|
|
7556
7838
|
] })
|
|
7557
7839
|
] }),
|
|
7558
|
-
entry.isCurrent && /* @__PURE__ */
|
|
7559
|
-
/* @__PURE__ */
|
|
7560
|
-
/* @__PURE__ */
|
|
7840
|
+
entry.isCurrent && /* @__PURE__ */ jsxs25(Fragment8, { children: [
|
|
7841
|
+
/* @__PURE__ */ jsx29("span", { children: "\xB7" }),
|
|
7842
|
+
/* @__PURE__ */ jsx29("span", { className: "text-primary font-medium", children: "active" })
|
|
7561
7843
|
] })
|
|
7562
7844
|
] })
|
|
7563
7845
|
] })
|
|
7564
7846
|
}
|
|
7565
7847
|
),
|
|
7566
|
-
/* @__PURE__ */
|
|
7567
|
-
/* @__PURE__ */
|
|
7848
|
+
/* @__PURE__ */ jsxs25("div", { className: "absolute right-2 top-2 flex items-center gap-1", children: [
|
|
7849
|
+
/* @__PURE__ */ jsx29(
|
|
7568
7850
|
"button",
|
|
7569
7851
|
{
|
|
7570
7852
|
type: "button",
|
|
@@ -7574,7 +7856,7 @@ Double-click to rename`,
|
|
|
7574
7856
|
favoriteSessionIds.includes(entry.id) ? "opacity-100 text-amber-500" : "opacity-0 group-hover:opacity-100 text-muted-foreground"
|
|
7575
7857
|
),
|
|
7576
7858
|
title: favoriteSessionIds.includes(entry.id) ? "Unfavorite" : "Mark as favorite",
|
|
7577
|
-
children: /* @__PURE__ */
|
|
7859
|
+
children: /* @__PURE__ */ jsx29(
|
|
7578
7860
|
Star,
|
|
7579
7861
|
{
|
|
7580
7862
|
className: cn(
|
|
@@ -7585,7 +7867,7 @@ Double-click to rename`,
|
|
|
7585
7867
|
)
|
|
7586
7868
|
}
|
|
7587
7869
|
),
|
|
7588
|
-
!entry.isCurrent && /* @__PURE__ */
|
|
7870
|
+
!entry.isCurrent && /* @__PURE__ */ jsx29(
|
|
7589
7871
|
"button",
|
|
7590
7872
|
{
|
|
7591
7873
|
type: "button",
|
|
@@ -7596,7 +7878,7 @@ Double-click to rename`,
|
|
|
7596
7878
|
},
|
|
7597
7879
|
className: "opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-destructive",
|
|
7598
7880
|
title: "Delete session",
|
|
7599
|
-
children: /* @__PURE__ */
|
|
7881
|
+
children: /* @__PURE__ */ jsx29(Trash23, { className: "h-3.5 w-3.5" })
|
|
7600
7882
|
}
|
|
7601
7883
|
)
|
|
7602
7884
|
] })
|
|
@@ -7615,7 +7897,7 @@ Double-click to rename`,
|
|
|
7615
7897
|
}
|
|
7616
7898
|
|
|
7617
7899
|
// src/App.tsx
|
|
7618
|
-
import { jsx as
|
|
7900
|
+
import { Fragment as Fragment9, jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
7619
7901
|
function AppInner() {
|
|
7620
7902
|
const { theme } = useTheme();
|
|
7621
7903
|
const { currentView, sidebarOpen, toggleSidebar, setSearchOpen, setSidebarOpen } = useUIStore();
|
|
@@ -7625,7 +7907,7 @@ function AppInner() {
|
|
|
7625
7907
|
const sessionTitle = useSessionStore((s) => s.session?.title);
|
|
7626
7908
|
const sessionId = useSessionStore((s) => s.session?.id);
|
|
7627
7909
|
const nickname = useUIStore((s) => sessionId ? s.sessionNicknames[sessionId] : void 0);
|
|
7628
|
-
|
|
7910
|
+
useEffect21(() => {
|
|
7629
7911
|
if (typeof window === "undefined") return;
|
|
7630
7912
|
const mq = window.matchMedia("(max-width: 768px)");
|
|
7631
7913
|
const apply = () => {
|
|
@@ -7638,7 +7920,7 @@ function AppInner() {
|
|
|
7638
7920
|
return () => mq.removeEventListener("change", apply);
|
|
7639
7921
|
}, [setSidebarOpen]);
|
|
7640
7922
|
useWebSocketBootstrap();
|
|
7641
|
-
|
|
7923
|
+
useEffect21(() => {
|
|
7642
7924
|
const parts = [];
|
|
7643
7925
|
if (isLoading) {
|
|
7644
7926
|
const it = iteration ? ` iter ${iteration.index}${iteration.max ? `/${iteration.max}` : ""}` : "";
|
|
@@ -7655,7 +7937,7 @@ function AppInner() {
|
|
|
7655
7937
|
document.title = "WrongStack";
|
|
7656
7938
|
};
|
|
7657
7939
|
}, [isLoading, iteration, projectName, sessionTitle, nickname]);
|
|
7658
|
-
|
|
7940
|
+
useEffect21(() => {
|
|
7659
7941
|
const onKey = (e) => {
|
|
7660
7942
|
const t = e.target;
|
|
7661
7943
|
const tag = t?.tagName?.toLowerCase();
|
|
@@ -7751,27 +8033,30 @@ function AppInner() {
|
|
|
7751
8033
|
window.addEventListener("keydown", onKey);
|
|
7752
8034
|
return () => window.removeEventListener("keydown", onKey);
|
|
7753
8035
|
}, [toggleSidebar, setSearchOpen]);
|
|
7754
|
-
return /* @__PURE__ */
|
|
7755
|
-
sidebarOpen && /* @__PURE__ */
|
|
7756
|
-
/* @__PURE__ */
|
|
7757
|
-
/* @__PURE__ */
|
|
7758
|
-
currentView === "chat" && /* @__PURE__ */
|
|
7759
|
-
|
|
8036
|
+
return /* @__PURE__ */ jsxs26("div", { className: cn("flex h-screen", theme), children: [
|
|
8037
|
+
sidebarOpen && /* @__PURE__ */ jsx30(Sidebar, {}),
|
|
8038
|
+
/* @__PURE__ */ jsxs26("main", { className: "flex-1 flex flex-col overflow-hidden", children: [
|
|
8039
|
+
/* @__PURE__ */ jsx30(ConnectionBanner, {}),
|
|
8040
|
+
currentView === "chat" && /* @__PURE__ */ jsxs26(Fragment9, { children: [
|
|
8041
|
+
sessionId && /* @__PURE__ */ jsx30("div", { className: "px-4 pt-2", children: /* @__PURE__ */ jsx30(CollabPanel, { sessionId }) }),
|
|
8042
|
+
/* @__PURE__ */ jsx30(ChatView, {})
|
|
8043
|
+
] }),
|
|
8044
|
+
currentView === "settings" && /* @__PURE__ */ jsx30(SettingsPanel, {})
|
|
7760
8045
|
] }),
|
|
7761
|
-
/* @__PURE__ */
|
|
7762
|
-
/* @__PURE__ */
|
|
7763
|
-
/* @__PURE__ */
|
|
7764
|
-
/* @__PURE__ */
|
|
7765
|
-
/* @__PURE__ */
|
|
8046
|
+
/* @__PURE__ */ jsx30(ConfirmDialog, {}),
|
|
8047
|
+
/* @__PURE__ */ jsx30(CommandPalette, {}),
|
|
8048
|
+
/* @__PURE__ */ jsx30(ShortcutsOverlay, {}),
|
|
8049
|
+
/* @__PURE__ */ jsx30(QuickModelSwitcher, {}),
|
|
8050
|
+
/* @__PURE__ */ jsx30(Toaster, {})
|
|
7766
8051
|
] });
|
|
7767
8052
|
}
|
|
7768
8053
|
function App() {
|
|
7769
|
-
return /* @__PURE__ */
|
|
8054
|
+
return /* @__PURE__ */ jsx30(ErrorBoundary, { children: /* @__PURE__ */ jsx30(ThemeProvider, { defaultTheme: "system", children: /* @__PURE__ */ jsx30(AppInner, {}) }) });
|
|
7770
8055
|
}
|
|
7771
8056
|
|
|
7772
8057
|
// src/main.tsx
|
|
7773
|
-
import { jsx as
|
|
8058
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
7774
8059
|
ReactDOM.createRoot(document.getElementById("root")).render(
|
|
7775
|
-
/* @__PURE__ */
|
|
8060
|
+
/* @__PURE__ */ jsx31(React6.StrictMode, { children: /* @__PURE__ */ jsx31(App, {}) })
|
|
7776
8061
|
);
|
|
7777
8062
|
//# sourceMappingURL=index.js.map
|