Documentation
¶
Index ¶
- Constants
- Variables
- func ANSILen(s string) int
- func BuildSubagentPreview(p *SubagentProgress, maxLines int) []string
- func CalcDiffWidth(oldContent, newContent string) int
- func ClearRenderedImages()
- func ComposeFlushFirstCommands(flushCmds []tea.Cmd, asyncCmds []tea.Cmd) tea.Cmd
- func CountLines(content string) int
- func CountTrailingNewlines(s string) int
- func ErrorCircle() string
- func FindSafeBoundary(text string) int
- func FindSafeBoundaryIncremental(text string, lastSafePos int) int
- func FormatTokenCount(n int) string
- func GetPendingToolTextLen(segments []Segment) int
- func GetRefinement() (string, error)
- func GlamourStyle() ansi.StyleConfig
- func GlamourStyleFromTheme(theme *Theme) ansi.StyleConfig
- func HandleSubagentProgress(tracker *ToolTracker, subagentTracker *SubagentTracker, callID string, ...)
- func HasDiff(oldContent, newContent string) bool
- func HasPendingTool(segments []Segment) bool
- func InitTheme(cfg ThemeConfig)
- func MatchPresetTheme(cfg ThemeConfig) string
- func NewlinePadding(currentTrailing, targetTrailing int) string
- func NewlinesNeededForTrailing(currentTrailing, targetTrailing int) int
- func NormalizeNewlines(s string) string
- func ParseBoolDefault(raw string, defaultValue bool) bool
- func PendingCircle() string
- func PrintCompactDiff(filePath, oldContent, newContent string, padWidth int)
- func PrintUnifiedDiff(filePath, oldContent, newContent string)
- func PrintUnifiedDiffMulti(filePath, oldContent, newContent string)
- func PromptApplyEdit() bool
- func RenderDiffSegment(filePath, oldContent, newContent string, width int, startLine int) string
- func RenderImagesAndDiffs(segments []*Segment, width int) string
- func RenderInlineImage(path string) string
- func RenderMarkdown(content string, width int) string
- func RenderMarkdownWithError(content string, width int) (string, error)
- func RenderSegments(segments []*Segment, width int, wavePos int, ...) string
- func RenderSegmentsWithLeading(leading *Segment, segments []*Segment, width int, wavePos int, ...) string
- func RenderSubagentProgress(p *SubagentProgress, expanded bool) string
- func RenderToolCallFromPart(tc *llm.ToolCall, width int) string
- func RenderToolSegment(seg *Segment, wavePos int, width int) string
- func RenderWaveText(text string, wavePos int) string
- func RunSetupWizard() (*config.Config, error)
- func RunWithSpinner(ctx context.Context, debug bool, run func(context.Context) (any, error)) (any, error)
- func RunWithSpinnerProgress(ctx context.Context, debug bool, progress <-chan ProgressUpdate, ...) (any, error)
- func RunWithSpinnerProgressAndHooks(ctx context.Context, debug bool, progress <-chan ProgressUpdate, ...) (any, error)
- func ScrollbackPrintlnCommands(content string, includeFinalSpacer bool) []tea.Cmd
- func SegmentSeparator(prevType, currType SegmentType) string
- func SelectCommand(suggestions []llm.CommandSuggestion, shell string, engine *llm.Engine, ...) (selected string, refinement string, err error)
- func SetTheme(t *Theme)
- func ShowCommand(cmd string)
- func ShowCommandHelp(command, shell string, engine *llm.Engine) error
- func ShowEditInfo(aboutText string)
- func ShowEditSkipped(filePath string, reason string)
- func ShowError(msg string)
- func SmoothTick() tea.Cmd
- func SplitLines(content string) []string
- func StripANSI(s string) string
- func SuccessCircle() string
- func Truncate(s string, maxLen int) string
- func UpdateSegmentFromSubagentProgress(tracker *ToolTracker, callID string, p *SubagentProgress)
- func WorkingCircle() string
- type ApprovalHookSetup
- type DiffData
- type EditApprovalResult
- type FlushStreamingTextResult
- type FlushToScrollbackResult
- type Highlighter
- type PlanStreamAdapter
- type ProgressUpdate
- type Segment
- type SegmentType
- type SessionStats
- type SmoothBuffer
- func (b *SmoothBuffer) FlushAll() string
- func (b *SmoothBuffer) IsDrained() bool
- func (b *SmoothBuffer) IsEmpty() bool
- func (b *SmoothBuffer) Len() int
- func (b *SmoothBuffer) MarkDone()
- func (b *SmoothBuffer) NextWords() string
- func (b *SmoothBuffer) Reset()
- func (b *SmoothBuffer) Write(text string)
- type SmoothTickMsg
- type StreamAdapter
- type StreamEvent
- func DiffEvent(path, old, new string, line int) StreamEvent
- func DoneEvent(totalTokens int) StreamEvent
- func ErrorEvent(err error) StreamEvent
- func ImageEvent(path string) StreamEvent
- func InlineDeleteEvent(from, to string) StreamEvent
- func InlineInsertEvent(after string, content []string) StreamEvent
- func InterjectionEvent(text string) StreamEvent
- func PartialInsertEvent(after, line string) StreamEvent
- func PhaseEvent(phase string) StreamEvent
- func RetryEvent(attempt, max int, waitSecs float64) StreamEvent
- func TextEvent(text string) StreamEvent
- func ToolEndEvent(callID, name, info string, success bool) StreamEvent
- func ToolStartEvent(callID, name, info string) StreamEvent
- func UsageEvent(input, output, cached, cacheWrite int) StreamEvent
- type StreamEventType
- type StreamingIndicator
- type Styles
- type SubagentDiff
- type SubagentProgress
- type SubagentTracker
- func (t *SubagentTracker) ActiveAgents() []*SubagentProgress
- func (t *SubagentTracker) Get(callID string) *SubagentProgress
- func (t *SubagentTracker) GetOrCreate(callID, agentName string) *SubagentProgress
- func (t *SubagentTracker) HandleInit(callID, provider, model string)
- func (t *SubagentTracker) HandlePhase(callID, phase string)
- func (t *SubagentTracker) HandleTextDelta(callID, text string)
- func (t *SubagentTracker) HandleToolEnd(callID, toolName string, success bool)
- func (t *SubagentTracker) HandleToolStart(callID, toolName, toolInfo string)
- func (t *SubagentTracker) HandleUsage(callID string, inputTokens, outputTokens int)
- func (t *SubagentTracker) HasActive() bool
- func (t *SubagentTracker) IsExpanded() bool
- func (t *SubagentTracker) MarkDone(callID string)
- func (t *SubagentTracker) Remove(callID string)
- func (t *SubagentTracker) SetMainProviderModel(provider, model string)
- func (t *SubagentTracker) ToggleExpanded()
- type TextSegmentRenderer
- func (r *TextSegmentRenderer) Close() error
- func (r *TextSegmentRenderer) CommittedMarkdownLen() int
- func (r *TextSegmentRenderer) Flush() error
- func (r *TextSegmentRenderer) FlushedRenderedPos() int
- func (r *TextSegmentRenderer) MarkFlushed()
- func (r *TextSegmentRenderer) PendingIsList() bool
- func (r *TextSegmentRenderer) PendingIsTable() bool
- func (r *TextSegmentRenderer) PendingMarkdown() string
- func (r *TextSegmentRenderer) Rendered() string
- func (r *TextSegmentRenderer) RenderedAll() string
- func (r *TextSegmentRenderer) RenderedUnflushed() string
- func (r *TextSegmentRenderer) Resize(newWidth int) error
- func (r *TextSegmentRenderer) Width() int
- func (r *TextSegmentRenderer) Write(text string) error
- type Theme
- type ThemeConfig
- type ThemePreset
- type ToolPhase
- type ToolSegment
- type ToolStatus
- type ToolTracker
- func (t *ToolTracker) ActiveSegments() []*Segment
- func (t *ToolTracker) AddDiffSegment(path, old, new string, line int)
- func (t *ToolTracker) AddExternalUIResult(summary string)
- func (t *ToolTracker) AddImageSegment(path string)
- func (t *ToolTracker) AddPreRenderedTextSegment(rendered string)
- func (t *ToolTracker) AddTextSegment(text string, width int) bool
- func (t *ToolTracker) AllCompletedSegments() []*Segment
- func (t *ToolTracker) AllSegments() []Segment
- func (t *ToolTracker) CompleteTextSegments(renderFunc func(string) string)
- func (t *ToolTracker) CompletedSegments() []*Segment
- func (t *ToolTracker) FlushAllRemaining(width int, printedLines int, renderMd func(string, int) string) FlushToScrollbackResult
- func (t *ToolTracker) FlushBeforeExternalUI(width int, printedLines int, keepLines int, renderMd func(string, int) string) FlushToScrollbackResult
- func (t *ToolTracker) FlushCompletedNow(width int, renderMd func(string, int) string) FlushToScrollbackResult
- func (t *ToolTracker) FlushLeadingSeparator(nextType SegmentType) string
- func (t *ToolTracker) FlushStreamingText(threshold int, width int, renderMd func(string, int) string) FlushStreamingTextResult
- func (t *ToolTracker) FlushToScrollback(width int, printedLines int, maxViewLines int, ...) FlushToScrollbackResult
- func (t *ToolTracker) ForceCompletePendingTools()
- func (t *ToolTracker) HandleToolEnd(callID string, success bool)
- func (t *ToolTracker) HandleToolStart(callID, toolName, toolInfo string) bool
- func (t *ToolTracker) HandleWavePause() tea.Cmd
- func (t *ToolTracker) HandleWaveTick() tea.Cmd
- func (t *ToolTracker) HasPending() bool
- func (t *ToolTracker) IsIdle(d time.Duration) bool
- func (t *ToolTracker) LeadingSeparator(nextType SegmentType) string
- func (t *ToolTracker) MarkCurrentTextComplete(renderFunc func(string) string)
- func (t *ToolTracker) RecordActivity()
- func (t *ToolTracker) RenderUnflushed(width int, renderMd func(string, int) string, includeImages bool) string
- func (t *ToolTracker) ResizeStreamRenderers(width int)
- func (t *ToolTracker) StartWave() tea.Cmd
- func (t *ToolTracker) UnflushedSegments() []*Segment
- type WavePauseMsg
- type WaveTickMsg
Constants ¶
const ( // SectionBreakTrailingNewlines is the minimum trailing newline run that // separates adjacent output sections. SectionBreakTrailingNewlines = 1 // FinalSpacerTrailingNewlines is the minimum trailing newline run to keep // one spacer line before the next prompt after completion. FinalSpacerTrailingNewlines = 2 )
const ( SmoothFrameInterval = 16 * time.Millisecond // 60fps SmoothBufferCapacity = 500 // characters SmoothMinWordsPerFrame = 1 SmoothMaxWordsPerFrame = 5 SmoothMaxWordLength = 12 // Chunk words longer than this )
Smooth buffer constants for 60fps adaptive rendering
const ( EnabledIcon = "●" DisabledIcon = "○" SuccessIcon = "✓" FailIcon = "✗" )
Status indicators
const DefaultStreamBufferSize = 100
DefaultStreamBufferSize is the default buffer size for the event channel. Large enough to handle bursts while still providing backpressure.
const SomethingElse = "__something_else__"
Variables ¶
var PresetThemeNames = []string{
"gruvbox",
"dracula",
"nord",
"solarized",
"monokai",
"classic",
}
PresetThemeNames defines the display order of themes
var PresetThemes = map[string]ThemePreset{ "classic": { Name: "classic", Description: "Classic green terminal style", Config: ThemeConfig{ Primary: "10", Secondary: "4", Success: "10", Error: "9", Warning: "11", Muted: "245", Text: "15", Spinner: "205", }, }, "dracula": { Name: "dracula", Description: "Popular dark theme with purple accents", Config: ThemeConfig{ Primary: "#bd93f9", Secondary: "#8be9fd", Success: "#50fa7b", Error: "#ff5555", Warning: "#f1fa8c", Muted: "#6272a4", Text: "#f8f8f2", Spinner: "#ff79c6", }, }, "nord": { Name: "nord", Description: "Arctic, north-bluish color palette", Config: ThemeConfig{ Primary: "#88c0d0", Secondary: "#81a1c1", Success: "#a3be8c", Error: "#bf616a", Warning: "#ebcb8b", Muted: "#4c566a", Text: "#eceff4", Spinner: "#b48ead", }, }, "solarized": { Name: "solarized", Description: "Precision colors for machines and people", Config: ThemeConfig{ Primary: "#268bd2", Secondary: "#2aa198", Success: "#859900", Error: "#dc322f", Warning: "#b58900", Muted: "#586e75", Text: "#839496", Spinner: "#d33682", }, }, "monokai": { Name: "monokai", Description: "Vibrant colors inspired by Sublime Text", Config: ThemeConfig{ Primary: "#a6e22e", Secondary: "#66d9ef", Success: "#a6e22e", Error: "#f92672", Warning: "#e6db74", Muted: "#75715e", Text: "#f8f8f2", Spinner: "#ae81ff", }, }, "gruvbox": { Name: "gruvbox", Description: "Retro groove color scheme (default)", Config: ThemeConfig{ Primary: "#b8bb26", Secondary: "#83a598", Success: "#b8bb26", Error: "#fb4934", Warning: "#fabd2f", Muted: "#928374", Text: "#ebdbb2", Spinner: "#d3869b", }, }, }
PresetThemes contains all predefined themes
Functions ¶
func BuildSubagentPreview ¶ added in v0.0.42
func BuildSubagentPreview(p *SubagentProgress, maxLines int) []string
BuildSubagentPreview builds preview lines for a subagent in chronological order. Shows completed tools first (oldest first), then active tools (most recent). maxLines is the total number of lines to show.
func CalcDiffWidth ¶ added in v0.0.5
CalcDiffWidth calculates the required padding width for a diff The result is capped to the terminal-aware max content width
func ClearRenderedImages ¶ added in v0.0.39
func ClearRenderedImages()
ClearRenderedImages clears the cache of rendered images. Call this when starting a new session.
func ComposeFlushFirstCommands ¶ added in v0.0.62
ComposeFlushFirstCommands builds a command pipeline where flush commands run first in-order, and all non-flush commands run afterward.
This prevents output-printing commands from racing with follow-up commands when the caller needs deterministic boundary rendering.
func CountLines ¶ added in v0.0.35
CountLines counts the number of newlines in content
func CountTrailingNewlines ¶ added in v0.0.69
CountTrailingNewlines returns how many '\n' characters appear at the end of s.
func ErrorCircle ¶ added in v0.0.26
func ErrorCircle() string
ErrorCircle returns the error status indicator
func FindSafeBoundary ¶ added in v0.0.46
FindSafeBoundary finds the last byte position where markdown context is complete. Returns -1 if no safe boundary exists.
A safe boundary is a position after which we can split the text without breaking markdown rendering. Safe positions are: - After complete paragraphs (\n\n) - After closed code blocks (balanced ``` markers) - When not inside incomplete inline markers (**, `, etc.)
func FindSafeBoundaryIncremental ¶ added in v0.0.46
FindSafeBoundaryIncremental finds a safe boundary only scanning from lastSafePos. This is O(delta) instead of O(n) for streaming scenarios. Returns -1 if no new safe boundary exists beyond lastSafePos.
func FormatTokenCount ¶ added in v0.0.61
FormatTokenCount formats a token count in compact form: 1, 999, 1.5k, 12.3k, 1.1M
func GetPendingToolTextLen ¶ added in v0.0.26
GetPendingToolTextLen returns the text length of the first pending tool (for wave animation)
func GetRefinement ¶
GetRefinement prompts the user for additional guidance
func GlamourStyle ¶ added in v0.0.31
func GlamourStyle() ansi.StyleConfig
GlamourStyle returns a glamour StyleConfig based on the current theme
func GlamourStyleFromTheme ¶ added in v0.0.31
func GlamourStyleFromTheme(theme *Theme) ansi.StyleConfig
GlamourStyleFromTheme creates a glamour StyleConfig from the given theme
func HandleSubagentProgress ¶ added in v0.0.42
func HandleSubagentProgress(tracker *ToolTracker, subagentTracker *SubagentTracker, callID string, event tools.SubagentEvent)
HandleSubagentProgress processes subagent events and updates both the subagent tracker and the corresponding spawn_agent segment's stats. This is shared logic used by both the ask command (streaming mode) and the chat TUI.
tracker: the ToolTracker containing segments subagentTracker: the SubagentTracker for subagent progress callID: the tool call ID of the spawn_agent invocation event: the subagent event to process
func HasPendingTool ¶ added in v0.0.26
HasPendingTool returns true if any segment has a pending tool
func MatchPresetTheme ¶ added in v0.0.31
func MatchPresetTheme(cfg ThemeConfig) string
MatchPresetTheme finds a preset that matches the given config, or returns empty string
func NewlinePadding ¶ added in v0.0.69
NewlinePadding returns the minimal newline padding needed to reach at least targetTrailing trailing newlines.
func NewlinesNeededForTrailing ¶ added in v0.0.69
NewlinesNeededForTrailing returns the number of '\n' characters required to reach at least targetTrailing newlines.
func NormalizeNewlines ¶ added in v0.0.55
NormalizeNewlines reduces 3+ consecutive newlines to 2 (one blank line max). This fixes inconsistent spacing between headers caused by glamour's hardcoded extra newline before headings combined with our BlockSuffix settings.
func ParseBoolDefault ¶ added in v0.0.74
ParseBoolDefault parses a boolean-like environment value with a fallback default. True values: 1, true, yes, on, y False values: 0, false, no, off, n Empty/unknown values return defaultValue.
func PendingCircle ¶ added in v0.0.26
func PendingCircle() string
PendingCircle returns the pending status indicator
func PrintCompactDiff ¶ added in v0.0.5
PrintCompactDiff prints a compact diff with 2 lines of context and line numbers padWidth specifies the total line width for consistent backgrounds across diffs
func PrintUnifiedDiff ¶ added in v0.0.10
func PrintUnifiedDiff(filePath, oldContent, newContent string)
PrintUnifiedDiff prints a clean unified diff between old and new content If multiFile is true, shows the filename header (for multi-file diffs)
func PrintUnifiedDiffMulti ¶ added in v0.0.10
func PrintUnifiedDiffMulti(filePath, oldContent, newContent string)
PrintUnifiedDiffMulti prints a diff with filename header (for multi-file edits)
func PromptApplyEdit ¶ added in v0.0.5
func PromptApplyEdit() bool
PromptApplyEdit asks the user whether to apply an edit Returns true if user wants to apply (Enter or y), false to skip (n)
func RenderDiffSegment ¶ added in v0.0.46
RenderDiffSegment renders a unified diff as a string for inline display. Returns empty string if no changes or on error. The width parameter is used for wrapping long lines. The startLine parameter is the 1-indexed line number where the edit starts (0 = use diff header).
func RenderImagesAndDiffs ¶ added in v0.0.50
RenderImagesAndDiffs renders only image and diff segments from a list. This is used for alt screen mode to preserve images/diffs after streaming ends, since text content is already stored in message history.
func RenderInlineImage ¶ added in v0.0.39
RenderInlineImage renders an image as terminal escape sequences for inline display. The rendered output is cached, so subsequent calls return the cached result. Returns empty string on error or if terminal doesn't support images. The cache is limited to maxImageCacheSize entries; oldest entries are evicted when full. The cache is invalidated when the file's modification time changes.
func RenderMarkdown ¶ added in v0.0.34
RenderMarkdown renders markdown content using glamour with standard styling. This is the main function for rendering markdown in streaming contexts. On error, returns the original content unchanged.
func RenderMarkdownWithError ¶ added in v0.0.34
RenderMarkdownWithError renders markdown content and returns any errors. Use this variant when error handling is needed.
func RenderSegments ¶ added in v0.0.26
func RenderSegments(segments []*Segment, width int, wavePos int, renderMarkdown func(string, int) string, includeImages bool) string
RenderSegments renders a list of segments with proper spacing.
func RenderSegmentsWithLeading ¶ added in v0.0.55
func RenderSegmentsWithLeading(leading *Segment, segments []*Segment, width int, wavePos int, renderMarkdown func(string, int) string, includeImages bool) string
RenderSegmentsWithLeading renders a list of segments, optionally using a leading segment for initial spacing.
func RenderSubagentProgress ¶ added in v0.0.42
func RenderSubagentProgress(p *SubagentProgress, expanded bool) string
RenderSubagentProgress renders progress for a single subagent. This is used when displaying inline beneath a spawn_agent tool indicator.
func RenderToolCallFromPart ¶ added in v0.0.49
RenderToolCallFromPart renders a historical tool call from an llm.ToolCall. Uses success styling since historical calls have completed. width is the terminal width used to truncate long lines (0 = no truncation).
func RenderToolSegment ¶ added in v0.0.26
RenderToolSegment renders a tool segment with its status indicator. For pending tools, wavePos controls the wave animation (-1 = paused/all dim). Tool name is rendered normally, params are rendered in slightly muted gray. For spawn_agent tools with progress, stats are shown instead of wave animation. width is the terminal width used to truncate long lines (0 = no truncation).
func RenderWaveText ¶ added in v0.0.26
RenderWaveText renders text with a wave animation effect using bold highlighting. wavePos is the position of the bright "peak" traveling through the text. If wavePos < 0, we're in the pause phase - show all dim.
func RunSetupWizard ¶
RunSetupWizard runs the first-time setup wizard and returns the config
func RunWithSpinner ¶
func RunWithSpinner(ctx context.Context, debug bool, run func(context.Context) (any, error)) (any, error)
RunWithSpinner shows a spinner while executing the provided function.
func RunWithSpinnerProgress ¶ added in v0.0.11
func RunWithSpinnerProgress(ctx context.Context, debug bool, progress <-chan ProgressUpdate, run func(context.Context) (any, error)) (any, error)
RunWithSpinnerProgress shows a spinner with progress updates while executing the provided function. The progress channel can receive updates with token counts, status messages, and milestones.
func RunWithSpinnerProgressAndHooks ¶ added in v0.0.26
func RunWithSpinnerProgressAndHooks(ctx context.Context, debug bool, progress <-chan ProgressUpdate, run func(context.Context) (any, error), setupHooks ApprovalHookSetup) (any, error)
RunWithSpinnerProgressAndHooks is like RunWithSpinnerProgress but also sets up approval hooks. The setupHooks function is called with pause/resume functions that should be used to set up tools.SetApprovalHooks() so the spinner pauses during tool approval prompts.
func ScrollbackPrintlnCommands ¶ added in v0.0.69
ScrollbackPrintlnCommands returns tea.Println command(s) for content and an optional final spacer line. It preserves content while avoiding synthetic double-newline inflation from unconditional blank-line commands.
func SegmentSeparator ¶ added in v0.0.55
func SegmentSeparator(prevType, currType SegmentType) string
SegmentSeparator returns the vertical spacing (newlines) required between two segments.
func SelectCommand ¶
func SelectCommand(suggestions []llm.CommandSuggestion, shell string, engine *llm.Engine, allowNonTTY bool) (selected string, refinement string, err error)
SelectCommand presents the user with a list of command suggestions and returns the selected one. Returns the selected command or SomethingElse if user wants to refine their request. When SomethingElse is returned, the second return value contains the user's refinement text. If engine is non-nil and user presses 'i', shows help for the highlighted command. allowNonTTY permits a non-interactive fallback when no TTY is available.
func ShowCommand ¶
func ShowCommand(cmd string)
ShowCommand displays the command that will be executed (to stderr, keeping stdout clean)
func ShowCommandHelp ¶
ShowCommandHelp renders scrollable help for a command
func ShowEditInfo ¶ added in v0.0.10
func ShowEditInfo(aboutText string)
ShowEditInfo displays the about/info text in a fullscreen pager
func ShowEditSkipped ¶ added in v0.0.5
ShowEditSkipped shows that an edit was skipped
func SmoothTick ¶ added in v0.0.39
SmoothTick returns a tea.Cmd that sends a SmoothTickMsg after the frame interval
func SplitLines ¶ added in v0.0.35
SplitLines splits content by newlines. Unlike strings.Split, this does NOT include an empty trailing element for content ending in newline. Example: "hello\nworld\n" → ["hello", "world"] (not ["hello", "world", ""])
func SuccessCircle ¶ added in v0.0.26
func SuccessCircle() string
SuccessCircle returns the success status indicator
func UpdateSegmentFromSubagentProgress ¶ added in v0.0.42
func UpdateSegmentFromSubagentProgress(tracker *ToolTracker, callID string, p *SubagentProgress)
UpdateSegmentFromSubagentProgress updates the spawn_agent segment stats from subagent progress. This syncs the subagent's stats (tool calls, tokens, provider/model) to the segment for display.
func WorkingCircle ¶ added in v0.0.29
func WorkingCircle() string
WorkingCircle returns the working status indicator
Types ¶
type ApprovalHookSetup ¶ added in v0.0.26
type ApprovalHookSetup func(pause, resume func())
ApprovalHookSetup is called with functions to pause/resume the spinner. It should set up approval hooks that call these functions.
type DiffData ¶ added in v0.0.55
DiffData is an alias for llm.DiffData for backward compatibility.
func ParseDiffMarkers ¶ added in v0.0.55
ParseDiffMarkers extracts diff data from tool output that contain __DIFF__: markers. Used for backward compatibility when rendering old sessions that have markers in Display/Content. Format: __DIFF__:<base64-encoded JSON>
type EditApprovalResult ¶ added in v0.0.10
type EditApprovalResult int
EditApprovalResult represents the result of batch approval prompt
const ( EditApprovalYes EditApprovalResult = iota // Apply all changes EditApprovalNo // Skip all changes EditApprovalInfo // Show info/about text )
func PromptBatchApproval ¶ added in v0.0.10
func PromptBatchApproval(hasInfo bool, reprompt bool) EditApprovalResult
PromptBatchApproval asks user to approve all changes with option to see info Returns EditApprovalYes, EditApprovalNo, or EditApprovalInfo If reprompt is true, clears the line before showing prompt (used after returning from info)
type FlushStreamingTextResult ¶ added in v0.0.52
type FlushStreamingTextResult struct {
// ToPrint is the rendered content to print to scrollback (empty if nothing to flush)
ToPrint string
}
FlushStreamingTextResult contains the result of a streaming text flush.
type FlushToScrollbackResult ¶ added in v0.0.34
type FlushToScrollbackResult struct {
// ToPrint is the content to print to scrollback (empty if nothing to flush)
ToPrint string
// NewPrintedLines is kept for API compatibility but no longer used for tracking
NewPrintedLines int
}
FlushToScrollbackResult contains the result of a scrollback flush operation.
type Highlighter ¶ added in v0.0.6
type Highlighter struct {
// contains filtered or unexported fields
}
Highlighter handles syntax highlighting for diff display
func NewHighlighter ¶ added in v0.0.6
func NewHighlighter(filePath string) *Highlighter
NewHighlighter creates a highlighter for the given file path. Returns nil if the language is not recognized. Results are cached since lexers.Match is expensive (iterates all ~500 lexers).
func (*Highlighter) HighlightLine ¶ added in v0.0.6
func (h *Highlighter) HighlightLine(line string) string
HighlightLine applies syntax highlighting to a line without a background color.
func (*Highlighter) HighlightLineWithBg ¶ added in v0.0.6
func (h *Highlighter) HighlightLineWithBg(line string, bg [3]int) string
HighlightLineWithBg applies syntax highlighting to a line with a specific background color. bg is an RGB array [r, g, b] for true color background.
type PlanStreamAdapter ¶ added in v0.0.52
type PlanStreamAdapter struct {
// contains filtered or unexported fields
}
PlanStreamAdapter bridges an llm.Stream to a channel of StreamEvents, with inline edit marker parsing for the plan mode. It converts text stream events into inline edit events when markers are detected.
func NewPlanStreamAdapter ¶ added in v0.0.52
func NewPlanStreamAdapter(bufSize int) *PlanStreamAdapter
NewPlanStreamAdapter creates a new PlanStreamAdapter with the specified buffer size. If bufSize <= 0, DefaultStreamBufferSize is used.
func (*PlanStreamAdapter) EmitErrorAndClose ¶ added in v0.0.52
func (a *PlanStreamAdapter) EmitErrorAndClose(err error)
EmitErrorAndClose sends an error event and closes the channel. Use this when stream creation fails before ProcessStream can be called.
func (*PlanStreamAdapter) Events ¶ added in v0.0.52
func (a *PlanStreamAdapter) Events() <-chan StreamEvent
Events returns the channel to read events from.
func (*PlanStreamAdapter) ProcessStream ¶ added in v0.0.52
func (a *PlanStreamAdapter) ProcessStream(ctx context.Context, stream llm.Stream)
ProcessStream reads events from the llm.Stream and sends them to the events channel. Text events are parsed for inline edit markers (INSERT/DELETE) and converted to StreamEventInlineInsert/StreamEventInlineDelete events. This method blocks until the stream is exhausted or an error occurs. The events channel is closed when this method returns.
Call this in a goroutine:
go adapter.ProcessStream(ctx, stream)
func (*PlanStreamAdapter) Stats ¶ added in v0.0.52
func (a *PlanStreamAdapter) Stats() *SessionStats
Stats returns the session stats being tracked.
type ProgressUpdate ¶ added in v0.0.11
type ProgressUpdate struct {
// OutputTokens is the number of tokens generated so far.
OutputTokens int
// Status is the current status text (e.g., "editing main.go").
Status string
// Milestone is a completed milestone to print above the spinner
// (e.g., "✓ Found edit for main.go").
Milestone string
// Phase is the current phase of the operation (e.g., "Thinking", "Responding").
// Used to show state transitions in the spinner.
Phase string
}
ProgressUpdate represents a progress update during long-running operations.
type Segment ¶ added in v0.0.26
type Segment struct {
Type SegmentType
Text string // For text segments: markdown content (finalized on completion)
Rendered string // For text segments: cached rendered markdown
ToolCallID string // For tool segments: unique ID for this invocation
ToolName string // For tool segments
ToolInfo string // For tool segments: additional context
ToolStatus ToolStatus // For tool segments
Complete bool // For text segments: whether streaming is complete
ImagePath string // For image segments: path to image file
DiffPath string // For diff segments: file path
DiffOld string // For diff segments: old content
DiffNew string // For diff segments: new content
DiffLine int // For diff segments: 1-indexed starting line (0 = unknown)
DiffRendered string // For diff segments: cached rendered output
DiffWidth int // For diff segments: width when rendered (for cache invalidation)
Flushed bool // True if this segment has been printed to scrollback
// Streaming text accumulation (O(1) append instead of O(n) string concat)
TextBuilder *strings.Builder // Used during streaming; nil when Complete
// Text snapshot cache - updated on append to avoid repeated String() calls
TextSnapshot string // Cached result of TextBuilder.String()
TextSnapshotLen int // Length when snapshot was taken (0 = invalid)
// Streaming markdown renderer - renders complete blocks as they arrive
StreamRenderer *TextSegmentRenderer // Active streaming renderer; nil when Complete
// Incremental rendering cache (streaming optimization)
SafePos int // Byte position of last safe markdown boundary
SafeRendered string // Cached render of text[:SafePos]
FlushedPos int // Byte position up to which content has been flushed to scrollback
FlushedRenderedPos int // Number of rendered bytes already flushed to scrollback
// Stitched rendering state (for correct inter-chunk spacing)
LastFlushedRaw string // Raw markdown of last flushed chunk (for stitched rendering)
LastFlushedRenderedLen int // Byte length of rendered LastFlushedRaw
// Subagent stats (for spawn_agent tools only)
SubagentToolCalls int // Number of tool calls made by subagent
SubagentTotalTokens int // Total tokens used by subagent
SubagentHasProgress bool // True if we have progress from this subagent
SubagentProvider string // Provider name if different from parent
SubagentModel string // Model name if different from parent
SubagentPreview []string // Preview lines (active tools + last few text lines)
SubagentStartTime time.Time // Start time for elapsed time display
SubagentEndTime time.Time // When subagent completed (zero if still running)
SubagentDiffs []SubagentDiff // Diffs from subagent's edit_file calls
}
Segment represents a discrete unit in the response stream (text or tool)
func FindSegmentByCallID ¶ added in v0.0.42
func FindSegmentByCallID(tracker *ToolTracker, callID string) *Segment
FindSegmentByCallID finds a segment by its tool call ID. Returns nil if not found.
func UpdateToolStatus ¶ added in v0.0.26
UpdateToolStatus updates the status of a pending tool matching the given call ID. Matching by unique ID ensures we update the correct tool when multiple calls to the same tool may be in progress.
func (*Segment) GetText ¶ added in v0.0.46
GetText returns the current text content of a segment. During streaming, it uses the cached TextSnapshot; after completion, it reads from Text. The snapshot is updated by AddTextSegment when content changes, avoiding repeated O(n) String() allocations on every render tick.
type SegmentType ¶ added in v0.0.26
type SegmentType int
SegmentType identifies the type of stream segment
const ( SegmentText SegmentType = iota SegmentTool SegmentAskUserResult // For ask_user answers (plain text, styled at render time) SegmentImage // For inline image display SegmentDiff // For inline diff display from edit tool )
type SessionStats ¶ added in v0.0.19
type SessionStats struct {
StartTime time.Time
InputTokens int
OutputTokens int
CachedInputTokens int // Tokens read from cache
CacheWriteTokens int // Tokens written to cache
ToolCallCount int
LLMCallCount int // Number of LLM API calls made
// Time tracking
LLMTime time.Duration
ToolTime time.Duration
// contains filtered or unexported fields
}
SessionStats tracks statistics for a session.
func NewSessionStats ¶ added in v0.0.19
func NewSessionStats() *SessionStats
NewSessionStats creates a new SessionStats with StartTime set to now.
func (*SessionStats) AddUsage ¶ added in v0.0.19
func (s *SessionStats) AddUsage(input, output, cached, cacheWrite int)
AddUsage adds token usage to the stats and increments the LLM call count.
func (*SessionStats) Finalize ¶ added in v0.0.19
func (s *SessionStats) Finalize()
Finalize records any remaining time.
func (SessionStats) Render ¶ added in v0.0.19
func (s SessionStats) Render() string
Render returns the stats as a compact single-line string.
func (*SessionStats) SeedTotals ¶ added in v0.0.73
func (s *SessionStats) SeedTotals(input, output, cached, toolCalls, llmCalls int)
SeedTotals initializes cumulative counters from persisted session metrics. Timing remains scoped to the current process run.
func (*SessionStats) ToolEnd ¶ added in v0.0.19
func (s *SessionStats) ToolEnd()
ToolEnd marks the end of tool execution (back to LLM).
func (*SessionStats) ToolStart ¶ added in v0.0.19
func (s *SessionStats) ToolStart()
ToolStart marks the start of a tool execution.
type SmoothBuffer ¶ added in v0.0.39
type SmoothBuffer struct {
// contains filtered or unexported fields
}
SmoothBuffer provides smooth 60fps text streaming with adaptive speed. Text is buffered and released word-by-word at a pace that adapts to the incoming content rate.
func NewSmoothBuffer ¶ added in v0.0.39
func NewSmoothBuffer() *SmoothBuffer
NewSmoothBuffer creates a new SmoothBuffer
func (*SmoothBuffer) FlushAll ¶ added in v0.0.39
func (b *SmoothBuffer) FlushAll() string
FlushAll returns all remaining content (for immediate display on tool start or cancel)
func (*SmoothBuffer) IsDrained ¶ added in v0.0.39
func (b *SmoothBuffer) IsDrained() bool
IsDrained returns true if the stream is done and buffer is empty
func (*SmoothBuffer) IsEmpty ¶ added in v0.0.39
func (b *SmoothBuffer) IsEmpty() bool
IsEmpty returns true if the buffer is empty
func (*SmoothBuffer) Len ¶ added in v0.0.39
func (b *SmoothBuffer) Len() int
Len returns the current buffer size in bytes
func (*SmoothBuffer) MarkDone ¶ added in v0.0.39
func (b *SmoothBuffer) MarkDone()
MarkDone signals that the input stream has ended
func (*SmoothBuffer) NextWords ¶ added in v0.0.39
func (b *SmoothBuffer) NextWords() string
NextWords returns the next N words based on buffer fill level. Long words are chunked into pieces. Whitespace is preserved.
func (*SmoothBuffer) Reset ¶ added in v0.0.39
func (b *SmoothBuffer) Reset()
Reset clears the buffer and resets the done flag
func (*SmoothBuffer) Write ¶ added in v0.0.39
func (b *SmoothBuffer) Write(text string)
Write adds incoming text to the buffer
type SmoothTickMsg ¶ added in v0.0.39
type SmoothTickMsg struct{}
SmoothTickMsg is sent to trigger the next frame of smooth text rendering
type StreamAdapter ¶ added in v0.0.34
type StreamAdapter struct {
// contains filtered or unexported fields
}
StreamAdapter bridges an llm.Stream to a channel of StreamEvents. It handles event conversion and provides proper buffering with blocking sends to ensure no events are dropped.
func NewStreamAdapter ¶ added in v0.0.34
func NewStreamAdapter(bufSize int) *StreamAdapter
NewStreamAdapter creates a new StreamAdapter with the specified buffer size. If bufSize <= 0, DefaultStreamBufferSize is used.
func (*StreamAdapter) EmitErrorAndClose ¶ added in v0.0.34
func (a *StreamAdapter) EmitErrorAndClose(err error)
EmitErrorAndClose sends an error event and closes the channel. Use this when stream creation fails before ProcessStream can be called.
func (*StreamAdapter) Events ¶ added in v0.0.34
func (a *StreamAdapter) Events() <-chan StreamEvent
Events returns the channel to read events from.
func (*StreamAdapter) ProcessStream ¶ added in v0.0.34
func (a *StreamAdapter) ProcessStream(ctx context.Context, stream llm.Stream)
ProcessStream reads events from the llm.Stream and sends them to the events channel. This method blocks until the stream is exhausted or an error occurs. The events channel is closed when this method returns.
Call this in a goroutine:
go adapter.ProcessStream(ctx, stream)
func (*StreamAdapter) Stats ¶ added in v0.0.34
func (a *StreamAdapter) Stats() *SessionStats
Stats returns the session stats being tracked.
type StreamEvent ¶ added in v0.0.34
type StreamEvent struct {
Type StreamEventType
// Text content (for StreamEventText)
Text string
// Tool events (for StreamEventToolStart, StreamEventToolEnd)
ToolCallID string
ToolName string
ToolInfo string
ToolSuccess bool
// Usage/stats (for StreamEventUsage)
InputTokens int
OutputTokens int
CachedTokens int
WriteTokens int
// Phase/retry (for StreamEventPhase, StreamEventRetry)
Phase string
RetryAttempt int
RetryMax int
RetryWait float64
// Completion (for StreamEventDone)
Done bool
Tokens int // Total output tokens at completion
// Error (for StreamEventError)
Err error
// Image (for StreamEventImage)
ImagePath string
// Diff (for StreamEventDiff)
DiffPath string
DiffOld string
DiffNew string
DiffLine int // 1-indexed starting line number (0 = unknown)
// Inline edits (for StreamEventInlineInsert, StreamEventInlineDelete, StreamEventPartialInsert)
InlineAfter string // INSERT: anchor text to insert after
InlineContent []string // INSERT: lines to insert (for complete insert)
InlineLine string // PartialInsert: single line being streamed
InlineFrom string // DELETE: start line text
InlineTo string // DELETE: end line text (empty for single line)
}
StreamEvent represents a unified event from the LLM stream. Used by both ask and chat commands for consistent event handling.
func DiffEvent ¶ added in v0.0.46
func DiffEvent(path, old, new string, line int) StreamEvent
DiffEvent creates a diff event from edit tool
func DoneEvent ¶ added in v0.0.34
func DoneEvent(totalTokens int) StreamEvent
DoneEvent creates a stream completion event
func ErrorEvent ¶ added in v0.0.34
func ErrorEvent(err error) StreamEvent
ErrorEvent creates an error event
func ImageEvent ¶ added in v0.0.39
func ImageEvent(path string) StreamEvent
ImageEvent creates an image event
func InlineDeleteEvent ¶ added in v0.0.52
func InlineDeleteEvent(from, to string) StreamEvent
InlineDeleteEvent creates an inline delete event
func InlineInsertEvent ¶ added in v0.0.52
func InlineInsertEvent(after string, content []string) StreamEvent
InlineInsertEvent creates an inline insert event
func InterjectionEvent ¶ added in v0.0.82
func InterjectionEvent(text string) StreamEvent
InterjectionEvent creates an interjection event (user message injected mid-stream)
func PartialInsertEvent ¶ added in v0.0.52
func PartialInsertEvent(after, line string) StreamEvent
PartialInsertEvent creates a partial insert event for streaming lines
func PhaseEvent ¶ added in v0.0.34
func PhaseEvent(phase string) StreamEvent
PhaseEvent creates a phase change event
func RetryEvent ¶ added in v0.0.34
func RetryEvent(attempt, max int, waitSecs float64) StreamEvent
RetryEvent creates a retry notification event
func TextEvent ¶ added in v0.0.34
func TextEvent(text string) StreamEvent
TextEvent creates a text delta event
func ToolEndEvent ¶ added in v0.0.34
func ToolEndEvent(callID, name, info string, success bool) StreamEvent
ToolEndEvent creates a tool execution end event
func ToolStartEvent ¶ added in v0.0.34
func ToolStartEvent(callID, name, info string) StreamEvent
ToolStartEvent creates a tool execution start event
func UsageEvent ¶ added in v0.0.34
func UsageEvent(input, output, cached, cacheWrite int) StreamEvent
UsageEvent creates a usage/token update event
type StreamEventType ¶ added in v0.0.34
type StreamEventType int
StreamEventType identifies the type of stream event
const ( StreamEventText StreamEventType = iota StreamEventToolStart StreamEventToolEnd StreamEventUsage StreamEventPhase StreamEventRetry StreamEventDone StreamEventError StreamEventImage // Image produced by tool StreamEventDiff // Diff from edit tool StreamEventInterjection // User interjected a message mid-stream StreamEventInlineInsert // Inline INSERT marker from planner (complete) StreamEventInlineDelete // Inline DELETE marker from planner StreamEventPartialInsert // Streaming partial line during INSERT )
type StreamingIndicator ¶ added in v0.0.15
type StreamingIndicator struct {
Spinner string // spinner.View() output
Phase string // "Thinking", "Searching", etc.
Elapsed time.Duration
Tokens int // 0 = don't show
Status string // optional status (e.g., "editing main.go")
ShowCancel bool // show "(esc to cancel)"
HideProgress bool // hide spinner/phase/tokens/time (shown in status line instead)
Segments []*Segment // active tool segments for wave animation
WavePos int // current wave position
Width int // terminal width for markdown rendering
RenderMarkdown func(string, int) string // markdown renderer for text segments
// Flush state for leading spacing
HasFlushed bool
LastFlushedType SegmentType
}
StreamingIndicator renders a consistent streaming status line
func (StreamingIndicator) Render ¶ added in v0.0.15
func (s StreamingIndicator) Render(styles *Styles) string
Render returns the formatted streaming indicator string
type Styles ¶
type Styles struct {
// Text styles
Title lipgloss.Style
Subtitle lipgloss.Style
Success lipgloss.Style
Error lipgloss.Style
Muted lipgloss.Style
Bold lipgloss.Style
Highlighted lipgloss.Style
// Table styles
TableHeader lipgloss.Style
TableCell lipgloss.Style
TableBorder lipgloss.Style
// UI element styles
Spinner lipgloss.Style
Command lipgloss.Style
// Diff styles
DiffAdd lipgloss.Style // Added lines (+)
DiffRemove lipgloss.Style // Removed lines (-)
DiffContext lipgloss.Style // Context lines (unchanged)
DiffHeader lipgloss.Style // Diff header (@@ ... @@)
// contains filtered or unexported fields
}
Styles returns styled text helpers bound to a renderer
func DefaultStyles ¶
func DefaultStyles() *Styles
DefaultStyles returns styles for stderr (default TUI output)
func NewStyledWithTheme ¶
NewStyledWithTheme creates styles with a specific theme
func (*Styles) FormatEnabled ¶
FormatEnabled returns a styled enabled/disabled indicator
func (*Styles) FormatResult ¶
FormatResult returns a styled success/fail result
type SubagentDiff ¶ added in v0.0.46
type SubagentDiff struct {
Path string
Old string
New string
Line int // 1-indexed starting line (0 = unknown)
Rendered string // Cached rendered output
Width int // Width when rendered (for cache invalidation)
}
SubagentDiff holds diff info from a subagent's edit_file call
type SubagentProgress ¶ added in v0.0.42
type SubagentProgress struct {
ToolCallID string // Links to parent's spawn_agent call
AgentName string // e.g., "reviewer"
TextBuffer strings.Builder // Text output (capped at maxTextBufferBytes)
ActiveTools []ToolSegment // Currently running tools
CompletedTools []ToolSegment // Completed tools (for expanded view)
Phase string // "Thinking", "Searching"
StartTime time.Time
Done bool
// Provider/model info (for displaying when different from parent)
Provider string // Provider name (e.g., "anthropic", "openai")
Model string // Model name (e.g., "claude-sonnet-4-20250514")
// Stats for header display
ToolCalls int // Total tool calls made
InputTokens int // Total input tokens
OutputTokens int // Total output tokens
// contains filtered or unexported fields
}
SubagentProgress tracks progress from a single spawned subagent.
func (*SubagentProgress) GetPreviewLines ¶ added in v0.0.42
func (p *SubagentProgress) GetPreviewLines() []string
GetPreviewLines returns the current preview lines for external access.
func (*SubagentProgress) Render ¶ added in v0.0.42
func (p *SubagentProgress) Render(expanded bool, maxPreviewLines int) string
Render returns preview (last N lines) or full content based on expanded flag.
func (*SubagentProgress) RenderHeader ¶ added in v0.0.42
func (p *SubagentProgress) RenderHeader(expanded bool) string
RenderHeader returns "@name N calls · X.Xk tokens [expanded]".
type SubagentTracker ¶ added in v0.0.42
type SubagentTracker struct {
// contains filtered or unexported fields
}
SubagentTracker tracks progress from multiple concurrent subagents.
func NewSubagentTracker ¶ added in v0.0.42
func NewSubagentTracker() *SubagentTracker
NewSubagentTracker creates a new tracker with default settings.
func (*SubagentTracker) ActiveAgents ¶ added in v0.0.42
func (t *SubagentTracker) ActiveAgents() []*SubagentProgress
ActiveAgents returns all non-done subagents in order of start time.
func (*SubagentTracker) Get ¶ added in v0.0.42
func (t *SubagentTracker) Get(callID string) *SubagentProgress
Get returns the progress tracker for a subagent, or nil if not found.
func (*SubagentTracker) GetOrCreate ¶ added in v0.0.42
func (t *SubagentTracker) GetOrCreate(callID, agentName string) *SubagentProgress
GetOrCreate returns the progress tracker for a subagent, creating if needed. Returns nil if the subagent has already been removed (tombstone exists).
func (*SubagentTracker) HandleInit ¶ added in v0.0.42
func (t *SubagentTracker) HandleInit(callID, provider, model string)
HandleInit sets the provider and model for a subagent. Only stores values if they differ from the main agent's provider/model.
func (*SubagentTracker) HandlePhase ¶ added in v0.0.42
func (t *SubagentTracker) HandlePhase(callID, phase string)
HandlePhase updates the phase of a subagent.
func (*SubagentTracker) HandleTextDelta ¶ added in v0.0.42
func (t *SubagentTracker) HandleTextDelta(callID, text string)
HandleTextDelta appends text to a subagent's buffer. The full buffer is capped at maxTextBufferBytes to prevent unbounded memory growth. Preview lines are always updated regardless of buffer cap.
func (*SubagentTracker) HandleToolEnd ¶ added in v0.0.42
func (t *SubagentTracker) HandleToolEnd(callID, toolName string, success bool)
HandleToolEnd marks a tool as completed in a subagent.
func (*SubagentTracker) HandleToolStart ¶ added in v0.0.42
func (t *SubagentTracker) HandleToolStart(callID, toolName, toolInfo string)
HandleToolStart records a tool starting in a subagent.
func (*SubagentTracker) HandleUsage ¶ added in v0.0.42
func (t *SubagentTracker) HandleUsage(callID string, inputTokens, outputTokens int)
HandleUsage accumulates token usage for a subagent.
func (*SubagentTracker) HasActive ¶ added in v0.0.42
func (t *SubagentTracker) HasActive() bool
HasActive returns true if there are any active (non-done) subagents.
func (*SubagentTracker) IsExpanded ¶ added in v0.0.42
func (t *SubagentTracker) IsExpanded() bool
IsExpanded returns whether expanded mode is active.
func (*SubagentTracker) MarkDone ¶ added in v0.0.42
func (t *SubagentTracker) MarkDone(callID string)
MarkDone marks a subagent as completed.
func (*SubagentTracker) Remove ¶ added in v0.0.42
func (t *SubagentTracker) Remove(callID string)
Remove removes a subagent from tracking (after spawn_agent completes). A tombstone is added to prevent late async events from resurrecting the entry. Only adds a tombstone if the callID was actually being tracked, to avoid unbounded tombstone growth from non-spawn_agent tool calls.
func (*SubagentTracker) SetMainProviderModel ¶ added in v0.0.42
func (t *SubagentTracker) SetMainProviderModel(provider, model string)
SetMainProviderModel sets the main agent's provider and model for comparison. Subagent provider/model will only be displayed if different from main.
func (*SubagentTracker) ToggleExpanded ¶ added in v0.0.42
func (t *SubagentTracker) ToggleExpanded()
ToggleExpanded switches between preview (4 lines) and full content.
type TextSegmentRenderer ¶ added in v0.0.53
type TextSegmentRenderer struct {
// contains filtered or unexported fields
}
TextSegmentRenderer wraps the streaming markdown renderer for use with text segments. It buffers rendered output so View() can read it.
func NewTextSegmentRenderer ¶ added in v0.0.53
func NewTextSegmentRenderer(width int) (*TextSegmentRenderer, error)
NewTextSegmentRenderer creates a new TextSegmentRenderer with the given width. Uses flowing mode (no cursor control) since Bubble Tea owns the terminal.
func (*TextSegmentRenderer) Close ¶ added in v0.0.53
func (r *TextSegmentRenderer) Close() error
Close flushes and cleans up the renderer.
func (*TextSegmentRenderer) CommittedMarkdownLen ¶ added in v0.0.55
func (r *TextSegmentRenderer) CommittedMarkdownLen() int
CommittedMarkdownLen returns the number of raw markdown bytes that have been committed as complete blocks by the streaming renderer.
func (*TextSegmentRenderer) Flush ¶ added in v0.0.53
func (r *TextSegmentRenderer) Flush() error
Flush renders any remaining incomplete blocks. Call this when the segment is complete.
func (*TextSegmentRenderer) FlushedRenderedPos ¶ added in v0.0.53
func (r *TextSegmentRenderer) FlushedRenderedPos() int
FlushedRenderedPos returns the current flushed position in the rendered output.
func (*TextSegmentRenderer) MarkFlushed ¶ added in v0.0.53
func (r *TextSegmentRenderer) MarkFlushed()
MarkFlushed marks the current rendered output length as flushed. Call this after successfully flushing content to scrollback.
func (*TextSegmentRenderer) PendingIsList ¶ added in v0.0.75
func (r *TextSegmentRenderer) PendingIsList() bool
PendingIsList reports whether the current incomplete block should be treated as a list for preview purposes.
func (*TextSegmentRenderer) PendingIsTable ¶ added in v0.0.60
func (r *TextSegmentRenderer) PendingIsTable() bool
PendingIsTable reports whether the current incomplete block is a table.
func (*TextSegmentRenderer) PendingMarkdown ¶ added in v0.0.60
func (r *TextSegmentRenderer) PendingMarkdown() string
PendingMarkdown returns the markdown that belongs to the current incomplete block.
func (*TextSegmentRenderer) Rendered ¶ added in v0.0.53
func (r *TextSegmentRenderer) Rendered() string
Rendered returns the currently rendered output. This is the content to display in View().
func (*TextSegmentRenderer) RenderedAll ¶ added in v0.0.55
func (r *TextSegmentRenderer) RenderedAll() string
RenderedAll returns the full rendered output including already-flushed content.
func (*TextSegmentRenderer) RenderedUnflushed ¶ added in v0.0.53
func (r *TextSegmentRenderer) RenderedUnflushed() string
RenderedUnflushed returns only the portion of rendered output that hasn't been flushed to scrollback yet. Use this in View() to avoid duplicating content that was already printed via FlushStreamingText.
func (*TextSegmentRenderer) Resize ¶ added in v0.0.53
func (r *TextSegmentRenderer) Resize(newWidth int) error
Resize handles terminal resize by re-rendering with new width. Note: The caller should handle any necessary screen clearing.
func (*TextSegmentRenderer) Width ¶ added in v0.0.53
func (r *TextSegmentRenderer) Width() int
Width returns the current terminal width.
func (*TextSegmentRenderer) Write ¶ added in v0.0.53
func (r *TextSegmentRenderer) Write(text string) error
Write writes text to the streaming renderer. Complete markdown blocks are rendered immediately.
type Theme ¶
type Theme struct {
// Primary colors
Primary lipgloss.Color // main accent color (commands, highlights)
Secondary lipgloss.Color // secondary accent (headers, borders)
// Semantic colors
Success lipgloss.Color // success states, enabled
Error lipgloss.Color // error states, disabled
Warning lipgloss.Color // warnings
Muted lipgloss.Color // dimmed/secondary text
Text lipgloss.Color // primary text
// UI element colors
Spinner lipgloss.Color // loading spinner
Border lipgloss.Color // borders and dividers
Background lipgloss.Color // background (if needed)
// Diff backgrounds
DiffAddBg lipgloss.Color // background for added lines
DiffRemoveBg lipgloss.Color // background for removed lines
DiffContextBg lipgloss.Color // background for context lines
// Message backgrounds
UserMsgBg lipgloss.Color // background for user messages in chat
}
Theme defines the color palette for the UI
func DefaultTheme ¶
func DefaultTheme() *Theme
DefaultTheme returns the default color theme (gruvbox)
func ThemeFromConfig ¶
func ThemeFromConfig(cfg ThemeConfig) *Theme
ThemeFromConfig creates a theme with config overrides applied
type ThemeConfig ¶
type ThemeConfig struct {
Primary string
Secondary string
Success string
Error string
Warning string
Muted string
Text string
Spinner string
UserMsgBg string
}
ThemeConfig mirrors the config.ThemeConfig for applying overrides
type ThemePreset ¶ added in v0.0.31
type ThemePreset struct {
Name string
Description string
Config ThemeConfig
}
ThemePreset represents a predefined color theme
func GetPresetTheme ¶ added in v0.0.31
func GetPresetTheme(name string) *ThemePreset
GetPresetTheme returns a preset by name, or nil if not found
type ToolPhase ¶ added in v0.0.25
type ToolPhase struct {
// Active is the phase text shown during execution (e.g., "web_search(cats)")
Active string
// Completed is the text shown after completion (e.g., "web_search(cats)")
Completed string
}
ToolPhase contains display strings for a tool execution phase.
func FormatToolPhase ¶ added in v0.0.25
FormatToolPhase returns display strings for a tool based on name and preview info. Uses unified format: name + info (where info contains parenthesized args). Example: web_search(cats), read_file(/src/main.go)
type ToolSegment ¶ added in v0.0.42
ToolSegment represents a tool's execution state in a subagent.
type ToolStatus ¶ added in v0.0.26
type ToolStatus int
ToolStatus represents the execution state of a tool
const ( ToolPending ToolStatus = iota ToolSuccess ToolError )
type ToolTracker ¶ added in v0.0.30
type ToolTracker struct {
Segments []Segment
WavePos int
WavePaused bool
LastActivity time.Time
Version uint64 // Incremented when content changes (segments added/modified)
TextMode bool // When true, skip markdown rendering (plain text output)
// Flush state for consistent spacing
LastFlushedType SegmentType
HasFlushed bool
}
ToolTracker manages tool segment state and wave animation. Designed to be embedded in larger models (ask, chat) for consistent tool tracking.
func NewToolTracker ¶ added in v0.0.30
func NewToolTracker() *ToolTracker
NewToolTracker creates a new ToolTracker
func (*ToolTracker) ActiveSegments ¶ added in v0.0.30
func (t *ToolTracker) ActiveSegments() []*Segment
ActiveSegments returns only the pending tool segments (for rendering). Returns pointers so mutations (like SafeRendered caching) persist.
func (*ToolTracker) AddDiffSegment ¶ added in v0.0.46
func (t *ToolTracker) AddDiffSegment(path, old, new string, line int)
AddDiffSegment adds a diff segment for inline display.
func (*ToolTracker) AddExternalUIResult ¶ added in v0.0.37
func (t *ToolTracker) AddExternalUIResult(summary string)
AddExternalUIResult adds a result from external UI (like ask_user) as a completed segment. The summary is plain text - styling is applied at render time to avoid ANSI corruption when passing through different tea.Program instances.
func (*ToolTracker) AddImageSegment ¶ added in v0.0.39
func (t *ToolTracker) AddImageSegment(path string)
AddImageSegment adds an image segment for inline display.
func (*ToolTracker) AddPreRenderedTextSegment ¶ added in v0.0.82
func (t *ToolTracker) AddPreRenderedTextSegment(rendered string)
AddPreRenderedTextSegment adds a text segment that is already fully rendered (e.g., styled interjection prompts). The segment is marked Complete immediately with the Rendered field set, so it bypasses markdown rendering entirely.
func (*ToolTracker) AddTextSegment ¶ added in v0.0.30
func (t *ToolTracker) AddTextSegment(text string, width int) bool
AddTextSegment adds or appends to a text segment. width is used to create the streaming markdown renderer for proper formatting. Returns true if this created a new segment.
func (*ToolTracker) AllCompletedSegments ¶ added in v0.0.52
func (t *ToolTracker) AllCompletedSegments() []*Segment
AllCompletedSegments returns all non-pending segments regardless of Flushed status. Use this for the final View() to ensure nothing is lost when segments were flushed to scrollback during streaming but we need the complete content for the final render.
func (*ToolTracker) AllSegments ¶ added in v0.0.46
func (t *ToolTracker) AllSegments() []Segment
AllSegments returns all segments regardless of Flushed status. Use for alt screen mode where we render everything in View().
func (*ToolTracker) CompleteTextSegments ¶ added in v0.0.30
func (t *ToolTracker) CompleteTextSegments(renderFunc func(string) string)
CompleteTextSegments marks all incomplete text segments as complete. Renders the full text with glamour on completion.
func (*ToolTracker) CompletedSegments ¶ added in v0.0.30
func (t *ToolTracker) CompletedSegments() []*Segment
CompletedSegments returns non-pending, non-flushed segments up to (but not past) the first pending tool. This preserves interleaving order: text before a pending tool is shown, but text after it is held back until the tool completes. Returns pointers so mutations (like SafeRendered caching) persist.
func (*ToolTracker) FlushAllRemaining ¶ added in v0.0.34
func (t *ToolTracker) FlushAllRemaining( width int, printedLines int, renderMd func(string, int) string, ) FlushToScrollbackResult
FlushAllRemaining returns any remaining unflushed content. Use this at the end of streaming to ensure all content is visible.
func (*ToolTracker) FlushBeforeExternalUI ¶ added in v0.0.37
func (t *ToolTracker) FlushBeforeExternalUI( width int, printedLines int, keepLines int, renderMd func(string, int) string, ) FlushToScrollbackResult
FlushBeforeExternalUI flushes content to scrollback before showing external UI. Keeps some recent content visible for context.
func (*ToolTracker) FlushCompletedNow ¶ added in v0.0.61
func (t *ToolTracker) FlushCompletedNow( width int, renderMd func(string, int) string, ) FlushToScrollbackResult
FlushCompletedNow flushes all completed, unflushed segments immediately. Unlike FlushToScrollback, this does not keep any segments for View(). Pending tools and incomplete text segments are never flushed.
func (*ToolTracker) FlushLeadingSeparator ¶ added in v0.0.61
func (t *ToolTracker) FlushLeadingSeparator(nextType SegmentType) string
FlushLeadingSeparator returns the spacing before a flushed segment, accounting for the trailing newline that tea.Printf/tea.Println adds. Use this only when the previous content was printed via a separate tea.Printf call. For intra-ToPrint spacing (multiple parts in one flush), use LeadingSeparator.
func (*ToolTracker) FlushStreamingText ¶ added in v0.0.52
func (t *ToolTracker) FlushStreamingText(threshold int, width int, renderMd func(string, int) string) FlushStreamingTextResult
FlushStreamingText flushes portions of in-progress text segments to scrollback when they exceed the threshold. Uses safe markdown boundaries to avoid breaking formatting. Returns rendered content to print, or empty if nothing to flush.
Parameters:
- threshold: minimum bytes before attempting flush (e.g., 4000)
- width: terminal width for rendering
- renderMd: markdown render function (text, width) -> rendered
func (*ToolTracker) FlushToScrollback ¶ added in v0.0.34
func (t *ToolTracker) FlushToScrollback( width int, printedLines int, maxViewLines int, renderMd func(string, int) string, ) FlushToScrollbackResult
FlushToScrollback flushes completed segments to scrollback. Incomplete text segments are NOT flushed - they show as raw text in View() and get rendered with glamour only when completed.
Parameters:
- width: terminal width for rendering
- printedLines: (unused, kept for API compatibility)
- maxViewLines: minimum completed segments to keep unflushed for View()
- renderMd: markdown render function (text, width) -> rendered
func (*ToolTracker) ForceCompletePendingTools ¶ added in v0.0.55
func (t *ToolTracker) ForceCompletePendingTools()
ForceCompletePendingTools marks any pending tools as complete. Call this before FlushAllRemaining when streaming is done to ensure no tools are left in pending state (which would be skipped during flush).
func (*ToolTracker) HandleToolEnd ¶ added in v0.0.30
func (t *ToolTracker) HandleToolEnd(callID string, success bool)
HandleToolEnd updates the status of a pending tool by its call ID.
func (*ToolTracker) HandleToolStart ¶ added in v0.0.30
func (t *ToolTracker) HandleToolStart(callID, toolName, toolInfo string) bool
HandleToolStart adds a pending segment for this tool call. Uses the unique callID to track this specific invocation. Returns true if a new segment was added (caller should start wave animation).
func (*ToolTracker) HandleWavePause ¶ added in v0.0.30
func (t *ToolTracker) HandleWavePause() tea.Cmd
HandleWavePause handles the end of a wave pause. Returns the next tick command if there are still pending tools.
func (*ToolTracker) HandleWaveTick ¶ added in v0.0.30
func (t *ToolTracker) HandleWaveTick() tea.Cmd
HandleWaveTick advances the wave animation. Returns the next command (tick, pause, or nil if no pending tools).
func (*ToolTracker) HasPending ¶ added in v0.0.30
func (t *ToolTracker) HasPending() bool
HasPending returns true if there are any pending tool segments.
func (*ToolTracker) IsIdle ¶ added in v0.0.34
func (t *ToolTracker) IsIdle(d time.Duration) bool
IsIdle returns true if there has been no activity for the given duration and there are no pending tools (tools have their own wave animation).
func (*ToolTracker) LeadingSeparator ¶ added in v0.0.55
func (t *ToolTracker) LeadingSeparator(nextType SegmentType) string
LeadingSeparator returns the full spacing before a segment of the given type, based on the last flushed segment. Use this for View()/Render() output and when appending multiple parts within a single ToPrint (no tea.Printf between them). For spacing across tea.Printf boundaries, use FlushLeadingSeparator instead.
func (*ToolTracker) MarkCurrentTextComplete ¶ added in v0.0.30
func (t *ToolTracker) MarkCurrentTextComplete(renderFunc func(string) string)
MarkCurrentTextComplete marks the current text segment as complete before a tool starts. Renders the full text with glamour.
func (*ToolTracker) RecordActivity ¶ added in v0.0.34
func (t *ToolTracker) RecordActivity()
RecordActivity records the current time as the last activity. Call this when text is received, tools start, or tools end.
func (*ToolTracker) RenderUnflushed ¶ added in v0.0.55
func (t *ToolTracker) RenderUnflushed(width int, renderMd func(string, int) string, includeImages bool) string
RenderUnflushed renders all non-pending, non-flushed segments with proper leading spacing.
func (*ToolTracker) ResizeStreamRenderers ¶ added in v0.0.53
func (t *ToolTracker) ResizeStreamRenderers(width int)
ResizeStreamRenderers updates all active streaming renderers with new width. On resize error, the renderer is disabled to avoid inconsistent output.
func (*ToolTracker) StartWave ¶ added in v0.0.30
func (t *ToolTracker) StartWave() tea.Cmd
StartWave initializes and starts the wave animation. Returns the command to start the tick cycle.
func (*ToolTracker) UnflushedSegments ¶ added in v0.0.52
func (t *ToolTracker) UnflushedSegments() []*Segment
UnflushedSegments returns segments with unflushed content for final rendering. For text segments with partial flushes (FlushedPos > 0), creates a copy with only the unflushed portion. This ensures we don't duplicate content that was already printed to scrollback during streaming.
type WavePauseMsg ¶ added in v0.0.30
type WavePauseMsg struct{}
WavePauseMsg is sent when wave pause ends
type WaveTickMsg ¶ added in v0.0.30
type WaveTickMsg struct{}
WaveTickMsg is sent to advance the wave animation
Source Files
¶
- cmd_compose.go
- env_bool.go
- highlight.go
- image_inline.go
- inline_diff.go
- markdown.go
- markdown_boundary.go
- newline_policy.go
- plan_stream_adapter.go
- postexec.go
- progress.go
- segment.go
- selector.go
- smooth_buffer.go
- stats.go
- stream_adapter.go
- stream_event.go
- styles.go
- subagent_helpers.go
- subagent_tracker.go
- text_segment_renderer.go
- theme_presets.go
- tool_display.go
- tool_tracker.go
- unified_diff.go
- wizard.go