@nextclaw/agent-chat-ui 0.2.16 → 0.2.18

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.d.ts CHANGED
@@ -81,6 +81,11 @@ type ChatSkillPickerOption = {
81
81
  description?: string;
82
82
  badgeLabel?: string;
83
83
  };
84
+ type ChatSkillPickerOptionGroup = {
85
+ key: string;
86
+ label?: string;
87
+ options: ChatSkillPickerOption[];
88
+ };
84
89
  type ChatSkillPickerProps = {
85
90
  title: string;
86
91
  searchPlaceholder: string;
@@ -90,6 +95,7 @@ type ChatSkillPickerProps = {
90
95
  manageLabel?: string;
91
96
  manageHref?: string;
92
97
  options: ChatSkillPickerOption[];
98
+ groups?: ChatSkillPickerOptionGroup[];
93
99
  selectedKeys: string[];
94
100
  onSelectedKeysChange: (next: string[]) => void;
95
101
  };
@@ -138,7 +144,9 @@ type ChatInputBarProps = {
138
144
  onFilesAdd?: (files: File[]) => Promise<void> | void;
139
145
  onSlashQueryChange?: (query: string | null) => void;
140
146
  };
141
- slashMenu: Pick<ChatSlashMenuProps, "isLoading" | "items" | "texts">;
147
+ slashMenu: Pick<ChatSlashMenuProps, "isLoading" | "items" | "texts"> & {
148
+ onSelectItem?: (item: ChatSlashItem) => void;
149
+ };
142
150
  hint?: ChatInlineHint | null;
143
151
  toolbar: ChatInputBarToolbarProps;
144
152
  };
@@ -155,9 +163,25 @@ type ChatToolPartViewModel = {
155
163
  outputLabel: string;
156
164
  emptyLabel: string;
157
165
  };
166
+ type ChatInlineTokenViewModel = {
167
+ kind: string;
168
+ key: string;
169
+ label: string;
170
+ rawText: string;
171
+ };
172
+ type ChatInlineContentSegmentViewModel = {
173
+ type: "markdown";
174
+ text: string;
175
+ } | {
176
+ type: "token";
177
+ token: ChatInlineTokenViewModel;
178
+ };
158
179
  type ChatMessagePartViewModel = {
159
180
  type: "markdown";
160
181
  text: string;
182
+ } | {
183
+ type: "inline-content";
184
+ segments: ChatInlineContentSegmentViewModel[];
161
185
  } | {
162
186
  type: "reasoning";
163
187
  text: string;
@@ -275,4 +299,4 @@ declare function resolveChatComposerSlashTrigger(nodes: ChatComposerNode[], sele
275
299
  end: number;
276
300
  } | null;
277
301
 
278
- export { type ChatComposerNode, type ChatComposerSelection, type ChatComposerTextNode, type ChatComposerTokenKind, type ChatComposerTokenNode, type ChatInlineHint, ChatInputBar, type ChatInputBarActionsProps, type ChatInputBarHandle, type ChatInputBarProps, type ChatInputBarToolbarProps, ChatMessageList, type ChatMessageListProps, type ChatMessagePartViewModel, type ChatMessageRole, type ChatMessageTexts, type ChatMessageViewModel, type ChatSelectedItem, type ChatSkillPickerOption, type ChatSkillPickerProps, type ChatSlashItem, type ChatSlashMenuProps, type ChatTexts, type ChatToolPartViewModel, type ChatToolbarAccessory, type ChatToolbarAccessoryIcon, type ChatToolbarIcon, type ChatToolbarSelect, type ChatToolbarSelectGroup, type ChatToolbarSelectOption, copyText, createChatComposerNodesFromText, createChatComposerTextNode, createChatComposerTokenNode, createEmptyChatComposerNodes, extractChatComposerTokenKeys, normalizeChatComposerNodes, removeChatComposerTokenNodes, replaceChatComposerRange, resolveChatComposerSlashTrigger, serializeChatComposerDocument, serializeChatComposerPlainText, useActiveItemScroll, useCopyFeedback, useElementWidth, useStickyBottomScroll };
302
+ export { type ChatComposerNode, type ChatComposerSelection, type ChatComposerTextNode, type ChatComposerTokenKind, type ChatComposerTokenNode, type ChatInlineContentSegmentViewModel, type ChatInlineHint, type ChatInlineTokenViewModel, ChatInputBar, type ChatInputBarActionsProps, type ChatInputBarHandle, type ChatInputBarProps, type ChatInputBarToolbarProps, ChatMessageList, type ChatMessageListProps, type ChatMessagePartViewModel, type ChatMessageRole, type ChatMessageTexts, type ChatMessageViewModel, type ChatSelectedItem, type ChatSkillPickerOption, type ChatSkillPickerProps, type ChatSlashItem, type ChatSlashMenuProps, type ChatTexts, type ChatToolPartViewModel, type ChatToolbarAccessory, type ChatToolbarAccessoryIcon, type ChatToolbarIcon, type ChatToolbarSelect, type ChatToolbarSelectGroup, type ChatToolbarSelectOption, copyText, createChatComposerNodesFromText, createChatComposerTextNode, createChatComposerTokenNode, createEmptyChatComposerNodes, extractChatComposerTokenKeys, normalizeChatComposerNodes, removeChatComposerTokenNodes, replaceChatComposerRange, resolveChatComposerSlashTrigger, serializeChatComposerDocument, serializeChatComposerPlainText, useActiveItemScroll, useCopyFeedback, useElementWidth, useStickyBottomScroll };
package/dist/index.js CHANGED
@@ -424,23 +424,36 @@ function ChatInputBarSkillPicker(props) {
424
424
  const [activeIndex, setActiveIndex] = useState2(0);
425
425
  const selectedSet = useMemo2(() => new Set(picker.selectedKeys), [picker.selectedKeys]);
426
426
  const selectedCount = picker.selectedKeys.length;
427
- const filteredOptions = useMemo2(() => filterOptions(picker.options, query), [picker.options, query]);
427
+ const isSearchActive = query.trim().length > 0;
428
+ const groupedOptions = useMemo2(() => {
429
+ if (isSearchActive) {
430
+ return null;
431
+ }
432
+ const groups = picker.groups?.filter((group) => group.options.length > 0) ?? [];
433
+ return groups.length > 0 ? groups : null;
434
+ }, [isSearchActive, picker.groups]);
435
+ const visibleOptions = useMemo2(() => {
436
+ if (groupedOptions) {
437
+ return groupedOptions.flatMap((group) => group.options);
438
+ }
439
+ return filterOptions(picker.options, query);
440
+ }, [groupedOptions, picker.options, query]);
428
441
  useEffect3(() => {
429
442
  setActiveIndex(0);
430
443
  }, [query]);
431
444
  useEffect3(() => {
432
445
  setActiveIndex((current) => {
433
- if (filteredOptions.length === 0) {
446
+ if (visibleOptions.length === 0) {
434
447
  return 0;
435
448
  }
436
- return Math.min(current, filteredOptions.length - 1);
449
+ return Math.min(current, visibleOptions.length - 1);
437
450
  });
438
- }, [filteredOptions.length]);
451
+ }, [visibleOptions.length]);
439
452
  useActiveItemScroll({
440
453
  containerRef: listRef,
441
454
  activeIndex,
442
- itemCount: filteredOptions.length,
443
- isEnabled: filteredOptions.length > 0,
455
+ itemCount: visibleOptions.length,
456
+ isEnabled: visibleOptions.length > 0,
444
457
  getItemSelector: (index) => `[data-skill-index="${index}"]`
445
458
  });
446
459
  const onToggleOption = (optionKey) => {
@@ -451,12 +464,12 @@ function ChatInputBarSkillPicker(props) {
451
464
  picker.onSelectedKeysChange([...picker.selectedKeys, optionKey]);
452
465
  };
453
466
  const onSearchKeyDown = (event) => {
454
- if (filteredOptions.length === 0) {
467
+ if (visibleOptions.length === 0) {
455
468
  return;
456
469
  }
457
470
  if (event.key === "ArrowDown") {
458
471
  event.preventDefault();
459
- setActiveIndex((current) => Math.min(current + 1, filteredOptions.length - 1));
472
+ setActiveIndex((current) => Math.min(current + 1, visibleOptions.length - 1));
460
473
  return;
461
474
  }
462
475
  if (event.key === "ArrowUp") {
@@ -466,7 +479,7 @@ function ChatInputBarSkillPicker(props) {
466
479
  }
467
480
  if (event.key === "Enter") {
468
481
  event.preventDefault();
469
- const activeOption = filteredOptions[activeIndex];
482
+ const activeOption = visibleOptions[activeIndex];
470
483
  if (activeOption) {
471
484
  onToggleOption(activeOption.key);
472
485
  }
@@ -502,7 +515,7 @@ function ChatInputBarSkillPicker(props) {
502
515
  "aria-controls": listId,
503
516
  "aria-expanded": "true",
504
517
  "aria-autocomplete": "list",
505
- "aria-activedescendant": filteredOptions[activeIndex] ? `${listId}-option-${activeIndex}` : void 0,
518
+ "aria-activedescendant": visibleOptions[activeIndex] ? `${listId}-option-${activeIndex}` : void 0,
506
519
  className: "h-8 rounded-lg pl-8 text-xs"
507
520
  }
508
521
  )
@@ -516,41 +529,50 @@ function ChatInputBarSkillPicker(props) {
516
529
  role: "listbox",
517
530
  "aria-multiselectable": "true",
518
531
  className: "custom-scrollbar max-h-[320px] overflow-y-auto",
519
- children: picker.isLoading ? /* @__PURE__ */ jsx8("div", { className: "p-4 text-xs text-gray-500", children: picker.loadingLabel }) : filteredOptions.length === 0 ? /* @__PURE__ */ jsx8("div", { className: "p-4 text-center text-xs text-gray-500", children: picker.emptyLabel }) : /* @__PURE__ */ jsx8("div", { className: "py-1", children: filteredOptions.map((option, index) => {
520
- const isSelected = selectedSet.has(option.key);
521
- const isActive = index === activeIndex;
522
- return /* @__PURE__ */ jsxs4(
523
- "button",
524
- {
525
- type: "button",
526
- id: `${listId}-option-${index}`,
527
- role: "option",
528
- "aria-selected": isSelected,
529
- "data-skill-index": index,
530
- onClick: () => onToggleOption(option.key),
531
- onMouseEnter: () => setActiveIndex(index),
532
- 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"}`,
533
- children: [
534
- /* @__PURE__ */ jsx8("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-500", children: /* @__PURE__ */ jsx8(Puzzle, { className: "h-4 w-4" }) }),
535
- /* @__PURE__ */ jsxs4("div", { className: "min-w-0 flex-1", children: [
536
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1.5", children: [
537
- /* @__PURE__ */ jsx8("span", { className: "truncate text-sm text-gray-900", children: option.label }),
538
- option.badgeLabel ? /* @__PURE__ */ jsx8("span", { className: "shrink-0 rounded-full bg-primary/10 px-1.5 py-0.5 text-[10px] font-medium text-primary", children: option.badgeLabel }) : null
539
- ] }),
540
- /* @__PURE__ */ jsx8("div", { className: "mt-0.5 truncate text-xs text-gray-500", children: option.description || option.key })
541
- ] }),
542
- /* @__PURE__ */ jsx8("div", { className: "ml-3 shrink-0", children: /* @__PURE__ */ jsx8(
543
- "span",
544
- {
545
- 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",
546
- children: isSelected ? /* @__PURE__ */ jsx8(Check2, { className: "h-3 w-3" }) : null
547
- }
548
- ) })
549
- ]
550
- },
551
- option.key
552
- );
553
- }) })
532
+ children: picker.isLoading ? /* @__PURE__ */ jsx8("div", { className: "p-4 text-xs text-gray-500", children: picker.loadingLabel }) : visibleOptions.length === 0 ? /* @__PURE__ */ jsx8("div", { className: "p-4 text-center text-xs text-gray-500", children: picker.emptyLabel }) : /* @__PURE__ */ jsx8("div", { className: "py-1", children: (() => {
533
+ const groups = groupedOptions ?? [{ key: "all-skills", options: visibleOptions }];
534
+ let visibleIndex = 0;
535
+ return groups.map((group) => /* @__PURE__ */ jsxs4("div", { children: [
536
+ group.label ? /* @__PURE__ */ jsx8("div", { className: "px-4 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-gray-500", children: group.label }) : null,
537
+ group.options.map((option) => {
538
+ const index = visibleIndex;
539
+ visibleIndex += 1;
540
+ const isSelected = selectedSet.has(option.key);
541
+ const isActive = index === activeIndex;
542
+ return /* @__PURE__ */ jsxs4(
543
+ "button",
544
+ {
545
+ type: "button",
546
+ id: `${listId}-option-${index}`,
547
+ role: "option",
548
+ "aria-selected": isSelected,
549
+ "data-skill-index": index,
550
+ onClick: () => onToggleOption(option.key),
551
+ onMouseEnter: () => setActiveIndex(index),
552
+ 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"}`,
553
+ children: [
554
+ /* @__PURE__ */ jsx8("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-500", children: /* @__PURE__ */ jsx8(Puzzle, { className: "h-4 w-4" }) }),
555
+ /* @__PURE__ */ jsxs4("div", { className: "min-w-0 flex-1", children: [
556
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-1.5", children: [
557
+ /* @__PURE__ */ jsx8("span", { className: "truncate text-sm text-gray-900", children: option.label }),
558
+ option.badgeLabel ? /* @__PURE__ */ jsx8("span", { className: "shrink-0 rounded-full bg-primary/10 px-1.5 py-0.5 text-[10px] font-medium text-primary", children: option.badgeLabel }) : null
559
+ ] }),
560
+ /* @__PURE__ */ jsx8("div", { className: "mt-0.5 truncate text-xs text-gray-500", children: option.description || option.key })
561
+ ] }),
562
+ /* @__PURE__ */ jsx8("div", { className: "ml-3 shrink-0", children: /* @__PURE__ */ jsx8(
563
+ "span",
564
+ {
565
+ 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",
566
+ children: isSelected ? /* @__PURE__ */ jsx8(Check2, { className: "h-3 w-3" }) : null
567
+ }
568
+ ) })
569
+ ]
570
+ },
571
+ option.key
572
+ );
573
+ })
574
+ ] }, group.key));
575
+ })() })
554
576
  }
555
577
  ),
556
578
  picker.manageHref && picker.manageLabel ? /* @__PURE__ */ jsx8("div", { className: "border-t border-gray-100 px-4 py-2.5", children: /* @__PURE__ */ jsxs4(
@@ -1189,6 +1211,9 @@ function resolveChatComposerKeyboardAction(params) {
1189
1211
  isSending,
1190
1212
  canStopGeneration
1191
1213
  } = params;
1214
+ if (key === "Enter" && !shiftKey && isSending) {
1215
+ return { type: "consume" };
1216
+ }
1192
1217
  if (isSlashMenuOpen && slashItemCount > 0) {
1193
1218
  if (key === "ArrowDown") {
1194
1219
  return {
@@ -1433,6 +1458,7 @@ var ChatComposerViewController = class {
1433
1458
  actions,
1434
1459
  commitSnapshot,
1435
1460
  insertSkillToken,
1461
+ onSlashItemSelect,
1436
1462
  onSlashActiveIndexChange,
1437
1463
  onSlashQueryChange,
1438
1464
  onSlashOpenChange
@@ -1452,36 +1478,17 @@ var ChatComposerViewController = class {
1452
1478
  return;
1453
1479
  }
1454
1480
  event.preventDefault();
1455
- if (action.type === "move-slash-index") {
1456
- onSlashActiveIndexChange(action.index);
1457
- return;
1458
- }
1459
- if (action.type === "insert-active-slash-item") {
1460
- if (activeSlashItem) {
1461
- insertSkillToken(activeSlashItem.value ?? activeSlashItem.key, activeSlashItem.title);
1462
- }
1463
- return;
1464
- }
1465
- if (action.type === "close-slash") {
1466
- onSlashQueryChange?.(null);
1467
- onSlashOpenChange(false);
1468
- return;
1469
- }
1470
- if (action.type === "stop-generation") {
1471
- void actions.onStop();
1472
- return;
1473
- }
1474
- if (action.type === "insert-line-break") {
1475
- commitSnapshot(this.controller.insertText("\n"));
1476
- return;
1477
- }
1478
- if (action.type === "send-message") {
1479
- void actions.onSend();
1480
- return;
1481
- }
1482
- if (action.type === "delete-content") {
1483
- commitSnapshot(this.controller.deleteContent(action.direction));
1484
- }
1481
+ this.applyKeyboardAction({
1482
+ action,
1483
+ activeSlashItem,
1484
+ actions,
1485
+ commitSnapshot,
1486
+ insertSkillToken,
1487
+ onSlashItemSelect,
1488
+ onSlashActiveIndexChange,
1489
+ onSlashQueryChange,
1490
+ onSlashOpenChange
1491
+ });
1485
1492
  };
1486
1493
  this.handlePaste = (params) => {
1487
1494
  const { event, onFilesAdd, commitSnapshot } = params;
@@ -1504,6 +1511,60 @@ var ChatComposerViewController = class {
1504
1511
  onSlashQueryChange?.(null);
1505
1512
  onSlashOpenChange(false);
1506
1513
  };
1514
+ this.applyKeyboardAction = (params) => {
1515
+ const {
1516
+ action,
1517
+ activeSlashItem,
1518
+ actions,
1519
+ commitSnapshot,
1520
+ insertSkillToken,
1521
+ onSlashItemSelect,
1522
+ onSlashActiveIndexChange,
1523
+ onSlashQueryChange,
1524
+ onSlashOpenChange
1525
+ } = params;
1526
+ switch (action.type) {
1527
+ case "move-slash-index": {
1528
+ onSlashActiveIndexChange(action.index);
1529
+ return;
1530
+ }
1531
+ case "insert-active-slash-item": {
1532
+ if (!activeSlashItem) {
1533
+ return;
1534
+ }
1535
+ onSlashItemSelect?.(activeSlashItem);
1536
+ insertSkillToken(activeSlashItem.value ?? activeSlashItem.key, activeSlashItem.title);
1537
+ return;
1538
+ }
1539
+ case "close-slash": {
1540
+ onSlashQueryChange?.(null);
1541
+ onSlashOpenChange(false);
1542
+ return;
1543
+ }
1544
+ case "consume": {
1545
+ return;
1546
+ }
1547
+ case "stop-generation": {
1548
+ void actions.onStop();
1549
+ return;
1550
+ }
1551
+ case "insert-line-break": {
1552
+ commitSnapshot(this.controller.insertText("\n"));
1553
+ return;
1554
+ }
1555
+ case "send-message": {
1556
+ void actions.onSend();
1557
+ return;
1558
+ }
1559
+ case "delete-content": {
1560
+ commitSnapshot(this.controller.deleteContent(action.direction));
1561
+ return;
1562
+ }
1563
+ case "noop": {
1564
+ return;
1565
+ }
1566
+ }
1567
+ };
1507
1568
  }
1508
1569
  };
1509
1570
 
@@ -1542,6 +1603,7 @@ var ChatComposerRuntime = class {
1542
1603
  this.createHandle = () => {
1543
1604
  return {
1544
1605
  insertSlashItem: (item) => {
1606
+ this.config?.onSlashItemSelect?.(item);
1545
1607
  this.viewController.insertSlashItem(item, this.commitSnapshot);
1546
1608
  },
1547
1609
  insertFileToken: (tokenKey, label) => {
@@ -1637,6 +1699,7 @@ var ChatComposerRuntime = class {
1637
1699
  actions: config.actions,
1638
1700
  commitSnapshot: this.commitSnapshot,
1639
1701
  insertSkillToken: this.insertSkillToken,
1702
+ onSlashItemSelect: config.onSlashItemSelect,
1640
1703
  onSlashActiveIndexChange: config.onSlashActiveIndexChange,
1641
1704
  onSlashQueryChange: config.onSlashQueryChange,
1642
1705
  onSlashOpenChange: config.onSlashOpenChange
@@ -1731,6 +1794,7 @@ var ChatInputBarTokenizedComposer = forwardRef6(function ChatInputBarTokenizedCo
1731
1794
  placeholder,
1732
1795
  disabled,
1733
1796
  slashItems,
1797
+ onSlashItemSelect,
1734
1798
  actions,
1735
1799
  onNodesChange,
1736
1800
  onFilesAdd,
@@ -1758,6 +1822,7 @@ var ChatInputBarTokenizedComposer = forwardRef6(function ChatInputBarTokenizedCo
1758
1822
  nodes,
1759
1823
  disabled,
1760
1824
  slashItems,
1825
+ onSlashItemSelect,
1761
1826
  actions,
1762
1827
  onNodesChange,
1763
1828
  onFilesAdd,
@@ -1880,6 +1945,7 @@ var ChatInputBar = forwardRef7(function ChatInputBar2(props, ref) {
1880
1945
  placeholder: props.composer.placeholder,
1881
1946
  disabled: props.composer.disabled,
1882
1947
  slashItems: props.slashMenu.items,
1948
+ onSlashItemSelect: props.slashMenu.onSelectItem,
1883
1949
  actions: props.toolbar.actions,
1884
1950
  activeSlashIndex,
1885
1951
  onNodesChange: props.composer.onNodesChange,
@@ -2131,7 +2197,7 @@ function ChatCodeBlock(props) {
2131
2197
  }
2132
2198
 
2133
2199
  // src/components/chat/ui/chat-message-list/chat-message-markdown.tsx
2134
- import { jsx as jsx14 } from "react/jsx-runtime";
2200
+ import { Fragment as Fragment2, jsx as jsx14 } from "react/jsx-runtime";
2135
2201
  var MARKDOWN_MAX_CHARS = 14e4;
2136
2202
  var SAFE_LINK_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:", "mailto:", "tel:"]);
2137
2203
  function trimMarkdown(value) {
@@ -2159,9 +2225,15 @@ function resolveSafeHref(href) {
2159
2225
  function isExternalHref(href) {
2160
2226
  return /^https?:\/\//i.test(href);
2161
2227
  }
2162
- function ChatMessageMarkdown(props) {
2163
- const isUser = props.role === "user";
2228
+ function ChatMessageMarkdown({
2229
+ text,
2230
+ role,
2231
+ texts,
2232
+ inline = false
2233
+ }) {
2234
+ const isUser = role === "user";
2164
2235
  const markdownComponents = useMemo5(() => ({
2236
+ p: ({ children }) => inline ? /* @__PURE__ */ jsx14(Fragment2, { children }) : /* @__PURE__ */ jsx14("p", { children }),
2165
2237
  a: ({ href, children, ...rest }) => {
2166
2238
  const safeHref = resolveSafeHref(href);
2167
2239
  if (!safeHref) {
@@ -2199,10 +2271,101 @@ function ChatMessageMarkdown(props) {
2199
2271
  if (isInlineCode) {
2200
2272
  return /* @__PURE__ */ jsx14("code", { ...rest, className: cn("chat-inline-code", className), children });
2201
2273
  }
2202
- return /* @__PURE__ */ jsx14(ChatCodeBlock, { className, texts: props.texts, children });
2274
+ return /* @__PURE__ */ jsx14(ChatCodeBlock, { className, texts, children });
2203
2275
  }
2204
- }), [props.texts]);
2205
- return /* @__PURE__ */ jsx14("div", { className: cn("chat-markdown", isUser ? "chat-markdown-user" : "chat-markdown-assistant"), children: /* @__PURE__ */ jsx14(ReactMarkdown, { skipHtml: true, remarkPlugins: [remarkGfm], components: markdownComponents, children: trimMarkdown(props.text) }) });
2276
+ }), [inline, texts]);
2277
+ const WrapperTag = inline ? "span" : "div";
2278
+ return /* @__PURE__ */ jsx14(WrapperTag, { className: cn("chat-markdown", isUser ? "chat-markdown-user" : "chat-markdown-assistant"), children: /* @__PURE__ */ jsx14(ReactMarkdown, { skipHtml: true, remarkPlugins: [remarkGfm], components: markdownComponents, children: trimMarkdown(text) }) });
2279
+ }
2280
+
2281
+ // src/components/chat/ui/chat-message-list/chat-message-inline-content.tsx
2282
+ import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
2283
+ function hasVisibleInlineText(value) {
2284
+ return value.split("\u200B").join("").split("\u200C").join("").split("\u200D").join("").split("\u2060").join("").split("\uFEFF").join("").length > 0;
2285
+ }
2286
+ function ChatInlineSkillIcon() {
2287
+ return /* @__PURE__ */ jsxs8(
2288
+ "svg",
2289
+ {
2290
+ viewBox: "0 0 16 16",
2291
+ fill: "none",
2292
+ stroke: "currentColor",
2293
+ strokeWidth: "1.25",
2294
+ strokeLinecap: "round",
2295
+ strokeLinejoin: "round",
2296
+ "aria-hidden": "true",
2297
+ className: "h-3 w-3",
2298
+ children: [
2299
+ /* @__PURE__ */ jsx15("path", { d: "M8.5 2.75 2.75 6l5.75 3.25L14.25 6 8.5 2.75Z" }),
2300
+ /* @__PURE__ */ jsx15("path", { d: "M2.75 10 8.5 13.25 14.25 10" }),
2301
+ /* @__PURE__ */ jsx15("path", { d: "M2.75 6v4l5.75 3.25V9.25L2.75 6Z" }),
2302
+ /* @__PURE__ */ jsx15("path", { d: "M14.25 6v4L8.5 13.25V9.25L14.25 6Z" })
2303
+ ]
2304
+ }
2305
+ );
2306
+ }
2307
+ function ChatInlineTokenBadge({
2308
+ kind,
2309
+ label,
2310
+ isUser
2311
+ }) {
2312
+ const isSkill = kind === "skill";
2313
+ return /* @__PURE__ */ jsxs8(
2314
+ "span",
2315
+ {
2316
+ className: cn(
2317
+ "mx-[2px] inline-flex h-7 max-w-full items-center gap-1.5 rounded-lg border px-2 align-baseline text-[11px] font-medium",
2318
+ isSkill ? isUser ? "border-white/25 bg-white/16 text-white" : "border-primary/12 bg-primary/8 text-primary" : isUser ? "border-white/20 bg-white/12 text-white" : "border-slate-200/80 bg-slate-50 text-slate-700"
2319
+ ),
2320
+ title: label,
2321
+ children: [
2322
+ /* @__PURE__ */ jsx15(
2323
+ "span",
2324
+ {
2325
+ className: cn(
2326
+ "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center",
2327
+ isSkill ? isUser ? "text-white/75" : "text-primary/70" : isUser ? "text-white/70" : "text-slate-500"
2328
+ ),
2329
+ children: /* @__PURE__ */ jsx15(ChatInlineSkillIcon, {})
2330
+ }
2331
+ ),
2332
+ /* @__PURE__ */ jsx15("span", { className: "truncate", children: label })
2333
+ ]
2334
+ }
2335
+ );
2336
+ }
2337
+ function ChatMessageInlineContent({
2338
+ segments,
2339
+ role,
2340
+ texts
2341
+ }) {
2342
+ const isUser = role === "user";
2343
+ return /* @__PURE__ */ jsx15("div", { className: "whitespace-pre-wrap break-words leading-6", children: segments.map((segment, index) => {
2344
+ if (segment.type === "token") {
2345
+ return /* @__PURE__ */ jsx15(
2346
+ ChatInlineTokenBadge,
2347
+ {
2348
+ kind: segment.token.kind,
2349
+ label: segment.token.label,
2350
+ isUser
2351
+ },
2352
+ `token-${index}-${segment.token.kind}-${segment.token.key}`
2353
+ );
2354
+ }
2355
+ if (!hasVisibleInlineText(segment.text)) {
2356
+ return /* @__PURE__ */ jsx15("span", { className: "whitespace-pre-wrap", children: segment.text }, `space-${index}`);
2357
+ }
2358
+ return /* @__PURE__ */ jsx15(
2359
+ ChatMessageMarkdown,
2360
+ {
2361
+ text: segment.text,
2362
+ role,
2363
+ texts,
2364
+ inline: true
2365
+ },
2366
+ `markdown-${index}`
2367
+ );
2368
+ }) });
2206
2369
  }
2207
2370
 
2208
2371
  // src/components/chat/ui/chat-message-list/chat-message-file/meta.ts
@@ -2358,9 +2521,9 @@ function buildChatMessageFileMeta(file) {
2358
2521
  }
2359
2522
 
2360
2523
  // src/components/chat/ui/chat-message-list/chat-message-file/index.tsx
2361
- import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
2524
+ import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
2362
2525
  function renderMetaBadge(label, isUser) {
2363
- return /* @__PURE__ */ jsx15(
2526
+ return /* @__PURE__ */ jsx16(
2364
2527
  "span",
2365
2528
  {
2366
2529
  className: cn(
@@ -2373,7 +2536,7 @@ function renderMetaBadge(label, isUser) {
2373
2536
  );
2374
2537
  }
2375
2538
  function renderMimeType(mimeType, isUser) {
2376
- return /* @__PURE__ */ jsx15(
2539
+ return /* @__PURE__ */ jsx16(
2377
2540
  "div",
2378
2541
  {
2379
2542
  className: cn(
@@ -2385,7 +2548,7 @@ function renderMimeType(mimeType, isUser) {
2385
2548
  );
2386
2549
  }
2387
2550
  function renderActionPill(label, isUser, isInteractive) {
2388
- return /* @__PURE__ */ jsx15(
2551
+ return /* @__PURE__ */ jsx16(
2389
2552
  "span",
2390
2553
  {
2391
2554
  className: cn(
@@ -2410,7 +2573,7 @@ function ChatMessageFile({
2410
2573
  isInteractive && (isUser ? "hover:border-white/18 hover:bg-white/13" : "hover:border-slate-300 hover:bg-white hover:shadow-[0_24px_50px_-30px_rgba(15,23,42,0.3)]")
2411
2574
  );
2412
2575
  if (file.isImage && file.dataUrl) {
2413
- return /* @__PURE__ */ jsx15(
2576
+ return /* @__PURE__ */ jsx16(
2414
2577
  "a",
2415
2578
  {
2416
2579
  href: file.dataUrl,
@@ -2418,8 +2581,8 @@ function ChatMessageFile({
2418
2581
  rel: "noreferrer",
2419
2582
  "aria-label": `Open preview: ${file.label}`,
2420
2583
  className: cn(shellClasses, "group"),
2421
- children: /* @__PURE__ */ jsxs8("figure", { children: [
2422
- /* @__PURE__ */ jsxs8(
2584
+ children: /* @__PURE__ */ jsxs9("figure", { children: [
2585
+ /* @__PURE__ */ jsxs9(
2423
2586
  "div",
2424
2587
  {
2425
2588
  className: cn(
@@ -2427,7 +2590,7 @@ function ChatMessageFile({
2427
2590
  isUser ? "bg-white/[0.04]" : "bg-gradient-to-br from-slate-100 via-white to-slate-100"
2428
2591
  ),
2429
2592
  children: [
2430
- /* @__PURE__ */ jsx15(
2593
+ /* @__PURE__ */ jsx16(
2431
2594
  "img",
2432
2595
  {
2433
2596
  src: file.dataUrl,
@@ -2435,9 +2598,9 @@ function ChatMessageFile({
2435
2598
  className: "block max-h-[22rem] w-full rounded-[1rem] object-cover shadow-[0_18px_40px_-26px_rgba(15,23,42,0.55)] transition duration-300 group-hover:scale-[1.01]"
2436
2599
  }
2437
2600
  ),
2438
- /* @__PURE__ */ jsxs8("div", { className: "pointer-events-none absolute inset-x-4 top-4 flex items-center justify-between", children: [
2439
- sizeLabel ? renderMetaBadge(sizeLabel, isUser) : /* @__PURE__ */ jsx15("span", {}),
2440
- /* @__PURE__ */ jsx15(
2601
+ /* @__PURE__ */ jsxs9("div", { className: "pointer-events-none absolute inset-x-4 top-4 flex items-center justify-between", children: [
2602
+ sizeLabel ? renderMetaBadge(sizeLabel, isUser) : /* @__PURE__ */ jsx16("span", {}),
2603
+ /* @__PURE__ */ jsx16(
2441
2604
  "span",
2442
2605
  {
2443
2606
  className: cn(
@@ -2451,8 +2614,8 @@ function ChatMessageFile({
2451
2614
  ]
2452
2615
  }
2453
2616
  ),
2454
- /* @__PURE__ */ jsxs8("figcaption", { className: "flex items-start gap-3 p-4", children: [
2455
- /* @__PURE__ */ jsx15(
2617
+ /* @__PURE__ */ jsxs9("figcaption", { className: "flex items-start gap-3 p-4", children: [
2618
+ /* @__PURE__ */ jsx16(
2456
2619
  "div",
2457
2620
  {
2458
2621
  className: cn(
@@ -2462,10 +2625,10 @@ function ChatMessageFile({
2462
2625
  children: tileLabel
2463
2626
  }
2464
2627
  ),
2465
- /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
2466
- /* @__PURE__ */ jsx15("div", { className: "truncate text-sm font-semibold leading-5", children: file.label }),
2467
- /* @__PURE__ */ jsx15("div", { className: "mt-2 flex flex-wrap gap-2", children: metaBadges.map((label) => renderMetaBadge(label, isUser)) }),
2468
- /* @__PURE__ */ jsx15("div", { className: "mt-2", children: renderMimeType(file.mimeType, isUser) })
2628
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
2629
+ /* @__PURE__ */ jsx16("div", { className: "truncate text-sm font-semibold leading-5", children: file.label }),
2630
+ /* @__PURE__ */ jsx16("div", { className: "mt-2 flex flex-wrap gap-2", children: metaBadges.map((label) => renderMetaBadge(label, isUser)) }),
2631
+ /* @__PURE__ */ jsx16("div", { className: "mt-2", children: renderMimeType(file.mimeType, isUser) })
2469
2632
  ] }),
2470
2633
  renderActionPill(actionLabel, isUser, true)
2471
2634
  ] })
@@ -2473,8 +2636,8 @@ function ChatMessageFile({
2473
2636
  }
2474
2637
  );
2475
2638
  }
2476
- const content = /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-3 p-3.5", children: [
2477
- /* @__PURE__ */ jsx15(
2639
+ const content = /* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-3 p-3.5", children: [
2640
+ /* @__PURE__ */ jsx16(
2478
2641
  "div",
2479
2642
  {
2480
2643
  className: cn(
@@ -2484,11 +2647,11 @@ function ChatMessageFile({
2484
2647
  children: tileLabel
2485
2648
  }
2486
2649
  ),
2487
- /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
2488
- /* @__PURE__ */ jsxs8("div", { className: "flex items-start gap-3", children: [
2489
- /* @__PURE__ */ jsxs8("div", { className: "min-w-0 flex-1", children: [
2490
- /* @__PURE__ */ jsx15("div", { className: "truncate text-sm font-semibold leading-5", children: file.label }),
2491
- /* @__PURE__ */ jsxs8(
2650
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
2651
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-3", children: [
2652
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
2653
+ /* @__PURE__ */ jsx16("div", { className: "truncate text-sm font-semibold leading-5", children: file.label }),
2654
+ /* @__PURE__ */ jsxs9(
2492
2655
  "div",
2493
2656
  {
2494
2657
  className: cn(
@@ -2504,14 +2667,14 @@ function ChatMessageFile({
2504
2667
  ] }),
2505
2668
  renderActionPill(actionLabel, isUser, isInteractive)
2506
2669
  ] }),
2507
- /* @__PURE__ */ jsx15("div", { className: "mt-3 flex flex-wrap gap-2", children: metaBadges.map((label) => renderMetaBadge(label, isUser)) }),
2508
- /* @__PURE__ */ jsx15("div", { className: "mt-2", children: renderMimeType(file.mimeType, isUser) })
2670
+ /* @__PURE__ */ jsx16("div", { className: "mt-3 flex flex-wrap gap-2", children: metaBadges.map((label) => renderMetaBadge(label, isUser)) }),
2671
+ /* @__PURE__ */ jsx16("div", { className: "mt-2", children: renderMimeType(file.mimeType, isUser) })
2509
2672
  ] })
2510
2673
  ] });
2511
2674
  if (!isInteractive) {
2512
- return /* @__PURE__ */ jsx15("div", { className: shellClasses, children: content });
2675
+ return /* @__PURE__ */ jsx16("div", { className: shellClasses, children: content });
2513
2676
  }
2514
- return /* @__PURE__ */ jsx15(
2677
+ return /* @__PURE__ */ jsx16(
2515
2678
  "a",
2516
2679
  {
2517
2680
  href: file.dataUrl,
@@ -2560,13 +2723,13 @@ function useReasoningBlockOpenState(params) {
2560
2723
  }
2561
2724
 
2562
2725
  // src/components/chat/ui/chat-message-list/chat-reasoning-block.tsx
2563
- import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
2726
+ import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
2564
2727
  function ChatReasoningBlock({ label, text, isUser, isInProgress }) {
2565
2728
  const { isOpen, onSummaryClick } = useReasoningBlockOpenState({
2566
2729
  isInProgress
2567
2730
  });
2568
- return /* @__PURE__ */ jsxs9("details", { className: "mt-2", open: isOpen, children: [
2569
- /* @__PURE__ */ jsx16(
2731
+ return /* @__PURE__ */ jsxs10("details", { className: "mt-2", open: isOpen, children: [
2732
+ /* @__PURE__ */ jsx17(
2570
2733
  "summary",
2571
2734
  {
2572
2735
  className: cn("cursor-pointer text-xs", isUser ? "text-primary-100" : "text-gray-500"),
@@ -2574,7 +2737,7 @@ function ChatReasoningBlock({ label, text, isUser, isInProgress }) {
2574
2737
  children: label
2575
2738
  }
2576
2739
  ),
2577
- /* @__PURE__ */ jsx16(
2740
+ /* @__PURE__ */ jsx17(
2578
2741
  "pre",
2579
2742
  {
2580
2743
  className: cn(
@@ -2592,9 +2755,9 @@ import { Terminal, FileText, Code2, Search as Search2, Globe } from "lucide-reac
2592
2755
  import { useState as useState7, useEffect as useEffect7, useRef as useRef6 } from "react";
2593
2756
 
2594
2757
  // src/components/chat/ui/chat-message-list/tool-card/tool-card-root.tsx
2595
- import { jsx as jsx17 } from "react/jsx-runtime";
2758
+ import { jsx as jsx18 } from "react/jsx-runtime";
2596
2759
  function ToolCardRoot({ children, className }) {
2597
- return /* @__PURE__ */ jsx17(
2760
+ return /* @__PURE__ */ jsx18(
2598
2761
  "div",
2599
2762
  {
2600
2763
  className: cn(
@@ -2607,7 +2770,7 @@ function ToolCardRoot({ children, className }) {
2607
2770
  );
2608
2771
  }
2609
2772
  function ToolCardContent({ children, className }) {
2610
- return /* @__PURE__ */ jsx17("div", { className: cn("border-t border-amber-200/15 bg-amber-50/50 px-3 pt-1 pb-2 w-full overflow-hidden", className), children });
2773
+ return /* @__PURE__ */ jsx18("div", { className: cn("border-t border-amber-200/15 bg-amber-50/50 px-3 pt-1 pb-2 w-full overflow-hidden", className), children });
2611
2774
  }
2612
2775
 
2613
2776
  // src/components/chat/ui/chat-message-list/tool-card/tool-card-header.tsx
@@ -2615,7 +2778,7 @@ import { ChevronDown as ChevronDown2, ChevronRight } from "lucide-react";
2615
2778
 
2616
2779
  // src/components/chat/ui/chat-message-list/tool-card/tool-card-status.tsx
2617
2780
  import { Check as Check4, Loader2, AlertTriangle, Minus } from "lucide-react";
2618
- import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
2781
+ import { jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
2619
2782
  var STATUS_STYLES = {
2620
2783
  running: { text: "text-amber-500/80", icon: Loader2, spin: true },
2621
2784
  success: { text: "text-amber-500/80", icon: Check4, spin: false },
@@ -2625,14 +2788,14 @@ var STATUS_STYLES = {
2625
2788
  function ToolStatusLabel({ card }) {
2626
2789
  const style = STATUS_STYLES[card.statusTone] || STATUS_STYLES.cancelled;
2627
2790
  const Icon2 = style.icon;
2628
- return /* @__PURE__ */ jsxs10("span", { className: cn("inline-flex items-center gap-1.5 text-[11px] font-medium leading-none shrink-0", style.text), children: [
2629
- /* @__PURE__ */ jsx18(Icon2, { className: cn("h-3.5 w-3.5", style.spin && "animate-spin"), strokeWidth: 3 }),
2791
+ return /* @__PURE__ */ jsxs11("span", { className: cn("inline-flex items-center gap-1.5 text-[11px] font-medium leading-none shrink-0", style.text), children: [
2792
+ /* @__PURE__ */ jsx19(Icon2, { className: cn("h-3.5 w-3.5", style.spin && "animate-spin"), strokeWidth: 3 }),
2630
2793
  card.statusTone === "running" ? card.statusLabel : null
2631
2794
  ] });
2632
2795
  }
2633
2796
 
2634
2797
  // src/components/chat/ui/chat-message-list/tool-card/tool-card-header.tsx
2635
- import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
2798
+ import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
2636
2799
  function ToolCardHeader({
2637
2800
  card,
2638
2801
  icon: Icon2,
@@ -2641,7 +2804,7 @@ function ToolCardHeader({
2641
2804
  onToggle
2642
2805
  }) {
2643
2806
  const summaryPart = card.summary?.replace(/^(command|path|args|query|input):\s*/i, "");
2644
- return /* @__PURE__ */ jsxs11(
2807
+ return /* @__PURE__ */ jsxs12(
2645
2808
  "div",
2646
2809
  {
2647
2810
  className: cn(
@@ -2650,19 +2813,19 @@ function ToolCardHeader({
2650
2813
  ),
2651
2814
  onClick: onToggle,
2652
2815
  children: [
2653
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 font-mono min-w-0 max-w-[calc(100%-80px)] text-amber-950/80", children: [
2654
- /* @__PURE__ */ jsx19(Icon2, { className: "h-4 w-4 text-amber-600/80 shrink-0", strokeWidth: 3 }),
2655
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1.5 min-w-0", children: [
2656
- /* @__PURE__ */ jsx19("span", { className: "font-bold shrink-0 tracking-tight", children: card.toolName }),
2657
- summaryPart && /* @__PURE__ */ jsxs11(Fragment2, { children: [
2658
- /* @__PURE__ */ jsx19("span", { className: "text-amber-300 font-bold select-none shrink-0", children: "\u203A" }),
2659
- /* @__PURE__ */ jsx19("span", { className: "truncate flex-1 min-w-0 font-normal", title: summaryPart, children: summaryPart })
2816
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 font-mono min-w-0 max-w-[calc(100%-80px)] text-amber-950/80", children: [
2817
+ /* @__PURE__ */ jsx20(Icon2, { className: "h-4 w-4 text-amber-600/80 shrink-0", strokeWidth: 3 }),
2818
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-1.5 min-w-0", children: [
2819
+ /* @__PURE__ */ jsx20("span", { className: "font-bold shrink-0 tracking-tight", children: card.toolName }),
2820
+ summaryPart && /* @__PURE__ */ jsxs12(Fragment3, { children: [
2821
+ /* @__PURE__ */ jsx20("span", { className: "text-amber-300 font-bold select-none shrink-0", children: "\u203A" }),
2822
+ /* @__PURE__ */ jsx20("span", { className: "truncate flex-1 min-w-0 font-normal", title: summaryPart, children: summaryPart })
2660
2823
  ] })
2661
2824
  ] })
2662
2825
  ] }),
2663
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-3 shrink-0", children: [
2664
- /* @__PURE__ */ jsx19(ToolStatusLabel, { card }),
2665
- canExpand && (expanded ? /* @__PURE__ */ jsx19(ChevronDown2, { className: "h-4 w-4 text-amber-400/80", strokeWidth: 3 }) : /* @__PURE__ */ jsx19(ChevronRight, { className: "h-4 w-4 text-amber-400/80", strokeWidth: 3 }))
2826
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-3 shrink-0", children: [
2827
+ /* @__PURE__ */ jsx20(ToolStatusLabel, { card }),
2828
+ canExpand && (expanded ? /* @__PURE__ */ jsx20(ChevronDown2, { className: "h-4 w-4 text-amber-400/80", strokeWidth: 3 }) : /* @__PURE__ */ jsx20(ChevronRight, { className: "h-4 w-4 text-amber-400/80", strokeWidth: 3 }))
2666
2829
  ] })
2667
2830
  ]
2668
2831
  }
@@ -2670,7 +2833,7 @@ function ToolCardHeader({
2670
2833
  }
2671
2834
 
2672
2835
  // src/components/chat/ui/chat-message-list/tool-card/tool-card-views.tsx
2673
- import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
2836
+ import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
2674
2837
  function TerminalExecutionView({ card }) {
2675
2838
  const output = card.output?.trim() ?? "";
2676
2839
  const isRunning = card.statusTone === "running";
@@ -2697,8 +2860,8 @@ function TerminalExecutionView({ card }) {
2697
2860
  setHasUserToggled(true);
2698
2861
  };
2699
2862
  const commandPart = card.summary?.replace(/^(command|path|args|query|input):\s*/i, "");
2700
- return /* @__PURE__ */ jsxs12(ToolCardRoot, { children: [
2701
- /* @__PURE__ */ jsx20(
2863
+ return /* @__PURE__ */ jsxs13(ToolCardRoot, { children: [
2864
+ /* @__PURE__ */ jsx21(
2702
2865
  ToolCardHeader,
2703
2866
  {
2704
2867
  card,
@@ -2708,17 +2871,17 @@ function TerminalExecutionView({ card }) {
2708
2871
  onToggle
2709
2872
  }
2710
2873
  ),
2711
- expanded && /* @__PURE__ */ jsxs12(Fragment3, { children: [
2712
- /* @__PURE__ */ jsx20("div", { className: "px-3 pb-2 font-mono w-full max-h-48 overflow-y-auto custom-scrollbar-amber min-h-0 text-[12px]", children: /* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-2 leading-relaxed", children: [
2713
- /* @__PURE__ */ jsx20("span", { className: "text-amber-500/50 font-medium shrink-0 select-none mt-[1px]", children: "$" }),
2714
- /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", children: commandPart ? /* @__PURE__ */ jsxs12("div", { className: "text-amber-950/80 break-words whitespace-pre-wrap tracking-tight font-medium inline-block", children: [
2874
+ expanded && /* @__PURE__ */ jsxs13(Fragment4, { children: [
2875
+ /* @__PURE__ */ jsx21("div", { className: "px-3 pb-2 font-mono w-full max-h-48 overflow-y-auto custom-scrollbar-amber min-h-0 text-[12px]", children: /* @__PURE__ */ jsxs13("div", { className: "flex items-start gap-2 leading-relaxed", children: [
2876
+ /* @__PURE__ */ jsx21("span", { className: "text-amber-500/50 font-medium shrink-0 select-none mt-[1px]", children: "$" }),
2877
+ /* @__PURE__ */ jsx21("div", { className: "flex-1 min-w-0", children: commandPart ? /* @__PURE__ */ jsxs13("div", { className: "text-amber-950/80 break-words whitespace-pre-wrap tracking-tight font-medium inline-block", children: [
2715
2878
  commandPart,
2716
- isRunning && !output && /* @__PURE__ */ jsx20("span", { className: "inline-block w-1.5 h-3 ml-1 bg-amber-500/60 animate-pulse align-middle" })
2717
- ] }) : /* @__PURE__ */ jsx20("div", { className: "h-3 w-32 bg-amber-200/30 rounded animate-pulse mt-2" }) })
2879
+ isRunning && !output && /* @__PURE__ */ jsx21("span", { className: "inline-block w-1.5 h-3 ml-1 bg-amber-500/60 animate-pulse align-middle" })
2880
+ ] }) : /* @__PURE__ */ jsx21("div", { className: "h-3 w-32 bg-amber-200/30 rounded animate-pulse mt-2" }) })
2718
2881
  ] }) }),
2719
- output && /* @__PURE__ */ jsx20(ToolCardContent, { children: /* @__PURE__ */ jsxs12("pre", { 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", children: [
2882
+ output && /* @__PURE__ */ jsx21(ToolCardContent, { children: /* @__PURE__ */ jsxs13("pre", { 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", children: [
2720
2883
  output,
2721
- isRunning && /* @__PURE__ */ jsx20("span", { className: "inline-block w-1.5 h-3 ml-1 bg-amber-500/60 animate-pulse align-middle" })
2884
+ isRunning && /* @__PURE__ */ jsx21("span", { className: "inline-block w-1.5 h-3 ml-1 bg-amber-500/60 animate-pulse align-middle" })
2722
2885
  ] }) })
2723
2886
  ] })
2724
2887
  ] });
@@ -2744,26 +2907,26 @@ function FileOperationView({ card }) {
2744
2907
  const renderLine = (line, idx) => {
2745
2908
  if (isEdit) {
2746
2909
  if (line.startsWith("+") && !line.startsWith("+++")) {
2747
- return /* @__PURE__ */ jsxs12("div", { className: "bg-emerald-500/10 text-emerald-700 px-2 py-0.5 w-full break-all whitespace-pre-wrap", children: [
2748
- /* @__PURE__ */ jsx20("span", { className: "select-none opacity-40 mr-2 w-3 inline-block shrink-0", children: "+" }),
2749
- /* @__PURE__ */ jsx20("span", { children: line.slice(1) })
2910
+ return /* @__PURE__ */ jsxs13("div", { className: "bg-emerald-500/10 text-emerald-700 px-2 py-0.5 w-full break-all whitespace-pre-wrap", children: [
2911
+ /* @__PURE__ */ jsx21("span", { className: "select-none opacity-40 mr-2 w-3 inline-block shrink-0", children: "+" }),
2912
+ /* @__PURE__ */ jsx21("span", { children: line.slice(1) })
2750
2913
  ] }, idx);
2751
2914
  }
2752
2915
  if (line.startsWith("-") && !line.startsWith("---")) {
2753
- return /* @__PURE__ */ jsxs12("div", { className: "bg-rose-500/10 text-rose-700 px-2 py-0.5 w-full break-all whitespace-pre-wrap", children: [
2754
- /* @__PURE__ */ jsx20("span", { className: "select-none opacity-40 mr-2 w-3 inline-block shrink-0", children: "-" }),
2755
- /* @__PURE__ */ jsx20("span", { className: "line-through decoration-rose-400/50", children: line.slice(1) })
2916
+ return /* @__PURE__ */ jsxs13("div", { className: "bg-rose-500/10 text-rose-700 px-2 py-0.5 w-full break-all whitespace-pre-wrap", children: [
2917
+ /* @__PURE__ */ jsx21("span", { className: "select-none opacity-40 mr-2 w-3 inline-block shrink-0", children: "-" }),
2918
+ /* @__PURE__ */ jsx21("span", { className: "line-through decoration-rose-400/50", children: line.slice(1) })
2756
2919
  ] }, idx);
2757
2920
  }
2758
2921
  }
2759
- return /* @__PURE__ */ jsx20("div", { className: "py-0.5 text-amber-950/80 w-full break-all whitespace-pre-wrap", children: /* @__PURE__ */ jsx20("span", { children: line }) }, idx);
2922
+ return /* @__PURE__ */ jsx21("div", { className: "py-0.5 text-amber-950/80 w-full break-all whitespace-pre-wrap", children: /* @__PURE__ */ jsx21("span", { children: line }) }, idx);
2760
2923
  };
2761
2924
  const lines = output.split("\n");
2762
2925
  const maxLines = 15;
2763
2926
  const isLong = lines.length > maxLines;
2764
2927
  const displayLines = !expanded && isLong ? lines.slice(0, maxLines) : lines;
2765
- return /* @__PURE__ */ jsxs12(ToolCardRoot, { children: [
2766
- /* @__PURE__ */ jsx20(
2928
+ return /* @__PURE__ */ jsxs13(ToolCardRoot, { children: [
2929
+ /* @__PURE__ */ jsx21(
2767
2930
  ToolCardHeader,
2768
2931
  {
2769
2932
  card,
@@ -2773,7 +2936,7 @@ function FileOperationView({ card }) {
2773
2936
  onToggle
2774
2937
  }
2775
2938
  ),
2776
- expanded && output && /* @__PURE__ */ jsx20(ToolCardContent, { children: /* @__PURE__ */ jsx20("div", { className: "font-mono text-[12px] leading-relaxed max-h-48 overflow-y-auto overflow-x-hidden min-w-0 custom-scrollbar-amber text-amber-950/80 w-full", children: displayLines.map(renderLine) }) })
2939
+ expanded && output && /* @__PURE__ */ jsx21(ToolCardContent, { children: /* @__PURE__ */ jsx21("div", { className: "font-mono text-[12px] leading-relaxed max-h-48 overflow-y-auto overflow-x-hidden min-w-0 custom-scrollbar-amber text-amber-950/80 w-full", children: displayLines.map(renderLine) }) })
2777
2940
  ] });
2778
2941
  }
2779
2942
  function SearchSnippetView({ card }) {
@@ -2793,8 +2956,8 @@ function SearchSnippetView({ card }) {
2793
2956
  setExpanded(!expanded);
2794
2957
  setHasUserToggled(true);
2795
2958
  };
2796
- return /* @__PURE__ */ jsxs12(ToolCardRoot, { children: [
2797
- /* @__PURE__ */ jsx20(
2959
+ return /* @__PURE__ */ jsxs13(ToolCardRoot, { children: [
2960
+ /* @__PURE__ */ jsx21(
2798
2961
  ToolCardHeader,
2799
2962
  {
2800
2963
  card,
@@ -2804,7 +2967,7 @@ function SearchSnippetView({ card }) {
2804
2967
  onToggle
2805
2968
  }
2806
2969
  ),
2807
- expanded && output && /* @__PURE__ */ jsx20(ToolCardContent, { children: /* @__PURE__ */ jsx20("pre", { 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", children: output }) })
2970
+ expanded && output && /* @__PURE__ */ jsx21(ToolCardContent, { children: /* @__PURE__ */ jsx21("pre", { 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", children: output }) })
2808
2971
  ] });
2809
2972
  }
2810
2973
  function GenericToolCard({ card }) {
@@ -2825,8 +2988,8 @@ function GenericToolCard({ card }) {
2825
2988
  setExpanded(!expanded);
2826
2989
  setHasUserToggled(true);
2827
2990
  };
2828
- return /* @__PURE__ */ jsxs12(ToolCardRoot, { children: [
2829
- /* @__PURE__ */ jsx20(
2991
+ return /* @__PURE__ */ jsxs13(ToolCardRoot, { children: [
2992
+ /* @__PURE__ */ jsx21(
2830
2993
  ToolCardHeader,
2831
2994
  {
2832
2995
  card,
@@ -2836,12 +2999,12 @@ function GenericToolCard({ card }) {
2836
2999
  onToggle
2837
3000
  }
2838
3001
  ),
2839
- expanded && output && /* @__PURE__ */ jsx20(ToolCardContent, { children: /* @__PURE__ */ jsx20("pre", { className: "text-amber-950/80 whitespace-pre-wrap break-all overflow-y-auto overflow-x-hidden max-h-64 custom-scrollbar-amber w-full min-w-0 max-w-full leading-relaxed", children: output }) })
3002
+ expanded && output && /* @__PURE__ */ jsx21(ToolCardContent, { children: /* @__PURE__ */ jsx21("pre", { className: "text-amber-950/80 whitespace-pre-wrap break-all overflow-y-auto overflow-x-hidden max-h-64 custom-scrollbar-amber w-full min-w-0 max-w-full leading-relaxed", children: output }) })
2840
3003
  ] });
2841
3004
  }
2842
3005
 
2843
3006
  // src/components/chat/ui/chat-message-list/chat-tool-card.tsx
2844
- import { jsx as jsx21 } from "react/jsx-runtime";
3007
+ import { jsx as jsx22 } from "react/jsx-runtime";
2845
3008
  function isTerminalTool(name) {
2846
3009
  const lowered = name.toLowerCase();
2847
3010
  return lowered === "exec" || lowered === "execute_command" || lowered === "bash" || lowered === "shell" || lowered.includes("run_");
@@ -2856,47 +3019,48 @@ function isSearchTool(name) {
2856
3019
  }
2857
3020
  function ChatToolCard({ card }) {
2858
3021
  if (isTerminalTool(card.toolName)) {
2859
- return /* @__PURE__ */ jsx21(TerminalExecutionView, { card });
3022
+ return /* @__PURE__ */ jsx22(TerminalExecutionView, { card });
2860
3023
  }
2861
3024
  if (isFileEditTool(card.toolName)) {
2862
- return /* @__PURE__ */ jsx21(FileOperationView, { card });
3025
+ return /* @__PURE__ */ jsx22(FileOperationView, { card });
2863
3026
  }
2864
3027
  if (isSearchTool(card.toolName)) {
2865
- return /* @__PURE__ */ jsx21(SearchSnippetView, { card });
3028
+ return /* @__PURE__ */ jsx22(SearchSnippetView, { card });
2866
3029
  }
2867
- return /* @__PURE__ */ jsx21(GenericToolCard, { card });
3030
+ return /* @__PURE__ */ jsx22(GenericToolCard, { card });
2868
3031
  }
2869
3032
 
2870
3033
  // src/components/chat/ui/chat-message-list/chat-unknown-part.tsx
2871
- import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
3034
+ import { jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
2872
3035
  function ChatUnknownPart(props) {
2873
- return /* @__PURE__ */ jsxs13("div", { className: "rounded-lg border border-gray-200 bg-gray-50 px-2.5 py-2 text-xs text-gray-600", children: [
2874
- /* @__PURE__ */ jsxs13("div", { className: "font-semibold text-gray-700", children: [
3036
+ return /* @__PURE__ */ jsxs14("div", { className: "rounded-lg border border-gray-200 bg-gray-50 px-2.5 py-2 text-xs text-gray-600", children: [
3037
+ /* @__PURE__ */ jsxs14("div", { className: "font-semibold text-gray-700", children: [
2875
3038
  props.label,
2876
3039
  ": ",
2877
3040
  props.rawType
2878
3041
  ] }),
2879
- props.text ? /* @__PURE__ */ jsx22("pre", { className: "mt-1 whitespace-pre-wrap break-words text-[11px] text-gray-500", children: props.text }) : null
3042
+ props.text ? /* @__PURE__ */ jsx23("pre", { className: "mt-1 whitespace-pre-wrap break-words text-[11px] text-gray-500", children: props.text }) : null
2880
3043
  ] });
2881
3044
  }
2882
3045
 
2883
3046
  // src/components/chat/ui/chat-message-list/chat-message.tsx
2884
- import { jsx as jsx23 } from "react/jsx-runtime";
3047
+ import { jsx as jsx24 } from "react/jsx-runtime";
2885
3048
  var ChatMessage = memo(function ChatMessage2(props) {
2886
3049
  const { message, texts } = props;
2887
3050
  const { role } = message;
2888
3051
  const isUser = role === "user";
2889
3052
  const isMessageInProgress = message.status === "pending" || message.status === "streaming";
2890
- return /* @__PURE__ */ jsx23(
3053
+ return /* @__PURE__ */ jsx24(
2891
3054
  "div",
2892
3055
  {
2893
3056
  className: cn(
2894
3057
  "inline-block w-fit max-w-full rounded-2xl border px-4 shadow-sm",
2895
3058
  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"
2896
3059
  ),
2897
- children: /* @__PURE__ */ jsx23("div", { className: "space-y-2", children: message.parts.map((part, index) => {
2898
- if (part.type === "markdown") {
2899
- return /* @__PURE__ */ jsx23(
3060
+ children: /* @__PURE__ */ jsx24("div", { className: "space-y-2", children: message.parts.map((part, index) => {
3061
+ const { type } = part;
3062
+ if (type === "markdown") {
3063
+ return /* @__PURE__ */ jsx24(
2900
3064
  ChatMessageMarkdown,
2901
3065
  {
2902
3066
  text: part.text,
@@ -2906,8 +3070,19 @@ var ChatMessage = memo(function ChatMessage2(props) {
2906
3070
  `markdown-${index}`
2907
3071
  );
2908
3072
  }
2909
- if (part.type === "reasoning") {
2910
- return /* @__PURE__ */ jsx23(
3073
+ if (type === "inline-content") {
3074
+ return /* @__PURE__ */ jsx24(
3075
+ ChatMessageInlineContent,
3076
+ {
3077
+ segments: part.segments,
3078
+ role,
3079
+ texts
3080
+ },
3081
+ `inline-content-${index}`
3082
+ );
3083
+ }
3084
+ if (type === "reasoning") {
3085
+ return /* @__PURE__ */ jsx24(
2911
3086
  ChatReasoningBlock,
2912
3087
  {
2913
3088
  label: part.label,
@@ -2918,11 +3093,11 @@ var ChatMessage = memo(function ChatMessage2(props) {
2918
3093
  `reasoning-${index}`
2919
3094
  );
2920
3095
  }
2921
- if (part.type === "tool-card") {
2922
- return /* @__PURE__ */ jsx23("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx23(ChatToolCard, { card: part.card }) }, `tool-${index}`);
3096
+ if (type === "tool-card") {
3097
+ return /* @__PURE__ */ jsx24("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx24(ChatToolCard, { card: part.card }) }, `tool-${index}`);
2923
3098
  }
2924
- if (part.type === "file") {
2925
- return /* @__PURE__ */ jsx23(
3099
+ if (type === "file") {
3100
+ return /* @__PURE__ */ jsx24(
2926
3101
  ChatMessageFile,
2927
3102
  {
2928
3103
  file: part.file,
@@ -2931,8 +3106,8 @@ var ChatMessage = memo(function ChatMessage2(props) {
2931
3106
  `file-${index}`
2932
3107
  );
2933
3108
  }
2934
- if (part.type === "unknown") {
2935
- return /* @__PURE__ */ jsx23(
3109
+ if (type === "unknown") {
3110
+ return /* @__PURE__ */ jsx24(
2936
3111
  ChatUnknownPart,
2937
3112
  {
2938
3113
  label: part.label,
@@ -2949,9 +3124,9 @@ var ChatMessage = memo(function ChatMessage2(props) {
2949
3124
  });
2950
3125
 
2951
3126
  // src/components/chat/ui/chat-message-list/chat-message-meta.tsx
2952
- import { jsxs as jsxs14 } from "react/jsx-runtime";
3127
+ import { jsxs as jsxs15 } from "react/jsx-runtime";
2953
3128
  function ChatMessageMeta(props) {
2954
- return /* @__PURE__ */ jsxs14(
3129
+ return /* @__PURE__ */ jsxs15(
2955
3130
  "div",
2956
3131
  {
2957
3132
  className: cn(
@@ -2970,7 +3145,7 @@ function ChatMessageMeta(props) {
2970
3145
  // src/components/chat/ui/chat-message-list/chat-message-action-copy.tsx
2971
3146
  import { useMemo as useMemo6 } from "react";
2972
3147
  import { Check as Check5, Copy as Copy2 } from "lucide-react";
2973
- import { jsx as jsx24 } from "react/jsx-runtime";
3148
+ import { jsx as jsx25 } from "react/jsx-runtime";
2974
3149
  function ChatMessageActionCopy({
2975
3150
  message,
2976
3151
  texts
@@ -2984,7 +3159,7 @@ function ChatMessageActionCopy({
2984
3159
  }, [message.parts]);
2985
3160
  const { copied, copy } = useCopyFeedback({ text: messageText });
2986
3161
  if (!messageText) return null;
2987
- return /* @__PURE__ */ jsx24(
3162
+ return /* @__PURE__ */ jsx25(
2988
3163
  "button",
2989
3164
  {
2990
3165
  type: "button",
@@ -2992,13 +3167,13 @@ function ChatMessageActionCopy({
2992
3167
  className: "text-gray-400 hover:text-gray-600 transition-colors p-1 rounded-md hover:bg-gray-100 flex items-center justify-center",
2993
3168
  "aria-label": copied ? texts.copiedMessageLabel : texts.copyMessageLabel,
2994
3169
  title: copied ? texts.copiedMessageLabel : texts.copyMessageLabel,
2995
- children: copied ? /* @__PURE__ */ jsx24(Check5, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx24(Copy2, { className: "h-3.5 w-3.5" })
3170
+ children: copied ? /* @__PURE__ */ jsx25(Check5, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx25(Copy2, { className: "h-3.5 w-3.5" })
2996
3171
  }
2997
3172
  );
2998
3173
  }
2999
3174
 
3000
3175
  // src/components/chat/ui/chat-message-list/chat-message-list.tsx
3001
- import { Fragment as Fragment4, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
3176
+ import { Fragment as Fragment5, jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
3002
3177
  var INVISIBLE_ONLY_TEXT_PATTERN = /\u200B|\u200C|\u200D|\u2060|\uFEFF/g;
3003
3178
  function hasRenderableText(value) {
3004
3179
  const trimmed = value.trim();
@@ -3016,10 +3191,10 @@ function hasRenderableMessageContent(message) {
3016
3191
  });
3017
3192
  }
3018
3193
  function ChatMessageTypingFooter() {
3019
- return /* @__PURE__ */ jsx25("div", { className: "flex items-center gap-2 px-1 py-0.5 text-[11px] text-gray-400", children: /* @__PURE__ */ jsxs15("div", { className: "flex space-x-1 items-center h-full", children: [
3020
- /* @__PURE__ */ jsx25("div", { className: "h-1.5 w-1.5 rounded-full bg-gray-400 animate-pulse" }),
3021
- /* @__PURE__ */ jsx25("div", { className: "h-1.5 w-1.5 rounded-full bg-gray-400 animate-pulse [animation-delay:200ms]" }),
3022
- /* @__PURE__ */ jsx25("div", { className: "h-1.5 w-1.5 rounded-full bg-gray-400 animate-pulse [animation-delay:400ms]" })
3194
+ return /* @__PURE__ */ jsx26("div", { className: "flex items-center gap-2 px-1 py-0.5 text-[11px] text-gray-400", children: /* @__PURE__ */ jsxs16("div", { className: "flex space-x-1 items-center h-full", children: [
3195
+ /* @__PURE__ */ jsx26("div", { className: "h-1.5 w-1.5 rounded-full bg-gray-400 animate-pulse" }),
3196
+ /* @__PURE__ */ jsx26("div", { className: "h-1.5 w-1.5 rounded-full bg-gray-400 animate-pulse [animation-delay:200ms]" }),
3197
+ /* @__PURE__ */ jsx26("div", { className: "h-1.5 w-1.5 rounded-full bg-gray-400 animate-pulse [animation-delay:400ms]" })
3023
3198
  ] }) });
3024
3199
  }
3025
3200
  function ChatMessageList(props) {
@@ -3027,25 +3202,25 @@ function ChatMessageList(props) {
3027
3202
  const hasRenderableAssistantDraft = visibleMessages.some(
3028
3203
  (message) => message.role === "assistant" && (message.status === "streaming" || message.status === "pending")
3029
3204
  );
3030
- return /* @__PURE__ */ jsxs15("div", { className: cn("space-y-5", props.className), children: [
3205
+ return /* @__PURE__ */ jsxs16("div", { className: cn("space-y-5", props.className), children: [
3031
3206
  visibleMessages.map((message) => {
3032
3207
  const isUser = message.role === "user";
3033
3208
  const isGenerating = !isUser && (message.status === "streaming" || message.status === "pending");
3034
- return /* @__PURE__ */ jsxs15("div", { className: cn("flex gap-3", isUser ? "justify-end" : "justify-start"), children: [
3035
- !isUser ? /* @__PURE__ */ jsx25(ChatMessageAvatar, { role: message.role }) : null,
3036
- /* @__PURE__ */ jsxs15("div", { className: cn("w-fit max-w-[92%] space-y-2", isUser && "flex flex-col items-end"), children: [
3037
- /* @__PURE__ */ jsx25(ChatMessage, { message, texts: props.texts }),
3038
- /* @__PURE__ */ jsx25("div", { className: cn("flex items-center gap-2", isUser && "justify-end"), children: isGenerating ? /* @__PURE__ */ jsx25(ChatMessageTypingFooter, {}) : /* @__PURE__ */ jsxs15(Fragment4, { children: [
3039
- /* @__PURE__ */ jsx25(ChatMessageMeta, { roleLabel: message.roleLabel, timestampLabel: message.timestampLabel, isUser }),
3040
- !isUser ? /* @__PURE__ */ jsx25(ChatMessageActionCopy, { message, texts: props.texts }) : null
3209
+ return /* @__PURE__ */ jsxs16("div", { className: cn("flex gap-3", isUser ? "justify-end" : "justify-start"), children: [
3210
+ !isUser ? /* @__PURE__ */ jsx26(ChatMessageAvatar, { role: message.role }) : null,
3211
+ /* @__PURE__ */ jsxs16("div", { className: cn("w-fit max-w-[92%] space-y-2", isUser && "flex flex-col items-end"), children: [
3212
+ /* @__PURE__ */ jsx26(ChatMessage, { message, texts: props.texts }),
3213
+ /* @__PURE__ */ jsx26("div", { className: cn("flex items-center gap-2", isUser && "justify-end"), children: isGenerating ? /* @__PURE__ */ jsx26(ChatMessageTypingFooter, {}) : /* @__PURE__ */ jsxs16(Fragment5, { children: [
3214
+ /* @__PURE__ */ jsx26(ChatMessageMeta, { roleLabel: message.roleLabel, timestampLabel: message.timestampLabel, isUser }),
3215
+ !isUser ? /* @__PURE__ */ jsx26(ChatMessageActionCopy, { message, texts: props.texts }) : null
3041
3216
  ] }) })
3042
3217
  ] }),
3043
- isUser ? /* @__PURE__ */ jsx25(ChatMessageAvatar, { role: message.role }) : null
3218
+ isUser ? /* @__PURE__ */ jsx26(ChatMessageAvatar, { role: message.role }) : null
3044
3219
  ] }, message.id);
3045
3220
  }),
3046
- props.isSending && !hasRenderableAssistantDraft ? /* @__PURE__ */ jsxs15("div", { className: "flex justify-start gap-3", children: [
3047
- /* @__PURE__ */ jsx25(ChatMessageAvatar, { role: "assistant" }),
3048
- /* @__PURE__ */ jsx25("div", { className: "rounded-2xl border border-gray-200 bg-white px-4 py-3 text-sm text-gray-500 shadow-sm", children: props.texts.typingLabel })
3221
+ props.isSending && !hasRenderableAssistantDraft ? /* @__PURE__ */ jsxs16("div", { className: "flex justify-start gap-3", children: [
3222
+ /* @__PURE__ */ jsx26(ChatMessageAvatar, { role: "assistant" }),
3223
+ /* @__PURE__ */ jsx26("div", { className: "rounded-2xl border border-gray-200 bg-white px-4 py-3 text-sm text-gray-500 shadow-sm", children: props.texts.typingLabel })
3049
3224
  ] }) : null
3050
3225
  ] });
3051
3226
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/agent-chat-ui",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
4
4
  "private": false,
5
5
  "description": "Reusable Nextclaw agent chat UI primitives and default skin.",
6
6
  "type": "module",