@lukeashford/aurelius 4.0.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.js CHANGED
@@ -59,6 +59,7 @@ __export(index_exports, {
59
59
  ChatView: () => ChatView,
60
60
  CheckSquareIcon: () => CheckSquareIcon,
61
61
  Checkbox: () => Checkbox,
62
+ Checkpoint: () => Checkpoint,
62
63
  ChevronLeftIcon: () => ChevronLeftIcon,
63
64
  ChevronRightIcon: () => ChevronRightIcon,
64
65
  CloseIcon: () => CloseIcon,
@@ -72,6 +73,7 @@ __export(index_exports, {
72
73
  EmptySquareIcon: () => EmptySquareIcon,
73
74
  ExpandIcon: () => ExpandIcon,
74
75
  FileChip: () => FileChip,
76
+ GreyedDivider: () => GreyedDivider,
75
77
  HelperText: () => HelperText,
76
78
  HistoryIcon: () => HistoryIcon,
77
79
  HistoryPanel: () => HistoryPanel,
@@ -149,16 +151,22 @@ __export(index_exports, {
149
151
  ToolSidebar: () => ToolSidebar,
150
152
  Tooltip: () => Tooltip,
151
153
  VideoCard: () => VideoCard,
152
- addMessageToTree: () => addMessageToTree,
154
+ addNodeToTree: () => addNodeToTree,
153
155
  areAllTasksSettled: () => areAllTasksSettled,
154
156
  createEmptyTree: () => createEmptyTree,
157
+ createPreviewUrl: () => createPreviewUrl,
158
+ findAncestor: () => findAncestor,
155
159
  generateId: () => generateId,
156
- getActivePathMessages: () => getActivePathMessages,
160
+ getActivePath: () => getActivePath,
161
+ getGreyedFuture: () => getGreyedFuture,
157
162
  getSiblingInfo: () => getSiblingInfo,
158
163
  isBranchPoint: () => isBranchPoint,
164
+ isImageFile: () => isImageFile,
159
165
  messagesToTree: () => messagesToTree,
166
+ revokePreviewUrl: () => revokePreviewUrl,
167
+ setActiveLeaf: () => setActiveLeaf,
160
168
  switchBranch: () => switchBranch,
161
- updateNodeContent: () => updateNodeContent,
169
+ updateMessageContent: () => updateMessageContent,
162
170
  useArtifactTreeNavigation: () => useArtifactTreeNavigation,
163
171
  useResizable: () => useResizable,
164
172
  useScrollAnchor: () => useScrollAnchor,
@@ -4213,10 +4221,10 @@ var StreamingCursor = import_react57.default.forwardRef(
4213
4221
  StreamingCursor.displayName = "StreamingCursor";
4214
4222
 
4215
4223
  // src/components/chat/ChatInterface.tsx
4216
- var import_react79 = __toESM(require("react"));
4224
+ var import_react81 = __toESM(require("react"));
4217
4225
 
4218
4226
  // src/components/chat/ChatView.tsx
4219
- var import_react61 = __toESM(require("react"));
4227
+ var import_react63 = __toESM(require("react"));
4220
4228
 
4221
4229
  // src/components/chat/hooks/useScrollAnchor.ts
4222
4230
  var import_react58 = require("react");
@@ -4431,9 +4439,169 @@ var ThinkingIndicator = import_react60.default.forwardRef(
4431
4439
  );
4432
4440
  ThinkingIndicator.displayName = "ThinkingIndicator";
4433
4441
 
4442
+ // src/components/chat/Checkpoint.tsx
4443
+ var import_react61 = __toESM(require("react"));
4444
+ var import_lucide_react12 = require("lucide-react");
4445
+ var KIND_ICONS = {
4446
+ task: import_lucide_react12.GitBranch,
4447
+ submit: import_lucide_react12.GitMerge,
4448
+ rename: import_lucide_react12.PencilLine,
4449
+ init: import_lucide_react12.GitCommitVertical
4450
+ };
4451
+ var KIND_ARIA_LABELS = {
4452
+ task: "Task checkpoint",
4453
+ submit: "Submit checkpoint",
4454
+ rename: "Rename checkpoint",
4455
+ init: "Project head checkpoint"
4456
+ };
4457
+ var Checkpoint = import_react61.default.forwardRef(
4458
+ function Checkpoint2({ name, executionKind, status = "completed", isActive, muted, branchInfo, onJumpHere }, ref) {
4459
+ const KindIcon = KIND_ICONS[executionKind];
4460
+ const isFailed = status === "failed";
4461
+ const isCancelled = status === "cancelled";
4462
+ const isInteractive = !isActive && !!onJumpHere;
4463
+ const iconColor = isActive ? "text-gold" : isFailed ? "text-error-muted" : "text-silver/50";
4464
+ const nameClasses = cx(
4465
+ "transition-colors text-xs",
4466
+ 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"
4467
+ );
4468
+ return /* @__PURE__ */ import_react61.default.createElement(
4469
+ "div",
4470
+ {
4471
+ ref,
4472
+ role: "group",
4473
+ "aria-label": KIND_ARIA_LABELS[executionKind],
4474
+ className: cx(
4475
+ "group/checkpoint flex items-center gap-2 py-1.5 select-none",
4476
+ muted && "opacity-60"
4477
+ )
4478
+ },
4479
+ /* @__PURE__ */ import_react61.default.createElement(KindIcon, { className: cx("w-3.5 h-3.5 shrink-0", iconColor), "aria-hidden": "true" }),
4480
+ /* @__PURE__ */ import_react61.default.createElement(
4481
+ "button",
4482
+ {
4483
+ type: "button",
4484
+ onClick: isInteractive ? onJumpHere : void 0,
4485
+ disabled: !isInteractive,
4486
+ className: cx(
4487
+ nameClasses,
4488
+ "truncate text-left",
4489
+ !isInteractive && "cursor-default"
4490
+ ),
4491
+ "aria-label": isInteractive ? `Jump to checkpoint ${name}` : name
4492
+ },
4493
+ /* @__PURE__ */ import_react61.default.createElement("span", { className: "truncate" }, name),
4494
+ isFailed && /* @__PURE__ */ import_react61.default.createElement("span", { className: "ml-1.5 text-error-muted" }, "\xB7 failed"),
4495
+ isCancelled && /* @__PURE__ */ import_react61.default.createElement("span", { className: "ml-1.5 text-silver/40" }, "\xB7 cancelled")
4496
+ ),
4497
+ isInteractive && /* @__PURE__ */ import_react61.default.createElement(
4498
+ "span",
4499
+ {
4500
+ className: cx(
4501
+ "ml-1 inline-flex items-center gap-1 text-xs text-silver/40",
4502
+ "opacity-0 group-hover/checkpoint:opacity-100 transition-opacity",
4503
+ "pointer-events-none"
4504
+ ),
4505
+ "aria-hidden": "true"
4506
+ },
4507
+ /* @__PURE__ */ import_react61.default.createElement(import_lucide_react12.ArrowLeft, { className: "w-3 h-3" }),
4508
+ "Jump here"
4509
+ ),
4510
+ branchInfo && branchInfo.total > 1 && /* @__PURE__ */ import_react61.default.createElement(
4511
+ "div",
4512
+ {
4513
+ className: "ml-auto inline-flex items-center gap-0.5 text-silver/70 text-xs",
4514
+ role: "navigation",
4515
+ "aria-label": "Switch sibling checkpoint"
4516
+ },
4517
+ /* @__PURE__ */ import_react61.default.createElement(
4518
+ "button",
4519
+ {
4520
+ type: "button",
4521
+ onClick: branchInfo.onPrevious,
4522
+ disabled: branchInfo.current <= 1,
4523
+ className: cx(
4524
+ "p-0.5 hover:text-white hover:bg-white/10 transition-colors",
4525
+ "disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
4526
+ ),
4527
+ "aria-label": "Previous sibling checkpoint"
4528
+ },
4529
+ /* @__PURE__ */ import_react61.default.createElement(import_lucide_react12.ChevronLeft, { className: "w-3 h-3" })
4530
+ ),
4531
+ /* @__PURE__ */ import_react61.default.createElement("span", { className: "tabular-nums min-w-6 text-center" }, branchInfo.current, "/", branchInfo.total),
4532
+ /* @__PURE__ */ import_react61.default.createElement(
4533
+ "button",
4534
+ {
4535
+ type: "button",
4536
+ onClick: branchInfo.onNext,
4537
+ disabled: branchInfo.current >= branchInfo.total,
4538
+ className: cx(
4539
+ "p-0.5 hover:text-white hover:bg-white/10 transition-colors",
4540
+ "disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
4541
+ ),
4542
+ "aria-label": "Next sibling checkpoint"
4543
+ },
4544
+ /* @__PURE__ */ import_react61.default.createElement(import_lucide_react12.ChevronRight, { className: "w-3 h-3" })
4545
+ )
4546
+ )
4547
+ );
4548
+ }
4549
+ );
4550
+ Checkpoint.displayName = "Checkpoint";
4551
+
4552
+ // src/components/chat/GreyedDivider.tsx
4553
+ var import_react62 = __toESM(require("react"));
4554
+ var import_lucide_react13 = require("lucide-react");
4555
+ function pluralize(n, singular, plural) {
4556
+ return `${n} ${n === 1 ? singular : plural}`;
4557
+ }
4558
+ function summarize(messageCount, checkpointCount) {
4559
+ const parts = [];
4560
+ if (messageCount > 0) {
4561
+ parts.push(pluralize(messageCount, "message", "messages"));
4562
+ }
4563
+ if (checkpointCount > 0) {
4564
+ parts.push(pluralize(checkpointCount, "checkpoint", "checkpoints"));
4565
+ }
4566
+ return parts.length > 0 ? parts.join(", ") : "no items";
4567
+ }
4568
+ var GreyedDivider = import_react62.default.forwardRef(
4569
+ function GreyedDivider2({ messageCount, checkpointCount, onJumpToLatest }, ref) {
4570
+ if (messageCount === 0 && checkpointCount === 0) {
4571
+ return null;
4572
+ }
4573
+ return /* @__PURE__ */ import_react62.default.createElement(
4574
+ "div",
4575
+ {
4576
+ ref,
4577
+ role: "separator",
4578
+ "aria-label": "Start of rewound timeline",
4579
+ className: "flex items-center gap-3 py-2 text-xs text-silver/50 select-none"
4580
+ },
4581
+ /* @__PURE__ */ import_react62.default.createElement("div", { className: "flex-1 h-px bg-ash/40", "aria-hidden": "true" }),
4582
+ /* @__PURE__ */ import_react62.default.createElement("span", { className: "inline-flex items-center gap-1.5 whitespace-nowrap" }, /* @__PURE__ */ import_react62.default.createElement(import_lucide_react13.ArrowDown, { className: "w-3 h-3", "aria-hidden": "true" }), "Later in this conversation \xB7 ", summarize(messageCount, checkpointCount)),
4583
+ /* @__PURE__ */ import_react62.default.createElement("div", { className: "flex-1 h-px bg-ash/40", "aria-hidden": "true" }),
4584
+ onJumpToLatest && /* @__PURE__ */ import_react62.default.createElement(
4585
+ "button",
4586
+ {
4587
+ type: "button",
4588
+ onClick: onJumpToLatest,
4589
+ className: cx(
4590
+ "shrink-0 transition-colors",
4591
+ "text-silver/60 hover:text-white",
4592
+ "underline decoration-silver/30 underline-offset-4 decoration-dotted hover:decoration-silver/70"
4593
+ )
4594
+ },
4595
+ "Jump to latest \u2192"
4596
+ )
4597
+ );
4598
+ }
4599
+ );
4600
+ GreyedDivider.displayName = "GreyedDivider";
4601
+
4434
4602
  // src/components/chat/ChatView.tsx
4435
- var ChatView = import_react61.default.forwardRef(
4436
- ({ messages, latestUserMessageIndex, isStreaming, isThinking, onScroll, className, ...rest }, ref) => {
4603
+ var ChatView = import_react63.default.forwardRef(
4604
+ function ChatView2({ items, latestUserMessageIndex, isStreaming, isThinking, onScroll, className, ...rest }, ref) {
4437
4605
  const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
4438
4606
  behavior: "smooth",
4439
4607
  block: "start"
@@ -4442,19 +4610,23 @@ var ChatView = import_react61.default.forwardRef(
4442
4610
  containerRef,
4443
4611
  anchorRef
4444
4612
  });
4445
- (0, import_react61.useEffect)(() => {
4613
+ const latestUserIdx = latestUserMessageIndex ?? items.reduceRight((found, item, idx) => {
4614
+ if (found === -1 && item.kind === "message" && item.variant === "user") {
4615
+ return idx;
4616
+ }
4617
+ return found;
4618
+ }, -1);
4619
+ (0, import_react63.useEffect)(() => {
4446
4620
  if (latestUserMessageIndex !== void 0 && latestUserMessageIndex >= 0) {
4447
4621
  scrollToAnchor();
4448
4622
  }
4449
4623
  }, [latestUserMessageIndex, scrollToAnchor]);
4450
- const latestUserIdx = latestUserMessageIndex ?? messages.reduceRight((found, msg, idx) => {
4451
- if (found === -1 && msg.variant === "user") {
4452
- return idx;
4453
- }
4454
- return found;
4624
+ const lastMessageIdx = items.reduceRight((found, item, idx) => {
4625
+ return found === -1 && item.kind === "message" ? idx : found;
4455
4626
  }, -1);
4456
- const showThinking = isThinking && messages.length > 0 && messages[messages.length - 1]?.variant === "user";
4457
- return /* @__PURE__ */ import_react61.default.createElement(
4627
+ const lastMessage = lastMessageIdx >= 0 ? items[lastMessageIdx] : null;
4628
+ const showThinking = isThinking && lastMessage?.kind === "message" && lastMessage.variant === "user";
4629
+ return /* @__PURE__ */ import_react63.default.createElement(
4458
4630
  "div",
4459
4631
  {
4460
4632
  ref: composeRefs(containerRef, ref),
@@ -4466,27 +4638,40 @@ var ChatView = import_react61.default.forwardRef(
4466
4638
  ),
4467
4639
  ...rest
4468
4640
  },
4469
- /* @__PURE__ */ import_react61.default.createElement("div", { ref: contentRef, className: "relative flex flex-col gap-3" }, messages.map(({
4470
- id,
4471
- variant,
4472
- className: messageClassName,
4473
- branchInfo,
4474
- actions,
4475
- isStreaming: nodeIsStreaming,
4476
- ...messageProps
4477
- }, index) => {
4641
+ /* @__PURE__ */ import_react63.default.createElement("div", { ref: contentRef, className: "relative flex flex-col gap-3" }, items.map((item, index) => {
4478
4642
  const isAnchor = index === latestUserIdx;
4479
- const isLastMessage = index === messages.length - 1;
4643
+ const wrapperRef = isAnchor ? anchorRef : void 0;
4644
+ const wrapperClass = isAnchor ? "scroll-mt-4" : void 0;
4645
+ if (item.kind === "divider") {
4646
+ const { kind: _k2, id: id2, ...dividerProps } = item;
4647
+ return /* @__PURE__ */ import_react63.default.createElement("div", { key: id2 }, /* @__PURE__ */ import_react63.default.createElement(GreyedDivider, { ...dividerProps }));
4648
+ }
4649
+ if (item.kind === "checkpoint") {
4650
+ const { kind: _k2, id: id2, ...checkpointProps } = item;
4651
+ return /* @__PURE__ */ import_react63.default.createElement("div", { key: id2, ref: wrapperRef, className: wrapperClass }, /* @__PURE__ */ import_react63.default.createElement(Checkpoint, { ...checkpointProps }));
4652
+ }
4653
+ const {
4654
+ kind: _k,
4655
+ id,
4656
+ variant,
4657
+ muted,
4658
+ className: messageClassName,
4659
+ branchInfo,
4660
+ actions,
4661
+ isStreaming: nodeIsStreaming,
4662
+ ...messageProps
4663
+ } = item;
4664
+ const isLastMessage = index === lastMessageIdx;
4480
4665
  const showStreaming = isLastMessage && isStreaming && variant === "assistant";
4481
4666
  const isMessageStreaming = showStreaming || !!nodeIsStreaming;
4482
- return /* @__PURE__ */ import_react61.default.createElement(
4667
+ return /* @__PURE__ */ import_react63.default.createElement(
4483
4668
  "div",
4484
4669
  {
4485
- key: id ?? `msg-${index}`,
4486
- ref: isAnchor ? anchorRef : void 0,
4487
- className: isAnchor ? "scroll-mt-4" : void 0
4670
+ key: id,
4671
+ ref: wrapperRef,
4672
+ className: cx(wrapperClass, muted && "opacity-60")
4488
4673
  },
4489
- /* @__PURE__ */ import_react61.default.createElement(
4674
+ /* @__PURE__ */ import_react63.default.createElement(
4490
4675
  Message,
4491
4676
  {
4492
4677
  variant,
@@ -4499,8 +4684,8 @@ var ChatView = import_react61.default.forwardRef(
4499
4684
  }
4500
4685
  )
4501
4686
  );
4502
- }), showThinking && /* @__PURE__ */ import_react61.default.createElement(ThinkingIndicator, { isVisible: true })),
4503
- /* @__PURE__ */ import_react61.default.createElement(
4687
+ }), showThinking && /* @__PURE__ */ import_react63.default.createElement(ThinkingIndicator, { isVisible: true })),
4688
+ /* @__PURE__ */ import_react63.default.createElement(
4504
4689
  "div",
4505
4690
  {
4506
4691
  ref: spacerRef,
@@ -4515,8 +4700,8 @@ var ChatView = import_react61.default.forwardRef(
4515
4700
  ChatView.displayName = "ChatView";
4516
4701
 
4517
4702
  // src/components/chat/ChatInput.tsx
4518
- var import_react62 = __toESM(require("react"));
4519
- var import_lucide_react12 = require("lucide-react");
4703
+ var import_react64 = __toESM(require("react"));
4704
+ var import_lucide_react14 = require("lucide-react");
4520
4705
 
4521
4706
  // src/components/chat/types.ts
4522
4707
  function isImageFile(file) {
@@ -4528,159 +4713,20 @@ function createPreviewUrl(file) {
4528
4713
  }
4529
4714
  return void 0;
4530
4715
  }
4716
+ function revokePreviewUrl(url) {
4717
+ if (url) {
4718
+ URL.revokeObjectURL(url);
4719
+ }
4720
+ }
4531
4721
  function generateId() {
4532
4722
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
4533
4723
  return crypto.randomUUID();
4534
4724
  }
4535
4725
  return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
4536
4726
  }
4537
- function createEmptyTree() {
4538
- return {
4539
- nodes: {},
4540
- rootIds: [],
4541
- activeLeafId: null
4542
- };
4543
- }
4544
- function addMessageToTree(tree, message, parentId = null) {
4545
- const newNodes = { ...tree.nodes };
4546
- const newRootIds = [...tree.rootIds];
4547
- let branchIndex = 0;
4548
- if (parentId && newNodes[parentId]) {
4549
- branchIndex = newNodes[parentId].children.length;
4550
- } else if (!parentId) {
4551
- branchIndex = newRootIds.length;
4552
- }
4553
- newNodes[message.id] = {
4554
- ...message,
4555
- parentId,
4556
- children: [],
4557
- branchIndex,
4558
- createdAt: message.createdAt ?? Date.now()
4559
- };
4560
- if (parentId && newNodes[parentId]) {
4561
- newNodes[parentId] = {
4562
- ...newNodes[parentId],
4563
- children: [...newNodes[parentId].children, message.id]
4564
- };
4565
- } else {
4566
- newRootIds.push(message.id);
4567
- }
4568
- return {
4569
- nodes: newNodes,
4570
- rootIds: newRootIds,
4571
- activeLeafId: message.id
4572
- };
4573
- }
4574
- function getActivePathMessages(tree) {
4575
- if (!tree.activeLeafId) {
4576
- return [];
4577
- }
4578
- const path = [];
4579
- let currentId = tree.activeLeafId;
4580
- while (currentId) {
4581
- const node = tree.nodes[currentId];
4582
- if (!node) {
4583
- break;
4584
- }
4585
- path.unshift(node);
4586
- currentId = node.parentId;
4587
- }
4588
- return path;
4589
- }
4590
- function getSiblingInfo(tree, nodeId) {
4591
- const node = tree.nodes[nodeId];
4592
- if (!node) {
4593
- return { total: 1, current: 1 };
4594
- }
4595
- if (node.parentId) {
4596
- const parent = tree.nodes[node.parentId];
4597
- if (parent) {
4598
- const index = parent.children.indexOf(nodeId);
4599
- return {
4600
- total: parent.children.length,
4601
- current: index + 1
4602
- };
4603
- }
4604
- } else {
4605
- const index = tree.rootIds.indexOf(nodeId);
4606
- return {
4607
- total: tree.rootIds.length,
4608
- current: index + 1
4609
- };
4610
- }
4611
- return { total: 1, current: 1 };
4612
- }
4613
- function switchBranch(tree, nodeId, direction) {
4614
- const node = tree.nodes[nodeId];
4615
- if (!node) {
4616
- return tree;
4617
- }
4618
- let siblings;
4619
- let currentIndex;
4620
- if (node.parentId) {
4621
- const parent = tree.nodes[node.parentId];
4622
- if (!parent) {
4623
- return tree;
4624
- }
4625
- siblings = parent.children;
4626
- currentIndex = siblings.indexOf(nodeId);
4627
- } else {
4628
- siblings = tree.rootIds;
4629
- currentIndex = siblings.indexOf(nodeId);
4630
- }
4631
- if (siblings.length <= 1) {
4632
- return tree;
4633
- }
4634
- const newIndex = direction === "next" ? (currentIndex + 1) % siblings.length : (currentIndex - 1 + siblings.length) % siblings.length;
4635
- let leafId = siblings[newIndex];
4636
- let currentNode = tree.nodes[leafId];
4637
- while (currentNode && currentNode.children.length > 0) {
4638
- leafId = currentNode.children[0];
4639
- currentNode = tree.nodes[leafId];
4640
- }
4641
- return {
4642
- ...tree,
4643
- activeLeafId: leafId
4644
- };
4645
- }
4646
- function updateNodeContent(tree, nodeId, content, isStreaming) {
4647
- const node = tree.nodes[nodeId];
4648
- if (!node) {
4649
- return tree;
4650
- }
4651
- return {
4652
- ...tree,
4653
- nodes: {
4654
- ...tree.nodes,
4655
- [nodeId]: {
4656
- ...node,
4657
- content,
4658
- isStreaming: isStreaming ?? node.isStreaming
4659
- }
4660
- }
4661
- };
4662
- }
4663
- function messagesToTree(messages) {
4664
- let tree = createEmptyTree();
4665
- for (const msg of messages) {
4666
- const parentId = tree.activeLeafId;
4667
- tree = addMessageToTree(tree, {
4668
- id: msg.id,
4669
- role: msg.role,
4670
- content: msg.content,
4671
- parentId,
4672
- isStreaming: msg.isStreaming
4673
- }, parentId);
4674
- }
4675
- return tree;
4676
- }
4677
- function isBranchPoint(tree, nodeId) {
4678
- const node = tree.nodes[nodeId];
4679
- return node ? node.children.length > 1 : false;
4680
- }
4681
4727
 
4682
4728
  // src/components/chat/ChatInput.tsx
4683
- var ChatInput = import_react62.default.forwardRef(
4729
+ var ChatInput = import_react64.default.forwardRef(
4684
4730
  ({
4685
4731
  position = "bottom",
4686
4732
  placeholder = "Send a message...",
@@ -4702,13 +4748,13 @@ var ChatInput = import_react62.default.forwardRef(
4702
4748
  className,
4703
4749
  ...rest
4704
4750
  }, ref) => {
4705
- const [value, setValue] = (0, import_react62.useState)(initialInputValue);
4706
- const [localAttachments, setLocalAttachments] = (0, import_react62.useState)([]);
4707
- const [isDragOver, setIsDragOver] = (0, import_react62.useState)(false);
4708
- const textareaRef = (0, import_react62.useRef)(null);
4709
- const fileInputRef = (0, import_react62.useRef)(null);
4751
+ const [value, setValue] = (0, import_react64.useState)(initialInputValue);
4752
+ const [localAttachments, setLocalAttachments] = (0, import_react64.useState)([]);
4753
+ const [isDragOver, setIsDragOver] = (0, import_react64.useState)(false);
4754
+ const textareaRef = (0, import_react64.useRef)(null);
4755
+ const fileInputRef = (0, import_react64.useRef)(null);
4710
4756
  const attachments = controlledAttachments ?? localAttachments;
4711
- const setAttachments = (0, import_react62.useCallback)(
4757
+ const setAttachments = (0, import_react64.useCallback)(
4712
4758
  (newAttachments) => {
4713
4759
  if (onAttachmentsChange) {
4714
4760
  if (typeof newAttachments === "function") {
@@ -4722,7 +4768,7 @@ var ChatInput = import_react62.default.forwardRef(
4722
4768
  },
4723
4769
  [attachments, onAttachmentsChange]
4724
4770
  );
4725
- const handleSubmit = (0, import_react62.useCallback)(() => {
4771
+ const handleSubmit = (0, import_react64.useCallback)(() => {
4726
4772
  const trimmed = value.trim();
4727
4773
  if (!trimmed || disabled || isStreaming) {
4728
4774
  return;
@@ -4734,7 +4780,7 @@ var ChatInput = import_react62.default.forwardRef(
4734
4780
  textareaRef.current.style.height = "auto";
4735
4781
  }
4736
4782
  }, [value, disabled, isStreaming, onSubmit, attachments, setAttachments]);
4737
- const handleKeyDown = (0, import_react62.useCallback)(
4783
+ const handleKeyDown = (0, import_react64.useCallback)(
4738
4784
  (e) => {
4739
4785
  if (e.key === "Enter" && !e.shiftKey) {
4740
4786
  e.preventDefault();
@@ -4743,19 +4789,19 @@ var ChatInput = import_react62.default.forwardRef(
4743
4789
  },
4744
4790
  [handleSubmit]
4745
4791
  );
4746
- const handleChange = (0, import_react62.useCallback)((e) => {
4792
+ const handleChange = (0, import_react64.useCallback)((e) => {
4747
4793
  setValue(e.target.value);
4748
4794
  onInputChange?.(e.target.value);
4749
4795
  const textarea = e.target;
4750
4796
  textarea.style.height = "auto";
4751
4797
  textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`;
4752
4798
  }, [onInputChange]);
4753
- (0, import_react62.useEffect)(() => {
4799
+ (0, import_react64.useEffect)(() => {
4754
4800
  if (autoFocus && !disabled && !isStreaming && textareaRef.current) {
4755
4801
  textareaRef.current.focus();
4756
4802
  }
4757
4803
  }, [disabled, isStreaming, autoFocus]);
4758
- const addFiles = (0, import_react62.useCallback)(
4804
+ const addFiles = (0, import_react64.useCallback)(
4759
4805
  (files) => {
4760
4806
  const newAttachments = Array.from(files).map((file) => ({
4761
4807
  id: generateId(),
@@ -4767,7 +4813,7 @@ var ChatInput = import_react62.default.forwardRef(
4767
4813
  },
4768
4814
  [setAttachments]
4769
4815
  );
4770
- const handleFileSelect = (0, import_react62.useCallback)(
4816
+ const handleFileSelect = (0, import_react64.useCallback)(
4771
4817
  (e) => {
4772
4818
  const files = e.target.files;
4773
4819
  if (files && files.length > 0) {
@@ -4777,7 +4823,7 @@ var ChatInput = import_react62.default.forwardRef(
4777
4823
  },
4778
4824
  [addFiles]
4779
4825
  );
4780
- const handleRemoveAttachment = (0, import_react62.useCallback)(
4826
+ const handleRemoveAttachment = (0, import_react64.useCallback)(
4781
4827
  (id) => {
4782
4828
  const attachment = attachments.find((a) => a.id === id);
4783
4829
  if (attachment && onAttachmentRemove) {
@@ -4793,23 +4839,23 @@ var ChatInput = import_react62.default.forwardRef(
4793
4839
  },
4794
4840
  [attachments, onAttachmentRemove, setAttachments]
4795
4841
  );
4796
- const handleDragEnter = (0, import_react62.useCallback)((e) => {
4842
+ const handleDragEnter = (0, import_react64.useCallback)((e) => {
4797
4843
  e.preventDefault();
4798
4844
  e.stopPropagation();
4799
4845
  setIsDragOver(true);
4800
4846
  }, []);
4801
- const handleDragLeave = (0, import_react62.useCallback)((e) => {
4847
+ const handleDragLeave = (0, import_react64.useCallback)((e) => {
4802
4848
  e.preventDefault();
4803
4849
  e.stopPropagation();
4804
4850
  if (!e.currentTarget.contains(e.relatedTarget)) {
4805
4851
  setIsDragOver(false);
4806
4852
  }
4807
4853
  }, []);
4808
- const handleDragOver = (0, import_react62.useCallback)((e) => {
4854
+ const handleDragOver = (0, import_react64.useCallback)((e) => {
4809
4855
  e.preventDefault();
4810
4856
  e.stopPropagation();
4811
4857
  }, []);
4812
- const handleDrop = (0, import_react62.useCallback)(
4858
+ const handleDrop = (0, import_react64.useCallback)(
4813
4859
  (e) => {
4814
4860
  e.preventDefault();
4815
4861
  e.stopPropagation();
@@ -4825,7 +4871,7 @@ var ChatInput = import_react62.default.forwardRef(
4825
4871
  const hasAttachments = attachments.length > 0;
4826
4872
  const isUploading = attachments.some((a) => a.status === "uploading");
4827
4873
  const canSubmit = value.trim() && !disabled && !isStreaming && !isUploading;
4828
- return /* @__PURE__ */ import_react62.default.createElement(
4874
+ return /* @__PURE__ */ import_react64.default.createElement(
4829
4875
  "div",
4830
4876
  {
4831
4877
  ref,
@@ -4837,12 +4883,12 @@ var ChatInput = import_react62.default.forwardRef(
4837
4883
  ),
4838
4884
  ...rest
4839
4885
  },
4840
- isCentered && helperText && /* @__PURE__ */ import_react62.default.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
4841
- notice && /* @__PURE__ */ import_react62.default.createElement("div", { className: cx(
4886
+ isCentered && helperText && /* @__PURE__ */ import_react64.default.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
4887
+ notice && /* @__PURE__ */ import_react64.default.createElement("div", { className: cx(
4842
4888
  "w-full flex items-start gap-2 px-3 py-2 mb-1 text-xs",
4843
4889
  isCentered && "max-w-lg",
4844
4890
  notice.variant === "warning" ? "bg-gold/5 border border-gold/20 text-gold/80" : "bg-error/10 border border-error/30 text-error"
4845
- ) }, /* @__PURE__ */ import_react62.default.createElement("span", { className: "flex-1" }, notice.content), (notice.dismissible ?? notice.variant === "warning") && notice.onDismiss && /* @__PURE__ */ import_react62.default.createElement(
4891
+ ) }, /* @__PURE__ */ import_react64.default.createElement("span", { className: "flex-1" }, notice.content), (notice.dismissible ?? notice.variant === "warning") && notice.onDismiss && /* @__PURE__ */ import_react64.default.createElement(
4846
4892
  "button",
4847
4893
  {
4848
4894
  type: "button",
@@ -4853,9 +4899,9 @@ var ChatInput = import_react62.default.forwardRef(
4853
4899
  notice.variant === "warning" ? "text-gold" : "text-error"
4854
4900
  )
4855
4901
  },
4856
- /* @__PURE__ */ import_react62.default.createElement(import_lucide_react12.X, { className: "w-3 h-3" })
4902
+ /* @__PURE__ */ import_react64.default.createElement(import_lucide_react14.X, { className: "w-3 h-3" })
4857
4903
  )),
4858
- /* @__PURE__ */ import_react62.default.createElement(
4904
+ /* @__PURE__ */ import_react64.default.createElement(
4859
4905
  "div",
4860
4906
  {
4861
4907
  className: cx(
@@ -4870,7 +4916,7 @@ var ChatInput = import_react62.default.forwardRef(
4870
4916
  onDragOver: showAttachmentButton ? handleDragOver : void 0,
4871
4917
  onDrop: showAttachmentButton ? handleDrop : void 0
4872
4918
  },
4873
- hasAttachments && /* @__PURE__ */ import_react62.default.createElement("div", { className: "px-3 pt-3 pb-1" }, /* @__PURE__ */ import_react62.default.createElement(
4919
+ hasAttachments && /* @__PURE__ */ import_react64.default.createElement("div", { className: "px-3 pt-3 pb-1" }, /* @__PURE__ */ import_react64.default.createElement(
4874
4920
  AttachmentPreview,
4875
4921
  {
4876
4922
  attachments,
@@ -4878,14 +4924,14 @@ var ChatInput = import_react62.default.forwardRef(
4878
4924
  removable: !isStreaming
4879
4925
  }
4880
4926
  )),
4881
- isDragOver && /* @__PURE__ */ import_react62.default.createElement(
4927
+ isDragOver && /* @__PURE__ */ import_react64.default.createElement(
4882
4928
  "div",
4883
4929
  {
4884
4930
  className: "absolute inset-0 bg-gold/10 flex items-center justify-center z-10 pointer-events-none"
4885
4931
  },
4886
- /* @__PURE__ */ import_react62.default.createElement("span", { className: "text-gold text-sm font-medium" }, "Drop files here")
4932
+ /* @__PURE__ */ import_react64.default.createElement("span", { className: "text-gold text-sm font-medium" }, "Drop files here")
4887
4933
  ),
4888
- /* @__PURE__ */ import_react62.default.createElement("div", { className: "flex items-end" }, showAttachmentButton && /* @__PURE__ */ import_react62.default.createElement(import_react62.default.Fragment, null, /* @__PURE__ */ import_react62.default.createElement(
4934
+ /* @__PURE__ */ import_react64.default.createElement("div", { className: "flex items-end" }, showAttachmentButton && /* @__PURE__ */ import_react64.default.createElement(import_react64.default.Fragment, null, /* @__PURE__ */ import_react64.default.createElement(
4889
4935
  "button",
4890
4936
  {
4891
4937
  type: "button",
@@ -4897,8 +4943,8 @@ var ChatInput = import_react62.default.forwardRef(
4897
4943
  ),
4898
4944
  "aria-label": "Attach file"
4899
4945
  },
4900
- /* @__PURE__ */ import_react62.default.createElement(import_lucide_react12.Paperclip, { className: "w-5 h-5" })
4901
- ), /* @__PURE__ */ import_react62.default.createElement(
4946
+ /* @__PURE__ */ import_react64.default.createElement(import_lucide_react14.Paperclip, { className: "w-5 h-5" })
4947
+ ), /* @__PURE__ */ import_react64.default.createElement(
4902
4948
  "input",
4903
4949
  {
4904
4950
  ref: fileInputRef,
@@ -4909,7 +4955,7 @@ var ChatInput = import_react62.default.forwardRef(
4909
4955
  className: "hidden",
4910
4956
  "aria-hidden": "true"
4911
4957
  }
4912
- )), /* @__PURE__ */ import_react62.default.createElement(
4958
+ )), /* @__PURE__ */ import_react64.default.createElement(
4913
4959
  "textarea",
4914
4960
  {
4915
4961
  ref: textareaRef,
@@ -4927,7 +4973,7 @@ var ChatInput = import_react62.default.forwardRef(
4927
4973
  ),
4928
4974
  style: { maxHeight: 200 }
4929
4975
  }
4930
- ), isStreaming ? /* @__PURE__ */ import_react62.default.createElement(
4976
+ ), isStreaming ? /* @__PURE__ */ import_react64.default.createElement(
4931
4977
  "button",
4932
4978
  {
4933
4979
  type: "button",
@@ -4938,8 +4984,8 @@ var ChatInput = import_react62.default.forwardRef(
4938
4984
  ),
4939
4985
  "aria-label": "Stop generation"
4940
4986
  },
4941
- /* @__PURE__ */ import_react62.default.createElement(import_lucide_react12.Square, { className: "w-5 h-5 fill-current" })
4942
- ) : /* @__PURE__ */ import_react62.default.createElement(
4987
+ /* @__PURE__ */ import_react64.default.createElement(import_lucide_react14.Square, { className: "w-5 h-5 fill-current" })
4988
+ ) : /* @__PURE__ */ import_react64.default.createElement(
4943
4989
  "button",
4944
4990
  {
4945
4991
  type: "button",
@@ -4952,7 +4998,7 @@ var ChatInput = import_react62.default.forwardRef(
4952
4998
  ),
4953
4999
  "aria-label": "Send message"
4954
5000
  },
4955
- /* @__PURE__ */ import_react62.default.createElement(import_lucide_react12.Send, { className: "w-5 h-5" })
5001
+ /* @__PURE__ */ import_react64.default.createElement(import_lucide_react14.Send, { className: "w-5 h-5" })
4956
5002
  ))
4957
5003
  )
4958
5004
  );
@@ -4961,14 +5007,14 @@ var ChatInput = import_react62.default.forwardRef(
4961
5007
  ChatInput.displayName = "ChatInput";
4962
5008
 
4963
5009
  // src/components/chat/ArtifactsPanel.tsx
4964
- var import_react73 = __toESM(require("react"));
4965
- var import_lucide_react15 = require("lucide-react");
5010
+ var import_react75 = __toESM(require("react"));
5011
+ var import_lucide_react17 = require("lucide-react");
4966
5012
 
4967
5013
  // src/components/ArtifactCard.tsx
4968
- var import_react69 = __toESM(require("react"));
5014
+ var import_react71 = __toESM(require("react"));
4969
5015
 
4970
5016
  // src/components/ImageCard.tsx
4971
- var import_react63 = __toESM(require("react"));
5017
+ var import_react65 = __toESM(require("react"));
4972
5018
  var ASPECT_RATIO_PRESETS = {
4973
5019
  landscape: "3 / 2",
4974
5020
  portrait: "2 / 3",
@@ -4980,7 +5026,7 @@ function resolveAspectRatio(ratio) {
4980
5026
  }
4981
5027
  return ratio.replace("/", " / ");
4982
5028
  }
4983
- var ImageCard = import_react63.default.forwardRef(
5029
+ var ImageCard = import_react65.default.forwardRef(
4984
5030
  ({
4985
5031
  src,
4986
5032
  alt = "",
@@ -4996,7 +5042,7 @@ var ImageCard = import_react63.default.forwardRef(
4996
5042
  loading,
4997
5043
  ...props
4998
5044
  }, ref) => {
4999
- return /* @__PURE__ */ import_react63.default.createElement(
5045
+ return /* @__PURE__ */ import_react65.default.createElement(
5000
5046
  Card,
5001
5047
  {
5002
5048
  ref,
@@ -5004,13 +5050,13 @@ var ImageCard = import_react63.default.forwardRef(
5004
5050
  loading,
5005
5051
  ...props
5006
5052
  },
5007
- /* @__PURE__ */ import_react63.default.createElement(
5053
+ /* @__PURE__ */ import_react65.default.createElement(
5008
5054
  Card.Media,
5009
5055
  {
5010
5056
  className: mediaClassName,
5011
5057
  style: { aspectRatio: resolveAspectRatio(aspectRatio) }
5012
5058
  },
5013
- /* @__PURE__ */ import_react63.default.createElement(import_react63.default.Fragment, null, src && /* @__PURE__ */ import_react63.default.createElement(
5059
+ /* @__PURE__ */ import_react65.default.createElement(import_react65.default.Fragment, null, src && /* @__PURE__ */ import_react65.default.createElement(
5014
5060
  "img",
5015
5061
  {
5016
5062
  src,
@@ -5020,7 +5066,7 @@ var ImageCard = import_react63.default.forwardRef(
5020
5066
  objectFit === "cover" ? "object-cover" : "object-contain"
5021
5067
  )
5022
5068
  }
5023
- ), overlay && /* @__PURE__ */ import_react63.default.createElement(
5069
+ ), overlay && /* @__PURE__ */ import_react65.default.createElement(
5024
5070
  "div",
5025
5071
  {
5026
5072
  className: "absolute inset-0 bg-obsidian/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex items-center justify-center"
@@ -5028,7 +5074,7 @@ var ImageCard = import_react63.default.forwardRef(
5028
5074
  overlay
5029
5075
  ))
5030
5076
  ),
5031
- /* @__PURE__ */ import_react63.default.createElement(
5077
+ /* @__PURE__ */ import_react65.default.createElement(
5032
5078
  Card.Header,
5033
5079
  {
5034
5080
  title,
@@ -5036,14 +5082,14 @@ var ImageCard = import_react63.default.forwardRef(
5036
5082
  className: contentClassName
5037
5083
  }
5038
5084
  ),
5039
- children && /* @__PURE__ */ import_react63.default.createElement(Card.Body, { className: contentClassName }, children)
5085
+ children && /* @__PURE__ */ import_react65.default.createElement(Card.Body, { className: contentClassName }, children)
5040
5086
  );
5041
5087
  }
5042
5088
  );
5043
5089
  ImageCard.displayName = "ImageCard";
5044
5090
 
5045
5091
  // src/components/VideoCard.tsx
5046
- var import_react64 = __toESM(require("react"));
5092
+ var import_react66 = __toESM(require("react"));
5047
5093
  var import_react_player = __toESM(require("react-player"));
5048
5094
  var ASPECT_RATIO_PRESETS2 = {
5049
5095
  video: "16 / 9",
@@ -5056,7 +5102,7 @@ function resolveAspectRatio2(ratio) {
5056
5102
  }
5057
5103
  return ratio.replace("/", " / ");
5058
5104
  }
5059
- var VideoCard = import_react64.default.forwardRef(
5105
+ var VideoCard = import_react66.default.forwardRef(
5060
5106
  ({
5061
5107
  src,
5062
5108
  title,
@@ -5076,7 +5122,7 @@ var VideoCard = import_react64.default.forwardRef(
5076
5122
  loading,
5077
5123
  ...props
5078
5124
  }, ref) => {
5079
- return /* @__PURE__ */ import_react64.default.createElement(
5125
+ return /* @__PURE__ */ import_react66.default.createElement(
5080
5126
  Card,
5081
5127
  {
5082
5128
  ref,
@@ -5084,13 +5130,13 @@ var VideoCard = import_react64.default.forwardRef(
5084
5130
  loading,
5085
5131
  ...props
5086
5132
  },
5087
- /* @__PURE__ */ import_react64.default.createElement(
5133
+ /* @__PURE__ */ import_react66.default.createElement(
5088
5134
  Card.Media,
5089
5135
  {
5090
5136
  className: mediaClassName,
5091
5137
  style: { aspectRatio: resolveAspectRatio2(aspectRatio) }
5092
5138
  },
5093
- src && /* @__PURE__ */ import_react64.default.createElement(
5139
+ src && /* @__PURE__ */ import_react66.default.createElement(
5094
5140
  import_react_player.default,
5095
5141
  {
5096
5142
  src,
@@ -5107,7 +5153,7 @@ var VideoCard = import_react64.default.forwardRef(
5107
5153
  }
5108
5154
  )
5109
5155
  ),
5110
- /* @__PURE__ */ import_react64.default.createElement(
5156
+ /* @__PURE__ */ import_react66.default.createElement(
5111
5157
  Card.Header,
5112
5158
  {
5113
5159
  title,
@@ -5115,17 +5161,17 @@ var VideoCard = import_react64.default.forwardRef(
5115
5161
  className: contentClassName
5116
5162
  }
5117
5163
  ),
5118
- children && /* @__PURE__ */ import_react64.default.createElement(Card.Body, { className: contentClassName }, children)
5164
+ children && /* @__PURE__ */ import_react66.default.createElement(Card.Body, { className: contentClassName }, children)
5119
5165
  );
5120
5166
  }
5121
5167
  );
5122
5168
  VideoCard.displayName = "VideoCard";
5123
5169
 
5124
5170
  // src/components/AudioCard.tsx
5125
- var import_react65 = __toESM(require("react"));
5171
+ var import_react67 = __toESM(require("react"));
5126
5172
  var import_react_player2 = __toESM(require("react-player"));
5127
- var import_lucide_react13 = require("lucide-react");
5128
- var AudioCard = import_react65.default.forwardRef(
5173
+ var import_lucide_react15 = require("lucide-react");
5174
+ var AudioCard = import_react67.default.forwardRef(
5129
5175
  ({
5130
5176
  src,
5131
5177
  title,
@@ -5144,7 +5190,7 @@ var AudioCard = import_react65.default.forwardRef(
5144
5190
  loading,
5145
5191
  ...props
5146
5192
  }, ref) => {
5147
- return /* @__PURE__ */ import_react65.default.createElement(
5193
+ return /* @__PURE__ */ import_react67.default.createElement(
5148
5194
  Card,
5149
5195
  {
5150
5196
  ref,
@@ -5152,10 +5198,10 @@ var AudioCard = import_react65.default.forwardRef(
5152
5198
  loading,
5153
5199
  ...props
5154
5200
  },
5155
- /* @__PURE__ */ import_react65.default.createElement(Card.Media, { className: cx(
5201
+ /* @__PURE__ */ import_react67.default.createElement(Card.Media, { className: cx(
5156
5202
  "bg-obsidian py-8 flex flex-col items-center justify-center",
5157
5203
  mediaClassName
5158
- ) }, /* @__PURE__ */ import_react65.default.createElement("div", { className: "mb-4 text-gold" }, /* @__PURE__ */ import_react65.default.createElement(import_lucide_react13.Music, { size: 48 })), src && /* @__PURE__ */ import_react65.default.createElement("div", { className: "w-full px-4" }, /* @__PURE__ */ import_react65.default.createElement(
5204
+ ) }, /* @__PURE__ */ import_react67.default.createElement("div", { className: "mb-4 text-gold" }, /* @__PURE__ */ import_react67.default.createElement(import_lucide_react15.Music, { size: 48 })), src && /* @__PURE__ */ import_react67.default.createElement("div", { className: "w-full px-4" }, /* @__PURE__ */ import_react67.default.createElement(
5159
5205
  import_react_player2.default,
5160
5206
  {
5161
5207
  src,
@@ -5170,7 +5216,7 @@ var AudioCard = import_react65.default.forwardRef(
5170
5216
  ...playerProps
5171
5217
  }
5172
5218
  ))),
5173
- /* @__PURE__ */ import_react65.default.createElement(
5219
+ /* @__PURE__ */ import_react67.default.createElement(
5174
5220
  Card.Header,
5175
5221
  {
5176
5222
  title,
@@ -5178,16 +5224,16 @@ var AudioCard = import_react65.default.forwardRef(
5178
5224
  className: contentClassName
5179
5225
  }
5180
5226
  ),
5181
- children && /* @__PURE__ */ import_react65.default.createElement(Card.Body, { className: contentClassName }, children)
5227
+ children && /* @__PURE__ */ import_react67.default.createElement(Card.Body, { className: contentClassName }, children)
5182
5228
  );
5183
5229
  }
5184
5230
  );
5185
5231
  AudioCard.displayName = "AudioCard";
5186
5232
 
5187
5233
  // src/components/PdfCard.tsx
5188
- var import_react66 = __toESM(require("react"));
5189
- var import_lucide_react14 = require("lucide-react");
5190
- var PdfCard = import_react66.default.forwardRef(
5234
+ var import_react68 = __toESM(require("react"));
5235
+ var import_lucide_react16 = require("lucide-react");
5236
+ var PdfCard = import_react68.default.forwardRef(
5191
5237
  ({
5192
5238
  src,
5193
5239
  title,
@@ -5200,7 +5246,7 @@ var PdfCard = import_react66.default.forwardRef(
5200
5246
  loading,
5201
5247
  ...props
5202
5248
  }, ref) => {
5203
- return /* @__PURE__ */ import_react66.default.createElement(
5249
+ return /* @__PURE__ */ import_react68.default.createElement(
5204
5250
  Card,
5205
5251
  {
5206
5252
  ref,
@@ -5208,13 +5254,13 @@ var PdfCard = import_react66.default.forwardRef(
5208
5254
  loading,
5209
5255
  ...props
5210
5256
  },
5211
- /* @__PURE__ */ import_react66.default.createElement(
5257
+ /* @__PURE__ */ import_react68.default.createElement(
5212
5258
  Card.Media,
5213
5259
  {
5214
5260
  className: cx("bg-obsidian", mediaClassName),
5215
5261
  style: { height }
5216
5262
  },
5217
- src && /* @__PURE__ */ import_react66.default.createElement(
5263
+ src && /* @__PURE__ */ import_react68.default.createElement(
5218
5264
  "iframe",
5219
5265
  {
5220
5266
  src: `${src}#view=FitH`,
@@ -5223,23 +5269,23 @@ var PdfCard = import_react66.default.forwardRef(
5223
5269
  }
5224
5270
  )
5225
5271
  ),
5226
- /* @__PURE__ */ import_react66.default.createElement(
5272
+ /* @__PURE__ */ import_react68.default.createElement(
5227
5273
  Card.Header,
5228
5274
  {
5229
5275
  title,
5230
5276
  subtitle,
5231
5277
  className: contentClassName,
5232
- action: /* @__PURE__ */ import_react66.default.createElement("div", { className: "p-2 bg-ash/20 text-gold shrink-0" }, /* @__PURE__ */ import_react66.default.createElement(import_lucide_react14.FileText, { size: 20 }))
5278
+ action: /* @__PURE__ */ import_react68.default.createElement("div", { className: "p-2 bg-ash/20 text-gold shrink-0" }, /* @__PURE__ */ import_react68.default.createElement(import_lucide_react16.FileText, { size: 20 }))
5233
5279
  }
5234
5280
  ),
5235
- children && /* @__PURE__ */ import_react66.default.createElement(Card.Body, { className: contentClassName }, children)
5281
+ children && /* @__PURE__ */ import_react68.default.createElement(Card.Body, { className: contentClassName }, children)
5236
5282
  );
5237
5283
  }
5238
5284
  );
5239
5285
  PdfCard.displayName = "PdfCard";
5240
5286
 
5241
5287
  // src/components/ScriptCard.tsx
5242
- var import_react67 = __toESM(require("react"));
5288
+ var import_react69 = __toESM(require("react"));
5243
5289
  var SCRIPT_ELEMENT_TYPES = {
5244
5290
  SCENE_HEADING: "scene-heading",
5245
5291
  ACTION: "action",
@@ -5253,28 +5299,28 @@ var SCRIPT_ELEMENT_TYPES = {
5253
5299
  function ScriptElementRenderer({ element }) {
5254
5300
  switch (element.type) {
5255
5301
  case "scene-heading":
5256
- return /* @__PURE__ */ import_react67.default.createElement("p", { className: "mt-4 mb-2 font-bold uppercase text-gold text-xs tracking-wide" }, element.content);
5302
+ return /* @__PURE__ */ import_react69.default.createElement("p", { className: "mt-4 mb-2 font-bold uppercase text-gold text-xs tracking-wide" }, element.content);
5257
5303
  case "action":
5258
- return /* @__PURE__ */ import_react67.default.createElement("p", { className: "my-2 text-silver text-xs leading-relaxed" }, element.content);
5304
+ return /* @__PURE__ */ import_react69.default.createElement("p", { className: "my-2 text-silver text-xs leading-relaxed" }, element.content);
5259
5305
  case "character":
5260
- return /* @__PURE__ */ import_react67.default.createElement("p", { className: "mt-4 mb-0.5 ml-8 font-bold text-white text-xs uppercase tracking-wide" }, element.content);
5306
+ return /* @__PURE__ */ import_react69.default.createElement("p", { className: "mt-4 mb-0.5 ml-8 font-bold text-white text-xs uppercase tracking-wide" }, element.content);
5261
5307
  case "parenthetical":
5262
- return /* @__PURE__ */ import_react67.default.createElement("p", { className: "ml-6 text-silver/70 text-xs italic" }, "(", element.content, ")");
5308
+ return /* @__PURE__ */ import_react69.default.createElement("p", { className: "ml-6 text-silver/70 text-xs italic" }, "(", element.content, ")");
5263
5309
  case "dialogue":
5264
- return /* @__PURE__ */ import_react67.default.createElement("p", { className: "ml-4 mr-8 text-silver text-xs leading-relaxed" }, element.content);
5310
+ return /* @__PURE__ */ import_react69.default.createElement("p", { className: "ml-4 mr-8 text-silver text-xs leading-relaxed" }, element.content);
5265
5311
  case "transition":
5266
- return /* @__PURE__ */ import_react67.default.createElement("p", { className: "mt-4 mb-2 text-right font-bold uppercase text-gold/80 text-xs tracking-wide" }, element.content);
5312
+ return /* @__PURE__ */ import_react69.default.createElement("p", { className: "mt-4 mb-2 text-right font-bold uppercase text-gold/80 text-xs tracking-wide" }, element.content);
5267
5313
  case "title":
5268
- return /* @__PURE__ */ import_react67.default.createElement("p", { className: "mt-6 mb-2 text-center font-bold text-gold text-sm" }, element.content);
5314
+ return /* @__PURE__ */ import_react69.default.createElement("p", { className: "mt-6 mb-2 text-center font-bold text-gold text-sm" }, element.content);
5269
5315
  case "subtitle":
5270
- return /* @__PURE__ */ import_react67.default.createElement("p", { className: "text-center italic text-gold/70 text-xs" }, element.content);
5316
+ return /* @__PURE__ */ import_react69.default.createElement("p", { className: "text-center italic text-gold/70 text-xs" }, element.content);
5271
5317
  default:
5272
5318
  return null;
5273
5319
  }
5274
5320
  }
5275
- var ScriptCard = import_react67.default.forwardRef(
5321
+ var ScriptCard = import_react69.default.forwardRef(
5276
5322
  ({ title, subtitle, elements, maxHeight = "16rem", className, style, loading, ...rest }, ref) => {
5277
- return /* @__PURE__ */ import_react67.default.createElement(
5323
+ return /* @__PURE__ */ import_react69.default.createElement(
5278
5324
  Card,
5279
5325
  {
5280
5326
  ref,
@@ -5282,20 +5328,20 @@ var ScriptCard = import_react67.default.forwardRef(
5282
5328
  loading,
5283
5329
  ...rest
5284
5330
  },
5285
- /* @__PURE__ */ import_react67.default.createElement(
5331
+ /* @__PURE__ */ import_react69.default.createElement(
5286
5332
  Card.Header,
5287
5333
  {
5288
5334
  title,
5289
5335
  subtitle
5290
5336
  }
5291
5337
  ),
5292
- /* @__PURE__ */ import_react67.default.createElement(
5338
+ /* @__PURE__ */ import_react69.default.createElement(
5293
5339
  Card.Body,
5294
5340
  {
5295
5341
  className: "font-mono overflow-y-auto",
5296
5342
  style: { maxHeight, ...style }
5297
5343
  },
5298
- elements.map((element, index) => /* @__PURE__ */ import_react67.default.createElement(ScriptElementRenderer, { key: index, element }))
5344
+ elements.map((element, index) => /* @__PURE__ */ import_react69.default.createElement(ScriptElementRenderer, { key: index, element }))
5299
5345
  )
5300
5346
  );
5301
5347
  }
@@ -5303,8 +5349,8 @@ var ScriptCard = import_react67.default.forwardRef(
5303
5349
  ScriptCard.displayName = "ScriptCard";
5304
5350
 
5305
5351
  // src/components/TextCard.tsx
5306
- var import_react68 = __toESM(require("react"));
5307
- var TextCard = import_react68.default.forwardRef(
5352
+ var import_react70 = __toESM(require("react"));
5353
+ var TextCard = import_react70.default.forwardRef(
5308
5354
  ({
5309
5355
  content,
5310
5356
  title,
@@ -5316,7 +5362,7 @@ var TextCard = import_react68.default.forwardRef(
5316
5362
  loading,
5317
5363
  ...props
5318
5364
  }, ref) => {
5319
- return /* @__PURE__ */ import_react68.default.createElement(
5365
+ return /* @__PURE__ */ import_react70.default.createElement(
5320
5366
  Card,
5321
5367
  {
5322
5368
  ref,
@@ -5324,20 +5370,20 @@ var TextCard = import_react68.default.forwardRef(
5324
5370
  loading,
5325
5371
  ...props
5326
5372
  },
5327
- /* @__PURE__ */ import_react68.default.createElement(
5373
+ /* @__PURE__ */ import_react70.default.createElement(
5328
5374
  Card.Header,
5329
5375
  {
5330
5376
  title,
5331
5377
  subtitle
5332
5378
  }
5333
5379
  ),
5334
- /* @__PURE__ */ import_react68.default.createElement(
5380
+ /* @__PURE__ */ import_react70.default.createElement(
5335
5381
  Card.Body,
5336
5382
  {
5337
5383
  className: cx("overflow-y-auto", contentClassName),
5338
5384
  style: { maxHeight }
5339
5385
  },
5340
- /* @__PURE__ */ import_react68.default.createElement(
5386
+ /* @__PURE__ */ import_react70.default.createElement(
5341
5387
  MarkdownContent,
5342
5388
  {
5343
5389
  content,
@@ -5375,7 +5421,7 @@ var ARTIFACT_TYPES = {
5375
5421
  SCRIPT: "SCRIPT",
5376
5422
  PDF: "PDF"
5377
5423
  };
5378
- var ArtifactCard = import_react69.default.forwardRef(
5424
+ var ArtifactCard = import_react71.default.forwardRef(
5379
5425
  ({ artifact, onExpand, loading, className, ...props }, ref) => {
5380
5426
  const derivedLoading = deriveCardSlotLoading(artifact);
5381
5427
  const commonProps = {
@@ -5393,7 +5439,7 @@ var ArtifactCard = import_react69.default.forwardRef(
5393
5439
  const renderContent = () => {
5394
5440
  switch (artifact.type) {
5395
5441
  case "IMAGE":
5396
- return /* @__PURE__ */ import_react69.default.createElement(
5442
+ return /* @__PURE__ */ import_react71.default.createElement(
5397
5443
  ImageCard,
5398
5444
  {
5399
5445
  ...commonProps,
@@ -5403,7 +5449,7 @@ var ArtifactCard = import_react69.default.forwardRef(
5403
5449
  }
5404
5450
  );
5405
5451
  case "VIDEO":
5406
- return /* @__PURE__ */ import_react69.default.createElement(
5452
+ return /* @__PURE__ */ import_react71.default.createElement(
5407
5453
  VideoCard,
5408
5454
  {
5409
5455
  ...commonProps,
@@ -5413,7 +5459,7 @@ var ArtifactCard = import_react69.default.forwardRef(
5413
5459
  }
5414
5460
  );
5415
5461
  case "AUDIO":
5416
- return /* @__PURE__ */ import_react69.default.createElement(
5462
+ return /* @__PURE__ */ import_react71.default.createElement(
5417
5463
  AudioCard,
5418
5464
  {
5419
5465
  ...commonProps,
@@ -5422,7 +5468,7 @@ var ArtifactCard = import_react69.default.forwardRef(
5422
5468
  }
5423
5469
  );
5424
5470
  case "PDF":
5425
- return /* @__PURE__ */ import_react69.default.createElement(
5471
+ return /* @__PURE__ */ import_react71.default.createElement(
5426
5472
  PdfCard,
5427
5473
  {
5428
5474
  ...commonProps,
@@ -5430,7 +5476,7 @@ var ArtifactCard = import_react69.default.forwardRef(
5430
5476
  }
5431
5477
  );
5432
5478
  case "SCRIPT":
5433
- return /* @__PURE__ */ import_react69.default.createElement(
5479
+ return /* @__PURE__ */ import_react71.default.createElement(
5434
5480
  ScriptCard,
5435
5481
  {
5436
5482
  ...commonProps,
@@ -5439,7 +5485,7 @@ var ArtifactCard = import_react69.default.forwardRef(
5439
5485
  }
5440
5486
  );
5441
5487
  case "TEXT":
5442
- return /* @__PURE__ */ import_react69.default.createElement(
5488
+ return /* @__PURE__ */ import_react71.default.createElement(
5443
5489
  TextCard,
5444
5490
  {
5445
5491
  ...commonProps,
@@ -5457,7 +5503,7 @@ var ArtifactCard = import_react69.default.forwardRef(
5457
5503
  }
5458
5504
  };
5459
5505
  const isCardExpandable = !!onExpand && (artifact.type === "IMAGE" || artifact.type === "PDF" || artifact.type === "SCRIPT" || artifact.type === "TEXT");
5460
- return /* @__PURE__ */ import_react69.default.createElement(
5506
+ return /* @__PURE__ */ import_react71.default.createElement(
5461
5507
  "div",
5462
5508
  {
5463
5509
  ref,
@@ -5470,7 +5516,7 @@ var ArtifactCard = import_react69.default.forwardRef(
5470
5516
  onClick: isCardExpandable ? handleExpand : void 0,
5471
5517
  ...props
5472
5518
  },
5473
- onExpand && /* @__PURE__ */ import_react69.default.createElement(
5519
+ onExpand && /* @__PURE__ */ import_react71.default.createElement(
5474
5520
  "button",
5475
5521
  {
5476
5522
  onClick: handleExpand,
@@ -5481,7 +5527,7 @@ var ArtifactCard = import_react69.default.forwardRef(
5481
5527
  ),
5482
5528
  "aria-label": "Expand artifact"
5483
5529
  },
5484
- /* @__PURE__ */ import_react69.default.createElement(ExpandIcon, { className: "w-4 h-4" })
5530
+ /* @__PURE__ */ import_react71.default.createElement(ExpandIcon, { className: "w-4 h-4" })
5485
5531
  ),
5486
5532
  renderContent()
5487
5533
  );
@@ -5490,17 +5536,17 @@ var ArtifactCard = import_react69.default.forwardRef(
5490
5536
  ArtifactCard.displayName = "ArtifactCard";
5491
5537
 
5492
5538
  // src/components/ArtifactGroup.tsx
5493
- var import_react70 = __toESM(require("react"));
5539
+ var import_react72 = __toESM(require("react"));
5494
5540
  var LAYER_OFFSET = "8px";
5495
5541
  var LAYER_OFFSET_2X = "16px";
5496
- var ArtifactGroup = import_react70.default.forwardRef(
5542
+ var ArtifactGroup = import_react72.default.forwardRef(
5497
5543
  ({ node, onClick, className, ...props }, ref) => {
5498
5544
  const children = node.children;
5499
5545
  const count = children.length;
5500
5546
  const frontChild = children[0];
5501
- const prevCountRef = (0, import_react70.useRef)(count);
5502
- const [badgePing, setBadgePing] = (0, import_react70.useState)(false);
5503
- (0, import_react70.useEffect)(() => {
5547
+ const prevCountRef = (0, import_react72.useRef)(count);
5548
+ const [badgePing, setBadgePing] = (0, import_react72.useState)(false);
5549
+ (0, import_react72.useEffect)(() => {
5504
5550
  if (count !== prevCountRef.current) {
5505
5551
  prevCountRef.current = count;
5506
5552
  setBadgePing(true);
@@ -5515,21 +5561,21 @@ var ArtifactGroup = import_react70.default.forwardRef(
5515
5561
  };
5516
5562
  const renderFrontContent = () => {
5517
5563
  if (!frontChild) {
5518
- return /* @__PURE__ */ import_react70.default.createElement("div", { className: "w-full aspect-video bg-graphite border border-ash/40 flex items-center justify-center" }, /* @__PURE__ */ import_react70.default.createElement("span", { className: "text-silver text-sm" }, "Empty group"));
5564
+ return /* @__PURE__ */ import_react72.default.createElement("div", { className: "w-full aspect-video bg-graphite border border-ash/40 flex items-center justify-center" }, /* @__PURE__ */ import_react72.default.createElement("span", { className: "text-silver text-sm" }, "Empty group"));
5519
5565
  }
5520
5566
  if (frontChild.type === "ARTIFACT" && frontChild.artifact) {
5521
- return /* @__PURE__ */ import_react70.default.createElement(ArtifactCard, { artifact: frontChild.artifact, className: "w-full" });
5567
+ return /* @__PURE__ */ import_react72.default.createElement(ArtifactCard, { artifact: frontChild.artifact, className: "w-full" });
5522
5568
  }
5523
- return /* @__PURE__ */ import_react70.default.createElement(
5569
+ return /* @__PURE__ */ import_react72.default.createElement(
5524
5570
  "div",
5525
5571
  {
5526
5572
  className: "w-full aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
5527
5573
  },
5528
- /* @__PURE__ */ import_react70.default.createElement("span", { className: "text-sm text-silver uppercase tracking-wider" }, frontChild.type === "GROUP" ? "Group" : "Variants"),
5529
- /* @__PURE__ */ import_react70.default.createElement("span", { className: "text-white font-semibold" }, frontChild.label)
5574
+ /* @__PURE__ */ import_react72.default.createElement("span", { className: "text-sm text-silver uppercase tracking-wider" }, frontChild.type === "GROUP" ? "Group" : "Variants"),
5575
+ /* @__PURE__ */ import_react72.default.createElement("span", { className: "text-white font-semibold" }, frontChild.label)
5530
5576
  );
5531
5577
  };
5532
- return /* @__PURE__ */ import_react70.default.createElement(
5578
+ return /* @__PURE__ */ import_react72.default.createElement(
5533
5579
  "div",
5534
5580
  {
5535
5581
  ref,
@@ -5549,21 +5595,21 @@ var ArtifactGroup = import_react70.default.forwardRef(
5549
5595
  "aria-label": `${node.label} \u2014 ${count} items`,
5550
5596
  ...props
5551
5597
  },
5552
- /* @__PURE__ */ import_react70.default.createElement(Card, { noPadding: true, className: "p-5" }, /* @__PURE__ */ import_react70.default.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label), /* @__PURE__ */ import_react70.default.createElement("div", { style: { paddingRight: LAYER_OFFSET_2X, paddingBottom: LAYER_OFFSET_2X } }, /* @__PURE__ */ import_react70.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react70.default.createElement(
5598
+ /* @__PURE__ */ import_react72.default.createElement(Card, { noPadding: true, className: "p-5" }, /* @__PURE__ */ import_react72.default.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label), /* @__PURE__ */ import_react72.default.createElement("div", { style: { paddingRight: LAYER_OFFSET_2X, paddingBottom: LAYER_OFFSET_2X } }, /* @__PURE__ */ import_react72.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react72.default.createElement(
5553
5599
  "div",
5554
5600
  {
5555
5601
  className: "absolute inset-0 bg-charcoal border border-ash/30 pointer-events-none",
5556
5602
  style: { transform: `translate(${LAYER_OFFSET_2X}, ${LAYER_OFFSET_2X})` },
5557
5603
  "aria-hidden": "true"
5558
5604
  }
5559
- ), /* @__PURE__ */ import_react70.default.createElement(
5605
+ ), /* @__PURE__ */ import_react72.default.createElement(
5560
5606
  "div",
5561
5607
  {
5562
5608
  className: "absolute inset-0 bg-charcoal border border-ash/40 pointer-events-none",
5563
5609
  style: { transform: `translate(${LAYER_OFFSET}, ${LAYER_OFFSET})` },
5564
5610
  "aria-hidden": "true"
5565
5611
  }
5566
- ), /* @__PURE__ */ import_react70.default.createElement("div", { className: "relative transition-transform duration-200 group-hover:-translate-y-0.5" }, renderFrontContent()), /* @__PURE__ */ import_react70.default.createElement(
5612
+ ), /* @__PURE__ */ import_react72.default.createElement("div", { className: "relative transition-transform duration-200 group-hover:-translate-y-0.5" }, renderFrontContent()), /* @__PURE__ */ import_react72.default.createElement(
5567
5613
  "div",
5568
5614
  {
5569
5615
  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",
@@ -5577,13 +5623,13 @@ var ArtifactGroup = import_react70.default.forwardRef(
5577
5623
  ArtifactGroup.displayName = "ArtifactGroup";
5578
5624
 
5579
5625
  // src/components/ArtifactVariantStack.tsx
5580
- var import_react71 = __toESM(require("react"));
5581
- var ArtifactVariantStack = import_react71.default.forwardRef(
5626
+ var import_react73 = __toESM(require("react"));
5627
+ var ArtifactVariantStack = import_react73.default.forwardRef(
5582
5628
  ({ node, onExpandArtifact, onGroupClick, className, ...props }, ref) => {
5583
5629
  const children = node.children;
5584
5630
  const renderChild = (child) => {
5585
5631
  if (child.type === "ARTIFACT" && child.artifact) {
5586
- return /* @__PURE__ */ import_react71.default.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react71.default.createElement(
5632
+ return /* @__PURE__ */ import_react73.default.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react73.default.createElement(
5587
5633
  ArtifactCard,
5588
5634
  {
5589
5635
  artifact: child.artifact,
@@ -5593,18 +5639,18 @@ var ArtifactVariantStack = import_react71.default.forwardRef(
5593
5639
  ));
5594
5640
  }
5595
5641
  if (child.type === "GROUP") {
5596
- return /* @__PURE__ */ import_react71.default.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react71.default.createElement(ArtifactGroup, { node: child, onClick: onGroupClick }));
5642
+ return /* @__PURE__ */ import_react73.default.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react73.default.createElement(ArtifactGroup, { node: child, onClick: onGroupClick }));
5597
5643
  }
5598
- return /* @__PURE__ */ import_react71.default.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react71.default.createElement(
5644
+ return /* @__PURE__ */ import_react73.default.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react73.default.createElement(
5599
5645
  "div",
5600
5646
  {
5601
5647
  className: "aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
5602
5648
  },
5603
- /* @__PURE__ */ import_react71.default.createElement("span", { className: "text-xs text-silver uppercase tracking-wider" }, "Variants"),
5604
- /* @__PURE__ */ import_react71.default.createElement("span", { className: "text-sm text-white font-semibold truncate max-w-full" }, child.label)
5649
+ /* @__PURE__ */ import_react73.default.createElement("span", { className: "text-xs text-silver uppercase tracking-wider" }, "Variants"),
5650
+ /* @__PURE__ */ import_react73.default.createElement("span", { className: "text-sm text-white font-semibold truncate max-w-full" }, child.label)
5605
5651
  ));
5606
5652
  };
5607
- return /* @__PURE__ */ import_react71.default.createElement(
5653
+ return /* @__PURE__ */ import_react73.default.createElement(
5608
5654
  Card,
5609
5655
  {
5610
5656
  ref,
@@ -5612,22 +5658,22 @@ var ArtifactVariantStack = import_react71.default.forwardRef(
5612
5658
  className: cx("w-full p-5", className),
5613
5659
  ...props
5614
5660
  },
5615
- /* @__PURE__ */ import_react71.default.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label),
5616
- /* @__PURE__ */ import_react71.default.createElement("div", { className: "flex gap-3" }, children.map(renderChild))
5661
+ /* @__PURE__ */ import_react73.default.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label),
5662
+ /* @__PURE__ */ import_react73.default.createElement("div", { className: "flex gap-3" }, children.map(renderChild))
5617
5663
  );
5618
5664
  }
5619
5665
  );
5620
5666
  ArtifactVariantStack.displayName = "ArtifactVariantStack";
5621
5667
 
5622
5668
  // src/components/chat/hooks/useArtifactTreeNavigation.ts
5623
- var import_react72 = require("react");
5669
+ var import_react74 = require("react");
5624
5670
  function useArtifactTreeNavigation(rootNodes) {
5625
- const [stack, setStack] = (0, import_react72.useState)([]);
5626
- const currentNodes = (0, import_react72.useMemo)(() => {
5671
+ const [stack, setStack] = (0, import_react74.useState)([]);
5672
+ const currentNodes = (0, import_react74.useMemo)(() => {
5627
5673
  if (stack.length === 0) return rootNodes;
5628
5674
  return stack[stack.length - 1].children;
5629
5675
  }, [rootNodes, stack]);
5630
- const breadcrumbs = (0, import_react72.useMemo)(() => {
5676
+ const breadcrumbs = (0, import_react74.useMemo)(() => {
5631
5677
  const entries = [{ label: "Project", node: null }];
5632
5678
  for (const node of stack) {
5633
5679
  entries.push({ label: node.label, node });
@@ -5635,13 +5681,13 @@ function useArtifactTreeNavigation(rootNodes) {
5635
5681
  return entries;
5636
5682
  }, [stack]);
5637
5683
  const isAtRoot = stack.length === 0;
5638
- const navigateInto = (0, import_react72.useCallback)((node) => {
5684
+ const navigateInto = (0, import_react74.useCallback)((node) => {
5639
5685
  setStack((prev) => [...prev, node]);
5640
5686
  }, []);
5641
- const navigateTo = (0, import_react72.useCallback)((index) => {
5687
+ const navigateTo = (0, import_react74.useCallback)((index) => {
5642
5688
  setStack((prev) => prev.slice(0, index));
5643
5689
  }, []);
5644
- const navigateBack = (0, import_react72.useCallback)(() => {
5690
+ const navigateBack = (0, import_react74.useCallback)(() => {
5645
5691
  setStack((prev) => prev.slice(0, -1));
5646
5692
  }, []);
5647
5693
  return {
@@ -5661,46 +5707,46 @@ function ArtifactModal({
5661
5707
  onClose
5662
5708
  }) {
5663
5709
  useEscapeKey(onClose);
5664
- const handleBackdropClick = (0, import_react73.useCallback)((e) => {
5710
+ const handleBackdropClick = (0, import_react75.useCallback)((e) => {
5665
5711
  if (e.target === e.currentTarget) {
5666
5712
  onClose();
5667
5713
  }
5668
5714
  }, [onClose]);
5669
- return /* @__PURE__ */ import_react73.default.createElement(
5715
+ return /* @__PURE__ */ import_react75.default.createElement(
5670
5716
  "div",
5671
5717
  {
5672
5718
  className: "fixed inset-0 z-50 flex items-center justify-center bg-void/90 backdrop-blur-sm animate-fade-in",
5673
5719
  onClick: handleBackdropClick
5674
5720
  },
5675
- /* @__PURE__ */ import_react73.default.createElement(
5721
+ /* @__PURE__ */ import_react75.default.createElement(
5676
5722
  "div",
5677
5723
  {
5678
5724
  className: "relative w-11/12 h-5/6 max-w-6xl bg-charcoal border border-ash/40 flex flex-col overflow-hidden"
5679
5725
  },
5680
- /* @__PURE__ */ import_react73.default.createElement(
5726
+ /* @__PURE__ */ import_react75.default.createElement(
5681
5727
  "div",
5682
5728
  {
5683
5729
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5684
5730
  },
5685
- /* @__PURE__ */ import_react73.default.createElement("div", null, artifact.title && /* @__PURE__ */ import_react73.default.createElement("h3", { className: "text-sm font-semibold text-white" }, artifact.title), artifact.subtitle && /* @__PURE__ */ import_react73.default.createElement("p", { className: "text-xs text-silver" }, artifact.subtitle)),
5686
- /* @__PURE__ */ import_react73.default.createElement(
5731
+ /* @__PURE__ */ import_react75.default.createElement("div", null, artifact.title && /* @__PURE__ */ import_react75.default.createElement("h3", { className: "text-sm font-semibold text-white" }, artifact.title), artifact.subtitle && /* @__PURE__ */ import_react75.default.createElement("p", { className: "text-xs text-silver" }, artifact.subtitle)),
5732
+ /* @__PURE__ */ import_react75.default.createElement(
5687
5733
  "button",
5688
5734
  {
5689
5735
  onClick: onClose,
5690
5736
  className: "p-2 text-silver hover:text-white hover:bg-ash/20 transition-colors",
5691
5737
  "aria-label": "Close modal"
5692
5738
  },
5693
- /* @__PURE__ */ import_react73.default.createElement(CloseIcon, { className: "w-5 h-5" })
5739
+ /* @__PURE__ */ import_react75.default.createElement(CloseIcon, { className: "w-5 h-5" })
5694
5740
  )
5695
5741
  ),
5696
- /* @__PURE__ */ import_react73.default.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ import_react73.default.createElement(
5742
+ /* @__PURE__ */ import_react75.default.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ import_react75.default.createElement(
5697
5743
  "img",
5698
5744
  {
5699
5745
  src: artifact.url,
5700
5746
  alt: artifact.alt || "Artifact image",
5701
5747
  className: "max-w-full max-h-full object-contain mx-auto"
5702
5748
  }
5703
- ), artifact.type === "VIDEO" && /* @__PURE__ */ import_react73.default.createElement(
5749
+ ), artifact.type === "VIDEO" && /* @__PURE__ */ import_react75.default.createElement(
5704
5750
  VideoCard,
5705
5751
  {
5706
5752
  src: artifact.url || "",
@@ -5708,20 +5754,20 @@ function ArtifactModal({
5708
5754
  controls: true,
5709
5755
  className: "max-w-full max-h-full mx-auto"
5710
5756
  }
5711
- ), artifact.type === "AUDIO" && /* @__PURE__ */ import_react73.default.createElement(
5757
+ ), artifact.type === "AUDIO" && /* @__PURE__ */ import_react75.default.createElement(
5712
5758
  AudioCard,
5713
5759
  {
5714
5760
  src: artifact.url || "",
5715
5761
  controls: true,
5716
5762
  className: "max-w-xl mx-auto"
5717
5763
  }
5718
- ), artifact.type === "PDF" && /* @__PURE__ */ import_react73.default.createElement(
5764
+ ), artifact.type === "PDF" && /* @__PURE__ */ import_react75.default.createElement(
5719
5765
  PdfCard,
5720
5766
  {
5721
5767
  src: artifact.url || "",
5722
5768
  className: "h-full border-0"
5723
5769
  }
5724
- ), artifact.type === "TEXT" && /* @__PURE__ */ import_react73.default.createElement(
5770
+ ), artifact.type === "TEXT" && /* @__PURE__ */ import_react75.default.createElement(
5725
5771
  MarkdownContent,
5726
5772
  {
5727
5773
  content: artifact.inlineContent || "",
@@ -5731,7 +5777,7 @@ function ArtifactModal({
5731
5777
  artifact.mimeType === "text/plain" && "whitespace-pre-wrap"
5732
5778
  )
5733
5779
  }
5734
- ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ import_react73.default.createElement(
5780
+ ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ import_react75.default.createElement(
5735
5781
  ScriptCard,
5736
5782
  {
5737
5783
  elements: artifact.scriptElements,
@@ -5749,7 +5795,7 @@ function NodeRenderer({
5749
5795
  onGroupClick
5750
5796
  }) {
5751
5797
  if (node.type === "ARTIFACT" && node.artifact) {
5752
- return /* @__PURE__ */ import_react73.default.createElement(
5798
+ return /* @__PURE__ */ import_react75.default.createElement(
5753
5799
  ArtifactCard,
5754
5800
  {
5755
5801
  artifact: node.artifact,
@@ -5759,10 +5805,10 @@ function NodeRenderer({
5759
5805
  );
5760
5806
  }
5761
5807
  if (node.type === "GROUP") {
5762
- return /* @__PURE__ */ import_react73.default.createElement(ArtifactGroup, { node, onClick: onGroupClick });
5808
+ return /* @__PURE__ */ import_react75.default.createElement(ArtifactGroup, { node, onClick: onGroupClick });
5763
5809
  }
5764
5810
  if (node.type === "VARIANT_SET") {
5765
- return /* @__PURE__ */ import_react73.default.createElement(
5811
+ return /* @__PURE__ */ import_react75.default.createElement(
5766
5812
  ArtifactVariantStack,
5767
5813
  {
5768
5814
  node,
@@ -5773,33 +5819,33 @@ function NodeRenderer({
5773
5819
  }
5774
5820
  return null;
5775
5821
  }
5776
- var ArtifactsPanel = import_react73.default.forwardRef(
5822
+ var ArtifactsPanel = import_react75.default.forwardRef(
5777
5823
  ({
5778
5824
  nodes,
5779
5825
  loading,
5780
5826
  className,
5781
5827
  ...rest
5782
5828
  }, ref) => {
5783
- const [expandedArtifact, setExpandedArtifact] = (0, import_react73.useState)(null);
5784
- const [zoomIndex, setZoomIndex] = (0, import_react73.useState)(ZOOM_LEVELS.length - 1);
5829
+ const [expandedArtifact, setExpandedArtifact] = (0, import_react75.useState)(null);
5830
+ const [zoomIndex, setZoomIndex] = (0, import_react75.useState)(ZOOM_LEVELS.length - 1);
5785
5831
  const treeNav = useArtifactTreeNavigation(nodes || []);
5786
5832
  const hasNodes = !!nodes && nodes.length > 0;
5787
- const handleExpandArtifact = (0, import_react73.useCallback)((artifact) => {
5833
+ const handleExpandArtifact = (0, import_react75.useCallback)((artifact) => {
5788
5834
  setExpandedArtifact(artifact);
5789
5835
  }, []);
5790
- const handleGroupClick = (0, import_react73.useCallback)((node) => {
5836
+ const handleGroupClick = (0, import_react75.useCallback)((node) => {
5791
5837
  treeNav.navigateInto(node);
5792
5838
  }, [treeNav]);
5793
- const zoomIn = (0, import_react73.useCallback)(() => {
5839
+ const zoomIn = (0, import_react75.useCallback)(() => {
5794
5840
  setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
5795
5841
  }, []);
5796
- const zoomOut = (0, import_react73.useCallback)(() => {
5842
+ const zoomOut = (0, import_react75.useCallback)(() => {
5797
5843
  setZoomIndex((prev) => Math.max(prev - 1, 0));
5798
5844
  }, []);
5799
5845
  const currentZoom = ZOOM_LEVELS[zoomIndex];
5800
- const contentRef = (0, import_react73.useRef)(null);
5801
- const [contentHeight, setContentHeight] = (0, import_react73.useState)(void 0);
5802
- (0, import_react73.useEffect)(() => {
5846
+ const contentRef = (0, import_react75.useRef)(null);
5847
+ const [contentHeight, setContentHeight] = (0, import_react75.useState)(void 0);
5848
+ (0, import_react75.useEffect)(() => {
5803
5849
  const el = contentRef.current;
5804
5850
  if (!el) return;
5805
5851
  const observer = new ResizeObserver(([entry]) => {
@@ -5808,7 +5854,7 @@ var ArtifactsPanel = import_react73.default.forwardRef(
5808
5854
  observer.observe(el);
5809
5855
  return () => observer.disconnect();
5810
5856
  }, []);
5811
- return /* @__PURE__ */ import_react73.default.createElement(import_react73.default.Fragment, null, /* @__PURE__ */ import_react73.default.createElement(
5857
+ return /* @__PURE__ */ import_react75.default.createElement(import_react75.default.Fragment, null, /* @__PURE__ */ import_react75.default.createElement(
5812
5858
  "div",
5813
5859
  {
5814
5860
  ref,
@@ -5819,19 +5865,19 @@ var ArtifactsPanel = import_react73.default.forwardRef(
5819
5865
  ),
5820
5866
  ...rest
5821
5867
  },
5822
- /* @__PURE__ */ import_react73.default.createElement(
5868
+ /* @__PURE__ */ import_react75.default.createElement(
5823
5869
  "div",
5824
5870
  {
5825
5871
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5826
5872
  },
5827
- /* @__PURE__ */ import_react73.default.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
5828
- hasNodes && /* @__PURE__ */ import_react73.default.createElement(
5873
+ /* @__PURE__ */ import_react75.default.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
5874
+ hasNodes && /* @__PURE__ */ import_react75.default.createElement(
5829
5875
  "div",
5830
5876
  {
5831
5877
  className: "flex items-center gap-0.5",
5832
5878
  "data-testid": "zoom-controls"
5833
5879
  },
5834
- /* @__PURE__ */ import_react73.default.createElement(
5880
+ /* @__PURE__ */ import_react75.default.createElement(
5835
5881
  "button",
5836
5882
  {
5837
5883
  onClick: zoomOut,
@@ -5845,8 +5891,8 @@ var ArtifactsPanel = import_react73.default.forwardRef(
5845
5891
  },
5846
5892
  "\u2212"
5847
5893
  ),
5848
- /* @__PURE__ */ import_react73.default.createElement("span", { className: "text-xs text-silver w-8 text-center tabular-nums", "data-testid": "zoom-level" }, Math.round(currentZoom * 100), "%"),
5849
- /* @__PURE__ */ import_react73.default.createElement(
5894
+ /* @__PURE__ */ import_react75.default.createElement("span", { className: "text-xs text-silver w-8 text-center tabular-nums", "data-testid": "zoom-level" }, Math.round(currentZoom * 100), "%"),
5895
+ /* @__PURE__ */ import_react75.default.createElement(
5850
5896
  "button",
5851
5897
  {
5852
5898
  onClick: zoomIn,
@@ -5862,7 +5908,7 @@ var ArtifactsPanel = import_react73.default.forwardRef(
5862
5908
  )
5863
5909
  )
5864
5910
  ),
5865
- hasNodes && !treeNav.isAtRoot && /* @__PURE__ */ import_react73.default.createElement(
5911
+ hasNodes && !treeNav.isAtRoot && /* @__PURE__ */ import_react75.default.createElement(
5866
5912
  "nav",
5867
5913
  {
5868
5914
  className: "flex items-center gap-1 px-4 py-2 border-b border-ash/40 shrink-0 overflow-x-auto text-xs",
@@ -5871,7 +5917,7 @@ var ArtifactsPanel = import_react73.default.forwardRef(
5871
5917
  },
5872
5918
  treeNav.breadcrumbs.map((crumb, i) => {
5873
5919
  const isLast = i === treeNav.breadcrumbs.length - 1;
5874
- return /* @__PURE__ */ import_react73.default.createElement("span", { key: i, className: "flex items-center gap-1 shrink-0" }, i > 0 && /* @__PURE__ */ import_react73.default.createElement(ChevronRightIcon, { className: "w-3 h-3 text-silver/50", "aria-hidden": true }), isLast ? /* @__PURE__ */ import_react73.default.createElement("span", { className: "text-gold font-medium" }, crumb.label) : /* @__PURE__ */ import_react73.default.createElement(
5920
+ return /* @__PURE__ */ import_react75.default.createElement("span", { key: i, className: "flex items-center gap-1 shrink-0" }, i > 0 && /* @__PURE__ */ import_react75.default.createElement(ChevronRightIcon, { className: "w-3 h-3 text-silver/50", "aria-hidden": true }), isLast ? /* @__PURE__ */ import_react75.default.createElement("span", { className: "text-gold font-medium" }, crumb.label) : /* @__PURE__ */ import_react75.default.createElement(
5875
5921
  "button",
5876
5922
  {
5877
5923
  onClick: () => treeNav.navigateTo(i),
@@ -5881,18 +5927,18 @@ var ArtifactsPanel = import_react73.default.forwardRef(
5881
5927
  ));
5882
5928
  })
5883
5929
  ),
5884
- /* @__PURE__ */ import_react73.default.createElement(
5930
+ /* @__PURE__ */ import_react75.default.createElement(
5885
5931
  "div",
5886
5932
  {
5887
5933
  className: "flex-1 overflow-auto relative",
5888
5934
  "data-testid": "artifacts-scroll-area"
5889
5935
  },
5890
- /* @__PURE__ */ import_react73.default.createElement(
5936
+ /* @__PURE__ */ import_react75.default.createElement(
5891
5937
  "div",
5892
5938
  {
5893
5939
  style: currentZoom !== 1 && contentHeight !== void 0 ? { height: contentHeight * currentZoom } : void 0
5894
5940
  },
5895
- /* @__PURE__ */ import_react73.default.createElement(
5941
+ /* @__PURE__ */ import_react75.default.createElement(
5896
5942
  "div",
5897
5943
  {
5898
5944
  ref: contentRef,
@@ -5903,7 +5949,7 @@ var ArtifactsPanel = import_react73.default.forwardRef(
5903
5949
  transformOrigin: "top center"
5904
5950
  } : void 0
5905
5951
  },
5906
- treeNav.currentNodes.length === 0 ? /* @__PURE__ */ import_react73.default.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, hasNodes ? "Empty group" : "No artifacts to display") : treeNav.currentNodes.map((node) => /* @__PURE__ */ import_react73.default.createElement(
5952
+ treeNav.currentNodes.length === 0 ? /* @__PURE__ */ import_react75.default.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, hasNodes ? "Empty group" : "No artifacts to display") : treeNav.currentNodes.map((node) => /* @__PURE__ */ import_react75.default.createElement(
5907
5953
  NodeRenderer,
5908
5954
  {
5909
5955
  key: node.id,
@@ -5916,7 +5962,7 @@ var ArtifactsPanel = import_react73.default.forwardRef(
5916
5962
  )
5917
5963
  )
5918
5964
  )
5919
- ), expandedArtifact && /* @__PURE__ */ import_react73.default.createElement(
5965
+ ), expandedArtifact && /* @__PURE__ */ import_react75.default.createElement(
5920
5966
  ArtifactModal,
5921
5967
  {
5922
5968
  artifact: expandedArtifact,
@@ -5926,8 +5972,8 @@ var ArtifactsPanel = import_react73.default.forwardRef(
5926
5972
  }
5927
5973
  );
5928
5974
  ArtifactsPanel.displayName = "ArtifactsPanel";
5929
- var ArtifactsPanelToggle = import_react73.default.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
5930
- return /* @__PURE__ */ import_react73.default.createElement(
5975
+ var ArtifactsPanelToggle = import_react75.default.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
5976
+ return /* @__PURE__ */ import_react75.default.createElement(
5931
5977
  "button",
5932
5978
  {
5933
5979
  ref,
@@ -5944,8 +5990,8 @@ var ArtifactsPanelToggle = import_react73.default.forwardRef(({ artifactCount =
5944
5990
  "aria-label": "Expand artifacts panel",
5945
5991
  ...rest
5946
5992
  },
5947
- /* @__PURE__ */ import_react73.default.createElement(import_lucide_react15.Image, { className: "w-5 h-5", "aria-hidden": true }),
5948
- artifactCount > 0 && /* @__PURE__ */ import_react73.default.createElement(
5993
+ /* @__PURE__ */ import_react75.default.createElement(import_lucide_react17.Image, { className: "w-5 h-5", "aria-hidden": true }),
5994
+ artifactCount > 0 && /* @__PURE__ */ import_react75.default.createElement(
5949
5995
  "span",
5950
5996
  {
5951
5997
  className: "absolute -top-1 -right-1 w-4 h-4 bg-gold text-obsidian text-xs font-medium flex items-center justify-center"
@@ -5957,8 +6003,8 @@ var ArtifactsPanelToggle = import_react73.default.forwardRef(({ artifactCount =
5957
6003
  ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
5958
6004
 
5959
6005
  // src/components/chat/HistoryPanel.tsx
5960
- var import_react74 = __toESM(require("react"));
5961
- var import_lucide_react16 = require("lucide-react");
6006
+ var import_react76 = __toESM(require("react"));
6007
+ var import_lucide_react18 = require("lucide-react");
5962
6008
  function parseTimestamp(ts) {
5963
6009
  if (ts == null) {
5964
6010
  return null;
@@ -6000,12 +6046,12 @@ function ProjectFilter({
6000
6046
  onChange,
6001
6047
  className
6002
6048
  }) {
6003
- const [open, setOpen] = (0, import_react74.useState)(false);
6004
- const ref = (0, import_react74.useRef)(null);
6005
- const closeFilter = (0, import_react74.useCallback)(() => setOpen(false), []);
6049
+ const [open, setOpen] = (0, import_react76.useState)(false);
6050
+ const ref = (0, import_react76.useRef)(null);
6051
+ const closeFilter = (0, import_react76.useCallback)(() => setOpen(false), []);
6006
6052
  useClickOutside(ref, closeFilter, open);
6007
6053
  const label = value ?? "All projects";
6008
- return /* @__PURE__ */ import_react74.default.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ import_react74.default.createElement(
6054
+ return /* @__PURE__ */ import_react76.default.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ import_react76.default.createElement(
6009
6055
  "button",
6010
6056
  {
6011
6057
  type: "button",
@@ -6021,9 +6067,9 @@ function ProjectFilter({
6021
6067
  "transition-colors duration-150 min-w-0"
6022
6068
  )
6023
6069
  },
6024
- /* @__PURE__ */ import_react74.default.createElement("span", { className: "truncate" }, label),
6025
- /* @__PURE__ */ import_react74.default.createElement(import_lucide_react16.ChevronDown, { className: "w-3 h-3 shrink-0", "aria-hidden": true })
6026
- ), open && /* @__PURE__ */ import_react74.default.createElement(
6070
+ /* @__PURE__ */ import_react76.default.createElement("span", { className: "truncate" }, label),
6071
+ /* @__PURE__ */ import_react76.default.createElement(import_lucide_react18.ChevronDown, { className: "w-3 h-3 shrink-0", "aria-hidden": true })
6072
+ ), open && /* @__PURE__ */ import_react76.default.createElement(
6027
6073
  "div",
6028
6074
  {
6029
6075
  role: "listbox",
@@ -6033,7 +6079,7 @@ function ProjectFilter({
6033
6079
  "max-h-60 overflow-y-auto"
6034
6080
  )
6035
6081
  },
6036
- /* @__PURE__ */ import_react74.default.createElement(
6082
+ /* @__PURE__ */ import_react76.default.createElement(
6037
6083
  "button",
6038
6084
  {
6039
6085
  type: "button",
@@ -6051,7 +6097,7 @@ function ProjectFilter({
6051
6097
  },
6052
6098
  "All projects"
6053
6099
  ),
6054
- projects.map((p) => /* @__PURE__ */ import_react74.default.createElement(
6100
+ projects.map((p) => /* @__PURE__ */ import_react76.default.createElement(
6055
6101
  "button",
6056
6102
  {
6057
6103
  key: p,
@@ -6077,33 +6123,33 @@ function ConversationRow({
6077
6123
  onSelect,
6078
6124
  onRename
6079
6125
  }) {
6080
- const [isEditing, setIsEditing] = (0, import_react74.useState)(false);
6081
- const [draft, setDraft] = (0, import_react74.useState)(conversation.title);
6082
- const inputRef = (0, import_react74.useRef)(null);
6083
- (0, import_react74.useEffect)(() => {
6126
+ const [isEditing, setIsEditing] = (0, import_react76.useState)(false);
6127
+ const [draft, setDraft] = (0, import_react76.useState)(conversation.title);
6128
+ const inputRef = (0, import_react76.useRef)(null);
6129
+ (0, import_react76.useEffect)(() => {
6084
6130
  if (isEditing && inputRef.current) {
6085
6131
  inputRef.current.focus();
6086
6132
  inputRef.current.select();
6087
6133
  }
6088
6134
  }, [isEditing]);
6089
- const startEdit = (0, import_react74.useCallback)((e) => {
6135
+ const startEdit = (0, import_react76.useCallback)((e) => {
6090
6136
  e.stopPropagation();
6091
6137
  setDraft(conversation.title);
6092
6138
  setIsEditing(true);
6093
6139
  }, [conversation.title]);
6094
- const commit = (0, import_react74.useCallback)(() => {
6140
+ const commit = (0, import_react76.useCallback)(() => {
6095
6141
  const trimmed = draft.trim();
6096
6142
  if (trimmed && trimmed !== conversation.title) {
6097
6143
  onRename?.(conversation.id, trimmed);
6098
6144
  }
6099
6145
  setIsEditing(false);
6100
6146
  }, [draft, conversation.id, conversation.title, onRename]);
6101
- const cancel = (0, import_react74.useCallback)(() => {
6147
+ const cancel = (0, import_react76.useCallback)(() => {
6102
6148
  setDraft(conversation.title);
6103
6149
  setIsEditing(false);
6104
6150
  }, [conversation.title]);
6105
6151
  if (isEditing) {
6106
- return /* @__PURE__ */ import_react74.default.createElement(
6152
+ return /* @__PURE__ */ import_react76.default.createElement(
6107
6153
  "div",
6108
6154
  {
6109
6155
  className: cx(
@@ -6111,7 +6157,7 @@ function ConversationRow({
6111
6157
  conversation.isActive ? "bg-ash/40" : "bg-ash/20"
6112
6158
  )
6113
6159
  },
6114
- /* @__PURE__ */ import_react74.default.createElement(
6160
+ /* @__PURE__ */ import_react76.default.createElement(
6115
6161
  "input",
6116
6162
  {
6117
6163
  ref: inputRef,
@@ -6136,10 +6182,10 @@ function ConversationRow({
6136
6182
  "aria-label": "Conversation title"
6137
6183
  }
6138
6184
  ),
6139
- conversation.project && /* @__PURE__ */ import_react74.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-1" }, conversation.project)
6185
+ conversation.project && /* @__PURE__ */ import_react76.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-1" }, conversation.project)
6140
6186
  );
6141
6187
  }
6142
- return /* @__PURE__ */ import_react74.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react74.default.createElement(
6188
+ return /* @__PURE__ */ import_react76.default.createElement("div", { className: "relative group" }, /* @__PURE__ */ import_react76.default.createElement(
6143
6189
  "button",
6144
6190
  {
6145
6191
  onClick: () => onSelect?.(conversation.id),
@@ -6149,7 +6195,7 @@ function ConversationRow({
6149
6195
  conversation.isActive ? "bg-ash/40 text-white" : "text-silver hover:bg-ash/20 hover:text-white"
6150
6196
  )
6151
6197
  },
6152
- /* @__PURE__ */ import_react74.default.createElement(
6198
+ /* @__PURE__ */ import_react76.default.createElement(
6153
6199
  "p",
6154
6200
  {
6155
6201
  className: cx(
@@ -6159,8 +6205,8 @@ function ConversationRow({
6159
6205
  },
6160
6206
  conversation.title
6161
6207
  ),
6162
- conversation.project && /* @__PURE__ */ import_react74.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.project)
6163
- ), onRename && /* @__PURE__ */ import_react74.default.createElement(
6208
+ conversation.project && /* @__PURE__ */ import_react76.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.project)
6209
+ ), onRename && /* @__PURE__ */ import_react76.default.createElement(
6164
6210
  "button",
6165
6211
  {
6166
6212
  type: "button",
@@ -6173,7 +6219,7 @@ function ConversationRow({
6173
6219
  "transition-opacity duration-150"
6174
6220
  )
6175
6221
  },
6176
- /* @__PURE__ */ import_react74.default.createElement(import_lucide_react16.Pencil, { className: "w-3.5 h-3.5", "aria-hidden": true })
6222
+ /* @__PURE__ */ import_react76.default.createElement(import_lucide_react18.Pencil, { className: "w-3.5 h-3.5", "aria-hidden": true })
6177
6223
  ));
6178
6224
  }
6179
6225
  function HistoryPanel({
@@ -6182,8 +6228,8 @@ function HistoryPanel({
6182
6228
  onNewChat,
6183
6229
  onRenameConversation
6184
6230
  }) {
6185
- const [projectFilter, setProjectFilter] = (0, import_react74.useState)(null);
6186
- const projects = (0, import_react74.useMemo)(() => {
6231
+ const [projectFilter, setProjectFilter] = (0, import_react76.useState)(null);
6232
+ const projects = (0, import_react76.useMemo)(() => {
6187
6233
  const set = /* @__PURE__ */ new Set();
6188
6234
  for (const c of conversations) {
6189
6235
  if (c.project) {
@@ -6192,23 +6238,23 @@ function HistoryPanel({
6192
6238
  }
6193
6239
  return Array.from(set).sort((a, b) => a.localeCompare(b));
6194
6240
  }, [conversations]);
6195
- (0, import_react74.useEffect)(() => {
6241
+ (0, import_react76.useEffect)(() => {
6196
6242
  if (projectFilter && !projects.includes(projectFilter)) {
6197
6243
  setProjectFilter(null);
6198
6244
  }
6199
6245
  }, [projects, projectFilter]);
6200
- const filteredConversations = (0, import_react74.useMemo)(() => {
6246
+ const filteredConversations = (0, import_react76.useMemo)(() => {
6201
6247
  if (!projectFilter) {
6202
6248
  return conversations;
6203
6249
  }
6204
6250
  return conversations.filter((c) => c.project === projectFilter);
6205
6251
  }, [conversations, projectFilter]);
6206
- const groups = (0, import_react74.useMemo)(
6252
+ const groups = (0, import_react76.useMemo)(
6207
6253
  () => groupConversations(filteredConversations),
6208
6254
  [filteredConversations]
6209
6255
  );
6210
6256
  const hasFilter = projects.length > 0;
6211
- return /* @__PURE__ */ import_react74.default.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ import_react74.default.createElement("div", { className: "px-4 py-3 border-b border-ash/40 shrink-0 flex items-center gap-2" }, /* @__PURE__ */ import_react74.default.createElement("h3", { className: "text-xs font-medium text-white shrink-0" }, "History"), (hasFilter || onNewChat) && /* @__PURE__ */ import_react74.default.createElement("div", { className: "flex items-center gap-2 flex-1 min-w-0" }, hasFilter && /* @__PURE__ */ import_react74.default.createElement(import_react74.default.Fragment, null, /* @__PURE__ */ import_react74.default.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ import_react74.default.createElement(
6257
+ return /* @__PURE__ */ import_react76.default.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ import_react76.default.createElement("div", { className: "px-4 py-3 border-b border-ash/40 shrink-0 flex items-center gap-2" }, /* @__PURE__ */ import_react76.default.createElement("h3", { className: "text-xs font-medium text-white shrink-0" }, "History"), (hasFilter || onNewChat) && /* @__PURE__ */ import_react76.default.createElement("div", { className: "flex items-center gap-2 flex-1 min-w-0" }, hasFilter && /* @__PURE__ */ import_react76.default.createElement(import_react76.default.Fragment, null, /* @__PURE__ */ import_react76.default.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ import_react76.default.createElement(
6212
6258
  ProjectFilter,
6213
6259
  {
6214
6260
  projects,
@@ -6216,7 +6262,7 @@ function HistoryPanel({
6216
6262
  onChange: setProjectFilter,
6217
6263
  className: "flex-1"
6218
6264
  }
6219
- )), onNewChat && /* @__PURE__ */ import_react74.default.createElement(import_react74.default.Fragment, null, /* @__PURE__ */ import_react74.default.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ import_react74.default.createElement(
6265
+ )), onNewChat && /* @__PURE__ */ import_react76.default.createElement(import_react76.default.Fragment, null, /* @__PURE__ */ import_react76.default.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ import_react76.default.createElement(
6220
6266
  "button",
6221
6267
  {
6222
6268
  onClick: onNewChat,
@@ -6228,15 +6274,15 @@ function HistoryPanel({
6228
6274
  "transition-colors duration-200"
6229
6275
  )
6230
6276
  },
6231
- /* @__PURE__ */ import_react74.default.createElement(PlusIcon, { className: "w-4 h-4" }),
6232
- /* @__PURE__ */ import_react74.default.createElement("span", { className: "truncate" }, "New Chat")
6233
- )))), /* @__PURE__ */ import_react74.default.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ import_react74.default.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations yet") : groups.length === 0 ? /* @__PURE__ */ import_react74.default.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations match this filter") : /* @__PURE__ */ import_react74.default.createElement("div", null, groups.map((group, index) => /* @__PURE__ */ import_react74.default.createElement("section", { key: group.key, className: cx(index > 0 && "mt-3") }, /* @__PURE__ */ import_react74.default.createElement("div", { className: "flex items-center gap-2 px-3 pb-2" }, /* @__PURE__ */ import_react74.default.createElement(
6277
+ /* @__PURE__ */ import_react76.default.createElement(PlusIcon, { className: "w-4 h-4" }),
6278
+ /* @__PURE__ */ import_react76.default.createElement("span", { className: "truncate" }, "New Chat")
6279
+ )))), /* @__PURE__ */ import_react76.default.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ import_react76.default.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations yet") : groups.length === 0 ? /* @__PURE__ */ import_react76.default.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations match this filter") : /* @__PURE__ */ import_react76.default.createElement("div", null, groups.map((group, index) => /* @__PURE__ */ import_react76.default.createElement("section", { key: group.key, className: cx(index > 0 && "mt-3") }, /* @__PURE__ */ import_react76.default.createElement("div", { className: "flex items-center gap-2 px-3 pb-2" }, /* @__PURE__ */ import_react76.default.createElement(
6234
6280
  "span",
6235
6281
  {
6236
6282
  className: "text-xs font-medium uppercase tracking-wider text-gold/70"
6237
6283
  },
6238
6284
  group.label
6239
- ), /* @__PURE__ */ import_react74.default.createElement("div", { className: "flex-1 h-px bg-gold/20" })), /* @__PURE__ */ import_react74.default.createElement("div", { className: "space-y-1 px-2" }, group.conversations.map((conversation) => /* @__PURE__ */ import_react74.default.createElement(
6285
+ ), /* @__PURE__ */ import_react76.default.createElement("div", { className: "flex-1 h-px bg-gold/20" })), /* @__PURE__ */ import_react76.default.createElement("div", { className: "space-y-1 px-2" }, group.conversations.map((conversation) => /* @__PURE__ */ import_react76.default.createElement(
6240
6286
  ConversationRow,
6241
6287
  {
6242
6288
  key: conversation.id,
@@ -6248,8 +6294,8 @@ function HistoryPanel({
6248
6294
  }
6249
6295
 
6250
6296
  // src/components/chat/TodosList.tsx
6251
- var import_react75 = __toESM(require("react"));
6252
- var import_lucide_react17 = require("lucide-react");
6297
+ var import_react77 = __toESM(require("react"));
6298
+ var import_lucide_react19 = require("lucide-react");
6253
6299
  var TASK_STATUSES = {
6254
6300
  PENDING: "pending",
6255
6301
  IN_PROGRESS: "in_progress",
@@ -6260,16 +6306,16 @@ var TASK_STATUSES = {
6260
6306
  function TaskIcon({ status }) {
6261
6307
  switch (status) {
6262
6308
  case "done":
6263
- return /* @__PURE__ */ import_react75.default.createElement(CheckSquareIcon, null);
6309
+ return /* @__PURE__ */ import_react77.default.createElement(CheckSquareIcon, null);
6264
6310
  case "in_progress":
6265
- return /* @__PURE__ */ import_react75.default.createElement(SquareLoaderIcon, null);
6311
+ return /* @__PURE__ */ import_react77.default.createElement(SquareLoaderIcon, null);
6266
6312
  case "cancelled":
6267
- return /* @__PURE__ */ import_react75.default.createElement(CrossSquareIcon, { variant: "cancelled" });
6313
+ return /* @__PURE__ */ import_react77.default.createElement(CrossSquareIcon, { variant: "cancelled" });
6268
6314
  case "failed":
6269
- return /* @__PURE__ */ import_react75.default.createElement(CrossSquareIcon, { variant: "failed" });
6315
+ return /* @__PURE__ */ import_react77.default.createElement(CrossSquareIcon, { variant: "failed" });
6270
6316
  case "pending":
6271
6317
  default:
6272
- return /* @__PURE__ */ import_react75.default.createElement(EmptySquareIcon, null);
6318
+ return /* @__PURE__ */ import_react77.default.createElement(EmptySquareIcon, null);
6273
6319
  }
6274
6320
  }
6275
6321
  function sortTasks(tasks) {
@@ -6289,14 +6335,14 @@ function TaskItem({ task, depth = 0 }) {
6289
6335
  const isSubtle = task.status === "cancelled" || task.status === "failed";
6290
6336
  const showSubtasks = task.subtasks && task.subtasks.length > 0;
6291
6337
  const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
6292
- return /* @__PURE__ */ import_react75.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react75.default.createElement(
6338
+ return /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react77.default.createElement(
6293
6339
  "div",
6294
6340
  {
6295
6341
  className: "flex items-center gap-2 py-1",
6296
6342
  style: { paddingLeft: `${depth * 1.5}rem` }
6297
6343
  },
6298
- /* @__PURE__ */ import_react75.default.createElement(TaskIcon, { status: task.status }),
6299
- /* @__PURE__ */ import_react75.default.createElement(
6344
+ /* @__PURE__ */ import_react77.default.createElement(TaskIcon, { status: task.status }),
6345
+ /* @__PURE__ */ import_react77.default.createElement(
6300
6346
  "span",
6301
6347
  {
6302
6348
  className: cx(
@@ -6308,10 +6354,10 @@ function TaskItem({ task, depth = 0 }) {
6308
6354
  )
6309
6355
  },
6310
6356
  task.label,
6311
- task.status === "cancelled" && /* @__PURE__ */ import_react75.default.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
6312
- task.status === "failed" && /* @__PURE__ */ import_react75.default.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
6357
+ task.status === "cancelled" && /* @__PURE__ */ import_react77.default.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
6358
+ task.status === "failed" && /* @__PURE__ */ import_react77.default.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
6313
6359
  )
6314
- ), showSubtasks && /* @__PURE__ */ import_react75.default.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ import_react75.default.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
6360
+ ), showSubtasks && /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ import_react77.default.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
6315
6361
  }
6316
6362
  function hasInProgressTask(tasks) {
6317
6363
  return tasks.some((t) => {
@@ -6324,11 +6370,11 @@ function hasInProgressTask(tasks) {
6324
6370
  return false;
6325
6371
  });
6326
6372
  }
6327
- var TodosList = import_react75.default.forwardRef(
6373
+ var TodosList = import_react77.default.forwardRef(
6328
6374
  ({ tasks, title = "Tasks", onStopAllTasks, className, ...rest }, ref) => {
6329
- const sortedTasks = (0, import_react75.useMemo)(() => sortTasks(tasks), [tasks]);
6330
- const [isStopping, setIsStopping] = (0, import_react75.useState)(false);
6331
- const handleStopClick = (0, import_react75.useCallback)(async () => {
6375
+ const sortedTasks = (0, import_react77.useMemo)(() => sortTasks(tasks), [tasks]);
6376
+ const [isStopping, setIsStopping] = (0, import_react77.useState)(false);
6377
+ const handleStopClick = (0, import_react77.useCallback)(async () => {
6332
6378
  if (!onStopAllTasks || isStopping) {
6333
6379
  return;
6334
6380
  }
@@ -6349,7 +6395,7 @@ var TodosList = import_react75.default.forwardRef(
6349
6395
  if (tasks.length === 0) {
6350
6396
  return null;
6351
6397
  }
6352
- return /* @__PURE__ */ import_react75.default.createElement(
6398
+ return /* @__PURE__ */ import_react77.default.createElement(
6353
6399
  "div",
6354
6400
  {
6355
6401
  ref,
@@ -6360,16 +6406,16 @@ var TodosList = import_react75.default.forwardRef(
6360
6406
  ),
6361
6407
  ...rest
6362
6408
  },
6363
- /* @__PURE__ */ import_react75.default.createElement(
6409
+ /* @__PURE__ */ import_react77.default.createElement(
6364
6410
  "div",
6365
6411
  {
6366
6412
  className: "flex items-center justify-between px-4 py-2 border-b border-ash/40 flex-shrink-0"
6367
6413
  },
6368
- /* @__PURE__ */ import_react75.default.createElement("h4", { className: "text-xs font-medium text-white" }, title),
6369
- /* @__PURE__ */ import_react75.default.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
6414
+ /* @__PURE__ */ import_react77.default.createElement("h4", { className: "text-xs font-medium text-white" }, title),
6415
+ /* @__PURE__ */ import_react77.default.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
6370
6416
  ),
6371
- /* @__PURE__ */ import_react75.default.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ import_react75.default.createElement(TaskItem, { key: task.id, task }))),
6372
- showStopButton && /* @__PURE__ */ import_react75.default.createElement("div", { className: "px-4 py-2 border-t border-ash/40 flex-shrink-0" }, /* @__PURE__ */ import_react75.default.createElement(
6417
+ /* @__PURE__ */ import_react77.default.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ import_react77.default.createElement(TaskItem, { key: task.id, task }))),
6418
+ showStopButton && /* @__PURE__ */ import_react77.default.createElement("div", { className: "px-4 py-2 border-t border-ash/40 flex-shrink-0" }, /* @__PURE__ */ import_react77.default.createElement(
6373
6419
  "button",
6374
6420
  {
6375
6421
  type: "button",
@@ -6386,7 +6432,7 @@ var TodosList = import_react75.default.forwardRef(
6386
6432
  isStopping ? "cursor-not-allowed opacity-70" : "hover:bg-error/20"
6387
6433
  )
6388
6434
  },
6389
- isStopping ? /* @__PURE__ */ import_react75.default.createElement(import_react75.default.Fragment, null, /* @__PURE__ */ import_react75.default.createElement(import_lucide_react17.Loader2, { className: "w-3 h-3 animate-spin" }), "Stopping tasks") : /* @__PURE__ */ import_react75.default.createElement(import_react75.default.Fragment, null, /* @__PURE__ */ import_react75.default.createElement(import_lucide_react17.Square, { className: "w-3 h-3 fill-current" }), "Stop All Tasks")
6435
+ isStopping ? /* @__PURE__ */ import_react77.default.createElement(import_react77.default.Fragment, null, /* @__PURE__ */ import_react77.default.createElement(import_lucide_react19.Loader2, { className: "w-3 h-3 animate-spin" }), "Stopping tasks") : /* @__PURE__ */ import_react77.default.createElement(import_react77.default.Fragment, null, /* @__PURE__ */ import_react77.default.createElement(import_lucide_react19.Square, { className: "w-3 h-3 fill-current" }), "Stop All Tasks")
6390
6436
  ))
6391
6437
  );
6392
6438
  }
@@ -6406,8 +6452,8 @@ function areAllTasksSettled(tasks) {
6406
6452
  }
6407
6453
 
6408
6454
  // src/components/chat/ToolSidebar.tsx
6409
- var import_react76 = __toESM(require("react"));
6410
- var ToolSidebar = import_react76.default.forwardRef(
6455
+ var import_react78 = __toESM(require("react"));
6456
+ var ToolSidebar = import_react78.default.forwardRef(
6411
6457
  ({ tools, activeTools, onToggleTool, side, className, ...rest }, ref) => {
6412
6458
  const topTools = tools.filter((t) => t.group === `top-${side}`);
6413
6459
  const bottomTools = tools.filter((t) => t.group === `bottom-${side}`);
@@ -6418,7 +6464,7 @@ var ToolSidebar = import_react76.default.forwardRef(
6418
6464
  };
6419
6465
  const renderButton = (tool) => {
6420
6466
  const active = isActive(tool.id);
6421
- return /* @__PURE__ */ import_react76.default.createElement(
6467
+ return /* @__PURE__ */ import_react78.default.createElement(
6422
6468
  "button",
6423
6469
  {
6424
6470
  key: tool.id,
@@ -6430,10 +6476,10 @@ var ToolSidebar = import_react76.default.forwardRef(
6430
6476
  "aria-label": tool.label,
6431
6477
  "aria-pressed": active
6432
6478
  },
6433
- /* @__PURE__ */ import_react76.default.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
6479
+ /* @__PURE__ */ import_react78.default.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
6434
6480
  );
6435
6481
  };
6436
- return /* @__PURE__ */ import_react76.default.createElement(
6482
+ return /* @__PURE__ */ import_react78.default.createElement(
6437
6483
  "div",
6438
6484
  {
6439
6485
  ref,
@@ -6444,17 +6490,17 @@ var ToolSidebar = import_react76.default.forwardRef(
6444
6490
  ),
6445
6491
  ...rest
6446
6492
  },
6447
- /* @__PURE__ */ import_react76.default.createElement("div", { className: "flex flex-col items-center gap-1" }, topTools.map(renderButton)),
6448
- /* @__PURE__ */ import_react76.default.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ import_react76.default.createElement("div", { className: "w-5 border-t border-ash/30" })),
6449
- /* @__PURE__ */ import_react76.default.createElement("div", { className: "flex flex-col items-center gap-1" }, bottomTools.map(renderButton))
6493
+ /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex flex-col items-center gap-1" }, topTools.map(renderButton)),
6494
+ /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ import_react78.default.createElement("div", { className: "w-5 border-t border-ash/30" })),
6495
+ /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex flex-col items-center gap-1" }, bottomTools.map(renderButton))
6450
6496
  );
6451
6497
  }
6452
6498
  );
6453
6499
  ToolSidebar.displayName = "ToolSidebar";
6454
6500
 
6455
6501
  // src/components/chat/ToolPanelContainer.tsx
6456
- var import_react77 = __toESM(require("react"));
6457
- var ToolPanelContainer = import_react77.default.forwardRef(
6502
+ var import_react79 = __toESM(require("react"));
6503
+ var ToolPanelContainer = import_react79.default.forwardRef(
6458
6504
  ({
6459
6505
  topContent,
6460
6506
  bottomContent,
@@ -6465,21 +6511,21 @@ var ToolPanelContainer = import_react77.default.forwardRef(
6465
6511
  initialTopPercent = 60,
6466
6512
  ...rest
6467
6513
  }, ref) => {
6468
- const [topPercent, setTopPercent] = (0, import_react77.useState)(initialTopPercent);
6469
- const [isResizingHeight, setIsResizingHeight] = (0, import_react77.useState)(false);
6470
- const containerRef = (0, import_react77.useRef)(null);
6471
- const lastY = (0, import_react77.useRef)(null);
6514
+ const [topPercent, setTopPercent] = (0, import_react79.useState)(initialTopPercent);
6515
+ const [isResizingHeight, setIsResizingHeight] = (0, import_react79.useState)(false);
6516
+ const containerRef = (0, import_react79.useRef)(null);
6517
+ const lastY = (0, import_react79.useRef)(null);
6472
6518
  const hasBoth = topContent !== null && bottomContent !== null;
6473
- const startHeightResize = (0, import_react77.useCallback)((e) => {
6519
+ const startHeightResize = (0, import_react79.useCallback)((e) => {
6474
6520
  e.preventDefault();
6475
6521
  setIsResizingHeight(true);
6476
6522
  lastY.current = e.clientY;
6477
6523
  }, []);
6478
- const stopHeightResize = (0, import_react77.useCallback)(() => {
6524
+ const stopHeightResize = (0, import_react79.useCallback)(() => {
6479
6525
  setIsResizingHeight(false);
6480
6526
  lastY.current = null;
6481
6527
  }, []);
6482
- const resizeHeight = (0, import_react77.useCallback)(
6528
+ const resizeHeight = (0, import_react79.useCallback)(
6483
6529
  (e) => {
6484
6530
  if (!isResizingHeight || lastY.current === null || !containerRef.current) {
6485
6531
  return;
@@ -6498,7 +6544,7 @@ var ToolPanelContainer = import_react77.default.forwardRef(
6498
6544
  },
6499
6545
  [isResizingHeight]
6500
6546
  );
6501
- (0, import_react77.useEffect)(() => {
6547
+ (0, import_react79.useEffect)(() => {
6502
6548
  if (isResizingHeight) {
6503
6549
  window.addEventListener("mousemove", resizeHeight);
6504
6550
  window.addEventListener("mouseup", stopHeightResize);
@@ -6517,7 +6563,7 @@ var ToolPanelContainer = import_react77.default.forwardRef(
6517
6563
  document.body.style.userSelect = "";
6518
6564
  };
6519
6565
  }, [isResizingHeight, resizeHeight, stopHeightResize]);
6520
- return /* @__PURE__ */ import_react77.default.createElement(
6566
+ return /* @__PURE__ */ import_react79.default.createElement(
6521
6567
  "div",
6522
6568
  {
6523
6569
  ref: composeRefs(containerRef, ref),
@@ -6529,7 +6575,7 @@ var ToolPanelContainer = import_react77.default.forwardRef(
6529
6575
  style: width ? { width } : void 0,
6530
6576
  ...rest
6531
6577
  },
6532
- /* @__PURE__ */ import_react77.default.createElement(
6578
+ /* @__PURE__ */ import_react79.default.createElement(
6533
6579
  "div",
6534
6580
  {
6535
6581
  onMouseDown: onResizeStart,
@@ -6540,7 +6586,7 @@ var ToolPanelContainer = import_react77.default.forwardRef(
6540
6586
  )
6541
6587
  }
6542
6588
  ),
6543
- topContent !== null && /* @__PURE__ */ import_react77.default.createElement(
6589
+ topContent !== null && /* @__PURE__ */ import_react79.default.createElement(
6544
6590
  "div",
6545
6591
  {
6546
6592
  className: "min-h-0 overflow-hidden flex flex-col",
@@ -6548,7 +6594,7 @@ var ToolPanelContainer = import_react77.default.forwardRef(
6548
6594
  },
6549
6595
  topContent
6550
6596
  ),
6551
- hasBoth && /* @__PURE__ */ import_react77.default.createElement(
6597
+ hasBoth && /* @__PURE__ */ import_react79.default.createElement(
6552
6598
  "div",
6553
6599
  {
6554
6600
  onMouseDown: startHeightResize,
@@ -6560,7 +6606,7 @@ var ToolPanelContainer = import_react77.default.forwardRef(
6560
6606
  )
6561
6607
  }
6562
6608
  ),
6563
- bottomContent !== null && /* @__PURE__ */ import_react77.default.createElement(
6609
+ bottomContent !== null && /* @__PURE__ */ import_react79.default.createElement(
6564
6610
  "div",
6565
6611
  {
6566
6612
  className: "min-h-0 overflow-hidden flex flex-col",
@@ -6574,26 +6620,26 @@ var ToolPanelContainer = import_react77.default.forwardRef(
6574
6620
  ToolPanelContainer.displayName = "ToolPanelContainer";
6575
6621
 
6576
6622
  // src/components/chat/hooks/useResizable.ts
6577
- var import_react78 = require("react");
6623
+ var import_react80 = require("react");
6578
6624
  function useResizable({
6579
6625
  initialWidthPercent,
6580
6626
  minWidthPercent,
6581
6627
  maxWidthPercent,
6582
6628
  direction
6583
6629
  }) {
6584
- const [widthPercent, setWidthPercent] = (0, import_react78.useState)(initialWidthPercent);
6585
- const [isResizing, setIsResizing] = (0, import_react78.useState)(false);
6586
- const lastX = (0, import_react78.useRef)(null);
6587
- const startResizing = (0, import_react78.useCallback)((e) => {
6630
+ const [widthPercent, setWidthPercent] = (0, import_react80.useState)(initialWidthPercent);
6631
+ const [isResizing, setIsResizing] = (0, import_react80.useState)(false);
6632
+ const lastX = (0, import_react80.useRef)(null);
6633
+ const startResizing = (0, import_react80.useCallback)((e) => {
6588
6634
  e.preventDefault();
6589
6635
  setIsResizing(true);
6590
6636
  lastX.current = e.clientX;
6591
6637
  }, []);
6592
- const stopResizing = (0, import_react78.useCallback)(() => {
6638
+ const stopResizing = (0, import_react80.useCallback)(() => {
6593
6639
  setIsResizing(false);
6594
6640
  lastX.current = null;
6595
6641
  }, []);
6596
- const resize = (0, import_react78.useCallback)(
6642
+ const resize = (0, import_react80.useCallback)(
6597
6643
  (e) => {
6598
6644
  if (!isResizing || lastX.current === null) {
6599
6645
  return;
@@ -6609,7 +6655,7 @@ function useResizable({
6609
6655
  },
6610
6656
  [isResizing, direction, minWidthPercent, maxWidthPercent]
6611
6657
  );
6612
- (0, import_react78.useEffect)(() => {
6658
+ (0, import_react80.useEffect)(() => {
6613
6659
  if (isResizing) {
6614
6660
  window.addEventListener("mousemove", resize);
6615
6661
  window.addEventListener("mouseup", stopResizing);
@@ -6632,8 +6678,150 @@ function useResizable({
6632
6678
  return { width, widthPercent, isResizing, startResizing };
6633
6679
  }
6634
6680
 
6681
+ // src/components/chat/tree.ts
6682
+ function createEmptyTree() {
6683
+ return { nodes: {}, rootIds: [], activeLeafId: null, lastLeafId: null };
6684
+ }
6685
+ function addNodeToTree(tree, node, parentId = null) {
6686
+ const newNodes = { ...tree.nodes };
6687
+ const newRootIds = [...tree.rootIds];
6688
+ const branchIndex = parentId ? newNodes[parentId]?.children.length ?? 0 : newRootIds.length;
6689
+ newNodes[node.id] = {
6690
+ ...node,
6691
+ parentId,
6692
+ children: [],
6693
+ branchIndex,
6694
+ createdAt: node.createdAt ?? Date.now()
6695
+ };
6696
+ if (parentId && newNodes[parentId]) {
6697
+ newNodes[parentId] = {
6698
+ ...newNodes[parentId],
6699
+ children: [...newNodes[parentId].children, node.id]
6700
+ };
6701
+ } else {
6702
+ newRootIds.push(node.id);
6703
+ }
6704
+ return {
6705
+ nodes: newNodes,
6706
+ rootIds: newRootIds,
6707
+ activeLeafId: node.id,
6708
+ lastLeafId: node.id
6709
+ };
6710
+ }
6711
+ function getActivePath(tree) {
6712
+ return walkUp(tree, tree.activeLeafId).reverse();
6713
+ }
6714
+ function findAncestor(tree, fromId, predicate) {
6715
+ let id = fromId;
6716
+ while (id) {
6717
+ const node = tree.nodes[id];
6718
+ if (!node) return null;
6719
+ if (predicate(node)) return node;
6720
+ id = node.parentId;
6721
+ }
6722
+ return null;
6723
+ }
6724
+ function getSiblingInfo(tree, nodeId) {
6725
+ const siblings = siblingsOf(tree, nodeId);
6726
+ const index = siblings.indexOf(nodeId);
6727
+ if (index < 0) return { total: 1, current: 1 };
6728
+ return { total: siblings.length, current: index + 1 };
6729
+ }
6730
+ function isBranchPoint(tree, nodeId) {
6731
+ return (tree.nodes[nodeId]?.children.length ?? 0) > 1;
6732
+ }
6733
+ function switchBranch(tree, nodeId, direction) {
6734
+ const siblings = siblingsOf(tree, nodeId);
6735
+ if (siblings.length <= 1) return tree;
6736
+ const currentIndex = siblings.indexOf(nodeId);
6737
+ const newIndex = direction === "next" ? (currentIndex + 1) % siblings.length : (currentIndex - 1 + siblings.length) % siblings.length;
6738
+ const leafId = deepestLeafOf(tree, siblings[newIndex]);
6739
+ return { ...tree, activeLeafId: leafId, lastLeafId: leafId };
6740
+ }
6741
+ function setActiveLeaf(tree, leafId) {
6742
+ if (!leafId || !tree.nodes[leafId]) {
6743
+ return { ...tree, activeLeafId: leafId, lastLeafId: leafId };
6744
+ }
6745
+ const lastLeafId = tree.lastLeafId && isAncestor(tree, leafId, tree.lastLeafId) ? tree.lastLeafId : leafId;
6746
+ return { ...tree, activeLeafId: leafId, lastLeafId };
6747
+ }
6748
+ function getGreyedFuture(tree) {
6749
+ const { activeLeafId, lastLeafId } = tree;
6750
+ if (!activeLeafId || !lastLeafId || activeLeafId === lastLeafId) return [];
6751
+ const path = [];
6752
+ let id = lastLeafId;
6753
+ while (id && id !== activeLeafId) {
6754
+ const node = tree.nodes[id];
6755
+ if (!node) return [];
6756
+ path.unshift(node);
6757
+ id = node.parentId;
6758
+ }
6759
+ return id === activeLeafId ? path : [];
6760
+ }
6761
+ function messagesToTree(messages) {
6762
+ let tree = createEmptyTree();
6763
+ for (const msg of messages) {
6764
+ const parentId = tree.activeLeafId;
6765
+ tree = addNodeToTree(
6766
+ tree,
6767
+ { ...msg, kind: "message", parentId },
6768
+ parentId
6769
+ );
6770
+ }
6771
+ return tree;
6772
+ }
6773
+ function updateMessageContent(tree, nodeId, content, isStreaming) {
6774
+ const node = tree.nodes[nodeId];
6775
+ if (!node || node.kind !== "message") return tree;
6776
+ const updated = {
6777
+ ...node,
6778
+ content,
6779
+ isStreaming: isStreaming ?? node.isStreaming
6780
+ };
6781
+ return {
6782
+ ...tree,
6783
+ nodes: {
6784
+ ...tree.nodes,
6785
+ [nodeId]: updated
6786
+ }
6787
+ };
6788
+ }
6789
+ function walkUp(tree, fromId) {
6790
+ const out = [];
6791
+ let id = fromId;
6792
+ while (id) {
6793
+ const node = tree.nodes[id];
6794
+ if (!node) break;
6795
+ out.push(node);
6796
+ id = node.parentId;
6797
+ }
6798
+ return out;
6799
+ }
6800
+ function siblingsOf(tree, nodeId) {
6801
+ const node = tree.nodes[nodeId];
6802
+ if (!node) return [];
6803
+ return node.parentId ? tree.nodes[node.parentId]?.children ?? [] : tree.rootIds;
6804
+ }
6805
+ function deepestLeafOf(tree, nodeId) {
6806
+ let id = nodeId;
6807
+ let node = tree.nodes[id];
6808
+ while (node && node.children.length > 0) {
6809
+ id = node.children[node.children.length - 1];
6810
+ node = tree.nodes[id];
6811
+ }
6812
+ return id;
6813
+ }
6814
+ function isAncestor(tree, ancestorId, descendantId) {
6815
+ let id = descendantId;
6816
+ while (id) {
6817
+ if (id === ancestorId) return true;
6818
+ id = tree.nodes[id]?.parentId ?? null;
6819
+ }
6820
+ return false;
6821
+ }
6822
+
6635
6823
  // src/components/chat/ChatInterface.tsx
6636
- var ChatInterface = import_react79.default.forwardRef(
6824
+ var ChatInterface = import_react81.default.forwardRef(
6637
6825
  ({
6638
6826
  messages = [],
6639
6827
  conversationTree,
@@ -6642,6 +6830,8 @@ var ChatInterface = import_react79.default.forwardRef(
6642
6830
  onMessageSubmit,
6643
6831
  onEditMessage,
6644
6832
  onRetryMessage,
6833
+ onJumpToCheckpoint,
6834
+ onJumpToLatest,
6645
6835
  onStop,
6646
6836
  onSelectConversation,
6647
6837
  onNewChat,
@@ -6670,17 +6860,17 @@ var ChatInterface = import_react79.default.forwardRef(
6670
6860
  className,
6671
6861
  ...rest
6672
6862
  }, ref) => {
6673
- const prevArtifactNodesRef = (0, import_react79.useRef)([]);
6674
- const prevTasksRef = (0, import_react79.useRef)([]);
6675
- const [internalTools, setInternalTools] = (0, import_react79.useState)({
6863
+ const prevArtifactNodesRef = (0, import_react81.useRef)([]);
6864
+ const prevTasksRef = (0, import_react81.useRef)([]);
6865
+ const [internalTools, setInternalTools] = (0, import_react81.useState)({
6676
6866
  "top-left": "history",
6677
6867
  "bottom-left": null,
6678
6868
  "top-right": null,
6679
6869
  "bottom-right": null
6680
6870
  });
6681
- const dismissedToolsRef = (0, import_react79.useRef)(/* @__PURE__ */ new Set());
6871
+ const dismissedToolsRef = (0, import_react81.useRef)(/* @__PURE__ */ new Set());
6682
6872
  const isPanelControlled = isArtifactsPanelOpen !== void 0;
6683
- const activeTools = (0, import_react79.useMemo)(() => {
6873
+ const activeTools = (0, import_react81.useMemo)(() => {
6684
6874
  if (isPanelControlled) {
6685
6875
  return {
6686
6876
  ...internalTools,
@@ -6710,13 +6900,13 @@ var ChatInterface = import_react79.default.forwardRef(
6710
6900
  direction: "right"
6711
6901
  });
6712
6902
  const allSettled = tasks.length === 0 || areAllTasksSettled(tasks);
6713
- const allToolDefinitions = (0, import_react79.useMemo)(() => {
6903
+ const allToolDefinitions = (0, import_react81.useMemo)(() => {
6714
6904
  const builtIn = [
6715
- { id: "history", icon: /* @__PURE__ */ import_react79.default.createElement(ChatBubbleIcon, null), label: "History", group: "top-left" },
6716
- { id: "artifacts", icon: /* @__PURE__ */ import_react79.default.createElement(MediaIcon, null), label: "Artifacts", group: "top-right" },
6905
+ { id: "history", icon: /* @__PURE__ */ import_react81.default.createElement(ChatBubbleIcon, null), label: "History", group: "top-left" },
6906
+ { id: "artifacts", icon: /* @__PURE__ */ import_react81.default.createElement(MediaIcon, null), label: "Artifacts", group: "top-right" },
6717
6907
  {
6718
6908
  id: "todos",
6719
- icon: allSettled ? /* @__PURE__ */ import_react79.default.createElement(CheckSquareIcon, null) : /* @__PURE__ */ import_react79.default.createElement(SquareLoaderIcon, null),
6909
+ icon: allSettled ? /* @__PURE__ */ import_react81.default.createElement(CheckSquareIcon, null) : /* @__PURE__ */ import_react81.default.createElement(SquareLoaderIcon, null),
6720
6910
  label: "Tasks",
6721
6911
  group: "bottom-right"
6722
6912
  }
@@ -6724,7 +6914,7 @@ var ChatInterface = import_react79.default.forwardRef(
6724
6914
  const external = externalTools.map(({ content: _content, ...def }) => def);
6725
6915
  return [...builtIn, ...external];
6726
6916
  }, [allSettled, externalTools]);
6727
- const toggleTool = (0, import_react79.useCallback)((toolId) => {
6917
+ const toggleTool = (0, import_react81.useCallback)((toolId) => {
6728
6918
  const toolDef = allToolDefinitions.find((t) => t.id === toolId);
6729
6919
  if (!toolDef) {
6730
6920
  return;
@@ -6754,21 +6944,25 @@ var ChatInterface = import_react79.default.forwardRef(
6754
6944
  });
6755
6945
  }, [allToolDefinitions, isPanelControlled, activeTools, onArtifactsPanelOpenChange]);
6756
6946
  const isTreeMode = !!conversationTree;
6757
- const effectiveMessages = (0, import_react79.useMemo)(() => {
6758
- if (isTreeMode && conversationTree) {
6759
- return getActivePathMessages(conversationTree);
6760
- }
6761
- return messages || [];
6762
- }, [isTreeMode, conversationTree, messages]);
6763
- const latestUserMessageIndex = (0, import_react79.useMemo)(() => {
6764
- for (let i = effectiveMessages.length - 1; i >= 0; i--) {
6765
- if (effectiveMessages[i].role === "user") {
6766
- return i;
6767
- }
6768
- }
6769
- return -1;
6770
- }, [effectiveMessages]);
6771
- (0, import_react79.useEffect)(() => {
6947
+ const tree = isTreeMode ? conversationTree : null;
6948
+ const activePath = (0, import_react81.useMemo)(() => {
6949
+ if (tree) return getActivePath(tree);
6950
+ return (messages || []).map((m) => ({ ...m, children: [], branchIndex: 0 }));
6951
+ }, [tree, messages]);
6952
+ const greyedFuture = (0, import_react81.useMemo)(
6953
+ () => tree ? getGreyedFuture(tree) : [],
6954
+ [tree]
6955
+ );
6956
+ const activeCheckpointId = (0, import_react81.useMemo)(() => {
6957
+ if (!tree) return null;
6958
+ const found = findAncestor(
6959
+ tree,
6960
+ tree.activeLeafId,
6961
+ (n) => n.kind === "checkpoint"
6962
+ );
6963
+ return found?.id ?? null;
6964
+ }, [tree]);
6965
+ (0, import_react81.useEffect)(() => {
6772
6966
  const nodes = artifactNodes || [];
6773
6967
  const prevNodes = prevArtifactNodesRef.current;
6774
6968
  const hasNewOrChangedNode = nodes.length !== prevNodes.length || nodes.some((n, i) => n.id !== prevNodes[i]?.id);
@@ -6793,71 +6987,120 @@ var ChatInterface = import_react79.default.forwardRef(
6793
6987
  prevArtifactNodesRef.current = nodes;
6794
6988
  prevTasksRef.current = tasks;
6795
6989
  }, [artifactNodes, tasks, isPanelControlled]);
6796
- const handleBranchSwitch = (0, import_react79.useCallback)(
6990
+ const handleBranchSwitch = (0, import_react81.useCallback)(
6797
6991
  (nodeId, direction) => {
6798
- if (!isTreeMode || !conversationTree || !onTreeChange) {
6992
+ if (!tree || !onTreeChange) {
6799
6993
  return;
6800
6994
  }
6801
- const newTree = switchBranch(conversationTree, nodeId, direction);
6802
- onTreeChange(newTree);
6995
+ onTreeChange(switchBranch(tree, nodeId, direction));
6803
6996
  },
6804
- [isTreeMode, conversationTree, onTreeChange]
6997
+ [tree, onTreeChange]
6805
6998
  );
6806
- const displayMessages = (0, import_react79.useMemo)(() => {
6807
- return effectiveMessages.map((msg) => {
6808
- let branchInfo = void 0;
6809
- if (isTreeMode && conversationTree) {
6810
- const siblingInfo = getSiblingInfo(conversationTree, msg.id);
6811
- if (siblingInfo.total > 1) {
6812
- branchInfo = {
6813
- current: siblingInfo.current,
6814
- total: siblingInfo.total,
6815
- onPrevious: () => handleBranchSwitch(msg.id, "prev"),
6816
- onNext: () => handleBranchSwitch(msg.id, "next")
6817
- };
6818
- }
6999
+ const handleJumpToCheckpoint = (0, import_react81.useCallback)((checkpointId) => {
7000
+ if (!tree) return;
7001
+ if (onJumpToCheckpoint) {
7002
+ onJumpToCheckpoint(checkpointId);
7003
+ return;
7004
+ }
7005
+ if (onTreeChange) {
7006
+ onTreeChange(setActiveLeaf(tree, checkpointId));
7007
+ }
7008
+ }, [tree, onTreeChange, onJumpToCheckpoint]);
7009
+ const handleJumpToLatest = (0, import_react81.useCallback)(() => {
7010
+ if (!tree) return;
7011
+ if (onJumpToLatest) {
7012
+ onJumpToLatest();
7013
+ return;
7014
+ }
7015
+ if (onTreeChange && tree.lastLeafId) {
7016
+ onTreeChange(setActiveLeaf(tree, tree.lastLeafId));
7017
+ }
7018
+ }, [tree, onTreeChange, onJumpToLatest]);
7019
+ const buildItem = (0, import_react81.useCallback)(
7020
+ (node, opts) => {
7021
+ const branchInfo = tree && getSiblingInfo(tree, node.id).total > 1 ? {
7022
+ ...getSiblingInfo(tree, node.id),
7023
+ onPrevious: () => handleBranchSwitch(node.id, "prev"),
7024
+ onNext: () => handleBranchSwitch(node.id, "next")
7025
+ } : void 0;
7026
+ if (node.kind === "checkpoint") {
7027
+ return {
7028
+ kind: "checkpoint",
7029
+ id: node.id,
7030
+ name: node.name,
7031
+ executionKind: node.executionKind,
7032
+ status: node.status,
7033
+ isActive: node.id === activeCheckpointId && !opts.muted,
7034
+ muted: opts.muted,
7035
+ branchInfo,
7036
+ onJumpHere: () => handleJumpToCheckpoint(node.id)
7037
+ };
6819
7038
  }
6820
7039
  const actions = enableMessageActions ? {
6821
7040
  showCopy: true,
6822
- onEdit: msg.role === "user" && onEditMessage ? (newContent) => onEditMessage(msg.id, newContent) : void 0,
6823
- onRetry: msg.role === "assistant" && onRetryMessage ? () => onRetryMessage(msg.id) : void 0
7041
+ onEdit: node.role === "user" && onEditMessage ? (newContent) => onEditMessage(node.id, newContent) : void 0,
7042
+ onRetry: node.role === "assistant" && onRetryMessage ? () => onRetryMessage(node.id) : void 0
6824
7043
  } : void 0;
6825
- const {
6826
- role,
6827
- parentId,
6828
- children,
6829
- branchIndex,
6830
- createdAt,
6831
- ...rest2
6832
- } = msg;
6833
7044
  return {
6834
- ...rest2,
6835
- variant: role,
7045
+ kind: "message",
7046
+ id: node.id,
7047
+ variant: node.role,
7048
+ content: node.content,
7049
+ isStreaming: node.isStreaming,
7050
+ muted: opts.muted,
6836
7051
  branchInfo,
6837
7052
  actions
6838
7053
  };
6839
- });
6840
- }, [
6841
- effectiveMessages,
6842
- isTreeMode,
6843
- conversationTree,
6844
- enableMessageActions,
6845
- onEditMessage,
6846
- onRetryMessage,
6847
- handleBranchSwitch
6848
- ]);
6849
- const handleSubmit = (0, import_react79.useCallback)(
7054
+ },
7055
+ [
7056
+ tree,
7057
+ activeCheckpointId,
7058
+ enableMessageActions,
7059
+ onEditMessage,
7060
+ onRetryMessage,
7061
+ handleBranchSwitch,
7062
+ handleJumpToCheckpoint
7063
+ ]
7064
+ );
7065
+ const displayItems = (0, import_react81.useMemo)(() => {
7066
+ const items = activePath.map((n) => buildItem(n, { muted: false }));
7067
+ if (greyedFuture.length > 0) {
7068
+ const messageCount = greyedFuture.filter((n) => n.kind === "message").length;
7069
+ const checkpointCount = greyedFuture.filter((n) => n.kind === "checkpoint").length;
7070
+ items.push({
7071
+ kind: "divider",
7072
+ id: "__greyed_divider__",
7073
+ messageCount,
7074
+ checkpointCount,
7075
+ onJumpToLatest: handleJumpToLatest
7076
+ });
7077
+ for (const n of greyedFuture) {
7078
+ items.push(buildItem(n, { muted: true }));
7079
+ }
7080
+ }
7081
+ return items;
7082
+ }, [activePath, greyedFuture, buildItem, handleJumpToLatest]);
7083
+ const latestUserMessageIndex = (0, import_react81.useMemo)(() => {
7084
+ for (let i = displayItems.length - 1; i >= 0; i--) {
7085
+ const item = displayItems[i];
7086
+ if (item.kind === "message" && item.variant === "user" && !item.muted) {
7087
+ return i;
7088
+ }
7089
+ }
7090
+ return -1;
7091
+ }, [displayItems]);
7092
+ const handleSubmit = (0, import_react81.useCallback)(
6850
7093
  (message, attachments) => {
6851
7094
  onMessageSubmit?.(message, attachments);
6852
7095
  },
6853
7096
  [onMessageSubmit]
6854
7097
  );
6855
- const isEmpty = effectiveMessages.length === 0;
6856
- const leftToolDefs = (0, import_react79.useMemo)(
7098
+ const isEmpty = displayItems.length === 0;
7099
+ const leftToolDefs = (0, import_react81.useMemo)(
6857
7100
  () => allToolDefinitions.filter((t) => t.group === "top-left" || t.group === "bottom-left"),
6858
7101
  [allToolDefinitions]
6859
7102
  );
6860
- const rightToolDefs = (0, import_react79.useMemo)(
7103
+ const rightToolDefs = (0, import_react81.useMemo)(
6861
7104
  () => allToolDefinitions.filter(
6862
7105
  (t) => t.group === "top-right" || t.group === "bottom-right"
6863
7106
  ),
@@ -6871,7 +7114,7 @@ var ChatInterface = import_react79.default.forwardRef(
6871
7114
  }
6872
7115
  switch (toolId) {
6873
7116
  case "history":
6874
- return /* @__PURE__ */ import_react79.default.createElement(
7117
+ return /* @__PURE__ */ import_react81.default.createElement(
6875
7118
  HistoryPanel,
6876
7119
  {
6877
7120
  conversations,
@@ -6881,7 +7124,7 @@ var ChatInterface = import_react79.default.forwardRef(
6881
7124
  }
6882
7125
  );
6883
7126
  case "artifacts":
6884
- return /* @__PURE__ */ import_react79.default.createElement(
7127
+ return /* @__PURE__ */ import_react81.default.createElement(
6885
7128
  ArtifactsPanel,
6886
7129
  {
6887
7130
  nodes: artifactNodes,
@@ -6889,7 +7132,7 @@ var ChatInterface = import_react79.default.forwardRef(
6889
7132
  }
6890
7133
  );
6891
7134
  case "todos":
6892
- return tasks.length > 0 ? /* @__PURE__ */ import_react79.default.createElement(
7135
+ return tasks.length > 0 ? /* @__PURE__ */ import_react81.default.createElement(
6893
7136
  TodosList,
6894
7137
  {
6895
7138
  tasks,
@@ -6897,21 +7140,21 @@ var ChatInterface = import_react79.default.forwardRef(
6897
7140
  onStopAllTasks,
6898
7141
  className: "h-full"
6899
7142
  }
6900
- ) : /* @__PURE__ */ import_react79.default.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex items-center p-4 border-b border-ash/40 shrink-0" }, /* @__PURE__ */ import_react79.default.createElement("h3", { className: "text-xs font-medium text-white" }, "Tasks")), /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ import_react79.default.createElement("p", { className: "text-xs text-silver/60" }, "No tasks")));
7143
+ ) : /* @__PURE__ */ import_react81.default.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ import_react81.default.createElement("div", { className: "flex items-center p-4 border-b border-ash/40 shrink-0" }, /* @__PURE__ */ import_react81.default.createElement("h3", { className: "text-xs font-medium text-white" }, "Tasks")), /* @__PURE__ */ import_react81.default.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ import_react81.default.createElement("p", { className: "text-xs text-silver/60" }, "No tasks")));
6901
7144
  default: {
6902
7145
  const externalTool = externalTools.find((t) => t.id === toolId);
6903
7146
  return externalTool?.content ?? null;
6904
7147
  }
6905
7148
  }
6906
7149
  };
6907
- return /* @__PURE__ */ import_react79.default.createElement(
7150
+ return /* @__PURE__ */ import_react81.default.createElement(
6908
7151
  "div",
6909
7152
  {
6910
7153
  ref,
6911
7154
  className: cx("flex h-full w-full bg-obsidian overflow-hidden", className),
6912
7155
  ...rest
6913
7156
  },
6914
- hasLeftTools && /* @__PURE__ */ import_react79.default.createElement(
7157
+ hasLeftTools && /* @__PURE__ */ import_react81.default.createElement(
6915
7158
  ToolSidebar,
6916
7159
  {
6917
7160
  tools: leftToolDefs,
@@ -6920,7 +7163,7 @@ var ChatInterface = import_react79.default.forwardRef(
6920
7163
  side: "left"
6921
7164
  }
6922
7165
  ),
6923
- isLeftPanelOpen && /* @__PURE__ */ import_react79.default.createElement(
7166
+ isLeftPanelOpen && /* @__PURE__ */ import_react81.default.createElement(
6924
7167
  ToolPanelContainer,
6925
7168
  {
6926
7169
  topContent: renderToolContent(activeTools["top-left"]),
@@ -6931,28 +7174,28 @@ var ChatInterface = import_react79.default.forwardRef(
6931
7174
  initialTopPercent: 30
6932
7175
  }
6933
7176
  ),
6934
- /* @__PURE__ */ import_react79.default.createElement("div", { className: "flex-1 flex flex-col min-w-0 relative" }, /* @__PURE__ */ import_react79.default.createElement("div", { className: cx(
7177
+ /* @__PURE__ */ import_react81.default.createElement("div", { className: "flex-1 flex flex-col min-w-0 relative" }, /* @__PURE__ */ import_react81.default.createElement("div", { className: cx(
6935
7178
  "flex-1 flex flex-col min-h-0 relative",
6936
7179
  isEmpty ? "justify-center" : "justify-start"
6937
- ) }, /* @__PURE__ */ import_react79.default.createElement("div", { className: cx(
7180
+ ) }, /* @__PURE__ */ import_react81.default.createElement("div", { className: cx(
6938
7181
  "transition-all duration-500 ease-in-out",
6939
7182
  isEmpty ? "flex-1" : "flex-zero"
6940
- ) }), /* @__PURE__ */ import_react79.default.createElement("div", { className: cx(
7183
+ ) }), /* @__PURE__ */ import_react81.default.createElement("div", { className: cx(
6941
7184
  "transition-all duration-500 ease-in-out overflow-hidden flex flex-col",
6942
7185
  isEmpty ? "flex-zero opacity-0" : "flex-1 opacity-100"
6943
- ) }, /* @__PURE__ */ import_react79.default.createElement(
7186
+ ) }, /* @__PURE__ */ import_react81.default.createElement(
6944
7187
  ChatView,
6945
7188
  {
6946
- messages: displayMessages,
7189
+ items: displayItems,
6947
7190
  latestUserMessageIndex,
6948
7191
  isStreaming,
6949
7192
  isThinking,
6950
7193
  className: "flex-1"
6951
7194
  }
6952
- )), /* @__PURE__ */ import_react79.default.createElement("div", { className: cx(
7195
+ )), /* @__PURE__ */ import_react81.default.createElement("div", { className: cx(
6953
7196
  "transition-all duration-500 ease-in-out z-10 w-full flex flex-col items-center",
6954
7197
  isEmpty ? "p-4" : "shrink-0 p-4 border-t border-ash/40 bg-obsidian"
6955
- ) }, isEmpty && /* @__PURE__ */ import_react79.default.createElement("div", { className: "mb-8 text-center animate-fade-in duration-500" }, emptyState ? emptyState : /* @__PURE__ */ import_react79.default.createElement("h1", { className: "text-4xl md:text-5xl font-heading text-gold mb-2 tracking-tight" }, "Welcome!")), /* @__PURE__ */ import_react79.default.createElement(
7198
+ ) }, isEmpty && /* @__PURE__ */ import_react81.default.createElement("div", { className: "mb-8 text-center animate-fade-in duration-500" }, emptyState ? emptyState : /* @__PURE__ */ import_react81.default.createElement("h1", { className: "text-4xl md:text-5xl font-heading text-gold mb-2 tracking-tight" }, "Welcome!")), /* @__PURE__ */ import_react81.default.createElement(
6956
7199
  ChatInput,
6957
7200
  {
6958
7201
  position: isEmpty ? "centered" : "bottom",
@@ -6971,11 +7214,11 @@ var ChatInterface = import_react79.default.forwardRef(
6971
7214
  initialInputValue,
6972
7215
  autoFocus
6973
7216
  }
6974
- )), /* @__PURE__ */ import_react79.default.createElement("div", { className: cx(
7217
+ )), /* @__PURE__ */ import_react81.default.createElement("div", { className: cx(
6975
7218
  "transition-all duration-500 ease-in-out",
6976
7219
  isEmpty ? "flex-1" : "flex-zero"
6977
7220
  ) }))),
6978
- isRightPanelOpen && /* @__PURE__ */ import_react79.default.createElement(
7221
+ isRightPanelOpen && /* @__PURE__ */ import_react81.default.createElement(
6979
7222
  ToolPanelContainer,
6980
7223
  {
6981
7224
  topContent: renderToolContent(activeTools["top-right"]),
@@ -6986,7 +7229,7 @@ var ChatInterface = import_react79.default.forwardRef(
6986
7229
  initialTopPercent: 70
6987
7230
  }
6988
7231
  ),
6989
- hasRightTools && /* @__PURE__ */ import_react79.default.createElement(
7232
+ hasRightTools && /* @__PURE__ */ import_react81.default.createElement(
6990
7233
  ToolSidebar,
6991
7234
  {
6992
7235
  tools: rightToolDefs,
@@ -7001,9 +7244,9 @@ var ChatInterface = import_react79.default.forwardRef(
7001
7244
  ChatInterface.displayName = "ChatInterface";
7002
7245
 
7003
7246
  // src/components/chat/MessageActions.tsx
7004
- var import_react80 = __toESM(require("react"));
7005
- var import_lucide_react18 = require("lucide-react");
7006
- var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ import_react80.default.createElement(
7247
+ var import_react82 = __toESM(require("react"));
7248
+ var import_lucide_react20 = require("lucide-react");
7249
+ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ import_react82.default.createElement(
7007
7250
  "button",
7008
7251
  {
7009
7252
  type: "button",
@@ -7019,7 +7262,7 @@ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @_
7019
7262
  },
7020
7263
  children
7021
7264
  );
7022
- var MessageActions = import_react80.default.forwardRef(
7265
+ var MessageActions = import_react82.default.forwardRef(
7023
7266
  ({
7024
7267
  variant,
7025
7268
  content,
@@ -7031,12 +7274,12 @@ var MessageActions = import_react80.default.forwardRef(
7031
7274
  className,
7032
7275
  ...rest
7033
7276
  }, ref) => {
7034
- const [localIsEditing, setLocalIsEditing] = (0, import_react80.useState)(false);
7035
- const [localEditValue, setLocalEditValue] = (0, import_react80.useState)(content);
7277
+ const [localIsEditing, setLocalIsEditing] = (0, import_react82.useState)(false);
7278
+ const [localEditValue, setLocalEditValue] = (0, import_react82.useState)(content);
7036
7279
  const { copied, copy } = useCopyToClipboard();
7037
7280
  const isEditing = controlledIsEditing ?? localIsEditing;
7038
7281
  const editValue = controlledEditValue ?? localEditValue;
7039
- const setIsEditing = (0, import_react80.useCallback)(
7282
+ const setIsEditing = (0, import_react82.useCallback)(
7040
7283
  (value) => {
7041
7284
  if (onEditingChange) {
7042
7285
  onEditingChange(value);
@@ -7046,28 +7289,28 @@ var MessageActions = import_react80.default.forwardRef(
7046
7289
  },
7047
7290
  [onEditingChange]
7048
7291
  );
7049
- const setEditValue = (0, import_react80.useCallback)((value) => {
7292
+ const setEditValue = (0, import_react82.useCallback)((value) => {
7050
7293
  setLocalEditValue(value);
7051
7294
  }, []);
7052
- const handleCopy = (0, import_react80.useCallback)(() => {
7295
+ const handleCopy = (0, import_react82.useCallback)(() => {
7053
7296
  void copy(content);
7054
7297
  }, [copy, content]);
7055
- const handleStartEdit = (0, import_react80.useCallback)(() => {
7298
+ const handleStartEdit = (0, import_react82.useCallback)(() => {
7056
7299
  setLocalEditValue(content);
7057
7300
  setIsEditing(true);
7058
7301
  }, [content, setIsEditing]);
7059
- const handleCancelEdit = (0, import_react80.useCallback)(() => {
7302
+ const handleCancelEdit = (0, import_react82.useCallback)(() => {
7060
7303
  setIsEditing(false);
7061
7304
  setLocalEditValue(content);
7062
7305
  }, [content, setIsEditing]);
7063
- const handleSubmitEdit = (0, import_react80.useCallback)(() => {
7306
+ const handleSubmitEdit = (0, import_react82.useCallback)(() => {
7064
7307
  const trimmed = editValue.trim();
7065
7308
  if (trimmed && trimmed !== content) {
7066
7309
  onEdit?.(trimmed);
7067
7310
  }
7068
7311
  setIsEditing(false);
7069
7312
  }, [editValue, content, onEdit, setIsEditing]);
7070
- const handleEditKeyDown = (0, import_react80.useCallback)(
7313
+ const handleEditKeyDown = (0, import_react82.useCallback)(
7071
7314
  (e) => {
7072
7315
  if (e.key === "Enter" && !e.shiftKey) {
7073
7316
  e.preventDefault();
@@ -7080,19 +7323,19 @@ var MessageActions = import_react80.default.forwardRef(
7080
7323
  );
7081
7324
  const isUser = variant === "user";
7082
7325
  if (isUser && isEditing) {
7083
- return /* @__PURE__ */ import_react80.default.createElement(
7326
+ return /* @__PURE__ */ import_react82.default.createElement(
7084
7327
  "div",
7085
7328
  {
7086
7329
  ref,
7087
7330
  className: cx("mt-2", className),
7088
7331
  ...rest
7089
7332
  },
7090
- /* @__PURE__ */ import_react80.default.createElement(
7333
+ /* @__PURE__ */ import_react82.default.createElement(
7091
7334
  "div",
7092
7335
  {
7093
7336
  className: "relative bg-charcoal border border-ash/60 focus-within:border-gold/60 focus-within:ring-1 focus-within:ring-gold/20"
7094
7337
  },
7095
- /* @__PURE__ */ import_react80.default.createElement(
7338
+ /* @__PURE__ */ import_react82.default.createElement(
7096
7339
  "textarea",
7097
7340
  {
7098
7341
  value: editValue,
@@ -7103,15 +7346,15 @@ var MessageActions = import_react80.default.forwardRef(
7103
7346
  rows: 2
7104
7347
  }
7105
7348
  ),
7106
- /* @__PURE__ */ import_react80.default.createElement("div", { className: "absolute right-2 bottom-2 flex gap-1" }, /* @__PURE__ */ import_react80.default.createElement(
7349
+ /* @__PURE__ */ import_react82.default.createElement("div", { className: "absolute right-2 bottom-2 flex gap-1" }, /* @__PURE__ */ import_react82.default.createElement(
7107
7350
  ActionButton2,
7108
7351
  {
7109
7352
  onClick: handleCancelEdit,
7110
7353
  label: "Cancel edit",
7111
7354
  className: "text-silver/60 hover:text-error"
7112
7355
  },
7113
- /* @__PURE__ */ import_react80.default.createElement(import_lucide_react18.X, { className: "w-4 h-4" })
7114
- ), /* @__PURE__ */ import_react80.default.createElement(
7356
+ /* @__PURE__ */ import_react82.default.createElement(import_lucide_react20.X, { className: "w-4 h-4" })
7357
+ ), /* @__PURE__ */ import_react82.default.createElement(
7115
7358
  ActionButton2,
7116
7359
  {
7117
7360
  onClick: handleSubmitEdit,
@@ -7119,13 +7362,13 @@ var MessageActions = import_react80.default.forwardRef(
7119
7362
  className: "text-silver/60 hover:text-gold",
7120
7363
  disabled: !editValue.trim() || editValue.trim() === content
7121
7364
  },
7122
- /* @__PURE__ */ import_react80.default.createElement(import_lucide_react18.Send, { className: "w-4 h-4" })
7365
+ /* @__PURE__ */ import_react82.default.createElement(import_lucide_react20.Send, { className: "w-4 h-4" })
7123
7366
  ))
7124
7367
  ),
7125
- /* @__PURE__ */ import_react80.default.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
7368
+ /* @__PURE__ */ import_react82.default.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
7126
7369
  );
7127
7370
  }
7128
- return /* @__PURE__ */ import_react80.default.createElement(
7371
+ return /* @__PURE__ */ import_react82.default.createElement(
7129
7372
  "div",
7130
7373
  {
7131
7374
  ref,
@@ -7136,18 +7379,18 @@ var MessageActions = import_react80.default.forwardRef(
7136
7379
  ),
7137
7380
  ...rest
7138
7381
  },
7139
- /* @__PURE__ */ import_react80.default.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ import_react80.default.createElement(import_lucide_react18.Check, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ import_react80.default.createElement(import_lucide_react18.Copy, { className: "w-3.5 h-3.5" })),
7140
- isUser && onEdit && /* @__PURE__ */ import_react80.default.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ import_react80.default.createElement(import_lucide_react18.Pencil, { className: "w-3.5 h-3.5" })),
7141
- !isUser && onRetry && /* @__PURE__ */ import_react80.default.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ import_react80.default.createElement(import_lucide_react18.RotateCcw, { className: "w-3.5 h-3.5" }))
7382
+ /* @__PURE__ */ import_react82.default.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ import_react82.default.createElement(import_lucide_react20.Check, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ import_react82.default.createElement(import_lucide_react20.Copy, { className: "w-3.5 h-3.5" })),
7383
+ isUser && onEdit && /* @__PURE__ */ import_react82.default.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ import_react82.default.createElement(import_lucide_react20.Pencil, { className: "w-3.5 h-3.5" })),
7384
+ !isUser && onRetry && /* @__PURE__ */ import_react82.default.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ import_react82.default.createElement(import_lucide_react20.RotateCcw, { className: "w-3.5 h-3.5" }))
7142
7385
  );
7143
7386
  }
7144
7387
  );
7145
7388
  MessageActions.displayName = "MessageActions";
7146
7389
 
7147
7390
  // src/components/chat/BranchNavigator.tsx
7148
- var import_react81 = __toESM(require("react"));
7149
- var import_lucide_react19 = require("lucide-react");
7150
- var BranchNavigator = import_react81.default.forwardRef(
7391
+ var import_react83 = __toESM(require("react"));
7392
+ var import_lucide_react21 = require("lucide-react");
7393
+ var BranchNavigator = import_react83.default.forwardRef(
7151
7394
  ({
7152
7395
  current,
7153
7396
  total,
@@ -7166,7 +7409,7 @@ var BranchNavigator = import_react81.default.forwardRef(
7166
7409
  const buttonSize = size === "sm" ? "p-0.5" : "p-1";
7167
7410
  const iconSize = size === "sm" ? "w-3 h-3" : "w-4 h-4";
7168
7411
  const textSize = size === "sm" ? "text-xs" : "text-sm";
7169
- return /* @__PURE__ */ import_react81.default.createElement(
7412
+ return /* @__PURE__ */ import_react83.default.createElement(
7170
7413
  "div",
7171
7414
  {
7172
7415
  ref,
@@ -7178,8 +7421,8 @@ var BranchNavigator = import_react81.default.forwardRef(
7178
7421
  "aria-label": "Branch navigation",
7179
7422
  ...rest
7180
7423
  },
7181
- showIcon && /* @__PURE__ */ import_react81.default.createElement(import_lucide_react19.GitBranch, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
7182
- /* @__PURE__ */ import_react81.default.createElement(
7424
+ showIcon && /* @__PURE__ */ import_react83.default.createElement(import_lucide_react21.GitBranch, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
7425
+ /* @__PURE__ */ import_react83.default.createElement(
7183
7426
  "button",
7184
7427
  {
7185
7428
  type: "button",
@@ -7192,10 +7435,10 @@ var BranchNavigator = import_react81.default.forwardRef(
7192
7435
  ),
7193
7436
  "aria-label": "Previous branch"
7194
7437
  },
7195
- /* @__PURE__ */ import_react81.default.createElement(import_lucide_react19.ChevronLeft, { className: iconSize })
7438
+ /* @__PURE__ */ import_react83.default.createElement(import_lucide_react21.ChevronLeft, { className: iconSize })
7196
7439
  ),
7197
- /* @__PURE__ */ import_react81.default.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
7198
- /* @__PURE__ */ import_react81.default.createElement(
7440
+ /* @__PURE__ */ import_react83.default.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
7441
+ /* @__PURE__ */ import_react83.default.createElement(
7199
7442
  "button",
7200
7443
  {
7201
7444
  type: "button",
@@ -7208,7 +7451,7 @@ var BranchNavigator = import_react81.default.forwardRef(
7208
7451
  ),
7209
7452
  "aria-label": "Next branch"
7210
7453
  },
7211
- /* @__PURE__ */ import_react81.default.createElement(import_lucide_react19.ChevronRight, { className: iconSize })
7454
+ /* @__PURE__ */ import_react83.default.createElement(import_lucide_react21.ChevronRight, { className: iconSize })
7212
7455
  )
7213
7456
  );
7214
7457
  }
@@ -7216,16 +7459,16 @@ var BranchNavigator = import_react81.default.forwardRef(
7216
7459
  BranchNavigator.displayName = "BranchNavigator";
7217
7460
 
7218
7461
  // src/components/BrandIcon.tsx
7219
- var import_react82 = __toESM(require("react"));
7462
+ var import_react84 = __toESM(require("react"));
7220
7463
  var sizeMap2 = {
7221
7464
  sm: "h-8 w-8 text-sm",
7222
7465
  md: "h-12 w-12 text-base",
7223
7466
  lg: "h-16 w-16 text-lg"
7224
7467
  };
7225
- var BrandIcon = import_react82.default.forwardRef(
7468
+ var BrandIcon = import_react84.default.forwardRef(
7226
7469
  ({ size = "md", variant = "solid", children, className, ...rest }, ref) => {
7227
7470
  const variantClasses = variant === "solid" ? "bg-gold text-obsidian border-2 border-gold" : "bg-transparent text-gold border-2 border-gold";
7228
- return /* @__PURE__ */ import_react82.default.createElement(
7471
+ return /* @__PURE__ */ import_react84.default.createElement(
7229
7472
  "div",
7230
7473
  {
7231
7474
  ref,
@@ -7244,17 +7487,17 @@ var BrandIcon = import_react82.default.forwardRef(
7244
7487
  BrandIcon.displayName = "BrandIcon";
7245
7488
 
7246
7489
  // src/components/ColorSwatch.tsx
7247
- var import_react83 = __toESM(require("react"));
7248
- var ColorSwatch = import_react83.default.forwardRef(
7490
+ var import_react85 = __toESM(require("react"));
7491
+ var ColorSwatch = import_react85.default.forwardRef(
7249
7492
  ({ color, label, className, ...rest }, ref) => {
7250
- return /* @__PURE__ */ import_react83.default.createElement(
7493
+ return /* @__PURE__ */ import_react85.default.createElement(
7251
7494
  "div",
7252
7495
  {
7253
7496
  ref,
7254
7497
  className: cx("flex flex-col items-center gap-2", className),
7255
7498
  ...rest
7256
7499
  },
7257
- /* @__PURE__ */ import_react83.default.createElement(
7500
+ /* @__PURE__ */ import_react85.default.createElement(
7258
7501
  "div",
7259
7502
  {
7260
7503
  className: "h-16 w-16 border-2 border-ash rounded-none shadow-sm",
@@ -7262,22 +7505,22 @@ var ColorSwatch = import_react83.default.forwardRef(
7262
7505
  "aria-label": label || color
7263
7506
  }
7264
7507
  ),
7265
- label && /* @__PURE__ */ import_react83.default.createElement("span", { className: "text-xs text-silver font-medium" }, label)
7508
+ label && /* @__PURE__ */ import_react85.default.createElement("span", { className: "text-xs text-silver font-medium" }, label)
7266
7509
  );
7267
7510
  }
7268
7511
  );
7269
7512
  ColorSwatch.displayName = "ColorSwatch";
7270
7513
 
7271
7514
  // src/components/SectionHeading.tsx
7272
- var import_react84 = __toESM(require("react"));
7515
+ var import_react86 = __toESM(require("react"));
7273
7516
  var levelStyles = {
7274
7517
  h2: "text-2xl mb-4",
7275
7518
  h3: "text-xl mb-3"
7276
7519
  };
7277
- var SectionHeading = import_react84.default.forwardRef(
7520
+ var SectionHeading = import_react86.default.forwardRef(
7278
7521
  ({ level = "h2", children, className, ...rest }, ref) => {
7279
7522
  const Component = level;
7280
- return /* @__PURE__ */ import_react84.default.createElement(
7523
+ return /* @__PURE__ */ import_react86.default.createElement(
7281
7524
  Component,
7282
7525
  {
7283
7526
  ref,
@@ -7334,6 +7577,7 @@ var version = "2.0.0";
7334
7577
  ChatView,
7335
7578
  CheckSquareIcon,
7336
7579
  Checkbox,
7580
+ Checkpoint,
7337
7581
  ChevronLeftIcon,
7338
7582
  ChevronRightIcon,
7339
7583
  CloseIcon,
@@ -7347,6 +7591,7 @@ var version = "2.0.0";
7347
7591
  EmptySquareIcon,
7348
7592
  ExpandIcon,
7349
7593
  FileChip,
7594
+ GreyedDivider,
7350
7595
  HelperText,
7351
7596
  HistoryIcon,
7352
7597
  HistoryPanel,
@@ -7424,16 +7669,22 @@ var version = "2.0.0";
7424
7669
  ToolSidebar,
7425
7670
  Tooltip,
7426
7671
  VideoCard,
7427
- addMessageToTree,
7672
+ addNodeToTree,
7428
7673
  areAllTasksSettled,
7429
7674
  createEmptyTree,
7675
+ createPreviewUrl,
7676
+ findAncestor,
7430
7677
  generateId,
7431
- getActivePathMessages,
7678
+ getActivePath,
7679
+ getGreyedFuture,
7432
7680
  getSiblingInfo,
7433
7681
  isBranchPoint,
7682
+ isImageFile,
7434
7683
  messagesToTree,
7684
+ revokePreviewUrl,
7685
+ setActiveLeaf,
7435
7686
  switchBranch,
7436
- updateNodeContent,
7687
+ updateMessageContent,
7437
7688
  useArtifactTreeNavigation,
7438
7689
  useResizable,
7439
7690
  useScrollAnchor,