centaurus-cli 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (552) hide show
  1. package/dist/ai/types.js +0 -1
  2. package/dist/ai/types.js.map +1 -1
  3. package/dist/cli-adapter.js +5047 -5037
  4. package/dist/cli-adapter.js.map +1 -1
  5. package/dist/commands/CommandParser.js +372 -315
  6. package/dist/commands/CommandParser.js.map +1 -1
  7. package/dist/config/build-config.js +11 -42
  8. package/dist/config/build-config.js.map +1 -1
  9. package/dist/config/defaultConfig.js +94 -82
  10. package/dist/config/defaultConfig.js.map +1 -1
  11. package/dist/config/manager.js +144 -160
  12. package/dist/config/manager.js.map +1 -1
  13. package/dist/config/mcp-config-manager.js +411 -364
  14. package/dist/config/mcp-config-manager.js.map +1 -1
  15. package/dist/config/models.js +118 -185
  16. package/dist/config/models.js.map +1 -1
  17. package/dist/config/slash-commands.js +186 -184
  18. package/dist/config/slash-commands.js.map +1 -1
  19. package/dist/config/types.js +33 -26
  20. package/dist/config/types.js.map +1 -1
  21. package/dist/context/command-detector.js +63 -67
  22. package/dist/context/command-detector.js.map +1 -1
  23. package/dist/context/context-manager.js +533 -518
  24. package/dist/context/context-manager.js.map +1 -1
  25. package/dist/context/handlers/docker-handler.js +518 -576
  26. package/dist/context/handlers/docker-handler.js.map +1 -1
  27. package/dist/context/handlers/ssh-handler.js +1050 -1109
  28. package/dist/context/handlers/ssh-handler.js.map +1 -1
  29. package/dist/context/handlers/wsl-handler.js +558 -630
  30. package/dist/context/handlers/wsl-handler.js.map +1 -1
  31. package/dist/context/index.js +42 -6
  32. package/dist/context/index.js.map +1 -1
  33. package/dist/context/subshell-handler.js +0 -4
  34. package/dist/context/subshell-handler.js.map +1 -1
  35. package/dist/context/types.js +20 -31
  36. package/dist/context/types.js.map +1 -1
  37. package/dist/hooks/useConnectivity.js +13 -10
  38. package/dist/hooks/useConnectivity.js.map +1 -1
  39. package/dist/hooks/useTerminalDimensions.js +67 -79
  40. package/dist/hooks/useTerminalDimensions.js.map +1 -1
  41. package/dist/index.js +228 -251
  42. package/dist/index.js.map +1 -1
  43. package/dist/mcp/mcp-command-handler.js +297 -260
  44. package/dist/mcp/mcp-command-handler.js.map +1 -1
  45. package/dist/mcp/mcp-server-manager.js +139 -155
  46. package/dist/mcp/mcp-server-manager.js.map +1 -1
  47. package/dist/mcp/mcp-tool-wrapper.js +74 -94
  48. package/dist/mcp/mcp-tool-wrapper.js.map +1 -1
  49. package/dist/services/ai-autocomplete-agent.js +169 -181
  50. package/dist/services/ai-autocomplete-agent.js.map +1 -1
  51. package/dist/services/ai-context-injector.js +180 -93
  52. package/dist/services/ai-context-injector.js.map +1 -1
  53. package/dist/services/ai-service-client.js +513 -456
  54. package/dist/services/ai-service-client.js.map +1 -1
  55. package/dist/services/api-client.js +443 -441
  56. package/dist/services/api-client.js.map +1 -1
  57. package/dist/services/auth-handler.js +162 -198
  58. package/dist/services/auth-handler.js.map +1 -1
  59. package/dist/services/background-task-manager.js +258 -282
  60. package/dist/services/background-task-manager.js.map +1 -1
  61. package/dist/services/checkpoint-manager.js +1513 -973
  62. package/dist/services/checkpoint-manager.js.map +1 -1
  63. package/dist/services/clipboard-service.js +151 -200
  64. package/dist/services/clipboard-service.js.map +1 -1
  65. package/dist/services/connectivity-manager.js +63 -65
  66. package/dist/services/connectivity-manager.js.map +1 -1
  67. package/dist/services/conversation-manager.js +118 -121
  68. package/dist/services/conversation-manager.js.map +1 -1
  69. package/dist/services/environment-context-injector.js +160 -187
  70. package/dist/services/environment-context-injector.js.map +1 -1
  71. package/dist/services/fast-context-agent.js +203 -243
  72. package/dist/services/fast-context-agent.js.map +1 -1
  73. package/dist/services/input-detection-agent.js +190 -202
  74. package/dist/services/input-detection-agent.js.map +1 -1
  75. package/dist/services/input-requirement-detector.js +155 -189
  76. package/dist/services/input-requirement-detector.js.map +1 -1
  77. package/dist/services/local-chat-storage.js +342 -365
  78. package/dist/services/local-chat-storage.js.map +1 -1
  79. package/dist/services/monitored-shell-manager.js +225 -233
  80. package/dist/services/monitored-shell-manager.js.map +1 -1
  81. package/dist/services/ollama-service.js +293 -310
  82. package/dist/services/ollama-service.js.map +1 -1
  83. package/dist/services/rules-storage.js +142 -0
  84. package/dist/services/rules-storage.js.map +1 -0
  85. package/dist/services/session-quota-manager.js +219 -235
  86. package/dist/services/session-quota-manager.js.map +1 -1
  87. package/dist/services/shell-input-agent.js +299 -334
  88. package/dist/services/shell-input-agent.js.map +1 -1
  89. package/dist/services/sub-agent-manager.js +459 -501
  90. package/dist/services/sub-agent-manager.js.map +1 -1
  91. package/dist/services/warpify-detector.js +133 -183
  92. package/dist/services/warpify-detector.js.map +1 -1
  93. package/dist/services/workflow-storage.js +202 -217
  94. package/dist/services/workflow-storage.js.map +1 -1
  95. package/dist/test-ssh-handler.js +148 -193
  96. package/dist/test-ssh-handler.js.map +1 -1
  97. package/dist/tools/add-mcp.js +161 -0
  98. package/dist/tools/add-mcp.js.map +1 -0
  99. package/dist/tools/background-command.js +240 -273
  100. package/dist/tools/background-command.js.map +1 -1
  101. package/dist/tools/command.js +447 -440
  102. package/dist/tools/command.js.map +1 -1
  103. package/dist/tools/create-image.js +172 -202
  104. package/dist/tools/create-image.js.map +1 -1
  105. package/dist/tools/enter-remote-session.js +169 -215
  106. package/dist/tools/enter-remote-session.js.map +1 -1
  107. package/dist/tools/fast-context.js +60 -67
  108. package/dist/tools/fast-context.js.map +1 -1
  109. package/dist/tools/file-ops.js +605 -537
  110. package/dist/tools/file-ops.js.map +1 -1
  111. package/dist/tools/find-files.js +262 -303
  112. package/dist/tools/find-files.js.map +1 -1
  113. package/dist/tools/get-diff.js +423 -400
  114. package/dist/tools/get-diff.js.map +1 -1
  115. package/dist/tools/grep-search.js +966 -948
  116. package/dist/tools/grep-search.js.map +1 -1
  117. package/dist/tools/inspect-symbol.js +308 -323
  118. package/dist/tools/inspect-symbol.js.map +1 -1
  119. package/dist/tools/plan-mode.js +459 -503
  120. package/dist/tools/plan-mode.js.map +1 -1
  121. package/dist/tools/read-binary-file.js +160 -190
  122. package/dist/tools/read-binary-file.js.map +1 -1
  123. package/dist/tools/registry.js +100 -84
  124. package/dist/tools/registry.js.map +1 -1
  125. package/dist/tools/reproduce_issue.js +170 -151
  126. package/dist/tools/reproduce_issue.js.map +1 -1
  127. package/dist/tools/sub-agent.js +223 -228
  128. package/dist/tools/sub-agent.js.map +1 -1
  129. package/dist/tools/task-complete.js +28 -27
  130. package/dist/tools/task-complete.js.map +1 -1
  131. package/dist/tools/types.js +0 -1
  132. package/dist/tools/types.js.map +1 -1
  133. package/dist/tools/validation.js +96 -118
  134. package/dist/tools/validation.js.map +1 -1
  135. package/dist/tools/web-search.js +194 -194
  136. package/dist/tools/web-search.js.map +1 -1
  137. package/dist/tools/workflow-tool.js +77 -82
  138. package/dist/tools/workflow-tool.js.map +1 -1
  139. package/dist/types/index.js +0 -1
  140. package/dist/types/index.js.map +1 -1
  141. package/dist/types/rule.js +1 -0
  142. package/dist/types/rule.js.map +1 -0
  143. package/dist/types/workflow.js +0 -7
  144. package/dist/types/workflow.js.map +1 -1
  145. package/dist/ui/components/AgentTimer.js +24 -25
  146. package/dist/ui/components/AgentTimer.js.map +1 -1
  147. package/dist/ui/components/App.js +3266 -3249
  148. package/dist/ui/components/App.js.map +1 -1
  149. package/dist/ui/components/AuthScreen.js +22 -34
  150. package/dist/ui/components/AuthScreen.js.map +1 -1
  151. package/dist/ui/components/AuthWelcomeScreen.js +30 -24
  152. package/dist/ui/components/AuthWelcomeScreen.js.map +1 -1
  153. package/dist/ui/components/Breadcrumbs.js +53 -82
  154. package/dist/ui/components/Breadcrumbs.js.map +1 -1
  155. package/dist/ui/components/CircularSelectInput.js +59 -67
  156. package/dist/ui/components/CircularSelectInput.js.map +1 -1
  157. package/dist/ui/components/ClipboardFileAutocomplete.js +78 -39
  158. package/dist/ui/components/ClipboardFileAutocomplete.js.map +1 -1
  159. package/dist/ui/components/CodeBlock.js +24 -42
  160. package/dist/ui/components/CodeBlock.js.map +1 -1
  161. package/dist/ui/components/ConfigViewer.js +18 -25
  162. package/dist/ui/components/ConfigViewer.js.map +1 -1
  163. package/dist/ui/components/ConfirmPrompt.js +49 -71
  164. package/dist/ui/components/ConfirmPrompt.js.map +1 -1
  165. package/dist/ui/components/ConnectionStatusMessage.js +32 -83
  166. package/dist/ui/components/ConnectionStatusMessage.js.map +1 -1
  167. package/dist/ui/components/ContextWindowIndicator.js +34 -49
  168. package/dist/ui/components/ContextWindowIndicator.js.map +1 -1
  169. package/dist/ui/components/DetailedPlanReviewScreen.js +104 -106
  170. package/dist/ui/components/DetailedPlanReviewScreen.js.map +1 -1
  171. package/dist/ui/components/DiffViewer.js +68 -121
  172. package/dist/ui/components/DiffViewer.js.map +1 -1
  173. package/dist/ui/components/ErrorBoundary.js +40 -48
  174. package/dist/ui/components/ErrorBoundary.js.map +1 -1
  175. package/dist/ui/components/FileCreationPreview.js +29 -60
  176. package/dist/ui/components/FileCreationPreview.js.map +1 -1
  177. package/dist/ui/components/FileOperation.js +34 -29
  178. package/dist/ui/components/FileOperation.js.map +1 -1
  179. package/dist/ui/components/FileTagAutocomplete.js +55 -25
  180. package/dist/ui/components/FileTagAutocomplete.js.map +1 -1
  181. package/dist/ui/components/FontRecommendation.js.map +1 -1
  182. package/dist/ui/components/GitDiffBreadcrumb.js +29 -0
  183. package/dist/ui/components/GitDiffBreadcrumb.js.map +1 -0
  184. package/dist/ui/components/InputBox.js +1620 -2150
  185. package/dist/ui/components/InputBox.js.map +1 -1
  186. package/dist/ui/components/InteractiveShell.js +234 -352
  187. package/dist/ui/components/InteractiveShell.js.map +1 -1
  188. package/dist/ui/components/KeyboardHelp.js +34 -35
  189. package/dist/ui/components/KeyboardHelp.js.map +1 -1
  190. package/dist/ui/components/LoadingIndicator.js +22 -25
  191. package/dist/ui/components/LoadingIndicator.js.map +1 -1
  192. package/dist/ui/components/MCPAddScreen.js +40 -51
  193. package/dist/ui/components/MCPAddScreen.js.map +1 -1
  194. package/dist/ui/components/MCPListScreen.js +40 -48
  195. package/dist/ui/components/MCPListScreen.js.map +1 -1
  196. package/dist/ui/components/MCPServerListScreen.js +49 -56
  197. package/dist/ui/components/MCPServerListScreen.js.map +1 -1
  198. package/dist/ui/components/MarkdownRenderer.js +69 -96
  199. package/dist/ui/components/MarkdownRenderer.js.map +1 -1
  200. package/dist/ui/components/MessageBox.js +66 -48
  201. package/dist/ui/components/MessageBox.js.map +1 -1
  202. package/dist/ui/components/MessageDisplay.js +150 -142
  203. package/dist/ui/components/MessageDisplay.js.map +1 -1
  204. package/dist/ui/components/MonitorModeAIPanel.js +46 -65
  205. package/dist/ui/components/MonitorModeAIPanel.js.map +1 -1
  206. package/dist/ui/components/MultiLineInput.js +243 -277
  207. package/dist/ui/components/MultiLineInput.js.map +1 -1
  208. package/dist/ui/components/PasswordPrompt.js +37 -18
  209. package/dist/ui/components/PasswordPrompt.js.map +1 -1
  210. package/dist/ui/components/PlanAcceptedMessage.js +27 -38
  211. package/dist/ui/components/PlanAcceptedMessage.js.map +1 -1
  212. package/dist/ui/components/PlanReviewScreen.js +46 -50
  213. package/dist/ui/components/PlanReviewScreen.js.map +1 -1
  214. package/dist/ui/components/RulesEditorScreen.js +81 -0
  215. package/dist/ui/components/RulesEditorScreen.js.map +1 -0
  216. package/dist/ui/components/SelectPrompt.js +19 -8
  217. package/dist/ui/components/SelectPrompt.js.map +1 -1
  218. package/dist/ui/components/ShimmerText.js +44 -0
  219. package/dist/ui/components/ShimmerText.js.map +1 -0
  220. package/dist/ui/components/SlashCommandAutocomplete.js +49 -22
  221. package/dist/ui/components/SlashCommandAutocomplete.js.map +1 -1
  222. package/dist/ui/components/StatusBar.js +56 -87
  223. package/dist/ui/components/StatusBar.js.map +1 -1
  224. package/dist/ui/components/StreamingMessageDisplay.js +116 -99
  225. package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
  226. package/dist/ui/components/TaskCompletedMessage.js +28 -23
  227. package/dist/ui/components/TaskCompletedMessage.js.map +1 -1
  228. package/dist/ui/components/TaskProgressIndicator.js +44 -70
  229. package/dist/ui/components/TaskProgressIndicator.js.map +1 -1
  230. package/dist/ui/components/ThinkingDisplay.js +44 -41
  231. package/dist/ui/components/ThinkingDisplay.js.map +1 -1
  232. package/dist/ui/components/ToolExecutionMessage.js +772 -1326
  233. package/dist/ui/components/ToolExecutionMessage.js.map +1 -1
  234. package/dist/ui/components/ToolExecutionStatus.js +53 -84
  235. package/dist/ui/components/ToolExecutionStatus.js.map +1 -1
  236. package/dist/ui/components/ToolResult.js +22 -15
  237. package/dist/ui/components/ToolResult.js.map +1 -1
  238. package/dist/ui/components/VersionUpdatePrompt.js +88 -120
  239. package/dist/ui/components/VersionUpdatePrompt.js.map +1 -1
  240. package/dist/ui/components/WelcomeBanner.js +176 -26
  241. package/dist/ui/components/WelcomeBanner.js.map +1 -1
  242. package/dist/ui/components/WorkflowCreatorScreen.js +94 -161
  243. package/dist/ui/components/WorkflowCreatorScreen.js.map +1 -1
  244. package/dist/utils/ansi-encoder.js +30 -61
  245. package/dist/utils/ansi-encoder.js.map +1 -1
  246. package/dist/utils/chat-formatter.js +327 -305
  247. package/dist/utils/chat-formatter.js.map +1 -1
  248. package/dist/utils/command-history.js +152 -174
  249. package/dist/utils/command-history.js.map +1 -1
  250. package/dist/utils/context-sanitizer.js +49 -112
  251. package/dist/utils/context-sanitizer.js.map +1 -1
  252. package/dist/utils/conversation-logger.js +292 -324
  253. package/dist/utils/conversation-logger.js.map +1 -1
  254. package/dist/utils/custom-commands-manager.js +126 -131
  255. package/dist/utils/custom-commands-manager.js.map +1 -1
  256. package/dist/utils/editor-utils.js +732 -837
  257. package/dist/utils/editor-utils.js.map +1 -1
  258. package/dist/utils/file.js +174 -213
  259. package/dist/utils/file.js.map +1 -1
  260. package/dist/utils/git-stats.js +169 -0
  261. package/dist/utils/git-stats.js.map +1 -0
  262. package/dist/utils/input-classifier.js +960 -482
  263. package/dist/utils/input-classifier.js.map +1 -1
  264. package/dist/utils/logger.js +48 -73
  265. package/dist/utils/logger.js.map +1 -1
  266. package/dist/utils/markdown-parser.js +277 -310
  267. package/dist/utils/markdown-parser.js.map +1 -1
  268. package/dist/utils/rule-reference-resolver.js +54 -0
  269. package/dist/utils/rule-reference-resolver.js.map +1 -0
  270. package/dist/utils/shell.js +144 -156
  271. package/dist/utils/shell.js.map +1 -1
  272. package/dist/utils/state.js +23 -22
  273. package/dist/utils/state.js.map +1 -1
  274. package/dist/utils/syntax-checker.js +279 -327
  275. package/dist/utils/syntax-checker.js.map +1 -1
  276. package/dist/utils/terminal-output.js +199 -302
  277. package/dist/utils/terminal-output.js.map +1 -1
  278. package/dist/utils/text-clipboard.js +47 -70
  279. package/dist/utils/text-clipboard.js.map +1 -1
  280. package/dist/utils/unicode-sanitizer.js +134 -197
  281. package/dist/utils/unicode-sanitizer.js.map +1 -1
  282. package/dist/utils/version-checker.js +46 -56
  283. package/dist/utils/version-checker.js.map +1 -1
  284. package/package.json +6 -4
  285. package/dist/ai/types.d.ts +0 -20
  286. package/dist/ai/types.d.ts.map +0 -1
  287. package/dist/cli-adapter.d.ts +0 -511
  288. package/dist/cli-adapter.d.ts.map +0 -1
  289. package/dist/commands/CommandParser.d.ts +0 -27
  290. package/dist/commands/CommandParser.d.ts.map +0 -1
  291. package/dist/config/build-config.d.ts +0 -42
  292. package/dist/config/build-config.d.ts.map +0 -1
  293. package/dist/config/defaultConfig.d.ts +0 -79
  294. package/dist/config/defaultConfig.d.ts.map +0 -1
  295. package/dist/config/manager.d.ts +0 -62
  296. package/dist/config/manager.d.ts.map +0 -1
  297. package/dist/config/mcp-config-manager.d.ts +0 -79
  298. package/dist/config/mcp-config-manager.d.ts.map +0 -1
  299. package/dist/config/models.d.ts +0 -83
  300. package/dist/config/models.d.ts.map +0 -1
  301. package/dist/config/slash-commands.d.ts +0 -23
  302. package/dist/config/slash-commands.d.ts.map +0 -1
  303. package/dist/config/types.d.ts +0 -35
  304. package/dist/config/types.d.ts.map +0 -1
  305. package/dist/context/command-detector.d.ts +0 -50
  306. package/dist/context/command-detector.d.ts.map +0 -1
  307. package/dist/context/context-manager.d.ts +0 -157
  308. package/dist/context/context-manager.d.ts.map +0 -1
  309. package/dist/context/handlers/docker-handler.d.ts +0 -130
  310. package/dist/context/handlers/docker-handler.d.ts.map +0 -1
  311. package/dist/context/handlers/ssh-handler.d.ts +0 -201
  312. package/dist/context/handlers/ssh-handler.d.ts.map +0 -1
  313. package/dist/context/handlers/wsl-handler.d.ts +0 -146
  314. package/dist/context/handlers/wsl-handler.d.ts.map +0 -1
  315. package/dist/context/index.d.ts +0 -8
  316. package/dist/context/index.d.ts.map +0 -1
  317. package/dist/context/subshell-handler.d.ts +0 -165
  318. package/dist/context/subshell-handler.d.ts.map +0 -1
  319. package/dist/context/types.d.ts +0 -70
  320. package/dist/context/types.d.ts.map +0 -1
  321. package/dist/hooks/useConnectivity.d.ts +0 -2
  322. package/dist/hooks/useConnectivity.d.ts.map +0 -1
  323. package/dist/hooks/useTerminalDimensions.d.ts +0 -41
  324. package/dist/hooks/useTerminalDimensions.d.ts.map +0 -1
  325. package/dist/index.d.ts +0 -9
  326. package/dist/index.d.ts.map +0 -1
  327. package/dist/mcp/mcp-command-handler.d.ts +0 -47
  328. package/dist/mcp/mcp-command-handler.d.ts.map +0 -1
  329. package/dist/mcp/mcp-server-manager.d.ts +0 -30
  330. package/dist/mcp/mcp-server-manager.d.ts.map +0 -1
  331. package/dist/mcp/mcp-tool-wrapper.d.ts +0 -12
  332. package/dist/mcp/mcp-tool-wrapper.d.ts.map +0 -1
  333. package/dist/services/ai-autocomplete-agent.d.ts +0 -39
  334. package/dist/services/ai-autocomplete-agent.d.ts.map +0 -1
  335. package/dist/services/ai-context-injector.d.ts +0 -41
  336. package/dist/services/ai-context-injector.d.ts.map +0 -1
  337. package/dist/services/ai-service-client.d.ts +0 -128
  338. package/dist/services/ai-service-client.d.ts.map +0 -1
  339. package/dist/services/api-client.d.ts +0 -353
  340. package/dist/services/api-client.d.ts.map +0 -1
  341. package/dist/services/auth-handler.d.ts +0 -30
  342. package/dist/services/auth-handler.d.ts.map +0 -1
  343. package/dist/services/background-task-manager.d.ts +0 -114
  344. package/dist/services/background-task-manager.d.ts.map +0 -1
  345. package/dist/services/checkpoint-manager.d.ts +0 -167
  346. package/dist/services/checkpoint-manager.d.ts.map +0 -1
  347. package/dist/services/clipboard-service.d.ts +0 -37
  348. package/dist/services/clipboard-service.d.ts.map +0 -1
  349. package/dist/services/connectivity-manager.d.ts +0 -18
  350. package/dist/services/connectivity-manager.d.ts.map +0 -1
  351. package/dist/services/conversation-manager.d.ts +0 -73
  352. package/dist/services/conversation-manager.d.ts.map +0 -1
  353. package/dist/services/environment-context-injector.d.ts +0 -69
  354. package/dist/services/environment-context-injector.d.ts.map +0 -1
  355. package/dist/services/fast-context-agent.d.ts +0 -12
  356. package/dist/services/fast-context-agent.d.ts.map +0 -1
  357. package/dist/services/input-detection-agent.d.ts +0 -40
  358. package/dist/services/input-detection-agent.d.ts.map +0 -1
  359. package/dist/services/input-requirement-detector.d.ts +0 -28
  360. package/dist/services/input-requirement-detector.d.ts.map +0 -1
  361. package/dist/services/local-chat-storage.d.ts +0 -182
  362. package/dist/services/local-chat-storage.d.ts.map +0 -1
  363. package/dist/services/monitored-shell-manager.d.ts +0 -120
  364. package/dist/services/monitored-shell-manager.d.ts.map +0 -1
  365. package/dist/services/ollama-service.d.ts +0 -197
  366. package/dist/services/ollama-service.d.ts.map +0 -1
  367. package/dist/services/session-quota-manager.d.ts +0 -101
  368. package/dist/services/session-quota-manager.d.ts.map +0 -1
  369. package/dist/services/shell-input-agent.d.ts +0 -89
  370. package/dist/services/shell-input-agent.d.ts.map +0 -1
  371. package/dist/services/sub-agent-manager.d.ts +0 -140
  372. package/dist/services/sub-agent-manager.d.ts.map +0 -1
  373. package/dist/services/warpify-detector.d.ts +0 -43
  374. package/dist/services/warpify-detector.d.ts.map +0 -1
  375. package/dist/services/workflow-storage.d.ts +0 -72
  376. package/dist/services/workflow-storage.d.ts.map +0 -1
  377. package/dist/test-ssh-handler.d.ts +0 -8
  378. package/dist/test-ssh-handler.d.ts.map +0 -1
  379. package/dist/tools/background-command.d.ts +0 -11
  380. package/dist/tools/background-command.d.ts.map +0 -1
  381. package/dist/tools/command.d.ts +0 -3
  382. package/dist/tools/command.d.ts.map +0 -1
  383. package/dist/tools/create-image.d.ts +0 -10
  384. package/dist/tools/create-image.d.ts.map +0 -1
  385. package/dist/tools/enter-remote-session.d.ts +0 -48
  386. package/dist/tools/enter-remote-session.d.ts.map +0 -1
  387. package/dist/tools/fast-context.d.ts +0 -3
  388. package/dist/tools/fast-context.d.ts.map +0 -1
  389. package/dist/tools/file-ops.d.ts +0 -7
  390. package/dist/tools/file-ops.d.ts.map +0 -1
  391. package/dist/tools/find-files.d.ts +0 -49
  392. package/dist/tools/find-files.d.ts.map +0 -1
  393. package/dist/tools/get-diff.d.ts +0 -14
  394. package/dist/tools/get-diff.d.ts.map +0 -1
  395. package/dist/tools/grep-search.d.ts +0 -155
  396. package/dist/tools/grep-search.d.ts.map +0 -1
  397. package/dist/tools/inspect-symbol.d.ts +0 -32
  398. package/dist/tools/inspect-symbol.d.ts.map +0 -1
  399. package/dist/tools/plan-mode.d.ts +0 -140
  400. package/dist/tools/plan-mode.d.ts.map +0 -1
  401. package/dist/tools/read-binary-file.d.ts +0 -10
  402. package/dist/tools/read-binary-file.d.ts.map +0 -1
  403. package/dist/tools/registry.d.ts +0 -31
  404. package/dist/tools/registry.d.ts.map +0 -1
  405. package/dist/tools/reproduce_issue.d.ts +0 -2
  406. package/dist/tools/reproduce_issue.d.ts.map +0 -1
  407. package/dist/tools/sub-agent.d.ts +0 -9
  408. package/dist/tools/sub-agent.d.ts.map +0 -1
  409. package/dist/tools/task-complete.d.ts +0 -3
  410. package/dist/tools/task-complete.d.ts.map +0 -1
  411. package/dist/tools/types.d.ts +0 -40
  412. package/dist/tools/types.d.ts.map +0 -1
  413. package/dist/tools/validation.d.ts +0 -47
  414. package/dist/tools/validation.d.ts.map +0 -1
  415. package/dist/tools/web-search.d.ts +0 -24
  416. package/dist/tools/web-search.d.ts.map +0 -1
  417. package/dist/tools/workflow-tool.d.ts +0 -11
  418. package/dist/tools/workflow-tool.d.ts.map +0 -1
  419. package/dist/types/index.d.ts +0 -123
  420. package/dist/types/index.d.ts.map +0 -1
  421. package/dist/types/workflow.d.ts +0 -110
  422. package/dist/types/workflow.d.ts.map +0 -1
  423. package/dist/ui/components/AgentTimer.d.ts +0 -7
  424. package/dist/ui/components/AgentTimer.d.ts.map +0 -1
  425. package/dist/ui/components/App.d.ts +0 -197
  426. package/dist/ui/components/App.d.ts.map +0 -1
  427. package/dist/ui/components/AuthScreen.d.ts +0 -8
  428. package/dist/ui/components/AuthScreen.d.ts.map +0 -1
  429. package/dist/ui/components/AuthWelcomeScreen.d.ts +0 -8
  430. package/dist/ui/components/AuthWelcomeScreen.d.ts.map +0 -1
  431. package/dist/ui/components/Breadcrumbs.d.ts +0 -13
  432. package/dist/ui/components/Breadcrumbs.d.ts.map +0 -1
  433. package/dist/ui/components/CircularSelectInput.d.ts +0 -24
  434. package/dist/ui/components/CircularSelectInput.d.ts.map +0 -1
  435. package/dist/ui/components/ClipboardFileAutocomplete.d.ts +0 -10
  436. package/dist/ui/components/ClipboardFileAutocomplete.d.ts.map +0 -1
  437. package/dist/ui/components/CodeBlock.d.ts +0 -9
  438. package/dist/ui/components/CodeBlock.d.ts.map +0 -1
  439. package/dist/ui/components/ConfigViewer.d.ts +0 -11
  440. package/dist/ui/components/ConfigViewer.d.ts.map +0 -1
  441. package/dist/ui/components/ConfirmPrompt.d.ts +0 -13
  442. package/dist/ui/components/ConfirmPrompt.d.ts.map +0 -1
  443. package/dist/ui/components/ConnectionStatusMessage.d.ts +0 -17
  444. package/dist/ui/components/ConnectionStatusMessage.d.ts.map +0 -1
  445. package/dist/ui/components/ContextWindowIndicator.d.ts +0 -8
  446. package/dist/ui/components/ContextWindowIndicator.d.ts.map +0 -1
  447. package/dist/ui/components/DetailedPlanReviewScreen.d.ts +0 -17
  448. package/dist/ui/components/DetailedPlanReviewScreen.d.ts.map +0 -1
  449. package/dist/ui/components/DiffViewer.d.ts +0 -9
  450. package/dist/ui/components/DiffViewer.d.ts.map +0 -1
  451. package/dist/ui/components/ErrorBoundary.d.ts +0 -17
  452. package/dist/ui/components/ErrorBoundary.d.ts.map +0 -1
  453. package/dist/ui/components/FileCreationPreview.d.ts +0 -8
  454. package/dist/ui/components/FileCreationPreview.d.ts.map +0 -1
  455. package/dist/ui/components/FileOperation.d.ts +0 -10
  456. package/dist/ui/components/FileOperation.d.ts.map +0 -1
  457. package/dist/ui/components/FileTagAutocomplete.d.ts +0 -11
  458. package/dist/ui/components/FileTagAutocomplete.d.ts.map +0 -1
  459. package/dist/ui/components/FontRecommendation.d.ts +0 -1
  460. package/dist/ui/components/FontRecommendation.d.ts.map +0 -1
  461. package/dist/ui/components/InputBox.d.ts +0 -42
  462. package/dist/ui/components/InputBox.d.ts.map +0 -1
  463. package/dist/ui/components/InteractiveShell.d.ts +0 -30
  464. package/dist/ui/components/InteractiveShell.d.ts.map +0 -1
  465. package/dist/ui/components/KeyboardHelp.d.ts +0 -7
  466. package/dist/ui/components/KeyboardHelp.d.ts.map +0 -1
  467. package/dist/ui/components/LoadingIndicator.d.ts +0 -3
  468. package/dist/ui/components/LoadingIndicator.d.ts.map +0 -1
  469. package/dist/ui/components/MCPAddScreen.d.ts +0 -13
  470. package/dist/ui/components/MCPAddScreen.d.ts.map +0 -1
  471. package/dist/ui/components/MCPListScreen.d.ts +0 -17
  472. package/dist/ui/components/MCPListScreen.d.ts.map +0 -1
  473. package/dist/ui/components/MCPServerListScreen.d.ts +0 -16
  474. package/dist/ui/components/MCPServerListScreen.d.ts.map +0 -1
  475. package/dist/ui/components/MarkdownRenderer.d.ts +0 -8
  476. package/dist/ui/components/MarkdownRenderer.d.ts.map +0 -1
  477. package/dist/ui/components/MessageBox.d.ts +0 -10
  478. package/dist/ui/components/MessageBox.d.ts.map +0 -1
  479. package/dist/ui/components/MessageDisplay.d.ts +0 -14
  480. package/dist/ui/components/MessageDisplay.d.ts.map +0 -1
  481. package/dist/ui/components/MonitorModeAIPanel.d.ts +0 -23
  482. package/dist/ui/components/MonitorModeAIPanel.d.ts.map +0 -1
  483. package/dist/ui/components/MultiLineInput.d.ts +0 -13
  484. package/dist/ui/components/MultiLineInput.d.ts.map +0 -1
  485. package/dist/ui/components/PasswordPrompt.d.ts +0 -9
  486. package/dist/ui/components/PasswordPrompt.d.ts.map +0 -1
  487. package/dist/ui/components/PlanAcceptedMessage.d.ts +0 -20
  488. package/dist/ui/components/PlanAcceptedMessage.d.ts.map +0 -1
  489. package/dist/ui/components/PlanReviewScreen.d.ts +0 -14
  490. package/dist/ui/components/PlanReviewScreen.d.ts.map +0 -1
  491. package/dist/ui/components/SelectPrompt.d.ts +0 -12
  492. package/dist/ui/components/SelectPrompt.d.ts.map +0 -1
  493. package/dist/ui/components/SlashCommandAutocomplete.d.ts +0 -13
  494. package/dist/ui/components/SlashCommandAutocomplete.d.ts.map +0 -1
  495. package/dist/ui/components/StatusBar.d.ts +0 -14
  496. package/dist/ui/components/StatusBar.d.ts.map +0 -1
  497. package/dist/ui/components/StreamingMessageDisplay.d.ts +0 -15
  498. package/dist/ui/components/StreamingMessageDisplay.d.ts.map +0 -1
  499. package/dist/ui/components/TaskCompletedMessage.d.ts +0 -14
  500. package/dist/ui/components/TaskCompletedMessage.d.ts.map +0 -1
  501. package/dist/ui/components/TaskProgressIndicator.d.ts +0 -18
  502. package/dist/ui/components/TaskProgressIndicator.d.ts.map +0 -1
  503. package/dist/ui/components/ThinkingDisplay.d.ts +0 -15
  504. package/dist/ui/components/ThinkingDisplay.d.ts.map +0 -1
  505. package/dist/ui/components/ToolExecutionMessage.d.ts +0 -8
  506. package/dist/ui/components/ToolExecutionMessage.d.ts.map +0 -1
  507. package/dist/ui/components/ToolExecutionStatus.d.ts +0 -10
  508. package/dist/ui/components/ToolExecutionStatus.d.ts.map +0 -1
  509. package/dist/ui/components/ToolResult.d.ts +0 -10
  510. package/dist/ui/components/ToolResult.d.ts.map +0 -1
  511. package/dist/ui/components/VersionUpdatePrompt.d.ts +0 -9
  512. package/dist/ui/components/VersionUpdatePrompt.d.ts.map +0 -1
  513. package/dist/ui/components/WelcomeBanner.d.ts +0 -3
  514. package/dist/ui/components/WelcomeBanner.d.ts.map +0 -1
  515. package/dist/ui/components/WorkflowCreatorScreen.d.ts +0 -25
  516. package/dist/ui/components/WorkflowCreatorScreen.d.ts.map +0 -1
  517. package/dist/utils/ansi-encoder.d.ts +0 -7
  518. package/dist/utils/ansi-encoder.d.ts.map +0 -1
  519. package/dist/utils/chat-formatter.d.ts +0 -12
  520. package/dist/utils/chat-formatter.d.ts.map +0 -1
  521. package/dist/utils/command-history.d.ts +0 -24
  522. package/dist/utils/command-history.d.ts.map +0 -1
  523. package/dist/utils/context-sanitizer.d.ts +0 -50
  524. package/dist/utils/context-sanitizer.d.ts.map +0 -1
  525. package/dist/utils/conversation-logger.d.ts +0 -142
  526. package/dist/utils/conversation-logger.d.ts.map +0 -1
  527. package/dist/utils/custom-commands-manager.d.ts +0 -59
  528. package/dist/utils/custom-commands-manager.d.ts.map +0 -1
  529. package/dist/utils/editor-utils.d.ts +0 -101
  530. package/dist/utils/editor-utils.d.ts.map +0 -1
  531. package/dist/utils/file.d.ts +0 -61
  532. package/dist/utils/file.d.ts.map +0 -1
  533. package/dist/utils/input-classifier.d.ts +0 -25
  534. package/dist/utils/input-classifier.d.ts.map +0 -1
  535. package/dist/utils/logger.d.ts +0 -17
  536. package/dist/utils/logger.d.ts.map +0 -1
  537. package/dist/utils/markdown-parser.d.ts +0 -60
  538. package/dist/utils/markdown-parser.d.ts.map +0 -1
  539. package/dist/utils/shell.d.ts +0 -47
  540. package/dist/utils/shell.d.ts.map +0 -1
  541. package/dist/utils/state.d.ts +0 -13
  542. package/dist/utils/state.d.ts.map +0 -1
  543. package/dist/utils/syntax-checker.d.ts +0 -24
  544. package/dist/utils/syntax-checker.d.ts.map +0 -1
  545. package/dist/utils/terminal-output.d.ts +0 -25
  546. package/dist/utils/terminal-output.d.ts.map +0 -1
  547. package/dist/utils/text-clipboard.d.ts +0 -12
  548. package/dist/utils/text-clipboard.d.ts.map +0 -1
  549. package/dist/utils/unicode-sanitizer.d.ts +0 -44
  550. package/dist/utils/unicode-sanitizer.d.ts.map +0 -1
  551. package/dist/utils/version-checker.d.ts +0 -14
  552. package/dist/utils/version-checker.d.ts.map +0 -1
@@ -1,1370 +1,816 @@
1
- import React from 'react';
2
- import { Box, Text } from 'ink';
3
- import Spinner from 'ink-spinner';
4
- import * as path from 'path';
5
- import { processTerminalOutput } from '../../utils/terminal-output.js';
1
+ import React from "react";
2
+ import { Box, Text } from "ink";
3
+ import Spinner from "ink-spinner";
4
+ import wrapAnsi from "wrap-ansi";
5
+ import stringWidth from "string-width";
6
+ import * as path from "path";
7
+ import { processTerminalOutput } from "../../utils/terminal-output.js";
6
8
  const TOOL_LABELS = {
7
- view_file: { verb: 'Reading file', emoji: '📖' },
8
- write_to_file: { verb: 'Writing file', emoji: '✍️' },
9
- edit_file: { verb: 'Editing file', emoji: '✏️' },
10
- multi_edit_file: { verb: 'Editing file', emoji: '✏️' },
11
- list_dir: { verb: 'Listing directory', emoji: '📁' },
12
- execute_command: { verb: 'Executing command', emoji: '⚡' },
13
- grep_search: { verb: 'Searching files', emoji: '🔍' },
14
- find_files: { verb: 'Finding files', emoji: '🔎' },
15
- web_search: { verb: 'Searching web', emoji: '🌐' },
16
- fetch_url: { verb: 'Fetching URL', emoji: '📡' },
17
- inspect_symbol: { verb: 'Inspecting symbol', emoji: '🔬' },
18
- read_binary_file: { verb: 'Reading binary file', emoji: '📄' },
19
- create_image: { verb: 'Generating image', emoji: '🎨' },
20
- background_command: { verb: 'Background command', emoji: '🔄' },
21
- get_diff: { verb: 'Getting diff', emoji: '📝' },
22
- sub_agent: { verb: 'Agent Task', emoji: '🤖' },
23
- fast_context_search: { verb: 'Searching context', emoji: '⚡' },
9
+ view_file: { verb: "Reading file", emoji: "\u{1F4D6}" },
10
+ write_to_file: { verb: "Writing file", emoji: "" },
11
+ edit_file: { verb: "Editing file", emoji: "" },
12
+ multi_edit_file: { verb: "Editing file", emoji: "" },
13
+ list_dir: { verb: "Listing directory", emoji: "\u{1F4C1}" },
14
+ execute_command: { verb: "Executing command", emoji: "\u26A1" },
15
+ grep_search: { verb: "Searching files", emoji: "\u{1F50D}" },
16
+ find_files: { verb: "Finding files", emoji: "\u{1F50E}" },
17
+ web_search: { verb: "Searching web", emoji: "\u{1F310}" },
18
+ fetch_url: { verb: "Fetching URL", emoji: "\u{1F4E1}" },
19
+ inspect_symbol: { verb: "Inspecting symbol", emoji: "\u{1F52C}" },
20
+ read_binary_file: { verb: "Reading binary file", emoji: "\u{1F4C4}" },
21
+ create_image: { verb: "Generating image", emoji: "\u{1F3A8}" },
22
+ background_command: { verb: "Background command", emoji: "\u{1F504}" },
23
+ get_diff: { verb: "Getting diff", emoji: "\u{1F4DD}" },
24
+ sub_agent: { verb: "Agent Task", emoji: "\u{1F916}" },
25
+ fast_context_search: { verb: "Searching context", emoji: "\u26A1" },
26
+ auto_context_compaction: { verb: "Auto compacting context", emoji: "[AUTO]" },
27
+ add_mcp: { verb: "Adding MCP server", emoji: "\u{1F50C}" }
24
28
  };
25
- /**
26
- * Convert an absolute path to a relative path from the current working directory.
27
- * If the path is outside the CWD, returns the full path.
28
- * Always uses forward slashes for consistency.
29
- */
30
29
  function toRelativePath(absolutePath) {
31
- if (!absolutePath)
32
- return '';
33
- try {
34
- const cwd = process.cwd();
35
- // Normalize paths for comparison (handle different path separators)
36
- const normalizedAbsolute = path.normalize(absolutePath);
37
- const normalizedCwd = path.normalize(cwd);
38
- // Check if the path starts with the CWD
39
- if (normalizedAbsolute.toLowerCase().startsWith(normalizedCwd.toLowerCase())) {
40
- let relativePath = path.relative(cwd, absolutePath);
41
- // If empty (same directory), show './'
42
- if (!relativePath)
43
- relativePath = '.';
44
- // Convert backslashes to forward slashes for consistent display
45
- return relativePath.replace(/\\/g, '/');
46
- }
47
- // Path is outside CWD, return as-is but with forward slashes
48
- return absolutePath.replace(/\\/g, '/');
49
- }
50
- catch {
51
- return absolutePath;
30
+ if (!absolutePath) return "";
31
+ try {
32
+ const cwd = process.cwd();
33
+ const normalizedAbsolute = path.normalize(absolutePath);
34
+ const normalizedCwd = path.normalize(cwd);
35
+ if (normalizedAbsolute.toLowerCase().startsWith(normalizedCwd.toLowerCase())) {
36
+ let relativePath = path.relative(cwd, absolutePath);
37
+ if (!relativePath) relativePath = ".";
38
+ return relativePath.replace(/\\/g, "/");
52
39
  }
40
+ return absolutePath.replace(/\\/g, "/");
41
+ } catch {
42
+ return absolutePath;
43
+ }
53
44
  }
54
- /**
55
- * Format a path with remote context prefix for SSH/Docker/WSL environments.
56
- * In local mode, returns just the path.
57
- * In remote mode, returns "user@host:/path" format.
58
- */
59
45
  function formatPathWithContext(absolutePath, remoteContext) {
60
- const pathStr = toRelativePath(absolutePath);
61
- if (remoteContext && absolutePath) {
62
- // For remote environments, show full path with remote prefix
63
- // Use the absolute path to make it clear this is a remote file
64
- return `${remoteContext}:${absolutePath.replace(/\\/g, '/')}`;
65
- }
66
- return pathStr;
46
+ const pathStr = toRelativePath(absolutePath);
47
+ if (remoteContext && absolutePath) {
48
+ return `${remoteContext}:${absolutePath.replace(/\\/g, "/")}`;
49
+ }
50
+ return pathStr;
67
51
  }
68
- /**
69
- * Clean shell output for display in history
70
- */
71
52
  function cleanShellOutput(result) {
72
- if (!result)
73
- return '';
74
- return processTerminalOutput(result);
53
+ if (!result) return "";
54
+ return processTerminalOutput(result);
75
55
  }
76
- /**
77
- * Truncate long commands for display to prevent rendering issues
78
- * @param command - The command string to truncate
79
- * @param maxLength - Maximum length before truncation (default: 80)
80
- * @returns Truncated command with ellipsis if needed
81
- */
82
56
  function truncateCommand(command, maxLength = 80) {
83
- if (!command || command.length <= maxLength)
84
- return command;
85
- return command.substring(0, maxLength) + '...';
57
+ if (!command || command.length <= maxLength) return command;
58
+ return command.substring(0, maxLength) + "...";
86
59
  }
87
- /**
88
- * Parse grep_search result to get match count
89
- * Format: "Found X matches in Y files for pattern..." or "Found X matches for pattern..."
90
- * Match lines are identified by the ":>" marker
91
- */
92
60
  function parseGrepSearchResult(result) {
93
- if (!result)
94
- return null;
95
- // Handle "No matches found" case
96
- if (result.includes('No matches found')) {
97
- return { matches: 0, files: 0 };
61
+ if (!result) return null;
62
+ if (result.includes("No matches found")) {
63
+ return { matches: 0, files: 0 };
64
+ }
65
+ const fullMatch = result.match(/Found (\d+) match(?:es)? in (\d+) file/);
66
+ if (fullMatch) {
67
+ return { matches: parseInt(fullMatch[1], 10), files: parseInt(fullMatch[2], 10) };
68
+ }
69
+ const matchCountOnly = result.match(/Found (\d+) match(?:es)?/);
70
+ if (matchCountOnly) {
71
+ const matchCount = parseInt(matchCountOnly[1], 10);
72
+ const lines2 = result.split("\n");
73
+ const uniqueFiles = /* @__PURE__ */ new Set();
74
+ for (const line of lines2) {
75
+ const trimmed = line.trim();
76
+ if (!trimmed || trimmed.startsWith("Found ") || trimmed.startsWith("(")) continue;
77
+ if (trimmed.includes(":>")) continue;
78
+ if (/^\d+:\s{3}/.test(trimmed)) continue;
79
+ if (!/^\d+:/.test(trimmed)) {
80
+ uniqueFiles.add(trimmed);
81
+ }
98
82
  }
99
- // Try to parse "Found X matches in Y files for pattern..." format (preferred)
100
- const fullMatch = result.match(/Found (\d+) match(?:es)? in (\d+) file/);
101
- if (fullMatch) {
102
- return { matches: parseInt(fullMatch[1], 10), files: parseInt(fullMatch[2], 10) };
83
+ return { matches: matchCount, files: uniqueFiles.size };
84
+ }
85
+ const lines = result.split("\n");
86
+ const matchLines = lines.filter((line) => line.includes(":>"));
87
+ if (matchLines.length > 0) {
88
+ const uniqueFiles = /* @__PURE__ */ new Set();
89
+ for (const line of lines) {
90
+ const trimmed = line.trim();
91
+ if (!trimmed || trimmed.startsWith("Found ") || trimmed.startsWith("(")) continue;
92
+ if (trimmed.includes(":>") || /^\d+:/.test(trimmed)) continue;
93
+ uniqueFiles.add(trimmed);
103
94
  }
104
- // Try to parse "Found X matches for pattern..." format (older format without file count)
105
- const matchCountOnly = result.match(/Found (\d+) match(?:es)?/);
106
- if (matchCountOnly) {
107
- const matchCount = parseInt(matchCountOnly[1], 10);
108
- // Count unique files from the output - files appear as standalone paths before their matches
109
- // File paths are lines that don't start with a number and don't contain ":>"
110
- const lines = result.split('\n');
111
- const uniqueFiles = new Set();
112
- for (const line of lines) {
113
- const trimmed = line.trim();
114
- // Skip header lines and empty lines
115
- if (!trimmed || trimmed.startsWith('Found ') || trimmed.startsWith('('))
116
- continue;
117
- // Match lines have ":>" in them, skip those
118
- if (trimmed.includes(':>'))
119
- continue;
120
- // Context lines start with "number: " (note the space after colon)
121
- if (/^\d+:\s{3}/.test(trimmed))
122
- continue;
123
- // Remaining lines that don't start with a number are file paths
124
- if (!/^\d+:/.test(trimmed)) {
125
- uniqueFiles.add(trimmed);
126
- }
127
- }
128
- return { matches: matchCount, files: uniqueFiles.size };
129
- }
130
- // Final fallback: count actual match lines (identified by ":>" marker)
131
- const lines = result.split('\n');
132
- const matchLines = lines.filter(line => line.includes(':>'));
133
- if (matchLines.length > 0) {
134
- // Count unique files from file header lines
135
- const uniqueFiles = new Set();
136
- for (const line of lines) {
137
- const trimmed = line.trim();
138
- if (!trimmed || trimmed.startsWith('Found ') || trimmed.startsWith('('))
139
- continue;
140
- if (trimmed.includes(':>') || /^\d+:/.test(trimmed))
141
- continue;
142
- uniqueFiles.add(trimmed);
143
- }
144
- return { matches: matchLines.length, files: uniqueFiles.size };
145
- }
146
- return null;
95
+ return { matches: matchLines.length, files: uniqueFiles.size };
96
+ }
97
+ return null;
147
98
  }
148
- /**
149
- * Parse find_files result to get file count
150
- * Format: one file path per line, or "Found X files"
151
- */
152
99
  function parseFindFilesResult(result) {
153
- if (!result)
154
- return null;
155
- // Check for "No files found" message
156
- if (result.includes('No files found') || result.includes('No matches found')) {
157
- return 0;
158
- }
159
- // Try to parse "Found X files" format
160
- const summaryMatch = result.match(/Found (\d+) file/);
161
- if (summaryMatch) {
162
- return parseInt(summaryMatch[1], 10);
100
+ if (!result) return null;
101
+ if (result.includes("No files found") || result.includes("No matches found")) {
102
+ return 0;
103
+ }
104
+ const summaryMatch = result.match(/Found (\d+) file/);
105
+ if (summaryMatch) {
106
+ return parseInt(summaryMatch[1], 10);
107
+ }
108
+ const totalMatch = result.match(/Total:\s*(\d+)/);
109
+ if (totalMatch) {
110
+ return parseInt(totalMatch[1], 10);
111
+ }
112
+ const lines = result.split("\n").filter((line) => line.trim() && !line.startsWith("Searching"));
113
+ return lines.length > 0 ? lines.length : null;
114
+ }
115
+ function toPositiveLineNumber(value) {
116
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
117
+ return Math.floor(value);
118
+ }
119
+ if (typeof value === "string" && value.trim()) {
120
+ const parsed = parseInt(value, 10);
121
+ if (Number.isFinite(parsed) && parsed > 0) {
122
+ return parsed;
163
123
  }
164
- // Try to parse "Total: X" format
165
- const totalMatch = result.match(/Total:\s*(\d+)/);
166
- if (totalMatch) {
167
- return parseInt(totalMatch[1], 10);
124
+ }
125
+ return null;
126
+ }
127
+ function parseViewFileResult(result) {
128
+ if (!result) return null;
129
+ const totalMatch = result.match(/^\s*Lines:\s*(\d+)/im);
130
+ const totalLines = totalMatch ? parseInt(totalMatch[1], 10) : null;
131
+ const shownMatch = result.match(/Showing first (\d+) lines only/i);
132
+ const shownLines = shownMatch ? parseInt(shownMatch[1], 10) : null;
133
+ const truncated = /\(Truncated\)/i.test(result) || /File truncated/i.test(result) || shownLines !== null;
134
+ const displayedLines = truncated ? shownLines : totalLines;
135
+ if (displayedLines === null && totalLines === null) {
136
+ return null;
137
+ }
138
+ return { displayedLines, totalLines, truncated };
139
+ }
140
+ function getViewFileLineInfo(toolArgs, result) {
141
+ const startLine = toPositiveLineNumber(toolArgs?.StartLine ?? toolArgs?.start_line) ?? 1;
142
+ const endLineArg = toPositiveLineNumber(toolArgs?.EndLine ?? toolArgs?.end_line);
143
+ const parsedResult = parseViewFileResult(result);
144
+ if (parsedResult?.displayedLines != null) {
145
+ const endLine = parsedResult.displayedLines > 0 ? startLine + parsedResult.displayedLines - 1 : startLine;
146
+ const lineRange = `lines ${startLine}-${endLine}`;
147
+ if (parsedResult.truncated && parsedResult.totalLines !== null && parsedResult.totalLines > parsedResult.displayedLines) {
148
+ return `${lineRange} (of ${parsedResult.totalLines})`;
168
149
  }
169
- // Count lines (each line is a file path)
170
- const lines = result.split('\n').filter(line => line.trim() && !line.startsWith('Searching'));
171
- return lines.length > 0 ? lines.length : null;
150
+ return lineRange;
151
+ }
152
+ if (endLineArg !== null) {
153
+ return `lines ${startLine}-${endLineArg}`;
154
+ }
155
+ return "lines 1-500";
172
156
  }
173
- /**
174
- * Parse list_dir result to get item count
175
- * New format: "Total: X directories, Y files, Z items"
176
- * Old format: "Directory: path\nTotal items: X\n..."
177
- */
178
157
  function parseListDirResult(result) {
179
- if (!result)
180
- return null;
181
- // Try to parse new enhanced format: "Total: X directories, Y files, Z items"
182
- const newFormatMatch = result.match(/Total:\s*(\d+)\s*director(?:y|ies),?\s*(\d+)\s*files?,?\s*(\d+)\s*items?/i);
183
- if (newFormatMatch) {
184
- return {
185
- dirs: parseInt(newFormatMatch[1], 10),
186
- files: parseInt(newFormatMatch[2], 10),
187
- total: parseInt(newFormatMatch[3], 10)
188
- };
189
- }
190
- // Try to parse old format: "Total items: X"
191
- const oldFormatMatch = result.match(/Total items:\s*(\d+)/);
192
- if (oldFormatMatch) {
193
- const total = parseInt(oldFormatMatch[1], 10);
194
- return { dirs: 0, files: 0, total };
195
- }
196
- return null;
158
+ if (!result) return null;
159
+ const newFormatMatch = result.match(/Total:\s*(\d+)\s*director(?:y|ies),?\s*(\d+)\s*files?,?\s*(\d+)\s*items?/i);
160
+ if (newFormatMatch) {
161
+ return {
162
+ dirs: parseInt(newFormatMatch[1], 10),
163
+ files: parseInt(newFormatMatch[2], 10),
164
+ total: parseInt(newFormatMatch[3], 10)
165
+ };
166
+ }
167
+ const oldFormatMatch = result.match(/Total items:\s*(\d+)/);
168
+ if (oldFormatMatch) {
169
+ const total = parseInt(oldFormatMatch[1], 10);
170
+ return { dirs: 0, files: 0, total };
171
+ }
172
+ return null;
197
173
  }
198
- /**
199
- * Parse inspect_symbol result to check if symbols were found
200
- */
201
174
  function parseInspectSymbolResult(result) {
202
- if (!result)
203
- return { found: false, count: 0 };
204
- // Check for "No symbols found" message
205
- if (result.includes('No symbols found')) {
206
- return { found: false, count: 0 };
207
- }
208
- // Count symbol definitions (rough estimate based on common patterns)
209
- const symbolMatches = result.match(/(?:function|class|interface|type|const|let|var|def|struct)\s+\w+/g);
210
- return { found: true, count: symbolMatches ? symbolMatches.length : 1 };
175
+ if (!result) return { found: false, count: 0 };
176
+ if (result.includes("No symbols found")) {
177
+ return { found: false, count: 0 };
178
+ }
179
+ const symbolMatches = result.match(/(?:function|class|interface|type|const|let|var|def|struct)\s+\w+/g);
180
+ return { found: true, count: symbolMatches ? symbolMatches.length : 1 };
211
181
  }
212
- /**
213
- * Parse fast_context_search result to get stats and markdown answer
214
- */
215
182
  function parseFastContextResult(result) {
216
- if (!result)
217
- return { answer: '' };
218
- try {
219
- // Try to parse as JSON first (new format)
220
- if (result.trim().startsWith('{')) {
221
- const parsed = JSON.parse(result);
222
- if (parsed.answer && parsed.stats) {
223
- return parsed;
224
- }
225
- }
226
- }
227
- catch (e) {
228
- // Fallback to raw string
183
+ if (!result) return { answer: "" };
184
+ try {
185
+ if (result.trim().startsWith("{")) {
186
+ const parsed = JSON.parse(result);
187
+ if (parsed.answer && parsed.stats) {
188
+ return parsed;
189
+ }
229
190
  }
230
- return { answer: result };
191
+ } catch (e) {
192
+ }
193
+ return { answer: result };
231
194
  }
232
- /**
233
- * Parse MCP tool name to extract server name and tool name
234
- * MCP tools are named: mcp_{serverName}_{toolName}
235
- */
236
195
  function parseMCPToolName(toolName) {
237
- if (!toolName.startsWith('mcp_'))
238
- return null;
239
- // Remove 'mcp_' prefix and split by first underscore
240
- const withoutPrefix = toolName.slice(4); // Remove 'mcp_'
241
- const firstUnderscoreIdx = withoutPrefix.indexOf('_');
242
- if (firstUnderscoreIdx === -1) {
243
- return { serverName: withoutPrefix, mcpToolName: 'unknown' };
244
- }
245
- const serverName = withoutPrefix.slice(0, firstUnderscoreIdx);
246
- const mcpToolName = withoutPrefix.slice(firstUnderscoreIdx + 1);
247
- return { serverName, mcpToolName };
196
+ if (!toolName.startsWith("mcp_")) return null;
197
+ const withoutPrefix = toolName.slice(4);
198
+ const firstUnderscoreIdx = withoutPrefix.indexOf("_");
199
+ if (firstUnderscoreIdx === -1) {
200
+ return { serverName: withoutPrefix, mcpToolName: "unknown" };
201
+ }
202
+ const serverName = withoutPrefix.slice(0, firstUnderscoreIdx);
203
+ const mcpToolName = withoutPrefix.slice(firstUnderscoreIdx + 1);
204
+ return { serverName, mcpToolName };
248
205
  }
249
- /**
250
- * Get display info for a tool, with special handling for MCP tools
251
- */
252
206
  function getToolDisplayInfo(toolName) {
253
- // Check if it's an MCP tool
254
- const mcpInfo = parseMCPToolName(toolName);
255
- if (mcpInfo) {
256
- return {
257
- verb: `MCP ${mcpInfo.serverName} ${mcpInfo.mcpToolName}`,
258
- emoji: '⚡',
259
- isMCP: true,
260
- serverName: mcpInfo.serverName,
261
- mcpToolName: mcpInfo.mcpToolName
262
- };
263
- }
264
- // Regular tool
265
- const toolInfo = TOOL_LABELS[toolName] || { verb: 'Executing', emoji: '🔧' };
266
- return { ...toolInfo, isMCP: false };
207
+ const mcpInfo = parseMCPToolName(toolName);
208
+ if (mcpInfo) {
209
+ return {
210
+ verb: `MCP ${mcpInfo.serverName} ${mcpInfo.mcpToolName}`,
211
+ emoji: "\u26A1",
212
+ isMCP: true,
213
+ serverName: mcpInfo.serverName,
214
+ mcpToolName: mcpInfo.mcpToolName
215
+ };
216
+ }
217
+ const toolInfo = TOOL_LABELS[toolName] || { verb: "Executing", emoji: "\u{1F527}" };
218
+ return { ...toolInfo, isMCP: false };
267
219
  }
268
- /**
269
- * Render a snippet of the diff (added/removed lines)
270
- */
271
220
  function renderDiffSnippet(removedContent, addedContent, options = {}) {
272
- const { compact } = options;
273
- if (!removedContent && !addedContent)
274
- return null;
275
- const removedLines = removedContent ? removedContent.split('\n') : [];
276
- const addedLines = addedContent ? addedContent.split('\n') : [];
277
- if (removedLines.length === 0 && addedLines.length === 0)
278
- return null;
279
- const items = [];
280
- // Show first 3 removed lines
281
- removedLines.slice(0, 3).forEach((line, i) => {
282
- items.push(React.createElement(Box, { key: `rem-${i}`, alignSelf: "flex-start" },
283
- React.createElement(Text, { color: "#e6e6e6", backgroundColor: "#5c1e1e", wrap: "truncate-end" }, `- ${line} `)));
221
+ const { compact } = options;
222
+ if (!removedContent && !addedContent) return null;
223
+ const removedLines = removedContent ? removedContent.split("\n") : [];
224
+ const addedLines = addedContent ? addedContent.split("\n") : [];
225
+ if (removedLines.length === 0 && addedLines.length === 0) return null;
226
+ const terminalWidth = process.stdout.columns || 80;
227
+ const maxPreviewWidth = Math.max(12, terminalWidth - 16);
228
+ const measuredLineWidths = [];
229
+ const wrapDiffLine = (prefix, line) => {
230
+ const continuationPrefix = " ".repeat(prefix.length);
231
+ const wrapped = wrapAnsi(line.length > 0 ? line : " ", Math.max(1, maxPreviewWidth - prefix.length), {
232
+ hard: true,
233
+ trim: false
234
+ }).split("\n");
235
+ return wrapped.map((segment, idx) => {
236
+ const rendered = `${idx === 0 ? prefix : continuationPrefix}${segment.length > 0 ? segment : " "}`;
237
+ measuredLineWidths.push(stringWidth(rendered));
238
+ return rendered;
284
239
  });
285
- if (removedLines.length > 3) {
286
- items.push(React.createElement(Text, { key: "rem-more", color: "gray", dimColor: true },
287
- " ... ",
288
- removedLines.length - 3,
289
- " more lines"));
290
- }
291
- // Show first 3 added lines
292
- addedLines.slice(0, 3).forEach((line, i) => {
293
- items.push(React.createElement(Box, { key: `add-${i}`, alignSelf: "flex-start" },
294
- React.createElement(Text, { color: "#e6e6e6", backgroundColor: "#1e4d2b", wrap: "truncate-end" }, `+ ${line} `)));
240
+ };
241
+ const items = [];
242
+ const previewLimit = 3;
243
+ removedLines.slice(0, previewLimit).forEach((line, i) => {
244
+ wrapDiffLine("- ", line).forEach((wrappedLine, wrappedIndex) => {
245
+ items.push(
246
+ /* @__PURE__ */ React.createElement(Box, { key: `rem-${i}-${wrappedIndex}` }, /* @__PURE__ */ React.createElement(Text, { color: "#e6e6e6", backgroundColor: "#5c1e1e", wrap: "truncate-end" }, wrappedLine))
247
+ );
295
248
  });
296
- if (addedLines.length > 3) {
297
- items.push(React.createElement(Text, { key: "add-more", color: "gray", dimColor: true },
298
- " ... ",
299
- addedLines.length - 3,
300
- " more lines"));
301
- }
302
- return (React.createElement(Box, { flexDirection: "column", marginTop: compact ? 0 : 1, alignSelf: "flex-start" },
303
- React.createElement(Box, { height: 1, borderStyle: "single", borderTop: true, borderBottom: false, borderLeft: false, borderRight: false, borderColor: "#333333", marginBottom: 0 }),
304
- items));
249
+ });
250
+ if (removedLines.length > previewLimit) {
251
+ items.push(
252
+ /* @__PURE__ */ React.createElement(Box, { key: "rem-more" }, /* @__PURE__ */ React.createElement(Text, { color: "gray", dimColor: true }, " ... ", removedLines.length - previewLimit, " more lines"))
253
+ );
254
+ }
255
+ addedLines.slice(0, previewLimit).forEach((line, i) => {
256
+ wrapDiffLine("+ ", line).forEach((wrappedLine, wrappedIndex) => {
257
+ items.push(
258
+ /* @__PURE__ */ React.createElement(Box, { key: `add-${i}-${wrappedIndex}` }, /* @__PURE__ */ React.createElement(Text, { color: "#e6e6e6", backgroundColor: "#1e4d2b", wrap: "truncate-end" }, wrappedLine))
259
+ );
260
+ });
261
+ });
262
+ if (addedLines.length > previewLimit) {
263
+ items.push(
264
+ /* @__PURE__ */ React.createElement(Box, { key: "add-more" }, /* @__PURE__ */ React.createElement(Text, { color: "gray", dimColor: true }, " ... ", addedLines.length - previewLimit, " more lines"))
265
+ );
266
+ }
267
+ const separatorWidth = Math.max(
268
+ 8,
269
+ Math.min(
270
+ maxPreviewWidth,
271
+ measuredLineWidths.length > 0 ? Math.max(...measuredLineWidths) : 8
272
+ )
273
+ );
274
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: compact ? 0 : 1, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "#333333" }, "\u2500".repeat(separatorWidth))), items);
305
275
  }
306
- export const ToolExecutionMessage = React.memo(({ message }) => {
307
- if (!message.toolExecution) {
308
- return null;
276
+ const ToolExecutionMessage = React.memo(({ message }) => {
277
+ if (!message.toolExecution) {
278
+ return null;
279
+ }
280
+ const { toolName, status, result, error, arguments: toolArgs } = message.toolExecution;
281
+ const toolInfo = getToolDisplayInfo(toolName);
282
+ const thinkingDuration = message.thinkingDuration;
283
+ const renderWithThinking = (content) => /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, thinkingDuration !== void 0 && thinkingDuration >= 0 && /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Thought for ", thinkingDuration, " second", thinkingDuration !== 1 ? "s" : "", " \u203A")), content);
284
+ if (status === "executing") {
285
+ if (toolName === "execute_command") {
286
+ return null;
309
287
  }
310
- const { toolName, status, result, error, arguments: toolArgs } = message.toolExecution;
311
- const toolInfo = getToolDisplayInfo(toolName);
312
- // Display thinking duration if available (carried from thought-only message)
313
- const thinkingDuration = message.thinkingDuration;
314
- // Helper to wrap content with thinking duration display
315
- const renderWithThinking = (content) => (React.createElement(Box, { flexDirection: "column" },
316
- thinkingDuration !== undefined && thinkingDuration >= 0 && (React.createElement(Box, { marginBottom: 1 },
317
- React.createElement(Text, { dimColor: true },
318
- "Thought for ",
319
- thinkingDuration,
320
- " second",
321
- thinkingDuration !== 1 ? 's' : '',
322
- " \u203A"))),
323
- content));
324
- // EXECUTING state
325
- if (status === 'executing') {
326
- // Skip execute_command - it's handled by InteractiveShell component
327
- if (toolName === 'execute_command') {
328
- return null;
329
- }
330
- // Note: web_search, grep_search, find_files now have custom executing states below
331
- // Skip plan-mode tools - they have their own UI components (TaskCompletedMessage, PlanReviewScreen)
332
- if (toolName === 'mark_task_complete' || toolName === 'create_plan') {
333
- return null;
334
- }
335
- // MCP tools - show executing state with simple format (no border to avoid emoji width issues)
336
- if (toolInfo.isMCP) {
337
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#9945FF", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
338
- React.createElement(Box, null,
339
- React.createElement(Text, { color: "#00ccff" },
340
- React.createElement(Spinner, { type: "arc" })),
341
- React.createElement(Text, { color: "#9945FF", bold: true }, " MCP"),
342
- React.createElement(Text, { color: "#9945FF" },
343
- " ",
344
- toolInfo.serverName,
345
- " ",
346
- toolInfo.mcpToolName))));
347
- }
348
- // VIEW_FILE
349
- if (toolName === 'view_file' && toolArgs) {
350
- const { AbsolutePath, StartLine, EndLine, remoteContext } = toolArgs;
351
- const lineInfo = StartLine && EndLine
352
- ? `lines ${StartLine}-${EndLine}`
353
- : 'entire file';
354
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
355
- React.createElement(Box, null,
356
- React.createElement(Text, { color: "#00ccff" },
357
- React.createElement(Spinner, { type: "arc" })),
358
- React.createElement(Text, { color: "#00ccff", bold: true },
359
- " Reading ",
360
- lineInfo,
361
- " from "),
362
- React.createElement(Text, { color: "#00ccff" },
363
- formatPathWithContext(AbsolutePath, remoteContext),
364
- "..."))));
365
- }
366
- // LIST_DIR
367
- if (toolName === 'list_dir' && toolArgs) {
368
- const { DirectoryPath, remoteContext } = toolArgs;
369
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
370
- React.createElement(Box, null,
371
- React.createElement(Text, { color: "#00ccff" },
372
- React.createElement(Spinner, { type: "arc" })),
373
- React.createElement(Text, { color: "#00ccff", bold: true }, " Listing "),
374
- React.createElement(Text, { color: "#00ccff" },
375
- formatPathWithContext(DirectoryPath, remoteContext),
376
- "..."))));
377
- }
378
- // GREP_SEARCH
379
- if (toolName === 'grep_search' && toolArgs) {
380
- const { Query, SearchPath } = toolArgs;
381
- const searchPathRelative = toRelativePath(SearchPath);
382
- // Determine if it's a file or directory (heuristic: check for common file extensions)
383
- const hasExtension = /\.[a-zA-Z0-9]{1,10}$/.test(SearchPath || '');
384
- const pathType = hasExtension ? 'file' : 'directory';
385
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
386
- React.createElement(Box, { flexWrap: "wrap" },
387
- React.createElement(Text, { color: "#00ccff" },
388
- React.createElement(Spinner, { type: "arc" })),
389
- React.createElement(Text, { color: "#00ccff", bold: true }, " Searching for "),
390
- React.createElement(Text, { color: "#00ccff" },
391
- "\"",
392
- Query,
393
- "\""),
394
- searchPathRelative && (React.createElement(Text, { color: "#00ccff" },
395
- " in ",
396
- React.createElement(Text, { color: "#00ccff", bold: true }, searchPathRelative),
397
- " ",
398
- pathType,
399
- "...")),
400
- !searchPathRelative && React.createElement(Text, { color: "#00ccff" }, "..."))));
401
- }
402
- // FIND_FILES
403
- if (toolName === 'find_files' && toolArgs) {
404
- const { pattern } = toolArgs;
405
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
406
- React.createElement(Box, null,
407
- React.createElement(Text, { color: "#00ccff" },
408
- React.createElement(Spinner, { type: "arc" })),
409
- React.createElement(Text, { color: "#00ccff", bold: true }, " Finding files matching "),
410
- React.createElement(Text, { color: "#00ccff" },
411
- "\"",
412
- pattern,
413
- "\"..."))));
414
- }
415
- // FETCH_URL
416
- if (toolName === 'fetch_url' && toolArgs) {
417
- const { url } = toolArgs;
418
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
419
- React.createElement(Box, null,
420
- React.createElement(Text, { color: "#00ccff" },
421
- React.createElement(Spinner, { type: "arc" })),
422
- React.createElement(Text, { color: "#00ccff", bold: true }, " Fetching "),
423
- React.createElement(Text, { color: "#00ccff" },
424
- url,
425
- "..."))));
426
- }
427
- // READ_BINARY_FILE
428
- if (toolName === 'read_binary_file' && toolArgs) {
429
- const { file_path, remoteContext } = toolArgs;
430
- const fileName = file_path ? path.basename(file_path) : 'file';
431
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff9900", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
432
- React.createElement(Box, null,
433
- React.createElement(Text, { color: "#00ccff" },
434
- React.createElement(Spinner, { type: "arc" })),
435
- React.createElement(Text, { color: "#ff9900", bold: true }, " Reading "),
436
- React.createElement(Text, { color: "#ff9900" },
437
- formatPathWithContext(file_path, remoteContext),
438
- "..."))));
439
- }
440
- // WRITE_TO_FILE
441
- if (toolName === 'write_to_file' && toolArgs) {
442
- const { TargetFile, remoteContext } = toolArgs;
443
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
444
- React.createElement(Box, null,
445
- React.createElement(Text, { color: "#00ccff" },
446
- React.createElement(Spinner, { type: "arc" })),
447
- React.createElement(Text, { color: "#00ccff", bold: true }, " Writing to "),
448
- React.createElement(Text, { color: "#00ccff" },
449
- formatPathWithContext(TargetFile, remoteContext),
450
- "..."))));
451
- }
452
- // EDIT_FILE
453
- if (toolName === 'edit_file' && toolArgs) {
454
- const { file_path, remoteContext } = toolArgs;
455
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
456
- React.createElement(Box, null,
457
- React.createElement(Text, { color: "#00ccff" },
458
- React.createElement(Spinner, { type: "arc" })),
459
- React.createElement(Text, { color: "#00ccff", bold: true }, " Editing "),
460
- React.createElement(Text, { color: "#00ccff" },
461
- formatPathWithContext(file_path, remoteContext),
462
- "..."))));
463
- }
464
- // MULTI_EDIT_FILE
465
- if (toolName === 'multi_edit_file' && toolArgs) {
466
- const { file_path, remoteContext } = toolArgs;
467
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
468
- React.createElement(Box, null,
469
- React.createElement(Text, { color: "#00ccff" },
470
- React.createElement(Spinner, { type: "arc" })),
471
- React.createElement(Text, { color: "#00ccff", bold: true }, " Editing "),
472
- React.createElement(Text, { color: "#00ccff" },
473
- formatPathWithContext(file_path, remoteContext),
474
- "..."))));
475
- }
476
- // CREATE_IMAGE
477
- if (toolName === 'create_image') {
478
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff9900", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
479
- React.createElement(Box, null,
480
- React.createElement(Text, { color: "#00ccff" },
481
- React.createElement(Spinner, { type: "arc" })),
482
- React.createElement(Text, { color: "#ff9900", bold: true }, " Generating image..."))));
483
- }
484
- // BACKGROUND_COMMAND - show action-specific message
485
- if (toolName === 'background_command' && toolArgs) {
486
- const { action, command, task_id, wait_seconds } = toolArgs;
487
- let actionText = 'Running background task...';
488
- if (action === 'start') {
489
- actionText = `Starting: ${command || 'command'}...`;
490
- }
491
- else if (action === 'status') {
492
- actionText = `Checking status: ${task_id || 'task'}...`;
493
- }
494
- else if (action === 'kill') {
495
- actionText = `Killing task: ${task_id || 'task'}...`;
496
- }
497
- else if (action === 'wait') {
498
- actionText = `Waiting for ${wait_seconds || '?'} second${wait_seconds !== 1 ? 's' : ''}...`;
499
- }
500
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff9900", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
501
- React.createElement(Box, null,
502
- React.createElement(Text, { color: "#00ccff" },
503
- React.createElement(Spinner, { type: "arc" })),
504
- React.createElement(Text, { color: "#ff9900", bold: true },
505
- " ",
506
- toolInfo.emoji,
507
- " ",
508
- actionText))));
509
- }
510
- // GET_DIFF
511
- if (toolName === 'get_diff' && toolArgs) {
512
- const { filePath, staged, reason_text } = toolArgs;
513
- const diffTarget = filePath ? `for ${filePath}` : 'for all files';
514
- const stagedText = staged ? ' (staged)' : '';
515
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
516
- React.createElement(Box, null,
517
- React.createElement(Text, { color: "#00ccff" },
518
- React.createElement(Spinner, { type: "arc" })),
519
- React.createElement(Text, { color: "#00ccff", bold: true },
520
- " ",
521
- toolInfo.emoji,
522
- " Getting diff ",
523
- diffTarget,
524
- stagedText,
525
- "..."))));
526
- }
527
- // WEB_SEARCH
528
- if (toolName === 'web_search' && toolArgs) {
529
- const { query } = toolArgs;
530
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
531
- React.createElement(Box, null,
532
- React.createElement(Text, { color: "#00ccff" },
533
- React.createElement(Spinner, { type: "arc" })),
534
- React.createElement(Text, { color: "#00ccff", bold: true },
535
- " ",
536
- toolInfo.emoji,
537
- " Searching the web for "),
538
- React.createElement(Text, { color: "#00ccff" },
539
- "\"",
540
- query,
541
- "\"..."))));
542
- }
543
- // FAST_CONTEXT_SEARCH
544
- if (toolName === 'fast_context_search' && toolArgs) {
545
- const { query } = toolArgs;
546
- let scannedFiles = [];
547
- try {
548
- const streamData = message.toolExecution?.streamingOutput || result;
549
- if (streamData) {
550
- const lines = streamData.trim().split('\n').filter(Boolean);
551
- if (lines.length > 0) {
552
- // Find the last valid JSON line by iterating backwards
553
- // The FastContextAgent outputs JSON blobs on stdout for UI updates
554
- for (let i = lines.length - 1; i >= 0; i--) {
555
- try {
556
- // The stream mixes logs and JSON. Fast context prints files inside JSON objects.
557
- const line = lines[i].trim();
558
- if (line.startsWith('{')) {
559
- const parsed = JSON.parse(line);
560
- if (parsed.type === 'scanned_files' && parsed.files) {
561
- scannedFiles = parsed.files;
562
- break; // Found the most recent valid state
563
- }
564
- }
565
- }
566
- catch (e) {
567
- // Ignore parsing errors for incomplete streamed lines
568
- }
569
- }
570
- }
571
- }
572
- }
573
- catch (e) {
574
- // ignore parsing errors
575
- }
576
- // Format query for executing state
577
- const truncatedQuery = query && query.length > 50 ? query.substring(0, 47) + '...' : query || '';
578
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
579
- React.createElement(Box, null,
580
- React.createElement(Text, { color: "#00ccff" },
581
- React.createElement(Spinner, { type: "arc" })),
582
- React.createElement(Text, { color: "#00cc66", bold: true }, " Rapid Context "),
583
- React.createElement(Text, { color: "#cccccc" },
584
- " \"",
585
- truncatedQuery,
586
- "\"")),
587
- scannedFiles.length > 0 && (React.createElement(Box, { flexDirection: "column", marginLeft: 2, marginTop: 1 }, scannedFiles.map((f, i) => (React.createElement(Text, { key: i, color: "#666666", wrap: "truncate-end" },
588
- "- ",
589
- toRelativePath(f))))))));
590
- }
591
- // INSPECT_SYMBOL
592
- if (toolName === 'inspect_symbol' && toolArgs) {
593
- const { filePath, symbols, remoteContext } = toolArgs;
594
- const symbolList = Array.isArray(symbols) ? symbols.join(', ') : symbols || 'symbols';
595
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
596
- React.createElement(Box, null,
597
- React.createElement(Text, { color: "#00ccff" },
598
- React.createElement(Spinner, { type: "arc" })),
599
- React.createElement(Text, { color: "#00ccff", bold: true },
600
- " ",
601
- toolInfo.emoji,
602
- " Inspecting "),
603
- React.createElement(Text, { color: "#00ccff" },
604
- symbolList,
605
- " in ",
606
- formatPathWithContext(filePath, remoteContext),
607
- "..."))));
608
- }
609
- // SUB_AGENT - executing
610
- if (toolName === 'sub_agent' && toolArgs) {
611
- const action = toolArgs.action;
612
- if (action === 'spawn') {
613
- const prompt = toolArgs.prompt || toolArgs.task || 'Unknown task';
614
- const complexity = toolArgs.complexity || 3;
615
- const modelName = complexity >= 5 ? 'Gemini 3 Pro Preview' : 'Gemini 3 Flash Preview';
616
- // Limit prompt display to 4 lines
617
- const promptLines = prompt.split('\n');
618
- const maxLines = 4;
619
- const displayLines = promptLines.slice(0, maxLines);
620
- const remainingLines = promptLines.length - maxLines;
621
- const truncatedPrompt = displayLines.join('\n');
622
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
623
- React.createElement(Box, null,
624
- React.createElement(Text, { color: "#00ccff" },
625
- React.createElement(Spinner, { type: "arc" })),
626
- React.createElement(Text, { color: "#9945FF", bold: true },
627
- " ",
628
- toolInfo.emoji,
629
- " Spawning Sub-Agent "),
630
- React.createElement(Text, { color: "#666666", dimColor: true },
631
- "(",
632
- modelName,
633
- ")")),
634
- React.createElement(Box, { marginLeft: 2, flexDirection: "column" },
635
- React.createElement(Text, { color: "#00ccff" }, truncatedPrompt),
636
- remainingLines > 0 && (React.createElement(Text, { color: "#666666", dimColor: true },
637
- "... ",
638
- remainingLines,
639
- " more lines")))));
640
- }
641
- else if (action === 'wait_for_status' || action === 'status') {
642
- const delay = toolArgs.time_delay || 0;
643
- const agentId = toolArgs.agent_id || 'unknown';
644
- const waitMessage = delay > 0 ? `Waiting for ${delay} seconds...` : 'Checking status...';
645
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
646
- React.createElement(Box, null,
647
- React.createElement(Text, { color: "#00ccff" },
648
- React.createElement(Spinner, { type: "arc" })),
649
- React.createElement(Text, { color: "#9945FF", bold: true },
650
- " ",
651
- toolInfo.emoji,
652
- " Sub Agent Status "),
653
- React.createElement(Text, { color: "#666666", dimColor: true },
654
- "(id: ",
655
- agentId,
656
- ")")),
657
- React.createElement(Box, { marginLeft: 2 },
658
- React.createElement(Text, { color: "#00ccff" }, waitMessage))));
659
- }
660
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
661
- React.createElement(Box, null,
662
- React.createElement(Text, { color: "#00ccff" },
663
- React.createElement(Spinner, { type: "arc" })),
664
- React.createElement(Text, { color: "#9945FF", bold: true },
665
- " ",
666
- toolInfo.emoji,
667
- " Sub Agent "),
668
- React.createElement(Text, { color: "#666666", dimColor: true },
669
- "(",
670
- action,
671
- ")"))));
672
- }
673
- // WORKFLOW - show action-specific message
674
- if (toolName === 'workflow' && toolArgs) {
675
- const action = toolArgs.action;
676
- const stepNumber = toolArgs.step_number;
677
- const exitType = toolArgs.exit_type;
678
- const reason = toolArgs.reason;
679
- let actionText = 'Workflow action...';
680
- let borderColor = '#00ccff';
681
- let textColor = '#00ccff';
682
- if (action === 'step_complete') {
683
- actionText = `Completing Step ${stepNumber || '?'}...`;
684
- borderColor = '#00cc66';
685
- textColor = '#00cc66';
686
- }
687
- else if (action === 'exit') {
688
- if (exitType === 'error') {
689
- actionText = `Workflow Failed${reason ? `: ${reason.slice(0, 50)}` : ''}`;
690
- borderColor = '#ff3366';
691
- textColor = '#ff3366';
692
- }
693
- else if (exitType === 'cancelled') {
694
- actionText = 'Workflow Cancelled';
695
- borderColor = '#ff9900';
696
- textColor = '#ff9900';
697
- }
698
- else {
699
- actionText = 'Workflow Completed';
700
- borderColor = '#00cc66';
701
- textColor = '#00cc66';
702
- }
703
- }
704
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: borderColor, paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
705
- React.createElement(Box, null,
706
- React.createElement(Text, { color: "#00ccff" },
707
- React.createElement(Spinner, { type: "arc" })),
708
- React.createElement(Text, { color: textColor, bold: true },
709
- " \uD83D\uDD04 ",
710
- actionText))));
711
- }
712
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
713
- React.createElement(Box, null,
714
- React.createElement(Text, { color: "#00ccff" },
715
- React.createElement(Spinner, { type: "arc" })),
716
- React.createElement(Text, { color: "#00ccff", bold: true },
717
- " ",
718
- toolInfo.verb,
719
- "..."))));
288
+ if (toolName === "mark_task_complete" || toolName === "create_plan") {
289
+ return null;
720
290
  }
721
- // ERROR state
722
- if (status === 'error') {
723
- // EXECUTE_COMMAND - render as static shell box with error
724
- if (toolName === 'execute_command' && toolArgs) {
725
- const command = toolArgs.command || toolArgs.CommandLine || toolArgs.commandLine || '';
726
- const truncatedCommand = truncateCommand(command, 80);
727
- const { cwd, remoteContext } = toolArgs;
728
- const cleanResult = cleanShellOutput(result);
729
- // For CWD display, use absolute path directly (don't convert to relative)
730
- const formattedCwd = cwd && remoteContext
731
- ? `${remoteContext}:${cwd.replace(/\\/g, '/')}`
732
- : (cwd || '').replace(/\\/g, '/');
733
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff3366", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
734
- React.createElement(Box, { marginBottom: 1 },
735
- React.createElement(Text, null,
736
- React.createElement(Text, { color: "#ff3366", bold: true }, "\u2717 Shell "),
737
- React.createElement(Text, { color: "#666666" },
738
- truncatedCommand,
739
- " "),
740
- cwd && React.createElement(Text, { color: "#666666", dimColor: true },
741
- "[current working directory ",
742
- formattedCwd,
743
- "]"))),
744
- cleanResult && (React.createElement(Box, null,
745
- React.createElement(Text, { wrap: "wrap" }, cleanResult)))));
746
- }
747
- return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff3366", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
748
- React.createElement(Box, null,
749
- React.createElement(Text, { color: "#ff3366", bold: true },
750
- "\u2717 ",
751
- toolInfo.emoji,
752
- " ",
753
- toolInfo.verb,
754
- " failed")),
755
- React.createElement(Box, { paddingLeft: 1, marginTop: 1 },
756
- React.createElement(Text, { color: "#ff3366" }, error || 'The Agent passed invalid parameters'))));
291
+ if (toolName === "auto_context_compaction") {
292
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " Auto summarizing context...")));
757
293
  }
758
- // COMPLETED state - tool-specific rendering
759
- if (status === 'completed') {
760
- // MCP tools - show only success indicator, hide output (output goes to AI only)
761
- if (toolInfo.isMCP) {
762
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
763
- React.createElement(Box, null,
764
- React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 MCP"),
765
- React.createElement(Text, { color: "#aaaaaa" },
766
- " ",
767
- toolInfo.serverName,
768
- " ",
769
- toolInfo.mcpToolName))));
770
- }
771
- // Skip plan-mode tools - they have their own UI components (TaskCompletedMessage, PlanReviewScreen)
772
- if (toolName === 'mark_task_complete' || toolName === 'create_plan') {
773
- return null;
774
- }
775
- // EXECUTE_COMMAND - render as static shell box
776
- if (toolName === 'execute_command' && toolArgs) {
777
- // Hide shell_input actions from history as per user request
778
- // These are just input submissions (like "1\n") and the result is just confirmation text
779
- // The actual side effects are seen in the persistent shell, so showing this block is redundant clutter
780
- if (toolArgs.shell_input) {
781
- return null;
782
- }
783
- const command = toolArgs.command || toolArgs.CommandLine || toolArgs.commandLine || '';
784
- const truncatedCommand = truncateCommand(command, 80);
785
- const { cwd, remoteContext } = toolArgs;
786
- const cleanResult = cleanShellOutput(result);
787
- // For CWD display, use absolute path directly (don't convert to relative)
788
- const formattedCwd = cwd && remoteContext
789
- ? `${remoteContext}:${cwd.replace(/\\/g, '/')}`
790
- : (cwd || '').replace(/\\/g, '/');
791
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
792
- React.createElement(Box, { marginBottom: 1 },
793
- React.createElement(Text, null,
794
- React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 Shell "),
795
- React.createElement(Text, { color: "#666666" },
796
- truncatedCommand,
797
- " "),
798
- cwd && React.createElement(Text, { color: "#666666", dimColor: true },
799
- "[current working directory ",
800
- formattedCwd,
801
- "]"))),
802
- cleanResult && (React.createElement(Box, null,
803
- React.createElement(Text, { wrap: "wrap" }, cleanResult)))));
804
- }
805
- // VIEW_FILE
806
- if (toolName === 'view_file' && toolArgs) {
807
- const { AbsolutePath, StartLine, EndLine, remoteContext } = toolArgs;
808
- const lineInfo = StartLine && EndLine
809
- ? `lines ${StartLine}-${EndLine}`
810
- : 'entire file';
811
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
812
- React.createElement(Box, null,
813
- React.createElement(Text, { color: "#00cc66", bold: true },
814
- "\u2713 ",
815
- toolInfo.emoji,
816
- " Read ",
817
- lineInfo,
818
- " from "),
819
- React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(AbsolutePath, remoteContext)))));
820
- }
821
- // WRITE_TO_FILE
822
- if (toolName === 'write_to_file' && toolArgs) {
823
- const { TargetFile, CodeContent, remoteContext } = toolArgs;
824
- const lines = CodeContent ? CodeContent.split('\n').length : 0;
825
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
826
- React.createElement(Box, null,
827
- React.createElement(Text, { color: "#00cc66", bold: true },
828
- "\u2713 ",
829
- toolInfo.emoji,
830
- " Wrote to "),
831
- React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(TargetFile, remoteContext)),
832
- lines > 0 && React.createElement(Text, { color: "green" },
833
- " +",
834
- lines)),
835
- renderDiffSnippet(undefined, CodeContent)));
836
- }
837
- // EDIT_FILE
838
- if (toolName === 'edit_file' && toolArgs) {
839
- const { file_path, remoteContext, replacement, search_pattern } = toolArgs;
840
- const added = replacement ? replacement.split('\n').length : 0;
841
- const removed = search_pattern ? search_pattern.split('\n').length : 0;
842
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
843
- React.createElement(Box, null,
844
- React.createElement(Text, { color: "#00cc66", bold: true },
845
- "\u2713 ",
846
- toolInfo.emoji,
847
- " Edited "),
848
- React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(file_path, remoteContext)),
849
- React.createElement(Text, { color: "green" },
850
- " +",
851
- added),
852
- React.createElement(Text, { color: "red" },
853
- " -",
854
- removed)),
855
- renderDiffSnippet(search_pattern, replacement)));
856
- }
857
- // MULTI_EDIT_FILE
858
- if (toolName === 'multi_edit_file' && toolArgs) {
859
- const { file_path, edits, remoteContext } = toolArgs;
860
- const editList = Array.isArray(edits) ? edits : [];
861
- let added = 0;
862
- let removed = 0;
863
- editList.forEach((edit) => {
864
- if (edit.replacement || edit.ReplacementContent) {
865
- added += (edit.replacement || edit.ReplacementContent).split('\n').length;
866
- }
867
- if (edit.search_pattern || edit.TargetContent) {
868
- removed += (edit.search_pattern || edit.TargetContent).split('\n').length;
869
- }
870
- });
871
- // For multi-edit, we show the snippet of the FIRST edit as a sample, or maybe we aggregate?
872
- // Lets show the first edit's snippet if available
873
- const firstEdit = editList[0];
874
- const searchExample = firstEdit ? (firstEdit.search_pattern || firstEdit.TargetContent) : undefined;
875
- const replaceExample = firstEdit ? (firstEdit.replacement || firstEdit.ReplacementContent) : undefined;
876
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
877
- React.createElement(Box, null,
878
- React.createElement(Text, { color: "#00cc66", bold: true },
879
- "\u2713 ",
880
- toolInfo.emoji,
881
- " Edited "),
882
- React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(file_path, remoteContext)),
883
- React.createElement(Text, { color: "green" },
884
- " +",
885
- added),
886
- React.createElement(Text, { color: "red" },
887
- " -",
888
- removed)),
889
- editList.length > 0 ? (React.createElement(Box, { flexDirection: "column", marginTop: 0 }, editList.map((edit, index) => {
890
- const search = edit.search_pattern || edit.TargetContent;
891
- const replace = edit.replacement || edit.ReplacementContent;
892
- return (React.createElement(React.Fragment, { key: index }, renderDiffSnippet(search, replace, { compact: index > 0 })));
893
- }))) : (null)));
894
- }
895
- // LIST_DIR
896
- if (toolName === 'list_dir' && toolArgs) {
897
- const { DirectoryPath, remoteContext } = toolArgs;
898
- const itemStats = parseListDirResult(result);
899
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
900
- React.createElement(Box, null,
901
- React.createElement(Text, { color: "#00cc66", bold: true },
902
- "\u2713 ",
903
- toolInfo.emoji,
904
- " Listed "),
905
- React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(DirectoryPath, remoteContext)),
906
- itemStats !== null && (React.createElement(Text, { color: "#666666" },
907
- " (",
908
- itemStats.dirs,
909
- " dir",
910
- itemStats.dirs !== 1 ? 's' : '',
911
- ", ",
912
- itemStats.files,
913
- " file",
914
- itemStats.files !== 1 ? 's' : '',
915
- ")")))));
916
- }
917
- // GREP_SEARCH
918
- if (toolName === 'grep_search' && toolArgs) {
919
- const { Query, SearchPath } = toolArgs;
920
- const searchResults = parseGrepSearchResult(result);
921
- const searchPathRelative = toRelativePath(SearchPath);
922
- // Determine if it's a file or directory (heuristic: check for common file extensions)
923
- const hasExtension = /\.[a-zA-Z0-9]{1,10}$/.test(SearchPath || '');
924
- const pathType = hasExtension ? 'file' : 'directory';
925
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
926
- React.createElement(Box, { flexWrap: "wrap" },
927
- React.createElement(Text, { color: "#00cc66", bold: true },
928
- "\u2713 ",
929
- toolInfo.emoji,
930
- " Searched for "),
931
- React.createElement(Text, { color: "#00ccff" },
932
- "\"",
933
- Query,
934
- "\""),
935
- searchPathRelative && (React.createElement(Text, { color: "#666666" },
936
- " in ",
937
- React.createElement(Text, { color: "#00ccff" }, searchPathRelative),
938
- " ",
939
- pathType)),
940
- searchResults && (React.createElement(Text, { color: "#666666" },
941
- " (",
942
- searchResults.matches,
943
- " match",
944
- searchResults.matches !== 1 ? 'es' : '',
945
- " in ",
946
- searchResults.files,
947
- " file",
948
- searchResults.files !== 1 ? 's' : '',
949
- ")")),
950
- !searchResults && result && React.createElement(Text, { color: "#666666" }, " (no matches)"))));
951
- }
952
- // FIND_FILES
953
- if (toolName === 'find_files' && toolArgs) {
954
- const { pattern, Pattern } = toolArgs;
955
- const displayPattern = pattern || Pattern || '*';
956
- const fileCount = parseFindFilesResult(result);
957
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
958
- React.createElement(Box, null,
959
- React.createElement(Text, { color: "#00cc66", bold: true },
960
- "\u2713 ",
961
- toolInfo.emoji,
962
- " Found ",
963
- fileCount !== null ? fileCount : 0,
964
- " files matching "),
965
- React.createElement(Text, { color: "#00ccff" },
966
- "\"",
967
- displayPattern,
968
- "\""))));
969
- }
970
- // WEB_SEARCH
971
- if (toolName === 'web_search' && toolArgs) {
972
- const { query } = toolArgs;
973
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
974
- React.createElement(Box, null,
975
- React.createElement(Text, { color: "#00cc66", bold: true },
976
- "\u2713 ",
977
- toolInfo.emoji,
978
- " Searched the web for "),
979
- React.createElement(Text, { color: "#00ccff" },
980
- "\"",
981
- query,
982
- "\""))));
983
- }
984
- // FETCH_URL
985
- if (toolName === 'fetch_url' && toolArgs) {
986
- const { url } = toolArgs;
987
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
988
- React.createElement(Box, null,
989
- React.createElement(Text, { color: "#00cc66", bold: true },
990
- "\u2713 ",
991
- toolInfo.emoji,
992
- " Fetched "),
993
- React.createElement(Text, { color: "#00ccff" }, url))));
994
- }
995
- // FAST_CONTEXT_SEARCH
996
- if (toolName === 'fast_context_search' && toolArgs) {
997
- let answer = result || '';
998
- let stats = undefined;
999
- try {
1000
- if (result && result.trim().startsWith('{')) {
1001
- const parsed = JSON.parse(result);
1002
- if (parsed.answer !== undefined) {
1003
- answer = parsed.answer;
1004
- }
1005
- if (parsed.stats !== undefined) {
1006
- stats = parsed.stats;
1007
- }
1008
- }
1009
- }
1010
- catch (e) {
1011
- // Fallback to raw result if parsing fails
1012
- }
1013
- const { query } = toolArgs;
1014
- const scannedFiles = stats?.scannedFiles || [];
1015
- const hasFiles = scannedFiles.length > 0;
1016
- const MAX_DISPLAY_FILES = 10;
1017
- const truncatedQuery = query && query.length > 50 ? query.substring(0, 47) + '...' : query || '';
1018
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
1019
- React.createElement(Box, null,
1020
- React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 Rapid Context "),
1021
- React.createElement(Text, { color: "#cccccc", wrap: "truncate-end" },
1022
- "\"",
1023
- truncatedQuery,
1024
- "\" "),
1025
- stats && (React.createElement(Text, { color: "#666666" },
1026
- "(Searched ",
1027
- stats.filesSearched,
1028
- " files in ",
1029
- (stats.duration / 1000).toFixed(1),
1030
- "s)"))),
1031
- React.createElement(Box, { paddingLeft: 1, marginTop: 1, flexDirection: "column" },
1032
- !hasFiles && answer && (React.createElement(Text, { color: "#aaaaaa", wrap: "truncate-end" }, answer)),
1033
- hasFiles && (React.createElement(Box, { flexDirection: "column", marginTop: 0 },
1034
- scannedFiles.slice(0, MAX_DISPLAY_FILES).map((f, i) => {
1035
- // Display only the file name to keep it clean, or relative path
1036
- return (React.createElement(Text, { key: i, color: "#444444", wrap: "truncate-end" },
1037
- "- ",
1038
- path.basename(f),
1039
- " ",
1040
- React.createElement(Text, { color: "#333333", italic: true },
1041
- "(",
1042
- toRelativePath(f),
1043
- ")")));
1044
- }),
1045
- scannedFiles.length > MAX_DISPLAY_FILES && (React.createElement(Text, { color: "#444444", italic: true },
1046
- "...and ",
1047
- scannedFiles.length - MAX_DISPLAY_FILES,
1048
- " more files checked")))))));
1049
- }
1050
- // INSPECT_SYMBOL
1051
- if (toolName === 'inspect_symbol' && toolArgs) {
1052
- const { filePath, remoteContext } = toolArgs;
1053
- const symbolResult = parseInspectSymbolResult(result);
1054
- const displayPath = filePath || 'unknown';
1055
- const noSymbols = result?.includes('No symbols found');
1056
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
1057
- React.createElement(Box, null,
1058
- React.createElement(Text, { color: "#00cc66", bold: true },
1059
- "\u2713 ",
1060
- toolInfo.emoji,
1061
- " Inspected "),
1062
- React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(displayPath, remoteContext)),
1063
- noSymbols && React.createElement(Text, { color: "#666666" }, " (no symbols found)"),
1064
- !noSymbols && symbolResult.found && React.createElement(Text, { color: "#666666" },
1065
- " (",
1066
- symbolResult.count,
1067
- " symbol",
1068
- symbolResult.count !== 1 ? 's' : '',
1069
- ")"))));
1070
- }
1071
- // READ_BINARY_FILE
1072
- if (toolName === 'read_binary_file' && toolArgs) {
1073
- const { file_path, remoteContext } = toolArgs;
1074
- const fileName = file_path ? path.basename(file_path) : 'file';
1075
- // Parse file info from result
1076
- const sizeMatch = result?.match(/Size:\s*([\d.]+\s*(?:B|KB|MB))/);
1077
- const typeMatch = result?.match(/Type:\s*([\w/+-]+)/);
1078
- const fileSize = sizeMatch ? sizeMatch[1] : '';
1079
- const fileType = typeMatch ? typeMatch[1] : '';
1080
- const isSuccess = result?.includes('Successfully uploaded');
1081
- const isError = result?.includes('Error:') || !isSuccess;
1082
- const errorMessage = result?.match(/Error:\s*(.+?)(?:\n|$)/)?.[1] || '';
1083
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: isSuccess ? "#00cc66" : "#ff6666", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
1084
- React.createElement(Box, null, isSuccess ? (React.createElement(React.Fragment, null,
1085
- React.createElement(Text, { color: "#00cc66", bold: true },
1086
- "\u2713 ",
1087
- toolInfo.emoji,
1088
- " Read "),
1089
- React.createElement(Text, { color: "#ff9900" }, formatPathWithContext(file_path, remoteContext)))) : (React.createElement(React.Fragment, null,
1090
- React.createElement(Text, { color: "#ff6666", bold: true },
1091
- "\u2717 ",
1092
- toolInfo.emoji,
1093
- " Read failed "),
1094
- React.createElement(Text, { color: "#ff9900" }, formatPathWithContext(file_path, remoteContext))))),
1095
- isSuccess && (fileType || fileSize) && (React.createElement(Box, null,
1096
- React.createElement(Text, { color: "#666666" },
1097
- fileType && `${fileType}`,
1098
- fileType && fileSize && ' • ',
1099
- fileSize && fileSize))),
1100
- isError && errorMessage && (React.createElement(Box, null,
1101
- React.createElement(Text, { color: "#ff6666" }, errorMessage)))));
1102
- }
1103
- // SUB_AGENT - completed
1104
- if (toolName === 'sub_agent') {
1105
- const toolAction = toolArgs?.action;
1106
- const agentId = toolArgs?.agent_id || 'unknown';
1107
- let title = 'Sub Agent';
1108
- let details = '';
1109
- let additionalContent = null;
1110
- // Helper to try parsing JSON result
1111
- let structResult = null;
1112
- let markdownReport = typeof result === 'string' ? result : '';
1113
- try {
1114
- if (typeof result === 'string' && result.trim().startsWith('{')) {
1115
- const parsed = JSON.parse(result);
1116
- if (parsed.data && parsed.report) {
1117
- structResult = parsed.data;
1118
- markdownReport = parsed.report;
1119
- }
1120
- }
1121
- }
1122
- catch (e) {
1123
- // Fallback to treating result as string
1124
- }
1125
- if (toolAction === 'spawn') {
1126
- title = 'Sub Agent';
1127
- const prompt = toolArgs?.prompt || '';
1128
- const shortPrompt = prompt.length > 50 ? prompt.substring(0, 47) + '...' : prompt;
1129
- // Result for spawn is usually text, we can parse ID from it if needed, but we don't have it in args yet usually
1130
- // Actually spawn returns the ID in the result text, but we might not parse it here easily.
1131
- // Assuming we rely on result text for ID if not in args.
1132
- // But per request: "id status, duration..."
1133
- // For spawn: "just the agent id, and the prompt"
1134
- // 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)
1135
- const idMatch = result?.match(/Agent ID:\*\* ([\w-]+)/);
1136
- const spawnedId = idMatch ? idMatch[1] : 'unknown';
1137
- details = `(id: ${spawnedId})`;
1138
- if (prompt) {
1139
- additionalContent = (React.createElement(Box, { marginTop: 1, marginLeft: 2 },
1140
- React.createElement(Text, { color: "#00ccff" }, prompt)));
1141
- }
1142
- }
1143
- else if (toolAction === 'wait_for_status' || toolAction === 'status') {
1144
- title = 'Sub Agent Status';
1145
- // Parse status details from result string or structured data if we had it (status usually returns text)
1146
- // Status result is text like: "**Status:** 🔄 running\n**Model:** ...\n**Duration:** 16s..."
1147
- const statusMatch = result?.match(/Status:\*\* (.+?)\n/);
1148
- const durationMatch = result?.match(/Duration:\*\* (.+?)\n/);
1149
- const fileOpsMatch = result?.match(/File Operations:\*\* (\d+)/);
1150
- const toolCallsMatch = result?.match(/Tool Calls:\*\* (\d+)/);
1151
- const status = statusMatch ? statusMatch[1].trim() : 'unknown';
1152
- const duration = durationMatch ? durationMatch[1].trim() : 'unknown';
1153
- const fileOps = fileOpsMatch ? fileOpsMatch[1] : '0';
1154
- const toolCalls = toolCallsMatch ? toolCallsMatch[1] : '0';
1155
- details = `(id: ${agentId}, status: ${status}, duration: ${duration}, files: ${fileOps}, tools: ${toolCalls})`;
1156
- }
1157
- else if (toolAction === 'terminate') {
1158
- title = 'Sub Agent Terminated';
1159
- details = `(id: ${agentId})`;
1160
- }
1161
- else if (toolAction === 'read_results') {
1162
- title = 'Sub Agent Results';
1163
- // Use structured result if available
1164
- if (structResult) {
1165
- details = `(id: ${structResult.agentId}, duration: ${structResult.duration})`;
1166
- // Show modified files
1167
- if (structResult.fileOperations && structResult.fileOperations.length > 0) {
1168
- additionalContent = (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
1169
- React.createElement(Text, { color: "#666666" }, "Files Modified:"),
1170
- structResult.fileOperations.map((op, i) => (React.createElement(Box, { key: i, marginLeft: 2 },
1171
- React.createElement(Text, { color: "#00ccff" },
1172
- "\u2022 ",
1173
- op.path,
1174
- " ",
1175
- React.createElement(Text, { color: "#666666", dimColor: true },
1176
- "(",
1177
- op.type,
1178
- ")")))))));
1179
- }
1180
- }
1181
- else {
1182
- // Fallback for string result
1183
- details = `(id: ${agentId})`;
1184
- const summary = result?.length > 100 ? result.substring(0, 97) + '...' : result;
1185
- additionalContent = React.createElement(Text, { color: "#666666", dimColor: true }, summary);
1186
- }
1187
- }
1188
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
1189
- React.createElement(Box, null,
1190
- React.createElement(Text, { color: "#00cc66", bold: true },
1191
- "\u2713 ",
1192
- toolInfo.emoji,
1193
- " ",
1194
- title,
1195
- " "),
1196
- React.createElement(Text, { color: "#666666" }, details)),
1197
- additionalContent));
1198
- }
1199
- // CREATE_IMAGE
1200
- if (toolName === 'create_image' && toolArgs) {
1201
- const { output_path, aspect_ratio } = toolArgs;
1202
- // Parse file info from result
1203
- const sizeMatch = result?.match(/\*\*Size:\*\*\s*([\d.]+\s*KB)/);
1204
- const formatMatch = result?.match(/\*\*Format:\*\*\s*([\w/]+)/);
1205
- const fileSize = sizeMatch ? sizeMatch[1] : '';
1206
- const format = formatMatch ? formatMatch[1] : '';
1207
- const isSuccess = result?.includes('generated successfully');
1208
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: isSuccess ? "#00cc66" : "#ff6666", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
1209
- React.createElement(Box, null, isSuccess ? (React.createElement(React.Fragment, null,
1210
- React.createElement(Text, { color: "#00cc66", bold: true },
1211
- "\u2713 ",
1212
- toolInfo.emoji,
1213
- " Generated image "),
1214
- React.createElement(Text, { color: "#00ccff" }, toRelativePath(output_path)),
1215
- (fileSize || format) && (React.createElement(Text, { color: "#666666" },
1216
- " (",
1217
- format,
1218
- format && fileSize ? ' • ' : '',
1219
- fileSize,
1220
- ")")))) : (React.createElement(React.Fragment, null,
1221
- React.createElement(Text, { color: "#ff6666", bold: true },
1222
- "\u2717 ",
1223
- toolInfo.emoji,
1224
- " Image generation failed"))))));
1225
- }
1226
- // BACKGROUND_COMMAND
1227
- if (toolName === 'background_command' && toolArgs) {
1228
- const { action, command, task_id, wait_seconds } = toolArgs;
1229
- let actionText = 'Background command';
1230
- let actionDetail = '';
1231
- if (action === 'start') {
1232
- actionText = 'Started background task';
1233
- actionDetail = command ? `(${command})` : '';
1234
- }
1235
- else if (action === 'status') {
1236
- actionText = 'Checked task status';
1237
- actionDetail = task_id ? `(${task_id})` : '';
1238
- }
1239
- else if (action === 'kill') {
1240
- actionText = 'Killed background task';
1241
- actionDetail = task_id ? `(${task_id})` : '';
1242
- }
1243
- else if (action === 'wait') {
1244
- actionText = 'Waited for';
1245
- actionDetail = wait_seconds ? `${wait_seconds} second${wait_seconds !== 1 ? 's' : ''}` : '';
1246
- }
1247
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
1248
- React.createElement(Box, null,
1249
- React.createElement(Text, { color: "#00cc66", bold: true },
1250
- "\u2713 ",
1251
- toolInfo.emoji,
1252
- " ",
1253
- actionText),
1254
- actionDetail && React.createElement(Text, { color: "#666666" },
1255
- " ",
1256
- actionDetail))));
1257
- }
1258
- // WORKFLOW - completed state
1259
- if (toolName === 'workflow' && toolArgs) {
1260
- const action = toolArgs.action;
1261
- const stepNumber = toolArgs.step_number;
1262
- const exitType = toolArgs.exit_type;
1263
- const reason = toolArgs.reason;
1264
- let actionText = 'Workflow action';
1265
- let borderColor = '#00cc66';
1266
- let textColor = '#00cc66';
1267
- let icon = '✓';
1268
- if (action === 'step_complete') {
1269
- actionText = `Step ${stepNumber || '?'} Complete`;
1270
- borderColor = '#00cc66';
1271
- textColor = '#00cc66';
1272
- }
1273
- else if (action === 'exit') {
1274
- if (exitType === 'error') {
1275
- actionText = `Workflow Failed${reason ? `: ${reason.slice(0, 50)}` : ''}`;
1276
- borderColor = '#ff3366';
1277
- textColor = '#ff3366';
1278
- icon = '✗';
1279
- }
1280
- else if (exitType === 'cancelled') {
1281
- actionText = 'Workflow Cancelled';
1282
- borderColor = '#ff9900';
1283
- textColor = '#ff9900';
1284
- icon = '⚠';
1285
- }
1286
- else {
1287
- actionText = 'Workflow Completed';
1288
- borderColor = '#00cc66';
1289
- textColor = '#00cc66';
1290
- }
1291
- }
1292
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: borderColor, paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
1293
- React.createElement(Box, null,
1294
- React.createElement(Text, { color: textColor, bold: true },
1295
- icon,
1296
- " \uD83D\uDD04 ",
1297
- actionText))));
1298
- }
1299
- // GET_DIFF
1300
- if (toolName === 'get_diff' && toolArgs) {
1301
- const { filePath, staged } = toolArgs;
1302
- const diffTarget = filePath ? toRelativePath(filePath) : '';
1303
- const stagedText = staged ? ' (staged)' : '';
1304
- // The get_diff tool returns JSON: { result: string, summary: string }
1305
- // Parse JSON to extract the human-readable summary
1306
- let parsedResult = result || '';
1307
- let parsedSummary = '';
1308
- try {
1309
- if (result) {
1310
- const json = JSON.parse(result);
1311
- parsedResult = json.result || result;
1312
- parsedSummary = json.summary || '';
1313
- }
1314
- }
1315
- catch {
1316
- // Not JSON, use raw result as-is
1317
- }
1318
- const hasChanges = !parsedResult.includes('No changes') && !parsedSummary.includes('No changes');
1319
- const truncated = parsedResult.includes('[Diff truncated');
1320
- // Build display summary from parsed data
1321
- let displayInfo = 'no changes';
1322
- if (hasChanges) {
1323
- if (parsedSummary) {
1324
- displayInfo = parsedSummary;
1325
- }
1326
- else {
1327
- // Fallback: extract file count from result text (format: **N file(s) changed**)
1328
- const filesMatch = parsedResult.match(/(\d+)\s+file\(?s?\)?\s+changed/);
1329
- displayInfo = filesMatch ? `${filesMatch[1]} file(s) changed` : 'changes detected';
294
+ if (toolInfo.isMCP) {
295
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#9945FF", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#9945FF", bold: true }, " MCP"), /* @__PURE__ */ React.createElement(Text, { color: "#9945FF" }, " ", toolInfo.serverName, " ", toolInfo.mcpToolName)));
296
+ }
297
+ if (toolName === "view_file" && toolArgs) {
298
+ const { AbsolutePath, remoteContext } = toolArgs;
299
+ const lineInfo = getViewFileLineInfo(toolArgs);
300
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " Reading ", lineInfo, " from "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(AbsolutePath, remoteContext), "...")));
301
+ }
302
+ if (toolName === "list_dir" && toolArgs) {
303
+ const { DirectoryPath, remoteContext } = toolArgs;
304
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " Listing "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(DirectoryPath, remoteContext), "...")));
305
+ }
306
+ if (toolName === "grep_search" && toolArgs) {
307
+ const { Query, SearchPath } = toolArgs;
308
+ const searchPathRelative = toRelativePath(SearchPath);
309
+ const hasExtension = /\.[a-zA-Z0-9]{1,10}$/.test(SearchPath || "");
310
+ const pathType = hasExtension ? "file" : "directory";
311
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, { flexWrap: "wrap" }, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " Searching for "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, '"', Query, '"'), searchPathRelative && /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, " in ", /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, searchPathRelative), " ", pathType, "..."), !searchPathRelative && /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, "...")));
312
+ }
313
+ if (toolName === "find_files" && toolArgs) {
314
+ const { pattern } = toolArgs;
315
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " Finding files matching "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, '"', pattern, '"...')));
316
+ }
317
+ if (toolName === "fetch_url" && toolArgs) {
318
+ const { url } = toolArgs;
319
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " Fetching "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, url, "...")));
320
+ }
321
+ if (toolName === "read_binary_file" && toolArgs) {
322
+ const { file_path, remoteContext } = toolArgs;
323
+ const fileName = file_path ? path.basename(file_path) : "file";
324
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff9900", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#ff9900", bold: true }, " Reading "), /* @__PURE__ */ React.createElement(Text, { color: "#ff9900" }, formatPathWithContext(file_path, remoteContext), "...")));
325
+ }
326
+ if (toolName === "write_to_file" && toolArgs) {
327
+ const { TargetFile, remoteContext } = toolArgs;
328
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " Writing to "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(TargetFile, remoteContext), "...")));
329
+ }
330
+ if (toolName === "edit_file" && toolArgs) {
331
+ const { file_path, remoteContext } = toolArgs;
332
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " Editing "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(file_path, remoteContext), "...")));
333
+ }
334
+ if (toolName === "multi_edit_file" && toolArgs) {
335
+ const { file_path, remoteContext } = toolArgs;
336
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " Editing "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(file_path, remoteContext), "...")));
337
+ }
338
+ if (toolName === "create_image") {
339
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff9900", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#ff9900", bold: true }, " Generating image...")));
340
+ }
341
+ if (toolName === "background_command" && toolArgs) {
342
+ const { action, command, task_id, wait_seconds } = toolArgs;
343
+ let actionText = "Running background task...";
344
+ if (action === "start") {
345
+ actionText = `Starting: ${command || "command"}...`;
346
+ } else if (action === "status") {
347
+ actionText = `Checking status: ${task_id || "task"}...`;
348
+ } else if (action === "kill") {
349
+ actionText = `Killing task: ${task_id || "task"}...`;
350
+ } else if (action === "wait") {
351
+ actionText = `Waiting for ${wait_seconds || "?"} second${wait_seconds !== 1 ? "s" : ""}...`;
352
+ }
353
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff9900", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#ff9900", bold: true }, " ", toolInfo.emoji, " ", actionText)));
354
+ }
355
+ if (toolName === "get_diff" && toolArgs) {
356
+ const { filePath, staged, reason_text } = toolArgs;
357
+ const diffTarget = filePath ? `for ${filePath}` : "for all files";
358
+ const stagedText = staged ? " (staged)" : "";
359
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " ", toolInfo.emoji, " Getting diff ", diffTarget, stagedText, "...")));
360
+ }
361
+ if (toolName === "web_search" && toolArgs) {
362
+ const { query } = toolArgs;
363
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " ", toolInfo.emoji, " Searching the web for "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, '"', query, '"...')));
364
+ }
365
+ if (toolName === "fast_context_search" && toolArgs) {
366
+ const { query } = toolArgs;
367
+ let scannedFiles = [];
368
+ try {
369
+ const streamData = message.toolExecution?.streamingOutput || result;
370
+ if (streamData) {
371
+ const lines = streamData.trim().split("\n").filter(Boolean);
372
+ if (lines.length > 0) {
373
+ for (let i = lines.length - 1; i >= 0; i--) {
374
+ try {
375
+ const line = lines[i].trim();
376
+ if (line.startsWith("{")) {
377
+ const parsed = JSON.parse(line);
378
+ if (parsed.type === "scanned_files" && parsed.files) {
379
+ scannedFiles = parsed.files;
380
+ break;
381
+ }
1330
382
  }
383
+ } catch (e) {
384
+ }
1331
385
  }
1332
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
1333
- React.createElement(Box, null,
1334
- React.createElement(Text, { color: "#00cc66", bold: true },
1335
- "\u2713 ",
1336
- toolInfo.emoji,
1337
- " Checked diff ",
1338
- diffTarget ? `for ${diffTarget} ` : '',
1339
- stagedText),
1340
- React.createElement(Text, { color: "#666666" },
1341
- "(",
1342
- displayInfo,
1343
- truncated ? ', truncated' : '',
1344
- ")"))));
386
+ }
1345
387
  }
1346
- // DEFAULT - for any other tool
1347
- return renderWithThinking(React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" },
1348
- React.createElement(Box, null,
1349
- React.createElement(Text, { color: "#00cc66", bold: true },
1350
- "\u2713 ",
1351
- toolInfo.emoji,
1352
- " ",
1353
- toolInfo.verb)),
1354
- result && result.length < 300 && (React.createElement(Box, { paddingLeft: 1, marginTop: 1 },
1355
- React.createElement(Text, { color: "#aaaaaa" }, result)))));
388
+ } catch (e) {
389
+ }
390
+ const truncatedQuery = query && query.length > 50 ? query.substring(0, 47) + "..." : query || "";
391
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, " Rapid Context "), /* @__PURE__ */ React.createElement(Text, { color: "#cccccc" }, ' "', truncatedQuery, '"')), scannedFiles.length > 0 && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginLeft: 2, marginTop: 1 }, scannedFiles.map((f, i) => /* @__PURE__ */ React.createElement(Text, { key: i, color: "#666666", wrap: "truncate-end" }, "- ", toRelativePath(f)))));
1356
392
  }
1357
- return null;
393
+ if (toolName === "inspect_symbol" && toolArgs) {
394
+ const { filePath, symbols, remoteContext } = toolArgs;
395
+ const symbolList = Array.isArray(symbols) ? symbols.join(", ") : symbols || "symbols";
396
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " ", toolInfo.emoji, " Inspecting "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, symbolList, " in ", formatPathWithContext(filePath, remoteContext), "...")));
397
+ }
398
+ if (toolName === "sub_agent" && toolArgs) {
399
+ const action = toolArgs.action;
400
+ if (action === "spawn") {
401
+ const prompt = toolArgs.prompt || toolArgs.task || "Unknown task";
402
+ const complexity = toolArgs.complexity || 3;
403
+ const modelName = complexity > 5 ? "Gemini 3.1 Pro Preview" : "Gemini 3 Flash Preview";
404
+ const promptLines = prompt.split("\n");
405
+ const maxLines = 4;
406
+ const displayLines = promptLines.slice(0, maxLines);
407
+ const remainingLines = promptLines.length - maxLines;
408
+ const truncatedPrompt = displayLines.join("\n");
409
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#9945FF", bold: true }, " ", toolInfo.emoji, " Spawning Sub-Agent "), /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, "(", modelName, ")")), /* @__PURE__ */ React.createElement(Box, { marginLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, truncatedPrompt), remainingLines > 0 && /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, "... ", remainingLines, " more lines")));
410
+ } else if (action === "wait_for_status" || action === "status") {
411
+ const delay = toolArgs.time_delay || 0;
412
+ const agentId = toolArgs.agent_id || "unknown";
413
+ const waitMessage = delay > 0 ? `Waiting for ${delay} seconds...` : "Checking status...";
414
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#9945FF", bold: true }, " ", toolInfo.emoji, " Sub Agent Status "), /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, "(id: ", agentId, ")")), /* @__PURE__ */ React.createElement(Box, { marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, waitMessage)));
415
+ }
416
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#9945FF", bold: true }, " ", toolInfo.emoji, " Sub Agent "), /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, "(", action, ")")));
417
+ }
418
+ if (toolName === "workflow" && toolArgs) {
419
+ const action = toolArgs.action;
420
+ const stepNumber = toolArgs.step_number;
421
+ const exitType = toolArgs.exit_type;
422
+ const reason = toolArgs.reason;
423
+ let actionText = "Workflow action...";
424
+ let borderColor = "#00ccff";
425
+ let textColor = "#00ccff";
426
+ if (action === "step_complete") {
427
+ actionText = `Completing Step ${stepNumber || "?"}...`;
428
+ borderColor = "#00cc66";
429
+ textColor = "#00cc66";
430
+ } else if (action === "exit") {
431
+ if (exitType === "error") {
432
+ actionText = `Workflow Failed${reason ? `: ${reason.slice(0, 50)}` : ""}`;
433
+ borderColor = "#ff3366";
434
+ textColor = "#ff3366";
435
+ } else if (exitType === "cancelled") {
436
+ actionText = "Workflow Cancelled";
437
+ borderColor = "#ff9900";
438
+ textColor = "#ff9900";
439
+ } else {
440
+ actionText = "Workflow Completed";
441
+ borderColor = "#00cc66";
442
+ textColor = "#00cc66";
443
+ }
444
+ }
445
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor, paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: textColor, bold: true }, " \u{1F504} ", actionText)));
446
+ }
447
+ if (toolName === "add_mcp" && toolArgs) {
448
+ const serverName = toolArgs.name || "unknown";
449
+ const command = toolArgs.command || "";
450
+ const serverArgs = Array.isArray(toolArgs.args) ? toolArgs.args.join(" ") : "";
451
+ const fullCommand = serverArgs ? `${command} ${serverArgs}` : command;
452
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#9945FF", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#9945FF" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#9945FF", bold: true }, " \u{1F50C} Adding MCP server "), /* @__PURE__ */ React.createElement(Text, { color: "#cc99ff", bold: true }, serverName)), fullCommand && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, " ", fullCommand)));
453
+ }
454
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#003b59", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, /* @__PURE__ */ React.createElement(Spinner, { type: "arc" })), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff", bold: true }, " ", toolInfo.verb, "...")));
455
+ }
456
+ if (status === "error") {
457
+ if (toolName === "execute_command" && toolArgs) {
458
+ const command = toolArgs.command || toolArgs.CommandLine || toolArgs.commandLine || "";
459
+ const truncatedCommand = truncateCommand(command, 80);
460
+ const { cwd, remoteContext } = toolArgs;
461
+ const cleanResult = cleanShellOutput(result);
462
+ const formattedCwd = cwd && remoteContext ? `${remoteContext}:${cwd.replace(/\\/g, "/")}` : (cwd || "").replace(/\\/g, "/");
463
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff3366", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: "#ff3366", bold: true }, "\u2717 Shell "), /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, truncatedCommand, " "), cwd && /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, "[current working directory ", formattedCwd, "]"))), cleanResult && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { wrap: "wrap" }, cleanResult)));
464
+ }
465
+ return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#ff3366", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#ff3366", bold: true }, "\u2717 ", toolInfo.emoji, " ", toolInfo.verb, " failed")), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 1, marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "#ff3366" }, error || "The Agent passed invalid parameters")));
466
+ }
467
+ if (status === "completed") {
468
+ if (toolInfo.isMCP) {
469
+ return renderWithThinking(
470
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 MCP"), /* @__PURE__ */ React.createElement(Text, { color: "#aaaaaa" }, " ", toolInfo.serverName, " ", toolInfo.mcpToolName)))
471
+ );
472
+ }
473
+ if (toolName === "mark_task_complete" || toolName === "create_plan") {
474
+ return null;
475
+ }
476
+ if (toolName === "auto_context_compaction") {
477
+ return renderWithThinking(
478
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "Auto compacted context")), result && /* @__PURE__ */ React.createElement(Box, { paddingLeft: 1, marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "#aaaaaa" }, result)))
479
+ );
480
+ }
481
+ if (toolName === "execute_command" && toolArgs) {
482
+ if (toolArgs.shell_input) {
483
+ return null;
484
+ }
485
+ const command = toolArgs.command || toolArgs.CommandLine || toolArgs.commandLine || "";
486
+ const truncatedCommand = truncateCommand(command, 80);
487
+ const { cwd, remoteContext } = toolArgs;
488
+ const cleanResult = cleanShellOutput(result);
489
+ const formattedCwd = cwd && remoteContext ? `${remoteContext}:${cwd.replace(/\\/g, "/")}` : (cwd || "").replace(/\\/g, "/");
490
+ return renderWithThinking(
491
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 Shell "), /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, truncatedCommand, " "), cwd && /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, "[current working directory ", formattedCwd, "]"))), cleanResult && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { wrap: "wrap" }, cleanResult)))
492
+ );
493
+ }
494
+ if (toolName === "view_file" && toolArgs) {
495
+ const { AbsolutePath, remoteContext } = toolArgs;
496
+ const lineInfo = getViewFileLineInfo(toolArgs, result);
497
+ return renderWithThinking(
498
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Read ", lineInfo, " from "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(AbsolutePath, remoteContext))))
499
+ );
500
+ }
501
+ if (toolName === "write_to_file" && toolArgs) {
502
+ const { TargetFile, CodeContent, remoteContext } = toolArgs;
503
+ const lines = CodeContent ? CodeContent.split("\n").length : 0;
504
+ return renderWithThinking(
505
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, { flexWrap: "wrap" }, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Wrote to "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(TargetFile, remoteContext)), lines > 0 && /* @__PURE__ */ React.createElement(Text, { color: "green" }, " +", lines)), renderDiffSnippet(void 0, CodeContent))
506
+ );
507
+ }
508
+ if (toolName === "edit_file" && toolArgs) {
509
+ const { file_path, remoteContext, replacement, search_pattern } = toolArgs;
510
+ const added = replacement ? replacement.split("\n").length : 0;
511
+ const removed = search_pattern ? search_pattern.split("\n").length : 0;
512
+ return renderWithThinking(
513
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, { flexWrap: "wrap" }, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Edited "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(file_path, remoteContext)), /* @__PURE__ */ React.createElement(Text, { color: "green" }, " +", added), /* @__PURE__ */ React.createElement(Text, { color: "red" }, " -", removed)), renderDiffSnippet(search_pattern, replacement))
514
+ );
515
+ }
516
+ if (toolName === "multi_edit_file" && toolArgs) {
517
+ const { file_path, edits, remoteContext } = toolArgs;
518
+ const editList = Array.isArray(edits) ? edits : [];
519
+ let added = 0;
520
+ let removed = 0;
521
+ editList.forEach((edit) => {
522
+ if (edit.replacement || edit.ReplacementContent) {
523
+ added += (edit.replacement || edit.ReplacementContent).split("\n").length;
524
+ }
525
+ if (edit.search_pattern || edit.TargetContent) {
526
+ removed += (edit.search_pattern || edit.TargetContent).split("\n").length;
527
+ }
528
+ });
529
+ const firstEdit = editList[0];
530
+ const searchExample = firstEdit ? firstEdit.search_pattern || firstEdit.TargetContent : void 0;
531
+ const replaceExample = firstEdit ? firstEdit.replacement || firstEdit.ReplacementContent : void 0;
532
+ return renderWithThinking(
533
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, { flexWrap: "wrap" }, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Edited "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(file_path, remoteContext)), /* @__PURE__ */ React.createElement(Text, { color: "green" }, " +", added), /* @__PURE__ */ React.createElement(Text, { color: "red" }, " -", removed)), editList.length > 0 ? /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 0 }, editList.map((edit, index) => {
534
+ const search = edit.search_pattern || edit.TargetContent;
535
+ const replace = edit.replacement || edit.ReplacementContent;
536
+ return /* @__PURE__ */ React.createElement(React.Fragment, { key: index }, renderDiffSnippet(search, replace, { compact: index > 0 }));
537
+ })) : null)
538
+ );
539
+ }
540
+ if (toolName === "list_dir" && toolArgs) {
541
+ const { DirectoryPath, remoteContext } = toolArgs;
542
+ const itemStats = parseListDirResult(result);
543
+ return renderWithThinking(
544
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Listed "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(DirectoryPath, remoteContext)), itemStats !== null && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, " (", itemStats.dirs, " dir", itemStats.dirs !== 1 ? "s" : "", ", ", itemStats.files, " file", itemStats.files !== 1 ? "s" : "", ")")))
545
+ );
546
+ }
547
+ if (toolName === "grep_search" && toolArgs) {
548
+ const { Query, SearchPath } = toolArgs;
549
+ const searchResults = parseGrepSearchResult(result);
550
+ const searchPathRelative = toRelativePath(SearchPath);
551
+ const hasExtension = /\.[a-zA-Z0-9]{1,10}$/.test(SearchPath || "");
552
+ const pathType = hasExtension ? "file" : "directory";
553
+ return renderWithThinking(
554
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, { flexWrap: "wrap" }, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Searched for "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, '"', Query, '"'), searchPathRelative && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, " in ", /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, searchPathRelative), " ", pathType), searchResults && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, " (", searchResults.matches, " match", searchResults.matches !== 1 ? "es" : "", " in ", searchResults.files, " file", searchResults.files !== 1 ? "s" : "", ")"), !searchResults && result && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, " (no matches)")))
555
+ );
556
+ }
557
+ if (toolName === "find_files" && toolArgs) {
558
+ const { pattern, Pattern } = toolArgs;
559
+ const displayPattern = pattern || Pattern || "*";
560
+ const fileCount = parseFindFilesResult(result);
561
+ return renderWithThinking(
562
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Found ", fileCount !== null ? fileCount : 0, " files matching "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, '"', displayPattern, '"')))
563
+ );
564
+ }
565
+ if (toolName === "web_search" && toolArgs) {
566
+ const { query } = toolArgs;
567
+ return renderWithThinking(
568
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Searched the web for "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, '"', query, '"')))
569
+ );
570
+ }
571
+ if (toolName === "fetch_url" && toolArgs) {
572
+ const { url } = toolArgs;
573
+ return renderWithThinking(
574
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Fetched "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, url)))
575
+ );
576
+ }
577
+ if (toolName === "fast_context_search" && toolArgs) {
578
+ let answer = result || "";
579
+ let stats = void 0;
580
+ try {
581
+ if (result && result.trim().startsWith("{")) {
582
+ const parsed = JSON.parse(result);
583
+ if (parsed.answer !== void 0) {
584
+ answer = parsed.answer;
585
+ }
586
+ if (parsed.stats !== void 0) {
587
+ stats = parsed.stats;
588
+ }
589
+ }
590
+ } catch (e) {
591
+ }
592
+ const { query } = toolArgs;
593
+ const scannedFiles = stats?.scannedFiles || [];
594
+ const hasFiles = scannedFiles.length > 0;
595
+ const MAX_DISPLAY_FILES = 10;
596
+ const truncatedQuery = query && query.length > 50 ? query.substring(0, 47) + "..." : query || "";
597
+ return renderWithThinking(
598
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 Rapid Context "), /* @__PURE__ */ React.createElement(Text, { color: "#cccccc", wrap: "truncate-end" }, '"', truncatedQuery, '" '), stats && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "(Searched ", stats.filesSearched, " files in ", (stats.duration / 1e3).toFixed(1), "s)")), /* @__PURE__ */ React.createElement(Box, { paddingLeft: 1, marginTop: 1, flexDirection: "column" }, !hasFiles && answer && /* @__PURE__ */ React.createElement(Text, { color: "#aaaaaa", wrap: "truncate-end" }, answer), hasFiles && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 0 }, scannedFiles.slice(0, MAX_DISPLAY_FILES).map((f, i) => {
599
+ return /* @__PURE__ */ React.createElement(Text, { key: i, color: "#444444", wrap: "truncate-end" }, "- ", path.basename(f), " ", /* @__PURE__ */ React.createElement(Text, { color: "#333333", italic: true }, "(", toRelativePath(f), ")"));
600
+ }), scannedFiles.length > MAX_DISPLAY_FILES && /* @__PURE__ */ React.createElement(Text, { color: "#444444", italic: true }, "...and ", scannedFiles.length - MAX_DISPLAY_FILES, " more files checked"))))
601
+ );
602
+ }
603
+ if (toolName === "inspect_symbol" && toolArgs) {
604
+ const { filePath, remoteContext } = toolArgs;
605
+ const symbolResult = parseInspectSymbolResult(result);
606
+ const displayPath = filePath || "unknown";
607
+ const noSymbols = result?.includes("No symbols found");
608
+ return renderWithThinking(
609
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Inspected "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, formatPathWithContext(displayPath, remoteContext)), noSymbols && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, " (no symbols found)"), !noSymbols && symbolResult.found && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, " (", symbolResult.count, " symbol", symbolResult.count !== 1 ? "s" : "", ")")))
610
+ );
611
+ }
612
+ if (toolName === "read_binary_file" && toolArgs) {
613
+ const { file_path, remoteContext } = toolArgs;
614
+ const fileName = file_path ? path.basename(file_path) : "file";
615
+ const sizeMatch = result?.match(/Size:\s*([\d.]+\s*(?:B|KB|MB))/);
616
+ const typeMatch = result?.match(/Type:\s*([\w/+-]+)/);
617
+ const fileSize = sizeMatch ? sizeMatch[1] : "";
618
+ const fileType = typeMatch ? typeMatch[1] : "";
619
+ const isSuccess = result?.includes("Successfully uploaded");
620
+ const isError = result?.includes("Error:") || !isSuccess;
621
+ const errorMessage = result?.match(/Error:\s*(.+?)(?:\n|$)/)?.[1] || "";
622
+ return renderWithThinking(
623
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: isSuccess ? "#00cc66" : "#ff6666", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, isSuccess ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Read "), /* @__PURE__ */ React.createElement(Text, { color: "#ff9900" }, formatPathWithContext(file_path, remoteContext))) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { color: "#ff6666", bold: true }, "\u2717 ", toolInfo.emoji, " Read failed "), /* @__PURE__ */ React.createElement(Text, { color: "#ff9900" }, formatPathWithContext(file_path, remoteContext)))), isSuccess && (fileType || fileSize) && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, fileType && `${fileType}`, fileType && fileSize && " \u2022 ", fileSize && fileSize)), isError && errorMessage && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#ff6666" }, errorMessage)))
624
+ );
625
+ }
626
+ if (toolName === "sub_agent") {
627
+ const toolAction = toolArgs?.action;
628
+ const agentId = toolArgs?.agent_id || "unknown";
629
+ let title = "Sub Agent";
630
+ let details = "";
631
+ let additionalContent = null;
632
+ let structResult = null;
633
+ let markdownReport = typeof result === "string" ? result : "";
634
+ try {
635
+ if (typeof result === "string" && result.trim().startsWith("{")) {
636
+ const parsed = JSON.parse(result);
637
+ if (parsed.data && parsed.report) {
638
+ structResult = parsed.data;
639
+ markdownReport = parsed.report;
640
+ }
641
+ }
642
+ } catch (e) {
643
+ }
644
+ if (toolAction === "spawn") {
645
+ title = "Sub Agent";
646
+ const prompt = toolArgs?.prompt || "";
647
+ const shortPrompt = prompt.length > 50 ? prompt.substring(0, 47) + "..." : prompt;
648
+ const idMatch = result?.match(/Agent ID:\*\* ([\w-]+)/);
649
+ const spawnedId = idMatch ? idMatch[1] : "unknown";
650
+ details = `(id: ${spawnedId})`;
651
+ if (prompt) {
652
+ additionalContent = /* @__PURE__ */ React.createElement(Box, { marginTop: 1, marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, prompt));
653
+ }
654
+ } else if (toolAction === "wait_for_status" || toolAction === "status") {
655
+ title = "Sub Agent Status";
656
+ const statusMatch = result?.match(/Status:\*\* (.+?)\n/);
657
+ const durationMatch = result?.match(/Duration:\*\* (.+?)\n/);
658
+ const fileOpsMatch = result?.match(/File Operations:\*\* (\d+)/);
659
+ const toolCallsMatch = result?.match(/Tool Calls:\*\* (\d+)/);
660
+ const status2 = statusMatch ? statusMatch[1].trim() : "unknown";
661
+ const duration = durationMatch ? durationMatch[1].trim() : "unknown";
662
+ const fileOps = fileOpsMatch ? fileOpsMatch[1] : "0";
663
+ const toolCalls = toolCallsMatch ? toolCallsMatch[1] : "0";
664
+ details = `(id: ${agentId}, status: ${status2}, duration: ${duration}, files: ${fileOps}, tools: ${toolCalls})`;
665
+ } else if (toolAction === "terminate") {
666
+ title = "Sub Agent Terminated";
667
+ details = `(id: ${agentId})`;
668
+ } else if (toolAction === "read_results") {
669
+ title = "Sub Agent Results";
670
+ if (structResult) {
671
+ details = `(id: ${structResult.agentId}, duration: ${structResult.duration})`;
672
+ if (structResult.fileOperations && structResult.fileOperations.length > 0) {
673
+ additionalContent = /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "Files Modified:"), structResult.fileOperations.map((op, i) => /* @__PURE__ */ React.createElement(Box, { key: i, marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, "\u2022 ", op.path, " ", /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, "(", op.type, ")")))));
674
+ }
675
+ } else {
676
+ details = `(id: ${agentId})`;
677
+ const summary = result?.length > 100 ? result.substring(0, 97) + "..." : result;
678
+ additionalContent = /* @__PURE__ */ React.createElement(Text, { color: "#666666", dimColor: true }, summary);
679
+ }
680
+ }
681
+ return renderWithThinking(
682
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " ", title, " "), /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, details)), additionalContent)
683
+ );
684
+ }
685
+ if (toolName === "create_image" && toolArgs) {
686
+ const { output_path, aspect_ratio } = toolArgs;
687
+ const sizeMatch = result?.match(/\*\*Size:\*\*\s*([\d.]+\s*KB)/);
688
+ const formatMatch = result?.match(/\*\*Format:\*\*\s*([\w/]+)/);
689
+ const fileSize = sizeMatch ? sizeMatch[1] : "";
690
+ const format = formatMatch ? formatMatch[1] : "";
691
+ const isSuccess = result?.includes("generated successfully");
692
+ return renderWithThinking(
693
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: isSuccess ? "#00cc66" : "#ff6666", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, isSuccess ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Generated image "), /* @__PURE__ */ React.createElement(Text, { color: "#00ccff" }, toRelativePath(output_path)), (fileSize || format) && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, " (", format, format && fileSize ? " \u2022 " : "", fileSize, ")")) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { color: "#ff6666", bold: true }, "\u2717 ", toolInfo.emoji, " Image generation failed"))))
694
+ );
695
+ }
696
+ if (toolName === "background_command" && toolArgs) {
697
+ const { action, command, task_id, wait_seconds } = toolArgs;
698
+ let actionText = "Background command";
699
+ let actionDetail = "";
700
+ if (action === "start") {
701
+ actionText = "Started background task";
702
+ actionDetail = command ? `(${command})` : "";
703
+ } else if (action === "status") {
704
+ actionText = "Checked task status";
705
+ actionDetail = task_id ? `(${task_id})` : "";
706
+ } else if (action === "kill") {
707
+ actionText = "Killed background task";
708
+ actionDetail = task_id ? `(${task_id})` : "";
709
+ } else if (action === "wait") {
710
+ actionText = "Waited for";
711
+ actionDetail = wait_seconds ? `${wait_seconds} second${wait_seconds !== 1 ? "s" : ""}` : "";
712
+ }
713
+ return renderWithThinking(
714
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " ", actionText), actionDetail && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, " ", actionDetail)))
715
+ );
716
+ }
717
+ if (toolName === "workflow" && toolArgs) {
718
+ const action = toolArgs.action;
719
+ const stepNumber = toolArgs.step_number;
720
+ const exitType = toolArgs.exit_type;
721
+ const reason = toolArgs.reason;
722
+ let actionText = "Workflow action";
723
+ let borderColor = "#00cc66";
724
+ let textColor = "#00cc66";
725
+ let icon = "\u2713";
726
+ if (action === "step_complete") {
727
+ actionText = `Step ${stepNumber || "?"} Complete`;
728
+ borderColor = "#00cc66";
729
+ textColor = "#00cc66";
730
+ } else if (action === "exit") {
731
+ if (exitType === "error") {
732
+ actionText = `Workflow Failed${reason ? `: ${reason.slice(0, 50)}` : ""}`;
733
+ borderColor = "#ff3366";
734
+ textColor = "#ff3366";
735
+ icon = "\u2717";
736
+ } else if (exitType === "cancelled") {
737
+ actionText = "Workflow Cancelled";
738
+ borderColor = "#ff9900";
739
+ textColor = "#ff9900";
740
+ icon = "\u26A0";
741
+ } else {
742
+ actionText = "Workflow Completed";
743
+ borderColor = "#00cc66";
744
+ textColor = "#00cc66";
745
+ }
746
+ }
747
+ return renderWithThinking(
748
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor, paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: textColor, bold: true }, icon, " \u{1F504} ", actionText)))
749
+ );
750
+ }
751
+ if (toolName === "get_diff" && toolArgs) {
752
+ const { filePath, staged } = toolArgs;
753
+ const diffTarget = filePath ? toRelativePath(filePath) : "";
754
+ const stagedText = staged ? " (staged)" : "";
755
+ let parsedResult = result || "";
756
+ let parsedSummary = "";
757
+ try {
758
+ if (result) {
759
+ const json = JSON.parse(result);
760
+ parsedResult = json.result || result;
761
+ parsedSummary = json.summary || "";
762
+ }
763
+ } catch {
764
+ }
765
+ const hasChanges = !parsedResult.includes("No changes") && !parsedSummary.includes("No changes");
766
+ const truncated = parsedResult.includes("[Diff truncated");
767
+ let displayInfo = "no changes";
768
+ if (hasChanges) {
769
+ if (parsedSummary) {
770
+ displayInfo = parsedSummary;
771
+ } else {
772
+ const filesMatch = parsedResult.match(/(\d+)\s+file\(?s?\)?\s+changed/);
773
+ displayInfo = filesMatch ? `${filesMatch[1]} file(s) changed` : "changes detected";
774
+ }
775
+ }
776
+ return renderWithThinking(
777
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00cc66", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " Checked diff ", diffTarget ? `for ${diffTarget} ` : "", stagedText), /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, "(", displayInfo, truncated ? ", truncated" : "", ")")))
778
+ );
779
+ }
780
+ if (toolName === "add_mcp" && toolArgs) {
781
+ const serverName = toolArgs.name || "unknown";
782
+ const isSuccess = result && result.includes("SUCCESS");
783
+ const borderColor = isSuccess ? "#9945FF" : "#ff3366";
784
+ const statusIcon = isSuccess ? "\u2713" : "\u2717";
785
+ const statusColor = isSuccess ? "#00cc66" : "#ff3366";
786
+ let toolCount = "";
787
+ const toolCountMatch = result?.match(/Available tools \((\d+)\)/);
788
+ if (toolCountMatch) {
789
+ toolCount = ` (${toolCountMatch[1]} tools)`;
790
+ }
791
+ let errorMsg = "";
792
+ if (!isSuccess) {
793
+ const errorMatch = result?.match(/Error: (.+)/);
794
+ if (errorMatch) {
795
+ errorMsg = errorMatch[1];
796
+ }
797
+ }
798
+ return renderWithThinking(
799
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor, paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: statusColor, bold: true }, statusIcon, " \u{1F50C} ", isSuccess ? "Connected" : "Failed", " MCP server "), /* @__PURE__ */ React.createElement(Text, { color: "#cc99ff", bold: true }, serverName), toolCount && /* @__PURE__ */ React.createElement(Text, { color: "#666666" }, toolCount)), errorMsg && /* @__PURE__ */ React.createElement(Box, { paddingLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "#ff6699" }, errorMsg)))
800
+ );
801
+ }
802
+ return renderWithThinking(
803
+ /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "#00ccff", paddingX: 1, marginBottom: 1, flexGrow: 0, alignSelf: "flex-start" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "#00cc66", bold: true }, "\u2713 ", toolInfo.emoji, " ", toolInfo.verb)), result && result.length < 300 && /* @__PURE__ */ React.createElement(Box, { paddingLeft: 1, marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "#aaaaaa" }, result)))
804
+ );
805
+ }
806
+ return null;
1358
807
  }, (prevProps, nextProps) => {
1359
- // Only re-render if the status or key fields changed
1360
- const prevExec = prevProps.message.toolExecution;
1361
- const nextExec = nextProps.message.toolExecution;
1362
- if (!prevExec || !nextExec)
1363
- return false;
1364
- return prevExec.status === nextExec.status &&
1365
- prevExec.toolName === nextExec.toolName &&
1366
- prevExec.result === nextExec.result &&
1367
- prevExec.error === nextExec.error &&
1368
- prevExec.streamingOutput === nextExec.streamingOutput;
808
+ const prevExec = prevProps.message.toolExecution;
809
+ const nextExec = nextProps.message.toolExecution;
810
+ if (!prevExec || !nextExec) return false;
811
+ return prevExec.status === nextExec.status && prevExec.toolName === nextExec.toolName && prevExec.result === nextExec.result && prevExec.error === nextExec.error && prevExec.streamingOutput === nextExec.streamingOutput;
1369
812
  });
813
+ export {
814
+ ToolExecutionMessage
815
+ };
1370
816
  //# sourceMappingURL=ToolExecutionMessage.js.map