@lukeashford/aurelius 4.0.0 → 4.1.0

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