ui

package
v0.0.362 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 47 Imported by: 0

Documentation

Index

Constants

View Source
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
	// MaxStreamingConsecutiveNewlines limits runaway vertical whitespace in streamed text.
	MaxStreamingConsecutiveNewlines = 2
)
View Source
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

View Source
const (
	EnabledIcon  = "●"
	DisabledIcon = "○"
	SuccessIcon  = "✓"
	FailIcon     = "✗"
)

Status indicators

View Source
const DefaultStreamBufferSize = 100

DefaultStreamBufferSize is the default buffer size for the event channel. Large enough to handle bursts while still providing backpressure.

View Source
const SomethingElse = "__something_else__"

Variables

View Source
var PresetThemeNames = []string{
	"gruvbox",
	"dracula",
	"nord",
	"solarized",
	"monokai",
	"classic",
}

PresetThemeNames defines the display order of themes

View Source
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 ANSILen added in v0.0.6

func ANSILen(s string) int

ANSILen returns the display width of a string, ignoring ANSI codes

func AttachSubagentProgressToSegment added in v0.0.307

func AttachSubagentProgressToSegment(tracker *ToolTracker, subagentTracker *SubagentTracker, callID string)

AttachSubagentProgressToSegment copies already-received subagent progress onto a newly visible spawn_agent tool segment. Progress can arrive through a TUI Program.Send before the stream ToolStart event has been processed, because the parent stream and subagent callback use independent channels.

func BuildSubagentPreview added in v0.0.42

func BuildSubagentPreview(p *SubagentProgress, maxCalls int) []string

BuildSubagentPreview builds preview lines for a subagent in chronological order. Shows completed tools first (oldest first), then active tools (most recent). maxCalls limits the number of nested tool calls, not rendered lines. A guardian annotation remains grouped with its tool; annotations on older omitted calls are available in the unbounded expanded preview. A non-positive limit shows all calls.

func CalcDiffWidth added in v0.0.5

func CalcDiffWidth(oldContent, newContent string) int

CalcDiffWidth calculates the required padding width for a diff The result is capped to the terminal-aware max content width

func ClampInt added in v0.0.176

func ClampInt(v, lo, hi int) int

ClampInt constrains v to the inclusive range [lo, hi].

func ClearRenderedImages added in v0.0.39

func ClearRenderedImages()

ClearRenderedImages clears the terminal image render cache. Call this when starting a new session.

func ComposeFlushFirstCommands added in v0.0.62

func ComposeFlushFirstCommands(flushCmds []tea.Cmd, asyncCmds []tea.Cmd) tea.Cmd

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

func CountLines(content string) int

CountLines counts the number of newlines in content

func CountTrailingNewlines added in v0.0.69

func CountTrailingNewlines(s string) int

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 EstimateSessionStatsCost added in v0.0.328

func EstimateSessionStatsCost(stats *SessionStats, fallbackModel string) (float64, error)

EstimateSessionStatsCost prices each current-process provider request separately using bundled or already-cached pricing only.

func FindSafeBoundary added in v0.0.46

func FindSafeBoundary(text string) int

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

func FindSafeBoundaryIncremental(text string, lastSafePos int) int

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 FlushSegmentSeparator added in v0.0.155

func FlushSegmentSeparator(prevType, currType SegmentType) string

FlushSegmentSeparator returns the spacing before a segment when the previous content was printed by a separate tea.Printf/tea.Println call, which already contributed one trailing newline.

func FlushSegmentSeparatorAfter added in v0.0.339

func FlushSegmentSeparatorAfter(prevType, currType SegmentType, previousPlan bool) string

FlushSegmentSeparatorAfter is SegmentSeparatorAfter adjusted for the newline automatically emitted by a separate tea.Printf/tea.Println call.

func FormatElapsedDuration added in v0.0.224

func FormatElapsedDuration(d time.Duration) string

FormatElapsedDuration formats an elapsed duration for compact progress displays.

func FormatRetryStatus added in v0.0.305

func FormatRetryStatus(label string, attempt, max int, waitSecs float64, precision int, suffix string) string

FormatRetryStatus returns a consistent retry status string for CLI/TUI surfaces. precision controls the wait seconds decimal places; suffix is often "..." for live terminal status messages.

func FormatTokenCount added in v0.0.61

func FormatTokenCount(n int) string

FormatTokenCount formats a token count in compact form: 1, 999, 1.5k, 12.3k, 1.1M

func GetPendingToolTextLen added in v0.0.26

func GetPendingToolTextLen(segments []Segment) int

GetPendingToolTextLen returns the text length of the first pending tool (for wave animation)

func GetRefinement

func GetRefinement() (string, error)

GetRefinement prompts the user for additional guidance

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 HasDiff added in v0.0.10

func HasDiff(oldContent, newContent string) bool

HasDiff returns true if old and new content are different

func HasPendingTool added in v0.0.26

func HasPendingTool(segments []Segment) bool

HasPendingTool returns true if any segment has a pending tool

func HasTTY added in v0.0.154

func HasTTY() bool

HasTTY returns true if /dev/tty can be opened (interactive terminal available).

func ImageArtifactCaption added in v0.0.227

func ImageArtifactCaption(path string) string

ImageArtifactCaption returns the standard visible caption for a generated image.

func InitTheme

func InitTheme(cfg ThemeConfig)

InitTheme initializes the theme from config

func IsPlanChecklistSegment added in v0.0.339

func IsPlanChecklistSegment(seg *Segment) bool

IsPlanChecklistSegment reports whether seg uses the dedicated multi-line plan renderer.

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 NewAltScreenMouseView added in v0.0.176

func NewAltScreenMouseView(content string) tea.View

NewAltScreenMouseView returns an alt-screen view with cell-motion mouse mode enabled.

func NewAltScreenView added in v0.0.176

func NewAltScreenView(content string) tea.View

NewAltScreenView returns a Bubble Tea view configured for alt-screen output.

func NewViewportWithFooter added in v0.0.176

func NewViewportWithFooter(width, height, footerLines int) viewport.Model

NewViewportWithFooter creates a viewport sized for a layout with a fixed number of footer lines.

func NewlinePadding added in v0.0.69

func NewlinePadding(currentTrailing, targetTrailing int) string

NewlinePadding returns the minimal newline padding needed to reach at least targetTrailing trailing newlines.

func NewlinesNeededForTrailing added in v0.0.69

func NewlinesNeededForTrailing(currentTrailing, targetTrailing int) int

NewlinesNeededForTrailing returns the number of '\n' characters required to reach at least targetTrailing newlines.

func NormalizeReasoningSegmentRendered added in v0.0.258

func NormalizeReasoningSegmentRendered(rendered string) string

func ParseBoolDefault added in v0.0.74

func ParseBoolDefault(raw string, defaultValue bool) bool

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

func PrintCompactDiff(filePath, oldContent, newContent string, padWidth int)

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 RemainingHeight added in v0.0.176

func RemainingHeight(total int, sections ...string) int

RemainingHeight subtracts the rendered heights of the provided sections from total and always returns at least 1.

func RemainingLines added in v0.0.176

func RemainingLines(total, reserved int) int

RemainingLines subtracts reserved lines from total and always returns at least 1.

func RenderDiffSegment added in v0.0.46

func RenderDiffSegment(filePath, oldContent, newContent string, width int, startLine int) string

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 RenderDiffSegmentWithOperation added in v0.0.197

func RenderDiffSegmentWithOperation(filePath, oldContent, newContent string, width int, startLine int, operation string) string

RenderDiffSegmentWithOperation renders a unified diff with an optional operation-specific header.

func RenderImageArtifact added in v0.0.226

func RenderImageArtifact(path string) string

RenderImageArtifact renders an image for terminal output and always includes a textual path caption. Some terminals advertise an image protocol but render the escape/placeholder area as blank (for example through multiplexers); the caption keeps generated-image artifacts visible and actionable in those cases.

func RenderImageArtifactWithRenderer added in v0.0.227

func RenderImageArtifactWithRenderer(path string, renderer ImageArtifactRenderer) string

RenderImageArtifactWithRenderer renders an image artifact using renderer. If renderer is nil, the normal inline/scrollback renderer is used.

func RenderImagesAndDiffs added in v0.0.50

func RenderImagesAndDiffs(segments []*Segment, width int) string

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 RenderImagesAndDiffsWithRenderer added in v0.0.227

func RenderImagesAndDiffsWithRenderer(segments []*Segment, width int, renderer ImageArtifactRenderer) string

RenderImagesAndDiffsWithRenderer renders only image and diff segments using renderer for images. When renderer is nil, images use the default renderer.

func RenderInlineImage added in v0.0.39

func RenderInlineImage(path string) string

RenderInlineImage renders an image for normal inline/scrollback terminal output. It returns an empty string on error or when image rendering is disabled.

func RenderMarkdown added in v0.0.34

func RenderMarkdown(content string, width int) string

RenderMarkdown renders markdown content with the shared terminal renderer. On error, returns the original content unchanged.

func RenderMarkdownWithError added in v0.0.34

func RenderMarkdownWithError(content string, width int) (string, error)

RenderMarkdownWithError renders markdown content and returns any errors.

func RenderMarkdownWithOptions added in v0.0.155

func RenderMarkdownWithOptions(content string, width int, options MarkdownRenderOptions) string

RenderMarkdownWithOptions renders markdown with caller-specific compatibility options. On error, returns the original content unchanged.

func RenderMarkdownWithOptionsError added in v0.0.155

func RenderMarkdownWithOptionsError(content string, width int, options MarkdownRenderOptions) (string, error)

RenderMarkdownWithOptionsError renders markdown with caller-specific compatibility options.

func RenderSegments added in v0.0.26

func RenderSegments(segments []*Segment, width int, wavePos int, renderMarkdown func(string, int) string, includeImages bool, expanded bool) string

RenderSegments renders a list of segments to a string.

func RenderSegmentsWithImageRenderer added in v0.0.227

func RenderSegmentsWithImageRenderer(segments []*Segment, width int, wavePos int, renderMarkdown func(string, int) string, includeImages bool, expanded bool, renderer ImageArtifactRenderer) string

RenderSegmentsWithImageRenderer renders segments using renderer for image segments. When renderer is nil, images use the default inline/scrollback renderer.

func RenderSegmentsWithLeading added in v0.0.55

func RenderSegmentsWithLeading(leading *Segment, segments []*Segment, width int, wavePos int, renderMarkdown func(string, int) string, includeImages bool, expanded bool) string

RenderSegmentsWithLeading renders a list of segments, optionally using a leading segment for initial spacing.

func RenderSegmentsWithLeadingAndImageRenderer added in v0.0.227

func RenderSegmentsWithLeadingAndImageRenderer(leading *Segment, segments []*Segment, width int, wavePos int, renderMarkdown func(string, int) string, includeImages bool, expanded bool, renderer ImageArtifactRenderer) string

RenderSegmentsWithLeadingAndImageRenderer renders a list of segments, optionally using a leading segment for initial spacing and renderer for image segments.

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

func RenderToolCallFromPart(tc *llm.ToolCall, width int, expanded bool) string

RenderToolCallFromPart renders a historical tool call from an llm.ToolCall. Uses success styling since historical calls without matching results are assumed completed. width is the terminal width used to truncate long lines (0 = no truncation).

func RenderToolCallFromPartWithStatus added in v0.0.308

func RenderToolCallFromPartWithStatus(tc *llm.ToolCall, width int, expanded bool, status ToolStatus) string

RenderToolCallFromPartWithStatus renders a historical tool call from an llm.ToolCall using the supplied execution status. width is the terminal width used to truncate long lines (0 = no truncation).

func RenderToolSegment added in v0.0.26

func RenderToolSegment(seg *Segment, wavePos int, width int, expanded bool) string

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

func RenderWaveText(text string, wavePos int) string

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 ResizeViewportWithFooter added in v0.0.176

func ResizeViewportWithFooter(vp *viewport.Model, width, height, footerLines int)

ResizeViewportWithFooter updates a viewport for a layout with a fixed number of footer lines.

func RetryAttemptLabel added in v0.0.305

func RetryAttemptLabel(attempt, max int) string

RetryAttemptLabel formats retry attempt progress. A max value of 0 means the retry policy is time-budgeted and has no fixed attempt ceiling.

func RunHeadlessSetup added in v0.0.154

func RunHeadlessSetup() (*config.Config, error)

RunHeadlessSetup auto-configures term-llm when no TTY is available (e.g. Docker). It picks the first provider with credentials set in the environment and saves a config.

func RunSetupWizard

func RunSetupWizard() (*config.Config, error)

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

func ScrollbackPrintlnCommands(content string, includeFinalSpacer bool) []tea.Cmd

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 SegmentBoundaryTrailingNewlines added in v0.0.155

func SegmentBoundaryTrailingNewlines(prevType, currType SegmentType) int

SegmentBoundaryTrailingNewlines returns the target trailing newline run for a boundary between two rendered segment types.

func SegmentBoundaryTrailingNewlinesAfter added in v0.0.339

func SegmentBoundaryTrailingNewlinesAfter(prevType, currType SegmentType, previousPlan bool) int

SegmentBoundaryTrailingNewlinesAfter returns the target trailing newline run after a rendered segment. Plan checklists are multi-line blocks, so always leave one blank line before a following block without changing ordinary compact tool-to-tool spacing.

func SegmentSeparator added in v0.0.55

func SegmentSeparator(prevType, currType SegmentType) string

SegmentSeparator returns the vertical spacing (newlines) required between two segments.

func SegmentSeparatorAfter added in v0.0.339

func SegmentSeparatorAfter(prevType, currType SegmentType, previousPlan bool) string

SegmentSeparatorAfter returns boundary spacing and can preserve a blank line after a rendered plan checklist.

func SegmentSeparatorBetween added in v0.0.339

func SegmentSeparatorBetween(previous, current *Segment) string

SegmentSeparatorBetween returns spacing for two concrete 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 SetTheme

func SetTheme(t *Theme)

SetTheme sets the current active theme

func ShowCommand

func ShowCommand(cmd string)

ShowCommand displays the command that will be executed (to stderr, keeping stdout clean)

func ShowCommandHelp

func ShowCommandHelp(command, shell string, engine *llm.Engine) error

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

func ShowEditSkipped(filePath string, reason string)

ShowEditSkipped shows that an edit was skipped

func ShowError

func ShowError(msg string)

ShowError displays an error message

func SmoothTick added in v0.0.39

func SmoothTick() tea.Cmd

SmoothTick returns a tea.Cmd that sends a SmoothTickMsg after the frame interval

func SplitLines added in v0.0.35

func SplitLines(content string) []string

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 StripANSI added in v0.0.6

func StripANSI(s string) string

StripANSI removes all ANSI escape codes from a string

func SuccessCircle added in v0.0.26

func SuccessCircle() string

SuccessCircle returns the success status indicator

func Truncate

func Truncate(s string, maxLen int) string

Truncate shortens a string to maxLen with ellipsis

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 VisibleRange added in v0.0.176

func VisibleRange(total, cursor, visible int) (start, end int)

VisibleRange returns the [start, end) range of items that should be shown to keep cursor visible inside a window of visible items.

func VisibleRangeByHeights added in v0.0.176

func VisibleRangeByHeights(heights []int, cursor, maxRows int) (start, end int)

VisibleRangeByHeights returns the [start, end) range of items that can fit within maxRows while keeping cursor visible. Item heights are measured in terminal rows.

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

type DiffData = llm.DiffData

DiffData is an alias for llm.DiffData for backward compatibility.

func ParseDiffMarkers added in v0.0.55

func ParseDiffMarkers(output string) []DiffData

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 ImageArtifact added in v0.0.227

type ImageArtifact struct {
	Caption  string
	Display  string
	Upload   string
	CacheKey string
	Height   int
	Warnings []string
}

ImageArtifact is a rendered generated-image artifact split into a safe display portion and any out-of-band terminal upload bytes.

func DefaultImageArtifactRenderer added in v0.0.227

func DefaultImageArtifactRenderer(path string) ImageArtifact

DefaultImageArtifactRenderer renders images for normal inline/scrollback use.

type ImageArtifactRenderer added in v0.0.227

type ImageArtifactRenderer func(path string) ImageArtifact

ImageArtifactRenderer renders a generated image path for a particular output surface. Viewport renderers should return raw terminal protocol bytes in Upload and keep Display line-clipping safe. RenderImageArtifactWithRenderer never embeds Upload in returned text; callers that need out-of-band upload emission should collect/queue Upload in the renderer or surrounding render context.

type MarkdownRenderOptions added in v0.0.155

type MarkdownRenderOptions struct {
	WrapOffset int

	NormalizeTabs     bool
	NormalizeNewlines bool

	EnsureTrailingLine bool
}

MarkdownRenderOptions controls legacy caller-specific markdown rendering quirks.

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 ReasoningSegment added in v0.0.258

type ReasoningSegment struct {
	Content  string
	Kind     string
	Title    string
	Expanded *bool // Optional per-segment override; nil follows global reasoning display mode.
}

ReasoningSegment is the renderer-owned display metadata for a committed reasoning/thought block in the streaming segment list. It deliberately avoids storing provider replay fields or llm.Part to keep ui segments decoupled from provider/session data structures.

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
	ToolArgs       json.RawMessage      // Raw args JSON, stored for expanded rendering
	Guardian       *tools.GuardianEvent // Guardian review for this exact tool invocation
	ToolStatus     ToolStatus           // For tool segments
	ToolExpandHint bool                 // Show one-time "CTRL+e to expand" discovery hint
	Reasoning      *ReasoningSegment    // For pre-rendered reasoning summary segments; rerendered when display mode changes
	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)
	DiffOperation  string               // For diff segments: optional operation hint, e.g. "create"
	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 - refreshed lazily when callers need stable text.
	TextSnapshot    string // Cached clone of TextBuilder contents
	TextSnapshotLen int    // Builder length when TextSnapshot was captured (-1 = stale)

	// 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
	SubagentPrompt          string         // Prompt/task passed to the subagent
	SubagentPreview         []string       // Bounded nested tool-call preview for collapsed display
	SubagentExpandedPreview []string       // Complete nested tool-call preview for expanded display
	SubagentPreviewTextOnly bool           // Preview is prose fallback and needs a visual-line bound
	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/write_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

func UpdateToolStatus(segments []Segment, callID string, success bool) []Segment

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

func (s *Segment) GetText() string

GetText returns the current text content of a segment. During streaming, it uses a cached cloned snapshot when one matches the current builder length; otherwise it refreshes the snapshot lazily.

type SegmentType added in v0.0.26

type SegmentType int

SegmentType identifies the type of stream segment

const (
	SegmentText SegmentType = iota
	SegmentTool
	SegmentReasoning     // For committed reasoning/thought summary blocks
	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
	CacheWriteTokens  int
	ToolCallCount     int
	LLMCallCount      int

	GuardianInputTokens       int
	GuardianOutputTokens      int
	GuardianCachedInputTokens int
	GuardianCacheWriteTokens  int
	GuardianLLMCallCount      int

	CompactionInputTokens       int
	CompactionOutputTokens      int
	CompactionCachedInputTokens int
	CompactionCacheWriteTokens  int
	CompactionLLMCallCount      int

	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

func (*SessionStats) AddCompactionUsage added in v0.0.234

func (s *SessionStats) AddCompactionUsage(input, output, cached, cacheWrite int)

AddCompactionUsage records a helper compaction call against the current model. Unlike AddUsage, it deliberately leaves pending main-call timing untouched.

func (*SessionStats) AddCompactionUsageForModel added in v0.0.328

func (s *SessionStats) AddCompactionUsageForModel(model string, input, output, cached, cacheWrite int)

AddCompactionUsageForModel records compaction usage against the model that performed it without changing the model or timing of a pending main call.

func (*SessionStats) AddGuardianUsageForModel added in v0.0.335

func (s *SessionStats) AddGuardianUsageForModel(model string, input, output, cached, cacheWrite int)

AddGuardianUsageForModel records guardian-review usage in aggregate token, call, and pricing totals without disturbing main-request timing or context hints.

func (*SessionStats) AddHandoverUsageForModel added in v0.0.358

func (s *SessionStats) AddHandoverUsageForModel(model string, input, output, cached, cacheWrite int)

AddHandoverUsageForModel records handover-helper usage without disturbing main-request timing or treating it as context compaction.

func (*SessionStats) AddSideQuestionUsageForModel added in v0.0.334

func (s *SessionStats) AddSideQuestionUsageForModel(model string, input, output, cached, cacheWrite int)

AddSideQuestionUsageForModel records side-question usage in aggregate token, call, and pricing totals without disturbing main-request timing or context hints.

func (*SessionStats) AddUsage added in v0.0.19

func (s *SessionStats) AddUsage(input, output, cached, cacheWrite int)

func (*SessionStats) ClearEstimatedCost added in v0.0.328

func (s *SessionStats) ClearEstimatedCost()

func (*SessionStats) DiscardUsage added in v0.0.229

func (s *SessionStats) DiscardUsage(input, output, cached, cacheWrite, calls int)

DiscardUsage removes provisional usage calls from the tail and resets any uncompleted attempt activity. Performance is always derived from retained call records, so TTFT and throughput are restored exactly after a retry.

func (*SessionStats) Finalize added in v0.0.19

func (s *SessionStats) Finalize()

func (*SessionStats) GenerationEnd added in v0.0.328

func (s *SessionStats) GenerationEnd()

GenerationEnd closes the current activity interval. AddUsage associates the accumulated interval with that completed provider request.

func (*SessionStats) ObserveOutput added in v0.0.328

func (s *SessionStats) ObserveOutput()

ObserveOutput records generation activity. This includes visible text and reasoning as well as hidden/encrypted reasoning events, but not tool calls.

func (SessionStats) Render added in v0.0.19

func (s SessionStats) Render() string

func (*SessionStats) RequestStart added in v0.0.328

func (s *SessionStats) RequestStart()

func (*SessionStats) ScheduleRetryStart added in v0.0.328

func (s *SessionStats) ScheduleRetryStart(waitSecs float64)

ScheduleRetryStart records when a retried provider request will start. Retry events are emitted before the provider wait, so TTFT must exclude that delay.

func (*SessionStats) SeedTotals added in v0.0.73

func (s *SessionStats) SeedTotals(input, output, cached, cacheWrite, toolCalls, llmCalls int)

SeedTotals initializes cumulative counters from persisted session metrics. Process-local call, timing, model, and cost state is reset: persisted totals do not contain enough request detail to price or calculate throughput safely.

func (*SessionStats) SetEstimatedCost added in v0.0.328

func (s *SessionStats) SetEstimatedCost(cost float64)

func (*SessionStats) SetModel added in v0.0.328

func (s *SessionStats) SetModel(model string)

SetModel sets the model attached to subsequently completed usage calls.

func (*SessionStats) ToolEnd added in v0.0.19

func (s *SessionStats) ToolEnd()

func (*SessionStats) ToolStart added in v0.0.19

func (s *SessionStats) ToolStart()

func (*SessionStats) UsageCalls added in v0.0.328

func (s *SessionStats) UsageCalls() ([]UsageCall, bool)

UsageCalls returns current-process calls and whether they represent the whole displayed session. A false completeness value means historical seeded usage prevents a truthful whole-session cost.

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) EmitGuardian added in v0.0.339

func (a *StreamAdapter) EmitGuardian(ctx context.Context, event tools.GuardianEvent) bool

EmitGuardian inserts a guardian review into the same ordered event stream as tool start/end events. It returns false after the adapter closes or when the supplied context is canceled.

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

	// Model switch metadata (for StreamEventModelSwitch)
	ReasoningEffort string

	// Interjection metadata (for StreamEventInterjection)
	InterjectionID string
	Message        llm.Message

	// Tool events (for StreamEventToolStart, StreamEventToolEnd)
	ToolCallID  string
	ToolName    string
	ToolInfo    string
	ToolArgs    json.RawMessage
	ToolSuccess bool

	// Guardian review (for StreamEventGuardian)
	Guardian tools.GuardianEvent

	// 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)
	DiffOperation string // Optional operation hint, e.g. "create" for new files

	// File change metadata (for StreamEventFileChange). Contents are never
	// carried on events; viewers fetch diffs from the session endpoints.
	FileChange llm.FileChange

	// Reasoning (for StreamEventReasoning). Encrypted replay payloads are never
	// included here; surfaces decide display policy from the classified text.
	ReasoningKind        llm.ReasoningKind
	ReasoningText        string
	ReasoningTitle       string
	ReasoningItemID      string
	ReasoningFinal       bool
	ReasoningDisplayable bool
}

StreamEvent represents a unified event from the LLM stream. Used by both ask and chat commands for consistent event handling.

func AttemptDiscardEvent added in v0.0.229

func AttemptDiscardEvent() StreamEvent

func DiffEvent added in v0.0.46

func DiffEvent(path, old, new string, line int) StreamEvent

DiffEvent creates a diff event from edit/write tools

func DiffEventWithOperation added in v0.0.197

func DiffEventWithOperation(path, old, new string, line int, operation string) StreamEvent

DiffEventWithOperation creates a diff event with an operation hint.

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 FileChangeEvent added in v0.0.286

func FileChangeEvent(fc llm.FileChange) StreamEvent

FileChangeEvent creates a file-change metadata event (file tracking).

func GenerationActivityEvent added in v0.0.328

func GenerationActivityEvent() StreamEvent

func GuardianReviewEvent added in v0.0.339

func GuardianReviewEvent(event tools.GuardianEvent) StreamEvent

GuardianReviewEvent creates a guardian review event correlated with a tool call.

func ImageEvent added in v0.0.39

func ImageEvent(path string) StreamEvent

ImageEvent creates an image event

func InterjectionEvent added in v0.0.82

func InterjectionEvent(text, interjectionID string) StreamEvent

InterjectionEvent creates an interjection event (user message injected mid-stream).

func InterjectionEventWithMessage added in v0.0.254

func InterjectionEventWithMessage(text, interjectionID string, msg llm.Message) StreamEvent

InterjectionEventWithMessage creates an interjection event with structured content.

func ModelSwitchEvent added in v0.0.292

func ModelSwitchEvent(model, reasoningEffort string) StreamEvent

ModelSwitchEvent creates an event for an in-run request model change.

func PhaseEvent added in v0.0.34

func PhaseEvent(phase string) StreamEvent

PhaseEvent creates a phase change event

func ReasoningEvent added in v0.0.258

func ReasoningEvent(kind llm.ReasoningKind, text, title, itemID string, final bool, displayable bool) StreamEvent

ReasoningEvent creates a classified, non-encrypted reasoning stream 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, args json.RawMessage) 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

func (StreamEvent) RetryStatus added in v0.0.305

func (e StreamEvent) RetryStatus(label string, precision int, suffix string) string

RetryStatus formats this event as retry status text.

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
	StreamEventModelSwitch  // Request model changed at a provider-turn boundary
	StreamEventAttemptDiscard
	StreamEventReasoning          // Classified, non-encrypted reasoning text/metadata
	StreamEventGenerationActivity // Hidden generation activity (for timing only)
	StreamEventFileChange         // Recorded file change metadata (file tracking)
	StreamEventGuardian           // Guardian review correlated with a tool call
)

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               // live tool segments for wave/status rendering
	WavePos        int                      // current wave position
	Width          int                      // terminal width for markdown rendering
	RenderMarkdown func(string, int) string // markdown renderer for text segments
	ToolsExpanded  bool                     // render tool calls in expanded mode

	// Flush state for leading spacing
	HasFlushed      bool
	LastFlushedType SegmentType
	LastFlushedPlan bool
}

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 StreamingNewlineCompactor added in v0.0.91

type StreamingNewlineCompactor struct {
	// contains filtered or unexported fields
}

StreamingNewlineCompactor incrementally compacts excessive newline runs across chunks.

func NewStreamingNewlineCompactor added in v0.0.91

func NewStreamingNewlineCompactor(maxRun int) *StreamingNewlineCompactor

NewStreamingNewlineCompactor creates a stateful compactor for streamed text.

func (*StreamingNewlineCompactor) CompactChunk added in v0.0.91

func (c *StreamingNewlineCompactor) CompactChunk(chunk string) string

CompactChunk returns chunk with newline runs capped to maxRun, preserving cross-chunk state.

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
	Footer  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 (@@ ... @@)

	// Reasoning display styles
	ReasoningSummary lipgloss.Style
	ReasoningHeader  lipgloss.Style
	ReasoningRaw     lipgloss.Style
	// contains filtered or unexported fields
}

Styles returns styled text helpers

func DefaultStyles

func DefaultStyles() *Styles

DefaultStyles returns styles for stderr (default TUI output)

func NewStyledWithTheme

func NewStyledWithTheme(output *os.File, theme *Theme) *Styles

NewStyledWithTheme creates styles with a specific theme

func NewStyles

func NewStyles(output *os.File) *Styles

NewStyles creates a new Styles instance for the given output

func (*Styles) FormatEnabled

func (s *Styles) FormatEnabled(enabled bool) string

FormatEnabled returns a styled enabled/disabled indicator

func (*Styles) FormatResult

func (s *Styles) FormatResult(success bool, msg string) string

FormatResult returns a styled success/fail result

func (*Styles) Theme

func (s *Styles) Theme() *Theme

Theme returns the theme used by these styles

type SubagentDiff added in v0.0.46

type SubagentDiff struct {
	Path      string
	Old       string
	New       string
	Line      int    // 1-indexed starting line (0 = unknown)
	Operation string // Optional operation hint, e.g. "create"
	Rendered  string // Cached rendered output
	Width     int    // Width when rendered (for cache invalidation)
}

SubagentDiff holds diff info from a subagent's edit_file/write_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"
	Prompt         string          // Task/question passed to the subagent
	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) HandleGuardianEvent added in v0.0.324

func (t *SubagentTracker) HandleGuardianEvent(callID string, event tools.GuardianEvent)

HandleGuardianEvent attaches a guardian review to the exact nested tool.

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, nestedCallID, 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, nestedCallID, toolName, toolInfo string, args json.RawMessage)

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. StreamRenderer owns the current snapshot so View() can read it without maintaining a second full-size buffer.

func NewTextSegmentRenderer added in v0.0.53

func NewTextSegmentRenderer(width int) (*TextSegmentRenderer, error)

NewTextSegmentRenderer creates a new TextSegmentRenderer with the given width. Uses partial flowing snapshots (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 committed rendered output 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) RenderedCommitted added in v0.0.229

func (r *TextSegmentRenderer) RenderedCommitted() string

RenderedCommitted returns the latest rendered snapshot that contains only committed markdown blocks and excludes any active partial preview.

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   color.Color // main accent color (commands, highlights)
	Secondary color.Color // secondary accent (headers, borders)

	// Semantic colors
	Success color.Color // success states, enabled
	Error   color.Color // error states, disabled
	Warning color.Color // warnings
	Muted   color.Color // dimmed/secondary text
	Text    color.Color // primary text

	// UI element colors
	Spinner    color.Color // loading spinner
	Border     color.Color // borders and dividers
	Background color.Color // background (if needed)

	// Diff backgrounds
	DiffAddBg     color.Color // background for added lines
	DiffRemoveBg  color.Color // background for removed lines
	DiffContextBg color.Color // background for context lines

	// Message backgrounds
	UserMsgBg color.Color // background for user messages in chat

	// Reasoning display colors
	ReasoningSummary color.Color // displayable reasoning summary body
	ReasoningHeader  color.Color // reasoning summary/raw header
	ReasoningRaw     color.Color // raw reasoning body
}

Theme defines the color palette for the UI

func DefaultTheme

func DefaultTheme() *Theme

DefaultTheme returns the default color theme (gruvbox)

func GetTheme

func GetTheme() *Theme

GetTheme returns the current active theme

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
	ReasoningSummary string
	ReasoningHeader  string
	ReasoningRaw     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

func FormatToolPhase(name, info string) ToolPhase

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

type ToolSegment struct {
	CallID   string
	Name     string
	Info     string
	Args     json.RawMessage
	Guardian *tools.GuardianEvent
	Success  bool
	Done     bool
}

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
	LastFlushedPlan bool
	HasFlushed      bool
	// contains filtered or unexported fields
}

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 the live tool segments used by the streaming indicator.

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) AddDiffSegmentWithOperation added in v0.0.197

func (t *ToolTracker) AddDiffSegmentWithOperation(path, old, new string, line int, operation string)

AddDiffSegmentWithOperation adds a diff segment with an operation hint 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) AddReasoningSegment added in v0.0.258

func (t *ToolTracker) AddReasoningSegment(rendered string, reasoning ReasoningSegment)

AddReasoningSegment adds a pre-rendered reasoning summary block. The display metadata is retained so Ctrl+E can rerender all thought blocks collapsed/expanded while the stream is still active.

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 through the configured markdown renderer 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) DiscardAttempt added in v0.0.229

func (t *ToolTracker) DiscardAttempt()

func (*ToolTracker) ExpandHintShown added in v0.0.213

func (t *ToolTracker) ExpandHintShown() bool

ExpandHintShown reports whether this tracker has consumed the one-time Ctrl+E discovery hint.

func (*ToolTracker) Expanded added in v0.0.319

func (t *ToolTracker) Expanded() bool

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 completed, unflushed segments immediately up to (but not past) the first pending tool barrier. Unlike FlushToScrollback, this does not keep any eligible segments for View(). Pending tools, segments after a pending tool, 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 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) ForceFailPendingTools added in v0.0.227

func (t *ToolTracker) ForceFailPendingTools()

ForceFailPendingTools marks any pending tools as failed. Use this when a stream terminates with an error so in-progress tools remain visible without being misrepresented as successful.

func (*ToolTracker) HandleGuardianEvent added in v0.0.324

func (t *ToolTracker) HandleGuardianEvent(event tools.GuardianEvent)

HandleGuardianEvent attaches a guardian annotation to its exact tool call. Events arriving before tool start are retained until that segment is created.

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, toolArgs json.RawMessage) 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 through the configured markdown renderer.

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) RenderUnflushedWithImageRenderer added in v0.0.227

func (t *ToolTracker) RenderUnflushedWithImageRenderer(width int, renderMd func(string, int) string, includeImages bool, renderer ImageArtifactRenderer) string

RenderUnflushedWithImageRenderer renders all non-pending, non-flushed segments with proper leading spacing, using renderer for image segments.

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) SetExpandHintShown added in v0.0.213

func (t *ToolTracker) SetExpandHintShown(v bool)

SetExpandHintShown controls whether the one-time Ctrl+E discovery hint has already been consumed by this tracker. Chat TUI keeps this session-scoped and reapplies it when a fresh per-turn tracker is created.

func (*ToolTracker) SetExpanded added in v0.0.94

func (t *ToolTracker) SetExpanded(v bool)

SetExpanded controls whether tool segments render in expanded mode.

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 UsageCall added in v0.0.328

type UsageCall struct {
	Model             string
	InputTokens       int
	OutputTokens      int
	CachedInputTokens int
	CacheWriteTokens  int
	TTFT              time.Duration
	GenerationTime    time.Duration
	ObservedOutput    bool
	Compaction        bool
	Handover          bool
	SideQuestion      bool
	Guardian          bool
}

UsageCall is usage and performance data for one provider request made by this process. Keeping request boundaries is important because some pricing tiers apply to each request independently.

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

Directories

Path Synopsis
Package streaming provides a streaming markdown renderer for incremental terminal markdown output.
Package streaming provides a streaming markdown renderer for incremental terminal markdown output.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL