langchain_agentx_stream_ui 0.1.2 → 0.1.8

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.
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/view/markdown/mermaidTheme.ts","../src/view/markdown/initMermaid.ts","../src/view/markdown/MermaidDiagram.tsx","../src/view/markdown/MermaidFullscreenModal.tsx","../src/view/markdown/mermaidDisplayUtils.ts","../src/view/markdown/useCopyText.ts","../src/view/markdown/copyToClipboard.ts","../src/view/markdown/PlantUMLBlock.tsx","../src/view/markdown/plantumlConfig.ts","../src/view/markdown/PlantUMLDiagram.tsx","../src/view/markdown/plantumlRender.ts","../src/view/markdown/RichMarkdown.tsx","../src/view/markdown/markdownUtils.ts","../src/view/markdown/richMarkdownComponents.tsx","../src/view/markdown/headingIds.ts","../src/view/nodes/ReasoningNode.tsx","../src/view/tools/presentation/StreamingMarkdown.tsx","../src/view/nodes/TextNode.tsx","../src/view/nodes/ToolCallNode.tsx","../src/view/nodes/StepNode.tsx","../src/view/nodes/ErrorNode.tsx","../src/view/nodes/UnknownNode.tsx","../src/view/nodes/PermissionNode.tsx","../src/view/nodes/MemorySavedNode.tsx","../src/view/NodeRegistry.ts","../src/view/defaultRegistry.ts","../src/core/sessionStore.ts","../src/core/dedupe.ts","../src/view/MultiAgentSession.tsx"],"sourcesContent":["/** Mermaid themeCSS:随 SVG 上 data-theme=\"dark\" 与 --lax-* 变量切换 */\nexport const MERMAID_THEME_CSS = `\n .node rect, .node circle, .node ellipse, .node polygon, .node path {\n fill: var(--lax-bg-surface, #f8f4e6);\n stroke: var(--lax-border-color, #d7c4bb);\n stroke-width: 1px;\n }\n .edgePath .path {\n stroke: var(--lax-accent-primary, #9b7cb9);\n stroke-width: 1.5px;\n }\n .edgeLabel {\n background-color: transparent;\n color: var(--lax-foreground, #333333);\n }\n .edgeLabel p {\n background-color: transparent !important;\n }\n .label {\n color: var(--lax-foreground, #333333);\n }\n .cluster rect {\n fill: var(--lax-bg-surface, #f8f4e6);\n stroke: var(--lax-border-color, #d7c4bb);\n stroke-width: 1px;\n }\n .actor {\n fill: var(--lax-bg-surface, #f8f4e6);\n stroke: var(--lax-border-color, #d7c4bb);\n stroke-width: 1px;\n }\n text.actor {\n fill: var(--lax-foreground, #333333);\n stroke: none;\n }\n .messageText {\n fill: var(--lax-foreground, #333333);\n stroke: none;\n }\n .messageLine0, .messageLine1 {\n stroke: var(--lax-accent-primary, #9b7cb9);\n }\n\n [data-theme=\"dark\"] .node rect,\n [data-theme=\"dark\"] .node circle,\n [data-theme=\"dark\"] .node ellipse,\n [data-theme=\"dark\"] .node polygon,\n [data-theme=\"dark\"] .node path {\n fill: var(--lax-card-bg, #222222);\n stroke: var(--lax-border-color, #5d4037);\n }\n [data-theme=\"dark\"] .edgePath .path,\n [data-theme=\"dark\"] .flowchart-link {\n stroke: var(--lax-accent-primary, #9370db);\n }\n [data-theme=\"dark\"] .edgeLabel,\n [data-theme=\"dark\"] .label,\n [data-theme=\"dark\"] text.actor,\n [data-theme=\"dark\"] .messageText,\n [data-theme=\"dark\"] text.sequenceText,\n [data-theme=\"dark\"] .noteText {\n fill: var(--lax-foreground, #f0f0f0);\n color: var(--lax-foreground, #f0f0f0);\n }\n [data-theme=\"dark\"] .cluster rect,\n [data-theme=\"dark\"] .actor {\n fill: var(--lax-card-bg, #222222);\n stroke: var(--lax-border-color, #5d4037);\n }\n [data-theme=\"dark\"] .messageLine0,\n [data-theme=\"dark\"] .messageLine1 {\n stroke: var(--lax-accent-primary, #9370db);\n stroke-width: 1.5px;\n }\n`;\n\nexport type MermaidThemeName = 'neutral' | 'default' | 'dark' | 'forest' | 'base';\n\nexport interface MermaidInitOptions {\n theme?: MermaidThemeName;\n maxTextSize?: number;\n}\n\nexport const DEFAULT_MERMAID_INIT: MermaidInitOptions = {\n theme: 'neutral',\n maxTextSize: 100_000,\n};\n","import {\n DEFAULT_MERMAID_INIT,\n MERMAID_THEME_CSS,\n type MermaidInitOptions,\n} from './mermaidTheme';\n\nlet mermaidInitPromise: Promise<typeof import('mermaid').default | null> | null = null;\nlet activeInitOptions: MermaidInitOptions = { ...DEFAULT_MERMAID_INIT };\n\nfunction buildInitializeConfig(options: MermaidInitOptions) {\n return {\n startOnLoad: false,\n theme: options.theme ?? DEFAULT_MERMAID_INIT.theme,\n securityLevel: 'strict' as const,\n suppressErrorRendering: true,\n logLevel: 'error' as const,\n maxTextSize: options.maxTextSize ?? DEFAULT_MERMAID_INIT.maxTextSize,\n htmlLabels: true,\n themeCSS: MERMAID_THEME_CSS,\n flowchart: {\n htmlLabels: true,\n curve: 'basis' as const,\n nodeSpacing: 60,\n rankSpacing: 60,\n padding: 20,\n },\n };\n}\n\n/** 覆盖默认 mermaid 初始化(需在首次 render 前调用) */\nexport function configureMermaid(options: MermaidInitOptions): void {\n activeInitOptions = { ...DEFAULT_MERMAID_INIT, ...options };\n mermaidInitPromise = null;\n}\n\n/** 懒加载并初始化 mermaid(peer:mermaid) */\nexport async function loadMermaid(): Promise<typeof import('mermaid').default | null> {\n if (typeof window === 'undefined') return null;\n\n if (!mermaidInitPromise) {\n mermaidInitPromise = import('mermaid')\n .then((mod) => {\n const mermaid = mod.default;\n mermaid.initialize(buildInitializeConfig(activeInitOptions));\n return mermaid;\n })\n .catch(() => null);\n }\n\n return mermaidInitPromise;\n}\n","import { useEffect, useId, useMemo, useRef, useState } from 'react';\n\nimport { loadMermaid } from './initMermaid';\nimport { MermaidFullscreenModal } from './MermaidFullscreenModal';\nimport { applyDarkThemeToSvg, useDarkMode } from './mermaidDisplayUtils';\nimport { useCopyText } from './useCopyText';\n\nexport interface MermaidDiagramProps {\n chart: string;\n className?: string;\n /** 画布内 svg-pan-zoom */\n zoomingEnabled?: boolean;\n /** 工具栏全屏与点击放大 */\n fullscreenEnabled?: boolean;\n}\n\nexport function MermaidDiagram({\n chart,\n className = '',\n zoomingEnabled = true,\n fullscreenEnabled = true,\n}: MermaidDiagramProps) {\n const [rawSvg, setRawSvg] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const { copied, copy } = useCopyText(chart);\n const containerRef = useRef<HTMLDivElement>(null);\n const reactId = useId().replace(/:/g, '');\n const renderId = `lax-mermaid-${reactId}`;\n const isDark = useDarkMode();\n\n const svg = useMemo(() => applyDarkThemeToSvg(rawSvg, isDark), [rawSvg, isDark]);\n\n useEffect(() => {\n if (!chart.trim()) return;\n\n let cancelled = false;\n\n const renderChart = async () => {\n const mermaid = await loadMermaid();\n if (cancelled) return;\n\n if (!mermaid) {\n setError('mermaid peer dependency is not installed');\n return;\n }\n\n try {\n setError(null);\n setRawSvg('');\n const { svg: renderedSvg } = await mermaid.render(renderId, chart.trim());\n if (!cancelled) {\n setRawSvg(renderedSvg);\n }\n } catch (err) {\n if (!cancelled) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n }\n }\n };\n\n void renderChart();\n\n return () => {\n cancelled = true;\n };\n }, [chart, renderId]);\n\n useEffect(() => {\n if (!svg || !zoomingEnabled || !containerRef.current) return;\n\n let disposed = false;\n\n const setupPanZoom = async () => {\n const svgElement = containerRef.current?.querySelector('svg');\n if (!svgElement || disposed) return;\n\n svgElement.style.maxWidth = 'none';\n svgElement.style.width = '100%';\n\n try {\n const svgPanZoom = (await import('svg-pan-zoom')).default;\n if (disposed) return;\n svgPanZoom(svgElement, {\n zoomEnabled: true,\n controlIconsEnabled: true,\n fit: true,\n center: true,\n minZoom: 0.1,\n maxZoom: 10,\n zoomScaleSensitivity: 0.3,\n });\n } catch {\n // svg-pan-zoom is optional peer\n }\n };\n\n const timer = window.setTimeout(() => {\n void setupPanZoom();\n }, 50);\n\n return () => {\n disposed = true;\n window.clearTimeout(timer);\n };\n }, [svg, zoomingEnabled]);\n\n const handleCopy = () => void copy();\n\n const openFullscreen = () => {\n if (!error && svg) setIsFullscreen(true);\n };\n\n const toolbar = (\n <div className=\"lax-mermaid__toolbar\">\n <span className=\"lax-mermaid__label\">Mermaid</span>\n <div className=\"lax-mermaid__actions\">\n {fullscreenEnabled && svg ? (\n <button\n type=\"button\"\n className=\"lax-mermaid__expand\"\n onClick={openFullscreen}\n aria-label=\"View fullscreen\"\n >\n Expand\n </button>\n ) : null}\n <button type=\"button\" className=\"lax-mermaid__copy\" onClick={handleCopy}>\n {copied ? 'Copied' : 'Copy'}\n </button>\n </div>\n </div>\n );\n\n if (error) {\n return (\n <div className={`lax-mermaid lax-mermaid--error ${className}`.trim()}>\n {toolbar}\n <pre className=\"lax-mermaid__fallback\">{chart}</pre>\n <p className=\"lax-mermaid__error-text\">{error}</p>\n </div>\n );\n }\n\n if (!svg) {\n return (\n <div className={`lax-mermaid lax-mermaid--loading ${className}`.trim()}>\n <span className=\"lax-mermaid__loading-dots\" aria-hidden=\"true\">\n <span /><span /><span />\n </span>\n <span className=\"lax-mermaid__loading-text\">Rendering diagram…</span>\n </div>\n );\n }\n\n const canvasClickable = fullscreenEnabled && !zoomingEnabled;\n\n return (\n <>\n <div className={`lax-mermaid ${className}`.trim()}>\n {toolbar}\n <div\n ref={containerRef}\n className={[\n 'lax-mermaid__canvas',\n zoomingEnabled ? 'lax-mermaid__canvas--zoom' : '',\n canvasClickable ? 'lax-mermaid__canvas--clickable' : '',\n ].filter(Boolean).join(' ')}\n dangerouslySetInnerHTML={{ __html: svg }}\n onClick={canvasClickable ? openFullscreen : undefined}\n onKeyDown={canvasClickable ? (event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n openFullscreen();\n }\n } : undefined}\n role={canvasClickable ? 'button' : undefined}\n tabIndex={canvasClickable ? 0 : undefined}\n aria-label={canvasClickable ? 'Click to view fullscreen' : undefined}\n title={canvasClickable ? 'Click to view fullscreen' : undefined}\n />\n </div>\n\n {fullscreenEnabled ? (\n <MermaidFullscreenModal\n isOpen={isFullscreen}\n onClose={() => setIsFullscreen(false)}\n svg={svg}\n />\n ) : null}\n </>\n );\n}\n","import { useEffect, useRef, useState, type ReactNode } from 'react';\n\nexport interface MermaidFullscreenModalProps {\n isOpen: boolean;\n onClose: () => void;\n svg: string;\n title?: string;\n}\n\nexport function MermaidFullscreenModal({\n isOpen,\n onClose,\n svg,\n title = 'Diagram',\n}: MermaidFullscreenModalProps) {\n const panelRef = useRef<HTMLDivElement>(null);\n const [zoom, setZoom] = useState(1);\n\n useEffect(() => {\n if (!isOpen) return;\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Escape') onClose();\n };\n\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n }, [isOpen, onClose]);\n\n useEffect(() => {\n if (isOpen) setZoom(1);\n }, [isOpen]);\n\n if (!isOpen) return null;\n\n const zoomOut = () => setZoom((z) => Math.max(0.5, z - 0.1));\n const zoomIn = () => setZoom((z) => Math.min(2, z + 0.1));\n\n return (\n <div\n className=\"lax-mermaid-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n onMouseDown={(event) => {\n if (panelRef.current && !panelRef.current.contains(event.target as Node)) {\n onClose();\n }\n }}\n >\n <div ref={panelRef} className=\"lax-mermaid-modal__panel\">\n <div className=\"lax-mermaid-modal__header\">\n <span className=\"lax-mermaid-modal__title\">{title}</span>\n <div className=\"lax-mermaid-modal__controls\">\n <ZoomButton label=\"Zoom out\" onClick={zoomOut}>−</ZoomButton>\n <span className=\"lax-mermaid-modal__zoom\">{Math.round(zoom * 100)}%</span>\n <ZoomButton label=\"Zoom in\" onClick={zoomIn}>+</ZoomButton>\n <ZoomButton label=\"Reset zoom\" onClick={() => setZoom(1)}>↺</ZoomButton>\n <ZoomButton label=\"Close\" onClick={onClose}>×</ZoomButton>\n </div>\n </div>\n <div className=\"lax-mermaid-modal__body\">\n <div\n className=\"lax-mermaid-modal__canvas\"\n style={{\n transform: `scale(${zoom})`,\n transformOrigin: 'center center',\n }}\n dangerouslySetInnerHTML={{ __html: svg }}\n />\n </div>\n </div>\n </div>\n );\n}\n\nfunction ZoomButton({\n label,\n onClick,\n children,\n}: {\n label: string;\n onClick: () => void;\n children: ReactNode;\n}) {\n return (\n <button type=\"button\" className=\"lax-mermaid-modal__btn\" aria-label={label} onClick={onClick}>\n {children}\n </button>\n );\n}\n","import { useEffect, useState } from 'react';\n\n/** 检测宿主暗色:data-theme / class.dark / prefers-color-scheme */\nexport function isDarkMode(): boolean {\n if (typeof document === 'undefined') return false;\n\n const root = document.documentElement;\n const dataTheme = root.getAttribute('data-theme');\n if (dataTheme === 'dark') return true;\n if (dataTheme === 'light') return false;\n if (root.classList.contains('dark')) return true;\n\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {\n return false;\n }\n\n return window.matchMedia('(prefers-color-scheme: dark)').matches;\n}\n\nexport function applyDarkThemeToSvg(svg: string, dark: boolean): string {\n if (!svg) return svg;\n\n const withoutAttr = svg.replace(/\\sdata-theme=\"dark\"/g, '');\n if (!dark) return withoutAttr;\n if (withoutAttr.includes('data-theme=\"dark\"')) return withoutAttr;\n\n return withoutAttr.replace('<svg ', '<svg data-theme=\"dark\" ');\n}\n\nexport function useDarkMode(): boolean {\n const [dark, setDark] = useState(false);\n\n useEffect(() => {\n const update = () => setDark(isDarkMode());\n update();\n\n const mq = typeof window.matchMedia === 'function'\n ? window.matchMedia('(prefers-color-scheme: dark)')\n : null;\n mq?.addEventListener('change', update);\n\n const observer = new MutationObserver(update);\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class', 'data-theme'],\n });\n\n return () => {\n mq?.removeEventListener('change', update);\n observer.disconnect();\n };\n }, []);\n\n return dark;\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { copyToClipboard } from './copyToClipboard';\n\n/** 带 Copied 反馈的拷贝 hook */\nexport function useCopyText(text: string, resetMs = 2000) {\n const [copied, setCopied] = useState(false);\n const timerRef = useRef<number>();\n\n useEffect(() => {\n return () => {\n if (timerRef.current !== undefined) {\n window.clearTimeout(timerRef.current);\n }\n };\n }, []);\n\n const copy = useCallback(async () => {\n const ok = await copyToClipboard(text);\n if (!ok) return;\n\n setCopied(true);\n if (timerRef.current !== undefined) {\n window.clearTimeout(timerRef.current);\n }\n timerRef.current = window.setTimeout(() => setCopied(false), resetMs);\n }, [text, resetMs]);\n\n return { copied, copy };\n}\n","/** 拷贝文本到剪贴板;clipboard API 失败时降级 execCommand */\nexport async function copyToClipboard(text: string): Promise<boolean> {\n if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n } catch {\n // fall through\n }\n }\n\n if (typeof document === 'undefined') return false;\n\n try {\n const textArea = document.createElement('textarea');\n textArea.value = text;\n textArea.style.position = 'fixed';\n textArea.style.left = '-9999px';\n document.body.appendChild(textArea);\n textArea.select();\n const ok = document.execCommand('copy');\n document.body.removeChild(textArea);\n return ok;\n } catch {\n return false;\n }\n}\n","import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';\n\nimport { useCopyText } from './useCopyText';\n\nexport interface PlantUMLBlockProps {\n content: string;\n className?: string;\n}\n\n/** PlantUML 源码块(高亮 + 拷贝;供 sourceOnly / 降级展示) */\nexport function PlantUMLBlock({ content, className = '' }: PlantUMLBlockProps) {\n const { copied, copy } = useCopyText(content);\n\n return (\n <div className={`lax-plantuml lax-code-block lax-code-block--rich ${className}`.trim()}>\n <div className=\"lax-code-block__header\">\n <span className=\"lax-code-block__lang\">PlantUML</span>\n <button\n type=\"button\"\n className={`lax-code-block__copy ${copied ? 'lax-code-block__copy--copied' : ''}`}\n onClick={() => void copy()}\n >\n {copied ? 'Copied' : 'Copy'}\n </button>\n </div>\n <SyntaxHighlighter\n language=\"text\"\n style={oneDark}\n customStyle={{ margin: 0, padding: '0.75rem 1rem', background: 'transparent' }}\n showLineNumbers\n wrapLongLines\n >\n {content}\n </SyntaxHighlighter>\n </div>\n );\n}\n","const DEFAULT_PLANTUML_SERVER_URL = 'https://kroki.io';\n\nlet plantumlServerUrl = DEFAULT_PLANTUML_SERVER_URL;\n\n/** 配置 PlantUML 渲染服务(默认 Kroki:https://kroki.io) */\nexport function configurePlantumlServer(url: string): void {\n plantumlServerUrl = url.replace(/\\/$/, '');\n}\n\nexport function getPlantumlServerUrl(): string {\n return plantumlServerUrl;\n}\n\nexport function resetPlantumlServerUrl(): void {\n plantumlServerUrl = DEFAULT_PLANTUML_SERVER_URL;\n}\n","import { useEffect, useState } from 'react';\n\nimport { MermaidFullscreenModal } from './MermaidFullscreenModal';\nimport { PlantUMLBlock } from './PlantUMLBlock';\nimport { fetchPlantumlSvg } from './plantumlRender';\nimport { useCopyText } from './useCopyText';\n\nexport interface PlantUMLDiagramProps {\n content: string;\n className?: string;\n /** Kroki 或兼容渲染服务根 URL */\n serverUrl?: string;\n fullscreenEnabled?: boolean;\n /** 仅源码高亮,不请求渲染 */\n sourceOnly?: boolean;\n}\n\nexport function PlantUMLDiagram({\n content,\n className = '',\n serverUrl,\n fullscreenEnabled = true,\n sourceOnly = false,\n}: PlantUMLDiagramProps) {\n const [svg, setSvg] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [isFullscreen, setIsFullscreen] = useState(false);\n const { copied, copy } = useCopyText(content);\n\n useEffect(() => {\n if (!content.trim() || sourceOnly) return;\n\n let cancelled = false;\n\n const render = async () => {\n if (typeof window === 'undefined') return;\n\n try {\n setError(null);\n setSvg('');\n const rendered = await fetchPlantumlSvg(content, serverUrl);\n if (!cancelled) setSvg(rendered);\n } catch (err) {\n if (!cancelled) {\n const message = err instanceof Error ? err.message : String(err);\n setError(message);\n }\n }\n };\n\n void render();\n\n return () => {\n cancelled = true;\n };\n }, [content, serverUrl, sourceOnly]);\n\n if (sourceOnly) {\n return <PlantUMLBlock content={content} className={className} />;\n }\n\n const handleCopy = () => void copy();\n const openFullscreen = () => {\n if (svg) setIsFullscreen(true);\n };\n\n const toolbar = (\n <div className=\"lax-plantuml__toolbar\">\n <span className=\"lax-plantuml__label\">PlantUML</span>\n <div className=\"lax-plantuml__actions\">\n {fullscreenEnabled && svg ? (\n <button\n type=\"button\"\n className=\"lax-plantuml__expand\"\n onClick={openFullscreen}\n aria-label=\"View fullscreen\"\n >\n Expand\n </button>\n ) : null}\n <button type=\"button\" className=\"lax-plantuml__copy\" onClick={handleCopy}>\n {copied ? 'Copied' : 'Copy'}\n </button>\n </div>\n </div>\n );\n\n if (error) {\n return (\n <div className={`lax-plantuml lax-plantuml--error ${className}`.trim()}>\n {toolbar}\n <pre className=\"lax-plantuml__fallback\">{content}</pre>\n <p className=\"lax-plantuml__error-text\">{error}</p>\n </div>\n );\n }\n\n if (!svg) {\n return (\n <div className={`lax-plantuml lax-plantuml--loading ${className}`.trim()}>\n <span className=\"lax-plantuml__loading-dots\" aria-hidden=\"true\">\n <span /><span /><span />\n </span>\n <span className=\"lax-plantuml__loading-text\">Rendering diagram…</span>\n </div>\n );\n }\n\n return (\n <>\n <div className={`lax-plantuml ${className}`.trim()}>\n {toolbar}\n <div\n className=\"lax-plantuml__canvas lax-plantuml__canvas--clickable\"\n dangerouslySetInnerHTML={{ __html: svg }}\n onClick={fullscreenEnabled ? openFullscreen : undefined}\n onKeyDown={fullscreenEnabled ? (event) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n openFullscreen();\n }\n } : undefined}\n role={fullscreenEnabled ? 'button' : undefined}\n tabIndex={fullscreenEnabled ? 0 : undefined}\n aria-label={fullscreenEnabled ? 'Click to view fullscreen' : undefined}\n />\n </div>\n\n {fullscreenEnabled ? (\n <MermaidFullscreenModal\n isOpen={isFullscreen}\n onClose={() => setIsFullscreen(false)}\n svg={svg}\n title=\"PlantUML\"\n />\n ) : null}\n </>\n );\n}\n","import { getPlantumlServerUrl } from './plantumlConfig';\n\n/** 补全 @startuml / @enduml 包裹 */\nexport function normalizePlantumlSource(source: string): string {\n const trimmed = source.trim();\n if (!trimmed) return trimmed;\n if (trimmed.includes('@startuml')) return trimmed;\n return `@startuml\\n${trimmed}\\n@enduml`;\n}\n\n/** 通过 Kroki(或兼容服务)POST 渲染 PlantUML → SVG 文本 */\nexport async function fetchPlantumlSvg(\n source: string,\n serverUrl = getPlantumlServerUrl(),\n): Promise<string> {\n const base = serverUrl.replace(/\\/$/, '');\n const diagramSource = normalizePlantumlSource(source);\n\n const res = await fetch(`${base}/`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'image/svg+xml',\n },\n body: JSON.stringify({\n diagram_source: diagramSource,\n diagram_type: 'plantuml',\n output_format: 'svg',\n }),\n });\n\n if (!res.ok) {\n const detail = await res.text().catch(() => '');\n const suffix = detail ? `: ${detail.slice(0, 200)}` : '';\n throw new Error(`PlantUML render failed (${res.status})${suffix}`);\n }\n\n const svg = await res.text();\n if (!svg.includes('<svg')) {\n throw new Error('PlantUML render returned non-SVG response');\n }\n\n return svg;\n}\n","import { useMemo } from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport {\n collapseExcessiveBlankLines,\n hasMarkdownSyntax,\n} from './markdownUtils';\nimport { RICH_MARKDOWN_COMPONENTS } from './richMarkdownComponents';\n\nexport interface RichMarkdownProps {\n content: string;\n className?: string;\n}\n\n/** Web 向富 Markdown(TextNode S1);含 Mermaid、GFM、代码高亮。 */\nexport function RichMarkdown({ content, className = '' }: RichMarkdownProps) {\n const processed = useMemo(() => collapseExcessiveBlankLines(content), [content]);\n\n if (!processed) {\n return null;\n }\n\n if (!hasMarkdownSyntax(processed)) {\n return (\n <p className={`lax-markdown__paragraph ${className}`.trim()}>{processed}</p>\n );\n }\n\n return (\n <div className={className || undefined}>\n <ReactMarkdown remarkPlugins={[remarkGfm]} components={RICH_MARKDOWN_COMPONENTS}>\n {processed}\n </ReactMarkdown>\n </div>\n );\n}\n","/** 检测 markdown 语法(快速路径,检查前 500 字符) */\nconst MD_SYNTAX_RE = /[#*`|[>\\-_~]|\\n\\n|^\\d+\\. |\\n\\d+\\. /;\n\nexport function hasMarkdownSyntax(content: string): boolean {\n const sample = content.length > 500 ? content.slice(0, 500) : content;\n return MD_SYNTAX_RE.test(sample);\n}\n\nexport function hashContent(content: string): string {\n let hash = 5381;\n for (let i = 0; i < content.length; i++) {\n hash = ((hash << 5) + hash + content.charCodeAt(i)) & 0xffffffff;\n }\n return hash.toString(36);\n}\n\nexport function collapseExcessiveBlankLines(text: string): string {\n return text.replace(/\\n{3,}/g, '\\n\\n').trim();\n}\n\nexport function paragraphHasContent(children: unknown): boolean {\n if (children == null || children === false) return false;\n if (typeof children === 'string') return children.trim().length > 0;\n if (typeof children === 'number') return true;\n if (Array.isArray(children)) return children.some(paragraphHasContent);\n return true;\n}\n","import { type ReactNode } from 'react';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';\n\nimport { generateHeadingId } from './headingIds';\nimport { MermaidDiagram } from './MermaidDiagram';\nimport { PlantUMLDiagram } from './PlantUMLDiagram';\nimport { paragraphHasContent } from './markdownUtils';\nimport { useCopyText } from './useCopyText';\n\ninterface CodeBlockProps {\n language: string;\n content: string;\n}\n\nfunction RichCodeBlock({ language, content }: CodeBlockProps) {\n const { copied, copy } = useCopyText(content);\n\n return (\n <div className=\"lax-code-block lax-code-block--rich\">\n <div className=\"lax-code-block__header\">\n <span className=\"lax-code-block__lang\">{language || 'code'}</span>\n <button\n type=\"button\"\n className={`lax-code-block__copy ${copied ? 'lax-code-block__copy--copied' : ''}`}\n onClick={() => void copy()}\n >\n {copied ? 'Copied' : 'Copy'}\n </button>\n </div>\n <SyntaxHighlighter\n language={language || 'text'}\n style={oneDark}\n customStyle={{ margin: 0, padding: '0.75rem 1rem', background: 'transparent' }}\n showLineNumbers\n wrapLongLines\n >\n {content}\n </SyntaxHighlighter>\n </div>\n );\n}\n\nfunction heading(children: ReactNode, level: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6', className: string) {\n const text = children != null ? String(children) : '';\n const id = generateHeadingId(text);\n const Tag = level;\n return (\n <Tag id={id} className={`lax-markdown__heading ${className}`}>\n {children}\n </Tag>\n );\n}\n\nexport const RICH_MARKDOWN_COMPONENTS = {\n code(props: {\n inline?: boolean;\n className?: string;\n children?: ReactNode;\n }) {\n const { inline, className, children, ...rest } = props;\n const match = /language-(\\w+)/.exec(className || '');\n const codeContent = children != null ? String(children).replace(/\\n$/, '') : '';\n\n if (!inline && match?.[1] === 'mermaid' && codeContent.trim()) {\n return <MermaidDiagram chart={codeContent} />;\n }\n\n if (!inline && match?.[1] === 'plantuml' && codeContent.trim()) {\n return <PlantUMLDiagram content={codeContent} />;\n }\n\n if (!inline && match) {\n return <RichCodeBlock language={match[1]!} content={codeContent} />;\n }\n\n return (\n <code className=\"lax-markdown__inline-code\" {...rest}>\n {children}\n </code>\n );\n },\n h1({ children }: { children?: ReactNode }) {\n return heading(children, 'h1', 'lax-markdown__h1');\n },\n h2({ children }: { children?: ReactNode }) {\n return heading(children, 'h2', 'lax-markdown__h2');\n },\n h3({ children }: { children?: ReactNode }) {\n return heading(children, 'h3', 'lax-markdown__h3');\n },\n h4({ children }: { children?: ReactNode }) {\n return heading(children, 'h4', 'lax-markdown__h4');\n },\n h5({ children }: { children?: ReactNode }) {\n return heading(children, 'h5', 'lax-markdown__h5');\n },\n h6({ children }: { children?: ReactNode }) {\n return heading(children, 'h6', 'lax-markdown__h6');\n },\n p({ children }: { children?: ReactNode }) {\n if (!paragraphHasContent(children)) return null;\n return <p className=\"lax-markdown__paragraph\">{children}</p>;\n },\n ul({ children }: { children?: ReactNode }) {\n return <ul className=\"lax-markdown__list lax-markdown__ul\">{children}</ul>;\n },\n ol({ children }: { children?: ReactNode }) {\n return <ol className=\"lax-markdown__list lax-markdown__ol\">{children}</ol>;\n },\n li({ children }: { children?: ReactNode }) {\n return <li className=\"lax-markdown__li\">{children}</li>;\n },\n a({ children, href }: { children?: ReactNode; href?: string }) {\n return (\n <a href={href} className=\"lax-markdown__link\" target=\"_blank\" rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n },\n blockquote({ children }: { children?: ReactNode }) {\n return <blockquote className=\"lax-markdown__blockquote\">{children}</blockquote>;\n },\n table({ children }: { children?: ReactNode }) {\n return (\n <div className=\"lax-markdown__table-wrapper\">\n <table className=\"lax-markdown__table\">{children}</table>\n </div>\n );\n },\n thead({ children }: { children?: ReactNode }) {\n return <thead className=\"lax-markdown__thead\">{children}</thead>;\n },\n tbody({ children }: { children?: ReactNode }) {\n return <tbody className=\"lax-markdown__tbody\">{children}</tbody>;\n },\n tr({ children }: { children?: ReactNode }) {\n return <tr className=\"lax-markdown__tr\">{children}</tr>;\n },\n th({ children }: { children?: ReactNode }) {\n return <th className=\"lax-markdown__th\">{children}</th>;\n },\n td({ children }: { children?: ReactNode }) {\n return <td className=\"lax-markdown__td\">{children}</td>;\n },\n hr() {\n return <hr className=\"lax-markdown__hr\" />;\n },\n strong({ children }: { children?: ReactNode }) {\n return <strong className=\"lax-markdown__strong\">{children}</strong>;\n },\n em({ children }: { children?: ReactNode }) {\n return <em className=\"lax-markdown__em\">{children}</em>;\n },\n};\n","let headingCounter = 0;\n\n/** 为 Markdown 标题生成稳定 id(锚点 / TOC 用) */\nexport function generateHeadingId(text: string): string {\n const slug = text\n .trim()\n .toLowerCase()\n .replace(/[^\\w\\u4e00-\\u9fff]+/g, '-')\n .replace(/^-+|-+$/g, '');\n\n if (slug) return slug;\n headingCounter += 1;\n return `heading-${headingCounter}`;\n}\n\nexport function resetHeadingIds(): void {\n headingCounter = 0;\n}\n","/**\n * 职责:ReasoningNode — 对齐 CC AssistantTextMessage / CLI assistant_message。\n * 正文前加 BLACK_CIRCLE(●);streaming 时圆点闪烁;正常字色、不折叠。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\n/** 对齐 CC constants/figures.ts BLACK_CIRCLE · CLI assistant_message._BLACK_CIRCLE */\nexport const REASONING_DOT = '●';\n\nexport interface ReasoningBubbleProps {\n nodeId: string;\n}\n\nexport function ReasoningBubble({ nodeId }: ReasoningBubbleProps) {\n const node = useNodeTyped(nodeId, 'reasoning');\n if (!node) return null;\n\n const text = node.accumulated.trim();\n if (!text) return null;\n\n return (\n <div className=\"lax-reasoning-bubble\" data-status={node.status} data-round-id={node.roundId}>\n <div className=\"lax-reasoning-bubble__body\">\n <span className=\"lax-reasoning-bubble__dot\" aria-hidden=\"true\">\n {REASONING_DOT}\n </span>\n <span className=\"lax-reasoning-bubble__content\">{node.accumulated}</span>\n </div>\n </div>\n );\n}\n","/**\n * StreamingMarkdown.tsx — 流式 Rich Markdown(S1:稳定/不稳定后缀均 RichMarkdown)\n *\n * 链路位置:TextNode 正式结果渲染。\n */\nimport { useRef } from 'react';\nimport { marked, type Token } from 'marked';\n\nimport { RichMarkdown } from '../../markdown/RichMarkdown';\nimport { hashContent, hasMarkdownSyntax } from '../../markdown/markdownUtils';\n\nconst TOKEN_CACHE_MAX = 500;\nconst tokenCache = new Map<string, Token[]>();\n\nfunction cachedLexer(content: string): Token[] {\n if (!hasMarkdownSyntax(content)) {\n return [{\n type: 'paragraph',\n raw: content,\n text: content,\n tokens: [{\n type: 'text',\n raw: content,\n text: content,\n }],\n } as Token];\n }\n\n const key = hashContent(content);\n const hit = tokenCache.get(key);\n\n if (hit) {\n tokenCache.delete(key);\n tokenCache.set(key, hit);\n return hit;\n }\n\n const tokens = marked.lexer(content);\n\n if (tokenCache.size >= TOKEN_CACHE_MAX) {\n const first = tokenCache.keys().next().value;\n if (first !== undefined) tokenCache.delete(first);\n }\n\n tokenCache.set(key, tokens);\n return tokens;\n}\n\nexport interface StreamingMarkdownProps {\n children: string;\n}\n\nexport function StreamingMarkdown({ children }: StreamingMarkdownProps) {\n 'use no memo';\n\n const stablePrefixRef = useRef('');\n\n if (!children.startsWith(stablePrefixRef.current)) {\n stablePrefixRef.current = '';\n }\n\n const boundary = stablePrefixRef.current.length;\n const tokens = cachedLexer(children.substring(boundary));\n\n let lastContentIdx = tokens.length - 1;\n while (lastContentIdx >= 0 && tokens[lastContentIdx]!.type === 'space') {\n lastContentIdx--;\n }\n\n let advance = 0;\n for (let i = 0; i < lastContentIdx; i++) {\n advance += tokens[i]!.raw.length;\n }\n\n if (advance > 0) {\n stablePrefixRef.current = children.substring(0, boundary + advance);\n }\n\n const stablePrefix = stablePrefixRef.current;\n const unstableSuffix = children.substring(stablePrefix.length);\n\n return (\n <div className=\"lax-markdown lax-markdown--rich\">\n {stablePrefix ? (\n <RichMarkdown key={`stable-${hashContent(stablePrefix)}`} content={stablePrefix} />\n ) : null}\n {unstableSuffix ? (\n <RichMarkdown key={`unstable-${hashContent(unstableSuffix)}`} content={unstableSuffix} />\n ) : null}\n </div>\n );\n}\n","/**\n * 职责:默认 TextNode 主舞台 widget。\n * 链路位置:NodeRegistry → Timeline 渲染。\n *\n * 渲染策略(对齐 CC):\n * - Streaming 时显示纯文本(避免高频 markdown 解析)\n * - Done 时使用边界跟踪优化的流式 markdown 渲染\n */\nimport { useNodeTyped } from '../../core/hooks';\n\n// 内置流式 markdown 渲染\nimport { StreamingMarkdown } from '../tools/presentation/StreamingMarkdown';\nimport { REASONING_DOT } from './ReasoningNode';\n\nexport interface TextBubbleProps {\n nodeId: string;\n}\n\nexport function TextBubble({ nodeId }: TextBubbleProps) {\n const node = useNodeTyped(nodeId, 'text');\n if (!node) return null;\n\n // 使用流式 markdown 渲染(对齐 CC:流式过程中就渲染 markdown)\n return (\n <div className=\"lax-text-bubble\" data-status={node.status}>\n <div className=\"lax-text-bubble__body\">\n <span className=\"lax-text-bubble__dot\" aria-hidden=\"true\">\n {REASONING_DOT}\n </span>\n <div className=\"lax-text-bubble__content lax-text-bubble__content--markdown\">\n <StreamingMarkdown>\n {node.accumulated}\n </StreamingMarkdown>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * 职责:默认 ToolCallNode 主舞台 widget(V3 Shell + resolveToolBody)。\n * 链路位置:NodeRegistry → Timeline。\n * 当前裁剪范围:T4.6 内嵌 permission 等待态(permissionUiMode 控制)。\n */\nimport { useEffect, useState } from 'react';\n\nimport {\n useSessionViewOptions,\n useToolDisplayOptions,\n} from '../../core/context/SessionContext';\nimport { useNodeTyped, usePendingPermissionForTool } from '../../core/hooks';\nimport { resolveEffectiveToolBodyMode } from '../sessionViewOptions';\nimport { formatToolTitle } from '../tools/formatToolTitle';\nimport { resolveToolBody } from '../tools/resolveToolBody';\nimport { ToolCallShell } from '../tools/ToolCallShell';\nimport type { ToolDisplayProps } from '../tools/types';\n\nexport interface ToolCallCardProps {\n nodeId: string;\n layout?: 'default' | 'grouped';\n}\n\nexport function ToolCallCard({ nodeId, layout = 'default' }: ToolCallCardProps) {\n const node = useNodeTyped(nodeId, 'tool_call');\n const { registry, defaultBodyMode } = useToolDisplayOptions();\n const viewOptions = useSessionViewOptions();\n const pendingPermission = usePendingPermissionForTool(node?.toolName ?? '');\n const effectiveDefault = resolveEffectiveToolBodyMode(viewOptions, defaultBodyMode);\n const [bodyMode, setBodyMode] = useState(effectiveDefault);\n\n useEffect(() => {\n setBodyMode(resolveEffectiveToolBodyMode(viewOptions, defaultBodyMode));\n }, [viewOptions.displayMode, viewOptions.verbose, defaultBodyMode]);\n\n if (!node) return null;\n\n // 内部工具(Task* 等)不在 Timeline 显示(对齐 CC renderToolUseMessage 返回 null)\n if (node.hidden) return null;\n\n const details = node.details;\n const inputStream = details?.inputStream ?? node.inputDelta;\n const result = node.result;\n const displayBody = result?.display ?? null;\n const hasSubagentProgress = (node.subagentProgress?.length ?? 0) > 0;\n const showBody =\n hasSubagentProgress || !(node.status === 'running' && result == null);\n\n const BodyComponent = resolveToolBody(node.toolName, displayBody, registry);\n const title = formatToolTitle(\n node.toolName,\n details?.input ?? node.input,\n displayBody,\n result?.summary,\n result?.meta,\n );\n\n const bodyProps: ToolDisplayProps = {\n nodeId,\n toolName: node.toolName,\n status: node.status,\n input: details?.input ?? node.input,\n inputStream,\n result,\n progress: node.progress ?? undefined,\n subagentProgress: node.subagentProgress,\n subagentSessions: node.subagentSessions,\n bodyMode,\n onBodyModeChange: setBodyMode,\n };\n\n const errorMessage = result?.error?.message ?? null;\n const permissionWait =\n viewOptions.permissionUiMode !== 'standalone' && node.status === 'running'\n ? pendingPermission\n : undefined;\n\n return (\n <ToolCallShell\n status={node.status}\n title={title}\n progress={node.progress ?? undefined}\n errorMessage={errorMessage}\n layout={layout}\n permissionWait={permissionWait}\n permissionUiMode={viewOptions.permissionUiMode}\n >\n {showBody ? (\n <div className=\"lax-tool-shell__body\">\n <BodyComponent {...bodyProps} />\n </div>\n ) : null}\n\n </ToolCallShell>\n );\n}\n","/**\n * 职责:默认 StepNode 折叠详情 widget。\n * 链路位置:NodeRegistry;MVP 折叠展示。\n * 当前裁剪范围:简单 label/status;不含复杂编排 UI。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface StepCardProps {\n nodeId: string;\n}\n\nexport function StepCard({ nodeId }: StepCardProps) {\n const node = useNodeTyped(nodeId, 'step');\n if (!node) return null;\n return (\n <details className=\"lax-step-card\" data-status={node.status}>\n <summary className=\"lax-step-card__summary\">{node.label}</summary>\n </details>\n );\n}\n","/**\n * 职责:默认 ErrorNode 主舞台 widget。\n * 链路位置:NodeRegistry → Timeline 渲染。\n * 当前裁剪范围:展示 message/type;不打断流。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface ErrorCardProps {\n nodeId: string;\n}\n\nexport function ErrorCard({ nodeId }: ErrorCardProps) {\n const node = useNodeTyped(nodeId, 'error');\n if (!node) return null;\n return (\n <div className=\"lax-error-card\" role=\"alert\">\n <div className=\"lax-error-card__message\">{node.message}</div>\n {node.errorType ? (\n <div className=\"lax-error-card__type\">{node.errorType}</div>\n ) : null}\n </div>\n );\n}\n","/**\n * 职责:未知 event_type 兜底 widget。\n * 链路位置:NodeRegistry → Timeline 渲染。\n * 当前裁剪范围:展示 eventType 与原始 data JSON。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface UnknownCardProps {\n nodeId: string;\n}\n\nexport function UnknownCard({ nodeId }: UnknownCardProps) {\n const node = useNodeTyped(nodeId, 'unknown');\n if (!node) return null;\n return (\n <div className=\"lax-unknown-card\">\n <div className=\"lax-unknown-card__type\">Unknown: {node.eventType}</div>\n <pre className=\"lax-unknown-card__data\">\n {JSON.stringify(node.rawData, null, 2)}\n </pre>\n </div>\n );\n}\n","/**\n * 职责:默认 PermissionNode 主舞台 widget(V2-D)。\n * 链路位置:NodeRegistry → Timeline;Allow/Deny 经 InteractionBus 回写业务 HTTP。\n * 当前裁剪范围:pending 态按钮;不含 suggestions 列表与 HITL 表单。\n */\nimport { useState } from 'react';\n\nimport { useInteractionBus } from '../../core/context/InteractionContext';\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface PermissionCardProps {\n nodeId: string;\n}\n\nexport function PermissionCard({ nodeId }: PermissionCardProps) {\n const node = useNodeTyped(nodeId, 'permission');\n const bus = useInteractionBus();\n const [resolvedLocally, setResolvedLocally] = useState(false);\n\n if (!node) return null;\n\n const pending = node.status === 'pending' && !resolvedLocally;\n\n const onAllow = () => {\n void bus.resolvePermission({ requestId: node.requestId, allow: true });\n setResolvedLocally(true);\n };\n\n const onDeny = () => {\n void bus.resolvePermission({ requestId: node.requestId, allow: false });\n setResolvedLocally(true);\n };\n\n return (\n <div\n className=\"lax-permission-card\"\n data-status={pending ? 'pending' : 'resolved'}\n data-request-id={node.requestId}\n >\n <div className=\"lax-permission-card__header\">\n <span className=\"lax-permission-card__label\">Permission</span>\n <span className=\"lax-permission-card__tool\">{node.toolName}</span>\n </div>\n <div className=\"lax-permission-card__message\">{node.message}</div>\n {node.askPrompt && node.askPrompt !== node.message ? (\n <div className=\"lax-permission-card__prompt\">{node.askPrompt}</div>\n ) : null}\n {pending ? (\n <div className=\"lax-permission-card__actions\">\n <button type=\"button\" className=\"lax-permission-card__allow\" onClick={onAllow}>\n Allow\n </button>\n <button type=\"button\" className=\"lax-permission-card__deny\" onClick={onDeny}>\n Deny\n </button>\n </div>\n ) : (\n <div className=\"lax-permission-card__resolved\">Resolved</div>\n )}\n </div>\n );\n}\n","/**\n * 职责:MEMORY_SAVED 摘要节点 widget — \"Saved N memories\" 一行折叠展示。\n *\n * 链路位置:\n * NodeRegistry → TimelineItem → 主舞台。\n *\n * 当前裁剪范围:\n * 默认折叠态;writtenPaths 非空时可展开列出路径。\n * 不解析路径语义(绝对 / 相对 / index 文件),由后端 SDK 契约保证。\n *\n * CLI 对照:\n * langchain_agentx_cli/screens/repl.py MemorySavedSummary 一行渲染。\n */\nimport { useNodeTyped } from '../../core/hooks';\n\nexport interface MemorySavedRowProps {\n nodeId: string;\n}\n\nexport function MemorySavedRow({ nodeId }: MemorySavedRowProps) {\n const node = useNodeTyped(nodeId, 'memory_saved');\n if (!node) return null;\n const hasPaths = node.writtenPaths.length > 0;\n return (\n <details\n className=\"lax-memory-saved\"\n data-testid=\"lax-memory-saved\"\n data-node-id={nodeId}\n >\n <summary className=\"lax-memory-saved__summary\">\n <span className=\"lax-memory-saved__icon\" aria-hidden=\"true\">\n 💾\n </span>\n <span className=\"lax-memory-saved__hint\">{node.displayHint}</span>\n </summary>\n {hasPaths ? (\n <ul className=\"lax-memory-saved__paths\">\n {node.writtenPaths.map((p) => (\n <li key={p} className=\"lax-memory-saved__path\">\n <code>{p}</code>\n </li>\n ))}\n </ul>\n ) : null}\n </details>\n );\n}\n","/**\n * 职责:kind → React widget 映射,支持 override/register 扩展。\n * 链路位置:Timeline 按节点 kind 查找 widget;业务通过 override 替换。\n * 当前裁剪范围:8 类内置 kind + 自定义 register;无插件系统。\n */\nimport type { ComponentType } from 'react';\n\nimport type { SessionNodeKind } from '../types/nodes';\nimport { TextBubble } from './nodes/TextNode';\nimport { ReasoningBubble } from './nodes/ReasoningNode';\nimport { ToolCallCard } from './nodes/ToolCallNode';\nimport { StepCard } from './nodes/StepNode';\nimport { ErrorCard } from './nodes/ErrorNode';\nimport { UnknownCard } from './nodes/UnknownNode';\nimport { PermissionCard } from './nodes/PermissionNode';\nimport { MemorySavedRow } from './nodes/MemorySavedNode';\n\nconst DEFAULT_WIDGETS = new Map<string, NodeWidget>([\n ['text', TextBubble],\n ['reasoning', ReasoningBubble],\n ['tool_call', ToolCallCard],\n ['step', StepCard],\n ['error', ErrorCard],\n ['unknown', UnknownCard],\n ['permission', PermissionCard],\n ['memory_saved', MemorySavedRow],\n]);\n\nexport interface NodeWidgetProps {\n nodeId: string;\n}\n\nexport type NodeWidget = ComponentType<NodeWidgetProps>;\n\nexport class NodeRegistry {\n private readonly widgets: Map<string, NodeWidget>;\n\n constructor(widgets: Map<string, NodeWidget>) {\n this.widgets = widgets;\n }\n\n static default(): NodeRegistry {\n return new NodeRegistry(new Map(DEFAULT_WIDGETS));\n }\n\n override(kind: SessionNodeKind | string, widget: NodeWidget): NodeRegistry {\n const next = new Map(this.widgets);\n next.set(kind, widget);\n return new NodeRegistry(next);\n }\n\n register(kind: string, widget: NodeWidget): NodeRegistry {\n return this.override(kind, widget);\n }\n\n get(kind: string): NodeWidget | undefined {\n return this.widgets.get(kind);\n }\n\n has(kind: string): boolean {\n return this.widgets.has(kind);\n }\n}\n","/**\n * 职责:默认 registry 工厂别名,供 AgentSession 内部使用。\n * 链路位置:AgentSession 未传 registry 时的 fallback。\n * 当前裁剪范围:委托 NodeRegistry.default()。\n */\nimport { NodeRegistry } from './NodeRegistry';\n\nexport function createDefaultRegistry(): NodeRegistry {\n return NodeRegistry.default();\n}\n","/**\n * 职责:多会话顶层 store,按 sessionId 路由事件到独立 SessionTree。\n * 链路位置:MultiAgentSession 消费;业务也可直接 createMultiSessionStore。\n * 当前裁剪范围:进程内 LRU(默认 10);不含 Source 生命周期管理。\n */\nimport { createStore, type StoreApi } from 'zustand/vanilla';\n\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport { createEmptyTree, type ReducerError, type SessionTree } from '../types/tree';\nimport { replayEvents } from './replay';\nimport { reduceTree, type ReduceOptions } from './reducer';\nimport { markEventIdSeen, shouldSkipDuplicateEvent } from './dedupe';\nimport type { SessionStoreState } from './store';\nimport type { SourceEventContext } from '../transport/types';\n\nexport interface SessionSlice {\n tree: SessionTree;\n eventCount: number;\n}\n\nexport interface MultiSessionStoreOptions {\n maxSessions?: number;\n tierOverrides?: TierOverrides;\n debug?: boolean;\n /** 初始活跃 session;默认 null */\n activeSessionId?: string | null;\n}\n\nexport interface MultiSessionStoreState {\n sessions: Record<string, SessionSlice>;\n activeSessionId: string | null;\n order: string[];\n applyEvent: (sessionId: string, event: LangchainAgentEvent, ctx?: SourceEventContext) => void;\n applyEvents: (sessionId: string, events: LangchainAgentEvent[]) => void;\n setActiveSessionId: (id: string | null) => void;\n removeSession: (id: string) => void;\n replaySession: (sessionId: string, events: LangchainAgentEvent[]) => void;\n ensureSession: (sessionId: string, initialEvents?: LangchainAgentEvent[]) => void;\n getSessionTree: (sessionId: string) => SessionTree | undefined;\n}\n\nconst DEFAULT_MAX_SESSIONS = 10;\n\nfunction touchOrder(order: string[], sessionId: string): string[] {\n return [...order.filter((id) => id !== sessionId), sessionId];\n}\n\nfunction safeReduce(\n tree: SessionTree,\n event: LangchainAgentEvent,\n eventIndex: number,\n options?: ReduceOptions,\n): SessionTree {\n try {\n return reduceTree(tree, event, eventIndex, options);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const stack = err instanceof Error ? err.stack : undefined;\n if (import.meta.env?.DEV) {\n console.error('[langchain_agentx_stream_ui] reducer error:', err);\n }\n const reducerError: ReducerError = {\n eventIndex,\n eventType: event.event_type,\n message,\n stack,\n };\n return {\n ...tree,\n internalErrors: [...tree.internalErrors, reducerError],\n };\n }\n}\n\nfunction evictSessions(\n sessions: Record<string, SessionSlice>,\n order: string[],\n maxSessions: number,\n activeSessionId: string | null,\n): { sessions: Record<string, SessionSlice>; order: string[] } {\n let nextSessions = { ...sessions };\n let nextOrder = [...order];\n while (nextOrder.length > maxSessions) {\n const candidate = nextOrder.find((id) => id !== activeSessionId) ?? nextOrder[0];\n if (!candidate) break;\n const { [candidate]: _removed, ...rest } = nextSessions;\n nextSessions = rest;\n nextOrder = nextOrder.filter((id) => id !== candidate);\n }\n return { sessions: nextSessions, order: nextOrder };\n}\n\nexport function createMultiSessionStore(\n options?: MultiSessionStoreOptions,\n): StoreApi<MultiSessionStoreState> {\n const maxSessions = options?.maxSessions ?? DEFAULT_MAX_SESSIONS;\n const reduceOpts: ReduceOptions = {\n tierOverrides: options?.tierOverrides,\n collectDebug: options?.debug === true,\n };\n const replayOpts = {\n tierOverrides: options?.tierOverrides,\n collectDebug: options?.debug === true,\n };\n const seenBySession = new Map<string, Set<string>>();\n\n function getSeenSet(sessionId: string): Set<string> {\n let set = seenBySession.get(sessionId);\n if (!set) {\n set = new Set<string>();\n seenBySession.set(sessionId, set);\n }\n return set;\n }\n\n return createStore<MultiSessionStoreState>((set, get) => ({\n sessions: {},\n activeSessionId: options?.activeSessionId ?? null,\n order: [],\n\n getSessionTree(sessionId) {\n return get().sessions[sessionId]?.tree;\n },\n\n ensureSession(sessionId, initialEvents) {\n const state = get();\n if (state.sessions[sessionId]) return;\n\n const tree =\n initialEvents && initialEvents.length > 0\n ? replayEvents(initialEvents, replayOpts)\n : createEmptyTree();\n const slice: SessionSlice = {\n tree,\n eventCount: initialEvents?.length ?? 0,\n };\n let order = touchOrder(state.order, sessionId);\n let sessions = { ...state.sessions, [sessionId]: slice };\n ({ sessions, order } = evictSessions(sessions, order, maxSessions, state.activeSessionId));\n\n set({\n sessions,\n order,\n activeSessionId: state.activeSessionId ?? sessionId,\n });\n },\n\n applyEvent(sessionId, event, ctx) {\n const sseEventId = ctx?.sseEventId;\n const seen = getSeenSet(sessionId);\n if (shouldSkipDuplicateEvent(seen, sseEventId)) return;\n\n const state = get();\n let slice = state.sessions[sessionId];\n if (!slice) {\n get().ensureSession(sessionId);\n slice = get().sessions[sessionId]!;\n }\n const reduced = safeReduce(slice.tree, event, slice.eventCount, reduceOpts);\n const nextTree: SessionTree =\n sseEventId\n ? { ...reduced, meta: { ...reduced.meta, lastEventId: sseEventId } }\n : reduced;\n const nextSlice: SessionSlice = {\n tree: nextTree,\n eventCount: slice.eventCount + 1,\n };\n markEventIdSeen(seen, sseEventId);\n let sessions = { ...state.sessions, [sessionId]: nextSlice };\n let order = touchOrder(state.order, sessionId);\n ({ sessions, order } = evictSessions(sessions, order, maxSessions, state.activeSessionId));\n set({ sessions, order });\n },\n\n applyEvents(sessionId, events) {\n for (const event of events) {\n get().applyEvent(sessionId, event);\n }\n },\n\n setActiveSessionId(id) {\n set({ activeSessionId: id });\n },\n\n removeSession(sessionId) {\n const state = get();\n if (!state.sessions[sessionId]) return;\n seenBySession.delete(sessionId);\n const { [sessionId]: _removed, ...sessions } = state.sessions;\n const order = state.order.filter((id) => id !== sessionId);\n const activeSessionId =\n state.activeSessionId === sessionId\n ? (order[order.length - 1] ?? null)\n : state.activeSessionId;\n set({ sessions, order, activeSessionId });\n },\n\n replaySession(sessionId, events) {\n const tree = replayEvents(events, replayOpts);\n const slice: SessionSlice = { tree, eventCount: events.length };\n const state = get();\n let order = touchOrder(state.order, sessionId);\n let sessions = { ...state.sessions, [sessionId]: slice };\n ({ sessions, order } = evictSessions(sessions, order, maxSessions, state.activeSessionId));\n set({ sessions, order });\n },\n }));\n}\n\nexport type MultiSessionStore = StoreApi<MultiSessionStoreState>;\n\n/** 将 MultiSessionStore 活跃会话投影为 SessionStore,供 Timeline hooks 复用。 */\nexport function createActiveSessionBridge(multiStore: MultiSessionStore): StoreApi<SessionStoreState> {\n type BridgeState = Pick<SessionStoreState, 'tree' | 'eventCount' | 'applyEvent' | 'applyEvents' | 'reset'>;\n\n const bridge = createStore<BridgeState>(() => ({\n tree: createEmptyTree(),\n eventCount: 0,\n applyEvent(event, ctx) {\n const id = multiStore.getState().activeSessionId;\n if (id) multiStore.getState().applyEvent(id, event, ctx);\n },\n applyEvents(events) {\n const id = multiStore.getState().activeSessionId;\n if (id) multiStore.getState().applyEvents(id, events);\n },\n reset() {\n const id = multiStore.getState().activeSessionId;\n if (id) multiStore.getState().replaySession(id, []);\n },\n }));\n\n const sync = (): void => {\n const { activeSessionId, sessions } = multiStore.getState();\n const slice = activeSessionId ? sessions[activeSessionId] : undefined;\n bridge.setState({\n tree: slice?.tree ?? createEmptyTree(),\n eventCount: slice?.eventCount ?? 0,\n });\n };\n\n multiStore.subscribe(sync);\n sync();\n return bridge as StoreApi<SessionStoreState>;\n}\n","/**\n * 职责:SSE 事件 id 幂等去重(M4 续传重叠帧)。\n * 链路位置:SessionStore / MultiSessionStore applyEvent 前置检查。\n * 当前裁剪范围:按 sseEventId 字符串去重;无 id 时始终应用。\n */\n\nexport function shouldSkipDuplicateEvent(\n seenEventIds: ReadonlySet<string>,\n sseEventId: string | undefined,\n): boolean {\n if (!sseEventId) return false;\n return seenEventIds.has(sseEventId);\n}\n\nexport function markEventIdSeen(\n seenEventIds: Set<string>,\n sseEventId: string | undefined,\n): void {\n if (sseEventId) seenEventIds.add(sseEventId);\n}\n","/**\n * 职责:多会话顶层容器,每 session 独立 Source + initialEvents,共享 MultiSessionStore。\n * 链路位置:业务多 Tab / 双路 SSE;Timeline 只渲染 activeSessionId 对应树。\n * 当前裁剪范围:薄封装;Source 生命周期由本组件管理;LRU 默认 10。\n */\nimport { useEffect, useMemo, useRef, type ReactNode } from 'react';\n\nimport {\n createMultiSessionStore,\n createActiveSessionBridge,\n type MultiSessionStore,\n} from '../core/sessionStore';\nimport {\n MultiSessionStoreContext,\n SessionStoreContext,\n NodeRegistryContext,\n ToolDisplayOptionsContext,\n SessionViewOptionsContext,\n} from '../core/context/SessionContext';\nimport type { Source } from '../transport/types';\nimport type { LangchainAgentEvent, TierOverrides } from '../types/events';\nimport type { ReducerError } from '../types/tree';\nimport { createDefaultRegistry } from './defaultRegistry';\nimport type { NodeRegistry } from './NodeRegistry';\nimport { SessionTimeline } from './SessionTimeline';\nimport { InteractionBusContext } from '../core/context/InteractionContext';\nimport type { InteractionBus } from '../core/interaction/InteractionBus';\nimport { getNoopInteractionBus } from '../core/interaction/InteractionBus';\nimport { useInternalErrors, useSessionStatus } from '../core/hooks';\nimport {\n createDefaultToolRegistry,\n type ToolDisplayRegistry,\n} from './tools/registry';\nimport type { ToolBodyMode } from './tools/types';\nimport type { MarkdownRenderer } from '../core/context/MarkdownRendererContext';\nimport { MarkdownRendererContext } from '../core/context/MarkdownRendererContext';\nimport type { PermissionUiMode } from './sessionViewOptions';\nimport { DEFAULT_SESSION_VIEW_OPTIONS } from './sessionViewOptions';\n\nexport interface MultiSessionSourceConfig {\n sessionId: string;\n source: Source;\n /** EventBuffer ingest 快照或历史事件;挂载时 replay 后再接 source 续流(M3) */\n initialEvents?: LangchainAgentEvent[];\n}\n\nexport interface MultiAgentSessionProps {\n sessions: MultiSessionSourceConfig[];\n /** 受控活跃 session */\n activeSessionId?: string | null;\n /** 非受控默认活跃 session */\n defaultActiveSessionId?: string | null;\n onActiveSessionChange?: (sessionId: string | null) => void;\n maxSessions?: number;\n tierOverrides?: TierOverrides;\n debug?: boolean;\n registry?: NodeRegistry;\n onError?: (error: Error, sessionId: string) => void;\n virtualized?: boolean;\n virtualizeThreshold?: number;\n interactionBus?: InteractionBus;\n toolDisplayRegistry?: ToolDisplayRegistry;\n defaultBodyMode?: ToolBodyMode;\n groupParallelTools?: boolean;\n permissionUiMode?: PermissionUiMode;\n markdownRenderer?: MarkdownRenderer;\n children?: ReactNode;\n}\n\nfunction DebugPanel() {\n const status = useSessionStatus();\n const errors = useInternalErrors();\n if (errors.length === 0) return null;\n return (\n <div className=\"lax-debug-panel\" data-testid=\"lax-debug-panel\">\n <div>status: {status}</div>\n <ul>\n {errors.map((err: ReducerError, i: number) => (\n <li key={`${err.eventIndex}-${i}`}>\n [{err.eventType}] {err.message}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\nexport function MultiAgentSession({\n sessions,\n activeSessionId: controlledActiveId,\n defaultActiveSessionId,\n onActiveSessionChange,\n maxSessions,\n tierOverrides,\n debug = false,\n registry,\n onError,\n virtualized = false,\n virtualizeThreshold,\n interactionBus,\n toolDisplayRegistry,\n defaultBodyMode = 'preview',\n groupParallelTools = false,\n permissionUiMode = 'standalone',\n markdownRenderer,\n children,\n}: MultiAgentSessionProps) {\n const multiStoreRef = useRef<MultiSessionStore | null>(null);\n const bridgeRef = useRef<ReturnType<typeof createActiveSessionBridge> | null>(null);\n\n if (multiStoreRef.current === null) {\n const defaultId =\n defaultActiveSessionId ??\n controlledActiveId ??\n sessions[0]?.sessionId ??\n null;\n multiStoreRef.current = createMultiSessionStore({\n maxSessions,\n tierOverrides,\n debug,\n activeSessionId: defaultId,\n });\n bridgeRef.current = createActiveSessionBridge(multiStoreRef.current);\n for (const cfg of sessions) {\n multiStoreRef.current.getState().ensureSession(cfg.sessionId, cfg.initialEvents);\n }\n }\n\n const registryRef = useMemo(() => registry ?? createDefaultRegistry(), [registry]);\n const busRef = useMemo(\n () => interactionBus ?? getNoopInteractionBus(),\n [interactionBus],\n );\n const toolDisplayRef = useMemo(\n () => ({\n registry: toolDisplayRegistry ?? createDefaultToolRegistry(),\n defaultBodyMode,\n }),\n [toolDisplayRegistry, defaultBodyMode],\n );\n const sessionViewRef = useMemo(\n () => ({\n ...DEFAULT_SESSION_VIEW_OPTIONS,\n groupParallelTools,\n permissionUiMode,\n verboseReasoning: debug,\n }),\n [groupParallelTools, permissionUiMode, debug],\n );\n\n useEffect(() => {\n if (controlledActiveId === undefined) return;\n multiStoreRef.current!.getState().setActiveSessionId(controlledActiveId);\n }, [controlledActiveId]);\n\n useEffect(() => {\n if (!onActiveSessionChange) return;\n return multiStoreRef.current!.subscribe((state) => {\n onActiveSessionChange(state.activeSessionId);\n });\n }, [onActiveSessionChange]);\n\n useEffect(() => {\n const multiStore = multiStoreRef.current!;\n const controllers = sessions.map((cfg) => {\n const controller = new AbortController();\n multiStore.getState().ensureSession(cfg.sessionId, cfg.initialEvents);\n void cfg.source.start((event, ctx) => {\n multiStore.getState().applyEvent(cfg.sessionId, event, ctx);\n }, controller.signal).catch((err: unknown) => {\n const error = err instanceof Error ? err : new Error(String(err));\n onError?.(error, cfg.sessionId);\n });\n return controller;\n });\n return () => {\n for (const c of controllers) c.abort();\n };\n }, [sessions, onError]);\n\n return (\n <MultiSessionStoreContext.Provider value={multiStoreRef.current!}>\n <SessionStoreContext.Provider value={bridgeRef.current!}>\n <InteractionBusContext.Provider value={busRef}>\n <NodeRegistryContext.Provider value={registryRef}>\n <MarkdownRendererContext.Provider value={markdownRenderer}>\n <ToolDisplayOptionsContext.Provider value={toolDisplayRef}>\n <SessionViewOptionsContext.Provider value={sessionViewRef}>\n <div className=\"lax-agent-session lax-multi-agent-session\" data-testid=\"lax-multi-agent-session\">\n {children ?? (\n <SessionTimeline\n virtualized={virtualized}\n virtualizeThreshold={virtualizeThreshold}\n groupParallelTools={groupParallelTools}\n />\n )}\n {debug ? <DebugPanel /> : null}\n </div>\n </SessionViewOptionsContext.Provider>\n </ToolDisplayOptionsContext.Provider>\n </MarkdownRendererContext.Provider>\n </NodeRegistryContext.Provider>\n </InteractionBusContext.Provider>\n </SessionStoreContext.Provider>\n </MultiSessionStoreContext.Provider>\n );\n}\n"],"mappings":"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","names":["useEffect","useRef","useState","useEffect","useState","useEffect","useRef","useState","useState","useRef","useEffect","jsx","jsxs","useState","useRef","useEffect","jsx","jsxs","useEffect","useState","Fragment","jsx","jsxs","useState","useEffect","useMemo","SyntaxHighlighter","oneDark","jsx","jsxs","SyntaxHighlighter","oneDark","jsx","useMemo","jsx","jsxs","useRef","jsx","jsxs","useRef","jsx","jsxs","useEffect","useState","jsx","useState","useEffect","jsx","jsx","jsxs","jsx","jsxs","useState","jsx","jsxs","useState","jsx","jsxs","useEffect","useMemo","useRef","jsx","jsxs","useRef","useMemo","useEffect"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/view/tools/toolNames.ts","../src/view/tools/presentation/agentProgressRenderer.ts","../src/view/tools/presentation/agentHelpers.ts","../src/view/tools/agent/AgentProgressLines.tsx","../src/view/tools/agent/AgentToolBody.tsx","../src/view/tools/displayRecord.ts","../src/view/tools/presentation/askUserHelpers.ts","../src/view/tools/ask_user_question/AskUserQuestionToolBody.tsx","../src/view/tools/bash/BashToolBody.tsx","../src/view/tools/edit/EditToolBody.tsx","../src/view/tools/glob/GlobToolBody.tsx","../src/view/tools/grep/GrepToolBody.tsx","../src/view/tools/read/ReadToolBody.tsx","../src/view/tools/skill/SkillToolBody.tsx","../src/view/tools/webfetch/WebFetchToolBody.tsx","../src/view/tools/websearch/WebSearchToolBody.tsx","../src/view/tools/write/WriteToolBody.tsx","../src/view/tools/registry.ts"],"sourcesContent":["/**\n * toolNames.ts — CC PascalCase 工具名 SSOT(对齐 SDK registry_names.py)\n *\n * 职责:Stream UI widget / projection / reducer 消费的工具名字面量唯一来源。\n * 链路位置:registry.ts、classify.ts、memoryPaths.ts、reducer.ts。\n * 当前裁剪范围:无 legacy alias、无 *Tool 后缀变体、无 REMOVED 双轨表。\n */\n\nexport const Read = 'Read';\nexport const Write = 'Write';\nexport const Edit = 'Edit';\nexport const Glob = 'Glob';\nexport const Grep = 'Grep';\nexport const Bash = 'Bash';\nexport const Skill = 'Skill';\nexport const Agent = 'Agent';\nexport const AskUserQuestion = 'AskUserQuestion';\nexport const WebSearch = 'WebSearch';\nexport const WebFetch = 'WebFetch';\n\nexport const TaskCreate = 'TaskCreate';\nexport const TaskUpdate = 'TaskUpdate';\nexport const TaskList = 'TaskList';\nexport const TaskGet = 'TaskGet';\nexport const TaskOutput = 'TaskOutput';\nexport const TaskStop = 'TaskStop';\n\n/** SSE 抑制 + Timeline hidden:SDK Task* 内部工具(仅 CC 注册名) */\nexport const SILENT_TASK_TOOL_NAMES: readonly string[] = [\n TaskCreate,\n TaskGet,\n TaskList,\n TaskUpdate,\n];\n\n/** reducer 不渲染的内部工具(= SILENT_TASK + TaskOutput/TaskStop) */\nexport const INTERNAL_TOOL_NAMES: ReadonlySet<string> = new Set([\n ...SILENT_TASK_TOOL_NAMES,\n TaskOutput,\n TaskStop,\n]);\n\n/** CC 核心文件/Shell 工具名(门禁:src 中禁止 legacy 小写 alias) */\nexport const CC_CORE_TOOL_NAMES: readonly string[] = [\n Read,\n Write,\n Edit,\n Glob,\n Grep,\n Bash,\n Skill,\n Agent,\n AskUserQuestion,\n WebSearch,\n WebFetch,\n];\n\n/** 单测负向样本:legacy 名不得出现在 src(由 TN-006 guard 扫描) */\nexport const LEGACY_TOOL_NAME_SAMPLES: readonly string[] = [\n 'read',\n 'read_file',\n 'write',\n 'edit',\n 'glob',\n 'grep',\n 'bash',\n 'skill',\n 'agent',\n 'Task',\n 'search',\n 'list',\n 'batch_edit',\n];\n","/**\n * agentProgressRenderer.ts — Agent 子工具 progress 行(对齐 CLI progress_renderer.py)\n */\nimport type { SubagentProgressEntry } from '../../../types/nodes';\nimport { truncateCommand } from './bashHelpers';\n\nexport const AGENT_PROGRESS_GUTTER = ' ⎿ ';\nexport const AGENT_PROGRESS_INDENT = ' ';\n\nfunction truncatePreview(text: string, maxChars = 80): string {\n const trimmed = text.trim();\n if (trimmed.length <= maxChars) return trimmed;\n return `${trimmed.slice(0, maxChars)}…`;\n}\n\nconst READ_TOOLS = new Set(['Read']);\nconst SEARCH_TOOLS = new Set(['Glob', 'Grep', 'SemanticSearch', 'Search']);\nconst BASH_TOOLS = new Set(['Bash']);\n\nexport interface ProcessedProgressLine {\n text: string;\n toolUseCount: number;\n}\n\nfunction toolInputRecord(input: unknown): Record<string, unknown> {\n if (input != null && typeof input === 'object' && !Array.isArray(input)) {\n return input as Record<string, unknown>;\n }\n return {};\n}\n\n/** 对齐 CLI format_subagent_tool_progress_line:Bash(cmd) / Read(path) / Glob(pattern)。 */\nexport function formatSubagentToolProgressLine(\n toolName: string,\n options: { summary?: string; toolInput?: unknown } = {},\n): string {\n const name = toolName.trim();\n const inp = toolInputRecord(options.toolInput);\n\n if (name === 'Bash') {\n const command = String(inp.command ?? inp.description ?? '').trim();\n if (command) return `Bash(${truncateCommand(command)})`;\n }\n if (name === 'Read') {\n const path = String(inp.path ?? inp.file_path ?? '').trim();\n if (path) return `Read(${truncatePreview(path, 60)})`;\n }\n if (name === 'Glob' || name === 'Grep') {\n const pattern = String(inp.pattern ?? inp.glob_pattern ?? '').trim();\n const path = String(inp.path ?? inp.glob ?? '').trim();\n if (pattern && path) {\n return `${name}(${truncatePreview(pattern, 40)}, ${truncatePreview(path, 40)})`;\n }\n if (pattern) return `${name}(${truncatePreview(pattern, 60)})`;\n if (path) return `${name}(${truncatePreview(path, 60)})`;\n }\n\n const summary = (options.summary ?? '').trim();\n const callingLower = `calling ${name.toLowerCase()}`;\n if (summary && summary.toLowerCase() !== callingLower) {\n return summary;\n }\n return name;\n}\n\nexport function formatSubagentProgressLine(entry: SubagentProgressEntry): string {\n return formatSubagentToolProgressLine(entry.toolName, {\n summary: entry.summary,\n toolInput: entry.toolInput,\n });\n}\n\nfunction formatGroupText(\n toolName: string,\n display: string,\n count: number,\n isRead: boolean,\n isSearch: boolean,\n isRunning: boolean,\n): string {\n if (count > 1) {\n if (isRead) {\n const verb = isRunning ? 'Reading' : 'Read';\n const noun = count === 1 ? 'file' : 'files';\n return `${verb} ${count} ${noun}`;\n }\n if (isSearch) {\n return `${toolName} ${count} times`;\n }\n return `${toolName} ${count} times`;\n }\n return display;\n}\n\nfunction groupProgressEntries(\n entries: SubagentProgressEntry[],\n isRunning: boolean,\n): ProcessedProgressLine[] {\n const raw = entries.map((entry) => ({\n toolName: entry.toolName,\n display: formatSubagentProgressLine(entry),\n isError: false,\n }));\n\n const grouped: ProcessedProgressLine[] = [];\n let currentTool: string | null = null;\n let currentDisplay: string | null = null;\n let currentCount = 0;\n let currentIsRead = false;\n let currentIsSearch = false;\n\n const flush = () => {\n if (currentTool == null || currentCount === 0) return;\n grouped.push({\n text: formatGroupText(\n currentTool,\n currentDisplay ?? currentTool,\n currentCount,\n currentIsRead,\n currentIsSearch,\n isRunning,\n ),\n toolUseCount: currentCount,\n });\n currentTool = null;\n currentDisplay = null;\n currentCount = 0;\n currentIsRead = false;\n currentIsSearch = false;\n };\n\n for (const { toolName, display } of raw) {\n const isRead = READ_TOOLS.has(toolName);\n const isSearch = SEARCH_TOOLS.has(toolName);\n const isBash = BASH_TOOLS.has(toolName);\n const sameGroup =\n !isBash &&\n currentTool === toolName &&\n currentIsRead === isRead &&\n currentIsSearch === isSearch;\n\n if (sameGroup) {\n currentCount += 1;\n } else {\n flush();\n currentTool = toolName;\n currentDisplay = display;\n currentCount = 1;\n currentIsRead = isRead;\n currentIsSearch = isSearch;\n }\n }\n flush();\n return grouped;\n}\n\nexport function processAgentProgressLines(\n entries: SubagentProgressEntry[],\n options: { isRunning: boolean; maxVisible: number },\n): { visible: ProcessedProgressLine[]; hiddenToolUseCount: number } {\n const processed = groupProgressEntries(entries, options.isRunning);\n if (options.maxVisible >= processed.length) {\n return { visible: processed, hiddenToolUseCount: 0 };\n }\n const visible = processed.slice(-options.maxVisible);\n const hidden = processed.slice(0, processed.length - options.maxVisible);\n const hiddenToolUseCount = hidden.reduce((sum, line) => sum + line.toolUseCount, 0);\n return { visible, hiddenToolUseCount };\n}\n","/**\n * agentHelpers.ts — Agent 标题与完成摘要\n *\n * 对齐参考:CLI helpers.format_agent_title · parse_agent_done_summary\n */\nimport { truncateLines } from './searchHelpers';\nimport { formatSubagentToolProgressLine } from './agentProgressRenderer';\n\nconst DONE_LINE_RE = /Done \\((.+?)\\)/i;\nconst AGENT_STEPS_RE = /(\\d+)\\s+tool uses?/i;\nexport const AGENT_MAX_BODY_LINES = 25;\nexport const AGENT_PROGRESS_TAIL_LINES = 3;\n\nexport function truncatePreview(text: string, maxChars = 80): string {\n const trimmed = text.trim();\n if (trimmed.length <= maxChars) return trimmed;\n return `${trimmed.slice(0, maxChars)}…`;\n}\n\nexport function formatAgentTitle(input: unknown, display: unknown): string {\n const inp =\n input != null && typeof input === 'object' && !Array.isArray(input)\n ? (input as Record<string, unknown>)\n : {};\n const d =\n display != null && typeof display === 'object' && !Array.isArray(display)\n ? (display as Record<string, unknown>)\n : null;\n\n const merged = { ...inp };\n if (d?.subagent_type) merged.subagent_type = d.subagent_type;\n if (d?.description) merged.description = d.description;\n\n const subagent = String(merged.subagent_type ?? 'general-purpose').trim();\n const desc = String(merged.description ?? merged.prompt ?? '').trim();\n\n let title = desc ? `${subagent}(${truncatePreview(desc)})` : subagent;\n\n const model = merged.model;\n if (model) {\n const modelStr = String(model).trim();\n if (modelStr) title = `${title} ${modelStr}`;\n }\n\n return title;\n}\n\nexport function parseAgentDoneSummary(output: string): string | null {\n const text = output.trim();\n if (!text) return null;\n\n const doneMatch = text.match(DONE_LINE_RE);\n if (doneMatch) return `Done (${doneMatch[1].trim()})`;\n\n const stepsMatch = text.match(AGENT_STEPS_RE);\n if (stepsMatch) return `Done (${stepsMatch[1]} tool uses)`;\n\n const first = text.split('\\n', 1)[0]?.trim() ?? '';\n if (first.toLowerCase().startsWith('done')) return first;\n\n return null;\n}\n\nexport function buildAgentBodyText(display: unknown, summary: string): string {\n const d =\n display != null && typeof display === 'object' && !Array.isArray(display)\n ? (display as Record<string, unknown>)\n : null;\n\n let done: string | null = null;\n if (d?.total_steps != null && d.status === 'completed') {\n done = `Done (${d.total_steps} tool uses)`;\n } else {\n done = parseAgentDoneSummary(summary);\n }\n\n if (done) {\n let rest = summary.trim();\n if (rest.startsWith(done)) {\n rest = rest.slice(done.length).trimStart();\n }\n const parts = [done];\n if (rest) {\n const { text: truncated, truncated: was } = truncateLines(\n rest,\n AGENT_MAX_BODY_LINES,\n );\n parts.push(was ? `${truncated}\\n… 超过 ${AGENT_MAX_BODY_LINES} 行,已截断` : truncated);\n }\n return parts.join('\\n');\n }\n\n const text = summary.trim();\n if (!text) return '(done)';\n\n const { text: truncated, truncated: was } = truncateLines(text, AGENT_MAX_BODY_LINES);\n return was ? `${truncated}\\n… 超过 ${AGENT_MAX_BODY_LINES} 行,已截断` : truncated;\n}\n\nexport function formatSubagentProgressLine(entry: {\n toolName: string;\n summary: string;\n status: string;\n toolInput?: unknown;\n}): string {\n return formatSubagentToolProgressLine(entry.toolName, {\n summary: entry.summary,\n toolInput: entry.toolInput,\n });\n}\n\n/** 完成后展开 transcript:优先 display.tool_calls,否则用 reducer 积累的 progress。 */\nexport function buildAgentTranscriptText(\n display: unknown,\n subagentProgress?: { toolName: string; summary: string; status: string }[],\n): string {\n const d =\n display != null && typeof display === 'object' && !Array.isArray(display)\n ? (display as Record<string, unknown>)\n : null;\n const toolCalls = d?.tool_calls;\n if (Array.isArray(toolCalls) && toolCalls.length > 0) {\n return toolCalls\n .map((row) => {\n const item = row as Record<string, unknown>;\n const name = String(item.tool_name ?? 'tool');\n const summary = String(item.summary ?? '').trim();\n return summary ? `${name}: ${summary}` : name;\n })\n .join('\\n');\n }\n if (subagentProgress?.length) {\n return subagentProgress.map(formatSubagentProgressLine).join('\\n');\n }\n return '';\n}\n","/**\n * AgentProgressLines.tsx — Agent 子工具 progress 折叠行\n *\n * 对齐 CLI AgentProgressLineRenderer · CC AgentTool/UI.tsx renderToolUseProgressMessage\n */\nimport {\n AGENT_PROGRESS_GUTTER,\n AGENT_PROGRESS_INDENT,\n processAgentProgressLines,\n} from '../presentation/agentProgressRenderer';\nimport { AGENT_PROGRESS_TAIL_LINES } from '../presentation/agentHelpers';\nimport type { SubagentProgressEntry } from '../../../types/nodes';\nimport type { ToolBodyMode } from '../types';\n\nexport interface AgentProgressLinesProps {\n entries: SubagentProgressEntry[];\n mode: ToolBodyMode;\n maxVisible?: number;\n onExpand?: () => void;\n}\n\nexport function AgentProgressLines({\n entries,\n mode,\n maxVisible = AGENT_PROGRESS_TAIL_LINES,\n onExpand,\n}: AgentProgressLinesProps) {\n if (entries.length === 0) return null;\n\n const isRunning = entries.some((e) => e.status === 'running');\n const limit = mode === 'full' ? entries.length : maxVisible;\n const { visible, hiddenToolUseCount } = processAgentProgressLines(entries, {\n isRunning,\n maxVisible: limit,\n });\n\n return (\n <div className=\"lax-agent-progress\" data-testid=\"lax-agent-progress\">\n {visible.map((line, index) => (\n <div\n key={`${index}:${line.text}`}\n className=\"lax-agent-progress__line\"\n >\n <span className=\"lax-agent-progress__gutter\" aria-hidden>\n {index === 0 ? AGENT_PROGRESS_GUTTER : AGENT_PROGRESS_INDENT}\n </span>\n <span className=\"lax-agent-progress__text\">{line.text}</span>\n </div>\n ))}\n {hiddenToolUseCount > 0 && mode !== 'full' ? (\n <div className=\"lax-agent-progress__line lax-agent-progress__line--more\">\n <span className=\"lax-agent-progress__gutter\" aria-hidden>\n {AGENT_PROGRESS_INDENT}\n </span>\n <button\n type=\"button\"\n className=\"lax-agent-progress__more\"\n onClick={onExpand}\n >\n +{hiddenToolUseCount} more tool {hiddenToolUseCount === 1 ? 'use' : 'uses'}\n </button>\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * AgentToolBody.tsx — Agent / Task 子代理正文\n *\n * 对齐参考:CLI widgets/tools/agent/widget.py · CC AgentTool/UI.tsx\n */\nimport {\n buildAgentBodyText,\n buildAgentTranscriptText,\n} from '../presentation/agentHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\nimport { AgentProgressLines } from './AgentProgressLines';\n\nexport function AgentToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n status,\n subagentProgress,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--agent\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const progress = subagentProgress ?? [];\n const bodyText = buildAgentBodyText(result?.display, result?.summary ?? '');\n const transcript = buildAgentTranscriptText(result?.display, progress);\n const showRunningProgress = status === 'running' && progress.length > 0;\n const showDoneSummary = status !== 'running' && bodyText.length > 0;\n const showTranscript =\n status === 'done' && bodyMode === 'full' && transcript.length > 0;\n\n if (!showRunningProgress && !showDoneSummary && !showTranscript) {\n return (\n <div className=\"lax-tool-body lax-tool-body--agent\">\n <div className=\"lax-tool-body__block\" data-variant=\"dim\">\n <pre className=\"lax-tool-body__text\">(running)</pre>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"lax-tool-body lax-tool-body--agent\">\n {showRunningProgress ? (\n <AgentProgressLines\n entries={progress}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n ) : null}\n {showDoneSummary ? (\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n ) : null}\n {showTranscript ? (\n <div className=\"lax-agent-progress lax-agent-progress--transcript\">\n <div className=\"lax-agent-progress__label\">Transcript</div>\n <TruncatedContent text={transcript} mode=\"full\" />\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * displayRecord.ts — 从 input / display 安全取字段\n */\n\nexport function asDisplayRecord(\n display: unknown,\n): Record<string, unknown> | null {\n if (display != null && typeof display === 'object' && !Array.isArray(display)) {\n return display as Record<string, unknown>;\n }\n return null;\n}\n\nexport function asInputRecord(input: unknown): Record<string, unknown> {\n if (input != null && typeof input === 'object' && !Array.isArray(input)) {\n return input as Record<string, unknown>;\n }\n return {};\n}\n\nexport function strField(record: Record<string, unknown>, key: string): string {\n const value = record[key];\n return value == null ? '' : String(value).trim();\n}\n\nexport function numField(record: Record<string, unknown>, key: string): number | undefined {\n const value = record[key];\n if (typeof value === 'number' && Number.isFinite(value)) return value;\n if (typeof value === 'string' && value.trim() !== '') {\n const n = Number(value);\n if (Number.isFinite(n)) return n;\n }\n return undefined;\n}\n","/**\n * askUserHelpers.ts — AskUserQuestion 正文与预览\n *\n * 对齐参考:CLI widgets/tools/helpers.py format_ask_user_*\n */\nexport function formatAskUserDisplayBody(display: Record<string, unknown>): string {\n const items = display.questions;\n if (!Array.isArray(items) || items.length === 0) return '';\n\n const lines: string[] = [];\n for (const item of items) {\n if (item == null || typeof item !== 'object') continue;\n const row = item as Record<string, unknown>;\n const header = String(row.header ?? '').trim();\n const question = String(row.question ?? '').trim();\n const answer = String(row.answer ?? '').trim();\n const prefix = header ? `[${header}] ` : '';\n lines.push(`${prefix}${question}`);\n if (answer) lines.push(` → ${answer}`);\n const selected = row.selected_options;\n if (Array.isArray(selected) && selected.length > 0) {\n for (const label of selected) {\n lines.push(` · ${String(label)}`);\n }\n }\n }\n return lines.length > 0 ? lines.join('\\n') : '';\n}\n\nexport function formatAskUserQuestionsPreview(input: Record<string, unknown>): string {\n const questions = input.questions;\n if (!Array.isArray(questions) || questions.length === 0) {\n return '(waiting for answers)';\n }\n\n const lines: string[] = [];\n questions.forEach((raw, idx) => {\n if (raw == null || typeof raw !== 'object') return;\n const q = raw as Record<string, unknown>;\n const header = String(q.header ?? '').trim();\n const qtext = String(q.question ?? '').trim();\n const prefix = header ? `[${header}] ` : '';\n lines.push(`${idx + 1}. ${prefix}${qtext}`);\n const options = q.options;\n if (Array.isArray(options)) {\n for (const opt of options) {\n if (opt != null && typeof opt === 'object') {\n const label = String((opt as Record<string, unknown>).label ?? '').trim();\n if (label) lines.push(` · ${label}`);\n }\n }\n }\n });\n return lines.length > 0 ? lines.join('\\n') : '(waiting for answers)';\n}\n","/**\n * AskUserQuestionToolBody.tsx — AskUserQuestion 工具正文\n *\n * 对齐参考:CLI widgets/tools/ask_user_question/widget.py\n */\nimport { asDisplayRecord, asInputRecord } from '../displayRecord';\nimport {\n formatAskUserDisplayBody,\n formatAskUserQuestionsPreview,\n} from '../presentation/askUserHelpers';\nimport { truncateLines } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst MAX_DISPLAY_LINES = 25;\nconst MAX_DISPLAY_CHARS = 1200;\n\nfunction buildAskUserBody(\n input: unknown,\n display: unknown,\n summary: string,\n): string {\n const d = asDisplayRecord(display);\n if (d) {\n const displayBody = formatAskUserDisplayBody(d);\n if (displayBody) {\n if (displayBody.length > MAX_DISPLAY_CHARS) {\n const { text, truncated } = truncateLines(displayBody, MAX_DISPLAY_LINES);\n return truncated ? `${text}\\n… 已截断` : text;\n }\n return displayBody;\n }\n }\n\n const text = summary.trim();\n if (text) return `Answered: ${text}`;\n\n return formatAskUserQuestionsPreview(asInputRecord(input));\n}\n\nexport function AskUserQuestionToolBody({\n input,\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--ask-user\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildAskUserBody(input, result?.display, result?.summary ?? '');\n\n return (\n <div className=\"lax-tool-body lax-tool-body--ask-user\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * BashToolBody.tsx — bash 工具多块 stdout/stderr 正文\n *\n * 对齐参考:CLI widgets/tools/bash/widget.py · CC BashTool/UI.tsx\n */\nimport { BodyBlockList } from '../presentation/BodyBlockList';\nimport { buildBashBodyBlocks } from '../presentation/bashHelpers';\nimport type { ToolDisplayProps } from '../types';\n\nexport function BashToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n const isError = result?.status === 'failed' || Boolean(result?.error);\n const summary = result?.summary ?? '';\n const { blocks, truncated, remainingLines } = buildBashBodyBlocks(\n result?.display,\n summary,\n result?.meta,\n bodyMode,\n isError,\n );\n\n return (\n <div className=\"lax-tool-body lax-tool-body--bash\">\n <BodyBlockList blocks={blocks} />\n {truncated && bodyMode === 'preview' ? (\n <button\n type=\"button\"\n className=\"lax-tool-body__expand\"\n onClick={() => onBodyModeChange?.('full')}\n >\n +{remainingLines} lines (点击展开)\n </button>\n ) : null}\n </div>\n );\n}\n","/**\n * EditToolBody.tsx — edit 工具正文(unified diff)\n *\n * 对齐参考:CLI widgets/tools/edit/widget.py · CC FileEditToolDiff.tsx\n */\nimport { resolveEditDiffText } from '../presentation/diffHelpers';\nimport { DiffView } from '../presentation/DiffView';\nimport type { ToolDisplayProps } from '../types';\n\nexport function EditToolBody({\n input,\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--edit\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const diff = resolveEditDiffText(\n result?.display,\n input,\n result?.summary ?? '',\n );\n\n return (\n <div className=\"lax-tool-body lax-tool-body--edit\">\n <DiffView\n diff={diff}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * GlobToolBody.tsx — glob 工具正文\n *\n * 对齐参考:CLI widgets/tools/glob/widget.py · helpers.format_search_result_body\n */\nimport { asDisplayRecord } from '../displayRecord';\nimport { formatSearchResultBody } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nfunction buildGlobBodyText(result: ToolDisplayProps['result']): string {\n const d = asDisplayRecord(result?.display);\n\n if (d?.type === 'file_list') {\n const files = Array.isArray(d.files) ? d.files.map((f) => String(f)) : [];\n const numFiles =\n typeof d.num_files === 'number' ? d.num_files : files.length;\n const summary =\n numFiles > 0 ? `Found ${numFiles} files` : 'No files found';\n if (files.length > 0) {\n return formatSearchResultBody(`${summary}\\n${files.join('\\n')}`);\n }\n return summary;\n }\n\n if (Array.isArray(d?.files)) {\n const files = d.files.map((f) => String(f));\n const summary = `Found ${files.length} files`;\n return formatSearchResultBody(`${summary}\\n${files.join('\\n')}`);\n }\n\n const summary = result?.summary?.trim() ?? '';\n if (summary) return formatSearchResultBody(summary);\n\n return '(No output)';\n}\n\nexport function GlobToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--glob\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildGlobBodyText(result);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--glob\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * GrepToolBody.tsx — grep 工具正文\n *\n * 对齐参考:CLI widgets/tools/grep/widget.py · helpers.format_search_result_body\n */\nimport { asDisplayRecord } from '../displayRecord';\nimport { formatSearchResultBody } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nfunction buildGrepBodyText(result: ToolDisplayProps['result']): string {\n const d = asDisplayRecord(result?.display);\n\n if (d?.type === 'search_results') {\n const matches = Array.isArray(d.matches)\n ? d.matches.map((m) => String(m))\n : [];\n const numMatches =\n typeof d.num_matches === 'number' ? d.num_matches : matches.length;\n const summary =\n numMatches > 0\n ? `Found ${numMatches} matches`\n : 'No matches found';\n if (matches.length > 0) {\n return formatSearchResultBody(`${summary}\\n${matches.join('\\n')}`);\n }\n return summary;\n }\n\n if (Array.isArray(d?.matches)) {\n const matches = d.matches.map((m) => String(m));\n const summary = `Found ${matches.length} matches`;\n return formatSearchResultBody(`${summary}\\n${matches.join('\\n')}`);\n }\n\n const summary = result?.summary?.trim() ?? '';\n if (summary) return formatSearchResultBody(summary);\n\n return '(No output)';\n}\n\nexport function GrepToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--grep\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildGrepBodyText(result);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--grep\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * ReadToolBody.tsx — Read 工具正文\n *\n * 对齐参考:CLI widgets/tools/read/widget.py format_body · CC FileReadTool/UI.tsx\n */\nimport { asDisplayRecord, numField, strField } from '../displayRecord';\nimport { BodyBlockList } from '../presentation/BodyBlockList';\nimport { MarkdownBlock } from '../presentation/MarkdownBlock';\nimport { MAX_PREVIEW_LINES } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst LINES_RANGE_RE = /lines (\\d+)-(\\d+) of (\\d+)/i;\nconst READ_LINES_RE = /Read (\\d+) lines from/i;\nconst EMPTY_RE = /\\(empty file\\)/i;\nconst NOTEBOOK_RE = /Read notebook.*?(\\d+) cells/i;\nconst IMAGE_RE = /Read image/i;\nconst PDF_RE = /Read PDF/i;\n\nfunction formatReadBodySummary(display: unknown, summary: string): string {\n const d = asDisplayRecord(display);\n\n if (d?.type === 'text') {\n const start = numField(d, 'line_start');\n const end = numField(d, 'line_end');\n const total = numField(d, 'total_lines');\n if (start != null && end != null && total != null) {\n return `Read lines ${start}–${end} of ${total}`;\n }\n const numLines = numField(d, 'num_lines');\n if (numLines != null) {\n return `Read ${numLines} lines`;\n }\n }\n\n if (d?.type === 'image') {\n const w = strField(d, 'width');\n const h = strField(d, 'height');\n if (w && h) return `Read image (${w}×${h})`;\n return 'Read image';\n }\n\n if (d?.type === 'pdf') {\n const ps = numField(d, 'page_start');\n const pe = numField(d, 'page_end');\n if (ps != null && pe != null) {\n return `Read PDF pages ${ps}–${pe}`;\n }\n return 'Read PDF';\n }\n\n const text = summary.trim();\n if (!text) return '(done)';\n\n if (EMPTY_RE.test(text)) return 'Empty file';\n const notebook = text.match(NOTEBOOK_RE);\n if (notebook) return `Read ${notebook[1]} cells`;\n if (IMAGE_RE.test(text)) return text.split('\\n', 1)[0]?.trim() || 'Read image';\n if (PDF_RE.test(text)) return text.split('\\n', 1)[0]?.trim() || 'Read PDF';\n\n const range = text.match(LINES_RANGE_RE);\n if (range) {\n return `Read lines ${range[1]}–${range[2]} of ${range[3]}`;\n }\n const readLines = text.match(READ_LINES_RE);\n if (readLines) return `Read ${readLines[1]} lines`;\n\n if (text.length > 500) {\n const lineCount = text.split('\\n').length;\n return `Read complete (${lineCount} lines in result)`;\n }\n\n return text.slice(0, 200) || '(done)';\n}\n\nfunction extractReadContent(display: unknown): string | null {\n const d = asDisplayRecord(display);\n if (!d) return null;\n if (d.type === 'markdown' || d.type === 'text') {\n const content = strField(d, 'content');\n if (content) return content;\n }\n return null;\n}\n\nexport function ReadToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n const display = result?.display ?? null;\n const summary = result?.summary ?? '';\n const bodyLine = formatReadBodySummary(display, summary);\n const content = extractReadContent(display);\n const d = asDisplayRecord(display);\n const isMarkdown = d?.type === 'markdown';\n\n // 构建文本 blocks(对齐 BashToolBody)\n const buildTextBlocks = () => {\n if (!content) return [];\n const lines = content.split('\\n');\n const isPreview = bodyMode === 'preview' && lines.length > MAX_PREVIEW_LINES;\n const text = isPreview ? lines.slice(0, MAX_PREVIEW_LINES).join('\\n') : content;\n return [{ text, variant: 'normal' as const }];\n };\n\n const textBlocks = buildTextBlocks();\n const hasMore = content && bodyMode === 'preview' && content.split('\\n').length > MAX_PREVIEW_LINES;\n\n return (\n <div className=\"lax-tool-body lax-tool-body--read\">\n <div className=\"lax-tool-body__summary\">{bodyLine}</div>\n {content ? (\n isMarkdown ? (\n <MarkdownBlock\n text={content}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n ) : (\n <>\n <BodyBlockList blocks={textBlocks} />\n {hasMore ? (\n <button\n type=\"button\"\n className=\"lax-tool-body__expand\"\n onClick={() => onBodyModeChange?.('full')}\n >\n +{content.split('\\n').length - MAX_PREVIEW_LINES} lines (点击展开)\n </button>\n ) : null}\n </>\n )\n ) : null}\n {result?.truncated ? (\n <div className=\"lax-tool-card__truncated\">结果已截断</div>\n ) : null}\n {result?.overflow_file ? (\n <div className=\"lax-tool-card__overflow\">\n 完整输出:\n <code>{result.overflow_file}</code>\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * SkillToolBody.tsx — skill 工具正文\n *\n * 对齐参考:CLI widgets/tools/skill/widget.py · CC SkillTool/UI.tsx\n */\nimport { truncateLines } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst MAX_BODY_LINES = 20;\n\nexport function SkillToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--skill\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const text = result?.summary?.trim() ?? '';\n if (!text) {\n return (\n <div className=\"lax-tool-body lax-tool-body--skill\">\n <div className=\"lax-tool-body__block\" data-variant=\"dim\">\n <pre className=\"lax-tool-body__text\">(done)</pre>\n </div>\n </div>\n );\n }\n\n const { text: truncated, truncated: was } = truncateLines(text, MAX_BODY_LINES);\n const bodyText = was ? `${truncated}\\n… 已截断` : truncated;\n\n return (\n <div className=\"lax-tool-body lax-tool-body--skill\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * WebFetchToolBody.tsx — WebFetch 工具正文\n *\n * 对齐参考:CLI widgets/tools/webfetch/widget.py · CC WebFetchTool/UI.tsx\n */\nimport { asDisplayRecord } from '../displayRecord';\nimport { truncateLines } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst RECEIVED_RE = /Received\\s+.+/i;\nconst MAX_BODY_LINES = 15;\n\nfunction buildWebFetchBody(result: ToolDisplayProps['result']): string {\n const d = asDisplayRecord(result?.display);\n if (d?.content_length != null) {\n const parts = [`Received ${d.content_length} bytes`];\n if (d.duration_ms != null) parts.push(`in ${d.duration_ms}ms`);\n if (d.from_cache) parts.push('(cached)');\n return parts.join(' ');\n }\n\n const text = result?.summary?.trim() ?? '';\n if (!text) return '(done)';\n\n const match = text.match(RECEIVED_RE);\n if (match) {\n const line = match[0].split('\\n', 1)[0] ?? match[0];\n return text.length <= 400 ? text : `${line}\\n…`;\n }\n\n const { text: truncated, truncated: was } = truncateLines(text, MAX_BODY_LINES);\n return was ? `${truncated}\\n… 已截断` : truncated;\n}\n\nexport function WebFetchToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--webfetch\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildWebFetchBody(result);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--webfetch\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * WebSearchToolBody.tsx — WebSearch 工具正文\n *\n * 对齐参考:CLI widgets/tools/websearch/widget.py · CC WebSearchTool/UI.tsx\n */\nimport { asDisplayRecord, strField } from '../displayRecord';\nimport { truncateLines } from '../presentation/searchHelpers';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\n\nconst MAX_BODY_LINES = 15;\n\nfunction buildWebSearchBody(result: ToolDisplayProps['result']): string {\n const d = asDisplayRecord(result?.display);\n if (d?.total_hits != null) {\n const engine = strField(d, 'search_engine') || 'search';\n return `Web search (${engine}): ${d.total_hits} results`;\n }\n\n const text = result?.summary?.trim() ?? '';\n if (!text) return '(done)';\n\n const first = text.split('\\n', 1)[0]?.trim() ?? '';\n if (/^(web search|did |found )/i.test(first)) {\n return text.length < 300 ? text : `${first}\\n…`;\n }\n\n const { text: truncated, truncated: was } = truncateLines(text, MAX_BODY_LINES);\n return was ? `${truncated}\\n… 已截断` : truncated;\n}\n\nexport function WebSearchToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--websearch\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const bodyText = buildWebSearchBody(result);\n\n return (\n <div className=\"lax-tool-body lax-tool-body--websearch\">\n <TruncatedContent\n text={bodyText}\n mode={bodyMode}\n maxLines={12}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * WriteToolBody.tsx — write 工具正文(diff 或新建预览)\n *\n * 对齐参考:CLI widgets/tools/write/widget.py · CC FileWriteTool/UI.tsx\n */\nimport { asDisplayRecord, asInputRecord, strField } from '../displayRecord';\nimport {\n countLines,\n formatDiffFromStrings,\n WRITE_PREVIEW_LINES,\n} from '../presentation/diffHelpers';\nimport { DiffView } from '../presentation/DiffView';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport { displayPath } from '../presentation/paths';\nimport type { ToolDisplayProps } from '../types';\n\nfunction buildWriteBodyText(\n input: unknown,\n display: unknown,\n summary: string,\n): { kind: 'diff' | 'preview' | 'text'; text: string } {\n const d = asDisplayRecord(display);\n const inp = asInputRecord(input);\n const content = strField(inp, 'content');\n const path = displayPath(\n strField(d ?? {}, 'file_path') || strField(inp, 'file_path'),\n );\n const fileType = strField(d ?? {}, 'type');\n\n const original = d?.original_file;\n if (fileType === 'update' && original != null && content) {\n return {\n kind: 'diff',\n text: formatDiffFromStrings(String(original), content),\n };\n }\n\n const diffText = strField(d ?? {}, 'diff');\n if (diffText) {\n return { kind: 'diff', text: diffText };\n }\n\n const numLines =\n typeof d?.num_lines === 'number'\n ? d.num_lines\n : countLines(content);\n\n if (numLines === 0 && !content.trim()) {\n const trimmed = summary.trim();\n return { kind: 'text', text: trimmed || '(No content)' };\n }\n\n const lines = content.split('\\n');\n const preview = lines.slice(0, WRITE_PREVIEW_LINES).join('\\n');\n const remaining = numLines - WRITE_PREVIEW_LINES;\n const header = `Wrote ${numLines} lines to ${path || 'file'}`;\n const body =\n remaining > 0 ? `${header}\\n${preview}\\n… +${remaining} lines` : `${header}\\n${preview}`;\n\n return { kind: 'preview', text: body };\n}\n\nexport function WriteToolBody({\n input,\n result,\n bodyMode,\n onBodyModeChange,\n}: ToolDisplayProps) {\n if (result?.error) {\n return (\n <div className=\"lax-tool-body lax-tool-body--write\">\n <div className=\"lax-tool-body__block\" data-variant=\"error\">\n <pre className=\"lax-tool-body__text\">{result.error.message}</pre>\n </div>\n </div>\n );\n }\n\n const body = buildWriteBodyText(\n input,\n result?.display,\n result?.summary ?? '',\n );\n\n if (body.kind === 'diff') {\n return (\n <div className=\"lax-tool-body lax-tool-body--write\">\n <DiffView\n diff={body.text}\n mode={bodyMode}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n }\n\n return (\n <div className=\"lax-tool-body lax-tool-body--write\">\n <TruncatedContent\n text={body.text}\n mode={bodyMode}\n maxLines={WRITE_PREVIEW_LINES + 1}\n onExpand={() => onBodyModeChange?.('full')}\n />\n </div>\n );\n}\n","/**\n * registry.ts — 工具展示注册表\n */\nimport { AgentToolBody } from './agent/AgentToolBody';\nimport { AskUserQuestionToolBody } from './ask_user_question/AskUserQuestionToolBody';\nimport { BashToolBody } from './bash/BashToolBody';\nimport { EditToolBody } from './edit/EditToolBody';\nimport { GlobToolBody } from './glob/GlobToolBody';\nimport { GrepToolBody } from './grep/GrepToolBody';\nimport { ReadToolBody } from './read/ReadToolBody';\nimport { SkillToolBody } from './skill/SkillToolBody';\nimport { WebFetchToolBody } from './webfetch/WebFetchToolBody';\nimport { WebSearchToolBody } from './websearch/WebSearchToolBody';\nimport { WriteToolBody } from './write/WriteToolBody';\nimport {\n Agent,\n AskUserQuestion,\n Bash,\n Edit,\n Glob,\n Grep,\n Read,\n Skill,\n WebFetch,\n WebSearch,\n Write,\n} from './toolNames';\nimport type { ToolBodyComponent } from './types';\n\nexport class ToolDisplayRegistry {\n private readonly map = new Map<string, ToolBodyComponent>();\n\n register(toolName: string, body: ToolBodyComponent): this {\n this.map.set(toolName, body);\n return this;\n }\n\n resolve(toolName: string): ToolBodyComponent | undefined {\n return this.map.get(toolName);\n }\n\n static default(): ToolDisplayRegistry {\n return createDefaultToolRegistry();\n }\n}\n\n/** 默认 registry:CC TOOL_NAME 单键,与 SDK registry_names.py 对齐。 */\nexport function createDefaultToolRegistry(): ToolDisplayRegistry {\n return new ToolDisplayRegistry()\n .register(Read, ReadToolBody)\n .register(Grep, GrepToolBody)\n .register(Glob, GlobToolBody)\n .register(Edit, EditToolBody)\n .register(Write, WriteToolBody)\n .register(Bash, BashToolBody)\n .register(Agent, AgentToolBody)\n .register(Skill, SkillToolBody)\n .register(AskUserQuestion, AskUserQuestionToolBody)\n .register(WebSearch, WebSearchToolBody)\n .register(WebFetch, WebFetchToolBody);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAQO,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,OAAO;AACb,IAAM,OAAO;AACb,IAAM,OAAO;AACb,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,QAAQ;AACd,IAAM,kBAAkB;AACxB,IAAM,YAAY;AAClB,IAAM,WAAW;AAEjB,IAAM,aAAa;AACnB,IAAM,aAAa;AACnB,IAAM,WAAW;AACjB,IAAM,UAAU;AAChB,IAAM,aAAa;AACnB,IAAM,WAAW;AAGjB,IAAM,yBAA4C;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,sBAA2C,oBAAI,IAAI;AAAA,EAC9D,GAAG;AAAA,EACH;AAAA,EACA;AACF,CAAC;;;AClCM,IAAM,wBAAwB;AAC9B,IAAM,wBAAwB;AAErC,SAAS,gBAAgB,MAAc,WAAW,IAAY;AAC5D,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,QAAQ,UAAU,SAAU,QAAO;AACvC,SAAO,GAAG,QAAQ,MAAM,GAAG,QAAQ,CAAC;AACtC;AAEA,IAAM,aAAa,oBAAI,IAAI,CAAC,MAAM,CAAC;AACnC,IAAM,eAAe,oBAAI,IAAI,CAAC,QAAQ,QAAQ,kBAAkB,QAAQ,CAAC;AACzE,IAAM,aAAa,oBAAI,IAAI,CAAC,MAAM,CAAC;AAOnC,SAAS,gBAAgB,OAAyC;AAChE,MAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AACvE,WAAO;AAAA,EACT;AACA,SAAO,CAAC;AACV;AAGO,SAAS,+BACd,UACA,UAAqD,CAAC,GAC9C;AACR,QAAM,OAAO,SAAS,KAAK;AAC3B,QAAM,MAAM,gBAAgB,QAAQ,SAAS;AAE7C,MAAI,SAAS,QAAQ;AACnB,UAAM,UAAU,OAAO,IAAI,WAAW,IAAI,eAAe,EAAE,EAAE,KAAK;AAClE,QAAI,QAAS,QAAO,QAAQ,gBAAgB,OAAO,CAAC;AAAA,EACtD;AACA,MAAI,SAAS,QAAQ;AACnB,UAAM,OAAO,OAAO,IAAI,QAAQ,IAAI,aAAa,EAAE,EAAE,KAAK;AAC1D,QAAI,KAAM,QAAO,QAAQ,gBAAgB,MAAM,EAAE,CAAC;AAAA,EACpD;AACA,MAAI,SAAS,UAAU,SAAS,QAAQ;AACtC,UAAM,UAAU,OAAO,IAAI,WAAW,IAAI,gBAAgB,EAAE,EAAE,KAAK;AACnE,UAAM,OAAO,OAAO,IAAI,QAAQ,IAAI,QAAQ,EAAE,EAAE,KAAK;AACrD,QAAI,WAAW,MAAM;AACnB,aAAO,GAAG,IAAI,IAAI,gBAAgB,SAAS,EAAE,CAAC,KAAK,gBAAgB,MAAM,EAAE,CAAC;AAAA,IAC9E;AACA,QAAI,QAAS,QAAO,GAAG,IAAI,IAAI,gBAAgB,SAAS,EAAE,CAAC;AAC3D,QAAI,KAAM,QAAO,GAAG,IAAI,IAAI,gBAAgB,MAAM,EAAE,CAAC;AAAA,EACvD;AAEA,QAAM,WAAW,QAAQ,WAAW,IAAI,KAAK;AAC7C,QAAM,eAAe,WAAW,KAAK,YAAY,CAAC;AAClD,MAAI,WAAW,QAAQ,YAAY,MAAM,cAAc;AACrD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,2BAA2B,OAAsC;AAC/E,SAAO,+BAA+B,MAAM,UAAU;AAAA,IACpD,SAAS,MAAM;AAAA,IACf,WAAW,MAAM;AAAA,EACnB,CAAC;AACH;AAEA,SAAS,gBACP,UACA,SACA,OACA,QACA,UACA,WACQ;AACR,MAAI,QAAQ,GAAG;AACb,QAAI,QAAQ;AACV,YAAM,OAAO,YAAY,YAAY;AACrC,YAAM,OAAO,UAAU,IAAI,SAAS;AACpC,aAAO,GAAG,IAAI,IAAI,KAAK,IAAI,IAAI;AAAA,IACjC;AACA,QAAI,UAAU;AACZ,aAAO,GAAG,QAAQ,IAAI,KAAK;AAAA,IAC7B;AACA,WAAO,GAAG,QAAQ,IAAI,KAAK;AAAA,EAC7B;AACA,SAAO;AACT;AAEA,SAAS,qBACP,SACA,WACyB;AACzB,QAAM,MAAM,QAAQ,IAAI,CAAC,WAAW;AAAA,IAClC,UAAU,MAAM;AAAA,IAChB,SAAS,2BAA2B,KAAK;AAAA,IACzC,SAAS;AAAA,EACX,EAAE;AAEF,QAAM,UAAmC,CAAC;AAC1C,MAAI,cAA6B;AACjC,MAAI,iBAAgC;AACpC,MAAI,eAAe;AACnB,MAAI,gBAAgB;AACpB,MAAI,kBAAkB;AAEtB,QAAM,QAAQ,MAAM;AAClB,QAAI,eAAe,QAAQ,iBAAiB,EAAG;AAC/C,YAAQ,KAAK;AAAA,MACX,MAAM;AAAA,QACJ;AAAA,QACA,kBAAkB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,cAAc;AAAA,IAChB,CAAC;AACD,kBAAc;AACd,qBAAiB;AACjB,mBAAe;AACf,oBAAgB;AAChB,sBAAkB;AAAA,EACpB;AAEA,aAAW,EAAE,UAAU,QAAQ,KAAK,KAAK;AACvC,UAAM,SAAS,WAAW,IAAI,QAAQ;AACtC,UAAM,WAAW,aAAa,IAAI,QAAQ;AAC1C,UAAM,SAAS,WAAW,IAAI,QAAQ;AACtC,UAAM,YACJ,CAAC,UACD,gBAAgB,YAChB,kBAAkB,UAClB,oBAAoB;AAEtB,QAAI,WAAW;AACb,sBAAgB;AAAA,IAClB,OAAO;AACL,YAAM;AACN,oBAAc;AACd,uBAAiB;AACjB,qBAAe;AACf,sBAAgB;AAChB,wBAAkB;AAAA,IACpB;AAAA,EACF;AACA,QAAM;AACN,SAAO;AACT;AAEO,SAAS,0BACd,SACA,SACkE;AAClE,QAAM,YAAY,qBAAqB,SAAS,QAAQ,SAAS;AACjE,MAAI,QAAQ,cAAc,UAAU,QAAQ;AAC1C,WAAO,EAAE,SAAS,WAAW,oBAAoB,EAAE;AAAA,EACrD;AACA,QAAM,UAAU,UAAU,MAAM,CAAC,QAAQ,UAAU;AACnD,QAAM,SAAS,UAAU,MAAM,GAAG,UAAU,SAAS,QAAQ,UAAU;AACvE,QAAM,qBAAqB,OAAO,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,cAAc,CAAC;AAClF,SAAO,EAAE,SAAS,mBAAmB;AACvC;;;AChKA,IAAM,eAAe;AACrB,IAAM,iBAAiB;AAChB,IAAM,uBAAuB;AAC7B,IAAM,4BAA4B;AAElC,SAASA,iBAAgB,MAAc,WAAW,IAAY;AACnE,QAAM,UAAU,KAAK,KAAK;AAC1B,MAAI,QAAQ,UAAU,SAAU,QAAO;AACvC,SAAO,GAAG,QAAQ,MAAM,GAAG,QAAQ,CAAC;AACtC;AAEO,SAAS,iBAAiB,OAAgB,SAA0B;AACzE,QAAM,MACJ,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC7D,QACD,CAAC;AACP,QAAM,IACJ,WAAW,QAAQ,OAAO,YAAY,YAAY,CAAC,MAAM,QAAQ,OAAO,IACnE,UACD;AAEN,QAAM,SAAS,EAAE,GAAG,IAAI;AACxB,MAAI,GAAG,cAAe,QAAO,gBAAgB,EAAE;AAC/C,MAAI,GAAG,YAAa,QAAO,cAAc,EAAE;AAE3C,QAAM,WAAW,OAAO,OAAO,iBAAiB,iBAAiB,EAAE,KAAK;AACxE,QAAM,OAAO,OAAO,OAAO,eAAe,OAAO,UAAU,EAAE,EAAE,KAAK;AAEpE,MAAI,QAAQ,OAAO,GAAG,QAAQ,IAAIA,iBAAgB,IAAI,CAAC,MAAM;AAE7D,QAAM,QAAQ,OAAO;AACrB,MAAI,OAAO;AACT,UAAM,WAAW,OAAO,KAAK,EAAE,KAAK;AACpC,QAAI,SAAU,SAAQ,GAAG,KAAK,IAAI,QAAQ;AAAA,EAC5C;AAEA,SAAO;AACT;AAEO,SAAS,sBAAsB,QAA+B;AACnE,QAAM,OAAO,OAAO,KAAK;AACzB,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,YAAY,KAAK,MAAM,YAAY;AACzC,MAAI,UAAW,QAAO,SAAS,UAAU,CAAC,EAAE,KAAK,CAAC;AAElD,QAAM,aAAa,KAAK,MAAM,cAAc;AAC5C,MAAI,WAAY,QAAO,SAAS,WAAW,CAAC,CAAC;AAE7C,QAAM,QAAQ,KAAK,MAAM,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,KAAK;AAChD,MAAI,MAAM,YAAY,EAAE,WAAW,MAAM,EAAG,QAAO;AAEnD,SAAO;AACT;AAEO,SAAS,mBAAmB,SAAkB,SAAyB;AAC5E,QAAM,IACJ,WAAW,QAAQ,OAAO,YAAY,YAAY,CAAC,MAAM,QAAQ,OAAO,IACnE,UACD;AAEN,MAAI,OAAsB;AAC1B,MAAI,GAAG,eAAe,QAAQ,EAAE,WAAW,aAAa;AACtD,WAAO,SAAS,EAAE,WAAW;AAAA,EAC/B,OAAO;AACL,WAAO,sBAAsB,OAAO;AAAA,EACtC;AAEA,MAAI,MAAM;AACR,QAAI,OAAO,QAAQ,KAAK;AACxB,QAAI,KAAK,WAAW,IAAI,GAAG;AACzB,aAAO,KAAK,MAAM,KAAK,MAAM,EAAE,UAAU;AAAA,IAC3C;AACA,UAAM,QAAQ,CAAC,IAAI;AACnB,QAAI,MAAM;AACR,YAAM,EAAE,MAAMC,YAAW,WAAWC,KAAI,IAAI;AAAA,QAC1C;AAAA,QACA;AAAA,MACF;AACA,YAAM,KAAKA,OAAM,GAAGD,UAAS;AAAA,sBAAU,oBAAoB,oCAAWA,UAAS;AAAA,IACjF;AACA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAEA,QAAM,OAAO,QAAQ,KAAK;AAC1B,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,EAAE,MAAM,WAAW,WAAW,IAAI,IAAI,cAAc,MAAM,oBAAoB;AACpF,SAAO,MAAM,GAAG,SAAS;AAAA,sBAAU,oBAAoB,oCAAW;AACpE;AAEO,SAASE,4BAA2B,OAKhC;AACT,SAAO,+BAA+B,MAAM,UAAU;AAAA,IACpD,SAAS,MAAM;AAAA,IACf,WAAW,MAAM;AAAA,EACnB,CAAC;AACH;AAGO,SAAS,yBACd,SACA,kBACQ;AACR,QAAM,IACJ,WAAW,QAAQ,OAAO,YAAY,YAAY,CAAC,MAAM,QAAQ,OAAO,IACnE,UACD;AACN,QAAM,YAAY,GAAG;AACrB,MAAI,MAAM,QAAQ,SAAS,KAAK,UAAU,SAAS,GAAG;AACpD,WAAO,UACJ,IAAI,CAAC,QAAQ;AACZ,YAAM,OAAO;AACb,YAAM,OAAO,OAAO,KAAK,aAAa,MAAM;AAC5C,YAAM,UAAU,OAAO,KAAK,WAAW,EAAE,EAAE,KAAK;AAChD,aAAO,UAAU,GAAG,IAAI,KAAK,OAAO,KAAK;AAAA,IAC3C,CAAC,EACA,KAAK,IAAI;AAAA,EACd;AACA,MAAI,kBAAkB,QAAQ;AAC5B,WAAO,iBAAiB,IAAIA,2BAA0B,EAAE,KAAK,IAAI;AAAA,EACnE;AACA,SAAO;AACT;;;AChGQ,SAIE,KAJF;AAlBD,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AACF,GAA4B;AAC1B,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,QAAM,YAAY,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS;AAC5D,QAAM,QAAQ,SAAS,SAAS,QAAQ,SAAS;AACjD,QAAM,EAAE,SAAS,mBAAmB,IAAI,0BAA0B,SAAS;AAAA,IACzE;AAAA,IACA,YAAY;AAAA,EACd,CAAC;AAED,SACE,qBAAC,SAAI,WAAU,sBAAqB,eAAY,sBAC7C;AAAA,YAAQ,IAAI,CAAC,MAAM,UAClB;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QAEV;AAAA,8BAAC,UAAK,WAAU,8BAA6B,eAAW,MACrD,oBAAU,IAAI,wBAAwB,uBACzC;AAAA,UACA,oBAAC,UAAK,WAAU,4BAA4B,eAAK,MAAK;AAAA;AAAA;AAAA,MANjD,GAAG,KAAK,IAAI,KAAK,IAAI;AAAA,IAO5B,CACD;AAAA,IACA,qBAAqB,KAAK,SAAS,SAClC,qBAAC,SAAI,WAAU,2DACb;AAAA,0BAAC,UAAK,WAAU,8BAA6B,eAAW,MACrD,iCACH;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS;AAAA,UACV;AAAA;AAAA,YACG;AAAA,YAAmB;AAAA,YAAY,uBAAuB,IAAI,QAAQ;AAAA;AAAA;AAAA,MACtE;AAAA,OACF,IACE;AAAA,KACN;AAEJ;;;ACzCU,gBAAAC,MA0CF,QAAAC,aA1CE;AAXH,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,MAAI,QAAQ,OAAO;AACjB,WACE,gBAAAD,KAAC,SAAI,WAAU,sCACb,0BAAAA,KAAC,SAAI,WAAU,wBAAuB,gBAAa,SACjD,0BAAAA,KAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAM,SAAQ,GAC7D,GACF;AAAA,EAEJ;AAEA,QAAM,WAAW,oBAAoB,CAAC;AACtC,QAAM,WAAW,mBAAmB,QAAQ,SAAS,QAAQ,WAAW,EAAE;AAC1E,QAAM,aAAa,yBAAyB,QAAQ,SAAS,QAAQ;AACrE,QAAM,sBAAsB,WAAW,aAAa,SAAS,SAAS;AACtE,QAAM,kBAAkB,WAAW,aAAa,SAAS,SAAS;AAClE,QAAM,iBACJ,WAAW,UAAU,aAAa,UAAU,WAAW,SAAS;AAElE,MAAI,CAAC,uBAAuB,CAAC,mBAAmB,CAAC,gBAAgB;AAC/D,WACE,gBAAAA,KAAC,SAAI,WAAU,sCACb,0BAAAA,KAAC,SAAI,WAAU,wBAAuB,gBAAa,OACjD,0BAAAA,KAAC,SAAI,WAAU,uBAAsB,uBAAS,GAChD,GACF;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAAC,SAAI,WAAU,sCACZ;AAAA,0BACC,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,MAAM;AAAA,QACN,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,IAC3C,IACE;AAAA,IACH,kBACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,IAC3C,IACE;AAAA,IACH,iBACC,gBAAAC,MAAC,SAAI,WAAU,qDACb;AAAA,sBAAAD,KAAC,SAAI,WAAU,6BAA4B,wBAAU;AAAA,MACrD,gBAAAA,KAAC,oBAAiB,MAAM,YAAY,MAAK,QAAO;AAAA,OAClD,IACE;AAAA,KACN;AAEJ;;;ACrEO,SAAS,gBACd,SACgC;AAChC,MAAI,WAAW,QAAQ,OAAO,YAAY,YAAY,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC7E,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,cAAc,OAAyC;AACrE,MAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AACvE,WAAO;AAAA,EACT;AACA,SAAO,CAAC;AACV;AAEO,SAAS,SAAS,QAAiC,KAAqB;AAC7E,QAAM,QAAQ,OAAO,GAAG;AACxB,SAAO,SAAS,OAAO,KAAK,OAAO,KAAK,EAAE,KAAK;AACjD;AAEO,SAAS,SAAS,QAAiC,KAAiC;AACzF,QAAM,QAAQ,OAAO,GAAG;AACxB,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAChE,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,UAAM,IAAI,OAAO,KAAK;AACtB,QAAI,OAAO,SAAS,CAAC,EAAG,QAAO;AAAA,EACjC;AACA,SAAO;AACT;;;AC5BO,SAAS,yBAAyB,SAA0C;AACjF,QAAM,QAAQ,QAAQ;AACtB,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,EAAG,QAAO;AAExD,QAAM,QAAkB,CAAC;AACzB,aAAW,QAAQ,OAAO;AACxB,QAAI,QAAQ,QAAQ,OAAO,SAAS,SAAU;AAC9C,UAAM,MAAM;AACZ,UAAM,SAAS,OAAO,IAAI,UAAU,EAAE,EAAE,KAAK;AAC7C,UAAM,WAAW,OAAO,IAAI,YAAY,EAAE,EAAE,KAAK;AACjD,UAAM,SAAS,OAAO,IAAI,UAAU,EAAE,EAAE,KAAK;AAC7C,UAAM,SAAS,SAAS,IAAI,MAAM,OAAO;AACzC,UAAM,KAAK,GAAG,MAAM,GAAG,QAAQ,EAAE;AACjC,QAAI,OAAQ,OAAM,KAAK,YAAO,MAAM,EAAE;AACtC,UAAM,WAAW,IAAI;AACrB,QAAI,MAAM,QAAQ,QAAQ,KAAK,SAAS,SAAS,GAAG;AAClD,iBAAW,SAAS,UAAU;AAC5B,cAAM,KAAK,UAAO,OAAO,KAAK,CAAC,EAAE;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AACA,SAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAC/C;AAEO,SAAS,8BAA8B,OAAwC;AACpF,QAAM,YAAY,MAAM;AACxB,MAAI,CAAC,MAAM,QAAQ,SAAS,KAAK,UAAU,WAAW,GAAG;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,QAAkB,CAAC;AACzB,YAAU,QAAQ,CAAC,KAAK,QAAQ;AAC9B,QAAI,OAAO,QAAQ,OAAO,QAAQ,SAAU;AAC5C,UAAM,IAAI;AACV,UAAM,SAAS,OAAO,EAAE,UAAU,EAAE,EAAE,KAAK;AAC3C,UAAM,QAAQ,OAAO,EAAE,YAAY,EAAE,EAAE,KAAK;AAC5C,UAAM,SAAS,SAAS,IAAI,MAAM,OAAO;AACzC,UAAM,KAAK,GAAG,MAAM,CAAC,KAAK,MAAM,GAAG,KAAK,EAAE;AAC1C,UAAM,UAAU,EAAE;AAClB,QAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,iBAAW,OAAO,SAAS;AACzB,YAAI,OAAO,QAAQ,OAAO,QAAQ,UAAU;AAC1C,gBAAM,QAAQ,OAAQ,IAAgC,SAAS,EAAE,EAAE,KAAK;AACxE,cAAI,MAAO,OAAM,KAAK,WAAQ,KAAK,EAAE;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAC/C;;;ACJU,gBAAAE,YAAA;AApCV,IAAM,oBAAoB;AAC1B,IAAM,oBAAoB;AAE1B,SAAS,iBACP,OACA,SACA,SACQ;AACR,QAAM,IAAI,gBAAgB,OAAO;AACjC,MAAI,GAAG;AACL,UAAM,cAAc,yBAAyB,CAAC;AAC9C,QAAI,aAAa;AACf,UAAI,YAAY,SAAS,mBAAmB;AAC1C,cAAM,EAAE,MAAAC,OAAM,UAAU,IAAI,cAAc,aAAa,iBAAiB;AACxE,eAAO,YAAY,GAAGA,KAAI;AAAA,6BAAYA;AAAA,MACxC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,OAAO,QAAQ,KAAK;AAC1B,MAAI,KAAM,QAAO,aAAa,IAAI;AAElC,SAAO,8BAA8B,cAAc,KAAK,CAAC;AAC3D;AAEO,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,MAAI,QAAQ,OAAO;AACjB,WACE,gBAAAD,KAAC,SAAI,WAAU,yCACb,0BAAAA,KAAC,SAAI,WAAU,wBAAuB,gBAAa,SACjD,0BAAAA,KAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAM,SAAQ,GAC7D,GACF;AAAA,EAEJ;AAEA,QAAM,WAAW,iBAAiB,OAAO,QAAQ,SAAS,QAAQ,WAAW,EAAE;AAE/E,SACE,gBAAAA,KAAC,SAAI,WAAU,yCACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,EAC3C,GACF;AAEJ;;;AC1CM,gBAAAE,MAEE,QAAAC,aAFF;AAjBC,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,UAAU,QAAQ,WAAW,YAAY,QAAQ,QAAQ,KAAK;AACpE,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,EAAE,QAAQ,WAAW,eAAe,IAAI;AAAA,IAC5C,QAAQ;AAAA,IACR;AAAA,IACA,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF;AAEA,SACE,gBAAAA,MAAC,SAAI,WAAU,qCACb;AAAA,oBAAAD,KAAC,iBAAc,QAAgB;AAAA,IAC9B,aAAa,aAAa,YACzB,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM,mBAAmB,MAAM;AAAA,QACzC;AAAA;AAAA,UACG;AAAA,UAAe;AAAA;AAAA;AAAA,IACnB,IACE;AAAA,KACN;AAEJ;;;ACnBU,gBAAAC,YAAA;AAVH,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,MAAI,QAAQ,OAAO;AACjB,WACE,gBAAAA,KAAC,SAAI,WAAU,qCACb,0BAAAA,KAAC,SAAI,WAAU,wBAAuB,gBAAa,SACjD,0BAAAA,KAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAM,SAAQ,GAC7D,GACF;AAAA,EAEJ;AAEA,QAAM,OAAO;AAAA,IACX,QAAQ;AAAA,IACR;AAAA,IACA,QAAQ,WAAW;AAAA,EACrB;AAEA,SACE,gBAAAA,KAAC,SAAI,WAAU,qCACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,MAAM;AAAA,MACN,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,EAC3C,GACF;AAEJ;;;ACMU,gBAAAC,YAAA;AApCV,SAAS,kBAAkB,QAA4C;AACrE,QAAM,IAAI,gBAAgB,QAAQ,OAAO;AAEzC,MAAI,GAAG,SAAS,aAAa;AAC3B,UAAM,QAAQ,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,MAAM,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC;AACxE,UAAM,WACJ,OAAO,EAAE,cAAc,WAAW,EAAE,YAAY,MAAM;AACxD,UAAMC,WACJ,WAAW,IAAI,SAAS,QAAQ,WAAW;AAC7C,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,uBAAuB,GAAGA,QAAO;AAAA,EAAK,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,IACjE;AACA,WAAOA;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,GAAG,KAAK,GAAG;AAC3B,UAAM,QAAQ,EAAE,MAAM,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC;AAC1C,UAAMA,WAAU,SAAS,MAAM,MAAM;AACrC,WAAO,uBAAuB,GAAGA,QAAO;AAAA,EAAK,MAAM,KAAK,IAAI,CAAC,EAAE;AAAA,EACjE;AAEA,QAAM,UAAU,QAAQ,SAAS,KAAK,KAAK;AAC3C,MAAI,QAAS,QAAO,uBAAuB,OAAO;AAElD,SAAO;AACT;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,MAAI,QAAQ,OAAO;AACjB,WACE,gBAAAD,KAAC,SAAI,WAAU,qCACb,0BAAAA,KAAC,SAAI,WAAU,wBAAuB,gBAAa,SACjD,0BAAAA,KAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAM,SAAQ,GAC7D,GACF;AAAA,EAEJ;AAEA,QAAM,WAAW,kBAAkB,MAAM;AAEzC,SACE,gBAAAA,KAAC,SAAI,WAAU,qCACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,EAC3C,GACF;AAEJ;;;ACbU,gBAAAE,YAAA;AAxCV,SAAS,kBAAkB,QAA4C;AACrE,QAAM,IAAI,gBAAgB,QAAQ,OAAO;AAEzC,MAAI,GAAG,SAAS,kBAAkB;AAChC,UAAM,UAAU,MAAM,QAAQ,EAAE,OAAO,IACnC,EAAE,QAAQ,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC,IAC9B,CAAC;AACL,UAAM,aACJ,OAAO,EAAE,gBAAgB,WAAW,EAAE,cAAc,QAAQ;AAC9D,UAAMC,WACJ,aAAa,IACT,SAAS,UAAU,aACnB;AACN,QAAI,QAAQ,SAAS,GAAG;AACtB,aAAO,uBAAuB,GAAGA,QAAO;AAAA,EAAK,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,IACnE;AACA,WAAOA;AAAA,EACT;AAEA,MAAI,MAAM,QAAQ,GAAG,OAAO,GAAG;AAC7B,UAAM,UAAU,EAAE,QAAQ,IAAI,CAAC,MAAM,OAAO,CAAC,CAAC;AAC9C,UAAMA,WAAU,SAAS,QAAQ,MAAM;AACvC,WAAO,uBAAuB,GAAGA,QAAO;AAAA,EAAK,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,EACnE;AAEA,QAAM,UAAU,QAAQ,SAAS,KAAK,KAAK;AAC3C,MAAI,QAAS,QAAO,uBAAuB,OAAO;AAElD,SAAO;AACT;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,MAAI,QAAQ,OAAO;AACjB,WACE,gBAAAD,KAAC,SAAI,WAAU,qCACb,0BAAAA,KAAC,SAAI,WAAU,wBAAuB,gBAAa,SACjD,0BAAAA,KAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAM,SAAQ,GAC7D,GACF;AAAA,EAEJ;AAEA,QAAM,WAAW,kBAAkB,MAAM;AAEzC,SACE,gBAAAA,KAAC,SAAI,WAAU,qCACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,EAC3C,GACF;AAEJ;;;AC2CM,SASI,UATJ,OAAAE,MAYQ,QAAAC,aAZR;AAnGN,IAAM,iBAAiB;AACvB,IAAM,gBAAgB;AACtB,IAAM,WAAW;AACjB,IAAM,cAAc;AACpB,IAAM,WAAW;AACjB,IAAM,SAAS;AAEf,SAAS,sBAAsB,SAAkB,SAAyB;AACxE,QAAM,IAAI,gBAAgB,OAAO;AAEjC,MAAI,GAAG,SAAS,QAAQ;AACtB,UAAM,QAAQ,SAAS,GAAG,YAAY;AACtC,UAAM,MAAM,SAAS,GAAG,UAAU;AAClC,UAAM,QAAQ,SAAS,GAAG,aAAa;AACvC,QAAI,SAAS,QAAQ,OAAO,QAAQ,SAAS,MAAM;AACjD,aAAO,cAAc,KAAK,SAAI,GAAG,OAAO,KAAK;AAAA,IAC/C;AACA,UAAM,WAAW,SAAS,GAAG,WAAW;AACxC,QAAI,YAAY,MAAM;AACpB,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAAA,EACF;AAEA,MAAI,GAAG,SAAS,SAAS;AACvB,UAAM,IAAI,SAAS,GAAG,OAAO;AAC7B,UAAM,IAAI,SAAS,GAAG,QAAQ;AAC9B,QAAI,KAAK,EAAG,QAAO,eAAe,CAAC,OAAI,CAAC;AACxC,WAAO;AAAA,EACT;AAEA,MAAI,GAAG,SAAS,OAAO;AACrB,UAAM,KAAK,SAAS,GAAG,YAAY;AACnC,UAAM,KAAK,SAAS,GAAG,UAAU;AACjC,QAAI,MAAM,QAAQ,MAAM,MAAM;AAC5B,aAAO,kBAAkB,EAAE,SAAI,EAAE;AAAA,IACnC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,QAAQ,KAAK;AAC1B,MAAI,CAAC,KAAM,QAAO;AAElB,MAAI,SAAS,KAAK,IAAI,EAAG,QAAO;AAChC,QAAM,WAAW,KAAK,MAAM,WAAW;AACvC,MAAI,SAAU,QAAO,QAAQ,SAAS,CAAC,CAAC;AACxC,MAAI,SAAS,KAAK,IAAI,EAAG,QAAO,KAAK,MAAM,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,KAAK;AAClE,MAAI,OAAO,KAAK,IAAI,EAAG,QAAO,KAAK,MAAM,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,KAAK;AAEhE,QAAM,QAAQ,KAAK,MAAM,cAAc;AACvC,MAAI,OAAO;AACT,WAAO,cAAc,MAAM,CAAC,CAAC,SAAI,MAAM,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC;AAAA,EAC1D;AACA,QAAM,YAAY,KAAK,MAAM,aAAa;AAC1C,MAAI,UAAW,QAAO,QAAQ,UAAU,CAAC,CAAC;AAE1C,MAAI,KAAK,SAAS,KAAK;AACrB,UAAM,YAAY,KAAK,MAAM,IAAI,EAAE;AACnC,WAAO,kBAAkB,SAAS;AAAA,EACpC;AAEA,SAAO,KAAK,MAAM,GAAG,GAAG,KAAK;AAC/B;AAEA,SAAS,mBAAmB,SAAiC;AAC3D,QAAM,IAAI,gBAAgB,OAAO;AACjC,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,EAAE,SAAS,cAAc,EAAE,SAAS,QAAQ;AAC9C,UAAM,UAAU,SAAS,GAAG,SAAS;AACrC,QAAI,QAAS,QAAO;AAAA,EACtB;AACA,SAAO;AACT;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,WAAW,sBAAsB,SAAS,OAAO;AACvD,QAAM,UAAU,mBAAmB,OAAO;AAC1C,QAAM,IAAI,gBAAgB,OAAO;AACjC,QAAM,aAAa,GAAG,SAAS;AAG/B,QAAM,kBAAkB,MAAM;AAC5B,QAAI,CAAC,QAAS,QAAO,CAAC;AACtB,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,UAAM,YAAY,aAAa,aAAa,MAAM,SAAS;AAC3D,UAAM,OAAO,YAAY,MAAM,MAAM,GAAG,iBAAiB,EAAE,KAAK,IAAI,IAAI;AACxE,WAAO,CAAC,EAAE,MAAM,SAAS,SAAkB,CAAC;AAAA,EAC9C;AAEA,QAAM,aAAa,gBAAgB;AACnC,QAAM,UAAU,WAAW,aAAa,aAAa,QAAQ,MAAM,IAAI,EAAE,SAAS;AAElF,SACE,gBAAAA,MAAC,SAAI,WAAU,qCACb;AAAA,oBAAAD,KAAC,SAAI,WAAU,0BAA0B,oBAAS;AAAA,IACjD,UACC,aACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,IAC3C,IAEA,gBAAAC,MAAA,YACE;AAAA,sBAAAD,KAAC,iBAAc,QAAQ,YAAY;AAAA,MAClC,UACC,gBAAAC;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM,mBAAmB,MAAM;AAAA,UACzC;AAAA;AAAA,YACG,QAAQ,MAAM,IAAI,EAAE,SAAS;AAAA,YAAkB;AAAA;AAAA;AAAA,MACnD,IACE;AAAA,OACN,IAEA;AAAA,IACH,QAAQ,YACP,gBAAAD,KAAC,SAAI,WAAU,4BAA2B,4CAAK,IAC7C;AAAA,IACH,QAAQ,gBACP,gBAAAC,MAAC,SAAI,WAAU,2BAA0B;AAAA;AAAA,MAEvC,gBAAAD,KAAC,UAAM,iBAAO,eAAc;AAAA,OAC9B,IACE;AAAA,KACN;AAEJ;;;AC5HU,gBAAAE,YAAA;AAXV,IAAM,iBAAiB;AAEhB,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,MAAI,QAAQ,OAAO;AACjB,WACE,gBAAAA,KAAC,SAAI,WAAU,sCACb,0BAAAA,KAAC,SAAI,WAAU,wBAAuB,gBAAa,SACjD,0BAAAA,KAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAM,SAAQ,GAC7D,GACF;AAAA,EAEJ;AAEA,QAAM,OAAO,QAAQ,SAAS,KAAK,KAAK;AACxC,MAAI,CAAC,MAAM;AACT,WACE,gBAAAA,KAAC,SAAI,WAAU,sCACb,0BAAAA,KAAC,SAAI,WAAU,wBAAuB,gBAAa,OACjD,0BAAAA,KAAC,SAAI,WAAU,uBAAsB,oBAAM,GAC7C,GACF;AAAA,EAEJ;AAEA,QAAM,EAAE,MAAM,WAAW,WAAW,IAAI,IAAI,cAAc,MAAM,cAAc;AAC9E,QAAM,WAAW,MAAM,GAAG,SAAS;AAAA,6BAAY;AAE/C,SACE,gBAAAA,KAAC,SAAI,WAAU,sCACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,EAC3C,GACF;AAEJ;;;ACNU,gBAAAC,aAAA;AAlCV,IAAM,cAAc;AACpB,IAAMC,kBAAiB;AAEvB,SAAS,kBAAkB,QAA4C;AACrE,QAAM,IAAI,gBAAgB,QAAQ,OAAO;AACzC,MAAI,GAAG,kBAAkB,MAAM;AAC7B,UAAM,QAAQ,CAAC,YAAY,EAAE,cAAc,QAAQ;AACnD,QAAI,EAAE,eAAe,KAAM,OAAM,KAAK,MAAM,EAAE,WAAW,IAAI;AAC7D,QAAI,EAAE,WAAY,OAAM,KAAK,UAAU;AACvC,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB;AAEA,QAAM,OAAO,QAAQ,SAAS,KAAK,KAAK;AACxC,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,QAAQ,KAAK,MAAM,WAAW;AACpC,MAAI,OAAO;AACT,UAAM,OAAO,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;AAClD,WAAO,KAAK,UAAU,MAAM,OAAO,GAAG,IAAI;AAAA;AAAA,EAC5C;AAEA,QAAM,EAAE,MAAM,WAAW,WAAW,IAAI,IAAI,cAAc,MAAMA,eAAc;AAC9E,SAAO,MAAM,GAAG,SAAS;AAAA,6BAAY;AACvC;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,MAAI,QAAQ,OAAO;AACjB,WACE,gBAAAD,MAAC,SAAI,WAAU,yCACb,0BAAAA,MAAC,SAAI,WAAU,wBAAuB,gBAAa,SACjD,0BAAAA,MAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAM,SAAQ,GAC7D,GACF;AAAA,EAEJ;AAEA,QAAM,WAAW,kBAAkB,MAAM;AAEzC,SACE,gBAAAA,MAAC,SAAI,WAAU,yCACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,EAC3C,GACF;AAEJ;;;ACtBU,gBAAAE,aAAA;AA9BV,IAAMC,kBAAiB;AAEvB,SAAS,mBAAmB,QAA4C;AACtE,QAAM,IAAI,gBAAgB,QAAQ,OAAO;AACzC,MAAI,GAAG,cAAc,MAAM;AACzB,UAAM,SAAS,SAAS,GAAG,eAAe,KAAK;AAC/C,WAAO,eAAe,MAAM,MAAM,EAAE,UAAU;AAAA,EAChD;AAEA,QAAM,OAAO,QAAQ,SAAS,KAAK,KAAK;AACxC,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,QAAQ,KAAK,MAAM,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,KAAK;AAChD,MAAI,6BAA6B,KAAK,KAAK,GAAG;AAC5C,WAAO,KAAK,SAAS,MAAM,OAAO,GAAG,KAAK;AAAA;AAAA,EAC5C;AAEA,QAAM,EAAE,MAAM,WAAW,WAAW,IAAI,IAAI,cAAc,MAAMA,eAAc;AAC9E,SAAO,MAAM,GAAG,SAAS;AAAA,6BAAY;AACvC;AAEO,SAAS,kBAAkB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,MAAI,QAAQ,OAAO;AACjB,WACE,gBAAAD,MAAC,SAAI,WAAU,0CACb,0BAAAA,MAAC,SAAI,WAAU,wBAAuB,gBAAa,SACjD,0BAAAA,MAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAM,SAAQ,GAC7D,GACF;AAAA,EAEJ;AAEA,QAAM,WAAW,mBAAmB,MAAM;AAE1C,SACE,gBAAAA,MAAC,SAAI,WAAU,0CACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,EAC3C,GACF;AAEJ;;;ACcU,gBAAAE,aAAA;AAxDV,SAAS,mBACP,OACA,SACA,SACqD;AACrD,QAAM,IAAI,gBAAgB,OAAO;AACjC,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,UAAU,SAAS,KAAK,SAAS;AACvC,QAAM,OAAO;AAAA,IACX,SAAS,KAAK,CAAC,GAAG,WAAW,KAAK,SAAS,KAAK,WAAW;AAAA,EAC7D;AACA,QAAM,WAAW,SAAS,KAAK,CAAC,GAAG,MAAM;AAEzC,QAAM,WAAW,GAAG;AACpB,MAAI,aAAa,YAAY,YAAY,QAAQ,SAAS;AACxD,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,sBAAsB,OAAO,QAAQ,GAAG,OAAO;AAAA,IACvD;AAAA,EACF;AAEA,QAAM,WAAW,SAAS,KAAK,CAAC,GAAG,MAAM;AACzC,MAAI,UAAU;AACZ,WAAO,EAAE,MAAM,QAAQ,MAAM,SAAS;AAAA,EACxC;AAEA,QAAM,WACJ,OAAO,GAAG,cAAc,WACpB,EAAE,YACF,WAAW,OAAO;AAExB,MAAI,aAAa,KAAK,CAAC,QAAQ,KAAK,GAAG;AACrC,UAAM,UAAU,QAAQ,KAAK;AAC7B,WAAO,EAAE,MAAM,QAAQ,MAAM,WAAW,eAAe;AAAA,EACzD;AAEA,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,UAAU,MAAM,MAAM,GAAG,mBAAmB,EAAE,KAAK,IAAI;AAC7D,QAAM,YAAY,WAAW;AAC7B,QAAM,SAAS,SAAS,QAAQ,aAAa,QAAQ,MAAM;AAC3D,QAAM,OACJ,YAAY,IAAI,GAAG,MAAM;AAAA,EAAK,OAAO;AAAA,UAAQ,SAAS,WAAW,GAAG,MAAM;AAAA,EAAK,OAAO;AAExF,SAAO,EAAE,MAAM,WAAW,MAAM,KAAK;AACvC;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,MAAI,QAAQ,OAAO;AACjB,WACE,gBAAAA,MAAC,SAAI,WAAU,sCACb,0BAAAA,MAAC,SAAI,WAAU,wBAAuB,gBAAa,SACjD,0BAAAA,MAAC,SAAI,WAAU,uBAAuB,iBAAO,MAAM,SAAQ,GAC7D,GACF;AAAA,EAEJ;AAEA,QAAM,OAAO;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ,WAAW;AAAA,EACrB;AAEA,MAAI,KAAK,SAAS,QAAQ;AACxB,WACE,gBAAAA,MAAC,SAAI,WAAU,sCACb,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,KAAK;AAAA,QACX,MAAM;AAAA,QACN,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,IAC3C,GACF;AAAA,EAEJ;AAEA,SACE,gBAAAA,MAAC,SAAI,WAAU,sCACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,KAAK;AAAA,MACX,MAAM;AAAA,MACN,UAAU,sBAAsB;AAAA,MAChC,UAAU,MAAM,mBAAmB,MAAM;AAAA;AAAA,EAC3C,GACF;AAEJ;;;AC7EO,IAAM,sBAAN,MAA0B;AAAA,EACd,MAAM,oBAAI,IAA+B;AAAA,EAE1D,SAAS,UAAkB,MAA+B;AACxD,SAAK,IAAI,IAAI,UAAU,IAAI;AAC3B,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,UAAiD;AACvD,WAAO,KAAK,IAAI,IAAI,QAAQ;AAAA,EAC9B;AAAA,EAEA,OAAO,UAA+B;AACpC,WAAO,0BAA0B;AAAA,EACnC;AACF;AAGO,SAAS,4BAAiD;AAC/D,SAAO,IAAI,oBAAoB,EAC5B,SAAS,MAAM,YAAY,EAC3B,SAAS,MAAM,YAAY,EAC3B,SAAS,MAAM,YAAY,EAC3B,SAAS,MAAM,YAAY,EAC3B,SAAS,OAAO,aAAa,EAC7B,SAAS,MAAM,YAAY,EAC3B,SAAS,OAAO,aAAa,EAC7B,SAAS,OAAO,aAAa,EAC7B,SAAS,iBAAiB,uBAAuB,EACjD,SAAS,WAAW,iBAAiB,EACrC,SAAS,UAAU,gBAAgB;AACxC;","names":["truncatePreview","truncated","was","formatSubagentProgressLine","jsx","jsxs","jsx","text","jsx","jsxs","jsx","jsx","summary","jsx","summary","jsx","jsxs","jsx","jsx","MAX_BODY_LINES","jsx","MAX_BODY_LINES","jsx"]}