@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.mjs CHANGED
@@ -3712,12 +3712,14 @@ import { Check as Check3, ChevronLeft as ChevronLeft2, ChevronRight as ChevronRi
3712
3712
  import React54, { useMemo } from "react";
3713
3713
  import DOMPurify from "dompurify";
3714
3714
  import { marked } from "marked";
3715
- DOMPurify.addHook("afterSanitizeAttributes", (node) => {
3716
- if (node.tagName === "A") {
3717
- node.setAttribute("target", "_blank");
3718
- node.setAttribute("rel", "noopener noreferrer");
3719
- }
3720
- });
3715
+ if (typeof window !== "undefined" && typeof DOMPurify.addHook === "function") {
3716
+ DOMPurify.addHook("afterSanitizeAttributes", (node) => {
3717
+ if (node.tagName === "A") {
3718
+ node.setAttribute("target", "_blank");
3719
+ node.setAttribute("rel", "noopener noreferrer");
3720
+ }
3721
+ });
3722
+ }
3721
3723
  var DEFAULT_SANITIZE_CONFIG = {
3722
3724
  ALLOWED_TAGS: [
3723
3725
  "h1",
@@ -3794,6 +3796,9 @@ function injectStreamingCursor(html, cursorClassName) {
3794
3796
  CURSOR_BASE_CLASSES,
3795
3797
  cursorClassName
3796
3798
  )}" aria-hidden="true"></span>`;
3799
+ if (typeof DOMParser === "undefined") {
3800
+ return html + cursorHtml;
3801
+ }
3797
3802
  const parser = new DOMParser();
3798
3803
  const doc = parser.parseFromString(`<div>${html}</div>`, "text/html");
3799
3804
  const container = doc.body.firstChild;
@@ -3830,7 +3835,7 @@ var MarkdownContent = React54.forwardRef(
3830
3835
  } else {
3831
3836
  htmlContent = content;
3832
3837
  }
3833
- const sanitized = htmlContent ? DOMPurify.sanitize(htmlContent, config) : "";
3838
+ const sanitized = htmlContent && typeof DOMPurify.sanitize === "function" ? DOMPurify.sanitize(htmlContent, config) : htmlContent || "";
3834
3839
  if (isStreaming) {
3835
3840
  return injectStreamingCursor(sanitized, cursorClassName);
3836
3841
  }
@@ -4062,10 +4067,10 @@ var StreamingCursor = React56.forwardRef(
4062
4067
  StreamingCursor.displayName = "StreamingCursor";
4063
4068
 
4064
4069
  // src/components/chat/ChatInterface.tsx
4065
- import React74, { useCallback as useCallback22, useEffect as useEffect16, useMemo as useMemo5, useRef as useRef15, useState as useState22 } from "react";
4070
+ import React76, { useCallback as useCallback22, useEffect as useEffect16, useMemo as useMemo5, useRef as useRef15, useState as useState22 } from "react";
4066
4071
 
4067
4072
  // src/components/chat/ChatView.tsx
4068
- import React58, { useEffect as useEffect9 } from "react";
4073
+ import React60, { useEffect as useEffect9 } from "react";
4069
4074
 
4070
4075
  // src/components/chat/hooks/useScrollAnchor.ts
4071
4076
  import { useCallback as useCallback13, useRef as useRef7 } from "react";
@@ -4280,9 +4285,177 @@ var ThinkingIndicator = React57.forwardRef(
4280
4285
  );
4281
4286
  ThinkingIndicator.displayName = "ThinkingIndicator";
4282
4287
 
4288
+ // src/components/chat/Checkpoint.tsx
4289
+ import React58 from "react";
4290
+ import {
4291
+ ArrowLeft,
4292
+ ChevronLeft as ChevronLeft3,
4293
+ ChevronRight as ChevronRight4,
4294
+ GitBranch as GitBranch2,
4295
+ GitCommitVertical,
4296
+ GitMerge,
4297
+ PencilLine
4298
+ } from "lucide-react";
4299
+ var KIND_ICONS = {
4300
+ task: GitBranch2,
4301
+ submit: GitMerge,
4302
+ rename: PencilLine,
4303
+ init: GitCommitVertical
4304
+ };
4305
+ var KIND_ARIA_LABELS = {
4306
+ task: "Task checkpoint",
4307
+ submit: "Submit checkpoint",
4308
+ rename: "Rename checkpoint",
4309
+ init: "Project head checkpoint"
4310
+ };
4311
+ var Checkpoint = React58.forwardRef(
4312
+ function Checkpoint2({ name, executionKind, status = "completed", isActive, muted, branchInfo, onJumpHere }, ref) {
4313
+ const KindIcon = KIND_ICONS[executionKind];
4314
+ const isFailed = status === "failed";
4315
+ const isCancelled = status === "cancelled";
4316
+ const isInteractive = !isActive && !!onJumpHere;
4317
+ const iconColor = isActive ? "text-gold" : isFailed ? "text-error-muted" : "text-silver/50";
4318
+ const nameClasses = cx(
4319
+ "transition-colors text-xs",
4320
+ 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"
4321
+ );
4322
+ return /* @__PURE__ */ React58.createElement(
4323
+ "div",
4324
+ {
4325
+ ref,
4326
+ role: "group",
4327
+ "aria-label": KIND_ARIA_LABELS[executionKind],
4328
+ className: cx(
4329
+ "group/checkpoint flex items-center gap-2 py-1.5 select-none",
4330
+ muted && "opacity-60"
4331
+ )
4332
+ },
4333
+ /* @__PURE__ */ React58.createElement(KindIcon, { className: cx("w-3.5 h-3.5 shrink-0", iconColor), "aria-hidden": "true" }),
4334
+ /* @__PURE__ */ React58.createElement(
4335
+ "button",
4336
+ {
4337
+ type: "button",
4338
+ onClick: isInteractive ? onJumpHere : void 0,
4339
+ disabled: !isInteractive,
4340
+ className: cx(
4341
+ nameClasses,
4342
+ "truncate text-left",
4343
+ !isInteractive && "cursor-default"
4344
+ ),
4345
+ "aria-label": isInteractive ? `Jump to checkpoint ${name}` : name
4346
+ },
4347
+ /* @__PURE__ */ React58.createElement("span", { className: "truncate" }, name),
4348
+ isFailed && /* @__PURE__ */ React58.createElement("span", { className: "ml-1.5 text-error-muted" }, "\xB7 failed"),
4349
+ isCancelled && /* @__PURE__ */ React58.createElement("span", { className: "ml-1.5 text-silver/40" }, "\xB7 cancelled")
4350
+ ),
4351
+ isInteractive && /* @__PURE__ */ React58.createElement(
4352
+ "span",
4353
+ {
4354
+ className: cx(
4355
+ "ml-1 inline-flex items-center gap-1 text-xs text-silver/40",
4356
+ "opacity-0 group-hover/checkpoint:opacity-100 transition-opacity",
4357
+ "pointer-events-none"
4358
+ ),
4359
+ "aria-hidden": "true"
4360
+ },
4361
+ /* @__PURE__ */ React58.createElement(ArrowLeft, { className: "w-3 h-3" }),
4362
+ "Jump here"
4363
+ ),
4364
+ branchInfo && branchInfo.total > 1 && /* @__PURE__ */ React58.createElement(
4365
+ "div",
4366
+ {
4367
+ className: "ml-auto inline-flex items-center gap-0.5 text-silver/70 text-xs",
4368
+ role: "navigation",
4369
+ "aria-label": "Switch sibling checkpoint"
4370
+ },
4371
+ /* @__PURE__ */ React58.createElement(
4372
+ "button",
4373
+ {
4374
+ type: "button",
4375
+ onClick: branchInfo.onPrevious,
4376
+ disabled: branchInfo.current <= 1,
4377
+ className: cx(
4378
+ "p-0.5 hover:text-white hover:bg-white/10 transition-colors",
4379
+ "disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
4380
+ ),
4381
+ "aria-label": "Previous sibling checkpoint"
4382
+ },
4383
+ /* @__PURE__ */ React58.createElement(ChevronLeft3, { className: "w-3 h-3" })
4384
+ ),
4385
+ /* @__PURE__ */ React58.createElement("span", { className: "tabular-nums min-w-6 text-center" }, branchInfo.current, "/", branchInfo.total),
4386
+ /* @__PURE__ */ React58.createElement(
4387
+ "button",
4388
+ {
4389
+ type: "button",
4390
+ onClick: branchInfo.onNext,
4391
+ disabled: branchInfo.current >= branchInfo.total,
4392
+ className: cx(
4393
+ "p-0.5 hover:text-white hover:bg-white/10 transition-colors",
4394
+ "disabled:opacity-30 disabled:cursor-not-allowed disabled:hover:bg-transparent disabled:hover:text-silver/70"
4395
+ ),
4396
+ "aria-label": "Next sibling checkpoint"
4397
+ },
4398
+ /* @__PURE__ */ React58.createElement(ChevronRight4, { className: "w-3 h-3" })
4399
+ )
4400
+ )
4401
+ );
4402
+ }
4403
+ );
4404
+ Checkpoint.displayName = "Checkpoint";
4405
+
4406
+ // src/components/chat/GreyedDivider.tsx
4407
+ import React59 from "react";
4408
+ import { ArrowDown } from "lucide-react";
4409
+ function pluralize(n, singular, plural) {
4410
+ return `${n} ${n === 1 ? singular : plural}`;
4411
+ }
4412
+ function summarize(messageCount, checkpointCount) {
4413
+ const parts = [];
4414
+ if (messageCount > 0) {
4415
+ parts.push(pluralize(messageCount, "message", "messages"));
4416
+ }
4417
+ if (checkpointCount > 0) {
4418
+ parts.push(pluralize(checkpointCount, "checkpoint", "checkpoints"));
4419
+ }
4420
+ return parts.length > 0 ? parts.join(", ") : "no items";
4421
+ }
4422
+ var GreyedDivider = React59.forwardRef(
4423
+ function GreyedDivider2({ messageCount, checkpointCount, onJumpToLatest }, ref) {
4424
+ if (messageCount === 0 && checkpointCount === 0) {
4425
+ return null;
4426
+ }
4427
+ return /* @__PURE__ */ React59.createElement(
4428
+ "div",
4429
+ {
4430
+ ref,
4431
+ role: "separator",
4432
+ "aria-label": "Start of rewound timeline",
4433
+ className: "flex items-center gap-3 py-2 text-xs text-silver/50 select-none"
4434
+ },
4435
+ /* @__PURE__ */ React59.createElement("div", { className: "flex-1 h-px bg-ash/40", "aria-hidden": "true" }),
4436
+ /* @__PURE__ */ React59.createElement("span", { className: "inline-flex items-center gap-1.5 whitespace-nowrap" }, /* @__PURE__ */ React59.createElement(ArrowDown, { className: "w-3 h-3", "aria-hidden": "true" }), "Later in this conversation \xB7 ", summarize(messageCount, checkpointCount)),
4437
+ /* @__PURE__ */ React59.createElement("div", { className: "flex-1 h-px bg-ash/40", "aria-hidden": "true" }),
4438
+ onJumpToLatest && /* @__PURE__ */ React59.createElement(
4439
+ "button",
4440
+ {
4441
+ type: "button",
4442
+ onClick: onJumpToLatest,
4443
+ className: cx(
4444
+ "shrink-0 transition-colors",
4445
+ "text-silver/60 hover:text-white",
4446
+ "underline decoration-silver/30 underline-offset-4 decoration-dotted hover:decoration-silver/70"
4447
+ )
4448
+ },
4449
+ "Jump to latest \u2192"
4450
+ )
4451
+ );
4452
+ }
4453
+ );
4454
+ GreyedDivider.displayName = "GreyedDivider";
4455
+
4283
4456
  // src/components/chat/ChatView.tsx
4284
- var ChatView = React58.forwardRef(
4285
- ({ messages, latestUserMessageIndex, isStreaming, isThinking, onScroll, className, ...rest }, ref) => {
4457
+ var ChatView = React60.forwardRef(
4458
+ function ChatView2({ items, latestUserMessageIndex, isStreaming, isThinking, onScroll, className, ...rest }, ref) {
4286
4459
  const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
4287
4460
  behavior: "smooth",
4288
4461
  block: "start"
@@ -4291,19 +4464,23 @@ var ChatView = React58.forwardRef(
4291
4464
  containerRef,
4292
4465
  anchorRef
4293
4466
  });
4467
+ const latestUserIdx = latestUserMessageIndex ?? items.reduceRight((found, item, idx) => {
4468
+ if (found === -1 && item.kind === "message" && item.variant === "user") {
4469
+ return idx;
4470
+ }
4471
+ return found;
4472
+ }, -1);
4294
4473
  useEffect9(() => {
4295
4474
  if (latestUserMessageIndex !== void 0 && latestUserMessageIndex >= 0) {
4296
4475
  scrollToAnchor();
4297
4476
  }
4298
4477
  }, [latestUserMessageIndex, scrollToAnchor]);
4299
- const latestUserIdx = latestUserMessageIndex ?? messages.reduceRight((found, msg, idx) => {
4300
- if (found === -1 && msg.variant === "user") {
4301
- return idx;
4302
- }
4303
- return found;
4478
+ const lastMessageIdx = items.reduceRight((found, item, idx) => {
4479
+ return found === -1 && item.kind === "message" ? idx : found;
4304
4480
  }, -1);
4305
- const showThinking = isThinking && messages.length > 0 && messages[messages.length - 1]?.variant === "user";
4306
- return /* @__PURE__ */ React58.createElement(
4481
+ const lastMessage = lastMessageIdx >= 0 ? items[lastMessageIdx] : null;
4482
+ const showThinking = isThinking && lastMessage?.kind === "message" && lastMessage.variant === "user";
4483
+ return /* @__PURE__ */ React60.createElement(
4307
4484
  "div",
4308
4485
  {
4309
4486
  ref: composeRefs(containerRef, ref),
@@ -4315,27 +4492,40 @@ var ChatView = React58.forwardRef(
4315
4492
  ),
4316
4493
  ...rest
4317
4494
  },
4318
- /* @__PURE__ */ React58.createElement("div", { ref: contentRef, className: "relative flex flex-col gap-3" }, messages.map(({
4319
- id,
4320
- variant,
4321
- className: messageClassName,
4322
- branchInfo,
4323
- actions,
4324
- isStreaming: nodeIsStreaming,
4325
- ...messageProps
4326
- }, index) => {
4495
+ /* @__PURE__ */ React60.createElement("div", { ref: contentRef, className: "relative flex flex-col gap-3" }, items.map((item, index) => {
4327
4496
  const isAnchor = index === latestUserIdx;
4328
- const isLastMessage = index === messages.length - 1;
4497
+ const wrapperRef = isAnchor ? anchorRef : void 0;
4498
+ const wrapperClass = isAnchor ? "scroll-mt-4" : void 0;
4499
+ if (item.kind === "divider") {
4500
+ const { kind: _k2, id: id2, ...dividerProps } = item;
4501
+ return /* @__PURE__ */ React60.createElement("div", { key: id2 }, /* @__PURE__ */ React60.createElement(GreyedDivider, { ...dividerProps }));
4502
+ }
4503
+ if (item.kind === "checkpoint") {
4504
+ const { kind: _k2, id: id2, ...checkpointProps } = item;
4505
+ return /* @__PURE__ */ React60.createElement("div", { key: id2, ref: wrapperRef, className: wrapperClass }, /* @__PURE__ */ React60.createElement(Checkpoint, { ...checkpointProps }));
4506
+ }
4507
+ const {
4508
+ kind: _k,
4509
+ id,
4510
+ variant,
4511
+ muted,
4512
+ className: messageClassName,
4513
+ branchInfo,
4514
+ actions,
4515
+ isStreaming: nodeIsStreaming,
4516
+ ...messageProps
4517
+ } = item;
4518
+ const isLastMessage = index === lastMessageIdx;
4329
4519
  const showStreaming = isLastMessage && isStreaming && variant === "assistant";
4330
4520
  const isMessageStreaming = showStreaming || !!nodeIsStreaming;
4331
- return /* @__PURE__ */ React58.createElement(
4521
+ return /* @__PURE__ */ React60.createElement(
4332
4522
  "div",
4333
4523
  {
4334
- key: id ?? `msg-${index}`,
4335
- ref: isAnchor ? anchorRef : void 0,
4336
- className: isAnchor ? "scroll-mt-4" : void 0
4524
+ key: id,
4525
+ ref: wrapperRef,
4526
+ className: cx(wrapperClass, muted && "opacity-60")
4337
4527
  },
4338
- /* @__PURE__ */ React58.createElement(
4528
+ /* @__PURE__ */ React60.createElement(
4339
4529
  Message,
4340
4530
  {
4341
4531
  variant,
@@ -4348,8 +4538,8 @@ var ChatView = React58.forwardRef(
4348
4538
  }
4349
4539
  )
4350
4540
  );
4351
- }), showThinking && /* @__PURE__ */ React58.createElement(ThinkingIndicator, { isVisible: true })),
4352
- /* @__PURE__ */ React58.createElement(
4541
+ }), showThinking && /* @__PURE__ */ React60.createElement(ThinkingIndicator, { isVisible: true })),
4542
+ /* @__PURE__ */ React60.createElement(
4353
4543
  "div",
4354
4544
  {
4355
4545
  ref: spacerRef,
@@ -4364,7 +4554,7 @@ var ChatView = React58.forwardRef(
4364
4554
  ChatView.displayName = "ChatView";
4365
4555
 
4366
4556
  // src/components/chat/ChatInput.tsx
4367
- import React59, { useCallback as useCallback15, useEffect as useEffect10, useRef as useRef9, useState as useState14 } from "react";
4557
+ import React61, { useCallback as useCallback15, useEffect as useEffect10, useRef as useRef9, useState as useState14 } from "react";
4368
4558
  import { Paperclip, Send as Send2, Square, X as X6 } from "lucide-react";
4369
4559
 
4370
4560
  // src/components/chat/types.ts
@@ -4377,159 +4567,20 @@ function createPreviewUrl(file) {
4377
4567
  }
4378
4568
  return void 0;
4379
4569
  }
4570
+ function revokePreviewUrl(url) {
4571
+ if (url) {
4572
+ URL.revokeObjectURL(url);
4573
+ }
4574
+ }
4380
4575
  function generateId() {
4381
4576
  if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
4382
4577
  return crypto.randomUUID();
4383
4578
  }
4384
4579
  return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
4385
4580
  }
4386
- function createEmptyTree() {
4387
- return {
4388
- nodes: {},
4389
- rootIds: [],
4390
- activeLeafId: null
4391
- };
4392
- }
4393
- function addMessageToTree(tree, message, parentId = null) {
4394
- const newNodes = { ...tree.nodes };
4395
- const newRootIds = [...tree.rootIds];
4396
- let branchIndex = 0;
4397
- if (parentId && newNodes[parentId]) {
4398
- branchIndex = newNodes[parentId].children.length;
4399
- } else if (!parentId) {
4400
- branchIndex = newRootIds.length;
4401
- }
4402
- newNodes[message.id] = {
4403
- ...message,
4404
- parentId,
4405
- children: [],
4406
- branchIndex,
4407
- createdAt: message.createdAt ?? Date.now()
4408
- };
4409
- if (parentId && newNodes[parentId]) {
4410
- newNodes[parentId] = {
4411
- ...newNodes[parentId],
4412
- children: [...newNodes[parentId].children, message.id]
4413
- };
4414
- } else {
4415
- newRootIds.push(message.id);
4416
- }
4417
- return {
4418
- nodes: newNodes,
4419
- rootIds: newRootIds,
4420
- activeLeafId: message.id
4421
- };
4422
- }
4423
- function getActivePathMessages(tree) {
4424
- if (!tree.activeLeafId) {
4425
- return [];
4426
- }
4427
- const path = [];
4428
- let currentId = tree.activeLeafId;
4429
- while (currentId) {
4430
- const node = tree.nodes[currentId];
4431
- if (!node) {
4432
- break;
4433
- }
4434
- path.unshift(node);
4435
- currentId = node.parentId;
4436
- }
4437
- return path;
4438
- }
4439
- function getSiblingInfo(tree, nodeId) {
4440
- const node = tree.nodes[nodeId];
4441
- if (!node) {
4442
- return { total: 1, current: 1 };
4443
- }
4444
- if (node.parentId) {
4445
- const parent = tree.nodes[node.parentId];
4446
- if (parent) {
4447
- const index = parent.children.indexOf(nodeId);
4448
- return {
4449
- total: parent.children.length,
4450
- current: index + 1
4451
- };
4452
- }
4453
- } else {
4454
- const index = tree.rootIds.indexOf(nodeId);
4455
- return {
4456
- total: tree.rootIds.length,
4457
- current: index + 1
4458
- };
4459
- }
4460
- return { total: 1, current: 1 };
4461
- }
4462
- function switchBranch(tree, nodeId, direction) {
4463
- const node = tree.nodes[nodeId];
4464
- if (!node) {
4465
- return tree;
4466
- }
4467
- let siblings;
4468
- let currentIndex;
4469
- if (node.parentId) {
4470
- const parent = tree.nodes[node.parentId];
4471
- if (!parent) {
4472
- return tree;
4473
- }
4474
- siblings = parent.children;
4475
- currentIndex = siblings.indexOf(nodeId);
4476
- } else {
4477
- siblings = tree.rootIds;
4478
- currentIndex = siblings.indexOf(nodeId);
4479
- }
4480
- if (siblings.length <= 1) {
4481
- return tree;
4482
- }
4483
- const newIndex = direction === "next" ? (currentIndex + 1) % siblings.length : (currentIndex - 1 + siblings.length) % siblings.length;
4484
- let leafId = siblings[newIndex];
4485
- let currentNode = tree.nodes[leafId];
4486
- while (currentNode && currentNode.children.length > 0) {
4487
- leafId = currentNode.children[0];
4488
- currentNode = tree.nodes[leafId];
4489
- }
4490
- return {
4491
- ...tree,
4492
- activeLeafId: leafId
4493
- };
4494
- }
4495
- function updateNodeContent(tree, nodeId, content, isStreaming) {
4496
- const node = tree.nodes[nodeId];
4497
- if (!node) {
4498
- return tree;
4499
- }
4500
- return {
4501
- ...tree,
4502
- nodes: {
4503
- ...tree.nodes,
4504
- [nodeId]: {
4505
- ...node,
4506
- content,
4507
- isStreaming: isStreaming ?? node.isStreaming
4508
- }
4509
- }
4510
- };
4511
- }
4512
- function messagesToTree(messages) {
4513
- let tree = createEmptyTree();
4514
- for (const msg of messages) {
4515
- const parentId = tree.activeLeafId;
4516
- tree = addMessageToTree(tree, {
4517
- id: msg.id,
4518
- role: msg.role,
4519
- content: msg.content,
4520
- parentId,
4521
- isStreaming: msg.isStreaming
4522
- }, parentId);
4523
- }
4524
- return tree;
4525
- }
4526
- function isBranchPoint(tree, nodeId) {
4527
- const node = tree.nodes[nodeId];
4528
- return node ? node.children.length > 1 : false;
4529
- }
4530
4581
 
4531
4582
  // src/components/chat/ChatInput.tsx
4532
- var ChatInput = React59.forwardRef(
4583
+ var ChatInput = React61.forwardRef(
4533
4584
  ({
4534
4585
  position = "bottom",
4535
4586
  placeholder = "Send a message...",
@@ -4674,7 +4725,7 @@ var ChatInput = React59.forwardRef(
4674
4725
  const hasAttachments = attachments.length > 0;
4675
4726
  const isUploading = attachments.some((a) => a.status === "uploading");
4676
4727
  const canSubmit = value.trim() && !disabled && !isStreaming && !isUploading;
4677
- return /* @__PURE__ */ React59.createElement(
4728
+ return /* @__PURE__ */ React61.createElement(
4678
4729
  "div",
4679
4730
  {
4680
4731
  ref,
@@ -4686,12 +4737,12 @@ var ChatInput = React59.forwardRef(
4686
4737
  ),
4687
4738
  ...rest
4688
4739
  },
4689
- isCentered && helperText && /* @__PURE__ */ React59.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
4690
- notice && /* @__PURE__ */ React59.createElement("div", { className: cx(
4740
+ isCentered && helperText && /* @__PURE__ */ React61.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
4741
+ notice && /* @__PURE__ */ React61.createElement("div", { className: cx(
4691
4742
  "w-full flex items-start gap-2 px-3 py-2 mb-1 text-xs",
4692
4743
  isCentered && "max-w-lg",
4693
4744
  notice.variant === "warning" ? "bg-gold/5 border border-gold/20 text-gold/80" : "bg-error/10 border border-error/30 text-error"
4694
- ) }, /* @__PURE__ */ React59.createElement("span", { className: "flex-1" }, notice.content), (notice.dismissible ?? notice.variant === "warning") && notice.onDismiss && /* @__PURE__ */ React59.createElement(
4745
+ ) }, /* @__PURE__ */ React61.createElement("span", { className: "flex-1" }, notice.content), (notice.dismissible ?? notice.variant === "warning") && notice.onDismiss && /* @__PURE__ */ React61.createElement(
4695
4746
  "button",
4696
4747
  {
4697
4748
  type: "button",
@@ -4702,9 +4753,9 @@ var ChatInput = React59.forwardRef(
4702
4753
  notice.variant === "warning" ? "text-gold" : "text-error"
4703
4754
  )
4704
4755
  },
4705
- /* @__PURE__ */ React59.createElement(X6, { className: "w-3 h-3" })
4756
+ /* @__PURE__ */ React61.createElement(X6, { className: "w-3 h-3" })
4706
4757
  )),
4707
- /* @__PURE__ */ React59.createElement(
4758
+ /* @__PURE__ */ React61.createElement(
4708
4759
  "div",
4709
4760
  {
4710
4761
  className: cx(
@@ -4719,7 +4770,7 @@ var ChatInput = React59.forwardRef(
4719
4770
  onDragOver: showAttachmentButton ? handleDragOver : void 0,
4720
4771
  onDrop: showAttachmentButton ? handleDrop : void 0
4721
4772
  },
4722
- hasAttachments && /* @__PURE__ */ React59.createElement("div", { className: "px-3 pt-3 pb-1" }, /* @__PURE__ */ React59.createElement(
4773
+ hasAttachments && /* @__PURE__ */ React61.createElement("div", { className: "px-3 pt-3 pb-1" }, /* @__PURE__ */ React61.createElement(
4723
4774
  AttachmentPreview,
4724
4775
  {
4725
4776
  attachments,
@@ -4727,14 +4778,14 @@ var ChatInput = React59.forwardRef(
4727
4778
  removable: !isStreaming
4728
4779
  }
4729
4780
  )),
4730
- isDragOver && /* @__PURE__ */ React59.createElement(
4781
+ isDragOver && /* @__PURE__ */ React61.createElement(
4731
4782
  "div",
4732
4783
  {
4733
4784
  className: "absolute inset-0 bg-gold/10 flex items-center justify-center z-10 pointer-events-none"
4734
4785
  },
4735
- /* @__PURE__ */ React59.createElement("span", { className: "text-gold text-sm font-medium" }, "Drop files here")
4786
+ /* @__PURE__ */ React61.createElement("span", { className: "text-gold text-sm font-medium" }, "Drop files here")
4736
4787
  ),
4737
- /* @__PURE__ */ React59.createElement("div", { className: "flex items-end" }, showAttachmentButton && /* @__PURE__ */ React59.createElement(React59.Fragment, null, /* @__PURE__ */ React59.createElement(
4788
+ /* @__PURE__ */ React61.createElement("div", { className: "flex items-end" }, showAttachmentButton && /* @__PURE__ */ React61.createElement(React61.Fragment, null, /* @__PURE__ */ React61.createElement(
4738
4789
  "button",
4739
4790
  {
4740
4791
  type: "button",
@@ -4746,8 +4797,8 @@ var ChatInput = React59.forwardRef(
4746
4797
  ),
4747
4798
  "aria-label": "Attach file"
4748
4799
  },
4749
- /* @__PURE__ */ React59.createElement(Paperclip, { className: "w-5 h-5" })
4750
- ), /* @__PURE__ */ React59.createElement(
4800
+ /* @__PURE__ */ React61.createElement(Paperclip, { className: "w-5 h-5" })
4801
+ ), /* @__PURE__ */ React61.createElement(
4751
4802
  "input",
4752
4803
  {
4753
4804
  ref: fileInputRef,
@@ -4758,7 +4809,7 @@ var ChatInput = React59.forwardRef(
4758
4809
  className: "hidden",
4759
4810
  "aria-hidden": "true"
4760
4811
  }
4761
- )), /* @__PURE__ */ React59.createElement(
4812
+ )), /* @__PURE__ */ React61.createElement(
4762
4813
  "textarea",
4763
4814
  {
4764
4815
  ref: textareaRef,
@@ -4776,7 +4827,7 @@ var ChatInput = React59.forwardRef(
4776
4827
  ),
4777
4828
  style: { maxHeight: 200 }
4778
4829
  }
4779
- ), isStreaming ? /* @__PURE__ */ React59.createElement(
4830
+ ), isStreaming ? /* @__PURE__ */ React61.createElement(
4780
4831
  "button",
4781
4832
  {
4782
4833
  type: "button",
@@ -4787,8 +4838,8 @@ var ChatInput = React59.forwardRef(
4787
4838
  ),
4788
4839
  "aria-label": "Stop generation"
4789
4840
  },
4790
- /* @__PURE__ */ React59.createElement(Square, { className: "w-5 h-5 fill-current" })
4791
- ) : /* @__PURE__ */ React59.createElement(
4841
+ /* @__PURE__ */ React61.createElement(Square, { className: "w-5 h-5 fill-current" })
4842
+ ) : /* @__PURE__ */ React61.createElement(
4792
4843
  "button",
4793
4844
  {
4794
4845
  type: "button",
@@ -4801,7 +4852,7 @@ var ChatInput = React59.forwardRef(
4801
4852
  ),
4802
4853
  "aria-label": "Send message"
4803
4854
  },
4804
- /* @__PURE__ */ React59.createElement(Send2, { className: "w-5 h-5" })
4855
+ /* @__PURE__ */ React61.createElement(Send2, { className: "w-5 h-5" })
4805
4856
  ))
4806
4857
  )
4807
4858
  );
@@ -4810,14 +4861,14 @@ var ChatInput = React59.forwardRef(
4810
4861
  ChatInput.displayName = "ChatInput";
4811
4862
 
4812
4863
  // src/components/chat/ArtifactsPanel.tsx
4813
- import React69, { useCallback as useCallback17, useEffect as useEffect12, useRef as useRef11, useState as useState17 } from "react";
4864
+ import React71, { useCallback as useCallback17, useEffect as useEffect12, useRef as useRef11, useState as useState17 } from "react";
4814
4865
  import { Image } from "lucide-react";
4815
4866
 
4816
4867
  // src/components/ArtifactCard.tsx
4817
- import React66 from "react";
4868
+ import React68 from "react";
4818
4869
 
4819
4870
  // src/components/ImageCard.tsx
4820
- import React60 from "react";
4871
+ import React62 from "react";
4821
4872
  var ASPECT_RATIO_PRESETS = {
4822
4873
  landscape: "3 / 2",
4823
4874
  portrait: "2 / 3",
@@ -4829,7 +4880,7 @@ function resolveAspectRatio(ratio) {
4829
4880
  }
4830
4881
  return ratio.replace("/", " / ");
4831
4882
  }
4832
- var ImageCard = React60.forwardRef(
4883
+ var ImageCard = React62.forwardRef(
4833
4884
  ({
4834
4885
  src,
4835
4886
  alt = "",
@@ -4845,7 +4896,7 @@ var ImageCard = React60.forwardRef(
4845
4896
  loading,
4846
4897
  ...props
4847
4898
  }, ref) => {
4848
- return /* @__PURE__ */ React60.createElement(
4899
+ return /* @__PURE__ */ React62.createElement(
4849
4900
  Card,
4850
4901
  {
4851
4902
  ref,
@@ -4853,13 +4904,13 @@ var ImageCard = React60.forwardRef(
4853
4904
  loading,
4854
4905
  ...props
4855
4906
  },
4856
- /* @__PURE__ */ React60.createElement(
4907
+ /* @__PURE__ */ React62.createElement(
4857
4908
  Card.Media,
4858
4909
  {
4859
4910
  className: mediaClassName,
4860
4911
  style: { aspectRatio: resolveAspectRatio(aspectRatio) }
4861
4912
  },
4862
- /* @__PURE__ */ React60.createElement(React60.Fragment, null, src && /* @__PURE__ */ React60.createElement(
4913
+ /* @__PURE__ */ React62.createElement(React62.Fragment, null, src && /* @__PURE__ */ React62.createElement(
4863
4914
  "img",
4864
4915
  {
4865
4916
  src,
@@ -4869,7 +4920,7 @@ var ImageCard = React60.forwardRef(
4869
4920
  objectFit === "cover" ? "object-cover" : "object-contain"
4870
4921
  )
4871
4922
  }
4872
- ), overlay && /* @__PURE__ */ React60.createElement(
4923
+ ), overlay && /* @__PURE__ */ React62.createElement(
4873
4924
  "div",
4874
4925
  {
4875
4926
  className: "absolute inset-0 bg-obsidian/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex items-center justify-center"
@@ -4877,7 +4928,7 @@ var ImageCard = React60.forwardRef(
4877
4928
  overlay
4878
4929
  ))
4879
4930
  ),
4880
- /* @__PURE__ */ React60.createElement(
4931
+ /* @__PURE__ */ React62.createElement(
4881
4932
  Card.Header,
4882
4933
  {
4883
4934
  title,
@@ -4885,14 +4936,14 @@ var ImageCard = React60.forwardRef(
4885
4936
  className: contentClassName
4886
4937
  }
4887
4938
  ),
4888
- children && /* @__PURE__ */ React60.createElement(Card.Body, { className: contentClassName }, children)
4939
+ children && /* @__PURE__ */ React62.createElement(Card.Body, { className: contentClassName }, children)
4889
4940
  );
4890
4941
  }
4891
4942
  );
4892
4943
  ImageCard.displayName = "ImageCard";
4893
4944
 
4894
4945
  // src/components/VideoCard.tsx
4895
- import React61 from "react";
4946
+ import React63 from "react";
4896
4947
  import ReactPlayer from "react-player";
4897
4948
  var ASPECT_RATIO_PRESETS2 = {
4898
4949
  video: "16 / 9",
@@ -4905,7 +4956,7 @@ function resolveAspectRatio2(ratio) {
4905
4956
  }
4906
4957
  return ratio.replace("/", " / ");
4907
4958
  }
4908
- var VideoCard = React61.forwardRef(
4959
+ var VideoCard = React63.forwardRef(
4909
4960
  ({
4910
4961
  src,
4911
4962
  title,
@@ -4925,7 +4976,7 @@ var VideoCard = React61.forwardRef(
4925
4976
  loading,
4926
4977
  ...props
4927
4978
  }, ref) => {
4928
- return /* @__PURE__ */ React61.createElement(
4979
+ return /* @__PURE__ */ React63.createElement(
4929
4980
  Card,
4930
4981
  {
4931
4982
  ref,
@@ -4933,13 +4984,13 @@ var VideoCard = React61.forwardRef(
4933
4984
  loading,
4934
4985
  ...props
4935
4986
  },
4936
- /* @__PURE__ */ React61.createElement(
4987
+ /* @__PURE__ */ React63.createElement(
4937
4988
  Card.Media,
4938
4989
  {
4939
4990
  className: mediaClassName,
4940
4991
  style: { aspectRatio: resolveAspectRatio2(aspectRatio) }
4941
4992
  },
4942
- src && /* @__PURE__ */ React61.createElement(
4993
+ src && /* @__PURE__ */ React63.createElement(
4943
4994
  ReactPlayer,
4944
4995
  {
4945
4996
  src,
@@ -4956,7 +5007,7 @@ var VideoCard = React61.forwardRef(
4956
5007
  }
4957
5008
  )
4958
5009
  ),
4959
- /* @__PURE__ */ React61.createElement(
5010
+ /* @__PURE__ */ React63.createElement(
4960
5011
  Card.Header,
4961
5012
  {
4962
5013
  title,
@@ -4964,17 +5015,17 @@ var VideoCard = React61.forwardRef(
4964
5015
  className: contentClassName
4965
5016
  }
4966
5017
  ),
4967
- children && /* @__PURE__ */ React61.createElement(Card.Body, { className: contentClassName }, children)
5018
+ children && /* @__PURE__ */ React63.createElement(Card.Body, { className: contentClassName }, children)
4968
5019
  );
4969
5020
  }
4970
5021
  );
4971
5022
  VideoCard.displayName = "VideoCard";
4972
5023
 
4973
5024
  // src/components/AudioCard.tsx
4974
- import React62 from "react";
5025
+ import React64 from "react";
4975
5026
  import ReactPlayer2 from "react-player";
4976
5027
  import { Music } from "lucide-react";
4977
- var AudioCard = React62.forwardRef(
5028
+ var AudioCard = React64.forwardRef(
4978
5029
  ({
4979
5030
  src,
4980
5031
  title,
@@ -4993,7 +5044,7 @@ var AudioCard = React62.forwardRef(
4993
5044
  loading,
4994
5045
  ...props
4995
5046
  }, ref) => {
4996
- return /* @__PURE__ */ React62.createElement(
5047
+ return /* @__PURE__ */ React64.createElement(
4997
5048
  Card,
4998
5049
  {
4999
5050
  ref,
@@ -5001,10 +5052,10 @@ var AudioCard = React62.forwardRef(
5001
5052
  loading,
5002
5053
  ...props
5003
5054
  },
5004
- /* @__PURE__ */ React62.createElement(Card.Media, { className: cx(
5055
+ /* @__PURE__ */ React64.createElement(Card.Media, { className: cx(
5005
5056
  "bg-obsidian py-8 flex flex-col items-center justify-center",
5006
5057
  mediaClassName
5007
- ) }, /* @__PURE__ */ React62.createElement("div", { className: "mb-4 text-gold" }, /* @__PURE__ */ React62.createElement(Music, { size: 48 })), src && /* @__PURE__ */ React62.createElement("div", { className: "w-full px-4" }, /* @__PURE__ */ React62.createElement(
5058
+ ) }, /* @__PURE__ */ React64.createElement("div", { className: "mb-4 text-gold" }, /* @__PURE__ */ React64.createElement(Music, { size: 48 })), src && /* @__PURE__ */ React64.createElement("div", { className: "w-full px-4" }, /* @__PURE__ */ React64.createElement(
5008
5059
  ReactPlayer2,
5009
5060
  {
5010
5061
  src,
@@ -5019,7 +5070,7 @@ var AudioCard = React62.forwardRef(
5019
5070
  ...playerProps
5020
5071
  }
5021
5072
  ))),
5022
- /* @__PURE__ */ React62.createElement(
5073
+ /* @__PURE__ */ React64.createElement(
5023
5074
  Card.Header,
5024
5075
  {
5025
5076
  title,
@@ -5027,16 +5078,16 @@ var AudioCard = React62.forwardRef(
5027
5078
  className: contentClassName
5028
5079
  }
5029
5080
  ),
5030
- children && /* @__PURE__ */ React62.createElement(Card.Body, { className: contentClassName }, children)
5081
+ children && /* @__PURE__ */ React64.createElement(Card.Body, { className: contentClassName }, children)
5031
5082
  );
5032
5083
  }
5033
5084
  );
5034
5085
  AudioCard.displayName = "AudioCard";
5035
5086
 
5036
5087
  // src/components/PdfCard.tsx
5037
- import React63 from "react";
5088
+ import React65 from "react";
5038
5089
  import { FileText as FileText2 } from "lucide-react";
5039
- var PdfCard = React63.forwardRef(
5090
+ var PdfCard = React65.forwardRef(
5040
5091
  ({
5041
5092
  src,
5042
5093
  title,
@@ -5049,7 +5100,7 @@ var PdfCard = React63.forwardRef(
5049
5100
  loading,
5050
5101
  ...props
5051
5102
  }, ref) => {
5052
- return /* @__PURE__ */ React63.createElement(
5103
+ return /* @__PURE__ */ React65.createElement(
5053
5104
  Card,
5054
5105
  {
5055
5106
  ref,
@@ -5057,13 +5108,13 @@ var PdfCard = React63.forwardRef(
5057
5108
  loading,
5058
5109
  ...props
5059
5110
  },
5060
- /* @__PURE__ */ React63.createElement(
5111
+ /* @__PURE__ */ React65.createElement(
5061
5112
  Card.Media,
5062
5113
  {
5063
5114
  className: cx("bg-obsidian", mediaClassName),
5064
5115
  style: { height }
5065
5116
  },
5066
- src && /* @__PURE__ */ React63.createElement(
5117
+ src && /* @__PURE__ */ React65.createElement(
5067
5118
  "iframe",
5068
5119
  {
5069
5120
  src: `${src}#view=FitH`,
@@ -5072,23 +5123,23 @@ var PdfCard = React63.forwardRef(
5072
5123
  }
5073
5124
  )
5074
5125
  ),
5075
- /* @__PURE__ */ React63.createElement(
5126
+ /* @__PURE__ */ React65.createElement(
5076
5127
  Card.Header,
5077
5128
  {
5078
5129
  title,
5079
5130
  subtitle,
5080
5131
  className: contentClassName,
5081
- action: /* @__PURE__ */ React63.createElement("div", { className: "p-2 bg-ash/20 text-gold shrink-0" }, /* @__PURE__ */ React63.createElement(FileText2, { size: 20 }))
5132
+ action: /* @__PURE__ */ React65.createElement("div", { className: "p-2 bg-ash/20 text-gold shrink-0" }, /* @__PURE__ */ React65.createElement(FileText2, { size: 20 }))
5082
5133
  }
5083
5134
  ),
5084
- children && /* @__PURE__ */ React63.createElement(Card.Body, { className: contentClassName }, children)
5135
+ children && /* @__PURE__ */ React65.createElement(Card.Body, { className: contentClassName }, children)
5085
5136
  );
5086
5137
  }
5087
5138
  );
5088
5139
  PdfCard.displayName = "PdfCard";
5089
5140
 
5090
5141
  // src/components/ScriptCard.tsx
5091
- import React64 from "react";
5142
+ import React66 from "react";
5092
5143
  var SCRIPT_ELEMENT_TYPES = {
5093
5144
  SCENE_HEADING: "scene-heading",
5094
5145
  ACTION: "action",
@@ -5102,28 +5153,28 @@ var SCRIPT_ELEMENT_TYPES = {
5102
5153
  function ScriptElementRenderer({ element }) {
5103
5154
  switch (element.type) {
5104
5155
  case "scene-heading":
5105
- return /* @__PURE__ */ React64.createElement("p", { className: "mt-4 mb-2 font-bold uppercase text-gold text-xs tracking-wide" }, element.content);
5156
+ return /* @__PURE__ */ React66.createElement("p", { className: "mt-4 mb-2 font-bold uppercase text-gold text-xs tracking-wide" }, element.content);
5106
5157
  case "action":
5107
- return /* @__PURE__ */ React64.createElement("p", { className: "my-2 text-silver text-xs leading-relaxed" }, element.content);
5158
+ return /* @__PURE__ */ React66.createElement("p", { className: "my-2 text-silver text-xs leading-relaxed" }, element.content);
5108
5159
  case "character":
5109
- return /* @__PURE__ */ React64.createElement("p", { className: "mt-4 mb-0.5 ml-8 font-bold text-white text-xs uppercase tracking-wide" }, element.content);
5160
+ return /* @__PURE__ */ React66.createElement("p", { className: "mt-4 mb-0.5 ml-8 font-bold text-white text-xs uppercase tracking-wide" }, element.content);
5110
5161
  case "parenthetical":
5111
- return /* @__PURE__ */ React64.createElement("p", { className: "ml-6 text-silver/70 text-xs italic" }, "(", element.content, ")");
5162
+ return /* @__PURE__ */ React66.createElement("p", { className: "ml-6 text-silver/70 text-xs italic" }, "(", element.content, ")");
5112
5163
  case "dialogue":
5113
- return /* @__PURE__ */ React64.createElement("p", { className: "ml-4 mr-8 text-silver text-xs leading-relaxed" }, element.content);
5164
+ return /* @__PURE__ */ React66.createElement("p", { className: "ml-4 mr-8 text-silver text-xs leading-relaxed" }, element.content);
5114
5165
  case "transition":
5115
- return /* @__PURE__ */ React64.createElement("p", { className: "mt-4 mb-2 text-right font-bold uppercase text-gold/80 text-xs tracking-wide" }, element.content);
5166
+ return /* @__PURE__ */ React66.createElement("p", { className: "mt-4 mb-2 text-right font-bold uppercase text-gold/80 text-xs tracking-wide" }, element.content);
5116
5167
  case "title":
5117
- return /* @__PURE__ */ React64.createElement("p", { className: "mt-6 mb-2 text-center font-bold text-gold text-sm" }, element.content);
5168
+ return /* @__PURE__ */ React66.createElement("p", { className: "mt-6 mb-2 text-center font-bold text-gold text-sm" }, element.content);
5118
5169
  case "subtitle":
5119
- return /* @__PURE__ */ React64.createElement("p", { className: "text-center italic text-gold/70 text-xs" }, element.content);
5170
+ return /* @__PURE__ */ React66.createElement("p", { className: "text-center italic text-gold/70 text-xs" }, element.content);
5120
5171
  default:
5121
5172
  return null;
5122
5173
  }
5123
5174
  }
5124
- var ScriptCard = React64.forwardRef(
5175
+ var ScriptCard = React66.forwardRef(
5125
5176
  ({ title, subtitle, elements, maxHeight = "16rem", className, style, loading, ...rest }, ref) => {
5126
- return /* @__PURE__ */ React64.createElement(
5177
+ return /* @__PURE__ */ React66.createElement(
5127
5178
  Card,
5128
5179
  {
5129
5180
  ref,
@@ -5131,20 +5182,20 @@ var ScriptCard = React64.forwardRef(
5131
5182
  loading,
5132
5183
  ...rest
5133
5184
  },
5134
- /* @__PURE__ */ React64.createElement(
5185
+ /* @__PURE__ */ React66.createElement(
5135
5186
  Card.Header,
5136
5187
  {
5137
5188
  title,
5138
5189
  subtitle
5139
5190
  }
5140
5191
  ),
5141
- /* @__PURE__ */ React64.createElement(
5192
+ /* @__PURE__ */ React66.createElement(
5142
5193
  Card.Body,
5143
5194
  {
5144
5195
  className: "font-mono overflow-y-auto",
5145
5196
  style: { maxHeight, ...style }
5146
5197
  },
5147
- elements.map((element, index) => /* @__PURE__ */ React64.createElement(ScriptElementRenderer, { key: index, element }))
5198
+ elements.map((element, index) => /* @__PURE__ */ React66.createElement(ScriptElementRenderer, { key: index, element }))
5148
5199
  )
5149
5200
  );
5150
5201
  }
@@ -5152,8 +5203,8 @@ var ScriptCard = React64.forwardRef(
5152
5203
  ScriptCard.displayName = "ScriptCard";
5153
5204
 
5154
5205
  // src/components/TextCard.tsx
5155
- import React65 from "react";
5156
- var TextCard = React65.forwardRef(
5206
+ import React67 from "react";
5207
+ var TextCard = React67.forwardRef(
5157
5208
  ({
5158
5209
  content,
5159
5210
  title,
@@ -5165,7 +5216,7 @@ var TextCard = React65.forwardRef(
5165
5216
  loading,
5166
5217
  ...props
5167
5218
  }, ref) => {
5168
- return /* @__PURE__ */ React65.createElement(
5219
+ return /* @__PURE__ */ React67.createElement(
5169
5220
  Card,
5170
5221
  {
5171
5222
  ref,
@@ -5173,20 +5224,20 @@ var TextCard = React65.forwardRef(
5173
5224
  loading,
5174
5225
  ...props
5175
5226
  },
5176
- /* @__PURE__ */ React65.createElement(
5227
+ /* @__PURE__ */ React67.createElement(
5177
5228
  Card.Header,
5178
5229
  {
5179
5230
  title,
5180
5231
  subtitle
5181
5232
  }
5182
5233
  ),
5183
- /* @__PURE__ */ React65.createElement(
5234
+ /* @__PURE__ */ React67.createElement(
5184
5235
  Card.Body,
5185
5236
  {
5186
5237
  className: cx("overflow-y-auto", contentClassName),
5187
5238
  style: { maxHeight }
5188
5239
  },
5189
- /* @__PURE__ */ React65.createElement(
5240
+ /* @__PURE__ */ React67.createElement(
5190
5241
  MarkdownContent,
5191
5242
  {
5192
5243
  content,
@@ -5224,7 +5275,7 @@ var ARTIFACT_TYPES = {
5224
5275
  SCRIPT: "SCRIPT",
5225
5276
  PDF: "PDF"
5226
5277
  };
5227
- var ArtifactCard = React66.forwardRef(
5278
+ var ArtifactCard = React68.forwardRef(
5228
5279
  ({ artifact, onExpand, loading, className, ...props }, ref) => {
5229
5280
  const derivedLoading = deriveCardSlotLoading(artifact);
5230
5281
  const commonProps = {
@@ -5242,7 +5293,7 @@ var ArtifactCard = React66.forwardRef(
5242
5293
  const renderContent = () => {
5243
5294
  switch (artifact.type) {
5244
5295
  case "IMAGE":
5245
- return /* @__PURE__ */ React66.createElement(
5296
+ return /* @__PURE__ */ React68.createElement(
5246
5297
  ImageCard,
5247
5298
  {
5248
5299
  ...commonProps,
@@ -5252,7 +5303,7 @@ var ArtifactCard = React66.forwardRef(
5252
5303
  }
5253
5304
  );
5254
5305
  case "VIDEO":
5255
- return /* @__PURE__ */ React66.createElement(
5306
+ return /* @__PURE__ */ React68.createElement(
5256
5307
  VideoCard,
5257
5308
  {
5258
5309
  ...commonProps,
@@ -5262,7 +5313,7 @@ var ArtifactCard = React66.forwardRef(
5262
5313
  }
5263
5314
  );
5264
5315
  case "AUDIO":
5265
- return /* @__PURE__ */ React66.createElement(
5316
+ return /* @__PURE__ */ React68.createElement(
5266
5317
  AudioCard,
5267
5318
  {
5268
5319
  ...commonProps,
@@ -5271,7 +5322,7 @@ var ArtifactCard = React66.forwardRef(
5271
5322
  }
5272
5323
  );
5273
5324
  case "PDF":
5274
- return /* @__PURE__ */ React66.createElement(
5325
+ return /* @__PURE__ */ React68.createElement(
5275
5326
  PdfCard,
5276
5327
  {
5277
5328
  ...commonProps,
@@ -5279,7 +5330,7 @@ var ArtifactCard = React66.forwardRef(
5279
5330
  }
5280
5331
  );
5281
5332
  case "SCRIPT":
5282
- return /* @__PURE__ */ React66.createElement(
5333
+ return /* @__PURE__ */ React68.createElement(
5283
5334
  ScriptCard,
5284
5335
  {
5285
5336
  ...commonProps,
@@ -5288,7 +5339,7 @@ var ArtifactCard = React66.forwardRef(
5288
5339
  }
5289
5340
  );
5290
5341
  case "TEXT":
5291
- return /* @__PURE__ */ React66.createElement(
5342
+ return /* @__PURE__ */ React68.createElement(
5292
5343
  TextCard,
5293
5344
  {
5294
5345
  ...commonProps,
@@ -5306,7 +5357,7 @@ var ArtifactCard = React66.forwardRef(
5306
5357
  }
5307
5358
  };
5308
5359
  const isCardExpandable = !!onExpand && (artifact.type === "IMAGE" || artifact.type === "PDF" || artifact.type === "SCRIPT" || artifact.type === "TEXT");
5309
- return /* @__PURE__ */ React66.createElement(
5360
+ return /* @__PURE__ */ React68.createElement(
5310
5361
  "div",
5311
5362
  {
5312
5363
  ref,
@@ -5319,7 +5370,7 @@ var ArtifactCard = React66.forwardRef(
5319
5370
  onClick: isCardExpandable ? handleExpand : void 0,
5320
5371
  ...props
5321
5372
  },
5322
- onExpand && /* @__PURE__ */ React66.createElement(
5373
+ onExpand && /* @__PURE__ */ React68.createElement(
5323
5374
  "button",
5324
5375
  {
5325
5376
  onClick: handleExpand,
@@ -5330,7 +5381,7 @@ var ArtifactCard = React66.forwardRef(
5330
5381
  ),
5331
5382
  "aria-label": "Expand artifact"
5332
5383
  },
5333
- /* @__PURE__ */ React66.createElement(ExpandIcon, { className: "w-4 h-4" })
5384
+ /* @__PURE__ */ React68.createElement(ExpandIcon, { className: "w-4 h-4" })
5334
5385
  ),
5335
5386
  renderContent()
5336
5387
  );
@@ -5339,10 +5390,10 @@ var ArtifactCard = React66.forwardRef(
5339
5390
  ArtifactCard.displayName = "ArtifactCard";
5340
5391
 
5341
5392
  // src/components/ArtifactGroup.tsx
5342
- import React67, { useEffect as useEffect11, useRef as useRef10, useState as useState15 } from "react";
5393
+ import React69, { useEffect as useEffect11, useRef as useRef10, useState as useState15 } from "react";
5343
5394
  var LAYER_OFFSET = "8px";
5344
5395
  var LAYER_OFFSET_2X = "16px";
5345
- var ArtifactGroup = React67.forwardRef(
5396
+ var ArtifactGroup = React69.forwardRef(
5346
5397
  ({ node, onClick, className, ...props }, ref) => {
5347
5398
  const children = node.children;
5348
5399
  const count = children.length;
@@ -5364,21 +5415,21 @@ var ArtifactGroup = React67.forwardRef(
5364
5415
  };
5365
5416
  const renderFrontContent = () => {
5366
5417
  if (!frontChild) {
5367
- return /* @__PURE__ */ React67.createElement("div", { className: "w-full aspect-video bg-graphite border border-ash/40 flex items-center justify-center" }, /* @__PURE__ */ React67.createElement("span", { className: "text-silver text-sm" }, "Empty group"));
5418
+ return /* @__PURE__ */ React69.createElement("div", { className: "w-full aspect-video bg-graphite border border-ash/40 flex items-center justify-center" }, /* @__PURE__ */ React69.createElement("span", { className: "text-silver text-sm" }, "Empty group"));
5368
5419
  }
5369
5420
  if (frontChild.type === "ARTIFACT" && frontChild.artifact) {
5370
- return /* @__PURE__ */ React67.createElement(ArtifactCard, { artifact: frontChild.artifact, className: "w-full" });
5421
+ return /* @__PURE__ */ React69.createElement(ArtifactCard, { artifact: frontChild.artifact, className: "w-full" });
5371
5422
  }
5372
- return /* @__PURE__ */ React67.createElement(
5423
+ return /* @__PURE__ */ React69.createElement(
5373
5424
  "div",
5374
5425
  {
5375
5426
  className: "w-full aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
5376
5427
  },
5377
- /* @__PURE__ */ React67.createElement("span", { className: "text-sm text-silver uppercase tracking-wider" }, frontChild.type === "GROUP" ? "Group" : "Variants"),
5378
- /* @__PURE__ */ React67.createElement("span", { className: "text-white font-semibold" }, frontChild.label)
5428
+ /* @__PURE__ */ React69.createElement("span", { className: "text-sm text-silver uppercase tracking-wider" }, frontChild.type === "GROUP" ? "Group" : "Variants"),
5429
+ /* @__PURE__ */ React69.createElement("span", { className: "text-white font-semibold" }, frontChild.label)
5379
5430
  );
5380
5431
  };
5381
- return /* @__PURE__ */ React67.createElement(
5432
+ return /* @__PURE__ */ React69.createElement(
5382
5433
  "div",
5383
5434
  {
5384
5435
  ref,
@@ -5398,21 +5449,21 @@ var ArtifactGroup = React67.forwardRef(
5398
5449
  "aria-label": `${node.label} \u2014 ${count} items`,
5399
5450
  ...props
5400
5451
  },
5401
- /* @__PURE__ */ React67.createElement(Card, { noPadding: true, className: "p-5" }, /* @__PURE__ */ React67.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label), /* @__PURE__ */ React67.createElement("div", { style: { paddingRight: LAYER_OFFSET_2X, paddingBottom: LAYER_OFFSET_2X } }, /* @__PURE__ */ React67.createElement("div", { className: "relative" }, /* @__PURE__ */ React67.createElement(
5452
+ /* @__PURE__ */ React69.createElement(Card, { noPadding: true, className: "p-5" }, /* @__PURE__ */ React69.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label), /* @__PURE__ */ React69.createElement("div", { style: { paddingRight: LAYER_OFFSET_2X, paddingBottom: LAYER_OFFSET_2X } }, /* @__PURE__ */ React69.createElement("div", { className: "relative" }, /* @__PURE__ */ React69.createElement(
5402
5453
  "div",
5403
5454
  {
5404
5455
  className: "absolute inset-0 bg-charcoal border border-ash/30 pointer-events-none",
5405
5456
  style: { transform: `translate(${LAYER_OFFSET_2X}, ${LAYER_OFFSET_2X})` },
5406
5457
  "aria-hidden": "true"
5407
5458
  }
5408
- ), /* @__PURE__ */ React67.createElement(
5459
+ ), /* @__PURE__ */ React69.createElement(
5409
5460
  "div",
5410
5461
  {
5411
5462
  className: "absolute inset-0 bg-charcoal border border-ash/40 pointer-events-none",
5412
5463
  style: { transform: `translate(${LAYER_OFFSET}, ${LAYER_OFFSET})` },
5413
5464
  "aria-hidden": "true"
5414
5465
  }
5415
- ), /* @__PURE__ */ React67.createElement("div", { className: "relative transition-transform duration-200 group-hover:-translate-y-0.5" }, renderFrontContent()), /* @__PURE__ */ React67.createElement(
5466
+ ), /* @__PURE__ */ React69.createElement("div", { className: "relative transition-transform duration-200 group-hover:-translate-y-0.5" }, renderFrontContent()), /* @__PURE__ */ React69.createElement(
5416
5467
  "div",
5417
5468
  {
5418
5469
  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",
@@ -5426,13 +5477,13 @@ var ArtifactGroup = React67.forwardRef(
5426
5477
  ArtifactGroup.displayName = "ArtifactGroup";
5427
5478
 
5428
5479
  // src/components/ArtifactVariantStack.tsx
5429
- import React68 from "react";
5430
- var ArtifactVariantStack = React68.forwardRef(
5480
+ import React70 from "react";
5481
+ var ArtifactVariantStack = React70.forwardRef(
5431
5482
  ({ node, onExpandArtifact, onGroupClick, className, ...props }, ref) => {
5432
5483
  const children = node.children;
5433
5484
  const renderChild = (child) => {
5434
5485
  if (child.type === "ARTIFACT" && child.artifact) {
5435
- return /* @__PURE__ */ React68.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React68.createElement(
5486
+ return /* @__PURE__ */ React70.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React70.createElement(
5436
5487
  ArtifactCard,
5437
5488
  {
5438
5489
  artifact: child.artifact,
@@ -5442,18 +5493,18 @@ var ArtifactVariantStack = React68.forwardRef(
5442
5493
  ));
5443
5494
  }
5444
5495
  if (child.type === "GROUP") {
5445
- return /* @__PURE__ */ React68.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React68.createElement(ArtifactGroup, { node: child, onClick: onGroupClick }));
5496
+ return /* @__PURE__ */ React70.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React70.createElement(ArtifactGroup, { node: child, onClick: onGroupClick }));
5446
5497
  }
5447
- return /* @__PURE__ */ React68.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React68.createElement(
5498
+ return /* @__PURE__ */ React70.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React70.createElement(
5448
5499
  "div",
5449
5500
  {
5450
5501
  className: "aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
5451
5502
  },
5452
- /* @__PURE__ */ React68.createElement("span", { className: "text-xs text-silver uppercase tracking-wider" }, "Variants"),
5453
- /* @__PURE__ */ React68.createElement("span", { className: "text-sm text-white font-semibold truncate max-w-full" }, child.label)
5503
+ /* @__PURE__ */ React70.createElement("span", { className: "text-xs text-silver uppercase tracking-wider" }, "Variants"),
5504
+ /* @__PURE__ */ React70.createElement("span", { className: "text-sm text-white font-semibold truncate max-w-full" }, child.label)
5454
5505
  ));
5455
5506
  };
5456
- return /* @__PURE__ */ React68.createElement(
5507
+ return /* @__PURE__ */ React70.createElement(
5457
5508
  Card,
5458
5509
  {
5459
5510
  ref,
@@ -5461,8 +5512,8 @@ var ArtifactVariantStack = React68.forwardRef(
5461
5512
  className: cx("w-full p-5", className),
5462
5513
  ...props
5463
5514
  },
5464
- /* @__PURE__ */ React68.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label),
5465
- /* @__PURE__ */ React68.createElement("div", { className: "flex gap-3" }, children.map(renderChild))
5515
+ /* @__PURE__ */ React70.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label),
5516
+ /* @__PURE__ */ React70.createElement("div", { className: "flex gap-3" }, children.map(renderChild))
5466
5517
  );
5467
5518
  }
5468
5519
  );
@@ -5515,41 +5566,41 @@ function ArtifactModal({
5515
5566
  onClose();
5516
5567
  }
5517
5568
  }, [onClose]);
5518
- return /* @__PURE__ */ React69.createElement(
5569
+ return /* @__PURE__ */ React71.createElement(
5519
5570
  "div",
5520
5571
  {
5521
5572
  className: "fixed inset-0 z-50 flex items-center justify-center bg-void/90 backdrop-blur-sm animate-fade-in",
5522
5573
  onClick: handleBackdropClick
5523
5574
  },
5524
- /* @__PURE__ */ React69.createElement(
5575
+ /* @__PURE__ */ React71.createElement(
5525
5576
  "div",
5526
5577
  {
5527
5578
  className: "relative w-11/12 h-5/6 max-w-6xl bg-charcoal border border-ash/40 flex flex-col overflow-hidden"
5528
5579
  },
5529
- /* @__PURE__ */ React69.createElement(
5580
+ /* @__PURE__ */ React71.createElement(
5530
5581
  "div",
5531
5582
  {
5532
5583
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5533
5584
  },
5534
- /* @__PURE__ */ React69.createElement("div", null, artifact.title && /* @__PURE__ */ React69.createElement("h3", { className: "text-sm font-semibold text-white" }, artifact.title), artifact.subtitle && /* @__PURE__ */ React69.createElement("p", { className: "text-xs text-silver" }, artifact.subtitle)),
5535
- /* @__PURE__ */ React69.createElement(
5585
+ /* @__PURE__ */ React71.createElement("div", null, artifact.title && /* @__PURE__ */ React71.createElement("h3", { className: "text-sm font-semibold text-white" }, artifact.title), artifact.subtitle && /* @__PURE__ */ React71.createElement("p", { className: "text-xs text-silver" }, artifact.subtitle)),
5586
+ /* @__PURE__ */ React71.createElement(
5536
5587
  "button",
5537
5588
  {
5538
5589
  onClick: onClose,
5539
5590
  className: "p-2 text-silver hover:text-white hover:bg-ash/20 transition-colors",
5540
5591
  "aria-label": "Close modal"
5541
5592
  },
5542
- /* @__PURE__ */ React69.createElement(CloseIcon, { className: "w-5 h-5" })
5593
+ /* @__PURE__ */ React71.createElement(CloseIcon, { className: "w-5 h-5" })
5543
5594
  )
5544
5595
  ),
5545
- /* @__PURE__ */ React69.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ React69.createElement(
5596
+ /* @__PURE__ */ React71.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ React71.createElement(
5546
5597
  "img",
5547
5598
  {
5548
5599
  src: artifact.url,
5549
5600
  alt: artifact.alt || "Artifact image",
5550
5601
  className: "max-w-full max-h-full object-contain mx-auto"
5551
5602
  }
5552
- ), artifact.type === "VIDEO" && /* @__PURE__ */ React69.createElement(
5603
+ ), artifact.type === "VIDEO" && /* @__PURE__ */ React71.createElement(
5553
5604
  VideoCard,
5554
5605
  {
5555
5606
  src: artifact.url || "",
@@ -5557,20 +5608,20 @@ function ArtifactModal({
5557
5608
  controls: true,
5558
5609
  className: "max-w-full max-h-full mx-auto"
5559
5610
  }
5560
- ), artifact.type === "AUDIO" && /* @__PURE__ */ React69.createElement(
5611
+ ), artifact.type === "AUDIO" && /* @__PURE__ */ React71.createElement(
5561
5612
  AudioCard,
5562
5613
  {
5563
5614
  src: artifact.url || "",
5564
5615
  controls: true,
5565
5616
  className: "max-w-xl mx-auto"
5566
5617
  }
5567
- ), artifact.type === "PDF" && /* @__PURE__ */ React69.createElement(
5618
+ ), artifact.type === "PDF" && /* @__PURE__ */ React71.createElement(
5568
5619
  PdfCard,
5569
5620
  {
5570
5621
  src: artifact.url || "",
5571
5622
  className: "h-full border-0"
5572
5623
  }
5573
- ), artifact.type === "TEXT" && /* @__PURE__ */ React69.createElement(
5624
+ ), artifact.type === "TEXT" && /* @__PURE__ */ React71.createElement(
5574
5625
  MarkdownContent,
5575
5626
  {
5576
5627
  content: artifact.inlineContent || "",
@@ -5580,7 +5631,7 @@ function ArtifactModal({
5580
5631
  artifact.mimeType === "text/plain" && "whitespace-pre-wrap"
5581
5632
  )
5582
5633
  }
5583
- ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ React69.createElement(
5634
+ ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ React71.createElement(
5584
5635
  ScriptCard,
5585
5636
  {
5586
5637
  elements: artifact.scriptElements,
@@ -5598,7 +5649,7 @@ function NodeRenderer({
5598
5649
  onGroupClick
5599
5650
  }) {
5600
5651
  if (node.type === "ARTIFACT" && node.artifact) {
5601
- return /* @__PURE__ */ React69.createElement(
5652
+ return /* @__PURE__ */ React71.createElement(
5602
5653
  ArtifactCard,
5603
5654
  {
5604
5655
  artifact: node.artifact,
@@ -5608,10 +5659,10 @@ function NodeRenderer({
5608
5659
  );
5609
5660
  }
5610
5661
  if (node.type === "GROUP") {
5611
- return /* @__PURE__ */ React69.createElement(ArtifactGroup, { node, onClick: onGroupClick });
5662
+ return /* @__PURE__ */ React71.createElement(ArtifactGroup, { node, onClick: onGroupClick });
5612
5663
  }
5613
5664
  if (node.type === "VARIANT_SET") {
5614
- return /* @__PURE__ */ React69.createElement(
5665
+ return /* @__PURE__ */ React71.createElement(
5615
5666
  ArtifactVariantStack,
5616
5667
  {
5617
5668
  node,
@@ -5622,7 +5673,7 @@ function NodeRenderer({
5622
5673
  }
5623
5674
  return null;
5624
5675
  }
5625
- var ArtifactsPanel = React69.forwardRef(
5676
+ var ArtifactsPanel = React71.forwardRef(
5626
5677
  ({
5627
5678
  nodes,
5628
5679
  loading,
@@ -5657,7 +5708,7 @@ var ArtifactsPanel = React69.forwardRef(
5657
5708
  observer.observe(el);
5658
5709
  return () => observer.disconnect();
5659
5710
  }, []);
5660
- return /* @__PURE__ */ React69.createElement(React69.Fragment, null, /* @__PURE__ */ React69.createElement(
5711
+ return /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(
5661
5712
  "div",
5662
5713
  {
5663
5714
  ref,
@@ -5668,19 +5719,19 @@ var ArtifactsPanel = React69.forwardRef(
5668
5719
  ),
5669
5720
  ...rest
5670
5721
  },
5671
- /* @__PURE__ */ React69.createElement(
5722
+ /* @__PURE__ */ React71.createElement(
5672
5723
  "div",
5673
5724
  {
5674
5725
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5675
5726
  },
5676
- /* @__PURE__ */ React69.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
5677
- hasNodes && /* @__PURE__ */ React69.createElement(
5727
+ /* @__PURE__ */ React71.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
5728
+ hasNodes && /* @__PURE__ */ React71.createElement(
5678
5729
  "div",
5679
5730
  {
5680
5731
  className: "flex items-center gap-0.5",
5681
5732
  "data-testid": "zoom-controls"
5682
5733
  },
5683
- /* @__PURE__ */ React69.createElement(
5734
+ /* @__PURE__ */ React71.createElement(
5684
5735
  "button",
5685
5736
  {
5686
5737
  onClick: zoomOut,
@@ -5694,8 +5745,8 @@ var ArtifactsPanel = React69.forwardRef(
5694
5745
  },
5695
5746
  "\u2212"
5696
5747
  ),
5697
- /* @__PURE__ */ React69.createElement("span", { className: "text-xs text-silver w-8 text-center tabular-nums", "data-testid": "zoom-level" }, Math.round(currentZoom * 100), "%"),
5698
- /* @__PURE__ */ React69.createElement(
5748
+ /* @__PURE__ */ React71.createElement("span", { className: "text-xs text-silver w-8 text-center tabular-nums", "data-testid": "zoom-level" }, Math.round(currentZoom * 100), "%"),
5749
+ /* @__PURE__ */ React71.createElement(
5699
5750
  "button",
5700
5751
  {
5701
5752
  onClick: zoomIn,
@@ -5711,7 +5762,7 @@ var ArtifactsPanel = React69.forwardRef(
5711
5762
  )
5712
5763
  )
5713
5764
  ),
5714
- hasNodes && !treeNav.isAtRoot && /* @__PURE__ */ React69.createElement(
5765
+ hasNodes && !treeNav.isAtRoot && /* @__PURE__ */ React71.createElement(
5715
5766
  "nav",
5716
5767
  {
5717
5768
  className: "flex items-center gap-1 px-4 py-2 border-b border-ash/40 shrink-0 overflow-x-auto text-xs",
@@ -5720,7 +5771,7 @@ var ArtifactsPanel = React69.forwardRef(
5720
5771
  },
5721
5772
  treeNav.breadcrumbs.map((crumb, i) => {
5722
5773
  const isLast = i === treeNav.breadcrumbs.length - 1;
5723
- return /* @__PURE__ */ React69.createElement("span", { key: i, className: "flex items-center gap-1 shrink-0" }, i > 0 && /* @__PURE__ */ React69.createElement(ChevronRightIcon, { className: "w-3 h-3 text-silver/50", "aria-hidden": true }), isLast ? /* @__PURE__ */ React69.createElement("span", { className: "text-gold font-medium" }, crumb.label) : /* @__PURE__ */ React69.createElement(
5774
+ return /* @__PURE__ */ React71.createElement("span", { key: i, className: "flex items-center gap-1 shrink-0" }, i > 0 && /* @__PURE__ */ React71.createElement(ChevronRightIcon, { className: "w-3 h-3 text-silver/50", "aria-hidden": true }), isLast ? /* @__PURE__ */ React71.createElement("span", { className: "text-gold font-medium" }, crumb.label) : /* @__PURE__ */ React71.createElement(
5724
5775
  "button",
5725
5776
  {
5726
5777
  onClick: () => treeNav.navigateTo(i),
@@ -5730,18 +5781,18 @@ var ArtifactsPanel = React69.forwardRef(
5730
5781
  ));
5731
5782
  })
5732
5783
  ),
5733
- /* @__PURE__ */ React69.createElement(
5784
+ /* @__PURE__ */ React71.createElement(
5734
5785
  "div",
5735
5786
  {
5736
5787
  className: "flex-1 overflow-auto relative",
5737
5788
  "data-testid": "artifacts-scroll-area"
5738
5789
  },
5739
- /* @__PURE__ */ React69.createElement(
5790
+ /* @__PURE__ */ React71.createElement(
5740
5791
  "div",
5741
5792
  {
5742
5793
  style: currentZoom !== 1 && contentHeight !== void 0 ? { height: contentHeight * currentZoom } : void 0
5743
5794
  },
5744
- /* @__PURE__ */ React69.createElement(
5795
+ /* @__PURE__ */ React71.createElement(
5745
5796
  "div",
5746
5797
  {
5747
5798
  ref: contentRef,
@@ -5752,7 +5803,7 @@ var ArtifactsPanel = React69.forwardRef(
5752
5803
  transformOrigin: "top center"
5753
5804
  } : void 0
5754
5805
  },
5755
- treeNav.currentNodes.length === 0 ? /* @__PURE__ */ React69.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, hasNodes ? "Empty group" : "No artifacts to display") : treeNav.currentNodes.map((node) => /* @__PURE__ */ React69.createElement(
5806
+ treeNav.currentNodes.length === 0 ? /* @__PURE__ */ React71.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, hasNodes ? "Empty group" : "No artifacts to display") : treeNav.currentNodes.map((node) => /* @__PURE__ */ React71.createElement(
5756
5807
  NodeRenderer,
5757
5808
  {
5758
5809
  key: node.id,
@@ -5765,7 +5816,7 @@ var ArtifactsPanel = React69.forwardRef(
5765
5816
  )
5766
5817
  )
5767
5818
  )
5768
- ), expandedArtifact && /* @__PURE__ */ React69.createElement(
5819
+ ), expandedArtifact && /* @__PURE__ */ React71.createElement(
5769
5820
  ArtifactModal,
5770
5821
  {
5771
5822
  artifact: expandedArtifact,
@@ -5775,8 +5826,8 @@ var ArtifactsPanel = React69.forwardRef(
5775
5826
  }
5776
5827
  );
5777
5828
  ArtifactsPanel.displayName = "ArtifactsPanel";
5778
- var ArtifactsPanelToggle = React69.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
5779
- return /* @__PURE__ */ React69.createElement(
5829
+ var ArtifactsPanelToggle = React71.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
5830
+ return /* @__PURE__ */ React71.createElement(
5780
5831
  "button",
5781
5832
  {
5782
5833
  ref,
@@ -5793,8 +5844,8 @@ var ArtifactsPanelToggle = React69.forwardRef(({ artifactCount = 0, onExpand, cl
5793
5844
  "aria-label": "Expand artifacts panel",
5794
5845
  ...rest
5795
5846
  },
5796
- /* @__PURE__ */ React69.createElement(Image, { className: "w-5 h-5", "aria-hidden": true }),
5797
- artifactCount > 0 && /* @__PURE__ */ React69.createElement(
5847
+ /* @__PURE__ */ React71.createElement(Image, { className: "w-5 h-5", "aria-hidden": true }),
5848
+ artifactCount > 0 && /* @__PURE__ */ React71.createElement(
5798
5849
  "span",
5799
5850
  {
5800
5851
  className: "absolute -top-1 -right-1 w-4 h-4 bg-gold text-obsidian text-xs font-medium flex items-center justify-center"
@@ -5806,7 +5857,7 @@ var ArtifactsPanelToggle = React69.forwardRef(({ artifactCount = 0, onExpand, cl
5806
5857
  ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
5807
5858
 
5808
5859
  // src/components/chat/HistoryPanel.tsx
5809
- import React70, { useCallback as useCallback18, useEffect as useEffect13, useMemo as useMemo3, useRef as useRef12, useState as useState18 } from "react";
5860
+ import React72, { useCallback as useCallback18, useEffect as useEffect13, useMemo as useMemo3, useRef as useRef12, useState as useState18 } from "react";
5810
5861
  import { ChevronDown as ChevronDown2, Pencil as Pencil2 } from "lucide-react";
5811
5862
  function parseTimestamp(ts) {
5812
5863
  if (ts == null) {
@@ -5854,7 +5905,7 @@ function ProjectFilter({
5854
5905
  const closeFilter = useCallback18(() => setOpen(false), []);
5855
5906
  useClickOutside(ref, closeFilter, open);
5856
5907
  const label = value ?? "All projects";
5857
- return /* @__PURE__ */ React70.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ React70.createElement(
5908
+ return /* @__PURE__ */ React72.createElement("div", { className: cx("relative min-w-0", className), ref }, /* @__PURE__ */ React72.createElement(
5858
5909
  "button",
5859
5910
  {
5860
5911
  type: "button",
@@ -5870,9 +5921,9 @@ function ProjectFilter({
5870
5921
  "transition-colors duration-150 min-w-0"
5871
5922
  )
5872
5923
  },
5873
- /* @__PURE__ */ React70.createElement("span", { className: "truncate" }, label),
5874
- /* @__PURE__ */ React70.createElement(ChevronDown2, { className: "w-3 h-3 shrink-0", "aria-hidden": true })
5875
- ), open && /* @__PURE__ */ React70.createElement(
5924
+ /* @__PURE__ */ React72.createElement("span", { className: "truncate" }, label),
5925
+ /* @__PURE__ */ React72.createElement(ChevronDown2, { className: "w-3 h-3 shrink-0", "aria-hidden": true })
5926
+ ), open && /* @__PURE__ */ React72.createElement(
5876
5927
  "div",
5877
5928
  {
5878
5929
  role: "listbox",
@@ -5882,7 +5933,7 @@ function ProjectFilter({
5882
5933
  "max-h-60 overflow-y-auto"
5883
5934
  )
5884
5935
  },
5885
- /* @__PURE__ */ React70.createElement(
5936
+ /* @__PURE__ */ React72.createElement(
5886
5937
  "button",
5887
5938
  {
5888
5939
  type: "button",
@@ -5900,7 +5951,7 @@ function ProjectFilter({
5900
5951
  },
5901
5952
  "All projects"
5902
5953
  ),
5903
- projects.map((p) => /* @__PURE__ */ React70.createElement(
5954
+ projects.map((p) => /* @__PURE__ */ React72.createElement(
5904
5955
  "button",
5905
5956
  {
5906
5957
  key: p,
@@ -5952,7 +6003,7 @@ function ConversationRow({
5952
6003
  setIsEditing(false);
5953
6004
  }, [conversation.title]);
5954
6005
  if (isEditing) {
5955
- return /* @__PURE__ */ React70.createElement(
6006
+ return /* @__PURE__ */ React72.createElement(
5956
6007
  "div",
5957
6008
  {
5958
6009
  className: cx(
@@ -5960,7 +6011,7 @@ function ConversationRow({
5960
6011
  conversation.isActive ? "bg-ash/40" : "bg-ash/20"
5961
6012
  )
5962
6013
  },
5963
- /* @__PURE__ */ React70.createElement(
6014
+ /* @__PURE__ */ React72.createElement(
5964
6015
  "input",
5965
6016
  {
5966
6017
  ref: inputRef,
@@ -5985,10 +6036,10 @@ function ConversationRow({
5985
6036
  "aria-label": "Conversation title"
5986
6037
  }
5987
6038
  ),
5988
- conversation.project && /* @__PURE__ */ React70.createElement("p", { className: "text-xs text-silver/60 truncate mt-1" }, conversation.project)
6039
+ conversation.project && /* @__PURE__ */ React72.createElement("p", { className: "text-xs text-silver/60 truncate mt-1" }, conversation.project)
5989
6040
  );
5990
6041
  }
5991
- return /* @__PURE__ */ React70.createElement("div", { className: "relative group" }, /* @__PURE__ */ React70.createElement(
6042
+ return /* @__PURE__ */ React72.createElement("div", { className: "relative group" }, /* @__PURE__ */ React72.createElement(
5992
6043
  "button",
5993
6044
  {
5994
6045
  onClick: () => onSelect?.(conversation.id),
@@ -5998,7 +6049,7 @@ function ConversationRow({
5998
6049
  conversation.isActive ? "bg-ash/40 text-white" : "text-silver hover:bg-ash/20 hover:text-white"
5999
6050
  )
6000
6051
  },
6001
- /* @__PURE__ */ React70.createElement(
6052
+ /* @__PURE__ */ React72.createElement(
6002
6053
  "p",
6003
6054
  {
6004
6055
  className: cx(
@@ -6008,8 +6059,8 @@ function ConversationRow({
6008
6059
  },
6009
6060
  conversation.title
6010
6061
  ),
6011
- conversation.project && /* @__PURE__ */ React70.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.project)
6012
- ), onRename && /* @__PURE__ */ React70.createElement(
6062
+ conversation.project && /* @__PURE__ */ React72.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.project)
6063
+ ), onRename && /* @__PURE__ */ React72.createElement(
6013
6064
  "button",
6014
6065
  {
6015
6066
  type: "button",
@@ -6022,7 +6073,7 @@ function ConversationRow({
6022
6073
  "transition-opacity duration-150"
6023
6074
  )
6024
6075
  },
6025
- /* @__PURE__ */ React70.createElement(Pencil2, { className: "w-3.5 h-3.5", "aria-hidden": true })
6076
+ /* @__PURE__ */ React72.createElement(Pencil2, { className: "w-3.5 h-3.5", "aria-hidden": true })
6026
6077
  ));
6027
6078
  }
6028
6079
  function HistoryPanel({
@@ -6057,7 +6108,7 @@ function HistoryPanel({
6057
6108
  [filteredConversations]
6058
6109
  );
6059
6110
  const hasFilter = projects.length > 0;
6060
- return /* @__PURE__ */ React70.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ React70.createElement("div", { className: "px-4 py-3 border-b border-ash/40 shrink-0 flex items-center gap-2" }, /* @__PURE__ */ React70.createElement("h3", { className: "text-xs font-medium text-white shrink-0" }, "History"), (hasFilter || onNewChat) && /* @__PURE__ */ React70.createElement("div", { className: "flex items-center gap-2 flex-1 min-w-0" }, hasFilter && /* @__PURE__ */ React70.createElement(React70.Fragment, null, /* @__PURE__ */ React70.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ React70.createElement(
6111
+ return /* @__PURE__ */ React72.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ React72.createElement("div", { className: "px-4 py-3 border-b border-ash/40 shrink-0 flex items-center gap-2" }, /* @__PURE__ */ React72.createElement("h3", { className: "text-xs font-medium text-white shrink-0" }, "History"), (hasFilter || onNewChat) && /* @__PURE__ */ React72.createElement("div", { className: "flex items-center gap-2 flex-1 min-w-0" }, hasFilter && /* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ React72.createElement(
6061
6112
  ProjectFilter,
6062
6113
  {
6063
6114
  projects,
@@ -6065,7 +6116,7 @@ function HistoryPanel({
6065
6116
  onChange: setProjectFilter,
6066
6117
  className: "flex-1"
6067
6118
  }
6068
- )), onNewChat && /* @__PURE__ */ React70.createElement(React70.Fragment, null, /* @__PURE__ */ React70.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ React70.createElement(
6119
+ )), onNewChat && /* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("div", { className: "w-px h-3 bg-ash/40 shrink-0 mx-1" }), /* @__PURE__ */ React72.createElement(
6069
6120
  "button",
6070
6121
  {
6071
6122
  onClick: onNewChat,
@@ -6077,15 +6128,15 @@ function HistoryPanel({
6077
6128
  "transition-colors duration-200"
6078
6129
  )
6079
6130
  },
6080
- /* @__PURE__ */ React70.createElement(PlusIcon, { className: "w-4 h-4" }),
6081
- /* @__PURE__ */ React70.createElement("span", { className: "truncate" }, "New Chat")
6082
- )))), /* @__PURE__ */ React70.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ React70.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations yet") : groups.length === 0 ? /* @__PURE__ */ React70.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations match this filter") : /* @__PURE__ */ React70.createElement("div", null, groups.map((group, index) => /* @__PURE__ */ React70.createElement("section", { key: group.key, className: cx(index > 0 && "mt-3") }, /* @__PURE__ */ React70.createElement("div", { className: "flex items-center gap-2 px-3 pb-2" }, /* @__PURE__ */ React70.createElement(
6131
+ /* @__PURE__ */ React72.createElement(PlusIcon, { className: "w-4 h-4" }),
6132
+ /* @__PURE__ */ React72.createElement("span", { className: "truncate" }, "New Chat")
6133
+ )))), /* @__PURE__ */ React72.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ React72.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations yet") : groups.length === 0 ? /* @__PURE__ */ React72.createElement("p", { className: "px-4 py-2 text-xs text-silver/60" }, "No conversations match this filter") : /* @__PURE__ */ React72.createElement("div", null, groups.map((group, index) => /* @__PURE__ */ React72.createElement("section", { key: group.key, className: cx(index > 0 && "mt-3") }, /* @__PURE__ */ React72.createElement("div", { className: "flex items-center gap-2 px-3 pb-2" }, /* @__PURE__ */ React72.createElement(
6083
6134
  "span",
6084
6135
  {
6085
6136
  className: "text-xs font-medium uppercase tracking-wider text-gold/70"
6086
6137
  },
6087
6138
  group.label
6088
- ), /* @__PURE__ */ React70.createElement("div", { className: "flex-1 h-px bg-gold/20" })), /* @__PURE__ */ React70.createElement("div", { className: "space-y-1 px-2" }, group.conversations.map((conversation) => /* @__PURE__ */ React70.createElement(
6139
+ ), /* @__PURE__ */ React72.createElement("div", { className: "flex-1 h-px bg-gold/20" })), /* @__PURE__ */ React72.createElement("div", { className: "space-y-1 px-2" }, group.conversations.map((conversation) => /* @__PURE__ */ React72.createElement(
6089
6140
  ConversationRow,
6090
6141
  {
6091
6142
  key: conversation.id,
@@ -6097,7 +6148,7 @@ function HistoryPanel({
6097
6148
  }
6098
6149
 
6099
6150
  // src/components/chat/TodosList.tsx
6100
- import React71, { useCallback as useCallback19, useMemo as useMemo4, useState as useState19 } from "react";
6151
+ import React73, { useCallback as useCallback19, useMemo as useMemo4, useState as useState19 } from "react";
6101
6152
  import { Loader2 as Loader22, Square as Square2 } from "lucide-react";
6102
6153
  var TASK_STATUSES = {
6103
6154
  PENDING: "pending",
@@ -6109,16 +6160,16 @@ var TASK_STATUSES = {
6109
6160
  function TaskIcon({ status }) {
6110
6161
  switch (status) {
6111
6162
  case "done":
6112
- return /* @__PURE__ */ React71.createElement(CheckSquareIcon, null);
6163
+ return /* @__PURE__ */ React73.createElement(CheckSquareIcon, null);
6113
6164
  case "in_progress":
6114
- return /* @__PURE__ */ React71.createElement(SquareLoaderIcon, null);
6165
+ return /* @__PURE__ */ React73.createElement(SquareLoaderIcon, null);
6115
6166
  case "cancelled":
6116
- return /* @__PURE__ */ React71.createElement(CrossSquareIcon, { variant: "cancelled" });
6167
+ return /* @__PURE__ */ React73.createElement(CrossSquareIcon, { variant: "cancelled" });
6117
6168
  case "failed":
6118
- return /* @__PURE__ */ React71.createElement(CrossSquareIcon, { variant: "failed" });
6169
+ return /* @__PURE__ */ React73.createElement(CrossSquareIcon, { variant: "failed" });
6119
6170
  case "pending":
6120
6171
  default:
6121
- return /* @__PURE__ */ React71.createElement(EmptySquareIcon, null);
6172
+ return /* @__PURE__ */ React73.createElement(EmptySquareIcon, null);
6122
6173
  }
6123
6174
  }
6124
6175
  function sortTasks(tasks) {
@@ -6138,14 +6189,14 @@ function TaskItem({ task, depth = 0 }) {
6138
6189
  const isSubtle = task.status === "cancelled" || task.status === "failed";
6139
6190
  const showSubtasks = task.subtasks && task.subtasks.length > 0;
6140
6191
  const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
6141
- return /* @__PURE__ */ React71.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React71.createElement(
6192
+ return /* @__PURE__ */ React73.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React73.createElement(
6142
6193
  "div",
6143
6194
  {
6144
6195
  className: "flex items-center gap-2 py-1",
6145
6196
  style: { paddingLeft: `${depth * 1.5}rem` }
6146
6197
  },
6147
- /* @__PURE__ */ React71.createElement(TaskIcon, { status: task.status }),
6148
- /* @__PURE__ */ React71.createElement(
6198
+ /* @__PURE__ */ React73.createElement(TaskIcon, { status: task.status }),
6199
+ /* @__PURE__ */ React73.createElement(
6149
6200
  "span",
6150
6201
  {
6151
6202
  className: cx(
@@ -6157,10 +6208,10 @@ function TaskItem({ task, depth = 0 }) {
6157
6208
  )
6158
6209
  },
6159
6210
  task.label,
6160
- task.status === "cancelled" && /* @__PURE__ */ React71.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
6161
- task.status === "failed" && /* @__PURE__ */ React71.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
6211
+ task.status === "cancelled" && /* @__PURE__ */ React73.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
6212
+ task.status === "failed" && /* @__PURE__ */ React73.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
6162
6213
  )
6163
- ), showSubtasks && /* @__PURE__ */ React71.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ React71.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
6214
+ ), showSubtasks && /* @__PURE__ */ React73.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ React73.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
6164
6215
  }
6165
6216
  function hasInProgressTask(tasks) {
6166
6217
  return tasks.some((t) => {
@@ -6173,7 +6224,7 @@ function hasInProgressTask(tasks) {
6173
6224
  return false;
6174
6225
  });
6175
6226
  }
6176
- var TodosList = React71.forwardRef(
6227
+ var TodosList = React73.forwardRef(
6177
6228
  ({ tasks, title = "Tasks", onStopAllTasks, className, ...rest }, ref) => {
6178
6229
  const sortedTasks = useMemo4(() => sortTasks(tasks), [tasks]);
6179
6230
  const [isStopping, setIsStopping] = useState19(false);
@@ -6198,7 +6249,7 @@ var TodosList = React71.forwardRef(
6198
6249
  if (tasks.length === 0) {
6199
6250
  return null;
6200
6251
  }
6201
- return /* @__PURE__ */ React71.createElement(
6252
+ return /* @__PURE__ */ React73.createElement(
6202
6253
  "div",
6203
6254
  {
6204
6255
  ref,
@@ -6209,16 +6260,16 @@ var TodosList = React71.forwardRef(
6209
6260
  ),
6210
6261
  ...rest
6211
6262
  },
6212
- /* @__PURE__ */ React71.createElement(
6263
+ /* @__PURE__ */ React73.createElement(
6213
6264
  "div",
6214
6265
  {
6215
6266
  className: "flex items-center justify-between px-4 py-2 border-b border-ash/40 flex-shrink-0"
6216
6267
  },
6217
- /* @__PURE__ */ React71.createElement("h4", { className: "text-xs font-medium text-white" }, title),
6218
- /* @__PURE__ */ React71.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
6268
+ /* @__PURE__ */ React73.createElement("h4", { className: "text-xs font-medium text-white" }, title),
6269
+ /* @__PURE__ */ React73.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
6219
6270
  ),
6220
- /* @__PURE__ */ React71.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ React71.createElement(TaskItem, { key: task.id, task }))),
6221
- showStopButton && /* @__PURE__ */ React71.createElement("div", { className: "px-4 py-2 border-t border-ash/40 flex-shrink-0" }, /* @__PURE__ */ React71.createElement(
6271
+ /* @__PURE__ */ React73.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ React73.createElement(TaskItem, { key: task.id, task }))),
6272
+ showStopButton && /* @__PURE__ */ React73.createElement("div", { className: "px-4 py-2 border-t border-ash/40 flex-shrink-0" }, /* @__PURE__ */ React73.createElement(
6222
6273
  "button",
6223
6274
  {
6224
6275
  type: "button",
@@ -6235,7 +6286,7 @@ var TodosList = React71.forwardRef(
6235
6286
  isStopping ? "cursor-not-allowed opacity-70" : "hover:bg-error/20"
6236
6287
  )
6237
6288
  },
6238
- isStopping ? /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(Loader22, { className: "w-3 h-3 animate-spin" }), "Stopping tasks") : /* @__PURE__ */ React71.createElement(React71.Fragment, null, /* @__PURE__ */ React71.createElement(Square2, { className: "w-3 h-3 fill-current" }), "Stop All Tasks")
6289
+ isStopping ? /* @__PURE__ */ React73.createElement(React73.Fragment, null, /* @__PURE__ */ React73.createElement(Loader22, { className: "w-3 h-3 animate-spin" }), "Stopping tasks") : /* @__PURE__ */ React73.createElement(React73.Fragment, null, /* @__PURE__ */ React73.createElement(Square2, { className: "w-3 h-3 fill-current" }), "Stop All Tasks")
6239
6290
  ))
6240
6291
  );
6241
6292
  }
@@ -6255,8 +6306,8 @@ function areAllTasksSettled(tasks) {
6255
6306
  }
6256
6307
 
6257
6308
  // src/components/chat/ToolSidebar.tsx
6258
- import React72 from "react";
6259
- var ToolSidebar = React72.forwardRef(
6309
+ import React74 from "react";
6310
+ var ToolSidebar = React74.forwardRef(
6260
6311
  ({ tools, activeTools, onToggleTool, side, className, ...rest }, ref) => {
6261
6312
  const topTools = tools.filter((t) => t.group === `top-${side}`);
6262
6313
  const bottomTools = tools.filter((t) => t.group === `bottom-${side}`);
@@ -6267,7 +6318,7 @@ var ToolSidebar = React72.forwardRef(
6267
6318
  };
6268
6319
  const renderButton = (tool) => {
6269
6320
  const active = isActive(tool.id);
6270
- return /* @__PURE__ */ React72.createElement(
6321
+ return /* @__PURE__ */ React74.createElement(
6271
6322
  "button",
6272
6323
  {
6273
6324
  key: tool.id,
@@ -6279,10 +6330,10 @@ var ToolSidebar = React72.forwardRef(
6279
6330
  "aria-label": tool.label,
6280
6331
  "aria-pressed": active
6281
6332
  },
6282
- /* @__PURE__ */ React72.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
6333
+ /* @__PURE__ */ React74.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
6283
6334
  );
6284
6335
  };
6285
- return /* @__PURE__ */ React72.createElement(
6336
+ return /* @__PURE__ */ React74.createElement(
6286
6337
  "div",
6287
6338
  {
6288
6339
  ref,
@@ -6293,17 +6344,17 @@ var ToolSidebar = React72.forwardRef(
6293
6344
  ),
6294
6345
  ...rest
6295
6346
  },
6296
- /* @__PURE__ */ React72.createElement("div", { className: "flex flex-col items-center gap-1" }, topTools.map(renderButton)),
6297
- /* @__PURE__ */ React72.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ React72.createElement("div", { className: "w-5 border-t border-ash/30" })),
6298
- /* @__PURE__ */ React72.createElement("div", { className: "flex flex-col items-center gap-1" }, bottomTools.map(renderButton))
6347
+ /* @__PURE__ */ React74.createElement("div", { className: "flex flex-col items-center gap-1" }, topTools.map(renderButton)),
6348
+ /* @__PURE__ */ React74.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ React74.createElement("div", { className: "w-5 border-t border-ash/30" })),
6349
+ /* @__PURE__ */ React74.createElement("div", { className: "flex flex-col items-center gap-1" }, bottomTools.map(renderButton))
6299
6350
  );
6300
6351
  }
6301
6352
  );
6302
6353
  ToolSidebar.displayName = "ToolSidebar";
6303
6354
 
6304
6355
  // src/components/chat/ToolPanelContainer.tsx
6305
- import React73, { useCallback as useCallback20, useEffect as useEffect14, useRef as useRef13, useState as useState20 } from "react";
6306
- var ToolPanelContainer = React73.forwardRef(
6356
+ import React75, { useCallback as useCallback20, useEffect as useEffect14, useRef as useRef13, useState as useState20 } from "react";
6357
+ var ToolPanelContainer = React75.forwardRef(
6307
6358
  ({
6308
6359
  topContent,
6309
6360
  bottomContent,
@@ -6366,7 +6417,7 @@ var ToolPanelContainer = React73.forwardRef(
6366
6417
  document.body.style.userSelect = "";
6367
6418
  };
6368
6419
  }, [isResizingHeight, resizeHeight, stopHeightResize]);
6369
- return /* @__PURE__ */ React73.createElement(
6420
+ return /* @__PURE__ */ React75.createElement(
6370
6421
  "div",
6371
6422
  {
6372
6423
  ref: composeRefs(containerRef, ref),
@@ -6378,7 +6429,7 @@ var ToolPanelContainer = React73.forwardRef(
6378
6429
  style: width ? { width } : void 0,
6379
6430
  ...rest
6380
6431
  },
6381
- /* @__PURE__ */ React73.createElement(
6432
+ /* @__PURE__ */ React75.createElement(
6382
6433
  "div",
6383
6434
  {
6384
6435
  onMouseDown: onResizeStart,
@@ -6389,7 +6440,7 @@ var ToolPanelContainer = React73.forwardRef(
6389
6440
  )
6390
6441
  }
6391
6442
  ),
6392
- topContent !== null && /* @__PURE__ */ React73.createElement(
6443
+ topContent !== null && /* @__PURE__ */ React75.createElement(
6393
6444
  "div",
6394
6445
  {
6395
6446
  className: "min-h-0 overflow-hidden flex flex-col",
@@ -6397,7 +6448,7 @@ var ToolPanelContainer = React73.forwardRef(
6397
6448
  },
6398
6449
  topContent
6399
6450
  ),
6400
- hasBoth && /* @__PURE__ */ React73.createElement(
6451
+ hasBoth && /* @__PURE__ */ React75.createElement(
6401
6452
  "div",
6402
6453
  {
6403
6454
  onMouseDown: startHeightResize,
@@ -6409,7 +6460,7 @@ var ToolPanelContainer = React73.forwardRef(
6409
6460
  )
6410
6461
  }
6411
6462
  ),
6412
- bottomContent !== null && /* @__PURE__ */ React73.createElement(
6463
+ bottomContent !== null && /* @__PURE__ */ React75.createElement(
6413
6464
  "div",
6414
6465
  {
6415
6466
  className: "min-h-0 overflow-hidden flex flex-col",
@@ -6481,8 +6532,150 @@ function useResizable({
6481
6532
  return { width, widthPercent, isResizing, startResizing };
6482
6533
  }
6483
6534
 
6535
+ // src/components/chat/tree.ts
6536
+ function createEmptyTree() {
6537
+ return { nodes: {}, rootIds: [], activeLeafId: null, lastLeafId: null };
6538
+ }
6539
+ function addNodeToTree(tree, node, parentId = null) {
6540
+ const newNodes = { ...tree.nodes };
6541
+ const newRootIds = [...tree.rootIds];
6542
+ const branchIndex = parentId ? newNodes[parentId]?.children.length ?? 0 : newRootIds.length;
6543
+ newNodes[node.id] = {
6544
+ ...node,
6545
+ parentId,
6546
+ children: [],
6547
+ branchIndex,
6548
+ createdAt: node.createdAt ?? Date.now()
6549
+ };
6550
+ if (parentId && newNodes[parentId]) {
6551
+ newNodes[parentId] = {
6552
+ ...newNodes[parentId],
6553
+ children: [...newNodes[parentId].children, node.id]
6554
+ };
6555
+ } else {
6556
+ newRootIds.push(node.id);
6557
+ }
6558
+ return {
6559
+ nodes: newNodes,
6560
+ rootIds: newRootIds,
6561
+ activeLeafId: node.id,
6562
+ lastLeafId: node.id
6563
+ };
6564
+ }
6565
+ function getActivePath(tree) {
6566
+ return walkUp(tree, tree.activeLeafId).reverse();
6567
+ }
6568
+ function findAncestor(tree, fromId, predicate) {
6569
+ let id = fromId;
6570
+ while (id) {
6571
+ const node = tree.nodes[id];
6572
+ if (!node) return null;
6573
+ if (predicate(node)) return node;
6574
+ id = node.parentId;
6575
+ }
6576
+ return null;
6577
+ }
6578
+ function getSiblingInfo(tree, nodeId) {
6579
+ const siblings = siblingsOf(tree, nodeId);
6580
+ const index = siblings.indexOf(nodeId);
6581
+ if (index < 0) return { total: 1, current: 1 };
6582
+ return { total: siblings.length, current: index + 1 };
6583
+ }
6584
+ function isBranchPoint(tree, nodeId) {
6585
+ return (tree.nodes[nodeId]?.children.length ?? 0) > 1;
6586
+ }
6587
+ function switchBranch(tree, nodeId, direction) {
6588
+ const siblings = siblingsOf(tree, nodeId);
6589
+ if (siblings.length <= 1) return tree;
6590
+ const currentIndex = siblings.indexOf(nodeId);
6591
+ const newIndex = direction === "next" ? (currentIndex + 1) % siblings.length : (currentIndex - 1 + siblings.length) % siblings.length;
6592
+ const leafId = deepestLeafOf(tree, siblings[newIndex]);
6593
+ return { ...tree, activeLeafId: leafId, lastLeafId: leafId };
6594
+ }
6595
+ function setActiveLeaf(tree, leafId) {
6596
+ if (!leafId || !tree.nodes[leafId]) {
6597
+ return { ...tree, activeLeafId: leafId, lastLeafId: leafId };
6598
+ }
6599
+ const lastLeafId = tree.lastLeafId && isAncestor(tree, leafId, tree.lastLeafId) ? tree.lastLeafId : leafId;
6600
+ return { ...tree, activeLeafId: leafId, lastLeafId };
6601
+ }
6602
+ function getGreyedFuture(tree) {
6603
+ const { activeLeafId, lastLeafId } = tree;
6604
+ if (!activeLeafId || !lastLeafId || activeLeafId === lastLeafId) return [];
6605
+ const path = [];
6606
+ let id = lastLeafId;
6607
+ while (id && id !== activeLeafId) {
6608
+ const node = tree.nodes[id];
6609
+ if (!node) return [];
6610
+ path.unshift(node);
6611
+ id = node.parentId;
6612
+ }
6613
+ return id === activeLeafId ? path : [];
6614
+ }
6615
+ function messagesToTree(messages) {
6616
+ let tree = createEmptyTree();
6617
+ for (const msg of messages) {
6618
+ const parentId = tree.activeLeafId;
6619
+ tree = addNodeToTree(
6620
+ tree,
6621
+ { ...msg, kind: "message", parentId },
6622
+ parentId
6623
+ );
6624
+ }
6625
+ return tree;
6626
+ }
6627
+ function updateMessageContent(tree, nodeId, content, isStreaming) {
6628
+ const node = tree.nodes[nodeId];
6629
+ if (!node || node.kind !== "message") return tree;
6630
+ const updated = {
6631
+ ...node,
6632
+ content,
6633
+ isStreaming: isStreaming ?? node.isStreaming
6634
+ };
6635
+ return {
6636
+ ...tree,
6637
+ nodes: {
6638
+ ...tree.nodes,
6639
+ [nodeId]: updated
6640
+ }
6641
+ };
6642
+ }
6643
+ function walkUp(tree, fromId) {
6644
+ const out = [];
6645
+ let id = fromId;
6646
+ while (id) {
6647
+ const node = tree.nodes[id];
6648
+ if (!node) break;
6649
+ out.push(node);
6650
+ id = node.parentId;
6651
+ }
6652
+ return out;
6653
+ }
6654
+ function siblingsOf(tree, nodeId) {
6655
+ const node = tree.nodes[nodeId];
6656
+ if (!node) return [];
6657
+ return node.parentId ? tree.nodes[node.parentId]?.children ?? [] : tree.rootIds;
6658
+ }
6659
+ function deepestLeafOf(tree, nodeId) {
6660
+ let id = nodeId;
6661
+ let node = tree.nodes[id];
6662
+ while (node && node.children.length > 0) {
6663
+ id = node.children[node.children.length - 1];
6664
+ node = tree.nodes[id];
6665
+ }
6666
+ return id;
6667
+ }
6668
+ function isAncestor(tree, ancestorId, descendantId) {
6669
+ let id = descendantId;
6670
+ while (id) {
6671
+ if (id === ancestorId) return true;
6672
+ id = tree.nodes[id]?.parentId ?? null;
6673
+ }
6674
+ return false;
6675
+ }
6676
+
6484
6677
  // src/components/chat/ChatInterface.tsx
6485
- var ChatInterface = React74.forwardRef(
6678
+ var ChatInterface = React76.forwardRef(
6486
6679
  ({
6487
6680
  messages = [],
6488
6681
  conversationTree,
@@ -6491,6 +6684,8 @@ var ChatInterface = React74.forwardRef(
6491
6684
  onMessageSubmit,
6492
6685
  onEditMessage,
6493
6686
  onRetryMessage,
6687
+ onJumpToCheckpoint,
6688
+ onJumpToLatest,
6494
6689
  onStop,
6495
6690
  onSelectConversation,
6496
6691
  onNewChat,
@@ -6561,11 +6756,11 @@ var ChatInterface = React74.forwardRef(
6561
6756
  const allSettled = tasks.length === 0 || areAllTasksSettled(tasks);
6562
6757
  const allToolDefinitions = useMemo5(() => {
6563
6758
  const builtIn = [
6564
- { id: "history", icon: /* @__PURE__ */ React74.createElement(ChatBubbleIcon, null), label: "History", group: "top-left" },
6565
- { id: "artifacts", icon: /* @__PURE__ */ React74.createElement(MediaIcon, null), label: "Artifacts", group: "top-right" },
6759
+ { id: "history", icon: /* @__PURE__ */ React76.createElement(ChatBubbleIcon, null), label: "History", group: "top-left" },
6760
+ { id: "artifacts", icon: /* @__PURE__ */ React76.createElement(MediaIcon, null), label: "Artifacts", group: "top-right" },
6566
6761
  {
6567
6762
  id: "todos",
6568
- icon: allSettled ? /* @__PURE__ */ React74.createElement(CheckSquareIcon, null) : /* @__PURE__ */ React74.createElement(SquareLoaderIcon, null),
6763
+ icon: allSettled ? /* @__PURE__ */ React76.createElement(CheckSquareIcon, null) : /* @__PURE__ */ React76.createElement(SquareLoaderIcon, null),
6569
6764
  label: "Tasks",
6570
6765
  group: "bottom-right"
6571
6766
  }
@@ -6603,20 +6798,24 @@ var ChatInterface = React74.forwardRef(
6603
6798
  });
6604
6799
  }, [allToolDefinitions, isPanelControlled, activeTools, onArtifactsPanelOpenChange]);
6605
6800
  const isTreeMode = !!conversationTree;
6606
- const effectiveMessages = useMemo5(() => {
6607
- if (isTreeMode && conversationTree) {
6608
- return getActivePathMessages(conversationTree);
6609
- }
6610
- return messages || [];
6611
- }, [isTreeMode, conversationTree, messages]);
6612
- const latestUserMessageIndex = useMemo5(() => {
6613
- for (let i = effectiveMessages.length - 1; i >= 0; i--) {
6614
- if (effectiveMessages[i].role === "user") {
6615
- return i;
6616
- }
6617
- }
6618
- return -1;
6619
- }, [effectiveMessages]);
6801
+ const tree = isTreeMode ? conversationTree : null;
6802
+ const activePath = useMemo5(() => {
6803
+ if (tree) return getActivePath(tree);
6804
+ return (messages || []).map((m) => ({ ...m, children: [], branchIndex: 0 }));
6805
+ }, [tree, messages]);
6806
+ const greyedFuture = useMemo5(
6807
+ () => tree ? getGreyedFuture(tree) : [],
6808
+ [tree]
6809
+ );
6810
+ const activeCheckpointId = useMemo5(() => {
6811
+ if (!tree) return null;
6812
+ const found = findAncestor(
6813
+ tree,
6814
+ tree.activeLeafId,
6815
+ (n) => n.kind === "checkpoint"
6816
+ );
6817
+ return found?.id ?? null;
6818
+ }, [tree]);
6620
6819
  useEffect16(() => {
6621
6820
  const nodes = artifactNodes || [];
6622
6821
  const prevNodes = prevArtifactNodesRef.current;
@@ -6644,64 +6843,113 @@ var ChatInterface = React74.forwardRef(
6644
6843
  }, [artifactNodes, tasks, isPanelControlled]);
6645
6844
  const handleBranchSwitch = useCallback22(
6646
6845
  (nodeId, direction) => {
6647
- if (!isTreeMode || !conversationTree || !onTreeChange) {
6846
+ if (!tree || !onTreeChange) {
6648
6847
  return;
6649
6848
  }
6650
- const newTree = switchBranch(conversationTree, nodeId, direction);
6651
- onTreeChange(newTree);
6849
+ onTreeChange(switchBranch(tree, nodeId, direction));
6652
6850
  },
6653
- [isTreeMode, conversationTree, onTreeChange]
6851
+ [tree, onTreeChange]
6654
6852
  );
6655
- const displayMessages = useMemo5(() => {
6656
- return effectiveMessages.map((msg) => {
6657
- let branchInfo = void 0;
6658
- if (isTreeMode && conversationTree) {
6659
- const siblingInfo = getSiblingInfo(conversationTree, msg.id);
6660
- if (siblingInfo.total > 1) {
6661
- branchInfo = {
6662
- current: siblingInfo.current,
6663
- total: siblingInfo.total,
6664
- onPrevious: () => handleBranchSwitch(msg.id, "prev"),
6665
- onNext: () => handleBranchSwitch(msg.id, "next")
6666
- };
6667
- }
6853
+ const handleJumpToCheckpoint = useCallback22((checkpointId) => {
6854
+ if (!tree) return;
6855
+ if (onJumpToCheckpoint) {
6856
+ onJumpToCheckpoint(checkpointId);
6857
+ return;
6858
+ }
6859
+ if (onTreeChange) {
6860
+ onTreeChange(setActiveLeaf(tree, checkpointId));
6861
+ }
6862
+ }, [tree, onTreeChange, onJumpToCheckpoint]);
6863
+ const handleJumpToLatest = useCallback22(() => {
6864
+ if (!tree) return;
6865
+ if (onJumpToLatest) {
6866
+ onJumpToLatest();
6867
+ return;
6868
+ }
6869
+ if (onTreeChange && tree.lastLeafId) {
6870
+ onTreeChange(setActiveLeaf(tree, tree.lastLeafId));
6871
+ }
6872
+ }, [tree, onTreeChange, onJumpToLatest]);
6873
+ const buildItem = useCallback22(
6874
+ (node, opts) => {
6875
+ const branchInfo = tree && getSiblingInfo(tree, node.id).total > 1 ? {
6876
+ ...getSiblingInfo(tree, node.id),
6877
+ onPrevious: () => handleBranchSwitch(node.id, "prev"),
6878
+ onNext: () => handleBranchSwitch(node.id, "next")
6879
+ } : void 0;
6880
+ if (node.kind === "checkpoint") {
6881
+ return {
6882
+ kind: "checkpoint",
6883
+ id: node.id,
6884
+ name: node.name,
6885
+ executionKind: node.executionKind,
6886
+ status: node.status,
6887
+ isActive: node.id === activeCheckpointId && !opts.muted,
6888
+ muted: opts.muted,
6889
+ branchInfo,
6890
+ onJumpHere: () => handleJumpToCheckpoint(node.id)
6891
+ };
6668
6892
  }
6669
6893
  const actions = enableMessageActions ? {
6670
6894
  showCopy: true,
6671
- onEdit: msg.role === "user" && onEditMessage ? (newContent) => onEditMessage(msg.id, newContent) : void 0,
6672
- onRetry: msg.role === "assistant" && onRetryMessage ? () => onRetryMessage(msg.id) : void 0
6895
+ onEdit: node.role === "user" && onEditMessage ? (newContent) => onEditMessage(node.id, newContent) : void 0,
6896
+ onRetry: node.role === "assistant" && onRetryMessage ? () => onRetryMessage(node.id) : void 0
6673
6897
  } : void 0;
6674
- const {
6675
- role,
6676
- parentId,
6677
- children,
6678
- branchIndex,
6679
- createdAt,
6680
- ...rest2
6681
- } = msg;
6682
6898
  return {
6683
- ...rest2,
6684
- variant: role,
6899
+ kind: "message",
6900
+ id: node.id,
6901
+ variant: node.role,
6902
+ content: node.content,
6903
+ isStreaming: node.isStreaming,
6904
+ muted: opts.muted,
6685
6905
  branchInfo,
6686
6906
  actions
6687
6907
  };
6688
- });
6689
- }, [
6690
- effectiveMessages,
6691
- isTreeMode,
6692
- conversationTree,
6693
- enableMessageActions,
6694
- onEditMessage,
6695
- onRetryMessage,
6696
- handleBranchSwitch
6697
- ]);
6908
+ },
6909
+ [
6910
+ tree,
6911
+ activeCheckpointId,
6912
+ enableMessageActions,
6913
+ onEditMessage,
6914
+ onRetryMessage,
6915
+ handleBranchSwitch,
6916
+ handleJumpToCheckpoint
6917
+ ]
6918
+ );
6919
+ const displayItems = useMemo5(() => {
6920
+ const items = activePath.map((n) => buildItem(n, { muted: false }));
6921
+ if (greyedFuture.length > 0) {
6922
+ const messageCount = greyedFuture.filter((n) => n.kind === "message").length;
6923
+ const checkpointCount = greyedFuture.filter((n) => n.kind === "checkpoint").length;
6924
+ items.push({
6925
+ kind: "divider",
6926
+ id: "__greyed_divider__",
6927
+ messageCount,
6928
+ checkpointCount,
6929
+ onJumpToLatest: handleJumpToLatest
6930
+ });
6931
+ for (const n of greyedFuture) {
6932
+ items.push(buildItem(n, { muted: true }));
6933
+ }
6934
+ }
6935
+ return items;
6936
+ }, [activePath, greyedFuture, buildItem, handleJumpToLatest]);
6937
+ const latestUserMessageIndex = useMemo5(() => {
6938
+ for (let i = displayItems.length - 1; i >= 0; i--) {
6939
+ const item = displayItems[i];
6940
+ if (item.kind === "message" && item.variant === "user" && !item.muted) {
6941
+ return i;
6942
+ }
6943
+ }
6944
+ return -1;
6945
+ }, [displayItems]);
6698
6946
  const handleSubmit = useCallback22(
6699
6947
  (message, attachments) => {
6700
6948
  onMessageSubmit?.(message, attachments);
6701
6949
  },
6702
6950
  [onMessageSubmit]
6703
6951
  );
6704
- const isEmpty = effectiveMessages.length === 0;
6952
+ const isEmpty = displayItems.length === 0;
6705
6953
  const leftToolDefs = useMemo5(
6706
6954
  () => allToolDefinitions.filter((t) => t.group === "top-left" || t.group === "bottom-left"),
6707
6955
  [allToolDefinitions]
@@ -6720,7 +6968,7 @@ var ChatInterface = React74.forwardRef(
6720
6968
  }
6721
6969
  switch (toolId) {
6722
6970
  case "history":
6723
- return /* @__PURE__ */ React74.createElement(
6971
+ return /* @__PURE__ */ React76.createElement(
6724
6972
  HistoryPanel,
6725
6973
  {
6726
6974
  conversations,
@@ -6730,7 +6978,7 @@ var ChatInterface = React74.forwardRef(
6730
6978
  }
6731
6979
  );
6732
6980
  case "artifacts":
6733
- return /* @__PURE__ */ React74.createElement(
6981
+ return /* @__PURE__ */ React76.createElement(
6734
6982
  ArtifactsPanel,
6735
6983
  {
6736
6984
  nodes: artifactNodes,
@@ -6738,7 +6986,7 @@ var ChatInterface = React74.forwardRef(
6738
6986
  }
6739
6987
  );
6740
6988
  case "todos":
6741
- return tasks.length > 0 ? /* @__PURE__ */ React74.createElement(
6989
+ return tasks.length > 0 ? /* @__PURE__ */ React76.createElement(
6742
6990
  TodosList,
6743
6991
  {
6744
6992
  tasks,
@@ -6746,21 +6994,21 @@ var ChatInterface = React74.forwardRef(
6746
6994
  onStopAllTasks,
6747
6995
  className: "h-full"
6748
6996
  }
6749
- ) : /* @__PURE__ */ React74.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ React74.createElement("div", { className: "flex items-center p-4 border-b border-ash/40 shrink-0" }, /* @__PURE__ */ React74.createElement("h3", { className: "text-xs font-medium text-white" }, "Tasks")), /* @__PURE__ */ React74.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ React74.createElement("p", { className: "text-xs text-silver/60" }, "No tasks")));
6997
+ ) : /* @__PURE__ */ React76.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ React76.createElement("div", { className: "flex items-center p-4 border-b border-ash/40 shrink-0" }, /* @__PURE__ */ React76.createElement("h3", { className: "text-xs font-medium text-white" }, "Tasks")), /* @__PURE__ */ React76.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ React76.createElement("p", { className: "text-xs text-silver/60" }, "No tasks")));
6750
6998
  default: {
6751
6999
  const externalTool = externalTools.find((t) => t.id === toolId);
6752
7000
  return externalTool?.content ?? null;
6753
7001
  }
6754
7002
  }
6755
7003
  };
6756
- return /* @__PURE__ */ React74.createElement(
7004
+ return /* @__PURE__ */ React76.createElement(
6757
7005
  "div",
6758
7006
  {
6759
7007
  ref,
6760
7008
  className: cx("flex h-full w-full bg-obsidian overflow-hidden", className),
6761
7009
  ...rest
6762
7010
  },
6763
- hasLeftTools && /* @__PURE__ */ React74.createElement(
7011
+ hasLeftTools && /* @__PURE__ */ React76.createElement(
6764
7012
  ToolSidebar,
6765
7013
  {
6766
7014
  tools: leftToolDefs,
@@ -6769,7 +7017,7 @@ var ChatInterface = React74.forwardRef(
6769
7017
  side: "left"
6770
7018
  }
6771
7019
  ),
6772
- isLeftPanelOpen && /* @__PURE__ */ React74.createElement(
7020
+ isLeftPanelOpen && /* @__PURE__ */ React76.createElement(
6773
7021
  ToolPanelContainer,
6774
7022
  {
6775
7023
  topContent: renderToolContent(activeTools["top-left"]),
@@ -6780,28 +7028,28 @@ var ChatInterface = React74.forwardRef(
6780
7028
  initialTopPercent: 30
6781
7029
  }
6782
7030
  ),
6783
- /* @__PURE__ */ React74.createElement("div", { className: "flex-1 flex flex-col min-w-0 relative" }, /* @__PURE__ */ React74.createElement("div", { className: cx(
7031
+ /* @__PURE__ */ React76.createElement("div", { className: "flex-1 flex flex-col min-w-0 relative" }, /* @__PURE__ */ React76.createElement("div", { className: cx(
6784
7032
  "flex-1 flex flex-col min-h-0 relative",
6785
7033
  isEmpty ? "justify-center" : "justify-start"
6786
- ) }, /* @__PURE__ */ React74.createElement("div", { className: cx(
7034
+ ) }, /* @__PURE__ */ React76.createElement("div", { className: cx(
6787
7035
  "transition-all duration-500 ease-in-out",
6788
7036
  isEmpty ? "flex-1" : "flex-zero"
6789
- ) }), /* @__PURE__ */ React74.createElement("div", { className: cx(
7037
+ ) }), /* @__PURE__ */ React76.createElement("div", { className: cx(
6790
7038
  "transition-all duration-500 ease-in-out overflow-hidden flex flex-col",
6791
7039
  isEmpty ? "flex-zero opacity-0" : "flex-1 opacity-100"
6792
- ) }, /* @__PURE__ */ React74.createElement(
7040
+ ) }, /* @__PURE__ */ React76.createElement(
6793
7041
  ChatView,
6794
7042
  {
6795
- messages: displayMessages,
7043
+ items: displayItems,
6796
7044
  latestUserMessageIndex,
6797
7045
  isStreaming,
6798
7046
  isThinking,
6799
7047
  className: "flex-1"
6800
7048
  }
6801
- )), /* @__PURE__ */ React74.createElement("div", { className: cx(
7049
+ )), /* @__PURE__ */ React76.createElement("div", { className: cx(
6802
7050
  "transition-all duration-500 ease-in-out z-10 w-full flex flex-col items-center",
6803
7051
  isEmpty ? "p-4" : "shrink-0 p-4 border-t border-ash/40 bg-obsidian"
6804
- ) }, isEmpty && /* @__PURE__ */ React74.createElement("div", { className: "mb-8 text-center animate-fade-in duration-500" }, emptyState ? emptyState : /* @__PURE__ */ React74.createElement("h1", { className: "text-4xl md:text-5xl font-heading text-gold mb-2 tracking-tight" }, "Welcome!")), /* @__PURE__ */ React74.createElement(
7052
+ ) }, isEmpty && /* @__PURE__ */ React76.createElement("div", { className: "mb-8 text-center animate-fade-in duration-500" }, emptyState ? emptyState : /* @__PURE__ */ React76.createElement("h1", { className: "text-4xl md:text-5xl font-heading text-gold mb-2 tracking-tight" }, "Welcome!")), /* @__PURE__ */ React76.createElement(
6805
7053
  ChatInput,
6806
7054
  {
6807
7055
  position: isEmpty ? "centered" : "bottom",
@@ -6820,11 +7068,11 @@ var ChatInterface = React74.forwardRef(
6820
7068
  initialInputValue,
6821
7069
  autoFocus
6822
7070
  }
6823
- )), /* @__PURE__ */ React74.createElement("div", { className: cx(
7071
+ )), /* @__PURE__ */ React76.createElement("div", { className: cx(
6824
7072
  "transition-all duration-500 ease-in-out",
6825
7073
  isEmpty ? "flex-1" : "flex-zero"
6826
7074
  ) }))),
6827
- isRightPanelOpen && /* @__PURE__ */ React74.createElement(
7075
+ isRightPanelOpen && /* @__PURE__ */ React76.createElement(
6828
7076
  ToolPanelContainer,
6829
7077
  {
6830
7078
  topContent: renderToolContent(activeTools["top-right"]),
@@ -6835,7 +7083,7 @@ var ChatInterface = React74.forwardRef(
6835
7083
  initialTopPercent: 70
6836
7084
  }
6837
7085
  ),
6838
- hasRightTools && /* @__PURE__ */ React74.createElement(
7086
+ hasRightTools && /* @__PURE__ */ React76.createElement(
6839
7087
  ToolSidebar,
6840
7088
  {
6841
7089
  tools: rightToolDefs,
@@ -6850,9 +7098,9 @@ var ChatInterface = React74.forwardRef(
6850
7098
  ChatInterface.displayName = "ChatInterface";
6851
7099
 
6852
7100
  // src/components/chat/MessageActions.tsx
6853
- import React75, { useCallback as useCallback23, useState as useState23 } from "react";
7101
+ import React77, { useCallback as useCallback23, useState as useState23 } from "react";
6854
7102
  import { Check as Check4, Copy as Copy2, Pencil as Pencil3, RotateCcw as RotateCcw2, Send as Send3, X as X7 } from "lucide-react";
6855
- var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ React75.createElement(
7103
+ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ React77.createElement(
6856
7104
  "button",
6857
7105
  {
6858
7106
  type: "button",
@@ -6868,7 +7116,7 @@ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @_
6868
7116
  },
6869
7117
  children
6870
7118
  );
6871
- var MessageActions = React75.forwardRef(
7119
+ var MessageActions = React77.forwardRef(
6872
7120
  ({
6873
7121
  variant,
6874
7122
  content,
@@ -6929,19 +7177,19 @@ var MessageActions = React75.forwardRef(
6929
7177
  );
6930
7178
  const isUser = variant === "user";
6931
7179
  if (isUser && isEditing) {
6932
- return /* @__PURE__ */ React75.createElement(
7180
+ return /* @__PURE__ */ React77.createElement(
6933
7181
  "div",
6934
7182
  {
6935
7183
  ref,
6936
7184
  className: cx("mt-2", className),
6937
7185
  ...rest
6938
7186
  },
6939
- /* @__PURE__ */ React75.createElement(
7187
+ /* @__PURE__ */ React77.createElement(
6940
7188
  "div",
6941
7189
  {
6942
7190
  className: "relative bg-charcoal border border-ash/60 focus-within:border-gold/60 focus-within:ring-1 focus-within:ring-gold/20"
6943
7191
  },
6944
- /* @__PURE__ */ React75.createElement(
7192
+ /* @__PURE__ */ React77.createElement(
6945
7193
  "textarea",
6946
7194
  {
6947
7195
  value: editValue,
@@ -6952,15 +7200,15 @@ var MessageActions = React75.forwardRef(
6952
7200
  rows: 2
6953
7201
  }
6954
7202
  ),
6955
- /* @__PURE__ */ React75.createElement("div", { className: "absolute right-2 bottom-2 flex gap-1" }, /* @__PURE__ */ React75.createElement(
7203
+ /* @__PURE__ */ React77.createElement("div", { className: "absolute right-2 bottom-2 flex gap-1" }, /* @__PURE__ */ React77.createElement(
6956
7204
  ActionButton2,
6957
7205
  {
6958
7206
  onClick: handleCancelEdit,
6959
7207
  label: "Cancel edit",
6960
7208
  className: "text-silver/60 hover:text-error"
6961
7209
  },
6962
- /* @__PURE__ */ React75.createElement(X7, { className: "w-4 h-4" })
6963
- ), /* @__PURE__ */ React75.createElement(
7210
+ /* @__PURE__ */ React77.createElement(X7, { className: "w-4 h-4" })
7211
+ ), /* @__PURE__ */ React77.createElement(
6964
7212
  ActionButton2,
6965
7213
  {
6966
7214
  onClick: handleSubmitEdit,
@@ -6968,13 +7216,13 @@ var MessageActions = React75.forwardRef(
6968
7216
  className: "text-silver/60 hover:text-gold",
6969
7217
  disabled: !editValue.trim() || editValue.trim() === content
6970
7218
  },
6971
- /* @__PURE__ */ React75.createElement(Send3, { className: "w-4 h-4" })
7219
+ /* @__PURE__ */ React77.createElement(Send3, { className: "w-4 h-4" })
6972
7220
  ))
6973
7221
  ),
6974
- /* @__PURE__ */ React75.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
7222
+ /* @__PURE__ */ React77.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
6975
7223
  );
6976
7224
  }
6977
- return /* @__PURE__ */ React75.createElement(
7225
+ return /* @__PURE__ */ React77.createElement(
6978
7226
  "div",
6979
7227
  {
6980
7228
  ref,
@@ -6985,18 +7233,18 @@ var MessageActions = React75.forwardRef(
6985
7233
  ),
6986
7234
  ...rest
6987
7235
  },
6988
- /* @__PURE__ */ React75.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ React75.createElement(Check4, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ React75.createElement(Copy2, { className: "w-3.5 h-3.5" })),
6989
- isUser && onEdit && /* @__PURE__ */ React75.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React75.createElement(Pencil3, { className: "w-3.5 h-3.5" })),
6990
- !isUser && onRetry && /* @__PURE__ */ React75.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ React75.createElement(RotateCcw2, { className: "w-3.5 h-3.5" }))
7236
+ /* @__PURE__ */ React77.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ React77.createElement(Check4, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ React77.createElement(Copy2, { className: "w-3.5 h-3.5" })),
7237
+ isUser && onEdit && /* @__PURE__ */ React77.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React77.createElement(Pencil3, { className: "w-3.5 h-3.5" })),
7238
+ !isUser && onRetry && /* @__PURE__ */ React77.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ React77.createElement(RotateCcw2, { className: "w-3.5 h-3.5" }))
6991
7239
  );
6992
7240
  }
6993
7241
  );
6994
7242
  MessageActions.displayName = "MessageActions";
6995
7243
 
6996
7244
  // src/components/chat/BranchNavigator.tsx
6997
- import React76 from "react";
6998
- import { ChevronLeft as ChevronLeft3, ChevronRight as ChevronRight4, GitBranch as GitBranch2 } from "lucide-react";
6999
- var BranchNavigator = React76.forwardRef(
7245
+ import React78 from "react";
7246
+ import { ChevronLeft as ChevronLeft4, ChevronRight as ChevronRight5, GitBranch as GitBranch3 } from "lucide-react";
7247
+ var BranchNavigator = React78.forwardRef(
7000
7248
  ({
7001
7249
  current,
7002
7250
  total,
@@ -7015,7 +7263,7 @@ var BranchNavigator = React76.forwardRef(
7015
7263
  const buttonSize = size === "sm" ? "p-0.5" : "p-1";
7016
7264
  const iconSize = size === "sm" ? "w-3 h-3" : "w-4 h-4";
7017
7265
  const textSize = size === "sm" ? "text-xs" : "text-sm";
7018
- return /* @__PURE__ */ React76.createElement(
7266
+ return /* @__PURE__ */ React78.createElement(
7019
7267
  "div",
7020
7268
  {
7021
7269
  ref,
@@ -7027,8 +7275,8 @@ var BranchNavigator = React76.forwardRef(
7027
7275
  "aria-label": "Branch navigation",
7028
7276
  ...rest
7029
7277
  },
7030
- showIcon && /* @__PURE__ */ React76.createElement(GitBranch2, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
7031
- /* @__PURE__ */ React76.createElement(
7278
+ showIcon && /* @__PURE__ */ React78.createElement(GitBranch3, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
7279
+ /* @__PURE__ */ React78.createElement(
7032
7280
  "button",
7033
7281
  {
7034
7282
  type: "button",
@@ -7041,10 +7289,10 @@ var BranchNavigator = React76.forwardRef(
7041
7289
  ),
7042
7290
  "aria-label": "Previous branch"
7043
7291
  },
7044
- /* @__PURE__ */ React76.createElement(ChevronLeft3, { className: iconSize })
7292
+ /* @__PURE__ */ React78.createElement(ChevronLeft4, { className: iconSize })
7045
7293
  ),
7046
- /* @__PURE__ */ React76.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
7047
- /* @__PURE__ */ React76.createElement(
7294
+ /* @__PURE__ */ React78.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
7295
+ /* @__PURE__ */ React78.createElement(
7048
7296
  "button",
7049
7297
  {
7050
7298
  type: "button",
@@ -7057,7 +7305,7 @@ var BranchNavigator = React76.forwardRef(
7057
7305
  ),
7058
7306
  "aria-label": "Next branch"
7059
7307
  },
7060
- /* @__PURE__ */ React76.createElement(ChevronRight4, { className: iconSize })
7308
+ /* @__PURE__ */ React78.createElement(ChevronRight5, { className: iconSize })
7061
7309
  )
7062
7310
  );
7063
7311
  }
@@ -7065,16 +7313,16 @@ var BranchNavigator = React76.forwardRef(
7065
7313
  BranchNavigator.displayName = "BranchNavigator";
7066
7314
 
7067
7315
  // src/components/BrandIcon.tsx
7068
- import React77 from "react";
7316
+ import React79 from "react";
7069
7317
  var sizeMap2 = {
7070
7318
  sm: "h-8 w-8 text-sm",
7071
7319
  md: "h-12 w-12 text-base",
7072
7320
  lg: "h-16 w-16 text-lg"
7073
7321
  };
7074
- var BrandIcon = React77.forwardRef(
7322
+ var BrandIcon = React79.forwardRef(
7075
7323
  ({ size = "md", variant = "solid", children, className, ...rest }, ref) => {
7076
7324
  const variantClasses = variant === "solid" ? "bg-gold text-obsidian border-2 border-gold" : "bg-transparent text-gold border-2 border-gold";
7077
- return /* @__PURE__ */ React77.createElement(
7325
+ return /* @__PURE__ */ React79.createElement(
7078
7326
  "div",
7079
7327
  {
7080
7328
  ref,
@@ -7093,17 +7341,17 @@ var BrandIcon = React77.forwardRef(
7093
7341
  BrandIcon.displayName = "BrandIcon";
7094
7342
 
7095
7343
  // src/components/ColorSwatch.tsx
7096
- import React78 from "react";
7097
- var ColorSwatch = React78.forwardRef(
7344
+ import React80 from "react";
7345
+ var ColorSwatch = React80.forwardRef(
7098
7346
  ({ color, label, className, ...rest }, ref) => {
7099
- return /* @__PURE__ */ React78.createElement(
7347
+ return /* @__PURE__ */ React80.createElement(
7100
7348
  "div",
7101
7349
  {
7102
7350
  ref,
7103
7351
  className: cx("flex flex-col items-center gap-2", className),
7104
7352
  ...rest
7105
7353
  },
7106
- /* @__PURE__ */ React78.createElement(
7354
+ /* @__PURE__ */ React80.createElement(
7107
7355
  "div",
7108
7356
  {
7109
7357
  className: "h-16 w-16 border-2 border-ash rounded-none shadow-sm",
@@ -7111,22 +7359,22 @@ var ColorSwatch = React78.forwardRef(
7111
7359
  "aria-label": label || color
7112
7360
  }
7113
7361
  ),
7114
- label && /* @__PURE__ */ React78.createElement("span", { className: "text-xs text-silver font-medium" }, label)
7362
+ label && /* @__PURE__ */ React80.createElement("span", { className: "text-xs text-silver font-medium" }, label)
7115
7363
  );
7116
7364
  }
7117
7365
  );
7118
7366
  ColorSwatch.displayName = "ColorSwatch";
7119
7367
 
7120
7368
  // src/components/SectionHeading.tsx
7121
- import React79 from "react";
7369
+ import React81 from "react";
7122
7370
  var levelStyles = {
7123
7371
  h2: "text-2xl mb-4",
7124
7372
  h3: "text-xl mb-3"
7125
7373
  };
7126
- var SectionHeading = React79.forwardRef(
7374
+ var SectionHeading = React81.forwardRef(
7127
7375
  ({ level = "h2", children, className, ...rest }, ref) => {
7128
7376
  const Component = level;
7129
- return /* @__PURE__ */ React79.createElement(
7377
+ return /* @__PURE__ */ React81.createElement(
7130
7378
  Component,
7131
7379
  {
7132
7380
  ref,
@@ -7182,6 +7430,7 @@ export {
7182
7430
  ChatView,
7183
7431
  CheckSquareIcon,
7184
7432
  Checkbox,
7433
+ Checkpoint,
7185
7434
  ChevronLeftIcon,
7186
7435
  ChevronRightIcon,
7187
7436
  CloseIcon,
@@ -7195,6 +7444,7 @@ export {
7195
7444
  EmptySquareIcon,
7196
7445
  ExpandIcon,
7197
7446
  FileChip,
7447
+ GreyedDivider,
7198
7448
  HelperText,
7199
7449
  HistoryIcon,
7200
7450
  HistoryPanel,
@@ -7272,16 +7522,22 @@ export {
7272
7522
  ToolSidebar,
7273
7523
  Tooltip,
7274
7524
  VideoCard,
7275
- addMessageToTree,
7525
+ addNodeToTree,
7276
7526
  areAllTasksSettled,
7277
7527
  createEmptyTree,
7528
+ createPreviewUrl,
7529
+ findAncestor,
7278
7530
  generateId,
7279
- getActivePathMessages,
7531
+ getActivePath,
7532
+ getGreyedFuture,
7280
7533
  getSiblingInfo,
7281
7534
  isBranchPoint,
7535
+ isImageFile,
7282
7536
  messagesToTree,
7537
+ revokePreviewUrl,
7538
+ setActiveLeaf,
7283
7539
  switchBranch,
7284
- updateNodeContent,
7540
+ updateMessageContent,
7285
7541
  useArtifactTreeNavigation,
7286
7542
  useResizable,
7287
7543
  useScrollAnchor,