@nextclaw/agent-chat-ui 0.2.20 → 0.2.21

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
@@ -166,6 +166,13 @@ type ChatFileOperationBlockViewModel = {
166
166
  rawText?: string;
167
167
  truncated?: boolean;
168
168
  };
169
+ type ChatToolActionViewModel = {
170
+ kind: "open-session";
171
+ sessionId: string;
172
+ sessionKind: "child" | "session";
173
+ label?: string;
174
+ parentSessionId?: string;
175
+ };
169
176
  type ChatToolPartViewModel = {
170
177
  kind: "call" | "result";
171
178
  toolName: string;
@@ -180,6 +187,7 @@ type ChatToolPartViewModel = {
180
187
  titleLabel: string;
181
188
  outputLabel: string;
182
189
  emptyLabel: string;
190
+ action?: ChatToolActionViewModel;
183
191
  fileOperation?: {
184
192
  blocks: ChatFileOperationBlockViewModel[];
185
193
  };
@@ -246,6 +254,7 @@ type ChatMessageListProps = {
246
254
  hasAssistantDraft: boolean;
247
255
  texts: ChatMessageTexts;
248
256
  className?: string;
257
+ onToolAction?: (action: ChatToolActionViewModel) => void;
249
258
  };
250
259
 
251
260
  type ChatInputBarHandle = {
@@ -320,4 +329,4 @@ declare function resolveChatComposerSlashTrigger(nodes: ChatComposerNode[], sele
320
329
  end: number;
321
330
  } | null;
322
331
 
323
- export { type ChatComposerNode, type ChatComposerSelection, type ChatComposerTextNode, type ChatComposerTokenKind, type ChatComposerTokenNode, type ChatFileOperationBlockViewModel, type ChatFileOperationLineViewModel, 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 };
332
+ export { type ChatComposerNode, type ChatComposerSelection, type ChatComposerTextNode, type ChatComposerTokenKind, type ChatComposerTokenNode, type ChatFileOperationBlockViewModel, type ChatFileOperationLineViewModel, 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 ChatToolActionViewModel, 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
@@ -290,13 +290,20 @@ function ChatSlashMenu(props) {
290
290
  ] })
291
291
  }
292
292
  ),
293
- /* @__PURE__ */ jsx5("div", { className: "max-w-[320px] p-3.5", children: activeItem ? /* @__PURE__ */ jsxs2("div", { className: "space-y-3", children: [
293
+ /* @__PURE__ */ jsx5("div", { className: "min-w-0 p-2.5", children: activeItem ? /* @__PURE__ */ jsxs2("div", { className: "space-y-3", children: [
294
294
  /* @__PURE__ */ jsxs2("div", { className: "flex items-center gap-2", children: [
295
295
  /* @__PURE__ */ jsx5("span", { className: "inline-flex rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-semibold text-primary", children: activeItem.subtitle }),
296
296
  /* @__PURE__ */ jsx5("span", { className: "text-sm font-semibold text-gray-900", children: activeItem.title })
297
297
  ] }),
298
298
  /* @__PURE__ */ jsx5("p", { className: "text-xs leading-5 text-gray-600", children: activeItem.description }),
299
- /* @__PURE__ */ jsx5("div", { className: "space-y-1", children: activeItem.detailLines.map((line) => /* @__PURE__ */ jsx5("div", { className: "rounded-md bg-gray-50 px-2 py-1 text-[11px] text-gray-600", children: line }, line)) }),
299
+ /* @__PURE__ */ jsx5("div", { className: "space-y-1", children: activeItem.detailLines.map((line) => /* @__PURE__ */ jsx5(
300
+ "div",
301
+ {
302
+ className: "min-w-0 break-all rounded-md bg-gray-50 px-2 py-1 text-[11px] leading-5 text-gray-600",
303
+ children: line
304
+ },
305
+ line
306
+ )) }),
300
307
  /* @__PURE__ */ jsx5("div", { className: "pt-1 text-[11px] text-gray-500", children: texts.slashSkillHintLabel })
301
308
  ] }) : /* @__PURE__ */ jsx5("div", { className: "text-xs text-gray-500", children: texts.slashHintLabel }) })
302
309
  ] })
@@ -3497,7 +3504,10 @@ function SearchSnippetView({ card }) {
3497
3504
  expanded && output && /* @__PURE__ */ jsx23(ToolCardContent, { children: /* @__PURE__ */ jsx23("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 }) })
3498
3505
  ] });
3499
3506
  }
3500
- function GenericToolCard({ card }) {
3507
+ function GenericToolCard({
3508
+ card,
3509
+ onToolAction
3510
+ }) {
3501
3511
  const input = card.input?.trim() ?? "";
3502
3512
  const output = card.output?.trim() ?? "";
3503
3513
  const isRunning = card.statusTone === "running";
@@ -3532,7 +3542,16 @@ function GenericToolCard({ card }) {
3532
3542
  tone: card.statusTone === "error" ? "error" : "output",
3533
3543
  children: output
3534
3544
  }
3535
- )
3545
+ ),
3546
+ card.action && onToolAction ? /* @__PURE__ */ jsx23("div", { className: "pt-2", children: /* @__PURE__ */ jsx23(
3547
+ "button",
3548
+ {
3549
+ type: "button",
3550
+ onClick: () => onToolAction(card.action),
3551
+ className: "rounded-md border border-amber-300/70 bg-white/80 px-3 py-1.5 text-[11px] font-semibold text-amber-900 transition-colors hover:bg-amber-100/70",
3552
+ children: card.action.sessionKind === "child" ? "Open child session" : "Open session"
3553
+ }
3554
+ ) }) : null
3536
3555
  ] })
3537
3556
  ] });
3538
3557
  }
@@ -3551,7 +3570,10 @@ function isSearchTool(name) {
3551
3570
  const lowered = name.toLowerCase();
3552
3571
  return lowered === "grep_search" || lowered === "find_files" || lowered.includes("search");
3553
3572
  }
3554
- function ChatToolCard({ card }) {
3573
+ function ChatToolCard({
3574
+ card,
3575
+ onToolAction
3576
+ }) {
3555
3577
  if (isTerminalTool(card.toolName)) {
3556
3578
  return /* @__PURE__ */ jsx24(TerminalExecutionView, { card });
3557
3579
  }
@@ -3561,7 +3583,7 @@ function ChatToolCard({ card }) {
3561
3583
  if (isSearchTool(card.toolName)) {
3562
3584
  return /* @__PURE__ */ jsx24(SearchSnippetView, { card });
3563
3585
  }
3564
- return /* @__PURE__ */ jsx24(GenericToolCard, { card });
3586
+ return /* @__PURE__ */ jsx24(GenericToolCard, { card, onToolAction });
3565
3587
  }
3566
3588
 
3567
3589
  // src/components/chat/ui/chat-message-list/chat-unknown-part.tsx
@@ -3580,7 +3602,7 @@ function ChatUnknownPart(props) {
3580
3602
  // src/components/chat/ui/chat-message-list/chat-message.tsx
3581
3603
  import { jsx as jsx26 } from "react/jsx-runtime";
3582
3604
  var ChatMessage = memo(function ChatMessage2(props) {
3583
- const { message, texts } = props;
3605
+ const { message, texts, onToolAction } = props;
3584
3606
  const { role } = message;
3585
3607
  const isUser = role === "user";
3586
3608
  const isMessageInProgress = message.status === "pending" || message.status === "streaming";
@@ -3628,7 +3650,7 @@ var ChatMessage = memo(function ChatMessage2(props) {
3628
3650
  );
3629
3651
  }
3630
3652
  if (type === "tool-card") {
3631
- return /* @__PURE__ */ jsx26("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx26(ChatToolCard, { card: part.card }) }, `tool-${index}`);
3653
+ return /* @__PURE__ */ jsx26("div", { className: "mt-0.5", children: /* @__PURE__ */ jsx26(ChatToolCard, { card: part.card, onToolAction }) }, `tool-${index}`);
3632
3654
  }
3633
3655
  if (type === "file") {
3634
3656
  return /* @__PURE__ */ jsx26(
@@ -3743,7 +3765,14 @@ function ChatMessageList(props) {
3743
3765
  return /* @__PURE__ */ jsxs18("div", { className: cn("flex gap-3", isUser ? "justify-end" : "justify-start"), children: [
3744
3766
  !isUser ? /* @__PURE__ */ jsx28(ChatMessageAvatar, { role: message.role }) : null,
3745
3767
  /* @__PURE__ */ jsxs18("div", { className: cn("w-fit max-w-[92%] space-y-2", isUser && "flex flex-col items-end"), children: [
3746
- /* @__PURE__ */ jsx28(ChatMessage, { message, texts: props.texts }),
3768
+ /* @__PURE__ */ jsx28(
3769
+ ChatMessage,
3770
+ {
3771
+ message,
3772
+ texts: props.texts,
3773
+ onToolAction: props.onToolAction
3774
+ }
3775
+ ),
3747
3776
  /* @__PURE__ */ jsx28("div", { className: cn("flex items-center gap-2", isUser && "justify-end"), children: isGenerating ? /* @__PURE__ */ jsx28(ChatMessageTypingFooter, {}) : /* @__PURE__ */ jsxs18(Fragment6, { children: [
3748
3777
  /* @__PURE__ */ jsx28(ChatMessageMeta, { roleLabel: message.roleLabel, timestampLabel: message.timestampLabel, isUser }),
3749
3778
  !isUser ? /* @__PURE__ */ jsx28(ChatMessageActionCopy, { message, texts: props.texts }) : null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/agent-chat-ui",
3
- "version": "0.2.20",
3
+ "version": "0.2.21",
4
4
  "private": false,
5
5
  "description": "Reusable Nextclaw agent chat UI primitives and default skin.",
6
6
  "type": "module",