@lukeashford/aurelius 3.9.0 → 4.1.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/index.d.mts +287 -125
- package/dist/index.d.ts +287 -125
- package/dist/index.js +1533 -1489
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1197 -1150
- package/dist/index.mjs.map +1 -1
- package/llms.md +60 -19
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -92,6 +92,147 @@ Input.displayName = "Input";
|
|
|
92
92
|
import React4, { createContext, useContext } from "react";
|
|
93
93
|
import { Check } from "lucide-react";
|
|
94
94
|
|
|
95
|
+
// src/utils/clipboard.ts
|
|
96
|
+
async function copyToClipboard(text) {
|
|
97
|
+
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
98
|
+
try {
|
|
99
|
+
await navigator.clipboard.writeText(text);
|
|
100
|
+
return true;
|
|
101
|
+
} catch {
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (typeof document === "undefined") {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const textArea = document.createElement("textarea");
|
|
108
|
+
textArea.value = text;
|
|
109
|
+
textArea.setAttribute("readonly", "");
|
|
110
|
+
textArea.setAttribute("aria-hidden", "true");
|
|
111
|
+
textArea.style.position = "fixed";
|
|
112
|
+
textArea.style.opacity = "0";
|
|
113
|
+
textArea.style.pointerEvents = "none";
|
|
114
|
+
document.body.appendChild(textArea);
|
|
115
|
+
try {
|
|
116
|
+
textArea.select();
|
|
117
|
+
return document.execCommand("copy");
|
|
118
|
+
} catch {
|
|
119
|
+
return false;
|
|
120
|
+
} finally {
|
|
121
|
+
document.body.removeChild(textArea);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// src/utils/hooks.ts
|
|
126
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
127
|
+
function composeRefs(...refs) {
|
|
128
|
+
return (node) => {
|
|
129
|
+
for (const ref of refs) {
|
|
130
|
+
if (!ref) {
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (typeof ref === "function") {
|
|
134
|
+
ref(node);
|
|
135
|
+
} else {
|
|
136
|
+
;
|
|
137
|
+
ref.current = node;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
var scrollLockCount = 0;
|
|
143
|
+
var scrollLockOriginalOverflow = null;
|
|
144
|
+
var scrollLockOriginalPaddingRight = null;
|
|
145
|
+
function useScrollLock(isLocked) {
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
if (!isLocked || typeof document === "undefined") {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (scrollLockCount === 0) {
|
|
151
|
+
scrollLockOriginalOverflow = document.body.style.overflow;
|
|
152
|
+
scrollLockOriginalPaddingRight = document.body.style.paddingRight;
|
|
153
|
+
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
154
|
+
document.body.style.overflow = "hidden";
|
|
155
|
+
if (scrollbarWidth > 0) {
|
|
156
|
+
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
scrollLockCount++;
|
|
160
|
+
return () => {
|
|
161
|
+
scrollLockCount--;
|
|
162
|
+
if (scrollLockCount === 0) {
|
|
163
|
+
document.body.style.overflow = scrollLockOriginalOverflow ?? "";
|
|
164
|
+
document.body.style.paddingRight = scrollLockOriginalPaddingRight ?? "";
|
|
165
|
+
scrollLockOriginalOverflow = null;
|
|
166
|
+
scrollLockOriginalPaddingRight = null;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}, [isLocked]);
|
|
170
|
+
}
|
|
171
|
+
function useEscapeKey(onEscape, isActive = true) {
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (!isActive || typeof window === "undefined") {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
const handler = (e) => {
|
|
177
|
+
if (e.key === "Escape") {
|
|
178
|
+
onEscape();
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
window.addEventListener("keydown", handler);
|
|
182
|
+
return () => window.removeEventListener("keydown", handler);
|
|
183
|
+
}, [onEscape, isActive]);
|
|
184
|
+
}
|
|
185
|
+
function useClickOutside(ref, handler, isActive = true) {
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
if (!isActive || typeof document === "undefined") {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const listener = (event) => {
|
|
191
|
+
const node = ref.current;
|
|
192
|
+
if (node && !node.contains(event.target)) {
|
|
193
|
+
handler(event);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
document.addEventListener("mousedown", listener);
|
|
197
|
+
return () => document.removeEventListener("mousedown", listener);
|
|
198
|
+
}, [ref, handler, isActive]);
|
|
199
|
+
}
|
|
200
|
+
function useCopyToClipboard(resetMs = 2e3) {
|
|
201
|
+
const [copied, setCopied] = useState(false);
|
|
202
|
+
const timerRef = useRef(null);
|
|
203
|
+
const mountedRef = useRef(true);
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
mountedRef.current = true;
|
|
206
|
+
return () => {
|
|
207
|
+
mountedRef.current = false;
|
|
208
|
+
if (timerRef.current !== null) {
|
|
209
|
+
clearTimeout(timerRef.current);
|
|
210
|
+
timerRef.current = null;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}, []);
|
|
214
|
+
const copy = useCallback(async (text) => {
|
|
215
|
+
const ok = await copyToClipboard(text);
|
|
216
|
+
if (!mountedRef.current) {
|
|
217
|
+
return ok;
|
|
218
|
+
}
|
|
219
|
+
if (ok) {
|
|
220
|
+
setCopied(true);
|
|
221
|
+
if (timerRef.current !== null) {
|
|
222
|
+
clearTimeout(timerRef.current);
|
|
223
|
+
}
|
|
224
|
+
timerRef.current = setTimeout(() => {
|
|
225
|
+
timerRef.current = null;
|
|
226
|
+
if (mountedRef.current) {
|
|
227
|
+
setCopied(false);
|
|
228
|
+
}
|
|
229
|
+
}, resetMs);
|
|
230
|
+
}
|
|
231
|
+
return ok;
|
|
232
|
+
}, [resetMs]);
|
|
233
|
+
return { copied, copy };
|
|
234
|
+
}
|
|
235
|
+
|
|
95
236
|
// src/components/Skeleton.tsx
|
|
96
237
|
import React3 from "react";
|
|
97
238
|
var Skeleton = React3.forwardRef(
|
|
@@ -116,8 +257,7 @@ function slotLoading(loading, path) {
|
|
|
116
257
|
return false;
|
|
117
258
|
}
|
|
118
259
|
if (Array.isArray(path)) {
|
|
119
|
-
|
|
120
|
-
return !!loading[section]?.[field];
|
|
260
|
+
return !!loading.header?.[path[1]];
|
|
121
261
|
}
|
|
122
262
|
return !!loading[path];
|
|
123
263
|
}
|
|
@@ -1393,29 +1533,28 @@ var Select = React20.forwardRef(
|
|
|
1393
1533
|
Select.displayName = "Select";
|
|
1394
1534
|
|
|
1395
1535
|
// src/components/Checkbox.tsx
|
|
1396
|
-
import React21, { useCallback } from "react";
|
|
1536
|
+
import React21, { useCallback as useCallback2, useId } from "react";
|
|
1397
1537
|
var checkmarkSvg = `url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='%231A1A1A' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e")`;
|
|
1398
1538
|
var Checkbox = React21.forwardRef(
|
|
1399
|
-
({ className, label, id, ...rest }, ref) => {
|
|
1400
|
-
const
|
|
1401
|
-
const
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
if (typeof ref === "function") {
|
|
1408
|
-
ref(node);
|
|
1409
|
-
} else if (ref) {
|
|
1410
|
-
ref.current = node;
|
|
1539
|
+
({ className, label, id, onChange, ...rest }, ref) => {
|
|
1540
|
+
const generatedId = useId();
|
|
1541
|
+
const inputId = id || rest.name || generatedId;
|
|
1542
|
+
const initBackground = useCallback2((node) => {
|
|
1543
|
+
if (node && node.checked) {
|
|
1544
|
+
node.style.backgroundImage = checkmarkSvg;
|
|
1411
1545
|
}
|
|
1412
|
-
}, [
|
|
1546
|
+
}, []);
|
|
1547
|
+
const handleChange = useCallback2((e) => {
|
|
1548
|
+
e.currentTarget.style.backgroundImage = e.currentTarget.checked ? checkmarkSvg : "none";
|
|
1549
|
+
onChange?.(e);
|
|
1550
|
+
}, [onChange]);
|
|
1413
1551
|
return /* @__PURE__ */ React21.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React21.createElement(
|
|
1414
1552
|
"input",
|
|
1415
1553
|
{
|
|
1554
|
+
...rest,
|
|
1416
1555
|
type: "checkbox",
|
|
1417
1556
|
id: inputId,
|
|
1418
|
-
ref:
|
|
1557
|
+
ref: composeRefs(initBackground, ref),
|
|
1419
1558
|
className: cx(
|
|
1420
1559
|
"appearance-none h-4 w-4 border border-ash bg-graphite",
|
|
1421
1560
|
"checked:bg-gold checked:border-gold",
|
|
@@ -1429,16 +1568,7 @@ var Checkbox = React21.forwardRef(
|
|
|
1429
1568
|
backgroundSize: "contain",
|
|
1430
1569
|
backgroundRepeat: "no-repeat"
|
|
1431
1570
|
},
|
|
1432
|
-
onChange:
|
|
1433
|
-
const input = e.currentTarget;
|
|
1434
|
-
if (input.checked) {
|
|
1435
|
-
input.style.backgroundImage = checkmarkSvg;
|
|
1436
|
-
} else {
|
|
1437
|
-
input.style.backgroundImage = "none";
|
|
1438
|
-
}
|
|
1439
|
-
rest.onChange?.(e);
|
|
1440
|
-
},
|
|
1441
|
-
...rest
|
|
1571
|
+
onChange: handleChange
|
|
1442
1572
|
}
|
|
1443
1573
|
), label && /* @__PURE__ */ React21.createElement(
|
|
1444
1574
|
"label",
|
|
@@ -1453,29 +1583,44 @@ var Checkbox = React21.forwardRef(
|
|
|
1453
1583
|
Checkbox.displayName = "Checkbox";
|
|
1454
1584
|
|
|
1455
1585
|
// src/components/Radio.tsx
|
|
1456
|
-
import React22, { useCallback as
|
|
1586
|
+
import React22, { useCallback as useCallback3, useId as useId2 } from "react";
|
|
1457
1587
|
var radioDotSvg = `url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='%231A1A1A' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e")`;
|
|
1458
1588
|
var Radio = React22.forwardRef(
|
|
1459
|
-
({ className, label, id, ...rest }, ref) => {
|
|
1460
|
-
const
|
|
1461
|
-
const
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
}
|
|
1589
|
+
({ className, label, id, onChange, ...rest }, ref) => {
|
|
1590
|
+
const generatedId = useId2();
|
|
1591
|
+
const inputId = id || rest.name || generatedId;
|
|
1592
|
+
const initBackground = useCallback3((node) => {
|
|
1593
|
+
if (node && node.checked) {
|
|
1594
|
+
node.style.backgroundImage = radioDotSvg;
|
|
1466
1595
|
}
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1596
|
+
}, []);
|
|
1597
|
+
const handleChange = useCallback3((e) => {
|
|
1598
|
+
const input = e.currentTarget;
|
|
1599
|
+
if (input.checked) {
|
|
1600
|
+
input.style.backgroundImage = radioDotSvg;
|
|
1601
|
+
if (input.name) {
|
|
1602
|
+
const escaped = typeof CSS !== "undefined" && typeof CSS.escape === "function" ? CSS.escape(input.name) : input.name.replace(/["\\\]]/g, "\\$&");
|
|
1603
|
+
const radios = input.ownerDocument.querySelectorAll(
|
|
1604
|
+
`input[type="radio"][name="${escaped}"]`
|
|
1605
|
+
);
|
|
1606
|
+
radios.forEach((radio) => {
|
|
1607
|
+
if (radio !== input) {
|
|
1608
|
+
radio.style.backgroundImage = "none";
|
|
1609
|
+
}
|
|
1610
|
+
});
|
|
1611
|
+
}
|
|
1612
|
+
} else {
|
|
1613
|
+
input.style.backgroundImage = "none";
|
|
1471
1614
|
}
|
|
1472
|
-
|
|
1615
|
+
onChange?.(e);
|
|
1616
|
+
}, [onChange]);
|
|
1473
1617
|
return /* @__PURE__ */ React22.createElement("div", { className: "flex items-center" }, /* @__PURE__ */ React22.createElement(
|
|
1474
1618
|
"input",
|
|
1475
1619
|
{
|
|
1620
|
+
...rest,
|
|
1476
1621
|
type: "radio",
|
|
1477
1622
|
id: inputId,
|
|
1478
|
-
ref:
|
|
1623
|
+
ref: composeRefs(initBackground, ref),
|
|
1479
1624
|
className: cx(
|
|
1480
1625
|
"appearance-none h-4 w-4 border border-ash rounded-full bg-graphite",
|
|
1481
1626
|
"checked:bg-gold checked:border-gold",
|
|
@@ -1489,26 +1634,7 @@ var Radio = React22.forwardRef(
|
|
|
1489
1634
|
backgroundSize: "contain",
|
|
1490
1635
|
backgroundRepeat: "no-repeat"
|
|
1491
1636
|
},
|
|
1492
|
-
onChange:
|
|
1493
|
-
const input = e.currentTarget;
|
|
1494
|
-
if (input.checked) {
|
|
1495
|
-
input.style.backgroundImage = radioDotSvg;
|
|
1496
|
-
if (input.name) {
|
|
1497
|
-
const radios = document.querySelectorAll(
|
|
1498
|
-
`input[type="radio"][name="${input.name}"]`
|
|
1499
|
-
);
|
|
1500
|
-
radios.forEach((radio) => {
|
|
1501
|
-
if (radio !== input) {
|
|
1502
|
-
radio.style.backgroundImage = "none";
|
|
1503
|
-
}
|
|
1504
|
-
});
|
|
1505
|
-
}
|
|
1506
|
-
} else {
|
|
1507
|
-
input.style.backgroundImage = "none";
|
|
1508
|
-
}
|
|
1509
|
-
rest.onChange?.(e);
|
|
1510
|
-
},
|
|
1511
|
-
...rest
|
|
1637
|
+
onChange: handleChange
|
|
1512
1638
|
}
|
|
1513
1639
|
), label && /* @__PURE__ */ React22.createElement(
|
|
1514
1640
|
"label",
|
|
@@ -1523,7 +1649,7 @@ var Radio = React22.forwardRef(
|
|
|
1523
1649
|
Radio.displayName = "Radio";
|
|
1524
1650
|
|
|
1525
1651
|
// src/components/Switch.tsx
|
|
1526
|
-
import React23, { useCallback as
|
|
1652
|
+
import React23, { useCallback as useCallback4, useRef as useRef2, useState as useState2 } from "react";
|
|
1527
1653
|
var Switch = React23.forwardRef(
|
|
1528
1654
|
({
|
|
1529
1655
|
checked: controlledChecked,
|
|
@@ -1534,11 +1660,11 @@ var Switch = React23.forwardRef(
|
|
|
1534
1660
|
label,
|
|
1535
1661
|
...rest
|
|
1536
1662
|
}, ref) => {
|
|
1537
|
-
const [internalChecked, setInternalChecked] =
|
|
1663
|
+
const [internalChecked, setInternalChecked] = useState2(defaultChecked);
|
|
1538
1664
|
const isControlled = controlledChecked !== void 0;
|
|
1539
1665
|
const checked = isControlled ? controlledChecked : internalChecked;
|
|
1540
|
-
const buttonRef =
|
|
1541
|
-
const setRefs =
|
|
1666
|
+
const buttonRef = useRef2(null);
|
|
1667
|
+
const setRefs = useCallback4(
|
|
1542
1668
|
(node) => {
|
|
1543
1669
|
buttonRef.current = node;
|
|
1544
1670
|
if (typeof ref === "function") {
|
|
@@ -1608,7 +1734,7 @@ var Switch = React23.forwardRef(
|
|
|
1608
1734
|
Switch.displayName = "Switch";
|
|
1609
1735
|
|
|
1610
1736
|
// src/components/Slider.tsx
|
|
1611
|
-
import React24, { useCallback as
|
|
1737
|
+
import React24, { useCallback as useCallback5, useRef as useRef3, useState as useState3 } from "react";
|
|
1612
1738
|
var SIZE_TRACK = {
|
|
1613
1739
|
sm: "h-1",
|
|
1614
1740
|
md: "h-2",
|
|
@@ -1635,13 +1761,13 @@ var Slider = React24.forwardRef(
|
|
|
1635
1761
|
className,
|
|
1636
1762
|
...props
|
|
1637
1763
|
}, ref) => {
|
|
1638
|
-
const [internalValue, setInternalValue] =
|
|
1639
|
-
const [isDragging, setIsDragging] =
|
|
1640
|
-
const trackRef =
|
|
1764
|
+
const [internalValue, setInternalValue] = useState3(defaultValue);
|
|
1765
|
+
const [isDragging, setIsDragging] = useState3(false);
|
|
1766
|
+
const trackRef = useRef3(null);
|
|
1641
1767
|
const isControlled = controlledValue !== void 0;
|
|
1642
1768
|
const value = isControlled ? controlledValue : internalValue;
|
|
1643
1769
|
const percentage = (value - min) / (max - min) * 100;
|
|
1644
|
-
const updateValue =
|
|
1770
|
+
const updateValue = useCallback5(
|
|
1645
1771
|
(clientX) => {
|
|
1646
1772
|
if (!trackRef.current || disabled) {
|
|
1647
1773
|
return;
|
|
@@ -1997,16 +2123,21 @@ var Progress = React28.forwardRef(
|
|
|
1997
2123
|
Progress.displayName = "Progress";
|
|
1998
2124
|
|
|
1999
2125
|
// src/components/Toast.tsx
|
|
2000
|
-
import React29, { createContext as createContext2, useCallback as
|
|
2126
|
+
import React29, { createContext as createContext2, useCallback as useCallback6, useContext as useContext2, useEffect as useEffect2, useState as useState4 } from "react";
|
|
2001
2127
|
import { createPortal } from "react-dom";
|
|
2002
2128
|
import { AlertCircle, AlertTriangle as AlertTriangle2, CheckCircle as CheckCircle2, Info as Info2, X as X2 } from "lucide-react";
|
|
2129
|
+
var toastCounter = 0;
|
|
2130
|
+
function createToastId() {
|
|
2131
|
+
toastCounter += 1;
|
|
2132
|
+
return `toast-${Date.now().toString(36)}-${toastCounter}`;
|
|
2133
|
+
}
|
|
2003
2134
|
var ToastContext = createContext2(null);
|
|
2004
2135
|
function useToast() {
|
|
2005
2136
|
const context = useContext2(ToastContext);
|
|
2006
2137
|
if (!context) {
|
|
2007
2138
|
throw new Error("useToast must be used within a ToastProvider");
|
|
2008
2139
|
}
|
|
2009
|
-
const toast =
|
|
2140
|
+
const toast = useCallback6(
|
|
2010
2141
|
(options) => {
|
|
2011
2142
|
return context.addToast(options);
|
|
2012
2143
|
},
|
|
@@ -2022,14 +2153,14 @@ var ToastProvider = ({
|
|
|
2022
2153
|
position = "bottom-right",
|
|
2023
2154
|
defaultDuration = 5e3
|
|
2024
2155
|
}) => {
|
|
2025
|
-
const [toasts, setToasts] =
|
|
2026
|
-
const [mounted, setMounted] =
|
|
2027
|
-
|
|
2156
|
+
const [toasts, setToasts] = useState4([]);
|
|
2157
|
+
const [mounted, setMounted] = useState4(false);
|
|
2158
|
+
useEffect2(() => {
|
|
2028
2159
|
setMounted(true);
|
|
2029
2160
|
}, []);
|
|
2030
|
-
const addToast =
|
|
2161
|
+
const addToast = useCallback6(
|
|
2031
2162
|
(toast) => {
|
|
2032
|
-
const id =
|
|
2163
|
+
const id = createToastId();
|
|
2033
2164
|
const newToast = {
|
|
2034
2165
|
...toast,
|
|
2035
2166
|
id,
|
|
@@ -2040,33 +2171,33 @@ var ToastProvider = ({
|
|
|
2040
2171
|
},
|
|
2041
2172
|
[defaultDuration]
|
|
2042
2173
|
);
|
|
2043
|
-
const removeToast =
|
|
2174
|
+
const removeToast = useCallback6((id) => {
|
|
2044
2175
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
2045
2176
|
}, []);
|
|
2046
2177
|
return /* @__PURE__ */ React29.createElement(ToastContext.Provider, { value: { toasts, addToast, removeToast, position } }, children, mounted && /* @__PURE__ */ React29.createElement(ToastViewport, null));
|
|
2047
2178
|
};
|
|
2048
2179
|
ToastProvider.displayName = "ToastProvider";
|
|
2180
|
+
var POSITION_CLASSES = {
|
|
2181
|
+
"top-right": "top-4 right-4",
|
|
2182
|
+
"top-left": "top-4 left-4",
|
|
2183
|
+
"bottom-right": "bottom-4 right-4",
|
|
2184
|
+
"bottom-left": "bottom-4 left-4",
|
|
2185
|
+
"top-center": "top-4 left-1/2 -translate-x-1/2",
|
|
2186
|
+
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
|
|
2187
|
+
};
|
|
2049
2188
|
var ToastViewport = () => {
|
|
2050
2189
|
const context = useContext2(ToastContext);
|
|
2051
2190
|
if (!context) {
|
|
2052
2191
|
return null;
|
|
2053
2192
|
}
|
|
2054
2193
|
const { toasts, position } = context;
|
|
2055
|
-
const positionClasses = {
|
|
2056
|
-
"top-right": "top-4 right-4",
|
|
2057
|
-
"top-left": "top-4 left-4",
|
|
2058
|
-
"bottom-right": "bottom-4 right-4",
|
|
2059
|
-
"bottom-left": "bottom-4 left-4",
|
|
2060
|
-
"top-center": "top-4 left-1/2 -translate-x-1/2",
|
|
2061
|
-
"bottom-center": "bottom-4 left-1/2 -translate-x-1/2"
|
|
2062
|
-
};
|
|
2063
2194
|
return createPortal(
|
|
2064
2195
|
/* @__PURE__ */ React29.createElement(
|
|
2065
2196
|
"div",
|
|
2066
2197
|
{
|
|
2067
2198
|
className: cx(
|
|
2068
2199
|
"fixed z-50 flex flex-col gap-2 pointer-events-none",
|
|
2069
|
-
|
|
2200
|
+
POSITION_CLASSES[position]
|
|
2070
2201
|
)
|
|
2071
2202
|
},
|
|
2072
2203
|
toasts.map((toast) => /* @__PURE__ */ React29.createElement(Toast, { key: toast.id, ...toast }))
|
|
@@ -2097,7 +2228,7 @@ var Toast = ({
|
|
|
2097
2228
|
action
|
|
2098
2229
|
}) => {
|
|
2099
2230
|
const context = useContext2(ToastContext);
|
|
2100
|
-
|
|
2231
|
+
useEffect2(() => {
|
|
2101
2232
|
if (duration && duration > 0) {
|
|
2102
2233
|
const timer = setTimeout(() => {
|
|
2103
2234
|
context?.removeToast(id);
|
|
@@ -2129,41 +2260,17 @@ var Toast = ({
|
|
|
2129
2260
|
Toast.displayName = "Toast";
|
|
2130
2261
|
|
|
2131
2262
|
// src/components/Modal.tsx
|
|
2132
|
-
import React30, { useEffect as
|
|
2263
|
+
import React30, { useEffect as useEffect3, useState as useState5 } from "react";
|
|
2133
2264
|
import { createPortal as createPortal2 } from "react-dom";
|
|
2134
2265
|
import { X as X3 } from "lucide-react";
|
|
2135
2266
|
var Modal = ({ isOpen, onClose, title, children, className }) => {
|
|
2136
|
-
const [mounted, setMounted] =
|
|
2137
|
-
|
|
2267
|
+
const [mounted, setMounted] = useState5(false);
|
|
2268
|
+
useEffect3(() => {
|
|
2138
2269
|
setMounted(true);
|
|
2139
2270
|
}, []);
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
document.body.style.overflow = "hidden";
|
|
2144
|
-
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
2145
|
-
} else {
|
|
2146
|
-
document.body.style.overflow = "unset";
|
|
2147
|
-
document.body.style.paddingRight = "0px";
|
|
2148
|
-
}
|
|
2149
|
-
return () => {
|
|
2150
|
-
document.body.style.overflow = "unset";
|
|
2151
|
-
document.body.style.paddingRight = "0px";
|
|
2152
|
-
};
|
|
2153
|
-
}, [isOpen]);
|
|
2154
|
-
useEffect2(() => {
|
|
2155
|
-
const handleEsc = (e) => {
|
|
2156
|
-
if (e.key === "Escape") {
|
|
2157
|
-
onClose();
|
|
2158
|
-
}
|
|
2159
|
-
};
|
|
2160
|
-
window.addEventListener("keydown", handleEsc);
|
|
2161
|
-
return () => window.removeEventListener("keydown", handleEsc);
|
|
2162
|
-
}, [onClose]);
|
|
2163
|
-
if (!mounted) {
|
|
2164
|
-
return null;
|
|
2165
|
-
}
|
|
2166
|
-
if (!isOpen) {
|
|
2271
|
+
useScrollLock(isOpen);
|
|
2272
|
+
useEscapeKey(onClose, isOpen);
|
|
2273
|
+
if (!mounted || !isOpen) {
|
|
2167
2274
|
return null;
|
|
2168
2275
|
}
|
|
2169
2276
|
const content = /* @__PURE__ */ React30.createElement(
|
|
@@ -2202,7 +2309,7 @@ var Modal = ({ isOpen, onClose, title, children, className }) => {
|
|
|
2202
2309
|
Modal.displayName = "Modal";
|
|
2203
2310
|
|
|
2204
2311
|
// src/components/Drawer.tsx
|
|
2205
|
-
import React31, { useEffect as
|
|
2312
|
+
import React31, { useEffect as useEffect4, useState as useState6 } from "react";
|
|
2206
2313
|
import { createPortal as createPortal3 } from "react-dom";
|
|
2207
2314
|
import { X as X4 } from "lucide-react";
|
|
2208
2315
|
var SIZE_MAP2 = {
|
|
@@ -2237,7 +2344,7 @@ var SIZE_MAP2 = {
|
|
|
2237
2344
|
bottom: "h-full"
|
|
2238
2345
|
}
|
|
2239
2346
|
};
|
|
2240
|
-
var
|
|
2347
|
+
var POSITION_CLASSES2 = {
|
|
2241
2348
|
left: "left-0 top-0 h-full",
|
|
2242
2349
|
right: "right-0 top-0 h-full",
|
|
2243
2350
|
top: "top-0 left-0 w-full",
|
|
@@ -2258,33 +2365,12 @@ var Drawer = ({
|
|
|
2258
2365
|
children,
|
|
2259
2366
|
className
|
|
2260
2367
|
}) => {
|
|
2261
|
-
const [mounted, setMounted] =
|
|
2262
|
-
|
|
2368
|
+
const [mounted, setMounted] = useState6(false);
|
|
2369
|
+
useEffect4(() => {
|
|
2263
2370
|
setMounted(true);
|
|
2264
2371
|
}, []);
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
|
|
2268
|
-
document.body.style.overflow = "hidden";
|
|
2269
|
-
document.body.style.paddingRight = `${scrollbarWidth}px`;
|
|
2270
|
-
} else {
|
|
2271
|
-
document.body.style.overflow = "unset";
|
|
2272
|
-
document.body.style.paddingRight = "0px";
|
|
2273
|
-
}
|
|
2274
|
-
return () => {
|
|
2275
|
-
document.body.style.overflow = "unset";
|
|
2276
|
-
document.body.style.paddingRight = "0px";
|
|
2277
|
-
};
|
|
2278
|
-
}, [isOpen]);
|
|
2279
|
-
useEffect3(() => {
|
|
2280
|
-
const handleEsc = (e) => {
|
|
2281
|
-
if (e.key === "Escape") {
|
|
2282
|
-
onClose();
|
|
2283
|
-
}
|
|
2284
|
-
};
|
|
2285
|
-
window.addEventListener("keydown", handleEsc);
|
|
2286
|
-
return () => window.removeEventListener("keydown", handleEsc);
|
|
2287
|
-
}, [onClose]);
|
|
2372
|
+
useScrollLock(isOpen);
|
|
2373
|
+
useEscapeKey(onClose, isOpen);
|
|
2288
2374
|
if (!mounted) {
|
|
2289
2375
|
return null;
|
|
2290
2376
|
}
|
|
@@ -2315,7 +2401,7 @@ var Drawer = ({
|
|
|
2315
2401
|
className: cx(
|
|
2316
2402
|
"fixed bg-charcoal border-ash shadow-2xl flex flex-col",
|
|
2317
2403
|
"transition-transform duration-300 ease-out",
|
|
2318
|
-
|
|
2404
|
+
POSITION_CLASSES2[position],
|
|
2319
2405
|
SIZE_MAP2[size][position],
|
|
2320
2406
|
position === "left" && "border-r",
|
|
2321
2407
|
position === "right" && "border-l",
|
|
@@ -2342,8 +2428,8 @@ var Drawer = ({
|
|
|
2342
2428
|
Drawer.displayName = "Drawer";
|
|
2343
2429
|
|
|
2344
2430
|
// src/components/Popover.tsx
|
|
2345
|
-
import React32, { useCallback as
|
|
2346
|
-
var
|
|
2431
|
+
import React32, { useCallback as useCallback7, useId as useId3, useRef as useRef4, useState as useState7 } from "react";
|
|
2432
|
+
var POSITION_CLASSES3 = {
|
|
2347
2433
|
top: {
|
|
2348
2434
|
start: "bottom-full left-0 mb-2",
|
|
2349
2435
|
center: "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
@@ -2374,12 +2460,12 @@ var Popover = ({
|
|
|
2374
2460
|
onOpenChange,
|
|
2375
2461
|
closeOnClickOutside = true
|
|
2376
2462
|
}) => {
|
|
2377
|
-
const [internalOpen, setInternalOpen] =
|
|
2463
|
+
const [internalOpen, setInternalOpen] = useState7(false);
|
|
2378
2464
|
const isControlled = controlledOpen !== void 0;
|
|
2379
2465
|
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
2380
|
-
const containerRef =
|
|
2381
|
-
const baseId =
|
|
2382
|
-
const setIsOpen =
|
|
2466
|
+
const containerRef = useRef4(null);
|
|
2467
|
+
const baseId = useId3();
|
|
2468
|
+
const setIsOpen = useCallback7(
|
|
2383
2469
|
(newOpen) => {
|
|
2384
2470
|
if (!isControlled) {
|
|
2385
2471
|
setInternalOpen(newOpen);
|
|
@@ -2388,30 +2474,9 @@ var Popover = ({
|
|
|
2388
2474
|
},
|
|
2389
2475
|
[isControlled, onOpenChange]
|
|
2390
2476
|
);
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
}
|
|
2395
|
-
const handleClickOutside = (e) => {
|
|
2396
|
-
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
2397
|
-
setIsOpen(false);
|
|
2398
|
-
}
|
|
2399
|
-
};
|
|
2400
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
2401
|
-
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2402
|
-
}, [isOpen, closeOnClickOutside, setIsOpen]);
|
|
2403
|
-
useEffect4(() => {
|
|
2404
|
-
if (!isOpen) {
|
|
2405
|
-
return;
|
|
2406
|
-
}
|
|
2407
|
-
const handleEscape = (e) => {
|
|
2408
|
-
if (e.key === "Escape") {
|
|
2409
|
-
setIsOpen(false);
|
|
2410
|
-
}
|
|
2411
|
-
};
|
|
2412
|
-
document.addEventListener("keydown", handleEscape);
|
|
2413
|
-
return () => document.removeEventListener("keydown", handleEscape);
|
|
2414
|
-
}, [isOpen, setIsOpen]);
|
|
2477
|
+
const close = useCallback7(() => setIsOpen(false), [setIsOpen]);
|
|
2478
|
+
useClickOutside(containerRef, close, isOpen && closeOnClickOutside);
|
|
2479
|
+
useEscapeKey(close, isOpen);
|
|
2415
2480
|
const handleTriggerClick = () => {
|
|
2416
2481
|
setIsOpen(!isOpen);
|
|
2417
2482
|
};
|
|
@@ -2432,7 +2497,7 @@ var Popover = ({
|
|
|
2432
2497
|
"absolute z-50 min-w-48 p-4",
|
|
2433
2498
|
"bg-charcoal border border-ash shadow-lg",
|
|
2434
2499
|
"animate-fade-in",
|
|
2435
|
-
|
|
2500
|
+
POSITION_CLASSES3[position][align]
|
|
2436
2501
|
)
|
|
2437
2502
|
},
|
|
2438
2503
|
children
|
|
@@ -2441,7 +2506,7 @@ var Popover = ({
|
|
|
2441
2506
|
Popover.displayName = "Popover";
|
|
2442
2507
|
|
|
2443
2508
|
// src/components/Dialog.tsx
|
|
2444
|
-
import React33, { useCallback as
|
|
2509
|
+
import React33, { useCallback as useCallback8 } from "react";
|
|
2445
2510
|
var ConfirmDialog = ({
|
|
2446
2511
|
title = "Confirm",
|
|
2447
2512
|
description,
|
|
@@ -2454,11 +2519,11 @@ var ConfirmDialog = ({
|
|
|
2454
2519
|
isLoading = false,
|
|
2455
2520
|
...props
|
|
2456
2521
|
}) => {
|
|
2457
|
-
const handleCancel =
|
|
2522
|
+
const handleCancel = useCallback8(() => {
|
|
2458
2523
|
onCancel?.();
|
|
2459
2524
|
onClose();
|
|
2460
2525
|
}, [onCancel, onClose]);
|
|
2461
|
-
const handleConfirm =
|
|
2526
|
+
const handleConfirm = useCallback8(async () => {
|
|
2462
2527
|
await onConfirm();
|
|
2463
2528
|
onClose();
|
|
2464
2529
|
}, [onConfirm, onClose]);
|
|
@@ -2502,11 +2567,11 @@ var PromptDialog = ({
|
|
|
2502
2567
|
...props
|
|
2503
2568
|
}) => {
|
|
2504
2569
|
const [value, setValue] = React33.useState(defaultValue);
|
|
2505
|
-
const handleCancel =
|
|
2570
|
+
const handleCancel = useCallback8(() => {
|
|
2506
2571
|
onCancel?.();
|
|
2507
2572
|
onClose();
|
|
2508
2573
|
}, [onCancel, onClose]);
|
|
2509
|
-
const handleSubmit =
|
|
2574
|
+
const handleSubmit = useCallback8(
|
|
2510
2575
|
async (e) => {
|
|
2511
2576
|
e.preventDefault();
|
|
2512
2577
|
await onSubmit(value);
|
|
@@ -2543,7 +2608,7 @@ var PromptDialog = ({
|
|
|
2543
2608
|
PromptDialog.displayName = "PromptDialog";
|
|
2544
2609
|
|
|
2545
2610
|
// src/components/Tabs.tsx
|
|
2546
|
-
import React34, { createContext as createContext3, useCallback as
|
|
2611
|
+
import React34, { createContext as createContext3, useCallback as useCallback9, useContext as useContext3, useId as useId4, useState as useState8 } from "react";
|
|
2547
2612
|
var TabsContext = createContext3(null);
|
|
2548
2613
|
function useTabsContext() {
|
|
2549
2614
|
const context = useContext3(TabsContext);
|
|
@@ -2554,11 +2619,11 @@ function useTabsContext() {
|
|
|
2554
2619
|
}
|
|
2555
2620
|
var Tabs = React34.forwardRef(
|
|
2556
2621
|
({ defaultValue, value, onValueChange, children, className, ...props }, ref) => {
|
|
2557
|
-
const [internalValue, setInternalValue] =
|
|
2622
|
+
const [internalValue, setInternalValue] = useState8(defaultValue ?? "");
|
|
2558
2623
|
const isControlled = value !== void 0;
|
|
2559
2624
|
const activeTab = isControlled ? value : internalValue;
|
|
2560
|
-
const baseId =
|
|
2561
|
-
const setActiveTab =
|
|
2625
|
+
const baseId = useId4();
|
|
2626
|
+
const setActiveTab = useCallback9(
|
|
2562
2627
|
(id) => {
|
|
2563
2628
|
if (!isControlled) {
|
|
2564
2629
|
setInternalValue(id);
|
|
@@ -2654,7 +2719,7 @@ var TabPanel = React34.forwardRef(
|
|
|
2654
2719
|
TabPanel.displayName = "TabPanel";
|
|
2655
2720
|
|
|
2656
2721
|
// src/components/Accordion.tsx
|
|
2657
|
-
import React35, { createContext as createContext4, useCallback as
|
|
2722
|
+
import React35, { createContext as createContext4, useCallback as useCallback10, useContext as useContext4, useId as useId5, useState as useState9 } from "react";
|
|
2658
2723
|
import { ChevronDown } from "lucide-react";
|
|
2659
2724
|
var AccordionContext = createContext4(null);
|
|
2660
2725
|
function useAccordionContext() {
|
|
@@ -2666,7 +2731,7 @@ function useAccordionContext() {
|
|
|
2666
2731
|
}
|
|
2667
2732
|
var Accordion = React35.forwardRef(
|
|
2668
2733
|
({ type = "single", defaultValue, value, onValueChange, children, className, ...props }, ref) => {
|
|
2669
|
-
const [internalValue, setInternalValue] =
|
|
2734
|
+
const [internalValue, setInternalValue] = useState9(() => {
|
|
2670
2735
|
if (defaultValue) {
|
|
2671
2736
|
return new Set(Array.isArray(defaultValue) ? defaultValue : [defaultValue]);
|
|
2672
2737
|
}
|
|
@@ -2674,7 +2739,7 @@ var Accordion = React35.forwardRef(
|
|
|
2674
2739
|
});
|
|
2675
2740
|
const isControlled = value !== void 0;
|
|
2676
2741
|
const expandedItems = isControlled ? new Set(Array.isArray(value) ? value : [value]) : internalValue;
|
|
2677
|
-
const toggleItem =
|
|
2742
|
+
const toggleItem = useCallback10(
|
|
2678
2743
|
(id) => {
|
|
2679
2744
|
const newSet = new Set(expandedItems);
|
|
2680
2745
|
if (newSet.has(id)) {
|
|
@@ -2725,7 +2790,7 @@ var AccordionTrigger = React35.forwardRef(
|
|
|
2725
2790
|
({ children, className, ...props }, ref) => {
|
|
2726
2791
|
const { expandedItems, toggleItem } = useAccordionContext();
|
|
2727
2792
|
const itemContext = useContext4(AccordionItemContext);
|
|
2728
|
-
const baseId =
|
|
2793
|
+
const baseId = useId5();
|
|
2729
2794
|
if (!itemContext) {
|
|
2730
2795
|
throw new Error("AccordionTrigger must be used within an AccordionItem");
|
|
2731
2796
|
}
|
|
@@ -2770,7 +2835,7 @@ var AccordionContent = React35.forwardRef(
|
|
|
2770
2835
|
({ children, className, ...props }, ref) => {
|
|
2771
2836
|
const { expandedItems } = useAccordionContext();
|
|
2772
2837
|
const itemContext = useContext4(AccordionItemContext);
|
|
2773
|
-
const baseId =
|
|
2838
|
+
const baseId = useId5();
|
|
2774
2839
|
if (!itemContext) {
|
|
2775
2840
|
throw new Error("AccordionContent must be used within an AccordionItem");
|
|
2776
2841
|
}
|
|
@@ -2800,12 +2865,12 @@ AccordionContent.displayName = "AccordionContent";
|
|
|
2800
2865
|
// src/components/Menu.tsx
|
|
2801
2866
|
import React36, {
|
|
2802
2867
|
createContext as createContext5,
|
|
2803
|
-
useCallback as
|
|
2868
|
+
useCallback as useCallback11,
|
|
2804
2869
|
useContext as useContext5,
|
|
2805
2870
|
useEffect as useEffect5,
|
|
2806
|
-
useId as
|
|
2807
|
-
useRef as
|
|
2808
|
-
useState as
|
|
2871
|
+
useId as useId6,
|
|
2872
|
+
useRef as useRef5,
|
|
2873
|
+
useState as useState10
|
|
2809
2874
|
} from "react";
|
|
2810
2875
|
var MenuContext = createContext5(null);
|
|
2811
2876
|
function useMenuContext() {
|
|
@@ -2816,11 +2881,11 @@ function useMenuContext() {
|
|
|
2816
2881
|
return context;
|
|
2817
2882
|
}
|
|
2818
2883
|
var Menu = ({ children, open, onOpenChange }) => {
|
|
2819
|
-
const [internalOpen, setInternalOpen] =
|
|
2884
|
+
const [internalOpen, setInternalOpen] = useState10(false);
|
|
2820
2885
|
const isControlled = open !== void 0;
|
|
2821
2886
|
const isOpen = isControlled ? open : internalOpen;
|
|
2822
|
-
const baseId =
|
|
2823
|
-
const setIsOpen =
|
|
2887
|
+
const baseId = useId6();
|
|
2888
|
+
const setIsOpen = useCallback11(
|
|
2824
2889
|
(newOpen) => {
|
|
2825
2890
|
if (!isControlled) {
|
|
2826
2891
|
setInternalOpen(newOpen);
|
|
@@ -2872,55 +2937,42 @@ var MenuTrigger = React36.forwardRef(
|
|
|
2872
2937
|
}
|
|
2873
2938
|
);
|
|
2874
2939
|
MenuTrigger.displayName = "MenuTrigger";
|
|
2940
|
+
var MENU_ALIGN_CLASSES = {
|
|
2941
|
+
start: "left-0",
|
|
2942
|
+
center: "left-1/2 -translate-x-1/2",
|
|
2943
|
+
end: "right-0"
|
|
2944
|
+
};
|
|
2945
|
+
var MENU_SIDE_CLASSES = {
|
|
2946
|
+
top: "bottom-full mb-1",
|
|
2947
|
+
bottom: "top-full mt-1"
|
|
2948
|
+
};
|
|
2875
2949
|
var MenuContent = React36.forwardRef(
|
|
2876
2950
|
({ children, className, align = "start", side = "bottom", ...props }, ref) => {
|
|
2877
2951
|
const { isOpen, setIsOpen, triggerId, menuId } = useMenuContext();
|
|
2878
|
-
const menuRef =
|
|
2952
|
+
const menuRef = useRef5(null);
|
|
2953
|
+
const close = useCallback11(() => setIsOpen(false), [setIsOpen]);
|
|
2954
|
+
useEscapeKey(close, isOpen);
|
|
2879
2955
|
useEffect5(() => {
|
|
2880
2956
|
if (!isOpen) {
|
|
2881
2957
|
return;
|
|
2882
2958
|
}
|
|
2883
2959
|
const handleClickOutside = (e) => {
|
|
2960
|
+
const target = e.target;
|
|
2884
2961
|
const trigger = document.getElementById(triggerId);
|
|
2885
|
-
if (menuRef.current && !menuRef.current.contains(
|
|
2886
|
-
setIsOpen(false);
|
|
2887
|
-
}
|
|
2888
|
-
};
|
|
2889
|
-
const handleEscape = (e) => {
|
|
2890
|
-
if (e.key === "Escape") {
|
|
2962
|
+
if (menuRef.current && !menuRef.current.contains(target) && !trigger?.contains(target)) {
|
|
2891
2963
|
setIsOpen(false);
|
|
2892
2964
|
}
|
|
2893
2965
|
};
|
|
2894
2966
|
document.addEventListener("mousedown", handleClickOutside);
|
|
2895
|
-
document.
|
|
2896
|
-
return () => {
|
|
2897
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
2898
|
-
document.removeEventListener("keydown", handleEscape);
|
|
2899
|
-
};
|
|
2967
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2900
2968
|
}, [isOpen, setIsOpen, triggerId]);
|
|
2901
2969
|
if (!isOpen) {
|
|
2902
2970
|
return null;
|
|
2903
2971
|
}
|
|
2904
|
-
const alignmentClasses = {
|
|
2905
|
-
start: "left-0",
|
|
2906
|
-
center: "left-1/2 -translate-x-1/2",
|
|
2907
|
-
end: "right-0"
|
|
2908
|
-
};
|
|
2909
|
-
const sideClasses = {
|
|
2910
|
-
top: "bottom-full mb-1",
|
|
2911
|
-
bottom: "top-full mt-1"
|
|
2912
|
-
};
|
|
2913
2972
|
return /* @__PURE__ */ React36.createElement(
|
|
2914
2973
|
"div",
|
|
2915
2974
|
{
|
|
2916
|
-
ref: (
|
|
2917
|
-
menuRef.current = node;
|
|
2918
|
-
if (typeof ref === "function") {
|
|
2919
|
-
ref(node);
|
|
2920
|
-
} else if (ref) {
|
|
2921
|
-
ref.current = node;
|
|
2922
|
-
}
|
|
2923
|
-
},
|
|
2975
|
+
ref: composeRefs(menuRef, ref),
|
|
2924
2976
|
id: menuId,
|
|
2925
2977
|
role: "menu",
|
|
2926
2978
|
"aria-labelledby": triggerId,
|
|
@@ -2928,8 +2980,8 @@ var MenuContent = React36.forwardRef(
|
|
|
2928
2980
|
"absolute z-50 min-w-40 py-1",
|
|
2929
2981
|
"bg-charcoal border border-ash shadow-lg",
|
|
2930
2982
|
"animate-fade-in",
|
|
2931
|
-
|
|
2932
|
-
|
|
2983
|
+
MENU_ALIGN_CLASSES[align],
|
|
2984
|
+
MENU_SIDE_CLASSES[side],
|
|
2933
2985
|
className
|
|
2934
2986
|
),
|
|
2935
2987
|
...props
|
|
@@ -3653,12 +3705,19 @@ function SquareLoaderIcon({ className, ...props }) {
|
|
|
3653
3705
|
}
|
|
3654
3706
|
|
|
3655
3707
|
// src/components/Message.tsx
|
|
3656
|
-
import React55, { useEffect as useEffect6, useRef as
|
|
3708
|
+
import React55, { useCallback as useCallback12, useEffect as useEffect6, useRef as useRef6, useState as useState11 } from "react";
|
|
3709
|
+
import { Check as Check3, ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight3, Copy, GitBranch, Pencil, RotateCcw, Send, X as X5 } from "lucide-react";
|
|
3657
3710
|
|
|
3658
3711
|
// src/components/MarkdownContent.tsx
|
|
3659
3712
|
import React54, { useMemo } from "react";
|
|
3660
3713
|
import DOMPurify from "dompurify";
|
|
3661
3714
|
import { marked } from "marked";
|
|
3715
|
+
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
|
|
3716
|
+
if (node.tagName === "A") {
|
|
3717
|
+
node.setAttribute("target", "_blank");
|
|
3718
|
+
node.setAttribute("rel", "noopener noreferrer");
|
|
3719
|
+
}
|
|
3720
|
+
});
|
|
3662
3721
|
var DEFAULT_SANITIZE_CONFIG = {
|
|
3663
3722
|
ALLOWED_TAGS: [
|
|
3664
3723
|
"h1",
|
|
@@ -3726,16 +3785,6 @@ var DEFAULT_SANITIZE_CONFIG = {
|
|
|
3726
3785
|
ADD_ATTR: ["target", "rel"],
|
|
3727
3786
|
ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto|tel):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i
|
|
3728
3787
|
};
|
|
3729
|
-
function useDOMPurifySetup() {
|
|
3730
|
-
useMemo(() => {
|
|
3731
|
-
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
|
|
3732
|
-
if (node.tagName === "A") {
|
|
3733
|
-
node.setAttribute("target", "_blank");
|
|
3734
|
-
node.setAttribute("rel", "noopener noreferrer");
|
|
3735
|
-
}
|
|
3736
|
-
});
|
|
3737
|
-
}, []);
|
|
3738
|
-
}
|
|
3739
3788
|
var CURSOR_BASE_CLASSES = "inline-block bg-current animate-cursor-blink w-0.5 h-cursor translate-y-cursor-offset";
|
|
3740
3789
|
function injectStreamingCursor(html, cursorClassName) {
|
|
3741
3790
|
if (!html.trim()) {
|
|
@@ -3765,7 +3814,6 @@ function injectStreamingCursor(html, cursorClassName) {
|
|
|
3765
3814
|
}
|
|
3766
3815
|
var MarkdownContent = React54.forwardRef(
|
|
3767
3816
|
({ className, content, isMarkdown = true, sanitizeConfig, isStreaming, cursorClassName, ...rest }, ref) => {
|
|
3768
|
-
useDOMPurifySetup();
|
|
3769
3817
|
const sanitizedHtml = useMemo(() => {
|
|
3770
3818
|
if (!content && !isStreaming) {
|
|
3771
3819
|
return "";
|
|
@@ -3787,7 +3835,7 @@ var MarkdownContent = React54.forwardRef(
|
|
|
3787
3835
|
return injectStreamingCursor(sanitized, cursorClassName);
|
|
3788
3836
|
}
|
|
3789
3837
|
return sanitized;
|
|
3790
|
-
}, [content, sanitizeConfig, isStreaming, cursorClassName]);
|
|
3838
|
+
}, [content, isMarkdown, sanitizeConfig, isStreaming, cursorClassName]);
|
|
3791
3839
|
return /* @__PURE__ */ React54.createElement(
|
|
3792
3840
|
"div",
|
|
3793
3841
|
{
|
|
@@ -3802,162 +3850,32 @@ var MarkdownContent = React54.forwardRef(
|
|
|
3802
3850
|
MarkdownContent.displayName = "MarkdownContent";
|
|
3803
3851
|
|
|
3804
3852
|
// src/components/Message.tsx
|
|
3805
|
-
var
|
|
3853
|
+
var VARIANT_STYLES3 = {
|
|
3806
3854
|
user: "bg-gold text-obsidian ml-auto",
|
|
3807
3855
|
assistant: "bg-charcoal border border-ash text-white mr-auto"
|
|
3808
3856
|
};
|
|
3809
|
-
var
|
|
3810
|
-
"
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
onClick,
|
|
3814
|
-
disabled,
|
|
3815
|
-
className: cx(
|
|
3816
|
-
"p-1.5 text-silver/60 hover:text-silver transition-colors duration-150",
|
|
3817
|
-
"hover:bg-white/5",
|
|
3818
|
-
"disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent",
|
|
3819
|
-
className
|
|
3820
|
-
),
|
|
3821
|
-
"aria-label": label
|
|
3822
|
-
},
|
|
3823
|
-
children
|
|
3824
|
-
);
|
|
3825
|
-
var CopyIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3826
|
-
"svg",
|
|
3827
|
-
{
|
|
3828
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3829
|
-
viewBox: "0 0 24 24",
|
|
3830
|
-
fill: "none",
|
|
3831
|
-
stroke: "currentColor",
|
|
3832
|
-
strokeWidth: "2",
|
|
3833
|
-
strokeLinecap: "round",
|
|
3834
|
-
strokeLinejoin: "round",
|
|
3835
|
-
className: "w-3.5 h-3.5"
|
|
3836
|
-
},
|
|
3837
|
-
/* @__PURE__ */ React55.createElement("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
|
|
3838
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
|
|
3839
|
-
);
|
|
3840
|
-
var CheckIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3841
|
-
"svg",
|
|
3842
|
-
{
|
|
3843
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3844
|
-
viewBox: "0 0 24 24",
|
|
3845
|
-
fill: "none",
|
|
3846
|
-
stroke: "currentColor",
|
|
3847
|
-
strokeWidth: "2",
|
|
3848
|
-
strokeLinecap: "round",
|
|
3849
|
-
strokeLinejoin: "round",
|
|
3850
|
-
className: "w-3.5 h-3.5 text-success"
|
|
3851
|
-
},
|
|
3852
|
-
/* @__PURE__ */ React55.createElement("polyline", { points: "20 6 9 17 4 12" })
|
|
3853
|
-
);
|
|
3854
|
-
var PencilIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3855
|
-
"svg",
|
|
3856
|
-
{
|
|
3857
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3858
|
-
viewBox: "0 0 24 24",
|
|
3859
|
-
fill: "none",
|
|
3860
|
-
stroke: "currentColor",
|
|
3861
|
-
strokeWidth: "2",
|
|
3862
|
-
strokeLinecap: "round",
|
|
3863
|
-
strokeLinejoin: "round",
|
|
3864
|
-
className: "w-3.5 h-3.5"
|
|
3865
|
-
},
|
|
3866
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }),
|
|
3867
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m15 5 4 4" })
|
|
3868
|
-
);
|
|
3869
|
-
var RetryIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3870
|
-
"svg",
|
|
3871
|
-
{
|
|
3872
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3873
|
-
viewBox: "0 0 24 24",
|
|
3874
|
-
fill: "none",
|
|
3875
|
-
stroke: "currentColor",
|
|
3876
|
-
strokeWidth: "2",
|
|
3877
|
-
strokeLinecap: "round",
|
|
3878
|
-
strokeLinejoin: "round",
|
|
3879
|
-
className: "w-3.5 h-3.5"
|
|
3880
|
-
},
|
|
3881
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
|
|
3882
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M21 3v5h-5" }),
|
|
3883
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
|
|
3884
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M8 16H3v5" })
|
|
3885
|
-
);
|
|
3886
|
-
var ChevronLeftIcon2 = () => /* @__PURE__ */ React55.createElement(
|
|
3887
|
-
"svg",
|
|
3888
|
-
{
|
|
3889
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3890
|
-
viewBox: "0 0 24 24",
|
|
3891
|
-
fill: "none",
|
|
3892
|
-
stroke: "currentColor",
|
|
3893
|
-
strokeWidth: "2",
|
|
3894
|
-
strokeLinecap: "round",
|
|
3895
|
-
strokeLinejoin: "round",
|
|
3896
|
-
className: "w-3 h-3"
|
|
3897
|
-
},
|
|
3898
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m15 18-6-6 6-6" })
|
|
3899
|
-
);
|
|
3900
|
-
var ChevronRightIcon2 = () => /* @__PURE__ */ React55.createElement(
|
|
3901
|
-
"svg",
|
|
3902
|
-
{
|
|
3903
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3904
|
-
viewBox: "0 0 24 24",
|
|
3905
|
-
fill: "none",
|
|
3906
|
-
stroke: "currentColor",
|
|
3907
|
-
strokeWidth: "2",
|
|
3908
|
-
strokeLinecap: "round",
|
|
3909
|
-
strokeLinejoin: "round",
|
|
3910
|
-
className: "w-3 h-3"
|
|
3911
|
-
},
|
|
3912
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m9 18 6-6-6-6" })
|
|
3857
|
+
var ACTION_BUTTON_CLASSES = cx(
|
|
3858
|
+
"p-1.5 text-silver/60 hover:text-silver transition-colors duration-150",
|
|
3859
|
+
"hover:bg-white/5",
|
|
3860
|
+
"disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent"
|
|
3913
3861
|
);
|
|
3914
|
-
var
|
|
3915
|
-
"
|
|
3916
|
-
|
|
3917
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3918
|
-
viewBox: "0 0 24 24",
|
|
3919
|
-
fill: "none",
|
|
3920
|
-
stroke: "currentColor",
|
|
3921
|
-
strokeWidth: "2",
|
|
3922
|
-
strokeLinecap: "round",
|
|
3923
|
-
strokeLinejoin: "round",
|
|
3924
|
-
className: "w-3 h-3 mr-0.5 text-silver/50"
|
|
3925
|
-
},
|
|
3926
|
-
/* @__PURE__ */ React55.createElement("line", { x1: "6", x2: "6", y1: "3", y2: "15" }),
|
|
3927
|
-
/* @__PURE__ */ React55.createElement("circle", { cx: "18", cy: "6", r: "3" }),
|
|
3928
|
-
/* @__PURE__ */ React55.createElement("circle", { cx: "6", cy: "18", r: "3" }),
|
|
3929
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })
|
|
3930
|
-
);
|
|
3931
|
-
var XIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3932
|
-
"svg",
|
|
3933
|
-
{
|
|
3934
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3935
|
-
viewBox: "0 0 24 24",
|
|
3936
|
-
fill: "none",
|
|
3937
|
-
stroke: "currentColor",
|
|
3938
|
-
strokeWidth: "2",
|
|
3939
|
-
strokeLinecap: "round",
|
|
3940
|
-
strokeLinejoin: "round",
|
|
3941
|
-
className: "w-4 h-4"
|
|
3942
|
-
},
|
|
3943
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M18 6 6 18" }),
|
|
3944
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m6 6 12 12" })
|
|
3945
|
-
);
|
|
3946
|
-
var SendIcon = () => /* @__PURE__ */ React55.createElement(
|
|
3947
|
-
"svg",
|
|
3948
|
-
{
|
|
3949
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3950
|
-
viewBox: "0 0 24 24",
|
|
3951
|
-
fill: "none",
|
|
3952
|
-
stroke: "currentColor",
|
|
3953
|
-
strokeWidth: "2",
|
|
3954
|
-
strokeLinecap: "round",
|
|
3955
|
-
strokeLinejoin: "round",
|
|
3956
|
-
className: "w-4 h-4"
|
|
3957
|
-
},
|
|
3958
|
-
/* @__PURE__ */ React55.createElement("path", { d: "m22 2-7 20-4-9-9-4Z" }),
|
|
3959
|
-
/* @__PURE__ */ React55.createElement("path", { d: "M22 2 11 13" })
|
|
3862
|
+
var BRANCH_BUTTON_CLASSES = cx(
|
|
3863
|
+
"p-0.5 hover:text-white hover:bg-white/10 transition-colors",
|
|
3864
|
+
"disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
|
|
3960
3865
|
);
|
|
3866
|
+
function ActionButton({ onClick, label, children, disabled }) {
|
|
3867
|
+
return /* @__PURE__ */ React55.createElement(
|
|
3868
|
+
"button",
|
|
3869
|
+
{
|
|
3870
|
+
type: "button",
|
|
3871
|
+
onClick,
|
|
3872
|
+
disabled,
|
|
3873
|
+
className: ACTION_BUTTON_CLASSES,
|
|
3874
|
+
"aria-label": label
|
|
3875
|
+
},
|
|
3876
|
+
children
|
|
3877
|
+
);
|
|
3878
|
+
}
|
|
3961
3879
|
var Message = React55.forwardRef(
|
|
3962
3880
|
({
|
|
3963
3881
|
variant = "assistant",
|
|
@@ -3970,10 +3888,10 @@ var Message = React55.forwardRef(
|
|
|
3970
3888
|
...rest
|
|
3971
3889
|
}, ref) => {
|
|
3972
3890
|
const isUser = variant === "user";
|
|
3973
|
-
const
|
|
3974
|
-
const [isEditing, setIsEditing] =
|
|
3975
|
-
const [editValue, setEditValue] =
|
|
3976
|
-
const textareaRef =
|
|
3891
|
+
const { copied, copy } = useCopyToClipboard();
|
|
3892
|
+
const [isEditing, setIsEditing] = useState11(false);
|
|
3893
|
+
const [editValue, setEditValue] = useState11(typeof content === "string" ? content : "");
|
|
3894
|
+
const textareaRef = useRef6(null);
|
|
3977
3895
|
const showBranchNav = branchInfo && branchInfo.total > 1;
|
|
3978
3896
|
const showActions = actions && !hideActions && !isStreaming;
|
|
3979
3897
|
useEffect6(() => {
|
|
@@ -3985,25 +3903,11 @@ var Message = React55.forwardRef(
|
|
|
3985
3903
|
textarea.setSelectionRange(textarea.value.length, textarea.value.length);
|
|
3986
3904
|
}
|
|
3987
3905
|
}, [isEditing]);
|
|
3988
|
-
const handleCopy =
|
|
3989
|
-
if (typeof content
|
|
3990
|
-
|
|
3991
|
-
}
|
|
3992
|
-
try {
|
|
3993
|
-
await navigator.clipboard.writeText(content);
|
|
3994
|
-
setCopied(true);
|
|
3995
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
3996
|
-
} catch {
|
|
3997
|
-
const textArea = document.createElement("textarea");
|
|
3998
|
-
textArea.value = content;
|
|
3999
|
-
document.body.appendChild(textArea);
|
|
4000
|
-
textArea.select();
|
|
4001
|
-
document.execCommand("copy");
|
|
4002
|
-
document.body.removeChild(textArea);
|
|
4003
|
-
setCopied(true);
|
|
4004
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
3906
|
+
const handleCopy = useCallback12(() => {
|
|
3907
|
+
if (typeof content === "string") {
|
|
3908
|
+
void copy(content);
|
|
4005
3909
|
}
|
|
4006
|
-
};
|
|
3910
|
+
}, [copy, content]);
|
|
4007
3911
|
const handleStartEdit = () => {
|
|
4008
3912
|
if (typeof content === "string") {
|
|
4009
3913
|
setEditValue(content);
|
|
@@ -4066,7 +3970,7 @@ var Message = React55.forwardRef(
|
|
|
4066
3970
|
className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors",
|
|
4067
3971
|
"aria-label": "Cancel edit"
|
|
4068
3972
|
},
|
|
4069
|
-
/* @__PURE__ */ React55.createElement(
|
|
3973
|
+
/* @__PURE__ */ React55.createElement(X5, { className: "w-4 h-4" })
|
|
4070
3974
|
), /* @__PURE__ */ React55.createElement(
|
|
4071
3975
|
"button",
|
|
4072
3976
|
{
|
|
@@ -4076,13 +3980,13 @@ var Message = React55.forwardRef(
|
|
|
4076
3980
|
className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors disabled:opacity-30",
|
|
4077
3981
|
"aria-label": "Submit edit"
|
|
4078
3982
|
},
|
|
4079
|
-
/* @__PURE__ */ React55.createElement(
|
|
3983
|
+
/* @__PURE__ */ React55.createElement(Send, { className: "w-4 h-4" })
|
|
4080
3984
|
)))) : /* @__PURE__ */ React55.createElement(
|
|
4081
3985
|
"div",
|
|
4082
3986
|
{
|
|
4083
3987
|
className: cx(
|
|
4084
3988
|
"px-3 py-2 w-fit max-w-11/12",
|
|
4085
|
-
|
|
3989
|
+
VARIANT_STYLES3[variant]
|
|
4086
3990
|
)
|
|
4087
3991
|
},
|
|
4088
3992
|
typeof content === "string" ? /* @__PURE__ */ React55.createElement(
|
|
@@ -4104,33 +4008,27 @@ var Message = React55.forwardRef(
|
|
|
4104
4008
|
onClick: handleCopy,
|
|
4105
4009
|
label: copied ? "Copied!" : "Copy message"
|
|
4106
4010
|
},
|
|
4107
|
-
copied ? /* @__PURE__ */ React55.createElement(
|
|
4108
|
-
), isUser && actions.onEdit && typeof content === "string" && /* @__PURE__ */ React55.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React55.createElement(
|
|
4011
|
+
copied ? /* @__PURE__ */ React55.createElement(Check3, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ React55.createElement(Copy, { className: "w-3.5 h-3.5" })
|
|
4012
|
+
), isUser && actions.onEdit && typeof content === "string" && /* @__PURE__ */ React55.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React55.createElement(Pencil, { className: "w-3.5 h-3.5" })), !isUser && actions.onRetry && /* @__PURE__ */ React55.createElement(ActionButton, { onClick: actions.onRetry, label: "Regenerate response" }, /* @__PURE__ */ React55.createElement(RotateCcw, { className: "w-3.5 h-3.5" })), showBranchNav && /* @__PURE__ */ React55.createElement(React55.Fragment, null, /* @__PURE__ */ React55.createElement("div", { className: "w-px h-4 bg-ash/40 mx-1" }), /* @__PURE__ */ React55.createElement("div", { className: "flex items-center gap-0.5 text-silver/70" }, /* @__PURE__ */ React55.createElement(GitBranch, { className: "w-3 h-3 mr-0.5 text-silver/50" }), /* @__PURE__ */ React55.createElement(
|
|
4109
4013
|
"button",
|
|
4110
4014
|
{
|
|
4111
4015
|
type: "button",
|
|
4112
4016
|
onClick: branchInfo.onPrevious,
|
|
4113
4017
|
disabled: branchInfo.current <= 1,
|
|
4114
|
-
className:
|
|
4115
|
-
"p-0.5 hover:text-white hover:bg-white/10 transition-colors",
|
|
4116
|
-
"disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
|
|
4117
|
-
),
|
|
4018
|
+
className: BRANCH_BUTTON_CLASSES,
|
|
4118
4019
|
"aria-label": "Previous branch"
|
|
4119
4020
|
},
|
|
4120
|
-
/* @__PURE__ */ React55.createElement(
|
|
4021
|
+
/* @__PURE__ */ React55.createElement(ChevronLeft2, { className: "w-3 h-3" })
|
|
4121
4022
|
), /* @__PURE__ */ React55.createElement("span", { className: "text-xs tabular-nums min-w-6 text-center" }, branchInfo.current, "/", branchInfo.total), /* @__PURE__ */ React55.createElement(
|
|
4122
4023
|
"button",
|
|
4123
4024
|
{
|
|
4124
4025
|
type: "button",
|
|
4125
4026
|
onClick: branchInfo.onNext,
|
|
4126
4027
|
disabled: branchInfo.current >= branchInfo.total,
|
|
4127
|
-
className:
|
|
4128
|
-
"p-0.5 hover:text-white hover:bg-white/10 transition-colors",
|
|
4129
|
-
"disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
|
|
4130
|
-
),
|
|
4028
|
+
className: BRANCH_BUTTON_CLASSES,
|
|
4131
4029
|
"aria-label": "Next branch"
|
|
4132
4030
|
},
|
|
4133
|
-
/* @__PURE__ */ React55.createElement(
|
|
4031
|
+
/* @__PURE__ */ React55.createElement(ChevronRight3, { className: "w-3 h-3" })
|
|
4134
4032
|
))))
|
|
4135
4033
|
);
|
|
4136
4034
|
}
|
|
@@ -4141,7 +4039,7 @@ Message.displayName = "Message";
|
|
|
4141
4039
|
import React56 from "react";
|
|
4142
4040
|
var StreamingCursor = React56.forwardRef(
|
|
4143
4041
|
({ className, variant = "line", ...rest }, ref) => {
|
|
4144
|
-
const
|
|
4042
|
+
const variantStyles2 = {
|
|
4145
4043
|
block: "w-2.5 h-cursor translate-y-cursor-offset",
|
|
4146
4044
|
line: "w-0.5 h-cursor translate-y-cursor-offset",
|
|
4147
4045
|
underscore: "w-2.5 h-0.5 self-end mb-0.5"
|
|
@@ -4152,7 +4050,7 @@ var StreamingCursor = React56.forwardRef(
|
|
|
4152
4050
|
ref,
|
|
4153
4051
|
className: cx(
|
|
4154
4052
|
"inline-block bg-current animate-cursor-blink",
|
|
4155
|
-
|
|
4053
|
+
variantStyles2[variant],
|
|
4156
4054
|
className
|
|
4157
4055
|
),
|
|
4158
4056
|
"aria-hidden": "true",
|
|
@@ -4164,18 +4062,18 @@ var StreamingCursor = React56.forwardRef(
|
|
|
4164
4062
|
StreamingCursor.displayName = "StreamingCursor";
|
|
4165
4063
|
|
|
4166
4064
|
// src/components/chat/ChatInterface.tsx
|
|
4167
|
-
import
|
|
4065
|
+
import React76, { useCallback as useCallback22, useEffect as useEffect16, useMemo as useMemo5, useRef as useRef15, useState as useState22 } from "react";
|
|
4168
4066
|
|
|
4169
4067
|
// src/components/chat/ChatView.tsx
|
|
4170
|
-
import
|
|
4068
|
+
import React60, { useEffect as useEffect9 } from "react";
|
|
4171
4069
|
|
|
4172
4070
|
// src/components/chat/hooks/useScrollAnchor.ts
|
|
4173
|
-
import { useCallback as
|
|
4071
|
+
import { useCallback as useCallback13, useRef as useRef7 } from "react";
|
|
4174
4072
|
function useScrollAnchor(options = {}) {
|
|
4175
4073
|
const { behavior = "smooth", block = "start" } = options;
|
|
4176
|
-
const containerRef =
|
|
4177
|
-
const anchorRef =
|
|
4178
|
-
const scrollToAnchor =
|
|
4074
|
+
const containerRef = useRef7(null);
|
|
4075
|
+
const anchorRef = useRef7(null);
|
|
4076
|
+
const scrollToAnchor = useCallback13(() => {
|
|
4179
4077
|
const el = anchorRef.current;
|
|
4180
4078
|
if (!el) {
|
|
4181
4079
|
return;
|
|
@@ -4186,7 +4084,7 @@ function useScrollAnchor(options = {}) {
|
|
|
4186
4084
|
});
|
|
4187
4085
|
});
|
|
4188
4086
|
}, [behavior, block]);
|
|
4189
|
-
const scrollToBottom =
|
|
4087
|
+
const scrollToBottom = useCallback13(() => {
|
|
4190
4088
|
const container = containerRef.current;
|
|
4191
4089
|
if (!container) {
|
|
4192
4090
|
return;
|
|
@@ -4197,7 +4095,7 @@ function useScrollAnchor(options = {}) {
|
|
|
4197
4095
|
container.scrollTop = container.scrollHeight;
|
|
4198
4096
|
}
|
|
4199
4097
|
}, [behavior]);
|
|
4200
|
-
const isScrolledToBottom =
|
|
4098
|
+
const isScrolledToBottom = useCallback13(() => {
|
|
4201
4099
|
const container = containerRef.current;
|
|
4202
4100
|
if (!container) {
|
|
4203
4101
|
return true;
|
|
@@ -4216,15 +4114,15 @@ function useScrollAnchor(options = {}) {
|
|
|
4216
4114
|
}
|
|
4217
4115
|
|
|
4218
4116
|
// src/components/chat/hooks/useAdaptiveSpacer.ts
|
|
4219
|
-
import { useCallback as
|
|
4117
|
+
import { useCallback as useCallback14, useEffect as useEffect7, useRef as useRef8, useState as useState12 } from "react";
|
|
4220
4118
|
function useAdaptiveSpacer(options = {}) {
|
|
4221
4119
|
const { minHeight = 0, containerRef: externalContainerRef, anchorRef } = options;
|
|
4222
|
-
const internalContainerRef =
|
|
4120
|
+
const internalContainerRef = useRef8(null);
|
|
4223
4121
|
const containerRef = externalContainerRef ?? internalContainerRef;
|
|
4224
|
-
const contentRef =
|
|
4225
|
-
const spacerRef =
|
|
4226
|
-
const [spacerHeight, setSpacerHeight] =
|
|
4227
|
-
const recalculate =
|
|
4122
|
+
const contentRef = useRef8(null);
|
|
4123
|
+
const spacerRef = useRef8(null);
|
|
4124
|
+
const [spacerHeight, setSpacerHeight] = useState12(0);
|
|
4125
|
+
const recalculate = useCallback14(() => {
|
|
4228
4126
|
const container = containerRef.current;
|
|
4229
4127
|
const content = contentRef.current;
|
|
4230
4128
|
if (!container || !content) {
|
|
@@ -4283,7 +4181,7 @@ function useAdaptiveSpacer(options = {}) {
|
|
|
4283
4181
|
}
|
|
4284
4182
|
|
|
4285
4183
|
// src/components/chat/ThinkingIndicator.tsx
|
|
4286
|
-
import React57, { useEffect as useEffect8, useState as
|
|
4184
|
+
import React57, { useEffect as useEffect8, useState as useState13 } from "react";
|
|
4287
4185
|
var THINKING_PHRASES = [
|
|
4288
4186
|
"Consulting the ancient tomes...",
|
|
4289
4187
|
"Parsing the ineffable...",
|
|
@@ -4307,22 +4205,29 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4307
4205
|
className,
|
|
4308
4206
|
...rest
|
|
4309
4207
|
}, ref) => {
|
|
4310
|
-
const [currentIndex, setCurrentIndex] =
|
|
4208
|
+
const [currentIndex, setCurrentIndex] = useState13(
|
|
4311
4209
|
() => Math.floor(Math.random() * phrases.length)
|
|
4312
4210
|
);
|
|
4313
|
-
const [isTransitioning, setIsTransitioning] =
|
|
4211
|
+
const [isTransitioning, setIsTransitioning] = useState13(false);
|
|
4314
4212
|
useEffect8(() => {
|
|
4315
4213
|
if (!isVisible || phrases.length <= 1) {
|
|
4316
4214
|
return;
|
|
4317
4215
|
}
|
|
4216
|
+
let fadeTimeout = null;
|
|
4318
4217
|
const interval = setInterval(() => {
|
|
4319
4218
|
setIsTransitioning(true);
|
|
4320
|
-
setTimeout(() => {
|
|
4219
|
+
fadeTimeout = setTimeout(() => {
|
|
4321
4220
|
setCurrentIndex((prev) => (prev + 1) % phrases.length);
|
|
4322
4221
|
setIsTransitioning(false);
|
|
4222
|
+
fadeTimeout = null;
|
|
4323
4223
|
}, 200);
|
|
4324
4224
|
}, phraseInterval);
|
|
4325
|
-
return () =>
|
|
4225
|
+
return () => {
|
|
4226
|
+
clearInterval(interval);
|
|
4227
|
+
if (fadeTimeout !== null) {
|
|
4228
|
+
clearTimeout(fadeTimeout);
|
|
4229
|
+
}
|
|
4230
|
+
};
|
|
4326
4231
|
}, [isVisible, phrases.length, phraseInterval]);
|
|
4327
4232
|
if (!isVisible) {
|
|
4328
4233
|
return null;
|
|
@@ -4375,73 +4280,250 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4375
4280
|
);
|
|
4376
4281
|
ThinkingIndicator.displayName = "ThinkingIndicator";
|
|
4377
4282
|
|
|
4378
|
-
// src/components/chat/
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4283
|
+
// src/components/chat/Checkpoint.tsx
|
|
4284
|
+
import React58 from "react";
|
|
4285
|
+
import {
|
|
4286
|
+
ArrowLeft,
|
|
4287
|
+
ChevronLeft as ChevronLeft3,
|
|
4288
|
+
ChevronRight as ChevronRight4,
|
|
4289
|
+
GitBranch as GitBranch2,
|
|
4290
|
+
GitCommitVertical,
|
|
4291
|
+
GitMerge,
|
|
4292
|
+
PencilLine
|
|
4293
|
+
} from "lucide-react";
|
|
4294
|
+
var KIND_ICONS = {
|
|
4295
|
+
task: GitBranch2,
|
|
4296
|
+
submit: GitMerge,
|
|
4297
|
+
rename: PencilLine,
|
|
4298
|
+
init: GitCommitVertical
|
|
4299
|
+
};
|
|
4300
|
+
var KIND_ARIA_LABELS = {
|
|
4301
|
+
task: "Task checkpoint",
|
|
4302
|
+
submit: "Submit checkpoint",
|
|
4303
|
+
rename: "Rename checkpoint",
|
|
4304
|
+
init: "Project head checkpoint"
|
|
4305
|
+
};
|
|
4306
|
+
var Checkpoint = React58.forwardRef(
|
|
4307
|
+
function Checkpoint2({ name, executionKind, status = "completed", isActive, muted, branchInfo, onJumpHere }, ref) {
|
|
4308
|
+
const KindIcon = KIND_ICONS[executionKind];
|
|
4309
|
+
const isFailed = status === "failed";
|
|
4310
|
+
const isCancelled = status === "cancelled";
|
|
4311
|
+
const isInteractive = !isActive && !!onJumpHere;
|
|
4312
|
+
const iconColor = isActive ? "text-gold" : isFailed ? "text-error-muted" : "text-silver/50";
|
|
4313
|
+
const nameClasses = cx(
|
|
4314
|
+
"transition-colors text-xs",
|
|
4315
|
+
isActive ? "text-silver font-medium" : isInteractive ? "text-silver/70 hover:text-white underline decoration-silver/30 underline-offset-4 decoration-dotted hover:decoration-silver/70" : "text-silver/50"
|
|
4316
|
+
);
|
|
4401
4317
|
return /* @__PURE__ */ React58.createElement(
|
|
4402
4318
|
"div",
|
|
4403
4319
|
{
|
|
4404
|
-
ref
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
if (typeof ref === "function") {
|
|
4408
|
-
ref(node);
|
|
4409
|
-
} else if (ref) {
|
|
4410
|
-
ref.current = node;
|
|
4411
|
-
}
|
|
4412
|
-
},
|
|
4413
|
-
onScroll,
|
|
4320
|
+
ref,
|
|
4321
|
+
role: "group",
|
|
4322
|
+
"aria-label": KIND_ARIA_LABELS[executionKind],
|
|
4414
4323
|
className: cx(
|
|
4415
|
-
"
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
),
|
|
4419
|
-
...rest
|
|
4324
|
+
"group/checkpoint flex items-center gap-2 py-1.5 select-none",
|
|
4325
|
+
muted && "opacity-60"
|
|
4326
|
+
)
|
|
4420
4327
|
},
|
|
4421
|
-
/* @__PURE__ */ React58.createElement(
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4328
|
+
/* @__PURE__ */ React58.createElement(KindIcon, { className: cx("w-3.5 h-3.5 shrink-0", iconColor), "aria-hidden": "true" }),
|
|
4329
|
+
/* @__PURE__ */ React58.createElement(
|
|
4330
|
+
"button",
|
|
4331
|
+
{
|
|
4332
|
+
type: "button",
|
|
4333
|
+
onClick: isInteractive ? onJumpHere : void 0,
|
|
4334
|
+
disabled: !isInteractive,
|
|
4335
|
+
className: cx(
|
|
4336
|
+
nameClasses,
|
|
4337
|
+
"truncate text-left",
|
|
4338
|
+
!isInteractive && "cursor-default"
|
|
4339
|
+
),
|
|
4340
|
+
"aria-label": isInteractive ? `Jump to checkpoint ${name}` : name
|
|
4341
|
+
},
|
|
4342
|
+
/* @__PURE__ */ React58.createElement("span", { className: "truncate" }, name),
|
|
4343
|
+
isFailed && /* @__PURE__ */ React58.createElement("span", { className: "ml-1.5 text-error-muted" }, "\xB7 failed"),
|
|
4344
|
+
isCancelled && /* @__PURE__ */ React58.createElement("span", { className: "ml-1.5 text-silver/40" }, "\xB7 cancelled")
|
|
4345
|
+
),
|
|
4346
|
+
isInteractive && /* @__PURE__ */ React58.createElement(
|
|
4347
|
+
"span",
|
|
4348
|
+
{
|
|
4349
|
+
className: cx(
|
|
4350
|
+
"ml-1 inline-flex items-center gap-1 text-xs text-silver/40",
|
|
4351
|
+
"opacity-0 group-hover/checkpoint:opacity-100 transition-opacity",
|
|
4352
|
+
"pointer-events-none"
|
|
4353
|
+
),
|
|
4354
|
+
"aria-hidden": "true"
|
|
4355
|
+
},
|
|
4356
|
+
/* @__PURE__ */ React58.createElement(ArrowLeft, { className: "w-3 h-3" }),
|
|
4357
|
+
"Jump here"
|
|
4358
|
+
),
|
|
4359
|
+
branchInfo && branchInfo.total > 1 && /* @__PURE__ */ React58.createElement(
|
|
4360
|
+
"div",
|
|
4361
|
+
{
|
|
4362
|
+
className: "ml-auto inline-flex items-center gap-0.5 text-silver/70 text-xs",
|
|
4363
|
+
role: "navigation",
|
|
4364
|
+
"aria-label": "Switch sibling checkpoint"
|
|
4365
|
+
},
|
|
4366
|
+
/* @__PURE__ */ React58.createElement(
|
|
4367
|
+
"button",
|
|
4368
|
+
{
|
|
4369
|
+
type: "button",
|
|
4370
|
+
onClick: branchInfo.onPrevious,
|
|
4371
|
+
disabled: branchInfo.current <= 1,
|
|
4372
|
+
className: cx(
|
|
4373
|
+
"p-0.5 hover:text-white hover:bg-white/10 transition-colors",
|
|
4374
|
+
"disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
|
|
4375
|
+
),
|
|
4376
|
+
"aria-label": "Previous sibling checkpoint"
|
|
4377
|
+
},
|
|
4378
|
+
/* @__PURE__ */ React58.createElement(ChevronLeft3, { className: "w-3 h-3" })
|
|
4379
|
+
),
|
|
4380
|
+
/* @__PURE__ */ React58.createElement("span", { className: "tabular-nums min-w-6 text-center" }, branchInfo.current, "/", branchInfo.total),
|
|
4381
|
+
/* @__PURE__ */ React58.createElement(
|
|
4382
|
+
"button",
|
|
4383
|
+
{
|
|
4384
|
+
type: "button",
|
|
4385
|
+
onClick: branchInfo.onNext,
|
|
4386
|
+
disabled: branchInfo.current >= branchInfo.total,
|
|
4387
|
+
className: cx(
|
|
4388
|
+
"p-0.5 hover:text-white hover:bg-white/10 transition-colors",
|
|
4389
|
+
"disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
|
|
4390
|
+
),
|
|
4391
|
+
"aria-label": "Next sibling checkpoint"
|
|
4392
|
+
},
|
|
4393
|
+
/* @__PURE__ */ React58.createElement(ChevronRight4, { className: "w-3 h-3" })
|
|
4394
|
+
)
|
|
4395
|
+
)
|
|
4396
|
+
);
|
|
4397
|
+
}
|
|
4398
|
+
);
|
|
4399
|
+
Checkpoint.displayName = "Checkpoint";
|
|
4400
|
+
|
|
4401
|
+
// src/components/chat/GreyedDivider.tsx
|
|
4402
|
+
import React59 from "react";
|
|
4403
|
+
import { ArrowDown } from "lucide-react";
|
|
4404
|
+
function pluralize(n, singular, plural) {
|
|
4405
|
+
return `${n} ${n === 1 ? singular : plural}`;
|
|
4406
|
+
}
|
|
4407
|
+
function summarize(messageCount, checkpointCount) {
|
|
4408
|
+
const parts = [];
|
|
4409
|
+
if (messageCount > 0) {
|
|
4410
|
+
parts.push(pluralize(messageCount, "message", "messages"));
|
|
4411
|
+
}
|
|
4412
|
+
if (checkpointCount > 0) {
|
|
4413
|
+
parts.push(pluralize(checkpointCount, "checkpoint", "checkpoints"));
|
|
4414
|
+
}
|
|
4415
|
+
return parts.length > 0 ? parts.join(", ") : "no items";
|
|
4416
|
+
}
|
|
4417
|
+
var GreyedDivider = React59.forwardRef(
|
|
4418
|
+
function GreyedDivider2({ messageCount, checkpointCount, onJumpToLatest }, ref) {
|
|
4419
|
+
if (messageCount === 0 && checkpointCount === 0) {
|
|
4420
|
+
return null;
|
|
4421
|
+
}
|
|
4422
|
+
return /* @__PURE__ */ React59.createElement(
|
|
4423
|
+
"div",
|
|
4424
|
+
{
|
|
4425
|
+
ref,
|
|
4426
|
+
role: "separator",
|
|
4427
|
+
"aria-label": "Start of rewound timeline",
|
|
4428
|
+
className: "flex items-center gap-3 py-2 text-xs text-silver/50 select-none"
|
|
4429
|
+
},
|
|
4430
|
+
/* @__PURE__ */ React59.createElement("div", { className: "flex-1 h-px bg-ash/40", "aria-hidden": "true" }),
|
|
4431
|
+
/* @__PURE__ */ React59.createElement("span", { className: "inline-flex items-center gap-1.5 whitespace-nowrap" }, /* @__PURE__ */ React59.createElement(ArrowDown, { className: "w-3 h-3", "aria-hidden": "true" }), "Later in this conversation \xB7 ", summarize(messageCount, checkpointCount)),
|
|
4432
|
+
/* @__PURE__ */ React59.createElement("div", { className: "flex-1 h-px bg-ash/40", "aria-hidden": "true" }),
|
|
4433
|
+
onJumpToLatest && /* @__PURE__ */ React59.createElement(
|
|
4434
|
+
"button",
|
|
4435
|
+
{
|
|
4436
|
+
type: "button",
|
|
4437
|
+
onClick: onJumpToLatest,
|
|
4438
|
+
className: cx(
|
|
4439
|
+
"shrink-0 transition-colors",
|
|
4440
|
+
"text-silver/60 hover:text-white",
|
|
4441
|
+
"underline decoration-silver/30 underline-offset-4 decoration-dotted hover:decoration-silver/70"
|
|
4442
|
+
)
|
|
4443
|
+
},
|
|
4444
|
+
"Jump to latest \u2192"
|
|
4445
|
+
)
|
|
4446
|
+
);
|
|
4447
|
+
}
|
|
4448
|
+
);
|
|
4449
|
+
GreyedDivider.displayName = "GreyedDivider";
|
|
4450
|
+
|
|
4451
|
+
// src/components/chat/ChatView.tsx
|
|
4452
|
+
var ChatView = React60.forwardRef(
|
|
4453
|
+
function ChatView2({ items, latestUserMessageIndex, isStreaming, isThinking, onScroll, className, ...rest }, ref) {
|
|
4454
|
+
const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
|
|
4455
|
+
behavior: "smooth",
|
|
4456
|
+
block: "start"
|
|
4457
|
+
});
|
|
4458
|
+
const { contentRef, spacerRef, spacerHeight } = useAdaptiveSpacer({
|
|
4459
|
+
containerRef,
|
|
4460
|
+
anchorRef
|
|
4461
|
+
});
|
|
4462
|
+
const latestUserIdx = latestUserMessageIndex ?? items.reduceRight((found, item, idx) => {
|
|
4463
|
+
if (found === -1 && item.kind === "message" && item.variant === "user") {
|
|
4464
|
+
return idx;
|
|
4465
|
+
}
|
|
4466
|
+
return found;
|
|
4467
|
+
}, -1);
|
|
4468
|
+
useEffect9(() => {
|
|
4469
|
+
if (latestUserMessageIndex !== void 0 && latestUserMessageIndex >= 0) {
|
|
4470
|
+
scrollToAnchor();
|
|
4471
|
+
}
|
|
4472
|
+
}, [latestUserMessageIndex, scrollToAnchor]);
|
|
4473
|
+
const lastMessageIdx = items.reduceRight((found, item, idx) => {
|
|
4474
|
+
return found === -1 && item.kind === "message" ? idx : found;
|
|
4475
|
+
}, -1);
|
|
4476
|
+
const lastMessage = lastMessageIdx >= 0 ? items[lastMessageIdx] : null;
|
|
4477
|
+
const showThinking = isThinking && lastMessage?.kind === "message" && lastMessage.variant === "user";
|
|
4478
|
+
return /* @__PURE__ */ React60.createElement(
|
|
4479
|
+
"div",
|
|
4480
|
+
{
|
|
4481
|
+
ref: composeRefs(containerRef, ref),
|
|
4482
|
+
onScroll,
|
|
4483
|
+
className: cx(
|
|
4484
|
+
"flex flex-col w-full h-full overflow-y-auto scroll-smooth",
|
|
4485
|
+
"px-4 py-6 overscroll-contain",
|
|
4486
|
+
className
|
|
4487
|
+
),
|
|
4488
|
+
...rest
|
|
4489
|
+
},
|
|
4490
|
+
/* @__PURE__ */ React60.createElement("div", { ref: contentRef, className: "relative flex flex-col gap-3" }, items.map((item, index) => {
|
|
4491
|
+
const isAnchor = index === latestUserIdx;
|
|
4492
|
+
const wrapperRef = isAnchor ? anchorRef : void 0;
|
|
4493
|
+
const wrapperClass = isAnchor ? "scroll-mt-4" : void 0;
|
|
4494
|
+
if (item.kind === "divider") {
|
|
4495
|
+
const { kind: _k2, id: id2, ...dividerProps } = item;
|
|
4496
|
+
return /* @__PURE__ */ React60.createElement("div", { key: id2 }, /* @__PURE__ */ React60.createElement(GreyedDivider, { ...dividerProps }));
|
|
4497
|
+
}
|
|
4498
|
+
if (item.kind === "checkpoint") {
|
|
4499
|
+
const { kind: _k2, id: id2, ...checkpointProps } = item;
|
|
4500
|
+
return /* @__PURE__ */ React60.createElement("div", { key: id2, ref: wrapperRef, className: wrapperClass }, /* @__PURE__ */ React60.createElement(Checkpoint, { ...checkpointProps }));
|
|
4501
|
+
}
|
|
4502
|
+
const {
|
|
4503
|
+
kind: _k,
|
|
4504
|
+
id,
|
|
4505
|
+
variant,
|
|
4506
|
+
muted,
|
|
4507
|
+
className: messageClassName,
|
|
4508
|
+
branchInfo,
|
|
4509
|
+
actions,
|
|
4510
|
+
isStreaming: nodeIsStreaming,
|
|
4511
|
+
...messageProps
|
|
4512
|
+
} = item;
|
|
4513
|
+
const isLastMessage = index === lastMessageIdx;
|
|
4514
|
+
const showStreaming = isLastMessage && isStreaming && variant === "assistant";
|
|
4515
|
+
const isMessageStreaming = showStreaming || !!nodeIsStreaming;
|
|
4516
|
+
return /* @__PURE__ */ React60.createElement(
|
|
4517
|
+
"div",
|
|
4518
|
+
{
|
|
4519
|
+
key: id,
|
|
4520
|
+
ref: wrapperRef,
|
|
4521
|
+
className: cx(wrapperClass, muted && "opacity-60")
|
|
4522
|
+
},
|
|
4523
|
+
/* @__PURE__ */ React60.createElement(
|
|
4524
|
+
Message,
|
|
4525
|
+
{
|
|
4526
|
+
variant,
|
|
4445
4527
|
isStreaming: isMessageStreaming,
|
|
4446
4528
|
className: messageClassName,
|
|
4447
4529
|
branchInfo,
|
|
@@ -4451,8 +4533,8 @@ var ChatView = React58.forwardRef(
|
|
|
4451
4533
|
}
|
|
4452
4534
|
)
|
|
4453
4535
|
);
|
|
4454
|
-
}), showThinking && /* @__PURE__ */
|
|
4455
|
-
/* @__PURE__ */
|
|
4536
|
+
}), showThinking && /* @__PURE__ */ React60.createElement(ThinkingIndicator, { isVisible: true })),
|
|
4537
|
+
/* @__PURE__ */ React60.createElement(
|
|
4456
4538
|
"div",
|
|
4457
4539
|
{
|
|
4458
4540
|
ref: spacerRef,
|
|
@@ -4467,8 +4549,8 @@ var ChatView = React58.forwardRef(
|
|
|
4467
4549
|
ChatView.displayName = "ChatView";
|
|
4468
4550
|
|
|
4469
4551
|
// src/components/chat/ChatInput.tsx
|
|
4470
|
-
import
|
|
4471
|
-
import { Paperclip, Send, Square, X as
|
|
4552
|
+
import React61, { useCallback as useCallback15, useEffect as useEffect10, useRef as useRef9, useState as useState14 } from "react";
|
|
4553
|
+
import { Paperclip, Send as Send2, Square, X as X6 } from "lucide-react";
|
|
4472
4554
|
|
|
4473
4555
|
// src/components/chat/types.ts
|
|
4474
4556
|
function isImageFile(file) {
|
|
@@ -4486,155 +4568,14 @@ function revokePreviewUrl(url) {
|
|
|
4486
4568
|
}
|
|
4487
4569
|
}
|
|
4488
4570
|
function generateId() {
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
function createEmptyTree() {
|
|
4492
|
-
return {
|
|
4493
|
-
nodes: {},
|
|
4494
|
-
rootIds: [],
|
|
4495
|
-
activeLeafId: null
|
|
4496
|
-
};
|
|
4497
|
-
}
|
|
4498
|
-
function addMessageToTree(tree, message, parentId = null) {
|
|
4499
|
-
const newNodes = { ...tree.nodes };
|
|
4500
|
-
const newRootIds = [...tree.rootIds];
|
|
4501
|
-
let branchIndex = 0;
|
|
4502
|
-
if (parentId && newNodes[parentId]) {
|
|
4503
|
-
branchIndex = newNodes[parentId].children.length;
|
|
4504
|
-
} else if (!parentId) {
|
|
4505
|
-
branchIndex = newRootIds.length;
|
|
4506
|
-
}
|
|
4507
|
-
newNodes[message.id] = {
|
|
4508
|
-
...message,
|
|
4509
|
-
parentId,
|
|
4510
|
-
children: [],
|
|
4511
|
-
branchIndex,
|
|
4512
|
-
createdAt: message.createdAt ?? Date.now()
|
|
4513
|
-
};
|
|
4514
|
-
if (parentId && newNodes[parentId]) {
|
|
4515
|
-
newNodes[parentId] = {
|
|
4516
|
-
...newNodes[parentId],
|
|
4517
|
-
children: [...newNodes[parentId].children, message.id]
|
|
4518
|
-
};
|
|
4519
|
-
} else {
|
|
4520
|
-
newRootIds.push(message.id);
|
|
4521
|
-
}
|
|
4522
|
-
return {
|
|
4523
|
-
nodes: newNodes,
|
|
4524
|
-
rootIds: newRootIds,
|
|
4525
|
-
activeLeafId: message.id
|
|
4526
|
-
};
|
|
4527
|
-
}
|
|
4528
|
-
function getActivePathMessages(tree) {
|
|
4529
|
-
if (!tree.activeLeafId) {
|
|
4530
|
-
return [];
|
|
4531
|
-
}
|
|
4532
|
-
const path = [];
|
|
4533
|
-
let currentId = tree.activeLeafId;
|
|
4534
|
-
while (currentId) {
|
|
4535
|
-
const node = tree.nodes[currentId];
|
|
4536
|
-
if (!node) {
|
|
4537
|
-
break;
|
|
4538
|
-
}
|
|
4539
|
-
path.unshift(node);
|
|
4540
|
-
currentId = node.parentId;
|
|
4541
|
-
}
|
|
4542
|
-
return path;
|
|
4543
|
-
}
|
|
4544
|
-
function getSiblingInfo(tree, nodeId) {
|
|
4545
|
-
const node = tree.nodes[nodeId];
|
|
4546
|
-
if (!node) {
|
|
4547
|
-
return { total: 1, current: 1 };
|
|
4548
|
-
}
|
|
4549
|
-
if (node.parentId) {
|
|
4550
|
-
const parent = tree.nodes[node.parentId];
|
|
4551
|
-
if (parent) {
|
|
4552
|
-
const index = parent.children.indexOf(nodeId);
|
|
4553
|
-
return {
|
|
4554
|
-
total: parent.children.length,
|
|
4555
|
-
current: index + 1
|
|
4556
|
-
};
|
|
4557
|
-
}
|
|
4558
|
-
} else {
|
|
4559
|
-
const index = tree.rootIds.indexOf(nodeId);
|
|
4560
|
-
return {
|
|
4561
|
-
total: tree.rootIds.length,
|
|
4562
|
-
current: index + 1
|
|
4563
|
-
};
|
|
4564
|
-
}
|
|
4565
|
-
return { total: 1, current: 1 };
|
|
4566
|
-
}
|
|
4567
|
-
function switchBranch(tree, nodeId, direction) {
|
|
4568
|
-
const node = tree.nodes[nodeId];
|
|
4569
|
-
if (!node) {
|
|
4570
|
-
return tree;
|
|
4571
|
-
}
|
|
4572
|
-
let siblings;
|
|
4573
|
-
let currentIndex;
|
|
4574
|
-
if (node.parentId) {
|
|
4575
|
-
const parent = tree.nodes[node.parentId];
|
|
4576
|
-
if (!parent) {
|
|
4577
|
-
return tree;
|
|
4578
|
-
}
|
|
4579
|
-
siblings = parent.children;
|
|
4580
|
-
currentIndex = siblings.indexOf(nodeId);
|
|
4581
|
-
} else {
|
|
4582
|
-
siblings = tree.rootIds;
|
|
4583
|
-
currentIndex = siblings.indexOf(nodeId);
|
|
4584
|
-
}
|
|
4585
|
-
if (siblings.length <= 1) {
|
|
4586
|
-
return tree;
|
|
4587
|
-
}
|
|
4588
|
-
const newIndex = direction === "next" ? (currentIndex + 1) % siblings.length : (currentIndex - 1 + siblings.length) % siblings.length;
|
|
4589
|
-
let leafId = siblings[newIndex];
|
|
4590
|
-
let currentNode = tree.nodes[leafId];
|
|
4591
|
-
while (currentNode && currentNode.children.length > 0) {
|
|
4592
|
-
leafId = currentNode.children[0];
|
|
4593
|
-
currentNode = tree.nodes[leafId];
|
|
4594
|
-
}
|
|
4595
|
-
return {
|
|
4596
|
-
...tree,
|
|
4597
|
-
activeLeafId: leafId
|
|
4598
|
-
};
|
|
4599
|
-
}
|
|
4600
|
-
function updateNodeContent(tree, nodeId, content, isStreaming) {
|
|
4601
|
-
const node = tree.nodes[nodeId];
|
|
4602
|
-
if (!node) {
|
|
4603
|
-
return tree;
|
|
4604
|
-
}
|
|
4605
|
-
return {
|
|
4606
|
-
...tree,
|
|
4607
|
-
nodes: {
|
|
4608
|
-
...tree.nodes,
|
|
4609
|
-
[nodeId]: {
|
|
4610
|
-
...node,
|
|
4611
|
-
content,
|
|
4612
|
-
isStreaming: isStreaming ?? node.isStreaming
|
|
4613
|
-
}
|
|
4614
|
-
}
|
|
4615
|
-
};
|
|
4616
|
-
}
|
|
4617
|
-
function messagesToTree(messages) {
|
|
4618
|
-
let tree = createEmptyTree();
|
|
4619
|
-
for (const msg of messages) {
|
|
4620
|
-
const parentId = tree.activeLeafId;
|
|
4621
|
-
tree = addMessageToTree(tree, {
|
|
4622
|
-
id: msg.id,
|
|
4623
|
-
role: msg.role,
|
|
4624
|
-
content: msg.content,
|
|
4625
|
-
parentId,
|
|
4626
|
-
isStreaming: msg.isStreaming
|
|
4627
|
-
}, parentId);
|
|
4571
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
4572
|
+
return crypto.randomUUID();
|
|
4628
4573
|
}
|
|
4629
|
-
return
|
|
4630
|
-
}
|
|
4631
|
-
function isBranchPoint(tree, nodeId) {
|
|
4632
|
-
const node = tree.nodes[nodeId];
|
|
4633
|
-
return node ? node.children.length > 1 : false;
|
|
4574
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
|
|
4634
4575
|
}
|
|
4635
4576
|
|
|
4636
4577
|
// src/components/chat/ChatInput.tsx
|
|
4637
|
-
var ChatInput =
|
|
4578
|
+
var ChatInput = React61.forwardRef(
|
|
4638
4579
|
({
|
|
4639
4580
|
position = "bottom",
|
|
4640
4581
|
placeholder = "Send a message...",
|
|
@@ -4656,13 +4597,13 @@ var ChatInput = React59.forwardRef(
|
|
|
4656
4597
|
className,
|
|
4657
4598
|
...rest
|
|
4658
4599
|
}, ref) => {
|
|
4659
|
-
const [value, setValue] =
|
|
4660
|
-
const [localAttachments, setLocalAttachments] =
|
|
4661
|
-
const [isDragOver, setIsDragOver] =
|
|
4662
|
-
const textareaRef =
|
|
4663
|
-
const fileInputRef =
|
|
4600
|
+
const [value, setValue] = useState14(initialInputValue);
|
|
4601
|
+
const [localAttachments, setLocalAttachments] = useState14([]);
|
|
4602
|
+
const [isDragOver, setIsDragOver] = useState14(false);
|
|
4603
|
+
const textareaRef = useRef9(null);
|
|
4604
|
+
const fileInputRef = useRef9(null);
|
|
4664
4605
|
const attachments = controlledAttachments ?? localAttachments;
|
|
4665
|
-
const setAttachments =
|
|
4606
|
+
const setAttachments = useCallback15(
|
|
4666
4607
|
(newAttachments) => {
|
|
4667
4608
|
if (onAttachmentsChange) {
|
|
4668
4609
|
if (typeof newAttachments === "function") {
|
|
@@ -4676,7 +4617,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4676
4617
|
},
|
|
4677
4618
|
[attachments, onAttachmentsChange]
|
|
4678
4619
|
);
|
|
4679
|
-
const handleSubmit =
|
|
4620
|
+
const handleSubmit = useCallback15(() => {
|
|
4680
4621
|
const trimmed = value.trim();
|
|
4681
4622
|
if (!trimmed || disabled || isStreaming) {
|
|
4682
4623
|
return;
|
|
@@ -4688,7 +4629,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4688
4629
|
textareaRef.current.style.height = "auto";
|
|
4689
4630
|
}
|
|
4690
4631
|
}, [value, disabled, isStreaming, onSubmit, attachments, setAttachments]);
|
|
4691
|
-
const handleKeyDown =
|
|
4632
|
+
const handleKeyDown = useCallback15(
|
|
4692
4633
|
(e) => {
|
|
4693
4634
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
4694
4635
|
e.preventDefault();
|
|
@@ -4697,7 +4638,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4697
4638
|
},
|
|
4698
4639
|
[handleSubmit]
|
|
4699
4640
|
);
|
|
4700
|
-
const handleChange =
|
|
4641
|
+
const handleChange = useCallback15((e) => {
|
|
4701
4642
|
setValue(e.target.value);
|
|
4702
4643
|
onInputChange?.(e.target.value);
|
|
4703
4644
|
const textarea = e.target;
|
|
@@ -4709,7 +4650,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4709
4650
|
textareaRef.current.focus();
|
|
4710
4651
|
}
|
|
4711
4652
|
}, [disabled, isStreaming, autoFocus]);
|
|
4712
|
-
const addFiles =
|
|
4653
|
+
const addFiles = useCallback15(
|
|
4713
4654
|
(files) => {
|
|
4714
4655
|
const newAttachments = Array.from(files).map((file) => ({
|
|
4715
4656
|
id: generateId(),
|
|
@@ -4721,7 +4662,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4721
4662
|
},
|
|
4722
4663
|
[setAttachments]
|
|
4723
4664
|
);
|
|
4724
|
-
const handleFileSelect =
|
|
4665
|
+
const handleFileSelect = useCallback15(
|
|
4725
4666
|
(e) => {
|
|
4726
4667
|
const files = e.target.files;
|
|
4727
4668
|
if (files && files.length > 0) {
|
|
@@ -4731,7 +4672,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4731
4672
|
},
|
|
4732
4673
|
[addFiles]
|
|
4733
4674
|
);
|
|
4734
|
-
const handleRemoveAttachment =
|
|
4675
|
+
const handleRemoveAttachment = useCallback15(
|
|
4735
4676
|
(id) => {
|
|
4736
4677
|
const attachment = attachments.find((a) => a.id === id);
|
|
4737
4678
|
if (attachment && onAttachmentRemove) {
|
|
@@ -4747,23 +4688,23 @@ var ChatInput = React59.forwardRef(
|
|
|
4747
4688
|
},
|
|
4748
4689
|
[attachments, onAttachmentRemove, setAttachments]
|
|
4749
4690
|
);
|
|
4750
|
-
const handleDragEnter =
|
|
4691
|
+
const handleDragEnter = useCallback15((e) => {
|
|
4751
4692
|
e.preventDefault();
|
|
4752
4693
|
e.stopPropagation();
|
|
4753
4694
|
setIsDragOver(true);
|
|
4754
4695
|
}, []);
|
|
4755
|
-
const handleDragLeave =
|
|
4696
|
+
const handleDragLeave = useCallback15((e) => {
|
|
4756
4697
|
e.preventDefault();
|
|
4757
4698
|
e.stopPropagation();
|
|
4758
4699
|
if (!e.currentTarget.contains(e.relatedTarget)) {
|
|
4759
4700
|
setIsDragOver(false);
|
|
4760
4701
|
}
|
|
4761
4702
|
}, []);
|
|
4762
|
-
const handleDragOver =
|
|
4703
|
+
const handleDragOver = useCallback15((e) => {
|
|
4763
4704
|
e.preventDefault();
|
|
4764
4705
|
e.stopPropagation();
|
|
4765
4706
|
}, []);
|
|
4766
|
-
const handleDrop =
|
|
4707
|
+
const handleDrop = useCallback15(
|
|
4767
4708
|
(e) => {
|
|
4768
4709
|
e.preventDefault();
|
|
4769
4710
|
e.stopPropagation();
|
|
@@ -4779,7 +4720,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4779
4720
|
const hasAttachments = attachments.length > 0;
|
|
4780
4721
|
const isUploading = attachments.some((a) => a.status === "uploading");
|
|
4781
4722
|
const canSubmit = value.trim() && !disabled && !isStreaming && !isUploading;
|
|
4782
|
-
return /* @__PURE__ */
|
|
4723
|
+
return /* @__PURE__ */ React61.createElement(
|
|
4783
4724
|
"div",
|
|
4784
4725
|
{
|
|
4785
4726
|
ref,
|
|
@@ -4791,12 +4732,12 @@ var ChatInput = React59.forwardRef(
|
|
|
4791
4732
|
),
|
|
4792
4733
|
...rest
|
|
4793
4734
|
},
|
|
4794
|
-
isCentered && helperText && /* @__PURE__ */
|
|
4795
|
-
notice && /* @__PURE__ */
|
|
4735
|
+
isCentered && helperText && /* @__PURE__ */ React61.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
|
|
4736
|
+
notice && /* @__PURE__ */ React61.createElement("div", { className: cx(
|
|
4796
4737
|
"w-full flex items-start gap-2 px-3 py-2 mb-1 text-xs",
|
|
4797
4738
|
isCentered && "max-w-lg",
|
|
4798
4739
|
notice.variant === "warning" ? "bg-gold/5 border border-gold/20 text-gold/80" : "bg-error/10 border border-error/30 text-error"
|
|
4799
|
-
) }, /* @__PURE__ */
|
|
4740
|
+
) }, /* @__PURE__ */ React61.createElement("span", { className: "flex-1" }, notice.content), (notice.dismissible ?? notice.variant === "warning") && notice.onDismiss && /* @__PURE__ */ React61.createElement(
|
|
4800
4741
|
"button",
|
|
4801
4742
|
{
|
|
4802
4743
|
type: "button",
|
|
@@ -4807,9 +4748,9 @@ var ChatInput = React59.forwardRef(
|
|
|
4807
4748
|
notice.variant === "warning" ? "text-gold" : "text-error"
|
|
4808
4749
|
)
|
|
4809
4750
|
},
|
|
4810
|
-
/* @__PURE__ */
|
|
4751
|
+
/* @__PURE__ */ React61.createElement(X6, { className: "w-3 h-3" })
|
|
4811
4752
|
)),
|
|
4812
|
-
/* @__PURE__ */
|
|
4753
|
+
/* @__PURE__ */ React61.createElement(
|
|
4813
4754
|
"div",
|
|
4814
4755
|
{
|
|
4815
4756
|
className: cx(
|
|
@@ -4824,7 +4765,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4824
4765
|
onDragOver: showAttachmentButton ? handleDragOver : void 0,
|
|
4825
4766
|
onDrop: showAttachmentButton ? handleDrop : void 0
|
|
4826
4767
|
},
|
|
4827
|
-
hasAttachments && /* @__PURE__ */
|
|
4768
|
+
hasAttachments && /* @__PURE__ */ React61.createElement("div", { className: "px-3 pt-3 pb-1" }, /* @__PURE__ */ React61.createElement(
|
|
4828
4769
|
AttachmentPreview,
|
|
4829
4770
|
{
|
|
4830
4771
|
attachments,
|
|
@@ -4832,14 +4773,14 @@ var ChatInput = React59.forwardRef(
|
|
|
4832
4773
|
removable: !isStreaming
|
|
4833
4774
|
}
|
|
4834
4775
|
)),
|
|
4835
|
-
isDragOver && /* @__PURE__ */
|
|
4776
|
+
isDragOver && /* @__PURE__ */ React61.createElement(
|
|
4836
4777
|
"div",
|
|
4837
4778
|
{
|
|
4838
4779
|
className: "absolute inset-0 bg-gold/10 flex items-center justify-center z-10 pointer-events-none"
|
|
4839
4780
|
},
|
|
4840
|
-
/* @__PURE__ */
|
|
4781
|
+
/* @__PURE__ */ React61.createElement("span", { className: "text-gold text-sm font-medium" }, "Drop files here")
|
|
4841
4782
|
),
|
|
4842
|
-
/* @__PURE__ */
|
|
4783
|
+
/* @__PURE__ */ React61.createElement("div", { className: "flex items-end" }, showAttachmentButton && /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(
|
|
4843
4784
|
"button",
|
|
4844
4785
|
{
|
|
4845
4786
|
type: "button",
|
|
@@ -4851,8 +4792,8 @@ var ChatInput = React59.forwardRef(
|
|
|
4851
4792
|
),
|
|
4852
4793
|
"aria-label": "Attach file"
|
|
4853
4794
|
},
|
|
4854
|
-
/* @__PURE__ */
|
|
4855
|
-
), /* @__PURE__ */
|
|
4795
|
+
/* @__PURE__ */ React61.createElement(Paperclip, { className: "w-5 h-5" })
|
|
4796
|
+
), /* @__PURE__ */ React61.createElement(
|
|
4856
4797
|
"input",
|
|
4857
4798
|
{
|
|
4858
4799
|
ref: fileInputRef,
|
|
@@ -4863,7 +4804,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4863
4804
|
className: "hidden",
|
|
4864
4805
|
"aria-hidden": "true"
|
|
4865
4806
|
}
|
|
4866
|
-
)), /* @__PURE__ */
|
|
4807
|
+
)), /* @__PURE__ */ React61.createElement(
|
|
4867
4808
|
"textarea",
|
|
4868
4809
|
{
|
|
4869
4810
|
ref: textareaRef,
|
|
@@ -4881,7 +4822,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4881
4822
|
),
|
|
4882
4823
|
style: { maxHeight: 200 }
|
|
4883
4824
|
}
|
|
4884
|
-
), isStreaming ? /* @__PURE__ */
|
|
4825
|
+
), isStreaming ? /* @__PURE__ */ React61.createElement(
|
|
4885
4826
|
"button",
|
|
4886
4827
|
{
|
|
4887
4828
|
type: "button",
|
|
@@ -4892,8 +4833,8 @@ var ChatInput = React59.forwardRef(
|
|
|
4892
4833
|
),
|
|
4893
4834
|
"aria-label": "Stop generation"
|
|
4894
4835
|
},
|
|
4895
|
-
/* @__PURE__ */
|
|
4896
|
-
) : /* @__PURE__ */
|
|
4836
|
+
/* @__PURE__ */ React61.createElement(Square, { className: "w-5 h-5 fill-current" })
|
|
4837
|
+
) : /* @__PURE__ */ React61.createElement(
|
|
4897
4838
|
"button",
|
|
4898
4839
|
{
|
|
4899
4840
|
type: "button",
|
|
@@ -4906,7 +4847,7 @@ var ChatInput = React59.forwardRef(
|
|
|
4906
4847
|
),
|
|
4907
4848
|
"aria-label": "Send message"
|
|
4908
4849
|
},
|
|
4909
|
-
/* @__PURE__ */
|
|
4850
|
+
/* @__PURE__ */ React61.createElement(Send2, { className: "w-5 h-5" })
|
|
4910
4851
|
))
|
|
4911
4852
|
)
|
|
4912
4853
|
);
|
|
@@ -4915,13 +4856,14 @@ var ChatInput = React59.forwardRef(
|
|
|
4915
4856
|
ChatInput.displayName = "ChatInput";
|
|
4916
4857
|
|
|
4917
4858
|
// src/components/chat/ArtifactsPanel.tsx
|
|
4918
|
-
import
|
|
4859
|
+
import React71, { useCallback as useCallback17, useEffect as useEffect12, useRef as useRef11, useState as useState17 } from "react";
|
|
4860
|
+
import { Image } from "lucide-react";
|
|
4919
4861
|
|
|
4920
4862
|
// src/components/ArtifactCard.tsx
|
|
4921
|
-
import
|
|
4863
|
+
import React68 from "react";
|
|
4922
4864
|
|
|
4923
4865
|
// src/components/ImageCard.tsx
|
|
4924
|
-
import
|
|
4866
|
+
import React62 from "react";
|
|
4925
4867
|
var ASPECT_RATIO_PRESETS = {
|
|
4926
4868
|
landscape: "3 / 2",
|
|
4927
4869
|
portrait: "2 / 3",
|
|
@@ -4933,7 +4875,7 @@ function resolveAspectRatio(ratio) {
|
|
|
4933
4875
|
}
|
|
4934
4876
|
return ratio.replace("/", " / ");
|
|
4935
4877
|
}
|
|
4936
|
-
var ImageCard =
|
|
4878
|
+
var ImageCard = React62.forwardRef(
|
|
4937
4879
|
({
|
|
4938
4880
|
src,
|
|
4939
4881
|
alt = "",
|
|
@@ -4949,7 +4891,7 @@ var ImageCard = React60.forwardRef(
|
|
|
4949
4891
|
loading,
|
|
4950
4892
|
...props
|
|
4951
4893
|
}, ref) => {
|
|
4952
|
-
return /* @__PURE__ */
|
|
4894
|
+
return /* @__PURE__ */ React62.createElement(
|
|
4953
4895
|
Card,
|
|
4954
4896
|
{
|
|
4955
4897
|
ref,
|
|
@@ -4957,13 +4899,13 @@ var ImageCard = React60.forwardRef(
|
|
|
4957
4899
|
loading,
|
|
4958
4900
|
...props
|
|
4959
4901
|
},
|
|
4960
|
-
/* @__PURE__ */
|
|
4902
|
+
/* @__PURE__ */ React62.createElement(
|
|
4961
4903
|
Card.Media,
|
|
4962
4904
|
{
|
|
4963
4905
|
className: mediaClassName,
|
|
4964
4906
|
style: { aspectRatio: resolveAspectRatio(aspectRatio) }
|
|
4965
4907
|
},
|
|
4966
|
-
/* @__PURE__ */
|
|
4908
|
+
/* @__PURE__ */ React62.createElement(React62.Fragment, null, src && /* @__PURE__ */ React62.createElement(
|
|
4967
4909
|
"img",
|
|
4968
4910
|
{
|
|
4969
4911
|
src,
|
|
@@ -4973,7 +4915,7 @@ var ImageCard = React60.forwardRef(
|
|
|
4973
4915
|
objectFit === "cover" ? "object-cover" : "object-contain"
|
|
4974
4916
|
)
|
|
4975
4917
|
}
|
|
4976
|
-
), overlay && /* @__PURE__ */
|
|
4918
|
+
), overlay && /* @__PURE__ */ React62.createElement(
|
|
4977
4919
|
"div",
|
|
4978
4920
|
{
|
|
4979
4921
|
className: "absolute inset-0 bg-obsidian/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex items-center justify-center"
|
|
@@ -4981,7 +4923,7 @@ var ImageCard = React60.forwardRef(
|
|
|
4981
4923
|
overlay
|
|
4982
4924
|
))
|
|
4983
4925
|
),
|
|
4984
|
-
/* @__PURE__ */
|
|
4926
|
+
/* @__PURE__ */ React62.createElement(
|
|
4985
4927
|
Card.Header,
|
|
4986
4928
|
{
|
|
4987
4929
|
title,
|
|
@@ -4989,14 +4931,14 @@ var ImageCard = React60.forwardRef(
|
|
|
4989
4931
|
className: contentClassName
|
|
4990
4932
|
}
|
|
4991
4933
|
),
|
|
4992
|
-
children && /* @__PURE__ */
|
|
4934
|
+
children && /* @__PURE__ */ React62.createElement(Card.Body, { className: contentClassName }, children)
|
|
4993
4935
|
);
|
|
4994
4936
|
}
|
|
4995
4937
|
);
|
|
4996
4938
|
ImageCard.displayName = "ImageCard";
|
|
4997
4939
|
|
|
4998
4940
|
// src/components/VideoCard.tsx
|
|
4999
|
-
import
|
|
4941
|
+
import React63 from "react";
|
|
5000
4942
|
import ReactPlayer from "react-player";
|
|
5001
4943
|
var ASPECT_RATIO_PRESETS2 = {
|
|
5002
4944
|
video: "16 / 9",
|
|
@@ -5009,7 +4951,7 @@ function resolveAspectRatio2(ratio) {
|
|
|
5009
4951
|
}
|
|
5010
4952
|
return ratio.replace("/", " / ");
|
|
5011
4953
|
}
|
|
5012
|
-
var VideoCard =
|
|
4954
|
+
var VideoCard = React63.forwardRef(
|
|
5013
4955
|
({
|
|
5014
4956
|
src,
|
|
5015
4957
|
title,
|
|
@@ -5029,7 +4971,7 @@ var VideoCard = React61.forwardRef(
|
|
|
5029
4971
|
loading,
|
|
5030
4972
|
...props
|
|
5031
4973
|
}, ref) => {
|
|
5032
|
-
return /* @__PURE__ */
|
|
4974
|
+
return /* @__PURE__ */ React63.createElement(
|
|
5033
4975
|
Card,
|
|
5034
4976
|
{
|
|
5035
4977
|
ref,
|
|
@@ -5037,13 +4979,13 @@ var VideoCard = React61.forwardRef(
|
|
|
5037
4979
|
loading,
|
|
5038
4980
|
...props
|
|
5039
4981
|
},
|
|
5040
|
-
/* @__PURE__ */
|
|
4982
|
+
/* @__PURE__ */ React63.createElement(
|
|
5041
4983
|
Card.Media,
|
|
5042
4984
|
{
|
|
5043
4985
|
className: mediaClassName,
|
|
5044
4986
|
style: { aspectRatio: resolveAspectRatio2(aspectRatio) }
|
|
5045
4987
|
},
|
|
5046
|
-
src && /* @__PURE__ */
|
|
4988
|
+
src && /* @__PURE__ */ React63.createElement(
|
|
5047
4989
|
ReactPlayer,
|
|
5048
4990
|
{
|
|
5049
4991
|
src,
|
|
@@ -5060,7 +5002,7 @@ var VideoCard = React61.forwardRef(
|
|
|
5060
5002
|
}
|
|
5061
5003
|
)
|
|
5062
5004
|
),
|
|
5063
|
-
/* @__PURE__ */
|
|
5005
|
+
/* @__PURE__ */ React63.createElement(
|
|
5064
5006
|
Card.Header,
|
|
5065
5007
|
{
|
|
5066
5008
|
title,
|
|
@@ -5068,17 +5010,17 @@ var VideoCard = React61.forwardRef(
|
|
|
5068
5010
|
className: contentClassName
|
|
5069
5011
|
}
|
|
5070
5012
|
),
|
|
5071
|
-
children && /* @__PURE__ */
|
|
5013
|
+
children && /* @__PURE__ */ React63.createElement(Card.Body, { className: contentClassName }, children)
|
|
5072
5014
|
);
|
|
5073
5015
|
}
|
|
5074
5016
|
);
|
|
5075
5017
|
VideoCard.displayName = "VideoCard";
|
|
5076
5018
|
|
|
5077
5019
|
// src/components/AudioCard.tsx
|
|
5078
|
-
import
|
|
5020
|
+
import React64 from "react";
|
|
5079
5021
|
import ReactPlayer2 from "react-player";
|
|
5080
5022
|
import { Music } from "lucide-react";
|
|
5081
|
-
var AudioCard =
|
|
5023
|
+
var AudioCard = React64.forwardRef(
|
|
5082
5024
|
({
|
|
5083
5025
|
src,
|
|
5084
5026
|
title,
|
|
@@ -5097,7 +5039,7 @@ var AudioCard = React62.forwardRef(
|
|
|
5097
5039
|
loading,
|
|
5098
5040
|
...props
|
|
5099
5041
|
}, ref) => {
|
|
5100
|
-
return /* @__PURE__ */
|
|
5042
|
+
return /* @__PURE__ */ React64.createElement(
|
|
5101
5043
|
Card,
|
|
5102
5044
|
{
|
|
5103
5045
|
ref,
|
|
@@ -5105,10 +5047,10 @@ var AudioCard = React62.forwardRef(
|
|
|
5105
5047
|
loading,
|
|
5106
5048
|
...props
|
|
5107
5049
|
},
|
|
5108
|
-
/* @__PURE__ */
|
|
5050
|
+
/* @__PURE__ */ React64.createElement(Card.Media, { className: cx(
|
|
5109
5051
|
"bg-obsidian py-8 flex flex-col items-center justify-center",
|
|
5110
5052
|
mediaClassName
|
|
5111
|
-
) }, /* @__PURE__ */
|
|
5053
|
+
) }, /* @__PURE__ */ React64.createElement("div", { className: "mb-4 text-gold" }, /* @__PURE__ */ React64.createElement(Music, { size: 48 })), src && /* @__PURE__ */ React64.createElement("div", { className: "w-full px-4" }, /* @__PURE__ */ React64.createElement(
|
|
5112
5054
|
ReactPlayer2,
|
|
5113
5055
|
{
|
|
5114
5056
|
src,
|
|
@@ -5119,19 +5061,11 @@ var AudioCard = React62.forwardRef(
|
|
|
5119
5061
|
loop,
|
|
5120
5062
|
width: "100%",
|
|
5121
5063
|
height,
|
|
5122
|
-
style: { backgroundColor: "transparent" },
|
|
5123
|
-
config: {
|
|
5124
|
-
file: {
|
|
5125
|
-
forceAudio: true,
|
|
5126
|
-
attributes: {
|
|
5127
|
-
style: { width: "100%", height }
|
|
5128
|
-
}
|
|
5129
|
-
}
|
|
5130
|
-
},
|
|
5064
|
+
style: { backgroundColor: "transparent", width: "100%", height },
|
|
5131
5065
|
...playerProps
|
|
5132
5066
|
}
|
|
5133
5067
|
))),
|
|
5134
|
-
/* @__PURE__ */
|
|
5068
|
+
/* @__PURE__ */ React64.createElement(
|
|
5135
5069
|
Card.Header,
|
|
5136
5070
|
{
|
|
5137
5071
|
title,
|
|
@@ -5139,16 +5073,16 @@ var AudioCard = React62.forwardRef(
|
|
|
5139
5073
|
className: contentClassName
|
|
5140
5074
|
}
|
|
5141
5075
|
),
|
|
5142
|
-
children && /* @__PURE__ */
|
|
5076
|
+
children && /* @__PURE__ */ React64.createElement(Card.Body, { className: contentClassName }, children)
|
|
5143
5077
|
);
|
|
5144
5078
|
}
|
|
5145
5079
|
);
|
|
5146
5080
|
AudioCard.displayName = "AudioCard";
|
|
5147
5081
|
|
|
5148
5082
|
// src/components/PdfCard.tsx
|
|
5149
|
-
import
|
|
5083
|
+
import React65 from "react";
|
|
5150
5084
|
import { FileText as FileText2 } from "lucide-react";
|
|
5151
|
-
var PdfCard =
|
|
5085
|
+
var PdfCard = React65.forwardRef(
|
|
5152
5086
|
({
|
|
5153
5087
|
src,
|
|
5154
5088
|
title,
|
|
@@ -5161,7 +5095,7 @@ var PdfCard = React63.forwardRef(
|
|
|
5161
5095
|
loading,
|
|
5162
5096
|
...props
|
|
5163
5097
|
}, ref) => {
|
|
5164
|
-
return /* @__PURE__ */
|
|
5098
|
+
return /* @__PURE__ */ React65.createElement(
|
|
5165
5099
|
Card,
|
|
5166
5100
|
{
|
|
5167
5101
|
ref,
|
|
@@ -5169,13 +5103,13 @@ var PdfCard = React63.forwardRef(
|
|
|
5169
5103
|
loading,
|
|
5170
5104
|
...props
|
|
5171
5105
|
},
|
|
5172
|
-
/* @__PURE__ */
|
|
5106
|
+
/* @__PURE__ */ React65.createElement(
|
|
5173
5107
|
Card.Media,
|
|
5174
5108
|
{
|
|
5175
5109
|
className: cx("bg-obsidian", mediaClassName),
|
|
5176
5110
|
style: { height }
|
|
5177
5111
|
},
|
|
5178
|
-
src && /* @__PURE__ */
|
|
5112
|
+
src && /* @__PURE__ */ React65.createElement(
|
|
5179
5113
|
"iframe",
|
|
5180
5114
|
{
|
|
5181
5115
|
src: `${src}#view=FitH`,
|
|
@@ -5184,23 +5118,23 @@ var PdfCard = React63.forwardRef(
|
|
|
5184
5118
|
}
|
|
5185
5119
|
)
|
|
5186
5120
|
),
|
|
5187
|
-
/* @__PURE__ */
|
|
5121
|
+
/* @__PURE__ */ React65.createElement(
|
|
5188
5122
|
Card.Header,
|
|
5189
5123
|
{
|
|
5190
5124
|
title,
|
|
5191
5125
|
subtitle,
|
|
5192
5126
|
className: contentClassName,
|
|
5193
|
-
action: /* @__PURE__ */
|
|
5127
|
+
action: /* @__PURE__ */ React65.createElement("div", { className: "p-2 bg-ash/20 text-gold shrink-0" }, /* @__PURE__ */ React65.createElement(FileText2, { size: 20 }))
|
|
5194
5128
|
}
|
|
5195
5129
|
),
|
|
5196
|
-
children && /* @__PURE__ */
|
|
5130
|
+
children && /* @__PURE__ */ React65.createElement(Card.Body, { className: contentClassName }, children)
|
|
5197
5131
|
);
|
|
5198
5132
|
}
|
|
5199
5133
|
);
|
|
5200
5134
|
PdfCard.displayName = "PdfCard";
|
|
5201
5135
|
|
|
5202
5136
|
// src/components/ScriptCard.tsx
|
|
5203
|
-
import
|
|
5137
|
+
import React66 from "react";
|
|
5204
5138
|
var SCRIPT_ELEMENT_TYPES = {
|
|
5205
5139
|
SCENE_HEADING: "scene-heading",
|
|
5206
5140
|
ACTION: "action",
|
|
@@ -5214,28 +5148,28 @@ var SCRIPT_ELEMENT_TYPES = {
|
|
|
5214
5148
|
function ScriptElementRenderer({ element }) {
|
|
5215
5149
|
switch (element.type) {
|
|
5216
5150
|
case "scene-heading":
|
|
5217
|
-
return /* @__PURE__ */
|
|
5151
|
+
return /* @__PURE__ */ React66.createElement("p", { className: "mt-4 mb-2 font-bold uppercase text-gold text-xs tracking-wide" }, element.content);
|
|
5218
5152
|
case "action":
|
|
5219
|
-
return /* @__PURE__ */
|
|
5153
|
+
return /* @__PURE__ */ React66.createElement("p", { className: "my-2 text-silver text-xs leading-relaxed" }, element.content);
|
|
5220
5154
|
case "character":
|
|
5221
|
-
return /* @__PURE__ */
|
|
5155
|
+
return /* @__PURE__ */ React66.createElement("p", { className: "mt-4 mb-0.5 ml-8 font-bold text-white text-xs uppercase tracking-wide" }, element.content);
|
|
5222
5156
|
case "parenthetical":
|
|
5223
|
-
return /* @__PURE__ */
|
|
5157
|
+
return /* @__PURE__ */ React66.createElement("p", { className: "ml-6 text-silver/70 text-xs italic" }, "(", element.content, ")");
|
|
5224
5158
|
case "dialogue":
|
|
5225
|
-
return /* @__PURE__ */
|
|
5159
|
+
return /* @__PURE__ */ React66.createElement("p", { className: "ml-4 mr-8 text-silver text-xs leading-relaxed" }, element.content);
|
|
5226
5160
|
case "transition":
|
|
5227
|
-
return /* @__PURE__ */
|
|
5161
|
+
return /* @__PURE__ */ React66.createElement("p", { className: "mt-4 mb-2 text-right font-bold uppercase text-gold/80 text-xs tracking-wide" }, element.content);
|
|
5228
5162
|
case "title":
|
|
5229
|
-
return /* @__PURE__ */
|
|
5163
|
+
return /* @__PURE__ */ React66.createElement("p", { className: "mt-6 mb-2 text-center font-bold text-gold text-sm" }, element.content);
|
|
5230
5164
|
case "subtitle":
|
|
5231
|
-
return /* @__PURE__ */
|
|
5165
|
+
return /* @__PURE__ */ React66.createElement("p", { className: "text-center italic text-gold/70 text-xs" }, element.content);
|
|
5232
5166
|
default:
|
|
5233
5167
|
return null;
|
|
5234
5168
|
}
|
|
5235
5169
|
}
|
|
5236
|
-
var ScriptCard =
|
|
5170
|
+
var ScriptCard = React66.forwardRef(
|
|
5237
5171
|
({ title, subtitle, elements, maxHeight = "16rem", className, style, loading, ...rest }, ref) => {
|
|
5238
|
-
return /* @__PURE__ */
|
|
5172
|
+
return /* @__PURE__ */ React66.createElement(
|
|
5239
5173
|
Card,
|
|
5240
5174
|
{
|
|
5241
5175
|
ref,
|
|
@@ -5243,20 +5177,20 @@ var ScriptCard = React64.forwardRef(
|
|
|
5243
5177
|
loading,
|
|
5244
5178
|
...rest
|
|
5245
5179
|
},
|
|
5246
|
-
/* @__PURE__ */
|
|
5180
|
+
/* @__PURE__ */ React66.createElement(
|
|
5247
5181
|
Card.Header,
|
|
5248
5182
|
{
|
|
5249
5183
|
title,
|
|
5250
5184
|
subtitle
|
|
5251
5185
|
}
|
|
5252
5186
|
),
|
|
5253
|
-
/* @__PURE__ */
|
|
5187
|
+
/* @__PURE__ */ React66.createElement(
|
|
5254
5188
|
Card.Body,
|
|
5255
5189
|
{
|
|
5256
5190
|
className: "font-mono overflow-y-auto",
|
|
5257
5191
|
style: { maxHeight, ...style }
|
|
5258
5192
|
},
|
|
5259
|
-
elements.map((element, index) => /* @__PURE__ */
|
|
5193
|
+
elements.map((element, index) => /* @__PURE__ */ React66.createElement(ScriptElementRenderer, { key: index, element }))
|
|
5260
5194
|
)
|
|
5261
5195
|
);
|
|
5262
5196
|
}
|
|
@@ -5264,8 +5198,8 @@ var ScriptCard = React64.forwardRef(
|
|
|
5264
5198
|
ScriptCard.displayName = "ScriptCard";
|
|
5265
5199
|
|
|
5266
5200
|
// src/components/TextCard.tsx
|
|
5267
|
-
import
|
|
5268
|
-
var TextCard =
|
|
5201
|
+
import React67 from "react";
|
|
5202
|
+
var TextCard = React67.forwardRef(
|
|
5269
5203
|
({
|
|
5270
5204
|
content,
|
|
5271
5205
|
title,
|
|
@@ -5277,7 +5211,7 @@ var TextCard = React65.forwardRef(
|
|
|
5277
5211
|
loading,
|
|
5278
5212
|
...props
|
|
5279
5213
|
}, ref) => {
|
|
5280
|
-
return /* @__PURE__ */
|
|
5214
|
+
return /* @__PURE__ */ React67.createElement(
|
|
5281
5215
|
Card,
|
|
5282
5216
|
{
|
|
5283
5217
|
ref,
|
|
@@ -5285,20 +5219,20 @@ var TextCard = React65.forwardRef(
|
|
|
5285
5219
|
loading,
|
|
5286
5220
|
...props
|
|
5287
5221
|
},
|
|
5288
|
-
/* @__PURE__ */
|
|
5222
|
+
/* @__PURE__ */ React67.createElement(
|
|
5289
5223
|
Card.Header,
|
|
5290
5224
|
{
|
|
5291
5225
|
title,
|
|
5292
5226
|
subtitle
|
|
5293
5227
|
}
|
|
5294
5228
|
),
|
|
5295
|
-
/* @__PURE__ */
|
|
5229
|
+
/* @__PURE__ */ React67.createElement(
|
|
5296
5230
|
Card.Body,
|
|
5297
5231
|
{
|
|
5298
5232
|
className: cx("overflow-y-auto", contentClassName),
|
|
5299
5233
|
style: { maxHeight }
|
|
5300
5234
|
},
|
|
5301
|
-
/* @__PURE__ */
|
|
5235
|
+
/* @__PURE__ */ React67.createElement(
|
|
5302
5236
|
MarkdownContent,
|
|
5303
5237
|
{
|
|
5304
5238
|
content,
|
|
@@ -5336,7 +5270,7 @@ var ARTIFACT_TYPES = {
|
|
|
5336
5270
|
SCRIPT: "SCRIPT",
|
|
5337
5271
|
PDF: "PDF"
|
|
5338
5272
|
};
|
|
5339
|
-
var ArtifactCard =
|
|
5273
|
+
var ArtifactCard = React68.forwardRef(
|
|
5340
5274
|
({ artifact, onExpand, loading, className, ...props }, ref) => {
|
|
5341
5275
|
const derivedLoading = deriveCardSlotLoading(artifact);
|
|
5342
5276
|
const commonProps = {
|
|
@@ -5354,7 +5288,7 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5354
5288
|
const renderContent = () => {
|
|
5355
5289
|
switch (artifact.type) {
|
|
5356
5290
|
case "IMAGE":
|
|
5357
|
-
return /* @__PURE__ */
|
|
5291
|
+
return /* @__PURE__ */ React68.createElement(
|
|
5358
5292
|
ImageCard,
|
|
5359
5293
|
{
|
|
5360
5294
|
...commonProps,
|
|
@@ -5364,7 +5298,7 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5364
5298
|
}
|
|
5365
5299
|
);
|
|
5366
5300
|
case "VIDEO":
|
|
5367
|
-
return /* @__PURE__ */
|
|
5301
|
+
return /* @__PURE__ */ React68.createElement(
|
|
5368
5302
|
VideoCard,
|
|
5369
5303
|
{
|
|
5370
5304
|
...commonProps,
|
|
@@ -5374,7 +5308,7 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5374
5308
|
}
|
|
5375
5309
|
);
|
|
5376
5310
|
case "AUDIO":
|
|
5377
|
-
return /* @__PURE__ */
|
|
5311
|
+
return /* @__PURE__ */ React68.createElement(
|
|
5378
5312
|
AudioCard,
|
|
5379
5313
|
{
|
|
5380
5314
|
...commonProps,
|
|
@@ -5383,7 +5317,7 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5383
5317
|
}
|
|
5384
5318
|
);
|
|
5385
5319
|
case "PDF":
|
|
5386
|
-
return /* @__PURE__ */
|
|
5320
|
+
return /* @__PURE__ */ React68.createElement(
|
|
5387
5321
|
PdfCard,
|
|
5388
5322
|
{
|
|
5389
5323
|
...commonProps,
|
|
@@ -5391,7 +5325,7 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5391
5325
|
}
|
|
5392
5326
|
);
|
|
5393
5327
|
case "SCRIPT":
|
|
5394
|
-
return /* @__PURE__ */
|
|
5328
|
+
return /* @__PURE__ */ React68.createElement(
|
|
5395
5329
|
ScriptCard,
|
|
5396
5330
|
{
|
|
5397
5331
|
...commonProps,
|
|
@@ -5400,7 +5334,7 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5400
5334
|
}
|
|
5401
5335
|
);
|
|
5402
5336
|
case "TEXT":
|
|
5403
|
-
return /* @__PURE__ */
|
|
5337
|
+
return /* @__PURE__ */ React68.createElement(
|
|
5404
5338
|
TextCard,
|
|
5405
5339
|
{
|
|
5406
5340
|
...commonProps,
|
|
@@ -5411,12 +5345,14 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5411
5345
|
)
|
|
5412
5346
|
}
|
|
5413
5347
|
);
|
|
5414
|
-
default:
|
|
5415
|
-
|
|
5348
|
+
default: {
|
|
5349
|
+
const _exhaustive = artifact.type;
|
|
5350
|
+
return _exhaustive;
|
|
5351
|
+
}
|
|
5416
5352
|
}
|
|
5417
5353
|
};
|
|
5418
5354
|
const isCardExpandable = !!onExpand && (artifact.type === "IMAGE" || artifact.type === "PDF" || artifact.type === "SCRIPT" || artifact.type === "TEXT");
|
|
5419
|
-
return /* @__PURE__ */
|
|
5355
|
+
return /* @__PURE__ */ React68.createElement(
|
|
5420
5356
|
"div",
|
|
5421
5357
|
{
|
|
5422
5358
|
ref,
|
|
@@ -5429,7 +5365,7 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5429
5365
|
onClick: isCardExpandable ? handleExpand : void 0,
|
|
5430
5366
|
...props
|
|
5431
5367
|
},
|
|
5432
|
-
onExpand && /* @__PURE__ */
|
|
5368
|
+
onExpand && /* @__PURE__ */ React68.createElement(
|
|
5433
5369
|
"button",
|
|
5434
5370
|
{
|
|
5435
5371
|
onClick: handleExpand,
|
|
@@ -5440,7 +5376,7 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5440
5376
|
),
|
|
5441
5377
|
"aria-label": "Expand artifact"
|
|
5442
5378
|
},
|
|
5443
|
-
/* @__PURE__ */
|
|
5379
|
+
/* @__PURE__ */ React68.createElement(ExpandIcon, { className: "w-4 h-4" })
|
|
5444
5380
|
),
|
|
5445
5381
|
renderContent()
|
|
5446
5382
|
);
|
|
@@ -5449,16 +5385,16 @@ var ArtifactCard = React66.forwardRef(
|
|
|
5449
5385
|
ArtifactCard.displayName = "ArtifactCard";
|
|
5450
5386
|
|
|
5451
5387
|
// src/components/ArtifactGroup.tsx
|
|
5452
|
-
import
|
|
5388
|
+
import React69, { useEffect as useEffect11, useRef as useRef10, useState as useState15 } from "react";
|
|
5453
5389
|
var LAYER_OFFSET = "8px";
|
|
5454
5390
|
var LAYER_OFFSET_2X = "16px";
|
|
5455
|
-
var ArtifactGroup =
|
|
5391
|
+
var ArtifactGroup = React69.forwardRef(
|
|
5456
5392
|
({ node, onClick, className, ...props }, ref) => {
|
|
5457
5393
|
const children = node.children;
|
|
5458
5394
|
const count = children.length;
|
|
5459
5395
|
const frontChild = children[0];
|
|
5460
|
-
const prevCountRef =
|
|
5461
|
-
const [badgePing, setBadgePing] =
|
|
5396
|
+
const prevCountRef = useRef10(count);
|
|
5397
|
+
const [badgePing, setBadgePing] = useState15(false);
|
|
5462
5398
|
useEffect11(() => {
|
|
5463
5399
|
if (count !== prevCountRef.current) {
|
|
5464
5400
|
prevCountRef.current = count;
|
|
@@ -5474,21 +5410,21 @@ var ArtifactGroup = React67.forwardRef(
|
|
|
5474
5410
|
};
|
|
5475
5411
|
const renderFrontContent = () => {
|
|
5476
5412
|
if (!frontChild) {
|
|
5477
|
-
return /* @__PURE__ */
|
|
5413
|
+
return /* @__PURE__ */ React69.createElement("div", { className: "w-full aspect-video bg-graphite border border-ash/40 flex items-center justify-center" }, /* @__PURE__ */ React69.createElement("span", { className: "text-silver text-sm" }, "Empty group"));
|
|
5478
5414
|
}
|
|
5479
5415
|
if (frontChild.type === "ARTIFACT" && frontChild.artifact) {
|
|
5480
|
-
return /* @__PURE__ */
|
|
5416
|
+
return /* @__PURE__ */ React69.createElement(ArtifactCard, { artifact: frontChild.artifact, className: "w-full" });
|
|
5481
5417
|
}
|
|
5482
|
-
return /* @__PURE__ */
|
|
5418
|
+
return /* @__PURE__ */ React69.createElement(
|
|
5483
5419
|
"div",
|
|
5484
5420
|
{
|
|
5485
5421
|
className: "w-full aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
|
|
5486
5422
|
},
|
|
5487
|
-
/* @__PURE__ */
|
|
5488
|
-
/* @__PURE__ */
|
|
5423
|
+
/* @__PURE__ */ React69.createElement("span", { className: "text-sm text-silver uppercase tracking-wider" }, frontChild.type === "GROUP" ? "Group" : "Variants"),
|
|
5424
|
+
/* @__PURE__ */ React69.createElement("span", { className: "text-white font-semibold" }, frontChild.label)
|
|
5489
5425
|
);
|
|
5490
5426
|
};
|
|
5491
|
-
return /* @__PURE__ */
|
|
5427
|
+
return /* @__PURE__ */ React69.createElement(
|
|
5492
5428
|
"div",
|
|
5493
5429
|
{
|
|
5494
5430
|
ref,
|
|
@@ -5508,21 +5444,21 @@ var ArtifactGroup = React67.forwardRef(
|
|
|
5508
5444
|
"aria-label": `${node.label} \u2014 ${count} items`,
|
|
5509
5445
|
...props
|
|
5510
5446
|
},
|
|
5511
|
-
/* @__PURE__ */
|
|
5447
|
+
/* @__PURE__ */ React69.createElement(Card, { noPadding: true, className: "p-5" }, /* @__PURE__ */ React69.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label), /* @__PURE__ */ React69.createElement("div", { style: { paddingRight: LAYER_OFFSET_2X, paddingBottom: LAYER_OFFSET_2X } }, /* @__PURE__ */ React69.createElement("div", { className: "relative" }, /* @__PURE__ */ React69.createElement(
|
|
5512
5448
|
"div",
|
|
5513
5449
|
{
|
|
5514
5450
|
className: "absolute inset-0 bg-charcoal border border-ash/30 pointer-events-none",
|
|
5515
5451
|
style: { transform: `translate(${LAYER_OFFSET_2X}, ${LAYER_OFFSET_2X})` },
|
|
5516
5452
|
"aria-hidden": "true"
|
|
5517
5453
|
}
|
|
5518
|
-
), /* @__PURE__ */
|
|
5454
|
+
), /* @__PURE__ */ React69.createElement(
|
|
5519
5455
|
"div",
|
|
5520
5456
|
{
|
|
5521
5457
|
className: "absolute inset-0 bg-charcoal border border-ash/40 pointer-events-none",
|
|
5522
5458
|
style: { transform: `translate(${LAYER_OFFSET}, ${LAYER_OFFSET})` },
|
|
5523
5459
|
"aria-hidden": "true"
|
|
5524
5460
|
}
|
|
5525
|
-
), /* @__PURE__ */
|
|
5461
|
+
), /* @__PURE__ */ React69.createElement("div", { className: "relative transition-transform duration-200 group-hover:-translate-y-0.5" }, renderFrontContent()), /* @__PURE__ */ React69.createElement(
|
|
5526
5462
|
"div",
|
|
5527
5463
|
{
|
|
5528
5464
|
className: "absolute -top-2 -right-2 z-10 min-w-6 h-6 px-1.5 flex items-center justify-center bg-gold text-obsidian text-xs font-bold",
|
|
@@ -5536,13 +5472,13 @@ var ArtifactGroup = React67.forwardRef(
|
|
|
5536
5472
|
ArtifactGroup.displayName = "ArtifactGroup";
|
|
5537
5473
|
|
|
5538
5474
|
// src/components/ArtifactVariantStack.tsx
|
|
5539
|
-
import
|
|
5540
|
-
var ArtifactVariantStack =
|
|
5475
|
+
import React70 from "react";
|
|
5476
|
+
var ArtifactVariantStack = React70.forwardRef(
|
|
5541
5477
|
({ node, onExpandArtifact, onGroupClick, className, ...props }, ref) => {
|
|
5542
5478
|
const children = node.children;
|
|
5543
5479
|
const renderChild = (child) => {
|
|
5544
5480
|
if (child.type === "ARTIFACT" && child.artifact) {
|
|
5545
|
-
return /* @__PURE__ */
|
|
5481
|
+
return /* @__PURE__ */ React70.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React70.createElement(
|
|
5546
5482
|
ArtifactCard,
|
|
5547
5483
|
{
|
|
5548
5484
|
artifact: child.artifact,
|
|
@@ -5552,18 +5488,18 @@ var ArtifactVariantStack = React68.forwardRef(
|
|
|
5552
5488
|
));
|
|
5553
5489
|
}
|
|
5554
5490
|
if (child.type === "GROUP") {
|
|
5555
|
-
return /* @__PURE__ */
|
|
5491
|
+
return /* @__PURE__ */ React70.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React70.createElement(ArtifactGroup, { node: child, onClick: onGroupClick }));
|
|
5556
5492
|
}
|
|
5557
|
-
return /* @__PURE__ */
|
|
5493
|
+
return /* @__PURE__ */ React70.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React70.createElement(
|
|
5558
5494
|
"div",
|
|
5559
5495
|
{
|
|
5560
5496
|
className: "aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
|
|
5561
5497
|
},
|
|
5562
|
-
/* @__PURE__ */
|
|
5563
|
-
/* @__PURE__ */
|
|
5498
|
+
/* @__PURE__ */ React70.createElement("span", { className: "text-xs text-silver uppercase tracking-wider" }, "Variants"),
|
|
5499
|
+
/* @__PURE__ */ React70.createElement("span", { className: "text-sm text-white font-semibold truncate max-w-full" }, child.label)
|
|
5564
5500
|
));
|
|
5565
5501
|
};
|
|
5566
|
-
return /* @__PURE__ */
|
|
5502
|
+
return /* @__PURE__ */ React70.createElement(
|
|
5567
5503
|
Card,
|
|
5568
5504
|
{
|
|
5569
5505
|
ref,
|
|
@@ -5571,17 +5507,17 @@ var ArtifactVariantStack = React68.forwardRef(
|
|
|
5571
5507
|
className: cx("w-full p-5", className),
|
|
5572
5508
|
...props
|
|
5573
5509
|
},
|
|
5574
|
-
/* @__PURE__ */
|
|
5575
|
-
/* @__PURE__ */
|
|
5510
|
+
/* @__PURE__ */ React70.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label),
|
|
5511
|
+
/* @__PURE__ */ React70.createElement("div", { className: "flex gap-3" }, children.map(renderChild))
|
|
5576
5512
|
);
|
|
5577
5513
|
}
|
|
5578
5514
|
);
|
|
5579
5515
|
ArtifactVariantStack.displayName = "ArtifactVariantStack";
|
|
5580
5516
|
|
|
5581
5517
|
// src/components/chat/hooks/useArtifactTreeNavigation.ts
|
|
5582
|
-
import { useCallback as
|
|
5518
|
+
import { useCallback as useCallback16, useMemo as useMemo2, useState as useState16 } from "react";
|
|
5583
5519
|
function useArtifactTreeNavigation(rootNodes) {
|
|
5584
|
-
const [stack, setStack] =
|
|
5520
|
+
const [stack, setStack] = useState16([]);
|
|
5585
5521
|
const currentNodes = useMemo2(() => {
|
|
5586
5522
|
if (stack.length === 0) return rootNodes;
|
|
5587
5523
|
return stack[stack.length - 1].children;
|
|
@@ -5594,13 +5530,13 @@ function useArtifactTreeNavigation(rootNodes) {
|
|
|
5594
5530
|
return entries;
|
|
5595
5531
|
}, [stack]);
|
|
5596
5532
|
const isAtRoot = stack.length === 0;
|
|
5597
|
-
const navigateInto =
|
|
5533
|
+
const navigateInto = useCallback16((node) => {
|
|
5598
5534
|
setStack((prev) => [...prev, node]);
|
|
5599
5535
|
}, []);
|
|
5600
|
-
const navigateTo =
|
|
5536
|
+
const navigateTo = useCallback16((index) => {
|
|
5601
5537
|
setStack((prev) => prev.slice(0, index));
|
|
5602
5538
|
}, []);
|
|
5603
|
-
const navigateBack =
|
|
5539
|
+
const navigateBack = useCallback16(() => {
|
|
5604
5540
|
setStack((prev) => prev.slice(0, -1));
|
|
5605
5541
|
}, []);
|
|
5606
5542
|
return {
|
|
@@ -5619,55 +5555,47 @@ function ArtifactModal({
|
|
|
5619
5555
|
artifact,
|
|
5620
5556
|
onClose
|
|
5621
5557
|
}) {
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
if (e.key === "Escape") {
|
|
5625
|
-
onClose();
|
|
5626
|
-
}
|
|
5627
|
-
};
|
|
5628
|
-
document.addEventListener("keydown", handleKeyDown);
|
|
5629
|
-
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
5630
|
-
}, [onClose]);
|
|
5631
|
-
const handleBackdropClick = useCallback15((e) => {
|
|
5558
|
+
useEscapeKey(onClose);
|
|
5559
|
+
const handleBackdropClick = useCallback17((e) => {
|
|
5632
5560
|
if (e.target === e.currentTarget) {
|
|
5633
5561
|
onClose();
|
|
5634
5562
|
}
|
|
5635
5563
|
}, [onClose]);
|
|
5636
|
-
return /* @__PURE__ */
|
|
5564
|
+
return /* @__PURE__ */ React71.createElement(
|
|
5637
5565
|
"div",
|
|
5638
5566
|
{
|
|
5639
5567
|
className: "fixed inset-0 z-50 flex items-center justify-center bg-void/90 backdrop-blur-sm animate-fade-in",
|
|
5640
5568
|
onClick: handleBackdropClick
|
|
5641
5569
|
},
|
|
5642
|
-
/* @__PURE__ */
|
|
5570
|
+
/* @__PURE__ */ React71.createElement(
|
|
5643
5571
|
"div",
|
|
5644
5572
|
{
|
|
5645
5573
|
className: "relative w-11/12 h-5/6 max-w-6xl bg-charcoal border border-ash/40 flex flex-col overflow-hidden"
|
|
5646
5574
|
},
|
|
5647
|
-
/* @__PURE__ */
|
|
5575
|
+
/* @__PURE__ */ React71.createElement(
|
|
5648
5576
|
"div",
|
|
5649
5577
|
{
|
|
5650
5578
|
className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
|
|
5651
5579
|
},
|
|
5652
|
-
/* @__PURE__ */
|
|
5653
|
-
/* @__PURE__ */
|
|
5580
|
+
/* @__PURE__ */ React71.createElement("div", null, artifact.title && /* @__PURE__ */ React71.createElement("h3", { className: "text-sm font-semibold text-white" }, artifact.title), artifact.subtitle && /* @__PURE__ */ React71.createElement("p", { className: "text-xs text-silver" }, artifact.subtitle)),
|
|
5581
|
+
/* @__PURE__ */ React71.createElement(
|
|
5654
5582
|
"button",
|
|
5655
5583
|
{
|
|
5656
5584
|
onClick: onClose,
|
|
5657
5585
|
className: "p-2 text-silver hover:text-white hover:bg-ash/20 transition-colors",
|
|
5658
5586
|
"aria-label": "Close modal"
|
|
5659
5587
|
},
|
|
5660
|
-
/* @__PURE__ */
|
|
5588
|
+
/* @__PURE__ */ React71.createElement(CloseIcon, { className: "w-5 h-5" })
|
|
5661
5589
|
)
|
|
5662
5590
|
),
|
|
5663
|
-
/* @__PURE__ */
|
|
5591
|
+
/* @__PURE__ */ React71.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ React71.createElement(
|
|
5664
5592
|
"img",
|
|
5665
5593
|
{
|
|
5666
5594
|
src: artifact.url,
|
|
5667
5595
|
alt: artifact.alt || "Artifact image",
|
|
5668
5596
|
className: "max-w-full max-h-full object-contain mx-auto"
|
|
5669
5597
|
}
|
|
5670
|
-
), artifact.type === "VIDEO" && /* @__PURE__ */
|
|
5598
|
+
), artifact.type === "VIDEO" && /* @__PURE__ */ React71.createElement(
|
|
5671
5599
|
VideoCard,
|
|
5672
5600
|
{
|
|
5673
5601
|
src: artifact.url || "",
|
|
@@ -5675,20 +5603,20 @@ function ArtifactModal({
|
|
|
5675
5603
|
controls: true,
|
|
5676
5604
|
className: "max-w-full max-h-full mx-auto"
|
|
5677
5605
|
}
|
|
5678
|
-
), artifact.type === "AUDIO" && /* @__PURE__ */
|
|
5606
|
+
), artifact.type === "AUDIO" && /* @__PURE__ */ React71.createElement(
|
|
5679
5607
|
AudioCard,
|
|
5680
5608
|
{
|
|
5681
5609
|
src: artifact.url || "",
|
|
5682
5610
|
controls: true,
|
|
5683
5611
|
className: "max-w-xl mx-auto"
|
|
5684
5612
|
}
|
|
5685
|
-
), artifact.type === "PDF" && /* @__PURE__ */
|
|
5613
|
+
), artifact.type === "PDF" && /* @__PURE__ */ React71.createElement(
|
|
5686
5614
|
PdfCard,
|
|
5687
5615
|
{
|
|
5688
5616
|
src: artifact.url || "",
|
|
5689
5617
|
className: "h-full border-0"
|
|
5690
5618
|
}
|
|
5691
|
-
), artifact.type === "TEXT" && /* @__PURE__ */
|
|
5619
|
+
), artifact.type === "TEXT" && /* @__PURE__ */ React71.createElement(
|
|
5692
5620
|
MarkdownContent,
|
|
5693
5621
|
{
|
|
5694
5622
|
content: artifact.inlineContent || "",
|
|
@@ -5698,7 +5626,7 @@ function ArtifactModal({
|
|
|
5698
5626
|
artifact.mimeType === "text/plain" && "whitespace-pre-wrap"
|
|
5699
5627
|
)
|
|
5700
5628
|
}
|
|
5701
|
-
), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */
|
|
5629
|
+
), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ React71.createElement(
|
|
5702
5630
|
ScriptCard,
|
|
5703
5631
|
{
|
|
5704
5632
|
elements: artifact.scriptElements,
|
|
@@ -5716,7 +5644,7 @@ function NodeRenderer({
|
|
|
5716
5644
|
onGroupClick
|
|
5717
5645
|
}) {
|
|
5718
5646
|
if (node.type === "ARTIFACT" && node.artifact) {
|
|
5719
|
-
return /* @__PURE__ */
|
|
5647
|
+
return /* @__PURE__ */ React71.createElement(
|
|
5720
5648
|
ArtifactCard,
|
|
5721
5649
|
{
|
|
5722
5650
|
artifact: node.artifact,
|
|
@@ -5726,10 +5654,10 @@ function NodeRenderer({
|
|
|
5726
5654
|
);
|
|
5727
5655
|
}
|
|
5728
5656
|
if (node.type === "GROUP") {
|
|
5729
|
-
return /* @__PURE__ */
|
|
5657
|
+
return /* @__PURE__ */ React71.createElement(ArtifactGroup, { node, onClick: onGroupClick });
|
|
5730
5658
|
}
|
|
5731
5659
|
if (node.type === "VARIANT_SET") {
|
|
5732
|
-
return /* @__PURE__ */
|
|
5660
|
+
return /* @__PURE__ */ React71.createElement(
|
|
5733
5661
|
ArtifactVariantStack,
|
|
5734
5662
|
{
|
|
5735
5663
|
node,
|
|
@@ -5740,32 +5668,32 @@ function NodeRenderer({
|
|
|
5740
5668
|
}
|
|
5741
5669
|
return null;
|
|
5742
5670
|
}
|
|
5743
|
-
var ArtifactsPanel =
|
|
5671
|
+
var ArtifactsPanel = React71.forwardRef(
|
|
5744
5672
|
({
|
|
5745
5673
|
nodes,
|
|
5746
5674
|
loading,
|
|
5747
5675
|
className,
|
|
5748
5676
|
...rest
|
|
5749
5677
|
}, ref) => {
|
|
5750
|
-
const [expandedArtifact, setExpandedArtifact] =
|
|
5751
|
-
const [zoomIndex, setZoomIndex] =
|
|
5678
|
+
const [expandedArtifact, setExpandedArtifact] = useState17(null);
|
|
5679
|
+
const [zoomIndex, setZoomIndex] = useState17(ZOOM_LEVELS.length - 1);
|
|
5752
5680
|
const treeNav = useArtifactTreeNavigation(nodes || []);
|
|
5753
5681
|
const hasNodes = !!nodes && nodes.length > 0;
|
|
5754
|
-
const handleExpandArtifact =
|
|
5682
|
+
const handleExpandArtifact = useCallback17((artifact) => {
|
|
5755
5683
|
setExpandedArtifact(artifact);
|
|
5756
5684
|
}, []);
|
|
5757
|
-
const handleGroupClick =
|
|
5685
|
+
const handleGroupClick = useCallback17((node) => {
|
|
5758
5686
|
treeNav.navigateInto(node);
|
|
5759
5687
|
}, [treeNav]);
|
|
5760
|
-
const zoomIn =
|
|
5688
|
+
const zoomIn = useCallback17(() => {
|
|
5761
5689
|
setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
|
|
5762
5690
|
}, []);
|
|
5763
|
-
const zoomOut =
|
|
5691
|
+
const zoomOut = useCallback17(() => {
|
|
5764
5692
|
setZoomIndex((prev) => Math.max(prev - 1, 0));
|
|
5765
5693
|
}, []);
|
|
5766
5694
|
const currentZoom = ZOOM_LEVELS[zoomIndex];
|
|
5767
|
-
const contentRef =
|
|
5768
|
-
const [contentHeight, setContentHeight] =
|
|
5695
|
+
const contentRef = useRef11(null);
|
|
5696
|
+
const [contentHeight, setContentHeight] = useState17(void 0);
|
|
5769
5697
|
useEffect12(() => {
|
|
5770
5698
|
const el = contentRef.current;
|
|
5771
5699
|
if (!el) return;
|
|
@@ -5775,7 +5703,7 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5775
5703
|
observer.observe(el);
|
|
5776
5704
|
return () => observer.disconnect();
|
|
5777
5705
|
}, []);
|
|
5778
|
-
return /* @__PURE__ */
|
|
5706
|
+
return /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(
|
|
5779
5707
|
"div",
|
|
5780
5708
|
{
|
|
5781
5709
|
ref,
|
|
@@ -5786,19 +5714,19 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5786
5714
|
),
|
|
5787
5715
|
...rest
|
|
5788
5716
|
},
|
|
5789
|
-
/* @__PURE__ */
|
|
5717
|
+
/* @__PURE__ */ React71.createElement(
|
|
5790
5718
|
"div",
|
|
5791
5719
|
{
|
|
5792
5720
|
className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
|
|
5793
5721
|
},
|
|
5794
|
-
/* @__PURE__ */
|
|
5795
|
-
hasNodes && /* @__PURE__ */
|
|
5722
|
+
/* @__PURE__ */ React71.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
|
|
5723
|
+
hasNodes && /* @__PURE__ */ React71.createElement(
|
|
5796
5724
|
"div",
|
|
5797
5725
|
{
|
|
5798
5726
|
className: "flex items-center gap-0.5",
|
|
5799
5727
|
"data-testid": "zoom-controls"
|
|
5800
5728
|
},
|
|
5801
|
-
/* @__PURE__ */
|
|
5729
|
+
/* @__PURE__ */ React71.createElement(
|
|
5802
5730
|
"button",
|
|
5803
5731
|
{
|
|
5804
5732
|
onClick: zoomOut,
|
|
@@ -5812,8 +5740,8 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5812
5740
|
},
|
|
5813
5741
|
"\u2212"
|
|
5814
5742
|
),
|
|
5815
|
-
/* @__PURE__ */
|
|
5816
|
-
/* @__PURE__ */
|
|
5743
|
+
/* @__PURE__ */ React71.createElement("span", { className: "text-xs text-silver w-8 text-center tabular-nums", "data-testid": "zoom-level" }, Math.round(currentZoom * 100), "%"),
|
|
5744
|
+
/* @__PURE__ */ React71.createElement(
|
|
5817
5745
|
"button",
|
|
5818
5746
|
{
|
|
5819
5747
|
onClick: zoomIn,
|
|
@@ -5829,7 +5757,7 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5829
5757
|
)
|
|
5830
5758
|
)
|
|
5831
5759
|
),
|
|
5832
|
-
hasNodes && !treeNav.isAtRoot && /* @__PURE__ */
|
|
5760
|
+
hasNodes && !treeNav.isAtRoot && /* @__PURE__ */ React71.createElement(
|
|
5833
5761
|
"nav",
|
|
5834
5762
|
{
|
|
5835
5763
|
className: "flex items-center gap-1 px-4 py-2 border-b border-ash/40 shrink-0 overflow-x-auto text-xs",
|
|
@@ -5838,7 +5766,7 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5838
5766
|
},
|
|
5839
5767
|
treeNav.breadcrumbs.map((crumb, i) => {
|
|
5840
5768
|
const isLast = i === treeNav.breadcrumbs.length - 1;
|
|
5841
|
-
return /* @__PURE__ */
|
|
5769
|
+
return /* @__PURE__ */ React71.createElement("span", { key: i, className: "flex items-center gap-1 shrink-0" }, i > 0 && /* @__PURE__ */ React71.createElement(ChevronRightIcon, { className: "w-3 h-3 text-silver/50", "aria-hidden": true }), isLast ? /* @__PURE__ */ React71.createElement("span", { className: "text-gold font-medium" }, crumb.label) : /* @__PURE__ */ React71.createElement(
|
|
5842
5770
|
"button",
|
|
5843
5771
|
{
|
|
5844
5772
|
onClick: () => treeNav.navigateTo(i),
|
|
@@ -5848,18 +5776,18 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5848
5776
|
));
|
|
5849
5777
|
})
|
|
5850
5778
|
),
|
|
5851
|
-
/* @__PURE__ */
|
|
5779
|
+
/* @__PURE__ */ React71.createElement(
|
|
5852
5780
|
"div",
|
|
5853
5781
|
{
|
|
5854
5782
|
className: "flex-1 overflow-auto relative",
|
|
5855
5783
|
"data-testid": "artifacts-scroll-area"
|
|
5856
5784
|
},
|
|
5857
|
-
/* @__PURE__ */
|
|
5785
|
+
/* @__PURE__ */ React71.createElement(
|
|
5858
5786
|
"div",
|
|
5859
5787
|
{
|
|
5860
5788
|
style: currentZoom !== 1 && contentHeight !== void 0 ? { height: contentHeight * currentZoom } : void 0
|
|
5861
5789
|
},
|
|
5862
|
-
/* @__PURE__ */
|
|
5790
|
+
/* @__PURE__ */ React71.createElement(
|
|
5863
5791
|
"div",
|
|
5864
5792
|
{
|
|
5865
5793
|
ref: contentRef,
|
|
@@ -5870,7 +5798,7 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5870
5798
|
transformOrigin: "top center"
|
|
5871
5799
|
} : void 0
|
|
5872
5800
|
},
|
|
5873
|
-
treeNav.currentNodes.length === 0 ? /* @__PURE__ */
|
|
5801
|
+
treeNav.currentNodes.length === 0 ? /* @__PURE__ */ React71.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, hasNodes ? "Empty group" : "No artifacts to display") : treeNav.currentNodes.map((node) => /* @__PURE__ */ React71.createElement(
|
|
5874
5802
|
NodeRenderer,
|
|
5875
5803
|
{
|
|
5876
5804
|
key: node.id,
|
|
@@ -5883,7 +5811,7 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5883
5811
|
)
|
|
5884
5812
|
)
|
|
5885
5813
|
)
|
|
5886
|
-
), expandedArtifact && /* @__PURE__ */
|
|
5814
|
+
), expandedArtifact && /* @__PURE__ */ React71.createElement(
|
|
5887
5815
|
ArtifactModal,
|
|
5888
5816
|
{
|
|
5889
5817
|
artifact: expandedArtifact,
|
|
@@ -5893,8 +5821,8 @@ var ArtifactsPanel = React69.forwardRef(
|
|
|
5893
5821
|
}
|
|
5894
5822
|
);
|
|
5895
5823
|
ArtifactsPanel.displayName = "ArtifactsPanel";
|
|
5896
|
-
var ArtifactsPanelToggle =
|
|
5897
|
-
return /* @__PURE__ */
|
|
5824
|
+
var ArtifactsPanelToggle = React71.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
|
|
5825
|
+
return /* @__PURE__ */ React71.createElement(
|
|
5898
5826
|
"button",
|
|
5899
5827
|
{
|
|
5900
5828
|
ref,
|
|
@@ -5911,24 +5839,8 @@ var ArtifactsPanelToggle = React69.forwardRef(({ artifactCount = 0, onExpand, cl
|
|
|
5911
5839
|
"aria-label": "Expand artifacts panel",
|
|
5912
5840
|
...rest
|
|
5913
5841
|
},
|
|
5914
|
-
/* @__PURE__ */
|
|
5915
|
-
|
|
5916
|
-
{
|
|
5917
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
5918
|
-
viewBox: "0 0 20 20",
|
|
5919
|
-
fill: "currentColor",
|
|
5920
|
-
className: "w-5 h-5"
|
|
5921
|
-
},
|
|
5922
|
-
/* @__PURE__ */ React69.createElement(
|
|
5923
|
-
"path",
|
|
5924
|
-
{
|
|
5925
|
-
fillRule: "evenodd",
|
|
5926
|
-
d: "M2 4.5A1.5 1.5 0 013.5 3h13A1.5 1.5 0 0118 4.5v11a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 012 15.5v-11zM4 5v1h1V5H4zm2 0v1h1V5H6zm7 0v1h1V5h-1zm2 0v1h1V5h-1zM4 14v1h1v-1H4zm2 0v1h1v-1H6zm7 0v1h1v-1h-1zm2 0v1h1v-1h-1zM8 8.118a.5.5 0 01.757-.429l4 2.382a.5.5 0 010 .858l-4 2.382A.5.5 0 018 12.882V8.118z",
|
|
5927
|
-
clipRule: "evenodd"
|
|
5928
|
-
}
|
|
5929
|
-
)
|
|
5930
|
-
),
|
|
5931
|
-
artifactCount > 0 && /* @__PURE__ */ React69.createElement(
|
|
5842
|
+
/* @__PURE__ */ React71.createElement(Image, { className: "w-5 h-5", "aria-hidden": true }),
|
|
5843
|
+
artifactCount > 0 && /* @__PURE__ */ React71.createElement(
|
|
5932
5844
|
"span",
|
|
5933
5845
|
{
|
|
5934
5846
|
className: "absolute -top-1 -right-1 w-4 h-4 bg-gold text-obsidian text-xs font-medium flex items-center justify-center"
|
|
@@ -5940,7 +5852,8 @@ var ArtifactsPanelToggle = React69.forwardRef(({ artifactCount = 0, onExpand, cl
|
|
|
5940
5852
|
ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
|
|
5941
5853
|
|
|
5942
5854
|
// src/components/chat/HistoryPanel.tsx
|
|
5943
|
-
import
|
|
5855
|
+
import React72, { useCallback as useCallback18, useEffect as useEffect13, useMemo as useMemo3, useRef as useRef12, useState as useState18 } from "react";
|
|
5856
|
+
import { ChevronDown as ChevronDown2, Pencil as Pencil2 } from "lucide-react";
|
|
5944
5857
|
function parseTimestamp(ts) {
|
|
5945
5858
|
if (ts == null) {
|
|
5946
5859
|
return null;
|
|
@@ -5976,66 +5889,18 @@ function groupConversations(conversations) {
|
|
|
5976
5889
|
{ key: "older", label: "Older", conversations: olderList }
|
|
5977
5890
|
].filter((g) => g.conversations.length > 0);
|
|
5978
5891
|
}
|
|
5979
|
-
function ChevronDownIcon({ className }) {
|
|
5980
|
-
return /* @__PURE__ */ React70.createElement(
|
|
5981
|
-
"svg",
|
|
5982
|
-
{
|
|
5983
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
5984
|
-
viewBox: "0 0 20 20",
|
|
5985
|
-
fill: "currentColor",
|
|
5986
|
-
className,
|
|
5987
|
-
"aria-hidden": "true"
|
|
5988
|
-
},
|
|
5989
|
-
/* @__PURE__ */ React70.createElement(
|
|
5990
|
-
"path",
|
|
5991
|
-
{
|
|
5992
|
-
fillRule: "evenodd",
|
|
5993
|
-
d: "M5.23 7.21a.75.75 0 011.06.02L10 11.06l3.71-3.83a.75.75 0 111.08 1.04l-4.25 4.39a.75.75 0 01-1.08 0L5.21 8.27a.75.75 0 01.02-1.06z",
|
|
5994
|
-
clipRule: "evenodd"
|
|
5995
|
-
}
|
|
5996
|
-
)
|
|
5997
|
-
);
|
|
5998
|
-
}
|
|
5999
|
-
function PencilIcon2({ className }) {
|
|
6000
|
-
return /* @__PURE__ */ React70.createElement(
|
|
6001
|
-
"svg",
|
|
6002
|
-
{
|
|
6003
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
6004
|
-
viewBox: "0 0 20 20",
|
|
6005
|
-
fill: "currentColor",
|
|
6006
|
-
className,
|
|
6007
|
-
"aria-hidden": "true"
|
|
6008
|
-
},
|
|
6009
|
-
/* @__PURE__ */ React70.createElement(
|
|
6010
|
-
"path",
|
|
6011
|
-
{
|
|
6012
|
-
d: "M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
|
|
6013
|
-
}
|
|
6014
|
-
)
|
|
6015
|
-
);
|
|
6016
|
-
}
|
|
6017
5892
|
function ProjectFilter({
|
|
6018
5893
|
projects,
|
|
6019
5894
|
value,
|
|
6020
5895
|
onChange,
|
|
6021
5896
|
className
|
|
6022
5897
|
}) {
|
|
6023
|
-
const [open, setOpen] =
|
|
6024
|
-
const ref =
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
return;
|
|
6028
|
-
}
|
|
6029
|
-
const handler = (e) => {
|
|
6030
|
-
if (ref.current && !ref.current.contains(e.target)) {
|
|
6031
|
-
setOpen(false);
|
|
6032
|
-
}
|
|
6033
|
-
};
|
|
6034
|
-
document.addEventListener("mousedown", handler);
|
|
6035
|
-
return () => document.removeEventListener("mousedown", handler);
|
|
6036
|
-
}, [open]);
|
|
5898
|
+
const [open, setOpen] = useState18(false);
|
|
5899
|
+
const ref = useRef12(null);
|
|
5900
|
+
const closeFilter = useCallback18(() => setOpen(false), []);
|
|
5901
|
+
useClickOutside(ref, closeFilter, open);
|
|
6037
5902
|
const label = value ?? "All projects";
|
|
6038
|
-
return /* @__PURE__ */
|
|
5903
|
+
return /* @__PURE__ */ React72.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ React72.createElement(
|
|
6039
5904
|
"button",
|
|
6040
5905
|
{
|
|
6041
5906
|
type: "button",
|
|
@@ -6051,9 +5916,9 @@ function ProjectFilter({
|
|
|
6051
5916
|
"transition-colors duration-150 min-w-0"
|
|
6052
5917
|
)
|
|
6053
5918
|
},
|
|
6054
|
-
/* @__PURE__ */
|
|
6055
|
-
/* @__PURE__ */
|
|
6056
|
-
), open && /* @__PURE__ */
|
|
5919
|
+
/* @__PURE__ */ React72.createElement("span", { className: "truncate" }, label),
|
|
5920
|
+
/* @__PURE__ */ React72.createElement(ChevronDown2, { className: "w-3 h-3 shrink-0", "aria-hidden": true })
|
|
5921
|
+
), open && /* @__PURE__ */ React72.createElement(
|
|
6057
5922
|
"div",
|
|
6058
5923
|
{
|
|
6059
5924
|
role: "listbox",
|
|
@@ -6063,7 +5928,7 @@ function ProjectFilter({
|
|
|
6063
5928
|
"max-h-60 overflow-y-auto"
|
|
6064
5929
|
)
|
|
6065
5930
|
},
|
|
6066
|
-
/* @__PURE__ */
|
|
5931
|
+
/* @__PURE__ */ React72.createElement(
|
|
6067
5932
|
"button",
|
|
6068
5933
|
{
|
|
6069
5934
|
type: "button",
|
|
@@ -6081,7 +5946,7 @@ function ProjectFilter({
|
|
|
6081
5946
|
},
|
|
6082
5947
|
"All projects"
|
|
6083
5948
|
),
|
|
6084
|
-
projects.map((p) => /* @__PURE__ */
|
|
5949
|
+
projects.map((p) => /* @__PURE__ */ React72.createElement(
|
|
6085
5950
|
"button",
|
|
6086
5951
|
{
|
|
6087
5952
|
key: p,
|
|
@@ -6107,33 +5972,33 @@ function ConversationRow({
|
|
|
6107
5972
|
onSelect,
|
|
6108
5973
|
onRename
|
|
6109
5974
|
}) {
|
|
6110
|
-
const [isEditing, setIsEditing] =
|
|
6111
|
-
const [draft, setDraft] =
|
|
6112
|
-
const inputRef =
|
|
5975
|
+
const [isEditing, setIsEditing] = useState18(false);
|
|
5976
|
+
const [draft, setDraft] = useState18(conversation.title);
|
|
5977
|
+
const inputRef = useRef12(null);
|
|
6113
5978
|
useEffect13(() => {
|
|
6114
5979
|
if (isEditing && inputRef.current) {
|
|
6115
5980
|
inputRef.current.focus();
|
|
6116
5981
|
inputRef.current.select();
|
|
6117
5982
|
}
|
|
6118
5983
|
}, [isEditing]);
|
|
6119
|
-
const startEdit =
|
|
5984
|
+
const startEdit = useCallback18((e) => {
|
|
6120
5985
|
e.stopPropagation();
|
|
6121
5986
|
setDraft(conversation.title);
|
|
6122
5987
|
setIsEditing(true);
|
|
6123
5988
|
}, [conversation.title]);
|
|
6124
|
-
const commit =
|
|
5989
|
+
const commit = useCallback18(() => {
|
|
6125
5990
|
const trimmed = draft.trim();
|
|
6126
5991
|
if (trimmed && trimmed !== conversation.title) {
|
|
6127
5992
|
onRename?.(conversation.id, trimmed);
|
|
6128
5993
|
}
|
|
6129
5994
|
setIsEditing(false);
|
|
6130
5995
|
}, [draft, conversation.id, conversation.title, onRename]);
|
|
6131
|
-
const cancel =
|
|
5996
|
+
const cancel = useCallback18(() => {
|
|
6132
5997
|
setDraft(conversation.title);
|
|
6133
5998
|
setIsEditing(false);
|
|
6134
5999
|
}, [conversation.title]);
|
|
6135
6000
|
if (isEditing) {
|
|
6136
|
-
return /* @__PURE__ */
|
|
6001
|
+
return /* @__PURE__ */ React72.createElement(
|
|
6137
6002
|
"div",
|
|
6138
6003
|
{
|
|
6139
6004
|
className: cx(
|
|
@@ -6141,7 +6006,7 @@ function ConversationRow({
|
|
|
6141
6006
|
conversation.isActive ? "bg-ash/40" : "bg-ash/20"
|
|
6142
6007
|
)
|
|
6143
6008
|
},
|
|
6144
|
-
/* @__PURE__ */
|
|
6009
|
+
/* @__PURE__ */ React72.createElement(
|
|
6145
6010
|
"input",
|
|
6146
6011
|
{
|
|
6147
6012
|
ref: inputRef,
|
|
@@ -6166,10 +6031,10 @@ function ConversationRow({
|
|
|
6166
6031
|
"aria-label": "Conversation title"
|
|
6167
6032
|
}
|
|
6168
6033
|
),
|
|
6169
|
-
conversation.project && /* @__PURE__ */
|
|
6034
|
+
conversation.project && /* @__PURE__ */ React72.createElement("p", { className: "text-xs text-silver/60 truncate mt-1" }, conversation.project)
|
|
6170
6035
|
);
|
|
6171
6036
|
}
|
|
6172
|
-
return /* @__PURE__ */
|
|
6037
|
+
return /* @__PURE__ */ React72.createElement("div", { className: "relative group" }, /* @__PURE__ */ React72.createElement(
|
|
6173
6038
|
"button",
|
|
6174
6039
|
{
|
|
6175
6040
|
onClick: () => onSelect?.(conversation.id),
|
|
@@ -6179,7 +6044,7 @@ function ConversationRow({
|
|
|
6179
6044
|
conversation.isActive ? "bg-ash/40 text-white" : "text-silver hover:bg-ash/20 hover:text-white"
|
|
6180
6045
|
)
|
|
6181
6046
|
},
|
|
6182
|
-
/* @__PURE__ */
|
|
6047
|
+
/* @__PURE__ */ React72.createElement(
|
|
6183
6048
|
"p",
|
|
6184
6049
|
{
|
|
6185
6050
|
className: cx(
|
|
@@ -6189,8 +6054,8 @@ function ConversationRow({
|
|
|
6189
6054
|
},
|
|
6190
6055
|
conversation.title
|
|
6191
6056
|
),
|
|
6192
|
-
conversation.project && /* @__PURE__ */
|
|
6193
|
-
), onRename && /* @__PURE__ */
|
|
6057
|
+
conversation.project && /* @__PURE__ */ React72.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.project)
|
|
6058
|
+
), onRename && /* @__PURE__ */ React72.createElement(
|
|
6194
6059
|
"button",
|
|
6195
6060
|
{
|
|
6196
6061
|
type: "button",
|
|
@@ -6203,7 +6068,7 @@ function ConversationRow({
|
|
|
6203
6068
|
"transition-opacity duration-150"
|
|
6204
6069
|
)
|
|
6205
6070
|
},
|
|
6206
|
-
/* @__PURE__ */
|
|
6071
|
+
/* @__PURE__ */ React72.createElement(Pencil2, { className: "w-3.5 h-3.5", "aria-hidden": true })
|
|
6207
6072
|
));
|
|
6208
6073
|
}
|
|
6209
6074
|
function HistoryPanel({
|
|
@@ -6212,7 +6077,7 @@ function HistoryPanel({
|
|
|
6212
6077
|
onNewChat,
|
|
6213
6078
|
onRenameConversation
|
|
6214
6079
|
}) {
|
|
6215
|
-
const [projectFilter, setProjectFilter] =
|
|
6080
|
+
const [projectFilter, setProjectFilter] = useState18(null);
|
|
6216
6081
|
const projects = useMemo3(() => {
|
|
6217
6082
|
const set = /* @__PURE__ */ new Set();
|
|
6218
6083
|
for (const c of conversations) {
|
|
@@ -6238,7 +6103,7 @@ function HistoryPanel({
|
|
|
6238
6103
|
[filteredConversations]
|
|
6239
6104
|
);
|
|
6240
6105
|
const hasFilter = projects.length > 0;
|
|
6241
|
-
return /* @__PURE__ */
|
|
6106
|
+
return /* @__PURE__ */ React72.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ React72.createElement("div", { className: "px-4 py-3 border-b border-ash/40 shrink-0 flex items-center gap-2" }, /* @__PURE__ */ React72.createElement("h3", { className: "text-xs font-medium text-white shrink-0" }, "History"), (hasFilter || onNewChat) && /* @__PURE__ */ React72.createElement("div", { className: "flex items-center gap-2 flex-1 min-w-0" }, hasFilter && /* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ React72.createElement(
|
|
6242
6107
|
ProjectFilter,
|
|
6243
6108
|
{
|
|
6244
6109
|
projects,
|
|
@@ -6246,7 +6111,7 @@ function HistoryPanel({
|
|
|
6246
6111
|
onChange: setProjectFilter,
|
|
6247
6112
|
className: "flex-1"
|
|
6248
6113
|
}
|
|
6249
|
-
)), onNewChat && /* @__PURE__ */
|
|
6114
|
+
)), onNewChat && /* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ React72.createElement(
|
|
6250
6115
|
"button",
|
|
6251
6116
|
{
|
|
6252
6117
|
onClick: onNewChat,
|
|
@@ -6258,15 +6123,15 @@ function HistoryPanel({
|
|
|
6258
6123
|
"transition-colors duration-200"
|
|
6259
6124
|
)
|
|
6260
6125
|
},
|
|
6261
|
-
/* @__PURE__ */
|
|
6262
|
-
/* @__PURE__ */
|
|
6263
|
-
)))), /* @__PURE__ */
|
|
6126
|
+
/* @__PURE__ */ React72.createElement(PlusIcon, { className: "w-4 h-4" }),
|
|
6127
|
+
/* @__PURE__ */ React72.createElement("span", { className: "truncate" }, "New Chat")
|
|
6128
|
+
)))), /* @__PURE__ */ React72.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ React72.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations yet") : groups.length === 0 ? /* @__PURE__ */ React72.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations match this filter") : /* @__PURE__ */ React72.createElement("div", null, groups.map((group, index) => /* @__PURE__ */ React72.createElement("section", { key: group.key, className: cx(index > 0 && "mt-3") }, /* @__PURE__ */ React72.createElement("div", { className: "flex items-center gap-2 px-3 pb-2" }, /* @__PURE__ */ React72.createElement(
|
|
6264
6129
|
"span",
|
|
6265
6130
|
{
|
|
6266
6131
|
className: "text-xs font-medium uppercase tracking-wider text-gold/70"
|
|
6267
6132
|
},
|
|
6268
6133
|
group.label
|
|
6269
|
-
), /* @__PURE__ */
|
|
6134
|
+
), /* @__PURE__ */ React72.createElement("div", { className: "flex-1 h-px bg-gold/20" })), /* @__PURE__ */ React72.createElement("div", { className: "space-y-1 px-2" }, group.conversations.map((conversation) => /* @__PURE__ */ React72.createElement(
|
|
6270
6135
|
ConversationRow,
|
|
6271
6136
|
{
|
|
6272
6137
|
key: conversation.id,
|
|
@@ -6278,7 +6143,7 @@ function HistoryPanel({
|
|
|
6278
6143
|
}
|
|
6279
6144
|
|
|
6280
6145
|
// src/components/chat/TodosList.tsx
|
|
6281
|
-
import
|
|
6146
|
+
import React73, { useCallback as useCallback19, useMemo as useMemo4, useState as useState19 } from "react";
|
|
6282
6147
|
import { Loader2 as Loader22, Square as Square2 } from "lucide-react";
|
|
6283
6148
|
var TASK_STATUSES = {
|
|
6284
6149
|
PENDING: "pending",
|
|
@@ -6290,16 +6155,16 @@ var TASK_STATUSES = {
|
|
|
6290
6155
|
function TaskIcon({ status }) {
|
|
6291
6156
|
switch (status) {
|
|
6292
6157
|
case "done":
|
|
6293
|
-
return /* @__PURE__ */
|
|
6158
|
+
return /* @__PURE__ */ React73.createElement(CheckSquareIcon, null);
|
|
6294
6159
|
case "in_progress":
|
|
6295
|
-
return /* @__PURE__ */
|
|
6160
|
+
return /* @__PURE__ */ React73.createElement(SquareLoaderIcon, null);
|
|
6296
6161
|
case "cancelled":
|
|
6297
|
-
return /* @__PURE__ */
|
|
6162
|
+
return /* @__PURE__ */ React73.createElement(CrossSquareIcon, { variant: "cancelled" });
|
|
6298
6163
|
case "failed":
|
|
6299
|
-
return /* @__PURE__ */
|
|
6164
|
+
return /* @__PURE__ */ React73.createElement(CrossSquareIcon, { variant: "failed" });
|
|
6300
6165
|
case "pending":
|
|
6301
6166
|
default:
|
|
6302
|
-
return /* @__PURE__ */
|
|
6167
|
+
return /* @__PURE__ */ React73.createElement(EmptySquareIcon, null);
|
|
6303
6168
|
}
|
|
6304
6169
|
}
|
|
6305
6170
|
function sortTasks(tasks) {
|
|
@@ -6319,14 +6184,14 @@ function TaskItem({ task, depth = 0 }) {
|
|
|
6319
6184
|
const isSubtle = task.status === "cancelled" || task.status === "failed";
|
|
6320
6185
|
const showSubtasks = task.subtasks && task.subtasks.length > 0;
|
|
6321
6186
|
const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
|
|
6322
|
-
return /* @__PURE__ */
|
|
6187
|
+
return /* @__PURE__ */ React73.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React73.createElement(
|
|
6323
6188
|
"div",
|
|
6324
6189
|
{
|
|
6325
6190
|
className: "flex items-center gap-2 py-1",
|
|
6326
6191
|
style: { paddingLeft: `${depth * 1.5}rem` }
|
|
6327
6192
|
},
|
|
6328
|
-
/* @__PURE__ */
|
|
6329
|
-
/* @__PURE__ */
|
|
6193
|
+
/* @__PURE__ */ React73.createElement(TaskIcon, { status: task.status }),
|
|
6194
|
+
/* @__PURE__ */ React73.createElement(
|
|
6330
6195
|
"span",
|
|
6331
6196
|
{
|
|
6332
6197
|
className: cx(
|
|
@@ -6338,10 +6203,10 @@ function TaskItem({ task, depth = 0 }) {
|
|
|
6338
6203
|
)
|
|
6339
6204
|
},
|
|
6340
6205
|
task.label,
|
|
6341
|
-
task.status === "cancelled" && /* @__PURE__ */
|
|
6342
|
-
task.status === "failed" && /* @__PURE__ */
|
|
6206
|
+
task.status === "cancelled" && /* @__PURE__ */ React73.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
|
|
6207
|
+
task.status === "failed" && /* @__PURE__ */ React73.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
|
|
6343
6208
|
)
|
|
6344
|
-
), showSubtasks && /* @__PURE__ */
|
|
6209
|
+
), showSubtasks && /* @__PURE__ */ React73.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ React73.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
|
|
6345
6210
|
}
|
|
6346
6211
|
function hasInProgressTask(tasks) {
|
|
6347
6212
|
return tasks.some((t) => {
|
|
@@ -6354,11 +6219,11 @@ function hasInProgressTask(tasks) {
|
|
|
6354
6219
|
return false;
|
|
6355
6220
|
});
|
|
6356
6221
|
}
|
|
6357
|
-
var TodosList =
|
|
6222
|
+
var TodosList = React73.forwardRef(
|
|
6358
6223
|
({ tasks, title = "Tasks", onStopAllTasks, className, ...rest }, ref) => {
|
|
6359
6224
|
const sortedTasks = useMemo4(() => sortTasks(tasks), [tasks]);
|
|
6360
|
-
const [isStopping, setIsStopping] =
|
|
6361
|
-
const handleStopClick =
|
|
6225
|
+
const [isStopping, setIsStopping] = useState19(false);
|
|
6226
|
+
const handleStopClick = useCallback19(async () => {
|
|
6362
6227
|
if (!onStopAllTasks || isStopping) {
|
|
6363
6228
|
return;
|
|
6364
6229
|
}
|
|
@@ -6379,7 +6244,7 @@ var TodosList = React71.forwardRef(
|
|
|
6379
6244
|
if (tasks.length === 0) {
|
|
6380
6245
|
return null;
|
|
6381
6246
|
}
|
|
6382
|
-
return /* @__PURE__ */
|
|
6247
|
+
return /* @__PURE__ */ React73.createElement(
|
|
6383
6248
|
"div",
|
|
6384
6249
|
{
|
|
6385
6250
|
ref,
|
|
@@ -6390,16 +6255,16 @@ var TodosList = React71.forwardRef(
|
|
|
6390
6255
|
),
|
|
6391
6256
|
...rest
|
|
6392
6257
|
},
|
|
6393
|
-
/* @__PURE__ */
|
|
6258
|
+
/* @__PURE__ */ React73.createElement(
|
|
6394
6259
|
"div",
|
|
6395
6260
|
{
|
|
6396
6261
|
className: "flex items-center justify-between px-4 py-2 border-b border-ash/40 flex-shrink-0"
|
|
6397
6262
|
},
|
|
6398
|
-
/* @__PURE__ */
|
|
6399
|
-
/* @__PURE__ */
|
|
6263
|
+
/* @__PURE__ */ React73.createElement("h4", { className: "text-xs font-medium text-white" }, title),
|
|
6264
|
+
/* @__PURE__ */ React73.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
|
|
6400
6265
|
),
|
|
6401
|
-
/* @__PURE__ */
|
|
6402
|
-
showStopButton && /* @__PURE__ */
|
|
6266
|
+
/* @__PURE__ */ React73.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ React73.createElement(TaskItem, { key: task.id, task }))),
|
|
6267
|
+
showStopButton && /* @__PURE__ */ React73.createElement("div", { className: "px-4 py-2 border-t border-ash/40 flex-shrink-0" }, /* @__PURE__ */ React73.createElement(
|
|
6403
6268
|
"button",
|
|
6404
6269
|
{
|
|
6405
6270
|
type: "button",
|
|
@@ -6416,7 +6281,7 @@ var TodosList = React71.forwardRef(
|
|
|
6416
6281
|
isStopping ? "cursor-not-allowed opacity-70" : "hover:bg-error/20"
|
|
6417
6282
|
)
|
|
6418
6283
|
},
|
|
6419
|
-
isStopping ? /* @__PURE__ */
|
|
6284
|
+
isStopping ? /* @__PURE__ */ React73.createElement(React73.Fragment, null, /* @__PURE__ */ React73.createElement(Loader22, { className: "w-3 h-3 animate-spin" }), "Stopping tasks") : /* @__PURE__ */ React73.createElement(React73.Fragment, null, /* @__PURE__ */ React73.createElement(Square2, { className: "w-3 h-3 fill-current" }), "Stop All Tasks")
|
|
6420
6285
|
))
|
|
6421
6286
|
);
|
|
6422
6287
|
}
|
|
@@ -6436,8 +6301,8 @@ function areAllTasksSettled(tasks) {
|
|
|
6436
6301
|
}
|
|
6437
6302
|
|
|
6438
6303
|
// src/components/chat/ToolSidebar.tsx
|
|
6439
|
-
import
|
|
6440
|
-
var ToolSidebar =
|
|
6304
|
+
import React74 from "react";
|
|
6305
|
+
var ToolSidebar = React74.forwardRef(
|
|
6441
6306
|
({ tools, activeTools, onToggleTool, side, className, ...rest }, ref) => {
|
|
6442
6307
|
const topTools = tools.filter((t) => t.group === `top-${side}`);
|
|
6443
6308
|
const bottomTools = tools.filter((t) => t.group === `bottom-${side}`);
|
|
@@ -6448,7 +6313,7 @@ var ToolSidebar = React72.forwardRef(
|
|
|
6448
6313
|
};
|
|
6449
6314
|
const renderButton = (tool) => {
|
|
6450
6315
|
const active = isActive(tool.id);
|
|
6451
|
-
return /* @__PURE__ */
|
|
6316
|
+
return /* @__PURE__ */ React74.createElement(
|
|
6452
6317
|
"button",
|
|
6453
6318
|
{
|
|
6454
6319
|
key: tool.id,
|
|
@@ -6460,10 +6325,10 @@ var ToolSidebar = React72.forwardRef(
|
|
|
6460
6325
|
"aria-label": tool.label,
|
|
6461
6326
|
"aria-pressed": active
|
|
6462
6327
|
},
|
|
6463
|
-
/* @__PURE__ */
|
|
6328
|
+
/* @__PURE__ */ React74.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
|
|
6464
6329
|
);
|
|
6465
6330
|
};
|
|
6466
|
-
return /* @__PURE__ */
|
|
6331
|
+
return /* @__PURE__ */ React74.createElement(
|
|
6467
6332
|
"div",
|
|
6468
6333
|
{
|
|
6469
6334
|
ref,
|
|
@@ -6474,17 +6339,17 @@ var ToolSidebar = React72.forwardRef(
|
|
|
6474
6339
|
),
|
|
6475
6340
|
...rest
|
|
6476
6341
|
},
|
|
6477
|
-
/* @__PURE__ */
|
|
6478
|
-
/* @__PURE__ */
|
|
6479
|
-
/* @__PURE__ */
|
|
6342
|
+
/* @__PURE__ */ React74.createElement("div", { className: "flex flex-col items-center gap-1" }, topTools.map(renderButton)),
|
|
6343
|
+
/* @__PURE__ */ React74.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ React74.createElement("div", { className: "w-5 border-t border-ash/30" })),
|
|
6344
|
+
/* @__PURE__ */ React74.createElement("div", { className: "flex flex-col items-center gap-1" }, bottomTools.map(renderButton))
|
|
6480
6345
|
);
|
|
6481
6346
|
}
|
|
6482
6347
|
);
|
|
6483
6348
|
ToolSidebar.displayName = "ToolSidebar";
|
|
6484
6349
|
|
|
6485
6350
|
// src/components/chat/ToolPanelContainer.tsx
|
|
6486
|
-
import
|
|
6487
|
-
var ToolPanelContainer =
|
|
6351
|
+
import React75, { useCallback as useCallback20, useEffect as useEffect14, useRef as useRef13, useState as useState20 } from "react";
|
|
6352
|
+
var ToolPanelContainer = React75.forwardRef(
|
|
6488
6353
|
({
|
|
6489
6354
|
topContent,
|
|
6490
6355
|
bottomContent,
|
|
@@ -6495,21 +6360,21 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6495
6360
|
initialTopPercent = 60,
|
|
6496
6361
|
...rest
|
|
6497
6362
|
}, ref) => {
|
|
6498
|
-
const [topPercent, setTopPercent] =
|
|
6499
|
-
const [isResizingHeight, setIsResizingHeight] =
|
|
6500
|
-
const containerRef =
|
|
6501
|
-
const lastY =
|
|
6363
|
+
const [topPercent, setTopPercent] = useState20(initialTopPercent);
|
|
6364
|
+
const [isResizingHeight, setIsResizingHeight] = useState20(false);
|
|
6365
|
+
const containerRef = useRef13(null);
|
|
6366
|
+
const lastY = useRef13(null);
|
|
6502
6367
|
const hasBoth = topContent !== null && bottomContent !== null;
|
|
6503
|
-
const startHeightResize =
|
|
6368
|
+
const startHeightResize = useCallback20((e) => {
|
|
6504
6369
|
e.preventDefault();
|
|
6505
6370
|
setIsResizingHeight(true);
|
|
6506
6371
|
lastY.current = e.clientY;
|
|
6507
6372
|
}, []);
|
|
6508
|
-
const stopHeightResize =
|
|
6373
|
+
const stopHeightResize = useCallback20(() => {
|
|
6509
6374
|
setIsResizingHeight(false);
|
|
6510
6375
|
lastY.current = null;
|
|
6511
6376
|
}, []);
|
|
6512
|
-
const resizeHeight =
|
|
6377
|
+
const resizeHeight = useCallback20(
|
|
6513
6378
|
(e) => {
|
|
6514
6379
|
if (!isResizingHeight || lastY.current === null || !containerRef.current) {
|
|
6515
6380
|
return;
|
|
@@ -6547,17 +6412,10 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6547
6412
|
document.body.style.userSelect = "";
|
|
6548
6413
|
};
|
|
6549
6414
|
}, [isResizingHeight, resizeHeight, stopHeightResize]);
|
|
6550
|
-
return /* @__PURE__ */
|
|
6415
|
+
return /* @__PURE__ */ React75.createElement(
|
|
6551
6416
|
"div",
|
|
6552
6417
|
{
|
|
6553
|
-
ref: (
|
|
6554
|
-
containerRef.current = node;
|
|
6555
|
-
if (typeof ref === "function") {
|
|
6556
|
-
ref(node);
|
|
6557
|
-
} else if (ref) {
|
|
6558
|
-
ref.current = node;
|
|
6559
|
-
}
|
|
6560
|
-
},
|
|
6418
|
+
ref: composeRefs(containerRef, ref),
|
|
6561
6419
|
className: cx(
|
|
6562
6420
|
"h-full bg-charcoal/50 flex flex-col relative shrink-0",
|
|
6563
6421
|
side === "left" ? "border-r border-ash/40" : "border-l border-ash/40",
|
|
@@ -6566,7 +6424,7 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6566
6424
|
style: width ? { width } : void 0,
|
|
6567
6425
|
...rest
|
|
6568
6426
|
},
|
|
6569
|
-
/* @__PURE__ */
|
|
6427
|
+
/* @__PURE__ */ React75.createElement(
|
|
6570
6428
|
"div",
|
|
6571
6429
|
{
|
|
6572
6430
|
onMouseDown: onResizeStart,
|
|
@@ -6577,7 +6435,7 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6577
6435
|
)
|
|
6578
6436
|
}
|
|
6579
6437
|
),
|
|
6580
|
-
topContent !== null && /* @__PURE__ */
|
|
6438
|
+
topContent !== null && /* @__PURE__ */ React75.createElement(
|
|
6581
6439
|
"div",
|
|
6582
6440
|
{
|
|
6583
6441
|
className: "min-h-0 overflow-hidden flex flex-col",
|
|
@@ -6585,7 +6443,7 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6585
6443
|
},
|
|
6586
6444
|
topContent
|
|
6587
6445
|
),
|
|
6588
|
-
hasBoth && /* @__PURE__ */
|
|
6446
|
+
hasBoth && /* @__PURE__ */ React75.createElement(
|
|
6589
6447
|
"div",
|
|
6590
6448
|
{
|
|
6591
6449
|
onMouseDown: startHeightResize,
|
|
@@ -6597,7 +6455,7 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6597
6455
|
)
|
|
6598
6456
|
}
|
|
6599
6457
|
),
|
|
6600
|
-
bottomContent !== null && /* @__PURE__ */
|
|
6458
|
+
bottomContent !== null && /* @__PURE__ */ React75.createElement(
|
|
6601
6459
|
"div",
|
|
6602
6460
|
{
|
|
6603
6461
|
className: "min-h-0 overflow-hidden flex flex-col",
|
|
@@ -6611,26 +6469,26 @@ var ToolPanelContainer = React73.forwardRef(
|
|
|
6611
6469
|
ToolPanelContainer.displayName = "ToolPanelContainer";
|
|
6612
6470
|
|
|
6613
6471
|
// src/components/chat/hooks/useResizable.ts
|
|
6614
|
-
import { useCallback as
|
|
6472
|
+
import { useCallback as useCallback21, useEffect as useEffect15, useRef as useRef14, useState as useState21 } from "react";
|
|
6615
6473
|
function useResizable({
|
|
6616
6474
|
initialWidthPercent,
|
|
6617
6475
|
minWidthPercent,
|
|
6618
6476
|
maxWidthPercent,
|
|
6619
6477
|
direction
|
|
6620
6478
|
}) {
|
|
6621
|
-
const [widthPercent, setWidthPercent] =
|
|
6622
|
-
const [isResizing, setIsResizing] =
|
|
6623
|
-
const lastX =
|
|
6624
|
-
const startResizing =
|
|
6479
|
+
const [widthPercent, setWidthPercent] = useState21(initialWidthPercent);
|
|
6480
|
+
const [isResizing, setIsResizing] = useState21(false);
|
|
6481
|
+
const lastX = useRef14(null);
|
|
6482
|
+
const startResizing = useCallback21((e) => {
|
|
6625
6483
|
e.preventDefault();
|
|
6626
6484
|
setIsResizing(true);
|
|
6627
6485
|
lastX.current = e.clientX;
|
|
6628
6486
|
}, []);
|
|
6629
|
-
const stopResizing =
|
|
6487
|
+
const stopResizing = useCallback21(() => {
|
|
6630
6488
|
setIsResizing(false);
|
|
6631
6489
|
lastX.current = null;
|
|
6632
6490
|
}, []);
|
|
6633
|
-
const resize =
|
|
6491
|
+
const resize = useCallback21(
|
|
6634
6492
|
(e) => {
|
|
6635
6493
|
if (!isResizing || lastX.current === null) {
|
|
6636
6494
|
return;
|
|
@@ -6669,8 +6527,150 @@ function useResizable({
|
|
|
6669
6527
|
return { width, widthPercent, isResizing, startResizing };
|
|
6670
6528
|
}
|
|
6671
6529
|
|
|
6530
|
+
// src/components/chat/tree.ts
|
|
6531
|
+
function createEmptyTree() {
|
|
6532
|
+
return { nodes: {}, rootIds: [], activeLeafId: null, lastLeafId: null };
|
|
6533
|
+
}
|
|
6534
|
+
function addNodeToTree(tree, node, parentId = null) {
|
|
6535
|
+
const newNodes = { ...tree.nodes };
|
|
6536
|
+
const newRootIds = [...tree.rootIds];
|
|
6537
|
+
const branchIndex = parentId ? newNodes[parentId]?.children.length ?? 0 : newRootIds.length;
|
|
6538
|
+
newNodes[node.id] = {
|
|
6539
|
+
...node,
|
|
6540
|
+
parentId,
|
|
6541
|
+
children: [],
|
|
6542
|
+
branchIndex,
|
|
6543
|
+
createdAt: node.createdAt ?? Date.now()
|
|
6544
|
+
};
|
|
6545
|
+
if (parentId && newNodes[parentId]) {
|
|
6546
|
+
newNodes[parentId] = {
|
|
6547
|
+
...newNodes[parentId],
|
|
6548
|
+
children: [...newNodes[parentId].children, node.id]
|
|
6549
|
+
};
|
|
6550
|
+
} else {
|
|
6551
|
+
newRootIds.push(node.id);
|
|
6552
|
+
}
|
|
6553
|
+
return {
|
|
6554
|
+
nodes: newNodes,
|
|
6555
|
+
rootIds: newRootIds,
|
|
6556
|
+
activeLeafId: node.id,
|
|
6557
|
+
lastLeafId: node.id
|
|
6558
|
+
};
|
|
6559
|
+
}
|
|
6560
|
+
function getActivePath(tree) {
|
|
6561
|
+
return walkUp(tree, tree.activeLeafId).reverse();
|
|
6562
|
+
}
|
|
6563
|
+
function findAncestor(tree, fromId, predicate) {
|
|
6564
|
+
let id = fromId;
|
|
6565
|
+
while (id) {
|
|
6566
|
+
const node = tree.nodes[id];
|
|
6567
|
+
if (!node) return null;
|
|
6568
|
+
if (predicate(node)) return node;
|
|
6569
|
+
id = node.parentId;
|
|
6570
|
+
}
|
|
6571
|
+
return null;
|
|
6572
|
+
}
|
|
6573
|
+
function getSiblingInfo(tree, nodeId) {
|
|
6574
|
+
const siblings = siblingsOf(tree, nodeId);
|
|
6575
|
+
const index = siblings.indexOf(nodeId);
|
|
6576
|
+
if (index < 0) return { total: 1, current: 1 };
|
|
6577
|
+
return { total: siblings.length, current: index + 1 };
|
|
6578
|
+
}
|
|
6579
|
+
function isBranchPoint(tree, nodeId) {
|
|
6580
|
+
return (tree.nodes[nodeId]?.children.length ?? 0) > 1;
|
|
6581
|
+
}
|
|
6582
|
+
function switchBranch(tree, nodeId, direction) {
|
|
6583
|
+
const siblings = siblingsOf(tree, nodeId);
|
|
6584
|
+
if (siblings.length <= 1) return tree;
|
|
6585
|
+
const currentIndex = siblings.indexOf(nodeId);
|
|
6586
|
+
const newIndex = direction === "next" ? (currentIndex + 1) % siblings.length : (currentIndex - 1 + siblings.length) % siblings.length;
|
|
6587
|
+
const leafId = deepestLeafOf(tree, siblings[newIndex]);
|
|
6588
|
+
return { ...tree, activeLeafId: leafId, lastLeafId: leafId };
|
|
6589
|
+
}
|
|
6590
|
+
function setActiveLeaf(tree, leafId) {
|
|
6591
|
+
if (!leafId || !tree.nodes[leafId]) {
|
|
6592
|
+
return { ...tree, activeLeafId: leafId, lastLeafId: leafId };
|
|
6593
|
+
}
|
|
6594
|
+
const lastLeafId = tree.lastLeafId && isAncestor(tree, leafId, tree.lastLeafId) ? tree.lastLeafId : leafId;
|
|
6595
|
+
return { ...tree, activeLeafId: leafId, lastLeafId };
|
|
6596
|
+
}
|
|
6597
|
+
function getGreyedFuture(tree) {
|
|
6598
|
+
const { activeLeafId, lastLeafId } = tree;
|
|
6599
|
+
if (!activeLeafId || !lastLeafId || activeLeafId === lastLeafId) return [];
|
|
6600
|
+
const path = [];
|
|
6601
|
+
let id = lastLeafId;
|
|
6602
|
+
while (id && id !== activeLeafId) {
|
|
6603
|
+
const node = tree.nodes[id];
|
|
6604
|
+
if (!node) return [];
|
|
6605
|
+
path.unshift(node);
|
|
6606
|
+
id = node.parentId;
|
|
6607
|
+
}
|
|
6608
|
+
return id === activeLeafId ? path : [];
|
|
6609
|
+
}
|
|
6610
|
+
function messagesToTree(messages) {
|
|
6611
|
+
let tree = createEmptyTree();
|
|
6612
|
+
for (const msg of messages) {
|
|
6613
|
+
const parentId = tree.activeLeafId;
|
|
6614
|
+
tree = addNodeToTree(
|
|
6615
|
+
tree,
|
|
6616
|
+
{ ...msg, kind: "message", parentId },
|
|
6617
|
+
parentId
|
|
6618
|
+
);
|
|
6619
|
+
}
|
|
6620
|
+
return tree;
|
|
6621
|
+
}
|
|
6622
|
+
function updateMessageContent(tree, nodeId, content, isStreaming) {
|
|
6623
|
+
const node = tree.nodes[nodeId];
|
|
6624
|
+
if (!node || node.kind !== "message") return tree;
|
|
6625
|
+
const updated = {
|
|
6626
|
+
...node,
|
|
6627
|
+
content,
|
|
6628
|
+
isStreaming: isStreaming ?? node.isStreaming
|
|
6629
|
+
};
|
|
6630
|
+
return {
|
|
6631
|
+
...tree,
|
|
6632
|
+
nodes: {
|
|
6633
|
+
...tree.nodes,
|
|
6634
|
+
[nodeId]: updated
|
|
6635
|
+
}
|
|
6636
|
+
};
|
|
6637
|
+
}
|
|
6638
|
+
function walkUp(tree, fromId) {
|
|
6639
|
+
const out = [];
|
|
6640
|
+
let id = fromId;
|
|
6641
|
+
while (id) {
|
|
6642
|
+
const node = tree.nodes[id];
|
|
6643
|
+
if (!node) break;
|
|
6644
|
+
out.push(node);
|
|
6645
|
+
id = node.parentId;
|
|
6646
|
+
}
|
|
6647
|
+
return out;
|
|
6648
|
+
}
|
|
6649
|
+
function siblingsOf(tree, nodeId) {
|
|
6650
|
+
const node = tree.nodes[nodeId];
|
|
6651
|
+
if (!node) return [];
|
|
6652
|
+
return node.parentId ? tree.nodes[node.parentId]?.children ?? [] : tree.rootIds;
|
|
6653
|
+
}
|
|
6654
|
+
function deepestLeafOf(tree, nodeId) {
|
|
6655
|
+
let id = nodeId;
|
|
6656
|
+
let node = tree.nodes[id];
|
|
6657
|
+
while (node && node.children.length > 0) {
|
|
6658
|
+
id = node.children[node.children.length - 1];
|
|
6659
|
+
node = tree.nodes[id];
|
|
6660
|
+
}
|
|
6661
|
+
return id;
|
|
6662
|
+
}
|
|
6663
|
+
function isAncestor(tree, ancestorId, descendantId) {
|
|
6664
|
+
let id = descendantId;
|
|
6665
|
+
while (id) {
|
|
6666
|
+
if (id === ancestorId) return true;
|
|
6667
|
+
id = tree.nodes[id]?.parentId ?? null;
|
|
6668
|
+
}
|
|
6669
|
+
return false;
|
|
6670
|
+
}
|
|
6671
|
+
|
|
6672
6672
|
// src/components/chat/ChatInterface.tsx
|
|
6673
|
-
var ChatInterface =
|
|
6673
|
+
var ChatInterface = React76.forwardRef(
|
|
6674
6674
|
({
|
|
6675
6675
|
messages = [],
|
|
6676
6676
|
conversationTree,
|
|
@@ -6679,6 +6679,8 @@ var ChatInterface = React74.forwardRef(
|
|
|
6679
6679
|
onMessageSubmit,
|
|
6680
6680
|
onEditMessage,
|
|
6681
6681
|
onRetryMessage,
|
|
6682
|
+
onJumpToCheckpoint,
|
|
6683
|
+
onJumpToLatest,
|
|
6682
6684
|
onStop,
|
|
6683
6685
|
onSelectConversation,
|
|
6684
6686
|
onNewChat,
|
|
@@ -6707,15 +6709,15 @@ var ChatInterface = React74.forwardRef(
|
|
|
6707
6709
|
className,
|
|
6708
6710
|
...rest
|
|
6709
6711
|
}, ref) => {
|
|
6710
|
-
const prevArtifactNodesRef =
|
|
6711
|
-
const prevTasksRef =
|
|
6712
|
-
const [internalTools, setInternalTools] =
|
|
6712
|
+
const prevArtifactNodesRef = useRef15([]);
|
|
6713
|
+
const prevTasksRef = useRef15([]);
|
|
6714
|
+
const [internalTools, setInternalTools] = useState22({
|
|
6713
6715
|
"top-left": "history",
|
|
6714
6716
|
"bottom-left": null,
|
|
6715
6717
|
"top-right": null,
|
|
6716
6718
|
"bottom-right": null
|
|
6717
6719
|
});
|
|
6718
|
-
const dismissedToolsRef =
|
|
6720
|
+
const dismissedToolsRef = useRef15(/* @__PURE__ */ new Set());
|
|
6719
6721
|
const isPanelControlled = isArtifactsPanelOpen !== void 0;
|
|
6720
6722
|
const activeTools = useMemo5(() => {
|
|
6721
6723
|
if (isPanelControlled) {
|
|
@@ -6749,11 +6751,11 @@ var ChatInterface = React74.forwardRef(
|
|
|
6749
6751
|
const allSettled = tasks.length === 0 || areAllTasksSettled(tasks);
|
|
6750
6752
|
const allToolDefinitions = useMemo5(() => {
|
|
6751
6753
|
const builtIn = [
|
|
6752
|
-
{ id: "history", icon: /* @__PURE__ */
|
|
6753
|
-
{ id: "artifacts", icon: /* @__PURE__ */
|
|
6754
|
+
{ id: "history", icon: /* @__PURE__ */ React76.createElement(ChatBubbleIcon, null), label: "History", group: "top-left" },
|
|
6755
|
+
{ id: "artifacts", icon: /* @__PURE__ */ React76.createElement(MediaIcon, null), label: "Artifacts", group: "top-right" },
|
|
6754
6756
|
{
|
|
6755
6757
|
id: "todos",
|
|
6756
|
-
icon: allSettled ? /* @__PURE__ */
|
|
6758
|
+
icon: allSettled ? /* @__PURE__ */ React76.createElement(CheckSquareIcon, null) : /* @__PURE__ */ React76.createElement(SquareLoaderIcon, null),
|
|
6757
6759
|
label: "Tasks",
|
|
6758
6760
|
group: "bottom-right"
|
|
6759
6761
|
}
|
|
@@ -6761,7 +6763,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6761
6763
|
const external = externalTools.map(({ content: _content, ...def }) => def);
|
|
6762
6764
|
return [...builtIn, ...external];
|
|
6763
6765
|
}, [allSettled, externalTools]);
|
|
6764
|
-
const toggleTool =
|
|
6766
|
+
const toggleTool = useCallback22((toolId) => {
|
|
6765
6767
|
const toolDef = allToolDefinitions.find((t) => t.id === toolId);
|
|
6766
6768
|
if (!toolDef) {
|
|
6767
6769
|
return;
|
|
@@ -6791,20 +6793,24 @@ var ChatInterface = React74.forwardRef(
|
|
|
6791
6793
|
});
|
|
6792
6794
|
}, [allToolDefinitions, isPanelControlled, activeTools, onArtifactsPanelOpenChange]);
|
|
6793
6795
|
const isTreeMode = !!conversationTree;
|
|
6794
|
-
const
|
|
6795
|
-
|
|
6796
|
-
|
|
6797
|
-
}
|
|
6798
|
-
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
|
|
6796
|
+
const tree = isTreeMode ? conversationTree : null;
|
|
6797
|
+
const activePath = useMemo5(() => {
|
|
6798
|
+
if (tree) return getActivePath(tree);
|
|
6799
|
+
return (messages || []).map((m) => ({ ...m, children: [], branchIndex: 0 }));
|
|
6800
|
+
}, [tree, messages]);
|
|
6801
|
+
const greyedFuture = useMemo5(
|
|
6802
|
+
() => tree ? getGreyedFuture(tree) : [],
|
|
6803
|
+
[tree]
|
|
6804
|
+
);
|
|
6805
|
+
const activeCheckpointId = useMemo5(() => {
|
|
6806
|
+
if (!tree) return null;
|
|
6807
|
+
const found = findAncestor(
|
|
6808
|
+
tree,
|
|
6809
|
+
tree.activeLeafId,
|
|
6810
|
+
(n) => n.kind === "checkpoint"
|
|
6811
|
+
);
|
|
6812
|
+
return found?.id ?? null;
|
|
6813
|
+
}, [tree]);
|
|
6808
6814
|
useEffect16(() => {
|
|
6809
6815
|
const nodes = artifactNodes || [];
|
|
6810
6816
|
const prevNodes = prevArtifactNodesRef.current;
|
|
@@ -6830,66 +6836,115 @@ var ChatInterface = React74.forwardRef(
|
|
|
6830
6836
|
prevArtifactNodesRef.current = nodes;
|
|
6831
6837
|
prevTasksRef.current = tasks;
|
|
6832
6838
|
}, [artifactNodes, tasks, isPanelControlled]);
|
|
6833
|
-
const handleBranchSwitch =
|
|
6839
|
+
const handleBranchSwitch = useCallback22(
|
|
6834
6840
|
(nodeId, direction) => {
|
|
6835
|
-
if (!
|
|
6841
|
+
if (!tree || !onTreeChange) {
|
|
6836
6842
|
return;
|
|
6837
6843
|
}
|
|
6838
|
-
|
|
6839
|
-
onTreeChange(newTree);
|
|
6844
|
+
onTreeChange(switchBranch(tree, nodeId, direction));
|
|
6840
6845
|
},
|
|
6841
|
-
[
|
|
6846
|
+
[tree, onTreeChange]
|
|
6842
6847
|
);
|
|
6843
|
-
const
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
6848
|
+
const handleJumpToCheckpoint = useCallback22((checkpointId) => {
|
|
6849
|
+
if (!tree) return;
|
|
6850
|
+
if (onJumpToCheckpoint) {
|
|
6851
|
+
onJumpToCheckpoint(checkpointId);
|
|
6852
|
+
return;
|
|
6853
|
+
}
|
|
6854
|
+
if (onTreeChange) {
|
|
6855
|
+
onTreeChange(setActiveLeaf(tree, checkpointId));
|
|
6856
|
+
}
|
|
6857
|
+
}, [tree, onTreeChange, onJumpToCheckpoint]);
|
|
6858
|
+
const handleJumpToLatest = useCallback22(() => {
|
|
6859
|
+
if (!tree) return;
|
|
6860
|
+
if (onJumpToLatest) {
|
|
6861
|
+
onJumpToLatest();
|
|
6862
|
+
return;
|
|
6863
|
+
}
|
|
6864
|
+
if (onTreeChange && tree.lastLeafId) {
|
|
6865
|
+
onTreeChange(setActiveLeaf(tree, tree.lastLeafId));
|
|
6866
|
+
}
|
|
6867
|
+
}, [tree, onTreeChange, onJumpToLatest]);
|
|
6868
|
+
const buildItem = useCallback22(
|
|
6869
|
+
(node, opts) => {
|
|
6870
|
+
const branchInfo = tree && getSiblingInfo(tree, node.id).total > 1 ? {
|
|
6871
|
+
...getSiblingInfo(tree, node.id),
|
|
6872
|
+
onPrevious: () => handleBranchSwitch(node.id, "prev"),
|
|
6873
|
+
onNext: () => handleBranchSwitch(node.id, "next")
|
|
6874
|
+
} : void 0;
|
|
6875
|
+
if (node.kind === "checkpoint") {
|
|
6876
|
+
return {
|
|
6877
|
+
kind: "checkpoint",
|
|
6878
|
+
id: node.id,
|
|
6879
|
+
name: node.name,
|
|
6880
|
+
executionKind: node.executionKind,
|
|
6881
|
+
status: node.status,
|
|
6882
|
+
isActive: node.id === activeCheckpointId && !opts.muted,
|
|
6883
|
+
muted: opts.muted,
|
|
6884
|
+
branchInfo,
|
|
6885
|
+
onJumpHere: () => handleJumpToCheckpoint(node.id)
|
|
6886
|
+
};
|
|
6856
6887
|
}
|
|
6857
6888
|
const actions = enableMessageActions ? {
|
|
6858
6889
|
showCopy: true,
|
|
6859
|
-
onEdit:
|
|
6860
|
-
onRetry:
|
|
6890
|
+
onEdit: node.role === "user" && onEditMessage ? (newContent) => onEditMessage(node.id, newContent) : void 0,
|
|
6891
|
+
onRetry: node.role === "assistant" && onRetryMessage ? () => onRetryMessage(node.id) : void 0
|
|
6861
6892
|
} : void 0;
|
|
6862
|
-
const {
|
|
6863
|
-
role,
|
|
6864
|
-
parentId,
|
|
6865
|
-
children,
|
|
6866
|
-
branchIndex,
|
|
6867
|
-
createdAt,
|
|
6868
|
-
...rest2
|
|
6869
|
-
} = msg;
|
|
6870
6893
|
return {
|
|
6871
|
-
|
|
6872
|
-
|
|
6894
|
+
kind: "message",
|
|
6895
|
+
id: node.id,
|
|
6896
|
+
variant: node.role,
|
|
6897
|
+
content: node.content,
|
|
6898
|
+
isStreaming: node.isStreaming,
|
|
6899
|
+
muted: opts.muted,
|
|
6873
6900
|
branchInfo,
|
|
6874
6901
|
actions
|
|
6875
6902
|
};
|
|
6876
|
-
}
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6903
|
+
},
|
|
6904
|
+
[
|
|
6905
|
+
tree,
|
|
6906
|
+
activeCheckpointId,
|
|
6907
|
+
enableMessageActions,
|
|
6908
|
+
onEditMessage,
|
|
6909
|
+
onRetryMessage,
|
|
6910
|
+
handleBranchSwitch,
|
|
6911
|
+
handleJumpToCheckpoint
|
|
6912
|
+
]
|
|
6913
|
+
);
|
|
6914
|
+
const displayItems = useMemo5(() => {
|
|
6915
|
+
const items = activePath.map((n) => buildItem(n, { muted: false }));
|
|
6916
|
+
if (greyedFuture.length > 0) {
|
|
6917
|
+
const messageCount = greyedFuture.filter((n) => n.kind === "message").length;
|
|
6918
|
+
const checkpointCount = greyedFuture.filter((n) => n.kind === "checkpoint").length;
|
|
6919
|
+
items.push({
|
|
6920
|
+
kind: "divider",
|
|
6921
|
+
id: "__greyed_divider__",
|
|
6922
|
+
messageCount,
|
|
6923
|
+
checkpointCount,
|
|
6924
|
+
onJumpToLatest: handleJumpToLatest
|
|
6925
|
+
});
|
|
6926
|
+
for (const n of greyedFuture) {
|
|
6927
|
+
items.push(buildItem(n, { muted: true }));
|
|
6928
|
+
}
|
|
6929
|
+
}
|
|
6930
|
+
return items;
|
|
6931
|
+
}, [activePath, greyedFuture, buildItem, handleJumpToLatest]);
|
|
6932
|
+
const latestUserMessageIndex = useMemo5(() => {
|
|
6933
|
+
for (let i = displayItems.length - 1; i >= 0; i--) {
|
|
6934
|
+
const item = displayItems[i];
|
|
6935
|
+
if (item.kind === "message" && item.variant === "user" && !item.muted) {
|
|
6936
|
+
return i;
|
|
6937
|
+
}
|
|
6938
|
+
}
|
|
6939
|
+
return -1;
|
|
6940
|
+
}, [displayItems]);
|
|
6941
|
+
const handleSubmit = useCallback22(
|
|
6887
6942
|
(message, attachments) => {
|
|
6888
6943
|
onMessageSubmit?.(message, attachments);
|
|
6889
6944
|
},
|
|
6890
6945
|
[onMessageSubmit]
|
|
6891
6946
|
);
|
|
6892
|
-
const isEmpty =
|
|
6947
|
+
const isEmpty = displayItems.length === 0;
|
|
6893
6948
|
const leftToolDefs = useMemo5(
|
|
6894
6949
|
() => allToolDefinitions.filter((t) => t.group === "top-left" || t.group === "bottom-left"),
|
|
6895
6950
|
[allToolDefinitions]
|
|
@@ -6908,7 +6963,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6908
6963
|
}
|
|
6909
6964
|
switch (toolId) {
|
|
6910
6965
|
case "history":
|
|
6911
|
-
return /* @__PURE__ */
|
|
6966
|
+
return /* @__PURE__ */ React76.createElement(
|
|
6912
6967
|
HistoryPanel,
|
|
6913
6968
|
{
|
|
6914
6969
|
conversations,
|
|
@@ -6918,7 +6973,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6918
6973
|
}
|
|
6919
6974
|
);
|
|
6920
6975
|
case "artifacts":
|
|
6921
|
-
return /* @__PURE__ */
|
|
6976
|
+
return /* @__PURE__ */ React76.createElement(
|
|
6922
6977
|
ArtifactsPanel,
|
|
6923
6978
|
{
|
|
6924
6979
|
nodes: artifactNodes,
|
|
@@ -6926,7 +6981,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6926
6981
|
}
|
|
6927
6982
|
);
|
|
6928
6983
|
case "todos":
|
|
6929
|
-
return tasks.length > 0 ? /* @__PURE__ */
|
|
6984
|
+
return tasks.length > 0 ? /* @__PURE__ */ React76.createElement(
|
|
6930
6985
|
TodosList,
|
|
6931
6986
|
{
|
|
6932
6987
|
tasks,
|
|
@@ -6934,21 +6989,21 @@ var ChatInterface = React74.forwardRef(
|
|
|
6934
6989
|
onStopAllTasks,
|
|
6935
6990
|
className: "h-full"
|
|
6936
6991
|
}
|
|
6937
|
-
) : /* @__PURE__ */
|
|
6992
|
+
) : /* @__PURE__ */ React76.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ React76.createElement("div", { className: "flex items-center p-4 border-b border-ash/40 shrink-0" }, /* @__PURE__ */ React76.createElement("h3", { className: "text-xs font-medium text-white" }, "Tasks")), /* @__PURE__ */ React76.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ React76.createElement("p", { className: "text-xs text-silver/60" }, "No tasks")));
|
|
6938
6993
|
default: {
|
|
6939
6994
|
const externalTool = externalTools.find((t) => t.id === toolId);
|
|
6940
6995
|
return externalTool?.content ?? null;
|
|
6941
6996
|
}
|
|
6942
6997
|
}
|
|
6943
6998
|
};
|
|
6944
|
-
return /* @__PURE__ */
|
|
6999
|
+
return /* @__PURE__ */ React76.createElement(
|
|
6945
7000
|
"div",
|
|
6946
7001
|
{
|
|
6947
7002
|
ref,
|
|
6948
7003
|
className: cx("flex h-full w-full bg-obsidian overflow-hidden", className),
|
|
6949
7004
|
...rest
|
|
6950
7005
|
},
|
|
6951
|
-
hasLeftTools && /* @__PURE__ */
|
|
7006
|
+
hasLeftTools && /* @__PURE__ */ React76.createElement(
|
|
6952
7007
|
ToolSidebar,
|
|
6953
7008
|
{
|
|
6954
7009
|
tools: leftToolDefs,
|
|
@@ -6957,7 +7012,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
6957
7012
|
side: "left"
|
|
6958
7013
|
}
|
|
6959
7014
|
),
|
|
6960
|
-
isLeftPanelOpen && /* @__PURE__ */
|
|
7015
|
+
isLeftPanelOpen && /* @__PURE__ */ React76.createElement(
|
|
6961
7016
|
ToolPanelContainer,
|
|
6962
7017
|
{
|
|
6963
7018
|
topContent: renderToolContent(activeTools["top-left"]),
|
|
@@ -6968,28 +7023,28 @@ var ChatInterface = React74.forwardRef(
|
|
|
6968
7023
|
initialTopPercent: 30
|
|
6969
7024
|
}
|
|
6970
7025
|
),
|
|
6971
|
-
/* @__PURE__ */
|
|
7026
|
+
/* @__PURE__ */ React76.createElement("div", { className: "flex-1 flex flex-col min-w-0 relative" }, /* @__PURE__ */ React76.createElement("div", { className: cx(
|
|
6972
7027
|
"flex-1 flex flex-col min-h-0 relative",
|
|
6973
7028
|
isEmpty ? "justify-center" : "justify-start"
|
|
6974
|
-
) }, /* @__PURE__ */
|
|
7029
|
+
) }, /* @__PURE__ */ React76.createElement("div", { className: cx(
|
|
6975
7030
|
"transition-all duration-500 ease-in-out",
|
|
6976
7031
|
isEmpty ? "flex-1" : "flex-zero"
|
|
6977
|
-
) }), /* @__PURE__ */
|
|
7032
|
+
) }), /* @__PURE__ */ React76.createElement("div", { className: cx(
|
|
6978
7033
|
"transition-all duration-500 ease-in-out overflow-hidden flex flex-col",
|
|
6979
7034
|
isEmpty ? "flex-zero opacity-0" : "flex-1 opacity-100"
|
|
6980
|
-
) }, /* @__PURE__ */
|
|
7035
|
+
) }, /* @__PURE__ */ React76.createElement(
|
|
6981
7036
|
ChatView,
|
|
6982
7037
|
{
|
|
6983
|
-
|
|
7038
|
+
items: displayItems,
|
|
6984
7039
|
latestUserMessageIndex,
|
|
6985
7040
|
isStreaming,
|
|
6986
7041
|
isThinking,
|
|
6987
7042
|
className: "flex-1"
|
|
6988
7043
|
}
|
|
6989
|
-
)), /* @__PURE__ */
|
|
7044
|
+
)), /* @__PURE__ */ React76.createElement("div", { className: cx(
|
|
6990
7045
|
"transition-all duration-500 ease-in-out z-10 w-full flex flex-col items-center",
|
|
6991
7046
|
isEmpty ? "p-4" : "shrink-0 p-4 border-t border-ash/40 bg-obsidian"
|
|
6992
|
-
) }, isEmpty && /* @__PURE__ */
|
|
7047
|
+
) }, isEmpty && /* @__PURE__ */ React76.createElement("div", { className: "mb-8 text-center animate-fade-in duration-500" }, emptyState ? emptyState : /* @__PURE__ */ React76.createElement("h1", { className: "text-4xl md:text-5xl font-heading text-gold mb-2 tracking-tight" }, "Welcome!")), /* @__PURE__ */ React76.createElement(
|
|
6993
7048
|
ChatInput,
|
|
6994
7049
|
{
|
|
6995
7050
|
position: isEmpty ? "centered" : "bottom",
|
|
@@ -7008,11 +7063,11 @@ var ChatInterface = React74.forwardRef(
|
|
|
7008
7063
|
initialInputValue,
|
|
7009
7064
|
autoFocus
|
|
7010
7065
|
}
|
|
7011
|
-
)), /* @__PURE__ */
|
|
7066
|
+
)), /* @__PURE__ */ React76.createElement("div", { className: cx(
|
|
7012
7067
|
"transition-all duration-500 ease-in-out",
|
|
7013
7068
|
isEmpty ? "flex-1" : "flex-zero"
|
|
7014
7069
|
) }))),
|
|
7015
|
-
isRightPanelOpen && /* @__PURE__ */
|
|
7070
|
+
isRightPanelOpen && /* @__PURE__ */ React76.createElement(
|
|
7016
7071
|
ToolPanelContainer,
|
|
7017
7072
|
{
|
|
7018
7073
|
topContent: renderToolContent(activeTools["top-right"]),
|
|
@@ -7023,7 +7078,7 @@ var ChatInterface = React74.forwardRef(
|
|
|
7023
7078
|
initialTopPercent: 70
|
|
7024
7079
|
}
|
|
7025
7080
|
),
|
|
7026
|
-
hasRightTools && /* @__PURE__ */
|
|
7081
|
+
hasRightTools && /* @__PURE__ */ React76.createElement(
|
|
7027
7082
|
ToolSidebar,
|
|
7028
7083
|
{
|
|
7029
7084
|
tools: rightToolDefs,
|
|
@@ -7038,9 +7093,9 @@ var ChatInterface = React74.forwardRef(
|
|
|
7038
7093
|
ChatInterface.displayName = "ChatInterface";
|
|
7039
7094
|
|
|
7040
7095
|
// src/components/chat/MessageActions.tsx
|
|
7041
|
-
import
|
|
7042
|
-
import { Check as
|
|
7043
|
-
var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */
|
|
7096
|
+
import React77, { useCallback as useCallback23, useState as useState23 } from "react";
|
|
7097
|
+
import { Check as Check4, Copy as Copy2, Pencil as Pencil3, RotateCcw as RotateCcw2, Send as Send3, X as X7 } from "lucide-react";
|
|
7098
|
+
var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ React77.createElement(
|
|
7044
7099
|
"button",
|
|
7045
7100
|
{
|
|
7046
7101
|
type: "button",
|
|
@@ -7056,7 +7111,7 @@ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @_
|
|
|
7056
7111
|
},
|
|
7057
7112
|
children
|
|
7058
7113
|
);
|
|
7059
|
-
var MessageActions =
|
|
7114
|
+
var MessageActions = React77.forwardRef(
|
|
7060
7115
|
({
|
|
7061
7116
|
variant,
|
|
7062
7117
|
content,
|
|
@@ -7068,12 +7123,12 @@ var MessageActions = React75.forwardRef(
|
|
|
7068
7123
|
className,
|
|
7069
7124
|
...rest
|
|
7070
7125
|
}, ref) => {
|
|
7071
|
-
const [localIsEditing, setLocalIsEditing] =
|
|
7072
|
-
const [localEditValue, setLocalEditValue] =
|
|
7073
|
-
const
|
|
7126
|
+
const [localIsEditing, setLocalIsEditing] = useState23(false);
|
|
7127
|
+
const [localEditValue, setLocalEditValue] = useState23(content);
|
|
7128
|
+
const { copied, copy } = useCopyToClipboard();
|
|
7074
7129
|
const isEditing = controlledIsEditing ?? localIsEditing;
|
|
7075
7130
|
const editValue = controlledEditValue ?? localEditValue;
|
|
7076
|
-
const setIsEditing =
|
|
7131
|
+
const setIsEditing = useCallback23(
|
|
7077
7132
|
(value) => {
|
|
7078
7133
|
if (onEditingChange) {
|
|
7079
7134
|
onEditingChange(value);
|
|
@@ -7083,41 +7138,28 @@ var MessageActions = React75.forwardRef(
|
|
|
7083
7138
|
},
|
|
7084
7139
|
[onEditingChange]
|
|
7085
7140
|
);
|
|
7086
|
-
const setEditValue =
|
|
7141
|
+
const setEditValue = useCallback23((value) => {
|
|
7087
7142
|
setLocalEditValue(value);
|
|
7088
7143
|
}, []);
|
|
7089
|
-
const handleCopy =
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
7094
|
-
} catch {
|
|
7095
|
-
const textArea = document.createElement("textarea");
|
|
7096
|
-
textArea.value = content;
|
|
7097
|
-
document.body.appendChild(textArea);
|
|
7098
|
-
textArea.select();
|
|
7099
|
-
document.execCommand("copy");
|
|
7100
|
-
document.body.removeChild(textArea);
|
|
7101
|
-
setCopied(true);
|
|
7102
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
7103
|
-
}
|
|
7104
|
-
}, [content]);
|
|
7105
|
-
const handleStartEdit = useCallback21(() => {
|
|
7144
|
+
const handleCopy = useCallback23(() => {
|
|
7145
|
+
void copy(content);
|
|
7146
|
+
}, [copy, content]);
|
|
7147
|
+
const handleStartEdit = useCallback23(() => {
|
|
7106
7148
|
setLocalEditValue(content);
|
|
7107
7149
|
setIsEditing(true);
|
|
7108
7150
|
}, [content, setIsEditing]);
|
|
7109
|
-
const handleCancelEdit =
|
|
7151
|
+
const handleCancelEdit = useCallback23(() => {
|
|
7110
7152
|
setIsEditing(false);
|
|
7111
7153
|
setLocalEditValue(content);
|
|
7112
7154
|
}, [content, setIsEditing]);
|
|
7113
|
-
const handleSubmitEdit =
|
|
7155
|
+
const handleSubmitEdit = useCallback23(() => {
|
|
7114
7156
|
const trimmed = editValue.trim();
|
|
7115
7157
|
if (trimmed && trimmed !== content) {
|
|
7116
7158
|
onEdit?.(trimmed);
|
|
7117
7159
|
}
|
|
7118
7160
|
setIsEditing(false);
|
|
7119
7161
|
}, [editValue, content, onEdit, setIsEditing]);
|
|
7120
|
-
const handleEditKeyDown =
|
|
7162
|
+
const handleEditKeyDown = useCallback23(
|
|
7121
7163
|
(e) => {
|
|
7122
7164
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
7123
7165
|
e.preventDefault();
|
|
@@ -7130,19 +7172,19 @@ var MessageActions = React75.forwardRef(
|
|
|
7130
7172
|
);
|
|
7131
7173
|
const isUser = variant === "user";
|
|
7132
7174
|
if (isUser && isEditing) {
|
|
7133
|
-
return /* @__PURE__ */
|
|
7175
|
+
return /* @__PURE__ */ React77.createElement(
|
|
7134
7176
|
"div",
|
|
7135
7177
|
{
|
|
7136
7178
|
ref,
|
|
7137
7179
|
className: cx("mt-2", className),
|
|
7138
7180
|
...rest
|
|
7139
7181
|
},
|
|
7140
|
-
/* @__PURE__ */
|
|
7182
|
+
/* @__PURE__ */ React77.createElement(
|
|
7141
7183
|
"div",
|
|
7142
7184
|
{
|
|
7143
7185
|
className: "relative bg-charcoal border border-ash/60 focus-within:border-gold/60 focus-within:ring-1 focus-within:ring-gold/20"
|
|
7144
7186
|
},
|
|
7145
|
-
/* @__PURE__ */
|
|
7187
|
+
/* @__PURE__ */ React77.createElement(
|
|
7146
7188
|
"textarea",
|
|
7147
7189
|
{
|
|
7148
7190
|
value: editValue,
|
|
@@ -7153,15 +7195,15 @@ var MessageActions = React75.forwardRef(
|
|
|
7153
7195
|
rows: 2
|
|
7154
7196
|
}
|
|
7155
7197
|
),
|
|
7156
|
-
/* @__PURE__ */
|
|
7198
|
+
/* @__PURE__ */ React77.createElement("div", { className: "absolute right-2 bottom-2 flex gap-1" }, /* @__PURE__ */ React77.createElement(
|
|
7157
7199
|
ActionButton2,
|
|
7158
7200
|
{
|
|
7159
7201
|
onClick: handleCancelEdit,
|
|
7160
7202
|
label: "Cancel edit",
|
|
7161
7203
|
className: "text-silver/60 hover:text-error"
|
|
7162
7204
|
},
|
|
7163
|
-
/* @__PURE__ */
|
|
7164
|
-
), /* @__PURE__ */
|
|
7205
|
+
/* @__PURE__ */ React77.createElement(X7, { className: "w-4 h-4" })
|
|
7206
|
+
), /* @__PURE__ */ React77.createElement(
|
|
7165
7207
|
ActionButton2,
|
|
7166
7208
|
{
|
|
7167
7209
|
onClick: handleSubmitEdit,
|
|
@@ -7169,13 +7211,13 @@ var MessageActions = React75.forwardRef(
|
|
|
7169
7211
|
className: "text-silver/60 hover:text-gold",
|
|
7170
7212
|
disabled: !editValue.trim() || editValue.trim() === content
|
|
7171
7213
|
},
|
|
7172
|
-
/* @__PURE__ */
|
|
7214
|
+
/* @__PURE__ */ React77.createElement(Send3, { className: "w-4 h-4" })
|
|
7173
7215
|
))
|
|
7174
7216
|
),
|
|
7175
|
-
/* @__PURE__ */
|
|
7217
|
+
/* @__PURE__ */ React77.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
|
|
7176
7218
|
);
|
|
7177
7219
|
}
|
|
7178
|
-
return /* @__PURE__ */
|
|
7220
|
+
return /* @__PURE__ */ React77.createElement(
|
|
7179
7221
|
"div",
|
|
7180
7222
|
{
|
|
7181
7223
|
ref,
|
|
@@ -7186,18 +7228,18 @@ var MessageActions = React75.forwardRef(
|
|
|
7186
7228
|
),
|
|
7187
7229
|
...rest
|
|
7188
7230
|
},
|
|
7189
|
-
/* @__PURE__ */
|
|
7190
|
-
isUser && onEdit && /* @__PURE__ */
|
|
7191
|
-
!isUser && onRetry && /* @__PURE__ */
|
|
7231
|
+
/* @__PURE__ */ React77.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ React77.createElement(Check4, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ React77.createElement(Copy2, { className: "w-3.5 h-3.5" })),
|
|
7232
|
+
isUser && onEdit && /* @__PURE__ */ React77.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React77.createElement(Pencil3, { className: "w-3.5 h-3.5" })),
|
|
7233
|
+
!isUser && onRetry && /* @__PURE__ */ React77.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ React77.createElement(RotateCcw2, { className: "w-3.5 h-3.5" }))
|
|
7192
7234
|
);
|
|
7193
7235
|
}
|
|
7194
7236
|
);
|
|
7195
7237
|
MessageActions.displayName = "MessageActions";
|
|
7196
7238
|
|
|
7197
7239
|
// src/components/chat/BranchNavigator.tsx
|
|
7198
|
-
import
|
|
7199
|
-
import { ChevronLeft as
|
|
7200
|
-
var BranchNavigator =
|
|
7240
|
+
import React78 from "react";
|
|
7241
|
+
import { ChevronLeft as ChevronLeft4, ChevronRight as ChevronRight5, GitBranch as GitBranch3 } from "lucide-react";
|
|
7242
|
+
var BranchNavigator = React78.forwardRef(
|
|
7201
7243
|
({
|
|
7202
7244
|
current,
|
|
7203
7245
|
total,
|
|
@@ -7216,7 +7258,7 @@ var BranchNavigator = React76.forwardRef(
|
|
|
7216
7258
|
const buttonSize = size === "sm" ? "p-0.5" : "p-1";
|
|
7217
7259
|
const iconSize = size === "sm" ? "w-3 h-3" : "w-4 h-4";
|
|
7218
7260
|
const textSize = size === "sm" ? "text-xs" : "text-sm";
|
|
7219
|
-
return /* @__PURE__ */
|
|
7261
|
+
return /* @__PURE__ */ React78.createElement(
|
|
7220
7262
|
"div",
|
|
7221
7263
|
{
|
|
7222
7264
|
ref,
|
|
@@ -7228,8 +7270,8 @@ var BranchNavigator = React76.forwardRef(
|
|
|
7228
7270
|
"aria-label": "Branch navigation",
|
|
7229
7271
|
...rest
|
|
7230
7272
|
},
|
|
7231
|
-
showIcon && /* @__PURE__ */
|
|
7232
|
-
/* @__PURE__ */
|
|
7273
|
+
showIcon && /* @__PURE__ */ React78.createElement(GitBranch3, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
|
|
7274
|
+
/* @__PURE__ */ React78.createElement(
|
|
7233
7275
|
"button",
|
|
7234
7276
|
{
|
|
7235
7277
|
type: "button",
|
|
@@ -7242,10 +7284,10 @@ var BranchNavigator = React76.forwardRef(
|
|
|
7242
7284
|
),
|
|
7243
7285
|
"aria-label": "Previous branch"
|
|
7244
7286
|
},
|
|
7245
|
-
/* @__PURE__ */
|
|
7287
|
+
/* @__PURE__ */ React78.createElement(ChevronLeft4, { className: iconSize })
|
|
7246
7288
|
),
|
|
7247
|
-
/* @__PURE__ */
|
|
7248
|
-
/* @__PURE__ */
|
|
7289
|
+
/* @__PURE__ */ React78.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
|
|
7290
|
+
/* @__PURE__ */ React78.createElement(
|
|
7249
7291
|
"button",
|
|
7250
7292
|
{
|
|
7251
7293
|
type: "button",
|
|
@@ -7258,7 +7300,7 @@ var BranchNavigator = React76.forwardRef(
|
|
|
7258
7300
|
),
|
|
7259
7301
|
"aria-label": "Next branch"
|
|
7260
7302
|
},
|
|
7261
|
-
/* @__PURE__ */
|
|
7303
|
+
/* @__PURE__ */ React78.createElement(ChevronRight5, { className: iconSize })
|
|
7262
7304
|
)
|
|
7263
7305
|
);
|
|
7264
7306
|
}
|
|
@@ -7266,16 +7308,16 @@ var BranchNavigator = React76.forwardRef(
|
|
|
7266
7308
|
BranchNavigator.displayName = "BranchNavigator";
|
|
7267
7309
|
|
|
7268
7310
|
// src/components/BrandIcon.tsx
|
|
7269
|
-
import
|
|
7311
|
+
import React79 from "react";
|
|
7270
7312
|
var sizeMap2 = {
|
|
7271
7313
|
sm: "h-8 w-8 text-sm",
|
|
7272
7314
|
md: "h-12 w-12 text-base",
|
|
7273
7315
|
lg: "h-16 w-16 text-lg"
|
|
7274
7316
|
};
|
|
7275
|
-
var BrandIcon =
|
|
7317
|
+
var BrandIcon = React79.forwardRef(
|
|
7276
7318
|
({ size = "md", variant = "solid", children, className, ...rest }, ref) => {
|
|
7277
7319
|
const variantClasses = variant === "solid" ? "bg-gold text-obsidian border-2 border-gold" : "bg-transparent text-gold border-2 border-gold";
|
|
7278
|
-
return /* @__PURE__ */
|
|
7320
|
+
return /* @__PURE__ */ React79.createElement(
|
|
7279
7321
|
"div",
|
|
7280
7322
|
{
|
|
7281
7323
|
ref,
|
|
@@ -7294,17 +7336,17 @@ var BrandIcon = React77.forwardRef(
|
|
|
7294
7336
|
BrandIcon.displayName = "BrandIcon";
|
|
7295
7337
|
|
|
7296
7338
|
// src/components/ColorSwatch.tsx
|
|
7297
|
-
import
|
|
7298
|
-
var ColorSwatch =
|
|
7339
|
+
import React80 from "react";
|
|
7340
|
+
var ColorSwatch = React80.forwardRef(
|
|
7299
7341
|
({ color, label, className, ...rest }, ref) => {
|
|
7300
|
-
return /* @__PURE__ */
|
|
7342
|
+
return /* @__PURE__ */ React80.createElement(
|
|
7301
7343
|
"div",
|
|
7302
7344
|
{
|
|
7303
7345
|
ref,
|
|
7304
7346
|
className: cx("flex flex-col items-center gap-2", className),
|
|
7305
7347
|
...rest
|
|
7306
7348
|
},
|
|
7307
|
-
/* @__PURE__ */
|
|
7349
|
+
/* @__PURE__ */ React80.createElement(
|
|
7308
7350
|
"div",
|
|
7309
7351
|
{
|
|
7310
7352
|
className: "h-16 w-16 border-2 border-ash rounded-none shadow-sm",
|
|
@@ -7312,22 +7354,22 @@ var ColorSwatch = React78.forwardRef(
|
|
|
7312
7354
|
"aria-label": label || color
|
|
7313
7355
|
}
|
|
7314
7356
|
),
|
|
7315
|
-
label && /* @__PURE__ */
|
|
7357
|
+
label && /* @__PURE__ */ React80.createElement("span", { className: "text-xs text-silver font-medium" }, label)
|
|
7316
7358
|
);
|
|
7317
7359
|
}
|
|
7318
7360
|
);
|
|
7319
7361
|
ColorSwatch.displayName = "ColorSwatch";
|
|
7320
7362
|
|
|
7321
7363
|
// src/components/SectionHeading.tsx
|
|
7322
|
-
import
|
|
7364
|
+
import React81 from "react";
|
|
7323
7365
|
var levelStyles = {
|
|
7324
7366
|
h2: "text-2xl mb-4",
|
|
7325
7367
|
h3: "text-xl mb-3"
|
|
7326
7368
|
};
|
|
7327
|
-
var SectionHeading =
|
|
7369
|
+
var SectionHeading = React81.forwardRef(
|
|
7328
7370
|
({ level = "h2", children, className, ...rest }, ref) => {
|
|
7329
7371
|
const Component = level;
|
|
7330
|
-
return /* @__PURE__ */
|
|
7372
|
+
return /* @__PURE__ */ React81.createElement(
|
|
7331
7373
|
Component,
|
|
7332
7374
|
{
|
|
7333
7375
|
ref,
|
|
@@ -7383,6 +7425,7 @@ export {
|
|
|
7383
7425
|
ChatView,
|
|
7384
7426
|
CheckSquareIcon,
|
|
7385
7427
|
Checkbox,
|
|
7428
|
+
Checkpoint,
|
|
7386
7429
|
ChevronLeftIcon,
|
|
7387
7430
|
ChevronRightIcon,
|
|
7388
7431
|
CloseIcon,
|
|
@@ -7396,6 +7439,7 @@ export {
|
|
|
7396
7439
|
EmptySquareIcon,
|
|
7397
7440
|
ExpandIcon,
|
|
7398
7441
|
FileChip,
|
|
7442
|
+
GreyedDivider,
|
|
7399
7443
|
HelperText,
|
|
7400
7444
|
HistoryIcon,
|
|
7401
7445
|
HistoryPanel,
|
|
@@ -7473,19 +7517,22 @@ export {
|
|
|
7473
7517
|
ToolSidebar,
|
|
7474
7518
|
Tooltip,
|
|
7475
7519
|
VideoCard,
|
|
7476
|
-
|
|
7520
|
+
addNodeToTree,
|
|
7477
7521
|
areAllTasksSettled,
|
|
7478
7522
|
createEmptyTree,
|
|
7479
7523
|
createPreviewUrl,
|
|
7524
|
+
findAncestor,
|
|
7480
7525
|
generateId,
|
|
7481
|
-
|
|
7526
|
+
getActivePath,
|
|
7527
|
+
getGreyedFuture,
|
|
7482
7528
|
getSiblingInfo,
|
|
7483
7529
|
isBranchPoint,
|
|
7484
7530
|
isImageFile,
|
|
7485
7531
|
messagesToTree,
|
|
7486
7532
|
revokePreviewUrl,
|
|
7533
|
+
setActiveLeaf,
|
|
7487
7534
|
switchBranch,
|
|
7488
|
-
|
|
7535
|
+
updateMessageContent,
|
|
7489
7536
|
useArtifactTreeNavigation,
|
|
7490
7537
|
useResizable,
|
|
7491
7538
|
useScrollAnchor,
|