Files
kit/internal/ui/format.go
Ed Zynda 9a662d440c fix(ui): reduce TUI visual noise and improve layout
- remove "You" label and icon from user messages, use borderless content block
- remove input title bar ("Enter your prompt...") and hint line
- increase textarea from 3 to 4 rows with top/bottom margin
- hide input hints permanently for a cleaner UI
- match separator colors (use theme.Border for both startup and input dividers)
- make startup separator full terminal width instead of hardcoded 80
- add /help for help hint and pipe separators to status bar
- add printCustomMessage/RenderCustomMessage for custom alert labels
- render /help output as markdown with "Help" alert label
- add Ctrl+V (paste image) to help message keys section
- fix reasoning text wrapping using ANSI-aware lipgloss.Style.Width
- export HighlightFileTokens for cross-package use
2026-04-22 11:41:09 +03:00

85 lines
2.9 KiB
Go

package ui
import (
"strings"
"time"
"charm.land/lipgloss/v2"
"github.com/mark3labs/kit/internal/ui/style"
)
// Renderer is the interface satisfied by MessageRenderer. It allows model.go
// and cli.go to call rendering methods uniformly.
type Renderer interface {
RenderUserMessage(content string, timestamp time.Time) UIMessage
RenderAssistantMessage(content string, timestamp time.Time, modelName string) UIMessage
RenderReasoningBlock(content string, timestamp time.Time) UIMessage
RenderToolMessage(toolName, toolArgs, toolResult string, isError bool) UIMessage
RenderSystemMessage(content string, timestamp time.Time) UIMessage
RenderCustomMessage(content, label string, timestamp time.Time) UIMessage
RenderErrorMessage(errorMsg string, timestamp time.Time) UIMessage
RenderDebugMessage(message string, timestamp time.Time) UIMessage
RenderDebugConfigMessage(config map[string]any, timestamp time.Time) UIMessage
SetWidth(width int)
UpdateTheme()
}
// Compile-time check that MessageRenderer satisfies the Renderer interface.
var _ Renderer = (*MessageRenderer)(nil)
// parseBashOutput parses <stdout>/<stderr> tagged output from bash tool
// results, styling stderr with the theme's error color. Returns the
// combined, styled output string with tags stripped.
//
// Shared by MessageRenderer.
func parseBashOutput(result string, theme style.Theme) string {
var formattedResult strings.Builder
remaining := result
for {
// Find stderr tags
stderrStart := strings.Index(remaining, "<stderr>")
stderrEnd := strings.Index(remaining, "</stderr>")
// Find stdout tags
stdoutStart := strings.Index(remaining, "<stdout>")
stdoutEnd := strings.Index(remaining, "</stdout>")
// Process whichever comes first
if stderrStart != -1 && stderrEnd != -1 && stderrEnd > stderrStart &&
(stdoutStart == -1 || stderrStart < stdoutStart) {
// Process stderr
if stderrStart > 0 {
formattedResult.WriteString(remaining[:stderrStart])
}
stderrContent := remaining[stderrStart+8 : stderrEnd]
stderrContent = strings.Trim(stderrContent, "\n")
if len(stderrContent) > 0 {
styledContent := lipgloss.NewStyle().Foreground(theme.Error).Render(stderrContent)
formattedResult.WriteString(styledContent)
}
remaining = remaining[stderrEnd+9:] // Skip past </stderr>
} else if stdoutStart != -1 && stdoutEnd != -1 && stdoutEnd > stdoutStart {
// Process stdout
if stdoutStart > 0 {
formattedResult.WriteString(remaining[:stdoutStart])
}
stdoutContent := remaining[stdoutStart+8 : stdoutEnd]
stdoutContent = strings.Trim(stdoutContent, "\n")
if len(stdoutContent) > 0 {
formattedResult.WriteString(stdoutContent)
}
remaining = remaining[stdoutEnd+9:] // Skip past </stdout>
} else {
// No more tags, add remaining content
formattedResult.WriteString(remaining)
break
}
}
return strings.TrimSpace(formattedResult.String())
}