@@ -15,6 +15,7 @@ import (
1515 "github.com/charmbracelet/crush/internal/diff"
1616 "github.com/charmbracelet/crush/internal/fsext"
1717 "github.com/charmbracelet/crush/internal/message"
18+ "github.com/charmbracelet/crush/internal/stringext"
1819 "github.com/charmbracelet/crush/internal/ui/anim"
1920 "github.com/charmbracelet/crush/internal/ui/common"
2021 "github.com/charmbracelet/crush/internal/ui/styles"
@@ -531,9 +532,7 @@ func toolHeader(sty *styles.Styles, status ToolStatus, name string, width int, n
531532
532533// toolOutputPlainContent renders plain text with optional expansion support.
533534func toolOutputPlainContent(sty *styles.Styles, content string, width int, expanded bool) string {
534− content = strings.ReplaceAll(content, "\r\n", "\n")
535− content = strings.ReplaceAll(content, "\t", " ")
536− content = strings.TrimSpace(content)
535+ content = stringext.NormalizeSpace(content)
537536 lines := strings.Split(content, "\n")
538537
539538 maxLines := responseContextHeight
@@ -566,8 +565,7 @@ func toolOutputPlainContent(sty *styles.Styles, content string, width int, expan
566565
567566// toolOutputCodeContent renders code with syntax highlighting and line numbers.
568567func toolOutputCodeContent(sty *styles.Styles, path, content string, offset, width int, expanded bool) string {
569− content = strings.ReplaceAll(content, "\r\n", "\n")
570− content = strings.ReplaceAll(content, "\t", " ")
568+ content = stringext.NormalizeSpace(content)
571569
572570 lines := strings.Split(content, "\n")
573571 maxLines := responseContextHeight
@@ -776,9 +774,7 @@ func roundedEnumerator(lPadding, width int) tree.Enumerator {
776774
777775// toolOutputMarkdownContent renders markdown content with optional truncation.
778776func toolOutputMarkdownContent(sty *styles.Styles, content string, width int, expanded bool) string {
779− content = strings.ReplaceAll(content, "\r\n", "\n")
780− content = strings.ReplaceAll(content, "\t", " ")
781− content = strings.TrimSpace(content)
777+ content = stringext.NormalizeSpace(content)
782778
783779 // Cap width for readability.
784780 if width > maxTextWidth {