@lukeashford/aurelius 2.20.0 → 3.0.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
@@ -2179,7 +2179,7 @@ var Modal = ({ isOpen, onClose, title, children, className }) => {
2179
2179
  role: "dialog",
2180
2180
  "aria-modal": "true",
2181
2181
  className: cx(
2182
- "bg-charcoal border border-gold/30 shadow-2xl z-50 w-full max-w-lg p-6 rounded-none relative",
2182
+ "bg-charcoal border border-gold/30 shadow-2xl z-50 w-full max-w-lg p-6 rounded-none relative flex flex-col",
2183
2183
  className
2184
2184
  ),
2185
2185
  "data-state": "open",
@@ -2194,7 +2194,7 @@ var Modal = ({ isOpen, onClose, title, children, className }) => {
2194
2194
  /* @__PURE__ */ React30.createElement(X3, { className: "h-5 w-5" }),
2195
2195
  /* @__PURE__ */ React30.createElement("span", { className: "sr-only" }, "Close")
2196
2196
  )),
2197
- /* @__PURE__ */ React30.createElement("div", null, children)
2197
+ /* @__PURE__ */ React30.createElement("div", { className: "overflow-y-auto min-h-0" }, children)
2198
2198
  )
2199
2199
  );
2200
2200
  return createPortal2(content, document.body);
@@ -3464,9 +3464,9 @@ function LayersIcon({ className, ...props }) {
3464
3464
  );
3465
3465
  }
3466
3466
 
3467
- // src/components/icons/PlusIcon.tsx
3467
+ // src/components/icons/MediaIcon.tsx
3468
3468
  import React47 from "react";
3469
- function PlusIcon({ className, ...props }) {
3469
+ function MediaIcon({ className, ...props }) {
3470
3470
  return /* @__PURE__ */ React47.createElement(
3471
3471
  "svg",
3472
3472
  {
@@ -3477,6 +3477,29 @@ function PlusIcon({ className, ...props }) {
3477
3477
  ...props
3478
3478
  },
3479
3479
  /* @__PURE__ */ React47.createElement(
3480
+ "path",
3481
+ {
3482
+ fillRule: "evenodd",
3483
+ d: "M2 4.5A1.5 1.5 0 013.5 3h13A1.5 1.5 0 0118 4.5v11a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 012 15.5v-11zM4 5v1h1V5H4zm2 0v1h1V5H6zm7 0v1h1V5h-1zm2 0v1h1V5h-1zM4 14v1h1v-1H4zm2 0v1h1v-1H6zm7 0v1h1v-1h-1zm2 0v1h1v-1h-1zM8 8.118a.5.5 0 01.757-.429l4 2.382a.5.5 0 010 .858l-4 2.382A.5.5 0 018 12.882V8.118z",
3484
+ clipRule: "evenodd"
3485
+ }
3486
+ )
3487
+ );
3488
+ }
3489
+
3490
+ // src/components/icons/PlusIcon.tsx
3491
+ import React48 from "react";
3492
+ function PlusIcon({ className, ...props }) {
3493
+ return /* @__PURE__ */ React48.createElement(
3494
+ "svg",
3495
+ {
3496
+ xmlns: "http://www.w3.org/2000/svg",
3497
+ viewBox: "0 0 20 20",
3498
+ fill: "currentColor",
3499
+ className,
3500
+ ...props
3501
+ },
3502
+ /* @__PURE__ */ React48.createElement(
3480
3503
  "path",
3481
3504
  {
3482
3505
  d: "M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
@@ -3486,9 +3509,9 @@ function PlusIcon({ className, ...props }) {
3486
3509
  }
3487
3510
 
3488
3511
  // src/components/icons/CheckSquareIcon.tsx
3489
- import React48 from "react";
3512
+ import React49 from "react";
3490
3513
  function CheckSquareIcon({ className, ...props }) {
3491
- return /* @__PURE__ */ React48.createElement(
3514
+ return /* @__PURE__ */ React49.createElement(
3492
3515
  "div",
3493
3516
  {
3494
3517
  className: cx(
@@ -3497,14 +3520,14 @@ function CheckSquareIcon({ className, ...props }) {
3497
3520
  ),
3498
3521
  ...props
3499
3522
  },
3500
- /* @__PURE__ */ React48.createElement(
3523
+ /* @__PURE__ */ React49.createElement(
3501
3524
  "svg",
3502
3525
  {
3503
3526
  viewBox: "0 0 16 16",
3504
3527
  fill: "none",
3505
3528
  className: "absolute inset-0 w-full h-full p-0.5"
3506
3529
  },
3507
- /* @__PURE__ */ React48.createElement(
3530
+ /* @__PURE__ */ React49.createElement(
3508
3531
  "path",
3509
3532
  {
3510
3533
  d: "M3 8l3 3 7-7",
@@ -3520,9 +3543,9 @@ function CheckSquareIcon({ className, ...props }) {
3520
3543
  }
3521
3544
 
3522
3545
  // src/components/icons/EmptySquareIcon.tsx
3523
- import React49 from "react";
3546
+ import React50 from "react";
3524
3547
  function EmptySquareIcon({ className, ...props }) {
3525
- return /* @__PURE__ */ React49.createElement(
3548
+ return /* @__PURE__ */ React50.createElement(
3526
3549
  "div",
3527
3550
  {
3528
3551
  className: cx(
@@ -3535,9 +3558,9 @@ function EmptySquareIcon({ className, ...props }) {
3535
3558
  }
3536
3559
 
3537
3560
  // src/components/icons/CrossSquareIcon.tsx
3538
- import React50 from "react";
3561
+ import React51 from "react";
3539
3562
  function CrossSquareIcon({ className, variant = "cancelled", ...props }) {
3540
- return /* @__PURE__ */ React50.createElement(
3563
+ return /* @__PURE__ */ React51.createElement(
3541
3564
  "div",
3542
3565
  {
3543
3566
  className: cx(
@@ -3547,14 +3570,14 @@ function CrossSquareIcon({ className, variant = "cancelled", ...props }) {
3547
3570
  ),
3548
3571
  ...props
3549
3572
  },
3550
- /* @__PURE__ */ React50.createElement(
3573
+ /* @__PURE__ */ React51.createElement(
3551
3574
  "svg",
3552
3575
  {
3553
3576
  viewBox: "0 0 16 16",
3554
3577
  fill: "none",
3555
3578
  className: "absolute inset-0 w-full h-full p-0.5"
3556
3579
  },
3557
- /* @__PURE__ */ React50.createElement(
3580
+ /* @__PURE__ */ React51.createElement(
3558
3581
  "path",
3559
3582
  {
3560
3583
  d: "M4 4l8 8M12 4l-8 8",
@@ -3569,15 +3592,15 @@ function CrossSquareIcon({ className, variant = "cancelled", ...props }) {
3569
3592
  }
3570
3593
 
3571
3594
  // src/components/icons/SquareLoaderIcon.tsx
3572
- import React51 from "react";
3595
+ import React52 from "react";
3573
3596
  function SquareLoaderIcon({ className, ...props }) {
3574
- return /* @__PURE__ */ React51.createElement("div", { className: cx("relative w-4 h-4 flex-shrink-0", className), ...props }, /* @__PURE__ */ React51.createElement(
3597
+ return /* @__PURE__ */ React52.createElement("div", { className: cx("relative w-4 h-4 flex-shrink-0", className), ...props }, /* @__PURE__ */ React52.createElement(
3575
3598
  "svg",
3576
3599
  {
3577
3600
  viewBox: "0 0 16 16",
3578
3601
  className: "w-full h-full animate-snake-spin"
3579
3602
  },
3580
- /* @__PURE__ */ React51.createElement(
3603
+ /* @__PURE__ */ React52.createElement(
3581
3604
  "rect",
3582
3605
  {
3583
3606
  x: "1",
@@ -3590,7 +3613,7 @@ function SquareLoaderIcon({ className, ...props }) {
3590
3613
  className: "text-ash/40"
3591
3614
  }
3592
3615
  ),
3593
- /* @__PURE__ */ React51.createElement(
3616
+ /* @__PURE__ */ React52.createElement(
3594
3617
  "rect",
3595
3618
  {
3596
3619
  x: "1",
@@ -3609,10 +3632,10 @@ function SquareLoaderIcon({ className, ...props }) {
3609
3632
  }
3610
3633
 
3611
3634
  // src/components/Message.tsx
3612
- import React53, { useEffect as useEffect6, useRef as useRef5, useState as useState10 } from "react";
3635
+ import React54, { useEffect as useEffect6, useRef as useRef5, useState as useState10 } from "react";
3613
3636
 
3614
3637
  // src/components/MarkdownContent.tsx
3615
- import React52, { useMemo } from "react";
3638
+ import React53, { useMemo } from "react";
3616
3639
  import DOMPurify from "dompurify";
3617
3640
  import { marked } from "marked";
3618
3641
  var DEFAULT_SANITIZE_CONFIG = {
@@ -3719,7 +3742,7 @@ function injectStreamingCursor(html, cursorClassName) {
3719
3742
  target.insertAdjacentHTML("beforeend", cursorHtml);
3720
3743
  return container.innerHTML;
3721
3744
  }
3722
- var MarkdownContent = React52.forwardRef(
3745
+ var MarkdownContent = React53.forwardRef(
3723
3746
  ({ className, content, isMarkdown = true, sanitizeConfig, isStreaming, cursorClassName, ...rest }, ref) => {
3724
3747
  useDOMPurifySetup();
3725
3748
  const sanitizedHtml = useMemo(() => {
@@ -3744,7 +3767,7 @@ var MarkdownContent = React52.forwardRef(
3744
3767
  }
3745
3768
  return sanitized;
3746
3769
  }, [content, sanitizeConfig, isStreaming, cursorClassName]);
3747
- return /* @__PURE__ */ React52.createElement(
3770
+ return /* @__PURE__ */ React53.createElement(
3748
3771
  "div",
3749
3772
  {
3750
3773
  ref,
@@ -3762,7 +3785,7 @@ var variantStyles2 = {
3762
3785
  user: "bg-gold text-obsidian ml-auto",
3763
3786
  assistant: "bg-charcoal border border-ash text-white mr-auto"
3764
3787
  };
3765
- var ActionButton = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ React53.createElement(
3788
+ var ActionButton = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ React54.createElement(
3766
3789
  "button",
3767
3790
  {
3768
3791
  type: "button",
@@ -3778,7 +3801,7 @@ var ActionButton = ({ onClick, label, children, className, disabled }) => /* @__
3778
3801
  },
3779
3802
  children
3780
3803
  );
3781
- var CopyIcon = () => /* @__PURE__ */ React53.createElement(
3804
+ var CopyIcon = () => /* @__PURE__ */ React54.createElement(
3782
3805
  "svg",
3783
3806
  {
3784
3807
  xmlns: "http://www.w3.org/2000/svg",
@@ -3790,10 +3813,10 @@ var CopyIcon = () => /* @__PURE__ */ React53.createElement(
3790
3813
  strokeLinejoin: "round",
3791
3814
  className: "w-3.5 h-3.5"
3792
3815
  },
3793
- /* @__PURE__ */ React53.createElement("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
3794
- /* @__PURE__ */ React53.createElement("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
3816
+ /* @__PURE__ */ React54.createElement("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
3817
+ /* @__PURE__ */ React54.createElement("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
3795
3818
  );
3796
- var CheckIcon = () => /* @__PURE__ */ React53.createElement(
3819
+ var CheckIcon = () => /* @__PURE__ */ React54.createElement(
3797
3820
  "svg",
3798
3821
  {
3799
3822
  xmlns: "http://www.w3.org/2000/svg",
@@ -3805,9 +3828,9 @@ var CheckIcon = () => /* @__PURE__ */ React53.createElement(
3805
3828
  strokeLinejoin: "round",
3806
3829
  className: "w-3.5 h-3.5 text-success"
3807
3830
  },
3808
- /* @__PURE__ */ React53.createElement("polyline", { points: "20 6 9 17 4 12" })
3831
+ /* @__PURE__ */ React54.createElement("polyline", { points: "20 6 9 17 4 12" })
3809
3832
  );
3810
- var PencilIcon = () => /* @__PURE__ */ React53.createElement(
3833
+ var PencilIcon = () => /* @__PURE__ */ React54.createElement(
3811
3834
  "svg",
3812
3835
  {
3813
3836
  xmlns: "http://www.w3.org/2000/svg",
@@ -3819,10 +3842,10 @@ var PencilIcon = () => /* @__PURE__ */ React53.createElement(
3819
3842
  strokeLinejoin: "round",
3820
3843
  className: "w-3.5 h-3.5"
3821
3844
  },
3822
- /* @__PURE__ */ React53.createElement("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }),
3823
- /* @__PURE__ */ React53.createElement("path", { d: "m15 5 4 4" })
3845
+ /* @__PURE__ */ React54.createElement("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }),
3846
+ /* @__PURE__ */ React54.createElement("path", { d: "m15 5 4 4" })
3824
3847
  );
3825
- var RetryIcon = () => /* @__PURE__ */ React53.createElement(
3848
+ var RetryIcon = () => /* @__PURE__ */ React54.createElement(
3826
3849
  "svg",
3827
3850
  {
3828
3851
  xmlns: "http://www.w3.org/2000/svg",
@@ -3834,12 +3857,12 @@ var RetryIcon = () => /* @__PURE__ */ React53.createElement(
3834
3857
  strokeLinejoin: "round",
3835
3858
  className: "w-3.5 h-3.5"
3836
3859
  },
3837
- /* @__PURE__ */ React53.createElement("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
3838
- /* @__PURE__ */ React53.createElement("path", { d: "M21 3v5h-5" }),
3839
- /* @__PURE__ */ React53.createElement("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
3840
- /* @__PURE__ */ React53.createElement("path", { d: "M8 16H3v5" })
3860
+ /* @__PURE__ */ React54.createElement("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
3861
+ /* @__PURE__ */ React54.createElement("path", { d: "M21 3v5h-5" }),
3862
+ /* @__PURE__ */ React54.createElement("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
3863
+ /* @__PURE__ */ React54.createElement("path", { d: "M8 16H3v5" })
3841
3864
  );
3842
- var ChevronLeftIcon2 = () => /* @__PURE__ */ React53.createElement(
3865
+ var ChevronLeftIcon2 = () => /* @__PURE__ */ React54.createElement(
3843
3866
  "svg",
3844
3867
  {
3845
3868
  xmlns: "http://www.w3.org/2000/svg",
@@ -3851,9 +3874,9 @@ var ChevronLeftIcon2 = () => /* @__PURE__ */ React53.createElement(
3851
3874
  strokeLinejoin: "round",
3852
3875
  className: "w-3 h-3"
3853
3876
  },
3854
- /* @__PURE__ */ React53.createElement("path", { d: "m15 18-6-6 6-6" })
3877
+ /* @__PURE__ */ React54.createElement("path", { d: "m15 18-6-6 6-6" })
3855
3878
  );
3856
- var ChevronRightIcon2 = () => /* @__PURE__ */ React53.createElement(
3879
+ var ChevronRightIcon2 = () => /* @__PURE__ */ React54.createElement(
3857
3880
  "svg",
3858
3881
  {
3859
3882
  xmlns: "http://www.w3.org/2000/svg",
@@ -3865,9 +3888,9 @@ var ChevronRightIcon2 = () => /* @__PURE__ */ React53.createElement(
3865
3888
  strokeLinejoin: "round",
3866
3889
  className: "w-3 h-3"
3867
3890
  },
3868
- /* @__PURE__ */ React53.createElement("path", { d: "m9 18 6-6-6-6" })
3891
+ /* @__PURE__ */ React54.createElement("path", { d: "m9 18 6-6-6-6" })
3869
3892
  );
3870
- var GitBranchIcon = () => /* @__PURE__ */ React53.createElement(
3893
+ var GitBranchIcon = () => /* @__PURE__ */ React54.createElement(
3871
3894
  "svg",
3872
3895
  {
3873
3896
  xmlns: "http://www.w3.org/2000/svg",
@@ -3879,12 +3902,12 @@ var GitBranchIcon = () => /* @__PURE__ */ React53.createElement(
3879
3902
  strokeLinejoin: "round",
3880
3903
  className: "w-3 h-3 mr-0.5 text-silver/50"
3881
3904
  },
3882
- /* @__PURE__ */ React53.createElement("line", { x1: "6", x2: "6", y1: "3", y2: "15" }),
3883
- /* @__PURE__ */ React53.createElement("circle", { cx: "18", cy: "6", r: "3" }),
3884
- /* @__PURE__ */ React53.createElement("circle", { cx: "6", cy: "18", r: "3" }),
3885
- /* @__PURE__ */ React53.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })
3905
+ /* @__PURE__ */ React54.createElement("line", { x1: "6", x2: "6", y1: "3", y2: "15" }),
3906
+ /* @__PURE__ */ React54.createElement("circle", { cx: "18", cy: "6", r: "3" }),
3907
+ /* @__PURE__ */ React54.createElement("circle", { cx: "6", cy: "18", r: "3" }),
3908
+ /* @__PURE__ */ React54.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })
3886
3909
  );
3887
- var XIcon = () => /* @__PURE__ */ React53.createElement(
3910
+ var XIcon = () => /* @__PURE__ */ React54.createElement(
3888
3911
  "svg",
3889
3912
  {
3890
3913
  xmlns: "http://www.w3.org/2000/svg",
@@ -3896,10 +3919,10 @@ var XIcon = () => /* @__PURE__ */ React53.createElement(
3896
3919
  strokeLinejoin: "round",
3897
3920
  className: "w-4 h-4"
3898
3921
  },
3899
- /* @__PURE__ */ React53.createElement("path", { d: "M18 6 6 18" }),
3900
- /* @__PURE__ */ React53.createElement("path", { d: "m6 6 12 12" })
3922
+ /* @__PURE__ */ React54.createElement("path", { d: "M18 6 6 18" }),
3923
+ /* @__PURE__ */ React54.createElement("path", { d: "m6 6 12 12" })
3901
3924
  );
3902
- var SendIcon = () => /* @__PURE__ */ React53.createElement(
3925
+ var SendIcon = () => /* @__PURE__ */ React54.createElement(
3903
3926
  "svg",
3904
3927
  {
3905
3928
  xmlns: "http://www.w3.org/2000/svg",
@@ -3911,10 +3934,10 @@ var SendIcon = () => /* @__PURE__ */ React53.createElement(
3911
3934
  strokeLinejoin: "round",
3912
3935
  className: "w-4 h-4"
3913
3936
  },
3914
- /* @__PURE__ */ React53.createElement("path", { d: "m22 2-7 20-4-9-9-4Z" }),
3915
- /* @__PURE__ */ React53.createElement("path", { d: "M22 2 11 13" })
3937
+ /* @__PURE__ */ React54.createElement("path", { d: "m22 2-7 20-4-9-9-4Z" }),
3938
+ /* @__PURE__ */ React54.createElement("path", { d: "M22 2 11 13" })
3916
3939
  );
3917
- var Message = React53.forwardRef(
3940
+ var Message = React54.forwardRef(
3918
3941
  ({
3919
3942
  variant = "assistant",
3920
3943
  className,
@@ -3986,7 +4009,7 @@ var Message = React53.forwardRef(
3986
4009
  textarea.style.height = "auto";
3987
4010
  textarea.style.height = `${textarea.scrollHeight}px`;
3988
4011
  };
3989
- return /* @__PURE__ */ React53.createElement(
4012
+ return /* @__PURE__ */ React54.createElement(
3990
4013
  "div",
3991
4014
  {
3992
4015
  ref,
@@ -3997,7 +4020,7 @@ var Message = React53.forwardRef(
3997
4020
  ),
3998
4021
  ...rest
3999
4022
  },
4000
- isUser && isEditing ? /* @__PURE__ */ React53.createElement("div", { className: "w-full max-w-11/12" }, /* @__PURE__ */ React53.createElement("div", { className: "relative bg-gold" }, /* @__PURE__ */ React53.createElement(
4023
+ isUser && isEditing ? /* @__PURE__ */ React54.createElement("div", { className: "w-full max-w-11/12" }, /* @__PURE__ */ React54.createElement("div", { className: "relative bg-gold" }, /* @__PURE__ */ React54.createElement(
4001
4024
  "textarea",
4002
4025
  {
4003
4026
  ref: textareaRef,
@@ -4007,7 +4030,7 @@ var Message = React53.forwardRef(
4007
4030
  className: "w-full bg-transparent text-obsidian px-3 py-2 pr-20 resize-none outline-none min-h-10 text-sm",
4008
4031
  rows: 1
4009
4032
  }
4010
- ), /* @__PURE__ */ React53.createElement("div", { className: "absolute right-1 top-1/2 -translate-y-1/2 flex gap-0.5" }, /* @__PURE__ */ React53.createElement(
4033
+ ), /* @__PURE__ */ React54.createElement("div", { className: "absolute right-1 top-1/2 -translate-y-1/2 flex gap-0.5" }, /* @__PURE__ */ React54.createElement(
4011
4034
  "button",
4012
4035
  {
4013
4036
  type: "button",
@@ -4015,8 +4038,8 @@ var Message = React53.forwardRef(
4015
4038
  className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors",
4016
4039
  "aria-label": "Cancel edit"
4017
4040
  },
4018
- /* @__PURE__ */ React53.createElement(XIcon, null)
4019
- ), /* @__PURE__ */ React53.createElement(
4041
+ /* @__PURE__ */ React54.createElement(XIcon, null)
4042
+ ), /* @__PURE__ */ React54.createElement(
4020
4043
  "button",
4021
4044
  {
4022
4045
  type: "button",
@@ -4025,8 +4048,8 @@ var Message = React53.forwardRef(
4025
4048
  className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors disabled:opacity-30",
4026
4049
  "aria-label": "Submit edit"
4027
4050
  },
4028
- /* @__PURE__ */ React53.createElement(SendIcon, null)
4029
- )))) : /* @__PURE__ */ React53.createElement(
4051
+ /* @__PURE__ */ React54.createElement(SendIcon, null)
4052
+ )))) : /* @__PURE__ */ React54.createElement(
4030
4053
  "div",
4031
4054
  {
4032
4055
  className: cx(
@@ -4034,7 +4057,7 @@ var Message = React53.forwardRef(
4034
4057
  variantStyles2[variant]
4035
4058
  )
4036
4059
  },
4037
- /* @__PURE__ */ React53.createElement(
4060
+ /* @__PURE__ */ React54.createElement(
4038
4061
  MarkdownContent,
4039
4062
  {
4040
4063
  content,
@@ -4044,17 +4067,17 @@ var Message = React53.forwardRef(
4044
4067
  }
4045
4068
  )
4046
4069
  ),
4047
- showActions && !isEditing && /* @__PURE__ */ React53.createElement("div", { className: cx(
4070
+ showActions && !isEditing && /* @__PURE__ */ React54.createElement("div", { className: cx(
4048
4071
  "flex items-center gap-0.5 mt-1",
4049
4072
  isUser ? "mr-1" : "ml-1"
4050
- ) }, actions.showCopy !== false && /* @__PURE__ */ React53.createElement(
4073
+ ) }, actions.showCopy !== false && /* @__PURE__ */ React54.createElement(
4051
4074
  ActionButton,
4052
4075
  {
4053
4076
  onClick: handleCopy,
4054
4077
  label: copied ? "Copied!" : "Copy message"
4055
4078
  },
4056
- copied ? /* @__PURE__ */ React53.createElement(CheckIcon, null) : /* @__PURE__ */ React53.createElement(CopyIcon, null)
4057
- ), isUser && actions.onEdit && /* @__PURE__ */ React53.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React53.createElement(PencilIcon, null)), !isUser && actions.onRetry && /* @__PURE__ */ React53.createElement(ActionButton, { onClick: actions.onRetry, label: "Regenerate response" }, /* @__PURE__ */ React53.createElement(RetryIcon, null)), showBranchNav && /* @__PURE__ */ React53.createElement(React53.Fragment, null, /* @__PURE__ */ React53.createElement("div", { className: "w-px h-4 bg-ash/40 mx-1" }), /* @__PURE__ */ React53.createElement("div", { className: "flex items-center gap-0.5 text-silver/70" }, /* @__PURE__ */ React53.createElement(GitBranchIcon, null), /* @__PURE__ */ React53.createElement(
4079
+ copied ? /* @__PURE__ */ React54.createElement(CheckIcon, null) : /* @__PURE__ */ React54.createElement(CopyIcon, null)
4080
+ ), isUser && actions.onEdit && /* @__PURE__ */ React54.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React54.createElement(PencilIcon, null)), !isUser && actions.onRetry && /* @__PURE__ */ React54.createElement(ActionButton, { onClick: actions.onRetry, label: "Regenerate response" }, /* @__PURE__ */ React54.createElement(RetryIcon, null)), showBranchNav && /* @__PURE__ */ React54.createElement(React54.Fragment, null, /* @__PURE__ */ React54.createElement("div", { className: "w-px h-4 bg-ash/40 mx-1" }), /* @__PURE__ */ React54.createElement("div", { className: "flex items-center gap-0.5 text-silver/70" }, /* @__PURE__ */ React54.createElement(GitBranchIcon, null), /* @__PURE__ */ React54.createElement(
4058
4081
  "button",
4059
4082
  {
4060
4083
  type: "button",
@@ -4066,8 +4089,8 @@ var Message = React53.forwardRef(
4066
4089
  ),
4067
4090
  "aria-label": "Previous branch"
4068
4091
  },
4069
- /* @__PURE__ */ React53.createElement(ChevronLeftIcon2, null)
4070
- ), /* @__PURE__ */ React53.createElement("span", { className: "text-xs tabular-nums min-w-6 text-center" }, branchInfo.current, "/", branchInfo.total), /* @__PURE__ */ React53.createElement(
4092
+ /* @__PURE__ */ React54.createElement(ChevronLeftIcon2, null)
4093
+ ), /* @__PURE__ */ React54.createElement("span", { className: "text-xs tabular-nums min-w-6 text-center" }, branchInfo.current, "/", branchInfo.total), /* @__PURE__ */ React54.createElement(
4071
4094
  "button",
4072
4095
  {
4073
4096
  type: "button",
@@ -4079,7 +4102,7 @@ var Message = React53.forwardRef(
4079
4102
  ),
4080
4103
  "aria-label": "Next branch"
4081
4104
  },
4082
- /* @__PURE__ */ React53.createElement(ChevronRightIcon2, null)
4105
+ /* @__PURE__ */ React54.createElement(ChevronRightIcon2, null)
4083
4106
  ))))
4084
4107
  );
4085
4108
  }
@@ -4087,15 +4110,15 @@ var Message = React53.forwardRef(
4087
4110
  Message.displayName = "Message";
4088
4111
 
4089
4112
  // src/components/StreamingCursor.tsx
4090
- import React54 from "react";
4091
- var StreamingCursor = React54.forwardRef(
4113
+ import React55 from "react";
4114
+ var StreamingCursor = React55.forwardRef(
4092
4115
  ({ className, variant = "line", ...rest }, ref) => {
4093
4116
  const variantStyles3 = {
4094
4117
  block: "w-2.5 h-cursor translate-y-cursor-offset",
4095
4118
  line: "w-0.5 h-cursor translate-y-cursor-offset",
4096
4119
  underscore: "w-2.5 h-0.5 self-end mb-0.5"
4097
4120
  };
4098
- return /* @__PURE__ */ React54.createElement(
4121
+ return /* @__PURE__ */ React55.createElement(
4099
4122
  "span",
4100
4123
  {
4101
4124
  ref,
@@ -4113,10 +4136,10 @@ var StreamingCursor = React54.forwardRef(
4113
4136
  StreamingCursor.displayName = "StreamingCursor";
4114
4137
 
4115
4138
  // src/components/chat/ChatInterface.tsx
4116
- import React68, { useCallback as useCallback17, useEffect as useEffect13, useMemo as useMemo3, useRef as useRef10, useState as useState17 } from "react";
4139
+ import React73, { useCallback as useCallback18, useEffect as useEffect15, useMemo as useMemo4, useRef as useRef13, useState as useState19 } from "react";
4117
4140
 
4118
4141
  // src/components/chat/ChatView.tsx
4119
- import React56, { useEffect as useEffect9 } from "react";
4142
+ import React57, { useEffect as useEffect9 } from "react";
4120
4143
 
4121
4144
  // src/components/chat/hooks/useScrollAnchor.ts
4122
4145
  import { useCallback as useCallback11, useRef as useRef6 } from "react";
@@ -4232,7 +4255,7 @@ function useAdaptiveSpacer(options = {}) {
4232
4255
  }
4233
4256
 
4234
4257
  // src/components/chat/ThinkingIndicator.tsx
4235
- import React55, { useEffect as useEffect8, useState as useState12 } from "react";
4258
+ import React56, { useEffect as useEffect8, useState as useState12 } from "react";
4236
4259
  var THINKING_PHRASES = [
4237
4260
  "Consulting the ancient tomes...",
4238
4261
  "Parsing the ineffable...",
@@ -4248,7 +4271,7 @@ var THINKING_PHRASES = [
4248
4271
  "Consulting my inner monologue...",
4249
4272
  "Summoning the muse..."
4250
4273
  ];
4251
- var ThinkingIndicator = React55.forwardRef(
4274
+ var ThinkingIndicator = React56.forwardRef(
4252
4275
  ({
4253
4276
  isVisible = true,
4254
4277
  phraseInterval = 2500,
@@ -4276,7 +4299,7 @@ var ThinkingIndicator = React55.forwardRef(
4276
4299
  if (!isVisible) {
4277
4300
  return null;
4278
4301
  }
4279
- return /* @__PURE__ */ React55.createElement(
4302
+ return /* @__PURE__ */ React56.createElement(
4280
4303
  "div",
4281
4304
  {
4282
4305
  ref,
@@ -4290,26 +4313,26 @@ var ThinkingIndicator = React55.forwardRef(
4290
4313
  "aria-live": "polite",
4291
4314
  ...rest
4292
4315
  },
4293
- /* @__PURE__ */ React55.createElement("div", { className: "flex gap-1", "aria-hidden": "true" }, /* @__PURE__ */ React55.createElement(
4316
+ /* @__PURE__ */ React56.createElement("div", { className: "flex gap-1", "aria-hidden": "true" }, /* @__PURE__ */ React56.createElement(
4294
4317
  "span",
4295
4318
  {
4296
4319
  className: "w-1.5 h-1.5 bg-gold/60 rounded-full animate-pulse",
4297
4320
  style: { animationDelay: "0ms" }
4298
4321
  }
4299
- ), /* @__PURE__ */ React55.createElement(
4322
+ ), /* @__PURE__ */ React56.createElement(
4300
4323
  "span",
4301
4324
  {
4302
4325
  className: "w-1.5 h-1.5 bg-gold/60 rounded-full animate-pulse",
4303
4326
  style: { animationDelay: "150ms" }
4304
4327
  }
4305
- ), /* @__PURE__ */ React55.createElement(
4328
+ ), /* @__PURE__ */ React56.createElement(
4306
4329
  "span",
4307
4330
  {
4308
4331
  className: "w-1.5 h-1.5 bg-gold/60 rounded-full animate-pulse",
4309
4332
  style: { animationDelay: "300ms" }
4310
4333
  }
4311
4334
  )),
4312
- /* @__PURE__ */ React55.createElement(
4335
+ /* @__PURE__ */ React56.createElement(
4313
4336
  "span",
4314
4337
  {
4315
4338
  className: cx(
@@ -4325,7 +4348,7 @@ var ThinkingIndicator = React55.forwardRef(
4325
4348
  ThinkingIndicator.displayName = "ThinkingIndicator";
4326
4349
 
4327
4350
  // src/components/chat/ChatView.tsx
4328
- var ChatView = React56.forwardRef(
4351
+ var ChatView = React57.forwardRef(
4329
4352
  ({ messages, latestUserMessageIndex, isStreaming, isThinking, onScroll, className, ...rest }, ref) => {
4330
4353
  const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
4331
4354
  behavior: "smooth",
@@ -4347,7 +4370,7 @@ var ChatView = React56.forwardRef(
4347
4370
  return found;
4348
4371
  }, -1);
4349
4372
  const showThinking = isThinking && messages.length > 0 && messages[messages.length - 1]?.variant === "user";
4350
- return /* @__PURE__ */ React56.createElement(
4373
+ return /* @__PURE__ */ React57.createElement(
4351
4374
  "div",
4352
4375
  {
4353
4376
  ref: (node) => {
@@ -4367,7 +4390,7 @@ var ChatView = React56.forwardRef(
4367
4390
  ),
4368
4391
  ...rest
4369
4392
  },
4370
- /* @__PURE__ */ React56.createElement("div", { ref: contentRef, className: "relative flex flex-col gap-3" }, messages.map(({
4393
+ /* @__PURE__ */ React57.createElement("div", { ref: contentRef, className: "relative flex flex-col gap-3" }, messages.map(({
4371
4394
  id,
4372
4395
  variant,
4373
4396
  className: messageClassName,
@@ -4380,14 +4403,14 @@ var ChatView = React56.forwardRef(
4380
4403
  const isLastMessage = index === messages.length - 1;
4381
4404
  const showStreaming = isLastMessage && isStreaming && variant === "assistant";
4382
4405
  const isMessageStreaming = showStreaming || !!nodeIsStreaming;
4383
- return /* @__PURE__ */ React56.createElement(
4406
+ return /* @__PURE__ */ React57.createElement(
4384
4407
  "div",
4385
4408
  {
4386
4409
  key: id ?? `msg-${index}`,
4387
4410
  ref: isAnchor ? anchorRef : void 0,
4388
4411
  className: isAnchor ? "scroll-mt-4" : void 0
4389
4412
  },
4390
- /* @__PURE__ */ React56.createElement(
4413
+ /* @__PURE__ */ React57.createElement(
4391
4414
  Message,
4392
4415
  {
4393
4416
  variant,
@@ -4400,8 +4423,8 @@ var ChatView = React56.forwardRef(
4400
4423
  }
4401
4424
  )
4402
4425
  );
4403
- }), showThinking && /* @__PURE__ */ React56.createElement(ThinkingIndicator, { isVisible: true })),
4404
- /* @__PURE__ */ React56.createElement(
4426
+ }), showThinking && /* @__PURE__ */ React57.createElement(ThinkingIndicator, { isVisible: true })),
4427
+ /* @__PURE__ */ React57.createElement(
4405
4428
  "div",
4406
4429
  {
4407
4430
  ref: spacerRef,
@@ -4416,7 +4439,7 @@ var ChatView = React56.forwardRef(
4416
4439
  ChatView.displayName = "ChatView";
4417
4440
 
4418
4441
  // src/components/chat/ChatInput.tsx
4419
- import React57, { useCallback as useCallback13, useEffect as useEffect10, useRef as useRef8, useState as useState13 } from "react";
4442
+ import React58, { useCallback as useCallback13, useEffect as useEffect10, useRef as useRef8, useState as useState13 } from "react";
4420
4443
  import { Paperclip, Send, Square } from "lucide-react";
4421
4444
 
4422
4445
  // src/components/chat/types.ts
@@ -4585,7 +4608,7 @@ function isBranchPoint(tree, nodeId) {
4585
4608
  }
4586
4609
 
4587
4610
  // src/components/chat/ChatInput.tsx
4588
- var ChatInput = React57.forwardRef(
4611
+ var ChatInput = React58.forwardRef(
4589
4612
  ({
4590
4613
  position = "bottom",
4591
4614
  placeholder = "Send a message...",
@@ -4719,7 +4742,7 @@ var ChatInput = React57.forwardRef(
4719
4742
  const isCentered = position === "centered";
4720
4743
  const hasAttachments = attachments.length > 0;
4721
4744
  const canSubmit = value.trim() && !disabled && !isStreaming;
4722
- return /* @__PURE__ */ React57.createElement(
4745
+ return /* @__PURE__ */ React58.createElement(
4723
4746
  "div",
4724
4747
  {
4725
4748
  ref,
@@ -4731,8 +4754,8 @@ var ChatInput = React57.forwardRef(
4731
4754
  ),
4732
4755
  ...rest
4733
4756
  },
4734
- isCentered && helperText && /* @__PURE__ */ React57.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
4735
- /* @__PURE__ */ React57.createElement(
4757
+ isCentered && helperText && /* @__PURE__ */ React58.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
4758
+ /* @__PURE__ */ React58.createElement(
4736
4759
  "div",
4737
4760
  {
4738
4761
  className: cx(
@@ -4747,7 +4770,7 @@ var ChatInput = React57.forwardRef(
4747
4770
  onDragOver: showAttachmentButton ? handleDragOver : void 0,
4748
4771
  onDrop: showAttachmentButton ? handleDrop : void 0
4749
4772
  },
4750
- hasAttachments && /* @__PURE__ */ React57.createElement("div", { className: "px-3 pt-3 pb-1" }, /* @__PURE__ */ React57.createElement(
4773
+ hasAttachments && /* @__PURE__ */ React58.createElement("div", { className: "px-3 pt-3 pb-1" }, /* @__PURE__ */ React58.createElement(
4751
4774
  AttachmentPreview,
4752
4775
  {
4753
4776
  attachments,
@@ -4755,14 +4778,14 @@ var ChatInput = React57.forwardRef(
4755
4778
  removable: !isStreaming
4756
4779
  }
4757
4780
  )),
4758
- isDragOver && /* @__PURE__ */ React57.createElement(
4781
+ isDragOver && /* @__PURE__ */ React58.createElement(
4759
4782
  "div",
4760
4783
  {
4761
4784
  className: "absolute inset-0 bg-gold/10 flex items-center justify-center z-10 pointer-events-none"
4762
4785
  },
4763
- /* @__PURE__ */ React57.createElement("span", { className: "text-gold text-sm font-medium" }, "Drop files here")
4786
+ /* @__PURE__ */ React58.createElement("span", { className: "text-gold text-sm font-medium" }, "Drop files here")
4764
4787
  ),
4765
- /* @__PURE__ */ React57.createElement("div", { className: "flex items-end" }, showAttachmentButton && /* @__PURE__ */ React57.createElement(React57.Fragment, null, /* @__PURE__ */ React57.createElement(
4788
+ /* @__PURE__ */ React58.createElement("div", { className: "flex items-end" }, showAttachmentButton && /* @__PURE__ */ React58.createElement(React58.Fragment, null, /* @__PURE__ */ React58.createElement(
4766
4789
  "button",
4767
4790
  {
4768
4791
  type: "button",
@@ -4774,8 +4797,8 @@ var ChatInput = React57.forwardRef(
4774
4797
  ),
4775
4798
  "aria-label": "Attach file"
4776
4799
  },
4777
- /* @__PURE__ */ React57.createElement(Paperclip, { className: "w-5 h-5" })
4778
- ), /* @__PURE__ */ React57.createElement(
4800
+ /* @__PURE__ */ React58.createElement(Paperclip, { className: "w-5 h-5" })
4801
+ ), /* @__PURE__ */ React58.createElement(
4779
4802
  "input",
4780
4803
  {
4781
4804
  ref: fileInputRef,
@@ -4786,7 +4809,7 @@ var ChatInput = React57.forwardRef(
4786
4809
  className: "hidden",
4787
4810
  "aria-hidden": "true"
4788
4811
  }
4789
- )), /* @__PURE__ */ React57.createElement(
4812
+ )), /* @__PURE__ */ React58.createElement(
4790
4813
  "textarea",
4791
4814
  {
4792
4815
  ref: textareaRef,
@@ -4804,7 +4827,7 @@ var ChatInput = React57.forwardRef(
4804
4827
  ),
4805
4828
  style: { maxHeight: 200 }
4806
4829
  }
4807
- ), isStreaming ? /* @__PURE__ */ React57.createElement(
4830
+ ), isStreaming ? /* @__PURE__ */ React58.createElement(
4808
4831
  "button",
4809
4832
  {
4810
4833
  type: "button",
@@ -4815,8 +4838,8 @@ var ChatInput = React57.forwardRef(
4815
4838
  ),
4816
4839
  "aria-label": "Stop generation"
4817
4840
  },
4818
- /* @__PURE__ */ React57.createElement(Square, { className: "w-5 h-5 fill-current" })
4819
- ) : /* @__PURE__ */ React57.createElement(
4841
+ /* @__PURE__ */ React58.createElement(Square, { className: "w-5 h-5 fill-current" })
4842
+ ) : /* @__PURE__ */ React58.createElement(
4820
4843
  "button",
4821
4844
  {
4822
4845
  type: "button",
@@ -4829,7 +4852,7 @@ var ChatInput = React57.forwardRef(
4829
4852
  ),
4830
4853
  "aria-label": "Send message"
4831
4854
  },
4832
- /* @__PURE__ */ React57.createElement(Send, { className: "w-5 h-5" })
4855
+ /* @__PURE__ */ React58.createElement(Send, { className: "w-5 h-5" })
4833
4856
  ))
4834
4857
  )
4835
4858
  );
@@ -4838,9 +4861,9 @@ var ChatInput = React57.forwardRef(
4838
4861
  ChatInput.displayName = "ChatInput";
4839
4862
 
4840
4863
  // src/components/chat/ConversationSidebar.tsx
4841
- import React58 from "react";
4864
+ import React59 from "react";
4842
4865
  function HistoryIcon2({ className }) {
4843
- return /* @__PURE__ */ React58.createElement(
4866
+ return /* @__PURE__ */ React59.createElement(
4844
4867
  "svg",
4845
4868
  {
4846
4869
  xmlns: "http://www.w3.org/2000/svg",
@@ -4848,7 +4871,7 @@ function HistoryIcon2({ className }) {
4848
4871
  fill: "currentColor",
4849
4872
  className
4850
4873
  },
4851
- /* @__PURE__ */ React58.createElement(
4874
+ /* @__PURE__ */ React59.createElement(
4852
4875
  "path",
4853
4876
  {
4854
4877
  fillRule: "evenodd",
@@ -4859,7 +4882,7 @@ function HistoryIcon2({ className }) {
4859
4882
  );
4860
4883
  }
4861
4884
  function ChevronLeftIcon3({ className }) {
4862
- return /* @__PURE__ */ React58.createElement(
4885
+ return /* @__PURE__ */ React59.createElement(
4863
4886
  "svg",
4864
4887
  {
4865
4888
  xmlns: "http://www.w3.org/2000/svg",
@@ -4867,7 +4890,7 @@ function ChevronLeftIcon3({ className }) {
4867
4890
  fill: "currentColor",
4868
4891
  className
4869
4892
  },
4870
- /* @__PURE__ */ React58.createElement(
4893
+ /* @__PURE__ */ React59.createElement(
4871
4894
  "path",
4872
4895
  {
4873
4896
  fillRule: "evenodd",
@@ -4877,7 +4900,7 @@ function ChevronLeftIcon3({ className }) {
4877
4900
  )
4878
4901
  );
4879
4902
  }
4880
- var ConversationSidebar = React58.forwardRef(
4903
+ var ConversationSidebar = React59.forwardRef(
4881
4904
  ({
4882
4905
  conversations,
4883
4906
  isCollapsed = false,
@@ -4890,7 +4913,7 @@ var ConversationSidebar = React58.forwardRef(
4890
4913
  ...rest
4891
4914
  }, ref) => {
4892
4915
  if (isCollapsed) {
4893
- return /* @__PURE__ */ React58.createElement(
4916
+ return /* @__PURE__ */ React59.createElement(
4894
4917
  "div",
4895
4918
  {
4896
4919
  ref,
@@ -4901,7 +4924,7 @@ var ConversationSidebar = React58.forwardRef(
4901
4924
  ),
4902
4925
  ...rest
4903
4926
  },
4904
- /* @__PURE__ */ React58.createElement(
4927
+ /* @__PURE__ */ React59.createElement(
4905
4928
  "button",
4906
4929
  {
4907
4930
  onClick: onToggleCollapse,
@@ -4912,11 +4935,11 @@ var ConversationSidebar = React58.forwardRef(
4912
4935
  ),
4913
4936
  "aria-label": "Expand sidebar"
4914
4937
  },
4915
- /* @__PURE__ */ React58.createElement(HistoryIcon2, { className: "w-5 h-5" })
4938
+ /* @__PURE__ */ React59.createElement(HistoryIcon2, { className: "w-5 h-5" })
4916
4939
  )
4917
4940
  );
4918
4941
  }
4919
- return /* @__PURE__ */ React58.createElement(
4942
+ return /* @__PURE__ */ React59.createElement(
4920
4943
  "div",
4921
4944
  {
4922
4945
  ref,
@@ -4930,7 +4953,7 @@ var ConversationSidebar = React58.forwardRef(
4930
4953
  style: width ? { width } : void 0,
4931
4954
  ...rest
4932
4955
  },
4933
- /* @__PURE__ */ React58.createElement(
4956
+ /* @__PURE__ */ React59.createElement(
4934
4957
  "div",
4935
4958
  {
4936
4959
  onMouseDown: onResizeStart,
@@ -4943,7 +4966,7 @@ var ConversationSidebar = React58.forwardRef(
4943
4966
  )
4944
4967
  }
4945
4968
  ),
4946
- /* @__PURE__ */ React58.createElement("div", { className: "p-3 border-b border-ash/40 flex-shrink-0 flex items-center gap-2" }, /* @__PURE__ */ React58.createElement(
4969
+ /* @__PURE__ */ React59.createElement("div", { className: "p-3 border-b border-ash/40 flex-shrink-0 flex items-center gap-2" }, /* @__PURE__ */ React59.createElement(
4947
4970
  "button",
4948
4971
  {
4949
4972
  onClick: onToggleCollapse,
@@ -4954,8 +4977,8 @@ var ConversationSidebar = React58.forwardRef(
4954
4977
  ),
4955
4978
  "aria-label": "Collapse sidebar"
4956
4979
  },
4957
- /* @__PURE__ */ React58.createElement(ChevronLeftIcon3, { className: "w-5 h-5" })
4958
- ), /* @__PURE__ */ React58.createElement(
4980
+ /* @__PURE__ */ React59.createElement(ChevronLeftIcon3, { className: "w-5 h-5" })
4981
+ ), /* @__PURE__ */ React59.createElement(
4959
4982
  "button",
4960
4983
  {
4961
4984
  onClick: onNewChat,
@@ -4967,7 +4990,7 @@ var ConversationSidebar = React58.forwardRef(
4967
4990
  "transition-colors duration-200"
4968
4991
  )
4969
4992
  },
4970
- /* @__PURE__ */ React58.createElement(
4993
+ /* @__PURE__ */ React59.createElement(
4971
4994
  "svg",
4972
4995
  {
4973
4996
  xmlns: "http://www.w3.org/2000/svg",
@@ -4975,16 +4998,16 @@ var ConversationSidebar = React58.forwardRef(
4975
4998
  fill: "currentColor",
4976
4999
  className: "w-4 h-4"
4977
5000
  },
4978
- /* @__PURE__ */ React58.createElement(
5001
+ /* @__PURE__ */ React59.createElement(
4979
5002
  "path",
4980
5003
  {
4981
5004
  d: "M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z"
4982
5005
  }
4983
5006
  )
4984
5007
  ),
4985
- /* @__PURE__ */ React58.createElement("span", { className: "text-sm font-medium" }, "New Chat")
5008
+ /* @__PURE__ */ React59.createElement("span", { className: "text-sm font-medium" }, "New Chat")
4986
5009
  )),
4987
- /* @__PURE__ */ React58.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ React58.createElement("p", { className: "px-4 py-2 text-sm text-silver/60" }, "No conversations yet") : /* @__PURE__ */ React58.createElement("div", { className: "space-y-1 px-2" }, conversations.map((conversation) => /* @__PURE__ */ React58.createElement(
5010
+ /* @__PURE__ */ React59.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ React59.createElement("p", { className: "px-4 py-2 text-sm text-silver/60" }, "No conversations yet") : /* @__PURE__ */ React59.createElement("div", { className: "space-y-1 px-2" }, conversations.map((conversation) => /* @__PURE__ */ React59.createElement(
4988
5011
  "button",
4989
5012
  {
4990
5013
  key: conversation.id,
@@ -4995,16 +5018,16 @@ var ConversationSidebar = React58.forwardRef(
4995
5018
  conversation.isActive ? "bg-ash/40 text-white" : "text-silver hover:bg-ash/20 hover:text-white"
4996
5019
  )
4997
5020
  },
4998
- /* @__PURE__ */ React58.createElement("p", { className: "text-sm font-medium truncate" }, conversation.title),
4999
- conversation.preview && /* @__PURE__ */ React58.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.preview),
5000
- conversation.timestamp && /* @__PURE__ */ React58.createElement("p", { className: "text-xs text-silver/40 mt-1" }, conversation.timestamp)
5021
+ /* @__PURE__ */ React59.createElement("p", { className: "text-sm font-medium truncate" }, conversation.title),
5022
+ conversation.preview && /* @__PURE__ */ React59.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.preview),
5023
+ conversation.timestamp && /* @__PURE__ */ React59.createElement("p", { className: "text-xs text-silver/40 mt-1" }, conversation.timestamp)
5001
5024
  ))))
5002
5025
  );
5003
5026
  }
5004
5027
  );
5005
5028
  ConversationSidebar.displayName = "ConversationSidebar";
5006
- var CollapsedSidebarToggle = React58.forwardRef(({ onExpand, className, ...rest }, ref) => {
5007
- return /* @__PURE__ */ React58.createElement(
5029
+ var CollapsedSidebarToggle = React59.forwardRef(({ onExpand, className, ...rest }, ref) => {
5030
+ return /* @__PURE__ */ React59.createElement(
5008
5031
  "button",
5009
5032
  {
5010
5033
  ref,
@@ -5019,19 +5042,19 @@ var CollapsedSidebarToggle = React58.forwardRef(({ onExpand, className, ...rest
5019
5042
  "aria-label": "Expand sidebar",
5020
5043
  ...rest
5021
5044
  },
5022
- /* @__PURE__ */ React58.createElement(HistoryIcon2, { className: "w-5 h-5" })
5045
+ /* @__PURE__ */ React59.createElement(HistoryIcon2, { className: "w-5 h-5" })
5023
5046
  );
5024
5047
  });
5025
5048
  CollapsedSidebarToggle.displayName = "CollapsedSidebarToggle";
5026
5049
 
5027
5050
  // src/components/chat/ArtifactsPanel.tsx
5028
- import React66, { useCallback as useCallback14, useEffect as useEffect11, useState as useState14 } from "react";
5051
+ import React69, { useCallback as useCallback15, useEffect as useEffect12, useRef as useRef10, useState as useState16 } from "react";
5029
5052
 
5030
5053
  // src/components/ArtifactCard.tsx
5031
- import React65 from "react";
5054
+ import React66 from "react";
5032
5055
 
5033
5056
  // src/components/ImageCard.tsx
5034
- import React59 from "react";
5057
+ import React60 from "react";
5035
5058
  var ASPECT_RATIO_PRESETS = {
5036
5059
  landscape: "3 / 2",
5037
5060
  portrait: "2 / 3",
@@ -5043,7 +5066,7 @@ function resolveAspectRatio(ratio) {
5043
5066
  }
5044
5067
  return ratio.replace("/", " / ");
5045
5068
  }
5046
- var ImageCard = React59.forwardRef(
5069
+ var ImageCard = React60.forwardRef(
5047
5070
  ({
5048
5071
  src,
5049
5072
  alt = "",
@@ -5059,7 +5082,7 @@ var ImageCard = React59.forwardRef(
5059
5082
  loading,
5060
5083
  ...props
5061
5084
  }, ref) => {
5062
- return /* @__PURE__ */ React59.createElement(
5085
+ return /* @__PURE__ */ React60.createElement(
5063
5086
  Card,
5064
5087
  {
5065
5088
  ref,
@@ -5067,13 +5090,13 @@ var ImageCard = React59.forwardRef(
5067
5090
  loading,
5068
5091
  ...props
5069
5092
  },
5070
- /* @__PURE__ */ React59.createElement(
5093
+ /* @__PURE__ */ React60.createElement(
5071
5094
  Card.Media,
5072
5095
  {
5073
5096
  className: mediaClassName,
5074
5097
  style: { aspectRatio: resolveAspectRatio(aspectRatio) }
5075
5098
  },
5076
- /* @__PURE__ */ React59.createElement(React59.Fragment, null, src && /* @__PURE__ */ React59.createElement(
5099
+ /* @__PURE__ */ React60.createElement(React60.Fragment, null, src && /* @__PURE__ */ React60.createElement(
5077
5100
  "img",
5078
5101
  {
5079
5102
  src,
@@ -5083,7 +5106,7 @@ var ImageCard = React59.forwardRef(
5083
5106
  objectFit === "cover" ? "object-cover" : "object-contain"
5084
5107
  )
5085
5108
  }
5086
- ), overlay && /* @__PURE__ */ React59.createElement(
5109
+ ), overlay && /* @__PURE__ */ React60.createElement(
5087
5110
  "div",
5088
5111
  {
5089
5112
  className: "absolute inset-0 bg-obsidian/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex items-center justify-center"
@@ -5091,7 +5114,7 @@ var ImageCard = React59.forwardRef(
5091
5114
  overlay
5092
5115
  ))
5093
5116
  ),
5094
- /* @__PURE__ */ React59.createElement(
5117
+ /* @__PURE__ */ React60.createElement(
5095
5118
  Card.Header,
5096
5119
  {
5097
5120
  title,
@@ -5099,14 +5122,14 @@ var ImageCard = React59.forwardRef(
5099
5122
  className: contentClassName
5100
5123
  }
5101
5124
  ),
5102
- children && /* @__PURE__ */ React59.createElement(Card.Body, { className: contentClassName }, children)
5125
+ children && /* @__PURE__ */ React60.createElement(Card.Body, { className: contentClassName }, children)
5103
5126
  );
5104
5127
  }
5105
5128
  );
5106
5129
  ImageCard.displayName = "ImageCard";
5107
5130
 
5108
5131
  // src/components/VideoCard.tsx
5109
- import React60 from "react";
5132
+ import React61 from "react";
5110
5133
  import ReactPlayer from "react-player";
5111
5134
  var ASPECT_RATIO_PRESETS2 = {
5112
5135
  video: "16 / 9",
@@ -5119,7 +5142,7 @@ function resolveAspectRatio2(ratio) {
5119
5142
  }
5120
5143
  return ratio.replace("/", " / ");
5121
5144
  }
5122
- var VideoCard = React60.forwardRef(
5145
+ var VideoCard = React61.forwardRef(
5123
5146
  ({
5124
5147
  src,
5125
5148
  title,
@@ -5139,7 +5162,7 @@ var VideoCard = React60.forwardRef(
5139
5162
  loading,
5140
5163
  ...props
5141
5164
  }, ref) => {
5142
- return /* @__PURE__ */ React60.createElement(
5165
+ return /* @__PURE__ */ React61.createElement(
5143
5166
  Card,
5144
5167
  {
5145
5168
  ref,
@@ -5147,13 +5170,13 @@ var VideoCard = React60.forwardRef(
5147
5170
  loading,
5148
5171
  ...props
5149
5172
  },
5150
- /* @__PURE__ */ React60.createElement(
5173
+ /* @__PURE__ */ React61.createElement(
5151
5174
  Card.Media,
5152
5175
  {
5153
5176
  className: mediaClassName,
5154
5177
  style: { aspectRatio: resolveAspectRatio2(aspectRatio) }
5155
5178
  },
5156
- src && /* @__PURE__ */ React60.createElement(
5179
+ src && /* @__PURE__ */ React61.createElement(
5157
5180
  ReactPlayer,
5158
5181
  {
5159
5182
  src,
@@ -5170,7 +5193,7 @@ var VideoCard = React60.forwardRef(
5170
5193
  }
5171
5194
  )
5172
5195
  ),
5173
- /* @__PURE__ */ React60.createElement(
5196
+ /* @__PURE__ */ React61.createElement(
5174
5197
  Card.Header,
5175
5198
  {
5176
5199
  title,
@@ -5178,17 +5201,17 @@ var VideoCard = React60.forwardRef(
5178
5201
  className: contentClassName
5179
5202
  }
5180
5203
  ),
5181
- children && /* @__PURE__ */ React60.createElement(Card.Body, { className: contentClassName }, children)
5204
+ children && /* @__PURE__ */ React61.createElement(Card.Body, { className: contentClassName }, children)
5182
5205
  );
5183
5206
  }
5184
5207
  );
5185
5208
  VideoCard.displayName = "VideoCard";
5186
5209
 
5187
5210
  // src/components/AudioCard.tsx
5188
- import React61 from "react";
5211
+ import React62 from "react";
5189
5212
  import ReactPlayer2 from "react-player";
5190
5213
  import { Music } from "lucide-react";
5191
- var AudioCard = React61.forwardRef(
5214
+ var AudioCard = React62.forwardRef(
5192
5215
  ({
5193
5216
  src,
5194
5217
  title,
@@ -5207,7 +5230,7 @@ var AudioCard = React61.forwardRef(
5207
5230
  loading,
5208
5231
  ...props
5209
5232
  }, ref) => {
5210
- return /* @__PURE__ */ React61.createElement(
5233
+ return /* @__PURE__ */ React62.createElement(
5211
5234
  Card,
5212
5235
  {
5213
5236
  ref,
@@ -5215,10 +5238,10 @@ var AudioCard = React61.forwardRef(
5215
5238
  loading,
5216
5239
  ...props
5217
5240
  },
5218
- /* @__PURE__ */ React61.createElement(Card.Media, { className: cx(
5241
+ /* @__PURE__ */ React62.createElement(Card.Media, { className: cx(
5219
5242
  "bg-obsidian py-8 flex flex-col items-center justify-center",
5220
5243
  mediaClassName
5221
- ) }, /* @__PURE__ */ React61.createElement("div", { className: "mb-4 text-gold" }, /* @__PURE__ */ React61.createElement(Music, { size: 48 })), src && /* @__PURE__ */ React61.createElement("div", { className: "w-full px-4" }, /* @__PURE__ */ React61.createElement(
5244
+ ) }, /* @__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(
5222
5245
  ReactPlayer2,
5223
5246
  {
5224
5247
  src,
@@ -5241,7 +5264,7 @@ var AudioCard = React61.forwardRef(
5241
5264
  ...playerProps
5242
5265
  }
5243
5266
  ))),
5244
- /* @__PURE__ */ React61.createElement(
5267
+ /* @__PURE__ */ React62.createElement(
5245
5268
  Card.Header,
5246
5269
  {
5247
5270
  title,
@@ -5249,16 +5272,16 @@ var AudioCard = React61.forwardRef(
5249
5272
  className: contentClassName
5250
5273
  }
5251
5274
  ),
5252
- children && /* @__PURE__ */ React61.createElement(Card.Body, { className: contentClassName }, children)
5275
+ children && /* @__PURE__ */ React62.createElement(Card.Body, { className: contentClassName }, children)
5253
5276
  );
5254
5277
  }
5255
5278
  );
5256
5279
  AudioCard.displayName = "AudioCard";
5257
5280
 
5258
5281
  // src/components/PdfCard.tsx
5259
- import React62 from "react";
5282
+ import React63 from "react";
5260
5283
  import { FileText as FileText2 } from "lucide-react";
5261
- var PdfCard = React62.forwardRef(
5284
+ var PdfCard = React63.forwardRef(
5262
5285
  ({
5263
5286
  src,
5264
5287
  title,
@@ -5271,7 +5294,7 @@ var PdfCard = React62.forwardRef(
5271
5294
  loading,
5272
5295
  ...props
5273
5296
  }, ref) => {
5274
- return /* @__PURE__ */ React62.createElement(
5297
+ return /* @__PURE__ */ React63.createElement(
5275
5298
  Card,
5276
5299
  {
5277
5300
  ref,
@@ -5279,13 +5302,13 @@ var PdfCard = React62.forwardRef(
5279
5302
  loading,
5280
5303
  ...props
5281
5304
  },
5282
- /* @__PURE__ */ React62.createElement(
5305
+ /* @__PURE__ */ React63.createElement(
5283
5306
  Card.Media,
5284
5307
  {
5285
5308
  className: cx("bg-obsidian", mediaClassName),
5286
5309
  style: { height }
5287
5310
  },
5288
- src && /* @__PURE__ */ React62.createElement(
5311
+ src && /* @__PURE__ */ React63.createElement(
5289
5312
  "iframe",
5290
5313
  {
5291
5314
  src: `${src}#view=FitH`,
@@ -5294,23 +5317,23 @@ var PdfCard = React62.forwardRef(
5294
5317
  }
5295
5318
  )
5296
5319
  ),
5297
- /* @__PURE__ */ React62.createElement(
5320
+ /* @__PURE__ */ React63.createElement(
5298
5321
  Card.Header,
5299
5322
  {
5300
5323
  title,
5301
5324
  subtitle,
5302
5325
  className: contentClassName,
5303
- action: /* @__PURE__ */ React62.createElement("div", { className: "p-2 bg-ash/20 text-gold shrink-0" }, /* @__PURE__ */ React62.createElement(FileText2, { size: 20 }))
5326
+ action: /* @__PURE__ */ React63.createElement("div", { className: "p-2 bg-ash/20 text-gold shrink-0" }, /* @__PURE__ */ React63.createElement(FileText2, { size: 20 }))
5304
5327
  }
5305
5328
  ),
5306
- children && /* @__PURE__ */ React62.createElement(Card.Body, { className: contentClassName }, children)
5329
+ children && /* @__PURE__ */ React63.createElement(Card.Body, { className: contentClassName }, children)
5307
5330
  );
5308
5331
  }
5309
5332
  );
5310
5333
  PdfCard.displayName = "PdfCard";
5311
5334
 
5312
5335
  // src/components/ScriptCard.tsx
5313
- import React63 from "react";
5336
+ import React64 from "react";
5314
5337
  var SCRIPT_ELEMENT_TYPES = {
5315
5338
  SCENE_HEADING: "scene-heading",
5316
5339
  ACTION: "action",
@@ -5324,28 +5347,28 @@ var SCRIPT_ELEMENT_TYPES = {
5324
5347
  function ScriptElementRenderer({ element }) {
5325
5348
  switch (element.type) {
5326
5349
  case "scene-heading":
5327
- return /* @__PURE__ */ React63.createElement("p", { className: "mt-4 mb-2 font-bold uppercase text-gold text-xs tracking-wide" }, element.content);
5350
+ return /* @__PURE__ */ React64.createElement("p", { className: "mt-4 mb-2 font-bold uppercase text-gold text-xs tracking-wide" }, element.content);
5328
5351
  case "action":
5329
- return /* @__PURE__ */ React63.createElement("p", { className: "my-2 text-silver text-xs leading-relaxed" }, element.content);
5352
+ return /* @__PURE__ */ React64.createElement("p", { className: "my-2 text-silver text-xs leading-relaxed" }, element.content);
5330
5353
  case "character":
5331
- return /* @__PURE__ */ React63.createElement("p", { className: "mt-4 mb-0.5 ml-8 font-bold text-white text-xs uppercase tracking-wide" }, element.content);
5354
+ return /* @__PURE__ */ React64.createElement("p", { className: "mt-4 mb-0.5 ml-8 font-bold text-white text-xs uppercase tracking-wide" }, element.content);
5332
5355
  case "parenthetical":
5333
- return /* @__PURE__ */ React63.createElement("p", { className: "ml-6 text-silver/70 text-xs italic" }, "(", element.content, ")");
5356
+ return /* @__PURE__ */ React64.createElement("p", { className: "ml-6 text-silver/70 text-xs italic" }, "(", element.content, ")");
5334
5357
  case "dialogue":
5335
- return /* @__PURE__ */ React63.createElement("p", { className: "ml-4 mr-8 text-silver text-xs leading-relaxed" }, element.content);
5358
+ return /* @__PURE__ */ React64.createElement("p", { className: "ml-4 mr-8 text-silver text-xs leading-relaxed" }, element.content);
5336
5359
  case "transition":
5337
- return /* @__PURE__ */ React63.createElement("p", { className: "mt-4 mb-2 text-right font-bold uppercase text-gold/80 text-xs tracking-wide" }, element.content);
5360
+ return /* @__PURE__ */ React64.createElement("p", { className: "mt-4 mb-2 text-right font-bold uppercase text-gold/80 text-xs tracking-wide" }, element.content);
5338
5361
  case "title":
5339
- return /* @__PURE__ */ React63.createElement("p", { className: "mt-6 mb-2 text-center font-bold text-gold text-sm" }, element.content);
5362
+ return /* @__PURE__ */ React64.createElement("p", { className: "mt-6 mb-2 text-center font-bold text-gold text-sm" }, element.content);
5340
5363
  case "subtitle":
5341
- return /* @__PURE__ */ React63.createElement("p", { className: "text-center italic text-gold/70 text-xs" }, element.content);
5364
+ return /* @__PURE__ */ React64.createElement("p", { className: "text-center italic text-gold/70 text-xs" }, element.content);
5342
5365
  default:
5343
5366
  return null;
5344
5367
  }
5345
5368
  }
5346
- var ScriptCard = React63.forwardRef(
5369
+ var ScriptCard = React64.forwardRef(
5347
5370
  ({ title, subtitle, elements, maxHeight = "16rem", className, style, loading, ...rest }, ref) => {
5348
- return /* @__PURE__ */ React63.createElement(
5371
+ return /* @__PURE__ */ React64.createElement(
5349
5372
  Card,
5350
5373
  {
5351
5374
  ref,
@@ -5353,20 +5376,20 @@ var ScriptCard = React63.forwardRef(
5353
5376
  loading,
5354
5377
  ...rest
5355
5378
  },
5356
- /* @__PURE__ */ React63.createElement(
5379
+ /* @__PURE__ */ React64.createElement(
5357
5380
  Card.Header,
5358
5381
  {
5359
5382
  title,
5360
5383
  subtitle
5361
5384
  }
5362
5385
  ),
5363
- /* @__PURE__ */ React63.createElement(
5386
+ /* @__PURE__ */ React64.createElement(
5364
5387
  Card.Body,
5365
5388
  {
5366
5389
  className: "font-mono overflow-y-auto",
5367
5390
  style: { maxHeight, ...style }
5368
5391
  },
5369
- elements.map((element, index) => /* @__PURE__ */ React63.createElement(ScriptElementRenderer, { key: index, element }))
5392
+ elements.map((element, index) => /* @__PURE__ */ React64.createElement(ScriptElementRenderer, { key: index, element }))
5370
5393
  )
5371
5394
  );
5372
5395
  }
@@ -5374,8 +5397,8 @@ var ScriptCard = React63.forwardRef(
5374
5397
  ScriptCard.displayName = "ScriptCard";
5375
5398
 
5376
5399
  // src/components/TextCard.tsx
5377
- import React64 from "react";
5378
- var TextCard = React64.forwardRef(
5400
+ import React65 from "react";
5401
+ var TextCard = React65.forwardRef(
5379
5402
  ({
5380
5403
  content,
5381
5404
  title,
@@ -5387,7 +5410,7 @@ var TextCard = React64.forwardRef(
5387
5410
  loading,
5388
5411
  ...props
5389
5412
  }, ref) => {
5390
- return /* @__PURE__ */ React64.createElement(
5413
+ return /* @__PURE__ */ React65.createElement(
5391
5414
  Card,
5392
5415
  {
5393
5416
  ref,
@@ -5395,20 +5418,20 @@ var TextCard = React64.forwardRef(
5395
5418
  loading,
5396
5419
  ...props
5397
5420
  },
5398
- /* @__PURE__ */ React64.createElement(
5421
+ /* @__PURE__ */ React65.createElement(
5399
5422
  Card.Header,
5400
5423
  {
5401
5424
  title,
5402
5425
  subtitle
5403
5426
  }
5404
5427
  ),
5405
- /* @__PURE__ */ React64.createElement(
5428
+ /* @__PURE__ */ React65.createElement(
5406
5429
  Card.Body,
5407
5430
  {
5408
5431
  className: cx("overflow-y-auto", contentClassName),
5409
5432
  style: { maxHeight }
5410
5433
  },
5411
- /* @__PURE__ */ React64.createElement(
5434
+ /* @__PURE__ */ React65.createElement(
5412
5435
  MarkdownContent,
5413
5436
  {
5414
5437
  content,
@@ -5446,7 +5469,7 @@ var ARTIFACT_TYPES = {
5446
5469
  SCRIPT: "SCRIPT",
5447
5470
  PDF: "PDF"
5448
5471
  };
5449
- var ArtifactCard = React65.forwardRef(
5472
+ var ArtifactCard = React66.forwardRef(
5450
5473
  ({ artifact, onExpand, loading, className, ...props }, ref) => {
5451
5474
  const derivedLoading = deriveCardSlotLoading(artifact);
5452
5475
  const commonProps = {
@@ -5464,7 +5487,7 @@ var ArtifactCard = React65.forwardRef(
5464
5487
  const renderContent = () => {
5465
5488
  switch (artifact.type) {
5466
5489
  case "IMAGE":
5467
- return /* @__PURE__ */ React65.createElement(
5490
+ return /* @__PURE__ */ React66.createElement(
5468
5491
  ImageCard,
5469
5492
  {
5470
5493
  ...commonProps,
@@ -5474,7 +5497,7 @@ var ArtifactCard = React65.forwardRef(
5474
5497
  }
5475
5498
  );
5476
5499
  case "VIDEO":
5477
- return /* @__PURE__ */ React65.createElement(
5500
+ return /* @__PURE__ */ React66.createElement(
5478
5501
  VideoCard,
5479
5502
  {
5480
5503
  ...commonProps,
@@ -5484,7 +5507,7 @@ var ArtifactCard = React65.forwardRef(
5484
5507
  }
5485
5508
  );
5486
5509
  case "AUDIO":
5487
- return /* @__PURE__ */ React65.createElement(
5510
+ return /* @__PURE__ */ React66.createElement(
5488
5511
  AudioCard,
5489
5512
  {
5490
5513
  ...commonProps,
@@ -5493,7 +5516,7 @@ var ArtifactCard = React65.forwardRef(
5493
5516
  }
5494
5517
  );
5495
5518
  case "PDF":
5496
- return /* @__PURE__ */ React65.createElement(
5519
+ return /* @__PURE__ */ React66.createElement(
5497
5520
  PdfCard,
5498
5521
  {
5499
5522
  ...commonProps,
@@ -5501,7 +5524,7 @@ var ArtifactCard = React65.forwardRef(
5501
5524
  }
5502
5525
  );
5503
5526
  case "SCRIPT":
5504
- return /* @__PURE__ */ React65.createElement(
5527
+ return /* @__PURE__ */ React66.createElement(
5505
5528
  ScriptCard,
5506
5529
  {
5507
5530
  ...commonProps,
@@ -5510,7 +5533,7 @@ var ArtifactCard = React65.forwardRef(
5510
5533
  }
5511
5534
  );
5512
5535
  case "TEXT":
5513
- return /* @__PURE__ */ React65.createElement(
5536
+ return /* @__PURE__ */ React66.createElement(
5514
5537
  TextCard,
5515
5538
  {
5516
5539
  ...commonProps,
@@ -5526,7 +5549,7 @@ var ArtifactCard = React65.forwardRef(
5526
5549
  }
5527
5550
  };
5528
5551
  const isCardExpandable = !!onExpand && (artifact.type === "IMAGE" || artifact.type === "PDF" || artifact.type === "SCRIPT" || artifact.type === "TEXT");
5529
- return /* @__PURE__ */ React65.createElement(
5552
+ return /* @__PURE__ */ React66.createElement(
5530
5553
  "div",
5531
5554
  {
5532
5555
  ref,
@@ -5539,7 +5562,7 @@ var ArtifactCard = React65.forwardRef(
5539
5562
  onClick: isCardExpandable ? handleExpand : void 0,
5540
5563
  ...props
5541
5564
  },
5542
- onExpand && /* @__PURE__ */ React65.createElement(
5565
+ onExpand && /* @__PURE__ */ React66.createElement(
5543
5566
  "button",
5544
5567
  {
5545
5568
  onClick: handleExpand,
@@ -5550,7 +5573,7 @@ var ArtifactCard = React65.forwardRef(
5550
5573
  ),
5551
5574
  "aria-label": "Expand artifact"
5552
5575
  },
5553
- /* @__PURE__ */ React65.createElement(ExpandIcon, { className: "w-4 h-4" })
5576
+ /* @__PURE__ */ React66.createElement(ExpandIcon, { className: "w-4 h-4" })
5554
5577
  ),
5555
5578
  renderContent()
5556
5579
  );
@@ -5558,12 +5581,178 @@ var ArtifactCard = React65.forwardRef(
5558
5581
  );
5559
5582
  ArtifactCard.displayName = "ArtifactCard";
5560
5583
 
5584
+ // src/components/ArtifactGroup.tsx
5585
+ import React67, { useEffect as useEffect11, useRef as useRef9, useState as useState14 } from "react";
5586
+ var LAYER_OFFSET = "8px";
5587
+ var LAYER_OFFSET_2X = "16px";
5588
+ var ArtifactGroup = React67.forwardRef(
5589
+ ({ node, onClick, className, ...props }, ref) => {
5590
+ const children = node.children;
5591
+ const count = children.length;
5592
+ const frontChild = children[0];
5593
+ const prevCountRef = useRef9(count);
5594
+ const [badgePing, setBadgePing] = useState14(false);
5595
+ useEffect11(() => {
5596
+ if (count !== prevCountRef.current) {
5597
+ prevCountRef.current = count;
5598
+ setBadgePing(true);
5599
+ const timer = setTimeout(() => setBadgePing(false), 500);
5600
+ return () => clearTimeout(timer);
5601
+ }
5602
+ }, [count]);
5603
+ const handleClick = () => {
5604
+ if (onClick) {
5605
+ onClick(node);
5606
+ }
5607
+ };
5608
+ const renderFrontContent = () => {
5609
+ if (!frontChild) {
5610
+ 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"));
5611
+ }
5612
+ if (frontChild.type === "ARTIFACT" && frontChild.artifact) {
5613
+ return /* @__PURE__ */ React67.createElement(ArtifactCard, { artifact: frontChild.artifact, className: "w-full" });
5614
+ }
5615
+ return /* @__PURE__ */ React67.createElement(
5616
+ "div",
5617
+ {
5618
+ className: "w-full aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
5619
+ },
5620
+ /* @__PURE__ */ React67.createElement("span", { className: "text-sm text-silver uppercase tracking-wider" }, frontChild.type === "GROUP" ? "Group" : "Variants"),
5621
+ /* @__PURE__ */ React67.createElement("span", { className: "text-white font-semibold" }, frontChild.label)
5622
+ );
5623
+ };
5624
+ return /* @__PURE__ */ React67.createElement(
5625
+ "div",
5626
+ {
5627
+ ref,
5628
+ className: cx(
5629
+ "cursor-pointer group",
5630
+ className
5631
+ ),
5632
+ onClick: handleClick,
5633
+ role: "button",
5634
+ tabIndex: 0,
5635
+ onKeyDown: (e) => {
5636
+ if (e.key === "Enter" || e.key === " ") {
5637
+ e.preventDefault();
5638
+ handleClick();
5639
+ }
5640
+ },
5641
+ "aria-label": `${node.label} \u2014 ${count} items`,
5642
+ ...props
5643
+ },
5644
+ /* @__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(
5645
+ "div",
5646
+ {
5647
+ className: "absolute inset-0 bg-charcoal border border-ash/30 pointer-events-none",
5648
+ style: { transform: `translate(${LAYER_OFFSET_2X}, ${LAYER_OFFSET_2X})` },
5649
+ "aria-hidden": "true"
5650
+ }
5651
+ ), /* @__PURE__ */ React67.createElement(
5652
+ "div",
5653
+ {
5654
+ className: "absolute inset-0 bg-charcoal border border-ash/40 pointer-events-none",
5655
+ style: { transform: `translate(${LAYER_OFFSET}, ${LAYER_OFFSET})` },
5656
+ "aria-hidden": "true"
5657
+ }
5658
+ ), /* @__PURE__ */ React67.createElement("div", { className: "relative transition-transform duration-200 group-hover:-translate-y-0.5" }, renderFrontContent()), /* @__PURE__ */ React67.createElement(
5659
+ "div",
5660
+ {
5661
+ 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",
5662
+ style: badgePing ? { animation: "badge-invert 0.6s ease-in-out" } : void 0
5663
+ },
5664
+ count
5665
+ ))))
5666
+ );
5667
+ }
5668
+ );
5669
+ ArtifactGroup.displayName = "ArtifactGroup";
5670
+
5671
+ // src/components/ArtifactVariantStack.tsx
5672
+ import React68 from "react";
5673
+ var ArtifactVariantStack = React68.forwardRef(
5674
+ ({ node, onExpandArtifact, onGroupClick, className, ...props }, ref) => {
5675
+ const children = node.children;
5676
+ const renderChild = (child) => {
5677
+ if (child.type === "ARTIFACT" && child.artifact) {
5678
+ return /* @__PURE__ */ React68.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React68.createElement(
5679
+ ArtifactCard,
5680
+ {
5681
+ artifact: child.artifact,
5682
+ onExpand: onExpandArtifact,
5683
+ className: "w-full"
5684
+ }
5685
+ ));
5686
+ }
5687
+ if (child.type === "GROUP") {
5688
+ return /* @__PURE__ */ React68.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React68.createElement(ArtifactGroup, { node: child, onClick: onGroupClick }));
5689
+ }
5690
+ return /* @__PURE__ */ React68.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ React68.createElement(
5691
+ "div",
5692
+ {
5693
+ className: "aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
5694
+ },
5695
+ /* @__PURE__ */ React68.createElement("span", { className: "text-xs text-silver uppercase tracking-wider" }, "Variants"),
5696
+ /* @__PURE__ */ React68.createElement("span", { className: "text-sm text-white font-semibold truncate max-w-full" }, child.label)
5697
+ ));
5698
+ };
5699
+ return /* @__PURE__ */ React68.createElement(
5700
+ Card,
5701
+ {
5702
+ ref,
5703
+ noPadding: true,
5704
+ className: cx("w-full p-5", className),
5705
+ ...props
5706
+ },
5707
+ /* @__PURE__ */ React68.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label),
5708
+ /* @__PURE__ */ React68.createElement("div", { className: "flex gap-3" }, children.map(renderChild))
5709
+ );
5710
+ }
5711
+ );
5712
+ ArtifactVariantStack.displayName = "ArtifactVariantStack";
5713
+
5714
+ // src/components/chat/hooks/useArtifactTreeNavigation.ts
5715
+ import { useCallback as useCallback14, useMemo as useMemo2, useState as useState15 } from "react";
5716
+ function useArtifactTreeNavigation(rootNodes) {
5717
+ const [stack, setStack] = useState15([]);
5718
+ const currentNodes = useMemo2(() => {
5719
+ if (stack.length === 0) return rootNodes;
5720
+ return stack[stack.length - 1].children;
5721
+ }, [rootNodes, stack]);
5722
+ const breadcrumbs = useMemo2(() => {
5723
+ const entries = [{ label: "Project", node: null }];
5724
+ for (const node of stack) {
5725
+ entries.push({ label: node.label, node });
5726
+ }
5727
+ return entries;
5728
+ }, [stack]);
5729
+ const isAtRoot = stack.length === 0;
5730
+ const navigateInto = useCallback14((node) => {
5731
+ setStack((prev) => [...prev, node]);
5732
+ }, []);
5733
+ const navigateTo = useCallback14((index) => {
5734
+ setStack((prev) => prev.slice(0, index));
5735
+ }, []);
5736
+ const navigateBack = useCallback14(() => {
5737
+ setStack((prev) => prev.slice(0, -1));
5738
+ }, []);
5739
+ return {
5740
+ currentNodes,
5741
+ breadcrumbs,
5742
+ isAtRoot,
5743
+ navigateInto,
5744
+ navigateTo,
5745
+ navigateBack
5746
+ };
5747
+ }
5748
+
5561
5749
  // src/components/chat/ArtifactsPanel.tsx
5750
+ var ZOOM_LEVELS = [0.25, 0.5, 0.75, 1];
5562
5751
  function ArtifactModal({
5563
5752
  artifact,
5564
5753
  onClose
5565
5754
  }) {
5566
- useEffect11(() => {
5755
+ useEffect12(() => {
5567
5756
  const handleKeyDown = (e) => {
5568
5757
  if (e.key === "Escape") {
5569
5758
  onClose();
@@ -5572,46 +5761,46 @@ function ArtifactModal({
5572
5761
  document.addEventListener("keydown", handleKeyDown);
5573
5762
  return () => document.removeEventListener("keydown", handleKeyDown);
5574
5763
  }, [onClose]);
5575
- const handleBackdropClick = useCallback14((e) => {
5764
+ const handleBackdropClick = useCallback15((e) => {
5576
5765
  if (e.target === e.currentTarget) {
5577
5766
  onClose();
5578
5767
  }
5579
5768
  }, [onClose]);
5580
- return /* @__PURE__ */ React66.createElement(
5769
+ return /* @__PURE__ */ React69.createElement(
5581
5770
  "div",
5582
5771
  {
5583
5772
  className: "fixed inset-0 z-50 flex items-center justify-center bg-void/90 backdrop-blur-sm animate-fade-in",
5584
5773
  onClick: handleBackdropClick
5585
5774
  },
5586
- /* @__PURE__ */ React66.createElement(
5775
+ /* @__PURE__ */ React69.createElement(
5587
5776
  "div",
5588
5777
  {
5589
5778
  className: "relative w-11/12 h-5/6 max-w-6xl bg-charcoal border border-ash/40 flex flex-col overflow-hidden"
5590
5779
  },
5591
- /* @__PURE__ */ React66.createElement(
5780
+ /* @__PURE__ */ React69.createElement(
5592
5781
  "div",
5593
5782
  {
5594
5783
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5595
5784
  },
5596
- /* @__PURE__ */ React66.createElement("div", null, artifact.title && /* @__PURE__ */ React66.createElement("h3", { className: "text-sm font-semibold text-white" }, artifact.title), artifact.subtitle && /* @__PURE__ */ React66.createElement("p", { className: "text-xs text-silver" }, artifact.subtitle)),
5597
- /* @__PURE__ */ React66.createElement(
5785
+ /* @__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)),
5786
+ /* @__PURE__ */ React69.createElement(
5598
5787
  "button",
5599
5788
  {
5600
5789
  onClick: onClose,
5601
5790
  className: "p-2 text-silver hover:text-white hover:bg-ash/20 transition-colors",
5602
5791
  "aria-label": "Close modal"
5603
5792
  },
5604
- /* @__PURE__ */ React66.createElement(CloseIcon, { className: "w-5 h-5" })
5793
+ /* @__PURE__ */ React69.createElement(CloseIcon, { className: "w-5 h-5" })
5605
5794
  )
5606
5795
  ),
5607
- /* @__PURE__ */ React66.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ React66.createElement(
5796
+ /* @__PURE__ */ React69.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ React69.createElement(
5608
5797
  "img",
5609
5798
  {
5610
5799
  src: artifact.url,
5611
5800
  alt: artifact.alt || "Artifact image",
5612
5801
  className: "max-w-full max-h-full object-contain mx-auto"
5613
5802
  }
5614
- ), artifact.type === "VIDEO" && /* @__PURE__ */ React66.createElement(
5803
+ ), artifact.type === "VIDEO" && /* @__PURE__ */ React69.createElement(
5615
5804
  VideoCard,
5616
5805
  {
5617
5806
  src: artifact.url || "",
@@ -5619,20 +5808,20 @@ function ArtifactModal({
5619
5808
  controls: true,
5620
5809
  className: "max-w-full max-h-full mx-auto"
5621
5810
  }
5622
- ), artifact.type === "AUDIO" && /* @__PURE__ */ React66.createElement(
5811
+ ), artifact.type === "AUDIO" && /* @__PURE__ */ React69.createElement(
5623
5812
  AudioCard,
5624
5813
  {
5625
5814
  src: artifact.url || "",
5626
5815
  controls: true,
5627
5816
  className: "max-w-xl mx-auto"
5628
5817
  }
5629
- ), artifact.type === "PDF" && /* @__PURE__ */ React66.createElement(
5818
+ ), artifact.type === "PDF" && /* @__PURE__ */ React69.createElement(
5630
5819
  PdfCard,
5631
5820
  {
5632
5821
  src: artifact.url || "",
5633
5822
  className: "h-full border-0"
5634
5823
  }
5635
- ), artifact.type === "TEXT" && /* @__PURE__ */ React66.createElement(
5824
+ ), artifact.type === "TEXT" && /* @__PURE__ */ React69.createElement(
5636
5825
  MarkdownContent,
5637
5826
  {
5638
5827
  content: artifact.inlineContent || "",
@@ -5642,7 +5831,7 @@ function ArtifactModal({
5642
5831
  artifact.mimeType === "text/plain" && "whitespace-pre-wrap"
5643
5832
  )
5644
5833
  }
5645
- ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ React66.createElement(
5834
+ ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ React69.createElement(
5646
5835
  ScriptCard,
5647
5836
  {
5648
5837
  elements: artifact.scriptElements,
@@ -5653,138 +5842,181 @@ function ArtifactModal({
5653
5842
  )
5654
5843
  );
5655
5844
  }
5656
- function ArtifactRenderer({
5657
- artifact,
5845
+ function NodeRenderer({
5846
+ node,
5658
5847
  loading,
5659
- onExpand
5848
+ onExpandArtifact,
5849
+ onGroupClick
5660
5850
  }) {
5661
- return /* @__PURE__ */ React66.createElement(
5662
- ArtifactCard,
5663
- {
5664
- artifact,
5665
- loading,
5666
- onExpand
5667
- }
5668
- );
5851
+ if (node.type === "ARTIFACT" && node.artifact) {
5852
+ return /* @__PURE__ */ React69.createElement(
5853
+ ArtifactCard,
5854
+ {
5855
+ artifact: node.artifact,
5856
+ loading,
5857
+ onExpand: onExpandArtifact
5858
+ }
5859
+ );
5860
+ }
5861
+ if (node.type === "GROUP") {
5862
+ return /* @__PURE__ */ React69.createElement(ArtifactGroup, { node, onClick: onGroupClick });
5863
+ }
5864
+ if (node.type === "VARIANT_SET") {
5865
+ return /* @__PURE__ */ React69.createElement(
5866
+ ArtifactVariantStack,
5867
+ {
5868
+ node,
5869
+ onExpandArtifact,
5870
+ onGroupClick
5871
+ }
5872
+ );
5873
+ }
5874
+ return null;
5669
5875
  }
5670
- var ArtifactsPanel = React66.forwardRef(
5876
+ var ArtifactsPanel = React69.forwardRef(
5671
5877
  ({
5672
- artifacts,
5673
- isOpen = false,
5674
- onClose,
5878
+ nodes,
5675
5879
  loading,
5676
- width,
5677
- widthPercent,
5678
- onResizeStart,
5679
5880
  className,
5680
5881
  ...rest
5681
5882
  }, ref) => {
5682
- const [expandedArtifact, setExpandedArtifact] = useState14(null);
5683
- const columns = widthPercent && widthPercent > 55 ? 3 : widthPercent && widthPercent > 35 ? 2 : 1;
5684
- if (!isOpen) {
5685
- return /* @__PURE__ */ React66.createElement(
5686
- "div",
5687
- {
5688
- ref,
5689
- className: cx(
5690
- "h-full bg-charcoal/80 border-l border-ash/40 flex flex-col items-center py-3",
5691
- "w-12 shrink-0",
5692
- className
5693
- ),
5694
- ...rest
5695
- },
5696
- /* @__PURE__ */ React66.createElement(
5697
- "button",
5698
- {
5699
- onClick: onClose,
5700
- className: cx(
5701
- "p-2",
5702
- "text-silver hover:text-white hover:bg-ash/20",
5703
- "transition-colors duration-150",
5704
- "relative"
5705
- ),
5706
- "aria-label": "Expand artifacts panel"
5707
- },
5708
- /* @__PURE__ */ React66.createElement(LayersIcon, { className: "w-5 h-5" }),
5709
- artifacts.length > 0 && /* @__PURE__ */ React66.createElement(
5710
- "span",
5711
- {
5712
- className: "absolute -top-1 -right-1 w-4 h-4 bg-gold text-obsidian text-xs font-medium flex items-center justify-center rounded-full"
5713
- },
5714
- artifacts.length
5715
- )
5716
- )
5717
- );
5718
- }
5719
- return /* @__PURE__ */ React66.createElement(React66.Fragment, null, /* @__PURE__ */ React66.createElement(
5883
+ const [expandedArtifact, setExpandedArtifact] = useState16(null);
5884
+ const [zoomIndex, setZoomIndex] = useState16(ZOOM_LEVELS.length - 1);
5885
+ const treeNav = useArtifactTreeNavigation(nodes || []);
5886
+ const hasNodes = !!nodes && nodes.length > 0;
5887
+ const handleExpandArtifact = useCallback15((artifact) => {
5888
+ setExpandedArtifact(artifact);
5889
+ }, []);
5890
+ const handleGroupClick = useCallback15((node) => {
5891
+ treeNav.navigateInto(node);
5892
+ }, [treeNav]);
5893
+ const zoomIn = useCallback15(() => {
5894
+ setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
5895
+ }, []);
5896
+ const zoomOut = useCallback15(() => {
5897
+ setZoomIndex((prev) => Math.max(prev - 1, 0));
5898
+ }, []);
5899
+ const currentZoom = ZOOM_LEVELS[zoomIndex];
5900
+ const contentRef = useRef10(null);
5901
+ const [contentHeight, setContentHeight] = useState16(void 0);
5902
+ useEffect12(() => {
5903
+ const el = contentRef.current;
5904
+ if (!el) return;
5905
+ const observer = new ResizeObserver(([entry]) => {
5906
+ setContentHeight(entry.contentRect.height);
5907
+ });
5908
+ observer.observe(el);
5909
+ return () => observer.disconnect();
5910
+ }, []);
5911
+ return /* @__PURE__ */ React69.createElement(React69.Fragment, null, /* @__PURE__ */ React69.createElement(
5720
5912
  "div",
5721
5913
  {
5722
5914
  ref,
5723
5915
  "data-testid": "artifacts-panel",
5724
5916
  className: cx(
5725
- "h-full bg-charcoal/50 border-l border-ash/40 flex flex-col relative",
5726
- !width && "w-96",
5727
- "shrink-0",
5917
+ "h-full flex flex-col relative",
5728
5918
  className
5729
5919
  ),
5730
- style: width ? { width } : void 0,
5731
5920
  ...rest
5732
5921
  },
5733
- /* @__PURE__ */ React66.createElement(
5734
- "div",
5735
- {
5736
- onMouseDown: onResizeStart,
5737
- "data-testid": "artifacts-resize-handle",
5738
- className: cx(
5739
- "absolute top-0 left-0 w-1 h-full cursor-col-resize z-50",
5740
- "hover:bg-gold/50 transition-colors",
5741
- "after:absolute after:inset-y-0 after:-left-1 after:w-2"
5742
- // Larger hit area
5743
- )
5744
- }
5745
- ),
5746
- /* @__PURE__ */ React66.createElement(
5922
+ /* @__PURE__ */ React69.createElement(
5747
5923
  "div",
5748
5924
  {
5749
5925
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5750
5926
  },
5751
- /* @__PURE__ */ React66.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
5752
- /* @__PURE__ */ React66.createElement(
5753
- "button",
5927
+ /* @__PURE__ */ React69.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
5928
+ hasNodes && /* @__PURE__ */ React69.createElement(
5929
+ "div",
5754
5930
  {
5755
- onClick: onClose,
5756
- className: cx(
5757
- "p-1.5",
5758
- "text-silver hover:text-white hover:bg-ash/20",
5759
- "transition-colors duration-150"
5760
- ),
5761
- "aria-label": "Collapse artifacts panel"
5931
+ className: "flex items-center gap-0.5",
5932
+ "data-testid": "zoom-controls"
5762
5933
  },
5763
- /* @__PURE__ */ React66.createElement(ChevronRightIcon, { className: "w-5 h-5" })
5934
+ /* @__PURE__ */ React69.createElement(
5935
+ "button",
5936
+ {
5937
+ onClick: zoomOut,
5938
+ disabled: zoomIndex === 0,
5939
+ className: cx(
5940
+ "w-6 h-6 flex items-center justify-center text-xs font-bold",
5941
+ "bg-charcoal border border-ash/40",
5942
+ zoomIndex === 0 ? "text-silver/30 cursor-not-allowed" : "text-silver hover:text-gold hover:border-gold/40 transition-colors"
5943
+ ),
5944
+ "aria-label": "Zoom out"
5945
+ },
5946
+ "\u2212"
5947
+ ),
5948
+ /* @__PURE__ */ React69.createElement("span", { className: "text-xs text-silver w-8 text-center tabular-nums", "data-testid": "zoom-level" }, Math.round(currentZoom * 100), "%"),
5949
+ /* @__PURE__ */ React69.createElement(
5950
+ "button",
5951
+ {
5952
+ onClick: zoomIn,
5953
+ disabled: zoomIndex === ZOOM_LEVELS.length - 1,
5954
+ className: cx(
5955
+ "w-6 h-6 flex items-center justify-center text-xs font-bold",
5956
+ "bg-charcoal border border-ash/40",
5957
+ zoomIndex === ZOOM_LEVELS.length - 1 ? "text-silver/30 cursor-not-allowed" : "text-silver hover:text-gold hover:border-gold/40 transition-colors"
5958
+ ),
5959
+ "aria-label": "Zoom in"
5960
+ },
5961
+ "+"
5962
+ )
5764
5963
  )
5765
5964
  ),
5766
- /* @__PURE__ */ React66.createElement(
5965
+ hasNodes && !treeNav.isAtRoot && /* @__PURE__ */ React69.createElement(
5966
+ "nav",
5967
+ {
5968
+ className: "flex items-center gap-1 px-4 py-2 border-b border-ash/40 shrink-0 overflow-x-auto text-xs",
5969
+ "aria-label": "Breadcrumb",
5970
+ "data-testid": "breadcrumb-nav"
5971
+ },
5972
+ treeNav.breadcrumbs.map((crumb, i) => {
5973
+ const isLast = i === treeNav.breadcrumbs.length - 1;
5974
+ 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(
5975
+ "button",
5976
+ {
5977
+ onClick: () => treeNav.navigateTo(i),
5978
+ className: "text-silver hover:text-white transition-colors"
5979
+ },
5980
+ crumb.label
5981
+ ));
5982
+ })
5983
+ ),
5984
+ /* @__PURE__ */ React69.createElement(
5767
5985
  "div",
5768
5986
  {
5769
- "data-testid": "artifacts-grid",
5770
- className: cx(
5771
- "flex-1 overflow-y-auto p-4",
5772
- columns === 1 ? "space-y-4" : "grid gap-4",
5773
- columns === 2 && "grid-cols-2",
5774
- columns === 3 && "grid-cols-3"
5775
- )
5987
+ className: "flex-1 overflow-auto relative",
5988
+ "data-testid": "artifacts-scroll-area"
5776
5989
  },
5777
- artifacts.length === 0 && !loading ? /* @__PURE__ */ React66.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, "No artifacts to display") : artifacts.map((artifact) => /* @__PURE__ */ React66.createElement(
5778
- ArtifactRenderer,
5990
+ /* @__PURE__ */ React69.createElement(
5991
+ "div",
5779
5992
  {
5780
- key: artifact.id,
5781
- artifact,
5782
- loading,
5783
- onExpand: () => setExpandedArtifact(artifact)
5784
- }
5785
- ))
5993
+ style: currentZoom !== 1 && contentHeight !== void 0 ? { height: contentHeight * currentZoom } : void 0
5994
+ },
5995
+ /* @__PURE__ */ React69.createElement(
5996
+ "div",
5997
+ {
5998
+ ref: contentRef,
5999
+ "data-testid": "artifacts-grid",
6000
+ className: "p-4 space-y-4",
6001
+ style: currentZoom !== 1 ? {
6002
+ transform: `scale(${currentZoom})`,
6003
+ transformOrigin: "top center"
6004
+ } : void 0
6005
+ },
6006
+ 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(
6007
+ NodeRenderer,
6008
+ {
6009
+ key: node.id,
6010
+ node,
6011
+ loading,
6012
+ onExpandArtifact: handleExpandArtifact,
6013
+ onGroupClick: handleGroupClick
6014
+ }
6015
+ ))
6016
+ )
6017
+ )
5786
6018
  )
5787
- ), expandedArtifact && /* @__PURE__ */ React66.createElement(
6019
+ ), expandedArtifact && /* @__PURE__ */ React69.createElement(
5788
6020
  ArtifactModal,
5789
6021
  {
5790
6022
  artifact: expandedArtifact,
@@ -5794,8 +6026,8 @@ var ArtifactsPanel = React66.forwardRef(
5794
6026
  }
5795
6027
  );
5796
6028
  ArtifactsPanel.displayName = "ArtifactsPanel";
5797
- var ArtifactsPanelToggle = React66.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
5798
- return /* @__PURE__ */ React66.createElement(
6029
+ var ArtifactsPanelToggle = React69.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
6030
+ return /* @__PURE__ */ React69.createElement(
5799
6031
  "button",
5800
6032
  {
5801
6033
  ref,
@@ -5812,11 +6044,27 @@ var ArtifactsPanelToggle = React66.forwardRef(({ artifactCount = 0, onExpand, cl
5812
6044
  "aria-label": "Expand artifacts panel",
5813
6045
  ...rest
5814
6046
  },
5815
- /* @__PURE__ */ React66.createElement(LayersIcon, { className: "w-5 h-5" }),
5816
- artifactCount > 0 && /* @__PURE__ */ React66.createElement(
6047
+ /* @__PURE__ */ React69.createElement(
6048
+ "svg",
6049
+ {
6050
+ xmlns: "http://www.w3.org/2000/svg",
6051
+ viewBox: "0 0 20 20",
6052
+ fill: "currentColor",
6053
+ className: "w-5 h-5"
6054
+ },
6055
+ /* @__PURE__ */ React69.createElement(
6056
+ "path",
6057
+ {
6058
+ fillRule: "evenodd",
6059
+ d: "M2 4.5A1.5 1.5 0 013.5 3h13A1.5 1.5 0 0118 4.5v11a1.5 1.5 0 01-1.5 1.5h-13A1.5 1.5 0 012 15.5v-11zM4 5v1h1V5H4zm2 0v1h1V5H6zm7 0v1h1V5h-1zm2 0v1h1V5h-1zM4 14v1h1v-1H4zm2 0v1h1v-1H6zm7 0v1h1v-1h-1zm2 0v1h1v-1h-1zM8 8.118a.5.5 0 01.757-.429l4 2.382a.5.5 0 010 .858l-4 2.382A.5.5 0 018 12.882V8.118z",
6060
+ clipRule: "evenodd"
6061
+ }
6062
+ )
6063
+ ),
6064
+ artifactCount > 0 && /* @__PURE__ */ React69.createElement(
5817
6065
  "span",
5818
6066
  {
5819
- className: "absolute -top-1 -right-1 w-4 h-4 bg-gold text-obsidian text-xs font-medium flex items-center justify-center rounded-full"
6067
+ className: "absolute -top-1 -right-1 w-4 h-4 bg-gold text-obsidian text-xs font-medium flex items-center justify-center"
5820
6068
  },
5821
6069
  artifactCount
5822
6070
  )
@@ -5825,7 +6073,7 @@ var ArtifactsPanelToggle = React66.forwardRef(({ artifactCount = 0, onExpand, cl
5825
6073
  ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
5826
6074
 
5827
6075
  // src/components/chat/TodosList.tsx
5828
- import React67, { useMemo as useMemo2 } from "react";
6076
+ import React70, { useMemo as useMemo3 } from "react";
5829
6077
  var TASK_STATUSES = {
5830
6078
  PENDING: "pending",
5831
6079
  IN_PROGRESS: "in_progress",
@@ -5836,16 +6084,16 @@ var TASK_STATUSES = {
5836
6084
  function TaskIcon({ status }) {
5837
6085
  switch (status) {
5838
6086
  case "done":
5839
- return /* @__PURE__ */ React67.createElement(CheckSquareIcon, null);
6087
+ return /* @__PURE__ */ React70.createElement(CheckSquareIcon, null);
5840
6088
  case "in_progress":
5841
- return /* @__PURE__ */ React67.createElement(SquareLoaderIcon, null);
6089
+ return /* @__PURE__ */ React70.createElement(SquareLoaderIcon, null);
5842
6090
  case "cancelled":
5843
- return /* @__PURE__ */ React67.createElement(CrossSquareIcon, { variant: "cancelled" });
6091
+ return /* @__PURE__ */ React70.createElement(CrossSquareIcon, { variant: "cancelled" });
5844
6092
  case "failed":
5845
- return /* @__PURE__ */ React67.createElement(CrossSquareIcon, { variant: "failed" });
6093
+ return /* @__PURE__ */ React70.createElement(CrossSquareIcon, { variant: "failed" });
5846
6094
  case "pending":
5847
6095
  default:
5848
- return /* @__PURE__ */ React67.createElement(EmptySquareIcon, null);
6096
+ return /* @__PURE__ */ React70.createElement(EmptySquareIcon, null);
5849
6097
  }
5850
6098
  }
5851
6099
  function sortTasks(tasks) {
@@ -5865,7 +6113,7 @@ function TaskItem({ task, depth = 0 }) {
5865
6113
  const isSubtle = task.status === "cancelled" || task.status === "failed";
5866
6114
  const showSubtasks = (task.status === "in_progress" || task.status === "done") && task.subtasks && task.subtasks.length > 0;
5867
6115
  const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
5868
- return /* @__PURE__ */ React67.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React67.createElement(
6116
+ return /* @__PURE__ */ React70.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React70.createElement(
5869
6117
  "div",
5870
6118
  {
5871
6119
  className: cx(
@@ -5873,8 +6121,8 @@ function TaskItem({ task, depth = 0 }) {
5873
6121
  depth > 0 && "pl-6"
5874
6122
  )
5875
6123
  },
5876
- /* @__PURE__ */ React67.createElement(TaskIcon, { status: task.status }),
5877
- /* @__PURE__ */ React67.createElement(
6124
+ /* @__PURE__ */ React70.createElement(TaskIcon, { status: task.status }),
6125
+ /* @__PURE__ */ React70.createElement(
5878
6126
  "span",
5879
6127
  {
5880
6128
  className: cx(
@@ -5886,14 +6134,14 @@ function TaskItem({ task, depth = 0 }) {
5886
6134
  )
5887
6135
  },
5888
6136
  task.label,
5889
- task.status === "cancelled" && /* @__PURE__ */ React67.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
5890
- task.status === "failed" && /* @__PURE__ */ React67.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
6137
+ task.status === "cancelled" && /* @__PURE__ */ React70.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
6138
+ task.status === "failed" && /* @__PURE__ */ React70.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
5891
6139
  )
5892
- ), showSubtasks && /* @__PURE__ */ React67.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ React67.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
6140
+ ), showSubtasks && /* @__PURE__ */ React70.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ React70.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
5893
6141
  }
5894
- var TodosList = React67.forwardRef(
6142
+ var TodosList = React70.forwardRef(
5895
6143
  ({ tasks, title = "Tasks", className, ...rest }, ref) => {
5896
- const sortedTasks = useMemo2(() => sortTasks(tasks), [tasks]);
6144
+ const sortedTasks = useMemo3(() => sortTasks(tasks), [tasks]);
5897
6145
  const countCompleted = (taskList) => {
5898
6146
  let count = 0;
5899
6147
  for (const task of taskList) {
@@ -5918,84 +6166,217 @@ var TodosList = React67.forwardRef(
5918
6166
  if (tasks.length === 0) {
5919
6167
  return null;
5920
6168
  }
5921
- return /* @__PURE__ */ React67.createElement(
6169
+ return /* @__PURE__ */ React70.createElement(
5922
6170
  "div",
5923
6171
  {
5924
6172
  ref,
5925
6173
  className: cx(
5926
- "flex flex-col bg-charcoal/30 border-l border-ash/40",
6174
+ "flex flex-col h-full",
5927
6175
  "overflow-hidden",
5928
6176
  className
5929
6177
  ),
5930
- style: { maxHeight: "25vh" },
5931
6178
  ...rest
5932
6179
  },
5933
- /* @__PURE__ */ React67.createElement(
6180
+ /* @__PURE__ */ React70.createElement(
5934
6181
  "div",
5935
6182
  {
5936
6183
  className: "flex items-center justify-between px-4 py-2 border-b border-ash/40 flex-shrink-0"
5937
6184
  },
5938
- /* @__PURE__ */ React67.createElement("h4", { className: "text-xs font-medium text-white" }, title),
5939
- /* @__PURE__ */ React67.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
6185
+ /* @__PURE__ */ React70.createElement("h4", { className: "text-xs font-medium text-white" }, title),
6186
+ /* @__PURE__ */ React70.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
5940
6187
  ),
5941
- /* @__PURE__ */ React67.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ React67.createElement(TaskItem, { key: task.id, task })))
6188
+ /* @__PURE__ */ React70.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ React70.createElement(TaskItem, { key: task.id, task })))
5942
6189
  );
5943
6190
  }
5944
6191
  );
5945
6192
  TodosList.displayName = "TodosList";
6193
+ function areAllTasksSettled(tasks) {
6194
+ return tasks.every((t) => {
6195
+ const settled = t.status === "done" || t.status === "cancelled" || t.status === "failed";
6196
+ if (!settled) return false;
6197
+ if (t.subtasks && t.subtasks.length > 0) return areAllTasksSettled(t.subtasks);
6198
+ return true;
6199
+ });
6200
+ }
5946
6201
 
5947
- // src/components/chat/hooks/useArtifacts.ts
5948
- import { useCallback as useCallback15, useState as useState15 } from "react";
5949
- function useArtifacts() {
5950
- const [artifacts, setArtifacts] = useState15([]);
5951
- const scheduleArtifact = useCallback15((artifact) => {
5952
- setArtifacts((prev) => [...prev, { ...artifact, isPending: true }]);
5953
- }, []);
5954
- const showArtifact = useCallback15(
5955
- (artifactId, updates) => {
5956
- setArtifacts((prev) => {
5957
- const existingIndex = prev.findIndex((a) => a.id === artifactId);
5958
- if (existingIndex >= 0) {
5959
- return prev.map(
5960
- (a) => a.id === artifactId ? { ...a, ...updates, isPending: false } : a
5961
- );
5962
- } else {
5963
- return [...prev, { id: artifactId, ...updates, isPending: false }];
6202
+ // src/components/chat/ToolSidebar.tsx
6203
+ import React71 from "react";
6204
+ var ToolSidebar = React71.forwardRef(
6205
+ ({ tools, activeTools, onToggleTool, className, ...rest }, ref) => {
6206
+ const topTools = tools.filter((t) => t.group === "top");
6207
+ const bottomTools = tools.filter((t) => t.group === "bottom");
6208
+ const isActive = (toolId) => {
6209
+ const tool = tools.find((t) => t.id === toolId);
6210
+ if (!tool) return false;
6211
+ return activeTools[tool.group] === toolId;
6212
+ };
6213
+ const renderButton = (tool) => {
6214
+ const active = isActive(tool.id);
6215
+ return /* @__PURE__ */ React71.createElement(
6216
+ "button",
6217
+ {
6218
+ key: tool.id,
6219
+ onClick: () => onToggleTool(tool.id),
6220
+ className: cx(
6221
+ "w-8 h-8 flex items-center justify-center transition-colors duration-150",
6222
+ active ? "bg-gold/15 text-gold border border-gold/30" : "text-silver hover:text-white hover:bg-ash/20"
6223
+ ),
6224
+ "aria-label": tool.label,
6225
+ "aria-pressed": active
6226
+ },
6227
+ /* @__PURE__ */ React71.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
6228
+ );
6229
+ };
6230
+ return /* @__PURE__ */ React71.createElement(
6231
+ "div",
6232
+ {
6233
+ ref,
6234
+ className: cx(
6235
+ "h-full w-9 bg-charcoal/80 border-l border-ash/40 flex flex-col items-center shrink-0 py-2",
6236
+ className
6237
+ ),
6238
+ ...rest
6239
+ },
6240
+ /* @__PURE__ */ React71.createElement("div", { className: "flex flex-col items-center gap-1" }, topTools.map(renderButton)),
6241
+ /* @__PURE__ */ React71.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ React71.createElement("div", { className: "w-5 border-t border-ash/30" })),
6242
+ /* @__PURE__ */ React71.createElement("div", { className: "flex flex-col items-center gap-1" }, bottomTools.map(renderButton))
6243
+ );
6244
+ }
6245
+ );
6246
+ ToolSidebar.displayName = "ToolSidebar";
6247
+
6248
+ // src/components/chat/ToolPanelContainer.tsx
6249
+ import React72, { useCallback as useCallback16, useEffect as useEffect13, useRef as useRef11, useState as useState17 } from "react";
6250
+ var ToolPanelContainer = React72.forwardRef(
6251
+ ({ topContent, bottomContent, width, onResizeStart, className, ...rest }, ref) => {
6252
+ const [topPercent, setTopPercent] = useState17(60);
6253
+ const [isResizingHeight, setIsResizingHeight] = useState17(false);
6254
+ const containerRef = useRef11(null);
6255
+ const lastY = useRef11(null);
6256
+ const hasBoth = topContent !== null && bottomContent !== null;
6257
+ const startHeightResize = useCallback16((e) => {
6258
+ e.preventDefault();
6259
+ setIsResizingHeight(true);
6260
+ lastY.current = e.clientY;
6261
+ }, []);
6262
+ const stopHeightResize = useCallback16(() => {
6263
+ setIsResizingHeight(false);
6264
+ lastY.current = null;
6265
+ }, []);
6266
+ const resizeHeight = useCallback16(
6267
+ (e) => {
6268
+ if (!isResizingHeight || lastY.current === null || !containerRef.current) return;
6269
+ const containerHeight = containerRef.current.getBoundingClientRect().height;
6270
+ if (containerHeight === 0) return;
6271
+ const deltaY = e.clientY - lastY.current;
6272
+ const deltaPercent = deltaY / containerHeight * 100;
6273
+ setTopPercent((prev) => {
6274
+ const next = prev + deltaPercent;
6275
+ return Math.min(Math.max(next, 20), 80);
6276
+ });
6277
+ lastY.current = e.clientY;
6278
+ },
6279
+ [isResizingHeight]
6280
+ );
6281
+ useEffect13(() => {
6282
+ if (isResizingHeight) {
6283
+ window.addEventListener("mousemove", resizeHeight);
6284
+ window.addEventListener("mouseup", stopHeightResize);
6285
+ document.body.style.cursor = "row-resize";
6286
+ document.body.style.userSelect = "none";
6287
+ } else {
6288
+ window.removeEventListener("mousemove", resizeHeight);
6289
+ window.removeEventListener("mouseup", stopHeightResize);
6290
+ document.body.style.cursor = "";
6291
+ document.body.style.userSelect = "";
6292
+ }
6293
+ return () => {
6294
+ window.removeEventListener("mousemove", resizeHeight);
6295
+ window.removeEventListener("mouseup", stopHeightResize);
6296
+ document.body.style.cursor = "";
6297
+ document.body.style.userSelect = "";
6298
+ };
6299
+ }, [isResizingHeight, resizeHeight, stopHeightResize]);
6300
+ return /* @__PURE__ */ React72.createElement(
6301
+ "div",
6302
+ {
6303
+ ref: (node) => {
6304
+ containerRef.current = node;
6305
+ if (typeof ref === "function") ref(node);
6306
+ else if (ref) ref.current = node;
6307
+ },
6308
+ className: cx(
6309
+ "h-full bg-charcoal/50 border-l border-ash/40 flex flex-col relative shrink-0",
6310
+ className
6311
+ ),
6312
+ style: width ? { width } : void 0,
6313
+ ...rest
6314
+ },
6315
+ /* @__PURE__ */ React72.createElement(
6316
+ "div",
6317
+ {
6318
+ onMouseDown: onResizeStart,
6319
+ className: cx(
6320
+ "absolute top-0 left-0 w-1 h-full cursor-col-resize z-50",
6321
+ "hover:bg-gold/50 transition-colors",
6322
+ "after:absolute after:inset-y-0 after:-left-1 after:w-2"
6323
+ )
5964
6324
  }
5965
- });
5966
- },
5967
- []
5968
- );
5969
- const removeArtifact = useCallback15((artifactId) => {
5970
- setArtifacts((prev) => prev.filter((a) => a.id !== artifactId));
5971
- }, []);
5972
- const clearArtifacts = useCallback15(() => {
5973
- setArtifacts([]);
5974
- }, []);
5975
- return { artifacts, scheduleArtifact, showArtifact, removeArtifact, clearArtifacts };
5976
- }
6325
+ ),
6326
+ topContent !== null && /* @__PURE__ */ React72.createElement(
6327
+ "div",
6328
+ {
6329
+ className: "min-h-0 overflow-hidden flex flex-col",
6330
+ style: hasBoth ? { height: `${topPercent}%` } : { flex: "1 1 0%" }
6331
+ },
6332
+ topContent
6333
+ ),
6334
+ hasBoth && /* @__PURE__ */ React72.createElement(
6335
+ "div",
6336
+ {
6337
+ onMouseDown: startHeightResize,
6338
+ className: cx(
6339
+ "h-1 cursor-row-resize z-50 shrink-0",
6340
+ "bg-ash/40 hover:bg-gold/50 transition-colors",
6341
+ "relative",
6342
+ "after:absolute after:-top-1 after:left-0 after:right-0 after:h-3"
6343
+ )
6344
+ }
6345
+ ),
6346
+ bottomContent !== null && /* @__PURE__ */ React72.createElement(
6347
+ "div",
6348
+ {
6349
+ className: "min-h-0 overflow-hidden flex flex-col",
6350
+ style: hasBoth ? { height: `${100 - topPercent}%` } : { flex: "1 1 0%" }
6351
+ },
6352
+ bottomContent
6353
+ )
6354
+ );
6355
+ }
6356
+ );
6357
+ ToolPanelContainer.displayName = "ToolPanelContainer";
5977
6358
 
5978
6359
  // src/components/chat/hooks/useResizable.ts
5979
- import { useCallback as useCallback16, useEffect as useEffect12, useRef as useRef9, useState as useState16 } from "react";
6360
+ import { useCallback as useCallback17, useEffect as useEffect14, useRef as useRef12, useState as useState18 } from "react";
5980
6361
  function useResizable({
5981
6362
  initialWidthPercent,
5982
6363
  minWidthPercent,
5983
6364
  maxWidthPercent,
5984
6365
  direction
5985
6366
  }) {
5986
- const [widthPercent, setWidthPercent] = useState16(initialWidthPercent);
5987
- const [isResizing, setIsResizing] = useState16(false);
5988
- const lastX = useRef9(null);
5989
- const startResizing = useCallback16((e) => {
6367
+ const [widthPercent, setWidthPercent] = useState18(initialWidthPercent);
6368
+ const [isResizing, setIsResizing] = useState18(false);
6369
+ const lastX = useRef12(null);
6370
+ const startResizing = useCallback17((e) => {
5990
6371
  e.preventDefault();
5991
6372
  setIsResizing(true);
5992
6373
  lastX.current = e.clientX;
5993
6374
  }, []);
5994
- const stopResizing = useCallback16(() => {
6375
+ const stopResizing = useCallback17(() => {
5995
6376
  setIsResizing(false);
5996
6377
  lastX.current = null;
5997
6378
  }, []);
5998
- const resize = useCallback16(
6379
+ const resize = useCallback17(
5999
6380
  (e) => {
6000
6381
  if (!isResizing || lastX.current === null) {
6001
6382
  return;
@@ -6011,7 +6392,7 @@ function useResizable({
6011
6392
  },
6012
6393
  [isResizing, direction, minWidthPercent, maxWidthPercent]
6013
6394
  );
6014
- useEffect12(() => {
6395
+ useEffect14(() => {
6015
6396
  if (isResizing) {
6016
6397
  window.addEventListener("mousemove", resize);
6017
6398
  window.addEventListener("mouseup", stopResizing);
@@ -6035,7 +6416,7 @@ function useResizable({
6035
6416
  }
6036
6417
 
6037
6418
  // src/components/chat/ChatInterface.tsx
6038
- var ChatInterface = React68.forwardRef(
6419
+ var ChatInterface = React73.forwardRef(
6039
6420
  ({
6040
6421
  messages = [],
6041
6422
  conversationTree,
@@ -6057,7 +6438,7 @@ var ChatInterface = React68.forwardRef(
6057
6438
  enableMessageActions = true,
6058
6439
  attachments: propsAttachments,
6059
6440
  onAttachmentsChange,
6060
- artifacts = [],
6441
+ artifactNodes,
6061
6442
  isArtifactsPanelOpen,
6062
6443
  onArtifactsPanelOpenChange,
6063
6444
  tasks = [],
@@ -6065,10 +6446,25 @@ var ChatInterface = React68.forwardRef(
6065
6446
  className,
6066
6447
  ...rest
6067
6448
  }, ref) => {
6068
- const [sidebarCollapsed, setSidebarCollapsed] = useState17(initialSidebarCollapsed);
6069
- const [internalPanelOpen, setInternalPanelOpen] = useState17(false);
6070
- const prevArtifactsRef = useRef10([]);
6071
- const prevTasksRef = useRef10([]);
6449
+ const [sidebarCollapsed, setSidebarCollapsed] = useState19(initialSidebarCollapsed);
6450
+ const prevArtifactNodesRef = useRef13([]);
6451
+ const prevTasksRef = useRef13([]);
6452
+ const [internalTools, setInternalTools] = useState19({
6453
+ top: null,
6454
+ bottom: null
6455
+ });
6456
+ const dismissedToolsRef = useRef13(/* @__PURE__ */ new Set());
6457
+ const isPanelControlled = isArtifactsPanelOpen !== void 0;
6458
+ const activeTools = useMemo4(() => {
6459
+ if (isPanelControlled) {
6460
+ return {
6461
+ top: isArtifactsPanelOpen ? "artifacts" : internalTools.top,
6462
+ bottom: internalTools.bottom
6463
+ };
6464
+ }
6465
+ return internalTools;
6466
+ }, [isPanelControlled, isArtifactsPanelOpen, internalTools]);
6467
+ const isAnyToolOpen = activeTools.top !== null || activeTools.bottom !== null;
6072
6468
  const {
6073
6469
  width: sidebarWidth,
6074
6470
  startResizing: startResizingSidebar
@@ -6079,19 +6475,43 @@ var ChatInterface = React68.forwardRef(
6079
6475
  direction: "right"
6080
6476
  });
6081
6477
  const {
6082
- width: artifactsWidth,
6083
- widthPercent: artifactsWidthPercent,
6084
- startResizing: startResizingArtifacts
6478
+ width: toolsWidth,
6479
+ startResizing: startResizingTools
6085
6480
  } = useResizable({
6086
6481
  initialWidthPercent: 50,
6087
6482
  minWidthPercent: 25,
6088
6483
  maxWidthPercent: 70,
6089
6484
  direction: "left"
6090
6485
  });
6091
- const isPanelControlled = isArtifactsPanelOpen !== void 0;
6092
- const artifactsPanelOpen = isPanelControlled ? isArtifactsPanelOpen : internalPanelOpen;
6486
+ const toggleTool = useCallback18((toolId) => {
6487
+ const toolDef = TOOL_DEFINITIONS.find((t) => t.id === toolId);
6488
+ if (!toolDef) return;
6489
+ const group = toolDef.group;
6490
+ if (toolId === "artifacts" && isPanelControlled) {
6491
+ const isCurrentlyOpen = activeTools.top === "artifacts";
6492
+ if (isCurrentlyOpen) {
6493
+ dismissedToolsRef.current.add("artifacts");
6494
+ } else {
6495
+ dismissedToolsRef.current.delete("artifacts");
6496
+ }
6497
+ onArtifactsPanelOpenChange?.(!isCurrentlyOpen);
6498
+ return;
6499
+ }
6500
+ setInternalTools((prev) => {
6501
+ const isCurrentlyOpen = prev[group] === toolId;
6502
+ if (isCurrentlyOpen) {
6503
+ dismissedToolsRef.current.add(toolId);
6504
+ } else {
6505
+ dismissedToolsRef.current.delete(toolId);
6506
+ }
6507
+ return {
6508
+ ...prev,
6509
+ [group]: isCurrentlyOpen ? null : toolId
6510
+ };
6511
+ });
6512
+ }, [isPanelControlled, activeTools.top, onArtifactsPanelOpenChange]);
6093
6513
  const isTreeMode = !!conversationTree;
6094
- const effectiveMessages = useMemo3(() => {
6514
+ const effectiveMessages = useMemo4(() => {
6095
6515
  if (isTreeMode && conversationTree) {
6096
6516
  const pathNodes = getActivePathMessages(conversationTree);
6097
6517
  return pathNodes.map((node) => ({
@@ -6103,63 +6523,43 @@ var ChatInterface = React68.forwardRef(
6103
6523
  }
6104
6524
  return messages;
6105
6525
  }, [isTreeMode, conversationTree, messages]);
6106
- const latestUserMessageIndex = useMemo3(() => {
6526
+ const latestUserMessageIndex = useMemo4(() => {
6107
6527
  for (let i = effectiveMessages.length - 1; i >= 0; i--) {
6108
- if (effectiveMessages[i].variant === "user") {
6109
- return i;
6110
- }
6528
+ if (effectiveMessages[i].variant === "user") return i;
6111
6529
  }
6112
6530
  return -1;
6113
6531
  }, [effectiveMessages]);
6114
- useEffect13(() => {
6115
- if (isPanelControlled) {
6116
- return;
6532
+ useEffect15(() => {
6533
+ const nodes = artifactNodes || [];
6534
+ const prevNodes = prevArtifactNodesRef.current;
6535
+ const hasNewOrChangedNode = nodes.length !== prevNodes.length || nodes.some((n, i) => n.id !== prevNodes[i]?.id);
6536
+ if (!isPanelControlled && hasNewOrChangedNode && nodes.length > 0 && !dismissedToolsRef.current.has("artifacts")) {
6537
+ setInternalTools((prev) => ({ ...prev, top: "artifacts" }));
6117
6538
  }
6118
- const hasNewOrSignificantArtifact = artifacts.some((a) => {
6119
- const p = prevArtifactsRef.current.find((prev) => prev.id === a.id);
6120
- if (!p) {
6121
- return true;
6122
- }
6123
- if (p.isPending && !a.isPending) {
6124
- return true;
6125
- }
6126
- if (p.title !== a.title || p.type !== a.type) {
6127
- return true;
6128
- }
6129
- return false;
6130
- });
6131
6539
  const hasNewOrUpdatedTask = (curr, prev) => {
6132
6540
  return curr.some((c) => {
6133
6541
  const p = prev.find((x) => x.id === c.id);
6134
- if (!p) {
6135
- return true;
6136
- }
6137
- if (c.status !== p.status || c.label !== p.label) {
6138
- return true;
6139
- }
6140
- if (c.subtasks && hasNewOrUpdatedTask(c.subtasks, p?.subtasks || [])) {
6141
- return true;
6142
- }
6542
+ if (!p) return true;
6543
+ if (c.status !== p.status || c.label !== p.label) return true;
6544
+ if (c.subtasks && hasNewOrUpdatedTask(c.subtasks, p?.subtasks || [])) return true;
6143
6545
  return false;
6144
6546
  });
6145
6547
  };
6146
- if (hasNewOrSignificantArtifact || hasNewOrUpdatedTask(tasks, prevTasksRef.current)) {
6147
- setInternalPanelOpen(true);
6548
+ if (hasNewOrUpdatedTask(tasks, prevTasksRef.current) && !dismissedToolsRef.current.has("todos")) {
6549
+ setInternalTools((prev) => ({ ...prev, bottom: "todos" }));
6148
6550
  }
6149
- prevArtifactsRef.current = artifacts;
6551
+ prevArtifactNodesRef.current = nodes;
6150
6552
  prevTasksRef.current = tasks;
6151
- }, [artifacts, tasks, isPanelControlled]);
6152
- const handleBranchSwitch = useCallback17(
6553
+ }, [artifactNodes, tasks, isPanelControlled]);
6554
+ const handleBranchSwitch = useCallback18(
6153
6555
  (nodeId, direction) => {
6154
- if (!isTreeMode || !conversationTree || !onTreeChange) {
6155
- return;
6156
- }
6556
+ if (!isTreeMode || !conversationTree || !onTreeChange) return;
6157
6557
  const newTree = switchBranch(conversationTree, nodeId, direction);
6158
6558
  onTreeChange(newTree);
6159
6559
  },
6160
6560
  [isTreeMode, conversationTree, onTreeChange]
6161
6561
  );
6162
- const displayMessages = useMemo3(() => {
6562
+ const displayMessages = useMemo4(() => {
6163
6563
  return effectiveMessages.map((msg) => {
6164
6564
  let branchInfo = void 0;
6165
6565
  if (isTreeMode && conversationTree) {
@@ -6178,11 +6578,7 @@ var ChatInterface = React68.forwardRef(
6178
6578
  onEdit: msg.variant === "user" && onEditMessage ? (newContent) => onEditMessage(msg.id, newContent) : void 0,
6179
6579
  onRetry: msg.variant === "assistant" && onRetryMessage ? () => onRetryMessage(msg.id) : void 0
6180
6580
  } : void 0;
6181
- return {
6182
- ...msg,
6183
- branchInfo,
6184
- actions
6185
- };
6581
+ return { ...msg, branchInfo, actions };
6186
6582
  });
6187
6583
  }, [
6188
6584
  effectiveMessages,
@@ -6193,31 +6589,56 @@ var ChatInterface = React68.forwardRef(
6193
6589
  onRetryMessage,
6194
6590
  handleBranchSwitch
6195
6591
  ]);
6196
- const handleSubmit = useCallback17(
6592
+ const handleSubmit = useCallback18(
6197
6593
  (message, attachments) => {
6198
6594
  onMessageSubmit?.(message, attachments);
6199
6595
  },
6200
6596
  [onMessageSubmit]
6201
6597
  );
6202
- const toggleSidebar = useCallback17(() => {
6598
+ const toggleSidebar = useCallback18(() => {
6203
6599
  setSidebarCollapsed((prev) => !prev);
6204
6600
  }, []);
6205
- const toggleArtifactsPanel = useCallback17(() => {
6206
- if (isPanelControlled) {
6207
- onArtifactsPanelOpenChange?.(!artifactsPanelOpen);
6208
- } else {
6209
- setInternalPanelOpen((prev) => !prev);
6210
- }
6211
- }, [isPanelControlled, artifactsPanelOpen, onArtifactsPanelOpenChange]);
6212
6601
  const isEmpty = effectiveMessages.length === 0;
6213
- return /* @__PURE__ */ React68.createElement(
6602
+ const allSettled = tasks.length === 0 || areAllTasksSettled(tasks);
6603
+ const toolDefinitions = useMemo4(() => [
6604
+ {
6605
+ id: "artifacts",
6606
+ icon: /* @__PURE__ */ React73.createElement(MediaIcon, null),
6607
+ label: "Artifacts",
6608
+ group: "top"
6609
+ },
6610
+ {
6611
+ id: "todos",
6612
+ icon: allSettled ? /* @__PURE__ */ React73.createElement(CheckSquareIcon, null) : /* @__PURE__ */ React73.createElement(SquareLoaderIcon, null),
6613
+ label: "Tasks",
6614
+ group: "bottom"
6615
+ }
6616
+ ], [allSettled]);
6617
+ const renderToolContent = (toolId) => {
6618
+ if (!toolId) return null;
6619
+ switch (toolId) {
6620
+ case "artifacts":
6621
+ return /* @__PURE__ */ React73.createElement(
6622
+ ArtifactsPanel,
6623
+ {
6624
+ nodes: artifactNodes,
6625
+ className: "h-full"
6626
+ }
6627
+ );
6628
+ case "todos":
6629
+ return tasks.length > 0 ? /* @__PURE__ */ React73.createElement(TodosList, { tasks, title: tasksTitle, className: "h-full" }) : /* @__PURE__ */ React73.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ React73.createElement("div", { className: "flex items-center p-4 border-b border-ash/40 shrink-0" }, /* @__PURE__ */ React73.createElement("h3", { className: "text-xs font-medium text-white" }, "Tasks")), /* @__PURE__ */ React73.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ React73.createElement("p", { className: "text-xs text-silver/60" }, "No tasks")));
6630
+ default:
6631
+ return null;
6632
+ }
6633
+ };
6634
+ return /* @__PURE__ */ React73.createElement(
6214
6635
  "div",
6215
6636
  {
6216
6637
  ref,
6217
6638
  className: cx("flex h-full w-full bg-obsidian overflow-hidden", className),
6218
6639
  ...rest
6219
6640
  },
6220
- /* @__PURE__ */ React68.createElement(
6641
+ /* @__PURE__ */ React73.createElement(
6221
6642
  ConversationSidebar,
6222
6643
  {
6223
6644
  conversations,
@@ -6229,16 +6650,16 @@ var ChatInterface = React68.forwardRef(
6229
6650
  onResizeStart: startResizingSidebar
6230
6651
  }
6231
6652
  ),
6232
- /* @__PURE__ */ React68.createElement("div", { className: "flex-1 flex flex-col min-w-0 relative" }, /* @__PURE__ */ React68.createElement("div", { className: cx(
6653
+ /* @__PURE__ */ React73.createElement("div", { className: "flex-1 flex flex-col min-w-0 relative" }, /* @__PURE__ */ React73.createElement("div", { className: cx(
6233
6654
  "flex-1 flex flex-col min-h-0 relative",
6234
6655
  isEmpty ? "justify-center" : "justify-start"
6235
- ) }, /* @__PURE__ */ React68.createElement("div", { className: cx(
6656
+ ) }, /* @__PURE__ */ React73.createElement("div", { className: cx(
6236
6657
  "transition-all duration-500 ease-in-out",
6237
6658
  isEmpty ? "flex-1" : "flex-zero"
6238
- ) }), /* @__PURE__ */ React68.createElement("div", { className: cx(
6659
+ ) }), /* @__PURE__ */ React73.createElement("div", { className: cx(
6239
6660
  "transition-all duration-500 ease-in-out overflow-hidden flex flex-col",
6240
6661
  isEmpty ? "flex-zero opacity-0" : "flex-1 opacity-100"
6241
- ) }, /* @__PURE__ */ React68.createElement(
6662
+ ) }, /* @__PURE__ */ React73.createElement(
6242
6663
  ChatView,
6243
6664
  {
6244
6665
  messages: displayMessages,
@@ -6247,10 +6668,10 @@ var ChatInterface = React68.forwardRef(
6247
6668
  isThinking,
6248
6669
  className: "flex-1"
6249
6670
  }
6250
- )), /* @__PURE__ */ React68.createElement("div", { className: cx(
6671
+ )), /* @__PURE__ */ React73.createElement("div", { className: cx(
6251
6672
  "transition-all duration-500 ease-in-out z-10 w-full flex flex-col items-center",
6252
6673
  isEmpty ? "p-4" : "shrink-0 p-4 border-t border-ash/40 bg-obsidian"
6253
- ) }, isEmpty && /* @__PURE__ */ React68.createElement("div", { className: "mb-8 text-center animate-fade-in duration-500" }, emptyState ? emptyState : /* @__PURE__ */ React68.createElement("h1", { className: "text-4xl md:text-5xl font-heading text-gold mb-2 tracking-tight" }, "Welcome!")), /* @__PURE__ */ React68.createElement(
6674
+ ) }, isEmpty && /* @__PURE__ */ React73.createElement("div", { className: "mb-8 text-center animate-fade-in duration-500" }, emptyState ? emptyState : /* @__PURE__ */ React73.createElement("h1", { className: "text-4xl md:text-5xl font-heading text-gold mb-2 tracking-tight" }, "Welcome!")), /* @__PURE__ */ React73.createElement(
6254
6675
  ChatInput,
6255
6676
  {
6256
6677
  position: isEmpty ? "centered" : "bottom",
@@ -6264,38 +6685,40 @@ var ChatInterface = React68.forwardRef(
6264
6685
  attachments: propsAttachments,
6265
6686
  onAttachmentsChange
6266
6687
  }
6267
- )), /* @__PURE__ */ React68.createElement("div", { className: cx(
6688
+ )), /* @__PURE__ */ React73.createElement("div", { className: cx(
6268
6689
  "transition-all duration-500 ease-in-out",
6269
6690
  isEmpty ? "flex-1" : "flex-zero"
6270
6691
  ) }))),
6271
- /* @__PURE__ */ React68.createElement("div", { className: "h-full flex flex-col shrink-0" }, /* @__PURE__ */ React68.createElement("div", { className: "flex-1 min-h-0" }, /* @__PURE__ */ React68.createElement(
6272
- ArtifactsPanel,
6692
+ isAnyToolOpen && /* @__PURE__ */ React73.createElement(
6693
+ ToolPanelContainer,
6273
6694
  {
6274
- artifacts,
6275
- isOpen: artifactsPanelOpen,
6276
- onClose: toggleArtifactsPanel,
6277
- width: artifactsWidth,
6278
- widthPercent: artifactsWidthPercent,
6279
- onResizeStart: startResizingArtifacts,
6280
- className: "h-full"
6695
+ topContent: renderToolContent(activeTools.top),
6696
+ bottomContent: renderToolContent(activeTools.bottom),
6697
+ width: toolsWidth,
6698
+ onResizeStart: startResizingTools
6281
6699
  }
6282
- )), tasks.length > 0 && artifactsPanelOpen && /* @__PURE__ */ React68.createElement(
6283
- TodosList,
6700
+ ),
6701
+ /* @__PURE__ */ React73.createElement(
6702
+ ToolSidebar,
6284
6703
  {
6285
- tasks,
6286
- title: tasksTitle,
6287
- style: { width: artifactsWidth }
6704
+ tools: toolDefinitions,
6705
+ activeTools,
6706
+ onToggleTool: toggleTool
6288
6707
  }
6289
- ))
6708
+ )
6290
6709
  );
6291
6710
  }
6292
6711
  );
6293
6712
  ChatInterface.displayName = "ChatInterface";
6713
+ var TOOL_DEFINITIONS = [
6714
+ { id: "artifacts", icon: null, label: "Artifacts", group: "top" },
6715
+ { id: "todos", icon: null, label: "Tasks", group: "bottom" }
6716
+ ];
6294
6717
 
6295
6718
  // src/components/chat/MessageActions.tsx
6296
- import React69, { useCallback as useCallback18, useState as useState18 } from "react";
6719
+ import React74, { useCallback as useCallback19, useState as useState20 } from "react";
6297
6720
  import { Check as Check3, Copy, Pencil, RotateCcw, Send as Send2, X as X5 } from "lucide-react";
6298
- var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ React69.createElement(
6721
+ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ React74.createElement(
6299
6722
  "button",
6300
6723
  {
6301
6724
  type: "button",
@@ -6311,7 +6734,7 @@ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @_
6311
6734
  },
6312
6735
  children
6313
6736
  );
6314
- var MessageActions = React69.forwardRef(
6737
+ var MessageActions = React74.forwardRef(
6315
6738
  ({
6316
6739
  variant,
6317
6740
  content,
@@ -6323,12 +6746,12 @@ var MessageActions = React69.forwardRef(
6323
6746
  className,
6324
6747
  ...rest
6325
6748
  }, ref) => {
6326
- const [localIsEditing, setLocalIsEditing] = useState18(false);
6327
- const [localEditValue, setLocalEditValue] = useState18(content);
6328
- const [copied, setCopied] = useState18(false);
6749
+ const [localIsEditing, setLocalIsEditing] = useState20(false);
6750
+ const [localEditValue, setLocalEditValue] = useState20(content);
6751
+ const [copied, setCopied] = useState20(false);
6329
6752
  const isEditing = controlledIsEditing ?? localIsEditing;
6330
6753
  const editValue = controlledEditValue ?? localEditValue;
6331
- const setIsEditing = useCallback18(
6754
+ const setIsEditing = useCallback19(
6332
6755
  (value) => {
6333
6756
  if (onEditingChange) {
6334
6757
  onEditingChange(value);
@@ -6338,10 +6761,10 @@ var MessageActions = React69.forwardRef(
6338
6761
  },
6339
6762
  [onEditingChange]
6340
6763
  );
6341
- const setEditValue = useCallback18((value) => {
6764
+ const setEditValue = useCallback19((value) => {
6342
6765
  setLocalEditValue(value);
6343
6766
  }, []);
6344
- const handleCopy = useCallback18(async () => {
6767
+ const handleCopy = useCallback19(async () => {
6345
6768
  try {
6346
6769
  await navigator.clipboard.writeText(content);
6347
6770
  setCopied(true);
@@ -6357,22 +6780,22 @@ var MessageActions = React69.forwardRef(
6357
6780
  setTimeout(() => setCopied(false), 2e3);
6358
6781
  }
6359
6782
  }, [content]);
6360
- const handleStartEdit = useCallback18(() => {
6783
+ const handleStartEdit = useCallback19(() => {
6361
6784
  setLocalEditValue(content);
6362
6785
  setIsEditing(true);
6363
6786
  }, [content, setIsEditing]);
6364
- const handleCancelEdit = useCallback18(() => {
6787
+ const handleCancelEdit = useCallback19(() => {
6365
6788
  setIsEditing(false);
6366
6789
  setLocalEditValue(content);
6367
6790
  }, [content, setIsEditing]);
6368
- const handleSubmitEdit = useCallback18(() => {
6791
+ const handleSubmitEdit = useCallback19(() => {
6369
6792
  const trimmed = editValue.trim();
6370
6793
  if (trimmed && trimmed !== content) {
6371
6794
  onEdit?.(trimmed);
6372
6795
  }
6373
6796
  setIsEditing(false);
6374
6797
  }, [editValue, content, onEdit, setIsEditing]);
6375
- const handleEditKeyDown = useCallback18(
6798
+ const handleEditKeyDown = useCallback19(
6376
6799
  (e) => {
6377
6800
  if (e.key === "Enter" && !e.shiftKey) {
6378
6801
  e.preventDefault();
@@ -6385,19 +6808,19 @@ var MessageActions = React69.forwardRef(
6385
6808
  );
6386
6809
  const isUser = variant === "user";
6387
6810
  if (isUser && isEditing) {
6388
- return /* @__PURE__ */ React69.createElement(
6811
+ return /* @__PURE__ */ React74.createElement(
6389
6812
  "div",
6390
6813
  {
6391
6814
  ref,
6392
6815
  className: cx("mt-2", className),
6393
6816
  ...rest
6394
6817
  },
6395
- /* @__PURE__ */ React69.createElement(
6818
+ /* @__PURE__ */ React74.createElement(
6396
6819
  "div",
6397
6820
  {
6398
6821
  className: "relative bg-charcoal border border-ash/60 focus-within:border-gold/60 focus-within:ring-1 focus-within:ring-gold/20"
6399
6822
  },
6400
- /* @__PURE__ */ React69.createElement(
6823
+ /* @__PURE__ */ React74.createElement(
6401
6824
  "textarea",
6402
6825
  {
6403
6826
  value: editValue,
@@ -6408,15 +6831,15 @@ var MessageActions = React69.forwardRef(
6408
6831
  rows: 2
6409
6832
  }
6410
6833
  ),
6411
- /* @__PURE__ */ React69.createElement("div", { className: "absolute right-2 bottom-2 flex gap-1" }, /* @__PURE__ */ React69.createElement(
6834
+ /* @__PURE__ */ React74.createElement("div", { className: "absolute right-2 bottom-2 flex gap-1" }, /* @__PURE__ */ React74.createElement(
6412
6835
  ActionButton2,
6413
6836
  {
6414
6837
  onClick: handleCancelEdit,
6415
6838
  label: "Cancel edit",
6416
6839
  className: "text-silver/60 hover:text-error"
6417
6840
  },
6418
- /* @__PURE__ */ React69.createElement(X5, { className: "w-4 h-4" })
6419
- ), /* @__PURE__ */ React69.createElement(
6841
+ /* @__PURE__ */ React74.createElement(X5, { className: "w-4 h-4" })
6842
+ ), /* @__PURE__ */ React74.createElement(
6420
6843
  ActionButton2,
6421
6844
  {
6422
6845
  onClick: handleSubmitEdit,
@@ -6424,13 +6847,13 @@ var MessageActions = React69.forwardRef(
6424
6847
  className: "text-silver/60 hover:text-gold",
6425
6848
  disabled: !editValue.trim() || editValue.trim() === content
6426
6849
  },
6427
- /* @__PURE__ */ React69.createElement(Send2, { className: "w-4 h-4" })
6850
+ /* @__PURE__ */ React74.createElement(Send2, { className: "w-4 h-4" })
6428
6851
  ))
6429
6852
  ),
6430
- /* @__PURE__ */ React69.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
6853
+ /* @__PURE__ */ React74.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
6431
6854
  );
6432
6855
  }
6433
- return /* @__PURE__ */ React69.createElement(
6856
+ return /* @__PURE__ */ React74.createElement(
6434
6857
  "div",
6435
6858
  {
6436
6859
  ref,
@@ -6441,18 +6864,18 @@ var MessageActions = React69.forwardRef(
6441
6864
  ),
6442
6865
  ...rest
6443
6866
  },
6444
- /* @__PURE__ */ React69.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ React69.createElement(Check3, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ React69.createElement(Copy, { className: "w-3.5 h-3.5" })),
6445
- isUser && onEdit && /* @__PURE__ */ React69.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React69.createElement(Pencil, { className: "w-3.5 h-3.5" })),
6446
- !isUser && onRetry && /* @__PURE__ */ React69.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ React69.createElement(RotateCcw, { className: "w-3.5 h-3.5" }))
6867
+ /* @__PURE__ */ React74.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ React74.createElement(Check3, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ React74.createElement(Copy, { className: "w-3.5 h-3.5" })),
6868
+ isUser && onEdit && /* @__PURE__ */ React74.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ React74.createElement(Pencil, { className: "w-3.5 h-3.5" })),
6869
+ !isUser && onRetry && /* @__PURE__ */ React74.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ React74.createElement(RotateCcw, { className: "w-3.5 h-3.5" }))
6447
6870
  );
6448
6871
  }
6449
6872
  );
6450
6873
  MessageActions.displayName = "MessageActions";
6451
6874
 
6452
6875
  // src/components/chat/BranchNavigator.tsx
6453
- import React70 from "react";
6876
+ import React75 from "react";
6454
6877
  import { ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight3, GitBranch } from "lucide-react";
6455
- var BranchNavigator = React70.forwardRef(
6878
+ var BranchNavigator = React75.forwardRef(
6456
6879
  ({
6457
6880
  current,
6458
6881
  total,
@@ -6471,7 +6894,7 @@ var BranchNavigator = React70.forwardRef(
6471
6894
  const buttonSize = size === "sm" ? "p-0.5" : "p-1";
6472
6895
  const iconSize = size === "sm" ? "w-3 h-3" : "w-4 h-4";
6473
6896
  const textSize = size === "sm" ? "text-xs" : "text-sm";
6474
- return /* @__PURE__ */ React70.createElement(
6897
+ return /* @__PURE__ */ React75.createElement(
6475
6898
  "div",
6476
6899
  {
6477
6900
  ref,
@@ -6483,8 +6906,8 @@ var BranchNavigator = React70.forwardRef(
6483
6906
  "aria-label": "Branch navigation",
6484
6907
  ...rest
6485
6908
  },
6486
- showIcon && /* @__PURE__ */ React70.createElement(GitBranch, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
6487
- /* @__PURE__ */ React70.createElement(
6909
+ showIcon && /* @__PURE__ */ React75.createElement(GitBranch, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
6910
+ /* @__PURE__ */ React75.createElement(
6488
6911
  "button",
6489
6912
  {
6490
6913
  type: "button",
@@ -6497,10 +6920,10 @@ var BranchNavigator = React70.forwardRef(
6497
6920
  ),
6498
6921
  "aria-label": "Previous branch"
6499
6922
  },
6500
- /* @__PURE__ */ React70.createElement(ChevronLeft2, { className: iconSize })
6923
+ /* @__PURE__ */ React75.createElement(ChevronLeft2, { className: iconSize })
6501
6924
  ),
6502
- /* @__PURE__ */ React70.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
6503
- /* @__PURE__ */ React70.createElement(
6925
+ /* @__PURE__ */ React75.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
6926
+ /* @__PURE__ */ React75.createElement(
6504
6927
  "button",
6505
6928
  {
6506
6929
  type: "button",
@@ -6513,7 +6936,7 @@ var BranchNavigator = React70.forwardRef(
6513
6936
  ),
6514
6937
  "aria-label": "Next branch"
6515
6938
  },
6516
- /* @__PURE__ */ React70.createElement(ChevronRight3, { className: iconSize })
6939
+ /* @__PURE__ */ React75.createElement(ChevronRight3, { className: iconSize })
6517
6940
  )
6518
6941
  );
6519
6942
  }
@@ -6521,16 +6944,16 @@ var BranchNavigator = React70.forwardRef(
6521
6944
  BranchNavigator.displayName = "BranchNavigator";
6522
6945
 
6523
6946
  // src/components/BrandIcon.tsx
6524
- import React71 from "react";
6947
+ import React76 from "react";
6525
6948
  var sizeMap2 = {
6526
6949
  sm: "h-8 w-8 text-sm",
6527
6950
  md: "h-12 w-12 text-base",
6528
6951
  lg: "h-16 w-16 text-lg"
6529
6952
  };
6530
- var BrandIcon = React71.forwardRef(
6953
+ var BrandIcon = React76.forwardRef(
6531
6954
  ({ size = "md", variant = "solid", children, className, ...rest }, ref) => {
6532
6955
  const variantClasses = variant === "solid" ? "bg-gold text-obsidian border-2 border-gold" : "bg-transparent text-gold border-2 border-gold";
6533
- return /* @__PURE__ */ React71.createElement(
6956
+ return /* @__PURE__ */ React76.createElement(
6534
6957
  "div",
6535
6958
  {
6536
6959
  ref,
@@ -6549,17 +6972,17 @@ var BrandIcon = React71.forwardRef(
6549
6972
  BrandIcon.displayName = "BrandIcon";
6550
6973
 
6551
6974
  // src/components/ColorSwatch.tsx
6552
- import React72 from "react";
6553
- var ColorSwatch = React72.forwardRef(
6975
+ import React77 from "react";
6976
+ var ColorSwatch = React77.forwardRef(
6554
6977
  ({ color, label, className, ...rest }, ref) => {
6555
- return /* @__PURE__ */ React72.createElement(
6978
+ return /* @__PURE__ */ React77.createElement(
6556
6979
  "div",
6557
6980
  {
6558
6981
  ref,
6559
6982
  className: cx("flex flex-col items-center gap-2", className),
6560
6983
  ...rest
6561
6984
  },
6562
- /* @__PURE__ */ React72.createElement(
6985
+ /* @__PURE__ */ React77.createElement(
6563
6986
  "div",
6564
6987
  {
6565
6988
  className: "h-16 w-16 border-2 border-ash rounded-none shadow-sm",
@@ -6567,22 +6990,22 @@ var ColorSwatch = React72.forwardRef(
6567
6990
  "aria-label": label || color
6568
6991
  }
6569
6992
  ),
6570
- label && /* @__PURE__ */ React72.createElement("span", { className: "text-xs text-silver font-medium" }, label)
6993
+ label && /* @__PURE__ */ React77.createElement("span", { className: "text-xs text-silver font-medium" }, label)
6571
6994
  );
6572
6995
  }
6573
6996
  );
6574
6997
  ColorSwatch.displayName = "ColorSwatch";
6575
6998
 
6576
6999
  // src/components/SectionHeading.tsx
6577
- import React73 from "react";
7000
+ import React78 from "react";
6578
7001
  var levelStyles = {
6579
7002
  h2: "text-2xl mb-4",
6580
7003
  h3: "text-xl mb-3"
6581
7004
  };
6582
- var SectionHeading = React73.forwardRef(
7005
+ var SectionHeading = React78.forwardRef(
6583
7006
  ({ level = "h2", children, className, ...rest }, ref) => {
6584
7007
  const Component = level;
6585
- return /* @__PURE__ */ React73.createElement(
7008
+ return /* @__PURE__ */ React78.createElement(
6586
7009
  Component,
6587
7010
  {
6588
7011
  ref,
@@ -6599,6 +7022,13 @@ var SectionHeading = React73.forwardRef(
6599
7022
  );
6600
7023
  SectionHeading.displayName = "SectionHeading";
6601
7024
 
7025
+ // src/components/ArtifactNode.ts
7026
+ var NODE_TYPES = {
7027
+ ARTIFACT: "ARTIFACT",
7028
+ GROUP: "GROUP",
7029
+ VARIANT_SET: "VARIANT_SET"
7030
+ };
7031
+
6602
7032
  // src/index.ts
6603
7033
  var version = "2.0.0";
6604
7034
  export {
@@ -6610,6 +7040,8 @@ export {
6610
7040
  Alert,
6611
7041
  AlertDialog,
6612
7042
  ArtifactCard,
7043
+ ArtifactGroup,
7044
+ ArtifactVariantStack,
6613
7045
  ArtifactsPanel,
6614
7046
  ArtifactsPanelToggle,
6615
7047
  AttachmentPreview,
@@ -6660,6 +7092,7 @@ export {
6660
7092
  ListItemText,
6661
7093
  ListSubheader,
6662
7094
  MarkdownContent,
7095
+ MediaIcon,
6663
7096
  Menu,
6664
7097
  MenuContent,
6665
7098
  MenuItem,
@@ -6669,6 +7102,7 @@ export {
6669
7102
  Message,
6670
7103
  MessageActions,
6671
7104
  Modal,
7105
+ NODE_TYPES,
6672
7106
  Navbar,
6673
7107
  NavbarBrand,
6674
7108
  NavbarContent,
@@ -6713,9 +7147,12 @@ export {
6713
7147
  ThinkingIndicator,
6714
7148
  ToastProvider,
6715
7149
  TodosList,
7150
+ ToolPanelContainer,
7151
+ ToolSidebar,
6716
7152
  Tooltip,
6717
7153
  VideoCard,
6718
7154
  addMessageToTree,
7155
+ areAllTasksSettled,
6719
7156
  createEmptyTree,
6720
7157
  createPreviewUrl,
6721
7158
  generateId,
@@ -6727,7 +7164,7 @@ export {
6727
7164
  revokePreviewUrl,
6728
7165
  switchBranch,
6729
7166
  updateNodeContent,
6730
- useArtifacts,
7167
+ useArtifactTreeNavigation,
6731
7168
  useResizable,
6732
7169
  useScrollAnchor,
6733
7170
  useToast,