From be5af5469fefb4869945b8a1ce691ee3733a9293 Mon Sep 17 00:00:00 2001 From: Ed Zynda Date: Fri, 27 Jun 2025 11:54:17 +0300 Subject: [PATCH] fix tool output --- internal/ui/messages.go | 65 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/internal/ui/messages.go b/internal/ui/messages.go index 29581eab..14ca5822 100644 --- a/internal/ui/messages.go +++ b/internal/ui/messages.go @@ -420,10 +420,20 @@ func (r *MessageRenderer) formatToolResult(toolName, result string, width int) s } } - // Format as code block for most tools + // Format bash/command output with better formatting if strings.Contains(toolName, "bash") || strings.Contains(toolName, "command") { - formatted := fmt.Sprintf("```bash\n%s\n```", result) - return r.renderMarkdown(formatted, width) + theme := getTheme() + + // Split result into sections if it contains both stdout and stderr + if strings.Contains(result, "") || strings.Contains(result, "") { + return r.formatBashOutput(result, width, theme) + } + + // For simple output, just render as monospace text with proper line breaks + return baseStyle. + Width(width). + Foreground(theme.Muted). + Render(result) } // For other tools, render as muted text @@ -434,6 +444,55 @@ func (r *MessageRenderer) formatToolResult(toolName, result string, width int) s Render(result) } +// formatBashOutput formats bash command output with proper section handling +func (r *MessageRenderer) formatBashOutput(result string, width int, theme Theme) string { + baseStyle := lipgloss.NewStyle() + + // Parse the output sections + lines := strings.Split(result, "\n") + var formattedLines []string + currentSection := "" + + for _, line := range lines { + if strings.HasPrefix(line, "") { + currentSection = "stdout" + if len(strings.TrimSpace(strings.TrimPrefix(line, ""))) > 0 { + // If there's content on the same line as + content := strings.TrimSpace(strings.TrimPrefix(line, "")) + formattedLines = append(formattedLines, content) + } + continue + } else if strings.HasPrefix(line, "") { + currentSection = "stderr" + if len(strings.TrimSpace(strings.TrimPrefix(line, ""))) > 0 { + // If there's content on the same line as + content := strings.TrimSpace(strings.TrimPrefix(line, "")) + styledLine := baseStyle.Foreground(theme.Error).Render(content) + formattedLines = append(formattedLines, styledLine) + } + continue + } else if line == "" { + // Preserve empty lines but don't add extra spacing + formattedLines = append(formattedLines, "") + continue + } + + // Regular content line + if currentSection == "stderr" { + styledLine := baseStyle.Foreground(theme.Error).Render(line) + formattedLines = append(formattedLines, styledLine) + } else { + // stdout or no section - use normal muted color + formattedLines = append(formattedLines, line) + } + } + + return baseStyle. + Width(width). + Foreground(theme.Muted). + Render(strings.Join(formattedLines, "\n")) +} + // truncateText truncates text to fit within the specified width func (r *MessageRenderer) truncateText(text string, maxWidth int) string { // In debug mode, don't truncate - just replace newlines with spaces