centaurus-cli 3.1.3 → 3.1.5

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.
Files changed (138) hide show
  1. package/dist/cli-adapter.js +685 -153
  2. package/dist/cli-adapter.js.map +1 -1
  3. package/dist/config/defaultConfig.js +1 -4
  4. package/dist/config/defaultConfig.js.map +1 -1
  5. package/dist/config/models.js +4 -0
  6. package/dist/config/models.js.map +1 -1
  7. package/dist/config/slash-commands.js +66 -2
  8. package/dist/config/slash-commands.js.map +1 -1
  9. package/dist/config/types.js +4 -4
  10. package/dist/config/types.js.map +1 -1
  11. package/dist/index.js +36 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/services/ai-context-injector.js +109 -0
  14. package/dist/services/ai-context-injector.js.map +1 -1
  15. package/dist/services/api-client.js.map +1 -1
  16. package/dist/services/background-task-manager.js +59 -0
  17. package/dist/services/background-task-manager.js.map +1 -1
  18. package/dist/services/local-chat-storage.js +2 -0
  19. package/dist/services/local-chat-storage.js.map +1 -1
  20. package/dist/services/skill-storage.js +141 -0
  21. package/dist/services/skill-storage.js.map +1 -0
  22. package/dist/services/sub-agent-manager.js +49 -8
  23. package/dist/services/sub-agent-manager.js.map +1 -1
  24. package/dist/services/warpify-detector.js +17 -5
  25. package/dist/services/warpify-detector.js.map +1 -1
  26. package/dist/tools/background-command.js +5 -2
  27. package/dist/tools/background-command.js.map +1 -1
  28. package/dist/tools/command.js +367 -109
  29. package/dist/tools/command.js.map +1 -1
  30. package/dist/tools/file-ops.js +23 -6
  31. package/dist/tools/file-ops.js.map +1 -1
  32. package/dist/tools/plan-mode.js +184 -336
  33. package/dist/tools/plan-mode.js.map +1 -1
  34. package/dist/tools/sub-agent.js +24 -5
  35. package/dist/tools/sub-agent.js.map +1 -1
  36. package/dist/tools/todo-list.js +157 -0
  37. package/dist/tools/todo-list.js.map +1 -0
  38. package/dist/types/skill.js +30 -0
  39. package/dist/types/skill.js.map +1 -0
  40. package/dist/ui/components/App.js +956 -162
  41. package/dist/ui/components/App.js.map +1 -1
  42. package/dist/ui/components/AuthScreen.js +3 -1
  43. package/dist/ui/components/AuthScreen.js.map +1 -1
  44. package/dist/ui/components/AuthWelcomeScreen.js +3 -1
  45. package/dist/ui/components/AuthWelcomeScreen.js.map +1 -1
  46. package/dist/ui/components/CodeBlock.js +3 -1
  47. package/dist/ui/components/CodeBlock.js.map +1 -1
  48. package/dist/ui/components/CompactShellPreview.js +44 -0
  49. package/dist/ui/components/CompactShellPreview.js.map +1 -0
  50. package/dist/ui/components/ConfigViewer.js +3 -1
  51. package/dist/ui/components/ConfigViewer.js.map +1 -1
  52. package/dist/ui/components/ConfirmPrompt.js +3 -1
  53. package/dist/ui/components/ConfirmPrompt.js.map +1 -1
  54. package/dist/ui/components/ConnectionStatusMessage.js +3 -1
  55. package/dist/ui/components/ConnectionStatusMessage.js.map +1 -1
  56. package/dist/ui/components/DetailedPlanReviewScreen.js +84 -74
  57. package/dist/ui/components/DetailedPlanReviewScreen.js.map +1 -1
  58. package/dist/ui/components/DiffViewer.js +6 -3
  59. package/dist/ui/components/DiffViewer.js.map +1 -1
  60. package/dist/ui/components/FileCreationPreview.js.map +1 -1
  61. package/dist/ui/components/FileTagAutocomplete.js +4 -2
  62. package/dist/ui/components/FileTagAutocomplete.js.map +1 -1
  63. package/dist/ui/components/InputBox.js +243 -40
  64. package/dist/ui/components/InputBox.js.map +1 -1
  65. package/dist/ui/components/InteractiveShell.js +5 -3
  66. package/dist/ui/components/InteractiveShell.js.map +1 -1
  67. package/dist/ui/components/KeyboardHelp.js +4 -1
  68. package/dist/ui/components/KeyboardHelp.js.map +1 -1
  69. package/dist/ui/components/LoadingIndicator.js +3 -1
  70. package/dist/ui/components/LoadingIndicator.js.map +1 -1
  71. package/dist/ui/components/MCPAddScreen.js +63 -13
  72. package/dist/ui/components/MCPAddScreen.js.map +1 -1
  73. package/dist/ui/components/MarkdownRenderer.js +3 -1
  74. package/dist/ui/components/MarkdownRenderer.js.map +1 -1
  75. package/dist/ui/components/MessageDisplay.js +9 -7
  76. package/dist/ui/components/MessageDisplay.js.map +1 -1
  77. package/dist/ui/components/ModelPicker.js +170 -0
  78. package/dist/ui/components/ModelPicker.js.map +1 -0
  79. package/dist/ui/components/MonitorModeAIPanel.js +3 -1
  80. package/dist/ui/components/MonitorModeAIPanel.js.map +1 -1
  81. package/dist/ui/components/PlanAcceptedMessage.js +12 -6
  82. package/dist/ui/components/PlanAcceptedMessage.js.map +1 -1
  83. package/dist/ui/components/PlanQuestionMessage.js +37 -0
  84. package/dist/ui/components/PlanQuestionMessage.js.map +1 -0
  85. package/dist/ui/components/PlanQuestionScreen.js +138 -0
  86. package/dist/ui/components/PlanQuestionScreen.js.map +1 -0
  87. package/dist/ui/components/PlanReviewScreen.js +7 -9
  88. package/dist/ui/components/PlanReviewScreen.js.map +1 -1
  89. package/dist/ui/components/RulesEditorScreen.js +65 -28
  90. package/dist/ui/components/RulesEditorScreen.js.map +1 -1
  91. package/dist/ui/components/SelectPrompt.js +3 -1
  92. package/dist/ui/components/SelectPrompt.js.map +1 -1
  93. package/dist/ui/components/SkillCreatorScreen.js +217 -0
  94. package/dist/ui/components/SkillCreatorScreen.js.map +1 -0
  95. package/dist/ui/components/SlashCommandAutocomplete.js +4 -2
  96. package/dist/ui/components/SlashCommandAutocomplete.js.map +1 -1
  97. package/dist/ui/components/StatusBar.js +4 -2
  98. package/dist/ui/components/StatusBar.js.map +1 -1
  99. package/dist/ui/components/StreamingMessageDisplay.js +5 -3
  100. package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
  101. package/dist/ui/components/SubAgentListScreen.js +65 -0
  102. package/dist/ui/components/SubAgentListScreen.js.map +1 -0
  103. package/dist/ui/components/SubAgentViewScreen.js +123 -0
  104. package/dist/ui/components/SubAgentViewScreen.js.map +1 -0
  105. package/dist/ui/components/TaskCompletedMessage.js +40 -8
  106. package/dist/ui/components/TaskCompletedMessage.js.map +1 -1
  107. package/dist/ui/components/TaskProgressIndicator.js +6 -4
  108. package/dist/ui/components/TaskProgressIndicator.js.map +1 -1
  109. package/dist/ui/components/TextEditor.js +297 -0
  110. package/dist/ui/components/TextEditor.js.map +1 -0
  111. package/dist/ui/components/TodoListMessage.js +59 -0
  112. package/dist/ui/components/TodoListMessage.js.map +1 -0
  113. package/dist/ui/components/ToolExecutionMessage.js +134 -84
  114. package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
  115. package/dist/ui/components/ToolExecutionStatus.js +3 -1
  116. package/dist/ui/components/ToolExecutionStatus.js.map +1 -1
  117. package/dist/ui/components/WelcomeBanner.js +33 -33
  118. package/dist/ui/components/WelcomeBanner.js.map +1 -1
  119. package/dist/ui/components/WorkflowCreatorScreen.js +5 -3
  120. package/dist/ui/components/WorkflowCreatorScreen.js.map +1 -1
  121. package/dist/ui/theme.js +97 -0
  122. package/dist/ui/theme.js.map +1 -0
  123. package/dist/ui/utils/chat-history-limit.js +247 -0
  124. package/dist/ui/utils/chat-history-limit.js.map +1 -0
  125. package/dist/utils/chat-formatter.js +22 -9
  126. package/dist/utils/chat-formatter.js.map +1 -1
  127. package/dist/utils/input-classifier.js +11 -1
  128. package/dist/utils/input-classifier.js.map +1 -1
  129. package/dist/utils/output-truncation.js +175 -0
  130. package/dist/utils/output-truncation.js.map +1 -0
  131. package/dist/utils/rule-reference-resolver.js +3 -3
  132. package/dist/utils/rule-reference-resolver.js.map +1 -1
  133. package/dist/utils/tunnel-commands-manager.js +134 -0
  134. package/dist/utils/tunnel-commands-manager.js.map +1 -0
  135. package/package.json +91 -90
  136. package/postinstall.js +4 -11
  137. package/dist/ui/components/MultiLineInput.js +0 -255
  138. package/dist/ui/components/MultiLineInput.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/ui/components/ToolExecutionMessage.tsx"],"sourcesContent":["import React from 'react';\r\nimport { Box, Text } from 'ink';\r\nimport Spinner from 'ink-spinner';\r\nimport stripAnsi from 'strip-ansi';\r\nimport wrapAnsi from 'wrap-ansi';\r\nimport stringWidth from 'string-width';\r\nimport * as path from 'path';\r\nimport { Message } from '../../types/index.js';\r\nimport { processTerminalOutput } from '../../utils/terminal-output.js';\r\n\r\ninterface ToolExecutionMessageProps {\r\n message: Message;\r\n}\r\n\r\nconst TOOL_LABELS: Record<string, { verb: string; emoji: string }> = {\r\n view_file: { verb: 'Reading file', emoji: '📖' },\r\n write_to_file: { verb: 'Writing file', emoji: '' },\r\n edit_file: { verb: 'Editing file', emoji: '' },\r\n multi_edit_file: { verb: 'Editing file', emoji: '' },\r\n list_dir: { verb: 'Listing directory', emoji: '📁' },\r\n execute_command: { verb: 'Executing command', emoji: '⚡' },\r\n grep_search: { verb: 'Searching files', emoji: '🔍' },\r\n find_files: { verb: 'Finding files', emoji: '🔎' },\r\n web_search: { verb: 'Searching web', emoji: '🌐' },\r\n fetch_url: { verb: 'Fetching URL', emoji: '📡' },\r\n inspect_symbol: { verb: 'Inspecting symbol', emoji: '🔬' },\r\n read_binary_file: { verb: 'Reading binary file', emoji: '📄' },\r\n create_image: { verb: 'Generating image', emoji: '🎨' },\r\n background_command: { verb: 'Background command', emoji: '🔄' },\r\n get_diff: { verb: 'Getting diff', emoji: '📝' },\r\n sub_agent: { verb: 'Agent Task', emoji: '🤖' },\r\n fast_context_search: { verb: 'Searching context', emoji: '⚡' },\r\n auto_context_compaction: { verb: 'Auto compacting context', emoji: '[AUTO]' },\r\n add_mcp: { verb: 'Adding MCP server', emoji: '🔌' },\r\n};\r\n\r\n/**\r\n * Convert an absolute path to a relative path from the current working directory.\r\n * If the path is outside the CWD, returns the full path.\r\n * Always uses forward slashes for consistency.\r\n */\r\nfunction toRelativePath(absolutePath: string | undefined): string {\r\n if (!absolutePath) return '';\r\n try {\r\n const cwd = process.cwd();\r\n // Normalize paths for comparison (handle different path separators)\r\n const normalizedAbsolute = path.normalize(absolutePath);\r\n const normalizedCwd = path.normalize(cwd);\r\n\r\n // Check if the path starts with the CWD\r\n if (normalizedAbsolute.toLowerCase().startsWith(normalizedCwd.toLowerCase())) {\r\n let relativePath = path.relative(cwd, absolutePath);\r\n // If empty (same directory), show './'\r\n if (!relativePath) relativePath = '.';\r\n // Convert backslashes to forward slashes for consistent display\r\n return relativePath.replace(/\\\\/g, '/');\r\n }\r\n // Path is outside CWD, return as-is but with forward slashes\r\n return absolutePath.replace(/\\\\/g, '/');\r\n } catch {\r\n return absolutePath;\r\n }\r\n}\r\n\r\n/**\r\n * Format a path with remote context prefix for SSH/Docker/WSL environments.\r\n * In local mode, returns just the path.\r\n * In remote mode, returns \"user@host:/path\" format.\r\n */\r\nfunction formatPathWithContext(absolutePath: string | undefined, remoteContext?: string): string {\r\n const pathStr = toRelativePath(absolutePath);\r\n if (remoteContext && absolutePath) {\r\n // For remote environments, show full path with remote prefix\r\n // Use the absolute path to make it clear this is a remote file\r\n return `${remoteContext}:${absolutePath.replace(/\\\\/g, '/')}`;\r\n }\r\n return pathStr;\r\n}\r\n\r\n/**\r\n * Clean shell output for display in history\r\n */\r\nfunction cleanShellOutput(result: string | undefined): string {\r\n if (!result) return '';\r\n return processTerminalOutput(result);\r\n}\r\n\r\n/**\r\n * Truncate long commands for display to prevent rendering issues\r\n * @param command - The command string to truncate\r\n * @param maxLength - Maximum length before truncation (default: 80)\r\n * @returns Truncated command with ellipsis if needed\r\n */\r\nfunction truncateCommand(command: string, maxLength: number = 80): string {\r\n if (!command || command.length <= maxLength) return command;\r\n return command.substring(0, maxLength) + '...';\r\n}\r\n\r\n/**\r\n * Parse grep_search result to get match count\r\n * Format: \"Found X matches in Y files for pattern...\" or \"Found X matches for pattern...\"\r\n * Match lines are identified by the \":>\" marker\r\n */\r\nfunction parseGrepSearchResult(result: string | undefined): { matches: number; files: number } | null {\r\n if (!result) return null;\r\n\r\n // Handle \"No matches found\" case\r\n if (result.includes('No matches found')) {\r\n return { matches: 0, files: 0 };\r\n }\r\n\r\n // Try to parse \"Found X matches in Y files for pattern...\" format (preferred)\r\n const fullMatch = result.match(/Found (\\d+) match(?:es)? in (\\d+) file/);\r\n if (fullMatch) {\r\n return { matches: parseInt(fullMatch[1], 10), files: parseInt(fullMatch[2], 10) };\r\n }\r\n\r\n // Try to parse \"Found X matches for pattern...\" format (older format without file count)\r\n const matchCountOnly = result.match(/Found (\\d+) match(?:es)?/);\r\n if (matchCountOnly) {\r\n const matchCount = parseInt(matchCountOnly[1], 10);\r\n // Count unique files from the output - files appear as standalone paths before their matches\r\n // File paths are lines that don't start with a number and don't contain \":>\"\r\n const lines = result.split('\\n');\r\n const uniqueFiles = new Set<string>();\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n // Skip header lines and empty lines\r\n if (!trimmed || trimmed.startsWith('Found ') || trimmed.startsWith('(')) continue;\r\n // Match lines have \":>\" in them, skip those\r\n if (trimmed.includes(':>')) continue;\r\n // Context lines start with \"number: \" (note the space after colon)\r\n if (/^\\d+:\\s{3}/.test(trimmed)) continue;\r\n // Remaining lines that don't start with a number are file paths\r\n if (!/^\\d+:/.test(trimmed)) {\r\n uniqueFiles.add(trimmed);\r\n }\r\n }\r\n return { matches: matchCount, files: uniqueFiles.size };\r\n }\r\n\r\n // Final fallback: count actual match lines (identified by \":>\" marker)\r\n const lines = result.split('\\n');\r\n const matchLines = lines.filter(line => line.includes(':>'));\r\n if (matchLines.length > 0) {\r\n // Count unique files from file header lines\r\n const uniqueFiles = new Set<string>();\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith('Found ') || trimmed.startsWith('(')) continue;\r\n if (trimmed.includes(':>') || /^\\d+:/.test(trimmed)) continue;\r\n uniqueFiles.add(trimmed);\r\n }\r\n return { matches: matchLines.length, files: uniqueFiles.size };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n\r\n/**\r\n * Parse find_files result to get file count\r\n * Format: one file path per line, or \"Found X files\"\r\n */\r\nfunction parseFindFilesResult(result: string | undefined): number | null {\r\n if (!result) return null;\r\n\r\n // Check for \"No files found\" message\r\n if (result.includes('No files found') || result.includes('No matches found')) {\r\n return 0;\r\n }\r\n\r\n // Try to parse \"Found X files\" format\r\n const summaryMatch = result.match(/Found (\\d+) file/);\r\n if (summaryMatch) {\r\n return parseInt(summaryMatch[1], 10);\r\n }\r\n\r\n // Try to parse \"Total: X\" format\r\n const totalMatch = result.match(/Total:\\s*(\\d+)/);\r\n if (totalMatch) {\r\n return parseInt(totalMatch[1], 10);\r\n }\r\n\r\n // Count lines (each line is a file path)\r\n const lines = result.split('\\n').filter(line => line.trim() && !line.startsWith('Searching'));\r\n return lines.length > 0 ? lines.length : null;\r\n}\r\n\r\n/**\r\n * Coerce line number inputs from tool args into positive integers.\r\n */\r\nfunction toPositiveLineNumber(value: unknown): number | null {\r\n if (typeof value === 'number' && Number.isFinite(value) && value > 0) {\r\n return Math.floor(value);\r\n }\r\n if (typeof value === 'string' && value.trim()) {\r\n const parsed = parseInt(value, 10);\r\n if (Number.isFinite(parsed) && parsed > 0) {\r\n return parsed;\r\n }\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse view_file result metadata.\r\n * Expected format includes:\r\n * - \"Lines: N\"\r\n * - Optional truncation marker \"(Truncated)\"\r\n * - Optional detail \"Showing first M lines only.\"\r\n */\r\nfunction parseViewFileResult(result: string | undefined): { displayedLines: number | null; totalLines: number | null; truncated: boolean } | null {\r\n if (!result) return null;\r\n\r\n const totalMatch = result.match(/^\\s*Lines:\\s*(\\d+)/im);\r\n const totalLines = totalMatch ? parseInt(totalMatch[1], 10) : null;\r\n\r\n const shownMatch = result.match(/Showing first (\\d+) lines only/i);\r\n const shownLines = shownMatch ? parseInt(shownMatch[1], 10) : null;\r\n\r\n const truncated = /\\(Truncated\\)/i.test(result) || /File truncated/i.test(result) || shownLines !== null;\r\n const displayedLines = truncated ? shownLines : totalLines;\r\n\r\n if (displayedLines === null && totalLines === null) {\r\n return null;\r\n }\r\n\r\n return { displayedLines, totalLines, truncated };\r\n}\r\n\r\n/**\r\n * Build user-facing line range text for view_file UI state.\r\n * Always favors concrete numeric ranges instead of \"entire file\".\r\n */\r\nfunction getViewFileLineInfo(toolArgs?: Record<string, any>, result?: string): string {\r\n const startLine = toPositiveLineNumber(toolArgs?.StartLine ?? toolArgs?.start_line) ?? 1;\r\n const endLineArg = toPositiveLineNumber(toolArgs?.EndLine ?? toolArgs?.end_line);\r\n\r\n const parsedResult = parseViewFileResult(result);\r\n if (parsedResult?.displayedLines != null) {\r\n const endLine = parsedResult.displayedLines > 0\r\n ? startLine + parsedResult.displayedLines - 1\r\n : startLine;\r\n const lineRange = `lines ${startLine}-${endLine}`;\r\n\r\n if (\r\n parsedResult.truncated &&\r\n parsedResult.totalLines !== null &&\r\n parsedResult.totalLines > parsedResult.displayedLines\r\n ) {\r\n return `${lineRange} (of ${parsedResult.totalLines})`;\r\n }\r\n\r\n return lineRange;\r\n }\r\n\r\n if (endLineArg !== null) {\r\n return `lines ${startLine}-${endLineArg}`;\r\n }\r\n\r\n return 'lines 1-500';\r\n}\r\n\r\n/**\r\n * Parse list_dir result to get item count\r\n * New format: \"Total: X directories, Y files, Z items\"\r\n * Old format: \"Directory: path\\nTotal items: X\\n...\"\r\n */\r\nfunction parseListDirResult(result: string | undefined): { dirs: number; files: number; total: number } | null {\r\n if (!result) return null;\r\n\r\n // Try to parse new enhanced format: \"Total: X directories, Y files, Z items\"\r\n const newFormatMatch = result.match(/Total:\\s*(\\d+)\\s*director(?:y|ies),?\\s*(\\d+)\\s*files?,?\\s*(\\d+)\\s*items?/i);\r\n if (newFormatMatch) {\r\n return {\r\n dirs: parseInt(newFormatMatch[1], 10),\r\n files: parseInt(newFormatMatch[2], 10),\r\n total: parseInt(newFormatMatch[3], 10)\r\n };\r\n }\r\n\r\n // Try to parse old format: \"Total items: X\"\r\n const oldFormatMatch = result.match(/Total items:\\s*(\\d+)/);\r\n if (oldFormatMatch) {\r\n const total = parseInt(oldFormatMatch[1], 10);\r\n return { dirs: 0, files: 0, total };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse inspect_symbol result to check if symbols were found\r\n */\r\nfunction parseInspectSymbolResult(result: string | undefined): { found: boolean; count: number } {\r\n if (!result) return { found: false, count: 0 };\r\n\r\n // Check for \"No symbols found\" message\r\n if (result.includes('No symbols found')) {\r\n return { found: false, count: 0 };\r\n }\r\n\r\n // Count symbol definitions (rough estimate based on common patterns)\r\n const symbolMatches = result.match(/(?:function|class|interface|type|const|let|var|def|struct)\\s+\\w+/g);\r\n return { found: true, count: symbolMatches ? symbolMatches.length : 1 };\r\n}\r\n\r\n/**\r\n * Parse fast_context_search result to get stats and markdown answer\r\n */\r\nfunction parseFastContextResult(result: string | undefined): { answer: string; stats?: { filesSearched: number; duration: number; scannedFiles: string[] } } {\r\n if (!result) return { answer: '' };\r\n\r\n try {\r\n // Try to parse as JSON first (new format)\r\n if (result.trim().startsWith('{')) {\r\n const parsed = JSON.parse(result);\r\n if (parsed.answer && parsed.stats) {\r\n return parsed;\r\n }\r\n }\r\n } catch (e) {\r\n // Fallback to raw string\r\n }\r\n\r\n return { answer: result };\r\n}\r\n\r\n/**\r\n * Parse MCP tool name to extract server name and tool name\r\n * MCP tools are named: mcp_{serverName}_{toolName}\r\n */\r\nfunction parseMCPToolName(toolName: string): { serverName: string; mcpToolName: string } | null {\r\n if (!toolName.startsWith('mcp_')) return null;\r\n\r\n // Remove 'mcp_' prefix and split by first underscore\r\n const withoutPrefix = toolName.slice(4); // Remove 'mcp_'\r\n const firstUnderscoreIdx = withoutPrefix.indexOf('_');\r\n\r\n if (firstUnderscoreIdx === -1) {\r\n return { serverName: withoutPrefix, mcpToolName: 'unknown' };\r\n }\r\n\r\n const serverName = withoutPrefix.slice(0, firstUnderscoreIdx);\r\n const mcpToolName = withoutPrefix.slice(firstUnderscoreIdx + 1);\r\n\r\n return { serverName, mcpToolName };\r\n}\r\n\r\n/**\r\n * Get display info for a tool, with special handling for MCP tools\r\n */\r\nfunction getToolDisplayInfo(toolName: string): { verb: string; emoji: string; isMCP: boolean; serverName?: string; mcpToolName?: string } {\r\n // Check if it's an MCP tool\r\n const mcpInfo = parseMCPToolName(toolName);\r\n if (mcpInfo) {\r\n return {\r\n verb: `MCP ${mcpInfo.serverName} ${mcpInfo.mcpToolName}`,\r\n emoji: '⚡',\r\n isMCP: true,\r\n serverName: mcpInfo.serverName,\r\n mcpToolName: mcpInfo.mcpToolName\r\n };\r\n }\r\n\r\n // Regular tool\r\n const toolInfo = TOOL_LABELS[toolName] || { verb: 'Executing', emoji: '🔧' };\r\n return { ...toolInfo, isMCP: false };\r\n}\r\n\r\n/**\r\n * Render a snippet of the diff (added/removed lines)\r\n */\r\nfunction renderDiffSnippet(removedContent: string | undefined, addedContent: string | undefined, options: { compact?: boolean } = {}): React.ReactNode {\r\n const { compact } = options;\r\n if (!removedContent && !addedContent) return null;\r\n\r\n const removedLines = removedContent ? removedContent.split('\\n') : [];\r\n const addedLines = addedContent ? addedContent.split('\\n') : [];\r\n\r\n if (removedLines.length === 0 && addedLines.length === 0) return null;\r\n\r\n const terminalWidth = process.stdout.columns || 80;\r\n // Keep line width conservative so wrapped content always stays inside the parent bordered box.\r\n const maxPreviewWidth = Math.max(12, terminalWidth - 16);\r\n const measuredLineWidths: number[] = [];\r\n\r\n const wrapDiffLine = (prefix: string, line: string): string[] => {\r\n const continuationPrefix = ' '.repeat(prefix.length);\r\n const wrapped = wrapAnsi(line.length > 0 ? line : ' ', Math.max(1, maxPreviewWidth - prefix.length), {\r\n hard: true,\r\n trim: false\r\n }).split('\\n');\r\n\r\n return wrapped.map((segment, idx) => {\r\n const rendered = `${idx === 0 ? prefix : continuationPrefix}${segment.length > 0 ? segment : ' '}`;\r\n measuredLineWidths.push(stringWidth(rendered));\r\n return rendered;\r\n });\r\n };\r\n\r\n const items: React.ReactNode[] = [];\r\n const previewLimit = 3;\r\n\r\n // Show first previewLimit removed lines with hard wrapping\r\n removedLines.slice(0, previewLimit).forEach((line, i) => {\r\n wrapDiffLine('- ', line).forEach((wrappedLine, wrappedIndex) => {\r\n items.push(\r\n <Box key={`rem-${i}-${wrappedIndex}`}>\r\n <Text color=\"#e6e6e6\" backgroundColor=\"#5c1e1e\" wrap=\"truncate-end\">\r\n {wrappedLine}\r\n </Text>\r\n </Box>\r\n );\r\n });\r\n });\r\n if (removedLines.length > previewLimit) {\r\n items.push(\r\n <Box key=\"rem-more\">\r\n <Text color=\"gray\" dimColor> ... {removedLines.length - previewLimit} more lines</Text>\r\n </Box>\r\n );\r\n }\r\n\r\n // Show first previewLimit added lines with hard wrapping\r\n addedLines.slice(0, previewLimit).forEach((line, i) => {\r\n wrapDiffLine('+ ', line).forEach((wrappedLine, wrappedIndex) => {\r\n items.push(\r\n <Box key={`add-${i}-${wrappedIndex}`}>\r\n <Text color=\"#e6e6e6\" backgroundColor=\"#1e4d2b\" wrap=\"truncate-end\">\r\n {wrappedLine}\r\n </Text>\r\n </Box>\r\n );\r\n });\r\n });\r\n if (addedLines.length > previewLimit) {\r\n items.push(\r\n <Box key=\"add-more\">\r\n <Text color=\"gray\" dimColor> ... {addedLines.length - previewLimit} more lines</Text>\r\n </Box>\r\n );\r\n }\r\n\r\n const separatorWidth = Math.max(\r\n 8,\r\n Math.min(\r\n maxPreviewWidth,\r\n measuredLineWidths.length > 0 ? Math.max(...measuredLineWidths) : 8\r\n )\r\n );\r\n\r\n return (\r\n <Box flexDirection=\"column\" marginTop={compact ? 0 : 1} alignSelf=\"flex-start\">\r\n <Box marginBottom={1}>\r\n <Text color=\"#333333\">{'─'.repeat(separatorWidth)}</Text>\r\n </Box>\r\n {items}\r\n </Box>\r\n );\r\n}\r\n\r\nexport const ToolExecutionMessage: React.FC<ToolExecutionMessageProps> = React.memo(({ message }) => {\r\n if (!message.toolExecution) {\r\n return null;\r\n }\r\n\r\n const { toolName, status, result, error, arguments: toolArgs } = message.toolExecution;\r\n const toolInfo = getToolDisplayInfo(toolName);\r\n\r\n // Display thinking duration if available (carried from thought-only message)\r\n const thinkingDuration = message.thinkingDuration;\r\n\r\n // Helper to wrap content with thinking duration display\r\n const renderWithThinking = (content: React.ReactNode) => (\r\n <Box flexDirection=\"column\">\r\n {thinkingDuration !== undefined && thinkingDuration >= 0 && (\r\n <Box marginBottom={1}>\r\n <Text dimColor>Thought for {thinkingDuration} second{thinkingDuration !== 1 ? 's' : ''} ›</Text>\r\n </Box>\r\n )}\r\n {content}\r\n </Box>\r\n );\r\n\r\n // EXECUTING state\r\n if (status === 'executing') {\r\n // Skip execute_command - it's handled by InteractiveShell component\r\n if (toolName === 'execute_command') {\r\n return null;\r\n }\r\n\r\n // Note: web_search, grep_search, find_files now have custom executing states below\r\n\r\n // Skip plan-mode tools - they have their own UI components (TaskCompletedMessage, PlanReviewScreen)\r\n if (toolName === 'mark_task_complete' || toolName === 'create_plan') {\r\n return null;\r\n }\r\n\r\n\r\n if (toolName === 'auto_context_compaction') {\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> Auto summarizing context...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n // MCP tools - show executing state with simple format (no border to avoid emoji width issues)\r\n if (toolInfo.isMCP) {\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#9945FF\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> MCP</Text>\r\n <Text color=\"#9945FF\"> {toolInfo.serverName} {toolInfo.mcpToolName}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // VIEW_FILE\r\n if (toolName === 'view_file' && toolArgs) {\r\n const { AbsolutePath, remoteContext } = toolArgs;\r\n const lineInfo = getViewFileLineInfo(toolArgs);\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> Reading {lineInfo} from </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(AbsolutePath, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // LIST_DIR\r\n if (toolName === 'list_dir' && toolArgs) {\r\n const { DirectoryPath, remoteContext } = toolArgs;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> Listing </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(DirectoryPath, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // GREP_SEARCH\r\n if (toolName === 'grep_search' && toolArgs) {\r\n const { Query, SearchPath } = toolArgs;\r\n const searchPathRelative = toRelativePath(SearchPath);\r\n // Determine if it's a file or directory (heuristic: check for common file extensions)\r\n const hasExtension = /\\.[a-zA-Z0-9]{1,10}$/.test(SearchPath || '');\r\n const pathType = hasExtension ? 'file' : 'directory';\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> Searching for </Text>\r\n <Text color=\"#00ccff\">\"{Query}\"</Text>\r\n {searchPathRelative && (\r\n <Text color=\"#00ccff\"> in <Text color=\"#00ccff\" bold>{searchPathRelative}</Text> {pathType}...</Text>\r\n )}\r\n {!searchPathRelative && <Text color=\"#00ccff\">...</Text>}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // FIND_FILES\r\n if (toolName === 'find_files' && toolArgs) {\r\n const { pattern } = toolArgs;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> Finding files matching </Text>\r\n <Text color=\"#00ccff\">\"{pattern}\"...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // FETCH_URL\r\n if (toolName === 'fetch_url' && toolArgs) {\r\n const { url } = toolArgs;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> Fetching </Text>\r\n <Text color=\"#00ccff\">{url}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // READ_BINARY_FILE\r\n if (toolName === 'read_binary_file' && toolArgs) {\r\n const { file_path, remoteContext } = toolArgs;\r\n const fileName = file_path ? path.basename(file_path) : 'file';\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff9900\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#ff9900\" bold> Reading </Text>\r\n <Text color=\"#ff9900\">{formatPathWithContext(file_path, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // WRITE_TO_FILE\r\n if (toolName === 'write_to_file' && toolArgs) {\r\n const { TargetFile, remoteContext } = toolArgs;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> Writing to </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(TargetFile, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // EDIT_FILE\r\n if (toolName === 'edit_file' && toolArgs) {\r\n const { file_path, remoteContext } = toolArgs;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> Editing </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(file_path, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // MULTI_EDIT_FILE\r\n if (toolName === 'multi_edit_file' && toolArgs) {\r\n const { file_path, remoteContext } = toolArgs;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> Editing </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(file_path, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // CREATE_IMAGE\r\n if (toolName === 'create_image') {\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff9900\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#ff9900\" bold> Generating image...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // BACKGROUND_COMMAND - show action-specific message\r\n if (toolName === 'background_command' && toolArgs) {\r\n const { action, command, task_id, wait_seconds } = toolArgs;\r\n let actionText = 'Running background task...';\r\n if (action === 'start') {\r\n actionText = `Starting: ${command || 'command'}...`;\r\n } else if (action === 'status') {\r\n actionText = `Checking status: ${task_id || 'task'}...`;\r\n } else if (action === 'kill') {\r\n actionText = `Killing task: ${task_id || 'task'}...`;\r\n } else if (action === 'wait') {\r\n actionText = `Waiting for ${wait_seconds || '?'} second${wait_seconds !== 1 ? 's' : ''}...`;\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff9900\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#ff9900\" bold> {toolInfo.emoji} {actionText}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // GET_DIFF\r\n if (toolName === 'get_diff' && toolArgs) {\r\n const { filePath, staged, reason_text } = toolArgs;\r\n const diffTarget = filePath ? `for ${filePath}` : 'for all files';\r\n const stagedText = staged ? ' (staged)' : '';\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> {toolInfo.emoji} Getting diff {diffTarget}{stagedText}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // WEB_SEARCH\r\n if (toolName === 'web_search' && toolArgs) {\r\n const { query } = toolArgs;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> {toolInfo.emoji} Searching the web for </Text>\r\n <Text color=\"#00ccff\">\"{query}\"...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // FAST_CONTEXT_SEARCH\r\n if (toolName === 'fast_context_search' && toolArgs) {\r\n const { query } = toolArgs;\r\n\r\n let scannedFiles: string[] = [];\r\n try {\r\n const streamData = message.toolExecution?.streamingOutput || result;\r\n if (streamData) {\r\n const lines = streamData.trim().split('\\n').filter(Boolean);\r\n if (lines.length > 0) {\r\n // Find the last valid JSON line by iterating backwards\r\n // The FastContextAgent outputs JSON blobs on stdout for UI updates\r\n for (let i = lines.length - 1; i >= 0; i--) {\r\n try {\r\n // The stream mixes logs and JSON. Fast context prints files inside JSON objects.\r\n const line = lines[i].trim();\r\n if (line.startsWith('{')) {\r\n const parsed = JSON.parse(line);\r\n if (parsed.type === 'scanned_files' && parsed.files) {\r\n scannedFiles = parsed.files;\r\n break; // Found the most recent valid state\r\n }\r\n }\r\n } catch (e) {\r\n // Ignore parsing errors for incomplete streamed lines\r\n }\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n // ignore parsing errors\r\n }\r\n\r\n // Format query for executing state\r\n const truncatedQuery = query && query.length > 50 ? query.substring(0, 47) + '...' : query || '';\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00cc66\" bold> Rapid Context </Text>\r\n <Text color=\"#cccccc\"> \"{truncatedQuery}\"</Text>\r\n </Box>\r\n {scannedFiles.length > 0 && (\r\n <Box flexDirection=\"column\" marginLeft={2} marginTop={1}>\r\n {scannedFiles.map((f, i) => (\r\n <Text key={i} color=\"#666666\" wrap=\"truncate-end\">\r\n - {toRelativePath(f)}\r\n </Text>\r\n ))}\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // INSPECT_SYMBOL\r\n if (toolName === 'inspect_symbol' && toolArgs) {\r\n const { filePath, symbols, remoteContext } = toolArgs;\r\n const symbolList = Array.isArray(symbols) ? symbols.join(', ') : symbols || 'symbols';\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> {toolInfo.emoji} Inspecting </Text>\r\n <Text color=\"#00ccff\">{symbolList} in {formatPathWithContext(filePath, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // SUB_AGENT - executing\r\n if (toolName === 'sub_agent' && toolArgs) {\r\n const action = (toolArgs as any).action;\r\n\r\n if (action === 'spawn') {\r\n const prompt = (toolArgs as any).prompt || (toolArgs as any).task || 'Unknown task';\r\n const complexity = (toolArgs as any).complexity || 3;\r\n const modelName = complexity > 5 ? 'Gemini 3.1 Pro Preview' : 'Gemini 3 Flash Preview';\r\n\r\n // Limit prompt display to 4 lines\r\n const promptLines = prompt.split('\\n');\r\n const maxLines = 4;\r\n const displayLines = promptLines.slice(0, maxLines);\r\n const remainingLines = promptLines.length - maxLines;\r\n const truncatedPrompt = displayLines.join('\\n');\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> {toolInfo.emoji} Spawning Sub-Agent </Text>\r\n <Text color=\"#666666\" dimColor>({modelName})</Text>\r\n </Box>\r\n <Box marginLeft={2} flexDirection=\"column\">\r\n <Text color=\"#00ccff\">{truncatedPrompt}</Text>\r\n {remainingLines > 0 && (\r\n <Text color=\"#666666\" dimColor>... {remainingLines} more lines</Text>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n } else if (action === 'wait_for_status' || action === 'status') {\r\n const delay = (toolArgs as any).time_delay || 0;\r\n const agentId = (toolArgs as any).agent_id || 'unknown';\r\n const waitMessage = delay > 0 ? `Waiting for ${delay} seconds...` : 'Checking status...';\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> {toolInfo.emoji} Sub Agent Status </Text>\r\n <Text color=\"#666666\" dimColor>(id: {agentId})</Text>\r\n </Box>\r\n <Box marginLeft={2}>\r\n <Text color=\"#00ccff\">{waitMessage}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> {toolInfo.emoji} Sub Agent </Text>\r\n <Text color=\"#666666\" dimColor>({action})</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // WORKFLOW - show action-specific message\r\n if (toolName === 'workflow' && toolArgs) {\r\n const action = toolArgs.action;\r\n const stepNumber = toolArgs.step_number;\r\n const exitType = toolArgs.exit_type;\r\n const reason = toolArgs.reason;\r\n\r\n let actionText = 'Workflow action...';\r\n let borderColor = '#00ccff';\r\n let textColor = '#00ccff';\r\n\r\n if (action === 'step_complete') {\r\n actionText = `Completing Step ${stepNumber || '?'}...`;\r\n borderColor = '#00cc66';\r\n textColor = '#00cc66';\r\n } else if (action === 'exit') {\r\n if (exitType === 'error') {\r\n actionText = `Workflow Failed${reason ? `: ${reason.slice(0, 50)}` : ''}`;\r\n borderColor = '#ff3366';\r\n textColor = '#ff3366';\r\n } else if (exitType === 'cancelled') {\r\n actionText = 'Workflow Cancelled';\r\n borderColor = '#ff9900';\r\n textColor = '#ff9900';\r\n } else {\r\n actionText = 'Workflow Completed';\r\n borderColor = '#00cc66';\r\n textColor = '#00cc66';\r\n }\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={borderColor} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color={textColor} bold> 🔄 {actionText}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // ADD_MCP - show server name and command being connected\r\n if (toolName === 'add_mcp' && toolArgs) {\r\n const serverName = toolArgs.name || 'unknown';\r\n const command = toolArgs.command || '';\r\n const serverArgs = Array.isArray(toolArgs.args) ? toolArgs.args.join(' ') : '';\r\n const fullCommand = serverArgs ? `${command} ${serverArgs}` : command;\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#9945FF\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#9945FF\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> 🔌 Adding MCP server </Text>\r\n <Text color=\"#cc99ff\" bold>{serverName}</Text>\r\n </Box>\r\n {fullCommand && (\r\n <Box>\r\n <Text color=\"#666666\" dimColor> {fullCommand}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#003b59\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00ccff\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00ccff\" bold> {toolInfo.verb}...</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // ERROR state\r\n if (status === 'error') {\r\n // EXECUTE_COMMAND - render as static shell box with error\r\n if (toolName === 'execute_command' && toolArgs) {\r\n const command = toolArgs.command || toolArgs.CommandLine || toolArgs.commandLine || '';\r\n const truncatedCommand = truncateCommand(command, 80);\r\n const { cwd, remoteContext } = toolArgs;\r\n const cleanResult = cleanShellOutput(result);\r\n // For CWD display, use absolute path directly (don't convert to relative)\r\n const formattedCwd = cwd && remoteContext\r\n ? `${remoteContext}:${cwd.replace(/\\\\/g, '/')}`\r\n : (cwd || '').replace(/\\\\/g, '/');\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff3366\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box marginBottom={1}>\r\n <Text>\r\n <Text color=\"#ff3366\" bold>✗ Shell </Text>\r\n <Text color=\"#666666\">{truncatedCommand} </Text>\r\n {cwd && <Text color=\"#666666\" dimColor>[current working directory {formattedCwd}]</Text>}\r\n </Text>\r\n </Box>\r\n {cleanResult && (\r\n <Box>\r\n <Text wrap=\"wrap\">{cleanResult}</Text>\r\n </Box>\r\n )}\r\n {/* Don't show error separately - it's already in the output */}\r\n </Box >\r\n );\r\n }\r\n\r\n return (\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff3366\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#ff3366\" bold>✗ {toolInfo.emoji} {toolInfo.verb} failed</Text>\r\n </Box>\r\n <Box paddingLeft={1} marginTop={1}>\r\n <Text color=\"#ff3366\">{error || 'The Agent passed invalid parameters'}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // COMPLETED state - tool-specific rendering\r\n if (status === 'completed') {\r\n // MCP tools - show only success indicator, hide output (output goes to AI only)\r\n if (toolInfo.isMCP) {\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ MCP</Text>\r\n <Text color=\"#aaaaaa\"> {toolInfo.serverName} {toolInfo.mcpToolName}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // Skip plan-mode tools - they have their own UI components (TaskCompletedMessage, PlanReviewScreen)\r\n if (toolName === 'mark_task_complete' || toolName === 'create_plan') {\r\n return null;\r\n }\r\n\r\n\r\n if (toolName === 'auto_context_compaction') {\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>Auto compacted context</Text>\r\n </Box>\r\n {result && (\r\n <Box paddingLeft={1} marginTop={1}>\r\n <Text color=\"#aaaaaa\">{result}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n // EXECUTE_COMMAND - render as static shell box\r\n if (toolName === 'execute_command' && toolArgs) {\r\n // Hide shell_input actions from history as per user request\r\n // These are just input submissions (like \"1\\n\") and the result is just confirmation text\r\n // The actual side effects are seen in the persistent shell, so showing this block is redundant clutter\r\n if (toolArgs.shell_input) {\r\n return null;\r\n }\r\n\r\n const command = toolArgs.command || toolArgs.CommandLine || toolArgs.commandLine || '';\r\n const truncatedCommand = truncateCommand(command, 80);\r\n const { cwd, remoteContext } = toolArgs;\r\n const cleanResult = cleanShellOutput(result);\r\n // For CWD display, use absolute path directly (don't convert to relative)\r\n const formattedCwd = cwd && remoteContext\r\n ? `${remoteContext}:${cwd.replace(/\\\\/g, '/')}`\r\n : (cwd || '').replace(/\\\\/g, '/');\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box marginBottom={1}>\r\n <Text>\r\n <Text color=\"#00cc66\" bold>✓ Shell </Text>\r\n <Text color=\"#666666\">{truncatedCommand} </Text>\r\n {cwd && <Text color=\"#666666\" dimColor>[current working directory {formattedCwd}]</Text>}\r\n </Text>\r\n </Box>\r\n {cleanResult && (\r\n <Box>\r\n <Text wrap=\"wrap\">{cleanResult}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // VIEW_FILE\r\n if (toolName === 'view_file' && toolArgs) {\r\n const { AbsolutePath, remoteContext } = toolArgs;\r\n const lineInfo = getViewFileLineInfo(toolArgs, result);\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Read {lineInfo} from </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(AbsolutePath, remoteContext)}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // WRITE_TO_FILE\r\n if (toolName === 'write_to_file' && toolArgs) {\r\n const { TargetFile, CodeContent, remoteContext } = toolArgs;\r\n const lines = CodeContent ? CodeContent.split('\\n').length : 0;\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Wrote to </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(TargetFile, remoteContext)}</Text>\r\n {lines > 0 && <Text color=\"green\"> +{lines}</Text>}\r\n </Box>\r\n {renderDiffSnippet(undefined, CodeContent)}\r\n </Box>\r\n );\r\n }\r\n\r\n // EDIT_FILE\r\n if (toolName === 'edit_file' && toolArgs) {\r\n const { file_path, remoteContext, replacement, search_pattern } = toolArgs;\r\n const added = replacement ? replacement.split('\\n').length : 0;\r\n const removed = search_pattern ? search_pattern.split('\\n').length : 0;\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Edited </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(file_path, remoteContext)}</Text>\r\n <Text color=\"green\"> +{added}</Text>\r\n <Text color=\"red\"> -{removed}</Text>\r\n </Box>\r\n {renderDiffSnippet(search_pattern, replacement)}\r\n </Box>\r\n );\r\n }\r\n\r\n // MULTI_EDIT_FILE\r\n if (toolName === 'multi_edit_file' && toolArgs) {\r\n const { file_path, edits, remoteContext } = toolArgs;\r\n const editList = Array.isArray(edits) ? edits : [];\r\n\r\n let added = 0;\r\n let removed = 0;\r\n\r\n editList.forEach((edit: any) => {\r\n if (edit.replacement || edit.ReplacementContent) {\r\n added += (edit.replacement || edit.ReplacementContent).split('\\n').length;\r\n }\r\n if (edit.search_pattern || edit.TargetContent) {\r\n removed += (edit.search_pattern || edit.TargetContent).split('\\n').length;\r\n }\r\n });\r\n\r\n // For multi-edit, we show the snippet of the FIRST edit as a sample, or maybe we aggregate?\r\n // Lets show the first edit's snippet if available\r\n const firstEdit = editList[0];\r\n const searchExample = firstEdit ? (firstEdit.search_pattern || firstEdit.TargetContent) : undefined;\r\n const replaceExample = firstEdit ? (firstEdit.replacement || firstEdit.ReplacementContent) : undefined;\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Edited </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(file_path, remoteContext)}</Text>\r\n <Text color=\"green\"> +{added}</Text>\r\n <Text color=\"red\"> -{removed}</Text>\r\n </Box>\r\n {editList.length > 0 ? (\r\n <Box flexDirection=\"column\" marginTop={0}>\r\n {editList.map((edit: any, index: number) => {\r\n const search = edit.search_pattern || edit.TargetContent;\r\n const replace = edit.replacement || edit.ReplacementContent;\r\n return (\r\n <React.Fragment key={index}>\r\n {renderDiffSnippet(search, replace, { compact: index > 0 })}\r\n </React.Fragment>\r\n );\r\n })}\r\n </Box>\r\n ) : (\r\n null\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // LIST_DIR\r\n if (toolName === 'list_dir' && toolArgs) {\r\n const { DirectoryPath, remoteContext } = toolArgs;\r\n const itemStats = parseListDirResult(result);\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Listed </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(DirectoryPath, remoteContext)}</Text>\r\n {itemStats !== null && (\r\n <Text color=\"#666666\"> ({itemStats.dirs} dir{itemStats.dirs !== 1 ? 's' : ''}, {itemStats.files} file{itemStats.files !== 1 ? 's' : ''})</Text>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // GREP_SEARCH\r\n if (toolName === 'grep_search' && toolArgs) {\r\n const { Query, SearchPath } = toolArgs;\r\n const searchResults = parseGrepSearchResult(result);\r\n const searchPathRelative = toRelativePath(SearchPath);\r\n // Determine if it's a file or directory (heuristic: check for common file extensions)\r\n const hasExtension = /\\.[a-zA-Z0-9]{1,10}$/.test(SearchPath || '');\r\n const pathType = hasExtension ? 'file' : 'directory';\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Searched for </Text>\r\n <Text color=\"#00ccff\">\"{Query}\"</Text>\r\n {searchPathRelative && (\r\n <Text color=\"#666666\"> in <Text color=\"#00ccff\">{searchPathRelative}</Text> {pathType}</Text>\r\n )}\r\n {searchResults && (\r\n <Text color=\"#666666\"> ({searchResults.matches} match{searchResults.matches !== 1 ? 'es' : ''} in {searchResults.files} file{searchResults.files !== 1 ? 's' : ''})</Text>\r\n )}\r\n {!searchResults && result && <Text color=\"#666666\"> (no matches)</Text>}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // FIND_FILES\r\n if (toolName === 'find_files' && toolArgs) {\r\n const { pattern, Pattern } = toolArgs;\r\n const displayPattern = pattern || Pattern || '*';\r\n const fileCount = parseFindFilesResult(result);\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Found {fileCount !== null ? fileCount : 0} files matching </Text>\r\n <Text color=\"#00ccff\">\"{displayPattern}\"</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // WEB_SEARCH\r\n if (toolName === 'web_search' && toolArgs) {\r\n const { query } = toolArgs;\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Searched the web for </Text>\r\n <Text color=\"#00ccff\">\"{query}\"</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // FETCH_URL\r\n if (toolName === 'fetch_url' && toolArgs) {\r\n const { url } = toolArgs;\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Fetched </Text>\r\n <Text color=\"#00ccff\">{url}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // FAST_CONTEXT_SEARCH\r\n if (toolName === 'fast_context_search' && toolArgs) {\r\n let answer = result || '';\r\n let stats = undefined;\r\n\r\n try {\r\n if (result && result.trim().startsWith('{')) {\r\n const parsed = JSON.parse(result);\r\n if (parsed.answer !== undefined) {\r\n answer = parsed.answer;\r\n }\r\n if (parsed.stats !== undefined) {\r\n stats = parsed.stats;\r\n }\r\n }\r\n } catch (e) {\r\n // Fallback to raw result if parsing fails\r\n }\r\n\r\n const { query } = toolArgs;\r\n const scannedFiles = stats?.scannedFiles || [];\r\n const hasFiles = scannedFiles.length > 0;\r\n const MAX_DISPLAY_FILES = 10;\r\n\r\n const truncatedQuery = query && query.length > 50 ? query.substring(0, 47) + '...' : query || '';\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ Rapid Context </Text>\r\n <Text color=\"#cccccc\" wrap=\"truncate-end\">\"{truncatedQuery}\" </Text>\r\n {stats && (\r\n <Text color=\"#666666\">\r\n (Searched {stats.filesSearched} files in {(stats.duration / 1000).toFixed(1)}s)\r\n </Text>\r\n )}\r\n </Box>\r\n <Box paddingLeft={1} marginTop={1} flexDirection=\"column\">\r\n {!hasFiles && answer && (\r\n <Text color=\"#aaaaaa\" wrap=\"truncate-end\">{answer}</Text>\r\n )}\r\n\r\n {hasFiles && (\r\n <Box flexDirection=\"column\" marginTop={0}>\r\n {scannedFiles.slice(0, MAX_DISPLAY_FILES).map((f: string, i: number) => {\r\n // Display only the file name to keep it clean, or relative path\r\n return (\r\n <Text key={i} color=\"#444444\" wrap=\"truncate-end\">\r\n - {path.basename(f)} <Text color=\"#333333\" italic>({toRelativePath(f)})</Text>\r\n </Text>\r\n );\r\n })}\r\n {scannedFiles.length > MAX_DISPLAY_FILES && (\r\n <Text color=\"#444444\" italic>...and {scannedFiles.length - MAX_DISPLAY_FILES} more files checked</Text>\r\n )}\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // INSPECT_SYMBOL\r\n if (toolName === 'inspect_symbol' && toolArgs) {\r\n const { filePath, remoteContext } = toolArgs;\r\n const symbolResult = parseInspectSymbolResult(result);\r\n const displayPath = filePath || 'unknown';\r\n const noSymbols = result?.includes('No symbols found');\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Inspected </Text>\r\n <Text color=\"#00ccff\">{formatPathWithContext(displayPath, remoteContext)}</Text>\r\n {noSymbols && <Text color=\"#666666\"> (no symbols found)</Text>}\r\n {!noSymbols && symbolResult.found && <Text color=\"#666666\"> ({symbolResult.count} symbol{symbolResult.count !== 1 ? 's' : ''})</Text>}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // READ_BINARY_FILE\r\n if (toolName === 'read_binary_file' && toolArgs) {\r\n const { file_path, remoteContext } = toolArgs;\r\n const fileName = file_path ? path.basename(file_path) : 'file';\r\n\r\n // Parse file info from result\r\n const sizeMatch = result?.match(/Size:\\s*([\\d.]+\\s*(?:B|KB|MB))/);\r\n const typeMatch = result?.match(/Type:\\s*([\\w/+-]+)/);\r\n const fileSize = sizeMatch ? sizeMatch[1] : '';\r\n const fileType = typeMatch ? typeMatch[1] : '';\r\n const isSuccess = result?.includes('Successfully uploaded');\r\n const isError = result?.includes('Error:') || !isSuccess;\r\n const errorMessage = result?.match(/Error:\\s*(.+?)(?:\\n|$)/)?.[1] || '';\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={isSuccess ? \"#00cc66\" : \"#ff6666\"} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n {isSuccess ? (\r\n <>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Read </Text>\r\n <Text color=\"#ff9900\">{formatPathWithContext(file_path, remoteContext)}</Text>\r\n </>\r\n ) : (\r\n <>\r\n <Text color=\"#ff6666\" bold>✗ {toolInfo.emoji} Read failed </Text>\r\n <Text color=\"#ff9900\">{formatPathWithContext(file_path, remoteContext)}</Text>\r\n </>\r\n )}\r\n </Box>\r\n {isSuccess && (fileType || fileSize) && (\r\n <Box>\r\n <Text color=\"#666666\">\r\n {fileType && `${fileType}`}\r\n {fileType && fileSize && ' • '}\r\n {fileSize && fileSize}\r\n </Text>\r\n </Box>\r\n )}\r\n {isError && errorMessage && (\r\n <Box>\r\n <Text color=\"#ff6666\">{errorMessage}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // SUB_AGENT - completed\r\n if (toolName === 'sub_agent') {\r\n const toolAction = (toolArgs as any)?.action;\r\n const agentId = (toolArgs as any)?.agent_id || 'unknown';\r\n let title = 'Sub Agent';\r\n let details = '';\r\n let additionalContent = null;\r\n\r\n // Helper to try parsing JSON result\r\n let structResult: any = null;\r\n let markdownReport = typeof result === 'string' ? result : '';\r\n\r\n try {\r\n if (typeof result === 'string' && result.trim().startsWith('{')) {\r\n const parsed = JSON.parse(result);\r\n if (parsed.data && parsed.report) {\r\n structResult = parsed.data;\r\n markdownReport = parsed.report;\r\n }\r\n }\r\n } catch (e) {\r\n // Fallback to treating result as string\r\n }\r\n\r\n if (toolAction === 'spawn') {\r\n title = 'Sub Agent';\r\n const prompt = (toolArgs as any)?.prompt || '';\r\n const shortPrompt = prompt.length > 50 ? prompt.substring(0, 47) + '...' : prompt;\r\n // Result for spawn is usually text, we can parse ID from it if needed, but we don't have it in args yet usually\r\n // Actually spawn returns the ID in the result text, but we might not parse it here easily.\r\n // Assuming we rely on result text for ID if not in args.\r\n // But per request: \"id status, duration...\"\r\n // For spawn: \"just the agent id, and the prompt\"\r\n // We'll try to extract ID from result if possible, or use a placeholder if it's not in args (spawn doesn't take agent_id)\r\n const idMatch = result?.match(/Agent ID:\\*\\* ([\\w-]+)/);\r\n const spawnedId = idMatch ? idMatch[1] : 'unknown';\r\n details = `(id: ${spawnedId})`;\r\n\r\n if (prompt) {\r\n additionalContent = (\r\n <Box marginTop={1} marginLeft={2}>\r\n <Text color=\"#00ccff\">{prompt}</Text>\r\n </Box>\r\n );\r\n }\r\n }\r\n else if (toolAction === 'wait_for_status' || toolAction === 'status') {\r\n title = 'Sub Agent Status';\r\n // Parse status details from result string or structured data if we had it (status usually returns text)\r\n // Status result is text like: \"**Status:** 🔄 running\\n**Model:** ...\\n**Duration:** 16s...\"\r\n const statusMatch = result?.match(/Status:\\*\\* (.+?)\\n/);\r\n const durationMatch = result?.match(/Duration:\\*\\* (.+?)\\n/);\r\n const fileOpsMatch = result?.match(/File Operations:\\*\\* (\\d+)/);\r\n const toolCallsMatch = result?.match(/Tool Calls:\\*\\* (\\d+)/);\r\n\r\n const status = statusMatch ? statusMatch[1].trim() : 'unknown';\r\n const duration = durationMatch ? durationMatch[1].trim() : 'unknown';\r\n const fileOps = fileOpsMatch ? fileOpsMatch[1] : '0';\r\n const toolCalls = toolCallsMatch ? toolCallsMatch[1] : '0';\r\n\r\n details = `(id: ${agentId}, status: ${status}, duration: ${duration}, files: ${fileOps}, tools: ${toolCalls})`;\r\n }\r\n else if (toolAction === 'terminate') {\r\n title = 'Sub Agent Terminated';\r\n details = `(id: ${agentId})`;\r\n }\r\n else if (toolAction === 'read_results') {\r\n title = 'Sub Agent Results';\r\n // Use structured result if available\r\n if (structResult) {\r\n details = `(id: ${structResult.agentId}, duration: ${structResult.duration})`;\r\n\r\n // Show modified files\r\n if (structResult.fileOperations && structResult.fileOperations.length > 0) {\r\n additionalContent = (\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n <Text color=\"#666666\">Files Modified:</Text>\r\n {structResult.fileOperations.map((op: any, i: number) => (\r\n <Box key={i} marginLeft={2}>\r\n <Text color=\"#00ccff\">\r\n • {op.path} <Text color=\"#666666\" dimColor>({op.type})</Text>\r\n </Text>\r\n </Box>\r\n ))}\r\n {/* We can show the full report if needed, maybe collapsed or just implied */}\r\n </Box>\r\n );\r\n }\r\n } else {\r\n // Fallback for string result\r\n details = `(id: ${agentId})`;\r\n const summary = result?.length > 100 ? result.substring(0, 97) + '...' : result;\r\n additionalContent = <Text color=\"#666666\" dimColor>{summary}</Text>;\r\n }\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} {title} </Text>\r\n <Text color=\"#666666\">{details}</Text>\r\n </Box>\r\n {additionalContent}\r\n </Box>\r\n );\r\n }\r\n\r\n // CREATE_IMAGE\r\n if (toolName === 'create_image' && toolArgs) {\r\n const { output_path, aspect_ratio } = toolArgs;\r\n\r\n // Parse file info from result\r\n const sizeMatch = result?.match(/\\*\\*Size:\\*\\*\\s*([\\d.]+\\s*KB)/);\r\n const formatMatch = result?.match(/\\*\\*Format:\\*\\*\\s*([\\w/]+)/);\r\n const fileSize = sizeMatch ? sizeMatch[1] : '';\r\n const format = formatMatch ? formatMatch[1] : '';\r\n const isSuccess = result?.includes('generated successfully');\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={isSuccess ? \"#00cc66\" : \"#ff6666\"} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n {isSuccess ? (\r\n <>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Generated image </Text>\r\n <Text color=\"#00ccff\">{toRelativePath(output_path)}</Text>\r\n {(fileSize || format) && (\r\n <Text color=\"#666666\"> ({format}{format && fileSize ? ' • ' : ''}{fileSize})</Text>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n <Text color=\"#ff6666\" bold>✗ {toolInfo.emoji} Image generation failed</Text>\r\n </>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // BACKGROUND_COMMAND\r\n if (toolName === 'background_command' && toolArgs) {\r\n const { action, command, task_id, wait_seconds } = toolArgs;\r\n let actionText = 'Background command';\r\n let actionDetail = '';\r\n\r\n if (action === 'start') {\r\n actionText = 'Started background task';\r\n actionDetail = command ? `(${command})` : '';\r\n } else if (action === 'status') {\r\n actionText = 'Checked task status';\r\n actionDetail = task_id ? `(${task_id})` : '';\r\n } else if (action === 'kill') {\r\n actionText = 'Killed background task';\r\n actionDetail = task_id ? `(${task_id})` : '';\r\n } else if (action === 'wait') {\r\n actionText = 'Waited for';\r\n actionDetail = wait_seconds ? `${wait_seconds} second${wait_seconds !== 1 ? 's' : ''}` : '';\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} {actionText}</Text>\r\n {actionDetail && <Text color=\"#666666\"> {actionDetail}</Text>}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // WORKFLOW - completed state\r\n if (toolName === 'workflow' && toolArgs) {\r\n const action = toolArgs.action;\r\n const stepNumber = toolArgs.step_number;\r\n const exitType = toolArgs.exit_type;\r\n const reason = toolArgs.reason;\r\n\r\n let actionText = 'Workflow action';\r\n let borderColor = '#00cc66';\r\n let textColor = '#00cc66';\r\n let icon = '✓';\r\n\r\n if (action === 'step_complete') {\r\n actionText = `Step ${stepNumber || '?'} Complete`;\r\n borderColor = '#00cc66';\r\n textColor = '#00cc66';\r\n } else if (action === 'exit') {\r\n if (exitType === 'error') {\r\n actionText = `Workflow Failed${reason ? `: ${reason.slice(0, 50)}` : ''}`;\r\n borderColor = '#ff3366';\r\n textColor = '#ff3366';\r\n icon = '✗';\r\n } else if (exitType === 'cancelled') {\r\n actionText = 'Workflow Cancelled';\r\n borderColor = '#ff9900';\r\n textColor = '#ff9900';\r\n icon = '⚠';\r\n } else {\r\n actionText = 'Workflow Completed';\r\n borderColor = '#00cc66';\r\n textColor = '#00cc66';\r\n }\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={borderColor} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color={textColor} bold>{icon} 🔄 {actionText}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // GET_DIFF\r\n if (toolName === 'get_diff' && toolArgs) {\r\n const { filePath, staged } = toolArgs;\r\n const diffTarget = filePath ? toRelativePath(filePath) : '';\r\n const stagedText = staged ? ' (staged)' : '';\r\n\r\n // The get_diff tool returns JSON: { result: string, summary: string }\r\n // Parse JSON to extract the human-readable summary\r\n let parsedResult = result || '';\r\n let parsedSummary = '';\r\n try {\r\n if (result) {\r\n const json = JSON.parse(result);\r\n parsedResult = json.result || result;\r\n parsedSummary = json.summary || '';\r\n }\r\n } catch {\r\n // Not JSON, use raw result as-is\r\n }\r\n\r\n const hasChanges = !parsedResult.includes('No changes') && !parsedSummary.includes('No changes');\r\n const truncated = parsedResult.includes('[Diff truncated');\r\n\r\n // Build display summary from parsed data\r\n let displayInfo = 'no changes';\r\n if (hasChanges) {\r\n if (parsedSummary) {\r\n displayInfo = parsedSummary;\r\n } else {\r\n // Fallback: extract file count from result text (format: **N file(s) changed**)\r\n const filesMatch = parsedResult.match(/(\\d+)\\s+file\\(?s?\\)?\\s+changed/);\r\n displayInfo = filesMatch ? `${filesMatch[1]} file(s) changed` : 'changes detected';\r\n }\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Checked diff {diffTarget ? `for ${diffTarget} ` : ''}{stagedText}</Text>\r\n <Text color=\"#666666\">({displayInfo}{truncated ? ', truncated' : ''})</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // ADD_MCP - show server name, connection status, and tool count\r\n if (toolName === 'add_mcp' && toolArgs) {\r\n const serverName = toolArgs.name || 'unknown';\r\n const isSuccess = result && result.includes('SUCCESS');\r\n const borderColor = isSuccess ? '#9945FF' : '#ff3366';\r\n const statusIcon = isSuccess ? '✓' : '✗';\r\n const statusColor = isSuccess ? '#00cc66' : '#ff3366';\r\n\r\n // Extract tool count from result\r\n let toolCount = '';\r\n const toolCountMatch = result?.match(/Available tools \\((\\d+)\\)/);\r\n if (toolCountMatch) {\r\n toolCount = ` (${toolCountMatch[1]} tools)`;\r\n }\r\n\r\n // Extract error from result for failure case\r\n let errorMsg = '';\r\n if (!isSuccess) {\r\n const errorMatch = result?.match(/Error: (.+)/);\r\n if (errorMatch) {\r\n errorMsg = errorMatch[1];\r\n }\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={borderColor} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color={statusColor} bold>{statusIcon} 🔌 {isSuccess ? 'Connected' : 'Failed'} MCP server </Text>\r\n <Text color=\"#cc99ff\" bold>{serverName}</Text>\r\n {toolCount && <Text color=\"#666666\">{toolCount}</Text>}\r\n </Box>\r\n {errorMsg && (\r\n <Box paddingLeft={2}>\r\n <Text color=\"#ff6699\">{errorMsg}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // DEFAULT - for any other tool\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00ccff\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} {toolInfo.verb}</Text>\r\n </Box>\r\n {result && result.length < 300 && (\r\n <Box paddingLeft={1} marginTop={1}>\r\n <Text color=\"#aaaaaa\">{result}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n return null;\r\n}, (prevProps, nextProps) => {\r\n // Only re-render if the status or key fields changed\r\n const prevExec = prevProps.message.toolExecution;\r\n const nextExec = nextProps.message.toolExecution;\r\n\r\n if (!prevExec || !nextExec) return false;\r\n\r\n return prevExec.status === nextExec.status &&\r\n prevExec.toolName === nextExec.toolName &&\r\n prevExec.result === nextExec.result &&\r\n prevExec.error === nextExec.error &&\r\n prevExec.streamingOutput === nextExec.streamingOutput;\r\n});\r\n"],"mappings":"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","names":["lines","status"]}
1
+ {"version":3,"sources":["../../../src/ui/components/ToolExecutionMessage.tsx"],"sourcesContent":["import React from 'react';\r\nimport { Box, Text } from 'ink';\r\nimport Spinner from 'ink-spinner';\r\nimport stripAnsi from 'strip-ansi';\r\nimport wrapAnsi from 'wrap-ansi';\r\nimport stringWidth from 'string-width';\r\nimport * as path from 'path';\r\nimport * as Diff from 'diff';\r\nimport { Message } from '../../types/index.js';\r\nimport { processTerminalOutput } from '../../utils/terminal-output.js';\r\nimport { useTheme } from '../theme.js';\r\n\r\ninterface ToolExecutionMessageProps {\r\n message: Message;\r\n}\r\n\r\nconst TOOL_LABELS: Record<string, { verb: string; emoji: string }> = {\r\n view_file: { verb: 'Reading file', emoji: '📖' },\r\n write_to_file: { verb: 'Writing file', emoji: '' },\r\n edit_file: { verb: 'Editing file', emoji: '' },\r\n multi_edit_file: { verb: 'Editing file', emoji: '' },\r\n list_dir: { verb: 'Listing directory', emoji: '📁' },\r\n execute_command: { verb: 'Executing command', emoji: '⚡' },\r\n grep_search: { verb: 'Searching files', emoji: '🔍' },\r\n find_files: { verb: 'Finding files', emoji: '🔎' },\r\n web_search: { verb: 'Searching web', emoji: '🌐' },\r\n fetch_url: { verb: 'Fetching URL', emoji: '📡' },\r\n inspect_symbol: { verb: 'Inspecting symbol', emoji: '🔬' },\r\n read_binary_file: { verb: 'Reading binary file', emoji: '📄' },\r\n create_image: { verb: 'Generating image', emoji: '🎨' },\r\n background_command: { verb: 'Background command', emoji: '🔄' },\r\n get_diff: { verb: 'Getting diff', emoji: '📝' },\r\n sub_agent: { verb: 'Agent Task', emoji: '🤖' },\r\n fast_context_search: { verb: 'Searching context', emoji: '⚡' },\r\n auto_context_compaction: { verb: 'Auto compacting context', emoji: '[AUTO]' },\r\n add_mcp: { verb: 'Adding MCP server', emoji: '🔌' },\r\n};\r\n\r\n/**\r\n * Convert an absolute path to a relative path from the current working directory.\r\n * If the path is outside the CWD, returns the full path.\r\n * Always uses forward slashes for consistency.\r\n */\r\nfunction toRelativePath(absolutePath: string | undefined): string {\r\n if (!absolutePath) return '';\r\n try {\r\n const cwd = process.cwd();\r\n // Normalize paths for comparison (handle different path separators)\r\n const normalizedAbsolute = path.normalize(absolutePath);\r\n const normalizedCwd = path.normalize(cwd);\r\n\r\n // Check if the path starts with the CWD\r\n if (normalizedAbsolute.toLowerCase().startsWith(normalizedCwd.toLowerCase())) {\r\n let relativePath = path.relative(cwd, absolutePath);\r\n // If empty (same directory), show './'\r\n if (!relativePath) relativePath = '.';\r\n // Convert backslashes to forward slashes for consistent display\r\n return relativePath.replace(/\\\\/g, '/');\r\n }\r\n // Path is outside CWD, return as-is but with forward slashes\r\n return absolutePath.replace(/\\\\/g, '/');\r\n } catch {\r\n return absolutePath;\r\n }\r\n}\r\n\r\n/**\r\n * Format a path with remote context prefix for SSH/Docker/WSL environments.\r\n * In local mode, returns just the path.\r\n * In remote mode, returns \"user@host:/path\" format.\r\n */\r\nfunction formatPathWithContext(absolutePath: string | undefined, remoteContext?: string): string {\r\n const pathStr = toRelativePath(absolutePath);\r\n if (remoteContext && absolutePath) {\r\n // For remote environments, show full path with remote prefix\r\n // Use the absolute path to make it clear this is a remote file\r\n return `${remoteContext}:${absolutePath.replace(/\\\\/g, '/')}`;\r\n }\r\n return pathStr;\r\n}\r\n\r\n/**\r\n * Clean shell output for display in history\r\n */\r\nfunction cleanShellOutput(result: string | undefined): string {\r\n if (!result) return '';\r\n return processTerminalOutput(result);\r\n}\r\n\r\n/**\r\n * Truncate long commands for display to prevent rendering issues\r\n * @param command - The command string to truncate\r\n * @param maxLength - Maximum length before truncation (default: 80)\r\n * @returns Truncated command with ellipsis if needed\r\n */\r\nfunction truncateCommand(command: string, maxLength: number = 80): string {\r\n if (!command || command.length <= maxLength) return command;\r\n return command.substring(0, maxLength) + '...';\r\n}\r\n\r\n/**\r\n * Parse grep_search result to get match count\r\n * Format: \"Found X matches in Y files for pattern...\" or \"Found X matches for pattern...\"\r\n * Match lines are identified by the \":>\" marker\r\n */\r\nfunction parseGrepSearchResult(result: string | undefined): { matches: number; files: number } | null {\r\n if (!result) return null;\r\n\r\n // Handle \"No matches found\" case\r\n if (result.includes('No matches found')) {\r\n return { matches: 0, files: 0 };\r\n }\r\n\r\n // Try to parse \"Found X matches in Y files for pattern...\" format (preferred)\r\n const fullMatch = result.match(/Found (\\d+) match(?:es)? in (\\d+) file/);\r\n if (fullMatch) {\r\n return { matches: parseInt(fullMatch[1], 10), files: parseInt(fullMatch[2], 10) };\r\n }\r\n\r\n // Try to parse \"Found X matches for pattern...\" format (older format without file count)\r\n const matchCountOnly = result.match(/Found (\\d+) match(?:es)?/);\r\n if (matchCountOnly) {\r\n const matchCount = parseInt(matchCountOnly[1], 10);\r\n // Count unique files from the output - files appear as standalone paths before their matches\r\n // File paths are lines that don't start with a number and don't contain \":>\"\r\n const lines = result.split('\\n');\r\n const uniqueFiles = new Set<string>();\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n // Skip header lines and empty lines\r\n if (!trimmed || trimmed.startsWith('Found ') || trimmed.startsWith('(')) continue;\r\n // Match lines have \":>\" in them, skip those\r\n if (trimmed.includes(':>')) continue;\r\n // Context lines start with \"number: \" (note the space after colon)\r\n if (/^\\d+:\\s{3}/.test(trimmed)) continue;\r\n // Remaining lines that don't start with a number are file paths\r\n if (!/^\\d+:/.test(trimmed)) {\r\n uniqueFiles.add(trimmed);\r\n }\r\n }\r\n return { matches: matchCount, files: uniqueFiles.size };\r\n }\r\n\r\n // Final fallback: count actual match lines (identified by \":>\" marker)\r\n const lines = result.split('\\n');\r\n const matchLines = lines.filter(line => line.includes(':>'));\r\n if (matchLines.length > 0) {\r\n // Count unique files from file header lines\r\n const uniqueFiles = new Set<string>();\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith('Found ') || trimmed.startsWith('(')) continue;\r\n if (trimmed.includes(':>') || /^\\d+:/.test(trimmed)) continue;\r\n uniqueFiles.add(trimmed);\r\n }\r\n return { matches: matchLines.length, files: uniqueFiles.size };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n\r\n/**\r\n * Parse find_files result to get file count\r\n * Format: one file path per line, or \"Found X files\"\r\n */\r\nfunction parseFindFilesResult(result: string | undefined): number | null {\r\n if (!result) return null;\r\n\r\n // Check for \"No files found\" message\r\n if (result.includes('No files found') || result.includes('No matches found')) {\r\n return 0;\r\n }\r\n\r\n // Try to parse \"Found X files\" format\r\n const summaryMatch = result.match(/Found (\\d+) file/);\r\n if (summaryMatch) {\r\n return parseInt(summaryMatch[1], 10);\r\n }\r\n\r\n // Try to parse \"Total: X\" format\r\n const totalMatch = result.match(/Total:\\s*(\\d+)/);\r\n if (totalMatch) {\r\n return parseInt(totalMatch[1], 10);\r\n }\r\n\r\n // Count lines (each line is a file path)\r\n const lines = result.split('\\n').filter(line => line.trim() && !line.startsWith('Searching'));\r\n return lines.length > 0 ? lines.length : null;\r\n}\r\n\r\n/**\r\n * Coerce line number inputs from tool args into positive integers.\r\n */\r\nfunction toPositiveLineNumber(value: unknown): number | null {\r\n if (typeof value === 'number' && Number.isFinite(value) && value > 0) {\r\n return Math.floor(value);\r\n }\r\n if (typeof value === 'string' && value.trim()) {\r\n const parsed = parseInt(value, 10);\r\n if (Number.isFinite(parsed) && parsed > 0) {\r\n return parsed;\r\n }\r\n }\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse view_file result metadata.\r\n * Expected format includes:\r\n * - \"Lines: N\"\r\n * - Optional truncation marker \"(Truncated)\"\r\n * - Optional detail \"Showing first M lines only.\"\r\n */\r\nfunction parseViewFileResult(result: string | undefined): { displayedLines: number | null; totalLines: number | null; truncated: boolean } | null {\r\n if (!result) return null;\r\n\r\n const totalMatch = result.match(/^\\s*Lines:\\s*(\\d+)/im);\r\n const totalLines = totalMatch ? parseInt(totalMatch[1], 10) : null;\r\n\r\n const shownMatch = result.match(/Showing first (\\d+) lines only/i);\r\n const shownLines = shownMatch ? parseInt(shownMatch[1], 10) : null;\r\n\r\n const truncated = /\\(Truncated\\)/i.test(result) || /File truncated/i.test(result) || shownLines !== null;\r\n const displayedLines = truncated ? shownLines : totalLines;\r\n\r\n if (displayedLines === null && totalLines === null) {\r\n return null;\r\n }\r\n\r\n return { displayedLines, totalLines, truncated };\r\n}\r\n\r\n/**\r\n * Build user-facing line range text for view_file UI state.\r\n * Always favors concrete numeric ranges instead of \"entire file\".\r\n */\r\nfunction getViewFileLineInfo(toolArgs?: Record<string, any>, result?: string): string {\r\n const startLine = toPositiveLineNumber(toolArgs?.StartLine ?? toolArgs?.start_line) ?? 1;\r\n const endLineArg = toPositiveLineNumber(toolArgs?.EndLine ?? toolArgs?.end_line);\r\n\r\n const parsedResult = parseViewFileResult(result);\r\n if (parsedResult?.displayedLines != null) {\r\n const endLine = parsedResult.displayedLines > 0\r\n ? startLine + parsedResult.displayedLines - 1\r\n : startLine;\r\n const lineRange = `lines ${startLine}-${endLine}`;\r\n\r\n if (\r\n parsedResult.truncated &&\r\n parsedResult.totalLines !== null &&\r\n parsedResult.totalLines > parsedResult.displayedLines\r\n ) {\r\n return `${lineRange} (of ${parsedResult.totalLines})`;\r\n }\r\n\r\n return lineRange;\r\n }\r\n\r\n if (endLineArg !== null) {\r\n return `lines ${startLine}-${endLineArg}`;\r\n }\r\n\r\n return 'lines 1-500';\r\n}\r\n\r\n/**\r\n * Parse list_dir result to get item count\r\n * New format: \"Total: X directories, Y files, Z items\"\r\n * Old format: \"Directory: path\\nTotal items: X\\n...\"\r\n */\r\nfunction parseListDirResult(result: string | undefined): { dirs: number; files: number; total: number } | null {\r\n if (!result) return null;\r\n\r\n // Try to parse new enhanced format: \"Total: X directories, Y files, Z items\"\r\n const newFormatMatch = result.match(/Total:\\s*(\\d+)\\s*director(?:y|ies),?\\s*(\\d+)\\s*files?,?\\s*(\\d+)\\s*items?/i);\r\n if (newFormatMatch) {\r\n return {\r\n dirs: parseInt(newFormatMatch[1], 10),\r\n files: parseInt(newFormatMatch[2], 10),\r\n total: parseInt(newFormatMatch[3], 10)\r\n };\r\n }\r\n\r\n // Try to parse old format: \"Total items: X\"\r\n const oldFormatMatch = result.match(/Total items:\\s*(\\d+)/);\r\n if (oldFormatMatch) {\r\n const total = parseInt(oldFormatMatch[1], 10);\r\n return { dirs: 0, files: 0, total };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Parse inspect_symbol result to check if symbols were found\r\n */\r\nfunction parseInspectSymbolResult(result: string | undefined): { found: boolean; count: number } {\r\n if (!result) return { found: false, count: 0 };\r\n\r\n // Check for \"No symbols found\" message\r\n if (result.includes('No symbols found')) {\r\n return { found: false, count: 0 };\r\n }\r\n\r\n // Count symbol definitions (rough estimate based on common patterns)\r\n const symbolMatches = result.match(/(?:function|class|interface|type|const|let|var|def|struct)\\s+\\w+/g);\r\n return { found: true, count: symbolMatches ? symbolMatches.length : 1 };\r\n}\r\n\r\n/**\r\n * Parse fast_context_search result to get stats and markdown answer\r\n */\r\nfunction parseFastContextResult(result: string | undefined): { answer: string; stats?: { filesSearched: number; duration: number; scannedFiles: string[] } } {\r\n if (!result) return { answer: '' };\r\n\r\n try {\r\n // Try to parse as JSON first (new format)\r\n if (result.trim().startsWith('{')) {\r\n const parsed = JSON.parse(result);\r\n if (parsed.answer && parsed.stats) {\r\n return parsed;\r\n }\r\n }\r\n } catch (e) {\r\n // Fallback to raw string\r\n }\r\n\r\n return { answer: result };\r\n}\r\n\r\n/**\r\n * Parse MCP tool name to extract server name and tool name\r\n * MCP tools are named: mcp_{serverName}_{toolName}\r\n */\r\nfunction parseMCPToolName(toolName: string): { serverName: string; mcpToolName: string } | null {\r\n if (!toolName.startsWith('mcp_')) return null;\r\n\r\n // Remove 'mcp_' prefix and split by first underscore\r\n const withoutPrefix = toolName.slice(4); // Remove 'mcp_'\r\n const firstUnderscoreIdx = withoutPrefix.indexOf('_');\r\n\r\n if (firstUnderscoreIdx === -1) {\r\n return { serverName: withoutPrefix, mcpToolName: 'unknown' };\r\n }\r\n\r\n const serverName = withoutPrefix.slice(0, firstUnderscoreIdx);\r\n const mcpToolName = withoutPrefix.slice(firstUnderscoreIdx + 1);\r\n\r\n return { serverName, mcpToolName };\r\n}\r\n\r\n/**\r\n * Get display info for a tool, with special handling for MCP tools\r\n */\r\nfunction getToolDisplayInfo(toolName: string): { verb: string; emoji: string; isMCP: boolean; serverName?: string; mcpToolName?: string } {\r\n // Check if it's an MCP tool\r\n const mcpInfo = parseMCPToolName(toolName);\r\n if (mcpInfo) {\r\n return {\r\n verb: `MCP ${mcpInfo.serverName} ${mcpInfo.mcpToolName}`,\r\n emoji: '⚡',\r\n isMCP: true,\r\n serverName: mcpInfo.serverName,\r\n mcpToolName: mcpInfo.mcpToolName\r\n };\r\n }\r\n\r\n // Regular tool\r\n const toolInfo = TOOL_LABELS[toolName] || { verb: 'Executing', emoji: '🔧' };\r\n return { ...toolInfo, isMCP: false };\r\n}\r\n\r\n/**\r\n * Render a snippet of the diff (added/removed/context lines)\r\n * Does a proper line-by-line diff so unchanged context lines have no highlight.\r\n */\r\nfunction renderDiffSnippet(removedContent: string | undefined, addedContent: string | undefined, options: { compact?: boolean; startLine?: number } = {}): React.ReactNode {\r\n const { compact, startLine } = options;\r\n if (!removedContent && !addedContent) return null;\r\n\r\n const oldText = removedContent || '';\r\n const newText = addedContent || '';\r\n\r\n if (oldText.length === 0 && newText.length === 0) return null;\r\n\r\n const terminalWidth = process.stdout.columns || 80;\r\n const maxPreviewWidth = Math.max(12, terminalWidth - 16);\r\n const measuredLineWidths: number[] = [];\r\n\r\n // Compute a unified diff between old and new to get proper context/added/removed\r\n const changes = Diff.diffLines(oldText, newText);\r\n\r\n // Build display lines from the diff changes\r\n type DiffLine = { type: 'context' | 'added' | 'removed'; text: string; lineNum?: number };\r\n const diffLines: DiffLine[] = [];\r\n let oldLineNum = startLine || 1;\r\n let newLineNum = startLine || 1;\r\n\r\n for (const change of changes) {\r\n const lines = change.value.replace(/\\n$/, '').split('\\n');\r\n for (const line of lines) {\r\n if (change.added) {\r\n diffLines.push({ type: 'added', text: line, lineNum: newLineNum++ });\r\n } else if (change.removed) {\r\n diffLines.push({ type: 'removed', text: line, lineNum: oldLineNum++ });\r\n } else {\r\n // Context line - same in both\r\n diffLines.push({ type: 'context', text: line, lineNum: newLineNum });\r\n oldLineNum++;\r\n newLineNum++;\r\n }\r\n }\r\n }\r\n\r\n // Calculate gutter width\r\n const maxLineNum = Math.max(oldLineNum, newLineNum) - 1;\r\n const gutterWidth = startLine !== undefined ? String(maxLineNum).length : 0;\r\n\r\n const wrapDiffLine = (prefix: string, line: string, lineNum?: number): string[] => {\r\n const gutterStr = lineNum !== undefined ? `${String(lineNum).padStart(gutterWidth)} ` : '';\r\n const fullPrefix = `${gutterStr}${prefix}`;\r\n const continuationPrefix = ' '.repeat(fullPrefix.length);\r\n const wrapped = wrapAnsi(line.length > 0 ? line : ' ', Math.max(1, maxPreviewWidth - fullPrefix.length), {\r\n hard: true,\r\n trim: false\r\n }).split('\\n');\r\n\r\n return wrapped.map((segment, idx) => {\r\n const rendered = `${idx === 0 ? fullPrefix : continuationPrefix}${segment.length > 0 ? segment : ' '}`;\r\n measuredLineWidths.push(stringWidth(rendered));\r\n return rendered;\r\n });\r\n };\r\n\r\n const items: React.ReactNode[] = [];\r\n const maxDiffLines = 50;\r\n let renderedCount = 0;\r\n let skippedCount = 0;\r\n\r\n for (const dl of diffLines) {\r\n if (renderedCount >= maxDiffLines) {\r\n skippedCount++;\r\n continue;\r\n }\r\n\r\n const prefix = dl.type === 'added' ? '+ ' : dl.type === 'removed' ? '- ' : ' ';\r\n\r\n // Style: red bg for removed, green bg for added, no bg for context\r\n let color = '#e6e6e6';\r\n let backgroundColor: string | undefined;\r\n if (dl.type === 'removed') backgroundColor = '#5c1e1e';\r\n else if (dl.type === 'added') backgroundColor = '#1e4d2b';\r\n else color = '#aaaaaa'; // context lines are slightly dimmer\r\n\r\n wrapDiffLine(prefix, dl.text, dl.lineNum).forEach((wrappedLine, wrappedIndex) => {\r\n items.push(\r\n <Box key={`${dl.type}-${renderedCount}-${wrappedIndex}`}>\r\n <Text color={color} backgroundColor={backgroundColor} wrap=\"truncate-end\">\r\n {wrappedLine}\r\n </Text>\r\n </Box>\r\n );\r\n });\r\n renderedCount++;\r\n }\r\n\r\n if (skippedCount > 0) {\r\n items.push(\r\n <Box key=\"more\">\r\n <Text color=\"gray\" dimColor> ... {skippedCount} more lines not shown</Text>\r\n </Box>\r\n );\r\n }\r\n\r\n const separatorWidth = Math.max(\r\n 8,\r\n Math.min(\r\n maxPreviewWidth,\r\n measuredLineWidths.length > 0 ? Math.max(...measuredLineWidths) : 8\r\n )\r\n );\r\n\r\n return (\r\n <Box flexDirection=\"column\" marginTop={compact ? 0 : 1} alignSelf=\"flex-start\">\r\n <Box marginBottom={1}>\r\n <Text color=\"#333333\">{'─'.repeat(separatorWidth)}</Text>\r\n </Box>\r\n {items}\r\n </Box>\r\n );\r\n}\r\n\r\n/**\r\n * Constrains tool boxes to terminal width to prevent border overflow.\r\n * When long text (e.g. file paths) causes a bordered box to exceed the\r\n * terminal width, the border characters wrap and break visually. This\r\n * wrapper establishes a width constraint so that child boxes with\r\n * alignSelf=\"flex-start\" shrink-to-content but never exceed the terminal.\r\n */\r\nconst ToolBoxContainer: React.FC<{children: React.ReactNode}> = ({ children }) => (\r\n <Box width={process.stdout.columns || 80}>{children}</Box>\r\n);\r\n\r\nexport const ToolExecutionMessage: React.FC<ToolExecutionMessageProps> = React.memo(({ message }) => {\r\n const theme = useTheme();\r\n if (!message.toolExecution) {\r\n return null;\r\n }\r\n\r\n const { toolName, status, result, error, arguments: toolArgs } = message.toolExecution;\r\n const toolInfo = getToolDisplayInfo(toolName);\r\n\r\n // Display thinking duration if available (carried from thought-only message)\r\n const thinkingDuration = message.thinkingDuration;\r\n\r\n // Helper to wrap content with thinking duration display\r\n // Also constrains width to terminal to prevent border overflow\r\n const renderWithThinking = (content: React.ReactNode) => (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\">\r\n {thinkingDuration !== undefined && thinkingDuration >= 0 && (\r\n <Box marginBottom={1}>\r\n <Text dimColor>Thought for {thinkingDuration} second{thinkingDuration !== 1 ? 's' : ''} ›</Text>\r\n </Box>\r\n )}\r\n {content}\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n\r\n // EXECUTING state\r\n if (status === 'executing') {\r\n // Skip execute_command - it's handled by InteractiveShell component\r\n if (toolName === 'execute_command') {\r\n return null;\r\n }\r\n\r\n // Note: web_search, grep_search, find_files now have custom executing states below\r\n\r\n // Skip plan-mode tools - they have their own UI components (TaskCompletedMessage, PlanReviewScreen)\r\n // Skip todo_write - it has its own UI component (TodoListMessage)\r\n if (toolName === 'mark_task_complete' || toolName === 'create_plan' || toolName === 'todo_write') {\r\n return null;\r\n }\r\n\r\n\r\n if (toolName === 'auto_context_compaction') {\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> Auto summarizing context...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n // MCP tools - show executing state with simple format (no border to avoid emoji width issues)\r\n if (toolInfo.isMCP) {\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#9945FF\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> MCP</Text>\r\n <Text color=\"#9945FF\"> {toolInfo.serverName} {toolInfo.mcpToolName}</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // VIEW_FILE\r\n if (toolName === 'view_file' && toolArgs) {\r\n const { AbsolutePath, remoteContext } = toolArgs;\r\n const lineInfo = getViewFileLineInfo(toolArgs);\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> Reading {lineInfo} from </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(AbsolutePath, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // LIST_DIR\r\n if (toolName === 'list_dir' && toolArgs) {\r\n const { DirectoryPath, remoteContext } = toolArgs;\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> Listing </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(DirectoryPath, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // GREP_SEARCH\r\n if (toolName === 'grep_search' && toolArgs) {\r\n const { Query, SearchPath } = toolArgs;\r\n const searchPathRelative = toRelativePath(SearchPath);\r\n // Determine if it's a file or directory (heuristic: check for common file extensions)\r\n const hasExtension = /\\.[a-zA-Z0-9]{1,10}$/.test(SearchPath || '');\r\n const pathType = hasExtension ? 'file' : 'directory';\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> Searching for </Text>\r\n <Text color={theme.accent}>\"{Query}\"</Text>\r\n {searchPathRelative && (\r\n <Text color={theme.accent}> in <Text color={theme.accent} bold>{searchPathRelative}</Text> {pathType}...</Text>\r\n )}\r\n {!searchPathRelative && <Text color={theme.accent}>...</Text>}\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // FIND_FILES\r\n if (toolName === 'find_files' && toolArgs) {\r\n const { pattern } = toolArgs;\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> Finding files matching </Text>\r\n <Text color={theme.accent}>\"{pattern}\"...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // FETCH_URL\r\n if (toolName === 'fetch_url' && toolArgs) {\r\n const { url } = toolArgs;\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> Fetching </Text>\r\n <Text color={theme.accent}>{url}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // READ_BINARY_FILE\r\n if (toolName === 'read_binary_file' && toolArgs) {\r\n const { file_path, remoteContext } = toolArgs;\r\n const fileName = file_path ? path.basename(file_path) : 'file';\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff9900\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#ff9900\" bold> Reading </Text>\r\n <Text color=\"#ff9900\">{formatPathWithContext(file_path, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // WRITE_TO_FILE\r\n if (toolName === 'write_to_file' && toolArgs) {\r\n const { TargetFile, remoteContext } = toolArgs;\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> Writing to </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(TargetFile, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // EDIT_FILE\r\n if (toolName === 'edit_file' && toolArgs) {\r\n const { file_path, remoteContext } = toolArgs;\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> Editing </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(file_path, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // MULTI_EDIT_FILE\r\n if (toolName === 'multi_edit_file' && toolArgs) {\r\n const { file_path, remoteContext } = toolArgs;\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> Editing </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(file_path, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // CREATE_IMAGE\r\n if (toolName === 'create_image') {\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff9900\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#ff9900\" bold> Generating image...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // BACKGROUND_COMMAND - show action-specific message\r\n if (toolName === 'background_command' && toolArgs) {\r\n const { action, command, task_id, wait_seconds } = toolArgs;\r\n let actionText = 'Running background task...';\r\n if (action === 'start') {\r\n actionText = `Starting: ${command || 'command'}...`;\r\n } else if (action === 'status') {\r\n actionText = `Checking status: ${task_id || 'task'}...`;\r\n } else if (action === 'kill') {\r\n actionText = `Killing task: ${task_id || 'task'}...`;\r\n } else if (action === 'wait') {\r\n actionText = `Waiting for ${wait_seconds || '?'} second${wait_seconds !== 1 ? 's' : ''}...`;\r\n }\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff9900\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#ff9900\" bold> {toolInfo.emoji} {actionText}</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // GET_DIFF\r\n if (toolName === 'get_diff' && toolArgs) {\r\n const { filePath, staged, reason_text } = toolArgs;\r\n const diffTarget = filePath ? `for ${filePath}` : 'for all files';\r\n const stagedText = staged ? ' (staged)' : '';\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> {toolInfo.emoji} Getting diff {diffTarget}{stagedText}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // WEB_SEARCH\r\n if (toolName === 'web_search' && toolArgs) {\r\n const { query } = toolArgs;\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> {toolInfo.emoji} Searching the web for </Text>\r\n <Text color={theme.accent}>\"{query}\"...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // FAST_CONTEXT_SEARCH\r\n if (toolName === 'fast_context_search' && toolArgs) {\r\n const { query } = toolArgs;\r\n\r\n let scannedFiles: string[] = [];\r\n try {\r\n const streamData = message.toolExecution?.streamingOutput || result;\r\n if (streamData) {\r\n const lines = streamData.trim().split('\\n').filter(Boolean);\r\n if (lines.length > 0) {\r\n // Find the last valid JSON line by iterating backwards\r\n // The FastContextAgent outputs JSON blobs on stdout for UI updates\r\n for (let i = lines.length - 1; i >= 0; i--) {\r\n try {\r\n // The stream mixes logs and JSON. Fast context prints files inside JSON objects.\r\n const line = lines[i].trim();\r\n if (line.startsWith('{')) {\r\n const parsed = JSON.parse(line);\r\n if (parsed.type === 'scanned_files' && parsed.files) {\r\n scannedFiles = parsed.files;\r\n break; // Found the most recent valid state\r\n }\r\n }\r\n } catch (e) {\r\n // Ignore parsing errors for incomplete streamed lines\r\n }\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n // ignore parsing errors\r\n }\r\n\r\n // Format query for executing state\r\n const truncatedQuery = query && query.length > 50 ? query.substring(0, 47) + '...' : query || '';\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#00cc66\" bold> Rapid Context </Text>\r\n <Text color=\"#cccccc\"> \"{truncatedQuery}\"</Text>\r\n </Box>\r\n {scannedFiles.length > 0 && (\r\n <Box flexDirection=\"column\" marginLeft={2} marginTop={1}>\r\n {scannedFiles.map((f, i) => (\r\n <Text key={i} color=\"#666666\" wrap=\"truncate-end\">\r\n - {toRelativePath(f)}\r\n </Text>\r\n ))}\r\n </Box>\r\n )}\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // INSPECT_SYMBOL\r\n if (toolName === 'inspect_symbol' && toolArgs) {\r\n const { filePath, symbols, remoteContext } = toolArgs;\r\n const symbolList = Array.isArray(symbols) ? symbols.join(', ') : symbols || 'symbols';\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> {toolInfo.emoji} Inspecting </Text>\r\n <Text color={theme.accent}>{symbolList} in {formatPathWithContext(filePath, remoteContext)}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // SUB_AGENT - executing\r\n if (toolName === 'sub_agent' && toolArgs) {\r\n const action = (toolArgs as any).action;\r\n\r\n if (action === 'spawn') {\r\n const prompt = (toolArgs as any).prompt || (toolArgs as any).task || 'Unknown task';\r\n const complexity = (toolArgs as any).complexity || 3;\r\n const modelName = complexity > 5 ? 'Gemini 3.1 Pro Preview' : 'Gemini 3 Flash Preview';\r\n\r\n // Limit prompt display to 4 lines\r\n const promptLines = prompt.split('\\n');\r\n const maxLines = 4;\r\n const displayLines = promptLines.slice(0, maxLines);\r\n const remainingLines = promptLines.length - maxLines;\r\n const truncatedPrompt = displayLines.join('\\n');\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> {toolInfo.emoji} Spawning Sub-Agent </Text>\r\n <Text color=\"#666666\" dimColor>({modelName})</Text>\r\n </Box>\r\n <Box marginLeft={2} flexDirection=\"column\">\r\n <Text color={theme.accent}>{truncatedPrompt}</Text>\r\n {remainingLines > 0 && (\r\n <Text color=\"#666666\" dimColor>... {remainingLines} more lines</Text>\r\n )}\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n } else if (action === 'wait_for_status' || action === 'status') {\r\n const delay = (toolArgs as any).time_delay || 0;\r\n const agentId = (toolArgs as any).agent_id || 'unknown';\r\n const waitMessage = delay > 0 ? `Waiting for ${delay} seconds...` : 'Checking status...';\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> {toolInfo.emoji} Sub Agent Status </Text>\r\n <Text color=\"#666666\" dimColor>(id: {agentId})</Text>\r\n </Box>\r\n <Box marginLeft={2}>\r\n <Text color={theme.accent}>{waitMessage}</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> {toolInfo.emoji} Sub Agent </Text>\r\n <Text color=\"#666666\" dimColor>({action})</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // WORKFLOW - show action-specific message\r\n if (toolName === 'workflow' && toolArgs) {\r\n const action = toolArgs.action;\r\n const stepNumber = toolArgs.step_number;\r\n const exitType = toolArgs.exit_type;\r\n const reason = toolArgs.reason;\r\n\r\n let actionText = 'Workflow action...';\r\n let borderColor = theme.accent;\r\n let textColor = theme.accent;\r\n\r\n if (action === 'step_complete') {\r\n actionText = `Completing Step ${stepNumber || '?'}...`;\r\n borderColor = '#00cc66';\r\n textColor = '#00cc66';\r\n } else if (action === 'exit') {\r\n if (exitType === 'error') {\r\n actionText = `Workflow Failed${reason ? `: ${reason.slice(0, 50)}` : ''}`;\r\n borderColor = '#ff3366';\r\n textColor = '#ff3366';\r\n } else if (exitType === 'cancelled') {\r\n actionText = 'Workflow Cancelled';\r\n borderColor = '#ff9900';\r\n textColor = '#ff9900';\r\n } else {\r\n actionText = 'Workflow Completed';\r\n borderColor = '#00cc66';\r\n textColor = '#00cc66';\r\n }\r\n }\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={borderColor} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={textColor} bold> 🔄 {actionText}</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // ADD_MCP - show server name and command being connected\r\n if (toolName === 'add_mcp' && toolArgs) {\r\n const serverName = toolArgs.name || 'unknown';\r\n const command = toolArgs.command || '';\r\n const serverArgs = Array.isArray(toolArgs.args) ? toolArgs.args.join(' ') : '';\r\n const fullCommand = serverArgs ? `${command} ${serverArgs}` : command;\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#9945FF\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#9945FF\"><Spinner type=\"arc\" /></Text>\r\n <Text color=\"#9945FF\" bold> 🔌 Adding MCP server </Text>\r\n <Text color=\"#cc99ff\" bold>{serverName}</Text>\r\n </Box>\r\n {fullCommand && (\r\n <Box>\r\n <Text color=\"#666666\" dimColor> {fullCommand}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.bgAccent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={theme.accent}><Spinner type=\"arc\" /></Text>\r\n <Text color={theme.accent} bold> {toolInfo.verb}...</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // ERROR state\r\n if (status === 'error') {\r\n // EXECUTE_COMMAND - render as static shell box with error\r\n if (toolName === 'execute_command' && toolArgs) {\r\n const command = toolArgs.command || toolArgs.CommandLine || toolArgs.commandLine || '';\r\n const truncatedCommand = truncateCommand(command, 80);\r\n const { cwd, remoteContext } = toolArgs;\r\n const cleanResult = cleanShellOutput(result);\r\n // For CWD display, use absolute path directly (don't convert to relative)\r\n const formattedCwd = cwd && remoteContext\r\n ? `${remoteContext}:${cwd.replace(/\\\\/g, '/')}`\r\n : (cwd || '').replace(/\\\\/g, '/');\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff3366\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\" marginBottom={1}>\r\n <Text>\r\n <Text color=\"#ff3366\" bold>✗ Shell </Text>\r\n <Text color=\"#666666\">{truncatedCommand} </Text>\r\n {cwd && <Text color=\"#666666\" dimColor>[current working directory {formattedCwd}]</Text>}\r\n </Text>\r\n </Box>\r\n {cleanResult && (\r\n <Box>\r\n <Text wrap=\"wrap\">{cleanResult}</Text>\r\n </Box>\r\n )}\r\n {/* Don't show error separately - it's already in the output */}\r\n </Box >\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n return (\r\n <ToolBoxContainer>\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#ff3366\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#ff3366\" bold>✗ {toolInfo.emoji} {toolInfo.verb} failed</Text>\r\n </Box>\r\n <Box paddingLeft={1} marginTop={1}>\r\n <Text color=\"#ff3366\">{error || 'The Agent passed invalid parameters'}</Text>\r\n </Box>\r\n </Box>\r\n </ToolBoxContainer>\r\n );\r\n }\r\n\r\n // COMPLETED state - tool-specific rendering\r\n if (status === 'completed') {\r\n // MCP tools - show only success indicator, hide output (output goes to AI only)\r\n if (toolInfo.isMCP) {\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ MCP</Text>\r\n <Text color=\"#aaaaaa\"> {toolInfo.serverName} {toolInfo.mcpToolName}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // Skip plan-mode tools - they have their own UI components (TaskCompletedMessage, PlanReviewScreen)\r\n // Skip todo_write - it has its own UI component (TodoListMessage)\r\n if (toolName === 'mark_task_complete' || toolName === 'create_plan' || toolName === 'todo_write') {\r\n return null;\r\n }\r\n\r\n\r\n if (toolName === 'auto_context_compaction') {\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>Auto compacted context</Text>\r\n </Box>\r\n {result && (\r\n <Box paddingLeft={1} marginTop={1}>\r\n <Text color=\"#aaaaaa\">{result}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n // EXECUTE_COMMAND - render as static shell box\r\n if (toolName === 'execute_command' && toolArgs) {\r\n // Hide shell_input actions from history as per user request\r\n // These are just input submissions (like \"1\\n\") and the result is just confirmation text\r\n // The actual side effects are seen in the persistent shell, so showing this block is redundant clutter\r\n if (toolArgs.shell_input) {\r\n return null;\r\n }\r\n\r\n const command = toolArgs.command || toolArgs.CommandLine || toolArgs.commandLine || '';\r\n const truncatedCommand = truncateCommand(command, 80);\r\n const { cwd, remoteContext } = toolArgs;\r\n const cleanResult = cleanShellOutput(result);\r\n // For CWD display, use absolute path directly (don't convert to relative)\r\n const formattedCwd = cwd && remoteContext\r\n ? `${remoteContext}:${cwd.replace(/\\\\/g, '/')}`\r\n : (cwd || '').replace(/\\\\/g, '/');\r\n\r\n // Detect if this command was transferred to background due to timeout\r\n const wasTransferred = !!toolArgs?.timeoutTransferred;\r\n const shellBorderColor = wasTransferred ? '#f59e0b' : '#00cc66';\r\n const shellHeaderColor = wasTransferred ? '#f59e0b' : '#00cc66';\r\n const shellIcon = wasTransferred ? '⏱' : '✓';\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={shellBorderColor} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\" marginBottom={1}>\r\n <Text>\r\n <Text color={shellHeaderColor} bold>{shellIcon} Shell </Text>\r\n <Text color=\"#666666\">{truncatedCommand} </Text>\r\n {cwd && <Text color=\"#666666\" dimColor>[current working directory {formattedCwd}]</Text>}\r\n </Text>\r\n </Box>\r\n {cleanResult && (\r\n <Box>\r\n <Text wrap=\"wrap\">{cleanResult}</Text>\r\n </Box>\r\n )}\r\n {wasTransferred && (\r\n <Box marginTop={1}>\r\n <Text color=\"#f59e0b\" bold>⚠ Timeout exceeded — transferred to background shell</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // VIEW_FILE\r\n if (toolName === 'view_file' && toolArgs) {\r\n const { AbsolutePath, remoteContext } = toolArgs;\r\n const lineInfo = getViewFileLineInfo(toolArgs, result);\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Read {lineInfo} from </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(AbsolutePath, remoteContext)}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // WRITE_TO_FILE\r\n if (toolName === 'write_to_file' && toolArgs) {\r\n const { TargetFile, CodeContent, remoteContext } = toolArgs;\r\n const lines = CodeContent ? CodeContent.split('\\n').length : 0;\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Wrote to </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(TargetFile, remoteContext)}</Text>\r\n {lines > 0 && <Text color=\"green\"> +{lines}</Text>}\r\n </Box>\r\n {renderDiffSnippet(undefined, CodeContent, { startLine: 1 })}\r\n </Box>\r\n );\r\n }\r\n\r\n // EDIT_FILE\r\n if (toolName === 'edit_file' && toolArgs) {\r\n const { file_path, remoteContext, replacement, search_pattern } = toolArgs;\r\n const added = replacement ? replacement.split('\\n').length : 0;\r\n const removed = search_pattern ? search_pattern.split('\\n').length : 0;\r\n\r\n // Parse the line number from the result (e.g. \"at line 42\")\r\n const lineMatch = result?.match(/at line (\\d+)/);\r\n const editStartLine = lineMatch ? parseInt(lineMatch[1], 10) : 1;\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Edited </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(file_path, remoteContext)}</Text>\r\n <Text color=\"green\"> +{added}</Text>\r\n <Text color=\"red\"> -{removed}</Text>\r\n </Box>\r\n {renderDiffSnippet(search_pattern, replacement, { startLine: editStartLine })}\r\n </Box>\r\n );\r\n }\r\n\r\n // MULTI_EDIT_FILE\r\n if (toolName === 'multi_edit_file' && toolArgs) {\r\n const { file_path, edits, remoteContext } = toolArgs;\r\n const editList = Array.isArray(edits) ? edits : [];\r\n\r\n let added = 0;\r\n let removed = 0;\r\n\r\n editList.forEach((edit: any) => {\r\n if (edit.replacement || edit.ReplacementContent) {\r\n added += (edit.replacement || edit.ReplacementContent).split('\\n').length;\r\n }\r\n if (edit.search_pattern || edit.TargetContent) {\r\n removed += (edit.search_pattern || edit.TargetContent).split('\\n').length;\r\n }\r\n });\r\n\r\n // Parse per-edit line numbers from the result (e.g. \"at lines 10, 45, 92\")\r\n const multiLineMatch = result?.match(/at lines ([\\d, ]+)/);\r\n const editLineNumbers: number[] = multiLineMatch\r\n ? multiLineMatch[1].split(',').map(s => parseInt(s.trim(), 10))\r\n : [];\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Edited </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(file_path, remoteContext)}</Text>\r\n <Text color=\"green\"> +{added}</Text>\r\n <Text color=\"red\"> -{removed}</Text>\r\n </Box>\r\n {editList.length > 0 ? (\r\n <Box flexDirection=\"column\" marginTop={0}>\r\n {editList.map((edit: any, index: number) => {\r\n const search = edit.search_pattern || edit.TargetContent;\r\n const replace = edit.replacement || edit.ReplacementContent;\r\n const editLine = editLineNumbers[index] || 1;\r\n return (\r\n <React.Fragment key={index}>\r\n {renderDiffSnippet(search, replace, { compact: index > 0, startLine: editLine })}\r\n </React.Fragment>\r\n );\r\n })}\r\n </Box>\r\n ) : (\r\n null\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // LIST_DIR\r\n if (toolName === 'list_dir' && toolArgs) {\r\n const { DirectoryPath, remoteContext } = toolArgs;\r\n const itemStats = parseListDirResult(result);\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Listed </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(DirectoryPath, remoteContext)}</Text>\r\n {itemStats !== null && (\r\n <Text color=\"#666666\"> ({itemStats.dirs} dir{itemStats.dirs !== 1 ? 's' : ''}, {itemStats.files} file{itemStats.files !== 1 ? 's' : ''})</Text>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // GREP_SEARCH\r\n if (toolName === 'grep_search' && toolArgs) {\r\n const { Query, SearchPath } = toolArgs;\r\n const searchResults = parseGrepSearchResult(result);\r\n const searchPathRelative = toRelativePath(SearchPath);\r\n // Determine if it's a file or directory (heuristic: check for common file extensions)\r\n const hasExtension = /\\.[a-zA-Z0-9]{1,10}$/.test(SearchPath || '');\r\n const pathType = hasExtension ? 'file' : 'directory';\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Searched for </Text>\r\n <Text color={theme.accent}>\"{Query}\"</Text>\r\n {searchPathRelative && (\r\n <Text color=\"#666666\"> in <Text color={theme.accent}>{searchPathRelative}</Text> {pathType}</Text>\r\n )}\r\n {searchResults && (\r\n <Text color=\"#666666\"> ({searchResults.matches} match{searchResults.matches !== 1 ? 'es' : ''} in {searchResults.files} file{searchResults.files !== 1 ? 's' : ''})</Text>\r\n )}\r\n {!searchResults && result && <Text color=\"#666666\"> (no matches)</Text>}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // FIND_FILES\r\n if (toolName === 'find_files' && toolArgs) {\r\n const { pattern, Pattern } = toolArgs;\r\n const displayPattern = pattern || Pattern || '*';\r\n const fileCount = parseFindFilesResult(result);\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Found {fileCount !== null ? fileCount : 0} files matching </Text>\r\n <Text color={theme.accent}>\"{displayPattern}\"</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // WEB_SEARCH\r\n if (toolName === 'web_search' && toolArgs) {\r\n const { query } = toolArgs;\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Searched the web for </Text>\r\n <Text color={theme.accent}>\"{query}\"</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // FETCH_URL\r\n if (toolName === 'fetch_url' && toolArgs) {\r\n const { url } = toolArgs;\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Fetched </Text>\r\n <Text color={theme.accent}>{url}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // FAST_CONTEXT_SEARCH\r\n if (toolName === 'fast_context_search' && toolArgs) {\r\n let answer = result || '';\r\n let stats = undefined;\r\n\r\n try {\r\n if (result && result.trim().startsWith('{')) {\r\n const parsed = JSON.parse(result);\r\n if (parsed.answer !== undefined) {\r\n answer = parsed.answer;\r\n }\r\n if (parsed.stats !== undefined) {\r\n stats = parsed.stats;\r\n }\r\n }\r\n } catch (e) {\r\n // Fallback to raw result if parsing fails\r\n }\r\n\r\n const { query } = toolArgs;\r\n const scannedFiles = stats?.scannedFiles || [];\r\n const hasFiles = scannedFiles.length > 0;\r\n const MAX_DISPLAY_FILES = 10;\r\n\r\n const truncatedQuery = query && query.length > 50 ? query.substring(0, 47) + '...' : query || '';\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ Rapid Context </Text>\r\n <Text color=\"#cccccc\" wrap=\"truncate-end\">\"{truncatedQuery}\" </Text>\r\n {stats && (\r\n <Text color=\"#666666\">\r\n (Searched {stats.filesSearched} files in {(stats.duration / 1000).toFixed(1)}s)\r\n </Text>\r\n )}\r\n </Box>\r\n <Box paddingLeft={1} marginTop={1} flexDirection=\"column\">\r\n {!hasFiles && answer && (\r\n <Text color=\"#aaaaaa\" wrap=\"truncate-end\">{answer}</Text>\r\n )}\r\n\r\n {hasFiles && (\r\n <Box flexDirection=\"column\" marginTop={0}>\r\n {scannedFiles.slice(0, MAX_DISPLAY_FILES).map((f: string, i: number) => {\r\n // Display only the file name to keep it clean, or relative path\r\n return (\r\n <Text key={i} color=\"#444444\" wrap=\"truncate-end\">\r\n - {path.basename(f)} <Text color=\"#333333\" italic>({toRelativePath(f)})</Text>\r\n </Text>\r\n );\r\n })}\r\n {scannedFiles.length > MAX_DISPLAY_FILES && (\r\n <Text color=\"#444444\" italic>...and {scannedFiles.length - MAX_DISPLAY_FILES} more files checked</Text>\r\n )}\r\n </Box>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // INSPECT_SYMBOL\r\n if (toolName === 'inspect_symbol' && toolArgs) {\r\n const { filePath, remoteContext } = toolArgs;\r\n const symbolResult = parseInspectSymbolResult(result);\r\n const displayPath = filePath || 'unknown';\r\n const noSymbols = result?.includes('No symbols found');\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Inspected </Text>\r\n <Text color={theme.accent}>{formatPathWithContext(displayPath, remoteContext)}</Text>\r\n {noSymbols && <Text color=\"#666666\"> (no symbols found)</Text>}\r\n {!noSymbols && symbolResult.found && <Text color=\"#666666\"> ({symbolResult.count} symbol{symbolResult.count !== 1 ? 's' : ''})</Text>}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // READ_BINARY_FILE\r\n if (toolName === 'read_binary_file' && toolArgs) {\r\n const { file_path, remoteContext } = toolArgs;\r\n const fileName = file_path ? path.basename(file_path) : 'file';\r\n\r\n // Parse file info from result\r\n const sizeMatch = result?.match(/Size:\\s*([\\d.]+\\s*(?:B|KB|MB))/);\r\n const typeMatch = result?.match(/Type:\\s*([\\w/+-]+)/);\r\n const fileSize = sizeMatch ? sizeMatch[1] : '';\r\n const fileType = typeMatch ? typeMatch[1] : '';\r\n const isSuccess = result?.includes('Successfully uploaded');\r\n const isError = result?.includes('Error:') || !isSuccess;\r\n const errorMessage = result?.match(/Error:\\s*(.+?)(?:\\n|$)/)?.[1] || '';\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={isSuccess ? \"#00cc66\" : \"#ff6666\"} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n {isSuccess ? (\r\n <>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Read </Text>\r\n <Text color=\"#ff9900\">{formatPathWithContext(file_path, remoteContext)}</Text>\r\n </>\r\n ) : (\r\n <>\r\n <Text color=\"#ff6666\" bold>✗ {toolInfo.emoji} Read failed </Text>\r\n <Text color=\"#ff9900\">{formatPathWithContext(file_path, remoteContext)}</Text>\r\n </>\r\n )}\r\n </Box>\r\n {isSuccess && (fileType || fileSize) && (\r\n <Box>\r\n <Text color=\"#666666\">\r\n {fileType && `${fileType}`}\r\n {fileType && fileSize && ' • '}\r\n {fileSize && fileSize}\r\n </Text>\r\n </Box>\r\n )}\r\n {isError && errorMessage && (\r\n <Box>\r\n <Text color=\"#ff6666\">{errorMessage}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // SUB_AGENT - completed\r\n if (toolName === 'sub_agent') {\r\n const toolAction = (toolArgs as any)?.action;\r\n const agentId = (toolArgs as any)?.agent_id || 'unknown';\r\n let title = 'Sub Agent';\r\n let details = '';\r\n let additionalContent = null;\r\n\r\n // Helper to try parsing JSON result\r\n let structResult: any = null;\r\n let markdownReport = typeof result === 'string' ? result : '';\r\n\r\n try {\r\n if (typeof result === 'string' && result.trim().startsWith('{')) {\r\n const parsed = JSON.parse(result);\r\n if (parsed.data && parsed.report) {\r\n structResult = parsed.data;\r\n markdownReport = parsed.report;\r\n }\r\n }\r\n } catch (e) {\r\n // Fallback to treating result as string\r\n }\r\n\r\n if (toolAction === 'spawn') {\r\n title = 'Sub Agent';\r\n const prompt = (toolArgs as any)?.prompt || '';\r\n const shortPrompt = prompt.length > 50 ? prompt.substring(0, 47) + '...' : prompt;\r\n // Result for spawn is usually text, we can parse ID from it if needed, but we don't have it in args yet usually\r\n // Actually spawn returns the ID in the result text, but we might not parse it here easily.\r\n // Assuming we rely on result text for ID if not in args.\r\n // But per request: \"id status, duration...\"\r\n // For spawn: \"just the agent id, and the prompt\"\r\n // We'll try to extract ID from result if possible, or use a placeholder if it's not in args (spawn doesn't take agent_id)\r\n const idMatch = result?.match(/Agent ID:\\*\\* ([\\w-]+)/);\r\n const spawnedId = idMatch ? idMatch[1] : 'unknown';\r\n details = `(id: ${spawnedId})`;\r\n\r\n if (prompt) {\r\n additionalContent = (\r\n <Box marginTop={1} marginLeft={2}>\r\n <Text color={theme.accent}>{prompt}</Text>\r\n </Box>\r\n );\r\n }\r\n }\r\n else if (toolAction === 'wait_for_status' || toolAction === 'status') {\r\n title = 'Sub Agent Status';\r\n // Parse status details from result string or structured data if we had it (status usually returns text)\r\n // Status result is text like: \"**Status:** 🔄 running\\n**Model:** ...\\n**Duration:** 16s...\"\r\n const statusMatch = result?.match(/Status:\\*\\* (.+?)\\n/);\r\n const durationMatch = result?.match(/Duration:\\*\\* (.+?)\\n/);\r\n const fileOpsMatch = result?.match(/File Operations:\\*\\* (\\d+)/);\r\n const toolCallsMatch = result?.match(/Tool Calls:\\*\\* (\\d+)/);\r\n\r\n const status = statusMatch ? statusMatch[1].trim() : 'unknown';\r\n const duration = durationMatch ? durationMatch[1].trim() : 'unknown';\r\n const fileOps = fileOpsMatch ? fileOpsMatch[1] : '0';\r\n const toolCalls = toolCallsMatch ? toolCallsMatch[1] : '0';\r\n\r\n details = `(id: ${agentId}, status: ${status}, duration: ${duration}, files: ${fileOps}, tools: ${toolCalls})`;\r\n }\r\n else if (toolAction === 'terminate') {\r\n title = 'Sub Agent Terminated';\r\n details = `(id: ${agentId})`;\r\n }\r\n else if (toolAction === 'read_results') {\r\n title = 'Sub Agent Results';\r\n // Use structured result if available\r\n if (structResult) {\r\n details = `(id: ${structResult.agentId}, duration: ${structResult.duration})`;\r\n\r\n // Show modified files\r\n if (structResult.fileOperations && structResult.fileOperations.length > 0) {\r\n additionalContent = (\r\n <Box flexDirection=\"column\" marginTop={1}>\r\n <Text color=\"#666666\">Files Modified:</Text>\r\n {structResult.fileOperations.map((op: any, i: number) => (\r\n <Box key={i} marginLeft={2}>\r\n <Text color={theme.accent}>\r\n • {op.path} <Text color=\"#666666\" dimColor>({op.type})</Text>\r\n </Text>\r\n </Box>\r\n ))}\r\n {/* We can show the full report if needed, maybe collapsed or just implied */}\r\n </Box>\r\n );\r\n }\r\n } else {\r\n // Fallback for string result\r\n details = `(id: ${agentId})`;\r\n const summary = result?.length > 100 ? result.substring(0, 97) + '...' : result;\r\n additionalContent = <Text color=\"#666666\" dimColor>{summary}</Text>;\r\n }\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} {title} </Text>\r\n <Text color=\"#666666\">{details}</Text>\r\n </Box>\r\n {additionalContent}\r\n </Box>\r\n );\r\n }\r\n\r\n // CREATE_IMAGE\r\n if (toolName === 'create_image' && toolArgs) {\r\n const { output_path, aspect_ratio } = toolArgs;\r\n\r\n // Parse file info from result\r\n const sizeMatch = result?.match(/\\*\\*Size:\\*\\*\\s*([\\d.]+\\s*KB)/);\r\n const formatMatch = result?.match(/\\*\\*Format:\\*\\*\\s*([\\w/]+)/);\r\n const fileSize = sizeMatch ? sizeMatch[1] : '';\r\n const format = formatMatch ? formatMatch[1] : '';\r\n const isSuccess = result?.includes('generated successfully');\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={isSuccess ? \"#00cc66\" : \"#ff6666\"} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n {isSuccess ? (\r\n <>\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Generated image </Text>\r\n <Text color={theme.accent}>{toRelativePath(output_path)}</Text>\r\n {(fileSize || format) && (\r\n <Text color=\"#666666\"> ({format}{format && fileSize ? ' • ' : ''}{fileSize})</Text>\r\n )}\r\n </>\r\n ) : (\r\n <>\r\n <Text color=\"#ff6666\" bold>✗ {toolInfo.emoji} Image generation failed</Text>\r\n </>\r\n )}\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // BACKGROUND_COMMAND\r\n if (toolName === 'background_command' && toolArgs) {\r\n const { action, command, task_id, wait_seconds } = toolArgs;\r\n let actionText = 'Background command';\r\n let actionDetail = '';\r\n\r\n if (action === 'start') {\r\n actionText = 'Started background task';\r\n actionDetail = command ? `(${command})` : '';\r\n } else if (action === 'status') {\r\n actionText = 'Checked task status';\r\n actionDetail = task_id ? `(${task_id})` : '';\r\n } else if (action === 'kill') {\r\n actionText = 'Killed background task';\r\n actionDetail = task_id ? `(${task_id})` : '';\r\n } else if (action === 'wait') {\r\n actionText = 'Waited for';\r\n actionDetail = wait_seconds ? `${wait_seconds} second${wait_seconds !== 1 ? 's' : ''}` : '';\r\n }\r\n\r\n // Extract output preview from result for status/wait actions\r\n let outputPreview = '';\r\n if ((action === 'status' || action === 'wait') && result) {\r\n // Sanitize: strip ANSI escapes, control characters, and emojis\r\n const sanitized = stripAnsi(processTerminalOutput(result))\r\n .replace(/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F\\x7F]/g, '') // strip control chars (keep \\n \\r \\t)\r\n .replace(/\\r\\n/g, '\\n')\r\n .replace(/\\r/g, '\\n');\r\n // The result contains task info including output — extract the last lines\r\n const outputMatch = sanitized.match(/(?:Output Preview|Recent Output|Output \\(last).*?:\\n?([\\s\\S]*?)(?:\\n\\n|$)/i);\r\n if (outputMatch) {\r\n outputPreview = outputMatch[1].trim();\r\n } else {\r\n // Fallback: show the last few lines of the result as a preview\r\n const lines = sanitized.split('\\n').filter((l: string) => l.trim());\r\n if (lines.length > 2) {\r\n outputPreview = lines.slice(-5).join('\\n');\r\n }\r\n }\r\n // Final safety: limit length to prevent huge renders\r\n if (outputPreview.length > 500) {\r\n outputPreview = outputPreview.slice(-500);\r\n }\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} {actionText}</Text>\r\n {actionDetail && <Text color=\"#666666\"> {actionDetail}</Text>}\r\n </Box>\r\n {outputPreview && (\r\n <Box marginTop={1}>\r\n <Text wrap=\"wrap\" dimColor>{outputPreview}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // WORKFLOW - completed state\r\n if (toolName === 'workflow' && toolArgs) {\r\n const action = toolArgs.action;\r\n const stepNumber = toolArgs.step_number;\r\n const exitType = toolArgs.exit_type;\r\n const reason = toolArgs.reason;\r\n\r\n let actionText = 'Workflow action';\r\n let borderColor = '#00cc66';\r\n let textColor = '#00cc66';\r\n let icon = '✓';\r\n\r\n if (action === 'step_complete') {\r\n actionText = `Step ${stepNumber || '?'} Complete`;\r\n borderColor = '#00cc66';\r\n textColor = '#00cc66';\r\n } else if (action === 'exit') {\r\n if (exitType === 'error') {\r\n actionText = `Workflow Failed${reason ? `: ${reason.slice(0, 50)}` : ''}`;\r\n borderColor = '#ff3366';\r\n textColor = '#ff3366';\r\n icon = '✗';\r\n } else if (exitType === 'cancelled') {\r\n actionText = 'Workflow Cancelled';\r\n borderColor = '#ff9900';\r\n textColor = '#ff9900';\r\n icon = '⚠';\r\n } else {\r\n actionText = 'Workflow Completed';\r\n borderColor = '#00cc66';\r\n textColor = '#00cc66';\r\n }\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={borderColor} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={textColor} bold>{icon} 🔄 {actionText}</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // GET_DIFF\r\n if (toolName === 'get_diff' && toolArgs) {\r\n const { filePath, staged } = toolArgs;\r\n const diffTarget = filePath ? toRelativePath(filePath) : '';\r\n const stagedText = staged ? ' (staged)' : '';\r\n\r\n // The get_diff tool returns JSON: { result: string, summary: string }\r\n // Parse JSON to extract the human-readable summary\r\n let parsedResult = result || '';\r\n let parsedSummary = '';\r\n try {\r\n if (result) {\r\n const json = JSON.parse(result);\r\n parsedResult = json.result || result;\r\n parsedSummary = json.summary || '';\r\n }\r\n } catch {\r\n // Not JSON, use raw result as-is\r\n }\r\n\r\n const hasChanges = !parsedResult.includes('No changes') && !parsedSummary.includes('No changes');\r\n const truncated = parsedResult.includes('[Diff truncated');\r\n\r\n // Build display summary from parsed data\r\n let displayInfo = 'no changes';\r\n if (hasChanges) {\r\n if (parsedSummary) {\r\n displayInfo = parsedSummary;\r\n } else {\r\n // Fallback: extract file count from result text (format: **N file(s) changed**)\r\n const filesMatch = parsedResult.match(/(\\d+)\\s+file\\(?s?\\)?\\s+changed/);\r\n displayInfo = filesMatch ? `${filesMatch[1]} file(s) changed` : 'changes detected';\r\n }\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"#00cc66\" paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} Checked diff {diffTarget ? `for ${diffTarget} ` : ''}{stagedText}</Text>\r\n <Text color=\"#666666\">({displayInfo}{truncated ? ', truncated' : ''})</Text>\r\n </Box>\r\n </Box>\r\n );\r\n }\r\n\r\n // ADD_MCP - show server name, connection status, and tool count\r\n if (toolName === 'add_mcp' && toolArgs) {\r\n const serverName = toolArgs.name || 'unknown';\r\n const isSuccess = result && result.includes('SUCCESS');\r\n const borderColor = isSuccess ? '#9945FF' : '#ff3366';\r\n const statusIcon = isSuccess ? '✓' : '✗';\r\n const statusColor = isSuccess ? '#00cc66' : '#ff3366';\r\n\r\n // Extract tool count from result\r\n let toolCount = '';\r\n const toolCountMatch = result?.match(/Available tools \\((\\d+)\\)/);\r\n if (toolCountMatch) {\r\n toolCount = ` (${toolCountMatch[1]} tools)`;\r\n }\r\n\r\n // Extract error from result for failure case\r\n let errorMsg = '';\r\n if (!isSuccess) {\r\n const errorMatch = result?.match(/Error: (.+)/);\r\n if (errorMatch) {\r\n errorMsg = errorMatch[1];\r\n }\r\n }\r\n\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={borderColor} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color={statusColor} bold>{statusIcon} 🔌 {isSuccess ? 'Connected' : 'Failed'} MCP server </Text>\r\n <Text color=\"#cc99ff\" bold>{serverName}</Text>\r\n {toolCount && <Text color=\"#666666\">{toolCount}</Text>}\r\n </Box>\r\n {errorMsg && (\r\n <Box paddingLeft={2}>\r\n <Text color=\"#ff6699\">{errorMsg}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n // DEFAULT - for any other tool\r\n return renderWithThinking(\r\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor={theme.accent} paddingX={1} marginBottom={1} flexGrow={0} alignSelf=\"flex-start\">\r\n <Box flexWrap=\"wrap\">\r\n <Text color=\"#00cc66\" bold>✓ {toolInfo.emoji} {toolInfo.verb}</Text>\r\n </Box>\r\n {result && result.length < 300 && (\r\n <Box paddingLeft={1} marginTop={1}>\r\n <Text color=\"#aaaaaa\">{result}</Text>\r\n </Box>\r\n )}\r\n </Box>\r\n );\r\n }\r\n\r\n return null;\r\n}, (prevProps, nextProps) => {\r\n // Only re-render if the status or key fields changed\r\n const prevExec = prevProps.message.toolExecution;\r\n const nextExec = nextProps.message.toolExecution;\r\n\r\n if (!prevExec || !nextExec) return false;\r\n\r\n return prevExec.status === nextExec.status &&\r\n prevExec.toolName === nextExec.toolName &&\r\n prevExec.result === nextExec.result &&\r\n prevExec.error === nextExec.error &&\r\n prevExec.streamingOutput === nextExec.streamingOutput;\r\n});\r\n"],"mappings":"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","names":["lines","status"]}