@lukeashford/aurelius 4.1.0 → 4.3.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 +124 -25
- package/dist/index.d.ts +124 -25
- package/dist/index.js +359 -224
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +269 -133
- package/dist/index.mjs.map +1 -1
- package/llms.md +23 -11
- package/package.json +10 -6
package/dist/index.mjs
CHANGED
|
@@ -1320,42 +1320,84 @@ function getFileIcon(type) {
|
|
|
1320
1320
|
}
|
|
1321
1321
|
return File;
|
|
1322
1322
|
}
|
|
1323
|
-
var
|
|
1323
|
+
var statusBorderClass = {
|
|
1324
1324
|
pending: "border-silver/30",
|
|
1325
1325
|
uploading: "border-gold/50",
|
|
1326
|
-
|
|
1327
|
-
|
|
1326
|
+
uploaded: "border-info/50",
|
|
1327
|
+
analyzing: "border-info/50",
|
|
1328
|
+
analyzed: "border-success/50",
|
|
1329
|
+
upload_failed: "border-error/50",
|
|
1330
|
+
analysis_failed: "border-error/50"
|
|
1328
1331
|
};
|
|
1332
|
+
var statusHoverLabel = {
|
|
1333
|
+
pending: null,
|
|
1334
|
+
uploading: "Uploading...",
|
|
1335
|
+
uploaded: "Upload complete. Analyzing...",
|
|
1336
|
+
analyzing: "Upload complete. Analyzing...",
|
|
1337
|
+
analyzed: null,
|
|
1338
|
+
upload_failed: "Upload failed. Remove and try again.",
|
|
1339
|
+
analysis_failed: "Analysis failed. Provide a description in your next message."
|
|
1340
|
+
};
|
|
1341
|
+
function isErrorStatus(status) {
|
|
1342
|
+
return status === "upload_failed" || status === "analysis_failed";
|
|
1343
|
+
}
|
|
1329
1344
|
var FileChip = React15.forwardRef(
|
|
1330
1345
|
({
|
|
1331
1346
|
name,
|
|
1332
1347
|
size,
|
|
1333
1348
|
type,
|
|
1334
|
-
status = "
|
|
1349
|
+
status = "analyzed",
|
|
1335
1350
|
previewUrl,
|
|
1336
1351
|
onRemove,
|
|
1337
1352
|
removable = true,
|
|
1338
1353
|
error,
|
|
1354
|
+
artifactId,
|
|
1355
|
+
onOpen,
|
|
1339
1356
|
className,
|
|
1357
|
+
title,
|
|
1340
1358
|
...rest
|
|
1341
1359
|
}, ref) => {
|
|
1342
1360
|
const Icon = getFileIcon(type);
|
|
1343
1361
|
const isImage = type?.startsWith("image/");
|
|
1344
1362
|
const showPreview = isImage && previewUrl;
|
|
1363
|
+
const clickable = !!(artifactId && onOpen);
|
|
1364
|
+
const hoverLabel = statusHoverLabel[status];
|
|
1365
|
+
const tooltip = title ?? hoverLabel ?? name;
|
|
1366
|
+
const showError = isErrorStatus(status);
|
|
1367
|
+
const handleClick = () => {
|
|
1368
|
+
if (clickable) {
|
|
1369
|
+
onOpen(artifactId);
|
|
1370
|
+
}
|
|
1371
|
+
};
|
|
1372
|
+
const handleKeyDown = (e) => {
|
|
1373
|
+
if (!clickable) {
|
|
1374
|
+
return;
|
|
1375
|
+
}
|
|
1376
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1377
|
+
e.preventDefault();
|
|
1378
|
+
onOpen(artifactId);
|
|
1379
|
+
}
|
|
1380
|
+
};
|
|
1345
1381
|
return /* @__PURE__ */ React15.createElement(
|
|
1346
1382
|
"div",
|
|
1347
1383
|
{
|
|
1384
|
+
...rest,
|
|
1348
1385
|
ref,
|
|
1349
1386
|
className: cx(
|
|
1350
1387
|
"group relative inline-flex items-center gap-2 px-2 py-1.5",
|
|
1351
1388
|
"bg-charcoal border text-sm text-white",
|
|
1352
1389
|
"transition-colors duration-150",
|
|
1353
|
-
|
|
1354
|
-
|
|
1390
|
+
statusBorderClass[status],
|
|
1391
|
+
showError && "bg-error/10",
|
|
1392
|
+
clickable && "cursor-pointer hover:bg-graphite",
|
|
1355
1393
|
className
|
|
1356
1394
|
),
|
|
1357
|
-
role: "listitem",
|
|
1358
|
-
|
|
1395
|
+
role: clickable ? "button" : "listitem",
|
|
1396
|
+
tabIndex: clickable ? 0 : void 0,
|
|
1397
|
+
onClick: clickable ? handleClick : void 0,
|
|
1398
|
+
onKeyDown: clickable ? handleKeyDown : void 0,
|
|
1399
|
+
title: tooltip,
|
|
1400
|
+
"aria-label": hoverLabel ? `${name}: ${hoverLabel}` : name
|
|
1359
1401
|
},
|
|
1360
1402
|
showPreview ? /* @__PURE__ */ React15.createElement("div", { className: "w-8 h-8 flex-shrink-0 overflow-hidden bg-slate" }, /* @__PURE__ */ React15.createElement(
|
|
1361
1403
|
"img",
|
|
@@ -1366,10 +1408,11 @@ var FileChip = React15.forwardRef(
|
|
|
1366
1408
|
}
|
|
1367
1409
|
)) : /* @__PURE__ */ React15.createElement(Icon, { className: cx(
|
|
1368
1410
|
"w-4 h-4 flex-shrink-0",
|
|
1369
|
-
|
|
1411
|
+
showError ? "text-error" : "text-silver"
|
|
1370
1412
|
) }),
|
|
1371
|
-
/* @__PURE__ */ React15.createElement("div", { className: "flex flex-col min-w-0 flex-1" }, /* @__PURE__ */ React15.createElement("span", { className: "truncate max-w-40", title: name }, name), size !== void 0 &&
|
|
1413
|
+
/* @__PURE__ */ React15.createElement("div", { className: "flex flex-col min-w-0 flex-1" }, /* @__PURE__ */ React15.createElement("span", { className: "truncate max-w-40", title: name }, name), size !== void 0 && !showError && /* @__PURE__ */ React15.createElement("span", { className: "text-xs text-silver/60" }, formatBytes(size)), showError && error && /* @__PURE__ */ React15.createElement("span", { className: "text-xs text-error truncate", title: error }, error)),
|
|
1372
1414
|
status === "uploading" && /* @__PURE__ */ React15.createElement(Loader2, { className: "w-3.5 h-3.5 text-gold animate-spin flex-shrink-0" }),
|
|
1415
|
+
(status === "uploaded" || status === "analyzing") && /* @__PURE__ */ React15.createElement(Loader2, { className: "w-3.5 h-3.5 text-info animate-spin flex-shrink-0" }),
|
|
1373
1416
|
status === "pending" && /* @__PURE__ */ React15.createElement("div", { className: "w-2 h-2 rounded-full bg-silver/50 flex-shrink-0" }),
|
|
1374
1417
|
removable && onRemove && /* @__PURE__ */ React15.createElement(
|
|
1375
1418
|
"button",
|
|
@@ -1402,6 +1445,7 @@ var AttachmentPreview = React16.forwardRef(
|
|
|
1402
1445
|
onRemove,
|
|
1403
1446
|
removable = true,
|
|
1404
1447
|
maxVisible,
|
|
1448
|
+
onOpen,
|
|
1405
1449
|
className,
|
|
1406
1450
|
...rest
|
|
1407
1451
|
}, ref) => {
|
|
@@ -1430,7 +1474,9 @@ var AttachmentPreview = React16.forwardRef(
|
|
|
1430
1474
|
previewUrl: attachment.previewUrl,
|
|
1431
1475
|
error: attachment.error,
|
|
1432
1476
|
removable,
|
|
1433
|
-
onRemove: onRemove ? () => onRemove(attachment.id) : void 0
|
|
1477
|
+
onRemove: onRemove ? () => onRemove(attachment.id) : void 0,
|
|
1478
|
+
artifactId: attachment.artifactId,
|
|
1479
|
+
onOpen
|
|
1434
1480
|
}
|
|
1435
1481
|
)),
|
|
1436
1482
|
hiddenCount > 0 && /* @__PURE__ */ React16.createElement(
|
|
@@ -3712,12 +3758,14 @@ import { Check as Check3, ChevronLeft as ChevronLeft2, ChevronRight as ChevronRi
|
|
|
3712
3758
|
import React54, { useMemo } from "react";
|
|
3713
3759
|
import DOMPurify from "dompurify";
|
|
3714
3760
|
import { marked } from "marked";
|
|
3715
|
-
DOMPurify.addHook
|
|
3716
|
-
|
|
3717
|
-
node.
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
}
|
|
3761
|
+
if (typeof window !== "undefined" && typeof DOMPurify.addHook === "function") {
|
|
3762
|
+
DOMPurify.addHook("afterSanitizeAttributes", (node) => {
|
|
3763
|
+
if (node.tagName === "A") {
|
|
3764
|
+
node.setAttribute("target", "_blank");
|
|
3765
|
+
node.setAttribute("rel", "noopener noreferrer");
|
|
3766
|
+
}
|
|
3767
|
+
});
|
|
3768
|
+
}
|
|
3721
3769
|
var DEFAULT_SANITIZE_CONFIG = {
|
|
3722
3770
|
ALLOWED_TAGS: [
|
|
3723
3771
|
"h1",
|
|
@@ -3794,6 +3842,9 @@ function injectStreamingCursor(html, cursorClassName) {
|
|
|
3794
3842
|
CURSOR_BASE_CLASSES,
|
|
3795
3843
|
cursorClassName
|
|
3796
3844
|
)}" aria-hidden="true"></span>`;
|
|
3845
|
+
if (typeof DOMParser === "undefined") {
|
|
3846
|
+
return html + cursorHtml;
|
|
3847
|
+
}
|
|
3797
3848
|
const parser = new DOMParser();
|
|
3798
3849
|
const doc = parser.parseFromString(`<div>${html}</div>`, "text/html");
|
|
3799
3850
|
const container = doc.body.firstChild;
|
|
@@ -3830,7 +3881,7 @@ var MarkdownContent = React54.forwardRef(
|
|
|
3830
3881
|
} else {
|
|
3831
3882
|
htmlContent = content;
|
|
3832
3883
|
}
|
|
3833
|
-
const sanitized = htmlContent ? DOMPurify.sanitize(htmlContent, config) : "";
|
|
3884
|
+
const sanitized = htmlContent && typeof DOMPurify.sanitize === "function" ? DOMPurify.sanitize(htmlContent, config) : htmlContent || "";
|
|
3834
3885
|
if (isStreaming) {
|
|
3835
3886
|
return injectStreamingCursor(sanitized, cursorClassName);
|
|
3836
3887
|
}
|
|
@@ -3885,6 +3936,8 @@ var Message = React55.forwardRef(
|
|
|
3885
3936
|
branchInfo,
|
|
3886
3937
|
actions,
|
|
3887
3938
|
hideActions,
|
|
3939
|
+
attachments,
|
|
3940
|
+
onAttachmentOpen,
|
|
3888
3941
|
...rest
|
|
3889
3942
|
}, ref) => {
|
|
3890
3943
|
const isUser = variant === "user";
|
|
@@ -3952,6 +4005,14 @@ var Message = React55.forwardRef(
|
|
|
3952
4005
|
),
|
|
3953
4006
|
...rest
|
|
3954
4007
|
},
|
|
4008
|
+
attachments && attachments.length > 0 && /* @__PURE__ */ React55.createElement("div", { className: cx("mb-1.5", isUser ? "self-end" : "self-start") }, /* @__PURE__ */ React55.createElement(
|
|
4009
|
+
AttachmentPreview,
|
|
4010
|
+
{
|
|
4011
|
+
attachments,
|
|
4012
|
+
removable: false,
|
|
4013
|
+
onOpen: onAttachmentOpen
|
|
4014
|
+
}
|
|
4015
|
+
)),
|
|
3955
4016
|
isUser && isEditing ? /* @__PURE__ */ React55.createElement("div", { className: "w-full max-w-11/12" }, /* @__PURE__ */ React55.createElement("div", { className: "relative bg-gold" }, /* @__PURE__ */ React55.createElement(
|
|
3956
4017
|
"textarea",
|
|
3957
4018
|
{
|
|
@@ -4202,6 +4263,7 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4202
4263
|
isVisible = true,
|
|
4203
4264
|
phraseInterval = 2500,
|
|
4204
4265
|
phrases = THINKING_PHRASES,
|
|
4266
|
+
manualLabel,
|
|
4205
4267
|
className,
|
|
4206
4268
|
...rest
|
|
4207
4269
|
}, ref) => {
|
|
@@ -4209,8 +4271,9 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4209
4271
|
() => Math.floor(Math.random() * phrases.length)
|
|
4210
4272
|
);
|
|
4211
4273
|
const [isTransitioning, setIsTransitioning] = useState13(false);
|
|
4274
|
+
const isManual = manualLabel !== void 0;
|
|
4212
4275
|
useEffect8(() => {
|
|
4213
|
-
if (!isVisible || phrases.length <= 1) {
|
|
4276
|
+
if (!isVisible || isManual || phrases.length <= 1) {
|
|
4214
4277
|
return;
|
|
4215
4278
|
}
|
|
4216
4279
|
let fadeTimeout = null;
|
|
@@ -4228,7 +4291,7 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4228
4291
|
clearTimeout(fadeTimeout);
|
|
4229
4292
|
}
|
|
4230
4293
|
};
|
|
4231
|
-
}, [isVisible, phrases.length, phraseInterval]);
|
|
4294
|
+
}, [isVisible, isManual, phrases.length, phraseInterval]);
|
|
4232
4295
|
if (!isVisible) {
|
|
4233
4296
|
return null;
|
|
4234
4297
|
}
|
|
@@ -4265,7 +4328,7 @@ var ThinkingIndicator = React57.forwardRef(
|
|
|
4265
4328
|
style: { animationDelay: "300ms" }
|
|
4266
4329
|
}
|
|
4267
4330
|
)),
|
|
4268
|
-
/* @__PURE__ */ React57.createElement(
|
|
4331
|
+
isManual ? /* @__PURE__ */ React57.createElement("span", { className: "text-sm italic" }, manualLabel) : /* @__PURE__ */ React57.createElement(
|
|
4269
4332
|
"span",
|
|
4270
4333
|
{
|
|
4271
4334
|
className: cx(
|
|
@@ -4289,19 +4352,22 @@ import {
|
|
|
4289
4352
|
GitBranch as GitBranch2,
|
|
4290
4353
|
GitCommitVertical,
|
|
4291
4354
|
GitMerge,
|
|
4292
|
-
PencilLine
|
|
4355
|
+
PencilLine,
|
|
4356
|
+
Upload
|
|
4293
4357
|
} from "lucide-react";
|
|
4294
4358
|
var KIND_ICONS = {
|
|
4295
4359
|
task: GitBranch2,
|
|
4296
4360
|
submit: GitMerge,
|
|
4297
4361
|
rename: PencilLine,
|
|
4298
|
-
init: GitCommitVertical
|
|
4362
|
+
init: GitCommitVertical,
|
|
4363
|
+
ingest: Upload
|
|
4299
4364
|
};
|
|
4300
4365
|
var KIND_ARIA_LABELS = {
|
|
4301
4366
|
task: "Task checkpoint",
|
|
4302
4367
|
submit: "Submit checkpoint",
|
|
4303
4368
|
rename: "Rename checkpoint",
|
|
4304
|
-
init: "Project head checkpoint"
|
|
4369
|
+
init: "Project head checkpoint",
|
|
4370
|
+
ingest: "Upload batch checkpoint"
|
|
4305
4371
|
};
|
|
4306
4372
|
var Checkpoint = React58.forwardRef(
|
|
4307
4373
|
function Checkpoint2({ name, executionKind, status = "completed", isActive, muted, branchInfo, onJumpHere }, ref) {
|
|
@@ -4450,7 +4516,16 @@ GreyedDivider.displayName = "GreyedDivider";
|
|
|
4450
4516
|
|
|
4451
4517
|
// src/components/chat/ChatView.tsx
|
|
4452
4518
|
var ChatView = React60.forwardRef(
|
|
4453
|
-
function ChatView2({
|
|
4519
|
+
function ChatView2({
|
|
4520
|
+
items,
|
|
4521
|
+
latestUserMessageIndex,
|
|
4522
|
+
isStreaming,
|
|
4523
|
+
isThinking,
|
|
4524
|
+
thinkingLabel,
|
|
4525
|
+
onScroll,
|
|
4526
|
+
className,
|
|
4527
|
+
...rest
|
|
4528
|
+
}, ref) {
|
|
4454
4529
|
const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
|
|
4455
4530
|
behavior: "smooth",
|
|
4456
4531
|
block: "start"
|
|
@@ -4533,7 +4608,7 @@ var ChatView = React60.forwardRef(
|
|
|
4533
4608
|
}
|
|
4534
4609
|
)
|
|
4535
4610
|
);
|
|
4536
|
-
}), showThinking && /* @__PURE__ */ React60.createElement(ThinkingIndicator, { isVisible: true })),
|
|
4611
|
+
}), showThinking && /* @__PURE__ */ React60.createElement(ThinkingIndicator, { isVisible: true, manualLabel: thinkingLabel })),
|
|
4537
4612
|
/* @__PURE__ */ React60.createElement(
|
|
4538
4613
|
"div",
|
|
4539
4614
|
{
|
|
@@ -4718,8 +4793,8 @@ var ChatInput = React61.forwardRef(
|
|
|
4718
4793
|
);
|
|
4719
4794
|
const isCentered = position === "centered";
|
|
4720
4795
|
const hasAttachments = attachments.length > 0;
|
|
4721
|
-
const
|
|
4722
|
-
const canSubmit = value.trim() && !disabled && !isStreaming && !
|
|
4796
|
+
const isUploadIncomplete = attachments.some((a) => a.status === "pending" || a.status === "uploading" || a.status === "upload_failed");
|
|
4797
|
+
const canSubmit = value.trim() && !disabled && !isStreaming && !isUploadIncomplete;
|
|
4723
4798
|
return /* @__PURE__ */ React61.createElement(
|
|
4724
4799
|
"div",
|
|
4725
4800
|
{
|
|
@@ -4856,7 +4931,7 @@ var ChatInput = React61.forwardRef(
|
|
|
4856
4931
|
ChatInput.displayName = "ChatInput";
|
|
4857
4932
|
|
|
4858
4933
|
// src/components/chat/ArtifactsPanel.tsx
|
|
4859
|
-
import React71, { useCallback as
|
|
4934
|
+
import React71, { useCallback as useCallback18, useEffect as useEffect13, useRef as useRef12, useState as useState18 } from "react";
|
|
4860
4935
|
import { Image } from "lucide-react";
|
|
4861
4936
|
|
|
4862
4937
|
// src/components/ArtifactCard.tsx
|
|
@@ -5514,10 +5589,69 @@ var ArtifactVariantStack = React70.forwardRef(
|
|
|
5514
5589
|
);
|
|
5515
5590
|
ArtifactVariantStack.displayName = "ArtifactVariantStack";
|
|
5516
5591
|
|
|
5592
|
+
// src/components/chat/hooks/useResizable.ts
|
|
5593
|
+
import { useCallback as useCallback16, useEffect as useEffect12, useRef as useRef11, useState as useState16 } from "react";
|
|
5594
|
+
function useResizable({
|
|
5595
|
+
initialWidthPercent,
|
|
5596
|
+
minWidthPercent,
|
|
5597
|
+
maxWidthPercent,
|
|
5598
|
+
direction
|
|
5599
|
+
}) {
|
|
5600
|
+
const [widthPercent, setWidthPercent] = useState16(initialWidthPercent);
|
|
5601
|
+
const [isResizing, setIsResizing] = useState16(false);
|
|
5602
|
+
const lastX = useRef11(null);
|
|
5603
|
+
const startResizing = useCallback16((e) => {
|
|
5604
|
+
e.preventDefault();
|
|
5605
|
+
setIsResizing(true);
|
|
5606
|
+
lastX.current = e.clientX;
|
|
5607
|
+
}, []);
|
|
5608
|
+
const stopResizing = useCallback16(() => {
|
|
5609
|
+
setIsResizing(false);
|
|
5610
|
+
lastX.current = null;
|
|
5611
|
+
}, []);
|
|
5612
|
+
const resize = useCallback16(
|
|
5613
|
+
(e) => {
|
|
5614
|
+
if (!isResizing || lastX.current === null) {
|
|
5615
|
+
return;
|
|
5616
|
+
}
|
|
5617
|
+
const deltaX = e.clientX - lastX.current;
|
|
5618
|
+
const factor = direction === "right" ? 1 : -1;
|
|
5619
|
+
const deltaPercent = deltaX / window.innerWidth * 100;
|
|
5620
|
+
setWidthPercent((prevPercent) => {
|
|
5621
|
+
const newPercent = prevPercent + deltaPercent * factor;
|
|
5622
|
+
return Math.min(Math.max(newPercent, minWidthPercent), maxWidthPercent);
|
|
5623
|
+
});
|
|
5624
|
+
lastX.current = e.clientX;
|
|
5625
|
+
},
|
|
5626
|
+
[isResizing, direction, minWidthPercent, maxWidthPercent]
|
|
5627
|
+
);
|
|
5628
|
+
useEffect12(() => {
|
|
5629
|
+
if (isResizing) {
|
|
5630
|
+
window.addEventListener("mousemove", resize);
|
|
5631
|
+
window.addEventListener("mouseup", stopResizing);
|
|
5632
|
+
document.body.style.cursor = "col-resize";
|
|
5633
|
+
document.body.style.userSelect = "none";
|
|
5634
|
+
} else {
|
|
5635
|
+
window.removeEventListener("mousemove", resize);
|
|
5636
|
+
window.removeEventListener("mouseup", stopResizing);
|
|
5637
|
+
document.body.style.cursor = "";
|
|
5638
|
+
document.body.style.userSelect = "";
|
|
5639
|
+
}
|
|
5640
|
+
return () => {
|
|
5641
|
+
window.removeEventListener("mousemove", resize);
|
|
5642
|
+
window.removeEventListener("mouseup", stopResizing);
|
|
5643
|
+
document.body.style.cursor = "";
|
|
5644
|
+
document.body.style.userSelect = "";
|
|
5645
|
+
};
|
|
5646
|
+
}, [isResizing, resize, stopResizing]);
|
|
5647
|
+
const width = `${widthPercent}vw`;
|
|
5648
|
+
return { width, widthPercent, isResizing, startResizing };
|
|
5649
|
+
}
|
|
5650
|
+
|
|
5517
5651
|
// src/components/chat/hooks/useArtifactTreeNavigation.ts
|
|
5518
|
-
import { useCallback as
|
|
5652
|
+
import { useCallback as useCallback17, useMemo as useMemo2, useState as useState17 } from "react";
|
|
5519
5653
|
function useArtifactTreeNavigation(rootNodes) {
|
|
5520
|
-
const [stack, setStack] =
|
|
5654
|
+
const [stack, setStack] = useState17([]);
|
|
5521
5655
|
const currentNodes = useMemo2(() => {
|
|
5522
5656
|
if (stack.length === 0) return rootNodes;
|
|
5523
5657
|
return stack[stack.length - 1].children;
|
|
@@ -5530,13 +5664,13 @@ function useArtifactTreeNavigation(rootNodes) {
|
|
|
5530
5664
|
return entries;
|
|
5531
5665
|
}, [stack]);
|
|
5532
5666
|
const isAtRoot = stack.length === 0;
|
|
5533
|
-
const navigateInto =
|
|
5667
|
+
const navigateInto = useCallback17((node) => {
|
|
5534
5668
|
setStack((prev) => [...prev, node]);
|
|
5535
5669
|
}, []);
|
|
5536
|
-
const navigateTo =
|
|
5670
|
+
const navigateTo = useCallback17((index) => {
|
|
5537
5671
|
setStack((prev) => prev.slice(0, index));
|
|
5538
5672
|
}, []);
|
|
5539
|
-
const navigateBack =
|
|
5673
|
+
const navigateBack = useCallback17(() => {
|
|
5540
5674
|
setStack((prev) => prev.slice(0, -1));
|
|
5541
5675
|
}, []);
|
|
5542
5676
|
return {
|
|
@@ -5556,7 +5690,7 @@ function ArtifactModal({
|
|
|
5556
5690
|
onClose
|
|
5557
5691
|
}) {
|
|
5558
5692
|
useEscapeKey(onClose);
|
|
5559
|
-
const handleBackdropClick =
|
|
5693
|
+
const handleBackdropClick = useCallback18((e) => {
|
|
5560
5694
|
if (e.target === e.currentTarget) {
|
|
5561
5695
|
onClose();
|
|
5562
5696
|
}
|
|
@@ -5637,6 +5771,20 @@ function ArtifactModal({
|
|
|
5637
5771
|
)
|
|
5638
5772
|
);
|
|
5639
5773
|
}
|
|
5774
|
+
function findArtifactInNodes(nodes, artifactId) {
|
|
5775
|
+
for (const node of nodes) {
|
|
5776
|
+
if (node.type === "ARTIFACT" && node.artifact?.id === artifactId) {
|
|
5777
|
+
return node.artifact;
|
|
5778
|
+
}
|
|
5779
|
+
if (node.children && node.children.length > 0) {
|
|
5780
|
+
const found = findArtifactInNodes(node.children, artifactId);
|
|
5781
|
+
if (found) {
|
|
5782
|
+
return found;
|
|
5783
|
+
}
|
|
5784
|
+
}
|
|
5785
|
+
}
|
|
5786
|
+
return null;
|
|
5787
|
+
}
|
|
5640
5788
|
function NodeRenderer({
|
|
5641
5789
|
node,
|
|
5642
5790
|
loading,
|
|
@@ -5672,31 +5820,48 @@ var ArtifactsPanel = React71.forwardRef(
|
|
|
5672
5820
|
({
|
|
5673
5821
|
nodes,
|
|
5674
5822
|
loading,
|
|
5823
|
+
openArtifactId,
|
|
5824
|
+
onArtifactClosed,
|
|
5675
5825
|
className,
|
|
5676
5826
|
...rest
|
|
5677
5827
|
}, ref) => {
|
|
5678
|
-
const [expandedArtifact, setExpandedArtifact] =
|
|
5679
|
-
const [zoomIndex, setZoomIndex] =
|
|
5828
|
+
const [expandedArtifact, setExpandedArtifact] = useState18(null);
|
|
5829
|
+
const [zoomIndex, setZoomIndex] = useState18(ZOOM_LEVELS.length - 1);
|
|
5680
5830
|
const treeNav = useArtifactTreeNavigation(nodes || []);
|
|
5681
5831
|
const hasNodes = !!nodes && nodes.length > 0;
|
|
5682
|
-
const handleExpandArtifact =
|
|
5832
|
+
const handleExpandArtifact = useCallback18((artifact) => {
|
|
5683
5833
|
setExpandedArtifact(artifact);
|
|
5684
5834
|
}, []);
|
|
5685
|
-
const handleGroupClick =
|
|
5835
|
+
const handleGroupClick = useCallback18((node) => {
|
|
5686
5836
|
treeNav.navigateInto(node);
|
|
5687
5837
|
}, [treeNav]);
|
|
5688
|
-
|
|
5838
|
+
useEffect13(() => {
|
|
5839
|
+
if (!openArtifactId || !nodes) {
|
|
5840
|
+
return;
|
|
5841
|
+
}
|
|
5842
|
+
const found = findArtifactInNodes(nodes, openArtifactId);
|
|
5843
|
+
if (found) {
|
|
5844
|
+
setExpandedArtifact(found);
|
|
5845
|
+
}
|
|
5846
|
+
}, [openArtifactId, nodes]);
|
|
5847
|
+
const handleModalClose = useCallback18(() => {
|
|
5848
|
+
setExpandedArtifact(null);
|
|
5849
|
+
onArtifactClosed?.();
|
|
5850
|
+
}, [onArtifactClosed]);
|
|
5851
|
+
const zoomIn = useCallback18(() => {
|
|
5689
5852
|
setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
|
|
5690
5853
|
}, []);
|
|
5691
|
-
const zoomOut =
|
|
5854
|
+
const zoomOut = useCallback18(() => {
|
|
5692
5855
|
setZoomIndex((prev) => Math.max(prev - 1, 0));
|
|
5693
5856
|
}, []);
|
|
5694
5857
|
const currentZoom = ZOOM_LEVELS[zoomIndex];
|
|
5695
|
-
const contentRef =
|
|
5696
|
-
const [contentHeight, setContentHeight] =
|
|
5697
|
-
|
|
5858
|
+
const contentRef = useRef12(null);
|
|
5859
|
+
const [contentHeight, setContentHeight] = useState18(void 0);
|
|
5860
|
+
useEffect13(() => {
|
|
5698
5861
|
const el = contentRef.current;
|
|
5699
|
-
if (!el)
|
|
5862
|
+
if (!el) {
|
|
5863
|
+
return;
|
|
5864
|
+
}
|
|
5700
5865
|
const observer = new ResizeObserver(([entry]) => {
|
|
5701
5866
|
setContentHeight(entry.contentRect.height);
|
|
5702
5867
|
});
|
|
@@ -5740,7 +5905,15 @@ var ArtifactsPanel = React71.forwardRef(
|
|
|
5740
5905
|
},
|
|
5741
5906
|
"\u2212"
|
|
5742
5907
|
),
|
|
5743
|
-
/* @__PURE__ */ React71.createElement(
|
|
5908
|
+
/* @__PURE__ */ React71.createElement(
|
|
5909
|
+
"span",
|
|
5910
|
+
{
|
|
5911
|
+
className: "text-xs text-silver w-8 text-center tabular-nums",
|
|
5912
|
+
"data-testid": "zoom-level"
|
|
5913
|
+
},
|
|
5914
|
+
Math.round(currentZoom * 100),
|
|
5915
|
+
"%"
|
|
5916
|
+
),
|
|
5744
5917
|
/* @__PURE__ */ React71.createElement(
|
|
5745
5918
|
"button",
|
|
5746
5919
|
{
|
|
@@ -5815,7 +5988,7 @@ var ArtifactsPanel = React71.forwardRef(
|
|
|
5815
5988
|
ArtifactModal,
|
|
5816
5989
|
{
|
|
5817
5990
|
artifact: expandedArtifact,
|
|
5818
|
-
onClose:
|
|
5991
|
+
onClose: handleModalClose
|
|
5819
5992
|
}
|
|
5820
5993
|
));
|
|
5821
5994
|
}
|
|
@@ -5852,7 +6025,7 @@ var ArtifactsPanelToggle = React71.forwardRef(({ artifactCount = 0, onExpand, cl
|
|
|
5852
6025
|
ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
|
|
5853
6026
|
|
|
5854
6027
|
// src/components/chat/HistoryPanel.tsx
|
|
5855
|
-
import React72, { useCallback as
|
|
6028
|
+
import React72, { useCallback as useCallback19, useEffect as useEffect14, useMemo as useMemo3, useRef as useRef13, useState as useState19 } from "react";
|
|
5856
6029
|
import { ChevronDown as ChevronDown2, Pencil as Pencil2 } from "lucide-react";
|
|
5857
6030
|
function parseTimestamp(ts) {
|
|
5858
6031
|
if (ts == null) {
|
|
@@ -5895,9 +6068,9 @@ function ProjectFilter({
|
|
|
5895
6068
|
onChange,
|
|
5896
6069
|
className
|
|
5897
6070
|
}) {
|
|
5898
|
-
const [open, setOpen] =
|
|
5899
|
-
const ref =
|
|
5900
|
-
const closeFilter =
|
|
6071
|
+
const [open, setOpen] = useState19(false);
|
|
6072
|
+
const ref = useRef13(null);
|
|
6073
|
+
const closeFilter = useCallback19(() => setOpen(false), []);
|
|
5901
6074
|
useClickOutside(ref, closeFilter, open);
|
|
5902
6075
|
const label = value ?? "All projects";
|
|
5903
6076
|
return /* @__PURE__ */ React72.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ React72.createElement(
|
|
@@ -5972,28 +6145,28 @@ function ConversationRow({
|
|
|
5972
6145
|
onSelect,
|
|
5973
6146
|
onRename
|
|
5974
6147
|
}) {
|
|
5975
|
-
const [isEditing, setIsEditing] =
|
|
5976
|
-
const [draft, setDraft] =
|
|
5977
|
-
const inputRef =
|
|
5978
|
-
|
|
6148
|
+
const [isEditing, setIsEditing] = useState19(false);
|
|
6149
|
+
const [draft, setDraft] = useState19(conversation.title);
|
|
6150
|
+
const inputRef = useRef13(null);
|
|
6151
|
+
useEffect14(() => {
|
|
5979
6152
|
if (isEditing && inputRef.current) {
|
|
5980
6153
|
inputRef.current.focus();
|
|
5981
6154
|
inputRef.current.select();
|
|
5982
6155
|
}
|
|
5983
6156
|
}, [isEditing]);
|
|
5984
|
-
const startEdit =
|
|
6157
|
+
const startEdit = useCallback19((e) => {
|
|
5985
6158
|
e.stopPropagation();
|
|
5986
6159
|
setDraft(conversation.title);
|
|
5987
6160
|
setIsEditing(true);
|
|
5988
6161
|
}, [conversation.title]);
|
|
5989
|
-
const commit =
|
|
6162
|
+
const commit = useCallback19(() => {
|
|
5990
6163
|
const trimmed = draft.trim();
|
|
5991
6164
|
if (trimmed && trimmed !== conversation.title) {
|
|
5992
6165
|
onRename?.(conversation.id, trimmed);
|
|
5993
6166
|
}
|
|
5994
6167
|
setIsEditing(false);
|
|
5995
6168
|
}, [draft, conversation.id, conversation.title, onRename]);
|
|
5996
|
-
const cancel =
|
|
6169
|
+
const cancel = useCallback19(() => {
|
|
5997
6170
|
setDraft(conversation.title);
|
|
5998
6171
|
setIsEditing(false);
|
|
5999
6172
|
}, [conversation.title]);
|
|
@@ -6077,7 +6250,7 @@ function HistoryPanel({
|
|
|
6077
6250
|
onNewChat,
|
|
6078
6251
|
onRenameConversation
|
|
6079
6252
|
}) {
|
|
6080
|
-
const [projectFilter, setProjectFilter] =
|
|
6253
|
+
const [projectFilter, setProjectFilter] = useState19(null);
|
|
6081
6254
|
const projects = useMemo3(() => {
|
|
6082
6255
|
const set = /* @__PURE__ */ new Set();
|
|
6083
6256
|
for (const c of conversations) {
|
|
@@ -6087,7 +6260,7 @@ function HistoryPanel({
|
|
|
6087
6260
|
}
|
|
6088
6261
|
return Array.from(set).sort((a, b) => a.localeCompare(b));
|
|
6089
6262
|
}, [conversations]);
|
|
6090
|
-
|
|
6263
|
+
useEffect14(() => {
|
|
6091
6264
|
if (projectFilter && !projects.includes(projectFilter)) {
|
|
6092
6265
|
setProjectFilter(null);
|
|
6093
6266
|
}
|
|
@@ -6143,7 +6316,7 @@ function HistoryPanel({
|
|
|
6143
6316
|
}
|
|
6144
6317
|
|
|
6145
6318
|
// src/components/chat/TodosList.tsx
|
|
6146
|
-
import React73, { useCallback as
|
|
6319
|
+
import React73, { useCallback as useCallback20, useMemo as useMemo4, useState as useState20 } from "react";
|
|
6147
6320
|
import { Loader2 as Loader22, Square as Square2 } from "lucide-react";
|
|
6148
6321
|
var TASK_STATUSES = {
|
|
6149
6322
|
PENDING: "pending",
|
|
@@ -6222,8 +6395,8 @@ function hasInProgressTask(tasks) {
|
|
|
6222
6395
|
var TodosList = React73.forwardRef(
|
|
6223
6396
|
({ tasks, title = "Tasks", onStopAllTasks, className, ...rest }, ref) => {
|
|
6224
6397
|
const sortedTasks = useMemo4(() => sortTasks(tasks), [tasks]);
|
|
6225
|
-
const [isStopping, setIsStopping] =
|
|
6226
|
-
const handleStopClick =
|
|
6398
|
+
const [isStopping, setIsStopping] = useState20(false);
|
|
6399
|
+
const handleStopClick = useCallback20(async () => {
|
|
6227
6400
|
if (!onStopAllTasks || isStopping) {
|
|
6228
6401
|
return;
|
|
6229
6402
|
}
|
|
@@ -6348,7 +6521,7 @@ var ToolSidebar = React74.forwardRef(
|
|
|
6348
6521
|
ToolSidebar.displayName = "ToolSidebar";
|
|
6349
6522
|
|
|
6350
6523
|
// src/components/chat/ToolPanelContainer.tsx
|
|
6351
|
-
import React75, { useCallback as
|
|
6524
|
+
import React75, { useCallback as useCallback21, useEffect as useEffect15, useRef as useRef14, useState as useState21 } from "react";
|
|
6352
6525
|
var ToolPanelContainer = React75.forwardRef(
|
|
6353
6526
|
({
|
|
6354
6527
|
topContent,
|
|
@@ -6360,21 +6533,21 @@ var ToolPanelContainer = React75.forwardRef(
|
|
|
6360
6533
|
initialTopPercent = 60,
|
|
6361
6534
|
...rest
|
|
6362
6535
|
}, ref) => {
|
|
6363
|
-
const [topPercent, setTopPercent] =
|
|
6364
|
-
const [isResizingHeight, setIsResizingHeight] =
|
|
6365
|
-
const containerRef =
|
|
6366
|
-
const lastY =
|
|
6536
|
+
const [topPercent, setTopPercent] = useState21(initialTopPercent);
|
|
6537
|
+
const [isResizingHeight, setIsResizingHeight] = useState21(false);
|
|
6538
|
+
const containerRef = useRef14(null);
|
|
6539
|
+
const lastY = useRef14(null);
|
|
6367
6540
|
const hasBoth = topContent !== null && bottomContent !== null;
|
|
6368
|
-
const startHeightResize =
|
|
6541
|
+
const startHeightResize = useCallback21((e) => {
|
|
6369
6542
|
e.preventDefault();
|
|
6370
6543
|
setIsResizingHeight(true);
|
|
6371
6544
|
lastY.current = e.clientY;
|
|
6372
6545
|
}, []);
|
|
6373
|
-
const stopHeightResize =
|
|
6546
|
+
const stopHeightResize = useCallback21(() => {
|
|
6374
6547
|
setIsResizingHeight(false);
|
|
6375
6548
|
lastY.current = null;
|
|
6376
6549
|
}, []);
|
|
6377
|
-
const resizeHeight =
|
|
6550
|
+
const resizeHeight = useCallback21(
|
|
6378
6551
|
(e) => {
|
|
6379
6552
|
if (!isResizingHeight || lastY.current === null || !containerRef.current) {
|
|
6380
6553
|
return;
|
|
@@ -6393,7 +6566,7 @@ var ToolPanelContainer = React75.forwardRef(
|
|
|
6393
6566
|
},
|
|
6394
6567
|
[isResizingHeight]
|
|
6395
6568
|
);
|
|
6396
|
-
|
|
6569
|
+
useEffect15(() => {
|
|
6397
6570
|
if (isResizingHeight) {
|
|
6398
6571
|
window.addEventListener("mousemove", resizeHeight);
|
|
6399
6572
|
window.addEventListener("mouseup", stopHeightResize);
|
|
@@ -6468,65 +6641,6 @@ var ToolPanelContainer = React75.forwardRef(
|
|
|
6468
6641
|
);
|
|
6469
6642
|
ToolPanelContainer.displayName = "ToolPanelContainer";
|
|
6470
6643
|
|
|
6471
|
-
// src/components/chat/hooks/useResizable.ts
|
|
6472
|
-
import { useCallback as useCallback21, useEffect as useEffect15, useRef as useRef14, useState as useState21 } from "react";
|
|
6473
|
-
function useResizable({
|
|
6474
|
-
initialWidthPercent,
|
|
6475
|
-
minWidthPercent,
|
|
6476
|
-
maxWidthPercent,
|
|
6477
|
-
direction
|
|
6478
|
-
}) {
|
|
6479
|
-
const [widthPercent, setWidthPercent] = useState21(initialWidthPercent);
|
|
6480
|
-
const [isResizing, setIsResizing] = useState21(false);
|
|
6481
|
-
const lastX = useRef14(null);
|
|
6482
|
-
const startResizing = useCallback21((e) => {
|
|
6483
|
-
e.preventDefault();
|
|
6484
|
-
setIsResizing(true);
|
|
6485
|
-
lastX.current = e.clientX;
|
|
6486
|
-
}, []);
|
|
6487
|
-
const stopResizing = useCallback21(() => {
|
|
6488
|
-
setIsResizing(false);
|
|
6489
|
-
lastX.current = null;
|
|
6490
|
-
}, []);
|
|
6491
|
-
const resize = useCallback21(
|
|
6492
|
-
(e) => {
|
|
6493
|
-
if (!isResizing || lastX.current === null) {
|
|
6494
|
-
return;
|
|
6495
|
-
}
|
|
6496
|
-
const deltaX = e.clientX - lastX.current;
|
|
6497
|
-
const factor = direction === "right" ? 1 : -1;
|
|
6498
|
-
const deltaPercent = deltaX / window.innerWidth * 100;
|
|
6499
|
-
setWidthPercent((prevPercent) => {
|
|
6500
|
-
const newPercent = prevPercent + deltaPercent * factor;
|
|
6501
|
-
return Math.min(Math.max(newPercent, minWidthPercent), maxWidthPercent);
|
|
6502
|
-
});
|
|
6503
|
-
lastX.current = e.clientX;
|
|
6504
|
-
},
|
|
6505
|
-
[isResizing, direction, minWidthPercent, maxWidthPercent]
|
|
6506
|
-
);
|
|
6507
|
-
useEffect15(() => {
|
|
6508
|
-
if (isResizing) {
|
|
6509
|
-
window.addEventListener("mousemove", resize);
|
|
6510
|
-
window.addEventListener("mouseup", stopResizing);
|
|
6511
|
-
document.body.style.cursor = "col-resize";
|
|
6512
|
-
document.body.style.userSelect = "none";
|
|
6513
|
-
} else {
|
|
6514
|
-
window.removeEventListener("mousemove", resize);
|
|
6515
|
-
window.removeEventListener("mouseup", stopResizing);
|
|
6516
|
-
document.body.style.cursor = "";
|
|
6517
|
-
document.body.style.userSelect = "";
|
|
6518
|
-
}
|
|
6519
|
-
return () => {
|
|
6520
|
-
window.removeEventListener("mousemove", resize);
|
|
6521
|
-
window.removeEventListener("mouseup", stopResizing);
|
|
6522
|
-
document.body.style.cursor = "";
|
|
6523
|
-
document.body.style.userSelect = "";
|
|
6524
|
-
};
|
|
6525
|
-
}, [isResizing, resize, stopResizing]);
|
|
6526
|
-
const width = `${widthPercent}vw`;
|
|
6527
|
-
return { width, widthPercent, isResizing, startResizing };
|
|
6528
|
-
}
|
|
6529
|
-
|
|
6530
6644
|
// src/components/chat/tree.ts
|
|
6531
6645
|
function createEmptyTree() {
|
|
6532
6646
|
return { nodes: {}, rootIds: [], activeLeafId: null, lastLeafId: null };
|
|
@@ -6687,6 +6801,7 @@ var ChatInterface = React76.forwardRef(
|
|
|
6687
6801
|
onRenameConversation,
|
|
6688
6802
|
isStreaming = false,
|
|
6689
6803
|
isThinking = false,
|
|
6804
|
+
thinkingLabel,
|
|
6690
6805
|
placeholder = "Send a message...",
|
|
6691
6806
|
emptyStateHelper = "Let's talk.",
|
|
6692
6807
|
emptyState,
|
|
@@ -6695,6 +6810,7 @@ var ChatInterface = React76.forwardRef(
|
|
|
6695
6810
|
attachments: propsAttachments,
|
|
6696
6811
|
onAttachmentsChange,
|
|
6697
6812
|
onAttachmentRemove,
|
|
6813
|
+
onAttachmentOpen,
|
|
6698
6814
|
artifactNodes,
|
|
6699
6815
|
isArtifactsPanelOpen,
|
|
6700
6816
|
onArtifactsPanelOpenChange,
|
|
@@ -6711,6 +6827,14 @@ var ChatInterface = React76.forwardRef(
|
|
|
6711
6827
|
}, ref) => {
|
|
6712
6828
|
const prevArtifactNodesRef = useRef15([]);
|
|
6713
6829
|
const prevTasksRef = useRef15([]);
|
|
6830
|
+
const [panelOpenArtifactId, setPanelOpenArtifactId] = useState22(null);
|
|
6831
|
+
const handleAttachmentOpen = useCallback22((artifactId) => {
|
|
6832
|
+
setPanelOpenArtifactId(artifactId);
|
|
6833
|
+
onAttachmentOpen?.(artifactId);
|
|
6834
|
+
}, [onAttachmentOpen]);
|
|
6835
|
+
const handleArtifactPanelClosed = useCallback22(() => {
|
|
6836
|
+
setPanelOpenArtifactId(null);
|
|
6837
|
+
}, []);
|
|
6714
6838
|
const [internalTools, setInternalTools] = useState22({
|
|
6715
6839
|
"top-left": "history",
|
|
6716
6840
|
"bottom-left": null,
|
|
@@ -6898,7 +7022,15 @@ var ChatInterface = React76.forwardRef(
|
|
|
6898
7022
|
isStreaming: node.isStreaming,
|
|
6899
7023
|
muted: opts.muted,
|
|
6900
7024
|
branchInfo,
|
|
6901
|
-
actions
|
|
7025
|
+
actions,
|
|
7026
|
+
attachments: node.attachments ? node.attachments.map((a) => ({
|
|
7027
|
+
id: a.id,
|
|
7028
|
+
file: { name: a.name, size: a.size ?? 0, type: a.type },
|
|
7029
|
+
previewUrl: a.previewUrl,
|
|
7030
|
+
artifactId: a.artifactId,
|
|
7031
|
+
status: a.status ?? "analyzed"
|
|
7032
|
+
})) : void 0,
|
|
7033
|
+
onAttachmentOpen: handleAttachmentOpen
|
|
6902
7034
|
};
|
|
6903
7035
|
},
|
|
6904
7036
|
[
|
|
@@ -6908,7 +7040,8 @@ var ChatInterface = React76.forwardRef(
|
|
|
6908
7040
|
onEditMessage,
|
|
6909
7041
|
onRetryMessage,
|
|
6910
7042
|
handleBranchSwitch,
|
|
6911
|
-
handleJumpToCheckpoint
|
|
7043
|
+
handleJumpToCheckpoint,
|
|
7044
|
+
handleAttachmentOpen
|
|
6912
7045
|
]
|
|
6913
7046
|
);
|
|
6914
7047
|
const displayItems = useMemo5(() => {
|
|
@@ -6977,6 +7110,8 @@ var ChatInterface = React76.forwardRef(
|
|
|
6977
7110
|
ArtifactsPanel,
|
|
6978
7111
|
{
|
|
6979
7112
|
nodes: artifactNodes,
|
|
7113
|
+
openArtifactId: panelOpenArtifactId,
|
|
7114
|
+
onArtifactClosed: handleArtifactPanelClosed,
|
|
6980
7115
|
className: "h-full"
|
|
6981
7116
|
}
|
|
6982
7117
|
);
|
|
@@ -7039,6 +7174,7 @@ var ChatInterface = React76.forwardRef(
|
|
|
7039
7174
|
latestUserMessageIndex,
|
|
7040
7175
|
isStreaming,
|
|
7041
7176
|
isThinking,
|
|
7177
|
+
thinkingLabel,
|
|
7042
7178
|
className: "flex-1"
|
|
7043
7179
|
}
|
|
7044
7180
|
)), /* @__PURE__ */ React76.createElement("div", { className: cx(
|