langchain_agentx_stream_ui 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-DP7V33X7.js → chunk-6Z4ZF36Z.js} +1 -1
- package/dist/chunk-6Z4ZF36Z.js.map +1 -0
- package/dist/{chunk-QL3DIGFI.js → chunk-FL2G7SV3.js} +2 -2
- package/dist/chunk-FL2G7SV3.js.map +1 -0
- package/dist/{chunk-4RIOBLGB.js → chunk-GBY5DJ7L.js} +1 -1
- package/dist/chunk-GBY5DJ7L.js.map +1 -0
- package/dist/{chunk-AY7QLXFB.js → chunk-JAOJAGMM.js} +3 -3
- package/dist/chunk-JAOJAGMM.js.map +1 -0
- package/dist/{chunk-7X7IF2A4.js → chunk-ME5T6YSV.js} +5 -5
- package/dist/chunk-ME5T6YSV.js.map +1 -0
- package/dist/{chunk-MRGHYRSV.js → chunk-TCKOXX7O.js} +4 -4
- package/dist/chunk-TCKOXX7O.js.map +1 -0
- package/dist/index.d.ts +113 -43
- package/dist/index.js +409 -240
- package/dist/index.js.map +1 -1
- package/dist/{multi-session--0z_-ut1.d.ts → multi-session-B7kIVfyG.d.ts} +16 -0
- package/dist/multi-session.d.ts +1 -1
- package/dist/multi-session.js +6 -6
- package/dist/tools-presentation.js +2 -2
- package/dist/tools.js +4 -4
- package/dist/virtual.js +3 -3
- package/package.json +4 -3
- package/dist/chunk-4RIOBLGB.js.map +0 -1
- package/dist/chunk-7X7IF2A4.js.map +0 -1
- package/dist/chunk-AY7QLXFB.js.map +0 -1
- package/dist/chunk-DP7V33X7.js.map +0 -1
- package/dist/chunk-MRGHYRSV.js.map +0 -1
- package/dist/chunk-QL3DIGFI.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/view/tools/presentation/textHelpers.ts"],"sourcesContent":["/**\r\n * textHelpers.ts — 标题预览截断\r\n *\r\n * 对齐参考:CLI widgets/tools/helpers.py truncate_preview\r\n */\r\nexport function truncatePreview(text: string, maxChars = 120): string {\r\n const line = (text || '').trim().split('\\n', 1)[0] ?? '';\r\n if (line.length > maxChars) {\r\n return `${line.slice(0, maxChars - 1)}…`;\r\n }\r\n return line;\r\n}\r\n"],"mappings":";AAKO,SAAS,gBAAgB,MAAc,WAAW,KAAa;AACpE,QAAM,QAAQ,QAAQ,IAAI,KAAK,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK;AACtD,MAAI,KAAK,SAAS,UAAU;AAC1B,WAAO,GAAG,KAAK,MAAM,GAAG,WAAW,CAAC,CAAC;AAAA,EACvC;AACA,SAAO;AACT;","names":[]}
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
resolveEditDiffText,
|
|
14
14
|
truncateCommand,
|
|
15
15
|
truncateLines
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-GBY5DJ7L.js";
|
|
17
17
|
|
|
18
18
|
// src/view/tools/toolNames.ts
|
|
19
19
|
var Read = "Read";
|
|
@@ -1409,4 +1409,4 @@ export {
|
|
|
1409
1409
|
ToolDisplayRegistry,
|
|
1410
1410
|
createDefaultToolRegistry
|
|
1411
1411
|
};
|
|
1412
|
-
//# sourceMappingURL=chunk-
|
|
1412
|
+
//# sourceMappingURL=chunk-FL2G7SV3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/view/tools/toolNames.ts","../src/core/projection/exploreSummary.ts","../src/view/tools/displayRecord.ts","../src/view/tools/edit/formatEditTitle.ts","../src/view/tools/write/formatWriteTitle.ts","../src/view/tools/presentation/planPaths.ts","../src/view/tools/presentation/agentProgressRenderer.ts","../src/view/tools/presentation/agentHelpers.ts","../src/view/tools/agent/AgentProgressLines.tsx","../src/view/tools/presentation/subagentTranscriptRenderer.ts","../src/view/tools/agent/SubagentTranscriptBlock.tsx","../src/view/tools/agent/AgentToolBody.tsx","../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":["/**\r\n * toolNames.ts — CC PascalCase 工具名 SSOT(对齐 SDK registry_names.py)\r\n *\r\n * 职责:Stream UI widget / projection / reducer 消费的工具名字面量唯一来源。\r\n * 链路位置:registry.ts、classify.ts、memoryPaths.ts、reducer.ts。\r\n * 当前裁剪范围:无 legacy alias、无 *Tool 后缀变体、无 REMOVED 双轨表。\r\n */\r\n\r\nexport const Read = 'Read';\r\nexport const Write = 'Write';\r\nexport const Edit = 'Edit';\r\nexport const Glob = 'Glob';\r\nexport const Grep = 'Grep';\r\nexport const Bash = 'Bash';\r\nexport const Skill = 'Skill';\r\nexport const Agent = 'Agent';\r\nexport const AskUserQuestion = 'AskUserQuestion';\r\nexport const WebSearch = 'WebSearch';\r\nexport const WebFetch = 'WebFetch';\r\n\r\nexport const TaskCreate = 'TaskCreate';\r\nexport const TaskUpdate = 'TaskUpdate';\r\nexport const TaskList = 'TaskList';\r\nexport const TaskGet = 'TaskGet';\r\nexport const TaskOutput = 'TaskOutput';\r\nexport const TaskStop = 'TaskStop';\r\n\r\n/** SSE 抑制 + Timeline hidden:SDK Task* 内部工具(仅 CC 注册名) */\r\nexport const SILENT_TASK_TOOL_NAMES: readonly string[] = [\r\n TaskCreate,\r\n TaskGet,\r\n TaskList,\r\n TaskUpdate,\r\n];\r\n\r\n/** reducer 不渲染的内部工具(= SILENT_TASK + TaskOutput/TaskStop) */\r\nexport const INTERNAL_TOOL_NAMES: ReadonlySet<string> = new Set([\r\n ...SILENT_TASK_TOOL_NAMES,\r\n TaskOutput,\r\n TaskStop,\r\n]);\r\n\r\n/** CC 核心文件/Shell 工具名(门禁:src 中禁止 legacy 小写 alias) */\r\nexport const CC_CORE_TOOL_NAMES: readonly string[] = [\r\n Read,\r\n Write,\r\n Edit,\r\n Glob,\r\n Grep,\r\n Bash,\r\n Skill,\r\n Agent,\r\n AskUserQuestion,\r\n WebSearch,\r\n WebFetch,\r\n];\r\n\r\n/** 单测负向样本:legacy 名不得出现在 src(由 TN-006 guard 扫描) */\r\nexport const LEGACY_TOOL_NAME_SAMPLES: readonly string[] = [\r\n 'read',\r\n 'read_file',\r\n 'write',\r\n 'edit',\r\n 'glob',\r\n 'grep',\r\n 'bash',\r\n 'skill',\r\n 'agent',\r\n 'Task',\r\n 'search',\r\n 'list',\r\n 'batch_edit',\r\n];\r\n","/**\n * exploreSummary.ts — collapsed_explore 摘要文案(对齐 CC / CLI)\n *\n * 职责:\n * 生成与 CC CollapsedReadSearchContent / getSearchReadSummaryText 一致的 plain 摘要。\n *\n * 链路位置:\n * ExploreCollapseAccumulator → payload.summaryText。\n *\n * 当前裁剪范围:\n * 仅 plain text;Rich/bold 渲染在 CollapsedExploreNode(Phase 3)。\n */\n\nexport interface ExploreSummaryCounts {\n searchCount: number;\n readCount: number;\n listCount: number;\n bashCount: number;\n memorySearchCount: number;\n memoryReadCount: number;\n memoryWriteCount: number;\n relevantRecallCount: number;\n gitOpBashCount: number;\n mcpCallCount: number;\n}\n\ninterface SummaryPart {\n verb: string;\n count: number | null;\n suffix: string;\n}\n\nfunction memoryReadTotal(counts: ExploreSummaryCounts): number {\n if (counts.memoryReadCount === 0 && counts.relevantRecallCount > 0) {\n return counts.relevantRecallCount;\n }\n return counts.memoryReadCount;\n}\n\nfunction tenseVerb(options: {\n active: boolean;\n isFirst: boolean;\n presentCap: string;\n presentLower: string;\n pastCap: string;\n pastLower: string;\n}): string {\n if (options.active) {\n return options.isFirst ? options.presentCap : options.presentLower;\n }\n return options.isFirst ? options.pastCap : options.pastLower;\n}\n\nfunction exploreSummaryParts(\n counts: ExploreSummaryCounts,\n active: boolean,\n continuingSentence = false,\n): SummaryPart[] {\n const parts: SummaryPart[] = [];\n let isFirst = !continuingSentence;\n\n // Memory operations first (对齐 CC/CLI)\n const memRead = memoryReadTotal(counts);\n if (memRead > 0) {\n parts.push({\n verb: tenseVerb({\n active,\n isFirst,\n presentCap: 'Recalling',\n presentLower: 'recalling',\n pastCap: 'Recalled',\n pastLower: 'recalled',\n }),\n count: memRead,\n suffix: memRead === 1 ? 'memory' : 'memories',\n });\n isFirst = false;\n }\n\n if (counts.memorySearchCount > 0) {\n parts.push({\n verb: tenseVerb({\n active,\n isFirst,\n presentCap: 'Searching',\n presentLower: 'searching',\n pastCap: 'Searched',\n pastLower: 'searched',\n }),\n count: null,\n suffix: 'memories',\n });\n isFirst = false;\n }\n\n if (counts.memoryWriteCount > 0) {\n parts.push({\n verb: tenseVerb({\n active,\n isFirst,\n presentCap: 'Writing',\n presentLower: 'writing',\n pastCap: 'Wrote',\n pastLower: 'wrote',\n }),\n count: counts.memoryWriteCount,\n suffix: counts.memoryWriteCount === 1 ? 'memory' : 'memories',\n });\n isFirst = false;\n }\n\n // Non-memory operations\n if (counts.searchCount > 0) {\n parts.push({\n verb: tenseVerb({\n active,\n isFirst,\n presentCap: 'Searching for',\n presentLower: 'searching for',\n pastCap: 'Searched for',\n pastLower: 'searched for',\n }),\n count: counts.searchCount,\n suffix: counts.searchCount === 1 ? 'pattern' : 'patterns',\n });\n isFirst = false;\n }\n\n if (counts.readCount > 0) {\n parts.push({\n verb: tenseVerb({\n active,\n isFirst,\n presentCap: 'Reading',\n presentLower: 'reading',\n pastCap: 'Read',\n pastLower: 'read',\n }),\n count: counts.readCount,\n suffix: counts.readCount === 1 ? 'file' : 'files',\n });\n isFirst = false;\n }\n\n if (counts.listCount > 0) {\n parts.push({\n verb: tenseVerb({\n active,\n isFirst,\n presentCap: 'Listing',\n presentLower: 'listing',\n pastCap: 'Listed',\n pastLower: 'listed',\n }),\n count: counts.listCount,\n suffix: counts.listCount === 1 ? 'directory' : 'directories',\n });\n isFirst = false;\n }\n\n if (counts.bashCount > 0) {\n parts.push({\n verb: tenseVerb({\n active,\n isFirst,\n presentCap: 'Running',\n presentLower: 'running',\n pastCap: 'Ran',\n pastLower: 'ran',\n }),\n count: counts.bashCount,\n suffix: counts.bashCount === 1 ? 'bash command' : 'bash commands',\n });\n isFirst = false;\n }\n\n if (counts.gitOpBashCount > 0) {\n parts.push({\n verb: tenseVerb({\n active,\n isFirst,\n presentCap: 'Running',\n presentLower: 'running',\n pastCap: 'Ran',\n pastLower: 'ran',\n }),\n count: counts.gitOpBashCount,\n suffix: counts.gitOpBashCount === 1 ? 'git command' : 'git commands',\n });\n isFirst = false;\n }\n\n if (counts.mcpCallCount > 0) {\n parts.push({\n verb: tenseVerb({\n active,\n isFirst,\n presentCap: 'Querying',\n presentLower: 'querying',\n pastCap: 'Queried',\n pastLower: 'queried',\n }),\n count: counts.mcpCallCount,\n suffix: counts.mcpCallCount === 1 ? 'MCP tool' : 'MCP tools',\n });\n isFirst = false;\n }\n\n return parts;\n}\n\nfunction partPlainText(part: SummaryPart): string {\n if (part.count !== null) {\n return `${part.verb} ${part.count} ${part.suffix}`.trim();\n }\n return `${part.verb} ${part.suffix}`.trim();\n}\n\nexport function formatExploreSummaryText(\n counts: ExploreSummaryCounts,\n options: {\n active: boolean;\n prefix?: string;\n joiner?: string;\n /** Thought 前缀已占用句首时,explore 动词用小写续写 */\n continuingSentence?: boolean;\n } = { active: false },\n): string | null {\n const parts = exploreSummaryParts(\n counts,\n options.active,\n options.continuingSentence ?? false,\n );\n if (parts.length === 0) return null;\n const joiner = options.joiner ?? ', ';\n let text = parts.map(partPlainText).join(joiner);\n if (options.active) {\n text = `${text}…`;\n }\n if (options.prefix) {\n text = options.prefix + text;\n }\n return text;\n}\n\n/** CC 合并行前缀:Thought for 8s, */\nexport function formatThoughtDurationPrefix(seconds: number): string {\n const rounded = Math.max(1, Math.round(seconds));\n return `Thought for ${rounded}s, `;\n}\n\nexport function exploreCountsHasActivity(counts: ExploreSummaryCounts): boolean {\n return (\n counts.searchCount > 0 ||\n counts.readCount > 0 ||\n counts.listCount > 0 ||\n counts.bashCount > 0 ||\n counts.memorySearchCount > 0 ||\n counts.memoryReadCount > 0 ||\n counts.memoryWriteCount > 0 ||\n counts.relevantRecallCount > 0 ||\n counts.gitOpBashCount > 0 ||\n counts.mcpCallCount > 0\n );\n}\n","/**\r\n * displayRecord.ts — 从 input / display 安全取字段\r\n */\r\n\r\nexport function asDisplayRecord(\r\n display: unknown,\r\n): Record<string, unknown> | null {\r\n if (display != null && typeof display === 'object' && !Array.isArray(display)) {\r\n return display as Record<string, unknown>;\r\n }\r\n return null;\r\n}\r\n\r\nexport function asInputRecord(input: unknown): Record<string, unknown> {\r\n if (input != null && typeof input === 'object' && !Array.isArray(input)) {\r\n return input as Record<string, unknown>;\r\n }\r\n return {};\r\n}\r\n\r\nexport function strField(record: Record<string, unknown>, key: string): string {\r\n const value = record[key];\r\n return value == null ? '' : String(value).trim();\r\n}\r\n\r\nexport function numField(record: Record<string, unknown>, key: string): number | undefined {\r\n const value = record[key];\r\n if (typeof value === 'number' && Number.isFinite(value)) return value;\r\n if (typeof value === 'string' && value.trim() !== '') {\r\n const n = Number(value);\r\n if (Number.isFinite(n)) return n;\r\n }\r\n return undefined;\r\n}\r\n","/**\r\n * formatEditTitle.ts — edit 工具标题(Update / Create)\r\n *\r\n * 对齐参考:CLI widgets/tools/edit/widget.py format_title\r\n */\r\nimport { asInputRecord, strField } from '../displayRecord';\r\nimport { displayPath } from '../presentation/paths';\r\n\r\nexport function editAction(input: unknown): 'Update' | 'Create' {\r\n const inp = asInputRecord(input);\r\n if (Array.isArray(inp.edits) && inp.edits.length > 0) return 'Update';\r\n if ('old_string' in inp && inp.old_string === '') return 'Create';\r\n return 'Update';\r\n}\r\n\r\nexport function formatEditTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const inp = asInputRecord(input);\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n const path = displayPath(\r\n strField(d ?? {}, 'file_path') || strField(inp, 'file_path'),\r\n );\r\n const action = editAction(inp);\r\n if (!path) return action;\r\n return `${action}(${path})`;\r\n}\r\n","/**\r\n * formatWriteTitle.ts — write 工具标题\r\n *\r\n * 对齐参考:CLI widgets/tools/write/widget.py format_title\r\n */\r\nimport { asDisplayRecord, asInputRecord, strField } from '../displayRecord';\r\nimport { displayPath } from '../presentation/paths';\r\n\r\nexport function formatWriteTitle(\r\n input: unknown,\r\n display: unknown,\r\n _summary?: string | null,\r\n): string {\r\n const inp = asInputRecord(input);\r\n const d = asDisplayRecord(display);\r\n const path = displayPath(\r\n strField(d ?? {}, 'file_path') || strField(inp, 'file_path'),\r\n );\r\n if (!path) return 'Write';\r\n return `Write(${path})`;\r\n}\r\n","/**\n * planPaths.ts — CC plan 文件路径判定(对齐 FileWriteTool/FileEditTool userFacingName)\n *\n * 链路:formatSubagentToolProgressLine Write/Edit → Updated plan\n */\nimport { displayPath } from './paths';\n\nconst PLAN_PATH_MARKERS = ['/.claude/plans/', '.claude/plans/'] as const;\n\nexport function isPlanFilePath(filePath: string): boolean {\n const normalized = displayPath(filePath.trim());\n if (!normalized) return false;\n return PLAN_PATH_MARKERS.some((marker) => normalized.includes(marker));\n}\n","/**\n * agentProgressRenderer.ts — Agent 子工具 progress 行(对齐 CLI progress_renderer.py)\n */\nimport {\n formatExploreSummaryText,\n type ExploreSummaryCounts,\n} from '../../../core/projection/exploreSummary';\nimport type { SubagentProgressEntry } from '../../../types/nodes';\nimport { formatEditTitle } from '../edit/formatEditTitle';\nimport { formatWriteTitle } from '../write/formatWriteTitle';\nimport { isPlanFilePath } from './planPaths';\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']);\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 if (name === 'Write') {\n const path = String(inp.file_path ?? inp.path ?? '').trim();\n if (path && isPlanFilePath(path)) return 'Updated plan';\n const title = formatWriteTitle(inp, null);\n if (title !== 'Write') return title;\n }\n if (name === 'Edit') {\n const path = String(inp.file_path ?? inp.path ?? '').trim();\n if (path && isPlanFilePath(path)) return 'Updated plan';\n const title = formatEditTitle(inp, null);\n if (title !== 'Edit') return title;\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 isSubagentProgressEntry(value: unknown): value is SubagentProgressEntry {\n if (value == null || typeof value !== 'object' || Array.isArray(value)) return false;\n const row = value as SubagentProgressEntry;\n return typeof row.toolName === 'string' && row.toolName.length > 0;\n}\n\nfunction readProgressField<T>(\n row: Record<string, unknown>,\n camel: string,\n snake: string,\n): T | undefined {\n const camelValue = row[camel];\n if (camelValue !== undefined && camelValue !== null) return camelValue as T;\n const snakeValue = row[snake];\n if (snakeValue !== undefined && snakeValue !== null) return snakeValue as T;\n return undefined;\n}\n\n/** grouped_tool_use payload 内 subagent_progress → SubagentProgressEntry[] */\nexport function coerceSubagentProgressEntries(raw: unknown): SubagentProgressEntry[] {\n if (!Array.isArray(raw)) return [];\n const entries: SubagentProgressEntry[] = [];\n for (const item of raw) {\n if (item == null || typeof item !== 'object' || Array.isArray(item)) continue;\n const row = item as Record<string, unknown>;\n const toolName = readProgressField<string>(row, 'toolName', 'tool_name');\n const agentId = readProgressField<string>(row, 'agentId', 'agent_id');\n if (!toolName || !agentId) continue;\n const stepRaw = readProgressField<number>(row, 'step', 'step') ?? 0;\n const statusRaw = readProgressField<string>(row, 'status', 'status') ?? 'completed';\n const status: SubagentProgressEntry['status'] =\n statusRaw === 'running'\n ? 'running'\n : statusRaw === 'error' || statusRaw === 'failed'\n ? 'error'\n : 'completed';\n entries.push({\n agentId,\n subagentType: readProgressField<string>(row, 'subagentType', 'subagent_type'),\n step: stepRaw,\n toolName,\n summary: readProgressField<string>(row, 'summary', 'summary') ?? toolName,\n status,\n toolInput: readProgressField<unknown>(row, 'toolInput', 'tool_input'),\n childToolCallId: readProgressField<string>(row, 'childToolCallId', 'child_tool_call_id'),\n });\n }\n return entries.sort((a, b) => a.step - b.step || a.toolName.localeCompare(b.toolName));\n}\n\n/** GroupedToolCallRow pending 态:Write(path) → Write: path(对齐 CC extractLastToolInfo 冒号格式)。 */\nexport function formatGroupedProgressStatus(entry: SubagentProgressEntry): string {\n const paren = formatSubagentProgressLine(entry);\n const m = /^(Write|Update|Create)\\((.+)\\)$/.exec(paren);\n if (m) return `${m[1]}: ${m[2]}`;\n return paren;\n}\n\n/** 对齐 CLI extractLastToolInfoFromProgressEntries:分组子行 pending 态展示。 */\nexport function extractLastToolInfoFromProgress(\n progress: unknown,\n): string | null {\n if (!Array.isArray(progress) || progress.length === 0) return null;\n for (let index = progress.length - 1; index >= 0; index -= 1) {\n const entry = progress[index];\n if (!isSubagentProgressEntry(entry)) continue;\n const line = formatGroupedProgressStatus(entry);\n if (line) return line;\n }\n return null;\n}\n\nconst FILESYSTEM_PROGRESS_TOOLS = new Set(['Write', 'Edit']);\n\n/** P2:done 态保留最后一行 Write/Edit/Plan filesystem status(冒号格式)。 */\nexport function extractLastFilesystemStatusFromProgress(\n progress: unknown,\n): string | null {\n if (!Array.isArray(progress) || progress.length === 0) return null;\n for (let index = progress.length - 1; index >= 0; index -= 1) {\n const entry = progress[index];\n if (!isSubagentProgressEntry(entry)) continue;\n if (!FILESYSTEM_PROGRESS_TOOLS.has(entry.toolName)) continue;\n const line = formatGroupedProgressStatus(entry);\n if (line === 'Write' || line === 'Edit' || line === 'Update' || line === 'Create') {\n continue;\n }\n return line;\n }\n return null;\n}\n\nfunction emptyExploreCounts(): ExploreSummaryCounts {\n return {\n searchCount: 0,\n readCount: 0,\n listCount: 0,\n bashCount: 0,\n memorySearchCount: 0,\n memoryReadCount: 0,\n memoryWriteCount: 0,\n relevantRecallCount: 0,\n gitOpBashCount: 0,\n mcpCallCount: 0,\n };\n}\n\n/** TodoWrite / Task* 不进子 Agent progress(对齐 CC renderToolUseMessage → null)。 */\nexport function isSilentTaskTool(toolName: string): boolean {\n const name = toolName.trim();\n if (!name) return false;\n if (name === 'TodoWrite') return true;\n return name.startsWith('Task');\n}\n\nfunction isExploreTool(toolName: string): boolean {\n return READ_TOOLS.has(toolName) || SEARCH_TOOLS.has(toolName);\n}\n\nfunction incrementExploreCount(counts: ExploreSummaryCounts, toolName: string): void {\n if (READ_TOOLS.has(toolName)) {\n counts.readCount += 1;\n return;\n }\n if (SEARCH_TOOLS.has(toolName)) {\n counts.searchCount += 1;\n }\n}\n\n/** P1:仅 searchCount + readCount,复用 exploreSummary 时态 SSOT。 */\nexport function buildExploreSummaryLine(\n counts: Pick<ExploreSummaryCounts, 'searchCount' | 'readCount'>,\n options: { active: boolean },\n): string {\n return (\n formatExploreSummaryText(\n { ...emptyExploreCounts(), ...counts },\n { active: options.active },\n ) ?? ''\n );\n}\n\n/** D34 §4.3:尾部连续 explore 块跨 Read/Glob/Grep 合并;Write/Edit/Bash 打断。 */\nfunction processProgressEntries(\n entries: SubagentProgressEntry[],\n isRunning: boolean,\n): ProcessedProgressLine[] {\n const lines: ProcessedProgressLine[] = [];\n let i = 0;\n\n while (i < entries.length) {\n const entry = entries[i]!;\n if (isSilentTaskTool(entry.toolName)) {\n i += 1;\n continue;\n }\n\n if (isExploreTool(entry.toolName)) {\n let j = i;\n const counts = emptyExploreCounts();\n while (j < entries.length && isExploreTool(entries[j]!.toolName)) {\n incrementExploreCount(counts, entries[j]!.toolName);\n j += 1;\n }\n const blockLen = j - i;\n if (blockLen >= 2) {\n lines.push({\n text: buildExploreSummaryLine(counts, { active: isRunning }),\n toolUseCount: blockLen,\n });\n } else {\n lines.push({\n text: formatSubagentProgressLine(entries[i]!),\n toolUseCount: 1,\n });\n }\n i = j;\n continue;\n }\n\n lines.push({\n text: formatSubagentProgressLine(entry),\n toolUseCount: 1,\n });\n i += 1;\n }\n\n return lines;\n}\n\nexport function processAgentProgressLines(\n entries: SubagentProgressEntry[],\n options: { isRunning: boolean; maxVisible: number },\n): { visible: ProcessedProgressLine[]; hiddenToolUseCount: number } {\n const processed = processProgressEntries(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","/**\r\n * agentHelpers.ts — Agent 标题与完成摘要\r\n *\r\n * 对齐参考:CLI helpers.format_agent_title · parse_agent_done_summary\r\n */\r\nimport { truncateLines } from './searchHelpers';\r\nimport { formatSubagentToolProgressLine } from './agentProgressRenderer';\r\n\r\nconst DONE_LINE_RE = /Done \\((.+?)\\)/i;\r\nconst AGENT_STEPS_RE = /(\\d+)\\s+tool uses?/i;\r\nexport const AGENT_MAX_BODY_LINES = 25;\r\nexport const AGENT_PROGRESS_TAIL_LINES = 3;\r\n\r\nexport function truncatePreview(text: string, maxChars = 80): string {\r\n const trimmed = text.trim();\r\n if (trimmed.length <= maxChars) return trimmed;\r\n return `${trimmed.slice(0, maxChars)}…`;\r\n}\r\n\r\nexport function formatAgentTitle(input: unknown, display: unknown): string {\r\n const inp =\r\n input != null && typeof input === 'object' && !Array.isArray(input)\r\n ? (input as Record<string, unknown>)\r\n : {};\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n\r\n const merged = { ...inp };\r\n if (d?.subagent_type) merged.subagent_type = d.subagent_type;\r\n if (d?.description) merged.description = d.description;\r\n\r\n const subagent = String(merged.subagent_type ?? 'general-purpose').trim();\r\n const desc = String(merged.description ?? merged.prompt ?? '').trim();\r\n\r\n let title = desc ? `${subagent}(${truncatePreview(desc)})` : subagent;\r\n\r\n const model = merged.model;\r\n if (model) {\r\n const modelStr = String(model).trim();\r\n if (modelStr) title = `${title} ${modelStr}`;\r\n }\r\n\r\n return title;\r\n}\r\n\r\nexport function parseAgentDoneSummary(output: string): string | null {\r\n const text = output.trim();\r\n if (!text) return null;\r\n\r\n const doneMatch = text.match(DONE_LINE_RE);\r\n if (doneMatch) return `Done (${doneMatch[1].trim()})`;\r\n\r\n const stepsMatch = text.match(AGENT_STEPS_RE);\r\n if (stepsMatch) return `Done (${stepsMatch[1]} tool uses)`;\r\n\r\n const first = text.split('\\n', 1)[0]?.trim() ?? '';\r\n if (first.toLowerCase().startsWith('done')) return first;\r\n\r\n return null;\r\n}\r\n\r\nexport function buildAgentBodyText(display: unknown, summary: string): string {\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n\r\n let done: string | null = null;\r\n if (d?.total_steps != null && d.status === 'completed') {\r\n done = `Done (${d.total_steps} tool uses)`;\r\n } else {\r\n done = parseAgentDoneSummary(summary);\r\n }\r\n\r\n if (done) {\r\n let rest = summary.trim();\r\n if (rest.startsWith(done)) {\r\n rest = rest.slice(done.length).trimStart();\r\n }\r\n const parts = [done];\r\n if (rest) {\r\n const { text: truncated, truncated: was } = truncateLines(\r\n rest,\r\n AGENT_MAX_BODY_LINES,\r\n );\r\n parts.push(was ? `${truncated}\\n… 超过 ${AGENT_MAX_BODY_LINES} 行,已截断` : truncated);\r\n }\r\n return parts.join('\\n');\r\n }\r\n\r\n const text = summary.trim();\r\n if (!text) return '(done)';\r\n\r\n const { text: truncated, truncated: was } = truncateLines(text, AGENT_MAX_BODY_LINES);\r\n return was ? `${truncated}\\n… 超过 ${AGENT_MAX_BODY_LINES} 行,已截断` : truncated;\r\n}\r\n\r\nexport function formatSubagentProgressLine(entry: {\r\n toolName: string;\r\n summary: string;\r\n status: string;\r\n toolInput?: unknown;\r\n}): string {\r\n return formatSubagentToolProgressLine(entry.toolName, {\r\n summary: entry.summary,\r\n toolInput: entry.toolInput,\r\n });\r\n}\r\n\r\n/** 完成后展开 transcript:优先 display.tool_calls,否则用 reducer 积累的 progress。 */\r\nexport function buildAgentTranscriptText(\r\n display: unknown,\r\n subagentProgress?: { toolName: string; summary: string; status: string }[],\r\n): string {\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n const toolCalls = d?.tool_calls;\r\n if (Array.isArray(toolCalls) && toolCalls.length > 0) {\r\n return toolCalls\r\n .map((row) => {\r\n const item = row as Record<string, unknown>;\r\n const name = String(item.tool_name ?? 'tool');\r\n const summary = String(item.summary ?? '').trim();\r\n return summary ? `${name}: ${summary}` : name;\r\n })\r\n .join('\\n');\r\n }\r\n if (subagentProgress?.length) {\r\n return subagentProgress.map(formatSubagentProgressLine).join('\\n');\r\n }\r\n return '';\r\n}\r\n","/**\r\n * AgentProgressLines.tsx — Agent 子工具 progress 折叠行\r\n *\r\n * 对齐 CLI AgentProgressLineRenderer · CC AgentTool/UI.tsx renderToolUseProgressMessage\r\n */\r\nimport {\r\n AGENT_PROGRESS_GUTTER,\r\n processAgentProgressLines,\r\n} from '../presentation/agentProgressRenderer';\r\nimport { AGENT_PROGRESS_TAIL_LINES } from '../presentation/agentHelpers';\r\nimport type { SubagentProgressEntry } from '../../../types/nodes';\r\nimport type { ToolBodyMode } from '../types';\r\n\r\nexport interface AgentProgressLinesProps {\r\n entries: SubagentProgressEntry[];\r\n mode: ToolBodyMode;\r\n maxVisible?: number;\r\n onExpand?: () => void;\r\n}\r\n\r\nexport function AgentProgressLines({\r\n entries,\r\n mode,\r\n maxVisible = AGENT_PROGRESS_TAIL_LINES,\r\n onExpand,\r\n}: AgentProgressLinesProps) {\r\n if (entries.length === 0) return null;\r\n\r\n const isRunning = entries.some((e) => e.status === 'running');\r\n const limit = mode === 'full' ? entries.length : maxVisible;\r\n const { visible, hiddenToolUseCount } = processAgentProgressLines(entries, {\r\n isRunning,\r\n maxVisible: limit,\r\n });\r\n\r\n return (\r\n <div className=\"lax-agent-progress\" data-testid=\"lax-agent-progress\">\r\n {visible.map((line, index) => (\r\n <div\r\n key={`${index}:${line.text}`}\r\n className=\"lax-agent-progress__line\"\r\n >\r\n <span className=\"lax-agent-progress__gutter\" aria-hidden>\r\n {AGENT_PROGRESS_GUTTER}\r\n </span>\r\n <span className=\"lax-agent-progress__text\">{line.text}</span>\r\n </div>\r\n ))}\r\n {hiddenToolUseCount > 0 && mode !== 'full' ? (\r\n <div className=\"lax-agent-progress__line lax-agent-progress__line--more\">\r\n <span className=\"lax-agent-progress__gutter\" aria-hidden>\r\n {AGENT_PROGRESS_GUTTER}\r\n </span>\r\n <button\r\n type=\"button\"\r\n className=\"lax-agent-progress__more\"\r\n onClick={onExpand}\r\n >\r\n +{hiddenToolUseCount} more tool {hiddenToolUseCount === 1 ? 'use' : 'uses'}\r\n </button>\r\n </div>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\n * subagentTranscriptRenderer.ts — transcript lane 行渲染(对齐 CLI subagent_transcript_lane.py)\n */\nimport type { SubagentTranscriptEntry } from '../../../types/nodes';\nimport { truncatePreview } from './agentHelpers';\nimport { formatSubagentToolProgressLine } from './agentProgressRenderer';\n\nfunction toolCallsFromAssistant(message: Record<string, unknown>): Record<string, unknown>[] {\n const raw = message.tool_calls;\n if (!Array.isArray(raw)) return [];\n return raw.filter(\n (item): item is Record<string, unknown> =>\n item != null && typeof item === 'object' && !Array.isArray(item),\n );\n}\n\nfunction toolInputFromCall(call: Record<string, unknown>): Record<string, unknown> | null {\n const args = call.args;\n if (args != null && typeof args === 'object' && !Array.isArray(args)) {\n return args as Record<string, unknown>;\n }\n const input = call.input;\n if (input != null && typeof input === 'object' && !Array.isArray(input)) {\n return input as Record<string, unknown>;\n }\n return null;\n}\n\nfunction formatAssistantToolLine(\n toolName: string,\n step: number | undefined,\n toolInput: Record<string, unknown> | null,\n): string {\n const name = toolName.trim() || 'Tool';\n if (name === 'Bash' && toolInput) {\n const cmd = String(toolInput.command ?? toolInput.cmd ?? '').trim();\n if (cmd) return formatSubagentToolProgressLine('Bash', { toolInput: { command: cmd } });\n }\n if (['Read', 'Write', 'Edit', 'Glob', 'Grep'].includes(name) && toolInput) {\n return formatSubagentToolProgressLine(name, { toolInput });\n }\n if (typeof step === 'number') return `${name} step ${step}`;\n return name;\n}\n\nfunction renderUserToolResult(message: Record<string, unknown>): string {\n const content = message.content;\n if (typeof content === 'string' && content.trim()) {\n return truncatePreview(content.trim(), 240);\n }\n if (content != null && typeof content !== 'string') {\n try {\n return truncatePreview(JSON.stringify(content), 240);\n } catch {\n return truncatePreview(String(content), 240);\n }\n }\n const toolName = String(message.name ?? 'tool').trim();\n return `${toolName} result`;\n}\n\n/** 将单条 transcript lane entry 渲染为一行或多行(assistant tool_calls 可展开为多行)。 */\nexport function renderTranscriptEntryLines(entry: SubagentTranscriptEntry): string[] {\n const lines: string[] = [];\n const { messageKind, message, step, toolName } = entry;\n\n if (messageKind === 'assistant') {\n const toolCalls = toolCallsFromAssistant(message);\n if (toolCalls.length > 0) {\n for (const call of toolCalls) {\n const callName = String(call.name ?? toolName ?? 'Tool').trim();\n lines.push(\n formatAssistantToolLine(callName, step, toolInputFromCall(call)),\n );\n }\n return lines;\n }\n const text = String(message.content ?? '').trim();\n if (text) {\n lines.push(truncatePreview(text, 240));\n }\n return lines;\n }\n\n if (messageKind === 'user') {\n lines.push(renderUserToolResult(message));\n }\n return lines;\n}\n\nexport function renderTranscriptLaneLines(entries: SubagentTranscriptEntry[]): string[] {\n const lines: string[] = [];\n for (const entry of entries) {\n lines.push(...renderTranscriptEntryLines(entry));\n }\n return lines.filter((line) => line.length > 0);\n}\n","/**\n * SubagentTranscriptBlock.tsx — transcript lane 展开块(Capability C Phase 3)\n *\n * 对齐 CLI render_transcript_lane_text · CC VerboseAgentTranscript\n */\nimport type { SubagentTranscriptEntry } from '../../../types/nodes';\nimport {\n AGENT_PROGRESS_GUTTER,\n AGENT_PROGRESS_INDENT,\n} from '../presentation/agentProgressRenderer';\nimport { renderTranscriptEntryLines } from '../presentation/subagentTranscriptRenderer';\n\nexport interface SubagentTranscriptBlockProps {\n entries: SubagentTranscriptEntry[];\n /** transcript-lane | progress-fallback | trace-fallback */\n dataSource?: string;\n}\n\nexport function SubagentTranscriptBlock({\n entries,\n dataSource = 'transcript-lane',\n}: SubagentTranscriptBlockProps) {\n if (entries.length === 0) return null;\n\n const rendered: string[] = [];\n for (const entry of entries) {\n rendered.push(...renderTranscriptEntryLines(entry));\n }\n if (rendered.length === 0) return null;\n\n return (\n <div\n className=\"lax-agent-progress lax-agent-progress--transcript\"\n data-testid=\"lax-subagent-transcript-lane\"\n data-source={dataSource}\n >\n {rendered.map((text, index) => (\n <div key={`${index}:${text}`} className=\"lax-agent-progress__line\">\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\">{text}</span>\n </div>\n ))}\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 {\n AGENT_PROGRESS_GUTTER,\n extractLastFilesystemStatusFromProgress,\n} from '../presentation/agentProgressRenderer';\nimport { TruncatedContent } from '../presentation/TruncatedContent';\nimport type { ToolDisplayProps } from '../types';\nimport { AgentProgressLines } from './AgentProgressLines';\nimport { SubagentTranscriptBlock } from './SubagentTranscriptBlock';\n\nexport function AgentToolBody({\n result,\n bodyMode,\n onBodyModeChange,\n status,\n subagentProgress,\n subagentTranscript,\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 transcriptLane = subagentTranscript ?? [];\n const bodyText = buildAgentBodyText(result?.display, result?.summary ?? '');\n const transcriptFallback = buildAgentTranscriptText(result?.display, progress);\n const showDoneSummary = status !== 'running' && bodyText.length > 0;\n const doneFilesystemStatus =\n status !== 'running' ? extractLastFilesystemStatusFromProgress(progress) : null;\n const showTranscriptLane =\n bodyMode === 'full' && transcriptLane.length > 0;\n const showRunningProgress =\n status === 'running' && progress.length > 0 && !showTranscriptLane;\n const showTranscriptFallback =\n bodyMode === 'full' &&\n !showTranscriptLane &&\n transcriptFallback.length > 0;\n\n if (\n !showRunningProgress &&\n !showDoneSummary &&\n !doneFilesystemStatus &&\n !showTranscriptLane &&\n !showTranscriptFallback\n ) {\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 {showDoneSummary && doneFilesystemStatus ? (\n <div\n className=\"lax-agent-progress lax-agent-progress--done-status\"\n data-testid=\"lax-agent-done-filesystem-status\"\n >\n <div className=\"lax-agent-progress__line\">\n <span className=\"lax-agent-progress__gutter\" aria-hidden>\n {AGENT_PROGRESS_GUTTER}\n </span>\n <span className=\"lax-agent-progress__text\">{doneFilesystemStatus}</span>\n </div>\n </div>\n ) : null}\n {showTranscriptLane ? (\n <SubagentTranscriptBlock entries={transcriptLane} dataSource=\"transcript-lane\" />\n ) : null}\n {showTranscriptFallback ? (\n <div\n className=\"lax-agent-progress lax-agent-progress--transcript\"\n data-source=\"trace-fallback\"\n >\n <div className=\"lax-agent-progress__label\">Transcript</div>\n <TruncatedContent text={transcriptFallback} mode=\"full\" />\n </div>\n ) : null}\n </div>\n );\n}\n","/**\r\n * askUserHelpers.ts — AskUserQuestion 正文与预览\r\n *\r\n * 对齐参考:CLI widgets/tools/helpers.py format_ask_user_*\r\n */\r\nexport function formatAskUserDisplayBody(display: Record<string, unknown>): string {\r\n const items = display.questions;\r\n if (!Array.isArray(items) || items.length === 0) return '';\r\n\r\n const lines: string[] = [];\r\n for (const item of items) {\r\n if (item == null || typeof item !== 'object') continue;\r\n const row = item as Record<string, unknown>;\r\n const header = String(row.header ?? '').trim();\r\n const question = String(row.question ?? '').trim();\r\n const answer = String(row.answer ?? '').trim();\r\n const prefix = header ? `[${header}] ` : '';\r\n lines.push(`${prefix}${question}`);\r\n if (answer) lines.push(` → ${answer}`);\r\n const selected = row.selected_options;\r\n if (Array.isArray(selected) && selected.length > 0) {\r\n for (const label of selected) {\r\n lines.push(` · ${String(label)}`);\r\n }\r\n }\r\n }\r\n return lines.length > 0 ? lines.join('\\n') : '';\r\n}\r\n\r\nexport function formatAskUserQuestionsPreview(input: Record<string, unknown>): string {\r\n const questions = input.questions;\r\n if (!Array.isArray(questions) || questions.length === 0) {\r\n return '(waiting for answers)';\r\n }\r\n\r\n const lines: string[] = [];\r\n questions.forEach((raw, idx) => {\r\n if (raw == null || typeof raw !== 'object') return;\r\n const q = raw as Record<string, unknown>;\r\n const header = String(q.header ?? '').trim();\r\n const qtext = String(q.question ?? '').trim();\r\n const prefix = header ? `[${header}] ` : '';\r\n lines.push(`${idx + 1}. ${prefix}${qtext}`);\r\n const options = q.options;\r\n if (Array.isArray(options)) {\r\n for (const opt of options) {\r\n if (opt != null && typeof opt === 'object') {\r\n const label = String((opt as Record<string, unknown>).label ?? '').trim();\r\n if (label) lines.push(` · ${label}`);\r\n }\r\n }\r\n }\r\n });\r\n return lines.length > 0 ? lines.join('\\n') : '(waiting for answers)';\r\n}\r\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","/**\r\n * BashToolBody.tsx — bash 工具多块 stdout/stderr 正文\r\n *\r\n * 对齐参考:CLI widgets/tools/bash/widget.py · CC BashTool/UI.tsx\r\n */\r\nimport { BodyBlockList } from '../presentation/BodyBlockList';\r\nimport { buildBashBodyBlocks } from '../presentation/bashHelpers';\r\nimport type { ToolDisplayProps } from '../types';\r\n\r\nexport function BashToolBody({\r\n result,\r\n bodyMode,\r\n onBodyModeChange,\r\n}: ToolDisplayProps) {\r\n const isError = result?.status === 'failed' || Boolean(result?.error);\r\n const summary = result?.summary ?? '';\r\n const { blocks, truncated, remainingLines } = buildBashBodyBlocks(\r\n result?.display,\r\n summary,\r\n result?.meta,\r\n bodyMode,\r\n isError,\r\n );\r\n\r\n return (\r\n <div className=\"lax-tool-body lax-tool-body--bash\">\r\n <BodyBlockList blocks={blocks} />\r\n {truncated && bodyMode === 'preview' ? (\r\n <button\r\n type=\"button\"\r\n className=\"lax-tool-body__expand\"\r\n onClick={() => onBodyModeChange?.('full')}\r\n >\r\n +{remainingLines} lines (点击展开)\r\n </button>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\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","/**\r\n * registry.ts — 工具展示注册表\r\n */\r\nimport { AgentToolBody } from './agent/AgentToolBody';\r\nimport { AskUserQuestionToolBody } from './ask_user_question/AskUserQuestionToolBody';\r\nimport { BashToolBody } from './bash/BashToolBody';\r\nimport { EditToolBody } from './edit/EditToolBody';\r\nimport { GlobToolBody } from './glob/GlobToolBody';\r\nimport { GrepToolBody } from './grep/GrepToolBody';\r\nimport { ReadToolBody } from './read/ReadToolBody';\r\nimport { SkillToolBody } from './skill/SkillToolBody';\r\nimport { WebFetchToolBody } from './webfetch/WebFetchToolBody';\r\nimport { WebSearchToolBody } from './websearch/WebSearchToolBody';\r\nimport { WriteToolBody } from './write/WriteToolBody';\r\nimport {\r\n Agent,\r\n AskUserQuestion,\r\n Bash,\r\n Edit,\r\n Glob,\r\n Grep,\r\n Read,\r\n Skill,\r\n WebFetch,\r\n WebSearch,\r\n Write,\r\n} from './toolNames';\r\nimport type { ToolBodyComponent } from './types';\r\n\r\nexport class ToolDisplayRegistry {\r\n private readonly map = new Map<string, ToolBodyComponent>();\r\n\r\n register(toolName: string, body: ToolBodyComponent): this {\r\n this.map.set(toolName, body);\r\n return this;\r\n }\r\n\r\n resolve(toolName: string): ToolBodyComponent | undefined {\r\n return this.map.get(toolName);\r\n }\r\n\r\n static default(): ToolDisplayRegistry {\r\n return createDefaultToolRegistry();\r\n }\r\n}\r\n\r\n/** 默认 registry:CC TOOL_NAME 单键,与 SDK registry_names.py 对齐。 */\r\nexport function createDefaultToolRegistry(): ToolDisplayRegistry {\r\n return new ToolDisplayRegistry()\r\n .register(Read, ReadToolBody)\r\n .register(Grep, GrepToolBody)\r\n .register(Glob, GlobToolBody)\r\n .register(Edit, EditToolBody)\r\n .register(Write, WriteToolBody)\r\n .register(Bash, BashToolBody)\r\n .register(Agent, AgentToolBody)\r\n .register(Skill, SkillToolBody)\r\n .register(AskUserQuestion, AskUserQuestionToolBody)\r\n .register(WebSearch, WebSearchToolBody)\r\n .register(WebFetch, WebFetchToolBody);\r\n}\r\n"],"mappings":"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","names":["truncatePreview","truncated","was","formatSubagentProgressLine","truncatePreview","jsx","jsxs","jsx","jsxs","jsx","text","jsx","jsxs","jsx","jsx","summary","jsx","summary","jsx","jsxs","jsx","jsx","MAX_BODY_LINES","jsx","MAX_BODY_LINES","jsx"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/view/tools/presentation/paths.ts","../src/view/tools/presentation/searchHelpers.ts","../src/view/tools/presentation/TruncatedContent.tsx","../src/view/tools/presentation/bashHelpers.ts","../src/view/tools/presentation/BodyBlockList.tsx","../src/view/tools/presentation/diffHelpers.ts","../src/view/tools/presentation/DiffView.tsx","../src/view/tools/presentation/MarkdownBlock.tsx","../src/core/context/MarkdownRendererContext.tsx"],"sourcesContent":["/**\r\n * paths.ts — 路径展示 helper\r\n *\r\n * 职责:\r\n * 将绝对路径转为较短展示字符串(Web 无 cwd 时仅 normalize 分隔符)。\r\n *\r\n * 链路位置:\r\n * T1+ Read/Edit Widget title。\r\n *\r\n * 当前裁剪范围:\r\n * 不做 relpath(浏览器无 process.cwd);仅 slash 归一化。\r\n *\r\n * 对齐参考:\r\n * CLI widgets/tools/helpers.py display_path\r\n */\r\n\r\nexport function displayPath(filePath: string): string {\r\n if (!filePath) return '';\r\n return filePath.replace(/\\\\/g, '/');\r\n}\r\n","/**\r\n * searchHelpers.ts — grep/glob 标题与列表正文 helper\r\n *\r\n * 对齐参考:CLI widgets/tools/helpers.py format_pattern_title、format_search_result_body\r\n */\r\n\r\nimport { displayPath } from './paths';\r\n\r\nexport const SEARCH_LIST_PREVIEW_LINES = 20;\r\n\r\nconst FOUND_SUMMARY_RE = /^(Found .+|No files found|No matches found)/i;\r\n\r\nexport function formatPatternTitle(pattern: string, path?: string | null): string {\r\n const parts = [`pattern: \"${pattern}\"`];\r\n if (path) {\r\n parts.push(`path: \"${displayPath(path)}\"`);\r\n }\r\n return parts.join(', ');\r\n}\r\n\r\nexport function extractSearchSummary(output: string): string {\r\n const text = output.trim();\r\n if (!text) return '';\r\n const match = text.match(FOUND_SUMMARY_RE);\r\n if (match) return match[1].trim();\r\n const first = text.split('\\n', 1)[0]?.trim() ?? '';\r\n if (/^(found |no files|no matches)/i.test(first)) return first;\r\n return '';\r\n}\r\n\r\nexport function truncateLines(\r\n text: string,\r\n maxLines: number,\r\n): { text: string; truncated: boolean } {\r\n const lines = text.split('\\n');\r\n if (lines.length <= maxLines) {\r\n return { text, truncated: false };\r\n }\r\n return {\r\n text: lines.slice(0, maxLines).join('\\n'),\r\n truncated: true,\r\n };\r\n}\r\n\r\nexport function formatSearchResultBody(\r\n output: string,\r\n maxListLines = SEARCH_LIST_PREVIEW_LINES,\r\n): string {\r\n const text = output.trim();\r\n if (!text) return '(No output)';\r\n\r\n const summary = extractSearchSummary(text);\r\n const lines = text.split('\\n');\r\n let listLines: string[];\r\n\r\n if (summary && lines[0]?.trim() === summary) {\r\n listLines = lines.slice(1);\r\n } else if (summary) {\r\n listLines = lines.filter((ln) => ln.trim() !== summary);\r\n } else {\r\n listLines = lines;\r\n }\r\n\r\n const listText = listLines\r\n .map((ln) => ln.trim())\r\n .filter(Boolean)\r\n .join('\\n');\r\n\r\n if (listText) {\r\n const { text: truncated, truncated: wasTruncated } = truncateLines(\r\n listText,\r\n maxListLines,\r\n );\r\n const suffix = wasTruncated ? `\\n… 列表超过 ${maxListLines} 行,已截断` : '';\r\n if (summary) return `${summary}\\n${truncated}${suffix}`;\r\n return `${truncated}${suffix}`;\r\n }\r\n\r\n return summary || text.slice(0, 500);\r\n}\r\n","/**\n * TruncatedContent.tsx — PREVIEW 行数截断\n *\n * 职责:\n * 默认 3 行预览 + expand 控件;FULL 模式展示全文。\n *\n * 链路位置:\n * DefaultToolBody、T1+ 各 ToolBody 正文。\n *\n * 当前裁剪范围:\n * 纯文本;不做 ANSI / 终端 wrap。\n *\n * 对齐参考:\n * CLI presentation/shell_output.py · CC utils/terminal.ts MAX_LINES_TO_SHOW=3\n */\nimport type { ToolBodyMode } from '../types';\n\nexport const MAX_PREVIEW_LINES = 3;\n\nexport interface TruncatedContentProps {\n text: string;\n mode: ToolBodyMode;\n maxLines?: number;\n onExpand?: () => void;\n}\n\nexport function TruncatedContent({\n text,\n mode,\n maxLines = MAX_PREVIEW_LINES,\n onExpand,\n}: TruncatedContentProps) {\n const lines = text.split('\\n');\n const needsTruncate = mode === 'preview' && lines.length > maxLines;\n\n if (!needsTruncate) {\n return (\n <div className=\"lax-tool-body__block\" data-variant=\"normal\">\n <pre className=\"lax-tool-body__text\">{text}</pre>\n </div>\n );\n }\n\n const preview = lines.slice(0, maxLines).join('\\n');\n const remaining = lines.length - maxLines;\n\n return (\n <div className=\"lax-tool-body__block\" data-variant=\"normal\">\n <pre className=\"lax-tool-body__text\">{preview}</pre>\n <button\n type=\"button\"\n className=\"lax-tool-body__expand\"\n onClick={onExpand}\n >\n +{remaining} lines (点击展开)\n </button>\n </div>\n );\n}\n","/**\r\n * bashHelpers.ts — bash 命令与输出解析\r\n *\r\n * 对齐参考:CLI widgets/tools/helpers.py · bash/widget.py format_body_blocks\r\n */\r\nimport type { ToolBodyMode } from '../types';\r\nimport { MAX_PREVIEW_LINES } from './TruncatedContent';\r\nimport type { BodyBlock } from './BodyBlockList';\r\n\r\nexport const MAX_COMMAND_DISPLAY_CHARS = 160;\r\nexport const MAX_COMMAND_DISPLAY_LINES = 2;\r\n\r\nconst CWD_RESET_PATTERN = /(?:^|\\n)(Shell cwd was reset to .+)$/m;\r\nconst EXIT_CODE_PATTERN = /(?:^|\\n)Exit code:\\s*(\\d+)/m;\r\n\r\nexport function truncateCommand(command: string, maxChars = MAX_COMMAND_DISPLAY_CHARS): string {\r\n let text = command.trim();\r\n if (!text) return '';\r\n const lines = text.split('\\n');\r\n if (lines.length > MAX_COMMAND_DISPLAY_LINES) {\r\n text = lines.slice(0, MAX_COMMAND_DISPLAY_LINES).join('\\n');\r\n }\r\n if (text.length > maxChars) {\r\n text = `${text.slice(0, maxChars)}…`;\r\n }\r\n return text;\r\n}\r\n\r\nexport function formatBashTitle(input: unknown): string {\r\n const inp =\r\n input != null && typeof input === 'object' && !Array.isArray(input)\r\n ? (input as Record<string, unknown>)\r\n : {};\r\n const command = String(inp.command ?? '').trim();\r\n if (!command) return 'Bash';\r\n return `Bash(${truncateCommand(command)})`;\r\n}\r\n\r\nexport function splitBashStreams(output: string): {\r\n stdout: string;\r\n stderr: string;\r\n cwdWarning: string | null;\r\n} {\r\n let text = output ?? '';\r\n let cwdWarning: string | null = null;\r\n const cwdMatch = text.match(CWD_RESET_PATTERN);\r\n if (cwdMatch) {\r\n cwdWarning = cwdMatch[1]?.trim() ?? null;\r\n text = text.replace(CWD_RESET_PATTERN, '').trim();\r\n }\r\n\r\n let stdout = text;\r\n let stderr = '';\r\n if (text.includes('\\n--- stderr ---\\n')) {\r\n const parts = text.split('\\n--- stderr ---\\n');\r\n stdout = parts[0] ?? '';\r\n stderr = parts[1] ?? '';\r\n } else if (text.startsWith('stderr:')) {\r\n stderr = text.slice(7).trim();\r\n stdout = '';\r\n }\r\n\r\n return { stdout: stdout.trim(), stderr: stderr.trim(), cwdWarning };\r\n}\r\n\r\nexport function parseExitCode(output: string, fallback?: number | null): number | null {\r\n const match = (output ?? '').match(EXIT_CODE_PATTERN);\r\n if (match) return Number.parseInt(match[1], 10);\r\n return fallback ?? null;\r\n}\r\n\r\nexport function formatDuration(seconds: number): string {\r\n if (seconds < 1) return `${seconds.toFixed(1)}s`;\r\n if (seconds < 60) return `${Math.floor(seconds)}s`;\r\n if (seconds < 3600) {\r\n const minutes = Math.floor(seconds / 60);\r\n const secs = Math.floor(seconds % 60);\r\n return secs === 0 ? `${minutes}m` : `${minutes}m ${secs}s`;\r\n }\r\n const hours = Math.floor(seconds / 3600);\r\n const minutes = Math.floor((seconds % 3600) / 60);\r\n return minutes === 0 ? `${hours}h` : `${hours}h ${minutes}m`;\r\n}\r\n\r\nexport function formatTimeoutFooter(timeoutMs: number | null | undefined): string | null {\r\n if (!timeoutMs) return null;\r\n return `(timeout ${formatDuration(timeoutMs / 1000)})`;\r\n}\r\n\r\nfunction previewStreamText(text: string, mode: ToolBodyMode): string {\r\n if (mode === 'full' || !text.trim()) return text;\r\n const lines = text.split('\\n');\r\n if (lines.length <= MAX_PREVIEW_LINES) return text;\r\n // 对齐 CLI ShellOutputPreviewer:PREVIEW 只保留前 N 行;expand hint 由 UI 层单独渲染\r\n return lines.slice(0, MAX_PREVIEW_LINES).join('\\n');\r\n}\r\n\r\nfunction resolveStreams(\r\n display: Record<string, unknown> | null,\r\n summary: string,\r\n): { stdout: string; stderr: string; cwdWarning: string | null } {\r\n if (display && ('stdout' in display || 'stderr' in display)) {\r\n return {\r\n stdout: String(display.stdout ?? ''),\r\n stderr: String(display.stderr ?? ''),\r\n cwdWarning: null,\r\n };\r\n }\r\n return splitBashStreams(summary);\r\n}\r\n\r\nfunction resolveExitCode(\r\n display: Record<string, unknown> | null,\r\n summary: string,\r\n): number | null {\r\n if (display && 'exit_code' in display) {\r\n const code = display.exit_code;\r\n if (typeof code === 'number') return code;\r\n if (typeof code === 'string' && code.trim()) {\r\n const n = Number.parseInt(code, 10);\r\n if (Number.isFinite(n)) return n;\r\n }\r\n return null;\r\n }\r\n return parseExitCode(summary);\r\n}\r\n\r\nfunction resolveTimeoutMs(\r\n display: Record<string, unknown> | null,\r\n meta: unknown,\r\n): number | null {\r\n if (display?.timeout_ms != null) {\r\n const n = Number(display.timeout_ms);\r\n return Number.isFinite(n) ? n : null;\r\n }\r\n if (meta != null && typeof meta === 'object' && !Array.isArray(meta)) {\r\n const ms = (meta as Record<string, unknown>).timeout_ms;\r\n if (ms != null) {\r\n const n = Number(ms);\r\n return Number.isFinite(n) ? n : null;\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nexport function buildBashBodyBlocks(\r\n display: unknown,\r\n summary: string,\r\n meta: unknown,\r\n mode: ToolBodyMode,\r\n isError: boolean,\r\n): { blocks: BodyBlock[]; truncated: boolean; remainingLines: number } {\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n\r\n if (isError) {\r\n const blocks: BodyBlock[] = [\r\n { text: summary.trim() || 'Error', variant: 'error' },\r\n ];\r\n const footer = formatTimeoutFooter(resolveTimeoutMs(d, meta));\r\n if (footer) blocks.push({ text: footer, variant: 'dim' });\r\n return { blocks, truncated: false, remainingLines: 0 };\r\n }\r\n\r\n const { stdout, stderr, cwdWarning } = resolveStreams(d, summary);\r\n const code = resolveExitCode(d, summary);\r\n const blocks: BodyBlock[] = [];\r\n let truncated = false;\r\n let remainingLines = 0;\r\n\r\n const addStream = (text: string, variant: BodyBlock['variant']) => {\r\n if (!text.trim()) return;\r\n const lines = text.split('\\n');\r\n const rendered = previewStreamText(text, mode);\r\n if (mode === 'preview' && lines.length > MAX_PREVIEW_LINES) {\r\n truncated = true;\r\n remainingLines += lines.length - MAX_PREVIEW_LINES;\r\n }\r\n blocks.push({ text: rendered, variant });\r\n };\r\n\r\n addStream(stdout, 'normal');\r\n addStream(stderr, 'error');\r\n\r\n if (cwdWarning) {\r\n blocks.push({ text: cwdWarning, variant: 'dim' });\r\n }\r\n\r\n if (code != null && code !== 0) {\r\n blocks.push({ text: `Exit code: ${code}`, variant: 'error' });\r\n }\r\n\r\n if (blocks.length === 0) {\r\n const noOutputExpected = Boolean(d?.no_output_expected);\r\n blocks.push({\r\n text: noOutputExpected ? 'Done' : '(No output)',\r\n variant: 'dim',\r\n });\r\n }\r\n\r\n const footer = formatTimeoutFooter(resolveTimeoutMs(d, meta));\r\n if (footer) {\r\n blocks.push({ text: footer, variant: 'dim' });\r\n }\r\n\r\n if (d?.truncated && d?.overflow_file) {\r\n blocks.push({\r\n text: `Output truncated; see ${String(d.overflow_file)}`,\r\n variant: 'dim',\r\n });\r\n }\r\n\r\n return { blocks, truncated, remainingLines };\r\n}\r\n","/**\r\n * BodyBlockList.tsx — ⎿ 多块正文布局\r\n *\r\n * 职责:\r\n * 多块平面文本,支持 normal / error / dim 变体。\r\n *\r\n * 链路位置:\r\n * T3 bash stdout/stderr 分块;DefaultToolBody 可复用。\r\n *\r\n * 当前裁剪范围:\r\n * 块内不做 TruncatedContent(由调用方传入已截断文本)。\r\n *\r\n * 对齐参考:\r\n * CLI presentation/message_layout.py · CC MessageResponse.tsx ⎿ 前缀\r\n */\r\n\r\nexport interface BodyBlock {\r\n text: string;\r\n variant?: 'normal' | 'error' | 'dim';\r\n}\r\n\r\nexport interface BodyBlockListProps {\r\n blocks: BodyBlock[];\r\n}\r\n\r\nexport function BodyBlockList({ blocks }: BodyBlockListProps) {\r\n if (blocks.length === 0) return null;\r\n\r\n return (\r\n <div className=\"lax-tool-body__blocks\">\r\n {blocks.map((block, index) => (\r\n <div\r\n key={index}\r\n className=\"lax-tool-body__block\"\r\n data-variant={block.variant ?? 'normal'}\r\n >\r\n <pre className=\"lax-tool-body__text\">{block.text}</pre>\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","/**\r\n * diffHelpers.ts — unified diff 生成与解析\r\n *\r\n * 对齐参考:CLI widgets/tools/helpers.py format_diff_from_strings\r\n */\r\n\r\nexport const WRITE_PREVIEW_LINES = 10;\r\nexport const DIFF_PREVIEW_LINES = 12;\r\n\r\nexport type DiffLineKind = 'add' | 'remove' | 'context' | 'meta';\r\n\r\nexport interface ParsedDiffLine {\r\n kind: DiffLineKind;\r\n text: string;\r\n}\r\n\r\nexport function countLines(text: string): number {\r\n if (!text) return 0;\r\n return text.split('\\n').length;\r\n}\r\n\r\nexport function formatDiffFromStrings(oldText: string, newText: string): string {\r\n if (oldText === newText) return '(no changes)';\r\n\r\n const oldLines = oldText.split('\\n');\r\n const newLines = newText.split('\\n');\r\n const body: string[] = [];\r\n let i = 0;\r\n let j = 0;\r\n\r\n while (i < oldLines.length || j < newLines.length) {\r\n const oldLine = oldLines[i];\r\n const newLine = newLines[j];\r\n\r\n if (i < oldLines.length && j < newLines.length && oldLine === newLine) {\r\n body.push(` ${oldLine}`);\r\n i += 1;\r\n j += 1;\r\n continue;\r\n }\r\n\r\n if (i < oldLines.length && (j >= newLines.length || oldLine !== newLine)) {\r\n body.push(`-${oldLine}`);\r\n i += 1;\r\n continue;\r\n }\r\n\r\n if (j < newLines.length) {\r\n body.push(`+${newLine}`);\r\n j += 1;\r\n }\r\n }\r\n\r\n if (body.length === 0) return '(no changes)';\r\n\r\n return ['--- old', '+++ new', '@@', ...body].join('\\n');\r\n}\r\n\r\nexport function parseDiffText(diff: string): ParsedDiffLine[] {\r\n if (diff === '(no changes)') {\r\n return [{ kind: 'meta', text: diff }];\r\n }\r\n\r\n const result: ParsedDiffLine[] = [];\r\n for (const line of diff.split('\\n')) {\r\n if (!line && result.length > 0) {\r\n result.push({ kind: 'context', text: '' });\r\n continue;\r\n }\r\n if (line.startsWith('+++') || line.startsWith('---') || line.startsWith('@@')) {\r\n result.push({ kind: 'meta', text: line });\r\n } else if (line.startsWith('+')) {\r\n result.push({ kind: 'add', text: line.slice(1) });\r\n } else if (line.startsWith('-')) {\r\n result.push({ kind: 'remove', text: line.slice(1) });\r\n } else if (line.startsWith(' ')) {\r\n result.push({ kind: 'context', text: line.slice(1) });\r\n } else {\r\n result.push({ kind: 'context', text: line });\r\n }\r\n }\r\n return result;\r\n}\r\n\r\nexport function resolveEditDiffText(\r\n display: unknown,\r\n input: unknown,\r\n summary: string,\r\n): string {\r\n const d =\r\n display != null && typeof display === 'object' && !Array.isArray(display)\r\n ? (display as Record<string, unknown>)\r\n : null;\r\n const inp =\r\n input != null && typeof input === 'object' && !Array.isArray(input)\r\n ? (input as Record<string, unknown>)\r\n : {};\r\n\r\n const diffField = d?.diff;\r\n if (typeof diffField === 'string' && diffField.trim()) {\r\n return diffField.trim();\r\n }\r\n\r\n const oldStr =\r\n (typeof d?.old_string === 'string' ? d.old_string : '') ||\r\n (typeof inp.old_string === 'string' ? inp.old_string : '');\r\n const newStr =\r\n (typeof d?.new_string === 'string' ? d.new_string : '') ||\r\n (typeof inp.new_string === 'string' ? inp.new_string : '');\r\n\r\n if (oldStr || newStr) {\r\n return formatDiffFromStrings(oldStr, newStr);\r\n }\r\n\r\n const trimmed = summary.trim();\r\n if (trimmed) return trimmed;\r\n return '(done)';\r\n}\r\n","/**\r\n * DiffView.tsx — unified diff 渲染(纯 CSS +/- 行前缀)\r\n *\r\n * 对齐参考:CC components/FileEditToolDiff.tsx · CLI format_diff_from_strings\r\n */\r\nimport type { ToolBodyMode } from '../types';\r\nimport {\r\n DIFF_PREVIEW_LINES,\r\n parseDiffText,\r\n type ParsedDiffLine,\r\n} from './diffHelpers';\r\n\r\nexport interface DiffViewProps {\r\n diff: string;\r\n mode: ToolBodyMode;\r\n maxPreviewLines?: number;\r\n onExpand?: () => void;\r\n}\r\n\r\nfunction renderLine(line: ParsedDiffLine, index: number) {\r\n const prefix =\r\n line.kind === 'add' ? '+' : line.kind === 'remove' ? '-' : line.kind === 'meta' ? '' : ' ';\r\n\r\n return (\r\n <div\r\n key={index}\r\n className=\"lax-tool-diff__line\"\r\n data-kind={line.kind}\r\n >\r\n {prefix ? (\r\n <span className=\"lax-tool-diff__prefix\" aria-hidden>\r\n {prefix}\r\n </span>\r\n ) : null}\r\n <span className=\"lax-tool-diff__text\">{line.text}</span>\r\n </div>\r\n );\r\n}\r\n\r\nexport function DiffView({\r\n diff,\r\n mode,\r\n maxPreviewLines = DIFF_PREVIEW_LINES,\r\n onExpand,\r\n}: DiffViewProps) {\r\n const lines = parseDiffText(diff);\r\n const needsTruncate = mode === 'preview' && lines.length > maxPreviewLines;\r\n const visible = needsTruncate ? lines.slice(0, maxPreviewLines) : lines;\r\n\r\n return (\r\n <div className=\"lax-tool-diff\">\r\n {visible.map(renderLine)}\r\n {needsTruncate ? (\r\n <button\r\n type=\"button\"\r\n className=\"lax-tool-body__expand\"\r\n onClick={onExpand}\r\n >\r\n +{lines.length - maxPreviewLines} diff lines (点击展开)\r\n </button>\r\n ) : null}\r\n </div>\r\n );\r\n}\r\n","/**\n * MarkdownBlock.tsx — 完整 markdown 渲染(带性能优化)\n *\n * 职责:display.type=markdown 等场景的段落/列表/代码块/表格。\n * 链路位置:ReadToolBody 等 ToolBody。\n *\n * 性能优化(参考 CC):\n * - 快速路径:纯文本跳过 markdown 解析\n * - 内容哈希缓存:相同内容不重复解析\n * - 组件记忆化:避免不必要的重渲染\n *\n * 功能:\n * - 完整 GFM 支持 (GitHub Flavored Markdown)\n * - 代码语法高亮\n * - 表格渲染\n * - 拷贝按钮\n */\nimport { memo, useMemo, useState } from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';\nimport { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';\n\nimport { useMarkdownRenderer } from '../../../core/context/MarkdownRendererContext';\nimport type { ToolBodyMode } from '../types';\nimport { MAX_PREVIEW_LINES } from './TruncatedContent';\n\nexport interface MarkdownBlockProps {\n text: string;\n mode: ToolBodyMode;\n maxLines?: number;\n onExpand?: () => void;\n className?: string;\n}\n\n/**\n * 简单的内容哈希函数(用于缓存)\n * 使用 djb2 算法,性能好且冲突率低\n */\nfunction 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\n/**\n * 检测是否包含 markdown 语法\n * 快速路径:如果没有任何 markdown 标记,直接渲染为纯文本\n * 检查前 500 字符即可(markdown 语法通常在前面)\n */\nfunction hasMarkdownSyntax(content: string): boolean {\n const sample = content.length > 500 ? content.slice(0, 500) : content;\n // 检测常见的 markdown 语法标记\n const MD_SYNTAX_RE = /[#*`|[>\\-_~]|\\n\\n|^\\d+\\. |\\n\\d+\\. /;\n return MD_SYNTAX_RE.test(sample);\n}\n\n// 代码块组件(带拷贝功能)- 记忆化\ninterface CodeBlockProps {\n language: string;\n content: string;\n}\n\nconst CodeBlock = memo(function CodeBlock({ language, content }: CodeBlockProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(content);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n };\n\n return (\n <div className=\"lax-code-block\">\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={handleCopy}\n title={copied ? '已拷贝!' : '拷贝代码'}\n >\n {copied ? (\n <>\n <svg className=\"lax-code-block__icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={3}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M5 13l4 4L19 7\" />\n </svg>\n <span>已拷贝</span>\n </>\n ) : (\n <>\n <svg className=\"lax-code-block__icon\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n <span>拷贝</span>\n </>\n )}\n </button>\n </div>\n <SyntaxHighlighter\n language={language}\n style={oneDark}\n customStyle={{\n margin: 0,\n padding: 0,\n background: 'transparent',\n }}\n showLineNumbers={false}\n wrapLongLines={true}\n >\n {content}\n </SyntaxHighlighter>\n </div>\n );\n});\n\n// Markdown 组件配置 - 缓存在组件外部,避免重复创建\nconst MARKDOWN_COMPONENTS = {\n // 代码块\n code({ node, className, children, ...props }: any) {\n const match = /language-(\\w+)/.exec(className || '');\n const codeContent = String(children).replace(/\\n$/, '');\n const inline = !className;\n\n if (!inline && match) {\n return <CodeBlock language={match[1]} content={codeContent} />;\n }\n\n return (\n <code className=\"lax-markdown__inline-code\" {...props}>\n {children}\n </code>\n );\n },\n // 标题\n h1({ children }: any) { return <h1 className=\"lax-markdown__heading lax-markdown__h1\">{children}</h1>; },\n h2({ children }: any) { return <h2 className=\"lax-markdown__heading lax-markdown__h2\">{children}</h2>; },\n h3({ children }: any) { return <h3 className=\"lax-markdown__heading lax-markdown__h3\">{children}</h3>; },\n h4({ children }: any) { return <h4 className=\"lax-markdown__heading lax-markdown__h4\">{children}</h4>; },\n h5({ children }: any) { return <h5 className=\"lax-markdown__heading lax-markdown__h5\">{children}</h5>; },\n h6({ children }: any) { return <h6 className=\"lax-markdown__heading lax-markdown__h6\">{children}</h6>; },\n // 段落\n p({ children }: any) { return <p className=\"lax-markdown__paragraph\">{children}</p>; },\n // 列表\n ul({ children }: any) { return <ul className=\"lax-markdown__list lax-markdown__ul\">{children}</ul>; },\n ol({ children }: any) { return <ol className=\"lax-markdown__list lax-markdown__ol\">{children}</ol>; },\n li({ children }: any) { return <li className=\"lax-markdown__li\">{children}</li>; },\n // 链接\n a({ children, href }: any) {\n return (\n <a href={href} className=\"lax-markdown__link\" target=\"_blank\" rel=\"noopener noreferrer\">\n {children}\n </a>\n );\n },\n // 引用\n blockquote({ children }: any) { return <blockquote className=\"lax-markdown__blockquote\">{children}</blockquote>; },\n // 表格\n table({ children }: any) {\n return (\n <div className=\"lax-markdown__table-wrapper\">\n <table className=\"lax-markdown__table\">{children}</table>\n </div>\n );\n },\n thead({ children }: any) { return <thead className=\"lax-markdown__thead\">{children}</thead>; },\n tbody({ children }: any) { return <tbody className=\"lax-markdown__tbody\">{children}</tbody>; },\n tr({ children }: any) { return <tr className=\"lax-markdown__tr\">{children}</tr>; },\n th({ children }: any) { return <th className=\"lax-markdown__th\">{children}</th>; },\n td({ children }: any) { return <td className=\"lax-markdown__td\">{children}</td>; },\n // 分隔线\n hr() { return <hr className=\"lax-markdown__hr\" />; },\n // 强调\n strong({ children }: any) { return <strong className=\"lax-markdown__strong\">{children}</strong>; },\n em({ children }: any) { return <em className=\"lax-markdown__em\">{children}</em>; },\n};\n\n// 纯文本渲染组件(快速路径)\nconst PureTextRenderer = memo(function PureTextRenderer({ content, className }: { content: string; className?: string }) {\n return (\n <div className={['lax-markdown', 'lax-markdown--pure', className].filter(Boolean).join(' ')}>\n <p className=\"lax-markdown__paragraph\">{content}</p>\n </div>\n );\n});\n\n// Markdown 渲染组件(记忆化)\nconst MarkdownRenderer = memo(function MarkdownRenderer({ content, className }: { content: string; className?: string }) {\n return (\n <div className={['lax-markdown', className].filter(Boolean).join(' ')}>\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={MARKDOWN_COMPONENTS}\n >\n {content}\n </ReactMarkdown>\n </div>\n );\n});\n\nexport function MarkdownBlock({\n text,\n mode,\n maxLines = MAX_PREVIEW_LINES,\n onExpand,\n className,\n}: MarkdownBlockProps) {\n const markdownRenderer = useMarkdownRenderer();\n\n // 使用 useMemo 缓存截断和哈希计算\n const { visible, remaining, needsTruncate, contentHash } = useMemo(() => {\n const lines = text.split('\\n');\n const needsTruncate = mode === 'preview' && lines.length > maxLines;\n const visible = needsTruncate ? lines.slice(0, maxLines).join('\\n') : text;\n const remaining = lines.length - maxLines;\n const contentHash = hashContent(visible);\n return { visible, remaining, needsTruncate, contentHash };\n }, [text, mode, maxLines]);\n\n // 如果应用层提供了 markdownRenderer,使用它\n if (markdownRenderer) {\n return (\n <div className={['lax-markdown', className].filter(Boolean).join(' ')}>\n {markdownRenderer({ content: visible, className: 'lax-markdown__rich' })}\n {needsTruncate ? (\n <button\n type=\"button\"\n className=\"lax-tool-body__expand\"\n onClick={onExpand}\n >\n +{remaining} 行 (点击展开)\n </button>\n ) : null}\n </div>\n );\n }\n\n // 使用内容哈希作为 key 来利用 React 的 diff 算法\n // 相同内容不会重新渲染\n const rendererKey = `md-${contentHash}`;\n\n // 快速路径:纯文本直接渲染,跳过 markdown 解析\n if (!hasMarkdownSyntax(visible)) {\n return (\n <>\n <PureTextRenderer key={rendererKey} content={visible} className={className} />\n {needsTruncate ? (\n <button\n type=\"button\"\n className=\"lax-tool-body__expand\"\n onClick={onExpand}\n >\n +{remaining} 行 (点击展开)\n </button>\n ) : null}\n </>\n );\n }\n\n // 完整 markdown 渲染\n return (\n <>\n <MarkdownRenderer key={rendererKey} content={visible} className={className} />\n {needsTruncate ? (\n <button\n type=\"button\"\n className=\"lax-tool-body__expand\"\n onClick={onExpand}\n >\n +{remaining} 行 (点击展开)\n </button>\n ) : null}\n </>\n );\n}\n","/**\r\n * MarkdownRendererContext — 富 Markdown 注入(与 ToolDisplayRegistry 解耦,避免循环依赖)\r\n */\r\nimport { createContext, useContext, type ReactNode } from 'react';\r\n\r\nexport interface MarkdownRendererProps {\r\n content: string;\r\n className?: string;\r\n}\r\n\r\nexport type MarkdownRenderer = (props: MarkdownRendererProps) => ReactNode;\r\n\r\nexport const MarkdownRendererContext = createContext<MarkdownRenderer | undefined>(\r\n undefined,\r\n);\r\n\r\nexport function useMarkdownRenderer(): MarkdownRenderer | undefined {\r\n return useContext(MarkdownRendererContext);\r\n}\r\n"],"mappings":"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","names":["minutes","blocks","footer","jsx","jsx","jsxs","jsx","jsxs","CodeBlock","PureTextRenderer","MarkdownRenderer","needsTruncate","visible","remaining","contentHash"]}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
extractLastToolInfoFromProgress,
|
|
16
16
|
formatExploreSummaryText,
|
|
17
17
|
formatThoughtDurationPrefix
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-FL2G7SV3.js";
|
|
19
19
|
|
|
20
20
|
// src/types/tree.ts
|
|
21
21
|
function createEmptyTree() {
|
|
@@ -1829,7 +1829,7 @@ function resolveWorkflowBanner(state) {
|
|
|
1829
1829
|
const suffix = dropped != null && dropped > 0 ? `\uFF08\u7EA6 ${dropped} \u6761\u4E8B\u4EF6\u672A\u5B8C\u6574\u5C55\u793A\uFF09` : "";
|
|
1830
1830
|
return {
|
|
1831
1831
|
kind: "projection_degraded",
|
|
1832
|
-
message: `\u5C55\u793A\u53EF\u80FD\u4E0D\u5B8C\u6574${suffix}`
|
|
1832
|
+
message: `\u4F20\u8F93\u5F02\u5E38\uFF0C\u5C55\u793A\u53EF\u80FD\u4E0D\u5B8C\u6574${suffix}`
|
|
1833
1833
|
};
|
|
1834
1834
|
}
|
|
1835
1835
|
if (state.display.terminalKind === "forced_closeout" && auth === "done") {
|
|
@@ -5715,4 +5715,4 @@ export {
|
|
|
5715
5715
|
VirtualTimeline,
|
|
5716
5716
|
SessionTimeline
|
|
5717
5717
|
};
|
|
5718
|
-
//# sourceMappingURL=chunk-
|
|
5718
|
+
//# sourceMappingURL=chunk-JAOJAGMM.js.map
|