chore(ui): standardize truncation message format

Ayman Bagabas created

Change summary

internal/ui/chat/assistant.go |  8 ++++++--
internal/ui/chat/tools.go     | 14 +++++++-------
2 files changed, 13 insertions(+), 9 deletions(-)

Detailed changes

internal/ui/chat/assistant.go 🔗

@@ -13,6 +13,10 @@ import (
 	"github.com/charmbracelet/x/ansi"
 )
 
+// assistantMessageTruncateFormat is the text shown when an assistant message is
+// truncated.
+const assistantMessageTruncateFormat = "… (%d lines hidden) [click or space to expand]"
+
 // maxCollapsedThinkingHeight defines the maximum height of the thinking
 const maxCollapsedThinkingHeight = 10
 
@@ -153,9 +157,9 @@ func (a *AssistantMessageItem) renderThinking(thinking string, width int) string
 	if !a.thinkingExpanded && isTruncated {
 		lines = lines[totalLines-maxCollapsedThinkingHeight:]
 		hint := a.sty.Chat.Message.ThinkingTruncationHint.Render(
-			fmt.Sprintf("… (%d lines hidden) [click or space to expand]", totalLines-maxCollapsedThinkingHeight),
+			fmt.Sprintf(assistantMessageTruncateFormat, totalLines-maxCollapsedThinkingHeight),
 		)
-		lines = append(lines, "", hint)
+		lines = append([]string{hint, ""}, lines...)
 	}
 
 	thinkingStyle := a.sty.Chat.Message.ThinkingBox.Width(width)

internal/ui/chat/tools.go 🔗

@@ -434,7 +434,7 @@ func toolOutputPlainContent(sty *styles.Styles, content string, width int, expan
 	if !expanded && wasTruncated {
 		out = append(out, sty.Tool.ContentTruncation.
 			Width(width).
-			Render(fmt.Sprintf("… (%d lines) [click or space to expand]", len(lines)-responseContextHeight)))
+			Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-responseContextHeight)))
 	}
 
 	return strings.Join(out, "\n")
@@ -489,8 +489,8 @@ func toolOutputCodeContent(sty *styles.Styles, path, content string, offset, wid
 	if len(lines) > maxLines && !expanded {
 		truncMsg := sty.Tool.ContentCodeTruncation.
 			Width(bodyWidth).
-			Render(fmt.Sprintf("… (%d lines) [click or space to expand]", len(lines)-maxLines))
-		out = append(out, truncMsg)
+			Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines))
+		out = append([]string{truncMsg}, out...)
 	}
 
 	return sty.Tool.Body.Render(strings.Join(out, "\n"))
@@ -567,8 +567,8 @@ func toolOutputDiffContent(sty *styles.Styles, file, oldContent, newContent stri
 	if len(lines) > maxLines && !expanded {
 		truncMsg := sty.Tool.DiffTruncation.
 			Width(bodyWidth).
-			Render(fmt.Sprintf("… (%d lines) [click or space to expand]", len(lines)-maxLines))
-		formatted = strings.Join(lines[:maxLines], "\n") + "\n" + truncMsg
+			Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines))
+		formatted = truncMsg + "\n" + strings.Join(lines[:maxLines], "\n")
 	}
 
 	return sty.Tool.Body.Render(formatted)
@@ -600,8 +600,8 @@ func toolOutputMultiEditDiffContent(sty *styles.Styles, file string, meta tools.
 	if len(lines) > maxLines && !expanded {
 		truncMsg := sty.Tool.DiffTruncation.
 			Width(bodyWidth).
-			Render(fmt.Sprintf("… (%d lines) [click or space to expand]", len(lines)-maxLines))
-		formatted = strings.Join(lines[:maxLines], "\n") + "\n" + truncMsg
+			Render(fmt.Sprintf(assistantMessageTruncateFormat, len(lines)-maxLines))
+		formatted = truncMsg + "\n" + strings.Join(lines[:maxLines], "\n")
 	}
 
 	// Add failed edits note if any exist.