@nextclaw/agent-chat-ui 0.6.2 → 0.6.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.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["DefaultPopover","DefaultPopoverAnchor","DefaultPopoverContent","DefaultPopoverTrigger","DefaultInput","DefaultSelect","DefaultSelectContent","DefaultSelectGroup","DefaultSelectItem","DefaultSelectLabel","DefaultSelectSeparator","DefaultSelectTrigger","DefaultSelectValue","DefaultTooltip","DefaultTooltipContent","DefaultTooltipProvider","DefaultTooltipTrigger","CODE_LANGUAGE_REGEX","isRecord"],"sources":["../src/components/chat/ui/chat-input-bar/chat-composer.utils.ts","../src/components/chat/hooks/use-active-item-scroll.ts","../src/components/chat/hooks/use-element-width.ts","../src/components/chat/internal/cn.ts","../src/components/chat/default-skin/input.tsx","../src/components/chat/default-skin/popover.tsx","../src/components/chat/default-skin/select.tsx","../src/components/chat/default-skin/tooltip.tsx","../src/components/chat/ui/primitives/chat-ui-primitives.tsx","../src/components/chat/ui/input-surface/chat-input-surface-menu.tsx","../src/components/chat/ui/input-surface/chat-input-surface-host.tsx","../src/components/chat/default-skin/button.tsx","../src/components/chat/ui/chat-input-bar/chat-input-bar-actions.tsx","../src/components/chat/ui/chat-input-bar/chat-input-bar-skill-picker.tsx","../src/components/chat/ui/chat-input-bar/chat-input-bar-toolbar.tsx","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-token-node.tsx","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-editor-state.ts","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-operations.ts","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-controller.ts","../src/components/chat/ui/chat-input-bar/lexical/owners/chat-composer-lexical-owner.ts","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-plugins.tsx","../src/components/chat/ui/chat-input-bar/lexical/chat-input-bar-tokenized-composer.tsx","../src/components/chat/ui/chat-input-bar/chat-input-bar.tsx","../src/components/chat/ui/chat-message-list/chat-message-avatar.tsx","../src/components/chat/ui/chat-message-list/chat-inline-token-badge.tsx","../src/components/chat/utils/copy-text.utils.ts","../src/components/chat/hooks/use-copy-feedback.ts","../src/components/chat/ui/chat-message-list/code-block/chat-code-syntax-highlighter.ts","../src/components/chat/ui/chat-message-list/chat-code-block.tsx","../src/components/chat/ui/chat-message-list/utils/chat-inline-display.utils.ts","../src/components/chat/ui/chat-message-list/chat-inline-display.tsx","../src/components/chat/ui/chat-message-list/chat-message-markdown.tsx","../src/components/chat/ui/chat-message-list/chat-message-file/meta.ts","../src/components/chat/ui/chat-message-list/chat-message-file/index.tsx","../src/components/chat/hooks/use-reasoning-block-open-state.ts","../src/components/chat/hooks/use-sticky-bottom-scroll.ts","../src/components/chat/ui/chat-message-list/chat-reasoning-block.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-root.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-status.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-header.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-file-operation-lines.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-file-operation.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-views.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-panel-app.tsx","../src/components/chat/ui/chat-message-list/chat-tool-card.tsx","../src/components/chat/ui/chat-message-list/chat-message.tsx","../src/components/chat/ui/chat-message-list/chat-message-action-copy.tsx","../src/components/chat/ui/chat-message-list/chat-message-list.tsx","../src/lib/input-surface/input-surface-plugin.utils.ts"],"sourcesContent":["import type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatComposerTextNode,\n ChatComposerTokenKind,\n ChatComposerTokenNode,\n ChatInputSurfaceTrigger,\n ChatInputSurfaceTriggerSpec,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nexport const CHAT_COMPOSER_TOKEN_PLACEHOLDER = '\\uFFFC';\nexport const CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC: ChatInputSurfaceTriggerSpec = {\n key: 'slash',\n marker: '/',\n};\n\nfunction createComposerNodeId(): string {\n return `composer-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport function createChatComposerTextNode(text = ''): ChatComposerTextNode {\n return {\n id: createComposerNodeId(),\n type: 'text',\n text\n };\n}\n\nexport function createChatComposerTokenNode(params: {\n tokenKind: ChatComposerTokenKind;\n tokenKey: string;\n label: string;\n}): ChatComposerTokenNode {\n return {\n id: createComposerNodeId(),\n type: 'token',\n tokenKind: params.tokenKind,\n tokenKey: params.tokenKey,\n label: params.label\n };\n}\n\nexport function getChatComposerNodeLength(node: ChatComposerNode): number {\n return node.type === 'text' ? node.text.length : 1;\n}\n\nexport function createEmptyChatComposerNodes(): ChatComposerNode[] {\n return [createChatComposerTextNode('')];\n}\n\nexport function createChatComposerNodesFromText(text: string): ChatComposerNode[] {\n return [createChatComposerTextNode(text)];\n}\n\nexport function normalizeChatComposerNodes(nodes: ChatComposerNode[]): ChatComposerNode[] {\n const normalized: ChatComposerNode[] = [];\n for (const node of nodes) {\n if (node.type === 'text') {\n if (node.text.length === 0) {\n continue;\n }\n const previous = normalized[normalized.length - 1];\n if (previous?.type === 'text') {\n normalized[normalized.length - 1] = {\n ...previous,\n text: previous.text + node.text\n };\n continue;\n }\n }\n normalized.push(node);\n }\n if (normalized.length === 0) {\n return createEmptyChatComposerNodes();\n }\n return normalized;\n}\n\nexport function serializeChatComposerDocument(nodes: ChatComposerNode[]): string {\n return nodes.map((node) => (node.type === 'text' ? node.text : CHAT_COMPOSER_TOKEN_PLACEHOLDER)).join('');\n}\n\nexport function serializeChatComposerPlainText(nodes: ChatComposerNode[]): string {\n return nodes.filter((node): node is ChatComposerTextNode => node.type === 'text').map((node) => node.text).join('');\n}\n\nexport function extractChatComposerTokenKeys(\n nodes: ChatComposerNode[],\n tokenKind: ChatComposerTokenKind\n): string[] {\n const keys: string[] = [];\n const keySet = new Set<string>();\n for (const node of nodes) {\n if (node.type !== 'token' || node.tokenKind !== tokenKind || keySet.has(node.tokenKey)) {\n continue;\n }\n keySet.add(node.tokenKey);\n keys.push(node.tokenKey);\n }\n return keys;\n}\n\nfunction buildTrimmedTextEdges(\n node: ChatComposerTextNode,\n nodeStart: number,\n rangeStart: number,\n rangeEnd: number\n): ChatComposerTextNode[] {\n const prefixLength = Math.max(0, rangeStart - nodeStart);\n const suffixLength = Math.max(0, nodeStart + node.text.length - rangeEnd);\n const edges: ChatComposerTextNode[] = [];\n\n if (prefixLength > 0) {\n edges.push({\n ...node,\n text: node.text.slice(0, prefixLength)\n });\n }\n if (suffixLength > 0) {\n edges.push({\n ...node,\n text: node.text.slice(node.text.length - suffixLength)\n });\n }\n\n return edges;\n}\n\nfunction isNodeOutsideComposerRange(\n nodeStart: number,\n nodeEnd: number,\n boundedStart: number,\n boundedEnd: number\n): boolean {\n return nodeEnd <= boundedStart || nodeStart >= boundedEnd;\n}\n\nfunction appendReplacementBeforeNode(\n nextNodes: ChatComposerNode[],\n replacement: ChatComposerNode[],\n inserted: boolean,\n nodeStart: number,\n boundedEnd: number\n): boolean {\n if (!inserted && nodeStart >= boundedEnd) {\n nextNodes.push(...replacement);\n return true;\n }\n return inserted;\n}\n\nfunction appendTextNodeWithReplacement(\n nextNodes: ChatComposerNode[],\n node: ChatComposerTextNode,\n nodeStart: number,\n boundedStart: number,\n boundedEnd: number,\n replacement: ChatComposerNode[],\n inserted: boolean\n): boolean {\n const edges = buildTrimmedTextEdges(node, nodeStart, boundedStart, boundedEnd);\n if (edges[0]) {\n nextNodes.push(edges[0]);\n }\n let didInsert = inserted;\n if (!didInsert) {\n nextNodes.push(...replacement);\n didInsert = true;\n }\n if (edges[1]) {\n nextNodes.push(edges[1]);\n }\n return didInsert;\n}\n\nfunction appendTokenNodeWithReplacement(\n nextNodes: ChatComposerNode[],\n node: ChatComposerNode,\n replacement: ChatComposerNode[],\n inserted: boolean,\n boundedStart: number,\n nodeStart: number\n): boolean {\n if (!inserted && boundedStart <= nodeStart) {\n nextNodes.push(...replacement);\n return true;\n }\n nextNodes.push(node);\n return inserted;\n}\n\nexport function replaceChatComposerRange(\n nodes: ChatComposerNode[],\n start: number,\n end: number,\n replacement: ChatComposerNode[]\n): ChatComposerNode[] {\n const boundedStart = Math.max(0, start);\n const boundedEnd = Math.max(boundedStart, end);\n const nextNodes: ChatComposerNode[] = [];\n let cursor = 0;\n let inserted = false;\n\n for (const node of nodes) {\n const nodeLength = getChatComposerNodeLength(node);\n const nodeStart = cursor;\n const nodeEnd = cursor + nodeLength;\n const isOutsideRange = isNodeOutsideComposerRange(nodeStart, nodeEnd, boundedStart, boundedEnd);\n\n if (isOutsideRange) {\n inserted = appendReplacementBeforeNode(nextNodes, replacement, inserted, nodeStart, boundedEnd);\n nextNodes.push(node);\n cursor = nodeEnd;\n continue;\n }\n\n if (node.type === 'text') {\n inserted = appendTextNodeWithReplacement(\n nextNodes,\n node,\n nodeStart,\n boundedStart,\n boundedEnd,\n replacement,\n inserted\n );\n } else {\n inserted = appendTokenNodeWithReplacement(nextNodes, node, replacement, inserted, boundedStart, nodeStart);\n }\n\n cursor = nodeEnd;\n }\n\n if (!inserted) {\n nextNodes.push(...replacement);\n }\n\n return normalizeChatComposerNodes(nextNodes);\n}\n\nexport function removeChatComposerTokenNodes(\n nodes: ChatComposerNode[],\n predicate: (node: ChatComposerTokenNode) => boolean\n): ChatComposerNode[] {\n return normalizeChatComposerNodes(\n nodes.filter((node) => node.type !== 'token' || !predicate(node))\n );\n}\n\nfunction hasTriggerBoundary(prefix: string, markerStart: number): boolean {\n return markerStart === 0 || /\\s/.test(prefix[markerStart - 1] ?? '');\n}\n\nexport function resolveChatComposerInputSurfaceTrigger(\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n triggerSpec: ChatInputSurfaceTriggerSpec\n): ChatInputSurfaceTrigger | null {\n if (!selection || selection.start !== selection.end) {\n return null;\n }\n\n const documentText = serializeChatComposerDocument(nodes);\n const caret = selection.end;\n const prefix = documentText.slice(0, caret);\n const markerStart = prefix.lastIndexOf(triggerSpec.marker);\n if (markerStart < 0 || !hasTriggerBoundary(prefix, markerStart)) {\n return null;\n }\n\n const rawQuery = prefix.slice(markerStart + triggerSpec.marker.length);\n if (/[\\s\\uFFFC]/.test(rawQuery)) {\n return null;\n }\n\n return {\n key: triggerSpec.key,\n marker: triggerSpec.marker,\n query: rawQuery.trim().toLowerCase(),\n start: markerStart,\n end: caret,\n };\n}\n\nexport function resolveChatComposerActiveInputSurfaceTrigger(\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n triggerSpecs: readonly ChatInputSurfaceTriggerSpec[] = [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n): ChatInputSurfaceTrigger | null {\n let activeTrigger: ChatInputSurfaceTrigger | null = null;\n for (const triggerSpec of triggerSpecs) {\n const trigger = resolveChatComposerInputSurfaceTrigger(nodes, selection, triggerSpec);\n if (!trigger) {\n continue;\n }\n if (!activeTrigger || trigger.start > activeTrigger.start) {\n activeTrigger = trigger;\n }\n }\n return activeTrigger;\n}\n\nexport function resolveChatComposerSlashTrigger(\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null\n): { query: string; start: number; end: number } | null {\n const trigger = resolveChatComposerInputSurfaceTrigger(\n nodes,\n selection,\n CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC,\n );\n return trigger\n ? {\n query: trigger.query,\n start: trigger.start,\n end: trigger.end,\n }\n : null;\n}\n\nexport function isChatComposerSelectionInsideRange(\n selection: ChatComposerSelection | null,\n start: number,\n end: number\n): boolean {\n if (!selection) {\n return false;\n }\n return selection.start < end && selection.end > start;\n}\n","import { useEffect, type RefObject } from 'react';\n\ntype UseActiveItemScrollParams = {\n containerRef: RefObject<HTMLElement>;\n activeIndex: number;\n itemCount: number;\n isEnabled: boolean;\n getItemSelector?: (index: number) => string;\n};\n\nconst defaultGetItemSelector = (index: number) => `[data-item-index=\"${index}\"]`;\n\nexport function useActiveItemScroll(params: UseActiveItemScrollParams) {\n const { activeIndex, containerRef, getItemSelector: customGetItemSelector, isEnabled, itemCount } =\n params;\n const getItemSelector = customGetItemSelector ?? defaultGetItemSelector;\n\n useEffect(() => {\n if (!isEnabled || itemCount === 0) {\n return;\n }\n\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const activeItem = container.querySelector<HTMLElement>(getItemSelector(activeIndex));\n if (typeof activeItem?.scrollIntoView === 'function') {\n activeItem.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n }\n }, [activeIndex, containerRef, getItemSelector, isEnabled, itemCount]);\n}\n","import { useEffect, useRef, useState, type RefObject } from 'react';\n\ntype UseElementWidthResult<T extends HTMLElement> = {\n elementRef: RefObject<T>;\n width: number | null;\n};\n\nexport function useElementWidth<T extends HTMLElement>(): UseElementWidthResult<T> {\n const elementRef = useRef<T | null>(null);\n const [width, setWidth] = useState<number | null>(null);\n\n useEffect(() => {\n const element = elementRef.current;\n if (!element || typeof ResizeObserver === 'undefined') {\n return;\n }\n\n const updateWidth = () => {\n setWidth(element.getBoundingClientRect().width);\n };\n\n updateWidth();\n\n const observer = new ResizeObserver(() => updateWidth());\n observer.observe(element);\n\n return () => observer.disconnect();\n }, []);\n\n return {\n elementRef,\n width\n };\n}\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from 'react';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nexport type ChatInputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nconst ChatInput = React.forwardRef<HTMLInputElement, ChatInputProps>(({ className, type, ...props }, ref) => (\n <input\n type={type}\n className={cn(\n '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',\n className\n )}\n ref={ref}\n {...props}\n />\n));\n\nChatInput.displayName = 'ChatInput';\n\nexport { ChatInput };\n","import * as React from 'react';\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nconst CHAT_FLOATING_CONTENT_AVAILABLE_HEIGHT_GAP = '2rem';\n\nfunction createChatPopoverAvailableHeightLimit(limit: string): string {\n return `min(${limit}, max(0px, calc(var(--radix-popover-content-available-height, 100vh) - ${CHAT_FLOATING_CONTENT_AVAILABLE_HEIGHT_GAP})))`;\n}\n\nconst CHAT_POPOVER_CONTENT_MAX_HEIGHT = createChatPopoverAvailableHeightLimit('24rem');\n\nconst ChatPopover = PopoverPrimitive.Root;\nconst ChatPopoverTrigger = PopoverPrimitive.Trigger;\nconst ChatPopoverAnchor = PopoverPrimitive.Anchor;\n\nconst ChatPopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, sideOffset = 8, align = 'start', collisionPadding = 12, style, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n align={align}\n collisionPadding={collisionPadding}\n className={cn(\n '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',\n className\n )}\n style={{ maxHeight: CHAT_POPOVER_CONTENT_MAX_HEIGHT, ...style }}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\n\nChatPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport {\n ChatPopover,\n ChatPopoverTrigger,\n ChatPopoverContent,\n ChatPopoverAnchor,\n createChatPopoverAvailableHeightLimit,\n};\n","import * as React from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\nimport { Check, ChevronDown, ChevronUp } from 'lucide-react';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nconst ChatSelect = SelectPrimitive.Root;\nconst ChatSelectGroup = SelectPrimitive.Group;\nconst ChatSelectValue = SelectPrimitive.Value;\nconst CHAT_SELECT_CONTENT_AVAILABLE_HEIGHT_GAP = '2rem';\n\nfunction createChatSelectAvailableHeightLimit(limit: string): string {\n return `min(${limit}, max(0px, calc(var(--radix-select-content-available-height, 100vh) - ${CHAT_SELECT_CONTENT_AVAILABLE_HEIGHT_GAP})))`;\n}\n\nconst CHAT_SELECT_CONTENT_MAX_HEIGHT = createChatSelectAvailableHeightLimit('24rem');\n\nconst ChatSelectTrigger = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n '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',\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n));\n\nChatSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nconst ChatSelectScrollUpButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton ref={ref} className={cn('flex cursor-default items-center justify-center py-1', className)} {...props}>\n <ChevronUp className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollUpButton>\n));\n\nChatSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nconst ChatSelectScrollDownButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton ref={ref} className={cn('flex cursor-default items-center justify-center py-1', className)} {...props}>\n <ChevronDown className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollDownButton>\n));\n\nChatSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;\n\ntype ChatSelectContentProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> & {\n viewportClassName?: string;\n};\n\nconst ChatSelectContent = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Content>,\n ChatSelectContentProps\n>(({ className, children, collisionPadding = 12, position = 'popper', style, viewportClassName, ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n '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',\n position === 'popper' &&\n 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n className\n )}\n collisionPadding={collisionPadding}\n position={position}\n style={{ maxHeight: CHAT_SELECT_CONTENT_MAX_HEIGHT, ...style }}\n {...props}\n >\n <ChatSelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n 'min-h-0 flex-1 overflow-y-auto overscroll-contain p-1',\n position === 'popper' && 'w-full min-w-[var(--radix-select-trigger-width)]',\n viewportClassName,\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <ChatSelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n));\n\nChatSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nconst ChatSelectLabel = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label ref={ref} className={cn('px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground', className)} {...props} />\n));\n\nChatSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nconst ChatSelectItem = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n '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',\n className\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n));\n\nChatSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nconst ChatSelectSeparator = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-border', className)} {...props} />\n));\n\nChatSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n\nexport {\n ChatSelect,\n ChatSelectContent,\n ChatSelectGroup,\n ChatSelectItem,\n ChatSelectLabel,\n ChatSelectSeparator,\n ChatSelectTrigger,\n ChatSelectValue,\n createChatSelectAvailableHeightLimit\n};\n","import * as React from 'react';\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nconst ChatTooltipProvider = TooltipPrimitive.Provider;\nconst ChatTooltip = TooltipPrimitive.Root;\nconst ChatTooltipTrigger = TooltipPrimitive.Trigger;\n\nconst ChatTooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-[var(--z-tooltip)] overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md 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',\n className\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n));\n\nChatTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { ChatTooltip, ChatTooltipTrigger, ChatTooltipContent, ChatTooltipProvider };\n","import { ChatInput as DefaultInput } from '@agent-chat-ui/components/chat/default-skin/input';\nimport {\n ChatPopover as DefaultPopover,\n ChatPopoverAnchor as DefaultPopoverAnchor,\n ChatPopoverContent as DefaultPopoverContent,\n ChatPopoverTrigger as DefaultPopoverTrigger,\n createChatPopoverAvailableHeightLimit\n} from '@agent-chat-ui/components/chat/default-skin/popover';\nimport {\n ChatSelect as DefaultSelect,\n ChatSelectContent as DefaultSelectContent,\n ChatSelectGroup as DefaultSelectGroup,\n ChatSelectItem as DefaultSelectItem,\n ChatSelectLabel as DefaultSelectLabel,\n ChatSelectSeparator as DefaultSelectSeparator,\n ChatSelectTrigger as DefaultSelectTrigger,\n ChatSelectValue as DefaultSelectValue,\n createChatSelectAvailableHeightLimit\n} from '@agent-chat-ui/components/chat/default-skin/select';\nimport {\n ChatTooltip as DefaultTooltip,\n ChatTooltipContent as DefaultTooltipContent,\n ChatTooltipProvider as DefaultTooltipProvider,\n ChatTooltipTrigger as DefaultTooltipTrigger\n} from '@agent-chat-ui/components/chat/default-skin/tooltip';\n\n// Centralized primitive adapter layer for chat UI.\nexport const ChatUiPrimitives = {\n Popover: DefaultPopover,\n PopoverAnchor: DefaultPopoverAnchor,\n PopoverContent: DefaultPopoverContent,\n PopoverTrigger: DefaultPopoverTrigger,\n Input: DefaultInput,\n Select: DefaultSelect,\n SelectContent: DefaultSelectContent,\n SelectGroup: DefaultSelectGroup,\n SelectItem: DefaultSelectItem,\n SelectLabel: DefaultSelectLabel,\n SelectSeparator: DefaultSelectSeparator,\n SelectTrigger: DefaultSelectTrigger,\n SelectValue: DefaultSelectValue,\n Tooltip: DefaultTooltip,\n TooltipContent: DefaultTooltipContent,\n TooltipProvider: DefaultTooltipProvider,\n TooltipTrigger: DefaultTooltipTrigger\n};\n\nexport {\n createChatPopoverAvailableHeightLimit,\n createChatSelectAvailableHeightLimit\n};\n","import { forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport { useActiveItemScroll } from '@agent-chat-ui/components/chat/hooks/use-active-item-scroll';\nimport { useElementWidth } from '@agent-chat-ui/components/chat/hooks/use-element-width';\nimport {\n ChatUiPrimitives,\n createChatPopoverAvailableHeightLimit,\n} from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport type {\n ChatInputSurfaceFilterOption,\n ChatInputSurfaceItem,\n ChatInputSurfaceMenuProps,\n} from '@agent-chat-ui/lib/input-surface';\n\nconst INPUT_SURFACE_PANEL_MAX_WIDTH = 680;\nconst INPUT_SURFACE_PANEL_DESKTOP_SHRINK_RATIO = 0.82;\nconst INPUT_SURFACE_PANEL_DESKTOP_MIN_WIDTH = 560;\nconst INPUT_SURFACE_PANEL_MAX_HEIGHT = createChatPopoverAvailableHeightLimit('24rem');\nconst INPUT_SURFACE_PANEL_MIN_HEIGHT = createChatPopoverAvailableHeightLimit('240px');\n\nexport type ChatInputSurfaceMenuHandle = {\n handleKeyDown: (event: KeyboardEvent) => boolean;\n};\n\ntype ChatInputSurfaceActiveState = {\n index: number;\n itemsSignature: string;\n};\n\ntype ChatInputSurfaceFilterView = ChatInputSurfaceFilterOption & {\n count: number;\n};\n\nfunction itemMatchesFilter(item: ChatInputSurfaceItem, filter: ChatInputSurfaceFilterOption): boolean {\n if (!filter.sectionKeys || filter.sectionKeys.length === 0) {\n return true;\n }\n return Boolean(item.sectionKey && filter.sectionKeys.includes(item.sectionKey));\n}\n\nexport const ChatInputSurfaceMenu = forwardRef<ChatInputSurfaceMenuHandle, ChatInputSurfaceMenuProps>(\nfunction ChatInputSurfaceMenu(props, ref) {\n const { Popover, PopoverAnchor, PopoverContent } = ChatUiPrimitives;\n const { elementRef: anchorRef, width: panelWidth } = useElementWidth<HTMLDivElement>();\n const listRef = useRef<HTMLDivElement | null>(null);\n const [activeState, setActiveState] = useState<ChatInputSurfaceActiveState>({\n index: 0,\n itemsSignature: '',\n });\n const {\n isOpen,\n isLoading,\n filterOptions,\n items,\n texts,\n onSelectItem,\n onOpenChange,\n onDetailsPointerDown,\n } = props;\n const firstFilterKey = filterOptions?.[0]?.key ?? null;\n const [activeFilterKey, setActiveFilterKey] = useState<string | null>(firstFilterKey);\n const resolvedActiveFilterKey = useMemo(() => {\n if (!filterOptions?.length) {\n return null;\n }\n return filterOptions.some((filter) => filter.key === activeFilterKey)\n ? activeFilterKey\n : filterOptions[0].key;\n }, [activeFilterKey, filterOptions]);\n const activeFilter = useMemo(\n () => filterOptions?.find((filter) => filter.key === resolvedActiveFilterKey) ?? null,\n [filterOptions, resolvedActiveFilterKey],\n );\n const filterViews = useMemo<ChatInputSurfaceFilterView[]>(\n () =>\n filterOptions?.map((filter) => ({\n ...filter,\n count: items.filter((item) => itemMatchesFilter(item, filter)).length,\n })) ?? [],\n [filterOptions, items],\n );\n const visibleItems = useMemo(\n () => (activeFilter ? items.filter((item) => itemMatchesFilter(item, activeFilter)) : items),\n [activeFilter, items],\n );\n const itemsSignature = useMemo(\n () => visibleItems.map((item) => item.key).join('\\u001f'),\n [visibleItems],\n );\n const hasItemSections = useMemo(\n () => visibleItems.some((item) => Boolean(item.sectionLabel?.trim())),\n [visibleItems],\n );\n const activeIndex = activeState.itemsSignature === itemsSignature ? activeState.index : 0;\n const activeIndexInRange = visibleItems.length === 0 ? 0 : Math.min(activeIndex, visibleItems.length - 1);\n const activeItem = visibleItems[activeIndexInRange] ?? null;\n const handleFilterSelect = useCallback((filterKey: string): void => {\n setActiveFilterKey(filterKey);\n setActiveState({ index: 0, itemsSignature: '' });\n }, []);\n const setActiveIndexForCurrentItems = useCallback(\n (nextIndex: number | ((currentIndex: number) => number)): void => {\n setActiveState((currentState) => {\n const currentIndex = currentState.itemsSignature === itemsSignature ? currentState.index : 0;\n return {\n index: typeof nextIndex === 'function' ? nextIndex(currentIndex) : nextIndex,\n itemsSignature,\n };\n });\n },\n [itemsSignature],\n );\n\n const resolvedWidth = useMemo(() => {\n if (!panelWidth) {\n return undefined;\n }\n return Math.min(\n panelWidth > INPUT_SURFACE_PANEL_DESKTOP_MIN_WIDTH\n ? panelWidth * INPUT_SURFACE_PANEL_DESKTOP_SHRINK_RATIO\n : panelWidth,\n INPUT_SURFACE_PANEL_MAX_WIDTH,\n );\n }, [panelWidth]);\n\n useImperativeHandle(ref, () => ({\n handleKeyDown: (event) => {\n if (!isOpen) {\n return false;\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n onOpenChange(false);\n return true;\n }\n\n if (visibleItems.length === 0) {\n return false;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n setActiveIndexForCurrentItems((index) => (index + 1) % visibleItems.length);\n return true;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n setActiveIndexForCurrentItems((index) => (index - 1 + visibleItems.length) % visibleItems.length);\n return true;\n }\n\n if ((event.key === 'Enter' && !event.shiftKey) || event.key === 'Tab') {\n event.preventDefault();\n onSelectItem(visibleItems[activeIndexInRange]);\n return true;\n }\n\n return false;\n },\n }), [activeIndexInRange, isOpen, onOpenChange, onSelectItem, setActiveIndexForCurrentItems, visibleItems]);\n\n useActiveItemScroll({\n containerRef: listRef,\n activeIndex: activeIndexInRange,\n itemCount: visibleItems.length,\n isEnabled: isOpen && !isLoading,\n getItemSelector: (index) => `[data-input-surface-index=\"${index}\"]`,\n });\n\n return (\n <Popover open={isOpen} onOpenChange={onOpenChange}>\n <PopoverAnchor asChild>\n <div ref={anchorRef} className=\"pointer-events-none absolute bottom-0 left-3 right-3 top-0\" />\n </PopoverAnchor>\n <PopoverContent\n side=\"top\"\n align=\"start\"\n sideOffset={10}\n className=\"z-[70] flex max-w-[calc(100vw-1.5rem)] flex-col overflow-hidden rounded-2xl border border-gray-200 bg-white/95 p-0 shadow-2xl backdrop-blur-md\"\n onOpenAutoFocus={(event) => event.preventDefault()}\n style={{\n maxHeight: INPUT_SURFACE_PANEL_MAX_HEIGHT,\n width: resolvedWidth ? `${resolvedWidth}px` : undefined,\n }}\n >\n <div\n className=\"grid min-h-0 flex-1 grid-cols-[minmax(220px,300px)_minmax(0,1fr)]\"\n style={{ minHeight: INPUT_SURFACE_PANEL_MIN_HEIGHT }}\n >\n <div className=\"flex min-h-0 flex-col border-r border-gray-200\">\n {!isLoading && filterViews.length > 0 ? (\n <div className=\"flex shrink-0 gap-1 overflow-x-auto px-2.5 pb-2 pt-2.5\">\n {filterViews.map(({ count, key, label }) => {\n const isActive = key === resolvedActiveFilterKey;\n return (\n <button\n key={key}\n type=\"button\"\n aria-pressed={isActive}\n onPointerDown={(event) => event.preventDefault()}\n onClick={() => handleFilterSelect(key)}\n className={`inline-flex shrink-0 items-center gap-1 rounded-full border px-2 py-1 text-[11px] font-semibold transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 ${\n isActive\n ? 'border-primary/30 bg-primary/10 text-primary'\n : 'border-gray-200 bg-white text-gray-600 hover:border-gray-300 hover:bg-gray-50'\n }`}\n >\n <span>{label}</span>\n <span className={isActive ? 'text-primary/70' : 'text-gray-400'}>{count}</span>\n </button>\n );\n })}\n </div>\n ) : null}\n <div\n ref={listRef}\n role=\"listbox\"\n aria-label={texts.sectionLabel}\n className={`custom-scrollbar min-h-0 flex-1 overflow-y-auto overscroll-contain ${\n !isLoading && filterViews.length > 0 ? 'px-2.5 pb-2.5' : 'p-2.5'\n }`}\n >\n {isLoading ? (\n <div className=\"p-2 text-xs text-gray-500\">{texts.loadingLabel}</div>\n ) : (\n <>\n {!hasItemSections ? (\n <div className=\"mb-2 px-2 text-[11px] font-semibold uppercase tracking-wide text-gray-500\">\n {texts.sectionLabel}\n </div>\n ) : null}\n {visibleItems.length === 0 ? (\n <div className=\"px-2 text-xs text-gray-400\">{texts.emptyLabel}</div>\n ) : (\n <div className=\"space-y-1\">\n {visibleItems.map((item, index) => {\n const { key, sectionKey, sectionLabel, title, subtitle } = item;\n const isActive = index === activeIndexInRange;\n const previousItem = visibleItems[index - 1];\n const shouldShowSection =\n hasItemSections &&\n Boolean(sectionLabel?.trim()) &&\n previousItem?.sectionKey !== sectionKey;\n return (\n <div key={key} className=\"space-y-1\">\n {shouldShowSection ? (\n <div className=\"px-2 pb-0.5 pt-1.5 text-[11px] font-semibold uppercase tracking-wide text-gray-500\">\n {sectionLabel}\n </div>\n ) : null}\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-input-surface-index={index}\n onPointerMove={(event) => {\n if (event.pointerType !== 'touch') {\n setActiveIndexForCurrentItems(index);\n }\n }}\n onPointerDown={(event) => {\n if (event.button > 0) {\n return;\n }\n event.preventDefault();\n onSelectItem(item);\n }}\n onClick={(event) => {\n if (event.detail === 0) {\n onSelectItem(item);\n }\n }}\n className={`flex w-full items-start gap-2 rounded-lg px-2 py-1.5 text-left transition ${\n isActive ? 'bg-gray-100 text-gray-900' : 'text-gray-700 hover:bg-gray-50'\n }`}\n >\n <span className=\"truncate text-xs font-semibold\">{title}</span>\n <span className=\"truncate text-xs text-gray-500\">{subtitle}</span>\n </button>\n </div>\n );\n })}\n </div>\n )}\n </>\n )}\n </div>\n </div>\n <div\n className=\"custom-scrollbar min-h-0 min-w-0 overflow-y-auto overscroll-contain p-2.5\"\n onPointerDown={onDetailsPointerDown}\n >\n {activeItem ? (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"inline-flex rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-semibold text-primary\">\n {activeItem.subtitle}\n </span>\n <span className=\"text-sm font-semibold text-gray-900\">{activeItem.title}</span>\n </div>\n <p className=\"text-xs leading-5 text-gray-600\">{activeItem.description}</p>\n <div className=\"space-y-1\">\n {activeItem.detailLines.map((line) => (\n <div\n key={line}\n className=\"min-w-0 break-all rounded-md bg-gray-50 px-2 py-1 text-[11px] leading-5 text-gray-600\"\n >\n {line}\n </div>\n ))}\n </div>\n <div className=\"pt-1 text-[11px] text-gray-500\">\n {activeItem.hintLabel ?? texts.itemHintLabel}\n </div>\n </div>\n ) : (\n <div className=\"text-xs text-gray-500\">{texts.hintLabel}</div>\n )}\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n});\n","import { useCallback, useMemo, useRef, useState, type ReactNode } from 'react';\nimport type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatInputSurfaceConfig,\n ChatInputSurfaceItem,\n ChatInputSurfaceTrigger,\n ChatInputSurfaceTriggerChangeReason,\n ChatInputSurfaceTriggerSpec,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC,\n resolveChatComposerActiveInputSurfaceTrigger,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/chat-composer.utils';\nimport {\n ChatInputSurfaceMenu,\n type ChatInputSurfaceMenuHandle,\n} from '@agent-chat-ui/components/chat/ui/input-surface/chat-input-surface-menu';\n\ntype ChatInputSurfaceHostBindings = {\n onInputSurfaceKeyDown: (event: KeyboardEvent) => boolean;\n onInputSurfaceOpenChange: (open: boolean) => void;\n onInputSurfaceSnapshotChange: (\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n ) => void;\n};\n\nexport type ChatInputSurfaceHostProps = {\n inputSurface: ChatInputSurfaceConfig | null;\n onInputSurfaceTriggerChange?: (trigger: ChatInputSurfaceTrigger | null) => void;\n onSelectItem: (item: ChatInputSurfaceItem) => void;\n triggerSpecs?: readonly ChatInputSurfaceTriggerSpec[];\n children: (bindings: ChatInputSurfaceHostBindings) => ReactNode;\n};\n\nexport function getInputSurfaceTriggerIdentity(trigger: ChatInputSurfaceTrigger): string {\n return `${trigger.key}:${trigger.marker}:${trigger.start}`;\n}\n\nexport function isInputSurfaceCreateEvent(\n trigger: ChatInputSurfaceTrigger,\n reason: ChatInputSurfaceTriggerChangeReason,\n): boolean {\n return (\n reason.type === 'insert-text' &&\n reason.text === trigger.marker &&\n trigger.query === '' &&\n trigger.end === trigger.start + trigger.marker.length\n );\n}\n\nexport function resolveInputSurfaceTriggerIdentity(\n currentIdentity: string | null,\n trigger: ChatInputSurfaceTrigger | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n): string | null {\n if (!trigger) {\n return null;\n }\n\n const nextIdentity = getInputSurfaceTriggerIdentity(trigger);\n if (currentIdentity === nextIdentity) {\n return currentIdentity;\n }\n return isInputSurfaceCreateEvent(trigger, reason) ? nextIdentity : null;\n}\n\nexport function ChatInputSurfaceHost(props: ChatInputSurfaceHostProps) {\n const {\n children,\n inputSurface,\n onInputSurfaceTriggerChange,\n onSelectItem,\n triggerSpecs = [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n } = props;\n const menuRef = useRef<ChatInputSurfaceMenuHandle | null>(null);\n const [activeTriggerIdentity, setActiveTriggerIdentity] = useState<string | null>(null);\n const isOpen = Boolean(inputSurface) && activeTriggerIdentity !== null;\n\n const setActiveTrigger = useCallback(\n (identity: string | null, trigger: ChatInputSurfaceTrigger | null): void => {\n setActiveTriggerIdentity(identity);\n onInputSurfaceTriggerChange?.(identity ? trigger : null);\n },\n [onInputSurfaceTriggerChange],\n );\n\n const closeInputSurface = useCallback(\n (): void => {\n setActiveTrigger(null, null);\n },\n [setActiveTrigger],\n );\n\n const handleInputSurfaceSnapshotChange = useCallback(\n (\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n ): void => {\n const trigger = resolveChatComposerActiveInputSurfaceTrigger(nodes, selection, triggerSpecs);\n const nextIdentity = resolveInputSurfaceTriggerIdentity(\n activeTriggerIdentity,\n trigger,\n reason,\n );\n setActiveTrigger(nextIdentity, nextIdentity ? trigger : null);\n },\n [activeTriggerIdentity, setActiveTrigger, triggerSpecs],\n );\n\n const handleInputSurfaceKeyDown = useCallback((event: KeyboardEvent): boolean => {\n return menuRef.current?.handleKeyDown(event) ?? false;\n }, []);\n\n const handleInputSurfaceOpenChange = useCallback(\n (open: boolean): void => {\n if (!open) {\n closeInputSurface();\n }\n },\n [closeInputSurface],\n );\n\n const bindings = useMemo(\n () => ({\n onInputSurfaceKeyDown: handleInputSurfaceKeyDown,\n onInputSurfaceOpenChange: handleInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange: handleInputSurfaceSnapshotChange,\n }),\n [\n handleInputSurfaceKeyDown,\n handleInputSurfaceOpenChange,\n handleInputSurfaceSnapshotChange,\n ],\n );\n\n return (\n <>\n {/* eslint-disable-next-line react-hooks/refs -- menu ref is read later from keydown handlers, not during render. */}\n {children(bindings)}\n {inputSurface && isOpen ? (\n <ChatInputSurfaceMenu\n key={activeTriggerIdentity}\n ref={menuRef}\n isOpen={isOpen}\n isLoading={inputSurface.isLoading}\n filterOptions={inputSurface.filterOptions}\n items={inputSurface.items}\n texts={inputSurface.texts}\n onSelectItem={(item) => {\n closeInputSurface();\n onSelectItem(item);\n }}\n onOpenChange={handleInputSurfaceOpenChange}\n onDetailsPointerDown={(event) => event.preventDefault()}\n />\n ) : null}\n </>\n );\n}\n","import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-full text-sm font-medium ring-offset-background transition-all duration-fast focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary-600 active:bg-primary-700 shadow-sm',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline: 'border border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n secondary: 'bg-muted text-foreground hover:bg-accent hover:text-accent-foreground',\n ghost: 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n primary: 'bg-primary text-primary-foreground hover:bg-primary-600 active:bg-primary-700 shadow-sm',\n subtle: 'bg-muted text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n 'primary-outline': 'border border-primary/30 text-primary hover:bg-primary hover:text-primary-foreground'\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 px-3 text-xs',\n lg: 'h-11 px-5 text-[14px]',\n xl: 'h-12 px-6 text-[15px]',\n icon: 'h-9 w-9'\n }\n },\n defaultVariants: {\n variant: 'default',\n size: 'default'\n }\n }\n);\n\nexport interface ChatButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst ChatButton = React.forwardRef<HTMLButtonElement, ChatButtonProps>(\n ({ className, variant, size, ...props }, ref) => (\n <button className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />\n )\n);\n\nChatButton.displayName = 'ChatButton';\n\nexport { ChatButton, buttonVariants };\n","import { ChatButton } from '@agent-chat-ui/components/chat/default-skin/button';\nimport { ChatUiPrimitives } from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport type { ChatContextWindowIndicator, ChatInputBarActionsProps } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { ArrowUp } from 'lucide-react';\n\nconst SEND_ERROR_PREVIEW_MAX_CHARS = 120;\n\nfunction buildSendErrorPreview(value: string): string {\n const compact = value.replace(/\\s+/g, ' ').trim();\n if (compact.length <= SEND_ERROR_PREVIEW_MAX_CHARS) {\n return compact;\n }\n return `${compact.slice(0, SEND_ERROR_PREVIEW_MAX_CHARS - 1)}…`;\n}\n\nfunction StopIcon() {\n return (\n <span\n aria-hidden=\"true\"\n data-testid=\"chat-stop-icon\"\n className=\"block h-3 w-3 rounded-[2px] bg-foreground shadow-[inset_0_0_0_1px_hsl(var(--border))]\"\n />\n );\n}\n\nfunction ContextWindowIndicator({ contextWindow }: { contextWindow: ChatContextWindowIndicator }) {\n const { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } = ChatUiPrimitives;\n const clampedRatio = Math.max(0, Math.min(1, contextWindow.ratio));\n const angle = Math.round(clampedRatio * 360);\n const ringColor = 'hsl(var(--muted-foreground))';\n\n return (\n <TooltipProvider delayDuration={0}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n 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\"\n aria-label={contextWindow.label}\n title={contextWindow.label}\n >\n <span\n aria-hidden=\"true\"\n className=\"absolute inset-[7px] rounded-full\"\n style={{ background: `conic-gradient(${ringColor} ${angle}deg, hsl(var(--border)) 0deg)` }}\n />\n <span aria-hidden=\"true\" className=\"absolute inset-[10px] rounded-full bg-card\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-[18rem]\">\n <div className=\"space-y-1.5 text-xs\">\n <div className=\"flex items-center justify-between gap-5 font-semibold text-foreground\">\n <span>{contextWindow.label}</span>\n <span>{contextWindow.percentLabel}</span>\n </div>\n {contextWindow.details.map((detail) => (\n <div key={detail.label} className=\"flex items-center justify-between gap-5 text-muted-foreground\">\n <span>{detail.label}</span>\n <span className=\"font-medium text-foreground\">{detail.value}</span>\n </div>\n ))}\n </div>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n\nexport function ChatInputBarActions({\n sendError,\n sendErrorDetailsLabel,\n isSending,\n canStopGeneration,\n sendDisabled,\n stopDisabled,\n stopHint,\n sendButtonLabel,\n stopButtonLabel,\n contextWindow,\n onSend,\n onStop\n}: ChatInputBarActionsProps) {\n const {\n Popover,\n PopoverContent,\n PopoverTrigger,\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger\n } = ChatUiPrimitives;\n const normalizedSendError = sendError?.trim() ?? '';\n const sendErrorPreview = normalizedSendError\n ? buildSendErrorPreview(normalizedSendError)\n : '';\n const resolvedSendErrorDetailsLabel = sendErrorDetailsLabel?.trim() || 'Details';\n const showSendButton = !isSending || !sendDisabled;\n\n return (\n <div className=\"flex shrink-0 flex-col items-end gap-1\">\n {normalizedSendError ? (\n <div className=\"flex max-w-[420px] items-start justify-end gap-2 text-right\">\n <div className=\"min-w-0 flex-1 text-[11px] text-red-600\">\n <span\n className=\"block truncate\"\n title={normalizedSendError}\n >\n {sendErrorPreview}\n </span>\n </div>\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"shrink-0 rounded-full border border-red-200/80 bg-red-50 px-2 py-0.5 text-[10px] font-semibold text-red-700 transition-colors hover:bg-red-100\"\n >\n {resolvedSendErrorDetailsLabel}\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n className=\"w-[min(32rem,calc(100vw-1.5rem))] border-red-100/80 p-0\"\n >\n <div className=\"border-b border-red-100 bg-red-50/80 px-4 py-2 text-xs font-semibold text-red-700\">\n {resolvedSendErrorDetailsLabel}\n </div>\n <pre className=\"max-h-80 overflow-auto whitespace-pre-wrap break-words px-4 py-3 text-xs leading-relaxed text-red-700\">\n {normalizedSendError}\n </pre>\n </PopoverContent>\n </Popover>\n </div>\n ) : null}\n <div className=\"flex items-center gap-2\">\n {contextWindow ? <ContextWindowIndicator contextWindow={contextWindow} /> : null}\n {showSendButton ? (\n <ChatButton\n size=\"icon\"\n className=\"h-8 w-8 rounded-full\"\n aria-label={sendButtonLabel}\n onClick={() => void onSend()}\n disabled={sendDisabled}\n >\n <ArrowUp className=\"h-5 w-5\" />\n </ChatButton>\n ) : canStopGeneration ? (\n <ChatButton\n size=\"icon\"\n variant=\"outline\"\n className=\"h-8 w-8 rounded-full\"\n aria-label={stopButtonLabel}\n onClick={() => void onStop()}\n disabled={stopDisabled}\n >\n <StopIcon />\n </ChatButton>\n ) : (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span>\n <ChatButton\n size=\"icon\"\n variant=\"outline\"\n className=\"h-8 w-8 rounded-full\"\n aria-label={stopButtonLabel}\n disabled\n >\n <StopIcon />\n </ChatButton>\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n <p className=\"text-xs\">{stopHint}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n </div>\n );\n}\n","import { useEffect, useId, useMemo, useRef, useState, type KeyboardEventHandler } from 'react';\nimport { BrainCircuit, Check, ExternalLink, Puzzle, Search } from 'lucide-react';\nimport { useActiveItemScroll } from '@agent-chat-ui/components/chat/hooks/use-active-item-scroll';\nimport {\n ChatUiPrimitives,\n createChatPopoverAvailableHeightLimit,\n} from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport type { ChatSkillPickerOption, ChatSkillPickerOptionGroup, ChatSkillPickerProps } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nfunction filterOptions(options: ChatSkillPickerOption[], query: string): ChatSkillPickerOption[] {\n const keyword = query.trim().toLowerCase();\n if (!keyword) {\n return options;\n }\n return options.filter((option) => {\n const haystack = [option.label, option.key, option.description]\n .filter((value): value is string => typeof value === 'string' && value.trim().length > 0)\n .join(' ')\n .toLowerCase();\n return haystack.includes(keyword);\n });\n}\n\nconst SKILL_PICKER_MAX_HEIGHT = createChatPopoverAvailableHeightLimit('24rem');\n\nexport function ChatInputBarSkillPicker(props: { picker: ChatSkillPickerProps }) {\n const { Input, Popover, PopoverContent, PopoverTrigger } = ChatUiPrimitives;\n const { picker } = props;\n const listRef = useRef<HTMLDivElement | null>(null);\n const listId = useId();\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n const selectedSet = useMemo(() => new Set(picker.selectedKeys), [picker.selectedKeys]);\n const selectedCount = picker.selectedKeys.length;\n const isSearchActive = query.trim().length > 0;\n const groupedOptions = useMemo<ChatSkillPickerOptionGroup[] | null>(() => {\n if (isSearchActive) {\n return null;\n }\n const groups = picker.groups?.filter((group) => group.options.length > 0) ?? [];\n return groups.length > 0 ? groups : null;\n }, [isSearchActive, picker.groups]);\n const visibleOptions = useMemo(() => {\n if (groupedOptions) {\n return groupedOptions.flatMap((group) => group.options);\n }\n return filterOptions(picker.options, query);\n }, [groupedOptions, picker.options, query]);\n\n useEffect(() => {\n setActiveIndex(0);\n }, [query]);\n\n useEffect(() => {\n setActiveIndex((current) => {\n if (visibleOptions.length === 0) {\n return 0;\n }\n return Math.min(current, visibleOptions.length - 1);\n });\n }, [visibleOptions.length]);\n\n useActiveItemScroll({\n containerRef: listRef,\n activeIndex,\n itemCount: visibleOptions.length,\n isEnabled: visibleOptions.length > 0,\n getItemSelector: (index) => `[data-skill-index=\"${index}\"]`\n });\n\n const onToggleOption = (optionKey: string) => {\n if (selectedSet.has(optionKey)) {\n picker.onSelectedKeysChange(picker.selectedKeys.filter((item) => item !== optionKey));\n return;\n }\n picker.onSelectedKeysChange([...picker.selectedKeys, optionKey]);\n };\n\n const onSearchKeyDown: KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (visibleOptions.length === 0) {\n return;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n setActiveIndex((current) => Math.min(current + 1, visibleOptions.length - 1));\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n setActiveIndex((current) => Math.max(current - 1, 0));\n return;\n }\n\n if (event.key === 'Enter') {\n event.preventDefault();\n const activeOption = visibleOptions[activeIndex];\n if (activeOption) {\n onToggleOption(activeOption.key);\n }\n }\n };\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-haspopup=\"listbox\"\n aria-label={picker.title}\n 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\"\n >\n <BrainCircuit className=\"h-4 w-4\" />\n <span className=\"nextclaw-chat-skill-picker-label hidden sm:inline [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden\">\n {picker.title}\n </span>\n {selectedCount > 0 ? (\n <span className=\"absolute -right-1 -top-1 flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1 text-[10px] font-semibold leading-none text-white shadow-sm sm:static sm:ml-0.5 sm:bg-primary/10 sm:text-primary sm:shadow-none\">\n {selectedCount}\n </span>\n ) : null}\n </button>\n </PopoverTrigger>\n <PopoverContent\n side=\"top\"\n align=\"start\"\n className=\"flex w-[min(360px,calc(100vw-1rem))] flex-col overflow-hidden p-0\"\n style={{ maxHeight: SKILL_PICKER_MAX_HEIGHT }}\n >\n <div className=\"shrink-0 space-y-2 border-b border-border px-4 py-3\">\n <div className=\"text-sm font-semibold text-foreground\">{picker.title}</div>\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-3 top-2.5 h-3.5 w-3.5 text-muted-foreground/70\" />\n <Input\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={onSearchKeyDown}\n placeholder={picker.searchPlaceholder}\n role=\"combobox\"\n aria-controls={listId}\n aria-expanded=\"true\"\n aria-autocomplete=\"list\"\n aria-activedescendant={visibleOptions[activeIndex] ? `${listId}-option-${activeIndex}` : undefined}\n className=\"h-8 rounded-lg pl-8 text-xs\"\n />\n </div>\n </div>\n\n <div\n ref={listRef}\n id={listId}\n role=\"listbox\"\n aria-multiselectable=\"true\"\n className=\"custom-scrollbar min-h-0 flex-1 overflow-y-auto overscroll-contain\"\n >\n {picker.isLoading ? (\n <div className=\"p-4 text-xs text-muted-foreground\">{picker.loadingLabel}</div>\n ) : visibleOptions.length === 0 ? (\n <div className=\"p-4 text-center text-xs text-muted-foreground\">{picker.emptyLabel}</div>\n ) : (\n <div className=\"py-1\">\n {(() => {\n const groups = groupedOptions ?? [{ key: 'all-skills', options: visibleOptions }];\n let visibleIndex = 0;\n return groups.map((group) => (\n <div key={group.key}>\n {group.label ? (\n <div className=\"px-4 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n {group.label}\n </div>\n ) : null}\n {group.options.map((option) => {\n const index = visibleIndex;\n visibleIndex += 1;\n const isSelected = selectedSet.has(option.key);\n const isActive = index === activeIndex;\n return (\n <div\n key={option.key}\n id={`${listId}-option-${index}`}\n role=\"option\"\n aria-selected={isSelected}\n data-skill-index={index}\n onMouseEnter={() => setActiveIndex(index)}\n className={`flex w-full items-center gap-3 px-4 py-2.5 text-left transition-colors ${\n isActive ? 'bg-accent' : 'hover:bg-accent'\n }`}\n >\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <Puzzle className=\"h-4 w-4\" />\n </div>\n <div className=\"min-w-0 flex-1 select-text\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"truncate text-sm text-foreground\">{option.label}</span>\n {option.badgeLabel ? (\n <span className=\"shrink-0 rounded-full bg-primary/10 px-1.5 py-0.5 text-[10px] font-medium text-primary\">\n {option.badgeLabel}\n </span>\n ) : null}\n </div>\n <div className=\"mt-0.5 truncate text-xs text-muted-foreground\">{option.description || option.key}</div>\n </div>\n <div className=\"ml-3 shrink-0\">\n <button\n type=\"button\"\n aria-label={`${isSelected ? 'Remove' : 'Add'} ${option.label}`}\n onClick={() => onToggleOption(option.key)}\n className={\n isSelected\n ? 'inline-flex h-5 w-5 items-center justify-center rounded-full bg-primary text-white'\n : 'inline-flex h-5 w-5 items-center justify-center rounded-full border border-border bg-card'\n }\n >\n {isSelected ? <Check className=\"h-3 w-3\" /> : null}\n </button>\n </div>\n </div>\n );\n })}\n </div>\n ));\n })()}\n </div>\n )}\n </div>\n\n {picker.manageHref && picker.manageLabel ? (\n <div className=\"shrink-0 border-t border-border px-4 py-2.5\">\n <a\n href={picker.manageHref}\n className=\"inline-flex items-center gap-1.5 text-xs font-medium text-primary transition-colors hover:text-primary/80\"\n >\n {picker.manageLabel}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n </div>\n ) : null}\n </PopoverContent>\n </Popover>\n );\n}\n","import {\n ChatUiPrimitives,\n createChatPopoverAvailableHeightLimit,\n createChatSelectAvailableHeightLimit,\n} from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport type {\n ChatInputBarToolbarProps,\n ChatToolbarAccessoryIcon,\n ChatToolbarIcon,\n ChatToolbarSelect\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { Brain, Check, ChevronDown, Paperclip, Search, Sparkles, Star } from 'lucide-react';\nimport { useMemo, useState } from 'react';\nimport { ChatInputBarActions } from './chat-input-bar-actions';\nimport { ChatInputBarSkillPicker } from './chat-input-bar-skill-picker';\n\nfunction ToolbarIcon({ icon }: { icon?: ChatToolbarIcon }) {\n return icon === 'sparkles'\n ? <Sparkles className=\"h-3.5 w-3.5 shrink-0 text-primary\" />\n : icon === 'brain'\n ? <Brain className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n : null;\n}\n\nfunction AccessoryIcon({ icon }: { icon?: ChatToolbarAccessoryIcon }) {\n return icon === 'paperclip' ? <Paperclip className=\"h-4 w-4\" /> : <ToolbarIcon icon={icon} />;\n}\n\nconst TRIGGER_WIDTH_BY_KEY: Record<string, string> = {\n model: 'min-w-0 max-w-[18rem]',\n 'session-type': 'shrink-0',\n thinking: 'shrink-0'\n};\n\nconst CONTENT_WIDTH_BY_KEY: Record<string, string> = {\n model: 'w-[min(18rem,calc(100vw-1rem))] sm:w-[320px]',\n 'session-type': 'w-[220px]',\n thinking: 'w-[180px]'\n};\n\nconst TOOLBAR_POPOVER_MAX_HEIGHT = createChatPopoverAvailableHeightLimit('18rem');\nconst TOOLBAR_SELECT_MAX_HEIGHT = createChatSelectAvailableHeightLimit('18rem');\n\nfunction resolveMobileSelectedLabel(item: ChatToolbarSelect): string | undefined {\n return item.key === 'model' && item.selectedLabel\n ? item.selectedLabel.split('/').slice(1).join('/').trim() || item.selectedLabel\n : item.selectedLabel;\n}\n\nfunction buildSelectGroups(item: ChatToolbarSelect) {\n return item.groups?.filter((group) => group.options.length > 0) ??\n (item.options.length > 0 ? [{ key: `${item.key}-default`, options: item.options }] : []);\n}\n\nfunction ToolbarSelectTriggerContent({ item }: { item: ChatToolbarSelect }) {\n const mobileSelectedLabel = resolveMobileSelectedLabel(item);\n if (item.selectedLabel) {\n return (\n <div className=\"flex min-w-0 items-center gap-2 text-left\">\n <ToolbarIcon icon={item.icon} />\n <span className=\"nextclaw-chat-toolbar-mobile-label truncate sm:hidden [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden\">{mobileSelectedLabel}</span>\n <span className=\"nextclaw-chat-toolbar-label hidden truncate sm:inline [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden\">{item.selectedLabel}</span>\n </div>\n );\n }\n if (item.loading) {\n return <div className=\"h-3 w-24 animate-pulse rounded bg-muted\" />;\n }\n return <span className=\"truncate\">{item.placeholder}</span>;\n}\n\nfunction ToolbarSelectOptionContent({\n option\n}: {\n option: ChatToolbarSelect['options'][number];\n}) {\n return option.description ? (\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <span className=\"truncate text-xs font-semibold text-foreground\">{option.label}</span>\n <span className=\"truncate text-[11px] text-muted-foreground\">{option.description}</span>\n </div>\n ) : (\n <span className=\"truncate text-xs font-semibold text-foreground\">{option.label}</span>\n );\n}\n\nfunction ToolbarSearchableSelect({ item }: { item: ChatToolbarSelect }) {\n const { Input, Popover, PopoverContent, PopoverTrigger, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } =\n ChatUiPrimitives;\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const groups = buildSelectGroups(item);\n const filteredGroups = useMemo(() => {\n const normalizedQuery = query.trim().toLowerCase();\n if (!normalizedQuery) {\n return groups;\n }\n return groups\n .map((group) => ({\n ...group,\n options: group.options.filter((option) =>\n [option.label, option.value, option.description]\n .filter((value): value is string => Boolean(value))\n .some((value) => value.toLowerCase().includes(normalizedQuery)),\n ),\n }))\n .filter((group) => group.options.length > 0);\n }, [groups, query]);\n const hasOptions = groups.some((group) => group.options.length > 0);\n const hasFilteredOptions = filteredGroups.some((group) => group.options.length > 0);\n const action = item.optionAction;\n const activeValues = new Set(action?.activeValues ?? []);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-label={item.selectedLabel ? `${item.placeholder}: ${item.selectedLabel}` : item.placeholder}\n disabled={item.disabled}\n 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] ?? ''}`}\n >\n <ToolbarSelectTriggerContent item={item} />\n <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\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n className={`flex flex-col overflow-hidden p-2 ${CONTENT_WIDTH_BY_KEY[item.key] ?? ''}`}\n style={{ maxHeight: TOOLBAR_POPOVER_MAX_HEIGHT }}\n >\n <div className=\"relative mb-2 shrink-0\">\n <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\" />\n <Input\n value={query}\n onChange={(event) => setQuery(event.currentTarget.value)}\n placeholder={item.search?.placeholder ?? item.placeholder}\n className=\"h-8 rounded-lg pl-8 text-xs\"\n />\n </div>\n {!hasOptions ? (\n item.loading ? (\n <div className=\"space-y-2 px-2 py-1\">\n <div className=\"h-3 w-36 animate-pulse rounded bg-muted\" />\n <div className=\"h-3 w-28 animate-pulse rounded bg-muted\" />\n <div className=\"h-3 w-32 animate-pulse rounded bg-muted\" />\n </div>\n ) : item.emptyLabel ? (\n <div className=\"px-2 py-1 text-xs text-muted-foreground\">{item.emptyLabel}</div>\n ) : null\n ) : null}\n {hasOptions && !hasFilteredOptions ? (\n <div className=\"px-2 py-1 text-xs text-muted-foreground\">{item.search?.emptyLabel ?? item.emptyLabel}</div>\n ) : null}\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n {filteredGroups.map((group, groupIndex) => (\n <div key={group.key} className={groupIndex > 0 ? 'border-t border-border pt-1' : undefined}>\n {group.label ? (\n <div className=\"px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground\">{group.label}</div>\n ) : null}\n {group.options.map((option) => {\n const isSelected = item.value === option.value;\n const isActive = activeValues.has(option.value);\n const actionLabel = isActive ? action?.activeLabel : action?.inactiveLabel;\n return (\n <div key={option.value} className=\"group flex items-center gap-1 rounded-md hover:bg-accent\">\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 items-center gap-2 rounded-md px-2 py-2 text-left\"\n onClick={() => {\n item.onValueChange(option.value);\n setOpen(false);\n setQuery('');\n }}\n >\n <div className=\"min-w-0 flex-1\">\n <ToolbarSelectOptionContent option={option} />\n </div>\n {isSelected ? <Check className=\"h-4 w-4 shrink-0 text-primary\" /> : null}\n </button>\n {action && actionLabel ? (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={actionLabel}\n aria-pressed={isActive}\n 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-foreground focus:outline-none focus:ring-1 focus:ring-primary/40\"\n onClick={(event) => {\n event.stopPropagation();\n action.onToggle(option.value, !isActive);\n }}\n >\n <Star className={`h-3.5 w-3.5 ${isActive ? 'fill-current text-foreground' : ''}`} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"left\">\n <p className=\"text-xs\">{actionLabel}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction ToolbarSelect({ item }: { item: ChatToolbarSelect }) {\n if (item.search) {\n return <ToolbarSearchableSelect item={item} />;\n }\n const { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue } =\n ChatUiPrimitives;\n const groups = buildSelectGroups(item);\n const hasOptions = groups.some((group) => group.options.length > 0);\n\n return (\n <Select value={item.value} onValueChange={item.onValueChange} disabled={item.disabled}>\n <SelectTrigger\n aria-label={item.selectedLabel ? `${item.placeholder}: ${item.selectedLabel}` : item.placeholder}\n title={item.selectedLabel}\n 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] ?? ''}`}\n >\n {item.selectedLabel || item.loading ? <ToolbarSelectTriggerContent item={item} /> : <SelectValue placeholder={item.placeholder} />}\n </SelectTrigger>\n <SelectContent\n className={CONTENT_WIDTH_BY_KEY[item.key] ?? ''}\n style={{ maxHeight: TOOLBAR_SELECT_MAX_HEIGHT }}\n >\n {!hasOptions ? (\n item.loading ? (\n <div className=\"space-y-2 px-3 py-2\">\n <div className=\"h-3 w-36 animate-pulse rounded bg-muted\" />\n <div className=\"h-3 w-28 animate-pulse rounded bg-muted\" />\n <div className=\"h-3 w-32 animate-pulse rounded bg-muted\" />\n </div>\n ) : item.emptyLabel ? (\n <div className=\"px-3 py-2 text-xs text-muted-foreground\">{item.emptyLabel}</div>\n ) : null\n ) : null}\n {groups.map((group, groupIndex) => (\n <div key={group.key}>\n {groupIndex > 0 ? <SelectSeparator /> : null}\n <SelectGroup>\n {group.label ? <SelectLabel>{group.label}</SelectLabel> : null}\n {group.options.map((option) => (\n <SelectItem key={option.value} value={option.value} className=\"py-2\">\n <ToolbarSelectOptionContent option={option} />\n </SelectItem>\n ))}\n </SelectGroup>\n </div>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\nexport function ChatInputBarToolbar({\n actions,\n accessories,\n selects,\n skillPicker,\n trailingSelects = [],\n}: ChatInputBarToolbarProps) {\n const { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } = ChatUiPrimitives;\n return (\n <div className=\"flex flex-wrap items-end justify-between gap-2 px-3 pb-3\">\n <div className=\"flex min-w-[12rem] flex-1 flex-wrap items-center gap-1 overflow-hidden\">\n {skillPicker ? <ChatInputBarSkillPicker picker={skillPicker} /> : null}\n {selects.map((item) => (\n <ToolbarSelect key={item.key} item={item} />\n ))}\n {accessories?.map((item) => {\n const button = (\n <button\n type=\"button\"\n 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 ${\n item.iconOnly ? 'h-8 w-8 justify-center px-0' : 'gap-1.5 px-3'\n }`}\n onClick={item.onClick}\n disabled={item.disabled}\n aria-label={item.label}\n >\n <AccessoryIcon icon={item.icon} />\n {item.iconOnly ? null : <span>{item.label}</span>}\n </button>\n );\n if (!item.tooltip) {\n return <div key={item.key}>{button}</div>;\n }\n const trigger = item.disabled ? <span className=\"inline-flex\">{button}</span> : button;\n return (\n <TooltipProvider key={item.key}>\n <Tooltip>\n <TooltipTrigger asChild>{trigger}</TooltipTrigger>\n <TooltipContent side=\"top\">\n <p className=\"text-xs\">{item.tooltip}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n })}\n </div>\n <div className=\"flex shrink-0 items-end gap-1\">\n {trailingSelects.length > 0 ? (\n <div className=\"nextclaw-chat-toolbar-trailing-selects flex min-w-0 items-center gap-1\">\n {trailingSelects.map((item) => (\n <ToolbarSelect key={item.key} item={item} />\n ))}\n </div>\n ) : null}\n <ChatInputBarActions {...actions} />\n </div>\n </div>\n );\n}\n","import {\n $applyNodeReplacement,\n DecoratorNode,\n type EditorConfig,\n type LexicalEditor,\n type LexicalNode,\n type NodeKey,\n type SerializedLexicalNode,\n} from 'lexical';\nimport type { ReactElement } from 'react';\nimport { AppWindow, ImageIcon, Puzzle } from 'lucide-react';\nimport { CHAT_COMPOSER_TOKEN_PLACEHOLDER } from '@agent-chat-ui/components/chat/ui/chat-input-bar/chat-composer.utils';\nimport type { ChatComposerTokenKind } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\ntype SerializedChatComposerTokenNode = SerializedLexicalNode & {\n composerId: string;\n label: string;\n tokenKey: string;\n tokenKind: ChatComposerTokenKind;\n type: 'chat-composer-token';\n version: 1;\n};\n\nfunction buildTokenClassName(tokenKind: ChatComposerTokenKind): string {\n if (tokenKind === 'file') {\n return [\n 'mx-[2px]',\n 'inline-flex',\n 'h-7',\n 'max-w-[min(100%,17rem)]',\n 'items-center',\n 'gap-1.5',\n 'rounded-lg',\n 'border',\n 'border-border',\n 'bg-muted',\n 'px-2',\n 'align-baseline',\n 'text-foreground',\n 'transition-[border-color,background-color,box-shadow,color]',\n 'duration-150',\n ].join(' ');\n }\n\n return [\n 'mx-[2px]',\n 'inline-flex',\n 'h-7',\n 'max-w-full',\n 'items-center',\n 'gap-1.5',\n 'rounded-lg',\n 'border',\n 'border-primary/12',\n 'bg-primary/8',\n 'px-2',\n 'align-baseline',\n 'text-[11px]',\n 'font-medium',\n 'text-primary',\n 'transition',\n ].join(' ');\n}\n\nfunction ChatComposerTokenChip({\n label,\n tokenKind,\n}: {\n label: string;\n tokenKind: ChatComposerTokenKind;\n}): ReactElement {\n return (\n <>\n <span\n className={\n tokenKind === 'file'\n ? 'inline-flex h-4.5 w-4.5 shrink-0 items-center justify-center rounded-md bg-card text-muted-foreground ring-1 ring-border'\n : 'inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center text-primary/70'\n }\n >\n {tokenKind === 'file' ? (\n <ImageIcon aria-hidden=\"true\" className=\"h-3 w-3\" />\n ) : tokenKind === 'panel_app' ? (\n <AppWindow aria-hidden=\"true\" className=\"h-3 w-3\" />\n ) : (\n <Puzzle aria-hidden=\"true\" className=\"h-3 w-3\" />\n )}\n </span>\n <span\n className={\n tokenKind === 'file'\n ? 'min-w-0 flex-1 truncate text-[12px] font-medium text-foreground'\n : 'truncate'\n }\n >\n {label}\n </span>\n </>\n );\n}\n\nexport class ChatComposerTokenNode extends DecoratorNode<ReactElement> {\n __composerId: string;\n __tokenKind: ChatComposerTokenKind;\n __tokenKey: string;\n __label: string;\n\n static getType(): string {\n return 'chat-composer-token';\n }\n\n static clone(node: ChatComposerTokenNode): ChatComposerTokenNode {\n return new ChatComposerTokenNode(\n node.__composerId,\n node.__tokenKind,\n node.__tokenKey,\n node.__label,\n node.__key,\n );\n }\n\n static importJSON(serializedNode: SerializedChatComposerTokenNode): ChatComposerTokenNode {\n return $createChatComposerTokenNode({\n composerId: serializedNode.composerId,\n label: serializedNode.label,\n tokenKey: serializedNode.tokenKey,\n tokenKind: serializedNode.tokenKind,\n });\n }\n\n constructor(\n composerId: string,\n tokenKind: ChatComposerTokenKind,\n tokenKey: string,\n label: string,\n key?: NodeKey,\n ) {\n super(key);\n this.__composerId = composerId;\n this.__tokenKind = tokenKind;\n this.__tokenKey = tokenKey;\n this.__label = label;\n }\n\n private readonly applyTokenDom = (element: HTMLElement): void => {\n element.contentEditable = 'false';\n element.dataset.composerNodeId = this.__composerId;\n element.dataset.composerNodeType = 'token';\n element.dataset.composerTokenKind = this.__tokenKind;\n element.dataset.composerTokenKey = this.__tokenKey;\n element.dataset.composerLabel = this.__label;\n element.title = this.__label;\n element.className = buildTokenClassName(this.__tokenKind);\n };\n\n createDOM = (_config: EditorConfig, _editor: LexicalEditor): HTMLElement => {\n const element = document.createElement('span');\n this.applyTokenDom(element);\n return element;\n };\n\n updateDOM = (_prevNode: ChatComposerTokenNode, dom: HTMLElement): false => {\n this.applyTokenDom(dom);\n return false;\n };\n\n decorate = (): ReactElement => {\n return <ChatComposerTokenChip label={this.__label} tokenKind={this.__tokenKind} />;\n };\n\n exportJSON = (): SerializedChatComposerTokenNode => {\n return {\n composerId: this.__composerId,\n label: this.__label,\n tokenKey: this.__tokenKey,\n tokenKind: this.__tokenKind,\n type: 'chat-composer-token',\n version: 1,\n };\n };\n\n getComposerId = (): string => {\n return this.getLatest().__composerId;\n };\n\n getTokenKind = (): ChatComposerTokenKind => {\n return this.getLatest().__tokenKind;\n };\n\n getTokenKey = (): string => {\n return this.getLatest().__tokenKey;\n };\n\n getLabel = (): string => {\n return this.getLatest().__label;\n };\n\n getTextContent = (): string => {\n return CHAT_COMPOSER_TOKEN_PLACEHOLDER;\n };\n\n isInline = (): true => {\n return true;\n };\n\n isIsolated = (): true => {\n return true;\n };\n\n isKeyboardSelectable = (): boolean => {\n return false;\n };\n}\n\nexport function $createChatComposerTokenNode(params: {\n composerId: string;\n label: string;\n tokenKey: string;\n tokenKind: ChatComposerTokenKind;\n}): ChatComposerTokenNode {\n const { composerId, label, tokenKey, tokenKind } = params;\n return $applyNodeReplacement(\n new ChatComposerTokenNode(composerId, tokenKind, tokenKey, label),\n );\n}\n\nexport function $isChatComposerTokenNode(\n node: LexicalNode | null | undefined,\n): node is ChatComposerTokenNode {\n return node instanceof ChatComposerTokenNode;\n}\n","import {\n $createLineBreakNode,\n $createParagraphNode,\n $createRangeSelection,\n $createTextNode,\n $getRoot,\n $getSelection,\n $isElementNode,\n $isRangeSelection,\n $isTextNode,\n $setSelection,\n type EditorState,\n type ElementPoint,\n type LexicalEditor,\n type LexicalNode,\n type NodeKey,\n type PointType,\n} from 'lexical';\nimport type { ChatComposerNode, ChatComposerSelection } from '../../../view-models/chat-ui.types';\nimport { normalizeChatComposerNodes } from '../chat-composer.utils';\nimport {\n $createChatComposerTokenNode,\n $isChatComposerTokenNode,\n type ChatComposerTokenNode,\n} from './chat-composer-token-node';\n\ntype LeafDescriptor =\n | {\n index: number;\n key: NodeKey;\n length: number;\n node: LexicalNode;\n start: number;\n type: 'linebreak' | 'token';\n }\n | {\n index: number;\n key: NodeKey;\n length: number;\n node: LexicalNode;\n start: number;\n text: string;\n type: 'text';\n };\n\ntype SelectionPointDescriptor = {\n key: NodeKey;\n offset: number;\n type: 'element' | 'text';\n};\n\nexport type ChatComposerEditorSnapshot = {\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n};\n\nfunction getComposerLeafDescriptors(): {\n descriptors: LeafDescriptor[];\n paragraphKey: NodeKey;\n paragraphSize: number;\n totalLength: number;\n} {\n const root = $getRoot();\n const paragraph = root.getFirstChild();\n if (!$isElementNode(paragraph)) {\n return {\n descriptors: [],\n paragraphKey: root.getKey(),\n paragraphSize: 0,\n totalLength: 0,\n };\n }\n\n const children = paragraph.getChildren();\n const descriptors: LeafDescriptor[] = [];\n let cursor = 0;\n\n for (const [index, child] of children.entries()) {\n if ($isTextNode(child)) {\n const text = child.getTextContent();\n descriptors.push({\n index,\n key: child.getKey(),\n length: text.length,\n node: child,\n start: cursor,\n text,\n type: 'text',\n });\n cursor += text.length;\n continue;\n }\n\n if ($isChatComposerTokenNode(child)) {\n descriptors.push({\n index,\n key: child.getKey(),\n length: 1,\n node: child,\n start: cursor,\n type: 'token',\n });\n cursor += 1;\n continue;\n }\n\n descriptors.push({\n index,\n key: child.getKey(),\n length: child.getTextContent().length,\n node: child,\n start: cursor,\n type: 'linebreak',\n });\n cursor += child.getTextContent().length;\n }\n\n return {\n descriptors,\n paragraphKey: paragraph.getKey(),\n paragraphSize: children.length,\n totalLength: cursor,\n };\n}\n\nfunction buildSelectionPointFromOffset(offset: number): SelectionPointDescriptor {\n const { descriptors, paragraphKey, paragraphSize, totalLength } = getComposerLeafDescriptors();\n const boundedOffset = Math.max(0, Math.min(offset, totalLength));\n\n if (descriptors.length === 0) {\n return {\n key: paragraphKey,\n offset: 0,\n type: 'element',\n };\n }\n\n for (const descriptor of descriptors) {\n const end = descriptor.start + descriptor.length;\n\n if (descriptor.type === 'text' && boundedOffset >= descriptor.start && boundedOffset <= end) {\n return {\n key: descriptor.key,\n offset: boundedOffset - descriptor.start,\n type: 'text',\n };\n }\n\n if (descriptor.type !== 'text') {\n if (boundedOffset === descriptor.start) {\n return {\n key: paragraphKey,\n offset: descriptor.index,\n type: 'element',\n };\n }\n\n if (boundedOffset === end) {\n const nextDescriptor = descriptors[descriptor.index + 1];\n if (nextDescriptor?.type === 'text' && nextDescriptor.length === 0) {\n return {\n key: nextDescriptor.key,\n offset: 0,\n type: 'text',\n };\n }\n return {\n key: paragraphKey,\n offset: descriptor.index + 1,\n type: 'element',\n };\n }\n }\n }\n\n return {\n key: paragraphKey,\n offset: paragraphSize,\n type: 'element',\n };\n}\n\nfunction getOffsetFromElementPoint(point: ElementPoint): number {\n const { descriptors, paragraphKey, totalLength } = getComposerLeafDescriptors();\n\n if (point.key === paragraphKey) {\n const previous = descriptors[point.offset - 1];\n return previous ? previous.start + previous.length : 0;\n }\n\n const descriptor = descriptors.find((item) => item.key === point.key);\n if (!descriptor) {\n return totalLength;\n }\n\n return descriptor.start + Math.min(point.offset, descriptor.length);\n}\n\nfunction getOffsetFromPoint(point: PointType): number {\n if (point.type === 'element') {\n return getOffsetFromElementPoint(point);\n }\n\n const { descriptors, totalLength } = getComposerLeafDescriptors();\n const descriptor = descriptors.find((item) => item.key === point.key);\n if (!descriptor) {\n return totalLength;\n }\n\n return descriptor.start + Math.min(point.offset, descriptor.length);\n}\n\nfunction readNodesFromEditor(): ChatComposerNode[] {\n const { descriptors } = getComposerLeafDescriptors();\n const nextNodes: ChatComposerNode[] = [];\n let textBuffer = '';\n let textId = '';\n\n const flushTextBuffer = (): void => {\n if (textBuffer.length === 0) {\n return;\n }\n nextNodes.push({\n id: textId,\n type: 'text',\n text: textBuffer,\n });\n textBuffer = '';\n textId = '';\n };\n\n for (const descriptor of descriptors) {\n if (descriptor.type === 'text') {\n if (textBuffer.length === 0) {\n textId = descriptor.key;\n }\n textBuffer += descriptor.text;\n continue;\n }\n\n if (descriptor.type === 'linebreak') {\n if (textBuffer.length === 0) {\n textId = descriptor.key;\n }\n textBuffer += '\\n';\n continue;\n }\n\n flushTextBuffer();\n const tokenNode = descriptor.node as ChatComposerTokenNode;\n nextNodes.push({\n id: tokenNode.getComposerId(),\n label: tokenNode.getLabel(),\n tokenKey: tokenNode.getTokenKey(),\n tokenKind: tokenNode.getTokenKind(),\n type: 'token',\n });\n }\n\n flushTextBuffer();\n return normalizeChatComposerNodes(nextNodes);\n}\n\nexport function readChatComposerSnapshotFromEditorState(\n editorState: EditorState,\n): ChatComposerEditorSnapshot {\n return editorState.read(() => {\n const selection = $getSelection();\n const nodes = readNodesFromEditor();\n\n if (!$isRangeSelection(selection)) {\n return {\n nodes,\n selection: null,\n };\n }\n\n return {\n nodes,\n selection: {\n start: Math.min(getOffsetFromPoint(selection.anchor), getOffsetFromPoint(selection.focus)),\n end: Math.max(getOffsetFromPoint(selection.anchor), getOffsetFromPoint(selection.focus)),\n },\n };\n });\n}\n\nexport function writeChatComposerStateToLexicalRoot(\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n): void {\n const root = $getRoot();\n root.clear();\n\n const paragraph = $createParagraphNode();\n root.append(paragraph);\n\n for (const node of normalizeChatComposerNodes(nodes)) {\n if (node.type === 'token') {\n paragraph.append(\n $createChatComposerTokenNode({\n composerId: node.id,\n label: node.label,\n tokenKey: node.tokenKey,\n tokenKind: node.tokenKind,\n }),\n );\n continue;\n }\n\n const parts = node.text.split('\\n');\n for (const [index, part] of parts.entries()) {\n if (part.length > 0) {\n paragraph.append($createTextNode(part));\n }\n if (index < parts.length - 1) {\n paragraph.append($createLineBreakNode());\n }\n }\n }\n\n if ($isChatComposerTokenNode(paragraph.getLastChild())) {\n paragraph.append($createTextNode(''));\n }\n\n if (!selection) {\n return;\n }\n\n const nextSelection = $createRangeSelection();\n const anchor = buildSelectionPointFromOffset(selection.start);\n const focus = buildSelectionPointFromOffset(selection.end);\n nextSelection.anchor.set(anchor.key, anchor.offset, anchor.type);\n nextSelection.focus.set(focus.key, focus.offset, focus.type);\n $setSelection(nextSelection);\n}\n\nexport function syncLexicalEditorFromChatComposerState(\n editor: LexicalEditor,\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n): void {\n editor.update(() => {\n writeChatComposerStateToLexicalRoot(nodes, selection);\n });\n}\n\nexport function syncLexicalSelectionFromChatComposerSelection(\n editor: LexicalEditor,\n selection: ChatComposerSelection,\n): void {\n editor.update(() => {\n const nextSelection = $createRangeSelection();\n const anchor = buildSelectionPointFromOffset(selection.start);\n const focus = buildSelectionPointFromOffset(selection.end);\n nextSelection.anchor.set(anchor.key, anchor.offset, anchor.type);\n nextSelection.focus.set(focus.key, focus.offset, focus.type);\n $setSelection(nextSelection);\n });\n}\n","import type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatComposerTokenKind,\n ChatInputSurfaceItem,\n ChatInputSurfaceTriggerSpec,\n ChatSkillPickerOption,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC,\n createChatComposerTextNode,\n createChatComposerTokenNode,\n extractChatComposerTokenKeys,\n getChatComposerNodeLength,\n normalizeChatComposerNodes,\n removeChatComposerTokenNodes,\n replaceChatComposerRange,\n resolveChatComposerActiveInputSurfaceTrigger,\n resolveChatComposerSlashTrigger,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/chat-composer.utils';\nimport type { ChatComposerEditorSnapshot } from './chat-composer-lexical-editor-state';\n\nfunction getDocumentLength(nodes: ChatComposerNode[]): number {\n return nodes.reduce((sum, node) => sum + getChatComposerNodeLength(node), 0);\n}\n\nfunction insertToken(params: {\n label: string;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n tokenKey: string;\n tokenKind: ChatComposerTokenKind;\n trigger?: { end: number; query: string; start: number } | null;\n}): ChatComposerEditorSnapshot {\n const { label, nodes, selection, tokenKey, tokenKind, trigger } = params;\n const documentLength = getDocumentLength(nodes);\n const [selectionStart, selectionEnd] = selection ? [Math.min(selection.start, selection.end), Math.max(selection.start, selection.end)] : [documentLength, documentLength];\n const replaceStart = trigger?.start ?? selectionStart;\n const replaceEnd = trigger?.end ?? selectionEnd;\n\n return {\n nodes: replaceChatComposerRange(\n nodes,\n replaceStart,\n replaceEnd,\n [\n createChatComposerTokenNode({\n label,\n tokenKey,\n tokenKind,\n }),\n ],\n ),\n selection: {\n start: replaceStart + 1,\n end: replaceStart + 1,\n },\n };\n}\n\nexport function insertChatComposerTokenIntoChatComposer(params: {\n label: string;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n tokenKey: string;\n tokenKind: ChatComposerTokenKind;\n triggerSpecs?: readonly ChatInputSurfaceTriggerSpec[];\n}): ChatComposerEditorSnapshot {\n const { label, nodes, selection, tokenKey, tokenKind, triggerSpecs } = params;\n\n if (extractChatComposerTokenKeys(nodes, tokenKind).includes(tokenKey)) {\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection,\n };\n }\n\n return insertToken({\n label,\n nodes,\n selection,\n tokenKey,\n tokenKind,\n trigger: resolveChatComposerActiveInputSurfaceTrigger(\n nodes,\n selection,\n triggerSpecs ?? [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n ),\n });\n}\n\nexport function insertInputSurfaceItemIntoChatComposer(params: {\n item: ChatInputSurfaceItem;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n triggerSpecs?: readonly ChatInputSurfaceTriggerSpec[];\n}): ChatComposerEditorSnapshot {\n const { item, nodes, selection, triggerSpecs } = params;\n const tokenKind = item.tokenKind ?? (item.value ? 'skill' : undefined);\n const tokenKey = item.tokenKey ?? item.value;\n if (!tokenKind || !tokenKey) {\n const trigger = resolveChatComposerActiveInputSurfaceTrigger(\n nodes,\n selection,\n triggerSpecs ?? [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n );\n if (trigger) {\n return {\n nodes: normalizeChatComposerNodes(\n replaceChatComposerRange(nodes, trigger.start, trigger.end, []),\n ),\n selection: {\n start: trigger.start,\n end: trigger.start,\n },\n };\n }\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection,\n };\n }\n\n return insertChatComposerTokenIntoChatComposer({\n label: item.title,\n nodes,\n selection,\n tokenKey,\n tokenKind,\n triggerSpecs,\n });\n}\n\nexport function getChatComposerNodesSignature(nodes: ChatComposerNode[]): string {\n return nodes\n .map((node) =>\n node.type === 'text'\n ? `text:${node.text}`\n : `token:${node.tokenKind}:${node.tokenKey}:${node.label}`,\n )\n .join('\\u001f');\n}\n\nexport function replaceChatComposerSelectionWithText(params: {\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n text: string;\n}): ChatComposerEditorSnapshot {\n const { nodes, selection, text } = params;\n const documentLength = getDocumentLength(nodes);\n const [selectionStart, selectionEnd] = selection ? [Math.min(selection.start, selection.end), Math.max(selection.start, selection.end)] : [documentLength, documentLength];\n const nextOffset = selectionStart + text.length;\n\n return {\n nodes: replaceChatComposerRange(\n nodes,\n selectionStart,\n selectionEnd,\n [createChatComposerTextNode(text)],\n ),\n selection: {\n start: nextOffset,\n end: nextOffset,\n },\n };\n}\n\nexport function insertFileTokenIntoChatComposer(params: {\n label: string;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n tokenKey: string;\n}): ChatComposerEditorSnapshot {\n const { label, nodes, selection, tokenKey } = params;\n return insertToken({\n label,\n nodes,\n selection,\n tokenKey,\n tokenKind: 'file',\n });\n}\n\nexport function insertSkillTokenIntoChatComposer(params: {\n label: string;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n tokenKey: string;\n}): ChatComposerEditorSnapshot {\n const { label, nodes, selection, tokenKey } = params;\n\n if (extractChatComposerTokenKeys(nodes, 'skill').includes(tokenKey)) {\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection,\n };\n }\n\n return insertToken({\n label,\n nodes,\n selection,\n tokenKey,\n tokenKind: 'skill',\n trigger: resolveChatComposerSlashTrigger(nodes, selection),\n });\n}\n\nexport function syncSelectedSkillsIntoChatComposer(params: {\n nextKeys: string[];\n nodes: ChatComposerNode[];\n options: ChatSkillPickerOption[];\n selection: ChatComposerSelection | null;\n}): ChatComposerEditorSnapshot {\n const { nextKeys, nodes, options, selection } = params;\n const selectedSkillKeys = extractChatComposerTokenKeys(nodes, 'skill');\n const optionMap = new Map(options.map((option) => [option.key, option]));\n const addedKey = nextKeys.find((key) => !selectedSkillKeys.includes(key));\n\n if (addedKey) {\n const option = optionMap.get(addedKey);\n return insertSkillTokenIntoChatComposer({\n label: option?.label ?? addedKey,\n nodes,\n selection,\n tokenKey: addedKey,\n });\n }\n\n const removedKey = selectedSkillKeys.find((key) => !nextKeys.includes(key));\n if (!removedKey) {\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection,\n };\n }\n\n return {\n nodes: removeChatComposerTokenNodes(\n nodes,\n (node) => node.tokenKind === 'skill' && node.tokenKey === removedKey,\n ),\n selection,\n };\n}\n\nexport function deleteChatComposerContent(params: {\n direction: 'backward' | 'forward';\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n}): ChatComposerEditorSnapshot {\n const { direction, nodes, selection: currentSelection } = params;\n const documentLength = getDocumentLength(nodes);\n const [selectionStart, selectionEnd] = currentSelection ? [Math.min(currentSelection.start, currentSelection.end), Math.max(currentSelection.start, currentSelection.end)] : [documentLength, documentLength];\n let rangeStart = selectionStart;\n let rangeEnd = selectionEnd;\n\n if (rangeStart === rangeEnd) {\n if (direction === 'backward' && rangeStart > 0) {\n rangeStart -= 1;\n } else if (direction === 'forward' && rangeEnd < documentLength) {\n rangeEnd += 1;\n } else {\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection: { start: rangeStart, end: rangeEnd },\n };\n }\n }\n\n return {\n nodes: replaceChatComposerRange(nodes, rangeStart, rangeEnd, []),\n selection: {\n start: rangeStart,\n end: rangeStart,\n },\n };\n}\n","import type { FormEvent } from 'react';\nimport type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatInputBarActionsProps,\n ChatInputSurfaceTriggerChangeReason,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n deleteChatComposerContent,\n replaceChatComposerSelectionWithText,\n type ChatComposerEditorSnapshot,\n} from './chat-composer-lexical-adapter';\n\ntype ComposerActions = Pick<\n ChatInputBarActionsProps,\n 'onSend' | 'onStop' | 'isSending' | 'canStopGeneration'\n>;\n\ntype ChatComposerPublishOptions = {\n focusAfterSync?: boolean;\n forcePublish?: boolean;\n inputSurfaceReason?: ChatInputSurfaceTriggerChangeReason;\n};\n\ntype ChatComposerKeyboardAction =\n | { type: 'delete-content'; direction: 'backward' | 'forward' }\n | { type: 'insert-line-break' }\n | { type: 'noop' }\n | { type: 'send-message' }\n | { type: 'stop-generation' };\n\nexport function resolveLexicalComposerKeyboardAction(params: {\n canStopGeneration: boolean;\n isComposing: boolean;\n isSending: boolean;\n key: string;\n shiftKey: boolean;\n}): ChatComposerKeyboardAction {\n const {\n canStopGeneration,\n isComposing,\n isSending,\n key,\n shiftKey,\n } = params;\n\n if (key === 'Escape') {\n if (isSending && canStopGeneration) {\n return { type: 'stop-generation' };\n }\n return { type: 'noop' };\n }\n\n if (key === 'Enter' && shiftKey) {\n return { type: 'insert-line-break' };\n }\n\n if (key === 'Enter') {\n return { type: 'send-message' };\n }\n\n if (!isComposing && (key === 'Backspace' || key === 'Delete')) {\n return {\n type: 'delete-content',\n direction: key === 'Backspace' ? 'backward' : 'forward',\n };\n }\n\n return { type: 'noop' };\n}\n\nfunction getChatComposerContentSignature(nodes: ChatComposerNode[]): string {\n return JSON.stringify(\n nodes.map((node) =>\n node.type === 'text'\n ? { text: node.text, type: node.type }\n : {\n label: node.label,\n tokenKey: node.tokenKey,\n tokenKind: node.tokenKind,\n type: node.type,\n },\n ),\n );\n}\n\nexport function handleLexicalComposerBeforeInput(params: {\n disabled: boolean;\n event: FormEvent<HTMLDivElement>;\n isComposing: boolean;\n publishSnapshot: (snapshot: ChatComposerEditorSnapshot, options?: ChatComposerPublishOptions) => void;\n snapshotReader: () => {\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n };\n}): void {\n const { disabled, event, isComposing, publishSnapshot, snapshotReader } = params;\n const nativeEvent = event.nativeEvent as InputEvent;\n const shouldInsertText =\n nativeEvent.inputType === 'insertText' ||\n nativeEvent.inputType === 'insertReplacementText';\n\n if (\n disabled ||\n isComposing ||\n nativeEvent.isComposing ||\n !shouldInsertText ||\n !nativeEvent.data\n ) {\n return;\n }\n\n event.preventDefault();\n publishSnapshot(\n replaceChatComposerSelectionWithText({\n nodes: snapshotReader().nodes,\n selection: snapshotReader().selection,\n text: nativeEvent.data,\n }),\n { inputSurfaceReason: { type: 'insert-text', text: nativeEvent.data } },\n );\n}\n\nexport function handleLexicalComposerCompositionEnd(params: {\n compositionStartSnapshot?: ChatComposerEditorSnapshot | null;\n data: string;\n fallbackSnapshot: () => ChatComposerEditorSnapshot;\n publishSnapshot: (\n snapshot: ChatComposerEditorSnapshot,\n options?: ChatComposerPublishOptions,\n ) => void;\n snapshotReader: () => {\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n };\n}): void {\n const { compositionStartSnapshot, data, fallbackSnapshot, publishSnapshot, snapshotReader } = params;\n const currentSnapshot = snapshotReader();\n const editorSnapshot = fallbackSnapshot();\n const baseSnapshot = compositionStartSnapshot ?? currentSnapshot;\n const shouldUseEditorSnapshot =\n getChatComposerContentSignature(editorSnapshot.nodes) !==\n getChatComposerContentSignature(baseSnapshot.nodes);\n const snapshot = shouldUseEditorSnapshot\n ? editorSnapshot\n : data.length > 0\n ? replaceChatComposerSelectionWithText({\n nodes: baseSnapshot.nodes,\n selection: baseSnapshot.selection,\n text: data,\n })\n : editorSnapshot;\n publishSnapshot(snapshot, {\n forcePublish: true,\n inputSurfaceReason: { type: 'insert-text', text: data },\n });\n}\n\nexport function handleLexicalComposerKeyboardCommand(params: {\n actions: ComposerActions;\n publishSnapshot: (\n snapshot: ChatComposerEditorSnapshot,\n options?: ChatComposerPublishOptions,\n ) => void;\n snapshot: ChatComposerEditorSnapshot;\n nativeEvent: KeyboardEvent;\n}): boolean {\n const {\n actions,\n nativeEvent,\n publishSnapshot,\n snapshot,\n } = params;\n const action = resolveLexicalComposerKeyboardAction({\n canStopGeneration: actions.canStopGeneration,\n isComposing: nativeEvent.isComposing,\n isSending: actions.isSending,\n key: nativeEvent.key,\n shiftKey: nativeEvent.shiftKey,\n });\n\n if (action.type !== 'noop') {\n nativeEvent.preventDefault();\n }\n\n switch (action.type) {\n case 'stop-generation':\n void actions.onStop();\n return true;\n case 'insert-line-break':\n publishSnapshot(\n replaceChatComposerSelectionWithText({\n nodes: snapshot.nodes,\n selection: snapshot.selection,\n text: '\\n',\n }),\n { inputSurfaceReason: { type: 'insert-text', text: '\\n' } },\n );\n return true;\n case 'send-message':\n void actions.onSend();\n return true;\n case 'delete-content':\n publishSnapshot(\n deleteChatComposerContent({\n direction: action.direction,\n nodes: snapshot.nodes,\n selection: snapshot.selection,\n }),\n { inputSurfaceReason: { type: 'delete-content' } },\n );\n return true;\n case 'noop':\n return false;\n }\n}\n","import type { FormEvent } from 'react';\nimport type { EditorState, LexicalEditor } from 'lexical';\nimport {\n BLUR_COMMAND,\n COMMAND_PRIORITY_EDITOR,\n COMMAND_PRIORITY_HIGH,\n KEY_DOWN_COMMAND,\n SELECTION_CHANGE_COMMAND,\n mergeRegister,\n} from 'lexical';\nimport type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatInputBarActionsProps,\n ChatInputSurfaceItem,\n ChatInputSurfaceTriggerChangeReason,\n ChatInputSurfaceTriggerSpec,\n ChatSkillPickerOption,\n ChatSlashItem,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/chat-composer.utils';\nimport {\n type ChatComposerEditorSnapshot,\n getChatComposerNodesSignature,\n insertFileTokenIntoChatComposer,\n insertInputSurfaceItemIntoChatComposer,\n readChatComposerSnapshotFromEditorState,\n syncLexicalEditorFromChatComposerState,\n syncLexicalSelectionFromChatComposerSelection,\n syncSelectedSkillsIntoChatComposer,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-adapter';\nimport {\n handleLexicalComposerBeforeInput,\n handleLexicalComposerCompositionEnd,\n handleLexicalComposerKeyboardCommand,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-controller';\n\ntype ComposerActions = Pick<ChatInputBarActionsProps, 'onSend' | 'onStop' | 'isSending' | 'canStopGeneration'>;\n\nexport type ChatComposerLexicalOwnerCallbacks = {\n onInputSurfaceItemSelect?: (item: ChatInputSurfaceItem) => void;\n onInputSurfaceKeyDown?: (event: KeyboardEvent) => boolean;\n onInputSurfaceOpenChange?: (open: boolean) => void;\n onInputSurfaceSnapshotChange?: (\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n ) => void;\n onNodesChange: (nodes: ChatComposerNode[]) => void;\n};\n\ntype ComposerRuntime = {\n actions: ComposerActions;\n callbacks: ChatComposerLexicalOwnerCallbacks;\n fallbackNodes: ChatComposerNode[];\n};\n\ntype PublishOptions = {\n focusAfterSync?: boolean;\n forcePublish?: boolean;\n inputSurfaceReason?: ChatInputSurfaceTriggerChangeReason;\n};\n\nfunction createMutableRef<T>(value: T): { current: T } {\n return { current: value };\n}\n\nfunction getChatComposerDocumentLength(nodes: ChatComposerNode[]): number {\n return nodes.reduce((cursor, node) => cursor + (node.type === 'text' ? node.text.length : 1), 0);\n}\n\nexport class ChatComposerLexicalOwner {\n readonly isApplyingExternalUpdateRef = createMutableRef(false);\n readonly isComposingRef = createMutableRef(false);\n readonly pendingOwnerSignatureRef = createMutableRef<string | null>(null);\n readonly pendingSelectionRef = createMutableRef<ChatComposerSelection | null>(null);\n readonly selectionRef = createMutableRef<ChatComposerSelection | null>(null);\n readonly shouldFocusAfterSyncRef = createMutableRef(false);\n\n private readonly compositionStartSnapshotRef = createMutableRef<ChatComposerEditorSnapshot | null>(null);\n private readonly editorSignatureRef = createMutableRef('');\n private readonly lastPublishedSignatureRef = createMutableRef('');\n private readonly pendingInputSurfaceReasonRef = createMutableRef<ChatInputSurfaceTriggerChangeReason | null>(null);\n private editor: LexicalEditor | null = null;\n private runtime: ComposerRuntime | null = null;\n\n configureRuntime = (runtime: ComposerRuntime): void => {\n this.runtime = runtime;\n };\n\n bindEditor = (editor: LexicalEditor): (() => void) => {\n this.editor = editor;\n return () => {\n if (this.editor === editor) {\n this.editor = null;\n }\n };\n };\n\n registerEditorListeners = (editor: LexicalEditor): (() => void) => {\n return mergeRegister(\n editor.registerUpdateListener(({ editorState }) => {\n const runtime = this.getRuntime();\n this.handleEditorUpdate(editorState, runtime.callbacks);\n }),\n editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n const runtime = this.getRuntime();\n this.handleSelectionChange(editor, runtime.callbacks);\n return false;\n },\n COMMAND_PRIORITY_EDITOR,\n ),\n editor.registerCommand(\n BLUR_COMMAND,\n () => {\n const runtime = this.getRuntime();\n runtime.callbacks.onInputSurfaceOpenChange?.(false);\n return false;\n },\n COMMAND_PRIORITY_EDITOR,\n ),\n editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event) => {\n const runtime = this.getRuntime();\n return this.handleKeyDown({\n actions: runtime.actions,\n callbacks: runtime.callbacks,\n event,\n fallbackNodes: runtime.fallbackNodes,\n });\n },\n COMMAND_PRIORITY_HIGH,\n ),\n );\n };\n\n syncExternalState = (editor: LexicalEditor, nodes: ChatComposerNode[]): void => {\n if (this.isComposingRef.current) {\n return;\n }\n const nextSignature = getChatComposerNodesSignature(nodes);\n const pendingSelection = this.pendingSelectionRef.current;\n const pendingOwnerSignature = this.pendingOwnerSignatureRef.current;\n\n if (pendingOwnerSignature) {\n if (nextSignature === pendingOwnerSignature) {\n this.pendingOwnerSignatureRef.current = null;\n } else if (nextSignature !== this.editorSignatureRef.current) {\n return;\n }\n }\n\n const shouldSyncDocument = nextSignature !== this.editorSignatureRef.current;\n\n if (!shouldSyncDocument && !pendingSelection) {\n return;\n }\n\n this.startApplyingExternalUpdate();\n\n if (shouldSyncDocument) {\n syncLexicalEditorFromChatComposerState(editor, nodes, pendingSelection);\n this.editorSignatureRef.current = nextSignature;\n this.lastPublishedSignatureRef.current = nextSignature;\n } else if (pendingSelection) {\n syncLexicalSelectionFromChatComposerSelection(editor, pendingSelection);\n }\n\n if (pendingSelection) {\n this.selectionRef.current = pendingSelection;\n this.pendingSelectionRef.current = null;\n }\n\n if (this.shouldFocusAfterSyncRef.current) {\n this.shouldFocusAfterSyncRef.current = false;\n const targetSelection = this.selectionRef.current;\n editor.focus(() => {\n if (targetSelection) {\n syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);\n }\n });\n }\n };\n\n publishSnapshot = (\n snapshot: ChatComposerEditorSnapshot,\n callbacks: ChatComposerLexicalOwnerCallbacks,\n options?: PublishOptions,\n ): void => {\n this.selectionRef.current = snapshot.selection;\n this.pendingSelectionRef.current = snapshot.selection;\n\n if (options?.focusAfterSync) {\n this.shouldFocusAfterSyncRef.current = true;\n }\n\n const signature = getChatComposerNodesSignature(snapshot.nodes);\n const { editor } = this;\n this.pendingOwnerSignatureRef.current = signature;\n if (editor) {\n this.startApplyingExternalUpdate();\n syncLexicalEditorFromChatComposerState(editor, snapshot.nodes, snapshot.selection);\n this.editorSignatureRef.current = signature;\n }\n callbacks.onInputSurfaceSnapshotChange?.(\n snapshot.nodes,\n snapshot.selection,\n options?.inputSurfaceReason ?? { type: 'programmatic' },\n );\n\n if (options?.forcePublish || signature !== this.lastPublishedSignatureRef.current) {\n this.lastPublishedSignatureRef.current = signature;\n callbacks.onNodesChange(snapshot.nodes);\n }\n };\n\n focusComposer = (): void => {\n const { editor } = this;\n if (!editor) {\n return;\n }\n\n editor.getRootElement()?.focus({ preventScroll: true });\n const targetSelection = this.selectionRef.current;\n if (targetSelection) {\n syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);\n }\n editor.focus();\n };\n\n focusComposerAtEnd = (nodes?: ChatComposerNode[]): void => {\n const { editor } = this;\n if (!editor) {\n return;\n }\n const targetNodes = nodes ?? readChatComposerSnapshotFromEditorState(editor.getEditorState()).nodes;\n const end = getChatComposerDocumentLength(targetNodes);\n const targetSelection = { start: end, end };\n this.selectionRef.current = targetSelection;\n this.pendingSelectionRef.current = targetSelection;\n editor.getRootElement()?.focus({ preventScroll: true });\n if (nodes) {\n this.startApplyingExternalUpdate();\n const signature = getChatComposerNodesSignature(nodes);\n syncLexicalEditorFromChatComposerState(editor, nodes, targetSelection);\n this.editorSignatureRef.current = signature;\n this.lastPublishedSignatureRef.current = signature;\n } else {\n syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);\n }\n editor.focus(() => {\n syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);\n });\n };\n\n readComposerSnapshot = (fallbackNodes: ChatComposerNode[]): ChatComposerEditorSnapshot => {\n const { editor } = this;\n if (!editor) {\n return {\n nodes: fallbackNodes,\n selection: this.selectionRef.current,\n };\n }\n const snapshot = readChatComposerSnapshotFromEditorState(editor.getEditorState());\n this.selectionRef.current = snapshot.selection;\n return snapshot;\n };\n\n createHandle = () => {\n const insertInputSurfaceItem = (\n item: ChatInputSurfaceItem,\n triggerSpecs: readonly ChatInputSurfaceTriggerSpec[] = [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n ): void => {\n const { callbacks } = this.getRuntime();\n callbacks.onInputSurfaceItemSelect?.(item);\n this.publishRuntimeSnapshot(\n (snapshot) => insertInputSurfaceItemIntoChatComposer({\n item,\n nodes: snapshot.nodes,\n selection: snapshot.selection,\n triggerSpecs,\n }),\n { focusAfterSync: true },\n );\n };\n\n return {\n insertInputSurfaceItem,\n insertSlashItem: (item: ChatSlashItem): void => {\n insertInputSurfaceItem(item);\n },\n insertFileToken: (tokenKey: string, label: string): void => {\n this.publishRuntimeSnapshot(\n (snapshot) => insertFileTokenIntoChatComposer({\n label,\n nodes: snapshot.nodes,\n selection: snapshot.selection,\n tokenKey,\n }),\n { focusAfterSync: true },\n );\n },\n insertFileTokens: (tokens: Array<{ tokenKey: string; label: string }>): void => {\n this.publishRuntimeSnapshot(\n (snapshot) =>\n tokens.reduce(\n (nextSnapshot, token) =>\n insertFileTokenIntoChatComposer({\n label: token.label,\n nodes: nextSnapshot.nodes,\n selection: nextSnapshot.selection,\n tokenKey: token.tokenKey,\n }),\n snapshot,\n ),\n { focusAfterSync: true },\n );\n },\n focusComposer: this.focusComposer,\n focusComposerAtEnd: this.focusComposerAtEnd,\n syncSelectedSkills: (nextKeys: string[], options: ChatSkillPickerOption[]): void => {\n this.publishRuntimeSnapshot(\n (snapshot) => syncSelectedSkillsIntoChatComposer({\n nextKeys,\n nodes: snapshot.nodes,\n options,\n selection: snapshot.selection,\n }),\n { focusAfterSync: true },\n );\n },\n };\n };\n\n handleBeforeInput = (params: {\n disabled: boolean;\n event: FormEvent<HTMLDivElement>;\n }): void => {\n const { disabled, event } = params;\n const { callbacks, fallbackNodes } = this.getRuntime();\n handleLexicalComposerBeforeInput({\n disabled,\n event,\n isComposing: this.isComposingRef.current,\n publishSnapshot: (snapshot, options) => this.publishSnapshot(snapshot, callbacks, options),\n snapshotReader: () => this.readComposerSnapshot(fallbackNodes),\n });\n };\n\n handleCompositionStart = (): void => {\n const { fallbackNodes } = this.getRuntime();\n this.compositionStartSnapshotRef.current = this.readComposerSnapshot(fallbackNodes);\n this.isComposingRef.current = true;\n };\n\n handleCompositionEnd = (params: { data: string }): void => {\n const { data } = params;\n const { callbacks, fallbackNodes } = this.getRuntime();\n this.isComposingRef.current = false;\n handleLexicalComposerCompositionEnd({\n compositionStartSnapshot: this.compositionStartSnapshotRef.current,\n data,\n fallbackSnapshot: () => this.readComposerSnapshot(fallbackNodes),\n publishSnapshot: (snapshot, options) => this.publishSnapshot(snapshot, callbacks, options),\n snapshotReader: () => this.readComposerSnapshot(fallbackNodes),\n });\n this.compositionStartSnapshotRef.current = null;\n };\n\n handleKeyDown = (params: {\n actions: ComposerActions;\n callbacks: ChatComposerLexicalOwnerCallbacks;\n event: KeyboardEvent;\n fallbackNodes: ChatComposerNode[];\n }): boolean => {\n const { actions, callbacks, event, fallbackNodes } = params;\n if (\n event.key.length === 1 &&\n !event.isComposing &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n this.pendingInputSurfaceReasonRef.current = { type: 'insert-text', text: event.key };\n }\n\n const snapshot = this.readComposerSnapshot(fallbackNodes);\n if (callbacks.onInputSurfaceKeyDown?.(event)) {\n return true;\n }\n return handleLexicalComposerKeyboardCommand({\n actions,\n nativeEvent: event,\n publishSnapshot: (nextSnapshot, options) => this.publishSnapshot(nextSnapshot, callbacks, options),\n snapshot,\n });\n };\n\n handleEditorUpdate = (editorState: EditorState, callbacks: ChatComposerLexicalOwnerCallbacks): void => {\n const snapshot = readChatComposerSnapshotFromEditorState(editorState);\n const signature = getChatComposerNodesSignature(snapshot.nodes);\n\n this.editorSignatureRef.current = signature;\n\n if (this.isApplyingExternalUpdateRef.current || this.isComposingRef.current) {\n return;\n }\n\n this.selectionRef.current = snapshot.selection;\n callbacks.onInputSurfaceSnapshotChange?.(\n snapshot.nodes,\n snapshot.selection,\n this.consumeInputSurfaceReason() ?? { type: 'sync' },\n );\n\n if (signature === this.lastPublishedSignatureRef.current) {\n return;\n }\n\n this.lastPublishedSignatureRef.current = signature;\n callbacks.onNodesChange(snapshot.nodes);\n };\n\n handleSelectionChange = (editor: LexicalEditor, callbacks: ChatComposerLexicalOwnerCallbacks): void => {\n const snapshot = readChatComposerSnapshotFromEditorState(editor.getEditorState());\n if (this.isComposingRef.current) {\n return;\n }\n this.selectionRef.current = snapshot.selection;\n callbacks.onInputSurfaceSnapshotChange?.(snapshot.nodes, snapshot.selection, { type: 'selection' });\n };\n\n private consumeInputSurfaceReason = (): ChatInputSurfaceTriggerChangeReason | null => {\n const reason = this.pendingInputSurfaceReasonRef.current;\n this.pendingInputSurfaceReasonRef.current = null;\n return reason;\n };\n\n private publishRuntimeSnapshot = (\n createSnapshot: (snapshot: ChatComposerEditorSnapshot) => ChatComposerEditorSnapshot,\n options: PublishOptions,\n ): void => {\n const { callbacks, fallbackNodes } = this.getRuntime();\n this.publishSnapshot(createSnapshot(this.readComposerSnapshot(fallbackNodes)), callbacks, options);\n };\n\n private startApplyingExternalUpdate = (): void => {\n this.isApplyingExternalUpdateRef.current = true;\n requestAnimationFrame(() => {\n this.isApplyingExternalUpdateRef.current = false;\n });\n };\n\n private getRuntime = (): ComposerRuntime => {\n if (!this.runtime) {\n throw new Error('ChatComposerLexicalOwner runtime has not been configured.');\n }\n return this.runtime;\n };\n}\n","import { useEffect, useLayoutEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport type {\n ChatComposerNode,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport type { ChatComposerLexicalOwner } from './owners/chat-composer-lexical-owner';\n\ntype ChatComposerBindingsPluginProps = {\n disabled: boolean;\n nodes: ChatComposerNode[];\n owner: ChatComposerLexicalOwner;\n};\n\nexport function ChatComposerBindingsPlugin(\n {\n disabled,\n nodes,\n owner,\n }: ChatComposerBindingsPluginProps,\n): null {\n const [editor] = useLexicalComposerContext();\n\n useLayoutEffect(() => {\n return owner.bindEditor(editor);\n }, [editor, owner]);\n\n useLayoutEffect(() => {\n editor.setEditable(!disabled);\n owner.syncExternalState(editor, nodes);\n }, [disabled, editor, nodes, owner]);\n\n useEffect(() => {\n return owner.registerEditorListeners(editor);\n }, [editor, owner]);\n\n return null;\n}\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useState,\n type ClipboardEvent,\n type FormEvent,\n} from 'react';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin';\nimport type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatInputSurfaceItem,\n ChatInputSurfaceTriggerChangeReason,\n ChatInputSurfaceTriggerSpec,\n ChatInputBarActionsProps,\n ChatSkillPickerOption,\n ChatSlashItem,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n writeChatComposerStateToLexicalRoot,\n} from './chat-composer-lexical-adapter';\nimport { ChatComposerLexicalOwner } from './owners/chat-composer-lexical-owner';\nimport { ChatComposerBindingsPlugin } from './chat-composer-plugins';\nimport { ChatComposerTokenNode } from './chat-composer-token-node';\n\nexport type ChatInputBarTokenizedComposerHandle = {\n insertInputSurfaceItem: (\n item: ChatInputSurfaceItem,\n triggerSpecs?: readonly ChatInputSurfaceTriggerSpec[],\n ) => void;\n insertSlashItem: (item: ChatSlashItem) => void;\n insertFileToken: (tokenKey: string, label: string) => void;\n insertFileTokens: (tokens: Array<{ tokenKey: string; label: string }>) => void;\n focusComposer: () => void;\n focusComposerAtEnd: (nodes?: ChatComposerNode[]) => void;\n syncSelectedSkills: (nextKeys: string[], options: ChatSkillPickerOption[]) => void;\n};\n\ntype ChatInputBarTokenizedComposerProps = {\n nodes: ChatComposerNode[];\n placeholder: string;\n disabled: boolean;\n onInputSurfaceItemSelect?: (item: ChatInputSurfaceItem) => void;\n actions: Pick<ChatInputBarActionsProps, 'onSend' | 'onStop' | 'isSending' | 'canStopGeneration'>;\n onNodesChange: (nodes: ChatComposerNode[]) => void;\n onFilesAdd?: (files: File[]) => Promise<void> | void;\n onInputSurfaceSnapshotChange?: (\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n ) => void;\n onInputSurfaceOpenChange?: (open: boolean) => void;\n onInputSurfaceKeyDown?: (event: KeyboardEvent) => boolean;\n};\n\nexport const ChatInputBarTokenizedComposer = forwardRef<\n ChatInputBarTokenizedComposerHandle,\n ChatInputBarTokenizedComposerProps\n>(function ChatInputBarTokenizedComposer(\n {\n actions,\n disabled,\n nodes,\n onFilesAdd,\n onInputSurfaceItemSelect,\n onInputSurfaceKeyDown,\n onInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange,\n onNodesChange,\n placeholder,\n },\n ref,\n) {\n const [owner] = useState(() => new ChatComposerLexicalOwner());\n const ownerCallbacks = useMemo(\n () => ({\n onInputSurfaceItemSelect,\n onInputSurfaceKeyDown,\n onInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange,\n onNodesChange,\n }),\n [\n onInputSurfaceItemSelect,\n onInputSurfaceKeyDown,\n onInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange,\n onNodesChange,\n ],\n );\n owner.configureRuntime({\n actions,\n callbacks: ownerCallbacks,\n fallbackNodes: nodes,\n });\n\n useImperativeHandle(\n ref,\n () => owner.createHandle(),\n [owner],\n );\n\n const initialConfig = useMemo(\n () => ({\n editable: !disabled,\n editorState: () => {\n writeChatComposerStateToLexicalRoot(nodes, null);\n },\n namespace: 'NextClawChatComposerLexical',\n nodes: [ChatComposerTokenNode],\n onError: (error: Error) => {\n throw error;\n },\n theme: {},\n }),\n [disabled, nodes],\n );\n\n return (\n <LexicalComposer initialConfig={initialConfig}>\n <div className=\"px-3 py-2 sm:px-4 sm:py-2.5\">\n <div className=\"min-h-11 sm:min-h-[60px]\">\n <PlainTextPlugin\n contentEditable={\n <ContentEditable\n 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\"\n onBeforeInput={(event: FormEvent<HTMLDivElement>) => {\n owner.handleBeforeInput({\n disabled,\n event,\n });\n }}\n onCompositionEnd={(event) => {\n const nativeEvent = event.nativeEvent as CompositionEvent;\n owner.handleCompositionEnd({\n data: typeof nativeEvent.data === 'string' ? nativeEvent.data : '',\n });\n }}\n onCompositionStart={() => {\n owner.handleCompositionStart();\n }}\n onPaste={(event: ClipboardEvent<HTMLDivElement>) => {\n const files = Array.from(event.clipboardData.files ?? []);\n if (files.length > 0 && onFilesAdd) {\n event.preventDefault();\n void onFilesAdd(files);\n }\n }}\n />\n }\n placeholder={\n <div 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\">\n {placeholder}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </div>\n </div>\n <ChatComposerBindingsPlugin\n disabled={disabled}\n nodes={nodes}\n owner={owner}\n />\n </LexicalComposer>\n );\n});\n\nChatInputBarTokenizedComposer.displayName = 'LexicalChatInputBarTokenizedComposer';\n","import { forwardRef, useImperativeHandle, useMemo, useRef } from 'react';\nimport type {\n ChatInputBarProps,\n ChatInputSurfaceConfig,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { ChatInputSurfaceHost } from '@agent-chat-ui/components/chat/ui/input-surface/chat-input-surface-host';\nimport { ChatInputBarToolbar } from './chat-input-bar-toolbar';\nimport { ChatInputBarTokenizedComposer, type ChatInputBarTokenizedComposerHandle } from './chat-input-bar-tokenized-composer';\n\nfunction InputBarHint({ hint }: { hint: ChatInputBarProps['hint'] }) {\n if (!hint) {\n return null;\n }\n\n if (hint.loading) {\n return (\n <div className=\"px-4 pb-2\">\n <div className=\"inline-flex items-center gap-2 rounded-lg border border-border bg-muted px-3 py-2\">\n <span className=\"h-3 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"h-3 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n </div>\n );\n }\n\n const toneClassName =\n hint.tone === 'warning'\n ? 'border-amber-200 bg-amber-50 text-amber-800'\n : 'border-border bg-muted text-muted-foreground';\n\n return (\n <div className=\"px-4 pb-2\">\n <div className={`inline-flex items-center gap-2 rounded-lg px-3 py-1.5 text-xs ${toneClassName}`}>\n {hint.text ? <span>{hint.text}</span> : null}\n {hint.actionLabel && hint.onAction ? (\n <button\n type=\"button\"\n onClick={hint.onAction}\n className=\"font-semibold underline-offset-2 hover:underline\"\n >\n {hint.actionLabel}\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport type ChatInputBarHandle = {\n insertFileToken: (tokenKey: string, label: string) => void;\n insertFileTokens: (tokens: Array<{ tokenKey: string; label: string }>) => void;\n focusComposer: () => void;\n focusComposerAtEnd: (nodes?: ChatInputBarProps['composer']['nodes']) => void;\n};\n\nexport const ChatInputBar = forwardRef<ChatInputBarHandle, ChatInputBarProps>(function ChatInputBar(\n { composer, hint, inputSurface, slashMenu, surface, toolbar: toolbarProps, topSlot },\n ref\n) {\n const composerRef = useRef<ChatInputBarTokenizedComposerHandle | null>(null);\n const resolvedInputSurface: ChatInputSurfaceConfig | null = inputSurface ?? (slashMenu\n ? {\n isLoading: slashMenu.isLoading,\n filterOptions: slashMenu.filterOptions,\n items: slashMenu.items,\n onSelectItem: slashMenu.onSelectItem,\n texts: {\n loadingLabel: slashMenu.texts.slashLoadingLabel,\n sectionLabel: slashMenu.texts.slashSectionLabel,\n emptyLabel: slashMenu.texts.slashEmptyLabel,\n hintLabel: slashMenu.texts.slashHintLabel,\n itemHintLabel: slashMenu.texts.slashSkillHintLabel,\n },\n }\n : null);\n\n const toolbar = useMemo(() => {\n if (!toolbarProps.skillPicker) {\n return toolbarProps;\n }\n return {\n ...toolbarProps,\n skillPicker: {\n ...toolbarProps.skillPicker,\n onSelectedKeysChange: (nextKeys: string[]) => {\n composerRef.current?.syncSelectedSkills(nextKeys, toolbarProps.skillPicker?.options ?? []);\n toolbarProps.skillPicker?.onSelectedKeysChange(nextKeys);\n }\n }\n };\n }, [toolbarProps]);\n\n useImperativeHandle(ref, () => ({\n insertFileToken: (tokenKey, label) => composerRef.current?.insertFileToken(tokenKey, label),\n insertFileTokens: (tokens) => composerRef.current?.insertFileTokens(tokens),\n focusComposer: () => composerRef.current?.focusComposer(),\n focusComposerAtEnd: (nodes) => composerRef.current?.focusComposerAtEnd(nodes),\n }), []);\n const surfaceClassName =\n surface === 'embedded'\n ? 'bg-transparent px-0 py-0'\n : 'bg-background px-3 pb-3 pt-2 sm:px-4 sm:pb-4 sm:pt-2';\n\n return (\n <div className={surfaceClassName}>\n <div className=\"nextclaw-chat-input-bar-shell mx-auto w-full max-w-[min(1120px,100%)] [container:nextclaw-chat-input-bar/inline-size]\">\n <div className=\"overflow-hidden rounded-2xl border border-border bg-card shadow-card\">\n {topSlot ? (\n <div className=\"px-3 pb-0 pt-2 sm:px-4 sm:pt-2.5\">\n {topSlot}\n </div>\n ) : null}\n <div className=\"relative\">\n <ChatInputSurfaceHost\n inputSurface={resolvedInputSurface}\n onInputSurfaceTriggerChange={composer.onInputSurfaceTriggerChange}\n onSelectItem={(item) => composerRef.current?.insertInputSurfaceItem(item, composer.inputSurfaceTriggerSpecs)}\n triggerSpecs={composer.inputSurfaceTriggerSpecs}\n >\n {({\n onInputSurfaceKeyDown,\n onInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange,\n }) => (\n <ChatInputBarTokenizedComposer\n ref={composerRef}\n nodes={composer.nodes}\n placeholder={composer.placeholder}\n disabled={composer.disabled}\n onInputSurfaceItemSelect={resolvedInputSurface?.onSelectItem}\n actions={toolbarProps.actions}\n onNodesChange={composer.onNodesChange}\n onFilesAdd={composer.onFilesAdd}\n onInputSurfaceSnapshotChange={onInputSurfaceSnapshotChange}\n onInputSurfaceOpenChange={onInputSurfaceOpenChange}\n onInputSurfaceKeyDown={onInputSurfaceKeyDown}\n />\n )}\n </ChatInputSurfaceHost>\n </div>\n\n <InputBarHint hint={hint} />\n <ChatInputBarToolbar {...toolbar} />\n </div>\n </div>\n </div>\n );\n});\n\nChatInputBar.displayName = 'ChatInputBar';\n","import type { ChatMessageRole } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { Bot, User, Wrench } from 'lucide-react';\n\nexport function ChatMessageAvatar({ role }: { role: ChatMessageRole }) {\n if (role === 'user') {\n return (\n <div\n data-testid=\"chat-message-avatar-user\"\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm\"\n >\n <User className=\"h-4 w-4\" />\n </div>\n );\n }\n if (role === 'tool') {\n return (\n <div\n data-testid=\"chat-message-avatar-tool\"\n 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\"\n >\n <Wrench className=\"h-4 w-4\" />\n </div>\n );\n }\n return (\n <div\n data-testid=\"chat-message-avatar-assistant\"\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-muted text-foreground shadow-sm ring-1 ring-border\"\n >\n <Bot className=\"h-[18px] w-[18px] text-current\" strokeWidth={2.5} />\n </div>\n );\n}\n","import { AppWindow, Puzzle } from \"lucide-react\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\n\ntype ChatInlineTokenTone = \"skill\" | \"panel_app\" | \"default\";\n\nfunction resolveInlineTokenTone(kind: string): ChatInlineTokenTone {\n if (kind === \"skill\") {\n return \"skill\";\n }\n if (kind === \"panel_app\") {\n return \"panel_app\";\n }\n return \"default\";\n}\n\nfunction resolveInlineTokenBadgeClassName(\n tone: ChatInlineTokenTone,\n isUser: boolean,\n): string {\n if (tone === \"skill\") {\n return isUser\n ? \"border-primary-foreground/30 bg-primary-foreground/18 text-primary-foreground\"\n : \"border-border bg-accent text-accent-foreground\";\n }\n if (tone === \"panel_app\") {\n return isUser\n ? \"border-primary-foreground/30 bg-primary-foreground/18 text-primary-foreground\"\n : \"border-border bg-accent text-accent-foreground\";\n }\n return isUser\n ? \"border-primary-foreground/30 bg-primary-foreground/18 text-primary-foreground\"\n : \"border-border bg-muted text-muted-foreground\";\n}\n\nfunction resolveInlineTokenIconClassName(\n tone: ChatInlineTokenTone,\n isUser: boolean,\n): string {\n if (tone === \"skill\") {\n return isUser ? \"text-primary-foreground/70\" : \"text-muted-foreground\";\n }\n if (tone === \"panel_app\") {\n return isUser ? \"text-primary-foreground/70\" : \"text-muted-foreground\";\n }\n return isUser ? \"text-primary-foreground/70\" : \"text-muted-foreground\";\n}\n\nfunction renderInlineTokenIcon(tone: ChatInlineTokenTone) {\n return tone === \"panel_app\" ? (\n <AppWindow aria-hidden=\"true\" className=\"h-3 w-3\" />\n ) : (\n <Puzzle aria-hidden=\"true\" className=\"h-3 w-3\" />\n );\n}\n\nexport function ChatInlineTokenBadge({\n kind,\n label,\n isUser,\n}: {\n kind: string;\n label: string;\n isUser: boolean;\n}) {\n const tone = resolveInlineTokenTone(kind);\n return (\n <span\n className={cn(\n \"mx-[2px] inline-flex h-7 max-w-full items-center gap-1.5 rounded-xl border px-2.5 align-baseline text-[11px] font-medium shadow-[0_0_0_1px_rgba(15,23,42,0.03)]\",\n resolveInlineTokenBadgeClassName(tone, isUser),\n )}\n title={label}\n >\n <span\n className={cn(\n \"inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center\",\n resolveInlineTokenIconClassName(tone, isUser),\n )}\n >\n {renderInlineTokenIcon(tone)}\n </span>\n <span className=\"truncate\">{label}</span>\n </span>\n );\n}\n","function canUseClipboardApi(): boolean {\n return (\n typeof navigator !== 'undefined' &&\n typeof navigator.clipboard?.writeText === 'function'\n );\n}\n\nfunction restoreSelection(ranges: Range[]) {\n if (typeof document === 'undefined') {\n return;\n }\n\n const selection = document.getSelection();\n if (!selection) {\n return;\n }\n\n selection.removeAllRanges();\n ranges.forEach((range) => selection.addRange(range));\n}\n\ntype CopyContextSnapshot = {\n activeElement: HTMLElement | null;\n activeInputSelection: {\n input: HTMLInputElement | HTMLTextAreaElement;\n start: number | null;\n end: number | null;\n } | null;\n ranges: Range[];\n};\n\nfunction snapshotCopyContext(): CopyContextSnapshot {\n const activeElement = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n const activeInput = activeElement instanceof HTMLInputElement || activeElement instanceof HTMLTextAreaElement\n ? activeElement\n : null;\n const activeInputSelection = activeInput\n ? {\n input: activeInput,\n start: activeInput.selectionStart,\n end: activeInput.selectionEnd\n }\n : null;\n const selection = document.getSelection();\n const ranges = selection\n ? Array.from({ length: selection.rangeCount }, (_, index) => selection.getRangeAt(index).cloneRange())\n : [];\n return { activeElement, activeInputSelection, ranges };\n}\n\nfunction createCopyTextarea(text: string): HTMLTextAreaElement {\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.setAttribute('readonly', '');\n textarea.setAttribute('aria-hidden', 'true');\n Object.assign(textarea.style, {\n fontSize: '12pt',\n left: '-9999px',\n opacity: '0',\n pointerEvents: 'none',\n position: 'fixed',\n top: '0'\n });\n return textarea;\n}\n\nfunction focusWithoutScroll(element: HTMLElement) {\n try {\n element.focus({ preventScroll: true });\n } catch {\n element.focus();\n }\n}\n\nfunction selectTextarea(textarea: HTMLTextAreaElement) {\n focusWithoutScroll(textarea);\n textarea.select();\n textarea.setSelectionRange(0, textarea.value.length);\n}\n\nfunction runCopyCommand(): boolean {\n try {\n return typeof document.execCommand === 'function' && document.execCommand('copy');\n } catch {\n return false;\n }\n}\n\nfunction restoreInputSelection(snapshot: CopyContextSnapshot): boolean {\n if (!snapshot.activeInputSelection) {\n return false;\n }\n\n const { input, start, end } = snapshot.activeInputSelection;\n if (start === null || end === null) {\n return false;\n }\n input.setSelectionRange(start, end);\n return true;\n}\n\nfunction restoreCopyContext(snapshot: CopyContextSnapshot) {\n if (snapshot.activeElement) {\n focusWithoutScroll(snapshot.activeElement);\n }\n if (!restoreInputSelection(snapshot)) {\n restoreSelection(snapshot.ranges);\n }\n}\n\nfunction fallbackCopyText(text: string): boolean {\n if (typeof document === 'undefined' || !document.body) {\n return false;\n }\n\n const snapshot = snapshotCopyContext();\n const textarea = createCopyTextarea(text);\n document.body.appendChild(textarea);\n selectTextarea(textarea);\n const copied = runCopyCommand();\n textarea.remove();\n restoreCopyContext(snapshot);\n return copied;\n}\n\nexport async function copyText(text: string): Promise<boolean> {\n if (!text) {\n return false;\n }\n\n if (canUseClipboardApi()) {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n return fallbackCopyText(text);\n }\n }\n\n return fallbackCopyText(text);\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { copyText } from '@agent-chat-ui/components/chat/utils/copy-text.utils';\n\ntype UseCopyFeedbackParams = {\n text: string;\n resetDelayMs?: number;\n};\n\ntype UseCopyFeedbackResult = {\n copied: boolean;\n copy: () => Promise<void>;\n};\n\nconst DEFAULT_RESET_DELAY_MS = 1300;\n\nexport function useCopyFeedback(params: UseCopyFeedbackParams): UseCopyFeedbackResult {\n const [copied, setCopied] = useState(false);\n\n const copy = useCallback(async () => {\n if (!params.text) {\n return;\n }\n\n const didCopy = await copyText(params.text);\n if (didCopy) {\n setCopied(true);\n } else {\n setCopied(false);\n }\n }, [params.text]);\n\n useEffect(() => {\n if (!copied || typeof window === 'undefined') {\n return;\n }\n\n const timer = window.setTimeout(() => setCopied(false), params.resetDelayMs ?? DEFAULT_RESET_DELAY_MS);\n return () => window.clearTimeout(timer);\n }, [copied, params.resetDelayMs]);\n\n return {\n copied,\n copy\n };\n}\n","import hljs from 'highlight.js/lib/core';\nimport bash from 'highlight.js/lib/languages/bash';\nimport css from 'highlight.js/lib/languages/css';\nimport diff from 'highlight.js/lib/languages/diff';\nimport javascript from 'highlight.js/lib/languages/javascript';\nimport json from 'highlight.js/lib/languages/json';\nimport markdown from 'highlight.js/lib/languages/markdown';\nimport python from 'highlight.js/lib/languages/python';\nimport shell from 'highlight.js/lib/languages/shell';\nimport sql from 'highlight.js/lib/languages/sql';\nimport typescript from 'highlight.js/lib/languages/typescript';\nimport xml from 'highlight.js/lib/languages/xml';\nimport yaml from 'highlight.js/lib/languages/yaml';\nimport type { HLJSApi, LanguageFn } from 'highlight.js';\n\nconst PLAIN_TEXT_LANGUAGES = new Set([\n 'text',\n 'txt',\n 'plain',\n 'plaintext',\n 'none',\n 'output',\n]);\n\nconst AUTO_DETECT_LANGUAGES = [\n 'typescript',\n 'javascript',\n 'json',\n 'bash',\n 'shell',\n 'python',\n 'css',\n 'xml',\n 'markdown',\n 'yaml',\n 'sql',\n 'diff',\n];\n\nconst AUTO_DETECT_MIN_RELEVANCE = 4;\n\ntype RegisteredLanguage = {\n name: string;\n language: LanguageFn;\n aliases?: string[];\n};\n\nconst REGISTERED_LANGUAGES: RegisteredLanguage[] = [\n { name: 'typescript', language: typescript, aliases: ['ts', 'tsx'] },\n { name: 'javascript', language: javascript, aliases: ['js', 'jsx', 'mjs', 'cjs'] },\n { name: 'json', language: json, aliases: ['jsonc'] },\n { name: 'bash', language: bash, aliases: ['sh', 'zsh'] },\n { name: 'shell', language: shell, aliases: ['console', 'terminal'] },\n { name: 'python', language: python, aliases: ['py'] },\n { name: 'css', language: css },\n { name: 'xml', language: xml, aliases: ['html', 'svg'] },\n { name: 'markdown', language: markdown, aliases: ['md', 'mdx'] },\n { name: 'yaml', language: yaml, aliases: ['yml'] },\n { name: 'sql', language: sql },\n { name: 'diff', language: diff, aliases: ['patch'] },\n];\n\nexport type ChatCodeHighlightResult = {\n html: string;\n language: string;\n highlighted: boolean;\n};\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\nfunction normalizeLanguage(value: string): string {\n return value.trim().toLowerCase();\n}\n\nexport class ChatCodeSyntaxHighlighter {\n private readonly engine: HLJSApi;\n\n constructor() {\n this.engine = hljs.newInstance();\n REGISTERED_LANGUAGES.forEach((entry) => {\n this.engine.registerLanguage(entry.name, entry.language);\n if (entry.aliases) {\n this.engine.registerAliases(entry.aliases, { languageName: entry.name });\n }\n });\n }\n\n highlight = (code: string, language: string): ChatCodeHighlightResult => {\n const normalizedLanguage = normalizeLanguage(language);\n if (!code || PLAIN_TEXT_LANGUAGES.has(normalizedLanguage)) {\n return this.createPlainTextResult(code, normalizedLanguage || 'text');\n }\n\n if (this.engine.getLanguage(normalizedLanguage)) {\n const result = this.engine.highlight(code, {\n language: normalizedLanguage,\n ignoreIllegals: true,\n });\n return {\n html: result.value,\n language: result.language ?? normalizedLanguage,\n highlighted: true,\n };\n }\n\n const autoDetected = this.engine.highlightAuto(code, AUTO_DETECT_LANGUAGES);\n if (autoDetected.language && autoDetected.relevance >= AUTO_DETECT_MIN_RELEVANCE) {\n return {\n html: autoDetected.value,\n language: autoDetected.language,\n highlighted: true,\n };\n }\n\n return this.createPlainTextResult(code, normalizedLanguage || 'text');\n };\n\n private createPlainTextResult = (code: string, language: string): ChatCodeHighlightResult => ({\n html: escapeHtml(code),\n language,\n highlighted: false,\n });\n}\n\nexport const chatCodeSyntaxHighlighter = new ChatCodeSyntaxHighlighter();\n","import { useMemo, type ReactNode } from 'react';\nimport { useCopyFeedback } from '../../hooks/use-copy-feedback';\nimport type { ChatMessageTexts } from '../../view-models/chat-ui.types';\nimport { Check, Copy } from 'lucide-react';\nimport { cn } from '../../internal/cn';\nimport { chatCodeSyntaxHighlighter } from './code-block/chat-code-syntax-highlighter';\n\nconst CODE_LANGUAGE_REGEX = /language-([a-z0-9-]+)/i;\n\nfunction flattenNodeText(value: ReactNode): string {\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value);\n }\n if (Array.isArray(value)) {\n return value.map(flattenNodeText).join('');\n }\n return '';\n}\n\nfunction normalizeCodeText(value: ReactNode): string {\n const content = flattenNodeText(value);\n return content.endsWith('\\n') ? content.slice(0, -1) : content;\n}\n\nfunction resolveCodeLanguage(className?: string): string {\n const match = className ? CODE_LANGUAGE_REGEX.exec(className) : null;\n return match?.[1]?.toLowerCase() || 'text';\n}\n\ntype ChatCodeBlockProps = {\n className?: string;\n children: ReactNode;\n texts: Pick<ChatMessageTexts, 'copyCodeLabel' | 'copiedCodeLabel'>;\n};\n\nexport function ChatCodeBlock({ className, children, texts }: ChatCodeBlockProps) {\n const language = useMemo(() => resolveCodeLanguage(className), [className]);\n const codeText = useMemo(() => normalizeCodeText(children), [children]);\n const highlightedCode = useMemo(\n () => chatCodeSyntaxHighlighter.highlight(codeText, language),\n [codeText, language],\n );\n const codeClassName = useMemo(() => {\n const highlightedLanguageClass = `language-${highlightedCode.language}`;\n return cn(\n 'hljs',\n className,\n className?.includes('language-') ? undefined : highlightedLanguageClass,\n );\n }, [className, highlightedCode.language]);\n const { copied, copy } = useCopyFeedback({ text: codeText });\n\n return (\n <div className=\"chat-codeblock\">\n <div className=\"chat-codeblock-toolbar\">\n <span className=\"chat-codeblock-language\">{language}</span>\n <button\n type=\"button\"\n className=\"chat-codeblock-copy\"\n onClick={() => void copy()}\n aria-label={copied ? texts.copiedCodeLabel : texts.copyCodeLabel}\n >\n {copied ? <Check className=\"h-3.5 w-3.5\" /> : <Copy className=\"h-3.5 w-3.5\" />}\n <span>{copied ? texts.copiedCodeLabel : texts.copyCodeLabel}</span>\n </button>\n </div>\n <pre>\n <code\n className={codeClassName}\n data-highlighted={highlightedCode.highlighted ? 'true' : 'false'}\n dangerouslySetInnerHTML={{ __html: highlightedCode.html }}\n />\n </pre>\n </div>\n );\n}\n","import type {\n ChatFilePreviewViewer,\n ChatInlineDisplayTarget,\n ChatInlineDisplayViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\n\nconst INLINE_DISPLAY_LANGUAGE = \"nextclaw-inline\";\nconst CODE_LANGUAGE_REGEX = /language-([a-z0-9-]+)/i;\nconst FILE_PREVIEW_VIEWERS = new Set<ChatFilePreviewViewer>([\n \"auto\",\n \"source\",\n \"rendered\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction readPositiveInteger(value: unknown): number | undefined {\n return Number.isInteger(value) && Number(value) > 0\n ? Number(value)\n : undefined;\n}\n\nfunction readFilePreviewViewer(value: unknown): ChatFilePreviewViewer | undefined {\n const viewer = readString(value);\n return viewer && FILE_PREVIEW_VIEWERS.has(viewer as ChatFilePreviewViewer)\n ? (viewer as ChatFilePreviewViewer)\n : undefined;\n}\n\nfunction readTargetPayload(record: Record<string, unknown>): Record<string, unknown> | null {\n const { payload } = record;\n return isRecord(payload) ? payload : null;\n}\n\nfunction readFileTarget(record: Record<string, unknown>): ChatInlineDisplayTarget | null {\n const payload = readTargetPayload(record);\n if (!payload) {\n return null;\n }\n const path = readString(payload.path);\n if (!path) {\n return null;\n }\n return {\n type: \"file\",\n payload: {\n path,\n line: readPositiveInteger(payload.line),\n column: readPositiveInteger(payload.column),\n viewer: readFilePreviewViewer(payload.viewer),\n },\n };\n}\n\nfunction readUrlTarget(record: Record<string, unknown>): ChatInlineDisplayTarget | null {\n const payload = readTargetPayload(record);\n if (!payload) {\n return null;\n }\n const url = readString(payload.url);\n if (!url) {\n return null;\n }\n return {\n type: \"url\",\n payload: { url },\n };\n}\n\nfunction readPanelAppTarget(record: Record<string, unknown>): ChatInlineDisplayTarget | null {\n const payload = readTargetPayload(record);\n if (!payload) {\n return null;\n }\n const appId = readString(payload.appId);\n if (!appId) {\n return null;\n }\n return {\n type: \"panel_app\",\n payload: { appId },\n };\n}\n\nfunction readJsonTarget(record: Record<string, unknown>): ChatInlineDisplayTarget | null {\n const payload = readTargetPayload(record);\n if (!payload || !(\"value\" in payload)) {\n return null;\n }\n return {\n type: \"json\",\n payload: { value: payload.value },\n };\n}\n\nfunction readInlineDisplayTarget(value: unknown): ChatInlineDisplayTarget | null {\n if (!isRecord(value)) {\n return null;\n }\n const type = readString(value.type);\n if (type === \"file\") {\n return readFileTarget(value);\n }\n if (type === \"url\") {\n return readUrlTarget(value);\n }\n if (type === \"panel_app\") {\n return readPanelAppTarget(value);\n }\n if (type === \"json\") {\n return readJsonTarget(value);\n }\n return null;\n}\n\nexport function isChatInlineDisplayLanguage(className?: string): boolean {\n const match = className ? CODE_LANGUAGE_REGEX.exec(className) : null;\n const language = match?.[1]?.toLowerCase();\n return language === INLINE_DISPLAY_LANGUAGE;\n}\n\nexport function parseChatInlineDisplayDirective(\n rawText: string,\n): ChatInlineDisplayViewModel | null {\n const text = rawText.endsWith(\"\\n\") ? rawText.slice(0, -1) : rawText;\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n if (!isRecord(parsed)) {\n return null;\n }\n const target = readInlineDisplayTarget(parsed.target);\n if (!target) {\n return null;\n }\n return {\n target,\n title: readString(parsed.title),\n description: readString(parsed.description),\n };\n}\n\nexport function getChatInlineDisplayLabel(display: ChatInlineDisplayViewModel): string {\n if (display.title) {\n return display.title;\n }\n if (display.target.type === \"file\") {\n const segments = display.target.payload.path.split(\"/\").filter(Boolean);\n return segments[segments.length - 1] ?? display.target.payload.path;\n }\n if (display.target.type === \"url\") {\n return display.target.payload.url;\n }\n if (display.target.type === \"panel_app\") {\n return display.target.payload.appId;\n }\n return \"JSON\";\n}\n\nexport function getChatInlineDisplayDetail(display: ChatInlineDisplayViewModel): string {\n if (display.target.type === \"file\") {\n return display.target.payload.path;\n }\n if (display.target.type === \"url\") {\n return display.target.payload.url;\n }\n if (display.target.type === \"panel_app\") {\n return display.target.payload.appId;\n }\n return JSON.stringify(display.target.payload.value, null, 2);\n}\n","import { AppWindow, Code2, FileText, Globe } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport type { ChatInlineDisplayViewModel } from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport {\n getChatInlineDisplayDetail,\n getChatInlineDisplayLabel,\n} from \"./utils/chat-inline-display.utils\";\n\ntype ChatInlineDisplayProps = {\n display: ChatInlineDisplayViewModel;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n};\n\nfunction ChatInlineDisplayIcon({ display }: { display: ChatInlineDisplayViewModel }) {\n const className = \"h-3.5 w-3.5 shrink-0 text-muted-foreground\";\n if (display.target.type === \"file\") {\n return <FileText className={className} aria-hidden />;\n }\n if (display.target.type === \"url\") {\n return <Globe className={className} aria-hidden />;\n }\n if (display.target.type === \"panel_app\") {\n return <AppWindow className={className} aria-hidden />;\n }\n return <Code2 className={className} aria-hidden />;\n}\n\nfunction formatJsonDetail(value: string): string {\n return value.length > 1_200 ? `${value.slice(0, 1_200)}\\n...` : value;\n}\n\nfunction ChatInlineDisplayFallback({ display }: { display: ChatInlineDisplayViewModel }) {\n const label = getChatInlineDisplayLabel(display);\n const detail = getChatInlineDisplayDetail(display);\n const formattedDetail = display.target.type === \"json\"\n ? formatJsonDetail(detail)\n : detail;\n\n return (\n <section\n className={cn(\n \"my-2 max-w-full border-l-2 border-border bg-muted/30 px-3 py-2\",\n \"text-xs leading-relaxed text-foreground\",\n )}\n data-nextclaw-inline-display=\"true\"\n data-nextclaw-inline-display-type={display.target.type}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <ChatInlineDisplayIcon display={display} />\n <span className=\"min-w-0 truncate font-medium\">{label}</span>\n </div>\n {display.description ? (\n <p className=\"mt-1 line-clamp-2 text-[12px] text-muted-foreground\">\n {display.description}\n </p>\n ) : null}\n <pre\n className={cn(\n \"mt-1 max-h-40 overflow-auto whitespace-pre-wrap break-words\",\n \"font-mono text-[11px] leading-relaxed text-muted-foreground\",\n )}\n >\n {formattedDetail}\n </pre>\n </section>\n );\n}\n\nexport function ChatInlineDisplay({\n display,\n renderInlineDisplay,\n}: ChatInlineDisplayProps) {\n const rendered = renderInlineDisplay?.(display);\n if (rendered !== undefined && rendered !== null) {\n return <>{rendered}</>;\n }\n return <ChatInlineDisplayFallback display={display} />;\n}\n","import { useMemo, type MouseEvent, type ReactNode } from \"react\";\nimport type { Components } from \"react-markdown\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { ChatInlineTokenBadge } from \"./chat-inline-token-badge\";\nimport { ChatCodeBlock } from \"./chat-code-block\";\nimport { ChatInlineDisplay } from \"./chat-inline-display\";\nimport type {\n ChatFileOpenActionViewModel,\n ChatInlineDisplayViewModel,\n ChatInlineTokenViewModel,\n ChatMessageRole,\n ChatMessageTexts,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport {\n isChatInlineDisplayLanguage,\n parseChatInlineDisplayDirective,\n} from \"./utils/chat-inline-display.utils\";\n\nconst MARKDOWN_MAX_CHARS = 140_000;\nconst SAFE_LINK_PROTOCOLS = new Set([\"http:\", \"https:\", \"mailto:\", \"tel:\"]);\nconst INLINE_TOKEN_KIND_ATTR = \"data-chat-inline-token-kind\";\nconst INLINE_TOKEN_KEY_ATTR = \"data-chat-inline-token-key\";\nconst INLINE_TOKEN_LABEL_ATTR = \"data-chat-inline-token-label\";\nconst INLINE_TOKEN_RAW_TEXT_ATTR = \"data-chat-inline-token-raw-text\";\nconst PROJECT_RELATIVE_FILE_EXTENSION_PATTERN =\n \"cjs|css|cts|html?|js|json|jsx|mdx?|mjs|mts|tsx?|txt|ya?ml\";\nconst PROJECT_RELATIVE_FILE_HREF_PATTERN = new RegExp(\n `^(?![a-zA-Z][a-zA-Z\\\\d+.-]*:)(?!//)(?:(?:[^/\\\\s?#]+/)+[^?#\\\\s]+\\\\.[A-Za-z0-9_-]+|[^/\\\\s?#]+\\\\.(?:${PROJECT_RELATIVE_FILE_EXTENSION_PATTERN}))(?::\\\\d+(?::\\\\d+)?)?(?:[?#].*)?$`,\n \"i\",\n);\n\nfunction trimMarkdown(value: string): string {\n if (value.length <= MARKDOWN_MAX_CHARS) {\n return value;\n }\n return `${value.slice(0, MARKDOWN_MAX_CHARS)}\\n\\n...`;\n}\n\nfunction resolveSafeHref(href?: string): string | null {\n if (!href) {\n return null;\n }\n if (\n href.startsWith(\"#\") ||\n href.startsWith(\"/\") ||\n href.startsWith(\"./\") ||\n href.startsWith(\"../\") ||\n PROJECT_RELATIVE_FILE_HREF_PATTERN.test(href)\n ) {\n return href;\n }\n try {\n const url = new URL(href);\n return SAFE_LINK_PROTOCOLS.has(url.protocol) ? href : null;\n } catch {\n return null;\n }\n}\n\nfunction isExternalHref(href: string): boolean {\n return /^https?:\\/\\//i.test(href);\n}\n\nfunction looksLikeLocalFileHref(href: string): boolean {\n return (\n href.startsWith(\"./\") ||\n href.startsWith(\"../\") ||\n href.startsWith(\"/Users/\") ||\n href.startsWith(\"/home/\") ||\n href.startsWith(\"/tmp/\") ||\n href.startsWith(\"/var/\") ||\n PROJECT_RELATIVE_FILE_HREF_PATTERN.test(href) ||\n /^\\/.+\\.[A-Za-z0-9_-]+(?::\\d+(?::\\d+)?)?$/.test(href)\n );\n}\n\nfunction parseLocalFileAction(\n href: string,\n): ChatFileOpenActionViewModel | null {\n const viewer = new URLSearchParams(href.split(\"#\")[0]?.split(\"?\")[1] ?? \"\").get(\"viewer\");\n const normalizedHref = href.split(\"#\")[0]?.split(\"?\")[0] ?? href;\n const decodedHref = decodeURIComponent(normalizedHref);\n if (!looksLikeLocalFileHref(decodedHref)) {\n return null;\n }\n const lineMatch = /^(.*?)(?::(\\d+)(?::(\\d+))?)$/.exec(decodedHref);\n const rawPath = lineMatch?.[1] ?? decodedHref;\n const line = lineMatch?.[2] ? Number(lineMatch[2]) : undefined;\n const column = lineMatch?.[3] ? Number(lineMatch[3]) : undefined;\n return {\n path: rawPath,\n label: rawPath.split(\"/\").filter(Boolean).pop() ?? rawPath,\n viewMode: \"preview\",\n ...(viewer === \"source\" || viewer === \"rendered\" ? { previewViewer: viewer } : {}),\n ...(typeof line === \"number\" ? { line } : {}),\n ...(typeof column === \"number\" ? { column } : {}),\n };\n}\n\ntype ChatMessageMarkdownProps = {\n text: string;\n role: ChatMessageRole;\n texts: Pick<ChatMessageTexts, \"copyCodeLabel\" | \"copiedCodeLabel\">;\n inline?: boolean;\n inlineTokens?: readonly ChatInlineTokenViewModel[];\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n};\n\ntype MarkdownNode = {\n type?: string;\n value?: string;\n children?: MarkdownNode[];\n data?: {\n hName?: string;\n hProperties?: Record<string, string>;\n hChildren?: Array<{ type: \"text\"; value: string }>;\n };\n};\n\nfunction prepareInlineTokens(\n inlineTokens: readonly ChatInlineTokenViewModel[] | undefined,\n): ChatInlineTokenViewModel[] {\n if (!inlineTokens || inlineTokens.length === 0) {\n return [];\n }\n const seenRawTexts = new Set<string>();\n const tokens: ChatInlineTokenViewModel[] = [];\n for (const token of inlineTokens) {\n if (!token.rawText || seenRawTexts.has(token.rawText)) {\n continue;\n }\n seenRawTexts.add(token.rawText);\n tokens.push(token);\n }\n return tokens.sort((left, right) => right.rawText.length - left.rawText.length);\n}\n\nfunction createInlineTokenNode(token: ChatInlineTokenViewModel): MarkdownNode {\n return {\n type: \"chatInlineToken\",\n data: {\n hName: \"span\",\n hProperties: {\n [INLINE_TOKEN_KIND_ATTR]: token.kind,\n [INLINE_TOKEN_KEY_ATTR]: token.key,\n [INLINE_TOKEN_LABEL_ATTR]: token.label,\n [INLINE_TOKEN_RAW_TEXT_ATTR]: token.rawText,\n },\n hChildren: [{ type: \"text\", value: token.label }],\n },\n };\n}\n\nfunction findNextInlineToken(\n value: string,\n cursor: number,\n tokens: readonly ChatInlineTokenViewModel[],\n): { index: number; token: ChatInlineTokenViewModel } | null {\n let next: { index: number; token: ChatInlineTokenViewModel } | null = null;\n for (const token of tokens) {\n const index = value.indexOf(token.rawText, cursor);\n if (index < 0) {\n continue;\n }\n if (\n !next ||\n index < next.index ||\n (index === next.index && token.rawText.length > next.token.rawText.length)\n ) {\n next = { index, token };\n }\n }\n return next;\n}\n\nfunction splitTextNodeByInlineTokens(\n value: string,\n tokens: readonly ChatInlineTokenViewModel[],\n): MarkdownNode[] {\n const output: MarkdownNode[] = [];\n let cursor = 0;\n\n while (cursor < value.length) {\n const next = findNextInlineToken(value, cursor, tokens);\n if (!next) {\n output.push({ type: \"text\", value: value.slice(cursor) });\n break;\n }\n if (next.index > cursor) {\n output.push({ type: \"text\", value: value.slice(cursor, next.index) });\n }\n output.push(createInlineTokenNode(next.token));\n cursor = next.index + next.token.rawText.length;\n }\n\n return output.length > 0 ? output : [{ type: \"text\", value }];\n}\n\nfunction transformInlineTokenTextNodes(\n node: MarkdownNode,\n tokens: readonly ChatInlineTokenViewModel[],\n): void {\n if (node.type === \"code\" || node.type === \"inlineCode\" || !node.children) {\n return;\n }\n\n const nextChildren: MarkdownNode[] = [];\n for (const child of node.children) {\n if (child.type === \"text\" && typeof child.value === \"string\") {\n nextChildren.push(...splitTextNodeByInlineTokens(child.value, tokens));\n continue;\n }\n transformInlineTokenTextNodes(child, tokens);\n nextChildren.push(child);\n }\n node.children = nextChildren;\n}\n\nfunction createRemarkInlineTokenPlugin(\n inlineTokens: readonly ChatInlineTokenViewModel[],\n) {\n const tokens = prepareInlineTokens(inlineTokens);\n return () => (tree: MarkdownNode) => {\n if (tokens.length === 0) {\n return;\n }\n transformInlineTokenTextNodes(tree, tokens);\n };\n}\n\nfunction readStringProp(props: Record<string, unknown>, key: string): string | null {\n const value = props[key];\n return typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nexport function ChatMessageMarkdown({\n text,\n role,\n texts,\n inline = false,\n inlineTokens,\n onFileOpen,\n renderInlineDisplay,\n}: ChatMessageMarkdownProps) {\n const isUser = role === \"user\";\n const remarkPlugins = useMemo(\n () =>\n inlineTokens && inlineTokens.length > 0\n ? [remarkGfm, createRemarkInlineTokenPlugin(inlineTokens)]\n : [remarkGfm],\n [inlineTokens],\n );\n const markdownComponents = useMemo<Components>(\n () => ({\n p: ({ children }) => (inline ? <>{children}</> : <p>{children}</p>),\n span: ({ node: _node, children, ...rest }) => {\n const restProps = rest as Record<string, unknown>;\n const kind = readStringProp(restProps, INLINE_TOKEN_KIND_ATTR);\n const key = readStringProp(restProps, INLINE_TOKEN_KEY_ATTR);\n const label = readStringProp(restProps, INLINE_TOKEN_LABEL_ATTR);\n const rawText = readStringProp(restProps, INLINE_TOKEN_RAW_TEXT_ATTR);\n if (kind && key && label && rawText) {\n return (\n <ChatInlineTokenBadge\n kind={kind}\n label={label}\n isUser={isUser}\n />\n );\n }\n return <span {...rest}>{children}</span>;\n },\n a: ({ node: _node, href, children, ...rest }) => {\n const safeHref = resolveSafeHref(href);\n if (!safeHref) {\n return <span className=\"chat-link-invalid\">{children}</span>;\n }\n const external = isExternalHref(safeHref);\n const localFileAction = external\n ? null\n : parseLocalFileAction(safeHref);\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (!onFileOpen || !localFileAction) {\n return;\n }\n if (\n event.defaultPrevented ||\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n event.preventDefault();\n onFileOpen(localFileAction);\n };\n return (\n <a\n {...rest}\n href={safeHref}\n onClick={handleClick}\n target={external ? \"_blank\" : undefined}\n rel={external ? \"noreferrer noopener\" : undefined}\n >\n {children}\n </a>\n );\n },\n table: ({ node: _node, children, ...rest }) => (\n <div className=\"chat-table-wrap\">\n <table {...rest}>{children}</table>\n </div>\n ),\n input: ({ node: _node, type, checked, ...rest }) => {\n if (type !== \"checkbox\") {\n return <input {...rest} type={type} />;\n }\n return (\n <input\n {...rest}\n type=\"checkbox\"\n checked={checked}\n readOnly\n disabled\n className=\"chat-task-checkbox\"\n />\n );\n },\n img: ({ node: _node, src, alt, ...rest }) => {\n const safeSrc = resolveSafeHref(src);\n if (!safeSrc) {\n return null;\n }\n return (\n <img\n {...rest}\n src={safeSrc}\n alt={alt || \"\"}\n loading=\"lazy\"\n decoding=\"async\"\n />\n );\n },\n code: ({ node: _node, className, children, ...rest }) => {\n const plainText = String(children ?? \"\");\n const isInlineCode = !className && !plainText.includes(\"\\n\");\n if (isInlineCode) {\n return (\n <code {...rest} className={cn(\"chat-inline-code\", className)}>\n {children}\n </code>\n );\n }\n const inlineDisplay = isChatInlineDisplayLanguage(className)\n ? parseChatInlineDisplayDirective(plainText)\n : null;\n if (inlineDisplay) {\n return (\n <ChatInlineDisplay\n display={inlineDisplay}\n renderInlineDisplay={renderInlineDisplay}\n />\n );\n }\n return (\n <ChatCodeBlock className={className} texts={texts}>\n {children as ReactNode}\n </ChatCodeBlock>\n );\n },\n }),\n [inline, isUser, onFileOpen, renderInlineDisplay, texts],\n );\n\n const WrapperTag = inline ? \"span\" : \"div\";\n\n return (\n <WrapperTag\n className={cn(\n \"chat-markdown\",\n isUser ? \"chat-markdown-user\" : \"chat-markdown-assistant\",\n )}\n >\n <ReactMarkdown\n skipHtml\n remarkPlugins={remarkPlugins}\n components={markdownComponents}\n >\n {trimMarkdown(text)}\n </ReactMarkdown>\n </WrapperTag>\n );\n}\n","import type {\n ChatAttachmentCategory,\n ChatMessagePartViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\n\nexport type ChatMessageFileView = Extract<\n ChatMessagePartViewModel,\n { type: \"file\" }\n>[\"file\"];\n\nexport type FileCategory = ChatAttachmentCategory;\n\nexport const FILE_CATEGORY_TILE_CLASSES: Record<FileCategory, string> = {\n archive: \"border-border bg-muted text-muted-foreground\",\n audio: \"border-border bg-muted text-muted-foreground\",\n code: \"border-border bg-muted text-muted-foreground\",\n data: \"border-border bg-muted text-muted-foreground\",\n document: \"border-border bg-muted text-muted-foreground\",\n generic: \"border-border bg-muted text-muted-foreground\",\n image: \"border-border bg-muted text-muted-foreground\",\n pdf: \"border-border bg-muted text-muted-foreground\",\n sheet: \"border-border bg-muted text-muted-foreground\",\n video: \"border-border bg-muted text-muted-foreground\",\n};\n\nconst CODE_EXTENSIONS = new Set([\n \"c\",\n \"cpp\",\n \"css\",\n \"go\",\n \"html\",\n \"java\",\n \"js\",\n \"jsx\",\n \"md\",\n \"php\",\n \"py\",\n \"rb\",\n \"rs\",\n \"sh\",\n \"sql\",\n \"svg\",\n \"ts\",\n \"tsx\",\n]);\n\nconst DATA_EXTENSIONS = new Set([\n \"graphql\",\n \"json\",\n \"toml\",\n \"xml\",\n \"yaml\",\n \"yml\",\n]);\nconst IMAGE_EXTENSIONS = new Set([\n \"avif\",\n \"bmp\",\n \"gif\",\n \"heic\",\n \"heif\",\n \"ico\",\n \"jpeg\",\n \"jpg\",\n \"png\",\n \"svg\",\n \"tif\",\n \"tiff\",\n \"webp\",\n]);\nconst AUDIO_EXTENSIONS = new Set([\n \"aac\",\n \"flac\",\n \"m4a\",\n \"mp3\",\n \"ogg\",\n \"opus\",\n \"wav\",\n \"weba\",\n]);\nconst VIDEO_EXTENSIONS = new Set([\n \"avi\",\n \"m4v\",\n \"mov\",\n \"mp4\",\n \"mkv\",\n \"webm\",\n \"wmv\",\n]);\nconst DOCUMENT_EXTENSIONS = new Set([\n \"doc\",\n \"docx\",\n \"odt\",\n \"pages\",\n \"rtf\",\n \"txt\",\n]);\nconst SHEET_EXTENSIONS = new Set([\n \"csv\",\n \"numbers\",\n \"ods\",\n \"tsv\",\n \"xls\",\n \"xlsx\",\n]);\nconst ARCHIVE_EXTENSIONS = new Set([\n \"7z\",\n \"bz2\",\n \"gz\",\n \"rar\",\n \"tar\",\n \"tgz\",\n \"zip\",\n]);\n\nfunction formatFileSize(sizeBytes?: number): string | null {\n if (!Number.isFinite(sizeBytes) || sizeBytes == null || sizeBytes < 0) {\n return null;\n }\n if (sizeBytes === 0) {\n return \"0 B\";\n }\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n let value = sizeBytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1;\n return `${value.toFixed(digits).replace(/\\.0$/, \"\")} ${units[unitIndex]}`;\n}\n\nfunction getFileExtension(label: string, mimeType: string): string {\n const extension = readFileExtension(label);\n if (extension) {\n return extension.toUpperCase();\n }\n const subtype = mimeType.split(\"/\")[1] ?? \"\";\n const cleaned = subtype.split(/[+.;-]/)[0]?.trim();\n if (!cleaned) {\n return \"FILE\";\n }\n return cleaned.slice(0, 6).toUpperCase();\n}\n\nfunction readFileExtension(label: string): string {\n return /\\.([a-z0-9]{1,12})$/i.exec(label.trim())?.[1]?.toLowerCase() ?? \"\";\n}\n\nfunction truncateDisplayCode(value: string): string {\n return value.trim().slice(0, 4).toUpperCase();\n}\n\nfunction isImageDataUrl(dataUrl?: string): boolean {\n return typeof dataUrl === \"string\" && /^data:image\\//i.test(dataUrl.trim());\n}\n\nfunction inferMimeTypeFromExtension(extension: string): string | null {\n if (IMAGE_EXTENSIONS.has(extension)) {\n if (extension === \"jpg\" || extension === \"jpeg\") {\n return \"image/jpeg\";\n }\n if (extension === \"svg\") {\n return \"image/svg+xml\";\n }\n return `image/${extension}`;\n }\n if (AUDIO_EXTENSIONS.has(extension)) {\n if (extension === \"mp3\") {\n return \"audio/mpeg\";\n }\n if (extension === \"m4a\") {\n return \"audio/mp4\";\n }\n if (extension === \"weba\") {\n return \"audio/webm\";\n }\n return `audio/${extension}`;\n }\n if (VIDEO_EXTENSIONS.has(extension)) {\n if (extension === \"mov\") {\n return \"video/quicktime\";\n }\n if (extension === \"m4v\") {\n return \"video/mp4\";\n }\n return `video/${extension}`;\n }\n if (extension === \"pdf\") {\n return \"application/pdf\";\n }\n return null;\n}\n\nexport function inferMimeTypeFromFileName(fileName: string): string | null {\n const extension = readFileExtension(fileName);\n if (!extension) {\n return null;\n }\n return inferMimeTypeFromExtension(extension);\n}\n\nexport function resolveRenderableMimeType(file: ChatMessageFileView): string | null {\n const normalizedMimeType = file.mimeType.trim().toLowerCase();\n if (\n normalizedMimeType.length > 0 &&\n normalizedMimeType !== \"application/octet-stream\"\n ) {\n return normalizedMimeType;\n }\n return inferMimeTypeFromFileName(file.label);\n}\n\nexport function isImageFileLike(file: ChatMessageFileView): boolean {\n const normalizedMimeType = file.mimeType.trim().toLowerCase();\n const extension = readFileExtension(file.label);\n return (\n file.isImage ||\n normalizedMimeType.startsWith(\"image/\") ||\n IMAGE_EXTENSIONS.has(extension) ||\n isImageDataUrl(file.dataUrl)\n );\n}\n\nfunction resolveFileCategory(label: string, mimeType: string): FileCategory {\n const extension = readFileExtension(label);\n const normalizedMimeType = mimeType.toLowerCase();\n\n if (normalizedMimeType.startsWith(\"image/\") || IMAGE_EXTENSIONS.has(extension)) {\n return \"image\";\n }\n if (normalizedMimeType.startsWith(\"audio/\") || AUDIO_EXTENSIONS.has(extension)) {\n return \"audio\";\n }\n if (normalizedMimeType.startsWith(\"video/\") || VIDEO_EXTENSIONS.has(extension)) {\n return \"video\";\n }\n if (normalizedMimeType.includes(\"pdf\") || extension === \"pdf\") {\n return \"pdf\";\n }\n if (\n ARCHIVE_EXTENSIONS.has(extension) ||\n /(zip|tar|gzip|rar|compressed|archive)/.test(normalizedMimeType)\n ) {\n return \"archive\";\n }\n if (\n SHEET_EXTENSIONS.has(extension) ||\n /(spreadsheet|sheet|excel|csv)/.test(normalizedMimeType)\n ) {\n return \"sheet\";\n }\n if (\n DATA_EXTENSIONS.has(extension) ||\n /(json|xml|yaml|toml)/.test(normalizedMimeType)\n ) {\n return \"data\";\n }\n if (\n CODE_EXTENSIONS.has(extension) ||\n /(javascript|typescript|jsx|tsx|css|html)/.test(normalizedMimeType)\n ) {\n return \"code\";\n }\n if (\n DOCUMENT_EXTENSIONS.has(extension) ||\n /(msword|document|opendocument|rtf|text\\/)/.test(normalizedMimeType)\n ) {\n return \"document\";\n }\n return \"generic\";\n}\n\nexport function buildChatMessageFileMeta(file: ChatMessageFileView): {\n category: FileCategory;\n extension: string;\n sizeLabel: string | null;\n} {\n const category = resolveFileCategory(file.label, file.mimeType);\n const sizeLabel = formatFileSize(file.sizeBytes);\n return {\n category,\n extension: getFileExtension(file.label, file.mimeType),\n sizeLabel,\n };\n}\n\nexport function getFileCategoryDisplayCode(\n category: FileCategory,\n extension: string,\n): string {\n if (category === \"image\") {\n return \"IMG\";\n }\n if (category === \"video\") {\n return \"VID\";\n }\n if (category === \"audio\") {\n return \"AUD\";\n }\n if (category === \"generic\") {\n return truncateDisplayCode(extension || \"FILE\");\n }\n return truncateDisplayCode(extension);\n}\n","import { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport {\n File,\n FileArchive,\n FileAudio2,\n FileCode2,\n FileImage,\n FileJson2,\n FileSpreadsheet,\n FileText,\n FileVideo2,\n} from \"lucide-react\";\nimport {\n buildChatMessageFileMeta,\n FILE_CATEGORY_TILE_CLASSES,\n isImageFileLike,\n resolveRenderableMimeType,\n type FileCategory,\n type ChatMessageFileView,\n} from \"./meta\";\nimport type { ChatMessageTexts } from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\n\ntype ChatMessageFileProps = {\n file: ChatMessageFileView;\n isUser?: boolean;\n texts?: Pick<\n ChatMessageTexts,\n \"attachmentOpenLabel\" | \"attachmentAttachedLabel\" | \"attachmentCategoryLabels\"\n >;\n};\n\nconst DEFAULT_FILE_CATEGORY_LABELS: Record<FileCategory, string> = {\n archive: \"Archive\",\n audio: \"Audio\",\n code: \"Code file\",\n data: \"Data file\",\n document: \"Document\",\n generic: \"File\",\n image: \"Image\",\n pdf: \"PDF document\",\n sheet: \"Spreadsheet\",\n video: \"Video\",\n};\n\nconst FILE_CATEGORY_ICONS: Record<FileCategory, typeof File> = {\n archive: FileArchive,\n audio: FileAudio2,\n code: FileCode2,\n data: FileJson2,\n document: FileText,\n generic: File,\n image: FileImage,\n pdf: FileText,\n sheet: FileSpreadsheet,\n video: FileVideo2,\n};\n\nfunction readFileCategoryLabel(\n category: FileCategory,\n texts?: ChatMessageFileProps[\"texts\"],\n): string {\n return (\n texts?.attachmentCategoryLabels?.[category] ??\n DEFAULT_FILE_CATEGORY_LABELS[category]\n );\n}\n\nfunction renderMetaLine(\n categoryLabel: string,\n sizeLabel: string | null,\n isUser: boolean,\n) {\n return (\n <div\n className={cn(\n \"mt-1 text-xs leading-5\",\n isUser ? \"text-primary-foreground/70\" : \"text-muted-foreground\",\n )}\n >\n {sizeLabel ? `${categoryLabel} · ${sizeLabel}` : categoryLabel}\n </div>\n );\n}\n\nfunction renderActionPill(\n label: string,\n isUser: boolean,\n isInteractive: boolean,\n) {\n return (\n <span\n className={cn(\n \"inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium\",\n isInteractive\n ? isUser\n ? \"border-primary-foreground/14 bg-primary-foreground/12 text-primary-foreground\"\n : \"border-border bg-card text-foreground\"\n : isUser\n ? \"border-primary-foreground/10 bg-primary-foreground/6 text-primary-foreground/62\"\n : \"border-border bg-muted text-muted-foreground\",\n )}\n >\n {label}\n </span>\n );\n}\n\nfunction renderActionLink(\n label: string,\n href: string,\n isUser: boolean,\n) {\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n className={cn(\n \"inline-flex items-center rounded-full border px-2.5 py-1 text-[11px] font-medium transition duration-200\",\n isUser\n ? \"border-primary-foreground/14 bg-primary-foreground/12 text-primary-foreground hover:border-primary-foreground/20 hover:bg-primary-foreground/16\"\n : \"border-border bg-card text-foreground hover:border-border-hover hover:bg-accent\",\n )}\n >\n {label}\n </a>\n );\n}\n\nfunction FileCategoryGlyph({\n category,\n isUser,\n}: {\n category: FileCategory;\n isUser: boolean;\n}) {\n const Icon = FILE_CATEGORY_ICONS[category];\n\n return (\n <div\n className={cn(\n \"flex h-14 w-14 shrink-0 items-center justify-center rounded-[1rem] border\",\n isUser\n ? \"border-primary-foreground/12 bg-primary-foreground/10 text-primary-foreground\"\n : FILE_CATEGORY_TILE_CLASSES[category],\n )}\n >\n <Icon\n className={cn(\n \"h-7 w-7\",\n isUser ? \"text-primary-foreground/92\" : \"text-current\",\n )}\n strokeWidth={2.2}\n />\n </div>\n );\n}\n\nfunction renderImagePreview(params: {\n file: ChatMessageFileView;\n categoryLabel: string;\n sizeLabel: string | null;\n isUser: boolean;\n}) {\n const { file, categoryLabel, sizeLabel, isUser } = params;\n if (!file.dataUrl) {\n return null;\n }\n return (\n <a\n href={file.dataUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"group block\"\n >\n <div\n className={cn(\n \"relative overflow-hidden rounded-[1rem]\",\n isUser\n ? \"ring-1 ring-primary-foreground/10\"\n : \"bg-muted ring-1 ring-border\",\n )}\n >\n <img\n src={file.dataUrl}\n alt={file.label}\n className=\"block h-auto max-h-[26rem] w-full rounded-[1rem] bg-transparent object-contain transition duration-300 group-hover:scale-[1.01]\"\n />\n <div className=\"pointer-events-none absolute right-3 top-3 flex items-center gap-2\">\n <span\n className={cn(\n \"inline-flex items-center rounded-full px-2 py-1 text-[10px] font-semibold tracking-[0.18em] text-white backdrop-blur-sm\",\n isUser ? \"bg-black/36\" : \"bg-black/58\",\n )}\n >\n {categoryLabel}\n </span>\n {sizeLabel ? (\n <span\n className={cn(\n \"inline-flex items-center rounded-full px-2 py-1 text-[10px] font-medium text-white/92 backdrop-blur-sm\",\n isUser ? \"bg-black/28\" : \"bg-black/46\",\n )}\n >\n {sizeLabel}\n </span>\n ) : null}\n </div>\n </div>\n </a>\n );\n}\n\nfunction renderFileCardHeader(params: {\n category: FileCategory;\n file: ChatMessageFileView;\n categoryLabel: string;\n sizeLabel: string | null;\n isUser: boolean;\n action: React.ReactNode;\n}) {\n const { category, file, categoryLabel, sizeLabel, isUser, action } = params;\n return (\n <div className=\"flex items-center gap-3 p-3.5\">\n <FileCategoryGlyph\n category={category}\n isUser={isUser}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-3\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-[15px] font-semibold leading-5\">\n {file.label}\n </div>\n {renderMetaLine(categoryLabel, sizeLabel, isUser)}\n </div>\n {action}\n </div>\n </div>\n </div>\n );\n}\n\nfunction renderInlineMediaCard(params: {\n category: FileCategory;\n file: ChatMessageFileView;\n categoryLabel: string;\n sizeLabel: string | null;\n isUser: boolean;\n shellClasses: string;\n actionLabel: string;\n}) {\n const { category, file, categoryLabel, sizeLabel, isUser, shellClasses, actionLabel } = params;\n if (!file.dataUrl || (category !== \"audio\" && category !== \"video\")) {\n return null;\n }\n const mediaMimeType = resolveRenderableMimeType(file);\n return (\n <div className={shellClasses}>\n {renderFileCardHeader({\n category,\n file,\n categoryLabel,\n sizeLabel,\n isUser,\n action: renderActionLink(actionLabel, file.dataUrl, isUser),\n })}\n <div className=\"px-3.5 pb-3.5\">\n {category === \"audio\" ? (\n <audio\n controls\n preload=\"metadata\"\n aria-label={file.label}\n className=\"block w-full\"\n >\n <source\n src={file.dataUrl}\n {...(mediaMimeType ? { type: mediaMimeType } : {})}\n />\n </audio>\n ) : (\n <div\n className={cn(\n \"overflow-hidden rounded-[1rem] border\",\n isUser\n ? \"border-primary-foreground/10 bg-black/26\"\n : \"border-border bg-muted\",\n )}\n >\n <video\n controls\n preload=\"metadata\"\n playsInline\n aria-label={file.label}\n className=\"block max-h-[28rem] w-full bg-black\"\n >\n <source\n src={file.dataUrl}\n {...(mediaMimeType ? { type: mediaMimeType } : {})}\n />\n </video>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function ChatMessageFile({\n file,\n isUser = false,\n texts,\n}: ChatMessageFileProps) {\n const { category, sizeLabel } = buildChatMessageFileMeta(file);\n const renderAsImage = isImageFileLike(file) && Boolean(file.dataUrl);\n const renderAsAudio = category === \"audio\" && Boolean(file.dataUrl);\n const renderAsVideo = category === \"video\" && Boolean(file.dataUrl);\n const isInteractive = Boolean(file.dataUrl);\n const actionLabel = isInteractive\n ? texts?.attachmentOpenLabel ?? \"Open\"\n : texts?.attachmentAttachedLabel ?? \"Attached\";\n const categoryLabel = readFileCategoryLabel(category, texts);\n const shellClasses = cn(\n \"block overflow-hidden rounded-[1.25rem] border transition duration-200\",\n isUser\n ? \"border-primary-foreground/12 bg-primary-foreground/10 text-primary-foreground\"\n : \"border-border bg-card text-card-foreground\",\n isInteractive &&\n (isUser\n ? \"hover:border-primary-foreground/18 hover:bg-primary-foreground/13\"\n : \"hover:border-border-hover hover:bg-accent\"),\n );\n\n if (renderAsImage) {\n return renderImagePreview({ file, categoryLabel, sizeLabel, isUser });\n }\n\n if (renderAsAudio || renderAsVideo) {\n return renderInlineMediaCard({\n category,\n file,\n categoryLabel,\n sizeLabel,\n isUser,\n shellClasses,\n actionLabel,\n });\n }\n\n const content = renderFileCardHeader({\n category,\n file,\n categoryLabel,\n sizeLabel,\n isUser,\n action: renderActionPill(actionLabel, isUser, isInteractive),\n });\n\n if (!isInteractive || !file.dataUrl) {\n return <div className={shellClasses}>{content}</div>;\n }\n\n return (\n <a\n href={file.dataUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className={cn(shellClasses, \"group\")}\n >\n {content}\n </a>\n );\n}\n","import { useEffect, useRef, useState, type MouseEvent } from \"react\";\n\ntype UseReasoningBlockOpenStateParams = {\n isInProgress: boolean;\n};\n\ntype UseReasoningBlockOpenStateResult = {\n isOpen: boolean;\n onSummaryClick: (event: MouseEvent<HTMLElement>) => void;\n};\n\nexport function useReasoningBlockOpenState(\n params: UseReasoningBlockOpenStateParams,\n): UseReasoningBlockOpenStateResult {\n const { isInProgress } = params;\n const [isOpen, setIsOpen] = useState(isInProgress);\n const [keepOpenAfterCompletion, setKeepOpenAfterCompletion] = useState(false);\n const previousInProgressRef = useRef(isInProgress);\n\n useEffect(() => {\n const wasInProgress = previousInProgressRef.current;\n if (!wasInProgress && isInProgress) {\n setIsOpen(true);\n setKeepOpenAfterCompletion(false);\n } else if (wasInProgress && !isInProgress && !keepOpenAfterCompletion) {\n setIsOpen(false);\n }\n previousInProgressRef.current = isInProgress;\n }, [isInProgress, keepOpenAfterCompletion]);\n\n function onSummaryClick(event: MouseEvent<HTMLElement>) {\n event.preventDefault();\n const nextOpen = !isOpen;\n setIsOpen(nextOpen);\n\n if (!nextOpen) {\n setKeepOpenAfterCompletion(false);\n return;\n }\n\n if (isInProgress) {\n setKeepOpenAfterCompletion(true);\n }\n }\n\n return {\n isOpen,\n onSummaryClick,\n };\n}\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type RefObject,\n} from \"react\";\n\ntype UseStickyBottomScrollParams = {\n scrollRef: RefObject<HTMLElement>;\n resetKey: string | null;\n isLoading: boolean;\n hasContent: boolean;\n contentVersion: unknown;\n stickyThresholdPx?: number;\n};\n\ntype UseStickyBottomScrollResult = {\n isAtBottom: boolean;\n onScroll: () => void;\n scrollToBottom: () => void;\n};\n\nconst DEFAULT_STICKY_THRESHOLD_PX = 10;\n\nexport function useStickyBottomScroll({\n contentVersion,\n hasContent,\n isLoading,\n resetKey,\n scrollRef,\n stickyThresholdPx,\n}: UseStickyBottomScrollParams): UseStickyBottomScrollResult {\n const [isAtBottom, setIsAtBottom] = useState(true);\n const isStickyRef = useRef(true);\n const isProgrammaticScrollRef = useRef(false);\n const previousResetKeyRef = useRef<string | null>(null);\n const pendingInitialScrollRef = useRef(false);\n const scheduledScrollFrameRef = useRef<number | null>(null);\n\n const updateStickyState = useCallback((nextIsAtBottom: boolean) => {\n isStickyRef.current = nextIsAtBottom;\n setIsAtBottom(nextIsAtBottom);\n }, []);\n\n const resolveIsAtBottom = useCallback(\n (element: HTMLElement): boolean => {\n const distanceFromBottom =\n element.scrollHeight - element.scrollTop - element.clientHeight;\n return (\n distanceFromBottom <=\n (stickyThresholdPx ?? DEFAULT_STICKY_THRESHOLD_PX)\n );\n },\n [stickyThresholdPx],\n );\n\n const queueScrollToBottom = useCallback((behavior: ScrollBehavior = \"auto\") => {\n const element = scrollRef.current;\n if (!element) {\n return;\n }\n\n if (scheduledScrollFrameRef.current !== null) {\n cancelAnimationFrame(scheduledScrollFrameRef.current);\n }\n\n scheduledScrollFrameRef.current = requestAnimationFrame(() => {\n scheduledScrollFrameRef.current = null;\n const currentElement = scrollRef.current;\n if (!currentElement) {\n return;\n }\n\n isProgrammaticScrollRef.current = true;\n if (typeof currentElement.scrollTo === \"function\") {\n currentElement.scrollTo({\n top: currentElement.scrollHeight,\n behavior,\n });\n } else {\n currentElement.scrollTop = currentElement.scrollHeight;\n }\n });\n }, [scrollRef]);\n\n const scrollToBottom = useCallback(() => {\n updateStickyState(true);\n queueScrollToBottom();\n }, [queueScrollToBottom, updateStickyState]);\n\n const onScroll = useCallback(() => {\n if (isProgrammaticScrollRef.current) {\n isProgrammaticScrollRef.current = false;\n return;\n }\n\n const element = scrollRef.current;\n if (!element) {\n return;\n }\n\n updateStickyState(resolveIsAtBottom(element));\n }, [resolveIsAtBottom, scrollRef, updateStickyState]);\n\n useEffect(() => {\n if (previousResetKeyRef.current === resetKey) {\n return;\n }\n\n previousResetKeyRef.current = resetKey;\n updateStickyState(true);\n pendingInitialScrollRef.current = true;\n }, [resetKey, updateStickyState]);\n\n useEffect(() => {\n return () => {\n const scheduledScrollFrame = scheduledScrollFrameRef.current;\n if (scheduledScrollFrame !== null) {\n cancelAnimationFrame(scheduledScrollFrame);\n scheduledScrollFrameRef.current = null;\n }\n };\n }, []);\n\n useLayoutEffect(() => {\n if (\n !pendingInitialScrollRef.current ||\n isLoading ||\n !hasContent\n ) {\n return;\n }\n\n const element = scrollRef.current;\n if (!element) {\n return;\n }\n\n pendingInitialScrollRef.current = false;\n queueScrollToBottom();\n }, [hasContent, isLoading, queueScrollToBottom, scrollRef]);\n\n useLayoutEffect(() => {\n if (!isStickyRef.current || !hasContent) {\n return;\n }\n\n const element = scrollRef.current;\n if (!element) {\n return;\n }\n\n queueScrollToBottom();\n }, [contentVersion, hasContent, queueScrollToBottom, scrollRef]);\n\n return { isAtBottom, onScroll, scrollToBottom };\n}\n","import { useRef } from \"react\";\nimport { useReasoningBlockOpenState } from \"@agent-chat-ui/components/chat/hooks/use-reasoning-block-open-state\";\nimport { useStickyBottomScroll } from \"@agent-chat-ui/components/chat/hooks/use-sticky-bottom-scroll\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\n\ntype ChatReasoningBlockProps = {\n label: string;\n text: string;\n isUser: boolean;\n isInProgress: boolean;\n};\n\nfunction normalizeReasoningLabel(label: string): string {\n const normalizedLabel = label.trim().toLowerCase();\n if (\n normalizedLabel === \"reasoning\" ||\n normalizedLabel === \"thinking\" ||\n normalizedLabel === \"推理\" ||\n normalizedLabel === \"推理过程\" ||\n normalizedLabel === \"思考过程\" ||\n normalizedLabel === \"思考\"\n ) {\n return \"思考\";\n }\n return label;\n}\n\nexport function ChatReasoningBlock({ label, text, isUser, isInProgress }: ChatReasoningBlockProps) {\n const { isOpen, onSummaryClick } = useReasoningBlockOpenState({\n isInProgress,\n });\n const scrollRef = useRef<HTMLDivElement>(null);\n const displayLabel = normalizeReasoningLabel(label);\n const { onScroll } = useStickyBottomScroll({\n scrollRef,\n resetKey: `${displayLabel}:${isInProgress ? \"streaming\" : \"idle\"}`,\n isLoading: false,\n hasContent: text.length > 0,\n contentVersion: text,\n stickyThresholdPx: 20,\n });\n\n return (\n <details className=\"mt-2\" open={isOpen}>\n <summary\n className={cn(\"cursor-pointer text-xs\", isUser ? \"text-primary-100\" : \"text-muted-foreground\")}\n onClick={onSummaryClick}\n >\n {displayLabel}\n </summary>\n <div\n ref={scrollRef}\n onScroll={onScroll}\n data-reasoning-scroll=\"true\"\n className={cn(\n \"mt-2 w-fit max-w-[500px] max-h-56 overflow-y-auto rounded-lg custom-scrollbar\",\n isUser ? \"bg-primary/70\" : \"bg-muted\",\n )}\n >\n <pre className=\"min-w-0 whitespace-pre-wrap break-all p-2 text-[11px]\">{text}</pre>\n </div>\n </details>\n );\n}\n","import { cn } from '@agent-chat-ui/components/chat/internal/cn';\nimport type { ReactNode } from 'react';\n\nexport function ToolCardRoot({ children, className }: { children: ReactNode; className?: string }) {\n return (\n <div \n className={cn(\n \"my-2 rounded-lg border border-border bg-card shadow-sm overflow-hidden text-[12px] text-card-foreground\",\n \"w-[280px] sm:w-[360px] md:w-[480px] min-w-full max-w-full transition-all flex flex-col\",\n className\n )}\n >\n {children}\n </div>\n );\n}\n\nexport function ToolCardContent({ children, className }: { children: ReactNode; className?: string }) {\n return (\n <div className={cn(\"border-t border-border bg-muted/35 px-3 pt-1 pb-2 w-full overflow-hidden\", className)}>\n {children}\n </div>\n );\n}\n","import { Check, Loader2, AlertTriangle, Minus } from 'lucide-react';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\nimport type { ChatToolPartViewModel } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nexport const STATUS_STYLES = {\n running: { text: 'text-primary/70', icon: Loader2, spin: true },\n success: { text: 'text-primary/70', icon: Check, spin: false },\n error: { text: 'text-destructive', icon: AlertTriangle, spin: false },\n cancelled: { text: 'text-muted-foreground', icon: Minus, spin: false }\n} as const;\n\nexport function ToolStatusLabel({ card }: { card: ChatToolPartViewModel }) {\n const style = STATUS_STYLES[card.statusTone] || STATUS_STYLES.cancelled;\n const Icon = style.icon;\n\n return (\n <span className={cn('inline-flex items-center gap-1.5 text-[11px] font-medium leading-none shrink-0', style.text)}>\n <Icon className={cn(\"h-3.5 w-3.5\", style.spin && \"animate-spin\")} strokeWidth={3} />\n {card.statusTone === 'running' ? card.statusLabel : null}\n </span>\n );\n}\n","import { ArrowUpRight, ChevronDown, ChevronRight, Eye, type LucideIcon } from 'lucide-react';\nimport type { MouseEvent, ReactNode } from 'react';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\nimport { ChatUiPrimitives } from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport { ToolStatusLabel } from './tool-card-status';\nimport type {\n ChatToolActionViewModel,\n ChatToolPartViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nfunction resolveToolCardActionView(action: ChatToolActionViewModel): {\n icon: LucideIcon;\n label: string;\n toneClassName: string;\n} {\n if (action.kind === 'show-content') {\n return {\n icon: Eye,\n label: action.label,\n toneClassName: 'border-border bg-card text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-primary/35',\n };\n }\n\n return {\n icon: ArrowUpRight,\n label: action.label ?? (action.sessionKind === 'child' ? 'Open child session' : 'Open session'),\n toneClassName: 'border-border bg-card text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:ring-primary/35',\n };\n}\n\nfunction ToolCardActionButton({\n action,\n onAction,\n}: {\n action: ChatToolActionViewModel;\n onAction: (action: ChatToolActionViewModel) => void;\n}) {\n const { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } = ChatUiPrimitives;\n const view = resolveToolCardActionView(action);\n const Icon = view.icon;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n onAction(action);\n };\n\n return (\n <TooltipProvider delayDuration={250}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={handleClick}\n className={cn(\n 'inline-flex h-7 w-7 items-center justify-center rounded-full border transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1',\n view.toneClassName,\n )}\n aria-label={view.label}\n title={view.label}\n >\n <Icon className=\"h-3.5 w-3.5\" strokeWidth={2.5} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"text-xs\">\n {view.label}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n\nexport function ToolCardHeader({ \n card, \n icon: Icon, \n expanded, \n canExpand,\n hideSummary = false,\n actionSlot,\n onToggle \n}: { \n card: ChatToolPartViewModel; \n icon: LucideIcon; \n expanded: boolean; \n canExpand: boolean;\n hideSummary?: boolean;\n actionSlot?: ReactNode;\n onToggle: () => void; \n}) {\n const summaryPart = hideSummary\n ? ''\n : card.summary?.replace(/^(command|path|args|query|input):\\s*/i, '') ?? '';\n\n return (\n <div \n className={cn(\n \"flex items-center gap-3 px-3 py-2.5 transition-colors bg-transparent\", \n canExpand ? \"cursor-pointer hover:bg-accent/70\" : \"\"\n )}\n onClick={onToggle}\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-2 overflow-hidden font-mono text-foreground\">\n <Icon className=\"h-4 w-4 text-primary/70 shrink-0\" strokeWidth={3} />\n <div className=\"flex min-w-0 flex-1 items-center gap-1.5 overflow-hidden\">\n <span className=\"font-bold shrink-0 tracking-tight\">{card.toolName}</span>\n {summaryPart && (\n <>\n <span className=\"text-muted-foreground/45 font-bold select-none shrink-0\">›</span>\n <span className=\"block min-w-0 flex-1 truncate font-normal text-muted-foreground\" title={summaryPart}>\n {summaryPart}\n </span>\n </>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-3 shrink-0\">\n {actionSlot}\n <ToolStatusLabel card={card} />\n {canExpand && (\n expanded ? (\n <ChevronDown className=\"h-4 w-4 text-muted-foreground\" strokeWidth={3} />\n ) : (\n <ChevronRight className=\"h-4 w-4 text-muted-foreground\" strokeWidth={3} />\n )\n )}\n </div>\n </div>\n );\n}\n\nexport function ToolCardHeaderAction({\n action,\n onAction,\n}: {\n action: ChatToolActionViewModel;\n onAction: (action: ChatToolActionViewModel) => void;\n}) {\n return <ToolCardActionButton action={action} onAction={onAction} />;\n}\n","import { useMemo } from \"react\";\nimport type {\n ChatFileOperationBlockViewModel,\n ChatFileOperationLineViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { chatCodeSyntaxHighlighter } from \"@agent-chat-ui/components/chat/ui/chat-message-list/code-block/chat-code-syntax-highlighter\";\n\nconst FILE_TEXT_CLASS_NAME = \"font-mono text-[11px] leading-5\";\nconst FILE_ROW_CLASS_NAME = `flex h-5 w-full ${FILE_TEXT_CLASS_NAME}`;\nconst FILE_LINE_NUMBER_CELL_CLASS_NAME =\n \"flex h-5 items-center justify-center px-2.5 tabular-nums select-none\";\n\nfunction readVisibleLineNumber(line: ChatFileOperationLineViewModel): string {\n const value = line.newLineNumber ?? line.oldLineNumber;\n return typeof value === \"number\" ? String(value) : \"\";\n}\n\nfunction readLineKey(\n prefix: string,\n line: ChatFileOperationLineViewModel,\n index: number,\n): string {\n return `${prefix}-${index}-${line.oldLineNumber ?? \"x\"}-${line.newLineNumber ?? \"x\"}`;\n}\n\nfunction hasVisibleLineNumber(line: ChatFileOperationLineViewModel): boolean {\n return (\n typeof line.newLineNumber === \"number\" ||\n typeof line.oldLineNumber === \"number\"\n );\n}\n\nfunction readHasBlockLineNumbers(block: ChatFileOperationBlockViewModel): boolean {\n return block.lines.some(hasVisibleLineNumber);\n}\n\nfunction readLineNumberColumnWidth(\n block: ChatFileOperationBlockViewModel,\n): string {\n const maxDigits = block.lines.reduce((currentMax, line) => {\n if (!hasVisibleLineNumber(line)) {\n return currentMax;\n }\n return Math.max(currentMax, readVisibleLineNumber(line).length);\n }, 0);\n const width = Math.max(6.5, Math.min(8, maxDigits + 3.5));\n return `${width}ch`;\n}\n\nfunction readCodeColumnWidth(block: ChatFileOperationBlockViewModel): string {\n const maxColumns = block.lines.reduce(\n (currentMax, line) => Math.max(currentMax, Math.max(1, line.text.length)),\n 1,\n );\n return `calc(${maxColumns}ch + 1.25rem)`;\n}\n\nfunction readPathExtension(path: string): string | null {\n const fileName = path.split(/[\\\\/]/).filter(Boolean).pop() ?? path;\n const cleanName = fileName.split(/[?#]/)[0] ?? fileName;\n const extensionStart = cleanName.lastIndexOf(\".\");\n if (extensionStart <= 0 || extensionStart === cleanName.length - 1) {\n return null;\n }\n return cleanName.slice(extensionStart + 1).toLowerCase();\n}\n\nfunction readBlockLanguage(block: ChatFileOperationBlockViewModel): string {\n const hint = block.languageHint?.trim();\n return hint || readPathExtension(block.path) || \"text\";\n}\n\nfunction readLanguageClassName(language: string): string {\n const normalized = language.toLowerCase().replace(/[^a-z0-9-]/g, \"-\");\n return normalized ? `language-${normalized}` : \"language-text\";\n}\n\nfunction getLineNumberTone(line: ChatFileOperationLineViewModel): string {\n if (line.kind === \"remove\") {\n return \"border-r border-rose-200 bg-rose-50 text-rose-700\";\n }\n if (line.kind === \"add\") {\n return \"border-r border-emerald-200 bg-emerald-50 text-emerald-700\";\n }\n return \"border-r border-border bg-muted text-muted-foreground\";\n}\n\nfunction getCodeRowTone(line: ChatFileOperationLineViewModel): string {\n if (line.kind === \"remove\") {\n return \"bg-rose-50 text-rose-950\";\n }\n if (line.kind === \"add\") {\n return \"bg-emerald-50 text-emerald-950\";\n }\n return \"bg-card text-foreground\";\n}\n\nfunction FileOperationLineNumberCell({\n layout,\n line,\n lineNumberColumnWidth,\n}: {\n layout: \"compact\" | \"workspace\";\n line: ChatFileOperationLineViewModel;\n lineNumberColumnWidth: string;\n}) {\n return (\n <span\n data-file-line-number-cell=\"true\"\n style={layout === \"compact\" ? { width: lineNumberColumnWidth, minWidth: lineNumberColumnWidth } : undefined}\n className={cn(\n FILE_LINE_NUMBER_CELL_CLASS_NAME,\n layout === \"compact\" ? \"sticky left-0 z-[1]\" : \"w-full shrink-0\",\n getLineNumberTone(line),\n )}\n >\n {readVisibleLineNumber(line)}\n </span>\n );\n}\n\nfunction FileOperationCodeCell({\n language,\n line,\n}: {\n language: string;\n line: ChatFileOperationLineViewModel;\n}) {\n const highlightedCode = useMemo(\n () => chatCodeSyntaxHighlighter.highlight(line.text || \" \", language),\n [language, line.text],\n );\n\n return (\n <span\n data-file-code-row=\"true\"\n data-file-code-language={highlightedCode.language}\n data-highlighted={highlightedCode.highlighted ? \"true\" : \"false\"}\n className={cn(\n \"chat-file-code-syntax hljs block min-w-0 flex-1 whitespace-pre px-2.5\",\n readLanguageClassName(highlightedCode.language),\n getCodeRowTone(line),\n )}\n dangerouslySetInnerHTML={{ __html: highlightedCode.html }}\n />\n );\n}\n\nfunction FileOperationLineRow({\n language,\n line,\n showLineNumbers,\n lineNumberColumnWidth,\n}: {\n language: string;\n line: ChatFileOperationLineViewModel;\n showLineNumbers: boolean;\n lineNumberColumnWidth: string;\n}) {\n return (\n <div data-file-line-row=\"true\" className={FILE_ROW_CLASS_NAME}>\n {showLineNumbers ? (\n <FileOperationLineNumberCell\n layout=\"compact\"\n line={line}\n lineNumberColumnWidth={lineNumberColumnWidth}\n />\n ) : null}\n <FileOperationCodeCell language={language} line={line} />\n </div>\n );\n}\n\nfunction FileOperationWorkspaceSurface({\n block,\n}: {\n block: ChatFileOperationBlockViewModel;\n}) {\n const showLineNumbers = readHasBlockLineNumbers(block);\n const lineNumberColumnWidth = readLineNumberColumnWidth(block);\n const codeColumnWidth = readCodeColumnWidth(block);\n const language = readBlockLanguage(block);\n\n return (\n <div\n data-file-code-surface=\"true\"\n data-file-code-surface-layout=\"workspace\"\n className=\"flex h-full min-h-full min-w-full bg-card\"\n >\n {showLineNumbers ? (\n <div\n data-file-code-gutter=\"true\"\n style={{\n width: lineNumberColumnWidth,\n minWidth: lineNumberColumnWidth,\n }}\n className={cn(\n \"flex h-full min-h-full shrink-0 flex-col\",\n FILE_TEXT_CLASS_NAME,\n )}\n >\n {block.lines.map((line, index) => (\n <FileOperationLineNumberCell\n key={readLineKey(\"gutter\", line, index)}\n layout=\"workspace\"\n line={line}\n lineNumberColumnWidth={lineNumberColumnWidth}\n />\n ))}\n <div className=\"min-h-0 flex-1 border-r border-border bg-muted\" />\n </div>\n ) : null}\n\n <div\n data-file-code-canvas=\"true\"\n className=\"flex h-full min-h-full min-w-0 flex-1 flex-col bg-card\"\n >\n <div\n data-file-code-stack=\"true\"\n className=\"min-w-full\"\n style={{ minWidth: codeColumnWidth }}\n >\n {block.lines.map((line, index) => (\n <div\n key={readLineKey(\"code\", line, index)}\n data-file-code-canvas-row=\"true\"\n className={FILE_ROW_CLASS_NAME}\n >\n <FileOperationCodeCell language={language} line={line} />\n </div>\n ))}\n </div>\n <div className=\"min-h-0 flex-1 bg-card\" />\n </div>\n </div>\n );\n}\n\nexport function FileOperationCodeSurface({\n block,\n layout = \"compact\",\n}: {\n block: ChatFileOperationBlockViewModel;\n layout?: \"compact\" | \"workspace\";\n}) {\n if (layout === \"workspace\") {\n return <FileOperationWorkspaceSurface block={block} />;\n }\n\n const showLineNumbers = readHasBlockLineNumbers(block);\n const lineNumberColumnWidth = readLineNumberColumnWidth(block);\n const codeColumnWidth = readCodeColumnWidth(block);\n const surfaceMinWidth = showLineNumbers\n ? `calc(${lineNumberColumnWidth} + ${codeColumnWidth})`\n : codeColumnWidth;\n const language = readBlockLanguage(block);\n\n return (\n <div\n data-file-code-surface=\"true\"\n data-file-code-surface-layout=\"compact\"\n className=\"overflow-x-auto custom-scrollbar bg-card\"\n >\n <div\n data-file-code-stack=\"true\"\n className=\"min-w-full\"\n style={{ minWidth: surfaceMinWidth }}\n >\n {block.lines.map((line, index) => (\n <FileOperationLineRow\n key={readLineKey(\"row\", line, index)}\n language={language}\n line={line}\n showLineNumbers={showLineNumbers}\n lineNumberColumnWidth={lineNumberColumnWidth}\n />\n ))}\n </div>\n </div>\n );\n}\n\nexport function FileOperationLinesGrid({\n block,\n}: {\n block: ChatFileOperationBlockViewModel;\n}) {\n return <FileOperationCodeSurface block={block} layout=\"compact\" />;\n}\n","import type {\n ChatFileOpenActionViewModel,\n ChatFileOperationBlockViewModel,\n ChatToolPartViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { useStickyBottomScroll } from \"@agent-chat-ui/components/chat/hooks/use-sticky-bottom-scroll\";\nimport { Fragment, type ReactNode, useRef } from \"react\";\nimport { ChatUiPrimitives } from \"@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives\";\nimport { FileOperationLinesGrid } from \"./tool-card-file-operation-lines\";\n\nfunction isPreviewBlock(block: ChatFileOperationBlockViewModel): boolean {\n return block.display === \"preview\";\n}\n\nfunction readFileOperationContentVersion(\n block: Pick<ChatFileOperationBlockViewModel, \"lines\" | \"rawText\">,\n): string {\n if (block.rawText) {\n return block.rawText;\n }\n return block.lines\n .map((line) =>\n [\n line.kind,\n line.oldLineNumber ?? \"\",\n line.newLineNumber ?? \"\",\n line.text,\n ].join(\":\"),\n )\n .join(\"\\n\");\n}\n\nfunction getCaptionTone(part: string): string {\n if (/^\\+\\d+$/.test(part)) {\n return \"text-emerald-700\";\n }\n if (/^-\\d+$/.test(part)) {\n return \"text-rose-700\";\n }\n return \"text-muted-foreground\";\n}\n\nfunction renderCaption(caption: string) {\n const parts = caption\n .split(\"·\")\n .map((part) => part.trim())\n .filter((part) => /^\\+\\d+$/.test(part) || /^-\\d+$/.test(part));\n if (parts.length === 0) {\n return null;\n }\n return (\n <div className=\"flex shrink-0 items-center gap-x-1 whitespace-nowrap text-[10px] font-medium uppercase tracking-[0.08em]\">\n {parts.map((part, index) => (\n <Fragment key={`${part}-${index}`}>\n {index > 0 ? <span className=\"text-muted-foreground/45\">·</span> : null}\n <span className={cn(getCaptionTone(part))}>{part}</span>\n </Fragment>\n ))}\n </div>\n );\n}\n\nfunction buildFileOpenAction(\n block: ChatFileOperationBlockViewModel,\n): ChatFileOpenActionViewModel {\n return {\n path: block.path,\n label: block.path.split(\"/\").filter(Boolean).pop() ?? block.path,\n viewMode: block.display === \"diff\" ? \"diff\" : \"preview\",\n ...(block.rawText ? { rawText: block.rawText } : {}),\n ...(block.beforeText ? { beforeText: block.beforeText } : {}),\n ...(block.afterText ? { afterText: block.afterText } : {}),\n ...(block.patchText ? { patchText: block.patchText } : {}),\n ...(typeof block.oldStartLine === \"number\"\n ? { oldStartLine: block.oldStartLine }\n : {}),\n ...(typeof block.newStartLine === \"number\"\n ? { newStartLine: block.newStartLine }\n : {}),\n fullLines: block.fullLines ?? block.lines,\n };\n}\n\nfunction StickyFileOperationScrollArea({\n children,\n contentVersion,\n resetKey,\n className,\n scrollKind,\n}: {\n children: ReactNode;\n contentVersion: unknown;\n resetKey: string;\n className?: string;\n scrollKind: \"block\" | \"raw\" | \"output\";\n}) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const { onScroll } = useStickyBottomScroll({\n scrollRef,\n resetKey,\n isLoading: false,\n hasContent: true,\n contentVersion,\n stickyThresholdPx: 20,\n });\n\n return (\n <div\n ref={scrollRef}\n onScroll={onScroll}\n data-file-scroll-kind={scrollKind}\n className={cn(\n \"overflow-y-auto bg-card custom-scrollbar\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\nfunction FileOperationBlock({\n block,\n showPathRow,\n isFirst,\n onFileOpen,\n}: {\n block: ChatFileOperationBlockViewModel;\n showPathRow: boolean;\n isFirst: boolean;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n}) {\n const { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } =\n ChatUiPrimitives;\n const previewBlock = isPreviewBlock(block);\n const showMetaRow = showPathRow || Boolean(block.caption);\n\n const handlePathClick = () => {\n if (!onFileOpen) {\n return;\n }\n onFileOpen(buildFileOpenAction(block));\n };\n\n return (\n <section\n className={cn(\n \"overflow-hidden bg-card\",\n !isFirst && \"border-t border-border\",\n )}\n >\n {showMetaRow ? (\n <div\n className={cn(\n \"flex items-center justify-between gap-4 border-b border-border px-4 text-muted-foreground\",\n showPathRow ? \"py-2\" : \"py-1.5\",\n )}\n >\n <div className=\"min-w-0 flex-1\">\n {showPathRow ? (\n <TooltipProvider delayDuration={250}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={handlePathClick}\n className={cn(\n \"w-full truncate whitespace-nowrap text-left font-mono text-[12px] font-medium text-foreground\",\n onFileOpen &&\n \"transition-colors hover:text-primary hover:underline\",\n )}\n title={block.path}\n >\n {block.path}\n </button>\n </TooltipTrigger>\n <TooltipContent\n side=\"top\"\n className=\"max-w-[420px] text-xs font-mono break-all\"\n >\n {block.path}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n {block.caption ? renderCaption(block.caption) : null}\n </div>\n ) : null}\n\n {block.lines.length > 0 ? (\n <StickyFileOperationScrollArea\n resetKey={`block:${block.key}`}\n contentVersion={readFileOperationContentVersion(block)}\n className=\"max-h-72\"\n scrollKind=\"block\"\n >\n <FileOperationLinesGrid block={block} />\n </StickyFileOperationScrollArea>\n ) : block.rawText ? (\n <StickyFileOperationScrollArea\n resetKey={`raw:${block.key}`}\n contentVersion={block.rawText}\n className=\"max-h-72\"\n scrollKind=\"raw\"\n >\n <div className=\"overflow-x-auto custom-scrollbar\">\n <pre className=\"min-w-max whitespace-pre bg-card px-4 py-2 font-mono text-[11px] leading-5 text-foreground\">\n {block.rawText}\n </pre>\n </div>\n </StickyFileOperationScrollArea>\n ) : null}\n\n {block.truncated && !previewBlock ? (\n <div className=\"border-t border-border bg-muted px-4 py-2 text-[10px] text-muted-foreground\">\n Showing a shortened diff preview.\n </div>\n ) : null}\n </section>\n );\n}\n\nexport function ToolCardFileOperationContent({\n card,\n className,\n onFileOpen,\n}: {\n card: ChatToolPartViewModel;\n className?: string;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n}) {\n const blocks = card.fileOperation?.blocks ?? [];\n const output = card.output?.trim() ?? \"\";\n if (blocks.length === 0 && !output) {\n return null;\n }\n\n return (\n <div className={cn(\"overflow-hidden bg-card\", className)}>\n {blocks.map((block, index) => {\n return (\n <FileOperationBlock\n key={block.key}\n block={block}\n showPathRow={true}\n isFirst={index === 0}\n onFileOpen={onFileOpen}\n />\n );\n })}\n\n {output ? (\n <StickyFileOperationScrollArea\n resetKey={`output:${card.toolName}:${card.summary ?? \"none\"}`}\n contentVersion={output}\n className={cn(\n \"max-h-56\",\n blocks.length > 0 && \"border-t border-border\",\n )}\n scrollKind=\"output\"\n >\n <div className=\"overflow-x-auto custom-scrollbar\">\n <pre className=\"min-w-max whitespace-pre bg-card px-4 py-2 font-mono text-[11px] leading-5 text-foreground\">\n {output}\n </pre>\n </div>\n </StickyFileOperationScrollArea>\n ) : null}\n </div>\n );\n}\n","import { Terminal, FileText, Code2, Search, Globe } from 'lucide-react';\nimport { useState, useEffect, useRef, type ReactNode } from 'react';\nimport type {\n ChatFileOpenActionViewModel,\n ChatToolActionViewModel,\n ChatToolPartViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { ToolCardRoot, ToolCardContent } from './tool-card-root';\nimport { ToolCardHeader, ToolCardHeaderAction } from './tool-card-header';\nimport { ToolCardFileOperationContent } from './tool-card-file-operation';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nconst TOOL_CARD_AUTO_EXPAND_DELAY_MS = 200;\nconst ANSI_ESCAPE_PREFIX = String.fromCharCode(27);\nconst ANSI_ESCAPE_PATTERN = new RegExp(`${ANSI_ESCAPE_PREFIX}\\\\[[0-?]*[ -/]*[@-~]`, 'g');\n\nfunction readNonEmptyString(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n return value.length > 0 ? value : null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stripAnsi(value: string): string {\n return value.replace(ANSI_ESCAPE_PATTERN, '');\n}\n\nfunction isStructuredTerminalRecord(record: Record<string, unknown>): boolean {\n return (\n 'command' in record ||\n 'workingDir' in record ||\n 'exitCode' in record ||\n 'durationMs' in record ||\n 'stdout' in record ||\n 'stderr' in record ||\n 'aggregated_output' in record ||\n 'combinedOutput' in record\n );\n}\n\nfunction extractTerminalOutputFromRecord(record: Record<string, unknown>): string | null {\n const aggregatedOutput =\n readNonEmptyString(record.aggregated_output) ??\n readNonEmptyString(record.combinedOutput) ??\n readNonEmptyString(record.output);\n if (aggregatedOutput) {\n return aggregatedOutput;\n }\n\n const stdout = readNonEmptyString(record.stdout);\n const stderr = readNonEmptyString(record.stderr);\n if (!stdout && !stderr) {\n return null;\n }\n return [stdout, stderr].filter((value): value is string => Boolean(value)).join('\\n');\n}\n\nfunction normalizeTerminalOutput(rawOutput?: string, structuredOutput?: unknown): string {\n if (isRecord(structuredOutput)) {\n const terminalOutput = extractTerminalOutputFromRecord(structuredOutput);\n if (terminalOutput) {\n return stripAnsi(terminalOutput);\n }\n if (isStructuredTerminalRecord(structuredOutput)) {\n return '';\n }\n }\n if (!rawOutput) {\n return '';\n }\n const trimmed = rawOutput.trim();\n if (!trimmed.startsWith('{')) {\n return stripAnsi(rawOutput);\n }\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!isRecord(parsed)) {\n return stripAnsi(rawOutput);\n }\n const terminalOutput = extractTerminalOutputFromRecord(parsed);\n if (terminalOutput) {\n return stripAnsi(terminalOutput);\n }\n if (isStructuredTerminalRecord(parsed)) {\n return '';\n }\n return stripAnsi(rawOutput);\n } catch {\n return stripAnsi(rawOutput);\n }\n}\n\nfunction shouldAutoExpandRunningFileOperation(toolName: string): boolean {\n return toolName === 'write_file' || toolName === 'edit_file';\n}\n\nfunction useToolCardExpandedState({\n canExpand,\n isRunning,\n autoExpandWhileRunning = true,\n expandOnError = false,\n statusTone,\n}: {\n canExpand: boolean;\n isRunning: boolean;\n autoExpandWhileRunning?: boolean;\n expandOnError?: boolean;\n statusTone: ChatToolPartViewModel['statusTone'];\n}) {\n const [expanded, setExpanded] = useState(false);\n const [hasUserToggled, setHasUserToggled] = useState(false);\n const expandTimerRef = useRef<number | null>(null);\n const prevRunningRef = useRef(isRunning);\n const isFirstRenderRef = useRef(true);\n\n useEffect(() => {\n return () => {\n if (expandTimerRef.current !== null) {\n window.clearTimeout(expandTimerRef.current);\n }\n };\n }, []);\n\n useEffect(() => {\n if (expandOnError && statusTone === 'error' && canExpand && !hasUserToggled) {\n if (expandTimerRef.current !== null) {\n window.clearTimeout(expandTimerRef.current);\n expandTimerRef.current = null;\n }\n setExpanded(true);\n prevRunningRef.current = isRunning;\n isFirstRenderRef.current = false;\n return;\n }\n\n if (\n autoExpandWhileRunning &&\n isRunning &&\n canExpand &&\n !hasUserToggled &&\n !expanded &&\n (isFirstRenderRef.current || !prevRunningRef.current)\n ) {\n expandTimerRef.current = window.setTimeout(() => {\n setExpanded(true);\n expandTimerRef.current = null;\n }, TOOL_CARD_AUTO_EXPAND_DELAY_MS);\n }\n\n if (!isRunning) {\n if (expandTimerRef.current !== null) {\n window.clearTimeout(expandTimerRef.current);\n expandTimerRef.current = null;\n }\n if (prevRunningRef.current && !hasUserToggled) {\n setExpanded(false);\n }\n }\n\n prevRunningRef.current = isRunning;\n isFirstRenderRef.current = false;\n }, [autoExpandWhileRunning, canExpand, expandOnError, expanded, hasUserToggled, isRunning, statusTone]);\n\n const onToggle = () => {\n if (!canExpand) {\n return;\n }\n if (expandTimerRef.current !== null) {\n window.clearTimeout(expandTimerRef.current);\n expandTimerRef.current = null;\n }\n setExpanded((current) => !current);\n setHasUserToggled(true);\n };\n\n return { expanded, onToggle };\n}\n\nfunction GenericToolSection({\n label,\n tone,\n children,\n}: {\n label: string;\n tone: 'input' | 'output' | 'error';\n children: ReactNode;\n}) {\n const tones = {\n input: {\n shell: 'border-border bg-card',\n header: 'border-border bg-muted/55 text-muted-foreground',\n dot: 'bg-muted-foreground/60',\n body: 'text-foreground',\n },\n output: {\n shell: 'border-border bg-card',\n header: 'border-border bg-muted/55 text-muted-foreground',\n dot: 'bg-primary/70',\n body: 'text-foreground',\n },\n error: {\n shell: 'border-rose-200/80 bg-rose-50/85',\n header: 'border-rose-200/80 bg-rose-100/80 text-rose-700',\n dot: 'bg-rose-500/80',\n body: 'text-rose-950/85',\n },\n } as const;\n const style = tones[tone];\n\n return (\n <section\n className={cn(\n 'overflow-hidden rounded-md border shadow-[inset_0_1px_0_rgba(255,255,255,0.45)]',\n style.shell,\n )}\n >\n <div\n className={cn(\n 'flex items-center gap-2 border-b px-3 py-2 text-[10px] font-semibold uppercase tracking-[0.16em]',\n style.header,\n )}\n >\n <span className={cn('h-1.5 w-1.5 rounded-full', style.dot)} />\n <span>{label}</span>\n </div>\n <div className=\"w-full overflow-hidden\">\n <pre\n className={cn(\n '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',\n style.body,\n )}\n >\n {children}\n </pre>\n </div>\n </section>\n );\n}\n\nexport function TerminalExecutionView({ card }: { card: ChatToolPartViewModel }) {\n const output = normalizeTerminalOutput(card.output, card.outputData);\n const isRunning = card.statusTone === 'running';\n const commandPart = card.summary?.replace(/^(command|path|args|query|input):\\s*/i, '');\n const hasOutput = output.trim().length > 0;\n const canExpand = isRunning || hasOutput || Boolean(commandPart?.trim());\n const { expanded, onToggle } = useToolCardExpandedState({\n canExpand,\n isRunning,\n autoExpandWhileRunning: false,\n expandOnError: canExpand,\n statusTone: card.statusTone,\n });\n\n return (\n <ToolCardRoot>\n <ToolCardHeader \n card={card} \n icon={Terminal} \n expanded={expanded} \n canExpand={canExpand}\n onToggle={onToggle} \n />\n {expanded && (\n <>\n <div className=\"px-3 pb-2 font-mono w-full max-h-48 overflow-y-auto custom-scrollbar min-h-0 text-[12px]\">\n <div className=\"flex items-start gap-2 leading-relaxed\">\n <span className=\"text-primary/55 font-medium shrink-0 select-none mt-[1px]\">$</span>\n <div className=\"flex-1 min-w-0\">\n {commandPart ? (\n <div className=\"text-foreground break-words whitespace-pre-wrap tracking-tight font-medium inline-block\">\n {commandPart}\n {isRunning && !output && (\n <span className=\"inline-block w-1.5 h-3 ml-1 bg-primary/60 animate-pulse align-middle\" />\n )}\n </div>\n ) : (\n <div className=\"h-3 w-32 bg-muted rounded animate-pulse mt-2\" />\n )}\n </div>\n </div>\n </div>\n {(hasOutput || !isRunning) && (\n <ToolCardContent className={hasOutput ? undefined : 'bg-muted/20 py-2'}>\n <pre className={cn(\n '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',\n hasOutput ? 'px-0' : 'rounded-md border border-dashed border-border bg-card/70 px-3 py-2 italic',\n )}>\n {hasOutput ? output : card.emptyLabel}\n {isRunning && hasOutput && <span className=\"inline-block w-1.5 h-3 ml-1 bg-primary/60 animate-pulse align-middle\" />}\n </pre>\n </ToolCardContent>\n )}\n </>\n )}\n </ToolCardRoot>\n );\n}\n\nexport function FileOperationView({\n card,\n onFileOpen,\n}: {\n card: ChatToolPartViewModel;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n}) {\n const output = card.output?.trim() ?? '';\n const isRunning = card.statusTone === 'running';\n const hasStructuredPreview = Boolean(card.fileOperation?.blocks.length);\n const hasContent = hasStructuredPreview || Boolean(output);\n const previewBlocks = card.fileOperation?.blocks ?? [];\n const previewLineCount = previewBlocks.reduce((count, block) => count + block.lines.length, 0);\n const previewCharCount = previewBlocks.reduce((count, block) => {\n if (block.rawText) {\n return count + block.rawText.length;\n }\n return count + block.lines.reduce((lineCount, line) => lineCount + line.text.length + 1, 0);\n }, 0);\n const shouldAutoExpandWhileRunning =\n shouldAutoExpandRunningFileOperation(card.toolName) &&\n !(\n isRunning &&\n card.toolName === 'write_file' &&\n (previewLineCount > 24 || previewCharCount > 1_200)\n );\n const { expanded, onToggle } = useToolCardExpandedState({\n canExpand: hasContent || isRunning,\n isRunning,\n autoExpandWhileRunning: shouldAutoExpandWhileRunning,\n expandOnError: hasContent,\n statusTone: card.statusTone,\n });\n\n const isEdit = card.toolName === 'edit_file' || card.toolName === 'write_file' || card.toolName === 'apply_patch' || card.toolName === 'file_change';\n\n return (\n <ToolCardRoot>\n <ToolCardHeader \n card={card} \n icon={isEdit ? Code2 : FileText} \n expanded={expanded} \n canExpand={hasContent || isRunning} \n hideSummary={expanded && hasStructuredPreview}\n onToggle={onToggle} \n />\n {expanded && hasContent && (\n <ToolCardContent className=\"border-t border-border bg-transparent px-0 pt-0 pb-0\">\n <ToolCardFileOperationContent card={card} onFileOpen={onFileOpen} />\n </ToolCardContent>\n )}\n </ToolCardRoot>\n );\n}\n\nexport function SearchSnippetView({ card }: { card: ChatToolPartViewModel }) {\n const isRunning = card.statusTone === 'running';\n const output = card.output?.trim() ?? '';\n const { expanded, onToggle } = useToolCardExpandedState({\n canExpand: !!output || isRunning,\n isRunning,\n autoExpandWhileRunning: false,\n statusTone: card.statusTone,\n });\n\n return (\n <ToolCardRoot>\n <ToolCardHeader \n card={card} \n icon={Search} \n expanded={expanded} \n canExpand={!!output || isRunning} \n onToggle={onToggle} \n />\n {expanded && output && (\n <ToolCardContent>\n <pre 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\">\n {output}\n </pre>\n </ToolCardContent>\n )}\n </ToolCardRoot>\n );\n}\n\nexport function GenericToolCard({\n card,\n onToolAction,\n renderToolAgent,\n}: {\n card: ChatToolPartViewModel;\n onToolAction?: (action: ChatToolActionViewModel) => void;\n renderToolAgent?: (agentId: string) => ReactNode;\n}) {\n const input = card.input?.trim() ?? '';\n const output = card.output?.trim() ?? '';\n const isRunning = card.statusTone === 'running';\n const hasInputSection = input.length > 0;\n const hasOutputSection = output.length > 0;\n const hasContent = hasInputSection || hasOutputSection;\n const inputLabel = card.inputLabel?.trim() || 'Input';\n const outputLabel = card.outputLabel?.trim() || 'Output';\n const { expanded, onToggle } = useToolCardExpandedState({\n canExpand: hasContent || isRunning,\n isRunning,\n autoExpandWhileRunning: false,\n statusTone: card.statusTone,\n });\n\n return (\n <ToolCardRoot>\n <ToolCardHeader \n card={card} \n icon={Globe} \n expanded={expanded} \n canExpand={hasContent || isRunning} \n actionSlot={\n card.agentId || (card.action && onToolAction) ? (\n <>\n {card.agentId && renderToolAgent ? renderToolAgent(card.agentId) : null}\n {card.action && onToolAction ? (\n <ToolCardHeaderAction\n action={card.action}\n onAction={onToolAction}\n />\n ) : null}\n </>\n ) : undefined\n }\n onToggle={onToggle} \n />\n {expanded && hasContent && (\n <ToolCardContent className=\"bg-transparent px-2.5 py-2.5\">\n {hasInputSection && (\n <GenericToolSection label={inputLabel} tone=\"input\">\n {input}\n </GenericToolSection>\n )}\n {hasInputSection && hasOutputSection && (\n <div className=\"h-2\" />\n )}\n {hasOutputSection && (\n <GenericToolSection\n label={outputLabel}\n tone={card.statusTone === 'error' ? 'error' : 'output'}\n >\n {output}\n </GenericToolSection>\n )}\n </ToolCardContent>\n )}\n </ToolCardRoot>\n );\n}\n","import type { ReactNode } from 'react';\nimport type {\n ChatPanelAppCardViewModel,\n ChatToolActionViewModel,\n ChatToolPartViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { GenericToolCard } from './tool-card-views';\n\nexport function PanelAppInlineToolCard({\n card,\n onToolAction,\n renderPanelAppCard,\n}: {\n card: ChatToolPartViewModel;\n onToolAction?: (action: ChatToolActionViewModel) => void;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n}) {\n const { panelApp } = card;\n if (!panelApp) {\n return <GenericToolCard card={card} onToolAction={onToolAction} />;\n }\n if (renderPanelAppCard) {\n return renderPanelAppCard(panelApp);\n }\n\n return <GenericToolCard card={card} onToolAction={onToolAction} />;\n}\n","import type {\n ChatFileOpenActionViewModel,\n ChatPanelAppCardViewModel,\n ChatToolActionViewModel,\n ChatToolPartViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport type { ReactNode } from 'react';\nimport { TerminalExecutionView, FileOperationView, SearchSnippetView, GenericToolCard, PanelAppInlineToolCard } from './chat-tool-specialized';\n\nfunction isTerminalTool(name: string) {\n const lowered = name.toLowerCase();\n return lowered === 'exec' || lowered === 'exec_command' || lowered === 'execute_command' || lowered === 'command_execution' || lowered === 'bash' || lowered === 'shell' || lowered.includes('run_');\n}\n\nfunction isFileEditTool(name: string) {\n const lowered = name.toLowerCase();\n return lowered === 'read_file' || lowered === 'write_file' || lowered === 'edit_file' || lowered === 'apply_patch' || lowered === 'file_change';\n}\n\nfunction isSearchTool(name: string) {\n const lowered = name.toLowerCase();\n return lowered === 'grep_search' || lowered === 'find_files' || lowered.includes('search');\n}\n\nexport function ChatToolCard({\n card,\n onToolAction,\n onFileOpen,\n renderToolAgent,\n renderPanelAppCard,\n}: {\n card: ChatToolPartViewModel;\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n}) {\n if (card.panelApp) {\n return (\n <PanelAppInlineToolCard\n card={card}\n onToolAction={onToolAction}\n renderPanelAppCard={renderPanelAppCard}\n />\n );\n }\n if (isTerminalTool(card.toolName)) {\n return <TerminalExecutionView card={card} />;\n }\n if (isFileEditTool(card.toolName)) {\n return <FileOperationView card={card} onFileOpen={onFileOpen} />;\n }\n if (isSearchTool(card.toolName)) {\n return <SearchSnippetView card={card} />;\n }\n\n // Fallback minimalist card for read_url_content, multi_replace, etc.\n return (\n <GenericToolCard\n card={card}\n onToolAction={onToolAction}\n renderToolAgent={renderToolAgent}\n />\n );\n}\n","import { memo, type ReactNode } from \"react\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport type {\n ChatFileOpenActionViewModel,\n ChatInlineDisplayViewModel,\n ChatPanelAppCardViewModel,\n ChatMessageTexts,\n ChatMessagePartViewModel,\n ChatToolActionViewModel,\n ChatMessageViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { ChatMessageMarkdown } from \"./chat-message-markdown\";\nimport { ChatMessageFile } from \"./chat-message-file\";\nimport { ChatReasoningBlock } from \"./chat-reasoning-block\";\nimport { ChatToolCard } from \"./chat-tool-card\";\n\ntype ChatMessageProps = {\n message: ChatMessageViewModel;\n texts: Pick<\n ChatMessageTexts,\n | \"copyCodeLabel\"\n | \"copiedCodeLabel\"\n | \"attachmentOpenLabel\"\n | \"attachmentAttachedLabel\"\n | \"attachmentCategoryLabels\"\n >;\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n};\n\ntype ChatMessageProcessSplit = {\n processParts: ChatMessagePartViewModel[];\n finalParts: ChatMessagePartViewModel[];\n};\n\ntype RenderChatMessagePartParams = {\n part: ChatMessagePartViewModel;\n index: number;\n role: ChatMessageViewModel[\"role\"];\n isUser: boolean;\n isInProgress: boolean;\n isLastPart: boolean;\n texts: ChatMessageProps[\"texts\"];\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n};\n\nfunction isMessageInProgress(status?: string): boolean {\n return status === \"pending\" || status === \"streaming\";\n}\n\nfunction isProcessPart(part: ChatMessagePartViewModel): boolean {\n return part.type === \"reasoning\" || part.type === \"tool-card\";\n}\n\nfunction splitAssistantProcess(message: ChatMessageViewModel): ChatMessageProcessSplit | null {\n if (\n message.role !== \"assistant\" ||\n !message.processSummary ||\n isMessageInProgress(message.status)\n ) {\n return null;\n }\n let lastProcessPartIndex = -1;\n for (let index = message.parts.length - 1; index >= 0; index -= 1) {\n if (isProcessPart(message.parts[index]!)) {\n lastProcessPartIndex = index;\n break;\n }\n }\n if (lastProcessPartIndex < 0 || lastProcessPartIndex >= message.parts.length - 1) {\n return null;\n }\n return {\n processParts: message.parts.slice(0, lastProcessPartIndex + 1),\n finalParts: message.parts.slice(lastProcessPartIndex + 1),\n };\n}\n\nfunction renderChatMessagePart({\n index,\n isInProgress,\n isLastPart,\n isUser,\n onFileOpen,\n onToolAction,\n part,\n renderInlineDisplay,\n renderPanelAppCard,\n renderToolAgent,\n role,\n texts,\n}: RenderChatMessagePartParams): ReactNode {\n const { type } = part;\n\n if (type === \"markdown\") {\n const { inlineTokens, text } = part;\n return (\n <ChatMessageMarkdown\n key={`markdown-${index}`}\n text={text}\n role={role}\n texts={texts}\n inlineTokens={inlineTokens}\n onFileOpen={onFileOpen}\n renderInlineDisplay={renderInlineDisplay}\n />\n );\n }\n if (type === \"reasoning\") {\n const { label, text } = part;\n return (\n <ChatReasoningBlock\n key={`reasoning-${index}`}\n label={label}\n text={text}\n isUser={isUser}\n isInProgress={isInProgress && isLastPart}\n />\n );\n }\n if (type === \"tool-card\") {\n const { card } = part;\n return (\n <div key={`tool-${index}`} className=\"mt-0.5\">\n <ChatToolCard\n card={card}\n onToolAction={onToolAction}\n onFileOpen={onFileOpen}\n renderToolAgent={renderToolAgent}\n renderPanelAppCard={renderPanelAppCard}\n />\n </div>\n );\n }\n if (type === \"file\") {\n const { file } = part;\n return (\n <ChatMessageFile\n key={`file-${index}`}\n file={file}\n isUser={isUser}\n texts={texts}\n />\n );\n }\n if (type === \"unknown\") {\n const { label, rawType, text } = part;\n return (\n <div\n key={`unknown-${index}`}\n className=\"rounded-lg border border-border bg-muted/60 px-2.5 py-2 text-xs text-muted-foreground\"\n >\n <div className=\"font-semibold text-foreground\">\n {label}: {rawType}\n </div>\n {text ? <pre className=\"mt-1 whitespace-pre-wrap break-words text-[11px] text-muted-foreground\">{text}</pre> : null}\n </div>\n );\n }\n return null;\n}\n\nexport const ChatMessage = memo(function ChatMessage({\n message,\n texts,\n onToolAction,\n onFileOpen,\n renderInlineDisplay,\n renderToolAgent,\n renderPanelAppCard,\n}: ChatMessageProps) {\n const { role } = message;\n const isUser = role === \"user\";\n const isInProgress = isMessageInProgress(message.status);\n const processSplit = splitAssistantProcess(message);\n const renderPart = (part: ChatMessagePartViewModel, index: number) =>\n renderChatMessagePart({\n part,\n index,\n role,\n isUser,\n isInProgress,\n isLastPart: index === message.parts.length - 1,\n texts,\n onToolAction,\n onFileOpen,\n renderInlineDisplay,\n renderToolAgent,\n renderPanelAppCard,\n });\n\n return (\n <div\n className={cn(\n \"inline-block w-fit max-w-full rounded-2xl border px-4 shadow-sm has-[[data-chat-message-wide-content=true]]:w-full\",\n isUser\n ? \"nextclaw-chat-message-user rounded-[1.45rem] border-primary bg-primary py-2.5 text-primary-foreground shadow-none\"\n : role === \"assistant\"\n ? \"border-border bg-card pb-3 pt-4 text-card-foreground\"\n : \"border-border bg-muted/45 py-3 text-foreground\",\n )}\n >\n <div className=\"space-y-2\">\n {processSplit ? (\n <>\n <details className=\"group/process text-xs text-muted-foreground\">\n <summary className=\"flex cursor-pointer list-none items-center gap-1.5 border-b border-border/60 pb-2 font-medium transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35 [&::-webkit-details-marker]:hidden\">\n <ChevronRight className=\"h-3.5 w-3.5 group-open/process:hidden\" strokeWidth={2.5} />\n <ChevronDown className=\"hidden h-3.5 w-3.5 group-open/process:block\" strokeWidth={2.5} />\n <span>{message.processSummary?.label}</span>\n </summary>\n <div className=\"space-y-2 pt-2\">\n {processSplit.processParts.map(renderPart)}\n </div>\n </details>\n {processSplit.finalParts.map((part, index) =>\n renderPart(part, processSplit.processParts.length + index),\n )}\n </>\n ) : (\n message.parts.map(renderPart)\n )}\n </div>\n </div>\n );\n});\n","import { useMemo } from 'react';\nimport { useCopyFeedback } from '@agent-chat-ui/components/chat/hooks/use-copy-feedback';\nimport { Check, Copy } from 'lucide-react';\nimport type { ChatMessageViewModel, ChatMessageTexts } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nexport function ChatMessageActionCopy({\n message,\n texts,\n}: {\n message: ChatMessageViewModel;\n texts: Pick<ChatMessageTexts, 'copyMessageLabel' | 'copiedMessageLabel'>;\n}) {\n const messageText = useMemo(() => {\n return message.parts\n .map((part) => {\n if (part.type === 'markdown') return part.text;\n if (part.type === 'unknown') return part.text;\n return '';\n })\n .filter((text) => !!text && text.trim().length > 0)\n .join('\\n\\n');\n }, [message.parts]);\n\n const { copied, copy } = useCopyFeedback({ text: messageText });\n\n if (!messageText) return null;\n\n return (\n <button\n type=\"button\"\n onClick={() => void copy()}\n className=\"text-muted-foreground hover:text-foreground transition-colors p-1 rounded-md hover:bg-accent flex items-center justify-center\"\n aria-label={copied ? texts.copiedMessageLabel : texts.copyMessageLabel}\n title={copied ? texts.copiedMessageLabel : texts.copyMessageLabel}\n >\n {copied ? <Check className=\"h-3.5 w-3.5\" /> : <Copy className=\"h-3.5 w-3.5\" />}\n </button>\n );\n}\n","import type { ReactNode } from 'react';\nimport type {\n ChatFileOpenActionViewModel,\n ChatInlineDisplayViewModel,\n ChatMessageTexts,\n ChatMessageViewModel,\n ChatPanelAppCardViewModel,\n ChatToolActionViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\nimport { ChatMessageAvatar } from './chat-message-avatar';\nimport { ChatMessage } from './chat-message';\nimport { ChatMessageActionCopy } from './chat-message-action-copy';\n\nconst INVISIBLE_ONLY_TEXT_PATTERN = /\\u200B|\\u200C|\\u200D|\\u2060|\\uFEFF/g;\nconst TYPING_TEXT_SHEEN_CSS = `\n@keyframes nextclaw-chat-typing-text-sheen {\n 0% {\n background-position: 160% 0;\n }\n 100% {\n background-position: -60% 0;\n }\n}\n\n.nextclaw-chat-typing-indicator__text {\n background-image: linear-gradient(\n 100deg,\n hsl(var(--muted-foreground)) 0%,\n hsl(var(--muted-foreground)) 34%,\n hsl(var(--foreground-tertiary)) 43%,\n hsl(var(--foreground-muted)) 50%,\n hsl(var(--foreground-tertiary)) 57%,\n hsl(var(--muted-foreground)) 66%,\n hsl(var(--muted-foreground)) 100%\n );\n background-size: 240% 100%;\n background-position: 160% 0;\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n -webkit-text-fill-color: transparent;\n animation: nextclaw-chat-typing-text-sheen 2.5s linear infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .nextclaw-chat-typing-indicator__text {\n animation: none;\n background-image: none;\n color: hsl(var(--muted-foreground));\n -webkit-text-fill-color: currentColor;\n }\n}\n`;\n\nfunction hasRenderableText(value: string): boolean {\n const trimmed = value.trim();\n if (!trimmed) {\n return false;\n }\n return trimmed.replace(INVISIBLE_ONLY_TEXT_PATTERN, '').trim().length > 0;\n}\n\nexport type ChatMessageListProps = {\n messages: ChatMessageViewModel[];\n isSending: boolean;\n hasAssistantDraft: boolean;\n texts: ChatMessageTexts;\n className?: string;\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n};\n\nfunction hasRenderableMessageContent(message: ChatMessageViewModel): boolean {\n return message.parts.some((part) => {\n if (part.type === 'markdown' || part.type === 'reasoning') {\n return hasRenderableText(part.text);\n }\n return true;\n });\n}\n\nfunction ChatMessageTypingFooter() {\n return (\n <div className=\"flex items-center gap-2 px-1 py-0.5 text-[11px] text-muted-foreground\">\n <div className=\"flex space-x-1 items-center h-full\">\n <div className=\"h-1.5 w-1.5 rounded-full bg-muted-foreground animate-pulse\"></div>\n <div className=\"h-1.5 w-1.5 rounded-full bg-muted-foreground animate-pulse [animation-delay:200ms]\"></div>\n <div className=\"h-1.5 w-1.5 rounded-full bg-muted-foreground animate-pulse [animation-delay:400ms]\"></div>\n </div>\n </div>\n );\n}\n\nfunction ChatTypingIndicator({ label }: { label: string }) {\n return (\n <div className=\"rounded-2xl border border-border bg-card px-4 py-3 text-sm text-muted-foreground shadow-sm\">\n <style>{TYPING_TEXT_SHEEN_CSS}</style>\n <span className=\"nextclaw-chat-typing-indicator__text\">{label}</span>\n </div>\n );\n}\n\nexport function ChatMessageList({\n className,\n isSending,\n messages,\n onFileOpen,\n onToolAction,\n renderInlineDisplay,\n renderPanelAppCard,\n renderToolAgent,\n texts,\n}: ChatMessageListProps) {\n const visibleMessages = messages.filter(hasRenderableMessageContent);\n const hasRenderableAssistantDraft = visibleMessages.some(\n (message) =>\n message.role === 'assistant' &&\n (message.status === 'streaming' || message.status === 'pending')\n );\n\n return (\n <div className={cn('space-y-5', className)}>\n {visibleMessages.map((message) => {\n const isUser = message.role === 'user';\n const isGenerating = !isUser && (message.status === 'streaming' || message.status === 'pending');\n\n return (\n <div key={message.id} className={cn('flex gap-3', isUser ? 'justify-end' : 'justify-start')}>\n {!isUser ? <ChatMessageAvatar role={message.role} /> : null}\n <div className={cn('w-fit max-w-[92%] space-y-2 has-[[data-chat-message-wide-content=true]]:w-full', isUser && 'flex flex-col items-end')}>\n <ChatMessage\n message={message}\n texts={texts}\n onToolAction={onToolAction}\n onFileOpen={onFileOpen}\n renderInlineDisplay={renderInlineDisplay}\n renderToolAgent={renderToolAgent}\n renderPanelAppCard={renderPanelAppCard}\n />\n <div className={cn('flex items-center gap-2', isUser && 'justify-end')}>\n {isGenerating ? (\n <ChatMessageTypingFooter />\n ) : (\n <>\n <div\n className={cn(\n 'px-1 text-[11px] leading-4 text-muted-foreground',\n isUser ? 'text-right' : 'text-left'\n )}\n >\n {message.roleLabel} · {message.timestampLabel}\n </div>\n {!isUser ? <ChatMessageActionCopy message={message} texts={texts} /> : null}\n </>\n )}\n </div>\n </div>\n {isUser ? <ChatMessageAvatar role={message.role} /> : null}\n </div>\n );\n })}\n\n {isSending && !hasRenderableAssistantDraft ? (\n <div className=\"flex justify-start gap-3\">\n <ChatMessageAvatar role=\"assistant\" />\n <ChatTypingIndicator label={texts.typingLabel} />\n </div>\n ) : null}\n </div>\n );\n}\n","import type {\n ChatInputSurfaceItem,\n ChatInputSurfaceMenuTexts,\n ChatInputSurfaceTrigger,\n ChatInputSurfaceTriggerSpec,\n ChatInputSurfacePanel,\n ChatInputSurfacePlugin,\n ChatInputSurfacePluginContext,\n ChatInputSurfaceResolvedState,\n} from './input-surface.types';\n\nexport function createInputSurfaceTriggeredPanelPlugin<TData>(params: {\n key: string;\n trigger: ChatInputSurfaceTriggerSpec;\n resolvePanel: (context: ChatInputSurfacePluginContext<TData>) => ChatInputSurfacePanel | null;\n}): ChatInputSurfacePlugin<TData> {\n return {\n key: params.key,\n triggerSpecs: [params.trigger],\n resolvePanel: (context) =>\n context.trigger.key === params.trigger.key ? params.resolvePanel(context) : null,\n };\n}\n\nexport function createInputSurfaceReferenceTokenPlugin<TData, TRecord>(params: {\n key: string;\n trigger: ChatInputSurfaceTriggerSpec;\n tokenKind: string;\n texts: ChatInputSurfaceMenuTexts;\n getRecords: (context: ChatInputSurfacePluginContext<TData>) => readonly TRecord[];\n getIsLoading?: (context: ChatInputSurfacePluginContext<TData>) => boolean;\n getItems: (params: {\n context: ChatInputSurfacePluginContext<TData>;\n records: readonly TRecord[];\n query: string;\n tokenKind: string;\n }) => ChatInputSurfaceItem[];\n onSelectItem?: (item: ChatInputSurfaceItem) => void;\n}): ChatInputSurfacePlugin<TData> {\n return createInputSurfaceTriggeredPanelPlugin({\n key: params.key,\n trigger: params.trigger,\n resolvePanel: (context) => ({\n isLoading: params.getIsLoading?.(context) ?? false,\n items: params.getItems({\n context,\n records: params.getRecords(context),\n query: context.trigger.query,\n tokenKind: params.tokenKind,\n }),\n onSelectItem: params.onSelectItem,\n texts: params.texts,\n }),\n });\n}\n\nexport function resolveChatInputSurfaceState<TData>(params: {\n data: TData;\n plugins: readonly ChatInputSurfacePlugin<TData>[];\n trigger: ChatInputSurfaceTrigger | null;\n}): ChatInputSurfaceResolvedState {\n const { data, plugins, trigger } = params;\n const triggerSpecs = plugins.flatMap((plugin) => [...plugin.triggerSpecs]);\n if (!trigger) {\n return {\n triggerSpecs,\n panel: null,\n };\n }\n\n for (const plugin of plugins) {\n const panel = plugin.resolvePanel({\n data,\n trigger,\n });\n if (panel) {\n return {\n triggerSpecs,\n panel,\n };\n }\n }\n\n return {\n triggerSpecs,\n panel: null,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["DefaultPopover","DefaultPopoverAnchor","DefaultPopoverContent","DefaultPopoverTrigger","DefaultInput","DefaultSelect","DefaultSelectContent","DefaultSelectGroup","DefaultSelectItem","DefaultSelectLabel","DefaultSelectSeparator","DefaultSelectTrigger","DefaultSelectValue","DefaultTooltip","DefaultTooltipContent","DefaultTooltipProvider","DefaultTooltipTrigger","escapeHtml","CODE_LANGUAGE_REGEX","isRecord"],"sources":["../src/components/chat/ui/chat-input-bar/chat-composer.utils.ts","../src/components/chat/hooks/use-active-item-scroll.ts","../src/components/chat/hooks/use-element-width.ts","../src/components/chat/internal/cn.ts","../src/components/chat/default-skin/input.tsx","../src/components/chat/default-skin/popover.tsx","../src/components/chat/default-skin/select.tsx","../src/components/chat/default-skin/tooltip.tsx","../src/components/chat/ui/primitives/chat-ui-primitives.tsx","../src/components/chat/ui/input-surface/chat-input-surface-menu.tsx","../src/components/chat/ui/input-surface/chat-input-surface-host.tsx","../src/components/chat/default-skin/button.tsx","../src/components/chat/ui/chat-input-bar/chat-input-bar-actions.tsx","../src/components/chat/ui/chat-input-bar/chat-input-bar-skill-picker.tsx","../src/components/chat/ui/chat-input-bar/chat-input-bar-toolbar.tsx","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-token-node.tsx","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-editor-state.ts","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-operations.ts","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-controller.ts","../src/components/chat/ui/chat-input-bar/lexical/owners/chat-composer-lexical-owner.ts","../src/components/chat/ui/chat-input-bar/lexical/chat-composer-plugins.tsx","../src/components/chat/ui/chat-input-bar/lexical/chat-input-bar-tokenized-composer.tsx","../src/components/chat/ui/chat-input-bar/chat-input-bar.tsx","../src/components/chat/ui/chat-message-list/chat-message-avatar.tsx","../src/components/chat/ui/chat-message-list/chat-inline-token-badge.tsx","../src/components/chat/utils/copy-text.utils.ts","../src/components/chat/hooks/use-copy-feedback.ts","../src/components/chat/ui/chat-message-list/code-block/chat-code-syntax-highlighter.ts","../src/components/chat/ui/chat-message-list/chat-code-block.tsx","../src/components/chat/ui/chat-message-list/utils/chat-inline-display.utils.ts","../src/components/chat/ui/chat-message-list/chat-inline-display.tsx","../src/components/chat/ui/chat-message-list/chat-message-markdown.tsx","../src/components/chat/ui/chat-message-list/chat-message-file/meta.ts","../src/components/chat/ui/chat-message-list/chat-message-file/index.tsx","../src/components/chat/hooks/use-reasoning-block-open-state.ts","../src/components/chat/hooks/use-sticky-bottom-scroll.ts","../src/components/chat/ui/chat-message-list/chat-process-meta-row.tsx","../src/components/chat/ui/chat-message-list/chat-collapsible-meta-summary.tsx","../src/components/chat/ui/chat-message-list/chat-reasoning-block.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-root.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-status.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-header.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-file-operation-lines.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-file-operation.tsx","../src/components/chat/ui/chat-message-list/tool-card/terminal/terminal-ansi.utils.ts","../src/components/chat/ui/chat-message-list/tool-card/terminal/terminal-panes.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-views.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-generic.tsx","../src/components/chat/ui/chat-message-list/tool-card/tool-card-panel-app.tsx","../src/components/chat/ui/chat-message-list/chat-tool-card.tsx","../src/components/chat/ui/chat-message-list/chat-tool-activity-group.tsx","../src/components/chat/ui/chat-message-list/chat-tool-activity-group.utils.ts","../src/components/chat/ui/chat-message-list/chat-message.tsx","../src/components/chat/ui/chat-message-list/chat-message-action-copy.tsx","../src/components/chat/ui/chat-message-list/chat-message-list.tsx","../src/lib/input-surface/input-surface-plugin.utils.ts"],"sourcesContent":["import type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatComposerTextNode,\n ChatComposerTokenKind,\n ChatComposerTokenNode,\n ChatInputSurfaceTrigger,\n ChatInputSurfaceTriggerSpec,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nexport const CHAT_COMPOSER_TOKEN_PLACEHOLDER = '\\uFFFC';\nexport const CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC: ChatInputSurfaceTriggerSpec = {\n key: 'slash',\n marker: '/',\n};\n\nfunction createComposerNodeId(): string {\n return `composer-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport function createChatComposerTextNode(text = ''): ChatComposerTextNode {\n return {\n id: createComposerNodeId(),\n type: 'text',\n text\n };\n}\n\nexport function createChatComposerTokenNode(params: {\n tokenKind: ChatComposerTokenKind;\n tokenKey: string;\n label: string;\n}): ChatComposerTokenNode {\n return {\n id: createComposerNodeId(),\n type: 'token',\n tokenKind: params.tokenKind,\n tokenKey: params.tokenKey,\n label: params.label\n };\n}\n\nexport function getChatComposerNodeLength(node: ChatComposerNode): number {\n return node.type === 'text' ? node.text.length : 1;\n}\n\nexport function createEmptyChatComposerNodes(): ChatComposerNode[] {\n return [createChatComposerTextNode('')];\n}\n\nexport function createChatComposerNodesFromText(text: string): ChatComposerNode[] {\n return [createChatComposerTextNode(text)];\n}\n\nexport function normalizeChatComposerNodes(nodes: ChatComposerNode[]): ChatComposerNode[] {\n const normalized: ChatComposerNode[] = [];\n for (const node of nodes) {\n if (node.type === 'text') {\n if (node.text.length === 0) {\n continue;\n }\n const previous = normalized[normalized.length - 1];\n if (previous?.type === 'text') {\n normalized[normalized.length - 1] = {\n ...previous,\n text: previous.text + node.text\n };\n continue;\n }\n }\n normalized.push(node);\n }\n if (normalized.length === 0) {\n return createEmptyChatComposerNodes();\n }\n return normalized;\n}\n\nexport function serializeChatComposerDocument(nodes: ChatComposerNode[]): string {\n return nodes.map((node) => (node.type === 'text' ? node.text : CHAT_COMPOSER_TOKEN_PLACEHOLDER)).join('');\n}\n\nexport function serializeChatComposerPlainText(nodes: ChatComposerNode[]): string {\n return nodes.filter((node): node is ChatComposerTextNode => node.type === 'text').map((node) => node.text).join('');\n}\n\nexport function extractChatComposerTokenKeys(\n nodes: ChatComposerNode[],\n tokenKind: ChatComposerTokenKind\n): string[] {\n const keys: string[] = [];\n const keySet = new Set<string>();\n for (const node of nodes) {\n if (node.type !== 'token' || node.tokenKind !== tokenKind || keySet.has(node.tokenKey)) {\n continue;\n }\n keySet.add(node.tokenKey);\n keys.push(node.tokenKey);\n }\n return keys;\n}\n\nfunction buildTrimmedTextEdges(\n node: ChatComposerTextNode,\n nodeStart: number,\n rangeStart: number,\n rangeEnd: number\n): ChatComposerTextNode[] {\n const prefixLength = Math.max(0, rangeStart - nodeStart);\n const suffixLength = Math.max(0, nodeStart + node.text.length - rangeEnd);\n const edges: ChatComposerTextNode[] = [];\n\n if (prefixLength > 0) {\n edges.push({\n ...node,\n text: node.text.slice(0, prefixLength)\n });\n }\n if (suffixLength > 0) {\n edges.push({\n ...node,\n text: node.text.slice(node.text.length - suffixLength)\n });\n }\n\n return edges;\n}\n\nfunction isNodeOutsideComposerRange(\n nodeStart: number,\n nodeEnd: number,\n boundedStart: number,\n boundedEnd: number\n): boolean {\n return nodeEnd <= boundedStart || nodeStart >= boundedEnd;\n}\n\nfunction appendReplacementBeforeNode(\n nextNodes: ChatComposerNode[],\n replacement: ChatComposerNode[],\n inserted: boolean,\n nodeStart: number,\n boundedEnd: number\n): boolean {\n if (!inserted && nodeStart >= boundedEnd) {\n nextNodes.push(...replacement);\n return true;\n }\n return inserted;\n}\n\nfunction appendTextNodeWithReplacement(\n nextNodes: ChatComposerNode[],\n node: ChatComposerTextNode,\n nodeStart: number,\n boundedStart: number,\n boundedEnd: number,\n replacement: ChatComposerNode[],\n inserted: boolean\n): boolean {\n const edges = buildTrimmedTextEdges(node, nodeStart, boundedStart, boundedEnd);\n if (edges[0]) {\n nextNodes.push(edges[0]);\n }\n let didInsert = inserted;\n if (!didInsert) {\n nextNodes.push(...replacement);\n didInsert = true;\n }\n if (edges[1]) {\n nextNodes.push(edges[1]);\n }\n return didInsert;\n}\n\nfunction appendTokenNodeWithReplacement(\n nextNodes: ChatComposerNode[],\n node: ChatComposerNode,\n replacement: ChatComposerNode[],\n inserted: boolean,\n boundedStart: number,\n nodeStart: number\n): boolean {\n if (!inserted && boundedStart <= nodeStart) {\n nextNodes.push(...replacement);\n return true;\n }\n nextNodes.push(node);\n return inserted;\n}\n\nexport function replaceChatComposerRange(\n nodes: ChatComposerNode[],\n start: number,\n end: number,\n replacement: ChatComposerNode[]\n): ChatComposerNode[] {\n const boundedStart = Math.max(0, start);\n const boundedEnd = Math.max(boundedStart, end);\n const nextNodes: ChatComposerNode[] = [];\n let cursor = 0;\n let inserted = false;\n\n for (const node of nodes) {\n const nodeLength = getChatComposerNodeLength(node);\n const nodeStart = cursor;\n const nodeEnd = cursor + nodeLength;\n const isOutsideRange = isNodeOutsideComposerRange(nodeStart, nodeEnd, boundedStart, boundedEnd);\n\n if (isOutsideRange) {\n inserted = appendReplacementBeforeNode(nextNodes, replacement, inserted, nodeStart, boundedEnd);\n nextNodes.push(node);\n cursor = nodeEnd;\n continue;\n }\n\n if (node.type === 'text') {\n inserted = appendTextNodeWithReplacement(\n nextNodes,\n node,\n nodeStart,\n boundedStart,\n boundedEnd,\n replacement,\n inserted\n );\n } else {\n inserted = appendTokenNodeWithReplacement(nextNodes, node, replacement, inserted, boundedStart, nodeStart);\n }\n\n cursor = nodeEnd;\n }\n\n if (!inserted) {\n nextNodes.push(...replacement);\n }\n\n return normalizeChatComposerNodes(nextNodes);\n}\n\nexport function removeChatComposerTokenNodes(\n nodes: ChatComposerNode[],\n predicate: (node: ChatComposerTokenNode) => boolean\n): ChatComposerNode[] {\n return normalizeChatComposerNodes(\n nodes.filter((node) => node.type !== 'token' || !predicate(node))\n );\n}\n\nfunction hasTriggerBoundary(prefix: string, markerStart: number): boolean {\n return markerStart === 0 || /\\s/.test(prefix[markerStart - 1] ?? '');\n}\n\nexport function resolveChatComposerInputSurfaceTrigger(\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n triggerSpec: ChatInputSurfaceTriggerSpec\n): ChatInputSurfaceTrigger | null {\n if (!selection || selection.start !== selection.end) {\n return null;\n }\n\n const documentText = serializeChatComposerDocument(nodes);\n const caret = selection.end;\n const prefix = documentText.slice(0, caret);\n const markerStart = prefix.lastIndexOf(triggerSpec.marker);\n if (markerStart < 0 || !hasTriggerBoundary(prefix, markerStart)) {\n return null;\n }\n\n const rawQuery = prefix.slice(markerStart + triggerSpec.marker.length);\n if (/[\\s\\uFFFC]/.test(rawQuery)) {\n return null;\n }\n\n return {\n key: triggerSpec.key,\n marker: triggerSpec.marker,\n query: rawQuery.trim().toLowerCase(),\n start: markerStart,\n end: caret,\n };\n}\n\nexport function resolveChatComposerActiveInputSurfaceTrigger(\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n triggerSpecs: readonly ChatInputSurfaceTriggerSpec[] = [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n): ChatInputSurfaceTrigger | null {\n let activeTrigger: ChatInputSurfaceTrigger | null = null;\n for (const triggerSpec of triggerSpecs) {\n const trigger = resolveChatComposerInputSurfaceTrigger(nodes, selection, triggerSpec);\n if (!trigger) {\n continue;\n }\n if (!activeTrigger || trigger.start > activeTrigger.start) {\n activeTrigger = trigger;\n }\n }\n return activeTrigger;\n}\n\nexport function resolveChatComposerSlashTrigger(\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null\n): { query: string; start: number; end: number } | null {\n const trigger = resolveChatComposerInputSurfaceTrigger(\n nodes,\n selection,\n CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC,\n );\n return trigger\n ? {\n query: trigger.query,\n start: trigger.start,\n end: trigger.end,\n }\n : null;\n}\n\nexport function isChatComposerSelectionInsideRange(\n selection: ChatComposerSelection | null,\n start: number,\n end: number\n): boolean {\n if (!selection) {\n return false;\n }\n return selection.start < end && selection.end > start;\n}\n","import { useEffect, type RefObject } from 'react';\n\ntype UseActiveItemScrollParams = {\n containerRef: RefObject<HTMLElement>;\n activeIndex: number;\n itemCount: number;\n isEnabled: boolean;\n getItemSelector?: (index: number) => string;\n};\n\nconst defaultGetItemSelector = (index: number) => `[data-item-index=\"${index}\"]`;\n\nexport function useActiveItemScroll(params: UseActiveItemScrollParams) {\n const { activeIndex, containerRef, getItemSelector: customGetItemSelector, isEnabled, itemCount } =\n params;\n const getItemSelector = customGetItemSelector ?? defaultGetItemSelector;\n\n useEffect(() => {\n if (!isEnabled || itemCount === 0) {\n return;\n }\n\n const container = containerRef.current;\n if (!container) {\n return;\n }\n\n const activeItem = container.querySelector<HTMLElement>(getItemSelector(activeIndex));\n if (typeof activeItem?.scrollIntoView === 'function') {\n activeItem.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n }\n }, [activeIndex, containerRef, getItemSelector, isEnabled, itemCount]);\n}\n","import { useEffect, useRef, useState, type RefObject } from 'react';\n\ntype UseElementWidthResult<T extends HTMLElement> = {\n elementRef: RefObject<T>;\n width: number | null;\n};\n\nexport function useElementWidth<T extends HTMLElement>(): UseElementWidthResult<T> {\n const elementRef = useRef<T | null>(null);\n const [width, setWidth] = useState<number | null>(null);\n\n useEffect(() => {\n const element = elementRef.current;\n if (!element || typeof ResizeObserver === 'undefined') {\n return;\n }\n\n const updateWidth = () => {\n setWidth(element.getBoundingClientRect().width);\n };\n\n updateWidth();\n\n const observer = new ResizeObserver(() => updateWidth());\n observer.observe(element);\n\n return () => observer.disconnect();\n }, []);\n\n return {\n elementRef,\n width\n };\n}\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import * as React from 'react';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nexport type ChatInputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nconst ChatInput = React.forwardRef<HTMLInputElement, ChatInputProps>(({ className, type, ...props }, ref) => (\n <input\n type={type}\n className={cn(\n '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',\n className\n )}\n ref={ref}\n {...props}\n />\n));\n\nChatInput.displayName = 'ChatInput';\n\nexport { ChatInput };\n","import * as React from 'react';\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nconst CHAT_FLOATING_CONTENT_AVAILABLE_HEIGHT_GAP = '2rem';\n\nfunction createChatPopoverAvailableHeightLimit(limit: string): string {\n return `min(${limit}, max(0px, calc(var(--radix-popover-content-available-height, 100vh) - ${CHAT_FLOATING_CONTENT_AVAILABLE_HEIGHT_GAP})))`;\n}\n\nconst CHAT_POPOVER_CONTENT_MAX_HEIGHT = createChatPopoverAvailableHeightLimit('24rem');\n\nconst ChatPopover = PopoverPrimitive.Root;\nconst ChatPopoverTrigger = PopoverPrimitive.Trigger;\nconst ChatPopoverAnchor = PopoverPrimitive.Anchor;\n\nconst ChatPopoverContent = React.forwardRef<\n React.ElementRef<typeof PopoverPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(({ className, sideOffset = 8, align = 'start', collisionPadding = 12, style, ...props }, ref) => (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n align={align}\n collisionPadding={collisionPadding}\n className={cn(\n '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',\n className\n )}\n style={{ maxHeight: CHAT_POPOVER_CONTENT_MAX_HEIGHT, ...style }}\n {...props}\n />\n </PopoverPrimitive.Portal>\n));\n\nChatPopoverContent.displayName = PopoverPrimitive.Content.displayName;\n\nexport {\n ChatPopover,\n ChatPopoverTrigger,\n ChatPopoverContent,\n ChatPopoverAnchor,\n createChatPopoverAvailableHeightLimit,\n};\n","import * as React from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\nimport { Check, ChevronDown, ChevronUp } from 'lucide-react';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nconst ChatSelect = SelectPrimitive.Root;\nconst ChatSelectGroup = SelectPrimitive.Group;\nconst ChatSelectValue = SelectPrimitive.Value;\nconst CHAT_SELECT_CONTENT_AVAILABLE_HEIGHT_GAP = '2rem';\n\nfunction createChatSelectAvailableHeightLimit(limit: string): string {\n return `min(${limit}, max(0px, calc(var(--radix-select-content-available-height, 100vh) - ${CHAT_SELECT_CONTENT_AVAILABLE_HEIGHT_GAP})))`;\n}\n\nconst CHAT_SELECT_CONTENT_MAX_HEIGHT = createChatSelectAvailableHeightLimit('24rem');\n\nconst ChatSelectTrigger = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Trigger>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Trigger\n ref={ref}\n className={cn(\n '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',\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"h-4 w-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n));\n\nChatSelectTrigger.displayName = SelectPrimitive.Trigger.displayName;\n\nconst ChatSelectScrollUpButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollUpButton ref={ref} className={cn('flex cursor-default items-center justify-center py-1', className)} {...props}>\n <ChevronUp className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollUpButton>\n));\n\nChatSelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;\n\nconst ChatSelectScrollDownButton = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.ScrollDownButton ref={ref} className={cn('flex cursor-default items-center justify-center py-1', className)} {...props}>\n <ChevronDown className=\"h-4 w-4\" />\n </SelectPrimitive.ScrollDownButton>\n));\n\nChatSelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;\n\ntype ChatSelectContentProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> & {\n viewportClassName?: string;\n};\n\nconst ChatSelectContent = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Content>,\n ChatSelectContentProps\n>(({ className, children, collisionPadding = 12, position = 'popper', style, viewportClassName, ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n className={cn(\n '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',\n position === 'popper' &&\n 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',\n className\n )}\n collisionPadding={collisionPadding}\n position={position}\n style={{ maxHeight: CHAT_SELECT_CONTENT_MAX_HEIGHT, ...style }}\n {...props}\n >\n <ChatSelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n 'min-h-0 flex-1 overflow-y-auto overscroll-contain p-1',\n position === 'popper' && 'w-full min-w-[var(--radix-select-trigger-width)]',\n viewportClassName,\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <ChatSelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n));\n\nChatSelectContent.displayName = SelectPrimitive.Content.displayName;\n\nconst ChatSelectLabel = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label ref={ref} className={cn('px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground', className)} {...props} />\n));\n\nChatSelectLabel.displayName = SelectPrimitive.Label.displayName;\n\nconst ChatSelectItem = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n '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',\n className\n )}\n {...props}\n >\n <span className=\"absolute right-2 flex h-3.5 w-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n));\n\nChatSelectItem.displayName = SelectPrimitive.Item.displayName;\n\nconst ChatSelectSeparator = React.forwardRef<\n React.ElementRef<typeof SelectPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-border', className)} {...props} />\n));\n\nChatSelectSeparator.displayName = SelectPrimitive.Separator.displayName;\n\nexport {\n ChatSelect,\n ChatSelectContent,\n ChatSelectGroup,\n ChatSelectItem,\n ChatSelectLabel,\n ChatSelectSeparator,\n ChatSelectTrigger,\n ChatSelectValue,\n createChatSelectAvailableHeightLimit\n};\n","import * as React from 'react';\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nconst ChatTooltipProvider = TooltipPrimitive.Provider;\nconst ChatTooltip = TooltipPrimitive.Root;\nconst ChatTooltipTrigger = TooltipPrimitive.Trigger;\n\nconst ChatTooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-[var(--z-tooltip)] overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md 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',\n className\n )}\n {...props}\n />\n </TooltipPrimitive.Portal>\n));\n\nChatTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { ChatTooltip, ChatTooltipTrigger, ChatTooltipContent, ChatTooltipProvider };\n","import { ChatInput as DefaultInput } from '@agent-chat-ui/components/chat/default-skin/input';\nimport {\n ChatPopover as DefaultPopover,\n ChatPopoverAnchor as DefaultPopoverAnchor,\n ChatPopoverContent as DefaultPopoverContent,\n ChatPopoverTrigger as DefaultPopoverTrigger,\n createChatPopoverAvailableHeightLimit\n} from '@agent-chat-ui/components/chat/default-skin/popover';\nimport {\n ChatSelect as DefaultSelect,\n ChatSelectContent as DefaultSelectContent,\n ChatSelectGroup as DefaultSelectGroup,\n ChatSelectItem as DefaultSelectItem,\n ChatSelectLabel as DefaultSelectLabel,\n ChatSelectSeparator as DefaultSelectSeparator,\n ChatSelectTrigger as DefaultSelectTrigger,\n ChatSelectValue as DefaultSelectValue,\n createChatSelectAvailableHeightLimit\n} from '@agent-chat-ui/components/chat/default-skin/select';\nimport {\n ChatTooltip as DefaultTooltip,\n ChatTooltipContent as DefaultTooltipContent,\n ChatTooltipProvider as DefaultTooltipProvider,\n ChatTooltipTrigger as DefaultTooltipTrigger\n} from '@agent-chat-ui/components/chat/default-skin/tooltip';\n\n// Centralized primitive adapter layer for chat UI.\nexport const ChatUiPrimitives = {\n Popover: DefaultPopover,\n PopoverAnchor: DefaultPopoverAnchor,\n PopoverContent: DefaultPopoverContent,\n PopoverTrigger: DefaultPopoverTrigger,\n Input: DefaultInput,\n Select: DefaultSelect,\n SelectContent: DefaultSelectContent,\n SelectGroup: DefaultSelectGroup,\n SelectItem: DefaultSelectItem,\n SelectLabel: DefaultSelectLabel,\n SelectSeparator: DefaultSelectSeparator,\n SelectTrigger: DefaultSelectTrigger,\n SelectValue: DefaultSelectValue,\n Tooltip: DefaultTooltip,\n TooltipContent: DefaultTooltipContent,\n TooltipProvider: DefaultTooltipProvider,\n TooltipTrigger: DefaultTooltipTrigger\n};\n\nexport {\n createChatPopoverAvailableHeightLimit,\n createChatSelectAvailableHeightLimit\n};\n","import { forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport { useActiveItemScroll } from '@agent-chat-ui/components/chat/hooks/use-active-item-scroll';\nimport { useElementWidth } from '@agent-chat-ui/components/chat/hooks/use-element-width';\nimport {\n ChatUiPrimitives,\n createChatPopoverAvailableHeightLimit,\n} from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport type {\n ChatInputSurfaceFilterOption,\n ChatInputSurfaceItem,\n ChatInputSurfaceMenuProps,\n} from '@agent-chat-ui/lib/input-surface';\n\nconst INPUT_SURFACE_PANEL_MAX_WIDTH = 680;\nconst INPUT_SURFACE_PANEL_DESKTOP_SHRINK_RATIO = 0.82;\nconst INPUT_SURFACE_PANEL_DESKTOP_MIN_WIDTH = 560;\nconst INPUT_SURFACE_PANEL_MAX_HEIGHT = createChatPopoverAvailableHeightLimit('24rem');\nconst INPUT_SURFACE_PANEL_MIN_HEIGHT = createChatPopoverAvailableHeightLimit('240px');\n\nexport type ChatInputSurfaceMenuHandle = {\n handleKeyDown: (event: KeyboardEvent) => boolean;\n};\n\ntype ChatInputSurfaceActiveState = {\n index: number;\n itemsSignature: string;\n};\n\ntype ChatInputSurfaceFilterView = ChatInputSurfaceFilterOption & {\n count: number;\n};\n\nfunction itemMatchesFilter(item: ChatInputSurfaceItem, filter: ChatInputSurfaceFilterOption): boolean {\n if (!filter.sectionKeys || filter.sectionKeys.length === 0) {\n return true;\n }\n return Boolean(item.sectionKey && filter.sectionKeys.includes(item.sectionKey));\n}\n\nexport const ChatInputSurfaceMenu = forwardRef<ChatInputSurfaceMenuHandle, ChatInputSurfaceMenuProps>(\nfunction ChatInputSurfaceMenu(props, ref) {\n const { Popover, PopoverAnchor, PopoverContent } = ChatUiPrimitives;\n const { elementRef: anchorRef, width: panelWidth } = useElementWidth<HTMLDivElement>();\n const listRef = useRef<HTMLDivElement | null>(null);\n const [activeState, setActiveState] = useState<ChatInputSurfaceActiveState>({\n index: 0,\n itemsSignature: '',\n });\n const {\n isOpen,\n isLoading,\n filterOptions,\n items,\n texts,\n onSelectItem,\n onOpenChange,\n onDetailsPointerDown,\n } = props;\n const firstFilterKey = filterOptions?.[0]?.key ?? null;\n const [activeFilterKey, setActiveFilterKey] = useState<string | null>(firstFilterKey);\n const resolvedActiveFilterKey = useMemo(() => {\n if (!filterOptions?.length) {\n return null;\n }\n return filterOptions.some((filter) => filter.key === activeFilterKey)\n ? activeFilterKey\n : filterOptions[0].key;\n }, [activeFilterKey, filterOptions]);\n const activeFilter = useMemo(\n () => filterOptions?.find((filter) => filter.key === resolvedActiveFilterKey) ?? null,\n [filterOptions, resolvedActiveFilterKey],\n );\n const filterViews = useMemo<ChatInputSurfaceFilterView[]>(\n () =>\n filterOptions?.map((filter) => ({\n ...filter,\n count: items.filter((item) => itemMatchesFilter(item, filter)).length,\n })) ?? [],\n [filterOptions, items],\n );\n const visibleItems = useMemo(\n () => (activeFilter ? items.filter((item) => itemMatchesFilter(item, activeFilter)) : items),\n [activeFilter, items],\n );\n const itemsSignature = useMemo(\n () => visibleItems.map((item) => item.key).join('\\u001f'),\n [visibleItems],\n );\n const hasItemSections = useMemo(\n () => visibleItems.some((item) => Boolean(item.sectionLabel?.trim())),\n [visibleItems],\n );\n const activeIndex = activeState.itemsSignature === itemsSignature ? activeState.index : 0;\n const activeIndexInRange = visibleItems.length === 0 ? 0 : Math.min(activeIndex, visibleItems.length - 1);\n const activeItem = visibleItems[activeIndexInRange] ?? null;\n const handleFilterSelect = useCallback((filterKey: string): void => {\n setActiveFilterKey(filterKey);\n setActiveState({ index: 0, itemsSignature: '' });\n }, []);\n const setActiveIndexForCurrentItems = useCallback(\n (nextIndex: number | ((currentIndex: number) => number)): void => {\n setActiveState((currentState) => {\n const currentIndex = currentState.itemsSignature === itemsSignature ? currentState.index : 0;\n return {\n index: typeof nextIndex === 'function' ? nextIndex(currentIndex) : nextIndex,\n itemsSignature,\n };\n });\n },\n [itemsSignature],\n );\n\n const resolvedWidth = useMemo(() => {\n if (!panelWidth) {\n return undefined;\n }\n return Math.min(\n panelWidth > INPUT_SURFACE_PANEL_DESKTOP_MIN_WIDTH\n ? panelWidth * INPUT_SURFACE_PANEL_DESKTOP_SHRINK_RATIO\n : panelWidth,\n INPUT_SURFACE_PANEL_MAX_WIDTH,\n );\n }, [panelWidth]);\n\n useImperativeHandle(ref, () => ({\n handleKeyDown: (event) => {\n if (!isOpen) {\n return false;\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n onOpenChange(false);\n return true;\n }\n\n if (visibleItems.length === 0) {\n return false;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n setActiveIndexForCurrentItems((index) => (index + 1) % visibleItems.length);\n return true;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n setActiveIndexForCurrentItems((index) => (index - 1 + visibleItems.length) % visibleItems.length);\n return true;\n }\n\n if ((event.key === 'Enter' && !event.shiftKey) || event.key === 'Tab') {\n event.preventDefault();\n onSelectItem(visibleItems[activeIndexInRange]);\n return true;\n }\n\n return false;\n },\n }), [activeIndexInRange, isOpen, onOpenChange, onSelectItem, setActiveIndexForCurrentItems, visibleItems]);\n\n useActiveItemScroll({\n containerRef: listRef,\n activeIndex: activeIndexInRange,\n itemCount: visibleItems.length,\n isEnabled: isOpen && !isLoading,\n getItemSelector: (index) => `[data-input-surface-index=\"${index}\"]`,\n });\n\n return (\n <Popover open={isOpen} onOpenChange={onOpenChange}>\n <PopoverAnchor asChild>\n <div ref={anchorRef} className=\"pointer-events-none absolute bottom-0 left-3 right-3 top-0\" />\n </PopoverAnchor>\n <PopoverContent\n side=\"top\"\n align=\"start\"\n sideOffset={10}\n className=\"z-[70] flex max-w-[calc(100vw-1.5rem)] flex-col overflow-hidden rounded-2xl border border-gray-200 bg-white/95 p-0 shadow-2xl backdrop-blur-md\"\n onOpenAutoFocus={(event) => event.preventDefault()}\n style={{\n maxHeight: INPUT_SURFACE_PANEL_MAX_HEIGHT,\n width: resolvedWidth ? `${resolvedWidth}px` : undefined,\n }}\n >\n <div\n className=\"grid min-h-0 flex-1 grid-cols-[minmax(220px,300px)_minmax(0,1fr)]\"\n style={{ minHeight: INPUT_SURFACE_PANEL_MIN_HEIGHT }}\n >\n <div className=\"flex min-h-0 flex-col border-r border-gray-200\">\n {!isLoading && filterViews.length > 0 ? (\n <div className=\"flex shrink-0 gap-1 overflow-x-auto px-2.5 pb-2 pt-2.5\">\n {filterViews.map(({ count, key, label }) => {\n const isActive = key === resolvedActiveFilterKey;\n return (\n <button\n key={key}\n type=\"button\"\n aria-pressed={isActive}\n onPointerDown={(event) => event.preventDefault()}\n onClick={() => handleFilterSelect(key)}\n className={`inline-flex shrink-0 items-center gap-1 rounded-full border px-2 py-1 text-[11px] font-semibold transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 ${\n isActive\n ? 'border-primary/30 bg-primary/10 text-primary'\n : 'border-gray-200 bg-white text-gray-600 hover:border-gray-300 hover:bg-gray-50'\n }`}\n >\n <span>{label}</span>\n <span className={isActive ? 'text-primary/70' : 'text-gray-400'}>{count}</span>\n </button>\n );\n })}\n </div>\n ) : null}\n <div\n ref={listRef}\n role=\"listbox\"\n aria-label={texts.sectionLabel}\n className={`custom-scrollbar min-h-0 flex-1 overflow-y-auto overscroll-contain ${\n !isLoading && filterViews.length > 0 ? 'px-2.5 pb-2.5' : 'p-2.5'\n }`}\n >\n {isLoading ? (\n <div className=\"p-2 text-xs text-gray-500\">{texts.loadingLabel}</div>\n ) : (\n <>\n {!hasItemSections ? (\n <div className=\"mb-2 px-2 text-[11px] font-semibold uppercase tracking-wide text-gray-500\">\n {texts.sectionLabel}\n </div>\n ) : null}\n {visibleItems.length === 0 ? (\n <div className=\"px-2 text-xs text-gray-400\">{texts.emptyLabel}</div>\n ) : (\n <div className=\"space-y-1\">\n {visibleItems.map((item, index) => {\n const { key, sectionKey, sectionLabel, title, subtitle } = item;\n const isActive = index === activeIndexInRange;\n const previousItem = visibleItems[index - 1];\n const shouldShowSection =\n hasItemSections &&\n Boolean(sectionLabel?.trim()) &&\n previousItem?.sectionKey !== sectionKey;\n return (\n <div key={key} className=\"space-y-1\">\n {shouldShowSection ? (\n <div className=\"px-2 pb-0.5 pt-1.5 text-[11px] font-semibold uppercase tracking-wide text-gray-500\">\n {sectionLabel}\n </div>\n ) : null}\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-input-surface-index={index}\n onPointerMove={(event) => {\n if (event.pointerType !== 'touch') {\n setActiveIndexForCurrentItems(index);\n }\n }}\n onPointerDown={(event) => {\n if (event.button > 0) {\n return;\n }\n event.preventDefault();\n onSelectItem(item);\n }}\n onClick={(event) => {\n if (event.detail === 0) {\n onSelectItem(item);\n }\n }}\n className={`flex w-full items-start gap-2 rounded-lg px-2 py-1.5 text-left transition ${\n isActive ? 'bg-gray-100 text-gray-900' : 'text-gray-700 hover:bg-gray-50'\n }`}\n >\n <span className=\"truncate text-xs font-semibold\">{title}</span>\n <span className=\"truncate text-xs text-gray-500\">{subtitle}</span>\n </button>\n </div>\n );\n })}\n </div>\n )}\n </>\n )}\n </div>\n </div>\n <div\n className=\"custom-scrollbar min-h-0 min-w-0 overflow-y-auto overscroll-contain p-2.5\"\n onPointerDown={onDetailsPointerDown}\n >\n {activeItem ? (\n <div className=\"space-y-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"inline-flex rounded-full bg-primary/10 px-2 py-0.5 text-[11px] font-semibold text-primary\">\n {activeItem.subtitle}\n </span>\n <span className=\"text-sm font-semibold text-gray-900\">{activeItem.title}</span>\n </div>\n <p className=\"text-xs leading-5 text-gray-600\">{activeItem.description}</p>\n <div className=\"space-y-1\">\n {activeItem.detailLines.map((line) => (\n <div\n key={line}\n className=\"min-w-0 break-all rounded-md bg-gray-50 px-2 py-1 text-[11px] leading-5 text-gray-600\"\n >\n {line}\n </div>\n ))}\n </div>\n <div className=\"pt-1 text-[11px] text-gray-500\">\n {activeItem.hintLabel ?? texts.itemHintLabel}\n </div>\n </div>\n ) : (\n <div className=\"text-xs text-gray-500\">{texts.hintLabel}</div>\n )}\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n});\n","import { useCallback, useMemo, useRef, useState, type ReactNode } from 'react';\nimport type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatInputSurfaceConfig,\n ChatInputSurfaceItem,\n ChatInputSurfaceTrigger,\n ChatInputSurfaceTriggerChangeReason,\n ChatInputSurfaceTriggerSpec,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC,\n resolveChatComposerActiveInputSurfaceTrigger,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/chat-composer.utils';\nimport {\n ChatInputSurfaceMenu,\n type ChatInputSurfaceMenuHandle,\n} from '@agent-chat-ui/components/chat/ui/input-surface/chat-input-surface-menu';\n\ntype ChatInputSurfaceHostBindings = {\n onInputSurfaceKeyDown: (event: KeyboardEvent) => boolean;\n onInputSurfaceOpenChange: (open: boolean) => void;\n onInputSurfaceSnapshotChange: (\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n ) => void;\n};\n\nexport type ChatInputSurfaceHostProps = {\n inputSurface: ChatInputSurfaceConfig | null;\n onInputSurfaceTriggerChange?: (trigger: ChatInputSurfaceTrigger | null) => void;\n onSelectItem: (item: ChatInputSurfaceItem) => void;\n triggerSpecs?: readonly ChatInputSurfaceTriggerSpec[];\n children: (bindings: ChatInputSurfaceHostBindings) => ReactNode;\n};\n\nexport function getInputSurfaceTriggerIdentity(trigger: ChatInputSurfaceTrigger): string {\n return `${trigger.key}:${trigger.marker}:${trigger.start}`;\n}\n\nexport function isInputSurfaceCreateEvent(\n trigger: ChatInputSurfaceTrigger,\n reason: ChatInputSurfaceTriggerChangeReason,\n): boolean {\n return (\n reason.type === 'insert-text' &&\n reason.text === trigger.marker &&\n trigger.query === '' &&\n trigger.end === trigger.start + trigger.marker.length\n );\n}\n\nexport function resolveInputSurfaceTriggerIdentity(\n currentIdentity: string | null,\n trigger: ChatInputSurfaceTrigger | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n): string | null {\n if (!trigger) {\n return null;\n }\n\n const nextIdentity = getInputSurfaceTriggerIdentity(trigger);\n if (currentIdentity === nextIdentity) {\n return currentIdentity;\n }\n return isInputSurfaceCreateEvent(trigger, reason) ? nextIdentity : null;\n}\n\nexport function ChatInputSurfaceHost(props: ChatInputSurfaceHostProps) {\n const {\n children,\n inputSurface,\n onInputSurfaceTriggerChange,\n onSelectItem,\n triggerSpecs = [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n } = props;\n const menuRef = useRef<ChatInputSurfaceMenuHandle | null>(null);\n const [activeTriggerIdentity, setActiveTriggerIdentity] = useState<string | null>(null);\n const isOpen = Boolean(inputSurface) && activeTriggerIdentity !== null;\n\n const setActiveTrigger = useCallback(\n (identity: string | null, trigger: ChatInputSurfaceTrigger | null): void => {\n setActiveTriggerIdentity(identity);\n onInputSurfaceTriggerChange?.(identity ? trigger : null);\n },\n [onInputSurfaceTriggerChange],\n );\n\n const closeInputSurface = useCallback(\n (): void => {\n setActiveTrigger(null, null);\n },\n [setActiveTrigger],\n );\n\n const handleInputSurfaceSnapshotChange = useCallback(\n (\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n ): void => {\n const trigger = resolveChatComposerActiveInputSurfaceTrigger(nodes, selection, triggerSpecs);\n const nextIdentity = resolveInputSurfaceTriggerIdentity(\n activeTriggerIdentity,\n trigger,\n reason,\n );\n setActiveTrigger(nextIdentity, nextIdentity ? trigger : null);\n },\n [activeTriggerIdentity, setActiveTrigger, triggerSpecs],\n );\n\n const handleInputSurfaceKeyDown = useCallback((event: KeyboardEvent): boolean => {\n return menuRef.current?.handleKeyDown(event) ?? false;\n }, []);\n\n const handleInputSurfaceOpenChange = useCallback(\n (open: boolean): void => {\n if (!open) {\n closeInputSurface();\n }\n },\n [closeInputSurface],\n );\n\n const bindings = useMemo(\n () => ({\n onInputSurfaceKeyDown: handleInputSurfaceKeyDown,\n onInputSurfaceOpenChange: handleInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange: handleInputSurfaceSnapshotChange,\n }),\n [\n handleInputSurfaceKeyDown,\n handleInputSurfaceOpenChange,\n handleInputSurfaceSnapshotChange,\n ],\n );\n\n return (\n <>\n {/* eslint-disable-next-line react-hooks/refs -- menu ref is read later from keydown handlers, not during render. */}\n {children(bindings)}\n {inputSurface && isOpen ? (\n <ChatInputSurfaceMenu\n key={activeTriggerIdentity}\n ref={menuRef}\n isOpen={isOpen}\n isLoading={inputSurface.isLoading}\n filterOptions={inputSurface.filterOptions}\n items={inputSurface.items}\n texts={inputSurface.texts}\n onSelectItem={(item) => {\n closeInputSurface();\n onSelectItem(item);\n }}\n onOpenChange={handleInputSurfaceOpenChange}\n onDetailsPointerDown={(event) => event.preventDefault()}\n />\n ) : null}\n </>\n );\n}\n","import * as React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\n\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-full text-sm font-medium transition-all duration-fast focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary-600 active:bg-primary-700 shadow-sm',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline: 'border border-border bg-card text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n secondary: 'bg-muted text-foreground hover:bg-accent hover:text-accent-foreground',\n ghost: 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n primary: 'bg-primary text-primary-foreground hover:bg-primary-600 active:bg-primary-700 shadow-sm',\n subtle: 'bg-muted text-muted-foreground hover:bg-accent hover:text-accent-foreground',\n 'primary-outline': 'border border-primary/30 text-primary hover:bg-primary hover:text-primary-foreground'\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 px-3 text-xs',\n lg: 'h-11 px-5 text-[14px]',\n xl: 'h-12 px-6 text-[15px]',\n icon: 'h-9 w-9'\n }\n },\n defaultVariants: {\n variant: 'default',\n size: 'default'\n }\n }\n);\n\nexport interface ChatButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst ChatButton = React.forwardRef<HTMLButtonElement, ChatButtonProps>(\n ({ className, variant, size, ...props }, ref) => (\n <button className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />\n )\n);\n\nChatButton.displayName = 'ChatButton';\n\nexport { ChatButton, buttonVariants };\n","import { ChatButton } from '@agent-chat-ui/components/chat/default-skin/button';\nimport { ChatUiPrimitives } from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport type { ChatContextWindowIndicator, ChatInputBarActionsProps } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { ArrowUp } from 'lucide-react';\n\nconst SEND_ERROR_PREVIEW_MAX_CHARS = 120;\n\nfunction buildSendErrorPreview(value: string): string {\n const compact = value.replace(/\\s+/g, ' ').trim();\n if (compact.length <= SEND_ERROR_PREVIEW_MAX_CHARS) {\n return compact;\n }\n return `${compact.slice(0, SEND_ERROR_PREVIEW_MAX_CHARS - 1)}…`;\n}\n\nfunction StopIcon() {\n return (\n <span\n aria-hidden=\"true\"\n data-testid=\"chat-stop-icon\"\n className=\"block h-3 w-3 rounded-[2px] bg-foreground shadow-[inset_0_0_0_1px_hsl(var(--border))]\"\n />\n );\n}\n\nfunction ContextWindowIndicator({ contextWindow }: { contextWindow: ChatContextWindowIndicator }) {\n const { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } = ChatUiPrimitives;\n const clampedRatio = Math.max(0, Math.min(1, contextWindow.ratio));\n const angle = Math.round(clampedRatio * 360);\n const ringColor = 'hsl(var(--muted-foreground))';\n\n return (\n <TooltipProvider delayDuration={0}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n 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\"\n aria-label={contextWindow.label}\n title={contextWindow.label}\n >\n <span\n aria-hidden=\"true\"\n className=\"absolute inset-[7px] rounded-full\"\n style={{ background: `conic-gradient(${ringColor} ${angle}deg, hsl(var(--border)) 0deg)` }}\n />\n <span aria-hidden=\"true\" className=\"absolute inset-[10px] rounded-full bg-card\" />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-[18rem]\">\n <div className=\"space-y-1.5 text-xs\">\n <div className=\"flex items-center justify-between gap-5 font-semibold text-foreground\">\n <span>{contextWindow.label}</span>\n <span>{contextWindow.percentLabel}</span>\n </div>\n {contextWindow.details.map((detail) => (\n <div key={detail.label} className=\"flex items-center justify-between gap-5 text-muted-foreground\">\n <span>{detail.label}</span>\n <span className=\"font-medium text-foreground\">{detail.value}</span>\n </div>\n ))}\n </div>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n\nexport function ChatInputBarActions({\n sendError,\n sendErrorDetailsLabel,\n isSending,\n canStopGeneration,\n sendDisabled,\n stopDisabled,\n stopHint,\n sendButtonLabel,\n stopButtonLabel,\n contextWindow,\n onSend,\n onStop\n}: ChatInputBarActionsProps) {\n const {\n Popover,\n PopoverContent,\n PopoverTrigger,\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger\n } = ChatUiPrimitives;\n const normalizedSendError = sendError?.trim() ?? '';\n const sendErrorPreview = normalizedSendError\n ? buildSendErrorPreview(normalizedSendError)\n : '';\n const resolvedSendErrorDetailsLabel = sendErrorDetailsLabel?.trim() || 'Details';\n const showSendButton = !isSending || !sendDisabled;\n\n return (\n <div className=\"flex shrink-0 flex-col items-end gap-1\">\n {normalizedSendError ? (\n <div className=\"flex max-w-[420px] items-start justify-end gap-2 text-right\">\n <div className=\"min-w-0 flex-1 text-[11px] text-red-600\">\n <span\n className=\"block truncate\"\n title={normalizedSendError}\n >\n {sendErrorPreview}\n </span>\n </div>\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"shrink-0 rounded-full border border-red-200/80 bg-red-50 px-2 py-0.5 text-[10px] font-semibold text-red-700 transition-colors hover:bg-red-100\"\n >\n {resolvedSendErrorDetailsLabel}\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"end\"\n className=\"w-[min(32rem,calc(100vw-1.5rem))] border-red-100/80 p-0\"\n >\n <div className=\"border-b border-red-100 bg-red-50/80 px-4 py-2 text-xs font-semibold text-red-700\">\n {resolvedSendErrorDetailsLabel}\n </div>\n <pre className=\"max-h-80 overflow-auto whitespace-pre-wrap break-words px-4 py-3 text-xs leading-relaxed text-red-700\">\n {normalizedSendError}\n </pre>\n </PopoverContent>\n </Popover>\n </div>\n ) : null}\n <div className=\"flex items-center gap-2\">\n {contextWindow ? <ContextWindowIndicator contextWindow={contextWindow} /> : null}\n {showSendButton ? (\n <ChatButton\n size=\"icon\"\n className=\"h-8 w-8 rounded-full\"\n aria-label={sendButtonLabel}\n onClick={() => void onSend()}\n disabled={sendDisabled}\n >\n <ArrowUp className=\"h-5 w-5\" />\n </ChatButton>\n ) : canStopGeneration ? (\n <ChatButton\n size=\"icon\"\n variant=\"outline\"\n className=\"h-8 w-8 rounded-full\"\n aria-label={stopButtonLabel}\n onClick={() => void onStop()}\n disabled={stopDisabled}\n >\n <StopIcon />\n </ChatButton>\n ) : (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span>\n <ChatButton\n size=\"icon\"\n variant=\"outline\"\n className=\"h-8 w-8 rounded-full\"\n aria-label={stopButtonLabel}\n disabled\n >\n <StopIcon />\n </ChatButton>\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n <p className=\"text-xs\">{stopHint}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n </div>\n );\n}\n","import { useEffect, useId, useMemo, useRef, useState, type KeyboardEventHandler } from 'react';\nimport { BrainCircuit, Check, ExternalLink, Puzzle, Search } from 'lucide-react';\nimport { useActiveItemScroll } from '@agent-chat-ui/components/chat/hooks/use-active-item-scroll';\nimport {\n ChatUiPrimitives,\n createChatPopoverAvailableHeightLimit,\n} from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport type { ChatSkillPickerOption, ChatSkillPickerOptionGroup, ChatSkillPickerProps } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nfunction filterOptions(options: ChatSkillPickerOption[], query: string): ChatSkillPickerOption[] {\n const keyword = query.trim().toLowerCase();\n if (!keyword) {\n return options;\n }\n return options.filter((option) => {\n const haystack = [option.label, option.key, option.description]\n .filter((value): value is string => typeof value === 'string' && value.trim().length > 0)\n .join(' ')\n .toLowerCase();\n return haystack.includes(keyword);\n });\n}\n\nconst SKILL_PICKER_MAX_HEIGHT = createChatPopoverAvailableHeightLimit('24rem');\n\nexport function ChatInputBarSkillPicker(props: { picker: ChatSkillPickerProps }) {\n const { Input, Popover, PopoverContent, PopoverTrigger } = ChatUiPrimitives;\n const { picker } = props;\n const listRef = useRef<HTMLDivElement | null>(null);\n const listId = useId();\n const [query, setQuery] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n const selectedSet = useMemo(() => new Set(picker.selectedKeys), [picker.selectedKeys]);\n const selectedCount = picker.selectedKeys.length;\n const isSearchActive = query.trim().length > 0;\n const groupedOptions = useMemo<ChatSkillPickerOptionGroup[] | null>(() => {\n if (isSearchActive) {\n return null;\n }\n const groups = picker.groups?.filter((group) => group.options.length > 0) ?? [];\n return groups.length > 0 ? groups : null;\n }, [isSearchActive, picker.groups]);\n const visibleOptions = useMemo(() => {\n if (groupedOptions) {\n return groupedOptions.flatMap((group) => group.options);\n }\n return filterOptions(picker.options, query);\n }, [groupedOptions, picker.options, query]);\n\n useEffect(() => {\n setActiveIndex(0);\n }, [query]);\n\n useEffect(() => {\n setActiveIndex((current) => {\n if (visibleOptions.length === 0) {\n return 0;\n }\n return Math.min(current, visibleOptions.length - 1);\n });\n }, [visibleOptions.length]);\n\n useActiveItemScroll({\n containerRef: listRef,\n activeIndex,\n itemCount: visibleOptions.length,\n isEnabled: visibleOptions.length > 0,\n getItemSelector: (index) => `[data-skill-index=\"${index}\"]`\n });\n\n const onToggleOption = (optionKey: string) => {\n if (selectedSet.has(optionKey)) {\n picker.onSelectedKeysChange(picker.selectedKeys.filter((item) => item !== optionKey));\n return;\n }\n picker.onSelectedKeysChange([...picker.selectedKeys, optionKey]);\n };\n\n const onSearchKeyDown: KeyboardEventHandler<HTMLInputElement> = (event) => {\n if (visibleOptions.length === 0) {\n return;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n setActiveIndex((current) => Math.min(current + 1, visibleOptions.length - 1));\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n setActiveIndex((current) => Math.max(current - 1, 0));\n return;\n }\n\n if (event.key === 'Enter') {\n event.preventDefault();\n const activeOption = visibleOptions[activeIndex];\n if (activeOption) {\n onToggleOption(activeOption.key);\n }\n }\n };\n\n return (\n <Popover>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-haspopup=\"listbox\"\n aria-label={picker.title}\n 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\"\n >\n <BrainCircuit className=\"h-4 w-4\" />\n <span className=\"nextclaw-chat-skill-picker-label hidden sm:inline [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden\">\n {picker.title}\n </span>\n {selectedCount > 0 ? (\n <span className=\"absolute -right-1 -top-1 flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1 text-[10px] font-semibold leading-none text-white shadow-sm sm:static sm:ml-0.5 sm:bg-primary/10 sm:text-primary sm:shadow-none\">\n {selectedCount}\n </span>\n ) : null}\n </button>\n </PopoverTrigger>\n <PopoverContent\n side=\"top\"\n align=\"start\"\n className=\"flex w-[min(360px,calc(100vw-1rem))] flex-col overflow-hidden p-0\"\n style={{ maxHeight: SKILL_PICKER_MAX_HEIGHT }}\n >\n <div className=\"shrink-0 space-y-2 border-b border-border px-4 py-3\">\n <div className=\"text-sm font-semibold text-foreground\">{picker.title}</div>\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-3 top-2.5 h-3.5 w-3.5 text-muted-foreground/70\" />\n <Input\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={onSearchKeyDown}\n placeholder={picker.searchPlaceholder}\n role=\"combobox\"\n aria-controls={listId}\n aria-expanded=\"true\"\n aria-autocomplete=\"list\"\n aria-activedescendant={visibleOptions[activeIndex] ? `${listId}-option-${activeIndex}` : undefined}\n className=\"h-8 rounded-lg pl-8 text-xs\"\n />\n </div>\n </div>\n\n <div\n ref={listRef}\n id={listId}\n role=\"listbox\"\n aria-multiselectable=\"true\"\n className=\"custom-scrollbar min-h-0 flex-1 overflow-y-auto overscroll-contain\"\n >\n {picker.isLoading ? (\n <div className=\"p-4 text-xs text-muted-foreground\">{picker.loadingLabel}</div>\n ) : visibleOptions.length === 0 ? (\n <div className=\"p-4 text-center text-xs text-muted-foreground\">{picker.emptyLabel}</div>\n ) : (\n <div className=\"py-1\">\n {(() => {\n const groups = groupedOptions ?? [{ key: 'all-skills', options: visibleOptions }];\n let visibleIndex = 0;\n return groups.map((group) => (\n <div key={group.key}>\n {group.label ? (\n <div className=\"px-4 pb-1 pt-2 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\">\n {group.label}\n </div>\n ) : null}\n {group.options.map((option) => {\n const index = visibleIndex;\n visibleIndex += 1;\n const isSelected = selectedSet.has(option.key);\n const isActive = index === activeIndex;\n return (\n <div\n key={option.key}\n id={`${listId}-option-${index}`}\n role=\"option\"\n aria-selected={isSelected}\n data-skill-index={index}\n onMouseEnter={() => setActiveIndex(index)}\n className={`flex w-full items-center gap-3 px-4 py-2.5 text-left transition-colors ${\n isActive ? 'bg-accent' : 'hover:bg-accent'\n }`}\n >\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground\">\n <Puzzle className=\"h-4 w-4\" />\n </div>\n <div className=\"min-w-0 flex-1 select-text\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"truncate text-sm text-foreground\">{option.label}</span>\n {option.badgeLabel ? (\n <span className=\"shrink-0 rounded-full bg-primary/10 px-1.5 py-0.5 text-[10px] font-medium text-primary\">\n {option.badgeLabel}\n </span>\n ) : null}\n </div>\n <div className=\"mt-0.5 truncate text-xs text-muted-foreground\">{option.description || option.key}</div>\n </div>\n <div className=\"ml-3 shrink-0\">\n <button\n type=\"button\"\n aria-label={`${isSelected ? 'Remove' : 'Add'} ${option.label}`}\n onClick={() => onToggleOption(option.key)}\n className={\n isSelected\n ? 'inline-flex h-5 w-5 items-center justify-center rounded-full bg-primary text-white'\n : 'inline-flex h-5 w-5 items-center justify-center rounded-full border border-border bg-card'\n }\n >\n {isSelected ? <Check className=\"h-3 w-3\" /> : null}\n </button>\n </div>\n </div>\n );\n })}\n </div>\n ));\n })()}\n </div>\n )}\n </div>\n\n {picker.manageHref && picker.manageLabel ? (\n <div className=\"shrink-0 border-t border-border px-4 py-2.5\">\n <a\n href={picker.manageHref}\n className=\"inline-flex items-center gap-1.5 text-xs font-medium text-primary transition-colors hover:text-primary/80\"\n >\n {picker.manageLabel}\n <ExternalLink className=\"h-3 w-3\" />\n </a>\n </div>\n ) : null}\n </PopoverContent>\n </Popover>\n );\n}\n","import {\n ChatUiPrimitives,\n createChatPopoverAvailableHeightLimit,\n createChatSelectAvailableHeightLimit,\n} from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport type {\n ChatInputBarToolbarProps,\n ChatToolbarAccessoryIcon,\n ChatToolbarIcon,\n ChatToolbarSelect\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { Brain, Check, ChevronDown, Paperclip, Search, Sparkles, Star } from 'lucide-react';\nimport { useMemo, useState } from 'react';\nimport { ChatInputBarActions } from './chat-input-bar-actions';\nimport { ChatInputBarSkillPicker } from './chat-input-bar-skill-picker';\n\nfunction ToolbarIcon({ icon }: { icon?: ChatToolbarIcon }) {\n return icon === 'sparkles'\n ? <Sparkles className=\"h-3.5 w-3.5 shrink-0 text-primary\" />\n : icon === 'brain'\n ? <Brain className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n : null;\n}\n\nfunction AccessoryIcon({ icon }: { icon?: ChatToolbarAccessoryIcon }) {\n return icon === 'paperclip' ? <Paperclip className=\"h-4 w-4\" /> : <ToolbarIcon icon={icon} />;\n}\n\nconst TRIGGER_WIDTH_BY_KEY: Record<string, string> = {\n model: 'min-w-0 max-w-[18rem]',\n 'session-type': 'shrink-0',\n thinking: 'shrink-0'\n};\n\nconst CONTENT_WIDTH_BY_KEY: Record<string, string> = {\n model: 'w-[min(18rem,calc(100vw-1rem))] sm:w-[320px]',\n 'session-type': 'w-[220px]',\n thinking: 'w-[180px]'\n};\n\nconst TOOLBAR_POPOVER_MAX_HEIGHT = createChatPopoverAvailableHeightLimit('18rem');\nconst TOOLBAR_SELECT_MAX_HEIGHT = createChatSelectAvailableHeightLimit('18rem');\n\nfunction resolveMobileSelectedLabel(item: ChatToolbarSelect): string | undefined {\n return item.key === 'model' && item.selectedLabel\n ? item.selectedLabel.split('/').slice(1).join('/').trim() || item.selectedLabel\n : item.selectedLabel;\n}\n\nfunction buildSelectGroups(item: ChatToolbarSelect) {\n return item.groups?.filter((group) => group.options.length > 0) ??\n (item.options.length > 0 ? [{ key: `${item.key}-default`, options: item.options }] : []);\n}\n\nfunction ToolbarSelectTriggerContent({ item }: { item: ChatToolbarSelect }) {\n const mobileSelectedLabel = resolveMobileSelectedLabel(item);\n if (item.selectedLabel) {\n return (\n <div className=\"flex min-w-0 items-center gap-2 text-left\">\n <ToolbarIcon icon={item.icon} />\n <span className=\"nextclaw-chat-toolbar-mobile-label truncate sm:hidden [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden\">{mobileSelectedLabel}</span>\n <span className=\"nextclaw-chat-toolbar-label hidden truncate sm:inline [@container_nextclaw-chat-input-bar_(max-width:440px)]:hidden\">{item.selectedLabel}</span>\n </div>\n );\n }\n if (item.loading) {\n return <div className=\"h-3 w-24 animate-pulse rounded bg-muted\" />;\n }\n return <span className=\"truncate\">{item.placeholder}</span>;\n}\n\nfunction ToolbarSelectOptionContent({\n option\n}: {\n option: ChatToolbarSelect['options'][number];\n}) {\n return option.description ? (\n <div className=\"flex min-w-0 flex-col gap-0.5\">\n <span className=\"truncate text-xs font-semibold text-foreground\">{option.label}</span>\n <span className=\"truncate text-[11px] text-muted-foreground\">{option.description}</span>\n </div>\n ) : (\n <span className=\"truncate text-xs font-semibold text-foreground\">{option.label}</span>\n );\n}\n\nfunction ToolbarSearchableSelect({ item }: { item: ChatToolbarSelect }) {\n const { Input, Popover, PopoverContent, PopoverTrigger, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } =\n ChatUiPrimitives;\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const groups = buildSelectGroups(item);\n const filteredGroups = useMemo(() => {\n const normalizedQuery = query.trim().toLowerCase();\n if (!normalizedQuery) {\n return groups;\n }\n return groups\n .map((group) => ({\n ...group,\n options: group.options.filter((option) =>\n [option.label, option.value, option.description]\n .filter((value): value is string => Boolean(value))\n .some((value) => value.toLowerCase().includes(normalizedQuery)),\n ),\n }))\n .filter((group) => group.options.length > 0);\n }, [groups, query]);\n const hasOptions = groups.some((group) => group.options.length > 0);\n const hasFilteredOptions = filteredGroups.some((group) => group.options.length > 0);\n const action = item.optionAction;\n const activeValues = new Set(action?.activeValues ?? []);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-label={item.selectedLabel ? `${item.placeholder}: ${item.selectedLabel}` : item.placeholder}\n disabled={item.disabled}\n 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] ?? ''}`}\n >\n <ToolbarSelectTriggerContent item={item} />\n <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\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n className={`flex flex-col overflow-hidden p-2 ${CONTENT_WIDTH_BY_KEY[item.key] ?? ''}`}\n style={{ maxHeight: TOOLBAR_POPOVER_MAX_HEIGHT }}\n >\n <div className=\"relative mb-2 shrink-0\">\n <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\" />\n <Input\n value={query}\n onChange={(event) => setQuery(event.currentTarget.value)}\n placeholder={item.search?.placeholder ?? item.placeholder}\n className=\"h-8 rounded-lg pl-8 text-xs\"\n />\n </div>\n {!hasOptions ? (\n item.loading ? (\n <div className=\"space-y-2 px-2 py-1\">\n <div className=\"h-3 w-36 animate-pulse rounded bg-muted\" />\n <div className=\"h-3 w-28 animate-pulse rounded bg-muted\" />\n <div className=\"h-3 w-32 animate-pulse rounded bg-muted\" />\n </div>\n ) : item.emptyLabel ? (\n <div className=\"px-2 py-1 text-xs text-muted-foreground\">{item.emptyLabel}</div>\n ) : null\n ) : null}\n {hasOptions && !hasFilteredOptions ? (\n <div className=\"px-2 py-1 text-xs text-muted-foreground\">{item.search?.emptyLabel ?? item.emptyLabel}</div>\n ) : null}\n <div className=\"min-h-0 flex-1 overflow-y-auto overscroll-contain\">\n {filteredGroups.map((group, groupIndex) => (\n <div key={group.key} className={groupIndex > 0 ? 'border-t border-border pt-1' : undefined}>\n {group.label ? (\n <div className=\"px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground\">{group.label}</div>\n ) : null}\n {group.options.map((option) => {\n const isSelected = item.value === option.value;\n const isActive = activeValues.has(option.value);\n const actionLabel = isActive ? action?.activeLabel : action?.inactiveLabel;\n return (\n <div key={option.value} className=\"group flex items-center gap-1 rounded-md hover:bg-accent\">\n <button\n type=\"button\"\n className=\"flex min-w-0 flex-1 items-center gap-2 rounded-md px-2 py-2 text-left\"\n onClick={() => {\n item.onValueChange(option.value);\n setOpen(false);\n setQuery('');\n }}\n >\n <div className=\"min-w-0 flex-1\">\n <ToolbarSelectOptionContent option={option} />\n </div>\n {isSelected ? <Check className=\"h-4 w-4 shrink-0 text-primary\" /> : null}\n </button>\n {action && actionLabel ? (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n aria-label={actionLabel}\n aria-pressed={isActive}\n 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-foreground focus:outline-none focus:ring-1 focus:ring-primary/40\"\n onClick={(event) => {\n event.stopPropagation();\n action.onToggle(option.value, !isActive);\n }}\n >\n <Star className={`h-3.5 w-3.5 ${isActive ? 'fill-current text-foreground' : ''}`} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"left\">\n <p className=\"text-xs\">{actionLabel}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n );\n })}\n </div>\n ))}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\nfunction ToolbarSelect({ item }: { item: ChatToolbarSelect }) {\n if (item.search) {\n return <ToolbarSearchableSelect item={item} />;\n }\n const { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue } =\n ChatUiPrimitives;\n const groups = buildSelectGroups(item);\n const hasOptions = groups.some((group) => group.options.length > 0);\n\n return (\n <Select value={item.value} onValueChange={item.onValueChange} disabled={item.disabled}>\n <SelectTrigger\n aria-label={item.selectedLabel ? `${item.placeholder}: ${item.selectedLabel}` : item.placeholder}\n title={item.selectedLabel}\n 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] ?? ''}`}\n >\n {item.selectedLabel || item.loading ? <ToolbarSelectTriggerContent item={item} /> : <SelectValue placeholder={item.placeholder} />}\n </SelectTrigger>\n <SelectContent\n className={CONTENT_WIDTH_BY_KEY[item.key] ?? ''}\n style={{ maxHeight: TOOLBAR_SELECT_MAX_HEIGHT }}\n >\n {!hasOptions ? (\n item.loading ? (\n <div className=\"space-y-2 px-3 py-2\">\n <div className=\"h-3 w-36 animate-pulse rounded bg-muted\" />\n <div className=\"h-3 w-28 animate-pulse rounded bg-muted\" />\n <div className=\"h-3 w-32 animate-pulse rounded bg-muted\" />\n </div>\n ) : item.emptyLabel ? (\n <div className=\"px-3 py-2 text-xs text-muted-foreground\">{item.emptyLabel}</div>\n ) : null\n ) : null}\n {groups.map((group, groupIndex) => (\n <div key={group.key}>\n {groupIndex > 0 ? <SelectSeparator /> : null}\n <SelectGroup>\n {group.label ? <SelectLabel>{group.label}</SelectLabel> : null}\n {group.options.map((option) => (\n <SelectItem key={option.value} value={option.value} className=\"py-2\">\n <ToolbarSelectOptionContent option={option} />\n </SelectItem>\n ))}\n </SelectGroup>\n </div>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\nexport function ChatInputBarToolbar({\n actions,\n accessories,\n selects,\n skillPicker,\n trailingSelects = [],\n}: ChatInputBarToolbarProps) {\n const { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } = ChatUiPrimitives;\n return (\n <div className=\"flex flex-wrap items-end justify-between gap-2 px-3 pb-3\">\n <div className=\"flex min-w-[12rem] flex-1 flex-wrap items-center gap-1 overflow-hidden\">\n {skillPicker ? <ChatInputBarSkillPicker picker={skillPicker} /> : null}\n {selects.map((item) => (\n <ToolbarSelect key={item.key} item={item} />\n ))}\n {accessories?.map((item) => {\n const button = (\n <button\n type=\"button\"\n 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 ${\n item.iconOnly ? 'h-8 w-8 justify-center px-0' : 'gap-1.5 px-3'\n }`}\n onClick={item.onClick}\n disabled={item.disabled}\n aria-label={item.label}\n >\n <AccessoryIcon icon={item.icon} />\n {item.iconOnly ? null : <span>{item.label}</span>}\n </button>\n );\n if (!item.tooltip) {\n return <div key={item.key}>{button}</div>;\n }\n const trigger = item.disabled ? <span className=\"inline-flex\">{button}</span> : button;\n return (\n <TooltipProvider key={item.key}>\n <Tooltip>\n <TooltipTrigger asChild>{trigger}</TooltipTrigger>\n <TooltipContent side=\"top\">\n <p className=\"text-xs\">{item.tooltip}</p>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n })}\n </div>\n <div className=\"flex shrink-0 items-end gap-1\">\n {trailingSelects.length > 0 ? (\n <div className=\"nextclaw-chat-toolbar-trailing-selects flex min-w-0 items-center gap-1\">\n {trailingSelects.map((item) => (\n <ToolbarSelect key={item.key} item={item} />\n ))}\n </div>\n ) : null}\n <ChatInputBarActions {...actions} />\n </div>\n </div>\n );\n}\n","import {\n $applyNodeReplacement,\n DecoratorNode,\n type EditorConfig,\n type LexicalEditor,\n type LexicalNode,\n type NodeKey,\n type SerializedLexicalNode,\n} from 'lexical';\nimport type { ReactElement } from 'react';\nimport { AppWindow, ImageIcon, Puzzle } from 'lucide-react';\nimport { CHAT_COMPOSER_TOKEN_PLACEHOLDER } from '@agent-chat-ui/components/chat/ui/chat-input-bar/chat-composer.utils';\nimport type { ChatComposerTokenKind } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\ntype SerializedChatComposerTokenNode = SerializedLexicalNode & {\n composerId: string;\n label: string;\n tokenKey: string;\n tokenKind: ChatComposerTokenKind;\n type: 'chat-composer-token';\n version: 1;\n};\n\nfunction buildTokenClassName(tokenKind: ChatComposerTokenKind): string {\n if (tokenKind === 'file') {\n return [\n 'mx-[2px]',\n 'inline-flex',\n 'h-7',\n 'max-w-[min(100%,17rem)]',\n 'items-center',\n 'gap-1.5',\n 'rounded-lg',\n 'border',\n 'border-border',\n 'bg-muted',\n 'px-2',\n 'align-baseline',\n 'text-foreground',\n 'transition-[border-color,background-color,box-shadow,color]',\n 'duration-150',\n ].join(' ');\n }\n\n return [\n 'mx-[2px]',\n 'inline-flex',\n 'h-7',\n 'max-w-full',\n 'items-center',\n 'gap-1.5',\n 'rounded-lg',\n 'border',\n 'border-primary/12',\n 'bg-primary/8',\n 'px-2',\n 'align-baseline',\n 'text-[11px]',\n 'font-medium',\n 'text-primary',\n 'transition',\n ].join(' ');\n}\n\nfunction ChatComposerTokenChip({\n label,\n tokenKind,\n}: {\n label: string;\n tokenKind: ChatComposerTokenKind;\n}): ReactElement {\n return (\n <>\n <span\n className={\n tokenKind === 'file'\n ? 'inline-flex h-4.5 w-4.5 shrink-0 items-center justify-center rounded-md bg-card text-muted-foreground ring-1 ring-border'\n : 'inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center text-primary/70'\n }\n >\n {tokenKind === 'file' ? (\n <ImageIcon aria-hidden=\"true\" className=\"h-3 w-3\" />\n ) : tokenKind === 'panel_app' ? (\n <AppWindow aria-hidden=\"true\" className=\"h-3 w-3\" />\n ) : (\n <Puzzle aria-hidden=\"true\" className=\"h-3 w-3\" />\n )}\n </span>\n <span\n className={\n tokenKind === 'file'\n ? 'min-w-0 flex-1 truncate text-[12px] font-medium text-foreground'\n : 'truncate'\n }\n >\n {label}\n </span>\n </>\n );\n}\n\nexport class ChatComposerTokenNode extends DecoratorNode<ReactElement> {\n __composerId: string;\n __tokenKind: ChatComposerTokenKind;\n __tokenKey: string;\n __label: string;\n\n static getType(): string {\n return 'chat-composer-token';\n }\n\n static clone(node: ChatComposerTokenNode): ChatComposerTokenNode {\n return new ChatComposerTokenNode(\n node.__composerId,\n node.__tokenKind,\n node.__tokenKey,\n node.__label,\n node.__key,\n );\n }\n\n static importJSON(serializedNode: SerializedChatComposerTokenNode): ChatComposerTokenNode {\n return $createChatComposerTokenNode({\n composerId: serializedNode.composerId,\n label: serializedNode.label,\n tokenKey: serializedNode.tokenKey,\n tokenKind: serializedNode.tokenKind,\n });\n }\n\n constructor(\n composerId: string,\n tokenKind: ChatComposerTokenKind,\n tokenKey: string,\n label: string,\n key?: NodeKey,\n ) {\n super(key);\n this.__composerId = composerId;\n this.__tokenKind = tokenKind;\n this.__tokenKey = tokenKey;\n this.__label = label;\n }\n\n private readonly applyTokenDom = (element: HTMLElement): void => {\n element.contentEditable = 'false';\n element.dataset.composerNodeId = this.__composerId;\n element.dataset.composerNodeType = 'token';\n element.dataset.composerTokenKind = this.__tokenKind;\n element.dataset.composerTokenKey = this.__tokenKey;\n element.dataset.composerLabel = this.__label;\n element.title = this.__label;\n element.className = buildTokenClassName(this.__tokenKind);\n };\n\n createDOM = (_config: EditorConfig, _editor: LexicalEditor): HTMLElement => {\n const element = document.createElement('span');\n this.applyTokenDom(element);\n return element;\n };\n\n updateDOM = (_prevNode: ChatComposerTokenNode, dom: HTMLElement): false => {\n this.applyTokenDom(dom);\n return false;\n };\n\n decorate = (): ReactElement => {\n return <ChatComposerTokenChip label={this.__label} tokenKind={this.__tokenKind} />;\n };\n\n exportJSON = (): SerializedChatComposerTokenNode => {\n return {\n composerId: this.__composerId,\n label: this.__label,\n tokenKey: this.__tokenKey,\n tokenKind: this.__tokenKind,\n type: 'chat-composer-token',\n version: 1,\n };\n };\n\n getComposerId = (): string => {\n return this.getLatest().__composerId;\n };\n\n getTokenKind = (): ChatComposerTokenKind => {\n return this.getLatest().__tokenKind;\n };\n\n getTokenKey = (): string => {\n return this.getLatest().__tokenKey;\n };\n\n getLabel = (): string => {\n return this.getLatest().__label;\n };\n\n getTextContent = (): string => {\n return CHAT_COMPOSER_TOKEN_PLACEHOLDER;\n };\n\n isInline = (): true => {\n return true;\n };\n\n isIsolated = (): true => {\n return true;\n };\n\n isKeyboardSelectable = (): boolean => {\n return false;\n };\n}\n\nexport function $createChatComposerTokenNode(params: {\n composerId: string;\n label: string;\n tokenKey: string;\n tokenKind: ChatComposerTokenKind;\n}): ChatComposerTokenNode {\n const { composerId, label, tokenKey, tokenKind } = params;\n return $applyNodeReplacement(\n new ChatComposerTokenNode(composerId, tokenKind, tokenKey, label),\n );\n}\n\nexport function $isChatComposerTokenNode(\n node: LexicalNode | null | undefined,\n): node is ChatComposerTokenNode {\n return node instanceof ChatComposerTokenNode;\n}\n","import {\n $createLineBreakNode,\n $createParagraphNode,\n $createRangeSelection,\n $createTextNode,\n $getRoot,\n $getSelection,\n $isElementNode,\n $isRangeSelection,\n $isTextNode,\n $setSelection,\n type EditorState,\n type ElementPoint,\n type LexicalEditor,\n type LexicalNode,\n type NodeKey,\n type PointType,\n} from 'lexical';\nimport type { ChatComposerNode, ChatComposerSelection } from '../../../view-models/chat-ui.types';\nimport { normalizeChatComposerNodes } from '../chat-composer.utils';\nimport {\n $createChatComposerTokenNode,\n $isChatComposerTokenNode,\n type ChatComposerTokenNode,\n} from './chat-composer-token-node';\n\ntype LeafDescriptor =\n | {\n index: number;\n key: NodeKey;\n length: number;\n node: LexicalNode;\n start: number;\n type: 'linebreak' | 'token';\n }\n | {\n index: number;\n key: NodeKey;\n length: number;\n node: LexicalNode;\n start: number;\n text: string;\n type: 'text';\n };\n\ntype SelectionPointDescriptor = {\n key: NodeKey;\n offset: number;\n type: 'element' | 'text';\n};\n\nexport type ChatComposerEditorSnapshot = {\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n};\n\nfunction getComposerLeafDescriptors(): {\n descriptors: LeafDescriptor[];\n paragraphKey: NodeKey;\n paragraphSize: number;\n totalLength: number;\n} {\n const root = $getRoot();\n const paragraph = root.getFirstChild();\n if (!$isElementNode(paragraph)) {\n return {\n descriptors: [],\n paragraphKey: root.getKey(),\n paragraphSize: 0,\n totalLength: 0,\n };\n }\n\n const children = paragraph.getChildren();\n const descriptors: LeafDescriptor[] = [];\n let cursor = 0;\n\n for (const [index, child] of children.entries()) {\n if ($isTextNode(child)) {\n const text = child.getTextContent();\n descriptors.push({\n index,\n key: child.getKey(),\n length: text.length,\n node: child,\n start: cursor,\n text,\n type: 'text',\n });\n cursor += text.length;\n continue;\n }\n\n if ($isChatComposerTokenNode(child)) {\n descriptors.push({\n index,\n key: child.getKey(),\n length: 1,\n node: child,\n start: cursor,\n type: 'token',\n });\n cursor += 1;\n continue;\n }\n\n descriptors.push({\n index,\n key: child.getKey(),\n length: child.getTextContent().length,\n node: child,\n start: cursor,\n type: 'linebreak',\n });\n cursor += child.getTextContent().length;\n }\n\n return {\n descriptors,\n paragraphKey: paragraph.getKey(),\n paragraphSize: children.length,\n totalLength: cursor,\n };\n}\n\nfunction buildSelectionPointFromOffset(offset: number): SelectionPointDescriptor {\n const { descriptors, paragraphKey, paragraphSize, totalLength } = getComposerLeafDescriptors();\n const boundedOffset = Math.max(0, Math.min(offset, totalLength));\n\n if (descriptors.length === 0) {\n return {\n key: paragraphKey,\n offset: 0,\n type: 'element',\n };\n }\n\n for (const descriptor of descriptors) {\n const end = descriptor.start + descriptor.length;\n\n if (descriptor.type === 'text' && boundedOffset >= descriptor.start && boundedOffset <= end) {\n return {\n key: descriptor.key,\n offset: boundedOffset - descriptor.start,\n type: 'text',\n };\n }\n\n if (descriptor.type !== 'text') {\n if (boundedOffset === descriptor.start) {\n return {\n key: paragraphKey,\n offset: descriptor.index,\n type: 'element',\n };\n }\n\n if (boundedOffset === end) {\n const nextDescriptor = descriptors[descriptor.index + 1];\n if (nextDescriptor?.type === 'text' && nextDescriptor.length === 0) {\n return {\n key: nextDescriptor.key,\n offset: 0,\n type: 'text',\n };\n }\n return {\n key: paragraphKey,\n offset: descriptor.index + 1,\n type: 'element',\n };\n }\n }\n }\n\n return {\n key: paragraphKey,\n offset: paragraphSize,\n type: 'element',\n };\n}\n\nfunction getOffsetFromElementPoint(point: ElementPoint): number {\n const { descriptors, paragraphKey, totalLength } = getComposerLeafDescriptors();\n\n if (point.key === paragraphKey) {\n const previous = descriptors[point.offset - 1];\n return previous ? previous.start + previous.length : 0;\n }\n\n const descriptor = descriptors.find((item) => item.key === point.key);\n if (!descriptor) {\n return totalLength;\n }\n\n return descriptor.start + Math.min(point.offset, descriptor.length);\n}\n\nfunction getOffsetFromPoint(point: PointType): number {\n if (point.type === 'element') {\n return getOffsetFromElementPoint(point);\n }\n\n const { descriptors, totalLength } = getComposerLeafDescriptors();\n const descriptor = descriptors.find((item) => item.key === point.key);\n if (!descriptor) {\n return totalLength;\n }\n\n return descriptor.start + Math.min(point.offset, descriptor.length);\n}\n\nfunction readNodesFromEditor(): ChatComposerNode[] {\n const { descriptors } = getComposerLeafDescriptors();\n const nextNodes: ChatComposerNode[] = [];\n let textBuffer = '';\n let textId = '';\n\n const flushTextBuffer = (): void => {\n if (textBuffer.length === 0) {\n return;\n }\n nextNodes.push({\n id: textId,\n type: 'text',\n text: textBuffer,\n });\n textBuffer = '';\n textId = '';\n };\n\n for (const descriptor of descriptors) {\n if (descriptor.type === 'text') {\n if (textBuffer.length === 0) {\n textId = descriptor.key;\n }\n textBuffer += descriptor.text;\n continue;\n }\n\n if (descriptor.type === 'linebreak') {\n if (textBuffer.length === 0) {\n textId = descriptor.key;\n }\n textBuffer += '\\n';\n continue;\n }\n\n flushTextBuffer();\n const tokenNode = descriptor.node as ChatComposerTokenNode;\n nextNodes.push({\n id: tokenNode.getComposerId(),\n label: tokenNode.getLabel(),\n tokenKey: tokenNode.getTokenKey(),\n tokenKind: tokenNode.getTokenKind(),\n type: 'token',\n });\n }\n\n flushTextBuffer();\n return normalizeChatComposerNodes(nextNodes);\n}\n\nexport function readChatComposerSnapshotFromEditorState(\n editorState: EditorState,\n): ChatComposerEditorSnapshot {\n return editorState.read(() => {\n const selection = $getSelection();\n const nodes = readNodesFromEditor();\n\n if (!$isRangeSelection(selection)) {\n return {\n nodes,\n selection: null,\n };\n }\n\n return {\n nodes,\n selection: {\n start: Math.min(getOffsetFromPoint(selection.anchor), getOffsetFromPoint(selection.focus)),\n end: Math.max(getOffsetFromPoint(selection.anchor), getOffsetFromPoint(selection.focus)),\n },\n };\n });\n}\n\nexport function writeChatComposerStateToLexicalRoot(\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n): void {\n const root = $getRoot();\n root.clear();\n\n const paragraph = $createParagraphNode();\n root.append(paragraph);\n\n for (const node of normalizeChatComposerNodes(nodes)) {\n if (node.type === 'token') {\n paragraph.append(\n $createChatComposerTokenNode({\n composerId: node.id,\n label: node.label,\n tokenKey: node.tokenKey,\n tokenKind: node.tokenKind,\n }),\n );\n continue;\n }\n\n const parts = node.text.split('\\n');\n for (const [index, part] of parts.entries()) {\n if (part.length > 0) {\n paragraph.append($createTextNode(part));\n }\n if (index < parts.length - 1) {\n paragraph.append($createLineBreakNode());\n }\n }\n }\n\n if ($isChatComposerTokenNode(paragraph.getLastChild())) {\n paragraph.append($createTextNode(''));\n }\n\n if (!selection) {\n return;\n }\n\n const nextSelection = $createRangeSelection();\n const anchor = buildSelectionPointFromOffset(selection.start);\n const focus = buildSelectionPointFromOffset(selection.end);\n nextSelection.anchor.set(anchor.key, anchor.offset, anchor.type);\n nextSelection.focus.set(focus.key, focus.offset, focus.type);\n $setSelection(nextSelection);\n}\n\nexport function syncLexicalEditorFromChatComposerState(\n editor: LexicalEditor,\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n): void {\n editor.update(() => {\n writeChatComposerStateToLexicalRoot(nodes, selection);\n });\n}\n\nexport function syncLexicalSelectionFromChatComposerSelection(\n editor: LexicalEditor,\n selection: ChatComposerSelection,\n): void {\n editor.update(() => {\n const nextSelection = $createRangeSelection();\n const anchor = buildSelectionPointFromOffset(selection.start);\n const focus = buildSelectionPointFromOffset(selection.end);\n nextSelection.anchor.set(anchor.key, anchor.offset, anchor.type);\n nextSelection.focus.set(focus.key, focus.offset, focus.type);\n $setSelection(nextSelection);\n });\n}\n","import type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatComposerTokenKind,\n ChatInputSurfaceItem,\n ChatInputSurfaceTriggerSpec,\n ChatSkillPickerOption,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC,\n createChatComposerTextNode,\n createChatComposerTokenNode,\n extractChatComposerTokenKeys,\n getChatComposerNodeLength,\n normalizeChatComposerNodes,\n removeChatComposerTokenNodes,\n replaceChatComposerRange,\n resolveChatComposerActiveInputSurfaceTrigger,\n resolveChatComposerSlashTrigger,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/chat-composer.utils';\nimport type { ChatComposerEditorSnapshot } from './chat-composer-lexical-editor-state';\n\nfunction getDocumentLength(nodes: ChatComposerNode[]): number {\n return nodes.reduce((sum, node) => sum + getChatComposerNodeLength(node), 0);\n}\n\nfunction insertToken(params: {\n label: string;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n tokenKey: string;\n tokenKind: ChatComposerTokenKind;\n trigger?: { end: number; query: string; start: number } | null;\n}): ChatComposerEditorSnapshot {\n const { label, nodes, selection, tokenKey, tokenKind, trigger } = params;\n const documentLength = getDocumentLength(nodes);\n const [selectionStart, selectionEnd] = selection ? [Math.min(selection.start, selection.end), Math.max(selection.start, selection.end)] : [documentLength, documentLength];\n const replaceStart = trigger?.start ?? selectionStart;\n const replaceEnd = trigger?.end ?? selectionEnd;\n\n return {\n nodes: replaceChatComposerRange(\n nodes,\n replaceStart,\n replaceEnd,\n [\n createChatComposerTokenNode({\n label,\n tokenKey,\n tokenKind,\n }),\n ],\n ),\n selection: {\n start: replaceStart + 1,\n end: replaceStart + 1,\n },\n };\n}\n\nexport function insertChatComposerTokenIntoChatComposer(params: {\n label: string;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n tokenKey: string;\n tokenKind: ChatComposerTokenKind;\n triggerSpecs?: readonly ChatInputSurfaceTriggerSpec[];\n}): ChatComposerEditorSnapshot {\n const { label, nodes, selection, tokenKey, tokenKind, triggerSpecs } = params;\n\n if (extractChatComposerTokenKeys(nodes, tokenKind).includes(tokenKey)) {\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection,\n };\n }\n\n return insertToken({\n label,\n nodes,\n selection,\n tokenKey,\n tokenKind,\n trigger: resolveChatComposerActiveInputSurfaceTrigger(\n nodes,\n selection,\n triggerSpecs ?? [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n ),\n });\n}\n\nexport function insertInputSurfaceItemIntoChatComposer(params: {\n item: ChatInputSurfaceItem;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n triggerSpecs?: readonly ChatInputSurfaceTriggerSpec[];\n}): ChatComposerEditorSnapshot {\n const { item, nodes, selection, triggerSpecs } = params;\n const tokenKind = item.tokenKind ?? (item.value ? 'skill' : undefined);\n const tokenKey = item.tokenKey ?? item.value;\n if (!tokenKind || !tokenKey) {\n const trigger = resolveChatComposerActiveInputSurfaceTrigger(\n nodes,\n selection,\n triggerSpecs ?? [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n );\n if (trigger) {\n return {\n nodes: normalizeChatComposerNodes(\n replaceChatComposerRange(nodes, trigger.start, trigger.end, []),\n ),\n selection: {\n start: trigger.start,\n end: trigger.start,\n },\n };\n }\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection,\n };\n }\n\n return insertChatComposerTokenIntoChatComposer({\n label: item.title,\n nodes,\n selection,\n tokenKey,\n tokenKind,\n triggerSpecs,\n });\n}\n\nexport function getChatComposerNodesSignature(nodes: ChatComposerNode[]): string {\n return nodes\n .map((node) =>\n node.type === 'text'\n ? `text:${node.text}`\n : `token:${node.tokenKind}:${node.tokenKey}:${node.label}`,\n )\n .join('\\u001f');\n}\n\nexport function replaceChatComposerSelectionWithText(params: {\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n text: string;\n}): ChatComposerEditorSnapshot {\n const { nodes, selection, text } = params;\n const documentLength = getDocumentLength(nodes);\n const [selectionStart, selectionEnd] = selection ? [Math.min(selection.start, selection.end), Math.max(selection.start, selection.end)] : [documentLength, documentLength];\n const nextOffset = selectionStart + text.length;\n\n return {\n nodes: replaceChatComposerRange(\n nodes,\n selectionStart,\n selectionEnd,\n [createChatComposerTextNode(text)],\n ),\n selection: {\n start: nextOffset,\n end: nextOffset,\n },\n };\n}\n\nexport function insertFileTokenIntoChatComposer(params: {\n label: string;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n tokenKey: string;\n}): ChatComposerEditorSnapshot {\n const { label, nodes, selection, tokenKey } = params;\n return insertToken({\n label,\n nodes,\n selection,\n tokenKey,\n tokenKind: 'file',\n });\n}\n\nexport function insertSkillTokenIntoChatComposer(params: {\n label: string;\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n tokenKey: string;\n}): ChatComposerEditorSnapshot {\n const { label, nodes, selection, tokenKey } = params;\n\n if (extractChatComposerTokenKeys(nodes, 'skill').includes(tokenKey)) {\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection,\n };\n }\n\n return insertToken({\n label,\n nodes,\n selection,\n tokenKey,\n tokenKind: 'skill',\n trigger: resolveChatComposerSlashTrigger(nodes, selection),\n });\n}\n\nexport function syncSelectedSkillsIntoChatComposer(params: {\n nextKeys: string[];\n nodes: ChatComposerNode[];\n options: ChatSkillPickerOption[];\n selection: ChatComposerSelection | null;\n}): ChatComposerEditorSnapshot {\n const { nextKeys, nodes, options, selection } = params;\n const selectedSkillKeys = extractChatComposerTokenKeys(nodes, 'skill');\n const optionMap = new Map(options.map((option) => [option.key, option]));\n const addedKey = nextKeys.find((key) => !selectedSkillKeys.includes(key));\n\n if (addedKey) {\n const option = optionMap.get(addedKey);\n return insertSkillTokenIntoChatComposer({\n label: option?.label ?? addedKey,\n nodes,\n selection,\n tokenKey: addedKey,\n });\n }\n\n const removedKey = selectedSkillKeys.find((key) => !nextKeys.includes(key));\n if (!removedKey) {\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection,\n };\n }\n\n return {\n nodes: removeChatComposerTokenNodes(\n nodes,\n (node) => node.tokenKind === 'skill' && node.tokenKey === removedKey,\n ),\n selection,\n };\n}\n\nexport function deleteChatComposerContent(params: {\n direction: 'backward' | 'forward';\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n}): ChatComposerEditorSnapshot {\n const { direction, nodes, selection: currentSelection } = params;\n const documentLength = getDocumentLength(nodes);\n const [selectionStart, selectionEnd] = currentSelection ? [Math.min(currentSelection.start, currentSelection.end), Math.max(currentSelection.start, currentSelection.end)] : [documentLength, documentLength];\n let rangeStart = selectionStart;\n let rangeEnd = selectionEnd;\n\n if (rangeStart === rangeEnd) {\n if (direction === 'backward' && rangeStart > 0) {\n rangeStart -= 1;\n } else if (direction === 'forward' && rangeEnd < documentLength) {\n rangeEnd += 1;\n } else {\n return {\n nodes: normalizeChatComposerNodes(nodes),\n selection: { start: rangeStart, end: rangeEnd },\n };\n }\n }\n\n return {\n nodes: replaceChatComposerRange(nodes, rangeStart, rangeEnd, []),\n selection: {\n start: rangeStart,\n end: rangeStart,\n },\n };\n}\n","import type { FormEvent } from 'react';\nimport type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatInputBarActionsProps,\n ChatInputSurfaceTriggerChangeReason,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n deleteChatComposerContent,\n replaceChatComposerSelectionWithText,\n type ChatComposerEditorSnapshot,\n} from './chat-composer-lexical-adapter';\n\ntype ComposerActions = Pick<\n ChatInputBarActionsProps,\n 'onSend' | 'onStop' | 'isSending' | 'canStopGeneration'\n>;\n\ntype ChatComposerPublishOptions = {\n focusAfterSync?: boolean;\n forcePublish?: boolean;\n inputSurfaceReason?: ChatInputSurfaceTriggerChangeReason;\n};\n\ntype ChatComposerKeyboardAction =\n | { type: 'delete-content'; direction: 'backward' | 'forward' }\n | { type: 'insert-line-break' }\n | { type: 'noop' }\n | { type: 'send-message' }\n | { type: 'stop-generation' };\n\nexport function resolveLexicalComposerKeyboardAction(params: {\n canStopGeneration: boolean;\n isComposing: boolean;\n isSending: boolean;\n key: string;\n shiftKey: boolean;\n}): ChatComposerKeyboardAction {\n const {\n canStopGeneration,\n isComposing,\n isSending,\n key,\n shiftKey,\n } = params;\n\n if (key === 'Escape') {\n if (isSending && canStopGeneration) {\n return { type: 'stop-generation' };\n }\n return { type: 'noop' };\n }\n\n if (key === 'Enter' && shiftKey) {\n return { type: 'insert-line-break' };\n }\n\n if (key === 'Enter') {\n return { type: 'send-message' };\n }\n\n if (!isComposing && (key === 'Backspace' || key === 'Delete')) {\n return {\n type: 'delete-content',\n direction: key === 'Backspace' ? 'backward' : 'forward',\n };\n }\n\n return { type: 'noop' };\n}\n\nfunction getChatComposerContentSignature(nodes: ChatComposerNode[]): string {\n return JSON.stringify(\n nodes.map((node) =>\n node.type === 'text'\n ? { text: node.text, type: node.type }\n : {\n label: node.label,\n tokenKey: node.tokenKey,\n tokenKind: node.tokenKind,\n type: node.type,\n },\n ),\n );\n}\n\nexport function handleLexicalComposerBeforeInput(params: {\n disabled: boolean;\n event: FormEvent<HTMLDivElement>;\n isComposing: boolean;\n publishSnapshot: (snapshot: ChatComposerEditorSnapshot, options?: ChatComposerPublishOptions) => void;\n snapshotReader: () => {\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n };\n}): void {\n const { disabled, event, isComposing, publishSnapshot, snapshotReader } = params;\n const nativeEvent = event.nativeEvent as InputEvent;\n const shouldInsertText =\n nativeEvent.inputType === 'insertText' ||\n nativeEvent.inputType === 'insertReplacementText';\n\n if (\n disabled ||\n isComposing ||\n nativeEvent.isComposing ||\n !shouldInsertText ||\n !nativeEvent.data\n ) {\n return;\n }\n\n event.preventDefault();\n publishSnapshot(\n replaceChatComposerSelectionWithText({\n nodes: snapshotReader().nodes,\n selection: snapshotReader().selection,\n text: nativeEvent.data,\n }),\n { inputSurfaceReason: { type: 'insert-text', text: nativeEvent.data } },\n );\n}\n\nexport function handleLexicalComposerCompositionEnd(params: {\n compositionStartSnapshot?: ChatComposerEditorSnapshot | null;\n data: string;\n fallbackSnapshot: () => ChatComposerEditorSnapshot;\n publishSnapshot: (\n snapshot: ChatComposerEditorSnapshot,\n options?: ChatComposerPublishOptions,\n ) => void;\n snapshotReader: () => {\n nodes: ChatComposerNode[];\n selection: ChatComposerSelection | null;\n };\n}): void {\n const { compositionStartSnapshot, data, fallbackSnapshot, publishSnapshot, snapshotReader } = params;\n const currentSnapshot = snapshotReader();\n const editorSnapshot = fallbackSnapshot();\n const baseSnapshot = compositionStartSnapshot ?? currentSnapshot;\n const shouldUseEditorSnapshot =\n getChatComposerContentSignature(editorSnapshot.nodes) !==\n getChatComposerContentSignature(baseSnapshot.nodes);\n const snapshot = shouldUseEditorSnapshot\n ? editorSnapshot\n : data.length > 0\n ? replaceChatComposerSelectionWithText({\n nodes: baseSnapshot.nodes,\n selection: baseSnapshot.selection,\n text: data,\n })\n : editorSnapshot;\n publishSnapshot(snapshot, {\n forcePublish: true,\n inputSurfaceReason: { type: 'insert-text', text: data },\n });\n}\n\nexport function handleLexicalComposerKeyboardCommand(params: {\n actions: ComposerActions;\n publishSnapshot: (\n snapshot: ChatComposerEditorSnapshot,\n options?: ChatComposerPublishOptions,\n ) => void;\n snapshot: ChatComposerEditorSnapshot;\n nativeEvent: KeyboardEvent;\n}): boolean {\n const {\n actions,\n nativeEvent,\n publishSnapshot,\n snapshot,\n } = params;\n const action = resolveLexicalComposerKeyboardAction({\n canStopGeneration: actions.canStopGeneration,\n isComposing: nativeEvent.isComposing,\n isSending: actions.isSending,\n key: nativeEvent.key,\n shiftKey: nativeEvent.shiftKey,\n });\n\n if (action.type !== 'noop') {\n nativeEvent.preventDefault();\n }\n\n switch (action.type) {\n case 'stop-generation':\n void actions.onStop();\n return true;\n case 'insert-line-break':\n publishSnapshot(\n replaceChatComposerSelectionWithText({\n nodes: snapshot.nodes,\n selection: snapshot.selection,\n text: '\\n',\n }),\n { inputSurfaceReason: { type: 'insert-text', text: '\\n' } },\n );\n return true;\n case 'send-message':\n void actions.onSend();\n return true;\n case 'delete-content':\n publishSnapshot(\n deleteChatComposerContent({\n direction: action.direction,\n nodes: snapshot.nodes,\n selection: snapshot.selection,\n }),\n { inputSurfaceReason: { type: 'delete-content' } },\n );\n return true;\n case 'noop':\n return false;\n }\n}\n","import type { FormEvent } from 'react';\nimport type { EditorState, LexicalEditor } from 'lexical';\nimport {\n BLUR_COMMAND,\n COMMAND_PRIORITY_EDITOR,\n COMMAND_PRIORITY_HIGH,\n KEY_DOWN_COMMAND,\n SELECTION_CHANGE_COMMAND,\n mergeRegister,\n} from 'lexical';\nimport type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatInputBarActionsProps,\n ChatInputSurfaceItem,\n ChatInputSurfaceTriggerChangeReason,\n ChatInputSurfaceTriggerSpec,\n ChatSkillPickerOption,\n ChatSlashItem,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/chat-composer.utils';\nimport {\n type ChatComposerEditorSnapshot,\n getChatComposerNodesSignature,\n insertFileTokenIntoChatComposer,\n insertInputSurfaceItemIntoChatComposer,\n readChatComposerSnapshotFromEditorState,\n syncLexicalEditorFromChatComposerState,\n syncLexicalSelectionFromChatComposerSelection,\n syncSelectedSkillsIntoChatComposer,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-adapter';\nimport {\n handleLexicalComposerBeforeInput,\n handleLexicalComposerCompositionEnd,\n handleLexicalComposerKeyboardCommand,\n} from '@agent-chat-ui/components/chat/ui/chat-input-bar/lexical/chat-composer-lexical-controller';\n\ntype ComposerActions = Pick<ChatInputBarActionsProps, 'onSend' | 'onStop' | 'isSending' | 'canStopGeneration'>;\n\nexport type ChatComposerLexicalOwnerCallbacks = {\n onInputSurfaceItemSelect?: (item: ChatInputSurfaceItem) => void;\n onInputSurfaceKeyDown?: (event: KeyboardEvent) => boolean;\n onInputSurfaceOpenChange?: (open: boolean) => void;\n onInputSurfaceSnapshotChange?: (\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n ) => void;\n onNodesChange: (nodes: ChatComposerNode[]) => void;\n};\n\ntype ComposerRuntime = {\n actions: ComposerActions;\n callbacks: ChatComposerLexicalOwnerCallbacks;\n fallbackNodes: ChatComposerNode[];\n};\n\ntype PublishOptions = {\n focusAfterSync?: boolean;\n forcePublish?: boolean;\n inputSurfaceReason?: ChatInputSurfaceTriggerChangeReason;\n};\n\nfunction createMutableRef<T>(value: T): { current: T } {\n return { current: value };\n}\n\nfunction getChatComposerDocumentLength(nodes: ChatComposerNode[]): number {\n return nodes.reduce((cursor, node) => cursor + (node.type === 'text' ? node.text.length : 1), 0);\n}\n\nexport class ChatComposerLexicalOwner {\n readonly isApplyingExternalUpdateRef = createMutableRef(false);\n readonly isComposingRef = createMutableRef(false);\n readonly pendingOwnerSignatureRef = createMutableRef<string | null>(null);\n readonly pendingSelectionRef = createMutableRef<ChatComposerSelection | null>(null);\n readonly selectionRef = createMutableRef<ChatComposerSelection | null>(null);\n readonly shouldFocusAfterSyncRef = createMutableRef(false);\n\n private readonly compositionStartSnapshotRef = createMutableRef<ChatComposerEditorSnapshot | null>(null);\n private readonly editorSignatureRef = createMutableRef('');\n private readonly lastPublishedSignatureRef = createMutableRef('');\n private readonly pendingInputSurfaceReasonRef = createMutableRef<ChatInputSurfaceTriggerChangeReason | null>(null);\n private editor: LexicalEditor | null = null;\n private runtime: ComposerRuntime | null = null;\n\n configureRuntime = (runtime: ComposerRuntime): void => {\n this.runtime = runtime;\n };\n\n bindEditor = (editor: LexicalEditor): (() => void) => {\n this.editor = editor;\n return () => {\n if (this.editor === editor) {\n this.editor = null;\n }\n };\n };\n\n registerEditorListeners = (editor: LexicalEditor): (() => void) => {\n return mergeRegister(\n editor.registerUpdateListener(({ editorState }) => {\n const runtime = this.getRuntime();\n this.handleEditorUpdate(editorState, runtime.callbacks);\n }),\n editor.registerCommand(\n SELECTION_CHANGE_COMMAND,\n () => {\n const runtime = this.getRuntime();\n this.handleSelectionChange(editor, runtime.callbacks);\n return false;\n },\n COMMAND_PRIORITY_EDITOR,\n ),\n editor.registerCommand(\n BLUR_COMMAND,\n () => {\n const runtime = this.getRuntime();\n runtime.callbacks.onInputSurfaceOpenChange?.(false);\n return false;\n },\n COMMAND_PRIORITY_EDITOR,\n ),\n editor.registerCommand(\n KEY_DOWN_COMMAND,\n (event) => {\n const runtime = this.getRuntime();\n return this.handleKeyDown({\n actions: runtime.actions,\n callbacks: runtime.callbacks,\n event,\n fallbackNodes: runtime.fallbackNodes,\n });\n },\n COMMAND_PRIORITY_HIGH,\n ),\n );\n };\n\n syncExternalState = (editor: LexicalEditor, nodes: ChatComposerNode[]): void => {\n if (this.isComposingRef.current) {\n return;\n }\n const nextSignature = getChatComposerNodesSignature(nodes);\n const pendingSelection = this.pendingSelectionRef.current;\n const pendingOwnerSignature = this.pendingOwnerSignatureRef.current;\n\n if (pendingOwnerSignature) {\n if (nextSignature === pendingOwnerSignature) {\n this.pendingOwnerSignatureRef.current = null;\n } else if (nextSignature !== this.editorSignatureRef.current) {\n return;\n }\n }\n\n const shouldSyncDocument = nextSignature !== this.editorSignatureRef.current;\n\n if (!shouldSyncDocument && !pendingSelection) {\n return;\n }\n\n this.startApplyingExternalUpdate();\n\n if (shouldSyncDocument) {\n syncLexicalEditorFromChatComposerState(editor, nodes, pendingSelection);\n this.editorSignatureRef.current = nextSignature;\n this.lastPublishedSignatureRef.current = nextSignature;\n } else if (pendingSelection) {\n syncLexicalSelectionFromChatComposerSelection(editor, pendingSelection);\n }\n\n if (pendingSelection) {\n this.selectionRef.current = pendingSelection;\n this.pendingSelectionRef.current = null;\n }\n\n if (this.shouldFocusAfterSyncRef.current) {\n this.shouldFocusAfterSyncRef.current = false;\n const targetSelection = this.selectionRef.current;\n editor.focus(() => {\n if (targetSelection) {\n syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);\n }\n });\n }\n };\n\n publishSnapshot = (\n snapshot: ChatComposerEditorSnapshot,\n callbacks: ChatComposerLexicalOwnerCallbacks,\n options?: PublishOptions,\n ): void => {\n this.selectionRef.current = snapshot.selection;\n this.pendingSelectionRef.current = snapshot.selection;\n\n if (options?.focusAfterSync) {\n this.shouldFocusAfterSyncRef.current = true;\n }\n\n const signature = getChatComposerNodesSignature(snapshot.nodes);\n const { editor } = this;\n this.pendingOwnerSignatureRef.current = signature;\n if (editor) {\n this.startApplyingExternalUpdate();\n syncLexicalEditorFromChatComposerState(editor, snapshot.nodes, snapshot.selection);\n this.editorSignatureRef.current = signature;\n }\n callbacks.onInputSurfaceSnapshotChange?.(\n snapshot.nodes,\n snapshot.selection,\n options?.inputSurfaceReason ?? { type: 'programmatic' },\n );\n\n if (options?.forcePublish || signature !== this.lastPublishedSignatureRef.current) {\n this.lastPublishedSignatureRef.current = signature;\n callbacks.onNodesChange(snapshot.nodes);\n }\n };\n\n focusComposer = (): void => {\n const { editor } = this;\n if (!editor) {\n return;\n }\n\n editor.getRootElement()?.focus({ preventScroll: true });\n const targetSelection = this.selectionRef.current;\n if (targetSelection) {\n syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);\n }\n editor.focus();\n };\n\n focusComposerAtEnd = (nodes?: ChatComposerNode[]): void => {\n const { editor } = this;\n if (!editor) {\n return;\n }\n const targetNodes = nodes ?? readChatComposerSnapshotFromEditorState(editor.getEditorState()).nodes;\n const end = getChatComposerDocumentLength(targetNodes);\n const targetSelection = { start: end, end };\n this.selectionRef.current = targetSelection;\n this.pendingSelectionRef.current = targetSelection;\n editor.getRootElement()?.focus({ preventScroll: true });\n if (nodes) {\n this.startApplyingExternalUpdate();\n const signature = getChatComposerNodesSignature(nodes);\n syncLexicalEditorFromChatComposerState(editor, nodes, targetSelection);\n this.editorSignatureRef.current = signature;\n this.lastPublishedSignatureRef.current = signature;\n } else {\n syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);\n }\n editor.focus(() => {\n syncLexicalSelectionFromChatComposerSelection(editor, targetSelection);\n });\n };\n\n readComposerSnapshot = (fallbackNodes: ChatComposerNode[]): ChatComposerEditorSnapshot => {\n const { editor } = this;\n if (!editor) {\n return {\n nodes: fallbackNodes,\n selection: this.selectionRef.current,\n };\n }\n const snapshot = readChatComposerSnapshotFromEditorState(editor.getEditorState());\n this.selectionRef.current = snapshot.selection;\n return snapshot;\n };\n\n createHandle = () => {\n const insertInputSurfaceItem = (\n item: ChatInputSurfaceItem,\n triggerSpecs: readonly ChatInputSurfaceTriggerSpec[] = [CHAT_INPUT_SURFACE_SLASH_TRIGGER_SPEC],\n ): void => {\n const { callbacks } = this.getRuntime();\n callbacks.onInputSurfaceItemSelect?.(item);\n this.publishRuntimeSnapshot(\n (snapshot) => insertInputSurfaceItemIntoChatComposer({\n item,\n nodes: snapshot.nodes,\n selection: snapshot.selection,\n triggerSpecs,\n }),\n { focusAfterSync: true },\n );\n };\n\n return {\n insertInputSurfaceItem,\n insertSlashItem: (item: ChatSlashItem): void => {\n insertInputSurfaceItem(item);\n },\n insertFileToken: (tokenKey: string, label: string): void => {\n this.publishRuntimeSnapshot(\n (snapshot) => insertFileTokenIntoChatComposer({\n label,\n nodes: snapshot.nodes,\n selection: snapshot.selection,\n tokenKey,\n }),\n { focusAfterSync: true },\n );\n },\n insertFileTokens: (tokens: Array<{ tokenKey: string; label: string }>): void => {\n this.publishRuntimeSnapshot(\n (snapshot) =>\n tokens.reduce(\n (nextSnapshot, token) =>\n insertFileTokenIntoChatComposer({\n label: token.label,\n nodes: nextSnapshot.nodes,\n selection: nextSnapshot.selection,\n tokenKey: token.tokenKey,\n }),\n snapshot,\n ),\n { focusAfterSync: true },\n );\n },\n focusComposer: this.focusComposer,\n focusComposerAtEnd: this.focusComposerAtEnd,\n syncSelectedSkills: (nextKeys: string[], options: ChatSkillPickerOption[]): void => {\n this.publishRuntimeSnapshot(\n (snapshot) => syncSelectedSkillsIntoChatComposer({\n nextKeys,\n nodes: snapshot.nodes,\n options,\n selection: snapshot.selection,\n }),\n { focusAfterSync: true },\n );\n },\n };\n };\n\n handleBeforeInput = (params: {\n disabled: boolean;\n event: FormEvent<HTMLDivElement>;\n }): void => {\n const { disabled, event } = params;\n const { callbacks, fallbackNodes } = this.getRuntime();\n handleLexicalComposerBeforeInput({\n disabled,\n event,\n isComposing: this.isComposingRef.current,\n publishSnapshot: (snapshot, options) => this.publishSnapshot(snapshot, callbacks, options),\n snapshotReader: () => this.readComposerSnapshot(fallbackNodes),\n });\n };\n\n handleCompositionStart = (): void => {\n const { fallbackNodes } = this.getRuntime();\n this.compositionStartSnapshotRef.current = this.readComposerSnapshot(fallbackNodes);\n this.isComposingRef.current = true;\n };\n\n handleCompositionEnd = (params: { data: string }): void => {\n const { data } = params;\n const { callbacks, fallbackNodes } = this.getRuntime();\n this.isComposingRef.current = false;\n handleLexicalComposerCompositionEnd({\n compositionStartSnapshot: this.compositionStartSnapshotRef.current,\n data,\n fallbackSnapshot: () => this.readComposerSnapshot(fallbackNodes),\n publishSnapshot: (snapshot, options) => this.publishSnapshot(snapshot, callbacks, options),\n snapshotReader: () => this.readComposerSnapshot(fallbackNodes),\n });\n this.compositionStartSnapshotRef.current = null;\n };\n\n handleKeyDown = (params: {\n actions: ComposerActions;\n callbacks: ChatComposerLexicalOwnerCallbacks;\n event: KeyboardEvent;\n fallbackNodes: ChatComposerNode[];\n }): boolean => {\n const { actions, callbacks, event, fallbackNodes } = params;\n if (\n event.key.length === 1 &&\n !event.isComposing &&\n !event.altKey &&\n !event.ctrlKey &&\n !event.metaKey\n ) {\n this.pendingInputSurfaceReasonRef.current = { type: 'insert-text', text: event.key };\n }\n\n const snapshot = this.readComposerSnapshot(fallbackNodes);\n if (callbacks.onInputSurfaceKeyDown?.(event)) {\n return true;\n }\n return handleLexicalComposerKeyboardCommand({\n actions,\n nativeEvent: event,\n publishSnapshot: (nextSnapshot, options) => this.publishSnapshot(nextSnapshot, callbacks, options),\n snapshot,\n });\n };\n\n handleEditorUpdate = (editorState: EditorState, callbacks: ChatComposerLexicalOwnerCallbacks): void => {\n const snapshot = readChatComposerSnapshotFromEditorState(editorState);\n const signature = getChatComposerNodesSignature(snapshot.nodes);\n\n this.editorSignatureRef.current = signature;\n\n if (this.isApplyingExternalUpdateRef.current || this.isComposingRef.current) {\n return;\n }\n\n this.selectionRef.current = snapshot.selection;\n callbacks.onInputSurfaceSnapshotChange?.(\n snapshot.nodes,\n snapshot.selection,\n this.consumeInputSurfaceReason() ?? { type: 'sync' },\n );\n\n if (signature === this.lastPublishedSignatureRef.current) {\n return;\n }\n\n this.lastPublishedSignatureRef.current = signature;\n callbacks.onNodesChange(snapshot.nodes);\n };\n\n handleSelectionChange = (editor: LexicalEditor, callbacks: ChatComposerLexicalOwnerCallbacks): void => {\n const snapshot = readChatComposerSnapshotFromEditorState(editor.getEditorState());\n if (this.isComposingRef.current) {\n return;\n }\n this.selectionRef.current = snapshot.selection;\n callbacks.onInputSurfaceSnapshotChange?.(snapshot.nodes, snapshot.selection, { type: 'selection' });\n };\n\n private consumeInputSurfaceReason = (): ChatInputSurfaceTriggerChangeReason | null => {\n const reason = this.pendingInputSurfaceReasonRef.current;\n this.pendingInputSurfaceReasonRef.current = null;\n return reason;\n };\n\n private publishRuntimeSnapshot = (\n createSnapshot: (snapshot: ChatComposerEditorSnapshot) => ChatComposerEditorSnapshot,\n options: PublishOptions,\n ): void => {\n const { callbacks, fallbackNodes } = this.getRuntime();\n this.publishSnapshot(createSnapshot(this.readComposerSnapshot(fallbackNodes)), callbacks, options);\n };\n\n private startApplyingExternalUpdate = (): void => {\n this.isApplyingExternalUpdateRef.current = true;\n requestAnimationFrame(() => {\n this.isApplyingExternalUpdateRef.current = false;\n });\n };\n\n private getRuntime = (): ComposerRuntime => {\n if (!this.runtime) {\n throw new Error('ChatComposerLexicalOwner runtime has not been configured.');\n }\n return this.runtime;\n };\n}\n","import { useEffect, useLayoutEffect } from 'react';\nimport { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';\nimport type {\n ChatComposerNode,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport type { ChatComposerLexicalOwner } from './owners/chat-composer-lexical-owner';\n\ntype ChatComposerBindingsPluginProps = {\n disabled: boolean;\n nodes: ChatComposerNode[];\n owner: ChatComposerLexicalOwner;\n};\n\nexport function ChatComposerBindingsPlugin(\n {\n disabled,\n nodes,\n owner,\n }: ChatComposerBindingsPluginProps,\n): null {\n const [editor] = useLexicalComposerContext();\n\n useLayoutEffect(() => {\n return owner.bindEditor(editor);\n }, [editor, owner]);\n\n useLayoutEffect(() => {\n editor.setEditable(!disabled);\n owner.syncExternalState(editor, nodes);\n }, [disabled, editor, nodes, owner]);\n\n useEffect(() => {\n return owner.registerEditorListeners(editor);\n }, [editor, owner]);\n\n return null;\n}\n","import {\n forwardRef,\n useImperativeHandle,\n useMemo,\n useState,\n type ClipboardEvent,\n type FormEvent,\n} from 'react';\nimport { ContentEditable } from '@lexical/react/LexicalContentEditable';\nimport { LexicalComposer } from '@lexical/react/LexicalComposer';\nimport { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';\nimport { PlainTextPlugin } from '@lexical/react/LexicalPlainTextPlugin';\nimport type {\n ChatComposerNode,\n ChatComposerSelection,\n ChatInputSurfaceItem,\n ChatInputSurfaceTriggerChangeReason,\n ChatInputSurfaceTriggerSpec,\n ChatInputBarActionsProps,\n ChatSkillPickerOption,\n ChatSlashItem,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n writeChatComposerStateToLexicalRoot,\n} from './chat-composer-lexical-adapter';\nimport { ChatComposerLexicalOwner } from './owners/chat-composer-lexical-owner';\nimport { ChatComposerBindingsPlugin } from './chat-composer-plugins';\nimport { ChatComposerTokenNode } from './chat-composer-token-node';\n\nexport type ChatInputBarTokenizedComposerHandle = {\n insertInputSurfaceItem: (\n item: ChatInputSurfaceItem,\n triggerSpecs?: readonly ChatInputSurfaceTriggerSpec[],\n ) => void;\n insertSlashItem: (item: ChatSlashItem) => void;\n insertFileToken: (tokenKey: string, label: string) => void;\n insertFileTokens: (tokens: Array<{ tokenKey: string; label: string }>) => void;\n focusComposer: () => void;\n focusComposerAtEnd: (nodes?: ChatComposerNode[]) => void;\n syncSelectedSkills: (nextKeys: string[], options: ChatSkillPickerOption[]) => void;\n};\n\ntype ChatInputBarTokenizedComposerProps = {\n nodes: ChatComposerNode[];\n placeholder: string;\n disabled: boolean;\n onInputSurfaceItemSelect?: (item: ChatInputSurfaceItem) => void;\n actions: Pick<ChatInputBarActionsProps, 'onSend' | 'onStop' | 'isSending' | 'canStopGeneration'>;\n onNodesChange: (nodes: ChatComposerNode[]) => void;\n onFilesAdd?: (files: File[]) => Promise<void> | void;\n onInputSurfaceSnapshotChange?: (\n nodes: ChatComposerNode[],\n selection: ChatComposerSelection | null,\n reason: ChatInputSurfaceTriggerChangeReason,\n ) => void;\n onInputSurfaceOpenChange?: (open: boolean) => void;\n onInputSurfaceKeyDown?: (event: KeyboardEvent) => boolean;\n};\n\nexport const ChatInputBarTokenizedComposer = forwardRef<\n ChatInputBarTokenizedComposerHandle,\n ChatInputBarTokenizedComposerProps\n>(function ChatInputBarTokenizedComposer(\n {\n actions,\n disabled,\n nodes,\n onFilesAdd,\n onInputSurfaceItemSelect,\n onInputSurfaceKeyDown,\n onInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange,\n onNodesChange,\n placeholder,\n },\n ref,\n) {\n const [owner] = useState(() => new ChatComposerLexicalOwner());\n const ownerCallbacks = useMemo(\n () => ({\n onInputSurfaceItemSelect,\n onInputSurfaceKeyDown,\n onInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange,\n onNodesChange,\n }),\n [\n onInputSurfaceItemSelect,\n onInputSurfaceKeyDown,\n onInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange,\n onNodesChange,\n ],\n );\n owner.configureRuntime({\n actions,\n callbacks: ownerCallbacks,\n fallbackNodes: nodes,\n });\n\n useImperativeHandle(\n ref,\n () => owner.createHandle(),\n [owner],\n );\n\n const initialConfig = useMemo(\n () => ({\n editable: !disabled,\n editorState: () => {\n writeChatComposerStateToLexicalRoot(nodes, null);\n },\n namespace: 'NextClawChatComposerLexical',\n nodes: [ChatComposerTokenNode],\n onError: (error: Error) => {\n throw error;\n },\n theme: {},\n }),\n [disabled, nodes],\n );\n\n return (\n <LexicalComposer initialConfig={initialConfig}>\n <div className=\"px-3 py-2 sm:px-4 sm:py-2.5\">\n <div className=\"min-h-11 sm:min-h-[60px]\">\n <PlainTextPlugin\n contentEditable={\n <ContentEditable\n 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\"\n onBeforeInput={(event: FormEvent<HTMLDivElement>) => {\n owner.handleBeforeInput({\n disabled,\n event,\n });\n }}\n onCompositionEnd={(event) => {\n const nativeEvent = event.nativeEvent as CompositionEvent;\n owner.handleCompositionEnd({\n data: typeof nativeEvent.data === 'string' ? nativeEvent.data : '',\n });\n }}\n onCompositionStart={() => {\n owner.handleCompositionStart();\n }}\n onPaste={(event: ClipboardEvent<HTMLDivElement>) => {\n const files = Array.from(event.clipboardData.files ?? []);\n if (files.length > 0 && onFilesAdd) {\n event.preventDefault();\n void onFilesAdd(files);\n }\n }}\n />\n }\n placeholder={\n <div 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\">\n {placeholder}\n </div>\n }\n ErrorBoundary={LexicalErrorBoundary}\n />\n </div>\n </div>\n <ChatComposerBindingsPlugin\n disabled={disabled}\n nodes={nodes}\n owner={owner}\n />\n </LexicalComposer>\n );\n});\n\nChatInputBarTokenizedComposer.displayName = 'LexicalChatInputBarTokenizedComposer';\n","import { forwardRef, useImperativeHandle, useMemo, useRef } from 'react';\nimport type {\n ChatInputBarProps,\n ChatInputSurfaceConfig,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { ChatInputSurfaceHost } from '@agent-chat-ui/components/chat/ui/input-surface/chat-input-surface-host';\nimport { ChatInputBarToolbar } from './chat-input-bar-toolbar';\nimport { ChatInputBarTokenizedComposer, type ChatInputBarTokenizedComposerHandle } from './chat-input-bar-tokenized-composer';\n\nfunction InputBarHint({ hint }: { hint: ChatInputBarProps['hint'] }) {\n if (!hint) {\n return null;\n }\n\n if (hint.loading) {\n return (\n <div className=\"px-4 pb-2\">\n <div className=\"inline-flex items-center gap-2 rounded-lg border border-border bg-muted px-3 py-2\">\n <span className=\"h-3 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"h-3 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n </div>\n );\n }\n\n const toneClassName =\n hint.tone === 'warning'\n ? 'border-amber-200 bg-amber-50 text-amber-800'\n : 'border-border bg-muted text-muted-foreground';\n\n return (\n <div className=\"px-4 pb-2\">\n <div className={`inline-flex items-center gap-2 rounded-lg px-3 py-1.5 text-xs ${toneClassName}`}>\n {hint.text ? <span>{hint.text}</span> : null}\n {hint.actionLabel && hint.onAction ? (\n <button\n type=\"button\"\n onClick={hint.onAction}\n className=\"font-semibold underline-offset-2 hover:underline\"\n >\n {hint.actionLabel}\n </button>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport type ChatInputBarHandle = {\n insertFileToken: (tokenKey: string, label: string) => void;\n insertFileTokens: (tokens: Array<{ tokenKey: string; label: string }>) => void;\n focusComposer: () => void;\n focusComposerAtEnd: (nodes?: ChatInputBarProps['composer']['nodes']) => void;\n};\n\nexport const ChatInputBar = forwardRef<ChatInputBarHandle, ChatInputBarProps>(function ChatInputBar(\n { composer, hint, inputSurface, slashMenu, surface, toolbar: toolbarProps, topSlot },\n ref\n) {\n const composerRef = useRef<ChatInputBarTokenizedComposerHandle | null>(null);\n const resolvedInputSurface: ChatInputSurfaceConfig | null = inputSurface ?? (slashMenu\n ? {\n isLoading: slashMenu.isLoading,\n filterOptions: slashMenu.filterOptions,\n items: slashMenu.items,\n onSelectItem: slashMenu.onSelectItem,\n texts: {\n loadingLabel: slashMenu.texts.slashLoadingLabel,\n sectionLabel: slashMenu.texts.slashSectionLabel,\n emptyLabel: slashMenu.texts.slashEmptyLabel,\n hintLabel: slashMenu.texts.slashHintLabel,\n itemHintLabel: slashMenu.texts.slashSkillHintLabel,\n },\n }\n : null);\n\n const toolbar = useMemo(() => {\n if (!toolbarProps.skillPicker) {\n return toolbarProps;\n }\n return {\n ...toolbarProps,\n skillPicker: {\n ...toolbarProps.skillPicker,\n onSelectedKeysChange: (nextKeys: string[]) => {\n composerRef.current?.syncSelectedSkills(nextKeys, toolbarProps.skillPicker?.options ?? []);\n toolbarProps.skillPicker?.onSelectedKeysChange(nextKeys);\n }\n }\n };\n }, [toolbarProps]);\n\n useImperativeHandle(ref, () => ({\n insertFileToken: (tokenKey, label) => composerRef.current?.insertFileToken(tokenKey, label),\n insertFileTokens: (tokens) => composerRef.current?.insertFileTokens(tokens),\n focusComposer: () => composerRef.current?.focusComposer(),\n focusComposerAtEnd: (nodes) => composerRef.current?.focusComposerAtEnd(nodes),\n }), []);\n const surfaceClassName =\n surface === 'embedded'\n ? 'bg-transparent px-0 py-0'\n : 'bg-background px-3 pb-3 pt-2 sm:px-4 sm:pb-4 sm:pt-2';\n\n return (\n <div className={surfaceClassName}>\n <div className=\"nextclaw-chat-input-bar-shell mx-auto w-full max-w-[min(1120px,100%)] [container:nextclaw-chat-input-bar/inline-size]\">\n <div className=\"overflow-hidden rounded-2xl border border-border bg-card shadow-card\">\n {topSlot ? (\n <div className=\"px-3 pb-0 pt-2 sm:px-4 sm:pt-2.5\">\n {topSlot}\n </div>\n ) : null}\n <div className=\"relative\">\n <ChatInputSurfaceHost\n inputSurface={resolvedInputSurface}\n onInputSurfaceTriggerChange={composer.onInputSurfaceTriggerChange}\n onSelectItem={(item) => composerRef.current?.insertInputSurfaceItem(item, composer.inputSurfaceTriggerSpecs)}\n triggerSpecs={composer.inputSurfaceTriggerSpecs}\n >\n {({\n onInputSurfaceKeyDown,\n onInputSurfaceOpenChange,\n onInputSurfaceSnapshotChange,\n }) => (\n <ChatInputBarTokenizedComposer\n ref={composerRef}\n nodes={composer.nodes}\n placeholder={composer.placeholder}\n disabled={composer.disabled}\n onInputSurfaceItemSelect={resolvedInputSurface?.onSelectItem}\n actions={toolbarProps.actions}\n onNodesChange={composer.onNodesChange}\n onFilesAdd={composer.onFilesAdd}\n onInputSurfaceSnapshotChange={onInputSurfaceSnapshotChange}\n onInputSurfaceOpenChange={onInputSurfaceOpenChange}\n onInputSurfaceKeyDown={onInputSurfaceKeyDown}\n />\n )}\n </ChatInputSurfaceHost>\n </div>\n\n <InputBarHint hint={hint} />\n <ChatInputBarToolbar {...toolbar} />\n </div>\n </div>\n </div>\n );\n});\n\nChatInputBar.displayName = 'ChatInputBar';\n","import type { ChatMessageRole } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { Bot, User, Wrench } from 'lucide-react';\n\nexport function ChatMessageAvatar({ role }: { role: ChatMessageRole }) {\n if (role === 'user') {\n return (\n <div\n data-testid=\"chat-message-avatar-user\"\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-sm\"\n >\n <User className=\"h-4 w-4\" />\n </div>\n );\n }\n if (role === 'tool') {\n return (\n <div\n data-testid=\"chat-message-avatar-tool\"\n 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\"\n >\n <Wrench className=\"h-4 w-4\" />\n </div>\n );\n }\n return (\n <div\n data-testid=\"chat-message-avatar-assistant\"\n className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-muted text-foreground shadow-sm ring-1 ring-border\"\n >\n <Bot className=\"h-[18px] w-[18px] text-current\" strokeWidth={2.5} />\n </div>\n );\n}\n","import { AppWindow, Puzzle } from \"lucide-react\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\n\ntype ChatInlineTokenTone = \"skill\" | \"panel_app\" | \"default\";\n\nfunction resolveInlineTokenTone(kind: string): ChatInlineTokenTone {\n if (kind === \"skill\") {\n return \"skill\";\n }\n if (kind === \"panel_app\") {\n return \"panel_app\";\n }\n return \"default\";\n}\n\nfunction resolveInlineTokenBadgeClassName(\n tone: ChatInlineTokenTone,\n isUser: boolean,\n interactive: boolean,\n): string {\n if (tone === \"skill\") {\n // Skill tokens use the markdown link semantic color, not primary brand fill.\n return cn(\n \"border-transparent bg-transparent text-[color:var(--md-link)]\",\n interactive &&\n \"cursor-pointer underline-offset-2 hover:underline focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-[color:var(--md-link)]/30\",\n !interactive && \"cursor-default\",\n );\n }\n if (tone === \"panel_app\") {\n return isUser\n ? \"border-primary-foreground/40 bg-primary-foreground/22 text-primary-foreground\"\n : \"border-border bg-muted text-foreground\";\n }\n return isUser\n ? \"border-primary-foreground/40 bg-primary-foreground/22 text-primary-foreground\"\n : \"border-border bg-muted text-muted-foreground\";\n}\n\nfunction resolveInlineTokenIconClassName(\n tone: ChatInlineTokenTone,\n isUser: boolean,\n): string {\n if (tone === \"skill\") {\n return \"text-current opacity-80\";\n }\n if (tone === \"panel_app\") {\n return isUser ? \"text-primary-foreground/80\" : \"text-muted-foreground\";\n }\n return isUser ? \"text-primary-foreground/80\" : \"text-muted-foreground\";\n}\n\nfunction renderInlineTokenIcon(tone: ChatInlineTokenTone) {\n return tone === \"panel_app\" ? (\n <AppWindow aria-hidden=\"true\" className=\"h-3 w-3\" />\n ) : (\n <Puzzle aria-hidden=\"true\" className=\"h-3 w-3\" />\n );\n}\n\nexport function ChatInlineTokenBadge({\n kind,\n label,\n isUser,\n onClick,\n}: {\n kind: string;\n label: string;\n isUser: boolean;\n onClick?: () => void;\n}) {\n const tone = resolveInlineTokenTone(kind);\n const interactive = Boolean(onClick);\n const className = cn(\n \"nextclaw-chat-inline-token mx-[2px] inline-flex max-w-full items-center gap-1 align-baseline text-[11px] font-medium\",\n tone === \"skill\" ? \"h-auto rounded-none px-0 py-0\" : \"h-7 rounded-xl border px-2.5\",\n resolveInlineTokenBadgeClassName(tone, isUser, interactive),\n );\n const content = (\n <>\n <span\n className={cn(\n \"inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center\",\n resolveInlineTokenIconClassName(tone, isUser),\n )}\n >\n {renderInlineTokenIcon(tone)}\n </span>\n <span className=\"truncate\">{label}</span>\n </>\n );\n\n if (interactive) {\n return (\n <button\n type=\"button\"\n className={className}\n title={label}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onClick?.();\n }}\n >\n {content}\n </button>\n );\n }\n\n return (\n <span className={className} title={label}>\n {content}\n </span>\n );\n}\n","function canUseClipboardApi(): boolean {\n return (\n typeof navigator !== 'undefined' &&\n typeof navigator.clipboard?.writeText === 'function'\n );\n}\n\nfunction restoreSelection(ranges: Range[]) {\n if (typeof document === 'undefined') {\n return;\n }\n\n const selection = document.getSelection();\n if (!selection) {\n return;\n }\n\n selection.removeAllRanges();\n ranges.forEach((range) => selection.addRange(range));\n}\n\ntype CopyContextSnapshot = {\n activeElement: HTMLElement | null;\n activeInputSelection: {\n input: HTMLInputElement | HTMLTextAreaElement;\n start: number | null;\n end: number | null;\n } | null;\n ranges: Range[];\n};\n\nfunction snapshotCopyContext(): CopyContextSnapshot {\n const activeElement = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n const activeInput = activeElement instanceof HTMLInputElement || activeElement instanceof HTMLTextAreaElement\n ? activeElement\n : null;\n const activeInputSelection = activeInput\n ? {\n input: activeInput,\n start: activeInput.selectionStart,\n end: activeInput.selectionEnd\n }\n : null;\n const selection = document.getSelection();\n const ranges = selection\n ? Array.from({ length: selection.rangeCount }, (_, index) => selection.getRangeAt(index).cloneRange())\n : [];\n return { activeElement, activeInputSelection, ranges };\n}\n\nfunction createCopyTextarea(text: string): HTMLTextAreaElement {\n const textarea = document.createElement('textarea');\n textarea.value = text;\n textarea.setAttribute('readonly', '');\n textarea.setAttribute('aria-hidden', 'true');\n Object.assign(textarea.style, {\n fontSize: '12pt',\n left: '-9999px',\n opacity: '0',\n pointerEvents: 'none',\n position: 'fixed',\n top: '0'\n });\n return textarea;\n}\n\nfunction focusWithoutScroll(element: HTMLElement) {\n try {\n element.focus({ preventScroll: true });\n } catch {\n element.focus();\n }\n}\n\nfunction selectTextarea(textarea: HTMLTextAreaElement) {\n focusWithoutScroll(textarea);\n textarea.select();\n textarea.setSelectionRange(0, textarea.value.length);\n}\n\nfunction runCopyCommand(): boolean {\n try {\n return typeof document.execCommand === 'function' && document.execCommand('copy');\n } catch {\n return false;\n }\n}\n\nfunction restoreInputSelection(snapshot: CopyContextSnapshot): boolean {\n if (!snapshot.activeInputSelection) {\n return false;\n }\n\n const { input, start, end } = snapshot.activeInputSelection;\n if (start === null || end === null) {\n return false;\n }\n input.setSelectionRange(start, end);\n return true;\n}\n\nfunction restoreCopyContext(snapshot: CopyContextSnapshot) {\n if (snapshot.activeElement) {\n focusWithoutScroll(snapshot.activeElement);\n }\n if (!restoreInputSelection(snapshot)) {\n restoreSelection(snapshot.ranges);\n }\n}\n\nfunction fallbackCopyText(text: string): boolean {\n if (typeof document === 'undefined' || !document.body) {\n return false;\n }\n\n const snapshot = snapshotCopyContext();\n const textarea = createCopyTextarea(text);\n document.body.appendChild(textarea);\n selectTextarea(textarea);\n const copied = runCopyCommand();\n textarea.remove();\n restoreCopyContext(snapshot);\n return copied;\n}\n\nexport async function copyText(text: string): Promise<boolean> {\n if (!text) {\n return false;\n }\n\n if (canUseClipboardApi()) {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n return fallbackCopyText(text);\n }\n }\n\n return fallbackCopyText(text);\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { copyText } from '@agent-chat-ui/components/chat/utils/copy-text.utils';\n\ntype UseCopyFeedbackParams = {\n text: string;\n resetDelayMs?: number;\n};\n\ntype UseCopyFeedbackResult = {\n copied: boolean;\n copy: () => Promise<void>;\n};\n\nconst DEFAULT_RESET_DELAY_MS = 1300;\n\nexport function useCopyFeedback(params: UseCopyFeedbackParams): UseCopyFeedbackResult {\n const [copied, setCopied] = useState(false);\n\n const copy = useCallback(async () => {\n if (!params.text) {\n return;\n }\n\n const didCopy = await copyText(params.text);\n if (didCopy) {\n setCopied(true);\n } else {\n setCopied(false);\n }\n }, [params.text]);\n\n useEffect(() => {\n if (!copied || typeof window === 'undefined') {\n return;\n }\n\n const timer = window.setTimeout(() => setCopied(false), params.resetDelayMs ?? DEFAULT_RESET_DELAY_MS);\n return () => window.clearTimeout(timer);\n }, [copied, params.resetDelayMs]);\n\n return {\n copied,\n copy\n };\n}\n","import hljs from 'highlight.js/lib/core';\nimport bash from 'highlight.js/lib/languages/bash';\nimport css from 'highlight.js/lib/languages/css';\nimport diff from 'highlight.js/lib/languages/diff';\nimport javascript from 'highlight.js/lib/languages/javascript';\nimport json from 'highlight.js/lib/languages/json';\nimport markdown from 'highlight.js/lib/languages/markdown';\nimport python from 'highlight.js/lib/languages/python';\nimport shell from 'highlight.js/lib/languages/shell';\nimport sql from 'highlight.js/lib/languages/sql';\nimport typescript from 'highlight.js/lib/languages/typescript';\nimport xml from 'highlight.js/lib/languages/xml';\nimport yaml from 'highlight.js/lib/languages/yaml';\nimport type { HLJSApi, LanguageFn } from 'highlight.js';\n\nconst PLAIN_TEXT_LANGUAGES = new Set([\n 'text',\n 'txt',\n 'plain',\n 'plaintext',\n 'none',\n 'output',\n]);\n\nconst AUTO_DETECT_LANGUAGES = [\n 'typescript',\n 'javascript',\n 'json',\n 'bash',\n 'shell',\n 'python',\n 'css',\n 'xml',\n 'markdown',\n 'yaml',\n 'sql',\n 'diff',\n];\n\nconst AUTO_DETECT_MIN_RELEVANCE = 4;\n\ntype RegisteredLanguage = {\n name: string;\n language: LanguageFn;\n aliases?: string[];\n};\n\nconst REGISTERED_LANGUAGES: RegisteredLanguage[] = [\n { name: 'typescript', language: typescript, aliases: ['ts', 'tsx'] },\n { name: 'javascript', language: javascript, aliases: ['js', 'jsx', 'mjs', 'cjs'] },\n { name: 'json', language: json, aliases: ['jsonc'] },\n { name: 'bash', language: bash, aliases: ['sh', 'zsh'] },\n { name: 'shell', language: shell, aliases: ['console', 'terminal'] },\n { name: 'python', language: python, aliases: ['py'] },\n { name: 'css', language: css },\n { name: 'xml', language: xml, aliases: ['html', 'svg'] },\n { name: 'markdown', language: markdown, aliases: ['md', 'mdx'] },\n { name: 'yaml', language: yaml, aliases: ['yml'] },\n { name: 'sql', language: sql },\n { name: 'diff', language: diff, aliases: ['patch'] },\n];\n\nexport type ChatCodeHighlightResult = {\n html: string;\n language: string;\n highlighted: boolean;\n};\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\nfunction normalizeLanguage(value: string): string {\n return value.trim().toLowerCase();\n}\n\nexport class ChatCodeSyntaxHighlighter {\n private readonly engine: HLJSApi;\n\n constructor() {\n this.engine = hljs.newInstance();\n REGISTERED_LANGUAGES.forEach((entry) => {\n this.engine.registerLanguage(entry.name, entry.language);\n if (entry.aliases) {\n this.engine.registerAliases(entry.aliases, { languageName: entry.name });\n }\n });\n }\n\n highlight = (code: string, language: string): ChatCodeHighlightResult => {\n const normalizedLanguage = normalizeLanguage(language);\n if (!code || PLAIN_TEXT_LANGUAGES.has(normalizedLanguage)) {\n return this.createPlainTextResult(code, normalizedLanguage || 'text');\n }\n\n if (this.engine.getLanguage(normalizedLanguage)) {\n const result = this.engine.highlight(code, {\n language: normalizedLanguage,\n ignoreIllegals: true,\n });\n return {\n html: result.value,\n language: result.language ?? normalizedLanguage,\n highlighted: true,\n };\n }\n\n const autoDetected = this.engine.highlightAuto(code, AUTO_DETECT_LANGUAGES);\n if (autoDetected.language && autoDetected.relevance >= AUTO_DETECT_MIN_RELEVANCE) {\n return {\n html: autoDetected.value,\n language: autoDetected.language,\n highlighted: true,\n };\n }\n\n return this.createPlainTextResult(code, normalizedLanguage || 'text');\n };\n\n private createPlainTextResult = (code: string, language: string): ChatCodeHighlightResult => ({\n html: escapeHtml(code),\n language,\n highlighted: false,\n });\n}\n\nexport const chatCodeSyntaxHighlighter = new ChatCodeSyntaxHighlighter();\n","import { useMemo, type ReactNode } from 'react';\nimport { useCopyFeedback } from '../../hooks/use-copy-feedback';\nimport type { ChatMessageTexts } from '../../view-models/chat-ui.types';\nimport { Check, Copy } from 'lucide-react';\nimport { cn } from '../../internal/cn';\nimport { chatCodeSyntaxHighlighter } from './code-block/chat-code-syntax-highlighter';\n\nconst CODE_LANGUAGE_REGEX = /language-([a-z0-9-]+)/i;\n\nfunction flattenNodeText(value: ReactNode): string {\n if (typeof value === 'string' || typeof value === 'number') {\n return String(value);\n }\n if (Array.isArray(value)) {\n return value.map(flattenNodeText).join('');\n }\n return '';\n}\n\nfunction normalizeCodeText(value: ReactNode): string {\n const content = flattenNodeText(value);\n return content.endsWith('\\n') ? content.slice(0, -1) : content;\n}\n\nfunction resolveCodeLanguage(className?: string): string {\n const match = className ? CODE_LANGUAGE_REGEX.exec(className) : null;\n return match?.[1]?.toLowerCase() || 'text';\n}\n\ntype ChatCodeBlockProps = {\n className?: string;\n children: ReactNode;\n texts: Pick<ChatMessageTexts, 'copyCodeLabel' | 'copiedCodeLabel'>;\n};\n\nexport function ChatCodeBlock({ className, children, texts }: ChatCodeBlockProps) {\n const language = useMemo(() => resolveCodeLanguage(className), [className]);\n const codeText = useMemo(() => normalizeCodeText(children), [children]);\n const highlightedCode = useMemo(\n () => chatCodeSyntaxHighlighter.highlight(codeText, language),\n [codeText, language],\n );\n const codeClassName = useMemo(() => {\n const highlightedLanguageClass = `language-${highlightedCode.language}`;\n return cn(\n 'hljs',\n className,\n className?.includes('language-') ? undefined : highlightedLanguageClass,\n );\n }, [className, highlightedCode.language]);\n const { copied, copy } = useCopyFeedback({ text: codeText });\n\n return (\n <div className=\"chat-codeblock\">\n <div className=\"chat-codeblock-toolbar\">\n <span className=\"chat-codeblock-language\">{language}</span>\n <button\n type=\"button\"\n className=\"chat-codeblock-copy\"\n onClick={() => void copy()}\n aria-label={copied ? texts.copiedCodeLabel : texts.copyCodeLabel}\n >\n {copied ? <Check className=\"h-3.5 w-3.5\" /> : <Copy className=\"h-3.5 w-3.5\" />}\n <span>{copied ? texts.copiedCodeLabel : texts.copyCodeLabel}</span>\n </button>\n </div>\n <pre>\n <code\n className={codeClassName}\n data-highlighted={highlightedCode.highlighted ? 'true' : 'false'}\n dangerouslySetInnerHTML={{ __html: highlightedCode.html }}\n />\n </pre>\n </div>\n );\n}\n","import type {\n ChatFilePreviewViewer,\n ChatInlineDisplayTarget,\n ChatInlineDisplayViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\n\nconst INLINE_DISPLAY_LANGUAGE = \"nextclaw-inline\";\nconst CODE_LANGUAGE_REGEX = /language-([a-z0-9-]+)/i;\nconst FILE_PREVIEW_VIEWERS = new Set<ChatFilePreviewViewer>([\n \"auto\",\n \"source\",\n \"rendered\",\n]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction readPositiveInteger(value: unknown): number | undefined {\n return Number.isInteger(value) && Number(value) > 0\n ? Number(value)\n : undefined;\n}\n\nfunction readFilePreviewViewer(value: unknown): ChatFilePreviewViewer | undefined {\n const viewer = readString(value);\n return viewer && FILE_PREVIEW_VIEWERS.has(viewer as ChatFilePreviewViewer)\n ? (viewer as ChatFilePreviewViewer)\n : undefined;\n}\n\nfunction readTargetPayload(record: Record<string, unknown>): Record<string, unknown> | null {\n const { payload } = record;\n return isRecord(payload) ? payload : null;\n}\n\nfunction readFileTarget(record: Record<string, unknown>): ChatInlineDisplayTarget | null {\n const payload = readTargetPayload(record);\n if (!payload) {\n return null;\n }\n const path = readString(payload.path);\n if (!path) {\n return null;\n }\n return {\n type: \"file\",\n payload: {\n path,\n line: readPositiveInteger(payload.line),\n column: readPositiveInteger(payload.column),\n viewer: readFilePreviewViewer(payload.viewer),\n },\n };\n}\n\nfunction readUrlTarget(record: Record<string, unknown>): ChatInlineDisplayTarget | null {\n const payload = readTargetPayload(record);\n if (!payload) {\n return null;\n }\n const url = readString(payload.url);\n if (!url) {\n return null;\n }\n return {\n type: \"url\",\n payload: { url },\n };\n}\n\nfunction readPanelAppTarget(record: Record<string, unknown>): ChatInlineDisplayTarget | null {\n const payload = readTargetPayload(record);\n if (!payload) {\n return null;\n }\n const appId = readString(payload.appId);\n if (!appId) {\n return null;\n }\n return {\n type: \"panel_app\",\n payload: { appId },\n };\n}\n\nfunction readJsonTarget(record: Record<string, unknown>): ChatInlineDisplayTarget | null {\n const payload = readTargetPayload(record);\n if (!payload || !(\"value\" in payload)) {\n return null;\n }\n return {\n type: \"json\",\n payload: { value: payload.value },\n };\n}\n\nfunction readInlineDisplayTarget(value: unknown): ChatInlineDisplayTarget | null {\n if (!isRecord(value)) {\n return null;\n }\n const type = readString(value.type);\n if (type === \"file\") {\n return readFileTarget(value);\n }\n if (type === \"url\") {\n return readUrlTarget(value);\n }\n if (type === \"panel_app\") {\n return readPanelAppTarget(value);\n }\n if (type === \"json\") {\n return readJsonTarget(value);\n }\n return null;\n}\n\nexport function isChatInlineDisplayLanguage(className?: string): boolean {\n const match = className ? CODE_LANGUAGE_REGEX.exec(className) : null;\n const language = match?.[1]?.toLowerCase();\n return language === INLINE_DISPLAY_LANGUAGE;\n}\n\nexport function parseChatInlineDisplayDirective(\n rawText: string,\n): ChatInlineDisplayViewModel | null {\n const text = rawText.endsWith(\"\\n\") ? rawText.slice(0, -1) : rawText;\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return null;\n }\n if (!isRecord(parsed)) {\n return null;\n }\n const target = readInlineDisplayTarget(parsed.target);\n if (!target) {\n return null;\n }\n return {\n target,\n title: readString(parsed.title),\n description: readString(parsed.description),\n };\n}\n\nexport function getChatInlineDisplayLabel(display: ChatInlineDisplayViewModel): string {\n if (display.title) {\n return display.title;\n }\n if (display.target.type === \"file\") {\n const segments = display.target.payload.path.split(\"/\").filter(Boolean);\n return segments[segments.length - 1] ?? display.target.payload.path;\n }\n if (display.target.type === \"url\") {\n return display.target.payload.url;\n }\n if (display.target.type === \"panel_app\") {\n return display.target.payload.appId;\n }\n return \"JSON\";\n}\n\nexport function getChatInlineDisplayDetail(display: ChatInlineDisplayViewModel): string {\n if (display.target.type === \"file\") {\n return display.target.payload.path;\n }\n if (display.target.type === \"url\") {\n return display.target.payload.url;\n }\n if (display.target.type === \"panel_app\") {\n return display.target.payload.appId;\n }\n return JSON.stringify(display.target.payload.value, null, 2);\n}\n","import { AppWindow, Code2, FileText, Globe } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport type { ChatInlineDisplayViewModel } from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport {\n getChatInlineDisplayDetail,\n getChatInlineDisplayLabel,\n} from \"./utils/chat-inline-display.utils\";\n\ntype ChatInlineDisplayProps = {\n display: ChatInlineDisplayViewModel;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n};\n\nfunction ChatInlineDisplayIcon({ display }: { display: ChatInlineDisplayViewModel }) {\n const className = \"h-3.5 w-3.5 shrink-0 text-muted-foreground\";\n if (display.target.type === \"file\") {\n return <FileText className={className} aria-hidden />;\n }\n if (display.target.type === \"url\") {\n return <Globe className={className} aria-hidden />;\n }\n if (display.target.type === \"panel_app\") {\n return <AppWindow className={className} aria-hidden />;\n }\n return <Code2 className={className} aria-hidden />;\n}\n\nfunction formatJsonDetail(value: string): string {\n return value.length > 1_200 ? `${value.slice(0, 1_200)}\\n...` : value;\n}\n\nfunction ChatInlineDisplayFallback({ display }: { display: ChatInlineDisplayViewModel }) {\n const label = getChatInlineDisplayLabel(display);\n const detail = getChatInlineDisplayDetail(display);\n const formattedDetail = display.target.type === \"json\"\n ? formatJsonDetail(detail)\n : detail;\n\n return (\n <section\n className={cn(\n \"my-2 max-w-full border-l-2 border-border bg-muted/30 px-3 py-2\",\n \"text-xs leading-relaxed text-foreground\",\n )}\n data-nextclaw-inline-display=\"true\"\n data-nextclaw-inline-display-type={display.target.type}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n <ChatInlineDisplayIcon display={display} />\n <span className=\"min-w-0 truncate font-medium\">{label}</span>\n </div>\n {display.description ? (\n <p className=\"mt-1 line-clamp-2 text-[12px] text-muted-foreground\">\n {display.description}\n </p>\n ) : null}\n <pre\n className={cn(\n \"mt-1 max-h-40 overflow-auto whitespace-pre-wrap break-words\",\n \"font-mono text-[11px] leading-relaxed text-muted-foreground\",\n )}\n >\n {formattedDetail}\n </pre>\n </section>\n );\n}\n\nexport function ChatInlineDisplay({\n display,\n renderInlineDisplay,\n}: ChatInlineDisplayProps) {\n const rendered = renderInlineDisplay?.(display);\n if (rendered !== undefined && rendered !== null) {\n return <>{rendered}</>;\n }\n return <ChatInlineDisplayFallback display={display} />;\n}\n","import { useMemo, type MouseEvent, type ReactNode } from \"react\";\nimport type { Components } from \"react-markdown\";\nimport ReactMarkdown from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { ChatInlineTokenBadge } from \"./chat-inline-token-badge\";\nimport { ChatCodeBlock } from \"./chat-code-block\";\nimport { ChatInlineDisplay } from \"./chat-inline-display\";\nimport type {\n ChatFileOpenActionViewModel,\n ChatInlineDisplayViewModel,\n ChatInlineTokenViewModel,\n ChatMessageRole,\n ChatMessageTexts,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport {\n isChatInlineDisplayLanguage,\n parseChatInlineDisplayDirective,\n} from \"./utils/chat-inline-display.utils\";\n\nconst MARKDOWN_MAX_CHARS = 140_000;\nconst SAFE_LINK_PROTOCOLS = new Set([\"http:\", \"https:\", \"mailto:\", \"tel:\"]);\nconst INLINE_TOKEN_KIND_ATTR = \"data-chat-inline-token-kind\";\nconst INLINE_TOKEN_KEY_ATTR = \"data-chat-inline-token-key\";\nconst INLINE_TOKEN_LABEL_ATTR = \"data-chat-inline-token-label\";\nconst INLINE_TOKEN_RAW_TEXT_ATTR = \"data-chat-inline-token-raw-text\";\nconst PROJECT_RELATIVE_FILE_EXTENSION_PATTERN =\n \"cjs|css|cts|html?|js|json|jsx|mdx?|mjs|mts|tsx?|txt|ya?ml\";\nconst PROJECT_RELATIVE_FILE_HREF_PATTERN = new RegExp(\n `^(?![a-zA-Z][a-zA-Z\\\\d+.-]*:)(?!//)(?:(?:[^/\\\\s?#]+/)+[^?#\\\\s]+\\\\.[A-Za-z0-9_-]+|[^/\\\\s?#]+\\\\.(?:${PROJECT_RELATIVE_FILE_EXTENSION_PATTERN}))(?::\\\\d+(?::\\\\d+)?)?(?:[?#].*)?$`,\n \"i\",\n);\n\nfunction trimMarkdown(value: string): string {\n if (value.length <= MARKDOWN_MAX_CHARS) {\n return value;\n }\n return `${value.slice(0, MARKDOWN_MAX_CHARS)}\\n\\n...`;\n}\n\nfunction resolveSafeHref(href?: string): string | null {\n if (!href) {\n return null;\n }\n if (\n href.startsWith(\"#\") ||\n href.startsWith(\"/\") ||\n href.startsWith(\"./\") ||\n href.startsWith(\"../\") ||\n PROJECT_RELATIVE_FILE_HREF_PATTERN.test(href)\n ) {\n return href;\n }\n try {\n const url = new URL(href);\n return SAFE_LINK_PROTOCOLS.has(url.protocol) ? href : null;\n } catch {\n return null;\n }\n}\n\nfunction isExternalHref(href: string): boolean {\n return /^https?:\\/\\//i.test(href);\n}\n\nfunction looksLikeLocalFileHref(href: string): boolean {\n return (\n href.startsWith(\"./\") ||\n href.startsWith(\"../\") ||\n href.startsWith(\"/Users/\") ||\n href.startsWith(\"/home/\") ||\n href.startsWith(\"/tmp/\") ||\n href.startsWith(\"/var/\") ||\n PROJECT_RELATIVE_FILE_HREF_PATTERN.test(href) ||\n /^\\/.+\\.[A-Za-z0-9_-]+(?::\\d+(?::\\d+)?)?$/.test(href)\n );\n}\n\nfunction parseLocalFileAction(\n href: string,\n): ChatFileOpenActionViewModel | null {\n const viewer = new URLSearchParams(href.split(\"#\")[0]?.split(\"?\")[1] ?? \"\").get(\"viewer\");\n const normalizedHref = href.split(\"#\")[0]?.split(\"?\")[0] ?? href;\n const decodedHref = decodeURIComponent(normalizedHref);\n if (!looksLikeLocalFileHref(decodedHref)) {\n return null;\n }\n const lineMatch = /^(.*?)(?::(\\d+)(?::(\\d+))?)$/.exec(decodedHref);\n const rawPath = lineMatch?.[1] ?? decodedHref;\n const line = lineMatch?.[2] ? Number(lineMatch[2]) : undefined;\n const column = lineMatch?.[3] ? Number(lineMatch[3]) : undefined;\n return {\n path: rawPath,\n label: rawPath.split(\"/\").filter(Boolean).pop() ?? rawPath,\n viewMode: \"preview\",\n ...(viewer === \"source\" || viewer === \"rendered\" ? { previewViewer: viewer } : {}),\n ...(typeof line === \"number\" ? { line } : {}),\n ...(typeof column === \"number\" ? { column } : {}),\n };\n}\n\ntype ChatMessageMarkdownProps = {\n text: string;\n role: ChatMessageRole;\n texts: Pick<ChatMessageTexts, \"copyCodeLabel\" | \"copiedCodeLabel\">;\n inline?: boolean;\n inlineTokens?: readonly ChatInlineTokenViewModel[];\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n onInlineTokenClick?: (token: ChatInlineTokenViewModel) => void;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n};\n\ntype MarkdownNode = {\n type?: string;\n value?: string;\n children?: MarkdownNode[];\n data?: {\n hName?: string;\n hProperties?: Record<string, string>;\n hChildren?: Array<{ type: \"text\"; value: string }>;\n };\n};\n\nfunction prepareInlineTokens(\n inlineTokens: readonly ChatInlineTokenViewModel[] | undefined,\n): ChatInlineTokenViewModel[] {\n if (!inlineTokens || inlineTokens.length === 0) {\n return [];\n }\n const seenRawTexts = new Set<string>();\n const tokens: ChatInlineTokenViewModel[] = [];\n for (const token of inlineTokens) {\n if (!token.rawText || seenRawTexts.has(token.rawText)) {\n continue;\n }\n seenRawTexts.add(token.rawText);\n tokens.push(token);\n }\n return tokens.sort((left, right) => right.rawText.length - left.rawText.length);\n}\n\nfunction createInlineTokenNode(token: ChatInlineTokenViewModel): MarkdownNode {\n return {\n type: \"chatInlineToken\",\n data: {\n hName: \"span\",\n hProperties: {\n [INLINE_TOKEN_KIND_ATTR]: token.kind,\n [INLINE_TOKEN_KEY_ATTR]: token.key,\n [INLINE_TOKEN_LABEL_ATTR]: token.label,\n [INLINE_TOKEN_RAW_TEXT_ATTR]: token.rawText,\n },\n hChildren: [{ type: \"text\", value: token.label }],\n },\n };\n}\n\nfunction findNextInlineToken(\n value: string,\n cursor: number,\n tokens: readonly ChatInlineTokenViewModel[],\n): { index: number; token: ChatInlineTokenViewModel } | null {\n let next: { index: number; token: ChatInlineTokenViewModel } | null = null;\n for (const token of tokens) {\n const index = value.indexOf(token.rawText, cursor);\n if (index < 0) {\n continue;\n }\n if (\n !next ||\n index < next.index ||\n (index === next.index && token.rawText.length > next.token.rawText.length)\n ) {\n next = { index, token };\n }\n }\n return next;\n}\n\nfunction splitTextNodeByInlineTokens(\n value: string,\n tokens: readonly ChatInlineTokenViewModel[],\n): MarkdownNode[] {\n const output: MarkdownNode[] = [];\n let cursor = 0;\n\n while (cursor < value.length) {\n const next = findNextInlineToken(value, cursor, tokens);\n if (!next) {\n output.push({ type: \"text\", value: value.slice(cursor) });\n break;\n }\n if (next.index > cursor) {\n output.push({ type: \"text\", value: value.slice(cursor, next.index) });\n }\n output.push(createInlineTokenNode(next.token));\n cursor = next.index + next.token.rawText.length;\n }\n\n return output.length > 0 ? output : [{ type: \"text\", value }];\n}\n\nfunction transformInlineTokenTextNodes(\n node: MarkdownNode,\n tokens: readonly ChatInlineTokenViewModel[],\n): void {\n if (node.type === \"code\" || node.type === \"inlineCode\" || !node.children) {\n return;\n }\n\n const nextChildren: MarkdownNode[] = [];\n for (const child of node.children) {\n if (child.type === \"text\" && typeof child.value === \"string\") {\n nextChildren.push(...splitTextNodeByInlineTokens(child.value, tokens));\n continue;\n }\n transformInlineTokenTextNodes(child, tokens);\n nextChildren.push(child);\n }\n node.children = nextChildren;\n}\n\nfunction createRemarkInlineTokenPlugin(\n inlineTokens: readonly ChatInlineTokenViewModel[],\n) {\n const tokens = prepareInlineTokens(inlineTokens);\n return () => (tree: MarkdownNode) => {\n if (tokens.length === 0) {\n return;\n }\n transformInlineTokenTextNodes(tree, tokens);\n };\n}\n\nfunction readStringProp(props: Record<string, unknown>, key: string): string | null {\n const value = props[key];\n return typeof value === \"string\" && value.length > 0 ? value : null;\n}\n\nexport function ChatMessageMarkdown({\n text,\n role,\n texts,\n inline = false,\n inlineTokens,\n onFileOpen,\n onInlineTokenClick,\n renderInlineDisplay,\n}: ChatMessageMarkdownProps) {\n const isUser = role === \"user\";\n const remarkPlugins = useMemo(\n () =>\n inlineTokens && inlineTokens.length > 0\n ? [remarkGfm, createRemarkInlineTokenPlugin(inlineTokens)]\n : [remarkGfm],\n [inlineTokens],\n );\n const markdownComponents = useMemo<Components>(\n () => ({\n p: ({ children }) => (inline ? <>{children}</> : <p>{children}</p>),\n span: ({ node: _node, children, ...rest }) => {\n const restProps = rest as Record<string, unknown>;\n const kind = readStringProp(restProps, INLINE_TOKEN_KIND_ATTR);\n const key = readStringProp(restProps, INLINE_TOKEN_KEY_ATTR);\n const label = readStringProp(restProps, INLINE_TOKEN_LABEL_ATTR);\n const rawText = readStringProp(restProps, INLINE_TOKEN_RAW_TEXT_ATTR);\n if (kind && key && label && rawText) {\n return (\n <ChatInlineTokenBadge\n kind={kind}\n label={label}\n isUser={isUser}\n onClick={\n onInlineTokenClick\n ? () => onInlineTokenClick({ kind, key, label, rawText })\n : undefined\n }\n />\n );\n }\n return <span {...rest}>{children}</span>;\n },\n a: ({ node: _node, href, children, ...rest }) => {\n const safeHref = resolveSafeHref(href);\n if (!safeHref) {\n return <span className=\"chat-link-invalid\">{children}</span>;\n }\n const external = isExternalHref(safeHref);\n const localFileAction = external\n ? null\n : parseLocalFileAction(safeHref);\n const handleClick = (event: MouseEvent<HTMLAnchorElement>) => {\n if (!onFileOpen || !localFileAction) {\n return;\n }\n if (\n event.defaultPrevented ||\n event.button !== 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n ) {\n return;\n }\n event.preventDefault();\n onFileOpen(localFileAction);\n };\n return (\n <a\n {...rest}\n href={safeHref}\n onClick={handleClick}\n target={external ? \"_blank\" : undefined}\n rel={external ? \"noreferrer noopener\" : undefined}\n >\n {children}\n </a>\n );\n },\n table: ({ node: _node, children, ...rest }) => (\n <div className=\"chat-table-wrap\">\n <table {...rest}>{children}</table>\n </div>\n ),\n input: ({ node: _node, type, checked, ...rest }) => {\n if (type !== \"checkbox\") {\n return <input {...rest} type={type} />;\n }\n return (\n <input\n {...rest}\n type=\"checkbox\"\n checked={checked}\n readOnly\n disabled\n className=\"chat-task-checkbox\"\n />\n );\n },\n img: ({ node: _node, src, alt, ...rest }) => {\n const safeSrc = resolveSafeHref(src);\n if (!safeSrc) {\n return null;\n }\n return (\n <img\n {...rest}\n src={safeSrc}\n alt={alt || \"\"}\n loading=\"lazy\"\n decoding=\"async\"\n />\n );\n },\n code: ({ node: _node, className, children, ...rest }) => {\n const plainText = String(children ?? \"\");\n const isInlineCode = !className && !plainText.includes(\"\\n\");\n if (isInlineCode) {\n return (\n <code {...rest} className={cn(\"chat-inline-code\", className)}>\n {children}\n </code>\n );\n }\n const inlineDisplay = isChatInlineDisplayLanguage(className)\n ? parseChatInlineDisplayDirective(plainText)\n : null;\n if (inlineDisplay) {\n return (\n <ChatInlineDisplay\n display={inlineDisplay}\n renderInlineDisplay={renderInlineDisplay}\n />\n );\n }\n return (\n <ChatCodeBlock className={className} texts={texts}>\n {children as ReactNode}\n </ChatCodeBlock>\n );\n },\n }),\n [inline, isUser, onFileOpen, onInlineTokenClick, renderInlineDisplay, texts],\n );\n\n const WrapperTag = inline ? \"span\" : \"div\";\n\n return (\n <WrapperTag\n className={cn(\n \"chat-markdown\",\n isUser ? \"chat-markdown-user\" : \"chat-markdown-assistant\",\n )}\n >\n <ReactMarkdown\n skipHtml\n remarkPlugins={remarkPlugins}\n components={markdownComponents}\n >\n {trimMarkdown(text)}\n </ReactMarkdown>\n </WrapperTag>\n );\n}\n","import type {\n ChatAttachmentCategory,\n ChatMessagePartViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\n\nexport type ChatMessageFileView = Extract<\n ChatMessagePartViewModel,\n { type: \"file\" }\n>[\"file\"];\n\nexport type FileCategory = ChatAttachmentCategory;\n\nexport const FILE_CATEGORY_TILE_CLASSES: Record<FileCategory, string> = {\n archive: \"bg-muted text-muted-foreground\",\n audio: \"bg-muted text-muted-foreground\",\n code: \"bg-muted text-muted-foreground\",\n data: \"bg-muted text-muted-foreground\",\n document: \"bg-muted text-muted-foreground\",\n generic: \"bg-muted text-muted-foreground\",\n image: \"bg-muted text-muted-foreground\",\n pdf: \"bg-muted text-muted-foreground\",\n sheet: \"bg-muted text-muted-foreground\",\n video: \"bg-muted text-muted-foreground\",\n};\n\nconst CODE_EXTENSIONS = new Set([\n \"c\",\n \"cpp\",\n \"css\",\n \"go\",\n \"html\",\n \"java\",\n \"js\",\n \"jsx\",\n \"md\",\n \"php\",\n \"py\",\n \"rb\",\n \"rs\",\n \"sh\",\n \"sql\",\n \"svg\",\n \"ts\",\n \"tsx\",\n]);\n\nconst DATA_EXTENSIONS = new Set([\n \"graphql\",\n \"json\",\n \"toml\",\n \"xml\",\n \"yaml\",\n \"yml\",\n]);\nconst IMAGE_EXTENSIONS = new Set([\n \"avif\",\n \"bmp\",\n \"gif\",\n \"heic\",\n \"heif\",\n \"ico\",\n \"jpeg\",\n \"jpg\",\n \"png\",\n \"svg\",\n \"tif\",\n \"tiff\",\n \"webp\",\n]);\nconst AUDIO_EXTENSIONS = new Set([\n \"aac\",\n \"flac\",\n \"m4a\",\n \"mp3\",\n \"ogg\",\n \"opus\",\n \"wav\",\n \"weba\",\n]);\nconst VIDEO_EXTENSIONS = new Set([\n \"avi\",\n \"m4v\",\n \"mov\",\n \"mp4\",\n \"mkv\",\n \"webm\",\n \"wmv\",\n]);\nconst DOCUMENT_EXTENSIONS = new Set([\n \"doc\",\n \"docx\",\n \"odt\",\n \"pages\",\n \"rtf\",\n \"txt\",\n]);\nconst SHEET_EXTENSIONS = new Set([\n \"csv\",\n \"numbers\",\n \"ods\",\n \"tsv\",\n \"xls\",\n \"xlsx\",\n]);\nconst ARCHIVE_EXTENSIONS = new Set([\n \"7z\",\n \"bz2\",\n \"gz\",\n \"rar\",\n \"tar\",\n \"tgz\",\n \"zip\",\n]);\n\nfunction formatFileSize(sizeBytes?: number): string | null {\n if (!Number.isFinite(sizeBytes) || sizeBytes == null || sizeBytes < 0) {\n return null;\n }\n if (sizeBytes === 0) {\n return \"0 B\";\n }\n const units = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\"];\n let value = sizeBytes;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n const digits = value >= 10 || unitIndex === 0 ? 0 : 1;\n return `${value.toFixed(digits).replace(/\\.0$/, \"\")} ${units[unitIndex]}`;\n}\n\nfunction getFileExtension(label: string, mimeType: string): string {\n const extension = readFileExtension(label);\n if (extension) {\n return extension.toUpperCase();\n }\n const subtype = mimeType.split(\"/\")[1] ?? \"\";\n const cleaned = subtype.split(/[+.;-]/)[0]?.trim();\n if (!cleaned) {\n return \"FILE\";\n }\n return cleaned.slice(0, 6).toUpperCase();\n}\n\nfunction readFileExtension(label: string): string {\n return /\\.([a-z0-9]{1,12})$/i.exec(label.trim())?.[1]?.toLowerCase() ?? \"\";\n}\n\nfunction truncateDisplayCode(value: string): string {\n return value.trim().slice(0, 4).toUpperCase();\n}\n\nfunction isImageDataUrl(dataUrl?: string): boolean {\n return typeof dataUrl === \"string\" && /^data:image\\//i.test(dataUrl.trim());\n}\n\nfunction inferMimeTypeFromExtension(extension: string): string | null {\n if (IMAGE_EXTENSIONS.has(extension)) {\n if (extension === \"jpg\" || extension === \"jpeg\") {\n return \"image/jpeg\";\n }\n if (extension === \"svg\") {\n return \"image/svg+xml\";\n }\n return `image/${extension}`;\n }\n if (AUDIO_EXTENSIONS.has(extension)) {\n if (extension === \"mp3\") {\n return \"audio/mpeg\";\n }\n if (extension === \"m4a\") {\n return \"audio/mp4\";\n }\n if (extension === \"weba\") {\n return \"audio/webm\";\n }\n return `audio/${extension}`;\n }\n if (VIDEO_EXTENSIONS.has(extension)) {\n if (extension === \"mov\") {\n return \"video/quicktime\";\n }\n if (extension === \"m4v\") {\n return \"video/mp4\";\n }\n return `video/${extension}`;\n }\n if (extension === \"pdf\") {\n return \"application/pdf\";\n }\n return null;\n}\n\nexport function inferMimeTypeFromFileName(fileName: string): string | null {\n const extension = readFileExtension(fileName);\n if (!extension) {\n return null;\n }\n return inferMimeTypeFromExtension(extension);\n}\n\nexport function resolveRenderableMimeType(file: ChatMessageFileView): string | null {\n const normalizedMimeType = file.mimeType.trim().toLowerCase();\n if (\n normalizedMimeType.length > 0 &&\n normalizedMimeType !== \"application/octet-stream\"\n ) {\n return normalizedMimeType;\n }\n return inferMimeTypeFromFileName(file.label);\n}\n\nexport function isImageFileLike(file: ChatMessageFileView): boolean {\n const normalizedMimeType = file.mimeType.trim().toLowerCase();\n const extension = readFileExtension(file.label);\n return (\n file.isImage ||\n normalizedMimeType.startsWith(\"image/\") ||\n IMAGE_EXTENSIONS.has(extension) ||\n isImageDataUrl(file.dataUrl)\n );\n}\n\nfunction resolveFileCategory(label: string, mimeType: string): FileCategory {\n const extension = readFileExtension(label);\n const normalizedMimeType = mimeType.toLowerCase();\n\n if (normalizedMimeType.startsWith(\"image/\") || IMAGE_EXTENSIONS.has(extension)) {\n return \"image\";\n }\n if (normalizedMimeType.startsWith(\"audio/\") || AUDIO_EXTENSIONS.has(extension)) {\n return \"audio\";\n }\n if (normalizedMimeType.startsWith(\"video/\") || VIDEO_EXTENSIONS.has(extension)) {\n return \"video\";\n }\n if (normalizedMimeType.includes(\"pdf\") || extension === \"pdf\") {\n return \"pdf\";\n }\n if (\n ARCHIVE_EXTENSIONS.has(extension) ||\n /(zip|tar|gzip|rar|compressed|archive)/.test(normalizedMimeType)\n ) {\n return \"archive\";\n }\n if (\n SHEET_EXTENSIONS.has(extension) ||\n /(spreadsheet|sheet|excel|csv)/.test(normalizedMimeType)\n ) {\n return \"sheet\";\n }\n if (\n DATA_EXTENSIONS.has(extension) ||\n /(json|xml|yaml|toml)/.test(normalizedMimeType)\n ) {\n return \"data\";\n }\n if (\n CODE_EXTENSIONS.has(extension) ||\n /(javascript|typescript|jsx|tsx|css|html)/.test(normalizedMimeType)\n ) {\n return \"code\";\n }\n if (\n DOCUMENT_EXTENSIONS.has(extension) ||\n /(msword|document|opendocument|rtf|text\\/)/.test(normalizedMimeType)\n ) {\n return \"document\";\n }\n return \"generic\";\n}\n\nexport function buildChatMessageFileMeta(file: ChatMessageFileView): {\n category: FileCategory;\n extension: string;\n sizeLabel: string | null;\n} {\n const category = resolveFileCategory(file.label, file.mimeType);\n const sizeLabel = formatFileSize(file.sizeBytes);\n return {\n category,\n extension: getFileExtension(file.label, file.mimeType),\n sizeLabel,\n };\n}\n\nexport function getFileCategoryDisplayCode(\n category: FileCategory,\n extension: string,\n): string {\n if (category === \"image\") {\n return \"IMG\";\n }\n if (category === \"video\") {\n return \"VID\";\n }\n if (category === \"audio\") {\n return \"AUD\";\n }\n if (category === \"generic\") {\n return truncateDisplayCode(extension || \"FILE\");\n }\n return truncateDisplayCode(extension);\n}\n","import { useEffect, useId, useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport {\n Expand,\n File,\n FileArchive,\n FileAudio2,\n FileCode2,\n FileImage,\n FileJson2,\n FileSpreadsheet,\n FileText,\n FileVideo2,\n X,\n} from \"lucide-react\";\nimport {\n buildChatMessageFileMeta,\n FILE_CATEGORY_TILE_CLASSES,\n isImageFileLike,\n resolveRenderableMimeType,\n type FileCategory,\n type ChatMessageFileView,\n} from \"./meta\";\nimport type { ChatMessageTexts } from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\n\ntype ChatMessageFileProps = {\n file: ChatMessageFileView;\n isUser?: boolean;\n texts?: Pick<\n ChatMessageTexts,\n | \"attachmentOpenLabel\"\n | \"attachmentAttachedLabel\"\n | \"attachmentExpandLabel\"\n | \"attachmentCloseLabel\"\n | \"attachmentCategoryLabels\"\n >;\n onOpen?: (file: ChatMessageFileView) => void;\n};\n\nconst DEFAULT_FILE_CATEGORY_LABELS: Record<FileCategory, string> = {\n archive: \"Archive\",\n audio: \"Audio\",\n code: \"Code file\",\n data: \"Data file\",\n document: \"Document\",\n generic: \"File\",\n image: \"Image\",\n pdf: \"PDF document\",\n sheet: \"Spreadsheet\",\n video: \"Video\",\n};\n\nconst FILE_CATEGORY_ICONS: Record<FileCategory, typeof File> = {\n archive: FileArchive,\n audio: FileAudio2,\n code: FileCode2,\n data: FileJson2,\n document: FileText,\n generic: File,\n image: FileImage,\n pdf: FileText,\n sheet: FileSpreadsheet,\n video: FileVideo2,\n};\n\nfunction readFileCategoryLabel(\n category: FileCategory,\n texts?: ChatMessageFileProps[\"texts\"],\n): string {\n return (\n texts?.attachmentCategoryLabels?.[category] ??\n DEFAULT_FILE_CATEGORY_LABELS[category]\n );\n}\n\nfunction renderMetaLine(\n categoryLabel: string,\n sizeLabel: string | null,\n isUser: boolean,\n) {\n return (\n <div\n className={cn(\n \"mt-0.5 text-[11px] leading-4\",\n isUser ? \"text-foreground/55\" : \"text-muted-foreground\",\n )}\n >\n {sizeLabel ? `${categoryLabel} · ${sizeLabel}` : categoryLabel}\n </div>\n );\n}\n\nfunction renderActionPill(\n label: string,\n isUser: boolean,\n isInteractive: boolean,\n) {\n return (\n <span\n className={cn(\n \"inline-flex items-center rounded-md px-2 py-0.5 text-[11px] font-medium\",\n isInteractive\n ? isUser\n ? \"bg-black/5 text-foreground/75\"\n : \"bg-muted text-muted-foreground\"\n : isUser\n ? \"bg-black/[0.03] text-foreground/45\"\n : \"bg-muted/70 text-muted-foreground/70\",\n )}\n >\n {label}\n </span>\n );\n}\n\nfunction renderActionControl(params: {\n label: string;\n href?: string;\n isUser: boolean;\n onOpen?: () => void;\n}) {\n const { label, href, isUser, onOpen } = params;\n const className = cn(\n \"inline-flex items-center rounded-md px-2 py-0.5 text-[11px] font-medium transition-colors\",\n isUser\n ? \"bg-black/5 text-foreground/75 hover:bg-black/10 hover:text-foreground\"\n : \"bg-muted text-muted-foreground hover:bg-accent hover:text-foreground\",\n );\n\n if (onOpen) {\n return (\n <button\n type=\"button\"\n className={className}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onOpen();\n }}\n >\n {label}\n </button>\n );\n }\n\n if (!href) {\n return renderActionPill(label, isUser, false);\n }\n\n return (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n className={className}\n >\n {label}\n </a>\n );\n}\n\nfunction FileCategoryGlyph({\n category,\n isUser,\n}: {\n category: FileCategory;\n isUser: boolean;\n}) {\n const Icon = FILE_CATEGORY_ICONS[category];\n\n return (\n <div\n className={cn(\n \"flex h-9 w-9 shrink-0 items-center justify-center rounded-lg\",\n isUser\n ? \"bg-black/5 text-foreground/70\"\n : FILE_CATEGORY_TILE_CLASSES[category],\n )}\n >\n <Icon\n className={cn(\n \"h-4 w-4\",\n isUser ? \"text-foreground/70\" : \"text-current\",\n )}\n strokeWidth={2}\n />\n </div>\n );\n}\n\nfunction ChatMessageImageLightbox({\n alt,\n closeLabel,\n onClose,\n src,\n}: {\n alt: string;\n closeLabel: string;\n onClose: () => void;\n src: string;\n}) {\n const titleId = useId();\n\n useEffect(() => {\n const previousOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n onClose();\n }\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => {\n document.body.style.overflow = previousOverflow;\n window.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [onClose]);\n\n return createPortal(\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n className=\"fixed inset-0 z-[var(--z-modal,10050)] flex items-center justify-center bg-black/80 p-4 backdrop-blur-[2px]\"\n data-testid=\"chat-message-image-lightbox\"\n onClick={onClose}\n >\n <span id={titleId} className=\"sr-only\">\n {alt}\n </span>\n <button\n type=\"button\"\n aria-label={closeLabel}\n className=\"absolute right-4 top-4 inline-flex h-9 w-9 items-center justify-center rounded-full bg-black/55 text-white transition-colors hover:bg-black/70 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-white/70\"\n onClick={(event) => {\n event.stopPropagation();\n onClose();\n }}\n >\n <X className=\"h-4 w-4\" strokeWidth={2} />\n </button>\n <img\n src={src}\n alt={alt}\n className=\"max-h-[min(92vh,100%)] max-w-[min(96vw,100%)] object-contain shadow-2xl\"\n onClick={(event) => event.stopPropagation()}\n />\n </div>,\n document.body,\n );\n}\n\nfunction ChatMessageImagePreview({\n expandLabel,\n closeLabel,\n file,\n sizeLabel,\n}: {\n expandLabel: string;\n closeLabel: string;\n file: ChatMessageFileView;\n sizeLabel: string | null;\n}) {\n const [isExpanded, setIsExpanded] = useState(false);\n if (!file.dataUrl) {\n return null;\n }\n\n const openLightbox = () => setIsExpanded(true);\n\n return (\n <>\n <div className=\"group/image relative w-fit max-w-full overflow-hidden rounded-xl\">\n <button\n type=\"button\"\n className=\"block w-fit max-w-full text-left focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-border\"\n onClick={openLightbox}\n onDoubleClick={(event) => {\n event.preventDefault();\n openLightbox();\n }}\n aria-label={expandLabel}\n >\n <img\n src={file.dataUrl}\n alt={file.label}\n className=\"block h-auto max-h-[26rem] max-w-full rounded-xl bg-transparent object-contain\"\n />\n </button>\n <button\n type=\"button\"\n aria-label={expandLabel}\n className=\"absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-md bg-black/45 text-white opacity-0 transition-opacity duration-150 hover:bg-black/60 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-white/70 group-hover/image:opacity-100\"\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n openLightbox();\n }}\n >\n <Expand className=\"h-3.5 w-3.5\" strokeWidth={2} />\n </button>\n {sizeLabel ? (\n <div className=\"pointer-events-none absolute inset-x-0 bottom-0 flex items-end justify-start bg-gradient-to-t from-black/50 via-black/15 to-transparent px-2.5 pb-2 pt-8 opacity-0 transition-opacity duration-150 group-hover/image:opacity-100 group-focus-within/image:opacity-100\">\n <span className=\"inline-flex items-center rounded-md bg-black/40 px-1.5 py-0.5 text-[10px] font-medium text-white/95 backdrop-blur-sm\">\n {sizeLabel}\n </span>\n </div>\n ) : null}\n </div>\n {isExpanded ? (\n <ChatMessageImageLightbox\n alt={file.label}\n closeLabel={closeLabel}\n onClose={() => setIsExpanded(false)}\n src={file.dataUrl}\n />\n ) : null}\n </>\n );\n}\n\nfunction renderFileCardHeader(params: {\n category: FileCategory;\n file: ChatMessageFileView;\n categoryLabel: string;\n sizeLabel: string | null;\n isUser: boolean;\n action: ReactNode;\n}) {\n const { category, file, categoryLabel, sizeLabel, isUser, action } = params;\n return (\n <div className=\"flex items-center gap-2.5 px-2.5 py-2\">\n <FileCategoryGlyph\n category={category}\n isUser={isUser}\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate text-[13px] font-medium leading-5\">\n {file.label}\n </div>\n {renderMetaLine(categoryLabel, sizeLabel, isUser)}\n </div>\n {action}\n </div>\n </div>\n </div>\n );\n}\n\nfunction renderInlineMediaCard(params: {\n category: FileCategory;\n file: ChatMessageFileView;\n categoryLabel: string;\n sizeLabel: string | null;\n isUser: boolean;\n shellClasses: string;\n actionLabel: string;\n onOpen?: (file: ChatMessageFileView) => void;\n}) {\n const {\n category,\n file,\n categoryLabel,\n sizeLabel,\n isUser,\n shellClasses,\n actionLabel,\n onOpen,\n } = params;\n if (!file.dataUrl || (category !== \"audio\" && category !== \"video\")) {\n return null;\n }\n const mediaMimeType = resolveRenderableMimeType(file);\n return (\n <div className={shellClasses}>\n {renderFileCardHeader({\n category,\n file,\n categoryLabel,\n sizeLabel,\n isUser,\n action: renderActionControl({\n label: actionLabel,\n href: file.dataUrl,\n isUser,\n onOpen: onOpen ? () => onOpen(file) : undefined,\n }),\n })}\n <div className=\"px-2.5 pb-2.5\">\n {category === \"audio\" ? (\n <audio\n controls\n preload=\"metadata\"\n aria-label={file.label}\n className=\"block w-full\"\n >\n <source\n src={file.dataUrl}\n {...(mediaMimeType ? { type: mediaMimeType } : {})}\n />\n </audio>\n ) : (\n <div\n className={cn(\n \"overflow-hidden rounded-lg\",\n isUser\n ? \"bg-black/10\"\n : \"bg-muted ring-1 ring-border/70\",\n )}\n >\n <video\n controls\n preload=\"metadata\"\n playsInline\n aria-label={file.label}\n className=\"block max-h-[28rem] w-full bg-black\"\n >\n <source\n src={file.dataUrl}\n {...(mediaMimeType ? { type: mediaMimeType } : {})}\n />\n </video>\n </div>\n )}\n </div>\n </div>\n );\n}\n\nexport function ChatMessageFile({\n file,\n isUser = false,\n texts,\n onOpen,\n}: ChatMessageFileProps) {\n const { category, sizeLabel } = buildChatMessageFileMeta(file);\n const renderAsImage = isImageFileLike(file) && Boolean(file.dataUrl);\n const renderAsAudio = category === \"audio\" && Boolean(file.dataUrl);\n const renderAsVideo = category === \"video\" && Boolean(file.dataUrl);\n const isInteractive = Boolean(file.dataUrl);\n const actionLabel = isInteractive\n ? texts?.attachmentOpenLabel ?? \"Open\"\n : texts?.attachmentAttachedLabel ?? \"Attached\";\n const expandLabel = texts?.attachmentExpandLabel ?? \"Expand image\";\n const closeLabel = texts?.attachmentCloseLabel ?? \"Close preview\";\n const categoryLabel = readFileCategoryLabel(category, texts);\n const shellClasses = cn(\n \"block overflow-hidden rounded-xl border transition-colors\",\n isUser\n ? \"border-black/8 bg-black/[0.03] text-foreground\"\n : \"border-border/70 bg-card text-card-foreground\",\n isInteractive &&\n (isUser\n ? \"hover:bg-black/[0.05]\"\n : \"hover:bg-muted/50\"),\n );\n\n if (renderAsImage) {\n return (\n <ChatMessageImagePreview\n expandLabel={expandLabel}\n closeLabel={closeLabel}\n file={file}\n sizeLabel={sizeLabel}\n />\n );\n }\n\n if (renderAsAudio || renderAsVideo) {\n return renderInlineMediaCard({\n category,\n file,\n categoryLabel,\n sizeLabel,\n isUser,\n shellClasses,\n actionLabel,\n onOpen,\n });\n }\n\n const content = renderFileCardHeader({\n category,\n file,\n categoryLabel,\n sizeLabel,\n isUser,\n action: renderActionPill(actionLabel, isUser, isInteractive),\n });\n\n if (!isInteractive || !file.dataUrl) {\n return <div className={shellClasses}>{content}</div>;\n }\n\n if (onOpen) {\n return (\n <button\n type=\"button\"\n className={cn(shellClasses, \"group w-full text-left\")}\n onClick={() => onOpen(file)}\n >\n {content}\n </button>\n );\n }\n\n return (\n <a\n href={file.dataUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className={cn(shellClasses, \"group\")}\n >\n {content}\n </a>\n );\n}\n","import { useEffect, useRef, useState, type MouseEvent } from \"react\";\n\ntype UseReasoningBlockOpenStateParams = {\n isInProgress: boolean;\n};\n\ntype UseReasoningBlockOpenStateResult = {\n isOpen: boolean;\n onSummaryClick: (event: MouseEvent<HTMLElement>) => void;\n};\n\nexport function useReasoningBlockOpenState(\n params: UseReasoningBlockOpenStateParams,\n): UseReasoningBlockOpenStateResult {\n const { isInProgress } = params;\n const [isOpen, setIsOpen] = useState(isInProgress);\n const [keepOpenAfterCompletion, setKeepOpenAfterCompletion] = useState(false);\n const previousInProgressRef = useRef(isInProgress);\n\n useEffect(() => {\n const wasInProgress = previousInProgressRef.current;\n if (!wasInProgress && isInProgress) {\n setIsOpen(true);\n setKeepOpenAfterCompletion(false);\n } else if (wasInProgress && !isInProgress && !keepOpenAfterCompletion) {\n setIsOpen(false);\n }\n previousInProgressRef.current = isInProgress;\n }, [isInProgress, keepOpenAfterCompletion]);\n\n function onSummaryClick(event: MouseEvent<HTMLElement>) {\n event.preventDefault();\n const nextOpen = !isOpen;\n setIsOpen(nextOpen);\n\n if (!nextOpen) {\n setKeepOpenAfterCompletion(false);\n return;\n }\n\n if (isInProgress) {\n setKeepOpenAfterCompletion(true);\n }\n }\n\n return {\n isOpen,\n onSummaryClick,\n };\n}\n","import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type RefObject,\n} from \"react\";\n\ntype UseStickyBottomScrollParams = {\n scrollRef: RefObject<HTMLElement>;\n resetKey: string | null;\n isLoading: boolean;\n hasContent: boolean;\n contentVersion: unknown;\n stickyThresholdPx?: number;\n};\n\ntype UseStickyBottomScrollResult = {\n isAtBottom: boolean;\n onScroll: () => void;\n scrollToBottom: () => void;\n};\n\nconst DEFAULT_STICKY_THRESHOLD_PX = 10;\n\nexport function useStickyBottomScroll({\n contentVersion,\n hasContent,\n isLoading,\n resetKey,\n scrollRef,\n stickyThresholdPx,\n}: UseStickyBottomScrollParams): UseStickyBottomScrollResult {\n const [isAtBottom, setIsAtBottom] = useState(true);\n const isStickyRef = useRef(true);\n const isProgrammaticScrollRef = useRef(false);\n const previousResetKeyRef = useRef<string | null>(null);\n const pendingInitialScrollRef = useRef(false);\n const scheduledScrollFrameRef = useRef<number | null>(null);\n\n const updateStickyState = useCallback((nextIsAtBottom: boolean) => {\n isStickyRef.current = nextIsAtBottom;\n setIsAtBottom(nextIsAtBottom);\n }, []);\n\n const resolveIsAtBottom = useCallback(\n (element: HTMLElement): boolean => {\n const distanceFromBottom =\n element.scrollHeight - element.scrollTop - element.clientHeight;\n return (\n distanceFromBottom <=\n (stickyThresholdPx ?? DEFAULT_STICKY_THRESHOLD_PX)\n );\n },\n [stickyThresholdPx],\n );\n\n const queueScrollToBottom = useCallback((behavior: ScrollBehavior = \"auto\") => {\n const element = scrollRef.current;\n if (!element) {\n return;\n }\n\n if (scheduledScrollFrameRef.current !== null) {\n cancelAnimationFrame(scheduledScrollFrameRef.current);\n }\n\n scheduledScrollFrameRef.current = requestAnimationFrame(() => {\n scheduledScrollFrameRef.current = null;\n const currentElement = scrollRef.current;\n if (!currentElement) {\n return;\n }\n\n isProgrammaticScrollRef.current = true;\n if (typeof currentElement.scrollTo === \"function\") {\n currentElement.scrollTo({\n top: currentElement.scrollHeight,\n behavior,\n });\n } else {\n currentElement.scrollTop = currentElement.scrollHeight;\n }\n });\n }, [scrollRef]);\n\n const scrollToBottom = useCallback(() => {\n updateStickyState(true);\n queueScrollToBottom();\n }, [queueScrollToBottom, updateStickyState]);\n\n const onScroll = useCallback(() => {\n if (isProgrammaticScrollRef.current) {\n isProgrammaticScrollRef.current = false;\n return;\n }\n\n const element = scrollRef.current;\n if (!element) {\n return;\n }\n\n updateStickyState(resolveIsAtBottom(element));\n }, [resolveIsAtBottom, scrollRef, updateStickyState]);\n\n useEffect(() => {\n if (previousResetKeyRef.current === resetKey) {\n return;\n }\n\n previousResetKeyRef.current = resetKey;\n updateStickyState(true);\n pendingInitialScrollRef.current = true;\n }, [resetKey, updateStickyState]);\n\n useEffect(() => {\n return () => {\n const scheduledScrollFrame = scheduledScrollFrameRef.current;\n if (scheduledScrollFrame !== null) {\n cancelAnimationFrame(scheduledScrollFrame);\n scheduledScrollFrameRef.current = null;\n }\n };\n }, []);\n\n useLayoutEffect(() => {\n if (\n !pendingInitialScrollRef.current ||\n isLoading ||\n !hasContent\n ) {\n return;\n }\n\n const element = scrollRef.current;\n if (!element) {\n return;\n }\n\n pendingInitialScrollRef.current = false;\n queueScrollToBottom();\n }, [hasContent, isLoading, queueScrollToBottom, scrollRef]);\n\n useLayoutEffect(() => {\n if (!isStickyRef.current || !hasContent) {\n return;\n }\n\n const element = scrollRef.current;\n if (!element) {\n return;\n }\n\n queueScrollToBottom();\n }, [contentVersion, hasContent, queueScrollToBottom, scrollRef]);\n\n return { isAtBottom, onScroll, scrollToBottom };\n}\n","import type { KeyboardEvent, MouseEvent, ReactNode } from \"react\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\n\n/**\n * Shared process-row metrics.\n * Collapsed process/tool rows should feel like ordinary body text lines.\n */\nexport const CHAT_PROCESS_LEADING_COL_CLASS =\n \"inline-flex h-[1.15em] w-[1.15em] shrink-0 items-center justify-center text-current\";\n\nexport const CHAT_PROCESS_META_ROW_CLASS =\n \"group/process-row flex w-full min-w-0 items-center gap-1.5 py-0 text-[0.925rem] font-normal leading-[1.72] text-muted-foreground\";\n\nexport function ChatProcessLeadingIcon({\n children,\n className,\n}: {\n children: ReactNode;\n className?: string;\n}) {\n return (\n <span className={cn(CHAT_PROCESS_LEADING_COL_CLASS, className)}>\n {children}\n </span>\n );\n}\n\nexport function ChatProcessMetaRow({\n children,\n className,\n interactive = false,\n onClick,\n role,\n tabIndex,\n onKeyDown,\n}: {\n children: ReactNode;\n className?: string;\n interactive?: boolean;\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n role?: string;\n tabIndex?: number;\n onKeyDown?: (event: KeyboardEvent<HTMLElement>) => void;\n}) {\n return (\n <div\n className={cn(\n CHAT_PROCESS_META_ROW_CLASS,\n interactive\n ? \"cursor-pointer transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35\"\n : null,\n className,\n )}\n onClick={onClick}\n role={role}\n tabIndex={tabIndex}\n onKeyDown={onKeyDown}\n >\n {children}\n </div>\n );\n}\n","import type { MouseEvent, ReactNode } from \"react\";\nimport { ChevronRight } from \"lucide-react\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { CHAT_PROCESS_META_ROW_CLASS } from \"./chat-process-meta-row\";\n\ntype MetaOpenGroup = \"process\" | \"tool-activity\" | \"reasoning\";\n\n/**\n * Shared collapsible meta-row for process / tool-group / reasoning summaries.\n * Rendered as a plain button-like row (not <summary>) so browsers never inject\n * a default disclosure label such as \"详情\" / \"Details\".\n */\nexport function ChatCollapsibleMetaSummary({\n label,\n openGroup,\n open = false,\n className,\n labelClassName,\n onClick,\n}: {\n label: ReactNode;\n openGroup: MetaOpenGroup;\n open?: boolean;\n className?: string;\n labelClassName?: string;\n onClick?: (event: MouseEvent<HTMLElement>) => void;\n}) {\n void openGroup;\n\n return (\n <button\n type=\"button\"\n className={cn(\n CHAT_PROCESS_META_ROW_CLASS,\n \"m-0 w-full border-0 bg-transparent p-0 text-left shadow-none transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/35\",\n className,\n )}\n aria-expanded={open}\n onClick={onClick}\n >\n <span className={cn(\"min-w-0 shrink truncate\", labelClassName)}>{label}</span>\n <span\n className={cn(\n \"inline-flex h-[1.15em] w-[1.15em] shrink-0 items-center justify-center text-muted-foreground/80 transition-opacity\",\n // Collapsed: hover/focus only. Expanded: always visible.\n open\n ? \"opacity-100\"\n : \"opacity-0 group-hover/process-row:opacity-100 focus-visible:opacity-100\",\n )}\n >\n <ChevronRight\n className={cn(\n \"h-[1.05em] w-[1.05em] transition-transform\",\n open && \"rotate-90\",\n )}\n strokeWidth={2.25}\n />\n </span>\n </button>\n );\n}\n","import { useRef } from \"react\";\nimport { useReasoningBlockOpenState } from \"@agent-chat-ui/components/chat/hooks/use-reasoning-block-open-state\";\nimport { useStickyBottomScroll } from \"@agent-chat-ui/components/chat/hooks/use-sticky-bottom-scroll\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { ChatCollapsibleMetaSummary } from \"./chat-collapsible-meta-summary\";\n\ntype ChatReasoningBlockProps = {\n label: string;\n text: string;\n characterCountTemplates?: {\n inProgress: string;\n completed: string;\n };\n isUser: boolean;\n isInProgress: boolean;\n};\n\nfunction formatReasoningLabel(\n label: string,\n text: string,\n characterCountTemplate?: string,\n): string {\n const characterCount = Array.from(text).length;\n return (characterCountTemplate ?? `${label} · {count}`)\n .split(\"{count}\")\n .join(String(characterCount));\n}\n\nexport function ChatReasoningBlock({\n label,\n text,\n characterCountTemplates,\n isUser,\n isInProgress,\n}: ChatReasoningBlockProps) {\n const { isOpen, onSummaryClick } = useReasoningBlockOpenState({\n isInProgress,\n });\n const scrollRef = useRef<HTMLDivElement>(null);\n const displayLabel = formatReasoningLabel(\n label,\n text,\n isInProgress\n ? characterCountTemplates?.inProgress\n : characterCountTemplates?.completed,\n );\n const { onScroll } = useStickyBottomScroll({\n scrollRef,\n resetKey: `${displayLabel}:${isInProgress ? \"streaming\" : \"idle\"}`,\n isLoading: false,\n hasContent: text.length > 0,\n contentVersion: text,\n stickyThresholdPx: 20,\n });\n\n return (\n <div className=\"group/reasoning\">\n <ChatCollapsibleMetaSummary\n openGroup=\"reasoning\"\n open={isOpen}\n label={displayLabel}\n labelClassName={isUser ? \"text-primary-100\" : undefined}\n onClick={onSummaryClick}\n />\n {isOpen ? (\n <div\n ref={scrollRef}\n onScroll={onScroll}\n data-reasoning-scroll=\"true\"\n className={cn(\n \"mt-1 w-fit max-w-[500px] max-h-56 overflow-y-auto rounded-lg custom-scrollbar\",\n isUser ? \"bg-primary/70\" : \"bg-muted\",\n )}\n >\n <pre className=\"min-w-0 whitespace-pre-wrap break-all p-2 text-[11px]\">{text}</pre>\n </div>\n ) : null}\n </div>\n );\n}\n","import { cn } from '@agent-chat-ui/components/chat/internal/cn';\nimport type { ReactNode } from 'react';\n\n/**\n * Default tool presentation is an inline process row, not a heavy card.\n * Expanded details sit under the overview text column with clear clearance\n * from any workflow rail in the icon column.\n */\nexport function ToolCardRoot({ children, className }: { children: ReactNode; className?: string }) {\n return (\n <div\n className={cn(\n 'relative my-0 flex w-full min-w-0 max-w-full flex-col text-[0.925rem] leading-[1.72] text-muted-foreground',\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\nexport function ToolCardContent({ children, className }: { children: ReactNode; className?: string }) {\n return (\n <div\n className={cn(\n // Align every expanded panel with the overview text column. The rail\n // remains isolated in the leading icon column.\n 'mt-0.5 w-full max-w-full min-w-0 overflow-hidden pl-[calc(1.15em+0.375rem)] text-[0.925rem] leading-[1.72] text-muted-foreground',\n className,\n )}\n >\n {children}\n </div>\n );\n}\n","import { Check, Loader2, AlertTriangle, Minus } from 'lucide-react';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\nimport type { ChatToolPartViewModel } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nexport const STATUS_STYLES = {\n running: { text: 'text-muted-foreground', icon: Loader2, spin: true },\n success: { text: 'text-muted-foreground/75', icon: Check, spin: false },\n error: { text: 'text-destructive', icon: AlertTriangle, spin: false },\n cancelled: { text: 'text-muted-foreground/70', icon: Minus, spin: false }\n} as const;\n\nexport function ToolStatusLabel({\n card,\n iconOnly = false,\n}: {\n card: ChatToolPartViewModel;\n iconOnly?: boolean;\n}) {\n const style = STATUS_STYLES[card.statusTone] || STATUS_STYLES.cancelled;\n const Icon = style.icon;\n const showLabel = !iconOnly && (card.statusTone === 'running' || card.statusTone === 'error');\n\n return (\n <span\n className={cn('inline-flex shrink-0 items-center gap-1 text-[0.925rem] font-normal leading-[1.72]', style.text)}\n aria-label={iconOnly ? card.statusLabel : undefined}\n >\n <Icon\n aria-hidden=\"true\"\n className={cn('h-[1.05em] w-[1.05em]', style.spin && 'animate-spin')}\n strokeWidth={2.25}\n />\n {showLabel ? card.statusLabel : null}\n </span>\n );\n}\n","import { ArrowUpRight, ChevronRight, Eye, type LucideIcon } from 'lucide-react';\nimport type { KeyboardEvent, MouseEvent, ReactNode } from 'react';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\nimport { ChatUiPrimitives } from '@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives';\nimport {\n ChatProcessLeadingIcon,\n ChatProcessMetaRow,\n} from '@agent-chat-ui/components/chat/ui/chat-message-list/chat-process-meta-row';\nimport { ToolStatusLabel } from './tool-card-status';\nimport type {\n ChatToolActionViewModel,\n ChatToolPartViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nfunction resolveToolCardActionView(action: ChatToolActionViewModel): {\n icon: LucideIcon;\n label: string;\n toneClassName: string;\n} {\n if (action.kind === 'show-content') {\n return {\n icon: Eye,\n label: action.label,\n toneClassName:\n 'border-border/70 bg-transparent text-muted-foreground hover:bg-muted/60 hover:text-foreground focus-visible:ring-primary/35',\n };\n }\n\n return {\n icon: ArrowUpRight,\n label: action.label ?? (action.sessionKind === 'child' ? 'Open child session' : 'Open session'),\n toneClassName:\n 'border-border/70 bg-transparent text-muted-foreground hover:bg-muted/60 hover:text-foreground focus-visible:ring-primary/35',\n };\n}\n\nfunction ToolCardActionButton({\n action,\n onAction,\n}: {\n action: ChatToolActionViewModel;\n onAction: (action: ChatToolActionViewModel) => void;\n}) {\n const { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } = ChatUiPrimitives;\n const view = resolveToolCardActionView(action);\n const Icon = view.icon;\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n event.stopPropagation();\n onAction(action);\n };\n\n return (\n <TooltipProvider delayDuration={250}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={handleClick}\n className={cn(\n 'inline-flex h-6 w-6 items-center justify-center rounded-md border transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1',\n view.toneClassName,\n )}\n aria-label={view.label}\n title={view.label}\n >\n <Icon className=\"h-3.5 w-3.5\" strokeWidth={2.25} />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"text-xs\">\n {view.label}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n\nfunction humanizeToolName(toolName: string): string {\n return toolName\n .replace(/[_-]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n}\n\nfunction handleToolHeaderKeyDown(\n event: KeyboardEvent<HTMLElement>,\n onToggle: () => void,\n) {\n if (event.key !== 'Enter' && event.key !== ' ') {\n return;\n }\n event.preventDefault();\n onToggle();\n}\n\nfunction ToolHeaderSummary({\n label,\n summary,\n}: {\n label: string;\n summary: string;\n}) {\n return (\n <span className=\"min-w-0 shrink truncate\">\n {label}\n {summary ? (\n <>\n <span className=\"mx-1.5 select-none text-muted-foreground/45\">·</span>\n <span title={summary}>{summary}</span>\n </>\n ) : null}\n </span>\n );\n}\n\nfunction ToolHeaderChevron({ expanded }: { expanded: boolean }) {\n return (\n <span\n className={cn(\n 'inline-flex h-[1.15em] w-[1.15em] shrink-0 items-center justify-center text-muted-foreground/80 transition-opacity',\n expanded\n ? 'opacity-100'\n : 'opacity-0 group-hover/process-row:opacity-100 group-focus-within/process-row:opacity-100',\n )}\n >\n <ChevronRight\n className={cn(\n 'h-[1.05em] w-[1.05em] transition-transform',\n expanded && 'rotate-90',\n )}\n strokeWidth={2.25}\n />\n </span>\n );\n}\n\nfunction ToolHeaderChangeSummary({\n additions,\n deletions,\n}: {\n additions: number;\n deletions: number;\n}) {\n if (additions === 0 && deletions === 0) {\n return null;\n }\n const accessibleLabel = [\n additions > 0 ? `+${additions}` : null,\n deletions > 0 ? `-${deletions}` : null,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <span\n className=\"inline-flex shrink-0 items-center gap-1.5 tabular-nums text-muted-foreground/75\"\n aria-label={accessibleLabel}\n >\n {additions > 0 ? (\n <span className=\"transition-colors group-hover/process-row:text-emerald-600\">\n +{additions}\n </span>\n ) : null}\n {deletions > 0 ? (\n <span className=\"transition-colors group-hover/process-row:text-rose-600\">\n -{deletions}\n </span>\n ) : null}\n </span>\n );\n}\n\nexport function ToolCardHeader({\n card,\n toolLabel,\n changeSummary,\n icon: Icon,\n expanded,\n canExpand,\n hideSummary = false,\n actionSlot,\n onToggle,\n}: {\n card: ChatToolPartViewModel;\n toolLabel?: string;\n changeSummary?: { additions: number; deletions: number };\n icon: LucideIcon;\n expanded: boolean;\n canExpand: boolean;\n hideSummary?: boolean;\n actionSlot?: ReactNode;\n onToggle: () => void;\n}) {\n const summaryPart = hideSummary\n ? ''\n : card.summary?.replace(/^(command|path|args|query|input):\\s*/i, '') ?? '';\n const displayLabel = toolLabel ?? humanizeToolName(card.toolName);\n\n return (\n <ChatProcessMetaRow\n interactive={canExpand}\n onClick={canExpand ? () => onToggle() : undefined}\n role={canExpand ? 'button' : undefined}\n tabIndex={canExpand ? 0 : undefined}\n onKeyDown={\n canExpand\n ? (event: KeyboardEvent<HTMLElement>) =>\n handleToolHeaderKeyDown(event, onToggle)\n : undefined\n }\n >\n <ChatProcessLeadingIcon className=\"relative z-[1] rounded-sm bg-card\">\n <Icon className=\"h-[1.05em] w-[1.05em]\" strokeWidth={2.25} />\n </ChatProcessLeadingIcon>\n\n {/*\n One flowing cluster: text → status → expand chevron.\n No flex-1 spacer, so chevron stays tight against the overview text\n instead of jumping to the far right edge.\n */}\n <ToolHeaderSummary label={displayLabel} summary={summaryPart} />\n {changeSummary ? <ToolHeaderChangeSummary {...changeSummary} /> : null}\n <ToolStatusLabel card={card} iconOnly={Boolean(toolLabel)} />\n {canExpand ? <ToolHeaderChevron expanded={expanded} /> : null}\n {actionSlot ? (\n <span className=\"inline-flex shrink-0 items-center gap-1 opacity-0 transition-opacity group-hover/process-row:opacity-100 group-focus-within/process-row:opacity-100\">\n {actionSlot}\n </span>\n ) : null}\n </ChatProcessMetaRow>\n );\n}\n\nexport function ToolCardHeaderAction({\n action,\n onAction,\n}: {\n action: ChatToolActionViewModel;\n onAction: (action: ChatToolActionViewModel) => void;\n}) {\n return <ToolCardActionButton action={action} onAction={onAction} />;\n}\n","import { useMemo } from \"react\";\nimport type {\n ChatFileOperationBlockViewModel,\n ChatFileOperationLineViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { chatCodeSyntaxHighlighter } from \"@agent-chat-ui/components/chat/ui/chat-message-list/code-block/chat-code-syntax-highlighter\";\n\nconst FILE_TEXT_CLASS_NAME = \"font-mono text-[11px] leading-5\";\nconst FILE_ROW_CLASS_NAME = `flex h-5 w-full ${FILE_TEXT_CLASS_NAME}`;\nconst FILE_LINE_NUMBER_CELL_CLASS_NAME =\n \"flex h-5 items-center justify-center px-2.5 tabular-nums select-none\";\n\nfunction readVisibleLineNumber(line: ChatFileOperationLineViewModel): string {\n const value = line.newLineNumber ?? line.oldLineNumber;\n return typeof value === \"number\" ? String(value) : \"\";\n}\n\nfunction readLineKey(\n prefix: string,\n line: ChatFileOperationLineViewModel,\n index: number,\n): string {\n return `${prefix}-${index}-${line.oldLineNumber ?? \"x\"}-${line.newLineNumber ?? \"x\"}`;\n}\n\nfunction hasVisibleLineNumber(line: ChatFileOperationLineViewModel): boolean {\n return (\n typeof line.newLineNumber === \"number\" ||\n typeof line.oldLineNumber === \"number\"\n );\n}\n\nfunction readHasBlockLineNumbers(block: ChatFileOperationBlockViewModel): boolean {\n return block.lines.some(hasVisibleLineNumber);\n}\n\nfunction readLineNumberColumnWidth(\n block: ChatFileOperationBlockViewModel,\n): string {\n const maxDigits = block.lines.reduce((currentMax, line) => {\n if (!hasVisibleLineNumber(line)) {\n return currentMax;\n }\n return Math.max(currentMax, readVisibleLineNumber(line).length);\n }, 0);\n const width = Math.max(6.5, Math.min(8, maxDigits + 3.5));\n return `${width}ch`;\n}\n\nfunction readCodeColumnWidth(block: ChatFileOperationBlockViewModel): string {\n const maxColumns = block.lines.reduce(\n (currentMax, line) => Math.max(currentMax, Math.max(1, line.text.length)),\n 1,\n );\n return `calc(${maxColumns}ch + 1.25rem)`;\n}\n\nfunction readPathExtension(path: string): string | null {\n const fileName = path.split(/[\\\\/]/).filter(Boolean).pop() ?? path;\n const cleanName = fileName.split(/[?#]/)[0] ?? fileName;\n const extensionStart = cleanName.lastIndexOf(\".\");\n if (extensionStart <= 0 || extensionStart === cleanName.length - 1) {\n return null;\n }\n return cleanName.slice(extensionStart + 1).toLowerCase();\n}\n\nfunction readBlockLanguage(block: ChatFileOperationBlockViewModel): string {\n const hint = block.languageHint?.trim();\n return hint || readPathExtension(block.path) || \"text\";\n}\n\nfunction readLanguageClassName(language: string): string {\n const normalized = language.toLowerCase().replace(/[^a-z0-9-]/g, \"-\");\n return normalized ? `language-${normalized}` : \"language-text\";\n}\n\nfunction getLineNumberTone(line: ChatFileOperationLineViewModel): string {\n if (line.kind === \"remove\") {\n return \"border-r border-rose-200 bg-rose-50 text-rose-700\";\n }\n if (line.kind === \"add\") {\n return \"border-r border-emerald-200 bg-emerald-50 text-emerald-700\";\n }\n return \"border-r border-border bg-muted text-muted-foreground\";\n}\n\nfunction getCodeRowTone(line: ChatFileOperationLineViewModel): string {\n if (line.kind === \"remove\") {\n return \"bg-rose-50 text-rose-950\";\n }\n if (line.kind === \"add\") {\n return \"bg-emerald-50 text-emerald-950\";\n }\n return \"bg-card text-foreground\";\n}\n\nfunction FileOperationLineNumberCell({\n layout,\n line,\n lineNumberColumnWidth,\n}: {\n layout: \"compact\" | \"workspace\";\n line: ChatFileOperationLineViewModel;\n lineNumberColumnWidth: string;\n}) {\n return (\n <span\n data-file-line-number-cell=\"true\"\n style={layout === \"compact\" ? { width: lineNumberColumnWidth, minWidth: lineNumberColumnWidth } : undefined}\n className={cn(\n FILE_LINE_NUMBER_CELL_CLASS_NAME,\n layout === \"compact\" ? \"sticky left-0 z-[1]\" : \"w-full shrink-0\",\n getLineNumberTone(line),\n )}\n >\n {readVisibleLineNumber(line)}\n </span>\n );\n}\n\nfunction FileOperationCodeCell({\n language,\n line,\n}: {\n language: string;\n line: ChatFileOperationLineViewModel;\n}) {\n const highlightedCode = useMemo(\n () => chatCodeSyntaxHighlighter.highlight(line.text || \" \", language),\n [language, line.text],\n );\n\n return (\n <span\n data-file-code-row=\"true\"\n data-file-code-language={highlightedCode.language}\n data-highlighted={highlightedCode.highlighted ? \"true\" : \"false\"}\n className={cn(\n \"chat-file-code-syntax hljs block min-w-0 flex-1 whitespace-pre px-2.5\",\n readLanguageClassName(highlightedCode.language),\n getCodeRowTone(line),\n )}\n dangerouslySetInnerHTML={{ __html: highlightedCode.html }}\n />\n );\n}\n\nfunction FileOperationLineRow({\n language,\n line,\n showLineNumbers,\n lineNumberColumnWidth,\n}: {\n language: string;\n line: ChatFileOperationLineViewModel;\n showLineNumbers: boolean;\n lineNumberColumnWidth: string;\n}) {\n return (\n <div data-file-line-row=\"true\" className={FILE_ROW_CLASS_NAME}>\n {showLineNumbers ? (\n <FileOperationLineNumberCell\n layout=\"compact\"\n line={line}\n lineNumberColumnWidth={lineNumberColumnWidth}\n />\n ) : null}\n <FileOperationCodeCell language={language} line={line} />\n </div>\n );\n}\n\nfunction FileOperationWorkspaceSurface({\n block,\n}: {\n block: ChatFileOperationBlockViewModel;\n}) {\n const showLineNumbers = readHasBlockLineNumbers(block);\n const lineNumberColumnWidth = readLineNumberColumnWidth(block);\n const codeColumnWidth = readCodeColumnWidth(block);\n const language = readBlockLanguage(block);\n\n return (\n <div\n data-file-code-surface=\"true\"\n data-file-code-surface-layout=\"workspace\"\n className=\"flex h-full min-h-full min-w-full bg-card\"\n >\n {showLineNumbers ? (\n <div\n data-file-code-gutter=\"true\"\n style={{\n width: lineNumberColumnWidth,\n minWidth: lineNumberColumnWidth,\n }}\n className={cn(\n \"flex h-full min-h-full shrink-0 flex-col\",\n FILE_TEXT_CLASS_NAME,\n )}\n >\n {block.lines.map((line, index) => (\n <FileOperationLineNumberCell\n key={readLineKey(\"gutter\", line, index)}\n layout=\"workspace\"\n line={line}\n lineNumberColumnWidth={lineNumberColumnWidth}\n />\n ))}\n <div className=\"min-h-0 flex-1 border-r border-border bg-muted\" />\n </div>\n ) : null}\n\n <div\n data-file-code-canvas=\"true\"\n className=\"flex h-full min-h-full min-w-0 flex-1 flex-col bg-card\"\n >\n <div\n data-file-code-stack=\"true\"\n className=\"min-w-full\"\n style={{ minWidth: codeColumnWidth }}\n >\n {block.lines.map((line, index) => (\n <div\n key={readLineKey(\"code\", line, index)}\n data-file-code-canvas-row=\"true\"\n className={FILE_ROW_CLASS_NAME}\n >\n <FileOperationCodeCell language={language} line={line} />\n </div>\n ))}\n </div>\n <div className=\"min-h-0 flex-1 bg-card\" />\n </div>\n </div>\n );\n}\n\nexport function FileOperationCodeSurface({\n block,\n layout = \"compact\",\n}: {\n block: ChatFileOperationBlockViewModel;\n layout?: \"compact\" | \"workspace\";\n}) {\n if (layout === \"workspace\") {\n return <FileOperationWorkspaceSurface block={block} />;\n }\n\n const showLineNumbers = readHasBlockLineNumbers(block);\n const lineNumberColumnWidth = readLineNumberColumnWidth(block);\n const codeColumnWidth = readCodeColumnWidth(block);\n const surfaceMinWidth = showLineNumbers\n ? `calc(${lineNumberColumnWidth} + ${codeColumnWidth})`\n : codeColumnWidth;\n const language = readBlockLanguage(block);\n\n return (\n <div\n data-file-code-surface=\"true\"\n data-file-code-surface-layout=\"compact\"\n className=\"overflow-x-auto custom-scrollbar bg-card\"\n >\n <div\n data-file-code-stack=\"true\"\n className=\"min-w-full\"\n style={{ minWidth: surfaceMinWidth }}\n >\n {block.lines.map((line, index) => (\n <FileOperationLineRow\n key={readLineKey(\"row\", line, index)}\n language={language}\n line={line}\n showLineNumbers={showLineNumbers}\n lineNumberColumnWidth={lineNumberColumnWidth}\n />\n ))}\n </div>\n </div>\n );\n}\n\nexport function FileOperationLinesGrid({\n block,\n}: {\n block: ChatFileOperationBlockViewModel;\n}) {\n return <FileOperationCodeSurface block={block} layout=\"compact\" />;\n}\n","import type {\n ChatFileOpenActionViewModel,\n ChatFileOperationBlockViewModel,\n ChatToolPartViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { useStickyBottomScroll } from \"@agent-chat-ui/components/chat/hooks/use-sticky-bottom-scroll\";\nimport { Fragment, type ReactNode, useRef } from \"react\";\nimport { ChatUiPrimitives } from \"@agent-chat-ui/components/chat/ui/primitives/chat-ui-primitives\";\nimport { FileOperationLinesGrid } from \"./tool-card-file-operation-lines\";\n\nfunction isPreviewBlock(block: ChatFileOperationBlockViewModel): boolean {\n return block.display === \"preview\";\n}\n\nfunction readFileOperationContentVersion(\n block: Pick<ChatFileOperationBlockViewModel, \"lines\" | \"rawText\">,\n): string {\n if (block.rawText) {\n return block.rawText;\n }\n return block.lines\n .map((line) =>\n [\n line.kind,\n line.oldLineNumber ?? \"\",\n line.newLineNumber ?? \"\",\n line.text,\n ].join(\":\"),\n )\n .join(\"\\n\");\n}\n\nfunction getCaptionTone(part: string): string {\n if (/^\\+\\d+$/.test(part)) {\n return \"text-emerald-700\";\n }\n if (/^-\\d+$/.test(part)) {\n return \"text-rose-700\";\n }\n return \"text-muted-foreground\";\n}\n\nfunction renderCaption(caption: string) {\n const parts = caption\n .split(\"·\")\n .map((part) => part.trim())\n .filter((part) => /^\\+\\d+$/.test(part) || /^-\\d+$/.test(part));\n if (parts.length === 0) {\n return null;\n }\n return (\n <div className=\"flex shrink-0 items-center gap-x-1 whitespace-nowrap text-[10px] font-medium uppercase tracking-[0.08em]\">\n {parts.map((part, index) => (\n <Fragment key={`${part}-${index}`}>\n {index > 0 ? <span className=\"text-muted-foreground/45\">·</span> : null}\n <span className={cn(getCaptionTone(part))}>{part}</span>\n </Fragment>\n ))}\n </div>\n );\n}\n\nfunction buildFileOpenAction(\n block: ChatFileOperationBlockViewModel,\n): ChatFileOpenActionViewModel {\n return {\n path: block.path,\n label: block.path.split(\"/\").filter(Boolean).pop() ?? block.path,\n viewMode: block.display === \"diff\" ? \"diff\" : \"preview\",\n ...(block.rawText ? { rawText: block.rawText } : {}),\n ...(block.beforeText ? { beforeText: block.beforeText } : {}),\n ...(block.afterText ? { afterText: block.afterText } : {}),\n ...(block.patchText ? { patchText: block.patchText } : {}),\n ...(typeof block.oldStartLine === \"number\"\n ? { oldStartLine: block.oldStartLine }\n : {}),\n ...(typeof block.newStartLine === \"number\"\n ? { newStartLine: block.newStartLine }\n : {}),\n fullLines: block.fullLines ?? block.lines,\n };\n}\n\nfunction StickyFileOperationScrollArea({\n children,\n contentVersion,\n resetKey,\n className,\n scrollKind,\n}: {\n children: ReactNode;\n contentVersion: unknown;\n resetKey: string;\n className?: string;\n scrollKind: \"block\" | \"raw\" | \"output\";\n}) {\n const scrollRef = useRef<HTMLDivElement>(null);\n const { onScroll } = useStickyBottomScroll({\n scrollRef,\n resetKey,\n isLoading: false,\n hasContent: true,\n contentVersion,\n stickyThresholdPx: 20,\n });\n\n return (\n <div\n ref={scrollRef}\n onScroll={onScroll}\n data-file-scroll-kind={scrollKind}\n className={cn(\n \"overflow-y-auto bg-card custom-scrollbar\",\n className,\n )}\n >\n {children}\n </div>\n );\n}\n\nfunction FileOperationBlock({\n block,\n showPathRow,\n isFirst,\n onFileOpen,\n}: {\n block: ChatFileOperationBlockViewModel;\n showPathRow: boolean;\n isFirst: boolean;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n}) {\n const { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } =\n ChatUiPrimitives;\n const previewBlock = isPreviewBlock(block);\n const showMetaRow = showPathRow || Boolean(block.caption);\n\n const handlePathClick = () => {\n if (!onFileOpen) {\n return;\n }\n onFileOpen(buildFileOpenAction(block));\n };\n\n return (\n <section\n className={cn(\n \"overflow-hidden bg-card\",\n !isFirst && \"border-t border-border\",\n )}\n >\n {showMetaRow ? (\n <div\n className={cn(\n \"flex min-h-9 items-center justify-between gap-4 border-b border-border px-3 text-muted-foreground\",\n showPathRow ? \"py-2\" : \"py-1.5\",\n )}\n >\n <div className=\"min-w-0 flex-1\">\n {showPathRow ? (\n <TooltipProvider delayDuration={250}>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={handlePathClick}\n className={cn(\n \"w-full truncate whitespace-nowrap text-left font-mono text-[12px] font-medium leading-5 text-foreground\",\n onFileOpen &&\n \"transition-colors hover:text-primary hover:underline\",\n )}\n title={block.path}\n >\n {block.path}\n </button>\n </TooltipTrigger>\n <TooltipContent\n side=\"top\"\n className=\"max-w-[420px] text-xs font-mono break-all\"\n >\n {block.path}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n {block.caption ? renderCaption(block.caption) : null}\n </div>\n ) : null}\n\n {block.lines.length > 0 ? (\n <StickyFileOperationScrollArea\n resetKey={`block:${block.key}`}\n contentVersion={readFileOperationContentVersion(block)}\n className=\"max-h-72\"\n scrollKind=\"block\"\n >\n <FileOperationLinesGrid block={block} />\n </StickyFileOperationScrollArea>\n ) : block.rawText ? (\n <StickyFileOperationScrollArea\n resetKey={`raw:${block.key}`}\n contentVersion={block.rawText}\n className=\"max-h-72\"\n scrollKind=\"raw\"\n >\n <div className=\"overflow-x-auto custom-scrollbar\">\n <pre className=\"min-w-max whitespace-pre bg-card px-3 py-2 font-mono text-[11px] leading-5 text-foreground\">\n {block.rawText}\n </pre>\n </div>\n </StickyFileOperationScrollArea>\n ) : null}\n\n {block.truncated && !previewBlock ? (\n <div className=\"border-t border-border bg-muted px-3 py-2 text-[10px] text-muted-foreground\">\n Showing a shortened diff preview.\n </div>\n ) : null}\n </section>\n );\n}\n\nexport function ToolCardFileOperationContent({\n card,\n className,\n onFileOpen,\n showPathRow = true,\n}: {\n card: ChatToolPartViewModel;\n className?: string;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n /**\n * Keep the path header by default so file open + +N/-N captions stay visible.\n */\n showPathRow?: boolean;\n}) {\n const blocks = card.fileOperation?.blocks ?? [];\n const output = card.output?.trim() ?? \"\";\n if (blocks.length === 0 && !output) {\n return null;\n }\n\n return (\n <div className={cn(\"overflow-hidden rounded-md border border-border/70 bg-card\", className)}>\n {blocks.map((block, index) => {\n return (\n <FileOperationBlock\n key={block.key}\n block={block}\n showPathRow={showPathRow}\n isFirst={index === 0}\n onFileOpen={onFileOpen}\n />\n );\n })}\n\n {output ? (\n <StickyFileOperationScrollArea\n resetKey={`output:${card.toolName}:${card.summary ?? \"none\"}`}\n contentVersion={output}\n className={cn(\n \"max-h-56\",\n blocks.length > 0 && \"border-t border-border\",\n )}\n scrollKind=\"output\"\n >\n <div className=\"overflow-x-auto custom-scrollbar\">\n <pre className=\"min-w-max whitespace-pre bg-card px-3 py-2 font-mono text-[11px] leading-5 text-foreground\">\n {output}\n </pre>\n </div>\n </StickyFileOperationScrollArea>\n ) : null}\n </div>\n );\n}\n","const ANSI_ESCAPE_PREFIX = String.fromCharCode(27);\nconst ANSI_PATTERN = new RegExp(`${ANSI_ESCAPE_PREFIX}\\\\[(.*?)([ -/]*[@-~])`, \"g\");\n\nexport function hasAnsiSequences(value: string): boolean {\n return value.includes(`${ANSI_ESCAPE_PREFIX}[`);\n}\n\nexport function stripAnsiSequences(value: string): string {\n return value.replace(new RegExp(`${ANSI_ESCAPE_PREFIX}\\\\[[0-?]*[ -/]*[@-~]`, \"g\"), \"\");\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\ntype AnsiStyle = {\n bold: boolean;\n dim: boolean;\n italic: boolean;\n underline: boolean;\n inverse: boolean;\n fg?: string;\n bg?: string;\n};\n\nconst DEFAULT_STYLE: AnsiStyle = {\n bold: false,\n dim: false,\n italic: false,\n underline: false,\n inverse: false,\n};\n\nconst SGR_STYLE_PATCHES: Record<number, Partial<AnsiStyle>> = {\n 1: { bold: true },\n 2: { dim: true },\n 3: { italic: true },\n 4: { underline: true },\n 7: { inverse: true },\n 22: { bold: false, dim: false },\n 23: { italic: false },\n 24: { underline: false },\n 27: { inverse: false },\n 39: { fg: undefined },\n 49: { bg: undefined },\n};\n\nconst BASIC_FG: Record<number, string> = {\n 30: \"black\",\n 31: \"red\",\n 32: \"green\",\n 33: \"yellow\",\n 34: \"blue\",\n 35: \"magenta\",\n 36: \"cyan\",\n 37: \"white\",\n 90: \"bright-black\",\n 91: \"bright-red\",\n 92: \"bright-green\",\n 93: \"bright-yellow\",\n 94: \"bright-blue\",\n 95: \"bright-magenta\",\n 96: \"bright-cyan\",\n 97: \"bright-white\",\n};\n\nconst BASIC_BG: Record<number, string> = {\n 40: \"black\",\n 41: \"red\",\n 42: \"green\",\n 43: \"yellow\",\n 44: \"blue\",\n 45: \"magenta\",\n 46: \"cyan\",\n 47: \"white\",\n 100: \"bright-black\",\n 101: \"bright-red\",\n 102: \"bright-green\",\n 103: \"bright-yellow\",\n 104: \"bright-blue\",\n 105: \"bright-magenta\",\n 106: \"bright-cyan\",\n 107: \"bright-white\",\n};\n\nfunction resolveExtendedColor(\n params: number[],\n index: number,\n): { color: string; consumed: number } | null {\n const mode = params[index + 1];\n if (mode === 5 && typeof params[index + 2] === \"number\") {\n return { color: `ansi-256-${params[index + 2]}`, consumed: 2 };\n }\n if (\n mode === 2 &&\n typeof params[index + 2] === \"number\" &&\n typeof params[index + 3] === \"number\" &&\n typeof params[index + 4] === \"number\"\n ) {\n return {\n color: `rgb(${params[index + 2]},${params[index + 3]},${params[index + 4]})`,\n consumed: 4,\n };\n }\n return null;\n}\n\nfunction applySgr(style: AnsiStyle, params: number[]): AnsiStyle {\n let next = { ...style };\n for (let index = 0; index < params.length; index += 1) {\n const code = params[index]!;\n if (code === 0) {\n return { ...DEFAULT_STYLE };\n }\n const stylePatch = SGR_STYLE_PATCHES[code];\n if (stylePatch) {\n next = { ...next, ...stylePatch };\n continue;\n }\n if (code === 38 || code === 48) {\n const extendedColor = resolveExtendedColor(params, index);\n if (extendedColor) {\n next =\n code === 38\n ? { ...next, fg: extendedColor.color }\n : { ...next, bg: extendedColor.color };\n index += extendedColor.consumed;\n }\n continue;\n }\n if (BASIC_FG[code]) {\n next = { ...next, fg: BASIC_FG[code] };\n continue;\n }\n if (BASIC_BG[code]) {\n next = { ...next, bg: BASIC_BG[code] };\n }\n }\n return next;\n}\n\nfunction styleToClassName(style: AnsiStyle): string {\n const classes: string[] = [\"ansi\"];\n if (style.bold) classes.push(\"ansi-bold\");\n if (style.dim) classes.push(\"ansi-dim\");\n if (style.italic) classes.push(\"ansi-italic\");\n if (style.underline) classes.push(\"ansi-underline\");\n if (style.inverse) classes.push(\"ansi-inverse\");\n if (style.fg) {\n if (style.fg.startsWith(\"rgb(\")) {\n classes.push(\"ansi-fg-custom\");\n } else if (style.fg.startsWith(\"ansi-256-\")) {\n classes.push(\"ansi-fg-256\");\n classes.push(style.fg);\n } else {\n classes.push(`ansi-fg-${style.fg}`);\n }\n }\n if (style.bg) {\n if (style.bg.startsWith(\"rgb(\")) {\n classes.push(\"ansi-bg-custom\");\n } else if (style.bg.startsWith(\"ansi-256-\")) {\n classes.push(\"ansi-bg-256\");\n classes.push(style.bg);\n } else {\n classes.push(`ansi-bg-${style.bg}`);\n }\n }\n return classes.join(\" \");\n}\n\nfunction styleToInlineStyle(style: AnsiStyle): string | undefined {\n const parts: string[] = [];\n if (style.fg?.startsWith(\"rgb(\")) {\n parts.push(`color:${style.fg}`);\n }\n if (style.bg?.startsWith(\"rgb(\")) {\n parts.push(`background-color:${style.bg}`);\n }\n return parts.length > 0 ? parts.join(\";\") : undefined;\n}\n\nfunction openSpan(style: AnsiStyle): string {\n const className = styleToClassName(style);\n const inline = styleToInlineStyle(style);\n return inline\n ? `<span class=\"${className}\" style=\"${inline}\">`\n : `<span class=\"${className}\">`;\n}\n\n/**\n * Lightweight ANSI SGR -> HTML converter for terminal output.\n * Handles common color/style codes without adding a dependency.\n */\nexport function ansiToHtml(value: string): string {\n if (!value) {\n return \"\";\n }\n if (!hasAnsiSequences(value)) {\n return escapeHtml(value);\n }\n\n let html = \"\";\n let lastIndex = 0;\n let style = { ...DEFAULT_STYLE };\n let spanOpen = false;\n\n const flushText = (text: string) => {\n if (!text) return;\n if (!spanOpen) {\n html += openSpan(style);\n spanOpen = true;\n }\n html += escapeHtml(text);\n };\n\n const closeSpan = () => {\n if (spanOpen) {\n html += \"</span>\";\n spanOpen = false;\n }\n };\n\n value.replace(ANSI_PATTERN, (match, body: string, terminator: string, offset: number) => {\n flushText(value.slice(lastIndex, offset));\n lastIndex = offset + match.length;\n\n // Only handle SGR (`m`). Other CSI sequences are dropped.\n if (terminator !== \"m\") {\n return match;\n }\n\n const params =\n body.trim().length === 0\n ? [0]\n : body\n .split(\";\")\n .map((part) => Number.parseInt(part, 10))\n .filter((part) => Number.isFinite(part));\n\n closeSpan();\n style = applySgr(style, params.length > 0 ? params : [0]);\n return match;\n });\n\n flushText(value.slice(lastIndex));\n closeSpan();\n return html;\n}\n","import { useMemo } from \"react\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { chatCodeSyntaxHighlighter } from \"@agent-chat-ui/components/chat/ui/chat-message-list/code-block/chat-code-syntax-highlighter\";\nimport {\n ansiToHtml,\n hasAnsiSequences,\n stripAnsiSequences,\n} from \"./terminal-ansi.utils\";\n\nconst MAX_TERMINAL_TEXT_CHARS = 120_000;\n\nfunction clampTerminalText(value: string): string {\n if (value.length <= MAX_TERMINAL_TEXT_CHARS) {\n return value;\n }\n return `${value.slice(0, MAX_TERMINAL_TEXT_CHARS)}\\n…`;\n}\n\nfunction TerminalCode({\n code,\n language,\n preferAnsi = false,\n className,\n}: {\n code: string;\n language: string;\n preferAnsi?: boolean;\n className?: string;\n}) {\n const source = clampTerminalText(code);\n const content = useMemo(() => {\n if (preferAnsi && hasAnsiSequences(source)) {\n return {\n html: ansiToHtml(source),\n language: \"ansi\",\n highlighted: true,\n };\n }\n const plain = stripAnsiSequences(source);\n return chatCodeSyntaxHighlighter.highlight(plain, language);\n }, [language, preferAnsi, source]);\n\n return (\n <code\n className={cn(\n \"hljs chat-terminal-code\",\n `language-${content.language}`,\n className,\n )}\n data-highlighted={content.highlighted ? \"true\" : \"false\"}\n dangerouslySetInnerHTML={{ __html: content.html }}\n />\n );\n}\n\n/**\n * Compact terminal-style surface for command tools.\n * Style only — no decorative window chrome.\n */\nexport function ChatTerminalSurface({\n command,\n output,\n emptyLabel,\n isRunning,\n hasOutput,\n isError = false,\n}: {\n command?: string | null;\n output: string;\n emptyLabel: string;\n isRunning: boolean;\n hasOutput: boolean;\n isError?: boolean;\n exitCode?: number | null;\n workingDir?: string | null;\n}) {\n return (\n <div\n className={cn(\n \"chat-terminal-surface\",\n isError ? \"chat-terminal-surface-error\" : undefined,\n )}\n data-testid=\"chat-terminal-surface\"\n >\n <div className=\"chat-terminal-body custom-scrollbar\">\n <div className=\"chat-terminal-line chat-terminal-line-command\">\n <span className=\"chat-terminal-gutter\" aria-hidden=\"true\">\n $\n </span>\n <div className=\"chat-terminal-line-content\">\n {command ? (\n <pre className=\"chat-terminal-pre\">\n <TerminalCode code={command} language=\"bash\" />\n {isRunning && !hasOutput ? (\n <span className=\"chat-terminal-caret\" aria-hidden=\"true\" />\n ) : null}\n </pre>\n ) : (\n <div className=\"chat-terminal-skeleton\" />\n )}\n </div>\n </div>\n\n {(hasOutput || !isRunning) && (\n <div className=\"chat-terminal-output-block\">\n {hasOutput ? (\n <pre\n className={cn(\n \"chat-terminal-pre chat-terminal-output\",\n isError ? \"chat-terminal-pre-error\" : undefined,\n )}\n >\n <TerminalCode\n code={output}\n language={isError ? \"text\" : \"shell\"}\n preferAnsi\n className={isError ? \"chat-terminal-code-error\" : undefined}\n />\n {isRunning ? (\n <span className=\"chat-terminal-caret\" aria-hidden=\"true\" />\n ) : null}\n </pre>\n ) : (\n <div className=\"chat-terminal-empty\">{emptyLabel}</div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { Terminal, FileText, Code2, Search, type LucideIcon } from 'lucide-react';\nimport { useState, useEffect, useRef } from 'react';\nimport type {\n ChatFileOperationBlockViewModel,\n ChatFileOpenActionViewModel,\n ChatToolPartViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { ToolCardRoot, ToolCardContent } from './tool-card-root';\nimport { ToolCardHeader } from './tool-card-header';\nimport { ToolCardFileOperationContent } from './tool-card-file-operation';\nimport { ChatTerminalSurface } from './terminal/terminal-panes';\n\nconst TOOL_CARD_AUTO_EXPAND_DELAY_MS = 200;\n\nfunction readNonEmptyString(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n return value.length > 0 ? value : null;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isStructuredTerminalRecord(record: Record<string, unknown>): boolean {\n return (\n 'command' in record ||\n 'workingDir' in record ||\n 'exitCode' in record ||\n 'durationMs' in record ||\n 'stdout' in record ||\n 'stderr' in record ||\n 'aggregated_output' in record ||\n 'combinedOutput' in record\n );\n}\n\nfunction extractTerminalOutputFromRecord(record: Record<string, unknown>): string | null {\n const aggregatedOutput =\n readNonEmptyString(record.aggregated_output) ??\n readNonEmptyString(record.combinedOutput) ??\n readNonEmptyString(record.output);\n if (aggregatedOutput) {\n return aggregatedOutput;\n }\n\n const stdout = readNonEmptyString(record.stdout);\n const stderr = readNonEmptyString(record.stderr);\n if (!stdout && !stderr) {\n return null;\n }\n return [stdout, stderr].filter((value): value is string => Boolean(value)).join('\\n');\n}\n\nfunction normalizeTerminalOutput(rawOutput?: string, structuredOutput?: unknown): string {\n if (isRecord(structuredOutput)) {\n const terminalOutput = extractTerminalOutputFromRecord(structuredOutput);\n if (terminalOutput) {\n return terminalOutput;\n }\n if (isStructuredTerminalRecord(structuredOutput)) {\n return '';\n }\n }\n if (!rawOutput) {\n return '';\n }\n const trimmed = rawOutput.trim();\n if (!trimmed.startsWith('{')) {\n return rawOutput;\n }\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!isRecord(parsed)) {\n return rawOutput;\n }\n const terminalOutput = extractTerminalOutputFromRecord(parsed);\n if (terminalOutput) {\n return terminalOutput;\n }\n if (isStructuredTerminalRecord(parsed)) {\n return '';\n }\n return rawOutput;\n } catch {\n return rawOutput;\n }\n}\n\nfunction shouldAutoExpandRunningFileOperation(toolName: string): boolean {\n return toolName === 'write_file' || toolName === 'edit_file';\n}\n\nfunction countFileOperationChanges(blocks: ChatFileOperationBlockViewModel[]): {\n additions: number;\n deletions: number;\n} {\n return blocks.reduce(\n (totals, block) => ({\n additions:\n totals.additions + block.lines.filter((line) => line.kind === 'add').length,\n deletions:\n totals.deletions + block.lines.filter((line) => line.kind === 'remove').length,\n }),\n { additions: 0, deletions: 0 },\n );\n}\n\nexport function useToolCardExpandedState({\n canExpand,\n isRunning,\n autoExpandWhileRunning = true,\n expandOnError = false,\n statusTone,\n}: {\n canExpand: boolean;\n isRunning: boolean;\n autoExpandWhileRunning?: boolean;\n expandOnError?: boolean;\n statusTone: ChatToolPartViewModel['statusTone'];\n}) {\n const [expanded, setExpanded] = useState(false);\n const [hasUserToggled, setHasUserToggled] = useState(false);\n const expandTimerRef = useRef<number | null>(null);\n const prevRunningRef = useRef(isRunning);\n const isFirstRenderRef = useRef(true);\n\n useEffect(() => {\n return () => {\n if (expandTimerRef.current !== null) {\n window.clearTimeout(expandTimerRef.current);\n }\n };\n }, []);\n\n useEffect(() => {\n if (expandOnError && statusTone === 'error' && canExpand && !hasUserToggled) {\n if (expandTimerRef.current !== null) {\n window.clearTimeout(expandTimerRef.current);\n expandTimerRef.current = null;\n }\n setExpanded(true);\n prevRunningRef.current = isRunning;\n isFirstRenderRef.current = false;\n return;\n }\n\n if (\n autoExpandWhileRunning &&\n isRunning &&\n canExpand &&\n !hasUserToggled &&\n !expanded &&\n (isFirstRenderRef.current || !prevRunningRef.current)\n ) {\n expandTimerRef.current = window.setTimeout(() => {\n setExpanded(true);\n expandTimerRef.current = null;\n }, TOOL_CARD_AUTO_EXPAND_DELAY_MS);\n }\n\n if (!isRunning) {\n if (expandTimerRef.current !== null) {\n window.clearTimeout(expandTimerRef.current);\n expandTimerRef.current = null;\n }\n if (prevRunningRef.current && !hasUserToggled) {\n setExpanded(false);\n }\n }\n\n prevRunningRef.current = isRunning;\n isFirstRenderRef.current = false;\n }, [autoExpandWhileRunning, canExpand, expandOnError, expanded, hasUserToggled, isRunning, statusTone]);\n\n const onToggle = () => {\n if (!canExpand) {\n return;\n }\n if (expandTimerRef.current !== null) {\n window.clearTimeout(expandTimerRef.current);\n expandTimerRef.current = null;\n }\n setExpanded((current) => !current);\n setHasUserToggled(true);\n };\n\n return { expanded, onToggle };\n}\n\nfunction extractTerminalMeta(structuredOutput?: unknown): {\n exitCode?: number | null;\n workingDir?: string | null;\n} {\n if (!isRecord(structuredOutput)) {\n return {};\n }\n const exitCode =\n typeof structuredOutput.exitCode === 'number'\n ? structuredOutput.exitCode\n : typeof structuredOutput.exit_code === 'number'\n ? structuredOutput.exit_code\n : null;\n const workingDir =\n readNonEmptyString(structuredOutput.workingDir) ??\n readNonEmptyString(structuredOutput.cwd) ??\n readNonEmptyString(structuredOutput.working_directory);\n return { exitCode, workingDir };\n}\n\nexport function TerminalExecutionView({ card, toolLabel }: { card: ChatToolPartViewModel; toolLabel?: string }) {\n const output = normalizeTerminalOutput(card.output, card.outputData);\n const isRunning = card.statusTone === 'running';\n const commandPart = card.summary?.replace(/^(command|path|args|query|input):\\s*/i, '');\n const hasOutput = output.trim().length > 0;\n const canExpand = isRunning || hasOutput || Boolean(commandPart?.trim());\n const meta = extractTerminalMeta(card.outputData);\n const { expanded, onToggle } = useToolCardExpandedState({\n canExpand,\n isRunning,\n autoExpandWhileRunning: false,\n expandOnError: canExpand,\n statusTone: card.statusTone,\n });\n\n return (\n <ToolCardRoot>\n <ToolCardHeader\n card={card}\n toolLabel={toolLabel}\n icon={Terminal}\n expanded={expanded}\n canExpand={canExpand}\n onToggle={onToggle}\n />\n {expanded && (\n <ToolCardContent className=\"bg-transparent py-0\">\n <ChatTerminalSurface\n command={commandPart}\n output={output}\n emptyLabel={card.emptyLabel}\n isRunning={isRunning}\n hasOutput={hasOutput}\n isError={card.statusTone === 'error'}\n exitCode={meta.exitCode}\n workingDir={meta.workingDir}\n />\n </ToolCardContent>\n )}\n </ToolCardRoot>\n );\n}\n\nexport function FileOperationView({\n card,\n toolLabel,\n onFileOpen,\n}: {\n card: ChatToolPartViewModel;\n toolLabel?: string;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n}) {\n const output = card.output?.trim() ?? '';\n const isRunning = card.statusTone === 'running';\n const hasStructuredPreview = Boolean(card.fileOperation?.blocks.length);\n const hasContent = hasStructuredPreview || Boolean(output);\n const previewBlocks = card.fileOperation?.blocks ?? [];\n const previewLineCount = previewBlocks.reduce((count, block) => count + block.lines.length, 0);\n const previewCharCount = previewBlocks.reduce((count, block) => {\n if (block.rawText) {\n return count + block.rawText.length;\n }\n return count + block.lines.reduce((lineCount, line) => lineCount + line.text.length + 1, 0);\n }, 0);\n const shouldAutoExpandWhileRunning =\n shouldAutoExpandRunningFileOperation(card.toolName) &&\n !(\n isRunning &&\n card.toolName === 'write_file' &&\n (previewLineCount > 24 || previewCharCount > 1_200)\n );\n const { expanded, onToggle } = useToolCardExpandedState({\n canExpand: hasContent || isRunning,\n isRunning,\n autoExpandWhileRunning: shouldAutoExpandWhileRunning,\n expandOnError: hasContent,\n statusTone: card.statusTone,\n });\n\n const isEdit =\n card.toolName === 'edit_file' ||\n card.toolName === 'write_file' ||\n card.toolName === 'apply_patch' ||\n card.toolName === 'file_change';\n const changeSummary = isEdit\n ? countFileOperationChanges(previewBlocks)\n : undefined;\n\n return (\n <ToolCardRoot>\n <ToolCardHeader\n card={card}\n toolLabel={toolLabel}\n changeSummary={changeSummary}\n icon={isEdit ? Code2 : FileText}\n expanded={expanded}\n canExpand={hasContent || isRunning}\n // Keep overview summary for collapsed scanning.\n hideSummary={false}\n onToggle={onToggle}\n />\n {expanded && hasContent ? (\n <ToolCardContent className=\"bg-transparent py-0\">\n <ToolCardFileOperationContent\n card={card}\n onFileOpen={onFileOpen}\n // Always show the path header in the content panel so users can\n // open the file and still see +N/-N captions (matches prior UX).\n showPathRow\n />\n </ToolCardContent>\n ) : null}\n </ToolCardRoot>\n );\n}\n\nexport function SearchSnippetView({\n card,\n toolLabel,\n icon: Icon = Search,\n}: {\n card: ChatToolPartViewModel;\n toolLabel?: string;\n icon?: LucideIcon;\n}) {\n const isRunning = card.statusTone === 'running';\n const output = card.output?.trim() ?? '';\n const { expanded, onToggle } = useToolCardExpandedState({\n canExpand: !!output || isRunning,\n isRunning,\n autoExpandWhileRunning: false,\n statusTone: card.statusTone,\n });\n\n return (\n <ToolCardRoot>\n <ToolCardHeader \n card={card} \n toolLabel={toolLabel}\n icon={Icon}\n expanded={expanded} \n canExpand={!!output || isRunning} \n onToggle={onToggle} \n />\n {expanded && output && (\n <ToolCardContent className=\"py-0\">\n <pre 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\">\n {output}\n </pre>\n </ToolCardContent>\n )}\n </ToolCardRoot>\n );\n}\n","import { Wrench, type LucideIcon } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport type {\n ChatToolActionViewModel,\n ChatToolPartViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\nimport { ToolCardRoot, ToolCardContent } from './tool-card-root';\nimport { ToolCardHeader, ToolCardHeaderAction } from './tool-card-header';\nimport { useToolCardExpandedState } from './tool-card-views';\n\nfunction GenericToolSection({\n label,\n tone,\n children,\n}: {\n label: string;\n tone: 'input' | 'output' | 'error';\n children: ReactNode;\n}) {\n const tones = {\n input: { dot: 'bg-muted-foreground/60', body: 'text-foreground' },\n output: { dot: 'bg-primary/70', body: 'text-foreground' },\n error: { dot: 'bg-rose-500/80', body: 'text-rose-950/85' },\n } as const;\n const style = tones[tone];\n\n return (\n <section className=\"overflow-hidden rounded-md border border-border/70 bg-muted/20\">\n <div className=\"flex items-center gap-2 border-b border-border/60 px-2.5 py-1.5 text-[10px] font-medium tracking-wide text-muted-foreground\">\n <span className={cn('h-1.5 w-1.5 rounded-full', style.dot)} />\n <span className=\"normal-case tracking-normal\">{label}</span>\n </div>\n <div className=\"w-full overflow-hidden\">\n <pre\n className={cn(\n 'w-full max-w-full min-w-0 max-h-64 overflow-x-auto overflow-y-auto px-2.5 py-2 font-mono text-[12px] leading-relaxed whitespace-pre custom-scrollbar',\n style.body,\n )}\n >\n {children}\n </pre>\n </div>\n </section>\n );\n}\n\nfunction buildToolActionSlot(\n card: ChatToolPartViewModel,\n onToolAction?: (action: ChatToolActionViewModel) => void,\n renderToolAgent?: (agentId: string) => ReactNode,\n): ReactNode | undefined {\n const agentAction = card.agentId && renderToolAgent\n ? renderToolAgent(card.agentId)\n : null;\n const toolAction = card.action && onToolAction\n ? <ToolCardHeaderAction action={card.action} onAction={onToolAction} />\n : null;\n return agentAction || toolAction ? <>{agentAction}{toolAction}</> : undefined;\n}\n\nexport function GenericToolCard({\n card,\n toolLabel,\n icon: Icon = Wrench,\n onToolAction,\n renderToolAgent,\n}: {\n card: ChatToolPartViewModel;\n toolLabel?: string;\n icon?: LucideIcon;\n onToolAction?: (action: ChatToolActionViewModel) => void;\n renderToolAgent?: (agentId: string) => ReactNode;\n}) {\n const input = card.input?.trim() ?? '';\n const output = card.output?.trim() ?? '';\n const isRunning = card.statusTone === 'running';\n const hasInputSection = input.length > 0;\n const hasOutputSection = output.length > 0;\n const hasContent = hasInputSection || hasOutputSection;\n const actionSlot = buildToolActionSlot(card, onToolAction, renderToolAgent);\n const { expanded, onToggle } = useToolCardExpandedState({\n canExpand: hasContent || isRunning,\n isRunning,\n autoExpandWhileRunning: false,\n statusTone: card.statusTone,\n });\n\n return (\n <ToolCardRoot>\n <ToolCardHeader\n card={card}\n toolLabel={toolLabel}\n icon={Icon}\n expanded={expanded}\n canExpand={hasContent || isRunning}\n actionSlot={actionSlot}\n onToggle={onToggle}\n />\n {expanded && hasContent ? (\n <ToolCardContent className=\"bg-transparent py-0\">\n {hasInputSection ? (\n <GenericToolSection label={card.inputLabel?.trim() || 'Input'} tone=\"input\">\n {input}\n </GenericToolSection>\n ) : null}\n {hasInputSection && hasOutputSection ? <div className=\"h-2\" /> : null}\n {hasOutputSection ? (\n <GenericToolSection\n label={card.outputLabel?.trim() || 'Output'}\n tone={card.statusTone === 'error' ? 'error' : 'output'}\n >\n {output}\n </GenericToolSection>\n ) : null}\n </ToolCardContent>\n ) : null}\n </ToolCardRoot>\n );\n}\n","import type { ReactNode } from 'react';\nimport type {\n ChatPanelAppCardViewModel,\n ChatToolActionViewModel,\n ChatToolPartViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { GenericToolCard } from './tool-card-generic';\n\nexport function PanelAppInlineToolCard({\n card,\n onToolAction,\n renderPanelAppCard,\n}: {\n card: ChatToolPartViewModel;\n onToolAction?: (action: ChatToolActionViewModel) => void;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n}) {\n const { panelApp } = card;\n if (!panelApp) {\n return <GenericToolCard card={card} onToolAction={onToolAction} />;\n }\n if (renderPanelAppCard) {\n return renderPanelAppCard(panelApp);\n }\n\n return <GenericToolCard card={card} onToolAction={onToolAction} />;\n}\n","import type {\n ChatFileOpenActionViewModel,\n ChatPanelAppCardViewModel,\n ChatBuiltInToolStatusKind,\n ChatMessageTexts,\n ChatToolActionViewModel,\n ChatToolPartViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport {\n Bot,\n Brain,\n CalendarClock,\n Eye,\n FolderTree,\n Globe2,\n ImageIcon,\n MessageSquare,\n Send,\n Settings,\n type LucideIcon,\n} from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { TerminalExecutionView, FileOperationView, SearchSnippetView, GenericToolCard, PanelAppInlineToolCard } from './chat-tool-specialized';\n\nfunction isTerminalTool(name: string) {\n const lowered = name.toLowerCase();\n return lowered === 'exec' || lowered === 'exec_command' || lowered === 'execute_command' || lowered === 'command_execution' || lowered === 'bash' || lowered === 'shell' || lowered.includes('run_');\n}\n\nfunction isFileTool(name: string) {\n const lowered = name.toLowerCase();\n return lowered === 'read_file' || lowered === 'write_file' || lowered === 'edit_file' || lowered === 'apply_patch' || lowered === 'file_change';\n}\n\nfunction isFileWriteTool(name: string) {\n const lowered = name.toLowerCase();\n return lowered === 'write_file' || lowered === 'edit_file' || lowered === 'apply_patch' || lowered === 'file_change';\n}\n\nfunction isSearchTool(name: string) {\n const lowered = name.toLowerCase();\n return lowered === 'grep_search' || lowered === 'find_files' || lowered.includes('search');\n}\n\ntype BuiltInToolPresentation = {\n statusKind: ChatBuiltInToolStatusKind;\n icon: LucideIcon;\n};\n\nconst BUILT_IN_TOOL_PRESENTATIONS: Record<string, BuiltInToolPresentation> = {\n list_dir: { statusKind: 'directory', icon: FolderTree },\n web_fetch: { statusKind: 'web', icon: Globe2 },\n message: { statusKind: 'message', icon: Send },\n sessions_list: { statusKind: 'session', icon: MessageSquare },\n sessions_history: { statusKind: 'session', icon: MessageSquare },\n sessions_request: { statusKind: 'session', icon: MessageSquare },\n spawn: { statusKind: 'agent', icon: Bot },\n sessions_spawn: { statusKind: 'agent', icon: Bot },\n subagents: { statusKind: 'agent', icon: Bot },\n memory_search: { statusKind: 'memory', icon: Brain },\n memory_get: { statusKind: 'memory', icon: Brain },\n cron: { statusKind: 'schedule', icon: CalendarClock },\n gateway: { statusKind: 'system', icon: Settings },\n view_image: { statusKind: 'image', icon: ImageIcon },\n show_file: { statusKind: 'display', icon: Eye },\n show_url: { statusKind: 'display', icon: Eye },\n show_panel_app: { statusKind: 'display', icon: Eye },\n show_content: { statusKind: 'display', icon: Eye },\n};\n\nfunction resolveBuiltInToolPresentation(name: string): BuiltInToolPresentation | null {\n return BUILT_IN_TOOL_PRESENTATIONS[name.toLowerCase()] ?? null;\n}\n\nexport function ChatToolCard({\n card,\n toolStatusLabels,\n onToolAction,\n onFileOpen,\n renderToolAgent,\n renderPanelAppCard,\n}: {\n card: ChatToolPartViewModel;\n toolStatusLabels?: ChatMessageTexts['toolStatusLabels'];\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n}) {\n if (card.panelApp) {\n return (\n <PanelAppInlineToolCard\n card={card}\n onToolAction={onToolAction}\n renderPanelAppCard={renderPanelAppCard}\n />\n );\n }\n const builtInPresentation = resolveBuiltInToolPresentation(card.toolName);\n const builtInLabel = builtInPresentation\n ? toolStatusLabels?.builtIn?.[builtInPresentation.statusKind]?.[card.statusTone]\n : undefined;\n if (isTerminalTool(card.toolName)) {\n return <TerminalExecutionView card={card} toolLabel={toolStatusLabels?.terminal[card.statusTone]} />;\n }\n if (isFileTool(card.toolName)) {\n const toolLabel = isFileWriteTool(card.toolName)\n ? toolStatusLabels?.fileEdit[card.statusTone]\n : toolStatusLabels?.fileRead[card.statusTone];\n return <FileOperationView card={card} toolLabel={toolLabel} onFileOpen={onFileOpen} />;\n }\n if (isSearchTool(card.toolName)) {\n return (\n <SearchSnippetView\n card={card}\n toolLabel={builtInLabel ?? toolStatusLabels?.search[card.statusTone]}\n icon={builtInPresentation?.icon}\n />\n );\n }\n\n // Fallback minimalist card for read_url_content, multi_replace, etc.\n return (\n <GenericToolCard\n card={card}\n toolLabel={builtInLabel}\n icon={builtInPresentation?.icon}\n onToolAction={onToolAction}\n renderToolAgent={renderToolAgent}\n />\n );\n}\n","import type {\n ChatFileOpenActionViewModel,\n ChatPanelAppCardViewModel,\n ChatToolActionViewModel,\n ChatMessageTexts,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport { useState, type ReactNode } from \"react\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { ChatToolCard } from \"./chat-tool-card\";\nimport { ChatCollapsibleMetaSummary } from \"./chat-collapsible-meta-summary\";\nimport { ChatReasoningBlock } from \"./chat-reasoning-block\";\nimport type { ChatToolActivityGroupViewModel } from \"./chat-tool-activity-group.utils\";\n\nexport function ChatToolActivityGroup({\n group,\n isUser,\n reasoningCharacterCountTemplates,\n toolStatusLabels,\n onToolAction,\n onFileOpen,\n renderToolAgent,\n renderPanelAppCard,\n}: {\n group: ChatToolActivityGroupViewModel;\n isUser: boolean;\n reasoningCharacterCountTemplates?: ChatMessageTexts[\"reasoningCharacterCountTemplates\"];\n toolStatusLabels?: ChatMessageTexts[\"toolStatusLabels\"];\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n}) {\n const [open, setOpen] = useState(false);\n const toolCount = group.parts.filter((part) => part.type === \"tool-card\").length;\n const showWorkflowRail = open && toolCount > 1;\n\n return (\n <div className=\"group/tool-activity\">\n <ChatCollapsibleMetaSummary\n openGroup=\"tool-activity\"\n open={open}\n label={group.label}\n onClick={() => setOpen((current) => !current)}\n />\n {open ? (\n <div className=\"text-[0.925rem] leading-[1.72]\">\n {group.parts.map((part, index) => {\n const isLast = index === group.parts.length - 1;\n return (\n <div\n key={`tool-group-item-${group.startIndex + index}`}\n className=\"relative min-w-0\"\n >\n {showWorkflowRail ? (\n <div\n aria-hidden=\"true\"\n data-tool-workflow-rail=\"true\"\n className={cn(\n \"pointer-events-none absolute left-[0.575em] w-px -translate-x-1/2 bg-border/70\",\n index === 0\n ? \"bottom-0 top-[0.86em]\"\n : isLast\n ? \"top-0 h-[0.86em]\"\n : \"inset-y-0\",\n )}\n />\n ) : null}\n {part.type === \"tool-card\" ? (\n <ChatToolCard\n card={part.card}\n toolStatusLabels={toolStatusLabels}\n onToolAction={onToolAction}\n onFileOpen={onFileOpen}\n renderToolAgent={renderToolAgent}\n renderPanelAppCard={renderPanelAppCard}\n />\n ) : (\n <div className=\"pl-[calc(1.15em+0.375rem)]\">\n <ChatReasoningBlock\n label={part.label}\n text={part.text}\n characterCountTemplates={reasoningCharacterCountTemplates}\n isUser={isUser}\n isInProgress={false}\n />\n </div>\n )}\n </div>\n );\n })}\n </div>\n ) : null}\n </div>\n );\n}\n","import type {\n ChatMessagePartViewModel,\n ChatToolPartViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\n\nexport type ChatToolActivityFamily =\n | \"read\"\n | \"edit\"\n | \"directory\"\n | \"search\"\n | \"bash\"\n | \"web\"\n | \"agent\"\n | \"panel\"\n | \"other\";\n\nexport type ChatToolActivityTone = \"success\" | \"error\" | \"cancelled\" | \"running\";\n\ntype ChatToolCardPart = Extract<ChatMessagePartViewModel, { type: \"tool-card\" }>;\ntype ChatToolGroupPart = Extract<\n ChatMessagePartViewModel,\n { type: \"tool-card\" | \"reasoning\" }\n>;\n\nexport type ChatToolActivitySegment = {\n family: ChatToolActivityFamily;\n count: number;\n tone: ChatToolActivityTone;\n};\n\ntype ActivityAccumulator = { units: Set<string>; tone: ChatToolActivityTone };\n\nexport type ChatToolActivityGroupViewModel = {\n key: string;\n startIndex: number;\n endIndex: number;\n parts: ChatToolGroupPart[];\n segments: ChatToolActivitySegment[];\n label: string;\n};\n\nexport type ChatToolActivityGroupLabels = {\n /** Full natural phrases. `one` is singular; `other` uses `{count}`. */\n segmentTemplates: Record<\n ChatToolActivityFamily,\n {\n one: string;\n other: string;\n }\n >;\n failedLabel: string;\n cancelledLabel: string;\n};\n\nexport type ChatMessageRenderBlock =\n | {\n kind: \"part\";\n key: string;\n index: number;\n part: ChatMessagePartViewModel;\n }\n | {\n kind: \"tool-group\";\n key: string;\n group: ChatToolActivityGroupViewModel;\n };\n\nconst MAX_SUMMARY_SEGMENTS = 3;\n\nfunction isToolCardPart(part: ChatToolGroupPart): part is ChatToolCardPart {\n return part.type === \"tool-card\";\n}\n\nexport function resolveToolActivityFamily(toolName: string): ChatToolActivityFamily {\n const lowered = toolName.toLowerCase();\n if (lowered === \"list_dir\") {\n return \"directory\";\n }\n if (\n lowered.includes(\"show_content\") ||\n lowered.includes(\"panel_app\") ||\n lowered.includes(\"panel\")\n ) {\n return \"panel\";\n }\n if (\n lowered === \"spawn\" ||\n lowered.includes(\"subagent\") ||\n lowered.includes(\"session_request\") ||\n (lowered.includes(\"agent\") && !lowered.includes(\"read\"))\n ) {\n return \"agent\";\n }\n if (\n lowered.includes(\"web_\") ||\n lowered.includes(\"_web\") ||\n lowered.includes(\"url\") ||\n lowered.includes(\"fetch\") ||\n lowered.includes(\"http\")\n ) {\n return \"web\";\n }\n if (\n lowered === \"grep_search\" ||\n lowered === \"find_files\" ||\n lowered === \"search_files\" ||\n lowered.includes(\"search\") ||\n lowered.includes(\"grep\")\n ) {\n return \"search\";\n }\n if (\n lowered === \"exec\" ||\n lowered === \"exec_command\" ||\n lowered === \"execute_command\" ||\n lowered === \"command_execution\" ||\n lowered === \"bash\" ||\n lowered === \"shell\" ||\n lowered === \"terminal\" ||\n lowered.includes(\"run_\")\n ) {\n return \"bash\";\n }\n if (\n lowered === \"write_file\" ||\n lowered === \"edit_file\" ||\n lowered === \"apply_patch\" ||\n lowered === \"file_change\" ||\n lowered === \"multi_replace\" ||\n lowered.includes(\"write_file\") ||\n lowered.includes(\"edit_file\") ||\n lowered.includes(\"apply_patch\")\n ) {\n return \"edit\";\n }\n if (\n lowered === \"read_file\" ||\n lowered === \"read\" ||\n lowered === \"view_file\" ||\n lowered.includes(\"read_file\") ||\n lowered.startsWith(\"read_\")\n ) {\n return \"read\";\n }\n return \"other\";\n}\n\nfunction toneRank(tone: ChatToolActivityTone): number {\n if (tone === \"error\") return 0;\n if (tone === \"cancelled\") return 1;\n if (tone === \"running\") return 2;\n return 3;\n}\n\nfunction resolveActivityUnitKeys(\n card: ChatToolPartViewModel,\n family: ChatToolActivityFamily,\n callIndex: number,\n): string[] {\n if (family !== \"read\" && family !== \"edit\" && family !== \"directory\") {\n return [`call:${callIndex}`];\n }\n const paths = card.fileOperation?.blocks.map(({ path }) => path.trim()).filter(Boolean);\n const summary = card.summary?.replace(/^(path|file):\\s*/i, \"\").trim();\n return paths?.length ? paths : [summary || `call:${callIndex}`];\n}\n\n/**\n * Natural category+count phrases only.\n * Examples: `Read 3 files`, `运行 2 条命令`, `搜索 2 次`.\n * No command/path payload.\n */\nfunction formatSegment(\n segment: ChatToolActivitySegment,\n labels: ChatToolActivityGroupLabels,\n): string {\n const template = labels.segmentTemplates[segment.family];\n const body =\n segment.count === 1\n ? template.one\n : template.other.split(\"{count}\").join(String(segment.count));\n\n if (segment.tone === \"error\") {\n return `${body} ${labels.failedLabel}`;\n }\n if (segment.tone === \"cancelled\") {\n return `${body} ${labels.cancelledLabel}`;\n }\n return body;\n}\n\nexport function buildToolActivitySegments(\n cards: ChatToolPartViewModel[],\n): ChatToolActivitySegment[] {\n const order: ChatToolActivityFamily[] = [];\n const byFamily = new Map<ChatToolActivityFamily, ActivityAccumulator>();\n\n for (const [callIndex, card] of cards.entries()) {\n const family = resolveToolActivityFamily(card.toolName);\n const unitKeys = resolveActivityUnitKeys(card, family, callIndex);\n const existing = byFamily.get(family);\n if (!existing) {\n order.push(family);\n byFamily.set(family, {\n units: new Set(unitKeys),\n tone: card.statusTone,\n });\n continue;\n }\n unitKeys.forEach((unitKey) => existing.units.add(unitKey));\n if (toneRank(card.statusTone) < toneRank(existing.tone)) {\n existing.tone = card.statusTone;\n }\n }\n\n const segments = order.map((family) => {\n const entry = byFamily.get(family)!;\n return {\n family,\n count: entry.units.size,\n tone: entry.tone,\n } satisfies ChatToolActivitySegment;\n });\n\n segments.sort((left, right) => {\n const toneDelta = toneRank(left.tone) - toneRank(right.tone);\n if (toneDelta !== 0) {\n return toneDelta;\n }\n return order.indexOf(left.family) - order.indexOf(right.family);\n });\n\n return segments;\n}\n\nexport function formatToolActivityGroupLabel(params: {\n segments: ChatToolActivitySegment[];\n labels: ChatToolActivityGroupLabels;\n}): string {\n const { labels, segments } = params;\n if (segments.length === 0) {\n return \"\";\n }\n const visible = segments.slice(0, MAX_SUMMARY_SEGMENTS);\n const hiddenCount = segments.length - visible.length;\n const parts = visible.map((segment) => formatSegment(segment, labels));\n if (hiddenCount > 0) {\n parts.push(`+${hiddenCount}`);\n }\n return parts.join(\" · \");\n}\n\n/**\n * Group tool cards separated only by reasoning into one visible workflow.\n * Markdown, files and unknown parts still break the run.\n * Single tool-cards stay ungrouped so they keep their native card UI.\n */\nexport function groupConsecutiveToolParts(\n parts: ChatMessagePartViewModel[],\n labels: ChatToolActivityGroupLabels,\n): ChatMessageRenderBlock[] {\n const blocks: ChatMessageRenderBlock[] = [];\n let index = 0;\n\n while (index < parts.length) {\n const part = parts[index]!;\n if (part.type !== \"tool-card\") {\n blocks.push({\n kind: \"part\",\n key: `part-${index}`,\n index,\n part,\n });\n index += 1;\n continue;\n }\n\n const startIndex = index;\n const candidateParts: ChatToolGroupPart[] = [];\n let lastToolOffset = -1;\n while (\n index < parts.length &&\n (parts[index]?.type === \"tool-card\" || parts[index]?.type === \"reasoning\")\n ) {\n const candidate = parts[index] as ChatToolGroupPart;\n candidateParts.push(candidate);\n if (candidate.type === \"tool-card\") {\n lastToolOffset = candidateParts.length - 1;\n }\n index += 1;\n }\n\n const toolParts = candidateParts.filter(isToolCardPart);\n if (toolParts.length === 1) {\n blocks.push({\n kind: \"part\",\n key: `part-${startIndex}`,\n index: startIndex,\n part,\n });\n index = startIndex + 1;\n continue;\n }\n\n const groupedParts = candidateParts.slice(0, lastToolOffset + 1);\n index = startIndex + groupedParts.length;\n const cards = toolParts.map((toolPart) => toolPart.card);\n const segments = buildToolActivitySegments(cards);\n const label = formatToolActivityGroupLabel({ segments, labels });\n blocks.push({\n kind: \"tool-group\",\n key: `tool-group-${startIndex}-${index - 1}`,\n group: {\n key: `tool-group-${startIndex}-${index - 1}`,\n startIndex,\n endIndex: index - 1,\n parts: groupedParts,\n segments,\n label,\n },\n });\n }\n\n return blocks;\n}\n","import { memo, useState, type ReactNode } from \"react\";\nimport type {\n ChatFileOpenActionViewModel,\n ChatInlineDisplayViewModel,\n ChatInlineTokenViewModel,\n ChatPanelAppCardViewModel,\n ChatMessageTexts,\n ChatMessagePartViewModel,\n ChatToolActionViewModel,\n ChatMessageViewModel,\n} from \"@agent-chat-ui/components/chat/view-models/chat-ui.types\";\nimport { cn } from \"@agent-chat-ui/components/chat/internal/cn\";\nimport { ChatMessageMarkdown } from \"./chat-message-markdown\";\nimport { ChatMessageFile } from \"./chat-message-file\";\nimport { ChatReasoningBlock } from \"./chat-reasoning-block\";\nimport { ChatToolCard } from \"./chat-tool-card\";\nimport { ChatToolActivityGroup } from \"./chat-tool-activity-group\";\nimport { ChatCollapsibleMetaSummary } from \"./chat-collapsible-meta-summary\";\nimport {\n groupConsecutiveToolParts,\n type ChatToolActivityGroupLabels,\n} from \"./chat-tool-activity-group.utils\";\n\ntype ChatMessageProps = {\n message: ChatMessageViewModel;\n texts: Pick<\n ChatMessageTexts,\n | \"copyCodeLabel\"\n | \"copiedCodeLabel\"\n | \"attachmentOpenLabel\"\n | \"attachmentAttachedLabel\"\n | \"attachmentCategoryLabels\"\n | \"toolActivitySegmentTemplates\"\n | \"toolActivityFailedLabel\"\n | \"toolActivityCancelledLabel\"\n | \"reasoningCharacterCountTemplates\"\n | \"toolStatusLabels\"\n >;\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n onAttachmentOpen?: (file: Extract<ChatMessagePartViewModel, { type: \"file\" }>[\"file\"]) => void;\n onInlineTokenClick?: (token: ChatInlineTokenViewModel) => void;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n};\n\ntype ChatMessageProcessSplit = {\n processParts: ChatMessagePartViewModel[];\n finalParts: ChatMessagePartViewModel[];\n};\n\ntype RenderChatMessagePartParams = {\n part: ChatMessagePartViewModel;\n index: number;\n role: ChatMessageViewModel[\"role\"];\n isUser: boolean;\n isInProgress: boolean;\n isLastPart: boolean;\n texts: ChatMessageProps[\"texts\"];\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n onAttachmentOpen?: (file: Extract<ChatMessagePartViewModel, { type: \"file\" }>[\"file\"]) => void;\n onInlineTokenClick?: (token: ChatInlineTokenViewModel) => void;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n};\n\nconst DEFAULT_TOOL_ACTIVITY_LABELS: ChatToolActivityGroupLabels = {\n segmentTemplates: {\n read: { one: \"Read 1 file\", other: \"Read {count} files\" },\n edit: { one: \"Edit 1 file\", other: \"Edit {count} files\" },\n directory: { one: \"View 1 directory\", other: \"View {count} directories\" },\n search: { one: \"Search 1 time\", other: \"Search {count} times\" },\n bash: { one: \"Run 1 command\", other: \"Run {count} commands\" },\n web: { one: \"Open 1 page\", other: \"Open {count} pages\" },\n agent: { one: \"Start 1 subtask\", other: \"Start {count} subtasks\" },\n panel: { one: \"Show 1 result\", other: \"Show {count} results\" },\n other: { one: \"Use 1 tool\", other: \"Use {count} tools\" },\n },\n failedLabel: \"failed\",\n cancelledLabel: \"cancelled\",\n};\n\nfunction resolveToolActivityLabels(\n texts: ChatMessageProps[\"texts\"],\n): ChatToolActivityGroupLabels {\n return {\n segmentTemplates: {\n ...DEFAULT_TOOL_ACTIVITY_LABELS.segmentTemplates,\n ...(texts.toolActivitySegmentTemplates ?? {}),\n },\n failedLabel:\n texts.toolActivityFailedLabel ?? DEFAULT_TOOL_ACTIVITY_LABELS.failedLabel,\n cancelledLabel:\n texts.toolActivityCancelledLabel ??\n DEFAULT_TOOL_ACTIVITY_LABELS.cancelledLabel,\n };\n}\n\nfunction isMessageInProgress(status?: string): boolean {\n return status === \"pending\" || status === \"streaming\";\n}\n\nfunction isProcessPart(part: ChatMessagePartViewModel): boolean {\n return part.type === \"reasoning\" || part.type === \"tool-card\";\n}\n\nfunction splitAssistantProcess(message: ChatMessageViewModel): ChatMessageProcessSplit | null {\n if (\n message.role !== \"assistant\" ||\n !message.processSummary ||\n isMessageInProgress(message.status)\n ) {\n return null;\n }\n let lastProcessPartIndex = -1;\n for (let index = message.parts.length - 1; index >= 0; index -= 1) {\n if (isProcessPart(message.parts[index]!)) {\n lastProcessPartIndex = index;\n break;\n }\n }\n if (lastProcessPartIndex < 0 || lastProcessPartIndex >= message.parts.length - 1) {\n return null;\n }\n return {\n processParts: message.parts.slice(0, lastProcessPartIndex + 1),\n finalParts: message.parts.slice(lastProcessPartIndex + 1),\n };\n}\n\nfunction renderChatMessagePart({\n index,\n isInProgress,\n isLastPart,\n isUser,\n onAttachmentOpen,\n onFileOpen,\n onInlineTokenClick,\n onToolAction,\n part,\n renderInlineDisplay,\n renderPanelAppCard,\n renderToolAgent,\n role,\n texts,\n}: RenderChatMessagePartParams): ReactNode {\n const { type } = part;\n\n if (type === \"markdown\") {\n const { inlineTokens, text } = part;\n return (\n <ChatMessageMarkdown\n key={`markdown-${index}`}\n text={text}\n role={role}\n texts={texts}\n inlineTokens={inlineTokens}\n onFileOpen={onFileOpen}\n onInlineTokenClick={onInlineTokenClick}\n renderInlineDisplay={renderInlineDisplay}\n />\n );\n }\n if (type === \"reasoning\") {\n const { label, text } = part;\n return (\n <ChatReasoningBlock\n key={`reasoning-${index}`}\n label={label}\n text={text}\n characterCountTemplates={texts.reasoningCharacterCountTemplates}\n isUser={isUser}\n isInProgress={isInProgress && isLastPart}\n />\n );\n }\n if (type === \"tool-card\") {\n const { card } = part;\n return (\n <div key={`tool-${index}`}>\n <ChatToolCard\n card={card}\n toolStatusLabels={texts.toolStatusLabels}\n onToolAction={onToolAction}\n onFileOpen={onFileOpen}\n renderToolAgent={renderToolAgent}\n renderPanelAppCard={renderPanelAppCard}\n />\n </div>\n );\n }\n if (type === \"file\") {\n const { file } = part;\n return (\n <ChatMessageFile\n key={`file-${index}`}\n file={file}\n isUser={isUser}\n texts={texts}\n onOpen={onAttachmentOpen}\n />\n );\n }\n if (type === \"unknown\") {\n const { label, rawType, text } = part;\n return (\n <div\n key={`unknown-${index}`}\n className=\"rounded-lg border border-border bg-muted/60 px-2.5 py-2 text-xs text-muted-foreground\"\n >\n <div className=\"font-semibold text-foreground\">\n {label}: {rawType}\n </div>\n {text ? <pre className=\"mt-1 whitespace-pre-wrap break-words text-[11px] text-muted-foreground\">{text}</pre> : null}\n </div>\n );\n }\n return null;\n}\n\nfunction renderMessageParts(params: {\n parts: ChatMessagePartViewModel[];\n role: ChatMessageViewModel[\"role\"];\n isUser: boolean;\n isInProgress: boolean;\n texts: ChatMessageProps[\"texts\"];\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n onAttachmentOpen?: (file: Extract<ChatMessagePartViewModel, { type: \"file\" }>[\"file\"]) => void;\n onInlineTokenClick?: (token: ChatInlineTokenViewModel) => void;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n indexOffset?: number;\n}): ReactNode[] {\n const {\n isInProgress,\n isUser,\n onAttachmentOpen,\n onFileOpen,\n onInlineTokenClick,\n onToolAction,\n parts,\n renderInlineDisplay,\n renderPanelAppCard,\n renderToolAgent,\n role,\n texts,\n indexOffset = 0,\n } = params;\n const labels = resolveToolActivityLabels(texts);\n const blocks = groupConsecutiveToolParts(parts, labels);\n\n return blocks.map((block) => {\n if (block.kind === \"tool-group\") {\n return (\n <ChatToolActivityGroup\n key={block.key}\n group={block.group}\n isUser={isUser}\n reasoningCharacterCountTemplates={texts.reasoningCharacterCountTemplates}\n toolStatusLabels={texts.toolStatusLabels}\n onToolAction={onToolAction}\n onFileOpen={onFileOpen}\n renderToolAgent={renderToolAgent}\n renderPanelAppCard={renderPanelAppCard}\n />\n );\n }\n\n return renderChatMessagePart({\n part: block.part,\n index: indexOffset + block.index,\n role,\n isUser,\n isInProgress,\n isLastPart: indexOffset + block.index === indexOffset + parts.length - 1,\n texts,\n onToolAction,\n onFileOpen,\n onAttachmentOpen,\n onInlineTokenClick,\n renderInlineDisplay,\n renderToolAgent,\n renderPanelAppCard,\n });\n });\n}\n\nexport const ChatMessage = memo(function ChatMessage({\n message,\n texts,\n onToolAction,\n onFileOpen,\n onAttachmentOpen,\n onInlineTokenClick,\n renderInlineDisplay,\n renderToolAgent,\n renderPanelAppCard,\n}: ChatMessageProps) {\n const { role } = message;\n const isUser = role === \"user\";\n const isInProgress = isMessageInProgress(message.status);\n const processSplit = splitAssistantProcess(message);\n // Controlled collapse avoids native <details>/<summary> UA labels like \"详情\".\n const [processOpen, setProcessOpen] = useState(false);\n\n return (\n <div\n className={cn(\n \"inline-block w-fit max-w-full rounded-2xl border px-4 shadow-sm has-[[data-chat-message-wide-content=true]]:w-full\",\n isUser\n ? \"nextclaw-chat-message-user rounded-[1.45rem] border-primary bg-primary py-2.5 text-primary-foreground shadow-none\"\n : role === \"assistant\"\n ? \"border-border bg-card pb-3 pt-4 text-card-foreground\"\n : \"border-border bg-muted/45 py-3 text-foreground\",\n )}\n >\n <div className=\"space-y-0\">\n {processSplit ? (\n <>\n <div className=\"group/process\">\n <div className=\"mb-2 border-b border-border/60 pb-2\">\n <ChatCollapsibleMetaSummary\n openGroup=\"process\"\n open={processOpen}\n label={message.processSummary?.label}\n onClick={() => setProcessOpen((current) => !current)}\n />\n </div>\n {processOpen ? (\n <div className=\"space-y-0\">\n {renderMessageParts({\n parts: processSplit.processParts,\n role,\n isUser,\n isInProgress,\n texts,\n onToolAction,\n onFileOpen,\n onAttachmentOpen,\n onInlineTokenClick,\n renderInlineDisplay,\n renderToolAgent,\n renderPanelAppCard,\n })}\n </div>\n ) : null}\n </div>\n {renderMessageParts({\n parts: processSplit.finalParts,\n role,\n isUser,\n isInProgress,\n texts,\n onToolAction,\n onFileOpen,\n onAttachmentOpen,\n onInlineTokenClick,\n renderInlineDisplay,\n renderToolAgent,\n renderPanelAppCard,\n indexOffset: processSplit.processParts.length,\n })}\n </>\n ) : (\n renderMessageParts({\n parts: message.parts,\n role,\n isUser,\n isInProgress,\n texts,\n onToolAction,\n onFileOpen,\n onAttachmentOpen,\n onInlineTokenClick,\n renderInlineDisplay,\n renderToolAgent,\n renderPanelAppCard,\n })\n )}\n </div>\n </div>\n );\n});\n","import { useMemo } from 'react';\nimport { useCopyFeedback } from '@agent-chat-ui/components/chat/hooks/use-copy-feedback';\nimport { Check, Copy } from 'lucide-react';\nimport type { ChatMessageViewModel, ChatMessageTexts } from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\n\nexport function ChatMessageActionCopy({\n message,\n texts,\n}: {\n message: ChatMessageViewModel;\n texts: Pick<ChatMessageTexts, 'copyMessageLabel' | 'copiedMessageLabel'>;\n}) {\n const messageText = useMemo(() => {\n return message.parts\n .map((part) => {\n if (part.type === 'markdown') return part.text;\n if (part.type === 'unknown') return part.text;\n return '';\n })\n .filter((text) => !!text && text.trim().length > 0)\n .join('\\n\\n');\n }, [message.parts]);\n\n const { copied, copy } = useCopyFeedback({ text: messageText });\n\n if (!messageText) return null;\n\n return (\n <button\n type=\"button\"\n onClick={() => void copy()}\n className=\"text-muted-foreground hover:text-foreground transition-colors p-1 rounded-md hover:bg-accent flex items-center justify-center\"\n aria-label={copied ? texts.copiedMessageLabel : texts.copyMessageLabel}\n title={copied ? texts.copiedMessageLabel : texts.copyMessageLabel}\n >\n {copied ? <Check className=\"h-3.5 w-3.5\" /> : <Copy className=\"h-3.5 w-3.5\" />}\n </button>\n );\n}\n","import type { ReactNode } from 'react';\nimport type {\n ChatFileOpenActionViewModel,\n ChatInlineDisplayViewModel,\n ChatInlineTokenViewModel,\n ChatMessageTexts,\n ChatMessageViewModel,\n ChatPanelAppCardViewModel,\n ChatToolActionViewModel,\n} from '@agent-chat-ui/components/chat/view-models/chat-ui.types';\nimport { cn } from '@agent-chat-ui/components/chat/internal/cn';\nimport { ChatMessageAvatar } from './chat-message-avatar';\nimport { ChatMessage } from './chat-message';\nimport { ChatMessageActionCopy } from './chat-message-action-copy';\n\nconst INVISIBLE_ONLY_TEXT_PATTERN = /\\u200B|\\u200C|\\u200D|\\u2060|\\uFEFF/g;\nconst TYPING_TEXT_SHEEN_CSS = `\n@keyframes nextclaw-chat-typing-text-sheen {\n 0% {\n background-position: 160% 0;\n }\n 100% {\n background-position: -60% 0;\n }\n}\n\n.nextclaw-chat-typing-indicator__text {\n background-image: linear-gradient(\n 100deg,\n hsl(var(--muted-foreground)) 0%,\n hsl(var(--muted-foreground)) 34%,\n hsl(var(--foreground-tertiary)) 43%,\n hsl(var(--foreground-muted)) 50%,\n hsl(var(--foreground-tertiary)) 57%,\n hsl(var(--muted-foreground)) 66%,\n hsl(var(--muted-foreground)) 100%\n );\n background-size: 240% 100%;\n background-position: 160% 0;\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n -webkit-text-fill-color: transparent;\n animation: nextclaw-chat-typing-text-sheen 2.5s linear infinite;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .nextclaw-chat-typing-indicator__text {\n animation: none;\n background-image: none;\n color: hsl(var(--muted-foreground));\n -webkit-text-fill-color: currentColor;\n }\n}\n`;\n\nfunction hasRenderableText(value: string): boolean {\n const trimmed = value.trim();\n if (!trimmed) {\n return false;\n }\n return trimmed.replace(INVISIBLE_ONLY_TEXT_PATTERN, '').trim().length > 0;\n}\n\nexport type ChatMessageListProps = {\n messages: ChatMessageViewModel[];\n isSending: boolean;\n hasAssistantDraft: boolean;\n texts: ChatMessageTexts;\n className?: string;\n onToolAction?: (action: ChatToolActionViewModel) => void;\n onFileOpen?: (action: ChatFileOpenActionViewModel) => void;\n onAttachmentOpen?: (\n file: Extract<ChatMessageViewModel[\"parts\"][number], { type: \"file\" }>[\"file\"],\n ) => void;\n onInlineTokenClick?: (token: ChatInlineTokenViewModel) => void;\n renderInlineDisplay?: (\n display: ChatInlineDisplayViewModel,\n ) => ReactNode | undefined;\n renderToolAgent?: (agentId: string) => ReactNode;\n renderPanelAppCard?: (panelApp: ChatPanelAppCardViewModel) => ReactNode;\n};\n\nfunction hasRenderableMessageContent(message: ChatMessageViewModel): boolean {\n return message.parts.some((part) => {\n if (part.type === 'markdown' || part.type === 'reasoning') {\n return hasRenderableText(part.text);\n }\n return true;\n });\n}\n\nfunction ChatMessageTypingFooter() {\n return (\n <div className=\"flex items-center gap-2 px-1 py-0.5 text-[11px] text-muted-foreground\">\n <div className=\"flex space-x-1 items-center h-full\">\n <div className=\"h-1.5 w-1.5 rounded-full bg-muted-foreground animate-pulse\"></div>\n <div className=\"h-1.5 w-1.5 rounded-full bg-muted-foreground animate-pulse [animation-delay:200ms]\"></div>\n <div className=\"h-1.5 w-1.5 rounded-full bg-muted-foreground animate-pulse [animation-delay:400ms]\"></div>\n </div>\n </div>\n );\n}\n\nfunction ChatTypingIndicator({ label }: { label: string }) {\n return (\n <div className=\"rounded-2xl border border-border bg-card px-4 py-3 text-sm text-muted-foreground shadow-sm\">\n <style>{TYPING_TEXT_SHEEN_CSS}</style>\n <span className=\"nextclaw-chat-typing-indicator__text\">{label}</span>\n </div>\n );\n}\n\nexport function ChatMessageList({\n className,\n isSending,\n messages,\n onAttachmentOpen,\n onFileOpen,\n onInlineTokenClick,\n onToolAction,\n renderInlineDisplay,\n renderPanelAppCard,\n renderToolAgent,\n texts,\n}: ChatMessageListProps) {\n const visibleMessages = messages.filter(hasRenderableMessageContent);\n const hasRenderableAssistantDraft = visibleMessages.some(\n (message) =>\n message.role === 'assistant' &&\n (message.status === 'streaming' || message.status === 'pending')\n );\n\n return (\n <div className={cn('space-y-5', className)}>\n {visibleMessages.map((message) => {\n const isUser = message.role === 'user';\n const isGenerating = !isUser && (message.status === 'streaming' || message.status === 'pending');\n\n return (\n <div key={message.id} className={cn('flex gap-3', isUser ? 'justify-end' : 'justify-start')}>\n {!isUser ? <ChatMessageAvatar role={message.role} /> : null}\n <div className={cn('w-fit max-w-[92%] space-y-2 has-[[data-chat-message-wide-content=true]]:w-full', isUser && 'flex flex-col items-end')}>\n <ChatMessage\n message={message}\n texts={texts}\n onToolAction={onToolAction}\n onFileOpen={onFileOpen}\n onAttachmentOpen={onAttachmentOpen}\n onInlineTokenClick={onInlineTokenClick}\n renderInlineDisplay={renderInlineDisplay}\n renderToolAgent={renderToolAgent}\n renderPanelAppCard={renderPanelAppCard}\n />\n <div className={cn('flex items-center gap-2', isUser && 'justify-end')}>\n {isGenerating ? (\n <ChatMessageTypingFooter />\n ) : (\n <>\n <div\n className={cn(\n 'px-1 text-[11px] leading-4 text-muted-foreground',\n isUser ? 'text-right' : 'text-left'\n )}\n >\n {message.roleLabel} · {message.timestampLabel}\n </div>\n {!isUser ? <ChatMessageActionCopy message={message} texts={texts} /> : null}\n </>\n )}\n </div>\n </div>\n {isUser ? <ChatMessageAvatar role={message.role} /> : null}\n </div>\n );\n })}\n\n {isSending && !hasRenderableAssistantDraft ? (\n <div className=\"flex justify-start gap-3\">\n <ChatMessageAvatar role=\"assistant\" />\n <ChatTypingIndicator label={texts.typingLabel} />\n </div>\n ) : null}\n </div>\n );\n}\n","import type {\n ChatInputSurfaceItem,\n ChatInputSurfaceMenuTexts,\n ChatInputSurfaceTrigger,\n ChatInputSurfaceTriggerSpec,\n ChatInputSurfacePanel,\n ChatInputSurfacePlugin,\n ChatInputSurfacePluginContext,\n ChatInputSurfaceResolvedState,\n} from './input-surface.types';\n\nexport function createInputSurfaceTriggeredPanelPlugin<TData>(params: {\n key: string;\n trigger: ChatInputSurfaceTriggerSpec;\n resolvePanel: (context: ChatInputSurfacePluginContext<TData>) => ChatInputSurfacePanel | null;\n}): ChatInputSurfacePlugin<TData> {\n return {\n key: params.key,\n triggerSpecs: [params.trigger],\n resolvePanel: (context) =>\n context.trigger.key === params.trigger.key ? params.resolvePanel(context) : null,\n };\n}\n\nexport function createInputSurfaceReferenceTokenPlugin<TData, TRecord>(params: {\n key: string;\n trigger: ChatInputSurfaceTriggerSpec;\n tokenKind: string;\n texts: ChatInputSurfaceMenuTexts;\n getRecords: (context: ChatInputSurfacePluginContext<TData>) => readonly TRecord[];\n getIsLoading?: (context: ChatInputSurfacePluginContext<TData>) => boolean;\n getItems: (params: {\n context: ChatInputSurfacePluginContext<TData>;\n records: readonly TRecord[];\n query: string;\n tokenKind: string;\n }) => ChatInputSurfaceItem[];\n onSelectItem?: (item: ChatInputSurfaceItem) => void;\n}): ChatInputSurfacePlugin<TData> {\n return createInputSurfaceTriggeredPanelPlugin({\n key: params.key,\n trigger: params.trigger,\n resolvePanel: (context) => ({\n isLoading: params.getIsLoading?.(context) ?? false,\n items: params.getItems({\n context,\n records: params.getRecords(context),\n query: context.trigger.query,\n tokenKind: params.tokenKind,\n }),\n onSelectItem: params.onSelectItem,\n texts: params.texts,\n }),\n });\n}\n\nexport function resolveChatInputSurfaceState<TData>(params: {\n data: TData;\n plugins: readonly ChatInputSurfacePlugin<TData>[];\n trigger: ChatInputSurfaceTrigger | null;\n}): ChatInputSurfaceResolvedState {\n const { data, plugins, trigger } = params;\n const triggerSpecs = plugins.flatMap((plugin) => [...plugin.triggerSpecs]);\n if (!trigger) {\n return {\n triggerSpecs,\n panel: null,\n };\n }\n\n for (const plugin of plugins) {\n const panel = plugin.resolvePanel({\n data,\n trigger,\n });\n if (panel) {\n return {\n triggerSpecs,\n panel,\n };\n }\n }\n\n return {\n triggerSpecs,\n panel: null,\n };\n}\n"],"mappings":"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"}