@lukeashford/aurelius 2.20.0 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -38,6 +38,8 @@ __export(index_exports, {
38
38
  Alert: () => Alert,
39
39
  AlertDialog: () => AlertDialog,
40
40
  ArtifactCard: () => ArtifactCard,
41
+ ArtifactGroup: () => ArtifactGroup,
42
+ ArtifactVariantStack: () => ArtifactVariantStack,
41
43
  ArtifactsPanel: () => ArtifactsPanel,
42
44
  ArtifactsPanelToggle: () => ArtifactsPanelToggle,
43
45
  AttachmentPreview: () => AttachmentPreview,
@@ -88,6 +90,7 @@ __export(index_exports, {
88
90
  ListItemText: () => ListItemText,
89
91
  ListSubheader: () => ListSubheader,
90
92
  MarkdownContent: () => MarkdownContent,
93
+ MediaIcon: () => MediaIcon,
91
94
  Menu: () => Menu,
92
95
  MenuContent: () => MenuContent,
93
96
  MenuItem: () => MenuItem,
@@ -97,6 +100,7 @@ __export(index_exports, {
97
100
  Message: () => Message,
98
101
  MessageActions: () => MessageActions,
99
102
  Modal: () => Modal,
103
+ NODE_TYPES: () => NODE_TYPES,
100
104
  Navbar: () => Navbar,
101
105
  NavbarBrand: () => NavbarBrand,
102
106
  NavbarContent: () => NavbarContent,
@@ -141,9 +145,12 @@ __export(index_exports, {
141
145
  ThinkingIndicator: () => ThinkingIndicator,
142
146
  ToastProvider: () => ToastProvider,
143
147
  TodosList: () => TodosList,
148
+ ToolPanelContainer: () => ToolPanelContainer,
149
+ ToolSidebar: () => ToolSidebar,
144
150
  Tooltip: () => Tooltip,
145
151
  VideoCard: () => VideoCard,
146
152
  addMessageToTree: () => addMessageToTree,
153
+ areAllTasksSettled: () => areAllTasksSettled,
147
154
  createEmptyTree: () => createEmptyTree,
148
155
  createPreviewUrl: () => createPreviewUrl,
149
156
  generateId: () => generateId,
@@ -155,6 +162,7 @@ __export(index_exports, {
155
162
  revokePreviewUrl: () => revokePreviewUrl,
156
163
  switchBranch: () => switchBranch,
157
164
  updateNodeContent: () => updateNodeContent,
165
+ useArtifactTreeNavigation: () => useArtifactTreeNavigation,
158
166
  useArtifacts: () => useArtifacts,
159
167
  useResizable: () => useResizable,
160
168
  useScrollAnchor: () => useScrollAnchor,
@@ -2334,7 +2342,7 @@ var Modal = ({ isOpen, onClose, title, children, className }) => {
2334
2342
  role: "dialog",
2335
2343
  "aria-modal": "true",
2336
2344
  className: cx(
2337
- "bg-charcoal border border-gold/30 shadow-2xl z-50 w-full max-w-lg p-6 rounded-none relative",
2345
+ "bg-charcoal border border-gold/30 shadow-2xl z-50 w-full max-w-lg p-6 rounded-none relative flex flex-col",
2338
2346
  className
2339
2347
  ),
2340
2348
  "data-state": "open",
@@ -2349,7 +2357,7 @@ var Modal = ({ isOpen, onClose, title, children, className }) => {
2349
2357
  /* @__PURE__ */ import_react30.default.createElement(import_lucide_react5.X, { className: "h-5 w-5" }),
2350
2358
  /* @__PURE__ */ import_react30.default.createElement("span", { className: "sr-only" }, "Close")
2351
2359
  )),
2352
- /* @__PURE__ */ import_react30.default.createElement("div", null, children)
2360
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "overflow-y-auto min-h-0" }, children)
2353
2361
  )
2354
2362
  );
2355
2363
  return (0, import_react_dom2.createPortal)(content, document.body);
@@ -3611,9 +3619,9 @@ function LayersIcon({ className, ...props }) {
3611
3619
  );
3612
3620
  }
3613
3621
 
3614
- // src/components/icons/PlusIcon.tsx
3622
+ // src/components/icons/MediaIcon.tsx
3615
3623
  var import_react47 = __toESM(require("react"));
3616
- function PlusIcon({ className, ...props }) {
3624
+ function MediaIcon({ className, ...props }) {
3617
3625
  return /* @__PURE__ */ import_react47.default.createElement(
3618
3626
  "svg",
3619
3627
  {
@@ -3624,6 +3632,29 @@ function PlusIcon({ className, ...props }) {
3624
3632
  ...props
3625
3633
  },
3626
3634
  /* @__PURE__ */ import_react47.default.createElement(
3635
+ "path",
3636
+ {
3637
+ fillRule: "evenodd",
3638
+ 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",
3639
+ clipRule: "evenodd"
3640
+ }
3641
+ )
3642
+ );
3643
+ }
3644
+
3645
+ // src/components/icons/PlusIcon.tsx
3646
+ var import_react48 = __toESM(require("react"));
3647
+ function PlusIcon({ className, ...props }) {
3648
+ return /* @__PURE__ */ import_react48.default.createElement(
3649
+ "svg",
3650
+ {
3651
+ xmlns: "http://www.w3.org/2000/svg",
3652
+ viewBox: "0 0 20 20",
3653
+ fill: "currentColor",
3654
+ className,
3655
+ ...props
3656
+ },
3657
+ /* @__PURE__ */ import_react48.default.createElement(
3627
3658
  "path",
3628
3659
  {
3629
3660
  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"
@@ -3633,9 +3664,9 @@ function PlusIcon({ className, ...props }) {
3633
3664
  }
3634
3665
 
3635
3666
  // src/components/icons/CheckSquareIcon.tsx
3636
- var import_react48 = __toESM(require("react"));
3667
+ var import_react49 = __toESM(require("react"));
3637
3668
  function CheckSquareIcon({ className, ...props }) {
3638
- return /* @__PURE__ */ import_react48.default.createElement(
3669
+ return /* @__PURE__ */ import_react49.default.createElement(
3639
3670
  "div",
3640
3671
  {
3641
3672
  className: cx(
@@ -3644,14 +3675,14 @@ function CheckSquareIcon({ className, ...props }) {
3644
3675
  ),
3645
3676
  ...props
3646
3677
  },
3647
- /* @__PURE__ */ import_react48.default.createElement(
3678
+ /* @__PURE__ */ import_react49.default.createElement(
3648
3679
  "svg",
3649
3680
  {
3650
3681
  viewBox: "0 0 16 16",
3651
3682
  fill: "none",
3652
3683
  className: "absolute inset-0 w-full h-full p-0.5"
3653
3684
  },
3654
- /* @__PURE__ */ import_react48.default.createElement(
3685
+ /* @__PURE__ */ import_react49.default.createElement(
3655
3686
  "path",
3656
3687
  {
3657
3688
  d: "M3 8l3 3 7-7",
@@ -3667,9 +3698,9 @@ function CheckSquareIcon({ className, ...props }) {
3667
3698
  }
3668
3699
 
3669
3700
  // src/components/icons/EmptySquareIcon.tsx
3670
- var import_react49 = __toESM(require("react"));
3701
+ var import_react50 = __toESM(require("react"));
3671
3702
  function EmptySquareIcon({ className, ...props }) {
3672
- return /* @__PURE__ */ import_react49.default.createElement(
3703
+ return /* @__PURE__ */ import_react50.default.createElement(
3673
3704
  "div",
3674
3705
  {
3675
3706
  className: cx(
@@ -3682,9 +3713,9 @@ function EmptySquareIcon({ className, ...props }) {
3682
3713
  }
3683
3714
 
3684
3715
  // src/components/icons/CrossSquareIcon.tsx
3685
- var import_react50 = __toESM(require("react"));
3716
+ var import_react51 = __toESM(require("react"));
3686
3717
  function CrossSquareIcon({ className, variant = "cancelled", ...props }) {
3687
- return /* @__PURE__ */ import_react50.default.createElement(
3718
+ return /* @__PURE__ */ import_react51.default.createElement(
3688
3719
  "div",
3689
3720
  {
3690
3721
  className: cx(
@@ -3694,14 +3725,14 @@ function CrossSquareIcon({ className, variant = "cancelled", ...props }) {
3694
3725
  ),
3695
3726
  ...props
3696
3727
  },
3697
- /* @__PURE__ */ import_react50.default.createElement(
3728
+ /* @__PURE__ */ import_react51.default.createElement(
3698
3729
  "svg",
3699
3730
  {
3700
3731
  viewBox: "0 0 16 16",
3701
3732
  fill: "none",
3702
3733
  className: "absolute inset-0 w-full h-full p-0.5"
3703
3734
  },
3704
- /* @__PURE__ */ import_react50.default.createElement(
3735
+ /* @__PURE__ */ import_react51.default.createElement(
3705
3736
  "path",
3706
3737
  {
3707
3738
  d: "M4 4l8 8M12 4l-8 8",
@@ -3716,15 +3747,15 @@ function CrossSquareIcon({ className, variant = "cancelled", ...props }) {
3716
3747
  }
3717
3748
 
3718
3749
  // src/components/icons/SquareLoaderIcon.tsx
3719
- var import_react51 = __toESM(require("react"));
3750
+ var import_react52 = __toESM(require("react"));
3720
3751
  function SquareLoaderIcon({ className, ...props }) {
3721
- return /* @__PURE__ */ import_react51.default.createElement("div", { className: cx("relative w-4 h-4 flex-shrink-0", className), ...props }, /* @__PURE__ */ import_react51.default.createElement(
3752
+ return /* @__PURE__ */ import_react52.default.createElement("div", { className: cx("relative w-4 h-4 flex-shrink-0", className), ...props }, /* @__PURE__ */ import_react52.default.createElement(
3722
3753
  "svg",
3723
3754
  {
3724
3755
  viewBox: "0 0 16 16",
3725
3756
  className: "w-full h-full animate-snake-spin"
3726
3757
  },
3727
- /* @__PURE__ */ import_react51.default.createElement(
3758
+ /* @__PURE__ */ import_react52.default.createElement(
3728
3759
  "rect",
3729
3760
  {
3730
3761
  x: "1",
@@ -3737,7 +3768,7 @@ function SquareLoaderIcon({ className, ...props }) {
3737
3768
  className: "text-ash/40"
3738
3769
  }
3739
3770
  ),
3740
- /* @__PURE__ */ import_react51.default.createElement(
3771
+ /* @__PURE__ */ import_react52.default.createElement(
3741
3772
  "rect",
3742
3773
  {
3743
3774
  x: "1",
@@ -3756,10 +3787,10 @@ function SquareLoaderIcon({ className, ...props }) {
3756
3787
  }
3757
3788
 
3758
3789
  // src/components/Message.tsx
3759
- var import_react53 = __toESM(require("react"));
3790
+ var import_react54 = __toESM(require("react"));
3760
3791
 
3761
3792
  // src/components/MarkdownContent.tsx
3762
- var import_react52 = __toESM(require("react"));
3793
+ var import_react53 = __toESM(require("react"));
3763
3794
  var import_dompurify = __toESM(require("dompurify"));
3764
3795
  var import_marked = require("marked");
3765
3796
  var DEFAULT_SANITIZE_CONFIG = {
@@ -3830,7 +3861,7 @@ var DEFAULT_SANITIZE_CONFIG = {
3830
3861
  ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto|tel):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i
3831
3862
  };
3832
3863
  function useDOMPurifySetup() {
3833
- (0, import_react52.useMemo)(() => {
3864
+ (0, import_react53.useMemo)(() => {
3834
3865
  import_dompurify.default.addHook("afterSanitizeAttributes", (node) => {
3835
3866
  if (node.tagName === "A") {
3836
3867
  node.setAttribute("target", "_blank");
@@ -3866,10 +3897,10 @@ function injectStreamingCursor(html, cursorClassName) {
3866
3897
  target.insertAdjacentHTML("beforeend", cursorHtml);
3867
3898
  return container.innerHTML;
3868
3899
  }
3869
- var MarkdownContent = import_react52.default.forwardRef(
3900
+ var MarkdownContent = import_react53.default.forwardRef(
3870
3901
  ({ className, content, isMarkdown = true, sanitizeConfig, isStreaming, cursorClassName, ...rest }, ref) => {
3871
3902
  useDOMPurifySetup();
3872
- const sanitizedHtml = (0, import_react52.useMemo)(() => {
3903
+ const sanitizedHtml = (0, import_react53.useMemo)(() => {
3873
3904
  if (!content && !isStreaming) {
3874
3905
  return "";
3875
3906
  }
@@ -3891,7 +3922,7 @@ var MarkdownContent = import_react52.default.forwardRef(
3891
3922
  }
3892
3923
  return sanitized;
3893
3924
  }, [content, sanitizeConfig, isStreaming, cursorClassName]);
3894
- return /* @__PURE__ */ import_react52.default.createElement(
3925
+ return /* @__PURE__ */ import_react53.default.createElement(
3895
3926
  "div",
3896
3927
  {
3897
3928
  ref,
@@ -3909,7 +3940,7 @@ var variantStyles2 = {
3909
3940
  user: "bg-gold text-obsidian ml-auto",
3910
3941
  assistant: "bg-charcoal border border-ash text-white mr-auto"
3911
3942
  };
3912
- var ActionButton = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ import_react53.default.createElement(
3943
+ var ActionButton = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ import_react54.default.createElement(
3913
3944
  "button",
3914
3945
  {
3915
3946
  type: "button",
@@ -3925,7 +3956,7 @@ var ActionButton = ({ onClick, label, children, className, disabled }) => /* @__
3925
3956
  },
3926
3957
  children
3927
3958
  );
3928
- var CopyIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3959
+ var CopyIcon = () => /* @__PURE__ */ import_react54.default.createElement(
3929
3960
  "svg",
3930
3961
  {
3931
3962
  xmlns: "http://www.w3.org/2000/svg",
@@ -3937,10 +3968,10 @@ var CopyIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3937
3968
  strokeLinejoin: "round",
3938
3969
  className: "w-3.5 h-3.5"
3939
3970
  },
3940
- /* @__PURE__ */ import_react53.default.createElement("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
3941
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
3971
+ /* @__PURE__ */ import_react54.default.createElement("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
3972
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })
3942
3973
  );
3943
- var CheckIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3974
+ var CheckIcon = () => /* @__PURE__ */ import_react54.default.createElement(
3944
3975
  "svg",
3945
3976
  {
3946
3977
  xmlns: "http://www.w3.org/2000/svg",
@@ -3952,9 +3983,9 @@ var CheckIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3952
3983
  strokeLinejoin: "round",
3953
3984
  className: "w-3.5 h-3.5 text-success"
3954
3985
  },
3955
- /* @__PURE__ */ import_react53.default.createElement("polyline", { points: "20 6 9 17 4 12" })
3986
+ /* @__PURE__ */ import_react54.default.createElement("polyline", { points: "20 6 9 17 4 12" })
3956
3987
  );
3957
- var PencilIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3988
+ var PencilIcon = () => /* @__PURE__ */ import_react54.default.createElement(
3958
3989
  "svg",
3959
3990
  {
3960
3991
  xmlns: "http://www.w3.org/2000/svg",
@@ -3966,10 +3997,10 @@ var PencilIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3966
3997
  strokeLinejoin: "round",
3967
3998
  className: "w-3.5 h-3.5"
3968
3999
  },
3969
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }),
3970
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "m15 5 4 4" })
4000
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" }),
4001
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "m15 5 4 4" })
3971
4002
  );
3972
- var RetryIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4003
+ var RetryIcon = () => /* @__PURE__ */ import_react54.default.createElement(
3973
4004
  "svg",
3974
4005
  {
3975
4006
  xmlns: "http://www.w3.org/2000/svg",
@@ -3981,12 +4012,12 @@ var RetryIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3981
4012
  strokeLinejoin: "round",
3982
4013
  className: "w-3.5 h-3.5"
3983
4014
  },
3984
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
3985
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M21 3v5h-5" }),
3986
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
3987
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M8 16H3v5" })
4015
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
4016
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "M21 3v5h-5" }),
4017
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
4018
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "M8 16H3v5" })
3988
4019
  );
3989
- var ChevronLeftIcon2 = () => /* @__PURE__ */ import_react53.default.createElement(
4020
+ var ChevronLeftIcon2 = () => /* @__PURE__ */ import_react54.default.createElement(
3990
4021
  "svg",
3991
4022
  {
3992
4023
  xmlns: "http://www.w3.org/2000/svg",
@@ -3998,9 +4029,9 @@ var ChevronLeftIcon2 = () => /* @__PURE__ */ import_react53.default.createElemen
3998
4029
  strokeLinejoin: "round",
3999
4030
  className: "w-3 h-3"
4000
4031
  },
4001
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "m15 18-6-6 6-6" })
4032
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "m15 18-6-6 6-6" })
4002
4033
  );
4003
- var ChevronRightIcon2 = () => /* @__PURE__ */ import_react53.default.createElement(
4034
+ var ChevronRightIcon2 = () => /* @__PURE__ */ import_react54.default.createElement(
4004
4035
  "svg",
4005
4036
  {
4006
4037
  xmlns: "http://www.w3.org/2000/svg",
@@ -4012,9 +4043,9 @@ var ChevronRightIcon2 = () => /* @__PURE__ */ import_react53.default.createEleme
4012
4043
  strokeLinejoin: "round",
4013
4044
  className: "w-3 h-3"
4014
4045
  },
4015
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "m9 18 6-6-6-6" })
4046
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "m9 18 6-6-6-6" })
4016
4047
  );
4017
- var GitBranchIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4048
+ var GitBranchIcon = () => /* @__PURE__ */ import_react54.default.createElement(
4018
4049
  "svg",
4019
4050
  {
4020
4051
  xmlns: "http://www.w3.org/2000/svg",
@@ -4026,12 +4057,12 @@ var GitBranchIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4026
4057
  strokeLinejoin: "round",
4027
4058
  className: "w-3 h-3 mr-0.5 text-silver/50"
4028
4059
  },
4029
- /* @__PURE__ */ import_react53.default.createElement("line", { x1: "6", x2: "6", y1: "3", y2: "15" }),
4030
- /* @__PURE__ */ import_react53.default.createElement("circle", { cx: "18", cy: "6", r: "3" }),
4031
- /* @__PURE__ */ import_react53.default.createElement("circle", { cx: "6", cy: "18", r: "3" }),
4032
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })
4060
+ /* @__PURE__ */ import_react54.default.createElement("line", { x1: "6", x2: "6", y1: "3", y2: "15" }),
4061
+ /* @__PURE__ */ import_react54.default.createElement("circle", { cx: "18", cy: "6", r: "3" }),
4062
+ /* @__PURE__ */ import_react54.default.createElement("circle", { cx: "6", cy: "18", r: "3" }),
4063
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "M18 9a9 9 0 0 1-9 9" })
4033
4064
  );
4034
- var XIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4065
+ var XIcon = () => /* @__PURE__ */ import_react54.default.createElement(
4035
4066
  "svg",
4036
4067
  {
4037
4068
  xmlns: "http://www.w3.org/2000/svg",
@@ -4043,10 +4074,10 @@ var XIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4043
4074
  strokeLinejoin: "round",
4044
4075
  className: "w-4 h-4"
4045
4076
  },
4046
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M18 6 6 18" }),
4047
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "m6 6 12 12" })
4077
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "M18 6 6 18" }),
4078
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "m6 6 12 12" })
4048
4079
  );
4049
- var SendIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4080
+ var SendIcon = () => /* @__PURE__ */ import_react54.default.createElement(
4050
4081
  "svg",
4051
4082
  {
4052
4083
  xmlns: "http://www.w3.org/2000/svg",
@@ -4058,10 +4089,10 @@ var SendIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4058
4089
  strokeLinejoin: "round",
4059
4090
  className: "w-4 h-4"
4060
4091
  },
4061
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "m22 2-7 20-4-9-9-4Z" }),
4062
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M22 2 11 13" })
4092
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "m22 2-7 20-4-9-9-4Z" }),
4093
+ /* @__PURE__ */ import_react54.default.createElement("path", { d: "M22 2 11 13" })
4063
4094
  );
4064
- var Message = import_react53.default.forwardRef(
4095
+ var Message = import_react54.default.forwardRef(
4065
4096
  ({
4066
4097
  variant = "assistant",
4067
4098
  className,
@@ -4073,13 +4104,13 @@ var Message = import_react53.default.forwardRef(
4073
4104
  ...rest
4074
4105
  }, ref) => {
4075
4106
  const isUser = variant === "user";
4076
- const [copied, setCopied] = (0, import_react53.useState)(false);
4077
- const [isEditing, setIsEditing] = (0, import_react53.useState)(false);
4078
- const [editValue, setEditValue] = (0, import_react53.useState)(content);
4079
- const textareaRef = (0, import_react53.useRef)(null);
4107
+ const [copied, setCopied] = (0, import_react54.useState)(false);
4108
+ const [isEditing, setIsEditing] = (0, import_react54.useState)(false);
4109
+ const [editValue, setEditValue] = (0, import_react54.useState)(content);
4110
+ const textareaRef = (0, import_react54.useRef)(null);
4080
4111
  const showBranchNav = branchInfo && branchInfo.total > 1;
4081
4112
  const showActions = actions && !hideActions && !isStreaming;
4082
- (0, import_react53.useEffect)(() => {
4113
+ (0, import_react54.useEffect)(() => {
4083
4114
  if (isEditing && textareaRef.current) {
4084
4115
  const textarea = textareaRef.current;
4085
4116
  textarea.style.height = "auto";
@@ -4133,7 +4164,7 @@ var Message = import_react53.default.forwardRef(
4133
4164
  textarea.style.height = "auto";
4134
4165
  textarea.style.height = `${textarea.scrollHeight}px`;
4135
4166
  };
4136
- return /* @__PURE__ */ import_react53.default.createElement(
4167
+ return /* @__PURE__ */ import_react54.default.createElement(
4137
4168
  "div",
4138
4169
  {
4139
4170
  ref,
@@ -4144,7 +4175,7 @@ var Message = import_react53.default.forwardRef(
4144
4175
  ),
4145
4176
  ...rest
4146
4177
  },
4147
- isUser && isEditing ? /* @__PURE__ */ import_react53.default.createElement("div", { className: "w-full max-w-11/12" }, /* @__PURE__ */ import_react53.default.createElement("div", { className: "relative bg-gold" }, /* @__PURE__ */ import_react53.default.createElement(
4178
+ isUser && isEditing ? /* @__PURE__ */ import_react54.default.createElement("div", { className: "w-full max-w-11/12" }, /* @__PURE__ */ import_react54.default.createElement("div", { className: "relative bg-gold" }, /* @__PURE__ */ import_react54.default.createElement(
4148
4179
  "textarea",
4149
4180
  {
4150
4181
  ref: textareaRef,
@@ -4154,7 +4185,7 @@ var Message = import_react53.default.forwardRef(
4154
4185
  className: "w-full bg-transparent text-obsidian px-3 py-2 pr-20 resize-none outline-none min-h-10 text-sm",
4155
4186
  rows: 1
4156
4187
  }
4157
- ), /* @__PURE__ */ import_react53.default.createElement("div", { className: "absolute right-1 top-1/2 -translate-y-1/2 flex gap-0.5" }, /* @__PURE__ */ import_react53.default.createElement(
4188
+ ), /* @__PURE__ */ import_react54.default.createElement("div", { className: "absolute right-1 top-1/2 -translate-y-1/2 flex gap-0.5" }, /* @__PURE__ */ import_react54.default.createElement(
4158
4189
  "button",
4159
4190
  {
4160
4191
  type: "button",
@@ -4162,8 +4193,8 @@ var Message = import_react53.default.forwardRef(
4162
4193
  className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors",
4163
4194
  "aria-label": "Cancel edit"
4164
4195
  },
4165
- /* @__PURE__ */ import_react53.default.createElement(XIcon, null)
4166
- ), /* @__PURE__ */ import_react53.default.createElement(
4196
+ /* @__PURE__ */ import_react54.default.createElement(XIcon, null)
4197
+ ), /* @__PURE__ */ import_react54.default.createElement(
4167
4198
  "button",
4168
4199
  {
4169
4200
  type: "button",
@@ -4172,8 +4203,8 @@ var Message = import_react53.default.forwardRef(
4172
4203
  className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors disabled:opacity-30",
4173
4204
  "aria-label": "Submit edit"
4174
4205
  },
4175
- /* @__PURE__ */ import_react53.default.createElement(SendIcon, null)
4176
- )))) : /* @__PURE__ */ import_react53.default.createElement(
4206
+ /* @__PURE__ */ import_react54.default.createElement(SendIcon, null)
4207
+ )))) : /* @__PURE__ */ import_react54.default.createElement(
4177
4208
  "div",
4178
4209
  {
4179
4210
  className: cx(
@@ -4181,7 +4212,7 @@ var Message = import_react53.default.forwardRef(
4181
4212
  variantStyles2[variant]
4182
4213
  )
4183
4214
  },
4184
- /* @__PURE__ */ import_react53.default.createElement(
4215
+ /* @__PURE__ */ import_react54.default.createElement(
4185
4216
  MarkdownContent,
4186
4217
  {
4187
4218
  content,
@@ -4191,17 +4222,17 @@ var Message = import_react53.default.forwardRef(
4191
4222
  }
4192
4223
  )
4193
4224
  ),
4194
- showActions && !isEditing && /* @__PURE__ */ import_react53.default.createElement("div", { className: cx(
4225
+ showActions && !isEditing && /* @__PURE__ */ import_react54.default.createElement("div", { className: cx(
4195
4226
  "flex items-center gap-0.5 mt-1",
4196
4227
  isUser ? "mr-1" : "ml-1"
4197
- ) }, actions.showCopy !== false && /* @__PURE__ */ import_react53.default.createElement(
4228
+ ) }, actions.showCopy !== false && /* @__PURE__ */ import_react54.default.createElement(
4198
4229
  ActionButton,
4199
4230
  {
4200
4231
  onClick: handleCopy,
4201
4232
  label: copied ? "Copied!" : "Copy message"
4202
4233
  },
4203
- copied ? /* @__PURE__ */ import_react53.default.createElement(CheckIcon, null) : /* @__PURE__ */ import_react53.default.createElement(CopyIcon, null)
4204
- ), isUser && actions.onEdit && /* @__PURE__ */ import_react53.default.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ import_react53.default.createElement(PencilIcon, null)), !isUser && actions.onRetry && /* @__PURE__ */ import_react53.default.createElement(ActionButton, { onClick: actions.onRetry, label: "Regenerate response" }, /* @__PURE__ */ import_react53.default.createElement(RetryIcon, null)), showBranchNav && /* @__PURE__ */ import_react53.default.createElement(import_react53.default.Fragment, null, /* @__PURE__ */ import_react53.default.createElement("div", { className: "w-px h-4 bg-ash/40 mx-1" }), /* @__PURE__ */ import_react53.default.createElement("div", { className: "flex items-center gap-0.5 text-silver/70" }, /* @__PURE__ */ import_react53.default.createElement(GitBranchIcon, null), /* @__PURE__ */ import_react53.default.createElement(
4234
+ copied ? /* @__PURE__ */ import_react54.default.createElement(CheckIcon, null) : /* @__PURE__ */ import_react54.default.createElement(CopyIcon, null)
4235
+ ), isUser && actions.onEdit && /* @__PURE__ */ import_react54.default.createElement(ActionButton, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ import_react54.default.createElement(PencilIcon, null)), !isUser && actions.onRetry && /* @__PURE__ */ import_react54.default.createElement(ActionButton, { onClick: actions.onRetry, label: "Regenerate response" }, /* @__PURE__ */ import_react54.default.createElement(RetryIcon, null)), showBranchNav && /* @__PURE__ */ import_react54.default.createElement(import_react54.default.Fragment, null, /* @__PURE__ */ import_react54.default.createElement("div", { className: "w-px h-4 bg-ash/40 mx-1" }), /* @__PURE__ */ import_react54.default.createElement("div", { className: "flex items-center gap-0.5 text-silver/70" }, /* @__PURE__ */ import_react54.default.createElement(GitBranchIcon, null), /* @__PURE__ */ import_react54.default.createElement(
4205
4236
  "button",
4206
4237
  {
4207
4238
  type: "button",
@@ -4213,8 +4244,8 @@ var Message = import_react53.default.forwardRef(
4213
4244
  ),
4214
4245
  "aria-label": "Previous branch"
4215
4246
  },
4216
- /* @__PURE__ */ import_react53.default.createElement(ChevronLeftIcon2, null)
4217
- ), /* @__PURE__ */ import_react53.default.createElement("span", { className: "text-xs tabular-nums min-w-6 text-center" }, branchInfo.current, "/", branchInfo.total), /* @__PURE__ */ import_react53.default.createElement(
4247
+ /* @__PURE__ */ import_react54.default.createElement(ChevronLeftIcon2, null)
4248
+ ), /* @__PURE__ */ import_react54.default.createElement("span", { className: "text-xs tabular-nums min-w-6 text-center" }, branchInfo.current, "/", branchInfo.total), /* @__PURE__ */ import_react54.default.createElement(
4218
4249
  "button",
4219
4250
  {
4220
4251
  type: "button",
@@ -4226,7 +4257,7 @@ var Message = import_react53.default.forwardRef(
4226
4257
  ),
4227
4258
  "aria-label": "Next branch"
4228
4259
  },
4229
- /* @__PURE__ */ import_react53.default.createElement(ChevronRightIcon2, null)
4260
+ /* @__PURE__ */ import_react54.default.createElement(ChevronRightIcon2, null)
4230
4261
  ))))
4231
4262
  );
4232
4263
  }
@@ -4234,15 +4265,15 @@ var Message = import_react53.default.forwardRef(
4234
4265
  Message.displayName = "Message";
4235
4266
 
4236
4267
  // src/components/StreamingCursor.tsx
4237
- var import_react54 = __toESM(require("react"));
4238
- var StreamingCursor = import_react54.default.forwardRef(
4268
+ var import_react55 = __toESM(require("react"));
4269
+ var StreamingCursor = import_react55.default.forwardRef(
4239
4270
  ({ className, variant = "line", ...rest }, ref) => {
4240
4271
  const variantStyles3 = {
4241
4272
  block: "w-2.5 h-cursor translate-y-cursor-offset",
4242
4273
  line: "w-0.5 h-cursor translate-y-cursor-offset",
4243
4274
  underscore: "w-2.5 h-0.5 self-end mb-0.5"
4244
4275
  };
4245
- return /* @__PURE__ */ import_react54.default.createElement(
4276
+ return /* @__PURE__ */ import_react55.default.createElement(
4246
4277
  "span",
4247
4278
  {
4248
4279
  ref,
@@ -4260,18 +4291,18 @@ var StreamingCursor = import_react54.default.forwardRef(
4260
4291
  StreamingCursor.displayName = "StreamingCursor";
4261
4292
 
4262
4293
  // src/components/chat/ChatInterface.tsx
4263
- var import_react72 = __toESM(require("react"));
4294
+ var import_react78 = __toESM(require("react"));
4264
4295
 
4265
4296
  // src/components/chat/ChatView.tsx
4266
- var import_react58 = __toESM(require("react"));
4297
+ var import_react59 = __toESM(require("react"));
4267
4298
 
4268
4299
  // src/components/chat/hooks/useScrollAnchor.ts
4269
- var import_react55 = require("react");
4300
+ var import_react56 = require("react");
4270
4301
  function useScrollAnchor(options = {}) {
4271
4302
  const { behavior = "smooth", block = "start" } = options;
4272
- const containerRef = (0, import_react55.useRef)(null);
4273
- const anchorRef = (0, import_react55.useRef)(null);
4274
- const scrollToAnchor = (0, import_react55.useCallback)(() => {
4303
+ const containerRef = (0, import_react56.useRef)(null);
4304
+ const anchorRef = (0, import_react56.useRef)(null);
4305
+ const scrollToAnchor = (0, import_react56.useCallback)(() => {
4275
4306
  const el = anchorRef.current;
4276
4307
  if (!el) {
4277
4308
  return;
@@ -4282,7 +4313,7 @@ function useScrollAnchor(options = {}) {
4282
4313
  });
4283
4314
  });
4284
4315
  }, [behavior, block]);
4285
- const scrollToBottom = (0, import_react55.useCallback)(() => {
4316
+ const scrollToBottom = (0, import_react56.useCallback)(() => {
4286
4317
  const container = containerRef.current;
4287
4318
  if (!container) {
4288
4319
  return;
@@ -4293,7 +4324,7 @@ function useScrollAnchor(options = {}) {
4293
4324
  container.scrollTop = container.scrollHeight;
4294
4325
  }
4295
4326
  }, [behavior]);
4296
- const isScrolledToBottom = (0, import_react55.useCallback)(() => {
4327
+ const isScrolledToBottom = (0, import_react56.useCallback)(() => {
4297
4328
  const container = containerRef.current;
4298
4329
  if (!container) {
4299
4330
  return true;
@@ -4312,15 +4343,15 @@ function useScrollAnchor(options = {}) {
4312
4343
  }
4313
4344
 
4314
4345
  // src/components/chat/hooks/useAdaptiveSpacer.ts
4315
- var import_react56 = require("react");
4346
+ var import_react57 = require("react");
4316
4347
  function useAdaptiveSpacer(options = {}) {
4317
4348
  const { minHeight = 0, containerRef: externalContainerRef, anchorRef } = options;
4318
- const internalContainerRef = (0, import_react56.useRef)(null);
4349
+ const internalContainerRef = (0, import_react57.useRef)(null);
4319
4350
  const containerRef = externalContainerRef ?? internalContainerRef;
4320
- const contentRef = (0, import_react56.useRef)(null);
4321
- const spacerRef = (0, import_react56.useRef)(null);
4322
- const [spacerHeight, setSpacerHeight] = (0, import_react56.useState)(0);
4323
- const recalculate = (0, import_react56.useCallback)(() => {
4351
+ const contentRef = (0, import_react57.useRef)(null);
4352
+ const spacerRef = (0, import_react57.useRef)(null);
4353
+ const [spacerHeight, setSpacerHeight] = (0, import_react57.useState)(0);
4354
+ const recalculate = (0, import_react57.useCallback)(() => {
4324
4355
  const container = containerRef.current;
4325
4356
  const content = contentRef.current;
4326
4357
  if (!container || !content) {
@@ -4344,7 +4375,7 @@ function useAdaptiveSpacer(options = {}) {
4344
4375
  }
4345
4376
  setSpacerHeight(newSpacerHeight);
4346
4377
  }, [minHeight, anchorRef]);
4347
- (0, import_react56.useEffect)(() => {
4378
+ (0, import_react57.useEffect)(() => {
4348
4379
  const container = containerRef.current;
4349
4380
  const content = contentRef.current;
4350
4381
  if (!container || !content) {
@@ -4379,7 +4410,7 @@ function useAdaptiveSpacer(options = {}) {
4379
4410
  }
4380
4411
 
4381
4412
  // src/components/chat/ThinkingIndicator.tsx
4382
- var import_react57 = __toESM(require("react"));
4413
+ var import_react58 = __toESM(require("react"));
4383
4414
  var THINKING_PHRASES = [
4384
4415
  "Consulting the ancient tomes...",
4385
4416
  "Parsing the ineffable...",
@@ -4395,7 +4426,7 @@ var THINKING_PHRASES = [
4395
4426
  "Consulting my inner monologue...",
4396
4427
  "Summoning the muse..."
4397
4428
  ];
4398
- var ThinkingIndicator = import_react57.default.forwardRef(
4429
+ var ThinkingIndicator = import_react58.default.forwardRef(
4399
4430
  ({
4400
4431
  isVisible = true,
4401
4432
  phraseInterval = 2500,
@@ -4403,11 +4434,11 @@ var ThinkingIndicator = import_react57.default.forwardRef(
4403
4434
  className,
4404
4435
  ...rest
4405
4436
  }, ref) => {
4406
- const [currentIndex, setCurrentIndex] = (0, import_react57.useState)(
4437
+ const [currentIndex, setCurrentIndex] = (0, import_react58.useState)(
4407
4438
  () => Math.floor(Math.random() * phrases.length)
4408
4439
  );
4409
- const [isTransitioning, setIsTransitioning] = (0, import_react57.useState)(false);
4410
- (0, import_react57.useEffect)(() => {
4440
+ const [isTransitioning, setIsTransitioning] = (0, import_react58.useState)(false);
4441
+ (0, import_react58.useEffect)(() => {
4411
4442
  if (!isVisible || phrases.length <= 1) {
4412
4443
  return;
4413
4444
  }
@@ -4423,7 +4454,7 @@ var ThinkingIndicator = import_react57.default.forwardRef(
4423
4454
  if (!isVisible) {
4424
4455
  return null;
4425
4456
  }
4426
- return /* @__PURE__ */ import_react57.default.createElement(
4457
+ return /* @__PURE__ */ import_react58.default.createElement(
4427
4458
  "div",
4428
4459
  {
4429
4460
  ref,
@@ -4437,26 +4468,26 @@ var ThinkingIndicator = import_react57.default.forwardRef(
4437
4468
  "aria-live": "polite",
4438
4469
  ...rest
4439
4470
  },
4440
- /* @__PURE__ */ import_react57.default.createElement("div", { className: "flex gap-1", "aria-hidden": "true" }, /* @__PURE__ */ import_react57.default.createElement(
4471
+ /* @__PURE__ */ import_react58.default.createElement("div", { className: "flex gap-1", "aria-hidden": "true" }, /* @__PURE__ */ import_react58.default.createElement(
4441
4472
  "span",
4442
4473
  {
4443
4474
  className: "w-1.5 h-1.5 bg-gold/60 rounded-full animate-pulse",
4444
4475
  style: { animationDelay: "0ms" }
4445
4476
  }
4446
- ), /* @__PURE__ */ import_react57.default.createElement(
4477
+ ), /* @__PURE__ */ import_react58.default.createElement(
4447
4478
  "span",
4448
4479
  {
4449
4480
  className: "w-1.5 h-1.5 bg-gold/60 rounded-full animate-pulse",
4450
4481
  style: { animationDelay: "150ms" }
4451
4482
  }
4452
- ), /* @__PURE__ */ import_react57.default.createElement(
4483
+ ), /* @__PURE__ */ import_react58.default.createElement(
4453
4484
  "span",
4454
4485
  {
4455
4486
  className: "w-1.5 h-1.5 bg-gold/60 rounded-full animate-pulse",
4456
4487
  style: { animationDelay: "300ms" }
4457
4488
  }
4458
4489
  )),
4459
- /* @__PURE__ */ import_react57.default.createElement(
4490
+ /* @__PURE__ */ import_react58.default.createElement(
4460
4491
  "span",
4461
4492
  {
4462
4493
  className: cx(
@@ -4472,7 +4503,7 @@ var ThinkingIndicator = import_react57.default.forwardRef(
4472
4503
  ThinkingIndicator.displayName = "ThinkingIndicator";
4473
4504
 
4474
4505
  // src/components/chat/ChatView.tsx
4475
- var ChatView = import_react58.default.forwardRef(
4506
+ var ChatView = import_react59.default.forwardRef(
4476
4507
  ({ messages, latestUserMessageIndex, isStreaming, isThinking, onScroll, className, ...rest }, ref) => {
4477
4508
  const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
4478
4509
  behavior: "smooth",
@@ -4482,7 +4513,7 @@ var ChatView = import_react58.default.forwardRef(
4482
4513
  containerRef,
4483
4514
  anchorRef
4484
4515
  });
4485
- (0, import_react58.useEffect)(() => {
4516
+ (0, import_react59.useEffect)(() => {
4486
4517
  if (latestUserMessageIndex !== void 0 && latestUserMessageIndex >= 0) {
4487
4518
  scrollToAnchor();
4488
4519
  }
@@ -4494,7 +4525,7 @@ var ChatView = import_react58.default.forwardRef(
4494
4525
  return found;
4495
4526
  }, -1);
4496
4527
  const showThinking = isThinking && messages.length > 0 && messages[messages.length - 1]?.variant === "user";
4497
- return /* @__PURE__ */ import_react58.default.createElement(
4528
+ return /* @__PURE__ */ import_react59.default.createElement(
4498
4529
  "div",
4499
4530
  {
4500
4531
  ref: (node) => {
@@ -4514,7 +4545,7 @@ var ChatView = import_react58.default.forwardRef(
4514
4545
  ),
4515
4546
  ...rest
4516
4547
  },
4517
- /* @__PURE__ */ import_react58.default.createElement("div", { ref: contentRef, className: "relative flex flex-col gap-3" }, messages.map(({
4548
+ /* @__PURE__ */ import_react59.default.createElement("div", { ref: contentRef, className: "relative flex flex-col gap-3" }, messages.map(({
4518
4549
  id,
4519
4550
  variant,
4520
4551
  className: messageClassName,
@@ -4527,14 +4558,14 @@ var ChatView = import_react58.default.forwardRef(
4527
4558
  const isLastMessage = index === messages.length - 1;
4528
4559
  const showStreaming = isLastMessage && isStreaming && variant === "assistant";
4529
4560
  const isMessageStreaming = showStreaming || !!nodeIsStreaming;
4530
- return /* @__PURE__ */ import_react58.default.createElement(
4561
+ return /* @__PURE__ */ import_react59.default.createElement(
4531
4562
  "div",
4532
4563
  {
4533
4564
  key: id ?? `msg-${index}`,
4534
4565
  ref: isAnchor ? anchorRef : void 0,
4535
4566
  className: isAnchor ? "scroll-mt-4" : void 0
4536
4567
  },
4537
- /* @__PURE__ */ import_react58.default.createElement(
4568
+ /* @__PURE__ */ import_react59.default.createElement(
4538
4569
  Message,
4539
4570
  {
4540
4571
  variant,
@@ -4547,8 +4578,8 @@ var ChatView = import_react58.default.forwardRef(
4547
4578
  }
4548
4579
  )
4549
4580
  );
4550
- }), showThinking && /* @__PURE__ */ import_react58.default.createElement(ThinkingIndicator, { isVisible: true })),
4551
- /* @__PURE__ */ import_react58.default.createElement(
4581
+ }), showThinking && /* @__PURE__ */ import_react59.default.createElement(ThinkingIndicator, { isVisible: true })),
4582
+ /* @__PURE__ */ import_react59.default.createElement(
4552
4583
  "div",
4553
4584
  {
4554
4585
  ref: spacerRef,
@@ -4563,7 +4594,7 @@ var ChatView = import_react58.default.forwardRef(
4563
4594
  ChatView.displayName = "ChatView";
4564
4595
 
4565
4596
  // src/components/chat/ChatInput.tsx
4566
- var import_react59 = __toESM(require("react"));
4597
+ var import_react60 = __toESM(require("react"));
4567
4598
  var import_lucide_react11 = require("lucide-react");
4568
4599
 
4569
4600
  // src/components/chat/types.ts
@@ -4732,7 +4763,7 @@ function isBranchPoint(tree, nodeId) {
4732
4763
  }
4733
4764
 
4734
4765
  // src/components/chat/ChatInput.tsx
4735
- var ChatInput = import_react59.default.forwardRef(
4766
+ var ChatInput = import_react60.default.forwardRef(
4736
4767
  ({
4737
4768
  position = "bottom",
4738
4769
  placeholder = "Send a message...",
@@ -4749,13 +4780,13 @@ var ChatInput = import_react59.default.forwardRef(
4749
4780
  className,
4750
4781
  ...rest
4751
4782
  }, ref) => {
4752
- const [value, setValue] = (0, import_react59.useState)("");
4753
- const [localAttachments, setLocalAttachments] = (0, import_react59.useState)([]);
4754
- const [isDragOver, setIsDragOver] = (0, import_react59.useState)(false);
4755
- const textareaRef = (0, import_react59.useRef)(null);
4756
- const fileInputRef = (0, import_react59.useRef)(null);
4783
+ const [value, setValue] = (0, import_react60.useState)("");
4784
+ const [localAttachments, setLocalAttachments] = (0, import_react60.useState)([]);
4785
+ const [isDragOver, setIsDragOver] = (0, import_react60.useState)(false);
4786
+ const textareaRef = (0, import_react60.useRef)(null);
4787
+ const fileInputRef = (0, import_react60.useRef)(null);
4757
4788
  const attachments = controlledAttachments ?? localAttachments;
4758
- const setAttachments = (0, import_react59.useCallback)(
4789
+ const setAttachments = (0, import_react60.useCallback)(
4759
4790
  (newAttachments) => {
4760
4791
  if (onAttachmentsChange) {
4761
4792
  if (typeof newAttachments === "function") {
@@ -4769,7 +4800,7 @@ var ChatInput = import_react59.default.forwardRef(
4769
4800
  },
4770
4801
  [attachments, onAttachmentsChange]
4771
4802
  );
4772
- const handleSubmit = (0, import_react59.useCallback)(() => {
4803
+ const handleSubmit = (0, import_react60.useCallback)(() => {
4773
4804
  const trimmed = value.trim();
4774
4805
  if (!trimmed || disabled || isStreaming) {
4775
4806
  return;
@@ -4781,7 +4812,7 @@ var ChatInput = import_react59.default.forwardRef(
4781
4812
  textareaRef.current.style.height = "auto";
4782
4813
  }
4783
4814
  }, [value, disabled, isStreaming, onSubmit, attachments, setAttachments]);
4784
- const handleKeyDown = (0, import_react59.useCallback)(
4815
+ const handleKeyDown = (0, import_react60.useCallback)(
4785
4816
  (e) => {
4786
4817
  if (e.key === "Enter" && !e.shiftKey) {
4787
4818
  e.preventDefault();
@@ -4790,18 +4821,18 @@ var ChatInput = import_react59.default.forwardRef(
4790
4821
  },
4791
4822
  [handleSubmit]
4792
4823
  );
4793
- const handleChange = (0, import_react59.useCallback)((e) => {
4824
+ const handleChange = (0, import_react60.useCallback)((e) => {
4794
4825
  setValue(e.target.value);
4795
4826
  const textarea = e.target;
4796
4827
  textarea.style.height = "auto";
4797
4828
  textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`;
4798
4829
  }, []);
4799
- (0, import_react59.useEffect)(() => {
4830
+ (0, import_react60.useEffect)(() => {
4800
4831
  if (!disabled && !isStreaming && textareaRef.current) {
4801
4832
  textareaRef.current.focus();
4802
4833
  }
4803
4834
  }, [disabled, isStreaming]);
4804
- const addFiles = (0, import_react59.useCallback)(
4835
+ const addFiles = (0, import_react60.useCallback)(
4805
4836
  (files) => {
4806
4837
  const newAttachments = Array.from(files).map((file) => ({
4807
4838
  id: generateId(),
@@ -4813,7 +4844,7 @@ var ChatInput = import_react59.default.forwardRef(
4813
4844
  },
4814
4845
  [setAttachments]
4815
4846
  );
4816
- const handleFileSelect = (0, import_react59.useCallback)(
4847
+ const handleFileSelect = (0, import_react60.useCallback)(
4817
4848
  (e) => {
4818
4849
  const files = e.target.files;
4819
4850
  if (files && files.length > 0) {
@@ -4823,7 +4854,7 @@ var ChatInput = import_react59.default.forwardRef(
4823
4854
  },
4824
4855
  [addFiles]
4825
4856
  );
4826
- const handleRemoveAttachment = (0, import_react59.useCallback)(
4857
+ const handleRemoveAttachment = (0, import_react60.useCallback)(
4827
4858
  (id) => {
4828
4859
  setAttachments((prev) => {
4829
4860
  const attachment = prev.find((a) => a.id === id);
@@ -4835,23 +4866,23 @@ var ChatInput = import_react59.default.forwardRef(
4835
4866
  },
4836
4867
  [setAttachments]
4837
4868
  );
4838
- const handleDragEnter = (0, import_react59.useCallback)((e) => {
4869
+ const handleDragEnter = (0, import_react60.useCallback)((e) => {
4839
4870
  e.preventDefault();
4840
4871
  e.stopPropagation();
4841
4872
  setIsDragOver(true);
4842
4873
  }, []);
4843
- const handleDragLeave = (0, import_react59.useCallback)((e) => {
4874
+ const handleDragLeave = (0, import_react60.useCallback)((e) => {
4844
4875
  e.preventDefault();
4845
4876
  e.stopPropagation();
4846
4877
  if (!e.currentTarget.contains(e.relatedTarget)) {
4847
4878
  setIsDragOver(false);
4848
4879
  }
4849
4880
  }, []);
4850
- const handleDragOver = (0, import_react59.useCallback)((e) => {
4881
+ const handleDragOver = (0, import_react60.useCallback)((e) => {
4851
4882
  e.preventDefault();
4852
4883
  e.stopPropagation();
4853
4884
  }, []);
4854
- const handleDrop = (0, import_react59.useCallback)(
4885
+ const handleDrop = (0, import_react60.useCallback)(
4855
4886
  (e) => {
4856
4887
  e.preventDefault();
4857
4888
  e.stopPropagation();
@@ -4866,7 +4897,7 @@ var ChatInput = import_react59.default.forwardRef(
4866
4897
  const isCentered = position === "centered";
4867
4898
  const hasAttachments = attachments.length > 0;
4868
4899
  const canSubmit = value.trim() && !disabled && !isStreaming;
4869
- return /* @__PURE__ */ import_react59.default.createElement(
4900
+ return /* @__PURE__ */ import_react60.default.createElement(
4870
4901
  "div",
4871
4902
  {
4872
4903
  ref,
@@ -4878,8 +4909,8 @@ var ChatInput = import_react59.default.forwardRef(
4878
4909
  ),
4879
4910
  ...rest
4880
4911
  },
4881
- isCentered && helperText && /* @__PURE__ */ import_react59.default.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
4882
- /* @__PURE__ */ import_react59.default.createElement(
4912
+ isCentered && helperText && /* @__PURE__ */ import_react60.default.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
4913
+ /* @__PURE__ */ import_react60.default.createElement(
4883
4914
  "div",
4884
4915
  {
4885
4916
  className: cx(
@@ -4894,7 +4925,7 @@ var ChatInput = import_react59.default.forwardRef(
4894
4925
  onDragOver: showAttachmentButton ? handleDragOver : void 0,
4895
4926
  onDrop: showAttachmentButton ? handleDrop : void 0
4896
4927
  },
4897
- hasAttachments && /* @__PURE__ */ import_react59.default.createElement("div", { className: "px-3 pt-3 pb-1" }, /* @__PURE__ */ import_react59.default.createElement(
4928
+ hasAttachments && /* @__PURE__ */ import_react60.default.createElement("div", { className: "px-3 pt-3 pb-1" }, /* @__PURE__ */ import_react60.default.createElement(
4898
4929
  AttachmentPreview,
4899
4930
  {
4900
4931
  attachments,
@@ -4902,14 +4933,14 @@ var ChatInput = import_react59.default.forwardRef(
4902
4933
  removable: !isStreaming
4903
4934
  }
4904
4935
  )),
4905
- isDragOver && /* @__PURE__ */ import_react59.default.createElement(
4936
+ isDragOver && /* @__PURE__ */ import_react60.default.createElement(
4906
4937
  "div",
4907
4938
  {
4908
4939
  className: "absolute inset-0 bg-gold/10 flex items-center justify-center z-10 pointer-events-none"
4909
4940
  },
4910
- /* @__PURE__ */ import_react59.default.createElement("span", { className: "text-gold text-sm font-medium" }, "Drop files here")
4941
+ /* @__PURE__ */ import_react60.default.createElement("span", { className: "text-gold text-sm font-medium" }, "Drop files here")
4911
4942
  ),
4912
- /* @__PURE__ */ import_react59.default.createElement("div", { className: "flex items-end" }, showAttachmentButton && /* @__PURE__ */ import_react59.default.createElement(import_react59.default.Fragment, null, /* @__PURE__ */ import_react59.default.createElement(
4943
+ /* @__PURE__ */ import_react60.default.createElement("div", { className: "flex items-end" }, showAttachmentButton && /* @__PURE__ */ import_react60.default.createElement(import_react60.default.Fragment, null, /* @__PURE__ */ import_react60.default.createElement(
4913
4944
  "button",
4914
4945
  {
4915
4946
  type: "button",
@@ -4921,8 +4952,8 @@ var ChatInput = import_react59.default.forwardRef(
4921
4952
  ),
4922
4953
  "aria-label": "Attach file"
4923
4954
  },
4924
- /* @__PURE__ */ import_react59.default.createElement(import_lucide_react11.Paperclip, { className: "w-5 h-5" })
4925
- ), /* @__PURE__ */ import_react59.default.createElement(
4955
+ /* @__PURE__ */ import_react60.default.createElement(import_lucide_react11.Paperclip, { className: "w-5 h-5" })
4956
+ ), /* @__PURE__ */ import_react60.default.createElement(
4926
4957
  "input",
4927
4958
  {
4928
4959
  ref: fileInputRef,
@@ -4933,7 +4964,7 @@ var ChatInput = import_react59.default.forwardRef(
4933
4964
  className: "hidden",
4934
4965
  "aria-hidden": "true"
4935
4966
  }
4936
- )), /* @__PURE__ */ import_react59.default.createElement(
4967
+ )), /* @__PURE__ */ import_react60.default.createElement(
4937
4968
  "textarea",
4938
4969
  {
4939
4970
  ref: textareaRef,
@@ -4951,7 +4982,7 @@ var ChatInput = import_react59.default.forwardRef(
4951
4982
  ),
4952
4983
  style: { maxHeight: 200 }
4953
4984
  }
4954
- ), isStreaming ? /* @__PURE__ */ import_react59.default.createElement(
4985
+ ), isStreaming ? /* @__PURE__ */ import_react60.default.createElement(
4955
4986
  "button",
4956
4987
  {
4957
4988
  type: "button",
@@ -4962,8 +4993,8 @@ var ChatInput = import_react59.default.forwardRef(
4962
4993
  ),
4963
4994
  "aria-label": "Stop generation"
4964
4995
  },
4965
- /* @__PURE__ */ import_react59.default.createElement(import_lucide_react11.Square, { className: "w-5 h-5 fill-current" })
4966
- ) : /* @__PURE__ */ import_react59.default.createElement(
4996
+ /* @__PURE__ */ import_react60.default.createElement(import_lucide_react11.Square, { className: "w-5 h-5 fill-current" })
4997
+ ) : /* @__PURE__ */ import_react60.default.createElement(
4967
4998
  "button",
4968
4999
  {
4969
5000
  type: "button",
@@ -4976,7 +5007,7 @@ var ChatInput = import_react59.default.forwardRef(
4976
5007
  ),
4977
5008
  "aria-label": "Send message"
4978
5009
  },
4979
- /* @__PURE__ */ import_react59.default.createElement(import_lucide_react11.Send, { className: "w-5 h-5" })
5010
+ /* @__PURE__ */ import_react60.default.createElement(import_lucide_react11.Send, { className: "w-5 h-5" })
4980
5011
  ))
4981
5012
  )
4982
5013
  );
@@ -4985,9 +5016,9 @@ var ChatInput = import_react59.default.forwardRef(
4985
5016
  ChatInput.displayName = "ChatInput";
4986
5017
 
4987
5018
  // src/components/chat/ConversationSidebar.tsx
4988
- var import_react60 = __toESM(require("react"));
5019
+ var import_react61 = __toESM(require("react"));
4989
5020
  function HistoryIcon2({ className }) {
4990
- return /* @__PURE__ */ import_react60.default.createElement(
5021
+ return /* @__PURE__ */ import_react61.default.createElement(
4991
5022
  "svg",
4992
5023
  {
4993
5024
  xmlns: "http://www.w3.org/2000/svg",
@@ -4995,7 +5026,7 @@ function HistoryIcon2({ className }) {
4995
5026
  fill: "currentColor",
4996
5027
  className
4997
5028
  },
4998
- /* @__PURE__ */ import_react60.default.createElement(
5029
+ /* @__PURE__ */ import_react61.default.createElement(
4999
5030
  "path",
5000
5031
  {
5001
5032
  fillRule: "evenodd",
@@ -5006,7 +5037,7 @@ function HistoryIcon2({ className }) {
5006
5037
  );
5007
5038
  }
5008
5039
  function ChevronLeftIcon3({ className }) {
5009
- return /* @__PURE__ */ import_react60.default.createElement(
5040
+ return /* @__PURE__ */ import_react61.default.createElement(
5010
5041
  "svg",
5011
5042
  {
5012
5043
  xmlns: "http://www.w3.org/2000/svg",
@@ -5014,7 +5045,7 @@ function ChevronLeftIcon3({ className }) {
5014
5045
  fill: "currentColor",
5015
5046
  className
5016
5047
  },
5017
- /* @__PURE__ */ import_react60.default.createElement(
5048
+ /* @__PURE__ */ import_react61.default.createElement(
5018
5049
  "path",
5019
5050
  {
5020
5051
  fillRule: "evenodd",
@@ -5024,7 +5055,7 @@ function ChevronLeftIcon3({ className }) {
5024
5055
  )
5025
5056
  );
5026
5057
  }
5027
- var ConversationSidebar = import_react60.default.forwardRef(
5058
+ var ConversationSidebar = import_react61.default.forwardRef(
5028
5059
  ({
5029
5060
  conversations,
5030
5061
  isCollapsed = false,
@@ -5037,7 +5068,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5037
5068
  ...rest
5038
5069
  }, ref) => {
5039
5070
  if (isCollapsed) {
5040
- return /* @__PURE__ */ import_react60.default.createElement(
5071
+ return /* @__PURE__ */ import_react61.default.createElement(
5041
5072
  "div",
5042
5073
  {
5043
5074
  ref,
@@ -5048,7 +5079,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5048
5079
  ),
5049
5080
  ...rest
5050
5081
  },
5051
- /* @__PURE__ */ import_react60.default.createElement(
5082
+ /* @__PURE__ */ import_react61.default.createElement(
5052
5083
  "button",
5053
5084
  {
5054
5085
  onClick: onToggleCollapse,
@@ -5059,11 +5090,11 @@ var ConversationSidebar = import_react60.default.forwardRef(
5059
5090
  ),
5060
5091
  "aria-label": "Expand sidebar"
5061
5092
  },
5062
- /* @__PURE__ */ import_react60.default.createElement(HistoryIcon2, { className: "w-5 h-5" })
5093
+ /* @__PURE__ */ import_react61.default.createElement(HistoryIcon2, { className: "w-5 h-5" })
5063
5094
  )
5064
5095
  );
5065
5096
  }
5066
- return /* @__PURE__ */ import_react60.default.createElement(
5097
+ return /* @__PURE__ */ import_react61.default.createElement(
5067
5098
  "div",
5068
5099
  {
5069
5100
  ref,
@@ -5077,7 +5108,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5077
5108
  style: width ? { width } : void 0,
5078
5109
  ...rest
5079
5110
  },
5080
- /* @__PURE__ */ import_react60.default.createElement(
5111
+ /* @__PURE__ */ import_react61.default.createElement(
5081
5112
  "div",
5082
5113
  {
5083
5114
  onMouseDown: onResizeStart,
@@ -5090,7 +5121,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5090
5121
  )
5091
5122
  }
5092
5123
  ),
5093
- /* @__PURE__ */ import_react60.default.createElement("div", { className: "p-3 border-b border-ash/40 flex-shrink-0 flex items-center gap-2" }, /* @__PURE__ */ import_react60.default.createElement(
5124
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "p-3 border-b border-ash/40 flex-shrink-0 flex items-center gap-2" }, /* @__PURE__ */ import_react61.default.createElement(
5094
5125
  "button",
5095
5126
  {
5096
5127
  onClick: onToggleCollapse,
@@ -5101,8 +5132,8 @@ var ConversationSidebar = import_react60.default.forwardRef(
5101
5132
  ),
5102
5133
  "aria-label": "Collapse sidebar"
5103
5134
  },
5104
- /* @__PURE__ */ import_react60.default.createElement(ChevronLeftIcon3, { className: "w-5 h-5" })
5105
- ), /* @__PURE__ */ import_react60.default.createElement(
5135
+ /* @__PURE__ */ import_react61.default.createElement(ChevronLeftIcon3, { className: "w-5 h-5" })
5136
+ ), /* @__PURE__ */ import_react61.default.createElement(
5106
5137
  "button",
5107
5138
  {
5108
5139
  onClick: onNewChat,
@@ -5114,7 +5145,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5114
5145
  "transition-colors duration-200"
5115
5146
  )
5116
5147
  },
5117
- /* @__PURE__ */ import_react60.default.createElement(
5148
+ /* @__PURE__ */ import_react61.default.createElement(
5118
5149
  "svg",
5119
5150
  {
5120
5151
  xmlns: "http://www.w3.org/2000/svg",
@@ -5122,16 +5153,16 @@ var ConversationSidebar = import_react60.default.forwardRef(
5122
5153
  fill: "currentColor",
5123
5154
  className: "w-4 h-4"
5124
5155
  },
5125
- /* @__PURE__ */ import_react60.default.createElement(
5156
+ /* @__PURE__ */ import_react61.default.createElement(
5126
5157
  "path",
5127
5158
  {
5128
5159
  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"
5129
5160
  }
5130
5161
  )
5131
5162
  ),
5132
- /* @__PURE__ */ import_react60.default.createElement("span", { className: "text-sm font-medium" }, "New Chat")
5163
+ /* @__PURE__ */ import_react61.default.createElement("span", { className: "text-sm font-medium" }, "New Chat")
5133
5164
  )),
5134
- /* @__PURE__ */ import_react60.default.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ import_react60.default.createElement("p", { className: "px-4 py-2 text-sm text-silver/60" }, "No conversations yet") : /* @__PURE__ */ import_react60.default.createElement("div", { className: "space-y-1 px-2" }, conversations.map((conversation) => /* @__PURE__ */ import_react60.default.createElement(
5165
+ /* @__PURE__ */ import_react61.default.createElement("div", { className: "flex-1 overflow-y-auto py-2" }, conversations.length === 0 ? /* @__PURE__ */ import_react61.default.createElement("p", { className: "px-4 py-2 text-sm text-silver/60" }, "No conversations yet") : /* @__PURE__ */ import_react61.default.createElement("div", { className: "space-y-1 px-2" }, conversations.map((conversation) => /* @__PURE__ */ import_react61.default.createElement(
5135
5166
  "button",
5136
5167
  {
5137
5168
  key: conversation.id,
@@ -5142,16 +5173,16 @@ var ConversationSidebar = import_react60.default.forwardRef(
5142
5173
  conversation.isActive ? "bg-ash/40 text-white" : "text-silver hover:bg-ash/20 hover:text-white"
5143
5174
  )
5144
5175
  },
5145
- /* @__PURE__ */ import_react60.default.createElement("p", { className: "text-sm font-medium truncate" }, conversation.title),
5146
- conversation.preview && /* @__PURE__ */ import_react60.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.preview),
5147
- conversation.timestamp && /* @__PURE__ */ import_react60.default.createElement("p", { className: "text-xs text-silver/40 mt-1" }, conversation.timestamp)
5176
+ /* @__PURE__ */ import_react61.default.createElement("p", { className: "text-sm font-medium truncate" }, conversation.title),
5177
+ conversation.preview && /* @__PURE__ */ import_react61.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.preview),
5178
+ conversation.timestamp && /* @__PURE__ */ import_react61.default.createElement("p", { className: "text-xs text-silver/40 mt-1" }, conversation.timestamp)
5148
5179
  ))))
5149
5180
  );
5150
5181
  }
5151
5182
  );
5152
5183
  ConversationSidebar.displayName = "ConversationSidebar";
5153
- var CollapsedSidebarToggle = import_react60.default.forwardRef(({ onExpand, className, ...rest }, ref) => {
5154
- return /* @__PURE__ */ import_react60.default.createElement(
5184
+ var CollapsedSidebarToggle = import_react61.default.forwardRef(({ onExpand, className, ...rest }, ref) => {
5185
+ return /* @__PURE__ */ import_react61.default.createElement(
5155
5186
  "button",
5156
5187
  {
5157
5188
  ref,
@@ -5166,19 +5197,19 @@ var CollapsedSidebarToggle = import_react60.default.forwardRef(({ onExpand, clas
5166
5197
  "aria-label": "Expand sidebar",
5167
5198
  ...rest
5168
5199
  },
5169
- /* @__PURE__ */ import_react60.default.createElement(HistoryIcon2, { className: "w-5 h-5" })
5200
+ /* @__PURE__ */ import_react61.default.createElement(HistoryIcon2, { className: "w-5 h-5" })
5170
5201
  );
5171
5202
  });
5172
5203
  CollapsedSidebarToggle.displayName = "CollapsedSidebarToggle";
5173
5204
 
5174
5205
  // src/components/chat/ArtifactsPanel.tsx
5175
- var import_react68 = __toESM(require("react"));
5206
+ var import_react72 = __toESM(require("react"));
5176
5207
 
5177
5208
  // src/components/ArtifactCard.tsx
5178
- var import_react67 = __toESM(require("react"));
5209
+ var import_react68 = __toESM(require("react"));
5179
5210
 
5180
5211
  // src/components/ImageCard.tsx
5181
- var import_react61 = __toESM(require("react"));
5212
+ var import_react62 = __toESM(require("react"));
5182
5213
  var ASPECT_RATIO_PRESETS = {
5183
5214
  landscape: "3 / 2",
5184
5215
  portrait: "2 / 3",
@@ -5190,7 +5221,7 @@ function resolveAspectRatio(ratio) {
5190
5221
  }
5191
5222
  return ratio.replace("/", " / ");
5192
5223
  }
5193
- var ImageCard = import_react61.default.forwardRef(
5224
+ var ImageCard = import_react62.default.forwardRef(
5194
5225
  ({
5195
5226
  src,
5196
5227
  alt = "",
@@ -5206,7 +5237,7 @@ var ImageCard = import_react61.default.forwardRef(
5206
5237
  loading,
5207
5238
  ...props
5208
5239
  }, ref) => {
5209
- return /* @__PURE__ */ import_react61.default.createElement(
5240
+ return /* @__PURE__ */ import_react62.default.createElement(
5210
5241
  Card,
5211
5242
  {
5212
5243
  ref,
@@ -5214,13 +5245,13 @@ var ImageCard = import_react61.default.forwardRef(
5214
5245
  loading,
5215
5246
  ...props
5216
5247
  },
5217
- /* @__PURE__ */ import_react61.default.createElement(
5248
+ /* @__PURE__ */ import_react62.default.createElement(
5218
5249
  Card.Media,
5219
5250
  {
5220
5251
  className: mediaClassName,
5221
5252
  style: { aspectRatio: resolveAspectRatio(aspectRatio) }
5222
5253
  },
5223
- /* @__PURE__ */ import_react61.default.createElement(import_react61.default.Fragment, null, src && /* @__PURE__ */ import_react61.default.createElement(
5254
+ /* @__PURE__ */ import_react62.default.createElement(import_react62.default.Fragment, null, src && /* @__PURE__ */ import_react62.default.createElement(
5224
5255
  "img",
5225
5256
  {
5226
5257
  src,
@@ -5230,7 +5261,7 @@ var ImageCard = import_react61.default.forwardRef(
5230
5261
  objectFit === "cover" ? "object-cover" : "object-contain"
5231
5262
  )
5232
5263
  }
5233
- ), overlay && /* @__PURE__ */ import_react61.default.createElement(
5264
+ ), overlay && /* @__PURE__ */ import_react62.default.createElement(
5234
5265
  "div",
5235
5266
  {
5236
5267
  className: "absolute inset-0 bg-obsidian/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex items-center justify-center"
@@ -5238,7 +5269,7 @@ var ImageCard = import_react61.default.forwardRef(
5238
5269
  overlay
5239
5270
  ))
5240
5271
  ),
5241
- /* @__PURE__ */ import_react61.default.createElement(
5272
+ /* @__PURE__ */ import_react62.default.createElement(
5242
5273
  Card.Header,
5243
5274
  {
5244
5275
  title,
@@ -5246,14 +5277,14 @@ var ImageCard = import_react61.default.forwardRef(
5246
5277
  className: contentClassName
5247
5278
  }
5248
5279
  ),
5249
- children && /* @__PURE__ */ import_react61.default.createElement(Card.Body, { className: contentClassName }, children)
5280
+ children && /* @__PURE__ */ import_react62.default.createElement(Card.Body, { className: contentClassName }, children)
5250
5281
  );
5251
5282
  }
5252
5283
  );
5253
5284
  ImageCard.displayName = "ImageCard";
5254
5285
 
5255
5286
  // src/components/VideoCard.tsx
5256
- var import_react62 = __toESM(require("react"));
5287
+ var import_react63 = __toESM(require("react"));
5257
5288
  var import_react_player = __toESM(require("react-player"));
5258
5289
  var ASPECT_RATIO_PRESETS2 = {
5259
5290
  video: "16 / 9",
@@ -5266,7 +5297,7 @@ function resolveAspectRatio2(ratio) {
5266
5297
  }
5267
5298
  return ratio.replace("/", " / ");
5268
5299
  }
5269
- var VideoCard = import_react62.default.forwardRef(
5300
+ var VideoCard = import_react63.default.forwardRef(
5270
5301
  ({
5271
5302
  src,
5272
5303
  title,
@@ -5286,7 +5317,7 @@ var VideoCard = import_react62.default.forwardRef(
5286
5317
  loading,
5287
5318
  ...props
5288
5319
  }, ref) => {
5289
- return /* @__PURE__ */ import_react62.default.createElement(
5320
+ return /* @__PURE__ */ import_react63.default.createElement(
5290
5321
  Card,
5291
5322
  {
5292
5323
  ref,
@@ -5294,13 +5325,13 @@ var VideoCard = import_react62.default.forwardRef(
5294
5325
  loading,
5295
5326
  ...props
5296
5327
  },
5297
- /* @__PURE__ */ import_react62.default.createElement(
5328
+ /* @__PURE__ */ import_react63.default.createElement(
5298
5329
  Card.Media,
5299
5330
  {
5300
5331
  className: mediaClassName,
5301
5332
  style: { aspectRatio: resolveAspectRatio2(aspectRatio) }
5302
5333
  },
5303
- src && /* @__PURE__ */ import_react62.default.createElement(
5334
+ src && /* @__PURE__ */ import_react63.default.createElement(
5304
5335
  import_react_player.default,
5305
5336
  {
5306
5337
  src,
@@ -5317,7 +5348,7 @@ var VideoCard = import_react62.default.forwardRef(
5317
5348
  }
5318
5349
  )
5319
5350
  ),
5320
- /* @__PURE__ */ import_react62.default.createElement(
5351
+ /* @__PURE__ */ import_react63.default.createElement(
5321
5352
  Card.Header,
5322
5353
  {
5323
5354
  title,
@@ -5325,17 +5356,17 @@ var VideoCard = import_react62.default.forwardRef(
5325
5356
  className: contentClassName
5326
5357
  }
5327
5358
  ),
5328
- children && /* @__PURE__ */ import_react62.default.createElement(Card.Body, { className: contentClassName }, children)
5359
+ children && /* @__PURE__ */ import_react63.default.createElement(Card.Body, { className: contentClassName }, children)
5329
5360
  );
5330
5361
  }
5331
5362
  );
5332
5363
  VideoCard.displayName = "VideoCard";
5333
5364
 
5334
5365
  // src/components/AudioCard.tsx
5335
- var import_react63 = __toESM(require("react"));
5366
+ var import_react64 = __toESM(require("react"));
5336
5367
  var import_react_player2 = __toESM(require("react-player"));
5337
5368
  var import_lucide_react12 = require("lucide-react");
5338
- var AudioCard = import_react63.default.forwardRef(
5369
+ var AudioCard = import_react64.default.forwardRef(
5339
5370
  ({
5340
5371
  src,
5341
5372
  title,
@@ -5354,7 +5385,7 @@ var AudioCard = import_react63.default.forwardRef(
5354
5385
  loading,
5355
5386
  ...props
5356
5387
  }, ref) => {
5357
- return /* @__PURE__ */ import_react63.default.createElement(
5388
+ return /* @__PURE__ */ import_react64.default.createElement(
5358
5389
  Card,
5359
5390
  {
5360
5391
  ref,
@@ -5362,10 +5393,10 @@ var AudioCard = import_react63.default.forwardRef(
5362
5393
  loading,
5363
5394
  ...props
5364
5395
  },
5365
- /* @__PURE__ */ import_react63.default.createElement(Card.Media, { className: cx(
5396
+ /* @__PURE__ */ import_react64.default.createElement(Card.Media, { className: cx(
5366
5397
  "bg-obsidian py-8 flex flex-col items-center justify-center",
5367
5398
  mediaClassName
5368
- ) }, /* @__PURE__ */ import_react63.default.createElement("div", { className: "mb-4 text-gold" }, /* @__PURE__ */ import_react63.default.createElement(import_lucide_react12.Music, { size: 48 })), src && /* @__PURE__ */ import_react63.default.createElement("div", { className: "w-full px-4" }, /* @__PURE__ */ import_react63.default.createElement(
5399
+ ) }, /* @__PURE__ */ import_react64.default.createElement("div", { className: "mb-4 text-gold" }, /* @__PURE__ */ import_react64.default.createElement(import_lucide_react12.Music, { size: 48 })), src && /* @__PURE__ */ import_react64.default.createElement("div", { className: "w-full px-4" }, /* @__PURE__ */ import_react64.default.createElement(
5369
5400
  import_react_player2.default,
5370
5401
  {
5371
5402
  src,
@@ -5388,7 +5419,7 @@ var AudioCard = import_react63.default.forwardRef(
5388
5419
  ...playerProps
5389
5420
  }
5390
5421
  ))),
5391
- /* @__PURE__ */ import_react63.default.createElement(
5422
+ /* @__PURE__ */ import_react64.default.createElement(
5392
5423
  Card.Header,
5393
5424
  {
5394
5425
  title,
@@ -5396,16 +5427,16 @@ var AudioCard = import_react63.default.forwardRef(
5396
5427
  className: contentClassName
5397
5428
  }
5398
5429
  ),
5399
- children && /* @__PURE__ */ import_react63.default.createElement(Card.Body, { className: contentClassName }, children)
5430
+ children && /* @__PURE__ */ import_react64.default.createElement(Card.Body, { className: contentClassName }, children)
5400
5431
  );
5401
5432
  }
5402
5433
  );
5403
5434
  AudioCard.displayName = "AudioCard";
5404
5435
 
5405
5436
  // src/components/PdfCard.tsx
5406
- var import_react64 = __toESM(require("react"));
5437
+ var import_react65 = __toESM(require("react"));
5407
5438
  var import_lucide_react13 = require("lucide-react");
5408
- var PdfCard = import_react64.default.forwardRef(
5439
+ var PdfCard = import_react65.default.forwardRef(
5409
5440
  ({
5410
5441
  src,
5411
5442
  title,
@@ -5418,7 +5449,7 @@ var PdfCard = import_react64.default.forwardRef(
5418
5449
  loading,
5419
5450
  ...props
5420
5451
  }, ref) => {
5421
- return /* @__PURE__ */ import_react64.default.createElement(
5452
+ return /* @__PURE__ */ import_react65.default.createElement(
5422
5453
  Card,
5423
5454
  {
5424
5455
  ref,
@@ -5426,13 +5457,13 @@ var PdfCard = import_react64.default.forwardRef(
5426
5457
  loading,
5427
5458
  ...props
5428
5459
  },
5429
- /* @__PURE__ */ import_react64.default.createElement(
5460
+ /* @__PURE__ */ import_react65.default.createElement(
5430
5461
  Card.Media,
5431
5462
  {
5432
5463
  className: cx("bg-obsidian", mediaClassName),
5433
5464
  style: { height }
5434
5465
  },
5435
- src && /* @__PURE__ */ import_react64.default.createElement(
5466
+ src && /* @__PURE__ */ import_react65.default.createElement(
5436
5467
  "iframe",
5437
5468
  {
5438
5469
  src: `${src}#view=FitH`,
@@ -5441,23 +5472,23 @@ var PdfCard = import_react64.default.forwardRef(
5441
5472
  }
5442
5473
  )
5443
5474
  ),
5444
- /* @__PURE__ */ import_react64.default.createElement(
5475
+ /* @__PURE__ */ import_react65.default.createElement(
5445
5476
  Card.Header,
5446
5477
  {
5447
5478
  title,
5448
5479
  subtitle,
5449
5480
  className: contentClassName,
5450
- action: /* @__PURE__ */ import_react64.default.createElement("div", { className: "p-2 bg-ash/20 text-gold shrink-0" }, /* @__PURE__ */ import_react64.default.createElement(import_lucide_react13.FileText, { size: 20 }))
5481
+ action: /* @__PURE__ */ import_react65.default.createElement("div", { className: "p-2 bg-ash/20 text-gold shrink-0" }, /* @__PURE__ */ import_react65.default.createElement(import_lucide_react13.FileText, { size: 20 }))
5451
5482
  }
5452
5483
  ),
5453
- children && /* @__PURE__ */ import_react64.default.createElement(Card.Body, { className: contentClassName }, children)
5484
+ children && /* @__PURE__ */ import_react65.default.createElement(Card.Body, { className: contentClassName }, children)
5454
5485
  );
5455
5486
  }
5456
5487
  );
5457
5488
  PdfCard.displayName = "PdfCard";
5458
5489
 
5459
5490
  // src/components/ScriptCard.tsx
5460
- var import_react65 = __toESM(require("react"));
5491
+ var import_react66 = __toESM(require("react"));
5461
5492
  var SCRIPT_ELEMENT_TYPES = {
5462
5493
  SCENE_HEADING: "scene-heading",
5463
5494
  ACTION: "action",
@@ -5471,28 +5502,28 @@ var SCRIPT_ELEMENT_TYPES = {
5471
5502
  function ScriptElementRenderer({ element }) {
5472
5503
  switch (element.type) {
5473
5504
  case "scene-heading":
5474
- return /* @__PURE__ */ import_react65.default.createElement("p", { className: "mt-4 mb-2 font-bold uppercase text-gold text-xs tracking-wide" }, element.content);
5505
+ return /* @__PURE__ */ import_react66.default.createElement("p", { className: "mt-4 mb-2 font-bold uppercase text-gold text-xs tracking-wide" }, element.content);
5475
5506
  case "action":
5476
- return /* @__PURE__ */ import_react65.default.createElement("p", { className: "my-2 text-silver text-xs leading-relaxed" }, element.content);
5507
+ return /* @__PURE__ */ import_react66.default.createElement("p", { className: "my-2 text-silver text-xs leading-relaxed" }, element.content);
5477
5508
  case "character":
5478
- return /* @__PURE__ */ import_react65.default.createElement("p", { className: "mt-4 mb-0.5 ml-8 font-bold text-white text-xs uppercase tracking-wide" }, element.content);
5509
+ return /* @__PURE__ */ import_react66.default.createElement("p", { className: "mt-4 mb-0.5 ml-8 font-bold text-white text-xs uppercase tracking-wide" }, element.content);
5479
5510
  case "parenthetical":
5480
- return /* @__PURE__ */ import_react65.default.createElement("p", { className: "ml-6 text-silver/70 text-xs italic" }, "(", element.content, ")");
5511
+ return /* @__PURE__ */ import_react66.default.createElement("p", { className: "ml-6 text-silver/70 text-xs italic" }, "(", element.content, ")");
5481
5512
  case "dialogue":
5482
- return /* @__PURE__ */ import_react65.default.createElement("p", { className: "ml-4 mr-8 text-silver text-xs leading-relaxed" }, element.content);
5513
+ return /* @__PURE__ */ import_react66.default.createElement("p", { className: "ml-4 mr-8 text-silver text-xs leading-relaxed" }, element.content);
5483
5514
  case "transition":
5484
- return /* @__PURE__ */ import_react65.default.createElement("p", { className: "mt-4 mb-2 text-right font-bold uppercase text-gold/80 text-xs tracking-wide" }, element.content);
5515
+ return /* @__PURE__ */ import_react66.default.createElement("p", { className: "mt-4 mb-2 text-right font-bold uppercase text-gold/80 text-xs tracking-wide" }, element.content);
5485
5516
  case "title":
5486
- return /* @__PURE__ */ import_react65.default.createElement("p", { className: "mt-6 mb-2 text-center font-bold text-gold text-sm" }, element.content);
5517
+ return /* @__PURE__ */ import_react66.default.createElement("p", { className: "mt-6 mb-2 text-center font-bold text-gold text-sm" }, element.content);
5487
5518
  case "subtitle":
5488
- return /* @__PURE__ */ import_react65.default.createElement("p", { className: "text-center italic text-gold/70 text-xs" }, element.content);
5519
+ return /* @__PURE__ */ import_react66.default.createElement("p", { className: "text-center italic text-gold/70 text-xs" }, element.content);
5489
5520
  default:
5490
5521
  return null;
5491
5522
  }
5492
5523
  }
5493
- var ScriptCard = import_react65.default.forwardRef(
5524
+ var ScriptCard = import_react66.default.forwardRef(
5494
5525
  ({ title, subtitle, elements, maxHeight = "16rem", className, style, loading, ...rest }, ref) => {
5495
- return /* @__PURE__ */ import_react65.default.createElement(
5526
+ return /* @__PURE__ */ import_react66.default.createElement(
5496
5527
  Card,
5497
5528
  {
5498
5529
  ref,
@@ -5500,20 +5531,20 @@ var ScriptCard = import_react65.default.forwardRef(
5500
5531
  loading,
5501
5532
  ...rest
5502
5533
  },
5503
- /* @__PURE__ */ import_react65.default.createElement(
5534
+ /* @__PURE__ */ import_react66.default.createElement(
5504
5535
  Card.Header,
5505
5536
  {
5506
5537
  title,
5507
5538
  subtitle
5508
5539
  }
5509
5540
  ),
5510
- /* @__PURE__ */ import_react65.default.createElement(
5541
+ /* @__PURE__ */ import_react66.default.createElement(
5511
5542
  Card.Body,
5512
5543
  {
5513
5544
  className: "font-mono overflow-y-auto",
5514
5545
  style: { maxHeight, ...style }
5515
5546
  },
5516
- elements.map((element, index) => /* @__PURE__ */ import_react65.default.createElement(ScriptElementRenderer, { key: index, element }))
5547
+ elements.map((element, index) => /* @__PURE__ */ import_react66.default.createElement(ScriptElementRenderer, { key: index, element }))
5517
5548
  )
5518
5549
  );
5519
5550
  }
@@ -5521,8 +5552,8 @@ var ScriptCard = import_react65.default.forwardRef(
5521
5552
  ScriptCard.displayName = "ScriptCard";
5522
5553
 
5523
5554
  // src/components/TextCard.tsx
5524
- var import_react66 = __toESM(require("react"));
5525
- var TextCard = import_react66.default.forwardRef(
5555
+ var import_react67 = __toESM(require("react"));
5556
+ var TextCard = import_react67.default.forwardRef(
5526
5557
  ({
5527
5558
  content,
5528
5559
  title,
@@ -5534,7 +5565,7 @@ var TextCard = import_react66.default.forwardRef(
5534
5565
  loading,
5535
5566
  ...props
5536
5567
  }, ref) => {
5537
- return /* @__PURE__ */ import_react66.default.createElement(
5568
+ return /* @__PURE__ */ import_react67.default.createElement(
5538
5569
  Card,
5539
5570
  {
5540
5571
  ref,
@@ -5542,20 +5573,20 @@ var TextCard = import_react66.default.forwardRef(
5542
5573
  loading,
5543
5574
  ...props
5544
5575
  },
5545
- /* @__PURE__ */ import_react66.default.createElement(
5576
+ /* @__PURE__ */ import_react67.default.createElement(
5546
5577
  Card.Header,
5547
5578
  {
5548
5579
  title,
5549
5580
  subtitle
5550
5581
  }
5551
5582
  ),
5552
- /* @__PURE__ */ import_react66.default.createElement(
5583
+ /* @__PURE__ */ import_react67.default.createElement(
5553
5584
  Card.Body,
5554
5585
  {
5555
5586
  className: cx("overflow-y-auto", contentClassName),
5556
5587
  style: { maxHeight }
5557
5588
  },
5558
- /* @__PURE__ */ import_react66.default.createElement(
5589
+ /* @__PURE__ */ import_react67.default.createElement(
5559
5590
  MarkdownContent,
5560
5591
  {
5561
5592
  content,
@@ -5593,7 +5624,7 @@ var ARTIFACT_TYPES = {
5593
5624
  SCRIPT: "SCRIPT",
5594
5625
  PDF: "PDF"
5595
5626
  };
5596
- var ArtifactCard = import_react67.default.forwardRef(
5627
+ var ArtifactCard = import_react68.default.forwardRef(
5597
5628
  ({ artifact, onExpand, loading, className, ...props }, ref) => {
5598
5629
  const derivedLoading = deriveCardSlotLoading(artifact);
5599
5630
  const commonProps = {
@@ -5611,7 +5642,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5611
5642
  const renderContent = () => {
5612
5643
  switch (artifact.type) {
5613
5644
  case "IMAGE":
5614
- return /* @__PURE__ */ import_react67.default.createElement(
5645
+ return /* @__PURE__ */ import_react68.default.createElement(
5615
5646
  ImageCard,
5616
5647
  {
5617
5648
  ...commonProps,
@@ -5621,7 +5652,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5621
5652
  }
5622
5653
  );
5623
5654
  case "VIDEO":
5624
- return /* @__PURE__ */ import_react67.default.createElement(
5655
+ return /* @__PURE__ */ import_react68.default.createElement(
5625
5656
  VideoCard,
5626
5657
  {
5627
5658
  ...commonProps,
@@ -5631,7 +5662,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5631
5662
  }
5632
5663
  );
5633
5664
  case "AUDIO":
5634
- return /* @__PURE__ */ import_react67.default.createElement(
5665
+ return /* @__PURE__ */ import_react68.default.createElement(
5635
5666
  AudioCard,
5636
5667
  {
5637
5668
  ...commonProps,
@@ -5640,7 +5671,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5640
5671
  }
5641
5672
  );
5642
5673
  case "PDF":
5643
- return /* @__PURE__ */ import_react67.default.createElement(
5674
+ return /* @__PURE__ */ import_react68.default.createElement(
5644
5675
  PdfCard,
5645
5676
  {
5646
5677
  ...commonProps,
@@ -5648,7 +5679,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5648
5679
  }
5649
5680
  );
5650
5681
  case "SCRIPT":
5651
- return /* @__PURE__ */ import_react67.default.createElement(
5682
+ return /* @__PURE__ */ import_react68.default.createElement(
5652
5683
  ScriptCard,
5653
5684
  {
5654
5685
  ...commonProps,
@@ -5657,7 +5688,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5657
5688
  }
5658
5689
  );
5659
5690
  case "TEXT":
5660
- return /* @__PURE__ */ import_react67.default.createElement(
5691
+ return /* @__PURE__ */ import_react68.default.createElement(
5661
5692
  TextCard,
5662
5693
  {
5663
5694
  ...commonProps,
@@ -5673,7 +5704,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5673
5704
  }
5674
5705
  };
5675
5706
  const isCardExpandable = !!onExpand && (artifact.type === "IMAGE" || artifact.type === "PDF" || artifact.type === "SCRIPT" || artifact.type === "TEXT");
5676
- return /* @__PURE__ */ import_react67.default.createElement(
5707
+ return /* @__PURE__ */ import_react68.default.createElement(
5677
5708
  "div",
5678
5709
  {
5679
5710
  ref,
@@ -5686,7 +5717,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5686
5717
  onClick: isCardExpandable ? handleExpand : void 0,
5687
5718
  ...props
5688
5719
  },
5689
- onExpand && /* @__PURE__ */ import_react67.default.createElement(
5720
+ onExpand && /* @__PURE__ */ import_react68.default.createElement(
5690
5721
  "button",
5691
5722
  {
5692
5723
  onClick: handleExpand,
@@ -5697,7 +5728,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5697
5728
  ),
5698
5729
  "aria-label": "Expand artifact"
5699
5730
  },
5700
- /* @__PURE__ */ import_react67.default.createElement(ExpandIcon, { className: "w-4 h-4" })
5731
+ /* @__PURE__ */ import_react68.default.createElement(ExpandIcon, { className: "w-4 h-4" })
5701
5732
  ),
5702
5733
  renderContent()
5703
5734
  );
@@ -5705,12 +5736,178 @@ var ArtifactCard = import_react67.default.forwardRef(
5705
5736
  );
5706
5737
  ArtifactCard.displayName = "ArtifactCard";
5707
5738
 
5739
+ // src/components/ArtifactGroup.tsx
5740
+ var import_react69 = __toESM(require("react"));
5741
+ var LAYER_OFFSET = "8px";
5742
+ var LAYER_OFFSET_2X = "16px";
5743
+ var ArtifactGroup = import_react69.default.forwardRef(
5744
+ ({ node, onClick, className, ...props }, ref) => {
5745
+ const children = node.children;
5746
+ const count = children.length;
5747
+ const frontChild = children[0];
5748
+ const prevCountRef = (0, import_react69.useRef)(count);
5749
+ const [badgePing, setBadgePing] = (0, import_react69.useState)(false);
5750
+ (0, import_react69.useEffect)(() => {
5751
+ if (count !== prevCountRef.current) {
5752
+ prevCountRef.current = count;
5753
+ setBadgePing(true);
5754
+ const timer = setTimeout(() => setBadgePing(false), 500);
5755
+ return () => clearTimeout(timer);
5756
+ }
5757
+ }, [count]);
5758
+ const handleClick = () => {
5759
+ if (onClick) {
5760
+ onClick(node);
5761
+ }
5762
+ };
5763
+ const renderFrontContent = () => {
5764
+ if (!frontChild) {
5765
+ return /* @__PURE__ */ import_react69.default.createElement("div", { className: "w-full aspect-video bg-graphite border border-ash/40 flex items-center justify-center" }, /* @__PURE__ */ import_react69.default.createElement("span", { className: "text-silver text-sm" }, "Empty group"));
5766
+ }
5767
+ if (frontChild.type === "ARTIFACT" && frontChild.artifact) {
5768
+ return /* @__PURE__ */ import_react69.default.createElement(ArtifactCard, { artifact: frontChild.artifact, className: "w-full" });
5769
+ }
5770
+ return /* @__PURE__ */ import_react69.default.createElement(
5771
+ "div",
5772
+ {
5773
+ className: "w-full aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
5774
+ },
5775
+ /* @__PURE__ */ import_react69.default.createElement("span", { className: "text-sm text-silver uppercase tracking-wider" }, frontChild.type === "GROUP" ? "Group" : "Variants"),
5776
+ /* @__PURE__ */ import_react69.default.createElement("span", { className: "text-white font-semibold" }, frontChild.label)
5777
+ );
5778
+ };
5779
+ return /* @__PURE__ */ import_react69.default.createElement(
5780
+ "div",
5781
+ {
5782
+ ref,
5783
+ className: cx(
5784
+ "cursor-pointer group",
5785
+ className
5786
+ ),
5787
+ onClick: handleClick,
5788
+ role: "button",
5789
+ tabIndex: 0,
5790
+ onKeyDown: (e) => {
5791
+ if (e.key === "Enter" || e.key === " ") {
5792
+ e.preventDefault();
5793
+ handleClick();
5794
+ }
5795
+ },
5796
+ "aria-label": `${node.label} \u2014 ${count} items`,
5797
+ ...props
5798
+ },
5799
+ /* @__PURE__ */ import_react69.default.createElement(Card, { noPadding: true, className: "p-5" }, /* @__PURE__ */ import_react69.default.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label), /* @__PURE__ */ import_react69.default.createElement("div", { style: { paddingRight: LAYER_OFFSET_2X, paddingBottom: LAYER_OFFSET_2X } }, /* @__PURE__ */ import_react69.default.createElement("div", { className: "relative" }, /* @__PURE__ */ import_react69.default.createElement(
5800
+ "div",
5801
+ {
5802
+ className: "absolute inset-0 bg-charcoal border border-ash/30 pointer-events-none",
5803
+ style: { transform: `translate(${LAYER_OFFSET_2X}, ${LAYER_OFFSET_2X})` },
5804
+ "aria-hidden": "true"
5805
+ }
5806
+ ), /* @__PURE__ */ import_react69.default.createElement(
5807
+ "div",
5808
+ {
5809
+ className: "absolute inset-0 bg-charcoal border border-ash/40 pointer-events-none",
5810
+ style: { transform: `translate(${LAYER_OFFSET}, ${LAYER_OFFSET})` },
5811
+ "aria-hidden": "true"
5812
+ }
5813
+ ), /* @__PURE__ */ import_react69.default.createElement("div", { className: "relative transition-transform duration-200 group-hover:-translate-y-0.5" }, renderFrontContent()), /* @__PURE__ */ import_react69.default.createElement(
5814
+ "div",
5815
+ {
5816
+ 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",
5817
+ style: badgePing ? { animation: "badge-invert 0.6s ease-in-out" } : void 0
5818
+ },
5819
+ count
5820
+ ))))
5821
+ );
5822
+ }
5823
+ );
5824
+ ArtifactGroup.displayName = "ArtifactGroup";
5825
+
5826
+ // src/components/ArtifactVariantStack.tsx
5827
+ var import_react70 = __toESM(require("react"));
5828
+ var ArtifactVariantStack = import_react70.default.forwardRef(
5829
+ ({ node, onExpandArtifact, onGroupClick, className, ...props }, ref) => {
5830
+ const children = node.children;
5831
+ const renderChild = (child) => {
5832
+ if (child.type === "ARTIFACT" && child.artifact) {
5833
+ return /* @__PURE__ */ import_react70.default.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react70.default.createElement(
5834
+ ArtifactCard,
5835
+ {
5836
+ artifact: child.artifact,
5837
+ onExpand: onExpandArtifact,
5838
+ className: "w-full"
5839
+ }
5840
+ ));
5841
+ }
5842
+ if (child.type === "GROUP") {
5843
+ return /* @__PURE__ */ import_react70.default.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react70.default.createElement(ArtifactGroup, { node: child, onClick: onGroupClick }));
5844
+ }
5845
+ return /* @__PURE__ */ import_react70.default.createElement("div", { key: child.id, className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react70.default.createElement(
5846
+ "div",
5847
+ {
5848
+ className: "aspect-video bg-graphite border border-gold/30 flex flex-col items-center justify-center gap-2 p-4"
5849
+ },
5850
+ /* @__PURE__ */ import_react70.default.createElement("span", { className: "text-xs text-silver uppercase tracking-wider" }, "Variants"),
5851
+ /* @__PURE__ */ import_react70.default.createElement("span", { className: "text-sm text-white font-semibold truncate max-w-full" }, child.label)
5852
+ ));
5853
+ };
5854
+ return /* @__PURE__ */ import_react70.default.createElement(
5855
+ Card,
5856
+ {
5857
+ ref,
5858
+ noPadding: true,
5859
+ className: cx("w-full p-5", className),
5860
+ ...props
5861
+ },
5862
+ /* @__PURE__ */ import_react70.default.createElement("h3", { className: "text-lg font-semibold text-white m-0 mb-4" }, node.label),
5863
+ /* @__PURE__ */ import_react70.default.createElement("div", { className: "flex gap-3" }, children.map(renderChild))
5864
+ );
5865
+ }
5866
+ );
5867
+ ArtifactVariantStack.displayName = "ArtifactVariantStack";
5868
+
5869
+ // src/components/chat/hooks/useArtifactTreeNavigation.ts
5870
+ var import_react71 = require("react");
5871
+ function useArtifactTreeNavigation(rootNodes) {
5872
+ const [stack, setStack] = (0, import_react71.useState)([]);
5873
+ const currentNodes = (0, import_react71.useMemo)(() => {
5874
+ if (stack.length === 0) return rootNodes;
5875
+ return stack[stack.length - 1].children;
5876
+ }, [rootNodes, stack]);
5877
+ const breadcrumbs = (0, import_react71.useMemo)(() => {
5878
+ const entries = [{ label: "Project", node: null }];
5879
+ for (const node of stack) {
5880
+ entries.push({ label: node.label, node });
5881
+ }
5882
+ return entries;
5883
+ }, [stack]);
5884
+ const isAtRoot = stack.length === 0;
5885
+ const navigateInto = (0, import_react71.useCallback)((node) => {
5886
+ setStack((prev) => [...prev, node]);
5887
+ }, []);
5888
+ const navigateTo = (0, import_react71.useCallback)((index) => {
5889
+ setStack((prev) => prev.slice(0, index));
5890
+ }, []);
5891
+ const navigateBack = (0, import_react71.useCallback)(() => {
5892
+ setStack((prev) => prev.slice(0, -1));
5893
+ }, []);
5894
+ return {
5895
+ currentNodes,
5896
+ breadcrumbs,
5897
+ isAtRoot,
5898
+ navigateInto,
5899
+ navigateTo,
5900
+ navigateBack
5901
+ };
5902
+ }
5903
+
5708
5904
  // src/components/chat/ArtifactsPanel.tsx
5905
+ var ZOOM_LEVELS = [0.25, 0.5, 0.75, 1];
5709
5906
  function ArtifactModal({
5710
5907
  artifact,
5711
5908
  onClose
5712
5909
  }) {
5713
- (0, import_react68.useEffect)(() => {
5910
+ (0, import_react72.useEffect)(() => {
5714
5911
  const handleKeyDown = (e) => {
5715
5912
  if (e.key === "Escape") {
5716
5913
  onClose();
@@ -5719,46 +5916,46 @@ function ArtifactModal({
5719
5916
  document.addEventListener("keydown", handleKeyDown);
5720
5917
  return () => document.removeEventListener("keydown", handleKeyDown);
5721
5918
  }, [onClose]);
5722
- const handleBackdropClick = (0, import_react68.useCallback)((e) => {
5919
+ const handleBackdropClick = (0, import_react72.useCallback)((e) => {
5723
5920
  if (e.target === e.currentTarget) {
5724
5921
  onClose();
5725
5922
  }
5726
5923
  }, [onClose]);
5727
- return /* @__PURE__ */ import_react68.default.createElement(
5924
+ return /* @__PURE__ */ import_react72.default.createElement(
5728
5925
  "div",
5729
5926
  {
5730
5927
  className: "fixed inset-0 z-50 flex items-center justify-center bg-void/90 backdrop-blur-sm animate-fade-in",
5731
5928
  onClick: handleBackdropClick
5732
5929
  },
5733
- /* @__PURE__ */ import_react68.default.createElement(
5930
+ /* @__PURE__ */ import_react72.default.createElement(
5734
5931
  "div",
5735
5932
  {
5736
5933
  className: "relative w-11/12 h-5/6 max-w-6xl bg-charcoal border border-ash/40 flex flex-col overflow-hidden"
5737
5934
  },
5738
- /* @__PURE__ */ import_react68.default.createElement(
5935
+ /* @__PURE__ */ import_react72.default.createElement(
5739
5936
  "div",
5740
5937
  {
5741
5938
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5742
5939
  },
5743
- /* @__PURE__ */ import_react68.default.createElement("div", null, artifact.title && /* @__PURE__ */ import_react68.default.createElement("h3", { className: "text-sm font-semibold text-white" }, artifact.title), artifact.subtitle && /* @__PURE__ */ import_react68.default.createElement("p", { className: "text-xs text-silver" }, artifact.subtitle)),
5744
- /* @__PURE__ */ import_react68.default.createElement(
5940
+ /* @__PURE__ */ import_react72.default.createElement("div", null, artifact.title && /* @__PURE__ */ import_react72.default.createElement("h3", { className: "text-sm font-semibold text-white" }, artifact.title), artifact.subtitle && /* @__PURE__ */ import_react72.default.createElement("p", { className: "text-xs text-silver" }, artifact.subtitle)),
5941
+ /* @__PURE__ */ import_react72.default.createElement(
5745
5942
  "button",
5746
5943
  {
5747
5944
  onClick: onClose,
5748
5945
  className: "p-2 text-silver hover:text-white hover:bg-ash/20 transition-colors",
5749
5946
  "aria-label": "Close modal"
5750
5947
  },
5751
- /* @__PURE__ */ import_react68.default.createElement(CloseIcon, { className: "w-5 h-5" })
5948
+ /* @__PURE__ */ import_react72.default.createElement(CloseIcon, { className: "w-5 h-5" })
5752
5949
  )
5753
5950
  ),
5754
- /* @__PURE__ */ import_react68.default.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ import_react68.default.createElement(
5951
+ /* @__PURE__ */ import_react72.default.createElement("div", { className: "flex-1 overflow-auto p-4" }, artifact.type === "IMAGE" && /* @__PURE__ */ import_react72.default.createElement(
5755
5952
  "img",
5756
5953
  {
5757
5954
  src: artifact.url,
5758
5955
  alt: artifact.alt || "Artifact image",
5759
5956
  className: "max-w-full max-h-full object-contain mx-auto"
5760
5957
  }
5761
- ), artifact.type === "VIDEO" && /* @__PURE__ */ import_react68.default.createElement(
5958
+ ), artifact.type === "VIDEO" && /* @__PURE__ */ import_react72.default.createElement(
5762
5959
  VideoCard,
5763
5960
  {
5764
5961
  src: artifact.url || "",
@@ -5766,20 +5963,20 @@ function ArtifactModal({
5766
5963
  controls: true,
5767
5964
  className: "max-w-full max-h-full mx-auto"
5768
5965
  }
5769
- ), artifact.type === "AUDIO" && /* @__PURE__ */ import_react68.default.createElement(
5966
+ ), artifact.type === "AUDIO" && /* @__PURE__ */ import_react72.default.createElement(
5770
5967
  AudioCard,
5771
5968
  {
5772
5969
  src: artifact.url || "",
5773
5970
  controls: true,
5774
5971
  className: "max-w-xl mx-auto"
5775
5972
  }
5776
- ), artifact.type === "PDF" && /* @__PURE__ */ import_react68.default.createElement(
5973
+ ), artifact.type === "PDF" && /* @__PURE__ */ import_react72.default.createElement(
5777
5974
  PdfCard,
5778
5975
  {
5779
5976
  src: artifact.url || "",
5780
5977
  className: "h-full border-0"
5781
5978
  }
5782
- ), artifact.type === "TEXT" && /* @__PURE__ */ import_react68.default.createElement(
5979
+ ), artifact.type === "TEXT" && /* @__PURE__ */ import_react72.default.createElement(
5783
5980
  MarkdownContent,
5784
5981
  {
5785
5982
  content: artifact.inlineContent || "",
@@ -5789,7 +5986,7 @@ function ArtifactModal({
5789
5986
  artifact.mimeType === "text/plain" && "whitespace-pre-wrap"
5790
5987
  )
5791
5988
  }
5792
- ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ import_react68.default.createElement(
5989
+ ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ import_react72.default.createElement(
5793
5990
  ScriptCard,
5794
5991
  {
5795
5992
  elements: artifact.scriptElements,
@@ -5800,138 +5997,190 @@ function ArtifactModal({
5800
5997
  )
5801
5998
  );
5802
5999
  }
5803
- function ArtifactRenderer({
5804
- artifact,
6000
+ function NodeRenderer({
6001
+ node,
5805
6002
  loading,
5806
- onExpand
6003
+ onExpandArtifact,
6004
+ onGroupClick
5807
6005
  }) {
5808
- return /* @__PURE__ */ import_react68.default.createElement(
5809
- ArtifactCard,
5810
- {
5811
- artifact,
5812
- loading,
5813
- onExpand
5814
- }
5815
- );
6006
+ if (node.type === "ARTIFACT" && node.artifact) {
6007
+ return /* @__PURE__ */ import_react72.default.createElement(
6008
+ ArtifactCard,
6009
+ {
6010
+ artifact: node.artifact,
6011
+ loading,
6012
+ onExpand: onExpandArtifact
6013
+ }
6014
+ );
6015
+ }
6016
+ if (node.type === "GROUP") {
6017
+ return /* @__PURE__ */ import_react72.default.createElement(ArtifactGroup, { node, onClick: onGroupClick });
6018
+ }
6019
+ if (node.type === "VARIANT_SET") {
6020
+ return /* @__PURE__ */ import_react72.default.createElement(
6021
+ ArtifactVariantStack,
6022
+ {
6023
+ node,
6024
+ onExpandArtifact,
6025
+ onGroupClick
6026
+ }
6027
+ );
6028
+ }
6029
+ return null;
5816
6030
  }
5817
- var ArtifactsPanel = import_react68.default.forwardRef(
6031
+ var ArtifactsPanel = import_react72.default.forwardRef(
5818
6032
  ({
6033
+ nodes,
5819
6034
  artifacts,
5820
- isOpen = false,
5821
- onClose,
5822
6035
  loading,
5823
- width,
5824
- widthPercent,
5825
- onResizeStart,
5826
6036
  className,
5827
6037
  ...rest
5828
6038
  }, ref) => {
5829
- const [expandedArtifact, setExpandedArtifact] = (0, import_react68.useState)(null);
5830
- const columns = widthPercent && widthPercent > 55 ? 3 : widthPercent && widthPercent > 35 ? 2 : 1;
5831
- if (!isOpen) {
5832
- return /* @__PURE__ */ import_react68.default.createElement(
5833
- "div",
5834
- {
5835
- ref,
5836
- className: cx(
5837
- "h-full bg-charcoal/80 border-l border-ash/40 flex flex-col items-center py-3",
5838
- "w-12 shrink-0",
5839
- className
5840
- ),
5841
- ...rest
5842
- },
5843
- /* @__PURE__ */ import_react68.default.createElement(
5844
- "button",
5845
- {
5846
- onClick: onClose,
5847
- className: cx(
5848
- "p-2",
5849
- "text-silver hover:text-white hover:bg-ash/20",
5850
- "transition-colors duration-150",
5851
- "relative"
5852
- ),
5853
- "aria-label": "Expand artifacts panel"
5854
- },
5855
- /* @__PURE__ */ import_react68.default.createElement(LayersIcon, { className: "w-5 h-5" }),
5856
- artifacts.length > 0 && /* @__PURE__ */ import_react68.default.createElement(
5857
- "span",
5858
- {
5859
- 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"
5860
- },
5861
- artifacts.length
5862
- )
5863
- )
5864
- );
5865
- }
5866
- return /* @__PURE__ */ import_react68.default.createElement(import_react68.default.Fragment, null, /* @__PURE__ */ import_react68.default.createElement(
6039
+ const [expandedArtifact, setExpandedArtifact] = (0, import_react72.useState)(null);
6040
+ const [zoomIndex, setZoomIndex] = (0, import_react72.useState)(ZOOM_LEVELS.length - 1);
6041
+ const treeNav = useArtifactTreeNavigation(nodes || []);
6042
+ const isTreeMode = !!nodes && nodes.length > 0;
6043
+ const handleExpandArtifact = (0, import_react72.useCallback)((artifact) => {
6044
+ setExpandedArtifact(artifact);
6045
+ }, []);
6046
+ const handleGroupClick = (0, import_react72.useCallback)((node) => {
6047
+ treeNav.navigateInto(node);
6048
+ }, [treeNav]);
6049
+ const zoomIn = (0, import_react72.useCallback)(() => {
6050
+ setZoomIndex((prev) => Math.min(prev + 1, ZOOM_LEVELS.length - 1));
6051
+ }, []);
6052
+ const zoomOut = (0, import_react72.useCallback)(() => {
6053
+ setZoomIndex((prev) => Math.max(prev - 1, 0));
6054
+ }, []);
6055
+ const currentZoom = ZOOM_LEVELS[zoomIndex];
6056
+ const contentRef = (0, import_react72.useRef)(null);
6057
+ const [contentHeight, setContentHeight] = (0, import_react72.useState)(void 0);
6058
+ (0, import_react72.useEffect)(() => {
6059
+ const el = contentRef.current;
6060
+ if (!el) return;
6061
+ const observer = new ResizeObserver(([entry]) => {
6062
+ setContentHeight(entry.contentRect.height);
6063
+ });
6064
+ observer.observe(el);
6065
+ return () => observer.disconnect();
6066
+ }, []);
6067
+ return /* @__PURE__ */ import_react72.default.createElement(import_react72.default.Fragment, null, /* @__PURE__ */ import_react72.default.createElement(
5867
6068
  "div",
5868
6069
  {
5869
6070
  ref,
5870
6071
  "data-testid": "artifacts-panel",
5871
6072
  className: cx(
5872
- "h-full bg-charcoal/50 border-l border-ash/40 flex flex-col relative",
5873
- !width && "w-96",
5874
- "shrink-0",
6073
+ "h-full flex flex-col relative",
5875
6074
  className
5876
6075
  ),
5877
- style: width ? { width } : void 0,
5878
6076
  ...rest
5879
6077
  },
5880
- /* @__PURE__ */ import_react68.default.createElement(
5881
- "div",
5882
- {
5883
- onMouseDown: onResizeStart,
5884
- "data-testid": "artifacts-resize-handle",
5885
- className: cx(
5886
- "absolute top-0 left-0 w-1 h-full cursor-col-resize z-50",
5887
- "hover:bg-gold/50 transition-colors",
5888
- "after:absolute after:inset-y-0 after:-left-1 after:w-2"
5889
- // Larger hit area
5890
- )
5891
- }
5892
- ),
5893
- /* @__PURE__ */ import_react68.default.createElement(
6078
+ /* @__PURE__ */ import_react72.default.createElement(
5894
6079
  "div",
5895
6080
  {
5896
6081
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5897
6082
  },
5898
- /* @__PURE__ */ import_react68.default.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
5899
- /* @__PURE__ */ import_react68.default.createElement(
5900
- "button",
6083
+ /* @__PURE__ */ import_react72.default.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
6084
+ isTreeMode && /* @__PURE__ */ import_react72.default.createElement(
6085
+ "div",
5901
6086
  {
5902
- onClick: onClose,
5903
- className: cx(
5904
- "p-1.5",
5905
- "text-silver hover:text-white hover:bg-ash/20",
5906
- "transition-colors duration-150"
5907
- ),
5908
- "aria-label": "Collapse artifacts panel"
6087
+ className: "flex items-center gap-0.5",
6088
+ "data-testid": "zoom-controls"
5909
6089
  },
5910
- /* @__PURE__ */ import_react68.default.createElement(ChevronRightIcon, { className: "w-5 h-5" })
6090
+ /* @__PURE__ */ import_react72.default.createElement(
6091
+ "button",
6092
+ {
6093
+ onClick: zoomOut,
6094
+ disabled: zoomIndex === 0,
6095
+ className: cx(
6096
+ "w-6 h-6 flex items-center justify-center text-xs font-bold",
6097
+ "bg-charcoal border border-ash/40",
6098
+ zoomIndex === 0 ? "text-silver/30 cursor-not-allowed" : "text-silver hover:text-gold hover:border-gold/40 transition-colors"
6099
+ ),
6100
+ "aria-label": "Zoom out"
6101
+ },
6102
+ "\u2212"
6103
+ ),
6104
+ /* @__PURE__ */ import_react72.default.createElement("span", { className: "text-xs text-silver w-8 text-center tabular-nums", "data-testid": "zoom-level" }, Math.round(currentZoom * 100), "%"),
6105
+ /* @__PURE__ */ import_react72.default.createElement(
6106
+ "button",
6107
+ {
6108
+ onClick: zoomIn,
6109
+ disabled: zoomIndex === ZOOM_LEVELS.length - 1,
6110
+ className: cx(
6111
+ "w-6 h-6 flex items-center justify-center text-xs font-bold",
6112
+ "bg-charcoal border border-ash/40",
6113
+ zoomIndex === ZOOM_LEVELS.length - 1 ? "text-silver/30 cursor-not-allowed" : "text-silver hover:text-gold hover:border-gold/40 transition-colors"
6114
+ ),
6115
+ "aria-label": "Zoom in"
6116
+ },
6117
+ "+"
6118
+ )
5911
6119
  )
5912
6120
  ),
5913
- /* @__PURE__ */ import_react68.default.createElement(
6121
+ isTreeMode && !treeNav.isAtRoot && /* @__PURE__ */ import_react72.default.createElement(
6122
+ "nav",
6123
+ {
6124
+ className: "flex items-center gap-1 px-4 py-2 border-b border-ash/40 shrink-0 overflow-x-auto text-xs",
6125
+ "aria-label": "Breadcrumb",
6126
+ "data-testid": "breadcrumb-nav"
6127
+ },
6128
+ treeNav.breadcrumbs.map((crumb, i) => {
6129
+ const isLast = i === treeNav.breadcrumbs.length - 1;
6130
+ return /* @__PURE__ */ import_react72.default.createElement("span", { key: i, className: "flex items-center gap-1 shrink-0" }, i > 0 && /* @__PURE__ */ import_react72.default.createElement(ChevronRightIcon, { className: "w-3 h-3 text-silver/50", "aria-hidden": true }), isLast ? /* @__PURE__ */ import_react72.default.createElement("span", { className: "text-gold font-medium" }, crumb.label) : /* @__PURE__ */ import_react72.default.createElement(
6131
+ "button",
6132
+ {
6133
+ onClick: () => treeNav.navigateTo(i),
6134
+ className: "text-silver hover:text-white transition-colors"
6135
+ },
6136
+ crumb.label
6137
+ ));
6138
+ })
6139
+ ),
6140
+ /* @__PURE__ */ import_react72.default.createElement(
5914
6141
  "div",
5915
6142
  {
5916
- "data-testid": "artifacts-grid",
5917
- className: cx(
5918
- "flex-1 overflow-y-auto p-4",
5919
- columns === 1 ? "space-y-4" : "grid gap-4",
5920
- columns === 2 && "grid-cols-2",
5921
- columns === 3 && "grid-cols-3"
5922
- )
6143
+ className: "flex-1 overflow-auto relative",
6144
+ "data-testid": "artifacts-scroll-area"
5923
6145
  },
5924
- artifacts.length === 0 && !loading ? /* @__PURE__ */ import_react68.default.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, "No artifacts to display") : artifacts.map((artifact) => /* @__PURE__ */ import_react68.default.createElement(
5925
- ArtifactRenderer,
6146
+ /* @__PURE__ */ import_react72.default.createElement(
6147
+ "div",
5926
6148
  {
5927
- key: artifact.id,
5928
- artifact,
5929
- loading,
5930
- onExpand: () => setExpandedArtifact(artifact)
5931
- }
5932
- ))
6149
+ style: currentZoom !== 1 && contentHeight !== void 0 ? { height: contentHeight * currentZoom } : void 0
6150
+ },
6151
+ /* @__PURE__ */ import_react72.default.createElement(
6152
+ "div",
6153
+ {
6154
+ ref: contentRef,
6155
+ "data-testid": "artifacts-grid",
6156
+ className: "p-4 space-y-4",
6157
+ style: currentZoom !== 1 ? {
6158
+ transform: `scale(${currentZoom})`,
6159
+ transformOrigin: "top center"
6160
+ } : void 0
6161
+ },
6162
+ isTreeMode ? treeNav.currentNodes.length === 0 ? /* @__PURE__ */ import_react72.default.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, "Empty group") : treeNav.currentNodes.map((node) => /* @__PURE__ */ import_react72.default.createElement(
6163
+ NodeRenderer,
6164
+ {
6165
+ key: node.id,
6166
+ node,
6167
+ loading,
6168
+ onExpandArtifact: handleExpandArtifact,
6169
+ onGroupClick: handleGroupClick
6170
+ }
6171
+ )) : (!artifacts || artifacts.length === 0) && !loading ? /* @__PURE__ */ import_react72.default.createElement("p", { className: "text-xs text-silver/60 text-center py-8" }, "No artifacts to display") : artifacts?.map((artifact) => /* @__PURE__ */ import_react72.default.createElement(
6172
+ ArtifactCard,
6173
+ {
6174
+ key: artifact.id,
6175
+ artifact,
6176
+ loading,
6177
+ onExpand: handleExpandArtifact
6178
+ }
6179
+ ))
6180
+ )
6181
+ )
5933
6182
  )
5934
- ), expandedArtifact && /* @__PURE__ */ import_react68.default.createElement(
6183
+ ), expandedArtifact && /* @__PURE__ */ import_react72.default.createElement(
5935
6184
  ArtifactModal,
5936
6185
  {
5937
6186
  artifact: expandedArtifact,
@@ -5941,8 +6190,8 @@ var ArtifactsPanel = import_react68.default.forwardRef(
5941
6190
  }
5942
6191
  );
5943
6192
  ArtifactsPanel.displayName = "ArtifactsPanel";
5944
- var ArtifactsPanelToggle = import_react68.default.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
5945
- return /* @__PURE__ */ import_react68.default.createElement(
6193
+ var ArtifactsPanelToggle = import_react72.default.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
6194
+ return /* @__PURE__ */ import_react72.default.createElement(
5946
6195
  "button",
5947
6196
  {
5948
6197
  ref,
@@ -5959,11 +6208,27 @@ var ArtifactsPanelToggle = import_react68.default.forwardRef(({ artifactCount =
5959
6208
  "aria-label": "Expand artifacts panel",
5960
6209
  ...rest
5961
6210
  },
5962
- /* @__PURE__ */ import_react68.default.createElement(LayersIcon, { className: "w-5 h-5" }),
5963
- artifactCount > 0 && /* @__PURE__ */ import_react68.default.createElement(
6211
+ /* @__PURE__ */ import_react72.default.createElement(
6212
+ "svg",
6213
+ {
6214
+ xmlns: "http://www.w3.org/2000/svg",
6215
+ viewBox: "0 0 20 20",
6216
+ fill: "currentColor",
6217
+ className: "w-5 h-5"
6218
+ },
6219
+ /* @__PURE__ */ import_react72.default.createElement(
6220
+ "path",
6221
+ {
6222
+ fillRule: "evenodd",
6223
+ 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",
6224
+ clipRule: "evenodd"
6225
+ }
6226
+ )
6227
+ ),
6228
+ artifactCount > 0 && /* @__PURE__ */ import_react72.default.createElement(
5964
6229
  "span",
5965
6230
  {
5966
- 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"
6231
+ className: "absolute -top-1 -right-1 w-4 h-4 bg-gold text-obsidian text-xs font-medium flex items-center justify-center"
5967
6232
  },
5968
6233
  artifactCount
5969
6234
  )
@@ -5972,7 +6237,7 @@ var ArtifactsPanelToggle = import_react68.default.forwardRef(({ artifactCount =
5972
6237
  ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
5973
6238
 
5974
6239
  // src/components/chat/TodosList.tsx
5975
- var import_react69 = __toESM(require("react"));
6240
+ var import_react73 = __toESM(require("react"));
5976
6241
  var TASK_STATUSES = {
5977
6242
  PENDING: "pending",
5978
6243
  IN_PROGRESS: "in_progress",
@@ -5983,16 +6248,16 @@ var TASK_STATUSES = {
5983
6248
  function TaskIcon({ status }) {
5984
6249
  switch (status) {
5985
6250
  case "done":
5986
- return /* @__PURE__ */ import_react69.default.createElement(CheckSquareIcon, null);
6251
+ return /* @__PURE__ */ import_react73.default.createElement(CheckSquareIcon, null);
5987
6252
  case "in_progress":
5988
- return /* @__PURE__ */ import_react69.default.createElement(SquareLoaderIcon, null);
6253
+ return /* @__PURE__ */ import_react73.default.createElement(SquareLoaderIcon, null);
5989
6254
  case "cancelled":
5990
- return /* @__PURE__ */ import_react69.default.createElement(CrossSquareIcon, { variant: "cancelled" });
6255
+ return /* @__PURE__ */ import_react73.default.createElement(CrossSquareIcon, { variant: "cancelled" });
5991
6256
  case "failed":
5992
- return /* @__PURE__ */ import_react69.default.createElement(CrossSquareIcon, { variant: "failed" });
6257
+ return /* @__PURE__ */ import_react73.default.createElement(CrossSquareIcon, { variant: "failed" });
5993
6258
  case "pending":
5994
6259
  default:
5995
- return /* @__PURE__ */ import_react69.default.createElement(EmptySquareIcon, null);
6260
+ return /* @__PURE__ */ import_react73.default.createElement(EmptySquareIcon, null);
5996
6261
  }
5997
6262
  }
5998
6263
  function sortTasks(tasks) {
@@ -6012,7 +6277,7 @@ function TaskItem({ task, depth = 0 }) {
6012
6277
  const isSubtle = task.status === "cancelled" || task.status === "failed";
6013
6278
  const showSubtasks = (task.status === "in_progress" || task.status === "done") && task.subtasks && task.subtasks.length > 0;
6014
6279
  const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
6015
- return /* @__PURE__ */ import_react69.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react69.default.createElement(
6280
+ return /* @__PURE__ */ import_react73.default.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ import_react73.default.createElement(
6016
6281
  "div",
6017
6282
  {
6018
6283
  className: cx(
@@ -6020,8 +6285,8 @@ function TaskItem({ task, depth = 0 }) {
6020
6285
  depth > 0 && "pl-6"
6021
6286
  )
6022
6287
  },
6023
- /* @__PURE__ */ import_react69.default.createElement(TaskIcon, { status: task.status }),
6024
- /* @__PURE__ */ import_react69.default.createElement(
6288
+ /* @__PURE__ */ import_react73.default.createElement(TaskIcon, { status: task.status }),
6289
+ /* @__PURE__ */ import_react73.default.createElement(
6025
6290
  "span",
6026
6291
  {
6027
6292
  className: cx(
@@ -6033,14 +6298,14 @@ function TaskItem({ task, depth = 0 }) {
6033
6298
  )
6034
6299
  },
6035
6300
  task.label,
6036
- task.status === "cancelled" && /* @__PURE__ */ import_react69.default.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
6037
- task.status === "failed" && /* @__PURE__ */ import_react69.default.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
6301
+ task.status === "cancelled" && /* @__PURE__ */ import_react73.default.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
6302
+ task.status === "failed" && /* @__PURE__ */ import_react73.default.createElement("span", { className: "text-error/60 ml-1" }, "(failed)")
6038
6303
  )
6039
- ), showSubtasks && /* @__PURE__ */ import_react69.default.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ import_react69.default.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
6304
+ ), showSubtasks && /* @__PURE__ */ import_react73.default.createElement("div", { className: "flex flex-col" }, sortedSubtasks.map((subtask) => /* @__PURE__ */ import_react73.default.createElement(TaskItem, { key: subtask.id, task: subtask, depth: depth + 1 }))));
6040
6305
  }
6041
- var TodosList = import_react69.default.forwardRef(
6306
+ var TodosList = import_react73.default.forwardRef(
6042
6307
  ({ tasks, title = "Tasks", className, ...rest }, ref) => {
6043
- const sortedTasks = (0, import_react69.useMemo)(() => sortTasks(tasks), [tasks]);
6308
+ const sortedTasks = (0, import_react73.useMemo)(() => sortTasks(tasks), [tasks]);
6044
6309
  const countCompleted = (taskList) => {
6045
6310
  let count = 0;
6046
6311
  for (const task of taskList) {
@@ -6065,40 +6330,204 @@ var TodosList = import_react69.default.forwardRef(
6065
6330
  if (tasks.length === 0) {
6066
6331
  return null;
6067
6332
  }
6068
- return /* @__PURE__ */ import_react69.default.createElement(
6333
+ return /* @__PURE__ */ import_react73.default.createElement(
6069
6334
  "div",
6070
6335
  {
6071
6336
  ref,
6072
6337
  className: cx(
6073
- "flex flex-col bg-charcoal/30 border-l border-ash/40",
6338
+ "flex flex-col h-full",
6074
6339
  "overflow-hidden",
6075
6340
  className
6076
6341
  ),
6077
- style: { maxHeight: "25vh" },
6078
6342
  ...rest
6079
6343
  },
6080
- /* @__PURE__ */ import_react69.default.createElement(
6344
+ /* @__PURE__ */ import_react73.default.createElement(
6081
6345
  "div",
6082
6346
  {
6083
6347
  className: "flex items-center justify-between px-4 py-2 border-b border-ash/40 flex-shrink-0"
6084
6348
  },
6085
- /* @__PURE__ */ import_react69.default.createElement("h4", { className: "text-xs font-medium text-white" }, title),
6086
- /* @__PURE__ */ import_react69.default.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
6349
+ /* @__PURE__ */ import_react73.default.createElement("h4", { className: "text-xs font-medium text-white" }, title),
6350
+ /* @__PURE__ */ import_react73.default.createElement("span", { className: "text-xs text-silver/60" }, countCompleted(tasks), "/", countTotal(tasks))
6087
6351
  ),
6088
- /* @__PURE__ */ import_react69.default.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ import_react69.default.createElement(TaskItem, { key: task.id, task })))
6352
+ /* @__PURE__ */ import_react73.default.createElement("div", { className: "flex-1 overflow-y-auto px-4 py-2" }, sortedTasks.map((task) => /* @__PURE__ */ import_react73.default.createElement(TaskItem, { key: task.id, task })))
6089
6353
  );
6090
6354
  }
6091
6355
  );
6092
6356
  TodosList.displayName = "TodosList";
6357
+ function areAllTasksSettled(tasks) {
6358
+ return tasks.every((t) => {
6359
+ const settled = t.status === "done" || t.status === "cancelled" || t.status === "failed";
6360
+ if (!settled) return false;
6361
+ if (t.subtasks && t.subtasks.length > 0) return areAllTasksSettled(t.subtasks);
6362
+ return true;
6363
+ });
6364
+ }
6365
+
6366
+ // src/components/chat/ToolSidebar.tsx
6367
+ var import_react74 = __toESM(require("react"));
6368
+ var ToolSidebar = import_react74.default.forwardRef(
6369
+ ({ tools, activeTools, onToggleTool, className, ...rest }, ref) => {
6370
+ const topTools = tools.filter((t) => t.group === "top");
6371
+ const bottomTools = tools.filter((t) => t.group === "bottom");
6372
+ const isActive = (toolId) => {
6373
+ const tool = tools.find((t) => t.id === toolId);
6374
+ if (!tool) return false;
6375
+ return activeTools[tool.group] === toolId;
6376
+ };
6377
+ const renderButton = (tool) => {
6378
+ const active = isActive(tool.id);
6379
+ return /* @__PURE__ */ import_react74.default.createElement(
6380
+ "button",
6381
+ {
6382
+ key: tool.id,
6383
+ onClick: () => onToggleTool(tool.id),
6384
+ className: cx(
6385
+ "w-8 h-8 flex items-center justify-center transition-colors duration-150",
6386
+ active ? "bg-gold/15 text-gold border border-gold/30" : "text-silver hover:text-white hover:bg-ash/20"
6387
+ ),
6388
+ "aria-label": tool.label,
6389
+ "aria-pressed": active
6390
+ },
6391
+ /* @__PURE__ */ import_react74.default.createElement("span", { className: "w-4 h-4 block" }, tool.icon)
6392
+ );
6393
+ };
6394
+ return /* @__PURE__ */ import_react74.default.createElement(
6395
+ "div",
6396
+ {
6397
+ ref,
6398
+ className: cx(
6399
+ "h-full w-9 bg-charcoal/80 border-l border-ash/40 flex flex-col items-center shrink-0 py-2",
6400
+ className
6401
+ ),
6402
+ ...rest
6403
+ },
6404
+ /* @__PURE__ */ import_react74.default.createElement("div", { className: "flex flex-col items-center gap-1" }, topTools.map(renderButton)),
6405
+ /* @__PURE__ */ import_react74.default.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ import_react74.default.createElement("div", { className: "w-5 border-t border-ash/30" })),
6406
+ /* @__PURE__ */ import_react74.default.createElement("div", { className: "flex flex-col items-center gap-1" }, bottomTools.map(renderButton))
6407
+ );
6408
+ }
6409
+ );
6410
+ ToolSidebar.displayName = "ToolSidebar";
6411
+
6412
+ // src/components/chat/ToolPanelContainer.tsx
6413
+ var import_react75 = __toESM(require("react"));
6414
+ var ToolPanelContainer = import_react75.default.forwardRef(
6415
+ ({ topContent, bottomContent, width, onResizeStart, className, ...rest }, ref) => {
6416
+ const [topPercent, setTopPercent] = (0, import_react75.useState)(60);
6417
+ const [isResizingHeight, setIsResizingHeight] = (0, import_react75.useState)(false);
6418
+ const containerRef = (0, import_react75.useRef)(null);
6419
+ const lastY = (0, import_react75.useRef)(null);
6420
+ const hasBoth = topContent !== null && bottomContent !== null;
6421
+ const startHeightResize = (0, import_react75.useCallback)((e) => {
6422
+ e.preventDefault();
6423
+ setIsResizingHeight(true);
6424
+ lastY.current = e.clientY;
6425
+ }, []);
6426
+ const stopHeightResize = (0, import_react75.useCallback)(() => {
6427
+ setIsResizingHeight(false);
6428
+ lastY.current = null;
6429
+ }, []);
6430
+ const resizeHeight = (0, import_react75.useCallback)(
6431
+ (e) => {
6432
+ if (!isResizingHeight || lastY.current === null || !containerRef.current) return;
6433
+ const containerHeight = containerRef.current.getBoundingClientRect().height;
6434
+ if (containerHeight === 0) return;
6435
+ const deltaY = e.clientY - lastY.current;
6436
+ const deltaPercent = deltaY / containerHeight * 100;
6437
+ setTopPercent((prev) => {
6438
+ const next = prev + deltaPercent;
6439
+ return Math.min(Math.max(next, 20), 80);
6440
+ });
6441
+ lastY.current = e.clientY;
6442
+ },
6443
+ [isResizingHeight]
6444
+ );
6445
+ (0, import_react75.useEffect)(() => {
6446
+ if (isResizingHeight) {
6447
+ window.addEventListener("mousemove", resizeHeight);
6448
+ window.addEventListener("mouseup", stopHeightResize);
6449
+ document.body.style.cursor = "row-resize";
6450
+ document.body.style.userSelect = "none";
6451
+ } else {
6452
+ window.removeEventListener("mousemove", resizeHeight);
6453
+ window.removeEventListener("mouseup", stopHeightResize);
6454
+ document.body.style.cursor = "";
6455
+ document.body.style.userSelect = "";
6456
+ }
6457
+ return () => {
6458
+ window.removeEventListener("mousemove", resizeHeight);
6459
+ window.removeEventListener("mouseup", stopHeightResize);
6460
+ document.body.style.cursor = "";
6461
+ document.body.style.userSelect = "";
6462
+ };
6463
+ }, [isResizingHeight, resizeHeight, stopHeightResize]);
6464
+ return /* @__PURE__ */ import_react75.default.createElement(
6465
+ "div",
6466
+ {
6467
+ ref: (node) => {
6468
+ containerRef.current = node;
6469
+ if (typeof ref === "function") ref(node);
6470
+ else if (ref) ref.current = node;
6471
+ },
6472
+ className: cx(
6473
+ "h-full bg-charcoal/50 border-l border-ash/40 flex flex-col relative shrink-0",
6474
+ className
6475
+ ),
6476
+ style: width ? { width } : void 0,
6477
+ ...rest
6478
+ },
6479
+ /* @__PURE__ */ import_react75.default.createElement(
6480
+ "div",
6481
+ {
6482
+ onMouseDown: onResizeStart,
6483
+ className: cx(
6484
+ "absolute top-0 left-0 w-1 h-full cursor-col-resize z-50",
6485
+ "hover:bg-gold/50 transition-colors",
6486
+ "after:absolute after:inset-y-0 after:-left-1 after:w-2"
6487
+ )
6488
+ }
6489
+ ),
6490
+ topContent !== null && /* @__PURE__ */ import_react75.default.createElement(
6491
+ "div",
6492
+ {
6493
+ className: "min-h-0 overflow-hidden flex flex-col",
6494
+ style: hasBoth ? { height: `${topPercent}%` } : { flex: "1 1 0%" }
6495
+ },
6496
+ topContent
6497
+ ),
6498
+ hasBoth && /* @__PURE__ */ import_react75.default.createElement(
6499
+ "div",
6500
+ {
6501
+ onMouseDown: startHeightResize,
6502
+ className: cx(
6503
+ "h-1 cursor-row-resize z-50 shrink-0",
6504
+ "bg-ash/40 hover:bg-gold/50 transition-colors",
6505
+ "relative",
6506
+ "after:absolute after:-top-1 after:left-0 after:right-0 after:h-3"
6507
+ )
6508
+ }
6509
+ ),
6510
+ bottomContent !== null && /* @__PURE__ */ import_react75.default.createElement(
6511
+ "div",
6512
+ {
6513
+ className: "min-h-0 overflow-hidden flex flex-col",
6514
+ style: hasBoth ? { height: `${100 - topPercent}%` } : { flex: "1 1 0%" }
6515
+ },
6516
+ bottomContent
6517
+ )
6518
+ );
6519
+ }
6520
+ );
6521
+ ToolPanelContainer.displayName = "ToolPanelContainer";
6093
6522
 
6094
6523
  // src/components/chat/hooks/useArtifacts.ts
6095
- var import_react70 = require("react");
6524
+ var import_react76 = require("react");
6096
6525
  function useArtifacts() {
6097
- const [artifacts, setArtifacts] = (0, import_react70.useState)([]);
6098
- const scheduleArtifact = (0, import_react70.useCallback)((artifact) => {
6526
+ const [artifacts, setArtifacts] = (0, import_react76.useState)([]);
6527
+ const scheduleArtifact = (0, import_react76.useCallback)((artifact) => {
6099
6528
  setArtifacts((prev) => [...prev, { ...artifact, isPending: true }]);
6100
6529
  }, []);
6101
- const showArtifact = (0, import_react70.useCallback)(
6530
+ const showArtifact = (0, import_react76.useCallback)(
6102
6531
  (artifactId, updates) => {
6103
6532
  setArtifacts((prev) => {
6104
6533
  const existingIndex = prev.findIndex((a) => a.id === artifactId);
@@ -6113,36 +6542,36 @@ function useArtifacts() {
6113
6542
  },
6114
6543
  []
6115
6544
  );
6116
- const removeArtifact = (0, import_react70.useCallback)((artifactId) => {
6545
+ const removeArtifact = (0, import_react76.useCallback)((artifactId) => {
6117
6546
  setArtifacts((prev) => prev.filter((a) => a.id !== artifactId));
6118
6547
  }, []);
6119
- const clearArtifacts = (0, import_react70.useCallback)(() => {
6548
+ const clearArtifacts = (0, import_react76.useCallback)(() => {
6120
6549
  setArtifacts([]);
6121
6550
  }, []);
6122
6551
  return { artifacts, scheduleArtifact, showArtifact, removeArtifact, clearArtifacts };
6123
6552
  }
6124
6553
 
6125
6554
  // src/components/chat/hooks/useResizable.ts
6126
- var import_react71 = require("react");
6555
+ var import_react77 = require("react");
6127
6556
  function useResizable({
6128
6557
  initialWidthPercent,
6129
6558
  minWidthPercent,
6130
6559
  maxWidthPercent,
6131
6560
  direction
6132
6561
  }) {
6133
- const [widthPercent, setWidthPercent] = (0, import_react71.useState)(initialWidthPercent);
6134
- const [isResizing, setIsResizing] = (0, import_react71.useState)(false);
6135
- const lastX = (0, import_react71.useRef)(null);
6136
- const startResizing = (0, import_react71.useCallback)((e) => {
6562
+ const [widthPercent, setWidthPercent] = (0, import_react77.useState)(initialWidthPercent);
6563
+ const [isResizing, setIsResizing] = (0, import_react77.useState)(false);
6564
+ const lastX = (0, import_react77.useRef)(null);
6565
+ const startResizing = (0, import_react77.useCallback)((e) => {
6137
6566
  e.preventDefault();
6138
6567
  setIsResizing(true);
6139
6568
  lastX.current = e.clientX;
6140
6569
  }, []);
6141
- const stopResizing = (0, import_react71.useCallback)(() => {
6570
+ const stopResizing = (0, import_react77.useCallback)(() => {
6142
6571
  setIsResizing(false);
6143
6572
  lastX.current = null;
6144
6573
  }, []);
6145
- const resize = (0, import_react71.useCallback)(
6574
+ const resize = (0, import_react77.useCallback)(
6146
6575
  (e) => {
6147
6576
  if (!isResizing || lastX.current === null) {
6148
6577
  return;
@@ -6158,7 +6587,7 @@ function useResizable({
6158
6587
  },
6159
6588
  [isResizing, direction, minWidthPercent, maxWidthPercent]
6160
6589
  );
6161
- (0, import_react71.useEffect)(() => {
6590
+ (0, import_react77.useEffect)(() => {
6162
6591
  if (isResizing) {
6163
6592
  window.addEventListener("mousemove", resize);
6164
6593
  window.addEventListener("mouseup", stopResizing);
@@ -6182,7 +6611,7 @@ function useResizable({
6182
6611
  }
6183
6612
 
6184
6613
  // src/components/chat/ChatInterface.tsx
6185
- var ChatInterface = import_react72.default.forwardRef(
6614
+ var ChatInterface = import_react78.default.forwardRef(
6186
6615
  ({
6187
6616
  messages = [],
6188
6617
  conversationTree,
@@ -6205,6 +6634,7 @@ var ChatInterface = import_react72.default.forwardRef(
6205
6634
  attachments: propsAttachments,
6206
6635
  onAttachmentsChange,
6207
6636
  artifacts = [],
6637
+ artifactNodes,
6208
6638
  isArtifactsPanelOpen,
6209
6639
  onArtifactsPanelOpenChange,
6210
6640
  tasks = [],
@@ -6212,10 +6642,25 @@ var ChatInterface = import_react72.default.forwardRef(
6212
6642
  className,
6213
6643
  ...rest
6214
6644
  }, ref) => {
6215
- const [sidebarCollapsed, setSidebarCollapsed] = (0, import_react72.useState)(initialSidebarCollapsed);
6216
- const [internalPanelOpen, setInternalPanelOpen] = (0, import_react72.useState)(false);
6217
- const prevArtifactsRef = (0, import_react72.useRef)([]);
6218
- const prevTasksRef = (0, import_react72.useRef)([]);
6645
+ const [sidebarCollapsed, setSidebarCollapsed] = (0, import_react78.useState)(initialSidebarCollapsed);
6646
+ const prevArtifactsRef = (0, import_react78.useRef)([]);
6647
+ const prevTasksRef = (0, import_react78.useRef)([]);
6648
+ const [internalTools, setInternalTools] = (0, import_react78.useState)({
6649
+ top: null,
6650
+ bottom: null
6651
+ });
6652
+ const dismissedToolsRef = (0, import_react78.useRef)(/* @__PURE__ */ new Set());
6653
+ const isPanelControlled = isArtifactsPanelOpen !== void 0;
6654
+ const activeTools = (0, import_react78.useMemo)(() => {
6655
+ if (isPanelControlled) {
6656
+ return {
6657
+ top: isArtifactsPanelOpen ? "artifacts" : internalTools.top,
6658
+ bottom: internalTools.bottom
6659
+ };
6660
+ }
6661
+ return internalTools;
6662
+ }, [isPanelControlled, isArtifactsPanelOpen, internalTools]);
6663
+ const isAnyToolOpen = activeTools.top !== null || activeTools.bottom !== null;
6219
6664
  const {
6220
6665
  width: sidebarWidth,
6221
6666
  startResizing: startResizingSidebar
@@ -6226,19 +6671,43 @@ var ChatInterface = import_react72.default.forwardRef(
6226
6671
  direction: "right"
6227
6672
  });
6228
6673
  const {
6229
- width: artifactsWidth,
6230
- widthPercent: artifactsWidthPercent,
6231
- startResizing: startResizingArtifacts
6674
+ width: toolsWidth,
6675
+ startResizing: startResizingTools
6232
6676
  } = useResizable({
6233
6677
  initialWidthPercent: 50,
6234
6678
  minWidthPercent: 25,
6235
6679
  maxWidthPercent: 70,
6236
6680
  direction: "left"
6237
6681
  });
6238
- const isPanelControlled = isArtifactsPanelOpen !== void 0;
6239
- const artifactsPanelOpen = isPanelControlled ? isArtifactsPanelOpen : internalPanelOpen;
6682
+ const toggleTool = (0, import_react78.useCallback)((toolId) => {
6683
+ const toolDef = TOOL_DEFINITIONS.find((t) => t.id === toolId);
6684
+ if (!toolDef) return;
6685
+ const group = toolDef.group;
6686
+ if (toolId === "artifacts" && isPanelControlled) {
6687
+ const isCurrentlyOpen = activeTools.top === "artifacts";
6688
+ if (isCurrentlyOpen) {
6689
+ dismissedToolsRef.current.add("artifacts");
6690
+ } else {
6691
+ dismissedToolsRef.current.delete("artifacts");
6692
+ }
6693
+ onArtifactsPanelOpenChange?.(!isCurrentlyOpen);
6694
+ return;
6695
+ }
6696
+ setInternalTools((prev) => {
6697
+ const isCurrentlyOpen = prev[group] === toolId;
6698
+ if (isCurrentlyOpen) {
6699
+ dismissedToolsRef.current.add(toolId);
6700
+ } else {
6701
+ dismissedToolsRef.current.delete(toolId);
6702
+ }
6703
+ return {
6704
+ ...prev,
6705
+ [group]: isCurrentlyOpen ? null : toolId
6706
+ };
6707
+ });
6708
+ }, [isPanelControlled, activeTools.top, onArtifactsPanelOpenChange]);
6240
6709
  const isTreeMode = !!conversationTree;
6241
- const effectiveMessages = (0, import_react72.useMemo)(() => {
6710
+ const effectiveMessages = (0, import_react78.useMemo)(() => {
6242
6711
  if (isTreeMode && conversationTree) {
6243
6712
  const pathNodes = getActivePathMessages(conversationTree);
6244
6713
  return pathNodes.map((node) => ({
@@ -6250,63 +6719,48 @@ var ChatInterface = import_react72.default.forwardRef(
6250
6719
  }
6251
6720
  return messages;
6252
6721
  }, [isTreeMode, conversationTree, messages]);
6253
- const latestUserMessageIndex = (0, import_react72.useMemo)(() => {
6722
+ const latestUserMessageIndex = (0, import_react78.useMemo)(() => {
6254
6723
  for (let i = effectiveMessages.length - 1; i >= 0; i--) {
6255
- if (effectiveMessages[i].variant === "user") {
6256
- return i;
6257
- }
6724
+ if (effectiveMessages[i].variant === "user") return i;
6258
6725
  }
6259
6726
  return -1;
6260
6727
  }, [effectiveMessages]);
6261
- (0, import_react72.useEffect)(() => {
6262
- if (isPanelControlled) {
6263
- return;
6264
- }
6728
+ (0, import_react78.useEffect)(() => {
6265
6729
  const hasNewOrSignificantArtifact = artifacts.some((a) => {
6266
6730
  const p = prevArtifactsRef.current.find((prev) => prev.id === a.id);
6267
- if (!p) {
6268
- return true;
6269
- }
6270
- if (p.isPending && !a.isPending) {
6271
- return true;
6272
- }
6273
- if (p.title !== a.title || p.type !== a.type) {
6274
- return true;
6275
- }
6731
+ if (!p) return true;
6732
+ if (p.isPending && !a.isPending) return true;
6733
+ if (p.title !== a.title || p.type !== a.type) return true;
6276
6734
  return false;
6277
6735
  });
6736
+ const hasNodes = artifactNodes && artifactNodes.length > 0;
6737
+ if (!isPanelControlled && (hasNewOrSignificantArtifact || hasNodes) && !dismissedToolsRef.current.has("artifacts")) {
6738
+ setInternalTools((prev) => ({ ...prev, top: "artifacts" }));
6739
+ }
6278
6740
  const hasNewOrUpdatedTask = (curr, prev) => {
6279
6741
  return curr.some((c) => {
6280
6742
  const p = prev.find((x) => x.id === c.id);
6281
- if (!p) {
6282
- return true;
6283
- }
6284
- if (c.status !== p.status || c.label !== p.label) {
6285
- return true;
6286
- }
6287
- if (c.subtasks && hasNewOrUpdatedTask(c.subtasks, p?.subtasks || [])) {
6288
- return true;
6289
- }
6743
+ if (!p) return true;
6744
+ if (c.status !== p.status || c.label !== p.label) return true;
6745
+ if (c.subtasks && hasNewOrUpdatedTask(c.subtasks, p?.subtasks || [])) return true;
6290
6746
  return false;
6291
6747
  });
6292
6748
  };
6293
- if (hasNewOrSignificantArtifact || hasNewOrUpdatedTask(tasks, prevTasksRef.current)) {
6294
- setInternalPanelOpen(true);
6749
+ if (hasNewOrUpdatedTask(tasks, prevTasksRef.current) && !dismissedToolsRef.current.has("todos")) {
6750
+ setInternalTools((prev) => ({ ...prev, bottom: "todos" }));
6295
6751
  }
6296
6752
  prevArtifactsRef.current = artifacts;
6297
6753
  prevTasksRef.current = tasks;
6298
- }, [artifacts, tasks, isPanelControlled]);
6299
- const handleBranchSwitch = (0, import_react72.useCallback)(
6754
+ }, [artifacts, artifactNodes, tasks, isPanelControlled]);
6755
+ const handleBranchSwitch = (0, import_react78.useCallback)(
6300
6756
  (nodeId, direction) => {
6301
- if (!isTreeMode || !conversationTree || !onTreeChange) {
6302
- return;
6303
- }
6757
+ if (!isTreeMode || !conversationTree || !onTreeChange) return;
6304
6758
  const newTree = switchBranch(conversationTree, nodeId, direction);
6305
6759
  onTreeChange(newTree);
6306
6760
  },
6307
6761
  [isTreeMode, conversationTree, onTreeChange]
6308
6762
  );
6309
- const displayMessages = (0, import_react72.useMemo)(() => {
6763
+ const displayMessages = (0, import_react78.useMemo)(() => {
6310
6764
  return effectiveMessages.map((msg) => {
6311
6765
  let branchInfo = void 0;
6312
6766
  if (isTreeMode && conversationTree) {
@@ -6325,11 +6779,7 @@ var ChatInterface = import_react72.default.forwardRef(
6325
6779
  onEdit: msg.variant === "user" && onEditMessage ? (newContent) => onEditMessage(msg.id, newContent) : void 0,
6326
6780
  onRetry: msg.variant === "assistant" && onRetryMessage ? () => onRetryMessage(msg.id) : void 0
6327
6781
  } : void 0;
6328
- return {
6329
- ...msg,
6330
- branchInfo,
6331
- actions
6332
- };
6782
+ return { ...msg, branchInfo, actions };
6333
6783
  });
6334
6784
  }, [
6335
6785
  effectiveMessages,
@@ -6340,31 +6790,57 @@ var ChatInterface = import_react72.default.forwardRef(
6340
6790
  onRetryMessage,
6341
6791
  handleBranchSwitch
6342
6792
  ]);
6343
- const handleSubmit = (0, import_react72.useCallback)(
6793
+ const handleSubmit = (0, import_react78.useCallback)(
6344
6794
  (message, attachments) => {
6345
6795
  onMessageSubmit?.(message, attachments);
6346
6796
  },
6347
6797
  [onMessageSubmit]
6348
6798
  );
6349
- const toggleSidebar = (0, import_react72.useCallback)(() => {
6799
+ const toggleSidebar = (0, import_react78.useCallback)(() => {
6350
6800
  setSidebarCollapsed((prev) => !prev);
6351
6801
  }, []);
6352
- const toggleArtifactsPanel = (0, import_react72.useCallback)(() => {
6353
- if (isPanelControlled) {
6354
- onArtifactsPanelOpenChange?.(!artifactsPanelOpen);
6355
- } else {
6356
- setInternalPanelOpen((prev) => !prev);
6357
- }
6358
- }, [isPanelControlled, artifactsPanelOpen, onArtifactsPanelOpenChange]);
6359
6802
  const isEmpty = effectiveMessages.length === 0;
6360
- return /* @__PURE__ */ import_react72.default.createElement(
6803
+ const allSettled = tasks.length === 0 || areAllTasksSettled(tasks);
6804
+ const toolDefinitions = (0, import_react78.useMemo)(() => [
6805
+ {
6806
+ id: "artifacts",
6807
+ icon: /* @__PURE__ */ import_react78.default.createElement(MediaIcon, null),
6808
+ label: "Artifacts",
6809
+ group: "top"
6810
+ },
6811
+ {
6812
+ id: "todos",
6813
+ icon: allSettled ? /* @__PURE__ */ import_react78.default.createElement(CheckSquareIcon, null) : /* @__PURE__ */ import_react78.default.createElement(SquareLoaderIcon, null),
6814
+ label: "Tasks",
6815
+ group: "bottom"
6816
+ }
6817
+ ], [allSettled]);
6818
+ const renderToolContent = (toolId) => {
6819
+ if (!toolId) return null;
6820
+ switch (toolId) {
6821
+ case "artifacts":
6822
+ return /* @__PURE__ */ import_react78.default.createElement(
6823
+ ArtifactsPanel,
6824
+ {
6825
+ artifacts,
6826
+ nodes: artifactNodes,
6827
+ className: "h-full"
6828
+ }
6829
+ );
6830
+ case "todos":
6831
+ return tasks.length > 0 ? /* @__PURE__ */ import_react78.default.createElement(TodosList, { tasks, title: tasksTitle, className: "h-full" }) : /* @__PURE__ */ import_react78.default.createElement("div", { className: "h-full flex flex-col" }, /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex items-center p-4 border-b border-ash/40 shrink-0" }, /* @__PURE__ */ import_react78.default.createElement("h3", { className: "text-xs font-medium text-white" }, "Tasks")), /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex-1 flex items-center justify-center" }, /* @__PURE__ */ import_react78.default.createElement("p", { className: "text-xs text-silver/60" }, "No tasks")));
6832
+ default:
6833
+ return null;
6834
+ }
6835
+ };
6836
+ return /* @__PURE__ */ import_react78.default.createElement(
6361
6837
  "div",
6362
6838
  {
6363
6839
  ref,
6364
6840
  className: cx("flex h-full w-full bg-obsidian overflow-hidden", className),
6365
6841
  ...rest
6366
6842
  },
6367
- /* @__PURE__ */ import_react72.default.createElement(
6843
+ /* @__PURE__ */ import_react78.default.createElement(
6368
6844
  ConversationSidebar,
6369
6845
  {
6370
6846
  conversations,
@@ -6376,16 +6852,16 @@ var ChatInterface = import_react72.default.forwardRef(
6376
6852
  onResizeStart: startResizingSidebar
6377
6853
  }
6378
6854
  ),
6379
- /* @__PURE__ */ import_react72.default.createElement("div", { className: "flex-1 flex flex-col min-w-0 relative" }, /* @__PURE__ */ import_react72.default.createElement("div", { className: cx(
6855
+ /* @__PURE__ */ import_react78.default.createElement("div", { className: "flex-1 flex flex-col min-w-0 relative" }, /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(
6380
6856
  "flex-1 flex flex-col min-h-0 relative",
6381
6857
  isEmpty ? "justify-center" : "justify-start"
6382
- ) }, /* @__PURE__ */ import_react72.default.createElement("div", { className: cx(
6858
+ ) }, /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(
6383
6859
  "transition-all duration-500 ease-in-out",
6384
6860
  isEmpty ? "flex-1" : "flex-zero"
6385
- ) }), /* @__PURE__ */ import_react72.default.createElement("div", { className: cx(
6861
+ ) }), /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(
6386
6862
  "transition-all duration-500 ease-in-out overflow-hidden flex flex-col",
6387
6863
  isEmpty ? "flex-zero opacity-0" : "flex-1 opacity-100"
6388
- ) }, /* @__PURE__ */ import_react72.default.createElement(
6864
+ ) }, /* @__PURE__ */ import_react78.default.createElement(
6389
6865
  ChatView,
6390
6866
  {
6391
6867
  messages: displayMessages,
@@ -6394,10 +6870,10 @@ var ChatInterface = import_react72.default.forwardRef(
6394
6870
  isThinking,
6395
6871
  className: "flex-1"
6396
6872
  }
6397
- )), /* @__PURE__ */ import_react72.default.createElement("div", { className: cx(
6873
+ )), /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(
6398
6874
  "transition-all duration-500 ease-in-out z-10 w-full flex flex-col items-center",
6399
6875
  isEmpty ? "p-4" : "shrink-0 p-4 border-t border-ash/40 bg-obsidian"
6400
- ) }, isEmpty && /* @__PURE__ */ import_react72.default.createElement("div", { className: "mb-8 text-center animate-fade-in duration-500" }, emptyState ? emptyState : /* @__PURE__ */ import_react72.default.createElement("h1", { className: "text-4xl md:text-5xl font-heading text-gold mb-2 tracking-tight" }, "Welcome!")), /* @__PURE__ */ import_react72.default.createElement(
6876
+ ) }, isEmpty && /* @__PURE__ */ import_react78.default.createElement("div", { className: "mb-8 text-center animate-fade-in duration-500" }, emptyState ? emptyState : /* @__PURE__ */ import_react78.default.createElement("h1", { className: "text-4xl md:text-5xl font-heading text-gold mb-2 tracking-tight" }, "Welcome!")), /* @__PURE__ */ import_react78.default.createElement(
6401
6877
  ChatInput,
6402
6878
  {
6403
6879
  position: isEmpty ? "centered" : "bottom",
@@ -6411,38 +6887,40 @@ var ChatInterface = import_react72.default.forwardRef(
6411
6887
  attachments: propsAttachments,
6412
6888
  onAttachmentsChange
6413
6889
  }
6414
- )), /* @__PURE__ */ import_react72.default.createElement("div", { className: cx(
6890
+ )), /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(
6415
6891
  "transition-all duration-500 ease-in-out",
6416
6892
  isEmpty ? "flex-1" : "flex-zero"
6417
6893
  ) }))),
6418
- /* @__PURE__ */ import_react72.default.createElement("div", { className: "h-full flex flex-col shrink-0" }, /* @__PURE__ */ import_react72.default.createElement("div", { className: "flex-1 min-h-0" }, /* @__PURE__ */ import_react72.default.createElement(
6419
- ArtifactsPanel,
6894
+ isAnyToolOpen && /* @__PURE__ */ import_react78.default.createElement(
6895
+ ToolPanelContainer,
6420
6896
  {
6421
- artifacts,
6422
- isOpen: artifactsPanelOpen,
6423
- onClose: toggleArtifactsPanel,
6424
- width: artifactsWidth,
6425
- widthPercent: artifactsWidthPercent,
6426
- onResizeStart: startResizingArtifacts,
6427
- className: "h-full"
6897
+ topContent: renderToolContent(activeTools.top),
6898
+ bottomContent: renderToolContent(activeTools.bottom),
6899
+ width: toolsWidth,
6900
+ onResizeStart: startResizingTools
6428
6901
  }
6429
- )), tasks.length > 0 && artifactsPanelOpen && /* @__PURE__ */ import_react72.default.createElement(
6430
- TodosList,
6902
+ ),
6903
+ /* @__PURE__ */ import_react78.default.createElement(
6904
+ ToolSidebar,
6431
6905
  {
6432
- tasks,
6433
- title: tasksTitle,
6434
- style: { width: artifactsWidth }
6906
+ tools: toolDefinitions,
6907
+ activeTools,
6908
+ onToggleTool: toggleTool
6435
6909
  }
6436
- ))
6910
+ )
6437
6911
  );
6438
6912
  }
6439
6913
  );
6440
6914
  ChatInterface.displayName = "ChatInterface";
6915
+ var TOOL_DEFINITIONS = [
6916
+ { id: "artifacts", icon: null, label: "Artifacts", group: "top" },
6917
+ { id: "todos", icon: null, label: "Tasks", group: "bottom" }
6918
+ ];
6441
6919
 
6442
6920
  // src/components/chat/MessageActions.tsx
6443
- var import_react73 = __toESM(require("react"));
6921
+ var import_react79 = __toESM(require("react"));
6444
6922
  var import_lucide_react14 = require("lucide-react");
6445
- var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ import_react73.default.createElement(
6923
+ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @__PURE__ */ import_react79.default.createElement(
6446
6924
  "button",
6447
6925
  {
6448
6926
  type: "button",
@@ -6458,7 +6936,7 @@ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @_
6458
6936
  },
6459
6937
  children
6460
6938
  );
6461
- var MessageActions = import_react73.default.forwardRef(
6939
+ var MessageActions = import_react79.default.forwardRef(
6462
6940
  ({
6463
6941
  variant,
6464
6942
  content,
@@ -6470,12 +6948,12 @@ var MessageActions = import_react73.default.forwardRef(
6470
6948
  className,
6471
6949
  ...rest
6472
6950
  }, ref) => {
6473
- const [localIsEditing, setLocalIsEditing] = (0, import_react73.useState)(false);
6474
- const [localEditValue, setLocalEditValue] = (0, import_react73.useState)(content);
6475
- const [copied, setCopied] = (0, import_react73.useState)(false);
6951
+ const [localIsEditing, setLocalIsEditing] = (0, import_react79.useState)(false);
6952
+ const [localEditValue, setLocalEditValue] = (0, import_react79.useState)(content);
6953
+ const [copied, setCopied] = (0, import_react79.useState)(false);
6476
6954
  const isEditing = controlledIsEditing ?? localIsEditing;
6477
6955
  const editValue = controlledEditValue ?? localEditValue;
6478
- const setIsEditing = (0, import_react73.useCallback)(
6956
+ const setIsEditing = (0, import_react79.useCallback)(
6479
6957
  (value) => {
6480
6958
  if (onEditingChange) {
6481
6959
  onEditingChange(value);
@@ -6485,10 +6963,10 @@ var MessageActions = import_react73.default.forwardRef(
6485
6963
  },
6486
6964
  [onEditingChange]
6487
6965
  );
6488
- const setEditValue = (0, import_react73.useCallback)((value) => {
6966
+ const setEditValue = (0, import_react79.useCallback)((value) => {
6489
6967
  setLocalEditValue(value);
6490
6968
  }, []);
6491
- const handleCopy = (0, import_react73.useCallback)(async () => {
6969
+ const handleCopy = (0, import_react79.useCallback)(async () => {
6492
6970
  try {
6493
6971
  await navigator.clipboard.writeText(content);
6494
6972
  setCopied(true);
@@ -6504,22 +6982,22 @@ var MessageActions = import_react73.default.forwardRef(
6504
6982
  setTimeout(() => setCopied(false), 2e3);
6505
6983
  }
6506
6984
  }, [content]);
6507
- const handleStartEdit = (0, import_react73.useCallback)(() => {
6985
+ const handleStartEdit = (0, import_react79.useCallback)(() => {
6508
6986
  setLocalEditValue(content);
6509
6987
  setIsEditing(true);
6510
6988
  }, [content, setIsEditing]);
6511
- const handleCancelEdit = (0, import_react73.useCallback)(() => {
6989
+ const handleCancelEdit = (0, import_react79.useCallback)(() => {
6512
6990
  setIsEditing(false);
6513
6991
  setLocalEditValue(content);
6514
6992
  }, [content, setIsEditing]);
6515
- const handleSubmitEdit = (0, import_react73.useCallback)(() => {
6993
+ const handleSubmitEdit = (0, import_react79.useCallback)(() => {
6516
6994
  const trimmed = editValue.trim();
6517
6995
  if (trimmed && trimmed !== content) {
6518
6996
  onEdit?.(trimmed);
6519
6997
  }
6520
6998
  setIsEditing(false);
6521
6999
  }, [editValue, content, onEdit, setIsEditing]);
6522
- const handleEditKeyDown = (0, import_react73.useCallback)(
7000
+ const handleEditKeyDown = (0, import_react79.useCallback)(
6523
7001
  (e) => {
6524
7002
  if (e.key === "Enter" && !e.shiftKey) {
6525
7003
  e.preventDefault();
@@ -6532,19 +7010,19 @@ var MessageActions = import_react73.default.forwardRef(
6532
7010
  );
6533
7011
  const isUser = variant === "user";
6534
7012
  if (isUser && isEditing) {
6535
- return /* @__PURE__ */ import_react73.default.createElement(
7013
+ return /* @__PURE__ */ import_react79.default.createElement(
6536
7014
  "div",
6537
7015
  {
6538
7016
  ref,
6539
7017
  className: cx("mt-2", className),
6540
7018
  ...rest
6541
7019
  },
6542
- /* @__PURE__ */ import_react73.default.createElement(
7020
+ /* @__PURE__ */ import_react79.default.createElement(
6543
7021
  "div",
6544
7022
  {
6545
7023
  className: "relative bg-charcoal border border-ash/60 focus-within:border-gold/60 focus-within:ring-1 focus-within:ring-gold/20"
6546
7024
  },
6547
- /* @__PURE__ */ import_react73.default.createElement(
7025
+ /* @__PURE__ */ import_react79.default.createElement(
6548
7026
  "textarea",
6549
7027
  {
6550
7028
  value: editValue,
@@ -6555,15 +7033,15 @@ var MessageActions = import_react73.default.forwardRef(
6555
7033
  rows: 2
6556
7034
  }
6557
7035
  ),
6558
- /* @__PURE__ */ import_react73.default.createElement("div", { className: "absolute right-2 bottom-2 flex gap-1" }, /* @__PURE__ */ import_react73.default.createElement(
7036
+ /* @__PURE__ */ import_react79.default.createElement("div", { className: "absolute right-2 bottom-2 flex gap-1" }, /* @__PURE__ */ import_react79.default.createElement(
6559
7037
  ActionButton2,
6560
7038
  {
6561
7039
  onClick: handleCancelEdit,
6562
7040
  label: "Cancel edit",
6563
7041
  className: "text-silver/60 hover:text-error"
6564
7042
  },
6565
- /* @__PURE__ */ import_react73.default.createElement(import_lucide_react14.X, { className: "w-4 h-4" })
6566
- ), /* @__PURE__ */ import_react73.default.createElement(
7043
+ /* @__PURE__ */ import_react79.default.createElement(import_lucide_react14.X, { className: "w-4 h-4" })
7044
+ ), /* @__PURE__ */ import_react79.default.createElement(
6567
7045
  ActionButton2,
6568
7046
  {
6569
7047
  onClick: handleSubmitEdit,
@@ -6571,13 +7049,13 @@ var MessageActions = import_react73.default.forwardRef(
6571
7049
  className: "text-silver/60 hover:text-gold",
6572
7050
  disabled: !editValue.trim() || editValue.trim() === content
6573
7051
  },
6574
- /* @__PURE__ */ import_react73.default.createElement(import_lucide_react14.Send, { className: "w-4 h-4" })
7052
+ /* @__PURE__ */ import_react79.default.createElement(import_lucide_react14.Send, { className: "w-4 h-4" })
6575
7053
  ))
6576
7054
  ),
6577
- /* @__PURE__ */ import_react73.default.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
7055
+ /* @__PURE__ */ import_react79.default.createElement("p", { className: "text-xs text-silver/50 mt-1" }, "Press Enter to submit, Esc to cancel. This will create a new branch.")
6578
7056
  );
6579
7057
  }
6580
- return /* @__PURE__ */ import_react73.default.createElement(
7058
+ return /* @__PURE__ */ import_react79.default.createElement(
6581
7059
  "div",
6582
7060
  {
6583
7061
  ref,
@@ -6588,18 +7066,18 @@ var MessageActions = import_react73.default.forwardRef(
6588
7066
  ),
6589
7067
  ...rest
6590
7068
  },
6591
- /* @__PURE__ */ import_react73.default.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ import_react73.default.createElement(import_lucide_react14.Check, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ import_react73.default.createElement(import_lucide_react14.Copy, { className: "w-3.5 h-3.5" })),
6592
- isUser && onEdit && /* @__PURE__ */ import_react73.default.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ import_react73.default.createElement(import_lucide_react14.Pencil, { className: "w-3.5 h-3.5" })),
6593
- !isUser && onRetry && /* @__PURE__ */ import_react73.default.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ import_react73.default.createElement(import_lucide_react14.RotateCcw, { className: "w-3.5 h-3.5" }))
7069
+ /* @__PURE__ */ import_react79.default.createElement(ActionButton2, { onClick: handleCopy, label: copied ? "Copied!" : "Copy message" }, copied ? /* @__PURE__ */ import_react79.default.createElement(import_lucide_react14.Check, { className: "w-3.5 h-3.5 text-success" }) : /* @__PURE__ */ import_react79.default.createElement(import_lucide_react14.Copy, { className: "w-3.5 h-3.5" })),
7070
+ isUser && onEdit && /* @__PURE__ */ import_react79.default.createElement(ActionButton2, { onClick: handleStartEdit, label: "Edit message" }, /* @__PURE__ */ import_react79.default.createElement(import_lucide_react14.Pencil, { className: "w-3.5 h-3.5" })),
7071
+ !isUser && onRetry && /* @__PURE__ */ import_react79.default.createElement(ActionButton2, { onClick: onRetry, label: "Regenerate response" }, /* @__PURE__ */ import_react79.default.createElement(import_lucide_react14.RotateCcw, { className: "w-3.5 h-3.5" }))
6594
7072
  );
6595
7073
  }
6596
7074
  );
6597
7075
  MessageActions.displayName = "MessageActions";
6598
7076
 
6599
7077
  // src/components/chat/BranchNavigator.tsx
6600
- var import_react74 = __toESM(require("react"));
7078
+ var import_react80 = __toESM(require("react"));
6601
7079
  var import_lucide_react15 = require("lucide-react");
6602
- var BranchNavigator = import_react74.default.forwardRef(
7080
+ var BranchNavigator = import_react80.default.forwardRef(
6603
7081
  ({
6604
7082
  current,
6605
7083
  total,
@@ -6618,7 +7096,7 @@ var BranchNavigator = import_react74.default.forwardRef(
6618
7096
  const buttonSize = size === "sm" ? "p-0.5" : "p-1";
6619
7097
  const iconSize = size === "sm" ? "w-3 h-3" : "w-4 h-4";
6620
7098
  const textSize = size === "sm" ? "text-xs" : "text-sm";
6621
- return /* @__PURE__ */ import_react74.default.createElement(
7099
+ return /* @__PURE__ */ import_react80.default.createElement(
6622
7100
  "div",
6623
7101
  {
6624
7102
  ref,
@@ -6630,8 +7108,8 @@ var BranchNavigator = import_react74.default.forwardRef(
6630
7108
  "aria-label": "Branch navigation",
6631
7109
  ...rest
6632
7110
  },
6633
- showIcon && /* @__PURE__ */ import_react74.default.createElement(import_lucide_react15.GitBranch, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
6634
- /* @__PURE__ */ import_react74.default.createElement(
7111
+ showIcon && /* @__PURE__ */ import_react80.default.createElement(import_lucide_react15.GitBranch, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
7112
+ /* @__PURE__ */ import_react80.default.createElement(
6635
7113
  "button",
6636
7114
  {
6637
7115
  type: "button",
@@ -6644,10 +7122,10 @@ var BranchNavigator = import_react74.default.forwardRef(
6644
7122
  ),
6645
7123
  "aria-label": "Previous branch"
6646
7124
  },
6647
- /* @__PURE__ */ import_react74.default.createElement(import_lucide_react15.ChevronLeft, { className: iconSize })
7125
+ /* @__PURE__ */ import_react80.default.createElement(import_lucide_react15.ChevronLeft, { className: iconSize })
6648
7126
  ),
6649
- /* @__PURE__ */ import_react74.default.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
6650
- /* @__PURE__ */ import_react74.default.createElement(
7127
+ /* @__PURE__ */ import_react80.default.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
7128
+ /* @__PURE__ */ import_react80.default.createElement(
6651
7129
  "button",
6652
7130
  {
6653
7131
  type: "button",
@@ -6660,7 +7138,7 @@ var BranchNavigator = import_react74.default.forwardRef(
6660
7138
  ),
6661
7139
  "aria-label": "Next branch"
6662
7140
  },
6663
- /* @__PURE__ */ import_react74.default.createElement(import_lucide_react15.ChevronRight, { className: iconSize })
7141
+ /* @__PURE__ */ import_react80.default.createElement(import_lucide_react15.ChevronRight, { className: iconSize })
6664
7142
  )
6665
7143
  );
6666
7144
  }
@@ -6668,16 +7146,16 @@ var BranchNavigator = import_react74.default.forwardRef(
6668
7146
  BranchNavigator.displayName = "BranchNavigator";
6669
7147
 
6670
7148
  // src/components/BrandIcon.tsx
6671
- var import_react75 = __toESM(require("react"));
7149
+ var import_react81 = __toESM(require("react"));
6672
7150
  var sizeMap2 = {
6673
7151
  sm: "h-8 w-8 text-sm",
6674
7152
  md: "h-12 w-12 text-base",
6675
7153
  lg: "h-16 w-16 text-lg"
6676
7154
  };
6677
- var BrandIcon = import_react75.default.forwardRef(
7155
+ var BrandIcon = import_react81.default.forwardRef(
6678
7156
  ({ size = "md", variant = "solid", children, className, ...rest }, ref) => {
6679
7157
  const variantClasses = variant === "solid" ? "bg-gold text-obsidian border-2 border-gold" : "bg-transparent text-gold border-2 border-gold";
6680
- return /* @__PURE__ */ import_react75.default.createElement(
7158
+ return /* @__PURE__ */ import_react81.default.createElement(
6681
7159
  "div",
6682
7160
  {
6683
7161
  ref,
@@ -6696,17 +7174,17 @@ var BrandIcon = import_react75.default.forwardRef(
6696
7174
  BrandIcon.displayName = "BrandIcon";
6697
7175
 
6698
7176
  // src/components/ColorSwatch.tsx
6699
- var import_react76 = __toESM(require("react"));
6700
- var ColorSwatch = import_react76.default.forwardRef(
7177
+ var import_react82 = __toESM(require("react"));
7178
+ var ColorSwatch = import_react82.default.forwardRef(
6701
7179
  ({ color, label, className, ...rest }, ref) => {
6702
- return /* @__PURE__ */ import_react76.default.createElement(
7180
+ return /* @__PURE__ */ import_react82.default.createElement(
6703
7181
  "div",
6704
7182
  {
6705
7183
  ref,
6706
7184
  className: cx("flex flex-col items-center gap-2", className),
6707
7185
  ...rest
6708
7186
  },
6709
- /* @__PURE__ */ import_react76.default.createElement(
7187
+ /* @__PURE__ */ import_react82.default.createElement(
6710
7188
  "div",
6711
7189
  {
6712
7190
  className: "h-16 w-16 border-2 border-ash rounded-none shadow-sm",
@@ -6714,22 +7192,22 @@ var ColorSwatch = import_react76.default.forwardRef(
6714
7192
  "aria-label": label || color
6715
7193
  }
6716
7194
  ),
6717
- label && /* @__PURE__ */ import_react76.default.createElement("span", { className: "text-xs text-silver font-medium" }, label)
7195
+ label && /* @__PURE__ */ import_react82.default.createElement("span", { className: "text-xs text-silver font-medium" }, label)
6718
7196
  );
6719
7197
  }
6720
7198
  );
6721
7199
  ColorSwatch.displayName = "ColorSwatch";
6722
7200
 
6723
7201
  // src/components/SectionHeading.tsx
6724
- var import_react77 = __toESM(require("react"));
7202
+ var import_react83 = __toESM(require("react"));
6725
7203
  var levelStyles = {
6726
7204
  h2: "text-2xl mb-4",
6727
7205
  h3: "text-xl mb-3"
6728
7206
  };
6729
- var SectionHeading = import_react77.default.forwardRef(
7207
+ var SectionHeading = import_react83.default.forwardRef(
6730
7208
  ({ level = "h2", children, className, ...rest }, ref) => {
6731
7209
  const Component = level;
6732
- return /* @__PURE__ */ import_react77.default.createElement(
7210
+ return /* @__PURE__ */ import_react83.default.createElement(
6733
7211
  Component,
6734
7212
  {
6735
7213
  ref,
@@ -6746,6 +7224,13 @@ var SectionHeading = import_react77.default.forwardRef(
6746
7224
  );
6747
7225
  SectionHeading.displayName = "SectionHeading";
6748
7226
 
7227
+ // src/components/ArtifactNode.ts
7228
+ var NODE_TYPES = {
7229
+ ARTIFACT: "ARTIFACT",
7230
+ GROUP: "GROUP",
7231
+ VARIANT_SET: "VARIANT_SET"
7232
+ };
7233
+
6749
7234
  // src/index.ts
6750
7235
  var version = "2.0.0";
6751
7236
  // Annotate the CommonJS export names for ESM import in node:
@@ -6758,6 +7243,8 @@ var version = "2.0.0";
6758
7243
  Alert,
6759
7244
  AlertDialog,
6760
7245
  ArtifactCard,
7246
+ ArtifactGroup,
7247
+ ArtifactVariantStack,
6761
7248
  ArtifactsPanel,
6762
7249
  ArtifactsPanelToggle,
6763
7250
  AttachmentPreview,
@@ -6808,6 +7295,7 @@ var version = "2.0.0";
6808
7295
  ListItemText,
6809
7296
  ListSubheader,
6810
7297
  MarkdownContent,
7298
+ MediaIcon,
6811
7299
  Menu,
6812
7300
  MenuContent,
6813
7301
  MenuItem,
@@ -6817,6 +7305,7 @@ var version = "2.0.0";
6817
7305
  Message,
6818
7306
  MessageActions,
6819
7307
  Modal,
7308
+ NODE_TYPES,
6820
7309
  Navbar,
6821
7310
  NavbarBrand,
6822
7311
  NavbarContent,
@@ -6861,9 +7350,12 @@ var version = "2.0.0";
6861
7350
  ThinkingIndicator,
6862
7351
  ToastProvider,
6863
7352
  TodosList,
7353
+ ToolPanelContainer,
7354
+ ToolSidebar,
6864
7355
  Tooltip,
6865
7356
  VideoCard,
6866
7357
  addMessageToTree,
7358
+ areAllTasksSettled,
6867
7359
  createEmptyTree,
6868
7360
  createPreviewUrl,
6869
7361
  generateId,
@@ -6875,6 +7367,7 @@ var version = "2.0.0";
6875
7367
  revokePreviewUrl,
6876
7368
  switchBranch,
6877
7369
  updateNodeContent,
7370
+ useArtifactTreeNavigation,
6878
7371
  useArtifacts,
6879
7372
  useResizable,
6880
7373
  useScrollAnchor,