feat: cap streaming bash output height and replace with tool result

- Limit streaming bash output to 20 lines max during live display
- Remove streaming bash item when tool completes
- Replace with truncated tool result block
- Expand background color to full terminal width with proper indentation
- Matches renderBashBody styling (lineIndent + width)

This prevents long-running commands from growing the UI forever while
still showing live output up to a reasonable height.
This commit is contained in:
Ed Zynda
2026-03-31 17:42:32 +03:00
parent ea6ddc8792
commit 1ad493c5c7
2 changed files with 25 additions and 10 deletions
+9 -4
View File
@@ -270,14 +270,18 @@ func (m *StreamingBashOutputItem) Render(width int) string {
parts = append(parts, headerStyle.Render(fmt.Sprintf("▸ %s", m.command)))
}
const lineIndent = " "
lineWidth := width - len(lineIndent)
// Stdout lines
if len(m.stdoutLines) > 0 {
outputStyle := lipgloss.NewStyle().
Foreground(theme.Text).
Background(theme.CodeBg).
PaddingLeft(2)
PaddingLeft(1).
Width(lineWidth)
for _, line := range m.stdoutLines {
parts = append(parts, outputStyle.Render(line))
parts = append(parts, lineIndent+outputStyle.Render(line))
}
}
@@ -286,9 +290,10 @@ func (m *StreamingBashOutputItem) Render(width int) string {
stderrStyle := lipgloss.NewStyle().
Foreground(theme.Error).
Background(theme.CodeBg).
PaddingLeft(2)
PaddingLeft(1).
Width(lineWidth)
for _, line := range m.stderrLines {
parts = append(parts, stderrStyle.Render(line))
parts = append(parts, lineIndent+stderrStyle.Render(line))
}
}
+16 -6
View File
@@ -1492,16 +1492,18 @@ func (m *AppModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
case app.ToolResultEvent:
// Buffer tool result for scrollback.
m.printToolResult(msg)
// Mark streaming bash output as complete.
// Remove streaming bash output item (if present) before adding the final tool result.
// The tool result will contain the truncated output.
if len(m.messages) > 0 {
if bashItem, ok := m.messages[len(m.messages)-1].(*StreamingBashOutputItem); ok {
bashItem.MarkComplete()
if _, ok := m.messages[len(m.messages)-1].(*StreamingBashOutputItem); ok {
// Remove the streaming bash item
m.messages = m.messages[:len(m.messages)-1]
}
}
// Add the final tool result with truncated output.
m.printToolResult(msg)
// Clear legacy bash output state
m.streamingBashOutput = nil
m.streamingBashStderr = nil
@@ -1538,6 +1540,14 @@ func (m *AppModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
bashItem.AppendStdout(msg.Chunk)
}
// Check height and cap if needed - we don't want streaming output to grow forever
const maxStreamingBashHeight = 20 // Max lines to show during streaming
if bashItem.Height() > maxStreamingBashHeight {
// Stop showing new output once we hit the limit
// The final tool result will show truncated output
return m, nil
}
// Refresh ScrollList
m.refreshContent()