@nextclaw/agent-chat-ui 0.5.2 → 0.5.3

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
@@ -10,7 +10,6 @@ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
10
10
  import { cva } from "class-variance-authority";
11
11
  import { ContentEditable } from "@lexical/react/LexicalContentEditable";
12
12
  import { LexicalComposer } from "@lexical/react/LexicalComposer";
13
- import { EditorRefPlugin } from "@lexical/react/LexicalEditorRefPlugin";
14
13
  import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
15
14
  import { PlainTextPlugin } from "@lexical/react/LexicalPlainTextPlugin";
16
15
  import { $applyNodeReplacement, $createLineBreakNode, $createParagraphNode, $createRangeSelection, $createTextNode, $getRoot, $getSelection, $isElementNode, $isRangeSelection, $isTextNode, $setSelection, BLUR_COMMAND, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_HIGH, DecoratorNode, KEY_DOWN_COMMAND, SELECTION_CHANGE_COMMAND, mergeRegister } from "lexical";
@@ -256,7 +255,7 @@ function cn(...inputs) {
256
255
  //#region src/components/chat/default-skin/input.tsx
257
256
  const ChatInput = React.forwardRef(({ className, type, ...props }, ref) => /* @__PURE__ */ jsx("input", {
258
257
  type,
259
- className: cn("flex h-9 w-full rounded-xl border border-gray-200/80 bg-white px-3.5 py-2 text-sm text-gray-900 file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-gray-300 placeholder:font-normal focus:outline-none focus:ring-1 focus:ring-primary/40 focus:border-primary/40 transition-colors disabled:cursor-not-allowed disabled:opacity-50", className),
258
+ className: cn("flex h-9 w-full rounded-xl border border-border bg-card px-3.5 py-2 text-sm text-foreground file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground/55 placeholder:font-normal focus:outline-none focus:ring-1 focus:ring-primary/40 focus:border-primary/40 transition-colors disabled:cursor-not-allowed disabled:opacity-50", className),
260
259
  ref,
261
260
  ...props
262
261
  }));
@@ -276,7 +275,7 @@ const ChatPopoverContent = React.forwardRef(({ className, sideOffset = 8, align
276
275
  sideOffset,
277
276
  align,
278
277
  collisionPadding,
279
- className: cn("z-[var(--z-popover,50)] w-72 overflow-x-hidden overflow-y-auto rounded-2xl border border-gray-200/50 bg-white p-4 shadow-lg animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className),
278
+ className: cn("z-[var(--z-popover,50)] w-72 overflow-x-hidden overflow-y-auto rounded-2xl border border-border bg-popover p-4 text-popover-foreground shadow-lg animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=top]:slide-in-from-bottom-2 data-[side=right]:slide-in-from-left-2", className),
280
279
  style: {
281
280
  maxHeight: CHAT_POPOVER_CONTENT_MAX_HEIGHT,
282
281
  ...style
@@ -296,7 +295,7 @@ function createChatSelectAvailableHeightLimit(limit) {
296
295
  const CHAT_SELECT_CONTENT_MAX_HEIGHT = createChatSelectAvailableHeightLimit("24rem");
297
296
  const ChatSelectTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Trigger, {
298
297
  ref,
299
- className: cn("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-xl border border-gray-200/80 bg-white px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary/40 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", className),
298
+ className: cn("flex h-9 w-full items-center justify-between whitespace-nowrap rounded-xl border border-border bg-card px-3 py-2 text-sm text-foreground shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-primary/40 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", className),
300
299
  ...props,
301
300
  children: [children, /* @__PURE__ */ jsx(SelectPrimitive.Icon, {
302
301
  asChild: true,
@@ -320,7 +319,7 @@ const ChatSelectScrollDownButton = React.forwardRef(({ className, ...props }, re
320
319
  ChatSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
321
320
  const ChatSelectContent = React.forwardRef(({ className, children, collisionPadding = 12, position = "popper", style, viewportClassName, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(SelectPrimitive.Content, {
322
321
  ref,
323
- className: cn("relative z-50 flex max-h-96 min-w-[8rem] flex-col overflow-hidden rounded-md bg-white text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
322
+ className: cn("relative z-50 flex max-h-96 min-w-[8rem] flex-col overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", className),
324
323
  collisionPadding,
325
324
  position,
326
325
  style: {
@@ -340,13 +339,13 @@ const ChatSelectContent = React.forwardRef(({ className, children, collisionPadd
340
339
  ChatSelectContent.displayName = SelectPrimitive.Content.displayName;
341
340
  const ChatSelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Label, {
342
341
  ref,
343
- className: cn("px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-gray-500", className),
342
+ className: cn("px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground", className),
344
343
  ...props
345
344
  }));
346
345
  ChatSelectLabel.displayName = SelectPrimitive.Label.displayName;
347
346
  const ChatSelectItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(SelectPrimitive.Item, {
348
347
  ref,
349
- className: cn("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-gray-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-gray-100", className),
348
+ className: cn("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 hover:bg-accent hover:text-accent-foreground", className),
350
349
  ...props,
351
350
  children: [/* @__PURE__ */ jsx("span", {
352
351
  className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
@@ -356,7 +355,7 @@ const ChatSelectItem = React.forwardRef(({ className, children, ...props }, ref)
356
355
  ChatSelectItem.displayName = SelectPrimitive.Item.displayName;
357
356
  const ChatSelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Separator, {
358
357
  ref,
359
- className: cn("-mx-1 my-1 h-px bg-gray-100", className),
358
+ className: cn("-mx-1 my-1 h-px bg-border", className),
360
359
  ...props
361
360
  }));
362
361
  ChatSelectSeparator.displayName = SelectPrimitive.Separator.displayName;
@@ -652,12 +651,12 @@ const buttonVariants = cva("inline-flex items-center justify-center whitespace-n
652
651
  variant: {
653
652
  default: "bg-primary text-primary-foreground hover:bg-primary-600 active:bg-primary-700 shadow-sm",
654
653
  destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
655
- outline: "border border-gray-200 bg-white hover:bg-gray-50 hover:text-gray-800 text-gray-600",
656
- secondary: "bg-gray-100 text-gray-700 hover:bg-gray-200/80",
657
- ghost: "hover:bg-gray-100/80 hover:text-gray-800",
654
+ outline: "border border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground",
655
+ secondary: "bg-muted text-foreground hover:bg-accent hover:text-accent-foreground",
656
+ ghost: "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
658
657
  link: "text-primary underline-offset-4 hover:underline",
659
658
  primary: "bg-primary text-primary-foreground hover:bg-primary-600 active:bg-primary-700 shadow-sm",
660
- subtle: "bg-gray-100 text-gray-600 hover:bg-gray-200/80",
659
+ subtle: "bg-muted text-muted-foreground hover:bg-accent hover:text-accent-foreground",
661
660
  "primary-outline": "border border-primary/30 text-primary hover:bg-primary hover:text-primary-foreground"
662
661
  },
663
662
  size: {
@@ -695,30 +694,30 @@ function StopIcon() {
695
694
  return /* @__PURE__ */ jsx("span", {
696
695
  "aria-hidden": "true",
697
696
  "data-testid": "chat-stop-icon",
698
- className: "block h-3 w-3 rounded-[2px] bg-gray-700 shadow-[inset_0_0_0_1px_rgba(17,24,39,0.06)]"
697
+ className: "block h-3 w-3 rounded-[2px] bg-foreground shadow-[inset_0_0_0_1px_hsl(var(--border))]"
699
698
  });
700
699
  }
701
700
  function ContextWindowIndicator({ contextWindow }) {
702
701
  const { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } = ChatUiPrimitives;
703
702
  const clampedRatio = Math.max(0, Math.min(1, contextWindow.ratio));
704
703
  const angle = Math.round(clampedRatio * 360);
705
- const ringColor = "#9ca3af";
704
+ const ringColor = "hsl(var(--muted-foreground))";
706
705
  return /* @__PURE__ */ jsx(TooltipProvider, {
707
706
  delayDuration: 0,
708
707
  children: /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
709
708
  asChild: true,
710
709
  children: /* @__PURE__ */ jsxs("button", {
711
710
  type: "button",
712
- className: "relative inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700",
711
+ className: "relative inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
713
712
  "aria-label": contextWindow.label,
714
713
  title: contextWindow.label,
715
714
  children: [/* @__PURE__ */ jsx("span", {
716
715
  "aria-hidden": "true",
717
716
  className: "absolute inset-[7px] rounded-full",
718
- style: { background: `conic-gradient(${ringColor} ${angle}deg, #e5e7eb 0deg)` }
717
+ style: { background: `conic-gradient(${ringColor} ${angle}deg, hsl(var(--border)) 0deg)` }
719
718
  }), /* @__PURE__ */ jsx("span", {
720
719
  "aria-hidden": "true",
721
- className: "absolute inset-[10px] rounded-full bg-white"
720
+ className: "absolute inset-[10px] rounded-full bg-card"
722
721
  })]
723
722
  })
724
723
  }), /* @__PURE__ */ jsx(TooltipContent, {
@@ -727,12 +726,12 @@ function ContextWindowIndicator({ contextWindow }) {
727
726
  children: /* @__PURE__ */ jsxs("div", {
728
727
  className: "space-y-1.5 text-xs",
729
728
  children: [/* @__PURE__ */ jsxs("div", {
730
- className: "flex items-center justify-between gap-5 font-semibold text-gray-800",
729
+ className: "flex items-center justify-between gap-5 font-semibold text-foreground",
731
730
  children: [/* @__PURE__ */ jsx("span", { children: contextWindow.label }), /* @__PURE__ */ jsx("span", { children: contextWindow.percentLabel })]
732
731
  }), contextWindow.details.map((detail) => /* @__PURE__ */ jsxs("div", {
733
- className: "flex items-center justify-between gap-5 text-gray-600",
732
+ className: "flex items-center justify-between gap-5 text-muted-foreground",
734
733
  children: [/* @__PURE__ */ jsx("span", { children: detail.label }), /* @__PURE__ */ jsx("span", {
735
- className: "font-medium text-gray-800",
734
+ className: "font-medium text-foreground",
736
735
  children: detail.value
737
736
  })]
738
737
  }, detail.label))]
@@ -895,7 +894,7 @@ function ChatInputBarSkillPicker(props) {
895
894
  type: "button",
896
895
  "aria-haspopup": "listbox",
897
896
  "aria-label": picker.title,
898
- className: "relative inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg px-0 text-xs font-medium text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900 sm:w-auto sm:gap-1.5 sm:px-3",
897
+ className: "relative inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-lg px-0 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground sm:w-auto sm:gap-1.5 sm:px-3",
899
898
  children: [
900
899
  /* @__PURE__ */ jsx(BrainCircuit, { className: "h-4 w-4" }),
901
900
  /* @__PURE__ */ jsx("span", {
@@ -915,13 +914,13 @@ function ChatInputBarSkillPicker(props) {
915
914
  style: { maxHeight: SKILL_PICKER_MAX_HEIGHT },
916
915
  children: [
917
916
  /* @__PURE__ */ jsxs("div", {
918
- className: "shrink-0 space-y-2 border-b border-gray-100 px-4 py-3",
917
+ className: "shrink-0 space-y-2 border-b border-border px-4 py-3",
919
918
  children: [/* @__PURE__ */ jsx("div", {
920
- className: "text-sm font-semibold text-gray-900",
919
+ className: "text-sm font-semibold text-foreground",
921
920
  children: picker.title
922
921
  }), /* @__PURE__ */ jsxs("div", {
923
922
  className: "relative",
924
- children: [/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-3 top-2.5 h-3.5 w-3.5 text-gray-400" }), /* @__PURE__ */ jsx(Input, {
923
+ children: [/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-3 top-2.5 h-3.5 w-3.5 text-muted-foreground/70" }), /* @__PURE__ */ jsx(Input, {
925
924
  value: query,
926
925
  onChange: (event) => setQuery(event.target.value),
927
926
  onKeyDown: onSearchKeyDown,
@@ -942,10 +941,10 @@ function ChatInputBarSkillPicker(props) {
942
941
  "aria-multiselectable": "true",
943
942
  className: "custom-scrollbar min-h-0 flex-1 overflow-y-auto overscroll-contain",
944
943
  children: picker.isLoading ? /* @__PURE__ */ jsx("div", {
945
- className: "p-4 text-xs text-gray-500",
944
+ className: "p-4 text-xs text-muted-foreground",
946
945
  children: picker.loadingLabel
947
946
  }) : visibleOptions.length === 0 ? /* @__PURE__ */ jsx("div", {
948
- className: "p-4 text-center text-xs text-gray-500",
947
+ className: "p-4 text-center text-xs text-muted-foreground",
949
948
  children: picker.emptyLabel
950
949
  }) : /* @__PURE__ */ jsx("div", {
951
950
  className: "py-1",
@@ -956,7 +955,7 @@ function ChatInputBarSkillPicker(props) {
956
955
  }];
957
956
  let visibleIndex = 0;
958
957
  return groups.map((group) => /* @__PURE__ */ jsxs("div", { children: [group.label ? /* @__PURE__ */ jsx("div", {
959
- className: "px-4 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-gray-500",
958
+ className: "px-4 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground",
960
959
  children: group.label
961
960
  }) : null, group.options.map((option) => {
962
961
  const index = visibleIndex;
@@ -969,10 +968,10 @@ function ChatInputBarSkillPicker(props) {
969
968
  "aria-selected": isSelected,
970
969
  "data-skill-index": index,
971
970
  onMouseEnter: () => setActiveIndex(index),
972
- className: `flex w-full items-center gap-3 px-4 py-2.5 text-left transition-colors ${isActive ? "bg-gray-50" : "hover:bg-gray-50"}`,
971
+ className: `flex w-full items-center gap-3 px-4 py-2.5 text-left transition-colors ${isActive ? "bg-accent" : "hover:bg-accent"}`,
973
972
  children: [
974
973
  /* @__PURE__ */ jsx("div", {
975
- className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-500",
974
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground",
976
975
  children: /* @__PURE__ */ jsx(Puzzle, { className: "h-4 w-4" })
977
976
  }),
978
977
  /* @__PURE__ */ jsxs("div", {
@@ -980,14 +979,14 @@ function ChatInputBarSkillPicker(props) {
980
979
  children: [/* @__PURE__ */ jsxs("div", {
981
980
  className: "flex items-center gap-1.5",
982
981
  children: [/* @__PURE__ */ jsx("span", {
983
- className: "truncate text-sm text-gray-900",
982
+ className: "truncate text-sm text-foreground",
984
983
  children: option.label
985
984
  }), option.badgeLabel ? /* @__PURE__ */ jsx("span", {
986
985
  className: "shrink-0 rounded-full bg-primary/10 px-1.5 py-0.5 text-[10px] font-medium text-primary",
987
986
  children: option.badgeLabel
988
987
  }) : null]
989
988
  }), /* @__PURE__ */ jsx("div", {
990
- className: "mt-0.5 truncate text-xs text-gray-500",
989
+ className: "mt-0.5 truncate text-xs text-muted-foreground",
991
990
  children: option.description || option.key
992
991
  })]
993
992
  }),
@@ -997,7 +996,7 @@ function ChatInputBarSkillPicker(props) {
997
996
  type: "button",
998
997
  "aria-label": `${isSelected ? "Remove" : "Add"} ${option.label}`,
999
998
  onClick: () => onToggleOption(option.key),
1000
- className: isSelected ? "inline-flex h-5 w-5 items-center justify-center rounded-full bg-primary text-white" : "inline-flex h-5 w-5 items-center justify-center rounded-full border border-gray-300 bg-white",
999
+ className: isSelected ? "inline-flex h-5 w-5 items-center justify-center rounded-full bg-primary text-white" : "inline-flex h-5 w-5 items-center justify-center rounded-full border border-border bg-card",
1001
1000
  children: isSelected ? /* @__PURE__ */ jsx(Check, { className: "h-3 w-3" }) : null
1002
1001
  })
1003
1002
  })
@@ -1008,7 +1007,7 @@ function ChatInputBarSkillPicker(props) {
1008
1007
  })
1009
1008
  }),
1010
1009
  picker.manageHref && picker.manageLabel ? /* @__PURE__ */ jsx("div", {
1011
- className: "shrink-0 border-t border-gray-100 px-4 py-2.5",
1010
+ className: "shrink-0 border-t border-border px-4 py-2.5",
1012
1011
  children: /* @__PURE__ */ jsxs("a", {
1013
1012
  href: picker.manageHref,
1014
1013
  className: "inline-flex items-center gap-1.5 text-xs font-medium text-primary transition-colors hover:text-primary/80",
@@ -1021,7 +1020,7 @@ function ChatInputBarSkillPicker(props) {
1021
1020
  //#endregion
1022
1021
  //#region src/components/chat/ui/chat-input-bar/chat-input-bar-toolbar.tsx
1023
1022
  function ToolbarIcon({ icon }) {
1024
- return icon === "sparkles" ? /* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5 shrink-0 text-primary" }) : icon === "brain" ? /* @__PURE__ */ jsx(Brain, { className: "h-3.5 w-3.5 shrink-0 text-gray-500" }) : null;
1023
+ return icon === "sparkles" ? /* @__PURE__ */ jsx(Sparkles, { className: "h-3.5 w-3.5 shrink-0 text-primary" }) : icon === "brain" ? /* @__PURE__ */ jsx(Brain, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }) : null;
1025
1024
  }
1026
1025
  function AccessoryIcon({ icon }) {
1027
1026
  return icon === "paperclip" ? /* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ToolbarIcon, { icon });
@@ -1054,16 +1053,16 @@ function ToolbarSelectTriggerContent({ item }) {
1054
1053
  children: [
1055
1054
  /* @__PURE__ */ jsx(ToolbarIcon, { icon: item.icon }),
1056
1055
  /* @__PURE__ */ jsx("span", {
1057
- className: "nextclaw-chat-toolbar-mobile-label truncate text-xs font-semibold text-gray-700 sm:hidden [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden",
1056
+ className: "nextclaw-chat-toolbar-mobile-label truncate text-xs font-semibold text-foreground sm:hidden [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden",
1058
1057
  children: mobileSelectedLabel
1059
1058
  }),
1060
1059
  /* @__PURE__ */ jsx("span", {
1061
- className: "nextclaw-chat-toolbar-label hidden truncate text-xs font-semibold text-gray-700 sm:inline [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden",
1060
+ className: "nextclaw-chat-toolbar-label hidden truncate text-xs font-semibold text-foreground sm:inline [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden",
1062
1061
  children: item.selectedLabel
1063
1062
  })
1064
1063
  ]
1065
1064
  });
1066
- if (item.loading) return /* @__PURE__ */ jsx("div", { className: "h-3 w-24 animate-pulse rounded bg-gray-200" });
1065
+ if (item.loading) return /* @__PURE__ */ jsx("div", { className: "h-3 w-24 animate-pulse rounded bg-muted" });
1067
1066
  return /* @__PURE__ */ jsx("span", {
1068
1067
  className: "truncate",
1069
1068
  children: item.placeholder
@@ -1073,14 +1072,14 @@ function ToolbarSelectOptionContent({ option }) {
1073
1072
  return option.description ? /* @__PURE__ */ jsxs("div", {
1074
1073
  className: "flex min-w-0 flex-col gap-0.5",
1075
1074
  children: [/* @__PURE__ */ jsx("span", {
1076
- className: "truncate text-xs font-semibold text-gray-800",
1075
+ className: "truncate text-xs font-semibold text-foreground",
1077
1076
  children: option.label
1078
1077
  }), /* @__PURE__ */ jsx("span", {
1079
- className: "truncate text-[11px] text-gray-500",
1078
+ className: "truncate text-[11px] text-muted-foreground",
1080
1079
  children: option.description
1081
1080
  })]
1082
1081
  }) : /* @__PURE__ */ jsx("span", {
1083
- className: "truncate text-xs font-semibold text-gray-800",
1082
+ className: "truncate text-xs font-semibold text-foreground",
1084
1083
  children: option.label
1085
1084
  });
1086
1085
  }
@@ -1114,8 +1113,8 @@ function ToolbarSearchableSelect({ item }) {
1114
1113
  type: "button",
1115
1114
  "aria-label": item.selectedLabel ? `${item.placeholder}: ${item.selectedLabel}` : item.placeholder,
1116
1115
  disabled: item.disabled,
1117
- className: `nextclaw-chat-toolbar-select-trigger inline-flex h-8 w-auto items-center justify-between rounded-lg border-0 bg-transparent px-2 text-xs font-medium text-gray-600 shadow-none hover:bg-gray-100 focus:outline-none focus:ring-0 disabled:cursor-not-allowed disabled:opacity-50 sm:px-3 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!basis-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!justify-center [@container_nextclaw-chat-input-bar_(max-width:440px)]:!max-w-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!min-w-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!px-0 ${TRIGGER_WIDTH_BY_KEY[item.key] ?? ""}`,
1118
- children: [/* @__PURE__ */ jsx(ToolbarSelectTriggerContent, { item }), /* @__PURE__ */ jsx(ChevronDown, { className: "ml-1 h-3.5 w-3.5 shrink-0 text-gray-400 [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden" })]
1116
+ className: `nextclaw-chat-toolbar-select-trigger inline-flex h-8 w-auto items-center justify-between rounded-lg border-0 bg-transparent px-2 text-xs font-medium text-muted-foreground shadow-none hover:bg-accent hover:text-accent-foreground focus:outline-none focus:ring-0 disabled:cursor-not-allowed disabled:opacity-50 sm:px-3 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!basis-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!justify-center [@container_nextclaw-chat-input-bar_(max-width:440px)]:!max-w-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!min-w-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!px-0 ${TRIGGER_WIDTH_BY_KEY[item.key] ?? ""}`,
1117
+ children: [/* @__PURE__ */ jsx(ToolbarSelectTriggerContent, { item }), /* @__PURE__ */ jsx(ChevronDown, { className: "ml-1 h-3.5 w-3.5 shrink-0 text-muted-foreground/70 [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden" })]
1119
1118
  })
1120
1119
  }), /* @__PURE__ */ jsxs(PopoverContent, {
1121
1120
  className: `flex flex-col overflow-hidden p-2 ${CONTENT_WIDTH_BY_KEY[item.key] ?? ""}`,
@@ -1123,7 +1122,7 @@ function ToolbarSearchableSelect({ item }) {
1123
1122
  children: [
1124
1123
  /* @__PURE__ */ jsxs("div", {
1125
1124
  className: "relative mb-2 shrink-0",
1126
- children: [/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-gray-400" }), /* @__PURE__ */ jsx(Input, {
1125
+ children: [/* @__PURE__ */ jsx(Search, { className: "pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-muted-foreground/70" }), /* @__PURE__ */ jsx(Input, {
1127
1126
  value: query,
1128
1127
  onChange: (event) => setQuery(event.currentTarget.value),
1129
1128
  placeholder: item.search?.placeholder ?? item.placeholder,
@@ -1133,31 +1132,31 @@ function ToolbarSearchableSelect({ item }) {
1133
1132
  !hasOptions ? item.loading ? /* @__PURE__ */ jsxs("div", {
1134
1133
  className: "space-y-2 px-2 py-1",
1135
1134
  children: [
1136
- /* @__PURE__ */ jsx("div", { className: "h-3 w-36 animate-pulse rounded bg-gray-200" }),
1137
- /* @__PURE__ */ jsx("div", { className: "h-3 w-28 animate-pulse rounded bg-gray-200" }),
1138
- /* @__PURE__ */ jsx("div", { className: "h-3 w-32 animate-pulse rounded bg-gray-200" })
1135
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-36 animate-pulse rounded bg-muted" }),
1136
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-28 animate-pulse rounded bg-muted" }),
1137
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-32 animate-pulse rounded bg-muted" })
1139
1138
  ]
1140
1139
  }) : item.emptyLabel ? /* @__PURE__ */ jsx("div", {
1141
- className: "px-2 py-1 text-xs text-gray-500",
1140
+ className: "px-2 py-1 text-xs text-muted-foreground",
1142
1141
  children: item.emptyLabel
1143
1142
  }) : null : null,
1144
1143
  hasOptions && !hasFilteredOptions ? /* @__PURE__ */ jsx("div", {
1145
- className: "px-2 py-1 text-xs text-gray-500",
1144
+ className: "px-2 py-1 text-xs text-muted-foreground",
1146
1145
  children: item.search?.emptyLabel ?? item.emptyLabel
1147
1146
  }) : null,
1148
1147
  /* @__PURE__ */ jsx("div", {
1149
1148
  className: "min-h-0 flex-1 overflow-y-auto overscroll-contain",
1150
1149
  children: filteredGroups.map((group, groupIndex) => /* @__PURE__ */ jsxs("div", {
1151
- className: groupIndex > 0 ? "border-t border-gray-100 pt-1" : void 0,
1150
+ className: groupIndex > 0 ? "border-t border-border pt-1" : void 0,
1152
1151
  children: [group.label ? /* @__PURE__ */ jsx("div", {
1153
- className: "px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-gray-500",
1152
+ className: "px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground",
1154
1153
  children: group.label
1155
1154
  }) : null, group.options.map((option) => {
1156
1155
  const isSelected = item.value === option.value;
1157
1156
  const isActive = activeValues.has(option.value);
1158
1157
  const actionLabel = isActive ? action?.activeLabel : action?.inactiveLabel;
1159
1158
  return /* @__PURE__ */ jsxs("div", {
1160
- className: "group flex items-center gap-1 rounded-md hover:bg-gray-100",
1159
+ className: "group flex items-center gap-1 rounded-md hover:bg-accent",
1161
1160
  children: [/* @__PURE__ */ jsxs("button", {
1162
1161
  type: "button",
1163
1162
  className: "flex min-w-0 flex-1 items-center gap-2 rounded-md px-2 py-2 text-left",
@@ -1176,7 +1175,7 @@ function ToolbarSearchableSelect({ item }) {
1176
1175
  type: "button",
1177
1176
  "aria-label": actionLabel,
1178
1177
  "aria-pressed": isActive,
1179
- className: "mr-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-gray-400 transition-colors hover:bg-white hover:text-amber-500 focus:outline-none focus:ring-1 focus:ring-primary/40",
1178
+ className: "mr-1 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-md text-muted-foreground/70 transition-colors hover:bg-card hover:text-amber-500 focus:outline-none focus:ring-1 focus:ring-primary/40",
1180
1179
  onClick: (event) => {
1181
1180
  event.stopPropagation();
1182
1181
  action.onToggle(option.value, !isActive);
@@ -1210,7 +1209,7 @@ function ToolbarSelect({ item }) {
1210
1209
  children: [/* @__PURE__ */ jsx(SelectTrigger, {
1211
1210
  "aria-label": item.selectedLabel ? `${item.placeholder}: ${item.selectedLabel}` : item.placeholder,
1212
1211
  title: item.selectedLabel,
1213
- className: `nextclaw-chat-toolbar-select-trigger h-8 w-auto rounded-lg border-0 bg-transparent px-2 text-xs font-medium text-gray-600 shadow-none hover:bg-gray-100 focus:ring-0 sm:px-3 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!basis-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!justify-center [@container_nextclaw-chat-input-bar_(max-width:440px)]:!max-w-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!min-w-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!px-0 ${TRIGGER_WIDTH_BY_KEY[item.key] ?? ""}`,
1212
+ className: `nextclaw-chat-toolbar-select-trigger h-8 w-auto rounded-lg border-0 bg-transparent px-2 text-xs font-medium text-muted-foreground shadow-none hover:bg-accent hover:text-accent-foreground focus:ring-0 sm:px-3 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!basis-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!justify-center [@container_nextclaw-chat-input-bar_(max-width:440px)]:!max-w-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!min-w-8 [@container_nextclaw-chat-input-bar_(max-width:440px)]:!px-0 ${TRIGGER_WIDTH_BY_KEY[item.key] ?? ""}`,
1214
1213
  children: item.selectedLabel || item.loading ? /* @__PURE__ */ jsx(ToolbarSelectTriggerContent, { item }) : /* @__PURE__ */ jsx(SelectValue, { placeholder: item.placeholder })
1215
1214
  }), /* @__PURE__ */ jsxs(SelectContent, {
1216
1215
  className: CONTENT_WIDTH_BY_KEY[item.key] ?? "",
@@ -1218,12 +1217,12 @@ function ToolbarSelect({ item }) {
1218
1217
  children: [!hasOptions ? item.loading ? /* @__PURE__ */ jsxs("div", {
1219
1218
  className: "space-y-2 px-3 py-2",
1220
1219
  children: [
1221
- /* @__PURE__ */ jsx("div", { className: "h-3 w-36 animate-pulse rounded bg-gray-200" }),
1222
- /* @__PURE__ */ jsx("div", { className: "h-3 w-28 animate-pulse rounded bg-gray-200" }),
1223
- /* @__PURE__ */ jsx("div", { className: "h-3 w-32 animate-pulse rounded bg-gray-200" })
1220
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-36 animate-pulse rounded bg-muted" }),
1221
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-28 animate-pulse rounded bg-muted" }),
1222
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-32 animate-pulse rounded bg-muted" })
1224
1223
  ]
1225
1224
  }) : item.emptyLabel ? /* @__PURE__ */ jsx("div", {
1226
- className: "px-3 py-2 text-xs text-gray-500",
1225
+ className: "px-3 py-2 text-xs text-muted-foreground",
1227
1226
  children: item.emptyLabel
1228
1227
  }) : null : null, groups.map((group, groupIndex) => /* @__PURE__ */ jsxs("div", { children: [groupIndex > 0 ? /* @__PURE__ */ jsx(SelectSeparator, {}) : null, /* @__PURE__ */ jsxs(SelectGroup, { children: [group.label ? /* @__PURE__ */ jsx(SelectLabel, { children: group.label }) : null, group.options.map((option) => /* @__PURE__ */ jsx(SelectItem, {
1229
1228
  value: option.value,
@@ -1245,7 +1244,7 @@ function ChatInputBarToolbar({ actions, accessories, selects, skillPicker }) {
1245
1244
  accessories?.map((item) => {
1246
1245
  const button = /* @__PURE__ */ jsxs("button", {
1247
1246
  type: "button",
1248
- className: `inline-flex items-center rounded-lg py-1.5 text-xs font-medium text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900 disabled:cursor-not-allowed disabled:text-gray-400 ${item.iconOnly ? "h-8 w-8 justify-center px-0" : "gap-1.5 px-3"}`,
1247
+ className: `inline-flex items-center rounded-lg py-1.5 text-xs font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:text-muted-foreground/50 ${item.iconOnly ? "h-8 w-8 justify-center px-0" : "gap-1.5 px-3"}`,
1249
1248
  onClick: item.onClick,
1250
1249
  disabled: item.disabled,
1251
1250
  "aria-label": item.label,
@@ -1699,7 +1698,7 @@ function insertInputSurfaceItemIntoChatComposer(params) {
1699
1698
  });
1700
1699
  }
1701
1700
  function getChatComposerNodesSignature(nodes) {
1702
- return nodes.map((node) => node.type === "text" ? `text:${node.id}:${node.text}` : `token:${node.id}:${node.tokenKind}:${node.tokenKey}:${node.label}`).join("");
1701
+ return nodes.map((node) => node.type === "text" ? `text:${node.text}` : `token:${node.tokenKind}:${node.tokenKey}:${node.label}`).join("");
1703
1702
  }
1704
1703
  function replaceChatComposerSelectionWithText(params) {
1705
1704
  const { nodes, selection, text } = params;
@@ -1800,66 +1799,6 @@ function resolveLexicalComposerKeyboardAction(params) {
1800
1799
  };
1801
1800
  return { type: "noop" };
1802
1801
  }
1803
- var LexicalComposerHandleOwner = class {
1804
- constructor(params) {
1805
- this.params = params;
1806
- this.insertInputSurfaceItem = (item, triggerSpecs = [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC]) => {
1807
- this.params.onInputSurfaceItemSelect?.(item);
1808
- this.params.publishSnapshot(insertInputSurfaceItemIntoChatComposer({
1809
- item,
1810
- nodes: this.params.optionsReader().nodes,
1811
- selection: this.params.optionsReader().selection,
1812
- triggerSpecs
1813
- }), { focusAfterSync: true });
1814
- };
1815
- this.insertSlashItem = (item) => {
1816
- this.insertInputSurfaceItem(item);
1817
- };
1818
- this.insertFileToken = (tokenKey, label) => {
1819
- this.params.publishSnapshot(insertFileTokenIntoChatComposer({
1820
- label,
1821
- nodes: this.params.optionsReader().nodes,
1822
- selection: this.params.optionsReader().selection,
1823
- tokenKey
1824
- }), { focusAfterSync: true });
1825
- };
1826
- this.insertFileTokens = (tokens) => {
1827
- let nextNodes = this.params.optionsReader().nodes;
1828
- let nextSelection = this.params.optionsReader().selection;
1829
- for (const token of tokens) {
1830
- const snapshot = insertFileTokenIntoChatComposer({
1831
- label: token.label,
1832
- nodes: nextNodes,
1833
- selection: nextSelection,
1834
- tokenKey: token.tokenKey
1835
- });
1836
- nextNodes = snapshot.nodes;
1837
- nextSelection = snapshot.selection;
1838
- }
1839
- this.params.publishSnapshot({
1840
- nodes: nextNodes,
1841
- selection: nextSelection
1842
- }, { focusAfterSync: true });
1843
- };
1844
- this.focusComposer = () => {
1845
- this.params.focusComposer();
1846
- };
1847
- this.focusComposerAtEnd = (nodes) => {
1848
- this.params.focusComposerAtEnd(nodes);
1849
- };
1850
- this.syncSelectedSkills = (nextKeys, options) => {
1851
- this.params.publishSnapshot(syncSelectedSkillsIntoChatComposer({
1852
- nextKeys,
1853
- nodes: this.params.optionsReader().nodes,
1854
- options,
1855
- selection: this.params.optionsReader().selection
1856
- }), { focusAfterSync: true });
1857
- };
1858
- }
1859
- };
1860
- function createLexicalComposerHandle(params) {
1861
- return new LexicalComposerHandleOwner(params);
1862
- }
1863
1802
  function getChatComposerContentSignature(nodes) {
1864
1803
  return JSON.stringify(nodes.map((node) => node.type === "text" ? {
1865
1804
  text: node.text,
@@ -1887,12 +1826,13 @@ function handleLexicalComposerBeforeInput(params) {
1887
1826
  } });
1888
1827
  }
1889
1828
  function handleLexicalComposerCompositionEnd(params) {
1890
- const { data, fallbackSnapshot, publishSnapshot, snapshotReader } = params;
1829
+ const { compositionStartSnapshot, data, fallbackSnapshot, publishSnapshot, snapshotReader } = params;
1891
1830
  const currentSnapshot = snapshotReader();
1892
1831
  const editorSnapshot = fallbackSnapshot();
1893
- publishSnapshot(getChatComposerContentSignature(editorSnapshot.nodes) !== getChatComposerContentSignature(currentSnapshot.nodes) ? editorSnapshot : data.length > 0 ? replaceChatComposerSelectionWithText({
1894
- nodes: currentSnapshot.nodes,
1895
- selection: currentSnapshot.selection,
1832
+ const baseSnapshot = compositionStartSnapshot ?? currentSnapshot;
1833
+ publishSnapshot(getChatComposerContentSignature(editorSnapshot.nodes) !== getChatComposerContentSignature(baseSnapshot.nodes) ? editorSnapshot : data.length > 0 ? replaceChatComposerSelectionWithText({
1834
+ nodes: baseSnapshot.nodes,
1835
+ selection: baseSnapshot.selection,
1896
1836
  text: data
1897
1837
  }) : editorSnapshot, {
1898
1838
  forcePublish: true,
@@ -1941,182 +1881,314 @@ function handleLexicalComposerKeyboardCommand(params) {
1941
1881
  }
1942
1882
  }
1943
1883
  //#endregion
1884
+ //#region src/components/chat/ui/chat-input-bar/lexical/owners/chat-composer-lexical-owner.ts
1885
+ function createMutableRef(value) {
1886
+ return { current: value };
1887
+ }
1888
+ function getChatComposerDocumentLength(nodes) {
1889
+ return nodes.reduce((cursor, node) => cursor + (node.type === "text" ? node.text.length : 1), 0);
1890
+ }
1891
+ var ChatComposerLexicalOwner = class {
1892
+ constructor() {
1893
+ this.isApplyingExternalUpdateRef = createMutableRef(false);
1894
+ this.isComposingRef = createMutableRef(false);
1895
+ this.pendingOwnerSignatureRef = createMutableRef(null);
1896
+ this.pendingSelectionRef = createMutableRef(null);
1897
+ this.selectionRef = createMutableRef(null);
1898
+ this.shouldFocusAfterSyncRef = createMutableRef(false);
1899
+ this.compositionStartSnapshotRef = createMutableRef(null);
1900
+ this.editorSignatureRef = createMutableRef("");
1901
+ this.lastPublishedSignatureRef = createMutableRef("");
1902
+ this.pendingInputSurfaceReasonRef = createMutableRef(null);
1903
+ this.editor = null;
1904
+ this.runtime = null;
1905
+ this.configureRuntime = (runtime) => {
1906
+ this.runtime = runtime;
1907
+ };
1908
+ this.bindEditor = (editor) => {
1909
+ this.editor = editor;
1910
+ return () => {
1911
+ if (this.editor === editor) this.editor = null;
1912
+ };
1913
+ };
1914
+ this.registerEditorListeners = (editor) => {
1915
+ return mergeRegister(editor.registerUpdateListener(({ editorState }) => {
1916
+ const runtime = this.getRuntime();
1917
+ this.handleEditorUpdate(editorState, runtime.callbacks);
1918
+ }), editor.registerCommand(SELECTION_CHANGE_COMMAND, () => {
1919
+ const runtime = this.getRuntime();
1920
+ this.handleSelectionChange(editor, runtime.callbacks);
1921
+ return false;
1922
+ }, COMMAND_PRIORITY_EDITOR), editor.registerCommand(BLUR_COMMAND, () => {
1923
+ this.getRuntime().callbacks.onInputSurfaceOpenChange?.(false);
1924
+ return false;
1925
+ }, COMMAND_PRIORITY_EDITOR), editor.registerCommand(KEY_DOWN_COMMAND, (event) => {
1926
+ const runtime = this.getRuntime();
1927
+ return this.handleKeyDown({
1928
+ actions: runtime.actions,
1929
+ callbacks: runtime.callbacks,
1930
+ event,
1931
+ fallbackNodes: runtime.fallbackNodes
1932
+ });
1933
+ }, COMMAND_PRIORITY_HIGH));
1934
+ };
1935
+ this.syncExternalState = (editor, nodes) => {
1936
+ if (this.isComposingRef.current) return;
1937
+ const nextSignature = getChatComposerNodesSignature(nodes);
1938
+ const pendingSelection = this.pendingSelectionRef.current;
1939
+ const pendingOwnerSignature = this.pendingOwnerSignatureRef.current;
1940
+ if (pendingOwnerSignature) {
1941
+ if (nextSignature === pendingOwnerSignature) this.pendingOwnerSignatureRef.current = null;
1942
+ else if (nextSignature !== this.editorSignatureRef.current) return;
1943
+ }
1944
+ const shouldSyncDocument = nextSignature !== this.editorSignatureRef.current;
1945
+ if (!shouldSyncDocument && !pendingSelection) return;
1946
+ this.startApplyingExternalUpdate();
1947
+ if (shouldSyncDocument) {
1948
+ syncLexicalEditorFromChatComposerState(editor, nodes, pendingSelection);
1949
+ this.editorSignatureRef.current = nextSignature;
1950
+ this.lastPublishedSignatureRef.current = nextSignature;
1951
+ } else if (pendingSelection) syncLexicalSelectionFromChatComposerSelection(editor, pendingSelection);
1952
+ if (pendingSelection) {
1953
+ this.selectionRef.current = pendingSelection;
1954
+ this.pendingSelectionRef.current = null;
1955
+ }
1956
+ if (this.shouldFocusAfterSyncRef.current) {
1957
+ this.shouldFocusAfterSyncRef.current = false;
1958
+ const targetSelection = this.selectionRef.current;
1959
+ editor.focus(() => {
1960
+ if (targetSelection) syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);
1961
+ });
1962
+ }
1963
+ };
1964
+ this.publishSnapshot = (snapshot, callbacks, options) => {
1965
+ this.selectionRef.current = snapshot.selection;
1966
+ this.pendingSelectionRef.current = snapshot.selection;
1967
+ if (options?.focusAfterSync) this.shouldFocusAfterSyncRef.current = true;
1968
+ const signature = getChatComposerNodesSignature(snapshot.nodes);
1969
+ const { editor } = this;
1970
+ this.pendingOwnerSignatureRef.current = signature;
1971
+ if (editor) {
1972
+ this.startApplyingExternalUpdate();
1973
+ syncLexicalEditorFromChatComposerState(editor, snapshot.nodes, snapshot.selection);
1974
+ this.editorSignatureRef.current = signature;
1975
+ }
1976
+ callbacks.onInputSurfaceSnapshotChange?.(snapshot.nodes, snapshot.selection, options?.inputSurfaceReason ?? { type: "programmatic" });
1977
+ if (options?.forcePublish || signature !== this.lastPublishedSignatureRef.current) {
1978
+ this.lastPublishedSignatureRef.current = signature;
1979
+ callbacks.onNodesChange(snapshot.nodes);
1980
+ }
1981
+ };
1982
+ this.focusComposer = () => {
1983
+ const { editor } = this;
1984
+ if (!editor) return;
1985
+ editor.getRootElement()?.focus({ preventScroll: true });
1986
+ const targetSelection = this.selectionRef.current;
1987
+ if (targetSelection) syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);
1988
+ editor.focus();
1989
+ };
1990
+ this.focusComposerAtEnd = (nodes) => {
1991
+ const { editor } = this;
1992
+ if (!editor) return;
1993
+ const end = getChatComposerDocumentLength(nodes ?? readChatComposerSnapshotFromEditorState(editor.getEditorState()).nodes);
1994
+ const targetSelection = {
1995
+ start: end,
1996
+ end
1997
+ };
1998
+ this.selectionRef.current = targetSelection;
1999
+ this.pendingSelectionRef.current = targetSelection;
2000
+ editor.getRootElement()?.focus({ preventScroll: true });
2001
+ if (nodes) {
2002
+ this.startApplyingExternalUpdate();
2003
+ const signature = getChatComposerNodesSignature(nodes);
2004
+ syncLexicalEditorFromChatComposerState(editor, nodes, targetSelection);
2005
+ this.editorSignatureRef.current = signature;
2006
+ this.lastPublishedSignatureRef.current = signature;
2007
+ } else syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);
2008
+ editor.focus(() => {
2009
+ syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);
2010
+ });
2011
+ };
2012
+ this.readComposerSnapshot = (fallbackNodes) => {
2013
+ const { editor } = this;
2014
+ if (!editor) return {
2015
+ nodes: fallbackNodes,
2016
+ selection: this.selectionRef.current
2017
+ };
2018
+ const snapshot = readChatComposerSnapshotFromEditorState(editor.getEditorState());
2019
+ this.selectionRef.current = snapshot.selection;
2020
+ return snapshot;
2021
+ };
2022
+ this.createHandle = () => {
2023
+ const insertInputSurfaceItem = (item, triggerSpecs = [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC]) => {
2024
+ const { callbacks } = this.getRuntime();
2025
+ callbacks.onInputSurfaceItemSelect?.(item);
2026
+ this.publishRuntimeSnapshot((snapshot) => insertInputSurfaceItemIntoChatComposer({
2027
+ item,
2028
+ nodes: snapshot.nodes,
2029
+ selection: snapshot.selection,
2030
+ triggerSpecs
2031
+ }), { focusAfterSync: true });
2032
+ };
2033
+ return {
2034
+ insertInputSurfaceItem,
2035
+ insertSlashItem: (item) => {
2036
+ insertInputSurfaceItem(item);
2037
+ },
2038
+ insertFileToken: (tokenKey, label) => {
2039
+ this.publishRuntimeSnapshot((snapshot) => insertFileTokenIntoChatComposer({
2040
+ label,
2041
+ nodes: snapshot.nodes,
2042
+ selection: snapshot.selection,
2043
+ tokenKey
2044
+ }), { focusAfterSync: true });
2045
+ },
2046
+ insertFileTokens: (tokens) => {
2047
+ this.publishRuntimeSnapshot((snapshot) => tokens.reduce((nextSnapshot, token) => insertFileTokenIntoChatComposer({
2048
+ label: token.label,
2049
+ nodes: nextSnapshot.nodes,
2050
+ selection: nextSnapshot.selection,
2051
+ tokenKey: token.tokenKey
2052
+ }), snapshot), { focusAfterSync: true });
2053
+ },
2054
+ focusComposer: this.focusComposer,
2055
+ focusComposerAtEnd: this.focusComposerAtEnd,
2056
+ syncSelectedSkills: (nextKeys, options) => {
2057
+ this.publishRuntimeSnapshot((snapshot) => syncSelectedSkillsIntoChatComposer({
2058
+ nextKeys,
2059
+ nodes: snapshot.nodes,
2060
+ options,
2061
+ selection: snapshot.selection
2062
+ }), { focusAfterSync: true });
2063
+ }
2064
+ };
2065
+ };
2066
+ this.handleBeforeInput = (params) => {
2067
+ const { disabled, event } = params;
2068
+ const { callbacks, fallbackNodes } = this.getRuntime();
2069
+ handleLexicalComposerBeforeInput({
2070
+ disabled,
2071
+ event,
2072
+ isComposing: this.isComposingRef.current,
2073
+ publishSnapshot: (snapshot, options) => this.publishSnapshot(snapshot, callbacks, options),
2074
+ snapshotReader: () => this.readComposerSnapshot(fallbackNodes)
2075
+ });
2076
+ };
2077
+ this.handleCompositionStart = () => {
2078
+ const { fallbackNodes } = this.getRuntime();
2079
+ this.compositionStartSnapshotRef.current = this.readComposerSnapshot(fallbackNodes);
2080
+ this.isComposingRef.current = true;
2081
+ };
2082
+ this.handleCompositionEnd = (params) => {
2083
+ const { data } = params;
2084
+ const { callbacks, fallbackNodes } = this.getRuntime();
2085
+ this.isComposingRef.current = false;
2086
+ handleLexicalComposerCompositionEnd({
2087
+ compositionStartSnapshot: this.compositionStartSnapshotRef.current,
2088
+ data,
2089
+ fallbackSnapshot: () => this.readComposerSnapshot(fallbackNodes),
2090
+ publishSnapshot: (snapshot, options) => this.publishSnapshot(snapshot, callbacks, options),
2091
+ snapshotReader: () => this.readComposerSnapshot(fallbackNodes)
2092
+ });
2093
+ this.compositionStartSnapshotRef.current = null;
2094
+ };
2095
+ this.handleKeyDown = (params) => {
2096
+ const { actions, callbacks, event, fallbackNodes } = params;
2097
+ if (event.key.length === 1 && !event.isComposing && !event.altKey && !event.ctrlKey && !event.metaKey) this.pendingInputSurfaceReasonRef.current = {
2098
+ type: "insert-text",
2099
+ text: event.key
2100
+ };
2101
+ const snapshot = this.readComposerSnapshot(fallbackNodes);
2102
+ if (callbacks.onInputSurfaceKeyDown?.(event)) return true;
2103
+ return handleLexicalComposerKeyboardCommand({
2104
+ actions,
2105
+ nativeEvent: event,
2106
+ publishSnapshot: (nextSnapshot, options) => this.publishSnapshot(nextSnapshot, callbacks, options),
2107
+ snapshot
2108
+ });
2109
+ };
2110
+ this.handleEditorUpdate = (editorState, callbacks) => {
2111
+ const snapshot = readChatComposerSnapshotFromEditorState(editorState);
2112
+ const signature = getChatComposerNodesSignature(snapshot.nodes);
2113
+ this.editorSignatureRef.current = signature;
2114
+ if (this.isApplyingExternalUpdateRef.current || this.isComposingRef.current) return;
2115
+ this.selectionRef.current = snapshot.selection;
2116
+ callbacks.onInputSurfaceSnapshotChange?.(snapshot.nodes, snapshot.selection, this.consumeInputSurfaceReason() ?? { type: "sync" });
2117
+ if (signature === this.lastPublishedSignatureRef.current) return;
2118
+ this.lastPublishedSignatureRef.current = signature;
2119
+ callbacks.onNodesChange(snapshot.nodes);
2120
+ };
2121
+ this.handleSelectionChange = (editor, callbacks) => {
2122
+ const snapshot = readChatComposerSnapshotFromEditorState(editor.getEditorState());
2123
+ if (this.isComposingRef.current) return;
2124
+ this.selectionRef.current = snapshot.selection;
2125
+ callbacks.onInputSurfaceSnapshotChange?.(snapshot.nodes, snapshot.selection, { type: "selection" });
2126
+ };
2127
+ this.consumeInputSurfaceReason = () => {
2128
+ const reason = this.pendingInputSurfaceReasonRef.current;
2129
+ this.pendingInputSurfaceReasonRef.current = null;
2130
+ return reason;
2131
+ };
2132
+ this.publishRuntimeSnapshot = (createSnapshot, options) => {
2133
+ const { callbacks, fallbackNodes } = this.getRuntime();
2134
+ this.publishSnapshot(createSnapshot(this.readComposerSnapshot(fallbackNodes)), callbacks, options);
2135
+ };
2136
+ this.startApplyingExternalUpdate = () => {
2137
+ this.isApplyingExternalUpdateRef.current = true;
2138
+ requestAnimationFrame(() => {
2139
+ this.isApplyingExternalUpdateRef.current = false;
2140
+ });
2141
+ };
2142
+ this.getRuntime = () => {
2143
+ if (!this.runtime) throw new Error("ChatComposerLexicalOwner runtime has not been configured.");
2144
+ return this.runtime;
2145
+ };
2146
+ }
2147
+ };
2148
+ //#endregion
1944
2149
  //#region src/components/chat/ui/chat-input-bar/lexical/chat-composer-plugins.tsx
1945
- function ChatComposerBindingsPlugin({ disabled, editorRef, editorSignatureRef, isApplyingExternalUpdateRef, isComposingRef, lastPublishedSignatureRef, nodes, onBlur, consumeInputSurfaceReason, onKeyDown, onNodesChange, pendingSelectionRef, selectionRef, shouldFocusAfterSyncRef, syncInputSurfaceSnapshot }) {
2150
+ function ChatComposerBindingsPlugin({ disabled, nodes, owner }) {
1946
2151
  const [editor] = useLexicalComposerContext();
1947
2152
  useLayoutEffect(() => {
1948
- editorRef.current = editor;
1949
- return () => {
1950
- if (editorRef.current === editor) editorRef.current = null;
1951
- };
1952
- }, [editor, editorRef]);
2153
+ return owner.bindEditor(editor);
2154
+ }, [editor, owner]);
1953
2155
  useLayoutEffect(() => {
1954
2156
  editor.setEditable(!disabled);
1955
- }, [disabled, editor]);
1956
- useLayoutEffect(() => {
1957
- const nextSignature = getChatComposerNodesSignature(nodes);
1958
- const pendingSelection = pendingSelectionRef.current;
1959
- const shouldSyncDocument = nextSignature !== editorSignatureRef.current;
1960
- if (!shouldSyncDocument && !pendingSelection) return;
1961
- isApplyingExternalUpdateRef.current = true;
1962
- if (shouldSyncDocument) {
1963
- syncLexicalEditorFromChatComposerState(editor, nodes, pendingSelection);
1964
- editorSignatureRef.current = nextSignature;
1965
- lastPublishedSignatureRef.current = nextSignature;
1966
- } else if (pendingSelection) syncLexicalSelectionFromChatComposerSelection(editor, pendingSelection);
1967
- if (pendingSelection) {
1968
- selectionRef.current = pendingSelection;
1969
- pendingSelectionRef.current = null;
1970
- }
1971
- if (shouldFocusAfterSyncRef.current) {
1972
- shouldFocusAfterSyncRef.current = false;
1973
- const targetSelection = selectionRef.current;
1974
- editor.focus(() => {
1975
- if (targetSelection) syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);
1976
- });
1977
- }
1978
- requestAnimationFrame(() => {
1979
- isApplyingExternalUpdateRef.current = false;
1980
- });
2157
+ owner.syncExternalState(editor, nodes);
1981
2158
  }, [
2159
+ disabled,
1982
2160
  editor,
1983
- editorSignatureRef,
1984
- isApplyingExternalUpdateRef,
1985
- lastPublishedSignatureRef,
1986
2161
  nodes,
1987
- pendingSelectionRef,
1988
- selectionRef,
1989
- shouldFocusAfterSyncRef
2162
+ owner
1990
2163
  ]);
1991
2164
  useEffect(() => {
1992
- return mergeRegister(editor.registerUpdateListener(({ editorState }) => {
1993
- const snapshot = readChatComposerSnapshotFromEditorState(editorState);
1994
- const signature = getChatComposerNodesSignature(snapshot.nodes);
1995
- selectionRef.current = snapshot.selection;
1996
- editorSignatureRef.current = signature;
1997
- if (isApplyingExternalUpdateRef.current || isComposingRef.current) return;
1998
- syncInputSurfaceSnapshot(snapshot.nodes, snapshot.selection, consumeInputSurfaceReason() ?? { type: "sync" });
1999
- if (signature === lastPublishedSignatureRef.current) return;
2000
- lastPublishedSignatureRef.current = signature;
2001
- onNodesChange(snapshot.nodes);
2002
- }), editor.registerCommand(SELECTION_CHANGE_COMMAND, () => {
2003
- const snapshot = readChatComposerSnapshotFromEditorState(editor.getEditorState());
2004
- selectionRef.current = snapshot.selection;
2005
- if (!isComposingRef.current) syncInputSurfaceSnapshot(snapshot.nodes, snapshot.selection, { type: "selection" });
2006
- return false;
2007
- }, COMMAND_PRIORITY_EDITOR), editor.registerCommand(BLUR_COMMAND, () => {
2008
- onBlur();
2009
- return false;
2010
- }, COMMAND_PRIORITY_EDITOR), editor.registerCommand(KEY_DOWN_COMMAND, (event) => onKeyDown(event), COMMAND_PRIORITY_HIGH));
2011
- }, [
2012
- editor,
2013
- editorSignatureRef,
2014
- isApplyingExternalUpdateRef,
2015
- isComposingRef,
2016
- lastPublishedSignatureRef,
2017
- onBlur,
2018
- consumeInputSurfaceReason,
2019
- onKeyDown,
2020
- onNodesChange,
2021
- selectionRef,
2022
- syncInputSurfaceSnapshot
2023
- ]);
2165
+ return owner.registerEditorListeners(editor);
2166
+ }, [editor, owner]);
2024
2167
  return null;
2025
2168
  }
2026
2169
  //#endregion
2027
2170
  //#region src/components/chat/ui/chat-input-bar/lexical/chat-input-bar-tokenized-composer.tsx
2028
- function getChatComposerDocumentLength(nodes) {
2029
- return nodes.reduce((cursor, node) => cursor + (node.type === "text" ? node.text.length : 1), 0);
2030
- }
2031
2171
  const ChatInputBarTokenizedComposer = forwardRef(function ChatInputBarTokenizedComposer({ actions, disabled, nodes, onFilesAdd, onInputSurfaceItemSelect, onInputSurfaceKeyDown, onInputSurfaceOpenChange, onInputSurfaceSnapshotChange, onNodesChange, placeholder }, ref) {
2032
- const editorRef = useRef(null);
2033
- const selectionRef = useRef(null);
2034
- const pendingSelectionRef = useRef(null);
2035
- const shouldFocusAfterSyncRef = useRef(false);
2036
- const isComposingRef = useRef(false);
2037
- const isApplyingExternalUpdateRef = useRef(false);
2038
- const pendingInputSurfaceReasonRef = useRef(null);
2039
- const editorSignatureRef = useRef("");
2040
- const lastPublishedSignatureRef = useRef("");
2041
- const syncInputSurfaceSnapshot = useCallback((nodes, selection, reason) => {
2042
- onInputSurfaceSnapshotChange?.(nodes, selection, reason);
2043
- }, [onInputSurfaceSnapshotChange]);
2044
- const readCurrentNodes = useCallback(() => {
2045
- return nodes;
2046
- }, [nodes]);
2047
- const readCurrentSelection = useCallback(() => {
2048
- if (selectionRef.current) return selectionRef.current;
2049
- if (!editorRef.current) return null;
2050
- const snapshot = readChatComposerSnapshotFromEditorState(editorRef.current.getEditorState());
2051
- selectionRef.current = snapshot.selection;
2052
- return snapshot.selection;
2053
- }, []);
2054
- const publishSnapshot = useCallback((snapshot, options) => {
2055
- selectionRef.current = snapshot.selection;
2056
- pendingSelectionRef.current = snapshot.selection;
2057
- if (options?.focusAfterSync) shouldFocusAfterSyncRef.current = true;
2058
- const signature = getChatComposerNodesSignature(snapshot.nodes);
2059
- syncInputSurfaceSnapshot(snapshot.nodes, snapshot.selection, options?.inputSurfaceReason ?? { type: "programmatic" });
2060
- if (options?.forcePublish || signature !== lastPublishedSignatureRef.current) {
2061
- lastPublishedSignatureRef.current = signature;
2062
- onNodesChange(snapshot.nodes);
2063
- }
2064
- }, [onNodesChange, syncInputSurfaceSnapshot]);
2065
- const focusComposer = useCallback(() => {
2066
- const editor = editorRef.current;
2067
- if (!editor) return;
2068
- editor.getRootElement()?.focus({ preventScroll: true });
2069
- const targetSelection = selectionRef.current;
2070
- if (targetSelection) syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);
2071
- editor.focus();
2072
- }, []);
2073
- const focusComposerAtEnd = useCallback((nodes) => {
2074
- const editor = editorRef.current;
2075
- if (!editor) return;
2076
- const end = getChatComposerDocumentLength(nodes ?? readChatComposerSnapshotFromEditorState(editor.getEditorState()).nodes);
2077
- const targetSelection = {
2078
- start: end,
2079
- end
2080
- };
2081
- selectionRef.current = targetSelection;
2082
- pendingSelectionRef.current = targetSelection;
2083
- editor.getRootElement()?.focus({ preventScroll: true });
2084
- if (nodes) {
2085
- isApplyingExternalUpdateRef.current = true;
2086
- const signature = getChatComposerNodesSignature(nodes);
2087
- syncLexicalEditorFromChatComposerState(editor, nodes, targetSelection);
2088
- editorSignatureRef.current = signature;
2089
- lastPublishedSignatureRef.current = signature;
2090
- requestAnimationFrame(() => {
2091
- isApplyingExternalUpdateRef.current = false;
2092
- });
2093
- } else syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);
2094
- editor.focus(() => {
2095
- syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);
2096
- });
2097
- }, []);
2098
- const readComposerSnapshot = useCallback(() => ({
2099
- nodes: readCurrentNodes(),
2100
- selection: readCurrentSelection()
2101
- }), [readCurrentNodes, readCurrentSelection]);
2102
- const consumeInputSurfaceReason = useCallback(() => {
2103
- const reason = pendingInputSurfaceReasonRef.current;
2104
- pendingInputSurfaceReasonRef.current = null;
2105
- return reason;
2106
- }, []);
2107
- useImperativeHandle(ref, () => createLexicalComposerHandle({
2108
- focusComposer,
2109
- focusComposerAtEnd,
2172
+ const [owner] = useState(() => new ChatComposerLexicalOwner());
2173
+ const ownerCallbacks = useMemo(() => ({
2110
2174
  onInputSurfaceItemSelect,
2111
- optionsReader: readComposerSnapshot,
2112
- publishSnapshot
2175
+ onInputSurfaceKeyDown,
2176
+ onInputSurfaceOpenChange,
2177
+ onInputSurfaceSnapshotChange,
2178
+ onNodesChange
2113
2179
  }), [
2114
- focusComposer,
2115
- focusComposerAtEnd,
2116
2180
  onInputSurfaceItemSelect,
2117
- publishSnapshot,
2118
- readComposerSnapshot
2181
+ onInputSurfaceKeyDown,
2182
+ onInputSurfaceOpenChange,
2183
+ onInputSurfaceSnapshotChange,
2184
+ onNodesChange
2119
2185
  ]);
2186
+ owner.configureRuntime({
2187
+ actions,
2188
+ callbacks: ownerCallbacks,
2189
+ fallbackNodes: nodes
2190
+ });
2191
+ useImperativeHandle(ref, () => owner.createHandle(), [owner]);
2120
2192
  return /* @__PURE__ */ jsxs(LexicalComposer, {
2121
2193
  initialConfig: useMemo(() => ({
2122
2194
  editable: !disabled,
@@ -2130,92 +2202,46 @@ const ChatInputBarTokenizedComposer = forwardRef(function ChatInputBarTokenizedC
2130
2202
  },
2131
2203
  theme: {}
2132
2204
  }), [disabled, nodes]),
2133
- children: [
2134
- /* @__PURE__ */ jsx("div", {
2135
- className: "px-3 py-2 sm:px-4 sm:py-2.5",
2136
- children: /* @__PURE__ */ jsx("div", {
2137
- className: "min-h-11 sm:min-h-[60px]",
2138
- children: /* @__PURE__ */ jsx(PlainTextPlugin, {
2139
- contentEditable: /* @__PURE__ */ jsx(ContentEditable, {
2140
- className: "min-h-7 max-h-[188px] w-full overflow-y-auto whitespace-pre-wrap break-words bg-transparent py-0.5 text-sm leading-6 text-gray-800 outline-none",
2141
- onBeforeInput: (event) => {
2142
- handleLexicalComposerBeforeInput({
2143
- disabled,
2144
- event,
2145
- isComposing: isComposingRef.current,
2146
- publishSnapshot,
2147
- snapshotReader: readComposerSnapshot
2148
- });
2149
- },
2150
- onCompositionEnd: (event) => {
2151
- isComposingRef.current = false;
2152
- const nativeEvent = event.nativeEvent;
2153
- handleLexicalComposerCompositionEnd({
2154
- data: typeof nativeEvent.data === "string" ? nativeEvent.data : "",
2155
- fallbackSnapshot: () => {
2156
- const editor = editorRef.current;
2157
- return editor ? readChatComposerSnapshotFromEditorState(editor.getEditorState()) : readComposerSnapshot();
2158
- },
2159
- publishSnapshot,
2160
- snapshotReader: readComposerSnapshot
2161
- });
2162
- },
2163
- onCompositionStart: () => {
2164
- isComposingRef.current = true;
2165
- },
2166
- onPaste: (event) => {
2167
- const files = Array.from(event.clipboardData.files ?? []);
2168
- if (files.length > 0 && onFilesAdd) {
2169
- event.preventDefault();
2170
- onFilesAdd(files);
2171
- }
2205
+ children: [/* @__PURE__ */ jsx("div", {
2206
+ className: "px-3 py-2 sm:px-4 sm:py-2.5",
2207
+ children: /* @__PURE__ */ jsx("div", {
2208
+ className: "min-h-11 sm:min-h-[60px]",
2209
+ children: /* @__PURE__ */ jsx(PlainTextPlugin, {
2210
+ contentEditable: /* @__PURE__ */ jsx(ContentEditable, {
2211
+ className: "min-h-7 max-h-[188px] w-full overflow-y-auto whitespace-pre-wrap break-words bg-transparent py-0.5 text-sm leading-6 text-foreground outline-none",
2212
+ onBeforeInput: (event) => {
2213
+ owner.handleBeforeInput({
2214
+ disabled,
2215
+ event
2216
+ });
2217
+ },
2218
+ onCompositionEnd: (event) => {
2219
+ const nativeEvent = event.nativeEvent;
2220
+ owner.handleCompositionEnd({ data: typeof nativeEvent.data === "string" ? nativeEvent.data : "" });
2221
+ },
2222
+ onCompositionStart: () => {
2223
+ owner.handleCompositionStart();
2224
+ },
2225
+ onPaste: (event) => {
2226
+ const files = Array.from(event.clipboardData.files ?? []);
2227
+ if (files.length > 0 && onFilesAdd) {
2228
+ event.preventDefault();
2229
+ onFilesAdd(files);
2172
2230
  }
2173
- }),
2174
- placeholder: /* @__PURE__ */ jsx("div", {
2175
- className: "pointer-events-none absolute left-3 top-2 select-none text-sm leading-6 text-gray-400 sm:left-4 sm:top-2.5",
2176
- children: placeholder
2177
- }),
2178
- ErrorBoundary: LexicalErrorBoundary
2179
- })
2231
+ }
2232
+ }),
2233
+ placeholder: /* @__PURE__ */ jsx("div", {
2234
+ className: "pointer-events-none absolute left-3 top-2 select-none text-sm leading-6 text-muted-foreground/60 sm:left-4 sm:top-2.5",
2235
+ children: placeholder
2236
+ }),
2237
+ ErrorBoundary: LexicalErrorBoundary
2180
2238
  })
2181
- }),
2182
- /* @__PURE__ */ jsx(EditorRefPlugin, { editorRef }),
2183
- /* @__PURE__ */ jsx(ChatComposerBindingsPlugin, {
2184
- disabled,
2185
- editorRef,
2186
- editorSignatureRef,
2187
- isApplyingExternalUpdateRef,
2188
- isComposingRef,
2189
- lastPublishedSignatureRef,
2190
- nodes,
2191
- onBlur: () => {
2192
- onInputSurfaceOpenChange?.(false);
2193
- },
2194
- consumeInputSurfaceReason,
2195
- onKeyDown: (event) => {
2196
- if (event.key.length === 1 && !event.isComposing && !event.altKey && !event.ctrlKey && !event.metaKey) pendingInputSurfaceReasonRef.current = {
2197
- type: "insert-text",
2198
- text: event.key
2199
- };
2200
- const editor = editorRef.current;
2201
- if (!editor) return false;
2202
- const snapshot = readChatComposerSnapshotFromEditorState(editor.getEditorState());
2203
- selectionRef.current = snapshot.selection;
2204
- if (onInputSurfaceKeyDown?.(event)) return true;
2205
- return handleLexicalComposerKeyboardCommand({
2206
- actions,
2207
- nativeEvent: event,
2208
- publishSnapshot,
2209
- snapshot
2210
- });
2211
- },
2212
- onNodesChange,
2213
- pendingSelectionRef,
2214
- selectionRef,
2215
- shouldFocusAfterSyncRef,
2216
- syncInputSurfaceSnapshot
2217
2239
  })
2218
- ]
2240
+ }), /* @__PURE__ */ jsx(ChatComposerBindingsPlugin, {
2241
+ disabled,
2242
+ nodes,
2243
+ owner
2244
+ })]
2219
2245
  });
2220
2246
  });
2221
2247
  ChatInputBarTokenizedComposer.displayName = "LexicalChatInputBarTokenizedComposer";
@@ -2226,14 +2252,14 @@ function InputBarHint({ hint }) {
2226
2252
  if (hint.loading) return /* @__PURE__ */ jsx("div", {
2227
2253
  className: "px-4 pb-2",
2228
2254
  children: /* @__PURE__ */ jsxs("div", {
2229
- className: "inline-flex items-center gap-2 rounded-lg border border-gray-200 bg-gray-50 px-3 py-2",
2230
- children: [/* @__PURE__ */ jsx("span", { className: "h-3 w-28 animate-pulse rounded bg-gray-200" }), /* @__PURE__ */ jsx("span", { className: "h-3 w-16 animate-pulse rounded bg-gray-200" })]
2255
+ className: "inline-flex items-center gap-2 rounded-lg border border-border bg-muted px-3 py-2",
2256
+ children: [/* @__PURE__ */ jsx("span", { className: "h-3 w-28 animate-pulse rounded bg-muted-foreground/20" }), /* @__PURE__ */ jsx("span", { className: "h-3 w-16 animate-pulse rounded bg-muted-foreground/20" })]
2231
2257
  })
2232
2258
  });
2233
2259
  return /* @__PURE__ */ jsx("div", {
2234
2260
  className: "px-4 pb-2",
2235
2261
  children: /* @__PURE__ */ jsxs("div", {
2236
- className: `inline-flex items-center gap-2 rounded-lg px-3 py-1.5 text-xs ${hint.tone === "warning" ? "border-amber-200 bg-amber-50 text-amber-800" : "border-gray-200 bg-gray-50 text-gray-700"}`,
2262
+ className: `inline-flex items-center gap-2 rounded-lg px-3 py-1.5 text-xs ${hint.tone === "warning" ? "border-amber-200 bg-amber-50 text-amber-800" : "border-border bg-muted text-muted-foreground"}`,
2237
2263
  children: [hint.text ? /* @__PURE__ */ jsx("span", { children: hint.text }) : null, hint.actionLabel && hint.onAction ? /* @__PURE__ */ jsx("button", {
2238
2264
  type: "button",
2239
2265
  onClick: hint.onAction,
@@ -2277,11 +2303,11 @@ const ChatInputBar = forwardRef(function ChatInputBar({ composer, hint, inputSur
2277
2303
  focusComposerAtEnd: (nodes) => composerRef.current?.focusComposerAtEnd(nodes)
2278
2304
  }), []);
2279
2305
  return /* @__PURE__ */ jsx("div", {
2280
- className: surface === "embedded" ? "bg-transparent px-0 py-0" : "border-t border-gray-200/80 bg-white px-3 py-3 sm:px-4 sm:py-4",
2306
+ className: surface === "embedded" ? "bg-transparent px-0 py-0" : "bg-background px-3 pb-3 pt-2 sm:px-4 sm:pb-4 sm:pt-2",
2281
2307
  children: /* @__PURE__ */ jsx("div", {
2282
2308
  className: "nextclaw-chat-input-bar-shell mx-auto w-full max-w-[min(1120px,100%)] [container:nextclaw-chat-input-bar/inline-size]",
2283
2309
  children: /* @__PURE__ */ jsxs("div", {
2284
- className: "overflow-hidden rounded-2xl border border-gray-200 bg-white shadow-card",
2310
+ className: "overflow-hidden rounded-2xl border border-border bg-card shadow-card",
2285
2311
  children: [
2286
2312
  /* @__PURE__ */ jsx("div", {
2287
2313
  className: "relative",
@@ -2318,19 +2344,19 @@ ChatInputBar.displayName = "ChatInputBar";
2318
2344
  function ChatMessageAvatar({ role }) {
2319
2345
  if (role === "user") return /* @__PURE__ */ jsx("div", {
2320
2346
  "data-testid": "chat-message-avatar-user",
2321
- className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary text-white shadow-sm",
2347
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm",
2322
2348
  children: /* @__PURE__ */ jsx(User, { className: "h-4 w-4" })
2323
2349
  });
2324
2350
  if (role === "tool") return /* @__PURE__ */ jsx("div", {
2325
2351
  "data-testid": "chat-message-avatar-tool",
2326
- className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-amber-100 text-amber-700 shadow-sm",
2352
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-accent text-accent-foreground shadow-sm ring-1 ring-border",
2327
2353
  children: /* @__PURE__ */ jsx(Wrench, { className: "h-4 w-4" })
2328
2354
  });
2329
2355
  return /* @__PURE__ */ jsx("div", {
2330
2356
  "data-testid": "chat-message-avatar-assistant",
2331
- className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-gradient-to-b from-gray-700 to-gray-950 text-white shadow-md ring-1 ring-inset ring-white/20",
2357
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-muted text-foreground shadow-sm ring-1 ring-border",
2332
2358
  children: /* @__PURE__ */ jsx(Bot, {
2333
- className: "h-[18px] w-[18px] text-white/95",
2359
+ className: "h-[18px] w-[18px] text-current",
2334
2360
  strokeWidth: 2.5
2335
2361
  })
2336
2362
  });
@@ -2343,14 +2369,14 @@ function resolveInlineTokenTone(kind) {
2343
2369
  return "default";
2344
2370
  }
2345
2371
  function resolveInlineTokenBadgeClassName(tone, isUser) {
2346
- if (tone === "skill") return isUser ? "border-emerald-200/35 bg-emerald-400/18 text-emerald-50/95" : "border-emerald-200/70 bg-emerald-50 text-emerald-700";
2347
- if (tone === "panel_app") return isUser ? "border-sky-200/35 bg-sky-400/18 text-sky-50/95" : "border-sky-200/70 bg-sky-50 text-sky-700";
2348
- return isUser ? "border-white/30 bg-white/18 text-white" : "border-slate-200/80 bg-slate-100 text-slate-700";
2372
+ if (tone === "skill") return isUser ? "border-primary-foreground/30 bg-primary-foreground/18 text-primary-foreground" : "border-border bg-accent text-accent-foreground";
2373
+ if (tone === "panel_app") return isUser ? "border-primary-foreground/30 bg-primary-foreground/18 text-primary-foreground" : "border-border bg-accent text-accent-foreground";
2374
+ return isUser ? "border-primary-foreground/30 bg-primary-foreground/18 text-primary-foreground" : "border-border bg-muted text-muted-foreground";
2349
2375
  }
2350
2376
  function resolveInlineTokenIconClassName(tone, isUser) {
2351
- if (tone === "skill") return isUser ? "text-emerald-100/90" : "text-emerald-600";
2352
- if (tone === "panel_app") return isUser ? "text-sky-100/90" : "text-sky-600";
2353
- return isUser ? "text-white/70" : "text-slate-500";
2377
+ if (tone === "skill") return isUser ? "text-primary-foreground/70" : "text-muted-foreground";
2378
+ if (tone === "panel_app") return isUser ? "text-primary-foreground/70" : "text-muted-foreground";
2379
+ return isUser ? "text-primary-foreground/70" : "text-muted-foreground";
2354
2380
  }
2355
2381
  function renderInlineTokenIcon(tone) {
2356
2382
  return tone === "panel_app" ? /* @__PURE__ */ jsx(AppWindow, {
@@ -2929,16 +2955,16 @@ function ChatMessageMarkdown({ text, role, texts, inline = false, inlineTokens,
2929
2955
  //#endregion
2930
2956
  //#region src/components/chat/ui/chat-message-list/chat-message-file/meta.ts
2931
2957
  const FILE_CATEGORY_TILE_CLASSES = {
2932
- archive: "border-amber-200/80 bg-amber-50 text-amber-700",
2933
- audio: "border-fuchsia-200/80 bg-fuchsia-50 text-fuchsia-700",
2934
- code: "border-cyan-200/80 bg-cyan-50 text-cyan-700",
2935
- data: "border-slate-200/80 bg-slate-50 text-slate-700",
2936
- document: "border-blue-200/80 bg-blue-50 text-blue-700",
2937
- generic: "border-slate-200/80 bg-slate-50 text-slate-700",
2938
- image: "border-emerald-200/80 bg-emerald-50 text-emerald-700",
2939
- pdf: "border-rose-200/80 bg-rose-50 text-rose-700",
2940
- sheet: "border-lime-200/80 bg-lime-50 text-lime-700",
2941
- video: "border-violet-200/80 bg-violet-50 text-violet-700"
2958
+ archive: "border-border bg-muted text-muted-foreground",
2959
+ audio: "border-border bg-muted text-muted-foreground",
2960
+ code: "border-border bg-muted text-muted-foreground",
2961
+ data: "border-border bg-muted text-muted-foreground",
2962
+ document: "border-border bg-muted text-muted-foreground",
2963
+ generic: "border-border bg-muted text-muted-foreground",
2964
+ image: "border-border bg-muted text-muted-foreground",
2965
+ pdf: "border-border bg-muted text-muted-foreground",
2966
+ sheet: "border-border bg-muted text-muted-foreground",
2967
+ video: "border-border bg-muted text-muted-foreground"
2942
2968
  };
2943
2969
  const CODE_EXTENSIONS = new Set([
2944
2970
  "c",
@@ -3148,13 +3174,13 @@ function readFileCategoryLabel(category, texts) {
3148
3174
  }
3149
3175
  function renderMetaLine(categoryLabel, sizeLabel, isUser) {
3150
3176
  return /* @__PURE__ */ jsx("div", {
3151
- className: cn("mt-1 text-xs leading-5", isUser ? "text-white/70" : "text-slate-500"),
3177
+ className: cn("mt-1 text-xs leading-5", isUser ? "text-primary-foreground/70" : "text-muted-foreground"),
3152
3178
  children: sizeLabel ? `${categoryLabel} · ${sizeLabel}` : categoryLabel
3153
3179
  });
3154
3180
  }
3155
3181
  function renderActionPill(label, isUser, isInteractive) {
3156
3182
  return /* @__PURE__ */ jsx("span", {
3157
- className: cn("inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium", isInteractive ? isUser ? "border-white/14 bg-white/12 text-white" : "border-slate-200/80 bg-white text-slate-700" : isUser ? "border-white/10 bg-white/6 text-white/62" : "border-slate-200/70 bg-slate-100/80 text-slate-500"),
3183
+ className: cn("inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium", isInteractive ? isUser ? "border-primary-foreground/14 bg-primary-foreground/12 text-primary-foreground" : "border-border bg-card text-foreground" : isUser ? "border-primary-foreground/10 bg-primary-foreground/6 text-primary-foreground/62" : "border-border bg-muted text-muted-foreground"),
3158
3184
  children: label
3159
3185
  });
3160
3186
  }
@@ -3163,16 +3189,16 @@ function renderActionLink(label, href, isUser) {
3163
3189
  href,
3164
3190
  target: "_blank",
3165
3191
  rel: "noreferrer",
3166
- className: cn("inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium transition duration-200", isUser ? "border-white/14 bg-white/12 text-white hover:border-white/20 hover:bg-white/16" : "border-slate-200/80 bg-white text-slate-700 hover:border-slate-300 hover:bg-slate-50"),
3192
+ className: cn("inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium transition duration-200", isUser ? "border-primary-foreground/14 bg-primary-foreground/12 text-primary-foreground hover:border-primary-foreground/20 hover:bg-primary-foreground/16" : "border-border bg-card text-foreground hover:border-border-hover hover:bg-accent"),
3167
3193
  children: label
3168
3194
  });
3169
3195
  }
3170
3196
  function FileCategoryGlyph({ category, isUser }) {
3171
3197
  const Icon = FILE_CATEGORY_ICONS[category];
3172
3198
  return /* @__PURE__ */ jsx("div", {
3173
- className: cn("flex h-14 w-14 shrink-0 items-center justify-center rounded-[1rem] border", isUser ? "border-white/12 bg-white/10 text-white" : FILE_CATEGORY_TILE_CLASSES[category]),
3199
+ className: cn("flex h-14 w-14 shrink-0 items-center justify-center rounded-[1rem] border", isUser ? "border-primary-foreground/12 bg-primary-foreground/10 text-primary-foreground" : FILE_CATEGORY_TILE_CLASSES[category]),
3174
3200
  children: /* @__PURE__ */ jsx(Icon, {
3175
- className: cn("h-7 w-7", isUser ? "text-white/92" : "text-current"),
3201
+ className: cn("h-7 w-7", isUser ? "text-primary-foreground/92" : "text-current"),
3176
3202
  strokeWidth: 2.2
3177
3203
  })
3178
3204
  });
@@ -3186,7 +3212,7 @@ function renderImagePreview(params) {
3186
3212
  rel: "noreferrer",
3187
3213
  className: "group block",
3188
3214
  children: /* @__PURE__ */ jsxs("div", {
3189
- className: cn("relative overflow-hidden rounded-[1rem]", isUser ? "ring-1 ring-white/10" : "bg-slate-100/80 ring-1 ring-slate-200/80"),
3215
+ className: cn("relative overflow-hidden rounded-[1rem]", isUser ? "ring-1 ring-primary-foreground/10" : "bg-muted ring-1 ring-border"),
3190
3216
  children: [/* @__PURE__ */ jsx("img", {
3191
3217
  src: file.dataUrl,
3192
3218
  alt: file.label,
@@ -3194,10 +3220,10 @@ function renderImagePreview(params) {
3194
3220
  }), /* @__PURE__ */ jsxs("div", {
3195
3221
  className: "pointer-events-none absolute right-3 top-3 flex items-center gap-2",
3196
3222
  children: [/* @__PURE__ */ jsx("span", {
3197
- className: cn("inline-flex items-center rounded-full px-2 py-1 text-[10px] font-semibold tracking-[0.18em] text-white backdrop-blur-sm", isUser ? "bg-slate-950/36" : "bg-slate-950/58"),
3223
+ className: cn("inline-flex items-center rounded-full px-2 py-1 text-[10px] font-semibold tracking-[0.18em] text-white backdrop-blur-sm", isUser ? "bg-black/36" : "bg-black/58"),
3198
3224
  children: categoryLabel
3199
3225
  }), sizeLabel ? /* @__PURE__ */ jsx("span", {
3200
- className: cn("inline-flex items-center rounded-full px-2 py-1 text-[10px] font-medium text-white/92 backdrop-blur-sm", isUser ? "bg-slate-950/28" : "bg-slate-950/46"),
3226
+ className: cn("inline-flex items-center rounded-full px-2 py-1 text-[10px] font-medium text-white/92 backdrop-blur-sm", isUser ? "bg-black/28" : "bg-black/46"),
3201
3227
  children: sizeLabel
3202
3228
  }) : null]
3203
3229
  })]
@@ -3251,7 +3277,7 @@ function renderInlineMediaCard(params) {
3251
3277
  ...mediaMimeType ? { type: mediaMimeType } : {}
3252
3278
  })
3253
3279
  }) : /* @__PURE__ */ jsx("div", {
3254
- className: cn("overflow-hidden rounded-[1rem] border", isUser ? "border-white/10 bg-slate-950/26" : "border-slate-200/80 bg-slate-100/80"),
3280
+ className: cn("overflow-hidden rounded-[1rem] border", isUser ? "border-primary-foreground/10 bg-black/26" : "border-border bg-muted"),
3255
3281
  children: /* @__PURE__ */ jsx("video", {
3256
3282
  controls: true,
3257
3283
  preload: "metadata",
@@ -3275,7 +3301,7 @@ function ChatMessageFile({ file, isUser = false, texts }) {
3275
3301
  const isInteractive = Boolean(file.dataUrl);
3276
3302
  const actionLabel = isInteractive ? texts?.attachmentOpenLabel ?? "Open" : texts?.attachmentAttachedLabel ?? "Attached";
3277
3303
  const categoryLabel = readFileCategoryLabel(category, texts);
3278
- const shellClasses = cn("block overflow-hidden rounded-[1.25rem] border transition duration-200", isUser ? "border-white/12 bg-white/10 text-white" : "border-slate-200/80 bg-white/95 text-slate-900", isInteractive && (isUser ? "hover:border-white/18 hover:bg-white/13" : "hover:border-slate-300 hover:bg-white"));
3304
+ const shellClasses = cn("block overflow-hidden rounded-[1.25rem] border transition duration-200", isUser ? "border-primary-foreground/12 bg-primary-foreground/10 text-primary-foreground" : "border-border bg-card text-card-foreground", isInteractive && (isUser ? "hover:border-primary-foreground/18 hover:bg-primary-foreground/13" : "hover:border-border-hover hover:bg-accent"));
3279
3305
  if (renderAsImage) return renderImagePreview({
3280
3306
  file,
3281
3307
  categoryLabel,
@@ -3431,14 +3457,14 @@ function ChatReasoningBlock({ label, text, isUser, isInProgress }) {
3431
3457
  className: "mt-2",
3432
3458
  open: isOpen,
3433
3459
  children: [/* @__PURE__ */ jsx("summary", {
3434
- className: cn("cursor-pointer text-xs", isUser ? "text-primary-100" : "text-gray-500"),
3460
+ className: cn("cursor-pointer text-xs", isUser ? "text-primary-100" : "text-muted-foreground"),
3435
3461
  onClick: onSummaryClick,
3436
3462
  children: displayLabel
3437
3463
  }), /* @__PURE__ */ jsx("div", {
3438
3464
  ref: scrollRef,
3439
3465
  onScroll,
3440
3466
  "data-reasoning-scroll": "true",
3441
- className: cn("mt-2 w-fit max-w-[500px] max-h-56 overflow-y-auto rounded-lg custom-scrollbar-amber", isUser ? "bg-primary-700/60" : "bg-gray-100"),
3467
+ className: cn("mt-2 w-fit max-w-[500px] max-h-56 overflow-y-auto rounded-lg custom-scrollbar", isUser ? "bg-primary/70" : "bg-muted"),
3442
3468
  children: /* @__PURE__ */ jsx("pre", {
3443
3469
  className: "min-w-0 whitespace-pre-wrap break-all p-2 text-[11px]",
3444
3470
  children: text
@@ -3450,13 +3476,13 @@ function ChatReasoningBlock({ label, text, isUser, isInProgress }) {
3450
3476
  //#region src/components/chat/ui/chat-message-list/tool-card/tool-card-root.tsx
3451
3477
  function ToolCardRoot({ children, className }) {
3452
3478
  return /* @__PURE__ */ jsx("div", {
3453
- className: cn("my-2 rounded-lg border border-amber-200/50 bg-amber-100/30 shadow-sm overflow-hidden text-[12px]", "w-[280px] sm:w-[360px] md:w-[480px] min-w-full max-w-full transition-all flex flex-col", className),
3479
+ className: cn("my-2 rounded-lg border border-border bg-card shadow-sm overflow-hidden text-[12px] text-card-foreground", "w-[280px] sm:w-[360px] md:w-[480px] min-w-full max-w-full transition-all flex flex-col", className),
3454
3480
  children
3455
3481
  });
3456
3482
  }
3457
3483
  function ToolCardContent({ children, className }) {
3458
3484
  return /* @__PURE__ */ jsx("div", {
3459
- className: cn("border-t border-amber-200/15 bg-amber-50/50 px-3 pt-1 pb-2 w-full overflow-hidden", className),
3485
+ className: cn("border-t border-border bg-muted/35 px-3 pt-1 pb-2 w-full overflow-hidden", className),
3460
3486
  children
3461
3487
  });
3462
3488
  }
@@ -3464,22 +3490,22 @@ function ToolCardContent({ children, className }) {
3464
3490
  //#region src/components/chat/ui/chat-message-list/tool-card/tool-card-status.tsx
3465
3491
  const STATUS_STYLES = {
3466
3492
  running: {
3467
- text: "text-amber-500/80",
3493
+ text: "text-primary/70",
3468
3494
  icon: Loader2,
3469
3495
  spin: true
3470
3496
  },
3471
3497
  success: {
3472
- text: "text-amber-500/80",
3498
+ text: "text-primary/70",
3473
3499
  icon: Check,
3474
3500
  spin: false
3475
3501
  },
3476
3502
  error: {
3477
- text: "text-amber-500/80",
3503
+ text: "text-destructive",
3478
3504
  icon: AlertTriangle,
3479
3505
  spin: false
3480
3506
  },
3481
3507
  cancelled: {
3482
- text: "text-amber-500/80",
3508
+ text: "text-muted-foreground",
3483
3509
  icon: Minus,
3484
3510
  spin: false
3485
3511
  }
@@ -3501,12 +3527,12 @@ function resolveToolCardActionView(action) {
3501
3527
  if (action.kind === "show-content") return {
3502
3528
  icon: Eye,
3503
3529
  label: action.label,
3504
- toneClassName: "border-sky-200/80 bg-white/85 text-sky-800 hover:bg-sky-50 focus-visible:ring-sky-300"
3530
+ toneClassName: "border-border bg-card text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-primary/35"
3505
3531
  };
3506
3532
  return {
3507
3533
  icon: ArrowUpRight,
3508
3534
  label: action.label ?? (action.sessionKind === "child" ? "Open child session" : "Open session"),
3509
- toneClassName: "border-amber-200/80 bg-white/80 text-amber-800 hover:bg-amber-50 focus-visible:ring-amber-300"
3535
+ toneClassName: "border-border bg-card text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-primary/35"
3510
3536
  };
3511
3537
  }
3512
3538
  function ToolCardActionButton({ action, onAction }) {
@@ -3542,12 +3568,12 @@ function ToolCardActionButton({ action, onAction }) {
3542
3568
  function ToolCardHeader({ card, icon: Icon, expanded, canExpand, hideSummary = false, actionSlot, onToggle }) {
3543
3569
  const summaryPart = hideSummary ? "" : card.summary?.replace(/^(command|path|args|query|input):\s*/i, "") ?? "";
3544
3570
  return /* @__PURE__ */ jsxs("div", {
3545
- className: cn("flex items-center gap-3 px-3 py-2.5 transition-colors bg-transparent", canExpand ? "cursor-pointer hover:bg-amber-100/30" : ""),
3571
+ className: cn("flex items-center gap-3 px-3 py-2.5 transition-colors bg-transparent", canExpand ? "cursor-pointer hover:bg-accent/70" : ""),
3546
3572
  onClick: onToggle,
3547
3573
  children: [/* @__PURE__ */ jsxs("div", {
3548
- className: "flex min-w-0 flex-1 items-center gap-2 overflow-hidden font-mono text-amber-950/80",
3574
+ className: "flex min-w-0 flex-1 items-center gap-2 overflow-hidden font-mono text-foreground",
3549
3575
  children: [/* @__PURE__ */ jsx(Icon, {
3550
- className: "h-4 w-4 text-amber-600/80 shrink-0",
3576
+ className: "h-4 w-4 text-primary/70 shrink-0",
3551
3577
  strokeWidth: 3
3552
3578
  }), /* @__PURE__ */ jsxs("div", {
3553
3579
  className: "flex min-w-0 flex-1 items-center gap-1.5 overflow-hidden",
@@ -3555,10 +3581,10 @@ function ToolCardHeader({ card, icon: Icon, expanded, canExpand, hideSummary = f
3555
3581
  className: "font-bold shrink-0 tracking-tight",
3556
3582
  children: card.toolName
3557
3583
  }), summaryPart && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
3558
- className: "text-amber-300 font-bold select-none shrink-0",
3584
+ className: "text-muted-foreground/45 font-bold select-none shrink-0",
3559
3585
  children: "›"
3560
3586
  }), /* @__PURE__ */ jsx("span", {
3561
- className: "block min-w-0 flex-1 truncate font-normal",
3587
+ className: "block min-w-0 flex-1 truncate font-normal text-muted-foreground",
3562
3588
  title: summaryPart,
3563
3589
  children: summaryPart
3564
3590
  })] })]
@@ -3569,10 +3595,10 @@ function ToolCardHeader({ card, icon: Icon, expanded, canExpand, hideSummary = f
3569
3595
  actionSlot,
3570
3596
  /* @__PURE__ */ jsx(ToolStatusLabel, { card }),
3571
3597
  canExpand && (expanded ? /* @__PURE__ */ jsx(ChevronDown, {
3572
- className: "h-4 w-4 text-amber-400/80",
3598
+ className: "h-4 w-4 text-muted-foreground",
3573
3599
  strokeWidth: 3
3574
3600
  }) : /* @__PURE__ */ jsx(ChevronRight, {
3575
- className: "h-4 w-4 text-amber-400/80",
3601
+ className: "h-4 w-4 text-muted-foreground",
3576
3602
  strokeWidth: 3
3577
3603
  }))
3578
3604
  ]
@@ -3616,12 +3642,12 @@ function readCodeColumnWidth(block) {
3616
3642
  function getLineNumberTone(line) {
3617
3643
  if (line.kind === "remove") return "border-r border-rose-200 bg-rose-50 text-rose-700";
3618
3644
  if (line.kind === "add") return "border-r border-emerald-200 bg-emerald-50 text-emerald-700";
3619
- return "border-r border-stone-200 bg-stone-100 text-stone-500";
3645
+ return "border-r border-border bg-muted text-muted-foreground";
3620
3646
  }
3621
3647
  function getCodeRowTone(line) {
3622
3648
  if (line.kind === "remove") return "bg-rose-50 text-rose-950";
3623
3649
  if (line.kind === "add") return "bg-emerald-50 text-emerald-950";
3624
- return "bg-white text-amber-950/80";
3650
+ return "bg-card text-foreground";
3625
3651
  }
3626
3652
  function FileOperationLineNumberCell({ layout, line, lineNumberColumnWidth }) {
3627
3653
  return /* @__PURE__ */ jsx("span", {
@@ -3659,7 +3685,7 @@ function FileOperationWorkspaceSurface({ block }) {
3659
3685
  return /* @__PURE__ */ jsxs("div", {
3660
3686
  "data-file-code-surface": "true",
3661
3687
  "data-file-code-surface-layout": "workspace",
3662
- className: "flex h-full min-h-full min-w-full bg-white",
3688
+ className: "flex h-full min-h-full min-w-full bg-card",
3663
3689
  children: [showLineNumbers ? /* @__PURE__ */ jsxs("div", {
3664
3690
  "data-file-code-gutter": "true",
3665
3691
  style: {
@@ -3671,10 +3697,10 @@ function FileOperationWorkspaceSurface({ block }) {
3671
3697
  layout: "workspace",
3672
3698
  line,
3673
3699
  lineNumberColumnWidth
3674
- }, readLineKey("gutter", line, index))), /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 border-r border-stone-200 bg-stone-100" })]
3700
+ }, readLineKey("gutter", line, index))), /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 border-r border-border bg-muted" })]
3675
3701
  }) : null, /* @__PURE__ */ jsxs("div", {
3676
3702
  "data-file-code-canvas": "true",
3677
- className: "flex h-full min-h-full min-w-0 flex-1 flex-col bg-white",
3703
+ className: "flex h-full min-h-full min-w-0 flex-1 flex-col bg-card",
3678
3704
  children: [/* @__PURE__ */ jsx("div", {
3679
3705
  "data-file-code-stack": "true",
3680
3706
  className: "min-w-full",
@@ -3684,7 +3710,7 @@ function FileOperationWorkspaceSurface({ block }) {
3684
3710
  className: FILE_ROW_CLASS_NAME,
3685
3711
  children: /* @__PURE__ */ jsx(FileOperationCodeCell, { line })
3686
3712
  }, readLineKey("code", line, index)))
3687
- }), /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 bg-white" })]
3713
+ }), /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 bg-card" })]
3688
3714
  })]
3689
3715
  });
3690
3716
  }
@@ -3697,7 +3723,7 @@ function FileOperationCodeSurface({ block, layout = "compact" }) {
3697
3723
  return /* @__PURE__ */ jsx("div", {
3698
3724
  "data-file-code-surface": "true",
3699
3725
  "data-file-code-surface-layout": "compact",
3700
- className: "overflow-x-auto custom-scrollbar-amber bg-white",
3726
+ className: "overflow-x-auto custom-scrollbar bg-card",
3701
3727
  children: /* @__PURE__ */ jsx("div", {
3702
3728
  "data-file-code-stack": "true",
3703
3729
  className: "min-w-full",
@@ -3733,7 +3759,7 @@ function readFileOperationContentVersion(block) {
3733
3759
  function getCaptionTone(part) {
3734
3760
  if (/^\+\d+$/.test(part)) return "text-emerald-700";
3735
3761
  if (/^-\d+$/.test(part)) return "text-rose-700";
3736
- return "text-stone-500";
3762
+ return "text-muted-foreground";
3737
3763
  }
3738
3764
  function renderCaption(caption) {
3739
3765
  const parts = caption.split("·").map((part) => part.trim()).filter((part) => /^\+\d+$/.test(part) || /^-\d+$/.test(part));
@@ -3741,7 +3767,7 @@ function renderCaption(caption) {
3741
3767
  return /* @__PURE__ */ jsx("div", {
3742
3768
  className: "flex shrink-0 items-center gap-x-1 whitespace-nowrap text-[10px] font-medium uppercase tracking-[0.08em]",
3743
3769
  children: parts.map((part, index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 ? /* @__PURE__ */ jsx("span", {
3744
- className: "text-stone-300",
3770
+ className: "text-muted-foreground/45",
3745
3771
  children: "·"
3746
3772
  }) : null, /* @__PURE__ */ jsx("span", {
3747
3773
  className: cn(getCaptionTone(part)),
@@ -3777,7 +3803,7 @@ function StickyFileOperationScrollArea({ children, contentVersion, resetKey, cla
3777
3803
  ref: scrollRef,
3778
3804
  onScroll,
3779
3805
  "data-file-scroll-kind": scrollKind,
3780
- className: cn("overflow-y-auto bg-white custom-scrollbar-amber", className),
3806
+ className: cn("overflow-y-auto bg-card custom-scrollbar", className),
3781
3807
  children
3782
3808
  });
3783
3809
  }
@@ -3790,10 +3816,10 @@ function FileOperationBlock({ block, showPathRow, isFirst, onFileOpen }) {
3790
3816
  onFileOpen(buildFileOpenAction(block));
3791
3817
  };
3792
3818
  return /* @__PURE__ */ jsxs("section", {
3793
- className: cn("overflow-hidden bg-white", !isFirst && "border-t border-stone-200/80"),
3819
+ className: cn("overflow-hidden bg-card", !isFirst && "border-t border-border"),
3794
3820
  children: [
3795
3821
  showMetaRow ? /* @__PURE__ */ jsxs("div", {
3796
- className: cn("flex items-center justify-between gap-4 border-b border-stone-200/80 px-4 text-stone-700", showPathRow ? "py-2" : "py-1.5"),
3822
+ className: cn("flex items-center justify-between gap-4 border-b border-border px-4 text-muted-foreground", showPathRow ? "py-2" : "py-1.5"),
3797
3823
  children: [/* @__PURE__ */ jsx("div", {
3798
3824
  className: "min-w-0 flex-1",
3799
3825
  children: showPathRow ? /* @__PURE__ */ jsx(TooltipProvider, {
@@ -3803,7 +3829,7 @@ function FileOperationBlock({ block, showPathRow, isFirst, onFileOpen }) {
3803
3829
  children: /* @__PURE__ */ jsx("button", {
3804
3830
  type: "button",
3805
3831
  onClick: handlePathClick,
3806
- className: cn("w-full truncate whitespace-nowrap text-left font-mono text-[12px] font-medium text-stone-700", onFileOpen && "transition-colors hover:text-amber-900 hover:underline"),
3832
+ className: cn("w-full truncate whitespace-nowrap text-left font-mono text-[12px] font-medium text-foreground", onFileOpen && "transition-colors hover:text-primary hover:underline"),
3807
3833
  title: block.path,
3808
3834
  children: block.path
3809
3835
  })
@@ -3827,15 +3853,15 @@ function FileOperationBlock({ block, showPathRow, isFirst, onFileOpen }) {
3827
3853
  className: "max-h-72",
3828
3854
  scrollKind: "raw",
3829
3855
  children: /* @__PURE__ */ jsx("div", {
3830
- className: "overflow-x-auto custom-scrollbar-amber",
3856
+ className: "overflow-x-auto custom-scrollbar",
3831
3857
  children: /* @__PURE__ */ jsx("pre", {
3832
- className: "min-w-max whitespace-pre bg-white px-4 py-2 font-mono text-[11px] leading-5 text-amber-950/80",
3858
+ className: "min-w-max whitespace-pre bg-card px-4 py-2 font-mono text-[11px] leading-5 text-foreground",
3833
3859
  children: block.rawText
3834
3860
  })
3835
3861
  })
3836
3862
  }) : null,
3837
3863
  block.truncated && !previewBlock ? /* @__PURE__ */ jsx("div", {
3838
- className: "border-t border-stone-200/85 bg-stone-50 px-4 py-2 text-[10px] text-stone-500",
3864
+ className: "border-t border-border bg-muted px-4 py-2 text-[10px] text-muted-foreground",
3839
3865
  children: "Showing a shortened diff preview."
3840
3866
  }) : null
3841
3867
  ]
@@ -3846,7 +3872,7 @@ function ToolCardFileOperationContent({ card, className, onFileOpen }) {
3846
3872
  const output = card.output?.trim() ?? "";
3847
3873
  if (blocks.length === 0 && !output) return null;
3848
3874
  return /* @__PURE__ */ jsxs("div", {
3849
- className: cn("overflow-hidden bg-white", className),
3875
+ className: cn("overflow-hidden bg-card", className),
3850
3876
  children: [blocks.map((block, index) => {
3851
3877
  return /* @__PURE__ */ jsx(FileOperationBlock, {
3852
3878
  block,
@@ -3857,12 +3883,12 @@ function ToolCardFileOperationContent({ card, className, onFileOpen }) {
3857
3883
  }), output ? /* @__PURE__ */ jsx(StickyFileOperationScrollArea, {
3858
3884
  resetKey: `output:${card.toolName}:${card.summary ?? "none"}`,
3859
3885
  contentVersion: output,
3860
- className: cn("max-h-56", blocks.length > 0 && "border-t border-stone-200/80"),
3886
+ className: cn("max-h-56", blocks.length > 0 && "border-t border-border"),
3861
3887
  scrollKind: "output",
3862
3888
  children: /* @__PURE__ */ jsx("div", {
3863
- className: "overflow-x-auto custom-scrollbar-amber",
3889
+ className: "overflow-x-auto custom-scrollbar",
3864
3890
  children: /* @__PURE__ */ jsx("pre", {
3865
- className: "min-w-max whitespace-pre bg-white px-4 py-2 font-mono text-[11px] leading-5 text-amber-950/80",
3891
+ className: "min-w-max whitespace-pre bg-card px-4 py-2 font-mono text-[11px] leading-5 text-foreground",
3866
3892
  children: output
3867
3893
  })
3868
3894
  })
@@ -3978,16 +4004,16 @@ function useToolCardExpandedState({ canExpand, isRunning, autoExpandWhileRunning
3978
4004
  function GenericToolSection({ label, tone, children }) {
3979
4005
  const style = {
3980
4006
  input: {
3981
- shell: "border-stone-200/80 bg-stone-50/90",
3982
- header: "border-stone-200/80 bg-stone-100/85 text-stone-500",
3983
- dot: "bg-stone-400/80",
3984
- body: "text-stone-700"
4007
+ shell: "border-border bg-card",
4008
+ header: "border-border bg-muted/55 text-muted-foreground",
4009
+ dot: "bg-muted-foreground/60",
4010
+ body: "text-foreground"
3985
4011
  },
3986
4012
  output: {
3987
- shell: "border-amber-200/70 bg-white/90",
3988
- header: "border-amber-200/70 bg-amber-50/90 text-amber-700",
3989
- dot: "bg-amber-500/80",
3990
- body: "text-amber-950/80"
4013
+ shell: "border-border bg-card",
4014
+ header: "border-border bg-muted/55 text-muted-foreground",
4015
+ dot: "bg-primary/70",
4016
+ body: "text-foreground"
3991
4017
  },
3992
4018
  error: {
3993
4019
  shell: "border-rose-200/80 bg-rose-50/85",
@@ -4004,7 +4030,7 @@ function GenericToolSection({ label, tone, children }) {
4004
4030
  }), /* @__PURE__ */ jsx("div", {
4005
4031
  className: "w-full overflow-hidden",
4006
4032
  children: /* @__PURE__ */ jsx("pre", {
4007
- className: cn("w-full max-w-full min-w-0 max-h-64 overflow-x-auto overflow-y-auto px-3 py-2.5 font-mono text-[12px] leading-relaxed whitespace-pre custom-scrollbar-amber", style.body),
4033
+ className: cn("w-full max-w-full min-w-0 max-h-64 overflow-x-auto overflow-y-auto px-3 py-2.5 font-mono text-[12px] leading-relaxed whitespace-pre custom-scrollbar", style.body),
4008
4034
  children
4009
4035
  })
4010
4036
  })]
@@ -4029,23 +4055,23 @@ function TerminalExecutionView({ card }) {
4029
4055
  canExpand: output.trim().length > 0 || isRunning,
4030
4056
  onToggle
4031
4057
  }), expanded && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
4032
- className: "px-3 pb-2 font-mono w-full max-h-48 overflow-y-auto custom-scrollbar-amber min-h-0 text-[12px]",
4058
+ className: "px-3 pb-2 font-mono w-full max-h-48 overflow-y-auto custom-scrollbar min-h-0 text-[12px]",
4033
4059
  children: /* @__PURE__ */ jsxs("div", {
4034
4060
  className: "flex items-start gap-2 leading-relaxed",
4035
4061
  children: [/* @__PURE__ */ jsx("span", {
4036
- className: "text-amber-500/50 font-medium shrink-0 select-none mt-[1px]",
4062
+ className: "text-primary/55 font-medium shrink-0 select-none mt-[1px]",
4037
4063
  children: "$"
4038
4064
  }), /* @__PURE__ */ jsx("div", {
4039
4065
  className: "flex-1 min-w-0",
4040
4066
  children: commandPart ? /* @__PURE__ */ jsxs("div", {
4041
- className: "text-amber-950/80 break-words whitespace-pre-wrap tracking-tight font-medium inline-block",
4042
- children: [commandPart, isRunning && !output && /* @__PURE__ */ jsx("span", { className: "inline-block w-1.5 h-3 ml-1 bg-amber-500/60 animate-pulse align-middle" })]
4043
- }) : /* @__PURE__ */ jsx("div", { className: "h-3 w-32 bg-amber-200/30 rounded animate-pulse mt-2" })
4067
+ className: "text-foreground break-words whitespace-pre-wrap tracking-tight font-medium inline-block",
4068
+ children: [commandPart, isRunning && !output && /* @__PURE__ */ jsx("span", { className: "inline-block w-1.5 h-3 ml-1 bg-primary/60 animate-pulse align-middle" })]
4069
+ }) : /* @__PURE__ */ jsx("div", { className: "h-3 w-32 bg-muted rounded animate-pulse mt-2" })
4044
4070
  })]
4045
4071
  })
4046
4072
  }), output && /* @__PURE__ */ jsx(ToolCardContent, { children: /* @__PURE__ */ jsxs("pre", {
4047
- className: "font-mono text-[12px] text-amber-950/70 whitespace-pre-wrap break-all w-full max-w-full max-h-64 overflow-y-auto overflow-x-hidden min-w-0 custom-scrollbar-amber leading-relaxed px-0",
4048
- children: [output, isRunning && /* @__PURE__ */ jsx("span", { className: "inline-block w-1.5 h-3 ml-1 bg-amber-500/60 animate-pulse align-middle" })]
4073
+ className: "font-mono text-[12px] text-muted-foreground whitespace-pre-wrap break-all w-full max-w-full max-h-64 overflow-y-auto overflow-x-hidden min-w-0 custom-scrollbar leading-relaxed px-0",
4074
+ children: [output, isRunning && /* @__PURE__ */ jsx("span", { className: "inline-block w-1.5 h-3 ml-1 bg-primary/60 animate-pulse align-middle" })]
4049
4075
  }) })] })] });
4050
4076
  }
4051
4077
  function FileOperationView({ card, onFileOpen }) {
@@ -4075,7 +4101,7 @@ function FileOperationView({ card, onFileOpen }) {
4075
4101
  hideSummary: expanded && hasStructuredPreview,
4076
4102
  onToggle
4077
4103
  }), expanded && hasContent && /* @__PURE__ */ jsx(ToolCardContent, {
4078
- className: "border-t border-amber-200/20 bg-transparent px-0 pt-0 pb-0",
4104
+ className: "border-t border-border bg-transparent px-0 pt-0 pb-0",
4079
4105
  children: /* @__PURE__ */ jsx(ToolCardFileOperationContent, {
4080
4106
  card,
4081
4107
  onFileOpen
@@ -4098,7 +4124,7 @@ function SearchSnippetView({ card }) {
4098
4124
  canExpand: !!output || isRunning,
4099
4125
  onToggle
4100
4126
  }), expanded && output && /* @__PURE__ */ jsx(ToolCardContent, { children: /* @__PURE__ */ jsx("pre", {
4101
- className: "font-mono text-[12px] text-amber-950/70 whitespace-pre-wrap break-all w-full max-w-full max-h-64 overflow-y-auto overflow-x-hidden min-w-0 custom-scrollbar-amber leading-relaxed",
4127
+ className: "font-mono text-[12px] text-muted-foreground whitespace-pre-wrap break-all w-full max-w-full max-h-64 overflow-y-auto overflow-x-hidden min-w-0 custom-scrollbar leading-relaxed",
4102
4128
  children: output
4103
4129
  }) })] });
4104
4130
  }
@@ -4197,7 +4223,7 @@ const ChatMessage = memo(function ChatMessage({ message, texts, onToolAction, on
4197
4223
  const isUser = role === "user";
4198
4224
  const isMessageInProgress = message.status === "pending" || message.status === "streaming";
4199
4225
  return /* @__PURE__ */ jsx("div", {
4200
- className: cn("inline-block w-fit max-w-full rounded-2xl border px-4 shadow-sm", isUser ? "border-primary bg-primary py-3 text-white" : role === "assistant" ? "border-gray-200 bg-white pb-3 pt-4 text-gray-900" : "border-orange-200/80 bg-orange-50/70 py-3 text-gray-900"),
4226
+ className: cn("inline-block w-fit max-w-full rounded-2xl border px-4 shadow-sm", isUser ? "border-primary bg-primary py-3 text-primary-foreground" : role === "assistant" ? "border-border bg-card pb-3 pt-4 text-card-foreground" : "border-border bg-muted/45 py-3 text-foreground"),
4201
4227
  children: /* @__PURE__ */ jsx("div", {
4202
4228
  className: "space-y-2",
4203
4229
  children: message.parts.map((part, index) => {
@@ -4245,16 +4271,16 @@ const ChatMessage = memo(function ChatMessage({ message, texts, onToolAction, on
4245
4271
  if (type === "unknown") {
4246
4272
  const { label, rawType, text } = part;
4247
4273
  return /* @__PURE__ */ jsxs("div", {
4248
- className: "rounded-lg border border-gray-200 bg-gray-50 px-2.5 py-2 text-xs text-gray-600",
4274
+ className: "rounded-lg border border-border bg-muted/60 px-2.5 py-2 text-xs text-muted-foreground",
4249
4275
  children: [/* @__PURE__ */ jsxs("div", {
4250
- className: "font-semibold text-gray-700",
4276
+ className: "font-semibold text-foreground",
4251
4277
  children: [
4252
4278
  label,
4253
4279
  ": ",
4254
4280
  rawType
4255
4281
  ]
4256
4282
  }), text ? /* @__PURE__ */ jsx("pre", {
4257
- className: "mt-1 whitespace-pre-wrap break-words text-[11px] text-gray-500",
4283
+ className: "mt-1 whitespace-pre-wrap break-words text-[11px] text-muted-foreground",
4258
4284
  children: text
4259
4285
  }) : null]
4260
4286
  }, `unknown-${index}`);
@@ -4279,7 +4305,7 @@ function ChatMessageActionCopy({ message, texts }) {
4279
4305
  return /* @__PURE__ */ jsx("button", {
4280
4306
  type: "button",
4281
4307
  onClick: () => void copy(),
4282
- className: "text-gray-400 hover:text-gray-600 transition-colors p-1 rounded-md hover:bg-gray-100 flex items-center justify-center",
4308
+ className: "text-muted-foreground hover:text-foreground transition-colors p-1 rounded-md hover:bg-accent flex items-center justify-center",
4283
4309
  "aria-label": copied ? texts.copiedMessageLabel : texts.copyMessageLabel,
4284
4310
  title: copied ? texts.copiedMessageLabel : texts.copyMessageLabel,
4285
4311
  children: copied ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" })
@@ -4301,13 +4327,13 @@ const TYPING_TEXT_SHEEN_CSS = `
4301
4327
  .nextclaw-chat-typing-indicator__text {
4302
4328
  background-image: linear-gradient(
4303
4329
  100deg,
4304
- #6b7280 0%,
4305
- #6b7280 34%,
4306
- #a6adba 43%,
4307
- #f8fafc 50%,
4308
- #a6adba 57%,
4309
- #6b7280 66%,
4310
- #6b7280 100%
4330
+ hsl(var(--muted-foreground)) 0%,
4331
+ hsl(var(--muted-foreground)) 34%,
4332
+ hsl(var(--foreground-tertiary)) 43%,
4333
+ hsl(var(--foreground-muted)) 50%,
4334
+ hsl(var(--foreground-tertiary)) 57%,
4335
+ hsl(var(--muted-foreground)) 66%,
4336
+ hsl(var(--muted-foreground)) 100%
4311
4337
  );
4312
4338
  background-size: 240% 100%;
4313
4339
  background-position: 160% 0;
@@ -4322,7 +4348,7 @@ const TYPING_TEXT_SHEEN_CSS = `
4322
4348
  .nextclaw-chat-typing-indicator__text {
4323
4349
  animation: none;
4324
4350
  background-image: none;
4325
- color: #6b7280;
4351
+ color: hsl(var(--muted-foreground));
4326
4352
  -webkit-text-fill-color: currentColor;
4327
4353
  }
4328
4354
  }
@@ -4340,20 +4366,20 @@ function hasRenderableMessageContent(message) {
4340
4366
  }
4341
4367
  function ChatMessageTypingFooter() {
4342
4368
  return /* @__PURE__ */ jsx("div", {
4343
- className: "flex items-center gap-2 px-1 py-0.5 text-[11px] text-gray-400",
4369
+ className: "flex items-center gap-2 px-1 py-0.5 text-[11px] text-muted-foreground",
4344
4370
  children: /* @__PURE__ */ jsxs("div", {
4345
4371
  className: "flex space-x-1 items-center h-full",
4346
4372
  children: [
4347
- /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full bg-gray-400 animate-pulse" }),
4348
- /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full bg-gray-400 animate-pulse [animation-delay:200ms]" }),
4349
- /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full bg-gray-400 animate-pulse [animation-delay:400ms]" })
4373
+ /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full bg-muted-foreground animate-pulse" }),
4374
+ /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full bg-muted-foreground animate-pulse [animation-delay:200ms]" }),
4375
+ /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 rounded-full bg-muted-foreground animate-pulse [animation-delay:400ms]" })
4350
4376
  ]
4351
4377
  })
4352
4378
  });
4353
4379
  }
4354
4380
  function ChatTypingIndicator({ label }) {
4355
4381
  return /* @__PURE__ */ jsxs("div", {
4356
- className: "rounded-2xl border border-gray-200 bg-white px-4 py-3 text-sm text-gray-500 shadow-sm",
4382
+ className: "rounded-2xl border border-border bg-card px-4 py-3 text-sm text-muted-foreground shadow-sm",
4357
4383
  children: [/* @__PURE__ */ jsx("style", { children: TYPING_TEXT_SHEEN_CSS }), /* @__PURE__ */ jsx("span", {
4358
4384
  className: "nextclaw-chat-typing-indicator__text",
4359
4385
  children: label
@@ -4384,7 +4410,7 @@ function ChatMessageList({ className, isSending, messages, onFileOpen, onToolAct
4384
4410
  }), /* @__PURE__ */ jsx("div", {
4385
4411
  className: cn("flex items-center gap-2", isUser && "justify-end"),
4386
4412
  children: isGenerating ? /* @__PURE__ */ jsx(ChatMessageTypingFooter, {}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("div", {
4387
- className: cn("px-1 text-[11px] leading-4 text-gray-400", isUser ? "text-right" : "text-left"),
4413
+ className: cn("px-1 text-[11px] leading-4 text-muted-foreground", isUser ? "text-right" : "text-left"),
4388
4414
  children: [
4389
4415
  message.roleLabel,
4390
4416
  " · ",