@@ -15,6 +15,7 @@ import (
15 "github.com/charmbracelet/crush/internal/diff"
15 "github.com/charmbracelet/crush/internal/diff"
16 "github.com/charmbracelet/crush/internal/fsext"
16 "github.com/charmbracelet/crush/internal/fsext"
17 "github.com/charmbracelet/crush/internal/message"
17 "github.com/charmbracelet/crush/internal/message"
18+ "github.com/charmbracelet/crush/internal/stringext"
18 "github.com/charmbracelet/crush/internal/ui/anim"
19 "github.com/charmbracelet/crush/internal/ui/anim"
19 "github.com/charmbracelet/crush/internal/ui/common"
20 "github.com/charmbracelet/crush/internal/ui/common"
20 "github.com/charmbracelet/crush/internal/ui/styles"
21 "github.com/charmbracelet/crush/internal/ui/styles"
@@ -531,9 +532,7 @@ func toolHeader(sty *styles.Styles, status ToolStatus, name string, width int, n
532// toolOutputPlainContent renders plain text with optional expansion support.
533// toolOutputPlainContent renders plain text with optional expansion support.
533func toolOutputPlainContent(sty *styles.Styles, content string, width int, expanded bool) string {
534func toolOutputPlainContent(sty *styles.Styles, content string, width int, expanded bool) string {
534− content = strings.ReplaceAll(content, "\r\n", "\n")
535+ content = stringext.NormalizeSpace(content)
535− content = strings.ReplaceAll(content, "\t", " ")
536− content = strings.TrimSpace(content)
537 lines := strings.Split(content, "\n")
536 lines := strings.Split(content, "\n")
539 maxLines := responseContextHeight
538 maxLines := responseContextHeight
@@ -566,8 +565,7 @@ func toolOutputPlainContent(sty *styles.Styles, content string, width int, expan
567// toolOutputCodeContent renders code with syntax highlighting and line numbers.
566// toolOutputCodeContent renders code with syntax highlighting and line numbers.
568func toolOutputCodeContent(sty *styles.Styles, path, content string, offset, width int, expanded bool) string {
567func toolOutputCodeContent(sty *styles.Styles, path, content string, offset, width int, expanded bool) string {
569− content = strings.ReplaceAll(content, "\r\n", "\n")
568+ content = stringext.NormalizeSpace(content)
570− content = strings.ReplaceAll(content, "\t", " ")
572 lines := strings.Split(content, "\n")
570 lines := strings.Split(content, "\n")
573 maxLines := responseContextHeight
571 maxLines := responseContextHeight
@@ -776,9 +774,7 @@ func roundedEnumerator(lPadding, width int) tree.Enumerator {
777// toolOutputMarkdownContent renders markdown content with optional truncation.
775// toolOutputMarkdownContent renders markdown content with optional truncation.
778func toolOutputMarkdownContent(sty *styles.Styles, content string, width int, expanded bool) string {
776func toolOutputMarkdownContent(sty *styles.Styles, content string, width int, expanded bool) string {
779− content = strings.ReplaceAll(content, "\r\n", "\n")
777+ content = stringext.NormalizeSpace(content)
780− content = strings.ReplaceAll(content, "\t", " ")
781− content = strings.TrimSpace(content)
783 // Cap width for readability.
779 // Cap width for readability.
784 if width > maxTextWidth {
780 if width > maxTextWidth {