@lukeashford/aurelius 2.19.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,
@@ -274,8 +282,18 @@ var Skeleton = import_react3.default.forwardRef(
274
282
  Skeleton.displayName = "Skeleton";
275
283
 
276
284
  // src/components/Card.tsx
277
- var CardContext = (0, import_react4.createContext)({ isLoading: false });
285
+ var CardContext = (0, import_react4.createContext)({ loading: void 0 });
278
286
  var useCardContext = () => (0, import_react4.useContext)(CardContext);
287
+ function slotLoading(loading, path) {
288
+ if (!loading) {
289
+ return false;
290
+ }
291
+ if (Array.isArray(path)) {
292
+ const [section, field] = path;
293
+ return !!loading[section]?.[field];
294
+ }
295
+ return !!loading[path];
296
+ }
279
297
  var VARIANT_STYLES = {
280
298
  default: "bg-charcoal shadow-sm border border-gold/30",
281
299
  elevated: "bg-charcoal shadow-lg border-0",
@@ -289,12 +307,12 @@ var CardBase = import_react4.default.forwardRef(
289
307
  interactive = false,
290
308
  selected = false,
291
309
  noPadding = false,
292
- isLoading = false,
310
+ loading,
293
311
  className,
294
312
  children,
295
313
  ...props
296
314
  }, ref) => {
297
- return /* @__PURE__ */ import_react4.default.createElement(CardContext.Provider, { value: { isLoading } }, /* @__PURE__ */ import_react4.default.createElement(
315
+ return /* @__PURE__ */ import_react4.default.createElement(CardContext.Provider, { value: { loading } }, /* @__PURE__ */ import_react4.default.createElement(
298
316
  "div",
299
317
  {
300
318
  ref,
@@ -322,9 +340,12 @@ var CardBase = import_react4.default.forwardRef(
322
340
  CardBase.displayName = "Card";
323
341
  var CardHeader = import_react4.default.forwardRef(
324
342
  ({ title, subtitle, action, className, children, ...props }, ref) => {
325
- const { isLoading } = useCardContext();
343
+ const { loading } = useCardContext();
344
+ const titleIsLoading = slotLoading(loading, ["header", "title"]);
345
+ const subtitleIsLoading = slotLoading(loading, ["header", "subtitle"]);
346
+ const actionIsLoading = slotLoading(loading, ["header", "action"]);
326
347
  const hasContent = title || subtitle || action || children;
327
- if (!hasContent && !isLoading) {
348
+ if (!hasContent && !titleIsLoading && !subtitleIsLoading && !actionIsLoading) {
328
349
  return null;
329
350
  }
330
351
  return /* @__PURE__ */ import_react4.default.createElement(
@@ -334,18 +355,19 @@ var CardHeader = import_react4.default.forwardRef(
334
355
  className: cx("px-6 py-4 border-b border-ash", className),
335
356
  ...props
336
357
  },
337
- isLoading && !title && !subtitle ? /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex flex-col gap-2" }, /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-5 w-3/4" }), /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-4 w-1/2" })) : title || subtitle || action ? /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex-1 min-w-0" }, title ? /* @__PURE__ */ import_react4.default.createElement("h3", { className: "text-lg font-semibold text-white m-0" }, title) : isLoading ? /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-5 w-3/4 mb-1" }) : null, subtitle ? /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-sm text-silver mt-1 m-0" }, subtitle) : isLoading ? /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-4 w-1/2 mt-1" }) : null), action && /* @__PURE__ */ import_react4.default.createElement("div", { className: "shrink-0" }, action)) : children
358
+ title || subtitle || action || titleIsLoading || subtitleIsLoading || actionIsLoading ? /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react4.default.createElement("div", { className: "flex-1 min-w-0" }, title ? /* @__PURE__ */ import_react4.default.createElement("h3", { className: "text-lg font-semibold text-white m-0" }, title) : titleIsLoading ? /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-5 w-3/4 mb-1" }) : null, subtitle ? /* @__PURE__ */ import_react4.default.createElement("p", { className: "text-sm text-silver mt-1 m-0" }, subtitle) : subtitleIsLoading ? /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-4 w-1/2 mt-1" }) : null), action ? /* @__PURE__ */ import_react4.default.createElement("div", { className: "shrink-0" }, action) : actionIsLoading ? /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-8 w-8 shrink-0" }) : null) : children
338
359
  );
339
360
  }
340
361
  );
341
362
  CardHeader.displayName = "CardHeader";
342
363
  var CardBody = import_react4.default.forwardRef(
343
364
  ({ className, children, ...props }, ref) => {
344
- const { isLoading } = useCardContext();
345
- if (!children && !isLoading) {
365
+ const { loading } = useCardContext();
366
+ const isBodyLoading = slotLoading(loading, "body");
367
+ if (!children && !isBodyLoading) {
346
368
  return null;
347
369
  }
348
- return /* @__PURE__ */ import_react4.default.createElement("div", { ref, className: cx("px-6 py-4", className), ...props }, isLoading && !children ? /* @__PURE__ */ import_react4.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-4 w-full" }), /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-4 w-full" }), /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-4 w-3/4" })) : children);
370
+ return /* @__PURE__ */ import_react4.default.createElement("div", { ref, className: cx("px-6 py-4", className), ...props }, isBodyLoading ? /* @__PURE__ */ import_react4.default.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-4 w-full" }), /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-4 w-full" }), /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "h-4 w-3/4" })) : children);
349
371
  }
350
372
  );
351
373
  CardBody.displayName = "CardBody";
@@ -381,13 +403,14 @@ var CardMedia = import_react4.default.forwardRef(
381
403
  children,
382
404
  ...props
383
405
  }, ref) => {
384
- const { isLoading } = useCardContext();
406
+ const { loading } = useCardContext();
407
+ const isMediaLoading = slotLoading(loading, "media");
385
408
  const aspectClass = aspect && aspect !== "none" ? {
386
409
  video: "aspect-video",
387
410
  square: "aspect-square",
388
411
  wide: "aspect-wide"
389
412
  }[aspect] : "";
390
- if (!children && !isLoading) {
413
+ if (!children && !isMediaLoading) {
391
414
  return null;
392
415
  }
393
416
  return /* @__PURE__ */ import_react4.default.createElement(
@@ -403,7 +426,7 @@ var CardMedia = import_react4.default.forwardRef(
403
426
  ),
404
427
  ...props
405
428
  },
406
- isLoading && !children ? /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "w-full h-full" }) : children
429
+ isMediaLoading ? /* @__PURE__ */ import_react4.default.createElement(Skeleton, { className: "w-full h-full" }) : children
407
430
  );
408
431
  }
409
432
  );
@@ -2319,7 +2342,7 @@ var Modal = ({ isOpen, onClose, title, children, className }) => {
2319
2342
  role: "dialog",
2320
2343
  "aria-modal": "true",
2321
2344
  className: cx(
2322
- "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",
2323
2346
  className
2324
2347
  ),
2325
2348
  "data-state": "open",
@@ -2334,7 +2357,7 @@ var Modal = ({ isOpen, onClose, title, children, className }) => {
2334
2357
  /* @__PURE__ */ import_react30.default.createElement(import_lucide_react5.X, { className: "h-5 w-5" }),
2335
2358
  /* @__PURE__ */ import_react30.default.createElement("span", { className: "sr-only" }, "Close")
2336
2359
  )),
2337
- /* @__PURE__ */ import_react30.default.createElement("div", null, children)
2360
+ /* @__PURE__ */ import_react30.default.createElement("div", { className: "overflow-y-auto min-h-0" }, children)
2338
2361
  )
2339
2362
  );
2340
2363
  return (0, import_react_dom2.createPortal)(content, document.body);
@@ -3596,9 +3619,9 @@ function LayersIcon({ className, ...props }) {
3596
3619
  );
3597
3620
  }
3598
3621
 
3599
- // src/components/icons/PlusIcon.tsx
3622
+ // src/components/icons/MediaIcon.tsx
3600
3623
  var import_react47 = __toESM(require("react"));
3601
- function PlusIcon({ className, ...props }) {
3624
+ function MediaIcon({ className, ...props }) {
3602
3625
  return /* @__PURE__ */ import_react47.default.createElement(
3603
3626
  "svg",
3604
3627
  {
@@ -3609,6 +3632,29 @@ function PlusIcon({ className, ...props }) {
3609
3632
  ...props
3610
3633
  },
3611
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(
3612
3658
  "path",
3613
3659
  {
3614
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"
@@ -3618,9 +3664,9 @@ function PlusIcon({ className, ...props }) {
3618
3664
  }
3619
3665
 
3620
3666
  // src/components/icons/CheckSquareIcon.tsx
3621
- var import_react48 = __toESM(require("react"));
3667
+ var import_react49 = __toESM(require("react"));
3622
3668
  function CheckSquareIcon({ className, ...props }) {
3623
- return /* @__PURE__ */ import_react48.default.createElement(
3669
+ return /* @__PURE__ */ import_react49.default.createElement(
3624
3670
  "div",
3625
3671
  {
3626
3672
  className: cx(
@@ -3629,14 +3675,14 @@ function CheckSquareIcon({ className, ...props }) {
3629
3675
  ),
3630
3676
  ...props
3631
3677
  },
3632
- /* @__PURE__ */ import_react48.default.createElement(
3678
+ /* @__PURE__ */ import_react49.default.createElement(
3633
3679
  "svg",
3634
3680
  {
3635
3681
  viewBox: "0 0 16 16",
3636
3682
  fill: "none",
3637
3683
  className: "absolute inset-0 w-full h-full p-0.5"
3638
3684
  },
3639
- /* @__PURE__ */ import_react48.default.createElement(
3685
+ /* @__PURE__ */ import_react49.default.createElement(
3640
3686
  "path",
3641
3687
  {
3642
3688
  d: "M3 8l3 3 7-7",
@@ -3652,9 +3698,9 @@ function CheckSquareIcon({ className, ...props }) {
3652
3698
  }
3653
3699
 
3654
3700
  // src/components/icons/EmptySquareIcon.tsx
3655
- var import_react49 = __toESM(require("react"));
3701
+ var import_react50 = __toESM(require("react"));
3656
3702
  function EmptySquareIcon({ className, ...props }) {
3657
- return /* @__PURE__ */ import_react49.default.createElement(
3703
+ return /* @__PURE__ */ import_react50.default.createElement(
3658
3704
  "div",
3659
3705
  {
3660
3706
  className: cx(
@@ -3667,9 +3713,9 @@ function EmptySquareIcon({ className, ...props }) {
3667
3713
  }
3668
3714
 
3669
3715
  // src/components/icons/CrossSquareIcon.tsx
3670
- var import_react50 = __toESM(require("react"));
3716
+ var import_react51 = __toESM(require("react"));
3671
3717
  function CrossSquareIcon({ className, variant = "cancelled", ...props }) {
3672
- return /* @__PURE__ */ import_react50.default.createElement(
3718
+ return /* @__PURE__ */ import_react51.default.createElement(
3673
3719
  "div",
3674
3720
  {
3675
3721
  className: cx(
@@ -3679,14 +3725,14 @@ function CrossSquareIcon({ className, variant = "cancelled", ...props }) {
3679
3725
  ),
3680
3726
  ...props
3681
3727
  },
3682
- /* @__PURE__ */ import_react50.default.createElement(
3728
+ /* @__PURE__ */ import_react51.default.createElement(
3683
3729
  "svg",
3684
3730
  {
3685
3731
  viewBox: "0 0 16 16",
3686
3732
  fill: "none",
3687
3733
  className: "absolute inset-0 w-full h-full p-0.5"
3688
3734
  },
3689
- /* @__PURE__ */ import_react50.default.createElement(
3735
+ /* @__PURE__ */ import_react51.default.createElement(
3690
3736
  "path",
3691
3737
  {
3692
3738
  d: "M4 4l8 8M12 4l-8 8",
@@ -3701,15 +3747,15 @@ function CrossSquareIcon({ className, variant = "cancelled", ...props }) {
3701
3747
  }
3702
3748
 
3703
3749
  // src/components/icons/SquareLoaderIcon.tsx
3704
- var import_react51 = __toESM(require("react"));
3750
+ var import_react52 = __toESM(require("react"));
3705
3751
  function SquareLoaderIcon({ className, ...props }) {
3706
- 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(
3707
3753
  "svg",
3708
3754
  {
3709
3755
  viewBox: "0 0 16 16",
3710
3756
  className: "w-full h-full animate-snake-spin"
3711
3757
  },
3712
- /* @__PURE__ */ import_react51.default.createElement(
3758
+ /* @__PURE__ */ import_react52.default.createElement(
3713
3759
  "rect",
3714
3760
  {
3715
3761
  x: "1",
@@ -3722,7 +3768,7 @@ function SquareLoaderIcon({ className, ...props }) {
3722
3768
  className: "text-ash/40"
3723
3769
  }
3724
3770
  ),
3725
- /* @__PURE__ */ import_react51.default.createElement(
3771
+ /* @__PURE__ */ import_react52.default.createElement(
3726
3772
  "rect",
3727
3773
  {
3728
3774
  x: "1",
@@ -3741,10 +3787,10 @@ function SquareLoaderIcon({ className, ...props }) {
3741
3787
  }
3742
3788
 
3743
3789
  // src/components/Message.tsx
3744
- var import_react53 = __toESM(require("react"));
3790
+ var import_react54 = __toESM(require("react"));
3745
3791
 
3746
3792
  // src/components/MarkdownContent.tsx
3747
- var import_react52 = __toESM(require("react"));
3793
+ var import_react53 = __toESM(require("react"));
3748
3794
  var import_dompurify = __toESM(require("dompurify"));
3749
3795
  var import_marked = require("marked");
3750
3796
  var DEFAULT_SANITIZE_CONFIG = {
@@ -3815,7 +3861,7 @@ var DEFAULT_SANITIZE_CONFIG = {
3815
3861
  ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto|tel):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i
3816
3862
  };
3817
3863
  function useDOMPurifySetup() {
3818
- (0, import_react52.useMemo)(() => {
3864
+ (0, import_react53.useMemo)(() => {
3819
3865
  import_dompurify.default.addHook("afterSanitizeAttributes", (node) => {
3820
3866
  if (node.tagName === "A") {
3821
3867
  node.setAttribute("target", "_blank");
@@ -3851,10 +3897,10 @@ function injectStreamingCursor(html, cursorClassName) {
3851
3897
  target.insertAdjacentHTML("beforeend", cursorHtml);
3852
3898
  return container.innerHTML;
3853
3899
  }
3854
- var MarkdownContent = import_react52.default.forwardRef(
3900
+ var MarkdownContent = import_react53.default.forwardRef(
3855
3901
  ({ className, content, isMarkdown = true, sanitizeConfig, isStreaming, cursorClassName, ...rest }, ref) => {
3856
3902
  useDOMPurifySetup();
3857
- const sanitizedHtml = (0, import_react52.useMemo)(() => {
3903
+ const sanitizedHtml = (0, import_react53.useMemo)(() => {
3858
3904
  if (!content && !isStreaming) {
3859
3905
  return "";
3860
3906
  }
@@ -3876,7 +3922,7 @@ var MarkdownContent = import_react52.default.forwardRef(
3876
3922
  }
3877
3923
  return sanitized;
3878
3924
  }, [content, sanitizeConfig, isStreaming, cursorClassName]);
3879
- return /* @__PURE__ */ import_react52.default.createElement(
3925
+ return /* @__PURE__ */ import_react53.default.createElement(
3880
3926
  "div",
3881
3927
  {
3882
3928
  ref,
@@ -3894,7 +3940,7 @@ var variantStyles2 = {
3894
3940
  user: "bg-gold text-obsidian ml-auto",
3895
3941
  assistant: "bg-charcoal border border-ash text-white mr-auto"
3896
3942
  };
3897
- 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(
3898
3944
  "button",
3899
3945
  {
3900
3946
  type: "button",
@@ -3910,7 +3956,7 @@ var ActionButton = ({ onClick, label, children, className, disabled }) => /* @__
3910
3956
  },
3911
3957
  children
3912
3958
  );
3913
- var CopyIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3959
+ var CopyIcon = () => /* @__PURE__ */ import_react54.default.createElement(
3914
3960
  "svg",
3915
3961
  {
3916
3962
  xmlns: "http://www.w3.org/2000/svg",
@@ -3922,10 +3968,10 @@ var CopyIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3922
3968
  strokeLinejoin: "round",
3923
3969
  className: "w-3.5 h-3.5"
3924
3970
  },
3925
- /* @__PURE__ */ import_react53.default.createElement("rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2" }),
3926
- /* @__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" })
3927
3973
  );
3928
- var CheckIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3974
+ var CheckIcon = () => /* @__PURE__ */ import_react54.default.createElement(
3929
3975
  "svg",
3930
3976
  {
3931
3977
  xmlns: "http://www.w3.org/2000/svg",
@@ -3937,9 +3983,9 @@ var CheckIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3937
3983
  strokeLinejoin: "round",
3938
3984
  className: "w-3.5 h-3.5 text-success"
3939
3985
  },
3940
- /* @__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" })
3941
3987
  );
3942
- var PencilIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3988
+ var PencilIcon = () => /* @__PURE__ */ import_react54.default.createElement(
3943
3989
  "svg",
3944
3990
  {
3945
3991
  xmlns: "http://www.w3.org/2000/svg",
@@ -3951,10 +3997,10 @@ var PencilIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3951
3997
  strokeLinejoin: "round",
3952
3998
  className: "w-3.5 h-3.5"
3953
3999
  },
3954
- /* @__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" }),
3955
- /* @__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" })
3956
4002
  );
3957
- var RetryIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4003
+ var RetryIcon = () => /* @__PURE__ */ import_react54.default.createElement(
3958
4004
  "svg",
3959
4005
  {
3960
4006
  xmlns: "http://www.w3.org/2000/svg",
@@ -3966,12 +4012,12 @@ var RetryIcon = () => /* @__PURE__ */ import_react53.default.createElement(
3966
4012
  strokeLinejoin: "round",
3967
4013
  className: "w-3.5 h-3.5"
3968
4014
  },
3969
- /* @__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" }),
3970
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M21 3v5h-5" }),
3971
- /* @__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" }),
3972
- /* @__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" })
3973
4019
  );
3974
- var ChevronLeftIcon2 = () => /* @__PURE__ */ import_react53.default.createElement(
4020
+ var ChevronLeftIcon2 = () => /* @__PURE__ */ import_react54.default.createElement(
3975
4021
  "svg",
3976
4022
  {
3977
4023
  xmlns: "http://www.w3.org/2000/svg",
@@ -3983,9 +4029,9 @@ var ChevronLeftIcon2 = () => /* @__PURE__ */ import_react53.default.createElemen
3983
4029
  strokeLinejoin: "round",
3984
4030
  className: "w-3 h-3"
3985
4031
  },
3986
- /* @__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" })
3987
4033
  );
3988
- var ChevronRightIcon2 = () => /* @__PURE__ */ import_react53.default.createElement(
4034
+ var ChevronRightIcon2 = () => /* @__PURE__ */ import_react54.default.createElement(
3989
4035
  "svg",
3990
4036
  {
3991
4037
  xmlns: "http://www.w3.org/2000/svg",
@@ -3997,9 +4043,9 @@ var ChevronRightIcon2 = () => /* @__PURE__ */ import_react53.default.createEleme
3997
4043
  strokeLinejoin: "round",
3998
4044
  className: "w-3 h-3"
3999
4045
  },
4000
- /* @__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" })
4001
4047
  );
4002
- var GitBranchIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4048
+ var GitBranchIcon = () => /* @__PURE__ */ import_react54.default.createElement(
4003
4049
  "svg",
4004
4050
  {
4005
4051
  xmlns: "http://www.w3.org/2000/svg",
@@ -4011,12 +4057,12 @@ var GitBranchIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4011
4057
  strokeLinejoin: "round",
4012
4058
  className: "w-3 h-3 mr-0.5 text-silver/50"
4013
4059
  },
4014
- /* @__PURE__ */ import_react53.default.createElement("line", { x1: "6", x2: "6", y1: "3", y2: "15" }),
4015
- /* @__PURE__ */ import_react53.default.createElement("circle", { cx: "18", cy: "6", r: "3" }),
4016
- /* @__PURE__ */ import_react53.default.createElement("circle", { cx: "6", cy: "18", r: "3" }),
4017
- /* @__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" })
4018
4064
  );
4019
- var XIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4065
+ var XIcon = () => /* @__PURE__ */ import_react54.default.createElement(
4020
4066
  "svg",
4021
4067
  {
4022
4068
  xmlns: "http://www.w3.org/2000/svg",
@@ -4028,10 +4074,10 @@ var XIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4028
4074
  strokeLinejoin: "round",
4029
4075
  className: "w-4 h-4"
4030
4076
  },
4031
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "M18 6 6 18" }),
4032
- /* @__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" })
4033
4079
  );
4034
- var SendIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4080
+ var SendIcon = () => /* @__PURE__ */ import_react54.default.createElement(
4035
4081
  "svg",
4036
4082
  {
4037
4083
  xmlns: "http://www.w3.org/2000/svg",
@@ -4043,10 +4089,10 @@ var SendIcon = () => /* @__PURE__ */ import_react53.default.createElement(
4043
4089
  strokeLinejoin: "round",
4044
4090
  className: "w-4 h-4"
4045
4091
  },
4046
- /* @__PURE__ */ import_react53.default.createElement("path", { d: "m22 2-7 20-4-9-9-4Z" }),
4047
- /* @__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" })
4048
4094
  );
4049
- var Message = import_react53.default.forwardRef(
4095
+ var Message = import_react54.default.forwardRef(
4050
4096
  ({
4051
4097
  variant = "assistant",
4052
4098
  className,
@@ -4058,13 +4104,13 @@ var Message = import_react53.default.forwardRef(
4058
4104
  ...rest
4059
4105
  }, ref) => {
4060
4106
  const isUser = variant === "user";
4061
- const [copied, setCopied] = (0, import_react53.useState)(false);
4062
- const [isEditing, setIsEditing] = (0, import_react53.useState)(false);
4063
- const [editValue, setEditValue] = (0, import_react53.useState)(content);
4064
- 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);
4065
4111
  const showBranchNav = branchInfo && branchInfo.total > 1;
4066
4112
  const showActions = actions && !hideActions && !isStreaming;
4067
- (0, import_react53.useEffect)(() => {
4113
+ (0, import_react54.useEffect)(() => {
4068
4114
  if (isEditing && textareaRef.current) {
4069
4115
  const textarea = textareaRef.current;
4070
4116
  textarea.style.height = "auto";
@@ -4118,7 +4164,7 @@ var Message = import_react53.default.forwardRef(
4118
4164
  textarea.style.height = "auto";
4119
4165
  textarea.style.height = `${textarea.scrollHeight}px`;
4120
4166
  };
4121
- return /* @__PURE__ */ import_react53.default.createElement(
4167
+ return /* @__PURE__ */ import_react54.default.createElement(
4122
4168
  "div",
4123
4169
  {
4124
4170
  ref,
@@ -4129,7 +4175,7 @@ var Message = import_react53.default.forwardRef(
4129
4175
  ),
4130
4176
  ...rest
4131
4177
  },
4132
- 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(
4133
4179
  "textarea",
4134
4180
  {
4135
4181
  ref: textareaRef,
@@ -4139,7 +4185,7 @@ var Message = import_react53.default.forwardRef(
4139
4185
  className: "w-full bg-transparent text-obsidian px-3 py-2 pr-20 resize-none outline-none min-h-10 text-sm",
4140
4186
  rows: 1
4141
4187
  }
4142
- ), /* @__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(
4143
4189
  "button",
4144
4190
  {
4145
4191
  type: "button",
@@ -4147,8 +4193,8 @@ var Message = import_react53.default.forwardRef(
4147
4193
  className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors",
4148
4194
  "aria-label": "Cancel edit"
4149
4195
  },
4150
- /* @__PURE__ */ import_react53.default.createElement(XIcon, null)
4151
- ), /* @__PURE__ */ import_react53.default.createElement(
4196
+ /* @__PURE__ */ import_react54.default.createElement(XIcon, null)
4197
+ ), /* @__PURE__ */ import_react54.default.createElement(
4152
4198
  "button",
4153
4199
  {
4154
4200
  type: "button",
@@ -4157,8 +4203,8 @@ var Message = import_react53.default.forwardRef(
4157
4203
  className: "p-1.5 text-obsidian/60 hover:text-obsidian transition-colors disabled:opacity-30",
4158
4204
  "aria-label": "Submit edit"
4159
4205
  },
4160
- /* @__PURE__ */ import_react53.default.createElement(SendIcon, null)
4161
- )))) : /* @__PURE__ */ import_react53.default.createElement(
4206
+ /* @__PURE__ */ import_react54.default.createElement(SendIcon, null)
4207
+ )))) : /* @__PURE__ */ import_react54.default.createElement(
4162
4208
  "div",
4163
4209
  {
4164
4210
  className: cx(
@@ -4166,7 +4212,7 @@ var Message = import_react53.default.forwardRef(
4166
4212
  variantStyles2[variant]
4167
4213
  )
4168
4214
  },
4169
- /* @__PURE__ */ import_react53.default.createElement(
4215
+ /* @__PURE__ */ import_react54.default.createElement(
4170
4216
  MarkdownContent,
4171
4217
  {
4172
4218
  content,
@@ -4176,17 +4222,17 @@ var Message = import_react53.default.forwardRef(
4176
4222
  }
4177
4223
  )
4178
4224
  ),
4179
- showActions && !isEditing && /* @__PURE__ */ import_react53.default.createElement("div", { className: cx(
4225
+ showActions && !isEditing && /* @__PURE__ */ import_react54.default.createElement("div", { className: cx(
4180
4226
  "flex items-center gap-0.5 mt-1",
4181
4227
  isUser ? "mr-1" : "ml-1"
4182
- ) }, actions.showCopy !== false && /* @__PURE__ */ import_react53.default.createElement(
4228
+ ) }, actions.showCopy !== false && /* @__PURE__ */ import_react54.default.createElement(
4183
4229
  ActionButton,
4184
4230
  {
4185
4231
  onClick: handleCopy,
4186
4232
  label: copied ? "Copied!" : "Copy message"
4187
4233
  },
4188
- copied ? /* @__PURE__ */ import_react53.default.createElement(CheckIcon, null) : /* @__PURE__ */ import_react53.default.createElement(CopyIcon, null)
4189
- ), 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(
4190
4236
  "button",
4191
4237
  {
4192
4238
  type: "button",
@@ -4198,8 +4244,8 @@ var Message = import_react53.default.forwardRef(
4198
4244
  ),
4199
4245
  "aria-label": "Previous branch"
4200
4246
  },
4201
- /* @__PURE__ */ import_react53.default.createElement(ChevronLeftIcon2, null)
4202
- ), /* @__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(
4203
4249
  "button",
4204
4250
  {
4205
4251
  type: "button",
@@ -4211,7 +4257,7 @@ var Message = import_react53.default.forwardRef(
4211
4257
  ),
4212
4258
  "aria-label": "Next branch"
4213
4259
  },
4214
- /* @__PURE__ */ import_react53.default.createElement(ChevronRightIcon2, null)
4260
+ /* @__PURE__ */ import_react54.default.createElement(ChevronRightIcon2, null)
4215
4261
  ))))
4216
4262
  );
4217
4263
  }
@@ -4219,15 +4265,15 @@ var Message = import_react53.default.forwardRef(
4219
4265
  Message.displayName = "Message";
4220
4266
 
4221
4267
  // src/components/StreamingCursor.tsx
4222
- var import_react54 = __toESM(require("react"));
4223
- var StreamingCursor = import_react54.default.forwardRef(
4268
+ var import_react55 = __toESM(require("react"));
4269
+ var StreamingCursor = import_react55.default.forwardRef(
4224
4270
  ({ className, variant = "line", ...rest }, ref) => {
4225
4271
  const variantStyles3 = {
4226
4272
  block: "w-2.5 h-cursor translate-y-cursor-offset",
4227
4273
  line: "w-0.5 h-cursor translate-y-cursor-offset",
4228
4274
  underscore: "w-2.5 h-0.5 self-end mb-0.5"
4229
4275
  };
4230
- return /* @__PURE__ */ import_react54.default.createElement(
4276
+ return /* @__PURE__ */ import_react55.default.createElement(
4231
4277
  "span",
4232
4278
  {
4233
4279
  ref,
@@ -4245,18 +4291,18 @@ var StreamingCursor = import_react54.default.forwardRef(
4245
4291
  StreamingCursor.displayName = "StreamingCursor";
4246
4292
 
4247
4293
  // src/components/chat/ChatInterface.tsx
4248
- var import_react72 = __toESM(require("react"));
4294
+ var import_react78 = __toESM(require("react"));
4249
4295
 
4250
4296
  // src/components/chat/ChatView.tsx
4251
- var import_react58 = __toESM(require("react"));
4297
+ var import_react59 = __toESM(require("react"));
4252
4298
 
4253
4299
  // src/components/chat/hooks/useScrollAnchor.ts
4254
- var import_react55 = require("react");
4300
+ var import_react56 = require("react");
4255
4301
  function useScrollAnchor(options = {}) {
4256
4302
  const { behavior = "smooth", block = "start" } = options;
4257
- const containerRef = (0, import_react55.useRef)(null);
4258
- const anchorRef = (0, import_react55.useRef)(null);
4259
- 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)(() => {
4260
4306
  const el = anchorRef.current;
4261
4307
  if (!el) {
4262
4308
  return;
@@ -4267,7 +4313,7 @@ function useScrollAnchor(options = {}) {
4267
4313
  });
4268
4314
  });
4269
4315
  }, [behavior, block]);
4270
- const scrollToBottom = (0, import_react55.useCallback)(() => {
4316
+ const scrollToBottom = (0, import_react56.useCallback)(() => {
4271
4317
  const container = containerRef.current;
4272
4318
  if (!container) {
4273
4319
  return;
@@ -4278,7 +4324,7 @@ function useScrollAnchor(options = {}) {
4278
4324
  container.scrollTop = container.scrollHeight;
4279
4325
  }
4280
4326
  }, [behavior]);
4281
- const isScrolledToBottom = (0, import_react55.useCallback)(() => {
4327
+ const isScrolledToBottom = (0, import_react56.useCallback)(() => {
4282
4328
  const container = containerRef.current;
4283
4329
  if (!container) {
4284
4330
  return true;
@@ -4297,15 +4343,15 @@ function useScrollAnchor(options = {}) {
4297
4343
  }
4298
4344
 
4299
4345
  // src/components/chat/hooks/useAdaptiveSpacer.ts
4300
- var import_react56 = require("react");
4346
+ var import_react57 = require("react");
4301
4347
  function useAdaptiveSpacer(options = {}) {
4302
4348
  const { minHeight = 0, containerRef: externalContainerRef, anchorRef } = options;
4303
- const internalContainerRef = (0, import_react56.useRef)(null);
4349
+ const internalContainerRef = (0, import_react57.useRef)(null);
4304
4350
  const containerRef = externalContainerRef ?? internalContainerRef;
4305
- const contentRef = (0, import_react56.useRef)(null);
4306
- const spacerRef = (0, import_react56.useRef)(null);
4307
- const [spacerHeight, setSpacerHeight] = (0, import_react56.useState)(0);
4308
- 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)(() => {
4309
4355
  const container = containerRef.current;
4310
4356
  const content = contentRef.current;
4311
4357
  if (!container || !content) {
@@ -4329,7 +4375,7 @@ function useAdaptiveSpacer(options = {}) {
4329
4375
  }
4330
4376
  setSpacerHeight(newSpacerHeight);
4331
4377
  }, [minHeight, anchorRef]);
4332
- (0, import_react56.useEffect)(() => {
4378
+ (0, import_react57.useEffect)(() => {
4333
4379
  const container = containerRef.current;
4334
4380
  const content = contentRef.current;
4335
4381
  if (!container || !content) {
@@ -4364,7 +4410,7 @@ function useAdaptiveSpacer(options = {}) {
4364
4410
  }
4365
4411
 
4366
4412
  // src/components/chat/ThinkingIndicator.tsx
4367
- var import_react57 = __toESM(require("react"));
4413
+ var import_react58 = __toESM(require("react"));
4368
4414
  var THINKING_PHRASES = [
4369
4415
  "Consulting the ancient tomes...",
4370
4416
  "Parsing the ineffable...",
@@ -4380,7 +4426,7 @@ var THINKING_PHRASES = [
4380
4426
  "Consulting my inner monologue...",
4381
4427
  "Summoning the muse..."
4382
4428
  ];
4383
- var ThinkingIndicator = import_react57.default.forwardRef(
4429
+ var ThinkingIndicator = import_react58.default.forwardRef(
4384
4430
  ({
4385
4431
  isVisible = true,
4386
4432
  phraseInterval = 2500,
@@ -4388,11 +4434,11 @@ var ThinkingIndicator = import_react57.default.forwardRef(
4388
4434
  className,
4389
4435
  ...rest
4390
4436
  }, ref) => {
4391
- const [currentIndex, setCurrentIndex] = (0, import_react57.useState)(
4437
+ const [currentIndex, setCurrentIndex] = (0, import_react58.useState)(
4392
4438
  () => Math.floor(Math.random() * phrases.length)
4393
4439
  );
4394
- const [isTransitioning, setIsTransitioning] = (0, import_react57.useState)(false);
4395
- (0, import_react57.useEffect)(() => {
4440
+ const [isTransitioning, setIsTransitioning] = (0, import_react58.useState)(false);
4441
+ (0, import_react58.useEffect)(() => {
4396
4442
  if (!isVisible || phrases.length <= 1) {
4397
4443
  return;
4398
4444
  }
@@ -4408,7 +4454,7 @@ var ThinkingIndicator = import_react57.default.forwardRef(
4408
4454
  if (!isVisible) {
4409
4455
  return null;
4410
4456
  }
4411
- return /* @__PURE__ */ import_react57.default.createElement(
4457
+ return /* @__PURE__ */ import_react58.default.createElement(
4412
4458
  "div",
4413
4459
  {
4414
4460
  ref,
@@ -4422,26 +4468,26 @@ var ThinkingIndicator = import_react57.default.forwardRef(
4422
4468
  "aria-live": "polite",
4423
4469
  ...rest
4424
4470
  },
4425
- /* @__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(
4426
4472
  "span",
4427
4473
  {
4428
4474
  className: "w-1.5 h-1.5 bg-gold/60 rounded-full animate-pulse",
4429
4475
  style: { animationDelay: "0ms" }
4430
4476
  }
4431
- ), /* @__PURE__ */ import_react57.default.createElement(
4477
+ ), /* @__PURE__ */ import_react58.default.createElement(
4432
4478
  "span",
4433
4479
  {
4434
4480
  className: "w-1.5 h-1.5 bg-gold/60 rounded-full animate-pulse",
4435
4481
  style: { animationDelay: "150ms" }
4436
4482
  }
4437
- ), /* @__PURE__ */ import_react57.default.createElement(
4483
+ ), /* @__PURE__ */ import_react58.default.createElement(
4438
4484
  "span",
4439
4485
  {
4440
4486
  className: "w-1.5 h-1.5 bg-gold/60 rounded-full animate-pulse",
4441
4487
  style: { animationDelay: "300ms" }
4442
4488
  }
4443
4489
  )),
4444
- /* @__PURE__ */ import_react57.default.createElement(
4490
+ /* @__PURE__ */ import_react58.default.createElement(
4445
4491
  "span",
4446
4492
  {
4447
4493
  className: cx(
@@ -4457,7 +4503,7 @@ var ThinkingIndicator = import_react57.default.forwardRef(
4457
4503
  ThinkingIndicator.displayName = "ThinkingIndicator";
4458
4504
 
4459
4505
  // src/components/chat/ChatView.tsx
4460
- var ChatView = import_react58.default.forwardRef(
4506
+ var ChatView = import_react59.default.forwardRef(
4461
4507
  ({ messages, latestUserMessageIndex, isStreaming, isThinking, onScroll, className, ...rest }, ref) => {
4462
4508
  const { containerRef, anchorRef, scrollToAnchor } = useScrollAnchor({
4463
4509
  behavior: "smooth",
@@ -4467,7 +4513,7 @@ var ChatView = import_react58.default.forwardRef(
4467
4513
  containerRef,
4468
4514
  anchorRef
4469
4515
  });
4470
- (0, import_react58.useEffect)(() => {
4516
+ (0, import_react59.useEffect)(() => {
4471
4517
  if (latestUserMessageIndex !== void 0 && latestUserMessageIndex >= 0) {
4472
4518
  scrollToAnchor();
4473
4519
  }
@@ -4479,7 +4525,7 @@ var ChatView = import_react58.default.forwardRef(
4479
4525
  return found;
4480
4526
  }, -1);
4481
4527
  const showThinking = isThinking && messages.length > 0 && messages[messages.length - 1]?.variant === "user";
4482
- return /* @__PURE__ */ import_react58.default.createElement(
4528
+ return /* @__PURE__ */ import_react59.default.createElement(
4483
4529
  "div",
4484
4530
  {
4485
4531
  ref: (node) => {
@@ -4499,7 +4545,7 @@ var ChatView = import_react58.default.forwardRef(
4499
4545
  ),
4500
4546
  ...rest
4501
4547
  },
4502
- /* @__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(({
4503
4549
  id,
4504
4550
  variant,
4505
4551
  className: messageClassName,
@@ -4512,14 +4558,14 @@ var ChatView = import_react58.default.forwardRef(
4512
4558
  const isLastMessage = index === messages.length - 1;
4513
4559
  const showStreaming = isLastMessage && isStreaming && variant === "assistant";
4514
4560
  const isMessageStreaming = showStreaming || !!nodeIsStreaming;
4515
- return /* @__PURE__ */ import_react58.default.createElement(
4561
+ return /* @__PURE__ */ import_react59.default.createElement(
4516
4562
  "div",
4517
4563
  {
4518
4564
  key: id ?? `msg-${index}`,
4519
4565
  ref: isAnchor ? anchorRef : void 0,
4520
4566
  className: isAnchor ? "scroll-mt-4" : void 0
4521
4567
  },
4522
- /* @__PURE__ */ import_react58.default.createElement(
4568
+ /* @__PURE__ */ import_react59.default.createElement(
4523
4569
  Message,
4524
4570
  {
4525
4571
  variant,
@@ -4532,8 +4578,8 @@ var ChatView = import_react58.default.forwardRef(
4532
4578
  }
4533
4579
  )
4534
4580
  );
4535
- }), showThinking && /* @__PURE__ */ import_react58.default.createElement(ThinkingIndicator, { isVisible: true })),
4536
- /* @__PURE__ */ import_react58.default.createElement(
4581
+ }), showThinking && /* @__PURE__ */ import_react59.default.createElement(ThinkingIndicator, { isVisible: true })),
4582
+ /* @__PURE__ */ import_react59.default.createElement(
4537
4583
  "div",
4538
4584
  {
4539
4585
  ref: spacerRef,
@@ -4548,7 +4594,7 @@ var ChatView = import_react58.default.forwardRef(
4548
4594
  ChatView.displayName = "ChatView";
4549
4595
 
4550
4596
  // src/components/chat/ChatInput.tsx
4551
- var import_react59 = __toESM(require("react"));
4597
+ var import_react60 = __toESM(require("react"));
4552
4598
  var import_lucide_react11 = require("lucide-react");
4553
4599
 
4554
4600
  // src/components/chat/types.ts
@@ -4717,7 +4763,7 @@ function isBranchPoint(tree, nodeId) {
4717
4763
  }
4718
4764
 
4719
4765
  // src/components/chat/ChatInput.tsx
4720
- var ChatInput = import_react59.default.forwardRef(
4766
+ var ChatInput = import_react60.default.forwardRef(
4721
4767
  ({
4722
4768
  position = "bottom",
4723
4769
  placeholder = "Send a message...",
@@ -4734,13 +4780,13 @@ var ChatInput = import_react59.default.forwardRef(
4734
4780
  className,
4735
4781
  ...rest
4736
4782
  }, ref) => {
4737
- const [value, setValue] = (0, import_react59.useState)("");
4738
- const [localAttachments, setLocalAttachments] = (0, import_react59.useState)([]);
4739
- const [isDragOver, setIsDragOver] = (0, import_react59.useState)(false);
4740
- const textareaRef = (0, import_react59.useRef)(null);
4741
- 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);
4742
4788
  const attachments = controlledAttachments ?? localAttachments;
4743
- const setAttachments = (0, import_react59.useCallback)(
4789
+ const setAttachments = (0, import_react60.useCallback)(
4744
4790
  (newAttachments) => {
4745
4791
  if (onAttachmentsChange) {
4746
4792
  if (typeof newAttachments === "function") {
@@ -4754,7 +4800,7 @@ var ChatInput = import_react59.default.forwardRef(
4754
4800
  },
4755
4801
  [attachments, onAttachmentsChange]
4756
4802
  );
4757
- const handleSubmit = (0, import_react59.useCallback)(() => {
4803
+ const handleSubmit = (0, import_react60.useCallback)(() => {
4758
4804
  const trimmed = value.trim();
4759
4805
  if (!trimmed || disabled || isStreaming) {
4760
4806
  return;
@@ -4766,7 +4812,7 @@ var ChatInput = import_react59.default.forwardRef(
4766
4812
  textareaRef.current.style.height = "auto";
4767
4813
  }
4768
4814
  }, [value, disabled, isStreaming, onSubmit, attachments, setAttachments]);
4769
- const handleKeyDown = (0, import_react59.useCallback)(
4815
+ const handleKeyDown = (0, import_react60.useCallback)(
4770
4816
  (e) => {
4771
4817
  if (e.key === "Enter" && !e.shiftKey) {
4772
4818
  e.preventDefault();
@@ -4775,18 +4821,18 @@ var ChatInput = import_react59.default.forwardRef(
4775
4821
  },
4776
4822
  [handleSubmit]
4777
4823
  );
4778
- const handleChange = (0, import_react59.useCallback)((e) => {
4824
+ const handleChange = (0, import_react60.useCallback)((e) => {
4779
4825
  setValue(e.target.value);
4780
4826
  const textarea = e.target;
4781
4827
  textarea.style.height = "auto";
4782
4828
  textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`;
4783
4829
  }, []);
4784
- (0, import_react59.useEffect)(() => {
4830
+ (0, import_react60.useEffect)(() => {
4785
4831
  if (!disabled && !isStreaming && textareaRef.current) {
4786
4832
  textareaRef.current.focus();
4787
4833
  }
4788
4834
  }, [disabled, isStreaming]);
4789
- const addFiles = (0, import_react59.useCallback)(
4835
+ const addFiles = (0, import_react60.useCallback)(
4790
4836
  (files) => {
4791
4837
  const newAttachments = Array.from(files).map((file) => ({
4792
4838
  id: generateId(),
@@ -4798,7 +4844,7 @@ var ChatInput = import_react59.default.forwardRef(
4798
4844
  },
4799
4845
  [setAttachments]
4800
4846
  );
4801
- const handleFileSelect = (0, import_react59.useCallback)(
4847
+ const handleFileSelect = (0, import_react60.useCallback)(
4802
4848
  (e) => {
4803
4849
  const files = e.target.files;
4804
4850
  if (files && files.length > 0) {
@@ -4808,7 +4854,7 @@ var ChatInput = import_react59.default.forwardRef(
4808
4854
  },
4809
4855
  [addFiles]
4810
4856
  );
4811
- const handleRemoveAttachment = (0, import_react59.useCallback)(
4857
+ const handleRemoveAttachment = (0, import_react60.useCallback)(
4812
4858
  (id) => {
4813
4859
  setAttachments((prev) => {
4814
4860
  const attachment = prev.find((a) => a.id === id);
@@ -4820,23 +4866,23 @@ var ChatInput = import_react59.default.forwardRef(
4820
4866
  },
4821
4867
  [setAttachments]
4822
4868
  );
4823
- const handleDragEnter = (0, import_react59.useCallback)((e) => {
4869
+ const handleDragEnter = (0, import_react60.useCallback)((e) => {
4824
4870
  e.preventDefault();
4825
4871
  e.stopPropagation();
4826
4872
  setIsDragOver(true);
4827
4873
  }, []);
4828
- const handleDragLeave = (0, import_react59.useCallback)((e) => {
4874
+ const handleDragLeave = (0, import_react60.useCallback)((e) => {
4829
4875
  e.preventDefault();
4830
4876
  e.stopPropagation();
4831
4877
  if (!e.currentTarget.contains(e.relatedTarget)) {
4832
4878
  setIsDragOver(false);
4833
4879
  }
4834
4880
  }, []);
4835
- const handleDragOver = (0, import_react59.useCallback)((e) => {
4881
+ const handleDragOver = (0, import_react60.useCallback)((e) => {
4836
4882
  e.preventDefault();
4837
4883
  e.stopPropagation();
4838
4884
  }, []);
4839
- const handleDrop = (0, import_react59.useCallback)(
4885
+ const handleDrop = (0, import_react60.useCallback)(
4840
4886
  (e) => {
4841
4887
  e.preventDefault();
4842
4888
  e.stopPropagation();
@@ -4851,7 +4897,7 @@ var ChatInput = import_react59.default.forwardRef(
4851
4897
  const isCentered = position === "centered";
4852
4898
  const hasAttachments = attachments.length > 0;
4853
4899
  const canSubmit = value.trim() && !disabled && !isStreaming;
4854
- return /* @__PURE__ */ import_react59.default.createElement(
4900
+ return /* @__PURE__ */ import_react60.default.createElement(
4855
4901
  "div",
4856
4902
  {
4857
4903
  ref,
@@ -4863,8 +4909,8 @@ var ChatInput = import_react59.default.forwardRef(
4863
4909
  ),
4864
4910
  ...rest
4865
4911
  },
4866
- isCentered && helperText && /* @__PURE__ */ import_react59.default.createElement("p", { className: "text-silver text-sm mb-4 text-center" }, helperText),
4867
- /* @__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(
4868
4914
  "div",
4869
4915
  {
4870
4916
  className: cx(
@@ -4879,7 +4925,7 @@ var ChatInput = import_react59.default.forwardRef(
4879
4925
  onDragOver: showAttachmentButton ? handleDragOver : void 0,
4880
4926
  onDrop: showAttachmentButton ? handleDrop : void 0
4881
4927
  },
4882
- 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(
4883
4929
  AttachmentPreview,
4884
4930
  {
4885
4931
  attachments,
@@ -4887,14 +4933,14 @@ var ChatInput = import_react59.default.forwardRef(
4887
4933
  removable: !isStreaming
4888
4934
  }
4889
4935
  )),
4890
- isDragOver && /* @__PURE__ */ import_react59.default.createElement(
4936
+ isDragOver && /* @__PURE__ */ import_react60.default.createElement(
4891
4937
  "div",
4892
4938
  {
4893
4939
  className: "absolute inset-0 bg-gold/10 flex items-center justify-center z-10 pointer-events-none"
4894
4940
  },
4895
- /* @__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")
4896
4942
  ),
4897
- /* @__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(
4898
4944
  "button",
4899
4945
  {
4900
4946
  type: "button",
@@ -4906,8 +4952,8 @@ var ChatInput = import_react59.default.forwardRef(
4906
4952
  ),
4907
4953
  "aria-label": "Attach file"
4908
4954
  },
4909
- /* @__PURE__ */ import_react59.default.createElement(import_lucide_react11.Paperclip, { className: "w-5 h-5" })
4910
- ), /* @__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(
4911
4957
  "input",
4912
4958
  {
4913
4959
  ref: fileInputRef,
@@ -4918,7 +4964,7 @@ var ChatInput = import_react59.default.forwardRef(
4918
4964
  className: "hidden",
4919
4965
  "aria-hidden": "true"
4920
4966
  }
4921
- )), /* @__PURE__ */ import_react59.default.createElement(
4967
+ )), /* @__PURE__ */ import_react60.default.createElement(
4922
4968
  "textarea",
4923
4969
  {
4924
4970
  ref: textareaRef,
@@ -4936,7 +4982,7 @@ var ChatInput = import_react59.default.forwardRef(
4936
4982
  ),
4937
4983
  style: { maxHeight: 200 }
4938
4984
  }
4939
- ), isStreaming ? /* @__PURE__ */ import_react59.default.createElement(
4985
+ ), isStreaming ? /* @__PURE__ */ import_react60.default.createElement(
4940
4986
  "button",
4941
4987
  {
4942
4988
  type: "button",
@@ -4947,8 +4993,8 @@ var ChatInput = import_react59.default.forwardRef(
4947
4993
  ),
4948
4994
  "aria-label": "Stop generation"
4949
4995
  },
4950
- /* @__PURE__ */ import_react59.default.createElement(import_lucide_react11.Square, { className: "w-5 h-5 fill-current" })
4951
- ) : /* @__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(
4952
4998
  "button",
4953
4999
  {
4954
5000
  type: "button",
@@ -4961,7 +5007,7 @@ var ChatInput = import_react59.default.forwardRef(
4961
5007
  ),
4962
5008
  "aria-label": "Send message"
4963
5009
  },
4964
- /* @__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" })
4965
5011
  ))
4966
5012
  )
4967
5013
  );
@@ -4970,9 +5016,9 @@ var ChatInput = import_react59.default.forwardRef(
4970
5016
  ChatInput.displayName = "ChatInput";
4971
5017
 
4972
5018
  // src/components/chat/ConversationSidebar.tsx
4973
- var import_react60 = __toESM(require("react"));
5019
+ var import_react61 = __toESM(require("react"));
4974
5020
  function HistoryIcon2({ className }) {
4975
- return /* @__PURE__ */ import_react60.default.createElement(
5021
+ return /* @__PURE__ */ import_react61.default.createElement(
4976
5022
  "svg",
4977
5023
  {
4978
5024
  xmlns: "http://www.w3.org/2000/svg",
@@ -4980,7 +5026,7 @@ function HistoryIcon2({ className }) {
4980
5026
  fill: "currentColor",
4981
5027
  className
4982
5028
  },
4983
- /* @__PURE__ */ import_react60.default.createElement(
5029
+ /* @__PURE__ */ import_react61.default.createElement(
4984
5030
  "path",
4985
5031
  {
4986
5032
  fillRule: "evenodd",
@@ -4991,7 +5037,7 @@ function HistoryIcon2({ className }) {
4991
5037
  );
4992
5038
  }
4993
5039
  function ChevronLeftIcon3({ className }) {
4994
- return /* @__PURE__ */ import_react60.default.createElement(
5040
+ return /* @__PURE__ */ import_react61.default.createElement(
4995
5041
  "svg",
4996
5042
  {
4997
5043
  xmlns: "http://www.w3.org/2000/svg",
@@ -4999,7 +5045,7 @@ function ChevronLeftIcon3({ className }) {
4999
5045
  fill: "currentColor",
5000
5046
  className
5001
5047
  },
5002
- /* @__PURE__ */ import_react60.default.createElement(
5048
+ /* @__PURE__ */ import_react61.default.createElement(
5003
5049
  "path",
5004
5050
  {
5005
5051
  fillRule: "evenodd",
@@ -5009,7 +5055,7 @@ function ChevronLeftIcon3({ className }) {
5009
5055
  )
5010
5056
  );
5011
5057
  }
5012
- var ConversationSidebar = import_react60.default.forwardRef(
5058
+ var ConversationSidebar = import_react61.default.forwardRef(
5013
5059
  ({
5014
5060
  conversations,
5015
5061
  isCollapsed = false,
@@ -5022,7 +5068,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5022
5068
  ...rest
5023
5069
  }, ref) => {
5024
5070
  if (isCollapsed) {
5025
- return /* @__PURE__ */ import_react60.default.createElement(
5071
+ return /* @__PURE__ */ import_react61.default.createElement(
5026
5072
  "div",
5027
5073
  {
5028
5074
  ref,
@@ -5033,7 +5079,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5033
5079
  ),
5034
5080
  ...rest
5035
5081
  },
5036
- /* @__PURE__ */ import_react60.default.createElement(
5082
+ /* @__PURE__ */ import_react61.default.createElement(
5037
5083
  "button",
5038
5084
  {
5039
5085
  onClick: onToggleCollapse,
@@ -5044,11 +5090,11 @@ var ConversationSidebar = import_react60.default.forwardRef(
5044
5090
  ),
5045
5091
  "aria-label": "Expand sidebar"
5046
5092
  },
5047
- /* @__PURE__ */ import_react60.default.createElement(HistoryIcon2, { className: "w-5 h-5" })
5093
+ /* @__PURE__ */ import_react61.default.createElement(HistoryIcon2, { className: "w-5 h-5" })
5048
5094
  )
5049
5095
  );
5050
5096
  }
5051
- return /* @__PURE__ */ import_react60.default.createElement(
5097
+ return /* @__PURE__ */ import_react61.default.createElement(
5052
5098
  "div",
5053
5099
  {
5054
5100
  ref,
@@ -5062,7 +5108,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5062
5108
  style: width ? { width } : void 0,
5063
5109
  ...rest
5064
5110
  },
5065
- /* @__PURE__ */ import_react60.default.createElement(
5111
+ /* @__PURE__ */ import_react61.default.createElement(
5066
5112
  "div",
5067
5113
  {
5068
5114
  onMouseDown: onResizeStart,
@@ -5075,7 +5121,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5075
5121
  )
5076
5122
  }
5077
5123
  ),
5078
- /* @__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(
5079
5125
  "button",
5080
5126
  {
5081
5127
  onClick: onToggleCollapse,
@@ -5086,8 +5132,8 @@ var ConversationSidebar = import_react60.default.forwardRef(
5086
5132
  ),
5087
5133
  "aria-label": "Collapse sidebar"
5088
5134
  },
5089
- /* @__PURE__ */ import_react60.default.createElement(ChevronLeftIcon3, { className: "w-5 h-5" })
5090
- ), /* @__PURE__ */ import_react60.default.createElement(
5135
+ /* @__PURE__ */ import_react61.default.createElement(ChevronLeftIcon3, { className: "w-5 h-5" })
5136
+ ), /* @__PURE__ */ import_react61.default.createElement(
5091
5137
  "button",
5092
5138
  {
5093
5139
  onClick: onNewChat,
@@ -5099,7 +5145,7 @@ var ConversationSidebar = import_react60.default.forwardRef(
5099
5145
  "transition-colors duration-200"
5100
5146
  )
5101
5147
  },
5102
- /* @__PURE__ */ import_react60.default.createElement(
5148
+ /* @__PURE__ */ import_react61.default.createElement(
5103
5149
  "svg",
5104
5150
  {
5105
5151
  xmlns: "http://www.w3.org/2000/svg",
@@ -5107,16 +5153,16 @@ var ConversationSidebar = import_react60.default.forwardRef(
5107
5153
  fill: "currentColor",
5108
5154
  className: "w-4 h-4"
5109
5155
  },
5110
- /* @__PURE__ */ import_react60.default.createElement(
5156
+ /* @__PURE__ */ import_react61.default.createElement(
5111
5157
  "path",
5112
5158
  {
5113
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"
5114
5160
  }
5115
5161
  )
5116
5162
  ),
5117
- /* @__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")
5118
5164
  )),
5119
- /* @__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(
5120
5166
  "button",
5121
5167
  {
5122
5168
  key: conversation.id,
@@ -5127,16 +5173,16 @@ var ConversationSidebar = import_react60.default.forwardRef(
5127
5173
  conversation.isActive ? "bg-ash/40 text-white" : "text-silver hover:bg-ash/20 hover:text-white"
5128
5174
  )
5129
5175
  },
5130
- /* @__PURE__ */ import_react60.default.createElement("p", { className: "text-sm font-medium truncate" }, conversation.title),
5131
- conversation.preview && /* @__PURE__ */ import_react60.default.createElement("p", { className: "text-xs text-silver/60 truncate mt-0.5" }, conversation.preview),
5132
- 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)
5133
5179
  ))))
5134
5180
  );
5135
5181
  }
5136
5182
  );
5137
5183
  ConversationSidebar.displayName = "ConversationSidebar";
5138
- var CollapsedSidebarToggle = import_react60.default.forwardRef(({ onExpand, className, ...rest }, ref) => {
5139
- return /* @__PURE__ */ import_react60.default.createElement(
5184
+ var CollapsedSidebarToggle = import_react61.default.forwardRef(({ onExpand, className, ...rest }, ref) => {
5185
+ return /* @__PURE__ */ import_react61.default.createElement(
5140
5186
  "button",
5141
5187
  {
5142
5188
  ref,
@@ -5151,19 +5197,19 @@ var CollapsedSidebarToggle = import_react60.default.forwardRef(({ onExpand, clas
5151
5197
  "aria-label": "Expand sidebar",
5152
5198
  ...rest
5153
5199
  },
5154
- /* @__PURE__ */ import_react60.default.createElement(HistoryIcon2, { className: "w-5 h-5" })
5200
+ /* @__PURE__ */ import_react61.default.createElement(HistoryIcon2, { className: "w-5 h-5" })
5155
5201
  );
5156
5202
  });
5157
5203
  CollapsedSidebarToggle.displayName = "CollapsedSidebarToggle";
5158
5204
 
5159
5205
  // src/components/chat/ArtifactsPanel.tsx
5160
- var import_react68 = __toESM(require("react"));
5206
+ var import_react72 = __toESM(require("react"));
5161
5207
 
5162
5208
  // src/components/ArtifactCard.tsx
5163
- var import_react67 = __toESM(require("react"));
5209
+ var import_react68 = __toESM(require("react"));
5164
5210
 
5165
5211
  // src/components/ImageCard.tsx
5166
- var import_react61 = __toESM(require("react"));
5212
+ var import_react62 = __toESM(require("react"));
5167
5213
  var ASPECT_RATIO_PRESETS = {
5168
5214
  landscape: "3 / 2",
5169
5215
  portrait: "2 / 3",
@@ -5175,7 +5221,7 @@ function resolveAspectRatio(ratio) {
5175
5221
  }
5176
5222
  return ratio.replace("/", " / ");
5177
5223
  }
5178
- var ImageCard = import_react61.default.forwardRef(
5224
+ var ImageCard = import_react62.default.forwardRef(
5179
5225
  ({
5180
5226
  src,
5181
5227
  alt = "",
@@ -5188,24 +5234,24 @@ var ImageCard = import_react61.default.forwardRef(
5188
5234
  contentClassName,
5189
5235
  className,
5190
5236
  children,
5191
- isLoading,
5237
+ loading,
5192
5238
  ...props
5193
5239
  }, ref) => {
5194
- return /* @__PURE__ */ import_react61.default.createElement(
5240
+ return /* @__PURE__ */ import_react62.default.createElement(
5195
5241
  Card,
5196
5242
  {
5197
5243
  ref,
5198
5244
  className: cx("p-0 overflow-hidden w-full", className),
5199
- isLoading,
5245
+ loading,
5200
5246
  ...props
5201
5247
  },
5202
- /* @__PURE__ */ import_react61.default.createElement(
5248
+ /* @__PURE__ */ import_react62.default.createElement(
5203
5249
  Card.Media,
5204
5250
  {
5205
5251
  className: mediaClassName,
5206
5252
  style: { aspectRatio: resolveAspectRatio(aspectRatio) }
5207
5253
  },
5208
- src && /* @__PURE__ */ import_react61.default.createElement(
5254
+ /* @__PURE__ */ import_react62.default.createElement(import_react62.default.Fragment, null, src && /* @__PURE__ */ import_react62.default.createElement(
5209
5255
  "img",
5210
5256
  {
5211
5257
  src,
@@ -5215,16 +5261,15 @@ var ImageCard = import_react61.default.forwardRef(
5215
5261
  objectFit === "cover" ? "object-cover" : "object-contain"
5216
5262
  )
5217
5263
  }
5218
- ),
5219
- overlay && /* @__PURE__ */ import_react61.default.createElement(
5264
+ ), overlay && /* @__PURE__ */ import_react62.default.createElement(
5220
5265
  "div",
5221
5266
  {
5222
5267
  className: "absolute inset-0 bg-obsidian/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex items-center justify-center"
5223
5268
  },
5224
5269
  overlay
5225
- )
5270
+ ))
5226
5271
  ),
5227
- /* @__PURE__ */ import_react61.default.createElement(
5272
+ /* @__PURE__ */ import_react62.default.createElement(
5228
5273
  Card.Header,
5229
5274
  {
5230
5275
  title,
@@ -5232,14 +5277,14 @@ var ImageCard = import_react61.default.forwardRef(
5232
5277
  className: contentClassName
5233
5278
  }
5234
5279
  ),
5235
- children && /* @__PURE__ */ import_react61.default.createElement(Card.Body, { className: contentClassName }, children)
5280
+ children && /* @__PURE__ */ import_react62.default.createElement(Card.Body, { className: contentClassName }, children)
5236
5281
  );
5237
5282
  }
5238
5283
  );
5239
5284
  ImageCard.displayName = "ImageCard";
5240
5285
 
5241
5286
  // src/components/VideoCard.tsx
5242
- var import_react62 = __toESM(require("react"));
5287
+ var import_react63 = __toESM(require("react"));
5243
5288
  var import_react_player = __toESM(require("react-player"));
5244
5289
  var ASPECT_RATIO_PRESETS2 = {
5245
5290
  video: "16 / 9",
@@ -5252,7 +5297,7 @@ function resolveAspectRatio2(ratio) {
5252
5297
  }
5253
5298
  return ratio.replace("/", " / ");
5254
5299
  }
5255
- var VideoCard = import_react62.default.forwardRef(
5300
+ var VideoCard = import_react63.default.forwardRef(
5256
5301
  ({
5257
5302
  src,
5258
5303
  title,
@@ -5269,24 +5314,24 @@ var VideoCard = import_react62.default.forwardRef(
5269
5314
  className,
5270
5315
  children,
5271
5316
  playerProps,
5272
- isLoading,
5317
+ loading,
5273
5318
  ...props
5274
5319
  }, ref) => {
5275
- return /* @__PURE__ */ import_react62.default.createElement(
5320
+ return /* @__PURE__ */ import_react63.default.createElement(
5276
5321
  Card,
5277
5322
  {
5278
5323
  ref,
5279
5324
  className: cx("p-0 overflow-hidden w-full", className),
5280
- isLoading,
5325
+ loading,
5281
5326
  ...props
5282
5327
  },
5283
- /* @__PURE__ */ import_react62.default.createElement(
5328
+ /* @__PURE__ */ import_react63.default.createElement(
5284
5329
  Card.Media,
5285
5330
  {
5286
5331
  className: mediaClassName,
5287
5332
  style: { aspectRatio: resolveAspectRatio2(aspectRatio) }
5288
5333
  },
5289
- src && /* @__PURE__ */ import_react62.default.createElement(
5334
+ src && /* @__PURE__ */ import_react63.default.createElement(
5290
5335
  import_react_player.default,
5291
5336
  {
5292
5337
  src,
@@ -5303,7 +5348,7 @@ var VideoCard = import_react62.default.forwardRef(
5303
5348
  }
5304
5349
  )
5305
5350
  ),
5306
- /* @__PURE__ */ import_react62.default.createElement(
5351
+ /* @__PURE__ */ import_react63.default.createElement(
5307
5352
  Card.Header,
5308
5353
  {
5309
5354
  title,
@@ -5311,17 +5356,17 @@ var VideoCard = import_react62.default.forwardRef(
5311
5356
  className: contentClassName
5312
5357
  }
5313
5358
  ),
5314
- children && /* @__PURE__ */ import_react62.default.createElement(Card.Body, { className: contentClassName }, children)
5359
+ children && /* @__PURE__ */ import_react63.default.createElement(Card.Body, { className: contentClassName }, children)
5315
5360
  );
5316
5361
  }
5317
5362
  );
5318
5363
  VideoCard.displayName = "VideoCard";
5319
5364
 
5320
5365
  // src/components/AudioCard.tsx
5321
- var import_react63 = __toESM(require("react"));
5366
+ var import_react64 = __toESM(require("react"));
5322
5367
  var import_react_player2 = __toESM(require("react-player"));
5323
5368
  var import_lucide_react12 = require("lucide-react");
5324
- var AudioCard = import_react63.default.forwardRef(
5369
+ var AudioCard = import_react64.default.forwardRef(
5325
5370
  ({
5326
5371
  src,
5327
5372
  title,
@@ -5337,21 +5382,21 @@ var AudioCard = import_react63.default.forwardRef(
5337
5382
  children,
5338
5383
  playerProps,
5339
5384
  height = "40px",
5340
- isLoading,
5385
+ loading,
5341
5386
  ...props
5342
5387
  }, ref) => {
5343
- return /* @__PURE__ */ import_react63.default.createElement(
5388
+ return /* @__PURE__ */ import_react64.default.createElement(
5344
5389
  Card,
5345
5390
  {
5346
5391
  ref,
5347
5392
  className: cx("p-0 overflow-hidden w-full", className),
5348
- isLoading,
5393
+ loading,
5349
5394
  ...props
5350
5395
  },
5351
- /* @__PURE__ */ import_react63.default.createElement(Card.Media, { className: cx(
5396
+ /* @__PURE__ */ import_react64.default.createElement(Card.Media, { className: cx(
5352
5397
  "bg-obsidian py-8 flex flex-col items-center justify-center",
5353
5398
  mediaClassName
5354
- ) }, /* @__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(
5355
5400
  import_react_player2.default,
5356
5401
  {
5357
5402
  src,
@@ -5374,7 +5419,7 @@ var AudioCard = import_react63.default.forwardRef(
5374
5419
  ...playerProps
5375
5420
  }
5376
5421
  ))),
5377
- /* @__PURE__ */ import_react63.default.createElement(
5422
+ /* @__PURE__ */ import_react64.default.createElement(
5378
5423
  Card.Header,
5379
5424
  {
5380
5425
  title,
@@ -5382,16 +5427,16 @@ var AudioCard = import_react63.default.forwardRef(
5382
5427
  className: contentClassName
5383
5428
  }
5384
5429
  ),
5385
- children && /* @__PURE__ */ import_react63.default.createElement(Card.Body, { className: contentClassName }, children)
5430
+ children && /* @__PURE__ */ import_react64.default.createElement(Card.Body, { className: contentClassName }, children)
5386
5431
  );
5387
5432
  }
5388
5433
  );
5389
5434
  AudioCard.displayName = "AudioCard";
5390
5435
 
5391
5436
  // src/components/PdfCard.tsx
5392
- var import_react64 = __toESM(require("react"));
5437
+ var import_react65 = __toESM(require("react"));
5393
5438
  var import_lucide_react13 = require("lucide-react");
5394
- var PdfCard = import_react64.default.forwardRef(
5439
+ var PdfCard = import_react65.default.forwardRef(
5395
5440
  ({
5396
5441
  src,
5397
5442
  title,
@@ -5401,24 +5446,24 @@ var PdfCard = import_react64.default.forwardRef(
5401
5446
  contentClassName,
5402
5447
  className,
5403
5448
  children,
5404
- isLoading,
5449
+ loading,
5405
5450
  ...props
5406
5451
  }, ref) => {
5407
- return /* @__PURE__ */ import_react64.default.createElement(
5452
+ return /* @__PURE__ */ import_react65.default.createElement(
5408
5453
  Card,
5409
5454
  {
5410
5455
  ref,
5411
5456
  className: cx("p-0 overflow-hidden w-full", className),
5412
- isLoading,
5457
+ loading,
5413
5458
  ...props
5414
5459
  },
5415
- /* @__PURE__ */ import_react64.default.createElement(
5460
+ /* @__PURE__ */ import_react65.default.createElement(
5416
5461
  Card.Media,
5417
5462
  {
5418
5463
  className: cx("bg-obsidian", mediaClassName),
5419
5464
  style: { height }
5420
5465
  },
5421
- src && /* @__PURE__ */ import_react64.default.createElement(
5466
+ src && /* @__PURE__ */ import_react65.default.createElement(
5422
5467
  "iframe",
5423
5468
  {
5424
5469
  src: `${src}#view=FitH`,
@@ -5427,23 +5472,23 @@ var PdfCard = import_react64.default.forwardRef(
5427
5472
  }
5428
5473
  )
5429
5474
  ),
5430
- /* @__PURE__ */ import_react64.default.createElement(
5475
+ /* @__PURE__ */ import_react65.default.createElement(
5431
5476
  Card.Header,
5432
5477
  {
5433
5478
  title,
5434
5479
  subtitle,
5435
5480
  className: contentClassName,
5436
- 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 }))
5437
5482
  }
5438
5483
  ),
5439
- children && /* @__PURE__ */ import_react64.default.createElement(Card.Body, { className: contentClassName }, children)
5484
+ children && /* @__PURE__ */ import_react65.default.createElement(Card.Body, { className: contentClassName }, children)
5440
5485
  );
5441
5486
  }
5442
5487
  );
5443
5488
  PdfCard.displayName = "PdfCard";
5444
5489
 
5445
5490
  // src/components/ScriptCard.tsx
5446
- var import_react65 = __toESM(require("react"));
5491
+ var import_react66 = __toESM(require("react"));
5447
5492
  var SCRIPT_ELEMENT_TYPES = {
5448
5493
  SCENE_HEADING: "scene-heading",
5449
5494
  ACTION: "action",
@@ -5457,49 +5502,49 @@ var SCRIPT_ELEMENT_TYPES = {
5457
5502
  function ScriptElementRenderer({ element }) {
5458
5503
  switch (element.type) {
5459
5504
  case "scene-heading":
5460
- 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);
5461
5506
  case "action":
5462
- 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);
5463
5508
  case "character":
5464
- 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);
5465
5510
  case "parenthetical":
5466
- 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, ")");
5467
5512
  case "dialogue":
5468
- 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);
5469
5514
  case "transition":
5470
- 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);
5471
5516
  case "title":
5472
- 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);
5473
5518
  case "subtitle":
5474
- 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);
5475
5520
  default:
5476
5521
  return null;
5477
5522
  }
5478
5523
  }
5479
- var ScriptCard = import_react65.default.forwardRef(
5480
- ({ title, subtitle, elements, maxHeight = "16rem", className, style, isLoading, ...rest }, ref) => {
5481
- return /* @__PURE__ */ import_react65.default.createElement(
5524
+ var ScriptCard = import_react66.default.forwardRef(
5525
+ ({ title, subtitle, elements, maxHeight = "16rem", className, style, loading, ...rest }, ref) => {
5526
+ return /* @__PURE__ */ import_react66.default.createElement(
5482
5527
  Card,
5483
5528
  {
5484
5529
  ref,
5485
5530
  className: cx("p-0 overflow-hidden w-full", className),
5486
- isLoading,
5531
+ loading,
5487
5532
  ...rest
5488
5533
  },
5489
- /* @__PURE__ */ import_react65.default.createElement(
5534
+ /* @__PURE__ */ import_react66.default.createElement(
5490
5535
  Card.Header,
5491
5536
  {
5492
5537
  title,
5493
5538
  subtitle
5494
5539
  }
5495
5540
  ),
5496
- /* @__PURE__ */ import_react65.default.createElement(
5541
+ /* @__PURE__ */ import_react66.default.createElement(
5497
5542
  Card.Body,
5498
5543
  {
5499
5544
  className: "font-mono overflow-y-auto",
5500
5545
  style: { maxHeight, ...style }
5501
5546
  },
5502
- 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 }))
5503
5548
  )
5504
5549
  );
5505
5550
  }
@@ -5507,8 +5552,8 @@ var ScriptCard = import_react65.default.forwardRef(
5507
5552
  ScriptCard.displayName = "ScriptCard";
5508
5553
 
5509
5554
  // src/components/TextCard.tsx
5510
- var import_react66 = __toESM(require("react"));
5511
- var TextCard = import_react66.default.forwardRef(
5555
+ var import_react67 = __toESM(require("react"));
5556
+ var TextCard = import_react67.default.forwardRef(
5512
5557
  ({
5513
5558
  content,
5514
5559
  title,
@@ -5517,31 +5562,31 @@ var TextCard = import_react66.default.forwardRef(
5517
5562
  maxHeight = "16rem",
5518
5563
  contentClassName,
5519
5564
  className,
5520
- isLoading,
5565
+ loading,
5521
5566
  ...props
5522
5567
  }, ref) => {
5523
- return /* @__PURE__ */ import_react66.default.createElement(
5568
+ return /* @__PURE__ */ import_react67.default.createElement(
5524
5569
  Card,
5525
5570
  {
5526
5571
  ref,
5527
5572
  className: cx("p-0 overflow-hidden w-full", className),
5528
- isLoading,
5573
+ loading,
5529
5574
  ...props
5530
5575
  },
5531
- /* @__PURE__ */ import_react66.default.createElement(
5576
+ /* @__PURE__ */ import_react67.default.createElement(
5532
5577
  Card.Header,
5533
5578
  {
5534
5579
  title,
5535
5580
  subtitle
5536
5581
  }
5537
5582
  ),
5538
- /* @__PURE__ */ import_react66.default.createElement(
5583
+ /* @__PURE__ */ import_react67.default.createElement(
5539
5584
  Card.Body,
5540
5585
  {
5541
5586
  className: cx("overflow-y-auto", contentClassName),
5542
5587
  style: { maxHeight }
5543
5588
  },
5544
- /* @__PURE__ */ import_react66.default.createElement(
5589
+ /* @__PURE__ */ import_react67.default.createElement(
5545
5590
  MarkdownContent,
5546
5591
  {
5547
5592
  content,
@@ -5555,6 +5600,21 @@ var TextCard = import_react66.default.forwardRef(
5555
5600
  );
5556
5601
  TextCard.displayName = "TextCard";
5557
5602
 
5603
+ // src/utils/artifactLoading.ts
5604
+ function deriveCardSlotLoading(a) {
5605
+ if (!a.isPending) {
5606
+ return void 0;
5607
+ }
5608
+ const header = {
5609
+ title: !a.title,
5610
+ subtitle: !a.subtitle
5611
+ };
5612
+ const mediaNeeded = (type) => ["IMAGE", "VIDEO", "AUDIO", "PDF"].includes(type);
5613
+ const media = mediaNeeded(a.type) && !a.url;
5614
+ const body = a.type === "TEXT" && !(a.inlineContent && a.inlineContent.trim().length) || a.type === "SCRIPT" && !(a.scriptElements && a.scriptElements.length > 0);
5615
+ return { header, media, body };
5616
+ }
5617
+
5558
5618
  // src/components/ArtifactCard.tsx
5559
5619
  var ARTIFACT_TYPES = {
5560
5620
  TEXT: "TEXT",
@@ -5564,12 +5624,13 @@ var ARTIFACT_TYPES = {
5564
5624
  SCRIPT: "SCRIPT",
5565
5625
  PDF: "PDF"
5566
5626
  };
5567
- var ArtifactCard = import_react67.default.forwardRef(
5568
- ({ artifact, onExpand, isLoading, className, ...props }, ref) => {
5627
+ var ArtifactCard = import_react68.default.forwardRef(
5628
+ ({ artifact, onExpand, loading, className, ...props }, ref) => {
5629
+ const derivedLoading = deriveCardSlotLoading(artifact);
5569
5630
  const commonProps = {
5570
5631
  title: artifact.title,
5571
5632
  subtitle: artifact.subtitle,
5572
- isLoading: isLoading || artifact.isPending,
5633
+ loading: loading || derivedLoading,
5573
5634
  className: "w-full"
5574
5635
  };
5575
5636
  const handleExpand = (e) => {
@@ -5581,7 +5642,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5581
5642
  const renderContent = () => {
5582
5643
  switch (artifact.type) {
5583
5644
  case "IMAGE":
5584
- return /* @__PURE__ */ import_react67.default.createElement(
5645
+ return /* @__PURE__ */ import_react68.default.createElement(
5585
5646
  ImageCard,
5586
5647
  {
5587
5648
  ...commonProps,
@@ -5591,7 +5652,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5591
5652
  }
5592
5653
  );
5593
5654
  case "VIDEO":
5594
- return /* @__PURE__ */ import_react67.default.createElement(
5655
+ return /* @__PURE__ */ import_react68.default.createElement(
5595
5656
  VideoCard,
5596
5657
  {
5597
5658
  ...commonProps,
@@ -5601,7 +5662,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5601
5662
  }
5602
5663
  );
5603
5664
  case "AUDIO":
5604
- return /* @__PURE__ */ import_react67.default.createElement(
5665
+ return /* @__PURE__ */ import_react68.default.createElement(
5605
5666
  AudioCard,
5606
5667
  {
5607
5668
  ...commonProps,
@@ -5610,7 +5671,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5610
5671
  }
5611
5672
  );
5612
5673
  case "PDF":
5613
- return /* @__PURE__ */ import_react67.default.createElement(
5674
+ return /* @__PURE__ */ import_react68.default.createElement(
5614
5675
  PdfCard,
5615
5676
  {
5616
5677
  ...commonProps,
@@ -5618,7 +5679,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5618
5679
  }
5619
5680
  );
5620
5681
  case "SCRIPT":
5621
- return /* @__PURE__ */ import_react67.default.createElement(
5682
+ return /* @__PURE__ */ import_react68.default.createElement(
5622
5683
  ScriptCard,
5623
5684
  {
5624
5685
  ...commonProps,
@@ -5627,7 +5688,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5627
5688
  }
5628
5689
  );
5629
5690
  case "TEXT":
5630
- return /* @__PURE__ */ import_react67.default.createElement(
5691
+ return /* @__PURE__ */ import_react68.default.createElement(
5631
5692
  TextCard,
5632
5693
  {
5633
5694
  ...commonProps,
@@ -5643,7 +5704,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5643
5704
  }
5644
5705
  };
5645
5706
  const isCardExpandable = !!onExpand && (artifact.type === "IMAGE" || artifact.type === "PDF" || artifact.type === "SCRIPT" || artifact.type === "TEXT");
5646
- return /* @__PURE__ */ import_react67.default.createElement(
5707
+ return /* @__PURE__ */ import_react68.default.createElement(
5647
5708
  "div",
5648
5709
  {
5649
5710
  ref,
@@ -5656,7 +5717,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5656
5717
  onClick: isCardExpandable ? handleExpand : void 0,
5657
5718
  ...props
5658
5719
  },
5659
- onExpand && /* @__PURE__ */ import_react67.default.createElement(
5720
+ onExpand && /* @__PURE__ */ import_react68.default.createElement(
5660
5721
  "button",
5661
5722
  {
5662
5723
  onClick: handleExpand,
@@ -5667,7 +5728,7 @@ var ArtifactCard = import_react67.default.forwardRef(
5667
5728
  ),
5668
5729
  "aria-label": "Expand artifact"
5669
5730
  },
5670
- /* @__PURE__ */ import_react67.default.createElement(ExpandIcon, { className: "w-4 h-4" })
5731
+ /* @__PURE__ */ import_react68.default.createElement(ExpandIcon, { className: "w-4 h-4" })
5671
5732
  ),
5672
5733
  renderContent()
5673
5734
  );
@@ -5675,12 +5736,178 @@ var ArtifactCard = import_react67.default.forwardRef(
5675
5736
  );
5676
5737
  ArtifactCard.displayName = "ArtifactCard";
5677
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
+
5678
5904
  // src/components/chat/ArtifactsPanel.tsx
5905
+ var ZOOM_LEVELS = [0.25, 0.5, 0.75, 1];
5679
5906
  function ArtifactModal({
5680
5907
  artifact,
5681
5908
  onClose
5682
5909
  }) {
5683
- (0, import_react68.useEffect)(() => {
5910
+ (0, import_react72.useEffect)(() => {
5684
5911
  const handleKeyDown = (e) => {
5685
5912
  if (e.key === "Escape") {
5686
5913
  onClose();
@@ -5689,46 +5916,46 @@ function ArtifactModal({
5689
5916
  document.addEventListener("keydown", handleKeyDown);
5690
5917
  return () => document.removeEventListener("keydown", handleKeyDown);
5691
5918
  }, [onClose]);
5692
- const handleBackdropClick = (0, import_react68.useCallback)((e) => {
5919
+ const handleBackdropClick = (0, import_react72.useCallback)((e) => {
5693
5920
  if (e.target === e.currentTarget) {
5694
5921
  onClose();
5695
5922
  }
5696
5923
  }, [onClose]);
5697
- return /* @__PURE__ */ import_react68.default.createElement(
5924
+ return /* @__PURE__ */ import_react72.default.createElement(
5698
5925
  "div",
5699
5926
  {
5700
5927
  className: "fixed inset-0 z-50 flex items-center justify-center bg-void/90 backdrop-blur-sm animate-fade-in",
5701
5928
  onClick: handleBackdropClick
5702
5929
  },
5703
- /* @__PURE__ */ import_react68.default.createElement(
5930
+ /* @__PURE__ */ import_react72.default.createElement(
5704
5931
  "div",
5705
5932
  {
5706
5933
  className: "relative w-11/12 h-5/6 max-w-6xl bg-charcoal border border-ash/40 flex flex-col overflow-hidden"
5707
5934
  },
5708
- /* @__PURE__ */ import_react68.default.createElement(
5935
+ /* @__PURE__ */ import_react72.default.createElement(
5709
5936
  "div",
5710
5937
  {
5711
5938
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5712
5939
  },
5713
- /* @__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)),
5714
- /* @__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(
5715
5942
  "button",
5716
5943
  {
5717
5944
  onClick: onClose,
5718
5945
  className: "p-2 text-silver hover:text-white hover:bg-ash/20 transition-colors",
5719
5946
  "aria-label": "Close modal"
5720
5947
  },
5721
- /* @__PURE__ */ import_react68.default.createElement(CloseIcon, { className: "w-5 h-5" })
5948
+ /* @__PURE__ */ import_react72.default.createElement(CloseIcon, { className: "w-5 h-5" })
5722
5949
  )
5723
5950
  ),
5724
- /* @__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(
5725
5952
  "img",
5726
5953
  {
5727
5954
  src: artifact.url,
5728
5955
  alt: artifact.alt || "Artifact image",
5729
5956
  className: "max-w-full max-h-full object-contain mx-auto"
5730
5957
  }
5731
- ), artifact.type === "VIDEO" && /* @__PURE__ */ import_react68.default.createElement(
5958
+ ), artifact.type === "VIDEO" && /* @__PURE__ */ import_react72.default.createElement(
5732
5959
  VideoCard,
5733
5960
  {
5734
5961
  src: artifact.url || "",
@@ -5736,30 +5963,30 @@ function ArtifactModal({
5736
5963
  controls: true,
5737
5964
  className: "max-w-full max-h-full mx-auto"
5738
5965
  }
5739
- ), artifact.type === "AUDIO" && /* @__PURE__ */ import_react68.default.createElement(
5966
+ ), artifact.type === "AUDIO" && /* @__PURE__ */ import_react72.default.createElement(
5740
5967
  AudioCard,
5741
5968
  {
5742
5969
  src: artifact.url || "",
5743
5970
  controls: true,
5744
5971
  className: "max-w-xl mx-auto"
5745
5972
  }
5746
- ), artifact.type === "PDF" && /* @__PURE__ */ import_react68.default.createElement(
5973
+ ), artifact.type === "PDF" && /* @__PURE__ */ import_react72.default.createElement(
5747
5974
  PdfCard,
5748
5975
  {
5749
5976
  src: artifact.url || "",
5750
5977
  className: "h-full border-0"
5751
5978
  }
5752
- ), artifact.type === "TEXT" && /* @__PURE__ */ import_react68.default.createElement(
5979
+ ), artifact.type === "TEXT" && /* @__PURE__ */ import_react72.default.createElement(
5753
5980
  MarkdownContent,
5754
5981
  {
5755
5982
  content: artifact.inlineContent || "",
5756
- isMarkdown: artifact.mimeType === "text/markdown",
5983
+ isMarkdown: artifact.mimeType !== "text/plain",
5757
5984
  className: cx(
5758
5985
  "prose prose-invert max-w-none",
5759
5986
  artifact.mimeType === "text/plain" && "whitespace-pre-wrap"
5760
5987
  )
5761
5988
  }
5762
- ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ import_react68.default.createElement(
5989
+ ), artifact.type === "SCRIPT" && artifact.scriptElements && /* @__PURE__ */ import_react72.default.createElement(
5763
5990
  ScriptCard,
5764
5991
  {
5765
5992
  elements: artifact.scriptElements,
@@ -5770,138 +5997,190 @@ function ArtifactModal({
5770
5997
  )
5771
5998
  );
5772
5999
  }
5773
- function ArtifactRenderer({
5774
- artifact,
5775
- isLoading,
5776
- onExpand
6000
+ function NodeRenderer({
6001
+ node,
6002
+ loading,
6003
+ onExpandArtifact,
6004
+ onGroupClick
5777
6005
  }) {
5778
- return /* @__PURE__ */ import_react68.default.createElement(
5779
- ArtifactCard,
5780
- {
5781
- artifact,
5782
- isLoading,
5783
- onExpand
5784
- }
5785
- );
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;
5786
6030
  }
5787
- var ArtifactsPanel = import_react68.default.forwardRef(
6031
+ var ArtifactsPanel = import_react72.default.forwardRef(
5788
6032
  ({
6033
+ nodes,
5789
6034
  artifacts,
5790
- isOpen = false,
5791
- onClose,
5792
- isLoading = false,
5793
- width,
5794
- widthPercent,
5795
- onResizeStart,
6035
+ loading,
5796
6036
  className,
5797
6037
  ...rest
5798
6038
  }, ref) => {
5799
- const [expandedArtifact, setExpandedArtifact] = (0, import_react68.useState)(null);
5800
- const columns = widthPercent && widthPercent > 55 ? 3 : widthPercent && widthPercent > 35 ? 2 : 1;
5801
- if (!isOpen) {
5802
- return /* @__PURE__ */ import_react68.default.createElement(
5803
- "div",
5804
- {
5805
- ref,
5806
- className: cx(
5807
- "h-full bg-charcoal/80 border-l border-ash/40 flex flex-col items-center py-3",
5808
- "w-12 shrink-0",
5809
- className
5810
- ),
5811
- ...rest
5812
- },
5813
- /* @__PURE__ */ import_react68.default.createElement(
5814
- "button",
5815
- {
5816
- onClick: onClose,
5817
- className: cx(
5818
- "p-2",
5819
- "text-silver hover:text-white hover:bg-ash/20",
5820
- "transition-colors duration-150",
5821
- "relative"
5822
- ),
5823
- "aria-label": "Expand artifacts panel"
5824
- },
5825
- /* @__PURE__ */ import_react68.default.createElement(LayersIcon, { className: "w-5 h-5" }),
5826
- artifacts.length > 0 && /* @__PURE__ */ import_react68.default.createElement(
5827
- "span",
5828
- {
5829
- 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"
5830
- },
5831
- artifacts.length
5832
- )
5833
- )
5834
- );
5835
- }
5836
- 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(
5837
6068
  "div",
5838
6069
  {
5839
6070
  ref,
5840
6071
  "data-testid": "artifacts-panel",
5841
6072
  className: cx(
5842
- "h-full bg-charcoal/50 border-l border-ash/40 flex flex-col relative",
5843
- !width && "w-96",
5844
- "shrink-0",
6073
+ "h-full flex flex-col relative",
5845
6074
  className
5846
6075
  ),
5847
- style: width ? { width } : void 0,
5848
6076
  ...rest
5849
6077
  },
5850
- /* @__PURE__ */ import_react68.default.createElement(
5851
- "div",
5852
- {
5853
- onMouseDown: onResizeStart,
5854
- "data-testid": "artifacts-resize-handle",
5855
- className: cx(
5856
- "absolute top-0 left-0 w-1 h-full cursor-col-resize z-50",
5857
- "hover:bg-gold/50 transition-colors",
5858
- "after:absolute after:inset-y-0 after:-left-1 after:w-2"
5859
- // Larger hit area
5860
- )
5861
- }
5862
- ),
5863
- /* @__PURE__ */ import_react68.default.createElement(
6078
+ /* @__PURE__ */ import_react72.default.createElement(
5864
6079
  "div",
5865
6080
  {
5866
6081
  className: "flex items-center justify-between p-4 border-b border-ash/40 shrink-0"
5867
6082
  },
5868
- /* @__PURE__ */ import_react68.default.createElement("h3", { className: "text-sm font-semibold text-white" }, "Artifacts"),
5869
- /* @__PURE__ */ import_react68.default.createElement(
5870
- "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",
5871
6086
  {
5872
- onClick: onClose,
5873
- className: cx(
5874
- "p-1.5",
5875
- "text-silver hover:text-white hover:bg-ash/20",
5876
- "transition-colors duration-150"
5877
- ),
5878
- "aria-label": "Collapse artifacts panel"
6087
+ className: "flex items-center gap-0.5",
6088
+ "data-testid": "zoom-controls"
5879
6089
  },
5880
- /* @__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
+ )
5881
6119
  )
5882
6120
  ),
5883
- /* @__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(
5884
6141
  "div",
5885
6142
  {
5886
- "data-testid": "artifacts-grid",
5887
- className: cx(
5888
- "flex-1 overflow-y-auto p-4",
5889
- columns === 1 ? "space-y-4" : "grid gap-4",
5890
- columns === 2 && "grid-cols-2",
5891
- columns === 3 && "grid-cols-3"
5892
- )
6143
+ className: "flex-1 overflow-auto relative",
6144
+ "data-testid": "artifacts-scroll-area"
5893
6145
  },
5894
- artifacts.length === 0 && !isLoading ? /* @__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(
5895
- ArtifactRenderer,
6146
+ /* @__PURE__ */ import_react72.default.createElement(
6147
+ "div",
5896
6148
  {
5897
- key: artifact.id,
5898
- artifact,
5899
- isLoading,
5900
- onExpand: () => setExpandedArtifact(artifact)
5901
- }
5902
- ))
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
+ )
5903
6182
  )
5904
- ), expandedArtifact && /* @__PURE__ */ import_react68.default.createElement(
6183
+ ), expandedArtifact && /* @__PURE__ */ import_react72.default.createElement(
5905
6184
  ArtifactModal,
5906
6185
  {
5907
6186
  artifact: expandedArtifact,
@@ -5911,8 +6190,8 @@ var ArtifactsPanel = import_react68.default.forwardRef(
5911
6190
  }
5912
6191
  );
5913
6192
  ArtifactsPanel.displayName = "ArtifactsPanel";
5914
- var ArtifactsPanelToggle = import_react68.default.forwardRef(({ artifactCount = 0, onExpand, className, ...rest }, ref) => {
5915
- 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(
5916
6195
  "button",
5917
6196
  {
5918
6197
  ref,
@@ -5929,11 +6208,27 @@ var ArtifactsPanelToggle = import_react68.default.forwardRef(({ artifactCount =
5929
6208
  "aria-label": "Expand artifacts panel",
5930
6209
  ...rest
5931
6210
  },
5932
- /* @__PURE__ */ import_react68.default.createElement(LayersIcon, { className: "w-5 h-5" }),
5933
- 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(
5934
6229
  "span",
5935
6230
  {
5936
- 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"
5937
6232
  },
5938
6233
  artifactCount
5939
6234
  )
@@ -5942,7 +6237,7 @@ var ArtifactsPanelToggle = import_react68.default.forwardRef(({ artifactCount =
5942
6237
  ArtifactsPanelToggle.displayName = "ArtifactsPanelToggle";
5943
6238
 
5944
6239
  // src/components/chat/TodosList.tsx
5945
- var import_react69 = __toESM(require("react"));
6240
+ var import_react73 = __toESM(require("react"));
5946
6241
  var TASK_STATUSES = {
5947
6242
  PENDING: "pending",
5948
6243
  IN_PROGRESS: "in_progress",
@@ -5953,16 +6248,16 @@ var TASK_STATUSES = {
5953
6248
  function TaskIcon({ status }) {
5954
6249
  switch (status) {
5955
6250
  case "done":
5956
- return /* @__PURE__ */ import_react69.default.createElement(CheckSquareIcon, null);
6251
+ return /* @__PURE__ */ import_react73.default.createElement(CheckSquareIcon, null);
5957
6252
  case "in_progress":
5958
- return /* @__PURE__ */ import_react69.default.createElement(SquareLoaderIcon, null);
6253
+ return /* @__PURE__ */ import_react73.default.createElement(SquareLoaderIcon, null);
5959
6254
  case "cancelled":
5960
- return /* @__PURE__ */ import_react69.default.createElement(CrossSquareIcon, { variant: "cancelled" });
6255
+ return /* @__PURE__ */ import_react73.default.createElement(CrossSquareIcon, { variant: "cancelled" });
5961
6256
  case "failed":
5962
- return /* @__PURE__ */ import_react69.default.createElement(CrossSquareIcon, { variant: "failed" });
6257
+ return /* @__PURE__ */ import_react73.default.createElement(CrossSquareIcon, { variant: "failed" });
5963
6258
  case "pending":
5964
6259
  default:
5965
- return /* @__PURE__ */ import_react69.default.createElement(EmptySquareIcon, null);
6260
+ return /* @__PURE__ */ import_react73.default.createElement(EmptySquareIcon, null);
5966
6261
  }
5967
6262
  }
5968
6263
  function sortTasks(tasks) {
@@ -5982,7 +6277,7 @@ function TaskItem({ task, depth = 0 }) {
5982
6277
  const isSubtle = task.status === "cancelled" || task.status === "failed";
5983
6278
  const showSubtasks = (task.status === "in_progress" || task.status === "done") && task.subtasks && task.subtasks.length > 0;
5984
6279
  const sortedSubtasks = showSubtasks ? sortTasks(task.subtasks) : [];
5985
- 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(
5986
6281
  "div",
5987
6282
  {
5988
6283
  className: cx(
@@ -5990,8 +6285,8 @@ function TaskItem({ task, depth = 0 }) {
5990
6285
  depth > 0 && "pl-6"
5991
6286
  )
5992
6287
  },
5993
- /* @__PURE__ */ import_react69.default.createElement(TaskIcon, { status: task.status }),
5994
- /* @__PURE__ */ import_react69.default.createElement(
6288
+ /* @__PURE__ */ import_react73.default.createElement(TaskIcon, { status: task.status }),
6289
+ /* @__PURE__ */ import_react73.default.createElement(
5995
6290
  "span",
5996
6291
  {
5997
6292
  className: cx(
@@ -6003,14 +6298,14 @@ function TaskItem({ task, depth = 0 }) {
6003
6298
  )
6004
6299
  },
6005
6300
  task.label,
6006
- task.status === "cancelled" && /* @__PURE__ */ import_react69.default.createElement("span", { className: "text-silver/40 ml-1" }, "(cancelled)"),
6007
- 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)")
6008
6303
  )
6009
- ), 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 }))));
6010
6305
  }
6011
- var TodosList = import_react69.default.forwardRef(
6306
+ var TodosList = import_react73.default.forwardRef(
6012
6307
  ({ tasks, title = "Tasks", className, ...rest }, ref) => {
6013
- const sortedTasks = (0, import_react69.useMemo)(() => sortTasks(tasks), [tasks]);
6308
+ const sortedTasks = (0, import_react73.useMemo)(() => sortTasks(tasks), [tasks]);
6014
6309
  const countCompleted = (taskList) => {
6015
6310
  let count = 0;
6016
6311
  for (const task of taskList) {
@@ -6035,40 +6330,204 @@ var TodosList = import_react69.default.forwardRef(
6035
6330
  if (tasks.length === 0) {
6036
6331
  return null;
6037
6332
  }
6038
- return /* @__PURE__ */ import_react69.default.createElement(
6333
+ return /* @__PURE__ */ import_react73.default.createElement(
6039
6334
  "div",
6040
6335
  {
6041
6336
  ref,
6042
6337
  className: cx(
6043
- "flex flex-col bg-charcoal/30 border-l border-ash/40",
6338
+ "flex flex-col h-full",
6044
6339
  "overflow-hidden",
6045
6340
  className
6046
6341
  ),
6047
- style: { maxHeight: "25vh" },
6048
6342
  ...rest
6049
6343
  },
6050
- /* @__PURE__ */ import_react69.default.createElement(
6344
+ /* @__PURE__ */ import_react73.default.createElement(
6051
6345
  "div",
6052
6346
  {
6053
6347
  className: "flex items-center justify-between px-4 py-2 border-b border-ash/40 flex-shrink-0"
6054
6348
  },
6055
- /* @__PURE__ */ import_react69.default.createElement("h4", { className: "text-xs font-medium text-white" }, title),
6056
- /* @__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))
6057
6351
  ),
6058
- /* @__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 })))
6059
6353
  );
6060
6354
  }
6061
6355
  );
6062
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";
6063
6522
 
6064
6523
  // src/components/chat/hooks/useArtifacts.ts
6065
- var import_react70 = require("react");
6524
+ var import_react76 = require("react");
6066
6525
  function useArtifacts() {
6067
- const [artifacts, setArtifacts] = (0, import_react70.useState)([]);
6068
- const scheduleArtifact = (0, import_react70.useCallback)((artifact) => {
6526
+ const [artifacts, setArtifacts] = (0, import_react76.useState)([]);
6527
+ const scheduleArtifact = (0, import_react76.useCallback)((artifact) => {
6069
6528
  setArtifacts((prev) => [...prev, { ...artifact, isPending: true }]);
6070
6529
  }, []);
6071
- const showArtifact = (0, import_react70.useCallback)(
6530
+ const showArtifact = (0, import_react76.useCallback)(
6072
6531
  (artifactId, updates) => {
6073
6532
  setArtifacts((prev) => {
6074
6533
  const existingIndex = prev.findIndex((a) => a.id === artifactId);
@@ -6083,36 +6542,36 @@ function useArtifacts() {
6083
6542
  },
6084
6543
  []
6085
6544
  );
6086
- const removeArtifact = (0, import_react70.useCallback)((artifactId) => {
6545
+ const removeArtifact = (0, import_react76.useCallback)((artifactId) => {
6087
6546
  setArtifacts((prev) => prev.filter((a) => a.id !== artifactId));
6088
6547
  }, []);
6089
- const clearArtifacts = (0, import_react70.useCallback)(() => {
6548
+ const clearArtifacts = (0, import_react76.useCallback)(() => {
6090
6549
  setArtifacts([]);
6091
6550
  }, []);
6092
6551
  return { artifacts, scheduleArtifact, showArtifact, removeArtifact, clearArtifacts };
6093
6552
  }
6094
6553
 
6095
6554
  // src/components/chat/hooks/useResizable.ts
6096
- var import_react71 = require("react");
6555
+ var import_react77 = require("react");
6097
6556
  function useResizable({
6098
6557
  initialWidthPercent,
6099
6558
  minWidthPercent,
6100
6559
  maxWidthPercent,
6101
6560
  direction
6102
6561
  }) {
6103
- const [widthPercent, setWidthPercent] = (0, import_react71.useState)(initialWidthPercent);
6104
- const [isResizing, setIsResizing] = (0, import_react71.useState)(false);
6105
- const lastX = (0, import_react71.useRef)(null);
6106
- 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) => {
6107
6566
  e.preventDefault();
6108
6567
  setIsResizing(true);
6109
6568
  lastX.current = e.clientX;
6110
6569
  }, []);
6111
- const stopResizing = (0, import_react71.useCallback)(() => {
6570
+ const stopResizing = (0, import_react77.useCallback)(() => {
6112
6571
  setIsResizing(false);
6113
6572
  lastX.current = null;
6114
6573
  }, []);
6115
- const resize = (0, import_react71.useCallback)(
6574
+ const resize = (0, import_react77.useCallback)(
6116
6575
  (e) => {
6117
6576
  if (!isResizing || lastX.current === null) {
6118
6577
  return;
@@ -6128,7 +6587,7 @@ function useResizable({
6128
6587
  },
6129
6588
  [isResizing, direction, minWidthPercent, maxWidthPercent]
6130
6589
  );
6131
- (0, import_react71.useEffect)(() => {
6590
+ (0, import_react77.useEffect)(() => {
6132
6591
  if (isResizing) {
6133
6592
  window.addEventListener("mousemove", resize);
6134
6593
  window.addEventListener("mouseup", stopResizing);
@@ -6152,7 +6611,7 @@ function useResizable({
6152
6611
  }
6153
6612
 
6154
6613
  // src/components/chat/ChatInterface.tsx
6155
- var ChatInterface = import_react72.default.forwardRef(
6614
+ var ChatInterface = import_react78.default.forwardRef(
6156
6615
  ({
6157
6616
  messages = [],
6158
6617
  conversationTree,
@@ -6175,6 +6634,7 @@ var ChatInterface = import_react72.default.forwardRef(
6175
6634
  attachments: propsAttachments,
6176
6635
  onAttachmentsChange,
6177
6636
  artifacts = [],
6637
+ artifactNodes,
6178
6638
  isArtifactsPanelOpen,
6179
6639
  onArtifactsPanelOpenChange,
6180
6640
  tasks = [],
@@ -6182,10 +6642,25 @@ var ChatInterface = import_react72.default.forwardRef(
6182
6642
  className,
6183
6643
  ...rest
6184
6644
  }, ref) => {
6185
- const [sidebarCollapsed, setSidebarCollapsed] = (0, import_react72.useState)(initialSidebarCollapsed);
6186
- const [internalPanelOpen, setInternalPanelOpen] = (0, import_react72.useState)(false);
6187
- const prevArtifactsRef = (0, import_react72.useRef)([]);
6188
- 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;
6189
6664
  const {
6190
6665
  width: sidebarWidth,
6191
6666
  startResizing: startResizingSidebar
@@ -6196,19 +6671,43 @@ var ChatInterface = import_react72.default.forwardRef(
6196
6671
  direction: "right"
6197
6672
  });
6198
6673
  const {
6199
- width: artifactsWidth,
6200
- widthPercent: artifactsWidthPercent,
6201
- startResizing: startResizingArtifacts
6674
+ width: toolsWidth,
6675
+ startResizing: startResizingTools
6202
6676
  } = useResizable({
6203
6677
  initialWidthPercent: 50,
6204
6678
  minWidthPercent: 25,
6205
6679
  maxWidthPercent: 70,
6206
6680
  direction: "left"
6207
6681
  });
6208
- const isPanelControlled = isArtifactsPanelOpen !== void 0;
6209
- 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]);
6210
6709
  const isTreeMode = !!conversationTree;
6211
- const effectiveMessages = (0, import_react72.useMemo)(() => {
6710
+ const effectiveMessages = (0, import_react78.useMemo)(() => {
6212
6711
  if (isTreeMode && conversationTree) {
6213
6712
  const pathNodes = getActivePathMessages(conversationTree);
6214
6713
  return pathNodes.map((node) => ({
@@ -6220,66 +6719,48 @@ var ChatInterface = import_react72.default.forwardRef(
6220
6719
  }
6221
6720
  return messages;
6222
6721
  }, [isTreeMode, conversationTree, messages]);
6223
- const latestUserMessageIndex = (0, import_react72.useMemo)(() => {
6722
+ const latestUserMessageIndex = (0, import_react78.useMemo)(() => {
6224
6723
  for (let i = effectiveMessages.length - 1; i >= 0; i--) {
6225
- if (effectiveMessages[i].variant === "user") {
6226
- return i;
6227
- }
6724
+ if (effectiveMessages[i].variant === "user") return i;
6228
6725
  }
6229
6726
  return -1;
6230
6727
  }, [effectiveMessages]);
6231
- const hasPendingArtifact = (0, import_react72.useMemo)(() => {
6232
- return artifacts.some((a) => a.isPending);
6233
- }, [artifacts]);
6234
- (0, import_react72.useEffect)(() => {
6235
- if (isPanelControlled) {
6236
- return;
6237
- }
6728
+ (0, import_react78.useEffect)(() => {
6238
6729
  const hasNewOrSignificantArtifact = artifacts.some((a) => {
6239
6730
  const p = prevArtifactsRef.current.find((prev) => prev.id === a.id);
6240
- if (!p) {
6241
- return true;
6242
- }
6243
- if (p.isPending && !a.isPending) {
6244
- return true;
6245
- }
6246
- if (p.title !== a.title || p.type !== a.type) {
6247
- return true;
6248
- }
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;
6249
6734
  return false;
6250
6735
  });
6736
+ const hasNodes = artifactNodes && artifactNodes.length > 0;
6737
+ if (!isPanelControlled && (hasNewOrSignificantArtifact || hasNodes) && !dismissedToolsRef.current.has("artifacts")) {
6738
+ setInternalTools((prev) => ({ ...prev, top: "artifacts" }));
6739
+ }
6251
6740
  const hasNewOrUpdatedTask = (curr, prev) => {
6252
6741
  return curr.some((c) => {
6253
6742
  const p = prev.find((x) => x.id === c.id);
6254
- if (!p) {
6255
- return true;
6256
- }
6257
- if (c.status !== p.status || c.label !== p.label) {
6258
- return true;
6259
- }
6260
- if (c.subtasks && hasNewOrUpdatedTask(c.subtasks, p?.subtasks || [])) {
6261
- return true;
6262
- }
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;
6263
6746
  return false;
6264
6747
  });
6265
6748
  };
6266
- if (hasNewOrSignificantArtifact || hasNewOrUpdatedTask(tasks, prevTasksRef.current)) {
6267
- setInternalPanelOpen(true);
6749
+ if (hasNewOrUpdatedTask(tasks, prevTasksRef.current) && !dismissedToolsRef.current.has("todos")) {
6750
+ setInternalTools((prev) => ({ ...prev, bottom: "todos" }));
6268
6751
  }
6269
6752
  prevArtifactsRef.current = artifacts;
6270
6753
  prevTasksRef.current = tasks;
6271
- }, [artifacts, tasks, isPanelControlled]);
6272
- const handleBranchSwitch = (0, import_react72.useCallback)(
6754
+ }, [artifacts, artifactNodes, tasks, isPanelControlled]);
6755
+ const handleBranchSwitch = (0, import_react78.useCallback)(
6273
6756
  (nodeId, direction) => {
6274
- if (!isTreeMode || !conversationTree || !onTreeChange) {
6275
- return;
6276
- }
6757
+ if (!isTreeMode || !conversationTree || !onTreeChange) return;
6277
6758
  const newTree = switchBranch(conversationTree, nodeId, direction);
6278
6759
  onTreeChange(newTree);
6279
6760
  },
6280
6761
  [isTreeMode, conversationTree, onTreeChange]
6281
6762
  );
6282
- const displayMessages = (0, import_react72.useMemo)(() => {
6763
+ const displayMessages = (0, import_react78.useMemo)(() => {
6283
6764
  return effectiveMessages.map((msg) => {
6284
6765
  let branchInfo = void 0;
6285
6766
  if (isTreeMode && conversationTree) {
@@ -6298,11 +6779,7 @@ var ChatInterface = import_react72.default.forwardRef(
6298
6779
  onEdit: msg.variant === "user" && onEditMessage ? (newContent) => onEditMessage(msg.id, newContent) : void 0,
6299
6780
  onRetry: msg.variant === "assistant" && onRetryMessage ? () => onRetryMessage(msg.id) : void 0
6300
6781
  } : void 0;
6301
- return {
6302
- ...msg,
6303
- branchInfo,
6304
- actions
6305
- };
6782
+ return { ...msg, branchInfo, actions };
6306
6783
  });
6307
6784
  }, [
6308
6785
  effectiveMessages,
@@ -6313,31 +6790,57 @@ var ChatInterface = import_react72.default.forwardRef(
6313
6790
  onRetryMessage,
6314
6791
  handleBranchSwitch
6315
6792
  ]);
6316
- const handleSubmit = (0, import_react72.useCallback)(
6793
+ const handleSubmit = (0, import_react78.useCallback)(
6317
6794
  (message, attachments) => {
6318
6795
  onMessageSubmit?.(message, attachments);
6319
6796
  },
6320
6797
  [onMessageSubmit]
6321
6798
  );
6322
- const toggleSidebar = (0, import_react72.useCallback)(() => {
6799
+ const toggleSidebar = (0, import_react78.useCallback)(() => {
6323
6800
  setSidebarCollapsed((prev) => !prev);
6324
6801
  }, []);
6325
- const toggleArtifactsPanel = (0, import_react72.useCallback)(() => {
6326
- if (isPanelControlled) {
6327
- onArtifactsPanelOpenChange?.(!artifactsPanelOpen);
6328
- } else {
6329
- setInternalPanelOpen((prev) => !prev);
6330
- }
6331
- }, [isPanelControlled, artifactsPanelOpen, onArtifactsPanelOpenChange]);
6332
6802
  const isEmpty = effectiveMessages.length === 0;
6333
- 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(
6334
6837
  "div",
6335
6838
  {
6336
6839
  ref,
6337
6840
  className: cx("flex h-full w-full bg-obsidian overflow-hidden", className),
6338
6841
  ...rest
6339
6842
  },
6340
- /* @__PURE__ */ import_react72.default.createElement(
6843
+ /* @__PURE__ */ import_react78.default.createElement(
6341
6844
  ConversationSidebar,
6342
6845
  {
6343
6846
  conversations,
@@ -6349,16 +6852,16 @@ var ChatInterface = import_react72.default.forwardRef(
6349
6852
  onResizeStart: startResizingSidebar
6350
6853
  }
6351
6854
  ),
6352
- /* @__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(
6353
6856
  "flex-1 flex flex-col min-h-0 relative",
6354
6857
  isEmpty ? "justify-center" : "justify-start"
6355
- ) }, /* @__PURE__ */ import_react72.default.createElement("div", { className: cx(
6858
+ ) }, /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(
6356
6859
  "transition-all duration-500 ease-in-out",
6357
6860
  isEmpty ? "flex-1" : "flex-zero"
6358
- ) }), /* @__PURE__ */ import_react72.default.createElement("div", { className: cx(
6861
+ ) }), /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(
6359
6862
  "transition-all duration-500 ease-in-out overflow-hidden flex flex-col",
6360
6863
  isEmpty ? "flex-zero opacity-0" : "flex-1 opacity-100"
6361
- ) }, /* @__PURE__ */ import_react72.default.createElement(
6864
+ ) }, /* @__PURE__ */ import_react78.default.createElement(
6362
6865
  ChatView,
6363
6866
  {
6364
6867
  messages: displayMessages,
@@ -6367,10 +6870,10 @@ var ChatInterface = import_react72.default.forwardRef(
6367
6870
  isThinking,
6368
6871
  className: "flex-1"
6369
6872
  }
6370
- )), /* @__PURE__ */ import_react72.default.createElement("div", { className: cx(
6873
+ )), /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(
6371
6874
  "transition-all duration-500 ease-in-out z-10 w-full flex flex-col items-center",
6372
6875
  isEmpty ? "p-4" : "shrink-0 p-4 border-t border-ash/40 bg-obsidian"
6373
- ) }, 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(
6374
6877
  ChatInput,
6375
6878
  {
6376
6879
  position: isEmpty ? "centered" : "bottom",
@@ -6384,39 +6887,40 @@ var ChatInterface = import_react72.default.forwardRef(
6384
6887
  attachments: propsAttachments,
6385
6888
  onAttachmentsChange
6386
6889
  }
6387
- )), /* @__PURE__ */ import_react72.default.createElement("div", { className: cx(
6890
+ )), /* @__PURE__ */ import_react78.default.createElement("div", { className: cx(
6388
6891
  "transition-all duration-500 ease-in-out",
6389
6892
  isEmpty ? "flex-1" : "flex-zero"
6390
6893
  ) }))),
6391
- /* @__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(
6392
- ArtifactsPanel,
6894
+ isAnyToolOpen && /* @__PURE__ */ import_react78.default.createElement(
6895
+ ToolPanelContainer,
6393
6896
  {
6394
- artifacts,
6395
- isOpen: artifactsPanelOpen,
6396
- onClose: toggleArtifactsPanel,
6397
- isLoading: isStreaming && hasPendingArtifact,
6398
- width: artifactsWidth,
6399
- widthPercent: artifactsWidthPercent,
6400
- onResizeStart: startResizingArtifacts,
6401
- className: "h-full"
6897
+ topContent: renderToolContent(activeTools.top),
6898
+ bottomContent: renderToolContent(activeTools.bottom),
6899
+ width: toolsWidth,
6900
+ onResizeStart: startResizingTools
6402
6901
  }
6403
- )), tasks.length > 0 && artifactsPanelOpen && /* @__PURE__ */ import_react72.default.createElement(
6404
- TodosList,
6902
+ ),
6903
+ /* @__PURE__ */ import_react78.default.createElement(
6904
+ ToolSidebar,
6405
6905
  {
6406
- tasks,
6407
- title: tasksTitle,
6408
- style: { width: artifactsWidth }
6906
+ tools: toolDefinitions,
6907
+ activeTools,
6908
+ onToggleTool: toggleTool
6409
6909
  }
6410
- ))
6910
+ )
6411
6911
  );
6412
6912
  }
6413
6913
  );
6414
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
+ ];
6415
6919
 
6416
6920
  // src/components/chat/MessageActions.tsx
6417
- var import_react73 = __toESM(require("react"));
6921
+ var import_react79 = __toESM(require("react"));
6418
6922
  var import_lucide_react14 = require("lucide-react");
6419
- 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(
6420
6924
  "button",
6421
6925
  {
6422
6926
  type: "button",
@@ -6432,7 +6936,7 @@ var ActionButton2 = ({ onClick, label, children, className, disabled }) => /* @_
6432
6936
  },
6433
6937
  children
6434
6938
  );
6435
- var MessageActions = import_react73.default.forwardRef(
6939
+ var MessageActions = import_react79.default.forwardRef(
6436
6940
  ({
6437
6941
  variant,
6438
6942
  content,
@@ -6444,12 +6948,12 @@ var MessageActions = import_react73.default.forwardRef(
6444
6948
  className,
6445
6949
  ...rest
6446
6950
  }, ref) => {
6447
- const [localIsEditing, setLocalIsEditing] = (0, import_react73.useState)(false);
6448
- const [localEditValue, setLocalEditValue] = (0, import_react73.useState)(content);
6449
- 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);
6450
6954
  const isEditing = controlledIsEditing ?? localIsEditing;
6451
6955
  const editValue = controlledEditValue ?? localEditValue;
6452
- const setIsEditing = (0, import_react73.useCallback)(
6956
+ const setIsEditing = (0, import_react79.useCallback)(
6453
6957
  (value) => {
6454
6958
  if (onEditingChange) {
6455
6959
  onEditingChange(value);
@@ -6459,10 +6963,10 @@ var MessageActions = import_react73.default.forwardRef(
6459
6963
  },
6460
6964
  [onEditingChange]
6461
6965
  );
6462
- const setEditValue = (0, import_react73.useCallback)((value) => {
6966
+ const setEditValue = (0, import_react79.useCallback)((value) => {
6463
6967
  setLocalEditValue(value);
6464
6968
  }, []);
6465
- const handleCopy = (0, import_react73.useCallback)(async () => {
6969
+ const handleCopy = (0, import_react79.useCallback)(async () => {
6466
6970
  try {
6467
6971
  await navigator.clipboard.writeText(content);
6468
6972
  setCopied(true);
@@ -6478,22 +6982,22 @@ var MessageActions = import_react73.default.forwardRef(
6478
6982
  setTimeout(() => setCopied(false), 2e3);
6479
6983
  }
6480
6984
  }, [content]);
6481
- const handleStartEdit = (0, import_react73.useCallback)(() => {
6985
+ const handleStartEdit = (0, import_react79.useCallback)(() => {
6482
6986
  setLocalEditValue(content);
6483
6987
  setIsEditing(true);
6484
6988
  }, [content, setIsEditing]);
6485
- const handleCancelEdit = (0, import_react73.useCallback)(() => {
6989
+ const handleCancelEdit = (0, import_react79.useCallback)(() => {
6486
6990
  setIsEditing(false);
6487
6991
  setLocalEditValue(content);
6488
6992
  }, [content, setIsEditing]);
6489
- const handleSubmitEdit = (0, import_react73.useCallback)(() => {
6993
+ const handleSubmitEdit = (0, import_react79.useCallback)(() => {
6490
6994
  const trimmed = editValue.trim();
6491
6995
  if (trimmed && trimmed !== content) {
6492
6996
  onEdit?.(trimmed);
6493
6997
  }
6494
6998
  setIsEditing(false);
6495
6999
  }, [editValue, content, onEdit, setIsEditing]);
6496
- const handleEditKeyDown = (0, import_react73.useCallback)(
7000
+ const handleEditKeyDown = (0, import_react79.useCallback)(
6497
7001
  (e) => {
6498
7002
  if (e.key === "Enter" && !e.shiftKey) {
6499
7003
  e.preventDefault();
@@ -6506,19 +7010,19 @@ var MessageActions = import_react73.default.forwardRef(
6506
7010
  );
6507
7011
  const isUser = variant === "user";
6508
7012
  if (isUser && isEditing) {
6509
- return /* @__PURE__ */ import_react73.default.createElement(
7013
+ return /* @__PURE__ */ import_react79.default.createElement(
6510
7014
  "div",
6511
7015
  {
6512
7016
  ref,
6513
7017
  className: cx("mt-2", className),
6514
7018
  ...rest
6515
7019
  },
6516
- /* @__PURE__ */ import_react73.default.createElement(
7020
+ /* @__PURE__ */ import_react79.default.createElement(
6517
7021
  "div",
6518
7022
  {
6519
7023
  className: "relative bg-charcoal border border-ash/60 focus-within:border-gold/60 focus-within:ring-1 focus-within:ring-gold/20"
6520
7024
  },
6521
- /* @__PURE__ */ import_react73.default.createElement(
7025
+ /* @__PURE__ */ import_react79.default.createElement(
6522
7026
  "textarea",
6523
7027
  {
6524
7028
  value: editValue,
@@ -6529,15 +7033,15 @@ var MessageActions = import_react73.default.forwardRef(
6529
7033
  rows: 2
6530
7034
  }
6531
7035
  ),
6532
- /* @__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(
6533
7037
  ActionButton2,
6534
7038
  {
6535
7039
  onClick: handleCancelEdit,
6536
7040
  label: "Cancel edit",
6537
7041
  className: "text-silver/60 hover:text-error"
6538
7042
  },
6539
- /* @__PURE__ */ import_react73.default.createElement(import_lucide_react14.X, { className: "w-4 h-4" })
6540
- ), /* @__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(
6541
7045
  ActionButton2,
6542
7046
  {
6543
7047
  onClick: handleSubmitEdit,
@@ -6545,13 +7049,13 @@ var MessageActions = import_react73.default.forwardRef(
6545
7049
  className: "text-silver/60 hover:text-gold",
6546
7050
  disabled: !editValue.trim() || editValue.trim() === content
6547
7051
  },
6548
- /* @__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" })
6549
7053
  ))
6550
7054
  ),
6551
- /* @__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.")
6552
7056
  );
6553
7057
  }
6554
- return /* @__PURE__ */ import_react73.default.createElement(
7058
+ return /* @__PURE__ */ import_react79.default.createElement(
6555
7059
  "div",
6556
7060
  {
6557
7061
  ref,
@@ -6562,18 +7066,18 @@ var MessageActions = import_react73.default.forwardRef(
6562
7066
  ),
6563
7067
  ...rest
6564
7068
  },
6565
- /* @__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" })),
6566
- 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" })),
6567
- !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" }))
6568
7072
  );
6569
7073
  }
6570
7074
  );
6571
7075
  MessageActions.displayName = "MessageActions";
6572
7076
 
6573
7077
  // src/components/chat/BranchNavigator.tsx
6574
- var import_react74 = __toESM(require("react"));
7078
+ var import_react80 = __toESM(require("react"));
6575
7079
  var import_lucide_react15 = require("lucide-react");
6576
- var BranchNavigator = import_react74.default.forwardRef(
7080
+ var BranchNavigator = import_react80.default.forwardRef(
6577
7081
  ({
6578
7082
  current,
6579
7083
  total,
@@ -6592,7 +7096,7 @@ var BranchNavigator = import_react74.default.forwardRef(
6592
7096
  const buttonSize = size === "sm" ? "p-0.5" : "p-1";
6593
7097
  const iconSize = size === "sm" ? "w-3 h-3" : "w-4 h-4";
6594
7098
  const textSize = size === "sm" ? "text-xs" : "text-sm";
6595
- return /* @__PURE__ */ import_react74.default.createElement(
7099
+ return /* @__PURE__ */ import_react80.default.createElement(
6596
7100
  "div",
6597
7101
  {
6598
7102
  ref,
@@ -6604,8 +7108,8 @@ var BranchNavigator = import_react74.default.forwardRef(
6604
7108
  "aria-label": "Branch navigation",
6605
7109
  ...rest
6606
7110
  },
6607
- showIcon && /* @__PURE__ */ import_react74.default.createElement(import_lucide_react15.GitBranch, { className: cx(iconSize, "mr-0.5 text-silver/50"), "aria-hidden": "true" }),
6608
- /* @__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(
6609
7113
  "button",
6610
7114
  {
6611
7115
  type: "button",
@@ -6618,10 +7122,10 @@ var BranchNavigator = import_react74.default.forwardRef(
6618
7122
  ),
6619
7123
  "aria-label": "Previous branch"
6620
7124
  },
6621
- /* @__PURE__ */ import_react74.default.createElement(import_lucide_react15.ChevronLeft, { className: iconSize })
7125
+ /* @__PURE__ */ import_react80.default.createElement(import_lucide_react15.ChevronLeft, { className: iconSize })
6622
7126
  ),
6623
- /* @__PURE__ */ import_react74.default.createElement("span", { className: cx(textSize, "tabular-nums min-w-6 text-center") }, current, "/", total),
6624
- /* @__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(
6625
7129
  "button",
6626
7130
  {
6627
7131
  type: "button",
@@ -6634,7 +7138,7 @@ var BranchNavigator = import_react74.default.forwardRef(
6634
7138
  ),
6635
7139
  "aria-label": "Next branch"
6636
7140
  },
6637
- /* @__PURE__ */ import_react74.default.createElement(import_lucide_react15.ChevronRight, { className: iconSize })
7141
+ /* @__PURE__ */ import_react80.default.createElement(import_lucide_react15.ChevronRight, { className: iconSize })
6638
7142
  )
6639
7143
  );
6640
7144
  }
@@ -6642,16 +7146,16 @@ var BranchNavigator = import_react74.default.forwardRef(
6642
7146
  BranchNavigator.displayName = "BranchNavigator";
6643
7147
 
6644
7148
  // src/components/BrandIcon.tsx
6645
- var import_react75 = __toESM(require("react"));
7149
+ var import_react81 = __toESM(require("react"));
6646
7150
  var sizeMap2 = {
6647
7151
  sm: "h-8 w-8 text-sm",
6648
7152
  md: "h-12 w-12 text-base",
6649
7153
  lg: "h-16 w-16 text-lg"
6650
7154
  };
6651
- var BrandIcon = import_react75.default.forwardRef(
7155
+ var BrandIcon = import_react81.default.forwardRef(
6652
7156
  ({ size = "md", variant = "solid", children, className, ...rest }, ref) => {
6653
7157
  const variantClasses = variant === "solid" ? "bg-gold text-obsidian border-2 border-gold" : "bg-transparent text-gold border-2 border-gold";
6654
- return /* @__PURE__ */ import_react75.default.createElement(
7158
+ return /* @__PURE__ */ import_react81.default.createElement(
6655
7159
  "div",
6656
7160
  {
6657
7161
  ref,
@@ -6670,17 +7174,17 @@ var BrandIcon = import_react75.default.forwardRef(
6670
7174
  BrandIcon.displayName = "BrandIcon";
6671
7175
 
6672
7176
  // src/components/ColorSwatch.tsx
6673
- var import_react76 = __toESM(require("react"));
6674
- var ColorSwatch = import_react76.default.forwardRef(
7177
+ var import_react82 = __toESM(require("react"));
7178
+ var ColorSwatch = import_react82.default.forwardRef(
6675
7179
  ({ color, label, className, ...rest }, ref) => {
6676
- return /* @__PURE__ */ import_react76.default.createElement(
7180
+ return /* @__PURE__ */ import_react82.default.createElement(
6677
7181
  "div",
6678
7182
  {
6679
7183
  ref,
6680
7184
  className: cx("flex flex-col items-center gap-2", className),
6681
7185
  ...rest
6682
7186
  },
6683
- /* @__PURE__ */ import_react76.default.createElement(
7187
+ /* @__PURE__ */ import_react82.default.createElement(
6684
7188
  "div",
6685
7189
  {
6686
7190
  className: "h-16 w-16 border-2 border-ash rounded-none shadow-sm",
@@ -6688,22 +7192,22 @@ var ColorSwatch = import_react76.default.forwardRef(
6688
7192
  "aria-label": label || color
6689
7193
  }
6690
7194
  ),
6691
- 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)
6692
7196
  );
6693
7197
  }
6694
7198
  );
6695
7199
  ColorSwatch.displayName = "ColorSwatch";
6696
7200
 
6697
7201
  // src/components/SectionHeading.tsx
6698
- var import_react77 = __toESM(require("react"));
7202
+ var import_react83 = __toESM(require("react"));
6699
7203
  var levelStyles = {
6700
7204
  h2: "text-2xl mb-4",
6701
7205
  h3: "text-xl mb-3"
6702
7206
  };
6703
- var SectionHeading = import_react77.default.forwardRef(
7207
+ var SectionHeading = import_react83.default.forwardRef(
6704
7208
  ({ level = "h2", children, className, ...rest }, ref) => {
6705
7209
  const Component = level;
6706
- return /* @__PURE__ */ import_react77.default.createElement(
7210
+ return /* @__PURE__ */ import_react83.default.createElement(
6707
7211
  Component,
6708
7212
  {
6709
7213
  ref,
@@ -6720,6 +7224,13 @@ var SectionHeading = import_react77.default.forwardRef(
6720
7224
  );
6721
7225
  SectionHeading.displayName = "SectionHeading";
6722
7226
 
7227
+ // src/components/ArtifactNode.ts
7228
+ var NODE_TYPES = {
7229
+ ARTIFACT: "ARTIFACT",
7230
+ GROUP: "GROUP",
7231
+ VARIANT_SET: "VARIANT_SET"
7232
+ };
7233
+
6723
7234
  // src/index.ts
6724
7235
  var version = "2.0.0";
6725
7236
  // Annotate the CommonJS export names for ESM import in node:
@@ -6732,6 +7243,8 @@ var version = "2.0.0";
6732
7243
  Alert,
6733
7244
  AlertDialog,
6734
7245
  ArtifactCard,
7246
+ ArtifactGroup,
7247
+ ArtifactVariantStack,
6735
7248
  ArtifactsPanel,
6736
7249
  ArtifactsPanelToggle,
6737
7250
  AttachmentPreview,
@@ -6782,6 +7295,7 @@ var version = "2.0.0";
6782
7295
  ListItemText,
6783
7296
  ListSubheader,
6784
7297
  MarkdownContent,
7298
+ MediaIcon,
6785
7299
  Menu,
6786
7300
  MenuContent,
6787
7301
  MenuItem,
@@ -6791,6 +7305,7 @@ var version = "2.0.0";
6791
7305
  Message,
6792
7306
  MessageActions,
6793
7307
  Modal,
7308
+ NODE_TYPES,
6794
7309
  Navbar,
6795
7310
  NavbarBrand,
6796
7311
  NavbarContent,
@@ -6835,9 +7350,12 @@ var version = "2.0.0";
6835
7350
  ThinkingIndicator,
6836
7351
  ToastProvider,
6837
7352
  TodosList,
7353
+ ToolPanelContainer,
7354
+ ToolSidebar,
6838
7355
  Tooltip,
6839
7356
  VideoCard,
6840
7357
  addMessageToTree,
7358
+ areAllTasksSettled,
6841
7359
  createEmptyTree,
6842
7360
  createPreviewUrl,
6843
7361
  generateId,
@@ -6849,6 +7367,7 @@ var version = "2.0.0";
6849
7367
  revokePreviewUrl,
6850
7368
  switchBranch,
6851
7369
  updateNodeContent,
7370
+ useArtifactTreeNavigation,
6852
7371
  useArtifacts,
6853
7372
  useResizable,
6854
7373
  useScrollAnchor,