Documentation
¶
Overview ¶
Package tui provides the terminal user interface for Falcon. It uses Bubble Tea for the TUI framework with a minimal, Claude Code-inspired design.
File organization: - app.go: Entry point (Run function) - model.go: Model struct and message types - init.go: Model initialization and tool registration - update.go: Event handling and state updates - view.go: Rendering and display logic - keys.go: Keyboard input handling - styles.go: Visual styling (colors, borders, etc.) - highlight.go: JSON syntax highlighting
Index ¶
Constants ¶
const ( ContentPadLeft = 2 // Left padding for viewport content ContentPadRight = 2 // Right padding for viewport content )
Content layout constants
const ( ThinkingPrefix = " thinking " ToolPrefix = " tool " ObservationPrefix = " result " ErrorPrefix = " error " Separator = "───" ToolCallPrefix = "○ " // Circle prefix for tool calls (legacy) )
Log prefixes
const FalconASCII = `` /* 781-byte string literal not displayed */
Variables ¶
var ( // USER: Adjust these colors to change the theme DimColor = lipgloss.Color("#6c6c6c") TextColor = lipgloss.Color("#e0e0e0") AccentColor = lipgloss.Color("#7aa2f7") // The blue cursor/spinner color ErrorColor = lipgloss.Color("#f7768e") ToolColor = lipgloss.Color("#9ece6a") MutedColor = lipgloss.Color("#545454") SuccessColor = lipgloss.Color("#73daca") WarningColor = lipgloss.Color("#e0af68") // Yellow/orange for warnings // OpenCode-style colors UserMessageBg = lipgloss.Color("#2a2a2a") // Gray background for user messages InputAreaBg = lipgloss.Color("#2a2a2a") // Matches user messages ModelBadgeBg = lipgloss.Color("#565f89") // Model name badge // Compact tool call colors ToolNameColor = lipgloss.Color("#cf8a6b") // Warm orange for tool names ToolArgsColor = lipgloss.Color("#6c6c6c") // Dim for arguments ToolUseColor = lipgloss.Color("#545454") // Very muted for usage fraction // Response card ResponseCardBg = lipgloss.Color("#1e1e2e") // Slightly elevated background ResponseCardBorder = lipgloss.Color("#3b3b5c") // Subtle border )
Minimal color palette
var ( UserStyle = lipgloss.NewStyle(). Foreground(TextColor) ThinkingStyle = lipgloss.NewStyle(). Foreground(DimColor). Italic(true) ToolStyle = lipgloss.NewStyle(). Foreground(ToolColor) ObservationStyle = lipgloss.NewStyle(). Foreground(DimColor) ResponseStyle = lipgloss.NewStyle(). Foreground(TextColor) ErrorStyle = lipgloss.NewStyle(). Foreground(ErrorColor) RetryStyle = lipgloss.NewStyle(). Foreground(lipgloss.Color("#e0af68")) // Interrupted style - faded/muted for agent interruption InterruptedStyle = lipgloss.NewStyle(). Foreground(MutedColor). Italic(true) PromptStyle = lipgloss.NewStyle(). Foreground(AccentColor) HelpStyle = lipgloss.NewStyle(). Foreground(DimColor) // Status line styles StatusIdleStyle = lipgloss.NewStyle(). Foreground(DimColor) StatusActiveStyle = lipgloss.NewStyle(). Foreground(AccentColor) StatusToolStyle = lipgloss.NewStyle(). Foreground(ToolColor) // Status label style (for "thinking", "streaming", "tool calling") StatusLabelStyle = lipgloss.NewStyle(). Foreground(DimColor) // Separator style SeparatorStyle = lipgloss.NewStyle(). Foreground(MutedColor) // Shortcut key style ShortcutKeyStyle = lipgloss.NewStyle(). Foreground(AccentColor) ShortcutDescStyle = lipgloss.NewStyle(). Foreground(DimColor) FooterAppNameStyle = lipgloss.NewStyle(). Foreground(AccentColor). Bold(true). PaddingRight(1) Foreground(DimColor). PaddingRight(1) Foreground(lipgloss.Color("#4ec9b0")). Bold(true). PaddingRight(1) Foreground(DimColor) // Splash screen styles SplashStyle = lipgloss.NewStyle(). Foreground(AccentColor). Bold(true). MarginLeft(ContentPadLeft). MarginTop(1). MarginBottom(1) SplashInfoStyle = lipgloss.NewStyle(). Foreground(DimColor). MarginLeft(ContentPadLeft) SplashVersionStyle = lipgloss.NewStyle(). Foreground(TextColor). Bold(true) )
Log entry styles
var ( // User message: blue left border + gray background + vertical spacing UserMessageStyle = lipgloss.NewStyle(). Background(UserMessageBg). BorderStyle(lipgloss.ThickBorder()). BorderForeground(AccentColor). BorderLeft(true). BorderTop(false). BorderRight(true). BorderBottom(false). Padding(1, 2). MarginLeft(ContentPadLeft). MarginTop(1). MarginBottom(1) // Tool block: groups all tool calls in one agent turn into a styled container ToolBlockStyle = lipgloss.NewStyle(). BorderStyle(lipgloss.ThickBorder()). BorderForeground(ToolNameColor). BorderLeft(true). BorderTop(false). BorderRight(false). BorderBottom(false). MarginLeft(ContentPadLeft) // Compact tool call styles ToolNameCompactStyle = lipgloss.NewStyle(). Foreground(ToolNameColor) ToolArgsCompactStyle = lipgloss.NewStyle(). Foreground(ToolArgsColor) ToolUsageCompactStyle = lipgloss.NewStyle(). Foreground(ToolUseColor) ToolDurationStyle = lipgloss.NewStyle(). Foreground(MutedColor) // Tool calls: dimmed with circle prefix (legacy, kept for compatibility) ToolCallStyle = lipgloss.NewStyle(). Foreground(DimColor) // Agent messages: plain text with left margin + top spacing AgentMessageStyle = lipgloss.NewStyle(). Foreground(TextColor). MarginLeft(ContentPadLeft). MarginTop(1) // System messages: single compact line for status updates (model switch, etc.) SystemMessageStyle = lipgloss.NewStyle(). Foreground(DimColor). Italic(true). MarginLeft(ContentPadLeft) // Response card: subtle box for tool output/responses ResponseCardStyle = lipgloss.NewStyle(). Background(ResponseCardBg). BorderStyle(lipgloss.RoundedBorder()). BorderForeground(ResponseCardBorder). Padding(1, 2). MarginLeft(2) // Input area: matches user message style exactly (same borders, padding, margin) InputAreaStyle = lipgloss.NewStyle(). Background(InputAreaBg). BorderStyle(lipgloss.ThickBorder()). BorderForeground(AccentColor). BorderLeft(true). BorderTop(false). BorderRight(true). BorderBottom(false). Padding(1, 2). MarginLeft(ContentPadLeft) FooterStyle = lipgloss.NewStyle(). Background(FooterBg). Foreground(DimColor). PaddingLeft(2) // Model badge ModelBadgeStyle = lipgloss.NewStyle(). Background(ModelBadgeBg). Foreground(TextColor). Padding(0, 1) )
OpenCode-style message block styles
var ( // Normal usage (green) ToolUsageNormalStyle = lipgloss.NewStyle(). Foreground(ToolColor) // Warning usage (70-89% - yellow) ToolUsageWarningStyle = lipgloss.NewStyle(). Foreground(WarningColor) // Critical usage (90%+ - red) ToolUsageCriticalStyle = lipgloss.NewStyle(). Foreground(ErrorColor) // Tool name in usage display ToolUsageNameStyle = lipgloss.NewStyle(). Foreground(DimColor) // Total usage style TotalUsageStyle = lipgloss.NewStyle(). Foreground(AccentColor) )
Tool usage display styles
var ( DiffAddColor = lipgloss.Color("#73daca") // Green - added lines DiffRemoveColor = lipgloss.Color("#f7768e") // Red - removed lines DiffHunkColor = lipgloss.Color("#7aa2f7") // Blue - hunk headers @@ DiffHeaderColor = lipgloss.Color("#e0af68") // Yellow - file headers ---/+++ )
Diff colors for file write confirmation
var ( DiffAddStyle = lipgloss.NewStyle(). Foreground(DiffAddColor) DiffRemoveStyle = lipgloss.NewStyle(). Foreground(DiffRemoveColor) DiffHunkStyle = lipgloss.NewStyle(). Foreground(DiffHunkColor) DiffHeaderStyle = lipgloss.NewStyle(). Foreground(DiffHeaderColor). Bold(true) DiffContextStyle = lipgloss.NewStyle(). Foreground(DimColor) )
Diff styles
var ( TagChipStyle = lipgloss.NewStyle(). Foreground(AccentColor). Faint(true). MarginLeft(ContentPadLeft) SlashPanelStyle = lipgloss.NewStyle(). MarginLeft(ContentPadLeft) SlashItemSelectedStyle = lipgloss.NewStyle(). Foreground(AccentColor). Bold(true) SlashItemStyle = lipgloss.NewStyle(). Foreground(DimColor) SlashItemKindStyle = lipgloss.NewStyle(). Foreground(MutedColor). Italic(true) )
Slash command panel styles
var ( ConfirmHeaderStyle = lipgloss.NewStyle(). Foreground(WarningColor). Bold(true) ConfirmPathStyle = lipgloss.NewStyle(). Foreground(AccentColor) Background(FooterBg). Padding(0, 1) ConfirmApproveStyle = lipgloss.NewStyle(). Foreground(SuccessColor). Bold(true) ConfirmRejectStyle = lipgloss.NewStyle(). Foreground(ErrorColor). Bold(true) )
Confirmation dialog styles
var PulseColors = []lipgloss.Color{
"#2a2f4e",
"#3b4570",
"#4c5a92",
"#5d70b4",
"#6e86d6",
"#7aa2f7",
"#6e86d6",
"#5d70b4",
"#4c5a92",
"#3b4570",
}
Pulse animation colors for status circle (dim blue → bright blue → dim blue)
Functions ¶
func HighlightJSON ¶
HighlightJSON takes a JSON string, validates it, and returns a syntax-highlighted string. If the input is not valid JSON, it returns the original string.
Types ¶
type Model ¶
type Model struct {
// contains filtered or unexported fields
}
Model is the Bubble Tea model for the Falcon TUI. It manages the state of the terminal interface including: - viewport for scrollable message history - textinput for user input - spinner for loading states - agent for LLM interaction
func InitialModel ¶
func InitialModel() Model
InitialModel creates and returns the initial TUI model.
func (Model) Init ¶
Init initializes the Bubble Tea model. This is called once when the program starts.
type SlashCommand ¶
type SlashCommand struct {
Name string // "model", flow filename, or request filename
Description string
Kind string // "builtin" | "flow" | "request"
}
SlashCommand represents a command available via "/" prefix
type SlashState ¶
type SlashState struct {
Active bool
Query string
Suggestions []SlashCommand
Selected int
FlowContent string // loaded file content (after selection, cleared after enter)
TaggedFile string // filename of the tagged file (shown as chip until message is sent)
// contains filtered or unexported fields
}
SlashState tracks current slash command panel state