Documentation
¶
Index ¶
- Variables
- func CommandPaletteCategoryBadge(category string) string
- func CommandPaletteIdleBadge(needsIdle bool) string
- func CommandPaletteKindBadge(kind string) string
- func DrawBox(lines []string, innerWidth, fixedRows int) string
- func FormatProgressLine(progress *agentcore.ProgressPayload) string
- func FormatSubagentOutput(result json.RawMessage) string
- func FormatTokens(n int) string
- func FormatToolArgs(args json.RawMessage) string
- func FormatToolHeader(tool string, args json.RawMessage) string
- func FormatToolOutput(text string, maxVisible int, styles ...lipgloss.Style) string
- func FormatToolResult(result json.RawMessage, isError bool) string
- func RenderEditResult(result json.RawMessage) string
- func RenderLsResult(result json.RawMessage) (dirPath string, body string)
- func RenderReadResult(result json.RawMessage) string
- func RenderStreamingOutput(full string, maxLines int) string
- func RenderWriteResult(result json.RawMessage) string
- func SendCommandResult(text string) tea.Cmd
- func TasksTickCmd() tea.Cmd
- func TruncateLines(s string, maxLines int) string
- type AgentEventMsg
- type AskUserMsg
- type BtwResultMsg
- type CommandResultMsg
- type CompletionItem
- type Config
- type Deps
- type Driver
- type HideCompletedTasksMsg
- type ImageAttachedMsg
- type MCPReadyMsg
- type Model
- func (m *Model) HandleAgentEvent(ev agentcore.Event) (tea.Model, tea.Cmd)
- func (m *Model) Init() tea.Cmd
- func (m *Model) RenderContextBar() string
- func (m *Model) RenderMarkdown(content string) string
- func (m *Model) RenderPlanBar() string
- func (m *Model) RenderPromptOutput(text string) string
- func (m *Model) RenderStatusBar() string
- func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)
- func (m *Model) View() string
- type OverlayState
- type PasteErrorMsg
- type PasteTextMsg
- type PermissionDismissMsg
- type PermissionMsg
- type PermitChoice
- type PlanBarInfo
- type PromptMsg
- type RestoreMsg
- type State
- type SuggestionMsg
- type TaskListUpdateMsg
- type TasksRefreshMsg
Constants ¶
This section is empty.
Variables ¶
var ( ColorPrimary = lipgloss.Color("#3FA796") // teal, core brand/action ColorAccent = lipgloss.Color("#D89B5B") // warm amber accent ColorUser = lipgloss.AdaptiveColor{Light: "25", Dark: "#8AB4F8"} // deeper blue on light theme, calm blue on dark ColorAssistant = lipgloss.Color("#B8E1DD") // pale teal ColorTool = lipgloss.Color("#E5B567") // amber/yellow ColorError = lipgloss.Color("#E06C75") // soft red ColorSuccess = lipgloss.Color("#98C379") // green ColorCommand = lipgloss.Color("#78C6E7") // cool cyan ColorShell = lipgloss.Color("#D16D9E") // shell hint // Claude Code 也是先走语义色,再让组件消费语义: // text / inactive / subtle / promptBorder / suggestion。 // 这里保持同样的思路,只保留一条中性色阶,避免每块 UI 自己挑灰度。 ColorText = lipgloss.AdaptiveColor{Light: "236", Dark: "252"} // 默认正文 ColorTextMuted = lipgloss.AdaptiveColor{Light: "242", Dark: "247"} // 次级信息 / 状态 ColorTextSubtle = lipgloss.AdaptiveColor{Light: "246", Dark: "243"} // placeholder / thinking / 弱提示 ColorChrome = lipgloss.AdaptiveColor{Light: "248", Dark: "242"} // 分隔线 / 边框 / 输入框 chrome ColorPrimarySoft = lipgloss.AdaptiveColor{Light: "30", Dark: "72"} // muted teal for borders/labels ColorMuted = ColorTextMuted ColorThinking = ColorTextSubtle ColorToken = lipgloss.AdaptiveColor{Light: "244", Dark: "245"} // neutral metadata ColorRunning = lipgloss.AdaptiveColor{Light: "31", Dark: "153"} // live-status spinner / strong live chrome ColorStatusBg = lipgloss.AdaptiveColor{Light: "254", Dark: "236"} // soft strip behind user echoes ColorSeparator = ColorChrome ColorBorder = lipgloss.AdaptiveColor{Light: "247", Dark: "241"} ColorPanelBg = lipgloss.AdaptiveColor{Light: "255", Dark: "235"} ColorPanelEdge = lipgloss.AdaptiveColor{Light: "248", Dark: "241"} ColorSubtleBg = lipgloss.AdaptiveColor{Light: "254", Dark: "237"} ColorTitle = lipgloss.AdaptiveColor{Light: "235", Dark: "255"} ColorSoftText = ColorText ColorInputChrome = lipgloss.AdaptiveColor{Light: "245", Dark: "244"} ColorPlaceholder = ColorTextSubtle ColorPath = lipgloss.AdaptiveColor{Light: "26", Dark: "111"} // path / file highlight ColorToolOutput = lipgloss.AdaptiveColor{Light: "239", Dark: "250"} // tool body text ColorToolMeta = lipgloss.AdaptiveColor{Light: "243", Dark: "246"} // tool line numbers / tails )
Color palette — terminal-friendly, restrained, and readable.
var ( ToolIconStyle = lipgloss.NewStyle().Foreground(ColorTool) ToolNameStyle = lipgloss.NewStyle().Foreground(ColorTool).Bold(true) ToolArgsStyle = lipgloss.NewStyle().Foreground(ColorMuted) ToolResultStyle = lipgloss.NewStyle().Foreground(ColorToolOutput) ToolPathStyle = lipgloss.NewStyle().Foreground(ColorPath) )
Tool blocks
var ( WelcomeTitleStyle = lipgloss.NewStyle().Foreground(ColorTitle).Bold(true) WelcomeDetailStyle = lipgloss.NewStyle().Foreground(ColorMuted) )
Welcome banner
var ( ChoiceActiveStyle = lipgloss.NewStyle().Foreground(ColorAccent).Bold(true) ChoiceInactiveStyle = lipgloss.NewStyle().Foreground(ColorMuted) )
Selection menu (plan approval, etc.)
var ( CommandPaletteStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(ColorPrimarySoft). Padding(0, 1) CommandPaletteTitleStyle = lipgloss.NewStyle(). Foreground(ColorTitle). Bold(true) CommandPaletteSectionStyle = lipgloss.NewStyle(). Foreground(ColorPrimarySoft). Bold(true) CommandPaletteSelectedStyle = lipgloss.NewStyle(). Foreground(ColorPrimary). Bold(true) CommandPaletteItemStyle = lipgloss.NewStyle(). Foreground(ColorSoftText) CommandPaletteDescStyle = lipgloss.NewStyle(). Foreground(ColorToken) CommandPaletteSelectedDescStyle = lipgloss.NewStyle(). Foreground(ColorAssistant) CommandPaletteHintStyle = lipgloss.NewStyle(). Foreground(ColorBorder) )
Command palette
var ( MutedStyle = lipgloss.NewStyle().Foreground(ColorMuted) BoxBorderStyle = lipgloss.NewStyle().Foreground(ColorBorder) QueuedMsgStyle = lipgloss.NewStyle().Foreground(ColorMuted).Italic(true) TokenStyle = lipgloss.NewStyle().Foreground(ColorToken) DiffAddStyle = lipgloss.NewStyle().Foreground(ColorSuccess) DiffRemoveStyle = lipgloss.NewStyle().Foreground(ColorError) DiffInverseAddStyle = lipgloss.NewStyle().Foreground(ColorSuccess).Reverse(true) DiffInverseRemoveStyle = lipgloss.NewStyle().Foreground(ColorError).Reverse(true) ReplyLabelStyle = lipgloss.NewStyle().Foreground(ColorAssistant) )
General purpose
var ( CardStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(ColorPanelEdge). Padding(0, 1) CardTitleStyle = lipgloss.NewStyle(). Foreground(ColorTitle). Bold(true) CardSectionStyle = lipgloss.NewStyle(). Foreground(ColorPrimarySoft). Bold(true) InputPanelStyle = lipgloss.NewStyle(). Border(lipgloss.Border{Top: "─", Bottom: "─"}). BorderTop(true). BorderBottom(true). BorderLeft(false). BorderRight(false). BorderForeground(ColorInputChrome). Padding(0, 1) InputHintStyle = lipgloss.NewStyle(). Foreground(ColorMuted) ContextChipStyle = lipgloss.NewStyle(). Foreground(ColorSoftText) ContextChipAccentStyle = lipgloss.NewStyle(). Foreground(ColorPrimary). Bold(true) ContextChipWarnStyle = lipgloss.NewStyle(). Foreground(ColorAccent). Bold(true) WelcomeFrameStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(ColorPrimarySoft). Padding(0, 1) WelcomeKickerStyle = lipgloss.NewStyle(). Foreground(ColorPrimary). Bold(true) WelcomeBodyStyle = lipgloss.NewStyle(). Foreground(ColorSoftText) WelcomeMutedStyle = lipgloss.NewStyle(). Foreground(ColorMuted) TagStyle = lipgloss.NewStyle(). Foreground(ColorPrimary). Bold(true) TagSubtleStyle = lipgloss.NewStyle(). Foreground(ColorSoftText) ImageTagStyle = lipgloss.NewStyle(). Foreground(ColorPrimary) TaskCardStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(ColorPanelEdge). Padding(0, 1) TaskProgressStyle = lipgloss.NewStyle(). Foreground(ColorTitle) PermissionTitleStyle = lipgloss.NewStyle(). Foreground(ColorAccent). Bold(true) AskCardStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(ColorPrimarySoft). Padding(0, 1) )
var AssistantIconStyle = lipgloss.NewStyle(). Foreground(ColorAssistant). Bold(true)
Assistant icon
var AssistantMarkdownBlockStyle = lipgloss.NewStyle(). BorderLeft(true). BorderForeground(ColorPrimarySoft). Padding(0, 1). MarginLeft(1)
Assistant markdown container
var CommandStyle = lipgloss.NewStyle(). Foreground(ColorCommand)
Command / system output
var ErrorStyle = lipgloss.NewStyle(). Foreground(ColorError). Bold(true)
Error
Foreground(ColorThinking). Background(lipgloss.Color("#b5e6b5")). Padding(0, 1)
Footer
var ImageSelectedStyle = lipgloss.NewStyle().Reverse(true)
Image tag selected (reverse video highlight)
var PlanBoxStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(ColorAccent). Padding(0, 1)
Plan box
var PlanTagStyle = lipgloss.NewStyle().Foreground(ColorPrimary)
Plan mode tag
var SeparatorStyle = lipgloss.NewStyle(). Foreground(ColorSeparator)
Separator
var ShellSeparatorStyle = lipgloss.NewStyle(). Foreground(ColorShell)
Shell mode separator
var SubagentCardStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(ColorTool). Padding(0, 1)
Subagent result card
var SystemMsgStyle = lipgloss.NewStyle(). Foreground(ColorMuted). Italic(true)
Short system notifications (e.g. "Switched to model", "Session cleared")
var ThinkingBodyStyle = lipgloss.NewStyle(). Foreground(ColorThinking). Italic(true)
Thinking body
Functions ¶
func CommandPaletteCategoryBadge ¶ added in v0.0.4
func CommandPaletteIdleBadge ¶ added in v0.0.2
func CommandPaletteKindBadge ¶ added in v0.0.2
func DrawBox ¶ added in v0.0.3
DrawBox draws a rounded border box with fixed height and gray border. innerWidth is the content width; fixedRows is the exact number of content rows (short content is padded with empty lines to keep view height stable).
func FormatProgressLine ¶
func FormatProgressLine(progress *agentcore.ProgressPayload) string
FormatProgressLine formats a structured tool progress update for display.
func FormatSubagentOutput ¶
func FormatSubagentOutput(result json.RawMessage) string
FormatSubagentOutput extracts the full output from a subagent result, appending usage stats as a footer. Returns content for card display.
func FormatTokens ¶
FormatTokens formats a token count with k/M suffix for readability.
func FormatToolArgs ¶
func FormatToolArgs(args json.RawMessage) string
FormatToolArgs formats tool arguments for display, truncating if needed.
func FormatToolHeader ¶ added in v0.0.2
func FormatToolHeader(tool string, args json.RawMessage) string
FormatToolHeader returns a one-line tool header like "Bash(git diff --stat)".
func FormatToolOutput ¶ added in v0.0.2
FormatToolOutput formats tool result text with tree connectors. First line gets "└ ", subsequent lines get " " alignment. Truncates to maxVisible lines with "… +N lines" hint. Optional styles override the default ToolResultStyle for line content.
func FormatToolResult ¶
func FormatToolResult(result json.RawMessage, isError bool) string
FormatToolResult extracts displayable text from a tool result. Truncation is handled by the caller (FormatToolOutput).
func RenderEditResult ¶
func RenderEditResult(result json.RawMessage) string
RenderEditResult renders the edit tool result with colored diff output. Single-line changes (1 removed + 1 added) get intra-line highlighting where only the changed portion is rendered in inverse color.
func RenderLsResult ¶ added in v0.0.4
func RenderLsResult(result json.RawMessage) (dirPath string, body string)
RenderLsResult renders ls tool results with tree structure. Returns the directory path (for header update) and the formatted body.
func RenderReadResult ¶ added in v0.0.4
func RenderReadResult(result json.RawMessage) string
RenderReadResult renders read/glob tool results with colored line numbers. Handles both numbered lines (" 123\tcontent") and plain path lists.
func RenderStreamingOutput ¶
RenderStreamingOutput shows the last N lines of streaming tool output with tree connectors (└ on first line, spaces for alignment).
func RenderWriteResult ¶ added in v0.0.2
func RenderWriteResult(result json.RawMessage) string
RenderWriteResult renders the write tool result with a green preview of the written content.
func SendCommandResult ¶
SendCommandResult is a helper that wraps text into a CommandResultMsg tea.Cmd.
func TasksTickCmd ¶ added in v0.0.3
TasksTickCmd returns a tea.Cmd that fires TasksRefreshMsg after 500ms.
func TruncateLines ¶
TruncateLines truncates text to maxLines, appending "..." if truncated.
Types ¶
type AgentEventMsg ¶
AgentEventMsg bridges agentcore events into the bubbletea Elm loop.
type AskUserMsg ¶
type AskUserMsg struct {
Questions []tools.Question
RespCh chan<- *tools.AskUserResponse
}
AskUserMsg is sent by the AskUser handler to show questions in the TUI.
type BtwResultMsg ¶ added in v0.0.4
BtwResultMsg carries the result of a /btw side question back to the overlay.
type CommandResultMsg ¶
type CommandResultMsg struct {
Text string
Quit bool // true for /exit
Clear bool // true for /clear
NewModel string // non-empty if model was switched
}
CommandResultMsg carries the result of a slash command back to the model.
type CompletionItem ¶ added in v0.0.2
type CompletionItem struct {
Name string // command name without "/" (e.g. "model")
Description string
Usage string
Kind string
Category string
NeedsIdle bool
Source string
Aliases []string
AutoExecute bool
}
CompletionItem is a single command completion candidate.
type Config ¶
type Config struct {
Placeholder string
Version string
Provider string
Cwd string
GitBranch string
EnvHint string // shown below welcome when using env var credentials
History *storage.History // input history (Up/Down navigation)
InitialTasks *tools.TaskSnapshot // initial task snapshot restored before first render
RestoredMessages []agentcore.AgentMessage // messages restored from a previous session (rendered on Init)
OnKey func(m *Model, msg tea.KeyMsg) (handled bool, cmd tea.Cmd)
OnEvent func(m *Model, ev agentcore.Event) tea.Cmd
OnPaste func(m *Model) tea.Cmd // Ctrl+V: read clipboard image, return ImageAttachedMsg
OnDrop func(m *Model, text string) tea.Cmd // Drag-drop: if text is image path, return cmd; else nil
OnMCPReady func(msg MCPReadyMsg) // called when MCP servers finish connecting
OnHideCompletedTasks func(snap tools.TaskSnapshot) tea.Cmd
StatusRight func(m *Model) string
StatusMode func(m *Model) string // mode indicator for context bar (e.g. "⏵⏵ trust")
StatusPlan func(m *Model) *PlanBarInfo
Overlay func(m *Model) *OverlayState // interactive command overlay
Completions func(prefix string) []CompletionItem // slash command completions
OnBtwResult func(msg BtwResultMsg) // called when /btw side question completes
}
Config provides hooks for extending the base TUI behavior.
type Deps ¶ added in v0.1.0
type Deps struct {
Driver Driver
ModelName string
Provider string
Version string
// contains filtered or unexported fields
}
Deps holds external dependencies and static configuration for the TUI.
type Driver ¶
type Driver interface {
Prompt(text string) error
PromptWithBlocks(blocks []agentcore.ContentBlock) error
Steer(text string)
Abort()
}
Driver defines the minimal conversation operations required by the TUI.
type HideCompletedTasksMsg ¶ added in v0.1.0
type HideCompletedTasksMsg struct {
Version uint64
}
HideCompletedTasksMsg hides the task card after all tasks stayed completed for a short delay. Version prevents stale timers from hiding a newer list.
type ImageAttachedMsg ¶
type ImageAttachedMsg struct {
Block agentcore.ContentBlock // pre-built ImageBlock (base64 + mime)
}
ImageAttachedMsg notifies the Model that an image has been pasted from clipboard.
type MCPReadyMsg ¶ added in v0.0.3
type MCPReadyMsg struct {
Tools int // total number of tools loaded across all servers
Errors []string // connection errors (server: reason)
Instructions string // MCP server instructions to set as system suffix
}
MCPReadyMsg notifies the TUI that background MCP server connection has completed.
type Model ¶
Model is the bubbletea Model for the agent TUI. Completed content is printed to terminal scrollback via tea.Println; View() only renders the live area (status + streaming + input).
func (*Model) HandleAgentEvent ¶
HandleAgentEvent processes agent events. Completed content is printed to terminal scrollback via tea.Println. In-progress content (streaming, tool output) is shown in the live View().
func (*Model) RenderContextBar ¶
RenderContextBar renders the context line below the input (env info).
func (*Model) RenderMarkdown ¶
RenderMarkdown renders a lightweight terminal-friendly markdown subset.
func (*Model) RenderPlanBar ¶
RenderPlanBar renders the plan review card (AskUser-style). Empty when inactive.
func (*Model) RenderPromptOutput ¶
RenderPromptOutput renders a user message with optional welcome banner for scrollback.
func (*Model) RenderStatusBar ¶
RenderStatusBar renders the status line above the input. Only shown while the agent is running.
type OverlayState ¶ added in v0.0.2
type OverlayState struct {
HandleKey func(msg tea.KeyMsg) (handled bool, cmd tea.Cmd)
View func(width int) string
ReplacesInput bool // when true, overlay replaces the input area instead of appearing below it
}
OverlayState bridges an interactive command overlay to the TUI.
type PasteErrorMsg ¶
type PasteErrorMsg struct {
Text string
}
PasteErrorMsg carries an error from clipboard paste or file drag-drop. Decrements Pasting counter and displays the error text.
type PasteTextMsg ¶
type PasteTextMsg struct{}
PasteTextMsg signals that Ctrl+V found no image; the textarea should paste text.
type PermissionDismissMsg ¶ added in v0.0.2
type PermissionDismissMsg struct{}
PermissionDismissMsg tells the TUI to close the permission prompt.
type PermissionMsg ¶ added in v0.0.2
type PermissionMsg struct {
Tool string
Command string
Reason string
Preview string
OutsideRoots bool // when true, only AllowOnce and Deny are shown
RespCh chan<- PermitChoice
}
PermissionMsg is sent to the TUI to show a permission confirmation prompt.
type PermitChoice ¶ added in v0.0.2
type PermitChoice int
PermitChoice is the user's response to a permission prompt.
const ( PermitChoiceDeny PermitChoice = iota PermitChoiceAllowOnce // allow this invocation only PermitChoiceAllowSession // allow for the rest of the session PermitChoiceAllowAlways // persist to project config )
type PlanBarInfo ¶
type PlanBarInfo struct {
Tag string // appended to status bar (e.g., "plan mode")
Choices []string // selectable options
Active int // active choice index
// Plan review card fields.
Prompt string // e.g., "Would you like to proceed?"
Details []string
OtherMode bool // typing custom feedback
OtherBuf string // custom feedback buffer
}
PlanBarInfo provides plan mode status for the status bar.
type PromptMsg ¶
type PromptMsg struct {
Text string
}
PromptMsg injects a message as if the user typed and sent it. The TUI renders it as a user message and forwards it to the agent.
type RestoreMsg ¶ added in v0.0.2
type RestoreMsg struct{ Msgs []agentcore.AgentMessage }
RestoreMsg is sent to replay restored session messages into scrollback.
type State ¶ added in v0.1.0
type State struct {
Input textarea.Model
Spinner spinner.Model
ToolSpinner spinner.Model // breathing-dot spinner for tool execution
Streaming *strings.Builder
Thinking *strings.Builder
IsStream bool
Running bool
TurnCount int
PendingTools map[string]string // toolID -> tool name
ToolHeaders map[string]string // toolID -> formatted header (printed at end)
ToolOutputBuf map[string]*strings.Builder // toolID -> streaming output
ToolDeltaBuf map[string]*strings.Builder // toolID -> accumulated subagent delta text
ToolThinkingBuf map[string]*strings.Builder // toolID -> accumulated subagent thinking text
Width int
Height int
Ready bool
Cwd string
GitBranch string
ShowWelcome bool
EnvHint string // env var hint shown below welcome
ShowSummary bool
RunStats runStats
Images []agentcore.ContentBlock // attached images (from Ctrl+V clipboard paste)
ImageCursor int // -1 = not selecting; 0+ = selected image index
Pasting int // number of async image reads in progress (clipboard paste or drag-drop)
Markdown *markdown.Renderer
AskUser *askUserState // non-nil when ask-user UI is active
Permission *permissionState // non-nil when permission prompt is active
Tasks *tools.TaskSnapshot // non-nil when task items exist; displayed above input
QueuedMsgs []string // messages queued while agent is running (display only)
MCPLoading bool // true while MCP servers are connecting in background
Suggestion string // prompt suggestion shown as placeholder after agent completes
QuitPending bool // true after first Ctrl+C, waiting for second to quit
// contains filtered or unexported fields
}
State holds mutable runtime state for the TUI.
type SuggestionMsg ¶ added in v0.0.4
type SuggestionMsg struct {
Text string
}
SuggestionMsg carries a prompt suggestion generated after agent completion.
type TaskListUpdateMsg ¶
type TaskListUpdateMsg struct {
Snapshot tools.TaskSnapshot
}
TaskListUpdateMsg notifies the TUI that the task list has changed.
type TasksRefreshMsg ¶ added in v0.0.3
type TasksRefreshMsg struct{}
TasksRefreshMsg is a periodic tick that triggers a re-render of the /tasks overlay.