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